:root {
  /* interference ramp — DARK (Aurora) */
  --c1:#F06BB7; --c2:#8F6CF0; --c3:#5E7CFF; --c4:#3FC6E0; --c5:#3EDBA8;
  /* ground ramp — depth by plane, never shadow: inset < ground < surface < raised */
  --ground:#0F0D13; --surface:#15121B; --raised:#1C1826; --inset:#0A090E;
  /* --ground-lift — CANDIDATE, landed 2026-07-31. The ONE new plane value, a half-step bisecting
     --ground -> --surface in OKLab. Authored because a real job had no plane: the operator shell's
     turn band sat on the same value as chrome while its own ruling forbids that. Measured: one rung
     at this joint is dL .0257 (Aurora) / .0241 (Feather); this half-step is dL .0116 / .0117 —
     agreeing across themes to .0001, which is what makes it a scale position rather than a nudge.
     THE STACK INVARIANT that keeps a half-step from becoming a fifth stratum: it never appears in
     one containment chain with BOTH its integer neighbours (max depth 4; the operator shell's real
     max is 3), so `nothing floats` is under-spent, not strained.
     Aaron ruled bisect-only over re-deriving the existing four (walk E1, 2026-07-31) — so the four
     above are UNTOUCHED and the six surfaces that vendor them see zero change.
     IT WAS SEEN BY EYE, 2026-09-19/20, and read as near-invisible: the turn-band render
     (turn-footer.md § Not reconciled) measured this half-step against --ground at reading distance
     and found it doing almost no work in Aurora — "the boundary is carried by the rule + the gap
     alone; it still counts, but the plane channel is doing almost nothing there." Aaron's redirect
     (batch-3 look 2, S2): "the stripe between turns one step stronger, dark theme only." Read here
     as ONE HALF-STEP MORE (the increment already in this token's own name, not a leap to --surface —
     merging the two would erase the band/plane distinction the token exists to carry): Aurora's dL
     .0116 doubles to dL .0231 (t .450 -> .902 on the ground->surface OKLab interpolation), landing
     one hex step below --surface at every channel — distinct, never equal. FEATHER IS HELD (Aaron's
     own word) — its dL stays .0117, UNTOUCHED below. CANDIDATE — the doubling is this seat's reading
     of "one step stronger", not a measured target; Aaron's eye on the re-render is what actually
     tests it (turns-are-countable-at-a-glance, wireframes/turn-footer.md). Derivation of record:
     operator-district/plane-ramp-rederivation.md; this retune: operator-district/PRIMITIVE-INDEX.md
     § THE TURN BAND. */
  --ground-lift:#14111A; /* CANDIDATE — Aurora only, S2 2026-09-20, dL .0231 from --ground (was .0116) */
  /* field-engine dark albedo floor — deep blue-violet, super-dark: makes magenta/teal pop by contrast
     ("colorless without being colorless"). spike-07 look-insight; Brand to ratify the exact tint + the
     anti-space-purple guard (must stay a super-dark FLOOR, never a purple field = reject #9). */
  --base-tint:#181B40;
  --ink:#EDEBF2; --ink-2:#C3BED0; --muted:#9B96A8; --hairline:#2A2536;
  /* --ink-2: lifted secondary ink for small labels that muted leaves under-legible */
  /* ── INK RAMP, stops 4 + 5 — CANDIDATE, pending Aaron's final hex (his production role, like --pr-*).
     --muted-2: the 4th LEGIBLE rung. Authored per-theme (NOT a color-mix) because its target is a
     CONTRAST RATIO, and a fixed mix % does not hold a ratio across two grounds — the same 86% mix
     lands 5.03:1 on Aurora and 4.51:1 on Feather. See operator-district/ink-ramp-4th-rung.md §3.
     Carries "present but below the reader's current altitude / focus": recessive and still READ.
     AA (>=4.5:1) on every plane it is permitted on — Aurora re-measured 2026-09-22 against the CURRENT
     ramp: ground 5.03 / band 4.86 / surface 4.82 / raised 4.53; Feather re-measured 2026-09-15 after
     its widen (see the Feather block): ground 4.86 / band 5.03 / surface 5.21 / raised 5.43.
     ⚠ THE AURORA ROW WAS ONE PLANE SHORT FOR EIGHT WEEKS, and the gap is the shape to watch rather
     than the number: this certification was verified 2026-07-29, --ground-lift landed 2026-07-31, and
     its Aurora value doubled again on 2026-09-20 (S2) — so a rung entered the ramp twice and the
     enumeration that certifies ink against planes trailed it both times, silently, because an
     enumeration says nothing about what it does not list. The band clears (4.86, +0.36), so nothing
     moves here; what changed is that the claim now covers the plane READ actually renders on. ADDING
     A PLANE RUNG OBLIGES A RE-MEASURE OF THIS LINE. Found by the 2026-09-22 plane-contrast sweep:
     workflows/ui-development/surfaces/operator-surface/steward-plane-contrast-2026-09-22.md.
     (Scope unchanged and still load-bearing: PLANES ONLY — the guarantee does not survive a TINT;
     operator-district/selection-scrollbar-and-tint-contrast.md § 4c/4d.)
     Hue + chroma held to --muted's family: an ink stop never separates on chroma (hue is spent on data).
     --ink-faint: the 5th stop, DERIVED (brand's own color-mix idiom), SUB-AA BY DESIGN and therefore
     DECORATIVE / DISABLED ONLY — never load-bearing text. The name deliberately BREAKS the -2 grammar:
     it is not another rung of the same kind, and the grammar break is the signal. Derived from --muted
     so it tracks any retune of it. Gate: no element with a semantic role resolves to --ink-faint. */
  --muted-2:#848090;
  --ink-faint:color-mix(in oklab,var(--muted) 55%,var(--ground));
  /* --rule-hover — a boundary the pointer is ON. PROMOTED 2026-08-02 from the operator district's
     --op-rule-hover, whose only consumer in the repo was .op-splitter:hover — and that consumer moved
     to brand core, so the alias would have been left with zero. Retiring it rather than keeping both
     is the --op-stroke-* move (walk E3): a district alias over a brand token of the same value is
     indirection without information. VALUE IS VERBATIM, not re-derived — Aaron's, unchanged.
     theme-derived: both inputs are themed, so parity holds THROUGH the derivation. */
  --rule-hover:color-mix(in oklab,var(--ink) 18%,var(--hairline)); /* theme-derived */
  /* ── SELECTION — RATIFIED 2026-07-31 against a render (walk D1). Aaron's value, his production role.
     TOKENIZED from the rule that had been inline at ::selection since the beginning. The rule was fine;
     the fact that it was ONLY a rule was not. A <link> carries rules; a vendored :root carries VALUES —
     so site/, museum/, field/ and proof-surface/ inherited ::selection for free while obsidian-theme,
     vscode-theme and the operator surface, which hand-carry a token block, inherited NOTHING and
     rendered the browser default. That is I11 one layer deeper than drift: a failure no --check could
     ever catch, because there is nothing to compare. A token can be emitted by a generator; a rule cannot.
     TWO FLOORS, and the old 34% only ever met one of them:
       --select-ink on the fill  >= 4.5:1  (selected text stays readable)   — 34% met this at ~10:1
       the fill vs --ground      >= 3:1    (1.4.11: selection reads as a STATE) — 34% was 1.58:1
     72% clears both in both themes, MEASURED IN A REAL COMPOSITOR (not modelled):
       Aurora  #6B51B2  separation 3.17:1  text 5.16:1
       Feather #907DE1  separation 3.02:1  text 5.37:1
     RETUNED TO 40% — 2026-09-15, Aaron's, asked twice on the installed operator surface (09-14:
     "the selected text should have better contrast. suggest lighter purple? … make sure aurora is
     updated too"; 09-15: "still medium purple background with black text. insufficient contrast").
     The 3:1 separation floor was the wrong instrument for THIS fill: a luminance ratio counts a
     saturated violet on a neutral ground as barely-there while the eye reads the hue shift
     unmistakably — and the 72% that satisfied the ratio put --ink on a mid-lightness field, the one
     place no ink reads well. Text is what a selection exists to keep legible, so the text floor
     governs and the fill is as light as the hue still carries. Re-measured, same compositor probe
     (Lab/vault-extension/scratchpad/probe-select-fraction.mjs):
       Aurora  #42336B  separation 1.77:1  text 9.25:1
       Feather #BBB1EA  separation 1.77:1  text 9.15:1
     DERIVED, not authored-per-theme — deliberately, and unlike --muted-2 above. This token's target is
     contrast FROM the ground it mixes with, where fraction and ground move together, so one fraction
     holds the ratio across both themes (measured within 0.02). --muted-2's target moves the other way,
     which is exactly why IT had to be authored twice. Same idiom, opposite reason.
     Probe: operator-district/selection-fill-probe/ — both themes, four fractions, live drag regions. */
  --select-fill:color-mix(in oklab,var(--c2) 40%,transparent);
  /* --select-ink looks like indirection without information and is not, for one reason: the three
     vendoring consumers cannot inherit the RULE, so they must re-author it, and a re-authored rule
     reaching for --ink directly re-spells the pairing instead of referencing it. The token is what makes
     the pair syncable AS A PAIR. If a future topology has every surface link this sheet, retire it. */
  --select-ink:var(--ink);
  /* ── SCROLLBAR — CANDIDATE values, RATIFIED mechanism (walk D6). STANDARD PROPERTIES ONLY, and the
     reason is layout rather than taste: ::-webkit-scrollbar{width} converts a macOS overlay scrollbar
     into a classic one that takes layout space, silently subtracting from measures the operator surface
     asserts as CONTRACTUAL. So the finer instrument is the one with the side effect, and coarse is the
     correct resolution for chrome anyway — the ramp is rationed and never fills chrome (thesis #1).
     Thumb is ink-family, NEVER accent: --c2 already has four consumers. */
  --scrollbar-thumb:color-mix(in oklab,var(--ink) 22%,transparent);
  --scrollbar-thumb-hover:color-mix(in oklab,var(--ink) 38%,transparent);
  --scrollbar-track:transparent;
  /* semantics — flat, never iridescent (Aurora values: brighter, read on dark) */
  --success:#3BC98A; --warn:#E8A93C; --error:#F0616B;
  /* ── PROOF DISTRICT (pr-) token group — CANDIDATE, pending Aaron's final hex (his production role).
     Authored HERE once (source-of-truth invariant); proof.css composes only var(--pr-*), zero hex.
     Method: dataviz palette (sequential=confidence · diverging=for/against · muted marks · WCAG-first).
     BID-Corvus direction: cool single-hue confidence ramp reads "measured/known"; for/against are two
     STRUCTURAL hues in tension (teal↔mauve), never good/bad / green↔red; K grounded-lit, U quiet-hollow. */
  /* sequential — confidence (low→high; low recedes toward paper "not-yet-proven", high earns .ring) */
  --pr-conf-1:#4A5170; --pr-conf-2:#515C87; --pr-conf-3:#586BA4; --pr-conf-4:#6183CE; --pr-conf-5:#7AA0FF;
  /* diverging — for/against margin (neutral midpoint = the paper's own ground = absence) */
  --pr-for:#48A6B4; --pr-against:#C77BAF;
  /* KIU evidence tiers — honesty encoded in weight (K grounded, I reasoned, U hollow/open) */
  --pr-tier-k:#4AC79A; --pr-tier-i:#7AA0FF; --pr-tier-u:#BFA06A;
  /* ── OPERATOR DISTRICT (op-) token group — CANDIDATE, landed 2026-07-31. Authored HERE once
     (source-of-truth invariant); the operator surface composes only var(--op-*) and authors zero hex.
     PURE ALIAS LAYER: every colour token resolves to an existing brand primitive or a color-mix of
     them — ZERO new base hexes here, so Feather comes free through the primitives' own remap. The
     ONLY per-theme override this group needs is the ghost-alpha triple at the bottom of [data-theme].
     BID-Corvus direction: on an instrument the colour budget is spent on DATA, so state (hover/
     active/selected) is ACHROMATIC (plane + rule weight + ink); --c2 is reserved system-wide for
     focus/selection (brand-core's own convention); the ramp fires nowhere on the working canvas.
     THEME-PARITY CLASSIFICATION, and it is why gate 1 accepts this group: an alias is NOT
     theme-invariant (its resolved value differs per theme) and NOT an orphan (it needs no override —
     the referent is already themed, so parity holds THROUGH the derivation). It is `theme-derived`,
     a CLAIM the gate verifies rather than an assertion it takes on trust. Non-colour rows below are
     genuinely theme-invariant and marked as such; the three real per-theme values carry no marker
     and appear in BOTH blocks. Derivations: operator-district/semantic-register.md §2g +
     plane-ramp-rederivation.md */
  /* planes — containment DEPTH (nesting), never zoom altitude. --op-band is the new half-step rung:
     the turn band had no plane of its own and was colliding with chrome. */
  --op-canvas:var(--ground); --op-plane:var(--surface); --op-plane-raised:var(--raised); --op-well:var(--inset); --op-band:var(--ground-lift); /* theme-derived */

  /* ── DATA-VIZ DISTRICT (dv-) token group — CANDIDATE, landed 2026-09-02 (Aaron approved
     at 30e9c4, no retune). Authored HERE once (source-of-truth invariant); dv.css composes
     only var(--dv-*) and authors zero hex, the --op-* discipline one district over.

     PURE ALIAS + DERIVATION LAYER: ZERO new base hexes. The categorical tier aliases ramp
     stops outright; the sequential tier is a color-mix of two already-themed primitives. So
     Feather comes free through the primitives' own remap and this group needs NO per-theme
     override at all — one fewer than --op-*, which still owes its ghost-alpha triple.

     CATEGORICAL — three stops, and the count is a measurement rather than a preference.
     All ten C(5,3) selections were scored in both themes against four floors (normal
     separation, deuteranopia, protanopia, chroma); exactly one clears all four. --c2/--c3
     collapse to 1.3 deltaE under deuteranopia, so every pair holding both is out first:
     five stops, three separable categorical slots. Reuse of a stop that already carries a
     chrome meaning is LEGAL by Aaron's D4 ruling (class-scoped, not global), which is what
     makes aliasing correct rather than merely convenient. Measurements + the acceptance
     test: dataviz-district/categorical-hue-candidates.md.

     TWO TIGHT MARGINS, APPROVED AS MEASURED — c1/c4 under deuteranopia at 6.3 (Aurora) /
     6.7 (Feather) against a 6.0 floor, and c4's Feather chroma at 0.101 against 0.10. A
     retune of --c1 or --c4 for reasons having nothing to do with data-viz can break a floor
     Aaron has approved, which is why dv-cat-separation is owed as a gate, not a note.

     SEQUENTIAL — magnitude, one hue's lightness steps. NOT the Interference Ramp: those are
     different objects sharing a word, and reading "the ramp is rationed" onto a 300-cell
     waffle would be correct-by-the-letter and wrong (DV-ESTABLISHMENT §3, encoding-contract
     §7.2). Derived toward --ground at the low end and --ink at the high end, so LOW VALUE
     SITS NEAR THE PAPER and high value sits far from it. The inversion between themes is
     therefore STRUCTURAL, not authored: Aurora runs dark->pale (OKLab L .225 -> .847),
     Feather runs pale->dark (.920 -> .396), because ground and ink swap. A copy-paste
     leaving both themes running the same direction is not expressible here. That is
     Contrast-Follows-The-Paper held by construction rather than by a gate.

     ABSENCE — an edge and no fill, deliberately. Absence-Is-Not-Zero requires the no-value
     mark to differ from a zero mark by a property OTHER than the magnitude channel; a fill
     token would supply exactly the affordance the principle refuses, so none exists.
     Derivations + the falsifiers: dataviz-district/DV-ESTABLISHMENT.md §3. */
  --dv-cat-1:var(--c1); --dv-cat-2:var(--c2); --dv-cat-3:var(--c4); /* theme-derived */
  --dv-seq-lo:color-mix(in oklab,var(--c4) 10%,var(--ground)); /* theme-derived */
  --dv-seq-hi:color-mix(in oklab,var(--c4) 55%,var(--ink)); /* theme-derived */
  /* e8cc52 (2026-09-29; PMO 2e9b9e94 + ab94c9d3, Aaron's direction e9250ba6) — CANDIDATE, in review.
     Absence's edge is the one mark of a no-value cell, so it takes the non-text floor (>= 3:1 vs the
     ground; WCAG 1.4.11): --muted-2 (the ramp's 4th legible rung, neutral) at 80%, measured 3.51:1
     Aurora / 3.31:1 Feather. A data cell's edge is a different job and keeps the old hairline value
     unchanged as --dv-cell-edge, so only absence moves. The track rises from --inset (1.03 / 1.09:1)
     to --muted-2 at 32%: 1.53:1 both themes, and the fill still reads >= 5.5:1 on it. */
  --dv-absent-edge:color-mix(in oklab,var(--muted-2) 80%,transparent); /* theme-derived */
  --dv-cell-edge:color-mix(in oklab,var(--ink) 16%,transparent); /* theme-derived */
  --dv-track:color-mix(in oklab,var(--muted-2) 32%,transparent); /* theme-derived */
  --op-rule:var(--hairline); --op-spine:var(--hairline); /* theme-derived */
  /* RECONCILED (S2, 2026-09-20): wireframes/turn-footer.md § Not mine, routed names "the rule's
     ink (D15's --ink-faint / --op-rule — the two names for one ruled ink are the Steward's to
     reconcile)". They are not two names for one ink — this line already says which: --op-rule IS
     D15's realized form ("the in-column divider D15 quieted", two sentences down), and --ink-faint
     is a DIFFERENT, sub-AA decorative role (--op-edge's, immediately below). The turn boundary's
     rule reads --op-rule; no new value, no rename — the ambiguity was in the wireframe's citation,
     not in canon. */
  /* --op-edge — the REGION boundary, and deliberately NOT --op-rule's value. Aaron ratified it by
     eye 2026-07-31 against plane-ramp-probe § 2b after the plane alone failed to separate chrome /
     band / read. A THIRD role, not an alias: --op-rule is the in-column divider D15 quieted, and
     --hairline measures 1.21-1.30:1 against the planes it would separate — barely stronger than the
     plane steps that already failed. --ink-faint is ~2x that (2.45-2.63:1) and still under the 3:1
     non-text reference, so "nothing floats" holds. Sub-AA is the POINT: a boundary that reads
     without becoming a drawn rule, which is --ink-faint's own declared decorative/non-text lane.
     NOT a fix for the span problem — a full rung still fails to read; that is lever 2 / E1, deferred
     by Aaron, re-opened in plane-ramp-rederivation.md § 9.2. Role name is provisional pending the
     Brand Identity Director seat (semantic-register.md § 5 reserves role naming).
     RETUNED 2026-09-29 (Aaron: "the border color to contrast less with its surface color so they
     stand out less"; his Figma pass, Corvus DS from-code 177:2166, set it to --hairline at 42%
     opacity), then dialled back up the same day ("the panes are barely visible … maybe not as
     contrasty as it was but not quite this flat"): --muted at 25% over the ground, ~1.25-1.6:1
     against the planes — about half of --ink-faint's 2.3-2.7:1, and one step above --op-rule's
     hairline, so the seam order edge > rule holds by value again (BAND 2/5 gates it; the full
     --hairline was tried first and collapsed the two). CANDIDATE — Aaron's value. */
  --op-edge:color-mix(in oklab,var(--muted) 25%,var(--ground)); /* theme-derived */
  /* ink — 5 stops. --op-ink-below is the 4th LEGIBLE rung (AA in both themes on canvas/plane/raised;
     NOT permitted on --op-well). --op-ink-faint is sub-AA BY DESIGN: decorative/disabled only. */
  --op-ink:var(--ink); --op-ink-2:var(--ink-2); --op-ink-muted:var(--muted); --op-ink-below:var(--muted-2); --op-ink-faint:var(--ink-faint); /* theme-derived */
  /* source-honesty (operator-surface C2) — confidence rides DASH + WEIGHT + ALPHA, never hue. Dash is
     primary (it survives forced-colors, print and greyscale); alpha only reinforces. EDGE-carried. */
  --op-dash-solid:none; --op-dash-long:6 3; --op-dash-short:2 5; /* theme-invariant */
  --op-src-attested-dash:var(--op-dash-solid); --op-src-derived-dash:var(--op-dash-long); --op-src-inferred-dash:var(--op-dash-short); /* theme-invariant */
  --op-src-attested-w:var(--stroke-bold); --op-src-derived-w:var(--stroke-regular); --op-src-inferred-w:var(--stroke-regular); --op-src-attested-alpha:1; /* theme-invariant */
  /* the ghost alphas — the ONLY genuinely per-theme values in this group. A .45 ghost reads as
     RECEDING on Aurora and as BROKEN/half-loaded on Feather, so both appear in [data-theme] too. */
  --op-src-derived-alpha:.72; --op-src-inferred-alpha:.45;
  /* move-type data channels — six, FLAT, never the gradient. --c2 is ABSENT by design (reserved for
     focus/selection). --op-move-event aliasing --warn is the ONE sanctioned move-type/status rhyme. */
  --op-move-decision:var(--c3); --op-move-branch:var(--c1); --op-move-verdict:var(--c4); --op-move-output:var(--c5); --op-move-event:var(--warn); --op-move-noise:var(--muted); /* theme-derived */
  /* interactive states — ACHROMATIC by district rule. Focus is the one inherited exception. */
  /* --op-rule-hover RETIRED 2026-08-02 into brand core's --rule-hover (same value, same role) when its
     one consumer, .op-splitter:hover, was promoted. --op-rule-active is UNCONSUMED as of that date and
     is left in place deliberately: deleting a district token with a recorded role is a district
     cleanup, not a side effect of a brand-core promotion. Surfaced to Aaron, not decided here. */
  --op-rule-active:color-mix(in oklab,var(--ink) 34%,var(--hairline)); /* theme-derived */
  --op-plane-hover:var(--raised); --op-focus:var(--c2); --op-select-fill:color-mix(in oklab,var(--c2) 14%,transparent); --op-ink-disabled:var(--ink-faint); /* theme-derived */
  /* --op-on-focus — INK for a label set ON the --op-focus fill (e55ad7, 2026-09-29; PMO 1164d64e + 199a372a).
     The armed Send used --op-well, a GROUND token, as its label ink: the pair cleared AA by 0.11 in
     Feather (4.61:1, mark-contrast measured), but no pair table could see it, because nobody enumerates
     "a ground used as ink on one state". A role token names the relation instead. NO NEW VALUE: it
     aliases a plane per theme — the darkest in Aurora (--inset, 5.26:1 on --c2, unchanged) and the
     lightest in Feather (--raised #FFF, 5.62:1 on --c2) — so it is a real per-theme value and appears
     in BOTH blocks, no marker. Gate: op-no-ground-as-ink (qa/check.mjs) + the armed state in
     operator-district/mark-contrast.json. */
  --op-on-focus:var(--inset);
  /* --op-hover-tint — the ONE written exception to "hover is achromatic" (semantic-register § 2e,
     amended 2026-09-16): where the plane rung has no headroom — a hover inside an object that already
     rests on the ramp's ceiling, Feather's #FFF on #FFF — a hover may wear the focus hue at a fixed
     low mix. The rail tab is its first and only consumer. CANDIDATE 8%, Aaron's to tune (digest #2);
     --op-select-fill is the same idiom at 14%, so hover < selection in the one hue they share. */
  --op-hover-tint:color-mix(in oklab,var(--c2) 8%,transparent); /* theme-derived */
  /* --op-chip-tint / --op-chip-tint-hover — op-link-chip's plane, look B "tint pill" (Aaron 2026-10-07, call C1;
     Steward re-entry 10 § 4, PMO 4839cbec). A mix of the chip's OWN ink over whatever ground it sits on, so it
     steps away from the ground in both themes with one rule: the plane rungs run in opposite directions per theme,
     so no single plane token can (D1 — Aurora's --op-plane-hover sat closer to READ's ground than --op-plane,
     1.07 < 1.14 : 1; D2 — Feather's --op-plane WAS READ's ground, 1.00 : 1; both measured on vault-extension).
     ACHROMATIC — the ink is the host's — so this is not a second consumer of --op-hover-tint's hue exception.
     THEME-INVARIANT by construction: the declaration names no themed input; currentColor resolves at the chip,
     per element, in either theme. CANDIDATE 8% / 13%, Aaron's (digest #2). */
  --op-chip-tint:color-mix(in oklab,currentColor 8%,transparent); /* theme-invariant */
  --op-chip-tint-hover:color-mix(in oklab,currentColor 13%,transparent); /* theme-invariant */
  /* --op-speaker-mark — fire ① of the district's colour ration (steward-theme-contrast-2026-09-15 § 4,
     walked by Aaron 2026-09-15; semantic-register § 2d amended 2026-09-16): the surface's OWN speaker
     mark — ◆, the face tile — wears --c2 as IDENTITY. Ink only, on READ's ground (5.12:1 Aurora ·
     5.03:1 Feather, computed), the one hue in a turn head. A ROLE token, not a second reach at
     --op-focus: "where you are" (focus, selection) and "who is speaking" share a VALUE today and are
     not one binding — the --node-branch finding (a move-type hue that happened to be c2, so "Vault
     speaking" and "a dispatch card" rhymed by coincidence) in canon's own costume. Retune one and the
     other must not move. NEVER a fill behind a speaker's words, never the operator's monogram (the two
     speakers differ by MARK, not by colour — or the pair becomes the bubble pair), never any seat's
     head beyond the mark itself. CANDIDATE, Aaron's (digest #2). */
  --op-speaker-mark:var(--c2); /* theme-derived */
  /* lifecycle — NODE-carried (border + fill alpha), disjoint from the EDGE-carried axis above.
     Predicted ghosts the CONTAINER, never the label's ink. */
  --op-life-live-w:var(--stroke-bold); --op-life-done-alpha:1; --op-collapsed-alpha:.6; /* theme-invariant */
  --op-life-predicted-alpha:.55;
  /* status / run-state — flat semantics; never a move-type, never a confidence. SPENT ON LABELS in
     this district (op-state-token · op-trace-row · op-btn--danger · the consumer's liveness word), so
     the three referents carry a TEXT obligation on every plane the district composes them on — met by
     value, both themes, since the Feather retune of --error/--success (2026-09-13, [data-theme] block). */
  --op-status-ok:var(--success); --op-status-warn:var(--warn); --op-status-error:var(--error); /* theme-derived */
  /* ── THE CONTEXT-FILL STEPS (--op-ctx-fill-1..7) — landed 2026-10-04, Aaron's design (Figma
     HIXJ2kc8 110:1101, `context-fill-icon-keyframes`; approved 2026-10-04). Fire ⑥ of the colour
     ration (semantic-register § 3): the ramp WALKED, one flat stop per step, on op-ctx-fill's segments
     and nowhere else (gate ctx-fill-reach-enumerated). Pure derivation, ZERO new hexes: steps 1 · 4 · 7
     are --c5 · --c3 · --c1 verbatim; 2 · 3 · 5 · 6 are oklab mixes of the adjacent stops, the share
     fitted to his Figma hexes (ΔE_ok 0.27 · 0.38 · 0.00 · 0.88 against #3FCFC7 · #49B0E9 · #8271F4 ·
     #BB6CD5). The walk skips --c4 and --c2 as pure stops — his, recorded, not corrected. CANDIDATE. */
  --op-ctx-fill-1:var(--c5); --op-ctx-fill-2:color-mix(in oklab,var(--c4) 55%,var(--c5)); --op-ctx-fill-3:color-mix(in oklab,var(--c3) 32%,var(--c4)); /* theme-derived */
  --op-ctx-fill-4:var(--c3); --op-ctx-fill-5:color-mix(in oklab,var(--c2) 70%,var(--c3)); --op-ctx-fill-6:color-mix(in oklab,var(--c1) 45%,var(--c2)); --op-ctx-fill-7:var(--c1); /* theme-derived */
  /* ── THE SYNTAX GROUP (--op-syn-*) — landed 2026-09-23, arm B (Aaron's pick, U10 · 7a4d20).
     The code well's ink, one role set painted identically in the editor and in READ's fences.
     Canon's rationale + the arms rendered + the reject reasons: operator-district/syntax-colour.md.
     THE CONTEXT EXCEPTION, and why the ramp hues are legal here at all (semantic-register § 2i):
     "within a code-editing view syntax highlighting is contextually different than seeing that
     particular color value elsewhere" (Aaron). A hue in a fence answers "what kind of token" and
     carries none of its chrome meaning — it never reaches prose or chrome (the .tok-* rules in
     operator.css are scoped to the three code wells, and a gate refuses a bare one).
     SHAPE — pure alias + derivation, ZERO new hexes:
       · --op-syn-lift — THE ONE NUMBER, and the one per-theme value in the group (no marker; it
         appears in BOTH blocks). Aurora 100% (the hue verbatim — its lowest hue, --c2, is already
         5.26:1 on the well). Feather 84% — CANDIDATE, Aaron's. Feather's ramp hues are boundary /
         mark colours and fail AA as TEXT on the well: raw on --inset c1 3.81 · c2 4.61 · c3 4.40 ·
         c4 3.79 · c5 3.56. 84% is the first whole step at which the worst (c5) clears 4.5 (4.61);
         86% falls under. Authored per theme for --muted-2's reason: the target is a RATIO, and a mix
         twin does not hold a ratio across two grounds. DO NOT TIDY THIS AWAY — the four raw ratios
         above are why it exists, and PRIMITIVE-INDEX § Tokens carries them too.
       · --op-syn-hue-1..5 — the five rungs a role reaches. A role NEVER reaches --cN directly
         (gate syn-rung-only), so the lift is applied in ONE place and a retune moves every hue.
       · sixteen role tokens — each carries an ASSIGNMENT decision (which hue this role wears),
         which is what separates this from the rejected --gap-* rename-alias shape.
     Arm B's map is One Dark's, hue-for-hue: keyword violet · string green · regex/escape cyan ·
     function blue · property magenta · type cyan · literal AMBER (--op-status-warn — the one
     status-hue-on-data line; the swap put to Aaron stood by silence, 2026-09-20). Contrast floor
     (syn-role-floor): 16 roles × {--op-well, --op-canvas} × both themes ≥ 4.5:1; the tightest cell
     is Feather string on the well, 4.61. */
  --op-syn-lift:100%;
  --op-syn-hue-1:color-mix(in oklab,var(--c1) var(--op-syn-lift),var(--ink)); --op-syn-hue-2:color-mix(in oklab,var(--c2) var(--op-syn-lift),var(--ink)); --op-syn-hue-3:color-mix(in oklab,var(--c3) var(--op-syn-lift),var(--ink)); /* theme-derived */
  --op-syn-hue-4:color-mix(in oklab,var(--c4) var(--op-syn-lift),var(--ink)); --op-syn-hue-5:color-mix(in oklab,var(--c5) var(--op-syn-lift),var(--ink)); /* theme-derived */
  --op-syn-name:var(--op-ink-2); --op-syn-definition:var(--op-ink); --op-syn-function:var(--op-syn-hue-3); --op-syn-keyword:var(--op-syn-hue-2); /* theme-derived */
  --op-syn-string:var(--op-syn-hue-5); --op-syn-string2:var(--op-syn-hue-4); --op-syn-literal:var(--op-status-warn); --op-syn-property:var(--op-syn-hue-1); /* theme-derived */
  --op-syn-type:var(--op-syn-hue-4); --op-syn-operator:var(--op-ink-2); --op-syn-punctuation:var(--op-ink-muted); --op-syn-comment:var(--op-ink-muted); /* theme-derived */
  --op-syn-meta:var(--op-ink-muted); --op-syn-invalid:var(--op-status-error); --op-syn-inserted:var(--op-status-ok); --op-syn-deleted:var(--op-status-error); /* theme-derived */
  --ease:cubic-bezier(.3,0,0,1);
  /* ── DURATION tier — I10 dimensional family, landed 2026-07-31. Theme-INVARIANT → :root ONLY
     (a transition is not slower in one theme). PROMOTES EXISTING VALUES AND INVENTS NONE: BRAND.md
     § Depth/Motion already ratifies "120 / 200 / 320ms, cubic-bezier(.3,0,0,1), no bounce" — the
     scale was decided and simply never tokenised, so --ease shipped alone and every consumer wrote
     its own raw ms. Same posture --stroke-* took, and the same reason: a scale nobody can reach is
     a scale that gets re-spelled. Curated-empirical per digest #3 — three values the DS already
     uses, not a ratio, because a ratio here would dress a decided choice as a derivation. */
  --dur-fast:120ms; --dur-base:200ms; --dur-slow:320ms; /* theme-invariant */
  /* ── STROKE tier — I10 dimensional family, landed 2026-07-31. Theme-INVARIANT → :root ONLY.
     Promoted to brand core rather than held at district scope because the promotion condition was
     MET on arrival: the operator district needs these for its source-honesty encoding, and 69 of
     82 border-width declarations on the operator surface are the literal `1px`. Two tiers over one
     value set is the --gap-* shape already rejected as indirection without information, so this is
     ONE tier and the district's --op-stroke-* aliases retire into it (walk E3).
     NAMED --stroke-*, deliberately NOT --rule-width-* (a downstream surface's vocabulary reaching
     upstream) and NOT --hairline-w (binding a WIDTH to a COLOUR token's name).
     THE ACCESSIBILITY CARVE this exists for: a high-contrast theme can now make every hairline
     heavier in ONE declaration under prefers-contrast / forced-colors, instead of selecting 40-odd
     internal class names. That is the whole return on tokenising the weight.
     THE CONSTRAINT, so tokenising is not read as licence: this does NOT permit raising the resting
     weight. D15 quieted the divider deliberately — the ramp separates, the rule stays quiet.

     ── T15, RULED 2026-10-07 15:26 (Aaron, on specimens/stroke-scale-2026-10-07.html @314a111):
     A STROKE'S WEIGHT IS A POSITION ON AN AXIS, THE WAY A FACE'S IS. Thin → black on the font
     convention (100 · 400 · 700 · 900), one continuous curve: stroke(w) = regular × 1.2^((w−400)/100)
     — the type scale's own minor third, one step per 100 of weight. Regular is today's hairline.
     His words: "i could actually feel the curve of values vs the snapped … exact always feels better."
     So the values are EXACT and never snapped: thin 1/1.2³ · regular 1 · bold 1.2³ · black 1.2⁵.
       THE CURVE IS RULED; THE ANCHOR IS CANDIDATE (digest #2). Each stop is written as a self-contained
     expression rather than var(--stroke-regular) × n because the operator surface's vendoring bridge
     derives these values verbatim and cannot follow a var() into a name it does not carry. So a
     retune of regular is four edits, and gate `stroke-on-the-curve` (qa/check.mjs) FAILs any stop
     left off the curve — the curve, not the authoring form, is what is pinned.
       ONLY THE FOUR STOPS THE REGISTER NAMES. Light/medium/semibold/extrabold sit on the same curve and
     are NOT declared: a token with no consumer is a guess about a shape nobody has built. A fifth
     stop is named by its font-weight word and the curve gate already knows its value.
       NAMED BY WEIGHT, and --stroke-hair RETIRED WITHOUT AN ALIAS. "hair" is not a position on the
     axis, it collided with the COLOUR token --hairline (a width wearing a colour's name, the shape
     the 07-31 note above refused for --hairline-w), and an alias over --stroke-regular would be
     indirection without information — the --gap-* case law. Tripwire `stroke-hair-retired` pins it.
       HOW AN EDGE DRAWS ITS WEIGHT (option b′). border-width and outline-width FLOOR to whole CSS px
     in Chromium at DPR 1 and 2 (measured: 1.5 and 1.728 both compute 1px), and a box drawn as a line
     paint-snaps (a 1.728px-wide box paints 2px). So a stroke that is not a whole px is NEVER fed to
     a snapping property: a box edge keeps its regular border (it reserves the layout every box was
     built around) and carries the weight ABOVE regular as a zero-blur inset edge —
     `box-shadow: inset 0 0 0 calc(var(--stroke-bold) - var(--stroke-regular)) <edge>` — which paints
     exactly what b′ painted (the regular pixel full ink, the remainder as coverage). A line drawn as
     a box carries its remainder as a zero-offset spread. Gate `stroke-never-snaps`. Neither is a
     cast: zero offset, zero blur, nothing floats (the 2026-08-02 slider-thumb ruling).
       FORCED COLOURS drops box-shadow, so every edge drawn ONLY as an inset edge owes a real
     border or outline under @media (forced-colors: active) — gate `inset-edge-forced-colors`.
     A remainder edge needs none: its regular border is real and survives; the weight above it goes.
       --stroke-bold's 1.5px RETIRES here: it was a hope that a half pixel would render, and it never
     did at a border. --stroke-focus below stays OFF this axis on purpose. */
  --stroke-thin:calc(1px / 1.728); --stroke-regular:1px; --stroke-bold:1.728px; --stroke-black:2.48832px;
  /* --stroke-focus — the FOCUS RING's width, 2px, an integer on purpose (6ad2c5, 2026-09-29; PMO
     ade9fa6b + 9a04a141). The ring read --stroke-bold, and 1.5px floors to 1px at 1x DPR, so
     OP-ESTABLISHMENT § 3.1's promised 2px rendered as 1 and a page carried two ring weights (brand
     core's blanket rule was a 2px literal). T15 (2026-10-07) did NOT bring it back onto the stroke
     axis: a ring is an indicator with an a11y floor (WCAG 2.4.13's 2px), a stroke is a weight — a
     retune of one must not move the other, so it is never an alias of a --stroke-<weight> stop.
     Theme-invariant → :root only. Gates: focus-width-integer (qa/check.mjs) · ro-p7's computed ≥ 2px lines. */
  --stroke-focus:2px;
  /* ── ICON tier — I10 dimensional family, landed 2026-08-22; RE-DERIVED 2026-09-16 for a FILL set.
     Theme-INVARIANT → :root ONLY (a glyph is not heavier in one theme). PROMOTED from the operator
     district on a re-derivation that had ALREADY HAPPENED: `.op-icon` and `obsidian-theme/theme.css`
     each declared the same weight for the same icon set with no token between them — CODIFICATION.md
     § Step 2's named silent failure, with the vendored theme as the prediction come true. Placement
     verdict + reason: operator-district/PRIMITIVE-INDEX.md § `op-icon` + `op-avatar`.

     THE SET LEFT AND TOOK ITS PROPERTY WITH IT. The tier landed with `--icon-stroke: 1.75`, a ratio on
     Lucide's 24-unit stroke grid. On 2026-09-16 the district's set became Phosphor Light — FILLED
     geometry on a 256-unit grid, no stroke to tune — and the token had no consumer left. It is
     RETIRED, not zeroed and not kept "for the theme": the Obsidian theme rides Obsidian's own Lucide
     and now declares its weight theme-locally (`--cv-icon-stroke`), an accepted divergence recorded
     at that declaration and under P10. A tripwire (`no-icon-stroke-after-phosphor`) pins the
     declaration and every `var()` of it absent from brand.css and the district. Lesson, recorded in
     the Steward's case law: the 08-22 tier was right as TOKENS and wrong in ONE — `--icon-stroke` was
     the SET's property wearing the TIER's name. What survives the set is the BOX.
     Record: operator-district/icon-set-change-record.md § 2.

     SIZE STEPS — CANDIDATE, RETUNED 2026-09-30 (f0a107 · PMO b6dc62f3), PENDING AARON'S LOOK.
     The 09-15 boxes measured SMALL beside their own label in real chrome (Steward seat read
     2026-09-30, op-surface at 1512×950, chrome label --text-small = 15.04px): head/toolbar icon
     buttons 1.00×, menu item marks, act carets, op-kind and rail pane tabs 0.93× — and Phosphor
     Light's ink inside a 14px box is 9.4–11.2px tall, i.e. the glyph read at the cap height of
     15px text. The retune puts the box ONE minor-third step (1.2, the type axis' ratio, ruling #3)
     above its label:
       --icon-md  1em → 1.2em — the inline step: still tracks its label, now at 1.2× it.
       --icon-sm  14px → 18px — the CONTROL step: 18 / 15.04 = 1.197× the chrome label.
     The smaller arm, 16px (1.06×), stands beside it on the look specimen; it sits UNDER the
     1.15× band this retune gates, so choosing it is a deliberate gate change, not a value swap.
     Gate: icon-to-label-ratio (qa/check.mjs) — every box 1.15–1.25× its label, a 1em plant FAILs.
     --icon-lg is 24px — the large step (no longer "1:1 with the source grid": the grid is 256).
     Consumers that sized a glyph by literal (`.shell-collapse .icon` and kin) say `var(--icon-sm)`
     and move with it; the working mark's DRAW does not (operator.css, pinned — its window clips).

     THE FLOOR IS OBSERVED, NOT DERIVED — reclassified 2026-09-16. The 08-22 floor was arithmetic:
     24 ÷ 1.75 = 13.71px, the box where a Lucide stroke clears one device pixel. Phosphor Light's
     12-unit ribbon is 0.66 device px at 14px — under that crossing — and it is the column he read as
     CLEAR. Counter-space decided, not stroke arithmetic, so the derived floor picked the wrong winner.
     RULE, unchanged: below the floor, DROP the icon; never shrink it.
     THE FLOOR IS MOVING, AND THIS SAYS SO. Until 2026-09-30 the floor was 14px, the smallest box a
     specimen approved (2026-09-15, "phosphor light at 14px looks the best"), and this comment said
     growing the box "ships something he did not look at". This retune DOES grow it, and that is the
     open condition, not a contradiction to hide: 18px is a CANDIDATE that has NOT been approved —
     Aaron judges 14 · 16 · 18 on a specimen of real chrome, both themes, before anything re-vendors
     (f0a109 waits on that look). What the 09-15 read approved was the SET's clarity at 14px; what it
     did not test was the box against its label, which is the axis this retune moves. */
  --icon-sm:18px;      /* CANDIDATE (was 14px) — the CONTROL step and the floor; 1.197× the chrome label */
  --icon-md:1.2em;     /* CANDIDATE (was 1em) — the inline step: 1.2× its label (one minor-third step) */
  --icon-lg:24px;      /* the large step */
  /* ── GLYPH tier — the slot every non-text mark beside text sits in (b8e2d5, 2026-10-11).
     The vault base's glyph-label contract (Lab/design-system-base/primitives/glyph-label.md,
     GLY-1–18) fixes relations; these are Corvus's values. Theme-INVARIANT → :root ONLY.
       --glyph-slot  16px CANDIDATE — the square slot a bullet, ordinal, checkbox, chevron or type
                     icon occupies (GLY-1). Its own token, not an --icon-* step and not a --space-*
                     rung: the slot is the COLUMN, and the --icon-* box is what an icon draws at
                     (with a dropped-never-shrunk floor, mid-retune 14 → 18). Coupling the column to
                     the icon look would move every list indent on an icon decision. 16 matches the
                     Obsidian binding (--cv-glyph, 06884d) so the brand's two surfaces nest alike.
       --glyph-unit  slot + --space-2 = 24px — one nesting step (GLY-4). A relation, not an alias:
                     a slot retune moves the step with it. The GAP is --space-2 spelled directly —
                     a --glyph-gap token would be the rejected --gap-* alias shape, and gate 2b
                     admits only var(--space-*) in a gap.
     THE OPEN CONDITION, said rather than hidden: a type icon drawn in a 16px slot sits under the
     --icon-sm CANDIDATE (18) and over the approved 14 floor. The reference page (glyph-label.html)
     wires --icon-sm and --icon-lg as slot alternates so the look can decide; 18 puts the unit at
     26, off the 4px grid. */
  --glyph-slot:16px;   /* CANDIDATE — the glyph slot (GLY-1) */
  --glyph-unit:calc(var(--glyph-slot) + var(--space-2)); /* the nesting step (GLY-4) */
  /* ── SHELL GEOMETRY tier — I10 dimensional family, PROMOTED from the operator district 2026-08-02
     alongside `.splitter` and `.collapsible` (Aaron, /walk D1.3). Theme-INVARIANT → :root ONLY.
     PROMOTES EXISTING VALUES AND INVENTS NONE: these are operator.css's GEOM constants verbatim
     (--op-splitter-w/hit/step, --op-rail-w), moved because their consumers moved. A brand-core rule
     reading a token declared in a district sheet resolves to NOTHING on any surface that does not
     also load that sheet — invalid at computed-value time, silently inheriting — which is precisely
     the surface this promotion exists to serve (field/artisan-01.html links brand.css and nothing
     else). The rules could not travel without them.
     NAMED without the district prefix, on the --stroke-* precedent: a downstream surface's
     vocabulary must not reach upstream, and the district's aliases retire rather than survive
     (the --gap-* shape, rejected as indirection without information).
     --collapsible-rail-w is NOT --rail-w, deliberately: brand core already spends `rail` twice
     (.rail is the fixed top gradient bar, .railed/.rail-col the margin-column layout), and a bare
     --rail-w would read as the width of a bar that has only a height. */
  --splitter-w:5px;          /* theme-invariant */ /* the visible handle */
  --splitter-hit:3px;        /* theme-invariant */ /* grab margin either side — 11px total target */
  --splitter-step:16px;      /* theme-invariant */ /* keyboard resize increment, read by splitter.js */
  /* RAISED 2026-09-04, --space-10 → --space-12, at the operator's request:
     *"the OS ui overall feels very tight to me in the left icon rail as well as
     the navigator pane."* The token's own comment is what licenses it — this is
     "a function of GLYPH + PADDING," so more room around the glyph is the value
     moving for the reason it exists, not a layout number being nudged.

     IT IS ONE KNOB FOR TWO AXES, and that coupling was the whole decision. The
     collapsible primitive reads it as the railed pane's WIDTH; the operator
     district reads it as each rail tab's HEIGHT. So one step buys air in both
     and keeps the icon box square. The alternative — decoupling, so the district
     declared its own tab-height rung — was measured, put to Aaron with its cost
     (cc-offer never moves; icon boxes stop being square; the district carries a
     divergence needing a recorded reason) and NOT chosen.

     BLAST RADIUS, ENUMERATED RATHER THAN EXPECTED: operator-district/operator.css
     (rail tab height) · the collapsible primitive (railed min/max width) ·
     dist-cc/index.html + dist-cc/cc-offer.html (inlined at build, so the shipped
     Change Craft offer moves on its NEXT rebuild, not today) ·
     field/artisan-02-layout.html. Aaron was shown that list, including the
     client-facing member, and took the trade.

     WHY THE LITERAL BECAME A var(). 40px was already exactly --space-10 — on the
     scale, but written as a number, so nothing said so and nothing would have
     caught it drifting off. The neighbours in this GEOM group are still literals
     and are a separate cleanup; this one converts because it was being touched
     anyway. --space-12 is declared below this line and resolves fine: custom
     properties are computed-value-time, not parse-order. */
  --collapsible-rail-w:var(--space-12); /* theme-invariant */ /* railed width — a function of glyph + padding, never of the pane */
  /* ── DIMENSIONAL FOUNDATION (--text/space/radius/leading/track) — CANDIDATE, values pending Aaron's
     tuning (his production role, like the --pr-* hexes). Theme-INVARIANT → defined here at ONE altitude,
     never duplicated into [data-theme="feather"] (size/space/radius don't change between themes).
     Derived from the ~237 raw values already in use (ds-foundation-assessment §4): a codify-not-redesign
     rationalization that snaps ad-hoc values to a scale, not a new look. Consume via var(); never re-guess. */
  /* type scale — modular minor-third 1.2, 18px anchor. READING-COMFORT BUMP (2026-07-25, ratified):
     anchor moved 16→18px — Instrument Sans's moderate x-height (~.50 em) reads a step under its set size,
     so 18px reads generous-not-oversized and answers the felt "runs small". Reading core (mono→h3) rides
     full 1.2 grid steps from the 18px body. --text-micro is KEPT as a DELIBERATE FLOORED token at ~11px
     (off the strict −3 step's 10.42px; held legible the way --radius-pill is a deliberate non-ratio
     extreme) — its fine-mono-label tier stays pointed here, NOT retired. --text-mono is the rail/folio
     identity signature at 12.5px. h2/display FLOORS re-floored so the bumped h3 (31.1px) never exceeds h2
     (anti-inversion); caps held (no display balloon — the mono rail stays load-bearing). CANDIDATE — Aaron
     tunes like --pr-*. Derivation of record: proof-surface/scale-function-token-derivation.md +
     proof-surface/type-scale-bump-proposal.md */
  --text-micro:.69rem; --text-mono:.78rem; --text-small:.94rem;
  --text-body:1.125rem; --text-body-lg:1.35rem; --text-lede:1.62rem; --text-h3:1.944rem;
  --text-h2:clamp(2.1rem,4.6vw,3.4rem); --text-display:clamp(3rem,7vw,6rem);
  /* leading (line-height) + tracking (letter-spacing) — paired scales for the type roles */
  --leading-display:1; --leading-tight:1.15; --leading-snug:1.22; --leading-body:1.45; --leading-relaxed:1.6; --leading-loose:1.75;
  --track-display:-.035em; --track-tight:-.02em; --track-normal:0; --track-wide:.02em;
  --track-mono:.06em; --track-caps:.1em; --track-caps-lg:.14em; --track-caps-xl:.2em;
  /* spacing — 4px base (the grid Corvus documents in comments but never tokenized); consumed by name */
  --space-1:4px; --space-2:8px; --space-3:12px; --space-4:16px; --space-5:20px;
  --space-6:24px; --space-8:32px; --space-10:40px; --space-12:48px; --space-16:64px;
  /* the two fluid rhythms, named once (section vertical rhythm · page gutter) — were re-clamped per file */
  --space-section:clamp(72px,12vh,128px); --space-gutter:clamp(22px,5vw,72px);
  /* radius — curated-geometric (ratified): ~1.5× guided low, gently decelerating (1.5·1.5·1.44·1.23),
     envelope-preserving (top=16, no corner-drama); pill UNIFIED (retires the 100px/999px split → one token) */
  --radius-xs:4px; --radius-sm:6px; --radius-md:9px; --radius-lg:13px; --radius-panel:16px; --radius-pill:999px;
  /* measure (line length) — I10 tier, landed 2026-07-28. The reading-comfort axis the 2026-07-25
     foundation pass never enumerated: measure was enforced by EIGHT hand-set `ch` literals scattered
     across brand.css + proof.css + one page's inline <style> (34/44/46/52/56/72/74ch), with no token
     and therefore no coverage guarantee — so a primitive authored without one simply had none, and
     .pr-claim-defeat shipped five lines of narrative prose at 122ch (Space Mono, 12.5px, no cap).
     Theme-INVARIANT → :root only, same one-altitude rule as --text/space/radius/font.
     SCALE FUNCTION IS CURATED-EMPIRICAL, NOT MODULAR — deliberate, and the reason is not aesthetic:
     measure is bounded by an EMPIRICAL reading band (45–75ch), not by perceived proportion, so a
     ratio would generate steps outside the band and dress an arbitrary choice as a system. Three
     curated steps, each pinned to a reading fact, is the honest shape (Typography Craft, `measure`).
     UNIT IS ch, NEVER px — ch scales with the font, so these caps survive any future --text-* bump
     unchanged (the 2026-07-25 bump already proved this: the ch-bound roles held, the uncapped ones
     did not). CANDIDATE — Aaron tunes like --pr-*. Derivation: proof-surface/feedback-ds-obligations.md */
  --measure-tight:34ch; --measure-lede:46ch; --measure-prose:66ch;
  /* NOT a measure axis, deliberately excluded: display BALANCE caps (h1 16ch, .h2 17ch, .catch 26ch)
     are a text-wrap:balance companion for 2–3-word display lines — a different problem from reading
     measure, and folding them in would imply the 45–75ch band governs them. They stay authored raw
     and are named in verify.mjs's gate-5 allowlist so the exclusion is explicit, not an oversight. */
  /* ── FONT-FAMILY FOUNDATION (--font-*) — I10 tier, landed 2026-07-27. Theme-INVARIANT → :root only,
     never duplicated into [data-theme="feather"] (a family doesn't change between themes), same one-altitude
     rule as --text/space/radius. Each token carries its COMPLETE stack INCLUDING fallbacks, declared ONCE;
     selectors reference the token and never re-spell a family name. Repair of record: the four faces load
     from a Google Fonts CDN with font-display:swap, and the display/serif/mono declarations named the brand
     face with NO fallback at all — so a blocked/slow CDN dropped h1/.h2/.brandmark to the browser's DEFAULT
     SERIF (Times), i.e. a different brand rather than a degraded one. Stacks are measured, not guessed:
     fallbacks ordered by advance-width + x-height proximity to the brand face (fontTools over the real CDN
     binaries) and by weight-axis coverage — system-ui leads the sans stacks because .brandmark/h1/.btn ask
     for 600/700 and the variable system faces cover those continuously where Arial/Helvetica would
     synthesize. Derivation + per-face degraded-state bar: proof-surface/font-token-tier.md */
  --font-display:"Bricolage Grotesque",ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  --font-text:"Instrument Sans",ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  --font-accent:"Instrument Serif",ui-serif,"Times New Roman",Times,Georgia,serif;
  /* --font-mono's coverage faces (e6f4a0, ruled 2026-10-03): kaomoji are a primary use of non-ASCII glyphs, so the
     mono voice carries them in-face. Each family after Space Mono is a self-hosted subset (fonts/faces.css, imported
     above) whose unicode-range is exactly what it adds — it never draws a glyph Space Mono has. Iosevka Charon Mono
     and Noto Sans JP/KR are size-adjusted onto Space Mono's cell; the single-script faces are proportional. Order is
     generated, not chosen here: tools/fonts/build-faces.py; gate tools/fonts/glyph-gate.mjs checks this stack
     against fonts/coverage.json. Derivation: proof-surface/font-token-tier.md §3.5. */
  --font-mono:"Space Mono","Iosevka Charon Mono","Noto Sans JP","Noto Sans KR","Noto Sans Thai","Noto Sans Kannada","Noto Sans Arabic","Noto Sans Canadian Aboriginal","Noto Sans Sinhala","Noto Sans Georgian","Noto Sans Math","Noto Sans Symbols 2",ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,"Liberation Mono",monospace;
  /* --font-display-italic — the .shimmer word's real italic (09c15c; face picked by Aaron 2026-09-29 at 8fe880,
     Typography + Brand Identity reviews PASS-WITH-CONDITIONS, 8fe880-review.md). Bricolage ships no italic, so
     the display voice borrows ONE drawn italic from a second family: Schibsted Grotesk italic, requested as a
     single master at 650 (its stems measured against Bricolage 600 across opsz 36-96: -0.6%…-2.3%; 600 was
     -9.5%…-11%). Zero weight steps, like --font-accent. Bricolage is the SECOND family on purpose: if Schibsted
     fails to load, .shimmer (font-synthesis:none) paints upright Bricolage — the 67899b interim's face, at 650
     rather than its 600 — and never a synthesized oblique. The system tail then carries it as --font-display's does. */
  --font-display-italic:"Schibsted Grotesk","Bricolage Grotesque",ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  /* the one signature gradient, define-once */
  --ramp:linear-gradient(120deg,var(--c1),var(--c2),var(--c3),var(--c4),var(--c5));
  --ramp-loop:linear-gradient(var(--sa),var(--c1),var(--c2),var(--c3),var(--c4),var(--c5),var(--c1));
  /* --ramp-radial: adjacent radial gradients (Argyle heritage) — each hue radiates, so the
     midpoints stay vibrant instead of muddying through a linear interpolation. The DEFAULT for
     substantial color FIELDS; --ramp (linear) stays for hairlines/text-clip/bookmarks. */
  --ramp-radial:
    radial-gradient(ellipse 62% 150% at 2% 46%,  var(--c1), transparent 56%),
    radial-gradient(ellipse 56% 150% at 27% 54%, var(--c2), transparent 56%),
    radial-gradient(ellipse 56% 150% at 50% 44%, var(--c3), transparent 56%),
    radial-gradient(ellipse 56% 150% at 73% 56%, var(--c4), transparent 56%),
    radial-gradient(ellipse 64% 150% at 98% 48%, var(--c5), transparent 58%),
    var(--c3);
  /* --btn-bold-deepen — the ink step laid over the ramp under .btn-bold's label (3e834c, Q4). Aurora
     needs none (its --ground label on the ramp clears AA, 5.03:1 worst); Feather's value is CANDIDATE. */
  --btn-bold-deepen:0%;
}
[data-theme="feather"] {
  /* interference ramp — LIGHT (Feather) */
  --c1:#C93B92; --c2:#6B4FD8; --c3:#3D5FE0; --c4:#0E7F9E; --c5:#0F8A64;
  /* pure white is reserved for raised — surface stays in the paper family (ruling 2026-07-16) */
  --ground:#F1F2F6; --surface:#FAFAFC; --raised:#FFFFFF; --inset:#E8E8EF;
  /* --ground-lift — the Feather half-step. Authored to the MEASURED delta, not copied as a mix
     percentage, for the same reason --muted-2 is: the two ramps are uneven in OPPOSITE directions
     (Aurora's steps rise .0208/.0257/.0303; Feather's fall .0285/.0242/.0143 against the #FFFFFF
     ceiling), so a percentage twin would land somewhere else entirely. dL here is .0117 vs Aurora's
     .0116. Feather has never been rendered on any operator surface — this value is arithmetic. */
  --ground-lift:#F5F6F9;
  --ink:#17141F; --ink-2:#3D3A49; --muted:#5D5A6B; --hairline:#DDDDE6;
  /* INK RAMP stop 4 — CANDIDATE. Feather is NOT a mix-percentage twin of Aurora: the same 86% mix
     lands 5.03:1 on Aurora and 4.51:1 here, so the value is authored to the RATIO, not copied.
     Theme-parity (I10): --muted-2 is defined in both themes; --ink-faint needs no override because
     it derives from --muted and --ground, which are already themed.
     WIDENED 2026-09-15 (Aaron, walked D1.6.5): #6F6D7D sat at 4.51:1 on --ground — AA by 0.01 — and
     the operator surface's first Feather render put that margin in front of him. One L step darker
     in OKLab with hue and chroma held (L 0.5421 → 0.5248, ΔL −0.0173; C 0.0248 → 0.0250; h 291.3° →
     291.2°, the residue of 8-bit quantisation). Measured (WCAG relative luminance, off the hex):
     --ground 4.86 · --ground-lift 5.03 · --surface 5.21 · --raised 5.43 · --inset 4.46 (inset was
     never a permitted plane for this rung — ink-ramp-4th-rung.md § 3.3). The --muted → --muted-2
     joint widens 0.066 → 0.082 (still a half-step of the house cadence; § 4.3 stands). Aurora is
     untouched: it was never at the margin. */
  --muted-2:#6A6878;
  /* --ink-faint is re-declared here rather than inherited. ink-ramp-4th-rung.md §2b argued it
     "needs no override because it derives from --muted and --ground, which are already themed" —
     true of how it RESOLVES, false of what theme-parity/light-co-equal checks, which is DECLARATION.
     The gate caught it on first run (2026-07-29). It is not `theme-invariant` either: it resolves to
     a different colour per theme, so marking it so would be a lie to satisfy a check. Same
     expression, declared in both blocks — the mix re-resolves against Feather's --muted/--ground. */
  --ink-faint:color-mix(in oklab,var(--muted) 55%,var(--ground));
  /* SELECTION + SCROLLBAR — same construction as --ink-faint directly above, and re-declared for the
     same reason: the expression is theme-neutral but the RESULT is not, so the parity gate wants both
     blocks and `theme-invariant` would be a lie told to satisfy a check. The mixes re-resolve against
     Feather's --c2 / --ink / --ground. Feather at 72%: fill #907DE1, separation 3.02:1, text 5.37:1 —
     measured in a real compositor, and it is the WORSE of the two themes, which is why 72% is the
     crossing rather than a round number. See :root for the two-floor rationale. */
  --select-fill:color-mix(in oklab,var(--c2) 40%,transparent);
  --select-ink:var(--ink);
  --scrollbar-thumb:color-mix(in oklab,var(--ink) 22%,transparent);
  --scrollbar-thumb-hover:color-mix(in oklab,var(--ink) 38%,transparent);
  --scrollbar-track:transparent;
  /* --warn darkened #C7871A→#8A5A0F for the WCAG AA floor: it is TEXT in .pr-against--empty on paper
     (was 2.49:1, now 4.85:1 vs --inset) and the .pr-claim-defeat border (was 2.92:1 <3, now 5.67:1).
     Feather-only; Aurora --warn stays bright (passes 8.97:1). CANDIDATE amber — Aaron may retune ≥AA.
     --error and --success TOOK THE SAME REPAIR 2026-09-13 (Steward, e7a3f1 second pass), for the same
     reason and by the same method. The operator district spends --op-status-{ok,error} on LABELS —
     op-state-token, op-trace-row, op-btn--danger, the consumer's liveness word — so on this district
     the aliases ARE text, and the unprimed critic measured the liveness word at 4.38:1 on --surface
     (P3, CRITICAL). --success had never been measured as text on paper: 3.02:1 on --ground. Each
     was moved in OKLab on L ALONE (hue and chroma held — #D93843 L.589→.528, #2E9E6B L.624→.489)
     until it clears AA on --inset, the hardest paper plane, so the 4.5:1 obligation a dual-role token
     carries is discharged by the VALUE on every plane rather than policed per use. Both land on
     --warn's own Feather rung to the hundredth (ground 5.28 / 5.31 · surface 5.67 / 5.70 · raised
     5.91 / 5.94 · inset 4.85 / 4.87) — three status tokens, one rung on paper. Aurora untouched
     (error 6.10 · success 9.11 on ground). The brand-core control-floor ruling below (--error is a
     boundary token in DS sheets; error TEXT rides --ink) is unchanged — this is the alternative it
     names as "a CANDIDATE value and Aaron's", reached for because the district's status register
     is ratified as label-carried. CANDIDATE hues — Aaron may retune ≥AA. */
  --success:#007343; --warn:#8A5A0F; --error:#C31E32;
  /* PROOF DISTRICT (pr-) — CANDIDATE, pending Aaron's final hex. Feather: marks darken to read on paper;
     low confidence = faint blue-gray near paper, high = deep structural blue.
     Two AA-floor nudges (Feather-only, ≥4.5:1 as text): --pr-tier-u #8A6A30→#7E5F28 (verdict-exceptions
     text was 4.11:1 vs --inset, now 4.84); --pr-tier-k #1E8A64→#16785A (the knockout "K" badge letter
     was 3.85:1, now 4.85). Candidate hues — Aaron retunes, keeping ≥AA. */
  --pr-conf-1:#B9C0D2; --pr-conf-2:#8E9CC0; --pr-conf-3:#5F79AE; --pr-conf-4:#3A5BB8; --pr-conf-5:#22468F;
  --pr-for:#1C7C8C; --pr-against:#A24C8A;
  --pr-tier-k:#16785A; --pr-tier-i:#22468F; --pr-tier-u:#7E5F28;
  /* ── OPERATOR DISTRICT (op-) — the ONLY per-theme override this group needs. Every other --op-*
     token inherits Feather free through the primitive it aliases; that is the whole point of the
     alias layer, and `theme-derived` is what lets gate 1 accept it as parity rather than as ~30
     missing overrides. Ghosting reads differently on paper: at Aurora's alphas a light-mode ghosted
     edge reads "broken / half-loaded" rather than "inferred", so the two ghost alphas lift and the
     predicted-container alpha with them — the co-equal-light guardrail applied to an ENCODING
     rather than to a palette. Never rendered on Feather; these are derived, not seen. */
  --op-src-derived-alpha:.80; --op-src-inferred-alpha:.58; --op-life-predicted-alpha:.62;
  /* THE SYNTAX GROUP's one per-theme value — CANDIDATE 84%, Aaron's (see :root). The first whole
     step at which Feather's least-luminous hue (--c5) clears AA as text on --inset: 4.61:1. */
  --op-syn-lift:84%;
  /* --op-on-focus — the lightest plane on paper; see :root (e55ad7). */
  --op-on-focus:var(--raised);
  /* --btn-bold-deepen — CANDIDATE, Aaron's (3e834c, Q4). Measured (mark-contrast gradient-text, worst
     pixel, system.html): 0% 4.13 · 6% 4.43 · 8% 4.60 · 10% 4.79 · 12% 4.87 · 14% 5.06. 8% is the first to
     clear and clears by 0.10 — the armed send's thin margin again — so 10% is the proposal. See :root. */
  --btn-bold-deepen:10%;
}
:root{color-scheme:dark}
[data-theme="feather"]{color-scheme:light}
