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

49 KiB
Raw Permalink Blame History

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

{
  "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:
    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:
    {
      "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):

{
  "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

/* 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:

{
  "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