Skip to content

Expose dock glyph and focused window control colours as tokens - #455

Merged
AllTerrainDeveloper merged 4 commits into
trunkfrom
add/dock-glyph-and-focused-control-tokens
Jul 30, 2026
Merged

Expose dock glyph and focused window control colours as tokens#455
AllTerrainDeveloper merged 4 commits into
trunkfrom
add/dock-glyph-and-focused-control-tokens

Conversation

@AllTerrainDeveloper

@AllTerrainDeveloper AllTerrainDeveloper commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

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 (sticky notes, desk chrome).

The tokens

Nine, all undeclared, every site reading var( --name, <the literal it always had> ).

Token Role
--desktop-mode-dock-icon-color Dock glyph at rest
--desktop-mode-dock-icon-color-hover Dock glyph on hover / peek
--desktop-mode-dock-item-bg-hover Wash behind a hovered tile
--desktop-mode-dock-item-outline Dock keyboard focus ring
--desktop-mode-titlebar-btn-focused-color Focused control glyph at rest
--desktop-mode-titlebar-btn-focused-color-hover Focused glyph on hover / press
--desktop-mode-titlebar-btn-focused-bg-hover Focused hover wash
--desktop-mode-titlebar-btn-focused-bg-active Focused pressed wash
--desktop-mode-titlebar-btn-focused-outline Focused keyboard focus ring

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 — the complete set needed to put a light strip on screen. An unthemed shell computes exactly what it computed before.

--desktop-mode-dock-icon-color is 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

  • Two sites take a token whose fallback differs from its neighbour's. Dock system tiles read -icon-color behind their own brighter 0.8; the screen-meta buttons (Screen Options, Help, ) 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. Without that, a themed dock reverted to white on first hover.
  • Close-button red is 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

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 under assets/css/, both halves of the title-bar set are read, and variables.css documents all nine. Text rather than computed style because jsdom will not resolve a nested var() chain against undeclared properties, so a computed-style assertion would prove nothing.

npm run build, lint, typecheck clean; 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-bg light 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

Open WordPress Playground Preview

AllTerrainDeveloper and others added 4 commits July 30, 2026 14:19
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
AllTerrainDeveloper enabled auto-merge (squash) July 30, 2026 13:58
@AllTerrainDeveloper
AllTerrainDeveloper merged commit 5c7af6f into trunk Jul 30, 2026
5 checks passed
@AllTerrainDeveloper
AllTerrainDeveloper deleted the add/dock-glyph-and-focused-control-tokens branch July 30, 2026 14:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant