// === LETTER DISCOVERY GAME === // Discover letters first, then explore words that start with each letter class LetterDiscovery { constructor({ container, content, onScoreUpdate, onGameEnd }) { this.container = container; this.content = content; this.onScoreUpdate = onScoreUpdate; this.onGameEnd = onGameEnd; // Game state this.currentPhase = 'letter-discovery'; // letter-discovery, word-exploration, practice this.currentLetterIndex = 0; this.discoveredLetters = []; this.currentLetter = null; this.currentWordIndex = 0; this.discoveredWords = []; this.score = 0; this.lives = 3; // Content processing this.letters = []; this.letterWords = {}; // Map letter -> words starting with that letter // Practice system this.practiceLevel = 1; this.practiceRound = 0; this.maxPracticeRounds = 8; this.practiceCorrectAnswers = 0; this.practiceErrors = 0; this.currentPracticeItems = []; this.injectCSS(); this.extractContent(); this.init(); } injectCSS() { if (document.getElementById('letter-discovery-styles')) return; const styleSheet = document.createElement('style'); styleSheet.id = 'letter-discovery-styles'; styleSheet.textContent = ` .letter-discovery-wrapper { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; padding: 20px; position: relative; overflow-y: auto; } .letter-discovery-hud { display: flex; justify-content: space-between; align-items: center; background: rgba(255,255,255,0.1); padding: 15px 20px; border-radius: 15px; backdrop-filter: blur(10px); margin-bottom: 20px; flex-wrap: wrap; gap: 10px; } .hud-group { display: flex; align-items: center; gap: 15px; } .hud-item { color: white; font-weight: bold; font-size: 1.1em; } .phase-indicator { background: rgba(255,255,255,0.2); padding: 8px 16px; border-radius: 20px; font-size: 0.9em; color: white; backdrop-filter: blur(5px); } .letter-discovery-main { background: rgba(255,255,255,0.1); border-radius: 20px; padding: 30px; backdrop-filter: blur(10px); min-height: 70vh; display: flex; flex-direction: column; align-items: center; justify-content: center; } .game-content { width: 100%; max-width: 900px; text-align: center; } /* Letter Display Styles */ .letter-card { background: rgba(255,255,255,0.95); border-radius: 25px; padding: 60px 40px; margin: 30px auto; max-width: 400px; box-shadow: 0 20px 40px rgba(0,0,0,0.1); transform: scale(0.8); animation: letterAppear 0.8s ease-out forwards; } @keyframes letterAppear { to { transform: scale(1); } } .letter-display { font-size: 8em; font-weight: bold; color: #667eea; margin-bottom: 20px; text-shadow: 0 4px 8px rgba(0,0,0,0.1); font-family: 'Arial Black', Arial, sans-serif; } .letter-info { font-size: 1.5em; color: #333; margin-bottom: 15px; } .letter-pronunciation { font-size: 1.2em; color: #666; font-style: italic; margin-bottom: 25px; } .letter-controls { display: flex; gap: 15px; justify-content: center; margin-top: 30px; } /* Word Exploration Styles */ .word-exploration-header { background: rgba(255,255,255,0.1); padding: 20px; border-radius: 15px; margin-bottom: 30px; backdrop-filter: blur(5px); } .exploring-letter { font-size: 3em; color: white; margin-bottom: 10px; font-weight: bold; } .word-progress { color: rgba(255,255,255,0.8); font-size: 1.1em; } .word-card { background: rgba(255,255,255,0.95); border-radius: 20px; padding: 40px 30px; margin: 25px auto; max-width: 500px; box-shadow: 0 15px 30px rgba(0,0,0,0.1); transform: translateY(20px); animation: wordSlideIn 0.6s ease-out forwards; } @keyframes wordSlideIn { to { transform: translateY(0); } } .word-text { font-size: 2.5em; color: #667eea; margin-bottom: 15px; font-weight: bold; } .word-translation { font-size: 1.3em; color: #333; margin-bottom: 10px; } .word-pronunciation { font-size: 1.1em; color: #666; font-style: italic; } /* Practice Challenge Styles */ .practice-challenge { text-align: center; margin-bottom: 30px; } .challenge-text { font-size: 1.8em; color: white; margin-bottom: 25px; text-shadow: 0 2px 4px rgba(0,0,0,0.3); } .practice-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; max-width: 800px; margin: 0 auto; } .practice-option { background: rgba(255,255,255,0.9); border: none; border-radius: 15px; padding: 20px; font-size: 1.2em; cursor: pointer; transition: all 0.3s ease; color: #333; font-weight: 500; } .practice-option:hover { background: rgba(255,255,255,1); transform: translateY(-3px); box-shadow: 0 8px 20px rgba(0,0,0,0.2); } .practice-option.correct { background: #4CAF50; color: white; animation: correctPulse 0.6s ease; } .practice-option.incorrect { background: #F44336; color: white; animation: incorrectShake 0.6s ease; } @keyframes correctPulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.05); } } @keyframes incorrectShake { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-5px); } 75% { transform: translateX(5px); } } .practice-stats { display: flex; justify-content: space-around; margin-top: 20px; color: white; font-size: 1.1em; } .stat-item { text-align: center; padding: 10px; background: rgba(255,255,255,0.1); border-radius: 10px; backdrop-filter: blur(5px); } /* Control Buttons */ .discovery-btn { background: linear-gradient(45deg, #667eea, #764ba2); color: white; border: none; padding: 15px 30px; border-radius: 25px; font-size: 1.1em; font-weight: bold; cursor: pointer; transition: all 0.3s ease; margin: 0 10px; } .discovery-btn:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(0,0,0,0.3); } .discovery-btn:active { transform: translateY(0); } .audio-btn { background: none; border: none; font-size: 2em; cursor: pointer; color: #667eea; margin-left: 15px; transition: all 0.3s ease; } .audio-btn:hover { transform: scale(1.2); color: #764ba2; } /* Completion Message */ .completion-message { text-align: center; padding: 40px; background: rgba(255,255,255,0.1); border-radius: 20px; backdrop-filter: blur(10px); color: white; } .completion-title { font-size: 2.5em; margin-bottom: 20px; color: #00ff88; text-shadow: 0 2px 10px rgba(0,255,136,0.3); } .completion-stats { font-size: 1.3em; margin-bottom: 30px; line-height: 1.6; } /* Responsive Design */ @media (max-width: 768px) { .letter-discovery-wrapper { padding: 15px; } .letter-display { font-size: 6em; } .word-text { font-size: 2em; } .challenge-text { font-size: 1.5em; } .practice-grid { grid-template-columns: 1fr; } } `; document.head.appendChild(styleSheet); } extractContent() { logSh('🔍 Letter Discovery - Extracting content...', 'INFO'); // Check if content has letter structure if (this.content.letters) { this.letters = Object.keys(this.content.letters); this.letterWords = this.content.letters; logSh(`📝 Found ${this.letters.length} letters with words`, 'INFO'); } else { // Fallback: Create letter structure from vocabulary this.generateLetterStructure(); } if (this.letters.length === 0) { throw new Error('No letters found in content'); } logSh(`🎯 Letter Discovery ready: ${this.letters.length} letters`, 'INFO'); } generateLetterStructure() { logSh('🔧 Generating letter structure from vocabulary...', 'INFO'); const letterMap = {}; if (this.content.vocabulary) { Object.keys(this.content.vocabulary).forEach(word => { const firstLetter = word.charAt(0).toUpperCase(); if (!letterMap[firstLetter]) { letterMap[firstLetter] = []; } const wordData = this.content.vocabulary[word]; letterMap[firstLetter].push({ word: word, translation: typeof wordData === 'string' ? wordData : wordData.translation || wordData.user_language, pronunciation: wordData.pronunciation || wordData.prononciation, type: wordData.type, image: wordData.image, audioFile: wordData.audioFile }); }); } this.letters = Object.keys(letterMap).sort(); this.letterWords = letterMap; logSh(`📝 Generated ${this.letters.length} letters from vocabulary`, 'INFO'); } init() { this.container.innerHTML = `