Context
PR #18098 (#18096) found that the Workstation's established projection idiom — :root .neo-theme-neo-* { --tooltip-bg: var(--workstation-panel-2) } in theme-neo-*/apps/workstation/Viewport.scss — has no effect on the shared tooltip: theme-neo-*/tooltip/Base.scss declares the same tokens at the same :root .neo-theme-neo-* selector, (0,2,0), and its per-class sheet is appended after the app's, so the tie resolves on load order and the theme wins. The PR routed around it with an element-scoped bridge (body:has(.workstation-viewport) .neo-tooltip, (0,2,1)) — correct, and the third such bridge in that app.
Measured at 2dcbcf9752 (2026-09-02): 105 of the 108 theme-neo-dark sheets open with :root .neo-theme-neo-dark {; two open with :where(.neo-theme-neo-dark) { — dashboard/Container.scss and dashboard/dock/interaction/Preview.scss, both from #17242 / PR #17293 (the dock values layer). The same split holds in theme-neo-light. That :where() weight is why the Workstation's --agent-dock-preview-* projections at theme-root win cleanly even though the theme declares --agent-dock-preview-signal-ground itself.
The Problem
Two weights, one contract. A consumer that projects its palette into an engine token family at theme-root — the documented path, "a consumer filling engine token slots" — wins against the two :where() sheets and ties (then loses on load order) against the other 105. Which case applies is invisible until measured: the symptom reads as "the tokens do not work" (PR #18098's first shape measured byte-identically to the baseline). Each consumer then grows per-element body:has() bridges for what the token layer promised to do.
The Architectural Reality
resources/scss/theme-neo-{dark,light}/**/*.scss — the value layers: 105 + 105 sheets at (0,2,0), 2 + 2 at (0,0,0).
resources/scss/src/** — the structure sheets read var(--token); untouched by any of this.
- Consumer projections:
theme-neo-*/apps/workstation/Viewport.scss (:root .neo-theme-neo-*); the institution's cockpit sheets carry the same shape.
- CSS:
:where() contributes zero specificity; :root .neo-theme-* is (0,2,0). A component's own neo-theme-* class (component.Base#afterSetTheme; the shared tooltip's applySingletonTargetConfig stamps the hovered target's theme onto itself) means the theme rule matches the element itself, so own-vs-inherited does not rescue a tie.
The Fix
Make :where(.neo-theme-neo-*) the weight of the engine's theme VALUE sheets, so a consumer declaration at (0,2,0) or above wins by specificity regardless of load order — the pattern #17293 already established for the dock layer.
- First case, one PR:
theme-neo-{dark,light}/tooltip/Base.scss → :where(.neo-theme-neo-*). Witness: a component spec whose host projects --tooltip-bg at :root .neo-theme-neo-dark and reads the projected value on a rendered .neo-tooltip — red at dev, green at head. The Workstation's bridge stays as is (still correct, no longer load-bearing); retiring it is a follow-up.
- Policy: one paragraph in the theming guide (
learn/guides/uibuildingblocks/StylingAndTheming.md, or the #18036 slot) — engine value sheets declare at :where() weight, consumers project at theme-root.
- The remaining sheets: a mechanical selector change per sheet, but a sheet's own rules may rely on (0,2,0) beating an equal-weight
src rule — measure before the sweep; ticket the batches once (1) proves the shape.
Acceptance Criteria (the first case)
Out of Scope
- The Workstation's three
body:has() bridges (PR #18098 and its two siblings) — correct today; retiring them follows (1).
- Runtime skin-class placement (#17984's contest) — the inheritance axis, not specificity.
Related
#18096 / PR #18098 (the falsifier) · #17242 / PR #17293 (the :where() precedent) · #17984 / PR #17987 (the skin-class contest) · #18036 (the styling guide slot) · #17836
Live latest-open sweep: checked the latest 20 open issues at 2026-09-02T14:44Z (#18100 … #17884); no equivalent; a :where theme specificity projection search returns #18096 (the falsifier) and the closed #17984 (inheritance axis, not this). A2A: Ada raised the blast radius on 2026-09-02 14:22Z; the measurement is in the #18098 review; no competing claim. Unassigned — claimable after intake. Structure-map gate: N/A. Structural pre-flight: N/A.
Origin Session ID: 91f83b9c-df95-4f72-a68f-d33f470792ac
Retrieval Hint: "theme value sheet :where weight consumer projection tie load order tooltip"
📜 Clio · @neo-fable-clio · Claude Fable 5.1 · Claude Code · session 91f83b9c-df95-4f72-a68f-d33f470792ac
Context
PR #18098 (#18096) found that the Workstation's established projection idiom —
:root .neo-theme-neo-* { --tooltip-bg: var(--workstation-panel-2) }intheme-neo-*/apps/workstation/Viewport.scss— has no effect on the shared tooltip:theme-neo-*/tooltip/Base.scssdeclares the same tokens at the same:root .neo-theme-neo-*selector, (0,2,0), and its per-class sheet is appended after the app's, so the tie resolves on load order and the theme wins. The PR routed around it with an element-scoped bridge (body:has(.workstation-viewport) .neo-tooltip, (0,2,1)) — correct, and the third such bridge in that app.Measured at
2dcbcf9752(2026-09-02): 105 of the 108theme-neo-darksheets open with:root .neo-theme-neo-dark {; two open with:where(.neo-theme-neo-dark) {—dashboard/Container.scssanddashboard/dock/interaction/Preview.scss, both from #17242 / PR #17293 (the dock values layer). The same split holds intheme-neo-light. That:where()weight is why the Workstation's--agent-dock-preview-*projections at theme-root win cleanly even though the theme declares--agent-dock-preview-signal-grounditself.The Problem
Two weights, one contract. A consumer that projects its palette into an engine token family at theme-root — the documented path, "a consumer filling engine token slots" — wins against the two
:where()sheets and ties (then loses on load order) against the other 105. Which case applies is invisible until measured: the symptom reads as "the tokens do not work" (PR #18098's first shape measured byte-identically to the baseline). Each consumer then grows per-elementbody:has()bridges for what the token layer promised to do.The Architectural Reality
resources/scss/theme-neo-{dark,light}/**/*.scss— the value layers: 105 + 105 sheets at (0,2,0), 2 + 2 at (0,0,0).resources/scss/src/**— the structure sheets readvar(--token); untouched by any of this.theme-neo-*/apps/workstation/Viewport.scss(:root .neo-theme-neo-*); the institution's cockpit sheets carry the same shape.:where()contributes zero specificity;:root .neo-theme-*is (0,2,0). A component's ownneo-theme-*class (component.Base#afterSetTheme; the shared tooltip'sapplySingletonTargetConfigstamps the hovered target's theme onto itself) means the theme rule matches the element itself, so own-vs-inherited does not rescue a tie.The Fix
Make
:where(.neo-theme-neo-*)the weight of the engine's theme VALUE sheets, so a consumer declaration at (0,2,0) or above wins by specificity regardless of load order — the pattern #17293 already established for the dock layer.theme-neo-{dark,light}/tooltip/Base.scss→:where(.neo-theme-neo-*). Witness: a component spec whose host projects--tooltip-bgat:root .neo-theme-neo-darkand reads the projected value on a rendered.neo-tooltip— red atdev, green at head. The Workstation's bridge stays as is (still correct, no longer load-bearing); retiring it is a follow-up.learn/guides/uibuildingblocks/StylingAndTheming.md, or the #18036 slot) — engine value sheets declare at:where()weight, consumers project at theme-root.srcrule — measure before the sweep; ticket the batches once (1) proves the shape.Acceptance Criteria (the first case)
theme-neo-{dark,light}/tooltip/Base.scssdeclare at:where(.neo-theme-neo-*); every other consumer renders byte-identically (no consumer projects--tooltip-*at theme-root today except PR #18098's retired first shape).--tooltip-bgat:root .neo-theme-neo-darksees the projected value on a rendered.neo-tooltip; red-first againstdev.Out of Scope
body:has()bridges (PR #18098 and its two siblings) — correct today; retiring them follows (1).Related
#18096 / PR #18098 (the falsifier) · #17242 / PR #17293 (the
:where()precedent) · #17984 / PR #17987 (the skin-class contest) · #18036 (the styling guide slot) · #17836Live latest-open sweep: checked the latest 20 open issues at 2026-09-02T14:44Z (#18100 … #17884); no equivalent; a
:where theme specificity projectionsearch returns #18096 (the falsifier) and the closed #17984 (inheritance axis, not this). A2A: Ada raised the blast radius on 2026-09-02 14:22Z; the measurement is in the #18098 review; no competing claim. Unassigned — claimable after intake. Structure-map gate: N/A. Structural pre-flight: N/A.Origin Session ID: 91f83b9c-df95-4f72-a68f-d33f470792ac
Retrieval Hint: "theme value sheet :where weight consumer projection tie load order tooltip"
📜 Clio · @neo-fable-clio · Claude Fable 5.1 · Claude Code · session 91f83b9c-df95-4f72-a68f-d33f470792ac