Resources
Accessibility Guidelines
System-wide rules, the current debt register, and where to verify contrast. Component-specific notes live on each component page; this is the policy layer.
System-wide rules
| Rule | Application |
|---|---|
| Color never carries meaning alone | confidence is a word; trend arrows pair with text; sync dot pairs with caption; selected chips change fill and label |
| Real semantics | buttons are <button>, switches are role=switch, scales are radiogroups, tab bars are tablists, sheets are aria-modal with focus traps |
| 44px minimum targets | text buttons extend hit areas with padding; chips meet it via height + spacing |
| Labels are persistent | form labels are eyebrows above fields — never placeholder-only |
| Errors are triple-coded | color + text + aria-invalid, with focus moved to the field |
| Motion is decorative | all animation is layer-change or status; prefers-reduced-motion can reduce to fades with zero meaning loss |
| Charts have text equivalents | the mandatory interpretation sentence + role=img labels |
Contrast policy
Live ratios for every shipped text/surface pair are computed on the Colors page. Policy: body text pairs must pass AA; text.muted is restricted to non-essential captions; white-on-orange is only legal at 15px/600+ (which is why the CTA gradient darkens to #C94800 and small active elements use #C2581D).
Known debt register
Open items, tracked honestly
- Long-press custom-tag CRUD has no keyboard path — needs a visible ⋮ entry point (pattern already exists in treatment categories).
- Demo-mode FAB is silently inert — visible but non-functional; mitigated by the persistent DEMO banner, but an announced “browsing only” state would be better.
- Sheet focus management — drag-dismiss is mouse/touch only by nature; Escape and the × button cover keyboard, but focus-return needs verification on every new sheet.