Commit Graph
65 Commits
Author SHA1 Message Date
gurix 13b8df5db0 feat(05-02): wire forest navigation handlers and fade animation
- Add saveProgress import to scene.ts
- Wire prevBtn/nextBtn onclick handlers in initForestScreen
- Persist currentForestPage to IndexedDB on every navigation
- Add fade-out/fade-in opacity transition on page changes
2026-03-29 23:02:03 +02:00
gurix 348a71aa59 feat(05-01): add forest navigation DOM elements and CSS styling
- Add forest__nav container with prev/next buttons and page indicator in index.html
- Navigation placed between forest scene and level map, hidden by default
- Add .forest__nav, .forest__nav-btn, .forest__nav-text CSS classes
- 44px minimum touch targets on nav buttons, pastel BEM styling
- Buttons use Quicksand font matching app design language
2026-03-29 22:58:37 +02:00
gurix 559d57a013 feat(05-01): extend Progress type with currentForestPage, add paginated renderForestScene
- Add currentForestPage: number field to Progress interface in types.ts
- Export SLOTS_PER_PAGE = 12 constant from scene.ts
- Change renderForestScene signature to accept page: number parameter
- Slice elements by page (start/end = page * SLOTS_PER_PAGE)
- Update navigation UI (forest-nav) after rendering
- Add migrateProgress entry for currentForestPage in app.ts
- Fix Progress object literals in db.test.ts and screens.ts to include new field
2026-03-29 22:57:32 +02:00
gurix 3a71799823 test(260329-uos): update tests for 16 levels
- levels.test.ts: change length assertion to 16, add newKeys tests for levels 7-16
- levels.test.ts: add Level 16 allKeys completeness test (all QWERTZ keys)
- words.test.ts: extend all loops from 6 to 16 levels, add validateWordList test
- companion.test.ts: fix unknown-letter test to use '@' (z now has a fallback entry)
2026-03-29 22:15:24 +02:00
gurix 1d4c709fb6 feat(260329-uos): add word lists for levels 7-16 and fallback letter intros
- Add German word lists for levels 7-16 (10 words each, max 5 chars)
- All words validated against allowed keys per level
- Level 16 uses short words with period for punctuation practice
- Add 19 new fallback letter introductions (r,u,t,z,w,o,q,p,n,b,v,m,c,x,ä,ü,y,, ,.)
- Update entry count comment to 32 entries (levels 1-16)
2026-03-29 22:14:02 +02:00
gurix 374298be23 feat(260329-uos): extend levels 7-16 with full QWERTZ coverage
- Add levels 7-16 covering r,u,t,z,w,o,q,p,n,b,v,m,c,x,ä,ü,y and punctuation
- Add comma and period to fingerMap (r-mid and r-ring)
- Update keyboard.ts: add ',' and '.' to bottom row in DE and CH layouts
- Add comma and period to fingerColorMap in keyboard.ts
2026-03-29 22:12:46 +02:00
gurix 10849b3146 fix(260329-u4z): replace ae/oe/ue transliterations with proper German umlauts
- index.html: Wähle, übe, Übung, wächst, Nächstes, Übungstage, Häufigste
- src/ui/screens.ts: Nächstes, schöner, üben, Drücke, herunterfällt, Wörter, große, drückst
- src/companion/fallbacks.ts: Früh, schönsten, Schön, Glühwürmchen, wächst, nächstes, Bäumen, Stück, schön, verändert, Spürst, Hügel, große, drückst, drücken, Ö
- src/app.ts: üben, Zurück (in comments)
2026-03-29 21:45:57 +02:00
gurix cf21710e2f feat(quick-260329-u1d): add kindgerechte Erklaerung on forest screen
- Added forest__intro paragraph between title and greeting area in index.html
- Added .forest__intro CSS block with Nunito font, centered, pastel-style styling
2026-03-29 21:40:07 +02:00
gurix bbb1edb433 feat(quick-260329-tv5): show instruction text persistently in phase indicator
- setPhase("practice") now shows full instruction instead of "Ueben"
- setPhase("words") now shows full instruction instead of "Woerter"
- Removed 2500ms delay and companion text flicker in runPracticePhase
- Removed 2500ms delay and companion text flicker in runWordsPhase
2026-03-29 21:32:41 +02:00
gurix d038cc3196 feat(quick-260329-ton): replace textContent with innerHTML + renderInlineMarkdown at all AI-text insertion points
- src/app.ts: greeting text now renders inline markdown
- src/ui/screens.ts: letter intro text now renders inline markdown
- src/forest/reward.ts: forest comment now renders inline markdown
- All 3 sites use innerHTML with XSS-safe renderInlineMarkdown
2026-03-29 21:26:04 +02:00
gurix e10bdf88dc feat(quick-260329-ton): implement renderInlineMarkdown utility
- Escapes HTML special chars first (XSS safe)
- Converts **bold** to <strong>, *italic* to <em>
- Standalone asterisks with spaces are left unchanged
- Pure function, no DOM dependency
2026-03-29 21:25:03 +02:00
gurix 860d671985 test(quick-260329-ton): add failing tests for renderInlineMarkdown
- Tests cover plain text, empty string, italic, bold, mixed
- Tests cover XSS escaping and standalone asterisks
2026-03-29 21:24:47 +02:00
gurix 4cb5fa6883 feat(quick-260329-tk2): add companion instructions for practice and words phases
- Practice phase shows 'Jetzt kannst du ueben! Druecke die Taste zu dem Buchstaben, der herunterfaellt.' for 2.5s before exercise starts
- Words phase shows 'Jetzt kommen ganze Woerter! Tippe die Buchstaben nacheinander ein.' for 2.5s before exercise starts
- Both functions converted to async/await pattern matching existing discover phase
- Companion text cleared after delay before exercises begin
2026-03-29 21:19:38 +02:00
gurix 869b1e36a9 feat(quick-260329-ten): add space bar discover step in runDiscoverPhase
- Replace 'if (key === " ") continue' with a dedicated space bar step
- Shows ␣ symbol large with 'Leertaste' label underneath
- Companion text explains the symbol in child-friendly German
- Highlights and pulses the space key on the keyboard
- Child must press space bar once to confirm understanding and continue
2026-03-29 21:13:54 +02:00
gurixandClaude Opus 4.6 5f9c35db1e feat: dev shortcut Ctrl+Shift+X to wipe IndexedDB and restart
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 21:03:57 +02:00
gurixandClaude Opus 4.6 7131a3522d fix: align continue button height with mute button (bottom: 70px)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 21:00:01 +02:00
gurixandClaude Opus 4.6 486869b99b fix: sticky continue button at bottom of forest screen
- Continue button uses position: sticky bottom: 1rem so it stays visible
- Mute button moved higher (bottom: 70px) to avoid overlap
- Forest content remains scrollable

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 20:58:38 +02:00
gurix 8af1b61f4a Revert "fix: prevent scrolling — all screens fit within viewport"
This reverts commit 59c3ae681c.
2026-03-29 20:58:03 +02:00
gurixandClaude Opus 4.6 59c3ae681c fix: prevent scrolling — all screens fit within viewport
- html/body: height 100dvh, overflow hidden
- .screen--active: height 100dvh instead of min-height 100vh
- Forest/lesson/reward/welcome: flex: 1 to fill available space
- Forest scene: flex: 1 with min-height: 0 to shrink properly
- Reduced padding and font sizes for better fit
- Continue button and title: flex-shrink: 0 to stay visible

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 20:55:52 +02:00
gurixandClaude Opus 4.6 fabf9211c4 feat: add lightbox for viewing forest and reward images fullscreen
- Click any forest element or reward image to see it large
- Smooth zoom-in animation, click anywhere to close
- Hover effect on clickable images
- Works on both forest grid and reward screen

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 20:50:20 +02:00
gurixandClaude Opus 4.6 f9ae7c45eb fix: replace remaining ASCII umlauts in characters.ts and tests
- vertraeumt → verträumt, Froehlich → Fröhlich, grossmuetterlich → grossmütterlich
- Updated matching test assertions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 20:48:05 +02:00
gurixandClaude Opus 4.6 50a4e987c7 fix: replace ASCII umlauts with proper German umlauts throughout UI and prompts
- index.html: Wähle, Zurück, Übersicht, zurücksetzen, üben
- screens.ts: Üben, Wörter phase labels
- companion.ts: All Gemini prompts use proper umlauts
- fallbacks.ts: All fallback texts use proper umlauts
- parent.ts: löschen, überschreiben confirmations
- reward.ts: für, grüner, Eichhörnchen
- Tests updated to match

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 20:46:04 +02:00
gurixandClaude Opus 4.6 b453efebb4 feat(04-04): wire audio and speech into lesson, reward, forest, and app
- playCorrectSound() on correct keypress in letter and word exercises
- playRewardSound() when reward image appears
- speakText() for companion comment on reward screen
- playForestElementSound() when new forest element renders
- speakText() for companion greeting on forest screen

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 18:22:40 +02:00
gurix 52596c57b0 feat(04-01): add mute button with CSS, wire audio toggle in main.ts
- Add mute-btn element to index.html outside all screen sections
- Add .mute-btn CSS styles (fixed position, bottom-right, circular)
- Wire mute button click handler to toggle audioEnabled in Settings
- Initialize AudioContext on first user interaction (autoplay policy)
- Fix lint issues: import ordering, non-null assertion
2026-03-29 18:18:31 +02:00
gurix c19b7fedc1 feat(04-01): add audio/speech modules and speechEnabled to Settings
- Create src/audio/sounds.ts with playCorrectSound, playRewardSound, playForestElementSound
- Create src/audio/speech.ts with speakText via Web Speech API
- Add speechEnabled field to Settings interface in types.ts
- Add speechEnabled defaults in all Settings initializers (gemini.ts, parent.ts, db.test.ts)
- All sound functions check audioEnabled, speakText checks speechEnabled
- AudioContext lazy initialization for autoplay policy compliance
2026-03-29 18:16:53 +02:00
gurixandClaude Opus 4.6 7931f7ec39 feat(04-03): implement Export/Import/Reset data logic in parent area
- exportData: downloads progress+settings as zauberwald-backup.json
- importData: validates JSON structure, confirms overwrite, saves and reloads
- resetAllData: double confirmation, clears all 5 IndexedDB stores, reloads
- Buttons wired in loadParentData after code entry

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 18:16:51 +02:00
gurix f3cb948878 feat(04-02): global error handler + child-friendly error overlay
- Add error overlay HTML element in index.html before script tag
- Add window error + unhandledrejection listeners in main.ts
- Add error overlay CSS styles (fixed, z-index 9999, tree icon, reload button)
- Error message: "Oh, der Wald braucht kurz eine Pause..."
2026-03-29 18:16:34 +02:00
gurixandClaude Opus 4.6 5396dc0e62 feat(04-03): add Daten section with Export/Import/Reset buttons in parent area
- HTML section with export-btn, import-btn, reset-btn, hidden file input
- CSS styles for action buttons including danger variant for reset

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 18:15:44 +02:00
gurix 3a79379e5a feat(04-02): enhanced CSS animations + responsive layout
- Replace letter-float with leaf-fall sinusoidal sway animation
- Add stardust particles on falling-letter--dissolve via pseudo-elements
- Add companion-float animation on companion-area__avatar
- Add prefers-reduced-motion media query to disable animations
- Add responsive styles at max-width 700px (smaller keys, scaled fonts, adjusted grids)
2026-03-29 18:15:33 +02:00
gurixandClaude Opus 4.6 e41d71d403 fix(03): soft radial mask for forest elements and green background prompt
- CSS radial-gradient mask for organic blending into forest scene
- Generate with light green background instead of transparency (avoids checkerboard)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 17:59:47 +02:00
gurix aaf9872f1d feat(03-04): wire complete game flow with reward screen and review triggers
- Lesson completion now shows reward screen instead of going directly to forest
- Pre-generation starts at lesson begin (fire-and-forget)
- Stats accumulated (correct/errors/errorKeys) in progress after each lesson
- Review mode triggers every 3rd session
- Encouragement shown after 2x same level (repetition protection)
- Progress migration for older saved data without new fields
2026-03-29 13:53:23 +02:00
gurix e599050303 feat(03-04): add reward module with pre-generation and reward screen
- Create src/forest/reward.ts with startPreGeneration() and initRewardScreen()
- Image pre-generation starts at lesson begin, placeholder shows while loading
- Fallback to static SVGs when rate-limited or API unavailable
- Reward screen HTML with image area, companion comment, action buttons
- CSS for reward screen with animated leaves placeholder and image appear animation
2026-03-29 13:52:05 +02:00
gurixandClaude Opus 4.6 770f566972 feat(03-02): lesson screen 3-phase state machine with review and repetition
- Discover phase: companion introduces new key, key pulses, child presses once
- Practice phase: existing letter exercise with cumulative stats
- Words phase: word display with active letter highlighting
- Review mode skips discover, mixes letters/words from recent levels
- Encouragement messages for repetition protection
- Phase indicator UI (Entdecken / Ueben / Woerter)
- CSS for word display, phase indicator, discover pulse animation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 13:48:56 +02:00
gurix a5326c7a24 feat(03-05): wire parent area into app.ts
- Import showParentCodePrompt and initParentScreen from ui/parent
- Register global Ctrl+Shift+E keyboard listener in initApp
- Initialize parent screen with back-to-forest callback
2026-03-29 13:46:45 +02:00
gurix 44c28fe226 feat(03-05): parent area HTML, CSS, and access gate
- Add parent screen HTML with code gate, stats overview, and settings form
- Add parent area CSS styles for stats grid, calendar dots, error badges, settings
- Create src/ui/parent.ts with showParentCodePrompt, initParentScreen, loadParentData
2026-03-29 13:46:10 +02:00
gurixandClaude Opus 4.6 2c0c2f2701 feat(03-02): implement word mode for typing engine
- Add createWordExerciseState() that splits words into letters with boundaries
- Add getCurrentWordIndex() helper for UI word tracking
- Extend TypingExerciseState with mode, words, wordBoundaries fields
- Backwards compatible: createExerciseState sets mode='letters'
- All 85 tests pass

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 13:45:54 +02:00
gurixandClaude Opus 4.6 958f4460a7 test(03-02): add failing tests for word mode typing engine
- Tests for createWordExerciseState, getCurrentWordIndex
- Backwards compatibility test for createExerciseState mode field
- handleKeyPress test with word-mode state

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 13:45:18 +02:00
gurixandClaude Opus 4.6 d4207bf33d feat(03-01): extend Progress type, add LessonPhase, update rate limits
- Progress: added totalCorrect, totalErrors, errorKeyCounts, lastPlayedLevels
- New LessonPhase type: discover | practice | words
- Rate limits: 10 text / 5 image per day (was 1 each)
- Updated screens.ts with new Progress field defaults
- Updated existing tests for new rate limits and Progress shape

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 13:42:32 +02:00
gurix e1fc5eb579 feat(03-03): render forest elements from IndexedDB in grid
- renderForestScene() loads elements from IDB and renders as images
- Object URLs tracked and revoked on re-render to prevent memory leaks
- Random +-10-20px offset for natural element placement
- New element animation class applied via newElementId parameter
- Integrated into initForestScreen alongside renderLevelMap
2026-03-29 13:41:33 +02:00
gurixandClaude Opus 4.6 5a6ba70dab feat(03-01): implement word lists per level with getWordsForLevel
- Static word lists for levels 1-6, 8-10 words each
- Levels 1-2 use letter combos (no real words possible with F/J/D/K)
- Levels 3-6 mix real German words with combos
- All words validated: only use learned letters, max 5 chars
- getWordsForLevel with/without replacement sampling
- All 8 tests pass

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 13:41:20 +02:00
gurix c9abc9e6a1 feat(03-03): add SVG forest background and 4x3 grid HTML/CSS structure
- SVG woodland background with sky gradient, clouds, sun, trees, hills, ground
- 4x3 CSS grid overlay for forest element placement
- Fade-in + scale-up animation keyframes for new elements
2026-03-29 13:40:54 +02:00
gurixandClaude Opus 4.6 420c0e1a1f test(03-01): add failing tests for word lists per level
- Tests for wordsByLevel entries levels 1-6
- Tests for allKeys-only characters validation
- Tests for max 5 chars per word
- Tests for getWordsForLevel random selection

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 13:40:27 +02:00
gurixandClaude Opus 4.6 57a929bc1a feat(02-05): add companion greeting to forest and avatar to lesson screen
- Add forest-greeting companion area in HTML with avatar + text
- Add lesson-companion area in HTML above letter area
- Wire getGreeting() call for returning users in app.ts
- Show companion avatar in lesson screen via getProgress lookup
- Fix pre-existing noUncheckedIndexedAccess errors in fallbacks.ts (Rule 3)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 12:15:45 +02:00
gurixandClaude Opus 4.6 2cf7687d51 feat(02-05): add avatar images to welcome screen with emoji fallback
- Extend CompanionDefinition with avatarUrl field using Vite static imports
- Replace emoji-only companion cards with avatar img + onerror emoji fallback
- Add companion-card__avatar CSS (80px round) and companion-area styles (48px)
- Add vite-env.d.ts for PNG import type declarations

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 12:14:28 +02:00
gurixandClaude Opus 4.6 1fa7d52d94 feat(02-03): add asset generation build script and generate all character assets
- Create scripts/generate-assets.ts: reads config.json, calls Gemini API for each companion
- Generate 4 character sheets (3-view: front, side, face) for Fee Lila, Einhorn Stella, Fuchs Finn, Eule Elsa
- Generate 4 avatars using character sheets as reference images for consistency
- Generate 1 style reference (initial forest scene) for art direction
- Add tsx devDependency and npm run generate-assets script
- Fix imageModel name: gemini-3.1-flash-preview-image -> gemini-3.1-flash-image-preview
- Script handles errors gracefully, skips already-generated assets, logs progress

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 12:10:59 +02:00
gurix 4b4aa8ecd9 feat(02-04): implement companion text module with API-first fallback strategy
- getGreeting: AI greeting with time-of-day context, falls back to static texts
- getLetterIntro: AI letter introduction with finger description, falls back to curated intros
- getForestComment: AI forest element comment, falls back to static comments
- All functions check config availability and rate limits before API calls
- System prompts enforce max 25 words, simple German, no performance praise
2026-03-29 12:05:50 +02:00
gurix 6fba02cbe9 test(02-04): add failing tests for companion text module
- Tests for getGreeting, getLetterIntro, getForestComment
- Covers API success, API failure, no config, rate-limited paths
- 12 test cases total with mocked dependencies
2026-03-29 12:05:00 +02:00
gurixandClaude Opus 4.6 a242ce1570 feat(02-03): add IndexedDB accessor methods for companionAssets, styleReference, forestElements
- saveCompanionAssets/getCompanionAssets keyed by characterType
- saveStyleReference/getStyleReference singleton pattern (id: 1)
- saveForestElement (auto-increment add) / getForestElements (getAll)
- Extended type imports for CompanionAssets, CompanionType, ForestElement, StyleReference

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 12:04:48 +02:00
gurixandClaude Opus 4.6 2bea324962 feat(02-01): implement config loader and Gemini API client
- Config loader: fetches/caches public/config.json with GeminiConfig interface
- generateText: Gemini REST with 3x exponential backoff retry, returns string|null
- generateImage: reference images as base64 inlineData, responseModalities: ["IMAGE"]
- Rate limiting: checkRateLimit/incrementApiCall with daily reset in Settings store
- Extended Settings type with apiCallsToday and lastApiCallDate fields
- 18 tests across config.test.ts and gemini.test.ts, all passing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 11:56:21 +02:00
gurixandClaude Opus 4.6 66f8403b33 feat(02-02): add 7 SVG fallback images for forest elements
- blume, pilz, vogel, schmetterling, reh, baum, bach
- Pastel watercolor style with soft gradients, 200x200 viewBox
- All under 2KB, no text elements, child-friendly aesthetic

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 11:54:56 +02:00