wcag
WCAG 2.2 Web Content Accessibility Guidelines. Covers conformance levels A/AA/AAA, success criteria, testing with axe-core, and common accessibility patterns. USE WHEN: user mentions "accessibility", "a11y", "WCAG", "screen reader", "ARIA", asks about "color contrast", "keyboard navigation", "accessible forms", "compliance", "ADA", "Section 508" DO NOT USE FOR: automated testing implementation - use `axe-core` instead
What this skill does
# WCAG 2.2 Accessibility
> **Deep Knowledge**: Use `mcp__documentation__fetch_docs` with technology: `wcag` for comprehensive WCAG guidelines, success criteria, and techniques.
## When NOT to Use This Skill
- **Automated testing setup** - Use the `axe-core` skill for integrating axe testing tools
- **Component library accessibility** - Use framework-specific skills (e.g., React, Vue) for accessible component patterns
- **Design systems** - Use UI library skills for pre-built accessible components
- **ARIA implementation only** - This skill covers broader WCAG compliance, not just ARIA
## Official References
| Resource | URL |
|----------|-----|
| WCAG 2.2 Spec | https://www.w3.org/TR/WCAG22/ |
| Quick Reference | https://www.w3.org/WAI/WCAG22/quickref/ |
| Understanding WCAG | https://www.w3.org/WAI/WCAG22/Understanding/ |
| axe-core | https://github.com/dequelabs/axe-core |
| WAI-ARIA | https://www.w3.org/TR/wai-aria-1.2/ |
---
## Conformance Levels
| Level | Description | Legal Requirement |
|-------|-------------|-------------------|
| **A** | Minimum accessibility | Rarely sufficient |
| **AA** | Standard accessibility | Most regulations (ADA, EN 301 549) |
| **AAA** | Enhanced accessibility | Specialized contexts |
### WCAG 2.2 Success Criteria Count
| Level | New in 2.2 | Total |
|-------|------------|-------|
| A | 0 | 30 |
| AA | 6 | 24 |
| AAA | 3 | 31 |
---
## POUR Principles
### 1. Perceivable
| Guideline | Key Criteria | Level |
|-----------|--------------|-------|
| **1.1 Text Alternatives** | All non-text content has text alternative | A |
| **1.2 Time-based Media** | Captions, audio descriptions | A-AAA |
| **1.3 Adaptable** | Content structure, meaningful sequence | A |
| **1.4 Distinguishable** | Color contrast, resize text, spacing | A-AAA |
```tsx
// Text alternatives
<img src="chart.png" alt="Q3 sales increased 25% compared to Q2" />
// Decorative images
<img src="divider.png" alt="" role="presentation" />
// Color contrast (4.5:1 for normal text, 3:1 for large text)
// Use tools: WebAIM Contrast Checker, axe DevTools
```
### 2. Operable
| Guideline | Key Criteria | Level |
|-----------|--------------|-------|
| **2.1 Keyboard** | All functionality via keyboard | A |
| **2.2 Enough Time** | Adjustable time limits | A-AAA |
| **2.4 Navigable** | Skip links, focus order, focus visible | A-AAA |
| **2.5 Input Modalities** | Target size, motion alternatives | A-AAA |
```tsx
// Skip link
<a href="#main-content" className="skip-link">
Skip to main content
</a>
// Focus visible (2.4.7)
button:focus {
outline: 3px solid #005fcc;
outline-offset: 2px;
}
// Target size minimum (2.5.8) - 24x24 CSS pixels
.button {
min-width: 44px;
min-height: 44px;
padding: 12px 16px;
}
```
### 3. Understandable
| Guideline | Key Criteria | Level |
|-----------|--------------|-------|
| **3.1 Readable** | Language of page, unusual words | A-AAA |
| **3.2 Predictable** | Consistent navigation, identification | A-AA |
| **3.3 Input Assistance** | Error identification, labels | A-AAA |
```tsx
// Language of page (3.1.1)
<html lang="en">
// Error identification (3.3.1)
<div role="alert" aria-live="assertive">
Email is required and must be valid
</div>
// Labels (3.3.2)
<label htmlFor="email">Email Address</label>
<input id="email" type="email" aria-describedby="email-hint" />
<span id="email-hint">We'll never share your email</span>
```
### 4. Robust
| Guideline | Key Criteria | Level |
|-----------|--------------|-------|
| **4.1 Compatible** | Valid HTML, name/role/value | A |
```tsx
// Name, Role, Value (4.1.2)
<button aria-pressed="true" aria-label="Favorite this item">
★
</button>
// Custom controls
<div
role="slider"
aria-valuemin={0}
aria-valuemax={100}
aria-valuenow={50}
aria-label="Volume"
tabIndex={0}
/>
```
---
## New in WCAG 2.2
### Level AA (Required)
| Criterion | Description |
|-----------|-------------|
| **2.4.11 Focus Not Obscured (Minimum)** | Focused element at least partially visible |
| **2.4.13 Focus Appearance** | Focus indicator meets size/contrast requirements |
| **2.5.7 Dragging Movements** | Single pointer alternative to drag |
| **2.5.8 Target Size (Minimum)** | 24x24 CSS pixels minimum |
| **3.2.6 Consistent Help** | Help in consistent location |
| **3.3.7 Redundant Entry** | Don't require re-entering info |
### Level AAA
| Criterion | Description |
|-----------|-------------|
| **2.4.12 Focus Not Obscured (Enhanced)** | Focused element fully visible |
| **3.3.8 Accessible Authentication (Minimum)** | No cognitive function test |
| **3.3.9 Accessible Authentication (Enhanced)** | No object/content recognition |
---
## Common Patterns
### Modal Dialog
```tsx
function Modal({ isOpen, onClose, title, children }) {
const modalRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (isOpen) {
// Trap focus inside modal
modalRef.current?.focus();
// Prevent body scroll
document.body.style.overflow = 'hidden';
}
return () => {
document.body.style.overflow = '';
};
}, [isOpen]);
if (!isOpen) return null;
return (
<div
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
ref={modalRef}
tabIndex={-1}
onKeyDown={(e) => e.key === 'Escape' && onClose()}
>
<h2 id="modal-title">{title}</h2>
{children}
<button onClick={onClose}>Close</button>
</div>
);
}
```
### Dropdown Menu
```tsx
function Dropdown({ label, items }) {
const [isOpen, setIsOpen] = useState(false);
const [activeIndex, setActiveIndex] = useState(-1);
const handleKeyDown = (e: KeyboardEvent) => {
switch (e.key) {
case 'ArrowDown':
e.preventDefault();
setActiveIndex(i => Math.min(i + 1, items.length - 1));
break;
case 'ArrowUp':
e.preventDefault();
setActiveIndex(i => Math.max(i - 1, 0));
break;
case 'Escape':
setIsOpen(false);
break;
case 'Enter':
case ' ':
if (activeIndex >= 0) items[activeIndex].onClick();
break;
}
};
return (
<div onKeyDown={handleKeyDown}>
<button
aria-haspopup="menu"
aria-expanded={isOpen}
onClick={() => setIsOpen(!isOpen)}
>
{label}
</button>
{isOpen && (
<ul role="menu">
{items.map((item, i) => (
<li
key={item.id}
role="menuitem"
tabIndex={activeIndex === i ? 0 : -1}
aria-current={activeIndex === i}
>
{item.label}
</li>
))}
</ul>
)}
</div>
);
}
```
### Form with Validation
```tsx
function Form() {
const [errors, setErrors] = useState<Record<string, string>>({});
return (
<form aria-describedby="form-errors">
{Object.keys(errors).length > 0 && (
<div id="form-errors" role="alert" aria-live="polite">
<h2>Please fix the following errors:</h2>
<ul>
{Object.entries(errors).map(([field, msg]) => (
<li key={field}>
<a href={`#${field}`}>{msg}</a>
</li>
))}
</ul>
</div>
)}
<div>
<label htmlFor="email">
Email <span aria-hidden="true">*</span>
<span className="sr-only">(required)</span>
</label>
<input
id="email"
type="email"
aria-required="true"
aria-invalid={!!errors.email}
aria-describedby={errors.email ? 'email-error' : undefined}
/>
{errors.email && (
<span id="email-error" role="alert">{errors.email}</span>
)}
</div>
</form>
);
}
```
---
## Testing
### Automated Testing with axe-core
```typescript
// Playwright + axe
import { test, expect } from '@playwright/test';
import AxeBuilder from '@axe-core/playwright';
test('homepage has no acceRelated in Writing & Docs
jax-development
IncludedUse this skill when the user is writing, debugging, profiling, refactoring, reviewing, benchmarking, parallelising, exporting, or explaining JAX code, or when they mention JAX, jax.numpy, jit, grad, value_and_grad, vmap, scan, lax, random keys, pytrees, jax.Array, sharding, Mesh, PartitionSpec, NamedSharding, pmap, shard_map, Pallas, XLA, StableHLO, checkify, profiler, or the JAX repo. It helps turn NumPy or PyTorch-style code into pure functional JAX, fix tracer/control-flow/shape/PRNG bugs, remove recompiles and host-device syncs, choose transforms and sharding strategies, inspect jaxpr/lowering/IR, and benchmark compiled code correctly.
nature-article-writer
IncludedDrafts, rewrites, diagnostically critiques, and style-calibrates primary research manuscripts for Nature and Nature Portfolio journals. Use when the user wants a Nature-style title, summary paragraph or abstract, introduction, results, discussion, methods, figure legends, presubmission enquiry, cover letter, reviewer response, or when a scientific draft sounds generic, jargon-heavy, structurally weak, or AI-ish and needs precise, broad-reader-friendly prose without inventing data, analyses, or references. Best for primary research articles and letters rather than reviews or press releases unless explicitly adapting one.
deckrd
IncludedDocument-driven framework that derives requirements, specifications, implementation plans, and executable tasks from goals through structured AI dialogue. Use when user says "write requirements", "create spec", "plan implementation", "derive tasks", "structure this feature", "break down into tasks", or "document this module". Also use for reverse engineering existing code into docs (/deckrd rev). Do NOT use for direct code writing — use /deckrd-coder after tasks are generated. Do NOT use when the user only wants to run or fix existing code without planning.
clinical-decision-support
IncludedGenerate professional clinical decision support (CDS) documents for pharmaceutical and clinical research settings, including patient cohort analyses (biomarker-stratified with outcomes) and treatment recommendation reports (evidence-based guidelines with decision algorithms). Supports GRADE evidence grading, statistical analysis (hazard ratios, survival curves, waterfall plots), biomarker integration, and regulatory compliance. Outputs publication-ready LaTeX/PDF format optimized for drug development, clinical research, and evidence synthesis.
handling-sf-data
IncludedSalesforce data operations with 130-point scoring. Use this skill to create, update, delete, bulk import/export, generate test data, and clean up org records using sf CLI and anonymous Apex. TRIGGER when: user creates test data, performs bulk import/export, uses sf data CLI commands, needs data factory patterns for Apex tests, or needs to seed/clean records in a Salesforce org. DO NOT TRIGGER when: SOQL query writing only (use querying-soql), Apex test execution (use running-apex-tests), or metadata deployment (use deploying-metadata).
accelint-ac-to-playwright
IncludedConvert and validate acceptance criteria for Playwright test automation. Use when user asks to (1) review/evaluate/check if AC are ready for automation, (2) assess if AC can be converted as-is, (3) validate AC quality for Playwright, (4) turn AC into tests, (5) generate tests from acceptance criteria, (6) convert .md bullets or .feature Gherkin files to Playwright specs, (7) create test automation from requirements. Handles both bullet-style markdown and Gherkin syntax with JSON test plan generation and validation.