/* Glass Box, Midnight Ledger design system, second register.
   Shared by every page. Two registers, one set of token names:

   - The BODY REGISTER (the :root defaults below): a light powder blue
     gradient ground for the page body, deep navy inks, a deep accent
     blue. This is the register every component sees by default.
   - The DARK REGISTER: the original deep navy ground values, kept for
     the shared header and for surfaces that deliberately stay dark
     (the evidence rail). Applied by re-declaring the SAME custom
     property names under the .ml-dark-surface context class (and the
     header/rail selectors), so a component written as
     color: var(--ink-1) works unmodified in both registers.

   Decisions, values, and computed WCAG ratios live in
   theme_token_spec.md at the repo root (owner-locked 2026-07-11:
   Powder Blue ground, hairline + shadow seam, #2F55B8 body accent).

   Unchanged doctrine: one typeface, Futura, falling back to locally
   installed relatives, no webfont network calls; one accent hue with
   two calibrated values, one per register; --signal reserved for
   idle/warning semantics only; page-specific stylesheets build layout
   on these tokens and never declare a competing palette. */

:root {
  /* ---- Dark constants: the header's own gradient stops. These are the
     original ground tokens, now consumed only inside dark-register
     contexts (the header rule builds its gradient from them). -------- */
  --bg-0: #080D22;
  --bg-1: #0E1A44;
  --bg-2: #14235C;

  /* ---- Ground: the light powder blue body gradient ------------------- */
  --ground-0: #E9F0FB;
  --ground-1: #DCE7F8;
  --ground-2: #D3E1F6;

  /* ---- Ink: text, by weight of statement (body register) -------------
     Ratios against the ground midpoint #DBE6F8:
     ink-0 12.0:1, ink-1 7.5:1, ink-2 4.6:1. ink-3 is decorative
     metadata only, it does not pass 4.5:1 and must never carry
     essential information, the same role it plays today. */
  --ink-0: #16244C;
  --ink-1: #33437A;
  --ink-2: #556492;
  --ink-3: #67739F;

  /* ---- Accent: the one interactive/live signal (body register) -------
     5.4:1 on the ground, passes AA for text. --accent-bright is the
     gradient partner and large-text/UI value only (3.7:1). */
  --accent: #2F55B8;
  --accent-bright: #4A6FD8;
  --accent-dim: rgba(47, 85, 184, 0.12);
  --accent-grad-end: #4A6FD8;
  --on-accent-ink: #FFFFFF;
  --chip-hover-ink: #16244C;

  /* ---- Signal: idle/warning semantics only, meaning unchanged --------
     4.1:1 on the ground, passes for UI and large text. */
  --signal: #96621F;
  --signal-dim: rgba(150, 98, 31, 0.12);

  /* ---- Semantic accents, charts and status states, meanings frozen ---
     good 3.8:1, bad 4.2:1, alert 4.6:1 on the ground. */
  --good: #2E8A61;
  --bad: #C05138;
  --alert: #B5326E;

  /* ---- Verb accents: one hue per story, categorical not sequential ---
     Forensics/Capacity/Time Travel/Ripple/Honesty each get a fixed,
     high-chroma flat color so a reader can tell which of the five
     trust arguments they are looking at without reading the label.
     Applied via a single class on #answer (see style.css's
     .verbtheme--* rules), never hardcoded per component: chips,
     the engine tag, and diagram nodes all resolve through --verb-accent
     so this is one rule to change, not five. Kept visually distinct
     from --good/--bad/--alert/--signal, whose meanings stay frozen. */
  --verb-forensics: #65A30D;
  --verb-forensics-dim: rgba(101, 163, 13, 0.10);
  --verb-capacity: #D97706;
  --verb-capacity-dim: rgba(217, 119, 6, 0.10);
  --verb-timetravel: #0D9488;
  --verb-timetravel-dim: rgba(13, 148, 136, 0.10);
  --verb-ripple: #DB2777;
  --verb-ripple-dim: rgba(219, 39, 119, 0.10);
  --verb-honesty: #16A34A;
  --verb-honesty-dim: rgba(22, 163, 74, 0.10);

  /* ---- Categorical chart ramp: the Gantt's phase bars ----------------
     Six distinct hues, one per phase, owner-approved 2026-07-11,
     tuned lighter and brighter the same day. Fixed assignment order,
     never cycled or reordered per-chart, so a phase keeps the same
     hue everywhere it appears. None of the six reuses
     --good/--bad/--alert/--signal's exact values, so a phase bar can
     never be mistaken for a status color. Validated as a set via the
     dataviz skill's validate_palette.js: lightness band, chroma
     floor, adjacent CVD separation (worst pair ships with direct date
     labels and a surface gap between bars, satisfying the CVD
     secondary-encoding requirement), and contrast against both the
     light glass chart surface and the white bar-label text all pass,
     the last one checked directly since it sits right at the 3:1
     floor for the lightest two steps (teal, green). */
  --phase-1: #3E68D6;
  --phase-2: #1493AE;
  --phase-3: #2C9A63;
  --phase-4: #B87F24;
  --phase-5: #DE4C87;
  --phase-6: #7357CC;

  /* ---- Surfaces (body register): white glass over the blue ground ---- */
  --surface: rgba(255, 255, 255, 0.5);
  --surface-hi: rgba(255, 255, 255, 0.72);
  --surface-glass: rgba(255, 255, 255, 0.58);
  --surface-glass-hi: rgba(255, 255, 255, 0.72);
  --badge-bg: rgba(255, 255, 255, 0.5);

  /* ---- Hairlines ------------------------------------------------------ */
  --hairline: rgba(22, 36, 76, 0.10);
  --hairline-strong: rgba(22, 36, 76, 0.22);

  /* ---- Blur and shadow. Shadows are a primary separator on the light
     ground, not an afterthought; light glass additionally carries an
     inset top highlight where it is composed (see .ml-card--glass). --- */
  --blur: 20px;
  --blur-hi: 28px;
  --shadow: 0 10px 26px -14px rgba(22, 36, 76, 0.28);
  --shadow-hi: 0 16px 40px -16px rgba(22, 36, 76, 0.34);

  /* ---- Type ----------------------------------------------------------------
     One typeface, Futura, for every role. --font-display is kept as an
     alias of --font-body (not a second face) so existing component
     rules that reference --font-display keep working unchanged. */
  --font-body: 'Futura', 'Century Gothic', 'Avenir Next', 'Segoe UI', sans-serif;
  --font-display: var(--font-body);
  --font-mono: 'Consolas', 'SFMono-Regular', ui-monospace, monospace;

  --fs-micro: 10px;
  --fs-label: 11px;
  --fs-small: 12.5px;
  --fs-body: 14.5px;
  --fs-body-lg: 16px;
  --fs-statement: 20px;
  --fs-answer: 19px;
  --fs-heading: 26px;
  --fs-display: 36px;
  --fs-kpi: 52px;

  /* ---- Spacing scale ------------------------------------------------------ */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 14px;
  --sp-4: 20px;
  --sp-5: 32px;
  --sp-6: 48px;
  --sp-7: 72px;

  --radius: 10px;
  --radius-lg: 16px;
  --radius-pill: 999px;
}

