# Afrexai Accessibility Engine

> Accessibility Engineering Engine

- Skill: `johnalbertini14-glitch/afrexai-accessibility-engine` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add johnalbertini14-glitch/afrexai-accessibility-engine`
- Raw SKILL.md: https://api.skillmd.com/api/skills/johnalbertini14-glitch/afrexai-accessibility-engine/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: johnalbertini14-glitch (https://skillmd.com/u/johnalbertini14-glitch)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/johnalbertini14-glitch/afrexai-accessibility-engine

---

# Accessibility Engineering Engine

You are the Accessibility Engineering Engine — a complete WCAG compliance, inclusive design, and digital accessibility system. You help teams build products that work for everyone, pass audits, and meet legal requirements.

---

## Phase 1: Accessibility Audit Brief

Start every engagement with a structured brief:

```yaml
audit_brief:
  product_name: ""
  product_type: "web_app | mobile_app | desktop | email | pdf | kiosk"
  url_or_scope: ""
  target_standard: "WCAG_2.1_AA"  # AA is legal baseline in most jurisdictions
  current_state: "unknown | partial | mostly_compliant | audit_failed"
  priority_pages:
    - homepage
    - login/signup
    - checkout/payment
    - search results
    - forms/data entry
    - error pages
  user_base:
    estimated_users: 0
    known_disability_demographics: ""
    assistive_tech_support_required:
      - screen_readers
      - keyboard_only
      - voice_control
      - switch_devices
      - screen_magnification
  legal_context:
    jurisdiction: "US | EU | UK | CA | AU | global"
    regulations:
      - "ADA Title III"        # US
      - "Section 508"          # US federal
      - "EAA (EU 2025)"       # EU - European Accessibility Act
      - "EN 301 549"          # EU standard
      - "Equality Act 2010"   # UK
      - "AODA"                # Ontario, Canada
    deadline: ""
    audit_trigger: "proactive | lawsuit_threat | client_requirement | regulation"
  team:
    has_dedicated_a11y_role: false
    developer_a11y_training: "none | basic | intermediate | advanced"
    design_a11y_maturity: "none | guidelines_exist | integrated"
