<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Pokémon Catcher Deluxe+</title>
    <link rel="stylesheet" href="style.css">
    <link rel="icon" href="https://img.icons8.com/color/48/000000/pokeball-2.png" type="image/png">
</head>
<body>

    <h1>Pokémon Catcher Deluxe+</h1>

    <div class="controls-container">
        <div class="difficulty-select">
            <label>Difficulty:</label>
            <input type="radio" id="diff-easy" name="difficulty" value="easy" checked>
            <label for="diff-easy">Easy</label>
            <input type="radio" id="diff-medium" name="difficulty" value="medium">
            <label for="diff-medium">Medium</label>
            <input type="radio" id="diff-hard" name="difficulty" value="hard">
            <label for="diff-hard">Hard</label>
        </div>
        <!-- In-Game Buttons (initially hidden) -->
        <div id="ingame-controls" class="hidden">
             <button id="ingame-restart-button" class="control-button">Restart</button>
             <button id="ingame-end-button" class="control-button">End Game</button>
        </div>
        <button id="mute-button" title="Toggle Sound">🎵</button>
    </div>


    <div class="game-info-container">
        <div class="game-info">
            <p>Score: <span id="score">0</span></p>
            <p>Time Left: <span id="time-left">30</span>s</p>
        </div>
         <div class="high-score-info">
            <p>High Score: <span id="high-score">0</span></p>
        </div>
    </div>


    <div id="game-area">
        <!-- Pokémon will appear here -->
        <div id="start-message">
            <p>Select difficulty and click Start!</p>
            <button id="start-button">Start Game</button>
        </div>
        <div id="game-over-message" class="hidden">
             <h2>Game Over!</h2>
             <p>Your final score: <span id="final-score">0</span></p>
              <p id="new-high-score-msg" class="hidden">🏆 New High Score! 🏆</p>
             <button id="restart-button">Play Again?</button>
        </div>
    </div>

    <p class="instructions">Click Pokémon before they flee! Shinies are worth more!</p>

    <!-- Audio Files -->
    <audio id="catch-sound" src="https://www.myinstants.com/media/sounds/pokemon-catch.mp3" preload="auto"></audio>
    <audio id="flee-sound" src="https://www.myinstants.com/media/sounds/pokemon-flee.mp3" preload="auto"></audio>
    <audio id="shiny-catch-sound" src="https://www.myinstants.com/media/sounds/itemfinder-sound-effect.mp3" preload="auto"></audio>
    <audio id="bg-music" src="https://vgmsite.com/soundtracks/pokemon-gameboy-sound-collection/vvhl DISC 1 TRACK 1/101-opening.mp3" loop preload="auto"></audio>
    <audio id="game-over-sound" src="https://www.myinstants.com/media/sounds/pokemon-center-recovery-sound-effect-hd.mp3" preload="auto"></audio>
    <!-- NEW AUDIO -->
    <audio id="win-sound" src="https://www.myinstants.com/media/sounds/pokemon_victory_sound_effect.mp3" preload="auto"></audio> <!-- For New High Score -->
    <audio id="restart-sound" src="https://www.myinstants.com/media/sounds/sound-971_hifi.mp3" preload="auto"></audio> <!-- Simple UI sound -->
    <audio id="button-click-sound" src="https://www.myinstants.com/media/sounds/sound-971_hifi.mp3" preload="auto"></audio> <!-- Same as restart for general clicks -->

    <script src="script.js"></script>
</body>
</html>
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&family=VT323&display=swap');

:root {
    --font-pixel: 'VT323', monospace;
    --font-title: 'Press Start 2P', cursive;
    --color-bg: #e0f2f7; /* Lighter blue sky */
    --color-grass: #a5d6a7;
    --color-grass-dark: #81c784;
    --color-text: #004d40; /* Dark Teal */
    --color-red: #e53935;
    --color-blue: #1e88e5;
    --color-yellow: #fdd835;
    --color-brown: #795548;
    --color-brown-light: #a1887f;
    --color-frame: #6d4c41; /* Darker brown for frame */
    --color-shiny: gold;
}

