/* Crucible web — design tokens.
 *
 * PROVENANCE. Every value below is traced to a real source in this repository
 * or the shipping app, per mission contract §4 ("Study the current running
 * TemplateApp and its source rather than imitating screenshots from memory.
 * Identify and cite the actual components, tokens and behaviors used as
 * references."). Nothing here is invented from memory.
 *
 * Source A — crucible-visualizer/static/css/main.css lines 2–24 (the existing
 *            Crucible web surface). Colours, radii, transitions, nav height and
 *            the monospace stack are lifted verbatim.
 * Source B — TemplateApp ThemeElementSchema (see web/content/typography.json,
 *   whose `source` field records the provenance). The absolute installed
 *   path used to be written here. It resolved to nothing for any reader who
 *   is not on this machine. An absolute machine-local path must not appear
 *   in a client artifact at all - not even in a comment, because a comment
 *   ships. Apollo, APO-...-136. (The forbidden roots are named in
 *   web/tests/artifact_gate.py, not here: writing them in a shipped file
 *   makes every future grep for them stop on this line. Mine did.)
 *            ("Strict mapping of all UI elements to configurable ThemeStore
 *            settings", schemaVersion 1.0). Supplies the typography ROLE names
 *            and the layout canvas concepts.
 *
 * Where a web value has no direct counterpart in either source it is marked
 * DERIVED, with the reasoning. Those are the values Apollo should attack first.
 */

:root {
  /* ---- Colour ----
   * DEFAULT IS LIGHT. Oscar chose the white instrument ground as the baseline,
   * so it must not depend on the visitor's OS setting. Dark is an explicit
   * Admin/user choice below, not the opening state.
   * Dark values are verbatim from Source A and preserved in the dark block. */
  --bg-dark: #09090b;
  --panel-bg: #18181b;
  --border: #27272a;
  --text-main: #f4f4f5;
  --text-muted: #a1a1aa;
  --nav-bg: #000000;

  --accent-blue: #3b82f6;
  /* --accent-green removed. Oscar: colour must always MEAN something. It
   * meant nothing - no success, verified or healthy state uses it - and a
   * palette entry waiting for a purpose is how tacky colour arrives. */
  --accent-purple: #8b5cf6;

  /* ---- Geometry: verbatim from Source A ---- */
  --nav-height: 52px;
  /* --radius-sm/md/lg now come from harmonics.css as 3/5/7 parti.
   * Source A's 6/10/14px were already exact parti multiples; they were simply
   * written as constants. Same pixels, derived provenance. Defining them here
   * as well would WIN, because this sheet loads after harmonics.css. */

  /* ---- Motion: verbatim from Source A ---- */
  --transition-fast: 0.15s ease;
  --transition-normal: 0.25s ease;

  /* ---- Type stacks ---- */
  /* Monospace verbatim from Source A. */
  --font-mono: "SF Mono", "Menlo", "Consolas", "Liberation Mono", monospace;
  /* DERIVED: Source A does not define a UI sans stack. Using the system stack
     so the web surface renders in the same face TemplateApp gets from AppKit,
     rather than shipping a webfont that would not match the app. */
  --font-sans: ui-sans-serif, -apple-system, "SF Pro Text", "Helvetica Neue", Arial, sans-serif;

  /* ---- Typography roles ----
   * Role NAMES are from Source B's typographyRoles, which defines 25 roles and
   * their usage. Source B is a mapping schema: it names roles and their intent
   * but does not carry px values (those live in the user's ThemeStore at
   * runtime). The sizes below are therefore DERIVED, chosen on a 1.200 minor-
   * third scale from a 16px body1 so the hierarchy is proportional rather than
   * arbitrary. They are a defensible starting point, NOT a claim of parity.
   * Parity must be confirmed against the running app — see LIMITS in the
   * TemplateApp parity note.
   */
  /* The ten role sizes now come from harmonics.css, each bound to a step of a
   * ladder DERIVED from the sourced role registry (web/content/typography.json).
   * They were hand-written rem constants on a 1.2 ratio, unrelated to the
   * harmonic ladder sitting beside them - two typographic systems, neither
   * answerable to the other, and every --type-step* dead as a result.
   * The ratios between roles are now exactly Source B's.
   * Defining them here as well would WIN, because this sheet loads after
   * harmonics.css, and the binding would be inert. */

  --weight-body: 400;
  --weight-emphasis: 600;        /* B: role "body1Emphasis" */
  --weight-heading: 600;

  --leading-tight: 1.15;
  --leading-normal: 1.6;
  --tracking-tight: -0.02em;
  --tracking-caps: 0.08em;       /* for sectionLabel, which B specifies as ALL-CAPS */

  /* ---- Spacing ----
   * DERIVED: neither source exposes a numeric spacing scale. 4px base, which is
   * the increment implied by Source A's 6/10/14px radii.
   */
  /* --space-1..7 now come from harmonics.css as 2/4/6/8/12/16/24 parti.
   * These were 4/8/12/16/24/32/48px - already whole parti of the same module,
   * discovered rather than designed. 56 call sites across shell.css and
   * admin-panel.css were laying the page out on constants while the harmonic
   * scale beside them was consumed by nothing. Same pixels, formulaic source. */

  /* ---- Shell layout ----
   * DERIVED from Source B's layoutCanvases concepts: a stage/pipeline canvas
   * flanked by panes, with drawerHandles for the drawers. Widths are a web
   * decision; the app is not a fixed-width medium.
   */
  --sidebar-width: 17rem;
  /* --canvas-max removed: the reading column is set by --measure. */
  --header-row-1: var(--nav-height);  /* Source A */
  --header-row-2: 44px;               /* DERIVED: shorter contextual row */

  /* Source B layoutCanvases: paneBackground → innerCornerRadius/innerBorderWidth,
     outerBorder → contentCornerRadius/contentBorderWidth. Mapped to web. */
  --pane-radius: var(--radius-md);
  --pane-border: 1px;
}

/* Light theme.
 * DERIVED. Source A ships dark-first and its light values are not defined.
 * These are computed inversions held to a measured contrast floor rather than
 * eyeballed; the ratios are recorded in the ledger and must be re-measured by
 * the reviewer, not trusted from here.
 */
/* Dark is an EXPLICIT choice, never OS-derived.
 * The baseline is the white instrument ground, so the opening state must not
 * depend on a visitor's system setting.
 *
 * A previous version wrote `:root[data-theme="dark"],` followed by an @media
 * at-rule in the same selector list. That is not valid CSS - a selector list
 * cannot contain an at-rule - so the whole block was discarded and dark mode
 * silently did nothing. Now a standalone, valid rule.
 */
:root[data-theme="light"] {
  color-scheme: light;
  --bg-dark: #ffffff;
  --panel-bg: #f4f4f5;
  --border: #d4d4d8;
  --text-main: #18181b;
  --text-muted: #52525b;
  --nav-bg: #fafafa;
}

/* Honour the user's contrast preference rather than assuming our palette wins. */
@media (prefers-contrast: more) {
  :root {
    --text-muted: var(--text-main);
    --border: var(--text-main);
  }
}

/* ---- Golden ratio (φ = 1.618) ----
 * Oscar asked for 1.618 proportions. PACING_STUDY.md records where it is
 * applied and, importantly, where it is NOT.
 *
 * NOT applied to the body type ramp: a full φ scale gives 16 → 25.9 → 41.9px,
 * which destroys paragraph readability. The measured Antigravity scale is not
 * golden either (1.905/1.312/1.143), so there is nothing to copy here.
 *
 * Applied where φ is actually visible:
 *   1. once at the hero step, mirroring the front-loaded drama in the study
 *   2. layout proportion, canvas to sidebar
 *   3. vertical rhythm between major beats
 *
 * Rule: where φ and legibility conflict, LEGIBILITY WINS and the deviation is
 * recorded in PACING_STUDY.md.
 */
:root {
  /* --phi removed. It was a second, less precise copy of the value in
   * harmonic-layout.json (1.618 vs 1.6180339887), read by one calc that
   * has itself been removed. Two sources for one constant, disagreeing
   * in the fourth decimal, is how a proportional system stops being one. */

  /* 1. Hero: one deliberate φ jump above the section title. */
  --type-hero: 3.75rem;          /* 60px ≈ --type-subheading(27.6px) × φ² / 1.33 */
  --leading-hero: 1.1;           /* study P3: large type earns tight leading */

  /* 2. Layout: sidebars are canvas / φ² so the trio stays proportional
        while the reading column keeps a usable measure. */
  /* --canvas-golden/--sidebar-golden removed. They described the wide shell a
   * second time, in pixels, alongside --shell-rail/--shell-centre which are
   * generated and asserted to sum to exactly 1. --sidebar-golden was 305px
   * beside a comment claiming "≈ 800 / φ²": a derivation asserted next to a
   * frozen number. Performing the division would have kept a duplicate; the
   * honest fix is that the rails have one source. */

  /* 3. Vertical rhythm stepped by φ rather than linearly. */
  --beat-1: 1.5rem;
  --beat-2: 2.427rem;            /* ×φ */
  --beat-3: 3.927rem;            /* ×φ² */
}
