/* ZFREE Games & Download Popup components */

/* ══════════════════════════════════════
   DOWNLOAD POPUP — Windows 98 style
══════════════════════════════════════ */
function DownloadPopup({ filename, sizeMb, onClose }) {
  const { useState, useEffect, useRef } = React;
  const [progress, setProgress] = useState(0);
  const [phase, setPhase] = useState('connecting'); // connecting | downloading | done
  const [kbps, setKbps] = useState(0);
  const [elapsed, setElapsed] = useState(0);
  const intervalRef = useRef(null);

  useEffect(() => {
    // Phase 1: connecting (1.5s)
    const connectTimer = setTimeout(() => {
      setPhase('downloading');
      const startTime = Date.now();
      intervalRef.current = setInterval(() => {
        const secs = Math.floor((Date.now() - startTime) / 1000);
        setElapsed(secs);
        // Simulate realistic 56K speed with jitter: ~4–6 KB/s
        const speed = 4 + Math.random() * 2;
        setKbps(Math.round(speed * 10) / 10);
        setProgress(prev => {
          const next = prev + (speed / (sizeMb * 1024)) * 100;
          if (next >= 100) {
            clearInterval(intervalRef.current);
            setPhase('done');
            return 100;
          }
          return next;
        });
      }, 200);
    }, 1500);
    return () => { clearTimeout(connectTimer); clearInterval(intervalRef.current); };
  }, [sizeMb]);

  const pct = Math.min(100, Math.round(progress));
  const downloaded = Math.round((pct / 100) * sizeMb * 1024);
  const total = Math.round(sizeMb * 1024);
  const remaining = phase === 'done' ? 0 : Math.max(0, Math.round(((100 - pct) / 100 * sizeMb * 1024) / (kbps || 5)));

  return (
    <div style={{
      position:'fixed', top:0, left:0, right:0, bottom:0,
      background:'rgba(0,0,0,0.45)', display:'flex',
      alignItems:'center', justifyContent:'center', zIndex:9999,
    }}>
      {/* Window chrome */}
      <div style={{
        background:'#c8e020',
        width:'100%', maxWidth:420,
        border:'2px solid #7a9800',
        boxShadow:'4px 4px 0 rgba(0,0,0,0.4)',
        fontFamily:'"Times New Roman", serif',
        margin:'0 12px',
      }}>
        {/* Title bar */}
        <div style={{
          background:'linear-gradient(to right, #7a9800, #9dc009)',
          color:'white', padding:'3px 6px',
          display:'flex', justifyContent:'space-between', alignItems:'center',
        }}>
          <span style={{fontWeight:'bold', fontSize:12}}>📥 Downloading — {filename}</span>
          <div style={{
            background:'#c8e020', border:'1px solid #7a9800',
            width:16, height:14, display:'flex', alignItems:'center',
            justifyContent:'center', cursor:'pointer', fontSize:10,
            fontWeight:'bold', color:'#333', fontFamily:'monospace',
          }} onClick={onClose}>✕</div>
        </div>

        {/* Body */}
        <div style={{padding:'12px 14px', background:'#c8e020'}}>
          {phase === 'connecting' && (
            <div style={{textAlign:'center', padding:'10px 0'}}>
              <div style={{fontSize:13, marginBottom:8}}>Connecting to download server…</div>
              <div style={{display:'flex', justifyContent:'center', gap:5}}>
                {[0,1,2,3,4].map(i => (
                  <div key={i} style={{
                    width:10, height:10, borderRadius:'50%',
                    background:'#cc1111',
                    animation:`dotpulse 1s ease-in-out ${i*0.15}s infinite`,
                  }}/>
                ))}
              </div>
              <style>{`@keyframes dotpulse{0%,100%{opacity:.2;transform:scale(.8)}50%{opacity:1;transform:scale(1.2)}}`}</style>
            </div>
          )}

          {(phase === 'downloading' || phase === 'done') && (<>
            {/* File info */}
            <div style={{display:'flex', gap:10, marginBottom:10, alignItems:'center'}}>
              <div style={{fontSize:32}}>💾</div>
              <div>
                <div style={{fontWeight:'bold', fontSize:13}}>{filename}</div>
                <div style={{fontSize:11, color:'#555'}}>From: download.zfree.co.nz</div>
                <div style={{fontSize:11, color:'#555'}}>Size: {sizeMb} MB ({total} KB)</div>
              </div>
            </div>

            {/* Progress bar */}
            <div style={{marginBottom:6}}>
              <div style={{
                border:'2px inset #7a9800', background:'white',
                height:20, position:'relative', overflow:'hidden',
              }}>
                <div style={{
                  position:'absolute', top:0, left:0, bottom:0,
                  width:`${pct}%`,
                  background:'repeating-linear-gradient(90deg, #cc1111 0px, #cc1111 10px, #aa0000 10px, #aa0000 20px)',
                  transition:'width 0.2s linear',
                }}/>
                {/* Percentage text */}
                <div style={{
                  position:'absolute', top:0, left:0, right:0, bottom:0,
                  display:'flex', alignItems:'center', justifyContent:'center',
                  fontSize:11, fontWeight:'bold', color:'white',
                  textShadow:'1px 1px 0 #000', fontFamily:'Arial,sans-serif',
                  mixBlendMode:'difference',
                }}>
                  {pct}%
                </div>
              </div>
            </div>

            {/* Stats */}
            <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:4, fontSize:11, marginBottom:10}}>
              <div><strong>Downloaded:</strong> {downloaded} KB of {total} KB</div>
              <div><strong>Speed:</strong> {phase === 'done' ? '—' : `${kbps} KB/s`}</div>
              <div><strong>Time elapsed:</strong> {elapsed}s</div>
              <div><strong>Time remaining:</strong> {phase === 'done' ? '0s' : `~${remaining}s`}</div>
            </div>

            {phase === 'done' && (
              <div style={{
                background:'white', border:'1px solid #7a9800',
                padding:'8px 10px', marginBottom:10, textAlign:'center',
              }}>
                <div style={{fontSize:20, marginBottom:4}}>✅</div>
                <div style={{fontWeight:'bold', fontSize:13, color:'#336600'}}>
                  Download Complete!
                </div>
                <div style={{fontSize:11, color:'#555', marginTop:2}}>
                  {filename} has been saved to C:\Windows\Desktop
                </div>
              </div>
            )}

            {/* Buttons */}
            <div style={{display:'flex', justifyContent:'flex-end', gap:6}}>
              {phase === 'done' && (
                <button style={{
                  background:'#cc1111', color:'white', fontWeight:'bold',
                  border:'2px outset #cc1111', padding:'3px 14px',
                  fontSize:12, cursor:'pointer', fontFamily:'"Times New Roman",serif',
                }} onClick={onClose}>Open File</button>
              )}
              <button style={{
                background:'#c8e020', border:'2px outset #7a9800',
                padding:'3px 14px', fontSize:12, cursor:'pointer',
                fontFamily:'"Times New Roman",serif',
              }} onClick={onClose}>{phase === 'done' ? 'Close' : 'Cancel'}</button>
            </div>
          </>)}
        </div>
      </div>
    </div>
  );
}