body {
    font-family: var(--font-pixel);
    display: flex;
    flex-direction: column;
    align-items: center;
    background: linear-gradient(to bottom, var(--color-bg) 70%, var(--color-grass) 95%);
    min-height: 100vh;
    color: var(--color-text);
    margin: 0;
    padding: 20px 15px;
    user-select: none;
}

h1 {
    font-family: var(--font-title);
    color: var(--color-red);
    text-shadow: 2px 2px var(--color-yellow);
    margin-bottom: 15px;
    font-size: clamp(1.5em, 4vw, 2.2em); /* Responsive font size */
    text-align: center;
}

.controls-container {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 90%;
    max-width: 600px;
    margin-bottom: 15px;
    background-color: rgba(255, 255, 255, 0.6);
    padding: 8px 15px;
    border-radius: 8px;
    border: 2px solid var(--color-brown-light);
    font-size: 1.3em;
}

.difficulty-select label {
    margin: 0 5px 0 10px;
}
.difficulty-select input[type="radio"] {
    margin-right: 3px;
    transform: scale(1.2); /* Make radio buttons slightly bigger */
    cursor: pointer;
}

#mute-button {
    font-size: 1.5em;
    background: none;
    border: none;
    cursor: pointer;
    padding: 0 5px;
    transition: transform 0.2s ease;
}
#mute-button:hover {
    transform: scale(1.2);
}
#mute-button.muted {
    filter: grayscale(100%);
    opacity: 0.7;
}


.game-info-container {
     display: flex;
     justify-content: space-between;
     width: 90%;
     max-width: 600px;
     margin-bottom: 15px;
     font-size: 1.6em; /* Slightly smaller */
     gap: 15px;
}

.game-info, .high-score-info {
    background-color: rgba(255, 255, 255, 0.8);
    padding: 10px 15px;
    border-radius: 8px;
    border: 3px solid var(--color-brown-light);
    text-align: center;
    flex-grow: 1; /* Make them share space */
}

.game-info span, .high-score-info span {
    font-weight: bold;
    color: var(--color-blue);
    display: inline-block; /* Prevent wrapping */
    min-width: 30px; /* Ensure space */
    text-align: right;
}
.high-score-info span {
    color: var(--color-red);
}


#game-area {
    width: 90%;
    max-width: 600px;
    height: 450px; /* Fixed height is often better for games */
    border: 10px ridge var(--color-frame); /* More distinct frame */
    background-color: var(--color-grass); /* Base color */
    /* Subtle grass texture */
    background-image:
      linear-gradient(90deg, rgba(0,0,0,0.03) 50%, transparent 50%),
      linear-gradient(rgba(0,0,0,0.03) 50%, transparent 50%);
    background-size: 15px 15px;
    position: relative;
    overflow: hidden;
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.25);
    display: flex;
    justify-content: center;
    align-items: center;
    text-align: center;
}

#start-message, #game-over-message {
    background-color: rgba(255, 250, 230, 0.95); /* Creamier */
    padding: clamp(20px, 5vw, 40px); /* Responsive padding */
    border-radius: 15px;
    border: 5px double var(--color-brown); /* Double border */
    font-size: clamp(1.2em, 3vw, 1.6em);
    box-shadow: 0 4px 10px rgba(0,0,0,0.1);
    z-index: 10; /* Ensure message is above potential Pokémon */
}

#game-over-message h2 {
    color: var(--color-red);
    margin-top: 0;
    font-family: var(--font-title);
    font-size: 1.2em;
}
#new-high-score-msg {
    color: var(--color-yellow);
    text-shadow: 1px 1px var(--color-red);
    font-weight: bold;
    margin-top: 10px;
}

#game-area button {
    font-family: var(--font-title);
    padding: 12px 25px;
    font-size: clamp(0.8em, 2.5vw, 1em);
    cursor: pointer;
    border-width: 4px;
    border-style: outset;
    border-color: #ccc #666 #666 #ccc; /* 3D button look */
    background-color: var(--color-red);
    color: white;
    text-shadow: 1px 1px #a00;
    border-radius: 5px;
    transition: all 0.1s ease;
    margin-top: 15px;
}

#game-area button:hover {
    filter: brightness(1.1);
}
#game-area button:active {
     border-style: inset;
     transform: translate(1px, 1px);
     filter: brightness(0.9);
}


.pokemon-sprite {
    --pokemon-size: clamp(45px, 8vw, 65px); /* Responsive size */
    width: var(--pokemon-size);
    height: var(--pokemon-size);
    position: absolute;
    cursor: url('https://img.icons8.com/color/32/000000/pokeball-2.png'), pointer;
    transition: transform 0.2s ease-out, opacity 0.3s ease-in-out;
    animation: hop 0.7s infinite ease-in-out alternate;
    image-rendering: pixelated;
    z-index: 5; /* Above background, below messages */
    will-change: transform, opacity; /* Performance hint */
}

@keyframes hop {
    from { transform: translateY(0); }
    to   { transform: translateY(-6px); }
}

.pokemon-sprite:hover {
    transform: scale(1.15) translateY(-3px); /* Adjust hop */
    filter: brightness(1.1);
}

/* --- NEW ANIMATIONS --- */
.pokemon-caught {
    animation: catchAnim 0.4s ease-out forwards;
    pointer-events: none; /* Prevent further clicks */
}
@keyframes catchAnim {
    0% { transform: scale(1.1); opacity: 1; }
    50% { transform: scale(1.3) rotate(20deg); opacity: 0.8; }
    100% { transform: scale(0.1) rotate(-30deg); opacity: 0; }
}

.pokemon-flee {
    animation: fleeAnim 0.5s ease-in forwards;
    pointer-events: none;
}
@keyframes fleeAnim {
    0% { transform: translateY(0); opacity: 1; }
    100% { transform: translateY(40px) scale(0.8); opacity: 0; }
}

/* --- SHINY STYLING --- */
.pokemon-sprite.shiny {
   /* Simple filter effect for shiny - might not look perfect for all sprites */
   filter: drop-shadow(0 0 5px var(--color-shiny)) brightness(1.2) saturate(1.5);
   /* Alternative: Use specific shiny sprites if you have URLs */
   /* background-image: url('shiny_sprite_url'); */
    animation: hop 0.7s infinite ease-in-out alternate, shinySparkle 1.5s infinite linear;
}

@keyframes shinySparkle {
    0%, 100% { filter: drop-shadow(0 0 5px var(--color-shiny)) brightness(1.2) saturate(1.5); }
    50% { filter: drop-shadow(0 0 10px var(--color-shiny)) brightness(1.4) saturate(1.8); }
}


.hidden {
    display: none !important;
}

.instructions {
    margin-top: 15px;
    font-size: clamp(1em, 2.5vw, 1.3em);
    font-style: italic;
    text-align: center;
    max-width: 600px;
}

/* ... (Keep all previous CSS from the "Deluxe" version) ... */

/* --- Add styles for new In-Game Controls --- */
.controls-container {
    /* Adjust layout slightly if needed */
    flex-wrap: wrap; /* Allow wrapping if space is tight */
    justify-content: space-around;
    gap: 10px;
}

#ingame-controls {
    display: flex; /* Use flex for the inner buttons */
    gap: 10px; /* Space between restart and end buttons */
}

.control-button {
    padding: 6px 12px;
    font-size: 0.9em; /* Slightly smaller */
    font-family: var(--font-pixel); /* Use pixel font */
    cursor: pointer;
    border-width: 3px;
    border-style: outset;
    border-color: #ccc #666 #666 #ccc;
    color: white;
    border-radius: 4px;
    transition: all 0.1s ease;
}

#ingame-restart-button {
    background-color: var(--color-blue); /* Blue for restart */
    text-shadow: 1px 1px #004080;
}
#ingame-restart-button:hover { filter: brightness(1.1); }
#ingame-restart-button:active { border-style: inset; transform: translate(1px, 1px); filter: brightness(0.9); }


#ingame-end-button {
    background-color: var(--color-red); /* Red for end */
     text-shadow: 1px 1px #a00;
}
#ingame-end-button:hover { filter: brightness(1.1); }
#ingame-end-button:active { border-style: inset; transform: translate(1px, 1px); filter: brightness(0.9); }


#new-high-score-msg {
    color: var(--color-yellow);
    text-shadow: 1px 1px var(--color-red);
    font-weight: bold;
    margin-top: 10px;
    font-size: 1.2em; /* Make it bigger */
    animation: pulseHighScore 1s infinite ease-in-out;
}

@keyframes pulseHighScore {
    0%, 100% { transform: scale(1); opacity: 1;}
    50% { transform: scale(1.1); opacity: 0.8; }
}

/* Ensure messages still have high z-index */
#start-message, #game-over-message {
    z-index: 10;
}

.pokemon-sprite {
     z-index: 5;
}
document.addEventListener('DOMContentLoaded', () => {
    // DOM Elements
    const scoreElement = document.getElementById('score');
    const timeLeftElement = document.getElementById('time-left');
    const gameArea = document.getElementById('game-area');
    const startButton = document.getElementById('start-button');
    const restartButton = document.getElementById('restart-button'); // Play Again button
    const startMessage = document.getElementById('start-message');
    const gameOverMessage = document.getElementById('game-over-message');
    const finalScoreElement = document.getElementById('final-score');
    const highScoreElement = document.getElementById('high-score');
    const newHighScoreMsg = document.getElementById('new-high-score-msg');
    const difficultyRadios = document.querySelectorAll('input[name="difficulty"]');
    const muteButton = document.getElementById('mute-button');
    // NEW In-Game Controls
    const ingameControls = document.getElementById('ingame-controls');
    const ingameRestartButton = document.getElementById('ingame-restart-button');
    const ingameEndButton = document.getElementById('ingame-end-button');


    // Audio Elements
    const catchSound = document.getElementById('catch-sound');
    const fleeSound = document.getElementById('flee-sound');
    const shinyCatchSound = document.getElementById('shiny-catch-sound');
    const bgMusic = document.getElementById('bg-music');
    const gameOverSound = document.getElementById('game-over-sound');
    // NEW AUDIO
    const winSound = document.getElementById('win-sound');
    const restartSound = document.getElementById('restart-sound');
    const buttonClickSound = document.getElementById('button-click-sound');


    // Game Settings (base values, adjusted by difficulty)
    const BASE_GAME_TIME = 30;
    const BASE_MIN_SPAWN = 800;
    const BASE_MAX_SPAWN = 2000;
    const BASE_POKEMON_LIFESPAN = 2500;
    const SHINY_CHANCE = 0.10;
    const SHINY_MULTIPLIER = 5;

    // Game State Variables
    let score = 0;
    let timeLeft = BASE_GAME_TIME;
    let currentHighScore = 0;
    let gameInterval = null;
    let activePokemon = {};
    let isGameRunning = false;
    let isMuted = false;
    let difficulty = 'easy';

    const difficulties = {
        easy: { spawnFactor: 1.2, lifeFactor: 1.3, time: BASE_GAME_TIME },
        medium: { spawnFactor: 1.0, lifeFactor: 1.0, time: BASE_GAME_TIME },
        hard: { spawnFactor: 0.7, lifeFactor: 0.7, time: BASE_GAME_TIME }
    };

    // --- Pokémon Data --- EXPANDED LIST
    const pokemonIds = [
        1, 4, 7, 10, 13, 16, 19, 21, 23, 25, 27, 29, 32, 35, 37, 39, 41, 43, 46, 48, 50,
        52, 54, 56, 58, 60, 63, 66, 69, 72, 74, 77, 79, 81, 83, 84, 86, 88, 90, 92, 95, 96, 98,
        100, 102, 104, 108, 109, 111, 113, 114, 115, 116, 118, 120, 122, 123, 124, 125, 126, 127, 128, 129,
        131, 132, 133, 137, 138, 140, 142, 143, 147, 152, 155, 158, 161, 163, 165, 167, 170, 172, 173, 174,
        175, 177, 179, 183, 185, 187, 190, 191, 193, 194, 198, 200, 201, 202, 203, 204, 206, 207, 209, 211,
        213, 214, 215, 216, 218, 220, 222, 223, 225, 226, 227, 228, 231, 234, 235, 236, 238, 239, 240, 241,
        246 // Up to Larvitar
    ];
    const getPokemonSpriteUrl = (id) => `https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/${id}.png`;


    // --- Initialization ---
    function init() {
        loadHighScore();
        updateHighScoreDisplay();

        // Main Buttons
        startButton.addEventListener('click', handleStartClick);
        restartButton.addEventListener('click', handleStartClick); // Play Again uses same logic
        muteButton.addEventListener('click', handleMuteToggle);

        // In-Game Buttons
        ingameRestartButton.addEventListener('click', handleIngameRestart);
        ingameEndButton.addEventListener('click', handleIngameEnd);

        // Difficulty Radios
        difficultyRadios.forEach(radio => {
            radio.addEventListener('change', handleDifficultyChange);
        });
        difficulty = document.querySelector('input[name="difficulty"]:checked').value;
    }

    // --- Button Handlers (with sound) ---
    function handleStartClick() {
        playSound(buttonClickSound);
        startGame();
    }

     function handleMuteToggle() {
        // Don't play click sound for mute
        toggleMute();
    }

    function handleDifficultyChange(e) {
        playSound(buttonClickSound);
         if (!isGameRunning) {
             difficulty = e.target.value;
             console.log("Difficulty set to:", difficulty);
         } else {
             e.target.checked = (e.target.value === difficulty); // Prevent change mid-game
         }
    }

     function handleIngameRestart() {
        playSound(restartSound);
        console.log("Restarting game...");
        // Stop current game cleanly *without* showing Game Over screen yet
        isGameRunning = false; // Set flag first
        clearInterval(gameInterval);
        clearTimeout(activePokemon.timeoutId);
        removeAllPokemonElements();
        stopBgMusic(); // Stop music before restarting
        activePokemon = {};

        // Immediately start new game
        startGame();
    }

    function handleIngameEnd() {
        playSound(gameOverSound); // Play end sound immediately
        console.log("Ending game via button...");
        endGame(); // Call the normal end game function
    }

    // --- Game Flow ---
    function startGame() {
        console.log(`Starting game on ${difficulty}...`);
        score = 0;
        timeLeft = difficulties[difficulty].time;
        isGameRunning = true;
        activePokemon = {};

        // Update UI
        scoreElement.textContent = score;
        timeLeftElement.textContent = timeLeft;
        startMessage.classList.add('hidden');
        gameOverMessage.classList.add('hidden');
        newHighScoreMsg.classList.add('hidden');
        ingameControls.classList.remove('hidden'); // SHOW in-game buttons
        removeAllPokemonElements();
        enableDifficultySelection(false);

        // Start Timers
        clearInterval(gameInterval); // Ensure no duplicates
        gameInterval = setInterval(updateTimer, 1000);
        scheduleSpawn();

        // Music
        playBgMusic();
    }

    function updateTimer() {
        timeLeft--;
        timeLeftElement.textContent = timeLeft;

        if (timeLeft <= 0) {
            endGame();
        }
    }

    function endGame() {
        if (!isGameRunning && !gameOverMessage.classList.contains('hidden')) return; // Prevent double endGame calls

        console.log("Ending game...");
        isGameRunning = false;
        clearInterval(gameInterval);
        clearTimeout(activePokemon.timeoutId);
        removeAllPokemonElements();
        activePokemon = {};

        // UI Updates
        finalScoreElement.textContent = score;
        const isNewHighScore = checkHighScore(); // Check and update high score
        gameOverMessage.classList.remove('hidden');
        ingameControls.classList.add('hidden'); // HIDE in-game buttons
        enableDifficultySelection(true);

        // Sound
        stopBgMusic();
        playSound(isNewHighScore ? winSound : gameOverSound); // Play win or game over sound
    }

    // --- Spawning Logic ---
    function scheduleSpawn() {
        if (!isGameRunning) return;

        clearTimeout(activePokemon.timeoutId); // Clear any pending spawn/flee

        const { spawnFactor } = difficulties[difficulty];
        const spawnDelay = Math.random() * (BASE_MAX_SPAWN - BASE_MIN_SPAWN) * spawnFactor + (BASE_MIN_SPAWN * spawnFactor);

        // Set timeout specifically for the *next* spawn action
        activePokemon.timeoutId = setTimeout(spawnPokemon, spawnDelay);
    }

    function spawnPokemon() {
        if (!isGameRunning) return;

        // Clear previous visual element if it somehow lingered (safety net)
        // removeAllPokemonElements(); // Reconsidered: Might cause flicker. State management should be primary.

        const pokemonId = pokemonIds[Math.floor(Math.random() * pokemonIds.length)];
        const isShiny = Math.random() < SHINY_CHANCE;
        const { lifeFactor } = difficulties[difficulty];
        const lifespan = BASE_POKEMON_LIFESPAN * lifeFactor;

        const pokemonElement = document.createElement('img');
        pokemonElement.src = getPokemonSpriteUrl(pokemonId);
        pokemonElement.classList.add('pokemon-sprite');
        if (isShiny) {
            pokemonElement.classList.add('shiny');
        }
        pokemonElement.alt = `Pokemon ${pokemonId}${isShiny ? ' (Shiny)' : ''}`;
        pokemonElement.draggable = false;
        pokemonElement.dataset.pokemonId = pokemonId;
        pokemonElement.dataset.isShiny = isShiny;

        // Position calculation (same as before)
        const gameAreaRect = gameArea.getBoundingClientRect();
        const pokemonSize = parseInt(getComputedStyle(document.documentElement).getPropertyValue('--pokemon-size') || '60'); // Get from CSS var
        const maxLeft = gameAreaRect.width - pokemonSize - 10;
        const maxTop = gameAreaRect.height - pokemonSize - 10;
        pokemonElement.style.left = `${Math.max(5, Math.random() * maxLeft)}px`;
        pokemonElement.style.top = `${Math.max(5, Math.random() * maxTop)}px`;

        pokemonElement.addEventListener('mousedown', handleCatchAttempt);
        gameArea.appendChild(pokemonElement);

        // Set flee timeout for this specific Pokemon
        const fleeTimeoutId = setTimeout(() => fleePokemon(pokemonElement), lifespan);

        // Update active Pokemon state - IMPORTANT: timeoutId now refers to FLEE
        activePokemon = {
            id: pokemonId,
            element: pokemonElement,
            timeoutId: fleeTimeoutId, // This timeout is for FLEEING
            isShiny: isShiny
        };

        // NOTE: The next spawn is scheduled *independently* via scheduleSpawn calls.
        // We do NOT schedule the next spawn from within spawnPokemon itself anymore.
    }


    // --- Catching & Fleeing ---
     function handleCatchAttempt(event) {
        // Check if the clicked element is the currently active one
        if (!isGameRunning || !activePokemon.element || event.target !== activePokemon.element) {
            return;
        }

        const caughtPokemonElement = activePokemon.element;
        const wasShiny = activePokemon.isShiny;

        // Prevent flee timer for this Pokémon
        clearTimeout(activePokemon.timeoutId);

        // --- BUG FIX ---
        // Immediately clear state and schedule the NEXT spawn
        const currentPokemonId = activePokemon.id; // Store before clearing
        activePokemon = {}; // Clear active state
        scheduleSpawn(); // <--- ADDED THIS LINE TO FIX THE BUG
        // ---------------

        // Score update
        const points = wasShiny ? SHINY_MULTIPLIER : 1;
        score += points;
        scoreElement.textContent = score;

        // Sound
        playSound(wasShiny ? shinyCatchSound : catchSound);

        // Animation & Removal
        caughtPokemonElement.removeEventListener('mousedown', handleCatchAttempt);
        caughtPokemonElement.classList.add('pokemon-caught');
        setTimeout(() => {
             if (caughtPokemonElement.parentNode === gameArea) {
                gameArea.removeChild(caughtPokemonElement);
            }
        }, 400); // Match catchAnim duration

        console.log(`Caught Pokemon ${currentPokemonId}! Score: ${score}`);
    }


    function fleePokemon(pokemonElement) {
         // Check if the fleeing element is the one we are tracking
        if (!isGameRunning || !activePokemon.element || pokemonElement !== activePokemon.element) {
             if (pokemonElement && pokemonElement.parentNode === gameArea) {
                gameArea.removeChild(pokemonElement); // Cleanup stray element
            }
            return;
        }

        console.log(`Pokemon ${activePokemon.id} fled!`);
        const fleeingElement = activePokemon.element; // Keep reference for animation

        // --- BUG FIX related ---
        // Clear state and schedule the next spawn because this one is gone
        activePokemon = {}; // Clear active state
        scheduleSpawn(); // <--- ENSURE NEXT SPAWN IS SCHEDULED AFTER A FLEE TOO
        // ---------------------

        // Play sound
        playSound(fleeSound);

        // Animation & Removal
        fleeingElement.removeEventListener('mousedown', handleCatchAttempt);
        fleeingElement.classList.add('pokemon-flee');
        setTimeout(() => {
             if (fleeingElement.parentNode === gameArea) {
                gameArea.removeChild(fleeingElement);
            }
        }, 500); // Match fleeAnim duration
    }

    // --- Helper Functions ---
    function removeAllPokemonElements() {
        const existingPokemon = gameArea.querySelectorAll('.pokemon-sprite');
        existingPokemon.forEach(p => {
            if(p.parentNode === gameArea) {
                gameArea.removeChild(p);
            }
        });
    }

    function enableDifficultySelection(enable) {
        difficultyRadios.forEach(radio => {
            radio.disabled = !enable;
        });
    }

    // --- High Score Logic ---
    function loadHighScore() {
        const savedScore = localStorage.getItem('pokemonCatcherHighScore');
        currentHighScore = savedScore ? parseInt(savedScore, 10) : 0;
        console.log("Loaded high score:", currentHighScore);
    }

    function saveHighScore() {
        localStorage.setItem('pokemonCatcherHighScore', currentHighScore.toString());
        console.log("Saved high score:", currentHighScore);
    }

    function updateHighScoreDisplay() {
        highScoreElement.textContent = currentHighScore;
    }

    function checkHighScore() {
        let isNew = false; // Track if it's a new high score
        if (score > currentHighScore) {
            console.log("New high score achieved!");
            currentHighScore = score;
            saveHighScore();
            updateHighScoreDisplay();
            newHighScoreMsg.classList.remove('hidden');
            isNew = true;
        } else {
            newHighScoreMsg.classList.add('hidden');
        }
        return isNew; // Return status for sound selection
    }

    // --- Music & Sound Logic ---
    function playSound(audioElement) {
        if (!isMuted && audioElement) {
            audioElement.currentTime = 0;
            // Lower volume slightly for UI sounds if desired
            if (audioElement === buttonClickSound || audioElement === restartSound) {
                 audioElement.volume = 0.6;
            } else {
                 audioElement.volume = 1.0; // Reset volume for others
            }
            audioElement.play().catch(e => console.error("Audio play failed:", e));
        }
    }

     function playBgMusic() {
        if (!isMuted && bgMusic) {
            bgMusic.volume = 0.3; // Background music should be quieter
            bgMusic.currentTime = 0;
            bgMusic.play().catch(e => console.error("Background music failed:", e));
        }
    }

    function stopBgMusic() {
        if (bgMusic) {
            bgMusic.pause();
            bgMusic.currentTime = 0;
        }
    }

     function toggleMute() {
        isMuted = !isMuted;
        muteButton.textContent = isMuted ? '🔇' : '🎵';
        muteButton.classList.toggle('muted', isMuted);
        console.log("Muted:", isMuted);

        if (isMuted) {
            stopBgMusic();
            // Stop other sounds maybe? Usually just affects music.
        } else {
            if (isGameRunning) {
                playBgMusic();
            }
        }
    }

    // --- Initialization ---
    init();

}); // End DOMContentLoaded

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.