Description
The frontend has no accessibility (a11y) implementation. The current code uses bare <div> elements without semantic HTML, no ARIA attributes, no keyboard navigation, and no screen reader support. For a public-facing utility dashboard, WCAG 2.1 AA compliance is essential.
Accessibility gaps:
- No semantic HTML structure (uses
<div> for everything)
- No heading hierarchy (h1, h2, h3)
- No ARIA landmarks (banner, navigation, main, contentinfo)
- No focus management (keyboard tab order, focus traps in modals)
- No color contrast validation (dark theme text on dark backgrounds)
- No reduced motion support (animation respect)
- No screen reader announcements for dynamic content updates
- No form error announcements to screen readers
- No keyboard shortcuts for power users
- No skip-to-content link
Technical Context & Impact
- Affected Components/Files:
app/page.tsx, app/layout.tsx, src/components/ (all)
- Impact: Legal compliance risk; excludes users with disabilities
Step-by-Step Implementation Guide
- Audit current accessibility: Use axe DevTools, Lighthouse, and manual keyboard testing to identify issues
- Add semantic HTML: Replace
<div> with <header>, <nav>, <main>, <footer>, <section>, <article>
- Implement heading hierarchy: Single
<h1> per page, logical nesting of h2/h3/h4
- Add ARIA landmarks:
role="banner", role="navigation", role="main", role="contentinfo", role="complementary"
- Create accessible interactive components:
A11yDialog.tsx - Focus trap, Escape to close, aria-modal, aria-labelledby
A11yTabs.tsx - tablist, tab, tabpanel roles with keyboard navigation
A11yTable.tsx - scope attributes on th, caption element, sort indicators
A11yButton.tsx - Proper button or role="button" with keyboard support
- Add focus management: Focus ring visible on all interactive elements, skip-to-main link at top
- Implement live regions:
aria-live="polite" for toast notifications and dynamic updates
- Respect reduced motion:
prefers-reduced-motion media query to disable animations
- Add keyboard shortcuts:
? to show shortcuts dialog, g+d for dashboard, g+m for meters, etc.
- Create accessibility documentation:
docs/ACCESSIBILITY.md with compliance status and known issues
Verification & Testing Steps
- Run axe DevTools audit: 0 critical, 0 serious violations
- Run Lighthouse a11y audit: score >=95
- Tab through entire page: all interactive elements reachable and visible
- Test with screen reader (VoiceOver/NVDA): verify all content is announced correctly
- Test reduced motion: enable OS setting -> verify animations are disabled
- Test zoom to 200%: no content cutoff, horizontal scroll only for tables
- Run
npx tsc --noEmit
Description
The frontend has no accessibility (a11y) implementation. The current code uses bare
<div>elements without semantic HTML, no ARIA attributes, no keyboard navigation, and no screen reader support. For a public-facing utility dashboard, WCAG 2.1 AA compliance is essential.Accessibility gaps:
<div>for everything)Technical Context & Impact
app/page.tsx,app/layout.tsx,src/components/(all)Step-by-Step Implementation Guide
<div>with<header>,<nav>,<main>,<footer>,<section>,<article><h1>per page, logical nesting of h2/h3/h4role="banner",role="navigation",role="main",role="contentinfo",role="complementary"A11yDialog.tsx- Focus trap, Escape to close, aria-modal, aria-labelledbyA11yTabs.tsx- tablist, tab, tabpanel roles with keyboard navigationA11yTable.tsx- scope attributes on th, caption element, sort indicatorsA11yButton.tsx- Proper button or role="button" with keyboard supportaria-live="polite"for toast notifications and dynamic updatesprefers-reduced-motionmedia query to disable animations?to show shortcuts dialog,g+dfor dashboard,g+mfor meters, etc.docs/ACCESSIBILITY.mdwith compliance status and known issuesVerification & Testing Steps
npx tsc --noEmit