/* screens.jsx — SelectScreen, GameScreen, ScoreScreen. Exports to window. */
const { useState: useS, useEffect: useE, useRef: useR } = React;

/* ============ HUBSPOT LIST PICKER ============ */
function ListScreen({ data, titleArt, onPick, mode, conn, loading, err, onLogout, onConnect }) {
  const [hover, setHover] = useS(null);
  const [search, setSearch] = useS("");
  const lists = (data.lists || []).filter(L => !search || (L.name || "").toLowerCase().includes(search.toLowerCase()));
  return (
    <div style={{ position: "absolute", inset: 0, display: "flex", flexDirection: "column", background: "var(--bg)", overflow: "hidden" }}>
      <div style={{ position: "absolute", inset: 0, background: "radial-gradient(ellipse at 50% -10%, var(--panel-edge), var(--bg) 62%)", opacity: .85 }} />
      <div style={{ position: "relative", padding: "30px 40px 6px", display: "flex", justifyContent: "space-between", alignItems: "flex-start", flexWrap: "wrap", gap: 14 }}>
        <Logo variant={titleArt} size={1.4} />
        <div style={{ display: "flex", flexDirection: "column", alignItems: "flex-end", gap: 9, fontFamily: "var(--font)" }}>
          {mode === "live" ? (
            <React.Fragment>
              <div style={{ display: "flex", alignItems: "center", gap: 8, color: "var(--good)", fontSize: "calc(13px * var(--fscale))" }}>
                <span style={{ width: 11, height: 11, background: "var(--good)", boxShadow: "0 0 8px var(--good)", display: "inline-block", animation: "blink 1.4s steps(2) infinite" }} />
                HUBSPOT CONNECTED
              </div>
              <div style={{ color: "var(--ink-dim)", fontSize: "calc(11px * var(--fscale))", letterSpacing: ".08em" }}>
                {conn && conn.portalId ? "PORTAL #" + conn.portalId : "PORTAL"}{conn && conn.email ? " · " + conn.email : ""}
              </div>
              <button onClick={onLogout} style={ghostBtn}>DISCONNECT</button>
            </React.Fragment>
          ) : (
            <React.Fragment>
              <div style={{ display: "flex", alignItems: "center", gap: 8, color: "var(--accent2)", fontSize: "calc(13px * var(--fscale))" }}>
                <span style={{ width: 11, height: 11, background: "var(--accent2)", display: "inline-block" }} />
                DEMO MODE · NOTHING REAL IS DELETED
              </div>
              <button onClick={onConnect} style={{ ...ghostBtn, color: "var(--good)", borderColor: "var(--good)" }}>CONNECT HUBSPOT ▸</button>
            </React.Fragment>
          )}
        </div>
      </div>

      <div style={{ position: "relative", padding: "12px 40px 4px" }}>
        <div style={{ fontFamily: "var(--font)", color: "var(--ink)", fontSize: "calc(21px * var(--fscale))" }}>CHOOSE YOUR HIT LIST</div>
        <div style={{ fontFamily: "var(--font)", color: "var(--ink-dim)", fontSize: "calc(14px * var(--fscale))", marginTop: 12, lineHeight: 1.8, maxWidth: 940 }}>
          Pick a HubSpot list. Every contact and company inside it becomes a demon in the arena. What dies in the arena, dies in the CRM. <span style={{ color: "var(--accent2)" }}>You can resurrect the survivors. The dead, mostly.</span>
        </div>
      </div>
      {(loading || err || (data && data.needsReconnect)) && (
        <div style={{ position: "relative", padding: "0 40px 8px", fontFamily: "var(--font)", fontSize: "calc(13px * var(--fscale))" }}>
          {loading ? <span style={{ color: "var(--accent2)" }}>▮ SCANNING YOUR CRM FOR SEGMENTS…</span>
            : err ? <span style={{ color: "var(--accent)" }}>✗ Couldn't load lists: {err}</span>
            : <span style={{ color: "var(--accent)" }}>Reconnect to grant access to your Lists — <button onClick={onConnect} style={ghostBtn}>RECONNECT</button></span>}
        </div>
      )}

      <div style={{ position: "relative", padding: "8px 40px 4px" }}>
        <input value={search} onChange={e => setSearch(e.target.value)} placeholder="SEARCH LISTS BY NAME…"
          style={{ width: "100%", maxWidth: 560, boxSizing: "border-box", fontFamily: "var(--font)", fontSize: "calc(13px * var(--fscale))", color: "var(--ink)",
            background: "rgba(0,0,0,.4)", border: "2px solid var(--panel-edge)", padding: "12px 15px", outline: "none", letterSpacing: ".05em" }} />
      </div>

      <div style={{ position: "relative", flex: 1, overflowY: "auto", padding: "14px 40px 24px" }}>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(440px, 1fr))", gap: 16 }}>
          {lists.map(L => {
            const on = hover === L.id;
            return (
              <div key={L.id} onMouseEnter={() => setHover(L.id)} onMouseLeave={() => setHover(null)} onClick={() => onPick(L)}
                style={{ cursor: "pointer", background: "var(--panel)", border: `3px solid ${on ? "var(--accent)" : "var(--panel-edge)"}`,
                  padding: "20px 22px", display: "flex", flexDirection: "column", gap: 12, position: "relative",
                  boxShadow: on ? "inset 0 0 0 1px var(--accent), 0 0 18px rgba(0,0,0,.5)" : "inset -3px -4px 0 rgba(0,0,0,.4)",
                  transform: on ? "translateY(-2px)" : "none", transition: "transform .08s, border-color .08s" }}>
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 10 }}>
                  <div style={{ fontFamily: "var(--font)", fontSize: "calc(16px * var(--fscale))", color: "var(--ink)", lineHeight: 1.45 }}>{L.name}</div>
                  <span style={{ fontFamily: "var(--font)", fontSize: "calc(10px * var(--fscale))", color: L.kind === "SMART LIST" ? "var(--accent2)" : "var(--ink-dim)", border: "1px solid currentColor", padding: "3px 6px", whiteSpace: "nowrap", letterSpacing: ".08em" }}>{L.kind}</span>
                </div>
                <div style={{ fontFamily: "var(--font)", fontSize: "calc(12px * var(--fscale))", color: "var(--ink-dim)", lineHeight: 1.7 }}>{L.blurb}</div>
                <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginTop: 2 }}>
                  <div style={{ display: "flex", gap: 14, fontFamily: "var(--font)", fontSize: "calc(12px * var(--fscale))" }}>
                    <span style={{ color: "var(--accent)" }}>{L.total} <span style={{ color: "var(--ink-dim)" }}>RECORDS</span></span>
                    <span style={{ color: "var(--ink-dim)" }}>{L.contacts}p · {L.companies}co</span>
                  </div>
                  <span style={{ fontFamily: "var(--font)", fontSize: "calc(12px * var(--fscale))", color: on ? "var(--accent)" : "var(--ink-dim)" }}>{on ? "DEPLOY ▸" : "owner: " + L.owner}</span>
                </div>
              </div>
            );
          })}
          {lists.length === 0 && !loading && (
            <div style={{ fontFamily: "var(--font)", fontSize: "calc(13px * var(--fscale))", color: "var(--ink-dim)", padding: 20 }}>
              {search ? "No lists match “" + search + "”." : "No lists found."}
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

/* ============ TARGET SELECT ============ */
function SelectScreen({ list, titleArt, selectedIds, toggle, selectAll, clearAll, filter, setFilter, onStart, onBack, hasMore, onLoadMore, loadingMore }) {
  const all = list.members;
  const recs = filter === "contacts" ? all.filter(r => r.type === "contact")
    : filter === "companies" ? all.filter(r => r.type === "company") : all;
  const count = selectedIds.size;
  const tabs = [["both", "ALL " + all.length], ["contacts", "PEOPLE " + list.contacts], ["companies", "COMPANIES " + list.companies]];

  return (
    <div style={{ position: "absolute", inset: 0, display: "flex", flexDirection: "column", background: "var(--bg)", overflow: "hidden" }}>
      <div style={{ position: "absolute", inset: 0, background: "radial-gradient(ellipse at 50% -10%, var(--panel-edge), var(--bg) 60%)", opacity: .8 }} />
      <div style={{ position: "relative", padding: "22px 34px 8px", display: "flex", justifyContent: "space-between", alignItems: "flex-start", flexWrap: "wrap", gap: 14 }}>
        <div>
          <button onClick={onBack} style={{ ...ghostBtn, marginBottom: 12 }}>◂ ALL LISTS</button>
          <div style={{ fontFamily: "var(--font)", fontSize: "calc(15px * var(--fscale))", color: "var(--accent)" }}>{list.name}</div>
          <div style={{ fontFamily: "var(--font)", fontSize: "calc(8px * var(--fscale))", color: "var(--ink-dim)", marginTop: 8 }}>{list.blurb}</div>
        </div>
        <Logo variant={titleArt} size={0.62} />
      </div>

      {/* tabs */}
      <div style={{ position: "relative", display: "flex", gap: 6, padding: "10px 34px 10px", flexWrap: "wrap" }}>
        {tabs.map(([k, label]) => (
          <button key={k} onClick={() => setFilter(k)} style={{
            fontFamily: "var(--font)", fontSize: "calc(8px * var(--fscale))", padding: "9px 13px", cursor: "pointer",
            color: filter === k ? "#120806" : "var(--ink)", background: filter === k ? "var(--accent)" : "var(--panel)",
            border: "0", boxShadow: filter === k ? "inset -2px -3px 0 rgba(0,0,0,.4)" : "inset -2px -3px 0 rgba(0,0,0,.5), inset 2px 2px 0 rgba(255,255,255,.08)",
            letterSpacing: ".05em", textTransform: "uppercase",
          }}>{label}</button>
        ))}
        <div style={{ flex: 1 }} />
        <button onClick={() => selectAll(recs)} style={ghostBtn}>SELECT ALL</button>
        <button onClick={clearAll} style={ghostBtn}>CLEAR</button>
      </div>

      {/* list */}
      <div style={{ position: "relative", flex: 1, overflowY: "auto", margin: "4px 34px", border: "3px solid var(--panel-edge)", background: "rgba(0,0,0,.35)" }}>
        {recs.map(r => {
          const on = selectedIds.has(r.id);
          return (
            <div key={r.id} onClick={() => toggle(r.id)} style={{
              display: "grid", gridTemplateColumns: "26px 1fr auto", gap: 14, alignItems: "center",
              padding: "11px 16px", cursor: "pointer", borderBottom: "1px solid rgba(255,255,255,.05)",
              background: on ? "color-mix(in srgb, var(--accent) 16%, transparent)" : "transparent",
            }}>
              <div style={{
                width: 18, height: 18, border: "2px solid var(--ink-dim)", background: on ? "var(--accent)" : "transparent",
                boxShadow: on ? "inset 0 0 0 2px #120806" : "none", display: "flex", alignItems: "center", justifyContent: "center",
                color: "#120806", fontFamily: "var(--font)", fontSize: 11,
              }}>{on ? "✕" : ""}</div>
              <div style={{ minWidth: 0 }}>
                <div style={{ fontFamily: "var(--font)", fontSize: "calc(11px * var(--fscale))", color: "var(--ink)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{r.line1}</div>
                <div style={{ fontFamily: "var(--font)", fontSize: "calc(8px * var(--fscale))", color: "var(--ink-dim)", marginTop: 4, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{r.line2} · <span style={{ color: "color-mix(in srgb, var(--accent) 70%, var(--ink-dim))" }}>{r.reason}</span></div>
              </div>
              <div style={{ fontFamily: "var(--font)", fontSize: "calc(7px * var(--fscale))", letterSpacing: ".08em", padding: "4px 7px", color: r.type === "company" ? "var(--good)" : "var(--accent2)", border: `1px solid currentColor`, opacity: .8 }}>
                {r.type === "company" ? "CO" : "PERSON"}
              </div>
            </div>
          );
        })}
        {hasMore && (
          <div style={{ padding: "12px 16px", textAlign: "center" }}>
            <button onClick={onLoadMore} disabled={loadingMore} style={{ ...ghostBtn, opacity: loadingMore ? 0.5 : 1 }}>
              {loadingMore ? "LOADING…" : "LOAD NEXT 100 ▾"}
            </button>
          </div>
        )}
      </div>

      {/* footer */}
      <div style={{ position: "relative", display: "flex", alignItems: "center", justifyContent: "space-between", gap: 16, padding: "14px 34px 22px", flexWrap: "wrap" }}>
        <div style={{ fontFamily: "var(--font)", color: "var(--ink)", fontSize: "calc(12px * var(--fscale))" }}>
          <span style={{ color: "var(--accent2)", fontSize: "calc(18px * var(--fscale))" }}>{count}</span>
          <span style={{ color: "var(--ink-dim)", fontSize: "calc(9px * var(--fscale))" }}>  DEMON{count === 1 ? "" : "S"} QUEUED FOR EXTERMINATION</span>
        </div>
        <PixelButton size="lg" disabled={count === 0} onClick={onStart}>ENTER THE ARENA ▸</PixelButton>
      </div>
    </div>
  );
}
const ghostBtn = {
  fontFamily: "var(--font)", fontSize: "calc(8px * var(--fscale))", padding: "9px 12px", cursor: "pointer",
  color: "var(--ink-dim)", background: "transparent", border: "1px solid var(--panel-edge)", letterSpacing: ".06em",
};

/* ============ GAME ============ */
function GameScreen({ records, theme, font, gore, spriteStyle, hudLayout, onKill, onGameOver }) {
  const canvasRef = useR(null);
  const labelRef = useR(null);
  const engRef = useR(null);
  const [stats, setStats] = useS({ health: 100, armor: 50, ammo: 18, kills: 0, total: records.length, remaining: records.length, combo: 0, acc: 100, weapon: "UNSUBSCRIBE CANNON", weaponId: "unsub", ammoType: "shells", store: { bullets: 70, shells: 18, rockets: 0, cells: 0 }, owned: { saw: 1, cold: 1, unsub: 1 } });
  const [bark, setBark] = useS(null);
  const [hurt, setHurt] = useS(false);
  const [hint, setHint] = useS(true);
  const [intro, setIntro] = useS(null);
  const hurtT = useR(null);

  useE(() => {
    const eng = new DoomEngine(canvasRef.current, {
      theme, font, gore, spriteStyle, enemies: records, labelCanvas: labelRef.current,
      callbacks: {
        onStats: s => setStats(s),
        onKill: rec => onKill(rec),
        onHurt: () => { setHurt(true); clearTimeout(hurtT.current); hurtT.current = setTimeout(() => setHurt(false), 320); },
        onBark: (text, kind) => setBark({ text, id: Math.random(), kind }),
        onGameOver: (reason, s) => onGameOver(reason, s),
      },
    });
    engRef.current = eng;
    window.__eng = eng; // dev: lets tooling aim the camera for screenshots
    if (new URLSearchParams(location.search).get("dev") === "game") {
      eng.god = true; eng.freeze = true;
      eng.owned = { saw: 1, cold: 1, unsub: 1, rip: 1, gat: 1, nuke: 1, bfd: 1 };
      eng.ammoStore = { bullets: 400, shells: 200, rockets: 40, cells: 50 };
    }
    requestAnimationFrame(() => { eng.resize(); eng.start(); });
    const onR = () => eng.resize();
    window.addEventListener("resize", onR);
    const D = window.DOOMSPOT_DATA;
    setIntro({ level: D.levelNames[(Math.random() * D.levelNames.length) | 0], tip: D.loadingTips[(Math.random() * D.loadingTips.length) | 0] });
    const introT = setTimeout(() => setIntro(null), 2800);
    const t = setTimeout(() => setHint(false), 5000);
    return () => { window.removeEventListener("resize", onR); clearTimeout(t); clearTimeout(introT); eng.destroy(); };
    // eslint-disable-next-line
  }, []);

  // live tweak updates
  useE(() => { engRef.current && engRef.current.setOption("theme", theme); }, [theme]);
  useE(() => { engRef.current && engRef.current.setOption("gore", gore); }, [gore]);
  useE(() => { engRef.current && engRef.current.setOption("font", font); }, [font]);
  useE(() => { engRef.current && engRef.current.setOption("spriteStyle", spriteStyle); }, [spriteStyle]);

  return (
    <div style={{ position: "absolute", inset: 0, background: "#000", overflow: "hidden" }}>
      <canvas ref={canvasRef} onContextMenu={e => e.preventDefault()}
        style={{ position: "absolute", inset: 0, width: "100%", height: "100%", imageRendering: "pixelated", cursor: "none", display: "block" }} />
      {/* crisp full-resolution overlay for nameplates (drawn by the engine) — keeps record names legible above the pixelated world */}
      <canvas ref={labelRef} aria-hidden="true"
        style={{ position: "absolute", inset: 0, width: "100%", height: "100%", pointerEvents: "none", display: "block" }} />

      {/* crosshair */}
      <div style={{ position: "absolute", left: "50%", top: "50%", transform: "translate(-50%,-50%)", pointerEvents: "none", mixBlendMode: "difference" }}>
        <div style={{ position: "absolute", width: 2, height: 14, background: "var(--crosshair)", left: -1, top: -7 }} />
        <div style={{ position: "absolute", width: 14, height: 2, background: "var(--crosshair)", left: -7, top: -1 }} />
        <div style={{ position: "absolute", width: 4, height: 4, border: "2px solid var(--crosshair)", left: -4, top: -4 }} />
      </div>

      <BarkToast bark={bark} />

      {/* level-name + tip intro card */}
      {intro && (
        <div style={{ position: "absolute", inset: 0, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", pointerEvents: "none", zIndex: 60, background: "radial-gradient(ellipse at 50% 50%, rgba(0,0,0,.55), rgba(0,0,0,.85))", animation: "introcard 2.8s ease-out forwards" }}>
          <div style={{ fontFamily: "var(--font)", fontSize: "calc(9px * var(--fscale))", color: "var(--ink-dim)", letterSpacing: ".34em", marginBottom: 16 }}>ENTERING</div>
          <div style={{ fontFamily: "'Press Start 2P', monospace", fontSize: "calc(30px)", color: "var(--accent)", textShadow: "3px 3px 0 #000", textAlign: "center", padding: "0 24px", lineHeight: 1.35 }}>{intro.level}</div>
          <div style={{ fontFamily: "var(--font)", fontSize: "calc(9px * var(--fscale))", color: "var(--accent2)", marginTop: 24, maxWidth: 560, textAlign: "center", lineHeight: 1.85, padding: "0 20px" }}>{intro.tip}</div>
        </div>
      )}

      {/* low-health pulse */}
      {stats.health < 34 && <div style={{ position: "absolute", inset: 0, pointerEvents: "none", boxShadow: "inset 0 0 120px rgba(180,20,12,.6)", animation: "hppulse 1s ease-in-out infinite" }} />}

      {/* controls hint */}
      {hint && (
        <div style={{ position: "absolute", top: 18, left: "50%", transform: "translateX(-50%)", textAlign: "center", fontFamily: "var(--font)", color: "var(--ink)", fontSize: "calc(8px * var(--fscale))", lineHeight: 2, background: "rgba(0,0,0,.6)", padding: "10px 18px", border: "1px solid var(--panel-edge)", pointerEvents: "none" }}>
          <span style={{ color: "var(--accent2)" }}>WASD</span> MOVE &nbsp; <span style={{ color: "var(--accent2)" }}>MOUSE</span> AIM &nbsp; <span style={{ color: "var(--accent2)" }}>CLICK / SPACE</span> PURGE &nbsp; <span style={{ color: "var(--accent2)" }}>1–6 / WHEEL</span> SWITCH GUN<br />
          <span style={{ color: "var(--ink-dim)" }}>(SHIFT run · arrows / Q·E turn · find more guns in the rooms · click once to lock mouse)</span>
        </div>
      )}

      <button onClick={() => onGameOver("retreat", { kills: stats.kills, total: stats.total, acc: stats.acc, maxCombo: stats.combo, health: stats.health })} style={{ position: "absolute", top: 14, right: 16, zIndex: 20, fontFamily: "var(--font)", fontSize: "calc(8px * var(--fscale))", color: "var(--ink-dim)", background: "rgba(0,0,0,.55)", border: "1px solid var(--panel-edge)", padding: "8px 11px", cursor: "pointer", letterSpacing: ".05em" }}>SURRENDER ✕</button>

      {/* current weapon name + ammo */}
      <div style={{ position: "absolute", bottom: 92, left: "50%", transform: "translateX(-50%)", pointerEvents: "none", zIndex: 15, fontFamily: "var(--font)", fontSize: "calc(9px * var(--fscale))", color: "var(--accent2)", textShadow: "2px 2px 0 #000", letterSpacing: ".08em", background: "rgba(0,0,0,.5)", padding: "5px 13px", border: "1px solid var(--panel-edge)", whiteSpace: "nowrap" }}>
        {stats.weapon || ""}{stats.ammo === -1 ? "  ·  ∞" : "  ·  " + stats.ammo}
      </div>

      <Hud stats={stats} hurt={hurt} layout={hudLayout} />
    </div>
  );
}

/* HUD layouts: classic / corners / minimal */
function Hud({ stats, hurt, layout }) {
  const item = (label, val, color) => (
    <div style={{ textAlign: "center" }}>
      <div style={{ fontFamily: "var(--font)", fontSize: "calc(7px * var(--fscale))", color: "var(--ink-dim)", letterSpacing: ".1em", marginBottom: 5 }}>{label}</div>
      <div style={{ fontFamily: "var(--font)", fontSize: "calc(20px * var(--fscale))", color, textShadow: "2px 2px 0 #000" }}>{val}</div>
    </div>
  );

  if (layout === "minimal") {
    return (
      <div style={{ position: "absolute", top: 12, left: 16, display: "flex", gap: 18, alignItems: "center", background: "rgba(0,0,0,.5)", padding: "8px 14px", border: "1px solid var(--panel-edge)" }}>
        <span style={{ fontFamily: "var(--font)", fontSize: "calc(13px * var(--fscale))", color: stats.health < 34 ? "var(--accent)" : "var(--ink)" }}>♥{stats.health}</span>
        <span style={{ fontFamily: "var(--font)", fontSize: "calc(13px * var(--fscale))", color: "var(--accent2)" }}>▮{stats.ammo}</span>
        <span style={{ fontFamily: "var(--font)", fontSize: "calc(13px * var(--fscale))", color: "var(--good)" }}>☠{stats.kills}/{stats.total}</span>
      </div>
    );
  }

  if (layout === "corners") {
    return (
      <React.Fragment>
        <div style={cornerBox("left")}>
          <FaceCanvas health={stats.health} hurt={hurt} size={44} />
          <div>
            <div style={{ fontFamily: "var(--font)", fontSize: "calc(22px * var(--fscale))", color: stats.health < 34 ? "var(--accent)" : "var(--ink)", lineHeight: 1 }}>{stats.health}<span style={{ fontSize: "calc(9px * var(--fscale))", color: "var(--ink-dim)" }}>%</span></div>
            <div style={{ width: 90, marginTop: 6 }}><StatBar value={stats.health} max={100} color="var(--accent)" /></div>
          </div>
        </div>
        <div style={cornerBox("right")}>
          <div style={{ textAlign: "right" }}>
            <div style={{ fontFamily: "var(--font)", fontSize: "calc(22px * var(--fscale))", color: "var(--accent2)", lineHeight: 1 }}>{stats.ammo}</div>
            <div style={{ fontFamily: "var(--font)", fontSize: "calc(7px * var(--fscale))", color: "var(--ink-dim)", marginTop: 5, letterSpacing: ".1em" }}>SHELLS</div>
          </div>
        </div>
        <div style={{ position: "absolute", top: 56, right: 16, textAlign: "right", fontFamily: "var(--font)" }}>
          <div style={{ fontSize: "calc(15px * var(--fscale))", color: "var(--good)" }}>☠ {stats.kills}/{stats.total}</div>
          <div style={{ fontSize: "calc(8px * var(--fscale))", color: "var(--ink-dim)", marginTop: 5 }}>ACC {stats.acc}%</div>
        </div>
      </React.Fragment>
    );
  }

  // ===== authentic Doom status bar =====
  const bigNum = (val, color) => (
    <div style={{ fontFamily: "'Press Start 2P', monospace", fontSize: "calc(30px * var(--fscale))", color, lineHeight: 1, textShadow: "0 2px 0 #000, 2px 0 0 rgba(0,0,0,.5)" }}>{val}</div>
  );
  const lbl = txt => <div style={{ fontFamily: "var(--font)", fontSize: "calc(7px * var(--fscale))", color: "var(--ink-dim)", letterSpacing: ".12em", marginTop: 7 }}>{txt}</div>;
  const cellBevel = { background: "rgba(0,0,0,.32)", boxShadow: "inset 2px 2px 0 rgba(0,0,0,.5), inset -2px -2px 0 rgba(255,255,255,.05)", padding: "10px 16px", display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center" };
  const SLOTS = { saw: 1, cold: 2, unsub: 3, rip: 3, gat: 4, nuke: 5, bfd: 6 };
  const owned = stats.owned || {};
  const ownedSlots = {}; Object.keys(owned).forEach(id => { if (owned[id] && SLOTS[id] != null) ownedSlots[SLOTS[id]] = true; });
  const curSlot = SLOTS[stats.weaponId];
  const arms = [1, 2, 3, 4, 5, 6].map(n => [String(n), !!ownedSlots[n], n === curSlot]);
  const store = stats.store || {};
  const curType = stats.ammoType;
  const typeKey = { BULL: "bullets", SHEL: "shells", RKT: "rockets", CEL: "cells" };
  const ammoTypes = [["BULL", store.bullets || 0], ["SHEL", store.shells || 0], ["RKT", store.rockets || 0], ["CEL", store.cells || 0]];
  return (
    <div style={{ position: "absolute", left: 0, right: 0, bottom: 0, display: "flex", alignItems: "stretch", justifyContent: "center", gap: 4, padding: "6px 8px", background: "linear-gradient(180deg, rgba(0,0,0,.0), rgba(0,0,0,.4) 18%, var(--panel) 42%)", borderTop: "3px solid var(--panel-edge)" }}>
      {/* AMMO (current weapon) */}
      <div style={{ ...cellBevel, minWidth: 96 }}>{bigNum(stats.ammo === -1 ? "∞" : stats.ammo, "var(--accent)")}{lbl(curType ? curType.toUpperCase() : "MELEE")}</div>
      {/* HEALTH */}
      <div style={{ ...cellBevel, minWidth: 110 }}>{bigNum(stats.health + "%", stats.health < 34 ? "var(--accent)" : "var(--accent)")}{lbl("HEALTH")}</div>
      {/* ARMS */}
      <div style={{ ...cellBevel, minWidth: 96 }}>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: "4px 9px" }}>
          {arms.map(([n, on, cur]) => (
            <span key={n} style={{ fontFamily: "'Press Start 2P', monospace", fontSize: "calc(11px * var(--fscale))", color: cur ? "var(--accent)" : on ? "var(--accent2)" : "rgba(255,255,255,.16)", textShadow: (on || cur) ? "0 1px 0 #000" : "none" }}>{n}</span>
          ))}
        </div>
        {lbl("ARMS")}
      </div>
      {/* FACE */}
      <div style={{ ...cellBevel, minWidth: 84, flex: "0 0 auto", padding: "6px 14px" }}>
        <div style={{ border: "2px solid var(--panel-edge)", background: "rgba(0,0,0,.4)", padding: 3 }}>
          <FaceCanvas health={stats.health} hurt={hurt} size={52} />
        </div>
      </div>
      {/* ARMOR */}
      <div style={{ ...cellBevel, minWidth: 100 }}>{bigNum(stats.armor + "%", "var(--accent2)")}{lbl("ARMOR")}</div>
      {/* KILLS (replaces Doom's keys panel — thematic) */}
      <div style={{ ...cellBevel, minWidth: 92 }}>{bigNum(stats.kills + "/" + stats.total, "var(--good)")}{lbl("PURGED")}</div>
      {/* AMMO TYPES */}
      <div style={{ ...cellBevel, minWidth: 116, alignItems: "stretch" }}>
        <div style={{ display: "grid", gridTemplateColumns: "auto auto", columnGap: 12, rowGap: 3, fontFamily: "'Press Start 2P', monospace", fontSize: "calc(8px * var(--fscale))", alignItems: "center" }}>
          {ammoTypes.map(([k, cur]) => {
            const on = typeKey[k] === curType;
            return (
              <React.Fragment key={k}>
                <span style={{ color: on ? "var(--accent2)" : "var(--ink-dim)" }}>{k}</span>
                <span style={{ color: on ? "var(--accent2)" : "var(--ink-dim)", textAlign: "right" }}>{cur}</span>
              </React.Fragment>
            );
          })}
        </div>
      </div>
    </div>
  );
}
function cornerBox(side) {
  return { position: "absolute", bottom: 16, [side]: 16, display: "flex", alignItems: "center", gap: 12, background: "rgba(0,0,0,.5)", padding: "10px 16px", border: "1px solid var(--panel-edge)" };
}

/* ============ SCOREBOARD + RESURRECT ============ */
function ScoreScreen({ reason, stats, deleted, onConfirm, onReplay, mode }) {
  const [restore, setRestore] = useS(new Set());
  const win = reason === "victory";
  const retreat = reason === "retreat";
  const [line] = useS(() => {
    const D = window.DOOMSPOT_DATA;
    if (retreat) return "You fled the arena. The leads remember. The leads always remember.";
    const arr = win ? D.winLines : D.deathLines;
    return arr[Math.floor(Math.random() * arr.length)];
  });
  const title = win ? "ARENA CLEARED" : retreat ? "YOU FLED" : "YOU DIED";
  const toggle = id => setRestore(s => { const n = new Set(s); n.has(id) ? n.delete(id) : n.add(id); return n; });
  const keep = deleted.length - restore.size;

  return (
    <div style={{ position: "absolute", inset: 0, background: "var(--bg)", display: "flex", flexDirection: "column", overflow: "hidden" }}>
      <div style={{ position: "absolute", inset: 0, background: win ? "radial-gradient(ellipse at 50% 0%, color-mix(in srgb, var(--good) 22%, transparent), transparent 55%)" : "radial-gradient(ellipse at 50% 0%, color-mix(in srgb, var(--blood) 32%, transparent), transparent 55%)" }} />
      <div style={{ position: "relative", textAlign: "center", padding: "34px 20px 16px" }}>
        <div style={{ fontFamily: "'Press Start 2P', monospace", fontSize: "calc(42px)", color: win ? "var(--good)" : "var(--accent)", textShadow: "4px 4px 0 #000", letterSpacing: ".02em" }}>
          {title}
        </div>
        <div style={{ fontFamily: "var(--font)", color: "var(--ink-dim)", fontSize: "calc(10px * var(--fscale))", marginTop: 14, letterSpacing: ".04em", maxWidth: 720, marginLeft: "auto", marginRight: "auto", lineHeight: 1.7 }}>
          {line}
        </div>
      </div>

      {/* stat grid */}
      <div style={{ position: "relative", display: "flex", justifyContent: "center", gap: 38, padding: "8px 20px 18px", flexWrap: "wrap" }}>
        {[["PURGED", `${stats.kills}/${stats.total}`, "var(--accent)"], ["ACCURACY", stats.acc + "%", "var(--ink)"], ["MAX COMBO", "x" + stats.maxCombo, "var(--accent2)"], ["HP LEFT", stats.health + "%", "var(--good)"]].map(([l, v, c]) => (
          <div key={l} style={{ textAlign: "center" }}>
            <div style={{ fontFamily: "var(--font)", fontSize: "calc(26px * var(--fscale))", color: c, textShadow: "2px 2px 0 #000" }}>{v}</div>
            <div style={{ fontFamily: "var(--font)", fontSize: "calc(8px * var(--fscale))", color: "var(--ink-dim)", marginTop: 7, letterSpacing: ".1em" }}>{l}</div>
          </div>
        ))}
      </div>

      {/* resurrect list */}
      <div style={{ position: "relative", padding: "0 34px 6px", display: "flex", justifyContent: "space-between", alignItems: "baseline" }}>
        <div style={{ fontFamily: "var(--font)", color: "var(--ink)", fontSize: "calc(11px * var(--fscale))" }}>THE GRAVEYARD <span style={{ color: "var(--ink-dim)", fontSize: "calc(8px * var(--fscale))" }}>· {deleted.length} deleted</span></div>
        <div style={{ fontFamily: "var(--font)", color: "var(--ink-dim)", fontSize: "calc(8px * var(--fscale))" }}>tick to resurrect</div>
      </div>
      <div style={{ position: "relative", flex: 1, overflowY: "auto", margin: "4px 34px", border: "3px solid var(--panel-edge)", background: "rgba(0,0,0,.35)" }}>
        {deleted.length === 0 && <div style={{ padding: 30, textAlign: "center", color: "var(--ink-dim)", fontFamily: "var(--font)", fontSize: "calc(9px * var(--fscale))" }}>No casualties. Suspicious.</div>}
        {deleted.map(r => {
          const res = restore.has(r.id);
          return (
            <div key={r.id} onClick={() => toggle(r.id)} style={{ display: "grid", gridTemplateColumns: "26px 1fr auto", gap: 14, alignItems: "center", padding: "10px 16px", cursor: "pointer", borderBottom: "1px solid rgba(255,255,255,.05)", background: res ? "color-mix(in srgb, var(--good) 14%, transparent)" : "transparent", opacity: res ? 1 : .62 }}>
              <div style={{ width: 18, height: 18, border: "2px solid var(--ink-dim)", background: res ? "var(--good)" : "transparent", display: "flex", alignItems: "center", justifyContent: "center", color: "#08160a", fontFamily: "var(--font)", fontSize: 10 }}>{res ? "↺" : ""}</div>
              <div style={{ minWidth: 0 }}>
                <div style={{ fontFamily: "var(--font)", fontSize: "calc(10px * var(--fscale))", color: "var(--ink)", textDecoration: res ? "none" : "line-through", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{r.line1}</div>
                <div style={{ fontFamily: "var(--font)", fontSize: "calc(8px * var(--fscale))", color: "var(--ink-dim)", marginTop: 4, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{r.line2}</div>
              </div>
              <div style={{ fontFamily: "var(--font)", fontSize: "calc(7px * var(--fscale))", color: res ? "var(--good)" : "var(--accent)", letterSpacing: ".06em" }}>{res ? "RESTORE" : "DELETED"}</div>
            </div>
          );
        })}
      </div>

      <div style={{ position: "relative", display: "flex", alignItems: "center", justifyContent: "space-between", gap: 16, padding: "14px 34px 22px", flexWrap: "wrap" }}>
        <div style={{ fontFamily: "var(--font)", fontSize: "calc(9px * var(--fscale))", color: "var(--ink-dim)" }}>
          <span style={{ color: "var(--good)" }}>{restore.size}</span> spared · <span style={{ color: "var(--accent)" }}>{keep}</span> {mode === "live" ? "to be ARCHIVED in HubSpot" : "purged (demo only)"}
        </div>
        <div style={{ display: "flex", gap: 12 }}>
          <PixelButton variant="ghost" onClick={onReplay}>◂ PLAY AGAIN</PixelButton>
          <PixelButton variant={mode === "live" ? "danger" : "good"} onClick={() => onConfirm([...restore])}>{mode === "live" ? "COMMIT TO HUBSPOT ▸" : "FINISH (DEMO) ▸"}</PixelButton>
        </div>
      </div>
    </div>
  );
}

/* ============ CONNECT GATE ============ */
function ConnectScreen({ titleArt, conn, onConnect, onPractice }) {
  const loading = conn === null;
  return (
    <div style={{ position: "absolute", inset: 0, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", background: "var(--bg)", overflow: "hidden", textAlign: "center", padding: 24 }}>
      <div style={{ position: "absolute", inset: 0, background: "radial-gradient(ellipse at 50% 0%, var(--panel-edge), var(--bg) 60%)", opacity: .9 }} />
      <div style={{ position: "relative", marginBottom: 34 }}><Logo variant={titleArt} size={1.7} /></div>
      <div style={{ position: "relative", fontFamily: "var(--font)", color: "var(--ink)", fontSize: "calc(20px * var(--fscale))", lineHeight: 1.9, maxWidth: 820, marginBottom: 30 }}>
        Connect HubSpot to drag your real stale contacts and companies into the arena and purge them for good — or play the demo with fake leads first. <span style={{ color: "var(--accent2)" }}>What dies in the arena, dies in your CRM.</span>
      </div>
      <div style={{ position: "relative", display: "flex", gap: 16, flexWrap: "wrap", justifyContent: "center" }}>
        <PixelButton size="lg" variant="good" disabled={loading} onClick={onConnect}>{loading ? "LOADING…" : "CONNECT HUBSPOT ▸"}</PixelButton>
        <PixelButton size="lg" variant="ghost" onClick={onPractice}>PLAY THE DEMO</PixelButton>
      </div>
      <div style={{ position: "relative", marginTop: 36, fontFamily: "var(--font)", color: "var(--ink-dim)", fontSize: "calc(16px * var(--fscale))", lineHeight: 2.0, maxWidth: 820 }}>
        <span style={{ color: "var(--accent2)" }}>HOW TO PLAY</span><br />
        Keys <span style={{ color: "var(--ink)" }}>1–6</span> switch weapons — from the Unsubscribe Cannon to the Workflow Decimator. <span style={{ color: "var(--ink)" }}>Arrow keys</span> to move, <span style={{ color: "var(--ink)" }}>Space</span> (or mouse) to shoot.
      </div>
      <div style={{ position: "relative", marginTop: 46, fontFamily: "var(--font)", color: "var(--ink-dim)", fontSize: "calc(11px * var(--fscale))", letterSpacing: ".2em" }}>
        by RESONATE · <a href="https://resonatehq.com" target="_blank" rel="noopener noreferrer" style={{ color: "var(--accent2)", textDecoration: "none" }}>resonatehq.com</a>
      </div>
    </div>
  );
}

Object.assign(window, { ConnectScreen, ListScreen, SelectScreen, GameScreen, ScoreScreen, Hud });
