/* ---------------------------------------------------------------------------
 * DESIGN TOKENS — copied verbatim from src/lib/design-tokens/dist/tokens.css by
 * clients/marketing/src/tokens.mjs at build time. Edit the token SOURCE
 * (src/lib/design-tokens/tokens.js) and run `npm run tokens:build`; an edit here
 * is overwritten by the next marketing build and caught by `npm run tokens:check`.
 * ------------------------------------------------------------------------- */

/*
  Sticker Console tokens, v3 "printed on paper" — GENERATED FILE, DO NOT EDIT.
  Source: src/lib/design-tokens/tokens.js · Regenerate: npm run tokens:build
  A hand edit here is reverted by the next build and fails `npm run tokens:check`.
*/

:root {
  /* color */
  --color-paper: #f6f6f3;
  --color-paper-lift-1: #ffffff;
  --color-paper-lift-2: #f0f0ec;
  --color-ink: #0d0e0f;
  --color-ink-secondary: #28292b;
  --color-ink-muted: #4e5054;
  --color-stamp: #2f6b46;
  --color-stamp-hover: #245538;
  --color-on-stamp: #ffffff;
  --color-delta-under: #1c5a3a;
  --color-delta-over: #9a1d39;
  --color-hold: #704700;
  --color-hairline: #e8e8e2;
  --color-rule: #dbdbd4;
  --color-rule-strong: #828589;
  --color-tearline: #828589;
  --color-stamp-wash: #eaf3ee;
  --color-delta-under-wash: #eaf3ee;
  --color-delta-over-wash: #fdeef1;
  --color-hold-wash: #fdf4e0;
  --color-paper-raised: #ffffff;
  --color-raised-gradient-from: #fcfcfd;
  --color-raised-gradient-to: #ffffff;
  --color-mat-gradient-from: #eef2ea;
  --color-mat-gradient-mid: #dde3dc;
  --color-mat-gradient-to: #d2d8d4;
  --color-stamp-gradient-from: #356f4a;
  --color-stamp-gradient-to: #2a6241;
  --color-edge-highlight: rgba(255, 255, 255, 0);
  --color-shadow-contact: rgba(16, 20, 24, 0.05);
  --color-shadow-cast: rgba(16, 20, 24, 0.14);
  --color-emphasis-cast: rgba(16, 20, 24, 0.22);
  --color-glow-accent: rgba(47, 107, 70, 0.55);
  --color-signal: #0b5fc4;
  --color-signal-wash: #e8f1fd;
  --color-verify: #0b5953;
  --color-verify-wash: #e6faf6;
  --color-ledger: #5e2fba;
  --color-ledger-wash: #f2edff;
  --color-stamp-wash-deep: #d7e8de;

  /* elevation */
  --elevation-sunk-blur: 3px;
  --elevation-contact-y: 1px;
  --elevation-contact-blur: 2px;
  --elevation-plate-y: 6px;
  --elevation-plate-blur: 16px;
  --elevation-plate-spread: -8px;
  --elevation-raised-y: 18px;
  --elevation-raised-blur: 40px;
  --elevation-raised-spread: -18px;
  --elevation-edge-y: 1px;
  --elevation-glow-blur: 18px;
  --elevation-glow-y: 6px;
  --elevation-glow-spread: -6px;

  /* type */
  --type-family-display: 'Space Grotesk', sans-serif;
  --type-family-body: Inter, sans-serif;
  --type-family-data: 'JetBrains Mono', monospace;
  --type-size-label: 11px;
  --type-size-cta-label: 12px;
  --type-size-body: 13px;
  --type-size-body-large: 14px;
  --type-size-panel-title: 16px;
  --type-size-input: 16px;
  --type-size-figure: 18px;
  --type-size-row-price: 22px;
  --type-size-row-price-large: 24px;
  --type-size-screen-title: 26px;
  --type-size-hero-price: 36px;
  --type-size-net-figure: 42px;
  --type-size-hero-delta: 40px;
  --type-size-hero-delta-feed: 64px;
  --type-size-hero-delta-feed-max: 104px;
  --type-weight-regular: 400;
  --type-weight-medium: 500;
  --type-weight-semibold: 600;
  --type-weight-bold: 700;
  --type-tracking-label: 0.08em;
  --type-tracking-body: 0em;
  --type-tracking-display: -0.02em;
  --type-line-height-hero: 1;
  --type-line-height-label: 1.3;
  --type-line-height-body: 1.5;
  --type-line-height-prose: 1.55;
  --type-numeric-data: tabular-nums;
  --type-numeric-prose: normal;
  --type-stretch-display: 100%;
  --type-min-size: 11px;

  /* space */
  --space-0: 0px;
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;
  --space-16: 64px;

  /* radius */
  --radius-document: 0px;
  --radius-control: 12px;
  --radius-floating: 14px;
  --radius-cap: 18px;
  --radius-pill: 99px;

  /* rule */
  --rule-hairline: 1px;
  --rule-strong: 2px;
  --rule-double: 3px;

  /* control */
  --control-cta: 40px;
  --control-button: 36px;
  --control-input: 40px;
  --control-touch-target: 44px;

  /* motion */
  --motion-duration-fast: 150ms;
  --motion-duration-enter: 180ms;
  --motion-duration-exit: 126ms;
  --motion-duration-slow: 200ms;
  --motion-duration-stamp-press: 220ms;
  --motion-easing-out: ease-out;
  --motion-exit-ratio: 0.7;
  --motion-stamp-press-scale: 1.04;
  --motion-stamp-in-scale: 1.4;
  --motion-stamp-in-rotate-deg: -6;
  --motion-stamp-in-delay: 120ms;
  --motion-print-in-offset: 6px;
  --motion-ruler-settle-offset: 12px;
}

/* Carbon (dark) — the SAME --color-* names, re-valued. Explicit choice first. */
[data-theme='dark'] {
  --color-paper: #0e1113;
  --color-paper-lift-1: #171a1d;
  --color-paper-lift-2: #22262a;
  --color-ink: #f2f4f2;
  --color-ink-secondary: #dde1df;
  --color-ink-muted: #a3aaad;
  --color-stamp: #aebe86;
  --color-stamp-hover: #c2d09c;
  --color-on-stamp: #141a0c;
  --color-delta-under: #c2d09c;
  --color-delta-over: #ff7e97;
  --color-hold: #e4a83f;
  --color-hairline: #282d32;
  --color-rule: #363c42;
  --color-rule-strong: #71787c;
  --color-tearline: #71787c;
  --color-stamp-wash: #1e2313;
  --color-delta-under-wash: #1e2313;
  --color-delta-over-wash: #2c1319;
  --color-hold-wash: #2a2011;
  --color-paper-raised: #1b1f22;
  --color-raised-gradient-from: #1e2225;
  --color-raised-gradient-to: #171a1d;
  --color-mat-gradient-from: #252b2c;
  --color-mat-gradient-mid: #1a1f21;
  --color-mat-gradient-to: #141819;
  --color-stamp-gradient-from: #b6c590;
  --color-stamp-gradient-to: #a5b67c;
  --color-edge-highlight: rgba(255, 255, 255, 0);
  --color-shadow-contact: rgba(0, 0, 0, 0.45);
  --color-shadow-cast: rgba(0, 0, 0, 0.7);
  --color-emphasis-cast: rgba(0, 0, 0, 0.55);
  --color-glow-accent: rgba(174, 190, 134, 0.45);
  --color-signal: #4aa9ff;
  --color-signal-wash: #10233a;
  --color-verify: #5eead4;
  --color-verify-wash: #0e2a27;
  --color-ledger: #ab8ff6;
  --color-ledger-wash: #1e1932;
  --color-stamp-wash-deep: #2b3320;
}

/* …and the system default, which stamps no attribute at all. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --color-paper: #0e1113;
    --color-paper-lift-1: #171a1d;
    --color-paper-lift-2: #22262a;
    --color-ink: #f2f4f2;
    --color-ink-secondary: #dde1df;
    --color-ink-muted: #a3aaad;
    --color-stamp: #aebe86;
    --color-stamp-hover: #c2d09c;
    --color-on-stamp: #141a0c;
    --color-delta-under: #c2d09c;
    --color-delta-over: #ff7e97;
    --color-hold: #e4a83f;
    --color-hairline: #282d32;
    --color-rule: #363c42;
    --color-rule-strong: #71787c;
    --color-tearline: #71787c;
    --color-stamp-wash: #1e2313;
    --color-delta-under-wash: #1e2313;
    --color-delta-over-wash: #2c1319;
    --color-hold-wash: #2a2011;
    --color-paper-raised: #1b1f22;
    --color-raised-gradient-from: #1e2225;
    --color-raised-gradient-to: #171a1d;
    --color-mat-gradient-from: #252b2c;
    --color-mat-gradient-mid: #1a1f21;
    --color-mat-gradient-to: #141819;
    --color-stamp-gradient-from: #b6c590;
    --color-stamp-gradient-to: #a5b67c;
    --color-edge-highlight: rgba(255, 255, 255, 0);
    --color-shadow-contact: rgba(0, 0, 0, 0.45);
    --color-shadow-cast: rgba(0, 0, 0, 0.7);
    --color-emphasis-cast: rgba(0, 0, 0, 0.55);
    --color-glow-accent: rgba(174, 190, 134, 0.45);
    --color-signal: #4aa9ff;
    --color-signal-wash: #10233a;
    --color-verify: #5eead4;
    --color-verify-wash: #0e2a27;
    --color-ledger: #ab8ff6;
    --color-ledger-wash: #1e1932;
    --color-stamp-wash-deep: #2b3320;
  }
}

/* ---------------------------------------------------------------------------
 * MARKETING PRESENTATION LAYER — copied verbatim from
 * clients/marketing/src/marketing.tokens.css by src/tokens.mjs at build time.
 * It is the ONE place this surface may name a value; styles.css names none.
 * Edit it THERE — an edit here is overwritten by the next marketing build.
 * ------------------------------------------------------------------------- */

/* ===========================================================================
 * THE MARKETING PRESENTATION LAYER — layer 2 of the built stylesheet, and the
 * ONLY file on this surface that may name a value.
 *
 * WHY IT EXISTS. Until 2026-08-24 layer 2 was `src/lib/console/console.css`,
 * the v3 shell the CRM also mounts. The v6 marketing direction is not the
 * console — it is a light-paper document with dark bands, a neon accent and a
 * type ramp that goes to 86px, none of which the console has or should. The
 * choice was to edit a file another surface owns (forbidden), fork a private
 * copy of it (worse — it drifts on the console's next edit), or UNMOUNT it and
 * declare what this surface actually needs. This is the third.
 *
 * WHAT STAYS SHARED, AND WHY IT MUST. Every SEMANTIC ink still comes from
 * `src/lib/design-tokens/dist/tokens.css` through a `var(--color-*)` below:
 * the grade stamp, the under/over-market delta, the hold amber, the paper and
 * plate grounds, the rules. The landing page renders THE PRODUCT'S OWN FEED
 * ROW — a real grade, a real delta — and if those forked, this site would be
 * advertising a product that does not match the one people sign up for. What is
 * local is PRESENTATION: type ramp, spacing, radii, motion, and the dark-band
 * grounds the shared palette has no concept of.
 *
 * ⚠️ THE LITERALS ARE COUNTED AND EACH ONE IS ARGUED. `styles.test.js` asserts
 * that `styles.css` contains none at all, that this file contains NOTHING BUT
 * custom-property declarations, and — for the two on-dark semantic inks — that
 * the literal EQUALS the token pipeline's own Carbon value. A literal a test
 * pins to its source of truth cannot drift; one that nothing pins is a fork.
 *
 * ⚠️ WHY A DARK BAND CANNOT JUST BE `data-theme="dark"`. It would be elegant —
 * `tokens.css` emits its Carbon block as a plain attribute selector, so any
 * element could opt in and every `--color-*` inside would resolve Carbon. It
 * does not work here for one measured reason: this design puts LIGHT CARDS
 * INSIDE dark bands (the step-02 score card, the grade dial), and there is no
 * `[data-theme='light']` block to switch back with — the pipeline emits `:root`,
 * `[data-theme='dark']` and a `prefers-color-scheme` copy, and nothing else. A
 * card inside a Carbon subtree would come out dark-on-dark. So the dark band
 * carries its OWN named grounds, and a light card inside it re-states the page
 * inks explicitly rather than inheriting the band's.
 * ======================================================================== */

