Accessibility
Inclusive defaults so every user — keyboard, screen-reader, reduced-motion, zoom — can complete core tasks.
Manifesto
“Accessibility isn’t a final-mile checklist. It’s the floor we start from — baked into tokens, components, and documentation so the right thing is the easy thing.”
01 · Non-negotiables
Six pillars
Every component and page inherits these. If a pattern can’t meet them, fix the system — not the symptom.
Color
Never convey meaning with hue alone. Pair with text, icon, or pattern.
Focus
Every interactive element renders a visible focus ring — the system token wins by default.
Keyboard
Every control is operable without a pointer. Tab order is predictable and documented.
Labels
Form fields and icon-only buttons expose an accessible name to assistive tech.
Motion
Entrance animation respects prefers-reduced-motion. Never gate meaning on motion alone.
Zoom
Layouts reflow to 400% zoom and 320px viewport without horizontal scroll.
02 · Contrast
Verified pairs
Default text + surface combinations that meet WCAG 2.2. Spot-check any new pairing with a contrast tool before shipping.
03 · Keyboard
Keyboard map
Standard bindings across brand components. Document additions per widget.
04 · Ship checklist
Every component ships with
- Correct semantic role, or appropriate ARIA where native HTML is insufficient.
- Accessible name and current state exposed to assistive tech.
- Keyboard map documented: Enter, Space, Escape, arrows, Home / End.
- Contrast verified for default, hover, focus and disabled states.
- Focus ring uses --brandOS-focus-* tokens; never removed without an equivalent.
- prefers-reduced-motion respected in every entrance animation.
- Works zoomed to 400% and on a 320px-wide viewport.
- Screen-reader pass on one canonical flow (NVDA + VoiceOver).
05 · Tooling
How we verify
Automation catches the obvious, humans catch the rest. Both layers are non-optional.
CI blocker. Fails the build on violations.
Per-story, per-PR.
Catches focus-ring regressions.
One canonical flow per release.