/* DeepEnough — design tokens (DD-006 B1)
   Single source of truth for color, typography, spacing, radius, and motion.
   See /DESIGN.md for the rationale behind every value below.

   Layer order on the page: theme-boot.js (sets [data-theme] pre-paint) ->
   tokens.css (this file) -> components.css -> app.css (page layout only).
   :root = light theme. [data-theme="dark"] overrides. */

:root {
  /* ---- Color: surfaces & text ------------------------------------------ */
  --bg: #ffffff;
  --surface: #f5f5f7;
  --surface-2: #ebebee;
  --text: #1d1d1f;
  --text-muted: #6e6e73;
  --text-subtle: #757579;

  /* ---- Color: accent & semantic ----------------------------------------- */
  --accent: #0066cc;
  --accent-hover: #0050a8;
  --on-accent: #ffffff;   /* foreground for text/icons on a solid --accent fill */
  --focus: #0071e3;       /* frozen spec value — same hex in both themes */
  --success: #1a7f37;
  --error: #d70015;

  /* ---- Color: chrome dividers & frost ----------------------------------- */
  --hairline: rgba(0, 0, 0, .08);
  --hairline-strong: rgba(0, 0, 0, .18);
  /* Border for interactive controls (inputs/selects) — decorative chrome, same
     weight class as --hairline-strong, kept visible-but-quiet rather than
     vanishing like --hairline. The WCAG 1.4.11 "component identification" duty
     rests on the select chevron (currentColor-strength, >=4.5:1, see WCAG
     block) plus the accent focus/hover border, not on this token. */
  --control-border-soft: rgba(0, 0, 0, .18);
  --frost: rgba(245, 245, 247, .8);

  /* ---- Liquid Glass (DD-006 r4) -----------------------------------------
     A capability-layered material for FLOATING chrome only (nav, toast,
     specular CTAs) — never for text/data content surfaces, which stay
     near-opaque for WCAG. Fills are deliberately high-alpha so text on glass
     keeps AA against the worst-case blended background (see the GLASS block
     in the WCAG verification at the end of this file). The base layer
     (translucent fill + backdrop blur/saturate + specular edge) works in
     every modern browser; the SVG refraction on the ambient layer is a
     progressive enhancement (see .ambient in app.css). */
  --glass-bg: rgba(250, 250, 252, .74);   /* translucent fill: nav / tabs / toast */
  --glass-blur: 26px;
  --glass-saturate: 200%;
  --glass-edge: rgba(255, 255, 255, .95); /* specular top-light highlight line */
  --glass-edge-soft: rgba(255, 255, 255, .30);
  --glass-rim: rgba(0, 0, 0, .12);        /* outer rim for definition over light */
  --glass-specular: rgba(255, 255, 255, .42); /* CTA top-edge specular */
  /* Brighter glass fill for the ACTIVE segment in the tab capsule — a raised
     chip that catches more light than the recessed track around it (iOS 26
     segmented-control read). Composited over the track, not the page. */
  --glass-chip: rgba(255, 255, 255, .82);
  --glass-track: rgba(120, 130, 150, .10); /* recessed capsule track tint */
  /* Floating ambient shadow — the one place chrome may cast a shadow: a
     genuinely floating glass surface (the detached nav/tab capsules, toast,
     modal) reads as detached only with it. */
  --glass-shadow: 0 10px 34px rgba(17, 20, 24, .13), 0 2px 8px rgba(17, 20, 24, .07);
  /* A deeper lift for the top nav capsule specifically — it floats highest. */
  --glass-shadow-lift: 0 16px 44px rgba(17, 24, 39, .16), 0 3px 12px rgba(17, 24, 39, .09);

  /* Ambient wallpaper glow — soft, saturated-but-diffuse orbs the floating
     glass refracts. Peak alpha at each orb's center only (they fade to
     transparent), so the averaged wash reads as a lit daylight scene the glass
     capsules blur and bend — visible, but never neon. Blue-led to hold the
     single-accent identity; teal + indigo are decorative non-text partners. */
  --orb-1: rgba(0, 102, 204, .22);   /* accent blue — top-left, behind the nav */
  --orb-2: rgba(6, 170, 168, .17);   /* teal — top-right                        */
  --orb-3: rgba(108, 104, 232, .16); /* indigo — lower-left, under the card      */
  --orb-4: rgba(0, 132, 214, .13);   /* soft blue — lower-right, for balance     */

  /* ---- Typography -------------------------------------------------------- */
  --font-sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui,
    sans-serif;
  --fs-content: 17px;
  --lh-content: 1.47;
  --ls-content: -0.01em;
  --fs-chrome-xs: 12px;
  --fs-chrome-sm: 13px;
  --fs-chrome-md: 14px;
  /* Form-control text: 16px is the iOS Safari threshold below which focusing
     an input/select triggers an auto-zoom. Chrome elsewhere stays 12-14px;
     this single 16px exception applies only to editable fields (WCAG-adjacent
     usability, DD-006 UIUX R2). Same value both themes. */
  --fs-input: 16px;
  --fw-light: 300;
  --fw-regular: 400;
  --fw-semibold: 600;

  /* ---- Wordmark & display type (DD-006 r5) --------------------------------
     A single, deliberate exception to the "one family" rule (DESIGN §1/§3):
     the DeepEnough wordmark and section-level display headings get a
     self-hosted display face with real character, subset to only the glyphs
     it draws (D,E,e,g,h,n,o,p,u — ~1.4KB woff2, see web/static/fonts/). Every
     other chrome/UI/data element stays on --font-sans. Licensed SIL OFL 1.1
     (web/static/fonts/OFL.txt) — self-hosted, CSP script/style-src untouched. */
  --font-display: "DE Display", var(--font-sans);
  --fw-display: 600;      /* the instanced weight the subset was built at */
  --fs-wordmark: 21px;
  --ls-wordmark: -0.01em;
  /* Section/panel-title heading scale: heavier weight + tighter tracking than
     chrome gives headings real presence without leaving the 12-14px chrome
     register users scan at. Display face at a modest size, not marketing-page
     scale (DD-006 r5: "type scale richness", still tool-dense). */
  --fs-heading: 19px;
  --ls-heading: -0.015em;
  /* Small-caps chrome labels (panel group headers, table headers) get a touch
     of POSITIVE tracking — the counter-motion that makes large/small type feel
     tuned rather than uniformly scaled. */
  --ls-label: 0.04em;

  /* ---- Spacing (4/8/12/17/24/32/48 — 48 is the hard ceiling) ------------- */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 17px;
  --sp-5: 24px;
  --sp-6: 32px;
  --sp-7: 48px;

  /* ---- Radius (pill reserved for primary CTAs only) ---------------------- */
  --r-sm: 8px;
  --r-md: 11px;
  --r-lg: 18px;
  --r-pill: 9999px;
  /* Floating glass capsules (nav bar, tab segmented control) — a large rounded
     radius that reads as a detached capsule without claiming the CTA-only pill.
     The active tab chip nests at (--r-capsule - inset) for concentric corners
     per Apple's Liquid Glass geometry. A new deliberate radius role (DESIGN §5). */
  --r-capsule: 22px;

  /* ---- Motion ------------------------------------------------------------ */
  --dur-fast: 120ms;
  --ease-standard: cubic-bezier(.4, 0, .2, 1);
  --press-scale: .95;
  /* Springy release for presses/hovers (a small overshoot, then settle) —
     the Liquid Glass micro-interaction. Disabled under prefers-reduced-motion
     (see the reduce blocks in components.css / app.css). */
  --dur-press: 220ms;
  --ease-spring: cubic-bezier(.34, 1.56, .64, 1);

  /* ---- Legacy bridge ----------------------------------------------------
     app.css still references these pre-redesign names; they resolve through
     the tokens above so the page layer needs no rename. --card and
     --accent-soft take theme-specific literals (see the dark block). */
  --card: var(--bg);
  --accent-soft: rgba(0, 102, 204, .12);
  --font: var(--font-sans);
}

