Files
Zauberwald/.planning/phases/04-polish-audio/04-CONTEXT.md
T

104 lines
5.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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>