---
prompt-id: "12"
name: Accessibility audit — WCAG 2.1 AA verification
status: live
mcp: none
model: Sonnet 4.6
environment: Claude.ai or Claude Code
inputs:
  - rendered HTML or component code (paste or file read)
  - output/tokens.css
outputs:
  - a11y report (WCAG 2.1 AA findings, severity-ranked)
chains: [5]
prereqs: ["01", "02", "03"]
documented-in: Ch21 — Quality Gates
---

# Prompt 12 — A11y audit

Audits component code or rendered HTML against WCAG 2.1 AA.
Checks colour contrast, focus-visible, semantic HTML, ARIA correctness, keyboard reachability,
and touch target sizing. Severity-ranked output; actionable fixes for every finding.

---

```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
META-HEADER — run before auditing
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

STEP -2 — DETECT ENVIRONMENT
  Claude Code: save report as output/a11y-report-<date>.md
  Claude.ai:   provide report in chat as copy-ready markdown

STEP -1 — CONTEXT CHECK
  output/tokens.css      → REQUIRED — needed for contrast ratio
                            computation against the token palette
  Component code / HTML  → ask the user: "Paste the HTML or
                            component source you want audited."
                            Accept: .html, .tsx, .vue, .svelte,
                            .css (component file only)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
MAIN PROMPT BODY
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

PROMPT 12 — WCAG 2.1 AA ACCESSIBILITY AUDIT

YOUR ROLE
You are an accessibility engineer running a WCAG 2.1 AA audit.
You review pasted code for conformance across six criteria
categories. For every failure you find, you provide:
  — The failing criterion (WCAG success criterion number + name)
  — The element or pattern that fails
  — The exact fix (a code snippet or attribute change)
  — Severity: Critical / High / Medium

WCAG 2.1 AA CRITERIA TO CHECK

1. COLOUR CONTRAST (SC 1.4.3 / 1.4.11)
   Minimum contrast ratios:
     — Normal text (< 18pt / 14pt bold): 4.5:1
     — Large text (≥ 18pt or 14pt bold): 3:1
     — UI components and graphical objects: 3:1
     — Focus indicator: 3:1 against adjacent colour

   For each text colour + background colour pair found:
     a. Identify the token references (from tokens.css)
     b. Resolve tokens to actual oklch/hex values
     c. Compute contrast ratio (use the WCAG relative luminance
        formula or report the computed ratio you know from the
        archetype spec if already verified)
     d. Mark PASS / FAIL

   Known archetype contrast notes (from spec — verify against
   actual token values, do not assume spec is current):
     Harbor:   #66D9C2 on dark surface — verify ratio
     Sentinel: orange #FF9900 on white = 2.30:1 — WCAG FAIL
               (book-documented; must not use as text on white)
     Current:  all CTAs must pass 4.5:1
     Lattice:  green accent on dark surface — verify
     Meridian: --color-text-primary on white — verify

2. FOCUS VISIBLE (SC 2.4.7 / 2.4.11)
   Every interactive element must have a visible focus indicator.
   Check:
     — Is :focus-visible styled? (not just :focus)
     — Does the focus ring use --focus-ring-width and
       --color-focus-ring tokens?
     — Is outline:none or outline:0 present WITHOUT a
       replacement? (failure)
     — Enhanced: is focus indicator ≥ 2px and ≥ 3:1 contrast?

3. SEMANTIC HTML (SC 1.3.1)
   Check:
     — Buttons use <button>, not <div role="button">
     — Links use <a href>, not <span> with click handler
     — Lists use <ul>/<ol>/<li>
     — Form labels are associated via <label for="..."> or
       aria-label / aria-labelledby
     — Headings are not skipped (h1 → h2 → h3, no h4 after h2)
     — Tables have <th> with scope attribute in headers

4. ARIA CORRECTNESS (SC 4.1.2)
   Check:
     — role attributes match the element's actual behaviour
     — aria-expanded is present on trigger elements
     — aria-controls points to the correct element id
     — aria-live regions used for dynamic content updates
     — No aria-hidden on interactive elements
     — Dialogs have aria-modal="true" and aria-labelledby
     — Custom components that mirror native roles have all
       required ARIA attributes (see ARIA authoring practices)

5. KEYBOARD REACHABILITY (SC 2.1.1)
   Check:
     — All interactive elements reachable by Tab
     — Custom components implement arrow-key navigation where
       expected (menus, tabs, listboxes, radiogroups)
     — Modals trap focus correctly
     — Modal close returns focus to trigger element
     — No keyboard traps (can always escape with Escape or Tab)
     — Skip nav link present and functional

6. TOUCH TARGET SIZE (SC 2.5.5 / 2.5.8)
   Minimum 44×44px for all touch targets (WCAG 2.5.5 AAA,
   but required for WCAG 2.2 AA via 2.5.8 at 24×24 minimum).
   Best practice and Current archetype requirement: 44×44px.
   Check:
     — Buttons, links, form controls: min-height and min-width
       using token (--btn-height-md should be ≥ 44px for
       Current archetype; ≥ 36px minimum for others)
     — Icon-only buttons: at least 44×44px clickable area
     — Checkbox/radio: visual target is augmented with padding

OUTPUT FORMAT

  # A11y Audit Report — <date>
  **Target:** <file(s) audited>
  **Standard:** WCAG 2.1 AA
  **Archetype:** <from chain-state.md>

  ## Summary
  | Severity | Count |
  |----------|-------|
  | Critical | n |
  | High | n |
  | Medium | n |
  | PASS | n |

  ## Critical findings
  | SC | Element | Issue | Fix |
  |----|---------|-------|-----|
  | 1.4.3 | .btn-primary on .dark-surface | contrast 2.8:1 (need 4.5:1) | change --color-cta-text to ... |

  ## High findings
  ...

  ## Medium findings
  ...

  ## Contrast matrix
  | Foreground token | Background token | Ratio | AA (text) | AA (UI) |
  |------------------|------------------|-------|-----------|---------|
  | --color-text-primary | --color-surface-base | 15.3:1 | PASS | PASS |
  ...

  ## Passing checks
  (brief list — confirm what is working correctly)

WHAT NOT TO FLAG
  — Decorative images with empty alt="" — correct usage
  — Presentation role elements — intentional
  — Focus styles on elements that are not keyboard-reachable
    by design (e.g., touch-only controls on native apps)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
META-FOOTER
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

SAVE INSTRUCTION
  Claude Code: output/a11y-report-<YYYY-MM-DD>.md
  Claude.ai:   copy report from chat

CHAIN-STATE LOG
Append to output/chain-state.md:

  ## Prompt 12 — A11y audit
  Date: <today>
  Archetype: <confirmed archetype>
  Files audited: <list>
  Critical: <count>
  High: <count>
  Contrast failures: <count>
  Report saved: output/a11y-report-<date>.md

HANDOFF
  "A11y audit complete. Fix all Critical findings before
   shipping. Re-run this prompt after fixes to confirm
   zero Critical items remain.
   Next → Prompt 13 — Framework wrappers (optional — wraps
   your CSS into React / Vue / Svelte components)."
```
