/* log8 on the web.
 *
 * The tokens here are copied from apps/mobile/lib/app/theme.dart rather than reinvented, so the
 * site and the app are recognisably the same product: Ledger Light by day, OLED Dark when the
 * device is dark. Prose uses the system stack; headings, the wordmark and numerals use Plus Jakarta,
 * as the app and its store stories do.
 *
 * No framework, no build step and no JavaScript except the consent-gated analytics loader, ga.js
 * (style-src 'self', so no inline style attributes either). The theme follows the device rather
 * than a toggle. These are compliance and marketing pages that a store
 * reviewer, a crawler and somebody on a bad connection all need to read.
 */

@font-face {
  font-family: 'PlusJakartaSans';
  src:
    url('assets/PlusJakartaSans-SemiBold.woff2') format('woff2'),
    url('assets/PlusJakartaSans-SemiBold.ttf') format('truetype');
  font-weight: 600;
  font-display: swap;
}
@font-face {
  font-family: 'PlusJakartaSans';
  src:
    url('assets/PlusJakartaSans-Bold.woff2') format('woff2'),
    url('assets/PlusJakartaSans-Bold.ttf') format('truetype');
  font-weight: 700;
  font-display: swap;
}

/* --page is what the body sits on and --page-alt the banded sections. In light the page is the
   app's white surface and the bands its #F7F5F2 canvas; in dark the page is the OLED canvas and the
   bands its surface. --raised is a card on the page, --card a card on a band. */
:root {
  color-scheme: light dark;
  --page: #ffffff;
  --page-alt: #f7f5f2;
  --raised: #ffffff;
  --card: #ffffff;
  --grouped: #f3f2ef;
  --control: #f1f1ee;
  --control-pressed: #e7e7e3;
  --ink: #141416;
  --secondary: #3a3a40;
  --caption: #636366;
  --divider: #e4e2dc;
  --edge: #cfccc4;
  --accent: #c8102e;
  --accent-hover: #ad1028;
  --accent-text: #c8102e;
  --accent-text-hover: #ad1028;
  --accent-tonal: #fbecef;
  --on-accent-tonal: #ad1028;
  --on-accent: #ffffff;
  --success: #0f7b4c;
  --success-tonal: #e6f4ec;
  --todo-bg: #fff4dc;
  --todo-edge: #b7791f;
  --header-bg: rgba(255, 255, 255, 0.88);
  --glow: rgba(200, 16, 46, 0.16);
  --band: #141416;
  --on-band: #ffffff;
  --on-band-muted: #d1d1d6;
  --shot-edge: rgba(20, 20, 22, 0);
  --die: #c8102e;
  --die-side: #ad1028;
  --die-top: #e5173a;
  --pip: #ffffff;
  --gutter: 20px;
  --readable: 720px;
  --wide: 1120px;
  --display: 'PlusJakartaSans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --shadow: 0 1px 2px rgba(20, 20, 22, 0.06), 0 16px 40px rgba(20, 20, 22, 0.12);
  --shadow-3d: 0 2px 4px rgba(20, 20, 22, 0.06), 0 30px 60px -18px rgba(20, 20, 22, 0.34);
}

@media (prefers-color-scheme: dark) {
  :root {
    --page: #000000;
    --page-alt: #0e0e10;
    --raised: #0e0e10;
    --card: #18181b;
    --grouped: #141417;
    --control: #1c1c1f;
    --control-pressed: #28282c;
    --ink: #f5f5f7;
    --secondary: #c7c7cc;
    --caption: #a1a1a8;
    --divider: #26262a;
    --edge: #3a3a40;
    --accent: #e5173a;
    --accent-hover: #c8102e;
    --accent-text: #ff6479;
    --accent-text-hover: #ff9aa8;
    --accent-tonal: #2c0b12;
    --on-accent-tonal: #ff9aa8;
    --success: #30d158;
    --success-tonal: #0c2615;
    --todo-bg: #241f06;
    --todo-edge: #f0b04a;
    --header-bg: rgba(0, 0, 0, 0.8);
    --glow: rgba(229, 23, 58, 0.3);
    --band: #18181b;
    --on-band: #f5f5f7;
    --on-band-muted: #c7c7cc;
    --shot-edge: #26262a;
    --die: #e5173a;
    --die-side: #b0102c;
    --die-top: #ff3354;
    --shadow: 0 1px 2px rgba(0, 0, 0, 0.6), 0 16px 40px rgba(0, 0, 0, 0.7);
    --shadow-3d: 0 2px 4px rgba(0, 0, 0, 0.6), 0 30px 60px -18px rgba(0, 0, 0, 0.9);
  }
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

body {
  margin: 0;
  background: var(--page);
  color: var(--ink);
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  font-size: 16px;
  line-height: 1.35;
  -webkit-font-smoothing: antialiased;
}

img {
  max-width: 100%;
}

/* The hero's glow and 3D stage reach past the edge on a phone; clip them rather than let the page
   scroll sideways. */
main {
  overflow-x: hidden;
  overflow-x: clip;
}

/* The app caps content at 720dp and centres it above that. Same rule here for prose, so a wide
   desktop window does not produce 200-character lines of a privacy policy. The chrome and the
   landing page use the wider measure. */
.wrap {
  max-width: var(--readable);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.wrap.wide {
  max-width: var(--wide);
}

/* ---------------------------------------------------------------- chrome */

header.site {
  border-bottom: 1px solid var(--divider);
  background: var(--header-bg);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  backdrop-filter: saturate(180%) blur(12px);
  position: sticky;
  top: 0;
  z-index: 10;
}

header.site .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 64px;
  gap: 12px;
}

.brand {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  text-decoration: none;
}

.brand picture,
.footer-brand picture {
  display: block;
}

.brand img {
  height: 26px;
  width: auto;
  display: block;
}

nav.site {
  display: flex;
  align-items: center;
  gap: 4px;
}

/* Padded to a 44px touch target rather than sized by the text alone. */
nav.site a:not(.btn) {
  color: var(--secondary);
  text-decoration: none;
  font-size: 15px;
  font-weight: 600;
  padding: 12px 10px;
  min-height: 44px;
  display: inline-block;
  white-space: nowrap;
  border-radius: 10px;
}

nav.site a:not(.btn):hover,
nav.site a:not(.btn):focus-visible {
  color: var(--ink);
  background: var(--control);
}

nav.site a[aria-current='page'] {
  color: var(--on-accent-tonal);
  background: var(--accent-tonal);
  font-weight: 700;
}

nav.site .btn {
  margin-left: 6px;
}

@media (max-width: 560px) {
  header.site .wrap {
    gap: 6px;
  }
  nav.site {
    gap: 0;
  }
  nav.site a:not(.btn) {
    padding: 12px 7px;
    font-size: 14px;
  }
  nav.site .btn {
    margin-left: 4px;
    padding: 11px 12px;
  }
  .brand img {
    height: 22px;
  }
}

/* Support, News and Blog stay one tap away in the footer of every page; on a phone the header keeps
   Features, Games and the ask. */
@media (max-width: 560px) {
  nav.site a.nav-wide:not(.btn) {
    display: none;
  }
}

footer.site {
  border-top: 1px solid var(--divider);
  margin-top: 64px;
  padding: 48px 0 32px;
  color: var(--caption);
  font-size: 14px;
}

.footer-grid {
  display: grid;
  grid-template-columns: 1.8fr repeat(4, 1fr);
  gap: 32px 24px;
}

.footer-grid > div,
.footer-grid > nav {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.footer-brand img {
  height: 26px;
  width: auto;
  display: block;
  margin-bottom: 12px;
}

.footer-brand p {
  font-size: 14px;
  color: var(--caption);
  margin: 0;
  max-width: 22em;
}

.footer-title {
  font-family: var(--display);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0 0 4px;
}

/* Each footer link is its own 40px-plus row, so a thumb hits the one it meant. */
footer.site a {
  color: var(--secondary);
  text-decoration: none;
  padding: 11px 0;
  line-height: 22px;
}

footer.site a:hover {
  color: var(--accent-text);
  text-decoration: underline;
}

.footer-note {
  font-size: 13px;
  color: var(--caption);
  margin: -8px 0 6px;
}

footer.site .legal {
  margin-top: 32px;
  padding-top: 20px;
  border-top: 1px solid var(--divider);
  font-size: 13px;
  color: var(--caption);
}

@media (max-width: 860px) {
  .footer-grid {
    grid-template-columns: repeat(2, 1fr);
  }
  .footer-brand {
    grid-column: 1 / -1;
  }
}

/* ------------------------------------------------------------------ type */

h1,
h2 {
  font-family: var(--display);
  text-wrap: balance;
}

h1 {
  font-size: 32px;
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.6px;
  margin: 40px 0 8px;
}

h2 {
  font-size: 22px;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.35px;
  margin: 40px 0 10px;
}

h3 {
  font-size: 16px;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.1px;
  margin: 24px 0 6px;
}

p,
li {
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink);
}

p {
  margin: 0 0 14px;
}

ul,
ol {
  margin: 0 0 16px;
  padding-left: 22px;
}

li {
  margin-bottom: 8px;
}

a {
  color: var(--accent-text);
  text-underline-offset: 2px;
}

a:hover {
  color: var(--accent-text-hover);
}

strong {
  font-weight: 700;
}

.lede {
  font-size: 18px;
  color: var(--secondary);
  line-height: 1.55;
}

.caption {
  font-size: 13px;
  color: var(--caption);
  line-height: 1.4;
}

.updated {
  font-size: 13px;
  color: var(--caption);
  margin-bottom: 28px;
}

/* The crimson rule from the splash ident: one accent, at the end of the beat. */
.rule {
  width: 22px;
  height: 2px;
  background: var(--accent);
  border: 0;
  margin: 22px auto 0;
}

.rule.left + p,
.rule.left + .lede {
  margin-top: 18px;
}

.rule.left {
  margin-left: 0;
  margin-right: auto;
}

/* SVG icons are line art in the text colour; the paths only carry geometry. */
.icon {
  width: 22px;
  height: 22px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* --------------------------------------------------------------- buttons */

/* The app's Sport-Tech controls: crimson for the primary, a borderless tonal fill for the rest,
   bold labels with an icon so neither reads as plain text. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  background: var(--accent);
  color: var(--on-accent);
  text-decoration: none;
  font-weight: 700;
  font-size: 16px;
  padding: 13px 22px;
  border: 0;
  border-radius: 12px;
  min-height: 48px;
  line-height: 20px;
  white-space: nowrap;
  transition:
    background-color 0.15s ease,
    transform 0.15s ease;
}

.btn:hover,
.btn:focus-visible {
  background: var(--accent-hover);
  color: var(--on-accent);
}

.btn:active {
  transform: scale(0.98);
}

.btn .icon {
  width: 18px;
  height: 18px;
}

.btn.secondary {
  background: var(--control);
  color: var(--ink);
}

.btn.secondary:hover,
.btn.secondary:focus-visible {
  background: var(--control-pressed);
  color: var(--ink);
}

.btn.small {
  font-size: 14px;
  padding: 11px 16px;
  min-height: 44px;
  border-radius: 10px;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin: 28px 0 8px;
}

.actions.centre {
  justify-content: center;
}

/* --------------------------------------------------------------- content */

.card {
  background: var(--grouped);
  border-radius: 16px;
  padding: 22px;
  margin: 20px 0;
}

.card h3 {
  margin-top: 0;
}

.card p:last-child,
.card ul:last-child {
  margin-bottom: 0;
}

/* Support's contact card: two inboxes, each with what it is for. */
.contacts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 12px;
  margin: 24px 0 8px;
}

.contacts .card {
  margin: 0;
}

.contacts .address {
  font-size: 18px;
  font-weight: 600;
  margin-bottom: 6px;
}

table {
  width: 100%;
  border-collapse: collapse;
  margin: 12px 0 20px;
  font-size: 15px;
}

th,
td {
  text-align: left;
  padding: 10px 12px 10px 0;
  border-bottom: 1px solid var(--divider);
  vertical-align: top;
}

th {
  font-weight: 600;
  font-size: 13px;
  color: var(--caption);
  text-transform: uppercase;
  letter-spacing: 0.4px;
}

/* A thing the reader must not skim past. Used for the "this cannot be undone" beat. */
.notice {
  border-left: 3px solid var(--accent);
  background: var(--accent-tonal);
  padding: 14px 16px;
  border-radius: 0 10px 10px 0;
  margin: 20px 0;
}

.notice p:last-child {
  margin-bottom: 0;
}

/* Marks a value the founder still has to supply. Visible on purpose: a placeholder that looks
   like finished copy is how a draft policy gets published with "Company Name" in it. */
.todo {
  background: var(--todo-bg);
  border-bottom: 1px dashed var(--todo-edge);
  padding: 0 3px;
  font-style: normal;
}

/* ------------------------------------------------------------- landing */

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 700;
  color: var(--on-accent-tonal);
  background: var(--accent-tonal);
  border-radius: 999px;
  padding: 6px 12px;
  margin: 0;
}

