# Impact Nova — Accessibility (a11y)

**Required.** All Impact Nova components follow the [Component API Charter](../../docs/architecture/COMPONENT_API_CHARTER.md) accessibility rules (CH-34–CH-40). Storybook a11y tests run in CI with `test: 'error'` — violations fail the build.

Impact Nova components are built on **Radix UI**, which provides keyboard navigation, focus management, and ARIA attributes.

---

## 1. Preserve built-in behavior

- **Do not remove or override** keyboard support, focus handling, or ARIA that Radix/Impact Nova provide (e.g. Dialog escape to close, Select arrow keys, DropdownMenu focus trap).
- Use **compound components** as intended (e.g. `DialogContent`, `Select` with `options` API) so semantics and behavior stay correct.

---

## 2. Labels and descriptions

- **Icon-only buttons**: Set `aria-label` (e.g. `<Button size="icon" aria-label="Close">`). Use i18n for the label when possible.
- **Form controls**: Associate labels with inputs (use the component's label prop or a visible `<label>` with correct `htmlFor`). Use `aria-describedby` for hint or error text when provided by the component.
- **Dialogs/Sheets**: Ensure a visible title (e.g. `DialogTitle`, `SheetTitle`) so screen readers announce the purpose.

---

## 3. Keyboard and focus

- **Focus order**: Layout and DOM order should match visual order; avoid positive `tabIndex` unless required for a custom focus flow.
- **Skip links**: For app shell or long pages, consider a "Skip to main content" link at the top (visible on focus).
- **Modals/Sheets**: Focus is trapped and restored by Radix; don't move focus manually unless the component API supports it.

---

## 4. Screen readers and semantics

- Use **semantic HTML** where Impact Nova doesn't replace it (e.g. headings hierarchy `h1` → `h2`, lists for lists).
- **Live regions**: For dynamic messages (toast, success after save), use the toast/alert components so they are announced.
- **Loading**: Prefer `Loader` or `Skeleton` and ensure loading state is communicated (e.g. `aria-busy` or `role="status"` with a message) when implementing custom loading UIs.

---

## 5. Color and contrast

- Use **design tokens** (e.g. `text-content`, `bg-brand`) so contrast follows the design system. Avoid custom colors that reduce contrast.
- Don't rely on color alone for meaning (e.g. pair an icon or text with color for status).

---

## 6. Testing and checks

- **CI**: `npm run test:storybook` runs axe on all stories — must pass before merge.
- Run **Lighthouse** on pages that use Impact Nova to catch missing labels, contrast, or focus issues.
- Test **keyboard-only** navigation (Tab, Enter, Escape, arrows) for dialogs, selects, and menus.
- Verify **screen reader** announcements for critical flows (form errors, success toasts, dialog open/close).

Use `search_best_practices` with query "accessibility" for condensed rules.
