Task 20: Accessibility audit improvements
Semantic HTML:
- Changed Card component from div to article element
- Added id="main-content" to main element for skip link target
Keyboard Navigation & ARIA:
- Added skip link to TopBar (visible only on focus, navigates to #main-content)
- Added aria-label="Active session information" to session info container
- Added aria-hidden="true" to all decorative colored dots (CardHeader, CareerActivity, Projects, Sidebar status badge)
- All expandable items already have role="button", tabIndex={0}, aria-expanded
- All KPI cards already have proper aria-label describing flip state
- Command palette already has full ARIA implementation (combobox, listbox, dialog)
Focus Management:
- Added global focus-visible styles in index.css (2px accent outline, 2px offset)
- Buttons, links, inputs all have proper focus rings with accent color
- Command palette focus trap already implemented
Reduced Motion:
- All components already check prefers-reduced-motion at module scope
- Dashboard entrance, tile expansion, KPI flip, palette animations respect reduced motion
- Added reduced motion override for pulse animation (disables pulse, keeps static dot)
Color Contrast:
- All color tokens already meet WCAG AA standards per ref spec
- Tertiary text (#8DA8A5) used only for supplementary labels where information is conveyed elsewhere
Quality checks: typecheck ✓, lint ✓ (1 pre-existing warning), build ✓
This commit is contained in:
@@ -26,6 +26,32 @@ export function TopBar({ onSearchClick }: TopBarProps) {
|
||||
zIndex: 100,
|
||||
}}
|
||||
>
|
||||
{/* Skip to main content link (only visible on focus) */}
|
||||
<a
|
||||
href="#main-content"
|
||||
className="skip-link"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: '-40px',
|
||||
left: '0',
|
||||
background: 'var(--accent)',
|
||||
color: '#FFFFFF',
|
||||
padding: '8px 16px',
|
||||
textDecoration: 'none',
|
||||
zIndex: 101,
|
||||
borderRadius: '0 0 4px 0',
|
||||
fontSize: '13px',
|
||||
fontWeight: 600,
|
||||
}}
|
||||
onFocus={(e) => {
|
||||
e.currentTarget.style.top = '0'
|
||||
}}
|
||||
onBlur={(e) => {
|
||||
e.currentTarget.style.top = '-40px'
|
||||
}}
|
||||
>
|
||||
Skip to main content
|
||||
</a>
|
||||
{/* Brand */}
|
||||
<div className="flex items-center gap-2 shrink-0">
|
||||
<Home
|
||||
@@ -131,7 +157,10 @@ export function TopBar({ onSearchClick }: TopBarProps) {
|
||||
</button>
|
||||
|
||||
{/* Session info (right) */}
|
||||
<div className="flex items-center gap-2 sm:gap-3 shrink-0">
|
||||
<div
|
||||
className="flex items-center gap-2 sm:gap-3 shrink-0"
|
||||
aria-label="Active session information"
|
||||
>
|
||||
<span
|
||||
className="hidden sm:inline"
|
||||
style={{
|
||||
|
||||
Reference in New Issue
Block a user