/*
  zonal.fit — one stylesheet for every page.

  Tokens are the app's, not the site's own: the chrome neutrals are DesignKit's Theme.Palette
  (Packages/DesignKit/Sources/DesignKit/Theme.swift) and the zone ramp is WorkoutPhase.screenTint
  (WorkoutPhase+Visual.swift). If a hex changes there, change it here in the same commit — the site
  should never drift from what the rider sees on the phone.

  "Circuit" (PRD §14): dark only, cool graphite, hairlines instead of shadows, and the zone ramp as
  the only colour. The ramp is rationed so it means something: the hero wordmark, the zone walk,
  and the real screenshots. Chrome everywhere else stays graphite (the footer wordmark sits unlit).

  Motion, all of it:
   - the hero wordmark's underlines easing on Z1 → Z5 once on load, like the room coming up;
   - the zone walk: scroll-linked, the ground easing from one zone to the next as you scroll.
  Opacity only, slow, never a flash (PRD §15 is a photosensitivity rule, not a taste call). Both are
  static under prefers-reduced-motion, and the walk falls back to a plain table where scroll-driven
  animations aren't supported.

  CSP note: the site's Content-Security-Policy is style-src 'self' with no 'unsafe-inline', so no
  page may use a style="" attribute or a <style> block. Put every rule here.
*/

:root {
  /* Theme.Palette */
  --bg: #0A0D12;
  --surface: #121821;
  --raised: #1A2230;
  --hairline: #263140;
  --t1: #EDF1F7;
  --t2: #94A2B8;
  --t3: #7E8CA2;
  --accent: #3E7BFA;
  /* WorkoutPhase.warmUp.screenTint — the neutral ("no zone yet") */
  --neutral: #9AA8BD;
  /* Zone ramp, Zone 1–5 */
  --z1: #4A90E2;
  --z2: #43A047;
  --z3: #E3B341;
  --z4: #ED5A2D;
  --z5: #E23227;

  --sans: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  /* Rounded is reserved for big numerals, as in the app (Theme.Typography.timer). */
  --rounded: ui-rounded, "SF Pro Rounded", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  --max: 1160px;
  /* One reading measure for every text column (the left of a split, the FAQ, legal prose), so the
     page has two right edges: the container and this. ~70 characters of body copy. */
  --measure: 680px;
  --gutter: 16px;
  --section: clamp(56px, 7vw, 96px);
  --ease: cubic-bezier(.4, 0, .2, 1);
  color-scheme: dark;
}

@media (min-width: 768px) {
  :root { --gutter: 32px; }
}

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

/* No `scroll-behavior: smooth`, on purpose: an in-page jump (the nav's "How it works") would glide
   through the zone walk and run five zone colours past in under a second — the kind of rapid colour
   sequence the no-flashing rule exists to prevent. Anchor jumps are instant. */
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--t1);
  font-family: var(--sans);
  font-size: 1.0625rem;
  line-height: 1.6;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  /* Long unbroken strings (discovery.meethue.com, support@zonal.fit) wrap rather than widen the
     page at 200% zoom on a phone. */
  overflow-wrap: break-word;
}

img { max-width: 100%; height: auto; }

h1, h2, h3 {
  margin: 0;
  font-weight: 700;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

/* Type, in order: h1 (the claim), h2 (sections), h3 (items), body, meta. The hero wordmark and the
   zone walk's readout are display elements outside the scale, as they are in the app. */
h1 {
  font-size: clamp(2.25rem, 1.6rem + 2.4vw, 3.5rem);
  line-height: 1.04;
  letter-spacing: -0.03em;
}

h2 {
  font-size: clamp(1.625rem, 1.25rem + 1.5vw, 2.25rem);
  line-height: 1.1;
}

h2.h-small { font-size: clamp(1.5rem, 1.25rem + 0.9vw, 1.875rem); }

h3 {
  font-size: 1.1875rem;
  line-height: 1.3;
  font-weight: 650;
  letter-spacing: -0.01em;
}

p { margin: 0; text-wrap: pretty; }

/* Inline links: text colour with a hairline underline. Standalone links (.go) use the accent. */
a {
  color: var(--t1);
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--t1) 40%, transparent);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
  transition: text-decoration-color 160ms var(--ease), color 160ms var(--ease);
}

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

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

::selection { background: color-mix(in srgb, var(--accent) 45%, transparent); }

