/* kubik.tools — design system v5, "Navy/Passport/Rust" (Stage 15)
   Single source of truth for every page (logistics-calculator.html,
   about.html, mcp.html, privacy.html). No hardcoded colors, fonts, or
   font sizes outside this file — everything consumes these custom
   properties.

   Three art-directed themes, switched by [data-theme] on <html>, set by
   the in-app theme picker (persisted to localStorage, defaults to the
   visitor's prefers-color-scheme — dark→navy, light→passport):
   - [data-theme="navy"]     (default) — dark blue/teal, engineering
     spec-sheet.
   - [data-theme="passport"] — light paper/green/orange, customs/transit.
   - [data-theme="rust"]     — dark amber/olive, freight-yard stencil.
   Values below are converged from design-ref-v2/Kubik Tokens.md (AA-
   verified per token — do not "fix" a ratio without re-verifying).
   Legacy var *names* from the old 2-theme system (dark/light) are kept
   1:1 so the ~5000 lines of existing CSS/JSX that consume them are
   untouched; only the palette values and the theme keys changed. */

@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;600;700&family=IBM+Plex+Sans:wght@400;500;600&family=IBM+Plex+Mono:wght@400;500;600&family=Newsreader:ital@1&display=swap');

:root,
:root[data-theme="navy"] {
  /* ── Neutral ramp — the contrast engine ───────────────────────── */
  --bg: #0a0f1a;
  --surface-1: #0e1524;
  --surface-2: #131c30;
  --border: #1c2740;
  --border-strong: rgba(28, 39, 64, 0.7);
  --hairline: #1c2740;
  --desk: #05080e;

  /* ── Text tiers (five) ────────────────────────────────────────── */
  --text-hero: #FFFFFF;      /* computed results, key metrics ONLY */
  --text-primary: #eaf0fa;   /* body, labels — 14.83:1 min */
  --text-second: #9aa7c4;    /* secondary labels, units — "muted" — 7.04:1 min */
  --text-label: #8492ad;     /* uppercase field/section labels — 5.42:1 min — the faint-grey label floor */
  --text-dim: #8492ad;       /* alias of text-label — meta, placeholders, eyebrows */
  --text-faint: #6c7994;     /* dimmest tier: disclaimers, "/ max" separators, fine print */

  /* ── Accent — primary + secondary ─────────────────────────────── */
  --accent: #5b9dff;
  --accent-deep: #4a8ceb;    /* gradient end, primary-button fill only */
  --accent-sky: #5b9dff;
  --accent-secondary: #f2b53d;
  --accent-glow: rgba(91, 157, 255, 0.35);
  --on-primary: #06101f;     /* text/icon color drawn on top of --accent fills */

  /* ── Weak tints + rail/panel-specific surfaces (Stage 15, AppShell.dc.html) */
  --accent-weak: rgba(91, 157, 255, 0.14);
  --accent-secondary-weak: rgba(242, 181, 61, 0.14);
  --accent2: #3fd0a4;
  --accent2-weak: rgba(63, 208, 164, 0.13);
  --accent2-border: rgba(63, 208, 164, 0.35);
  --danger-weak: rgba(255, 122, 122, 0.16);
  --active-bg: rgba(91, 157, 255, 0.13);
  --panel: #080d17;

  --input-bg: #0c1322;
  --btn-quiet-bg: #131c30;

  --deck-border: rgba(28, 39, 64, 0.7);
  --deck-texture: rgba(132, 146, 173, 0.03);

  /* ── Status — safety states only, never decorative ────────────── */
  --success: #3fd0a4;
  --warning: #f2b53d;
  --danger: #ff7a7a;

  /* ── Focus / active-view / glow / ambient / motif (Stage 15) ─────── */
  --focus-ring: #5b9dff;
  --active-view-bar: #5b9dff;
  --glow-title: 0 0 30px rgba(91, 157, 255, 0.48);
  --ambient-top: radial-gradient(130% 90% at 50% -25%, rgba(91, 157, 255, .20), rgba(63, 208, 164, .06) 44%, transparent 72%);
  --motif-stamp-color: #f2b53d;
  --motif-stamp-opacity: 0.30;
  --motif-refline: #8492ad;
  --watermark-ceiling: 0.06;

  /* ── Hazard tape — exactly two decorative placements only (see
     usage rules) — amber / navy. Two rhythms: -stripe (11/22px) and
     -stripe-tight (7/14px, active-tab underline). ─────────────────── */
  --tape-amber: #f2c94c;
  --hazard-a: #f2c94c;
  --hazard-b: #0e1524;
  --tape-stripe: repeating-linear-gradient(135deg, #f2c94c 0 11px, #0e1524 11px 22px);
  --tape-stripe-tight: repeating-linear-gradient(135deg, #f2c94c 0 7px, #0e1524 7px 14px);

  /* ── Cargo colors (8 × fill/on-color) ────────────────────────────── */
  --cargo-0: #5b9dff; --cargo-0-on: #0f0f0f; /* Sky */
  --cargo-1: #3fd0a4; --cargo-1-on: #0f0f0f; /* Teal */
  --cargo-2: #f2c94c; --cargo-2-on: #0f0f0f; /* Amber */
  --cargo-3: #ff7a7a; --cargo-3-on: #0f0f0f; /* Coral */
  --cargo-4: #b28dff; --cargo-4-on: #0f0f0f; /* Violet */
  --cargo-5: #4fd1e0; --cargo-5-on: #0f0f0f; /* Cyan */
  --cargo-6: #f2803c; --cargo-6-on: #0f0f0f; /* Orange */
  --cargo-7: #ff86c8; --cargo-7-on: #0f0f0f; /* Pink */

  color-scheme: dark;
}

:root[data-theme="passport"] {
  /* ── Neutral ramp ─────────────────────────────────────────────────
     Stage 16.1 density pass: --surface-1 used to be *darker* than --bg
     (efe7ce vs f3ecd7) — backwards from Navy/Rust, where every surface
     tier gets strictly brighter as it comes forward (bg < surface-1 <
     surface-2), and backwards from the refreshed mocks' own passport
     palette (bg2 #f4eeda is lighter than bg #efe6cd). Cards/sheets were
     reading as recessed wells instead of paper sitting on top of the desk.
     Flipped surface-1 to sit above bg (brighter, "paper" tier); surface-2
     stays the deeper/recessed tier (hover fills, input tracks), matching
     the mock's bg3 direction — Passport is the one theme where the third
     tier goes *darker* (shadow-side of the paper), not lighter. ────── */
  --bg: #f3ecd7;
  --surface-1: #f9f3e2;
  --surface-2: #e8dfc2;
  --border: #ddd1af;
  --border-strong: #cbbb95;
  --hairline: #ddd1af;
  --desk: #d9c79a;

  /* ── Text tiers — ink / secondary / label / faint ────────────────
     (hero aliases to ink: there's no brighter tier on paper). */
  --text-hero: #1c2b26;
  --text-primary: #1c2b26;   /* 11.08:1 min */
  --text-second: #4f5e54;    /* 5.15:1 min */
  --text-label: #586357;     /* 4.72:1 min — the faint-grey label floor */
  --text-dim: #586357;
  --text-faint: #7a8577;

  /* ── Accent — forest green primary, burnt-orange secondary. Its own
     identity, not an inversion of Navy. ───────────────────────────── */
  --accent: #1f6b52;
  --accent-deep: #195943;
  --accent-sky: #1f6b52;
  --accent-secondary: #cf6a2a; /* 3.09:1 vs s0 — large text/border/icon/motif ONLY, never body text */
  --accent-glow: rgba(31, 107, 82, 0.25);
  --on-primary: #f3ecd7;

  /* ── Weak tints + rail/panel-specific surfaces (Stage 15, AppShell.dc.html) */
  --accent-weak: rgba(31, 107, 82, 0.10);
  --accent-secondary-weak: rgba(207, 106, 42, 0.13);
  --accent2: #a9791f;
  --accent2-weak: rgba(169, 121, 31, 0.12);
  --accent2-border: rgba(169, 121, 31, 0.32);
  --danger-weak: rgba(178, 58, 46, 0.13);
  --active-bg: rgba(31, 107, 82, 0.10);
  --panel: #ece2c6;

  --input-bg: #fbf7ea;
  --btn-quiet-bg: #fbf7ea;

  --deck-border: #ddd1af;
  --deck-texture: rgba(120, 105, 70, 0.04);

  /* ── Status — forest doubles as success; burnt-orange is warning;
     brick is danger. accent-secondary and success are different roles
     even though both land near orange/green — don't conflate. ─────── */
  --success: #2f8a5f;
  --warning: #cf6a2a;
  --danger: #b23a2e;

  --focus-ring: #1f6b52;
  --active-view-bar: #1f6b52;
  --glow-title: 0 0 30px rgba(31, 107, 82, 0.22);
  --ambient-top: radial-gradient(130% 90% at 50% -25%, rgba(207, 106, 42, .13), rgba(31, 107, 82, .06) 42%, transparent 70%);
  --motif-stamp-color: #cf6a2a;
  --motif-stamp-opacity: 0.30;
  --motif-refline: #586357;
  --watermark-ceiling: 0.06;

  /* ── Personality accents: gold/deep-green, not amber/navy. ───────── */
  --tape-amber: #c9a33e;
  --hazard-a: #c9a33e;
  --hazard-b: #1c3a30;
  --tape-stripe: repeating-linear-gradient(135deg, #c9a33e 0 11px, #1c3a30 11px 22px);
  --tape-stripe-tight: repeating-linear-gradient(135deg, #c9a33e 0 7px, #1c3a30 7px 14px);

  --cargo-0: #1f6b52; --cargo-0-on: #ffffff; /* Forest */
  --cargo-1: #cf6a2a; --cargo-1-on: #0f0f0f; /* Burnt */
  --cargo-2: #c9a63a; --cargo-2-on: #0f0f0f; /* Ochre */
  --cargo-3: #b23a2e; --cargo-3-on: #ffffff; /* Brick */
  --cargo-4: #6d8f4e; --cargo-4-on: #0f0f0f; /* Olive */
  --cargo-5: #3a7d78; --cargo-5-on: #ffffff; /* Teal */
  --cargo-6: #8a5a2b; --cargo-6-on: #ffffff; /* Umber */
  --cargo-7: #8f5b7a; --cargo-7-on: #ffffff; /* Plum */

  color-scheme: light;
}

:root[data-theme="rust"] {
  /* ── Neutral ramp ─────────────────────────────────────────────── */
  --bg: #14100a;
  --surface-1: #1c160d;
  --surface-2: #251d11;
  --border: #332818;
  --border-strong: rgba(51, 40, 24, 0.85);
  --hairline: #332818;
  --desk: #0c0904;

  /* ── Text tiers ───────────────────────────────────────────────── */
  --text-hero: #ffffff;
  --text-primary: #f6eddd;   /* 14.32:1 min */
  --text-second: #bcac90;    /* 7.48:1 min */
  --text-label: #a99a7d;     /* 6.02:1 min — the faint-grey label floor */
  --text-dim: #a99a7d;
  --text-faint: #8f8267;

  /* ── Accent — amber primary, steel-blue secondary. ───────────────── */
  --accent: #e8833a;
  --accent-deep: #d47530;
  --accent-sky: #e8833a;
  --accent-secondary: #6ba3b8;
  --accent-glow: rgba(232, 131, 58, 0.35);
  --on-primary: #14100a;

  /* ── Weak tints + rail/panel-specific surfaces (Stage 15, AppShell.dc.html) */
  --accent-weak: rgba(232, 131, 58, 0.15);
  --accent-secondary-weak: rgba(107, 163, 184, 0.14);
  --accent2: #9caa5c;
  --accent2-weak: rgba(156, 170, 92, 0.14);
  --accent2-border: rgba(156, 170, 92, 0.35);
  --danger-weak: rgba(229, 112, 90, 0.16);
  --active-bg: rgba(232, 131, 58, 0.14);
  --panel: #100c07;

  --input-bg: #191308;
  --btn-quiet-bg: #251d11;

  --deck-border: #332818;
  --deck-texture: rgba(169, 154, 125, 0.03);

  /* ── Status — olive success, gold warning, warm-red danger. ──────── */
  --success: #9caa5c;
  --warning: #e0b84a;
  --danger: #e5705a;

  --focus-ring: #e8833a;
  --active-view-bar: #e8833a;
  --glow-title: 0 0 30px rgba(232, 131, 58, 0.45);
  --ambient-top: radial-gradient(130% 90% at 50% -25%, rgba(232, 131, 58, .18), rgba(156, 170, 92, .06) 44%, transparent 72%);
  --motif-stamp-color: #6ba3b8;
  --motif-stamp-opacity: 0.30;
  --motif-refline: #a99a7d;
  --watermark-ceiling: 0.06;

  /* ── Personality accents: amber / warm-black. ────────────────────── */
  --tape-amber: #e8a33a;
  --hazard-a: #e8a33a;
  --hazard-b: #14100a;
  --tape-stripe: repeating-linear-gradient(135deg, #e8a33a 0 11px, #14100a 11px 22px);
  --tape-stripe-tight: repeating-linear-gradient(135deg, #e8a33a 0 7px, #14100a 7px 14px);

  --cargo-0: #e8833a; --cargo-0-on: #0f0f0f; /* Amber */
  --cargo-1: #9caa5c; --cargo-1-on: #0f0f0f; /* Olive */
  --cargo-2: #e0b84a; --cargo-2-on: #0f0f0f; /* Gold */
  --cargo-3: #e5705a; --cargo-3-on: #0f0f0f; /* Rust */
  --cargo-4: #6ba3b8; --cargo-4-on: #0f0f0f; /* Steel */
  --cargo-5: #c98a4a; --cargo-5-on: #0f0f0f; /* Tan */
  --cargo-6: #5fa878; --cargo-6-on: #0f0f0f; /* Sage */
  --cargo-7: #c78ba0; --cargo-7-on: #0f0f0f; /* Mauve */

  color-scheme: dark;
}

:root {
  /* ── Legacy radius names (kept — consumed throughout the app) ────── */
  --radius: 6px;         /* buttons, chips, badges → radius-sm/md */
  --radius-input: 9px;   /* text inputs, selects → radius-md */
  --radius-window: 12px; /* app window, modal, cards → radius-lg */

  /* ── Radius scale (Stage 15 spec §1) ──────────────────────────────── */
  --radius-sm: 6px;
  --radius-md: 9px;   /* inputs, buttons, chips */
  --radius-lg: 12px;  /* cards, meters */
  --radius-xl: 14px;  /* major cards */
  --radius-2xl: 16px; /* modals */
  --radius-pill: 999px;

  /* ── Spacing scale (4px base) ─────────────────────────────────────── */
  --space-0: 0px;
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-7: 32px;
  --space-8: 40px;
  --space-9: 56px;

  /* ── Depth ─────────────────────────────────────────────────────── */
  --shadow-card: 0 4px 16px rgba(0, 0, 0, 0.35);

  /* ── Fonts ─────────────────────────────────────────────────────── */
  --font-heading: 'Space Grotesk', system-ui, sans-serif;   /* display / title / stat headline */
  --font-label: 'IBM Plex Sans', system-ui, sans-serif;     /* UI / body copy (legacy name, now the body font per Stage 15 spec) */
  --font-mono: 'IBM Plex Mono', monospace;                  /* data, labels, numerics */
  --font-serif: 'Newsreader', serif;                        /* editorial italic — restricted to 3 slots, see spec §1 */

  /* ── Type scale — legacy px set (12/14/16/20/25/31/39), kept for
     existing call sites. Stage 15 additions below. */
  --fs-12: 12px;
  --fs-14: 14px;
  --fs-16: 16px;
  --fs-20: 20px;
  --fs-25: 25px;
  --fs-31: 31px;
  --fs-39: 39px;

  /* ── Stage 15 named type scale ─────────────────────────────────────── */
  --type-title: 34px;     /* Space Grotesk 700 — page H1, the only glow element */
  --type-section: 20px;   /* Space Grotesk 600 — section headings */
  --type-card: 16px;      /* Space Grotesk 600 — card titles, result labels */
  --type-body: 14px;      /* IBM Plex Sans 400 — body copy, min body size */
  --type-body-sm: 13px;   /* IBM Plex Sans 400/500 — dense UI text, buttons */
  --type-label: 11px;     /* IBM Plex Mono 500 uppercase, tracking 1.4px — field/section labels */
  --type-micro: 10.5px;   /* IBM Plex Mono 400 — ref-lines, sub-captions, ruler ticks */
  --type-stat-min: 26px;  /* IBM Plex Mono / Space Grotesk 600/700 — numeric readouts */
  --type-stat-max: 32px;

  /* ── Motion ────────────────────────────────────────────────────── */
  --transition-fast: 150ms ease;      /* hover, color, background */
  --transition-result: 200ms ease;
  --transition-panel: 200ms ease-out; /* panel / secondary-nav reveal */
}

/* Background wash — the only two allowed gradients are this one and
   primary-button fill. A single soft light source top-center, not a
   texture — the page should "breathe," not look like a grid. Uses
   --accent so it tints correctly across all three themes without a
   separate override. */
body {
  background-color: var(--bg);
  background-image: radial-gradient(ellipse 1100px 700px at 50% -10%, var(--accent-glow), transparent 60%);
  background-repeat: no-repeat;
  /* 14.4 (scroll smoothness): `background-attachment: fixed` forces a
     repaint of this gradient on every scroll frame on most mobile browser
     engines (it can't be promoted to its own compositor layer the way a
     scrolling background can) — the single biggest contributor to scroll
     jank on phones. The glow only reads at the top of the page anyway, so
     letting it scroll away with the content costs nothing visually. */
  transition: background-color var(--transition-fast);
}

/* ── Result-value hierarchy pattern (10.2) ───────────────────────
   Every computed result: big text-hero white mono number, label in
   text-second above/below (never beside at equal size), unit in
   text-second smaller than the number. No glow on the number itself
   — it pops via size + text-hero white only. */
.result-label {
  font-family: var(--font-mono);
  font-size: var(--fs-12);
  color: var(--text-label);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 600;
}
.result-value {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--text-hero);
  font-weight: 700;
  animation: resultIn var(--transition-result) ease;
}
.result-value.is-warning { color: var(--warning); }
.result-value.is-danger { color: var(--danger); }
.result-unit {
  font-family: var(--font-mono);
  font-size: var(--fs-14);
  color: var(--text-second);
  font-weight: 500;
}

/* ── Digit <-> unit spacing (14.2) — number in mono, unit smaller/muted,
   fixed ~6px gap. Thousands grouping uses a thin space (see fmtNum in
   logistics-calculator.html), independent of the . / , decimal-separator
   preference. */
.qty { display: inline-flex; align-items: baseline; gap: 6px; }
.qty-value {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
.qty-unit {
  font-family: var(--font-mono);
  color: var(--text-second);
  font-size: 0.85em;
}

@keyframes resultIn {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Wordmark (10.3): text-only, no icon. "kubik" text-primary,
   ".tools" accent-sky, tight tracking. */
.wordmark {
  font-family: var(--font-heading);
  font-weight: 700;
  letter-spacing: -0.02em;
}
.wordmark .w-kubik { color: var(--text-primary); }
.wordmark .w-tools { color: var(--accent-sky); }

/* Page H1 — the only glow element (Stage 15 usage rule 1). */
.page-title-glow {
  text-shadow: var(--glow-title);
}

@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;
  }
}