.eyebrow::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
}

.display {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(38px, 6.2vw, 64px);
  line-height: 1.04;
  letter-spacing: -0.035em;
  margin: 20px 0 18px;
}

.display em,
.section-head h2 em {
  font-style: normal;
  color: var(--accent-text);
}

.hero {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: 48px;
  align-items: center;
  padding: 72px 0 64px;
}

.hero .lede {
  font-size: 19px;
  max-width: 32em;
}

.hero-note {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  list-style: none;
  padding: 0;
  margin: 22px 0 0;
}

.hero-note li {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  color: var(--caption);
  margin: 0;
}

.hero-note .icon {
  width: 16px;
  height: 16px;
  color: var(--success);
}

/* A store story, shown as the card it is: rounded, lifted, with its space reserved so nothing
   jumps while it loads. The stories are light screens, so in dark a hairline keeps their edge. */
.shot {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 9 / 16;
  border-radius: 28px;
  background: var(--grouped);
  box-shadow:
    0 0 0 1px var(--shot-edge),
    var(--shadow);
}

@media (max-width: 860px) {
  .hero {
    grid-template-columns: 1fr;
    gap: 32px;
    padding: 40px 0 48px;
  }
  .hero .lede {
    font-size: 17px;
  }
}

/* ------------------------------------------------------------- 3D stage */

/* The hero: three store stories standing in space, a result card floating in front of them and a
   die turning above. CSS transforms only, so it costs no script and no download beyond the
   stories already on the page. Only the scene's sway and the die move, and neither moves at all
   for somebody who has asked for reduced motion. */
.stage {
  position: relative;
  isolation: isolate;
  justify-self: center;
  width: min(100%, 440px);
  aspect-ratio: 11 / 12;
  perspective: 1400px;
  perspective-origin: 50% 40%;
}

.stage::before {
  content: '';
  position: absolute;
  inset: 0 -25% -10%;
  z-index: -1;
  background: radial-gradient(closest-side, var(--glow), transparent);
}

.scene {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  transform: rotateX(6deg) rotateY(-14deg);
}

.scene .shot {
  position: absolute;
  top: 4%;
  left: 25%;
  width: 50%;
  border-radius: 24px;
  box-shadow:
    0 0 0 1px var(--shot-edge),
    var(--shadow-3d);
  backface-visibility: hidden;
}

.scene .shot.left {
  transform: translate3d(-58%, 7%, -160px) rotateY(22deg);
}

.scene .shot.right {
  transform: translate3d(58%, 7%, -160px) rotateY(-22deg);
}

.scene .shot.front {
  transform: translateZ(30px);
}

.float-card {
  position: absolute;
  left: 0;
  bottom: 6%;
  width: min(66%, 280px);
  transform: translateZ(140px);
}

.die-mount {
  position: absolute;
  right: 6%;
  top: 0;
  transform: translateZ(200px);
  transform-style: preserve-3d;
}

@media (prefers-reduced-motion: no-preference) {
  .scene {
    animation: sway 10s ease-in-out infinite alternate;
  }
  .die {
    animation: tumble 14s linear infinite;
  }
}

@keyframes sway {
  from {
    transform: rotateX(7deg) rotateY(-18deg);
  }
  to {
    transform: rotateX(4deg) rotateY(-8deg);
  }
}

@keyframes tumble {
  from {
    transform: rotateX(-28deg) rotateY(0deg) rotateZ(8deg);
  }
  to {
    transform: rotateX(-28deg) rotateY(360deg) rotateZ(8deg);
  }
}

@media (max-width: 860px) {
  .stage {
    width: min(100%, 340px);
    margin-top: 12px;
  }
  .float-card {
    left: 4%;
    width: 64%;
    transform: translateZ(90px);
  }
  .die-mount {
    top: 8%;
    right: 8%;
    transform: translateZ(110px);
  }
}

/* A die in the brand crimson. Each face is one element; the pips are radial gradients, so the
   whole cube is six spans and no images. */
.die {
  --s: 64px;
  --pip-r: 5.5px;
  position: relative;
  display: block;
  width: var(--s);
  height: var(--s);
  transform-style: preserve-3d;
  transform: rotateX(-28deg) rotateY(-36deg) rotateZ(8deg);
}

.die span {
  position: absolute;
  inset: 0;
  border-radius: 12px;
  background-color: var(--die);
  background-repeat: no-repeat;
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.14),
    inset 0 -8px 14px rgba(0, 0, 0, 0.18);
}

.die .f1 {
  transform: translateZ(calc(var(--s) / 2));
  background-image: radial-gradient(circle at 50% 50%, var(--pip) var(--pip-r), transparent calc(var(--pip-r) + 0.5px));
}

.die .f2 {
  transform: rotateY(90deg) translateZ(calc(var(--s) / 2));
  background-color: var(--die-side);
  background-image:
    radial-gradient(circle at 28% 28%, var(--pip) var(--pip-r), transparent calc(var(--pip-r) + 0.5px)),
    radial-gradient(circle at 72% 72%, var(--pip) var(--pip-r), transparent calc(var(--pip-r) + 0.5px));
}

.die .f3 {
  transform: rotateY(180deg) translateZ(calc(var(--s) / 2));
  background-image:
    radial-gradient(circle at 28% 28%, var(--pip) var(--pip-r), transparent calc(var(--pip-r) + 0.5px)),
    radial-gradient(circle at 50% 50%, var(--pip) var(--pip-r), transparent calc(var(--pip-r) + 0.5px)),
    radial-gradient(circle at 72% 72%, var(--pip) var(--pip-r), transparent calc(var(--pip-r) + 0.5px));
}

.die .f4 {
  transform: rotateY(-90deg) translateZ(calc(var(--s) / 2));
  background-color: var(--die-side);
  background-image:
    radial-gradient(circle at 28% 28%, var(--pip) var(--pip-r), transparent calc(var(--pip-r) + 0.5px)),
    radial-gradient(circle at 72% 28%, var(--pip) var(--pip-r), transparent calc(var(--pip-r) + 0.5px)),
    radial-gradient(circle at 28% 72%, var(--pip) var(--pip-r), transparent calc(var(--pip-r) + 0.5px)),
    radial-gradient(circle at 72% 72%, var(--pip) var(--pip-r), transparent calc(var(--pip-r) + 0.5px));
}

.die .f5 {
  transform: rotateX(90deg) translateZ(calc(var(--s) / 2));
  background-color: var(--die-top);
  background-image:
    radial-gradient(circle at 28% 28%, var(--pip) var(--pip-r), transparent calc(var(--pip-r) + 0.5px)),
    radial-gradient(circle at 72% 28%, var(--pip) var(--pip-r), transparent calc(var(--pip-r) + 0.5px)),
    radial-gradient(circle at 50% 50%, var(--pip) var(--pip-r), transparent calc(var(--pip-r) + 0.5px)),
    radial-gradient(circle at 28% 72%, var(--pip) var(--pip-r), transparent calc(var(--pip-r) + 0.5px)),
    radial-gradient(circle at 72% 72%, var(--pip) var(--pip-r), transparent calc(var(--pip-r) + 0.5px));
}

.die .f6 {
  transform: rotateX(-90deg) translateZ(calc(var(--s) / 2));
  background-color: var(--die-side);
  background-image:
    radial-gradient(circle at 28% 25%, var(--pip) var(--pip-r), transparent calc(var(--pip-r) + 0.5px)),
    radial-gradient(circle at 72% 25%, var(--pip) var(--pip-r), transparent calc(var(--pip-r) + 0.5px)),
    radial-gradient(circle at 28% 50%, var(--pip) var(--pip-r), transparent calc(var(--pip-r) + 0.5px)),
    radial-gradient(circle at 72% 50%, var(--pip) var(--pip-r), transparent calc(var(--pip-r) + 0.5px)),
    radial-gradient(circle at 28% 75%, var(--pip) var(--pip-r), transparent calc(var(--pip-r) + 0.5px)),
    radial-gradient(circle at 72% 75%, var(--pip) var(--pip-r), transparent calc(var(--pip-r) + 0.5px));
}

/* The app's result row, drawn in the page's own theme, so it is light by day and OLED at night
   with the rest of the site. Always beside a real image or text that says the same thing, so it is
   hidden from screen readers. */
.result-card {
  background: var(--card);
  border: 1px solid var(--divider);
  border-radius: 18px;
  padding: 14px 16px 16px;
  box-shadow: var(--shadow-3d);
  font-family: var(--display);
}

.rc-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin: 0 0 10px;
  font-size: 13px;
  font-weight: 700;
  color: var(--caption);
  line-height: 20px;
}

.rc-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  border-radius: 999px;
  padding: 2px 8px 2px 6px;
  background: var(--success-tonal);
  color: var(--success);
  font-size: 12px;
}

.rc-badge.pending {
  background: var(--accent-tonal);
  color: var(--on-accent-tonal);
}

.rc-badge .icon {
  width: 14px;
  height: 14px;
  stroke-width: 2.5;
}

.rc-score {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.rc-side {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  font-size: 13px;
  font-weight: 700;
  color: var(--secondary);
  min-width: 48px;
}

.rc-side.lost {
  color: var(--caption);
}

.avatar {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 15px;
  font-weight: 700;
}

.avatar.alt {
  background: var(--control-pressed);
  color: var(--ink);
}

.rc-digits {
  font-size: 34px;
  font-weight: 700;
  letter-spacing: -0.03em;
  color: var(--ink);
  line-height: 1;
}

.rc-digits .muted {
  color: var(--caption);
}

.rc-rows {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 6px;
}

.rc-rows li {
  display: grid;
  grid-template-columns: 34px 1fr auto;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: 14px;
  font-weight: 700;
  line-height: 22px;
  color: var(--secondary);
}

.rc-rows .place {
  color: var(--caption);
}

.rc-rows li:first-child .place {
  color: var(--accent-text);
}

.rc-rows .mark {
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.rc-line {
  margin: 10px 0 0;
  padding-top: 10px;
  border-top: 1px solid var(--divider);
  font-size: 13px;
  font-weight: 700;
  color: var(--secondary);
  text-align: center;
  line-height: 20px;
}

/* ------------------------------------------------------------- sections */

.section {
  padding: 80px 0;
}

.section:last-child {
  padding-bottom: 0;
}

.section.first {
  padding-top: 0;
}

.section.snug {
  padding-bottom: 32px;
}

.section.alt {
  background: var(--page-alt);
}

.section-head {
  max-width: 640px;
  margin-bottom: 40px;
}

.section-head.centre {
  margin-left: auto;
  margin-right: auto;
  text-align: center;
}

.kicker {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin: 0 0 10px;
}

.section-head h2 {
  font-size: clamp(28px, 4vw, 40px);
  letter-spacing: -0.025em;
  line-height: 1.12;
  margin: 0 0 14px;
}

.section-head p {
  font-size: 18px;
  color: var(--secondary);
  margin: 0;
}

.section-head .kicker {
  font-size: 13px;
  color: var(--accent-text);
  margin: 0 0 10px;
}

@media (max-width: 560px) {
  .section {
    padding: 56px 0;
  }
  .section-head {
    margin-bottom: 28px;
  }
  .section-head p {
    font-size: 16px;
  }
}

/* What's new: the latest news post, offered on the landing page with its highlights fanned out in
   3D beside it. */
.whats-new {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 40px;
  align-items: center;
  background: var(--raised);
  border: 1px solid var(--divider);
  border-radius: 24px;
  padding: 40px;
}

.whats-new .section-head {
  margin: 0;
}

.whats-new .actions {
  margin-bottom: 0;
}

.fan {
  display: grid;
  perspective: 1000px;
  padding: 8px 0;
}

.fan > * {
  width: min(82%, 300px);
  transform: rotateX(12deg) rotateY(-16deg);
}

.fan > :nth-child(1) {
  justify-self: end;
  transform: rotateX(12deg) rotateY(-16deg) rotateZ(2deg) translateZ(-40px);
}

.fan > :nth-child(2) {
  justify-self: center;
  margin-top: 6px;
}

.fan > :nth-child(3) {
  justify-self: start;
  margin-top: 6px;
  transform: rotateX(12deg) rotateY(-16deg) rotateZ(-2deg) translateZ(40px);
}

.fan .tiles {
  grid-template-columns: repeat(6, 1fr);
}

@media (max-width: 860px) {
  .whats-new {
    grid-template-columns: 1fr;
    padding: 28px 22px;
    gap: 24px;
  }
}

.steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 32px;
  list-style: none;
  padding: 0;
  margin: 0;
}

.step {
  margin: 0;
}

.step .shot {
  max-width: 300px;
  margin: 0 0 24px;
}

.step-n {
  display: inline-grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--on-accent);
  font-family: var(--display);
  font-weight: 700;
  font-size: 15px;
  margin-bottom: 12px;
}

.step h3 {
  font-family: var(--display);
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.3px;
  margin: 0 0 6px;
}

