{
  "tool": "VoiceOver AAA Audit Checklist",
  "screenReader": "VoiceOver",
  "platform": "macOS + Safari",
  "standard": "WCAG 2.2 AAA",
  "url": "https://a11yequitas.org",
  "timestamp": "2026-05-24T21:46:25.513Z",
  "summary": {
    "total": 43,
    "checked": 43,
    "percent": 100
  },
  "items": [
    {
      "id": "s1",
      "group": "0. Setup (do once)",
      "sc": "",
      "label": "Confirm core keys: VO = Control+Option, toggle ⌘F5, Rotor VO+U, Read-all VO+A, stop Control, next VO+→.",
      "checked": true
    },
    {
      "id": "s2",
      "group": "0. Setup (do once)",
      "sc": "",
      "label": "Set VoiceOver Utility → Verbosity → High for the audit (but don't design to High-only).",
      "checked": true
    },
    {
      "id": "s3",
      "group": "0. Setup (do once)",
      "sc": "",
      "label": "Test in Safari first, then spot-check Chrome — AT+browser combos differ.",
      "checked": true
    },
    {
      "id": "s4",
      "group": "0. Setup (do once)",
      "sc": "",
      "label": "Do at least one screen-off pass per page: complete the task by ear alone.",
      "checked": true
    },
    {
      "id": "s5",
      "group": "0. Setup (do once)",
      "sc": "",
      "label": "Decide record format: per-page notes (URL, criterion, pass / N-A reason / defect + repro).",
      "checked": true
    },
    {
      "id": "g1",
      "group": "1. Global / every-page",
      "sc": "2.4.1",
      "label": "[2.4.1] Skip link: first Tab hits 'Skip to main content'; activating moves VO focus into #main.",
      "checked": true
    },
    {
      "id": "g2",
      "group": "1. Global / every-page",
      "sc": "1.3.1 / 2.4.1",
      "label": "[1.3.1 / 2.4.1] Landmark sweep (VO+U → Landmarks): banner, nav, main, contentinfo present and named; no duplicate unlabeled navs.",
      "checked": true
    },
    {
      "id": "g3",
      "group": "1. Global / every-page",
      "sc": "1.3.1 / 2.4.10",
      "label": "[1.3.1 / 2.4.10] Heading sweep (VO+U → Headings): one h1, no skipped levels, coherent outline by ear.",
      "checked": true
    },
    {
      "id": "g4",
      "group": "1. Global / every-page",
      "sc": "2.4.4 / 2.4.9",
      "label": "[2.4.4 / 2.4.9] Link sweep (VO+U → Links): every link makes sense out of context; no 'click here / read more'.",
      "checked": true
    },
    {
      "id": "g5",
      "group": "1. Global / every-page",
      "sc": "1.1.1",
      "label": "[1.1.1] Logo link announces a text name, not 'image' or a filename.",
      "checked": true
    },
    {
      "id": "g6",
      "group": "1. Global / every-page",
      "sc": "1.3.2",
      "label": "[1.3.2] Reading order: VO+A read-all flows logically, matching visual layout.",
      "checked": true
    },
    {
      "id": "g7",
      "group": "1. Global / every-page",
      "sc": "2.4.7 / 2.4.13",
      "label": "[2.4.7 / 2.4.13] VO cursor and visible focus indicator stay together; focus never lands on an empty/unlabeled element.",
      "checked": true
    },
    {
      "id": "g8",
      "group": "1. Global / every-page",
      "sc": "3.1.1 / 3.1.2",
      "label": "[3.1.1 / 3.1.2] Correct voice/pronunciation; html lang set; inline foreign phrases marked.",
      "checked": true
    },
    {
      "id": "g9",
      "group": "1. Global / every-page",
      "sc": "2.1.2",
      "label": "[2.1.2] No keyboard/focus trap: Tab and VO+→ through and back out of every region.",
      "checked": true
    },
    {
      "id": "m1",
      "group": "2. Masthead — font & theme switchers",
      "sc": "4.1.2 / 1.3.1",
      "label": "[4.1.2 / 1.3.1] Font switcher (System/Lexend/Atkinson/OpenDyslexic): each announces name + role + current state; change is announced.",
      "checked": true
    },
    {
      "id": "m2",
      "group": "2. Masthead — font & theme switchers",
      "sc": "4.1.2",
      "label": "[4.1.2] Theme switcher (System/Light/Dark): name + role + selected state announced; selection updates state.",
      "checked": true
    },
    {
      "id": "m3",
      "group": "2. Masthead — font & theme switchers",
      "sc": "1.3.1",
      "label": "[1.3.1] State persists & is perceivable: after choosing OpenDyslexic and navigating back, VO still reports correct selection.",
      "checked": true
    },
    {
      "id": "m4",
      "group": "2. Masthead — font & theme switchers",
      "sc": "2.1.1",
      "label": "[2.1.1] Both switchers reachable and operable via VO+Space / arrows; no mouse-only behavior.",
      "checked": true
    },
    {
      "id": "m5",
      "group": "2. Masthead — font & theme switchers",
      "sc": "1.4.12",
      "label": "[1.4.12] OpenDyslexic is a visual-only change: VO output and reading order unaffected.",
      "checked": true
    },
    {
      "id": "gd1",
      "group": "3. How-to guide pages (content + embedded examples)",
      "sc": "1.3.1",
      "label": "[1.3.1] Tables page: navigate live table with VO table commands — row/column headers announced per cell, caption announced, scope correct.",
      "checked": true
    },
    {
      "id": "gd2",
      "group": "3. How-to guide pages (content + embedded examples)",
      "sc": "1.1.1 / 1.3.1",
      "label": "[1.1.1 / 1.3.1] Charts page (Chart.js bar + doughnut): canvas is aria-hidden/labeled, sibling data table reachable; numbers available by ear.",
      "checked": true
    },
    {
      "id": "gd3",
      "group": "3. How-to guide pages (content + embedded examples)",
      "sc": "1.1.1 / 2.1.1",
      "label": "[1.1.1 / 2.1.1] Charts page (OpenStreetMap WA/OR/CA): text/data equivalent of map content exists; map isn't a pile of image announcements.",
      "checked": true
    },
    {
      "id": "gd4",
      "group": "3. How-to guide pages (content + embedded examples)",
      "sc": "1.1.1",
      "label": "[1.1.1] Images page: informative images announce useful description; decorative ones silent; complex SVGs have reachable text equivalent.",
      "checked": true
    },
    {
      "id": "gd5",
      "group": "3. How-to guide pages (content + embedded examples)",
      "sc": "1.2.x / 4.1.2",
      "label": "[1.2.x / 4.1.2] Videos page: VO operates player controls (name+state); captions toggle announced; transcript present and readable.",
      "checked": true
    },
    {
      "id": "gd6",
      "group": "3. How-to guide pages (content + embedded examples)",
      "sc": "3.1.3 / 3.1.4 / 3.1.5",
      "label": "[3.1.3 / 3.1.4 / 3.1.5] Plain-language by ear: prose holds at Grade 8; abbreviations (ARIA, WCAG, DOJ) expanded or have accessible expansion.",
      "checked": true
    },
    {
      "id": "c1",
      "group": "4. Custom ARIA components",
      "sc": "4.1.2 / 1.3.1",
      "label": "[4.1.2 / 1.3.1] Accordion: headers announce as buttons with aria-expanded state; activation announces change; collapsed content not reachable.",
      "checked": true
    },
    {
      "id": "c2",
      "group": "4. Custom ARIA components",
      "sc": "4.1.2 / 2.1.1",
      "label": "[4.1.2 / 2.1.1] Tabs: tablist + tabs announce role + selected state; arrow keys move; panel associated. Test auto AND manual activation.",
      "checked": true
    },
    {
      "id": "c3",
      "group": "4. Custom ARIA components",
      "sc": "4.1.2 / 2.1.1 / 2.1.2",
      "label": "[4.1.2 / 2.1.1 / 2.1.2] Dropdown/combobox: native select announces value; custom combobox announces role/expanded/active option/selection; Escape returns focus audibly.",
      "checked": true
    },
    {
      "id": "c4",
      "group": "4. Custom ARIA components",
      "sc": "4.1.3",
      "label": "[4.1.3] Live regions: updates announced without moving focus, once, with correct politeness (status vs alert).",
      "checked": true
    },
    {
      "id": "f1",
      "group": "5. Forms (where present)",
      "sc": "1.3.1 / 3.3.2",
      "label": "[1.3.1 / 3.3.2] Every field announces a programmatic label (not just placeholder); required state announced.",
      "checked": true
    },
    {
      "id": "f2",
      "group": "5. Forms (where present)",
      "sc": "3.3.1 / 3.3.3",
      "label": "[3.3.1 / 3.3.3] Errors announced; VO can navigate to the field in error; error text associated, not just colored.",
      "checked": true
    },
    {
      "id": "f3",
      "group": "5. Forms (where present)",
      "sc": "3.3.5 / 2.2.6",
      "label": "[3.3.5 / 2.2.6] AAA help available where claimed (3.3.5); any timeout warned (2.2.6).",
      "checked": true
    },
    {
      "id": "f4",
      "group": "5. Forms (where present)",
      "sc": "1.3.5",
      "label": "[1.3.5] Autocomplete/purpose set so field purpose is programmatically determinable.",
      "checked": true
    },
    {
      "id": "a1",
      "group": "6. AAA-specific by-ear checks",
      "sc": "2.4.8",
      "label": "[2.4.8] Location: breadcrumb or current-page indicator announced so a VO user knows where they are.",
      "checked": true
    },
    {
      "id": "a2",
      "group": "6. AAA-specific by-ear checks",
      "sc": "2.4.12 / 2.4.13",
      "label": "[2.4.12 / 2.4.13] Focus not obscured by sticky header/footer; focus indicator substantial (visual + VO-cursor correlation).",
      "checked": true
    },
    {
      "id": "a3",
      "group": "6. AAA-specific by-ear checks",
      "sc": "1.4.6 / 1.4.8",
      "label": "[1.4.6 / 1.4.8] Enhanced contrast holds across theme + font combos; check OpenDyslexic + dark theme.",
      "checked": true
    },
    {
      "id": "a4",
      "group": "6. AAA-specific by-ear checks",
      "sc": "2.1.3",
      "label": "[2.1.3] Everything operable by keyboard, including map and charts, or a documented accessible alternative.",
      "checked": true
    },
    {
      "id": "a5",
      "group": "6. AAA-specific by-ear checks",
      "sc": "2.2.3 / 2.3.2",
      "label": "[2.2.3 / 2.3.2] No timed content; no flashing in any chart animation.",
      "checked": true
    },
    {
      "id": "a6",
      "group": "6. AAA-specific by-ear checks",
      "sc": "3.2.5",
      "label": "[3.2.5] Font/theme switch and nav don't trigger unexpected context changes; nothing auto-navigates.",
      "checked": true
    },
    {
      "id": "w1",
      "group": "7. Wrap-up",
      "sc": "",
      "label": "Re-run screen-off task test end-to-end on the two most complex pages (charts page, one component demo).",
      "checked": true
    },
    {
      "id": "w2",
      "group": "7. Wrap-up",
      "sc": "",
      "label": "For every AAA criterion you cannot meet, write the N/A rationale into the accessibility statement; match VPAT/ACR language.",
      "checked": true
    },
    {
      "id": "w3",
      "group": "7. Wrap-up",
      "sc": "",
      "label": "Anything VoiceOver flagged that axe/Alfa/Insights passed → new Playwright assertion or permanent manual line-item.",
      "checked": true
    },
    {
      "id": "w4",
      "group": "7. Wrap-up",
      "sc": "",
      "label": "Record browser/AT versions (Safari + VoiceOver build, macOS version).",
      "checked": true
    }
  ]
}