/*
 * stashgame.net — the one stylesheet (spec 2026-10-03-website-design.md).
 *
 * Every colour below is copied BY HAND from constants/theme.ts — the brand
 * palette, the dark and light colour sets, and the Glass Radar tokens
 * (glass, ground, glow) of 1.28.0. This folder has no build step to import
 * them from, so that file and this one are the only two places a Stash hex
 * value may live (CLAUDE.md, "Brand"). __tests__/web-site.test.ts checks the
 * palette and the light substitutions against the real tokens.
 *
 * Contrast (WCAG, recomputed by the test from the tokens):
 *   off-white on charcoal 18.32 · muted #9A9A94 on charcoal 6.96 ·
 *   lime text on charcoal 14.90 · gold text on charcoal 12.52 ·
 *   charcoal on lime 14.90 · charcoal on gold 12.52 ·
 *   light: #657A00 on off-white 4.51 · #8F6900 4.67 · #5F5F5A 5.97.
 *
 * No `style=` attribute and no `\3c style>` block exists in any page: the
 * Content-Security-Policy in _headers allows neither.
 */

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('/fonts/Inter-300.ttf') format('truetype');
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/Inter-400.ttf') format('truetype');
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/Inter-600.ttf') format('truetype');
}

:root {
  /* brand (constants/theme.ts `brand`) */
  --lime: #c7f000;
  --charcoal: #0b0b0b;
  --off-white: #f7f7f2;
  --sage: #9cb89b;
  --purple: #a78bfa;
  --coral: #ff684a;
  --gold: #ffc629;

  /* dark colours (`darkColors`) — the default, as the app is dark-first */
  --bg: var(--charcoal);
  --surface: #151515;
  --surface-elevated: #1e1e1e;
  --border: #262626;
  --text: var(--off-white);
  --text-muted: #9a9a94;
  --signal: var(--lime);
  --on-signal: var(--charcoal);
  --signal-text: var(--lime);
  --gold-text: var(--gold);
  --coral-text: var(--coral);

  /* glass (`darkGlass`) */
  --glass-fill: rgba(247, 247, 242, 0.06);
  --glass-elevated: rgba(247, 247, 242, 0.1);
  --glass-edge: rgba(247, 247, 242, 0.14);
  --glass-border: rgba(247, 247, 242, 0.08);
  --glass-floating-under: rgba(11, 11, 11, 0.94);
  --glass-muted: rgba(247, 247, 242, 0.65);

  /* ground (`darkGround`) */
  --ground-ambient: rgba(247, 247, 242, 0.04);
  --ground-grid: rgba(247, 247, 242, 0.045);

  /* glow (`darkGlow`, Subtle): button 0.165 / 6 / 15, selected 0.18 / 3 / 9 */
  --glow-button: 0 6px 15px rgba(199, 240, 0, 0.165);
  --glow-button-gold: 0 6px 15px rgba(255, 198, 41, 0.165);
  --glow-selected: 0 3px 9px rgba(199, 240, 0, 0.18);

  /* the map's own ground, the same in both themes (`map.groundFill`) */
  --map-ground: #1b2117;
  --map-grid: rgba(247, 247, 242, 0.045);

  color-scheme: dark;
}

@media (prefers-color-scheme: light) {
  :root {
    /* light colours (`lightColors`) */
    --bg: var(--off-white);
    --surface: #edede8;
    --surface-elevated: #ffffff;
    --border: #e4e4de;
    --text: var(--charcoal);
    --text-muted: #5f5f5a; /* 5.97:1 on off-white */
    --signal-text: #657a00; /* 4.51:1 on off-white (LIGHT signalText) */
    --gold-text: #8f6900; /* 4.67:1 (LIGHT_LEGENDARY_TEXT) */
    --coral-text: #db2400; /* 4.58:1 (LIGHT_EVENT_TEXT) */

    /* glass (`lightGlass`) */
    --glass-fill: rgba(255, 255, 255, 0.55);
    --glass-elevated: rgba(255, 255, 255, 0.72);
    --glass-edge: rgba(255, 255, 255, 0.9);
    --glass-border: rgba(11, 11, 11, 0.06);
    --glass-floating-under: rgba(255, 255, 255, 0.9);
    --glass-muted: rgba(11, 11, 11, 0.65);

    /* ground (`lightGround`) */
    --ground-ambient: rgba(255, 255, 255, 0.7);
    --ground-grid: rgba(11, 11, 11, 0.04);

    /* glow (`lightGlow`): in the text shades, 0.18 */
    --glow-button: 0 6px 15px rgba(101, 122, 0, 0.18);
    --glow-button-gold: 0 6px 15px rgba(143, 105, 0, 0.18);
    --glow-selected: 0 3px 9px rgba(101, 122, 0, 0.18);

    color-scheme: light;
  }
}

/* ---------------------------------------------------------------- base */

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

html {
  -webkit-text-size-adjust: 100%;
  /* The sticky header never covers a focused link or an anchor target (WCAG 2.2 SC 2.4.11). */
  scroll-padding-top: 6rem;
}

