/* ═══ DATUM FI · TOKENS ════════════════════════════════════════════════════════════════════════
 * THE ONE PLACE THE PALETTE LIVES. Every page links this file; nothing else declares these names.
 *
 * WHY IT IS SPLIT IN THREE. The old names encoded A PIGMENT in the identifier — --teal-mid,
 * --gold, --bg-navy, --danger-red. The moment the accent stops being teal, `--teal-mid: #d5ad63`
 * is a lie in a variable name, read 1,334 times across 43 files. A straight rename to a prettier
 * pigment would be the same mistake in better taste: `var(--verdigris)` still does not tell you
 * whether it is an accent, a border or a background.
 *   🔑 PAINT is WHAT THE COLOUR IS. ROLE is WHAT IT IS FOR. Pages read ROLE (or, for now, LEGACY).
 *      Recolouring the site becomes editing the PAINT block, and not one identifier anywhere
 *      becomes a lie.
 *
 * ⛔ THE RULE THAT KEEPS THIS HONEST: A TOKEN FILE MAY ONLY CONTAIN VALUES THAT ALREADY EXIST.
 *    A NAME WITH NO SOURCE IS A DESIGN DECISION SMUGGLED IN AS PLUMBING. Two paints and four
 *    roles from the original scheme are DELIBERATELY ABSENT below — see the omissions note.
 * ═════════════════════════════════════════════════════════════════════════════════════════════ */

