/*
 * THE MARKETING STYLESHEET (stage-10 §9) — hand-written, no bundler, no framework, no PostCSS.
 *
 * `scripts/design/build-customer-web.mjs` emits this file content-hashed and its header carries the
 * rule this file exists under: **THIS SCRIPT IS NOT A BUNDLER AND MUST NOT BECOME ONE.** So the
 * whole payload of this site is one stylesheet and one small script, and `page-budget --marketing`
 * measures the gzipped total, which is what a minifier would mostly have been for.
 *
 * ── EVERY COLOUR IS A CONSTITUTION TOKEN, AND `design-tokens.mjs --marketing` PROVES IT ─────────
 *
 * The palette below is `docs/design/DESIGN-DIRECTION.md`'s, value for value. The gate reads the
 * document rather than this file, so an improvised neighbour fails here for the same reason it
 * fails on a customer page — and the marketing site is the surface where improvising is most
 * tempting, because it is the one page whose job is to look good rather than to be read in a
 * basement.
 *
 * ── 🔴 THE DARK FAMILY HAS ITS OWN VARIABLE NAMES, AND THAT IS A CHECKABILITY DECISION ──────────
 *
 * The obvious way to write dark mode is to redefine `--ink` inside
 * `@media (prefers-color-scheme: dark)`. It is also the way that makes this stylesheet unreadable
 * to `contrast.mjs`: its `customProperties()` builds ONE flat map over the whole file, so the last
 * definition of a name wins, and every light-mode pair would then be computed against dark values.
 * The check would be measuring a theme that never renders together.
 *
 * So the dark family is `--d-*` — distinct names, defined once, never shadowed. Both themes resolve
 * unambiguously, both are computed, and S10-020's *"in both themes"* is a measurement rather than an
 * intention. The cost is a longer `:root`; the benefit is that the gate is not lying.
 *
 * ── MOTION: EVERY DURATION IS ONE THE CONSTITUTION NAMES ────────────────────────────────────────
 *
 * `motion-conformance.mjs --marketing` parses the permitted list out of the document's
 * "### MARKETING SITE" section — 32, 60, 70, 100, 150, 200, 320, 480, 600, 900, 1100, 4000, 24000 —
 * rather than transcribing it here. Exactly one ambient loop, gated behind reduced motion; exactly
 * one count-up; hover only on pointer devices; the pricing block, the nav and the footer hold still.
 */

/* ══════════════════════════════════════════════════════════════════════════════════════════════
 * FACES — self-hosted, subset, committed, and never fetched (§9.2, S10-026)
 *
 * `local()` first so a visitor who already has the face pays nothing. `font-display: swap` because
 * the alternative on a slow connection is invisible text. The `unicode-range` is the one Google
 * Fonts cuts its `latin` block at, carried verbatim beside the bytes it describes — a subset whose
 * declared range is wider than its glyph coverage is a subset that silently drops a character.
 * ═══════════════════════════════════════════════════════════════════════════════════════════ */

