Skip to content

feat(a11y): WCAG 2.2 AA — V1 complete (5 chunks: infra + AA fixes + generators + CI + page)#1

Draft
adoistic wants to merge 43 commits into
mainfrom
claude/elegant-sammet-f9bc5b
Draft

feat(a11y): WCAG 2.2 AA — V1 complete (5 chunks: infra + AA fixes + generators + CI + page)#1
adoistic wants to merge 43 commits into
mainfrom
claude/elegant-sammet-f9bc5b

Conversation

@adoistic
Copy link
Copy Markdown
Owner

@adoistic adoistic commented May 14, 2026

Summary

All five chunks of the WCAG 2.2 AA implementation. Lands a defensible conformance claim with single-source-of-truth YAML, three AA blocker fixes, three derived-data generators (VPAT 2.5 INT, EN 301 549 Annex F, typed matrix module), a four-job CI workflow that runs real-screen-reader transcripts on every PR, and a public /accessibility page that exposes every claim with click-through proof.

Spec: docs/superpowers/specs/2026-05-14-accessibility-design.md
Plan: docs/superpowers/plans/2026-05-14-accessibility-v1.md

What lands

Chunk 1 — Bootstrap

apps/a11y-tools/ package (zod schema, parser, verifier with lines + anchor evidence); docs/accessibility/conformance.yaml seeded with 86 WCAG SCs + 9 § 508 + 7 EN 301 549; 11 a11y:* npm scripts.

Chunk 2 — AA blocker fixes

  • B.3 contrast (scripts/a11y-contrast-audit.ts regression gate): --rule 1.22:1 → 3.92:1 light; --accent-soft 2.52:1 → 9.70:1 light; dark + sepia equivalents (15 pairs verified)
  • B.5 system-pref CSS: prefers-color-scheme, prefers-contrast, forced-colors
  • B.1 language emission: bcp47Of() + isRtl() helpers normalize corpus's long-form (Urdu/arabic) to BCP-47 (ur-Arab); variant pages emit <article lang dir>; /about wraps 16 foreign-term spans
  • B.2 RTL: :dir(rtl) overrides in reader.css
  • B.4 SearchDialog: combobox/listbox pattern with role, aria-expanded, aria-controls, aria-activedescendant, arrow-key navigation; native search clear button restored

Chunk 3 — Generators

  • VPAT 2.5 INTdocs/accessibility/vpat-v1.0.html (105 table rows)
  • Annex Fdocs/accessibility/statement-en301549.html (EU/US/India enforcement)
  • Matrix TS moduleapps/site/src/lib/conformance.generated.ts (typed, drives the page)
  • CLI dispatcher: a11y:generate vpat | annex-f | matrix

Chunk 4 — CI workflow + 8 journeys

  • New deps: pa11y-ci, @guidepup/guidepup, @guidepup/playwright
  • Playwright config with 3 projects (synthetic / voiceover / nvda); 47 tests across 8 journey specs (homepage, search, catalog, reader-english, reader-original, variant-switch, eval-case, theme-prefs)
  • Helpers: synthetic-transcript (AT-tree dumper, 3 unit tests), guidepup-helpers (VO + NVDA lifecycle), synthesize-audio (espeak-ng fallback), merge-artifacts (CI artifact reorganizer)
  • pa11y config with 7 audited URLs (real corpus slugs)
  • .github/workflows/a11y.yml — 4 parallel jobs (Ubuntu static, Ubuntu synthetic, macOS VoiceOver, Windows NVDA) + commit-results that pushes [skip ci] artifact refresh to main

Chunk 5 — /accessibility page + footer link

  • apps/site/src/pages/accessibility.astro — 10-section audit page (lede + downloads, preferences, audit-yourself, matrix, exceptions, methodology, § 508 + EN 301 549 mappings, recent test runs, JAWS log, report issue)
  • 5 new components under apps/site/src/components/: ConformanceMatrix (4 principle groups, 86 rows, expandable evidence), AccessibilityExceptions, AuditYourself, AccessibilityTestRuns (filesystem-backed), JawsLog (YAML-backed)
  • apps/site/src/lib/test-run-artifacts.ts — build-time reader for docs/accessibility/test-runs/
  • apps/site/scripts/prepare-a11y-artifacts.ts — mirrors docs/accessibility/ into Astro's public dir so the page can link to its own VPAT/Annex-F/test-runs via /docs/... URLs
  • Footer link "Accessibility" on every page (Base.astro)

Evidence in conformance.yaml