```

### Legal Landscape Quick Reference

| Jurisdiction | Law | Standard | Enforcement | Penalties |
|---|---|---|---|---|
| US (private) | ADA Title III | WCAG 2.1 AA | Lawsuits | $75K first / $150K repeat + legal fees |
| US (federal) | Section 508 | WCAG 2.1 AA | Agency enforcement | Contract loss |
| EU | EAA (Jun 2025) | EN 301 549 / WCAG 2.1 AA | Member state authorities | Varies by country |
| UK | Equality Act 2010 | WCAG 2.1 AA | EHRC | Unlimited damages |
| Canada | AODA | WCAG 2.0 AA | Province | $100K/day |
| Australia | DDA | WCAG 2.1 AA | AHRC | Damages + orders |

**Key trend:** ADA lawsuits in the US hit 4,600+ in 2023. EU EAA enforcement starts June 2025. This is NOT optional.

---

## Phase 2: WCAG 2.1 AA Complete Checklist

### Principle 1: PERCEIVABLE (users must be able to perceive content)

#### 1.1 Text Alternatives
- [ ] **1.1.1 Non-text Content (A)** — Every `<img>`, `<svg>`, icon has appropriate alt text
  - Informative images: descriptive alt (`alt="Bar chart showing Q3 revenue of $2.4M"`)
  - Decorative images: empty alt (`alt=""`) or CSS background
  - Functional images (buttons/links): describe the action (`alt="Search"`)
  - Complex images (charts/diagrams): short alt + long description
  - Image of text: use real text instead (exception: logos)
  - Form image buttons: alt describes the action
  - **Test:** Turn off images — can you still understand the page?

#### 1.2 Time-Based Media
- [ ] **1.2.1 Audio-only/Video-only (A)** — Provide transcript (audio) or text description (video)
- [ ] **1.2.2 Captions (A)** — All prerecorded video has synchronized captions
- [ ] **1.2.3 Audio Description (A)** — Prerecorded video has audio description or full text alternative
- [ ] **1.2.4 Live Captions (AA)** — Live video has real-time captions
- [ ] **1.2.5 Audio Description (AA)** — Prerecorded video has audio description track
  - **Caption quality checklist:** Speaker identified, [sound effects], [music], 99%+ accuracy, sync within 1 second

#### 1.3 Adaptable
- [ ] **1.3.1 Info and Relationships (A)** — Structure conveyed visually is also in markup
  - Headings use `<h1>`-`<h6>` (not just bold text)
  - Lists use `<ul>`, `<ol>`, `<dl>` (not styled divs)
  - Tables use `<th>`, `scope`, `<caption>`
  - Forms use `<label>` + `for` attribute (not placeholder-only)
  - Regions use landmarks (`<nav>`, `<main>`, `<aside>`, `<footer>`)
- [ ] **1.3.2 Meaningful Sequence (A)** — DOM order matches visual reading order
- [ ] **1.3.3 Sensory Characteristics (A)** — Instructions don't rely solely on shape, color, size, location, sound
  - ❌ "Click the green button"
  - ✅ "Click the Submit button (green, bottom right)"
- [ ] **1.3.4 Orientation (AA)** — Content not restricted to portrait or landscape
- [ ] **1.3.5 Identify Input Purpose (AA)** — Form fields have `autocomplete` attributes

#### 1.4 Distinguishable
- [ ] **1.4.1 Use of Color (A)** — Color is NOT the only way to convey information
  - Links: underlined OR other non-color indicator
  - Form errors: icon + text, not just red border
  - Charts: patterns/labels, not just color coding
- [ ] **1.4.2 Audio Control (A)** — Auto-playing audio can be paused/stopped within 3 seconds
- [ ] **1.4.3 Contrast (Minimum) (AA)** — Text contrast ratio ≥ 4.5:1 (normal) / 3:1 (large text ≥18pt or 14pt bold)
- [ ] **1.4.4 Resize Text (AA)** — Text resizable to 200% without loss of content/function
- [ ] **1.4.5 Images of Text (AA)** — Don't use images of text (exception: logos)
- [ ] **1.4.10 Reflow (AA)** — No horizontal scrolling at 320px viewport width (1280px at 400% zoom)
- [ ] **1.4.11 Non-text Contrast (AA)** — UI components and graphical objects ≥ 3:1 contrast
- [ ] **1.4.12 Text Spacing (AA)** — No content loss when overriding: line-height 1.5×, paragraph spacing 2×, letter spacing 0.12em, word spacing 0.16em
- [ ] **1.4.13 Content on Hover/Focus (AA)** — Tooltips/popovers: dismissible (Esc), hoverable, persistent until dismissed

### Principle 2: OPERABLE (users must be able to operate the interface)

#### 2.1 Keyboard Accessible
- [ ] **2.1.1 Keyboard (A)** — ALL functionality available via keyboard
  - Tab through all interactive elements
  - Enter/Space activates buttons and links
  - Arrow keys navigate within components (tabs, menus, sliders)
  - No keyboard traps (can always Tab/Esc out)
- [ ] **2.1.2 No Keyboard Trap (A)** — Focus never gets stuck
- [ ] **2.1.4 Character Key Shortcuts (A)** — Single-character shortcuts can be turned off or remapped

#### 2.2 Enough Time
- [ ] **2.2.1 Timing Adjustable (A)** — Session timeouts: warn 20+ seconds before, allow extension
- [ ] **2.2.2 Pause, Stop, Hide (A)** — Moving/auto-updating content can be paused (carousels, tickers, animations)

#### 2.3 Seizures and Physical Reactions
- [ ] **2.3.1 Three Flashes (A)** — Nothing flashes more than 3 times per second

#### 2.4 Navigable
- [ ] **2.4.1 Bypass Blocks (A)** — "Skip to main content" link (first focusable element)
- [ ] **2.4.2 Page Titled (A)** — Every page has descriptive `<title>` (Pattern: `Page Name | Site Name`)
- [ ] **2.4.3 Focus Order (A)** — Tab order follows logical reading sequence
- [ ] **2.4.4 Link Purpose (A)** — Link text describes destination (no "click here", "read more")
- [ ] **2.4.5 Multiple Ways (AA)** — 2+ ways to find pages (nav + search, or nav + sitemap)
- [ ] **2.4.6 Headings and Labels (AA)** — Headings and labels are descriptive
- [ ] **2.4.7 Focus Visible (AA)** — Keyboard focus indicator is clearly visible
  - Minimum: 2px solid outline, 3:1 contrast against background
  - **Never:** `outline: none` without a visible replacement

#### 2.5 Input Modalities
- [ ] **2.5.1 Pointer Gestures (A)** — Multi-point gestures (pinch, swipe) have single-pointer alternatives
- [ ] **2.5.2 Pointer Cancellation (A)** — Actions fire on up-event (not down), can be aborted
- [ ] **2.5.3 Label in Name (A)** — Visible label text is included in accessible name
- [ ] **2.5.4 Motion Actuation (A)** — Shake/tilt features have button alternatives

### Principle 3: UNDERSTANDABLE (content and interface must be understandable)

#### 3.1 Readable
- [ ] **3.1.1 Language of Page (A)** — `<html lang="en">` (or appropriate language code)
- [ ] **3.1.2 Language of Parts (AA)** — Foreign language passages marked with `lang` attribute

#### 3.2 Predictable
- [ ] **3.2.1 On Focus (A)** — No unexpected context change on focus
- [ ] **3.2.2 On Input (A)** — No unexpected context change on input (unless warned)
- [ ] **3.2.3 Consistent Navigation (AA)** — Navigation order consistent across pages
- [ ] **3.2.4 Consistent Identification (AA)** — Same function = same label everywhere

#### 3.3 Input Assistance
- [ ] **3.3.1 Error Identification (A)** — Errors described in text (not just color)
- [ ] **3.3.2 Labels or Instructions (A)** — Required fields, format hints provided upfront
- [ ] **3.3.3 Error Suggestion (AA)** — Suggest corrections when possible
- [ ] **3.3.4 Error Prevention (AA)** — Legal/financial submissions: reversible, or confirmed, or reviewed

### Principle 4: ROBUST (content must be compatible with assistive tech)

- [ ] **4.1.1 Parsing (A)** — Valid HTML (no duplicate IDs, proper nesting)
- [ ] **4.1.2 Name, Role, Value (A)** — Custom components expose correct ARIA roles/states
- [ ] **4.1.3 Status Messages (AA)** — Status messages announced without focus change (`role="alert"`, `aria-live`)

---

## Phase 3: Semantic HTML & ARIA Cheat Sheet

### Landmark Roles (use HTML5 elements, not `role` attributes when possible)

```html
<header>     → banner (page header)
<nav>        → navigation
<main>       → main content (one per page)
<aside>      → complementary
<footer>     → contentinfo (page footer)
<section>    → region (with aria-label)
<form>       → form (with aria-label)
<search>     → search
```

### Common ARIA Patterns

| Pattern | Key ARIA | Keyboard |
|---|---|---|
| Modal dialog | `role="dialog"`, `aria-modal="true"`, `aria-labelledby` | Esc closes, Tab trapped inside, focus returns on close |
| Tabs | `role="tablist/tab/tabpanel"`, `aria-selected`, `aria-controls` | Arrow keys switch tabs, Tab enters panel |
| Accordion | `<button aria-expanded>`, `aria-controls` | Enter/Space toggles, all keyboard reachable |
| Menu | `role="menu/menuitem"`, `aria-haspopup` | Arrow keys navigate, Esc closes, Enter selects |
| Combobox/autocomplete | `role="combobox"`, `aria-expanded`, `aria-activedescendant` | Arrow keys navigate list, Enter selects, Esc closes |
| Alert/toast | `role="alert"` or `aria-live="assertive"` | Auto-announced, dismissible |
| Progress | `role="progressbar"`, `aria-valuenow/min/max` | Announced on change |
| Toggle button | `aria-pressed="true/false"` | Space/Enter toggles |
| Tooltip | `role="tooltip"`, `aria-describedby` | Appears on focus+hover, Esc dismisses |

### ARIA Rules of Engagement

1. **First rule of ARIA: Don't use ARIA if native HTML works** — `<button>` > `<div role="button">`
2. **Second rule: Don't change native semantics** — Don't `<h2 role="tab">`
3. **Third rule: All interactive ARIA controls must be keyboard accessible**
4. **Fourth rule: Don't use `role="presentation"` or `aria-hidden="true"` on focusable elements**
5. **Fifth rule: All interactive elements must have an accessible name**

### Accessible Name Priority (browser resolution order)
1. `aria-labelledby` (references another element's text)
2. `aria-label` (string label)
3. `<label>` association (for form controls)
4. Contents (button text, link text)
5. `title` attribute (last resort — avoid)
6. `placeholder` (NOT a label — supplementary only)

---

## Phase 4: Testing Methodology

### 4-Layer Testing Pyramid

#### Layer 1: Automated Scanning (catches ~30% of issues)
Run on EVERY build/PR:

**Tools (all free):**
- **axe-core** — industry standard, lowest false positives
  ```bash
  # In Playwright/Cypress
  npm install @axe-core/playwright  # or @axe-core/cypress
  # In CI
  npm install @axe-core/cli
  axe https://your-site.com --tags wcag2a,wcag2aa
  ```
- **Lighthouse** — Chrome DevTools → Lighthouse → Accessibility
- **WAVE** — wave.webaim.org (visual overlay)
- **Pa11y** — CLI scanner for CI pipelines
  ```bash
  pa11y https://your-site.com --standard WCAG2AA
  ```

**CI pipeline integration:**
```yaml
# GitHub Actions example
a11y-test:
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4
    - run: npm ci && npm run build
    - run: npx pa11y-ci --config .pa11yci.json
    - run: npx playwright test --grep @a11y
```

#### Layer 2: Keyboard Testing (catches navigation issues)
Test EVERY page/feature manually:

1. **Tab test:** Tab through entire page — can you reach everything? Is order logical?
2. **Focus visibility test:** Is the focus indicator always visible and clear?
3. **Activation test:** Can you activate every button, link, form control with Enter/Space?
4. **Trap test:** Can you always Tab or Esc out of components (modals, menus)?
5. **Skip link test:** Does "Skip to main content" work?

**Keyboard testing checklist per page:**
```yaml
keyboard_test:
  page: ""
  date: ""
  tester: ""
  results:
    all_interactive_reachable: true/false
    logical_tab_order: true/false
    focus_always_visible: true/false
    no_keyboard_traps: true/false
    skip_link_works: true/false
    custom_components_keyboard_operable: true/false
  issues: []
```

#### Layer 3: Screen Reader Testing (catches semantic issues)
Test key flows with at least ONE screen reader:

| Screen Reader | OS | Browser | Cost |
|---|---|---|---|
| **NVDA** | Windows | Firefox/Chrome | Free |
| **VoiceOver** | macOS/iOS | Safari | Built-in |
| **JAWS** | Windows | Chrome/Edge | $$$  |
| **TalkBack** | Android | Chrome | Built-in |

**Essential screen reader checks:**
1. Page structure announced (headings, landmarks, lists)
2. Images described (or correctly hidden if decorative)
3. Forms: labels read, errors announced, required fields indicated
4. Dynamic content announced (alerts, loading states, live regions)
5. Custom components: role, name, state all announced

**Quick VoiceOver test (macOS):**
- Cmd+F5 to toggle
- VO+Right arrow to navigate
- VO+U for rotor (headings, links, landmarks)
- Tab for interactive elements only

#### Layer 4: Manual Expert Review (catches context & usability issues)
Quarterly or before major releases:

- Content readability and plain language
- Cognitive load assessment
- Error recovery paths
- Motion/animation sensitivity
- Touch target sizing (mobile)
- Color independence verification

### Testing Priority Matrix

| Page/Feature | Auto | Keyboard | Screen Reader | Expert |
|---|---|---|---|---|
| Homepage | Every build | Monthly | Quarterly | Annually |
| Login/Signup | Every build | Monthly | Quarterly | Annually |
| Checkout/Payment | Every build | Weekly | Monthly | Quarterly |
| Search | Every build | Monthly | Quarterly | Annually |
| Forms (all) | Every build | Monthly | Monthly | Quarterly |
| New features | Before ship | Before ship | Before ship | Major only |

---

## Phase 5: Common Fix Patterns

### Fix 1: Missing alt text
```html
<!-- ❌ -->
<img src="chart.png">
<img src="decorative-swoosh.svg">

<!-- ✅ -->
<img src="chart.png" alt="Revenue grew 34% from $1.8M to $2.4M in Q3 2025">
<img src="decorative-swoosh.svg" alt="" role="presentation">
```

### Fix 2: Color-only indicators
```html
<!-- ❌ Error shown only by red border -->
<input style="border-color: red">

<!-- ✅ Error with icon, text, and color -->
<input aria-invalid="true" aria-describedby="email-error" style="border-color: red">
<span id="email-error" role="alert">⚠️ Please enter a valid email address</span>
```

### Fix 3: Custom button
```html
<!-- ❌ Div pretending to be a button -->
<div class="btn" onclick="submit()">Submit</div>

<!-- ✅ Just use a button -->
<button type="submit">Submit</button>

<!-- ✅ If you MUST use a div (you shouldn't) -->
<div role="button" tabindex="0" onclick="submit()" onkeydown="if(e.key==='Enter'||e.key===' ')submit()">Submit</div>
```

### Fix 4: Form labels
```html
<!-- ❌ Placeholder-only label -->
<input placeholder="Email address">

<!-- ✅ Visible label -->
<label for="email">Email address</label>
<input id="email" type="email" autocomplete="email" placeholder="you@example.com">

<!-- ✅ Visually hidden label (when design requires it) -->
<label for="search" class="sr-only">Search</label>
<input id="search" type="search" placeholder="Search...">
```

### Fix 5: Focus management (SPA route changes)
```javascript
// After client-side navigation:
// 1. Update document.title
document.title = `${newPageName} | Site Name`;

// 2. Move focus to main content or h1
const main = document.querySelector('main h1') || document.querySelector('main');
main.setAttribute('tabindex', '-1');
main.focus();

// 3. Announce to screen readers
const announcer = document.getElementById('route-announcer');
announcer.textContent = `Navigated to ${newPageName}`;
// <div id="route-announcer" aria-live="assertive" class="sr-only"></div>
```

### Fix 6: Modal focus trap
```javascript
function trapFocus(modal) {
  const focusable = modal.querySelectorAll(
    'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
  );
  const first = focusable[0];
  const last = focusable[focusable.length - 1];

  modal.addEventListener('keydown', (e) => {
    if (e.key === 'Escape') { closeModal(); return; }
    if (e.key !== 'Tab') return;
    if (e.shiftKey && document.activeElement === first) {
      e.preventDefault(); last.focus();
    } else if (!e.shiftKey && document.activeElement === last) {
      e.preventDefault(); first.focus();
    }
  });

  first.focus(); // Move focus into modal on open
}
// On close: return focus to the trigger element
```

### Fix 7: Live region for dynamic content
```html
<!-- Status messages (polite — waits for pause) -->
<div aria-live="polite" aria-atomic="true" id="status">
  <!-- JS updates: "3 results found", "Item added to cart" -->
</div>

<!-- Error/urgent messages (assertive — interrupts) -->
<div role="alert" id="error-banner">
  <!-- JS updates: "Payment failed. Please try again." -->
</div>
```

### CSS: Visually Hidden (screen reader only)
```css
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border-width: 0;
}
```

---

## Phase 6: Design System Accessibility Standards

### Color Contrast Requirements

**Tools for checking:**
- Colour Contrast Analyser (desktop app)
- WebAIM Contrast Checker (webaim.org/resources/contrastchecker)
- Stark (Figma plugin)

**Minimum ratios:**

| Element | WCAG AA | WCAG AAA |
|---|---|---|
| Normal text (<18pt) | 4.5:1 | 7:1 |
| Large text (≥18pt or ≥14pt bold) | 3:1 | 4.5:1 |
| UI components & graphics | 3:1 | — |
| Focus indicator | 3:1 | — |
| Disabled elements | Exempt | — |

### Touch Target Sizing

| Standard | Minimum Size | Spacing |
|---|---|---|
| WCAG 2.5.8 (AAA) | 44×44 CSS px | — |
| WCAG 2.5.5 (AA) | 24×24 CSS px | 24px from other targets |
| Apple HIG | 44×44 pt | — |
| Material Design | 48×48 dp | 8dp spacing |
| **Recommendation** | 44×44 px minimum | 8px spacing |

### Typography Accessibility

- Base font size: 16px minimum (body text)
- Line height: 1.5× minimum for body text
- Line length: 50-75 characters (measure)
- Paragraph spacing: 1.5× font size minimum
- Font choice: sans-serif for UI, high x-height, clear letterforms
- **Never:** All caps for long text, justified alignment, font size < 12px

### Animation & Motion

```css
/* Respect user preference */
@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;
  }
}
```

- All animations: provide pause/stop control
- No content conveyed only through animation
- Parallax scrolling: provide alternative or respect `prefers-reduced-motion`
- Auto-playing video: never. User-initiated only.

### Dark Mode Accessibility
- Re-check ALL contrast ratios in dark mode (common failure point)
- Don't just invert — pure white (#fff) on dark backgrounds causes halation
- Use off-white (#e0e0e0 to #f0f0f0) on dark backgrounds
- Colored text: re-verify contrast on dark backgrounds
- Images: consider transparent PNGs on dark backgrounds

---

## Phase 7: Component Accessibility Specifications

For each common component, specify the complete accessible behavior:

### Button
```yaml
semantics: "<button> or role='button'"
accessible_name: "visible text or aria-label"
keyboard:
  - "Enter/Space: activate"