@font-face {
  font-family: 'Plus Jakarta Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src:
    local('Plus Jakarta Sans'),
    url('/f/pjs-latin.woff2') format('woff2');
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
    U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/*
 * IBM Plex Mono is DEMO-TIER: it is referenced only from the demo page's own stylesheet block and
 * never from the landing page's <head>, so `page-budget --marketing` counts it under "demo tier,
 * lazy" rather than against the 150 KB critical path. §9.2: it is needed only inside the demo's
 * transcript timestamps.
 */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src:
    local('IBM Plex Mono'),
    url('/f/plex-mono-latin-400.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+2000-206F, U+2212;
}

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src:
    local('IBM Plex Mono'),
    url('/f/plex-mono-latin-500.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+2000-206F, U+2212;
}

/* ══════════════════════════════════════════════════════════════════════════════════════════════
 * TOKENS
 * ═══════════════════════════════════════════════════════════════════════════════════════════ */

:root {
  /* light — core */
  --canvas: #f6f8fb;
  --well: #edf2fa;
  --surface: #ffffff;
  --hairline: #e6ebf2;
  --border-strong: #7a8798;
  --ink: #0b2239;
  --slate: #55647a;

  /* light — accent */
  --accent: #2e6be6;
  --accent-text: #2556b8;
  --accent-tint: #eaf1fe;

  /* light — semantic, the two states this site actually renders */
  --missed-fill: #fdecec;
  --missed-label: #b4302f;
  --enroute-fill: #eaf1fe;
  --enroute-label: #2556b8;

  /* dark — its own names, never shadowing the light ones (see the header) */
  --d-navy950: #0a1626;
  --d-navy900: #0f2439;
  --d-navy800: #14304a;
  --d-navy700: #1e3a54;
  --d-border-strong: #4a7096;
  --d-ink: #eaf1fa;
  --d-slate: #9fb2c7;
  --d-accent-text: #7fb0ff;
  --d-accent-dot: #5b9bff;
  --d-missed-fill: #3e1f27;
  --d-missed-label: #ff9ea2;

  /* elevation — the constitution's four, verbatim, alpha included */
  --l1: 0 1px 2px rgba(11, 34, 57, 0.06);
  --l2: 0 8px 24px rgba(11, 34, 57, 0.08);
  --l3: 0 20px 48px rgba(11, 34, 57, 0.12);

  /* radius ladder */
  --r-sm: 10px;
  --r-md: 14px;
  --r-lg: 24px;
  --r-plate: 32px;
  --r-pill: 999px;

  /* spacing scale */
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 20px;
  --s-6: 24px;
  --s-7: 32px;
  --s-8: 40px;
  --s-9: 56px;
  --s-10: 80px;
  --s-11: 120px;

  /* 🔴 measure — the constitution's 56–62ch, as a token so no section improvises one */
  --measure: 60ch;

  --face: 'Plus Jakarta Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --face-mono: 'IBM Plex Mono', ui-monospace, 'SFMono-Regular', monospace;
}

/* ══════════════════════════════════════════════════════════════════════════════════════════════
 * BASE
 * ═══════════════════════════════════════════════════════════════════════════════════════════ */

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

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

body {
  margin: 0;
  font-family: var(--face);
  font-size: 16px;
  line-height: 1.6;
  font-weight: 400;
  color: var(--ink);
  background: var(--canvas);
  padding-bottom: 88px;
}

/* Left-aligned always. The constitution bans centred-heading-over-centred-body outright, and the
 * simplest way to be certain of that is to have no centring rule in the file at all. */
h1,
h2,
h3,
p,
ul,
ol {
  margin: 0;
  text-align: left;
}

h1 {
  font-size: 40px;
  line-height: 0.98;
  letter-spacing: -0.026em;
  font-weight: 600;
  max-width: 22ch;
}

h2 {
  font-size: 28px;
  line-height: 1.12;
  letter-spacing: -0.02em;
  font-weight: 600;
}

h3 {
  font-size: 20px;
  line-height: 1.25;
  letter-spacing: -0.014em;
  font-weight: 600;
}

p {
  max-width: var(--measure);
}

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

a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}

.skip {
  position: absolute;
  left: -9999px;
  color: var(--ink);
  background: var(--surface);
}

.skip:focus {
  left: var(--s-4);
  top: var(--s-4);
  padding: var(--s-3);
  border-radius: var(--r-sm);
  z-index: 3;
}

.wrap {
  width: 100%;
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 var(--s-5);
}

.microcaps {
  font-size: 11px;
  line-height: 1;
  letter-spacing: 0.1em;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--slate);
  background: transparent;
}

.meta {
  font-size: 14px;
  line-height: 1.4;
  font-weight: 500;
  color: var(--slate);
  background: transparent;
}

/* ══════════════════════════════════════════════════════════════════════════════════════════════
 * NAV — left wordmark, right-aligned links, one quiet secondary CTA. It does not animate.
 * ═══════════════════════════════════════════════════════════════════════════════════════════ */

.nav {
  display: flex;
  align-items: center;
  gap: var(--s-6);
  padding-top: var(--s-6);
  padding-bottom: var(--s-6);
  color: var(--ink);
  background: var(--canvas);
}

.nav-mark {
  font-weight: 600;
  font-size: 20px;
  letter-spacing: -0.014em;
  margin-right: auto;
  color: var(--ink);
  background: transparent;
}

.nav-links {
  display: flex;
  align-items: center;
  gap: var(--s-6);
  list-style: none;
  padding: 0;
  margin: 0;
}

