Files
2026-03-29 10:25:08 +02:00

1028 lines
49 KiB
Markdown
Raw Permalink 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.
# Zauberwald — Tipp-Trainer für Kinder
## Spec v1.1
---
## 0. Hinweise für die autonome Umsetzung (gsd / Claude Code)
### Autonomie-Prinzip
Diese Spec enthält alle Entscheidungen. Es gibt keine offenen Fragen. Bei Unklarheiten: Die Spec ist die Wahrheit. Bei Widersprüchen: Der spezifischere Abschnitt gewinnt. Ziel ist maximale autonome Ausführung ohne Rückfragen.
### Gemini API-Key
Der Gemini API-Key liegt in `config.json` im `public/`-Verzeichnis des Projekts (damit Vite sie als statische Datei serviert). Die App lädt sie zur Laufzeit via `fetch('/config.json')`. Die Datei wird via `.gitignore` nicht eingecheckt. Dieser Key soll **auch während der Entwicklung aktiv genutzt werden**, um:
1. Die Character Sheets für alle 4 Begleitfiguren vorab zu generieren (Build-Script)
2. Die Stil-Referenz-Waldszene vorab zu generieren (Build-Script)
3. Die Text-Generierungs-Pipeline zu testen (Unit-/Integrationstests)
4. Die Bild-Generierungs-Pipeline zu testen (Integrationstests)
Dafür wird ein Script `scripts/generate-assets.ts` erstellt, das die statischen Assets generiert und in `src/assets/generated/` ablegt. Diese werden eingecheckt.
### Empfohlene gsd-Konfiguration
```json
{
"mode": "yolo",
"granularity": "standard",
"workflow": {
"research": false,
"plan_check": true,
"verifier": true,
"auto_advance": true,
"discuss_mode": "assumptions",
"skip_discuss": true
}
}
```
Begründung: `research: false` weil die Spec alle Technologie-Entscheidungen enthält. `skip_discuss: true` weil alle Diskussionspunkte in der Spec beantwortet sind. `auto_advance: true` damit es durchläuft.
### Entwicklungsumgebung
Die Entwicklung findet auf einem **virtuellen privaten Server (VPS)** statt, nicht lokal. Das hat Implikationen:
1. **Vite Dev-Server muss von aussen erreichbar sein.** In `vite.config.ts`:
```typescript
export default defineConfig({
server: {
host: '0.0.0.0', // Auf allen Interfaces lauschen
port: 5173,
}
})
```
2. **Zwischenstände testen:** Der Entwickler (Papa) will die App zwischendurch im Browser auf seinem lokalen Rechner testen, indem er `http://<vps-ip>:5173` aufruft. Das muss jederzeit funktionieren.
3. **Preview-Build:** Zusätzlich zum Dev-Server ein `npm run preview` Script konfigurieren, das einen produktionsnahen Build serviert:
```json
{
"scripts": {
"dev": "vite --host",
"build": "tsc && vite build",
"preview": "vite preview --host --port 4173"
}
}
```
4. **Kein HTTPS nötig** — die App läuft nur im privaten Netz/zum Testen, nicht öffentlich.
### Phasen-Mapping
Die Roadmap soll exakt die 4 Phasen aus Abschnitt 16 übernehmen. Nicht umstrukturieren.
---
## 1. Überblick
**Zauberwald** ist eine Webapplikation, die einem 7-jährigen Kind das 10-Finger-Tastaturschreiben beibringt. Die App verbindet strukturiertes Tipptraining mit einer dynamisch wachsenden, KI-generierten Waldwelt.
### Kernphilosophie
- **Fester Rahmen, überraschende Belohnung**: Die Übungsstruktur (Progression, Fingerzonen, Mechanik) ist determiniert und vorhersehbar. Die Belohnungsebene (was im Wald erscheint, was die Begleitfigur sagt, welche Geschichten erzählt werden) ist dynamisch und wird zur Laufzeit von Gemini generiert.
- **Kein sichtbarer Leistungsdruck**: Keine Scores, keine Sterne-Bewertung, keine Timer, keine Fehler-Zähler. Fortschritt zeigt sich ausschliesslich im Wachstum des Waldes.
- **Neugier als Motor**: Nicht Perfektion motiviert zum Weitermachen, sondern die Frage "Was erscheint als Nächstes in meinem Wald?"
---
## 2. Zielgruppe & Nutzungskontext
### Primäre Nutzerin
- **Alter**: 7 Jahre, 1. Klasse
- **Lesefähigkeit**: Liest einfache, kurze Wörter flüssig. Neue oder längere Wörter brauchen noch Zeit. Nur einfache Sprache verwenden.
- **Vermuteter ADHS-Hintergrund** (nicht diagnostiziert):
- Niedrige Frustrationstoleranz
- Impulsiv
- Neigt dazu, bei Lernapps dieselbe Aufgabe zu wiederholen, bis sie perfekt ist (Perfektionismus-Loop)
- Maximale Übungsdauer: **5 Minuten**
- **Interessen**: Tiere (Pferde, Katzen), Feen, Einhörner, Magie, Natur/Wald
### Technischer Kontext
- Linux-Laptop, Desktop-Browser (kein Mobile-Support nötig)
- Stabile Internetverbindung vorhanden
- Einzige Nutzerin des Programms
---
## 3. Pädagogisches Konzept
### 3.1 Mikro-Einheiten
Jede Übungseinheit besteht aus 3 kurzen Phasen, die zusammen ca. 90120 Sekunden dauern. In 5 Minuten schafft sie 23 solcher Einheiten. Jede Einheit ist in sich abgeschlossen — sie kann nach jeder Einheit aufhören und hat trotzdem etwas erreicht.
#### Phase 1: "Entdecken" (~30 Sekunden)
- Ein neuer Buchstabe (oder ein Review-Buchstabe) wird vorgestellt
- Die Begleitfigur erklärt, welcher Finger den Buchstaben drückt
- Auf der Bildschirmtastatur leuchtet die richtige Taste in der Fingerfarbe auf
- Optional: Gemini-generierte Eselsbrücke ("Das F ist da, wo dein linker Zeigefinger den kleinen Hügel spürt!")
#### Phase 2: "Üben" (~60 Sekunden)
- Buchstaben erscheinen einzeln auf dem Bildschirm (als sanft fallende Blätter, Schneeflocken, Schmetterlinge — je nach Jahreszeit/Stimmung)
- Das Kind tippt den richtigen Buchstaben
- Bei richtigem Tastendruck: Buchstabe löst sich in Glitzer/Sternenstaub auf, sanftes positives Audio-Feedback
- Bei falschem Tastendruck: **Nichts passiert.** Der Buchstabe wartet geduldig. Die richtige Taste blinkt sanft auf der Bildschirmtastatur. Kein Fehler-Sound, kein roter Blitz, kein Zähler.
- Tempo passt sich an: Langsam starten, leicht schneller werden wenn es gut läuft, sofort wieder langsamer bei Schwierigkeiten
- Ca. 812 Buchstaben pro Übung
#### Phase 3: "Wörter bauen" (~60 Sekunden)
- 34 kurze Wörter aus den bisher gelernten Buchstaben
- Die Wörter erscheinen als Lückentext, Buchstabe für Buchstabe zu tippen
- Kontext: Die Wörter beschriften etwas im Wald oder sind Namen für Waldbewohner
- Nur Wörter, die ausschliesslich bereits gelernte Buchstaben verwenden
- Max. 5 Buchstaben pro Wort
#### Nach jeder Einheit: Belohnung
- Ein neues Element erscheint im Wald (KI-generiertes Bild)
- Die Begleitfigur kommentiert es (KI-generierter Text)
- Kurzer Moment des Staunens, dann kann sie entscheiden: Weitermachen oder aufhören
### 3.2 Umgang mit Frustration und Perfektionismus
| Problem | Design-Lösung |
|---------|---------------|
| Fehler frustrieren | Fehler sind unsichtbar — kein negatives Feedback jeglicher Art |
| Will dieselbe Übung wiederholen bis perfekt | Wiederholung erlaubt, aber nach 2× erscheint die Begleitfigur mit Ermutigung + Neugier-Trigger ("Magst du sehen, was als Nächstes kommt?"). Alte Übungen bleiben zugänglich. |
| Geschwindigkeit als Stressor | Kein Timer, keine Geschwindigkeitsanzeige. Nur im Elternbereich einsehbar. |
| Vergleich/Wettbewerb | Keine Ranglisten, keine Punkte, keine Sterne. Einziger Fortschrittsmesser: der Wald wächst. |
| Session zu lang | Jede Mikro-Einheit hat ein natürliches Ende. Kein "Du bist erst bei 3 von 10!" |
| Neue Inhalte als Bedrohung | Neues wird als Belohnung geframed, nicht als Anforderung. "Du hast dir den nächsten Buchstaben verdient!" |
### 3.3 Genauigkeit vor Geschwindigkeit
Die App misst intern beides, zeigt dem Kind aber nur den Wald-Fortschritt. Geschwindigkeit wird nie thematisiert. Das Kind soll lernen, die richtigen Finger zu verwenden, nicht schnell zu sein. Das steht im Einklang mit der bewährten Pädagogik: Erst Genauigkeit automatisieren, Geschwindigkeit kommt von alleine.
---
## 4. Progressionssystem
### 4.1 Stufenplan (QWERTZ-Layout)
Die Reihenfolge orientiert sich an der bewährten Progression: Grundreihe → Oberreihe → Unterreihe → Zahlen/Sonderzeichen.
| Stufe | Neue Tasten | Finger | Übungswörter (Beispiele) |
|-------|-------------|--------|--------------------------|
| 1 | F J + Leertaste | Beide Zeigefinger | (nur Buchstaben) |
| 2 | D K | Mittelfinger | (nur Buchstaben) |
| 3 | S L | Ringfinger | als, falls |
| 4 | A Ö | Kleine Finger | da, das, Salad |
| 5 | G H | Zeigefinger Mitte | glas, halb, Jagd |
| 6 | E I | Mittelfinger oben | Eis, Idee, Kleid |
| 7 | R U | Zeigefinger oben | Ruhe, Krug |
| 8 | T Z | Zeigefinger oben | Katze, Salz |
| 9 | W O | Ringfinger oben | Wohl, Wald, Ohr |
| 10 | Q P | Kleine Finger oben | Quark |
| 11 | Y X | Ringfinger/Kleiner Finger unten | |
| 12 | C V | Mittelfinger/Zeigefinger unten | |
| 13 | B N M | Zeigefinger unten + Mittelfinger | Baum, Name, Mund |
| 14 | Ä Ü | Kleine Finger (Layout-abhängig) | |
| 15 | Umlaute, Shift, Punkt, Komma | Diverse | Ganze Sätze |
**Anmerkung zur Wortgenerierung**: Die Übungswörter können teilweise von Gemini generiert werden, mit dem Constraint: "Nur Buchstaben [X, Y, Z, ...] verwenden, max. 5 Buchstaben, einfache deutsche Wörter die ein 7-jähriges Kind kennt."
### 4.2 Freischaltung
- Eine Stufe gilt als "abgeschlossen", wenn die Übung einmal durchgespielt wurde — nicht perfekt, einfach durchgespielt
- Die nächste Stufe wird sofort freigeschaltet
- Alle bereits gespielten Stufen bleiben jederzeit zugänglich zum Wiederholen
- Keine Sperren, keine "3 Sterne um weiterzukommen"-Mechanik
### 4.3 Review-Mechanik
- Jede 3. Übungseinheit ist automatisch ein Review: Es kommen gemischte Buchstaben aus den letzten 23 gelernten Stufen
- Reviews generieren ebenfalls Wald-Belohnungen (damit sie nicht als "langweilig" empfunden werden)
---
## 5. Spielwelt: Der Zauberwald
### 5.1 Visuelle Grundidee
Eine Waldlichtung, die zu Beginn leer und still ist. Mit jeder abgeschlossenen Übungseinheit erscheint ein neues Element: eine Blume, ein Tier, ein Pilz, ein Bach, ein Regenbogen. Die Welt füllt sich nach und nach und wird immer reichhaltiger.
**Visueller Stil**: Warm, weich, einladend. Pastellfarben, sanfte Formen, keine grellen Kontraste. Inspiriert von Kinderbuch-Illustrationen (Aquarell-Stil). Keine "Pixel-Art" oder "Game-Look".
### 5.2 Begleitfigur
Bei Spielstart wählt das Kind eine von vier Begleitfiguren:
| Figur | Name | Persönlichkeit (für Gemini-Prompt) |
|-------|------|------------------------------------|
| Fee | Lila | Sanft, ermutigend, ein bisschen verträumt. Spricht in kurzen, liebevollen Sätzen. |
| Einhorn | Stella | Fröhlich, enthusiastisch, feiert jeden kleinen Erfolg. Etwas überschwänglich. |
| Fuchs | Finn | Ruhig, weise, humorvoll. Gibt Tipps mit einem Augenzwinkern. |
| Eule | Elsa | Geduldig, warm, grossmütterlich. Ermutigt ohne Druck. |
Die Begleitfigur:
- Stellt neue Buchstaben vor
- Kommentiert Waldbelohnungen (KI-generiert, daher immer unterschiedlich)
- Ermutigt bei Wiederholungen, weiterzugehen
- Erscheint beim Öffnen der App mit einer Begrüssung (KI-generiert, zeit-/tagesabhängig)
- Spricht NIE negativ, bewertet NIE Leistung, vergleicht NIE
### 5.3 Dynamisches Wachstum (Gemini-generiert)
Nach jeder Übungseinheit generiert die App:
1. **Ein Bild** eines neuen Waldbewohners/Elements (Gemini Image / Nano Banana 2)
- Prompt-Template: "Kinderbuch-Illustration, Aquarell-Stil, [Tier/Pflanze/Element], magischer Wald, warm, einladend, für Kinder, Pastellfarben, kein Text"
- Das Bild wird im Wald an einer Position platziert und dauerhaft gecacht
2. **Einen kurzen Text** der Begleitfigur (Gemini Flash Text)
- Prompt-Template: "Du bist [Figurname], [Persönlichkeit]. Ein Kind hat gerade [Buchstabe X] gelernt. Schreib 12 kurze Sätze (max. 30 Wörter), mit denen du das neue Waldelement begrüsst. Einfache Sprache, für 7-Jährige verständlich. Kein Lob für Leistung, sondern Staunen über die Welt."
3. **Optional: Audio-Ausgabe** des Begleitfigur-Textes (Gemini TTS oder Web Speech API als Fallback)
### 5.4 Visuelle Konsistenz
Konsistenz ist entscheidend — die Waldwelt muss sich wie ein zusammenhängender Ort anfühlen, nicht wie eine Collage zufälliger Bilder. Es gibt zwei Konsistenz-Ebenen:
#### Ebene 1: Begleitfiguren (100% Konsistenz erforderlich)
Die 4 Begleitfiguren (Fee Lila, Einhorn Stella, Fuchs Finn, Eule Elsa) erscheinen in jeder Sitzung, in jeder Sprechblase, auf jedem Screen. Sie müssen **pixel-perfekt identisch** sein.
**Strategie: Character Sheet + Referenzbild-Ansatz**
1. **Beim allerersten Start** (oder beim Wechsel der Begleitfigur) wird einmalig ein **Character Sheet** generiert:
- Gemini-Prompt: "Character sheet of [Figurname], a [Beschreibung]. Front view and side view. Watercolor children's book illustration style, warm pastel colors. White background. Consistent proportions. Label: FRONT VIEW / SIDE VIEW"
- Dieses Character Sheet wird in IndexedDB als `companionCharacterSheet` gespeichert (Blob)
- Es dient als **Referenzbild für alle zukünftigen Generierungen**, die die Begleitfigur enthalten
2. **Für UI-Elemente** (Sprechblase, Menüs, etc.) wird aus dem Character Sheet ein **festes Avatar-Bild** extrahiert oder ein separates, einmaliges Portrait generiert und gecacht. Dieses ändert sich nie mehr.
3. **Wenn die Begleitfigur in Waldszenen auftaucht**, wird das Character Sheet als Referenzbild an die Gemini API mitgesendet (Character Consistency Feature, bis zu 14 Referenzbilder möglich).
**Fallback:** Falls die initiale Generierung nicht zufriedenstellend ist, enthält die App 4 vorgezeichnete SVG-Avatare als Fallback. Diese sind immer verfügbar und werden auch während der API-Call-Wartezeit angezeigt.
#### Ebene 2: Waldbewohner (Konsistenz pro Element)
Jedes Waldelement (Tier, Pflanze, etc.) wird **einmal generiert und für immer gecacht**. Dasselbe Reh sieht immer gleich aus, weil es immer dasselbe Bild ist.
**Strategie:**
1. Bei Generierung eines neuen Waldelements:
- Bild wird generiert (Gemini Image)
- Bild-Blob wird in IndexedDB gespeichert (`forestElements.imageBlob`)
- Zusätzlich wird eine kurze Beschreibung gespeichert (`forestElements.description`), z.B. "Ein kleines braunes Reh mit weissen Flecken und grossen Augen"
2. Das gecachte Bild wird immer verwendet, nie neu generiert
3. Falls das Bild in einem neuen Kontext gebraucht wird (z.B. Belohnungsscreen vs. Waldübersicht), wird dasselbe gecachte Bild verwendet — ggf. unterschiedlich skaliert/positioniert
#### Ebene 3: Gesamt-Stil-Konsistenz
Alle generierten Bilder müssen im selben visuellen Stil sein. Dafür:
1. **Stil-Prompt-Prefix** wird an jeden Bildgenerierungs-Call angehängt:
```
"Watercolor children's book illustration, warm pastel colors, soft edges,
magical forest atmosphere, gentle and dreamy, no text, no letters,
consistent with the following art style: [Referenzbild des ersten generierten Elements]"
```
2. **Stil-Referenzbild**: Das allererste generierte Waldelement dient als Stil-Referenz für alle weiteren. Es wird als `styleReferenceBlob` in IndexedDB gespeichert und bei jeder Bildgenerierung als Referenzbild mitgesendet.
3. So entsteht über die Zeit ein kohärenter visueller Stil, auch wenn die Inhalte variieren.
#### Zusammenfassung Konsistenz-Architektur
```
Beim ersten Start:
1. Character Sheet der gewählten Begleitfigur generieren → IndexedDB
2. Avatar-Portrait extrahieren/generieren → IndexedDB
3. Erste Waldszene generieren → wird zur Stil-Referenz → IndexedDB
Bei jeder Übungseinheit:
1. Begleitfigur: Immer gecachtes Avatar-Bild verwenden
2. Neues Waldelement generieren MIT:
- Character Sheet als Referenz (falls Figur im Bild)
- Stil-Referenzbild als Referenz (immer)
3. Generiertes Bild cachen → IndexedDB
```
---
## 6. Technische Architektur
### 6.1 Übersicht
```
Webapplikation (SPA)
├── Frontend: Vanilla TypeScript (kein Framework)
├── Kein eigener Backend-Server
├── Gemini API: Direkte REST-Calls vom Frontend
├── Datenhaltung: IndexedDB (im Browser)
└── Deployment: Vite dev-server lokal
```
### 6.2 Tech-Stack
Alle Entscheidungen sind final:
- **Sprache**: TypeScript (strict mode, `"strict": true` in tsconfig)
- **Framework**: Keins. Vanilla TypeScript mit DOM-Manipulation. Kein React, Svelte, Preact, Vue.
- **Build**: Vite 6.x (vanilla-ts Template)
- **Styling**: Einzelne `main.css` mit CSS Custom Properties. Kein Tailwind, kein CSS-in-JS, kein Preprocessor.
- **Gemini API**: Eigener typisierter REST-Client via `fetch()`. Kein Google SDK.
- **Audio**: Web Audio API für Sound-Effekte. Web Speech API (`speechSynthesis`) für optionale Sprachausgabe. Kein Gemini TTS.
- **Linting**: Biome (Format + Lint in einem Tool)
- **Testing**: Vitest für Unit-Tests der Kernlogik
- **Waldszene-Rendering**: Ein `<div>` Container mit CSS Grid/Flexbox. Generierte Bilder als `<img>` Elemente positioniert über einem SVG-Hintergrund (statische Waldlandschaft). Kein Canvas, kein WebGL.
- **Bild-Platzierung im Wald**: Rasterbasiert mit leichter Zufallsvariation. 4 Spalten × 3 Reihen = 12 Slots. Jedes neue Element bekommt den nächsten freien Slot ± 1020px Offset.
- **Adaptives Tempo (Phase "Üben")**: Einfache Heuristik: Startintervall 3 Sekunden. Nach 2 richtigen in Folge: -200ms (min. 1.5s). Nach 1 Fehler: +500ms (max. 4s). Reset auf 3s bei neuer Übung.
### 6.3 Datenhaltung (IndexedDB)
IndexedDB statt localStorage, weil wir binäre Daten (generierte Bilder) speichern müssen.
#### Stores:
```
progress
├── currentLevel: number
├── completedLevels: number[]
├── totalSessions: number
├── sessionDates: string[] (ISO-Dates, nur Tage — für Elternbereich)
├── selectedCharacter: 'fee' | 'einhorn' | 'fuchs' | 'eule'
├── selectedLayout: 'de' | 'ch'
companionAssets
├── characterSheet: Blob (generiertes Character Sheet — Referenz für Konsistenz)
├── avatarImage: Blob (gecachtes Portrait für UI-Elemente)
├── characterType: string (welche Figur)
├── generatedAt: string (ISO-Date)
styleReference
├── imageBlob: Blob (erstes generiertes Waldelement — Stil-Anker)
├── generatedAt: string (ISO-Date)
forestElements
├── id: auto-increment
├── levelCompleted: number
├── imageBlob: Blob (gecachtes generiertes Bild)
├── imagePrompt: string (für Debugging/Regenerierung)
├── description: string (z.B. "kleines braunes Reh mit weissen Flecken")
├── companionText: string
├── position: { x: number, y: number } (Position im Wald)
├── createdAt: string (ISO-Date)
settings
├── audioEnabled: boolean
├── apiKey: string (falls nicht über Config-Datei gelöst)
```
#### Export/Import
- JSON-Export umfasst `progress` und Metadaten aus `forestElements` (ohne Blobs — die sind zu gross)
- Beim Import können Bilder neu generiert werden (kostet API-Calls, aber ist ein Edge Case)
- Export-Button im Elternbereich
### 6.4 API-Key-Handling
Der Gemini-API-Key liegt in `public/config.json` (wird von Vite als statische Datei serviert):
```json
{
"geminiApiKey": "AIza...",
"geminiModel": "gemini-2.5-flash",
"imageModel": "gemini-3.1-flash-image-preview"
}
```
- Die App lädt `config.json` beim Start via `fetch('/config.json')`
- `public/config.json` wird via `.gitignore` nicht eingecheckt
- `scripts/generate-assets.ts` liest dieselbe Datei direkt via `fs.readFileSync('./public/config.json')`
- Fallback: Falls keine Config gefunden wird, zeigt die App im Elternbereich ein Eingabefeld für den API-Key an und speichert ihn in IndexedDB
**Sicherheitshinweis**: Da die App nur privat auf einem VPS läuft und nicht öffentlich deployed wird, ist ein API-Key im Frontend akzeptabel.
### 6.5 Caching-Strategie
- Character Sheets + Avatare sind vorab-generierte statische Assets → kein API-Call beim Onboarding
- Waldelement-Bilder werden aggressiv gecacht (einmal generiert, nie neu generiert)
- Text-Generierung wird für häufige Situationen mit statischen Fallback-Texten ergänzt
- Review-Einheiten verwenden bestehende Waldbilder und generieren nur neuen Begleittext
- Pre-Generation: Während sie tippt, wird im Hintergrund das nächste Bild generiert → keine Wartezeit
---
## 7. UI-Struktur
### 7.1 Screens
```
1. Willkommen (nur beim allerersten Start)
├── Begleitfigur wählen (Avatar-Preview aus statischen Assets)
├── Tastatur-Layout wählen (DE/CH)
└── "Los geht's" → Direkt zur Wald-Übersicht (kein Lade-Screen)
(Character Sheet + Avatar liegen als statische Assets vor)
2. Wald-Übersicht (Hauptscreen)
├── Waldszene mit allen bisher generierten Elementen
├── Stufenkarte (welche Stufen verfügbar/abgeschlossen)
├── "Weiter üben" Button (startet nächste offene Stufe)
└── Zahnrad-Icon → Elternbereich
3. Übung (Lesson)
├── Phase-Anzeige (Entdecken / Üben / Wörter)
├── Begleitfigur + Sprechblase
├── Übungsbereich (variiert je nach Phase)
└── Bildschirmtastatur mit Farbzonen
4. Belohnung (nach jeder Einheit)
├── Neues Waldelement (KI-generiertes Bild)
├── Begleitfigur-Kommentar
└── "Weiter üben" / "Zurück zum Wald" Buttons
5. Elternbereich (hinter Zugangscode)
├── Fortschritts-Übersicht (Stufen, Übungstage)
├── Export/Import Fortschritt
├── Layout-Wechsel
├── API-Key-Konfiguration (Fallback)
├── Audio an/aus
└── Fortschritt zurücksetzen (mit Bestätigung)
```
### 7.2 Visuelle Gestaltung
#### Farben
```css
/* Grundpalette — warm, einladend, Waldstimmung */
--bg-cream: #FFF8F0; /* Haupthintergrund */
--bg-forest: #E8F5E4; /* Wald-Hintergrund */
--text-dark: #3D3225; /* Haupttext */
--text-warm: #5C4A3A; /* Sekundärtext */
--text-light: #8B7D6B; /* Subtiler Text */
--accent-green: #6DB87D; /* Erfolg, Hauptakzent */
--accent-gold: #E8B84B; /* Highlight, aktive Taste */
--accent-pink: #E88BAE; /* Begleitfigur Fee */
--accent-purple: #9B7DC4; /* Dekorativ */
--accent-blue: #7DB8D4; /* Wasser, Himmel */
/* Fingerfarben — weiche Pastelltöne */
--finger-l-pinky: #E8B4C8; /* Linker kleiner Finger */
--finger-l-ring: #C4A8D4; /* Linker Ringfinger */
--finger-l-mid: #A8C4E0; /* Linker Mittelfinger */
--finger-l-index: #A8D8B8; /* Linker Zeigefinger */
--finger-r-index: #D4D8A8; /* Rechter Zeigefinger */
--finger-r-mid: #E0C4A8; /* Rechter Mittelfinger */
--finger-r-ring: #D4A8A8; /* Rechter Ringfinger */
--finger-r-pinky: #C8B4E8; /* Rechter kleiner Finger */
--finger-thumb: #D4CFC8; /* Daumen (Leertaste) */
```
#### Typografie
- **Überschriften**: Quicksand (rund, freundlich, kindgerecht)
- **Fliesstext**: Nunito (gut lesbar, warm)
- **Tastatur-Labels**: Quicksand Bold
- Mindestschriftgrösse: 16px (für Kindertauglichkeit)
#### Animationen
- Sanft und langsam. Keine schnellen Blitze oder Ruckler.
- Fallende Buchstaben: Wie Blätter, mit leichtem Schweben
- Erfolg: Sanftes Aufleuchten + Auflösen in Sternenstaub
- Neues Waldelement: Langsames Einblenden (fade-in + leichtes scale-up)
- Begleitfigur: Sanftes Schweben (float-Animation)
---
## 8. Tastatur-Anzeige
### 8.1 Bildschirmtastatur
- Zeigt das vollständige QWERTZ-Layout
- Tasten, die in der aktuellen Stufe relevant sind, leuchten in ihrer Fingerfarbe
- Noch nicht gelernte Tasten sind ausgegraut
- Die aktuell zu drückende Taste pulsiert sanft
- Beim Tastendruck: Kurze "gedrückt"-Animation (scale down)
### 8.2 Layout-Unterschiede DE vs. CH
| Taste | DE | CH |
|-------|----|----|
| Ö | Ö (rechts neben L) | Ö (rechts neben L) |
| Ä | Ä (rechts neben Ö) | Ä (rechts neben Ö) |
| Ü | Ü (rechts neben P) | Ü (rechts neben P) |
| ß | ß (rechts neben 0) | Nicht vorhanden |
| Sonderzeichen-Reihe | Standard DE | Leicht abweichend |
Für die Grundlagen (Buchstaben) sind die Layouts identisch. Unterschiede werden erst ab Stufe 14+ relevant.
### 8.3 Fingerzuordnung (Standard QWERTZ)
```
Linke Hand: Rechte Hand:
Kleiner Finger: Q A Y 1 Kleiner Finger: P Ö Ä Ü 0 ß
Ringfinger: W S X 2 Ringfinger: O L . 9
Mittelfinger: E D C 3 Mittelfinger: I K , 8
Zeigefinger: R F V T G B 4 5 Zeigefinger: U J M Z H N 6 7
Daumen: Leertaste Daumen: Leertaste
```
---
## 9. Gemini-Integration
### 9.1 API-Endpoints
```
Text Generation:
POST https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key={API_KEY}
Image Generation (Nano Banana 2, mit Character Consistency):
POST https://generativelanguage.googleapis.com/v1beta/models/gemini-3.1-flash-image-preview:generateContent?key={API_KEY}
→ Config: response_modalities: ["IMAGE"]
```
**Empfehlung**: `gemini-3.1-flash-image-preview` (Nano Banana 2, neuestes Modell, seit Feb. 2026) für alle Bildgenerierung verwenden. Unterstützt Character Consistency via Referenzbilder, 1K/2K/4K Auflösung. Ältere Imagen-Modelle werden am 24. Juni 2026 abgeschaltet.
**Wichtig**: Die Modellnamen und Endpoints entwickeln sich schnell. Bei der Implementierung die aktuelle Gemini-API-Dokumentation prüfen: https://ai.google.dev/gemini-api/docs/image-generation
### 9.2 Prompt-Templates
#### Begleitfigur — Begrüssung (beim Öffnen der App)
```
System: Du bist {figurName}, ein(e) {figurBeschreibung} im Zauberwald.
Du sprichst mit einem 7-jährigen Kind, das Tippen lernt.
Regeln:
- Max. 2 kurze Sätze (insgesamt max. 25 Wörter)
- Einfache Sprache, kurze Wörter
- Freundlich und warm, nie belehrend
- Keine Bewertung von Leistung
- Kein Englisch
- Beziehe dich auf die Tageszeit: {tageszeit}
Schreib eine Begrüssung.
```
#### Begleitfigur — Character Sheet (einmalig beim Onboarding)
```
Character sheet for a children's book. The character is {figurName},
{figurVisualDescription}.
Show the character in 3 views: front view, side view, and a close-up
of the face. All views must show the EXACT SAME character with identical
colors, proportions, and features.
Art style: Watercolor children's book illustration, warm pastel colors,
soft edges, magical forest theme. White background.
Label each view clearly: "FRONT" "SIDE" "FACE"
The character must be: cute, friendly, approachable, with large expressive
eyes. Suitable for a 7-year-old audience.
```
**Figur-Beschreibungen für den Prompt:**
| Figur | figurVisualDescription |
|-------|----------------------|
| Fee Lila | a small fairy with lavender-purple wings, a flowing lilac dress, big warm brown eyes, a tiny flower crown made of forget-me-nots, light skin, and short wavy auburn hair |
| Einhorn Stella | a small unicorn with a white coat, a shimmering golden horn, a flowing mane in soft rainbow pastels (pink, lavender, light blue), big dark eyes with long lashes, and small silver hooves |
| Fuchs Finn | a young red fox with warm orange-brown fur, a white chest and belly, a bushy tail with a white tip, bright curious amber eyes, and slightly oversized pointed ears |
| Eule Elsa | a small round owl with soft brown-and-cream feathers, a heart-shaped face, large round golden eyes, tiny ear tufts, and small talons perched on a mossy branch |
#### Begleitfigur — Avatar-Portrait (einmalig beim Onboarding)
```
[Character Sheet als Referenzbild]
Create a single portrait of this exact character from the reference sheet.
Show only the face and upper body, looking directly at the viewer with a
warm, friendly expression. Same art style as the reference.
Square format. No text. No background (or simple soft gradient).
```
#### Begleitfigur — Waldbelohnung kommentieren
```
System: Du bist {figurName}, ein(e) {figurBeschreibung} im Zauberwald.
Ein Kind hat gerade eine Tippübung abgeschlossen. Im Wald ist ein neues Wesen
erschienen: {elementBeschreibung}.
Regeln:
- Max. 2 kurze Sätze (insgesamt max. 25 Wörter)
- Drücke Staunen und Freude aus
- Einfache Sprache für 7-Jährige
- Kein Lob für Leistung, sondern Begeisterung über das neue Waldelement
- Kein Englisch
Kommentiere das neue Element.
```
#### Begleitfigur — Buchstabe vorstellen
```
System: Du bist {figurName}, ein(e) {figurBeschreibung} im Zauberwald.
Du stellst einem 7-jährigen Kind den Buchstaben {buchstabe} vor.
Regeln:
- Max. 2 Sätze (max. 25 Wörter)
- Erkläre, welcher Finger den Buchstaben drückt: {fingerBeschreibung}
- Verwende eine bildhafte Eselsbrücke, die zum Wald/Natur/Tiere-Thema passt
- Einfache Sprache
- Kein Englisch
```
#### Waldbelohnung — Bild generieren
**API-Call-Struktur mit Referenzbildern:**
```
POST /v1beta/models/gemini-3.1-flash-image-preview:generateContent
Contents:
1. [Stil-Referenzbild aus IndexedDB] — "This is the art style reference. Match this exact visual style."
2. [Character Sheet aus IndexedDB, falls Begleitfigur im Bild] — "This is the companion character. Maintain exact appearance."
3. Text-Prompt (siehe unten)
Config:
response_modalities: ["IMAGE"]
image_config: { aspect_ratio: "16:9" }
```
**Text-Prompt:**
```
Watercolor children's book illustration in the exact same art style as the
reference image. A {elementTyp} in a magical forest clearing. Warm pastel
colors, soft edges, dreamy atmosphere. No text, no letters, no words anywhere
in the image. The creature/element should have a distinctive, memorable
appearance.
Specific details: {spezifischeBeschreibung}
```
**Element-Beschreibung wird zufällig generiert**, z.B.:
- "ein kleines Reh mit goldbraunem Fell und auffällig grossen, dunklen Augen"
- "ein leuchtend blauer Schmetterling mit schimmernden Flügeln"
- "ein Pilz mit rotem Hut und weissen Punkten, umgeben von Moos"
Diese Beschreibung wird zusammen mit dem Bild in IndexedDB gespeichert (`forestElements.description`), damit das Element auch im Text konsistent referenziert werden kann.
**Hinweis zu Gemini-Modellen**: Die API und Modellnamen entwickeln sich schnell. Bei Implementierung die aktuelle Dokumentation prüfen. `gemini-3.1-flash-image-preview` (Nano Banana 2) ist das neueste Bildgenerierungsmodell (Stand März 2026) und unterstützt Character Consistency mit bis zu 14 Referenzbildern pro Request.
Element-Typen rotieren und werden zufällig aus einem Pool gewählt:
- Tiere: Reh, Fuchs, Hase, Eichhörnchen, Igel, Schmetterling, Vogel, Frosch, Eule, Biene, Marienkäfer, Schnecke
- Fantasie: Einhorn, Feenpilz, leuchtender Schmetterling, sprechende Blume, Mondfalter
- Pflanzen: Blume, Pilz, alter Baum, Moos, Farn, blühender Busch
- Landschaft: Bach, kleiner Wasserfall, Regenbogen, Glühwürmchen, Sternschnuppe, Mondlicht
### 9.3 Fehlerbehandlung
- API-Timeout oder Fehler: Fallback auf einen Pool von **510 vorbereiteten statischen Bildern** (SVG oder eingebettete PNGs) und vorbereiteten Texten
- Langsame Generierung: Bild wird im Hintergrund generiert, während sie tippt. Wenn es bei der Belohnung noch nicht fertig ist, zeigt ein sanftes "Der Wald denkt nach..."-Placeholder (animierte Blätter o.ä.)
- Rate-Limiting: Max. 1 Bild-Request + 1 Text-Request pro Übungseinheit
### 9.4 Pre-Generation-Strategie
Um Wartezeiten zu vermeiden:
1. Beim Start der Übungseinheit: Text-Request für Belohnung starten (geht schnell)
2. Während Phase 2 (Üben): Bild-Request starten
3. Bei Einheitende: Bild und Text sollten fertig sein
4. Falls nicht: Sanft warten mit Placeholder
---
## 10. Audio-Konzept
### 10.1 Sound-Effekte (lokal, kein API-Call)
- **Richtiger Tastendruck**: Sanfter, kurzer Ton (Glockenspiel-artig, ~0.2s)
- **Belohnung**: Aufsteigende Melodie (Harfe/Windspiel, ~1.5s)
- **Neues Waldelement erscheint**: Magischer Glitzer-Sound (~1s)
- **App-Start**: Leise Waldgeräusche (Vögel, Wind, Bach)
Alle Sounds: sanft, nicht laut, nicht erschreckend. Keine "Game-Over"-Sounds. Kein "Falsch"-Sound.
### 10.2 Begleitfigur-Sprache (optional, KI-generiert)
- Gemini TTS oder Web Speech API als Fallback
- Die Sprechblase zeigt den Text immer auch geschrieben an (sie lernt ja gerade lesen)
- Audio ist optional und kann im Elternbereich deaktiviert werden
- Stimme: Warm, freundlich, Deutsch, nicht zu schnell
---
## 11. Elternbereich
### Zugang
- Tastenkombination: z.B. `Ctrl+Shift+E` oder ein verstecktes Zahnrad-Icon in der Ecke
- Kein komplexes Passwort — ein einfacher 4-stelliger Code (Standard: 1234, änderbar)
- Soll nicht einladend für das Kind sein, aber auch nicht verstörend wenn sie es findet
### Inhalte
1. **Übersicht**
- Aktuelle Stufe
- Anzahl abgeschlossener Einheiten
- An welchen Tagen wurde geübt (Kalender-Dots)
- Durchschnittliche Genauigkeit (intern gemessen) — NUR hier angezeigt
- Häufigste Fehlertasten — NUR hier angezeigt
2. **Einstellungen**
- Tastatur-Layout wechseln
- Audio an/aus
- Begleitfigur wechseln
- API-Key eingeben/ändern
3. **Daten**
- Export: Fortschritt als JSON herunterladen
- Import: JSON hochladen (mit Bestätigung)
- Zurücksetzen: Alles löschen (mit doppelter Bestätigung)
---
## 12. MVP-Scope
Der MVP umfasst alle 4 Phasen der Roadmap (Abschnitt 16). Nach Phase 4 ist die App bereit zum Testen mit dem Kind.
**Explizit NICHT im MVP** (können als spätere Milestones ergänzt werden):
- Stufen 715 (untere Reihe, Grossbuchstaben, Zahlen, Sonderzeichen)
- Ganze Sätze tippen
- "Freies Schreiben"-Modus (Brief an die Begleitfigur)
- Saisonale Wald-Themen
- Begleitfigur reagiert auf längere Abwesenheit
- Druckbare Urkunden
- Mobile Support
---
## 13. Projektstruktur (verbindlich)
```
zauberwald/
├── index.html
├── vite.config.ts
├── tsconfig.json
├── biome.json
├── package.json
├── .gitignore ← Enthält: public/config.json, node_modules, dist
├── public/
│ └── config.json ← API-Key (NICHT in Git! Wird von Vite als statische Datei serviert)
├── src/
│ ├── main.ts ← Entry point
│ ├── app.ts ← Screen management, routing
│ ├── types.ts ← Gemeinsame Type-Definitionen
│ ├── game/
│ │ ├── levels.ts ← Stufendefinitionen, Tastenzuordnungen
│ │ ├── typing.ts ← Kern-Tippmechanik
│ │ ├── keyboard.ts ← Bildschirmtastatur-Rendering
│ │ └── words.ts ← Wortlisten (Fallbacks) + Wort-Generierung
│ ├── forest/
│ │ ├── scene.ts ← Waldszene rendern
│ │ └── elements.ts ← Waldelemente verwalten
│ ├── companion/
│ │ ├── characters.ts ← Figur-Definitionen + SVGs
│ │ └── dialogue.ts ← Gemini-Textgenerierung
│ ├── api/
│ │ ├── gemini.ts ← Gemini API Client (Text + Bild)
│ │ ├── gemini-image.ts ← Bildgenerierung mit Referenzbild-Management
│ │ └── config.ts ← Config-Loader (fetch('/config.json'))
│ ├── storage/
│ │ ├── db.ts ← IndexedDB Wrapper
│ │ ├── assets.ts ← Character Sheet, Avatar, Stil-Referenz verwalten
│ │ └── export.ts ← Export/Import-Logik
│ ├── ui/
│ │ ├── screens.ts ← Screen-Komponenten
│ │ └── animations.ts ← Animationshelfer
│ ├── styles/
│ │ └── main.css
│ └── assets/
│ ├── companions/ ← Vorab-generierte Character Sheets + Avatare (in Git!)
│ │ ├── fee-lila/
│ │ │ ├── character-sheet.png
│ │ │ └── avatar.png
│ │ ├── einhorn-stella/
│ │ │ ├── character-sheet.png
│ │ │ └── avatar.png
│ │ ├── fuchs-finn/
│ │ │ ├── character-sheet.png
│ │ │ └── avatar.png
│ │ └── eule-elsa/
│ │ ├── character-sheet.png
│ │ └── avatar.png
│ ├── style-reference/ ← Vorab-generierte Stil-Referenz (in Git!)
│ │ └── initial-forest-scene.png
│ └── fallback-images/ ← Statische Fallback-Bilder (SVG, in Git!)
├── scripts/
│ └── generate-assets.ts ← Script zum (Re-)Generieren der statischen Assets (via tsx)
└── README.md
```
---
## 14. Entwicklung mit Gemini-API
### 14.1 API-Key-Setup für die Entwicklung
Der Gemini-API-Key wird über `config.json` im Projektroot bereitgestellt:
```json
{
"geminiApiKey": "AIza...",
"geminiModel": "gemini-2.5-flash",
"imageModel": "gemini-3.1-flash-image-preview"
}
```
Diese Datei ist im `.gitignore` eingetragen. Claude Code liest den Key daraus und verwendet ihn sowohl für das Asset-Generierungs-Script als auch zum Testen der laufenden App.
### 14.2 Vorab-Generierung der Character Assets
**Ziel**: Alle 4 Begleitfiguren werden während der Entwicklung generiert, visuell geprüft und als statische Assets eingecheckt. So gibt es beim Onboarding keine Wartezeit.
**Ablauf:**
1. Claude Code erstellt ein Script `scripts/generate-assets.js` das:
- Die `config.json` liest
- Für jede der 4 Figuren ein Character Sheet generiert (Gemini Image API)
- Für jede Figur ein Avatar-Portrait generiert (mit dem Character Sheet als Referenz)
- Eine initiale Waldszene als Stil-Referenz generiert
- Alle Bilder nach `src/assets/companions/{figur}/` und `src/assets/style-reference/` speichert
2. Claude Code führt das Script aus und prüft die Ergebnisse
3. Falls ein Ergebnis nicht zufriedenstellend ist (z.B. Figur sieht nicht kindgerecht aus, Stil ist inkonsistent), wird das Script mit angepassten Prompts erneut ausgeführt
4. Die finalen Assets werden in Git eingecheckt
### 14.3 Testen der vollständigen Pipeline
Claude Code soll während der Entwicklung die gesamte Generierungs-Pipeline E2E testen:
**Test 1: Text-Generierung**
- Begrüssungstext generieren für jede Figur + jede Tageszeit
- Prüfen: Wortanzahl ≤ 25? Deutsch? Kein Leistungslob?
- Buchstaben-Vorstellungstext generieren für Buchstaben F, J, D, K
- Waldbelohnungs-Kommentar generieren für verschiedene Elemente
**Test 2: Bild-Generierung mit Konsistenz**
- Ein Waldelement generieren MIT Stil-Referenzbild → Prüfen ob Stil konsistent
- Ein zweites Waldelement generieren MIT demselben Stil-Referenzbild → Vergleichen
- Ein Bild generieren das die Begleitfigur enthält MIT Character Sheet als Referenz → Prüfen ob Figur wiedererkennbar
**Test 3: Caching**
- Bild generieren → in IndexedDB speichern → Browser neu laden → Prüfen ob Bild korrekt geladen wird
- Character Sheet aus `src/assets/` laden → Prüfen ob es als Referenzbild an die API gesendet werden kann
**Test 4: Fehlerbehandlung**
- API-Call mit ungültigem Key → Prüfen ob Fallback-Assets angezeigt werden
- API-Call simuliert Timeout → Prüfen ob Placeholder-UI erscheint
### 14.4 Anpassung des Onboarding-Flows
Da die Character Sheets jetzt als statische Assets vorliegen, vereinfacht sich der Onboarding-Flow:
```
1. Willkommen (nur beim allerersten Start)
├── Begleitfigur wählen
├── Tastatur-Layout wählen (DE/CH)
└── "Los geht's" → SOFORT zur ersten Übung
(Kein Lade-Screen mehr nötig — Character Sheet + Avatar
werden aus src/assets/ geladen, nicht generiert)
Beim ersten Abschluss einer Übungseinheit:
└── Erstes Waldelement wird generiert (Gemini Image, ~5 Sek.)
→ Wird gleichzeitig als Stil-Referenz gecacht
(Fallback: Vorab-generierte Stil-Referenz aus src/assets/)
```
---
## 15. Design-Entscheidungen (alle geschlossen)
Alle Entscheidungen sind getroffen. Diese Liste dient der Dokumentation:
| Entscheidung | Gewählt | Begründung |
|---|---|---|
| Framework | Vanilla TypeScript | Minimale Komplexität, kein Framework-Overhead |
| Waldszene-Rendering | DOM-basiert (`<img>` über SVG-Hintergrund) | Einfachste Lösung, generierte Bilder sind PNGs |
| Bild-Platzierung | Raster 4×3 mit ±20px Zufallsvariation | Vorhersehbar, kein Overlap |
| Adaptives Tempo | Heuristik: ±200/500ms, Bereich 1.54s | Einfach, keine ML-Logik nötig |
| Gemini-Modell (Bild) | gemini-3.1-flash-image-preview (Nano Banana 2) | Neuestes Modell, Character Consistency, 1K4K |
| Gemini-Modell (Text) | gemini-2.5-flash | Stabil, günstig, schnell |
| Audio-TTS | Web Speech API (Browser-nativ) | Gratis, offline-fähig, kein API-Call |
| Elternbereich-Zugang | Ctrl+Shift+E öffnet Overlay, Code "1234" | Einfach, kein Over-Engineering |
| Character-Assets | Vorab generiert via Build-Script, eingecheckt | Kein Onboarding-Warten, volle Kontrolle |
---
## 16. Phasen-Roadmap (für gsd)
Jede Phase hat klare Akzeptanzkriterien. Die Phase gilt als abgeschlossen, wenn ALLE Kriterien erfüllt sind.
### Phase 1: Grundgerüst + Tippmechanik (ohne Gemini)
**Ziel**: Eine spielbare Tipp-Übung im Browser, die ohne API funktioniert.
**Tasks:**
1. Vite-Projekt initialisieren: `npm create vite@latest . -- --template vanilla-ts`, Biome konfigurieren, Vitest einrichten
2. Projektstruktur gemäss Abschnitt 13 anlegen (alle Verzeichnisse + leere Dateien)
3. `src/types.ts` erstellen mit allen Interfaces (Progress, ForestElement, CompanionAssets, Level, etc.)
4. IndexedDB-Wrapper (`src/storage/db.ts`) implementieren mit allen Stores gemäss Abschnitt 6.3
5. Screen-Management (`src/app.ts`): 5 Screens (welcome, forest, lesson, reward, parent), nur einer sichtbar, Transitions mit CSS fade
6. Willkommens-Screen: Figur-Auswahl (4 Karten mit Platzhalter-Emojis 🧚 🦄 🦊 🦉), Layout-Auswahl (DE/CH), "Los geht's" Button. Auswahl in IndexedDB speichern.
7. Bildschirmtastatur rendern (`src/game/keyboard.ts`): Vollständiges QWERTZ-Layout, Farbzonen gemäss Abschnitt 8.3 + Farbpalette, aktive Taste pulsiert, gedrückte Taste animiert. Beide Layouts (DE/CH) als Daten hinterlegen.
8. Level-Definitionen (`src/game/levels.ts`): Stufen 16 gemäss Abschnitt 4.1, inklusive Finger-Zuordnung und Beispiel-Wörter
9. Kern-Tippmechanik (`src/game/typing.ts`): keydown-Listener, prüft ob richtiger Buchstabe, ignoriert falschen Tastendruck (kein Feedback), markiert richtige Taste auf Tastatur. Adaptives Tempo gemäss Heuristik.
10. Phase "Üben" implementieren: Buchstaben erscheinen einzeln (CSS-Animation von oben nach unten), 10 Buchstaben pro Übung, Progress-Dots am unteren Rand
11. CSS: Komplette Farbpalette + Typografie gemäss Abschnitt 7.2, responsive bis 700px Breite
12. Wald-Übersicht: Stufenkarte (Level-Grid mit Karten: Nummer, Tasten, Status locked/current/completed)
**Akzeptanzkriterien:**
- [ ] `npm run dev` startet die App und ist via `http://<vps-ip>:5173` von aussen erreichbar
- [ ] Willkommens-Screen: Figur + Layout wählbar, Auswahl persistiert nach Reload
- [ ] Tastatur rendert korrekt für DE und CH Layout
- [ ] Stufe 1 (F, J, Leertaste) ist spielbar: Buchstaben erscheinen, richtiger Tastendruck löst sie auf
- [ ] Falscher Tastendruck: Kein sichtbares Feedback, App wartet geduldig
- [ ] Nach 10 richtigen Buchstaben: Übung gilt als abgeschlossen
- [ ] Wald-Übersicht zeigt Stufe 1 als "current", Rest als "locked"
- [ ] Nach Abschluss: Stufe 2 wird "current"
- [ ] `npm run test` läuft (Vitest, mindestens Tests für Level-Definitionen und Typing-Logik)
- [ ] Keine TypeScript-Fehler (`npx tsc --noEmit`)
- [ ] Biome lint ohne Fehler
### Phase 2: Gemini-Integration + Asset-Pipeline
**Ziel**: Gemini-API funktioniert für Text und Bild, Character Sheets sind generiert und eingebunden.
**Tasks:**
1. `src/api/config.ts`: `config.json` laden via fetch, typisiertes Config-Interface, Fehlerbehandlung wenn Datei fehlt
2. `src/api/gemini.ts`: Typisierter API-Client für Text-Generierung. Methode: `generateText(prompt: string, systemPrompt?: string): Promise<string>`. Fehlerbehandlung, Retry (1×), Logging.
3. `src/api/gemini-image.ts`: Typisierter API-Client für Bild-Generierung. Methode: `generateImage(prompt: string, referenceImages?: Blob[]): Promise<Blob>`. Character Consistency via Referenzbilder. Fehlerbehandlung.
4. API-Call-Logger: Jeder Call wird gezählt und geloggt (Typ, Timestamp). In IndexedDB speichern für Elternbereich.
5. `scripts/generate-assets.ts`: Node-Script (tsx), liest `config.json`, generiert:
- 4 Character Sheets (alle Figuren, Prompts aus Abschnitt 9.2)
- 4 Avatar-Portraits
- 1 Stil-Referenz-Waldszene ("Empty magical forest clearing, watercolor children's book illustration...")
- Speichert als PNG in `src/assets/generated/{figur}-character-sheet.png`, `{figur}-avatar.png`, `style-reference.png`
- Script kann wiederholt ausgeführt werden (überschreibt vorherige)
6. `package.json` Script: `"generate-assets": "npx tsx scripts/generate-assets.ts"`
7. Character-Assets in die App einbinden: Willkommens-Screen zeigt echte Avatare statt Emojis, Companion-Area zeigt Avatar
8. Begleitfigur-Textgenerierung (`src/companion/dialogue.ts`): Methoden für Begrüssung, Buchstaben-Vorstellung, Wald-Kommentar. Alle Prompt-Templates aus Abschnitt 9.2 umsetzen. Fallback: Statische Texte wenn API nicht verfügbar.
9. Fallback-Pool: 10 statische Begrüssungen, 10 Wald-Kommentare, Buchstaben-Vorstellungen für Stufe 16 als hardcoded Strings
**Akzeptanzkriterien:**
- [ ] `npm run generate-assets` generiert alle Bilder erfolgreich in `src/assets/generated/`
- [ ] Character Sheets zeigen erkennbar verschiedene Figuren im konsistenten Aquarell-Stil
- [ ] Willkommens-Screen zeigt echte generierte Avatare
- [ ] Companion-Area in der Übung zeigt den Avatar der gewählten Figur
- [ ] Text-API-Call funktioniert: Begrüssung wird generiert, ist deutsch, ≤25 Wörter
- [ ] Bild-API-Call funktioniert: Ein Waldelement kann mit Stil-Referenz generiert werden
- [ ] Bei fehlendem API-Key: Fallback-Texte werden angezeigt, kein Crash
### Phase 3: Komplettes Spielerlebnis
**Ziel**: Alle 3 Übungsphasen verbunden, Wald wächst visuell, Stufen 16 spielbar.
**Tasks:**
1. Phase "Entdecken" implementieren: Begleitfigur stellt neuen Buchstaben vor (Gemini-Text oder Fallback), Bildschirmtastatur hebt die Taste hervor, animierte Demo welcher Finger
2. Phase "Wörter bauen" implementieren: 34 Wörter pro Übung, Wort-Display (Buchstabe für Buchstabe ausfüllen), Wörter aus `src/game/words.ts` (hardcoded pro Stufe, nur mit gelernten Buchstaben)
3. Alle 3 Phasen verbinden: Entdecken → Üben → Wörter → Belohnung. Fliessender Übergang, Companion-Sprechblase aktualisiert sich.
4. Belohnungs-Screen: Neues Waldelement generieren (Gemini Image mit Stil-Referenz), Begleitfigur kommentiert (Gemini Text). "Weiter üben" / "Zurück zum Wald" Buttons.
5. Waldszene rendern: SVG-Hintergrund (statische Landschaft: Himmel, Hügel, Gras), darüber 4×3 Grid für generierte Bilder. Bilder laden aus IndexedDB. Neue Bilder mit fade-in Animation.
6. Review-Mechanik: Jede 3. Übungseinheit mischt Buchstaben der letzten 23 Stufen
7. Stufen 26 implementieren: Wortlisten erweitern, Buchstaben-Vorstellungstexte ergänzen
8. Perfektionismus-Loop-Handling: Nach 2× Wiederholung derselben Stufe zeigt die Begleitfigur Ermutigung + Neugier-Trigger ("Magst du sehen, was als Nächstes im Wald kommt?")
9. Pre-Generation: Während Phase "Üben" wird im Hintergrund das Belohnungs-Bild generiert. Bei Timeout: Placeholder ("Der Wald überlegt...") mit animierten CSS-Blättern.
10. Elternbereich: Overlay-Screen, Zugang via Ctrl+Shift+E + Code "1234". Zeigt: aktuelle Stufe, abgeschlossene Einheiten, Übungstage (Kalender-Dots), Layout-Wechsel, Audio an/aus, Fortschritt-Reset (mit doppelter Bestätigung).
**Akzeptanzkriterien:**
- [ ] Komplette Übungseinheit spielbar: Entdecken → Üben → Wörter → Belohnung → zurück zum Wald
- [ ] Nach Belohnung: Neues Bild erscheint im Wald, bleibt nach Reload
- [ ] Stufen 16 alle spielbar, jede mit passenden Wörtern
- [ ] Review-Einheiten kommen alle 3 Übungen
- [ ] Waldszene zeigt alle bisherigen Elemente
- [ ] Elternbereich erreichbar und zeigt Fortschrittsdaten
- [ ] Wiederholungs-Ermutigung erscheint nach 2× gleicher Stufe
- [ ] Pre-Generation: Kein sichtbares Warten auf Bild (oder sanfter Placeholder)
### Phase 4: Polish + Audio
**Ziel**: Visuell und auditiv angenehmes Erlebnis, bereit zum Testen mit dem Kind.
**Tasks:**
1. Animationen: Fallende Buchstaben als CSS-Animation (sanftes Schweben, wie Blätter), Erfolg-Animation (Sternenstaub/Glitzer via CSS particles), Neues Waldelement (scale-up + fade-in), Begleitfigur-Avatar (float-Animation)
2. Audio: Web Audio API — 3 Sounds als generierte Sinuswellen (kein Datei-Download nötig): Richtiger Tastendruck (kurzer heller Ton, 800Hz, 0.1s), Belohnung (aufsteigende Tonfolge, 0.8s), Neues Waldelement (Glitzer-Sound, weisses Rauschen gefiltert, 0.5s). Mute-Button immer sichtbar.
3. Optionale Sprachausgabe: Web Speech API `speechSynthesis` für Companion-Texte. Deutsch, Rate 0.9, Pitch 1.1 (kindgerecht). Deaktivierbar im Elternbereich.
4. Responsive Anpassungen: Tastatur verkleinert sich unter 700px Breite, Fonts skalieren
5. Ladezeiten optimieren: Bilder in IndexedDB lazy laden, nur sichtbare Waldelemente rendern
6. Globaler Error-Handler: `window.onerror` fängt unbehandelte Fehler, zeigt kindgerechte Meldung ("Oh, der Wald braucht kurz eine Pause"), kein Crash
7. Export/Import im Elternbereich: JSON-Download (ohne Bild-Blobs), JSON-Upload mit Validierung
**Akzeptanzkriterien:**
- [ ] Tastendruck-Sound spielt bei richtigem Buchstaben
- [ ] Belohnungs-Sound spielt nach Übungsabschluss
- [ ] Mute-Button funktioniert, Zustand persistiert
- [ ] Buchstaben fallen sanft (keine ruckartigen Animationen)
- [ ] Erfolg-Animation sichtbar (Glitzer/Sternenstaub)
- [ ] Sprachausgabe liest Companion-Text vor (wenn aktiviert)
- [ ] Export/Import funktioniert: Exportieren → Browser-Daten löschen → Importieren → Fortschritt wiederhergestellt
- [ ] Keine unbehandelten Exceptions in der Console bei normalem Gebrauch