DESCRIPTION
apps/web/app/design-system/page.tsx gives a starting point, but the component library has no real documentation surface, no automated accessibility checks, and no visual-regression safety net — so it's easy for a future change to silently break a primitive used across dozens of pages. This epic builds the quality-gate layer the design system is missing.
GOAL
Every exported primitive and its variants are browsable/testable in isolation, automated accessibility checks catch a11y regressions, and a visual-regression baseline catches unintended visual changes — all wired into the project's scripts.
REQUIREMENTS
- A documentation surface demonstrating every primitive exported from the component library (
apps/web/components/ui/index.ts) with all its variants/states — either expand /design-system into a real catalog, or add Storybook.
- Live theme toggle (light/dark, and any per-country branding) inside the docs surface, backed by the real
ThemeProvider/useTheme.
- Automated accessibility checks (e.g.
axe-core/jest-axe or an equivalent) run against every documented component, wired into npm run lint or a new npm run test step.
- A visual-regression baseline (e.g. Playwright screenshot tests) for the documented components, with instructions for updating baselines intentionally.
ACCEPTANCE CRITERIA
- Every primitive currently exported from
components/ui/index.ts has a documented page/story showing its variants.
- Accessibility checks run in CI/scripts and fail on a known-bad example (demonstrate in the PR).
- Visual-regression baseline exists and is checked into the repo; a deliberate visual change requires an explicit baseline update.
npm run build, npm run lint, npm run test (new) pass in apps/web with NO VELAR credentials.
NOTES
Relevant files: apps/web/app/design-system/page.tsx, apps/web/components/ui/**, apps/web/package.json (new scripts/deps), docs/FRONTEND_GUIDE.md. Do not change component behavior, only add documentation/testing infrastructure (docs/AGENTS.md §3).
No VELAR credentials required: verifiable locally — no database, secrets, or external APIs.
Difficulty: Advanced
Priority: Medium
PR REQUIREMENTS
- Ship this as a single pull request — do not split into stacked/sequential PRs.
- Your PR description must include
Closes #<this-issue-number> (this issue's GitHub number) so merging auto-closes it.
CAMPAIGN REQUIREMENTS (FWC26)
To be eligible for the reward on this issue, the contributor must:
DESCRIPTION
apps/web/app/design-system/page.tsxgives a starting point, but the component library has no real documentation surface, no automated accessibility checks, and no visual-regression safety net — so it's easy for a future change to silently break a primitive used across dozens of pages. This epic builds the quality-gate layer the design system is missing.GOAL
Every exported primitive and its variants are browsable/testable in isolation, automated accessibility checks catch a11y regressions, and a visual-regression baseline catches unintended visual changes — all wired into the project's scripts.
REQUIREMENTS
apps/web/components/ui/index.ts) with all its variants/states — either expand/design-systeminto a real catalog, or add Storybook.ThemeProvider/useTheme.axe-core/jest-axeor an equivalent) run against every documented component, wired intonpm run lintor a newnpm run teststep.ACCEPTANCE CRITERIA
components/ui/index.tshas a documented page/story showing its variants.npm run build,npm run lint,npm run test(new) pass inapps/webwith NO VELAR credentials.NOTES
Relevant files:
apps/web/app/design-system/page.tsx,apps/web/components/ui/**,apps/web/package.json(new scripts/deps),docs/FRONTEND_GUIDE.md. Do not change component behavior, only add documentation/testing infrastructure (docs/AGENTS.md§3).No VELAR credentials required: verifiable locally — no database, secrets, or external APIs.
Difficulty: Advanced
Priority: Medium
PR REQUIREMENTS
Closes #<this-issue-number>(this issue's GitHub number) so merging auto-closes it.CAMPAIGN REQUIREMENTS (FWC26)
To be eligible for the reward on this issue, the contributor must: