/* ============================================================================
   @briefcase/ui — design tokens (the single source of truth)
   ----------------------------------------------------------------------------
   One file. Every surface — web workbench, mobile (PWA / Capacitor), the
   outfra marketing site, and any later Electron shell — inherits from here.
   This is what unifies the product and keeps "AI slop" drift out.

   THEMING (added 2026-06-23): the system now ships BOTH a dark and a light
   palette under the SAME token names, and defaults to the user's OS theme via
   prefers-color-scheme. A manual choice is applied with :root[data-theme="…"]
   (see theme.ts / the no-FOUC snippet in README). Structural tokens (type,
   space, radius, motion, layout, touch) are theme-independent and live in the
   base :root; only the *palette* (and elevation shadows) changes per theme.

   - Dark  = "instrument / living blueprint" (near-black, cyan).      [default]
   - Light = "TEST BENCH" (warm bone paper, safety orange + cobalt).

   Colors are raw RGB triplets so they compose with alpha and so the SAME name
   carries the right value per theme — derived tints/shadows/glass recompute
   automatically:
       background: rgb(var(--cyan) / 0.12);
       color:      rgb(var(--ink));

   THE ONE RULE: surfaces reference these vars, never raw hex/rgba, off-scale
   radii, or ad-hoc durations. tools/verify/briefcase/lint-tokens.mjs enforces it.
   ========================================================================== */

