# Accessibility Default target: WCAG 2.2 AA. For government, healthcare, finance, or other regulated contexts: AAA on specific criteria (verify with the user). Don't wait for a retrofit — apply during build. This is a baseline for all frontend work, not just interactive components. ## Color Contrast **WCAG AA thresholds:** - Normal text (< 18pt / < 14pt bold): **4.5:1** minimum - Large text (≥ 18pt or ≥ 14pt bold): **3:1** minimum - UI components and graphics (borders, icons, focus indicators): **3:1** minimum against adjacent colors - Decorative or disabled elements are exempt — but a "disabled" button the user might still try to click is NOT decorative **Practical:** - Use a checker during palette lock-in (WebAIM Contrast Checker, or `npx check-color-contrast`) - Light text on saturated backgrounds (e.g., white on red-500) often fails — check, don't assume - Gradient backgrounds mean text contrast varies across the gradient — check against the *worst-case* point under the text - Ambient/atmospheric effects (dust, grain overlays, gradient meshes) can push borderline contrast below the line — verify after the effect is applied ## Keyboard **Every interactive element reachable via keyboard alone.** Test by putting away the mouse and Tab / Shift-Tab / Enter / Space / arrow keys through the interface. - Focus order follows visual order (not DOM order if CSS reorders) - `Tab` moves between controls; `Enter` / `Space` activates buttons and links; `Esc` dismisses modals/menus; arrow keys navigate within composite widgets (menus, radio groups, sliders) - Custom controls (non-native buttons, non-native select): implement full keyboard behavior, not just `onClick` - Skip-to-content link at the top of every page — invisible until focused **Focus visibility:** - The default browser focus ring is ugly but functional. Don't delete it without a replacement. - Custom focus styles need ≥ 3:1 contrast against the adjacent background - `:focus-visible` (not `:focus`) for keyboard-only focus rings — lets mouse clicks stay clean without losing keyboard clarity **Focus not obscured (WCAG 2.2):** - A focused element must not be fully hidden behind sticky headers, footers, or other overlays. Sticky top bars are the usual culprit — they cover the control the user just tabbed to. - `scroll-margin-top` on focusable elements, or `scroll-padding-top` on the scroll container, keeps the focused item clear of a fixed header. **Target size (WCAG 2.2):** - Interactive targets are at least 24x24 CSS pixels, or have enough surrounding spacing that a 24px circle centered on the target doesn't overlap a neighbor's. - Exceptions: inline links in a sentence, targets sized by the user agent, or an equivalent control of adequate size elsewhere on the page. - Dense or maximalist layouts don't get a pass — cramped tap targets fail on touch and for users with motor impairments. ## Semantic HTML Prefer native elements over `
`. Native buttons, links, form controls, and landmarks come with keyboard behavior, focus management, and screen reader semantics for free. **Landmarks:** - `
`, `