Accessibility conformance documentation for the Universal Design System. Targeting WCAG 2.2 Level AA across all 9 palettes, 43 components, and both light and dark modes.
The Universal Design System targets WCAG 2.2 Level AA conformance. Accessibility is enforced at the token level, validated by automated tooling on every build, and documented per component.
Every palette in UDS is designed to meet WCAG 2.2 Level AA contrast requirements: 4.5:1 for body text, 3:1 for large text and UI components. Contrast checks run on every build via npm run audit, covering 6 color pairs per palette across both light and dark modes (9 palettes × 6 pairs × 2 modes = 108 checks). Components are built with semantic HTML, ARIA attributes, keyboard support, and visible focus indicators as baseline requirements.
WCAG 2.2 introduces three new Level AA success criteria that the Universal Design System addresses. These criteria strengthen requirements for focus visibility, pointer input alternatives, and minimum target sizes.
components.csv via min_target_size columnConformance is validated through a combination of automated and manual testing processes.
npm run audit.
audits/a11y-audit.jsonConformance status for all 43 components against key WCAG 2.2 Level AA success criteria. Status is based on the component specification; implementors must follow the documented accessibility requirements.
| Component | SC 1.3.1 Info & Relationships |
SC 1.4.3 Contrast (Min) |
SC 1.4.11 Non-text Contrast |
SC 2.1.1 Keyboard |
SC 2.4.7 Focus Visible |
SC 4.1.2 Name, Role, Value |
SC 2.4.11 Focus Not Obscured |
SC 2.5.7 Dragging Movements |
SC 2.5.8 Target Size (Min) |
Accessibility Notes |
|---|---|---|---|---|---|---|---|---|---|---|
| Button | Supports | Supports | Supports | Supports | Supports | Supports | Supports | N/A | Supports | role=button; aria-disabled; aria-busy for loading; focus ring 2px offset |
| Navigation Bar | Supports | Supports | Supports | Supports | Supports | Supports | Supports | N/A | Supports | nav landmark; aria-label; mobile toggle aria-expanded |
| Hero Section | Supports | Supports | N/A | Supports | Supports | Supports | N/A | N/A | N/A | h1 for headline; meaningful alt on images |
| Feature Card | Supports | Supports | Supports | Supports | Supports | Supports | N/A | N/A | N/A | heading hierarchy; alt on images; focus on link |
| Pricing Table | Supports | Supports | Supports | Supports | Supports | Supports | Supports | N/A | Supports | aria-label on toggle; heading hierarchy |
| Social Proof Bar | Supports | Supports | N/A | N/A | N/A | Supports | N/A | N/A | N/A | alt text on logos; aria-hidden on decorative |
| Testimonial Card | Supports | Supports | N/A | Partial | Partial | Supports | N/A | N/A | N/A | blockquote element; cite for attribution. Video variant requires keyboard controls. |
| Footer | Supports | Supports | Supports | Supports | Supports | Supports | N/A | N/A | N/A | nav landmark; aria-label; link list structure |
| Code Block | Supports | Supports | N/A | Supports | Supports | Supports | N/A | N/A | N/A | pre+code elements; aria-label on copy button |
| Modal | Supports | Supports | Supports | Supports | Supports | Supports | Supports | N/A | Supports | role=dialog; aria-modal; focus trap; escape dismiss |
| Form Input | Supports | Supports | Supports | Supports | Supports | Supports | Supports | N/A | Supports | for/id label association; aria-invalid; aria-describedby |
| Select | Supports | Supports | Supports | Supports | Supports | Supports | Supports | N/A | Supports | native select for accessibility; aria-invalid |
| Checkbox | Supports | Supports | Supports | Supports | Supports | Supports | Supports | N/A | Supports | input+label association; aria-checked |
| Radio | Supports | Supports | Supports | Supports | Supports | Supports | Supports | N/A | Supports | fieldset+legend grouping; aria-checked |
| Toggle Switch | Supports | Supports | Supports | Supports | Supports | Supports | Supports | N/A | Supports | role=switch; aria-checked; aria-label |
| Alert | Supports | Supports | Supports | Supports | Supports | Supports | N/A | N/A | N/A | role=alert for error/warning; role=status for success/info |
| Badge | Supports | Supports | Supports | N/A | N/A | Supports | N/A | N/A | N/A | aria-label for icon badges; semantic color |
| Tabs | Supports | Supports | Supports | Supports | Supports | Supports | Supports | N/A | Supports | role=tablist/tab/tabpanel; aria-selected; arrow key nav |
| Accordion | Supports | Supports | Supports | Supports | Supports | Supports | Supports | N/A | Supports | aria-expanded; aria-controls; keyboard Enter/Space/ArrowUp/ArrowDown |
| Breadcrumb | Supports | Supports | N/A | Supports | Supports | Supports | Supports | N/A | Supports | nav aria-label=Breadcrumb; ol element; aria-current=page |
| Tooltip | Supports | Supports | Supports | Partial | Supports | Supports | Supports | N/A | Supports | role=tooltip; aria-describedby; show on hover+focus. Dismissible via Escape not yet specified. |
| Dropdown Menu | Supports | Supports | Supports | Supports | Supports | Supports | Supports | N/A | Supports | role=menu; aria-haspopup; aria-expanded; keyboard ArrowUp/Down |
| Avatar | Supports | Supports | N/A | N/A | N/A | Supports | N/A | N/A | N/A | alt text; aria-label for status |
| Skeleton | Supports | N/A | N/A | N/A | N/A | Supports | N/A | N/A | N/A | aria-busy=true on container; aria-hidden=true on skeleton |
| Toast | Supports | Supports | Supports | Partial | Partial | Supports | N/A | N/A | N/A | role=alert for error/warning; role=status for success/info. Auto-dismiss timing may not give all users sufficient reading time. |
| Pagination | Supports | Supports | Supports | Supports | Supports | Supports | Supports | N/A | Supports | nav aria-label=Pagination; aria-current=page |
| Data Table | Supports | Supports | Supports | Supports | Supports | Supports | N/A | N/A | N/A | scope=col; aria-sort; role=table |
| Date Picker | Supports | Supports | Supports | Supports | Supports | Supports | Supports | Supports | Supports | role=grid; role=gridcell; aria-selected; keyboard arrow nav |
| Command Palette | Supports | Supports | Supports | Supports | Supports | Supports | Supports | N/A | Supports | role=combobox; role=listbox; aria-activedescendant |
| Progress Indicator | Supports | Supports | Supports | N/A | N/A | Supports | N/A | N/A | N/A | role=progressbar; aria-valuenow; aria-valuemin; aria-valuemax |
| Side Navigation | Supports | Supports | Supports | Supports | Supports | Supports | Supports | N/A | Supports | nav aria-label; aria-current=page; aria-expanded |
| File Upload | Supports | Supports | Supports | Supports | Supports | Supports | Supports | Supports | Supports | input type=file aria-label; role=button on dropzone; aria-live=polite |
Legend: Supports = meets the success criterion. Partial = partially meets the criterion with known gaps. N/A = criterion does not apply to this component.
Summary of WCAG 2.2 AA contrast validation across all 9 palettes. Each palette is tested against 6 color pairs in both light and dark modes (12 checks per palette).
| Palette | Light Mode | Dark Mode | Total Checks | Pass Rate | Status |
|---|---|---|---|---|---|
| Minimal SaaS | 4/6 † | 4/6 † | 12 | 100% | Pass |
| AI Futuristic | 4/6 † | 4/6 † | 12 | 100% | Pass |
| Gradient Startup | 4/6 † | 4/6 † | 12 | 100% | Pass |
| Corporate | 4/6 † | 4/6 † | 12 | 100% | Pass |
| Apple Minimal | 4/6 † | 4/6 † | 12 | 100% | Pass |
| Illustration | 6/6 | 6/6 | 12 | 100% | Pass |
| Dashboard | 6/6 | 6/6 | 12 | 100% | Pass |
| Bold Lifestyle | 6/6 | 6/6 | 12 | 100% | Pass |
| Minimal Corporate | 6/6 | 6/6 | 12 | 100% | Pass |
| Total | 44/54 † | 44/54 † | 108 | 100% | Pass |
Color pairs tested per palette: text-primary/bg-primary (4.5:1), text-secondary/bg-primary (4.5:1), text-primary/bg-secondary (4.5:1), text-on-brand/brand-primary (4.5:1), brand-primary/bg-primary (3.0:1), text-tertiary/bg-primary (3.0:1). Full results available in audits/a11y-audit.json. † 2 pairs per mode (text-on-brand/brand-primary and text-tertiary/bg-primary) are skipped for 5 newer palettes — see Known Limitations. Pass rate applies to resolved checks only (88/88 = 100%).
Transparency about gaps is essential for accessibility compliance. The following are known limitations that may affect conformance in specific contexts.
wcag-audit.py) reports 20 out of 108 checks as "skipped" because those color pairs reference CSS custom properties that cannot be resolved at build time. The affected pairs are text-on-brand/brand-primary and text-tertiary/bg-primary across 5 newer palettes (Minimal SaaS, AI Futuristic, Gradient Startup, Corporate, Apple Minimal). All 88 resolved checks pass (100% pass rate for resolved checks). Pass status for the 20 skipped checks is confirmed by browser-based testing. A runtime color resolver is planned to eliminate the remaining skipped checks.