accessibility-audit — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited accessibility-audit (Agent Skill) and scored it 96/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 1 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
This skill audits a project for accessibility issues and fixes them. Based on:
Invoke this skill when an accessibility audit is requested. It should scan the project automatically without assuming a specific slash-command system.
This skill must work across Codex, Claude, and other SKILL.md-compatible agents. Do not assume slash commands, Claude-only memory files, or a specific package manager. Use the repository's existing tools and conventions. If no automated accessibility tooling is installed, perform the manual audit and recommend optional external tools without installing dependencies.
Read the project's index.html, all page components, layout components, and form components. Build a mental map of:
prefers-reduced-motion is already handledGo through each category below. For every issue found, note the file, line, and which WCAG criterion it violates. Group findings by severity (Critical → Major → Minor).
| Check | WCAG | How to verify |
|---|---|---|
<html lang="..."> is set and correct | 3.1.1 (A) | Read index.html |
Each page has a unique <title> | 2.4.2 (A) | Check all pages |
Viewport zoom is NOT disabled (maximum-scale=1 or user-scalable=no must be absent) | 1.4.4 (AA) | Check <meta name="viewport"> |
Landmark elements used (<main>, <nav>, <header>, <footer>, <section>) | 4.1.2 (A) | Check page structure |
| Linear content flow / logical DOM order | 2.4.3 (A) | Check for CSS-only reordering |
No autofocus attribute on inputs | 2.4.3 (A) | Grep for autofocus |
No title attribute tooltips on interactive elements | 4.1.2 (A) | Grep for title= |
| Check | WCAG | How to verify |
|---|---|---|
Only one <h1> per page | 2.4.6 (AA) | Check all pages |
| Heading levels don't skip (h1 → h3 without h2) | 2.4.6 (AA) | Check heading hierarchy |
| Headings introduce content sections | 2.4.6 (AA) | Check section structure |
| Check | WCAG | How to verify |
|---|---|---|
All <img> have alt attribute | 1.1.1 (A) | Grep for <img without alt |
Decorative images have alt="" | 1.1.1 (A) | Check decorative images |
SVG icons have aria-hidden="true" or accessible label | 1.1.1 (A) | Check SVG usage |
| Complex images (charts, graphs) have text alternatives | 1.1.1 (A) | Check if applicable |
| Check | WCAG | How to verify |
|---|---|---|
| Normal text: 4.5:1 contrast ratio minimum | 1.4.3 (AA) | Check all text colors against backgrounds |
| Large text (18px+ or 14px+ bold): 3:1 minimum | 1.4.3 (AA) | Check large text |
| UI components & icons: 3:1 minimum | 1.4.11 (AA) | Check borders, icons, focus rings |
| No opacity modifiers that reduce contrast below threshold | 1.4.3 (AA) | Grep for opacity on text |
| Color is not the only way to convey info | 1.4.1 (A) | Check error states, status indicators |
| Check | WCAG | How to verify |
|---|---|---|
| All interactive elements are keyboard accessible | 2.1.1 (A) | Check for onClick without keyboard handler |
| Visible focus styles on all interactive elements | 2.4.7 (AA) | Check :focus / focus-visible styles |
| Focus order matches visual layout | 1.3.2 (A) | Check tabIndex usage |
| No keyboard traps | 2.1.2 (A) | Check modals, dropdowns |
| Focus not obscured by sticky headers/bars | 2.4.11 (AA) | Check sticky/fixed elements |
| Skip link present and visible on focus | 2.4.1 (A) | Check for skip navigation |
| Check | WCAG | How to verify |
|---|---|---|
All inputs have associated <label> (or aria-label / aria-labelledby) | 3.2.2 (A) | Check all form inputs |
Required fields marked with aria-required="true" | 3.3.2 (A) | Check required inputs |
Error messages associated with inputs (aria-describedby or aria-invalid) | 3.3.1 (A) | Check error handling |
| Errors not communicated by color alone | 1.4.1 (A) | Check error states |
autocomplete attributes on common fields (name, email, etc.) | 1.3.5 (AA) | Check form inputs |
fieldset + legend for grouped inputs (radio groups, checkboxes) | 1.3.1 (A) | Check grouped inputs |
| Check | WCAG | How to verify |
|---|---|---|
Links use <a>, buttons use <button> (not <div onClick>) | 1.3.1 (A) | Check interactive elements |
| Link/button text is descriptive (no "click here", "read more" without context) | 2.4.4 (A) | Check link text |
Links opening in new tab have indication (aria-label or visual + sr text) | G201 | Grep for target="_blank" |
| Links are visually distinguishable (not just by color) | 1.4.1 (A) | Check link styling |
| Check | WCAG | How to verify |
|---|---|---|
| No autoplay audio/video with sound | 1.4.2 (A) | Check media elements |
| Video has captions/subtitles | 1.2.2 (A) | Check video elements |
| All media can be paused | 2.2.2 (AA) | Check media controls |
prefers-reduced-motion disables animations | 2.3.3 (AAA) | Check CSS + JS animations |
| No content flashes more than 3 times per second | 2.3.1 (A) | Check animations |
| Check | WCAG | How to verify |
|---|---|---|
| Touch targets minimum 24×24px (44×44px recommended) | 2.5.8 (AA) | Check buttons, links on mobile |
| No horizontal scrolling at 320px viewport | 1.4.10 (AA) | Check responsive layout |
| Content works in both orientations | 1.3.4 (AA) | Check orientation lock |
| Dragging actions have alternatives | 2.5.7 (AA) | Check drag interactions |
| Check | WCAG | How to verify |
|---|---|---|
| ARIA roles used correctly (not on wrong elements) | 4.1.2 (A) | Check ARIA usage |
aria-hidden="true" on decorative elements | 4.1.2 (A) | Check decorative content |
Live regions (aria-live) for dynamic updates | 4.1.3 (AA) | Check toast/notification components |
Modals/dialogs have role="dialog" + aria-modal + focus trap | 4.1.2 (A) | Check modal components |
| Accordion/disclosure patterns use proper ARIA | 4.1.2 (A) | Check accordion components |
| Check | WCAG | How to verify |
|---|---|---|
| Help mechanisms are consistent across pages (chat, FAQ link, etc.) | 3.2.6 (A) | Check help patterns |
| No redundant entry — don't ask users to re-enter info already provided | 3.3.7 (A) | Check multi-step forms |
| No cognitive function tests for auth (CAPTCHA alternatives) | 3.3.8 (AA) | Check auth flows |
Present findings as a table grouped by severity:
## Accessibility Audit Results
### 🔴 Critical (breaks access for some users)
| Issue | File | WCAG | Fix |
|-------|------|------|-----|
| ... | ... | ... | ... |
### 🟠 Major (significant barrier)
| Issue | File | WCAG | Fix |
|-------|------|------|-----|
| ... | ... | ... | ... |
### 🟡 Minor (improvement opportunity)
| Issue | File | WCAG | Fix |
|-------|------|------|-----|
| ... | ... | ... | ... |
### ✅ Passing
- [list what's already good]Ask the user: "Should I fix the issues automatically? All issues or only selected ones?"
Apply fixes directly in the codebase. For each fix:
Missing alt text:
// Decorative → alt=""
<img src="..." alt="" />
// Meaningful → descriptive alt
<img src="..." alt="Description of image content" />Missing labels:
<label htmlFor="email">E-Mail</label>
<input id="email" type="email" aria-required="true" />
// Or for icon-only buttons:
<button aria-label="Open menu">
<MenuIcon aria-hidden="true" />
</button>Focus styles:
:focus-visible {
outline: 2px solid var(--c-accent);
outline-offset: 2px;
}Skip link:
<a href="#main-content" className="sr-only focus:not-sr-only focus:absolute focus:top-4 focus:left-4 focus:z-50 focus:px-4 focus:py-2 focus:bg-white focus:text-black">
Skip to content
</a>prefers-reduced-motion:
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}External links:
<a href="..." target="_blank" rel="noopener noreferrer">
Link Text <span className="sr-only">(opens in new tab)</span>
</a>aria-live for dynamic content:
<div aria-live="polite" aria-atomic="true">
{statusMessage}
</div>After fixing, present:
Accessibility Audit Complete!
✅ [N] issues fixed
⚠️ [N] issues need manual testing (keyboard nav, screen reader)
📊 WCAG 2.2 Level AA compliance: [estimated %]
Fixed:
- [list of fixes applied]
Manual testing recommended:
- Tab through all pages — verify focus order and visibility
- Test with screen reader (VoiceOver: Cmd+F5 on Mac)
- Test at 200% zoom — verify no content is cut off
- Test at 320px width — verify no horizontal scroll
- Test with prefers-reduced-motion enabled
Tools for further testing:
- axe DevTools: browser extension for automated checks
- WAVE: https://wave.webaim.org/
- Lighthouse Accessibility audit in Chrome DevToolsprefers-reduced-motion handling is mandatory, not optionalsr-only text in examples; localize to the project's language at implementation time~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.