A11y theme modes (color-blind, low-vision)
themes specs/themes/a11y-modes.kmd
Two additional theme modes alongside Verge light/dark — `color-blind` (deuteranopia-safe palette swap) and `low-vision` (text size +20%, font-weight ≥500, contrast floor AAA). User opt-in via Settings; persisted in `koder.a11y_mode`. Mirrors Duet (LocalTapiola) practice.
When this spec applies
Primary triggers
- Build or revise a Verge-themed UI for an a11y mode
All triggers
- Add a11y theme support to a Koder product
- Audit a surface's contrast in non-default modes
Specification body
Spec — Accessibility theme modes
Status: v0.1.0 — Draft. Companion to Verge v0 (
specs/themes/verge.kmd). v0 introduces the SELECTORS + token overrides; per-product implementation inkoder_kit/koder_web_kitis sub-ticketed.
R1 — Two new modes
| Mode | Selector | Default | Purpose |
|---|---|---|---|
| color-blind | [data-a11y-mode="color-blind"] | OFF | Deuteranopia/protanopia-safe palette: red→orange, green→blue (high-distinguishability pair) |
| low-vision | [data-a11y-mode="low-vision"] | OFF | Larger text, heavier weight, AAA-floor contrast |
Modes compose with light/dark ([data-theme="dark"][data-a11y-mode="color-blind"]).
R2 — Color-blind palette deltas
Verge v0 (Adwaita-based) currently exposes only
bg / surface / surface-2 / text / text-muted / accent / accent-on / border / focus. Semantic status tokens (success / danger / warning) are NOT yet ratified ininternal/kinds/verge.go. Until they are, color-blind mode v0 ships the selector only — the swap table below is the contract semantic tokens MUST honor when added.
| Verge role (proposed) | Default light | color-blind light | Default dark | color-blind dark |
|---|---|---|---|---|
--kdr-accent | #1f3a93 (blue base) | unchanged | #6fa3ff | unchanged |
--kdr-success (TBR) | #1a7f37 (green) | #2563eb (blue) | #46c476 | #60a5fa (blue) |
--kdr-danger (TBR) | #cf222e (red) | #ea7c34 (orange) | #ff7b7b | #f59e0b (amber) |
--kdr-warning (TBR) | #d29922 (amber) | #a855f7 (violet) | #f0c674 | #c084fc (violet) |
Rationale: deuteranopia-safe pairs use blue/orange axis where the typical red/green axis fails.
Follow-up ticket required in tools/design-gen to ratify
--kdr-success / --kdr-danger / --kdr-warning tokens in Verge before
the color-blind mode can carry semantic meaning.
R3 — Low-vision deltas
| Token | Default | low-vision |
|---|---|---|
--kdr-fs-base | 16px | 19px (+20%) |
--kdr-line-height (TBR) | 1.5 | 1.6 |
--kdr-font-weight-min (TBR) | 400 | 500 |
--kdr-contrast-floor (TBR) | 4.5 (WCAG AA) | 7.0 (WCAG AAA) |
Tokens marked (TBR) (to be ratified) are not yet in Verge v0;
their introduction is gated on a follow-up Verge token-set expansion
ticket. --kdr-fs-base already exists and IS swapped in v0 of this
spec — text-scaling support ships immediately.
R4 — Implementation contract
base.cssships[data-a11y-mode="color-blind"]and[data-a11y-mode="low-vision"]selectors at the same cascade level as[data-theme="dark"]. Tokens cascade through; products that usevar(--kds-color-...)get the swap for free.- Settings drawer ratchets the 4-segment control:
default/color-blind/low-vision/both. Last option applies both selectors. - localStorage key
koder.a11y_modepersists choice; anti-flash script sets thedata-a11y-modeattr on<html>before first paint (same pattern asdata-theme). tools/design-gen/cmd/verge-contrast-auditextends to also audit pairs under both new modes; CI fails on regressions.
R5 — Live demo
/<locale>/themes/a11y-modes/ renders a sample card (heading + body +
button + success + danger pills) in 4 modes side-by-side.
R6 — Nutrition-labels integration
Products that ship working color-blind / low-vision support SHOULD
declare in their koder.toml:
[a11y_labels]
color-blind-mode = "supported"
high-contrast = "supported" # if also adding forced-colors
dynamic-type = "supported" # implied by low-vision
Per specs/accessibility/nutrition-labels.kmd.
Não-escopo
- Auto-detect from OS (forced-colors media query is separate spec).
- Per-locale typography overrides beyond size/weight (e.g., script- specific weight rebalancing for CJK).
- Windows high-contrast bridge (separate spec).
References
specs/themes/verge.kmdspecs/themes/light-dark.kmdspecs/accessibility/nutrition-labels.kmd