Accessibility gate (WCAG 2.2 AA, verified)
Make a web UI accessible and prove it — conformance is gated by checks that
run (axe-core, scripted keyboard/reflow audits) plus a mandatory human checklist,
not by assertion.
Core principle
Conformance is measured, not claimed. The loop is: scan → triage by severity
→ fix the root cause → re-scan, until the automated gate is green; then complete
the manual + screen-reader checklist before sign-off.
Be honest about scope (this is the rule that keeps the skill correct):
automated tools catch only ~30–50% of WCAG issues. A green scan is necessary,
not sufficient. Never report "WCAG AA conformant" on automated results alone —
report "0 blocking automated violations; manual checklist completed and
attested." → references/01-standards-and-scope.md
When to use vs. not
- Use for: auditing/fixing accessibility of a site, app, page, or component;
adding an a11y CI gate; keyboard/contrast/ARIA/screen-reader review; WCAG /
ADA / Section 508 / EAA remediation.
- Not for: native-mobile-only a11y (different tooling), or general UI design with
no accessibility ask.
Inputs to gather first
- What to audit — URL(s)/routes, and key interactive states (menus, modals,
tabs). The app must be runnable locally (prefer the production build).
- Target level — default WCAG 2.2 AA; confirm if a different standard
(2.1 AA, AAA, Section 508) is required.
- Severity bar — default gate blocks on
critical + serious; tighten to
include moderate for strict sign-off.
Workflow
Load each reference when you reach its step.
Set the standard & scope. Confirm WCAG 2.2 AA (or other), and that
automated ≠ full conformance. → references/01-standards-and-scope.md
Set up the harness. Copy scripts/ into the project, install deps,
configure routes + interactive states. → references/02-running-the-audit.md
npm i -D @playwright/test playwright @axe-core/playwright && npx playwright install chromium
cp scripts/a11y.config.example.json scripts/a11y.config.json # edit baseUrl, routes, states
Run the automated gate against the running app; triage by severity. → references/03-automated-coverage.md
npm run build && npm run preview &
npm run a11y:scan # axe gate -> a11y-report/axe-summary.md
npm run a11y:keyboard # keyboard traps / reachability / focus
npm run a11y:reflow # 320px reflow (WCAG 1.4.10)
Fix root causes, semantic HTML first, ARIA only when needed ("no ARIA is
better than bad ARIA"); re-scan after each fix. → references/05-remediation-patterns.md
Verify keyboard & focus by hand for custom widgets and SPA navigation —
the part automation covers least. → references/04-keyboard-and-focus.md
Complete the manual + screen-reader checklist (VoiceOver/NVDA, zoom, text
spacing, reduced motion, media). → references/06-manual-and-screen-reader.md
Gate in CI and record the attestation. → references/07-wcag22-aa-checklist.md
npm run a11y:test # CI-grade gate + HTML report (npm run a11y:report)
What's in this skill
scripts/a11y-scan.mjs — axe-core over every route + interactive state; the gate backbone. Writes axe-summary.md + axe-report.json, exits non-zero on blocking impacts.
scripts/keyboard-audit.mjs — Tab-walks each route: keyboard traps (hard fail), unreachable controls, missing focus indicators (review).
scripts/reflow-check.mjs — 320px reflow check (WCAG 1.4.10), names the overflowing elements.
scripts/a11y.spec.ts + playwright.config.ts — CI gate with an HTML report and axe JSON attached.
scripts/lib/ — config loader + browser/state helpers.
scripts/a11y.config.example.json — routes, states, tags, severity gate, reflow viewport.
references/01–07 — standards, running the audit, automated coverage limits, keyboard/focus, remediation patterns, the manual/screen-reader checklist, and the full WCAG 2.2 AA checklist with per-SC test method.
Definition of done
Guardrails — avoid these mistakes
- Don't claim "WCAG conformant" from a green scan. State "0 blocking
automated violations; manual checklist complete." Overclaiming is the cardinal
error here.
- Semantic HTML first.
<button>/<a>/<label>/<select> give you
keyboard, focus, and roles for free. No ARIA is better than bad ARIA.
- Never remove focus outlines without a visible replacement (use
:focus-visible).
- Scan interactive states, not just initial load — most real violations hide
in opened menus/modals.
- Don't suppress a rule to go green —
disableRules only for verified false
positives, with a written reason.
- Audit the production build, not the dev server (overlays cause false
positives).
- Placeholders are not labels; color alone is not information.
1---2name: a11y-gate3description: Audit and fix web accessibility to WCAG 2.2 AA, gated by automated checks that actually run — axe-core via Playwright for violations, scripted keyboard/focus and reflow audits, plus a mandatory manual + screen-reader checklist. Use when the user wants to make a site/app/page accessible, fix a11y or WCAG/ADA/Section 508 issues, add an accessibility CI gate, run an axe/Lighthouse-style audit, check keyboard navigation, color contrast, ARIA, screen-reader support, or remediate accessibility violations. Triggers: "accessibility", "a11y", "WCAG", "ADA compliance", "screen reader", "keyboard navigation", "axe audit".4license: MIT5---67# Accessibility gate (WCAG 2.2 AA, verified)89Make a web UI accessible and **prove it** — conformance is gated by checks that10run (axe-core, scripted keyboard/reflow audits) plus a mandatory human checklist,11not by assertion.1213## Core principle1415**Conformance is measured, not claimed.** The loop is: scan → triage by severity16→ fix the root cause → re-scan, until the automated gate is green; then complete17the manual + screen-reader checklist before sign-off.1819**Be honest about scope (this is the rule that keeps the skill correct):**20automated tools catch only ~30–50% of WCAG issues. A green scan is **necessary,21not sufficient**. Never report "WCAG AA conformant" on automated results alone —22report "0 blocking automated violations; manual checklist completed and23attested." → `references/01-standards-and-scope.md`2425## When to use vs. not2627- Use for: auditing/fixing accessibility of a site, app, page, or component;28 adding an a11y CI gate; keyboard/contrast/ARIA/screen-reader review; WCAG /29 ADA / Section 508 / EAA remediation.30- Not for: native-mobile-only a11y (different tooling), or general UI design with31 no accessibility ask.3233## Inputs to gather first34351. **What to audit** — URL(s)/routes, and key interactive states (menus, modals,36 tabs). The app must be runnable locally (prefer the production build).372. **Target level** — default **WCAG 2.2 AA**; confirm if a different standard38 (2.1 AA, AAA, Section 508) is required.393. **Severity bar** — default gate blocks on `critical` + `serious`; tighten to40 include `moderate` for strict sign-off.4142## Workflow4344Load each reference when you reach its step.45461. **Set the standard & scope.** Confirm WCAG 2.2 AA (or other), and that47 automated ≠ full conformance. → `references/01-standards-and-scope.md`48492. **Set up the harness.** Copy `scripts/` into the project, install deps,50 configure routes + interactive states. → `references/02-running-the-audit.md`51 ```bash52 npm i -D @playwright/test playwright @axe-core/playwright && npx playwright install chromium53 cp scripts/a11y.config.example.json scripts/a11y.config.json # edit baseUrl, routes, states54 ```55563. **Run the automated gate** against the running app; triage by severity. → `references/03-automated-coverage.md`57 ```bash58 npm run build && npm run preview &59 npm run a11y:scan # axe gate -> a11y-report/axe-summary.md60 npm run a11y:keyboard # keyboard traps / reachability / focus61 npm run a11y:reflow # 320px reflow (WCAG 1.4.10)62 ```63644. **Fix root causes**, semantic HTML first, ARIA only when needed ("no ARIA is65 better than bad ARIA"); re-scan after each fix. → `references/05-remediation-patterns.md`66675. **Verify keyboard & focus** by hand for custom widgets and SPA navigation —68 the part automation covers least. → `references/04-keyboard-and-focus.md`69706. **Complete the manual + screen-reader checklist** (VoiceOver/NVDA, zoom, text71 spacing, reduced motion, media). → `references/06-manual-and-screen-reader.md`72737. **Gate in CI** and record the attestation. → `references/07-wcag22-aa-checklist.md`74 ```bash75 npm run a11y:test # CI-grade gate + HTML report (npm run a11y:report)76 ```7778## What's in this skill7980- `scripts/a11y-scan.mjs` — axe-core over every route + interactive state; the gate backbone. Writes `axe-summary.md` + `axe-report.json`, exits non-zero on blocking impacts.81- `scripts/keyboard-audit.mjs` — Tab-walks each route: keyboard traps (hard fail), unreachable controls, missing focus indicators (review).82- `scripts/reflow-check.mjs` — 320px reflow check (WCAG 1.4.10), names the overflowing elements.83- `scripts/a11y.spec.ts` + `playwright.config.ts` — CI gate with an HTML report and axe JSON attached.84- `scripts/lib/` — config loader + browser/state helpers.85- `scripts/a11y.config.example.json` — routes, states, tags, severity gate, reflow viewport.86- `references/01–07` — standards, running the audit, automated coverage limits, keyboard/focus, remediation patterns, the manual/screen-reader checklist, and the full WCAG 2.2 AA checklist with per-SC test method.8788## Definition of done8990- [ ] `a11y:scan` reports **0** `critical`/`serious` violations across all routes91 **and** key interactive states (menus, modals open).92- [ ] `a11y:keyboard` finds **no keyboard traps**; reachability + focus-visibility93 findings reviewed; custom widgets manually operated.94- [ ] `a11y:reflow` passes at 320px (documented 2D exceptions only).95- [ ] axe **`incomplete`** items reviewed (contrast over images, etc.).96- [ ] Manual + screen-reader checklist (`06`) completed and attested.97- [ ] CI runs `a11y:test`; report archived; attestation recorded.9899## Guardrails — avoid these mistakes100101- **Don't claim "WCAG conformant" from a green scan.** State "0 blocking102 automated violations; manual checklist complete." Overclaiming is the cardinal103 error here.104- **Semantic HTML first.** `<button>`/`<a>`/`<label>`/`<select>` give you105 keyboard, focus, and roles for free. **No ARIA is better than bad ARIA.**106- **Never remove focus outlines** without a visible replacement (use107 `:focus-visible`).108- **Scan interactive states, not just initial load** — most real violations hide109 in opened menus/modals.110- **Don't suppress a rule to go green** — `disableRules` only for verified false111 positives, with a written reason.112- **Audit the production build**, not the dev server (overlays cause false113 positives).114- **Placeholders are not labels**; color alone is not information.