/* ============================================================================
   GARAMUT DESIGN TOKENS — single source of truth (redesign Phase 0)
   docs/ui-redesign-brainstorm.md §3 (palette direction C) + §5 (architecture)

   Contract (mirrors the Lukaut playbook):
   - BRAND CONSTANTS are never themed.
   - SEMANTIC TOKENS are day-first in :root; [data-theme="night"] overrides;
     [data-surface="field"] is the high-contrast PWA variant.
   - Legacy pre-redesign aliases are RETIRED (Phase 4b): screens consume
     semantic names only, enforced by scripts/assert-semantic-tokens.mjs.
   - The dashboard + login currently pin <html data-theme="night"> so the
     app keeps its command-navy look until Phase 1 ships the Day/Night
     switcher with day as the desk default.

   Fonts are self-hosted (assets/fonts/): a remote font @import would leak
   every visitor's IP to a third party on a politically sensitive page and
   block first paint. Subset for the PNG connectivity reality
   (ui5-field-resilience, spec §11): each face instanced to the weights the
   dashboard renders and to its real character set — display + mono are
   ASCII app copy (headings, stamps, labels), Public Sans is the CONTENT
   face and keeps full Latin-1 for names/quotes. A char outside a face's
   range per-glyph-falls-back to the system stack. ~42KB total (was ~90KB);
   size ceiling enforced by tests/field-resilience.test.ts.
   ========================================================================== */

@font-face {
  font-family: "Space Grotesk";
  src: url("/assets/fonts/space-grotesk-var-latin.woff2") format("woff2-variations");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0020-007E, U+00A0, U+00A9, U+00B0, U+00B7, U+00D7, U+00F7, U+2010-2015, U+2018-201F, U+2022, U+2026, U+2030, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215;
}
@font-face {
  font-family: "Public Sans";
  src: url("/assets/fonts/public-sans-var-latin.woff2") format("woff2-variations");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2010-2015, U+2018-201F, U+2022, U+2026, U+2030, U+2039-203A, U+2044, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("/assets/fonts/jetbrains-mono-var-latin.woff2") format("woff2-variations");
  font-weight: 400 800;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0020-007E, U+00A0, U+00A9, U+00B0, U+00B7, U+00D7, U+00F7, U+2010-2015, U+2018-201F, U+2022, U+2026, U+2030, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215;
}

