| name | accessibility-review |
| description | Systematic WCAG 2.1 AA accessibility audit with confidence-based reporting. Scans UI components for keyboard, screen reader, and visual accessibility issues. Use for pre-release audits or after major UI changes. |
| category | process |
| triggers | ["accessibility audit","WCAG check","a11y review","screen reader","keyboard navigation"] |
Accessibility Review
Purpose: Systematic accessibility audit against WCAG 2.1 AA
Mode: Read-only by default — fixes require approval
Usage: /accessibility-review [scope flags] [component or page]
Iron Laws
- ACCESSIBILITY IS NOT OPTIONAL — Every interactive element must be keyboard accessible. Every image must have alt text. Every form must have labels. No exceptions, no "we'll add it later."
- TEST WITH REAL TOOLS — Do not guess at accessibility. Run axe-core, test with keyboard navigation, verify screen reader announcements. Assumptions are not evidence.
- SEVERITY REFLECTS USER IMPACT — A missing skip link is not the same as a completely inaccessible form. Prioritize by how many users are blocked and how severely.
Constraints
- Confidence-based reporting — HIGH: report, MEDIUM: flag as needs verification, LOW: do not report
- Don't invent issues — If nothing found, say "clean review" (this is a valid outcome)
- Research the entire codebase before reporting — check for shared components, theme providers, layout wrappers
- No framework FUD — Don't flag things the framework already handles (e.g., Next.js
<Image> requires alt, React Native accessibility props)
- Evidence required — Every finding must include the specific code AND explain which users are affected
Note: Command examples below use generic placeholders. Use the project's package manager (detect from lockfile: pnpm-lock.yaml -> pnpm, yarn.lock -> yarn, bun.lockb -> bun, package-lock.json -> npm).
When to Use
- UI component review (new or modified)
- Pre-release accessibility audit
- After major UI changes or redesigns
- New page or feature with interactive elements
- WCAG compliance check before launch
When NOT to Use
- Non-visual code (APIs, CLI tools, backend services)
- Purely design review (colors, spacing) — ask designer
- Performance audit — use
/validate
- Security review — use
/security-review
Scope Flags
| Flag | Description |
|---|
--files=<paths> | Review specific files or directories |
--wcag-level=<A|AA|AAA> | Target conformance level (default: AA) |
--component=<name> | Review a specific component and its variants |
| (none) | Review all UI files (will ask to confirm scope) |
Confidence Levels
| Level | Criteria | Action |
|---|
| HIGH | Confirmed violation + code evidence + no mitigation found | Report as finding |
| MEDIUM | Possible violation but shared component may handle it, or runtime behavior unclear | Report as "needs verification" |
| LOW | Theoretical concern, framework-mitigated, or requires unlikely conditions | Do not report |
Do Not Flag
Skip these — they produce noise, not signal:
- Test files and test fixtures
- Storybook decorator wrappers (review the stories themselves, not decorators)
- Server-only code with no rendered output
- Components that are never rendered directly (abstract base components)
- Framework-provided components with built-in accessibility (e.g., Radix UI, Headless UI) — unless ARIA attributes or keyboard handlers have been overridden (see "Accessible Library Misuse Detection" below)
- Decorative images that already have
alt=""
Accessible Library Misuse Detection
If the project uses accessible component libraries (Radix, Headless UI, Reach UI, Ark UI):
- Check that ARIA attributes haven't been overridden or removed — Look for props that replace or nullify the library's built-in
role, aria-*, or tabIndex attributes
- Check that keyboard handlers haven't been replaced — Look for
onKeyDown, onKeyUp overrides that prevent the library's default keyboard behavior
- These libraries provide accessibility by default — misuse is worse than not using them — A custom
onKeyDown that swallows events or a removed aria-expanded breaks the accessibility the library provides, and developers may falsely assume the component is accessible because they are using an accessible library
If no accessible component library is detected, note the absence and recommend one if custom interactive widgets (dropdowns, modals, tabs, etc.) are found in the codebase.
Workflow
Phase 1: Scope
Identify what to review:
find . -type f \( -name "*.tsx" -o -name "*.jsx" -o -name "*.vue" -o -name "*.svelte" \) | head -100
- Categorize UI files — Pages, layouts, components, modals, forms
- Check for existing a11y setup:
- Testing:
jest-axe, @axe-core/playwright, @axe-core/react
- Linting:
eslint-plugin-jsx-a11y, eslint-plugin-vuejs-accessibility
- Component library: Does it have built-in a11y? (Radix, Headless UI, Ark UI)
- Note the UI framework — React, Vue, Svelte, Angular, etc.
- Identify WCAG level — A, AA (default), or AAA
If scope is large (>30 components), present categories and ask user which to focus on.
- Review at two levels:
- (a) Component level — Individual ARIA roles/states, labels, alt text, contrast, keyboard handlers within each component
- (b) Layout level — Focus order across the page, skip-to-content navigation, landmark regions (
<main>, <nav>, <aside>, <header>, <footer>), heading hierarchy spanning the entire page (not just within one component), and modal/dialog focus management in context of the full page
Both levels are required. Component-level issues (e.g., missing ARIA on a dropdown) and layout-level issues (e.g., no skip link, broken focus order between components, missing landmarks) are equally important.
Phase 2: Automated Scan
Review code for common violations (see references/wcag-checklist.md for full WCAG criterion reference, references/a11y-remediation-patterns.md for fix patterns by component type):
Critical checks (P0 candidates):
- Interactive elements not reachable by keyboard (
div with onClick but no role/tabIndex)
- Form inputs without associated labels (
<label> or aria-label/aria-labelledby)
- Images without
alt attributes or with non-descriptive alt text (generic values like "image", "photo", "icon", "picture", "img", or the filename — these fail WCAG 1.1.1 because they do not convey the content or purpose)
- Missing
lang attribute on <html>
High-priority checks (P1 candidates):
- Color contrast issues (if theme tokens or CSS variables are available)
- Missing document/page
<title>
- Heading hierarchy violations (skipping levels, multiple
<h1>)
- ARIA roles used incorrectly (e.g.,
role="button" without keyboard handler)
- Missing
aria-live regions for dynamic content updates
Medium-priority checks (P2 candidates):
- Missing skip-to-content link in layouts
- Focus order that doesn't match visual order
- Missing focus styles (
:focus-visible or :focus)
- Modals/dropdowns without Escape key dismissal
Enhancement checks (P3 candidates):
prefers-reduced-motion not respected for animations
- Decorative images using descriptive alt instead of
alt=""
- ARIA attributes that could be simplified with semantic HTML
- Missing
autocomplete on form fields
If a11y testing tools are configured, suggest running them:
<pkg-manager> run test -- --grep "a11y\|accessibility\|axe"
<pkg-runner> playwright test --grep "a11y"
<pkg-runner> eslint --rule '{"jsx-a11y/*": "error"}' src/
Detect the project's package manager from lockfile: pnpm-lock.yaml -> pnpm/pnpm exec, yarn.lock -> yarn/yarn, bun.lockb -> bun/bunx, package-lock.json -> npm/npx.
Tooling Recommendations
If a11y tooling is NOT already configured, recommend adding it based on the project's stack:
| Tool | When to Recommend | What It Catches |
|---|
eslint-plugin-jsx-a11y | React/JSX projects | Missing alt, missing labels, invalid ARIA attributes (static analysis) |
eslint-plugin-vuejs-accessibility | Vue projects | Same as above for Vue templates |
axe-core / @axe-core/react | Any web project | Runtime accessibility violations (rendered DOM analysis) |
jest-axe | Projects using Jest | Accessibility assertions in unit tests |
@axe-core/playwright | Projects using Playwright | Accessibility checks in E2E tests |
| Lighthouse accessibility audit | Any web project | Chrome DevTools audit for deployed/running pages |
Important: Automated tools catch ~30-40% of accessibility issues. They are excellent at detecting missing attributes, invalid ARIA, and contrast violations, but they cannot verify focus order, keyboard usability, screen reader announcements, or meaningful alt text. Manual review is still essential for full WCAG compliance.
Phase 3: Manual Review
Keyboard Navigation Checklist
Screen Reader Checklist (see references/screen-reader-testing.md for platform-specific commands and detailed testing methodology)
Motion and Visual Checklist
Phase 4: Report
Use P0-P3 severity levels:
| Severity | Definition | Examples |
|---|
| P0 Critical | Users cannot complete a task at all | No keyboard access to submit button, form with no labels, interactive div with no role |
| P1 High | Significant barrier for assistive tech users | Poor color contrast on body text, missing alt on informational images, heading hierarchy broken |
| P2 Medium | Usability degradation but workaround exists | Missing skip link, focus order quirks, no aria-live on toast notifications |
| P3 Low | Enhancement opportunity | Decorative image could use alt="", ARIA could be simplified, autocomplete missing |
Report Format
## Accessibility Review: [scope description]
### Scope
- **Files reviewed:** [count]
- **WCAG level:** [A / AA / AAA]
- **UI framework:** [React / Vue / Svelte / etc.]
- **Existing a11y tooling:** [jest-axe, eslint-plugin-jsx-a11y, etc. or "None detected"]
### HIGH Confidence Findings
#### Finding 1: [WCAG Criterion] — [Issue Summary]
- **Severity:** P0 Critical / P1 High
- **WCAG:** [criterion number and name]
- **Location:** `file.tsx:line`
- **Affected code:**
```tsx
[the actual code]
- User impact: [Who is affected and how — keyboard users, screen reader users, etc.]
- Evidence: [Why no mitigation exists — what was checked]
- Recommended fix:
[specific code fix]
(Repeat for each HIGH finding, or "No HIGH confidence findings.")
MEDIUM Confidence — Needs Verification
These may be real issues but require runtime or manual testing to confirm:
- [WCAG Criterion] —
file.tsx:line — [Why uncertain: "Contrast depends on runtime theme" / "Shared layout may provide skip link"]
(Or "None.")
Summary Table
| # | Severity | WCAG | Issue | Location | Confidence |
|---|
| 1 | P0 | 2.1.1 | No keyboard access on dropdown | Menu.tsx:42 | HIGH |
| 2 | P1 | 1.1.1 | Missing alt text | Hero.tsx:15 | HIGH |
Pre-Conclusion Audit
| Item | Status |
|---|
| Files in scope reviewed | X / Y |
| Keyboard navigation checked | Yes / No |
| Screen reader semantics checked | Yes / No |
| Color and contrast checked | Yes / No |
| WCAG criteria covered | X / [total for level] |
| Shared components checked for mitigations | Yes / No |
Conclusion
[Overall accessibility posture assessment]
Recommendation: [Compliant / Needs P0-P1 fixes before release / Needs deeper audit with assistive technology]
#### Clean Review Template
When no issues are found:
```markdown
## Accessibility Review: [scope]
**Files reviewed:** [count]
**WCAG level:** AA
**Criteria checked:** [count]
**Findings:** None
No accessibility violations found at HIGH or MEDIUM confidence.
This does not guarantee full WCAG compliance — it means static code analysis
did not identify issues in the reviewed scope. Manual testing with assistive
technology is recommended for full conformance verification.
Phase 5: Fix (Optional, With Approval)
After presenting the report:
- Offer to fix P0/P1 issues — "I found [N] critical/high issues. Want me to fix them?"
- GATE: User must approve before any changes — Do not modify files without explicit approval
- Fix in priority order — P0 first, then P1
- Add a11y tests for fixed issues — If jest-axe or similar is available, add regression tests
- Run verification — Confirm fixes don't break existing tests
Acceptance Tests
| ID | Type | Prompt / Condition | Expected |
|---|
| A11-T1 | Positive | "Check accessibility of the login form" | Skill triggers |
| A11-T2 | Positive | "WCAG audit before release" | Skill triggers |
| A11-T3 | Positive | "Screen reader compatibility check" | Skill triggers |
| A11-T4 | Negative | "Fix the broken button" | Does NOT trigger (-> /debug) |
| A11-T5 | Negative | "Review code quality" | Does NOT trigger (-> /review) |
| A11-T6 | Negative | "Check for security vulnerabilities" | Does NOT trigger (-> /security-review) |
| A11-T7 | Boundary | "Review this component for accessibility and usability" | Triggers for accessibility phase only |
Quick Reference
| Task | Command |
|---|
| Review specific files | /accessibility-review --files=src/components/Modal.tsx |
| Review a component | /accessibility-review --component=LoginForm |
| AAA conformance check | /accessibility-review --wcag-level=AAA |
| Full project audit | /accessibility-review |