/* ═══════════════════════════════════════════════════════════════
   D4D Site Platform — design tokens
   Source of truth: DESIGN.md (Session 0, 2026-08-14). Every value
   here is either measured from the reference set or a documented
   Session-0 decision. Components consume tokens only — no raw hex
   values in any component CSS.
   ═══════════════════════════════════════════════════════════════ */

/* ── Build-time accent re-hue hook — INKS, NOT PAPERS ─────────────
   The nine ink/paper neutrals below are the NEUTRAL-WARM DEFAULTS.
   At build time the generation pipeline re-hues the INK tokens toward
   the candidate's accent; the PAPER tokens ship VERBATIM. That split
   is what the reference sites actually did by hand — measured from
   Gertsen: its inks carry the accent hue (#170414 H 333.7 · #2A1F26
   H 340.3 vs accent #9C2088 H 335.8) while its papers stay warm bone
   (#FBF7F1 H 78.3 · #F3EBE1 H 73.7). The Session-3 ship-quality gate
   measured the cost of re-hueing both sides: --ink-950 under-tinted
   at ~3% chroma (below the 4–8% dark band) and papers drifted
   pink-lavender (≈#F6EEF4) — inks-not-papers is that fix.

   Pipeline contract (DESIGN.md "Neutral scale", amended Session 3;
   implemented in lib/generate/color.js):
     1. Convert the candidate accent to OKLCH; take its hue H.
     2. INK tokens (--ink-*): keep the token's LIGHTNESS exactly
        (lightness is locked so the contrast math in this file never
        changes per candidate), set hue = H, set chroma inside the
        4–8% dark band — OKLCH C 0.016–0.032, target C 0.024
        (chroma % per CSS Color 4 oklch(): 100% = C 0.4). The
        documented contrast floors outrank the band: chroma steps
        down if a measured pair would fail.
     3. PAPER tokens (--paper-*): emitted verbatim — warm bone is the
        cross-candidate constant. A whisper shift of at most C 0.006
        (≤1.5%) toward the accent is sanctioned; the v1 pipeline
        ships zero shift.
     4. Emit the re-hued hexes over the defaults below (a simple
        string substitution in this file — the token names are the API).
   --accent-h is registered here so the hue survives as an inspectable
   value in the built page and so any future runtime color-mix()
   upgrade has a typed hook to key off. The simple v1 pipeline only
   needs to rewrite the hex literals. */
@property --accent-h {
  syntax: '<number>';
  inherits: true;
  initial-value: 320;
}

