Context
#18102 established the policy and landed its first case: the engine's theme VALUE sheets declare at :where(.neo-theme-neo-*) weight (zero specificity) so a consumer projecting into a token family at theme-root (:root .neo-theme-neo-* { … }, (0,2,0)) wins by weight rather than by load order. After it, the dock values layer (dashboard/Container.scss, dashboard/dock/interaction/Preview.scss, from #17293) and tooltip/Base.scss carry that weight in both neo themes; the other sheets — 103 in theme-neo-dark, 103 in theme-neo-light at the time of #18102's measurement — still open with :root .neo-theme-neo-* {.
Why a sweep and not one commit
The selector change is mechanical, but a sheet's own rules may have relied on (0,2,0) outranking an equal-weight structure rule in src/ — a theme sheet that declares a non-token property, or nests a selector, or nullifies something a src rule sets on the same element. Dropping such a sheet to zero weight changes paint. Each batch therefore needs a measurement before the change, not an assumption after it.
Proposed change
Batches by directory (button/, form/, grid/, list/, tab/, toolbar/, apps/, …), each its own PR:
- Inventory the batch: which sheets declare anything other than custom properties at the theme-root rule, and which nest selectors. Those need a read against their
src counterpart before moving.
- Move the pure-token sheets to
:where(); record the theme paint of one rendered example per moved family before and after (a component screenshot or computed-style read), byte-identical expected.
- For sheets that are not pure-token, either restructure (the structural part belongs in
src/, per the guide's structure-vs-skin rule) or leave them at theme-root weight with a comment saying why, and ticket the restructure.
Acceptance Criteria
Non-goals
- The legacy
theme-dark / theme-light sheets: a separate decision, since they are not the neo design-token layer.
- Consumer bridges (the Workstation's
body:has() rules): retire them per family after that family moves.
Related
#18102 (policy + first case) · #17293 (the dock precedent) · #18098 (the falsifier)
Sweep 14:58Z before filing: live latest-20 open (no equivalent; #18102 is the policy ticket), A2A (no claim), Knowledge Base (no leaf).
Authored by Mnemosyne (@neo-fable, Claude Fable 5.1, Claude Code) · session 37bbc610-f0cd-4abb-95c2-eb70336a86f3
Context
#18102 established the policy and landed its first case: the engine's theme VALUE sheets declare at
:where(.neo-theme-neo-*)weight (zero specificity) so a consumer projecting into a token family at theme-root (:root .neo-theme-neo-* { … }, (0,2,0)) wins by weight rather than by load order. After it, the dock values layer (dashboard/Container.scss,dashboard/dock/interaction/Preview.scss, from #17293) andtooltip/Base.scsscarry that weight in both neo themes; the other sheets — 103 intheme-neo-dark, 103 intheme-neo-lightat the time of #18102's measurement — still open with:root .neo-theme-neo-* {.Why a sweep and not one commit
The selector change is mechanical, but a sheet's own rules may have relied on (0,2,0) outranking an equal-weight structure rule in
src/— a theme sheet that declares a non-token property, or nests a selector, or nullifies something asrcrule sets on the same element. Dropping such a sheet to zero weight changes paint. Each batch therefore needs a measurement before the change, not an assumption after it.Proposed change
Batches by directory (
button/,form/,grid/,list/,tab/,toolbar/,apps/, …), each its own PR:srccounterpart before moving.:where(); record the theme paint of one rendered example per moved family before and after (a component screenshot or computed-style read), byte-identical expected.src/, per the guide's structure-vs-skin rule) or leave them at theme-root weight with a comment saying why, and ticket the restructure.Acceptance Criteria
:where()weight or carries a comment naming the rule that keeps it at theme-root weight.:where()subsection drops its "while a family still declares at theme-root weight" clause once the last batch lands.Non-goals
theme-dark/theme-lightsheets: a separate decision, since they are not the neo design-token layer.body:has()rules): retire them per family after that family moves.Related
#18102 (policy + first case) · #17293 (the dock precedent) · #18098 (the falsifier)
Sweep 14:58Z before filing: live latest-20 open (no equivalent; #18102 is the policy ticket), A2A (no claim), Knowledge Base (no leaf).
Authored by Mnemosyne (@neo-fable, Claude Fable 5.1, Claude Code) · session 37bbc610-f0cd-4abb-95c2-eb70336a86f3