Help us improve
Share bugs, ideas, or general feedback.
From software-engineering
Audit a screen, component, or flow for WCAG 2.2 AA conformance and remediate the findings — keyboard navigation, focus management, screen-reader semantics, contrast, motion, touch targets, error handling, and forms. Covers automated tooling (axe, Lighthouse, Storybook a11y addon) plus the manual passes that automation can't replace. Use this skill any time the user is auditing for accessibility, fixing a specific a11y finding, preparing for an external audit, or asking "is this accessible," even when "WCAG" or "a11y" isn't said. Trigger whenever accessibility is the question so the audit goes beyond the automated tools' false sense of completeness.
npx claudepluginhub bpainter/composable-dxp-claude-marketplace --plugin software-engineeringHow this skill is triggered — by the user, by Claude, or both
Slash command
/software-engineering:software-engineering-a11y-auditThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Accessibility is part of quality, not a compliance overlay. WCAG 2.2 AA is the floor for any project this skill governs. This skill produces both the audit (what's wrong, with severity) and the remediation guidance (how to fix it, in this stack).
Guides technical evaluation of code review feedback: read fully, restate for understanding, verify against codebase, respond with reasoning or pushback before implementing.
Share bugs, ideas, or general feedback.
Accessibility is part of quality, not a compliance overlay. WCAG 2.2 AA is the floor for any project this skill governs. This skill produces both the audit (what's wrong, with severity) and the remediation guidance (how to fix it, in this stack).
A few principles up front:
Pair with software-engineering-shadcn-component (Radix-based primitives give us most of the keyboard and ARIA defaults), software-engineering-nextjs-scaffold (where some semantic decisions live), software-engineering-tailwind-tokens (contrast pairs and motion tokens), design-handoff (which sets a11y requirements at design-time), software-engineering-quality-engineer (CI integration).
Run these layers in order. Each catches things the next can't see.
Tools: axe (via @axe-core/playwright in CI, or the browser extension), Lighthouse, the Storybook a11y addon, ESLint plugin eslint-plugin-jsx-a11y.
What it catches reliably:
tabindex > 0).How to run:
# In CI: axe via Playwright
import { test } from "@playwright/test";
import AxeBuilder from "@axe-core/playwright";
test("a11y on home", async ({ page }) => {
await page.goto("/");
const results = await new AxeBuilder({ page }).analyze();
expect(results.violations).toEqual([]);
});
# Local: axe browser extension or Lighthouse in DevTools.
For Storybook, install @storybook/addon-a11y and per-story violations show up in the addon panel. Catches issues at the component-isolated level.
Don't trust this layer to be complete; it's the smoke detector, not the inspection.
Disconnect the mouse. Walk every flow with Tab, Shift+Tab, Enter, Space, Escape, and Arrow keys.
What it catches:
What to check on each interactive element:
:focus, which is often suppressed)?For overlays (Dialog, Sheet, Popover, DropdownMenu): focus must move into the overlay on open and back to the trigger on close. Radix-based primitives in shadcn handle this; custom widgets often do not.
Tools: VoiceOver (macOS / iOS), NVDA (Windows, free), JAWS (Windows, paid), TalkBack (Android).
For consulting-grade web projects:
What to check:
aria-live="polite" or aria-describedby linking to the error.aria-hidden="true" or empty alt), informative ones have alt text that conveys the information.aria-live regions.What it catches:
<button> for "go somewhere," <a> for "do something" — both wrong).prefers-reduced-motion).Grouped by the area of the project they affect. Not every criterion applies to every screen; mark N/A and move on.
alt="" for decorative.<ul>/<ol>. Tables use <th> with scope.autocomplete attributes on form fields where applicable (autocomplete="email", etc.).<title>.<html lang="en"> set.<html lang="en"> in the root layout.<title> via metadata API on every page (template + per-page; see software-engineering-nextjs-scaffold).error.tsx pages, ensure they communicate error state to assistive tech (use semantic markup; an alert role on the heading where appropriate).loading.tsx, use aria-live="polite" and a meaningful loading message, not just a spinner.next/image with proper alt. Decorative images: alt="".The shadcn primitives inherit Radix's a11y defaults — keyboard support, ARIA, focus management. Do not break them:
data-state attributes; they drive styling and signal state to assistive tech.<DialogClose>, <SheetClose>, etc., not bare buttons.<DropdownMenu>, items should use the menuitem role (Radix handles this); custom menu items must follow.The --ring token (see software-engineering-tailwind-tokens) drives focus rings. Don't suppress with focus:outline-none without applying a focus-visible:ring-... replacement. Many a11y bugs are "we suppressed the default focus outline and forgot to replace it."
Form primitive (react-hook-form + zod resolver). It wires labels and error messages correctly via FormField.software-engineering-nextjs-scaffold) need server-side validation; surface errors via the action's return shape and announce them with aria-live.aria-required="true" (browser-native required attribute is fine, but pair with the label so screen readers don't only learn it from validation).aria-live="polite").# A11y Audit: [Page / Component / Flow]
**Audited**: [date]
**Auditor**: [name]
**Standard**: WCAG 2.2 AA
**Tools used**: axe, manual keyboard, VoiceOver / NVDA
## Verdict
[✅ Passes | ⚠️ Needs work | ❌ Significant issues]
## Summary
[2-3 sentences on the overall state.]
## Findings
| # | Severity | WCAG | Finding | Location | Fix |
|---|---|---|---|---|---|
| 1 | 🔴 Critical | 2.1.1 | "Continue" button not keyboard-reachable | Step 3 of questionnaire | Replace `<div onClick>` with `<Button>` |
| 2 | 🟠 High | 1.4.3 | Muted-foreground text fails 4.5:1 on white | Body copy | Update `--muted-foreground` to a darker hex |
| ... | ... | ... | ... | ... | ... |
## Details
### Finding 1: [...]
**Severity**: 🔴 Critical
**WCAG**: 2.1.1 (Keyboard)
**Location**: src/app/(tools)/formation-questionnaire/_components/step-3.tsx:42
**Issue**: The "Continue" affordance is rendered as a styled `<div>` with `onClick`. Tab does not reach it; Enter does not activate it.
**User impact**: Keyboard-only users cannot advance past step 3.
**Fix**: Use the `<Button>` primitive. Move the click handler to its `onClick` prop. Ensure the button receives correct semantic role.
**Verification**: Tab-key walkthrough confirms reachability; VoiceOver announces "Continue, button."
### ...
## Recommendations
1. [Highest-priority fix.]
2. [Next.]
3. [...]
For component specs (see software-engineering-component-spec), each component's a11y section captures: role, keyboard, ARIA, focus management, contrast, motion, touch target. The component-level spec is the canonical contract; the audit checks that the contract holds.
focus:outline-none without a focus-visible:ring-... replacement. Standard fix: ensure ring tokens are applied.<div>. Replace with <Button> or <a>.aria-label or visible text. shadcn's Button doesn't enforce this; we have to.<FormLabel> paired with <FormField>; never put labels in placeholder only.--muted-foreground value or reserve text-muted-foreground for genuinely tertiary content.<Dialog>, not a hand-rolled overlay.motion-safe:animate-... or rely on the global prefers-reduced-motion rule from software-engineering-tailwind-tokens.<h2> followed by <h4> confuses screen-reader heading nav. Use <h3> or restructure.Per software-engineering-quality-engineer:
eslint-plugin-jsx-a11y runs as part of the lint step.These catch the automation-discoverable subset. Manual passes (Layers 2-4 above) happen pre-launch and on substantive flow changes.
aria-button on a <div> is worse than a <button>.software-engineering-tailwind-tokens.software-engineering-shadcn-component.software-engineering-nextjs-scaffold.software-engineering-component-spec.design-handoff.software-engineering-quality-engineer.