- AdminPage: password gate (sessionStorage), user table, stats banner
- Auto-login using stored sessionStorage password on mount
- App.tsx: route to admin when pathname === '/admin'
- Fix: remove redundant setPassword in auto-login effect (useState already seeds from sessionStorage)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- useMorseAudio: wraps MorseAudioEngine, exposes currentSignal for FlashArea
- useProgress: fetches /api/progress + /api/mnemonics, recordAnswer with local stats
- FlashArea: gold flash on signal, height varies dot/dash
- ScoreBar: level name, score, streak display
- PracticeCard: play button, answer input, correct/incorrect feedback with mnemonic
- GamePage: full practice loop, level-up modal at streak%10, anti-repeat history
- Fix: incorrect attempt recorded only once per challenge (no stat inflation on retries)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- MnemonicBuilder: 12 NOVICE_LETTERS, real-time validatePhrase, save/skip
- OnboardingPage: wraps builder, passes token and onComplete
- App.tsx: post-auth fetch /api/mnemonics, route to onboarding if <12 saved
- Fix: validatePhrase called with letter (not Morse pattern) as second arg
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- useAuth: session token from URL/localStorage, /api/auth/me validation, logout
- LoginPage: email form with POST /api/auth/request, error handling
- App.tsx: use useAuth hook, LoginPage, 'sent' confirmation route
- Fix: auto-route to game covers both 'login' and 'sent' routes when authenticated
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>