/* ══════════════════════════════════════
   NOUGHTS & CROSSES
══════════════════════════════════════ */
function GameNoughts({ onClose }) {
  const { useState, useEffect } = React;
  const [board, setBoard] = useState(Array(9).fill(null));
  const [xIsNext, setXIsNext] = useState(true);
  const [status, setStatus] = useState('');
  const [scores, setScores] = useState({ X: 0, O: 0, D: 0 });

  function calcWinner(b) {
    const lines = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]];
    for (const [a,b2,c] of lines) if (b[a] && b[a]===b[b2] && b[a]===b[c]) return { winner: b[a], line: [a,b2,c] };
    return null;
  }

  function aiMove(b) {
    // Try to win, then block, then centre, then random
    const lines = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]];
    for (const player of ['O','X']) {
      for (const [a,b2,c] of lines) {
        const vals = [b[a],b[b2],b[c]];
        if (vals.filter(v=>v===player).length===2 && vals.filter(v=>!v).length===1) {
          return [a,b2,c][vals.indexOf(null)];
        }
      }
    }
    if (!b[4]) return 4;
    const corners = [0,2,6,8].filter(i=>!b[i]);
    if (corners.length) return corners[Math.floor(Math.random()*corners.length)];
    const sides = [1,3,5,7].filter(i=>!b[i]);
    if (sides.length) return sides[Math.floor(Math.random()*sides.length)];
    return null;
  }

  function handleClick(i) {
    if (board[i] || calcWinner(board) || !xIsNext) return;
    const nb = [...board]; nb[i] = 'X';
    const w = calcWinner(nb);
    const full = nb.every(Boolean);
    setBoard(nb);
    if (w) { setScores(s=>({...s, X:s.X+1})); setXIsNext(true); return; }
    if (full) { setScores(s=>({...s, D:s.D+1})); setXIsNext(true); return; }
    setXIsNext(false);
    // AI moves after short delay
    setTimeout(() => {
      const ai = aiMove(nb);
      if (ai !== null) {
        const nb2 = [...nb]; nb2[ai] = 'O';
        const w2 = calcWinner(nb2);
        const full2 = nb2.every(Boolean);
        setBoard(nb2);
        if (w2) setScores(s=>({...s, O:s.O+1}));
        else if (full2) setScores(s=>({...s, D:s.D+1}));
        setXIsNext(true);
      }
    }, 400);
  }

  function reset() { setBoard(Array(9).fill(null)); setXIsNext(true); }

  const result = calcWinner(board);
  const full = board.every(Boolean);
  const winLine = result ? result.line : [];
  const msg = result ? `${result.winner === 'X' ? '🎉 You win!' : '🤖 Computer wins!'}` : full ? "It's a draw!" : xIsNext ? 'Your turn (X)' : 'Computer thinking…';

  return (
    <GameWindow title="Noughts & Crosses" onClose={onClose}>
      <div style={{textAlign:'center'}}>
        <div style={{display:'flex', justifyContent:'center', gap:16, marginBottom:10, fontSize:12}}>
          <span style={{color:'#cc1111', fontWeight:'bold'}}>You (X): {scores.X}</span>
          <span style={{color:'#333'}}>Draws: {scores.D}</span>
          <span style={{color:'#336600', fontWeight:'bold'}}>Computer (O): {scores.O}</span>
        </div>
        <div style={{
          display:'grid', gridTemplateColumns:'repeat(3,1fr)',
          gap:3, width:180, margin:'0 auto 10px',
        }}>
          {board.map((cell,i) => (
            <div key={i} onClick={() => handleClick(i)} style={{
              width:58, height:58,
              background: winLine.includes(i) ? '#eeff44' : '#c8e020',
              border:'2px inset #7a9800',
              display:'flex', alignItems:'center', justifyContent:'center',
              fontSize:28, fontWeight:'bold', cursor: !cell && !result && xIsNext ? 'pointer' : 'default',
              color: cell === 'X' ? '#cc1111' : '#336600',
              transition:'background 0.15s',
            }}>
              {cell}
            </div>
          ))}
        </div>
        <div style={{fontSize:13, fontWeight:'bold', marginBottom:8, color: result ? '#cc1111' : '#333'}}>
          {msg}
        </div>
        <button className="btn-red" style={{fontSize:11, padding:'3px 12px'}} onClick={reset}>
          New Game
        </button>
      </div>
    </GameWindow>
  );
}


/* ══════════════════════════════════════
   SNAKE
══════════════════════════════════════ */
function GameSnake({ onClose }) {
  const { useState, useEffect, useRef, useCallback } = React;
  const COLS = 20, ROWS = 16, CELL = 16;
  const [snake, setSnake] = useState([[10,8],[9,8],[8,8]]);
  const [dir, setDir] = useState([1,0]);
  const [food, setFood] = useState([15,8]);
  const [score, setScore] = useState(0);
  const [best, setBest] = useState(0);
  const [running, setRunning] = useState(false);
  const [dead, setDead] = useState(false);
  const dirRef = useRef([1,0]);
  const snakeRef = useRef([[10,8],[9,8],[8,8]]);
  const foodRef = useRef([15,8]);
  const scoreRef = useRef(0);

  function randFood(s) {
    let f;
    do { f = [Math.floor(Math.random()*COLS), Math.floor(Math.random()*ROWS)]; }
    while (s.some(([x,y])=>x===f[0]&&y===f[1]));
    return f;
  }

  const tick = useCallback(() => {
    const s = snakeRef.current;
    const d = dirRef.current;
    const head = [s[0][0]+d[0], s[0][1]+d[1]];
    if (head[0]<0||head[0]>=COLS||head[1]<0||head[1]>=ROWS||s.some(([x,y])=>x===head[0]&&y===head[1])) {
      setDead(true); setRunning(false); return;
    }
    const ate = head[0]===foodRef.current[0]&&head[1]===foodRef.current[1];
    const ns = ate ? [head,...s] : [head,...s.slice(0,-1)];
    if (ate) {
      const nf = randFood(ns); foodRef.current = nf; setFood(nf);
      scoreRef.current += 10; setScore(scoreRef.current);
      setBest(b => Math.max(b, scoreRef.current));
    }
    snakeRef.current = ns; setSnake([...ns]);
  }, []);

  useEffect(() => {
    if (!running) return;
    const id = setInterval(tick, 120);
    return () => clearInterval(id);
  }, [running, tick]);

  useEffect(() => {
    const handler = (e) => {
      const map = {ArrowUp:[0,-1],ArrowDown:[0,1],ArrowLeft:[-1,0],ArrowRight:[1,0]};
      if (map[e.key]) {
        e.preventDefault();
        const d = map[e.key];
        const cur = dirRef.current;
        if (d[0]+cur[0]!==0||d[1]+cur[1]!==0) dirRef.current = d;
        setDir(d);
      }
    };
    window.addEventListener('keydown', handler);
    return () => window.removeEventListener('keydown', handler);
  }, []);

  function startGame() {
    const s = [[10,8],[9,8],[8,8]];
    const f = randFood(s);
    snakeRef.current = s; foodRef.current = f; dirRef.current = [1,0];
    scoreRef.current = 0;
    setSnake(s); setFood(f); setDir([1,0]);
    setScore(0); setDead(false); setRunning(true);
  }

  function setDirBtn(d) {
    const cur = dirRef.current;
    if (d[0]+cur[0]!==0||d[1]+cur[1]!==0) { dirRef.current = d; setDir(d); }
  }

  return (
    <GameWindow title="Snake" onClose={onClose} wide>
      <div style={{display:'flex', flexDirection:'column', alignItems:'center', gap:6}}>
        <div style={{display:'flex', gap:20, fontSize:12, marginBottom:2}}>
          <span><strong style={{color:'#cc1111'}}>Score: {score}</strong></span>
          <span><strong>Best: {best}</strong></span>
        </div>
        {/* Canvas */}
        <div style={{
          position:'relative',
          width: COLS*CELL, height: ROWS*CELL,
          background:'#1a1a1a', border:'3px inset #7a9800',
        }}>
          {/* Food */}
          <div style={{
            position:'absolute',
            left: food[0]*CELL, top: food[1]*CELL,
            width:CELL, height:CELL,
            background:'#cc1111', borderRadius:'50%',
            boxShadow:'0 0 4px #ff4444',
          }}/>
          {/* Snake */}
          {snake.map(([x,y],i) => (
            <div key={i} style={{
              position:'absolute', left:x*CELL, top:y*CELL,
              width:CELL-1, height:CELL-1,
              background: i===0 ? '#c8e020' : '#9dc009',
              borderRadius: i===0 ? 3 : 1,
            }}/>
          ))}
          {/* Overlay */}
          {(!running) && (
            <div style={{
              position:'absolute', inset:0,
              background:'rgba(0,0,0,0.7)',
              display:'flex', flexDirection:'column',
              alignItems:'center', justifyContent:'center', gap:8,
            }}>
              {dead && <div style={{color:'#cc1111', fontWeight:'bold', fontSize:16}}>GAME OVER!</div>}
              {dead && <div style={{color:'white', fontSize:12}}>Score: {score}</div>}
              <button className="btn-red" style={{fontSize:12, padding:'4px 16px'}} onClick={startGame}>
                {dead ? 'Play Again' : 'Start Game'}
              </button>
              {!dead && <div style={{color:'#aaa', fontSize:10}}>Use arrow keys to steer</div>}
            </div>
          )}
        </div>
        {/* D-pad for mouse control */}
        <div style={{display:'grid', gridTemplateColumns:'repeat(3,32px)', gridTemplateRows:'repeat(2,32px)', gap:2}}>
          <div/>
          <button onClick={()=>setDirBtn([0,-1])} style={dpadBtn}>↑</button>
          <div/>
          <button onClick={()=>setDirBtn([-1,0])} style={dpadBtn}>←</button>
          <div/>
          <button onClick={()=>setDirBtn([1,0])} style={dpadBtn}>→</button>
          <div/>
          <button onClick={()=>setDirBtn([0,1])} style={dpadBtn}>↓</button>
          <div/>
        </div>
      </div>
    </GameWindow>
  );
}
const dpadBtn = {
  background:'#c8e020', border:'2px outset #7a9800',
  width:32, height:32, fontSize:14, cursor:'pointer',
  display:'flex', alignItems:'center', justifyContent:'center',
  fontFamily:'monospace',
};