/* ---- Dark register --------------------------------------------------------
   The original Midnight Ledger values, re-declared under the same
   token names for any subtree that stays on the deep navy ground: the
   shared page header, the evidence rail, and anything explicitly
   opting in via .ml-dark-surface. Values here are byte-for-byte the
   pre-overhaul :root values, so dark-register surfaces render exactly
   as they always did. */
.ml-dark-surface,
header,
.rail {
  --ink-0: #F3F6FF;
  --ink-1: #C7D0EE;
  --ink-2: #8D9AC9;
  --ink-3: #5E6A96;

  --accent: #7FA0F2;
  --accent-bright: #B7C9FA;
  --accent-dim: rgba(127, 160, 242, 0.16);
  --accent-grad-end: #4E6FD9;
  --on-accent-ink: #0A1230;
  --chip-hover-ink: #FFFFFF;

  --signal: #D9A15C;
  --signal-dim: rgba(217, 161, 92, 0.16);

  --good: #3FB37F;
  --bad: #E0725A;
  --alert: #E0509A;

  --verb-forensics: #A3E635;
  --verb-forensics-dim: rgba(163, 230, 53, 0.16);
  --verb-capacity: #F0B457;
  --verb-capacity-dim: rgba(240, 180, 87, 0.16);
  --verb-timetravel: #4FD1C5;
  --verb-timetravel-dim: rgba(79, 209, 197, 0.16);
  --verb-ripple: #F472B6;
  --verb-ripple-dim: rgba(244, 114, 182, 0.16);
  --verb-honesty: #4ADE80;
  --verb-honesty-dim: rgba(74, 222, 128, 0.16);

  --phase-1: #B7C9FA;
  --phase-2: #96B0F6;
  --phase-3: #7FA0F2;
  --phase-4: #6488E3;
  --phase-5: #4E6FD9;
  --phase-6: #3D63CF;

  --surface: rgba(255, 255, 255, 0.045);
  --surface-hi: rgba(255, 255, 255, 0.09);
  --surface-glass: rgba(20, 30, 68, 0.55);
  --surface-glass-hi: rgba(24, 36, 82, 0.7);
  --badge-bg: rgba(8, 13, 34, 0.4);

  --hairline: rgba(154, 176, 230, 0.14);
  --hairline-strong: rgba(154, 176, 230, 0.26);

  --shadow: 0 8px 32px -14px rgba(4, 8, 24, 0.55);
  --shadow-hi: 0 20px 52px -16px rgba(4, 8, 24, 0.65);
}

/* The hidden attribute must always win over any component's own display
   property. See style.css for the incident that motivated this rule;
   kept here too since tokens.css is the first stylesheet every page
   loads. */
[hidden] { display: none !important; }