body {
  margin: 0;
  min-height: 100vh;
  color: var(--text);
  font-family:
    'Inter',
    -apple-system,
    BlinkMacSystemFont,
    'Segoe UI',
    sans-serif;
  font-size: 1rem;
  line-height: 1.55;
  /* The radar ground (GR2, GR5): the page colour, a neutral light from the
     top centre fading by 62% of the height, and the 28 px grid. */
  background-color: var(--bg);
  background-image:
    radial-gradient(60% 40% at 50% 0%, var(--ground-ambient), transparent 62%),
    linear-gradient(var(--ground-grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--ground-grid) 1px, transparent 1px);
  background-size:
    100% 100%,
    28px 28px,
    28px 28px;
}

a {
  color: var(--signal-text);
}

a:focus-visible,
button:focus-visible,
summary:focus-visible {
  outline: 3px solid var(--signal-text);
  outline-offset: 3px;
  border-radius: 4px;
}

h1,
h2,
h3 {
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.15;
  margin: 0 0 0.5rem;
}

h1 {
  font-size: 2.5rem;
}
h2 {
  font-size: 1.75rem;
}
h3 {
  font-size: 1.1875rem;
}

p,
li {
  margin: 0 0 0.75rem;
}

.muted {
  color: var(--glass-muted);
}

.eyebrow {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 0 0 0.5rem;
}

/* The skip link: first in the tab order, visible only when focused. */
.skip {
  position: absolute;
  left: -999px;
  top: 0.5rem;
  z-index: 100;
  padding: 0.625rem 0.75rem;
  min-height: 44px;
  border-radius: 0.5rem;
  background: var(--lime);
  color: var(--charcoal);
  font-weight: 600;
  text-decoration: none;
}
.skip:focus {
  left: 0.5rem;
}

/* --------------------------------------------------------- site header */

.site-header {
  position: sticky;
  top: 0;
  z-index: 10;
  background: var(--glass-floating-under);
  border-bottom: 1px solid var(--glass-border);
}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .site-header {
    background: var(--glass-elevated);
    -webkit-backdrop-filter: blur(28px);
    backdrop-filter: blur(28px);
  }
}
.site-header .bar {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0.75rem 1.25rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  color: var(--text);
  text-decoration: none;
  font-weight: 600;
  letter-spacing: 0.18em;
  min-height: 44px;
}
.brand svg {
  width: 1.25rem;
  height: 1.25rem;
}
.site-nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  gap: 0.25rem;
  flex-wrap: wrap;
}
.site-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 0.75rem;
  color: var(--text);
  text-decoration: none;
  font-size: 0.9375rem;
  border-radius: 999px;
}
.site-nav a:hover {
  background: var(--glass-fill);
}

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

.btn,
.btn-secondary,
.btn-gold {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0.75rem 1.25rem;
  border-radius: 999px;
  font-weight: 600;
  font-size: 1rem;
  text-decoration: none;
  border: 1px solid transparent;
}
.btn {
  background: var(--lime);
  color: var(--charcoal);
  box-shadow: var(--glow-button);
}
.btn-secondary {
  background: var(--glass-fill);
  color: var(--text);
  border-color: var(--glass-border);
}
.btn-gold {
  background: var(--gold);
  color: var(--charcoal);
  box-shadow: var(--glow-button-gold);
}

/* The launch state (WS9): one attribute on <html> decides which CTA shows. */
.cta-live {
  display: inline-flex;
  gap: 0.75rem;
  flex-wrap: wrap;
}

html[data-launch='soon'] .cta-live,
html[data-launch='live'] .cta-soon {
  display: none;
}

/* --------------------------------------------------------- legal pages */

.article {
  max-width: 680px;
  margin: 0 auto;
  padding: 2rem 1.25rem 4rem;
}
.article h1 {
  font-size: 2rem;
}
.article h2 {
  font-size: 1.1875rem;
  margin: 2.25rem 0 0.5rem;
}
.article ul {
  padding-left: 1.25rem;
}
.article ol {
  padding-left: 1.25rem;
}
.article li {
  margin: 0.375rem 0;
}
.article .marker {
  font-weight: 600;
  color: var(--coral-text);
}

/* ----------------------------------------------------------- footer */

.footer {
  border-top: 1px solid var(--glass-border);
  margin-top: 2rem;
}
.footer .inner {
  max-width: 1100px;
  margin: 0 auto;
  padding: 1.75rem 1.25rem 2.25rem;
  font-size: 0.875rem;
  color: var(--glass-muted);
}
.footer ul {
  list-style: none;
  margin: 0 0 0.75rem;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 0.5rem;
}
.footer li a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 0.5rem;
  color: var(--text);
  text-decoration: none;
}
.footer li a:hover {
  text-decoration: underline;
}
.footer p {
  margin: 0.25rem 0;
}

/* ---------------------------------------------------------- 404 page */

.not-found {
  max-width: 680px;
  margin: 0 auto;
  padding: 6rem 1.25rem 4rem;
  text-align: center;
}

/* ---------------------------------------------------- shared-run page */
/* The 1.16.0 run page's own rules, moved here verbatim from the old
   index.html's \3c style> block (the CSP forbids inline styles). */

