Foundations

Accessibility

WCAG 2.1 AA is the non-negotiable floor for every screen shipped, per this system's constraint context. Not a phase-two audit item.

Contrast

Content typeMinimum ratio
Body text, labels (< 19px)4.5:1
Large text (≥ 24px, or ≥ 19px bold)3:1
UI component boundaries & icons3:1 against adjacent color
Disabled contentExempt, but should still read as clearly inactive
4.5:1 — passes on light and dark
~2.1:1 — fails, avoid this pairing

Focus states

Every interactive element gets a visible 2px focus ring using color-focus-ring, offset 2px from the element — never outline: none without a replacement.

Touch & click targets

  • Minimum 40×40px hit area for any clickable control (44×44px on touch-primary surfaces).
  • Adjacent targets keep at least 8px of separation to prevent mis-taps.
  • Never rely on hover alone to reveal a control needed to complete a task — provide a persistent or keyboard-reachable alternative.

Content & structure

  • One <h1> per page; heading levels never skip (no h2 → h4).
  • Every form input has a visible, programmatically-associated <label> — placeholder text is never a substitute for a label.
  • Error messages are specific and instructive ("Policy number must be 8 digits"), not generic ("Invalid input"), and are associated to the field via aria-describedby.
  • Icon-only buttons always carry an aria-label.
  • Color is never the only signal for status — always pair with an icon, label, or pattern (see Feedback & status).

Reduced motion

All transitions defined with --duration-* tokens should be wrapped so they collapse to near-instant when the user has prefers-reduced-motion: reduce set at the OS level.

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}