.step p {
  color: var(--secondary);
  margin: 0;
}

/* On a phone the three stories sit beside their text instead of stacking three screens tall. */
@media (max-width: 760px) {
  .steps {
    grid-template-columns: 1fr;
    gap: 28px;
  }
  .step {
    display: grid;
    grid-template-columns: 112px 1fr;
    gap: 18px;
    align-items: center;
  }
  .step .shot {
    margin: 0;
    border-radius: 16px;
  }
  .step h3 {
    font-size: 18px;
  }
  .step p {
    font-size: 15px;
  }
}

.features {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}

@media (max-width: 960px) {
  .features {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 620px) {
  .features {
    grid-template-columns: 1fr;
  }
}

.feature {
  background: var(--raised);
  border: 1px solid var(--divider);
  border-radius: 18px;
  padding: 24px;
}

/* The app's 46px icon circle, with a lit top edge so it sits up off the card. */
.feature-icon {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: var(--accent-tonal);
  color: var(--on-accent-tonal);
  margin-bottom: 16px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.5),
    inset 0 -2px 0 rgba(0, 0, 0, 0.06),
    0 8px 18px -8px var(--glow);
}

.feature h3 {
  font-family: var(--display);
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -0.2px;
  margin: 0 0 6px;
}

.feature p {
  margin: 0;
  font-size: 15px;
  color: var(--secondary);
}

.feature .new {
  display: inline-block;
  vertical-align: 2px;
  margin-left: 6px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--on-accent-tonal);
  background: var(--accent-tonal);
  border-radius: 999px;
  padding: 2px 7px;
}

/* One column on a phone: icon beside the text, so seven cards are not seven screens. */
@media (max-width: 620px) {
  .feature {
    display: grid;
    grid-template-columns: 46px 1fr;
    gap: 0 16px;
    padding: 18px;
  }
  .feature-icon {
    grid-row: span 2;
    margin: 0;
  }
}

.games {
  margin-top: 48px;
  text-align: center;
}

.games h3 {
  font-family: var(--display);
  font-size: 18px;
  font-weight: 700;
  margin: 0 0 6px;
}

.games p {
  color: var(--caption);
  font-size: 15px;
  margin: 0 0 16px;
}

/* Game names, not buttons: flat labels with no hover, so nothing here asks to be tapped. */
.chips {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  list-style: none;
  padding: 0;
  margin: 0;
}

.chips li {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  line-height: 20px;
  padding: 8px 14px;
  border-radius: 999px;
  background: var(--grouped);
  color: var(--secondary);
}

.chips li.more {
  background: transparent;
  border: 1px dashed var(--edge);
  color: var(--caption);
}

.privacy {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 48px;
  align-items: start;
}

.privacy .section-head {
  margin-bottom: 0;
}

.promises {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 12px;
}

.promises li {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  background: var(--card);
  border-radius: 14px;
  padding: 16px 18px;
  margin: 0;
  font-size: 15px;
  color: var(--secondary);
}

.promises strong {
  display: block;
  color: var(--ink);
  font-size: 16px;
  margin-bottom: 2px;
}

.promises .icon {
  color: var(--success);
  margin-top: 2px;
}

@media (max-width: 860px) {
  .privacy {
    grid-template-columns: 1fr;
    gap: 28px;
  }
}

/* The ask. Dark in light mode so it reads as the end of the page rather than another feature card;
   in dark mode an elevated panel with the crimson glow does the same job. */
.cta-band {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 32px;
  align-items: center;
  background: var(--band);
  color: var(--on-band);
  border: 1px solid var(--divider);
  border-radius: 24px;
  padding: 56px;
}

.cta-band::before {
  content: '';
  position: absolute;
  z-index: -1;
  width: 520px;
  height: 520px;
  right: -160px;
  top: -220px;
  background: radial-gradient(closest-side, rgba(229, 23, 58, 0.35), transparent);
}

.cta-band h2 {
  font-size: clamp(28px, 4vw, 38px);
  letter-spacing: -0.025em;
  line-height: 1.12;
  color: var(--on-band);
  margin: 0 0 12px;
}

.cta-band p {
  color: var(--on-band-muted);
  font-size: 17px;
  margin: 0;
  max-width: 36em;
}

.cta-band .actions {
  margin: 0;
  flex-direction: column;
  align-items: stretch;
}

.cta-band a:not(.btn) {
  color: var(--on-band);
  text-align: center;
  padding: 12px 0;
  font-size: 15px;
  font-weight: 600;
}

.cta-band :focus-visible {
  outline-color: var(--on-band);
}

@media (max-width: 760px) {
  .cta-band {
    grid-template-columns: 1fr;
    padding: 36px 24px;
    gap: 24px;
  }
}

/* ------------------------------------------------------- news and blog */

.back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  margin-top: 24px;
  font-size: 14px;
  font-weight: 700;
  text-decoration: none;
}

.back .icon {
  width: 16px;
  height: 16px;
}

.post-meta {
  font-size: 14px;
  color: var(--caption);
  margin: 0 0 8px;
}

.post-meta .tag {
  color: var(--accent-text);
  font-weight: 700;
}

.article h1 {
  font-size: clamp(32px, 5vw, 46px);
  letter-spacing: -0.03em;
  line-height: 1.08;
  margin: 12px 0 16px;
}

.article .lede {
  font-size: 20px;
}

.article p,
.article li {
  font-size: 17px;
  line-height: 1.7;
}

.article h2 {
  margin-top: 44px;
}

.article figure {
  margin: 36px 0;
}

.figure-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
}

.figure-row .shot {
  border-radius: 18px;
}

.article figcaption {
  font-size: 14px;
  color: var(--caption);
  text-align: center;
  margin-top: 14px;
}

.signoff {
  font-family: var(--display);
  font-weight: 600;
  margin-top: 32px;
}

@media (max-width: 560px) {
  .article .lede {
    font-size: 18px;
  }
  .figure-row {
    gap: 8px;
  }
  .figure-row .shot {
    border-radius: 12px;
  }
}

/* Three result cards on a tilted table: the news post's picture of what changed, in the page's
   theme rather than a screenshot that would stay light at night. */
.tableau {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  padding: 28px 8px 36px;
  perspective: 1200px;
}

.tableau > * {
  transform: rotateX(18deg) rotateZ(-2deg);
  transform-origin: 50% 100%;
}

.tableau > :nth-child(2) {
  transform: rotateX(18deg) translateZ(40px) translateY(-10px);
}

.tableau > :nth-child(3) {
  transform: rotateX(18deg) rotateZ(2deg);
}