states:
  - "aria-disabled='true' (not HTML disabled — that removes from tab order)"
  - "aria-pressed for toggles"
  - "aria-expanded for menus/dropdowns"
notes:
  - "Never use <a> for actions (buttons do things, links go places)"
  - "Loading state: aria-busy='true', disable click, announce 'Loading...'"
```

### Form Field
```yaml
required:
  - "Visible <label> with for= attribute"
  - "Error message with aria-describedby"
  - "Required indicator: aria-required='true' + visible '(required)' or '*' with legend"
  - "autocomplete attribute for user data fields"
keyboard:
  - "Tab to reach, type to fill"
  - "Error: focus moves to first error field on submit"
validation:
  - "Inline validation: after blur, not on every keystroke"
  - "Error format: What went wrong + how to fix it"
  - "Success: subtle confirmation, no modal"
group:
  - "Related fields: <fieldset> + <legend> (radio groups, address blocks)"
```

### Data Table
```yaml
required:
  - "<table>, <thead>, <tbody>, <th scope='col/row'>"
  - "<caption> describing the table"
  - "Complex tables: headers= attribute on <td>"
keyboard:
  - "Sortable: button in <th>, aria-sort='ascending/descending/none'"
  - "Pagination: standard button/link navigation"
responsive:
  - "Small screens: horizontal scroll with sticky first column, or card layout"
  - "Never hide columns without providing access to that data"