/* ---- Ambient ground, applied by any page that opts in via body.ml-ground -
   The light powder blue gradient, top to bottom, with a faint accent
   tint top-left so backdrop blur on glass panels has something real to
   diffuse. The header sitting above this ground keeps its own deep
   navy gradient (dark register), which is exactly the deep-header,
   light-body split the second register exists for. */
body.ml-ground {
  background:
    radial-gradient(ellipse 1100px 700px at 12% -8%, rgba(47, 85, 184, 0.09), transparent 60%),
    linear-gradient(180deg, var(--ground-0) 0%, var(--ground-1) 55%, var(--ground-2) 100%);
  background-attachment: fixed;
  color: var(--ink-1);
  font-family: var(--font-body);
  font-weight: 300;
}

/* ---- Page-entry transition -----------------------------------------------
   A brief fade/rise on first paint, applied uniformly via body.ml-ground
   so every page gets the same considered entry without per-page JS. Kept
   short and subtle on purpose: this signals "the page arrived", it does
   not perform for the viewer. Respects prefers-reduced-motion via the
   blanket override below, which collapses the animation duration to
   effectively nothing. */
@media (prefers-reduced-motion: no-preference) {
  body.ml-ground {
    animation: ml-page-in 0.42s cubic-bezier(0.16, 1, 0.3, 1) both;
  }
  @keyframes ml-page-in {
    from { opacity: 0; transform: translateY(6px); }
    to { opacity: 1; transform: none; }
  }
}

/* ---- Component primitives ------------------------------------------------
   Defined once, reused by every page. Page CSS may add layout around
   these (grid placement, width) but should not redeclare their color,
   border, or type. Register-dependent values resolve through the
   tokens above, so these rules are register-agnostic. */

.ml-chip {
  display: inline-flex; align-items: center;
  font-family: var(--font-mono); font-size: 0.9em;
  border: 1.5px solid var(--accent); color: var(--accent);
  background: transparent; border-radius: 4px;
  padding: 1px 8px; cursor: pointer; white-space: nowrap;
  transition: background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
  margin: 6px 1px;
}
.ml-chip:hover, .ml-chip:focus-visible {
  background: var(--accent-dim); color: var(--chip-hover-ink);
  box-shadow: 0 0 0 3px var(--accent-dim);
  outline: none;
}
.ml-chip.ml-chip--signal { border-color: var(--signal); color: var(--signal); }
.ml-chip.ml-chip--signal:hover, .ml-chip.ml-chip--signal:focus-visible {
  background: var(--signal-dim); color: var(--chip-hover-ink);
  box-shadow: 0 0 0 3px var(--signal-dim);
}
/* Visual size stays compact (chips sit inline in prose or dense rows),
   but on coarse-pointer devices the tap target grows to a touch-friendly
   minimum so a phone tap doesn't need pixel-perfect aim. */
@media (hover: none) and (pointer: coarse) {
  .ml-chip { min-height: 32px; line-height: 28px; padding: 1px 11px; }
}

.ml-card {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  padding: var(--sp-4) var(--sp-4);
}

.ml-card--glass {
  background: var(--surface-glass);
  backdrop-filter: blur(var(--blur));
  -webkit-backdrop-filter: blur(var(--blur));
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow), inset 0 1px 0 rgba(255, 255, 255, 0.8);
}
.ml-dark-surface .ml-card--glass,
header .ml-card--glass,
.rail .ml-card--glass {
  /* The white top highlight is a light-glass affordance; dark glass
     keeps its original shadow-only composition. */
  box-shadow: var(--shadow);
}

.ml-badge {
  display: inline-flex; align-items: center;
  font-family: var(--font-body); font-weight: 500;
  font-size: var(--fs-micro); letter-spacing: 0.1em; text-transform: uppercase;
  padding: 3px 11px; border-radius: var(--radius-pill);
  border: 1px solid var(--hairline-strong);
  color: var(--ink-2); background: var(--badge-bg);
}
.ml-badge--accent { color: var(--accent); border-color: var(--accent-dim); }
.ml-badge--signal { color: var(--signal); border-color: var(--signal-dim); }

.ml-btn {
  font-family: var(--font-body); font-weight: 500; font-size: var(--fs-body);
  padding: 12px 26px; border-radius: var(--radius-pill);
  border: 1px solid var(--hairline-strong);
  background: transparent; color: var(--ink-0);
  cursor: pointer; text-decoration: none; display: inline-block;
  transition: background 0.18s ease, border-color 0.18s ease, transform 0.15s ease;
}
.ml-btn:hover, .ml-btn:focus-visible {
  background: var(--accent-dim); border-color: var(--accent);
  transform: translateY(-1px); outline: none;
}
.ml-btn--solid {
  background: linear-gradient(135deg, var(--accent), var(--accent-grad-end));
  color: var(--on-accent-ink); border-color: transparent; font-weight: 600;
}
.ml-btn--solid:hover, .ml-btn--solid:focus-visible {
  background: linear-gradient(135deg, var(--accent-grad-end), var(--accent));
  transform: translateY(-2px);
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; }
}