:root {
  /* ── page grounds and inks — the shared palette, under this surface's names ──
     Renamed rather than used directly so a rule reads `var(--ms-plate)` and a
     reader can see at a glance which half of the stylesheet a value came from.
     They still MOVE with the token pipeline, because they are references. */
  --ms-paper: var(--color-paper);
  --ms-plate: var(--color-paper-raised);
  --ms-sunk: var(--color-paper-lift-2);
  --ms-ink: var(--color-ink);
  --ms-rule: var(--color-rule);
  --ms-hair: var(--color-hairline);

  /* ── the semantic inks — imported, never restated ──
     Grade, delta and hold. These are the product's own vocabulary and the one
     thing on this site that has to be true rather than merely on-brand. */
  --ms-moss: var(--color-stamp);
  --ms-moss-wash: var(--color-stamp-wash);
  --ms-on-moss: var(--color-on-stamp);
  --ms-under: var(--color-delta-under);
  --ms-over: var(--color-delta-over);
  --ms-over-wash: var(--color-delta-over-wash);
  --ms-hold: var(--color-hold);

  /* ── the dark band ────────────────────────────────────────────────────────
     ⚠️ NOT `--color-paper` UNDER `[data-theme='dark']`. A dark band is a
     COMPOSITIONAL element of a light page, not a palette state: it is present
     in Carbon too, where the page around it is already near-black and the band
     still has to read as a separate object. Three grounds because the design
     stacks them — the band, the ticker inside it, and a raised plate on top. */
  --ms-night: #0b0e0f;
  --ms-night-2: #141819;
  --ms-night-3: #1c2122;
  --ms-rule-night: #262d2d;

  /* ⚠️ ONE WHITE AND ONE BLACK, NOT A GREY RAMP (owner, v6 neon pass). Grey
     type is retired on this surface: black on light, white on dark, one value
     each side. `--ms-pale` is the on-dark ink; the page's on-light ink is
     `--ms-ink` above, which the shared palette owns. */
  --ms-pale: #ffffff;

  /* ── the accent ───────────────────────────────────────────────────────────
     The logo lime's hue (80°) at full saturation, derived from the brand rather
     than picked. It carries TYPE and FILLS on dark grounds only: measured
     against paper it is 1.11:1, which is unreadable, and that is why
     `--ms-moss` above survives as the green-on-paper. Ink on a neon fill is a
     near-black of its own — pure `#000` is harsh against a colour this bright. */
  --ms-neon: #bbff33;
  --ms-on-neon: #0b0f0e;

  /* ⚠️ THE ON-DARK OVER-MARKET INK IS PINNED TO THE PIPELINE'S CARBON VALUE.
     `--color-delta-over` is `#9a1d39` on paper, which measures ~2.3:1 on the
     night ground — a semantic ink that cannot be read is not a semantic ink.
     The pipeline's Carbon value is the one drawn FOR a dark ground, and it is
     restated here because CSS cannot read another selector's declaration.
     `styles.test.js` asserts this literal equals `TOKENS_DARK.deltaOver`, so
     the restatement cannot drift from its source. Same for the under-market
     ink, which the tape uses when the accent is spent elsewhere, and for the hold amber, which
     the sticker's comp ruler spends on the fair band. `--color-hold` is `#704700` on paper — a
     dark brown that reads as a smear on the night ground. */
  --ms-over-night: #ff7e97;
  --ms-under-night: #c2d09c;
  --ms-hold-night: #e4a83f;

  /* ── films: white and neon at low alpha over the night ground ─────────────
     Six alphas, not sixteen. Every hairline, inset and tint in the dark half of
     the design resolves to one of these, so a change to the band's depth is one
     edit rather than a sweep. `color-mix` over `--ms-pale` rather than a literal
     `rgba(255,255,255,…)`: the mix names its base, so the film follows the ink
     it is a film OF. */
  --ms-film-1: color-mix(in srgb, var(--ms-pale) 2.2%, transparent);
  --ms-film-2: color-mix(in srgb, var(--ms-pale) 4%, transparent);
  --ms-film-3: color-mix(in srgb, var(--ms-pale) 6%, transparent);
  --ms-film-4: color-mix(in srgb, var(--ms-pale) 9%, transparent);
  --ms-film-5: color-mix(in srgb, var(--ms-pale) 16%, transparent);
  --ms-film-6: color-mix(in srgb, var(--ms-pale) 20%, transparent);
  --ms-neon-line: color-mix(in srgb, var(--ms-neon) 32%, transparent);
  --ms-neon-edge: color-mix(in srgb, var(--ms-neon) 14%, transparent);
  --ms-neon-tint: color-mix(in srgb, var(--ms-neon) 7%, transparent);
  --ms-neon-glow: color-mix(in srgb, var(--ms-neon) 55%, transparent);
  --ms-neon-halo: color-mix(in srgb, var(--ms-neon) 22%, transparent);

  /* The travelling wash's two lights. The green one is the SEMANTIC moss, so
     the band's own light is the product's colour rather than a fourth green. */
  --ms-wash-neon: color-mix(in srgb, var(--ms-neon) 30%, transparent);
  --ms-wash-moss: color-mix(in srgb, var(--ms-moss) 78%, transparent);
  --ms-wash-moss-soft: color-mix(in srgb, var(--ms-moss) 34%, transparent);

  /* ⚠️ A MASK STOP IS AN ALPHA CHANNEL, NOT AN INK, and it still has to be a
     colour token. `-webkit-mask-image: linear-gradient(…, #000, transparent)`
     uses the BLACK only for its opacity — nothing paints it — but a bare hex in
     `styles.css` is indistinguishable from a real one to any guard, and the ban
     is only worth having while it has no exceptions. Named once here, used by
     the hero grid, the ticker's fade and the wash's own grid.
     The photograph's drop-shadow is the same shape: a shadow cast by a cut-out
     PNG, which has no plate to sit on, so it is darker than the plate cast. */
  --ms-mask-on: #000;
  --ms-shot-shadow: color-mix(in srgb, var(--ms-night) 55%, transparent);

  /* ── depth ────────────────────────────────────────────────────────────────
     Two shadows, not a ramp: a cast for a plate on paper, and a glow for the
     one object that sits on the night ground and has to look lit. Both are
     composed here rather than in `styles.css` so the surface has one answer to
     "how far off the page is this?". */
  --ms-cast: 0 18px 44px -26px color-mix(in srgb, var(--ms-night) 45%, transparent);
  --ms-cast-deep: 0 40px 80px -34px color-mix(in srgb, var(--ms-night) 80%, transparent);

  /* ── the type ramp ────────────────────────────────────────────────────────
     ⚠️ FLUID, AND THAT IS THE POINT OF DECLARING IT HERE. Every one of these is
     a `clamp()`, so the ramp is a property of the VIEWPORT rather than of a
     breakpoint — which is what lets the same rule serve 390 and 1440 without a
     media query per heading. The floor of each clamp is the phone value, and no
     value anywhere on this surface goes below 11px (craft gate 1). */
  --ms-t-hero: clamp(40px, 6.4vw, 86px);
  --ms-t-h1: clamp(34px, 5vw, 62px);
  --ms-t-h2: clamp(30px, 4.6vw, 58px);
  --ms-t-h2-sm: clamp(26px, 3.6vw, 42px);
  --ms-t-h3: clamp(30px, 4.2vw, 52px);
  --ms-t-figure: clamp(38px, 5vw, 66px);
  --ms-t-stat: clamp(30px, 3.6vw, 46px);
  --ms-t-lead: clamp(18px, 1.7vw, 21px);
  --ms-t-line: clamp(17px, 1.5vw, 19.5px);
  --ms-t-body: 16.5px;
  --ms-t-sm: 15.5px;
  --ms-t-xs: 14.5px;
  --ms-t-mono: 12.5px;
  --ms-t-label: 11px;
  --ms-t-micro: 11px;

  /* ── rhythm ───────────────────────────────────────────────────────────────
     The gutter and the measure. `--ms-gut` is the page's side padding at every
     width; `--ms-wide` is the one content measure, so a section is never wider
     than its neighbours by accident. */
  --ms-gut: clamp(20px, 4vw, 44px);
  --ms-wide: 1220px;
  --ms-sec-y: clamp(64px, 8vw, 124px);
  --ms-sec-gap: clamp(28px, 3.4vw, 48px);
  --ms-stack: clamp(34px, 4vw, 54px);

  /* ── radii ────────────────────────────────────────────────────────────────
     Four steps and a pill. The plate radius is the largest because a plate is
     the biggest object; a control never exceeds it. */
  --ms-r-plate: 20px;
  --ms-r-card: 18px;
  --ms-r-control: 12px;
  --ms-r-chip: 9px;
  --ms-r-pill: 99px;

  /* ── motion ───────────────────────────────────────────────────────────────
     ONE easing curve for everything that moves under a pointer, and three
     durations. A surface with five curves reads as five surfaces. Every rule
     that uses these is inside a `prefers-reduced-motion` escape at the foot of
     `styles.css` — see the note there, which also collapses the LAYOUT and not
     only the animation. */
  --ms-ease: cubic-bezier(0.2, 0.7, 0.3, 1);
  --ms-ease-rise: cubic-bezier(0.16, 0.9, 0.28, 1);
  --ms-fast: 0.18s;
  --ms-mid: 0.35s;
  --ms-slow: 0.7s;

  /* The masthead's measured height, written by `site.js` so the phone menu can
     be `position: fixed` under it. The fallback is the desktop measurement and
     exists so the menu is never off-screen in the frame before the script runs. */
  --ms-head-h: 84px;
}

/*
 * GENERATED by clients/marketing/tools/fetch-fonts.mjs — do not hand-edit.
 * Self-hosted woff2 faces; see ./README for the exact upstream request and the date.
 * Only the latin + latin-ext subsets are vendored; the unicode-range descriptors are
 * Google's own, so any other script falls back to the system face per-character.
 */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/inter-variable-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;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/inter-variable-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;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/inter-variable-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;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/inter-variable-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;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/inter-variable-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/inter-variable-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/inter-variable-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/inter-variable-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/jetbrains-mono-variable-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;
}

@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/jetbrains-mono-variable-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;
}

@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/jetbrains-mono-variable-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;
}

@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/jetbrains-mono-variable-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/jetbrains-mono-variable-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/jetbrains-mono-variable-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/space-grotesk-variable-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;
}

@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/space-grotesk-variable-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;
}

@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/space-grotesk-variable-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;
}

@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/space-grotesk-variable-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/space-grotesk-variable-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/space-grotesk-variable-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ===========================================================================
 * clients/marketing/src/styles.css — the MARKETING-LOCAL rules. Layer 4 of 4.
 *
 * WHAT CHANGED, AND WHY THE WHOLE FILE MOVED (v6 neon rebuild, 2026-08-24).
 * Layer 2 used to be `src/lib/console/console.css`, the v3 shell the CRM also
 * mounts, and this file was the marketing-local HALF of it. The v6 direction is
 * not the console: a light-paper document with dark bands, a neon accent, a type
 * ramp that goes to 86px and a motion layer. Editing a file another surface owns
 * was forbidden and forking it was worse, so the console layer is UNMOUNTED and
 * `marketing.tokens.css` declares what this surface needs. That file is the ONE
 * place a value may be named here.
 *
 * ⚠️ THIS FILE DECLARES NO COLOUR AT ALL — not a hex, not an `rgb()`, not a
 * keyword. Every paint is `var(--ms-*)` or `var(--color-*)`, and
 * `styles.test.js` asserts it with a negative control so the check cannot pass
 * vacuously. That is the same rule this file has always carried; what moved is
 * where the values live.
 *
 * ⚠️ SIX CLASS COLLISIONS WERE PAID FOR ONCE ALREADY. Building the v6 mock
 * produced `.r`, `summary::after`, `.f > span`, `.frow`, `.tk` and `.night h3`
 * — every one shipping a visible defect, every one invisible to the guards that
 * existed. They are why the section banners below are load-bearing:
 * `css-guards.js#duplicateKeyClasses` splits this file on them and refuses one
 * short class name claimed by two of them, and `#bareTypeSelectors` refuses a
 * rule aimed at an element TYPE unless `styles.test.js` allowlists it by name.
 * Rename before you re-use; the guard will tell you which two sections clashed.
 *
 * ⚠️ NOTHING PINS THE SCROLL. Two earlier passes used sticky scroll-scrub
 * sections and both were rejected as "the page has stopped responding". The only
 * `position: sticky` in this file is the masthead. Do not reintroduce a
 * scroll-jack — the timeline and the wash read scroll position and write
 * transforms, which is a different thing: the page never stops moving.
 * ======================================================================== */