:root {
  /* ── Accent system ─────────────────────────────────────────────
     --accent       candidate's color (default = Gertsen magenta, the
                    preview accent; pipeline replaces it per candidate)
     --accent-text  accessible variant for TEXT and small elements on
                    light grounds. When the chosen accent already
                    clears 4.5:1 on --paper-100 AND --paper-200 the
                    pipeline sets it equal to --accent; when it fails,
                    the pipeline preserves the hue and darkens
                    luminance until it clears (DESIGN.md: never reject
                    a candidate's color). Default #9C2088 clears at
                    6.61:1 on --paper-100 and 6.06:1 on --paper-200.
     Contrast note: white on default accent = 7.06:1 (buttons OK).
     Accent on --ink-950 is 2.61:1 — large decorative fields only,
     never text on dark. On dark grounds the text accent is --gold. */
  --accent-h: 320;               /* OKLCH-ish hue of --accent, set by pipeline */
  --accent: #9C2088;
  --accent-text: #9C2088;

  /* CTA gold — the one cross-candidate constant (G's --gold).
     Ratios: --gold-ink on --gold 7.28:1 · on --gold-hi 9.98:1 ·
     --gold on --ink-950 8.01:1. */
  --gold: #D9A21B;
  --gold-hi: #F0C24C;            /* hover/em-pop companion on dark grounds */
  --gold-ink: #2A1B00;           /* text on gold surfaces */

  /* ── Neutrals — nine steps, dark → light (re-hued at build) ──── */
  --ink-950: #171314;            /* darkest ground: hero, stats band, footer */
  --ink-900: #262023;            /* second dark ground, gradient ends, modals */
  --ink-800: #2B2428;            /* body text on light — 14.20:1 on --paper-100 */
  --ink-700: #403A3E;            /* strong prose, <b> upgrades — 10.40:1 on --paper-100 */
  --ink-500: #6A6166;            /* muted text — 5.60:1 on --paper-100, 5.13:1 on
                                    --paper-200; margin above the 4.5:1 AA floor is
                                    held in reserve for the accent-hue re-tinting */
  --paper-400: #DCD4C9;          /* borders and hairlines on light */
  --paper-300: #E6DFD3;          /* image placeholders, frame fills */
  --paper-200: #F3EDE2;          /* alternate light section background */
  --paper-100: #FBF7F1;          /* page background (G's --bone, verbatim) */

  /* ── On-dark text — tokenized alpha ramp, never literals ─────── */
  --on-dark-heading:   rgba(255,255,255,.87);
  --on-dark-body:      rgba(255,255,255,.84);
  --on-dark-secondary: rgba(255,255,255,.70);
  --on-dark-caption:   rgba(255,255,255,.55);
  --on-dark-legal:     rgba(255,255,255,.50);
  --on-dark-hairline:  rgba(255,255,255,.14);  /* borders/dividers on dark (G's stat rules) */
  --on-dark-ring:      rgba(255,255,255,.50);  /* ghost-button inset ring */
  --on-dark-ring-fill: rgba(255,255,255,.12);  /* ghost-button hover fill */

  /* Absolutes (so component CSS never carries a raw hex) */
  --white: #FFFFFF;
  --black: #000000;

  /* ── Type ──────────────────────────────────────────────────────
     Fraunces variable (SOFT/WONK axes) for display; Inter variable
     for body, kickers, buttons, forms. Self-hosted — see base.css
     @font-face; no font CDN at runtime. */
  --ff-d: 'Fraunces', Georgia, 'Times New Roman', serif;
  --ff-b: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;

  /* 1.35 ratio @ 17px base — governs any NEW size a component needs.
     17 → 23 → 31 → 42 → 56.5 → 76.2 → 103 → 139 (px at 1rem=16px) */
  --fs-0: 1.0625rem;             /*  17px — body */
  --fs-1: 1.4375rem;             /*  23px */
  --fs-2: 1.9375rem;             /*  31px */
  --fs-3: 2.625rem;              /*  42px */
  --fs-4: 3.5312rem;             /*  56.5px */
  --fs-5: 4.7625rem;             /*  76.2px */
  --fs-6: 6.4375rem;             /* 103px */
  --fs-7: 8.6875rem;             /* 139px */

  /* Adopted display clamps — Gertsen verbatim, documented off-scale
     ceilings (the 131px hero cap is a column-fit constraint, not a
     scale step). Ultrawide tiers step these up — see the min-width
     blocks at the bottom of this file. */
  --fs-hero: clamp(3.5rem, 11.5vw, 131px);
  --fs-h2:   clamp(2.05rem, 4.6vw, 3.55rem);
  --fs-h3:   clamp(1.42rem, 2.9vw, 2rem);
  --fs-stat: clamp(2.5rem, 6.2vw, 4.1rem);

  /* Line-heights (DESIGN.md system values; hero 0.9 is the deliberate
     override of G's .86 so two-line surnames with descenders never collide) */
  --lh-hero: 0.9;
  --lh-h2:   1.05;
  --lh-h3:   1.06;
  --lh-body: 1.65;

  /* Kicker — Gertsen verbatim (0.7812rem / .19em / Inter 600 upper-
     case, 34×2px currentColor leading dash, 11px gap). The dash and
     face are the section-header component's spec; the sizes live here. */
  --fs-kicker: 0.7812rem;
  --ls-kicker: .19em;
  --kicker-dash-w: 34px;
  --kicker-dash-h: 2px;
  --kicker-gap: 11px;

  /* ── Spacing — 4px base, tokenized scale ─────────────────────── */
  --sp-1:  4px;
  --sp-2:  8px;
  --sp-3:  12px;
  --sp-4:  16px;
  --sp-5:  24px;
  --sp-6:  32px;
  --sp-7:  44px;
  --sp-8:  56px;
  --sp-9:  66px;
  --sp-10: 76px;
  --sp-11: 132px;

  /* Section rhythm — G verbatim (the only fluid rhythm of the four).
     Sections vs interstitials is a real editorial distinction; keep it. */
  --rhythm-section:      clamp(72px, 10vw, 132px);
  --rhythm-interstitial: clamp(48px, 6vw, 78px);
  --rhythm-headgap:      clamp(38px, 5vw, 66px);

  /* ── Container ────────────────────────────────────────────────── */
  --wrap: 1220px;                /* 1400 ≥1700px, 1580 ≥2300px — see below */
  --pad-inline: 24px;            /* 18px ≤620px — see below */

  /* ── Header ───────────────────────────────────────────────────── */
  --head-h: 74px;                /* 66px ≤860px — shared by hero offset,
                                    scroll-margin and mobile-nav inset */

  /* ── Motion ───────────────────────────────────────────────────── */
  --ease: cubic-bezier(.22, 1, .36, 1);
  --dur: .85s;

  /* ── Z-scale ──────────────────────────────────────────────────────
     Documented ladder — components never invent z-index values.
     Fixes G's grain-at-z-90-over-header bug: page-level texture (70)
     now sits BELOW the header (80).
       texture (in-section) 1 · content-over-texture 2 · grain 70 ·
       mobile-nav 79 · header 80 · lightbox 120 · modal 130 · skip 200 */
  --z-texture:  1;
  --z-raise:    2;
  --z-grain:    70;
  --z-nav:      79;
  --z-header:   80;
  --z-lightbox: 120;
  --z-modal:    130;
  --z-skip:     200;

  /* ── Corner radius — theme: soft (default) ────────────────────────
     Two sanctioned voices, decided 2026-08-14. Chosen per site via
     data-radius on <html>; never mixed within one site. Components
     use ONLY these two tokens for any rounding. */
  --r-surface: 14px;             /* cards, frames, panels */
  --r-control: 999px;            /* buttons, pills, inputs */
}