@media (max-width: 640px) {
  .tableau {
    grid-template-columns: 1fr;
    max-width: 320px;
    margin: 0 auto;
    padding: 12px 0 20px;
  }
  .tableau > *,
  .tableau > :nth-child(2),
  .tableau > :nth-child(3) {
    transform: rotateX(10deg);
  }
}

/* A photo grid in miniature: tiles with a month heading, the shape of Profile › Your photos. */
.photo-card .rc-top {
  margin-bottom: 8px;
}

.tiles {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
}

.tiles span {
  aspect-ratio: 1;
  border-radius: 6px;
  background: linear-gradient(140deg, var(--accent-tonal), var(--control-pressed));
}

.tiles span:nth-child(2) {
  background: linear-gradient(200deg, var(--accent), var(--accent-tonal));
}

.tiles span:nth-child(4) {
  background: linear-gradient(160deg, var(--success-tonal), var(--control));
}

.tiles span:nth-child(6) {
  background: linear-gradient(120deg, var(--control-pressed), var(--accent));
}

.post-list {
  list-style: none;
  padding: 0;
  margin: 28px 0 0;
}

.post-list li {
  margin: 0 0 16px;
}

/* A whole post is one link, so the card lifts toward you on hover and press like the app's
   disclosure cards, and ends in a labelled arrow rather than relying on the lift alone. */
.post-card {
  display: grid;
  grid-template-columns: 1fr 120px;
  gap: 24px;
  align-items: center;
  background: var(--raised);
  border: 1px solid var(--divider);
  border-radius: 18px;
  padding: 24px;
  color: inherit;
  text-decoration: none;
  transition:
    border-color 0.2s ease,
    box-shadow 0.2s ease,
    transform 0.2s ease;
}

.post-card:hover,
.post-card:focus-visible {
  color: inherit;
  border-color: var(--edge);
  box-shadow: var(--shadow);
  transform: perspective(900px) rotateX(2deg) translateY(-3px);
}

.post-card:active {
  transform: translateY(-1px);
}

.post-card h2 {
  font-size: 22px;
  margin: 4px 0 8px;
}

.post-card p {
  color: var(--secondary);
  margin: 0 0 12px;
}

.post-card .more {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--accent-text);
  font-weight: 700;
  font-size: 15px;
}

.post-card .more .icon {
  width: 16px;
  height: 16px;
}

.post-card .shot {
  border-radius: 14px;
  box-shadow: 0 0 0 1px var(--shot-edge);
}

@media (max-width: 560px) {
  .post-card {
    grid-template-columns: 1fr;
    padding: 20px;
  }
  .post-card .shot,
  .post-card .cover {
    display: none;
  }
}

/* Blog covers: a small CSS sculpture per column, so a post has art without an image to cache.
   System design gets a stack of isometric layers, the founder's corner gets the die. */
.cover {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  border-radius: 16px;
  background: var(--page-alt);
  overflow: hidden;
  perspective: 600px;
}

.cover.large {
  aspect-ratio: 21 / 9;
  margin: 28px 0 8px;
  border: 1px solid var(--divider);
}

.layers {
  position: relative;
  width: 64px;
  height: 64px;
  transform-style: preserve-3d;
  transform: rotateX(58deg) rotateZ(-45deg);
}

.layers span {
  position: absolute;
  inset: 0;
  border-radius: 10px;
  background: var(--card);
  border: 1px solid var(--edge);
  box-shadow: 6px 6px 0 -1px var(--divider);
}

.layers span:nth-child(1) {
  transform: translateZ(0);
}

.layers span:nth-child(2) {
  transform: translateZ(18px);
}

.layers span:nth-child(3) {
  transform: translateZ(36px);
  background: var(--accent);
  border-color: var(--accent);
}

.cover.large .layers {
  width: 96px;
  height: 96px;
}

.cover.large .layers span:nth-child(2) {
  transform: translateZ(26px);
}

.cover.large .layers span:nth-child(3) {
  transform: translateZ(52px);
}

.post-card .cover {
  width: 120px;
}

/* Category chips on the blog index jump to their column, and look like the app's chips. */
.chip-links {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  list-style: none;
  padding: 0;
  margin: 24px 0 0;
}

.chip-links li {
  margin: 0;
}

.chip-links a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  padding: 10px 16px;
  border-radius: 999px;
  background: var(--control);
  color: var(--ink);
  font-size: 15px;
  font-weight: 700;
  text-decoration: none;
}

.chip-links a:hover,
.chip-links a:focus-visible {
  background: var(--control-pressed);
  color: var(--ink);
}

.chip-links .icon {
  width: 16px;
  height: 16px;
}

.column-head {
  scroll-margin-top: 80px;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin: 48px 0 0;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--divider);
}

.column-head h2 {
  margin: 0;
}

.column-head p {
  margin: 0;
  font-size: 14px;
  color: var(--caption);
}

/* A system's path, step by step. An ordered list so it reads in order without the arrows. */
.flow {
  list-style: none;
  counter-reset: flow;
  padding: 0;
  margin: 28px 0;
  display: grid;
  gap: 10px;
}

.flow li {
  counter-increment: flow;
  position: relative;
  display: grid;
  grid-template-columns: 36px 1fr;
  gap: 2px 14px;
  align-items: start;
  margin: 0;
  padding: 14px 16px;
  border-radius: 14px;
  background: var(--grouped);
  font-size: 16px;
  line-height: 1.55;
  color: var(--secondary);
}

.flow li::before {
  content: counter(flow);
  grid-row: span 2;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--accent-tonal);
  color: var(--on-accent-tonal);
  font-family: var(--display);
  font-weight: 700;
}

.flow strong {
  color: var(--ink);
  font-family: var(--display);
}

.flow li:not(:last-child)::after {
  content: '';
  position: absolute;
  left: 33px;
  bottom: -10px;
  width: 2px;
  height: 10px;
  background: var(--edge);
}

/* ------------------------------------------------- stats, FAQ, social */

/* Number-first tiles, like the app's steppers: the figure carries the line, the label explains it.
   Each figure is a fact about the product today, not a growth claim. */
.stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  list-style: none;
  padding: 0;
  margin: 0;
  perspective: 1200px;
}

.stats li {
  margin: 0;
  padding: 22px 20px;
  border-radius: 18px;
  background: var(--raised);
  border: 1px solid var(--divider);
  box-shadow:
    0 1px 0 var(--divider),
    0 18px 30px -24px rgba(20, 20, 22, 0.5);
  transform: rotateX(8deg);
  transform-origin: 50% 100%;
}

