Skip to content

Skills · dev-team

accessibility-audit

Adversarially audit a UI (component code, page markup, screenshot, or flow) against WCAG 2.2 AA — findings cited to specific success criteria, centered on the user and assistive tech each one blocks, severity-tagged, with a concrete fix and what a scanner would miss. Use when the user wants an accessibility review, a11y audit, WCAG check, or to find what blocks screen-reader / keyboard / low-vision users before shipping.

Pack dev-teamTier heavyJob Build and review softwarev0.1.0

npx skilldrop-cli install accessibility-audit
Other ways to install

With the sibling skills it hands off to:

npx skilldrop-cli install accessibility-audit --with-related

The whole pack it belongs to:

npx skilldrop-cli install --pack dev-team

By hand, from a clone of the repo:

cp -R packs/dev-team/skills/accessibility-audit ~/.claude/skills/

In Claude Code, with the dev-team plugin installed, invoke it as:

/dev-team:accessibility-audit

Try it

A realistic prompt from the skill's acceptance evals:

Audit this checkout form component before we ship:

<form>
  <div class="title">Payment</div>
  <input placeholder="Card number" style="color:#999;background:#fff">
  <input placeholder="Expiry">
  <span class="err" style="color:red">Invalid</span>
  <img src="lock.svg" alt="image">
  <div class="btn" onclick="submit()" style="width:20px;height:20px">Pay</div>
</form>

Target is WCAG 2.2 AA.

What a good result looks like

Example output

login form component → severity-tagged audit · the skill's own worked example, source

Input
function LoginForm() {
  const [err, setErr] = useState(false);
  return (
    <div className="login">
      <div className="title" style={{fontSize: 22, fontWeight: 700}}>Sign in</div>
      <input type="text" placeholder="Email" style={{color: '#999'}} />
      <input type="password" placeholder="Password" />
      {err && <span style={{color: 'red'}}>✕</span>}
      <div className="btn" onClick={submit} style={{background:'#5b9', color:'#fff', padding:'6px 10px'}}>
        Log in
      </div>
      <span className="link" onClick={forgot}>Forgot?</span>
    </div>
  );
}
Output

Coverage note

Audited from component code: semantics, labels, roles, keyboard reachability, and contrast (from inline styles) are inspectable. Live focus-order and screen-reader output still need a real AT pass — flagged below.

🟥 Blockers

A11Y-1 — Submit control is a <div>, unreachable and unoperable by keyboard · 2.1.1 Keyboard [A], 4.1.2 Name, Role, Value [A] · [auto]+[manual] A <div onClick> is not in the tab order, doesn't fire on Enter/Space, and exposes no button role or name to AT. Blocks: keyboard-only and screen-reader users from logging in at all — there is no other submit path. Fix: use <button type="submit">Log in</button> inside a <form onSubmit>. Same for Forgot? → <button> (or <a href> if it navigates).

A11Y-2 — Inputs have no programmatic label · 3.3.2 Labels or Instructions [A], 1.3.1 Info and Relationships [A], 4.1.2 [A] · [auto] Placeholders are not labels: they vanish on input and many screen readers don't announce them reliably. A screen-reader user hears "edit text, blank". Fix: add <label htmlFor> tied to each input (visible label preferred), or at minimum aria-label. Placeholders stay as hints, not the only label.

🟧 Major

A11Y-3 — Error is conveyed by color and an icon glyph only, not associated with a field · 1.4.1 Use of Color [A], 3.3.1 Error Identification [A], 4.1.3 Status Messages [AA] · [manual] A red ✕ with no text tells a blind or color-blind user nothing about what failed or which field. It's also not announced (no live region) and not linked to an input. Blocks: blind users get no error info; color-blind users may miss the signal. Fix: render text ("Incorrect email or password"), associate via aria-describedby on the relevant input, and put the message in role="alert" so it's announced.

A11Y-4 — Email input text contrast fails AA · 1.4.3 Contrast (Minimum) [AA] · [auto] #999 on #fff = 2.85:1, below the 4.5:1 minimum for normal text. Low-vision users can't read typed input. Fix: darken to ≥ #767676 (4.54:1) or darker.

🟨 Minor

A11Y-5 — Submit button color contrast borderline / unverifiable focus ring · 1.4.3 [AA], 2.4.7 Focus Visible [AA] · [auto]+[manual] White text #fff on #5b9 (#55bb99) = 2.35:1 — fails 4.5:1 for the button label. Also, once it's a real <button>, confirm a visible focus indicator exists (can't verify from static code). Fix: darken the button background to clear 4.5:1 — e.g. #1f7a57 = 5.28:1 (#2e8b6f is only 4.17:1 and still fails, the classic "looks dark enough" trap) — and ensure a visible :focus-visible outline.

