Level 1
Zetten 0
Gevonden 0/0
Wat is 1 + 1?
Kies het goede antwoord
Welke letter begint met appel?
Level 1 • Vraag 1 / 3
Kies het goede antwoord
Level 1 • Vraag 1 / 5
Luister en kies het goede dier
Welk dier is dit?
Level 1 • Vraag 1 / 4
Tik de letters van het dier
Goed gedaan!
Op naar level 2!
Goed gedaan!
Op naar de volgende vraag!
Goed gedaan!
Goed: 0 • Fout: 0
Goed gedaan!
Op naar de volgende vraag!
Goed gedaan!
Goed: 0 • Fout: 0
Goed gedaan!
Op naar de volgende vraag!
Goed gedaan!
Goed: 0 • Fout: 0
Goed gedaan!
Ja, goed gespeld!
';
button.addEventListener('click', function () { onMemoryCard(button, card); });
board.appendChild(button);
});
applyMemoryBoardFit();
}
function buildMemoryLevel() {
state.memory.moves = 0;
state.memory.found = 0;
state.memory.open = [];
state.memory.lock = false;
state.memory.levelCompleted = false;
nextBtn.disabled = true;
if (memoryTyped) {
memoryTyped.textContent = '';
memoryTyped.classList.remove('show');
}
updateMemoryHud();
buildMemoryDeck();
renderMemoryBoard();
}
function unlockMemoryControls() {
if (state.memory.controlsUnlocked) return;
state.memory.controlsUnlocked = true;
if (state.mode === 'memory') {
memoryControls.classList.add('visible');
playArea.classList.add('controls-on');
applyMemoryBoardFit();
}
}
function onMemoryCard(element, card) {
unlockAudio();
if (state.mode !== 'memory' || state.memory.lock || card.matched || element.classList.contains('open') || element.classList.contains('match')) return;
element.classList.add('open');
state.memory.open.push({ element: element, card: card });
if (state.memory.open.length !== 2) return;
state.memory.lock = true;
const first = state.memory.open[0];
const second = state.memory.open[1];
if (first.card.key === second.card.key) {
window.setTimeout(function () {
first.card.matched = true;
second.card.matched = true;
first.element.classList.remove('open');
second.element.classList.remove('open');
first.element.classList.add('match');
second.element.classList.add('match');
state.memory.found += 1;
updateMemoryHud();
playCoinSound();
speak(first.card.label);
showMemoryTyped(first.card.label);
state.memory.open = [];
state.memory.lock = false;
applyMemoryBoardFit();
if (state.memory.found === state.memory.pairs) {
state.memory.levelCompleted = true;
if (state.memory.level === 1) unlockMemoryControls();
nextBtn.disabled = false;
playWinSound();
const nextLevel = state.memory.pairs >= ANIMALS_MASTER.length ? 1 : state.memory.level + 1;
memoryWinMsg.textContent = state.memory.pairs >= ANIMALS_MASTER.length ? 'Je hebt alles gevonden!' : 'Op naar level ' + nextLevel + '!';
window.setTimeout(function () { memoryWin.classList.add('show'); }, 500);
}
}, 260);
} else {
playWrongSound();
speak('Helaas, probeer opnieuw');
window.setTimeout(function () {
first.element.classList.remove('open');
second.element.classList.remove('open');
state.memory.open = [];
state.memory.lock = false;
}, 760);
}
}
function startMemory() {
startScreen.classList.add('hide');
showMode('memory');
buildMemoryLevel();
}
function restartMemory() {
memoryWin.classList.remove('show');
buildMemoryLevel();
}
function nextMemoryLevel() {
if (!state.memory.levelCompleted) return;
memoryWin.classList.remove('show');
if (state.memory.pairs < ANIMALS_MASTER.length) {
state.memory.level += 1;
state.memory.pairs += 1;
} else {
state.memory.level = 1;
state.memory.pairs = 2;
}
buildMemoryLevel();
}
function makeCountQuestion() {
const max = Math.min(10 + (state.count.level - 1) * 2, 20);
const a = Math.floor(Math.random() * max) + 1;
const b = Math.floor(Math.random() * max) + 1;
const answer = a + b;
const options = shuffle([answer, answer + 1, answer - 1, answer + 2, answer - 2]).filter(function (v, i, arr) {
return v > 0 && v <= 40 && arr.indexOf(v) === i;
}).slice(0, 3);
if (options.indexOf(answer) === -1) options[0] = answer;
state.count.question = { a: a, b: b, answer: answer, options: shuffle(options) };
}
function updateCountXp() {
const totalXp = state.count.totalRounds * 10;
const currentXp = state.count.correct * 10;
if (countXpFill) countXpFill.style.width = Math.min(100, (currentXp / totalXp) * 100) + '%';
if (countXpText) countXpText.textContent = 'XP: ' + currentXp + ' / ' + totalXp;
renderGameLevelBar(countLevelbar, state.count.correct, state.count.totalRounds);
}
function updateCountHud() {
const totalXp = state.count.totalRounds * 10;
const currentXp = state.count.correct * 10;
const shownQuestion = Math.min(state.count.round + 1, state.count.totalRounds);
setHud('Level', String(state.count.level), 'Vraag', shownQuestion + '/' + state.count.totalRounds, 'XP', currentXp + '/' + totalXp);
updateCountXp();
}
function renderCountQuestion() {
const q = state.count.question;
countQuestionEl.textContent = 'Wat is ' + q.a + ' + ' + q.b + '?';
countHelpEl.textContent = 'Kies het goede antwoord';
countAnswersEl.innerHTML = '';
q.options.forEach(function (value) {
const btn = document.createElement('button');
btn.type = 'button';
btn.className = 'answer-btn';
btn.dataset.value = String(value);
btn.innerHTML = '
';
btn.addEventListener('click', function () { onCountAnswer(value); });
countAnswersEl.appendChild(btn);
});
speak(countQuestionEl.textContent);
}
function startCountLevel() {
state.count.round = 0;
state.count.correct = 0;
state.count.answerLocked = false;
updateCountHud();
makeCountQuestion();
renderCountQuestion();
}
function startCounting() {
startScreen.classList.add('hide');
showMode('count');
state.count.level = 1;
startCountLevel();
}
function onCountAnswer(value) {
if (state.mode !== 'count' || state.count.answerLocked) return;
state.count.answerLocked = true;
const good = value === state.count.question.answer;
countAnswersEl.querySelectorAll('.answer-btn').forEach(function (btn) {
btn.disabled = true;
const btnValue = Number(btn.dataset.value || '0');
if (btnValue === state.count.question.answer) btn.classList.add('correct');
if (btnValue === value && value !== state.count.question.answer) btn.classList.add('wrong');
});
if (good) {
state.count.correct += 1;
playCoinSound();
speak('Ja, ' + state.count.question.answer);
countResultTitle.textContent = 'Goed gedaan!';
countResultText.textContent = 'Ja, ' + state.count.question.answer + ' is goed! Volgende vraag!';
state.count.pendingAction = 'next';
} else {
playWrongSound();
speak('Dat is fout');
countResultTitle.textContent = 'Dat is fout';
countResultText.textContent = 'Het juiste antwoord is ' + state.count.question.answer + '.';
state.count.pendingAction = 'next';
}
state.count.round += 1;
updateCountHud();
if (state.count.round >= state.count.totalRounds) {
countResultTitle.textContent = 'Level klaar!';
countResultText.textContent = 'Je had ' + state.count.correct + ' van de ' + state.count.totalRounds + ' goed. Op naar level ' + (state.count.level + 1) + '!';
state.count.pendingAction = 'levelup';
playWinSound();
}
window.setTimeout(function () { countResult.classList.add('show'); }, 320);
}
function advanceCount() {
countResult.classList.remove('show');
state.count.answerLocked = false;
if (state.count.pendingAction === 'levelup') {
state.count.level += 1;
startCountLevel();
showBubble('Level ' + state.count.level);
return;
}
makeCountQuestion();
renderCountQuestion();
}
function buildLettersSession() {
const totalQ = LETTERS_LEVELS[state.letters.level - 1] || 3;
let session = [];
while (session.length < totalQ) session = session.concat(shuffle(LETTERS_QUESTIONS));
state.letters.session = session.slice(0, totalQ);
}
function renderLettersLevelBar() {
renderGameLevelBar(lettersLevelbar, state.letters.correct, state.letters.session.length || (LETTERS_LEVELS[state.letters.level - 1] || 3));
}
function updateLettersHud() {
const totalQ = state.letters.session.length || (LETTERS_LEVELS[state.letters.level - 1] || 3);
setHud('Level', String(state.letters.level), 'Vraag', (state.letters.currentQuestion + 1) + '/' + totalQ, 'XP', state.letters.xp + '/' + (totalQ * 10));
lettersProgress.textContent = 'Goed: ' + state.letters.correct + ' / ' + totalQ;
lettersXpFill.style.width = Math.min(100, (state.letters.xp / (totalQ * 10)) * 100) + '%';
renderLettersLevelBar();
}
function renderLettersQuestion() {
const q = state.letters.session[state.letters.currentQuestion];
lettersQuestionEl.textContent = q.text;
lettersHelp.textContent = 'Kies het goede antwoord';
lettersNextBtn.classList.remove('show');
lettersAnswersEl.innerHTML = '';
q.answers.forEach(function (value, index) {
const btn = document.createElement('button');
btn.type = 'button';
btn.className = 'letters-answer-btn';
btn.dataset.index = String(index);
btn.innerHTML = '
';
btn.addEventListener('click', function () { onLettersAnswer(index, btn); });
lettersAnswersEl.appendChild(btn);
});
speak(q.text);
}
function startLettersLevel() {
state.letters.currentQuestion = 0;
state.letters.correct = 0;
state.letters.wrong = 0;
state.letters.xp = 0;
state.letters.answerLocked = false;
buildLettersSession();
updateLettersHud();
renderLettersQuestion();
}
function startLetters() {
startScreen.classList.add('hide');
showMode('letters');
if (state.letters.level < 1) state.letters.level = 1;
startLettersLevel();
}
function onLettersAnswer(index, clickedBtn) {
if (state.mode !== 'letters' || state.letters.answerLocked) return;
const q = state.letters.session[state.letters.currentQuestion];
if (index === q.correct) {
state.letters.answerLocked = true;
state.letters.correct += 1;
state.letters.xp += 10;
lettersAnswersEl.querySelectorAll('.letters-answer-btn').forEach(function (btn, btnIndex) {
btn.disabled = true;
if (btnIndex === q.correct) btn.classList.add('correct');
});
playCoinSound();
speak('Goed gedaan plus tien XP');
lettersHelp.textContent = 'Goed gedaan!';
updateLettersHud();
const nextLabel = state.letters.currentQuestion + 1 >= state.letters.session.length ? 'Op naar de level-afronding!' : 'Op naar de volgende vraag!';
if (lettersStepText) lettersStepText.textContent = nextLabel;
window.setTimeout(function () { if (lettersStepResult) lettersStepResult.classList.add('show'); }, 280);
} else {
state.letters.wrong += 1;
clickedBtn.classList.add('wrong');
playWrongSound();
speak('Probeer opnieuw');
lettersHelp.textContent = 'Probeer opnieuw';
window.setTimeout(function () { clickedBtn.classList.remove('wrong'); }, 700);
}
}
function nextLettersQuestion() {
if (!state.letters.answerLocked) return;
if (lettersStepResult) lettersStepResult.classList.remove('show');
state.letters.currentQuestion += 1;
if (state.letters.currentQuestion >= state.letters.session.length) {
lettersResultTitle.textContent = 'Goed gedaan!';
lettersResultText.textContent = 'Goed: ' + state.letters.correct + ' • Fout: ' + state.letters.wrong + '\nTotaal vragen: ' + state.letters.session.length;
lettersLevelupBtn.textContent = state.letters.level >= 10 ? 'Blijf oefenen' : 'Volgend level ▶';
lettersResult.classList.add('show');
playWinSound();
return;
}
state.letters.answerLocked = false;
updateLettersHud();
renderLettersQuestion();
}
function lettersLevelUp() {
lettersResult.classList.remove('show');
if (state.letters.level < 10) state.letters.level += 1;
startLettersLevel();
}
function retryLettersLevel() {
lettersResult.classList.remove('show');
startLettersLevel();
}
function buildSoundSession() {
const totalQ = SOUND_LEVELS[state.sound.level - 1] || 5;
let session = [];
while (session.length < totalQ) session = session.concat(shuffle(ANIMALS_MASTER));
state.sound.session = session.slice(0, totalQ);
}
function renderSoundLevelBar() {
renderGameLevelBar(soundLevelbar, state.sound.correct, state.sound.session.length || (SOUND_LEVELS[state.sound.level - 1] || 5));
}
function updateSoundHud() {
const totalQ = state.sound.session.length || (SOUND_LEVELS[state.sound.level - 1] || 5);
setHud('Level', String(state.sound.level), 'Vraag', (state.sound.currentQuestion + 1) + '/' + totalQ, 'XP', state.sound.xp + '/' + (totalQ * 10));
if (soundProgress) soundProgress.textContent = 'Goed: ' + state.sound.correct + ' / ' + totalQ;
if (soundXpFill) soundXpFill.style.width = Math.min(100, (state.sound.xp / (totalQ * 10)) * 100) + '%';
renderSoundLevelBar();
}
function playSoundPrompt() {
const q = state.sound.session[state.sound.currentQuestion];
if (!q) return;
speak(q.label);
}
function renderSoundQuestion() {
const q = state.sound.session[state.sound.currentQuestion];
if (!q) return;
if (soundQuestionEl) soundQuestionEl.textContent = 'Wat hoor je?';
if (soundHelp) soundHelp.textContent = 'Luister en kies het goede dier';
if (soundAnswersEl) soundAnswersEl.innerHTML = '';
const optionsPool = shuffle(ANIMALS_MASTER.filter(function (item) { return item.label !== q.label; })).slice(0, 3);
const options = shuffle([q].concat(optionsPool));
options.forEach(function (item) {
const btn = document.createElement('button');
btn.type = 'button';
btn.className = 'sound-answer-btn';
btn.dataset.label = item.label;
btn.innerHTML = '
';
btn.addEventListener('click', function () { onSoundAnswer(item.label, btn); });
soundAnswersEl.appendChild(btn);
});
window.setTimeout(playSoundPrompt, 180);
}
function startSoundLevel() {
state.sound.currentQuestion = 0;
state.sound.correct = 0;
state.sound.wrong = 0;
state.sound.xp = 0;
state.sound.answerLocked = false;
buildSoundSession();
updateSoundHud();
renderSoundQuestion();
}
function startSoundGame() {
startScreen.classList.add('hide');
showMode('sound');
if (state.sound.level < 1) state.sound.level = 1;
startSoundLevel();
}
function onSoundAnswer(label, clickedBtn) {
if (state.mode !== 'sound' || state.sound.answerLocked) return;
const q = state.sound.session[state.sound.currentQuestion];
if (!q) return;
if (label === q.label) {
state.sound.answerLocked = true;
state.sound.correct += 1;
state.sound.xp += 10;
soundAnswersEl.querySelectorAll('.sound-answer-btn').forEach(function (btn) {
btn.disabled = true;
if (btn.dataset.label === q.label) btn.classList.add('correct');
});
playCoinSound();
speak('Goed gedaan! Dat is ' + q.label);
if (soundHelp) soundHelp.textContent = 'Goed gedaan!';
updateSoundHud();
if (soundStepText) soundStepText.textContent = state.sound.currentQuestion + 1 >= state.sound.session.length ? 'Op naar de level-afronding!' : 'Op naar de volgende vraag!';
window.setTimeout(function () { if (soundStepResult) soundStepResult.classList.add('show'); }, 280);
} else {
state.sound.wrong += 1;
clickedBtn.classList.add('wrong');
playWrongSound();
speak('Probeer opnieuw');
if (soundHelp) soundHelp.textContent = 'Probeer opnieuw';
window.setTimeout(function () { clickedBtn.classList.remove('wrong'); }, 700);
}
}
function nextSoundQuestion() {
if (!state.sound.answerLocked) return;
if (soundStepResult) soundStepResult.classList.remove('show');
state.sound.currentQuestion += 1;
if (state.sound.currentQuestion >= state.sound.session.length) {
if (soundResultTitle) soundResultTitle.textContent = 'Goed gedaan!';
if (soundResultText) soundResultText.textContent = 'Goed: ' + state.sound.correct + ' • Fout: ' + state.sound.wrong + '\nTotaal vragen: ' + state.sound.session.length;
if (soundLevelupBtn) soundLevelupBtn.textContent = state.sound.level >= 10 ? 'Blijf oefenen' : 'Volgend level ▶';
if (soundResult) soundResult.classList.add('show');
playWinSound();
return;
}
state.sound.answerLocked = false;
updateSoundHud();
renderSoundQuestion();
}
function soundLevelUp() {
if (soundResult) soundResult.classList.remove('show');
if (state.sound.level < 10) state.sound.level += 1;
startSoundLevel();
}
function retrySoundLevel() {
if (soundResult) soundResult.classList.remove('show');
startSoundLevel();
}
function buildAnimalwordSession() {
const totalQ = ANIMALWORD_LEVELS[state.animalword.level - 1] || 4;
let session = [];
while (session.length < totalQ) session = session.concat(shuffle(ANIMALS_MASTER));
state.animalword.session = session.slice(0, totalQ);
}
function renderAnimalwordLevelBar() {
renderGameLevelBar(animalwordLevelbar, state.animalword.correct, state.animalword.session.length || (ANIMALWORD_LEVELS[state.animalword.level - 1] || 4));
}
function updateAnimalwordHud() {
const totalQ = state.animalword.session.length || (ANIMALWORD_LEVELS[state.animalword.level - 1] || 4);
setHud('Level', String(state.animalword.level), 'Vraag', (state.animalword.currentQuestion + 1) + '/' + totalQ, 'XP', state.animalword.xp + '/' + (totalQ * 10));
if (animalwordProgress) animalwordProgress.textContent = 'Goed: ' + state.animalword.correct + ' / ' + totalQ;
if (animalwordXpFill) animalwordXpFill.style.width = Math.min(100, (state.animalword.xp / (totalQ * 10)) * 100) + '%';
renderAnimalwordLevelBar();
}
function makeAnimalwordLetterPool(answer) {
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
const needed = Math.max(answer.length + 3, 8);
const pool = answer.toUpperCase().split('');
while (pool.length < needed) {
const pick = alphabet[Math.floor(Math.random() * alphabet.length)];
pool.push(pick);
}
return shuffle(pool).slice(0, needed);
}
function renderAnimalwordSlots(answer, built) {
if (!animalwordSlotsEl) return;
animalwordSlotsEl.innerHTML = '';
answer.split('').forEach(function (_, index) {
const slot = document.createElement('div');
slot.className = 'animalword-slot' + (built[index] ? ' filled' : '');
slot.textContent = built[index] || '';
animalwordSlotsEl.appendChild(slot);
});
}
function renderAnimalwordQuestion() {
const q = state.animalword.session[state.animalword.currentQuestion];
if (!q) return;
state.animalword.built = [];
state.animalword.usedIndexes = [];
state.animalword.answerLocked = false;
if (animalwordQuestionEl) animalwordQuestionEl.textContent = 'Welk dier is dit?';
if (animalwordHelp) animalwordHelp.textContent = 'Tik de letters van het dier';
if (animalwordPreviewEl) animalwordPreviewEl.innerHTML = '

';
renderAnimalwordSlots(q.label.toUpperCase(), state.animalword.built);
const pool = makeAnimalwordLetterPool(q.label);
if (animalwordLetterbankEl) animalwordLetterbankEl.innerHTML = '';
pool.forEach(function (letter, index) {
const btn = document.createElement('button');
btn.type = 'button';
btn.className = 'animalword-letter';
btn.textContent = letter;
btn.dataset.index = String(index);
btn.addEventListener('click', function () { onAnimalwordLetter(letter, btn); });
animalwordLetterbankEl.appendChild(btn);
});
speak(q.label);
}
function resetAnimalwordInput() {
if (state.animalword.answerLocked) return;
state.animalword.built = [];
animalwordLetterbankEl.querySelectorAll('.animalword-letter').forEach(function (btn) { btn.disabled = false; });
const q = state.animalword.session[state.animalword.currentQuestion];
if (q) renderAnimalwordSlots(q.label.toUpperCase(), state.animalword.built);
if (animalwordHelp) animalwordHelp.textContent = 'Tik de letters van het dier';
}
function onAnimalwordLetter(letter, btn) {
if (state.mode !== 'animalword' || state.animalword.answerLocked) return;
const q = state.animalword.session[state.animalword.currentQuestion];
if (!q) return;
state.animalword.built.push(letter);
btn.disabled = true;
renderAnimalwordSlots(q.label.toUpperCase(), state.animalword.built);
if (state.animalword.built.length < q.label.length) return;
const guess = state.animalword.built.join('').toLowerCase();
const answer = q.label.toLowerCase();
if (guess === answer) {
state.animalword.answerLocked = true;
state.animalword.correct += 1;
state.animalword.xp += 10;
playCoinSound();
speak('Ja, ' + q.label);
if (animalwordHelp) animalwordHelp.textContent = 'Goed gedaan!';
updateAnimalwordHud();
if (animalwordStepText) animalwordStepText.textContent = 'Ja, ' + q.label + ' is goed gespeld!';
window.setTimeout(function () { if (animalwordStepResult) animalwordStepResult.classList.add('show'); }, 280);
} else {
state.animalword.wrong += 1;
playWrongSound();
speak('Probeer opnieuw');
if (animalwordHelp) animalwordHelp.textContent = 'Probeer opnieuw';
window.setTimeout(function () { resetAnimalwordInput(); }, 700);
}
}
function startAnimalwordLevel() {
state.animalword.currentQuestion = 0;
state.animalword.correct = 0;
state.animalword.wrong = 0;
state.animalword.xp = 0;
state.animalword.answerLocked = false;
buildAnimalwordSession();
updateAnimalwordHud();
renderAnimalwordQuestion();
}
function startAnimalwordGame() {
startScreen.classList.add('hide');
showMode('animalword');
if (state.animalword.level < 1) state.animalword.level = 1;
startAnimalwordLevel();
}
function nextAnimalwordQuestion() {
if (!state.animalword.answerLocked) return;
if (animalwordStepResult) animalwordStepResult.classList.remove('show');
state.animalword.currentQuestion += 1;
if (state.animalword.currentQuestion >= state.animalword.session.length) {
if (animalwordResultTitle) animalwordResultTitle.textContent = 'Goed gedaan!';
if (animalwordResultText) animalwordResultText.textContent = 'Goed: ' + state.animalword.correct + ' • Fout: ' + state.animalword.wrong + '\nTotaal vragen: ' + state.animalword.session.length;
if (animalwordLevelupBtn) animalwordLevelupBtn.textContent = state.animalword.level >= 10 ? 'Blijf oefenen' : 'Volgend level ▶';
if (animalwordResult) animalwordResult.classList.add('show');
playWinSound();
return;
}
state.animalword.answerLocked = false;
updateAnimalwordHud();
renderAnimalwordQuestion();
}
function animalwordLevelUp() {
if (animalwordResult) animalwordResult.classList.remove('show');
if (state.animalword.level < 10) state.animalword.level += 1;
startAnimalwordLevel();
}
function retryAnimalwordLevel() {
if (animalwordResult) animalwordResult.classList.remove('show');
startAnimalwordLevel();
}
function goHomeMenu() {
memoryWin.classList.remove('show');
countResult.classList.remove('show');
lettersResult.classList.remove('show');
if (lettersStepResult) lettersStepResult.classList.remove('show');
if (soundResult) soundResult.classList.remove('show');
if (soundStepResult) soundStepResult.classList.remove('show');
if (animalwordResult) animalwordResult.classList.remove('show');
if (animalwordStepResult) animalwordStepResult.classList.remove('show');
bubble.classList.remove('show');
if (memoryTyped) {
memoryTyped.classList.remove('show');
memoryTyped.textContent = '';
}
if ('speechSynthesis' in window) window.speechSynthesis.cancel();
startScreen.classList.remove('hide');
showMode(null);
}
menuMemoryButton.addEventListener('click', startMemory);
menuMemoryButton.addEventListener('pointerup', startMemory);
menuTellenButton.addEventListener('click', startCounting);
menuTellenButton.addEventListener('pointerup', startCounting);
menuLettersButton.addEventListener('click', startLetters);
menuLettersButton.addEventListener('pointerup', startLetters);
menuSoundButton.addEventListener('click', startSoundGame);
menuSoundButton.addEventListener('pointerup', startSoundGame);
menuAnimalwordButton.addEventListener('click', startAnimalwordGame);
menuAnimalwordButton.addEventListener('pointerup', startAnimalwordGame);
memoryAgain.addEventListener('click', nextMemoryLevel);
nextBtn.addEventListener('click', nextMemoryLevel);
restartBtn.addEventListener('click', restartMemory);
topHomeBtn.addEventListener('click', goHomeMenu);
countNextBtn.addEventListener('click', advanceCount);
lettersNextBtn.addEventListener('click', nextLettersQuestion);
if (lettersStepNextBtn) lettersStepNextBtn.addEventListener('click', nextLettersQuestion);
lettersLevelupBtn.addEventListener('click', lettersLevelUp);
lettersRetryBtn.addEventListener('click', retryLettersLevel);
if (soundReplayBtn) soundReplayBtn.addEventListener('click', playSoundPrompt);
if (soundStepNextBtn) soundStepNextBtn.addEventListener('click', nextSoundQuestion);
if (soundLevelupBtn) soundLevelupBtn.addEventListener('click', soundLevelUp);
if (soundRetryBtn) soundRetryBtn.addEventListener('click', retrySoundLevel);
if (animalwordResetBtn) animalwordResetBtn.addEventListener('click', resetAnimalwordInput);
if (animalwordStepNextBtn) animalwordStepNextBtn.addEventListener('click', nextAnimalwordQuestion);
if (animalwordLevelupBtn) animalwordLevelupBtn.addEventListener('click', animalwordLevelUp);
if (animalwordRetryBtn) animalwordRetryBtn.addEventListener('click', retryAnimalwordLevel);
root.addEventListener('pointerdown', unlockAudio, { once: true });
window.addEventListener('resize', function () { setRealVh(); applyMemoryBoardFit(); });
window.addEventListener('orientationchange', function () { setRealVh(); applyMemoryBoardFit(); });
console.assert(Array.isArray(ANIMALS_MASTER) && ANIMALS_MASTER.length >= 3, 'Minimaal 3 dieren verwacht');
console.assert(Array.isArray(LETTERS_QUESTIONS) && LETTERS_QUESTIONS.length >= 3, 'Minimaal 3 lettervragen verwacht');
console.assert(typeof startMemory === 'function', 'startMemory moet bestaan');
console.assert(typeof startCounting === 'function', 'startCounting moet bestaan');
console.assert(typeof startLetters === 'function', 'startLetters moet bestaan');
console.assert(typeof applyMemoryBoardFit === 'function', 'applyMemoryBoardFit moet bestaan');
console.assert(typeof showMemoryTyped === 'function', 'showMemoryTyped moet bestaan');
console.assert(typeof nextLettersQuestion === 'function', 'nextLettersQuestion moet bestaan');
console.assert(typeof startSoundGame === 'function', 'startSoundGame moet bestaan');
console.assert(typeof playSoundPrompt === 'function', 'playSoundPrompt moet bestaan');
console.assert(typeof playCoinSound === 'function', 'playCoinSound moet bestaan');
console.assert(typeof startAnimalwordGame === 'function', 'startAnimalwordGame moet bestaan');
console.assert(typeof nextAnimalwordQuestion === 'function', 'nextAnimalwordQuestion moet bestaan');
console.assert(shuffle([1,2,3,4]).length === 4, 'shuffle test mislukt');
console.assert(('Goed: 1 • Fout: 0\nTotaal vragen: 3').indexOf('\n') > -1, 'newline string test mislukt');
setRealVh();
updateMemoryHud();
showMode('memory');
buildMemoryLevel();
startScreen.classList.remove('hide');
}());