Accessibility annex
Component contracts & pre-launch checklist.
Internal-facing documentation used by the production team. Lists the accessibility contract each component must meet, and the checklist run before any page goes live.
- Navigation: reachable by keyboard tab; current page marked with
aria-current="page"; mobile drawer has aria-expanded toggle. - Buttons: use
<button>or<a>, never divs. Visible focus ring. 3px outline + 2px offset. - Forms: every input has a label, either visible or via aria-label. Inline errors per field plus a top-of-form error summary;
aria-describedbylinking each input to its error. - Schedule: times announce their timezone. The day-tab pattern uses
role="tab"/role="tabpanel"; arrow-key navigation across tabs. - Cards: if the whole card is clickable, use a nested
<a>that wraps the heading — the card-as-link pattern that screen readers can announce. - Decorative media:
aria-hidden="true"on decorative SVGs and patterns. Alt-empty on decorative images. - Live regions: error summaries are
role="alert"; timezone-change confirmations use polite live-regions.
- Run axe-core on every template; zero violations.
- Keyboard-only test of every flow (signup, ticket, schedule, drawer).
- Screen reader sweep: VoiceOver/Safari + NVDA/Firefox + JAWS/Chrome.
- Zoom to 200% — no horizontal scroll, no clipped content.
- Reduce-motion preference: no animation runs.
- Forced-colors (Windows High Contrast): all interactive elements still distinguishable.
- Form error states: tab to each field, submit empty, confirm field gets focus + error summary appears.
- Skip-link works from the very first tab press.
- Live captioner contracted; backup auto-captioning on as fallback.
- BSL interpreter contracted for any session by request (4-week lead time).
- Transcripts uploaded to each session page within 7 days.
- Recordings include captions and audio descriptions where useful.
- Quiet/sensory-relief room signposted in every block.
- Access-requirement form linked from every ticket confirmation.