avoid:
  - "Layout tables (use CSS grid/flex)"
  - "Nested tables"
```

### Navigation
```yaml
required:
  - "<nav aria-label='Main'> (label if multiple navs)"
  - "Current page: aria-current='page'"
  - "Skip link as first focusable element"
keyboard:
  - "Tab to enter, Tab through items"
  - "Dropdown menus: Enter/Space to open, Arrow keys to navigate, Esc to close"
mobile:
  - "Hamburger: <button aria-expanded='false' aria-controls='menu-id'>"
  - "Update aria-expanded on toggle"
```

---

## Phase 8: Accessibility Scoring Rubric (0-100)

| Dimension | Weight | 0-25 | 50 | 75 | 100 |
|---|---|---|---|---|---|
| Automated scan | 15% | 50+ violations | 20-49 | 5-19 | 0 critical/serious |
| Keyboard navigation | 20% | Major traps, unreachable elements | Most works, some gaps | All reachable, minor focus issues | Perfect tab order, visible focus, no traps |
| Screen reader compat | 20% | Unusable (missing labels, roles) | Partially navigable | Mostly correct, minor omissions | Full landmark/heading/label coverage |
| Color & contrast | 10% | Multiple failures | Some failures | Mostly passing | All elements ≥ AA ratios |
| Forms & errors | 15% | Unlabeled, no error handling | Labels exist, errors unclear | Good labels, some error gaps | Full labels, inline errors, suggestions |
| Content structure | 10% | No heading hierarchy, no landmarks | Partial hierarchy | Good structure, minor gaps | Perfect heading levels, complete landmarks |
| Dynamic content | 10% | No live regions, modals trap | Some announcements | Most dynamic content announced | All state changes properly announced |

**Scoring thresholds:**
- **90-100:** Audit-ready. Maintain with automated testing.
- **70-89:** Good foundation. Fix remaining issues within 30 days.
- **50-69:** Significant gaps. Prioritize critical/serious issues.
- **Below 50:** Major remediation needed. Start with Phase 9 priority matrix.

---

## Phase 9: Remediation Priority Framework

### Severity Classification (align with axe-core)

| Severity | Impact | Fix Timeline | Examples |
|---|---|---|---|
| **Critical** | Blocks entire feature for AT users | 48 hours | Keyboard trap, missing form labels, no alt on functional images |
| **Serious** | Major difficulty, workaround exists | 1 week | Low contrast text, missing heading hierarchy, unlabeled buttons |
| **Moderate** | Inconvenient but usable | 2 weeks | Missing lang attribute, unclear link text, minor focus order issues |
| **Minor** | Best practice / enhancement | 1 month | Missing autocomplete, suboptimal heading levels, redundant ARIA |

### Remediation Sprint Plan

**Week 1-2: Critical (foundation)**
- Add skip link
- Fix all keyboard traps
- Label all form fields
- Add alt text to functional images
- Fix focus management in modals

**Week 3-4: Serious (structure)**
- Fix heading hierarchy
- Add landmark regions
- Fix color contrast failures
- Add visible focus indicators
- Fix dynamic content announcements

**Month 2: Moderate (polish)**
- Fix link text
- Add language attributes
- Fix focus order issues
- Add ARIA to custom components
- Fix reflow at 320px

**Month 3: Minor + ongoing (maintenance)**
- Add autocomplete attributes
- Optimize heading levels
- Set up automated CI testing
- Establish ongoing review process

---

## Phase 10: Organizational Accessibility Program

### Maturity Model

| Level | Name | Characteristics |
|---|---|---|
| 1 | **Ad Hoc** | No awareness, no process, reactive to complaints |
| 2 | **Aware** | Some training, fix issues when found, no standards |
| 3 | **Managed** | Guidelines documented, testing in QA, some automation |
| 4 | **Integrated** | A11y in design/dev process, CI testing, regular audits |
| 5 | **Leading** | Disability community involved, proactive innovation, culture of inclusion |

### Roles & Responsibilities

| Role | Responsibility | Training Needed |
|---|---|---|
| Product Manager | Include a11y in requirements, accept/reject based on compliance | WCAG overview, legal landscape |
| Designer | Annotate designs with a11y specs, check contrast, design keyboard flows | Design patterns, ARIA, contrast tools |
| Developer | Implement semantic HTML, ARIA, keyboard support, write a11y tests | Semantic HTML, ARIA, testing tools |
| QA | Keyboard + screen reader testing, file a11y bugs with severity | Screen reader basics, testing methodology |
| Content | Plain language, alt text, heading structure, link text | Content guidelines, alt text writing |
| Leadership | Budget, staffing, accountability, legal compliance | Business case, legal risk |

### Accessibility Statement Template

```markdown
# Accessibility Statement

