// Turnix — Game screens (Word Impostor, Letter Game, Wrong Answer Wins, Results)
// All screens receive: roomState, isHost, myId, onAction, onAdvance, onNextRound, onPlayAgain, onLeave

const kbdStyle = {
  fontFamily: "var(--font-mono)", fontSize: 11,
  background: "rgba(255,255,255,0.05)", border: "1px solid var(--line-2)",
  borderRadius: 5, padding: "2px 6px",
};

// ── Shared layout ─────────────────────────────────────────────────────────
function GameTopBar({ game, code, timer, timerMax, phaseLabel, round, totalRounds }) {
  return (
    <TopBar
      left={<>
        <span style={{ width: 6, height: 24, background: game.accentRaw, borderRadius: 2 }} />
        <span style={{ fontWeight: 600, fontSize: 14 }}>{game.name}</span>
        <span style={{ color: "var(--fg-3)", fontSize: 12, marginLeft: 4 }}>Round {round}/{totalRounds}</span>
      </>}
      center={
        <Chip mono style={{ fontWeight: 600, fontSize: 13, height: 30, paddingInline: 14, color: game.accentRaw, borderColor: `${game.accentRaw}55` }}>
          {phaseLabel}
        </Chip>
      }
      right={<>
        {timer != null && <TimerRing value={timer} max={timerMax} accent={game.accentRaw} size={28} />}
        <Chip mono style={{ letterSpacing: "0.14em" }}>{code}</Chip>
      </>}
    />
  );
}

function StatusFooter({ status, hint, primaryLabel, primaryDisabled, primaryGame, onPrimary, secondaryLabel, onSecondary }) {
  return (
    <footer style={{ display: "flex", alignItems: "center", gap: 14, paddingTop: 8 }}>
      <div style={{ flex: 1, display: "flex", flexDirection: "column", gap: 2 }}>
        <div style={{ fontSize: 14, fontWeight: 500 }}>{status}</div>
        {hint && <div style={{ color: "var(--fg-3)", fontSize: 12 }}>{hint}</div>}
      </div>
      {secondaryLabel && <button className="tx-btn ghost" onClick={onSecondary}>{secondaryLabel}</button>}
      {primaryLabel && (
        <button className="tx-btn accent" data-game={primaryGame} disabled={primaryDisabled} onClick={onPrimary}>
          {primaryLabel}
        </button>
      )}
    </footer>
  );
}

// ── WORD IMPOSTOR ─────────────────────────────────────────────────────────
function ImpostorScreen({ roomState, isHost, myId, onAction, onAdvance }) {
  const game = GAMES.impostor;
  const { players, round = 1, rounds = 5, code, gameState: gs } = roomState;

  const phase      = gs?.phase || "clue";
  const impostorId = gs?.impostorId;
  const clues      = gs?.clues || {};
  const votes      = gs?.votes || {};
  const lockedVotes = gs?.lockedVotes || [];

  const youAreImpostor = impostorId === myId;
  const word = youAreImpostor ? "????" : (gs?.word || "BANANA");

  const [yourClue, setYourClue] = React.useState("");
  const [yourVote, setYourVote] = React.useState(null);

  const myClueSubmitted  = !!clues[myId];
  const myVoteSubmitted  = !!votes[myId];
  const myVoteLocked     = lockedVotes.includes(myId);
  const cluesIn          = players.filter(p => clues[p.id]).length;
  const lockedIn         = lockedVotes.length;

  const [timer, setTimer] = useCountdown(35, {
    running: phase === "clue" && !myClueSubmitted && isHost,
    onEnd: isHost ? () => onAction({ type: "submitClue", clue: "—" }) : undefined,
    key: phase,
  });
  const [voteTimer] = useCountdown(20, {
    running: phase === "vote" && !myVoteLocked && isHost,
    key: "vote",
  });

  // ── REVEAL phase ──
  if (phase === "reveal") {
    const countMap = {};
    Object.values(votes).forEach(id => { countMap[id] = (countMap[id] || 0) + 1; });
    const topId = Object.entries(countMap).sort((a, b) => b[1] - a[1])[0]?.[0];
    const caught = topId === impostorId;
    const impostor = players.find(p => p.id === impostorId);

    return (
      <div className="tx-screen" style={{ padding: 24, gap: 18 }}>
        <GameTopBar game={game} code={code} timer={null} timerMax={20} phaseLabel="Reveal" round={round} totalRounds={rounds} />
        <div style={{ flex: 1, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 24 }}>
          <div className="tx-eyebrow" style={{ color: game.accentRaw }}>The impostor was…</div>
          <div className="tx-title xl" style={{ textShadow: `0 0 40px ${game.accentRaw}66` }}>
            {impostor?.name}
            {impostorId === myId && " (you!)"}
          </div>
          <div style={{ fontSize: 16, color: caught ? "var(--ok)" : "var(--bad)", fontWeight: 600 }}>
            {caught ? "Caught! Crewmates win this round." : "Escaped! Impostor wins this round."}
          </div>
          <div style={{ display: "flex", gap: 8, flexWrap: "wrap", justifyContent: "center" }}>
            {players.map(p => {
              const v = votes[p.id];
              const target = players.find(x => x.id === v);
              return (
                <div key={p.id} className="tx-card" style={{ padding: "12px 16px", minWidth: 140 }}>
                  <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 6 }}>
                    <Avatar player={{ ...p, you: p.id === myId }} size={28} />
                    <span style={{ fontWeight: 500, fontSize: 13 }}>{p.id === myId ? "You" : p.name}</span>
                  </div>
                  <div style={{ fontFamily: "var(--font-mono)", fontSize: 14, color: game.accentRaw }}>{clues[p.id] || "—"}</div>
                  <div style={{ fontSize: 11, color: "var(--fg-3)", marginTop: 4 }}>voted: {target?.name || "—"}</div>
                </div>
              );
            })}
          </div>
        </div>
        <StatusFooter
          status="Round over."
          hint={`The word was "${gs?.word || "BANANA"}"`}
          primaryLabel={isHost ? "See scores →" : "Waiting for host…"}
          primaryDisabled={!isHost}
          primaryGame="impostor"
          onPrimary={onAdvance}
        />
      </div>
    );
  }

  // ── VOTE phase ──
  if (phase === "vote") {
    return (
      <div className="tx-screen" style={{ padding: 24, gap: 18 }}>
        <GameTopBar game={game} code={code} timer={voteTimer} timerMax={20} phaseLabel="Vote · who's the impostor?" round={round} totalRounds={rounds} />
        <div style={{ flex: 1, display: "flex", flexDirection: "column", gap: 18, justifyContent: "center" }}>
          <div style={{ textAlign: "center" }}>
            <div className="tx-eyebrow" style={{ color: game.accentRaw }}>Voting</div>
            <h1 className="tx-title lg" style={{ marginTop: 8 }}>Pick the impostor</h1>
            <div className="tx-sub" style={{ marginTop: 6 }}>Tap a player to vote. Lock in when sure.</div>
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 12, maxWidth: 720, margin: "0 auto", width: "100%" }}>
            {players.map(p => {
              const sel = (yourVote || votes[myId]) === p.id;
              const isMe = p.id === myId;
              return (
                <button key={p.id}
                  disabled={isMe || myVoteLocked}
                  onClick={() => {
                    if (isMe || myVoteLocked) return;
                    setYourVote(p.id);
                    onAction({ type: "submitVote", targetId: p.id });
                  }}
                  className="tx-card tx-rise"
                  style={{
                    padding: 16, cursor: isMe ? "not-allowed" : "pointer", textAlign: "left",
                    borderColor: sel ? game.accentRaw : "var(--line)",
                    background: sel ? `linear-gradient(180deg, color-mix(in oklab, ${game.accentRaw} 18%, var(--bg-2)) 0%, var(--bg-1) 100%)` : undefined,
                    boxShadow: sel ? `0 0 0 1px ${game.accentRaw}99, 0 8px 24px ${game.accentRaw}33` : "none",
                    opacity: isMe ? 0.55 : 1, transition: "all 160ms",
                  }}>
                  <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 10 }}>
                    <Avatar player={{ ...p, you: isMe }} />
                    <span style={{ fontWeight: 600, fontSize: 14 }}>
                      {p.name}{isMe && <span style={{ color: "var(--fg-3)", fontWeight: 400 }}> · you</span>}
                    </span>
                  </div>
                  <div style={{ fontFamily: "var(--font-mono)", fontSize: 18, fontWeight: 600, color: clues[p.id] ? "var(--fg-0)" : "var(--fg-3)" }}>
                    {clues[p.id] || "—"}
                  </div>
                </button>
              );
            })}
          </div>
        </div>
        <StatusFooter
          status={myVoteLocked ? `Locked in. (${lockedIn}/${players.length} locked)` : (yourVote || votes[myId]) ? `Voting: ${players.find(p => p.id === (yourVote || votes[myId]))?.name}` : "Pick someone."}
          hint={myVoteLocked ? "Waiting for the rest…" : "You can change your vote until you lock in."}
          primaryLabel={myVoteLocked ? "Locked ✓" : "Lock vote"}
          primaryDisabled={!(yourVote || votes[myId]) || myVoteLocked}
          primaryGame="impostor"
          onPrimary={() => onAction({ type: "lockVote" })}
          secondaryLabel={isHost ? "Force reveal" : null}
          onSecondary={isHost ? () => onAction({ type: "lockVote" }) : null}
        />
      </div>
    );
  }

  // ── CLUE phase ──
  return (
    <div className="tx-screen" style={{ padding: 24, gap: 18 }}>
      <GameTopBar game={game} code={code} timer={timer} timerMax={35} phaseLabel="Clue phase" round={round} totalRounds={rounds} />
      <div style={{ display: "grid", gridTemplateColumns: "1.15fr 1fr", gap: 22, flex: 1, minHeight: 0 }}>
        <div className="tx-card tx-rise" style={{
          padding: 28, display: "flex", flexDirection: "column", gap: 18,
          background: `linear-gradient(160deg, color-mix(in oklab, ${game.accentRaw} 16%, var(--bg-2)) 0%, var(--bg-1) 100%)`,
          border: `1px solid color-mix(in oklab, ${game.accentRaw} 30%, transparent)`,
        }}>
          <div className="tx-eyebrow" style={{ color: game.accentRaw }}>
            {youAreImpostor ? "You are the impostor" : "Your secret word"}
          </div>
          <div style={{
            fontFamily: "var(--font-mono)", fontWeight: 700, fontSize: 80,
            letterSpacing: "0.08em", lineHeight: 1,
            color: youAreImpostor ? "var(--fg-2)" : "var(--fg-0)",
            textShadow: youAreImpostor ? "none" : `0 0 calc(40px * var(--glow-strength)) ${game.accentRaw}55`,
          }}>{word}</div>
          <div className="tx-sub">{youAreImpostor ? "Blend in. You don't know the word." : "Give a 1-word clue."}</div>
          <div style={{ marginTop: "auto", display: "flex", flexDirection: "column", gap: 10 }}>
            <label style={{ fontSize: 12, color: "var(--fg-2)", fontWeight: 500, letterSpacing: "0.06em", textTransform: "uppercase" }}>
              Your clue (1 word)
            </label>
            <div style={{ display: "flex", gap: 10 }}>
              <input className="tx-input" autoFocus
                placeholder={youAreImpostor ? "Bluff something plausible…" : "e.g. tropical"}
                value={yourClue}
                disabled={myClueSubmitted}
                onChange={e => setYourClue(e.target.value.replace(/\s/g, "").slice(0, 16))}
                onKeyDown={e => { if (e.key === "Enter" && yourClue.trim()) onAction({ type: "submitClue", clue: yourClue.trim() }); }}
                style={{ flex: 1, fontFamily: "var(--font-mono)", letterSpacing: "0.02em" }}
              />
              <button className="tx-btn accent" data-game="impostor"
                onClick={() => onAction({ type: "submitClue", clue: yourClue.trim() })}
                disabled={!yourClue.trim() || myClueSubmitted}>
                {myClueSubmitted ? "✓ Sent" : "Submit"}
              </button>
            </div>
            <div style={{ fontSize: 11, color: "var(--fg-3)" }}>
              <kbd style={kbdStyle}>Enter</kbd> Submit · No spaces. Don't say the word.
            </div>
          </div>
        </div>

        <div className="tx-card" style={{ padding: 22, display: "flex", flexDirection: "column", gap: 12, minHeight: 0 }}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline" }}>
            <div className="tx-eyebrow">Clue feed</div>
            <span style={{ fontSize: 12, color: "var(--fg-3)" }}>{cluesIn}/{players.length} in</span>
          </div>
          <div style={{ display: "flex", flexDirection: "column", gap: 8, flex: 1, overflow: "auto" }} className="tx-noscroll">
            {players.map(p => {
              const clue = clues[p.id];
              const isMe = p.id === myId;
              return (
                <div key={p.id} className={clue ? "tx-pop" : ""} style={{
                  display: "flex", alignItems: "center", gap: 12, padding: "10px 12px", borderRadius: 10,
                  background: clue ? "rgba(255,255,255,0.03)" : "transparent",
                  border: clue ? "1px solid var(--line-2)" : "1px dashed var(--line)",
                }}>
                  <Avatar player={{ ...p, you: isMe }} size={28} />
                  <span style={{ fontSize: 13, fontWeight: 500, minWidth: 80 }}>
                    {p.name}{isMe && <span style={{ color: "var(--fg-3)", fontWeight: 400 }}> · you</span>}
                  </span>
                  <span style={{ flex: 1 }} />
                  {clue ? (
                    <span style={{ fontFamily: "var(--font-mono)", fontSize: 16, fontWeight: 600, color: game.accentRaw }}>{clue}</span>
                  ) : (
                    <span style={{ display: "flex", gap: 3 }}>
                      {[0,1,2].map(d => (
                        <span key={d} style={{ width: 4, height: 4, borderRadius: "50%", background: "var(--fg-3)", animation: `tx-typing 1.2s ${d * 0.15}s infinite` }} />
                      ))}
                    </span>
                  )}
                </div>
              );
            })}
          </div>
        </div>
      </div>

      <StatusFooter
        status={myClueSubmitted ? "Clue submitted." : "Give a 1-word clue."}
        hint={myClueSubmitted ? `Waiting on others… (${cluesIn}/${players.length} in)` : "Hint at your word but don't give it away."}
        secondaryLabel={isHost && cluesIn === players.length ? "Move to vote →" : null}
        onSecondary={isHost ? () => onAction({ type: "submitClue", clue: yourClue.trim() || "—" }) : null}
      />
      <style>{`@keyframes tx-typing { 0%,60%,100%{opacity:.25} 30%{opacity:1} }`}</style>
    </div>
  );
}

// ── LETTER GAME ───────────────────────────────────────────────────────────
function LetterScreen({ roomState, isHost, myId, onAction, onAdvance }) {
  const game = GAMES.letter;
  const { players, round = 1, rounds = 5, code, gameState: gs } = roomState;

  const letters      = gs?.letters || ["S","T","R"];
  const turnPlayerIdx = gs?.turnPlayerIdx ?? 0;
  const phase        = gs?.phase || "play";
  const challengedId = gs?.challengedId;
  const challengeResult = gs?.challengeResult;

  const currentPlayer = players[turnPlayerIdx % players.length];
  const yourTurn = currentPlayer?.id === myId;
  const [yourLetter, setYourLetter] = React.useState("");

  const [timer] = useCountdown(15, {
    running: phase === "play" && yourTurn,
    key: `${turnPlayerIdx}-${letters.length}`,
  });

  const playLetter = () => {
    if (!yourLetter || !yourTurn) return;
    onAction({ type: "addLetter", letter: yourLetter });
    setYourLetter("");
  };

  // ── CHALLENGE phase ──
  if (phase === "challenge") {
    const challenged = players.find(p => p.id === challengedId);
    const word = gs?.challengeWord || letters.join("");
    const valid = challengeResult;

    return (
      <div className="tx-screen" style={{ padding: 24, gap: 18 }}>
        <GameTopBar game={game} code={code} timer={null} timerMax={15} phaseLabel="Challenge!" round={round} totalRounds={rounds} />
        <div style={{ flex: 1, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 28, textAlign: "center" }}>
          <div className="tx-eyebrow" style={{ color: game.accentRaw }}>Challenge → {challenged?.name}</div>
          <h1 className="tx-title xl" style={{ maxWidth: 700 }}>
            {challenged?.id === myId ? "Prove you had a word." : `${challenged?.name}, prove it.`}
          </h1>
          <div style={{ display: "flex", gap: 8, padding: 24, background: `radial-gradient(60% 80% at 50% 50%, ${game.accentRaw}33, transparent)` }}>
            {letters.map((L, i) => <LetterTile key={i} letter={L} accent={game.accentRaw} highlight idx={i} />)}
            <LetterTile letter="?" accent={game.accentRaw} ghostly />
          </div>
          <div className="tx-card" style={{ padding: 20, maxWidth: 460, width: "100%" }}>
            <div className="tx-eyebrow" style={{ marginBottom: 6 }}>
              {valid ? "Valid word — challenger loses." : "Not a valid continuation — challenged loses."}
            </div>
            <div style={{
              fontFamily: "var(--font-mono)", fontSize: 30, fontWeight: 700, letterSpacing: "0.08em",
              color: valid ? "var(--ok)" : "var(--bad)",
              textShadow: `0 0 calc(20px * var(--glow-strength)) ${valid ? "var(--ok)" : "var(--bad)"}55`,
            }}>{word}…</div>
          </div>
        </div>
        <StatusFooter
          status={valid ? `${challenged?.name} had a valid word.` : `${challenged?.name} was bluffing!`}
          hint="Round over."
          primaryLabel={isHost ? "See scores →" : "Waiting for host…"}
          primaryDisabled={!isHost}
          primaryGame="letter"
          onPrimary={onAdvance}
        />
      </div>
    );
  }

  // ── PLAY phase ──
  return (
    <div className="tx-screen" style={{ padding: 24, gap: 18 }}>
      <GameTopBar game={game} code={code} timer={yourTurn ? timer : null} timerMax={15}
        phaseLabel={yourTurn ? "Your turn" : `${currentPlayer?.name}'s turn`} round={round} totalRounds={rounds} />

      <div style={{ flex: 1, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 28 }}>
        <div className="tx-eyebrow" style={{ color: game.accentRaw }}>Word so far</div>
        <div style={{ display: "flex", gap: 10, flexWrap: "wrap", justifyContent: "center" }}>
          {letters.map((L, i) => <LetterTile key={i} letter={L} accent={game.accentRaw} idx={i} />)}
          <LetterTile letter={yourTurn ? (yourLetter || "_") : "…"} accent={game.accentRaw} pending={yourTurn} ghostly={!yourTurn} />
        </div>
        <div style={{ fontSize: 13, color: "var(--fg-2)", maxWidth: 460, textAlign: "center" }}>
          Add a letter without completing a real word. Or <strong style={{ color: "var(--fg-1)" }}>Challenge</strong> if you think the last player was bluffing.
        </div>
        <div style={{ display: "flex", gap: 8, alignItems: "center", marginTop: 4 }}>
          {players.map((p, i) => (
            <div key={p.id} style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 4, opacity: i === turnPlayerIdx % players.length ? 1 : 0.4, transform: i === turnPlayerIdx % players.length ? "scale(1.06)" : "scale(1)", transition: "all 200ms" }}>
              <Avatar player={{ ...p, you: p.id === myId }} size={32} speaking={i === turnPlayerIdx % players.length} />
              <span style={{ fontSize: 10, color: i === turnPlayerIdx % players.length ? game.accentRaw : "var(--fg-3)", fontWeight: 600, letterSpacing: ".04em", textTransform: "uppercase" }}>
                {i === turnPlayerIdx % players.length ? "Now" : p.name.slice(0, 4)}
              </span>
            </div>
          ))}
        </div>
      </div>

      <footer style={{ display: "flex", gap: 12, alignItems: "center" }}>
        <button className="tx-btn ghost" onClick={() => onAction({ type: "challenge" })} disabled={letters.length < 2}>
          <span style={{ color: "var(--bad)" }}>⚠</span> Challenge
        </button>
        <div style={{ flex: 1, display: "flex", gap: 10 }}>
          <input className="tx-input"
            placeholder={yourTurn ? "Type one letter…" : `Waiting for ${currentPlayer?.name}…`}
            disabled={!yourTurn}
            value={yourLetter}
            maxLength={1}
            onChange={e => setYourLetter(e.target.value.toUpperCase().replace(/[^A-Z]/g, ""))}
            onKeyDown={e => { if (e.key === "Enter") playLetter(); }}
            style={{ flex: 1, fontFamily: "var(--font-mono)", textAlign: "center", fontSize: 22, fontWeight: 700, letterSpacing: "0.1em" }}
          />
          <button className="tx-btn accent" data-game="letter" disabled={!yourTurn || !yourLetter} onClick={playLetter}>
            Add Letter
          </button>
        </div>
      </footer>
    </div>
  );
}

function LetterTile({ letter, accent, highlight, ghostly, pending, idx = 0 }) {
  return (
    <span className={!ghostly ? "tx-pop" : ""} style={{
      width: 64, height: 80, display: "inline-flex", alignItems: "center", justifyContent: "center",
      fontFamily: "var(--font-mono)", fontWeight: 700, fontSize: 38, borderRadius: 12,
      background: highlight ? `linear-gradient(180deg, color-mix(in oklab, ${accent} 22%, var(--bg-2)) 0%, var(--bg-1) 100%)` : ghostly ? "transparent" : "rgba(255,255,255,0.04)",
      border: ghostly ? `1.5px dashed ${accent}55` : `1px solid ${highlight ? accent : "var(--line-2)"}`,
      color: ghostly ? "var(--fg-3)" : (highlight ? accent : "var(--fg-0)"),
      boxShadow: highlight ? `0 0 calc(20px * var(--glow-strength)) ${accent}55` : "none",
      animationDelay: `${idx * 40}ms`, letterSpacing: 0,
      textShadow: pending ? `0 0 18px ${accent}88` : "none",
    }}>{letter}</span>
  );
}

// ── WRONG ANSWER WINS ─────────────────────────────────────────────────────
function WrongScreen({ roomState, isHost, myId, onAction, onAdvance }) {
  const game = GAMES.wrong;
  const { players, round = 1, rounds = 5, code, gameState: gs } = roomState;

  const phase     = gs?.phase || "answer";
  const qIdx      = gs?.questionIdx ?? 0;
  const answers   = gs?.answers || {};
  const Q         = WRONG_QUESTIONS_DATA[qIdx % WRONG_QUESTIONS_DATA.length];

  const [answer, setAnswer] = React.useState("");
  const myAnswer = answers[myId];
  const submitted = !!myAnswer;
  const answersIn = players.filter(p => answers[p.id]).length;

  const [timer] = useCountdown(30, {
    running: phase === "answer" && !submitted,
    onEnd: () => { if (!submitted) onAction({ type: "submitAnswer", answer: answer.trim() || "—" }); },
    key: phase,
  });

  // ── REVEAL phase ──
  if (phase === "reveal") {
    const vals = Object.fromEntries(players.map(p => [p.id, (answers[p.id] || "").trim().toLowerCase()]));
    const counts = {};
    Object.values(vals).forEach(a => { if (a) counts[a] = (counts[a] || 0) + 1; });

    return (
      <div className="tx-screen" style={{ padding: 24, gap: 18 }}>
        <GameTopBar game={game} code={code} timer={null} timerMax={30} phaseLabel="Reveal" round={round} totalRounds={rounds} />
        <div style={{ flex: 1, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 24 }}>
          <div className="tx-eyebrow" style={{ color: game.accentRaw }}>The question was</div>
          <h1 className="tx-title xl" style={{ maxWidth: 760, textAlign: "center" }}>{Q.q}</h1>
          <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(180px, 1fr))", gap: 14, maxWidth: 920, width: "100%" }}>
            {players.map(p => {
              const a = answers[p.id] || "";
              const k = a.trim().toLowerCase();
              const dup = counts[k] > 1;
              const canon = Q.canon.includes(k);
              const losing = dup || canon || !a;
              return (
                <div key={p.id} className="tx-pop" style={{
                  padding: 18, borderRadius: 14,
                  background: losing ? "rgba(255,84,112,0.08)" : `linear-gradient(180deg, color-mix(in oklab, ${game.accentRaw} 14%, var(--bg-2)) 0%, var(--bg-1) 100%)`,
                  border: losing ? "1px solid rgba(255,84,112,0.35)" : `1px solid ${game.accentRaw}88`,
                  boxShadow: !losing ? `0 0 0 1px ${game.accentRaw}33, 0 8px 24px ${game.accentRaw}22` : "none",
                  minHeight: 130, display: "flex", flexDirection: "column", gap: 10,
                }}>
                  <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                    <Avatar player={{ ...p, you: p.id === myId }} size={26} />
                    <span style={{ fontSize: 12, fontWeight: 500 }}>
                      {p.name}{p.id === myId && <span style={{ color: "var(--fg-3)" }}> · you</span>}
                    </span>
                  </div>
                  <div style={{ fontFamily: "var(--font-mono)", fontSize: 22, fontWeight: 700, color: losing ? "var(--bad)" : game.accentRaw, textTransform: "lowercase" }}>
                    {a || "—"}
                  </div>
                  <div style={{ marginTop: "auto", fontSize: 11, color: losing ? "var(--bad)" : "var(--ok)", fontWeight: 600, letterSpacing: ".06em", textTransform: "uppercase" }}>
                    {!a ? "× No answer" : dup ? "× Duplicate" : canon ? "× Too obvious" : "✓ +1 point"}
                  </div>
                </div>
              );
            })}
          </div>
        </div>
        <StatusFooter
          status="Round complete."
          hint="Wrong + unique = points. Obvious or duplicate = zero."
          primaryLabel={isHost ? "See scores →" : "Waiting for host…"}
          primaryDisabled={!isHost}
          primaryGame="wrong"
          onPrimary={onAdvance}
        />
      </div>
    );
  }

  // ── ANSWER phase ──
  return (
    <div className="tx-screen" style={{ padding: 24, gap: 18 }}>
      <GameTopBar game={game} code={code} timer={timer} timerMax={30} phaseLabel="Be wrong" round={round} totalRounds={rounds} />
      <div style={{ flex: 1, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 28 }}>
        <div className="tx-eyebrow" style={{ color: game.accentRaw }}>Question</div>
        <h1 className="tx-title xl" style={{ maxWidth: 820, textAlign: "center", textShadow: `0 0 calc(40px * var(--glow-strength)) ${game.accentRaw}33` }}>
          {Q.q}
        </h1>
        <div className="tx-sub" style={{ maxWidth: 460, textAlign: "center" }}>
          Give a wrong answer. Match someone else and you both lose the point.
        </div>
        <div style={{ width: "100%", maxWidth: 520, display: "flex", flexDirection: "column", gap: 12 }}>
          <div style={{ display: "flex", gap: 10 }}>
            <input className="tx-input" autoFocus
              placeholder="Your wrong answer…"
              value={answer}
              disabled={submitted}
              onChange={e => setAnswer(e.target.value.slice(0, 32))}
              onKeyDown={e => { if (e.key === "Enter" && answer.trim()) onAction({ type: "submitAnswer", answer: answer.trim() }); }}
              style={{ flex: 1, height: 60, fontSize: 18 }}
            />
            <button className="tx-btn accent lg" data-game="wrong"
              disabled={!answer.trim() || submitted}
              onClick={() => onAction({ type: "submitAnswer", answer: answer.trim() })}>
              {submitted ? "✓ Locked" : "Submit"}
            </button>
          </div>
          <div style={{ display: "flex", justifyContent: "space-between", color: "var(--fg-3)", fontSize: 11 }}>
            <span><kbd style={kbdStyle}>Enter</kbd> Submit</span>
            <span>{answersIn}/{players.length} answered</span>
          </div>
        </div>
        <div style={{ display: "flex", gap: 10, marginTop: 8, flexWrap: "wrap", justifyContent: "center" }}>
          {players.map(p => (
            <div key={p.id} style={{ display: "flex", alignItems: "center", gap: 6, padding: "6px 10px", borderRadius: 999, background: "rgba(255,255,255,0.04)", border: "1px solid var(--line)", fontSize: 11, color: "var(--fg-2)" }}>
              <Avatar player={{ ...p, you: p.id === myId }} size={20} />
              {p.name}
              <span style={{ width: 6, height: 6, borderRadius: "50%", background: answers[p.id] ? "var(--ok)" : game.accentRaw, animation: !answers[p.id] ? "tx-blink 1.4s infinite" : "none" }} />
            </div>
          ))}
        </div>
      </div>
      <StatusFooter
        status={submitted ? "Locked in. Waiting for others…" : "Type something wrong, hit Enter."}
        hint={submitted ? null : "Stay weird. Stay unique."}
        secondaryLabel={isHost ? "Force reveal" : null}
        onSecondary={isHost ? () => onAction({ type: "submitAnswer", answer: answer.trim() || "—" }) : null}
      />
      <style>{`@keyframes tx-blink { 0%,100%{opacity:.3} 50%{opacity:1} }`}</style>
    </div>
  );
}

// ── RESULTS / SCORES ──────────────────────────────────────────────────────
function ResultsScreen({ roomState, isHost, myId, onNextRound, onPlayAgain, onLeave, isFinal }) {
  const { players, game: gameId, round = 1, rounds = 5, code } = roomState;
  const game = GAMES[gameId];

  const scored = [...players].sort((a, b) => (b.score || 0) - (a.score || 0));
  const winner = scored[0];

  return (
    <div className="tx-screen" style={{ padding: 24, gap: 18 }}>
      <TopBar
        left={<>
          <span style={{ width: 6, height: 24, background: game.accentRaw, borderRadius: 2 }} />
          <span style={{ fontWeight: 600, fontSize: 14 }}>{game.name}</span>
          <span style={{ color: "var(--fg-3)", fontSize: 12, marginLeft: 4 }}>
            {isFinal ? "Final results" : `End of round ${round}`}
          </span>
        </>}
        right={<>
          <Chip mono style={{ letterSpacing: "0.14em" }}>{code}</Chip>
        </>}
      />

      <div style={{ flex: 1, display: "grid", gridTemplateColumns: "1.2fr 1fr", gap: 22, minHeight: 0 }}>
        <div className="tx-card" style={{
          padding: 28, display: "flex", flexDirection: "column", gap: 18,
          background: `linear-gradient(160deg, color-mix(in oklab, ${game.accentRaw} 14%, var(--bg-2)) 0%, var(--bg-1) 100%)`,
          border: `1px solid color-mix(in oklab, ${game.accentRaw} 30%, transparent)`,
        }}>
          <div className="tx-eyebrow" style={{ color: game.accentRaw }}>
            {isFinal ? "Winner" : "Round leader"}
          </div>
          <div style={{ display: "flex", alignItems: "center", gap: 18 }}>
            <div style={{ position: "relative" }}>
              <Avatar player={{ ...winner, you: winner.id === myId }} size={88} />
              <span style={{ position: "absolute", bottom: -6, right: -6, width: 28, height: 28, borderRadius: "50%", background: game.accentRaw, color: "#0a0b10", display: "flex", alignItems: "center", justifyContent: "center", fontWeight: 800, fontSize: 14, boxShadow: game.glow }}>1</span>
            </div>
            <div>
              <div className="tx-title lg">{winner.name}{winner.id === myId && " (you!)"}</div>
              <div className="tx-sub" style={{ marginTop: 4 }}>
                <span style={{ fontFamily: "var(--font-mono)", fontWeight: 700, color: "var(--fg-0)", fontSize: 22 }}>{winner.score || 0}</span>
                {" points"}
                {(winner.delta || 0) > 0 && <span style={{ color: "var(--ok)" }}> · +{winner.delta} this round</span>}
              </div>
            </div>
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 10, alignItems: "end", marginTop: 12, height: 160 }}>
            {[scored[1], scored[0], scored[2]].filter(Boolean).map((p, i) => {
              const place = [2,1,3][i], h = [110,150,80][i];
              return (
                <div key={p.id} style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 8 }}>
                  <Avatar player={{ ...p, you: p.id === myId }} size={40} />
                  <div style={{ fontSize: 12, fontWeight: 600 }}>{p.id === myId ? "You" : p.name}</div>
                  <div style={{ height: h, width: "100%", borderRadius: "10px 10px 0 0", background: place === 1 ? `linear-gradient(180deg, ${game.accentRaw}, color-mix(in oklab, ${game.accentRaw} 40%, var(--bg-2)))` : "rgba(255,255,255,0.06)", border: place === 1 ? `1px solid ${game.accentRaw}` : "1px solid var(--line-2)", borderBottom: 0, display: "flex", alignItems: "flex-start", justifyContent: "center", paddingTop: 8, fontFamily: "var(--font-mono)", fontWeight: 700, color: place === 1 ? "#0a0b10" : "var(--fg-1)", boxShadow: place === 1 ? game.glow : "none" }}>
                    #{place}
                  </div>
                </div>
              );
            })}
          </div>
        </div>

        <div className="tx-card" style={{ padding: 22, display: "flex", flexDirection: "column", gap: 8, minHeight: 0 }}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline" }}>
            <div className="tx-eyebrow">Scoreboard</div>
            <span style={{ color: "var(--fg-3)", fontSize: 12 }}>{round}/{rounds} rounds</span>
          </div>
          <div style={{ display: "flex", flexDirection: "column", gap: 4, overflow: "auto" }} className="tx-noscroll">
            {scored.map((p, i) => (
              <div key={p.id} style={{ display: "flex", alignItems: "center", gap: 12, padding: "10px 12px", borderRadius: 10, background: i === 0 ? `${game.accentRaw}10` : "transparent", border: i === 0 ? `1px solid ${game.accentRaw}40` : "1px solid transparent" }}>
                <span style={{ width: 22, textAlign: "center", fontFamily: "var(--font-mono)", fontWeight: 700, fontSize: 14, color: i === 0 ? game.accentRaw : "var(--fg-3)" }}>{i + 1}</span>
                <Avatar player={{ ...p, you: p.id === myId }} size={28} />
                <span style={{ flex: 1, fontSize: 13, fontWeight: 500 }}>
                  {p.name}{p.id === myId && <span style={{ color: "var(--fg-3)", fontWeight: 400 }}> · you</span>}
                </span>
                {(p.delta || 0) > 0 && <span style={{ fontSize: 11, color: "var(--ok)", fontWeight: 600 }}>+{p.delta}</span>}
                <span style={{ fontFamily: "var(--font-mono)", fontWeight: 700, fontSize: 16, color: i === 0 ? game.accentRaw : "var(--fg-0)", width: 40, textAlign: "right" }}>{p.score || 0}</span>
              </div>
            ))}
          </div>
        </div>
      </div>

      <footer style={{ display: "flex", gap: 10, alignItems: "center" }}>
        <button className="tx-btn ghost" onClick={onLeave}>← Leave room</button>
        <span style={{ flex: 1 }} />
        {isHost ? (
          isFinal ? (
            <button className="tx-btn accent" data-game={gameId} onClick={onPlayAgain}>Play again →</button>
          ) : (
            <button className="tx-btn accent" data-game={gameId} onClick={onNextRound}>Next round →</button>
          )
        ) : (
          <div style={{ fontSize: 13, color: "var(--fg-3)" }}>Waiting for host to continue…</div>
        )}
      </footer>
    </div>
  );
}

Object.assign(window, {
  ImpostorScreen, LetterScreen, WrongScreen, ResultsScreen,
});