.nav-cta {
  display: inline-block;
  padding: var(--s-2) var(--s-4);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-pill);
  color: var(--accent-text);
  background: var(--surface);
  font-weight: 600;
  text-decoration: none;
}

/* ══════════════════════════════════════════════════════════════════════════════════════════════
 * SECTIONAL RHYTHM — plates on Canvas, not bands. 80px mobile, 120px desktop, from SPACING.
 * ═══════════════════════════════════════════════════════════════════════════════════════════ */

.section {
  padding-top: var(--s-10);
  padding-bottom: var(--s-10);
}

.plate {
  padding: var(--s-7);
  border-radius: var(--r-plate);
  border: 1px solid var(--hairline);
  color: var(--ink);
  background: var(--surface);
  box-shadow: var(--l1);
}

.plate--well {
  color: var(--ink);
  background: var(--well);
  box-shadow: none;
}

/*
 * 🔴 THE ONE FULL-BLEED ACCENT SLAB ON THE PAGE. The constitution allows exactly one, with the
 * reason attached: the parking reference uses two and *"the accent stops meaning anything by the
 * second one"*. `marketing-copy.mjs --constitution` counts them.
 */
.slab--accent {
  padding: var(--s-9) var(--s-7);
  border-radius: var(--r-plate);
  color: var(--surface);
  background: var(--accent);
  box-shadow: var(--l3);
}

.slab--accent a {
  color: var(--surface);
  background: transparent;
}

/* ══════════════════════════════════════════════════════════════════════════════════════════════
 * HERO — one blunt claim, the calculator, and the page's one count-up
 * ═══════════════════════════════════════════════════════════════════════════════════════════ */

.hero {
  position: relative;
  padding-top: var(--s-9);
  padding-bottom: var(--s-10);
  border-radius: var(--r-plate);
  color: var(--ink);
  background: var(--canvas);
}

/*
 * THE ONE AMBIENT LOOP: 24s, 3% luminance drift, inside the cool family, never toward a second hue.
 * It is a pseudo-element so the drift is a background and never touches text contrast.
 */
.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: var(--r-plate);
  background: var(--well);
  opacity: 0.55;
  z-index: 0;
  animation: drift 24s ease-in-out infinite;
}

.hero > * {
  position: relative;
  z-index: 1;
}

@keyframes drift {
  0% {
    opacity: 0.55;
  }
  50% {
    opacity: 0.58;
  }
  100% {
    opacity: 0.55;
  }
}

.hero-sub {
  margin-top: var(--s-5);
  font-size: 17px;
  line-height: 1.45;
  color: var(--slate);
  background: transparent;
}

.calc {
  margin-top: var(--s-8);
  display: grid;
  gap: var(--s-4);
  padding: var(--s-6);
  border-radius: var(--r-lg);
  border: 1px solid var(--hairline);
  color: var(--ink);
  background: var(--surface);
  box-shadow: var(--l2);
}

.calc-fields {
  display: grid;
  gap: var(--s-4);
  grid-template-columns: 1fr;
}

.field {
  display: grid;
  gap: var(--s-2);
}

.field > span {
  font-size: 14px;
  font-weight: 500;
  color: var(--slate);
  background: transparent;
}

input,
select,
textarea {
  font-family: var(--face);
  font-size: 16px;
  padding: var(--s-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-sm);
  color: var(--ink);
  background: var(--surface);
}

.calc-out {
  font-size: 40px;
  line-height: 0.98;
  letter-spacing: -0.026em;
  font-weight: 600;
  color: var(--ink);
  background: transparent;
}

.calc-note {
  font-size: 14px;
  color: var(--slate);
  background: transparent;
}

/* ══════════════════════════════════════════════════════════════════════════════════════════════
 * FEATURES, HOW IT WORKS, PROOF
 * ═══════════════════════════════════════════════════════════════════════════════════════════ */

.grid {
  display: grid;
  gap: var(--s-6);
  grid-template-columns: 1fr;
  margin-top: var(--s-7);
  padding: 0;
  list-style: none;
}

.card {
  padding: var(--s-6);
  border-radius: var(--r-lg);
  border: 1px solid var(--hairline);
  color: var(--ink);
  background: var(--surface);
  box-shadow: var(--l1);
  transition:
    box-shadow 150ms ease-out,
    transform 150ms ease-out;
}

