diff --git a/Ralph/IMPLEMENTATION_PLAN.md b/Ralph/IMPLEMENTATION_PLAN.md
index 5ed43ea..21d8ab6 100644
--- a/Ralph/IMPLEMENTATION_PLAN.md
+++ b/Ralph/IMPLEMENTATION_PLAN.md
@@ -184,13 +184,13 @@ Replace the "CareerRecord PMR" sidebar-nav + view-switching interface with a til
#### Task 20: Accessibility audit
> Detail: `Ralph/refs/ref-08-polish.md` (Accessibility section)
-- [ ] Semantic HTML (header, nav, main, article, section)
-- [ ] Keyboard navigation (Tab, Enter/Space, Escape, Ctrl+K, arrows)
-- [ ] ARIA (expanded, controls, labels, live regions, dialog)
-- [ ] Focus management (trap in palette, visible rings, return focus)
-- [ ] `prefers-reduced-motion` on all animations
-- [ ] Color contrast verification
-- [ ] Run quality checks
+- [x] Semantic HTML (header, nav, main, article, section)
+- [x] Keyboard navigation (Tab, Enter/Space, Escape, Ctrl+K, arrows)
+- [x] ARIA (expanded, controls, labels, live regions, dialog)
+- [x] Focus management (trap in palette, visible rings, return focus)
+- [x] `prefers-reduced-motion` on all animations
+- [x] Color contrast verification
+- [x] Run quality checks
#### Task 21: Clean up and final polish
> Detail: `Ralph/refs/ref-08-polish.md` (Cleanup section)
diff --git a/Ralph/progress.txt b/Ralph/progress.txt
index 039b53c..9f3c62d 100644
--- a/Ralph/progress.txt
+++ b/Ralph/progress.txt
@@ -542,3 +542,71 @@
**Quality checks:** typecheck ✓, lint ✓ (1 pre-existing warning), build ✓
**Visual review:** Skipped — visual verification should be done by user at multiple breakpoints (1280px, 800px, 375px)
+### Iteration 18 — Task 20: Accessibility audit
+**Status:** Complete
+**Changes:**
+- Updated `src/components/Card.tsx`:
+ - Changed wrapper from `
` to `
` for semantic HTML (tiles are self-contained content sections)
+ - Added `aria-hidden="true"` to CardHeader colored dot (decorative, text label conveys information)
+- Updated `src/components/TopBar.tsx`:
+ - Added skip link (href="#main-content") positioned off-screen, visible only on focus
+ - Skip link uses accent background, slides down on focus, slides up on blur
+ - Added `aria-label="Active session information"` to session info container
+- Updated `src/components/DashboardLayout.tsx`:
+ - Added `id="main-content"` to main element (skip link target)
+- Updated `src/components/Sidebar.tsx`:
+ - Added `aria-hidden="true"` to status badge pulse dot (decorative, "Open to Opportunities" text label conveys status)
+- Updated `src/components/tiles/CareerActivityTile.tsx`:
+ - Added `aria-hidden="true"` to colored dots (8px activity type indicators — decorative, activity title conveys information)
+- Updated `src/components/tiles/ProjectsTile.tsx`:
+ - Added `aria-hidden="true"` to status dots (7px Complete/Ongoing/Live indicators — decorative, project name + year conveys information)
+- Updated `src/index.css`:
+ - Added global `*:focus-visible` styles (2px accent outline, 2px offset)
+ - Specific focus-visible styles for buttons, role="button", role="option", links (2px accent outline rgba(13,110,110,0.4))
+ - Input/textarea focus-visible with slightly stronger accent (rgba 0.6, 0px offset)
+ - Added `prefers-reduced-motion` override for pulse animation (disables pulse on status badge dot — keeps opacity 1)
+**Learnings:**
+- **Semantic HTML audit results:**
+ - ✅ TopBar uses `` element (Task 4)
+ - ✅ Sidebar uses `