Fix this code add swipe gestures touchscreen compatible on the screen of the game: <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<title>Colorful Snake Game</title>
<style>
    /* Reset / base styles */
    * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        -webkit-tap-highlight-color: transparent; /* remove tap highlight on mobile */
    }
    
    html, body {
        height: 100%;
        background: linear-gradient(135deg, #1a1a2e, #16213e);
        overflow: hidden;
        color: white;
        user-select: none;
    }
    
    body {
        display: flex;
        justify-content: center;
        align-items: center;
        padding: 20px;
    }
    
    .game-container {
        position: relative;
        width: 100%;
        max-width: 600px;
        text-align: center;
        touch-action: manipulation;  /* Improve touch input handling */
    }
    
    .header {
        margin-bottom: 20px;
        text-shadow: 0 0 12px rgba(255, 255, 255, 0.6);
    }
    
    .header h1 {
        font-size: 2.5rem;
        margin-bottom: 5px;
        background: linear-gradient(to right, #ff7e5f, #feb47b);
        -webkit-background-clip: text;
        -webkit-text-fill-color: transparent;
        letter-spacing: 3px;
        user-select: none;
    }
    
    .score-container {
        display: flex;
        justify-content: center;
        gap: 30px;
        margin-bottom: 10px;
    }
    
    .score-box {
        background: rgba(255, 255, 255, 0.1);
        padding: 12px 25px;
        border-radius: 12px;
        box-shadow: 0 5px 15px rgba(0, 0, 0, 0.35);
        backdrop-filter: blur(6px);
        min-width: 110px;
        user-select: none;
        transition: transform 0.2s ease;
    }
    
    .score-box:hover {
        transform: scale(1.05);
    }
    
    .score-box h2 {
        color: #feb47b;
        font-size: 1.3rem;
        margin-bottom: 6px;
        letter-spacing: 1.2px;
    }
    
    .score-box p {
        color: white;
        font-size: 2rem;
        font-weight: 700;
    }
    
    .game-board {
        position: relative;
        width: 100%;
        height: 70vh;
        max-height: 500px;
        background: rgba(0, 0, 0, 0.35);
        border-radius: 18px;
        overflow: hidden;
        box-shadow: 0 12px 35px rgba(0, 0, 0, 0.5);
        margin: 0 auto 20px;
        border: 3px solid rgba(255, 255, 255, 0.12);
        touch-action: none; /* prevent scrolling on touch drag */
        -webkit-tap-highlight-color: transparent;
    }
    
    canvas {
        display: block;
        width: 100% !important;  /* force full container size avoiding scaling issues */
        height: 100% !important;
        background: rgba(10, 10, 25, 0.85);
        border-radius: 18px;
        image-rendering: pixelated; /* sharp pixels on canvas sprites */
    }
    
    /* Game state overlays */
    .overlay {
        position: absolute;
        inset: 0;
        background: rgba(0, 0, 0, 0.82);
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        z-index: 20;
        color: #ff7e5f;
        font-weight: 700;
        letter-spacing: 2.5px;
        text-align: center;
        user-select: none;
        padding: 10px 20px;
        font-size: 2rem;
        text-shadow: 0 0 14px rgba(255, 126, 95, 0.7);
        border-radius: 18px;
    }
    .overlay.hidden {
        display: none;
    }
    .overlay button {
        margin-top: 22px;
        background: linear-gradient(to right, #ff7e5f, #feb47b);
        border: none;
        padding: 16px 48px;
        border-radius: 32px;
        color: white;
        font-size: 1.3rem;
        font-weight: 700;
        cursor: pointer;
        box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
        transition: all 0.3s ease;
        -webkit-tap-highlight-color: transparent;
    }
    .overlay button:hover,
    .overlay button:focus {
        outline: none;
        transform: scale(1.08);
        box-shadow: 0 8px 28px rgba(0, 0, 0, 0.5);
    }
    
    /* Controls */
    .controls {
        display: flex;
        justify-content: center;
        margin-top: 20px;
        user-select: none;
    }
    
    .direction-controls {
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        grid-template-rows: repeat(3, 1fr);
        gap: 12px;
        width: 220px;
        height: 220px;
        margin: 0 auto;
    }
    
    .control-btn {
        background: rgba(255, 255, 255, 0.12);
        border: 2px solid rgba(255, 255, 255, 0.25);
        border-radius: 50%;
        display: flex;
        justify-content: center;
        align-items: center;
        font-size: 32px;
        color: white;
        cursor: pointer;
        box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3);
        transition: transform 0.15s ease, background 0.25s ease;
        user-select: none;
        touch-action: manipulation;
        -webkit-tap-highlight-color: transparent;
    }
    .control-btn:active,
    .control-btn.pressed {
        transform: scale(0.95);
        background: rgba(255, 255, 255, 0.3);
        box-shadow: 0 3px 10px rgba(0, 0, 0, 0.2);
        user-select: none; /* Prevent text selection on press */
    }
    
    #up {
        grid-column: 2;
        grid-row: 1;
    }
    
    #down {
        grid-column: 2;
        grid-row: 3;
    }
    
    #left {
        grid-column: 1;
        grid-row: 2;
    }
    
    #right {
        grid-column: 3;
        grid-row: 2;
    }
    
    #pause {
        grid-column: 1 / span 3;
        grid-row: 2;
        width: 110px;
        height: 54px;
        border-radius: 28px;
        font-size: 24px;
        color: #ff6464;
        background: rgba(255, 100, 100, 0.35);
        border-color: rgba(255, 100, 100, 0.55);
        align-self: center;
        justify-self: center;
        user-select: none;
        touch-action: manipulation;
        -webkit-tap-highlight-color: transparent;
    }
    #pause:active,
    #pause.pressed {
        background: rgba(255, 100, 100, 0.6);
        border-color: rgba(255, 100, 100, 0.8);
        transform: scale(0.96);
        box-shadow: none;
    }
    
    /* Instructions */
    .instructions {
        margin-top: 18px;
        font-size: 1rem;
        line-height: 1.5;
        color: rgba(255, 255, 255, 0.75);
        user-select: none;
        max-width: 500px;
        margin-left: auto;
        margin-right: auto;
        letter-spacing: 0.08em;
    }
    
    /* Background particles container */
    .particles {
        position: fixed;
        top: 0;
        left: 0;
        height: 100vh;
        width: 100vw;
        pointer-events: none;
        z-index: 1;
        overflow: hidden;
    }
    .particle {
        position: absolute;
        border-radius: 50%;
        opacity: 0;
        animation-name: float;
        animation-timing-function: linear;
        animation-iteration-count: infinite;
        will-change: transform, opacity;
        box-shadow: 0 0 6px 2px currentColor;
    }
    @keyframes float {
        0% {
            transform: translateY(100vh) translateX(0);
            opacity: 0;
        }
        10% {
            opacity: 0.9;
        }
        85% {
            opacity: 0.35;
        }
        100% {
            transform: translateY(-150px) translateX(100px);
            opacity: 0;
        }
    }
    
    /* Responsive */
    @media (max-width: 600px) {
        .header h1 {
            font-size: 1.9rem;
            letter-spacing: 1.5px;
        }
        
        .score-container {
            gap: 18px;
        }
        
        .score-box {
            padding: 9px 18px;
            min-width: 90px;
        }
        
        .score-box h2 {
            font-size: 1rem;
        }
        
        .score-box p {
            font-size: 1.5rem;
        }
        
        .direction-controls {
            width: 180px;
            height: 180px;
            gap: 10px;
        }
        
        .control-btn {
            width: 55px;
            height: 55px;
            font-size: 24px;
            border-width: 1.8px;
        }
        
        #pause {
            width: 90px;
            height: 44px;
            font-size: 20px;
        }
    }
    @media (max-width: 350px) {
        .instructions {
            font-size: 0.9rem;
            letter-spacing: 0.07em;
            padding: 0 10px;
        }
    }
</style>
</head>
<body>
<div class="particles" id="particles" aria-hidden="true"></div>

<div class="game-container" role="main" aria-label="Colorful Snake Game">
    <div class="header">
        <h1>COLORFUL SNAKE</h1>
        <div class="score-container" aria-live="polite" aria-atomic="true">
            <div class="score-box" role="region" aria-label="Current score">
                <h2>SCORE</h2>
                <p id="score" aria-live="polite">0</p>
            </div>
            <div class="score-box" role="region" aria-label="Apples eaten">
                <h2>APPLES</h2>
                <p id="apples-eaten" aria-live="polite">0</p>
            </div>
        </div>
    </div>

    <div class="game-board">
        <canvas id="gameCanvas" role="img" aria-label="Snake game board" tabindex="0"></canvas>

        <!-- Overlay screens with accessible visibility -->
        <div class="overlay" id="startOverlay" role="dialog" aria-modal="true" aria-labelledby="startTitle">
            <h2 id="startTitle">WELCOME TO COLORFUL SNAKE</h2>
            <p>Eat the colorful apples! Snake wraps around walls.<br />3-5 apples at a time.<br />Use arrow keys or tap controls.<br /><br /><strong>Press Start to Play!</strong></p>
            <button id="startBtn" aria-label="Start game">START</button>
        </div>

        <div class="overlay hidden" id="pauseOverlay" role="alert" aria-live="assertive">
            <h2>PAUSED</h2>
            <p>Press Resume or Spacebar to continue</p>
            <button id="resumeBtn">RESUME</button>
        </div>

        <div class="overlay hidden" id="gameOverOverlay" role="alertdialog" aria-modal="true" aria-labelledby="gameOverTitle">
            <h2 id="gameOverTitle">GAME OVER</h2>
            <p>Your final score: <span id="finalScore">0</span></p>
            <button class="restart-btn" id="restartBtn" aria-label="Restart game">PLAY AGAIN</button>
        </div>
    </div>

    <div class="controls" role="region" aria-label="Game controls" >
        <div class="direction-controls">
            <button class="control-btn" id="up" aria-label="Move up" role="button">↑</button>
            <button class="control-btn" id="left" aria-label="Move left" role="button">←</button>
            <button class="control-btn" id="pause" aria-label="Pause game" role="button">❚❚</button>
            <button class="control-btn" id="right" aria-label="Move right" role="button">→</button>
            <button class="control-btn" id="down" aria-label="Move down" role="button">↓</button>
        </div>
    </div>

    <div class="instructions">
        <p>Eat the colorful apples! Snake wraps around walls. 3-5 apples at a time. Use arrow keys or tap on controls to move.</p>
    </div>
