Add spelling improvements and local Piper TTS

Practice: fire streak badge, first-letter hint on wrong answers, missed-words drill session after practice completes.
Test: audio-only mode with listening state before input appears, larger re-read button.
Words: definition field (DB migration + admin editor + TTS playback).
TTS: replace speechSynthesis with local Piper via /api/tts, WAV cached in data/tts-cache, falls back to browser voice when Piper is not installed.
Dockerfile: switched to node:26-slim, installs Piper binary + en_US-lessac-medium voice.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Nate EmmertandClaude Sonnet 4.6 committed 2026-07-21 08:47:10 -04:00
1 parent 544469d6c9
commit 6f2281e2a7
8 files changed
+202 -35

No files matched your search

+10 -7
View File
@@ -156,13 +156,16 @@
<div class="progress-track"><div id="test-bar" class="progress-fill test-fill"></div></div>
<div id="test-card" class="word-card">
<button id="btn-test-speak" class="speak-btn">🔊 Say it again</button>
<p class="prompt">Spell the word. No hints — you've got this!</p>
<form id="test-form" autocomplete="off">
<input id="test-input" class="spell-input" type="text" autocomplete="off"
autocapitalize="off" autocorrect="off" spellcheck="false" aria-label="Spell the word">
<button type="submit" class="check-btn">Next →</button>
</form>
<p id="test-listening" class="test-listening-state">🔊 Listen carefully…</p>
<div id="test-form-row" hidden>
<button id="btn-test-speak" class="speak-btn speak-btn-prominent">🔊 Hear it again</button>
<p class="prompt">Now spell the word:</p>
<form id="test-form" autocomplete="off">
<input id="test-input" class="spell-input" type="text" autocomplete="off"
autocapitalize="off" autocorrect="off" spellcheck="false" aria-label="Spell the word">
<button type="submit" class="check-btn">Next →</button>
</form>
</div>
</div>
<div id="test-done" class="done-card" hidden></div>