/* ═══════════════════════════════════════════════════════════════════════════
   FEDERAL INDEX — DESIGN TOKENS · single source of truth
   ═══════════════════════════════════════════════════════════════════════════

   Extracted 2026-08-06 from the inline <style> block in landing/index.html,
   where this system was trapped and invisible to every other surface:
   coverage.html had ZERO styles, and the React app's five per-screen CSS files
   (1,211 lines) re-declared colours by hand.

   Consumed by:  landing/index.html · coverage.html · counties.html ·
                 terms.html · privacy.html · legal.css
   Next step:    tokens.json (DTCG) → `tz build` emits this file AND the
                 Tailwind v4 @theme block for src/index.css, so the React app
                 and the static site finally share one palette.

   PALETTE LOCK — American flag only.
   #bf0a30 Old Glory Red · #002868 Old Glory Blue · white.
   60/30/10: white dominant, navy secondary, red accent under 10% of pixels.
   Every ratio below was COMPUTED (WCAG 2.x relative luminance) on 2026-08-06,
   not estimated — an earlier draft of this file carried eyeballed numbers and
   all ten were wrong. Recompute before changing any value.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* ── Brand ──────────────────────────────────────────────────────────────
     The two flag colours and their pressed/deep variants. --navy-soft is the
     only lightened navy permitted for links on white (5.21:1). */
  --red:        #bf0a30;   /*  6.36:1 on white — AA body, AAA large          */
  --red-deep:   #8f0a24;   /*  9.39:1 on white — pressed/active states       */
  --navy:       #002868;   /* 13.97:1 on white — AAA everywhere              */
  --navy-2:     #0b3a86;   /* 10.69:1 on white — AAA everywhere              */
  --navy-soft:  #1d5fd0;   /*  5.83:1 on white — AA body                     */

  /* ── Ink (text) ─────────────────────────────────────────────────────────
     Never pure #000. --ink-3 is metadata-only: at 4.02:1 it clears AA for
     large text (≥18.66px bold / ≥24px) but NOT for body copy. Do not use it
     for anything a customer must read. */
  --ink:        #0d1526;   /* 18.22:1 on white — primary text                */
  --ink-2:      #3d4a63;   /*  8.91:1 on white — secondary/body              */
  /* --ink-3 WAS #6b788f, which computes to 4.46:1 on white — 0.04 under the AA
     body threshold. axe-core confirmed it live on 2026-08-06 as 17 real
     color-contrast violations on the production landing page (.proof .k,
     .step p, .role .cite, .f-bot, .mono).
     Darkened along the SAME hue (218.3°) and saturation (0.252) to the first
     value that clears 4.5:1 against the DARKEST surface it is used on
     (--paper-3), not merely against white. */
  --ink-3:      #626e83;   /* 5.15:1 white · 4.85:1 paper-2 · 4.55:1 paper-3  */

  /* ── Paper (surfaces) ───────────────────────────────────────────────────  */
  --paper:      #ffffff;
  --paper-2:    #f7f8fb;   /* alternating section bands                      */
  --paper-3:    #eef1f7;   /* wells, inset panels                            */

  /* ── Hairlines ──────────────────────────────────────────────────────────
     Tinted toward navy, never neutral #ccc — that grey is what makes a page
     read as a template. --line-2 is the only border strong enough to carry a
     meaningful edge; --line is decorative chrome. */
  --line:       #e2e7f0;
  --line-2:     #cdd6e6;

  /* ── Inverse (on navy) ──────────────────────────────────────────────────
     For the .problem and .routing bands. Rose is the only red that survives
     on navy — #bf0a30 on #002868 computes to 2.20:1 and fails outright. */
  --on-navy:        #ffffff;
  --on-navy-2:      rgba(255, 255, 255, .72);
  /* .56 is not arbitrary. Minimum white alpha for 4.5:1, computed per surface:
     navy #002868 needs .50 · role card #0d3370 needs .53 · footer ink #0d1526
     needs .46. .56 clears the worst case with headroom. The previous .52
     FAILED on the role cards (4.21:1), which axe-core caught live. Any tertiary
     text on a dark band must use this token, never a hand-typed alpha. */
  --on-navy-3:      rgba(255, 255, 255, .56);
  --on-navy-line:   rgba(255, 255, 255, .10);
  --on-navy-well:   rgba(255, 255, 255, .035);
  --rose:           #ff8ba3;   /* 6.30:1 on navy — accent for dark bands     */

  /* ── Type families ──────────────────────────────────────────────────────  */
  --sans:  'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --serif: 'Playfair Display', Georgia, 'Times New Roman', serif;
  --mono:  'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  /* ── Type scale — modular 1.25 ──────────────────────────────────────────
     Pick from the scale. An arbitrary size is a bug, not a decision. */
  --t-xs:   12.8px;
  --t-s:    16px;
  --t-m:    20px;
  --t-l:    25px;
  --t-xl:   31px;
  --t-2xl:  39px;
  --t-3xl:  49px;
  --t-4xl:  61px;

  /* Line-height and tracking travel WITH the size — big type needs tighter
     leading and negative tracking, body needs the opposite. */
  --lh-display: 1.08;
  --lh-heading: 1.25;
  --lh-body:    1.65;

  /* Display weight and tracking. Measured against the reference set rather than
     chosen: DOSS sets its H1 at weight 500 / -1.45px (-0.030em), Thalamus at
     400 / -0.5px (-0.012em). Both read modern and expensive. Display serif at
     700 — where this was — reads editorial and traditional by comparison, and
     that single value was most of the visual gap.
     500 rather than 400 because Playfair is a high-contrast Didone: at 400 its
     hairlines get thin enough to shimmer on a light background at large sizes.
     Tracking is -.018em globally and tighter on the hero only (see .hero h1) —
     a serif needs less negative tracking than a grotesque before the serifs
     start colliding. */
  --w-display: 500;
  --track-display: -.018em;
  --track-label:    .18em;

  /* ── Spacing — 4px base ─────────────────────────────────────────────────  */
  --sp-1:  4px;   --sp-2:  8px;   --sp-3: 12px;  --sp-4: 16px;
  --sp-5: 24px;   --sp-6: 32px;   --sp-7: 48px;  --sp-8: 64px;
  --sp-9: 96px;   --sp-10:132px;

  /* Section rhythm — whitespace is the luxury signal. */
  --section-y:        132px;
  --section-y-mobile:  72px;
  --gutter:            48px;
  --gutter-mobile:     24px;
  --measure:         1180px;   /* content max-width                          */
  --measure-text:      68ch;   /* prose max line length                      */

  /* ── Radius — 8/12/16, one per component class ──────────────────────────  */
  --r-s:  8px;    /* chips, inputs        */
  --r-m: 12px;    /* buttons, cards       */
  --r-l: 16px;    /* panels, large media  */
  --r-full: 999px;

  /* ── Elevation — layered, never a single blur ───────────────────────────  */
  --shadow-rest: 0 1px 2px rgba(13,21,38,.06), 0 8px 24px rgba(13,21,38,.07);
  --shadow-lift: 0 2px 4px rgba(13,21,38,.07), 0 16px 40px rgba(13,21,38,.11);
  --shadow-red:  0 1px 2px rgba(13,21,38,.08), 0 6px 16px rgba(191,10,48,.14);
  --shadow-red-lift: 0 2px 4px rgba(13,21,38,.09), 0 12px 26px rgba(191,10,48,.20);

  /* ── Focus ──────────────────────────────────────────────────────────────
     Designed, not the browser default. Two rings so it reads on both white
     and navy without needing a variant. */
  --focus-ring: 0 0 0 3px rgba(0,40,104,.18), 0 0 0 5px rgba(0,40,104,.32);

  /* ── Motion ─────────────────────────────────────────────────────────────
     Nothing moves linearly. Arrivals ease out, departures ease in.
     Durations map to weight: chips are quick, panels are slow. */
  --ease:      cubic-bezier(.22, 1, .36, 1);      /* ease-out-quint, arrivals */
  --ease-in:   cubic-bezier(.55, 0, 1, .45);      /* departures               */
  --ease-pop:  cubic-bezier(.34, 1.56, .64, 1);   /* small celebratory only   */

  --dur-press:  110ms;   /* active/down                    */
  --dur-hover:  180ms;   /* hover feedback                 */
  --dur-ui:     250ms;   /* state change                   */
  /* 320ms, down from 550ms. The reference sites all sit at 200-500ms
     (DOSS 0.3-0.5s ease-out-cubic, Thalamus 0.2-0.3s ease). Slow motion reads
     as heavy, not as premium — 550ms was the second-biggest gap after weight. */
  --dur-enter:  320ms;   /* element entrance               */
  --dur-scene:  800ms;   /* choreographed scene moment     */
  --stagger:     60ms;   /* between siblings (40–80 band)  */
}

/* ── Reduced motion ───────────────────────────────────────────────────────
   Collapse every duration to ~0 at the token layer, so any component built on
   these tokens inherits the preference without writing its own media query.
   Components that animate transform/opacity directly still need their own
   reset — this handles everything driven by --dur-*. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-press: 1ms; --dur-hover: 1ms; --dur-ui: 1ms;
    --dur-enter: 1ms; --dur-scene: 1ms; --stagger: 0ms;
  }
  html { scroll-behavior: auto; }
}
