#186: pond accent theming (ADR 0018 stage C) #187
No reviewers
Labels
No Label
area:auth
area:docs
area:export
area:ops
area:storage
area:supply-chain
auth
backend
blocked
collab
deployment
docs
effort:L
effort:M
effort:S
frontend
plugins
qa
vs-nfd
vs-nfd:blocker
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: stwaidele/dorfteich#187
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "feat/186-pond-accent"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Implements #186. STACKED on #185 (which stacks on #183) — merge order: #183 -> #185 -> this; each merge shrinks the next diff accordingly.
Verified locally: typecheck, eslint+prettier, i18n:check; FULL api suite vs. fresh DB dorfteich_t186 (424 passed incl. new theme-merge test); shared 177 + web 131 unit tests; e2e vs. fresh env dorfteich_e2e_182: pond-theme 1/1 (scope boundary + axe on pond settings), theme-accent 2/2, theme 3/3, settings-nav 2/2, a11y light+dark 8/8; screenshots show the violet pond accent on content links while the app chrome keeps the viewer's green in both modes.
Do not merge on red CI. Issue #186 will be closed manually after a green pipeline.
apply-theme.ts derives BOTH modes' accent tokens from the stored choice (ui.theme.accent: preset id or {custom:'#hex'}) and writes them as <style id="user-theme"> with :root:root + :root:root[data-theme='dark'] blocks — the doubled :root beats tokens.css regardless of document order, since theme-init.js injects the ui.theme.css cache during <head> parsing, before the bundle styles. The default preset means NO override (hand-tuned tokens.css values stay). main.tsx re-derives from the choice at startup, healing stale caches after app updates. Settings: accent radiogroup inside the Appearance section (visible names, color never the only cue) with per-mode preview swatches on each mode's canonical background, plus a custom color input; i18n de+en. The second fieldset made bare .settings-fieldset locators ambiguous — theme specs now scope via input[name] (fence stays). Tests: apply-theme unit pack, BASE_PALETTE<->tokens.css drift fence in theme-contrast.test.ts, e2e theme-accent.spec (instant apply, pre-paint persistence, default removes override, axe smoke with garish yellow in both modes). ADR 0018 amendment documents the stage-B details. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QRtCnB3uLdQtFmvp9HXcRXpondSettingsSchema gains theme = { accent: '#rrggbb' | null } (null = inherit the viewer's theme), exposed as a top-level key of the flat updatePondInputSchema and included in the PondsService settings merge (the known silent-no-op pitfall). The server validates only the hex; conformance arises at render time: PondThemeScope (mounted around the page content next to PondFontScope) derives the accent pair for the EFFECTIVE mode via useEffectiveTheme and sets it as inline custom properties — inline beats both tokens.css and the user-theme <style>, which IS the cascade precedence pond > user > default. Pond settings get a PondThemeSection (inherit | presets | custom color with per-mode preview swatches, explicit save like the font manager); AccentSwatches extracted for reuse; i18n de+en. The no-JS public shell stays deliberately un-themed (ADR 0018 amendment). Tests: pond DB test (theme merge keeps fonts, invalid hex 400), e2e pond-theme.spec (scope boundary content vs. chrome, per-mode re-derivation, axe on the pond settings page; resets the fixture pond). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QRtCnB3uLdQtFmvp9HXcRX