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
Draft
feat(a11y): WCAG 2.2 AA — V1 complete (5 chunks: infra + AA fixes + generators + CI + page)#1adoistic wants to merge 43 commits into
adoistic wants to merge 43 commits into
Conversation
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>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
/accessibilitypage that exposes every claim with click-through proof.Spec:
docs/superpowers/specs/2026-05-14-accessibility-design.mdPlan:
docs/superpowers/plans/2026-05-14-accessibility-v1.mdWhat lands
Chunk 1 — Bootstrap
apps/a11y-tools/package (zod schema, parser, verifier withlines+anchorevidence);docs/accessibility/conformance.yamlseeded with 86 WCAG SCs + 9 § 508 + 7 EN 301 549; 11a11y:*npm scripts.Chunk 2 — AA blocker fixes
scripts/a11y-contrast-audit.tsregression gate):--rule1.22:1 → 3.92:1 light;--accent-soft2.52:1 → 9.70:1 light; dark + sepia equivalents (15 pairs verified)prefers-color-scheme,prefers-contrast,forced-colorsbcp47Of()+isRtl()helpers normalize corpus's long-form (Urdu/arabic) to BCP-47 (ur-Arab); variant pages emit<article lang dir>;/aboutwraps 16 foreign-term spans:dir(rtl)overrides inreader.cssrole,aria-expanded,aria-controls,aria-activedescendant, arrow-key navigation; native search clear button restoredChunk 3 — Generators
docs/accessibility/vpat-v1.0.html(105 table rows)docs/accessibility/statement-en301549.html(EU/US/India enforcement)apps/site/src/lib/conformance.generated.ts(typed, drives the page)a11y:generate vpat | annex-f | matrixChunk 4 — CI workflow + 8 journeys
pa11y-ci,@guidepup/guidepup,@guidepup/playwright.github/workflows/a11y.yml— 4 parallel jobs (Ubuntu static, Ubuntu synthetic, macOS VoiceOver, Windows NVDA) +commit-resultsthat pushes[skip ci]artifact refresh to mainChunk 5 —
/accessibilitypage + footer linkapps/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)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 fordocs/accessibility/test-runs/apps/site/scripts/prepare-a11y-artifacts.ts— mirrorsdocs/accessibility/into Astro's public dir so the page can link to its own VPAT/Annex-F/test-runs via/docs/...URLsEvidence 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-support→supportswith source/test/artifact refs.Plan deviations (flagged)
works.jsonschema didn't match; corpus hasscriptpopulated as long-form names. Pivoted to extendbcp47Of()with normalization maps. Zero data migration.bunx --cwd apps/site …syntax breaks on current bun. Switched tobunx playwright … --config tests/a11y/playwright.config.tsfrom worktree root.bun testauto-loads Playwright.spec.tsfiles as bun tests (8 load failures). Scoped thetestnpm script to explicit rootsapps scripts tests/a11y/lib./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 test— 386 pass, 0 fail (35 net new across Chunks 2-4)bun run a11y:contrast—Contrast audit PASSED. 15 pairs verified.bun run a11y:verify—Conformance 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 deterministicallybun run --cwd apps/site build— succeeds; 1936 pages indexed including/accessibilitybun run a11y:synthetic -- --list— 47 tests across 8 journeys enumerate/accessibility→ 86 matrix rows (60 / 18 / 8 by status), 10aria-labelledbysections, download links resolve 200/docs/accessibility/vpat-v1.0.html→ 200/docs/accessibility/statement-en301549.html→ 200<a href="/accessibility/">Accessibility</a>lang+dir(Chunk 2 carryover, still verified)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-resultsdownloads all 4 artifact buckets, runsbun run a11y:merge-artifactsto reorganize into the canonicaldocs/accessibility/test-runs/<journey>/<sha>/layout, regenerates VPAT/Annex-F/matrix from the new SHA, and pusheschore(a11y): refresh test-run artifacts [skip ci]back to main. Vercel then redeploys; the/accessibilitypage 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
Aapicker (font size + theme override)<abbr>sweepAll earmarked for V2 in a separate spec + plan.
Test plan
bun installresolves cleanlybun run testpasses (386 tests)bun run a11y:contrastexits 0 (15 pairs verified)bun run a11y:verifyexits 0 with 86/9/7 countbun run a11y:generate {vpat,annex-f,matrix}re-emits artifacts byte-identical (modulo date)bun run --cwd apps/site buildsucceeds/accessibilityrenders with 86 matrix rows + downloads + footer linkcommit-resultsproduces the artifact-refresh commit🤖 Generated with Claude Code