/* tokens.css — every global custom property, and the three theme blocks.
   Doctrine is :root; Field Briefing is body[data-theme="light"]; Los Angeles is
   body[data-theme="wla"]. Hues belong here: everywhere else a colour is a
   property or a neutral black/white alpha (test/consistency.mjs enforces it),
   so a theme is one block, not a hunt. Theme-scoped overrides that cannot be expressed as a token stay
   beside their theme so the three palettes read side by side.
   Load order is the cascade order — see the <link> list in index.html. */

/* ============================================================
   SOVIET COMMANDER PCE — Command Room redesign
   Palette mapped onto the variable names src/ modules inject inline,
   so dynamically-generated content inherits the theme.
   Army green = structure / data / operational
   Soviet red = command / authority / threat
   ============================================================ */
:root {
    --bg-color: #0a0d07;
    --surface-color: #131a0e;          /* olive panel */
    --surface-2: #0e140a;
    --surface-raised: #182011;
    --surface-border: rgba(168, 188, 120, 0.16);
    --surface-border-strong: rgba(168, 188, 120, 0.30);
    --text-primary: #e9ead9;           /* bone */
    --text-secondary: rgba(233, 234, 217, 0.64);   /* ~4.5:1 on --bg-color */
    --text-faint: rgba(233, 234, 217, 0.60);       /* placeholder/meta — must clear 4.5:1, same as body */
    --accent-color: #a7c049;           /* ARMY GREEN — workhorse accent */
    /* The feed's six channels each own a colour, and no two of them may
       resolve to the same value in a theme. They did: user and error
       shared a stripe in all three, and learning and retrieval shared
       stripe AND label in two — on Los Angeles the six collapsed to
       three. --ch-learned is the one hue this palette had free, and it
       is violet-magenta on purpose: it carries blue, so it is the only
       channel that survives the red-green axis the rest of the console
       lives on. */
    --ch-learned: #9581ff;
    --tint-learned: rgba(149, 129, 255, 0.10);
    --tint-system:  rgba(167, 192, 73, 0.045);
    --focus-ring:   rgba(167, 192, 73, 0.12);    /* the accent at focus-halo strength */
    --scanline:     rgba(168, 188, 120, 0.022);  /* the feed's ruled-paper texture */
    --wash-machine: rgba(167, 192, 73, 0.07);   /* the room's ambient light, machine side */
    --wash-command: rgba(210, 58, 44, 0.06);   /* and command side */
    --grid-line:    rgba(168, 188, 120, 0.035);
    --scrollbar-thumb:       rgba(167, 192, 73, 0.18);
    --scrollbar-thumb-hover: rgba(167, 192, 73, 0.32);
    --selection:             rgba(210, 58, 44, 0.35);
    --select-chevron: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23a7c049' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'></polyline></svg>");
    --accent-danger: #d23a2c;          /* SOVIET RED — fills, borders, indicators */
    --danger-text:   #f4655c;          /* 5.8:1 on ground, 5.2:1 on its own red tint */
    --on-danger:     #ffffff;          /* label sitting on a danger fill */
    --accent-red-deep: #9b271d;
    --terminal-text: #bcd86a;          /* phosphor readout */
    --card-panel: rgba(32, 44, 32, 0.95);   /* generated article/asset cards */
    --group-head: rgba(0, 0, 0, 0.4);       /* collapsible group / status headers */
    /* Any surface that should read as SET INTO its ground: the nav tab
       group, theme switch, class strip, pane heads. Must be a token —
       a fixed black alpha reads as dirt on the light theme's manila. */
    --surface-recessed: rgba(0, 0, 0, 0.35);
    --surface-recessed-soft: rgba(0, 0, 0, 0.22);
    /* Channel tints for content blocks inside a log entry. A tint carries
       the channel where a colored side stripe used to; the stripe belongs
       to the entry, not to blocks nested inside it. */
    --tint-info:    rgba(168, 199, 250, 0.09);
    --tint-command: rgba(210, 58, 44, 0.10);
    --danger-border:  rgba(210, 58, 44, 0.88);   /* destructive outline — 3.06:1, WCAG 1.4.11 */
    --control-border: rgba(168, 188, 120, 0.55);  /* the visible EDGE of a control — 3.3:1 */
    --tint-terminal: rgba(123, 220, 129, 0.12); /* hover ground for controls printed on the phosphor readout */
    --tint-objective: rgba(167, 192, 73, 0.12);
    --tint-gold: rgba(212, 175, 55, 0.14);
    --accent-danger-hot: #e0463a;
    --shadow-action: 0 4px 16px rgba(210, 58, 44, 0.30);
    /* Semantic status/output tokens — consumed by src/-generated content so
       dynamic readouts follow the active theme instead of hardcoded hex. */
    --success-text:   #74cf7d;         /* op complete — 9.3:1 as text here */
    --status-working:  #d6a92e;        /* in-progress amber */
    --status-info:     #a8c7fa;        /* neutral progress */
    --terminal-bg:     rgba(0, 24, 6, 0.55);   /* green CRT readout box */
    --terminal-fg:     #7bdc81;        /* emerald terminal text */
    --oga-accent:      #9db8ff;        /* recovered-asset / OGA blue */
    --loot-gold:       #d4af37;        /* guaranteed-drop gold */
    --heading-strong:  #ffffff;        /* max-contrast generated headings */
    /* Grounds and shades that used to sit as literals in the area stylesheets
       (phase 14). Each theme states its own, so manila never inherits a black
       inset and the neon HUD never inherits olive. */
    --header-ground:   linear-gradient(180deg, #0e140a 0%, #0b0f08 100%);
    --strip-ground:    #090c06;           /* the classification strip */
    --option-ground:   #0c1107;           /* an open <select>'s list */
    --optgroup-ground: #0c1107;
    --on-accent:       #0a0d07;           /* a mark printed on an accent fill (the checkbox tick) */
    --control-ground:       rgba(0, 0, 0, 0.32);   /* text fields and selects */
    --control-ground-focus: rgba(0, 0, 0, 0.5);
    --dropzone-ground: rgba(0, 0, 0, 0.32);       /* the file picker */
    --inset-ground:    rgba(0, 0, 0, 0.28);       /* the order input well */
    --button-ground:   rgba(255, 255, 255, 0.04);
    --entry-ground:    rgba(255, 255, 255, 0.018); /* a feed entry, lifted off the ruled feed */
    --hover-tint:      rgba(127, 127, 127, 0.14); /* neutral grey: reads on every ground */
    --hover-tint-soft: rgba(127, 127, 127, 0.10);
    --scrollbar-track: rgba(0, 0, 0, 0.2);
    --scrim:           rgba(0, 0, 0, 0.62);       /* behind a modal or a sheet */
    --shadow-ink:      rgba(0, 0, 0, 0.6);        /* a drawer's edge shadow */
    --shadow-overlay:  0 18px 60px rgba(0, 0, 0, 0.55);
    --crest-wash-top:    rgba(155, 39, 29, 0.20);  /* the rail crest: --accent-red-deep */
    --crest-wash-bottom: rgba(155, 39, 29, 0.05);
    --crest-edge:        rgba(210, 58, 44, 0.32);  /* --accent-danger */
    --crest-hatch:       rgba(210, 58, 44, 0.06);
    /* Printed plates (phase 13): the commander portraits, the sector terrain
       plates and the emblem ship as ONE grayscale engraving each, and the
       #plate-duotone filter (index.html) prints them in two inks: black
       becomes --plate-ink, white becomes --plate-paper. Luminance order is
       kept, so a face is never a negative. The paper is held below the
       accents, so a plate never outshouts the readouts around it. */
    --plate-ink:   #0c1108;
    --plate-paper: #a9b27a;
    --radius: 3px;
    /* Type. Spacing, colour, radius and motion all became tokens; type
       stayed 123 bare font-size literals, 74 tracking values and 30
       leadings — which is why tracking had drifted to eight undocumented
       values and leading to five. The ramp is the six documented steps
       and nothing else.
       In rem, not px: a fixed ratio scale and respecting the reader's
       browser font-size setting are separate decisions, and the Fixed
       Scale Rule only ever argued the first. Measured before this: a
       reader who sets their default to 24px moved zero of five sampled
       elements. At a 16px default these render byte-identically to the
       px values they replace. */
    --type-data:    0.6875rem;  /* 11px — status rows, channel tags, mono readouts */
    --type-caption: 0.75rem;    /* 12px — field hints, notes, metadata */
    --type-control: 0.8125rem;  /* 13px — buttons, tabs, chips, routine feed */
    --type-body:    0.9375rem;  /* 15px — prose, form values, the payload tier */
    --type-claim:   1.125rem;   /* 18px — view titles, and what a proof moment asserts */
    --type-display: 1.3125rem;  /* 21px — the wordmark alone */
    /* One stack per voice. 29 of 65 font-family declarations named a face
       with no fallback at all, and four in app.js dropped to a bare
       generic — including both <code> blocks carrying the raw packet,
       which The Mono Is Evidence Rule governs. */
    --font-display: 'Oswald', 'IBM Plex Sans', sans-serif;
    --font-body:    'IBM Plex Sans', system-ui, sans-serif;
    --font-data:    'IBM Plex Mono', 'Courier New', monospace;
    /* Leading and tracking, per role. Eighteen distinct tracking values
       and nine leadings were in the stylesheet against a spec that names
       nine and six; three documented roles set no leading at all and were
       silently taking the browser default.
       --leading-body is 1.6 here and 1.55 on Field Briefing: light text on
       a dark ground reads tighter than the same ratio does dark-on-light,
       so the two dark themes get the compensation and the manila one does
       not. That is the first time this system has distinguished them. */
    --leading-display: 1;
    --leading-claim:   1.2;
    --leading-title:   1.3;
    --leading-label:   1.4;
    --leading-body:    1.6;
    --leading-data:    1.5;
    --track-body:    0.01em;
    --track-display: 0.06em;
    --track-control: 0.08em;
    --track-tab:     0.1em;
    --track-data:    0.12em;
    --track-title:   0.14em;
    --track-label:   0.18em;
    --track-seal:    0.22em;
    /* Spacing scale. DESIGN.md described this ladder for a long time before
       it existed as code, so the stylesheet drifted onto a second, generic
       8/12/16 ladder and two thirds of every spacing value landed off both.
       These are the ladder: ~1.4x per step, odd-numbered on purpose so it
       never coincides with the browser default and every gap is a choice
       somebody made. Reach for a token; if none fits, the layout is wrong,
       not the scale. */
    --space-hair: 3px;      /* optical nudges only — never structural */
    --space-tight: 4px;     /* inside a control: chip gaps, icon offsets */
    --space-micro: 6px;     /* label to its field */
    --space-snug: 9px;      /* between siblings in one group */
    --space-base: 13px;     /* the default: block padding, list gaps */
    --space-shell: 18px;    /* container padding, group separation */
    --space-loose: 26px;    /* between unrelated groups */
    --space-section: 36px;
    --gutter-shell: clamp(12px, 1.8vw, 26px);   /* shell inline gutter, fluid */  /* between sections of a view */
    /* Motion system — one decelerating curve, two durations. Enters ease out
       (content arrives and settles); no bounce, matching the console register. */
    --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
    --dur-fast: 140ms;
    --dur-med:  240ms;
}

/* ============================================================
   THEME B — FIELD BRIEFING (light: olive ink on manila paper)
   ============================================================ */
body[data-theme="light"] {
    --bg-color: #dcd8c3;
    --surface-color: #edeadb;          /* manila panel */
    --surface-2: #e3e0cf;              /* recessed */
    --surface-raised: #f4f2e6;
    --surface-border: rgba(58, 64, 28, 0.22);
    --surface-border-strong: rgba(58, 64, 28, 0.40);
    --text-primary: #23260f;           /* olive ink */
    --text-secondary: rgba(35, 38, 15, 0.74);   /* ~4.5:1 on manila */
    --text-faint: rgba(35, 38, 15, 0.76);       /* placeholder/meta on light */
    --accent-color: #4b5d17;           /* army green, deepened to clear 4.5:1 on manila */
    /* The feed's six channels each own a colour, and no two of them may
       resolve to the same value in a theme. They did: user and error
       shared a stripe in all three, and learning and retrieval shared
       stripe AND label in two — on Los Angeles the six collapsed to
       three. --ch-learned is the one hue this palette had free, and it
       is violet-magenta on purpose: it carries blue, so it is the only
       channel that survives the red-green axis the rest of the console
       lives on. */
    --ch-learned: #510840;
    --tint-learned: rgba(81, 8, 64, 0.09);
    --tint-system:  rgba(75, 93, 23, 0.07);
    --focus-ring:   rgba(75, 93, 23, 0.16);    /* the accent at focus-halo strength */
    --scanline:     rgba(75, 93, 23, 0.030);     /* the feed's ruled-paper texture */
    --wash-machine: rgba(75, 93, 23, 0.06);   /* the room's ambient light, machine side */
    --wash-command: rgba(176, 36, 23, 0.05);   /* and command side */
    --grid-line:    rgba(75, 93, 23, 0.045);
    --scrollbar-thumb:       rgba(85, 105, 26, 0.30);
    --scrollbar-thumb-hover: rgba(85, 105, 26, 0.50);
    --selection:             rgba(176, 36, 23, 0.28);
    --select-chevron: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%234b5d17' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'></polyline></svg>");
    --accent-danger: #b02417;          /* soviet red, deepened */
    --danger-text:   #9d200d;          /* deepened: #b02417 measured 4.31:1 on the header */
    --on-danger:     #ffffff;
    --accent-red-deep: #8a1d12;
    --terminal-text: #4a5d16;          /* ink-green readout */
    --card-panel: #f4f2e6;             /* manila card */
    --group-head: rgba(0, 0, 0, 0.06);
    /* Olive tint, not black: on manila a black alpha reads as grime. */
    --surface-recessed: rgba(58, 64, 28, 0.10);
    --surface-recessed-soft: rgba(58, 64, 28, 0.06);
    --tint-info:    rgba(47, 90, 168, 0.12);
    --leading-body: 1.55;   /* dark-on-light needs no leading compensation */
    --tint-command: rgba(176, 36, 23, 0.10);
    --danger-border:  rgba(176, 36, 23, 0.78);
    --control-border: rgba(58, 64, 28, 0.66);
    --tint-terminal: rgba(30, 90, 40, 0.12);
    --tint-objective: rgba(85, 105, 26, 0.14);
    --tint-gold: rgba(122, 94, 18, 0.14);
    --accent-danger-hot: #c62d1d;
    --shadow-action: 0 4px 16px rgba(176, 36, 23, 0.22);
    /* Daylight-legible status tokens: the green CRT slab becomes an olive
       tint on manila, and generated headings flip to ink (white would vanish). */
    /* Deepened for TEXT, exactly as --danger-text was: #2f7d36 is a fine swatch
       but measures 3.4-4.2:1 as type on the three manila grounds it lands on,
       and eight generated strings colour their text with it. Hue held at 125,
       chroma raised, lightness dropped — 4.7:1 worst case. */
    --success-text:   #196620;
    --status-working:  #685000;
    --status-info:     #2f5aa8;
    --terminal-bg:     rgba(85, 105, 26, 0.10);
    --terminal-fg:     #33481a;
    --plate-ink:   #23260f;
    --plate-paper: #e2ddc5;
    --oga-accent:      #4a3d9e;   /* was byte-identical to --status-info on manila */
    --loot-gold:       #7a5e12;
    --heading-strong:  #23260f;
    --header-ground:   linear-gradient(180deg, #e7e4d2 0%, #dcd8c3 100%);
    --strip-ground:    #cdc9b2;
    --option-ground:   #edeadb;
    --optgroup-ground: #e3e0cf;
    --on-accent:       #f4f2e6;           /* dark ink on the deepened green measured 2.3:1 */
    --control-ground:       rgba(255, 255, 255, 0.6);
    --control-ground-focus: rgba(255, 255, 255, 0.85);
    --dropzone-ground: rgba(0, 0, 0, 0.05);
    --inset-ground:    rgba(0, 0, 0, 0.05);
    --scrollbar-track: rgba(0, 0, 0, 0.06);
    --shadow-ink:      rgba(35, 38, 15, 0.30);    /* The Daylight Shadow Rule: olive ink, half the weight */
    --shadow-overlay:  0 18px 60px rgba(35, 38, 15, 0.28);
    --crest-wash-top:    rgba(138, 29, 18, 0.20);
    --crest-wash-bottom: rgba(138, 29, 18, 0.05);
    --crest-edge:        rgba(176, 36, 23, 0.32);
    --crest-hatch:       rgba(176, 36, 23, 0.06);
    background-color: #d3cfba;
    background-image:
        radial-gradient(120% 80% at 50% -10%, rgba(85, 105, 26, 0.10) 0%, transparent 55%),
        radial-gradient(90% 70% at 92% 8%, rgba(176, 36, 23, 0.06) 0%, transparent 50%),
        linear-gradient(rgba(58, 64, 28, 0.05) 1px, transparent 1px),
        linear-gradient(90deg, rgba(58, 64, 28, 0.05) 1px, transparent 1px);
    background-size: 100% 100%, 100% 100%, 44px 44px, 44px 44px;
}
body[data-theme="light"] #radio-transcript-box { background: rgba(85, 105, 26, 0.10) !important; }
/* The pane heads are --surface-recessed-soft everywhere else; on manila they
   sit one step lighter, level with the order input well (--inset-ground). */
body[data-theme="light"] .comms-head,
body[data-theme="light"] .nl-pane-head { background: rgba(0, 0, 0, 0.05); }
/* The retrieval percentage in the info blue measured 4.26:1 on its row on Field Briefing (18px is not "large" text below bold 18.67px, so AA is 4.5:1). Ink here; the entry's own edge and heading still carry the channel colour. */
body[data-theme="light"] .retrieval-score { color: var(--text-primary); }

/* ============================================================
   THEME C — WESTCODE : LA (neon HUD, from the WLA pitch)
   near-black blue surfaces; cyan workhorse, hot-orange alert,
   magenta classify, gold detail — glows ride existing shadows
   ============================================================ */
body[data-theme="wla"] {
    --bg-color: #05060a;
    --surface-color: #0f1219;
    --surface-2: #0a0b10;
    --surface-raised: #151a26;
    --surface-border: rgba(51, 225, 230, 0.16);
    --surface-border-strong: rgba(51, 225, 230, 0.32);
    --text-primary: #e6eaf1;
    --text-secondary: rgba(230, 234, 241, 0.66);   /* ~4.5:1 on HUD near-black */
    --text-faint: rgba(230, 234, 241, 0.62);       /* placeholder/meta */
    --accent-color: #33e1e6;           /* cyan workhorse */
    /* The feed's six channels each own a colour, and no two of them may
       resolve to the same value in a theme. They did: user and error
       shared a stripe in all three, and learning and retrieval shared
       stripe AND label in two — on Los Angeles the six collapsed to
       three. --ch-learned is the one hue this palette had free, and it
       is violet-magenta on purpose: it carries blue, so it is the only
       channel that survives the red-green axis the rest of the console
       lives on. */
    --ch-learned: #ff5fb0;
    --tint-learned: rgba(255, 95, 176, 0.10);
    --tint-system:  rgba(51, 225, 230, 0.05);
    --focus-ring:   rgba(51, 225, 230, 0.14);    /* the accent at focus-halo strength */
    --scanline:     rgba(51, 225, 230, 0.030);   /* the feed's ruled-paper texture */
    --wash-machine: rgba(255, 106, 31, 0.10);   /* the room's ambient light, machine side */
    --wash-command: rgba(51, 225, 230, 0.07);   /* and command side */
    --grid-line:    rgba(51, 225, 230, 0.03);
    --scrollbar-thumb:       rgba(51, 225, 230, 0.22);
    --scrollbar-thumb-hover: rgba(51, 225, 230, 0.40);
    --selection:             rgba(255, 106, 31, 0.35);
    --select-chevron: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%2333e1e6' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'></polyline></svg>");
    --accent-danger: #ff6a1f;          /* hot orange alert */
    --danger-text:   #ff8747;
    --on-danger:     #1a0b02;          /* white on hot orange measured 2.86:1 */
    --accent-red-deep: #c2410c;
    --terminal-text: #46e0c0;          /* mint phosphor */
    --card-panel: rgba(21, 26, 38, 0.92);   /* raised blue card */
    --group-head: rgba(0, 0, 0, 0.35);
    --surface-recessed: rgba(0, 0, 0, 0.42);
    --surface-recessed-soft: rgba(0, 0, 0, 0.26);
    --tint-info:    rgba(127, 168, 255, 0.12);
    --tint-command: rgba(255, 106, 31, 0.12);
    --danger-border:  rgba(255, 106, 31, 0.65);
    --control-border: rgba(51, 225, 230, 0.50);
    --tint-terminal: rgba(51, 225, 230, 0.12);
    --tint-objective: rgba(51, 225, 230, 0.14);
    --tint-gold: rgba(255, 207, 95, 0.14);
    --accent-danger-hot: #ff8747;
    --shadow-action: 0 4px 16px rgba(255, 106, 31, 0.34);
    /* Neon HUD status tokens — mint success, cyan info, hot-orange error. */
    --success-text:   #46e0c0;         /* op complete — 11.3:1 as text here */
    --status-working:  #e0a458;
    --status-info:     #7fa8ff;   /* was the cyan the workhorse accent already owned */
    --terminal-bg:     rgba(0, 20, 24, 0.5);
    --terminal-fg:     #46e0c0;
    --plate-ink:   #05070c;
    --plate-paper: #8ccfd1;
    --oga-accent:      #c07dff;   /* likewise — provenance is its own colour now */
    --loot-gold:       #ffcf5f;
    --heading-strong:  #ffffff;
    --header-ground:   linear-gradient(180deg, #0b0e16 0%, #07080e 100%);
    --strip-ground:    #06070c;
    --option-ground:   #0a0b10;
    --optgroup-ground: #0a0b10;
    --on-accent:       #05060a;
    --crest-wash-top:    rgba(255, 106, 31, 0.16);
    --crest-wash-bottom: rgba(255, 106, 31, 0.03);
    --crest-edge:        rgba(255, 106, 31, 0.34);
    --crest-hatch:       rgba(51, 225, 230, 0.05);
    background-color: #05060a;
    background-image:
        radial-gradient(120% 90% at 100% -10%, rgba(255, 106, 31, 0.10) 0%, transparent 55%),
        radial-gradient(90% 80% at 0% 110%, rgba(51, 225, 230, 0.07) 0%, transparent 55%),
        radial-gradient(80% 70% at 50% 120%, rgba(255, 47, 142, 0.06) 0%, transparent 60%),
        linear-gradient(rgba(51, 225, 230, 0.03) 1px, transparent 1px),
        linear-gradient(90deg, rgba(51, 225, 230, 0.03) 1px, transparent 1px);
    background-size: 100% 100%, 100% 100%, 100% 100%, 44px 44px, 44px 44px;
}
body[data-theme="wla"] .class-strip .seal { background: #b3005f; color: #ffe3f1; }  /* magenta classify */
body[data-theme="wla"] .brand .wordmark .top .ru { color: var(--accent-color); }
body[data-theme="wla"] .rail-stamp { color: rgba(51, 225, 230, 0.78); border-color: rgba(51, 225, 230, 0.55); }

/* Shell gutter. Every view pads by this; it steps down with the viewport.
   It lived beside the SIM VIEW rules until the stylesheet left index.html. */
:root { --shell-pad: var(--space-shell); }
@media (max-width: 1000px) { :root { --shell-pad: var(--space-base); } }
@media (max-width: 640px)  { :root { --shell-pad: var(--space-snug); } }