.card p {
  margin-top: var(--s-3);
  color: var(--slate);
}

.card-note {
  margin-top: var(--s-3);
  font-size: 14px;
  color: var(--slate);
  background: transparent;
}

.step-n {
  font-size: 11px;
  line-height: 1;
  letter-spacing: 0.1em;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--accent-text);
  background: transparent;
}

.proof {
  margin-top: var(--s-6);
  font-size: 17px;
  line-height: 1.45;
  color: var(--ink);
  background: transparent;
}

/*
 * 🔴 A CLAIM RENDERING ITS WEAK FORM IS MARKED IN THE MARKUP, NOT ONLY IN A REPORT.
 * `claim-site-fence.mjs` prints the resolved table; this is the same fact where a reader is.
 */
.claim-weak {
  border-left: 3px solid var(--border-strong);
  padding-left: var(--s-4);
}

/* ── the photographic plates (§10.2) ───────────────────────────────────────────────────────── */

.figure {
  margin: var(--s-7) 0 0;
}

.plate-img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--r-lg);
  border: 1px solid var(--hairline);
}

/* ══════════════════════════════════════════════════════════════════════════════════════════════
 * PRICING — numbers a skeptic is reading must hold still. Nothing here animates.
 * ═══════════════════════════════════════════════════════════════════════════════════════════ */

.pricing {
  padding: var(--s-7);
  border-radius: var(--r-plate);
  border: 1px solid var(--hairline);
  color: var(--ink);
  background: var(--surface);
  box-shadow: var(--l1);
}

.pricing-figure {
  font-size: 40px;
  line-height: 0.98;
  letter-spacing: -0.026em;
  font-weight: 600;
  color: var(--ink);
  background: transparent;
}

.pricing-caption {
  margin-top: var(--s-2);
  color: var(--slate);
}

.pricing-trust {
  margin-top: var(--s-7);
  display: grid;
  gap: var(--s-4);
  padding: 0;
  list-style: none;
}

.pricing-trust li {
  padding: var(--s-4);
  border-radius: var(--r-md);
  color: var(--enroute-label);
  background: var(--enroute-fill);
}

/* ══════════════════════════════════════════════════════════════════════════════════════════════
 * THE WAITLIST — a plain HTML POST that works with JavaScript disabled
 * ═══════════════════════════════════════════════════════════════════════════════════════════ */

.form {
  display: grid;
  gap: var(--s-5);
  margin-top: var(--s-6);
}

.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.btn {
  display: inline-block;
  padding: var(--s-4) var(--s-6);
  border: 0;
  border-radius: var(--r-pill);
  font-family: var(--face);
  font-size: 16px;
  font-weight: 600;
  color: var(--surface);
  background: var(--accent);
  cursor: pointer;
  text-decoration: none;
  transition: transform 200ms ease-out;
}

.btn--quiet {
  color: var(--accent-text);
  background: var(--surface);
  border: 1px solid var(--border-strong);
}

.notice {
  padding: var(--s-4);
  border-radius: var(--r-md);
  color: var(--missed-label);
  background: var(--missed-fill);
}

.notice--ok {
  color: var(--enroute-label);
  background: var(--enroute-fill);
}

/* ══════════════════════════════════════════════════════════════════════════════════════════════
 * THE DEMO
 * ═══════════════════════════════════════════════════════════════════════════════════════════ */

.acts {
  display: grid;
  gap: var(--s-5);
  margin-top: var(--s-6);
  padding: 0;
  list-style: none;
}

.act {
  padding: var(--s-6);
  border-radius: var(--r-lg);
  border: 1px solid var(--hairline);
  color: var(--ink);
  background: var(--surface);
}

.act-label {
  font-size: 11px;
  line-height: 1;
  letter-spacing: 0.1em;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--slate);
  background: transparent;
}

/*
 * 🔴 THE ACT STATES MUST BE VISIBLE, OR THE MATRIX PHOTOGRAPHS FOUR IDENTICAL PICTURES.
 *
 * S10-044's whole point is that *"a demo photographed one frame at a time can be four correct
 * pictures of a broken timeline"*, and `assertAxesAreLive` catches that by refusing two cells that
 * should differ and are byte-identical. It can only catch it if the state a viewer is meant to see
 * is actually rendered — so `data-state` changes the plate, and the change is an opacity and a
 * border, both cheap and both on the constitution's permitted 480ms.
 */
