Expose dock glyph and focused window control colours as tokens - #455
Merged
AllTerrainDeveloper merged 4 commits intoJul 30, 2026
Merged
Conversation
Two clusters of shell chrome painted themselves white with no name a
desktop theme could aim at. Both sit on a surface a theme CAN
repaint, which is what makes it a trap: recolour the surface and the
marks on top of it vanish.
- Dock glyphs. `--desktop-mode-dock-bg` is declared and themes set
it. What sits on the strip was fixed: the glyph at 70% white,
brightening to full on hover, over a 15% white wash, with a 70%
white focus ring. A pale dock left every tile blank.
- Focused window controls. Same five whites on
`--desktop-mode-titlebar-bg-focused`. The unfocused half already
had `--desktop-mode-titlebar-btn-*` and, under an active theme,
derives itself from `--desktop-mode-titlebar-color`; the focused
half had neither, so a pale focused title bar produced the one
window whose close button you cannot see.
`--wpd-btn-*` was not a workaround for the second. Those declarations
land on the WINDOW element, so a value set at the shell root loses to
them, and the same names drive buttons well outside the title bar.
Nine tokens, all UNDECLARED, every site reading `var( --name, <the
literal it always had> )`:
--desktop-mode-dock-icon-color / -icon-color-hover
--desktop-mode-dock-item-bg-hover / -item-outline
--desktop-mode-titlebar-btn-focused-color / -color-hover
/ -bg-hover / -bg-active / -outline
The focused set mirrors the unfocused one name for name; the dock set
covers the mark, its hover, the tile wash under it, and the focus
ring, which is the complete set needed to put a light strip on screen.
An unthemed shell computes exactly what it computed before.
Two sites take a token whose fallback differs from the one beside it,
on purpose. Dock system tiles read `-icon-color` behind their own
brighter 0.8, and the screen-meta buttons read the focused set behind
their own dimmer 0.65. Unthemed each keeps its deliberate notch;
themed, one colour covers the whole cluster instead of half of it
going legible while the other half stays white. `dock-peek.css`
re-states the hover rule and outranks the base one, so it reads the
same two tokens — otherwise a themed dock reverted to white on first
hover.
Close-button red is deliberately not exposed. It is semantic signal,
not chrome; the focused half now resolves it through `--wpd-danger`
like the unfocused half always did, instead of repeating the literal.
Nothing derives the focused glyphs the way the unfocused ones derive
from `--desktop-mode-titlebar-color`: they sit on a fill a theme may
set to anything from near-black to a pastel, and CSS has no
contrast-safe function of a background colour. Explicit, or white.
No PHP — `desktop_mode_sanitize_desktop_theme_tokens()` already
accepts anything matching `^--desktop-mode-[a-z0-9-]+$`.
Tests assert against stylesheet text: every site reads its token
first with its exact prior literal, no token is declared in any sheet,
and both halves of the title-bar set exist. jsdom will not resolve a
nested `var()` chain against undeclared properties, so a
computed-style assertion would prove nothing.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015sKW1mu1SGg5k9oSHgxv5s
dock.css sets the resting hover wash as a background-COLOR on purpose — "so it composes with the texture rather than erasing it" — and dock-peek.css then re-stated the same rule with the `background` shorthand, which resets `background-image` along with it. Any theme shipping a DOCK_ITEM tile face lost it the moment the cursor landed, and got it back when the cursor left. One word, in a rule this branch already touches for the glyph tokens. Nothing moves without a theme: unthemed, `--desktop-mode-dock-item-image` is `none`, so resetting it or not resetting it look identical. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015sKW1mu1SGg5k9oSHgxv5s
The dock flattens plugin and CPT SVGs to one colour so a brand mark can't shout over its dashicon neighbours. Correct, and it stays. But it flattened with `filter: brightness(0) invert(1)`, and a filter has no colour to name — so those glyphs stayed WHITE on a dock a theme had just repainted pale, with nothing to override. A `currentColor` mask flattens identically: both paths keep only the source's alpha and discard its colours. The difference is that a mask has a fill, and that fill is the tile's own `color` — so plugin art now follows `--desktop-mode-dock-icon-color` like every other glyph. Nothing moves without a theme. Unthemed, `currentColor` on a dock tile is `rgba( 255, 255, 255, 0.7 )` at rest and `#fff` on hover, which is exactly what `brightness(0) invert(1)` plus `opacity: 0.7 → 1` computed. Same silhouette, same two values, one of them now nameable. `src/icon.ts` already reached this conclusion from the other side: it masks silhouette art and leaves fixed-colour art as an image. The dock masks both, because the dock had already decided every plugin icon is monochrome — this only changes which monochrome. The `background-image` span and its filter stay as the fallback for anything `isMaskableIcon()` refuses (a URL carrying literal quotes, spaces or parens), so no icon can disappear on account of this. Tests cover both branches, including the live-activation harvest shape, whose `url( … )` wrapper is stripped before validation — the wrapper's quotes and parens are what the guard rejects, not the URL inside them. Also folds the masked-span construction the themed path already did into `_makeMaskSpan()`, since there are now two callers. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015sKW1mu1SGg5k9oSHgxv5s
AllTerrainDeveloper
enabled auto-merge (squash)
July 30, 2026 13:58
AllTerrainDeveloper
deleted the
add/dock-glyph-and-focused-control-tokens
branch
July 30, 2026 14:01
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two clusters of shell chrome painted themselves white with no name a desktop theme could aim at. Both sit on a surface a theme can repaint, which is what makes it a trap: recolour the surface and the marks on top of it vanish.
--desktop-mode-dock-bgis declared and themes set it. What sits on the strip was fixed: the glyph at 70% white, brightening to full on hover, over a 15% white wash, with a 70% white focus ring. A pale dock left every tile blank.--desktop-mode-titlebar-bg-focused. The unfocused half already had--desktop-mode-titlebar-btn-*and, under an active theme, derives itself from--desktop-mode-titlebar-color. The focused half had neither, so a pale focused title bar produced the one window whose close button you cannot see.--wpd-btn-*was not a workaround for the second: those declarations land on the window element, so a value set at the shell root loses to them, and the same names drive buttons well outside the title bar (sticky notes, desk chrome).The tokens
Nine, all undeclared, every site reading
var( --name, <the literal it always had> ).--desktop-mode-dock-icon-color--desktop-mode-dock-icon-color-hover--desktop-mode-dock-item-bg-hover--desktop-mode-dock-item-outline--desktop-mode-titlebar-btn-focused-color--desktop-mode-titlebar-btn-focused-color-hover--desktop-mode-titlebar-btn-focused-bg-hover--desktop-mode-titlebar-btn-focused-bg-active--desktop-mode-titlebar-btn-focused-outlineThe focused set mirrors the unfocused one name for name. The dock set covers the mark, its hover, the tile wash under it, and the focus ring — the complete set needed to put a light strip on screen. An unthemed shell computes exactly what it computed before.
--desktop-mode-dock-icon-coloris a colour, not a fill, which matters for an iconset using"iconColor": "currentColor": those icons are masked with the glyph colour, so one token drives dashicons, the theme's artwork, and the hover transition together.Deliberate choices
-icon-colorbehind their own brighter0.8; the screen-meta buttons (Screen Options, Help,⋯) read the focused set behind their own dimmer0.65. Unthemed, each keeps its deliberate notch. Themed, one colour covers the whole cluster instead of half of it going legible while the other half stays white.dock-peek.cssre-states the hover rule and outranks the base one, so it reads the same two tokens. Without that, a themed dock reverted to white on first hover.--wpd-dangerlike the unfocused half always did, instead of repeating the literal.--desktop-mode-titlebar-color. They sit on a fill a theme may set to anything from near-black to a pastel, and CSS has no contrast-safe function of a background colour. Explicit, or white.desktop_mode_sanitize_desktop_theme_tokens()already accepts anything matching^--desktop-mode-[a-z0-9-]+$.Tests
tests/vitest/dock-and-titlebar-glyph-tokens.test.ts, 14 cases, asserting against stylesheet text: every site reads its token first with its exact prior literal, no token is declared in any sheet underassets/css/, both halves of the title-bar set are read, andvariables.cssdocuments all nine. Text rather than computed style because jsdom will not resolve a nestedvar()chain against undeclared properties, so a computed-style assertion would prove nothing.npm run build,lint,typecheckclean; full suite green (257 files, 2513 tests). No PHP touched.Manual QA
CSS-only, so the interesting check is that nothing moved by default: open the shell unthemed and confirm the dock glyphs, their hover, and the focused window controls look identical to trunk. Then, with a theme active, set e.g.
--desktop-mode-dock-bglight plus the four dock tokens dark and confirm the tiles stay legible — including on hover, which is the path the peek sheet used to override.Or use this theme to test it all by uploading it as theme in OS Settings:
neon-glass.zip
🤖 Generated with Claude Code