import React, { useEffect, useState } from "react";
import { ClipboardList, Lightbulb, Map, FolderOpen, Sparkles, Bot, Boxes, Plug, Terminal } from "lucide-react";
import { C, FD, FB, FM, fmt, fmtWhen, intentOf, intentIcon, turnSeverity, shortPrompt } from "./theme.js";
import { useAnalysis, useApi, fetchAdvice, fetchOverview } from "./useAnalysis.js";
import { Chip, Stat, BinaryRow } from "./components/Primitives.jsx";
import Legend, { defaultVis } from "./components/Legend.jsx";
import SessionGraph from "./components/SessionGraph.jsx";
import TurnGraph from "./components/TurnGraph.jsx";
import { SessionDetail, TurnDetail, ToolDetail } from "./components/DetailPanel.jsx";
import SessionBrowser from "./components/SessionBrowser.jsx";
import ChatPanel from "./components/ChatPanel.jsx";
import ProjectView from "./components/ProjectView.jsx";
import ProjectsHome from "./components/ProjectsHome.jsx";
import SessionReport from "./components/SessionReport.jsx";
import DisclaimerModal, { needsDisclaimer } from "./components/DisclaimerModal.jsx";

// Session-level entity inventory (Mode A left rail): the skills, sub-agents, and
// MCP servers this ONE session used, each traceable to the turn that launched it —
// the same inventory the project view shows, scoped to the session. Renders nothing
// when the session used none (honest silence). Sub-agents run in their OWN
// transcripts, so this never changes the tool/causality counts in the Legend above.
function SessionEntities({ entities, binaries, onOpen }) {
  const bins = binaries || [];
  const groups = [
    ["subAgents", "Sub-agents", Bot, C.blue],
    ["skills", "Skills", Boxes, C.amber],
    ["mcpServers", "MCP servers", Plug, C.cyan],
  ];
  const hasEntities = !!entities && groups.some(([k]) => (entities[k] || []).length);
  if (!hasEntities && !bins.length) return null;
  return (
    <>
      {/* BINARIES — real tools run via Bash (npx remotion -> remotion, railway, …),
          a separate dimension from tool calls. Each row traces to its turn. */}
      {bins.length > 0 && (
        <>
          <div style={{ padding: "12px 10px 2px" }}>
            <span style={{ fontFamily: FM, fontSize: 10, letterSpacing: 1, color: C.muted }}>BINARIES RUN</span>
          </div>
          <div style={{ display: "flex", alignItems: "center", gap: 6, padding: "5px 13px 3px" }}>
            <Terminal size={11} color={C.orange} />
            <span style={{ fontFamily: FM, fontSize: 9.5, letterSpacing: 0.5, color: C.orange }}>via Bash</span>
            <span style={{ fontFamily: FM, fontSize: 9, color: C.muted }}>{bins.length}</span>
          </div>
          <div style={{ padding: "0 8px 6px" }}>
            {bins.map((b) => <BinaryRow key={b.binary} b={b} onOpen={onOpen} />)}
            <div style={{ fontFamily: FM, fontSize: 8.5, color: C.muted, padding: "4px 6px 0", lineHeight: 1.45 }}>
              extracted from the command (the real binary behind <code>npx</code>/<code>bash</code>) · click to jump to the turn it fired
            </div>
          </div>
        </>
      )}
      {!hasEntities ? null : (
      <>
      <div style={{ padding: "12px 10px 2px" }}>
        <span style={{ fontFamily: FM, fontSize: 10, letterSpacing: 1, color: C.muted }}>ENTITIES IN THIS SESSION</span>
      </div>
      <div style={{ padding: "0 8px 12px" }}>
        {groups.map(([k, label, Icon, color]) => {
          const rows = entities[k] || [];
          if (!rows.length) return null;
          return (
            <div key={k} style={{ marginBottom: 6 }}>
              <div style={{ display: "flex", alignItems: "center", gap: 6, padding: "5px 5px 3px" }}>
                <Icon size={11} color={color} />
                <span style={{ fontFamily: FM, fontSize: 9.5, letterSpacing: 0.5, color }}>{label}</span>
                <span style={{ fontFamily: FM, fontSize: 9, color: C.muted }}>{rows.length}</span>
              </div>
              {rows.map((e) => (
                <div key={e.name} className="row lift"
                  onClick={() => e.turns && e.turns.length && onOpen(e.turns[0])}
                  title={`used in turn(s) ${(e.turns || []).join(", ")}${e.via ? " · via " + e.via : ""}${e.workflow ? " · workflow " + e.workflow : ""}`}
                  style={{ display: "flex", alignItems: "center", gap: 6, padding: "4px 8px", borderRadius: 6, cursor: "pointer", borderLeft: `2px solid ${color}` }}>
                  <span style={{ fontFamily: FM, fontSize: 11.5, color: C.text2, flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{e.name}</span>
                  <span style={{ fontFamily: FM, fontSize: 9, color: C.muted }}>×{e.count}</span>
                </div>
              ))}
            </div>
          );
        })}
        <div style={{ fontFamily: FM, fontSize: 8.5, color: C.muted, padding: "4px 6px 0", lineHeight: 1.45 }}>
          launched from the cited turn · each runs in its own transcript, so it doesn't change the tool or causality counts above
        </div>
      </div>
      </>
      )}
    </>
  );
}

export default function App() {
  // sourcePath: null = no session loaded (welcome) · "__demo__" = the bundled demo
  // session (click-to-load, never a default) · else a real ~/.claude session, all
  // analyzed live by the API server.
  const [sourcePath, setSourcePath] = useState(null);
  const { status, data, narrated, error } = useAnalysis(sourcePath);
  const api = useApi();

  // view: "report" = executive summary (DEFAULT) · "session" = Mode A journey graph
  // · "turn" = Mode B drill-in
  const [view, setView] = useState("report");
  const [ti, setTi] = useState(0);     // selected turn index
  const [tool, setTool] = useState(null); // selected tool index in Mode B
  const [vis, setVis] = useState(defaultVis);
  const [atHome, setAtHome] = useState(true); // top-level Projects landing is the default
  const [browserOpen, setBrowserOpen] = useState(false);
  const [chatOpen, setChatOpen] = useState(false);
  const [overview, setOverview] = useState(null); // plain-English "what happened"
  const [advice, setAdvice] = useState(null); // LLM "what could have been better", session-scoped
  const [projectCwd, setProjectCwd] = useState(null); // project scope (many sessions)
  const [showDisclaimer, setShowDisclaimer] = useState(needsDisclaimer()); // first-run opt-in
  const consentModal = showDisclaimer ? <DisclaimerModal onDone={() => setShowDisclaimer(false)} /> : null;

  const hasApiEarly = api?.hasApi;
  // The human "what happened" overview shown at the top of Mode A. For the bundled
  // fixture we reuse the curated narrator outcome; for any real session we ask the
  // local model to write one (grounded in the turns). Narrator prose only — the
  // numbers stay deterministic.
  useEffect(() => {
    setOverview(null);
    if (atHome || status !== "ready") return;
    let alive = true;
    const curated = narrated && (narrated.session_outcome || narrated.summary || narrated.outcome);
    const fromCurated = () =>
      curated && setOverview({ text: String(curated).replace(/^Generated summary[^\n]*\n+/i, "").trim(), label: "narrator" });
    // Prefer the freshly-generated "what happened" (plain English, doesn't dwell on
    // tokens) for ANY session; fall back to a curated narrated outcome if the API
    // or model is down.
    if (hasApiEarly) {
      (async () => {
        try {
          const j = await fetchOverview(sourcePath);
          if (!alive) return;
          if (j && j.overview) setOverview({ text: j.overview, label: j.model ? j.model.split("/").pop() : "narrator" });
          else fromCurated();
        } catch {
          if (alive) fromCurated();
        }
      })();
    } else {
      fromCurated();
    }
    return () => { alive = false; };
  }, [status, sourcePath, narrated, hasApiEarly, atHome]);

  // Session-scoped advice ("what could have been better") — the local model writes
  // it from the engine's fired signals + this session's objective + the Anthropic
  // codebook. Best-effort: the deterministic recommendations render instantly and
  // this upgrades them to scoped prose when the model answers.
  useEffect(() => {
    setAdvice(null);
    if (atHome || status !== "ready" || !hasApiEarly) return;
    let alive = true;
    (async () => {
      try {
        const j = await fetchAdvice(sourcePath);
        if (alive && j && Array.isArray(j.recommendations)) setAdvice(j);
      } catch { /* fall back to the deterministic recommendations */ }
    })();
    return () => { alive = false; };
  }, [status, sourcePath, hasApiEarly, atHome]);

  const openTurn = (i, toolIdx = null) => { setView("turn"); setTi(i); setTool(toolIdx); };
  const pickSession = (path) => {
    setAtHome(false);
    setSourcePath(path);
    setView("report"); setTi(0); setTool(null);
    setBrowserOpen(false); setProjectCwd(null);
  };
  const openProject = (cwd) => { setAtHome(false); setProjectCwd(cwd); setBrowserOpen(false); setChatOpen(false); };
  const goHome = () => { setAtHome(true); setProjectCwd(null); setChatOpen(false); setBrowserOpen(false); };
  // The bundled demo session — loads ONLY on this explicit click (the "__demo__"
  // sentinel the server resolves to fixtures/demo-session.jsonl). Never a default.
  const openDemo = () => pickSession("__demo__");

  const hasApi = api?.hasApi;

  // DEFAULT LANDING — the top-level Projects list. From here: project -> sessions
  // (ProjectView) -> a session (the graph). ProjectsHome handles its own
  // loading/no-engine states, so we only wait while the API probe is in flight.
  if (atHome) {
    if (api == null) return <Splash text="connecting to the local engine…" />;
    return (
      <>
        <Style />
        {consentModal}
        <ProjectsHome onOpenProject={openProject} onOpenSession={pickSession} onDemo={openDemo} />
      </>
    );
  }

  // Project scope is session-independent — ProjectView loads its own data from `cwd`.
  // The welcome / loading / error screens below key off the loaded SESSION's status, so
  // scope them to session view only. Otherwise opening a project before any session is
  // analyzed (sourcePath still null → status "welcome") falls through to the welcome
  // screen, and only "works" once some session has been loaded. A project click must
  // never require a loaded session.
  const inProject = !!projectCwd;

  if (!inProject && status === "welcome")
    return (
      <div style={{ fontFamily: FB, color: C.text, height: "100vh", display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 16, background: "radial-gradient(1200px 500px at 50% -10%, #3b3633 0%, #2b2927 60%)" }}>
        <Style />
        <img src="/her-logo-light.png" alt="Her" style={{ height: 70 }} />
        <div style={{ fontFamily: FM, fontSize: 13, color: C.text2 }}>हेर — a detective for your coding-agent sessions · 100% local</div>
        <div style={{ fontFamily: FM, fontSize: 12, color: C.muted, maxWidth: 460, textAlign: "center", lineHeight: 1.6 }}>
          No session loaded (traces are never bundled). Pick one of your <code style={{ color: C.text2 }}>~/.claude</code> sessions and Her will analyze it live.
        </div>
        {api == null ? (
          <div style={{ fontFamily: FM, fontSize: 11, color: C.muted }}>connecting to the local engine…</div>
        ) : hasApiEarly ? (
          <div className="lift" onClick={() => setBrowserOpen(true)} style={{ cursor: "pointer", display: "flex", alignItems: "center", gap: 8, background: C.orange, color: "#fff", fontFamily: FD, fontWeight: 600, fontSize: 13.5, borderRadius: 9, padding: "11px 20px" }}>
            <FolderOpen size={16} /> Browse your sessions
          </div>
        ) : (
          <div style={{ fontFamily: FM, fontSize: 12, color: C.amber, border: `1px solid ${C.amber}`, borderRadius: 8, padding: "10px 14px" }}>
            Start the local engine: <b>./her</b> &nbsp;(then refresh)
          </div>
        )}
        {browserOpen && <SessionBrowser current={null} onPick={pickSession} onClose={() => setBrowserOpen(false)} />}
      </div>
    );

  if (!inProject && status === "loading")
    return <Splash text={sourcePath ? "analyzing session…" : "loading trace…"} />;
  if (!inProject && status === "error")
    return (
      <Splash bad text={`could not load engine output — ${error}`}>
        {hasApi && <button onClick={() => setBrowserOpen(true)} style={btnStyle}>browse sessions</button>}
        {sourcePath && <button onClick={goHome} style={btnStyle}>back to home</button>}
        {browserOpen && <SessionBrowser current={sourcePath} onPick={pickSession} onClose={() => setBrowserOpen(false)} />}
      </Splash>
    );

  // Session-scope data — null/empty in project scope (ProjectView fetches its own from
  // `cwd`). The JSX that dereferences these only renders when !inProject, so guarding
  // here keeps a project click from throwing on the still-null session `data`.
  const S = inProject ? null : data.session;
  const turns = inProject ? [] : data.turns;
  const t = turns[Math.min(ti, turns.length - 1)];
  // Sub-turns are SIZED BY COST (Anthropic token consumption) — what you pay for —
  // not by raw cacheRead. cacheRead stays as a secondary metric on hover.
  const maxCost = Math.max(1, ...turns.map((x) => x.tokens.cost ?? 0));

  return (
    <div style={{ fontFamily: FB, color: C.text, height: "100vh", display: "flex", flexDirection: "column", background: "radial-gradient(1200px 500px at 25% -8%, #3b3633 0%, #2b2927 55%)" }}>
      <Style />
      {consentModal}

      {/* header */}
      <div style={{ height: 58, background: C.header, borderBottom: `1px solid ${C.borderSoft}`, boxShadow: `0 1px 0 0 ${C.orange}22`, display: "flex", alignItems: "center", padding: "0 18px", gap: 14, flexShrink: 0 }}>
        <div className="lift" onClick={goHome} style={{ display: "flex", alignItems: "center", gap: 9, cursor: "pointer" }} title="Her · हेर — back to all projects">
          <img src="/her-logo-light.png" alt="Her" style={{ height: 28, display: "block" }} />
          <span style={{ fontFamily: FD, fontWeight: 600, fontSize: 13, color: C.muted, letterSpacing: 1 }}>हेर</span>
        </div>
        {inProject ? (
          <div style={{ fontFamily: FM, fontSize: 11, color: C.muted, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
            <span style={{ color: C.orange }}>project</span> · {projectCwd}
          </div>
        ) : (
          <div onClick={() => hasApi && openProject(S.cwd)} title={hasApi ? "open the project view — all sessions in this folder" : undefined} style={{ fontFamily: FM, fontSize: 11, color: C.muted, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", cursor: hasApi ? "pointer" : "default" }}>
            session {S.sessionId ? S.sessionId.slice(0, 8) : "?"} · <span style={{ color: hasApi ? C.text2 : C.muted, borderBottom: hasApi ? `1px dotted ${C.border}` : "none" }}>{S.cwd}</span>{S.startedAt ? <> · <span style={{ color: C.text2 }}>{fmtWhen(S.startedAt)}</span></> : null} · {S.gitBranch} · v{S.version}
          </div>
        )}
        <div style={{ flex: 1 }} />
        {hasApi && (
          <div className="row lift" onClick={() => setBrowserOpen(true)} style={{ cursor: "pointer", display: "flex", alignItems: "center", gap: 6, fontFamily: FM, fontSize: 11, color: C.text2, border: `1px solid ${C.border}`, borderRadius: 7, padding: "5px 10px" }}>
            <FolderOpen size={13} color={C.orange} /> {inProject ? "project" : sourcePath === "__demo__" ? "demo session" : sourcePath ? "live session" : "home"} · browse
          </div>
        )}
        <Chip dot={C.cyan} text="100% LOCAL" />
        {!inProject && narrated && <Chip dot={C.amber} text="NARRATED" />}
        {!inProject && <Stat label="queries" v={S.turns} />}
        {!inProject && <Stat label="tools" v={S.tools} />}
        {!inProject && <Stat label="token cost" v={fmt(S.cost ?? S.tokens?.cost ?? 0)} grad />}
        {!inProject && <Stat label="cache re-reads" v={fmt(S.tokens.cacheRead)} />}
        {!inProject && S.context && <Stat label="peak ctx" v={`${Math.round((S.context.peakPct || 0) * 100)}%`} />}
        {!inProject && <Stat label="generated" v={fmt(S.tokens.out)} />}
      </div>

      {inProject ? (
        <ProjectView cwd={projectCwd} llama={api?.llama} onOpenSession={pickSession} onBack={goHome} onBrowse={() => setBrowserOpen(true)} />
      ) : view === "report" ? (
      /* DEFAULT: the executive Session Report (full width). Buttons drill into the
         Journey Graph (Mode A) and turn-by-turn (Mode B); chat opens on the right. */
      <div style={{ display: "flex", flex: 1, minHeight: 0 }}>
        <SessionReport
          session={S} turns={turns} binaries={data.binaries} entities={data.entities}
          impact={data.impact} recommendations={data.recommendations} advice={advice}
          overview={overview} narrated={narrated}
          onOpenTurn={openTurn}
          onOpenJourney={() => { setView("session"); setTool(null); }}
          onOpenRaw={() => openTurn(0)}
          onAskHer={() => setChatOpen((v) => !v)}
          chatOpen={chatOpen}
        />
        {chatOpen && (
          <div style={{ width: 392, background: C.panel, borderLeft: `1px solid ${C.borderSoft}`, display: "flex", flexDirection: "column", flexShrink: 0 }}>
            <ChatPanel sessionPath={sourcePath} llama={api?.llama} onFocusTurn={openTurn} />
          </div>
        )}
      </div>
      ) : (
      <div style={{ display: "flex", flex: 1, minHeight: 0 }}>
        {/* LEFT: mode switch + legend + query list */}
        <div style={{ width: 312, background: C.panel, borderRight: `1px solid ${C.borderSoft}`, display: "flex", flexDirection: "column", flexShrink: 0 }}>
          <div style={{ padding: "10px 10px 4px", display: "flex", flexDirection: "column", gap: 5 }}>
            <ModeButton active={view === "report"} icon={ClipboardList} title="Session report" sub="the summary · default" onClick={() => { setView("report"); setTool(null); }} />
            <ModeButton active={view === "session"} icon={Map} title="Session graph" sub="the journey · Mode A" onClick={() => { setView("session"); setTool(null); }} />
            {hasApi && (
              <div style={{ display: "flex", gap: 5 }}>
                <ModeButton small icon={FolderOpen} title="Sessions" sub="browse all" onClick={() => setBrowserOpen(true)} />
                <ModeButton small active={chatOpen} icon={Sparkles} title="Ask Her" sub="this session" onClick={() => setChatOpen((v) => !v)} />
              </div>
            )}
          </div>

          {/* Mode A legend lives here when on the landing graph */}
          {view === "session" ? (
            <div style={{ overflowY: "auto", flex: 1, minHeight: 0 }}>
              <SectionLabel text="LEGEND" />
              <Legend turns={turns} vis={vis} setVis={setVis} />
              <SessionEntities entities={data.entities} binaries={data.binaries} onOpen={openTurn} />
            </div>
          ) : (
            <>
              <SectionLabel text="QUERIES" />
              <div style={{ overflowY: "auto", flex: 1, padding: "0 8px 12px" }}>
                {turns.map((x) => {
                  const on = view === "turn" && x.i === ti;
                  const heavy = x.heavy;                       // top-3 by cost (orange)
                  const over = x.overBudget && !x.heavy;       // over the 500k floor (amber)
                  const II = intentIcon(intentOf(x));
                  return (
                    <div key={x.i} className="row" onClick={() => openTurn(x.i)}
                      style={{ background: on ? C.card : "transparent", border: `1px solid ${on ? C.border : "transparent"}`, borderLeft: `3px solid ${heavy ? C.orange : over ? C.amber : on ? C.border : "transparent"}`, borderRadius: 7, padding: "8px 10px", marginBottom: 5, cursor: "pointer" }}>
                      <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
                        <div style={{ width: 20, height: 20, borderRadius: 5, flexShrink: 0, background: C.elevated, display: "flex", alignItems: "center", justifyContent: "center" }}>
                          <II size={11} color={heavy ? C.orange : C.text2} />
                        </div>
                        <span style={{ fontFamily: FM, fontSize: 10, color: C.muted }}>{String(x.i).padStart(2, "0")}</span>
                        <span style={{ fontSize: 12, fontWeight: on ? 600 : 500, color: on ? C.text : C.text2, lineHeight: 1.3, flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{shortPrompt(x)}</span>
                        {x.guide && <Lightbulb size={12} color={C.amber} style={{ flexShrink: 0 }} />}
                      </div>
                      <div style={{ display: "flex", alignItems: "center", gap: 8, marginTop: 6, paddingLeft: 28 }}
                        title={`cost ${fmt(x.tokens.cost ?? 0)} (Anthropic token consumption) · ${fmt(x.tokens.cacheRead)} cache re-reads (cumulative) · ${fmt(x.tokens.out)} generated${x.ctxPeak ? ` · window peaked ${fmt(x.ctxPeak)}` : ""}`}>
                        <div style={{ flex: 1, height: 4, background: C.black, borderRadius: 3, overflow: "hidden" }}>
                          <div style={{ width: `${Math.max(3, (100 * (x.tokens.cost ?? 0)) / maxCost)}%`, height: "100%", background: heavy ? `linear-gradient(90deg,${C.orange},${C.amber})` : over ? C.amber : C.border }} />
                        </div>
                        <span style={{ fontFamily: FM, fontSize: 9.5, color: heavy ? C.orange : over ? C.amber : C.muted }}>{fmt(x.tokens.cost ?? 0)}</span>
                      </div>
                    </div>
                  );
                })}
              </div>
            </>
          )}
        </div>

        {/* CENTER */}
        {view === "session" ? (
          <SessionGraph session={S} turns={turns} narrated={narrated} overview={overview} recommendations={data.recommendations} advice={advice} vis={vis} onOpen={openTurn} />
        ) : (
          <TurnGraph turn={t} selected={tool} onSelect={setTool} vis={vis} />
        )}

        {/* RIGHT: chat (when open) else the detail panel */}
        <div style={{ width: chatOpen ? 392 : 368, background: C.panel, borderLeft: `1px solid ${C.borderSoft}`, display: "flex", flexDirection: "column", flexShrink: 0 }}>
          {chatOpen ? (
            <ChatPanel sessionPath={sourcePath} llama={api?.llama} onFocusTurn={openTurn} />
          ) : view === "session" ? (
            <SessionDetail session={S} />
          ) : tool === null ? (
            <TurnDetail turn={t} narrated={narrated} binaries={data.binaries} />
          ) : (
            <ToolDetail tool={t.tools[tool]} onBack={() => setTool(null)} />
          )}
        </div>
      </div>
      )}

      {browserOpen && <SessionBrowser current={sourcePath} onPick={pickSession} onOpenProject={openProject} onClose={() => setBrowserOpen(false)} />}
    </div>
  );
}

function ModeButton({ active, icon: Icon, title, sub, onClick, small }) {
  return (
    <div className="row lift" onClick={onClick} style={{ flex: small ? 1 : "unset", display: "flex", alignItems: "center", gap: 9, padding: small ? "8px 9px" : "11px 11px", cursor: "pointer", borderRadius: 8, background: active ? `linear-gradient(135deg,${C.orangeMut},transparent)` : "transparent", border: `1px solid ${active ? C.orangeBd : C.borderSoft}` }}>
      <div style={{ width: small ? 24 : 30, height: small ? 24 : 30, borderRadius: 7, background: active ? C.orange : C.elevated, display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }}>
        <Icon size={small ? 13 : 16} color={active ? "#fff" : C.text2} />
      </div>
      <div style={{ minWidth: 0 }}>
        <div style={{ fontSize: small ? 12 : 13.5, fontWeight: 600, color: active ? C.text : C.text2 }}>{title}</div>
        <div style={{ fontFamily: FM, fontSize: 9.5, color: C.muted, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{sub}</div>
      </div>
    </div>
  );
}

function SectionLabel({ text }) {
  return (
    <div style={{ padding: "8px 12px 7px", borderTop: `1px solid ${C.borderSoft}` }}>
      <span style={{ fontFamily: FM, fontSize: 10.5, letterSpacing: 0.8, color: C.text2, fontWeight: 600 }}>{text}</span>
    </div>
  );
}

const btnStyle = { marginTop: 14, marginInline: 6, background: C.card, color: C.text2, border: `1px solid ${C.border}`, borderRadius: 7, padding: "8px 14px", fontFamily: FM, fontSize: 12, cursor: "pointer" };

function Splash({ text, bad, children }) {
  return (
    <div style={{ fontFamily: FM, color: bad ? C.red : C.text2, height: "100vh", display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", background: C.bg, padding: 24, textAlign: "center", fontSize: 13 }}>
      <div>{text}</div>
      <div style={{ display: "flex", gap: 6 }}>{children}</div>
    </div>
  );
}

function Style() {
  return (
    <style>{`
      *{scrollbar-width:thin;scrollbar-color:${C.border} transparent}
      *::-webkit-scrollbar{width:8px;height:8px}
      *::-webkit-scrollbar-thumb{background:${C.border};border-radius:4px}
      *::-webkit-scrollbar-track{background:transparent}
      .row{transition:background .12s ease,border-color .12s ease}
      .row:hover{background:${C.card}}
      .lift{transition:transform .12s ease,box-shadow .12s ease}
      .lift:hover{transform:translateY(-1px)}
      .pop{animation:pop .32s ease both}
      @keyframes pop{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
      .glow{animation:glow 2.6s ease-in-out infinite}
      @keyframes glow{0%,100%{box-shadow:0 0 0 0 rgba(240,106,23,.0),0 0 14px 0 rgba(240,106,23,.35)}50%{box-shadow:0 0 0 4px rgba(240,106,23,.06),0 0 22px 2px rgba(240,106,23,.5)}}
      .spin{animation:spin 1s linear infinite}
      @keyframes spin{to{transform:rotate(360deg)}}
      .hb{background:linear-gradient(90deg,${C.orange},${C.amber});-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
    `}</style>
  );
}