.act[data-state='waiting'] {
  opacity: 0.45;
  transition: opacity 480ms ease-out;
}

.act[data-state='playing'] {
  opacity: 1;
  border-color: var(--accent);
  box-shadow: var(--l2);
  transition: opacity 480ms ease-out;
}

.act[data-state='done'] {
  opacity: 1;
  transition: opacity 480ms ease-out;
}

.turn {
  margin-top: var(--s-3);
  padding: var(--s-3) var(--s-4);
  border-radius: var(--r-md);
  color: var(--ink);
  background: var(--well);
}

.turn--agent {
  color: var(--enroute-label);
  background: var(--enroute-fill);
}

.stamp,
.segments {
  font-family: var(--face-mono);
  font-size: 14px;
  color: var(--slate);
  background: transparent;
}

.frame {
  width: 100%;
  height: 520px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  background: var(--surface);
}

.degraded {
  padding: var(--s-6);
  border-radius: var(--r-lg);
  border: 1px dashed var(--border-strong);
  color: var(--ink);
  background: var(--well);
}

/* ══════════════════════════════════════════════════════════════════════════════════════════════
 * 🔴 THE STICKY INK RAIL — 72px, proof left, one primary CTA right (constitution, MARKETING)
 * ═══════════════════════════════════════════════════════════════════════════════════════════ */

.rail {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  min-height: 72px;
  display: flex;
  align-items: center;
  gap: var(--s-5);
  padding: var(--s-4) var(--s-5);
  color: var(--d-ink);
  background: var(--ink);
  transform: translateY(100%);
  transition: transform 320ms ease-out;
}

/*
 * It slides up once the hero passes, and gains its shadow 100ms AFTER it lands. Arriving flat and
 * then settling reads physical; arriving pre-shadowed reads pasted.
 */
.rail.is-up {
  transform: translateY(0);
}

.rail.is-settled {
  box-shadow: var(--l3);
}

.rail p {
  margin-right: auto;
  color: var(--d-ink);
  background: transparent;
}

.rail .btn {
  color: var(--surface);
  background: var(--accent);
}

/* ══════════════════════════════════════════════════════════════════════════════════════════════
 * FOOTER — does not animate
 * ═══════════════════════════════════════════════════════════════════════════════════════════ */

.footer {
  padding-top: var(--s-9);
  padding-bottom: var(--s-9);
  border-top: 1px solid var(--hairline);
  color: var(--slate);
  background: var(--canvas);
}

.footer-mark {
  font-weight: 600;
  color: var(--ink);
  background: transparent;
}

/* ══════════════════════════════════════════════════════════════════════════════════════════════
 * SCROLL REVEALS — 480ms, 60ms stagger, once only. The script sets `is-in` and unobserves.
 * ═══════════════════════════════════════════════════════════════════════════════════════════ */

.reveal {
  opacity: 1;
  transform: none;
}

.js .reveal {
  opacity: 0;
  transform: translateY(16px);
  transition:
    opacity 480ms ease-out,
    transform 480ms ease-out;
}

.js .reveal.is-in {
  opacity: 1;
  transform: none;
}

.js .reveal-line {
  clip-path: inset(0 0 100% 0);
  transition: clip-path 600ms ease-out;
}

.js .reveal-line.is-in {
  clip-path: inset(0 0 0 0);
}

/* ══════════════════════════════════════════════════════════════════════════════════════════════
 * HOVER — pointer devices only. Touch devices get none of it.
 * ═══════════════════════════════════════════════════════════════════════════════════════════ */

@media (hover: hover) and (pointer: fine) {
  .card:hover {
    box-shadow: var(--l3);
    transform: translateY(-3px);
  }

  .btn:hover {
    transform: scale(1.015);
  }

  .nav-links a:hover {
    text-decoration: underline;
  }
}

/* ══════════════════════════════════════════════════════════════════════════════════════════════
 * LEGAL DOCUMENTS — the index block, the anchor landing, and the hub's index of indexes.
 *
 * 🔴 SCOPED TO `.legal-doc` AND NOTHING ELSE. These four pages are under live A2P review and rule
 * R-E9a carves them out of the round-4 restyle; the goal here is to make a document NAVIGABLE, not
 * to redesign it. No new tokens, no new sizes, no `clamp()` — every value below is an existing
 * spacing step, and the type ladder is untouched. Our body is already 16px on 1.6 at 60ch, which
 * beats the reference page the owner pointed at (13px on 1.15, measured).
 * ═══════════════════════════════════════════════════════════════════════════════════════════ */

