fix(theme): custom themes cover all twenty-one roles #210
No reviewers
Labels
No labels
adr
android
area/calendar
area/design-system
area/i18n
area/jobs
area/offline
area/server
area/testing
bug
ci
duplicate
enhancement
help wanted
invalid
notifications
question
reliability
security
severity/low
severity/medium
tracking
web
wontfix
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
eagraiclainne/app!210
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/custom-theme-roles"
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?
Closes #202.
#207 took the palette from nine roles to twenty-one. A household's custom
theme still overrode nine, so the other twelve fell back to the family
theme — and a dark custom theme on a light family kept that family's light
surface-raisedanderror-surface. A pale edit box on a dark card, andan invalid-row ring on a ground nobody had checked.
The generator guarantees WCAG AA for everything it emits, but it runs at
build time over authored values. A custom theme escaped that guarantee for
twelve of twenty-one roles, silently, and would have started showing the
moment a component consumed them.
Eleven roles are now derived from the household's anchors and clamped at
runtime against the same thresholds
cmd/tokengenenforces, includingborder-strongat the 3:1 non-text floor — a checkbox outline is a mark,not text. The clamp walks toward black and toward white a fiftieth at a
time and takes the first step that clears every ground: the smallest
nudge, not a replacement. Where no nudge reaches the floor it keeps the
closest and never blocks; a separate audit then names which of the
household's own colours to move, in plain words.
--warningis the twelfth, and it is asked rather than derived.Deriving it fails exactly where it matters: a family whose celebrate is
pink or blue has nothing warm to turn toward, which is why two built-in
themes needed hand-tuning when the roles were authored. It joins
background, text and accent as a fourth anchor — the workshop asks for
four decisions, not twenty-one.
The border constants were fitted, not invented: 0.20 and 0.45 reproduce
hearth's authored values exactly in both modes, so a custom theme lands
where a hand-authored one would.
The rules exist twice, in TypeScript and Kotlin, because the derivation
runs at runtime on each client — the workshop re-derives on every
colour-well change, and the phone completes a stored map offline.
tokengenrenders build-time constants and cannot produce a runtimefunction, so the repo's existing answer for twice-implemented logic holds
them together:
conformance/theme-derive.json.A vocabulary drift gate now fails the suite if the client's token list and
the generated CSS disagree — the failure mode this PR fixes cannot recur
silently.
Existing custom themes keep every value they chose.
🤖 Generated with Claude Code
Test report
Coverage: 27.0%
Updated by the check workflow · commit
918ded3ca4Android test report
Coverage: 10.3% of lines
Updated by the android workflow · commit
918ded3ca42897911567918ded3ca4