.skip {
  position: absolute;
  left: var(--gutter);
  top: -100px;
  z-index: 10;
  padding: 10px 14px;
  background: var(--raised);
  border: 1px solid var(--hairline);
  border-radius: 10px;
  text-decoration: none;
}

.skip:focus { top: 12px; }

.wrap {
  width: 100%;
  max-width: calc(var(--max) + 2 * var(--gutter));
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.lede {
  max-width: 34em;
  font-size: clamp(1.125rem, 1.05rem + 0.35vw, 1.3125rem);
  line-height: 1.5;
  color: var(--t2);
}

h2 + .lede { margin-top: 16px; }

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

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

/* ── Wordmark (ZonalWordmark.swift / "A" in designs/html/Zonal - Brand r2.html) ────────────────
   Lowercase, bold, each letter over its own zone-coloured bar: z·o·n·a·l = Zone 1–5. The bars follow
   the glyph widths on purpose (the "l" gets a short one). Geometry is the app's: bar 0.085em tall,
   inset 0.04em each side, 0.2em below the letter box. */

.wm {
  display: inline-flex;
  margin: 0;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1;
  color: var(--t1);
  text-decoration: none;
}

.wm span {
  position: relative;
  display: inline-block;
  padding-bottom: 0.2em;
}

.wm span::after {
  content: "";
  position: absolute;
  left: 0.04em;
  right: 0.04em;
  bottom: 0;
  height: 0.085em;
  min-height: 2px;
  border-radius: 1em;
  background: var(--zc);
}

.wm span:nth-child(1) { --zc: var(--z1); --i: 0; }
.wm span:nth-child(2) { --zc: var(--z2); --i: 1; }
.wm span:nth-child(3) { --zc: var(--z3); --i: 2; }
.wm span:nth-child(4) { --zc: var(--z4); --i: 3; }
.wm span:nth-child(5) { --zc: var(--z5); --i: 4; }

/* The hero wordmark: the bars start dim — present, like the session strip before a zone commits —
   and come up one after another, left to right, the way the room does on Start. */
.site-header .wm-hero { font-size: clamp(2rem, 1.6rem + 1.2vw, 2.5rem); }

.wm-hero span::after {
  opacity: 0.16;
  animation: zone-on 1400ms var(--ease) forwards;
  animation-delay: calc(450ms + var(--i) * 420ms);
}

@keyframes zone-on { to { opacity: 1; } }

/* Unlit: every bar dim, the wordmark's "no zone" state (footer, 404). */
.wm-idle span::after { opacity: 0.22; }

@media (prefers-reduced-motion: reduce) {
  .wm-hero span::after { animation: none; opacity: 1; }
}

/* ── The zone strip (ZoneStrip.swift): equal segments low → high, each numbered underneath so it
   never relies on colour alone. ──────────────────────────────────────────────────────────────── */

.strip {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 6px;
}

.strip span {
  position: relative;
  padding-top: 20px;
  text-align: center;
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1;
  color: var(--t3);
  font-variant-numeric: tabular-nums;
}

.strip span::before,
.strip span::after {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 8px;
  border-radius: 4px;
  background: var(--zc);
}

.strip span::after { display: none; }

.strip span:nth-child(1) { --zc: var(--z1); }
.strip span:nth-child(2) { --zc: var(--z2); }
.strip span:nth-child(3) { --zc: var(--z3); }
.strip span:nth-child(4) { --zc: var(--z4); }
.strip span:nth-child(5) { --zc: var(--z5); }

/* Data labels ("Heart rate", "Room", "On this page"): small, tracked capitals — the instrument's
   label voice, used only for labels, never as section eyebrows. */
.zone dt {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--t3);
}

/* ── Header ─────────────────────────────────────────────────────────────────────────────────── */

.site-header .wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  align-content: center; /* a wrapping flex row doesn't centre its line in min-height without this */
  justify-content: space-between;
  gap: 16px;
  min-height: 72px;
}

.site-header .wm { font-size: 1.5rem; }

.nav {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-left: auto;
  margin-right: -10px;
  font-size: 0.9375rem;
}

.nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: 10px;
  color: var(--t2);
  text-decoration: none;
  border-radius: 8px;
}

.nav a:hover,
.nav a[aria-current="page"] { color: var(--t1); }

/* Narrow phones drop "How it works" (an anchor into Home) so the wordmark and the other two links
   fit on one line. Same header on every page. */