:root {
  /* dark is the base/fallback palette; light is applied below by media query
     (system pref) and by an explicit [data-theme="light"] override. */
  color-scheme: dark;

  /* ====================================================================== */
  /* STRUCTURAL TOKENS (theme-independent)                                   */
  /* ====================================================================== */

  /* --- typography --------------------------------------------------------- */
  /* --font-display backs apps/web/assets/theme.css's h1/h2/h3/.display rules
     (Archivo, loaded there via Google Fonts); apps/workbench doesn't load
     that webfont yet and stays on --font-ui/--font-mono only. */
  --font-display: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --font-ui:   "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --fs-xs:   0.72rem;   /* eyebrows, captions, BOM micro-labels */
  --fs-sm:   0.84rem;
  --fs-base: 0.95rem;
  --fs-md:   1.1rem;
  --fs-lg:   1.4rem;
  --fs-xl:   2.0rem;
  --fs-2xl:  3.1rem;    /* hero headline */
  --fs-3xl:  4.2rem;    /* hero numerals */

  --fw-regular:  400;
  --fw-medium:   500;
  --fw-semibold: 600;
  --fw-bold:     700;
  --fw-black:    800;   /* Archivo display / brand wordmark */

  --tracking-eyebrow:  0.16em;  /* uppercase instrument-label spacing */
  --tracking-wide:     0.1em;   /* nav labels, small caps */
  --tracking-tight:   -0.025em; /* headline negative tracking */
  --tracking-tighter:  -0.03em; /* hero / wordmark */
  --leading-tight:    1.06;
  --leading-snug:     1.25;
  --leading-body:     1.6;

  --text-eyebrow-size: var(--fs-xs);
  --text-body-size:    var(--fs-base);
  --text-lead-size:    var(--fs-md);

  /* --- spacing: strict 4px baseline --------------------------------------- */
  --space-1: 0.25rem;  --space-2: 0.5rem;   --space-3: 0.75rem;
  --space-4: 1rem;     --space-5: 1.5rem;   --space-6: 2rem;
  --space-8: 3rem;     --space-10: 4rem;    --space-12: 6rem;
  --space-16: 8rem;

  /* --- radius (tight, instrument-grade — not pill-soft) ------------------- */
  --radius-sm: 6px;
  --radius:    10px;
  --radius-lg: 14px;
  --radius-pill: 999px;   /* reserved for genuine pills/chips only */

  /* --- motion: "motion = computation" ------------------------------------- */
  --dur-fast: 120ms;
  --dur-base: 220ms;
  --dur-slow: 480ms;
  --ease:      cubic-bezier(0.2, 0.8, 0.2, 1);   /* resolve & settle */
  --ease-out:  cubic-bezier(0.16, 1, 0.3, 1);    /* assembly snap */

  /* --- layout ------------------------------------------------------------- */
  --maxw: 1200px;
  --gutter: clamp(1rem, 4vw, 3rem);

  /* --- instrument screen / viewport (theme-INVARIANT color) ---------------- */
  /* The CAD viewport's backdrop: a dark instrument screen in BOTH themes,
     mirroring the design system's --screen convention. Lives here with the
     theme-independent tokens on purpose — do NOT restate it in the light/dark
     palette blocks below. */
  --viewport-bg: 6 7 8;     /* #060708 */

  /* instrument screen (theme-invariant graphite inset for live readouts) */
  --screen:      27 29 30;    /* #1b1d1e */
  --screen-edge: 62 66 64;    /* #3e4240 */
  --screen-ink:  226 229 222; /* #e2e5de */
  --screen-dim:  148 153 146; /* #949992 */
  --screen-amber: 251 191 36; /* amber ON a screen — screens stay dark in both themes,
                                 so the light-theme --amber (AA on paper) fails here;
                                 screen-bg components remap --amber to this value */

  /* ====================================================================== */
  /* PALETTE — DARK (base default)                                           */
  /* Keep in sync with the light blocks below.                              */
  /* ====================================================================== */

  /* --- surfaces: the board ------------------------------------------------ */
  --canvas:    10 13 18;    /* #0a0d12  page background */
  --surface:   17 22 29;    /* #11161d  cards, panels */
  --elevated:  22 28 37;    /* #161c25  raised panels, popovers */
  --hairline:  35 43 54;    /* #232b36  borders, the engineering grid */
  --paper-hi:  22 28 37;    /* #161c25  text-on-ink / light-surface fills — always contrasts
                                against an --ink-colored background, flips with theme */

  /* --- ink ---------------------------------------------------------------- */
  --ink:       232 236 242; /* #e8ecf2  primary text */
  --ink-dim:   154 164 178; /* #9aa4b2  secondary text */
  --ink-mute:  107 114 128; /* #6b7280  labels, captions, disabled */

  /* --- overlay bases (glass highlights, shadows) -------------------------- */
  --white:     255 255 255; /* overlay / glass highlight base */
  --black:     0 0 0;       /* overlay / shadow base */

  /* --- semantic accents (physics-mapped) ---------------------------------- */
  --cyan:      125 211 252; /* airflow · cool · data · primary */
  --amber:     251 191 36;  /* heat · power · battery · CTA */
  --green:     74 222 128;  /* validated · in-budget · charge */
  --red:       248 113 113; /* over-thermal · over-budget · fault */
  --warn:      234 179 8;   /* caution (distinct from CTA) */

  /* --- elevation (dark: depth via shadow + faint glow) -------------------- */
  --shadow-card:   0 1px 0 rgb(var(--ink) / 0.03), 0 8px 24px rgb(0 0 0 / 0.35);
  --shadow-lifted: 0 12px 48px rgb(0 0 0 / 0.5);

  /* ====================================================================== */
  /* DERIVED (theme-independent: recompute from whichever palette is active) */
  /* ====================================================================== */

  /* the one chrome accent, system-wide. chrome uses --accent; the physics
     colors are DATA/instrumentation and must not bleed into chrome. */
  --accent:    var(--cyan);
  --data:      var(--cyan);

  --cyan-soft:  rgb(var(--cyan)  / 0.12);
  --amber-soft: rgb(var(--amber) / 0.14);
  --green-soft: rgb(var(--green) / 0.14);
  --red-soft:   rgb(var(--red)   / 0.14);
  --warn-soft:  rgb(var(--warn)  / 0.14);

  --glow-cyan:  0 0 0 1px rgb(var(--cyan) / 0.4), 0 0 24px rgb(var(--cyan) / 0.18);
  --ring-data:  0 0 0 3px rgb(var(--cyan) / 0.22);

  /* glass chrome derives from --elevated (theme-aware) — never from a name a
     legacy stylesheet might redefine as a plain color. */
  --glass-bg:   rgb(var(--elevated) / 0.72);
  --glass-blur: blur(14px);

  /* --- semantic text / surface aliases (handoff parity) ------------------- */
  --text-strong:    rgb(var(--ink));
  --text-body:      rgb(var(--ink-dim));
  --text-muted:     rgb(var(--ink-mute));
  --text-accent:    rgb(var(--accent));
  --text-on-accent: rgb(var(--canvas));
  --surface-page:    rgb(var(--canvas));
  --surface-card:    rgb(var(--surface));
  --surface-inset:   rgb(var(--elevated));
  --border-hairline: rgb(var(--hairline));

  /* --- focus (a11y; one ring everywhere, theme-aware via --accent) -------- */
  --focus-ring:   0 0 0 2px rgb(var(--canvas)), 0 0 0 4px rgb(var(--accent) / 0.9);
  --focus-offset: 2px;

  /* === MOBILE / TOUCH EXTENSIONS ========================================== */
  --touch-min:     44px;   /* Apple HIG */
  --touch-comfy:   48px;   /* Material */

  --safe-top:    env(safe-area-inset-top, 0px);
  --safe-right:  env(safe-area-inset-right, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left:   env(safe-area-inset-left, 0px);

  --sheet-max-h:    80svh;
  --sheet-radius:   var(--radius-lg);
  --sheet-grabber:  36px;
}

/* ============================================================================
   PALETTE — LIGHT ("TEST BENCH")
   Applied when the OS prefers light AND the user hasn't forced dark, and again
   for an explicit [data-theme="light"]. The two blocks MUST stay identical —
   CSS can't share a body across a media query and an attribute selector.
   ========================================================================== */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    color-scheme: light;

    --canvas:    238 236 228; /* #eeece4  warm bone paper */
    --surface:   250 249 245; /* #faf9f5  brighter paper */
    --elevated:  230 227 217; /* #e6e3d9  inset wells */
    --hairline:  206 201 187; /* #cec9bb  drafting rules */
    --paper-hi:  255 254 250; /* #fffefa  text-on-ink / light-surface fills */

    --ink:       28 26 21;    /* #1c1a15  warm graphite */
    --ink-dim:   94 89 78;    /* #5e594e */
    --ink-mute:  106 100 86;  /* #6a6456  AA: 4.97 on canvas, 4.58 on elevated */

    --cyan:      36 86 184;   /* #2456b8  drafting cobalt — data · links */
    --amber:     170 47 10;   /* #aa2f0a  safety orange — CTA · heat; AA as text
                                 on canvas (5.69) and on --amber-soft chips (4.59) */
    --green:     17 101 60;   /* #11653c  AA on --green-soft chips (4.90) */
    --red:       182 41 35;   /* #b62923 */
    --warn:      164 98 6;    /* #a46206 */

    --shadow-card:   0 1px 2px rgb(28 26 21 / 0.05), 0 6px 20px rgb(28 26 21 / 0.07);
    --shadow-lifted: 0 2px 4px rgb(28 26 21 / 0.08), 0 18px 48px rgb(28 26 21 / 0.16);
  }
}

