diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md
index 8874c97..dc70ae7 100644
--- a/.planning/ROADMAP.md
+++ b/.planning/ROADMAP.md
@@ -89,7 +89,14 @@ Plans:
3. Sprachausgabe liest Companion-Text vor wenn aktiviert (Web Speech API, Deutsch)
4. Export und Import funktionieren: Exportieren → Browser-Daten loeschen → Importieren → Fortschritt wiederhergestellt
5. Keine unbehandelten Exceptions in der Browser-Konsole bei normalem Gebrauch
-**Plans**: TBD
+**Plans:** 4 plans
+
+Plans:
+- [ ] 04-01-PLAN.md — Audio system (Web Audio API sounds, Web Speech API speech, mute button)
+- [ ] 04-02-PLAN.md — Animation polish (leaf-fall, stardust, companion float), responsive, error handler
+- [ ] 04-03-PLAN.md — Export/Import/Reset in parent area
+- [ ] 04-04-PLAN.md — Wire audio into all screens, end-to-end human verification
+
**UI hint**: yes
## Progress
@@ -99,7 +106,7 @@ Phases execute in numeric order: 1 → 2 → 3 → 4
| Phase | Plans Complete | Status | Completed |
|-------|----------------|--------|-----------|
-| 1. Grundgerüst + Tippmechanik | 0/5 | Planning complete | - |
-| 2. Gemini-Integration + Asset-Pipeline | 0/5 | Planning complete | - |
-| 3. Komplettes Spielerlebnis | 0/5 | Planning complete | - |
-| 4. Polish + Audio | 0/? | Not started | - |
+| 1. Grundgerüst + Tippmechanik | 5/5 | Complete | - |
+| 2. Gemini-Integration + Asset-Pipeline | 5/5 | Complete | - |
+| 3. Komplettes Spielerlebnis | 5/5 | Complete | - |
+| 4. Polish + Audio | 0/4 | Planning complete | - |
diff --git a/.planning/phases/04-polish-audio/04-01-PLAN.md b/.planning/phases/04-polish-audio/04-01-PLAN.md
new file mode 100644
index 0000000..2caafd3
--- /dev/null
+++ b/.planning/phases/04-polish-audio/04-01-PLAN.md
@@ -0,0 +1,165 @@
+---
+phase: 04-polish-audio
+plan: 01
+type: execute
+wave: 1
+depends_on: []
+files_modified:
+ - src/audio/sounds.ts
+ - src/audio/speech.ts
+ - src/types.ts
+ - index.html
+ - src/styles/main.css
+ - src/main.ts
+autonomous: true
+requirements: [AUDI-01, AUDI-02, AUDI-03, AUDI-04, AUDI-05]
+
+must_haves:
+ truths:
+ - "playCorrectSound() erzeugt 800Hz Sinus-Ton fuer 0.1s bei audioEnabled=true"
+ - "playRewardSound() erzeugt aufsteigende Tonfolge fuer 0.8s"
+ - "playForestElementSound() erzeugt gefiltertes weisses Rauschen fuer 0.5s"
+ - "Mute-Button im DOM sichtbar, toggle aendert audioEnabled in Settings und persistiert"
+ - "speakText() liest deutschen Text via Web Speech API vor wenn speechEnabled=true"
+ - "AudioContext wird lazy bei erster User-Interaktion erstellt (Autoplay Policy)"
+ artifacts:
+ - path: "src/audio/sounds.ts"
+ provides: "Web Audio API sound effects"
+ exports: ["playCorrectSound", "playRewardSound", "playForestElementSound", "initAudioOnInteraction"]
+ - path: "src/audio/speech.ts"
+ provides: "Web Speech API text-to-speech"
+ exports: ["speakText"]
+ - path: "index.html"
+ provides: "Mute button element outside screens"
+ contains: "mute-btn"
+ key_links:
+ - from: "src/audio/sounds.ts"
+ to: "src/storage/db.ts"
+ via: "getSettings() check for audioEnabled"
+ pattern: "getSettings.*audioEnabled"
+ - from: "src/audio/speech.ts"
+ to: "src/storage/db.ts"
+ via: "getSettings() check for speechEnabled"
+ pattern: "getSettings.*speechEnabled"
+---
+
+
+Audio-System fuer Zauberwald: Web Audio API Sound-Effekte (3 Sounds), Mute-Button, optionale Sprachausgabe via Web Speech API.
+
+Purpose: Auditives Feedback macht das Tipperlebnis lebendig und belohnend -- per D-01 bis D-05 aus CONTEXT.md.
+Output: Zwei neue Module (sounds.ts, speech.ts), Mute-Button in index.html, speechEnabled Feld in Settings.
+
+
+
+@$HOME/.claude/get-shit-done/workflows/execute-plan.md
+@$HOME/.claude/get-shit-done/templates/summary.md
+
+
+
+@.planning/PROJECT.md
+@.planning/ROADMAP.md
+@.planning/STATE.md
+@.planning/phases/04-polish-audio/04-CONTEXT.md
+
+@src/types.ts
+@src/storage/db.ts
+@src/main.ts
+@index.html
+@src/styles/main.css
+
+
+
+
+
+ Task 1: Audio module + Speech module + Settings extension
+ src/audio/sounds.ts, src/audio/speech.ts, src/types.ts
+ src/types.ts, src/storage/db.ts, .planning/phases/04-polish-audio/04-CONTEXT.md
+
+1. In `src/types.ts`: Add `speechEnabled: boolean` to the `Settings` interface (per D-05). Keep existing fields unchanged.
+
+2. Create `src/audio/sounds.ts` (per D-01, D-02):
+ - Module-level `let audioCtx: AudioContext | null = null`
+ - `initAudioOnInteraction()`: Creates/resumes AudioContext on first call. Intended to be called from a user-interaction event handler. Export this.
+ - Helper `isAudioEnabled()`: async, calls `getSettings(db)` from db.ts (needs db reference -- use a module-level `let db: IDBDatabase | null` set via an `setAudioDB(d)` function, or import `getDB()` from app.ts). Check `settings?.audioEnabled !== false`. Return boolean.
+ - `playCorrectSound()`: async. Check `isAudioEnabled()`. If false, return. Ensure audioCtx exists (call initAudioOnInteraction if needed). Create OscillatorNode: type sine, frequency 800Hz, connect to gain (0.15), start, stop after 0.1s. Ramp gain to 0 over last 0.02s for click-free cutoff.
+ - `playRewardSound()`: async. Check enabled. Ascending tone sequence: play 3-4 notes (e.g. C5=523, E5=659, G5=784, C6=1047) each ~0.2s apart, each 0.15s duration, sine wave, gain 0.12. Total ~0.8s.
+ - `playForestElementSound()`: async. Check enabled. Create white noise buffer (AudioBuffer, fill with Math.random()*2-1), play through BiquadFilterNode (bandpass, frequency 3000Hz, Q 0.5), gain 0.1, duration 0.5s with gain ramp-down.
+ - All functions: wrap in try/catch (never throw to caller).
+
+3. Create `src/audio/speech.ts` (per D-04, D-05):
+ - `speakText(text: string)`: async. Check `speechEnabled` from Settings via getSettings. If not enabled, return. Check `window.speechSynthesis` exists. Create `SpeechSynthesisUtterance(text)`, set `lang='de-DE'`, `rate=0.9`, `pitch=1.1`. Try to find a German voice (`getVoices().find(v => v.lang.startsWith('de'))`), set if found. Call `speechSynthesis.speak(utterance)`. Wrap in try/catch, silent fallback.
+ - Handle voice loading: voices may load async. Use `speechSynthesis.onvoiceschanged` if `getVoices()` returns empty initially.
+
+
+ cd /home/dev/workspace/zauberwald && npx tsc --noEmit 2>&1 | head -20
+
+
+ - src/audio/sounds.ts exports playCorrectSound, playRewardSound, playForestElementSound, initAudioOnInteraction
+ - src/audio/speech.ts exports speakText
+ - Settings interface in types.ts includes speechEnabled: boolean
+ - All three sound functions check audioEnabled before playing
+ - speakText checks speechEnabled before speaking
+ - TypeScript compiles without errors
+
+ Three sound functions and speakText function exist, all check Settings before executing, TypeScript compiles clean
+
+
+
+ Task 2: Mute button in HTML + CSS + wiring in main.ts
+ index.html, src/styles/main.css, src/main.ts
+ index.html, src/main.ts, src/styles/main.css, src/storage/db.ts
+
+1. In `index.html` (per D-03): Add a mute button BEFORE the `