/web-accessibility
Audit and improve web accessibility following WCAG 2.1 guidelines. Use when asked to "improve accessibility", "a11y audit", "WCAG compliance", "screen reader support", "keyboard navigation", or "make accessible". Do NOT use for SEO (use seo), performance (use core-web-vitals),
$ npx -y skills add tech-leads-club/agent-skills --skill web-accessibility --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/web-accessibility
Context preview
The summary Claude sees to decide when to auto-load this skill.
Audit and improve web accessibility following WCAG 2.1 guidelines. Use when asked to "improve accessibility", "a11y audit", "WCAG compliance", "screen reader support", "keyboard navigation", or "make accessible". Do NOT use for SEO (use seo), performance (use core-web-vitals),
SKILL.md
web-accessibility.SKILL.mdname: accessibility
description: Audit and improve web accessibility following WCAG 2.1 guidelines. Use when asked to "improve accessibility", "a11y audit", "WCAG compliance", "screen reader support", "keyboard navigation", or "make accessible". Do NOT use for SEO (use seo), performance (use core-web-vitals), or comprehensive site audits covering multiple areas (use web-quality-audit).
license: MIT
metadata:
author: web-quality-skills
version: '1.0'
Accessibility (a11y)
Comprehensive accessibility guidelines based on WCAG 2.1 and Lighthouse accessibility audits. Goal: make content usable by everyone, including people with disabilities.
WCAG Principles: POUR
| Principle | Description | | ------------------ | ------------------------------------------------- | | **P**erceivable | Content can be perceived through different senses | | **O**perable | Interface can be operated by all users | | **U**nderstandable | Content and interface are understandable | | **R**obust | Content works with assistive technologies |
Conformance levels
| Level | Requirement | Target | | ------- | ---------------------- | ----------------------------------------------------- | | **A** | Minimum accessibility | Must pass | | **AA** | Standard compliance | Should pass (legal requirement in many jurisdictions) | | **AAA** | Enhanced accessibility | Nice to have |
---
Perceivable
Text alternatives (1.1)
**Images require alt text:**
<!-- ❌ Missing alt -->
<img src="chart.png" />
<!-- ✅ Descriptive alt -->
<img src="chart.png" alt="Bar chart showing 40% increase in Q3 sales" />
<!-- ✅ Decorative image (empty alt) -->
<img src="decorative-border.png" alt="" role="presentation" />
<!-- ✅ Complex image with longer description -->
<figure>
<img src="infographic.png" alt="2024 market trends infographic" aria-describedby="infographic-desc" />
<figcaption id="infographic-desc">
<!-- Detailed description -->
</figcaption>
</figure>**Icon buttons need accessible names:**
<!-- ❌ No accessible name -->
<button>
<svg><!-- menu icon --></svg>
</button>
<!-- ✅ Using aria-label -->
<button aria-label="Open menu">
<svg aria-hidden="true"><!-- menu icon --></svg>
</button>
<!-- ✅ Using visually hidden text -->
<button>
<svg aria-hidden="true"><!-- menu icon --></svg>
<span class="visually-hidden">Open menu</span>
</button>
**Visually hidden class:**
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}Color contrast (1.4.3, 1.4.6)
| Text Size | AA minimum | AAA enhanced | | ---------------------------------- | ---------- | ------------ | | Normal text (< 18px / < 14px bold) | 4.5:1 | 7:1 | | Large text (≥ 18px / ≥ 14px bold) | 3:1 | 4.5:1 | | UI components & graphics | 3:1 | 3:1 |
/* ❌ Low contrast (2.5:1) */
.low-contrast {
color: #999;
background: #fff;
}
/* ✅ Sufficient contrast (7:1) */
.high-contrast {
color: #333;
background: #fff;
}
/* ✅ Focus states need contrast too */
:focus-visible {
outline: 2px solid #005fcc;
outline-offset: 2px;
}**Don't rely on color alone:**
<!-- ❌ Only color indicates error -->
<input class="error-border" />
<style>
.error-border {
border-color: red;
}
</style>
<!-- ✅ Color + icon + text -->
<div class="field-error">
<input aria-invalid="true" aria-describedby="email-error" />
<span id="email-error" class="error-message">
<svg aria-hidden="true"><!-- error icon --></svg>
Please enter a valid email address
</span>
</div>Media alternatives (1.2)
<!-- Video with captions -->
<video controls>
<source src="video.mp4" type="video/mp4" />
<track kind="captions" src="captions.vtt" srclang="en" label="English" default />
<track kind="descriptions" src="descriptions.vtt" srclang="en" label="Descriptions" />
</video>
<!-- Audio with transcript -->
<audio controls>
<source src="podcast.mp3" type="audio/mp3" />
</audio>
<details>
<summary>Transcript</summary>
<p>Full transcript text...</p>
</details>
---
Operable
Keyboard accessible (2.1)
**All functionality must be keyboard accessible:**
// ❌ Only handles click
element.addEventListener('click', handleAction)
// ✅ Handles both click and keyboard
element.addEventListener('click', handleAction)
element.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault()
handleAction()
}
})**No keyboard traps:**
// Modal focus management
function openModal(modal) {
const focusableElements = modal.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])',
)
const firstElement = focusableElements[0]
const lastElement = focusableElements[focusableElements.length - 1]
// Trap focus within modal
modal.addEventListener('keydown', (e) => {
if (e.key === 'Tab') {
if (e.shiftKey && document.activeElement === firstElement) {
e.preventDefault()
lastElement.focus()
} else if (!e.shiftKey && document.activeElement === lastElement) {
e.preventDefault()
firstElement.focus()
}
}
if (e.key === 'Escape') {
closeModal()
}
})
firstElement.focus()
}Focus visible (2.4.7)
/* ❌ Never remove focus outlines */
*:focus {
outline: none;
}
/* ✅ Use :focus-visible for keyboard-only focus */
:focus {
outline: none;
}
:focus-visible {
outline: 2px solid #005fcc;
outline-offset: 2px;
}
/* ✅ Or custom focus stylesRead more
name: accessibility description: Audit and improve web accessibility following WCAG 2.1 guidelines. Use when asked to "improve accessibility", "a11y audit", "WCAG compliance", "screen reader support", "keyboard navigation", or "make accessible". Do NOT use for SEO (use seo), performance (use core-web-vitals), or comprehensive site audits covering multiple areas (use web-quality-audit). license: MIT metadata: author: web-quality-skills version: '1.0'
Accessibility (a11y)
Comprehensive accessibility guidelines based on WCAG 2.1 and Lighthouse accessibility audits. Goal: make content usable by everyone, including people with disabilities.
WCAG Principles: POUR
| Principle | Description | | ------------------ | ------------------------------------------------- | | **P**erceivable | Content can be perceived through different senses | | **O**perable | Interface can be operated by all users | | **U**nderstandable | Content and interface are understandable | | **R**obust | Content works with assistive technologies |
Conformance levels
| Level | Requirement | Target | | ------- | ---------------------- | ----------------------------------------------------- | | **A** | Minimum accessibility | Must pass | | **AA** | Standard compliance | Should pass (legal requirement in many jurisdictions) | | **AAA** | Enhanced accessibility | Nice to have |
---
Perceivable
Text alternatives (1.1)
**Images require alt text:**
<!-- ❌ Missing alt -->
<img src="chart.png" />
<!-- ✅ Descriptive alt -->
<img src="chart.png" alt="Bar chart showing 40% increase in Q3 sales" />
<!-- ✅ Decorative image (empty alt) -->
<img src="decorative-border.png" alt="" role="presentation" />
<!-- ✅ Complex image with longer description -->
<figure>
<img src="infographic.png" alt="2024 market trends infographic" aria-describedby="infographic-desc" />
<figcaption id="infographic-desc">
<!-- Detailed description -->
</figcaption>
</figure>**Icon buttons need accessible names:**
<!-- ❌ No accessible name --> <button> <svg><!-- menu icon --></svg> </button> <!-- ✅ Using aria-label --> <button aria-label="Open menu"> <svg aria-hidden="true"><!-- menu icon --></svg> </button> <!-- ✅ Using visually hidden text --> <button> <svg aria-hidden="true"><!-- menu icon --></svg> <span class="visually-hidden">Open menu</span> </button>
**Visually hidden class:**
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}Color contrast (1.4.3, 1.4.6)
| Text Size | AA minimum | AAA enhanced | | ---------------------------------- | ---------- | ------------ | | Normal text (< 18px / < 14px bold) | 4.5:1 | 7:1 | | Large text (≥ 18px / ≥ 14px bold) | 3:1 | 4.5:1 | | UI components & graphics | 3:1 | 3:1 |
/* ❌ Low contrast (2.5:1) */
.low-contrast {
color: #999;
background: #fff;
}
/* ✅ Sufficient contrast (7:1) */
.high-contrast {
color: #333;
background: #fff;
}
/* ✅ Focus states need contrast too */
:focus-visible {
outline: 2px solid #005fcc;
outline-offset: 2px;
}**Don't rely on color alone:**
<!-- ❌ Only color indicates error -->
<input class="error-border" />
<style>
.error-border {
border-color: red;
}
</style>
<!-- ✅ Color + icon + text -->
<div class="field-error">
<input aria-invalid="true" aria-describedby="email-error" />
<span id="email-error" class="error-message">
<svg aria-hidden="true"><!-- error icon --></svg>
Please enter a valid email address
</span>
</div>Media alternatives (1.2)
<!-- Video with captions --> <video controls> <source src="video.mp4" type="video/mp4" /> <track kind="captions" src="captions.vtt" srclang="en" label="English" default /> <track kind="descriptions" src="descriptions.vtt" srclang="en" label="Descriptions" /> </video> <!-- Audio with transcript --> <audio controls> <source src="podcast.mp3" type="audio/mp3" /> </audio> <details> <summary>Transcript</summary> <p>Full transcript text...</p> </details>
---
Operable
Keyboard accessible (2.1)
**All functionality must be keyboard accessible:**
// ❌ Only handles click
element.addEventListener('click', handleAction)
// ✅ Handles both click and keyboard
element.addEventListener('click', handleAction)
element.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault()
handleAction()
}
})**No keyboard traps:**
// Modal focus management
function openModal(modal) {
const focusableElements = modal.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])',
)
const firstElement = focusableElements[0]
const lastElement = focusableElements[focusableElements.length - 1]
// Trap focus within modal
modal.addEventListener('keydown', (e) => {
if (e.key === 'Tab') {
if (e.shiftKey && document.activeElement === firstElement) {
e.preventDefault()
lastElement.focus()
} else if (!e.shiftKey && document.activeElement === lastElement) {
e.preventDefault()
firstElement.focus()
}
}
if (e.key === 'Escape') {
closeModal()
}
})
firstElement.focus()
}Focus visible (2.4.7)
/* ❌ Never remove focus outlines */
*:focus {
outline: none;
}
/* ✅ Use :focus-visible for keyboard-only focus */
:focus {
outline: none;
}
:focus-visible {
outline: 2px solid #005fcc;
outline-offset: 2px;
}
/* ✅ Or custom focus stylesThe secure, validated skill registry for professional AI coding agents. Extend Antigravity, Claude Code, Cursor, Copilot and more with absolute confidence.
Repo: tech-leads-club/agent-skills
Other skills on tech-leads-club-agent-skills.
- /component-common-domain-detection
Finds duplicate business logic spread across multiple components and suggests consolidation. Use when asking "where is this logic duplicated?", "find common code between services", "what can be consolidated?", "detect shared domain logic", or analyzing component overlap before
Open skill - /component-flattening-analysis
Detects misplaced classes and fixes component hierarchy problems — finds code that should belong inside a component but sits at the root level. Use when asking "clean up component structure", "find orphaned classes", "fix module hierarchy", "flatten nested components", or
Open skill - /component-identification-sizing
Maps architectural components in a codebase and measures their size to identify what should be extracted first. Use when asking "how big is each module?", "what components do I have?", "which service is too large?", "analyze codebase structure", "size my monolith", or planning
Open skill - /coupling-analysis
Analyzes coupling between modules using the three-dimensional model (strength, distance, volatility) from "Balancing Coupling in Software Design". Use when asking "are these modules too coupled?", "show me dependencies", "analyze integration quality", "which modules should I
Open skill - /decomposition-planning-roadmap
Creates step-by-step decomposition plans and migration roadmaps for breaking apart monolithic applications. Use when asking "what order should I extract services?", "plan my migration", "create a decomposition roadmap", "prioritize what to split", "monolith to microservices
Open skill - /domain-analysis
Maps business domains and suggests service boundaries in any codebase using DDD Strategic Design. Use when asking "what are the domains in this codebase?", "where should I draw service boundaries?", "identify bounded contexts", "classify subdomains", "DDD analysis", or analyzing
Open skill