.run main {
  width: 100%;
  max-width: 480px;
  margin: 0 auto;
  padding: 1.5rem 1rem 3rem;
}
.run .eyebrow {
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  margin: 0 0 4px;
}
.run .hero {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin: 8px 0 24px;
  padding: 0;
  grid-template-columns: none;
}
.hero-value {
  font-size: 3.5rem;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.hero-unit {
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--signal-text);
}
.stats {
  display: flex;
  gap: 16px;
  margin-bottom: 24px;
}
.stat {
  flex: 1;
  min-width: 0;
}
.stat-label {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 0 0 4px;
}
.stat-value {
  font-size: 1.25rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  margin: 0;
}
.route-box {
  /* The map's ground is dark in both themes, as the app's map is. */
  background: var(--map-ground);
  border-radius: 16px;
  overflow: hidden;
  margin-bottom: 24px;
  aspect-ratio: 1 / 1;
}
.route-box svg {
  display: block;
  width: 100%;
  height: 100%;
}
.laps {
  margin-bottom: 24px;
}
.laps h2 {
  font-size: 0.9375rem;
  font-weight: 600;
  margin: 0 0 12px;
}
.lap-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 0;
  border-bottom: 1px solid var(--border);
  font-size: 0.875rem;
  font-variant-numeric: tabular-nums;
}
.lap-row:last-child {
  border-bottom: none;
}
.lap-index {
  width: 24px;
  color: var(--text-muted);
}
.lap-cell {
  flex: 1;
}
.lap-fastest {
  color: var(--signal-text);
}
.shared-by {
  font-size: 0.875rem;
  color: var(--text-muted);
  margin: 0 0 32px;
}
.cta {
  display: block;
  text-align: center;
  background: var(--lime);
  color: var(--charcoal);
  font-weight: 600;
  font-size: 1rem;
  text-decoration: none;
  padding: 14px 20px;
  border-radius: 999px;
  box-shadow: var(--glow-button);
}
.state {
  padding: 64px 0;
  text-align: center;
}
.state h1 {
  font-size: 1.25rem;
  margin: 0 0 8px;
}
.state p {
  font-size: 0.9375rem;
  color: var(--text-muted);
  margin: 0 0 24px;
}
.loading-dot {
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: var(--text-muted);
  margin: 0 auto;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
  }
}

/* ---------------------------------------------------------- narrow */

/* A tablet or a phone. The header is one row, the brand and the TikTok pill,
   from the width where it stops sticking: the home page's sections are a
   scroll away and every footer carries the legal links. */
@media (max-width: 820px) {
  h1 {
    font-size: 2rem;
  }
  .site-header {
    position: static;
  }
  .site-header .bar {
    flex-wrap: nowrap;
    padding-top: 0.5rem;
    padding-bottom: 0.5rem;
  }
  .site-nav {
    display: none;
  }
  .site-header .follow {
    padding-top: 0.5rem;
    padding-bottom: 0.5rem;
  }
}

/* -------------------------------------------------------- home v4 */
/* Spec 2026-10-04-website-home-v4-design (HV1–HV14). The owner's reference
   structure, every picture the app itself, drawn as the paywall proposal
   draws it (docs/design/2026-10-03-plus-paywall-touchpoints.html). Built from
   three generated sheets: the reference page's rules (re-tokenised, every
   selector under :where(.home) so its specificity, and so the cascade the
   owner approved, is unchanged), the paywall's rules scoped under .pw with
   the class map of the drawings' inline values, and the glue that places the
   phones. Every per-element value is a class — the CSP forbids inline styles.
   Since the fifth draft (SY17) the page hero's, "Sound familiar"'s and the
   chapters' rules are gone with their sections; what is left styles the
   sections that still stand under the story (`.pw .hero` is a phone's own
   hero, not the page's). */

/* The home page is charcoal and cream whatever the OS theme (HV2): the
   phones are the app's dark UI, and the sections alternate on their own. */
body.home {
  --bg: var(--charcoal);
  --surface: #151515;
  --surface-elevated: #1e1e1e;
  --border: #262626;
  --text: var(--off-white);
  --text-muted: #9a9a94; /* 6.96:1 on charcoal */
  --signal-text: var(--lime);
  --gold-text: var(--gold);
  --coral-text: var(--coral);
  --glass-fill: rgba(247, 247, 242, 0.06);
  --glass-elevated: rgba(247, 247, 242, 0.1);
  --glass-edge: rgba(247, 247, 242, 0.14);
  --glass-border: rgba(247, 247, 242, 0.08);
  --glass-floating-under: rgba(11, 11, 11, 0.94);
  --glass-muted: rgba(247, 247, 242, 0.65);
  --glow-button: 0 6px 15px rgba(199, 240, 0, 0.165);
  --glow-button-gold: 0 6px 15px rgba(255, 198, 41, 0.165);
  --glow-selected: 0 3px 9px rgba(199, 240, 0, 0.18);
  color-scheme: dark;
  background: var(--charcoal);
  color: var(--off-white);
}
/* the reference's reading measure; the header and the footer keep the site's own */
:where(.home) main {
  line-height: 1.65;
}
/* the cream sections read in the app's light text tokens (HV2, HV12) */
:where(.home) .light,
:where(.home) .end {
  --text-muted: #5f5f5a; /* 5.97:1 on off-white */
  --signal-text: #657a00; /* 4.51:1 — the focus ring on cream */
}
/* The header stays charcoal over the cream sections too, as the reference's did. */
body.home .site-header {
  background: var(--glass-floating-under);
}
@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}
:where(.home) a:focus-visible,
:where(.home) summary:focus-visible {
  outline: 3px solid var(--signal-text);
  outline-offset: 5px;
}
:where(.home) .btn,
:where(.home) .btn-secondary {
  gap: 0.625rem;
}