</div>

<script>
document.addEventListener('DOMContentLoaded', () => {
    // === Setup & DOM refs ===
    const canvas = document.getElementById('gameCanvas');
    const ctx = canvas.getContext('2d');
    const gameBoard = document.querySelector('.game-board');
    const scoreDisplay = document.getElementById('score');
    const applesEatenDisplay = document.getElementById('apples-eaten');
    const finalScoreDisplay = document.getElementById('finalScore');

    const startOverlay = document.getElementById('startOverlay');
    const pauseOverlay = document.getElementById('pauseOverlay');
    const gameOverOverlay = document.getElementById('gameOverOverlay');
    const startBtn = document.getElementById('startBtn');
    const resumeBtn = document.getElementById('resumeBtn');
    const restartBtn = document.getElementById('restartBtn');

    const controls = {
        up: document.getElementById('up'),
        down: document.getElementById('down'),
        left: document.getElementById('left'),
        right: document.getElementById('right'),
        pause: document.getElementById('pause')
    };

    // === Retina support by scaling canvas ===
    function setupCanvas() {
        const dpr = window.devicePixelRatio || 1;
        canvas.width = gameBoard.clientWidth * dpr;
        canvas.height = gameBoard.clientHeight * dpr;
        canvas.style.width = `${gameBoard.clientWidth}px`;
        canvas.style.height = `${gameBoard.clientHeight}px`;
        ctx.setTransform(1, 0, 0, 1, 0, 0);
        ctx.scale(dpr, dpr);
    }
    setupCanvas();
    window.addEventListener('resize', () => {
        setupCanvas();
    });

    const gridSize = 20;

    // Recompute grid size based on canvas pixel size and CSS size for responsive scaling
    function computeGrid() {
        return {
            width: Math.floor(gameBoard.clientWidth / gridSize),
            height: Math.floor(gameBoard.clientHeight / gridSize),
        };
    }
    let {width: gridWidth, height: gridHeight} = computeGrid();
    window.addEventListener('resize', () => {
        ({width: gridWidth, height: gridHeight} = computeGrid());
    });

    const minApples = 3;
    const maxApples = 5;

    // === Game variables ===
    let snake = [];
    let apples = [];
    let direction = 'right';
    let nextDirection = 'right';
    let score = 0;
    let applesEaten = 0;
    let gameSpeed = 120; // FPS-ish, controls update frequency
    let gameRunning = false;
    let animationFrameId = null;
    let lastRenderTime = null;
    let particles = [];

    // === Particle System ===
    function createParticles(x, y, color) {
        for (let i = 0; i < 15; i++) {
            particles.push({
                x: x * gridSize + gridSize / 2,
                y: y * gridSize + gridSize / 2,
                color: color,
                size: Math.random() * 4 + 2,
                speedX: (Math.random() - 0.5) * 8,
                speedY: (Math.random() - 0.5) * 8,
                life: 35,
                opacity: 1,
                decayRate: 1 / 35,
            });
        }
    }

    function updateParticles() {
        for (let i = particles.length - 1; i >= 0; i--) {
            const p = particles[i];
            p.x += p.speedX;
            p.y += p.speedY;
            p.life--;
            p.opacity -= p.decayRate;
            if (p.life <= 0 || p.opacity <= 0) particles.splice(i, 1);
        }
    }

    function drawParticles() {
        particles.forEach(p => {
            ctx.globalAlpha = Math.max(p.opacity, 0);
            ctx.fillStyle = p.color;
            ctx.beginPath();
            ctx.arc(p.x, p.y, p.size, 0, 2 * Math.PI);
            ctx.fill();
        });
        ctx.globalAlpha = 1;
    }

    // === Utility functions ===
    function getRandomColor() {
        const colors = [
            '#FF5252', '#FF4081', '#E040FB', '#7C4DFF',
            '#536DFE', '#448AFF', '#40C4FF', '#18FFFF',
            '#64FFDA', '#69F0AE', '#B2FF59', '#EEFF41'
        ];
        return colors[Math.floor(Math.random() * colors.length)];
    }

    // === Spawn apples that do not overlap snake or other apples ===
    function spawnApples() {
        const appleCount = Math.floor(Math.random() * (maxApples - minApples + 1)) + minApples;
        while (apples.length < appleCount) {
            const newApple = {
                x: Math.floor(Math.random() * gridWidth),
                y: Math.floor(Math.random() * gridHeight),
                color: getRandomColor()
            };
            const collisionWithSnake = snake.some(s => s.x === newApple.x && s.y === newApple.y);
            const collisionWithApple = apples.some(a => a.x === newApple.x && a.y === newApple.y);
            if (!collisionWithSnake && !collisionWithApple) apples.push(newApple);
        }
    }

    // === Initialize or reset game ===
    function initGame() {
        ({width: gridWidth, height: gridHeight} = computeGrid());
        snake = [
            {x: Math.floor(gridWidth / 2), y: Math.floor(gridHeight / 2)},
            {x: Math.floor(gridWidth / 2) - 1, y: Math.floor(gridHeight / 2)},
            {x: Math.floor(gridWidth / 2) - 2, y: Math.floor(gridHeight / 2)}
        ];

        apples = [];
        spawnApples();

        direction = 'right';
        nextDirection = 'right';
        score = 0;
        applesEaten = 0;
        gameSpeed = 8; // speed: moves per second
        gameRunning = false;
        particles = [];

        scoreDisplay.textContent = score;
        applesEatenDisplay.textContent = applesEaten;
        finalScoreDisplay.textContent = '0';

        pauseOverlay.classList.add('hidden');
        gameOverOverlay.classList.add('hidden');
        startOverlay.classList.remove('hidden');
        setFocusToButton(startBtn);
    }

    // === Draw helper: rounded rect for snake segments ===
    function drawRoundedRect(x, y, width, height, radius, fillStyle, strokeStyle, lineWidth = 2) {
        const r = Math.min(radius, width / 2, height / 2);
        ctx.beginPath();
        ctx.moveTo(x + r, y);
        ctx.lineTo(x + width - r, y);
        ctx.quadraticCurveTo(x + width, y, x + width, y + r);
        ctx.lineTo(x + width, y + height - r);
        ctx.quadraticCurveTo(x + width, y + height, x + width - r, y + height);
        ctx.lineTo(x + r, y + height);
        ctx.quadraticCurveTo(x, y + height, x, y + height - r);
        ctx.lineTo(x, y + r);
        ctx.quadraticCurveTo(x, y, x + r, y);
        ctx.closePath();
        ctx.fillStyle = fillStyle;
        ctx.fill();
        if (strokeStyle) {
            ctx.strokeStyle = strokeStyle;
            ctx.lineWidth = lineWidth;
            ctx.stroke();
        }
    }

    // === Main draw function ===
    function draw() {
        // Clear background
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.fillStyle = 'rgba(10, 10, 25, 0.9)';
        ctx.fillRect(0, 0, canvas.width, canvas.height);

        // Draw grid faintly (skip drawing all squares, draw lines instead for better performance)
        ctx.strokeStyle = 'rgba(255, 255, 255, 0.05)';
        ctx.lineWidth = 0.4;
        ctx.beginPath();
        for (let x = 0; x <= gridWidth; x++) {
            ctx.moveTo(x * gridSize + 0.5, 0);
            ctx.lineTo(x * gridSize + 0.5, gridHeight * gridSize);
        }
        for (let y = 0; y <= gridHeight; y++) {
            ctx.moveTo(0, y * gridSize + 0.5);
            ctx.lineTo(gridWidth * gridSize, y * gridSize + 0.5);
        }
        ctx.stroke();

        // Draw apples
        apples.forEach(({x, y, color}) => {
            const centerX = x * gridSize + gridSize / 2;
            const centerY = y * gridSize + gridSize / 2;

            // Apple body
            ctx.fillStyle = color;
            ctx.beginPath();
            ctx.arc(centerX, centerY, gridSize / 2 - 2, 0, 2 * Math.PI);
            ctx.fill();

            // Shine effect
            ctx.fillStyle = 'rgba(255, 255, 255, 0.55)';
            ctx.beginPath();
            ctx.arc(centerX - gridSize / 5, centerY - gridSize / 5, gridSize / 6, 0, 2 * Math.PI);
            ctx.fill();
        });

        // Draw snake with gradient coloring & rounded shapes
        snake.forEach((segment, i) => {
            const xPos = segment.x * gridSize;
            const yPos = segment.y * gridSize;
            if (i === 0) {
                // Head (green)
                drawRoundedRect(xPos, yPos, gridSize, gridSize, 6, '#4caf50', 'rgba(0, 64, 0, 0.8)', 3);
            } else {
                // Body gradient
                const hue = 120 + 30 * (i / snake.length);
                const color = `hsl(${hue}, 70%, 50%)`;
                drawRoundedRect(xPos, yPos, gridSize, gridSize, 5, color, 'rgba(0, 0, 0, 0.3)');
            }
        });

        // Draw particles on top
        updateParticles();
        drawParticles();
    }

    // === Game logic for move & update ===
    function update() {
        // Apply next direction if valid (no 180 turns)
        if (nextDirection) {
            if (
                (nextDirection === 'up' && direction !== 'down') ||
                (nextDirection === 'down' && direction !== 'up') ||
                (nextDirection === 'left' && direction !== 'right') ||
                (nextDirection === 'right' && direction !== 'left')
            ) {
                direction = nextDirection;
            }
        }

        // Compute new head position
        const head = {...snake[0]};
        switch (direction) {
            case 'up': head.y--; break;
            case 'down': head.y++; break;
            case 'left': head.x--; break;
            case 'right': head.x++; break;
        }

        // Wrap positions
        if (head.x < 0) head.x = gridWidth - 1;
        else if (head.x >= gridWidth) head.x = 0;
        if (head.y < 0) head.y = gridHeight - 1;
        else if (head.y >= gridHeight) head.y = 0;

        // Check collision with self
        for (let i = 0; i < snake.length; i++) {
            if (snake[i].x === head.x && snake[i].y === head.y) {
                endGame();
                return;
            }
        }

        snake.unshift(head);

        // Check if apple eaten
        let ateApple = false;
        for (let i = 0; i < apples.length; i++) {
            if (apples[i].x === head.x && apples[i].y === head.y) {
                const appleColor = apples[i].color;
                apples.splice(i, 1);
                createParticles(head.x, head.y, appleColor);
                score += 10;
                applesEaten++;
                // Increase speed gradually, capped
                gameSpeed = Math.min(20, gameSpeed + 0.3);

                scoreDisplay.textContent = score;
                applesEatenDisplay.textContent = applesEaten;
                ateApple = true;
                break;
            }
        }

        if (!ateApple) {
            snake.pop();
        } else {
            spawnApples();
        }
    }

    // === Game loop with precise timing ===
    function gameLoop(timestamp) {
        if (!gameRunning) return;

        if (!lastRenderTime) lastRenderTime = timestamp;

        const secondsSinceLastRender = (timestamp - lastRenderTime) / 1000;
        const interval = 1 / gameSpeed;

        if (secondsSinceLastRender >= interval) {
            lastRenderTime = timestamp;
            update();
            draw();
        }

        animationFrameId = window.requestAnimationFrame(gameLoop);
    }

    // === Game state controls ===
    function startGame() {
        if (gameRunning) return;

        gameRunning = true;
        lastRenderTime = null;
        startOverlay.classList.add('hidden');
        pauseOverlay.classList.add('hidden');
        gameOverOverlay.classList.add('hidden');
        canvas.focus();
        animationFrameId = window.requestAnimationFrame(gameLoop);
        updatePauseButton();
    }

    function pauseGame() {
        if (!gameRunning) return;
        gameRunning = false;
        pauseOverlay.classList.remove('hidden');
        animationFrameId && window.cancelAnimationFrame(animationFrameId);
        animationFrameId = null;
        updatePauseButton();
    }

    function resumeGame() {
        if (gameRunning) return;
        gameRunning = true;
        lastRenderTime = null;
        pauseOverlay.classList.add('hidden');
        animationFrameId = window.requestAnimationFrame(gameLoop);
        updatePauseButton();
        canvas.focus();
    }

    function togglePause() {
        if (gameRunning) pauseGame();
        else resumeGame();
    }

    function endGame() {
        gameRunning = false;
        animationFrameId && window.cancelAnimationFrame(animationFrameId);
        animationFrameId = null;
        finalScoreDisplay.textContent = score;
        gameOverOverlay.classList.remove('hidden');
        updatePauseButton();
        setFocusToButton(restartBtn);
    }

    // Update pause button appearance
    function updatePauseButton() {
        if (!gameRunning) {
            controls.pause.setAttribute('aria-pressed', 'true');
            controls.pause.classList.add('pressed');
        } else {
            controls.pause.setAttribute('aria-pressed', 'false');
            controls.pause.classList.remove('pressed');
        }
    }

    // Set focus helper
    function setFocusToButton(button) {
        setTimeout(() => {
            button.focus();
        }, 100);
    }

    // === Input handlers ===

    // Use unified pointer events and add repeated input while held

    const activePointers = new Map();

    Object.entries(controls).forEach(([key, button]) => {
        if (key === 'pause') {
            // Pause button: toggle on pointerup (click or touch-end equivalent)
            button.addEventListener('pointerup', (e) => {
                if (e.pointerType === 'mouse' || e.pointerType === 'touch' || e.pointerType === 'pen') {
                    e.preventDefault();
                    togglePause();
                    button.classList.remove('pressed');
                }
            });
            button.addEventListener('pointerdown', (e) => {
                e.preventDefault();
                button.classList.add('pressed');
            });
            button.addEventListener('pointercancel', (e) => {
                e.preventDefault();
                button.classList.remove('pressed');
            });
            button.addEventListener('keydown', e => {
                if (e.key === 'Enter' || e.key === ' ') {
                    e.preventDefault();
                    togglePause();
                }
            });
            return;
        }
        
        let repeatInterval = null;

        function startMoving() {
            changeDirection(key);
            // move every 100ms if button held down
            if (repeatInterval) clearInterval(repeatInterval);
            repeatInterval = setInterval(() => {
                changeDirection(key);
            }, 100);
        }

        function stopMoving() {
            if (repeatInterval) {
                clearInterval(repeatInterval);
                repeatInterval = null;
            }
            button.classList.remove('pressed');
        }

        button.addEventListener('pointerdown', e => {
            e.preventDefault();
            // Track this pointer id to handle multi-touch properly
            if (!activePointers.has(e.pointerId)) {
                activePointers.set(e.pointerId, key);
                button.classList.add('pressed');
                startMoving();
            }
        }, {passive: false});

        button.addEventListener('pointerup', e => {
            e.preventDefault();
            if (activePointers.get(e.pointerId) === key) {
                activePointers.delete(e.pointerId);
                stopMoving();
            }
        }, {passive: false});

        button.addEventListener('pointercancel', e => {
            e.preventDefault();
            if (activePointers.get(e.pointerId) === key) {
                activePointers.delete(e.pointerId);
                stopMoving();
            }
        }, {passive: false});

        // Keyboard support
        button.addEventListener('keydown', e => {
            if (e.key === 'Enter' || e.key === ' ') {
                e.preventDefault();
                changeDirection(key);
                button.classList.add('pressed');
            }
        });
        button.addEventListener('keyup', e => {
            if (e.key === 'Enter' || e.key === ' ') {
                e.preventDefault();
                button.classList.remove('pressed');
            }
        });
    });

    function changeDirection(newDir) {
        // Prevent opposite direction immediately
        const opposites = {
            up: 'down',
            down: 'up',
            left: 'right',
            right: 'left'
        };
        if (direction !== opposites[newDir]) {
            nextDirection = newDir;
        }
    }

    // Keyboard controls and extra keys
    document.addEventListener('keydown', (e) => {
        if (!gameRunning && e.key.toLowerCase() !== ' ') return; // only space to start

        switch (e.key) {
            case 'ArrowUp':
                changeDirection('up');
                e.preventDefault();
                break;
            case 'ArrowDown':
                changeDirection('down');
                e.preventDefault();
                break;
            case 'ArrowLeft':
                changeDirection('left');
                e.preventDefault();
                break;
            case 'ArrowRight':
                changeDirection('right');
                e.preventDefault();
                break;
            case ' ':
                e.preventDefault();
                // Space bar: start, pause or resume toggle
                if (startOverlay.classList.contains('hidden')) {
                    togglePause();
                } else {
                    startGame();
                }
                break;
        }
    });

    // Start/Resume buttons on overlays
    startBtn.addEventListener('click', () => {
        startGame();
    });
    startBtn.addEventListener('keydown', e => {
        if (e.key === 'Enter' || e.key === ' ') {
            e.preventDefault();
            startGame();
        }
    });

    resumeBtn.addEventListener('click', () => {
        resumeGame();
    });
    resumeBtn.addEventListener('keydown', e => {
        if (e.key === 'Enter' || e.key === ' ') {
            e.preventDefault();
            resumeGame();
        }
    });

    restartBtn.addEventListener('click', () => {
        initGame();
        startGame();
    });
    restartBtn.addEventListener('keydown', e => {
        if (e.key === 'Enter' || e.key === ' ') {
            e.preventDefault();
            initGame();
            startGame();
        }
    });

    // === Background floating particles ===
    function createBackgroundParticles() {
        const particlesContainer = document.getElementById('particles');
        const particleCount = 60;

        for (let i = 0; i < particleCount; i++) {
            const particle = document.createElement('div');
            particle.classList.add('particle');
            particle.style.left = `${Math.random() * 100}%`;
            const size = Math.random() * 10 + 3;
            particle.style.width = `${size}px`;
            particle.style.height = `${size}px`;
            particle.style.animationDuration = `${Math.random() * 20 + 15}s`;
            particle.style.animationDelay = `${Math.random() * 10}s`;
            particle.style.color = getRandomColor();
            particlesContainer.appendChild(particle);
        }
    }

    createBackgroundParticles();

    // === Initialize ===
    initGame();

});
</script>
</body>
</html>