/*
 * ⚠ THE ONE RENDERING CHANGE TO THE THREE EXISTING DOCUMENTS, AND IT IS SPACING ONLY.
 *
 * These pages had NO stacking rule at all, so their plates sat flush against one another — which
 * was survivable while a plate followed a plate, and stops being survivable the moment a heading
 * has to sit between two of them. Four paragraphs on `/terms` and three on `/sms` became named,
 * linkable sections this round; without this rule each new heading welds itself to the card above
 * it. Not one word of copy moved and no token changed.
 */
.legal-doc > * + * {
  margin-top: var(--s-5);
}

/* A heading owns the block beneath it, so it takes its air from above. */
.legal-doc > h3 {
  margin-top: var(--s-9);
}

/*
 * ⚠ TWO CLAUSES IN ONE CARD WERE RENDERING AS ONE PARAGRAPH. The global reset zeroes `p` margins
 * and nothing put them back, so a plate holding three separate sentences — which on this page is
 * the norm, not the exception — printed them as an unbroken block. On a marketing page that reads
 * as tight typesetting; on a document where a reviewer is matching individual published strings,
 * running two clauses together is the thing that makes one of them hard to find. Each clause gets
 * its own block. No text moved.
 */
.legal-doc .plate > p + p {
  margin-top: var(--s-4);
}

.legal-doc > h3 + .plate,
.legal-doc > h3 + .plate--well {
  margin-top: var(--s-4);
}

/*
 * An anchored heading must not land jammed against the top of the viewport — the reader arrives
 * having clicked a link and needs to see that they arrived somewhere.
 */
.legal-doc :where(h2, h3)[id] {
  scroll-margin-top: var(--s-6);
}

/*
 * THE PER-PAGE INDEX. Static, never sticky (research §8.4): a permanently-occupied strip of a
 * 390px screen is a bad trade for a document read once, and a static index is also the only kind
 * that prints correctly.
 */
.legal-toc {
  padding: var(--s-6);
  border-radius: var(--r-lg);
  border: 1px solid var(--hairline);
}

.legal-toc nav {
  margin-top: var(--s-3);
}

.legal-toc ol,
.legal-index ol {
  padding-left: var(--s-5);
  max-width: var(--measure);
}

/*
 * ⚠ 24px of vertical hit area at 390px — an index whose links are too small to hit is not an
 * index, it is a list.
 *
 * ⚠ `block` AND NOT `inline-block`, AND THE DIFFERENCE IS VISIBLE AT 390px. An inline-block that
 * wraps to two lines takes its baseline from its LAST line, so the list marker slid down beside
 * the second line of "Text messages, and the number they go to" and the index read as though item
 * 2 had lost its number. A block-level child keeps the marker on the first line where it belongs,
 * and it makes the whole row the tap target rather than just the glyphs.
 */
.legal-toc li a,
.legal-index li a {
  display: block;
  padding-block: var(--s-2);
}

/*
 * 🔴 THE INDEX LINKS ARE INK, NOT ACCENT, AND THAT IS THE BLUE BUDGET RATHER THAN A PREFERENCE.
 *
 * R-E9a's viewport clause allows a legal page two accent marks in any one screen, and R-E9a(c) is
 * explicit about what may hold one: a PRIMARY ACTION or a LIVE MARK, and *"anything else … loses
 * the accent"*. A table of contents is neither — it is the quiet way into a document. Left at the
 * global link colour these blocks rendered eleven blue items in a single 390px viewport, which is
 * precisely the "where do I look" failure the owner named, arriving in the one place on the site
 * whose entire job is to help someone look.
 *
 * This is the same call round 4 already made on `a.hubgolink` and `a.heardlink`, and it costs
 * nothing for the same reason: THE UNDERLINE AND THE HIT BOX BOTH STAY, so affordance is
 * untouched and only the spend moves. The page keeps exactly one accent — the nav CTA, which
 * R-E9a(a) exempts and counts once in the page total.
 *
 * ⚠ SCOPED TO THE INDEX BLOCKS THIS ROUND ADDED. Every link that was already on `/privacy`,
 * `/terms` and `/sms` keeps the colour it shipped with; nothing under live review changes hue.
 */