:root {
  /* ---- BRAND CONSTANTS (never themed) ---------------------------------- */
  --png-red: #c8102e;          /* PNG flag red — shared brand DNA with Lukaut */
  --hq-gold-day: #b08321;      /* ochre gold — daylight desk accent */
  --hq-gold-night: #f5c518;    /* bright gold — command-night accent */
  --hq-ink: #1c1f26;
  --hq-paper: #f6f5f1;
  --hq-navy: #0a1226;

  /* ---- TYPE ------------------------------------------------------------- */
  --font-display: "Space Grotesk", "Inter Tight", "Arial Narrow", "Helvetica Neue", Arial, sans-serif;
  --font-ui: "Public Sans", Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-mono: "JetBrains Mono", "SFMono-Regular", Consolas, monospace;
  --track-label: 0.1em;
  --fs-stamp: 0.78rem;

  /* ---- TYPE SCALE (ui5-type-scale, spec §5.1–5.2) ------------------------
     The ten font sizes the dashboard is allowed to speak, plus the three
     tracking stops. Every `font-size:` / `letter-spacing:` in
     ui_kits/dashboard/*.css must reference these (display glyphs above the
     scale use calc() multiples) — enforced by scripts/assert-type-scale.mjs. */
  --fs-2xs: 11px;
  --fs-xs: 12px;
  --fs-sm: 13px;
  --fs-md: 14px;
  --fs-lg: 16px;
  --fs-xl: 19px;
  --fs-2xl: 23px;
  --fs-3xl: 28px;
  --fs-4xl: 34px;
  --fs-5xl: clamp(38px, 4vw, 48px);
  --track-tight: -0.02em;
  --track-normal: 0;
  --track-eyebrow: 0.12em;

  /* ---- SEMANTIC TOKENS — DAY (default) ---------------------------------- */
  --bg: var(--hq-paper);
  --surface: #ffffff;
  --surface-2: #f1efe9;
  --surface-sunken: #efede8;
  --chrome: #eceae4;                 /* sidebar / app chrome (deeper neutral field) */
  --ink-well: #1c1f26;               /* permanently-dark stage (login identity) */
  --text: #1c1f26;
  --text-strong: #14161b;
  --text-soft: #424954;
  --text-faint: #545b66;
  --text-on-accent2: #14161b;

  --accent: #c8102e;                 /* urgent / primary CTA */
  --accent-deep: #9d1220;
  --accent-2: var(--hq-gold-day);    /* secondary CTA, highlights */
  --accent-2-deep: #8f6a1a;
  --accent-2-soft: #cfa53f;
  --live: #157e83;                   /* live / positive signal (teal); 4.83:1 on white */
  --info: #4a6285;
  --slate: #5d6470;

  /* readiness (spec §6: on_target / watch / behind) */
  --ready-on-target: #25785a;
  --ready-watch: #8a6e0e;
  --sensitive: #a4457b;           /* sensitive-cluster flag (magenta), AA on white */
  --ready-behind: #a23b2e;

  /* chart palette (ui5-dataviz, spec §8): Okabe–Ito-derived, darkened for
     ≥3:1 non-text contrast on --surface AND --bg, pairwise-distinct under
     deuteranopia (checked mechanically in tests/viz-tokens.test.ts).
     --viz-1..6 are categorical strokes/fills; --viz-up/down/flat tone trend
     deltas — never the alarm red, direction never by line color alone. */
  --viz-1: #0e6ea8;
  --viz-2: #9c6a06;
  --viz-3: #0f7862;
  --viz-4: #a04d78;
  --viz-5: #b3400f;
  --viz-6: #5b6474;
  --viz-up: #1f7a4d;
  --viz-down: #b3400f;
  --viz-flat: #5d6470;

  /* volunteer tiers (spec §4) */
  --tier-hq: #1c1f26;
  --tier-leader: #25785a;
  --tier-sub: #8a6e0e;
  --tier-volunteer: #5d6470;

  /* fill tokens — pinned light in BOTH themes (white text on fills must stay AA) */
  --ok-fill: #1f7a4d;
  --on-fill: #ffffff;

  /* registration / ID status */
  --st-pending: #9a6a16;
  --st-active: #1f7a4d;
  --st-suspended: #c8102e;
  --st-issued: #1f7a4d;
  --st-none: #636a75;

  --border: #dedbd2;
  --border-strong: #b9b5aa;
  --border-input: #7c7a72;
  --divider: #e8e5dd;
  --surface-hover: rgba(28, 31, 38, 0.045);
  --surface-raised: rgba(28, 31, 38, 0.055);
  --ring: rgba(176, 131, 33, 0.45);
  --focus-outline: #1c1f26;

  /* depth ladder (ui5-depth-radius-z): exactly three tiers, navy-tinted so
     day shadows read as cast light rather than soot. Floating elements only
     (menus/popovers, .rail, toasts, modal surfaces, glass pass). */
  --shadow-sm: 0 1px 2px color-mix(in oklab, var(--hq-navy) 4%, transparent), 0 8px 24px -16px color-mix(in oklab, var(--hq-navy) 14%, transparent);
  --shadow-md: 0 2px 6px color-mix(in oklab, var(--hq-navy) 5%, transparent), 0 14px 36px -14px color-mix(in oklab, var(--hq-navy) 22%, transparent);
  --shadow-lg: 0 30px 80px -32px color-mix(in oklab, var(--hq-navy) 55%, transparent);
  /* 1px edge hairlines (night border-light rims / chrome under-edges) — not depth */
  --edge-shade: rgba(0, 0, 0, 0.5);
  --edge-light: rgba(255, 255, 255, 0.025);
  --shadow-glow: 0 0 0 1px rgba(176, 131, 33, 0.22), 0 0 28px rgba(176, 131, 33, 0.12);

  /* ---- LIQUID GLASS (surface treatment, Xavier 2026-07-02) --------------
     Translucent panel skin + blur amounts. Solid fallbacks remain the
     semantic tokens above; [data-surface="field"] re-pins glass to solid. */
  --glass-surface: rgba(255, 255, 255, 0.5);
  --glass-surface-strong: rgba(252, 251, 248, 0.72);
  --glass-edge: rgba(255, 255, 255, 0.6);
  --glass-rim: rgba(255, 255, 255, 0.85);
  --glass-blur: 18px;
  --glass-sat: 1.4;

  /* ---- SCALES (theme-invariant) ----------------------------------------- */
  --space-1: 4px;  --space-2: 8px;  --space-3: 12px; --space-4: 16px;
  --space-5: 20px; --space-6: 24px; --space-7: 28px; --space-8: 32px;

  /* radius scale (ui5-depth-radius-z): the only corner rounding the dashboard
     speaks — enforced by scripts/assert-radius-scale.mjs. --radius-pill is the
     shape exception for pills/bars; true circles use bare 50%. */
  --radius-xs: 4px; --radius-sm: 10px; --radius: 14px; --radius-lg: 20px;
  --radius-pill: 999px;

  /* z-index ladder (ui5-depth-radius-z): every z-index in dashboard CSS sits
     on one of these rungs — enforced by scripts/assert-z-ladder.mjs. */
  --z-below: -1;
  --z-base: 0;
  --z-raised: 10;
  --z-sticky: 100;
  --z-rail: 200;
  --z-overlay: 300;
  --z-modal: 400;
  --z-toast: 500;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-amb: ease-in-out;
  --dur-1: 150ms; --dur-2: 300ms; --dur-3: 550ms; --dur-amb: 1.4s;
}