/* ── §1 reset and base type ═══════════════════════════════════════════════ */

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

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--ms-paper);
  color: var(--ms-ink);
  font:
    400 var(--ms-t-body) / 1.6 Inter,
    system-ui,
    sans-serif;
  -webkit-font-smoothing: antialiased;
  /* ⚠️ NO `overflow-x: hidden` HERE, AND IT IS A BAN RATHER THAN AN OMISSION.
     `css-guards`' clipper rule refuses the html/body bandage on all three
     stylesheets for one reason: it makes `scrollWidth` report the CLIPPED width,
     so the verifier measures the bandage instead of the wound and a real
     overflow becomes unmeasurable. Everything on this page that is deliberately
     wider than its box clips ITSELF — the ticker, the tape's `.tapewrap`, the
     matrix's `.mx-scroll` — and the allowlist in `styles.test.js` is the record
     of which those are. */
}

h1,
h2,
h3 {
  margin: 0;
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 600;
  letter-spacing: -0.028em;
  line-height: 1.02;
  text-wrap: balance;
}

p {
  margin: 0;
}

a {
  color: inherit;
  text-decoration: none;
}

img {
  max-width: 100%;
}

/*
 * ⚠️ TWO RINGS, BECAUSE ONE INK CANNOT SERVE BOTH GROUNDS. Measured against the page's four
 * grounds: moss `#2f6b46` is 5.86:1 on paper but 3.06 / 2.82 / 2.57:1 on `--ms-night`,
 * `--ms-night-2` and `--ms-night-3` — two of the three UNDER the 3:1 floor WCAG 1.4.11 sets for a
 * focus indicator, on bands that carry the metro chips, the outline CTA, the ticker links, all
 * twelve footer links and the closing CTA. The accent is 16.11 / 14.87 / 13.54:1 on those same
 * grounds, and DESIGN-v6 §6 sanctions the accent for focus rings explicitly ("plus focus rings"),
 * so the dark half spends it there. `.night` is the band class; the default stays moss on paper,
 * where the accent would be 1.11:1 and invisible.
 *
 * ⚠️ AND NO `border-radius` ON THIS RULE. DESIGN-v6 §3 names it verbatim: "Never set
 * `border-radius` on a `:focus-visible` rule. It overrides the element's own radius; a focused
 * button snapping 12→2px was a live defect found during the v6 pass." It was set to 4px here, so a
 * focused 99px pill wore a 4px-cornered ring. `outline` follows the element's own border-radius on
 * its own; nothing needs to restate it.
 */
:focus-visible {
  outline: 2.5px solid var(--ms-moss);
  outline-offset: 3px;
}

.night :focus-visible,
.night:focus-visible {
  outline-color: var(--ms-neon);
}

/* ⚠️ PARKED WITH A TRANSFORM, NOT AT `left: -9999px`. The off-screen-left idiom is the classic
   one and it is a horizontal OVERFLOW: `verify:responsive` walks ancestors for a clipper, finds
   none over an unsized absolutely-positioned box, and reports "a.skiplink runs 9999px past the
   390px viewport" — a real measurement of a real overflow, on the one element that exists to help
   the visitor the verifier cannot see. Measured at 390 through the real host. A vertical transform
   parks it just as completely, costs nothing, and does not move the layout. */
.skiplink {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 100;
  background: var(--ms-plate);
  color: var(--ms-ink);
  padding: 12px 18px;
  border-radius: 0 0 var(--ms-r-control) 0;
  transform: translateY(-200%);
}

.skiplink:focus {
  transform: none;
}

.wrap {
  max-width: var(--ms-wide);
  margin: 0 auto;
  padding-inline: var(--ms-gut);
}

.eyebrow {
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-label);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ms-ink);
}

.num {
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.035em;
}

.num i {
  font-style: normal;
  font-size: 0.52em;
  margin-left: 3px;
  letter-spacing: 0;
}

.mono {
  font-family: 'JetBrains Mono', monospace;
  font-variant-numeric: tabular-nums;
}

/* ── §2 buttons ═══════════════════════════════════════════════════════════
   ⚠️ THE RATION IS ONE FILLED ACTION PER VIEWPORT, and it survived the accent
   change unchanged — what moved is the colour (v6's green, not safety orange).
   `.btn-fill` is that one; every other action on a screen is `.btn-line`.    */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  border-radius: var(--ms-r-control);
  font:
    500 var(--ms-t-sm) Inter,
    sans-serif;
  padding: 15px 24px;
  border: 1.5px solid transparent;
  cursor: pointer;
  transition:
    transform var(--ms-fast) var(--ms-ease),
    box-shadow var(--ms-fast) ease,
    background var(--ms-fast) ease;
}

.btn-fill {
  background: var(--ms-neon);
  color: var(--ms-on-neon);
  box-shadow: 0 8px 22px -8px var(--ms-neon-glow);
}

.btn-fill:hover {
  transform: translateY(-2px);
  box-shadow: 0 14px 32px -10px var(--ms-neon-glow);
}

.btn-line {
  border-color: var(--ms-rule);
  background: var(--ms-plate);
}

.btn-line:hover {
  border-color: var(--ms-ink);
  transform: translateY(-2px);
}

/* ⚠️ THE OUTLINE BUTTON ON A DARK BAND HAS TO RESTATE ITSELF, and this is the trap the file header
   names: a light surface inside a dark band inheriting the band's ink. `.btn-line` paints
   `--ms-plate` (white) and takes its colour from the cascade, so on `.night` it rendered a WHITE
   PILL WITH WHITE TEXT — a button with no label, which is invisible in a diff and obvious in a
   screenshot. Caught by reading the PNG, which is why that rule exists. */
.night .btn-line {
  background: transparent;
  border-color: var(--ms-rule-night);
  color: var(--ms-pale);
}

.night .btn-line:hover {
  border-color: var(--ms-pale);
}

.btn-block {
  width: 100%;
}

.btn-arrow {
  width: 16px;
  height: 16px;
  transition: transform var(--ms-fast) ease;
}

.btn:hover .btn-arrow {
  transform: translateX(3px);
}

/* ── §3 the masthead ══════════════════════════════════════════════════════
   ONE COLOUR, ALWAYS (owner). It does not swap on scroll: a masthead that
   changes ground mid-page is a second masthead, and the progress bar already
   says where the reader is.                                                 */

.head {
  position: sticky;
  top: 0;
  z-index: 60;
  background: var(--ms-night);
  border-bottom: 1px solid var(--ms-rule-night);
}

.head .wrap {
  display: flex;
  align-items: center;
  gap: 20px;
  padding-block: 13px;
}

.logo {
  width: 62px;
  flex: none;
  /* The mark's three inks. `--mk-ink` is the wordmark's `VM`, which has to be
     the on-dark ink here because the masthead is always night. */
  --mk-accent: var(--ms-neon);
  --mk-face: var(--ms-night);
  --mk-ink: var(--ms-pale);
}

.logo svg {
  width: 100%;
  height: auto;
  display: block;
}

.nav {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 28px;
  font-size: var(--ms-t-xs);
  color: var(--ms-pale);
}

.nav a:hover {
  color: var(--ms-neon);
}

.nav .btn {
  padding: 11px 18px;
  font-size: 14px;
}

.cta {
  margin-left: 18px;
}

.burger {
  display: none;
  width: 42px;
  height: 42px;
  margin-left: 12px;
  border: 0;
  background: transparent;
  cursor: pointer;
  padding: 11px 9px;
  flex-direction: column;
  justify-content: space-between;
}

.burger span {
  display: block;
  height: 2px;
  border-radius: 2px;
  background: var(--ms-pale);
  transition:
    transform 0.28s var(--ms-ease),
    opacity var(--ms-fast) ease;
}

.burger.on span:nth-child(1) {
  transform: translateY(9px) rotate(45deg);
}

.burger.on span:nth-child(2) {
  opacity: 0;
}

.burger.on span:nth-child(3) {
  transform: translateY(-9px) rotate(-45deg);
}

/* The scroll progress bar — the masthead's only state. */
.prog {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  background: transparent;
  overflow: hidden;
}

.prog i {
  display: block;
  height: 100%;
  width: 100%;
  background: var(--ms-neon);
  box-shadow: 0 0 10px var(--ms-neon-glow);
  transform: scaleX(0);
  transform-origin: 0 50%;
}

@media (max-width: 880px) {
  .burger {
    display: flex;
  }

  .cta {
    margin-left: auto;
    padding: 10px 15px;
    font-size: 13.5px;
  }

  /* ⚠️ THE MENU IS `position: fixed` UNDER A MEASURED HEADER. `--ms-head-h` is
     written by `site.js`; the token's fallback is the desktop measurement, so
     the menu is never off-screen in the frame before the script runs. */
  .nav {
    position: fixed;
    top: var(--ms-head-h);
    left: 0;
    right: 0;
    margin: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--ms-night);
    border-bottom: 1px solid var(--ms-rule-night);
    padding: 6px var(--ms-gut) 24px;
    transform: translateY(-10px);
    opacity: 0;
    visibility: hidden;
    transition:
      transform 0.3s var(--ms-ease),
      opacity 0.24s ease,
      visibility 0.24s;
    max-height: calc(100dvh - var(--ms-head-h));
    overflow-y: auto;
  }

  .nav.open {
    transform: none;
    opacity: 1;
    visibility: visible;
  }

  .nav a {
    padding: 17px 2px;
    border-bottom: 1px solid var(--ms-rule-night);
    font-size: 17.5px;
    color: var(--ms-pale);
    font-family: 'Space Grotesk', sans-serif;
    font-weight: 500;
    letter-spacing: -0.015em;
  }

  .nav a:last-child {
    border-bottom: 0;
  }

  body.locked {
    overflow: hidden;
  }

  /* ⚠️ WITHOUT JAVASCRIPT THE MENU IS ALWAYS OPEN, never always closed. The
     burger is the only thing that can open it and the burger needs a script, so
     the no-JS fallback has to be the state that shows the links. */
  .no-js .nav {
    position: static;
    transform: none;
    opacity: 1;
    visibility: visible;
    max-height: none;
  }

  .no-js .burger {
    display: none;
  }
}

@media (max-width: 400px) {
  .cta {
    padding: 9px 12px;
    font-size: 13px;
  }
}

/* ── §4 section frame and the dark band ═══════════════════════════════════ */

.sec {
  padding-block: var(--ms-sec-y);
}

.sec-tight {
  padding-top: 0;
}

.sec-mid {
  padding-block: clamp(38px, 5vw, 64px);
}

.sec-top {
  max-width: 52ch;
}

.sec-top h2 {
  font-size: var(--ms-t-h2);
  margin-top: 14px;
}

.sec-top .line {
  margin-top: 16px;
  font-size: var(--ms-t-line);
  color: var(--ms-ink);
  max-width: 44ch;
}

.h2-sm {
  font-size: var(--ms-t-h2-sm);
}

.night {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background: var(--ms-night);
  color: var(--ms-pale);
}

.night > *:not(.wash) {
  position: relative;
  z-index: 1;
}

.night h2,
.night h3 {
  color: var(--ms-pale);
}

.night .eyebrow,
.night .sec-top .line {
  color: var(--ms-pale);
}

.night .num i {
  color: var(--ms-pale);
}

/* ⚠️ A LIGHT SURFACE INSIDE A DARK BAND DECLARES ITS OWN INK. Inheriting the
   band's is how a card title shipped white on white in the mock — the failure
   is invisible in a diff and obvious only in a screenshot. `.card` and `.play`
   are the two light plates that appear inside `.night`, and both restate the
   page inks rather than relying on cascade order. */
.night .card,
.night .play {
  color: var(--ms-ink);
}

.night .card h2,
.night .card h3,
.night .play h2,
.night .play h3 {
  color: var(--ms-ink);
}

/* The travelling wash. One pass of light crossing the band top-right →
   bottom-left as it moves through the viewport; `site.js` writes the three
   custom properties from a rAF loop. Both radial lights are named colours: the
   green one is the SEMANTIC moss, so the band is lit by the product's colour. */