@media (max-width: 479px) {
  .nav .nav-how { display: none; }
  .nav a { padding-inline: 8px; }
}

/* ── Sections and the two-column split ──────────────────────────────────────────────────────── */

.section {
  padding-block: var(--section);
  border-top: 1px solid var(--hairline);
}

/* Every two-column section uses this one split: text on the measure, the right column (a phone, an
   index, an aside) at 300 px on the container's right edge — so the right column starts at the
   same x all the way down the page. */
.split {
  display: grid;
  gap: 56px;
  align-items: center;
}

@media (min-width: 900px) {
  .split {
    grid-template-columns: minmax(0, var(--measure)) 300px;
    justify-content: space-between;
    gap: 56px;
  }
}

.split-top { align-items: start; }

/* Phone frame: a plain bezel around a real capture. No tilt, no reflections, no floating shadow. */
.phone {
  margin: 0;
  width: min(100%, 260px);
  justify-self: center;
  padding: 6px;
  border-radius: 44px;
  background: #05070A;
  border: 1px solid var(--hairline);
}

.phone img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 38px;
}

@media (min-width: 900px) {
  .phone { width: 300px; justify-self: end; border-radius: 48px; }
  .phone img { border-radius: 42px; }
}

/* ── Home: hero ─────────────────────────────────────────────────────────────────────────────── */

.hero { padding-block: clamp(24px, 5vw, 64px) var(--section); }

.hero-copy h1 { max-width: 12em; }

.hero-copy .lede { margin-top: 20px; }

/* "Coming soon" is a status, not a button: nothing to tap until the App Store link exists, so it's
   drawn like the app's status rows — text + dot, the dot in the neutral (waiting) steel. */
.status {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 14px;
  margin-top: 32px;
  font-size: 1rem;
}

.status-label {
  display: inline-flex;
  align-items: flex-start;
  gap: 10px;
  font-weight: 600;
}

/* Centred on the first line (line-height 1.6 → its middle is 0.8em down), so a wrapped label
   doesn't pull the dot to the middle of two lines. */
.status-label::before {
  content: "";
  flex: none;
  width: 8px;
  height: 8px;
  margin-top: calc(0.8em - 4px);
  border-radius: 50%;
  background: var(--neutral);
}

.status-meta { color: var(--t3); font-variant-numeric: tabular-nums; }

@media (max-width: 599px) {
  /* One status, two lines: the meta sits under the label, aligned with its text, not the dot. */
  .status { gap: 2px; }
  .status-meta { flex-basis: 100%; padding-left: 18px; font-size: 0.9375rem; }
}

/* ── Home: the zone walk ────────────────────────────────────────────────────────────────────────
   Default (reduced motion, browsers without scroll-driven animations, short viewports): a spec
   table — five rows on phones, five columns on wide screens. Otherwise the same section becomes the
   room: it pins to the viewport and, as you scroll, steps Zone 1 → Zone 5 — the ground eases to each
   zone's scene edge to edge (the app's session wash, at the app's strength), the big readout names
   the zone, and the table's column (the strip, on phones) lights. See the @supports block. */

.walk {
  padding-block: var(--section);
  border-top: 1px solid var(--hairline);
}

.washes,
.readouts,
.walk-strip { display: none; }

.zones {
  list-style: none;
  margin: 40px 0 0;
  padding: 0;
  display: grid;
}

.zone {
  position: relative;
  padding: 22px 0 22px 56px;
  border-top: 1px solid var(--hairline);
}

.zone:last-child { border-bottom: 1px solid var(--hairline); }

/* The zone's colour as a short bar — the number and the name carry the meaning, never the colour
   alone. */
.zone::before,
.zone::after {
  content: "";
  position: absolute;
  left: 0;
  top: 32px;
  width: 36px;
  height: 8px;
  border-radius: 4px;
  background: var(--zc);
}

.zone::after { display: none; }

.zone:nth-child(1) { --zc: var(--z1); }
.zone:nth-child(2) { --zc: var(--z2); }
.zone:nth-child(3) { --zc: var(--z3); }
.zone:nth-child(4) { --zc: var(--z4); }
.zone:nth-child(5) { --zc: var(--z5); }

.zone-n { color: var(--t3); font-weight: 600; }

.zone-desc {
  margin-top: 6px;
  color: var(--t2);
  font-size: 1rem;
}

.zone dl {
  margin: 12px 0 0;
  display: grid;
  gap: 6px;
  font-size: 1rem;
}

.zone dl div {
  display: grid;
  grid-template-columns: 96px minmax(0, 1fr);
  gap: 12px;
  align-items: baseline;
}

.zone dd { margin: 0; color: var(--t2); }
.zone .alt { display: block; color: var(--t3); font-size: 0.9375rem; }

/* Visually hidden, still read: " · " between "Zone 1" and "Recovery" where they sit on two lines. */
.zone-sep {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* Very narrow (a small phone at 200% zoom): the colour bar moves above the row and each fact
   stacks, so nothing is squeezed into a sliver of a column. */
@media (max-width: 359px) {
  .zone { padding-left: 0; padding-top: 46px; }
  .zone::before { top: 22px; }
  .zone dl div { grid-template-columns: minmax(0, 1fr); gap: 0; }
}

@media (max-width: 899px) {
  /* Phone table rows read "Zone 1 · Recovery" on one line, so the separator shows. */
  .zone-sep { position: static; width: auto; height: auto; overflow: visible; clip: auto; }
}

@media (min-width: 900px) {
  .zones {
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 0 16px;
  }
  .zone,
  .zone:last-child {
    padding: 28px 0 0;
    border: 0;
  }
  .zone::before,
  .zone::after { top: 0; width: 100%; }
  .zone-n,
  .zone-name { display: block; }
  .zone-n { font-size: 0.9375rem; }
  .zone-desc { font-size: 0.9375rem; }
  .zone dl div { grid-template-columns: minmax(0, 1fr); gap: 2px; margin-top: 8px; }
}

.fineprint {
  margin-top: 28px;
  font-size: 0.9375rem;
  color: var(--t3);
  max-width: var(--measure);
}

/* The walk proper. One timeline — the track's passage through the viewport (`cover`) — drives it
   all: graphite as the stage slides in, Zones 1–5 while it's pinned (each about a fifth of the
   pinned scroll), graphite again as it leaves. Washes and lit segments cross-fade with their
   neighbour (an ease, like the room, about a fifth of a viewport of scrolling); readout text swaps
   out-then-in, so two zone names are never legible at once. Scroll-linked: the reader sets the pace.
   min-height: the pinned stage must fit, so short viewports (a phone in landscape, 200% zoom on a
   laptop) keep the table. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) and (min-height: 640px) {
    .walk { padding-bottom: 0; }

    .walk-track {
      height: 360vh;
      margin-top: 8px;
      view-timeline: --walk block;
    }

    .walk-stage {
      position: sticky;
      top: 0;
      height: 100vh;
      height: 100svh;
      display: grid;
      align-items: center;
      overflow: hidden;
      isolation: isolate;
    }

    .washes {
      display: block;
      position: absolute;
      inset: 0;
      z-index: -1;
    }

    /* The session wash: the whole ground takes the zone, brightest behind the readout. Strength
       matches the app (Zone 4's screen peaks near #77321F on #0A0D12). All text on it is t1 except
       the table's labels and idle columns, which sit where the wash is at its base strength. */
    .washes i {
      position: absolute;
      inset: 0;
      background:
        radial-gradient(60% 55% at 24% 32%, color-mix(in srgb, var(--zc) 38%, transparent), transparent 72%),
        color-mix(in srgb, var(--zc) 12%, var(--bg));
    }

    .washes i:nth-child(1) { --zc: var(--z1); }
    .washes i:nth-child(2) { --zc: var(--z2); }
    .washes i:nth-child(3) { --zc: var(--z3); }
    .washes i:nth-child(4) { --zc: var(--z4); }
    .washes i:nth-child(5) { --zc: var(--z5); }

    .walk-inner {
      display: grid;
      align-content: center;
      gap: clamp(28px, 6vh, 64px);
    }

    .readouts {
      display: grid;
      grid-template-areas: "readout";
    }

    .readout { grid-area: readout; }

    .readout-n {
      font-size: clamp(3.5rem, 12vh, 8rem);
      font-weight: 800;
      line-height: 0.92;
      letter-spacing: -0.02em;
      text-transform: uppercase;
    }

    .readout-name {
      margin-top: 10px;
      font-size: clamp(1.375rem, 1.1rem + 1vw, 1.875rem);
      font-weight: 600;
    }

    .readout-desc {
      max-width: 30em;
      margin-top: 18px;
      font-size: clamp(1.125rem, 1.05rem + 0.35vw, 1.3125rem);
      line-height: 1.5;
    }

    .readout-facts {
      margin-top: 12px;
      font-size: 0.9375rem;
      font-variant-numeric: tabular-nums;
    }

    .walk-inner .fineprint { margin: 0; color: var(--t2); }

    /* Phones: the readout and the strip; the table stays in the DOM (visually hidden) so assistive
       tech reads the same list as everyone else. */
    @media (max-width: 899px) {
      .washes i {
        background:
          radial-gradient(90% 50% at 30% 30%, color-mix(in srgb, var(--zc) 38%, transparent), transparent 72%),
          color-mix(in srgb, var(--zc) 12%, var(--bg));
      }
      .zones {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip: rect(0 0 0 0);
        margin: 0;
      }
      .walk-strip { display: grid; }
      .walk-strip span { color: var(--t2); }
      .walk-strip span::before { opacity: 0.3; }
      .walk-strip span::after { display: block; top: -2px; height: 12px; border-radius: 5px; }
    }

    /* Wide: the table is the strip — its colour bars dim, the live zone's column lit and raised. */
    @media (min-width: 900px) {
      .readout-facts { display: none; }
      .zones { margin: 0; }
      .zone-desc { display: none; }
      .zone { color: var(--t2); }
      .zone-n,
      .zone dd,
      .zone .alt { color: inherit; }
      .zone::before { opacity: 0.3; }
      .zone::after { display: block; top: -2px; height: 12px; border-radius: 5px; }
    }

    .washes i,
    .readout,
    .zone,
    .zone::after,
    .walk-strip span::after {
      animation-duration: auto;
      animation-timing-function: linear;
      animation-fill-mode: both;
      animation-timeline: --walk;
      animation-range: cover 0% cover 100%;
    }

    .washes i:nth-child(1), .zone:nth-child(1)::after, .walk-strip span:nth-child(1)::after { animation-name: walk-1; }
    .washes i:nth-child(2), .zone:nth-child(2)::after, .walk-strip span:nth-child(2)::after { animation-name: walk-2; }
    .washes i:nth-child(3), .zone:nth-child(3)::after, .walk-strip span:nth-child(3)::after { animation-name: walk-3; }
    .washes i:nth-child(4), .zone:nth-child(4)::after, .walk-strip span:nth-child(4)::after { animation-name: walk-4; }
    .washes i:nth-child(5), .zone:nth-child(5)::after, .walk-strip span:nth-child(5)::after { animation-name: walk-5; }

    .readout:nth-child(1) { animation-name: walk-t1; }
    .readout:nth-child(2) { animation-name: walk-t2; }
    .readout:nth-child(3) { animation-name: walk-t3; }
    .readout:nth-child(4) { animation-name: walk-t4; }
    .readout:nth-child(5) { animation-name: walk-t5; }

    .zone:nth-child(1) { animation-name: walk-c1; }
    .zone:nth-child(2) { animation-name: walk-c2; }
    .zone:nth-child(3) { animation-name: walk-c3; }
    .zone:nth-child(4) { animation-name: walk-c4; }
    .zone:nth-child(5) { animation-name: walk-c5; }
  }
}

