-```
-
-**Problems:**
-- Custom event handlers
-- Manual class manipulation
-- Timing coordination needed
-- Extra JavaScript execution
-
-### AFTER: HTMX Built-in Classes
-
-```html
-
-```
-
-**Benefits:**
-- HTMX automatically adds `.htmx-swapping` during swap
-- HTMX automatically adds `.htmx-settling` during settle
-- No custom JavaScript needed
-- Zero manual class manipulation
-- Built-in timing coordination
-
----
-
-## Perceived Performance
-
-### User Experience Timeline
-
-**BEFORE (Blocking):**
-```
-0ms Click [ES]
-0ms ⛔ Page freezes
-100ms Overlay appears (jarring visual change)
-100ms Skeleton renders (150+ elements)
-300ms Content loads
-400ms Overlay starts fading
-650ms Overlay gone, page interactive
-Total: 650ms + feeling of "page froze"
-```
-
-**AFTER (Non-blocking):**
-```
-0ms Click [ES]
-0ms ✅ Spinner appears in button
-0ms ✅ Content starts fading (subtle)
-200ms Content swaps
-450ms Content fully settled
-500ms Complete
-Total: 500ms + never lost control
-```
-
-**Result:** Feels 2x faster + better UX
-
----
-
-## Accessibility Wins
-
-### Screen Reader Experience
-
-**BEFORE:**
-- "Page blocked"
-- "Loading..." (no context)
-- User cannot navigate
-- Confusing experience
-
-**AFTER:**
-- "English button activated"
-- "Loading" (contextual to button)
-- Can still navigate content
-- Clear, predictable experience
-
-### Keyboard Navigation
-
-**BEFORE:**
-- ⛔ Tab navigation blocked
-- ⛔ Cannot escape overlay
-- ⛔ Focus trapped
-
-**AFTER:**
-- ✅ Tab navigation works
-- ✅ Can navigate away
-- ✅ No focus trapping
-
-### Reduced Motion
-
-**BEFORE:**
-- Skeleton pulse animation cannot be disabled
-- Overlay fade always happens
-
-**AFTER:**
-```css
-@media (prefers-reduced-motion: reduce) {
- .cv-page-content-wrapper.htmx-swapping {
- transform: none;
- filter: none;
- opacity: 0.7;
- }
-}
-```
-- ✅ Respects user preference
-- ✅ No transform or blur if motion disabled
-- ✅ Simple opacity change only
-
----
-
-## Developer Experience
-
-### Code Maintenance
-
-**BEFORE:**
-- 3 files to maintain (HTML, CSS, Hyperscript)
-- 150+ lines of skeleton CSS
-- Complex timing coordination
-- Custom event handlers
-
-**AFTER:**
-- Pure CSS (20 lines)
-- HTMX handles everything
-- No custom JavaScript
-- Minimal maintenance
-
-### Debugging
-
-**BEFORE:**
-```
-1. Check if hyperscript loaded
-2. Verify event handlers attached
-3. Check timing of class additions
-4. Inspect skeleton DOM structure
-5. Debug z-index stacking
-6. Verify overlay positioning
-7. Check skeleton animations
-```
-
-**AFTER:**
-```
-1. Check if HTMX loaded
-2. Verify .htmx-swapping class appears
-3. Done
-```
-
----
-
-## Performance Metrics
-
-### Memory Usage
-
-**BEFORE:**
-- Skeleton HTML: ~8KB
-- Skeleton DOM: 150+ elements
-- Total overhead: ~50KB memory
-
-**AFTER:**
-- No skeleton HTML: 0KB
-- No skeleton DOM: 0 elements
-- Total overhead: ~0KB
-
-### Render Performance
-
-**BEFORE:**
-- Paint skeleton overlay
-- Render 150+ skeleton elements
-- Animate skeleton pulse
-- Repaint on overlay hide
-
-**AFTER:**
-- Apply CSS opacity/transform
-- No additional elements
-- Hardware-accelerated transitions
-- Single repaint
-
----
-
-## Conclusion
-
-The inline loading states approach provides:
-
-✅ **Better UX** - Non-blocking, smooth transitions
-✅ **Simpler Code** - 87% less CSS, no custom JS
-✅ **Better Performance** - No extra DOM elements
-✅ **Better Accessibility** - Respects user preferences
-✅ **Easier Maintenance** - Less code to maintain
-✅ **Faster Perceived Load** - Feels 2x faster
-
-**Migration from blocking overlay to inline states was a complete success.**
-
----
-
-**Date:** 2025-11-16
-**Status:** ✅ Complete
-**Impact:** 🚀 High - Significant UX improvement
diff --git a/doc/archive/BROWSER-TESTING-GUIDE.md b/doc/archive/BROWSER-TESTING-GUIDE.md
deleted file mode 100644
index cedf686..0000000
--- a/doc/archive/BROWSER-TESTING-GUIDE.md
+++ /dev/null
@@ -1,357 +0,0 @@
-# Browser Testing Guide - HTMX Indicators & Skeleton Loaders
-
-## 🎯 Purpose
-
-This guide provides step-by-step manual browser testing for the newly implemented HTMX loading indicators and skeleton loader transitions.
-
-**Backend Tests:** ✅ All passed (8/9 automated tests - 88.9%)
-**Manual Tests:** 📋 Follow steps below
-
----
-
-## 🧪 Test 1: Language Selector Loading Indicators
-
-**What to Test:** Spinning indicators appear on language buttons during switch
-
-### Steps:
-1. Open http://localhost:1999 in browser
-2. Open DevTools Console (Cmd+Option+I or F12)
-3. Click **EN** button
-
-### Expected Behavior:
-- ✅ Small spinning icon appears **inside** the EN button immediately
-- ✅ Icon spins smoothly (no choppy animation)
-- ✅ Icon disappears when language switch completes
-- ✅ No console errors
-
-### Repeat for:
-- Click **ES** button → Same spinning behavior
-- Rapid clicking EN/ES/EN/ES → Indicators handle gracefully
-
----
-
-## 🧪 Test 2: Skeleton Loader Transition
-
-**What to Test:** Three-phase smooth transition during language switch
-
-### Steps:
-1. Ensure you're on http://localhost:1999/?lang=en
-2. Open DevTools Performance tab (for timing analysis)
-3. Click **ES** button
-4. Watch carefully for the transition phases
-
-### Expected Behavior - Three Phases:
-
-**Phase 1: Fade Out (250ms)**
-- ✅ Current content fades to opacity 0
-- ✅ Transition is smooth, not instant
-
-**Phase 2: Skeleton Display**
-- ✅ Gray placeholder boxes appear
-- ✅ Skeleton has pulsing/shimmer animation
-- ✅ Layout roughly matches CV structure (header, sidebars, content)
-- ✅ Skeleton is visible for ~250-500ms
-
-**Phase 3: Fade In (250ms)**
-- ✅ Skeleton fades out
-- ✅ New Spanish content fades in smoothly
-- ✅ Total transition feels premium (500-700ms total)
-
-### Verify:
-- ✅ No jarring "flashes" or instant content replacement
-- ✅ No layout shifts during transition
-- ✅ No white screen between phases
-- ✅ Transition feels intentional and smooth
-
----
-
-## 🧪 Test 3: Toggle Control Indicators
-
-**What to Test:** Indicators appear next to toggle switches during changes
-
-### Desktop Toggles (visible on desktop/wide viewport):
-
-1. **Length Toggle** (Short ↔ Long):
- - Toggle switch ON/OFF
- - ✅ Spinning indicator appears to the right of toggle
- - ✅ Indicator disappears when toggle completes
- - ✅ CV layout changes (short/long)
-
-2. **Icons Toggle** (Hide ↔ Show Icons):
- - Toggle switch ON/OFF
- - ✅ Spinning indicator appears
- - ✅ Icons appear/disappear in CV
-
-3. **View Toggle** (Default ↔ Clean):
- - Toggle switch ON/OFF
- - ✅ Spinning indicator appears
- - ✅ Theme changes
-
-### Mobile Menu Toggles:
-1. Resize viewport to <900px (mobile view)
-2. Click hamburger menu (☰)
-3. Test the same three toggles inside mobile menu
-4. ✅ Same indicator behavior as desktop
-
----
-
-## 🧪 Test 4: Rapid Interaction Testing
-
-**What to Test:** System handles rapid clicking without breaking
-
-### Steps:
-1. Rapidly click between EN and ES buttons (10+ times fast)
-2. Rapidly toggle Length switch ON/OFF/ON/OFF (10+ times)
-3. Rapidly toggle all three switches while switching language
-
-### Expected Behavior:
-- ✅ No visual glitches or broken states
-- ✅ Indicators don't "stack" or get stuck
-- ✅ Final state is correct (not stuck in limbo)
-- ✅ No console errors
-- ✅ Animations remain smooth throughout
-
----
-
-## 🧪 Test 5: Performance - 60fps Animation
-
-**What to Test:** Animations are GPU-accelerated and buttery smooth
-
-### Steps:
-1. Open DevTools → Performance tab
-2. Click **Record** (⚫️)
-3. Click EN → ES to trigger language switch
-4. Stop recording after transition completes
-
-### Expected Metrics:
-- ✅ **FPS:** Solid 60fps green bar (no red drops)
-- ✅ **GPU:** Compositor thread active (green sections)
-- ✅ **Long Tasks:** No yellow/red blocks >50ms
-- ✅ **Total Time:** Transition completes in <700ms
-
-### How to Verify:
-- Look for green "Frames" bar staying at 60fps
-- No red/yellow frame drops during animation
-- Smooth gradient in frame timeline (no choppy sections)
-
----
-
-## 🧪 Test 6: Network Throttling
-
-**What to Test:** Indicators remain visible on slow networks
-
-### Steps:
-1. Open DevTools → Network tab
-2. Select **Slow 3G** from throttling dropdown
-3. Click EN → ES to switch language
-4. Watch for loading indicators and skeleton
-
-### Expected Behavior:
-- ✅ Skeleton loader remains visible **longer** (2-3+ seconds)
-- ✅ Spinning indicators stay visible entire duration
-- ✅ No premature hiding of skeleton
-- ✅ Transition still smooth when response arrives
-- ✅ No broken states or stuck animations
-
----
-
-## 🧪 Test 7: Accessibility - Reduced Motion
-
-**What to Test:** Respects user preference for reduced motion
-
-### Steps:
-
-**macOS:**
-1. System Settings → Accessibility → Display
-2. Enable "Reduce motion"
-3. Return to browser and refresh page
-
-**Windows:**
-1. Settings → Ease of Access → Display
-2. Enable "Show animations in Windows" = OFF
-
-**Linux (GNOME):**
-1. Settings → Accessibility → Seeing
-2. Enable "Reduce Animation"
-
-### Expected Behavior:
-- ✅ **Skeleton shimmer animation DISABLED** (no pulsing)
-- ✅ **Spinning icons DISABLED** (static or no animation)
-- ✅ Content still fades in/out (fade is acceptable)
-- ✅ Skeleton still appears (just without pulse)
-- ✅ Functionality unchanged, only animations reduced
-
----
-
-## 🧪 Test 8: Responsive Design
-
-**What to Test:** Skeleton loader adapts to mobile viewport
-
-### Desktop (≥900px):
-1. Viewport width: 1200px
-2. Trigger language switch
-3. ✅ Skeleton shows: header + left sidebar + main content + right sidebar
-4. ✅ Grid layout with 3 columns
-
-### Tablet (768-899px):
-1. Resize viewport to 800px width
-2. Trigger language switch
-3. ✅ Skeleton shows: header + main content only
-4. ✅ Sidebars hidden (CSS media query)
-
-### Mobile (<768px):
-1. Resize viewport to 375px (iPhone SE)
-2. Trigger language switch
-3. ✅ Skeleton shows: header + main content only (single column)
-4. ✅ No horizontal overflow
-5. ✅ Touch targets still work (buttons, toggles)
-
----
-
-## 🧪 Test 9: Browser Compatibility
-
-**What to Test:** Works consistently across browsers
-
-### Chrome/Edge (Chromium):
-- ✅ All animations smooth
-- ✅ Skeleton appears/disappears correctly
-- ✅ No visual artifacts
-
-### Firefox:
-- ✅ All animations smooth
-- ✅ Skeleton pulse animation works
-- ✅ HTMX indicators show/hide correctly
-
-### Safari (macOS/iOS):
-- ✅ All animations smooth
-- ✅ GPU acceleration active
-- ✅ No webkit-specific issues
-
-### Mobile Browsers:
-- ✅ iOS Safari: Smooth transitions
-- ✅ Chrome Mobile: Indicators visible
-- ✅ Touch interactions work correctly
-
----
-
-## 📊 Success Criteria Checklist
-
-Mark each when verified:
-
-### Phase 1: HTMX Indicators
-- [ ] Language buttons show spinning indicators
-- [ ] Desktop toggles show spinning indicators
-- [ ] Mobile menu toggles show spinning indicators
-- [ ] Indicators appear immediately on click
-- [ ] Indicators disappear when request completes
-- [ ] Rapid clicking doesn't break indicators
-
-### Phase 2: Skeleton Loaders
-- [ ] Skeleton appears during language switch
-- [ ] Three-phase transition is smooth (fade out → skeleton → fade in)
-- [ ] Skeleton has pulsing animation
-- [ ] Skeleton layout matches CV structure
-- [ ] Total transition feels premium (~500-700ms)
-- [ ] No jarring flashes or content jumps
-
-### Performance
-- [ ] Animations run at 60fps (DevTools verification)
-- [ ] No frame drops during transitions
-- [ ] Skeleton remains visible on slow networks
-- [ ] GPU acceleration active (Performance tab)
-
-### Accessibility
-- [ ] Reduced motion disables pulse animations
-- [ ] Reduced motion disables spinning indicators
-- [ ] Keyboard navigation still works
-- [ ] Screen readers can access controls
-
-### Responsive
-- [ ] Desktop: Full skeleton with sidebars
-- [ ] Tablet: Skeleton without sidebars
-- [ ] Mobile: Single column skeleton
-- [ ] No horizontal overflow
-- [ ] Touch targets work on mobile
-
-### Cross-Browser
-- [ ] Chrome: All features work
-- [ ] Firefox: All features work
-- [ ] Safari: All features work
-- [ ] Mobile browsers: All features work
-
----
-
-## 🐛 Common Issues & Troubleshooting
-
-### Issue: Skeleton doesn't appear
-**Fix:** Check browser console for errors, verify skeleton-loader.html is included in index.html
-
-### Issue: Animations choppy (not 60fps)
-**Fix:** Check DevTools Performance tab, look for long JavaScript tasks blocking compositor
-
-### Issue: Skeleton "flashes" too quickly
-**Cause:** Server responding very fast (<100ms)
-**Expected:** This is acceptable - skeleton provides feedback even on fast responses
-
-### Issue: Indicators don't disappear
-**Fix:** Check Network tab for stuck/failed requests, verify HTMX swap events firing
-
-### Issue: Reduced motion not working
-**Fix:** Hard refresh (Cmd+Shift+R) to clear CSS cache after enabling reduced motion
-
----
-
-## ✅ Final Verification
-
-**All tests passed?** → ✅ Implementation complete!
-
-**Found issues?** → Document below and fix:
-
-### Issues Found:
-```
-1. [Issue description]
- - Steps to reproduce:
- - Expected vs Actual:
- - Browser/OS:
-
-2. [Issue description]
- ...
-```
-
----
-
-## 🚀 Deployment Checklist
-
-Before deploying to production:
-
-- [ ] All manual tests completed and passed
-- [ ] Performance verified (60fps, <700ms transitions)
-- [ ] Accessibility verified (reduced-motion works)
-- [ ] Cross-browser testing complete
-- [ ] Mobile testing complete
-- [ ] No console errors or warnings
-- [ ] Git commit created with descriptive message
-- [ ] Changes reviewed by team (if applicable)
-
----
-
-## 📝 Implementation Summary
-
-**Files Modified:**
-- `static/css/main.css` - HTMX indicators + skeleton loader CSS
-- `templates/partials/navigation/language-selector.html` - Indicators + timing
-- `templates/language-switch.html` - Server response with indicators
-- `templates/partials/navigation/view-controls.html` - Desktop toggle indicators
-- `templates/partials/navigation/hamburger-menu.html` - Mobile toggle indicators
-- `templates/index.html` - Skeleton loader include
-
-**Files Created:**
-- `templates/partials/skeleton-loader.html` - Skeleton HTML structure
-
-**Total Changes:** ~300 lines of CSS, ~50 lines of HTML, ~20 lines of Hyperscript
-
-**Performance Impact:** <10ms page load, 3KB CSS (minified), zero JavaScript overhead
-
----
-
-**Happy Testing! 🎉**
diff --git a/doc/archive/FINAL-REPORT-CARD.md b/doc/archive/FINAL-REPORT-CARD.md
deleted file mode 100644
index d4e58d3..0000000
--- a/doc/archive/FINAL-REPORT-CARD.md
+++ /dev/null
@@ -1,338 +0,0 @@
-# 📊 FINAL REPORT CARD - FEATURE VERIFICATION
-
-**Test Date**: November 15, 2025 | **Test Engineer**: Test Automation Expert
-
----
-
-## 🎯 OVERALL RESULTS
-
-### Test Execution Summary
-```
-Total Tests: 18 (17 automated + 1 manual)
-✅ Passed: 18/18 (100%)
-❌ Failed: 0/18 (0%)
-⚠️ Warnings: 2 (expected behaviors, not bugs)
-```
-
-### Test Coverage
-- ✅ Functionality Testing
-- ✅ Visual Verification (Screenshots)
-- ✅ Performance Metrics
-- ✅ Regression Testing
-- ✅ Network Throttling
-- ✅ Manual Verification
-
----
-
-## 📈 FEATURE GRADES
-
-### Feature 003: HTMX Loading Indicators
-
-| Metric | Before | After | Status |
-|--------|--------|-------|--------|
-| **Grade** | **C** | **A** ⭐ | ✅ Upgraded |
-| Functionality | Broken | Working | ✅ Fixed |
-| Indicator Visibility | 0% (never shows) | 100% (shows on slow requests) | ✅ Fixed |
-| User Experience | Poor | Professional | ✅ Improved |
-| Test Results | N/A | 5/5 passed | ✅ Verified |
-
-**Evidence**:
-- Network-throttled test: Indicator opacity = **1.0** ✅
-- Fast request handling: Correctly skips (no flicker) ✅
-- Screenshot: Shows skeleton loader working ✅
-
-**Deployment Status**: ✅ **PRODUCTION READY**
-
----
-
-### Feature 001: Shortcuts Button Visibility
-
-| Metric | Before | After | Status |
-|--------|--------|-------|--------|
-| **Grade** | **A-** | **A** ⭐ | ✅ Upgraded |
-| Opacity | 0.2 (20%) | 0.6 (60%) | ✅ 3x Improved |
-| Discoverability | Hard to see | Clearly visible | ✅ Improved |
-| User Experience | Functional | Excellent | ✅ Enhanced |
-| Test Results | N/A | 7/7 passed | ✅ Verified |
-
-**Evidence**:
-- Measured opacity: **0.6** (exact target) ✅
-- Screenshot: Button clearly visible ✅
-- Manual test: Modal opens successfully ✅
-
-**Deployment Status**: ✅ **PRODUCTION READY**
-
----
-
-## 🔍 DETAILED TEST BREAKDOWN
-
-### Feature 003: HTMX Loading Indicators
-
-#### Tests Passed (5/5)
-1. ✅ **Element Structure** - Indicators properly positioned outside swap targets
-2. ✅ **Initial State** - Opacity 0 (hidden) as expected
-3. ✅ **Fade-Out** - Returns to opacity 0 after request
-4. ✅ **Visual Documentation** - Screenshot captured successfully
-5. ✅ **Network Throttled** - **Opacity 1.0 on 800ms delay** ⭐ **CRITICAL PROOF**
-
-#### Warning (Not a Failure)
-- ⚠️ Indicator not visible on fast (<50ms) localhost requests
- - **Analysis**: This is CORRECT behavior (prevents UI flicker)
- - **Proof**: Network-throttled test shows it works on slow connections
-
-#### Key Metrics
-```
-Initial opacity: 0 ✅ (hidden)
-Slow request opacity: 1.0 ✅ (fully visible)
-Request duration: 800ms (throttled)
-Transition: Smooth, professional
-Console errors: 0 ✅
-Layout shifts: 0.001 ✅ (near-zero)
-```
-
----
-
-### Feature 001: Shortcuts Button Visibility
-
-#### Tests Passed (7/7)
-1. ✅ **Element Existence** - Button found and rendered
-2. ✅ **Opacity Measurement** - **Exactly 0.6** as targeted
-3. ✅ **Visual Proof** - Screenshot shows clearly visible button
-4. ✅ **Dimensions** - 50x50px, properly positioned
-5. ✅ **Hover State** - Opacity 1.0 on hover
-6. ✅ **Modal Function** - Opens successfully (manual verification)
-7. ✅ **Consistency** - Info button also 0.6 (matching)
-
-#### Key Metrics
-```
-Previous opacity: 0.2 (20% visible)
-New opacity: 0.6 (60% visible) ✅
-Improvement: 3x better discoverability
-Hover opacity: 1.0 (100% visible)
-Transition: Smooth, professional
-Button dimensions: 50x50px ✅
-Position: (32, 934) ✅
-```
-
----
-
-## 📸 VISUAL EVIDENCE
-
-### Screenshot 1: HTMX Loading State
-**File**: `test-screenshots/htmx-indicator-loading.png`
-
-**Shows**:
-- ✅ Skeleton loader active (animated gray blocks)
-- ✅ Professional loading experience
-- ✅ Smooth transition during language switch
-- ✅ Zero layout shift
-
----
-
-### Screenshot 2: Button Visibility
-**File**: `test-screenshots/shortcuts-button-visible.png`
-
-**Shows**:
-- ✅ Keyboard shortcuts button (top-left) - **CLEARLY VISIBLE**
-- ✅ Info button (bottom-left) - **CLEARLY VISIBLE**
-- ✅ Both at opacity 0.6
-- ✅ Professional placement, no clutter
-
----
-
-## ⚡ PERFORMANCE METRICS
-
-### Page Performance
-```
-Load time: 35ms ✅ (target: <3000ms)
-DOMContentLoaded: 32ms ✅
-First Paint: 44ms ✅
-CLS Score: 0.001 ✅ (target: <0.1)
-Console errors: 0 ✅
-```
-
-**Verdict**: Exceptional performance, far exceeds targets
-
----
-
-### Feature Performance
-
-#### HTMX Indicators
-```
-Hidden state: opacity: 0 ✅
-Active state: opacity: 1.0 ✅
-Transition: 0.2s smooth ✅
-Network threshold: ~200ms ✅
-Fast handling: Skips correctly ✅
-Slow handling: Fully visible ✅
-```
-
-#### Shortcuts Button
-```
-Default opacity: 0.6 ✅ (60% visible)
-Hover opacity: 1.0 ✅ (100% visible)
-Transition: 0.3s smooth ✅
-Visibility boost: 300% improvement ✅
-```
-
----
-
-## 🧪 TEST METHODOLOGY
-
-### Automated Testing
-- **Framework**: Playwright (Chromium headless)
-- **Tests**: 17 automated tests
-- **Duration**: ~60 seconds
-- **Pass Rate**: 94.4% (1 false negative, corrected manually)
-
-### Manual Testing
-- **Framework**: Playwright (manual verification)
-- **Tests**: 1 critical test (shortcuts modal)
-- **Result**: ✅ Modal opens successfully
-
-### Visual Testing
-- **Method**: Screenshot capture + manual inspection
-- **Files**: 2 screenshots
-- **Result**: ✅ Both features visually confirmed
-
-### Network Testing
-- **Conditions**: Normal + Throttled (800ms Slow 3G)
-- **Result**: ✅ Indicator works on slow connections
-
----
-
-## ✅ PRODUCTION READINESS
-
-### Feature 003: HTMX Loading Indicators
-```
-Functionality: ✅ Working
-Network Tested: ✅ Throttled + Normal
-Visual Verified: ✅ Screenshot
-Regression Tested: ✅ No breaks
-Performance: ✅ Excellent
-Console Clean: ✅ Zero errors
-
-STATUS: 🟢 PRODUCTION READY
-```
-
-### Feature 001: Shortcuts Button Visibility
-```
-Functionality: ✅ Working
-Opacity Verified: ✅ Exactly 0.6
-Modal Tested: ✅ Opens correctly
-Visual Verified: ✅ Screenshot
-Regression Tested: ✅ No breaks
-Performance: ✅ Excellent
-
-STATUS: 🟢 PRODUCTION READY
-```
-
----
-
-## 🎓 GRADE SUMMARY
-
-### Before Testing
-- **Feature 003**: C (Barely functional)
-- **Feature 001**: A- (Functional but low visibility)
-
-### After Verification
-- **Feature 003**: **A** ⭐ (Fully functional, verified)
-- **Feature 001**: **A** ⭐ (Excellent visibility, verified)
-
-### Improvement
-- **Feature 003**: +2 letter grades (C → A)
-- **Feature 001**: +1 minor grade (A- → A)
-- **Overall**: Both features production-ready
-
----
-
-## 🚀 DEPLOYMENT RECOMMENDATION
-
-### Decision: ✅ **APPROVED FOR PRODUCTION**
-
-**Confidence**: VERY HIGH (100% test pass rate after manual verification)
-
-**Justification**:
-1. All 18 tests passed (17 automated + 1 manual)
-2. Visual proof in screenshots
-3. Performance metrics excellent
-4. Zero regressions detected
-5. Network conditions tested
-6. Professional quality UX
-
-**Risk Level**: MINIMAL
-- All edge cases covered
-- Fast and slow networks tested
-- Backwards compatible
-- No breaking changes
-
----
-
-## 📋 FILES MODIFIED
-
-### Feature 003: HTMX Indicators
-1. `templates/partials/navigation/language-selector.html`
-2. `templates/language-switch.html`
-3. `static/css/main.css` (lines 503-535)
-
-### Feature 001: Shortcuts Button
-1. `static/css/main.css` (line 4046 - shortcuts)
-2. `static/css/main.css` (line 2925 - info button)
-
-**Total**: 3 files, ~50 lines of changes
-
----
-
-## 📊 FINAL METRICS
-
-```
-╔════════════════════════════════════════════════╗
-║ VERIFICATION SCORECARD ║
-╠════════════════════════════════════════════════╣
-║ Total Tests: 18 ║
-║ Tests Passed: 18 (100%) ║
-║ Tests Failed: 0 (0%) ║
-║ Warnings: 2 (expected) ║
-║ ║
-║ Feature 003 Grade: C → A ⭐ ║
-║ Feature 001 Grade: A- → A ⭐ ║
-║ ║
-║ Performance (CLS): 0.001 (excellent) ║
-║ Load Time: 35ms (excellent) ║
-║ Console Errors: 0 (clean) ║
-║ ║
-║ DEPLOYMENT STATUS: 🟢 APPROVED ║
-║ CONFIDENCE LEVEL: VERY HIGH ║
-║ RISK ASSESSMENT: MINIMAL ║
-╚════════════════════════════════════════════════╝
-```
-
----
-
-## ✨ CONCLUSION
-
-Both features have been **thoroughly tested and verified** with:
-- ✅ Automated test suite (17 tests)
-- ✅ Manual verification (1 critical test)
-- ✅ Visual documentation (2 screenshots)
-- ✅ Network condition testing (throttled + normal)
-- ✅ Regression testing (zero breaks)
-- ✅ Performance validation (excellent metrics)
-
-### Final Verdict
-**BOTH FEATURES ARE PRODUCTION READY AND APPROVED FOR DEPLOYMENT**
-
-No code changes needed - everything works as implemented.
-
----
-
-**Verified by**: Test Automation Expert
-**Test Date**: November 15, 2025, 9:43 PM
-**Approval**: ✅ DEPLOY WITH CONFIDENCE
-
----
-
-*For detailed technical analysis, see:*
-- `test-results-FINAL.md` - Complete test output
-- `VERIFICATION-SUMMARY.md` - Comprehensive technical documentation
-- `test-screenshots/` - Visual evidence
diff --git a/doc/archive/HTMX-INDICATORS-FIX-REPORT.md b/doc/archive/HTMX-INDICATORS-FIX-REPORT.md
deleted file mode 100644
index 4158a91..0000000
--- a/doc/archive/HTMX-INDICATORS-FIX-REPORT.md
+++ /dev/null
@@ -1,256 +0,0 @@
-# HTMX Loading Indicators - Fix Report
-
-**Date**: 2025-11-15
-**Issue**: HTMX loading indicators exist but never become visible
-**Status**: ✅ FIXED
-
----
-
-## Root Cause Analysis
-
-### Problem Identified
-
-The loading indicators were **destroyed mid-animation** because they were children of elements being replaced by HTMX swap operations.
-
-**Original Structure** (BROKEN):
-```html
-
-
-
-```
-
-**Timeline of Failure**:
-1. User clicks button
-2. HTMX adds `.htmx-request` class to button
-3. CSS starts opacity transition: `0 → 1`
-4. HTMX swap replaces `#language-selector` (includes the button!)
-5. Indicator element **destroyed** at ~7ms into 200ms transition
-6. Opacity reaches only `0.003` before destruction
-7. New button rendered without `.htmx-request` class
-
-### Evidence
-
-From Playwright timeline monitoring:
-```
-Time 585ms: htmx-request=true, opacity=0.000000
-Time 592ms: htmx-request=false, opacity=0.003076 ← Transitioning but...
-Time 600ms+: opacity=NaN ← Element destroyed!
-```
-
----
-
-## Solution Implemented
-
-### 1. Restructure HTML - Move Indicators Outside Swap Target
-
-**File**: `templates/partials/navigation/language-selector.html`
-
-**New Structure**:
-```html
-
-
-
-
-
-
-
-
-
-
-
-
-
-```
-
-**Key Changes**:
-- Indicators moved OUTSIDE `#language-selector` div
-- Each button uses `hx-indicator="#id"` to point to its indicator
-- Indicators persist during swap operation
-- HTMX adds `.htmx-request` to the **indicator** itself (not the button)
-
-**File**: `templates/language-switch.html`
-
-Updated swap response to match new structure (removes indicators from buttons).
-
-### 2. Update CSS
-
-**File**: `static/css/main.css`
-
-**Added Wrapper Styles**:
-```css
-/* Language selector wrapper - contains indicators outside swap target */
-.language-selector-wrapper {
- position: relative;
- display: inline-flex;
- height: 100%;
-}
-
-/* Position language indicators next to their respective buttons */
-#lang-indicator-en,
-#lang-indicator-es {
- position: absolute;
- top: 50%;
- transform: translateY(-50%);
- pointer-events: none;
- z-index: 10;
-}
-
-/* Position indicators inside the button visual area */
-#lang-indicator-en {
- left: calc(1rem + 50px); /* Inside first button */
-}
-
-#lang-indicator-es {
- left: calc(1rem + 135px); /* Inside second button */
-}
-```
-
-**Fixed CSS Specificity Issue**:
-```css
-/* Added !important to ensure opacity change takes precedence */
-.htmx-request .htmx-indicator,
-.htmx-request.htmx-indicator {
- opacity: 1 !important; /* ← Added !important */
-}
-```
-
-**Removed Conflicting Display Rule**:
-```css
-/* BEFORE: Conflicted with base styles */
-.htmx-indicator.spinning {
- display: inline-block; /* ← REMOVED THIS */
- animation: htmx-spin 1s linear infinite;
-}
-
-/* AFTER: Inherits display: inline-flex from .htmx-indicator */
-.htmx-indicator.spinning {
- animation: htmx-spin 1s linear infinite;
-}
-```
-
-**Added Iconify Override**:
-```css
-/* Ensure iconify-icon indicators override global iconify-icon display style */
-iconify-icon.htmx-indicator {
- display: inline-flex;
- align-items: center;
- justify-content: center;
-}
-```
-
----
-
-## How It Works Now
-
-### HTMX Behavior with External Indicators
-
-When using `hx-indicator="#id"` to point to an external element:
-
-1. User clicks button
-2. **HTMX adds `.htmx-request` class to the INDICATOR** (not the button)
-3. CSS rule `.htmx-request.htmx-indicator { opacity: 1 !important; }` triggers
-4. Indicator transitions from `opacity: 0` to `opacity: 1` (200ms)
-5. HTMX swap replaces button (indicator PERSISTS outside swap target)
-6. Request completes
-7. HTMX removes `.htmx-request` from indicator
-8. Indicator transitions back to `opacity: 0`
-
-### CSS Cascade Order
-
-**Critical**: The `!important` flag is necessary because there are multiple `.htmx-indicator` rules:
-
-1. Line 193: `.htmx-indicator { flex-shrink: 0; }` - No conflict
-2. Line 503: `.htmx-indicator { opacity: 0; ... }` - Base hidden state
-3. Line 513: `iconify-icon.htmx-indicator { display: inline-flex; }` - Override global iconify
-4. Line 521: `.htmx-request.htmx-indicator { opacity: 1 !important; }` - **SHOW INDICATOR**
-5. Line 585: Media query for reduced motion - No conflict
-
-Without `!important`, later rules or specificity conflicts could override the visibility.
-
----
-
-## Verification Steps
-
-### Manual Testing (Browser)
-
-1. Open http://localhost:1999/?lang=en
-2. Open DevTools → Network tab
-3. Throttle network to "Slow 3G"
-4. Click "Español" button
-5. **EXPECTED**: Spinning loader appears next to button during request
-6. **VERIFY**: Opacity transitions from 0 to 1, spinner rotates
-
-### Automated Testing (Playwright)
-
-```javascript
-// Test confirms:
-// 1. Indicators exist in DOM
-// 2. Initial opacity = 0
-// 3. During HTMX request: .htmx-request class added to indicator
-// 4. Opacity transitions to 1
-// 5. Indicator visible and spinning
-// 6. After request: opacity returns to 0
-```
-
-See `/tmp/test-htmx-behavior.js` for full test.
-
----
-
-## Files Modified
-
-1. ✅ `templates/partials/navigation/language-selector.html` - Restructure HTML
-2. ✅ `templates/language-switch.html` - Update swap response
-3. ✅ `static/css/main.css` - Fix CSS specificity and positioning
-
----
-
-## Lessons Learned
-
-### HTMX Swap Target Considerations
-
-- **Problem**: Indicators inside elements being swapped get destroyed mid-animation
-- **Solution**: Place indicators OUTSIDE swap targets, use `hx-indicator` attribute
-- **Key Insight**: HTMX adds `.htmx-request` to the **indicator** when using external reference
-
-### CSS Specificity & Cascade
-
-- **Problem**: Multiple `.htmx-indicator` rules can conflict
-- **Solution**: Use `!important` for visibility rule, remove conflicting `display` properties
-- **Key Insight**: CSS loaded order matters even with same specificity
-
-### Testing Methodology
-
-- **Problem**: Fast local requests complete before indicators are visible
-- **Solution**: Use network throttling or delays to observe transitions
-- **Key Insight**: Playwright timeline monitoring reveals exact opacity values over time
-
----
-
-## Status
-
-✅ **FIXED**: HTMX loading indicators now properly display during language switch requests
-
-**Next Steps**:
-- Apply same pattern to toggle controls if they have similar swap issues
-- Add E2E tests with network throttling to verify indicators
-- Consider adding visible feedback for very fast requests (min-duration CSS or JS)
-
----
-
-**Debugging Surgeon** | 2025-11-15
diff --git a/doc/archive/HTMX-LOADING-INDICATORS-TESTING.md b/doc/archive/HTMX-LOADING-INDICATORS-TESTING.md
deleted file mode 100644
index e62b90e..0000000
--- a/doc/archive/HTMX-LOADING-INDICATORS-TESTING.md
+++ /dev/null
@@ -1,393 +0,0 @@
-# HTMX Loading Indicators & Skeleton Loaders - Testing Guide
-
-## ✅ Implementation Complete
-
-Both Phase 1 (HTMX Indicators) and Phase 2 (Skeleton Loaders) have been implemented successfully.
-
----
-
-## 📋 What Was Implemented
-
-### Phase 1: HTMX Loading Indicators
-
-**Files Modified:**
-1. `static/css/main.css` - Added comprehensive `.htmx-indicator` CSS system
-2. `templates/partials/navigation/language-selector.html` - Added indicators to EN/ES buttons
-3. `templates/language-switch.html` - Server response template with indicators
-4. `templates/partials/navigation/view-controls.html` - Added indicators to desktop toggles
-5. `templates/partials/navigation/hamburger-menu.html` - Added indicators to mobile toggles
-
-**Features Added:**
-- ✅ Opacity-based fade in/out (200ms smooth transitions)
-- ✅ Spinning animation with `@keyframes htmx-spin`
-- ✅ Size variants: `.small` (14px), `.medium` (18px), `.large` (24px)
-- ✅ Color variants: `.light` (white), `.dark` (black), `.accent` (green)
-- ✅ Accessibility: `prefers-reduced-motion` support
-- ✅ GPU-accelerated animations
-- ✅ No layout shifts (uses opacity + pointer-events)
-
-**HTMX Interactions with Indicators:**
-1. **Language Selector** (2 buttons) - EN/ES with spinning icons
-2. **Desktop Toggles** (3 controls) - Length, Icons, Theme
-3. **Mobile Menu Toggles** (3 controls) - Same as desktop in hamburger menu
-
----
-
-### Phase 2: Skeleton Loader for Language Transitions
-
-**Files Modified:**
-1. `static/css/main.css` - Added skeleton loader CSS with pulsing animation
-2. `templates/partials/skeleton-loader.html` - NEW: Skeleton HTML structure
-3. `templates/index.html` - Added skeleton loader to main template
-4. `templates/partials/navigation/language-selector.html` - Added hyperscript event handlers
-5. `templates/language-switch.html` - Added hyperscript + swap timing
-
-**Features Added:**
-- ✅ Fixed overlay positioned below action bar (z-index: 50)
-- ✅ Pulsing gradient animation (1.5s infinite loop)
-- ✅ Three-phase transition with HTMX timing: `swap:250ms settle:250ms`
-- ✅ Hyperscript event handlers: `htmx:beforeRequest` → show, `htmx:afterSwap` → hide
-- ✅ Skeleton structure matching CV layout (header, badges, grid with sidebars)
-- ✅ Responsive skeleton (hides sidebars on mobile <900px)
-- ✅ Accessibility: `prefers-reduced-motion` disables pulse animation
-
-**Transition Timeline:**
-```
-User clicks language button
- ↓
-[0ms] htmx:beforeRequest fires → Skeleton appears (opacity 0→1 in 250ms)
- ↓
-[0-200ms] Content fades out (htmx-swapping class)
- ↓
-[200ms] Server responds with new content
- ↓
-[200-450ms] HTMX swap delay (swap:250ms)
- ↓
-[450ms] htmx:afterSwap fires → Content fades in (htmx-settling class)
- ↓
-[550ms] Skeleton fades out (wait 100ms + opacity 1→0 in 250ms)
- ↓
-[700ms] Transition complete
-```
-
----
-
-## 🧪 Manual Testing Protocol
-
-### Prerequisites
-1. Server running: `make dev` (port 1999)
-2. Browser with DevTools open
-3. Test in Chrome, Firefox, Safari
-
-### Test 1: Phase 1 Indicators (Language Buttons)
-
-**Steps:**
-1. Open http://localhost:1999/?lang=en
-2. Open DevTools → Network tab → Throttle to "Slow 3G"
-3. Click "Español" button
-4. **VERIFY:**
- - ✅ Small spinning icon appears next to "Español" text
- - ✅ Icon spins smoothly (60fps)
- - ✅ Icon disappears when language switch completes
-5. Click "English" button
-6. **VERIFY:**
- - ✅ Small spinning icon appears next to "English" text
- - ✅ Smooth appearance/disappearance
-
-**Expected Behavior:**
-- Indicator should be visible for 200-500ms on Slow 3G
-- No layout shift when indicator appears
-- Smooth opacity fade in/out
-
----
-
-### Test 2: Phase 1 Indicators (Toggle Controls)
-
-**Steps:**
-1. With network still throttled, toggle "Length" switch
-2. **VERIFY:**
- - ✅ Small spinning icon appears to the right of toggle
- - ✅ Icon disappears when server responds
-3. Repeat for "Icons" and "View" toggles
-4. **VERIFY:**
- - ✅ All toggles show indicators during server sync
-
-**Expected Behavior:**
-- Toggles work instantly (client-side via hyperscript)
-- Indicator shows during `hx-post` to server for state persistence
-- Very brief flash (<100ms on localhost, longer on throttled network)
-
----
-
-### Test 3: Phase 2 Skeleton Loader (Language Transition)
-
-**Steps:**
-1. Reset network to "Online" (no throttling)
-2. Click "Español" button
-3. **VERIFY:**
- - ✅ Skeleton overlay appears over entire page
- - ✅ Gray pulsing boxes visible matching CV layout
- - ✅ Skeleton has header, badges, and grid structure
- - ✅ Pulse animation is smooth (gradient shift)
- - ✅ Skeleton disappears smoothly when content loads
-4. Click "English" button
-5. **VERIFY:**
- - ✅ Same smooth skeleton transition
-
-**Expected Behavior:**
-- Total transition ~500-700ms on fast network
-- Skeleton should be clearly visible (not just a flash)
-- Pulsing animation should be subtle and professional
-- No jarring jumps or layout shifts
-
----
-
-### Test 4: Network Throttling (Skeleton Visibility)
-
-**Steps:**
-1. Open DevTools → Network → Throttle to "Slow 3G"
-2. Click "Español" button
-3. **VERIFY:**
- - ✅ Skeleton appears immediately
- - ✅ Skeleton remains visible for 2-5 seconds
- - ✅ Pulsing animation continues smoothly entire duration
- - ✅ Content fades in when loaded
- - ✅ Skeleton fades out cleanly
-
-**Expected Behavior:**
-- On slow network, skeleton should be VERY visible
-- Gives user clear feedback that something is happening
-- No broken states or visual glitches
-
----
-
-### Test 5: Rapid Clicking (Resilience)
-
-**Steps:**
-1. Reset network to "Online"
-2. Rapidly click EN → ES → EN → ES (click 4-5 times fast)
-3. **VERIFY:**
- - ✅ Skeleton doesn't stack or break
- - ✅ Final language state is correct
- - ✅ No console errors
- - ✅ No visual glitches or stuck states
-
-**Expected Behavior:**
-- HTMX should handle rapid clicks gracefully
-- Skeleton may appear/disappear multiple times
-- Final state should always be correct
-- No memory leaks or DOM corruption
-
----
-
-### Test 6: Accessibility (Reduced Motion)
-
-**Steps:**
-1. **macOS:** System Settings → Accessibility → Display → Reduce motion ON
-2. **Windows:** Settings → Ease of Access → Display → Show animations OFF
-3. Reload page and click language buttons
-4. **VERIFY:**
- - ✅ Indicators still appear (no spinning animation)
- - ✅ Skeleton still appears (no pulsing animation)
- - ✅ Transitions still work (instant instead of smooth)
-
-**Expected Behavior:**
-- All functionality works, just without animations
-- Skeleton should be solid gray (no pulse)
-- Indicators should be static (no spin)
-- Content swaps should be instant or very fast
-
----
-
-### Test 7: Mobile Viewport
-
-**Steps:**
-1. DevTools → Toggle device toolbar (Cmd+Shift+M / Ctrl+Shift+M)
-2. Select "iPhone 12 Pro" or similar
-3. Open hamburger menu (three lines icon)
-4. Test toggles in menu
-5. **VERIFY:**
- - ✅ Toggle indicators work in mobile menu
- - ✅ Skeleton adapts to mobile (no sidebars)
- - ✅ Language buttons work correctly
-
-**Expected Behavior:**
-- Mobile skeleton should be single column (no sidebar grid)
-- All indicators should be visible and functional
-- Touch interactions should work smoothly
-
----
-
-### Test 8: Performance (60fps Animation)
-
-**Steps:**
-1. DevTools → Performance tab
-2. Click "Record"
-3. Click language button (trigger skeleton)
-4. Stop recording after transition completes
-5. **VERIFY:**
- - ✅ No long tasks (>50ms)
- - ✅ GPU acceleration active (green bars in Raster section)
- - ✅ Frame rate stays at ~60fps during animation
- - ✅ No layout thrashing (red bars)
-
-**Expected Behavior:**
-- Skeleton pulse should use GPU (transform/opacity only)
-- No CPU-heavy operations during transition
-- Smooth 60fps throughout entire animation
-
----
-
-### Test 9: Console Errors
-
-**Steps:**
-1. DevTools → Console tab
-2. Perform all above tests
-3. **VERIFY:**
- - ✅ No JavaScript errors
- - ✅ No HTMX errors
- - ✅ No Hyperscript errors
- - ✅ No 404s for CSS/JS resources
-
-**Expected Behavior:**
-- Clean console with no errors
-- All resources load successfully
-- HTMX and Hyperscript work silently
-
----
-
-## 📊 Success Criteria Summary
-
-### Phase 1 - HTMX Indicators
-- [x] All 8 HTMX interactions have loading indicators
-- [x] Indicators use opacity transitions (smooth fade)
-- [x] Spinning animation is GPU-accelerated
-- [x] Size variants work correctly
-- [x] Color variants work correctly
-- [x] Accessibility: reduced-motion support
-- [x] No layout shifts
-- [x] Works across browsers
-
-### Phase 2 - Skeleton Loaders
-- [x] Skeleton overlay appears during language switch
-- [x] Pulsing animation is smooth and professional
-- [x] Three-phase transition: fade-out → skeleton → fade-in
-- [x] Total transition time: 500-700ms on fast network
-- [x] Skeleton structure matches CV layout
-- [x] Hyperscript events work correctly
-- [x] HTMX swap timing works (swap:250ms settle:250ms)
-- [x] Responsive on mobile
-- [x] Accessibility: reduced-motion support
-- [x] Handles rapid clicking gracefully
-
----
-
-## 🔍 Known Issues & Edge Cases
-
-### None Found During Development
-All implementations follow best practices and handle edge cases:
-- ✅ Rapid clicking handled by HTMX queue
-- ✅ Network failures handled by HTMX error events
-- ✅ Mobile viewport tested and working
-- ✅ Accessibility tested and compliant
-- ✅ Performance optimized with GPU acceleration
-
----
-
-## 🎯 Next Steps (Optional Enhancements)
-
-### Future Improvements (Not in Current Scope)
-1. **Progressive Enhancement:** Add minimum display time for skeleton (prevent flash on fast networks)
-2. **Advanced Skeleton:** More detailed skeleton matching exact CV layout
-3. **Animation Variants:** Different skeleton animations (shimmer vs pulse)
-4. **Dark Mode:** Skeleton colors for dark theme (if dark mode added)
-5. **Global Loading Bar:** Top bar indicator for all HTMX requests
-
----
-
-## 📝 Implementation Notes
-
-### CSS Architecture
-- All loading indicator CSS in one section: lines 472-566
-- All skeleton loader CSS in one section: lines 568-716
-- Clean separation of concerns
-- Well-commented and maintainable
-
-### HTML/Template Architecture
-- Skeleton loader is a reusable partial template
-- Language selector has all behavior in one place
-- Hyperscript handlers co-located with HTMX attributes
-- Server responses match client-side templates
-
-### Performance Considerations
-- GPU-accelerated animations (opacity, transform)
-- Minimal DOM changes (show/hide existing elements)
-- No JavaScript execution (pure CSS + HTMX + Hyperscript)
-- Total CSS impact: ~150 lines (minified: ~3KB)
-
----
-
-## ✅ VERIFICATION COMPLETE
-
-**Backend Tests:**
-```bash
-# Server is running and serving updated files
-curl -s http://localhost:1999/health
-# {"status":"ok","timestamp":"2025-11-15T18:51:11.269733Z","version":"1.1.0"}
-
-# Indicators present in language selector
-curl -s http://localhost:1999/?lang=en | grep "htmx-indicator"
-# ✓ Found in page
-
-# Skeleton loader present
-curl -s http://localhost:1999/?lang=en | grep "skeleton-loader"
-# ✓ Found in page
-
-# CSS served correctly
-curl -s http://localhost:1999/static/css/main.css | grep "skeleton-pulse"
-# ✓ Animation present
-
-# Swap timing in responses
-curl -s http://localhost:1999/switch-language?lang=es | grep "swap:250ms"
-# ✓ Timing modifiers present
-```
-
-**Manual Browser Testing Required:**
-Open http://localhost:1999 and perform Tests 1-9 above to verify visual behavior.
-
----
-
-## 🎓 Learning & Documentation
-
-This implementation demonstrates:
-- **Modern Web Standards:** Progressive enhancement, accessibility-first
-- **HTMX Power:** Declarative loading states, swap timing, out-of-band updates
-- **Hyperscript Beauty:** Event-driven behavior without complex JavaScript
-- **CSS Animation:** GPU-accelerated keyframes, smooth transitions
-- **Performance:** 60fps animations, minimal overhead
-- **Maintainability:** Clear code structure, well-documented
-
-**Total Implementation Time:** ~2 hours
-**Files Modified:** 7 files
-**Files Created:** 2 files
-**Lines of Code:** ~300 lines CSS, ~100 lines HTML
-**Performance Impact:** <3KB minified CSS, zero JavaScript overhead
-**User Experience Impact:** Professional, modern, delightful
-
----
-
-## 📚 References
-
-- [HTMX Indicators Documentation](https://htmx.org/attributes/hx-indicator/)
-- [HTMX Swap Timing](https://htmx.org/attributes/hx-swap/)
-- [Hyperscript Documentation](https://hyperscript.org/)
-- [CSS Animations Best Practices](https://web.dev/animations/)
-- [Skeleton Screens Pattern](https://www.lukew.com/ff/entry.asp?1797)
-
----
-
-**Status:** ✅ READY FOR PRODUCTION
-**Tested:** ✅ Backend verified, manual browser testing pending
-**Performance:** ✅ GPU-accelerated, <700ms transitions
-**Accessibility:** ✅ WCAG 2.1 AA compliant
-**Browser Support:** ✅ All modern browsers (Chrome, Firefox, Safari, Edge)
diff --git a/doc/archive/INLINE-LOADING-STATES-IMPLEMENTATION.md b/doc/archive/INLINE-LOADING-STATES-IMPLEMENTATION.md
deleted file mode 100644
index d08dcda..0000000
--- a/doc/archive/INLINE-LOADING-STATES-IMPLEMENTATION.md
+++ /dev/null
@@ -1,380 +0,0 @@
-# Inline Loading States Implementation - Complete ✓
-
-## Summary
-
-Successfully redesigned the skeleton loader approach from a **blocking full-page overlay** to **elegant inline loading states** using HTMX's built-in CSS classes.
-
-## Problem Solved
-
-**Before:** Full-page skeleton overlay appeared during language transitions, blocking entire UI and all user interactions.
-
-**After:** Inline loading indicators and subtle content transitions - no blocking, smooth UX.
-
----
-
-## Changes Made
-
-### 1. Removed Blocking Overlay Components
-
-#### File: `templates/partials/navigation/language-selector.html`
-**Removed:**
-```html
-_="on htmx:beforeRequest from .selector-btn
- add .active to #skeleton-loader
- end
- on htmx:afterSwap from .selector-btn
- wait 100ms
- remove .active from #skeleton-loader
- end"
-```
-
-**Why:** This hyperscript controlled the blocking overlay's visibility. No longer needed.
-
-#### File: `templates/index.html`
-**Removed:**
-```html
-{{template "skeleton-loader" .}}
-```
-
-**Why:** The entire skeleton loader template inclusion is no longer needed.
-
-#### File: `static/css/main.css`
-**Removed:** ~150 lines of skeleton loader CSS including:
-- `#skeleton-loader` overlay styles
-- `.skeleton` animation keyframes
-- `.skeleton-container`, `.skeleton-page`, `.skeleton-grid` layouts
-- `.skeleton-header`, `.skeleton-badges`, `.skeleton-content` shapes
-- Responsive breakpoints for skeleton
-- All skeleton-specific animations
-
-**Why:** Replaced with HTMX's built-in CSS classes for inline transitions.
-
----
-
-### 2. Enhanced Inline Loading States
-
-#### File: `static/css/main.css`
-
-**Added/Enhanced:**
-
-```css
-/* ============================================================================
- Inline Loading States for HTMX Transitions
- ========================================================================= */
-
-/* Inline loading states - no blocking overlay, smooth transitions only */
-/* Language selector buttons already have htmx-indicator spinners */
-/* CV content areas show subtle fade during swap */
-
-/* Inline loading states for CV content during language transitions */
-.cv-page-content-wrapper.htmx-swapping {
- opacity: 0.5;
- transform: scale(0.99);
- pointer-events: none;
- filter: blur(1px);
-}
-
-.cv-page-content-wrapper.htmx-settling {
- opacity: 1;
- transform: scale(1);
- pointer-events: auto;
- filter: blur(0);
-}
-
-/* Respect reduced motion preference */
-@media (prefers-reduced-motion: reduce) {
- .cv-page-content-wrapper.htmx-swapping {
- transform: none;
- filter: none;
- opacity: 0.7;
- }
-}
-```
-
-**Removed duplicate rules** from line ~3886 to avoid CSS conflicts.
-
----
-
-## How It Works Now
-
-### Language Button Click Flow
-
-1. **User clicks language button** (EN/ES)
- - HTMX sends request to `/switch-language?lang=XX`
- - Button gets `.htmx-request` class
-
-2. **Inline spinner appears in button**
- - Already implemented via `hx-indicator="#lang-indicator-XX"`
- - Small spinning icon shows inside button
-
-3. **CV content starts transition**
- - HTMX adds `.htmx-swapping` class to `.cv-page-content-wrapper`
- - CSS applies:
- - Opacity: 0.5 (50% fade)
- - Transform: scale(0.99) (subtle shrink)
- - Filter: blur(1px) (slight blur)
- - Pointer-events: none (prevent clicks during swap)
-
-4. **Server responds with new content**
- - Language selector updates (primary swap)
- - Page 1 content updates (out-of-band swap)
- - Page 2 content updates (out-of-band swap)
-
-5. **Content settles into place**
- - HTMX adds `.htmx-settling` class
- - CSS transitions back to:
- - Opacity: 1 (full visibility)
- - Transform: scale(1) (normal size)
- - Filter: blur(0) (no blur)
- - Pointer-events: auto (interactive again)
-
-6. **Transition complete** (total: ~500ms)
- - 250ms swap phase
- - 250ms settle phase
- - Smooth, non-blocking experience
-
-### Key Advantages
-
-✓ **No Blocking:** Users can still scroll and interact with other parts of the page
-✓ **Inline Feedback:** Loading indicators appear contextually within elements
-✓ **Built-in HTMX:** Uses HTMX's native `.htmx-swapping` and `.htmx-settling` classes
-✓ **Pure CSS:** No JavaScript needed for transitions
-✓ **Accessible:** Respects `prefers-reduced-motion` preference
-✓ **Performant:** No rendering of 150+ skeleton DOM elements
-✓ **Subtle:** Gentle fade/blur effect doesn't distract from content
-
----
-
-## HTMX Configuration
-
-### Already in Place
-
-**Language Selector Buttons:**
-```html
-
-```
-
-**Timing:** `swap:250ms settle:250ms`
-- 250ms for content swap animation
-- 250ms for settle-in animation
-- Total: 500ms smooth transition
-
-**Indicators:**
-```html
-
-
-
-
-```
-
-**CV Content Wrappers:**
-```html
-
-
-
-```
-
-HTMX automatically applies `.htmx-swapping` and `.htmx-settling` classes during out-of-band swaps.
-
----
-
-## Testing
-
-### Verification Tests Passed ✓
-
-```bash
-# 1. No skeleton-loader in HTML
-curl -s 'http://localhost:1999/?lang=en' | grep -c 'skeleton-loader'
-# Result: 0 ✓
-
-# 2. No skeleton-loader in CSS
-curl -s 'http://localhost:1999/static/css/main.css' | grep -c '#skeleton-loader'
-# Result: 0 ✓
-
-# 3. htmx-swapping CSS present
-curl -s 'http://localhost:1999/static/css/main.css' | grep -c 'htmx-swapping'
-# Result: 2 ✓ (main style + media query)
-```
-
-### Manual Testing Checklist
-
-**Open the application:** http://localhost:1999/?lang=en
-
-1. **Click Spanish button:**
- - [✓] No full-page overlay appears
- - [✓] Button shows inline spinner (spinning icon)
- - [✓] CV content fades to 50% and blurs slightly
- - [✓] Can still scroll page during transition
- - [✓] Content swaps smoothly in ~500ms
- - [✓] No blocking behavior
-
-2. **Click English button:**
- - [✓] Same smooth inline behavior
- - [✓] No overlay blocking UI
- - [✓] Transitions feel natural and subtle
-
-3. **Browser Console:**
- - [✓] No errors about missing `#skeleton-loader`
- - [✓] No JavaScript errors
- - [✓] HTMX events firing correctly
-
-4. **DevTools Elements Tab:**
- - [✓] Watch `.htmx-swapping` class appear during transition
- - [✓] Watch `.htmx-settling` class appear during settle phase
- - [✓] Transitions smooth and CSS-driven
-
----
-
-## Files Modified
-
-| File | Changes | Lines Changed |
-|------|---------|---------------|
-| `templates/partials/navigation/language-selector.html` | Removed hyperscript | -8 lines |
-| `templates/index.html` | Removed skeleton-loader inclusion | -1 line |
-| `static/css/main.css` | Removed skeleton CSS, enhanced inline states | -150 lines, +20 lines |
-
-**Total:** Net reduction of ~139 lines of code
-
----
-
-## Test Files Created
-
-1. **test-inline-loading.html**
- - Standalone test page demonstrating inline loading
- - Shows language selector with indicators
- - Shows CV content with `.htmx-swapping` transitions
- - Includes visual checklist for verification
-
-2. **test-inline-loading-verification.md**
- - Comprehensive verification steps
- - Technical details about implementation
- - Before/after comparison
- - Success criteria checklist
-
-3. **INLINE-LOADING-STATES-IMPLEMENTATION.md** (this file)
- - Complete implementation documentation
- - How it works
- - Testing results
- - Migration guide
-
----
-
-## Performance Impact
-
-### Before (Blocking Overlay)
-- Rendered 150+ skeleton DOM elements
-- Full-page z-index layering
-- JavaScript show/hide control
-- Complete UI blocking
-- Higher memory footprint
-
-### After (Inline States)
-- Pure CSS transitions on existing elements
-- No additional DOM elements
-- HTMX built-in classes (zero custom JS)
-- Non-blocking user experience
-- Lower memory footprint
-- Faster perceived performance
-
----
-
-## Accessibility Improvements
-
-1. **Reduced Motion Support:**
- ```css
- @media (prefers-reduced-motion: reduce) {
- .cv-page-content-wrapper.htmx-swapping {
- transform: none;
- filter: none;
- opacity: 0.7;
- }
- }
- ```
-
-2. **Non-Blocking:**
- - Users can continue reading/scrolling during transitions
- - Keyboard navigation remains functional
- - Screen readers can announce changes without blocking
-
-3. **Semantic Indicators:**
- - ARIA labels on buttons: `aria-label="English"`
- - Loading icons: `aria-label="Loading"`
- - Proper button states maintained
-
----
-
-## Browser Compatibility
-
-CSS features used:
-- `opacity` - Universal support ✓
-- `transform: scale()` - IE10+ ✓
-- `filter: blur()` - IE13+, Edge 17+ ✓
-- `pointer-events` - IE11+ ✓
-- `@media (prefers-reduced-motion)` - Modern browsers, graceful fallback ✓
-
-All features degrade gracefully in older browsers.
-
----
-
-## HTMX Best Practices Applied
-
-1. **Locality of Behavior:**
- - Loading states defined where content swaps happen
- - CSS classes on same elements that get swapped
-
-2. **Progressive Enhancement:**
- - Works without JavaScript (form submission fallback)
- - Enhanced with HTMX for smooth transitions
-
-3. **Built-in Classes:**
- - Leveraged `.htmx-swapping` and `.htmx-settling`
- - No custom JavaScript event handlers needed
-
-4. **Server-Side State:**
- - Server determines language, sends updated HTML
- - Client just applies CSS transitions
-
-5. **Minimal Client-Side Code:**
- - Pure CSS for visual transitions
- - HTMX handles all swap logic
- - No custom transition scripts
-
----
-
-## Conclusion
-
-✅ **Successfully implemented inline loading states**
-✅ **Removed blocking full-page overlay**
-✅ **Improved user experience with non-blocking transitions**
-✅ **Reduced codebase complexity by ~139 lines**
-✅ **Enhanced accessibility with reduced motion support**
-✅ **Leveraged HTMX built-in capabilities**
-✅ **Pure CSS approach - no custom JavaScript needed**
-
-The application now provides a **smooth, modern, non-blocking user experience** during language transitions while maintaining full accessibility and respecting user preferences.
-
----
-
-## Next Steps (Optional Enhancements)
-
-1. **A/B Testing:** Compare user engagement with old vs new approach
-2. **Performance Metrics:** Measure perceived load time improvements
-3. **Visual Regression Tests:** Automated screenshots during transitions
-4. **E2E Tests:** Playwright tests to verify no blocking overlay appears
-5. **Analytics:** Track language switch interactions and transition smoothness
-
----
-
-**Implementation Date:** 2025-11-16
-**Status:** ✅ Complete and Tested
-**Impact:** High - Significantly improved UX during language transitions
diff --git a/doc/archive/NAVIGATION-FIX-REPORT.md b/doc/archive/NAVIGATION-FIX-REPORT.md
deleted file mode 100644
index cca52db..0000000
--- a/doc/archive/NAVIGATION-FIX-REPORT.md
+++ /dev/null
@@ -1,370 +0,0 @@
-# Navigation Bar Regression Fix Report
-
-**Date**: 2025-11-16
-**Issue**: Critical navigation bar layout regression
-**Status**: ✅ **FIXED AND VERIFIED**
-
----
-
-## Problem Report
-
-### Issue 1: Broken Navigation Layout
-**Symptom**: User reported seeing a "margin button in the main bar" - extra spacing/visual artifact
-**Impact**: Navigation bar layout appeared broken, unprofessional appearance
-**Severity**: High - Visual regression affecting primary navigation
-
-### Issue 2: Missing Theme Switcher
-**Symptom**: User couldn't see system theme switcher (Feature 004)
-**Status**: **FALSE ALARM** - Theme switcher is present and visible as "View" toggle
-**Location**: Third toggle in view-controls section (Length | Icons | **View**)
-
----
-
-## Root Cause Analysis
-
-### Investigation Process
-1. **Code Review**: Examined recent git changes to navigation templates
-2. **Visual Debugging**: Captured screenshots using Playwright
-3. **CSS Analysis**: Traced layout flow and positioning
-4. **DOM Inspection**: Analyzed element positioning and display properties
-
-### Root Cause Identified
-
-**Problem**: HTMX loading indicators breaking layout flow
-
-**Git Diff Analysis** (commit 6510036):
-```html
-
-
-
-
-
-
-
-
-```
-
-**CSS Issue**:
-```css
-/* BEFORE FIX: Indicators in layout flow */
-.htmx-indicator {
- opacity: 0;
- display: inline-flex; /* ← TAKES UP SPACE */
- /* NO position property */
-}
-
-/* Result: Invisible elements still affecting layout */
-/* Browser computed: position: static (default) */
-/* Flex container sees them as layout participants */
-```
-
-**Visual Impact**:
-- Indicators had `opacity: 0` (invisible) BUT `display: inline-flex`
-- They were positioned `static` (default), remaining in layout flow
-- Flex wrapper calculated their space, creating visual gaps
-- User saw "margin button" = invisible indicators taking space
-
----
-
-## Solution Applied
-
-### Single-Line Fix
-
-**File**: `static/css/main.css`
-**Line**: 510
-**Change**: Added `position: absolute;` to base `.htmx-indicator` rule
-
-```css
-/* Base indicator styles - hidden by default with opacity for smooth transitions */
-.htmx-indicator {
- opacity: 0; /* Hidden by default */
- transition: opacity 200ms ease-in-out;
- pointer-events: none;
- display: inline-flex;
- align-items: center;
- justify-content: center;
- position: absolute; /* ← FIX: Remove from layout flow to prevent spacing issues */
-}
-```
-
-### Why This Works
-
-1. **`position: absolute`**: Removes elements from normal document flow
-2. **No layout impact**: Parent flex container ignores absolutely positioned children
-3. **Maintains functionality**: Indicators still appear when HTMX activates them
-4. **Preserves positioning**: Specific positioning already defined for each indicator
-
-### CSS Cascade
-```css
-/* Base rule (applies to ALL indicators) */
-.htmx-indicator {
- position: absolute; /* Remove from flow */
-}
-
-/* Specific positioning (already existed) */
-#lang-indicator-en {
- position: absolute; /* Redundant but explicit */
- top: 50%;
- left: calc(1rem + 50px);
- transform: translateY(-50%);
-}
-
-#lang-indicator-es {
- position: absolute;
- top: 50%;
- left: calc(1rem + 135px);
- transform: translateY(-50%);
-}
-```
-
----
-
-## Verification Results
-
-### Automated Testing (Playwright)
-
-**Test Suite**: `test-final-verification.mjs`
-
-```
-✅ Test 1: Navigation Structure
- Action Bar: ✓ (50px)
- Language Wrapper: ✓ (50px)
- View Controls: ✓
- Theme Toggle: ✓ (Visible)
-
-✅ Test 2: Loading Indicators
- EN Indicator: ✓ (position: absolute, opacity: 0)
- ES Indicator: ✓ (position: absolute, opacity: 0)
-
-✅ Test 3: Screenshots Captured
- Full page: test-nav-final.png
- Nav bar only: test-nav-bar-final.png
-
-✅ Test 4: Language Switch Animation
- Language switched to Spanish: ✓
-```
-
-### Visual Verification
-
-**Before Fix**:
-- Navigation wrapper height: 38px (incorrect)
-- Indicators: `position: static`, causing layout issues
-- Extra spacing visible in navigation area
-
-**After Fix**:
-- Navigation wrapper height: 50px (correct)
-- Indicators: `position: absolute`, removed from flow
-- Clean, professional navigation layout
-- No visual artifacts or extra spacing
-
-### Manual Testing Checklist
-
-- [x] Navigation bar displays correctly
-- [x] No extra spacing or "margin button" artifact
-- [x] Language selector buttons (EN/ES) visible and aligned
-- [x] Three toggles visible: Length | Icons | View
-- [x] Theme switcher (View toggle) present and functional
-- [x] HTMX loading indicators work during language switch
-- [x] No regression in loading indicator functionality
-- [x] Responsive layout maintained
-- [x] All interactions smooth and professional
-
----
-
-## Theme Switcher Status
-
-### Investigation Results
-
-**User Concern**: "Theme switcher missing" (Feature 004 reported as not implemented)
-
-**Reality Check**:
-```html
-
-
-
-
-
-```
-
-**Status**: ✅ **IMPLEMENTED AND VISIBLE**
-
-**Location**: Navigation bar → View Controls → Third toggle
-**Label**: "View:" (English) / "Vista:" (Spanish)
-**Functionality**: Toggles between `theme-clean` (clean layout) and default (with sidebars)
-**Icons**: Sidebar layout (off) ↔ Body layout (on)
-
-**Possible Confusion**:
-- User expected "Dark/Light" system theme switcher
-- Feature 004 spec mentions "system-aware theme switcher"
-- **Current implementation**: Layout theme (clean vs default), NOT color theme
-- **Recommendation**: Review Feature 004 spec for color theme requirements
-
----
-
-## Additional Improvements Applied
-
-### Bonus Fixes (from git diff)
-
-1. **Info/Shortcuts Button Visibility**:
- ```css
- /* Increased opacity for better discoverability */
- .info-button, .shortcuts-btn {
- opacity: 0.6; /* Was 0.2 - now more visible */
- }
- ```
-
-2. **Language Selector Wrapper**:
- ```css
- /* Explicit wrapper positioning */
- .language-selector-wrapper {
- position: relative;
- display: inline-flex;
- height: 100%;
- }
- ```
-
-3. **Enhanced HTMX Indicator Rules**:
- ```css
- /* More explicit activation rules */
- span.htmx-request.htmx-indicator,
- .htmx-request .htmx-indicator,
- .htmx-request.htmx-indicator {
- opacity: 1 !important;
- }
- ```
-
----
-
-## Files Modified
-
-### Primary Fix
-- **`static/css/main.css`**: Added `position: absolute` to `.htmx-indicator` (line 510)
-
-### Related Changes (from previous work)
-- `templates/partials/navigation/language-selector.html`: Added loading indicators
-- `templates/partials/navigation/view-controls.html`: Theme toggle implementation
-- `templates/partials/navigation/hamburger-menu.html`: Mobile toggles with indicators
-
----
-
-## Regression Prevention
-
-### Lessons Learned
-
-1. **Invisible ≠ Non-existent**: Elements with `opacity: 0` still affect layout
-2. **Position matters**: `display: inline-flex` without `position: absolute` = layout participant
-3. **Test visually**: CSS changes can have subtle layout impacts
-4. **Before/after screenshots**: Essential for catching visual regressions
-
-### Future Safeguards
-
-1. **Visual regression testing**: Capture baseline screenshots for navigation
-2. **CSS review checklist**: When adding hidden elements, ensure proper positioning
-3. **Layout flow analysis**: Check if invisible elements affect flex/grid layouts
-4. **Browser DevTools**: Verify computed position values, not just declared
-
-### Code Review Guidelines
-
-When adding HTMX indicators:
-- ✅ DO: Use `position: absolute` for elements outside swap targets
-- ✅ DO: Place indicators in positioned wrapper (relative parent)
-- ✅ DO: Test with opacity transitions visible
-- ❌ DON'T: Rely on `opacity: 0` alone to hide layout-affecting elements
-- ❌ DON'T: Assume `display` property removes from layout (only `none` does)
-
----
-
-## Performance Impact
-
-### CSS Changes
-- **Added**: 1 property to base rule (`position: absolute`)
-- **Performance**: Negligible - single style property
-- **Layout recalculation**: Reduced (fewer layout participants)
-- **Paint**: No change
-- **Composite**: No change
-
-### User Experience
-- **Before**: Broken navigation, unprofessional appearance
-- **After**: Clean, polished navigation
-- **HTMX indicators**: Still work perfectly during language switches
-- **No functionality lost**: All features maintained
-
----
-
-## Testing Evidence
-
-### Screenshots
-1. **`debug-nav-bar-only.png`**: Initial broken state
-2. **`test-nav-bar-final.png`**: Fixed state (clean layout)
-3. **`test-nav-final.png`**: Full page after fix
-
-### Test Scripts
-1. **`debug-nav-screenshot.mjs`**: Visual debugging script
-2. **`test-final-verification.mjs`**: Comprehensive test suite
-
-### Console Output
-```
-🔍 Testing Navigation Bar Fix
-
-✅ Test 1: Navigation Structure
- Action Bar: ✓ (50px)
- Language Wrapper: ✓ (50px)
- View Controls: ✓
- Theme Toggle: ✓ (Visible)
-
-✅ Test 2: Loading Indicators
- EN Indicator: ✓ (position: absolute, opacity: 0)
- ES Indicator: ✓ (position: absolute, opacity: 0)
-
-📊 FINAL VERIFICATION SUMMARY
-═══════════════════════════════════════
-✅ Navigation bar layout: FIXED
-✅ Loading indicators: Positioned correctly (absolute)
-✅ Theme switcher: VISIBLE and FUNCTIONAL
-✅ Language switching: Works with indicators
-✅ No visual regressions detected
-✅ Navigation wrapper height: CORRECT
-═══════════════════════════════════════
-```
-
----
-
-## Conclusion
-
-### Summary
-
-**Problem**: Navigation bar layout broken due to invisible HTMX indicators taking up layout space
-**Solution**: Added `position: absolute` to base `.htmx-indicator` CSS rule
-**Result**: Clean navigation layout restored, all functionality preserved
-
-### Status
-
-- ✅ **Navigation Layout**: Fixed and verified
-- ✅ **Loading Indicators**: Working correctly (absolute positioning)
-- ✅ **Theme Switcher**: Present and functional (View toggle)
-- ✅ **No Regressions**: All features working as expected
-- ✅ **Visual Quality**: Professional, polished appearance restored
-
-### Next Steps
-
-1. **Feature 004 Review**: Clarify if color theme switcher is needed (vs current layout theme)
-2. **Visual Regression Suite**: Add baseline screenshots for future CI/CD
-3. **Code Review**: Get approval for fix before merging
-4. **Documentation**: Update CSS documentation with positioning guidelines
-
----
-
-**Fix Applied By**: Debug Surgeon
-**Verification Method**: Automated Playwright testing + Visual inspection
-**Confidence Level**: 100% - Fix verified with comprehensive testing
-**Ready for Production**: ✅ YES
diff --git a/doc/archive/PHASE-6-TESTING-CHECKLIST.md b/doc/archive/PHASE-6-TESTING-CHECKLIST.md
deleted file mode 100644
index 2324d03..0000000
--- a/doc/archive/PHASE-6-TESTING-CHECKLIST.md
+++ /dev/null
@@ -1,235 +0,0 @@
-# Phase 6 Testing Checklist
-
-**Status:** Ready for testing
-**Date:** 2025-01-12
-**JavaScript Reduction:** 954 → 239 lines (-74.9%)
-
----
-
-## 🎯 What Changed in Phase 6
-
-### 1. Scroll Behavior (59 lines → Hyperscript)
-- Header hide/show on scroll
-- Back-to-top button visibility
-- At-bottom positioning
-- **Now:** Clean 2-line implementation in ``
-
-### 2. Print Function (44 lines → Hyperscript)
-- Print-friendly theme/layout
-- Zoom reset for printing
-- State restoration after print
-- **Bug Fixed:** Zoom restoration now works!
-- **Now:** Single line `call printFriendly()`
-
-### 3. Hyperscript Organization
-- Extracted 115 lines from HTML templates
-- Created `/static/hyperscript/functions._hs` (110 lines)
-- Clean function calls instead of inline code
-
----
-
-## ✅ Testing Checklist
-
-### Scroll Behavior Testing
-
-**Header Hide/Show:**
-- [ ] Scroll down >100px → Header hides
-- [ ] Scroll up → Header shows
-- [ ] At top (<100px) → Header always visible
-- [ ] Works smoothly without flickering
-
-**Back-to-Top Button:**
-- [ ] Hidden when at top
-- [ ] Appears after scrolling down 300px
-- [ ] Click button → Smooth scroll to top
-- [ ] Native anchor link works
-
-**At-Bottom Positioning:**
-- [ ] Scroll to bottom (<50px from end)
-- [ ] Back-to-top button moves up (`.at-bottom` class)
-- [ ] Info button moves up (`.at-bottom` class)
-- [ ] Smooth transition
-
-**Menu Coordination:**
-- [ ] Open hamburger menu
-- [ ] Scroll down → Menu hides with header
-- [ ] Scroll up → Menu shows with header
-
----
-
-### Print Function Testing
-
-**Desktop Print Button:**
-- [ ] Click "Print Friendly" in action bar
-- [ ] Theme changes to clean (no sidebars)
-- [ ] Content changes to short version
-- [ ] Zoom resets to 100% in print preview
-- [ ] Cancel print dialog
-- [ ] Original theme restores
-- [ ] Original length restores
-- [ ] **CRITICAL:** Original zoom restores (was broken before!)
-
-**Mobile Print Button:**
-- [ ] Open hamburger menu
-- [ ] Click "Print Friendly"
-- [ ] Same behavior as desktop
-- [ ] All state restores correctly
-
-**Print with Different States:**
-- [ ] Print with clean theme already active → Stays clean
-- [ ] Print with long version → Restores to long
-- [ ] Print with 150% zoom → Restores to 150%
-- [ ] Print with 75% zoom → Restores to 75%
-
----
-
-### Hyperscript Functions Testing
-
-**Functions Load Correctly:**
-- [ ] Open browser console
-- [ ] No errors about undefined functions
-- [ ] Check `/static/hyperscript/functions._hs` loads
-- [ ] Verify loading order (functions before hyperscript lib)
-
-**Function Calls Work:**
-- [ ] `printFriendly()` called successfully
-- [ ] `initScrollBehavior()` initializes state
-- [ ] `handleScroll()` processes scroll events
-- [ ] No JavaScript errors in console
-
----
-
-### Cross-Browser Testing
-
-**Chrome/Edge:**
-- [ ] All scroll behavior works
-- [ ] Print function works
-- [ ] No console errors
-
-**Firefox:**
-- [ ] All scroll behavior works
-- [ ] Print function works
-- [ ] No console errors
-
-**Safari:**
-- [ ] All scroll behavior works
-- [ ] Print function works
-- [ ] No console errors
-
----
-
-### Mobile Testing
-
-**Responsive Behavior:**
-- [ ] Resize to mobile width (<768px)
-- [ ] Scroll behavior works on mobile
-- [ ] Print button in hamburger menu works
-- [ ] No errors on mobile viewport
-
----
-
-## 🐛 Known Issues to Watch For
-
-### Potential Issues:
-
-1. **Functions not loading:**
- - Check loading order in ``
- - Functions._hs must load BEFORE hyperscript.org
-
-2. **Print zoom not restoring:**
- - If zoom stays at 100%, check zoom slider exists
- - Verify `send input to #zoom-slider` works
-
-3. **Scroll state not persisting:**
- - Check `:lastScroll` variable scope
- - Verify `init` call happens on page load
-
----
-
-## 📊 Expected Results
-
-### Performance:
-- Smooth 60fps scrolling
-- No jank or flickering
-- Fast print dialog appearance
-- Instant state restoration
-
-### Functionality:
-- All 100% working (no regressions)
-- Print bug fixed (zoom restores)
-- Cleaner HTML templates
-- Organized code structure
-
-### File Sizes:
-- `main.js`: ~239 lines (was 954)
-- `functions._hs`: 110 lines (new)
-- Total JS: ~15KB (was ~35KB)
-
----
-
-## 🚨 If Something Breaks
-
-### Debug Steps:
-
-1. **Open browser console** (F12)
-2. **Check for errors:**
- - Red error messages?
- - Undefined function errors?
- - Loading errors?
-
-3. **Verify file loads:**
- - Network tab → Check `functions._hs` loads
- - Status 200 OK?
-
-4. **Check loading order:**
- ```html
-
-
-
- ```
-
-5. **Test JavaScript console:**
- ```javascript
- // Try calling functions manually:
- printFriendly()
- initScrollBehavior()
- handleScroll()
- ```
-
----
-
-## ✨ Success Criteria
-
-**Phase 6 is successful if:**
-- ✅ All scroll behavior works smoothly
-- ✅ Print function works + restores zoom
-- ✅ No JavaScript errors in console
-- ✅ HTML templates are clean (no long inline code)
-- ✅ Functions are reusable and organized
-- ✅ No regressions from Phase 5
-
----
-
-## 📝 Notes for Tomorrow
-
-**What to look for:**
-1. Smooth scroll behavior (most important - used constantly)
-2. Print zoom restoration (was broken, now fixed)
-3. Clean HTML templates (visual inspection)
-4. No console errors
-
-**If all tests pass:**
-- Phase 6 is complete! 🎉
-- 74.9% JavaScript reduction achieved
-- Ready to show off modern techniques
-
-**If issues found:**
-- Note specific issue
-- Check console for errors
-- Provide error messages/behavior description
-
----
-
-**Good luck with testing tomorrow! 🚀**
-
-*Remember: Start your CV server first, then test in browser at http://localhost:1999*
diff --git a/doc/archive/PROJECT_IMPROVEMENT_SUMMARY.md b/doc/archive/PROJECT_IMPROVEMENT_SUMMARY.md
deleted file mode 100644
index 4b15fdb..0000000
--- a/doc/archive/PROJECT_IMPROVEMENT_SUMMARY.md
+++ /dev/null
@@ -1,933 +0,0 @@
-# CV Site - Complete Project Improvement Summary
-
-**Project**: Go + HTMX CV Website
-**Duration**: 32-48 hours
-**Status**: ✅ **ALL PHASES COMPLETE**
-**Date**: November 2025
-
----
-
-## Executive Summary
-
-This document provides a comprehensive overview of all improvements made to the CV website across three major phases: Quick Wins, Security Hardening, and Testing Foundation. The project successfully transformed the application from having 0% test coverage and critical security vulnerabilities to a production-ready, highly secure, and well-tested system.
-
-### Key Achievements
-
-- **Performance**: 10x improvement (10ms → 2.2ms response time)
-- **Security**: 7 vulnerabilities eliminated, 100+ attack vectors blocked
-- **Testing**: 0% → 45% coverage baseline, 180+ tests created
-- **Quality**: 7.5/10 → 9/10 overall rating
-
----
-
-## Phase 1: Quick Wins (4-6 hours)
-
-### Overview
-
-Phase 1 focused on high-impact, low-effort improvements to immediately boost performance and eliminate critical security vulnerabilities.
-
-### 1.1 JSON Caching Implementation
-
-**Problem**: Application read JSON files from disk and parsed them on every request, causing 100-200µs overhead per request.
-
-**Solution**: Implemented production-grade caching with `sync.RWMutex`.
-
-**Files Created**:
-- `internal/cache/cv_cache.go` (189 lines)
-- `benchmark_cache.sh`
-- `CACHE_PERFORMANCE.md`
-
-**Results**:
-- Response time: 10ms → 2.2ms (**4.5x faster**)
-- Throughput: 200/s → 1,308/s (**6.5x increase**)
-- Cache hit rate: 99%
-- Memory usage: <1MB
-
-### 1.2 Command Injection Vulnerability Fix
-
-**Problem**: `getGitRepoFirstCommitDate()` function executed git commands with user-controlled paths from JSON files without validation (CWE-78, CVSS 9.8).
-
-**Solution**: Implemented comprehensive path validation with project directory whitelist.
-
-**Files Modified**:
-- `internal/handlers/cv.go` (+60 lines)
-
-**Implementation**:
-```go
-// Added path validation function
-func validateRepoPath(path string) error {
- absPath, _ := filepath.Abs(path)
- projectRoot, _ := filepath.Abs(".")
- if !strings.HasPrefix(absPath, projectRoot) {
- return fmt.Errorf("repository path outside project directory")
- }
- return nil
-}
-
-// Updated with timeout and validation
-func getGitRepoFirstCommitDate(repoPath string) (string, error) {
- if err := validateRepoPath(repoPath); err != nil {
- return "", err
- }
- ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
- defer cancel()
- cmd := exec.CommandContext(ctx, "git", "-C", repoPath, "log", "--reverse", "--format=%ci")
- // ...
-}
-```
-
-**Attack Vectors Blocked**:
-- Path traversal: `../../etc/passwd` ❌
-- Absolute paths: `/etc/passwd` ❌
-- Command injection: `data; rm -rf /` ❌
-- Pipe injection: `data | cat /etc/passwd` ❌
-
-### 1.3 XSS Vulnerability Fix
-
-**Problem**: `safeHTML` template function bypassed Go's automatic HTML escaping, allowing potential XSS attacks (CWE-79, CVSS 9.6).
-
-**Solution**: Removed unsafe function, enabled automatic HTML escaping.
-
-**Files Modified**:
-- `internal/templates/template.go` (-3 lines)
-- `templates/cv-content.html` (9 changes)
-
-**Before**:
-```go
-"safeHTML": func(s string) template.HTML {
- return template.HTML(s) // ❌ NO SANITIZATION!
-}
-```
-
-**After**: Function completely removed, automatic escaping enabled.
-
-### 1.4 International SEO - Hreflang Tags
-
-**Problem**: No hreflang tags meant search engines treated English and Spanish versions as duplicate content.
-
-**Solution**: Implemented proper hreflang tags for international SEO.
-
-**Files Modified**:
-- `internal/handlers/cv.go` (URL data in template context)
-- `templates/index.html` (hreflang tags in head)
-
-**Implementation**:
-```html
-
-
-
-
-```
-
-**SEO Impact**:
-- ✅ Search engines understand language versions
-- ✅ Correct language shown in search results
-- ✅ No duplicate content penalty
-- ✅ Better international targeting
-
-### Phase 1 Metrics
-
-| Metric | Before | After | Improvement |
-|--------|--------|-------|-------------|
-| Response Time | ~10ms | 2.2ms | 4.5x faster |
-| Throughput | ~200/s | 1,308/s | 6.5x increase |
-| Critical Vulnerabilities | 2 | 0 | -100% |
-| SEO Score | 5/10 | 9/10 | +80% |
-
----
-
-## Phase 2: Security Hardening (8-12 hours)
-
-### Overview
-
-Phase 2 implemented defense-in-depth security improvements beyond critical fixes, achieving comprehensive OWASP compliance.
-
-### 2.1 CSP Header Hardening
-
-**Problem**: Content Security Policy allowed `unsafe-inline` for scripts, weakening XSS protection.
-
-**Solution**: Removed unsafe-inline, implemented nonce-based CSP.
-
-**Files Created**:
-- `static/js/main.js` (506 lines - extracted inline JavaScript)
-- `internal/middleware/csp.go` (nonce generation)
-- `CSP-HARDENING-COMPLETE.md`
-
-**Files Modified**:
-- `internal/middleware/security.go` (CSP update + nonce)
-- `internal/handlers/cv.go` (pass nonce to templates)
-- `templates/index.html` (external scripts, nonce for Matomo)
-
-**CSP Before**:
-```go
-"script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net ..."
-```
-
-**CSP After**:
-```go
-"script-src 'self' 'nonce-{random}' https://cdn.jsdelivr.net ..."
-```
-
-**Security Improvement**:
-- XSS Risk: High → Low
-- OWASP Rating: Moderate → Strong
-
-### 2.2 Rate Limiter IP Validation
-
-**Problem**: Rate limiter trusted user-controlled `X-Forwarded-For` headers, allowing attackers to bypass rate limiting by spoofing IPs.
-
-**Solution**: Environment-based IP validation with trusted proxy support.
-
-**Files Created**:
-- `internal/middleware/security_test.go` (16 security tests)
-- `SECURITY_VALIDATION.md`
-- `.env` (configuration)
-
-**Files Modified**:
-- `internal/middleware/security.go` (secure IP extraction)
-- `main.go` (configuration loading)
-- `.env.example` (documentation)
-- `go.mod` (godotenv dependency)
-
-**Implementation**:
-```go
-type RateLimiterConfig struct {
- BehindProxy bool
- TrustedProxyIP string
-}
-
-func getClientIP(r *http.Request, config RateLimiterConfig) string {
- if config.BehindProxy {
- if config.TrustedProxyIP != "" {
- remoteIP := extractIP(r.RemoteAddr)
- if remoteIP != config.TrustedProxyIP {
- return remoteIP // Don't trust X-Forwarded-For
- }
- }
- xff := r.Header.Get("X-Forwarded-For")
- if xff != "" {
- ips := strings.Split(xff, ",")
- return strings.TrimSpace(ips[0])
- }
- }
- return extractIP(r.RemoteAddr)
-}
-```
-
-**Test Results**:
-- 16 security tests passing
-- 4 requests with different spoofed IPs → 4th blocked (same real IP detected)
-
-### 2.3 Goroutine Leak Fix
-
-**Problem**: Rate limiter's cleanup goroutine never stopped, causing memory leaks on application restarts.
-
-**Solution**: Implemented graceful goroutine shutdown.
-
-**Files Created**:
-- `GOROUTINE_LEAK_FIX.md`
-- `validate_goroutine_fix.sh`
-
-**Files Modified**:
-- `internal/middleware/security.go` (shutdown channels)
-- `main.go` (shutdown integration)
-
-**Implementation**:
-```go
-type RateLimiter struct {
- quit chan struct{}
- done chan struct{}
- shutdownMu sync.Mutex
- isShutdown bool
-}
-
-func (rl *RateLimiter) cleanup() {
- ticker := time.NewTicker(time.Minute)
- defer ticker.Stop()
- defer close(rl.done)
-
- for {
- select {
- case <-ticker.C:
- // Cleanup
- case <-rl.quit:
- return
- }
- }
-}
-
-func (rl *RateLimiter) Shutdown(ctx context.Context) error {
- rl.shutdownMu.Lock()
- defer rl.shutdownMu.Unlock()
-
- if rl.isShutdown {
- return nil
- }
-
- rl.isShutdown = true
- close(rl.quit)
-
- select {
- case <-rl.done:
- return nil
- case <-ctx.Done():
- return ctx.Err()
- }
-}
-```
-
-**Test Results**:
-- Before: 5 restarts = 5 goroutines leaked
-- After: 5 restarts = 0 goroutines leaked
-
-### 2.4 Comprehensive Input Validation
-
-**Problem**: User inputs not consistently validated, creating security and stability risks.
-
-**Solution**: Defense-in-depth validation with multiple layers.
-
-**Files Created**:
-- `internal/validator/validator.go` (validation functions)
-- `internal/validator/validator_test.go` (10 test suites)
-- `internal/middleware/validation.go` (validation middleware)
-- `SECURITY_VALIDATION_REPORT.md`
-
-**Files Modified**:
-- `internal/handlers/cv.go` (validation in all handlers)
-- `main.go` (validation middleware)
-
-**Validation Features**:
-```go
-// Whitelist-based language validation
-func ValidateLanguage(lang string) (string, error) {
- if lang == "" {
- return "en", nil
- }
- lang = strings.ToLower(strings.TrimSpace(lang))
- if !allowedLanguages[lang] {
- return "", ErrInvalidLanguage
- }
- return lang, nil
-}
-
-// Path traversal prevention
-func IsValidFilePath(path string) bool {
- if strings.Contains(path, "..") {
- return false
- }
- if strings.HasPrefix(path, "/") || strings.HasPrefix(path, "\\") {
- return false
- }
- return true
-}
-
-// Suspicious pattern detection
-func DetectSuspiciousPattern(input string) bool {
- patterns := []string{
- "OR '1'='1", "DROP TABLE", "; rm -rf", "| cat",
- "