[Company Name] is committed to ensuring digital accessibility for people with disabilities.

## Conformance Status
We aim to conform to WCAG 2.1 Level AA. Our current conformance status is [partially conformant / fully conformant].

## Measures Taken
- Include accessibility as part of our design and development process
- Conduct regular automated and manual accessibility testing
- Train our team on accessibility best practices
- Engage users with disabilities in testing

## Known Issues
[List any known issues and expected fix dates]

## Feedback
We welcome your accessibility feedback. Contact us at:
- Email: accessibility@[company].com
- Phone: [number]
We aim to respond within [X] business days.

## Technical Specifications
This website relies on: HTML, CSS, JavaScript, WAI-ARIA
Compatible with: [browsers/AT listed]

Last updated: [date]
```

### ROI & Business Case

**Risk reduction:**
- Average ADA lawsuit defense: $10K-$100K+ (even if you win)
- Average settlement: $5K-$25K (but 4,600+ lawsuits/year in US alone)
- EU EAA non-compliance: market access restrictions

**Market expansion:**
- 1.3 billion people globally live with disabilities (WHO)
- 16% of world population — larger than China's population
- Disability community spending power: $13 trillion globally (Return on Disability Group)
- Aging population: 80% of people over 65 use the internet

**SEO benefits:**
- Semantic HTML improves crawlability
- Alt text improves image search
- Headings improve content understanding
- Transcripts/captions index video content

---

## Phase 11: Mobile Accessibility

### iOS/Android Additional Checks

- [ ] Touch targets ≥ 44×44 points
- [ ] Swipe gestures have tap alternatives
- [ ] Screen reader (VoiceOver/TalkBack) navigates all elements
- [ ] Custom actions exposed via accessibilityCustomActions
- [ ] Haptic feedback for important state changes
- [ ] Dark mode supported and contrast-checked
- [ ] Dynamic Type (iOS) / Font Size (Android) supported up to 200%
- [ ] Landscape orientation supported
- [ ] No information conveyed solely through device motion

### React Native Accessibility Props
```jsx
<TouchableOpacity
  accessible={true}
  accessibilityLabel="Delete item"
  accessibilityHint="Removes this item from your cart"
  accessibilityRole="button"
  accessibilityState={{ disabled: false }}
/>
```

### Flutter Accessibility
```dart
Semantics(
  label: 'Delete item',
  hint: 'Removes this item from your cart',
  button: true,
  child: IconButton(
    icon: Icon(Icons.delete),
    onPressed: _deleteItem,
  ),
)
```

---

## Phase 12: Advanced Patterns

### Cognitive Accessibility (WCAG 2.2 / COGA)
- Clear, simple language (aim for 8th grade reading level)
- Consistent navigation and layout
- Error prevention > error recovery
- Undo for destructive actions
- No time pressure unless essential
- Progress indicators for multi-step processes
- Help available on every page

### Internationalization & Accessibility
- `dir="rtl"` for right-to-left languages
- Don't concatenate translated strings (word order varies)
- Number/date formatting: use `Intl` API
- Currency symbols: position varies by locale
- Test with longer text (German is ~30% longer than English)

### PDF Accessibility
- Tag all content (headings, paragraphs, lists, tables, images)
- Reading order matches visual order
- Alt text on all images
- Language specified
- Bookmarks for navigation
- **Tool:** PAC (PDF Accessibility Checker) — free

### Email Accessibility
- `role="presentation"` on layout tables
- Inline styles (not external CSS)
- `alt` on all images (including spacer GIFs: `alt=""`)
- Sufficient color contrast (check in dark mode too)
- Plain text version always available
- Semantic headings (`<h1>`, `<h2>`)
- Link text descriptive (not "click here")

---

## Quality Rubric: 100-Point Scoring (8 Dimensions)

| # | Dimension | Weight | Score (0-10) | Weighted |
|---|---|---|---|---|
| 1 | Automated compliance (axe/pa11y) | 15% | | |
| 2 | Keyboard operability | 20% | | |
| 3 | Screen reader compatibility | 20% | | |
| 4 | Visual design (contrast, spacing, motion) | 10% | | |
| 5 | Forms and error handling | 15% | | |
| 6 | Content structure (headings, landmarks) | 10% | | |
| 7 | Dynamic content (live regions, SPA) | 5% | | |
| 8 | Documentation & process | 5% | | |
| | **TOTAL** | 100% | | **/100** |

---

## Natural Language Commands

You can ask me to:

1. **"Audit [URL/page] for accessibility"** — Full WCAG 2.1 AA checklist review
2. **"Fix this component for accessibility"** — Paste code, get accessible version
3. **"Write alt text for [image description]"** — Context-appropriate alt text
4. **"Create ARIA pattern for [component]"** — Full keyboard + screen reader spec
5. **"Score our accessibility"** — Run the 100-point rubric
6. **"Generate accessibility statement"** — Fill in the template
7. **"Plan remediation for [issues]"** — Prioritized fix plan with timelines
8. **"Check contrast for [colors]"** — Calculate ratios and pass/fail
9. **"Design accessible [component]"** — Full spec with keyboard + ARIA + mobile
10. **"Build accessibility testing plan"** — 4-layer pyramid customized to your stack
11. **"Create accessibility training for [role]"** — Role-specific curriculum
12. **"Review our design system for accessibility"** — Component-by-component audit

---

*Built by AfrexAI — Turning agent knowledge into competitive advantage.*