/* Keyframe stops are percentages of the track's `cover` range: with a 360vh track and a 100vh
   stage, the pinned stretch runs from 21.7% to 78.3%, and each zone gets 11.3% of it (boundaries
   at 33.0, 44.4, 55.7 and 67.0). */

/* Washes and lit segments: fade in as the stage arrives (Zone 1 is already named: text first,
   then the light, as in a session), cross-fade at each boundary, fade out. */
@keyframes walk-1 { 0%, 10% { opacity: 0; } 20%, 31% { opacity: 1; } 35%, 100% { opacity: 0; } }
@keyframes walk-2 { 0%, 31% { opacity: 0; } 35%, 42.4% { opacity: 1; } 46.4%, 100% { opacity: 0; } }
@keyframes walk-3 { 0%, 42.4% { opacity: 0; } 46.4%, 53.7% { opacity: 1; } 57.7%, 100% { opacity: 0; } }
@keyframes walk-4 { 0%, 53.7% { opacity: 0; } 57.7%, 65% { opacity: 1; } 69%, 100% { opacity: 0; } }
@keyframes walk-5 { 0%, 65% { opacity: 0; } 69%, 80% { opacity: 1; } 90%, 100% { opacity: 0; } }

/* Readouts: out, then in — never two zone names at once. */
@keyframes walk-t1 { 0%, 32% { opacity: 1; } 33%, 100% { opacity: 0; } }
@keyframes walk-t2 { 0%, 33% { opacity: 0; } 34%, 43.4% { opacity: 1; } 44.4%, 100% { opacity: 0; } }
@keyframes walk-t3 { 0%, 44.4% { opacity: 0; } 45.4%, 54.7% { opacity: 1; } 55.7%, 100% { opacity: 0; } }
@keyframes walk-t4 { 0%, 55.7% { opacity: 0; } 56.7%, 66% { opacity: 1; } 67%, 100% { opacity: 0; } }
@keyframes walk-t5 { 0%, 67% { opacity: 0; } 68%, 84% { opacity: 1; } 90%, 100% { opacity: 0; } }

