Nihongo Challenge N3 90%

.restart-btn background: #e6d5b3; color: #5e3a22; border: none; margin-top: 1rem; padding: 0.7rem; border-radius: 40px; font-weight: 600; width: 100%; cursor: pointer; font-family: inherit; transition: 0.1s;

.result-screen text-align: center; padding: 1.5rem;

const feedbackMsg = "✨ 正しいと思う答えをタップしてください ✨";

/* stats panel */ .stats-panel display: flex; justify-content: space-between; background: #f3efdf; padding: 0.9rem 2rem; border-bottom: 1px solid #e7dbb8; font-weight: 600; color: #5a3e2b; nihongo challenge n3

// エスケープ処理 (XSS対策) function escapeHtml(str) return str.replace(/[&<>]/g, function(m) if (m === '&') return '&'; if (m === '<') return '<'; if (m === '>') return '>'; return m; ).replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, function(c) return c; );

// 通常レンダリング (初期表示、回答前) function renderCurrentQuestion() if (currentIndex >= currentQuestions.length) // クイズ終了: 結果画面を表示 showResultScreen(); return;

footer font-size: 0.7rem; text-align: center; padding: 1rem; background: #f9f3e2; color: #8b765a; .restart-btn background: #e6d5b3

.option-btn background: #ffffff; border: 2px solid #eeddaa; border-radius: 60px; padding: 1rem 1.2rem; font-size: 1rem; font-weight: 500; text-align: left; display: flex; align-items: center; gap: 1rem; transition: all 0.2s; cursor: pointer; color: #2e241f; font-family: inherit;

const resultHtml = ` <div class="quiz-main result-screen"> <div class="badge">🏆 クイズ完了 🏆</div> <div class="result-score">$userScore / $totalQuestions</div> <div style="font-size:1.2rem; margin-bottom: 1rem;">$percentage% 正答率</div> <p style="background:#f2ebd0; padding: 0.8rem; border-radius: 2rem;">$message</p> <button class="restart-btn" id="restartResultBtn" style="margin-top: 2rem; background:#b13e3e; color:white;">🔁 もう一度 N3チャレンジ</button> </div> `; dynamicContainer.innerHTML = resultHtml; const restartResult = document.getElementById('restartResultBtn'); if (restartResult) restartResult.addEventListener('click', () => initGame(); ); // スコアプログレス表示も維持(statsパネルは生きてる) updateProgressUI(); // 最終的に currentIndex が total と同じだが見た目維持

.score-box span, .question-counter span color: #b13e3e; font-size: 1.3rem; margin-left: 6px; font-weight: 800; .result-screen text-align: center

dynamicContainer.innerHTML = html;

answerLocked = true; selectedOptionIndex = selectedIdx; const isCorrect = (selectedIdx === correctIdx);

// ゲーム初期化 / リスタート function initGame() // 問題をシャッフルしてコピー currentQuestions = shuffleArray([...QUESTION_SET]); currentIndex = 0; userScore = 0; answerLocked = false; selectedOptionIndex = null; updateScoreUI(); updateProgressUI(); renderCurrentQuestion();