// ——— The Game Of Chess — main game component ———
// Depends on ChessEngine.jsx, ChessAI.jsx, ChessScreens.jsx (loaded first).
// Human plays White (bottom); computer plays Black.

const CHESS_SAVE_KEY = 'chess_save_v1';

function chessDefaults() {
  return {
    level: 1,
    sound: true,
    stats: {
      played: 0, wins: 0, losses: 0, draws: 0,
      highestBeaten: 0, totalPoints: 0, streak: 0, bestStreak: 0,
    },
    game: null, // serialized active match for resume
  };
}
function chessLoad() {
  try {
    const raw = JSON.parse(localStorage.getItem(CHESS_SAVE_KEY) || '{}');
    const d = chessDefaults();
    return { ...d, ...raw, stats: { ...d.stats, ...(raw.stats || {}) } };
  } catch { return chessDefaults(); }
}
function chessSave(d) { try { localStorage.setItem(CHESS_SAVE_KEY, JSON.stringify(d)); } catch {} }

// ——— game object builders ———
function chMakeGame(state, level, history, capW, capB, repMap, last) {
  return {
    state, level, history, capW, capB, repMap, last,
    legal: chLegalMoves(state),
    status: chStatus(state, repMap),
  };
}
function chNewMatch(level) {
  const st = chNewGame();
  const repMap = {}; repMap[chPosKey(st)] = 1;
  return chMakeGame(st, level, [], [], [], repMap, null);
}
function chApplyMove(g, mv) {
  const san = chSAN(g.state, mv);
  const ns = chMakeMove(g.state, mv);
  const capW = g.capW.slice(), capB = g.capB.slice();
  if (mv.captured) { (g.state.turn === 'w' ? capW : capB).push(mv.captured); }
  const repMap = { ...g.repMap };
  const key = chPosKey(ns); repMap[key] = (repMap[key] || 0) + 1;
  const history = g.history.concat([{ san, from: mv.from, to: mv.to, flag: mv.flag }]);
  return chMakeGame(ns, g.level, history, capW, capB, repMap, { from: mv.from, to: mv.to });
}
function chSnap(g) {
  return {
    state: chClone(g.state), level: g.level, history: g.history.slice(),
    capW: g.capW.slice(), capB: g.capB.slice(), repMap: { ...g.repMap }, last: g.last,
  };
}
function chRestore(s) {
  return chMakeGame(s.state, s.level, s.history, s.capW, s.capB, s.repMap, s.last);
}

// ——— tiny WebAudio sound engine ———
const chAudio = (function () {
  let ctx = null;
  function ac() { if (ctx) return ctx; try { ctx = new (window.AudioContext || window.webkitAudioContext)(); } catch (e) { ctx = null; } return ctx; }
  function tone(freq, dur, type, vol, when) {
    const c = ac(); if (!c) return;
    const t = c.currentTime + (when || 0);
    const o = c.createOscillator(), g = c.createGain();
    o.type = type || 'sine'; o.frequency.setValueAtTime(freq, t);
    o.connect(g); g.connect(c.destination);
    g.gain.setValueAtTime(0.0001, t);
    g.gain.exponentialRampToValueAtTime(vol || 0.16, t + 0.01);
    g.gain.exponentialRampToValueAtTime(0.0001, t + dur);
    o.start(t); o.stop(t + dur + 0.02);
  }
  function arp(freqs, step, type, vol) { freqs.forEach((f, i) => tone(f, step * 1.8, type || 'triangle', vol || 0.15, i * step)); }
  function resume() { const c = ac(); if (c && c.state === 'suspended') { try { c.resume(); } catch (e) {} } }
  return { resume, tone, arp };
})();
function chPlay(name, muted) {
  if (muted) return;
  try {
    chAudio.resume();
    switch (name) {
      case 'move':    chAudio.tone(220, 0.08, 'sine', 0.16); chAudio.tone(180, 0.10, 'triangle', 0.10, 0.02); break;
      case 'capture': chAudio.tone(150, 0.10, 'sawtooth', 0.16); chAudio.tone(90, 0.14, 'square', 0.10, 0.02); break;
      case 'castle':  chAudio.tone(260, 0.08, 'triangle', 0.13); chAudio.tone(330, 0.09, 'triangle', 0.12, 0.07); break;
      case 'check':   chAudio.tone(880, 0.10, 'square', 0.12); chAudio.tone(1180, 0.12, 'square', 0.10, 0.07); break;
      case 'select':  chAudio.tone(520, 0.05, 'sine', 0.07); break;
      case 'win':     chAudio.arp([523, 659, 784, 1046, 1318], 0.10, 'triangle', 0.16); break;
      case 'lose':    chAudio.arp([523, 440, 349, 262], 0.13, 'sine', 0.15); break;
      case 'draw':    chAudio.arp([440, 523, 440], 0.12, 'triangle', 0.12); break;
      case 'ui':      chAudio.tone(480, 0.06, 'sine', 0.08); break;
      default: break;
    }
  } catch (e) {}
}

