# Accessibility Checklist Template

**Source:** docs/specs/2026-05-31-wcag-accessibility.md (spec 115)

Every new UI module spec **must** embed the `## Accessibility` section below verbatim.
Module specs that omit this section are **incomplete** and may not be implemented until it is added.

---

## How to use this template

Copy the block below into your module spec's `## Accessibility` section. Check off
items as implementation proceeds. Unchecked items remaining at PR time are blocking
unless explicitly marked `N/A — <reason>`.

---

## Accessibility

- [ ] All interactive elements keyboard-reachable (Tab/Arrow)
- [ ] Focus visible on all interactive elements
- [ ] ARIA labels on icon-only buttons
- [ ] Form errors associated via `aria-describedby` (see design-system spec)
- [ ] Reduced-motion safe (no essential animations)
- [ ] Color contrast checked in both dark/light themes
- [ ] Screen reader tested or marked "pending SR test" with issue reference
- [ ] Drag-and-drop (if present): keyboard sensor configured (see tasks-board-engine)
- [ ] Charts (if present): aria-label + data table fallback (see reports-analytics)
- [ ] Tiptap editors (if present): Content Security pattern applied (see kb-article-editor)

**Additional patterns:**

- [ ] Charts have `role="figure"` + visually-hidden data table alternative
- [ ] Rich text editors (Tiptap): `role="textbox"` `aria-multiline="true"`, toolbar has `role="toolbar"`
- [ ] File upload zones: `role="button"` `tabindex="0"`, keyboard operable, progress announced via `role="progressbar"`
- [ ] Drag-and-drop: `KeyboardSensor` configured, `DndContext` `announcements` prop defined
- [ ] Live-updating counters: `aria-label` updated periodically; do NOT use `aria-live="assertive"` on counters
- [ ] Data tables with sortable columns: `aria-sort="ascending|descending|none"` on headers; sort change announced via `aria-live="polite"`
- [ ] Date pickers: full keyboard navigation (Arrow/Page/Home/End), `aria-label` on each day cell

---

## Enforcement notes

- This checklist is required — not optional — for every new UI module spec.
- `--ink-faint` is NOT WCAG-compliant for readable text (contrast < 4.5:1). Use only for
  decorative content, disabled controls, and placeholders.
- Never suppress focus styles globally (`outline: none` without a `:focus-visible` alternative
  is a **code-review gate violation**). Any PR suppressing focus must restore visibility via
  `:focus-visible` in the same changeset.
- The global reduced-motion media block (packages/ui/src/tokens/index.css) neutralizes
  CSS animations. Components that show a *different element tree* under reduced motion
  (Spinner → static text, Toast → instant placement) must use the `useReducedMotion` hook
  from `@zync/ui`.