[data-theme="dark"] {
  /* ---- Color: surfaces & text ------------------------------------------ */
  --bg: #000000;
  --surface: #1d1d1f;
  --surface-2: #2a2a2c;
  --text: #f5f5f7;
  --text-muted: #a1a1a6;
  --text-subtle: #8e8e93;

  /* ---- Color: accent & semantic -----------------------------------------
     Not a mechanical inversion of the light tokens — Apple's own dark-mode
     link blue (#2997ff) replaces #0066cc, which fails WCAG on near-black. */
  --accent: #2997ff;
  --accent-hover: #57ade0;
  --on-accent: #1d1d1f;   /* white-on-#2997ff fails 4.5:1 (3.02); near-black passes (5.58) */
  --success: #32d74b;
  --error: #ff453a;

  /* ---- Color: chrome dividers & frost ------------------------------------ */
  --hairline: rgba(255, 255, 255, .12);
  --hairline-strong: rgba(255, 255, 255, .24);
  /* Decorative-only, same weight class as --hairline-strong — see the r7
     rationale on the light definition above. */
  --control-border-soft: rgba(255, 255, 255, .24);
  --frost: rgba(0, 0, 0, .72);

  /* ---- Liquid Glass (dark) ----------------------------------------------
     Not a mechanical invert: the specular edge is a low-alpha WHITE line in
     both themes (that is how glass catches light), but the fill and rim are
     tuned for near-black. Fills stay high-alpha so muted text on the glass
     nav/toast keeps AA over the worst-case blended background (GLASS block
     in the WCAG verification below). The fill composites SLIGHTLY LIGHTER than
     the opaque content panes (#1d1d1f) so the frosted nav sits raised over the
     content rather than recessing under it — mirroring the raised-chip logic.
     Muted-on-glass stays >=4.5 (GLASS block). */
  --glass-bg: rgba(48, 51, 58, .66);
  --glass-blur: 26px;
  --glass-saturate: 190%;
  --glass-edge: rgba(255, 255, 255, .22);
  --glass-edge-soft: rgba(255, 255, 255, .06);
  --glass-rim: rgba(255, 255, 255, .12);
  --glass-specular: rgba(255, 255, 255, .26);
  --glass-chip: rgba(255, 255, 255, .26);   /* raised active-segment chip */
  --glass-track: rgba(255, 255, 255, .05);  /* recessed capsule track      */
  --glass-shadow: 0 12px 40px rgba(0, 0, 0, .55), 0 2px 10px rgba(0, 0, 0, .45);
  --glass-shadow-lift: 0 18px 50px rgba(0, 0, 0, .62), 0 3px 14px rgba(0, 0, 0, .5);

  /* Ambient orbs glow more openly against true black — the drama of the dark
     theme — while staying blue-led to hold the single-accent identity. */
  --orb-1: rgba(41, 151, 255, .24);  /* dark accent blue — behind the nav */
  --orb-2: rgba(0, 208, 190, .16);   /* teal                              */
  --orb-3: rgba(128, 118, 255, .18); /* indigo                            */
  --orb-4: rgba(30, 140, 255, .13);  /* soft blue                         */

  /* ---- Legacy bridge ----------------------------------------------------
     --font resolves through the tokens above via var() indirection, so it
     needs no dark redeclaration; --card and --accent-soft take the
     theme-specific literals below. */
  --card: var(--surface);
  --accent-soft: rgba(41, 151, 255, .18);
}