.stats .figure {
  display: block;
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(34px, 4.4vw, 48px);
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--ink);
  margin-bottom: 8px;
  font-variant-numeric: tabular-nums;
}

.stats .figure em {
  font-style: normal;
  color: var(--accent-text);
}

.stats .label {
  display: block;
  font-size: 14px;
  line-height: 1.45;
  color: var(--caption);
}

@media (max-width: 760px) {
  .stats {
    grid-template-columns: repeat(2, 1fr);
  }
  .stats li {
    padding: 18px 16px;
  }
}

/* Questions as the app's disclosure cards: the whole summary row is the control, with a chevron
   that turns when it opens. Native <details>, so it works with no script and from the keyboard. */
.faq {
  display: grid;
  gap: 10px;
  max-width: 820px;
  margin: 0 auto;
}

.faq details {
  background: var(--grouped);
  border-radius: 16px;
}

.faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 62px;
  padding: 16px 20px;
  cursor: pointer;
  list-style: none;
  font-family: var(--display);
  font-size: 17px;
  font-weight: 700;
  line-height: 1.35;
  color: var(--ink);
  border-radius: 16px;
}

.faq summary::-webkit-details-marker {
  display: none;
}

.faq summary:hover {
  background: var(--control);
}

.faq summary .chev {
  display: grid;
  place-items: center;
  flex: none;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--control);
  color: var(--ink);
  transition:
    transform 0.2s ease,
    background-color 0.2s ease;
}

.faq summary .chev .icon {
  width: 18px;
  height: 18px;
}

.faq details[open] summary .chev {
  transform: rotate(180deg);
  background: var(--accent-tonal);
  color: var(--on-accent-tonal);
}

.faq .answer {
  padding: 0 20px 18px;
}

.faq .answer p {
  font-size: 16px;
  color: var(--secondary);
  margin: 0 0 10px;
}

.faq .answer p:last-child {
  margin-bottom: 0;
}

/* Follow log8: one row per channel in the style of the app's 62px navigation rows, each with the
   network's own mark in a tile, the handle, and a labelled action, so it is plainly a link out. */
.socials {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 12px;
  list-style: none;
  padding: 0;
  margin: 0;
}

.socials li {
  margin: 0;
}

.social {
  display: grid;
  grid-template-columns: 46px 1fr;
  gap: 4px 14px;
  align-items: center;
  min-height: 62px;
  height: 100%;
  padding: 16px;
  border-radius: 18px;
  background: var(--card);
  border: 1px solid var(--divider);
  color: var(--ink);
  text-decoration: none;
  transition:
    transform 0.2s ease,
    box-shadow 0.2s ease,
    border-color 0.2s ease;
}

.social:hover,
.social:focus-visible {
  color: var(--ink);
  border-color: var(--edge);
  box-shadow: var(--shadow);
  transform: perspective(800px) rotateX(4deg) translateY(-3px);
}

.social:active {
  transform: translateY(-1px);
}

.social .tile {
  grid-row: span 2;
}

.social .name {
  font-family: var(--display);
  font-weight: 700;
  font-size: 16px;
  line-height: 1.2;
}

.social .handle {
  font-size: 14px;
  color: var(--caption);
  line-height: 1.3;
  overflow-wrap: anywhere;
}

.social .go {
  grid-column: 1 / -1;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 10px;
  font-size: 14px;
  font-weight: 700;
  color: var(--accent-text);
}

.social .go .icon {
  width: 16px;
  height: 16px;
}

/* On a phone the five channels are list rows, name and handle beside the mark and the arrow at the
   end, rather than five cards a screen and a half tall. */
@media (max-width: 620px) {
  .socials {
    grid-template-columns: 1fr;
    gap: 8px;
  }
  .social {
    grid-template-columns: 46px 1fr 32px;
    padding: 12px 14px;
  }
  .social .go {
    grid-column: 3;
    grid-row: 1 / span 2;
    justify-self: end;
    margin: 0;
  }
  .social .go .icon {
    width: 20px;
    height: 20px;
  }
  .social .go-text {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
  }
}

/* The networks' own colours, so each is recognisable at a glance. X follows the page's ink so it
   stays visible on OLED black. */
.tile {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border-radius: 14px;
  color: #ffffff;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.25),
    0 8px 16px -10px rgba(0, 0, 0, 0.6);
}

.tile svg {
  width: 22px;
  height: 22px;
  fill: currentColor;
}

.tile.x {
  background: var(--ink);
  color: var(--page);
}

