// Cubexagent — single-file React landing page.
// Default-exported component. Tailwind utility classes only. Inline SVG icons
// (lucide-style line icons) so the file is fully self-contained.

const { useState, useEffect, useRef, useCallback, createContext, useContext } = React;

/* ---------- Wallet (Phantom — Solana) ---------- */

const WalletCtx = createContext(null);

const useWallet = () => useContext(WalletCtx);

const WalletProvider = ({ children }) => {
  const [pubkey, setPubkey] = useState(null);
  const [connecting, setConnecting] = useState(false);
  const [error, setError] = useState(null);

  const provider = () => (typeof window !== "undefined" && window.solana && window.solana.isPhantom ? window.solana : null);

  const connect = useCallback(async () => {
    setError(null);
    const p = provider();
    if (!p) {
      // open phantom site in new tab if not installed
      window.open("https://phantom.app/", "_blank", "noopener");
      setError("Phantom not detected. Install Phantom and refresh.");
      return;
    }
    try {
      setConnecting(true);
      const res = await p.connect();
      const key = res?.publicKey?.toString?.() || p.publicKey?.toString?.() || null;
      setPubkey(key);
    } catch (e) {
      setError(e?.message || "Connection rejected.");
    } finally {
      setConnecting(false);
    }
  }, []);

  const disconnect = useCallback(async () => {
    const p = provider();
    if (p) { try { await p.disconnect(); } catch {} }
    setPubkey(null);
  }, []);

  useEffect(() => {
    const p = provider();
    if (!p) return;
    // silent reconnect if previously trusted
    p.connect({ onlyIfTrusted: true })
      .then((r) => setPubkey(r?.publicKey?.toString?.() || null))
      .catch(() => {});
    const onAcc = (k) => setPubkey(k ? k.toString() : null);
    p.on?.("accountChanged", onAcc);
    p.on?.("disconnect", () => setPubkey(null));
    return () => { p.removeListener?.("accountChanged", onAcc); };
  }, []);

  return (
    <WalletCtx.Provider value={{ pubkey, connecting, error, connect, disconnect }}>
      {children}
    </WalletCtx.Provider>
  );
};

const shortKey = (k) => (k ? `${k.slice(0, 4)}…${k.slice(-4)}` : "");

/* ---------- Icons (lucide-style, 24x24, stroke 1.5) ---------- */
const I = (paths, opts = {}) => ({ size = 16, className = "", strokeWidth = 1.5 }) => (
  <svg
    width={size}
    height={size}
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth={strokeWidth}
    strokeLinecap="round"
    strokeLinejoin="round"
    className={className}
    {...opts}
  >
    {paths}
  </svg>
);

