What this site commits to on accessibility
This site targets WCAG 2.2 Level AAacross every page and every reachable slider state. The conformance claim is self-assessed: no third-party VPAT, no signed audit. It’s the bar that’s automated in CI, walked manually before each release, and listed honestly with its limits below.
Tested against
- axe-core via Playwright: tagged at WCAG 2.0/2.1/2.2 levels A and AA, run on every route at five representative slider positions plus the JD adapter across idle, typed-in, scored, and expanded-miss states.
- Contrast snapshot: a Vitest enumerates the four-slider grid at step 0.1 (11⁴ = 14,641 combinations) and asserts ≥ 4.5:1 on every load-bearing pair. Worst-case ratios snapshot so regressions surface as diffs.
- Lighthouse CI: accessibility score = 100 on
/,/jd,/lab, and/accessibilityat default slider state. - Biome a11y rule group: recommended set enabled at error level on every
.tsxin CI. - Manual walkthrough: keyboard-only, VoiceOver + Safari, NVDA + Firefox, 400% browser zoom, OS-level reduced motion, OS-level high contrast / forced colors, iOS VoiceOver on a real device. Checklist at
docs/runbooks/a11y-manual.md.
Known limits
- Contrast floor is AA, not AAA.At every reachable slider state, body and accent text hit ≥ 4.5:1 against the background. The site does not promise the AAA 7:1 floor, because the refined-polish default cream palette can’t carry it without losing its character. The worst-case ratio across the slider grid is 5.46:1 on muted text.
- The rethemer panel is dark by design.The slider deck pill and panel are hardcoded chrome; they don’t re-theme with the page, and under Windows High Contrast Mode they opt out of system-color substitution to stay visually distinct. The interactive controls inside (native
<input type="range">) remain keyboard-operable and labelled. - OS prefs win via cascade only. When
prefers-contrast: moreorforced-colors: activeare on, the page restyles via CSS, but the slider position you chose is preserved. The contrast Vitest guarantees AA is held at every slider state, so OS prefs and slider state coexist without forcing a choice. - Self-assessed claim, no VPAT. No third-party audit has been commissioned. If anything below the floor is found, please report; see contact below.
Reproduce locally
The full automated bar runs as a single command from a checkout of the source:
bun run a11y # Biome a11y + contrast Vitest + axe Playwright
bun run a11y:lhci # Lighthouse CI (separate, needs a running build)Contact
Found something that breaks? Want to flag a barrier? oliver.kg2@gmail.com. Honest gap reports are welcome; that’s the same posture the JD adapter takes about itself.
The full rationale (slider-token strategy, OS-pref handling, screen-reader strategy, alternatives considered) lives in ADR-0032 — Accessibility approach when the /decisions page is live; until then it’s in the repo at docs/adr/0032-accessibility-approach.md.