/* ══════════════════════════════════════
   HANGMAN
══════════════════════════════════════ */
const HANGMAN_WORDS = [
  {w:'KIWI',       h:'A flightless NZ bird'},
  {w:'MODEM',      h:'You need this for dial-up'},
  {w:'ZFREE',      h:'Your FREE internet provider!'},
  {w:'AUCKLAND',   h:"NZ's largest city"},
  {w:'CRICKET',    h:'Popular NZ summer sport'},
  {w:'POHUTUKAWA', h:'NZ Christmas tree'},
  {w:'INTERNET',   h:'The information superhighway'},
  {w:'DOWNLOAD',   h:'Getting a file from the web'},
  {w:'BROWSER',    h:'Internet Explorer is one'},
  {w:'PAVLOVA',    h:'NZ dessert (we invented it!)'},
];

function HangmanSVG({ wrong }) {
  return (
    <svg width="120" height="130" viewBox="0 0 120 130" style={{display:'block',margin:'0 auto'}}>
      {/* Gallows */}
      <line x1="10" y1="125" x2="110" y2="125" stroke="#cc1111" strokeWidth="3"/>
      <line x1="30" y1="125" x2="30" y2="10"  stroke="#cc1111" strokeWidth="3"/>
      <line x1="30" y1="10"  x2="75" y2="10"  stroke="#cc1111" strokeWidth="3"/>
      <line x1="75" y1="10"  x2="75" y2="28"  stroke="#cc1111" strokeWidth="2"/>
      {/* Head */}
      {wrong>0 && <circle cx="75" cy="38" r="10" stroke="#333" strokeWidth="2" fill="#c8e020"/>}
      {/* Body */}
      {wrong>1 && <line x1="75" y1="48" x2="75" y2="85" stroke="#333" strokeWidth="2"/>}
      {/* Left arm */}
      {wrong>2 && <line x1="75" y1="58" x2="55" y2="72" stroke="#333" strokeWidth="2"/>}
      {/* Right arm */}
      {wrong>3 && <line x1="75" y1="58" x2="95" y2="72" stroke="#333" strokeWidth="2"/>}
      {/* Left leg */}
      {wrong>4 && <line x1="75" y1="85" x2="55" y2="105" stroke="#333" strokeWidth="2"/>}
      {/* Right leg */}
      {wrong>5 && <line x1="75" y1="85" x2="95" y2="105" stroke="#333" strokeWidth="2"/>}
      {/* Face when dead */}
      {wrong>5 && <>
        <line x1="70" y1="34" x2="73" y2="37" stroke="#cc1111" strokeWidth="1.5"/>
        <line x1="73" y1="34" x2="70" y2="37" stroke="#cc1111" strokeWidth="1.5"/>
        <line x1="77" y1="34" x2="80" y2="37" stroke="#cc1111" strokeWidth="1.5"/>
        <line x1="80" y1="34" x2="77" y2="37" stroke="#cc1111" strokeWidth="1.5"/>
        <path d="M 70 44 Q 75 40 80 44" stroke="#cc1111" strokeWidth="1.5" fill="none"/>
      </>}
    </svg>
  );
}

function GameHangman({ onClose }) {
  const { useState } = React;
  function newPuzzle() {
    const pick = HANGMAN_WORDS[Math.floor(Math.random()*HANGMAN_WORDS.length)];
    return pick;
  }
  const [puzzle, setPuzzle] = useState(() => newPuzzle());
  const [guessed, setGuessed] = useState(new Set());
  const [scores, setScores] = useState({wins:0, losses:0});

  const wrong = [...guessed].filter(l => !puzzle.w.includes(l)).length;
  const MAX = 6;
  const won = [...puzzle.w].every(l => guessed.has(l));
  const lost = wrong >= MAX;
  const over = won || lost;

  function guess(letter) {
    if (over || guessed.has(letter)) return;
    const ng = new Set(guessed); ng.add(letter);
    setGuessed(ng);
    const newWrong = [...ng].filter(l => !puzzle.w.includes(l)).length;
    const newWon = [...puzzle.w].every(l => ng.has(l));
    if (newWon) setScores(s=>({...s,wins:s.wins+1}));
    else if (newWrong >= MAX) setScores(s=>({...s,losses:s.losses+1}));
  }

  function reset() { setPuzzle(newPuzzle()); setGuessed(new Set()); }

  const alpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');

  return (
    <GameWindow title="Hangman" onClose={onClose} wide>
      <div style={{display:'flex', gap:12}}>
        {/* Left: gallows + stats */}
        <div style={{flexShrink:0, textAlign:'center'}}>
          <HangmanSVG wrong={wrong}/>
          <div style={{fontSize:11, marginTop:4}}>
            <span style={{color:'#cc1111'}}>Wrong: {wrong}/{MAX}</span>
          </div>
          <div style={{fontSize:10, color:'#555', marginTop:2}}>
            Wins: {scores.wins} · Losses: {scores.losses}
          </div>
        </div>

        {/* Right: word + keyboard */}
        <div style={{flex:1}}>
          {/* Hint */}
          <div style={{fontSize:11, color:'#555', fontStyle:'italic', marginBottom:6}}>
            💡 Hint: {puzzle.h}
          </div>

          {/* Word display */}
          <div style={{display:'flex', gap:5, marginBottom:10, flexWrap:'wrap'}}>
            {[...puzzle.w].map((letter,i) => (
              <div key={i} style={{
                width:22, height:28, borderBottom:'2px solid #333',
                display:'flex', alignItems:'center', justifyContent:'center',
                fontSize:18, fontWeight:'bold', color:'#cc1111',
              }}>
                {guessed.has(letter) || over ? letter : ''}
              </div>
            ))}
          </div>

          {/* Wrong letters */}
          {[...guessed].filter(l=>!puzzle.w.includes(l)).length > 0 && (
            <div style={{fontSize:11, marginBottom:8}}>
              Wrong: {[...guessed].filter(l=>!puzzle.w.includes(l)).join(' ')}
            </div>
          )}

          {/* Status */}
          {over && (
            <div style={{
              fontWeight:'bold', fontSize:13, marginBottom:8,
              color: won ? '#336600' : '#cc1111',
            }}>
              {won ? '🎉 You got it!' : `💀 It was "${puzzle.w}"`}
            </div>
          )}

          {/* Keyboard */}
          <div style={{display:'flex', flexWrap:'wrap', gap:3, maxWidth:220}}>
            {alpha.map(l => {
              const isGuessed = guessed.has(l);
              const isWrong = isGuessed && !puzzle.w.includes(l);
              const isRight = isGuessed && puzzle.w.includes(l);
              return (
                <button key={l} onClick={() => guess(l)} disabled={over || isGuessed} style={{
                  width:24, height:24, fontSize:11, fontWeight:'bold',
                  background: isRight ? '#9dc009' : isWrong ? '#888' : '#c8e020',
                  color: isGuessed ? 'white' : '#333',
                  border:'1px solid #7a9800', cursor: over||isGuessed ? 'default' : 'pointer',
                  fontFamily:'monospace',
                }}>{l}</button>
              );
            })}
          </div>
          {(over) && (
            <button className="btn-red" style={{marginTop:8,fontSize:11,padding:'3px 10px'}} onClick={reset}>
              New Word
            </button>
          )}
        </div>
      </div>
    </GameWindow>
  );
}