// ——— board square colours (classic wood) ———
const CH_LIGHT = '#f0d8b6';
const CH_DARK = '#b3835b';

function ChessGame() {
  const [data, setData] = React.useState(chessLoad);
  const [screen, setScreen] = React.useState('menu'); // menu | play | stats | over
  const [game, setGame] = React.useState(null);
  const [selected, setSelected] = React.useState(null);
  const [promo, setPromo] = React.useState(null);   // {from, to, options:[moves]}
  const [thinking, setThinking] = React.useState(false);
  const [drag, setDrag] = React.useState(null);     // {pc, x, y}
  const [over, setOver] = React.useState(null);     // {outcome, reason, points, level, moves}
  const [cellPx, setCellPx] = React.useState(50);
  const [toast, setToast] = React.useState(null);

  const gameRef = React.useRef(game);
  const undoRef = React.useRef([]);
  const thinkingRef = React.useRef(false);
  const dragRef = React.useRef(null);
  const boardRef = React.useRef(null);

  const muted = !data.sound;
  const commitGame = React.useCallback((g) => { gameRef.current = g; setGame(g); }, []);

  // measure board → cell size for crisp piece scaling
  React.useEffect(() => {
    if (!boardRef.current || screen !== 'play') return;
    const el = boardRef.current;
    const update = () => setCellPx(el.getBoundingClientRect().width / 8);
    update();
    let ro; if (window.ResizeObserver) { ro = new ResizeObserver(update); ro.observe(el); }
    window.addEventListener('resize', update);
    return () => { if (ro) ro.disconnect(); window.removeEventListener('resize', update); };
  }, [screen]);

  // persist
  React.useEffect(() => {
    chessSave({ ...data, game: (screen === 'play' && game) ? chSnap(game) : (data.game) });
  }, [data, game, screen]);

  // report final score to the Lab leaderboard at game over only
  window.useReportScore(screen === 'over' && over ? over.points : 0);

  const showSaved = () => { setToast('Progress Saved ✓'); setTimeout(() => setToast(null), 1500); };

  // ——— AI turn ———
  React.useEffect(() => {
    if (screen !== 'play') return;
    const g = gameRef.current;
    if (!g || g.status.over) return;
    if (g.state.turn === 'b' && !thinkingRef.current) {
      thinkingRef.current = true; setThinking(true);
      const captured = g;
      setTimeout(() => {
        const t0 = performance.now();
        const mv = chPickMove(captured.state, captured.level);
        const wait = Math.max(0, 360 - (performance.now() - t0));
        setTimeout(() => {
          thinkingRef.current = false; setThinking(false);
          if (!mv) return;
          const cur = gameRef.current;
          undoRef.current.push(chSnap(cur));
          const ng = chApplyMove(cur, mv);
          playMoveSound(cur, mv, ng);
          commitGame(ng);
          if (ng.status.over) finishGame(ng);
          else if (ng.status.check) setToastBriefly('Check!');
        }, wait);
      }, 70);
    }
  }, [game, screen]);

  const setToastBriefly = (t) => { setToast(t); setTimeout(() => setToast((c) => c === t ? null : c), 1300); };

  function playMoveSound(prevG, mv, ng) {
    if (ng.status.over && ng.status.reason === 'checkmate') { /* handled in finish */ return; }
    if (ng.status.check) chPlay('check', muted);
    else if (mv.flag === 'castleK' || mv.flag === 'castleQ') chPlay('castle', muted);
    else if (mv.captured) chPlay('capture', muted);
    else chPlay('move', muted);
  }

  // ——— flow ———
  const startMatch = (level) => {
    chPlay('ui', muted);
    const g = chNewMatch(level);
    undoRef.current = [];
    commitGame(g);
    setData((d) => ({ ...d, level, game: chSnap(g), stats: { ...d.stats, played: d.stats.played + 1 } }));
    setSelected(null); setPromo(null); setOver(null);
    setScreen('play');
  };

  const resumeMatch = () => {
    if (!data.game) return;
    chPlay('ui', muted);
    const g = chRestore(data.game);
    undoRef.current = [];
    commitGame(g);
    setSelected(null); setPromo(null); setOver(null);
    setScreen('play');
  };

  const goMenu = () => { chPlay('ui', muted); thinkingRef.current = false; setThinking(false); setScreen('menu'); };

  const finishGame = (g) => {
    const result = g.status.result; // 'white' | 'black' | 'draw'
    const outcome = result === 'white' ? 'win' : result === 'black' ? 'lose' : 'draw';
    const youValue = chMaterial(g.capW);
    const bonus = outcome === 'win' ? 100 + g.level * 20 : outcome === 'draw' ? 25 : 0;
    const points = youValue + bonus;
    const moves = Math.ceil(g.history.length / 2);

    setData((d) => {
      const s = { ...d.stats };
      s.played = s.played; // already counted at start
      s.totalPoints += points;
      if (outcome === 'win') {
        s.wins += 1; s.streak += 1; s.bestStreak = Math.max(s.bestStreak, s.streak);
        s.highestBeaten = Math.max(s.highestBeaten, g.level);
      } else if (outcome === 'lose') {
        s.losses += 1; s.streak = 0;
      } else { s.draws += 1; s.streak = 0; }
      return { ...d, game: null, stats: s };
    });

    setOver({ outcome, reason: chReasonText(g.status.reason, outcome), points, level: g.level, moves });
    setTimeout(() => chPlay(outcome === 'win' ? 'win' : outcome === 'lose' ? 'lose' : 'draw', muted), 250);
    setScreen('over');
  };

  function chReasonText(reason, outcome) {
    if (reason === 'checkmate') return outcome === 'win' ? 'Checkmate!' : 'Checkmate';
    if (reason === 'stalemate') return 'Stalemate';
    if (reason === 'insufficient material') return 'Draw — not enough pieces';
    if (reason === 'fifty-move rule') return 'Draw — fifty-move rule';
    if (reason === 'threefold repetition') return 'Draw — threefold repetition';
    return 'Game over';
  }

  // ——— move application (player) ———
  const interactive = screen === 'play' && game && !game.status.over && !thinking && !promo && game.state.turn === 'w';

  const playMove = (mv) => {
    const g = gameRef.current;
    undoRef.current.push(chSnap(g));
    const ng = chApplyMove(g, mv);
    playMoveSound(g, mv, ng);
    commitGame(ng);
    showSaved();
    if (ng.status.over) finishGame(ng);
    else if (ng.status.check) setToastBriefly('Check!');
  };

  const initiateMove = (from, to, mvs) => {
    if (mvs.some((m) => m.flag === 'promo')) { setPromo({ from, to, options: mvs }); setSelected(null); }
    else { playMove(mvs[0]); setSelected(null); }
  };
  const legalFrom = (from, to) => (game ? game.legal.filter((m) => m.from === from && m.to === to) : []);

  // ——— pointer / tap handling ———
  const sqFromEvent = (e) => {
    const el = boardRef.current; if (!el) return -1;
    const rect = el.getBoundingClientRect();
    const x = e.clientX - rect.left, y = e.clientY - rect.top;
    if (x < 0 || y < 0 || x > rect.width || y > rect.height) return -1;
    const cell = rect.width / 8;
    const file = Math.min(7, Math.max(0, Math.floor(x / cell)));
    const row = Math.min(7, Math.max(0, Math.floor(y / cell)));
    return row * 8 + file;
  };

  const onMove = (e) => {
    const d = dragRef.current; if (!d) return;
    const dist = Math.hypot(e.clientX - d.sx, e.clientY - d.sy);
    if (!d.moved && dist > 6) d.moved = true;
    if (d.moved) setDrag({ pc: gameRef.current.state.board[d.from], x: e.clientX, y: e.clientY, from: d.from });
  };
  const onUp = (e) => {
    document.removeEventListener('pointermove', onMove);
    document.removeEventListener('pointerup', onUp);
    const d = dragRef.current; dragRef.current = null; setDrag(null);
    if (!d || !d.moved) return; // a tap — selection already handled on down
    const sq = sqFromEvent(e);
    const mvs = sq >= 0 ? legalFrom(d.from, sq) : [];
    if (mvs.length) initiateMove(d.from, sq, mvs);
  };
  const onDown = (e) => {
    if (!interactive) return;
    e.preventDefault();
    const sq = sqFromEvent(e); if (sq < 0) return;
    const pc = game.state.board[sq];
    if (selected != null) {
      const mvs = legalFrom(selected, sq);
      if (mvs.length) { initiateMove(selected, sq, mvs); return; }
      if (sq === selected) { setSelected(null); return; }
    }
    if (pc && chColorOf(pc) === 'w') {
      chPlay('select', muted);
      setSelected(sq);
      dragRef.current = { from: sq, sx: e.clientX, sy: e.clientY, moved: false };
      document.addEventListener('pointermove', onMove);
      document.addEventListener('pointerup', onUp);
    } else {
      setSelected(null);
    }
  };

  const choosePromo = (mv) => { chPlay('ui', muted); playMove(mv); setPromo(null); };

  const undo = () => {
    if (thinking || !undoRef.current.length) return;
    chPlay('ui', muted);
    let snap = undoRef.current.pop();
    // if we popped the AI's reply, also revert the player's own move
    if (snap.state.turn === 'b' && undoRef.current.length) snap = undoRef.current.pop();
    commitGame(chRestore(snap));
    setSelected(null); setPromo(null);
  };

  const toggleSound = () => { setData((d) => ({ ...d, sound: !d.sound })); if (muted) chPlay('ui', false); };

  // ——— render ———
  return (
    <div className="chess-root" style={{
      position: 'relative', borderRadius: 22, overflow: 'hidden',
      background: 'linear-gradient(165deg, #FFF6E8, #FFE6C4)', border: 'var(--border)',
      minHeight: 540, padding: 'clamp(14px, 3vw, 24px)',
    }}>
      {screen === 'menu' && (
        <ChMenu data={data} muted={muted}
          onStart={startMatch} onResume={data.game ? resumeMatch : null}
          onStats={() => { chPlay('ui', muted); setScreen('stats'); }}
          onToggleSound={toggleSound} />
      )}

      {screen === 'stats' && <ChStats data={data} onBack={goMenu} />}

      {screen === 'over' && over && (
        <ChGameOver over={over} level={over.level} moves={over.moves} points={over.points} data={data}
          onAgain={() => startMatch(over.level)}
          onNext={() => startMatch(Math.min(10, over.level + 1))}
          onHome={goMenu} />
      )}

      {screen === 'play' && game && (
        <ChessPlay
          game={game} data={data} muted={muted} thinking={thinking}
          selected={selected} cellPx={cellPx} boardRef={boardRef} onDown={onDown}
          onUndo={undo} onRestart={() => startMatch(game.level)} onHome={goMenu} onToggleSound={toggleSound}
          canUndo={undoRef.current.length > 0 && !thinking} drag={drag}
        />
      )}

      {/* Promotion picker */}
      {promo && (
        <div style={chOverlay}>
          <div style={chCard}>
            <h2 style={{ marginBottom: 4 }}>Promote your pawn</h2>
            <p style={{ color: 'var(--ink-soft)', fontWeight: 700, fontSize: 14, marginBottom: 16 }}>Pick a piece to crown</p>
            <div style={{ display: 'flex', gap: 10, justifyContent: 'center' }}>
              {['Q', 'R', 'B', 'N'].map((p) => {
                const mv = promo.options.find((m) => m.promo === p);
                return (
                  <button key={p} onClick={() => choosePromo(mv)} style={{
                    width: 60, height: 60, borderRadius: 14, border: 'var(--border)',
                    background: 'var(--paper)', cursor: 'pointer', boxShadow: '3px 3px 0 var(--ink)',
                    display: 'grid', placeItems: 'center',
                  }}><ChPiece pc={p} size={40} /></button>
                );
              })}
            </div>
          </div>
        </div>
      )}

      {/* Floating drag piece */}
      {drag && (
        <div style={{
          position: 'fixed', left: drag.x, top: drag.y, transform: 'translate(-50%,-55%)',
          pointerEvents: 'none', zIndex: 30,
        }}><ChPiece pc={drag.pc} size={cellPx * 0.95} /></div>
      )}

      {toast && (
        <div style={{
          position: 'absolute', bottom: 16, left: '50%', transform: 'translateX(-50%)',
          background: toast === 'Check!' ? 'var(--c-coral)' : 'var(--c-grass)', color: '#fff',
          padding: '9px 20px', borderRadius: 999, border: 'var(--border)', boxShadow: '3px 3px 0 var(--ink)',
          fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 14, zIndex: 20,
          animation: 'ch-toast 1.4s ease forwards', whiteSpace: 'nowrap',
        }}>{toast}</div>
      )}

      <style>{`
        @keyframes ch-toast { 0%{transform:translate(-50%,16px);opacity:0} 15%{transform:translate(-50%,0);opacity:1} 80%{opacity:1} 100%{opacity:0} }
        @keyframes ch-pulse { 0%,100%{box-shadow:inset 0 0 0 3px rgba(255,60,40,.0)} 50%{box-shadow:inset 0 0 0 4px rgba(220,40,30,.9)} }
        @keyframes ch-pop { 0%{transform:scale(.6);opacity:0} 70%{transform:scale(1.06)} 100%{transform:scale(1);opacity:1} }
        @keyframes ch-think { 0%,80%,100%{opacity:.3} 40%{opacity:1} }
        .ch-sq { -webkit-tap-highlight-color: transparent; }
      `}</style>
    </div>
  );
}

const chOverlay = {
  position: 'absolute', inset: 0, display: 'grid', placeItems: 'center',
  background: 'rgba(27,24,64,0.55)', zIndex: 25, padding: 16, textAlign: 'center',
};
const chCard = {
  background: 'var(--paper)', border: 'var(--border-thick)', borderRadius: 24,
  boxShadow: 'var(--shadow-lg)', padding: 'clamp(20px,5vw,28px)', maxWidth: 360, width: '100%',
  animation: 'ch-pop .35s ease',
};

Object.assign(window, { ChessGame, chPlay, chMakeGame, chNewMatch });

// ——— PLAY screen: HUD + board + controls + move history ———
function ChessPlay({ game, data, muted, thinking, selected, cellPx, boardRef, onDown,
                     onUndo, onRestart, onHome, onToggleSound, canUndo, drag }) {
  const board = game.state.board;
  const youValue = chMaterial(game.capW);   // black pieces White captured
  const aiValue = chMaterial(game.capB);    // white pieces Black captured
  const adv = youValue - aiValue;

  // targets for the selected piece: to-square -> isCapture
  const targets = React.useMemo(() => {
    const m = new Map();
    if (selected != null) for (const mv of game.legal) {
      if (mv.from === selected) m.set(mv.to, !!mv.captured || mv.flag === 'ep');
    }
    return m;
  }, [selected, game]);

  const checkSq = game.status.check ? chKingSquare(board, game.state.turn) : -1;
  const dragFrom = drag ? drag.from : -1;
  const pieceSize = Math.max(20, cellPx * 0.82);

  const statusText = thinking ? 'thinking' : game.status.check ? 'Check!' : 'Your move';
  const statusBg = game.status.check ? 'var(--c-coral)' : thinking ? 'var(--c-grape)' : 'var(--c-grass)';

  return (
    <div className="ch-play" style={{ maxWidth: 520, margin: '0 auto' }}>
      {/* HUD top */}
      <div className="ch-hud" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 10, flexWrap: 'wrap' }}>
        <div>
          <div style={{ fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: 'clamp(17px,5vw,22px)' }}>
            Level {game.level}
          </div>
          <div style={{ color: chLevelColor(game.level), fontWeight: 800, fontSize: 13 }}>{chLevelName(game.level)}</div>
        </div>
        <ChPill bg={statusBg} color="#fff" big>
          {thinking ? (
            <span>Computer is thinking
              <span style={{ animation: 'ch-think 1s infinite' }}>.</span>
              <span style={{ animation: 'ch-think 1s infinite .2s' }}>.</span>
              <span style={{ animation: 'ch-think 1s infinite .4s' }}>.</span>
            </span>
          ) : statusText}
        </ChPill>
      </div>

      {/* Score row */}
      <div className="ch-score" style={{ display: 'flex', gap: 7, justifyContent: 'center', flexWrap: 'wrap', margin: '12px 0 8px' }}>
        <ChPill bg="var(--paper)"><ChPiece pc="P" size={16} /> You: {youValue}</ChPill>
        <ChPill bg="var(--paper)"><ChPiece pc="p" size={16} /> Computer: {aiValue}</ChPill>
        <ChPill bg={adv > 0 ? 'var(--c-grass)' : adv < 0 ? 'var(--c-coral)' : 'var(--paper)'} color={adv !== 0 ? '#fff' : 'var(--ink)'}>
          {adv === 0 ? 'Even' : adv > 0 ? `+${adv} you` : `+${-adv} computer`}
        </ChPill>
      </div>

      {/* Captured by you (their lost pieces) */}
      <div className="ch-cap-you" style={{ minHeight: 26, padding: '2px 2px' }}>
        <ChCaptured pieces={game.capW} advantage={Math.max(0, adv)} label="You won" />
      </div>

      {/* Board */}
      <div className="ch-board-wrap" style={{ display: 'grid', placeItems: 'center' }}>
        <div
          ref={boardRef}
          onPointerDown={onDown}
          style={{
            width: 'min(100%, 460px)', aspectRatio: '1',
            display: 'grid', gridTemplateColumns: 'repeat(8, 1fr)', gridTemplateRows: 'repeat(8, 1fr)',
            border: 'var(--border-thick)', borderRadius: 8, overflow: 'hidden',
            boxShadow: 'var(--shadow)', touchAction: 'none', userSelect: 'none',
            cursor: 'pointer',
          }}>
          {Array.from({ length: 64 }, (_, sq) => {
            const row = sq >> 3, file = sq & 7;
            const light = (row + file) % 2 === 0;
            const pc = board[sq];
            const isLast = game.last && (sq === game.last.from || sq === game.last.to);
            const isSel = selected === sq;
            const isTarget = targets.has(sq);
            const targetCap = isTarget && targets.get(sq);
            const isCheck = sq === checkSq;
            return (
              <div key={sq} className="ch-sq" style={{
                position: 'relative', background: light ? CH_LIGHT : CH_DARK,
                display: 'grid', placeItems: 'center',
                animation: isCheck ? 'ch-pulse 1s ease infinite' : 'none',
              }}>
                {isLast && <div style={{ position: 'absolute', inset: 0, background: 'rgba(255,205,55,.40)' }} />}
                {isSel && <div style={{ position: 'absolute', inset: 0, boxShadow: 'inset 0 0 0 4px var(--c-grass)' }} />}
                {/* coordinate labels */}
                {file === 0 && (
                  <span style={{ position: 'absolute', top: 1, left: 3, fontSize: Math.max(8, cellPx * 0.2), fontWeight: 800, color: light ? '#9a6a3e' : '#f0d8b6', pointerEvents: 'none' }}>{8 - row}</span>
                )}
                {row === 7 && (
                  <span style={{ position: 'absolute', bottom: 0, right: 3, fontSize: Math.max(8, cellPx * 0.2), fontWeight: 800, color: light ? '#9a6a3e' : '#f0d8b6', pointerEvents: 'none' }}>{String.fromCharCode(97 + file)}</span>
                )}
                {/* piece */}
                {pc && sq !== dragFrom && (
                  <span style={{ position: 'relative', zIndex: 2, pointerEvents: 'none' }}>
                    <ChPiece pc={pc} size={pieceSize} />
                  </span>
                )}
                {/* move hints */}
                {isTarget && !targetCap && (
                  <div style={{ position: 'absolute', width: '30%', height: '30%', borderRadius: '50%', background: 'rgba(20,16,10,.28)', zIndex: 1, pointerEvents: 'none' }} />
                )}
                {isTarget && targetCap && (
                  <div style={{ position: 'absolute', inset: '6%', borderRadius: '50%', boxShadow: 'inset 0 0 0 4px rgba(20,16,10,.35)', zIndex: 1, pointerEvents: 'none' }} />
                )}
              </div>
            );
          })}
        </div>
      </div>

      {/* Captured by computer (your lost pieces) */}
      <div className="ch-cap-comp" style={{ minHeight: 26, padding: '6px 2px 2px' }}>
        <ChCaptured pieces={game.capB} advantage={Math.max(0, -adv)} label="Computer won" />
      </div>

      {/* Controls */}
      <div className="ch-controls" style={{ display: 'flex', gap: 8, justifyContent: 'center', marginTop: 10, marginBottom: 14 }}>
        <ChIconBtn label="↶" onClick={onUndo} title="Undo move" disabled={!canUndo} />
        <ChIconBtn label="↻" onClick={onRestart} title="Restart match" />
        <ChIconBtn label={muted ? '🔇' : '🔊'} onClick={onToggleSound} title="Sound" />
        <ChIconBtn label="🏠" onClick={onHome} title="Main menu" />
      </div>

      <div className="ch-moves"><ChMoveList history={game.history} /></div>
    </div>
  );
}
