v2.43.0
Dashboard Appearance Themes
A complete dashboard-native appearance system: eight curated themes with per-browser light/dark controls, a live-preview gallery, and accessibility-focused coverage. No TUI-theme mapping, component library, or runtime dependency introduced.
Added
- Theme gallery in settings. Eight curated themes — entropist.ca (default), Dim, Solarized, Gruvbox, Caves of Qud, Van Gogh, and the colorblind-safe Okabe-Ito and Paul Tol — each with a light and dark variant. Inline preview cards render in their own scoped tokens, reflecting the selected mode without affecting the page.
- System / Light / Dark mode selector. Works for every theme including the default. Forced dark wins on a light OS and vice versa. System mode responds to live OS changes via matchMedia.
- Synchronous first-paint bootstrap. An inline head script applies the persisted theme before stylesheets load, preventing a wrong-theme flash on reload. A contract test keeps the bootstrap and runtime allowlists in sync.
- Cross-tab synchronization. Theme and mode selections propagate to all open same-origin tabs through the storage event, including full reconciliation on
localStorage.clear(). - Self-hosted JetBrains Mono. Variable WOFF2 (normal + italic), loaded only when Gruvbox is the active theme. OFL license and provenance files ship with the published package. Gallery previews use the base font to avoid eager fetches.
- Live theme-color meta. Browser chrome tracks the resolved
--bgbackground in real time as themes, modes, and OS preferences change. - WCAG AA from live CSS. All eight themes × two variants verified ≥ 4.5:1 contrast for text, muted, all four status accents, all nine syntax foregrounds, and the filled attention chip — computed from actual
getComputedStyle, not duplicated palette values. - Dim theme. Low-glare palette (no pure #000/#fff extremes) while clearing WCAG AA. Target 8–11:1 text-on-background.
- Colorblind-safe themes. Okabe-Ito and Paul Tol palettes keep status running/error distinguishable without relying on green-vs-red (blue/teal vs vermillion/red axis).
Technical
- Pure CSS custom properties in an additive
themes.csslayer. Selectors target[data-theme]/[data-color-mode]so they scope to both the document root and gallery preview containers. - Default theme + system mode leaves zero DOM footprint (no attributes, no
color-scheme, no font requests) — byte-for-bit identical to the pre-theme baseline. - iOS Safari 16.4 floor maintained — no
light-dark()CSS function used. - 155 jsdom + 92 real-browser Playwright tests covering the full theme × mode × OS matrix, contrast, font isolation, bootstrap parity, scoped previews, gallery interactions, and persistence resilience.
Closes #325.