Pular para o conteúdo

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.

Quando esta spec se aplica

Triggers primários

Todos os triggers

Corpo da especificação

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 in koder_kit / koder_web_kit is sub-ticketed.

R1 — Two new modes

ModeSelectorDefaultPurpose
color-blind[data-a11y-mode="color-blind"]OFFDeuteranopia/protanopia-safe palette: red→orange, green→blue (high-distinguishability pair)
low-vision[data-a11y-mode="low-vision"]OFFLarger 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 in internal/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 lightcolor-blind lightDefault darkcolor-blind dark
--kdr-accent#1f3a93 (blue base)unchanged#6fa3ffunchanged
--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

TokenDefaultlow-vision
--kdr-fs-base16px19px (+20%)
--kdr-line-height (TBR)1.51.6
--kdr-font-weight-min (TBR)400500
--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.css ships [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 use var(--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_mode persists choice; anti-flash script sets the data-a11y-mode attr on <html> before first paint (same pattern as data-theme).
  • tools/design-gen/cmd/verge-contrast-audit extends 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).

Referências