:where(.home) a {
  color: inherit;
  text-decoration: none;
}
:where(.home) button {
  font: inherit;
  cursor: pointer;
}
:where(.home) button,
:where(.home) a,
:where(.home) summary {
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
:where(.home) h1,
:where(.home) h2,
:where(.home) h3,
:where(.home) p {
  margin: 0;
}
:where(.home) h1,
:where(.home) h2,
:where(.home) h3 {
  font-weight: 600;
  letter-spacing: -0.045em;
  line-height: 1.08;
}
:where(.home) h1 {
  font-size: clamp(48px, 6.6vw, 86px);
}
:where(.home) h2 {
  font-size: clamp(34px, 4.5vw, 57px);
}
:where(.home) h3 {
  font-size: 22px;
}
:where(.home) main p {
  color: var(--text-muted);
}
:where(.home) .wrap {
  max-width: 1190px;
  margin: auto;
  padding: 0 42px;
}
:where(.home) .eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.16em;
  font-size: 11px;
  font-weight: 600;
  margin-bottom: 22px;
}
:where(.home) .light {
  background: var(--off-white);
  color: var(--charcoal);
}
:where(.home) .section {
  padding: 83px 0;
}
:where(.home) .center {
  text-align: center;
  max-width: 700px;
  margin: 0 auto 38px;
}
:where(.home) .center > p:not(.eyebrow) {
  margin: 20px auto 0;
  max-width: 500px;
}
:where(.home) .visual {
  border-radius: 22px;
  position: relative;
  background: var(--map-ground);
  border: 1px solid #363e2e; /* not text */
}
:where(.home) .avatar {
  width: 37px;
  height: 37px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 12px;
  flex: none;
}
:where(.home) .together {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 80px;
  align-items: center;
}
:where(.home) .together p {
  margin-top: 22px;
  max-width: 405px;
}
:where(.home) .board {
  background: #fff; /* not text */
  border: 1px solid #deded6; /* not text */
  border-radius: 22px;
  padding: 27px;
  transform: rotate(2deg);
  box-shadow: 0 18px 45px #0b0b0b09; /* not text */
}
:where(.home) .board-head {
  display: flex;
  justify-content: space-between;
  gap: 15px;
  font-size: 13px;
  margin-bottom: 20px;
}
:where(.home) .board-head span {
  font-size: 11px;
  color: var(--text-muted); /* #5f5f5a, 6.42:1 on #fff */
}
:where(.home) .rank {
  display: flex;
  gap: 13px;
  align-items: center;
  padding: 16px 10px;
  border-bottom: 1px solid #eeeee7; /* not text */
}
:where(.home) .rank:last-child {
  border: 0;
}
:where(.home) .rank > span:first-child {
  font-size: 12px;
  color: var(--text-muted); /* #5f5f5a, 6.42:1 on #fff */
  min-width: 12px;
}
:where(.home) .rank .avatar {
  background: #e3e9da; /* not text */
  color: #47503c; /* 6.83:1 on #e3e9da */
}
:where(.home) .rank strong {
  font-size: 13px;
}
:where(.home) .rank small {
  display: block;
  font-size: 11px;
  color: var(--text-muted); /* #5f5f5a, 6.42:1 on #fff */
}
:where(.home) .rank > b {
  margin-left: auto;
  font-size: 15px;
  font-weight: 600;
}
:where(.home) .rank.me {
  background: var(--lime);
  border-radius: 11px;
  border-bottom: 0;
}
:where(.home) .rank.me .avatar {
  background: var(--charcoal);
  color: var(--lime);
}
:where(.home) .rank.me small {
  color: #454c21; /* 6.88:1 on lime */
}
/* the board's disclaimer; .together .sample outranks .together p's margin */
:where(.home) .together .sample {
  font-size: 11px;
  color: var(--text-muted);
  text-align: center;
  margin-top: 16px;
}
:where(.home) .life {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 30px;
  margin-top: 44px;
}
:where(.home) .life article {
  border-top: 1px solid #43443c; /* not text */
  padding: 25px 0;
}
:where(.home) .life h3 {
  font-size: 20px;
  margin-bottom: 13px;
}
:where(.home) .life p {
  font-size: 14px;
}
:where(.home) .life .eyebrow {
  color: var(--sage);
  margin-bottom: 22px;
}
:where(.home) .privacy-strip {
  display: flex;
  align-items: center;
  gap: 55px;
  border-top: 1px solid #34342b; /* not text */
  border-bottom: 1px solid #34342b; /* not text */
  padding: 30px 0;
}
:where(.home) .privacy-strip h2 {
  font-size: 21px;
  min-width: 230px;
}
:where(.home) .privacy-strip p {
  font-size: 13px;
}
:where(.home) .privacy-strip a {
  white-space: nowrap;
  font-size: 12px;
  border-bottom: 1px solid #777; /* not text */
  padding: 12px 0;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}
:where(.home) .faq {
  max-width: 730px;
  margin: auto;
  padding: 75px 24px;
}
:where(.home) .faq h2 {
  text-align: center;
  margin-bottom: 35px;
  font-size: 39px;
}
:where(.home) details {
  border-bottom: 1px solid #36362d; /* not text */
  padding: 0 3px;
}
:where(.home) summary {
  list-style: none;
  cursor: pointer;
  padding: 20px 30px 20px 0;
  font-size: 15px;
  position: relative;
}
:where(.home) summary::-webkit-details-marker {
  display: none;
}
:where(.home) summary:after {
  content: '+';
  position: absolute;
  right: 3px;
  font-size: 23px;
  top: 13px;
  color: var(--sage);
}
:where(.home) details[open] summary:after {
  content: '−';
}
:where(.home) details a {
  text-decoration: underline;
}
:where(.home) details p {
  font-size: 14px;
  padding: 0 25px 22px 0;
}
:where(.home) .end {
  text-align: center;
  padding: 69px 24px;
  background: var(--off-white);
  color: var(--charcoal);
}
:where(.home) .end .eyebrow {
  color: #587a57; /* 4.51:1 on off-white */
}
:where(.home) .end p {
  color: var(--text-muted); /* #5f5f5a, 5.97:1 on off-white */
  max-width: 430px;
  margin: 23px auto;
}
:where(.home) .end .btn-secondary {
  background: var(--charcoal);
  color: var(--off-white);
  border-color: var(--charcoal);
}
:where(.home) .end .btn-secondary:hover {
  background: #303529; /* not text */
}
:where(.home) .end .launch {
  display: block;
  font-size: 11px;
  color: var(--text-muted); /* #5f5f5a, 5.97:1 on off-white */
  margin-top: 16px;
}
/* The live launch state (WS9's one-attribute flip): the store links on their
   own line under the button, each a 44 px target (HV12). :where() keeps these
   under html[data-launch='soon'] .cta-live, which hides them until launch. */
:where(.home) .launch.cta-live {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 0.75rem 1.25rem;
  margin-top: 14px;
}
:where(.home) .cta-live .sep {
  font-size: 14px;
}
:where(.home) .cta-live a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 0.75rem;
  font-size: 14px;
  color: var(--text);
  text-decoration: underline;
  text-underline-offset: 3px;
}
:where(.home) .end .cta-live a {
  color: var(--charcoal);
}
@media (max-width: 900px) {
  :where(.home) .wrap {
    padding-left: 26px;
    padding-right: 26px;
  }
  :where(.home) .together {
    gap: 40px;
  }
  :where(.home) .privacy-strip {
    gap: 25px;
    flex-wrap: wrap;
  }
  :where(.home) .life {
    gap: 20px;
  }
}
@media (max-width: 650px) {
  :where(.home) .wrap {
    padding-left: 22px;
    padding-right: 22px;
  }
  :where(.home) .section {
    padding: 56px 0;
  }
  :where(.home) .center {
    margin-bottom: 28px;
  }
  :where(.home) .center > p:not(.eyebrow) {
    font-size: 15px;
  }
  :where(.home) .together {
    grid-template-columns: 1fr;
    gap: 30px;
  }
  :where(.home) .together h2 {
    font-size: 36px;
  }
  :where(.home) .board {
    padding: 22px;
    transform: none;
  }
  :where(.home) .life {
    grid-template-columns: 1fr;
    gap: 7px;
    margin-top: 30px;
  }
  :where(.home) .life article {
    padding: 22px 0;
  }
  :where(.home) .life .eyebrow {
    margin-bottom: 12px;
  }
  :where(.home) .privacy-strip {
    gap: 18px;
    align-items: start;
  }
  :where(.home) .privacy-strip h2 {
    min-width: 0;
  }
  :where(.home) .privacy-strip p {
    flex-basis: 100%;
  }
  :where(.home) .faq {
    padding: 50px 22px;
  }
  :where(.home) .faq h2 {
    font-size: 34px;
  }
  :where(.home) .end {
    padding: 50px 22px;
  }
  /* the store links stack here; a dot left at the end of a row reads as litter */
  :where(.home) .cta-live .sep {
    display: none;
  }
}
/* -- the paywall proposal's drawings (docs/design/2026-10-03-plus-paywall-touchpoints.html), scoped under .pw, and their class map */
.pw {
  --bg: #0b0b0b;
  --border: #262626;
  --text: #f7f7f2;
  --muted: #9a9a94;
  --lime: #c7f000;
  --gold: #ffc629;
  --ground: #1b2117;
  --grid: rgba(199, 240, 0, 0.07);
  --font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  --safe-top: 14px;
  font-family: var(--font);
  background: var(--off-white);
  color: var(--charcoal);
  -webkit-font-smoothing: antialiased;
  line-height: 1.55;
}
.pw * {
  box-sizing: border-box;
}
.pw .phone {
  width: 375px;
  height: 812px;
  background: var(--bg);
  color: var(--text);
  border-radius: 44px;
  border: 6px solid #1f1f1f;
  box-shadow: 0 20px 60px rgba(11, 11, 11, 0.25);
  overflow: hidden;
  position: relative;
  font-family: var(--font);
  line-height: 1.35;
}
.pw .statusbar {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: var(--safe-top);
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  padding: 0 28px 10px;
  font-size: 15px;
  font-weight: 600;
  z-index: 60;
  pointer-events: none;
}
.pw .statusbar .dyn {
  position: absolute;
  top: 12px;
  left: 50%;
  transform: translateX(-50%);
  width: 120px;
  height: 34px;
  border-radius: 20px;
  background: #000;
}
.pw .p-eyebrow {
  font-size: 11px;
  line-height: 14px;
  font-weight: 600;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--muted);
}
.pw .gold {
  color: var(--gold);
}
@keyframes rise {
  from {
    transform: translateY(24px);
    opacity: 0;
  }
  to {
    transform: none;
    opacity: 1;
  }
}
.pw .hero {
  position: relative;
  height: 334px;
  overflow: hidden;
  background:
    radial-gradient(
      120% 80% at 50% 0%,
      rgba(255, 198, 41, 0.2),
      rgba(255, 198, 41, 0.04) 55%,
      transparent 75%
    ),
    var(--bg);
  padding: calc(var(--safe-top) + 6px) 20px 0;
  /* the page's own .hero centres its text; a phone screen does not inherit it */
  text-align: left;
}
.pw .hero::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 56px;
  background: linear-gradient(to bottom, transparent, var(--bg));
  pointer-events: none;
}
.pw .hero.tall {
  height: 400px;
}
.pw .hp {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.pw .hp-top {
  display: flex;
  align-items: center;
  height: 34px;
  padding-left: 44px;
}
.pw .bars {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  height: 72px;
}
.pw .bar {
  flex: 1;
  border-radius: 5px 5px 2px 2px;
  background: rgba(247, 247, 242, 0.34);
  transform-origin: bottom;
  animation: grow 0.7s cubic-bezier(0.2, 0.8, 0.2, 1) both;
  animation-delay: calc(var(--i) * 70ms + 150ms);
  position: relative;
}
.pw .bar.now {
  background: var(--lime);
}
.pw .bar.light {
  background: rgba(247, 247, 242, 0.2);
}
.pw .bar.race {
  background: var(--gold);
}
@keyframes grow {
  from {
    transform: scaleY(0);
  }
  to {
    transform: scaleY(1);
  }
}
.pw .barlbl {
  display: flex;
  justify-content: space-between;
  font-size: 10px;
  color: var(--muted);
  letter-spacing: 0.3px;
}
.pw .sess {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.pw .ses {
  display: flex;
  align-items: center;
  gap: 10px;
  background: rgba(21, 21, 21, 0.9);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 7px 10px;
  font-size: 13px;
  animation: rise 0.5s cubic-bezier(0.2, 0.8, 0.2, 1) both;
  animation-delay: calc(var(--i) * 140ms + 1000ms);
}
.pw .ses .d {
  width: 30px;
  font-weight: 700;
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.5px;
  text-transform: uppercase;
}
.pw .ses .k {
  font-weight: 600;
}
.pw .ses .m {
  margin-left: auto;
  color: var(--muted);
  font-size: 12px;
}
.pw .ses.today {
  border-color: rgba(199, 240, 0, 0.5);
}
.pw .ses.today .d {
  color: var(--lime);
}

/* inline styles of the drawings, as classes (the CSP allows no style attribute) */
.pw .t-lime {
  color: #c7f000;
}
.pw .i-0 {
  --i: 0;
}
.pw .i-1 {
  --i: 1;
}
.pw .i-2 {
  --i: 2;
}
.pw .i-3 {
  --i: 3;
}
.pw .i-4 {
  --i: 4;
}
.pw .i-5 {
  --i: 5;
}
.pw .i-6 {
  --i: 6;
}
.pw .i-7 {
  --i: 7;
}
.pw .i-8 {
  --i: 8;
}
.pw .i-9 {
  --i: 9;
}
.pw .h-42 {
  height: 42%;
}
.pw .h-50 {
  height: 50%;
}
.pw .h-58 {
  height: 58%;
}
.pw .h-40 {
  height: 40%;
}
.pw .h-66 {
  height: 66%;
}
.pw .h-74 {
  height: 74%;
}
.pw .h-82 {
  height: 82%;
}
.pw .h-56 {
  height: 56%;
}
.pw .h-70 {
  height: 70%;
}
.pw .h-34 {
  height: 34%;
}
/* -- the glue: the phones' placement, the in-screen glass pieces and their animations */
.pw .phone {
  margin: 0 auto;
}
:where(.home) .phonewrap {
  position: absolute;
  left: 50%;
  top: 0;
  transform: translateX(-50%) scale(0.62);
  transform-origin: top center;
}
:where(.home) .visual {
  height: 540px;
  overflow: visible;
}
:where(.home) .visual .phonewrap {
  top: 16px;
}
/* the strip's flex row and its -20px margins are what the approved preview
   drew (the paywall's scroller, measured: nothing else of it showed) */
:where(.home) .bigger {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 60px;
  align-items: center;
  margin-top: 44px;
}
:where(.home) .bigger .life {
  grid-template-columns: 1fr;
  gap: 0;
  margin-top: 0;
}
@media (max-width: 900px) {
  :where(.home) .bigger {
    grid-template-columns: 1fr;
    gap: 30px;
  }
}
:where(.home) .visual.crop {
  height: 430px;
  overflow: hidden;
  border-radius: 22px;
}
:where(.home) .visual.crop .phonewrap {
  top: 0;
  transform: translateX(-50%) scale(0.98);
}
:where(.home) .visual.crop .pw .phone {
  border-bottom: 0;
  border-radius: 44px 44px 0 0;
}

/* -- the approved preview centred these pieces through the page hero's
   text-align, which .pw .hero no longer inherits: kept on them explicitly */
.pw .ses .d {
  text-align: center;
}

/* -- what the site's shared run-page rules would otherwise add inside a phone */

/* -- a block plays when home.js marks it .on (HV10); until then its drawings
   wait at their first frame. The hero and the before/after phones play at once. */
html:not(.no-js) [data-scene]:not(.on) .pw *,
html:not(.no-js) [data-scene]:not(.on) .pw *::before,
html:not(.no-js) [data-scene]:not(.on) .pw *::after {
  animation-play-state: paused;
}

/* the board's rows rise in */
.home main [data-scene] .rise {
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity 0.6s ease,
    transform 0.6s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.home main [data-scene].on .rise {
  opacity: 1;
  transform: none;
}
.home main [data-scene].on .rise:nth-child(2) {
  transition-delay: 0.08s;
}
.home main [data-scene].on .rise:nth-child(3) {
  transition-delay: 0.16s;
}
.home main [data-scene].on .rise:nth-child(4) {
  transition-delay: 0.24s;
}

/* Reduce Motion: every drawing at its finished frame from the first paint (HV11) */
@media (prefers-reduced-motion: reduce) {
  .pw .ses,
  .pw .bar {
    opacity: 1;
    transform: none;
    animation: none !important;
  }
  /* the played frame: `fade` ends the side cards at full opacity */
  .home main [data-scene] .rise {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* No JavaScript: the same finished frames, nothing plays (HV11). Duplicated
   rather than shared, since a selector cannot span the media query. */
.no-js .pw .ses,
.no-js .pw .bar {
  opacity: 1;
  transform: none;
  animation: none !important;
}
.no-js .home main [data-scene] .rise {
  opacity: 1;
  transform: none;
  transition: none;
}

/* ------------------------------------------------- home v5: the story */
/* Spec 2026-10-05-website-home-story-scroll-design (SY1–SY20). The document
   is the fallback (SY3): nine beats down the page, words beside a still. With
   JavaScript on and motion allowed, home.js adds .live to .story: one stage is
   pinned for nine screens of scroll and redrawn from the scroll position
   (SY4). Nothing here or there writes an inline style (SY5). */
:where(.home) .story {
  background: var(--charcoal);
  --story-clear: 88px; /* the sticky header is 81 px tall */
  --story-top: 0px;
}
@media (min-width: 821px) {
  :where(.home) .story {
    --story-top: var(--story-clear);
  }
}
:where(.home) .story-view,
:where(.home) .story-sound[hidden] {
  display: none;
}
:where(.home) .beats {
  max-width: 980px;
  margin: 0 auto;
  padding: 63px 42px 96px;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 96px;
}
:where(.home) .beat {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 290px);
  gap: 56px;
  align-items: center;
}
:where(.home) .beat .eyebrow {
  margin-bottom: 16px;
}
:where(.home) .beat-copy > p:not(.eyebrow, .launch, .cue) {
  font-size: 18px;
  max-width: 30em;
  margin-top: 18px;
}
:where(.home) .still {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 28px;
  border: 1px solid var(--border);
}
/* The download button is a design until launch (SY12): not a link, not a
   control. One attribute on <html> swaps it for the store links (WS9). */
:where(.home) .launch.cta-soon {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  margin-top: 28px;
}
:where(.home) .end .launch.cta-soon {
  align-items: center;
  max-width: none;
}
:where(.home) .get {
  cursor: default;
  -webkit-user-select: none;
  user-select: none;
}
:where(.home) .soon {
  font-size: 13px;
  color: var(--text-muted);
}
:where(.home) .beat-copy > .cue {
  font-size: 13px;
  letter-spacing: 0.04em;
  margin-top: 26px;
}
:where(.home) .story .launch.cta-live {
  justify-content: flex-start;
  margin-top: 22px;
}

/* -- live: one pinned stage, the scroll plays it */
:where(.home) .story.live {
  height: 900vh;
  height: 900svh;
}
:where(.home) .story.live .story-pin {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  isolation: isolate;
}
/* The view sits behind the words: the pin is its own stacking context. */
:where(.home) .story.live .story-view {
  display: block;
  position: absolute;
  inset: 0;
  z-index: -1;
}
:where(.home) .story-svg {
  display: block;
  width: 100%;
  height: 100%;
}
:where(.home) .story-svg text {
  font-family: inherit;
}
:where(.home) .story.live .still {
  display: none;
}
:where(.home) .story.live .beats {
  max-width: none;
  margin: 0;
  padding: 22px 22px 52px;
  gap: 0;
  pointer-events: none;
  background: linear-gradient(
    var(--charcoal) 0%,
    rgba(11, 11, 11, 0.86) 58%,
    rgba(11, 11, 11, 0) 100%
  );
}
:where(.home) .story.live .beat {
  grid-area: 1 / 1;
  display: block;
  opacity: 0;
  transition: opacity 0.28s ease;
}
:where(.home) .story.live .beat.on {
  opacity: 1;
  pointer-events: auto;
}
:where(.home) .story.live .beat h1,
:where(.home) .story.live .beat h2 {
  font-size: clamp(28px, 8vw, 40px);
}
:where(.home) .story.live .beat .eyebrow {
  margin-bottom: 10px;
}
:where(.home) .story.live .beat-copy > p:not(.eyebrow, .launch, .cue) {
  font-size: 14.5px;
  line-height: 1.5;
  margin-top: 10px;
}
/* On a short phone the call to action sits at the foot of the stage, on the
   ground under the drawing, and the cue gives way; on a taller one both
   follow the words. */
:where(.home) .story.live .beat-copy > .launch {
  position: absolute;
  left: 22px;
  right: 22px;
  bottom: 70px;
  margin: 0;
}
:where(.home) .story.live .beat-copy > .cue {
  display: none;
}
@media (min-height: 700px) {
  :where(.home) .story.live .beat-copy > .launch {
    position: static;
    margin-top: 20px;
  }
  :where(.home) .story.live .beat-copy > .cue {
    display: block;
    margin-top: 18px;
  }
}
/* Bottom left: the phone in the drawing comes up on the right. */
:where(.home) .story-sound {
  position: absolute;
  left: 14px;
  bottom: 14px;
  min-height: 44px;
  padding: 0 16px;
  border-radius: 999px;
  border: 1px solid var(--glass-border);
  background: var(--glass-floating-under);
  color: var(--text);
  font-size: 13px;
  font-weight: 600;
}
:where(.home) .story-sound[aria-pressed='true'] {
  border-color: var(--text);
}
/* From 821 px the header sticks (it does not below). The pin still fills the
   screen and runs under it; its content starts below a clearance that is more
   than the header is tall, so no rule here needs the header's exact height. */
@media (min-width: 821px) {
  :where(.home) .story.live .story-pin {
    padding-top: var(--story-clear);
  }
}
/* Wide, or a phone on its side: the words left, the view right in a 9:16
   window (SY9). */
@media (min-width: 900px), (min-width: 560px) and (min-aspect-ratio: 1 / 1) {
  :where(.home) .story.live .story-pin {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 56px;
    max-width: 1190px;
    margin: 0 auto;
    padding-left: 42px;
    padding-right: 42px;
  }
  :where(.home) .story.live .story-view {
    position: relative;
    inset: auto;
    z-index: 0;
    order: 2;
    height: min(calc(100% - 48px), 760px);
    aspect-ratio: 9 / 16;
    border-radius: 32px;
    overflow: hidden;
    border: 1px solid var(--border);
  }
  :where(.home) .story.live .beats {
    order: 1;
    padding: 0;
    background: none;
  }
  :where(.home) .story.live .beat h1,
  :where(.home) .story.live .beat h2 {
    font-size: clamp(40px, 4.6vw, 66px);
  }
  :where(.home) .story.live .beat .eyebrow {
    margin-bottom: 18px;
  }
  :where(.home) .story.live .beat-copy > p:not(.eyebrow, .launch, .cue) {
    font-size: 18px;
    line-height: 1.6;
    margin-top: 18px;
  }
  /* No display here: the launch state (WS9) decides which of the pair shows. */
  :where(.home) .story.live .beat-copy > .launch {
    position: static;
    margin-top: 26px;
  }
  :where(.home) .story.live .beat-copy > .cue {
    display: block;
    margin-top: 22px;
  }
  /* In the view's top corner: its sky is never busy, and the words and the
     call to action have the left column to themselves. */
  :where(.home) .story-sound {
    left: auto;
    bottom: auto;
    right: 56px;
    top: calc(
      var(--story-top) + (100% - var(--story-top)) / 2 -
        min((100% - var(--story-top)) / 2 - 24px, 380px) + 14px
    );
  }
}
/* Two columns in a window under 900 px wide — a phone on its side, a split
   view: the same layout, set smaller so a beat fits its column. */
@media (min-width: 560px) and (max-width: 899px) and (min-aspect-ratio: 1 / 1) {
  :where(.home) .story.live .beat h1,
  :where(.home) .story.live .beat h2 {
    font-size: 30px;
  }
  :where(.home) .story.live .beat .eyebrow {
    margin-bottom: 8px;
  }
  :where(.home) .story.live .beat-copy > p:not(.eyebrow, .launch, .cue) {
    font-size: 15px;
    line-height: 1.5;
    margin-top: 8px;
  }
  :where(.home) .story.live .beat-copy > .launch {
    margin-top: 14px;
  }
  :where(.home) .story.live .beat-copy > .cue {
    display: none;
  }
}
@media (max-width: 700px) {
  :where(.home) .beats {
    padding: 43px 22px 72px;
    gap: 72px;
  }
  :where(.home) .beat {
    grid-template-columns: minmax(0, 1fr);
    gap: 28px;
  }
  :where(.home) .still {
    max-width: 280px;
    margin: 0 auto;
  }
}