/* ---- SEMANTIC TOKENS — NIGHT (command navy) ------------------------------ */
[data-theme="night"] {
  --bg: var(--hq-navy);
  --surface: #12203f;
  --surface-2: #1a2a4d;
  --surface-sunken: #0d1730;
  --chrome: #060b18;
  --ink-well: #060b18;
  --text: #e3e6ec;
  --text-strong: #f7f8fa;
  --text-soft: #a7b0c4;
  --text-faint: #a7b0c4;
  --text-on-accent2: #08112a;

  --accent: #f0606d;                 /* lifted PNG red (raw fails AA on navy) */
  --accent-deep: #c8102e;
  --accent-2: var(--hq-gold-night);
  --accent-2-deep: #e89b00;
  --accent-2-soft: #ffe27a;
  --live: #5fbfae;
  --info: #cadcfc;
  --slate: #8b93a3;

  --ready-on-target: #5cc08a;
  --ready-watch: #d4b04a;
  --sensitive: #d86ca0;
  --ready-behind: #e8924a;

  --viz-1: #66b3e3;
  --viz-2: #f2c14e;
  --viz-3: #46c39c;
  --viz-4: #d98bb5;
  --viz-5: #e0703a;
  --viz-6: #98a0b4;
  --viz-up: #5cc08a;
  --viz-down: #e0703a;
  --viz-flat: #98a0b4;

  --tier-hq: #e8ebf1;
  --tier-leader: #5cc08a;
  --tier-sub: #d4b04a;
  --tier-volunteer: #8b93a3;

  --st-pending: #d9a84e;
  --st-active: #5cc08a;
  --st-suspended: #f0606d;
  --st-issued: #5cc08a;
  --st-none: #a3aab8;

  --border: rgba(227, 230, 236, 0.16);
  --border-strong: rgba(227, 230, 236, 0.28);
  --border-input: #7e879a;
  --divider: rgba(227, 230, 236, 0.10);
  --surface-hover: rgba(255, 255, 255, 0.045);
  --surface-raised: rgba(255, 255, 255, 0.055);
  --ring: rgba(245, 197, 24, 0.5);
  --focus-outline: #f5c518;

  --glass-surface: rgba(18, 32, 63, 0.5);
  --glass-surface-strong: rgba(6, 11, 24, 0.66);
  --glass-edge: rgba(255, 255, 255, 0.14);
  --glass-rim: rgba(255, 255, 255, 0.09);
  --glass-blur: 20px;
  --glass-sat: 1.35;

  /* deployed shell-pass shadows (agent-shell-pass.css, absorbed Phase 0) */
  --shadow-sm: inset 0 1px 0 rgba(255, 255, 255, 0.025), 0 1px 0 rgba(0, 0, 0, 0.55);
  --shadow-md: inset 0 1px 0 rgba(255, 255, 255, 0.035), 0 18px 40px rgba(0, 0, 0, 0.24);
  --shadow-lg: 0 34px 90px rgba(0, 0, 0, 0.42);
  --shadow-glow: inset 0 0 0 1px rgba(245, 197, 24, 0.22), 0 18px 42px rgba(0, 0, 0, 0.22);
}

