const { useState, useEffect, useRef, useMemo } = React;

/* ============================================================
   SOLSCOPE — Solana smart-wallet tracker & copy-trade platform
   Palette: ink #0A0E14 / panel #10161F / line #1C2733
   amber signal #FFB454 / teal #59C2C6 / up #4BD08B / down #F0616D
   ============================================================ */

const C = {
  bg: "#0A0E14",
  panel: "#10161F",
  panel2: "#141C27",
  line: "#1C2733",
  text: "#E6EDF3",
  dim: "#8B99A8",
  faint: "#5A6675",
  amber: "#FFB454",
  teal: "#59C2C6",
  up: "#4BD08B",
  down: "#F0616D",
};

const font = {
  mono: "'IBM Plex Mono', 'SFMono-Regular', Consolas, monospace",
  disp: "'Space Grotesk', 'Segoe UI', sans-serif",
};

/* ---------------- mock data ---------------- */

const seedTrades = (winRate, n, avgWin, avgLoss, seed) => {
  let x = seed;
  const rnd = () => ((x = (x * 1103515245 + 12345) % 2147483648) / 2147483648);
  const toks = ["WIF", "BONK", "POPCAT", "MEW", "GIGA", "PNUT", "MOODENG", "FWOG", "CHILLGUY", "RETARDIO", "SIGMA", "BOME"];
  const out = [];
  let cum = 0;
  for (let i = 0; i < n; i++) {
    const win = rnd() < winRate;
    const pnl = win ? avgWin * (0.4 + rnd() * 1.6) : -avgLoss * (0.4 + rnd() * 1.4);
    cum += pnl;
    out.push({
      token: toks[Math.floor(rnd() * toks.length)],
      entry: (0.0001 + rnd() * 0.02).toFixed(6),
      pnlSol: pnl,
      pct: win ? Math.round(20 + rnd() * 380) : -Math.round(10 + rnd() * 70),
      hold: Math.round(4 + rnd() * 300),
      daysAgo: Math.round(rnd() * 30),
      cum,
    });
  }
  return out.sort((a, b) => b.daysAgo - a.daysAgo).map((t, i, arr) => {
    // rebuild cumulative in chronological order
    const prev = i === 0 ? 0 : arr[i - 1].cum2;
    t.cum2 = prev + t.pnlSol;
    return t;
  });
};

const WALLETS = [
  { addr: "7xKq...mR2v", name: "phantom.sol", score: 94, win: 78, pnl30: 1842, trades: 96, hold: "41m", size: 12.4, flags: [], badge: "verified", trades_: seedTrades(0.78, 40, 62, 22, 7) },
  { addr: "3nWa...pL9c", name: "quietwhale", score: 91, win: 71, pnl30: 2410, trades: 64, hold: "2.1h", size: 28.0, flags: [], badge: "verified", trades_: seedTrades(0.71, 38, 95, 30, 13) },
  { addr: "9dFe...xT4h", name: "gm_capital", score: 87, win: 74, pnl30: 1120, trades: 142, hold: "18m", size: 6.2, flags: [], badge: "verified", trades_: seedTrades(0.74, 42, 38, 15, 29) },
  { addr: "5hRt...kQ8n", name: "delta.sol", score: 83, win: 66, pnl30: 890, trades: 71, hold: "1.4h", size: 9.8, flags: [], badge: "verified", trades_: seedTrades(0.66, 36, 48, 20, 41) },
  { addr: "Bq2z...vN6m", name: "0xsilent", score: 79, win: 69, pnl30: 645, trades: 55, hold: "55m", size: 7.5, flags: [], badge: "verified", trades_: seedTrades(0.69, 34, 40, 19, 53) },
  { addr: "Hj8p...aW3d", name: "latenight", score: 71, win: 62, pnl30: 512, trades: 48, hold: "3.2h", size: 11.1, flags: [], badge: "verified", trades_: seedTrades(0.62, 32, 42, 24, 67) },
  { addr: "2mVc...eY7s", name: "snipe404", score: 44, win: 81, pnl30: 3105, trades: 210, hold: "3m", size: 4.1, flags: ["Same-slot entries on 34 launches", "Funded by 2 token deployers"], badge: "flagged", trades_: seedTrades(0.81, 44, 70, 12, 71) },
  { addr: "6tGb...zU1k", name: "freshwlt", score: 38, win: 88, pnl30: 260, trades: 9, hold: "26m", size: 3.0, flags: ["Only 9 closed positions — below minimum sample"], badge: "new", trades_: seedTrades(0.88, 9, 35, 14, 83) },
];

/* launchpads: only pump.fun, LetsBonk and Bags are on by default — everything else filtered out */
const DEFAULT_PADS = { "pump.fun": true, "letsbonk": true, "bags": true, "moonshot": false, "believe": false, "daos.fun": false };

const ALERT_TOKENS = [
  { sym: "GOATSE", name: "Goatseus", mc: "$412K", liq: "$88K", age: "22m", mint: true, lp: true, top10: 18, pad: "pump.fun" },
  { sym: "HAWK", name: "Hawkfi", mc: "$1.2M", liq: "$240K", age: "3h", mint: true, lp: true, top10: 24, pad: "letsbonk" },
  { sym: "ZEREBRO", name: "Zerebro", mc: "$860K", liq: "$150K", age: "1.1h", mint: true, lp: true, top10: 21, pad: "bags" },
  { sym: "LUCE", name: "Luce", mc: "$630K", liq: "$112K", age: "47m", mint: true, lp: false, top10: 41, pad: "pump.fun" },
  { sym: "PENGU", name: "Pengu Frens", mc: "$2.4M", liq: "$410K", age: "6h", mint: true, lp: true, top10: 15, pad: "bags" },
  { sym: "DEGOD", name: "DeGodMode", mc: "$298K", liq: "$61K", age: "14m", mint: false, lp: true, top10: 33, pad: "letsbonk" },
  { sym: "MSHOT", name: "Moonrunner", mc: "$540K", liq: "$95K", age: "38m", mint: true, lp: true, top10: 19, pad: "moonshot" },
  { sym: "BLV", name: "Believer", mc: "$1.1M", liq: "$180K", age: "2h", mint: true, lp: true, top10: 22, pad: "believe" },
];

/* Build a wallet profile for a seeded/imported address.
   In production this data comes from the Helius backfill →
   position-pairing → scoring pipeline. Here it's simulated. */
const hashAddr = (s) => { let h = 0; for (let i = 0; i < s.length; i++) h = (h * 31 + s.charCodeAt(i)) % 2147483648; return h; };
const makeImportedWallet = (addr) => {
  const h = hashAddr(addr);
  const win = 55 + (h % 28);
  const trades = 24 + (h % 90);
  const flagged = h % 7 === 0;
  const score = flagged ? 35 + (h % 15) : Math.min(96, Math.round(win * 0.7 + Math.min(trades, 100) * 0.3));
  return {
    addr: `${addr.slice(0, 4)}...${addr.slice(-4)}`,
    fullAddr: addr,
    name: `seed_${addr.slice(0, 4).toLowerCase()}`,
    score,
    win,
    pnl30: 180 + (h % 2200),
    pnl24: Math.round((180 + (h % 2200)) * (0.03 + (h % 18) / 100)) * (h % 6 === 0 ? -1 : 1),
    pnl4: Math.round((14 + (h % 90))) * (h % 4 === 0 ? -1 : 1),
    trades,
    hold: `${8 + (h % 170)}m`,
    size: +(3 + (h % 20) * 0.9).toFixed(1),
    flags: flagged ? ["Bought in creation slot on 6 launches — sniper pattern"] : [],
    badge: flagged ? "flagged" : trades < 30 ? "new" : "verified",
    seeded: true,
    trades_: seedTrades(win / 100, Math.min(trades, 44), 30 + (h % 60), 12 + (h % 20), (h % 97) + 3),
  };
};

const VERIFY_STEPS = ["Backfilling swap history", "Pairing round-trip positions", "Running insider & sniper checks", "Scoring"];

/* derive short-window PnL for each wallet (production: computed from trades in window) */
WALLETS.forEach((w) => {
  const h = hashAddr(w.addr);
  w.pnl24 = Math.round(w.pnl30 * (0.04 + (h % 20) / 100)) * (h % 5 === 0 ? -1 : 1);
  w.pnl4 = Math.round(Math.abs(w.pnl24) * (0.1 + (h % 30) / 100)) * (h % 3 === 0 ? -1 : 1);
});

const scoreParts = (w) => [
  { k: "Win consistency", v: Math.min(100, w.win + 10) },
  { k: "Sample size", v: Math.min(100, Math.round(w.trades / 1.5)) },
  { k: "Insider checks", v: w.flags.length ? 20 : 98 },
  { k: "PnL distribution", v: w.badge === "flagged" ? 45 : 82 },
];

/* ---------------- tiny UI atoms ---------------- */

const Badge = ({ type }) => {
  const map = {
    verified: { t: "VERIFIED", c: C.up, b: "rgba(75,208,139,.12)" },
    flagged: { t: "FLAGGED", c: C.down, b: "rgba(240,97,109,.12)" },
    new: { t: "NEW", c: C.dim, b: "rgba(139,153,168,.12)" },
  };
  const m = map[type];
  return (
    <span style={{ fontFamily: font.mono, fontSize: 10, letterSpacing: 1, color: m.c, background: m.b, padding: "3px 8px", borderRadius: 4 }}>
      {m.t}
    </span>
  );
};

const Num = ({ v, suffix = "", sign = false }) => (
  <span style={{ fontFamily: font.mono, color: v >= 0 ? C.up : C.down }}>
    {sign && v > 0 ? "+" : ""}
    {typeof v === "number" ? v.toLocaleString() : v}
    {suffix}
  </span>
);

const Donut = ({ score, size = 92 }) => {
  const r = size / 2 - 7;
  const circ = 2 * Math.PI * r;
  const col = score >= 75 ? C.up : score >= 55 ? C.amber : C.down;
  return (
    <svg width={size} height={size}>
      <circle cx={size / 2} cy={size / 2} r={r} fill="none" stroke={C.line} strokeWidth="7" />
      <circle
        cx={size / 2} cy={size / 2} r={r} fill="none" stroke={col} strokeWidth="7"
        strokeDasharray={`${(score / 100) * circ} ${circ}`} strokeLinecap="round"
        transform={`rotate(-90 ${size / 2} ${size / 2})`}
        style={{ transition: "stroke-dasharray .8s ease" }}
      />
      <text x="50%" y="46%" textAnchor="middle" fill={C.text} style={{ fontFamily: font.disp, fontSize: 24, fontWeight: 700 }}>{score}</text>
      <text x="50%" y="64%" textAnchor="middle" fill={C.faint} style={{ fontFamily: font.mono, fontSize: 9, letterSpacing: 1 }}>SCORE</text>
    </svg>
  );
};

const Spark = ({ pts, w = 560, h = 120 }) => {
  if (!pts.length) return null;
  const min = Math.min(...pts), max = Math.max(...pts);
  const span = max - min || 1;
  const path = pts.map((p, i) => `${i === 0 ? "M" : "L"}${(i / (pts.length - 1)) * w},${h - ((p - min) / span) * (h - 10) - 5}`).join(" ");
  const up = pts[pts.length - 1] >= pts[0];
  return (
    <svg width="100%" viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none" style={{ display: "block" }}>
      <path d={`${path} L${w},${h} L0,${h} Z`} fill={up ? "rgba(75,208,139,.08)" : "rgba(240,97,109,.08)"} />
      <path d={path} fill="none" stroke={up ? C.up : C.down} strokeWidth="2" />
    </svg>
  );
};

const Check = ({ ok, label }) => (
  <span style={{ fontFamily: font.mono, fontSize: 11, color: ok ? C.up : C.down, marginRight: 12 }}>
    {ok ? "✓" : "✗"} {label}
  </span>
);

/* ---------------- main app ---------------- */

function App() {
  const [view, setView] = useState("leaderboard");
  const [sel, setSel] = useState(null);
  const [following, setFollowing] = useState(new Set(["7xKq...mR2v", "3nWa...pL9c"]));
  const [alerts, setAlerts] = useState([]);
  const [ticket, setTicket] = useState(null);
  const [copies, setCopies] = useState([]);
  const [toast, setToast] = useState(null);
  const [sortBy, setSortBy] = useState("score");
  const [live, setLive] = useState(true);
  const [imported, setImported] = useState([]);   // verified seeded wallets
  const [queue, setQueue] = useState([]);         // { addr, step, error } while verifying
  const [seedText, setSeedText] = useState("");
  const [autoScan, setAutoScan] = useState(true);
  const [lastScan, setLastScan] = useState(new Date());
  const [scanning, setScanning] = useState(false);
  const [plan, setPlan] = useState("pro");
  const [planLabel, setPlanLabel] = useState("VIP");
  const [showPricing, setShowPricing] = useState(false);
  const [tg, setTg] = useState({ connected: false, group: "", topEntries: true, mcCross: true, followedEntries: true });
  const [pads, setPads] = useState(DEFAULT_PADS);
  const idRef = useRef(0);

  /* ----- auto-discovery: every 4h in production, compressed to 75s in this demo ----- */
  const B58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
  const randAddr = () => Array.from({ length: 43 }, () => B58[Math.floor(Math.random() * B58.length)]).join("");
  const runScan = () => {
    setScanning(true);
    setTimeout(() => {
      const found = Array.from({ length: 1 + Math.floor(Math.random() * 2) }, () => {
        const w = makeImportedWallet(randAddr());
        w.seeded = false; w.discovered = true;
        return w;
      });
      const promoted = found.filter((w) => w.score >= 70);
      setImported((prev) => [...prev, ...found]);
      setLastScan(new Date());
      setScanning(false);
      flash(promoted.length
        ? `Discovery scan: ${promoted.length} new wallet${promoted.length > 1 ? "s" : ""} cleared thresholds — added to leaderboard`
        : "Discovery scan complete — no new wallets cleared thresholds");
    }, 2200);
  };
  useEffect(() => {
    if (!autoScan) return;
    const iv = setInterval(runScan, 75000);
    return () => clearInterval(iv);
  }, [autoScan]);

  // simulated real-time alert stream
  useEffect(() => {
    if (!live) return;
    const tick = () => {
      const universe = [...WALLETS, ...imported];
      const top5 = [...universe].sort((a, b) => b.score - a.score).slice(0, 5);
      const tokPool = ALERT_TOKENS.filter((t) => pads[t.pad]);
      if (!tokPool.length) return;
      if (Math.random() < 0.28) {
        // token crossing $1M market cap
        const t = tokPool[Math.floor(Math.random() * tokPool.length)];
        const a = {
          id: ++idRef.current,
          type: "MC_CROSS",
          token: t,
          mcNow: `$${(1.0 + Math.random() * 0.4).toFixed(2)}M`,
          entry: (0.0008 + Math.random() * 0.003).toFixed(6),
          holders: 400 + Math.floor(Math.random() * 2600),
          ts: new Date(),
        };
        setAlerts((prev) => [a, ...prev].slice(0, 30));
        return;
      }
      const followed = universe.filter((w) => following.has(w.addr));
      const pool = [...new Map([...top5, ...followed].map((w) => [w.addr, w])).values()];
      const w = pool[Math.floor(Math.random() * pool.length)];
      const t = tokPool[Math.floor(Math.random() * tokPool.length)];
      const a = {
        id: ++idRef.current,
        type: "ENTRY",
        wallet: w,
        topFive: top5.some((x) => x.addr === w.addr),
        token: t,
        sizeSol: +(w.size * (0.6 + Math.random() * 0.8)).toFixed(1),
        entry: (0.00008 + Math.random() * 0.004).toFixed(6),
        ts: new Date(),
      };
      setAlerts((prev) => [a, ...prev].slice(0, 30));
    };
    tick();
    const iv = setInterval(tick, 6500 + Math.random() * 3000);
    return () => clearInterval(iv);
  }, [live, following, imported, pads]);

  const flash = (msg) => {
    setToast(msg);
    setTimeout(() => setToast(null), 2600);
  };

  const toggleFollow = (addr) => {
    setFollowing((prev) => {
      const n = new Set(prev);
      n.has(addr) ? n.delete(addr) : n.add(addr);
      flash(n.has(addr) ? "Following wallet — alerts on new entries" : "Unfollowed");
      return n;
    });
  };

  const ALL = useMemo(() => [...WALLETS, ...imported], [imported]);

  const sorted = useMemo(() => {
    const arr = [...ALL];
    if (sortBy === "score") arr.sort((a, b) => b.score - a.score);
    if (sortBy === "win") arr.sort((a, b) => b.win - a.win);
    if (sortBy === "pnl") arr.sort((a, b) => b.pnl30 - a.pnl30);
    if (sortBy === "pnl24") arr.sort((a, b) => b.pnl24 - a.pnl24);
    if (sortBy === "pnl4") arr.sort((a, b) => b.pnl4 - a.pnl4);
    return arr;
  }, [sortBy, ALL]);

  const wallet = sel ? ALL.find((w) => w.addr === sel) : null;

  /* ----- seed import & verification pipeline (simulated) ----- */
  const runImport = () => {
    const raw = seedText.split(/[\s,;]+/).map((s) => s.trim()).filter(Boolean);
    if (!raw.length) return;
    const items = raw.map((addr) => {
      if (/^0x[0-9a-fA-F]{40}$/.test(addr)) return { addr, step: -1, error: "EVM address — SolScope tracks Solana wallets only" };
      if (!/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(addr)) return { addr, step: -1, error: "Not a valid Solana address" };
      if (imported.some((w) => w.fullAddr === addr) || queue.some((q) => q.addr === addr)) return { addr, step: -1, error: "Already imported" };
      return { addr, step: 0, error: null };
    });
    setQueue((prev) => [...items, ...prev]);
    setSeedText("");
    // advance each valid item through the pipeline steps
    items.filter((it) => !it.error).forEach((it, idx) => {
      VERIFY_STEPS.forEach((_, s) => {
        setTimeout(() => {
          setQueue((prev) => prev.map((q) => (q.addr === it.addr ? { ...q, step: s + 1 } : q)));
          if (s === VERIFY_STEPS.length - 1) {
            setTimeout(() => {
              setImported((prev) => [...prev, makeImportedWallet(it.addr)]);
              setQueue((prev) => prev.filter((q) => q.addr !== it.addr));
              flash("Wallet verified & scored — live on the leaderboard");
            }, 500);
          }
        }, 900 * (s + 1) + idx * 400);
      });
    });
  };

  /* ---------- shared styles ---------- */
  const card = { background: C.panel, border: `1px solid ${C.line}`, borderRadius: 10 };
  const th = { fontFamily: font.mono, fontSize: 10, letterSpacing: 1.2, color: C.faint, textAlign: "left", padding: "10px 14px", fontWeight: 500 };
  const td = { padding: "13px 14px", fontSize: 13, borderTop: `1px solid ${C.line}` };
  const btn = (primary) => ({
    fontFamily: font.disp, fontSize: 13, fontWeight: 600, cursor: "pointer", borderRadius: 7,
    padding: "8px 14px", border: `1px solid ${primary ? C.amber : C.line}`,
    background: primary ? C.amber : "transparent", color: primary ? "#1A1205" : C.text,
  });

  return (
    <div style={{ minHeight: "100vh", background: C.bg, color: C.text, fontFamily: font.disp }}>
      <style>{`
        @import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap');
        * { box-sizing: border-box; }
        ::selection { background: rgba(255,180,84,.3); }
        button:focus-visible, [tabindex]:focus-visible { outline: 2px solid ${C.teal}; outline-offset: 2px; }
        tr.row:hover { background: ${C.panel2}; }
        @keyframes slideIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
        .alert-in { animation: slideIn .35s ease; }
        @media (prefers-reduced-motion: reduce) { .alert-in { animation: none; } }
        /* mobile: wrap the header, make nav + tables horizontally scrollable */
        @media (max-width: 760px) {
          header { flex-wrap: wrap; gap: 10px !important; padding: 12px 14px !important; }
          header nav { overflow-x: auto; max-width: 100%; -webkit-overflow-scrolling: touch; }
          main { padding: 18px 12px 60px !important; }
          h1 { font-size: 21px !important; }
          table { display: block; overflow-x: auto; white-space: nowrap; -webkit-overflow-scrolling: touch; }
          button { min-height: 38px; }
          .page-head { flex-wrap: wrap; }
          .page-head h1 { font-size: 21px !important; }
        }
      `}</style>

      {/* ---------- header ---------- */}
      <header style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "16px 24px", borderBottom: `1px solid ${C.line}` }}>
        <div style={{ display: "flex", alignItems: "center", gap: 28 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
            <div style={{ width: 28, height: 28, borderRadius: 7, background: `linear-gradient(135deg, ${C.amber}, #E88A2A)`, display: "grid", placeItems: "center", color: "#1A1205", fontWeight: 700, fontSize: 15 }}>S</div>
            <div>
              <div style={{ fontWeight: 700, fontSize: 16, letterSpacing: 0.3 }}>SolScope</div>
              <div style={{ fontFamily: font.mono, fontSize: 9, color: C.faint, letterSpacing: 1.5 }}>SMART WALLET TERMINAL</div>
            </div>
          </div>
          <nav style={{ display: "flex", gap: 4 }}>
            {[["leaderboard", "Leaderboard"], ["alerts", `Alerts${alerts.length ? ` · ${alerts.length}` : ""}`], ["copies", `My copies${copies.length ? ` · ${copies.length}` : ""}`], ["import", `Import${queue.filter((q) => !q.error).length ? ` · ${queue.filter((q) => !q.error).length}` : ""}`]].map(([k, label]) => (
              <button key={k} onClick={() => { setView(k); setSel(null); }}
                style={{ ...btn(false), border: "none", color: view === k ? C.text : C.dim, background: view === k ? C.panel2 : "transparent" }}>
                {label}
              </button>
            ))}
          </nav>
        </div>
        <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
          <span style={{ fontFamily: font.mono, fontSize: 10, letterSpacing: 1, padding: "4px 10px", borderRadius: 5, color: plan === "pro" ? C.up : C.dim, background: plan === "pro" ? "rgba(75,208,139,.12)" : "rgba(139,153,168,.1)" }}>
            {plan === "pro" ? `PRO · ${planLabel}` : "FREE"}
          </span>
          {plan === "free" && (
            <button style={{ ...btn(false), borderColor: C.teal, color: C.teal, fontSize: 12 }} onClick={() => setShowPricing(true)}>Upgrade</button>
          )}
          <button onClick={() => setLive((v) => !v)} style={{ ...btn(false), display: "flex", alignItems: "center", gap: 7, fontFamily: font.mono, fontSize: 11 }}>
            <span style={{ width: 7, height: 7, borderRadius: 99, background: live ? C.up : C.faint }} />
            {live ? "LIVE" : "PAUSED"}
          </button>
          <button style={btn(true)} onClick={() => flash("Wallet connect: plug in Solana wallet adapter in production build")}>Connect wallet</button>
        </div>
      </header>

      <main style={{ maxWidth: 1080, margin: "0 auto", padding: "26px 24px 80px" }}>

        {/* ---------- LEADERBOARD ---------- */}
        {view === "leaderboard" && !wallet && (
          <>
            <div className="page-head" style={{ display: "flex", alignItems: "baseline", justifyContent: "space-between", marginBottom: 18, gap: 10 }}>
              <div style={{ minWidth: 240 }}>
                <h1 style={{ margin: 0, fontSize: 26, fontWeight: 700 }}>Top wallets · 30 days</h1>
                <p style={{ margin: "6px 0 0", color: C.dim, fontSize: 13, maxWidth: 560 }}>
                  Ranked on closed round-trip positions only. Snipers, insider-funded wallets and thin samples are flagged, not hidden.
                </p>
              </div>
              <div style={{ display: "flex", gap: 6 }}>
                {[["score", "Score"], ["win", "Win rate"], ["pnl", "30d PnL"], ["pnl24", "24h PnL"], ["pnl4", "4h PnL"]].map(([k, l]) => (
                  <button key={k} onClick={() => setSortBy(k)} style={{ ...btn(false), fontFamily: font.mono, fontSize: 11, color: sortBy === k ? C.amber : C.dim, borderColor: sortBy === k ? C.amber : C.line }}>{l}</button>
                ))}
              </div>
            </div>

            <div style={{ ...card, padding: "12px 16px", marginBottom: 16, display: "flex", alignItems: "center", justifyContent: "space-between", flexWrap: "wrap", gap: 10, borderLeft: `3px solid ${autoScan ? C.teal : C.faint}` }}>
              <div style={{ display: "flex", alignItems: "center", gap: 14, flexWrap: "wrap" }}>
                <span style={{ fontFamily: font.mono, fontSize: 11, letterSpacing: 1, color: autoScan ? C.teal : C.faint }}>
                  {scanning ? "◌ SCANNING CHAIN…" : autoScan ? "● AUTO-DISCOVERY ON" : "○ AUTO-DISCOVERY OFF"}
                </span>
                <span style={{ fontFamily: font.mono, fontSize: 11, color: C.dim }}>
                  every 4h · last scan {lastScan.toLocaleTimeString()} · promotes score ≥ 70, ≥ 20 closed positions
                </span>
              </div>
              <div style={{ display: "flex", gap: 8 }}>
                <button style={{ ...btn(false), fontFamily: font.mono, fontSize: 11, opacity: scanning ? 0.5 : 1 }} onClick={runScan} disabled={scanning}>Scan now</button>
                <button style={{ ...btn(false), fontFamily: font.mono, fontSize: 11, color: autoScan ? C.amber : C.dim }} onClick={() => setAutoScan((v) => !v)}>
                  {autoScan ? "Pause" : "Resume"}
                </button>
              </div>
            </div>

            <div style={{ ...card, overflow: "hidden" }}>
              <table style={{ width: "100%", borderCollapse: "collapse" }}>
                <thead>
                  <tr>
                    <th style={th}>#</th><th style={th}>WALLET</th><th style={th}>SCORE</th><th style={th}>WIN RATE</th>
                    <th style={th}>30D PNL</th><th style={th}>24H PNL</th><th style={th}>4H PNL</th><th style={th}>TRADES</th><th style={th}>AVG HOLD</th><th style={th}></th>
                  </tr>
                </thead>
                <tbody>
                  {sorted.map((w, i) => (
                    <tr key={w.addr} className="row" style={{ cursor: "pointer" }} onClick={() => setSel(w.addr)}>
                      <td style={{ ...td, fontFamily: font.mono, color: C.faint }}>{i + 1}</td>
                      <td style={td}>
                        <div style={{ fontWeight: 600 }}>
                          {w.name}
                          {w.seeded && <span style={{ fontFamily: font.mono, fontSize: 9, letterSpacing: 1, color: C.teal, background: "rgba(89,194,198,.12)", padding: "2px 6px", borderRadius: 4, marginLeft: 8 }}>SEEDED</span>}
                          {w.discovered && <span style={{ fontFamily: font.mono, fontSize: 9, letterSpacing: 1, color: C.amber, background: "rgba(255,180,84,.12)", padding: "2px 6px", borderRadius: 4, marginLeft: 8 }}>AUTO</span>}
                        </div>
                        <div style={{ fontFamily: font.mono, fontSize: 11, color: C.faint }}>{w.addr}</div>
                      </td>
                      <td style={td}>
                        <span style={{ fontFamily: font.mono, fontWeight: 600, color: w.score >= 75 ? C.up : w.score >= 55 ? C.amber : C.down }}>{w.score}</span>
                        <span style={{ marginLeft: 8 }}><Badge type={w.badge} /></span>
                      </td>
                      <td style={{ ...td, fontFamily: font.mono }}>{w.win}%</td>
                      <td style={td}><Num v={w.pnl30} suffix=" SOL" sign /></td>
                      <td style={td}><Num v={w.pnl24} suffix=" SOL" sign /></td>
                      <td style={td}><Num v={w.pnl4} suffix=" SOL" sign /></td>
                      <td style={{ ...td, fontFamily: font.mono, color: C.dim }}>{w.trades}</td>
                      <td style={{ ...td, fontFamily: font.mono, color: C.dim }}>{w.hold}</td>
                      <td style={{ ...td, textAlign: "right" }}>
                        <button style={{ ...btn(following.has(w.addr)), fontSize: 12 }} onClick={(e) => { e.stopPropagation(); toggleFollow(w.addr); }}>
                          {following.has(w.addr) ? "Following" : "Follow"}
                        </button>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
            <p style={{ fontFamily: font.mono, fontSize: 10, color: C.faint, marginTop: 14 }}>
              Past wallet performance does not predict future results. Nothing here is financial advice. Demo build — data shown is simulated.
            </p>
          </>
        )}

        {/* ---------- WALLET PROFILE ---------- */}
        {wallet && (
          <>
            <button onClick={() => setSel(null)} style={{ ...btn(false), border: "none", color: C.dim, padding: "4px 0", marginBottom: 14, fontFamily: font.mono, fontSize: 12 }}>← Back to leaderboard</button>
            <div style={{ display: "flex", gap: 18, flexWrap: "wrap" }}>
              <div style={{ ...card, padding: 20, flex: "1 1 300px", display: "flex", gap: 20, alignItems: "center" }}>
                <Donut score={wallet.score} />
                <div style={{ flex: 1 }}>
                  <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                    <h2 style={{ margin: 0, fontSize: 20 }}>{wallet.name}</h2>
                    <Badge type={wallet.badge} />
                  </div>
                  <div style={{ fontFamily: font.mono, fontSize: 12, color: C.faint, margin: "4px 0 12px" }}>{wallet.addr}</div>
                  <button style={btn(following.has(wallet.addr))} onClick={() => toggleFollow(wallet.addr)}>
                    {following.has(wallet.addr) ? "Following ✓" : "Follow — alert me on entries"}
                  </button>
                </div>
              </div>
              <div style={{ ...card, padding: 20, flex: "1 1 300px" }}>
                <div style={{ fontFamily: font.mono, fontSize: 10, letterSpacing: 1.2, color: C.faint, marginBottom: 12 }}>SCORE BREAKDOWN</div>
                {scoreParts(wallet).map((p) => (
                  <div key={p.k} style={{ marginBottom: 10 }}>
                    <div style={{ display: "flex", justifyContent: "space-between", fontSize: 12, marginBottom: 4 }}>
                      <span style={{ color: C.dim }}>{p.k}</span>
                      <span style={{ fontFamily: font.mono, color: p.v >= 70 ? C.up : p.v >= 45 ? C.amber : C.down }}>{p.v}</span>
                    </div>
                    <div style={{ height: 4, background: C.line, borderRadius: 3 }}>
                      <div style={{ height: 4, width: `${p.v}%`, borderRadius: 3, background: p.v >= 70 ? C.up : p.v >= 45 ? C.amber : C.down, transition: "width .6s ease" }} />
                    </div>
                  </div>
                ))}
              </div>
            </div>

            {wallet.flags.length > 0 && (
              <div style={{ ...card, borderColor: "rgba(240,97,109,.4)", padding: "14px 18px", marginTop: 18 }}>
                <div style={{ fontFamily: font.mono, fontSize: 10, letterSpacing: 1.2, color: C.down, marginBottom: 8 }}>MANIPULATION SIGNALS</div>
                {wallet.flags.map((f) => <div key={f} style={{ fontSize: 13, color: C.dim, padding: "2px 0" }}>· {f}</div>)}
              </div>
            )}

            <div style={{ ...card, padding: 20, marginTop: 18 }}>
              <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 8 }}>
                <div style={{ fontFamily: font.mono, fontSize: 10, letterSpacing: 1.2, color: C.faint }}>REALISED PNL — CUMULATIVE (SOL)</div>
                <Num v={Math.round(wallet.trades_[wallet.trades_.length - 1]?.cum2 || 0)} suffix=" SOL" sign />
              </div>
              <Spark pts={wallet.trades_.map((t) => t.cum2)} />
            </div>

            <div style={{ ...card, overflow: "hidden", marginTop: 18 }}>
              <div style={{ padding: "14px 16px", fontFamily: font.mono, fontSize: 10, letterSpacing: 1.2, color: C.faint }}>CLOSED POSITIONS (LAST 30D)</div>
              <table style={{ width: "100%", borderCollapse: "collapse" }}>
                <thead><tr><th style={th}>TOKEN</th><th style={th}>ENTRY</th><th style={th}>PNL</th><th style={th}>RETURN</th><th style={th}>HOLD</th><th style={th}>WHEN</th></tr></thead>
                <tbody>
                  {wallet.trades_.slice(-10).reverse().map((t, i) => (
                    <tr key={i}>
                      <td style={{ ...td, fontWeight: 600 }}>${t.token}</td>
                      <td style={{ ...td, fontFamily: font.mono, color: C.dim }}>{t.entry}</td>
                      <td style={td}><Num v={+t.pnlSol.toFixed(1)} suffix=" SOL" sign /></td>
                      <td style={td}><Num v={t.pct} suffix="%" sign /></td>
                      <td style={{ ...td, fontFamily: font.mono, color: C.dim }}>{t.hold}m</td>
                      <td style={{ ...td, fontFamily: font.mono, color: C.faint }}>{t.daysAgo}d ago</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </>
        )}

        {/* ---------- ALERTS ---------- */}
        {view === "alerts" && (
          <>
            <div className="page-head" style={{ display: "flex", alignItems: "baseline", justifyContent: "space-between", marginBottom: 18, gap: 10 }}>
              <div style={{ minWidth: 240 }}>
                <h1 style={{ margin: 0, fontSize: 26, fontWeight: 700 }}>Live entries</h1>
                <p style={{ margin: "6px 0 0", color: C.dim, fontSize: 13 }}>
                  New buys from wallets you follow, streamed as they confirm on-chain. Safety checks run before the trade button unlocks.
                </p>
              </div>
              <span style={{ fontFamily: font.mono, fontSize: 11, color: following.size ? C.up : C.amber }}>
                {following.size} wallet{following.size !== 1 ? "s" : ""} followed
              </span>
            </div>

            <div style={{ ...card, padding: "12px 18px", marginBottom: 16 }}>
              <div style={{ display: "flex", alignItems: "center", gap: 12, flexWrap: "wrap" }}>
                <span style={{ fontFamily: font.mono, fontSize: 10, letterSpacing: 1.2, color: C.faint }}>LAUNCHPADS</span>
                {Object.keys(pads).map((p) => (
                  <button key={p} onClick={() => setPads((prev) => ({ ...prev, [p]: !prev[p] }))}
                    style={{
                      fontFamily: font.mono, fontSize: 11, cursor: "pointer", borderRadius: 20, padding: "5px 12px",
                      border: `1px solid ${pads[p] ? C.amber : C.line}`,
                      background: pads[p] ? "rgba(255,180,84,.1)" : "transparent",
                      color: pads[p] ? C.amber : C.faint,
                    }}>
                    {pads[p] ? "✓ " : ""}{p}
                  </button>
                ))}
                <span style={{ fontFamily: font.mono, fontSize: 10, color: C.faint, marginLeft: "auto" }}>
                  alerts fire only from enabled pads
                </span>
              </div>
            </div>

            <div style={{ ...card, padding: "14px 18px", marginBottom: 16, borderLeft: `3px solid ${tg.connected ? "#2AABEE" : C.faint}` }}>
              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", flexWrap: "wrap", gap: 10 }}>
                <div style={{ display: "flex", alignItems: "center", gap: 12, flexWrap: "wrap" }}>
                  <span style={{ fontFamily: font.mono, fontSize: 11, letterSpacing: 1, color: tg.connected ? "#2AABEE" : C.faint }}>
                    {tg.connected ? `✈ TELEGRAM → ${tg.group}` : "✈ TELEGRAM DELIVERY OFF"}
                  </span>
                  {tg.connected && (
                    <div style={{ display: "flex", gap: 12, flexWrap: "wrap" }}>
                      {[["topEntries", "Top-5 trader entries"], ["mcCross", "$1M MC crossings"], ["followedEntries", "Followed wallet entries"]].map(([k, l]) => (
                        <button key={k} onClick={() => setTg((p) => ({ ...p, [k]: !p[k] }))}
                          style={{ background: "none", border: "none", cursor: "pointer", fontFamily: font.mono, fontSize: 11, color: tg[k] ? C.up : C.faint, padding: 0 }}>
                          {tg[k] ? "✓" : "○"} {l}
                        </button>
                      ))}
                    </div>
                  )}
                </div>
                <button
                  style={{ ...btn(!tg.connected), fontSize: 12 }}
                  onClick={() => {
                    if (tg.connected) { setTg((p) => ({ ...p, connected: false, group: "" })); flash("Telegram disconnected"); }
                    else { setTg((p) => ({ ...p, connected: true, group: "@solscope_alerts" })); flash("Bot added to @solscope_alerts — alerts now mirror to Telegram"); }
                  }}
                >
                  {tg.connected ? "Disconnect" : "Connect Telegram group"}
                </button>
              </div>
            </div>

            {plan === "free" && (
              <div style={{ ...card, padding: "14px 18px", marginBottom: 16, borderLeft: `3px solid ${C.amber}`, display: "flex", justifyContent: "space-between", alignItems: "center", flexWrap: "wrap", gap: 12 }}>
                <div>
                  <div style={{ fontWeight: 600, marginBottom: 3 }}>Free plan: alerts delayed 15 minutes, copy execution locked</div>
                  <div style={{ fontSize: 12, color: C.dim }}>In memecoin timeframes a 15-minute-old entry is history. Real-time alerts + one-tap copy from $9.99/day, paid in USDC.</div>
                </div>
                <button style={btn(true)} onClick={() => setShowPricing(true)}>Unlock real-time</button>
              </div>
            )}

            {alerts.length === 0 && (
              <div style={{ ...card, padding: 40, textAlign: "center", color: C.dim }}>
                Waiting for the next entry from a followed wallet — alerts land here in real time.
              </div>
            )}

            <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
              {alerts.map((a) => {
                const safe = a.token.mint && a.token.lp && a.token.top10 < 30;
                const isMc = a.type === "MC_CROSS";
                const sentTg = tg.connected && (isMc ? tg.mcCross : a.topFive ? tg.topEntries : tg.followedEntries);
                return (
                  <div key={a.id} className="alert-in" style={{ ...card, padding: "16px 18px", borderLeft: `3px solid ${isMc ? C.teal : C.amber}` }}>
                    <div style={{ display: "flex", justifyContent: "space-between", flexWrap: "wrap", gap: 12 }}>
                      <div>
                        <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 4, flexWrap: "wrap" }}>
                          <span style={{ fontFamily: font.mono, fontSize: 10, letterSpacing: 1, color: isMc ? C.teal : C.amber }}>
                            {isMc ? "$1M MC CROSS" : "ENTRY"}
                          </span>
                          {!isMc && a.topFive && (
                            <span style={{ fontFamily: font.mono, fontSize: 9, letterSpacing: 1, color: C.amber, background: "rgba(255,180,84,.12)", padding: "2px 6px", borderRadius: 4 }}>TOP 5 TRADER</span>
                          )}
                          <span style={{ fontWeight: 700, fontSize: 16 }}>${a.token.sym}</span>
                          <span style={{ color: C.faint, fontSize: 12 }}>{a.token.name}</span>
                          <span style={{ fontFamily: font.mono, fontSize: 9, letterSpacing: 1, color: C.dim, background: "rgba(139,153,168,.12)", padding: "2px 6px", borderRadius: 4 }}>{a.token.pad.toUpperCase()}</span>
                          {sentTg && <span style={{ fontFamily: font.mono, fontSize: 9, letterSpacing: 1, color: "#2AABEE" }}>✈ SENT TO TELEGRAM</span>}
                        </div>
                        <div style={{ fontSize: 13, color: C.dim }}>
                          {isMc ? (
                            <>Crossed <b style={{ color: C.text }}>$1M market cap</b> — now <span style={{ fontFamily: font.mono, color: C.text }}>{a.mcNow}</span> · {a.holders.toLocaleString()} holders</>
                          ) : (
                            <><b style={{ color: C.text }}>{a.wallet.name}</b> bought <span style={{ fontFamily: font.mono, color: C.text }}>{a.sizeSol} SOL</span> at <span style={{ fontFamily: font.mono }}>{a.entry}</span></>
                          )}
                        </div>
                        <div style={{ marginTop: 8 }}>
                          <Check ok={a.token.mint} label="mint revoked" />
                          <Check ok={a.token.lp} label="LP locked" />
                          <Check ok={a.token.top10 < 30} label={`top10 ${a.token.top10}%`} />
                        </div>
                      </div>
                      <div style={{ textAlign: "right" }}>
                        <div style={{ fontFamily: font.mono, fontSize: 11, color: C.faint, marginBottom: 2 }}>
                          MC {isMc ? a.mcNow : a.token.mc} · LIQ {a.token.liq} · AGE {a.token.age}
                        </div>
                        <div style={{ fontFamily: font.mono, fontSize: 10, color: C.faint, marginBottom: 10 }}>
                          {a.ts.toLocaleTimeString()}
                        </div>
                        <button
                          disabled={!safe}
                          style={{ ...btn(safe && plan === "pro"), opacity: safe ? 1 : 0.45, cursor: safe ? "pointer" : "not-allowed", borderColor: safe && plan === "free" ? C.teal : undefined, color: safe && plan === "free" ? C.teal : undefined }}
                          onClick={() => safe && (plan === "pro" ? setTicket(a) : setShowPricing(true))}
                        >
                          {!safe ? "Blocked — failed safety" : plan === "pro" ? (isMc ? "Trade this token" : "Copy this entry") : "🔒 Trade — Pro only"}
                        </button>
                      </div>
                    </div>
                  </div>
                );
              })}
            </div>
          </>
        )}

        {/* ---------- IMPORT / SEED ---------- */}
        {view === "import" && (
          <>
            <h1 style={{ margin: "0 0 6px", fontSize: 26, fontWeight: 700 }}>Import wallets</h1>
            <p style={{ margin: "0 0 18px", color: C.dim, fontSize: 13, maxWidth: 620 }}>
              Seed your watchlist with wallet addresses you've found anywhere — leaderboards, Telegram groups, explorers. SolScope pulls their full trade history from the chain, pairs positions, runs sniper and insider checks, and scores them independently. You rank on verified on-chain data, never on someone else's numbers.
            </p>

            <div style={{ ...card, padding: 20 }}>
              <label style={{ fontFamily: font.mono, fontSize: 10, letterSpacing: 1.2, color: C.faint, display: "block", marginBottom: 8 }}>
                SOLANA ADDRESSES — ONE PER LINE
              </label>
              <textarea
                value={seedText}
                onChange={(e) => setSeedText(e.target.value)}
                placeholder={"e.g.\nDYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK\n5Q544fKrFoe6tsEbD7S8EmxGTJYAKtTVhAW5Q5pge4j1"}
                rows={5}
                style={{ width: "100%", background: C.bg, border: `1px solid ${C.line}`, borderRadius: 8, color: C.text, fontFamily: font.mono, fontSize: 13, padding: "12px 14px", resize: "vertical" }}
              />
              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginTop: 12 }}>
                <span style={{ fontFamily: font.mono, fontSize: 11, color: C.faint }}>
                  {imported.length} seeded wallet{imported.length !== 1 ? "s" : ""} live on leaderboard
                </span>
                <button style={btn(true)} onClick={runImport}>Import & verify on-chain</button>
              </div>
            </div>

            {queue.length > 0 && (
              <div style={{ display: "flex", flexDirection: "column", gap: 10, marginTop: 18 }}>
                {queue.map((q) => (
                  <div key={q.addr} className="alert-in" style={{ ...card, padding: "14px 18px", borderLeft: `3px solid ${q.error ? C.down : C.teal}` }}>
                    <div style={{ fontFamily: font.mono, fontSize: 12, color: C.text, wordBreak: "break-all", marginBottom: 6 }}>{q.addr}</div>
                    {q.error ? (
                      <div style={{ fontSize: 12, color: C.down }}>✗ {q.error}</div>
                    ) : (
                      <div style={{ display: "flex", flexWrap: "wrap", gap: 14 }}>
                        {VERIFY_STEPS.map((s, i) => (
                          <span key={s} style={{ fontFamily: font.mono, fontSize: 11, color: q.step > i ? C.up : q.step === i ? C.amber : C.faint }}>
                            {q.step > i ? "✓" : q.step === i ? "◌" : "·"} {s}
                          </span>
                        ))}
                      </div>
                    )}
                  </div>
                ))}
              </div>
            )}

            <div style={{ ...card, padding: "14px 18px", marginTop: 18, borderColor: "rgba(255,180,84,.35)" }}>
              <div style={{ fontFamily: font.mono, fontSize: 10, letterSpacing: 1.2, color: C.amber, marginBottom: 6 }}>HOW SEEDING WORKS IN PRODUCTION</div>
              <div style={{ fontSize: 12.5, color: C.dim, lineHeight: 1.6 }}>
                Wallet addresses are public on-chain identifiers — importing one triggers a Helius backfill of its full swap history across Raydium, Pump.fun, PumpSwap, Meteora and Orca. Win rate and PnL are computed from closed round-trips on your own infrastructure. If a wallet fails the sniper/insider checks it still appears, flagged, with the evidence shown. This demo simulates the pipeline; the live build runs it for real.
              </div>
            </div>
          </>
        )}

        {/* ---------- MY COPIES ---------- */}
        {view === "copies" && (
          <>
            <h1 style={{ margin: "0 0 6px", fontSize: 26, fontWeight: 700 }}>My copies</h1>
            <p style={{ margin: "0 0 18px", color: C.dim, fontSize: 13 }}>
              Every executed copy, with the gap between the tracked wallet's entry and your fill — so you can see what following actually costs.
            </p>
            {copies.length === 0 ? (
              <div style={{ ...card, padding: 40, textAlign: "center", color: C.dim }}>
                No copies yet. Open the Alerts tab and copy an entry to see it tracked here.
              </div>
            ) : (
              <div style={{ ...card, overflow: "hidden" }}>
                <table style={{ width: "100%", borderCollapse: "collapse" }}>
                  <thead><tr><th style={th}>TOKEN</th><th style={th}>FOLLOWED</th><th style={th}>SIZE</th><th style={th}>THEIR ENTRY</th><th style={th}>YOUR FILL</th><th style={th}>ENTRY DELTA</th><th style={th}>TIME</th></tr></thead>
                  <tbody>
                    {copies.map((c, i) => (
                      <tr key={i}>
                        <td style={{ ...td, fontWeight: 600 }}>${c.token}</td>
                        <td style={{ ...td, color: C.dim }}>{c.walletName}</td>
                        <td style={{ ...td, fontFamily: font.mono }}>{c.size} SOL</td>
                        <td style={{ ...td, fontFamily: font.mono, color: C.dim }}>{c.theirEntry}</td>
                        <td style={{ ...td, fontFamily: font.mono }}>{c.yourFill}</td>
                        <td style={td}><Num v={c.delta} suffix="%" sign /></td>
                        <td style={{ ...td, fontFamily: font.mono, color: C.faint }}>{c.ts}</td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            )}
          </>
        )}
      </main>

      {/* ---------- TRADE TICKET MODAL ---------- */}
      {ticket && (
        <TradeTicket
          alert={ticket}
          onClose={() => setTicket(null)}
          onSign={(order) => {
            const slip = +(Math.random() * 2.2 + 0.3).toFixed(2);
            setCopies((prev) => [{
              token: ticket.token.sym,
              walletName: ticket.wallet ? ticket.wallet.name : "$1M MC scanner",
              size: order.size,
              theirEntry: ticket.entry,
              yourFill: (parseFloat(ticket.entry) * (1 + slip / 100)).toFixed(6),
              delta: -slip,
              ts: new Date().toLocaleTimeString(),
            }, ...prev]);
            setTicket(null);
            flash(`Copied $${ticket.token.sym} — ${order.size} SOL signed & sent`);
          }}
          card={card} btn={btn}
        />
      )}

      {/* ---------- PRICING / CRYPTO CHECKOUT ---------- */}
      {showPricing && (
        <div style={{ position: "fixed", inset: 0, background: "rgba(4,7,11,.72)", display: "grid", placeItems: "center", zIndex: 60 }} onClick={() => setShowPricing(false)}>
          <div style={{ ...card, width: 640, maxWidth: "94vw", padding: 24 }} onClick={(e) => e.stopPropagation()}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 4 }}>
              <h3 style={{ margin: 0, fontSize: 18 }}>Go Pro — pay in USDC</h3>
              <button onClick={() => setShowPricing(false)} style={{ background: "none", border: "none", color: C.faint, fontSize: 18, cursor: "pointer" }}>×</button>
            </div>
            <p style={{ margin: "0 0 18px", fontSize: 12.5, color: C.dim }}>
              Paid on Solana via Solana Pay from the same wallet you trade with. Access unlocks the moment the transfer confirms on-chain — no card, no account, no chargebacks.
            </p>
            <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(170px, 1fr))", gap: 12 }}>
              {[
                { id: "day", label: "DAY PASS", price: "9.99", per: "/24h", pitch: "Real-time alerts + copy execution for one session", hot: false },
                { id: "week", label: "WEEKLY", price: "34.99", per: "/7d", pitch: "Everything, all week — best for active runs", hot: true },
                { id: "month", label: "MONTHLY", price: "99", per: "/30d", pitch: "Full access + priority alert delivery", hot: false },
              ].map((t) => (
                <div key={t.id} style={{ background: C.bg, border: `1px solid ${t.hot ? C.amber : C.line}`, borderRadius: 10, padding: 16, position: "relative" }}>
                  {t.hot && <span style={{ position: "absolute", top: -9, right: 10, fontFamily: font.mono, fontSize: 9, letterSpacing: 1, background: C.amber, color: "#1A1205", padding: "2px 8px", borderRadius: 4 }}>POPULAR</span>}
                  <div style={{ fontFamily: font.mono, fontSize: 10, letterSpacing: 1.2, color: C.faint }}>{t.label}</div>
                  <div style={{ margin: "8px 0 2px" }}>
                    <span style={{ fontSize: 26, fontWeight: 700 }}>${t.price}</span>
                    <span style={{ fontFamily: font.mono, fontSize: 11, color: C.faint }}> USDC{t.per}</span>
                  </div>
                  <div style={{ fontSize: 11.5, color: C.dim, minHeight: 34, marginBottom: 12 }}>{t.pitch}</div>
                  <button
                    style={{ ...btn(false), width: "100%", fontSize: 12.5, opacity: 0.8 }}
                    onClick={() => flash("Checkout launches soon — USDC via Solana Pay")}
                  >
                    Launching soon
                  </button>
                </div>
              ))}
            </div>
            <p style={{ fontFamily: font.mono, fontSize: 10, color: C.faint, margin: "16px 0 0" }}>
              Production flow: backend issues a Solana Pay transfer request with a unique reference → wallet pays USDC → indexer confirms the reference on-chain → entitlement activates. A 0.75% fee applies to copy-trade executions on all plans.
            </p>
          </div>
        </div>
      )}

      {/* ---------- toast ---------- */}
      {toast && (
        <div style={{ position: "fixed", bottom: 24, left: "50%", transform: "translateX(-50%)", background: C.panel2, border: `1px solid ${C.line}`, borderRadius: 8, padding: "10px 18px", fontSize: 13, boxShadow: "0 8px 28px rgba(0,0,0,.5)" }}>
          {toast}
        </div>
      )}
    </div>
  );
}

