Skip to content
This repository was archived by the owner on Jul 6, 2026. It is now read-only.

Latest commit

 

History

History
116 lines (85 loc) · 4.05 KB

File metadata and controls

116 lines (85 loc) · 4.05 KB

Loopless — Accessibility Audit

Date: May 2026 | Sprint 4 | Auditor: Enes Shehu Tools: axe DevTools, @axe-core/react, Lighthouse CI, manual WCAG 2.1 AA review


1. Automated Scan — @axe-core/react

Configured in dev mode via app/layout.tsx (dev-only):

// Loaded conditionally in dev
if (process.env.NODE_ENV !== 'production') {
  const axe = await import('@axe-core/react');
  const React = await import('react');
  const ReactDOM = await import('react-dom');
  axe.default(React.default, ReactDOM.default, 1000);
}

Critical Violations Fixed

Rule Element Fix Applied
button-name ThemeToggle button had no accessible name Added aria-label with dynamic text
color-contrast text-muted-foreground on white bg: ratio 2.8:1 (fails AA) Darkened --color-muted-foreground from #94a3b8 to #64748b (4.6:1)
landmark-one-main Landing page lacked <main> element Added <main id="main-content"> wrapper
list Nav links not in <ul> Wrapped nav items in <ul><li>

Warnings (Non-blocking)

Rule Element Status
image-redundant-alt BrandWordmark infinity symbol has aria-hidden Acceptable — full name in parent aria-label
scrollable-region-focusable Notification dropdown Added tabindex="0" to scrollable div

2. Lighthouse CI — Accessibility Score

npx @lhci/cli autorun --config=scripts/lighthouse.config.json
Page Score Key Issues
Landing (/) 96/100 Skip-to-main link present ✅
Login (/login) 98/100 Form labels associated ✅
Discover (/discover) 94/100 MatchCard missing article landmark
Projects (/projects) 97/100 —

MatchCard fix applied: Wrapped each card in <article aria-label={freelancer.name}>.


3. Keyboard Navigation

Flow Status Notes
Tab through landing nav ✅ PASS Focus order: logo → theme toggle → login → signup
Skip-to-main link ✅ PASS Visible on focus, jumps to #main-content
Theme toggle keyboard ✅ PASS Space/Enter activates
Onboarding wizard ✅ PASS Each step traps focus correctly
Modal/dropdown close on Esc ✅ PASS NotificationBell closes on Esc
Form submission on Enter ✅ PASS RHF + Zod forms submit on Enter

4. Screen Reader Testing (NVDA + Chrome)

Component Announcement Status
ThemeToggle (light) "Switch to dark mode, button" ✅
ThemeToggle (dark) "Switch to light mode, button" ✅
NotificationBell (0 unread) "Notifications, button" ✅
NotificationBell (3 unread) "Notifications, 3 unread, button" ✅
SkillChip (selected) "TypeScript, button, pressed" ✅
Error boundary "Something went wrong. Try again, button" ✅

5. Dark Mode Contrast Check

Dark mode palette verified against WCAG 2.1 AA (4.5:1 for normal text):

Token Light Value Contrast Dark Value Contrast
foreground on background #0f172a on #ffffff 19.1:1 ✅ #f1f5f9 on #0f172a 17.2:1 ✅
muted-foreground on background #64748b on #ffffff 4.6:1 ✅ #94a3b8 on #0f172a 5.2:1 ✅
primary on white #6366f1 on #ffffff 3.8:1 ⚠️ (used on interactive only) — —

Note: --color-primary (#6366f1) does not meet 4.5:1 on white for body text, but is only used for interactive elements (buttons, links) where 3:1 is the UI component threshold per WCAG 2.1 1.4.11.


6. ARIA Landmarks Audit

Landmark Present Notes
<header> ✅ NavigationHeader
<main> ✅ Added to all route pages
<nav> ✅ Auth nav + AppNavigation
<footer> ⚠️ Not yet on all pages
Skip link ✅ #main-content href in layout

Summary

Category Before Audit After Fixes
Lighthouse a11y avg 89/100 96/100
axe CRITICAL violations 4 0
axe SERIOUS violations 2 0
WCAG 2.1 AA compliance Partial Substantially compliant