.wash {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: var(--gi, 0.55);
  transition: opacity var(--ms-mid) linear;
  background:
    radial-gradient(64% 48% at var(--gx, 74%) var(--gy, 12%), var(--ms-wash-neon), transparent 70%),
    radial-gradient(
      58% 46% at calc(102% - var(--gx, 74%)) calc(96% - var(--gy, 12%)),
      var(--ms-wash-moss),
      transparent 72%
    ),
    radial-gradient(120% 60% at 50% 116%, var(--ms-wash-moss-soft), transparent 74%);
}

.wash::after {
  content: '';
  position: absolute;
  inset: 0;
  opacity: 0.42;
  background-image:
    linear-gradient(var(--ms-film-2) 1px, transparent 1px),
    linear-gradient(90deg, var(--ms-film-2) 1px, transparent 1px);
  background-size: 72px 72px;
  -webkit-mask-image: radial-gradient(
    80% 60% at var(--gx, 74%) var(--gy, 12%),
    var(--ms-mask-on),
    transparent 76%
  );
  mask-image: radial-gradient(
    80% 60% at var(--gx, 74%) var(--gy, 12%),
    var(--ms-mask-on),
    transparent 76%
  );
}

/* ── §5 reveal on scroll ══════════════════════════════════════════════════
   ⚠️ IT FAILS OPEN, AND THAT IS THE WHOLE DESIGN. The hidden state is scoped to
   `.js`, which `site.js` adds — so with the script blocked, broken or simply
   slow, every `.rv` is visible from the first paint. `site.js` also carries a
   timed belt that reveals everything regardless. And the classes are NEVER
   stripped after animating: other rules key off `.in`, and removing them blanked
   every step visual in the mock.                                            */

.js .rv {
  opacity: 0;
  transform: translateY(22px);
  transition:
    opacity var(--ms-slow) ease,
    transform var(--ms-slow) var(--ms-ease);
}

.js .rv.in {
  opacity: 1;
  transform: none;
}

/* ── §6 the hero ══════════════════════════════════════════════════════════ */

.hero {
  position: relative;
  overflow: hidden;
}

.hero::after {
  content: '';
  position: absolute;
  inset: 0;
  opacity: 0.5;
  background-image:
    linear-gradient(var(--ms-film-2) 1px, transparent 1px),
    linear-gradient(90deg, var(--ms-film-2) 1px, transparent 1px);
  background-size: 64px 64px;
  -webkit-mask-image: radial-gradient(90% 70% at 50% 30%, var(--ms-mask-on), transparent 78%);
  mask-image: radial-gradient(90% 70% at 50% 30%, var(--ms-mask-on), transparent 78%);
}

.hero .wrap {
  position: relative;
  z-index: 2;
  padding-block: clamp(56px, 8vw, 116px) clamp(58px, 8vw, 106px);
}

.hero-grid {
  display: grid;
  gap: clamp(38px, 5vw, 64px);
  align-items: center;
  grid-template-columns: minmax(0, 1.04fr) minmax(0, 0.96fr);
}

.hero h1 {
  font-size: var(--ms-t-hero);
  letter-spacing: -0.042em;
  margin-top: 20px;
}

.hero h1 .hl {
  color: var(--ms-neon);
}

.hero .sub {
  margin-top: 24px;
  font-size: var(--ms-t-lead);
  color: var(--ms-pale);
  max-width: 38ch;
  line-height: 1.5;
}

.hero .acts {
  margin-top: 36px;
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}

.fine {
  margin-top: 18px;
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-label);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ms-pale);
}

/* The headline's words rise out of their own line box. `site.js` wraps each
   word; with no script the `<h1>` is plain text and simply sits there — which
   is why every rule here is `.js`-scoped: the elements do not exist otherwise.

   ⚠️ THE MASK HAD NO ROOM FOR A DESCENDER, and the shipped headline hides it.
   Measured at DPR 2 against the type's own luminance: "Great deals don't wait.
   Neither do we." ends 15 / 17 / 27 device px clear of the mask edge at 390 /
   768 / 1440 — because that sentence contains NO DESCENDER ANYWHERE. Force a
   `g` or a `y` in and the ink lands on the mask's final row at 390 and 1440,
   with 2px left at 768. So the headline renders correctly today and would clip
   the first time anyone edits the copy, with nothing to catch it.

   The fix is bottom padding on the mask, TAKEN STRAIGHT BACK as a negative
   margin: `.w` is an inline-block with `vertical-align: top`, so the line box
   is sized from its MARGIN box — the two cancel and the leading does not move.
   The rise offset grows by the same amount, or the taller mask would show the
   top of each word before it rises. */
.hero h1 .w {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  padding-bottom: 0.16em;
  margin-bottom: -0.16em;
}

.js .hero h1 .w > i {
  display: inline-block;
  /* Space Grotesk ships no italic, so a browser asked for one SYNTHESISES an
     oblique — and the mask above clips the lean. This is what stops it, and it
     is why `site.js` must add the `js` class rather than only removing
     `no-js`: with the class missing this rule never applied and the headline
     rendered leaning and cut (owner-reported, 2026-08-24). */
  font-style: normal;
  transform: translateY(calc(105% + 0.16em));
  transition: transform 0.9s var(--ms-ease-rise);
}

.js .hero h1.lift .w > i {
  transform: none;
}

.stage {
  position: relative;
  z-index: 2;
  perspective: 1100px;
  perspective-origin: 60% 30%;
}

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

/* ── §7 the market window sticker ═════════════════════════════════════════
   The hero artifact: a glass document standing on the dark hero, with the
   vehicle floating free. ⚠️ THE SOURCE IMAGE IS ALREADY A CUT-OUT — there is no
   plate behind it, and adding one would put a rectangle around a truck that was
   masked precisely so it would not need one.                                */

.sticker {
  position: relative;
  border-radius: var(--ms-r-plate);
  overflow: hidden;
  color: var(--ms-pale);
  font-size: var(--ms-t-sm);
  background: var(--ms-film-2);
  backdrop-filter: blur(10px);
  border: 1px solid var(--ms-neon-line);
  box-shadow: var(--ms-cast-deep);
  transform-style: preserve-3d;
  will-change: transform;
}

.sk-head {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  padding: 13px 20px;
  border-bottom: 1px solid var(--ms-neon-line);
  background: var(--ms-neon-tint);
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-label);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ms-neon);
}

.sk-body {
  padding: 17px 20px 16px;
}

.sk-top {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  align-items: flex-start;
}

/* ⚠️ AN `<h2>`, NOT AN `<h3>`. The sticker is the first thing under the hero's `<h1>`, so an
   `<h3>` here jumped a level and left a hole in the only structure a screen reader has — caught by
   the outline walk in `build.test.js`, which no screenshot can see. */
.sk-top h2 {
  font-size: clamp(19px, 1.9vw, 23px);
  letter-spacing: -0.025em;
  color: var(--ms-pale);
}

.sk-spec {
  margin-top: 8px;
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-label);
  line-height: 1.75;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ms-pale);
}

.sk-stamp {
  flex: none;
  font-family: 'JetBrains Mono', monospace;
  font-weight: 700;
  font-size: clamp(17px, 1.9vw, 23px);
  letter-spacing: 0.13em;
  color: var(--ms-neon);
  border: 3px solid var(--ms-neon);
  padding: 7px 16px 5px;
  transform: rotate(-2.5deg);
  white-space: nowrap;
}

.sk-shot {
  margin: 10px 0 0;
}

figure {
  margin: 0;
}

.sk-shot img {
  display: block;
  width: 100%;
  height: auto;
  filter: drop-shadow(0 16px 22px var(--ms-shot-shadow));
}

.sk-cap {
  margin-top: 9px;
  text-align: center;
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-micro);
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ms-pale);
  opacity: 0.7;
}

.sk-figs {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  margin-top: 13px;
  border: 1px solid var(--ms-film-6);
  border-radius: 10px;
  overflow: hidden;
}

.sk-fig {
  padding: 11px 13px;
  border-right: 1px solid var(--ms-film-6);
}

.sk-figs .sk-fig:last-child {
  border-right: 0;
}

.sk-fig .k {
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-micro);
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ms-pale);
  opacity: 0.72;
}

.sk-fig .v {
  margin-top: 5px;
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 600;
  font-size: clamp(20px, 2.3vw, 27px);
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  color: var(--ms-pale);
}

/* The one figure the accent is spent on: the delta in the reader's favour. */
.sk-fig .v.under {
  color: var(--ms-neon);
}

.sk-rule {
  margin-top: 19px;
  padding-bottom: 2px;
}

.sk-track {
  position: relative;
  height: 7px;
  border-radius: 3px;
  background: linear-gradient(
    90deg,
    var(--ms-neon) 0%,
    var(--ms-under-night) 26%,
    var(--ms-hold-night) 48%,
    var(--ms-film-6) 70%,
    var(--ms-film-6) 100%
  );
}

.sk-tick {
  position: absolute;
  top: -5px;
  bottom: -5px;
  width: 2px;
  background: var(--ms-pale);
  opacity: 0.6;
}

.sk-tick.mvi {
  opacity: 1;
  width: 3px;
  top: -8px;
  bottom: -8px;
}

.sk-ask {
  position: absolute;
  top: -11px;
  width: 0;
  height: 0;
  transform: translateX(-6px);
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-top: 8px solid var(--ms-neon);
}

.sk-lab {
  position: relative;
  height: 16px;
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-label);
  letter-spacing: 0.07em;
  font-variant-numeric: tabular-nums;
  color: var(--ms-pale);
}

.sk-lab .sk-at {
  position: absolute;
  white-space: nowrap;
  transform: translateX(-50%);
}

.sk-lab.above {
  margin-bottom: 15px;
}

.sk-lab.below {
  margin-top: 9px;
}

.sk-lab .hi {
  color: var(--ms-neon);
  font-weight: 500;
}

.sk-lab .edge {
  transform: none;
}

.sk-lab .edge.r {
  transform: translateX(-100%);
}

/* ⚠️ THE POSITIONS ARE CLASSES, NOT INLINE STYLES. The site's CSP is
   `style-src 'self'`, so a `style="left:15%"` attribute is markup the browser
   REFUSES — the ruler would collapse to a stack at the origin. These five
   percentages are fixed marketing copy, so naming them costs nothing. */
.sk-at-0 {
  left: 0;
}

.sk-at-ask {
  left: 15%;
}

.sk-at-lo {
  left: 26%;
}

.sk-at-mid {
  left: 30%;
}

.sk-at-mvi {
  left: 62%;
}

.sk-at-end {
  left: calc(100% - 2px);
}

.sk-at-full {
  left: 100%;
}

.sk-foot {
  display: flex;
  justify-content: space-between;
  gap: 18px;
  align-items: center;
  flex-wrap: wrap;
  padding: 12px 20px 14px;
  border-top: 1px solid var(--ms-film-5);
  background: var(--ms-film-2);
}

.sk-code svg {
  display: block;
  width: 168px;
  height: 30px;
  fill: var(--ms-pale);
}

.sk-vin {
  margin-top: 6px;
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-label);
  letter-spacing: 0.09em;
  color: var(--ms-pale);
  opacity: 0.8;
}

.sk-meta {
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-micro);
  line-height: 1.9;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  text-align: right;
  color: var(--ms-pale);
  opacity: 0.8;
}

.sk-toast {
  position: absolute;
  right: -10px;
  bottom: -30px;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 9px;
  background: var(--ms-night-3);
  border: 1px solid var(--ms-neon-line);
  border-radius: var(--ms-r-control);
  padding: 12px 17px;
  font-size: 13.5px;
  color: var(--ms-pale);
  box-shadow: var(--ms-cast-deep);
  white-space: nowrap;
}

.sk-toast b {
  font-weight: 600;
}

.sk-toast .dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--ms-neon);
  flex: none;
  box-shadow: 0 0 10px var(--ms-neon-glow);
}

.js .sk-toast {
  animation: toast-in 0.8s var(--ms-ease-rise) 0.55s both;
}

