test(a11y): add three-tier accessibility audit tooling (#31)
* test(a11y): add three-tier accessibility audit tooling
Add Playwright + axe-core e2e tests for all 8 page types, pa11y-ci
with WCAG2AA standard, and Lighthouse CI with accessibility score >= 95
assertion. Replace basic axe-core/cli CI job with proper three-tool
pipeline including artifact uploads. Add manual VoiceOver and keyboard
walkthrough checklists for human review.
* fix(ci): build in accessibility job and fix standalone path
Next.js standalone output mirrors the absolute filesystem path. Build
within the accessibility job instead of downloading artifacts to ensure
paths match. Start server before Playwright tests with reuseExistingServer.
* fix(ci): use flat standalone paths for CI compatibility
Next.js standalone output mirrors absolute filesystem paths locally but
uses flat paths on CI runners. Use simple flat paths in CI workflow and
dynamic path discovery in Playwright config for cross-platform support.
* fix(a11y): increase destructive color contrast for dark mode
Override --color-destructive in dark mode with #ff6369 (red-dark-11)
for sufficient contrast against dark backgrounds. The previous #ce2c31
only achieved 3.53:1 ratio, below the WCAG AA minimum of 4.5:1.
* fix(a11y): use Radix var refs for destructive colors
Replace hardcoded destructive color values with var(--red-11),
var(--red-12), and var(--red-1) references so Radix dark mode
automatically provides AA-compliant contrast in both color schemes.
Light: #ce2c31 text (5.21:1 vs white bg)
Dark: #ff9592 text (8.95:1 vs dark bg)
* fix(ci): install Chrome for pa11y-ci and Lighthouse
pa11y-ci uses Puppeteer which needs its own Chrome binary. Install it
explicitly via npx puppeteer browsers install. Set CHROME_PATH for
Lighthouse CI to use system Chrome.
* fix(ci): use pnpm exec for puppeteer browser install
* fix(ci): use system Chrome for pa11y-ci in CI
Convert .pa11yci.json to .pa11yci.js to conditionally set
executablePath to system Chrome in CI environment. Removes the
separate Chrome installation step.
* fix(ci): remove dynamic routes from Lighthouse CI config
Dynamic routes (/c/[slug], /t/[slug]/[rkey], /u/[handle]) return 404
without a running API backend, causing Lighthouse to fail. Only test
static routes that render without the API.
authored by