const Menu = I(<><path d="M4 6h16"/><path d="M4 12h16"/><path d="M4 18h16"/></>);
const X = I(<><path d="M18 6 6 18"/><path d="m6 6 12 12"/></>);
const Plug = I(<><path d="M12 22v-5"/><path d="M9 8V2"/><path d="M15 8V2"/><path d="M18 8v5a4 4 0 0 1-4 4h-4a4 4 0 0 1-4-4V8Z"/></>);
const ArrowUpRight = I(<><path d="M7 7h10v10"/><path d="M7 17 17 7"/></>);
const Copy = I(<><rect width="14" height="14" x="8" y="8" rx="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></>);
const Check = I(<path d="M20 6 9 17l-5-5"/>);
const MessageCircle = I(<path d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"/>);
const Zap = I(<path d="M13 2 3 14h9l-1 8 10-12h-9l1-8z"/>);
const Activity = I(<path d="M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.5.5 0 0 1-.96 0L9.68 3.18a.5.5 0 0 0-.96 0l-2.35 8.36A2 2 0 0 1 4.44 13H2"/>);
const Globe = I(<><circle cx="12" cy="12" r="10"/><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"/><path d="M2 12h20"/></>);
const Code = I(<><path d="m16 18 6-6-6-6"/><path d="m8 6-6 6 6 6"/></>);
const Crosshair = I(<><circle cx="12" cy="12" r="10"/><path d="M22 12h-4"/><path d="M6 12H2"/><path d="M12 6V2"/><path d="M12 22v-4"/></>);
const Bot = I(<><path d="M12 8V4H8"/><rect width="16" height="12" x="4" y="8" rx="2"/><path d="M2 14h2"/><path d="M20 14h2"/><path d="M15 13v2"/><path d="M9 13v2"/></>);
const Users = I(<><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></>);
const Workflow = I(<><rect width="8" height="8" x="3" y="3" rx="2"/><path d="M7 11v4a2 2 0 0 0 2 2h4"/><rect width="8" height="8" x="13" y="13" rx="2"/></>);
const Flame = I(<path d="M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z"/>);
const Twitter = I(<path d="M18 4 6.5 20H3l8.5-12L3 4h3.5L12 11l4-7z"/>);
const CheckCircle = I(<><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><path d="m9 11 3 3L22 4"/></>);
const Loader = I(<><path d="M21 12a9 9 0 1 1-6.219-8.56"/></>);
const Clock = I(<><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></>);
const ChevronRight = I(<path d="m9 18 6-6-6-6"/>);
const Search = I(<><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></>);

/* ---------- Shared bits ---------- */

const MonoLabel = ({ children, className = "" }) => (
  <span className={`font-mono tracking-[0.2em] text-[11px] uppercase text-neutral-500 ${className}`}>
    {children}
  </span>
);

const GhostNumber = ({ children, side = "left" }) => (
  <div
    aria-hidden
    className={`pointer-events-none absolute top-0 ${side === "left" ? "left-0 -translate-x-2" : "right-0 translate-x-2"} select-none font-semibold leading-none text-[#1A1A1A]`}
    style={{ fontSize: "clamp(120px, 18vw, 280px)" }}
  >
    {children}
  </div>
);

const DotField = ({ className = "", opacity = 0.6 }) => (
  <div
    aria-hidden
    className={`pointer-events-none absolute inset-0 ${className}`}
    style={{
      backgroundImage:
        "radial-gradient(circle, rgba(74,222,128,0.25) 1px, transparent 1px)",
      backgroundSize: "14px 14px",
      opacity,
      maskImage:
        "radial-gradient(ellipse at center, black 30%, transparent 75%)",
      WebkitMaskImage:
        "radial-gradient(ellipse at center, black 30%, transparent 75%)",
    }}
  />
);

const useReveal = () => {
  const ref = useRef(null);
  const [shown, setShown] = useState(false);
  useEffect(() => {
    if (!ref.current) return;
    const io = new IntersectionObserver(
      ([e]) => e.isIntersecting && (setShown(true), io.disconnect()),
      { threshold: 0.12 }
    );
    io.observe(ref.current);
    return () => io.disconnect();
  }, []);
  return [ref, shown];
};

const Reveal = ({ children, delay = 0, className = "" }) => {
  const [ref, shown] = useReveal();
  return (
    <div
      ref={ref}
      style={{ transitionDelay: `${delay}ms` }}
      className={`transition-all duration-[900ms] ease-out ${shown ? "opacity-100 translate-y-0" : "opacity-0 translate-y-6"} ${className}`}
    >
      {children}
    </div>
  );
};

/* ---------- Cube (animated GIF, black knocked out via mix-blend-mode) ---------- */

const CubeMark = ({ size = 320, glow = true, className = "" }) => (
  <div className={`relative ${className}`} style={{ width: size, height: size }}>
    {glow && (
      <div
        aria-hidden
        className="absolute inset-0"
        style={{
          background:
            "radial-gradient(circle at 50% 50%, rgba(74,222,128,0.18), transparent 60%)",
          filter: "blur(20px)",
        }}
      />
    )}
    <img
      src="assets/cube.gif"
      alt=""
      width={size}
      height={size}
      draggable={false}
      className="relative h-full w-full select-none"
      style={{ mixBlendMode: "screen" }}
    />
  </div>
);

/* ---------- Logo mark (small static cube + wordmark) ---------- */

const LogoMark = ({ size = 24 }) => (
  <span className="relative inline-block" style={{ width: size, height: size }}>
    <img
      src="assets/logo.jpg"
      alt="Cubexagent"
      width={size}
      height={size}
      draggable={false}
      className="block select-none"
      style={{ mixBlendMode: "screen" }}
    />
  </span>
);

/* ---------- Nav ---------- */

const NAV_SCROLL = ["About", "Features", "Tokenomics", "Roadmap", "Community", "Agents", "Stats"];
const NAV_PAGES  = [{ label: "APP", href: "/#/app" }, { label: "DOCS", href: "/#/docs" }];

/* ---------- Connect button (wired to wallet) ---------- */
const ConnectButton = ({ variant = "dark", size = "sm" }) => {
  const w = useWallet();
  const padding = size === "lg" ? "px-5 py-2.5" : "px-4 py-2";
  const base = variant === "ghost"
    ? "border-green-400/60 text-green-400 hover:bg-green-400/10"
    : "border-neutral-800 bg-black/70 text-white hover:border-green-400/60 hover:text-green-400";
  if (w?.pubkey) {
    return (
      <button
        onClick={w.disconnect}
        title={w.pubkey}
        className={`group flex items-center gap-2 rounded-full border ${padding} font-mono text-[11px] tracking-[0.2em] backdrop-blur transition-colors border-green-400/60 text-green-400 hover:bg-green-400/10`}
      >
        <span className="h-1.5 w-1.5 rounded-full bg-green-400"/> {shortKey(w.pubkey)}
      </button>
    );
  }
  return (
    <button
      onClick={w?.connect}
      disabled={w?.connecting}
      className={`group flex items-center gap-2 rounded-full border ${padding} font-mono text-[11px] tracking-[0.2em] backdrop-blur transition-colors disabled:opacity-60 ${base}`}
    >
      <Plug size={13}/> {w?.connecting ? "CONNECTING…" : "CONNECT"}
    </button>
  );
};

const Nav = ({ currentPage = "landing" }) => {
  const [open, setOpen] = useState(false);
  return (
    <header className="fixed inset-x-0 top-0 z-50 px-5 pt-5 md:px-10">
      <div className="mx-auto flex max-w-[1400px] items-center justify-between gap-4">
        <a href="/#" className="flex items-center gap-2 rounded-full border border-neutral-800 bg-black/70 px-4 py-2 backdrop-blur">
          <LogoMark />
          <span className="font-mono text-[13px] tracking-[0.18em] text-white">CUBEXAGENT</span>
        </a>

        <nav className="hidden lg:flex items-center rounded-full border border-neutral-800 bg-black/70 px-2 py-1.5 backdrop-blur">
          {currentPage === "landing" && NAV_SCROLL.map((n) => (
            <a
              key={n}
              href={`#${n.toLowerCase()}`}
              className="rounded-full px-4 py-2 font-mono text-[11px] tracking-[0.2em] text-neutral-400 transition-colors hover:bg-neutral-900 hover:text-white"
            >
              {n.toUpperCase()}
            </a>
          ))}
          {NAV_PAGES.map(({ label, href }) => (
            <a
              key={label}
              href={href}
              className={`rounded-full px-4 py-2 font-mono text-[11px] tracking-[0.2em] transition-colors hover:bg-neutral-900 hover:text-white ${
                (label === "APP" && currentPage === "app") || (label === "DOCS" && currentPage === "docs")
                  ? "text-white bg-neutral-900"
                  : "text-neutral-400"
              }`}
            >
              {label}
            </a>
          ))}
        </nav>

        <div className="hidden md:flex items-center gap-2">
          <ConnectButton/>
          <a href="/#/app" className="group flex items-center gap-2 rounded-full bg-white px-4 py-2 font-mono text-[11px] tracking-[0.2em] text-black transition-transform hover:-translate-y-0.5">
            DASHBOARD <ArrowUpRight size={13}/>
          </a>
        </div>

        <button
          aria-label="Menu"
          onClick={() => setOpen((o) => !o)}
          className="lg:hidden flex h-10 w-10 items-center justify-center rounded-full border border-neutral-800 bg-black/70 text-white backdrop-blur"
        >
          {open ? <X size={18}/> : <Menu size={18}/>}
        </button>
      </div>

      {open && (
        <div className="lg:hidden mx-auto mt-2 max-w-[1400px] rounded-2xl border border-neutral-800 bg-black/90 p-4 backdrop-blur">
          <div className="flex flex-col gap-1">
            {currentPage === "landing" && NAV_SCROLL.map((n) => (
              <a key={n} href={`#${n.toLowerCase()}`} onClick={() => setOpen(false)} className="rounded-lg px-3 py-2 font-mono text-[11px] tracking-[0.2em] text-neutral-400 hover:bg-neutral-900 hover:text-white">
                {n.toUpperCase()}
              </a>
            ))}
            {NAV_PAGES.map(({ label, href }) => (
              <a key={label} href={href} onClick={() => setOpen(false)} className={`rounded-lg px-3 py-2 font-mono text-[11px] tracking-[0.2em] hover:bg-neutral-900 hover:text-white ${
                (label === "APP" && currentPage === "app") || (label === "DOCS" && currentPage === "docs")
                  ? "text-white bg-neutral-900"
                  : "text-neutral-400"
              }`}>
                {label}
              </a>
            ))}
            <div className="mt-2 grid grid-cols-2 gap-2">
              <ConnectButton/>
              <a href="/#/app" className="flex items-center justify-center gap-2 rounded-full bg-white px-3 py-2 font-mono text-[11px] tracking-[0.2em] text-black">DASHBOARD <ArrowUpRight size={13}/></a>
            </div>
          </div>
        </div>
      )}
    </header>
  );
};

/* ---------- Contract address pill ---------- */

const CA = "TBA";
const shortCA = `${CA.slice(0, 6)}…${CA.slice(-5)}`;

const ContractPill = ({ variant = "dark" }) => {
  const [copied, setCopied] = useState(false);
  const copy = () => {
    navigator.clipboard?.writeText(CA);
    setCopied(true);
    setTimeout(() => setCopied(false), 1400);
  };
  const base = variant === "dark"
    ? "border-neutral-800 bg-black/60 text-neutral-300"
    : "border-neutral-800 bg-neutral-950 text-neutral-300";
  return (
    <div className={`inline-flex items-center gap-3 rounded-full border ${base} pl-3 pr-1.5 py-1.5 backdrop-blur`}>
      <span className="font-mono text-[10px] tracking-[0.2em] text-neutral-500">CA</span>
      <span className="font-mono text-[12px] text-neutral-200">{shortCA}</span>
      <button
        onClick={copy}
        aria-label="Copy contract address"
        className="flex h-7 w-7 items-center justify-center rounded-full text-neutral-400 transition-colors hover:bg-neutral-900 hover:text-green-400"
      >
        {copied ? <Check size={13} className="text-green-400"/> : <Copy size={13}/>}
      </button>
      {copied && <span className="pr-2 font-mono text-[10px] tracking-[0.2em] text-green-400">COPIED</span>}
    </div>
  );
};

/* ---------- HERO ---------- */

const Hero = () => (
  <section id="top" className="relative overflow-hidden pt-40 pb-24 md:pt-44 md:pb-32">
    <DotField opacity={0.7}/>
    <div className="relative mx-auto max-w-[1400px] px-5 md:px-10">
      <div className="flex flex-col items-center text-center">

        <Reveal>
          <MonoLabel className="text-neutral-500">CUBEXAGENT / 01 / SOLANA</MonoLabel>
        </Reveal>

        {/* Hero stack: cube behind, text foreground */}
        <div className="relative mt-10 flex w-full items-center justify-center">
          <div className="pointer-events-none absolute inset-0 flex items-center justify-center">
            <CubeMark size={520}/>
          </div>

          <Reveal delay={120}>
            <h1 className="relative font-semibold leading-[0.95] tracking-[-0.04em] text-white" style={{ fontSize: "clamp(56px, 11vw, 168px)" }}>
              <span className="block">Move</span>
              <span className="block italic font-light" style={{ color: "#4ADE80" }}>with intent.</span>
            </h1>
          </Reveal>
        </div>

        <Reveal delay={220}>
          <p className="mt-12 max-w-xl text-balance text-base text-neutral-400 md:text-lg">
            No “join the journey.” Drop a question, query the mesh, publish your own agent.
            The work shows itself.
          </p>
        </Reveal>

        <Reveal delay={300}>
          <div className="mt-10 flex flex-wrap items-center justify-center gap-2">
            <a href="https://x.com/cubexagent" target="_blank" rel="noopener noreferrer" className="group flex items-center gap-2 rounded-full border border-neutral-800 bg-black/70 px-4 py-2.5 font-mono text-[11px] tracking-[0.2em] text-neutral-300 transition-colors hover:border-green-400/60 hover:text-white">
              <Twitter size={13}/> X
            </a>
            <a href="https://pump.fun" target="_blank" rel="noopener noreferrer" className="group flex items-center gap-2 rounded-full border border-neutral-800 bg-black/70 px-4 py-2.5 font-mono text-[11px] tracking-[0.2em] text-neutral-300 transition-colors hover:border-green-400/60 hover:text-white">
              <Flame size={13}/> PUMP.FUN
            </a>
            <a className="group flex items-center gap-2 rounded-full border border-neutral-800 bg-black/70 px-4 py-2.5 font-mono text-[11px] tracking-[0.2em] text-neutral-300 transition-colors hover:border-green-400/60 hover:text-white">
              <Search size={13}/> BROWSE AGENTS
            </a>
            <a className="group flex items-center gap-2 rounded-full bg-white px-5 py-2.5 font-mono text-[11px] tracking-[0.2em] text-black transition-transform hover:-translate-y-0.5">
              OPEN DASHBOARD <ArrowUpRight size={13}/>
            </a>
          </div>
        </Reveal>

        <Reveal delay={380}>
          <div className="mt-12"><ContractPill/></div>
        </Reveal>
      </div>
    </div>

    {/* status strip */}
    <div className="relative mx-auto mt-24 max-w-[1400px] px-5 md:px-10">
      <div className="flex flex-col items-center justify-between gap-4 rounded-full border border-neutral-800 bg-neutral-950/60 px-6 py-3 backdrop-blur md:flex-row">
        <MonoLabel className="text-neutral-400">NOT NOISE. SIGNAL.</MonoLabel>
        <a href="#about" className="rounded-full border border-neutral-800 px-5 py-2 font-mono text-[11px] tracking-[0.2em] text-white transition-colors hover:border-green-400/60 hover:text-green-400">
          HOW IT WORKS
        </a>
        <MonoLabel className="text-neutral-400">AI AGENT MESH ON SOLANA.</MonoLabel>
      </div>
    </div>
  </section>
);

/* ---------- ABOUT (02) ---------- */

const About = () => (
  <section id="about" className="relative overflow-hidden py-32 md:py-44">
    <GhostNumber side="right">02</GhostNumber>
    <DotField opacity={0.4}/>
    <div className="relative mx-auto grid max-w-[1400px] gap-12 px-5 md:grid-cols-12 md:px-10">
      <div className="md:col-span-3">
        <MonoLabel>ABOUT / 02</MonoLabel>
        <p className="mt-6 font-mono text-[11px] uppercase tracking-[0.2em] leading-[2] text-neutral-500">
          Five<br/>agents.<br/>One mesh.<br/>Yours on<br/>login.
        </p>
      </div>

      <div className="md:col-span-9">
        <Reveal>
          <h2 className="font-semibold leading-[0.95] tracking-[-0.03em] text-white" style={{ fontSize: "clamp(40px, 6.2vw, 96px)" }}>
            You transmit.<br/>
            They <span className="italic font-light" style={{ color: "#4ADE80" }}>read the tape.</span>
          </h2>
        </Reveal>

        <div className="mt-12 grid gap-10 md:grid-cols-2">
          <Reveal delay={120}>
            <p className="text-balance text-neutral-300 text-lg leading-relaxed">
              Cubexagent is an <span className="text-white font-medium">AI agent mesh</span> on Solana.
              Five signal nodes — each with a defined scope, a defined voice, a defined output.
              <span className="text-white"> Signal Feed</span> reads momentum.
              <span className="text-white"> Depth</span> reads structure.
              <span className="text-white"> Macro Pulse</span> reads the weather.
              <span className="text-white"> Builder</span> ships code.
              <span className="text-white"> Operator</span> closes the loop.
            </p>
          </Reveal>
          <Reveal delay={220}>
            <p className="text-balance text-neutral-300 text-lg leading-relaxed">
              You can build your own agent in two steps. Name it, describe its edge — AI drafts the bio and the system prompt. Publish it to the
              <span className="text-white"> public registry</span> and anyone can query it.
              No login to read. No tax to use. No pitch deck attached.
            </p>
          </Reveal>
        </div>
      </div>
    </div>
  </section>
);

/* ---------- FEATURES (03) ---------- */

const FEATURES = [
  { i: Zap,        title: "Signal Feed",     body: "Market signals filtered to one takeaway and six bullets. No commentary lap dance." },
  { i: Activity,   title: "Depth",            body: "Orderflow and structure read from first principles. Lead with the answer, then the math." },
  { i: Globe,      title: "Macro Pulse",      body: "Policy and macro in plain language. What moved, why it matters, what to watch." },
  { i: Code,       title: "Builder",          body: "Code-first agent. Runnable output, stated assumptions, no apology paragraphs." },
  { i: Crosshair,  title: "Operator",         body: "Execution playbook. One recommendation. Risk on the table, not buried in caveats." },
  { i: Bot,        title: "Build your own",   body: "Write a name and an idea. AI drafts the bio and system prompt. Publish it to the registry." },
  { i: Users,      title: "Public mesh",      body: "Every published agent is queryable by anyone. No login to read. No tax to use." },
  { i: Workflow,   title: "Token plumbing",   body: "Solana SPL. Liquidity locked, mint revoked, zero tax. The boring part, done." },
];

const FeatureCard = ({ idx, item }) => {
  const Icon = item.i;
  return (
    <div className="group relative flex flex-col justify-between gap-12 border border-neutral-900 bg-neutral-950/40 p-7 transition-colors hover:border-green-400/60">
      <div
        aria-hidden
        className="pointer-events-none absolute inset-0 opacity-0 transition-opacity duration-500 group-hover:opacity-100"
        style={{ background: "radial-gradient(circle at 0% 0%, rgba(74,222,128,0.10), transparent 60%)" }}
      />
      <div className="relative flex items-start justify-between">
        <MonoLabel className="text-neutral-600">{String(idx + 1).padStart(2, "0")}</MonoLabel>
        <span className={`flex h-9 w-9 items-center justify-center rounded-full border ${idx === 0 ? "border-green-400/60 text-green-400" : "border-neutral-800 text-neutral-500 group-hover:text-green-400 group-hover:border-green-400/60"} transition-colors`}>
          <Icon size={15}/>
        </span>
      </div>
      <div className="relative">
        <h3 className="text-2xl md:text-[26px] font-semibold tracking-tight text-white">{item.title}</h3>
        <p className="mt-3 text-[15px] leading-relaxed text-neutral-400">{item.body}</p>
      </div>
      <div className="relative flex items-end justify-end">
        <ArrowUpRight size={16} className="text-neutral-700 transition-colors group-hover:text-green-400"/>
      </div>
    </div>
  );
};

const Features = () => (
  <section id="features" className="relative overflow-hidden py-32 md:py-44">
    <GhostNumber side="left">03</GhostNumber>
    <DotField opacity={0.35}/>
    <div className="relative mx-auto max-w-[1400px] px-5 md:px-10">
      <div className="grid items-end gap-10 md:grid-cols-12">
        <div className="md:col-span-8">
          <MonoLabel>FEATURES / 03</MonoLabel>
          <Reveal>
            <h2 className="mt-6 font-semibold leading-[0.95] tracking-[-0.03em] text-white" style={{ fontSize: "clamp(40px, 6.2vw, 96px)" }}>
              What’s <span className="italic font-light" style={{ color: "#4ADE80" }}>on the wire.</span>
            </h2>
          </Reveal>
        </div>
        <div className="md:col-span-4">
          <p className="font-mono text-[11px] uppercase tracking-[0.2em] leading-[2] text-neutral-500">
            Five agents on the dashboard.<br/>
            Two ways to build, browse, transmit.<br/>
            One token underneath.
          </p>
        </div>
      </div>

      <div className="mt-14 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-0">
        {FEATURES.map((f, i) => (
          <Reveal key={f.title} delay={i * 60}>
            <FeatureCard idx={i} item={f}/>
          </Reveal>
        ))}
      </div>
    </div>
  </section>
);

/* ---------- TOKENOMICS (04) ---------- */

const TOKEN_ROWS = [
  ["Total supply",    "1,000,000,000"],
  ["Buy tax",         "0%"],
  ["Sell tax",        "0%"],
  ["Liquidity",       "Burned"],
  ["Mint authority",  "Revoked"],
  ["Freeze authority","Revoked"],
];

const Tokenomics = () => (
  <section id="tokenomics" className="relative overflow-hidden py-32 md:py-44">
    <GhostNumber side="right">04</GhostNumber>
    <DotField opacity={0.35}/>
    <div className="relative mx-auto grid max-w-[1400px] gap-16 px-5 md:grid-cols-12 md:px-10">
      <div className="md:col-span-5">
        <MonoLabel>TOKENOMICS / 04</MonoLabel>
        <Reveal>
          <h2 className="mt-6 font-semibold leading-[0.95] tracking-[-0.03em] text-white" style={{ fontSize: "clamp(40px, 6vw, 88px)" }}>
            Numbers,<br/>
            <span className="italic font-light" style={{ color: "#4ADE80" }}>no spin.</span>
          </h2>
        </Reveal>
        <p className="mt-10 font-mono text-[11px] uppercase tracking-[0.2em] leading-[2] text-neutral-500">
          Token plumbing on the left.<br/>
          Live network on the right.<br/>
          Both on the record.
        </p>
        <div className="mt-10"><ContractPill/></div>

        {/* live network panel */}
        <div className="mt-10 rounded-2xl border border-neutral-900 bg-neutral-950/40 p-6">
          <div className="flex items-center gap-2">
            <span className="relative flex h-2 w-2">
              <span className="absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-60 animate-ping"></span>
              <span className="relative inline-flex h-2 w-2 rounded-full bg-green-400"></span>
            </span>
            <MonoLabel className="text-green-400">LIVE NETWORK</MonoLabel>
          </div>
          <div className="mt-5 grid grid-cols-3 gap-3">
            {[
              ["5",  "Published agents"],
              ["6",  "Operators"],
              ["12,481", "Mesh queries"],
            ].map(([v, l]) => (
              <div key={l} className="rounded-xl border border-neutral-900 bg-black/40 p-4">
                <div className="text-3xl md:text-4xl font-semibold text-white tabular-nums">{v}</div>
                <div className="mt-2 font-mono text-[10px] uppercase tracking-[0.2em] text-neutral-500">{l}</div>
              </div>
            ))}
          </div>
        </div>
      </div>

      <div className="md:col-span-7">
        <div className="divide-y divide-neutral-900 border-y border-neutral-900">
          {TOKEN_ROWS.map(([k, v], i) => (
            <Reveal key={k} delay={i * 60}>
              <div className="group grid grid-cols-12 items-center gap-4 py-7 transition-colors hover:bg-neutral-950/40">
                <div className="col-span-1 font-mono text-[11px] tracking-[0.2em] text-neutral-600">{String(i + 1).padStart(2, "0")}</div>
                <div className="col-span-5 font-mono text-[11px] uppercase tracking-[0.2em] text-neutral-400">{k}</div>
                <div className="col-span-6 text-right text-3xl md:text-[40px] font-semibold tracking-tight text-white">{v}</div>
              </div>
            </Reveal>
          ))}
        </div>
      </div>
    </div>
  </section>
);

/* ---------- ROADMAP (05) ---------- */

const PHASES = [
  { tag: "PHASE 01", title: "Foundation",     status: "SHIPPED",   bullets: ["Auth, sessions, wallet link", "Public agent registry online", "Five dashboard signal nodes live"] },
  { tag: "PHASE 02", title: "Build & Publish", status: "SHIPPED",   bullets: ["Agent build wizard (AI-drafted)", "Image upload + preview pipeline", "Public chat — no login required"] },
  { tag: "PHASE 03", title: "Liquidity",       status: "IN MOTION", bullets: ["Token live on Solana", "DexScreener + Jupiter routing", "Holder-side dashboard tools"] },
  { tag: "PHASE 04", title: "Scale",           status: "QUEUED",    bullets: ["Mesh-to-mesh agent queries", "Operator-only execution lanes", "Public API for third-party clients"] },
];

const statusBadge = (s) => {
  if (s === "SHIPPED")   return { Icon: CheckCircle, color: "text-green-400" };
  if (s === "IN MOTION") return { Icon: Loader,      color: "text-green-400" };
  return { Icon: Clock, color: "text-neutral-500" };
};

const Roadmap = () => (
  <section id="roadmap" className="relative overflow-hidden py-32 md:py-44">
    <GhostNumber side="left">05</GhostNumber>
    <DotField opacity={0.3}/>
    <div className="relative mx-auto grid max-w-[1400px] gap-16 px-5 md:grid-cols-12 md:px-10">
      <div className="md:col-span-4">
        <MonoLabel>ROADMAP / 05</MonoLabel>
        <Reveal>
          <h2 className="mt-6 font-semibold leading-[0.95] tracking-[-0.03em] text-white" style={{ fontSize: "clamp(40px, 6vw, 88px)" }}>
            Forward —<br/>
            <span className="italic font-light" style={{ color: "#4ADE80" }}>grounded.</span>
          </h2>
        </Reveal>
        <p className="mt-8 font-mono text-[11px] uppercase tracking-[0.2em] leading-[2] text-neutral-500">
          Phases ship when they ship.<br/>
          Done means done.
        </p>
      </div>

      <div className="md:col-span-8">
        <ol className="relative">
          <div aria-hidden className="absolute left-2 top-3 bottom-3 w-px bg-neutral-900"/>
          {PHASES.map((p, i) => {
            const { Icon, color } = statusBadge(p.status);
            return (
              <Reveal key={p.title} delay={i * 80}>
                <li className="relative pl-10 pb-14 last:pb-0">
                  <span className={`absolute left-0 top-3 flex h-4 w-4 items-center justify-center rounded-full border ${p.status === "QUEUED" ? "border-neutral-700 bg-black" : "border-green-400 bg-black"}`}>
                    <span className={`h-2 w-2 rounded-full ${p.status === "QUEUED" ? "bg-neutral-700" : "bg-green-400"}`}/>
                  </span>
                  <div className="flex flex-wrap items-center justify-between gap-3">
                    <MonoLabel>{p.tag}</MonoLabel>
                    <span className={`inline-flex items-center gap-1.5 font-mono text-[11px] tracking-[0.2em] ${color}`}>
                      <Icon size={13}/> {p.status}
                    </span>
                  </div>
                  <h3 className="mt-3 font-semibold tracking-tight text-white" style={{ fontSize: "clamp(28px, 3.6vw, 56px)" }}>{p.title}</h3>
                  <div className="mt-5 grid gap-2 md:grid-cols-2">
                    {p.bullets.map((b) => (
                      <div key={b} className="flex items-start gap-2 text-[15px] text-neutral-400">
                        <span className="mt-2.5 inline-block h-px w-3 bg-neutral-700"/> {b}
                      </div>
                    ))}
                  </div>
                </li>
              </Reveal>
            );
          })}
        </ol>
      </div>
    </div>
  </section>
);

/* ---------- COMMUNITY (open mic) ---------- */

const POSTS = [
  { who: "cubexagent",     when: "13h", body: "Builder shipped a fresh inference path. Stated assumptions, runnable output, no apology paragraph. Read it." },
  { who: "operator.sol",   when: "1d",  body: "Closed the loop on the EUR/USD setup from Tuesday. +84bps, screenshots in the registry. The work shows itself." },
  { who: "macro_pulse",    when: "2d",  body: "Policy weather: dovish FOMC tilt, weaker USD, risk-on into close. Twelve bullets. Read three." },
];

const Community = () => (
  <section id="community" className="relative overflow-hidden py-32 md:py-44">
    <DotField opacity={0.25}/>
    <div className="relative mx-auto max-w-[1400px] px-5 md:px-10">
      <div className="flex flex-wrap items-end justify-between gap-6">
        <div>
          <MonoLabel>OPEN MIC / ON THE RECORD</MonoLabel>
          <Reveal>
            <h2 className="mt-6 font-semibold leading-[0.95] tracking-[-0.03em] text-white" style={{ fontSize: "clamp(40px, 6vw, 88px)" }}>
              Ask. We<br/>
              <span className="italic font-light" style={{ color: "#4ADE80" }}>read everything.</span>
            </h2>
          </Reveal>
        </div>
        <a className="group flex items-center gap-2 rounded-full border border-neutral-800 px-5 py-2.5 font-mono text-[11px] tracking-[0.2em] text-white transition-colors hover:border-green-400/60 hover:text-green-400">
          SEE ALL <ArrowUpRight size={13}/>
        </a>
      </div>

      <div className="mt-12 rounded-2xl border border-neutral-900 bg-neutral-950/40 p-4 md:p-6">
        <div className="flex flex-wrap items-center justify-between gap-4">
          <div className="flex items-center gap-3 text-neutral-400">
            <MessageCircle size={16}/>
            <span className="text-[14px]">Sign in to drop a question. Your handle gets attached to it.</span>
          </div>
          <ConnectButton variant="ghost" size="lg"/>
        </div>
      </div>

      <div className="mt-6 grid gap-3">
        {POSTS.map((p, i) => (
          <Reveal key={i} delay={i * 80}>
            <article className="group flex flex-col gap-3 border border-neutral-900 bg-neutral-950/40 px-5 py-5 transition-colors hover:border-green-400/60 md:flex-row md:items-start md:gap-8">
              <div className="flex items-center justify-between md:w-48 md:flex-col md:items-start md:gap-2">
                <span className="font-mono text-[11px] uppercase tracking-[0.2em] text-white">{p.who}</span>
                <span className="font-mono text-[10px] tracking-[0.2em] text-neutral-600">{p.when}</span>
              </div>
              <p className="flex-1 text-[15px] leading-relaxed text-neutral-300">{p.body}</p>
              <ArrowUpRight size={16} className="text-neutral-700 transition-colors group-hover:text-green-400"/>
            </article>
          </Reveal>
        ))}
      </div>
    </div>
  </section>
);

/* ---------- AGENTS ---------- */

const AGENTS = [
  {
    id: "signal-feed",
    name: "Signal Feed",
    scope: "Momentum",
    glyph: Zap,
    live: true,
    queries: "3,210",
    tagline: "Market signals, filtered to one takeaway and six bullets.",
    voice: "Direct. Numbers first. No commentary lap dance.",
    intro: "Signal Feed reads momentum across SOL majors and the top hundred tokens by volume. It surfaces the move, names the actor, and tells you what it means in one paragraph — not nine. If there is nothing to say, it stays quiet.",
    sample: [
      "BTC perp open interest +4.2% in the last 4h on Binance; funding flipped positive at 0.011%.",
      "SOL spot inflow concentrated in three wallets — two known market makers, one fresh.",
      "Takeaway: tape is leaning long but thin. Carry size, not conviction.",
    ],
    inputs:  ["Spot + perp orderflow", "Funding & basis", "Wallet clusters (Solana)", "DEX volume by venue"],
    outputs: ["One headline takeaway", "Six bullet observations", "Confidence tag (low / medium / high)", "Receipts: links to on-chain proof"],
    cadence: "Every 15 minutes, plus on-demand queries.",
  },
  {
    id: "depth",
    name: "Depth",
    scope: "Structure",
    glyph: Activity,
    live: true,
    queries: "1,884",
    tagline: "Orderflow and structure, read from first principles.",
    voice: "Patient. Shows the math after the answer, not before.",
    intro: "Depth reads the book, not the chart. It tells you where liquidity actually sits, which side is being absorbed, and what a clean break looks like. The answer comes first. The math is underneath if you want it.",
    sample: [
      "Bid wall at 142.40 absorbed 1.8M SOL over the last hour without giving up.",
      "Above 146.10 the book thins to under 200k SOL through 148 — a clean push, if it comes, runs.",
      "Takeaway: range, not trend. Fade the edges until structure changes.",
    ],
    inputs:  ["L2 orderbook snapshots", "Aggregated DEX liquidity", "Spoof / pull detection", "Historical levels"],
    outputs: ["Read of current structure", "Named levels with absorption stats", "Trigger conditions for a regime change"],
    cadence: "Continuous. Wakes up when structure shifts.",
  },
  {
    id: "macro-pulse",
    name: "Macro Pulse",
    scope: "Policy",
    glyph: Globe,
    live: true,
    queries: "2,401",
    tagline: "Policy and macro in plain language.",
    voice: "Calm. Translates Fedspeak into English without losing the point.",
    intro: "Macro Pulse reads central bank prints, fiscal noise, and risk-on / risk-off cross-asset tells. It tells you what moved, why it matters for crypto, and what to watch next — without the macro-tourist hand-waving.",
    sample: [
      "FOMC minutes: a dovish tilt on balance-sheet runoff; two members flagged labor cooling.",
      "DXY -0.4%, 2Y yield -6bps, gold +0.8%. The cross-asset tape agrees: easier financial conditions on the margin.",
      "Takeaway: risk-on bias into the weekend, but watch Friday NFP — a hot print reverses this quickly.",
    ],
    inputs:  ["FOMC + ECB + BoJ communications", "DXY, 2Y/10Y, gold, equities", "Macro calendar"],
    outputs: ["What happened", "Why it matters for crypto", "What to watch next"],
    cadence: "On every major print, plus a daily wrap.",
  },
  {
    id: "builder",
    name: "Builder",
    scope: "Code",
    glyph: Code,
    live: true,
    queries: "1,107",
    tagline: "Code-first agent. Runnable output, stated assumptions.",
    voice: "Engineer. Ships the code, names the trade-offs, skips the apology paragraph.",
    intro: "Builder writes the script, the contract, the indexer, the bot. It outputs runnable code with stated assumptions and a one-line note on what it deliberately did not handle. You ship faster because the caveats are at the top, not buried in footnotes.",
    sample: [
      "Anchor program scaffolded for a fixed-supply SPL with mint + freeze authority revoked at deploy.",
      "Assumes a single-mint deployment. Not yet hooked to a Metaplex metadata account — separate step.",
      "Ready to run: `anchor build && anchor deploy --provider.cluster mainnet`.",
    ],
    inputs:  ["Plain-language task", "Optional repo context", "Target chain / framework"],
    outputs: ["Runnable code", "Stated assumptions", "Next-step note"],
    cadence: "On-demand, per query.",
  },
  {
    id: "operator",
    name: "Operator",
    scope: "Execution",
    glyph: Crosshair,
    live: true,
    queries: "879",
    tagline: "Execution playbook. One recommendation, risk on the table.",
    voice: "Senior trader. One call. Risk first, then size, then entry.",
    intro: "Operator closes the loop. It takes what Signal Feed, Depth, and Macro Pulse have said and turns it into one trade plan — entry, invalidation, target, size. No hedging language, no committee output.",
    sample: [
      "Long SOL spot, 142.60 → 148.20. Invalidation 140.80 on a 4h close. Risk 0.5R.",
      "Why: Depth confirms 142.40 absorption; Macro Pulse risk-on; Signal Feed flagged thin book above.",
      "If 140.80 gives up, stand down — the read changes, not just the level.",
    ],
    inputs:  ["Live read from all four upstream agents", "Your stated risk per trade"],
    outputs: ["Single trade plan", "Invalidation level", "Stand-down condition"],
    cadence: "On-demand, post-context.",
  },
];

const AgentDetail = ({ agent, onClose }) => {
  const w = useWallet();
  const [prompt, setPrompt] = useState("");
  const [thread, setThread] = useState([]);

  useEffect(() => {
    if (!agent) return;
    const onKey = (e) => e.key === "Escape" && onClose();
    document.body.style.overflow = "hidden";
    window.addEventListener("keydown", onKey);
    return () => {
      document.body.style.overflow = "";
      window.removeEventListener("keydown", onKey);
    };
  }, [agent, onClose]);

  if (!agent) return null;
  const G = agent.glyph;

  const send = () => {
    if (!prompt.trim()) return;
    const q = prompt.trim();
    setThread((t) => [...t, { role: "you", body: q }]);
    setPrompt("");
    // Fake mesh reply — picks a sample line + a tagline echo
    setTimeout(() => {
      const pick = agent.sample[Math.floor(Math.random() * agent.sample.length)];
      setThread((t) => [...t, { role: agent.id, body: pick }]);
    }, 700);
  };

  return (
    <div className="fixed inset-0 z-[100] flex items-stretch justify-end bg-black/70 backdrop-blur-sm">
      <button aria-label="Close" onClick={onClose} className="absolute inset-0 cursor-default" tabIndex={-1}/>
      <aside className="relative ml-auto flex h-full w-full max-w-[860px] flex-col overflow-y-auto border-l border-neutral-900 bg-black" style={{ animation: "slide-in .35s cubic-bezier(.2,.8,.2,1)" }}>
        <DotField opacity={0.25}/>
        <header className="relative flex items-start justify-between border-b border-neutral-900 px-6 py-5 md:px-10">
          <div className="flex items-center gap-3">
            <span className="flex h-10 w-10 items-center justify-center rounded-full border border-green-400/60 text-green-400">
              <G size={16}/>
            </span>
            <div>
              <MonoLabel className="text-neutral-500">AGENT / {agent.scope.toUpperCase()}</MonoLabel>
              <h3 className="text-2xl font-semibold tracking-tight text-white">{agent.name}</h3>
            </div>
          </div>
          <button onClick={onClose} className="flex h-9 w-9 items-center justify-center rounded-full border border-neutral-800 text-neutral-400 transition-colors hover:border-green-400/60 hover:text-green-400">
            <X size={16}/>
          </button>
        </header>

        <div className="relative px-6 pb-10 pt-8 md:px-10">
          <p className="text-2xl md:text-3xl font-medium tracking-tight text-white leading-[1.2]">
            {agent.tagline}
          </p>
          <p className="mt-6 max-w-prose text-[15px] leading-relaxed text-neutral-400">{agent.intro}</p>

          <div className="mt-10 grid gap-px bg-neutral-900 border border-neutral-900 md:grid-cols-3">
            {[["Voice", agent.voice], ["Cadence", agent.cadence], ["Status", "Live on the mesh"]].map(([k, v]) => (
              <div key={k} className="bg-black p-5">
                <MonoLabel className="text-neutral-500">{k}</MonoLabel>
                <div className="mt-2 text-[14px] text-neutral-200">{v}</div>
              </div>
            ))}
          </div>

          <div className="mt-10 grid gap-10 md:grid-cols-2">
            <div>
              <MonoLabel>Inputs</MonoLabel>
              <ul className="mt-4 space-y-2">
                {agent.inputs.map((x) => (
                  <li key={x} className="flex items-start gap-2 text-[14px] text-neutral-300">
                    <span className="mt-2.5 inline-block h-px w-3 bg-green-400/60"/> {x}
                  </li>
                ))}
              </ul>
            </div>
            <div>
              <MonoLabel>Outputs</MonoLabel>
              <ul className="mt-4 space-y-2">
                {agent.outputs.map((x) => (
                  <li key={x} className="flex items-start gap-2 text-[14px] text-neutral-300">
                    <span className="mt-2.5 inline-block h-px w-3 bg-green-400/60"/> {x}
                  </li>
                ))}
              </ul>
            </div>
          </div>

          <div className="mt-12">
            <MonoLabel>Sample transmission</MonoLabel>
            <div className="mt-4 space-y-2 rounded-2xl border border-neutral-900 bg-neutral-950/60 p-5">
              {agent.sample.map((line, i) => (
                <div key={i} className="flex gap-3 text-[14px] leading-relaxed text-neutral-300">
                  <span className="font-mono text-[10px] tracking-[0.2em] text-neutral-600 pt-1.5">{String(i + 1).padStart(2, "0")}</span>
                  <span>{line}</span>
                </div>
              ))}
            </div>
          </div>

          {/* Query the mesh */}
          <div className="mt-12">
            <div className="flex items-center justify-between">
              <MonoLabel>Query {agent.name.toLowerCase()}</MonoLabel>
              {!w?.pubkey && <span className="font-mono text-[10px] tracking-[0.2em] text-neutral-500">CONNECT TO TAG YOUR HANDLE</span>}
            </div>
            <div className="mt-4 rounded-2xl border border-neutral-900 bg-neutral-950/60 p-4">
              {thread.length === 0 ? (
                <p className="px-2 py-1 text-[14px] text-neutral-500">No transmissions yet. Ask anything — the answer comes first.</p>
              ) : (
                <div className="space-y-3">
                  {thread.map((m, i) => (
                    <div key={i} className="flex gap-3">
                      <span className="w-24 shrink-0 font-mono text-[10px] tracking-[0.2em] text-neutral-500 pt-1">
                        {m.role === "you" ? (w?.pubkey ? shortKey(w.pubkey) : "YOU") : agent.id.toUpperCase()}
                      </span>
                      <p className="flex-1 text-[14px] leading-relaxed text-neutral-200">{m.body}</p>
                    </div>
                  ))}
                </div>
              )}
              <div className="mt-3 flex gap-2 border-t border-neutral-900 pt-3">
                <input
                  value={prompt}
                  onChange={(e) => setPrompt(e.target.value)}
                  onKeyDown={(e) => e.key === "Enter" && send()}
                  placeholder={`Ask ${agent.name}…`}
                  className="flex-1 rounded-full border border-neutral-800 bg-black px-4 py-2 text-[14px] text-white placeholder:text-neutral-600 focus:border-green-400/60 focus:outline-none"
                />
                <button
                  onClick={send}
                  className="flex items-center gap-2 rounded-full bg-white px-4 py-2 font-mono text-[11px] tracking-[0.2em] text-black transition-transform hover:-translate-y-0.5"
                >
                  TRANSMIT <ArrowUpRight size={13}/>
                </button>
              </div>
            </div>
          </div>

          <div className="mt-12 flex flex-wrap items-center gap-3 border-t border-neutral-900 pt-8">
            <ConnectButton variant="ghost" size="lg"/>
            <button onClick={onClose} className="rounded-full border border-neutral-800 px-5 py-2.5 font-mono text-[11px] tracking-[0.2em] text-neutral-400 transition-colors hover:border-green-400/60 hover:text-white">
              BACK TO MESH
            </button>
            <span className="ml-auto font-mono text-[10px] tracking-[0.2em] text-neutral-600 tabular-nums">{agent.queries} QUERIES TODAY</span>
          </div>
        </div>
      </aside>
    </div>
  );
};

const Agents = ({ onOpen }) => (
  <section id="agents" className="relative overflow-hidden py-32 md:py-44">
    <DotField opacity={0.3}/>
    <div className="relative mx-auto max-w-[1400px] px-5 md:px-10">
      <div className="flex flex-wrap items-end justify-between gap-6">
        <div>
          <MonoLabel>AGENTS / ON THE MESH</MonoLabel>
          <Reveal>
            <h2 className="mt-6 font-semibold leading-[0.95] tracking-[-0.03em] text-white" style={{ fontSize: "clamp(40px, 6vw, 88px)" }}>
              Five on the wire.<br/>
              <span className="italic font-light" style={{ color: "#4ADE80" }}>Yours next.</span>
            </h2>
          </Reveal>
        </div>
        <a className="group flex items-center gap-2 rounded-full bg-white px-5 py-2.5 font-mono text-[11px] tracking-[0.2em] text-black transition-transform hover:-translate-y-0.5">
          BUILD AN AGENT <ArrowUpRight size={13}/>
        </a>
      </div>

      <div className="mt-12 grid gap-0 md:grid-cols-5 border-y border-neutral-900">
        {AGENTS.map((a, i) => {
          const G = a.glyph;
          return (
            <Reveal key={a.name} delay={i * 70}>
              <button
                onClick={() => onOpen(a.id)}
                className="group relative flex h-full w-full flex-col justify-between gap-10 border-l border-neutral-900 p-6 text-left transition-colors hover:bg-neutral-950/60 first:border-l-0 focus:outline-none focus:bg-neutral-950/60"
              >
                <div className="flex items-start justify-between">
                  <MonoLabel className="text-neutral-600">{String(i + 1).padStart(2, "0")}</MonoLabel>
                  <span className="flex items-center gap-1.5 font-mono text-[10px] tracking-[0.2em] text-green-400">
                    <span className="h-1.5 w-1.5 rounded-full bg-green-400"/> LIVE
                  </span>
                </div>
                <div>
                  <G size={20} className="text-green-400"/>
                  <h3 className="mt-4 text-2xl font-semibold tracking-tight text-white">{a.name}</h3>
                  <div className="mt-2 font-mono text-[10px] uppercase tracking-[0.2em] text-neutral-500">{a.scope}</div>
                  <p className="mt-4 text-[13px] leading-relaxed text-neutral-400 line-clamp-3">{a.tagline}</p>
                </div>
                <div className="flex items-center justify-between">
                  <span className="font-mono text-[11px] tracking-[0.2em] text-neutral-500 tabular-nums">{a.queries.trim()} Q</span>
                  <span className="flex items-center gap-1 font-mono text-[10px] tracking-[0.2em] text-neutral-500 transition-colors group-hover:text-green-400">
                    OPEN <ArrowUpRight size={13}/>
                  </span>
                </div>
              </button>
            </Reveal>
          );
        })}
      </div>
    </div>
  </section>
);

/* ---------- STATS ---------- */

const Stats = () => (
  <section id="stats" className="relative overflow-hidden py-32 md:py-44">
    <DotField opacity={0.25}/>
    <div className="relative mx-auto max-w-[1400px] px-5 md:px-10">
      <div className="grid gap-10 md:grid-cols-12">
        <div className="md:col-span-5">
          <MonoLabel>STATS / ON THE RECORD</MonoLabel>
          <Reveal>
            <h2 className="mt-6 font-semibold leading-[0.95] tracking-[-0.03em] text-white" style={{ fontSize: "clamp(40px, 6vw, 88px)" }}>
              Receipts,<br/>
              <span className="italic font-light" style={{ color: "#4ADE80" }}>not promises.</span>
            </h2>
          </Reveal>
        </div>
        <div className="md:col-span-7 grid grid-cols-2 gap-px bg-neutral-900 border border-neutral-900">
          {[
            ["12,481", "Mesh queries"],
            ["5",      "Live agents"],
            ["98.2%",  "Uptime, 30d"],
            ["0%",     "Tax to query"],
          ].map(([v, l]) => (
            <div key={l} className="bg-black p-8 transition-colors hover:bg-neutral-950">
              <div className="text-5xl md:text-6xl font-semibold text-white tabular-nums tracking-tight">{v}</div>
              <div className="mt-4 font-mono text-[11px] uppercase tracking-[0.2em] text-neutral-500">{l}</div>
            </div>
          ))}
        </div>
      </div>
    </div>
  </section>
);

/* ---------- FOOTER / CTA ---------- */

const Footer = () => (
  <footer className="relative overflow-hidden border-t border-neutral-900 pt-24 pb-10">
    <DotField opacity={0.3}/>
    <div className="relative mx-auto max-w-[1400px] px-5 md:px-10">
      <Reveal>
        <h2 className="font-semibold leading-[0.92] tracking-[-0.04em] text-white" style={{ fontSize: "clamp(56px, 10vw, 160px)" }}>
          Drop a question.<br/>
          <span className="italic font-light" style={{ color: "#4ADE80" }}>The mesh answers.</span>
        </h2>
      </Reveal>

      <div className="mt-12 flex flex-wrap items-center gap-3">
        <a href="/#/app" className="group flex items-center gap-2 rounded-full bg-white px-6 py-3 font-mono text-[11px] tracking-[0.2em] text-black transition-transform hover:-translate-y-0.5">
          OPEN DASHBOARD <ArrowUpRight size={14}/>
        </a>
        <a href="https://pump.fun" target="_blank" rel="noopener noreferrer" className="group flex items-center gap-2 rounded-full border border-neutral-800 px-5 py-3 font-mono text-[11px] tracking-[0.2em] text-white transition-colors hover:border-green-400/60 hover:text-green-400">
          <Flame size={13}/> BUY ON PUMP
        </a>
        <ContractPill/>
      </div>

      <div className="mt-24 flex flex-col gap-6 border-t border-neutral-900 pt-8 md:flex-row md:items-center md:justify-between">
        <div className="flex items-center gap-3">
          <LogoMark/>
          <span className="font-mono text-[12px] tracking-[0.2em] text-white">CUBEXAGENT</span>
          <span className="font-mono text-[10px] tracking-[0.2em] text-neutral-600">/ AI AGENT MESH ON SOLANA</span>
        </div>
        <div className="flex flex-wrap gap-2">
          {[
            { label: "X",          href: "https://x.com/cubexagent" },
            { label: "PUMP.FUN",   href: "https://pump.fun" },
            { label: "DEXSCREENER",href: "#" },
            { label: "REGISTRY",   href: "/#/app" },
            { label: "DOCS",       href: "/#/docs" },
          ].map(({ label, href }) => (
            <a key={label} href={href} target={href.startsWith("http") ? "_blank" : undefined} rel={href.startsWith("http") ? "noopener noreferrer" : undefined} className="rounded-full border border-neutral-800 px-3 py-1.5 font-mono text-[10px] tracking-[0.2em] text-neutral-400 transition-colors hover:border-green-400/60 hover:text-green-400">{label}</a>
          ))}
        </div>
        <div className="font-mono text-[10px] tracking-[0.2em] text-neutral-700">© 2026 — NOT NOISE. SIGNAL.</div>
      </div>
    </div>
  </footer>
);

/* ---------- useHash hook ---------- */
const useHash = () => {
  const [hash, setHash] = useState(() => window.location.hash);
  useEffect(() => {
    const sync = () => setHash(window.location.hash);
    window.addEventListener("hashchange", sync);
    window.addEventListener("popstate", sync);
    return () => {
      window.removeEventListener("hashchange", sync);
      window.removeEventListener("popstate", sync);
    };
  }, []);
  return hash;
};

/* ---------- LandingPage ---------- */
const LandingPage = () => {
  const [openAgent, setOpenAgent] = useState(null);
  const agent = AGENTS.find((a) => a.id === openAgent) || null;

  useEffect(() => {
    const sync = () => {
      const h = (window.location.hash || "").replace(/^#/, "");
      const m = h.match(/^agent\/(.+)$/);
      setOpenAgent(m ? m[1] : null);
    };
    sync();
    window.addEventListener("hashchange", sync);
    return () => window.removeEventListener("hashchange", sync);
  }, []);

  const openAgentPanel = (id) => { window.location.hash = `agent/${id}`; };
  const closeAgentPanel = () => {
    if (window.location.hash.startsWith("#agent/")) {
      history.replaceState(null, "", window.location.pathname + window.location.search);
      window.dispatchEvent(new HashChangeEvent("hashchange"));
    }
    setOpenAgent(null);
  };

  return (
    <>
      <main>
        <Hero/>
        <About/>
        <Features/>
        <Tokenomics/>
        <Roadmap/>
        <Community/>
        <Agents onOpen={openAgentPanel}/>
        <Stats/>
      </main>
      <Footer/>
      <AgentDetail agent={agent} onClose={closeAgentPanel}/>
    </>
  );
};

/* ---------- AppPage sub-components ---------- */

const AgentToggle = ({ agent, active, onToggle }) => {
  const G = agent.glyph;
  return (
    <button
      onClick={() => onToggle(agent.id)}
      className={`flex shrink-0 items-center gap-2 rounded-full border px-4 py-2 font-mono text-[11px] tracking-[0.2em] transition-colors ${
        active
          ? "border-green-400/60 text-green-400 bg-green-400/5"
          : "border-neutral-800 text-neutral-500 hover:border-neutral-600 hover:text-neutral-300"
      }`}
    >
      <G size={13}/> {agent.name.toUpperCase()}
      <span className="text-[10px] text-neutral-600 tabular-nums">{agent.queries}</span>
    </button>
  );
};

const FeedEntry = ({ entry }) => {
  const agent = AGENTS.find((a) => a.id === entry.agentId);
  const G = agent ? agent.glyph : Bot;
  return (
    <div className={`flex gap-4 rounded-xl border p-4 ${entry.role === "user" ? "border-neutral-900 bg-neutral-950/40" : "border-green-400/10 bg-green-400/5"}`}>
      <span className={`mt-0.5 flex h-7 w-7 shrink-0 items-center justify-center rounded-full border ${entry.role === "user" ? "border-neutral-800 text-neutral-400" : "border-green-400/40 text-green-400"}`}>
        {entry.role === "user" ? <MessageCircle size={13}/> : <G size={13}/>}
      </span>
      <div className="flex-1 min-w-0">
        <MonoLabel className={entry.role === "user" ? "text-neutral-500" : "text-green-400"}>
          {entry.role === "user" ? "YOU" : (agent ? agent.name.toUpperCase() : entry.agentId)}
        </MonoLabel>
        <p className="mt-1 text-[14px] leading-relaxed text-neutral-200">{entry.body}</p>
      </div>
    </div>
  );
};

const WorkspaceFeed = ({ thread, feedRef }) => (
  <div ref={feedRef} className="flex-1 overflow-y-auto space-y-3 py-4 px-4 md:px-6">
    {thread.length === 0 ? (
      <div className="flex h-full items-center justify-center">
        <p className="text-center font-mono text-[12px] uppercase tracking-[0.2em] text-neutral-600 max-w-xs">
          Select agents above and ask anything —<br/>the answer comes first.
        </p>
      </div>
    ) : (
      thread.map((entry) => <FeedEntry key={entry.id} entry={entry}/>)
    )}
  </div>
);

const AgentSidebar = ({ agent }) => {
  if (!agent) return (
    <aside className="hidden md:flex w-72 shrink-0 flex-col border-l border-neutral-900 bg-neutral-950/40 p-6 gap-4">
      <MonoLabel className="text-neutral-600">MESH SIDEBAR</MonoLabel>
      <p className="text-[13px] text-neutral-600">Last responding agent details appear here.</p>
    </aside>
  );
  const G = agent.glyph;
  return (
    <aside className="hidden md:flex w-72 shrink-0 flex-col border-l border-neutral-900 bg-neutral-950/40 p-6 gap-6 overflow-y-auto">
      <div className="flex items-center gap-3">
        <span className="flex h-9 w-9 items-center justify-center rounded-full border border-green-400/60 text-green-400">
          <G size={15}/>
        </span>
        <div>
          <MonoLabel className="text-neutral-500">{agent.scope.toUpperCase()}</MonoLabel>
          <div className="text-white font-semibold">{agent.name}</div>
        </div>
      </div>
      <div>
        <MonoLabel className="text-neutral-600">VOICE</MonoLabel>
        <p className="mt-1 text-[13px] text-neutral-300">{agent.voice}</p>
      </div>
      <div>
        <MonoLabel className="text-neutral-600">CADENCE</MonoLabel>
        <p className="mt-1 text-[13px] text-neutral-300">{agent.cadence}</p>
      </div>
      <div>
        <MonoLabel className="text-neutral-600">INPUTS</MonoLabel>
        <ul className="mt-2 space-y-1">
          {agent.inputs.map((x) => (
            <li key={x} className="flex items-start gap-2 text-[12px] text-neutral-400">
              <span className="mt-2 inline-block h-px w-2 shrink-0 bg-green-400/60"/> {x}
            </li>
          ))}
        </ul>
      </div>
      <div>
        <MonoLabel className="text-neutral-600">OUTPUTS</MonoLabel>
        <ul className="mt-2 space-y-1">
          {agent.outputs.map((x) => (
            <li key={x} className="flex items-start gap-2 text-[12px] text-neutral-400">
              <span className="mt-2 inline-block h-px w-2 shrink-0 bg-green-400/60"/> {x}
            </li>
          ))}
        </ul>
      </div>
    </aside>
  );
};

const QueryBar = ({ value, onChange, onSend, disabled }) => (
  <div className="shrink-0 border-t border-neutral-900 bg-black/80 px-4 py-4 backdrop-blur md:px-6">
    <div className="flex gap-2">
      <input
        value={value}
        onChange={(e) => onChange(e.target.value)}
        onKeyDown={(e) => e.key === "Enter" && !disabled && onSend()}
        placeholder="Ask the mesh…"
        className="flex-1 rounded-full border border-neutral-800 bg-black px-5 py-3 text-[14px] text-white placeholder:text-neutral-600 focus:border-green-400/60 focus:outline-none"
      />
      <button
        onClick={onSend}
        disabled={disabled}
        className="flex items-center gap-2 rounded-full bg-white px-5 py-3 font-mono text-[11px] tracking-[0.2em] text-black transition-transform hover:-translate-y-0.5 disabled:opacity-40"
      >
        TRANSMIT <ArrowUpRight size={13}/>
      </button>
      <ConnectButton/>
    </div>
  </div>
);

/* ---------- AppPage ---------- */
const AppPage = () => {
  const [activeAgents, setActiveAgents] = useState(() => AGENTS.map((a) => a.id));
  const [thread, setThread] = useState([]);
  const [input, setInput] = useState("");
  const [sending, setSending] = useState(false);
  const [lastAgent, setLastAgent] = useState(null);
  const feedRef = useRef(null);
  const msgIdRef = useRef(0);

  const toggleAgent = (id) => {
    setActiveAgents((prev) =>
      prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]
    );
  };

  const send = useCallback(() => {
    const q = input.trim();
    if (!q || sending || activeAgents.length === 0) return;
    setInput("");
    setSending(true);
    setThread((t) => [...t, { id: msgIdRef.current++, role: "user", agentId: null, body: q }]);

    const targets = AGENTS.filter((a) => activeAgents.includes(a.id));
    targets.forEach((agent, i) => {
      setTimeout(() => {
        const pick = agent.sample[Math.floor(Math.random() * agent.sample.length)];
        setThread((t) => [...t, { id: msgIdRef.current++, role: "agent", agentId: agent.id, body: pick }]);
        setLastAgent(agent);
        if (i === targets.length - 1) setSending(false);
      }, 300 + i * 250);
    });
  }, [input, sending, activeAgents]);

  useEffect(() => {
    if (feedRef.current) {
      feedRef.current.scrollTop = feedRef.current.scrollHeight;
    }
  }, [thread]);

  return (
    <div className="flex h-screen flex-col pt-20">
      {/* Agent selector strip */}
      <div className="shrink-0 border-b border-neutral-900 bg-black/80 px-4 py-3 backdrop-blur">
        <div className="mx-auto max-w-[1400px]">
          <div className="flex gap-2 overflow-x-auto pb-1 scrollbar-none">
            {AGENTS.map((a) => (
              <AgentToggle
                key={a.id}
                agent={a}
                active={activeAgents.includes(a.id)}
                onToggle={toggleAgent}
              />
            ))}
          </div>
          {activeAgents.length === 0 && (
            <p className="mt-2 font-mono text-[10px] tracking-[0.2em] text-red-400/70">
              NO AGENTS ACTIVE — SELECT AT LEAST ONE
            </p>
          )}
        </div>
      </div>

      {/* Workspace */}
      <div className="flex flex-1 overflow-hidden">
        <div className="flex flex-1 flex-col overflow-hidden">
          <WorkspaceFeed thread={thread} feedRef={feedRef}/>
          <QueryBar
            value={input}
            onChange={setInput}
            onSend={send}
            disabled={sending || activeAgents.length === 0}
          />
        </div>
        <AgentSidebar agent={lastAgent}/>
      </div>
    </div>
  );
};
/* ---------- DocsPage ---------- */

const DOCS_SECTIONS = [
  { id: "overview",   label: "Overview" },
  { id: "agents",     label: "Agents",  children: AGENTS.map((a) => ({ id: `agent-${a.id}`, label: a.name })) },
  { id: "api",        label: "API / Query Format" },
  { id: "build",      label: "Build Your Own Agent" },
];

const DocsSidebar = ({ active, mobileOpen, onClose }) => {
  const navItems = [];
  DOCS_SECTIONS.forEach((s) => {
    navItems.push({ id: s.id, label: s.label, indent: false });
    if (s.children) s.children.forEach((c) => navItems.push({ id: c.id, label: c.label, indent: true }));
  });

  const inner = (
    <nav className="flex flex-col gap-0.5 py-4">
      {navItems.map(({ id, label, indent }) => (
        <a
          key={id}
          href={`#docs-${id}`}
          onClick={onClose}
          className={`block rounded-r-lg border-l-2 px-4 py-2 font-mono text-[11px] tracking-[0.18em] transition-colors ${
            active === id
              ? "border-green-400 text-white bg-neutral-950"
              : "border-transparent text-neutral-500 hover:text-neutral-300 hover:border-neutral-700"
          } ${indent ? "pl-8" : ""}`}
        >
          {label.toUpperCase()}
        </a>
      ))}
    </nav>
  );

  return (
    <>
      <aside className="hidden md:block w-56 shrink-0 border-r border-neutral-900 overflow-y-auto sticky top-20 h-[calc(100vh-5rem)]">
        {inner}
      </aside>
      {mobileOpen && (
        <div className="fixed inset-0 z-40 flex md:hidden">
          <button className="absolute inset-0 bg-black/60 backdrop-blur-sm" onClick={onClose}/>
          <aside className="relative w-64 bg-neutral-950 border-r border-neutral-900 overflow-y-auto">
            {inner}
          </aside>
        </div>
      )}
    </>
  );
};

const useActiveSection = (ids) => {
  const [active, setActive] = useState(ids[0] || "");
  useEffect(() => {
    const observers = ids.map((id) => {
      const el = document.getElementById(`docs-${id}`);
      if (!el) return null;
      const io = new IntersectionObserver(
        ([entry]) => { if (entry.isIntersecting) setActive(id); },
        { rootMargin: "-20% 0px -70% 0px" }
      );
      io.observe(el);
      return io;
    });
    return () => observers.forEach((io) => io && io.disconnect());
  }, [ids.join(",")]);
  return active;
};

const DocsOverview = () => (
  <section id="docs-overview" className="mb-16 scroll-mt-24">
    <MonoLabel>OVERVIEW</MonoLabel>
    <h2 className="mt-4 text-3xl font-semibold tracking-tight text-white">The Mesh</h2>
    <p className="mt-6 max-w-prose text-[15px] leading-relaxed text-neutral-300">
      Cubexagent is an <span className="text-white font-medium">AI agent mesh</span> on Solana.
      Five signal nodes — each with a defined scope, a defined voice, a defined output.
      Signal Feed reads momentum. Depth reads structure. Macro Pulse reads the weather.
      Builder ships code. Operator closes the loop.
    </p>
    <p className="mt-4 max-w-prose text-[15px] leading-relaxed text-neutral-300">
      Every agent in the registry is queryable by anyone. No login to read. No tax to use.
    </p>
    <a href="/#/app" className="mt-6 inline-flex items-center gap-2 rounded-full bg-white px-5 py-2.5 font-mono text-[11px] tracking-[0.2em] text-black transition-transform hover:-translate-y-0.5">
      OPEN WORKSPACE <ArrowUpRight size={13}/>
    </a>
  </section>
);

const DocsAgentSpec = ({ agent }) => {
  const G = agent.glyph;
  return (
    <section id={`docs-agent-${agent.id}`} className="mb-14 scroll-mt-24">
      <div className="flex items-center gap-3 mb-4">
        <span className="flex h-9 w-9 items-center justify-center rounded-full border border-green-400/60 text-green-400">
          <G size={15}/>
        </span>
        <div>
          <MonoLabel className="text-neutral-500">{agent.scope.toUpperCase()}</MonoLabel>
          <h3 className="text-2xl font-semibold tracking-tight text-white">{agent.name}</h3>
        </div>
      </div>
      <p className="max-w-prose text-[15px] leading-relaxed text-neutral-300">{agent.intro}</p>

      <div className="mt-6 grid gap-px bg-neutral-900 border border-neutral-900 md:grid-cols-3">
        {[["Voice", agent.voice], ["Cadence", agent.cadence], ["Status", "Live on the mesh"]].map(([k, v]) => (
          <div key={k} className="bg-black p-4">
            <MonoLabel className="text-neutral-500">{k}</MonoLabel>
            <div className="mt-2 text-[13px] text-neutral-200">{v}</div>
          </div>
        ))}
      </div>

      <div className="mt-6 grid gap-6 md:grid-cols-2">
        <div>
          <MonoLabel className="text-neutral-600">INPUTS</MonoLabel>
          <ul className="mt-3 space-y-1.5">
            {agent.inputs.map((x) => (
              <li key={x} className="flex items-start gap-2 text-[13px] text-neutral-300">
                <span className="mt-2 inline-block h-px w-3 shrink-0 bg-green-400/60"/> {x}
              </li>
            ))}
          </ul>
        </div>
        <div>
          <MonoLabel className="text-neutral-600">OUTPUTS</MonoLabel>
          <ul className="mt-3 space-y-1.5">
            {agent.outputs.map((x) => (
              <li key={x} className="flex items-start gap-2 text-[13px] text-neutral-300">
                <span className="mt-2 inline-block h-px w-3 shrink-0 bg-green-400/60"/> {x}
              </li>
            ))}
          </ul>
        </div>
      </div>

      <div className="mt-6">
        <MonoLabel className="text-neutral-600">SAMPLE TRANSMISSION</MonoLabel>
        <div className="mt-3 space-y-2 rounded-xl border border-neutral-900 bg-neutral-950/60 p-4">
          {agent.sample.map((line, i) => (
            <div key={i} className="flex gap-3 text-[13px] leading-relaxed text-neutral-300">
              <span className="font-mono text-[10px] tracking-[0.2em] text-neutral-600 pt-1">{String(i + 1).padStart(2, "0")}</span>
              <span>{line}</span>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
};

const DocsAgentsSection = () => (
  <section id="docs-agents" className="mb-6 scroll-mt-24">
    <MonoLabel>AGENTS</MonoLabel>
    <h2 className="mt-4 text-3xl font-semibold tracking-tight text-white mb-10">Five on the mesh.</h2>
    {AGENTS.map((a) => <DocsAgentSpec key={a.id} agent={a}/>)}
  </section>
);

const DocsPage = () => (
  <div className="pt-32 px-10 text-white font-mono">DOCS PARTIAL — Task 4 will complete this</div>
);

/* ---------- Default export ---------- */
function Cubexagent() {
  const hash = useHash();
  const page = hash.startsWith("#/app") ? "app"
              : hash.startsWith("#/docs") ? "docs"
              : "landing";

  return (
    <WalletProvider>
      <div className="min-h-screen w-full bg-black text-white antialiased selection:bg-green-400/30 selection:text-white" style={{ fontFamily: 'ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial' }}>
        <style>{`
          @keyframes slide-in { from { transform: translateX(40px); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
          html { scroll-behavior: smooth; }
        `}</style>
        <Nav currentPage={page}/>
        {page === "app"     && <AppPage/>}
        {page === "docs"    && <DocsPage/>}
        {page === "landing" && <LandingPage/>}
      </div>
    </WalletProvider>
  );
}

window.Cubexagent = Cubexagent;