:root[data-theme="light"] {
  color-scheme: light;

  --canvas:    238 236 228;
  --surface:   250 249 245;
  --elevated:  230 227 217;
  --hairline:  206 201 187;
  --paper-hi:  255 254 250;

  --ink:       28 26 21;
  --ink-dim:   94 89 78;
  --ink-mute:  106 100 86;

  --cyan:      36 86 184;
  --amber:     170 47 10;
  --green:     17 101 60;
  --red:       182 41 35;
  --warn:      164 98 6;

  --shadow-card:   0 1px 2px rgb(28 26 21 / 0.05), 0 6px 20px rgb(28 26 21 / 0.07);
  --shadow-lifted: 0 2px 4px rgb(28 26 21 / 0.08), 0 18px 48px rgb(28 26 21 / 0.16);
}

/* Explicit dark override (user forced dark on a light-OS machine): re-assert
   the dark palette so it beats the prefers-light media block above. Dark is the
   base :root, so only color-scheme + the differing values need restating. */
:root[data-theme="dark"] {
  color-scheme: dark;

  --canvas:    10 13 18;
  --surface:   17 22 29;
  --elevated:  22 28 37;
  --hairline:  35 43 54;
  --paper-hi:  22 28 37;

  --ink:       232 236 242;
  --ink-dim:   154 164 178;
  --ink-mute:  107 114 128;

  --cyan:      125 211 252;
  --amber:     251 191 36;
  --green:     74 222 128;
  --red:       248 113 113;
  --warn:      234 179 8;

  --shadow-card:   0 1px 0 rgb(var(--ink) / 0.03), 0 8px 24px rgb(0 0 0 / 0.35);
  --shadow-lifted: 0 12px 48px rgb(0 0 0 / 0.5);
}

/* ----------------------------------------------------------------------------
   Touch density scope. data-density="touch" on <html> (or a subtree) for
   coarse-pointer / narrow surfaces. Pointer defaults first; the explicit touch
   opt-in must come AFTER with equal specificity so it wins. Don't reorder.
   -------------------------------------------------------------------------- */
:root {
  --control-h:    36px;        /* instrument density default (pointer) */
  --row-gap:      var(--space-2);
  --tap-pad:      var(--space-2);
}
[data-density="touch"] {
  --control-h:    var(--touch-comfy);
  --row-gap:      var(--space-3);
  --tap-pad:      var(--space-3);
}
@media (hover: none) and (pointer: coarse) {
  :root:not([data-density="pointer"]) {
    --control-h:  var(--touch-comfy);
    --row-gap:    var(--space-3);
    --tap-pad:    var(--space-3);
  }
}

/* ----------------------------------------------------------------------------
   A11y fallbacks. Glass + transparency hurt contrast for some users and tank
   fill-rate on weak GPUs. Solid fallback so the look degrades gracefully.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-transparency: reduce) {
  :root {
    --glass-bg:   rgb(var(--elevated));
    --glass-blur: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-fast: 0.001ms;
    --dur-base: 0.001ms;
    --dur-slow: 0.001ms;
  }
}

/* ----------------------------------------------------------------------------
   Instrument screen: dark graphite inset with bright trace accents. Re-scopes
   physics triplets so rgb(var(--amber)) etc. stay legible on graphite in any
   page theme (the marketing hero viewport, ticker, footer).
   -------------------------------------------------------------------------- */
.screen {
  --amber: 255 138 76;
  --cyan:  126 168 255;
  --green: 96 205 150;
  --red:   255 110 95;
  --warn:  255 184 108;
  --cyan-soft:  rgb(var(--cyan)  / 0.14);
  --amber-soft: rgb(var(--amber) / 0.14);
  --green-soft: rgb(var(--green) / 0.14);
  --red-soft:   rgb(var(--red)   / 0.14);
  --ink:      var(--screen-ink);
  --ink-dim:  var(--screen-dim);
  --ink-mute: 118 123 117;
  --surface:  35 38 39;
  --elevated: 42 45 46;
  --hairline: var(--screen-edge);
  --accent:   var(--cyan);
  background: rgb(var(--screen));
  color: rgb(var(--screen-ink));
}
