Theme engine: accent presets and free accent color (ADR 0018 stage B) #184

Closed
opened 2026-07-29 08:45:52 +02:00 by fable-5 · 1 comment
Collaborator

Second theming stage per ADR 0018: user-selectable accent color, device-local, with WCAG conformance BY CONSTRUCTION (derivation, not validation).

  • New dependency-free packages/shared/src/theme.ts: relativeLuminance/contrastRatio (WCAG 2.1), deriveAccentTokens(accentHex, mode) (hue/saturation preserved, lightness searched until >= 4.5:1 against the mode's bg, bg-subtle, and surface), THEME_PRESETS (~5 curated accents, pond green = default), BASE_PALETTE (canonical mode backgrounds).
  • apps/web/src/theme/apply-theme.ts: applyUserTheme() writes
Second theming stage per ADR 0018: user-selectable accent color, device-local, with WCAG conformance BY CONSTRUCTION (derivation, not validation). - New dependency-free packages/shared/src/theme.ts: relativeLuminance/contrastRatio (WCAG 2.1), deriveAccentTokens(accentHex, mode) (hue/saturation preserved, lightness searched until >= 4.5:1 against the mode's bg, bg-subtle, and surface), THEME_PRESETS (~5 curated accents, pond green = default), BASE_PALETTE (canonical mode backgrounds). - apps/web/src/theme/apply-theme.ts: applyUserTheme() writes <style id="user-theme"> with :root + :root[data-theme='dark'] blocks (mirrors the selector contract from #180); caches the derived CSS as ui.theme.css so public/theme-init.js injects it before first paint; choice stored under ui.theme.accent (preset id or {custom:'#hex'}). Default preset = no override (hand-tuned tokens.css values stay). - Settings UI: accent radiogroup with visible names (color never the only cue) + custom color input, live preview of the derived accents for BOTH modes, hint that colors are auto-adjusted for readability. i18n de+en. - Tests: shared sweep test (hue x sat x lightness x both modes, all >= 4.5:1), BASE_PALETTE <-> tokens.css drift fence, apply-theme unit tests, e2e accent pack incl. axe smoke with a garish custom accent in both modes. - ADR 0018 amendment with the stage-B details.
Author
Collaborator

Merged to main (83a2fe4/b1643bb via PR #185) and deployed: CD run 464 green, Test+Int verified live (readyz 5/5 both, accent-swatch styles in bundle index-Dw-jC8Tf.css, theme-init.js 200 for the pre-paint ui.theme.css cache). Sweep test fences the derivation (972 cases >= 4.5:1). Closing.

Merged to main (83a2fe4/b1643bb via PR #185) and deployed: CD run 464 green, Test+Int verified live (readyz 5/5 both, accent-swatch styles in bundle index-Dw-jC8Tf.css, theme-init.js 200 for the pre-paint ui.theme.css cache). Sweep test fences the derivation (972 cases >= 4.5:1). Closing.
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: stwaidele/dorfteich#184
No description provided.