// === CHINESE STUDY MODE === class ChineseStudyGame { constructor(options) { this.container = options.container; this.content = options.content; this.onScoreUpdate = options.onScoreUpdate || (() => {}); this.onGameEnd = options.onGameEnd || (() => {}); // Game state this.vocabulary = []; this.currentMode = null; this.currentIndex = 0; this.score = 0; this.correctAnswers = 0; this.isRunning = false; this.studyState = 'menu'; // 'menu', 'playing', 'review' // Extract vocabulary this.vocabulary = this.extractVocabulary(this.content); this.init(); } init() { // Check if we have enough vocabulary if (!this.vocabulary || this.vocabulary.length === 0) { logSh('No Chinese vocabulary found for Chinese Study Game', 'ERROR'); this.showInitError(); return; } this.createGameInterface(); } showInitError() { this.container.innerHTML = `

❌ Error loading

This content doesn't have Chinese vocabulary for the Chinese Study Game.

The game needs vocabulary with Chinese characters, translations, and optional pinyin.

`; this.addStyles(); } extractVocabulary(content) { let vocabulary = []; logSh('🔍 Extracting Chinese vocabulary from:', content?.name || 'content', 'INFO'); // Priority 1: Use raw module content (simple format) if (content.rawContent) { logSh('📦 Using raw module content', 'INFO'); return this.extractVocabularyFromRaw(content.rawContent); } // Priority 2: Ultra-modular format (vocabulary object) - ONLY format supported if (content.vocabulary && typeof content.vocabulary === 'object' && !Array.isArray(content.vocabulary)) { logSh('✨ Ultra-modular format detected (vocabulary object)', 'INFO'); vocabulary = Object.entries(content.vocabulary).map(([word, data]) => { // Support ultra-modular format ONLY if (typeof data === 'object' && data.user_language) { return { chinese: word, // Clé = caractère chinois translation: data.user_language.split(';')[0], // First translation fullTranslation: data.user_language, // Complete translation pronunciation: data.pronunciation || '', // Pinyin type: data.type || 'general', hskLevel: data.hskLevel || null, examples: data.examples || [], strokeOrder: data.strokeOrder || [] }; } // Legacy fallback - simple string (temporary, will be removed) else if (typeof data === 'string') { return { chinese: word, translation: data.split(';')[0], fullTranslation: data, pronunciation: '', type: 'general', hskLevel: null }; } return null; }).filter(Boolean); } // No other formats supported - ultra-modular only return this.finalizeVocabulary(vocabulary); } extractVocabularyFromRaw(rawContent) { logSh('🔧 Extracting from raw content:', rawContent.name || 'Module', 'INFO'); let vocabulary = []; // Extract from vocabulary object in raw content if (rawContent.vocabulary && typeof rawContent.vocabulary === 'object') { vocabulary = Object.entries(rawContent.vocabulary).map(([word, data]) => { if (typeof data === 'object' && data.user_language) { return { chinese: word, translation: data.user_language.split(';')[0], fullTranslation: data.user_language, pronunciation: data.pronunciation || '', type: data.type || 'general', hskLevel: data.hskLevel || null, examples: data.examples || [], strokeOrder: data.strokeOrder || [] }; } else if (typeof data === 'string') { return { chinese: word, translation: data.split(';')[0], fullTranslation: data, pronunciation: '', type: 'general', hskLevel: null }; } return null; }).filter(Boolean); } return vocabulary; } finalizeVocabulary(vocabulary) { if (vocabulary.length === 0) { logSh('⚠️ No valid vocabulary found', 'WARNING'); return []; } // Shuffle vocabulary vocabulary = vocabulary.sort(() => Math.random() - 0.5); logSh(`✅ Vocabulary extraction complete: ${vocabulary.length} items`, 'INFO'); return vocabulary; } createGameInterface() { if (this.studyState === 'menu') { this.createModeSelection(); } else if (this.studyState === 'playing') { this.createStudyMode(); } this.addStyles(); } createModeSelection() { const hasPinyin = this.vocabulary.some(item => item.pronunciation); const hasHSK = this.vocabulary.some(item => item.hskLevel); this.container.innerHTML = `

🇨🇳 Chinese Study Mode

