{"description":"Standalone accessibility contract: WCAG 2.2 AA target, value-level rules, automated enforcement method, manual review checklist, anti-patterns, and pass/fail criteria.","objective":"Give a future agent enough structure to start from the main URL and understand how to inspect, plan, build, validate, and improve a serious website without needing prior chat context.","accessibility":{"objective":"Make accessibility a versioned, value-level contract checked on every run, not a heuristic scattered across other files.","why":"Accessibility failures exclude real users and carry legal risk, and they are invisible to authors who navigate by mouse on large screens. A contract with named values and an automated gate catches the regressions that intent alone never does.","target":"WCAG 2.2 AA","enforcement":{"command":"npm run qa:browser","method":"axe-core runs with wcag2a, wcag2aa, wcag21a, wcag21aa, wcag22aa, and best-practice tags on every route and viewport; critical/serious violations fail the build with rule IDs and node targets. Keyboard operability is verified by tabbing through every desktop route. Landmark, accessible-name, alt, duplicate-ID, and focus-style heuristics run on every page.","evidencePath":"reports/browser/browser-visual-report.json","automatedCoverageCaveat":"Automated scanning catches roughly a third of WCAG failures. The manual review checklist below is part of the contract, not optional extra credit."},"valueRules":[{"id":"text-contrast","value":"4.5:1 minimum for body text, 3:1 for large text (24px+, or 18.5px+ bold) and UI component boundaries","wcag":"1.4.3 / 1.4.11","checkedBy":"axe color-contrast rule on every route/viewport"},{"id":"target-size","value":"24x24 CSS px minimum for interactive targets, or equivalent spacing exceptions","wcag":"2.5.8 (WCAG 2.2)","checkedBy":"axe target-size rule under the wcag22aa tag"},{"id":"focus-visible","value":"Every focusable element shows a visible focus indicator (outline or box-shadow); keyboard tab order reaches every interactive control","wcag":"2.4.7 / 2.4.11","checkedBy":"Live keyboard pass per desktop route recording focus stops and indicator visibility"},{"id":"one-main-landmark","value":"Exactly one main landmark, at least one nav landmark, skip link as first focusable element","wcag":"1.3.1 / 2.4.1","checkedBy":"Landmark heuristics per page plus visible skip-link in the base layout"},{"id":"accessible-names","value":"Zero links, buttons, or form controls without an accessible name; zero images without alt attributes","wcag":"1.1.1 / 4.1.2","checkedBy":"Per-page heuristics plus axe name rules"},{"id":"scrollable-region-focus","value":"Any scrollable region is keyboard-focusable with a role and accessible name","wcag":"2.1.1","checkedBy":"axe scrollable-region-focusable; the repo's table-wrap pattern carries tabindex, role, and aria-label"},{"id":"reduced-motion","value":"No animation is load-bearing; any future motion must respect prefers-reduced-motion","wcag":"2.3.3","checkedBy":"Design-system motion rules; currently trivially satisfied by a zero-animation baseline"},{"id":"language-and-zoom","value":"html lang is set; content reflows without horizontal scroll at mobile widths (proxy for 400% zoom)","wcag":"3.1.1 / 1.4.10","checkedBy":"SEO QA lang check plus browser QA overflow checks at 390px"}],"manualReviewChecklist":["Read each new page with a screen reader or accessibility-tree inspector; heading order must tell the page's story without visual styling.","Operate every interactive flow keyboard-only, including escape paths.","Check color is never the only signal for state or meaning.","Check link text makes sense out of context (no bare 'learn more').","Re-test after any design-token change that touches color or type scale."],"antiPatterns":[{"id":"scan-only-confidence","issue":"Treating a clean axe scan as full WCAG compliance.","fix":"Run the manual checklist; automated coverage is partial by design."},{"id":"decorative-focus-removal","issue":"Removing focus outlines for aesthetics.","fix":"Style focus indicators; never remove them."},{"id":"alt-noise","issue":"Stuffing alt text with keywords or repeating captions.","fix":"Alt text describes function or content; decorative images get empty alt."},{"id":"fake-buttons","issue":"Click handlers on divs/spans.","fix":"Use button and a elements; semantics are the accessibility API."}],"qaGates":["npm run qa:browser","npm run qa:all"],"passCriteria":["Zero critical or serious axe violations across all routes and viewports under the 2.2 tag set.","Every desktop route is keyboard-operable with visible focus indicators.","All landmark, name, alt, and duplicate-ID heuristics pass.","Manual review checklist completed for new or redesigned pages."],"failCriteria":["Any critical/serious axe violation.","Any route with fewer than two keyboard focus stops.","Missing main landmark, unnamed interactive elements, or undimensioned focus traps."],"objectiveAlignment":"Moves accessibility from scattered heuristics to a versioned WCAG 2.2 AA contract with measured enforcement and honest coverage limits."}}