diff --git a/craft/README.md b/craft/README.md index 7c9564222..16e17aaf0 100644 --- a/craft/README.md +++ b/craft/README.md @@ -66,6 +66,7 @@ A purely behavioral craft file (state-coverage, animation-discipline) is guidanc | `anti-ai-slop.md` | `anti-ai-slop` | Marketing pages, landing pages, decks | | `state-coverage.md` | `state-coverage` | Any skill with stateful UI (dashboards, mobile apps, forms, list/table views) | | `animation-discipline.md` | `animation-discipline` | Any skill that ships motion: mobile apps, multi-screen flows, gamified UI, transitions, microinteractions | +| `accessibility-baseline.md` | `accessibility-baseline` | Any skill that ships interactive UI: dashboards, forms, mobile flows, anything with focus/labels/keyboard paths | **Partial-stateful skills.** A skill that's mostly static but contains an embedded form, data table, or query surface should opt in. State-coverage rules apply to the stateful component, not the whole page. diff --git a/craft/accessibility-baseline.md b/craft/accessibility-baseline.md new file mode 100644 index 000000000..388e70953 --- /dev/null +++ b/craft/accessibility-baseline.md @@ -0,0 +1,201 @@ +# Accessibility baseline craft rules + +Universal rules for the legal floor of accessibility plus the craft +commitments that go beyond it. The active `DESIGN.md` decides brand +appearance; this file decides which rules an artifact has to clear +before it ships. + +> Grounded in primary sources: WCAG 2.2 Understanding pages, +> ISO/IEC 40500:2025, ADA Title II 2024 + 2026 IFR, EN 301 549 v3.2.1, +> WAI-ARIA 1.3 + AccName 1.2 + Core AAM 1.2, WebAIM Million 2026 +> (February 2026 crawl), A11yn (arXiv 2510.13914), APCA W3C silver +> branch. + +## Prior art and scope + +Existing OSS a11y guidance for AI agents (`fecarrico/A11Y.md`, +`awesome-copilot agents/accessibility.agent.md`, +`Community-Access/accessibility-agents`) tends to inline a checklist of +WCAG SCs without versioning the legal floor or specifying which +constraints survive on iOS / Android / Flutter. This file scopes +narrower: the compliance floor an OD artifact must clear, with +jurisdiction notes and native-mobile parity. Heuristic rules and +linter-checked items live in sibling craft files +(`anti-ai-slop.md`, `state-coverage.md`); WCAG SC numbers map to +specific rules below rather than being re-listed. + +## The legal floor changes by jurisdiction + +- **EU (EAA, enforcement live 2025-06-28):** EN 301 549 v3.2.1 is the OJ-cited harmonised standard; it references **WCAG 2.1 AA**. EN 301 549 v4.1.1 (which incorporates WCAG 2.2's nine new SCs) is OJ-citation-targeted late 2026 / 2027. Until then, EAA references WCAG 2.1. The Web Accessibility Directive (WAD, EU 2016/2102) covers public-sector bodies separately and also points at EN 301 549. +- **US public sector — ADA Title II 2024 final rule:** **WCAG 2.1 AA**. The 2026-04-20 IFR slipped deadlines: 2027-04-26 for jurisdictions with population ≥ 50,000; 2028-04-26 for sub-50,000 and special districts. +- **US federal procurement — Section 508 (Revised 508 Standards):** harmonised with EN 301 549 → references **WCAG 2.0 AA** in the current published rev. The Access Board has WCAG 2.x updates in flight; until they ship, federal IT procurement floor is WCAG 2.0. +- **US private sector — ADA Title III:** no federal regulation specifies a technical standard. Settlements and DOJ guidance routinely cite **WCAG 2.1 AA** as the de-facto target, but the legal mechanism is case-by-case, not rule-based. +- **ISO/IEC 40500:2025** (October 2025) ratified WCAG 2.2 verbatim. Does not by itself change EU or US legal floors. + +**Practical rule for craft:** target **WCAG 2.2 AA** as the working +ceiling. It clears the WCAG 2.1 AA legal floor in both jurisdictions +and prepares for v4.1.1. Anything below 2.2 AA is craft debt. + +## Color contrast + +| Pair | WCAG 2.x AA minimum | +|---|---| +| Normal text below 18 pt regular / 14 pt bold (covers most body and UI text) | 4.5:1 | +| Large text (≥18 *pt* regular ≈24 px, or ≥14 *pt* bold ≈18.5 px) | 3:1 | +| Non-text UI components and graphical objects | 3:1 | +| Focus indicator vs adjacent and unfocused state | 3:1 | + +Thresholds are **inclusive** — exactly 4.5:1 or 3:1 passes. Don't round +up: 2.999:1 fails because rounding is not a permitted mechanism. + +"Large text" means **18 pt** regular, not 18 px. 18 px regular needs +4.5:1; 14 pt bold (≈18.5 px) qualifies for 3:1, 14 px bold does not. + +**APCA as a parallel design check.** APCA's Lc value catches font-weight +and stem-thickness effects that WCAG 2.x luminance ratios miss. Body +copy at Lc ≥60 is a reasonable parallel pass; APCA's actual lookup +table is size- and weight-dependent (heavier weights at larger sizes +clear at lower Lc, thin small text needs Lc ≥75+). APCA is not part +of WCAG, EN 301 549, ADA, or Section 508 compliance as of 2026-05 — +keep WCAG 2.2 AA as the compliance floor and treat APCA as +design-review only. If you ship APCA tooling, use the `apca-w3` +package; the SAPC repo is non-commercial. + +## Touch targets + +| Bar | SC | Size | +|---|---|---| +| AA (legal floor) | 2.5.8 Target Size (Minimum) | **24×24 CSS px** | +| AAA (craft commitment) | 2.5.5 Target Size (Enhanced) | 44×44 CSS px | +| iOS HIG | — | 44×44 pt | +| Material 3 | — | 48×48 dp | + +WCAG 2.5.8 lists five exceptions where the 24×24 minimum doesn't +apply: **Spacing** (a 24-CSS-px exclusion circle around the target +doesn't intersect adjacent ones), **Equivalent** (an alternative +control of sufficient size achieves the same function), **Inline** +(target sits inside a sentence, e.g. links in body copy), **User +agent control** (browser default like a native scrollbar), and +**Essential** (the smaller size is required to convey information, +e.g. a map pin). The Spacing exception is the one icon-button +toolbars rely on; the others are narrower than they read and +shouldn't be used to justify undersized primary actions. + +## Focus visibility + +Removing the focus outline via CSS is a **triple failure**: 1.4.11 +Non-text Contrast, 2.4.7 Focus Visible, and 2.4.13 Focus Appearance +(AAA). Use `:focus-visible` for keyboard users; suppress the outline +for mouse clicks only when an alternative non-color affordance exists. + +For AAA (2.4.13): indicator area must equal at least a 2 CSS px +perimeter of the component, contrast ≥3:1 between focused and +unfocused states. A 1-px outline at 3:1 doesn't qualify. + +## Form input labels + +WebAIM Million 2026 (which uses WAVE, not axe-core): **51% of top 1M +home pages have at least one missing form-input label; 33.1% of all +6.9M inputs are unlabeled**. The page-level rate moved from 48.2% +(2025) to 51% (2026) — missing-label prevalence is one of the few +categories WebAIM explicitly calls out as rising in 2026, against an +overall errors-per-page count of 56.1. + +Default form-error wiring (WCAG 2.2 + ARIA APG): + +```html + + +Used for receipts only. +Email must include @ and a domain. +``` + +`aria-describedby` is the production default; `aria-errormessage` has +incomplete screen-reader support as of 2026-05 (full on NVDA, partial +on JAWS / VoiceOver / TalkBack) — treat as progressive enhancement. + +WCAG 3.3.7 Redundant Entry is **Level A** (legal floor). Re-asking for +data the user already entered "in the same process" fails unless the +site auto-populates or offers a selectable shortcut. Browser autofill +does not satisfy it. + +## Keyboard operability and semantic structure + +Visual contrast and labelled inputs don't matter if a keyboard or +screen-reader user can't reach the control or parse the page. The +bullets below are Level A / AA WCAG essentials plus a small set of +structural conventions OD treats as craft commitments. WCAG levels +are noted per item. + +- **Tab reachability** (2.1.1 Keyboard, Level A): every interactive element must be reachable and operable via keyboard. `tabindex="-1"` removes from the tab order; `tabindex` values >0 break document order and should not be used. (2.1.3 No Exception extends 2.1.1 to AAA by removing the underlying-function exception.) +- **Activation keys** (2.1.1, Level A): `