/* ---------------- trade ticket ---------------- */

function TradeTicket({ alert, onClose, onSign, card, btn }) {
  const [size, setSize] = useState("1.0");
  const [slippage, setSlippage] = useState("2");
  const [tp, setTp] = useState("100");
  const [sl, setSl] = useState("40");
  const label = { fontFamily: font.mono, fontSize: 10, letterSpacing: 1.2, color: C.faint, display: "block", marginBottom: 6 };
  const input = { width: "100%", background: C.bg, border: `1px solid ${C.line}`, borderRadius: 7, color: C.text, fontFamily: font.mono, fontSize: 14, padding: "9px 11px" };

  return (
    <div style={{ position: "fixed", inset: 0, background: "rgba(4,7,11,.72)", display: "grid", placeItems: "center", zIndex: 50 }} onClick={onClose}>
      <div style={{ ...card, width: 400, maxWidth: "92vw", padding: 22 }} onClick={(e) => e.stopPropagation()}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 4 }}>
          <h3 style={{ margin: 0, fontSize: 17 }}>Copy entry · ${alert.token.sym}</h3>
          <button onClick={onClose} style={{ background: "none", border: "none", color: C.faint, fontSize: 18, cursor: "pointer" }}>×</button>
        </div>
        <p style={{ margin: "0 0 16px", fontSize: 12, color: C.dim }}>
          {alert.wallet
            ? <>Following <b style={{ color: C.text }}>{alert.wallet.name}</b> · their size {alert.sizeSol} SOL · routed via Jupiter, signed in your wallet</>
            : <>Momentum entry on $1M MC crossing · routed via Jupiter, signed in your wallet</>}
        </p>

        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
          <div>
            <label style={label}>YOUR SIZE (SOL)</label>
            <input style={input} value={size} onChange={(e) => setSize(e.target.value)} inputMode="decimal" />
          </div>
          <div>
            <label style={label}>MAX SLIPPAGE (%)</label>
            <input style={input} value={slippage} onChange={(e) => setSlippage(e.target.value)} inputMode="decimal" />
          </div>
          <div>
            <label style={label}>TAKE PROFIT (+%)</label>
            <input style={input} value={tp} onChange={(e) => setTp(e.target.value)} inputMode="decimal" />
          </div>
          <div>
            <label style={label}>STOP LOSS (−%)</label>
            <input style={input} value={sl} onChange={(e) => setSl(e.target.value)} inputMode="decimal" />
          </div>
        </div>

        <p style={{ fontSize: 11, color: C.faint, margin: "14px 0" }}>
          Non-custodial: TP/SL are monitored conditions — you'll be prompted to sign the exit when they trigger. Keys never leave your wallet.
        </p>

        <button style={{ ...btn(true), width: "100%", padding: "12px", fontSize: 14 }} onClick={() => onSign({ size: parseFloat(size) || 1 })}>
          Review & sign in wallet
        </button>
      </div>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
