agentleFS
arcasilesgrouparcasilesgroup/ai-engineering/skills/a11y-audit/SKILL.md

a11y-audit

Skill65 starsChanged 2 months agoApache-2.0View on GitHub

Audit the UI for accessibility defects against WCAG 2.2 AA — semantic structure, keyboard operability, focus management, form labeling, ARIA correctness, contrast, and motion — with each finding tied to the user it locks out. Use when asked to check accessibility or a11y, review UI for screen-reader or keyboard support, or verify WCAG compliance.

34 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use design-tokens, dependency-audit and 8 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • ilikescienceSkill

    design-tokens

    Expert in design tokens using the DTCG specification. Use this skill when users ask about design tokens, DTCG format, token validation, formatting, transformation, color spaces (sRGB, Display P3, OKLCH), references and aliasing, resolvers, theming with modifiers/contexts, multi-platform design systems, accessibility, or working with tools like jq, jsonata, and terrazzo. Helps with token file creation, resolver configuration, structure, naming conventions, and best practices.

    Also in 4 projects that use this

  • Sagargupta16Skill

    dependency-audit

    Audit project dependencies for security vulnerabilities, licensing issues, maintenance health, and optimization opportunities. Use it during regular security audits (monthly or quarterly); before a major release when you want to ensure the dependency tree is clean; when evaluating whether to adopt or replace a dependency; after a security advisory affects one of your dependencies; when your install times or bundle sizes have grown noticeably.

    Also in 3 projects that use this

  • lbednerSkill

    i18n

    Use when a code or template change introduces a new translation message key, in either the framework CLI (aegis/i18n/locales/) or a generated project's CLI (the app/i18n/locales/ template tree). Covers adding the real English string, stubbing the same key into every other locale for parity, and the separate translation PR that later replaces placeholders with reviewed native text.

    Also in 3 projects that use this

  • GitHubSkill

    refactor

    Surgical code refactoring to improve maintainability without changing behavior. Covers extracting functions, renaming variables, breaking down god functions, improving type safety, eliminating code smells, and applying design patterns. Less drastic than repo-rebuilder; use for gradual improvements.

    Also in 5 projects that use this

  • VercelSkill

    deploy

    Deploy applications to Vercel. Use when the user says "deploy", "deploy to Vercel", "push to production", "deploy my app", or "go live".

    Also in 4 projects that use this

  • AnthropicSkill

    debug

    Structured debugging session — reproduce, isolate, diagnose, and fix. Trigger with an error message or stack trace, "this works in staging but not prod", "something broke after the deploy", or when behavior diverges from expected and the cause isn't obvious.

    Also in 4 projects that use this

The file

We split this skill into the rules it gives an agent

12 rules. 0 are common, 5 are distinctive, and 7 are very specific to this project.

  • 0

    Common

    Most of the 27 edited versions we read keep these.

  • 5

    Distinctive

    This author's own choices. Worth a look.

  • 7

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Read .claude/review/CONVENTIONS.md first — stack detection, scope, severity, false-positive gate, report format.

    line 13
  2. Very specific:

    Check landmarks (main, nav, header, footer) exist and are not duplicated without labels.

    line 36
  3. Very specific:

    Every input has a programmatic label — <label htmlFor>, aria-label, or aria-labelledby.

    line 70
  4. Distinctive:

    Read the root document shell and the global stylesheet first — lang, landmarks, focus resets, motion settings, and the color system are …

    line 116
  5. Very specific:

    Verify pass: Check the parent for a label or role you missed, check globals.css for a global :focus-visible style, and confirm a component …

    line 122
  6. Very specific:

    Follow the output contract in CONVENTIONS.md.

    line 135
  7. Distinctive:

    Add the WCAG criterion to each finding, and write Trigger as the blocked user:

    line 138
  8. Distinctive:

    Consequence: no way to know it closes the dialog

    line 143
  9. Distinctive:

    "The design specified it" is never a defense: If the spec mandates 3:1 body text, that is a finding here, and the fix is to change the …

    line 155
  10. Very specific:

    Do not read design.md to decide what is correct, and do not report a divergence from the spec — that is design-check's job and it will …

    line 158
  11. Very specific:

    When a finding traces back to something the design explicitly mandates, note design-specified on it.

    line 160
  12. Distinctive:

    Read by: the human, full-review Dies: with the reviewed interface Next: ai-verify

    line 172

“Common” is measured: kept by at least 6 in 10 of the 27 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Accessibility audit

Find the places where someone cannot use this app. Every finding names the user and the barrier: "a keyboard user cannot dismiss this dialog" is a finding; "missing ARIA attributes" is a lint message.

Read .claude/review/CONVENTIONS.md first — stack detection, scope, severity, false-positive gate, report format. Target is WCAG 2.2 level AA.

WCAG is an external standard, so this skill is largely stack-independent — but where the checks below name a file or a styling mechanism, map it to whatever this project actually uses. Identify these three things up front:

  • The root document shell — wherever <html lang>, landmarks, and the page skeleton are set (a root layout, a template, index.html, a base view).
  • The global stylesheet and design tokens — wherever focus resets, color variables, and motion settings live.
  • The styling mechanism — utility classes, CSS modules, CSS-in-JS, or plain stylesheets. This decides how you resolve a color to an actual value in §6.

Checklist

1. Semantics before ARIA The most common real defect is a <div> doing a control's job. A <div onClick> is invisible to screen readers, not focusable, and does not fire on Enter/Space — use <button>. Likewise: <a> for navigation, <button> for actions (an <a> with no href is not focusable), real <ul>/<li> for lists, <table> with <th scope> for tabular data.