.tile.instagram {
  background: radial-gradient(circle at 30% 107%, #fdf497 0%, #fd5949 45%, #d6249f 60%, #285aeb 90%);
}

.tile.facebook {
  background: #1877f2;
}

.tile.linkedin {
  background: #0a66c2;
}

.tile.youtube {
  background: #e00000;
}

/* The compact row of round buttons used in the footer and under the news and blog lists. */
.follow {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  list-style: none;
  padding: 0;
  margin: 0;
}

.follow li {
  margin: 0;
}

.follow a {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border-radius: 50%;
  background: var(--control);
  color: var(--ink);
  transition:
    background-color 0.15s ease,
    color 0.15s ease,
    transform 0.15s ease;
}

.follow a:hover,
.follow a:focus-visible {
  color: #ffffff;
  text-decoration: none;
  transform: translateY(-2px);
}

.follow svg {
  width: 20px;
  height: 20px;
  fill: currentColor;
}

.follow .x:hover,
.follow .x:focus-visible {
  background: var(--ink);
  color: var(--page);
}

.follow .instagram:hover,
.follow .instagram:focus-visible {
  background: radial-gradient(circle at 30% 107%, #fdf497 0%, #fd5949 45%, #d6249f 60%, #285aeb 90%);
}

.follow .facebook:hover,
.follow .facebook:focus-visible {
  background: #1877f2;
}

.follow .linkedin:hover,
.follow .linkedin:focus-visible {
  background: #0a66c2;
}

.follow .youtube:hover,
.follow .youtube:focus-visible {
  background: #e00000;
}

.follow .feed:hover,
.follow .feed:focus-visible {
  background: var(--accent);
}

.follow .feed svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
}

footer.site .follow {
  margin-top: 14px;
}

footer.site .follow a {
  padding: 0;
  line-height: 1;
}

/* A strip at the foot of the news and blog lists: where the next post will be announced. */
.subscribe {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 36px;
  padding: 22px;
  border-radius: 18px;
  background: var(--grouped);
}

.subscribe h2 {
  font-size: 18px;
  margin: 0 0 4px;
}

.subscribe p {
  margin: 0;
  font-size: 15px;
  color: var(--secondary);
}

/* Visible to screen readers only, for "opens in a new tab" on links whose text is the name. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Not found: the die, rolled, and the way back. */
.not-found {
  display: grid;
  justify-items: center;
  text-align: center;
  padding: 72px 0 24px;
}

.not-found .die-mount {
  position: static;
  transform: none;
  perspective: 600px;
  margin-bottom: 28px;
}

/* --------------------------------------------------------- accessibility */

:focus-visible {
  outline: 2px solid var(--accent-text);
  outline-offset: 2px;
  border-radius: 4px;
}

.skip {
  position: absolute;
  left: -9999px;
}

.skip:focus {
  position: static;
  display: inline-block;
  margin: 8px;
  padding: 12px 16px;
}

@media (prefers-reduced-motion: reduce) {
  * {
    transition: none !important;
    animation: none !important;
  }
  .post-card:hover,
  .post-card:focus-visible,
  .post-card:active,
  .social:hover,
  .social:focus-visible,
  .social:active,
  .follow a:hover,
  .follow a:focus-visible,
  .btn:active {
    transform: none;
  }
}

/* ------------------------------------------- generated pages (tools/build_pages.py) */

/* The store listings do not exist yet, so every generated page says so under the header. */
.soon-bar {
  margin: 0;
  padding: 8px var(--gutter);
  text-align: center;
  font-size: 14px;
  font-weight: 600;
  background: var(--accent-tonal);
  color: var(--on-accent-tonal);
}

.soon-bar a {
  white-space: nowrap;
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.page-intro {
  padding-top: 32px;
}

.page-intro .lede {
  max-width: 40em;
}

.crumbs ol {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 8px;
  list-style: none;
  padding: 0;
  margin: 0 0 20px;
  font-size: 14px;
  color: var(--caption);
}

.crumbs li {
  margin: 0;
}

.crumbs li + li::before {
  content: '/';
  margin-right: 8px;
  color: var(--edge);
}

.crumbs a {
  display: inline-block;
  padding-block: 4px;
  color: var(--caption);
}

/* Feature cards that are links: the whole card is the target. */
.link-cards {
  list-style: none;
  padding: 0;
  margin: 0;
}

.link-cards li {
  margin: 0;
  display: grid;
}

.link-card {
  color: inherit;
  text-decoration: none;
  transition:
    border-color 0.15s ease,
    transform 0.15s ease;
}

.link-card:hover,
.link-card:focus-visible {
  border-color: var(--accent);
  color: inherit;
  transform: translateY(-2px);
}

.link-cards.compact .feature {
  padding: 18px 20px;
  display: block;
}

.link-cards.compact h3 {
  font-size: 16px;
}

.link-cards.compact p {
  font-size: 14px;
}

.flow span {
  display: block;
}

.more-line {
  margin: 20px 0 0;
  font-size: 15px;
}

.prose {
  max-width: var(--readable);
  font-size: 17px;
  line-height: 1.65;
  color: var(--secondary);
}

@media (prefers-reduced-motion: reduce) {
  .link-card:hover,
  .link-card:focus-visible {
    transform: none;
  }
}

/* Landing page links into the generated pages. */
.chip-links.centre {
  justify-content: center;
}

.more-actions {
  margin-top: 28px;
}

.feature h3 a {
  display: inline-block;
  padding-block: 2px;
  color: inherit;
  text-decoration: none;
}

.feature h3 a:hover,
.feature h3 a:focus-visible {
  color: var(--accent-text);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Generated pages end with when they last changed and who wrote them. */
.page-updated {
  margin-block: 0 40px;
  font-size: 0.875rem;
  color: var(--caption);
}

/* In-page jumps (section chips, #early-access) land below the sticky header, not under it. */
h2[id],
section[id] {
  scroll-margin-top: 88px;
}

/* One visible focus ring in both themes for anything without its own. */
:where(a, button, summary):focus-visible {
  outline: 2px solid var(--accent-text);
  outline-offset: 2px;
  border-radius: 4px;
}

.page-updated a,
.post-meta a {
  color: inherit;
  text-underline-offset: 3px;
  white-space: nowrap;
}

/* The brand is always lower-case "log8", even inside upper-cased labels. */
.brand-case {
  text-transform: none;
}

/* Analytics consent (ga.js builds it; nothing shows without JavaScript). */
.consent {
  position: fixed;
  z-index: 50;
  inset-inline: 16px;
  bottom: 16px;
  max-width: 560px;
  margin-inline: auto;
  padding: 16px 18px;
  background: var(--raised);
  color: var(--ink);
  border: 1px solid var(--divider);
  border-radius: 16px;
  box-shadow: var(--shadow);
  font-size: 14px;
  line-height: 1.45;
}

.consent p {
  margin: 0 0 12px;
  color: var(--secondary);
}

.consent a {
  color: var(--accent-text);
}

.consent-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.consent button {
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}

/* ------------------------------------------- download page */

/* Default state: no href, so these are not focusable or clickable without JS. aria-disabled
   marks the intent for assistive tech; download.js adds a real href once a store URL exists. */
.store-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin: 20px 0;
}

.store-badge {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  background: var(--control);
  color: var(--secondary);
  text-decoration: none;
  border-radius: 14px;
  padding: 12px 18px;
  min-height: 56px;
  cursor: not-allowed;
}

.store-badge-icon {
  width: 28px;
  height: 28px;
  flex: none;
  color: var(--secondary);
}

.store-badge-text {
  display: flex;
  flex-direction: column;
  line-height: 1.3;
}

.store-badge-eyebrow {
  font-size: 12px;
}

.store-badge-name {
  font-size: 17px;
  font-weight: 700;
  color: var(--ink);
}

/* Once download.js fills in a real href, the badge behaves and looks like a normal link. */
.store-badge[href] {
  cursor: pointer;
  background: var(--card);
  transition:
    background-color 0.15s ease,
    transform 0.15s ease;
}

.store-badge[href]:hover,
.store-badge[href]:focus-visible {
  background: var(--control-pressed);
  transform: translateY(-2px);
}

.store-badge[href] .store-badge-icon,
.store-badge[href] .store-badge-eyebrow {
  color: var(--secondary);
}

/* Platform match: highlights the badge for the visitor's own device. Pure enhancement; the page
   is identical without JS, just without the highlight. */
.store-badge-match {
  box-shadow: 0 0 0 2px var(--accent) inset;
}

@media (max-width: 400px) {
  .store-badges {
    flex-direction: column;
  }
  .store-badge {
    width: 100%;
  }
}
