Improve: <!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no,viewport-fit=cover" />
  <title>ULTRA CYBER-NEON SNAKE</title>
  <style>
    /* Improved Reset & Base */
    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
      touch-action: manipulation;
    }
    html, body {
      height: 100%;
      overflow: hidden;
      user-select: none;
      background: linear-gradient(135deg, #0f2027, #0c1a20, #0d1520);
      background-size: 600% 600%;
      animation: bgShift 20s ease infinite;
      font-family: 'Rajdhani', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      color: #0f9;
      touch-action: manipulation;
    }
    @keyframes bgShift {
      0% { background-position: 0% 50%; }
      50% { background-position: 100% 50%; }
      100% { background-position: 0% 50%; }
    }
    
    /* Enhanced Title with Neon Effect */
    .title {
      font-size: 3.5rem;
      text-transform: uppercase;
      letter-spacing: 10px;
      margin-bottom: 20px;
      text-align: center;
      text-shadow: 
        0 0 5px #0f9,
        0 0 10px #0f9,
        0 0 20px #0f9,
        0 0 40px #0ff,
        0 0 80px #0ff;
      animation: neonFlicker 3s infinite alternate;
      position: relative;
      z-index: 10;
      font-weight: 900;
      margin-top: 15px;
    }
    .title span {
      color: #f0f;
      animation: neonFlickerPink 3s infinite alternate;
      text-shadow: 
        0 0 5px #f0f,
        0 0 10px #f0f,
        0 0 20px #f0f,
        0 0 40px #ff00ff,
        0 0 80px #ff00ff;
    }
    
    /* Game Container */
    .game-container {
      display: flex;
      flex-direction: column;
      align-items: center;
      width: 100%;
      max-width: 100vmin;
      position: relative;
      padding: 10px;
    }
    
    /* Game Frame */
    #game {
      position: relative;
      width: 90vmin;
      height: 90vmin;
      background: #111;
      border: 4px solid #0f9;
      border-radius: 20px;
      box-shadow: 
        inset 0 0 20px #0f9a,
        0 0 30px rgba(0, 255, 200, 0.5);
      touch-action: none;
      user-select: none;
      overflow: hidden;
    }
    canvas {
      width: 100%;
      height: 100%;
      display: block;
      background: #111;
      border-radius: 20px;
      position: relative;
      z-index: 2;
    }
    
    /* Neon Glow Effect */
    .neon-glow {
      position: absolute;
      top: -50%;
      left: -50%;
      width: 200%;
      height: 200%;
      background: radial-gradient(circle at center, rgba(0, 255, 200, 0.2), transparent 70%);
      z-index: 1;
      pointer-events: none;
      animation: rotateGlow 40s linear infinite;
      filter: blur(50px);
    }
    @keyframes rotateGlow {
      100% { transform: rotate(360deg); }
    }
    
    /* Neon Scoreboard */
    @keyframes neonFlicker {
      0%, 18%, 22%, 25%, 53%, 57%, 100% {
        text-shadow:
          0 0 5px #0f9,
          0 0 10px #0f9,
          0 0 20px #0f9,
          0 0 40px #0ff,
          0 0 80px #0ff;
      }
      20%, 24%, 55% {
        text-shadow: none;
      }
    }
    @keyframes neonFlickerPink {
      0%, 18%, 22%, 25%, 53%, 57%, 100% {
        text-shadow:
          0 0 5px #f0f,
          0 0 10px #f0f,
          0 0 20px #f0f,
          0 0 40px #f0f,
          0 0 80px #f0f;
      }
      20%, 24%, 55% {
        text-shadow: none;
      }
    }
    #scoreboard {
      margin-top: 15px;
      text-align: center;
      font-size: 1.8rem;
      font-weight: 700;
      animation: neonFlicker 3s infinite;
      user-select: none;
      padding: 15px 25px;
      border-radius: 15px;
      background: rgba(0, 20, 30, 0.7);
      box-shadow: 0 0 20px rgba(0, 255, 200, 0.5);
      transition: all 0.3s ease;
      display: flex;
      gap: 20px;
      letter-spacing: 1px;
    }
    #scoreboard.flash {
      color: #fff;
      text-shadow:
        0 0 25px #0ff,
        0 0 50px #0ff,
        0 0 75px #0ff;
      transition: text-shadow 0.2s, color 0.2s;
      background: rgba(0, 40, 60, 0.9);
      transform: scale(1.05);
    }
    #scoreboard.combo {
      animation: comboFlash 0.5s infinite alternate;
    }
    @keyframes comboFlash {
      0% { background: rgba(200, 0, 100, 0.7); }
      100% { background: rgba(255, 0, 150, 0.9); }
    }
    
    /* Controls */
    #controls {
      margin-top: 25px;
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: 15px;
      width: 90vmin;
      max-width: 400px;
      position: relative;
      z-index: 10;
    }
    .btn {
      background: linear-gradient(145deg, #0f9, #0c7);
      border: none;
      border-radius: 15px;
      padding: 18px 0;
      font-size: 1.6rem;
      font-weight: 900;
      box-shadow: 
        0 0 20px #0f9,
        inset 0 0 8px rgba(255, 255, 255, 0.5);
      cursor: pointer;
      transition: all 0.2s;
      user-select: none;
      color: #000;
      outline-offset: 2px;
      outline-color: transparent;
      outline-style: solid;
      position: relative;
      overflow: hidden;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    .btn::before {
      content: '';
      position: absolute;
      top: -50%;
      left: -50%;
      width: 200%;
      height: 200%;
      background: rgba(255, 255, 255, 0.2);
      transform: rotate(45deg);
      transition: all 0.5s;
      pointer-events: none;
    }
    .btn:hover,
    .btn:focus-visible {
      background: linear-gradient(145deg, #0cffaa, #0cffaa);
      box-shadow: 
        0 0 40px #0cffaa,
        inset 0 0 15px rgba(255, 255, 255, 0.7);
      outline-color: #0cffaa;
      transform: scale(1.05);
    }
    .btn:hover::before {
      transform: rotate(45deg) translate(100px, 100px);
    }
    .btn:active {
      background: linear-gradient(145deg, #0c7, #0a5);
      box-shadow: 
        inset 0 0 40px #0c7,
        inset 0 0 15px rgba(0, 0, 0, 0.5);
      transform: scale(0.95);
    }
    @media (max-width: 500px) {
      .btn {
        font-size: 1.4rem;
        padding: 14px 0;
      }
    }
    
    /* Restart button */
    #restartBtn {
      margin-top: 20px;
      background: linear-gradient(145deg, #0ff, #0cc);
      color: #000;
      border-radius: 15px;
      padding: 16px 0;
      font-size: 1.5rem;
      font-weight: 700;
      box-shadow: 
        0 0 30px #0ff,
        inset 0 0 8px rgba(255, 255, 255, 0.5);
      cursor: pointer;
      user-select: none;
      width: 90vmin;
      max-width: 400px;
      display: none;
      transition: all 0.3s;
      position: relative;
      overflow: hidden;
      border: none;
    }
    #restartBtn::before {
      content: '';
      position: absolute;
      top: -50%;
      left: -50%;
      width: 200%;
      height: 200%;
      background: rgba(255, 255, 255, 0.2);
      transform: rotate(45deg);
      transition: all 0.5s;
      pointer-events: none;
    }
    #restartBtn:hover,
    #restartBtn:focus-visible {
      background: linear-gradient(145deg, #0cc, #0aa);
      box-shadow: 
        0 0 50px #0cc,
        inset 0 0 15px rgba(255, 255, 255, 0.7);
      outline: none;
      transform: scale(1.05);
    }
    #restartBtn:hover::before {
      transform: rotate(45deg) translate(100px, 100px);
    }
    #restartBtn:active {
      background: linear-gradient(145deg, #099, #077);
      box-shadow: 
        inset 0 0 40px #099,
        inset 0 0 15px rgba(0, 0, 0, 0.5);
      transform: scale(0.95);
    }
    
    /* Combo Meter */
    #comboMeter {
      width: 90vmin;
      max-width: 400px;
      height: 14px;
      background: rgba(0, 20, 30, 0.7);
      border-radius: 10px;
      margin-top: 20px;
      overflow: hidden;
      position: relative;
      box-shadow: 0 0 15px rgba(0, 255, 200, 0.4);
    }
    #comboBar {
      height: 100%;
      width: 0%;
      background: linear-gradient(90deg, #0f9, #f0f);
      border-radius: 10px;
      transition: width 0.3s ease;
      box-shadow: 0 0 10px rgba(0, 255, 200, 0.7);
    }
    
    /* Power-ups */
    .power-up {
      position: absolute;
      z-index: 3;
      animation: float 3s infinite ease-in-out;
      filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.9));
    }
    
    @keyframes float {
      0%, 100% { transform: translateY(0); }
      50% { transform: translateY(-15px); }
    }
    
    /* Game over screen */
    .game-over {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: rgba(0, 0, 0, 0.9);
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      z-index: 100;
      opacity: 0;
      pointer-events: none;
      transition: opacity 0.5s ease;
    }
    .game-over.show {
      opacity: 1;
      pointer-events: all;
    }
    .game-over h2 {
      font-size: 4rem;
      color: #f0f;
      text-shadow: 0 0 15px #f0f, 0 0 30px #f0f;
      margin-bottom: 30px;
      animation: neonFlickerPink 1.5s infinite alternate;
      letter-spacing: 5px;
      font-weight: 900;
    }
    .game-over p {
      font-size: 2rem;
      margin-bottom: 40px;
      color: #0ff;
      text-shadow: 0 0 10px #0ff;
      letter-spacing: 2px;
    }
    
    /* Snake Type Indicator */
    #snakeType {
      position: absolute;
      top: 15px;
      right: 15px;
      font-size: 1rem;
      background: rgba(0, 20, 30, 0.7);
      padding: 8px 15px;
      border-radius: 25px;
      color: #0ff;
      text-shadow: 0 0 8px #0ff;
      z-index: 10;
      box-shadow: 0 0 15px rgba(0, 255, 200, 0.4);
      font-weight: 700;
      letter-spacing: 1px;
    }
    
    /* Mobile Controls Notice */
    .mobile-notice {
      margin-top: 15px;
      color: #0f9;
      text-align: center;
      font-size: 1.1rem;
      text-shadow: 0 0 5px #0f9;
      display: none;
      max-width: 90vmin;
    }
    
    /* Power-up Timer */
    .power-timer {
      position: absolute;
      bottom: 15px;
      left: 50%;
      transform: translateX(-50%);
      width: 70%;
      height: 10px;
      background: rgba(0, 20, 30, 0.7);
      border-radius: 5px;
      overflow: hidden;
      z-index: 10;
      box-shadow: 0 0 10px rgba(0, 255, 200, 0.3);
      display: none;
    }
    .power-timer-bar {
      height: 100%;
      width: 100%;
      background: linear-gradient(90deg, #0f9, #f0f);
      transition: width 0.1s linear;
    }
    
    /* New Power-up: Shield */
    .shield-effect {
      position: absolute;
      top: 50%;
      left: 50%;
      width: 100%;
      height: 100%;
      transform: translate(-50%, -50%);
      border-radius: 50%;
      border: 3px solid rgba(0, 200, 255, 0.5);
      box-shadow: 0 0 30px rgba(0, 200, 255, 0.7);
      animation: shieldPulse 2s infinite;
      pointer-events: none;
      z-index: 5;
    }
    @keyframes shieldPulse {
      0%, 100% { transform: translate(-50%, -50%) scale(0.9); opacity: 0.5; }
      50% { transform: translate(-50%, -50%) scale(1.1); opacity: 0.8; }
    }
  </style>
  <link href="https://fonts.googleapis.com/css2?family=Rajdhani:wght@700&display=swap" rel="stylesheet">
</head>
<body>
  <div class="neon-glow"></div>
  
  <h1 class="title">ULTRA <span>CYBER</span> SNAKE</h1>
  
  <div class="game-container">
    <div id="game" role="region" aria-label="Snake game area">
      <canvas id="canvas" tabindex="0" aria-live="polite" aria-label="Game canvas"></canvas>
      <div id="snakeType">NORMAL</div>
      <div class="power-timer" id="powerTimer">
        <div class="power-timer-bar" id="powerTimerBar"></div>
      </div>
      <div class="game-over" id="gameOverScreen">
        <h2>GAME OVER</h2>
        <p>SCORE: <span id="finalScore">0</span></p>
        <button id="restartBtn2" class="btn" type="button" aria-label="Restart game">PLAY AGAIN</button>
      </div>
    </div>

    <div id="scoreboard" aria-live="polite" aria-atomic="true" role="status">
      <div>SCORE: <span id="currentScore">0</span></div>
      <div>HIGH: <span id="highScore">0</span></div>
    </div>

    <div id="comboMeter">
      <div id="comboBar"></div>
    </div>
    
    <div id="controls" aria-label="Directional controls">
      <button class="btn" data-dir="left" aria-label="Move left" type="button">←</button>
      <button class="btn" data-dir="up" aria-label="Move up" type="button">↑</button>
      <button class="btn" data-dir="down" aria-label="Move down" type="button">↓</button>
      <button class="btn" data-dir="right" aria-label="Move right" type="button">→</button>
    </div>

    <button id="restartBtn" type="button" aria-label="Restart game">RESTART GAME</button>
    
    <div class="mobile-notice" id="mobileNotice">Swipe or tap buttons to control the snake</div>
  </div>

  <!-- Sound effects -->
  <audio id="eatSfx" preload="auto" aria-hidden="true">
    <source src="data:audio/mpeg;base64,SUQzBAAAAAABEVRYWFgAAAAtAAADY29tbWVudABCaWdTb3VuZEJhbmsuY29tIC8gTGFTb25vdGhlcXVlLm9yZwBURU5DAAAAHQAAA1N3aXRjaCBQbHVzIMKpIE5DSCBTb2Z0d2FyZQBUSVQyAAAABgAAAzIyMzUAVFNTRQAAAA8AAANMYXZmNTcuODMuMTAwAAAAAAAAAAAAAAD/80DEAAAAA0gAAAAATEFNRTMuMTAwVVVVVVVVVVVVVUxBTUUzLjEwMFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf/zQsRbAAADSAAAAABVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf/zQMSkAAADSAAAAABVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV" type="audio/mpeg">
  </audio>
  <audio id="powerSfx" preload="auto" aria-hidden="true">
    <source src="data:audio/mpeg;base64,SUQzBAAAAAABEVRYWFgAAAAtAAADY29tbWVudABCaWdTb3VuZEJhbmsuY29tIC8gTGFTb25vdGhlcXVlLm9yZwBURU5DAAAAHQAAA1N3aXRjaCBQbHVzIMKpIE5DSCBTb2Z0d2FyZQBUSVQyAAAABgAAAzIyMzUAVFNTRQAAAA8AAANMYXZmNTcuODMuMTAwAAAAAAAAAAAAAAD/80DEAAAAA0gAAAAATEFNRTMuMTAwVVVVVVVVVVVVVUxBTUUzLjEwMFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf/zQsRbAAADSAAAAABVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf/zQMSkAAADSAAAAABVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV" type="audio/mpeg">
  </audio>
  <audio id="gameOverSfx" preload="auto" aria-hidden="true">
    <source src="data:audio/mpeg;base64,SUQzBAAAAAABEVRYWFgAAAAtAAADY29tbWVudABCaWdTb3VuZEJhbmsuY29tIC8gTGFTb25vdGhlcXVlLm9yZwBURU5DAAAAHQAAA1N3aXRjaCBQbHVzIMKp IE5DSCBTb2Z0d2FyZQBUSVQyAAAABgAAAzIyMzUAVFNTRQAAAA8AAANMYXZmNTcuODMuMTAwAAAAAAAAAAAAAAD/80DEAAAAA0gAAAAATEFNRTMuMTAwVVVVVVVVVVVVVUxBTUUzLjEwMFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf/zQsRbAAADSAAAAABVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf/zQMSkAAADSAAAAABVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV" type="audio/mpeg">
  </audio>

  <script>
  (function(){
    // Generate sound effects dynamically
    function generateEatSound() {
      const context = new (window.AudioContext || window.webkitAudioContext)();
      const oscillator = context.createOscillator();
      const gainNode = context.createGain();
      
      oscillator.type = 'sine';
      oscillator.frequency.value = 523.25; // C5
      gainNode.gain.value = 0.3;
      
      oscillator.connect(gainNode);
      gainNode.connect(context.destination);
      
      oscillator.start();
      gainNode.gain.exponentialRampToValueAtTime(0.00001, context.currentTime + 0.3);
      
      return oscillator;
    }
    
    function generatePowerSound() {
      const context = new (window.AudioContext || window.webkitAudioContext)();
      const oscillator = context.createOscillator();
      const gainNode = context.createGain();
      
      oscillator.type = 'sine';
      oscillator.frequency.setValueAtTime(220, context.currentTime);
      oscillator.frequency.exponentialRampToValueAtTime(880, context.currentTime + 0.3);
      gainNode.gain.value = 0.3;
      
      oscillator.connect(gainNode);
      gainNode.connect(context.destination);
      
      oscillator.start();
      gainNode.gain.exponentialRampToValueAtTime(0.00001, context.currentTime + 0.5);
      
      return oscillator;
    }
    
    function generateGameOverSound() {
      const context = new (window.AudioContext || window.webkitAudioContext)();
      const oscillator = context.createOscillator();
      const gainNode = context.createGain();
      
      oscillator.type = 'sine';
      oscillator.frequency.setValueAtTime(349.23, context.currentTime); // F4
      oscillator.frequency.exponentialRampToValueAtTime(130.81, context.currentTime + 0.5); // C3
      gainNode.gain.value = 0.4;
      
      oscillator.connect(gainNode);
      gainNode.connect(context.destination);
      
      oscillator.start();
      gainNode.gain.exponentialRampToValueAtTime(0.00001, context.currentTime + 0.7);
      
      return oscillator;
    }

    // DOM & audio refs
    const game       = document.getElementById('game');
    const canvas     = document.getElementById('canvas');
    const ctx        = canvas.getContext('2d');
    const scoreEl    = document.getElementById('currentScore');
    const highEl     = document.getElementById('highScore');
    const sb         = document.getElementById('scoreboard');
    const comboBar   = document.getElementById('comboBar');
    const snakeType  = document.getElementById('snakeType');
    const btns       = document.querySelectorAll('.btn');
    const restartBtn = document.getElementById('restartBtn');
    const restartBtn2 = document.getElementById('restartBtn2');
    const gameOverScreen = document.getElementById('gameOverScreen');
    const finalScore = document.getElementById('finalScore');
    const powerTimer = document.getElementById('powerTimer');
    const powerTimerBar = document.getElementById('powerTimerBar');
    const mobileNotice = document.getElementById('mobileNotice');

    // Config & state
    const tileCount    = 24;
    let gridSize;
    const fps          = 15; // Increased FPS for smoother gameplay
    const maxApples    = 4;  // More apples
    let snake, velocity, nextVel, apples, score, gameOver;
    let comboCounter, lastAppleTime, hue;
    let effects;
    let highScore     = parseInt(localStorage.getItem('snakeHighScore'),10) || 0;
    let powerUps = [];
    let snakeMode = 'normal'; // normal, fast, ghost, shield
    let powerUpActive = false;
    let powerUpEndTime = 0;
    highEl.textContent = highScore;
    
    // Show mobile notice on touch devices
    if ('ontouchstart' in window || navigator.maxTouchPoints) {
      mobileNotice.style.display = 'block';
    }
    
    // Initialize or reset game state
    function initGame() {
      snake = [{x:12,y:12}, {x:11,y:12}, {x:10,y:12}];
      velocity = {x:1, y:0};
      nextVel = {x:1, y:0};
      apples = [];
      powerUps = [];
      score = 0;
      comboCounter = 0;
      lastAppleTime = 0;
      hue = 0;
      effects = { score: [], particles: [] };
      gameOver = false;
      snakeMode = 'normal';
      powerUpActive = false;
      powerUpEndTime = 0;
      comboBar.style.width = '0%';
      snakeType.textContent = 'NORMAL';
      snakeType.style.color = '#0ff';
      scoreEl.textContent = score;
      restartBtn.style.display = 'none';
      powerTimer.style.display = 'none';
      gameOverScreen.classList.remove('show');
      spawnApples();
    }

    // Dynamic canvas sizing
    function resizeCanvas(){
      const size = game.clientWidth;
      canvas.width  = size;
      canvas.height = size;
      gridSize      = size / tileCount;
    }
    resizeCanvas();
    window.addEventListener('resize', resizeCanvas);

    // Helpers (color gradients, rounded rect, empty‑cell check)
    function colorGradient(isSnake){
      hue = (hue + 2) % 360;
      if(isSnake){
        const c1 = `hsl(${hue},100%,60%)`,
              c2 = `hsl(${(hue+40)%360},100%,70%)`,
              g  = ctx.createLinearGradient(0, 0, canvas.width, canvas.height);
        g.addColorStop(0, c1);
        g.addColorStop(1, c2);
        return g;
      } else {
        const g = ctx.createRadialGradient(0,0,5, 0,0, gridSize*0.6);
        g.addColorStop(0, `hsl(${hue},100%,80%)`);
        g.addColorStop(1, `hsl(${(hue+60)%360},80%,50%)`);
        return g;
      }
    }
    function roundedRect(x,y,w,h,r){
      ctx.beginPath();
      ctx.moveTo(x+r,y);           ctx.lineTo(x+w-r,y);
      ctx.quadraticCurveTo(x+w,y,  x+w,y+r);
      ctx.lineTo(x+w,y+h-r);
      ctx.quadraticCurveTo(x+w,y+h, x+w-r,y+h);
      ctx.lineTo(x+r,y+h);
      ctx.quadraticCurveTo(x,y+h,   x,y+h-r);
      ctx.lineTo(x,y+r);
      ctx.quadraticCurveTo(x,y,     x+r,y);
      ctx.closePath();
      ctx.fill();
    }
    function isEmpty(x,y){
      return !snake.some(s=>s.x===x&&s.y===y)
          && !apples.some(a=>a.x===x&&a.y===y)
          && !powerUps.some(p=>p.x===x&&p.y===y);
    }

    // Apple spawning
    function spawnApples(){
      while(apples.length < maxApples){
        const p = {
          x: Math.floor(Math.random() * tileCount),
          y: Math.floor(Math.random() * tileCount)
        };
        if(isEmpty(p.x, p.y)) apples.push(p);
      }
      
      // Spawn power-up occasionally
      if(Math.random() < 0.15 && !powerUpActive && powerUps.length === 0) {
        const types = ['speed', 'ghost', 'shield'];
        const p = {
          x: Math.floor(Math.random() * tileCount),
          y: Math.floor(Math.random() * tileCount),
          type: types[Math.floor(Math.random() * types.length)]
        };
        if(isEmpty(p.x, p.y)) powerUps.push(p);
      }
    }

    // Effects (score pop‑up, particles, flash)
    function addScoreFx(x,y,amt){
      effects.score.push({
        x: x*gridSize + gridSize/2,
        y: y*gridSize + gridSize/2,
        alpha: 1, text: '+'+amt, size: 24
      });
    }
    function addParticles(x,y, color){
      for(let i=0;i<25;i++){
        effects.particles.push({
          x: x*gridSize + gridSize/2,
          y: y*gridSize + gridSize/2,
          dx: (Math.random()-0.5)*10,
          dy: (Math.random()-0.5)*10,
          alpha: 1, 
          size: Math.random()*6+3,
          color: color || `hsla(${(hue + i*30)%360},100%,70%,1)`
        });
      }
    }
    function updateEffects(){
      // Use reverse loops to safely remove items while iterating
      for(let i=effects.score.length-1; i>=0; i--){
        const e = effects.score[i];
        e.y -= 1.5;
        e.alpha -= 0.02;
        e.size += 0.3;
        if(e.alpha <= 0) effects.score.splice(i,1);
      }
      for(let i=effects.particles.length-1; i>=0; i--){
        const p = effects.particles[i];
        p.x += p.dx;
        p.y += p.dy;
        p.alpha -= 0.03;
        if(!p.color) {
          p.color = `hsla(${(hue + i*30)%360},100%,70%,${p.alpha})`;
        } else {
          p.color = p.color.replace(/[\d\.]+\)$/, p.alpha + ')');
        }
        if(p.alpha <= 0) effects.particles.splice(i,1);
      }
    }
    function flashScore(){
      sb.classList.add('flash');
      setTimeout(()=> sb.classList.remove('flash'), 200);
      try {
        generateEatSound();
      } catch(e) {
        // Audio play might fail if not triggered by user interaction
      }
    }
    
    function flashCombo(){
      sb.classList.add('combo');
      setTimeout(()=> sb.classList.remove('combo'), 500);
    }

    // Game update
    function update(){
      if(gameOver) return;
      
      // Update power-up state
      if(powerUpActive) {
        const timeLeft = powerUpEndTime - Date.now();
        if(timeLeft > 0) {
          powerTimerBar.style.width = (timeLeft / 10000 * 100) + '%';
        } else {
          powerUpActive = false;
          snakeMode = 'normal';
          snakeType.textContent = 'NORMAL';
          snakeType.style.color = '#0ff';
          powerTimer.style.display = 'none';
        }
      }

      // Prevent reversing direction
      if((nextVel.x !== -velocity.x || nextVel.y !== -velocity.y)
       &&(nextVel.x !== velocity.x  || nextVel.y !== velocity.y)) {
        velocity = nextVel;
      }

      const head = {
        x: (snake[0].x + velocity.x + tileCount) % tileCount,
        y: (snake[0].y + velocity.y + tileCount) % tileCount
      };

      // Check collision with self (unless ghost or shield mode)
      if(snakeMode !== 'ghost' && snakeMode !== 'shield' && 
         snake.some((p,i)=>i>0 && p.x===head.x && p.y===head.y)){
        gameOver = true;
        showGameOver();
        return;
      }

      snake.unshift(head);

      let ate = false;
      let powerUpCollected = false;
      
      // Check for apple collision
      for(let i=0; i<apples.length; i++){
        if(apples[i].x===head.x && apples[i].y===head.y){
          const now = Date.now();
          const timeBonus  = (now - lastAppleTime < 3000) ? 5 : 0;
          const comboBonus = comboCounter * 3;
          const gain      = 10 + timeBonus + comboBonus;
          score += gain;
          comboCounter++;
          lastAppleTime = now;
          comboBar.style.width = Math.min(100, comboCounter * 10) + '%';
          if(comboCounter >= 3) {
            flashCombo();
          }
          scoreEl.textContent = score;
          if(score > highScore){
            highScore = score;
            localStorage.setItem('snakeHighScore', highScore);
            highEl.textContent = highScore;
          }
          addScoreFx(head.x, head.y, gain);
          addParticles(head.x, head.y);
          flashScore();
          apples.splice(i,1);
          spawnApples();
          ate = true;
          break;
        }
      }
      
      // Check for power-up collision
      for(let i=0; i<powerUps.length; i++){
        if(powerUps[i].x===head.x && powerUps[i].y===head.y){
          snakeMode = powerUps[i].type;
          powerUpActive = true;
          powerUpEndTime = Date.now() + 10000; // 10 seconds
          snakeType.textContent = snakeMode.toUpperCase();
          
          // Set color based on power-up type
          if(snakeMode === 'speed') snakeType.style.color = '#0f9';
          else if(snakeMode === 'ghost') snakeType.style.color = '#f0f';
          else if(snakeMode === 'shield') snakeType.style.color = '#0ff';
          
          // Show power timer
          powerTimer.style.display = 'block';
          powerTimerBar.style.width = '100%';
          
          addParticles(
            head.x, 
            head.y, 
            snakeMode === 'speed' ? 'rgba(0,255,150,1)' : 
            snakeMode === 'ghost' ? 'rgba(255,0,200,1)' : 
            'rgba(0,200,255,1)'
          );
          
          try {
            generatePowerSound();
          } catch(e) {}
          
          powerUps.splice(i,1);
          powerUpCollected = true;
          break;
        }
      }
      
      if(!ate && !powerUpCollected){
        comboCounter = 0;
        comboBar.style.width = '0%';
        snake.pop();
      }
      
      // Adjust speed based on power-up
      const speedMultiplier = snakeMode === 'speed' ? 1.7 : 1;
      const adjustedInterval = interval / speedMultiplier;
      if(delta >= adjustedInterval) {
        delta -= adjustedInterval;
      }
    }

    // Draw
    function draw(){
      ctx.clearRect(0, 0, canvas.width, canvas.height);

      // Draw background grid
      ctx.strokeStyle = 'rgba(0, 200, 180, 0.1)';
      ctx.lineWidth = 1;
      for(let i=0; i<=tileCount; i++){
        const pos = i * gridSize;
        ctx.beginPath();
        ctx.moveTo(pos, 0);
        ctx.lineTo(pos, canvas.height);
        ctx.moveTo(0, pos);
        ctx.lineTo(canvas.width, pos);
        ctx.stroke();
      }

      // Draw glow particles background
      const time = Date.now() * 0.001;
      for(let i=0; i<30; i++){
        const x = (Math.sin(time * 0.2 + i * 0.7) * 0.5 + 0.5) * canvas.width;
        const y = (Math.cos(time * 0.3 + i * 0.5) * 0.5 + 0.5) * canvas.height;
        const size = 3 + Math.sin(time + i) * 2;
        const alpha = 0.1 + Math.sin(time * 2 + i) * 0.05;
        const hue = (time * 20 + i * 12) % 360;
        
        ctx.beginPath();
        ctx.arc(x, y, size, 0, Math.PI * 2);
        ctx.fillStyle = `hsla(${hue}, 100%, 70%, ${alpha})`;
        ctx.fill();
      }

      // power-ups
      powerUps.forEach(p=>{
        const cx = p.x*gridSize + gridSize/2;
        const cy = p.y*gridSize + gridSize/2;
        ctx.save();
        ctx.translate(cx, cy);
        ctx.rotate(Date.now() * 0.002);
        ctx.shadowColor = p.type === 'speed' ? '#0f9' : p.type === 'ghost' ? '#f0f' : '#0ff';
        ctx.shadowBlur = 20;
        
        if(p.type === 'speed') {
          // Lightning bolt
          ctx.fillStyle = '#0ff';
          ctx.beginPath();
          ctx.moveTo(0, -gridSize*0.3);
          ctx.lineTo(gridSize*0.25, 0);
          ctx.lineTo(0, gridSize*0.3);
          ctx.lineTo(-gridSize*0.25, 0);
          ctx.closePath();
          ctx.fill();
        } else if(p.type === 'ghost') {
          // Ghost
          ctx.fillStyle = '#f0f';
          ctx.beginPath();
          ctx.arc(0, 0, gridSize*0.3, 0, Math.PI);
          ctx.lineTo(gridSize*0.3, gridSize*0.3);
          ctx.quadraticCurveTo(gridSize*0.1, gridSize*0.5, 0, gridSize*0.3);
          ctx.quadraticCurveTo(-gridSize*0.1, gridSize*0.5, -gridSize*0.3, gridSize*0.3);
          ctx.closePath();
          ctx.fill();
          
          // Eyes
          ctx.fillStyle = '#000';
          ctx.beginPath();
          ctx.arc(-gridSize*0.1, -gridSize*0.1, gridSize*0.07, 0, Math.PI*2);
          ctx.arc(gridSize*0.1, -gridSize*0.1, gridSize*0.07, 0, Math.PI*2);
          ctx.fill();
        } else {
          // Shield
          ctx.fillStyle = '#0ff';
          ctx.beginPath();
          ctx.arc(0, 0, gridSize*0.35, 0, Math.PI*2);
          ctx.fill();
          
          ctx.fillStyle = '#111';
          ctx.beginPath();
          ctx.arc(0, 0, gridSize*0.25, 0, Math.PI*2);
          ctx.fill();
          
          ctx.strokeStyle = '#0ff';
          ctx.lineWidth = 3;
          ctx.beginPath();
          ctx.arc(0, 0, gridSize*0.3, 0, Math.PI*2);
          ctx.stroke();
        }
        
        ctx.restore();
      });

      // apples
      apples.forEach(a=>{
        const cx = a.x*gridSize + gridSize/2;
        const cy = a.y*gridSize + gridSize/2;
        ctx.save();
        ctx.translate(cx, cy);
        const scale = 0.9 + 0.1 * Math.sin(Date.now() / 200);
        ctx.scale(scale, scale);
        ctx.shadowColor = '#f44';
        ctx.shadowBlur = 18;
        ctx.fillStyle = colorGradient(false);
        ctx.beginPath();
        ctx.ellipse(0,0, gridSize*0.4, gridSize*0.55, Math.PI/6, 0, 2*Math.PI);
        ctx.fill();
        ctx.fillStyle = '#282';
        ctx.beginPath();
        ctx.ellipse(0, -gridSize*0.3, gridSize*0.15, gridSize*0.3, Math.PI/4, 0, 2*Math.PI);
        ctx.fill();
        ctx.restore();
      });

      // snake
      snake.forEach((s,i)=>{
        const px = s.x*gridSize, py = s.y*gridSize;
        ctx.save();
        
        // Head is brighter, tail is darker
        const alpha = 1 - (i / snake.length) * 0.7;
        ctx.globalAlpha = alpha;
        
        ctx.fillStyle = colorGradient(true);
        
        // Different colors for different modes
        if(snakeMode === 'speed') {
          ctx.fillStyle = `hsl(${(hue + i*10) % 360}, 100%, 60%)`;
        } else if(snakeMode === 'ghost') {
          ctx.fillStyle = `hsla(${(hue + 240 + i*10) % 360}, 100%, 70%, ${alpha})`;
        } else if(snakeMode === 'shield') {
          ctx.fillStyle = `hsla(${(hue + 180 + i*10) % 360}, 100%, 60%, ${alpha})`;
        }
        
        ctx.shadowColor = snakeMode === 'ghost' ? '#f0f' : 
                          snakeMode === 'shield' ? '#0ff' : '#0ff';
        ctx.shadowBlur = (i===0 ? 25 : 18);
        
        // Draw rounded rectangle for snake segment
        roundedRect(px+2, py+2, gridSize-4, gridSize-4, 8);
        
        // Draw eyes on head
        if(i === 0) {
          ctx.fillStyle = '#000';
          ctx.globalAlpha = 1;
          const eyeSize = gridSize * 0.15;
          
          // Left eye
          ctx.beginPath();
          ctx.arc(
            px + gridSize * 0.3, 
            py + gridSize * 0.4, 
            eyeSize, 0, Math.PI*2
          );
          ctx.fill();
          
          // Right eye
          ctx.beginPath();
          ctx.arc(
            px + gridSize * 0.7, 
            py + gridSize * 0.4, 
            eyeSize, 0, Math.PI*2
          );
          ctx.fill();
          
          // Pupils
          ctx.fillStyle = '#fff';
          const pupilOffsetX = velocity.x * eyeSize * 0.5;
          const pupilOffsetY = velocity.y * eyeSize * 0.5;
          
          ctx.beginPath();
          ctx.arc(
            px + gridSize * 0.3 + pupilOffsetX, 
            py + gridSize * 0.4 + pupilOffsetY, 
            eyeSize * 0.5, 0, Math.PI*2
          );
          ctx.fill();
          
          ctx.beginPath();
          ctx.arc(
            px + gridSize * 0.7 + pupilOffsetX, 
            py + gridSize * 0.4 + pupilOffsetY, 
            eyeSize * 0.5, 0, Math.PI*2
          );
          ctx.fill();
        }
        
        ctx.restore();
      });

      // effects
      effects.particles.forEach(p=>{
        ctx.fillStyle = p.color;
        ctx.beginPath();
        ctx.arc(p.x, p.y, p.size, 0, 2*Math.PI);
        ctx.fill();
      });
      effects.score.forEach(e=>{
        ctx.fillStyle = `rgba(0,255,150,${e.alpha})`;
        ctx.font = `bold ${e.size}px 'Rajdhani', 'Segoe UI', sans-serif`;
        ctx.textAlign = 'center';
        ctx.shadowColor = '#0f9';
        ctx.shadowBlur = 10;
        ctx.fillText(e.text, e.x, e.y);
      });
      
      // Draw shield effect if active
      if(snakeMode === 'shield') {
        const head = snake[0];
        const cx = head.x * gridSize + gridSize/2;
        const cy = head.y * gridSize + gridSize/2;
        
        ctx.save();
        ctx.beginPath();
        ctx.arc(cx, cy, gridSize * 0.8, 0, Math.PI * 2);
        ctx.strokeStyle = 'rgba(0, 200, 255, 0.5)';
        ctx.lineWidth = 3;
        ctx.shadowColor = '#0ff';
        ctx.shadowBlur = 20;
        ctx.stroke();
        ctx.restore();
      }
    }

    // Input handling
    let touchStart = null;
    const minSwipe = 30;

    canvas.addEventListener('touchstart', e=>{
      if(e.touches.length === 1) {
        touchStart = { x: e.touches[0].clientX, y: e.touches[0].clientY };
      }
    }, { passive: true });

    canvas.addEventListener('touchmove', e=>{
      if(!touchStart) return;
      const dx = e.touches[0].clientX - touchStart.x;
      const dy = e.touches[0].clientY - touchStart.y;
      if(Math.abs(dx) > minSwipe || Math.abs(dy) > minSwipe){
        const dir = Math.abs(dx) > Math.abs(dy) ? (dx > 0 ? 'right' : 'left') : (dy > 0 ? 'down' : 'up');
        changeDir(dir);
        touchStart = null;
      }
    }, { passive: true });

    canvas.addEventListener('touchend', () => { touchStart = null; });

    btns.forEach(b => b.addEventListener('click', () => changeDir(b.dataset.dir)));

    // Keyboard support: arrows + WASD
    window.addEventListener('keydown', e => {
      if(gameOver) return; // ignore input if game over
      const keyMap = {
        ArrowUp: 'up',
        ArrowDown: 'down',
        ArrowLeft: 'left',
        ArrowRight: 'right',
        w: 'up',
        s: 'down',
        a: 'left',
        d: 'right'
      };
      const dir = keyMap[e.key];
      if(dir) {
        e.preventDefault();
        changeDir(dir);
      }
    });

    function changeDir(dir){
      const map = { up:{x:0,y:-1}, down:{x:0,y:1}, left:{x:-1,y:0}, right:{x:1,y:0} };
      const nv = map[dir];
      if(nv && (nv.x !== -velocity.x || nv.y !== -velocity.y)) nextVel = nv;
    }

    // Game over UI and restart
    function showGameOver(){
      try {
        generateGameOverSound();
      } catch(e) {}
      
      setTimeout(() => {
        finalScore.textContent = score;
        gameOverScreen.classList.add('show');
        restartBtn.style.display = 'block';
        restartBtn.focus();
      }, 100);
    }

    restartBtn.addEventListener('click', () => {
      initGame();
    });
    
    restartBtn2.addEventListener('click', () => {
      initGame();
    });

    // Main loop with fixed FPS using delta accumulator
    let lastTime = 0;
    let delta = 0;
    const interval = 1000 / fps;

    function loop(ts=0){
      if(!lastTime) lastTime = ts;
      delta += ts - lastTime;
      lastTime = ts;

      while(delta >= interval){
        update();
        updateEffects();
        delta -= interval;
      }
      draw();
      requestAnimationFrame(loop);
    }

    // Start game
    initGame();
    requestAnimationFrame(loop);
  })();
  </script>
</body>
</html>