// peper-snake.jsx, klassieke Snake-variant met Hete Peper als slang-kop.
// Eet pepertjes om te groeien, ontwijk de muren en jezelf. Power-pepers
// geven kort onkwetsbaarheid. Touch (swipe of richtingknoppen) of pijltjes.

function PeperSnake({ onClose }) {
  const COLS = 22;
  const ROWS = 22;
  const CELL = 28;
  const FIELD_W = COLS * CELL;
  const FIELD_H = ROWS * CELL;
  const BASE_TICK = 0.16;          // seconden per stap, daalt met score
  const MIN_TICK = 0.07;
  const POWER_DURATION = 4;        // seconden onkwetsbaar
  const OBSTACLE_COUNT = 6;

  const STORAGE_KEY = "peper-snake-best";

  const [phase, setPhase] = React.useState("intro");
  const [score, setScore] = React.useState(0);
  const [best, setBest] = React.useState(() => {
    try { return parseInt(localStorage.getItem(STORAGE_KEY) || "0", 10) || 0; } catch { return 0; }
  });
  const [scale, setScale] = React.useState(1);
  const [narrow, setNarrow] = React.useState(typeof window !== "undefined" && window.innerWidth <= 600);
  const [, forceRender] = React.useReducer(x => x + 1, 0);

  const wrapRef = React.useRef(null);
  const snakeRef = React.useRef([]);          // [{x,y}], 0 = head
  const dirRef = React.useRef({ x: 1, y: 0 });
  const nextDirRef = React.useRef({ x: 1, y: 0 });
  const foodRef = React.useRef(null);
  const powerRef = React.useRef(null);
  const obstaclesRef = React.useRef([]);
  const tickAccRef = React.useRef(0);
  const lastFrameRef = React.useRef(0);
  const invincibleRef = React.useRef(0);
  const flashRef = React.useRef(0);
  const eatBumpRef = React.useRef(0);
  const fliesRef = React.useRef([]);
  const trailRef = React.useRef([]);   // [{x,y,life}]
  const animTimeRef = React.useRef(0);

  // schaling
  React.useEffect(() => {
    function measure() {
      setNarrow(window.innerWidth <= 600);
      if (!wrapRef.current) return;
      const r = wrapRef.current.getBoundingClientRect();
      if (r.width > 0 && r.height > 0) {
        setScale(Math.max(0.3, Math.min(r.width / FIELD_W, r.height / FIELD_H)));
      }
    }
    measure();
    let ro;
    if (typeof ResizeObserver !== "undefined" && wrapRef.current) {
      ro = new ResizeObserver(measure);
      ro.observe(wrapRef.current);
    }
    window.addEventListener("resize", measure);
    window.addEventListener("orientationchange", measure);
    return () => {
      if (ro) ro.disconnect();
      window.removeEventListener("resize", measure);
      window.removeEventListener("orientationchange", measure);
    };
  }, []);

  // body-scroll vergrendelen
  React.useEffect(() => {
    const prev = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    return () => { document.body.style.overflow = prev; };
  }, []);

  // toetsen: pijltjes, WASD, ESC
  React.useEffect(() => {
    function onKey(e) {
      if (e.key === "Escape") { onClose && onClose(); return; }
      const map = {
        ArrowUp: { x: 0, y: -1 }, w: { x: 0, y: -1 }, W: { x: 0, y: -1 },
        ArrowDown: { x: 0, y: 1 }, s: { x: 0, y: 1 }, S: { x: 0, y: 1 },
        ArrowLeft: { x: -1, y: 0 }, a: { x: -1, y: 0 }, A: { x: -1, y: 0 },
        ArrowRight: { x: 1, y: 0 }, d: { x: 1, y: 0 }, D: { x: 1, y: 0 },
      };
      const d = map[e.key];
      if (d) { e.preventDefault(); turn(d); return; }
      if (e.key === " " || e.key === "Enter") {
        e.preventDefault();
        if (phase === "intro") start();
        else if (phase === "dead") restart();
      }
    }
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [phase]);

  function turn(d) {
    const cur = dirRef.current;
    if (d.x === -cur.x && d.y === -cur.y) return; // niet 180° op zichzelf
    nextDirRef.current = d;
  }

  function randCell() {
    return { x: Math.floor(Math.random() * COLS), y: Math.floor(Math.random() * ROWS) };
  }

  function cellOccupied(c) {
    if (snakeRef.current.some(s => s.x === c.x && s.y === c.y)) return true;
    if (obstaclesRef.current.some(o => o.x === c.x && o.y === c.y)) return true;
    if (foodRef.current && foodRef.current.x === c.x && foodRef.current.y === c.y) return true;
    if (powerRef.current && powerRef.current.x === c.x && powerRef.current.y === c.y) return true;
    return false;
  }

  function spawnFood() {
    for (let i = 0; i < 60; i++) {
      const c = randCell();
      if (!cellOccupied(c)) { foodRef.current = c; return; }
    }
  }

  function maybeSpawnPower() {
    if (powerRef.current) return;
    if (Math.random() > 0.16) return;
    for (let i = 0; i < 40; i++) {
      const c = randCell();
      if (!cellOccupied(c)) {
        powerRef.current = { ...c, life: 9 }; // verdwijnt na 9 seconden
        return;
      }
    }
  }

  function placeObstacles() {
    const arr = [];
    const startY = Math.floor(ROWS / 2);
    for (let i = 0; i < OBSTACLE_COUNT; i++) {
      for (let tries = 0; tries < 60; tries++) {
        const c = randCell();
        // veilige startbaan: hele rij waarop slang begint + buffer ervoor
        if (c.y >= startY - 2 && c.y <= startY + 2 && c.x < 14) continue;
        if (snakeRef.current.some(s => s.x === c.x && s.y === c.y)) continue;
        if (arr.some(o => Math.abs(o.x - c.x) + Math.abs(o.y - c.y) < 2)) continue;
        arr.push(c);
        break;
      }
    }
    obstaclesRef.current = arr;
  }

  function reset() {
    const startY = Math.floor(ROWS / 2);
    snakeRef.current = [
      { x: 5, y: startY },
      { x: 4, y: startY },
      { x: 3, y: startY },
    ];
    dirRef.current = { x: 1, y: 0 };
    nextDirRef.current = { x: 1, y: 0 };
    powerRef.current = null;
    invincibleRef.current = 0;
    flashRef.current = 0;
    eatBumpRef.current = 0;
    tickAccRef.current = 0;
    trailRef.current = [];
    fliesRef.current = Array.from({ length: 14 }, () => ({
      x: Math.random() * FIELD_W,
      y: Math.random() * FIELD_H,
      vx: (Math.random() - 0.5) * 18,
      vy: (Math.random() - 0.5) * 14,
      ph: Math.random() * Math.PI * 2,
      r: 1.5 + Math.random() * 1.5,
    }));
    setScore(0);
    placeObstacles();
    spawnFood();
  }

  function start() { reset(); setPhase("playing"); }
  function restart() { reset(); setPhase("playing"); }

  function currentTick() {
    const s = scoreRefVal.current;
    return Math.max(MIN_TICK, BASE_TICK - s * 0.0035);
  }

  // huidige score-ref voor in de loop
  const scoreRefVal = React.useRef(0);
  React.useEffect(() => { scoreRefVal.current = score; }, [score]);

  function step() {
    dirRef.current = nextDirRef.current;
    const head = snakeRef.current[0];
    const nx = head.x + dirRef.current.x;
    const ny = head.y + dirRef.current.y;
    const newHead = { x: nx, y: ny };

    const hitWall = nx < 0 || ny < 0 || nx >= COLS || ny >= ROWS;
    const hitSelf = snakeRef.current.some((s, i) => i > 0 && s.x === nx && s.y === ny);
    const hitObst = obstaclesRef.current.some(o => o.x === nx && o.y === ny);

    if ((hitWall || hitObst) && invincibleRef.current <= 0) {
      die();
      return;
    }
    if (hitSelf) {
      die();
      return;
    }
    // bij wand-doorgaan tijdens onkwetsbaar: wrap
    if (invincibleRef.current > 0 && hitWall) {
      newHead.x = (nx + COLS) % COLS;
      newHead.y = (ny + ROWS) % ROWS;
    }
    if (invincibleRef.current > 0 && hitObst) {
      // smelten van obstakel
      obstaclesRef.current = obstaclesRef.current.filter(o => !(o.x === nx && o.y === ny));
      flashRef.current = 0.5;
    }

    snakeRef.current = [newHead, ...snakeRef.current];

    // food?
    if (foodRef.current && foodRef.current.x === newHead.x && foodRef.current.y === newHead.y) {
      foodRef.current = null;
      eatBumpRef.current = 1;
      setScore(s => s + 1);
      spawnFood();
      maybeSpawnPower();
    } else {
      snakeRef.current.pop();
    }

    // power?
    if (powerRef.current && powerRef.current.x === newHead.x && powerRef.current.y === newHead.y) {
      powerRef.current = null;
      invincibleRef.current = POWER_DURATION;
      flashRef.current = 1;
    }
  }

  function die() {
    flashRef.current = 1;
    setBest(prev => {
      const nv = scoreRefVal.current;
      if (nv > prev) {
        try { localStorage.setItem(STORAGE_KEY, String(nv)); } catch {}
        return nv;
      }
      return prev;
    });
    setPhase("dead");
  }

  // game loop
  React.useEffect(() => {
    if (phase !== "playing") return;
    let raf = 0;
    lastFrameRef.current = performance.now();
    function frame(ts) {
      const dt = Math.min(0.05, (ts - lastFrameRef.current) / 1000);
      lastFrameRef.current = ts;
      tickAccRef.current += dt;
      const tick = currentTick();
      while (tickAccRef.current >= tick) {
        tickAccRef.current -= tick;
        step();
        if (phase !== "playing") break;
      }
      invincibleRef.current = Math.max(0, invincibleRef.current - dt);
      flashRef.current = Math.max(0, flashRef.current - dt * 1.6);
      eatBumpRef.current = Math.max(0, eatBumpRef.current - dt * 3);
      animTimeRef.current += dt;
      if (powerRef.current) {
        powerRef.current.life -= dt;
        if (powerRef.current.life <= 0) powerRef.current = null;
      }
      // fireflies driften langzaam rond
      for (const f of fliesRef.current) {
        f.x += f.vx * dt;
        f.y += f.vy * dt;
        f.ph += dt * 3;
        if (f.x < 0) f.x = FIELD_W; if (f.x > FIELD_W) f.x = 0;
        if (f.y < 0) f.y = FIELD_H; if (f.y > FIELD_H) f.y = 0;
      }
      // motion-trail decay
      trailRef.current = trailRef.current
        .map(t => ({ ...t, life: t.life - dt * 1.2 }))
        .filter(t => t.life > 0);
      // trail toevoegen aan kop
      const head = snakeRef.current[0];
      if (head && Math.random() < 0.6) {
        trailRef.current.push({
          x: head.x * CELL + CELL / 2 + (Math.random() - 0.5) * 6,
          y: head.y * CELL + CELL / 2 + (Math.random() - 0.5) * 6,
          life: 1,
          r: 4 + Math.random() * 3,
        });
      }
      forceRender();
      raf = requestAnimationFrame(frame);
    }
    raf = requestAnimationFrame(frame);
    return () => cancelAnimationFrame(raf);
  }, [phase]);

  // swipe-controls op het speelveld
  const touchStartRef = React.useRef(null);
  function onTouchStart(e) {
    const t = e.touches ? e.touches[0] : e;
    touchStartRef.current = { x: t.clientX, y: t.clientY };
  }
  function onTouchEnd(e) {
    const start = touchStartRef.current;
    if (!start) return;
    const t = e.changedTouches ? e.changedTouches[0] : e;
    const dx = t.clientX - start.x;
    const dy = t.clientY - start.y;
    const adx = Math.abs(dx), ady = Math.abs(dy);
    if (Math.max(adx, ady) < 18) return;
    if (adx > ady) turn({ x: dx > 0 ? 1 : -1, y: 0 });
    else turn({ x: 0, y: dy > 0 ? 1 : -1 });
    touchStartRef.current = null;
  }

  function pad(dx, dy) { turn({ x: dx, y: dy }); }

  const inv = invincibleRef.current;
  const flash = flashRef.current;
  const bump = eatBumpRef.current;

  return (
    <div style={{
      position: "fixed", inset: 0, zIndex: 200,
      background: "#0F2A18",
      fontFamily: "'Patrick Hand', cursive",
      color: "#1A1A1A",
      display: "flex", flexDirection: "column",
      overscrollBehavior: "contain",
      touchAction: "none",
    }}>
      <div style={{
        flexShrink: 0,
        display: "flex", alignItems: "center", justifyContent: "space-between",
        padding: narrow ? "8px 10px" : "10px 16px",
        gap: 8,
        background: "rgba(255,245,220,0.96)",
        borderBottom: "3px solid #1A1A1A",
      }}>
        <div style={{
          fontFamily: "'Bangers', sans-serif",
          fontSize: narrow ? 22 : 28, letterSpacing: "0.04em",
          color: "#3FA34D",
          WebkitTextStroke: "1.2px #1A1A1A",
          textShadow: "2px 2px 0 #1A1A1A",
          display: "flex", alignItems: "center", gap: 6,
          whiteSpace: "nowrap",
        }}>
          <span style={{ fontSize: narrow ? 20 : 24, WebkitTextStroke: 0, textShadow: "none" }}>🐍</span>
          {narrow ? "SNAKE" : "PEPER SNAKE"}
        </div>
        <div style={{ display: "flex", alignItems: "center", gap: narrow ? 6 : 10 }}>
          <Pill bg="#FFD23F" color="#1A1A1A" narrow={narrow}>🌶️ {score}</Pill>
          <Pill bg="#FF8C1A" color="#FFF" narrow={narrow}>🏆 {best}</Pill>
          <button onClick={onClose} aria-label="Sluiten" style={{
            width: 44, height: 44, borderRadius: "50%",
            background: "#1A1A1A", color: "#F0FAE6",
            border: "3px solid #F0FAE6", boxShadow: "2px 2px 0 #1A1A1A",
            fontFamily: "'Bangers', sans-serif", fontSize: 22,
            cursor: "pointer", flexShrink: 0,
          }}>✕</button>
        </div>
      </div>

      <div ref={wrapRef} style={{
        flex: 1, position: "relative",
        display: "flex", alignItems: "center", justifyContent: "center",
        padding: 6, overflow: "hidden",
      }}>
        <div style={{ width: FIELD_W * scale, height: FIELD_H * scale, position: "relative" }}
          onPointerDown={onTouchStart}
          onPointerUp={onTouchEnd}
        >
          <svg
            viewBox={`0 0 ${FIELD_W} ${FIELD_H}`}
            width={FIELD_W * scale}
            height={FIELD_H * scale}
            style={{
              display: "block",
              border: "4px solid #1A1A1A",
              boxShadow: "0 0 30px rgba(63, 163, 77, 0.4), 5px 5px 0 #1A1A1A",
              touchAction: "none", userSelect: "none",
            }}>
            <defs>
              <radialGradient id="ps-bg" cx="0.5" cy="0.5" r="0.7">
                <stop offset="0%" stopColor="#0F3D24" />
                <stop offset="60%" stopColor="#0A2418" />
                <stop offset="100%" stopColor="#04120D" />
              </radialGradient>
              <radialGradient id="ps-power" cx="0.5" cy="0.5" r="0.5">
                <stop offset="0%" stopColor="#FFFAE0" />
                <stop offset="40%" stopColor="#FFD23F" />
                <stop offset="100%" stopColor="#FF8C1A" />
              </radialGradient>
              <radialGradient id="ps-power-halo" cx="0.5" cy="0.5" r="0.5">
                <stop offset="0%" stopColor="rgba(255, 210, 63, 0.6)" />
                <stop offset="100%" stopColor="rgba(255, 210, 63, 0)" />
              </radialGradient>
              <radialGradient id="ps-food-halo" cx="0.5" cy="0.5" r="0.5">
                <stop offset="0%" stopColor="rgba(230, 57, 70, 0.55)" />
                <stop offset="100%" stopColor="rgba(230, 57, 70, 0)" />
              </radialGradient>
              <radialGradient id="ps-trail" cx="0.5" cy="0.5" r="0.5">
                <stop offset="0%" stopColor="rgba(255, 200, 100, 0.7)" />
                <stop offset="100%" stopColor="rgba(255, 140, 26, 0)" />
              </radialGradient>
              <linearGradient id="ps-body" x1="0" y1="0" x2="0" y2="1">
                <stop offset="0%" stopColor="#FF6B5A" />
                <stop offset="100%" stopColor="#A01B26" />
              </linearGradient>
              <linearGradient id="ps-body-inv" x1="0" y1="0" x2="0" y2="1">
                <stop offset="0%" stopColor="#FFE56F" />
                <stop offset="100%" stopColor="#FF8C1A" />
              </linearGradient>
              <linearGradient id="ps-head" x1="0" y1="0" x2="1" y2="1">
                <stop offset="0%" stopColor="#FF8B7A" />
                <stop offset="60%" stopColor="#E63946" />
                <stop offset="100%" stopColor="#7C0F1A" />
              </linearGradient>
              <linearGradient id="ps-ice" x1="0" y1="0" x2="0" y2="1">
                <stop offset="0%" stopColor="#E5F8FF" />
                <stop offset="50%" stopColor="#9CD8F2" />
                <stop offset="100%" stopColor="#3F8AB8" />
              </linearGradient>
              <radialGradient id="ps-vignette" cx="0.5" cy="0.5" r="0.7">
                <stop offset="60%" stopColor="rgba(0,0,0,0)" />
                <stop offset="100%" stopColor="rgba(0,0,0,0.55)" />
              </radialGradient>
              <filter id="ps-glow" x="-50%" y="-50%" width="200%" height="200%">
                <feGaussianBlur stdDeviation="4" result="b" />
                <feMerge><feMergeNode in="b" /><feMergeNode in="SourceGraphic" /></feMerge>
              </filter>
            </defs>

            {/* atmosfeer */}
            <rect x="0" y="0" width={FIELD_W} height={FIELD_H} fill="url(#ps-bg)" />

            {/* subtiel grid */}
            <g opacity="0.18">
              {Array.from({ length: COLS - 1 }).map((_, i) => (
                <line key={`v${i}`} x1={(i + 1) * CELL} y1="0" x2={(i + 1) * CELL} y2={FIELD_H}
                  stroke="#3FA34D" strokeWidth="0.6" />
              ))}
              {Array.from({ length: ROWS - 1 }).map((_, i) => (
                <line key={`h${i}`} x1="0" y1={(i + 1) * CELL} x2={FIELD_W} y2={(i + 1) * CELL}
                  stroke="#3FA34D" strokeWidth="0.6" />
              ))}
            </g>

            {/* fireflies, ambient */}
            {fliesRef.current.map((f, i) => (
              <g key={i}>
                <circle cx={f.x} cy={f.y} r={f.r * 4}
                  fill="#FFE56F"
                  opacity={0.18 + 0.12 * Math.sin(f.ph)} />
                <circle cx={f.x} cy={f.y} r={f.r}
                  fill="#FFFAE0"
                  opacity={0.7 + 0.3 * Math.sin(f.ph)} />
              </g>
            ))}

            {/* motion-trail van de kop */}
            {trailRef.current.map((t, i) => (
              <circle key={i} cx={t.x} cy={t.y} r={t.r * t.life * 1.4}
                fill="url(#ps-trail)" opacity={t.life * 0.7} />
            ))}

            {/* obstakels: ijskristallen met shine */}
            {obstaclesRef.current.map((o, i) => {
              const cx = o.x * CELL + CELL / 2;
              const cy = o.y * CELL + CELL / 2;
              const r = CELL * 0.42;
              return (
                <g key={i}>
                  {/* glow */}
                  <circle cx={cx} cy={cy} r={r * 1.5}
                    fill="rgba(156, 216, 242, 0.25)" />
                  {/* zeshoekig kristal */}
                  <polygon
                    points={[0, 60, 120, 180, 240, 300].map(a => {
                      const rad = a * Math.PI / 180;
                      return `${cx + Math.cos(rad) * r},${cy + Math.sin(rad) * r}`;
                    }).join(" ")}
                    fill="url(#ps-ice)" stroke="#1A1A1A" strokeWidth="2" />
                  {/* shine */}
                  <line x1={cx - r * 0.4} y1={cy - r * 0.2}
                    x2={cx - r * 0.05} y2={cy - r * 0.55}
                    stroke="#FFF" strokeWidth="2.5" strokeLinecap="round" opacity="0.85" />
                  <circle cx={cx - r * 0.5} cy={cy + r * 0.05} r="1.5" fill="#FFF" opacity="0.6" />
                </g>
              );
            })}

            {/* food, pittig pepertje met halo */}
            {foodRef.current && (() => {
              const cx = foodRef.current.x * CELL + CELL / 2;
              const cy = foodRef.current.y * CELL + CELL / 2;
              const pulse = 1 + 0.08 * Math.sin(animTimeRef.current * 6);
              return (
                <g>
                  <circle cx={cx} cy={cy} r={CELL * 0.7 * pulse} fill="url(#ps-food-halo)" />
                  <g transform={`translate(${cx} ${cy}) scale(${pulse})`}>
                    <ellipse cx="0" cy="2" rx={CELL * 0.36} ry={CELL * 0.28}
                      fill="url(#ps-head)" stroke="#1A1A1A" strokeWidth="2" />
                    <ellipse cx={-CELL * 0.10} cy={-CELL * 0.02} rx="3" ry="2.5" fill="#FFF" opacity="0.85" />
                    <ellipse cx={CELL * 0.18} cy={CELL * 0.10} rx="2" ry="1.5" fill="#FFF" opacity="0.5" />
                    <path d={`M 0 ${-CELL * 0.30} q -3 -4 1 -7 q 3 -3 5 0`}
                      stroke="#1F6826" strokeWidth="2" fill="#3FA34D" />
                  </g>
                </g>
              );
            })()}

            {/* power-peper, met roterende ring */}
            {powerRef.current && (() => {
              const cx = powerRef.current.x * CELL + CELL / 2;
              const cy = powerRef.current.y * CELL + CELL / 2;
              const blink = powerRef.current.life < 3
                ? 0.4 + 0.6 * Math.abs(Math.sin(powerRef.current.life * 8))
                : 1;
              const t = animTimeRef.current;
              return (
                <g opacity={blink}>
                  <circle cx={cx} cy={cy} r={CELL * 0.85} fill="url(#ps-power-halo)" />
                  {/* roterende ring */}
                  <circle cx={cx} cy={cy} r={CELL * 0.55}
                    fill="none" stroke="#FFE56F" strokeWidth="2"
                    strokeDasharray="6 4"
                    transform={`rotate(${(t * 60) % 360} ${cx} ${cy})`}
                    opacity="0.85" />
                  <circle cx={cx} cy={cy} r={CELL * 0.4} fill="url(#ps-power)" stroke="#1A1A1A" strokeWidth="2.5" />
                  <text x={cx} y={cy + 2} textAnchor="middle" dominantBaseline="middle"
                    fontSize={CELL * 0.55} fontWeight="bold" fill="#1A1A1A">⚡</text>
                </g>
              );
            })()}

            {/* slang body, glow + gradient + segmentatie */}
            <g filter="url(#ps-glow)">
              {snakeRef.current.map((s, i) => {
                if (i === 0) return null;
                const isInv = inv > 0;
                const fade = Math.max(0.55, 1 - i / Math.max(20, snakeRef.current.length));
                const bodyFill = isInv ? "url(#ps-body-inv)" : "url(#ps-body)";
                const cx = s.x * CELL + CELL / 2;
                const cy = s.y * CELL + CELL / 2;
                const r = CELL * 0.42 * fade;
                return (
                  <g key={i}>
                    <circle cx={cx} cy={cy} r={r}
                      fill={bodyFill} stroke="#1A1A1A" strokeWidth="2" />
                    {/* shine */}
                    <ellipse cx={cx - r * 0.3} cy={cy - r * 0.3}
                      rx={r * 0.4} ry={r * 0.25}
                      fill="#FFF" opacity={isInv ? 0.6 : 0.35} />
                  </g>
                );
              })}
            </g>

            {/* slang head, peper-stijl met glow */}
            {snakeRef.current[0] && (() => {
              const h = snakeRef.current[0];
              const cx = h.x * CELL + CELL / 2;
              const cy = h.y * CELL + CELL / 2;
              const angle = Math.atan2(dirRef.current.y, dirRef.current.x) * 180 / Math.PI;
              const sBump = 1 + bump * 0.18;
              return (
                <g transform={`translate(${cx} ${cy}) rotate(${angle}) scale(${sBump})`}>
                  {/* glow halo */}
                  <ellipse cx="0" cy="0" rx={CELL * 0.85} ry={CELL * 0.7}
                    fill={inv > 0 ? "rgba(255,210,63,0.35)" : "rgba(230,57,70,0.30)"} />
                  {/* steel */}
                  <path d={`M ${-CELL * 0.5} 0 q -4 -5 0 -8 q 4 -3 6 1`}
                    stroke="#1F6826" strokeWidth="2.5" fill="#3FA34D" />
                  {/* peper-romp */}
                  <ellipse cx="2" cy="0" rx={CELL * 0.46} ry={CELL * 0.40}
                    fill={inv > 0 ? "url(#ps-body-inv)" : "url(#ps-head)"}
                    stroke="#1A1A1A" strokeWidth="2.5" />
                  {/* shine */}
                  <ellipse cx={-CELL * 0.10} cy={-CELL * 0.13}
                    rx={CELL * 0.14} ry={CELL * 0.08}
                    fill="#FFF" opacity="0.8" />
                  {/* ogen */}
                  <circle cx={CELL * 0.15} cy={-CELL * 0.16} r={CELL * 0.11} fill="#FFF" stroke="#1A1A1A" strokeWidth="1.5" />
                  <circle cx={CELL * 0.15} cy={CELL * 0.16} r={CELL * 0.11} fill="#FFF" stroke="#1A1A1A" strokeWidth="1.5" />
                  <circle cx={CELL * 0.19} cy={-CELL * 0.16} r={CELL * 0.055} fill="#1A1A1A" />
                  <circle cx={CELL * 0.19} cy={CELL * 0.16} r={CELL * 0.055} fill="#1A1A1A" />
                  <circle cx={CELL * 0.20} cy={-CELL * 0.18} r={CELL * 0.018} fill="#FFF" />
                  <circle cx={CELL * 0.20} cy={CELL * 0.14} r={CELL * 0.018} fill="#FFF" />
                  {/* gespleten tong */}
                  <path d={`M ${CELL * 0.40} 0 l ${CELL * 0.30} -4 m ${-CELL * 0.30} 4 l ${CELL * 0.30} 4`}
                    stroke="#FF6B5A" strokeWidth="2.2" fill="none" strokeLinecap="round" />
                </g>
              );
            })()}

            {/* invincible-ring */}
            {inv > 0 && snakeRef.current[0] && (
              <g>
                <circle
                  cx={snakeRef.current[0].x * CELL + CELL / 2}
                  cy={snakeRef.current[0].y * CELL + CELL / 2}
                  r={CELL * 0.85}
                  fill="none" stroke="#FFD23F" strokeWidth="3"
                  strokeDasharray="8 6"
                  transform={`rotate(${(animTimeRef.current * 120) % 360} ${snakeRef.current[0].x * CELL + CELL / 2} ${snakeRef.current[0].y * CELL + CELL / 2})`}
                  opacity={0.6 + 0.4 * Math.sin(animTimeRef.current * 6)} />
              </g>
            )}

            {/* vignette */}
            <rect x="0" y="0" width={FIELD_W} height={FIELD_H}
              fill="url(#ps-vignette)" pointerEvents="none" />

            {/* flash */}
            {flash > 0 && (
              <rect x="0" y="0" width={FIELD_W} height={FIELD_H}
                fill="#FFF" opacity={flash * 0.55} />
            )}
          </svg>

          {phase === "playing" && inv > 0 && (
            <div style={{
              position: "absolute", top: 8, left: 0, right: 0, textAlign: "center",
              fontFamily: "'Bangers', sans-serif", fontSize: 24 * scale,
              color: "#FFD23F", WebkitTextStroke: `${1.5 * scale}px #1A1A1A`,
              pointerEvents: "none",
            }}>⚡ ONKWETSBAAR · {Math.ceil(inv)}s</div>
          )}

          {phase === "intro" && (
            <Overlay>
              <Title color="#3FA34D">PEPER SNAKE</Title>
              <p style={overlayText}>
                Veeg of gebruik <strong>pijltjes</strong>/<strong>WASD</strong> om te draaien.
                Eet pepertjes om te groeien, ontwijk de muren, ijsblokken en jezelf!
                ⚡-pepers maken je kort onkwetsbaar.
              </p>
              <BigBtn onClick={start} color="#5BB85B">▶ START</BigBtn>
            </Overlay>
          )}

          {phase === "dead" && (
            <Overlay>
              <Title color="#E63946">GAME OVER!</Title>
              <p style={overlayText}>
                Je at <strong>{score}</strong> {score === 1 ? "pepertje" : "pepertjes"}.
                {score >= best && score > 0 && <><br /><span style={{ color: "#FF8C1A", fontWeight: "bold" }}>🏆 NIEUW RECORD!</span></>}
                {score < best && <><br />Beste: <strong>{best}</strong></>}
              </p>
              <BigBtn onClick={restart} color="#5BB85B">↻ NOG EENS</BigBtn>
            </Overlay>
          )}
        </div>
      </div>

      {phase === "playing" && (
        <div style={{
          flexShrink: 0,
          display: narrow ? "grid" : "none",
          gridTemplateColumns: "1fr 1fr 1fr",
          gridTemplateRows: "1fr 1fr",
          gap: 6, padding: 10,
          background: "rgba(255,245,220,0.96)",
          borderTop: "3px solid #1A1A1A",
          touchAction: "none",
        }}>
          <DirBtn onClick={() => pad(0, -1)} style={{ gridColumn: "2", gridRow: "1" }}>▲</DirBtn>
          <DirBtn onClick={() => pad(-1, 0)} style={{ gridColumn: "1", gridRow: "2" }}>◀</DirBtn>
          <DirBtn onClick={() => pad(0, 1)} style={{ gridColumn: "2", gridRow: "2" }}>▼</DirBtn>
          <DirBtn onClick={() => pad(1, 0)} style={{ gridColumn: "3", gridRow: "2" }}>▶</DirBtn>
        </div>
      )}
    </div>
  );

  function Pill({ bg, color, narrow, children }) {
    return (
      <span style={{
        background: bg, color, border: "3px solid #1A1A1A",
        boxShadow: "2px 2px 0 #1A1A1A",
        padding: narrow ? "4px 8px" : "6px 12px",
        fontFamily: "'Bangers', sans-serif",
        fontSize: narrow ? 16 : 20, letterSpacing: "0.04em",
      }}>{children}</span>
    );
  }

  function Title({ color, children }) {
    return (
      <div style={{
        fontFamily: "'Bangers', sans-serif", fontSize: 44,
        color, WebkitTextStroke: "1.5px #1A1A1A",
        textShadow: "3px 3px 0 #1A1A1A", letterSpacing: "0.05em",
        textAlign: "center", margin: 0,
      }}>{children}</div>
    );
  }

  function BigBtn({ onClick, color, children }) {
    return (
      <button onClick={onClick} style={{
        background: color, color: "#FFF",
        border: "4px solid #1A1A1A", boxShadow: "4px 4px 0 #1A1A1A",
        fontFamily: "'Bangers', sans-serif", fontSize: 28,
        padding: "10px 28px", cursor: "pointer", letterSpacing: "0.04em",
        marginTop: 8,
      }}>{children}</button>
    );
  }

  function Overlay({ children }) {
    return (
      <div style={{
        position: "absolute", inset: 0,
        background: "rgba(15,42,24,0.85)",
        display: "flex", flexDirection: "column",
        alignItems: "center", justifyContent: "center",
        padding: 20, gap: 12, color: "#FFF8EC",
      }}>{children}</div>
    );
  }

  function DirBtn({ onClick, style, children }) {
    return (
      <button onPointerDown={e => { e.preventDefault(); onClick(); }} style={{
        ...style,
        background: "#FFD23F", border: "3px solid #1A1A1A",
        boxShadow: "3px 3px 0 #1A1A1A",
        fontFamily: "'Bangers', sans-serif", fontSize: 30,
        cursor: "pointer", touchAction: "none",
        minHeight: 56,
      }}>{children}</button>
    );
  }
}

const overlayText = {
  fontSize: 19, lineHeight: 1.5, maxWidth: 460, textAlign: "center",
  color: "#FFF8EC", margin: 0,
};

Object.assign(window, { PeperSnake });