Score: ${this.score}
${this.vocabulary.length} characters available
${hasHSK ? '
📊 HSK levels included
' : ''} ${hasPinyin ? '
🗣️ Pinyin available
' : ''}
📚

Flashcards

Study characters with flip cards

🧠

Character Recognition

Match characters to their meanings

${!hasPinyin ? '
Requires pinyin data
' : ''}
🗣️

Pinyin Practice

Learn pronunciation with pinyin

${!hasPinyin ? '
Requires pinyin data
' : ''}
📊

HSK Review

Study by HSK difficulty levels

${!hasHSK ? '
Requires HSK level data
' : ''}

📖 Vocabulary Preview

${this.vocabulary.slice(0, 6).map(item => `
${item.chinese} ${item.translation} ${item.pronunciation ? `${item.pronunciation}` : ''} ${item.hskLevel ? `${item.hskLevel}` : ''}
`).join('')} ${this.vocabulary.length > 6 ? `
... and ${this.vocabulary.length - 6} more
` : ''}
`; this.setupModeListeners(); } createStudyMode() { const currentItem = this.vocabulary[this.currentIndex]; const progress = Math.round(((this.currentIndex + 1) / this.vocabulary.length) * 100); let modeContent = ''; switch (this.currentMode) { case 'flashcards': modeContent = this.createFlashcardMode(currentItem); break; case 'recognition': modeContent = this.createRecognitionMode(currentItem); break; case 'pinyin': modeContent = this.createPinyinMode(currentItem); break; case 'hsk': modeContent = this.createHSKMode(currentItem); break; } this.container.innerHTML = `

${this.getModeTitle()}

${this.currentIndex + 1} / ${this.vocabulary.length}
Score: ${this.score}
${modeContent}
`; this.setupStudyListeners(); } setupModeListeners() { const modeCards = this.container.querySelectorAll('.mode-card:not([data-disabled])'); modeCards.forEach(card => { card.addEventListener('click', (e) => { const mode = card.dataset.mode; this.startMode(mode); }); }); } setupStudyListeners() { // Bind this context to methods for onclick handlers window.chineseStudyInstance = this; // Override global onclick handlers this.container.querySelector('.back-to-menu-btn').onclick = () => this.backToMenu(); this.container.querySelector('.prev-btn').onclick = () => this.previousItem(); this.container.querySelector('.next-btn').onclick = () => this.nextItem(); // Setup mode-specific listeners this.setupModeSpecificListeners(); } setupModeSpecificListeners() { if (this.currentMode === 'flashcards') { const flashcard = this.container.querySelector('.flashcard'); if (flashcard) { flashcard.addEventListener('click', () => this.flipCard()); } } else if (this.currentMode === 'recognition') { const options = this.container.querySelectorAll('.option-btn'); options.forEach(option => { option.addEventListener('click', (e) => this.selectOption(e.target.dataset.translation)); }); } else if (this.currentMode === 'pinyin') { const pinyinInput = this.container.querySelector('.pinyin-input'); if (pinyinInput) { pinyinInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') this.checkPinyinAnswer(); }); } const checkBtn = this.container.querySelector('.check-pinyin-btn'); if (checkBtn) { checkBtn.onclick = () => this.checkPinyinAnswer(); } } } startMode(mode) { this.currentMode = mode; this.studyState = 'playing'; this.currentIndex = 0; this.correctAnswers = 0; this.createGameInterface(); } backToMenu() { this.studyState = 'menu'; this.currentMode = null; this.createGameInterface(); } getModeTitle() { const titles = { flashcards: '📚 Flashcards', recognition: '🧠 Character Recognition', pinyin: '🗣️ Pinyin Practice', hsk: '📊 HSK Review' }; return titles[this.currentMode] || 'Chinese Study'; } createFlashcardMode(item) { return `
${item.chinese}
Click to reveal translation
${item.translation}
${item.pronunciation ? `
${item.pronunciation}
` : ''} ${item.type ? `
${item.type}
` : ''} ${item.hskLevel ? `
${item.hskLevel}
` : ''}
`; } createRecognitionMode(item) { // Create wrong options const wrongOptions = this.vocabulary .filter(v => v.chinese !== item.chinese) .sort(() => Math.random() - 0.5) .slice(0, 3) .map(v => v.translation); const allOptions = [...wrongOptions, item.translation].sort(() => Math.random() - 0.5); return `
${item.chinese}
${item.pronunciation ? `
${item.pronunciation}
` : ''}
What does this character mean?
${allOptions.map(option => ` `).join('')}
`; } createPinyinMode(item) { return `
${item.chinese}
${item.translation}
${item.pronunciation ? `` : ''}
`; } createHSKMode(item) { const hskInfo = item.hskLevel || 'No HSK level'; return `
${hskInfo}
Chinese Character Study
${item.chinese}
${item.translation}
${item.pronunciation ? `
${item.pronunciation}
` : ''} ${item.type ? `
Type: ${item.type}
` : ''} ${item.examples && item.examples.length > 0 ? `
Examples:
${item.examples.slice(0, 2).map(ex => `
${ex}
`).join('')}
` : ''}
`; } // Navigation methods nextItem() { if (this.currentIndex < this.vocabulary.length - 1) { this.currentIndex++; this.createStudyMode(); } } previousItem() { if (this.currentIndex > 0) { this.currentIndex--; this.createStudyMode(); } } // Flashcard methods flipCard() { const flashcard = this.container.querySelector('.flashcard'); const isFlipped = flashcard.dataset.flipped === 'true'; flashcard.dataset.flipped = (!isFlipped).toString(); } markAsKnown(known) { const points = known ? 10 : 5; this.score += points; this.correctAnswers += known ? 1 : 0; this.onScoreUpdate(this.score); this.updateScoreDisplay(); // Auto-advance after a short delay setTimeout(() => { if (this.currentIndex < this.vocabulary.length - 1) { this.nextItem(); } else { this.endStudySession(); } }, 1000); } // Recognition mode methods selectOption(selectedTranslation) { const currentItem = this.vocabulary[this.currentIndex]; const isCorrect = selectedTranslation === currentItem.translation; const feedback = this.container.querySelector('.result-feedback'); if (isCorrect) { this.score += 15; this.correctAnswers++; feedback.innerHTML = '✅ Correct! Well done!'; feedback.className = 'result-feedback correct'; } else { this.score = Math.max(0, this.score - 5); feedback.innerHTML = `❌ Incorrect. The correct answer is: ${currentItem.translation}`; feedback.className = 'result-feedback incorrect'; } feedback.style.display = 'block'; this.onScoreUpdate(this.score); this.updateScoreDisplay(); // Disable all option buttons const options = this.container.querySelectorAll('.option-btn'); options.forEach(btn => btn.disabled = true); // Auto-advance after a delay setTimeout(() => { if (this.currentIndex < this.vocabulary.length - 1) { this.nextItem(); } else { this.endStudySession(); } }, 2000); } // Pinyin mode methods checkPinyinAnswer() { const input = this.container.querySelector('.pinyin-input'); const userAnswer = input.value.trim().toLowerCase(); const currentItem = this.vocabulary[this.currentIndex]; const correctPinyin = currentItem.pronunciation ? currentItem.pronunciation.toLowerCase() : ''; const feedback = this.container.querySelector('.pinyin-feedback'); const correctAnswer = this.container.querySelector('.correct-answer'); if (correctPinyin && this.normalizePinyin(userAnswer) === this.normalizePinyin(correctPinyin)) { this.score += 20; this.correctAnswers++; feedback.innerHTML = '🎉 Excellent pronunciation!'; feedback.className = 'pinyin-feedback correct'; } else { this.score = Math.max(0, this.score - 3); feedback.innerHTML = '🤔 Not quite right. Try again or see the correct answer below.'; feedback.className = 'pinyin-feedback incorrect'; if (correctAnswer) correctAnswer.style.display = 'block'; } feedback.style.display = 'block'; input.disabled = true; this.container.querySelector('.check-pinyin-btn').disabled = true; this.onScoreUpdate(this.score); this.updateScoreDisplay(); // Auto-advance after a delay setTimeout(() => { if (this.currentIndex < this.vocabulary.length - 1) { this.nextItem(); } else { this.endStudySession(); } }, 3000); } normalizePinyin(pinyin) { // Remove tone marks and accents for easier comparison return pinyin.replace(/[āáǎàēéěèīíǐìōóǒòūúǔùüǖǘǚǜ]/g, (match) => { const toneMap = { 'ā': 'a', 'á': 'a', 'ǎ': 'a', 'à': 'a', 'ē': 'e', 'é': 'e', 'ě': 'e', 'è': 'e', 'ī': 'i', 'í': 'i', 'ǐ': 'i', 'ì': 'i', 'ō': 'o', 'ó': 'o', 'ǒ': 'o', 'ò': 'o', 'ū': 'u', 'ú': 'u', 'ǔ': 'u', 'ù': 'u', 'ü': 'u', 'ǖ': 'u', 'ǘ': 'u', 'ǚ': 'u', 'ǜ': 'u' }; return toneMap[match] || match; }).replace(/\s+/g, ''); } // HSK mode methods markDifficulty(difficulty) { const points = { 'easy': 5, 'medium': 8, 'hard': 12 }; this.score += points[difficulty]; this.correctAnswers++; this.onScoreUpdate(this.score); this.updateScoreDisplay(); // Visual feedback const buttons = this.container.querySelectorAll('.difficulty-btn'); buttons.forEach(btn => btn.disabled = true); const selectedBtn = this.container.querySelector(`.difficulty-btn.${difficulty}`); selectedBtn.style.backgroundColor = '#10b981'; selectedBtn.style.color = 'white'; // Auto-advance after a delay setTimeout(() => { if (this.currentIndex < this.vocabulary.length - 1) { this.nextItem(); } else { this.endStudySession(); } }, 1500); } updateScoreDisplay() { const scoreElement = this.container.querySelector('#score'); if (scoreElement) { scoreElement.textContent = this.score; } } endStudySession() { const accuracy = Math.round((this.correctAnswers / this.vocabulary.length) * 100); this.container.innerHTML = `

🎓 Study Session Complete!

${this.score}
Final Score
${this.correctAnswers}/${this.vocabulary.length}
Correct
${accuracy}%
Accuracy
${accuracy >= 80 ? '🌟 Excellent work! You\'ve mastered these characters!' : accuracy >= 60 ? '👍 Good job! Keep practicing to improve further.' : '💪 Nice effort! More practice will help you improve.'}
`; this.addStyles(); // Trigger game end callback this.onGameEnd({ score: this.score, accuracy: accuracy, mode: this.currentMode, totalItems: this.vocabulary.length, correctAnswers: this.correctAnswers }); } addStyles() { const style = document.createElement('style'); style.textContent = ` .chinese-study-container { max-width: 1000px; margin: 0 auto; padding: 20px; font-family: 'Arial', sans-serif; } .game-header { text-align: center; margin-bottom: 30px; border-bottom: 2px solid #e5e7eb; padding-bottom: 20px; } .game-header h2 { color: #dc2626; font-size: 2.2em; margin-bottom: 15px; } .game-stats { display: flex; justify-content: center; gap: 20px; flex-wrap: wrap; margin-top: 10px; } .score-display, .vocab-count, .hsk-indicator, .pinyin-indicator { font-size: 1em; padding: 5px 12px; border-radius: 20px; font-weight: bold; } .score-display { background: #10b981; color: white; } .vocab-count { background: #3b82f6; color: white; } .hsk-indicator, .pinyin-indicator { background: #f59e0b; color: white; font-size: 0.9em; } .study-modes { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 20px; margin-bottom: 30px; } .mode-card { background: linear-gradient(135deg, #fff 0%, #f8fafc 100%); border: 2px solid #e5e7eb; border-radius: 16px; padding: 24px; text-align: center; cursor: pointer; transition: all 0.3s ease; box-shadow: 0 2px 8px rgba(0,0,0,0.1); position: relative; } .mode-card:not([data-disabled]):hover { border-color: #dc2626; transform: translateY(-4px); box-shadow: 0 8px 20px rgba(220, 38, 38, 0.15); } .mode-card[data-disabled="true"] { opacity: 0.6; cursor: not-allowed; background: #f9fafb; } .mode-requirement { background: #fee2e2; color: #dc2626; padding: 4px 8px; border-radius: 12px; font-size: 0.8em; margin-bottom: 10px; } .mode-icon { font-size: 3em; margin-bottom: 12px; } .mode-card h3 { color: #374151; margin-bottom: 8px; font-size: 1.3em; } .mode-card p { color: #6b7280; margin-bottom: 16px; line-height: 1.5; } .mode-btn { background: #dc2626; color: white; border: none; padding: 10px 20px; border-radius: 8px; cursor: pointer; font-weight: bold; transition: background 0.3s ease; } .mode-btn:hover:not(:disabled) { background: #b91c1c; } .mode-btn:disabled { background: #9ca3af; cursor: not-allowed; } .vocabulary-preview { background: #f8fafc; border: 1px solid #e5e7eb; border-radius: 12px; padding: 20px; margin-bottom: 30px; } .vocabulary-preview h4 { color: #374151; margin-bottom: 15px; text-align: center; } .preview-items { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 10px; } .preview-item { background: white; border: 1px solid #e5e7eb; border-radius: 8px; padding: 10px; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 4px; } .preview-item .chinese { font-size: 1.4em; font-weight: bold; color: #dc2626; } .preview-item .translation { color: #374151; font-size: 0.9em; } .preview-item .pinyin { color: #6b7280; font-size: 0.8em; font-style: italic; } .preview-item .hsk-badge { background: #f59e0b; color: white; padding: 2px 6px; border-radius: 10px; font-size: 0.7em; font-weight: bold; } .more-items { grid-column: 1/-1; text-align: center; color: #6b7280; font-style: italic; padding: 10px; } /* Study Mode Styles */ .study-mode-active { max-width: 800px; } .study-header { background: linear-gradient(135deg, #dc2626 0%, #b91c1c 100%); color: white; border-radius: 12px; padding: 20px; margin-bottom: 30px; } .mode-title { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; } .mode-title h2 { margin: 0; font-size: 1.8em; } .back-to-menu-btn { background: rgba(255,255,255,0.2); color: white; border: 1px solid rgba(255,255,255,0.3); padding: 8px 16px; border-radius: 6px; cursor: pointer; transition: background 0.3s ease; } .back-to-menu-btn:hover { background: rgba(255,255,255,0.3); } .progress-section { display: flex; align-items: center; gap: 15px; flex-wrap: wrap; } .progress-bar { flex: 1; min-width: 200px; height: 8px; background: rgba(255,255,255,0.3); border-radius: 4px; overflow: hidden; } .progress-fill { height: 100%; background: white; transition: width 0.3s ease; } .progress-text { font-weight: bold; min-width: 60px; } .study-content { background: white; border: 1px solid #e5e7eb; border-radius: 12px; padding: 30px; margin-bottom: 20px; min-height: 300px; display: flex; align-items: center; justify-content: center; } /* Flashcard Styles */ .flashcard-container { width: 100%; max-width: 400px; text-align: center; } .flashcard { width: 100%; height: 250px; position: relative; transform-style: preserve-3d; transition: transform 0.6s; cursor: pointer; margin-bottom: 20px; } .flashcard[data-flipped="true"] { transform: rotateY(180deg); } .flashcard-front, .flashcard-back { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; border: 2px solid #e5e7eb; border-radius: 12px; display: flex; flex-direction: column; justify-content: center; align-items: center; padding: 20px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); } .flashcard-back { transform: rotateY(180deg); background: #f8fafc; } .chinese-character { font-size: 4em; font-weight: bold; color: #dc2626; margin-bottom: 10px; } .card-hint { color: #6b7280; font-style: italic; } .translation { font-size: 1.5em; color: #374151; margin-bottom: 10px; } .pronunciation { color: #6b7280; font-style: italic; margin-bottom: 8px; } .word-type, .hsk-level { background: #e5e7eb; color: #374151; padding: 4px 8px; border-radius: 12px; font-size: 0.8em; margin-bottom: 4px; } .hsk-level { background: #f59e0b; color: white; } .flashcard-actions { display: flex; gap: 15px; justify-content: center; } .know-btn, .dont-know-btn { padding: 12px 24px; border: none; border-radius: 8px; font-weight: bold; cursor: pointer; transition: all 0.3s ease; } .know-btn { background: #10b981; color: white; } .know-btn:hover { background: #059669; } .dont-know-btn { background: #f59e0b; color: white; } .dont-know-btn:hover { background: #d97706; } /* Recognition Mode Styles */ .recognition-container { width: 100%; text-align: center; } .question-section { margin-bottom: 30px; } .pronunciation-hint { color: #6b7280; font-style: italic; margin-bottom: 15px; } .question-text { font-size: 1.2em; color: #374151; margin-bottom: 20px; } .options-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 15px; margin-bottom: 20px; } .option-btn { background: #f8fafc; border: 2px solid #e5e7eb; border-radius: 8px; padding: 15px; cursor: pointer; font-size: 1em; transition: all 0.3s ease; } .option-btn:hover:not(:disabled) { border-color: #dc2626; background: #fef2f2; } .option-btn:disabled { cursor: not-allowed; opacity: 0.6; } .result-feedback { padding: 15px; border-radius: 8px; font-weight: bold; margin-bottom: 15px; } .result-feedback.correct { background: #d1fae5; color: #065f46; border: 1px solid #10b981; } .result-feedback.incorrect { background: #fee2e2; color: #991b1b; border: 1px solid #ef4444; } /* Pinyin Mode Styles */ .pinyin-container { width: 100%; text-align: center; } .character-section { margin-bottom: 30px; } .translation-hint { font-size: 1.2em; color: #6b7280; margin-top: 10px; } .pinyin-exercise { margin-bottom: 20px; } .pinyin-label { display: block; font-weight: bold; color: #374151; margin-bottom: 10px; } .pinyin-input { padding: 12px; border: 2px solid #e5e7eb; border-radius: 8px; font-size: 1.1em; width: 250px; max-width: 100%; margin-bottom: 15px; margin-right: 10px; } .pinyin-input:focus { outline: none; border-color: #dc2626; } .check-pinyin-btn { background: #dc2626; color: white; border: none; padding: 12px 20px; border-radius: 8px; cursor: pointer; font-weight: bold; } .check-pinyin-btn:hover:not(:disabled) { background: #b91c1c; } .check-pinyin-btn:disabled { background: #9ca3af; cursor: not-allowed; } .pinyin-feedback { padding: 15px; border-radius: 8px; font-weight: bold; margin-bottom: 15px; } .pinyin-feedback.correct { background: #d1fae5; color: #065f46; border: 1px solid #10b981; } .pinyin-feedback.incorrect { background: #fee2e2; color: #991b1b; border: 1px solid #ef4444; } .correct-answer { background: #f0f9ff; color: #0c4a6e; border: 1px solid #3b82f6; padding: 10px; border-radius: 8px; font-weight: bold; } /* HSK Mode Styles */ .hsk-container { width: 100%; text-align: center; } .hsk-header { margin-bottom: 30px; } .hsk-level-badge { background: #f59e0b; color: white; padding: 8px 16px; border-radius: 20px; font-weight: bold; display: inline-block; margin-bottom: 10px; } .character-difficulty { color: #6b7280; font-size: 1em; } .character-study { margin-bottom: 30px; } .character-details { background: #f8fafc; border-radius: 8px; padding: 20px; margin-top: 15px; } .character-details .translation { font-size: 1.3em; margin-bottom: 10px; } .character-details .word-type { background: #e5e7eb; color: #374151; padding: 4px 12px; border-radius: 12px; font-size: 0.9em; display: inline-block; margin-bottom: 15px; } .examples { text-align: left; margin-top: 15px; } .examples h5 { color: #374151; margin-bottom: 8px; text-align: center; } .example { background: white; border: 1px solid #e5e7eb; border-radius: 6px; padding: 8px; margin-bottom: 5px; color: #6b7280; } .hsk-actions { display: flex; gap: 15px; justify-content: center; flex-wrap: wrap; } .difficulty-btn { padding: 12px 20px; border: 2px solid #e5e7eb; border-radius: 8px; background: white; cursor: pointer; font-weight: bold; transition: all 0.3s ease; min-width: 100px; } .difficulty-btn.easy { border-color: #10b981; color: #10b981; } .difficulty-btn.easy:hover:not(:disabled) { background: #10b981; color: white; } .difficulty-btn.medium { border-color: #f59e0b; color: #f59e0b; } .difficulty-btn.medium:hover:not(:disabled) { background: #f59e0b; color: white; } .difficulty-btn.hard { border-color: #ef4444; color: #ef4444; } .difficulty-btn.hard:hover:not(:disabled) { background: #ef4444; color: white; } .difficulty-btn:disabled { cursor: not-allowed; opacity: 0.7; } /* Study Controls */ .study-controls { display: flex; justify-content: space-between; gap: 15px; } .prev-btn, .next-btn { background: #6b7280; color: white; border: none; padding: 12px 24px; border-radius: 8px; cursor: pointer; font-weight: bold; transition: background 0.3s ease; flex: 1; max-width: 150px; } .prev-btn:hover:not(:disabled), .next-btn:hover:not(:disabled) { background: #4b5563; } .prev-btn:disabled, .next-btn:disabled { background: #9ca3af; cursor: not-allowed; } /* Study Complete Styles */ .study-complete { text-align: center; padding: 40px 20px; } .study-complete h2 { color: #dc2626; font-size: 2.5em; margin-bottom: 30px; } .final-stats { display: flex; justify-content: center; gap: 30px; margin-bottom: 30px; flex-wrap: wrap; } .stat-item { background: #f8fafc; border: 1px solid #e5e7eb; border-radius: 12px; padding: 20px; min-width: 120px; } .stat-value { font-size: 2em; font-weight: bold; color: #dc2626; margin-bottom: 5px; } .stat-label { color: #6b7280; font-size: 0.9em; } .completion-message { background: #f0f9ff; border: 1px solid #3b82f6; border-radius: 12px; padding: 20px; color: #1e40af; font-size: 1.1em; font-weight: bold; margin-bottom: 30px; } .final-actions { display: flex; gap: 15px; justify-content: center; flex-wrap: wrap; } .restart-btn, .menu-btn, .back-btn { padding: 12px 24px; border: none; border-radius: 8px; cursor: pointer; font-weight: bold; transition: background 0.3s ease; font-size: 1em; } .restart-btn { background: #10b981; color: white; } .restart-btn:hover { background: #059669; } .menu-btn { background: #3b82f6; color: white; } .menu-btn:hover { background: #2563eb; } .back-btn { background: #6b7280; color: white; } .back-btn:hover { background: #4b5563; } .game-controls { text-align: center; } .game-error { text-align: center; padding: 40px 20px; background: #fee2e2; border: 1px solid #ef4444; border-radius: 12px; } .game-error h3 { color: #991b1b; margin-bottom: 15px; } .game-error p { color: #7f1d1d; margin-bottom: 10px; } @media (max-width: 768px) { .chinese-study-container { padding: 15px; } .game-header h2 { font-size: 1.8em; } .study-modes { grid-template-columns: 1fr; } .preview-items { grid-template-columns: 1fr; } .game-stats { flex-direction: column; align-items: center; gap: 10px; } .chinese-character { font-size: 3em; } .flashcard { height: 200px; } .options-grid { grid-template-columns: 1fr; } .final-stats { flex-direction: column; align-items: center; gap: 15px; } .final-actions { flex-direction: column; align-items: center; } .hsk-actions { flex-direction: column; align-items: center; } .study-controls { flex-direction: column; } .prev-btn, .next-btn { max-width: none; } .mode-title { flex-direction: column; gap: 10px; text-align: center; } .progress-section { flex-direction: column; gap: 10px; } } `; document.head.appendChild(style); } start() { this.isRunning = true; logSh('Chinese Study Mode initialized with ultra-modular format', 'INFO'); } destroy() { this.isRunning = false; // Clean up global references if (window.chineseStudyInstance === this) { delete window.chineseStudyInstance; } logSh('Chinese Study Mode destroyed', 'INFO'); } restart() { this.score = 0; this.correctAnswers = 0; this.currentIndex = 0; this.studyState = 'menu'; this.currentMode = null; this.onScoreUpdate(this.score); // Re-shuffle vocabulary this.vocabulary = this.vocabulary.sort(() => Math.random() - 0.5); this.createGameInterface(); logSh('Chinese Study Mode restarted', 'INFO'); } } // Export to global scope window.GameModules = window.GameModules || {}; window.GameModules.ChineseStudy = ChineseStudyGame;