/* ---- FIELD SURFACE (PWA, sunlight-readable) ------------------------------ */
[data-surface="field"] {
  /* viz tokens re-pinned to the light-background palette: data-surface
     composes with data-theme on the same <html>, so with night pinned the
     night viz values would land on this near-white bg at <3:1. This block
     is declared after [data-theme="night"], so it wins the tie.
     Enforced for BOTH day+field and night+field in tests/viz-tokens.test.ts. */
  --viz-1: #0e6ea8;
  --viz-2: #9c6a06;
  --viz-3: #0f7862;
  --viz-4: #a04d78;
  --viz-5: #b3400f;
  --viz-6: #5b6474;
  --viz-up: #1f7a4d;
  --viz-down: #b3400f;
  --viz-flat: #5d6470;
  /* glass off in sunlight: translucency + blur hurt outdoor readability */
  --glass-surface: var(--surface);
  --glass-surface-strong: var(--surface);
  --glass-edge: var(--border);
  --glass-rim: transparent;
  --glass-blur: 0px;
  --glass-sat: 1;
  --bg: #fdfdfb;
  --surface: #ffffff;
  --surface-2: #f2f0ea;
  --text: #101318;
  --text-soft: #33383f;
  --text-faint: #474d57;
  --border: #b9b5aa;
  --border-strong: #8d897e;
}

/* Phase-0 legacy alias layer RETIRED (Phase 4b, ui-phase4-premium-polish):
   every screen now consumes semantic tokens directly — see
   scripts/assert-semantic-tokens.mjs for the enforced contract. */

/* ---- Structural accessibility (ui5-a11y-structural, spec §10) -------------
   Lives in the token layer so all four shipped pages inherit it. */

/* Screen-reader-only labels: visually removed, fully announced. */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* One focus ring for every focusable element (component rules that load
   later may tighten the offset, never remove the ring). Keyboard-only:
   :focus-visible leaves pointer clicks unringed. */
:focus-visible {
  outline: 2px solid var(--focus-outline);
  outline-offset: 2px;
}

/* Reduced-motion completion (spec §5.5): the curated keyframe gates handle
   the designed reveals; this closes over every remaining transition and
   animation so no bare hover/entrance moves for reduced-motion users. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* iOS focus-zoom guard: iOS Safari (and every iOS WebView) zooms the page in
   when a form control whose font-size is under 16px takes focus, and never
   zooms back out. Floor text-entry controls at 16px on touch pointers so
   tapping a field never zooms; mouse/desktop type scales are untouched.
   Deliberately NOT fixed with `maximum-scale=1` on the viewport meta — that
   also kills pinch-to-zoom for low-vision users. */
@media (pointer: coarse) {
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]),
  textarea,
  select {
    font-size: 16px !important;
  }
}