WCAG 1.3.1, 1.4.3, 1.4.11, 2.1.1, 2.3.3, 2.4.1, 2.4.6, 2.4.7, 3.1.1, 3.1.2, 4.1.2, 4.1.3 + EN 301 549 § 5.2 — does-not-supportsupports with source/test/artifact refs.

Plan deviations (flagged)

  1. Task 14works.json schema didn't match; corpus has script populated as long-form names. Pivoted to extend bcp47Of() with normalization maps. Zero data migration.
  2. Task 26 — plan's bunx --cwd apps/site … syntax breaks on current bun. Switched to bunx playwright … --config tests/a11y/playwright.config.ts from worktree root.
  3. Task 33 fix-up — bare bun test auto-loads Playwright .spec.ts files as bun tests (8 load failures). Scoped the test npm script to explicit roots apps scripts tests/a11y/lib.
  4. Journey URLs — plan's simplified slugs (/works/bang-i-dara/01/original/) don't exist; used real corpus slugs (mirza-ghalib-diwan-e-ghalib-74ed4c/01-aa-ke-meri-jaan-ko-qarar-nahin-hai, etc.) for journeys + pa11y URLs.

Verification

  • bun run test386 pass, 0 fail (35 net new across Chunks 2-4)
  • bun run a11y:contrastContrast audit PASSED. 15 pairs verified.
  • bun run a11y:verifyConformance YAML verification PASSED (86 criteria, 9 508, 7 EN 301 549 checked).
  • bun run a11y:generate {vpat,annex-f,matrix} — all three regenerate from the YAML deterministically
  • bun run --cwd apps/site build — succeeds; 1936 pages indexed including /accessibility
  • bun run a11y:synthetic -- --list — 47 tests across 8 journeys enumerate
  • End-to-end DOM smoke on dev server:
    • /accessibility → 86 matrix rows (60 / 18 / 8 by status), 10 aria-labelledby sections, download links resolve 200
    • /docs/accessibility/vpat-v1.0.html → 200
    • /docs/accessibility/statement-en301549.html → 200
    • Home page footer → <a href="/accessibility/">Accessibility</a>
    • Variant pages emit lang + dir (Chunk 2 carryover, still verified)
    • Search dialog emits role="combobox" + role="listbox" (Chunk 2 carryover)

CI first-run expectations

Merge → push to main → triggers 4 parallel jobs (static, synthetic, voiceover, nvda). On success, commit-results downloads all 4 artifact buckets, runs bun run a11y:merge-artifacts to reorganize into the canonical docs/accessibility/test-runs/<journey>/<sha>/ layout, regenerates VPAT/Annex-F/matrix from the new SHA, and pushes chore(a11y): refresh test-run artifacts [skip ci] back to main. Vercel then redeploys; the /accessibility page goes live with the first set of CI artifacts.

The plan acknowledges Guidepup on macOS / NVDA on Windows can be flaky on first setup (audio routing permissions, NVDA installation timing). Job-level if: always() ensures artifacts upload even on partial failure.

Out of V1

  • Chrome Aa picker (font size + theme override)
  • Focus-appearance AAA (2.4.13)
  • Target-size AAA (2.5.8)
  • Glossary popovers / <abbr> sweep
  • 3 documented content-type exceptions (WCAG 3.1.3 / 3.1.5 / 3.1.6 — graduate-philosophy corpus)

All earmarked for V2 in a separate spec + plan.

Test plan

  • bun install resolves cleanly
  • bun run test passes (386 tests)
  • bun run a11y:contrast exits 0 (15 pairs verified)
  • bun run a11y:verify exits 0 with 86/9/7 count
  • bun run a11y:generate {vpat,annex-f,matrix} re-emits artifacts byte-identical (modulo date)
  • bun run --cwd apps/site build succeeds
  • /accessibility renders with 86 matrix rows + downloads + footer link
  • First push to main: 4 CI jobs go green; commit-results produces the artifact-refresh commit

🤖 Generated with Claude Code

adoistic and others added 11 commits May 14, 2026 19:14
Showcase-grade accessibility for govt clients (India / EU / US). Single
source of truth (conformance.yaml) generates VPAT 2.5 INT + EN 301 549
Annex F. CI matrix runs axe + pa11y + Playwright synthetic transcripts
on Linux, real VoiceOver via Guidepup on macOS, and real NVDA on Windows
— all free on public-repo runners. Per-PR audio recordings of both
screen readers committed to the repo. /accessibility page surfaces
click-through proof per criterion plus an "audit yourself" section.

V1 (~5 days): three AA blockers (lang attrs, --rule contrast, search
combobox), conformance infra, CI, /accessibility page, system-pref CSS,
RTL on Urdu. V2 (~1-2 weeks later): Aa picker chrome control, focus/
target-size AAA polish, glossary popovers, VPAT v1.1.

