Accessibility
Contrast, focus, keyboard access, names, themes, and reduced motion.
Rule
Every surface meets WCAG 2.2 AA in light and dark themes. Body text, secondary text,
interactive boundaries, and focus indicators meet the contrast contract defined in
DESIGN.md. Colour is always a second channel.
Every interactive element has visible focus, a logical keyboard path, and an accessible name. Escape closes overlays, dialog focus is trapped, and focus returns to the opening control. Brand surfaces and handheld layouts use the large control target. Images have purposeful alternative text. Fields have real labels.
Token contract
Use colors.on-surface and colors.on-surface-variant on their documented surfaces.
Focus uses colors.primary. The boundary of a control uses colors.outline-strong, the
only outline value that clears 3:1 against every surface step in both themes;
colors.outline-variant is a decorative rule and never the sole boundary of a control or
the sole separator carrying meaning. Status uses the matching components.badge-* recipe
plus written text and an icon. Touch targets use spacing.control-lg, applied by the
design system under a coarse pointer rather than by each call site.
Correct example
A blocked status reads “blocked,” includes its pause icon, and uses the attention badge recipe. The row is keyboard reachable, the action has a descriptive accessible name, and the same meaning remains in dark theme and with colour perception removed.
Rejected example
A row uses a coloured dot as its only status, removes the browser focus indicator, opens details only on hover, and draws a secondary button with the decorative hairline, so the control has no boundary a low-vision reader can see. Neither an agent nor a keyboard user can recover the missing meaning.
Verification
Check both themes and the reduced-motion preference. Complete the primary flow with a keyboard. Confirm labels and names in the accessibility tree. Validate the changed route with automated accessibility checks, then inspect the state and focus behavior manually.
Reasoning
The human constraints are documented in personas. The reusable state and overlay behavior lives in UI patterns.