/* Radius theme: sharp (S's Swiss hard-corner language).
   :root[…] outranks the bare :root block at any rule order. */
:root[data-radius="sharp"] {
  --r-surface: 0px;
  --r-control: 0px;
}

/* ═══════════════════════════════════════════════════════════════
   Breakpoints — the system set (G's, the only one where JS and CSS
   agree on the same numbers). Use these and no component-local
   variants:
     max-width: 1080px · 860px · 620px · 420px
     min-width: 1700px · 2300px (ultrawide tiers)
   JS that needs a breakpoint (nav collapse) keys off 860 to match.
   ═══════════════════════════════════════════════════════════════ */

@media (max-width: 860px) {
  :root { --head-h: 66px; }
}

@media (max-width: 620px) {
  :root { --pad-inline: 18px; }
}

/* Ultrawide: widen the CONTAINERS and scale the art, keep the text
   measure capped — long lines are the one thing that gets worse, not
   better, with more room (G's comment, adopted as policy). */
@media (min-width: 1700px) {
  :root {
    --wrap: 1400px;
    --fs-hero: clamp(3.5rem, 11.5vw, 150px);
    --fs-h2:   clamp(2.05rem, 4.6vw, 4.05rem);
  }
}

@media (min-width: 2300px) {
  :root { --wrap: 1580px; }
}