/* The table's live column: its text steps up from t2 to t1 while its zone is on. */
@keyframes walk-c1 { 0%, 32% { color: #EDF1F7; } 34%, 100% { color: #94A2B8; } }
@keyframes walk-c2 { 0%, 32% { color: #94A2B8; } 34%, 43.4% { color: #EDF1F7; } 45.4%, 100% { color: #94A2B8; } }
@keyframes walk-c3 { 0%, 43.4% { color: #94A2B8; } 45.4%, 54.7% { color: #EDF1F7; } 56.7%, 100% { color: #94A2B8; } }
@keyframes walk-c4 { 0%, 54.7% { color: #94A2B8; } 56.7%, 66% { color: #EDF1F7; } 68%, 100% { color: #94A2B8; } }
@keyframes walk-c5 { 0%, 66% { color: #94A2B8; } 68%, 84% { color: #EDF1F7; } 90%, 100% { color: #94A2B8; } }

/* ── Home: how it works ─────────────────────────────────────────────────────────────────────── */

.steps {
  list-style: none;
  margin: 40px 0 0;
  padding: 0;
}

.steps li {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr);
  gap: 4px 16px;
  padding-block: 24px;
  border-top: 1px solid var(--hairline);
}

.steps li:last-child { border-bottom: 1px solid var(--hairline); }

.num {
  grid-row: span 2;
  font-family: var(--rounded);
  font-size: 2.5rem;
  font-weight: 600;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.steps p { color: var(--t2); }

.note {
  margin-top: 28px;
  color: var(--t2);
  font-size: 1rem;
}

/* ── Home: calm by design — three figures on the grid ───────────────────────────────────────── */

.specs {
  margin: 36px 0 0;
  display: grid;
}

.specs div {
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr);
  gap: 16px;
  align-items: baseline;
  padding-block: 18px;
  border-top: 1px solid var(--hairline);
}

.specs div:last-child { border-bottom: 1px solid var(--hairline); }

.specs dt {
  font-family: var(--rounded);
  font-size: 2rem;
  font-weight: 600;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.specs dt small {
  margin-left: 0.08em;
  font-size: 0.45em;
  font-weight: 600;
  color: var(--t2);
}

.spec-label {
  display: block;
  margin-bottom: 8px;
  font-family: var(--sans);
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--t3);
}

@media (max-width: 899px) {
  .specs div { grid-template-columns: 112px minmax(0, 1fr); }
}

.specs dd { margin: 0; color: var(--t2); }

@media (min-width: 900px) {
  .specs { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0 28px; }
  .specs div,
  .specs div:last-child {
    grid-template-columns: minmax(0, 1fr);
    gap: 14px;
    padding-block: 24px 0;
    border-bottom: 0;
  }
  .specs dt { font-size: 3.5rem; }
  .specs dd { font-size: 0.9375rem; }
}

.after-specs { margin-top: 32px; color: var(--t2); }

.after-specs strong { color: var(--t1); font-weight: 600; }

/* ── Home: setups index (links into /works-with) ──────────────────────────────────────────── */

.setups {
  display: grid;
  border-top: 1px solid var(--hairline);
}

.setups a {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 2px 16px;
  padding: 14px 0;
  border-bottom: 1px solid var(--hairline);
  text-decoration: none;
}

.setups a::after {
  content: "\2192";
  grid-column: 2;
  grid-row: 1 / span 2;
  align-self: center;
  color: var(--t3);
  transition: transform 180ms var(--ease), color 180ms var(--ease);
}

.setups a:hover::after { transform: translateX(3px); color: var(--t1); }

.setup-name { font-weight: 600; }

.setup-note { color: var(--t3); font-size: 0.9375rem; }

/* ── Arrow links: the arrow is part of the link text (a no-break space keeps it with the last
   word) and shares its underline, so it reads as one link. ─────────────────────────────────── */

.go {
  font-weight: 600;
  line-height: 2.75; /* ≥ 44 px tap height on one line */
  color: var(--accent);
  text-decoration-color: transparent;
}

.go:hover { text-decoration-color: currentColor; }

.go::after { content: "\00a0\2192"; }

/* ── FAQ (native <details>, so it works with no script and with every assistive tech) ─────────── */

.faq {
  margin-top: 32px;
  border-top: 1px solid var(--hairline);
  max-width: var(--measure);
}

.faq details { border-bottom: 1px solid var(--hairline); }

.faq summary {
  position: relative;
  display: block;
  padding: 20px 44px 20px 0;
  font-weight: 600;
  font-size: 1.0625rem;
  line-height: 1.4;
  cursor: pointer;
  list-style: none;
  border-radius: 6px;
}

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

/* A plus that turns to a cross — a quiet rotate, not a jump. */
.faq summary::before,
.faq summary::after {
  content: "";
  position: absolute;
  right: 8px;
  top: 50%;
  width: 14px;
  height: 2px;
  margin-top: -1px;
  border-radius: 1px;
  background: var(--t2);
  transition: transform 220ms var(--ease);
}

.faq summary::after { transform: rotate(90deg); }
.faq details[open] summary::before { transform: rotate(45deg); }
.faq details[open] summary::after { transform: rotate(135deg); }

.faq summary:hover::before,
.faq summary:hover::after { background: var(--t1); }

.faq .answer {
  padding: 0 0 22px;
  color: var(--t2);
}

.faq .answer p + p,
.faq .answer p + ul,
.faq .answer ul + p { margin-top: 12px; }

.faq .answer ul { margin: 0; padding-left: 1.2em; }
.faq .answer li + li { margin-top: 6px; }

.faq .answer strong { color: var(--t1); font-weight: 600; }

/* The FAQ's right column: where to go next. */
.aside-block {
  padding-top: 18px;
  border-top: 1px solid var(--hairline);
  color: var(--t2);
  font-size: 0.9375rem;
}

.aside-block .aside-title {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--t3);
}

.aside-block .aside-title:not(:first-child) { margin-top: 20px; }

.aside-block p + p { margin-top: 4px; }

@media (min-width: 900px) {
  /* Level with the FAQ's top rule: the h2's line box plus the FAQ's top margin. */
  .aside-block { margin-top: calc(clamp(1.5rem, 1.25rem + 0.9vw, 1.875rem) * 1.1 + 32px); }
}

/* ── Home: closing ──────────────────────────────────────────────────────────────────────────── */

.closing p { margin-top: 14px; color: var(--t2); }

/* ── Footer ─────────────────────────────────────────────────────────────────────────────────── */

.site-footer {
  padding-block: 48px 56px;
  border-top: 1px solid var(--hairline);
  font-size: 0.9375rem;
  color: var(--t3);
}

.footer-grid {
  display: grid;
  gap: 28px;
}

@media (min-width: 900px) {
  .footer-grid { grid-template-columns: 1fr auto; align-items: start; }
}

.site-footer .wm { font-size: 1.375rem; }

.footer-tag { margin-top: 12px; color: var(--t2); }

.footer-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0 4px;
  margin-inline: -10px;
}

.footer-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: 10px;
  color: var(--t2);
  text-decoration: none;
  border-radius: 8px;
}

.footer-nav a:hover,
.footer-nav a[aria-current="page"] { color: var(--t1); }

/* "Also from us": the maker's other app (Shoey), one quiet line above the legal text. */
.also {
  margin-top: 32px;
  padding-top: 20px;
  border-top: 1px solid var(--hairline);
  max-width: var(--measure);
  color: var(--t2);
}

.also + .legal-line { margin-top: 16px; }

.legal-line { margin-top: 28px; max-width: var(--measure); line-height: 1.55; }

.legal-line + .legal-line { margin-top: 10px; }

/* ── Inner pages (support, works with, privacy, terms, 404) ─────────────────────────────────── */

.page-head { padding-block: clamp(32px, 6vw, 80px) clamp(40px, 5vw, 64px); }

.page-head .lede { margin-top: 18px; }

.page-head .meta {
  margin-top: 16px;
  font-size: 0.9375rem;
  color: var(--t3);
}

/* Text on the measure, and an "On this page" index on wide screens. */
.doc { display: grid; }

.toc { display: none; }

.doc-main { min-width: 0; }

@media (min-width: 1100px) {
  .doc {
    grid-template-columns: minmax(0, var(--measure)) 220px;
    justify-content: space-between;
    gap: 48px;
  }
  .toc { display: block; padding-top: clamp(32px, 6vw, 80px); }
  .toc nav { position: sticky; top: 32px; padding-bottom: 32px; }
}

.toc-title {
  margin-bottom: 12px;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--t3);
}

.toc ol {
  list-style: none;
  margin: 0;
  padding: 0;
  border-left: 1px solid var(--hairline);
}

.toc a {
  display: block;
  margin-left: -1px;
  padding: 5px 0 5px 16px;
  border-left: 1px solid transparent;
  color: var(--t2);
  font-size: 0.9375rem;
  line-height: 1.4;
  text-decoration: none;
}

.toc a:hover { color: var(--t1); border-left-color: var(--t2); }

.prose {
  min-width: 0;
  max-width: var(--measure);
  padding-bottom: var(--section);
}

.prose h2 {
  font-size: clamp(1.375rem, 1.2rem + 0.8vw, 1.75rem);
  margin-top: 56px;
  padding-top: 32px;
  border-top: 1px solid var(--hairline);
}

.prose h2:first-child { margin-top: 0; }

.prose h3 { margin-top: 32px; }

.prose p,
.prose ul,
.prose ol { margin-top: 14px; }

.prose h2 + p,
.prose h3 + p { margin-top: 12px; }

.prose p,
.prose li { color: var(--t2); }

.prose strong { color: var(--t1); font-weight: 600; }

.prose ul,
.prose ol { padding-left: 1.25em; }

.prose li + li { margin-top: 8px; }

.prose li::marker { color: var(--t3); }

.prose .faq { margin-top: 20px; }

.prose code {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.9em;
  color: var(--t1);
}

/* Privacy's plain-English summary: set apart by a heavier rule above, not a card. The next
   section's own hairline closes it. */
.summary {
  margin: 0;
  padding-top: 24px;
  border-top: 2px solid var(--t1);
}

.summary h2,
.prose .summary h2 {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 1.1875rem;
}

.summary ul { margin-top: 12px; }

/* Data tables (privacy: what is sent, and where). Scroll inside their box on a narrow phone rather
   than widening the page. */
.table-wrap {
  margin-top: 16px;
  overflow-x: auto;
  border-top: 1px solid var(--t3);
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9375rem;
}

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

th {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--t3);
}

td { color: var(--t2); }

td code { white-space: nowrap; }

/* Zone key on the works-with page: one row per zone, the colour as a short bar. */
.prose .key {
  list-style: none;
  padding: 0;
  margin-top: 16px;
  border-top: 1px solid var(--hairline);
}

.prose .key li {
  display: grid;
  grid-template-columns: 36px minmax(0, 1fr);
  gap: 14px;
  align-items: baseline;
  padding-block: 12px;
  margin: 0;
  border-bottom: 1px solid var(--hairline);
}

.prose .key li::before {
  content: "";
  width: 36px;
  height: 8px;
  border-radius: 4px;
  background: var(--zc);
  align-self: center;
}

.key li:nth-child(1) { --zc: var(--z1); }
.key li:nth-child(2) { --zc: var(--z2); }
.key li:nth-child(3) { --zc: var(--z3); }
.key li:nth-child(4) { --zc: var(--z4); }
.key li:nth-child(5) { --zc: var(--z5); }

.contact-line {
  font-size: clamp(1.25rem, 1.1rem + 0.8vw, 1.625rem);
  font-weight: 650;
  letter-spacing: -0.01em;
}

.prose .contact-line { margin-top: 20px; }

.not-found {
  padding-block: clamp(48px, 10vw, 120px) var(--section);
}

.strip-idle { max-width: 320px; }
.strip-idle span::before { opacity: 0.22; }

.not-found h1 { margin-top: 40px; }

.not-found .lede { margin-top: 16px; }

.not-found p:has(> .go) { margin-top: 20px; }