@keyframes toast-in {
  from {
    opacity: 0;
    transform: translateY(14px) scale(0.94);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

@media (max-width: 560px) {
  /* The band edges crowd the delta at phone width; the two that matter stay. */
  .sk-lab .mid {
    display: none;
  }

  .sk-figs {
    grid-template-columns: 1fr;
  }

  .sk-fig {
    border-right: 0;
    border-bottom: 1px solid var(--ms-film-6);
  }

  .sk-figs .sk-fig:last-child {
    border-bottom: 0;
  }

  .sk-toast {
    right: 0;
    left: 0;
    bottom: -26px;
    justify-content: center;
    white-space: normal;
    text-align: center;
  }

  .sk-meta {
    text-align: left;
  }
}

/* ── §8 the ticker ════════════════════════════════════════════════════════ */

.ticker {
  background: var(--ms-night-2);
  border-block: 1px solid var(--ms-rule-night);
  overflow: hidden;
  padding-block: 13px;
  -webkit-mask-image: linear-gradient(
    90deg,
    transparent,
    var(--ms-mask-on) 7%,
    var(--ms-mask-on) 93%,
    transparent
  );
  mask-image: linear-gradient(
    90deg,
    transparent,
    var(--ms-mask-on) 7%,
    var(--ms-mask-on) 93%,
    transparent
  );
}

.tick-row {
  display: flex;
  gap: 0;
  width: max-content;
  animation: slide-l 44s linear infinite;
}

.ticker:hover .tick-row {
  animation-play-state: paused;
}

@keyframes slide-l {
  to {
    transform: translateX(-50%);
  }
}

/* ⚠️ `.tick-item`, NOT `.tk`. `.tk` was the ticker item AND the ruler tick in
   the mock, and the collision rendered the ruler's ticks as grey blocks. */
.tick-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 26px;
  white-space: nowrap;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  color: var(--ms-pale);
  letter-spacing: 0.03em;
  border-right: 1px solid var(--ms-rule-night);
}

.tick-item b {
  color: var(--ms-pale);
  font-weight: 400;
}

.tick-item .dd {
  color: var(--ms-neon);
  font-variant-numeric: tabular-nums;
}

.tick-item .dd.up {
  color: var(--ms-over-night);
}

/* ── §9 the stat band ═════════════════════════════════════════════════════ */

.stats {
  border-bottom: 1px solid var(--ms-rule);
  background: var(--ms-plate);
}

.stats .wrap {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(16px, 3vw, 40px);
  padding-block: 34px;
}

.stat .v {
  font-size: var(--ms-t-stat);
  color: var(--ms-ink);
}

.stat .k {
  margin-top: 5px;
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-label);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ms-ink);
}

@media (max-width: 820px) {
  .stats .wrap {
    grid-template-columns: repeat(2, 1fr);
    gap: 26px;
  }
}

/* ── §10 the three steps ══════════════════════════════════════════════════
   Stacked rows, alternating sides, revealed on scroll. ⚠️ `.srow`, and the form
   row two sections down is `.form-row` — in the mock both were `.frow`, which
   put a phantom 74px gap in the contact form.                               */

.flow {
  margin-top: clamp(26px, 3.4vw, 44px);
}

.srow {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(26px, 4vw, 72px);
  align-items: center;
  padding-block: clamp(38px, 5vw, 74px);
  border-top: 1px solid var(--ms-rule-night);
}

.srow:first-child {
  border-top: 0;
  padding-top: clamp(20px, 2.6vw, 34px);
}

.srow:nth-child(even) .fcopy {
  order: 2;
}

.srow:nth-child(even) .fart {
  order: 1;
}

.fcopy .step-n {
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-label);
  letter-spacing: 0.14em;
  color: var(--ms-neon);
}

.fcopy h3 {
  font-size: var(--ms-t-h3);
  margin-top: 12px;
  letter-spacing: -0.035em;
}

.fcopy p {
  margin-top: 14px;
  color: var(--ms-pale);
  font-size: 17.5px;
  max-width: 40ch;
}

.fcopy .meta {
  margin-top: 16px;
  max-width: none;
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-label);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ms-pale);
}

.fart {
  display: grid;
  place-items: center;
  perspective: 1100px;
}

.fart .card {
  width: min(392px, 84vw);
}

.js .fart > * {
  transform: scale(0.93) rotateX(9deg);
  opacity: 0;
  transition:
    transform 0.85s var(--ms-ease-rise),
    opacity var(--ms-slow) ease;
}

.js .srow.in .fart > * {
  transform: none;
  opacity: 1;
}

/* Face 1 — the scope. */
.scope-big {
  width: min(360px, 74vw);
  aspect-ratio: 1;
  position: relative;
  border-radius: 50%;
  border: 2px solid var(--ms-neon-line);
  background: radial-gradient(circle at 50% 50%, var(--ms-neon-tint), transparent 68%);
}

.scope-big::before,
.scope-big::after {
  content: '';
  position: absolute;
  border-radius: 50%;
  border: 1px solid var(--ms-neon-edge);
}

.scope-big::before {
  inset: 19%;
}

.scope-big::after {
  inset: 38%;
}

.scope-sweep {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  overflow: hidden;
}

.scope-sweep i {
  position: absolute;
  inset: 0;
  background: conic-gradient(from 0deg, var(--ms-neon-glow), transparent 66deg, transparent);
  animation: spin 3.6s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

.pin-d {
  position: absolute;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--ms-neon);
  transform: translate(-50%, -50%) scale(0.5);
  opacity: 0.25;
  animation: blip 3.6s linear infinite;
}

@keyframes blip {
  0%,
  74% {
    opacity: 0.22;
    transform: translate(-50%, -50%) scale(0.5);
  }

  80% {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1.5);
  }

  100% {
    opacity: 0.22;
    transform: translate(-50%, -50%) scale(0.5);
  }
}

.pin-1 {
  left: 31%;
  top: 38%;
  animation-delay: -2.9s;
}

.pin-2 {
  left: 68%;
  top: 29%;
  animation-delay: -0.4s;
}

.pin-3 {
  left: 75%;
  top: 62%;
  animation-delay: -1.1s;
}

.pin-4 {
  left: 44%;
  top: 71%;
  animation-delay: -1.9s;
}

.pin-5 {
  left: 57%;
  top: 47%;
  animation-delay: -3.3s;
}

/* Face 3 — the alert on a lock screen. */
.lock {
  width: min(360px, 78vw);
  border-radius: 22px;
  padding: 16px;
  background: linear-gradient(180deg, var(--ms-night-3), var(--ms-night-2));
  border: 1px solid var(--ms-rule-night);
  box-shadow: var(--ms-cast-deep);
}

.lock .time {
  text-align: center;
  font-family: 'Space Grotesk', sans-serif;
  font-size: 44px;
  font-weight: 600;
  color: var(--ms-pale);
  letter-spacing: -0.03em;
}

.lock .day {
  text-align: center;
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-label);
  color: var(--ms-pale);
  letter-spacing: 0.12em;
  margin-top: 2px;
}

.note-card {
  margin-top: 22px;
  border-radius: 15px;
  padding: 14px 15px;
  background: var(--ms-film-4);
  backdrop-filter: blur(8px);
  border: 1px solid var(--ms-film-4);
  animation: drop-in var(--ms-slow) var(--ms-ease-rise) 0.25s both;
}

@keyframes drop-in {
  from {
    opacity: 0;
    transform: translateY(-16px) scale(0.95);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

.note-h {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-micro);
  letter-spacing: 0.1em;
  color: var(--ms-pale);
  text-transform: uppercase;
}

.note-h .ic {
  width: 17px;
  height: 17px;
  border-radius: 5px;
  flex: none;
  --mk-accent: var(--ms-neon);
  --mk-face: var(--ms-night);
}

.note-h .ic svg {
  display: block;
  width: 100%;
  height: 100%;
}

.note-h .ago {
  margin-left: auto;
  text-transform: none;
  letter-spacing: 0.04em;
}

.note-card .big {
  margin-top: 9px;
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 600;
  font-size: 17px;
  color: var(--ms-pale);
  letter-spacing: -0.015em;
}

.note-card .sml {
  margin-top: 4px;
  font-size: 13px;
  color: var(--ms-pale);
  line-height: 1.45;
}

@media (max-width: 900px) {
  .srow {
    grid-template-columns: 1fr;
    gap: 26px;
    padding-block: 38px;
  }

  .srow:nth-child(even) .fcopy {
    order: 1;
  }

  .srow:nth-child(even) .fart {
    order: 2;
  }
}

/* ── §11 the card, and the grade dial ═════════════════════════════════════
   The product's own feed row, rendered at marketing size. Every ink in this
   section is a SEMANTIC one — the stamp, the delta, the over-market rose — for
   the reason `marketing.tokens.css` gives: this has to be true, not on-brand. */

.card {
  background: var(--ms-plate);
  border: 1px solid var(--ms-rule);
  border-radius: var(--ms-r-plate);
  overflow: hidden;
  box-shadow: var(--ms-cast);
}

.card .shot {
  position: relative;
  background: var(--ms-sunk);
}

.card .shot img {
  display: block;
  width: 100%;
  height: auto;
}

.card .shot .tag {
  position: absolute;
  left: 14px;
  top: 14px;
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-micro);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ms-ink);
  background: var(--ms-plate);
  padding: 5px 9px;
  border-radius: 6px;
}

.card-b {
  padding: 22px 24px 26px;
}

.card-h {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  align-items: flex-start;
}

.card-h h3 {
  font-size: 20px;
}

.card-h .sp {
  margin-top: 6px;
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-label);
  color: var(--ms-ink);
  letter-spacing: 0.05em;
}

.card-h .h3-sm {
  font-size: 18px;
}

/* ⚠️ `.grade-chip`, NOT `.stamp`, AND THE RENAME IS THE RATION MADE STRUCTURAL. The design
   contract rations the STAMP — the rotated, ruled signature device — to ONE per page, and
   `build.test.js` counts it with a word-bounded `\bstamp\b` inside class attributes. This is not
   that device: it is the product's own grade chip, the same class of object as the tape's `.gp`
   pill, and the landing page shows it three times because three different product surfaces are on
   screen. The hero sticker's `.sk-stamp` is the one stamp. */
.grade-chip {
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-label);
  letter-spacing: 0.13em;
  padding: 8px 13px;
  border-radius: var(--ms-r-chip);
  border: 2px solid currentColor;
  white-space: nowrap;
  font-weight: 500;
  color: var(--ms-moss);
  transition: color 0.25s ease;
}

.grade-chip.ov,
.grade-chip.rk {
  color: var(--ms-over);
}

.grade-chip.fa {
  color: var(--ms-ink);
}

.figs {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 18px;
  margin-top: 22px;
}

.figs-tight {
  margin-top: 24px;
}

.figs .k {
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-micro);
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ms-ink);
}

.figs .ask .v {
  font-size: 32px;
  margin-top: 3px;
}

.figs .dl {
  text-align: right;
}

.figs .dl .v {
  font-size: clamp(42px, 5.4vw, 62px);
  color: var(--ms-under);
  line-height: 0.92;
  transition: color 0.25s ease;
}

.figs .dl .v.v-md {
  font-size: 44px;
}

.figs .dl .v.v-sm {
  font-size: 32px;
}

.figs .dl.ov .v {
  color: var(--ms-over);
}

.figs .dl .k {
  margin-top: 6px;
}

.bar {
  margin-top: 20px;
  height: 10px;
  border-radius: var(--ms-r-pill);
  background: var(--ms-sunk);
  position: relative;
}

.bar .fill {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  border-radius: var(--ms-r-pill);
  background: var(--ms-moss);
  transition:
    width var(--ms-fast) ease,
    background 0.25s ease;
}

.bar.ov .fill {
  background: var(--ms-over);
}

.bar .mvi {
  position: absolute;
  top: -6px;
  bottom: -6px;
  width: 2px;
  background: var(--ms-ink);
}

.bar .knob {
  position: absolute;
  top: 50%;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: var(--ms-moss);
  border: 3px solid var(--ms-plate);
  transform: translate(-50%, -50%);
  transition:
    left var(--ms-fast) ease,
    background 0.25s ease;
}

.bar.ov .knob {
  background: var(--ms-over);
}

.bar-at-47 {
  width: 47%;
}

.bar-at-74 {
  left: 74%;
}

.knob-at-47 {
  left: 47%;
}

.legend {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  margin-top: 12px;
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-label);
  letter-spacing: 0.05em;
  color: var(--ms-ink);
}

.legend b {
  font-weight: 500;
  color: var(--ms-moss);
}

.legend.ov b {
  color: var(--ms-over);
}

.dial-grid {
  display: grid;
  gap: var(--ms-sec-gap);
  margin-top: var(--ms-stack);
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.08fr);
  align-items: center;
}

.play {
  background: var(--ms-plate);
  border: 1px solid var(--ms-rule);
  border-radius: var(--ms-r-plate);
  padding: 26px 26px 30px;
  box-shadow: var(--ms-cast);
}

.play .hint {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-label);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ms-moss);
}

.play .hint svg {
  width: 15px;
  height: 15px;
  flex: none;
  animation: nudge 1.9s ease-in-out infinite;
}

@keyframes nudge {
  0%,
  100% {
    transform: translateX(-3px);
  }

  50% {
    transform: translateX(3px);
  }
}

.play h3 {
  margin-top: 14px;
  font-size: clamp(22px, 2.4vw, 30px);
}

.play .say {
  margin-top: 10px;
  color: var(--ms-ink);
  font-size: var(--ms-t-body);
  max-width: 38ch;
}

/* ⚠️ THE PADDING IS THE RANGE THUMB'S. A `::-webkit-slider-thumb` is 28px wide and centred on the
   value, so at 0% and 100% it hangs 14px outside the track — measured as a horizontal overflow of
   `.slider` at 390. Padding the container is the fix that keeps the track full-width and does not
   reach for a clip. */
.slider {
  margin-top: 26px;
  padding-inline: 14px;
}

.slider .cap,
.slider input[type='range'] {
  margin-inline: -14px;
  width: calc(100% + 28px);
}

.slider .cap {
  display: flex;
  justify-content: space-between;
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-label);
  letter-spacing: 0.06em;
  color: var(--ms-ink);
  margin-bottom: 9px;
}

input[type='range'] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  background: transparent;
  cursor: grab;
}

input[type='range']:active {
  cursor: grabbing;
}

input[type='range']::-webkit-slider-runnable-track {
  height: 8px;
  border-radius: var(--ms-r-pill);
  background: var(--ms-sunk);
}

input[type='range']::-moz-range-track {
  height: 8px;
  border-radius: var(--ms-r-pill);
  background: var(--ms-sunk);
}

input[type='range']::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--ms-ink);
  border: 4px solid var(--ms-plate);
  box-shadow: var(--ms-cast);
  margin-top: -10px;
}

input[type='range']::-moz-range-thumb {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--ms-ink);
  border: 4px solid var(--ms-plate);
  box-shadow: var(--ms-cast);
}

.grades {
  display: flex;
  gap: 6px;
  margin-top: 24px;
  flex-wrap: wrap;
}

.gd {
  flex: 1;
  min-width: 64px;
  text-align: center;
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-micro);
  letter-spacing: 0.09em;
  padding: 9px 4px;
  border-radius: var(--ms-r-chip);
  border: 1px solid var(--ms-hair);
  color: var(--ms-ink);
  transition: all 0.25s ease;
  background: var(--ms-paper);
}

.gd.on {
  border-color: currentColor;
  color: var(--ms-moss);
  background: var(--ms-moss-wash);
  font-weight: 500;
}

.gd.on.bad {
  color: var(--ms-over);
  background: var(--ms-over-wash);
}

.says {
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--ms-hair);
  font-size: var(--ms-t-sm);
  color: var(--ms-ink);
  min-height: 52px;
}

.says b {
  color: var(--ms-ink);
  font-weight: 600;
}

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

/* ── §12 the timeline ═════════════════════════════════════════════════════
   It draws DOWN the page, with the scroll rather than against it. Nothing here
   is sticky — see the file header.                                          */

.wire {
  position: relative;
  margin-top: var(--ms-stack);
}

.wire-line {
  position: absolute;
  left: 6px;
  top: 8px;
  bottom: 8px;
  width: 2px;
  background: var(--ms-rule-night);
  overflow: hidden;
}

.wire-line i {
  display: block;
  width: 100%;
  height: 100%;
  background: linear-gradient(
    180deg,
    var(--ms-neon) 0%,
    var(--ms-neon) 52%,
    var(--ms-over-night) 100%
  );
  clip-path: inset(0 0 100% 0);
  transition: clip-path 0.12s linear;
}

.beats4 {
  display: grid;
  gap: 0;
}

.b4 {
  position: relative;
  padding: 0 0 clamp(34px, 4.4vw, 60px) clamp(38px, 4vw, 62px);
  display: grid;
  grid-template-columns: minmax(150px, 230px) minmax(0, 1fr);
  column-gap: clamp(20px, 3.4vw, 56px);
  row-gap: 4px;
  grid-template-areas: 't w' 'v w';
  align-items: start;
}

/*
 * ⚠️ THE DIMMED STATE IS `.js`-SCOPED, LIKE `.rv` ABOVE. `opacity: .3` sat on the bare `.b4` until
 * 2026-08-25, so with JavaScript blocked or merely slow to arrive, three timeline beats — "Your
 * phone buzzes", "The first dealer message lands", "Marked pending" — stayed at 30% FOREVER.
 * Measured against their bands: 2.37 / 2.45 / 2.65 / 2.72 / 2.74 / 2.75 / 2.78 / 2.81:1, under both
 * the 4.5:1 body floor and the 3:1 large-text floor, with the `10:11` stamp effectively invisible.
 *
 * `styles.test.js` states this invariant ("every piece of CONTENT is visible by default and only
 * ANIMATED under `.js`") but its guard only inspects selectors containing `.rv`, and the other
 * guard that knows `.b4` by name only checks the reduced-motion escape — so the defect fell exactly
 * between two tests that each knew half of it. The guard is widened alongside this change.
 */
.js .b4 {
  opacity: 0.3;
  transform: translateY(12px);
  transition:
    opacity 0.55s ease,
    transform 0.55s var(--ms-ease);
}

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

.b4.on {
  opacity: 1;
  transform: none;
}

.b4 .dot {
  position: absolute;
  left: 0;
  top: 3px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--ms-night);
  border: 2px solid var(--ms-rule-night);
  transition: all 0.45s ease;
}

.b4.on .dot {
  border-color: var(--ms-neon);
  background: var(--ms-neon);
  box-shadow: 0 0 0 5px var(--ms-neon-halo);
}

.b4.hot.on .dot {
  border-color: var(--ms-over-night);
  background: var(--ms-over-night);
}

.b4 .t {
  grid-area: t;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  color: var(--ms-neon);
  letter-spacing: 0.08em;
}

.b4.hot .t {
  color: var(--ms-over-night);
}

.b4 .v {
  grid-area: v;
  font-size: var(--ms-t-figure);
  margin-top: 4px;
  color: var(--ms-pale);
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 600;
  letter-spacing: -0.045em;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.b4 .v i {
  font-style: normal;
  font-size: 0.38em;
  color: var(--ms-pale);
  margin-left: 5px;
  letter-spacing: 0;
}

.b4 .w {
  grid-area: w;
  align-self: center;
  font-size: 17.5px;
  color: var(--ms-pale);
  max-width: 46ch;
}

@media (max-width: 760px) {
  .b4 {
    grid-template-columns: 1fr;
    grid-template-areas: 't' 'v' 'w';
    padding-left: 34px;
  }

  .b4 .w {
    margin-top: 10px;
    align-self: start;
    font-size: var(--ms-t-sm);
  }

  .b4 .v {
    font-size: clamp(34px, 10vw, 46px);
  }
}

/* ── §13 the zone builder ═════════════════════════════════════════════════ */

.zone-grid {
  display: grid;
  gap: var(--ms-sec-gap);
  margin-top: var(--ms-stack);
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
  align-items: center;
}

.map {
  background: var(--ms-night);
  border-radius: var(--ms-r-plate);
  padding: 8px;
  border: 1px solid var(--ms-rule-night);
  box-shadow: var(--ms-cast);
}

/* ⚠️ `color` IS THE WHOLE MECHANISM. Everything the reader is meant to see in the map is drawn in
   `currentColor`, and this is where that resolves to the accent — on a light section the page ink
   is near-black, which on the map's near-black ground is an invisible drawing. */
.map {
  color: var(--ms-neon);
}

.map svg {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 14px;
}

.map-grid {
  fill: none;
  stroke: var(--ms-rule-night);
  stroke-width: 1;
}

.map .ring {
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-dasharray: 5 5;
  transition: r 0.25s var(--ms-ease);
}

.map-pin {
  fill: currentColor;
}

.map-halo {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  opacity: 0.5;
}

/* A town. `.on` is written by `site.js` as the radius crosses it — a CLASS rather than a `fill`
   attribute, so the colour still lives in this file and the transition has something to animate. */
.map .dot {
  fill: var(--ms-rule-night);
  transition:
    fill var(--ms-mid) ease,
    r var(--ms-mid) ease;
}

.map .dot.on {
  fill: currentColor;
}

.h3-gap {
  margin-top: 16px;
}

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

/* ── §14 the metro tape ═══════════════════════════════════════════════════ */

.chips {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 26px;
}

.chip {
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-label);
  letter-spacing: 0.07em;
  padding: 9px 15px;
  border-radius: var(--ms-r-pill);
  border: 1px solid var(--ms-rule-night);
  color: var(--ms-pale);
  background: transparent;
  cursor: pointer;
  transition: all 0.2s ease;
}

.chip:hover {
  border-color: var(--ms-pale);
}

.chip.on {
  background: var(--ms-neon);
  color: var(--ms-on-neon);
  border-color: var(--ms-neon);
  font-weight: 500;
}

/*
 * ⚠️ THE SCROLL HAS TO BE VISIBLE, BECAUSE THE PRODUCT IS OFF-SCREEN WITHOUT IT (2026-08-25).
 * `table.tape` is `min-width: 760px` inside this scroller, so at 390 the visible columns are
 * VEHICLE / ASK / MVI and Δ, GRADE, MILES, LOCATION and AGE are all past the right edge — the
 * GRADE being the whole product. It shipped with no fade, no shadow and no affordance of any kind,
 * while the ticker directly above it does carry a mask fade, so the one element that was scrollable
 * looked fixed and the one that was decorative looked scrollable. REBUILD-BRIEF §3: "the payload is
 * never quieter than chrome."
 *
 * A right-edge mask that retracts as you scroll: `background-attachment: local` pins the second
 * layer to the CONTENT, so the fade is painted only while there is content still to the right and
 * disappears at the end of the scroll. No JavaScript, and it degrades to a plain scroller wherever
 * `mask-image` is unsupported.
 */
.tapewrap {
  margin-top: 22px;
  overflow-x: auto;
  border: 1px solid var(--ms-rule-night);
  border-radius: var(--ms-r-card);
  background:
    linear-gradient(to right, var(--ms-film-1), var(--ms-film-1)) 0 0 / 100% 100% no-repeat,
    linear-gradient(to left, var(--ms-night-2), transparent) right center / 34px 100% no-repeat
      local;
}

/* The fade is a hint, not a divider: on a pointer device where the whole table already fits, it
   would be noise. Only spend it where the overflow is real. */
@media (min-width: 900px) {
  .tapewrap {
    background: var(--ms-film-1);
  }
}

table.tape {
  border-collapse: collapse;
  width: 100%;
  min-width: 760px;
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-mono);
  font-variant-numeric: tabular-nums;
}

table.tape th {
  text-align: left;
  padding: 12px 16px;
  font-weight: 500;
  font-size: var(--ms-t-micro);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ms-pale);
  border-bottom: 1px solid var(--ms-rule-night);
}

table.tape td {
  padding: 13px 16px;
  border-bottom: 1px solid var(--ms-film-2);
  color: var(--ms-pale);
}

table.tape tr:last-child td {
  border-bottom: 0;
}

/* ⚠️ `.ra`, NOT `.r`. In the mock the table's right-align class collided with
   the console row's `.r` and collapsed the tape header. */
table.tape td.ra,
table.tape th.ra {
  text-align: right;
}

table.tape .nm {
  font-family: Inter, sans-serif;
  font-size: 13.5px;
}

/*
 * ⚠️ THE DELTA IS THE PRODUCT'S OWN INK, NOT THE BRAND ACCENT (corrected 2026-08-25). Both of
 * these read `var(--ms-neon)` until now, which forks the one thing `marketing.tokens.css`'s header
 * says may never fork: "Every SEMANTIC ink still comes from `dist/tokens.css` … the under/over-
 * market delta … if those forked, this site would be advertising a product that does not match the
 * one people sign up for." `--ms-under-night` IS that ink — the pipeline's own Carbon `deltaUnder`,
 * restated here only because CSS cannot read another selector's declaration, and pinned to
 * `TOKENS_DARK.deltaUnder` by `styles.test.js` so it cannot drift. It was declared, test-guarded
 * and spent in exactly one gradient stop while the accent did its job.
 *
 * DESIGN-v6 §1 already accepts that green no longer means "money in your favour" on its own; the
 * mitigation it names is "weight and placement, never hue", and that only works while the accent
 * and `deltaUnder` are different VALUES. Contrast is unaffected: 11.81 / 10.90 / 9.92:1 on the
 * three night grounds, against the accent's 16.11 / 14.87 / 13.54.
 */
table.tape .dn {
  color: var(--ms-under-night);
}

table.tape .up {
  color: var(--ms-over-night);
}

table.tape tbody tr {
  animation: fadein 0.45s ease both;
}

@keyframes fadein {
  from {
    opacity: 0;
    transform: translateY(6px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

.gp {
  font-size: var(--ms-t-micro);
  letter-spacing: 0.11em;
  padding: 3px 8px;
  border-radius: var(--ms-r-pill);
  border: 1px solid currentColor;
  color: var(--ms-pale);
}

.gp.great {
  /* Same correction as `table.tape .dn` above — the grade's ink is the product's, not the brand's. */
  color: var(--ms-under-night);
}

.gp.risk,
.gp.over {
  color: var(--ms-over-night);
}

/* ── §15 the rate card ════════════════════════════════════════════════════ */

.toggle {
  display: inline-flex;
  background: var(--ms-sunk);
  border-radius: var(--ms-r-pill);
  padding: 4px;
  margin-top: 22px;
}

.toggle button {
  border: 0;
  background: transparent;
  cursor: pointer;
  border-radius: var(--ms-r-pill);
  padding: 9px 18px;
  font:
    500 13.5px Inter,
    sans-serif;
  color: var(--ms-ink);
  transition: all 0.2s ease;
}

.toggle button.on {
  background: var(--ms-ink);
  color: var(--ms-paper);
}

/* ⚠️ WITHOUT JAVASCRIPT THE TOGGLE DOES NOTHING, so it does not ship. The page
   renders one period's prices and the other's total is printed in words. */
.no-js .toggle {
  display: none;
}

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

.plans.full {
  margin-top: 0;
}

.plan {
  background: var(--ms-plate);
  border: 1px solid var(--ms-rule);
  border-radius: var(--ms-r-plate);
  padding: 26px 24px;
  display: flex;
  flex-direction: column;
  transition:
    transform 0.22s ease,
    box-shadow 0.22s ease;
}

.plan:hover {
  transform: translateY(-4px);
  box-shadow: var(--ms-cast);
}

.plan.best {
  border: 2px solid var(--ms-ink);
  box-shadow: var(--ms-cast);
}

.plan .pt {
  display: flex;
  align-items: center;
  gap: 10px;
}

.plan h3 {
  font-size: 20px;
}

.plan .flag {
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-micro);
  letter-spacing: 0.11em;
  text-transform: uppercase;
  background: var(--ms-ink);
  color: var(--ms-paper);
  padding: 4px 9px;
  border-radius: var(--ms-r-pill);
}

.plan .pr {
  margin-top: 18px;
  display: flex;
  align-items: baseline;
  gap: 6px;
}

.plan .pr .v {
  font-size: 40px;
}

.plan .pr .per {
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-label);
  color: var(--ms-ink);
  letter-spacing: 0.07em;
}

/* ⚠️ THE PERIOD SWAP IS PURE CSS, and that is an FR-30a requirement rather than a preference.
   Both figures ship in the HTML as two elements; `site.js` moves ONE attribute on the region and
   this pair decides which is painted. A price written by JavaScript would be a second pricing
   source invisible to the build-time check that pins each figure to its Stripe Price ID — even
   when it is copied out of a data attribute one line earlier. It also means the card is correct
   before the script runs, and stays correct if it never does. */
[data-billing='monthly'] .yr,
[data-billing='annual'] .mo {
  display: none;
}

.plan .save {
  margin-top: 5px;
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-label);
  color: var(--ms-moss);
  letter-spacing: 0.05em;
  min-height: 16px;
}

.plan ul {
  list-style: none;
  margin: 20px 0 0;
  padding: 0;
  flex: 1;
}

.plan li {
  padding: 8px 0;
  font-size: var(--ms-t-xs);
  color: var(--ms-ink);
  display: flex;
  gap: 10px;
}

.plan li::before {
  content: '';
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--ms-moss);
  flex: none;
  margin-top: 9px;
}

.plan .go {
  margin-top: 22px;
}

.plan .go .btn {
  width: 100%;
}

.plan.full ul {
  border-top: 1px solid var(--ms-hair);
  margin-top: 18px;
  padding-top: 6px;
}

.plan.full li {
  padding: 9px 0;
}

.plan .tiny {
  margin-top: 10px;
  text-align: center;
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-micro);
  letter-spacing: 0.06em;
  color: var(--ms-ink);
}

.cmp-cta {
  margin-top: 26px;
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
}

.cmp-cta .note {
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-label);
  letter-spacing: 0.05em;
  color: var(--ms-ink);
}

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

/* ── §16 the feature matrix ═══════════════════════════════════════════════ */

.mxwrap {
  margin-top: var(--ms-stack);
}

.mx-scroll {
  margin-top: 20px;
  overflow-x: auto;
  border: 1px solid var(--ms-rule);
  border-radius: var(--ms-r-card);
  background: var(--ms-plate);
}

table.mx {
  border-collapse: collapse;
  width: 100%;
  min-width: 720px;
  font-size: var(--ms-t-xs);
}

table.mx th,
table.mx td {
  padding: 14px 18px;
  text-align: left;
  border-bottom: 1px solid var(--ms-hair);
}

table.mx tbody tr:last-child td {
  border-bottom: 0;
}

table.mx thead th {
  background: var(--ms-sunk);
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-micro);
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ms-ink);
  font-weight: 500;
  vertical-align: bottom;
}

table.mx thead th .pn {
  display: block;
  font-family: 'Space Grotesk', sans-serif;
  font-size: 16px;
  letter-spacing: -0.02em;
  text-transform: none;
  color: var(--ms-ink);
  font-weight: 600;
  margin-bottom: 3px;
}

table.mx thead th .pp {
  display: block;
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-label);
  color: var(--ms-ink);
  letter-spacing: 0.04em;
}

table.mx td:not(:first-child),
table.mx th:not(:first-child) {
  text-align: center;
}

table.mx .hi {
  background: var(--ms-moss-wash);
}

table.mx .y {
  color: var(--ms-moss);
  font-weight: 600;
}

table.mx .n {
  color: var(--ms-ink);
}

table.mx .val {
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-mono);
  font-variant-numeric: tabular-nums;
}

.mx-foot {
  margin-top: 12px;
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-label);
  letter-spacing: 0.05em;
  color: var(--ms-ink);
  line-height: 1.9;
}

/* The three trial steps under the matrix. */
.trial {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(18px, 2.4vw, 34px);
  margin-top: clamp(28px, 3.4vw, 44px);
}

.tstep {
  border-top: 2px solid var(--ms-ink);
  padding-top: 20px;
}

.tstep .k {
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-label);
  letter-spacing: 0.1em;
  color: var(--ms-ink);
}

.tstep h3 {
  margin-top: 10px;
  font-size: 20px;
}

.tstep p {
  margin-top: 8px;
  color: var(--ms-ink);
  font-size: var(--ms-t-sm);
}

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

/* ── §17 the FAQ ══════════════════════════════════════════════════════════
   ⚠️ EVERY SELECTOR HERE IS SCOPED TO `.faq`. In the mock the chevron was a
   bare `summary::after`, which drew a second chevron on the compare button in
   a different section entirely.                                             */

.faq {
  margin-top: clamp(28px, 3vw, 42px);
  max-width: 80ch;
}

.faq details {
  border-top: 1px solid var(--ms-rule);
}

.faq details:last-of-type {
  border-bottom: 1px solid var(--ms-rule);
}

.faq summary {
  list-style: none;
  cursor: pointer;
  padding: 20px 40px 20px 0;
  position: relative;
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 600;
  font-size: 17.5px;
  letter-spacing: -0.015em;
}

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

.faq summary::marker {
  content: '';
}

.faq summary::after {
  content: '';
  position: absolute;
  right: 6px;
  top: 50%;
  width: 11px;
  height: 11px;
  border-right: 2px solid var(--ms-ink);
  border-bottom: 2px solid var(--ms-ink);
  transform: translateY(-70%) rotate(45deg);
  transition: transform 0.25s ease;
}

.faq details[open] summary::after {
  transform: translateY(-30%) rotate(225deg);
}

.faq details p {
  padding: 0 0 22px;
  color: var(--ms-ink);
  font-size: var(--ms-t-sm);
  max-width: 70ch;
}

.faq summary:hover {
  color: var(--ms-moss);
}

/* ── §18 the interior page head ═══════════════════════════════════════════ */

.phead {
  border-bottom: 1px solid var(--ms-rule);
  background: var(--ms-plate);
}

.phead .wrap {
  padding-block: clamp(34px, 4.6vw, 60px);
}

.phead h1 {
  font-size: var(--ms-t-h1);
  letter-spacing: -0.038em;
  margin-top: 12px;
}

.phead .line {
  margin-top: 15px;
  font-size: var(--ms-t-line);
  color: var(--ms-ink);
  max-width: 56ch;
}

.phead .eyebrow-gap {
  margin-top: 20px;
}

.backlink {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-label);
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ms-ink);
  padding: 9px 15px 9px 12px;
  border: 1px solid var(--ms-rule);
  border-radius: var(--ms-r-pill);
  background: var(--ms-plate);
  transition:
    border-color var(--ms-fast) ease,
    transform var(--ms-fast) ease;
}

.backlink:hover {
  border-color: var(--ms-ink);
  transform: translateX(-3px);
}

.backlink svg {
  width: 13px;
  height: 13px;
  flex: none;
}

/* ── §19 running prose — /about and the legal stubs ═══════════════════════ */

.prose {
  max-width: 66ch;
  margin-top: clamp(20px, 2.4vw, 32px);
}

.prose p {
  font-size: 17.5px;
  line-height: 1.68;
  color: var(--ms-ink);
}

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

.prose .lead {
  font-size: clamp(19px, 1.8vw, 23px);
  line-height: 1.55;
  letter-spacing: -0.012em;
}

.ab .sec-top {
  max-width: 60ch;
}

.ab .sec-top h2 {
  font-size: clamp(27px, 3.4vw, 42px);
}

.pillars {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(18px, 2.6vw, 34px);
  margin-top: clamp(30px, 3.6vw, 48px);
}

.pillar {
  border-top: 2px solid var(--ms-ink);
  padding-top: 20px;
}

.pillar h3 {
  font-size: 19px;
}

.pillar p {
  margin-top: 9px;
  color: var(--ms-ink);
  font-size: var(--ms-t-sm);
  line-height: 1.6;
}

.stances {
  display: grid;
  gap: 0;
  margin-top: clamp(28px, 3.4vw, 44px);
}

.stance {
  display: grid;
  grid-template-columns: minmax(0, 240px) minmax(0, 1fr);
  gap: clamp(18px, 3vw, 44px);
  padding-block: clamp(20px, 2.4vw, 30px);
  border-top: 1px solid var(--ms-rule-night);
}

.stance:last-child {
  border-bottom: 1px solid var(--ms-rule-night);
}

.stance h3 {
  font-size: clamp(19px, 2.2vw, 25px);
  color: var(--ms-pale);
}

.stance p {
  color: var(--ms-pale);
  font-size: var(--ms-t-body);
  line-height: 1.62;
  opacity: 0.9;
}

.cta-row {
  margin-top: clamp(30px, 4vw, 52px);
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  align-items: center;
}

/* The legal stubs' printed-contract split. */
.legal-sections {
  margin-top: clamp(20px, 2.4vw, 32px);
  display: grid;
  gap: 22px;
}

.legal-section h2 {
  font-size: 20px;
}

.legal-section p {
  margin-top: 8px;
  color: var(--ms-ink);
  font-size: var(--ms-t-sm);
  line-height: 1.6;
  max-width: 70ch;
}

.legal-foot {
  margin-top: 26px;
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-label);
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ms-ink);
}

/* The 404 slip. */
.slip {
  padding-block: clamp(70px, 10vw, 150px);
  text-align: center;
}

.slip-code {
  display: block;
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 600;
  font-size: clamp(72px, 14vw, 180px);
  line-height: 0.9;
  letter-spacing: -0.05em;
  color: var(--ms-rule);
}

.slip h1 {
  margin-top: 18px;
  font-size: var(--ms-t-h2-sm);
}

.slip p {
  margin-top: 12px;
  color: var(--ms-ink);
  font-size: var(--ms-t-line);
}

.slip .cta-row {
  justify-content: center;
}

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

@media (max-width: 760px) {
  .stance {
    grid-template-columns: 1fr;
    gap: 8px;
  }
}

/* ── §20 contact ══════════════════════════════════════════════════════════ */

.ct-grid {
  display: grid;
  gap: clamp(28px, 3.4vw, 52px);
  margin-top: clamp(30px, 3.6vw, 48px);
  grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr);
  align-items: start;
}

.ways {
  display: grid;
  gap: 2px;
}

.way {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  padding: 18px 0;
  border-top: 1px solid var(--ms-rule);
}

.way:last-child {
  border-bottom: 1px solid var(--ms-rule);
}

.way .ic {
  width: 34px;
  height: 34px;
  flex: none;
  border-radius: 10px;
  background: var(--ms-sunk);
  display: grid;
  place-items: center;
  color: var(--ms-moss);
}

.way .ic svg {
  width: 17px;
  height: 17px;
}

.way h2 {
  font-size: var(--ms-t-sm);
}

.way p {
  margin-top: 3px;
  font-size: var(--ms-t-xs);
  color: var(--ms-ink);
}

.way a {
  color: var(--ms-moss);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.form {
  background: var(--ms-plate);
  border: 1px solid var(--ms-rule);
  border-radius: var(--ms-r-plate);
  padding: 28px 28px 30px;
  box-shadow: var(--ms-cast);
  position: relative;
}

/* ⚠️ `.form-row`, NOT `.frow`. The step row in §10 owns `.srow`; in the mock
   both were `.frow` and the step row's `padding-block` put a phantom 74px gap
   into the contact form. */
.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}

.field {
  display: block;
  margin-top: 16px;
}

.field:first-child,
.form-row .field {
  margin-top: 0;
}

/* ⚠️ `.field-label`, NOT `.field > span`. In the mock this was `.f > span`,
   which also matched the ERROR span — so every form error was visible on first
   paint, styled as a field label. */
.field-label {
  display: block;
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-micro);
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ms-ink);
  margin-bottom: 7px;
}

.field input,
.field textarea {
  width: 100%;
  font:
    400 var(--ms-t-sm) Inter,
    sans-serif;
  color: var(--ms-ink);
  background: var(--ms-paper);
  border: 1.5px solid var(--ms-rule);
  border-radius: 11px;
  padding: 12px 14px;
  transition:
    border-color var(--ms-fast) ease,
    background var(--ms-fast) ease;
}

.field textarea {
  resize: vertical;
  min-height: 118px;
  line-height: 1.55;
}

.field input:focus,
.field textarea:focus {
  border-color: var(--ms-moss);
  background: var(--ms-plate);
  outline: none;
}

.field.bad input,
.field.bad textarea {
  border-color: var(--ms-over);
}

.field-err {
  display: none;
  margin-top: 6px;
  font-size: 13px;
  color: var(--ms-over);
}

.field.bad .field-err {
  display: block;
}

/* A listbox we OWN, because a native <select> hands its options popup to the
   browser to place and ANY transformed ancestor moves it — and the scroll-reveal
   class in §5 animates `transform`, so this form is that ancestor. Absolutely
   positioned inside the field, keyboard-driven, value posted through a hidden
   input. Do not go back to <select>. */
.sel {
  position: relative;
}

.sel-btn {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 12px;
  cursor: pointer;
  font:
    400 var(--ms-t-sm) Inter,
    sans-serif;
  color: var(--ms-ink);
  text-align: left;
  background: var(--ms-paper);
  border: 1.5px solid var(--ms-rule);
  border-radius: 11px;
  padding: 12px 14px;
  transition:
    border-color var(--ms-fast) ease,
    background var(--ms-fast) ease;
}

.sel-btn:hover {
  border-color: var(--ms-ink);
}

.sel.open .sel-btn {
  border-color: var(--ms-moss);
  background: var(--ms-plate);
}

.sel-val {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sel-cv {
  flex: none;
  width: 10px;
  height: 10px;
  border-right: 2px solid var(--ms-ink);
  border-bottom: 2px solid var(--ms-ink);
  transform: translateY(-3px) rotate(45deg);
  transition: transform 0.25s ease;
}

.sel.open .sel-cv {
  transform: translateY(1px) rotate(225deg);
}

.sel-list {
  position: absolute;
  z-index: 40;
  top: calc(100% + 7px);
  left: 0;
  right: 0;
  margin: 0;
  padding: 5px;
  list-style: none;
  background: var(--ms-plate);
  border: 1.5px solid var(--ms-rule);
  border-radius: var(--ms-r-control);
  box-shadow: var(--ms-cast);
  max-height: 264px;
  overflow-y: auto;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition:
    opacity 0.16s ease,
    transform var(--ms-fast) var(--ms-ease),
    visibility var(--ms-fast);
}

.sel.open .sel-list {
  opacity: 1;
  visibility: visible;
  transform: none;
}

.sel-list li {
  padding: 11px 13px;
  border-radius: 8px;
  font-size: 15px;
  color: var(--ms-ink);
  cursor: pointer;
}

.sel-list li:hover,
.sel-list li.cursor {
  background: var(--ms-sunk);
}

.sel-list li[aria-selected='true'] {
  color: var(--ms-moss);
  font-weight: 500;
}

/* ⚠️ WITH NO SCRIPT THE LISTBOX IS A REAL <select>. The button cannot open
   anything without JavaScript, so the no-JS document ships the native control
   and hides ours — the popup-placement bug the owned listbox exists for needs a
   transformed ancestor, and `.rv` only transforms under `.js`. */
.no-js .sel {
  display: none;
}

.sel-native {
  display: none;
}

.no-js .sel-native {
  display: block;
  width: 100%;
  font:
    400 var(--ms-t-sm) Inter,
    sans-serif;
  color: var(--ms-ink);
  background: var(--ms-paper);
  border: 1.5px solid var(--ms-rule);
  border-radius: 11px;
  padding: 12px 14px;
}

/* ⚠️ THE STANDARD VISUALLY-HIDDEN RECIPE, NOT `left: -9999px`. The off-screen-left idiom is a
   horizontal OVERFLOW that nothing clips, and `verify:responsive` measures it as one — at 1440 the
   honeypot's own label and input reported "+9,351px past the viewport", which is a true reading of
   a real overflow. A 1px box with `clip-path: inset(50%)` is invisible to a human, unreachable by
   the tab order, and occupies no space to overflow with. Measured through the production host at
   390 / 768 / 1440. */
.honeypot {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.fsend {
  margin-top: 22px;
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}

.fsend .note {
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-label);
  letter-spacing: 0.06em;
  color: var(--ms-ink);
}

/* ⚠️ THE SUBMIT IS HIDDEN WITHOUT JAVASCRIPT, and the note beside it names the
   email address instead. `form-action 'none'` in this site's CSP means a real
   POST from the page is refused by the browser — a visible button that cannot
   work is worse than no button. */
.no-js .fsend button {
  display: none;
}

.nojs-note {
  display: none;
}

.no-js .nojs-note {
  display: block;
}

/* ⚠️ NO `display: none` HERE. The confirmation is driven by the `hidden` ATTRIBUTE, which
   `site.js` clears on a 201 — and a `display: none` in this file would win over `hidden` and hide
   the panel forever, with the script believing it had shown it. One mechanism, not two. */
.sent {
  text-align: center;
  padding: 38px 10px;
}

.sent .tick {
  width: 52px;
  height: 52px;
  margin: 0 auto;
  border-radius: 50%;
  background: var(--ms-moss);
  display: grid;
  place-items: center;
  color: var(--ms-on-moss);
}

.sent .tick svg {
  width: 24px;
  height: 24px;
}

.sent h3 {
  margin-top: 18px;
  font-size: 22px;
}

.sent p {
  margin-top: 9px;
  color: var(--ms-ink);
  font-size: var(--ms-t-sm);
}

/* The form and the confirmation swap through `hidden` too — `site.js` sets `form.hidden = true`
   and moves focus to the panel, so a keyboard or screen-reader user is not left on a submit button
   that has just vanished. */
[hidden] {
  display: none !important;
}

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

@media (max-width: 560px) {
  .form-row {
    grid-template-columns: 1fr;
  }
}

/* ── §21 the close band and the footer ════════════════════════════════════ */

.close {
  position: relative;
  overflow: hidden;
  text-align: center;
}

.close .wrap {
  position: relative;
  z-index: 2;
  padding-block: clamp(64px, 8vw, 116px);
}

.close h2 {
  font-size: clamp(32px, 4.8vw, 62px);
  max-width: 16ch;
  margin-inline: auto;
}

.close .acts {
  margin-top: 32px;
  display: flex;
  gap: 12px;
  justify-content: center;
  flex-wrap: wrap;
}

.site-footer {
  background: var(--ms-night-2);
  color: var(--ms-pale);
  padding-block: 42px 32px;
  border-top: 1px solid var(--ms-rule-night);
}

.f-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) repeat(3, minmax(0, 1fr));
  gap: clamp(24px, 3vw, 48px);
  padding-bottom: 30px;
  border-bottom: 1px solid var(--ms-rule-night);
}

.f-logo {
  width: 132px;
  --mk-accent: var(--ms-neon);
  --mk-face: var(--ms-night-2);
  --mk-ink: var(--ms-pale);
}

.f-logo svg {
  width: 100%;
  height: auto;
  display: block;
}

.f-brand p {
  margin-top: 14px;
  font-size: 14px;
  line-height: 1.6;
  color: var(--ms-pale);
  max-width: 34ch;
  opacity: 0.8;
}

.f-col {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
}

.f-col h2 {
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ms-neon);
  font-weight: 500;
  margin-bottom: 4px;
}

.f-col a {
  font-size: var(--ms-t-xs);
  color: var(--ms-pale);
  opacity: 0.85;
}

.f-col a:hover {
  opacity: 1;
  color: var(--ms-neon);
}

.f-legal {
  margin-top: 20px;
  font-family: 'JetBrains Mono', monospace;
  font-size: var(--ms-t-micro);
  line-height: 2.1;
  letter-spacing: 0.06em;
  color: var(--ms-pale);
  opacity: 0.75;
}

/* The configured domain, in its own element so `build.test.js` can assert a STAGING build prints
   the staging host — the v3 masthead shipped the production literal here and nothing could see it. */
.f-legal .host {
  letter-spacing: 0.06em;
}

.f-legal .s {
  letter-spacing: 0.1em;
  opacity: 1;
}

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

@media (max-width: 520px) {
  .f-grid {
    grid-template-columns: 1fr;
    gap: 26px;
  }
}

/* ── §22 phone ════════════════════════════════════════════════════════════ */

@media (max-width: 760px) {
  .figs {
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
  }

  .figs .dl {
    text-align: left;
  }

  .sec-top h2 {
    font-size: clamp(30px, 8vw, 42px);
  }

  .hero h1 {
    font-size: clamp(40px, 11vw, 58px);
  }
}

/* ── §23 reduced motion ═══════════════════════════════════════════════════
   ⚠️ IT COLLAPSES LAYOUT, NOT ONLY ANIMATION. A section sized for a scrub —
   the timeline's dimmed beats, the reveal's 22px offset, the step art's
   rotateX — leaves dead space and half-visible content when the motion is off,
   so every one of them is returned to its resting state rather than merely
   frozen. Freezing alone would ship a page whose content is 30% opaque.      */

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

  .js .rv,
  .js .fart > *,
  .js .hero h1 .w > i {
    opacity: 1;
    transform: none;
  }

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

  .wire-line i {
    clip-path: none;
  }

  .tick-row {
    animation: none;
  }
}