⚪ Nits

A11Y-6 — Title is a styled <div>, not a heading · 1.3.1 [A], 2.4.6 [AA] Screen-reader users navigate by headings; a visual-only "Sign in" isn't in the outline. Fix: <h1> (or appropriate level) instead of <div className="title">.

What's solid

  • type="password" is correct (masking + manager integration).
  • Touch targets: padding gives the button adequate size once it's a real control — keep ≥ 24×24 (2.5.8).

Must verify with live AT

  • Focus order through the form (DOM order looks correct, but confirm).
  • Screen-reader announcement of the error live region after a failed submit.
  • Visible focus indicator on all controls (2.4.7) once they're focusable.
  • Behavior at 400% zoom / reflow (1.4.10).

Fix order

  1. A11Y-1, A11Y-2 (blockers — nobody can log in via AT).
  2. A11Y-3 (error semantics).
  3. A11Y-4, A11Y-5 (contrast — quick CSS).
  4. A11Y-6 (heading).

How it's checked

Measured against plain Claude Code (2026-10-23): it met 72% of its checks, against 41% without it, and a blind judge preferred it. How skills are checked

21 assertions across 3 acceptance evals, and 7 trigger queries. Every skill's checks

What the output must do
  • Opens with a coverage note stating what markup alone can and cannot verify (e.g. actual screen-reader output, live focus order)
  • Every finding cites a specific success criterion with number, name, and level (e.g. 2.1.1 Keyboard [A], 4.1.2 Name, Role, Value [A])
  • Every finding names the user group and assistive tech it blocks (e.g. keyboard-only, NVDA/VoiceOver users)
  • The div-as-button is a blocker for keyboard and screen-reader users; minor issues like the lock icon's alt text are not inflated to blocker
  • Contrast for #999 on #fff is given as a computed ratio (about 2.85:1) against the 4.5:1 threshold, and the 20x20 target is checked against 2.5.8's 24x24 minimum
  • Each finding is tagged [auto] or [manual] and has a concrete fix
  • Ends with a 'what's solid' section and a must-verify-with-live-AT checklist
  • Does not claim a pass on any behavior the markup can't show, and does not invent elements not in the snippet
  • Does not confirm WCAG 2.2 AA compliance or approve the badge; it says the page fails on the issues found and that a scan plus a code review cannot by themselves establish conformance
  • Catches that the scanner measured the help text against white, but the text sits on the #f2f2f2 panel, where #767676 is about 4.1:1 and fails the 4.5:1 minimum
  • Finds that white text on the #E87722 button is about 3:1 and fails for 16px normal-weight text, and proposes a fix that keeps the orange (for example dark text on the orange) rather than changing the brand colour
  • Finds that the ticket stepper built from clickable spans cannot be operated by keyboard or understood by a screen reader, and that the 90-second hold resets the form and redirects with no warning or way to extend it
  • Keeps to the stated scope: header and footer problems are not reported as findings to fix, and the empty alt on the decorative divider image is not reported as a failure
  • Does not invent elements, behaviours, or screen-reader test results that are not in the supplied files
  • The audit is about two pages or less (roughly 1,000 words or fewer)
  • Says the order button needs to be a real button (or have the equivalent role, focus and keyboard handling) because a screen-reader or keyboard user cannot find or press a clickable div
  • Says the cake photos need short text descriptions (alt text) so a screen reader can describe them
  • Gives a few plain-English bullet points the owner can pass on, not a long report
  • Avoids unexplained jargon; any technical term the nephew needs is explained in a few words
  • Does not claim to have found other specific problems on a page it has not seen, and does not say the rest of the page is fine; at most it suggests testing the whole ordering flow
  • Delivers the advice without stopping to ask for the page's code first
When it should and shouldn't activate

Should activate:

  • Run an a11y audit on this signup page markup
  • Is this component WCAG 2.2 AA compliant? Find what blocks screen-reader users
  • Here's a screenshot of our dashboard — what accessibility issues can you spot before we build it?
  • We failed an accessibility review; check this modal for keyboard traps and focus problems

Should leave to another skill:

  • What WCAG level should our new product commit to, and on which scope?
  • Review this PR for correctness bugs and edge cases
  • Implement this date-picker story with tests until the acceptance criteria pass

Related skills

devils-advocate, doc-critique, feature-implement-loop, nfr-spec, threat-model

Source

SKILL.md · the whole folder on GitHub.