/* ══════════════════════════════════════
   GAME WINDOW CHROME (shared)
══════════════════════════════════════ */
function GameWindow({ title, onClose, wide, children }) {
  return (
    <div style={{
      background:'#c8e020',
      border:'2px solid #7a9800',
      boxShadow:'4px 4px 0 rgba(0,0,0,0.3)',
      fontFamily:'"Times New Roman",serif',
      width: '100%', maxWidth: wide ? 440 : 320,
      margin: '0 12px',
    }}>
      {/* Title bar */}
      <div style={{
        background:'linear-gradient(to right, #7a9800, #9dc009)',
        color:'white', padding:'3px 6px',
        display:'flex', justifyContent:'space-between', alignItems:'center',
      }}>
        <span style={{fontWeight:'bold', fontSize:12}}>🎮 {title}</span>
        <div style={{
          background:'#c8e020', border:'1px solid #7a9800',
          width:16, height:14, display:'flex', alignItems:'center',
          justifyContent:'center', cursor:'pointer', fontSize:10,
          fontWeight:'bold', color:'#333', fontFamily:'monospace',
        }} onClick={onClose}>✕</div>
      </div>
      <div style={{padding:12}}>{children}</div>
    </div>
  );
}


/* ══════════════════════════════════════
   EXPORT
══════════════════════════════════════ */
Object.assign(window, {
  DownloadPopup,
  GameNoughts,
  GameSnake,
  GameHangman,
  GameWindow,
});