Three content-type exceptions documented (3.1.3 / 3.1.5 / 3.1.6 — graduate
philosophy across six languages).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Address spec-review feedback:
- §B.3 point at tokens.css token definitions, not global.css uses
- §B.5 specify prefers-contrast handling for sepia (no override)
- §C.1 YAML example uses real tokens.css line range
- §C.4 pin eval-case journey to the absorbed TODOS.md item
- §D.4 add audio-player accessibility requirement
- §Q1 escalate: implementation plan must resolve before coding
- §Q8 actions/upload-artifact v4 no longer auto-merges
- §Q9 line-number drift mitigation (anchor-based vs exact)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ks, 42 tasks)

Spec → plan transition for WCAG 2.2 AA + AAA-where-feasible.

Five chunks, sequential:
- Chunk 1 (~1,000 lines, Tasks 1-9): apps/a11y-tools/ package, YAML
  schema with zod validation, verifier supporting lines + anchor
  evidence, conformance.yaml seed (86 SCs + 9 Section 508 + 7 EN 301 549
  via one-shot seed-wcag22.ts script).
- Chunk 2 (~1,150 lines, Tasks 10-20): three AA blocker fixes — contrast
  audit script + token bumps (B.3), system-pref CSS (B.5), bcp47Of helpers
  + works.json script field + variant page lang/dir emission (B.1),
  RTL CSS overrides (B.2), SearchDialog combobox + native clear (B.4).
- Chunk 3 (~780 lines, Tasks 21-25): VPAT 2.5 INT generator + EN 301 549
  Annex F generator + matrix TS module generator. HTML-only output;
  PDF deferred to V2.
- Chunk 4 (~770 lines, Tasks 26-33b): three-platform CI matrix (Linux
  static + synthetic Playwright + macOS VoiceOver via Guidepup + Windows
  NVDA via Guidepup), 8 journey specs, commit-results bot, and the
  prepare-a11y-artifacts mirror that makes docs/accessibility/ servable
  by Astro.
- Chunk 5 (~840 lines, Tasks 34-42): /accessibility page (10 sections),
  5 components, filesystem reader for test-runs, footer link wiring,
  conformance.yaml evidence for 1.3.1 / 2.4.1 / 2.4.6 / 2.4.7.

Three open questions (Q1 auto-commit strategy, Q8 download-artifact v4
behavior, Q9 lines-vs-anchor evidence refs) resolved before any code lands.

Plan passed three reviewer rounds: Chunk 1 (re-reviewed for WCAG count
fix + Zod schema fix), Chunk 2 (re-reviewed for contrast-value
correctness + concrete diff anchors), parallel review of Chunks 3-5
(fixed broken Playwright PDF spawn, espeak cleanup, local-artifacts
gitignore, critical Astro artifact-serving mirror).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 14, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
falsafa-site Ready Ready Preview, Comment May 14, 2026 4:37pm

adoistic added 10 commits May 14, 2026 20:43
The corpus already carries script + language fields on every variant (in
docs/accessibility/specs the plan assumed works.json drove this, but the
real source-of-truth is corpus/works/*/chapters/*/meta.json). Values are
long-form ("arabic", "Urdu") rather than ISO 639/15924. Extending
bcp47Of() with two normalization maps lets the variant page emit valid
BCP-47 from corpus data with no schema migration.

Includes the "other" script fallback used by Bang-e-Dara's 100 Urdu
chapters — language alone (ur) still carries correct RTL direction.
@adoistic adoistic changed the title feat(a11y): WCAG 2.2 AA infrastructure — Chunk 1 (bootstrap) feat(a11y): WCAG 2.2 AA — Chunks 1+2 (infrastructure + AA blocker fixes) May 14, 2026
@adoistic adoistic changed the title feat(a11y): WCAG 2.2 AA — Chunks 1+2 (infrastructure + AA blocker fixes) feat(a11y): WCAG 2.2 AA — Chunks 1-3 (infra + AA fixes + generators) May 14, 2026
@adoistic adoistic changed the title feat(a11y): WCAG 2.2 AA — Chunks 1-3 (infra + AA fixes + generators) feat(a11y): WCAG 2.2 AA — Chunks 1-4 (infra + AA fixes + generators + CI) May 14, 2026
@adoistic adoistic changed the title feat(a11y): WCAG 2.2 AA — Chunks 1-4 (infra + AA fixes + generators + CI) feat(a11y): WCAG 2.2 AA — V1 complete (5 chunks: infra + AA fixes + generators + CI + page) May 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant