accessibility-audit
Skill9 starsChanged 7 days agoMITView on GitHub
Audit a component or page for accessibility violations against WCAG 2.1 AA criteria. Use when asked for an accessibility audit, a11y check, WCAG compliance check, or "is X accessible".
55 other projects use a version of this, 1 of them edited.
Adopted by
Most recently taken up by
- ishandutta2007/Awesome-Claude-Skillstheir own version, first seen Nov 8, 2026
- ainurdev/mystical-assistanttheir own version, first seen Nov 8, 2026
- mzeleniuk/ClaudeVueProjectTemplatetheir own version, first seen Nov 8, 2026
- Smaui94/ClaudeSkillCollectiontheir own version, first seen Nov 8, 2026
- memi-design/design-skillstheir own version, first seen Nov 8, 2026
- Cure-Consulting-Group/ProductEngineeringSkillstheir own version, first seen Nov 4, 2026
Used with
Projects with it also use design-system-audit, flaky-test-triage and 9 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.
jpoindexterSkilldesign-system-audit
Audit code for design system violations - grid spacing, tokens, existing components
Also in 4 projects that use this
SUDARSHANCHAUDHARISkillflaky-test-triage
Diagnoses inconsistent test results by separating product nondeterminism, automation defects, shared data, timing, infrastructure, environment, order, and concurrency effects.
Also in 3 projects that use this
tekumaraSkillapi-design-review
Reviews REST API design by inventorying routes, finding overlapping functionality, comparing payloads and pagination, and checking resource naming, URL structure, identifiers, errors, idempotency, and timestamps. Use when asked to review API routes, compare endpoints, find redundant or superseding operations, assess contract consistency, or run a REST API design review.
Also in 3 projects that use this
BufferoverflovvSkillobservability-setup
Add production observability to a FastMCP server: request IDs, slow-request logging, structured log fields, and optional Prometheus metrics. Use when: hardening logging for production, adding request tracing or correlation IDs, setting up slow-request alerts, adding a /metrics endpoint, or improving structured log output beyond the base middleware.
Also in 3 projects that use this
mmondoraSkillinfrastructure-as-code
Infrastructure as Code with Terraform and Pulumi. State management, modularity, drift detection, secrets handling. Use when provisioning cloud resources, writing Terraform/Pulumi modules, or managing infrastructure configuration.
Also in 3 projects that use this
Sagargupta16Skillupgrade-dependencies
Upgrade a project's dependencies one at a time, running the test suite after each bump and reverting the ones that break it. Use it during routine dependency maintenance, when a batch of updates has accumulated; before a major release, to go into it on current and patched dependencies; when Renovate or Dependabot PRs have piled up and you want them resolved locally in one sitting; when a security advisory means you need the patched version in, and you need to know what it breaks.
Also in 3 projects that use this
Other versions55 projects use a version of this.
Word for word · 0
None found.
Edited · 1
- robritacca-dotcom/design-system★ 175% same
Wrote their own version · 54
- me2resh/apexyard★ 542same name
- github/replica★ 230same name
- cuellarfr/design-skills★ 94same name
- adityareddy-dev/deskstudio★ 43same name
- launchapp-dev/animus-cli★ 39same name
- kumaran-is/claude-code-onboarding★ 35same name
- 5throck/ai-workspace-standards★ 25same name
- Indium-AI-Labs/indium-agentkit★ 18same name
- Ionate-Technologies/indium-agentkit★ 17same name
- ishandutta2007/Awesome-Claude-Skills★ 16same name
44 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository33 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- animation-jump-checkSkill
- api-consistencySkill
- chat-qualitySkill
- checkpointSkill
- component-consistency-auditSkill
- component-doc-pageSkill
- content-auditSkill
- dependency-advisorySkill
- design-qaSkill
- dogfoodSkill
- drift-auditSkill
- first-deploySkill
- landSkill
- link-rotSkill
- new-componentSkill
- new-pageSkill
- new-presetSkill
- new-templateSkill
- new-tokenSkill
- new-validatorSkill
- parkSkill
- pre-deploySkill
- release-postSkill
- releaseSkill
- responsive-sweepSkill
- security-auditSkill
- seo-auditSkill
- shipSkill
- super-shipSkill
- token-auditSkill
- token-renameSkill
- visual-reviewSkill
The file
We split this skill into the rules it gives an agent
8 rules. 0 are common, 5 are distinctive, and 3 are very specific to this project.
0
Common
Most of the 46 edited versions we read keep these.
5
Distinctive
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 15
Use this skill when asked to check accessibility, run an a11y audit, or find WCAG issues — phrases like "accessibility audit", "a11y check …
- Very specific: line 25
If that is green, every violation axe can detect is already absent — and re-checking icon-only button names, label association, …
- Distinctive: line 56
[manual]: All interactive elements are reachable by Tab, in an order that makes sense — axe cannot judge order
- Very specific: line 63
Every interactive element has a :focus-visible rule in its CSS
- Very specific: line 71
Visual audit (from screenshots): Start the preview server and screenshot the target in both light and dark mode (follow the visual-review …
- Distinctive: line 73
Text sizing: No text visually below ~12px (WCAG 1.4.4)
- Distinctive: line 77
Stop the server when done.
- Distinctive: line 95
If clean: "No accessibility violations found.
“Common” is measured: kept by at least 6 in 10 of the 46 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.
Files
accessibility-audit
Audit a component or page for accessibility violations against WCAG 2.1 AA criteria.
When invoked
Use this skill when asked to check accessibility, run an a11y audit, or find WCAG issues — phrases like "accessibility audit", "a11y check on [component/page]", "check WCAG compliance", "is [X] accessible".
What is already automated — read this before auditing anything
Axe runs on every Storybook story and fails the build. .storybook/preview.ts sets a11y.test: 'error', so npm run test (and therefore CI and npm run verify) already enforces WCAG 2.1 AA across the whole library — and the same run executes any story play function, so behavior a story asserts (focus, dismissal, keyboard) is enforced too. Start by running it:
npm run testIf that is green, every violation axe can detect is already absent — and re-checking icon-only button names, label association, role="dialog" naming or ARIA parent/child relationships by hand is duplicated effort.
This skill exists for the three things that gate does not cover:
- Colour contrast — excluded from the axe gate entirely.
color-contrastis switched off in.storybook/preview.tsby a settled decision of the owner's. Read that override's comment first: it is the authoritative record of why, and the single place the details belong. Since the 2026-08-20 split of the action colour by mode the shipped pairs the rule used to fail all clear AA; the rule stays off because the action colour is a token consumers re-point to their own palettes, so the gate would be judging a value the system does not own. One slice of contrast is build-enforced at token level instead:scripts/validate-theme-presets.mjsholds every action fill against the label or icon components draw on it — resting, hover and pressed, in both themes, for the shipped tokens and every preset — and itsACTION_PAIRINGStable is the authoritative list of what it covers. Every other rendered pair (text and surfaces, status, charts, alpha composites over real content) is the manual auditor's job, and the single highest-value thing to audit: nothing else checks it. Never propose re-enabling the rule without asking the owner first. - What axe cannot see. Axe catches roughly a third of WCAG issues. It cannot tell whether alt text is meaningful, whether focus order makes sense, or whether a helper message should have been associated with its control. (Behavior a story's
playfunction asserts is covered —Dialog.stories.tsxproves the modal focus trap, restore, and stacked Escape in CI — so the manual job is the overlays with no play coverage yet.) (Two such bugs once shipped undetected until a manual survey found them: Dropdown announced neither its helper text nor its error state. Both were since fixed by moving Dropdown ontoField, but it took the manual survey, not axe, to find them.) - Website pages beyond the automated sample. A page-level axe pass (
scripts/validate-website-a11y.mjs, inverifyand CI) now runs against the served site in both themes with the same rule set — but only over the route sample inscripts/served-site.mjs, at one desktop viewport. Full-site sweeps, mobile viewports, and any page outside that sample remain this skill's job.
Report a finding as already-enforced if npm run test or the page-level axe pass would have caught it; that tells the reader the gate is working rather than implying a gap.
Instructions
- Determine scope. Accept one of:
- A component name (e.g.
Dropdown) → auditssrc/components/Dropdown/Dropdown.tsxand its CSS (the chat widget's own components are the.tsxmodules insrc/chat/; read the folder rather than a list. Its question flow moves focus deliberately: into the first option when a set of questions holds the composer, and back to the composer once the set is answered or skipped; check both by keyboard) - A website page URL (e.g.
/components/button) → audits the live rendered page all-components→ audits all components insrc/components/and the chat widget insrc/chat/
- A component name (e.g.
- Read the source files. For each component in scope, read the
.tsxand.cssfiles before taking screenshots. Structural audit (from source code). Most items here are already enforced by axe — spend your effort on the ones marked [manual], which it cannot evaluate:
Semantic HTML & ARIA:
- Interactive elements use correct roles (
button,link,checkbox, etc.) — never a<div onClick>withoutroleandtabIndex - Icon-only
<button>elements havearia-labeldescribing their action - [manual]
<img>elements have meaningfulalttext — axe only checks that the attribute exists; decorative images usealt="" - Form inputs are associated with
<label>viahtmlFor/id, or havearia-label - Modals and dialogs use
role="dialog"andaria-modal="true", witharia-labelledbypointing to the title - Lists use
<ul>/<ol>+<li>, not<div>stacks - Heading hierarchy is logical — no h3 before h2, no skipped levels
Keyboard Navigation:
- [manual] All interactive elements are reachable by Tab, in an order that makes sense — axe cannot judge order
- Custom interactive components handle
onKeyDownfor Enter/Space (buttons) and arrow keys (any component with roving or list focus — radio groups, segmented controls, listboxes, tablists) - [manual where no
playfunction covers it] Modal/dialog actually traps focus while open and restores it to the trigger on close — axe sees the attributes, not the behaviour. The modal overlays share one behavior implementation (design.md's Components intro owns the contract), so a real trap/restore defect there is a finding against all of them, not one. The site chat is modal only in some of its forms, and its floating card's move and size grips are pointer-only by a recorded decision: design.md's ChatWidget spec says which forms trap focus and why the grips are not a finding - Escape key closes dismissible overlays (any floating panel — tooltips, popovers, menus, dialogs, pickers), and only the topmost: a popover, menu or visible tooltip open inside a dialog closes before the dialog does, and a press on a dialog's backdrop with a menu open closes only the menu. Every overlay dismisses through the shared layer stack (
scripts/validate-overlay-listeners.mjskeeps it so), andDialog.stories.tsx's nested-overlay stories assert the contract; a component handling Escape in its own keydown handler must mark it handled withpreventDefault(), so check that on anything new - A literal English accessible name the consumer cannot replace is a finding: it cannot be localised.
scripts/validate-accessible-names.mjscatches literalaria-label,aria-roledescriptionand*Labelattributes, andscripts/validate-visible-text.mjsliteral JSX text; [manual] check English built in string literals and arrays (a weekday list, a${n} resultstemplate), which neither can see
Focus Styles:
- Every interactive element has a
:focus-visiblerule in its CSS - Focus ring uses the action colour token (
--color-action-primary-bg) — design.md's action-colour rules are the authoritative list of sanctioned uses. Flag anyoutline: nonewithout a visible replacement
Motion (axe evaluates none of this):
- [manual] Anything that animates for more than five seconds, or loops indefinitely, can be paused, stopped, or hidden (WCAG 2.2.2). CSS motion satisfies this through the reduced-motion block in
tokens-motion.css, which carries two mechanisms and whose own header comment owns the contract: token collapse for token-consuming CSS, and a universal*guard that also covers hardcoded andds-allow(motion)-sanctioned literal timings (an infinite loop on an off-scale duration is still guarded). Read it there rather than assuming which half applies - [manual] Animation driven from JavaScript is outside that guard — a
requestAnimationFrameloop cannot be seen by CSS, so each one has to checkprefers-reduced-motionitself. Enumerate the JS-side checks with a grep forprefers-reduced-motionacrosssrc/components/**/*.tsx,src/chat/**/*.{ts,tsx}(the streaming reveal's check is in a.tsfile) andwebsite/src— the grep is the inventory, not any list written here (the site's ambient background, which renders a single static frame under the preference, is one illustration; more exist and new ones keep arriving) — and confirm each still honours the preference rather than assuming the token layer covers it. That grep has one known blind spot: the recharts-backed charts animate their marks in from JavaScript but never contain the string — their guard is recharts' ownisAnimationActive: 'auto'default, and design.md's chart-set spec owns the contract (a literaltruewould override the guard). Run a second grep forisAnimationActiveacrosssrc/components/— the one expected hit is the shared entrance hook insrc/components/Chart/useChartAnimation.ts, which keeps recharts''auto'guard while an entrance is due and setsfalseonce it has played (design.md's chart-set spec sanctions it); a literaltrue, or a chart setting the flag without the hook, is a finding to check against that spec - [manual] Motion triggered by interaction (parallax, cursor-reactive effects) is disabled under reduced motion, or is not essential (WCAG 2.3.3)
- Interactive elements use correct roles (
Visual audit (from screenshots). Start the preview server and screenshot the target in both light and dark mode (follow the
visual-reviewskill pattern). Check:- Colour contrast (the priority — axe does not check it): compute the ratio for every foreground/background pair actually rendered, not just body text. Flag anything below 4.5:1 for normal text or 3:1 for large text and UI components (WCAG 1.4.3 / 1.4.11). Note which token is used. The
color-contrastaxe rule is off for every pair (see item 1 under "What is already automated"); the action-fill pairings are the one slice the build gates, so cross-check a failing action pair againstACTION_PAIRINGSinscripts/validate-theme-presets.mjs— a pair it lists is already enforced (a hit there means the render is not using the token the table names, unless the cell is pinned inSANCTIONED_AA_GAPSin the same script, which is an owner-accepted gap to note rather than raise), and a label or icon on an action fill that it does not list is a gap in the table worth reporting. - Text sizing: No text visually below ~12px (WCAG 1.4.4)
- Focus visibility: Confirm focus rings are clearly visible in both light and dark themes
- Forced colors (WCAG 1.4.11 under high contrast): render the target with forced colors on (Playwright's
forcedColors: 'active', or the browser's emulation) and check that every state carried by a fill (checked, selected, on, a count) still stands apart from the page, that a floating panel keeps an edge once its shadow is dropped, and that focus rings still show.src/tokens/tokens-forced-colors.cssre-points the state-bearing roles at system colours (design.md's Forced colors section owns which); the page-level check covers only the table bench (FORCED_CHECKSinscripts/validate-website-a11y.mjs), so anything else is this audit's to judge. A state that vanishes is a finding against the token layer, not the component, unless the component draws the state outside the tokens.
Stop the server when done.
- Colour contrast (the priority — axe does not check it): compute the ratio for every foreground/background pair actually rendered, not just body text. Flag anything below 4.5:1 for normal text or 3:1 for large text and UI components (WCAG 1.4.3 / 1.4.11). Note which token is used. The
For each issue, report:
src/components/FilterMenu/FilterMenu.tsx:84 — WCAG 4.1.2 Name, Role, Value [Critical] Trigger button has no accessible name. Icon-only button needs aria-label="Open filters".(The example is fictional by design —
FilterMenuis not a real component; it illustrates the report shape only.)Severity:
- Critical — blocks keyboard or screen reader users entirely
- Moderate — degrades experience significantly
- Minor — best practice violation, low direct impact
- Summarise:
X critical · Y moderate · Z minor- If clean: "No accessibility violations found. Component meets WCAG 2.1 AA."
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
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.

