# Phase 4: Polish + Audio - Context

**Gathered:** 2026-03-29 (assumptions mode)
**Status:** Ready for planning

<domain>
## Phase Boundary

Visuell und auditiv angenehmes Erlebnis, bereit zum Testen mit dem Kind. Umfasst: Sound-Effekte (Web Audio API), Sprachausgabe (Web Speech API), sanfte Animationen (Blätter-Fall, Sternenstaub, Avatar-Schweben), Responsive bis 700px, globaler Error-Handler, Export/Import/Reset im Elternbereich. Keine neuen Features — rein Polish auf bestehendem Spielerlebnis.
</domain>

<decisions>
## Implementation Decisions

### Audio System
- **D-01:** Ein Modul `src/audio/sounds.ts` mit Web Audio API. Shared `AudioContext`, procedural Sounds (Oszillatoren, Noise Buffers). Exportiert: `playCorrectSound()` (800Hz, 0.1s), `playRewardSound()` (aufsteigende Tonfolge, 0.8s), `playForestElementSound()` (gefiltertes weisses Rauschen, 0.5s). Alle prüfen `audioEnabled` aus Settings Store.
- **D-02:** AudioContext wird bei erster User-Interaktion erstellt/resumed (Auto-Play Policy Compliance). Lazy initialization Pattern.
- **D-03:** Mute-Button als fixed-position Element in `<body>` ausserhalb aller `<section>` Screens. Liest/schreibt `audioEnabled` in Settings Store. Zustand persistiert über Reload.

### Speech Synthesis
- **D-04:** Optionale Sprachausgabe via `window.speechSynthesis` (Web Speech API). Deutsch, Rate 0.9, Pitch 1.1. Liest Companion-Texte vor (Begrüssung, Wald-Kommentar). Silent Fallback wenn keine deutsche Stimme verfügbar.
- **D-05:** Eigene Funktion `speakText(text: string)` in `src/audio/speech.ts`. Prüft Settings-Flag (neues Feld `speechEnabled: boolean` in Settings).

### Animations
- **D-06:** Fallende Buchstaben: Neue `@keyframes leaf-fall` Animation mit lateralem Sway (sinusförmig) + sanftem vertikalen Abstieg. Ersetzt bestehende `letter-float`.
- **D-07:** Sternenstaub bei richtigem Tastendruck: CSS `::before`/`::after` Pseudo-Elemente auf `.falling-letter--dissolve` mit kleinen Particles die auseinanderfliegen und verblassen. Pure CSS, kein JS.
- **D-08:** Companion-Avatar Float-Animation: Sanftes Auf-Ab-Schweben via `@keyframes companion-float` auf `.companion-area__avatar`.
- **D-09:** Alle Animationen respektieren `prefers-reduced-motion: reduce` Media Query.

### Responsive
- **D-10:** `@media (max-width: 700px)` in main.css. Keyboard-Tasten von 44px auf ~32px, Leertaste proportional. Fonts skalieren via `clamp()`. Forest-Grid reduziert auf 3×4 oder 2×6. Welcome-Cards in 2×2 statt 4×1.

### Error Handling
- **D-11:** Globaler Error-Handler in `src/main.ts`: `window.addEventListener('error')` + `window.addEventListener('unhandledrejection')`. Zeigt kindgerechtes Overlay ("Oh, der Wald braucht kurz eine Pause...") mit Reload-Button. Console.error für Debugging.

### Export/Import/Reset
- **D-12:** Export: `progress` + `settings` als JSON-Download. Blobs ausgeschlossen (zu gross). Funktion in `src/ui/parent.ts`.
- **D-13:** Import: JSON-Datei hochladen via `<input type="file">`. Validiert gegen Progress + Settings Interface-Struktur. Überschreibt nach Bestätigung.
- **D-14:** Reset: Alle 5 IndexedDB Stores löschen. Doppelte Bestätigung ("Wirklich alles löschen?" → "Ja, alles löschen"). Danach Reload auf Welcome-Screen.

### Claude's Discretion
- Exakte Frequenzen und Hüllkurven für Belohnungs-Tonfolge und Glitzer-Sound
- CSS Particle-Anzahl und Timing für Sternenstaub
- Leaf-Fall Animation Kurvenparameter
- Exact responsive Breakpoints innerhalb 700px
- Error-Overlay Styling
</decisions>

<canonical_refs>
## Canonical References

**Downstream agents MUST read these before planning or implementing.**

- `SPEC.md` section 11 — Audio-Details (Frequenzen, Dauern, Web Audio API)
- `SPEC.md` section 7.2 — Animationen (sanft, langsam, keine schnellen Blitze)
- `SPEC.md` section 12 — Responsive, Error-Handler
- `src/styles/main.css` — Bestehende Animationen (letter-float, falling-letter--dissolve, forest-element-appear)
- `src/ui/screens.ts` — Lesson screen (touch points für Audio + Animationen)
- `src/forest/reward.ts` — Reward screen (touch point für Belohnungs-Sound)
- `src/forest/scene.ts` — Forest scene (touch point für Waldelement-Sound)
- `src/ui/parent.ts` — Parent area (Export/Import/Reset einbauen)
- `src/storage/db.ts` — IndexedDB Stores (Export liest, Import schreibt, Reset löscht)
- `src/types.ts` — Settings Interface (audioEnabled existiert, speechEnabled hinzufügen)
- `src/main.ts` — Entry point (Error-Handler hier)
- `index.html` — Mute-Button ausserhalb Screens
</canonical_refs>

<code_context>
## Existing Code Insights

### Reusable Assets
- `Settings.audioEnabled: boolean` existiert in types.ts, Parent-Screen hat Toggle, DB-Methoden fertig
- `getSettings()`/`saveSettings()` in db.ts ready
- Bestehende CSS Animationen: `letter-float`, `falling-letter--dissolve`, `forest-element-appear`, `companion-float` (teilweise)
- `getProgress()`/`saveProgress()` für Export ready
- Parent-Screen HTML/CSS existiert mit Settings-Section

### Established Patterns
- Settings Store für Persistenz (audioEnabled Pattern wiederverwendbar für speechEnabled)
- CSS `@keyframes` für alle Animationen
- IndexedDB Promise-Wrapper Pattern in db.ts

### Integration Points
- `screens.ts` Zeile ~214 (result.correct Branch) → `playCorrectSound()`
- `reward.ts` initRewardScreen → `playRewardSound()` + `speakText(comment)`
- `scene.ts` forest element appear → `playForestElementSound()`
- `app.ts` greeting → `speakText(greeting)`
- `parent.ts` → Export/Import/Reset Buttons
- `main.ts` → Error-Handler
- `index.html` `<body>` → Mute-Button
</code_context>

<specifics>
## Specific Ideas

No specific requirements — open to standard approaches
</specifics>

<deferred>
## Deferred Ideas

None — analysis stayed within phase scope
</deferred>