/* ==========================================================================
   WCAG contrast verification (computed via the WCAG 2.1 relative-luminance
   formula, not eyeballed). Text pairs target >=4.5:1 (AA normal text);
   non-text UI components (focus ring, hairline borders) target >=3:1 where
   the pairing is load-bearing for identifying the component. Recomputed
   whenever a token value in this file changes.

   LIGHT THEME
   -----------
   text        #1d1d1f on bg      #ffffff  -> 16.83:1  PASS (>=4.5)
   text        #1d1d1f on surface #f5f5f7  -> 15.46:1  PASS (>=4.5)
   text-muted  #6e6e73 on bg      #ffffff  ->  5.07:1  PASS (>=4.5)
   text-muted  #6e6e73 on surface #f5f5f7  ->  4.66:1  PASS (>=4.5)
   text-subtle #757579 on bg      #ffffff  ->  4.59:1  PASS (>=4.5)
     (text-subtle is used against --bg/--card in practice, never bare
     --surface, as noted in DESIGN.md; on --surface it measures 4.21:1.)
   accent      #0066cc on bg      #ffffff  ->  5.57:1  PASS (>=4.5, used as link/icon text)
   accent      #0066cc on accent-soft      ->  4.99:1  PASS (active-tab text on tinted bg)
   on-accent   #ffffff on accent  #0066cc  ->  5.57:1  PASS (filled-button text)
   focus       #0071e3 on bg      #ffffff  ->  4.70:1  PASS (>=3, non-text UI)
   success     #1a7f37 on bg      #ffffff  ->  5.08:1  PASS (>=4.5)
   error       #d70015 on bg      #ffffff  ->  5.38:1  PASS (>=4.5)
   hairline    rgba(0,0,0,.08) on white     ~1.25:1  Accepted exception —
     frozen DD-006 §2 spec intentionally uses a near-invisible chrome
     divider; never used to convey information on its own.
   control-border-soft rgba(0,0,0,.18) on bg #ffffff -> ~1.72:1  Accepted
     exception (r7) — same weight class as --hairline-strong, decorative
     only; no longer the WCAG 1.4.11 carrier. See CONTROL IDENTIFICATION
     STRATEGY below for what replaced it.
   surface     #f5f5f7 on bg      #ffffff  ->  1.09:1  Decorative fill only
     (ENH-007, select/.swap-btn resting background) — NOT a WCAG 1.4.11
     boundary; carries no contrast floor, same status as --hairline. The
     actual identification duty is the chevron + hover/focus border, per
     CONTROL IDENTIFICATION STRATEGY below.
   surface-2   #ebebee on bg      #ffffff  ->  1.19:1  Decorative fill only
     (ENH-007, .modal-select/#panel select resting background — see the dark
     entry below for why these two contexts step up from plain --surface).

   DARK THEME
   ----------
   text        #f5f5f7 on bg      #000000  -> 19.29:1  PASS (>=4.5)
   text        #f5f5f7 on surface #1d1d1f  -> 15.46:1  PASS (>=4.5)
   text-muted  #a1a1a6 on bg      #000000  ->  8.16:1  PASS (>=4.5)
   text-muted  #a1a1a6 on surface #1d1d1f  ->  6.54:1  PASS (>=4.5)
   text-subtle #8e8e93 on bg      #000000  ->  6.44:1  PASS (>=4.5)
   text-subtle #8e8e93 on surface #1d1d1f  ->  5.16:1  PASS (>=4.5)
   accent      #2997ff on bg      #000000  ->  6.96:1  PASS (>=4.5, link/icon text)
   accent      #2997ff on surface #1d1d1f  ->  5.58:1  PASS
   on-accent   #1d1d1f on accent  #2997ff  ->  5.58:1  PASS (filled-button text;
     white-on-#2997ff was tested first and FAILS at 3.02:1 — this is why
     --on-accent flips to near-black in dark mode, see DESIGN.md §2)
   focus       #0071e3 on bg      #000000  ->  4.47:1  PASS (>=3, non-text UI;
     same hex as light theme, independently verified here)
   success     #32d74b on bg      #000000  -> 10.96:1  PASS (>=4.5)
   error       #ff453a on bg      #000000  ->  6.16:1  PASS (>=4.5)
   hairline    rgba(255,255,255,.12) on black ~1.2:1  Accepted exception,
     same rationale as light theme.
   control-border-soft rgba(255,255,255,.24) on bg #000000 -> ~1.93:1
     Accepted exception (r7), same rationale as the light theme entry above.
   surface     #1d1d1f on bg      #000000  ->  1.25:1  Decorative fill only
     (ENH-007), same status as the light-theme entry above.
   surface-2   #2a2a2c on card    #1d1d1f  ->  1.18:1  Decorative fill only
     (ENH-007, .modal-card .modal-select AND #panel select — both containers
     fill with --card, which equals --surface in dark mode (#1d1d1f); a plain
     --surface select background would be visually IDENTICAL to either
     container there (1.00:1), so these two contexts step to --surface-2
     instead — see the light-theme entry above for the same fill's contrast
     against --bg). Still purely decorative, no contrast floor — see above.

   CONTROL IDENTIFICATION STRATEGY (r7) — border decorative, not the carrier
   ---------------------------------------------------------------------
   The control border is decorative chrome, not the WCAG 1.4.11 "component
   identification" carrier: a solid >=3:1 gray border reads as a hard rectangle
   fighting the frosted, translucent chrome everywhere else, so the duty rests
   instead on two indicators that are always present and independently >=3:1 in
   both themes:
     1. The select chevron. Its stroke reuses --text-muted's hex per theme
        (#6e6e73 light / #a1a1a6 dark) against the control's own resting
        fill — --surface for .lang-select and .panel select outside #panel
        (ENH-007; the already-verified text-muted-on-surface pairing above,
        4.66:1 light / 6.54:1 dark), --surface-2 for .modal-select and
        #panel select specifically (ENH-007; recomputed for this change
        since the fill differs: #6e6e73 on #ebebee -> 4.26:1 light, #a1a1a6
        on #2a2a2c -> 5.57:1 dark) — both comfortably clear >=3:1, and the
        chevron is present on every <select> in the app (.panel select,
        .lang-select, .modal-select share one rule; the dark-theme chevron
        override is unconditional, not select-specific — no select ships
        without it).
     2. The focus/hover state. Hover switches the border to --accent (a
        theme-relative var — 5.57:1 light / 6.96:1 dark against --bg, both
        verified above) and focus does the same (or --focus on
        .lang-select's focus-visible ring, 4.70:1 light / 4.47:1 dark) plus,
        on .lang-select, a 2px outline — a much stronger non-text signal
        than a static border.
   Plain text inputs/textareas have no chevron, so their identification
   rests on the visible bounded box (background + padding, a distinct shape
   from surrounding static text) plus the same focus-to-accent transition —
   the same precedent this file already accepts for --hairline (a
   near-invisible divider whose identification role is carried by context,
   not raw contrast). control-border-soft itself is now purely decorative
   chrome and carries no contrast floor, same as --hairline/--hairline-strong.

   GLASS (r5) — text on the translucent glass nav / tab-capsule / toast
   ---------------------------------------------------------------------
   Glass fills are translucent, so the effective background is the fill
   composited over whatever is painted behind it. r5 raises both the fill
   alpha AND the ambient-orb presence (DD-006 r5 brief: the glass must be
   visibly refracting in a static screenshot), so the WORST REALISTIC
   underlying surface is re-verified against TWO backdrops: --surface-2
   (content scrolled under the bar) and the peak ambient-orb tint (the
   nav sits directly over --orb-1 at its blue-brightest point). The lower
   of the two is the binding case.

   LIGHT — glass-bg rgba(250,250,252,.74)
     over --surface-2 #ebebee           -> eff #f6f6f8
       text  #1d1d1f -> 15.61:1 PASS | muted #6e6e73 -> 4.70:1 PASS | accent #0066cc -> 5.16:1 PASS
     over peak ambient (orb-1 .22 on white) -> eff #edf3fa
       text  #1d1d1f -> 15.02:1 PASS | muted #6e6e73 -> 4.52:1 PASS <- binding case | accent #0066cc -> 4.97:1 PASS
   DARK — glass-bg rgba(48,51,58,.66)
     Nav composited over pure --bg #000 reads #202226 (32,34,38) — a
     touch LIGHTER than the opaque panes (--surface #1d1d1f = 29,29,31),
     so the frosted nav sits proud of the content rather than recessing
     under it.
     over --surface-2 #2a2a2c           -> eff #2e3035
       text  #f5f5f7 -> 12.13:1 PASS | muted #a1a1a6 -> 5.13:1 PASS <- binding case | accent* #2997ff -> 4.38:1
     over peak ambient (orb-1 .24 on black) -> eff #232e3b
       text  #f5f5f7 -> 12.64:1 PASS | muted #a1a1a6 -> 5.35:1 PASS | accent* #2997ff -> 4.57:1
     *accent on the nav glass is the brand MARK (an SVG icon) + the active-tab
      dot — non-text UI, so the >=3:1 floor applies (both cases pass). No
      accent-COLORED text sits on the glass; the tagline is --text-muted
      (verified >=4.5 above), tab labels are --text.

   ACTIVE TAB CHIP (--glass-chip) — the raised segment inside the tab
   capsule's recessed --glass-track. Its label uses --text (not --accent):
   on a bright/lifted glass chip, primary text is the contrast-safe choice
   in both themes — this is also the authentic iOS segmented-control read
   (the raised segment carries the label in the primary ink, not a tinted
   one). A small accent-colored dot marks which segment is active as a
   second, non-text cue (decorative, no contrast floor).
     LIGHT chip rgba(255,255,255,.82) over track over peak ambient -> eff #f3f7fb
       text #1d1d1f -> 15.68:1 PASS (>=4.5)
     DARK  chip rgba(255,255,255,.26) over track over peak ambient -> eff #535f6e
       text #f5f5f7 -> 5.51:1 PASS (>=4.5)

   The modal-card is deliberately NOT translucent: it is a dense form surface
   sitting over a dark dim-scrim, and a see-through fill would drop --text-
   subtle (the disclaimer) below 4.5:1. It keeps the opaque --card fill and
   earns its glass read from the specular edge + floating --glass-shadow
   only, so every modal label holds its already-verified on-card contrast.
   The specular edge and ambient orbs are decorative, non-text, and never the
   sole carrier of information — no contrast floor applies to them.
   ========================================================================== */