:root {
  /* ── 🎨 PAINT · WHAT THE COLOUR IS ──────────────────────────────────────────────────────────
   * THE ONLY PLACE A HEX EVER APPEARS. To recolour the site, edit this block and nothing else. */
  --paint-verdigris:      #5DCAA5;                    /* the workhorse accent */
  --paint-verdigris-deep: #1D9E75;
  /* PROVENANCE, NOT IMPLEMENTATION: verdigris mixed 30% toward chalk. Shipped as a HEX because
   * paints hold hex — recomputed and checked against the derivation before landing (141.6/217.9/192).
   * ⚠️ DERIVED FROM *OUR* VERDIGRIS, NOT LIFTED FROM proto's #a3efe0, which is relative to proto's
   *    accent and would have drifted us off our own family. (MASTER SPEC §76.1) */
  --paint-verdigris-light: #8EDAC0;
  --paint-brass:          #C9A84C;
  --paint-brass-deep:     #B8952F;
  /* ⭐ ADDED 2026-08-28 (Captain-ruled). The Studio's design source carries a BRIGHTER gold than
     brass and the Captain chose it on LEGIBILITY grounds, not taste. It is a -light sibling rather
     than a new material because brass already had a -deep and verdigris already had both — REUSING
     THE MODIFIER CONVENTION INSTEAD OF COINING A COLOUR-WORD KEEPS THE PAINT TIER MATERIAL-NAMED,
     which is the whole reason a recolour cannot make a paint name into a lie. */
  --paint-brass-light:    #D5AD63;
  --paint-chalk:          #ffffff;                    /* what a draughtsman marks with on a dark ground */
  --paint-red-lead:       #e24b4a;
  /* ⛔⛔ OPAQUE SINCE 2026-08-19, AND THE LAW IT NOW OBEYS WAS ALREADY WRITTEN THREE LINES BELOW.
   * It held rgba(100,180,255,0.05) — a PAINT carrying an alpha — which is precisely what
   * --paint-graphite-blue's comment forbids: "A PAINT IS A PIGMENT; TRANSPARENCY IS HOW A SURFACE
   * *USES* IT." One paint was exempt from a rule the file already stated, and nothing caught it
   * because its only consumer wanted exactly that alpha.
   * ⛔ IT STOPPED BEING HARMLESS THE MOMENT A SECOND CONSUMER APPEARED. --light-fill derives 14%
   *    from this paint; against a 5%-alpha pigment that COMPOUNDS to 0.00714 — MEASURED 20x TOO
   *    FAINT (§80.4), a light source that would have been effectively invisible.
   * 🔑 THE ALPHA DID NOT VANISH, IT MOVED TO WHERE IT ALWAYS BELONGED: --grid-line derives its own
   *    5% below, so the ONE consumer that wanted a 5% blue still gets exactly that. */
  --paint-cyanotype:      #64B4FF;                    /* blueprint blue — the ruling of the paper */
  /* ⭐ ADDED 2026-08-28 (Captain-ruled), same reason and same convention as --paint-brass-light. */
  --paint-cyanotype-light: #7AC0FF;
  /* proto's drafting-grid major with THE ALPHA STRIPPED OUT. 🔑 A PAINT IS A PIGMENT; TRANSPARENCY
   * IS HOW A SURFACE *USES* IT. Storing rgba(42,78,104,.16) here would have made every future
   * opacity tweak a recolour. (MASTER SPEC §76.1) */
  --paint-graphite-blue: #2A4E68;
  /* 🆕 proto2's STAGE ACCENT, ADDED 2026-08-20 ON A CAPTAIN RULING. It is NOT our verdigris and it
   * is not meant to be: #79DEC7 is (121,222,199) against verdigris's (93,202,165) — paler, cooler,
   * and it is THE VALUE THE DONOR ACTUALLY USES on the surface we are porting.
   * ⛔ §82.6 PRESCRIBED DERIVING A LIGHT FROM --paint-verdigris-deep TO CLOSE A BRIGHTNESS GAP.
   *    THAT WAS WITHDRAWN (§82.15) ONCE THE GAP WAS MEASURED: donor +18 green lift, ours +33 — our
   *    light was nearly TWICE the donor's. 🔑 THE GOAL WAS NEVER "A CORRECTLY DERIVED GREEN", IT WAS
   *    "LOOKS LIKE proto2" — AND THE DONOR'S VALUE IS NOT AN APPROXIMATION OF THE TARGET, IT IS THE
   *    TARGET. L48 in its purest form: copy the donor, do not re-derive it.
   * ⭐ ADDED RATHER THAN MOVING --paint-verdigris, DELIBERATELY: verdigris has other consumers
   *    (--accent, --border, --hairline) and repointing it would have recoloured surfaces nobody
   *    ruled on. A NEW PAINT HAS A BLAST RADIUS OF EXACTLY ITS CONSUMERS. */
  --paint-seafoam:        #79DEC7;                    /* proto2's stage accent — (121,222,199) */
  /* 🆕 THE SPINE'S SECOND MOVEMENT COLOUR (§82.19, 2026-08-20). ⛔ ADDED BECAUSE WE OWN NO VIOLET
   * AT ALL — every other pillar tone maps onto a paint we already have, and this one had nowhere to
   * land. Value is the design file's own (`--test:#8178d7` in datumae_studio_framework_v13).
   * ⚠️ AND ITS NAME IN THE DONOR IS A TRAP WORTH RECORDING: `--test` reads as a DEBUG token and was
   *    ruled "do not port" on that basis. MEASURED: `.stage-label.test{color:var(--test)}` — it is
   *    the AUTHORED colour of pillar 02, and dropping it would have left that pillar unpainted and
   *    broken the spine gradient's second stop. THE NAME WAS A LEFTOVER FROM WHEN 02 WAS CALLED
   *    "TEST IT"; renamed here for what it IS, not what it was called. */
  --paint-amethyst:       #8178D7;                    /* the spine's second movement — (129,120,215) */
  --paint-inkwell:        #091221;                    /* the page field behind everything */

  /* ── ⚙️ ROLE · WHAT THE COLOUR IS FOR ───────────────────────────────────────────────────────
   * NEVER A BARE HEX. A role holds either a PAINT, or a stated derivation of EXACTLY ONE paint
   * (an alpha or a color-mix) — never a derivation of two, which would hide a blend nobody ruled.
   * 🔑 THE TEST: change one paint and every role deriving from it moves with it. */
  --accent:      var(--paint-verdigris);
  --accent-deep: var(--paint-verdigris-deep);
  /* A STRAIGHT PAINT READ — NO DERIVATION, SO NO @supports GUARD. var() is universally supported;
   * wrapping this one would mean it CEASES TO EXIST on a browser lacking color-mix(), which is the
   * opposite of what the guard is for. The four roles below are the derivations. */
  --accent-hover: var(--paint-verdigris-light);
  --bg:          var(--paint-inkwell);
  --text:        var(--paint-chalk);
  /* A DERIVATION, NOT A PIGMENT: muted text is chalk at 40%, so it must follow chalk. Written as
   * a hard-coded rgba() this role would silently keep its old colour on the day chalk changes —
   * which is precisely the class of lie this file exists to end.
   * ⚠️ THE LITERAL BELOW IS THE FALLBACK, NOT A SECOND SOURCE OF TRUTH: it is the same value the
   * derivation produces, spelled for an older reader. The upgrade lives in the @supports block at
   * the foot of this file — see the note there for why it CANNOT be written as two declarations. */
  /* ⬆️ RAISED 0.40 -> 0.55 (2026-08-16, MASTER SPEC ruling on the census). At 0.40 this role
   * measured 3.80:1 against the inkwell field — THE ROLE ITSELF WAS BELOW THE 4.5 FLOOR, on 709
   * read sites, and the lit surfaces of (C3) put a LIGHTER ground under it. 0.55 measures ~6.16:1
   * on the page field.
   * ⭐ THE TARGET IS 5.0:1, NOT 4.5:1 — A ROLE SPECIFIED *AT* ITS FLOOR IS A DEFECT WITH A DATE ON
   *    IT. Two sessions were spent on a paragraph sitting at 4.51 against a 4.5 floor.
   * ⚠️ CHOSEN FROM THE DISTRIBUTION, NOT FROM THE WORST CASE. Solving for the single darkest-text
   *    outlier demanded 0.79, which is not "muted" any more. Measured over 1098 muted runs on the
   *    lit ground: p50 0.49 · p90 0.50 · p95 0.51. At 0.55, 1092 of 1098 clear 4.5:1 and 1084 clear
   *    5.0:1; the six that do not are LOCAL surfaces carrying their own light or grey backgrounds
   *    (a brass card tier, two grey buttons, two step numerals) and are their own findings.
   *    🔑 A GLOBAL ROLE SET BY ITS WORST LOCAL CONSUMER STOPS BEING A ROLE. */
  --text-muted:  rgba(255, 255, 255, 0.55);
  --label:       var(--paint-brass);                  /* headings + mono kickers read this today */
  --debt:        var(--paint-red-lead);

  /* ── THE FOUR DERIVED ROLES ─────────────────────────────────────────────────────────────────
   * Each is EXACTLY ONE paint at an alpha. The literal here is the FALLBACK — the same value the
   * derivation produces, spelled for a reader without color-mix(); the derivation itself lives in
   * the @supports block at the foot of this file.
   * ⛔ THEY ARE *NOT* WRITTEN AS TWO ADJACENT DECLARATIONS, AND THAT IS MEASURED, NOT STYLISTIC —
   *    see the block at the foot. MASTER SPEC §69.4 / §76.2 / §76.3 authored the adjacent-pair
   *    form; it was STRUCK 2026-08-16 after measurement. THE CASCADE PROTECTS A DECLARATION THAT
   *    IS *INVALID*; IT CANNOT PROTECT ONE THAT IS *VALID UNTIL SUBSTITUTION*. */

  /* THE PANEL IS THE PAGE FIELD MADE TRANSLUCENT, so the body's light shows through it.
   * ⭐ THE LIFT COMES FROM THE LIGHT BENEATH, NOT FROM A LIGHTER PAINT. (§60.1 / §76.2) */
  --surface:     rgba(9, 18, 33, 0.88);      /* inkwell at 88% */
  --border:      rgba(93, 202, 165, 0.18);   /* verdigris at 18% — the panel's own edge */
  /* A DIFFERENT VALUE FROM --border ON PURPOSE (6% vs 18%): this is the inset top highlight,
   * `box-shadow: inset 0 1px 0 var(--hairline)`. Reusing --border here loses the effect. (§76.3) */
  --hairline:    rgba(93, 202, 165, 0.06);   /* verdigris at 6% */

  /* ── 🥁 THE VEILS · CHROME LAID OVER THE PAGE FIELD ────────────────────────────────────────────
   * The nav, the footer, the privacy banner, the two HUDs and the requirements panel all paint the
   * SAME colour as the page field at a near-opaque alpha — they are the field made solid enough to
   * sit on top of itself. Until now every one of them spelled it as a raw rgba(9,18,33,0.9x), which
   * meant THE PAINT COULD NOT REACH THEM: measured 2026-08-29 by flipping all 14 paints to a light
   * palette, these seven surfaces were the entire "stayed dark" list.
   * ⚠️ FIVE ALPHAS ARE PRESERVED BYTE-EXACT AND THAT IS DELIBERATE. 0.92 / 0.95 / 0.96 / 0.97 /
   *    0.99 for one job looks like drift, and it probably is — but MERGING THEM MOVES PIXELS, and
   *    this commit's whole claim is that it moves none. They are named by STRENGTH rather than by
   *    consumer precisely so the drift stays legible: a role named for its consumer would hide the
   *    fact that five of them do one thing. Whether they collapse is the Architect's ruling, and it
   *    is a separate commit with its own before/after.
   * 🔑 NAMED FOR WHAT THEY DO (§67.1): a veil is chrome you can almost see the field through. */
  --veil-92:     rgba(9, 18, 33, 0.92);      /* inkwell at 92% — the want-face HUD dash */
  --veil-95:     rgba(9, 18, 33, 0.95);      /* inkwell at 95% — the tension HUD */
  --veil-96:     rgba(9, 18, 33, 0.96);      /* inkwell at 96% — the site nav, the requirements panel */
  --veil-97:     rgba(9, 18, 33, 0.97);      /* inkwell at 97% — the disclosure footer, the privacy banner */
  --veil-99:     rgba(9, 18, 33, 0.99);      /* inkwell at 99% — the nav's scrolled state */

  /* THE TWO GRID FREQUENCIES. 🔑 THE 4:1 RATIO IS WHAT READS AS DRAFTING PAPER, NOT THE HUE —
   * so the minor stays CYANOTYPE (our blueprint blue) rather than taking proto's accent. */
  /* ⚠️ NO LONGER `var(--paint-cyanotype)` BARE — the paint went opaque above, so the 5% that used
   * to ride inside the pigment is now stated HERE, where the surface decides it. THE RESOLVED
   * COLOUR IS UNCHANGED: #64B4FF is rgb(100,180,255), so this is the same rgba() it always was. */
  --grid-line:   rgba(100, 180, 255, 0.05); /* cyanotype at 5% — the 19px MINOR, value unmoved */
  --grid-major:  rgba(42, 78, 104, 0.16);    /* graphite blue at 16% — the 76px MAJOR */

  /* ── 💡 THE TWO LIGHTS OVER THE DRAFTING TABLE ─────────────────────────────────────────────────
   * ⭐ NAMED FOR WHAT THEY DO, NOT WHAT COLOUR THEY ARE (§67.1). KEY and FILL are the actual
   *    vocabulary for two lights over a table, and they SURVIVE A RECOLOUR — which a name like
   *    --teal-glow would not.
   * ⛔ NO NEW PAINT WAS CREATED. proto's raw teal rgba(60,145,131,.18) and blue rgba(73,110,180,.14)
   *    are REJECTED (§79.3): each role is a derivation of exactly ONE paint we already own (§68.5).
   * ⚠️ SO THESE ARE BRIGHTER AND MORE SATURATED THAN THE DONOR'S, DELIBERATELY AND MEASURABLY: our
   *    verdigris is (93,202,165) against proto's (60,145,131), our cyanotype (100,180,255) against
   *    its (73,110,180). At the same alpha the key lands ~(6,10,6) hotter and the fill ~(4,10,11).
   *    THAT IS THE RULED SUBSTITUTION, NOT A DRIFT — recorded so nobody "fixes" it back toward proto.
   * ⛔ THE GEOMETRY IS THE DONOR'S AND IS *NOT* INVENTED HERE. Position and extent live at the
   *    consuming surface (studio.html body), taken from proto.html:48-49 — 70%/15% out to 24%, and
   *    20%/80% out to 22%. §79.3 authored colour, alpha and position and was silent on extent;
   *    THAT HOLE WAS CLOSED BY MEASURING THE DONOR, NOT BY PICKING A NUMBER (L47/L48).
   * ⛔ proto's THIRD body layer — a linear-gradient field #040a12->#07101b->#091220 — IS NOT PORTED.
   *    It is a distinct darker stage tone, it is the Architect's to author, and it gets its own
   *    commit. It does not ride in behind a mechanism fix. (§81.7) */
  /* ⛔⛔ --light-key IS RETIRED, NOT MOVED, AND THIS BLANK IS THE POINT (§82.15, 2026-08-20).
   * IT WAS A *GLOBAL* LIGHT ON `body`, AND A GLOBAL LIGHT IS THE DEFECT THIS COMMIT REMOVES.
   * MEASURED: with `--stage-base` on `.canvas-wrapper` above it, the key delivered d=(2,3,3) at its
   * own centre against an authored (15,33,24) — 12% transmission. `dffdecd` smothered it and three
   * separate proofs (profile 4/4, CSSOM 10/10, a 951,717px differential) were all blind, because
   * every one was scoped to the STAGE's own variable and none to the LIGHT underneath it.
   * 🔑🔑 A LAYER ORDER SPLIT ACROSS TWO ELEMENTS IS NOT A LAYER ORDER; IT IS A HOPE. proto2 keeps
   *    light and base in ONE list on ONE element, so the order cannot be broken by anything.
   * ⇒ THE STAGE NOW LIGHTS ITSELF (--stage-key below). A role with no consumer is a name waiting to
   *    become a lie (§76.3), so this one is gone rather than left latent. */

  /* ── 🎭 THE STAGE — PORTED AS ONE OBJECT FROM proto2 `.right` (§82.15, 2026-08-20) ─────────────
   * ⛔⛔ THE PORT UNIT IS THE SURFACE, NOT THE TOKEN. Five days were spent decomposing this donor
   *    into tokens and re-attaching them to DIFFERENT elements — the light to `body`, the base to
   *    `.canvas-wrapper` — which turned a declared order into a stacking accident and made every
   *    subsequent problem a transmission problem. THE VALUES WERE NEVER MISSING; WE HAD TAKEN APART
   *    THE FILE THAT CONTAINED THEM.
   * ⭐ EVERY COLOUR BELOW IS proto2's, VERBATIM. Nothing is derived, nothing is authored by us.
   *    GEOMETRY (position + extent) lives at the consuming surface in studio.html, as it already
   *    did — these hold COLOUR only.
   * ⭐⭐ AND THEY ARE SPELLED THROUGH THE PALETTE RATHER THAN AS proto2's LITERALS, ON A CAPTAIN
   *    RULING, BECAUSE THE DONOR'S OWN SPELLING IS ITS ONE REAL FLAW: MEASURED, proto2 writes its
   *    teal as a hard-coded triple 27 TIMES and reads `var(--teal)` only 9 — so changing --teal in
   *    ITS :root would recolour a quarter of the page and leave the rest. Copying that would have
   *    imported a slow re-skin into a 1.68MB SACRED file.
   *    🔑 THE PIXELS ARE IDENTICAL EITHER WAY AND THAT IS PROVEN, NOT ASSUMED (literal-vs-token
   *      differential, reported with this commit). THE VALUE IS THE DONOR'S; ONLY THE SPELLING IS
   *      OURS. ⇒ ONE EDIT TO --paint-seafoam NOW MOVES FOUR LAYERS AT ONCE. */
  --stage-key:      rgba(121, 222, 199, 0.085);  /* seafoam 8.5% — the stage's own key light      */
  --stage-glow:     rgba(121, 222, 199, 0.055);  /* seafoam 5.5% — the broad centre glow (::before)*/
  --stage-rim:      rgba(121, 222, 199, 0.035);  /* seafoam 3.5% — the 1px inset ring             */
  --stage-grid-minor: rgba(121, 222, 199, 0.045); /* seafoam 4.5% — the 19px MINOR, stage only    */
  /* ⛔ THE COOL FILL KEEPS A LITERAL AND I AM NAMING THAT RATHER THAN HIDING IT. (73,110,180) has
   * no paint in our palette, and exactly ONE new paint was ruled (seafoam). Inventing a second
   * would be authoring a palette entry nobody approved (L47). It follows the same precedent as
   * --stage-base's literals below. ⚠️ CONSEQUENCE, STATED: changing the GREEN costs one edit;
   * changing THIS BLUE still costs a literal edit. That is a known limit, not an oversight. */
  --stage-fill:     rgba(73, 110, 180, 0.075);   /* proto2's cool counter-light, lower left        */
  /* A COMPLETE RAMP, NOT A STOP (§81.8) — proto2 `.right::before`'s second layer: a top sheen and
   * a bottom shade that give the stage its curvature. */
  --stage-sheen:    linear-gradient(180deg, rgba(255,255,255,0.01), transparent 16%, transparent 82%, rgba(0,0,0,0.14));

  /* ── 🖊️ THE PANEL — proto2 `.left`, PORTED AS ONE OBJECT (§82.16, 2026-08-20) ──────────────────
   * Same rule as the stage: the donor's values verbatim, our spelling, geometry at the surface.
   * ⭐⭐ A MEASURED FINDING ABOUT THE DONOR, WORTH RECORDING: `.left` AND `.right` USE THE SAME TWO
   *    LIGHT COLOURS AT THE SAME TWO ALPHAS — seafoam .055 and the cool blue .075 appear on BOTH
   *    surfaces. proto2 has TWO lights and puts them on every surface that needs lighting, rather
   *    than one global light seen through things. That is the same insight that fixed the stage,
   *    visible from the other side.
   * ⛔ THEY ARE STILL DECLARED SEPARATELY FROM THE --stage-* PAIR, ON PURPOSE. Identical VALUE is
   *    not identical MEANING: EACH SURFACE OWNS ITS OWN STACK, so re-lighting the panel must not
   *    silently re-light the stage. Collapsing them would re-create the coupling this whole arc
   *    exists to remove — one name owning a position on two different elements. */
  --panel-key:      rgba(121, 222, 199, 0.055);  /* seafoam 5.5% — panel key light, upper left     */
  --panel-fill:     rgba(73, 110, 180, 0.075);   /* the cool counter-light, lower left (literal:   */
                                                 /* no paint owns (73,110,180) — see --stage-fill) */
  --panel-grid:     rgba(42, 78, 104, 0.08);     /* graphite blue 8% — the panel's own faint grid  */
  --panel-edge:     rgba(121, 222, 199, 0.10);   /* seafoam 10% — the rim between panel and stage  */
  --panel-base:     linear-gradient(180deg, rgba(4,10,18,0.97), rgba(6,13,24,0.94));
  /* A COMPLETE RAMP (§81.8): the donor fades its panel grid out toward the bottom rather than
     ruling the whole panel, so the grid reads as drafting paper near the title and disappears
     behind the content. */
  --panel-grid-mask: linear-gradient(180deg, rgba(0,0,0,0.72), rgba(0,0,0,0.24) 70%, transparent);

  /* ── 🧭 THE FOUR MOVEMENT TONES (§82.19) — THE SPINE'S GRADIENT, BY POSITION ────────────────
   * teal -> violet -> blue -> gold ACROSS THE FOUR MOVEMENTS (§82.2), so the gradient IS the
   * formula's grouping. ⛔ THE TONE BELONGS TO THE POSITION, NOT TO THE LABEL — which is why the
   * Captain's 02/03 label swap left these untouched. The markup carries `data-tone` and the CSS
   * reads it; a colour inlined beside a label would have travelled with it.
   * ⚠️ ~~03 AND 04 REUSE PAINTS WE ALREADY OWN RATHER THAN IMPORTING THE DESIGN FILE'S
   *    NEAR-DUPLICATES... if the exact screenshot values are wanted, that is two more paints and one
   *    ruling — it is not a thing to discover later.~~ STRUCK 2026-08-28, NOT DELETED: THE EXACT
   *    SCREENSHOT VALUES WERE WANTED. The Captain ruled for the brighter blue and gold on LEGIBILITY
   *    grounds, so 03 and 04 now point at --paint-cyanotype-light and --paint-brass-light.
   *    ⭐⭐ THE PRIOR NOTE IS WHY THIS WAS ONE RULING INSTEAD OF AN ARCHAEOLOGY EXPEDITION: it priced
   *    the decision ("two more paints and one ruling") months before anyone asked, and it was right
   *    to the paint. A DOCUMENTED NON-DECISION IS AN ASSET; AN UNDOCUMENTED ONE IS A DRIFT NOBODY
   *    CAN DATE.
   *    ⛔ AND IT CLOSED A FORK THAT HAD ALREADY OPENED. The entry overlay shipped 2026-08-27 with its
   *    own scoped hex, so BUILD/TEST matched the movement column while SHAPE/LIVE did not — two
   *    colours for one pillar on one page. Repointing here is what makes the two surfaces agree,
   *    which is the POINT of the change, not a side effect of it. */
  --movement-1:  var(--paint-seafoam);
  --movement-2:  var(--paint-amethyst);
  --movement-3:  var(--paint-cyanotype-light);
  --movement-4:  var(--paint-brass-light);

  /* ⛔ --grid-line IS DELIBERATELY *NOT* REPOINTED AT SEAFOAM, AND THIS IS A RULING COLLISION I AM
   * RESOLVING IN THE OPEN RATHER THAN SILENTLY. proto2's minor grid is teal at 4.5%; ours is
   * cyanotype at 5%, and §76 ruled that ON PURPOSE ("the 4:1 RATIO is what reads as drafting paper,
   * NOT the hue"). --grid-line also has 22 consumer sites across 10 files — far beyond this stage.
   * 🔑 "EACH SURFACE OWNS ITS OWN STACK" CUTS BOTH WAYS: the stage takes the donor's minor via
   *    --stage-grid-minor, and every OTHER surface keeps the grid §76 ruled for it. A site-wide
   *    recolour smuggled in behind a stage port would be exactly the blast radius this arc exists
   *    to stop. ⭐ --grid-major needs no new token at all: it ALREADY resolves to rgba(42,78,104,
   *    0.16), which is proto2's major to the digit. The donor and the palette already agreed. */

  /* ── 🎭 THE STAGE GROUND (§82.7, 2026-08-19) ──────────────────────────────────────────────────
   * ⛔⛔ THESE TWO ARE AUTHORED AS A PAIR AND MUST STAY ONE. MEASURED: proto2's RENDERED ground is
   *    DARKER than its own declared stops, because the vignette sits over them. Shipping the
   *    gradient alone gets the top right and leaves the edges bright — a half-port that would look
   *    like a failed match rather than a missing layer.
   *    🔑 THE VIGNETTE IS PART OF THE GROUND, NOT DECORATION.
   * ⚠️ WHY A WHOLE GRADIENT IS ALLOWED TO BE A TOKEN HERE, WHEN §81.8 FORBADE ROLES AS STOPS:
   *    §81.8's rule is "A ROLE HOLDS ONE VALUE; A STOP IS HALF A RAMP" — it bans putting a role
   *    INTO one stop of someone else's ramp. These hold a COMPLETE ramp, authored as a ramp, which
   *    is precisely the remedy that rule prescribed. Nothing here is half of anything.
   * ⛔ NOT SITE-WIDE. The Studio is the only consumer; every other page keeps the flat field. A
   *    graded field on a 13-viewport page is lit for two screens and dark for twelve (F4).
   * ⚖️ ACCEPTANCE IS THE PROFILE, NOT THE DECLARATION — `_c3_light_probe.mjs --mode=profile
   *    --target=proto2` must land within ±2 per channel at y=20/250/550/860. The tolerance is RULED
   *    (Architect), and the probe prints the real deltas even on green so nothing drifts inside it. */
  --stage-field:    linear-gradient(180deg, #040a12 0%, #07101b 24%, #091220 100%);
  --stage-vignette: radial-gradient(circle at 50% 50%, transparent 54%, rgba(2,8,15,0.10) 78%, rgba(2,8,15,0.28) 100%);
  /* ⛔⛔ THE STAGE'S OWN BASE — AND IT IS NOT THE FIELD. THIS WAS THE MISSING LAYER (§82.8).
   * MEASURED: proto2's stage darkness does NOT come from its field. `.app` carries the graded field
   * (which `--stage-field` above ports), and `.right` — the blueprint stage — carries a SEPARATE
   * translucent dark base ON TOP of it. We were looking through a transparent canvas down to the
   * field; proto2 looks at a stack. Porting the field alone got us to d=(2,5,8); this closes it.
   * ⛔ THIS DOES NOT REVERT `85e21bf`, AND THE DISTINCTION IS THE WHOLE POINT. That commit removed
   *    `.canvas-wrapper`'s opaque fill because the fill was a DUPLICATE of the field behind it —
   *    a deletion, correctly reasoned, and its message stays true. THIS ADDS A DIFFERENT THING AT
   *    THE SAME ADDRESS: a distinct, darker, TRANSLUCENT layer the field does not provide.
   *    🔑 REMOVING A DUPLICATE WAS A DELETION. ADDING A NON-DUPLICATE IS A DECISION. */
  --stage-base:     linear-gradient(180deg, rgba(4,10,18,0.88), rgba(8,16,28,0.94));

  /* ⛔⛔ --light-fill IS AUTHORED AND DELIBERATELY ABSENT. THIS IS AN HONEST BLANK, NOT AN OVERSIGHT.
   * §79.3 authored it — cyanotype at 14%, a cool fill at 20%/80% — and it is NOT DECLARED HERE
   * because it was MEASURED AND IT ILLUMINATES NOTHING. On the entered Studio at 1440x900 its own
   * centre reads d=(0,0,0). The stack at that point, innermost first:
   *     #disclosure-footer  rgba(9,18,33,0.97)
   *     .drafting-panel     rgb(9,18,33)      <- FULLY OPAQUE, and F1 already named it as still
   *     #studio-layout      transparent          blocking the light after the ground commit
   *     body                rgb(9,18,33)
   * 🔑 THE AUTHORING FAULT, RECORDED BECAUSE IT GENERALISES: A POSITION IS NOT A VALUE — IT IS A
   *    CLAIM ABOUT WHAT SITS AT THAT POSITION. 20%/80% came from proto, whose sidebar is
   *    rgba(4,10,18,.96)->.92 and therefore leaks 4-8%. OURS IS rgb(). The coordinate was ported
   *    and its premise was left behind.
   * ⛔ AND IT IS NOT DECLARED-BUT-UNUSED ON PURPOSE: A ROLE WITH NO CONSUMER IS A NAME WAITING TO
   *    BECOME A LIE (§76.3, the same rule that keeps --info out of this file). Shipping the token
   *    while knowing it lights nothing would put a dead role in the palette.
   * ⚖️ HELD, NOT KILLED. It returns when the Architect authors a POSITION against the measured lit
   *    ground — not moved by a wirer picking a coordinate, which would be the same fault again.
   * ⚠️ THE CYANOTYPE REPAIR ABOVE SHIPS ANYWAY AND ITS BENEFICIARY IS THIS HELD TOKEN: 14% derived
   *    from a 5%-alpha paint compounds to 0.00714 (§80.4). The hazard is real and the repair is
   *    correct whether or not the fill is placed today — but NOBODY SHOULD READ THE REPAIR AS
   *    EVIDENCE THAT THE FILL IS LIVE. IT IS NOT. */

  /* ── ✍️ TYPE ────────────────────────────────────────────────────────────────────────────────
   * RELOCATED, NOT INVENTED. These two shared tokens moved here with the :root block they lived
   * in; styles/typography.css still reads --font-serif for `body`, so leaving them behind would
   * have broken it. Georgia is in the stack deliberately — it degrades gracefully where a bare
   * `serif` falls to the browser default. */
  --font-serif: 'Fraunces', Georgia, serif;
  --font-mono:  'DM Mono', monospace;

  /* LEGACY NAMES — read-only compatibility. New code uses the ROLE tokens above. Retired page-by-page; see MASTER SPEC §67. */
  --teal:       var(--accent-deep);
  --teal-mid:   var(--accent);
  --gold:       var(--label);
  --gold-dark:  var(--paint-brass-deep);
  --danger-red: var(--debt);
  --bg-navy:    var(--bg);
  --white:      var(--text);
  --muted:      var(--text-muted);
}

/* ── THE DERIVATION UPGRADE, GUARDED ──────────────────────────────────────────────────────────
 * Where color-mix() is understood, --text-muted becomes a real derivation of the chalk paint, so
 * it moves when chalk moves. Where it is not, the literal above stands and the page renders
 * exactly what it renders today.
 *
 * ⛔⛔ THIS CANNOT BE WRITTEN AS TWO DECLARATIONS, AND THE MEASUREMENT IS WHY. For a normal
 * property the cascade drops a declaration the parser cannot understand and the earlier one
 * survives. A CUSTOM PROPERTY ACCEPTS ALMOST ANY TOKEN SEQUENCE AS VALID AT PARSE TIME, so the
 * LATER declaration wins even when the function inside it is unknown, and the failure surfaces
 * later at substitution as "invalid at computed-value time" — which falls back to inherited or
 * initial, NEVER to the earlier declaration.
 *   MEASURED, with an unknown function standing in for an unsupported one:
 *     two declarations -> painted rgba(0, 0, 0, 0)          — TRANSPARENT. Muted text INVISIBLE.
 *     @supports guard  -> painted rgba(255, 255, 255, 0.4)  — exactly today's rendering.
 * 🔑 THE FALLBACK IDIOM EVERY CSS AUTHOR KNOWS IS INERT ON CUSTOM PROPERTIES, AND IT FAILS WORSE
 *    THAN THE THING IT WAS MEANT TO PREVENT. @supports is evaluated at PARSE time, so an
 *    unsupporting browser never enters the block at all.
 * ⚠️ And the proof that missed this first time round was byte-identical PNGs — painted in a
 *    browser that HAS color-mix. A PROOF INHERITS THE CAPABILITIES OF THE THING THAT RAN IT. */
@supports (color: color-mix(in srgb, white 40%, transparent)) {
  :root {
    --text-muted: color-mix(in srgb, var(--paint-chalk) 55%, transparent);
    /* THE SAME GUARD COVERS ALL FIVE — one feature, one test. Re-measured 2026-08-16 with an
     * unknown function standing in for an unsupported color-mix(), because we cannot install a
     * pre-2023 browser:
     *     two adjacent declarations -> painted rgba(0, 0, 0, 0)      TRANSPARENT
     *     @supports guard           -> painted rgba(9, 18, 33, 0.88) today's pixel
     * ⛔ ON THE ADJACENT-PAIR FORM THE DRAFTING PANEL WOULD HAVE BEEN *INVISIBLE*, NOT merely
     *    mis-tinted — a silent failure strictly worse than the bug the fallback was meant to stop. */
    --surface:    color-mix(in srgb, var(--paint-inkwell) 88%, transparent);
    --border:     color-mix(in srgb, var(--paint-verdigris) 18%, transparent);
    --hairline:   color-mix(in srgb, var(--paint-verdigris) 6%, transparent);
    /* THE VEILS JOIN THE DERIVATIONS — and this block is what makes them mean anything. Without it
     * the five literals above are the same hardcoded rgba() they replaced, just wearing token names,
     * and --paint-inkwell would still move NOTHING on the nav, the footer or the HUDs.
     * 🔑 REGISTRATION IS THE DECLARATION; WIRING IS THIS. (The same sentence the stage layers earned.) */
    --veil-92:    color-mix(in srgb, var(--paint-inkwell) 92%, transparent);
    --veil-95:    color-mix(in srgb, var(--paint-inkwell) 95%, transparent);
    --veil-96:    color-mix(in srgb, var(--paint-inkwell) 96%, transparent);
    --veil-97:    color-mix(in srgb, var(--paint-inkwell) 97%, transparent);
    --veil-99:    color-mix(in srgb, var(--paint-inkwell) 99%, transparent);
    --grid-major: color-mix(in srgb, var(--paint-graphite-blue) 16%, transparent);
    /* ⚠️ --grid-line JOINS THE DERIVATIONS AND IT IS NOT A PURE NO-OP — SAID PLAINLY BECAUSE
     * "IMPERCEPTIBLE" IS A JUDGEMENT AND "NO-OP" IS A MEASUREMENT, AND THIS ARC KEEPS THEM APART.
     * The RESOLVED COLOUR is unchanged: #64B4FF is exactly rgb(100,180,255), so this derivation and
     * the rgba() literal above name the SAME colour. What moves is the COMPOSITING PATH — chromium
     * resolves color-mix() to color(srgb ...) and rounds one unit differently on a 5%-alpha
     * hairline: rgb(14,26,44) -> rgb(14,26,43), off-line pixels identical (§80.4, ratified).
     * 🔑 TWO DIFFERENT MEASURANDS, BOTH TRUE: the VALUE is invariant, the PIXEL moves by 1/255 on
     *    one channel. Anyone who states only one of those has stated it wrong. */
    --grid-line:  color-mix(in srgb, var(--paint-cyanotype) 5%, transparent);
    /* 🎭 THE STAGE'S FOUR SEAFOAM LAYERS. ⛔ THIS BLOCK IS WHAT MAKES THE PALETTE SPELLING REAL —
       without it the :root literals above are just proto2's numbers wearing token names, and
       --paint-seafoam would move NOTHING. 🔑 THE CAPTAIN'S REQUIREMENT ("the next green costs one
       edit") IS SATISFIED HERE, NOT ABOVE. Registration is the declaration; WIRING is this. */
    --stage-key:        color-mix(in srgb, var(--paint-seafoam) 8.5%, transparent);
    --stage-glow:       color-mix(in srgb, var(--paint-seafoam) 5.5%, transparent);
    --stage-rim:        color-mix(in srgb, var(--paint-seafoam) 3.5%, transparent);
    --stage-grid-minor: color-mix(in srgb, var(--paint-seafoam) 4.5%, transparent);
    /* 🖊️ THE PANEL'S THREE DERIVED LAYERS (§82.16). --panel-fill is absent for the same reason
       --stage-fill is: no paint owns (73,110,180) and exactly one new paint was ruled. */
    --panel-key:  color-mix(in srgb, var(--paint-seafoam) 5.5%, transparent);
    --panel-edge: color-mix(in srgb, var(--paint-seafoam) 10%, transparent);
    --panel-grid: color-mix(in srgb, var(--paint-graphite-blue) 8%, transparent);
    /* ⛔ --stage-fill IS ABSENT HERE ON PURPOSE — it has no paint to derive from (see its note
       above). A derivation of a paint we do not own would be a blend nobody ruled (§68.5). */
    /* --light-key is GONE, not merely underived — it lost its consumer when the key became the
       stage's own light. See the retirement note beside its old declaration. */
  }
}

/* ── OMITTED ON PURPOSE — NO CONSUMER EXISTS ──────────────────────────────────────────────────
 * --info
 * ⛔ A ROLE WITH NO CONSUMER IS A NAME WAITING TO BECOME A LIE. No surface needs an informational
 *    tone: cyanotype already has a job via --grid-line. (MASTER SPEC §76.3)
 *
 * ✅ THE FIVE HONEST BLANKS ARE CLOSED. --paint-verdigris-light · --paint-graphite-blue ·
 *    --accent-hover · --surface · --border were absent from 2026-08-16 until the design existed;
 *    they were AUTHORED in MASTER SPEC Part 76 and landed here with their derivations stated.
 *    --hairline joined them for the reason recorded at its declaration.
 * ⭐ THE RULE THAT HELD THE LINE, AND IT WORKED: A TOKEN FILE MAY ONLY CONTAIN VALUES THAT ALREADY
 *    EXIST. AN EMPTY SLOT IS AN HONEST BLANK *AND* A WORK ITEM THAT CANNOT BE LOST — the arc could
 *    not proceed until somebody ruled them, which is exactly what an honest blank is for. */