.legal-toc a,
.legal-index a {
  color: var(--ink);
  text-decoration-color: var(--border-strong);
}

/* THE HUB'S INDEX — one entry per document: title, one plain line, its own date, its sections. */
.legal-index {
  padding-left: 0;
  list-style: none;
  max-width: var(--measure);
}

.legal-index > li + li {
  margin-top: var(--s-8);
  padding-top: var(--s-8);
  border-top: 1px solid var(--hairline);
}

.legal-index > li > p {
  margin-top: var(--s-2);
}

.legal-index > li > ol {
  margin-top: var(--s-3);
}

/* ══════════════════════════════════════════════════════════════════════════════════════════════
 * DESKTOP
 * ═══════════════════════════════════════════════════════════════════════════════════════════ */

@media (min-width: 900px) {
  h1 {
    font-size: 56px;
    line-height: 0.94;
    letter-spacing: -0.03em;
  }

  .section {
    padding-top: var(--s-11);
    padding-bottom: var(--s-11);
  }

  .grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .calc-fields {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .pricing-trust {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* ══════════════════════════════════════════════════════════════════════════════════════════════
 * DARK — re-derived inside the navy family, on its own token names (see the header)
 * ═══════════════════════════════════════════════════════════════════════════════════════════ */

/*
 * ⚠ `screen and` IS LOAD-BEARING AND IT WAS ADDED BY A DEFECT THAT PRINTED BLANK PAGES.
 *
 * `prefers-color-scheme` is a property of the USER, not of the output device, so it stays true
 * when the page goes to paper: a visitor whose OS is in dark mode printed `/privacy` and got
 * `--d-ink` (#eaf1fa) body copy on white paper. The headings survived — they inherit from `body`,
 * which the print block re-inks — but every paragraph inside a `.plate` is coloured by the rule
 * below, and near-white text on white paper is an EMPTY PAGE. A legal document that prints blank
 * for half the population is worse than one with no print stylesheet at all, because the person
 * holding it has no way to know anything is missing.
 *
 * Gating the whole dark family to `screen` fixes it once, for all eight pages, instead of
 * enumerating an override per element inside `@media print` and forgetting one. Screen rendering
 * is byte-identical — this changes nothing anybody sees on a display.
 */
@media screen and (prefers-color-scheme: dark) {
  body {
    color: var(--d-ink);
    background: var(--d-navy950);
  }

  a {
    color: var(--d-accent-text);
    background: transparent;
  }

  .nav {
    color: var(--d-ink);
    background: var(--d-navy950);
  }

  .nav-mark {
    color: var(--d-ink);
    background: transparent;
  }

  .nav-cta {
    color: var(--d-accent-text);
    background: var(--d-navy900);
    border-color: var(--d-border-strong);
  }

  .hero {
    color: var(--d-ink);
    background: var(--d-navy950);
  }

  .hero::before {
    background: var(--d-navy900);
  }

  .hero-sub {
    color: var(--d-slate);
    background: transparent;
  }

  .plate,
  .card,
  .act,
  .calc,
  .pricing {
    color: var(--d-ink);
    background: var(--d-navy900);
    border-color: var(--d-navy700);
  }

  .plate--well {
    color: var(--d-ink);
    background: var(--d-navy800);
  }

  /* The index block borrows the well's fill from the rule above; only its hairline needs
     re-deriving inside the navy family. */
  .legal-toc,
  .legal-index > li + li {
    border-color: var(--d-navy700);
  }

  /* Ink rather than accent, re-derived in the navy family. See the light rule for the argument. */
  .legal-toc a,
  .legal-index a {
    color: var(--d-ink);
    text-decoration-color: var(--d-border-strong);
  }

  .card p,
  .card-note,
  .calc-note,
  .pricing-caption,
  .field > span,
  .meta,
  .microcaps,
  .act-label,
  .stamp,
  .segments {
    color: var(--d-slate);
    background: transparent;
  }

  .step-n {
    color: var(--d-accent-text);
    background: transparent;
  }

  .calc-out,
  .pricing-figure,
  .proof {
    color: var(--d-ink);
    background: transparent;
  }

  input,
  select,
  textarea {
    color: var(--d-ink);
    background: var(--d-navy800);
    border-color: var(--d-border-strong);
  }

  .turn {
    color: var(--d-ink);
    background: var(--d-navy800);
  }

  .turn--agent,
  .pricing-trust li,
  .notice--ok {
    color: var(--d-accent-text);
    background: var(--d-navy800);
  }

  .notice {
    color: var(--d-missed-label);
    background: var(--d-missed-fill);
  }

  .degraded {
    color: var(--d-ink);
    background: var(--d-navy800);
    border-color: var(--d-border-strong);
  }

  .frame,
  .plate-img {
    background: var(--d-navy900);
    border-color: var(--d-navy700);
  }

  .rail {
    color: var(--d-ink);
    background: var(--d-navy950);
    border-top: 1px solid var(--d-navy700);
  }

  .rail p {
    color: var(--d-ink);
    background: transparent;
  }

  .footer {
    color: var(--d-slate);
    background: var(--d-navy950);
    border-color: var(--d-navy700);
  }

  .footer-mark {
    color: var(--d-ink);
    background: transparent;
  }

  .skip {
    color: var(--d-ink);
    background: var(--d-navy900);
  }

  .claim-weak {
    border-left-color: var(--d-border-strong);
  }
}

/* ══════════════════════════════════════════════════════════════════════════════════════════════
 * 🔴 REDUCED MOTION — the ambient loop, the reveals and the rail all stop. The demo renders its
 * completed end-state and does not loop; that half is the player's decision and is in site.js.
 * ═══════════════════════════════════════════════════════════════════════════════════════════ */

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

  .js .reveal {
    opacity: 1;
    transform: none;
  }

  .js .reveal-line {
    clip-path: none;
  }

  .rail {
    transform: translateY(0);
  }
}

/* ══════════════════════════════════════════════════════════════════════════════════════════════
 * 🔴 PRINT — because legal documents get printed and filed, and this is one of the few places
 * where print genuinely matters. The reference page the owner pointed at has no print stylesheet
 * at all (measured); this is a free win over it.
 * ═══════════════════════════════════════════════════════════════════════════════════════════ */

@media print {
  /* Chrome that means nothing on paper. */
  .nav,
  .rail,
  .skip,
  .footer-mark {
    display: none;
  }

  /*
   * ⚠ THE INDEX IS HIDDEN, AND THAT IS THE OPPOSITE OF THE ON-SCREEN DECISION FOR A REASON.
   * HTML has no page numbers, so a printed index is a list of anchors pointing at nothing a reader
   * can act on. An index of dead links is worse than no index — on paper the headings themselves
   * are the navigation.
   */
  .legal-toc {
    display: none;
  }

  /*
   * ⚠ TOKENS, NOT THE `#000`/`#999`/`#fff` THE SPEC SKETCHED. `design-tokens --marketing` reads
   * every colour in this file against DESIGN-DIRECTION.md and refused all three, correctly: the
   * document's own instruction is "if a value you need is missing, raise it; do not improvise a
   * neighbour", and a print rule is not exempt from it. The light family is the right family here
   * whichever theme the screen was in — the dark palette is `--d-*` and is never redefined into
   * these names, so a page printed from dark mode still comes out on white paper in dark ink,
   * which is what anybody pressing Ctrl+P on a legal document wants.
   */
  body {
    padding-bottom: 0;
    color: var(--ink);
    background: var(--surface);
  }

  /* Ink is expensive and a drop shadow is not information. */
  .plate,
  .plate--well {
    box-shadow: none;
    border-radius: 0;
    border-color: var(--border-strong);
    background: var(--surface);
    break-inside: avoid;
  }

  /* A measure is a screen-reading device; paper has its own column. */
  p {
    max-width: none;
  }

  /* A heading that prints as the last line of a page is a heading on the wrong page. */
  h2,
  h3 {
    break-after: avoid;
  }

  /*
   * Expand internal link targets, so a printed page stays usable. Without this the whole point of
   * the hub — that it points somewhere — is lost the moment it leaves the screen.
   */
  a[href^='/']::after {
    content: ' (minutesout.com' attr(href) ')';
    font-size: 0.9em;
  }
}