Check landmarks (main, nav, header, footer) exist and are not duplicated without labels; exactly one <h1> per page; heading levels that descend without skipping; <html lang> set in the root document shell.

The first rule of ARIA is not to use ARIA. A native element with correct semantics beats role="button" plus three attributes. Report added ARIA as a finding when a native element would have worked.

2. Keyboard operability Walk each interactive element and ask: can I reach it with Tab, operate it with Enter/Space, and leave it?

  • Anything interactive must be reachable. tabIndex={-1} on a control, or a custom widget with no tabIndex, removes it.
  • Focus traps — modals/menus that keep focus inside with no Escape route. Critical severity: the user is stuck.
  • Positive tabIndex (tabIndex={1}+) breaks document order. Always a finding.
  • Tab order must follow visual order — watch for CSS (order, flex-direction: row-reverse, absolute positioning) that reorders visually but not in the DOM.
  • Custom widgets need their expected key handling (Escape closes, arrows move within a composite control).

3. Focus management and visibility Focus must always be visible. A focus outline removed with no :focus-visible replacement is the single most common instance — grep for outline-none, outline: none, and outline: 0 across styles and utility classes. The indicator needs 3:1 contrast against its background.

On dynamic changes: focus moves into an opened dialog and returns to the trigger on close; route changes do not strand focus on a removed element; content that appears (errors, results) is announced or focused. A "skip to main content" link should exist when there is repeated navigation.

4. Forms Every input has a programmatic label — <label htmlFor>, aria-label, or aria-labelledby. Placeholder is not a label; it disappears on input. Required fields marked with required/aria-required, not color or an asterisk alone. Errors associated via aria-describedby and announced (role="alert" or a live region), not communicated by red border alone. Related radios/checkboxes wrapped in <fieldset> with <legend>. Autocomplete attributes on personal-data fields.

5. Images and non-text content Meaningful images need alt describing their function, not their appearance — a logo linking home is alt="Home". Decorative images take alt="" (present and empty, never missing). Icon-only buttons need an accessible name. Inline SVGs need role="img" + <title>, or aria-hidden="true" when decorative. Text baked into an image is a finding.

6. Contrast and color AA: 4.5:1 for body text, 3:1 for large text (≥18.66px bold / ≥24px) and for UI component boundaries and focus indicators.

Resolve every color to an actual value — follow utility classes to the theme config, CSS variables to their definitions, and tokens to the design system — then compute the ratio. Do not eyeball it. Watch for low-contrast conventions: mid grays on white, placeholder text, disabled states that still need to be readable, and text over images or gradients. Check both light and dark themes if prefers-color-scheme or a theme toggle is present — a pair that passes in light often fails in dark.

Color must never be the only carrier of meaning (status by hue alone, links distinguished from body text by color alone).

7. Motion, timing, zoom Animations respect prefers-reduced-motion — check the global stylesheet and any animation utilities or libraries. Nothing auto-plays or auto-advances without a pause control. No content lost at 200% zoom or 320px width. No horizontal scroll of the page body at narrow widths.

8. Dynamic content Live regions (aria-live) for content that updates without a user action — toasts, async results, validation. Loading states announced, not just spinners. aria-expanded / aria-controls on disclosure triggers, kept in sync with state. Content hidden visually must also be hidden from assistive tech (display:none or hidden, not opacity-0 alone, which leaves it focusable).

Method

  1. Detect the stack and resolve scope per CONVENTIONS.md; identify the components and routes in play.
  2. Read the root document shell and the global stylesheet first — lang, landmarks, focus resets, motion settings, and the color system are established there and affect every page.
  3. For each interactive component, walk it as a keyboard user, then as a screen reader user: what is announced, in what order, and what happens on activation?
  4. Resolve and compute contrast for every text/background pair you find.
  5. Verify pass. Check the parent for a label or role you missed, check globals.css for a global :focus-visible style, and confirm a component is actually rendered before reporting it. Drop what does not survive.
  6. Report.

Static review cannot see computed styles or real screen-reader output. State that limit honestly in Not covered rather than guessing — and note that an automated checker run against the running app complements this review by catching computed-style issues. npx @axe-core/cli <dev-url> works for any web app regardless of framework; use the project's own dev URL and port.

Report

Follow the output contract in CONVENTIONS.md. Write to .claude/reviews/a11y-audit-<stamp>.md.

Add the WCAG criterion to each finding, and write Trigger as the blocked user:

  • [HIGH] Icon-only close button has no accessible name — WCAG 4.1.2
  • Where: src/components/Dialog.tsx:34
  • Trigger: screen-reader user reaches the button; it announces as "button"
  • Consequence: no way to know it closes the dialog
  • Fix: add aria-label="Close dialog"

Severity by exclusion: Critical = a user group cannot complete a core task (focus trap, unreachable control). High = a task is possible but seriously degraded. Medium = friction or a failure on a secondary path. Low = polish.

Relationship to design-check

Your source of truth is WCAG, not design.md. A defect is a defect whether or not the design document asked for it — so:

  • "The design specified it" is never a defense. If the spec mandates 3:1 body text, that is a finding here, and the fix is to change the design. (WCAG 2.2 AA requires 4.5:1 for body text.)
  • Do not read design.md to decide what is correct, and do not report a divergence from the spec — that is design-check's job and it will catch it.
  • When a finding traces back to something the design explicitly mandates, note design-specified on it. full-review pairs that with design-check's conformance verdict and reports the conflict, which is how the design gets fixed rather than the two reviews quietly cancelling out.

This skill therefore runs and produces full value even when no design document exists.

Lifecycle

Lane: full Writes: the accessibility audit report Read by: the human, full-review Dies: with the reviewed interface Next: ai-verify

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.