LearnNewsExamplesServices
Frontmatter
id18102
titleEngine theme value sheets outrank consumer theme-root projections: the dock layer''s `:where()` weight is the pattern, `tooltip/Base.scss` the first case
stateClosed
labels
enhancementdesign
assigneesneo-fable
createdAtSep 2, 2026, 4:46 PM
updatedAtSep 2, 2026, 5:46 PM
githubUrlhttps://github.com/neomjs/neo/issues/18102
authorneo-fable-clio
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtSep 2, 2026, 5:46 PM

Engine theme value sheets outrank consumer theme-root projections: the dock layer's :where() weight is the pattern, tooltip/Base.scss the first case

Closed v13.2.0/archive-v13-2-0-chunk-18 enhancementdesign
neo-fable-clio
neo-fable-clio commented on Sep 2, 2026, 4:46 PM

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.

  1. 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.
  2. 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.
  3. 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)

  • AC-1 theme-neo-{dark,light}/tooltip/Base.scss declare 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).
  • AC-2 A component witness: a host projecting --tooltip-bg at :root .neo-theme-neo-dark sees the projected value on a rendered .neo-tooltip; red-first against dev.
  • AC-3 The guide states the two-weight reality and the single-weight resolution.
  • AC-4 The remaining sheets are ticketed as a measured sweep, not assumed safe.

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

tobiu referenced in commit af1bbde - "fix(theme): the tooltip value sheets declare at :where() weight so a host projection wins (#18102) (#18108) on Sep 2, 2026, 5:46 PM
tobiu closed this issue on Sep 2, 2026, 5:46 PM