/* InterNull — landing page v11.4 (v2, live-source cut).

   Stops importing copy from a fictional positioning layer. Anchors the page
   in what the actual project says about itself on internull.xyz and in
   theblackbox.network/llms-full.txt.

   What stays from v11: editorial structure, plate captions, folios, voice.
   What gets dropped: WhyNow, ThreatModel, the Audit/Vault section, the
   PullQuote — all of which were Jamshed's editorial layer rather than
   protocol claims. The live project doesn't market user-initiated audit
   or selective disclosure; it markets cross-chain privacy with an
   MCP-first interface for AI agents.

   What gets added: an Agents § using the project's actual MCP install
   instructions and tool surface.
*/

const { useState, useEffect, useRef } = React;

/* ─── InlineSVG — fetch an .svg and inject it inline so it inherits
   currentColor (theme-aware) and scales crisply at any size. ─── */
function InlineSVG({ src, label }) {
  const ref = useRef(null);
  const [markup, setMarkup] = useState("");
  useEffect(() => {
    let alive = true;
    fetch(src).then(r => r.text()).then(t => { if (alive) setMarkup(t); }).catch(() => {});
    return () => { alive = false; };
  }, [src]);
  return (
    <div
      ref={ref}
      className="inline-svg"
      role="img"
      aria-label={label}
      dangerouslySetInnerHTML={{ __html: markup }}
    />
  );
}

/* ─── Lockup — the ORIGINAL chromed trefoil knot + INTERNULL wordmark ─── */
function Logo({ size = 40, wordmark = true }) {
  return (
    <span className="logo" aria-label="InterNull">
      <img className="logo__mark" src={window.__A.logoSmall} alt="" width={size} height={size}/>
      {wordmark && (
        <span className="logo__word">
          <span className="logo__inter">INTER</span><span className="logo__null">NULL</span>
        </span>
      )}
    </span>
  );
}

/* ─── Masthead ─── */
function Masthead() {
  return (
    <header className="masthead">
      <div className="masthead__brand">
        <Logo size={40}/>
        <span className="masthead__sub">Privacy protocol</span>
        <span className="masthead__dot" title="Live on testnet"/>
      </div>
      <nav className="masthead__right">
        <a className="masthead__link" href="#how">How it works</a>
        <a className="masthead__link" href="#deployments">Chains</a>
        <a className="masthead__link" href="#paper">Paper</a>
        <ThemeToggle/>
        <a className="masthead__link masthead__link--cta" href="https://testnet.internull.xyz" target="_blank" rel="noreferrer">
          <span>Launch app</span>
          <span className="masthead__badge">testnet</span>
          <span aria-hidden="true">↗</span>
        </a>
      </nav>
    </header>
  );
}

/* ─── Front matter — product-first ─── */
function Front() {
  return (
    <section className="front">
      <div className="front__inner">
        <div className="front__left">
          <h1 className="front__title">
            <em>Complete</em> privacy.<br/>
            <em>Any</em> chain.
          </h1>

          <p className="front__subtitle">
            Deposit on one chain, withdraw on another with mathematical
            anonymity. Cross-chain privacy for EVM and Solana — and a
            Model&nbsp;Context Protocol server so any AI agent can use it.
          </p>

          <div className="front__authors">
            <div className="front__author">
              <div className="front__author-name">Status</div>
              <div className="front__author-aff">ETH · SOL · BNB · POL · Base · HYPE</div>
              <div className="front__author-email">Six chains, testnet · mainnet pending audit</div>
            </div>
          </div>

          <div className="front__actions">
            <a className="front__action" href="https://testnet.internull.xyz" target="_blank" rel="noreferrer">
              <span className="front__action-num">◉</span>
              <span>Enter dashboard</span>
              <span className="front__action-arrow">↗</span>
            </a>
            <a className="front__action" href="#how">
              <span className="front__action-num">§ i</span>
              <span>Protocol logic</span>
            </a>
            <a className="front__action" href="#agents">
              <span className="front__action-num">§ ii</span>
              <span>For AI agents</span>
            </a>
            <a className="front__action" href="uploads/paper.pdf" target="_blank" rel="noreferrer">
              <span className="front__action-num">§ iii</span>
              <span>Read the paper</span>
              <span className="front__action-arrow">↗</span>
            </a>
          </div>
        </div>

        <div className="front__right">
          <figure className="hero-plate">
            <div className="hero-plate__img hero-plate__img--logo">
              <img src={window.__A.logoHero} alt="InterNull — a chromed trefoil knot"/>
            </div>
            <figcaption className="hero-plate__cap">
              <span className="hero-plate__label">Plate&nbsp;I</span>
              <span className="hero-plate__text">
                <em>Trefoil knot</em> — a closed thread that crosses itself
                three times. The protocol's emblem: single-use signatures that
                close on themselves and leave no trace.
              </span>
            </figcaption>
          </figure>
        </div>
      </div>
    </section>
  );
}

/* ─── Principle strip — three claims, like a manifesto ─── */
function Principles() {
  return (
    <section className="section section--principles" id="principles">
      <div className="section__head">
        <span className="section__head-title">§ 1 &nbsp; Principles</span>
        <span className="section__folio">01 / 07</span>
      </div>
      <div className="section__body">
        <ol className="principles">
          <li>
            <span className="principles__num">I</span>
            <h3>Private, always.</h3>
            <p>
              Deposit and withdrawal are cryptographically unlinkable on-chain.
              No party — including InterNull's operators — can correlate them
              by reading the chain.
            </p>
          </li>
          <li>
            <span className="principles__num">II</span>
            <h3>Cross-chain by construction.</h3>
            <p>
              Built on threshold ECDSA over secp256k1 — works with any chain
              that verifies ECDSA or Ed25519 signatures. Withdraw on a different
              chain than you deposited on. The on-chain link does not exist;
              it is not obscured, it is not produced.
            </p>
          </li>
          <li>
            <span className="principles__num">III</span>
            <h3>Non-custodial, always.</h3>
            <p>
              Funds move through a Distributed Key Generation quorum of five
              nodes — three required to reconstruct, two cannot. No team, no
              operator, no relayer ever holds user funds at any point.
            </p>
          </li>
        </ol>
      </div>
    </section>
  );
}

/* ─── Fiber plate — full-bleed ─── */
/* ─── Linkage thesis — deck-sourced positioning ─── */
function LinkageThesis() {
  return (
    <section className="pullquote" id="thesis">
      <div className="pullquote__inner">
        <p className="pullquote__text">
          We don't prove cross-chain movement.<br/>
          We <em>remove the need</em> for it.
        </p>
        <p style={{
          fontFamily: "var(--serif)",
          fontSize: "1rem",
          lineHeight: 1.7,
          color: "var(--fg-2)",
          maxWidth: "58ch",
          margin: "32px auto 0",
          fontStyle: "italic",
        }}>
          InterNull reassigns value using one-time keys derived via DKG.
          Privacy by eliminating linkage, not hiding it.
        </p>
      </div>
    </section>
  );
}

/* ─── Fiber plate — full-bleed interstitial breath ─── */
function FiberPlate() {
  return (
    <figure className="bleed-plate bleed-plate--fiber">
      <img src="assets/fiber-plate.jpg" alt="Fine threads converging from many sources to a single point of light in the dark"/>
      <figcaption className="bleed-plate__cap bleed-plate__cap--right">
        <span className="bleed-plate__label">Plate II &nbsp;—&nbsp; Threshold</span>
        <span className="bleed-plate__text">
          Many independent shares, one reconstructed key. No single thread
          carries the secret; the secret exists only where they <em>cross</em>.
        </span>
      </figcaption>
    </figure>
  );
}

/* ─── Construction overview — diagram + 4 phases ─── */
function Construction() {
  return (
    <section className="section" id="how">
      <div className="section__head">
        <span className="section__head-title">§ 2 &nbsp; How it works</span>
        <span className="section__folio">02 / 07</span>
      </div>
      <div className="section__body">
        <h2 className="section-title">
          Four phases, end&#8209;to&#8209;end.<br/><em>No custodian in the middle.</em>
        </h2>

        <div className="diagram-grid">
          <figure className="diagram-figure diagram-figure--wide">
            <div className="diagram-figure__img">
              <InlineSVG src="assets/diagram-flow.svg" label="Schematic: deposit → 3-of-5 threshold committee → merkle tree of one-time signature keys → signed once → withdrawal"/>
            </div>
            <figcaption className="diagram-figure__cap">
              <span className="figure__label">Fig. 1</span>
              <span className="figure__text">
                On-chain, the transaction graph is indistinguishable from random.
                Only the user holds the secret witness that proves their own
                deposits are theirs — and only they can choose to reveal it.
              </span>
            </figcaption>
          </figure>

          <ol className="phase-list">
            <li>
              <span className="phase-list__num">Phase I · Deposit</span>
              <h4>Commit a note.</h4>
              <p>
                A fixed-denomination note enters the pool on chain&nbsp;A. No
                custodian. No metadata links the note to the depositor.
              </p>
            </li>
            <li>
              <span className="phase-list__num">Phase II · Commitment</span>
              <h4>DKG publishes the tree.</h4>
              <p>
                A 3-of-5 threshold committee of independent nodes publishes a
                Merkle tree of ephemeral withdrawal keys. No node holds the full set.
              </p>
            </li>
            <li>
              <span className="phase-list__num">Phase III · Signing</span>
              <h4>One-time signature.</h4>
              <p>
                Threshold ECDSA over secp256k1 produces a fresh, single-use
                withdrawal key per claim — no master key ever exists in one place.
                Reuse leaks the key. Single-use is enforced cryptographically,
                not policed.
              </p>
            </li>
            <li>
              <span className="phase-list__num">Phase IV · Withdrawal</span>
              <h4>Arrive unlinked.</h4>
              <p>
                A fresh address on chain&nbsp;B redeems the note. No on-chain
                link remains. Only the user holds the witness.
              </p>
            </li>
          </ol>
        </div>
      </div>
    </section>
  );
}

/* ─── Numbers ─── */
function Results() {
  return (
    <section className="section" id="results">
      <div className="section__head">
        <span className="section__head-title">§ 3 &nbsp; Numbers</span>
        <span className="section__folio">03 / 07</span>
      </div>
      <div className="section__body">
        <h2 className="section-title">
          Comparable privacy,<br/><em>at a fraction of the cost.</em>
        </h2>
        <div className="metrics">
          <div className="metric">
            <div className="metric__value">~85<span className="unit"> %</span></div>
            <div className="metric__label">Gas reduction vs. zk-SNARK mixers</div>
          </div>
          <div className="metric">
            <div className="metric__value">6<span className="unit"> chains</span></div>
            <div className="metric__label">ETH · SOL · BNB · POL · Base · HYPE</div>
          </div>
          <div className="metric">
            <div className="metric__value">3<span style={{fontFamily: "Source Serif 4", fontStyle: "italic", fontSize: "2rem", margin: "0 4px", color: "var(--fg-2)"}}>/</span>5</div>
            <div className="metric__label">DKG threshold (t-of-n)</div>
          </div>
          <div className="metric">
            <div className="metric__value">0<span className="unit"> custody</span></div>
            <div className="metric__label">No team or node ever holds user funds</div>
          </div>
        </div>

        <p style={{marginTop: 40, maxWidth: "64ch", color: "var(--fg-2)", fontSize: "var(--fs-small)", fontStyle: "italic"}}>
          Benchmarked on mainnet-forked testnets against Tornado Cash, Aztec, and Monero.
          Full methodology in the paper.
        </p>
      </div>
    </section>
  );
}

/* ─── Deployments (chains) ─── */
function Deployments() {
  const chains = [
    { num: "I",   name: "Ethereum",    ticker: "ETH",  logo: "eth",  sub: "Sepolia testnet",  status: "live", folio: "§ 4.1" },
    { num: "II",  name: "Solana",      ticker: "SOL",  logo: "sol",  sub: "Devnet",            status: "live", folio: "§ 4.2" },
    { num: "III", name: "BNB Chain",   ticker: "BNB",  logo: "bnb",  sub: "Testnet",           status: "live", folio: "§ 4.3" },
    { num: "IV",  name: "Polygon",     ticker: "POL",  logo: "pol",  sub: "Amoy testnet",      status: "live", folio: "§ 4.4" },
    { num: "V",   name: "Base",        ticker: "ETH",  logo: "base", sub: "Sepolia testnet",   status: "live", folio: "§ 4.5" },
    { num: "VI",  name: "Hyperliquid", ticker: "HYPE", logo: "hype", sub: "Testnet",           status: "live", folio: "§ 4.6" }
  ];
  return (
    <section className="section" id="deployments">
      <div className="section__head">
        <span className="section__head-title">§ 4 &nbsp; Deployments</span>
        <span className="section__folio">04 / 07</span>
      </div>
      <div className="section__body">
        <h2 className="section-title">
          Six chains.<br/><em>One private exit.</em>
        </h2>
        <div className="toc">
          {chains.map((c, i) => (
            <div className="toc__row" key={i}>
              <div className="toc__num">№ {c.num}</div>
              <div className="toc__chain">
                <img className="toc__logo" src={window.__A["chain_" + c.logo]} alt=""/>
                {c.name} <span className="toc__ticker">{c.ticker}</span> <em>— {c.sub}</em>
              </div>
              <div className="toc__leaders"/>
              <div className={"toc__status " + (c.status === "live" ? "live" : "")}>
                {c.status}
              </div>
              <div className="toc__folio">{c.folio}</div>
            </div>
          ))}
        </div>

        <p style={{marginTop: 36, maxWidth: "60ch", fontSize: "var(--fs-small)", fontStyle: "italic", color: "var(--fg-2)"}}>
          Each chain maintains an independent nullifier set; there is no cross-chain
          state synchronisation.
        </p>
      </div>
    </section>
  );
}

/* ─── Agents — MCP-first interface (project's own emphasis) ─── */
function Agents() {
  return (
    <section className="section" id="agents">
      <div className="section__head">
        <span className="section__head-title">§ 5 &nbsp; For AI agents</span>
        <span className="section__folio">05 / 07</span>
      </div>
      <div className="section__body">
        <h2 className="section-title">
          AI agents,<br/>
          <em>with a wallet of their own.</em>
        </h2>

        <p style={{maxWidth: "62ch", color: "var(--fg-2)", marginBottom: 32, fontSize: "1.0625rem"}}>
          InterNull ships a Model Context Protocol server with eighteen tools.
          Any LLM — Claude, GPT, custom — can deposit, claim one-time keys,
          withdraw, and route cross-chain swaps through the protocol. No API
          keys. Wallet-based ECDSA on every request. Encrypted local wallet
          storage (AES-256-GCM, PBKDF2).
        </p>

        <div className="agents-install" style={{
          display: "grid",
          gridTemplateColumns: "1fr 1fr",
          gap: 0,
          marginTop: 24,
          border: "0.5px solid var(--rule)",
        }}>
          <div style={{padding: "32px 28px", borderRight: "0.5px solid var(--rule)"}}>
            <div style={{
              fontFamily: "var(--mono)", fontSize: "0.7rem",
              letterSpacing: "0.18em", textTransform: "uppercase",
              color: "var(--fg-2)", marginBottom: 14,
            }}>Install</div>
            <pre style={{
              fontFamily: "var(--mono)", fontSize: "0.875rem",
              margin: 0, padding: 0, color: "var(--fg)", lineHeight: 1.5,
            }}>{`$ npx internull-mcp`}</pre>
            <p style={{color: "var(--fg-2)", fontSize: "0.875rem", marginTop: 14, marginBottom: 0}}>
              No clone. No build step. Node ≥ 18.
            </p>
          </div>
          <div style={{padding: "32px 28px"}}>
            <div style={{
              fontFamily: "var(--mono)", fontSize: "0.7rem",
              letterSpacing: "0.18em", textTransform: "uppercase",
              color: "var(--fg-2)", marginBottom: 14,
            }}>Claude / Cursor config</div>
            <pre style={{
              fontFamily: "var(--mono)", fontSize: "0.78rem",
              margin: 0, padding: 0, color: "var(--fg)", lineHeight: 1.5,
              whiteSpace: "pre-wrap",
            }}>{`"internull": {
  "command": "npx",
  "args": ["internull-mcp"]
}`}</pre>
          </div>
        </div>

        <div className="agents-stats" style={{
          display: "grid",
          gridTemplateColumns: "repeat(3, 1fr)",
          gap: 0,
          borderLeft: "0.5px solid var(--rule)",
          borderRight: "0.5px solid var(--rule)",
          borderBottom: "0.5px solid var(--rule)",
        }}>
          {[
            ["18 tools", "wallet · discovery · deposit · claim · withdraw · relay · swap"],
            ["3-of-5 DKG", "any 3 nodes reconstruct, no 2 nodes can"],
            ["Stdio transport", "standard MCP, runs locally next to your agent"],
          ].map(([k, v], i) => (
            <div key={i} style={{
              padding: "24px 28px",
              borderRight: i < 2 ? "0.5px solid var(--rule)" : "none",
            }}>
              <div style={{
                fontFamily: "var(--serif)", fontWeight: 500,
                fontSize: "1rem", color: "var(--fg)", marginBottom: 6,
              }}>{k}</div>
              <div style={{
                fontFamily: "var(--mono)", fontSize: "0.75rem",
                color: "var(--fg-2)", lineHeight: 1.5,
              }}>{v}</div>
            </div>
          ))}
        </div>

        <p style={{marginTop: 32, maxWidth: "60ch", fontSize: "var(--fs-small)", fontStyle: "italic", color: "var(--fg-2)"}}>
          Repository: <a href="https://github.com/InterNullOrg/blackbox_mcp" target="_blank" rel="noreferrer" style={{color: "inherit", borderBottom: "0.5px solid currentColor"}}>github.com/InterNullOrg/blackbox_mcp</a>
        </p>
      </div>
    </section>
  );
}

/* ─── Builders rail — open source / run a node / MCP ─── */
function Builders() {
  const items = [
    { num: "i",   label: "GitHub",
      sub: "Contracts · node · frontend",
      body: "All source open. MIT-licensed where applicable.",
      href: "https://github.com/InterNullOrg" },
    { num: "ii",  label: "Run a node",
      sub: "Threshold quorum",
      body: "Join the 3-of-5 DKG committee. Spec, hardware notes and join procedure in the docs.",
      href: "https://www.internull.xyz/docs" },
    { num: "iii", label: "MCP server",
      sub: "For AI agents",
      body: "Model Context Protocol endpoint. Agents deposit, derive keys, and withdraw — privately, programmatically.",
      href: "https://github.com/InterNullOrg/blackbox_mcp" },
  ];
  return (
    <section className="section" id="builders">
      <div className="section__head">
        <span className="section__head-title">§ 6 &nbsp; For builders</span>
        <span className="section__folio">06 / 07</span>
      </div>
      <div className="section__body">
        <h2 className="section-title">
          Run a node. Integrate the protocol.<br/>
          <em>Fork it.</em>
        </h2>
        <ol className="phase-list" style={{marginTop: 28}}>
          {items.map((it) => (
            <li key={it.num}>
              <span className="phase-list__num">§ {it.num} · {it.sub}</span>
              <h4>
                <a href={it.href} target="_blank" rel="noreferrer" style={{color:"inherit", textDecoration:"none", borderBottom:"1px solid currentColor", paddingBottom:1}}>
                  {it.label} <span style={{fontStyle:"normal", marginLeft:4}}>↗</span>
                </a>
              </h4>
              <p>{it.body}</p>
            </li>
          ))}
        </ol>
      </div>
    </section>
  );
}

/* ─── Paper section — "there's a paper, by the way" ─── */
function Paper() {
  return (
    <section className="section" id="paper">
      <div className="section__head">
        <span className="section__head-title">§ 7 &nbsp; The paper</span>
        <span className="section__folio">07 / 07</span>
      </div>
      <div className="section__body">
        <div className="paper-intro">
          <div className="paper-intro__copy">
            <h2 className="section-title" style={{marginBottom: 24}}>
              <em>Achieving Cross-Chain Transaction Privacy Through ECDSA One-Time Signatures.</em>
            </h2>
            <p style={{color: "var(--fg-2)", maxWidth: "52ch", marginBottom: 20}}>
              The cryptographic underpinnings of the protocol are documented in a
              16-page technical preprint. It covers the ECDSA-OTS
              construction, the threshold DKG, fixed-denomination splitting, the
              cross-chain allocation scheme, and the security proofs.
            </p>
            <p style={{color: "var(--fg-2)", maxWidth: "52ch", marginBottom: 32}}>
              This landing page is a summary. The paper is the reference.
            </p>
            <div className="paper-intro__actions">
              <a href="uploads/paper.pdf" className="paper-intro__btn">
                <span>Read the paper</span>
                <span style={{marginLeft: 12}}>↗</span>
              </a>
            </div>
          </div>
          <figure className="mercury">
            <img src="assets/knot-detail.jpg" alt="Detail of the trefoil knot — a closed thread crossing itself three times"/>
            <figcaption>
              <span className="figure__label">Fig. 4</span>
              <span>The thread closes on&nbsp;itself.</span>
            </figcaption>
          </figure>
        </div>
      </div>
    </section>
  );
}

/* ─── Colophon ─── */
function Colophon() {
  return (
    <footer className="colophon">
      <div className="colophon__inner">
        <div>
          <div className="colophon__title">
            <Logo size={56}/>
          </div>
          <p className="colophon__note">
            A non-custodial cross-chain privacy protocol. Private by default.
            Contracts, node software, and frontend are open source. The
            protocol is the counterparty — funds never touch a company wallet.
          </p>
        </div>
        <div>
          <div className="colophon__col-title">Protocol</div>
          <ul className="colophon__list">
            <li><a href="https://testnet.internull.xyz" target="_blank" rel="noreferrer">Launch app ↗</a></li>
            <li><a href="https://github.com/InterNullOrg" target="_blank" rel="noreferrer">GitHub ↗</a></li>
            <li><a href="https://github.com/InterNullOrg" target="_blank" rel="noreferrer">Node software</a></li>
            <li><a href="https://github.com/InterNullOrg/blackbox_mcp" target="_blank" rel="noreferrer">MCP server</a></li>
          </ul>
        </div>
        <div>
          <div className="colophon__col-title">Paper</div>
          <ul className="colophon__list">
            <li><a href="uploads/paper.pdf" target="_blank" rel="noreferrer">Read the paper ↗</a></li>
            <li><a href="#how">Construction</a></li>
            <li><a href="#agents">For AI agents</a></li>
            <li><a href="#results">Methodology &amp; numbers</a></li>
          </ul>
        </div>
        <div>
          <div className="colophon__col-title">Contact</div>
          {/* NOTE(daniel): confirm contact addresses. Paper lists j@internull.xyz;
              site previously used jamshed@. Twitter handle from source = @0xinternull. */}
          <ul className="colophon__list">
            <li><a href="mailto:jamshed@internull.xyz">jamshed@internull.xyz</a></li>
            <li><a href="https://x.com/0xinternull" target="_blank" rel="noreferrer">Twitter / X</a></li>
            <li><a href="mailto:security@internull.xyz">Responsible disclosure</a></li>
          </ul>
        </div>
      </div>
      <div className="colophon__baseline">
        <span>internull.xyz</span>
        <span style={{textAlign:"right"}}>Open source · Testnet</span>
      </div>
    </footer>
  );
}

/* ─── Theme toggle ─── */
function ThemeToggle() {
  const [theme, setTheme] = useState(() => document.documentElement.getAttribute("data-theme") || "paper");
  useEffect(() => {
    document.documentElement.setAttribute("data-theme", theme);
    try { localStorage.setItem("internull-theme", theme); } catch {}
  }, [theme]);
  useEffect(() => {
    try {
      const saved = localStorage.getItem("internull-theme");
      if (saved && saved !== theme) setTheme(saved);
    } catch {}
    // eslint-disable-next-line
  }, []);
  const dark = theme === "ink";
  return (
    <button
      className="theme-toggle"
      onClick={() => setTheme(dark ? "paper" : "ink")}
      aria-label={dark ? "Switch to light theme" : "Switch to dark theme"}
      title={dark ? "Light" : "Dark"}
    >
      {dark ? (
        /* sun — currently dark, click for light */
        <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round">
          <circle cx="12" cy="12" r="4.2"/>
          <path d="M12 2.5v2.4M12 19.1v2.4M21.5 12h-2.4M4.9 12H2.5M18.7 5.3l-1.7 1.7M7 17l-1.7 1.7M18.7 18.7L17 17M7 7L5.3 5.3"/>
        </svg>
      ) : (
        /* moon — currently light, click for dark */
        <svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor" stroke="none">
          <path d="M20 14.5A8 8 0 1 1 9.5 4a6.5 6.5 0 0 0 10.5 10.5z"/>
        </svg>
      )}
    </button>
  );
}

/* ─── Paper color picker (temporary — for choosing between candidates) ─── */
function PaperColorPicker() {
  const options = [
    { key: "modern",   hex: "#FAFAFA", label: "Modern" },
    { key: "bone",     hex: "#F5F5F0", label: "Bone" },
    { key: "blush",    hex: "#FCF8F8", label: "Blush" },
    { key: "cream",    hex: "#F3EFE6", label: "Cream" },
  ];
  const [choice, setChoice] = useState(() => {
    try { return localStorage.getItem("internull-paper-v2") || "modern"; } catch { return "modern"; }
  });
  // separate storage key from v1 so v2 doesn't inherit a stored "blush"
  useEffect(() => { try { localStorage.setItem("internull-paper-v2", choice); } catch {} }, [choice]);
  useEffect(() => {
    const o = options.find(x => x.key === choice) || options[0];
    document.documentElement.style.setProperty("--paper-bg", o.hex);
    try { localStorage.setItem("internull-paper", choice); } catch {}
  }, [choice]);
  return (
    <div style={{
      position: "fixed", bottom: 24, left: 24, zIndex: 100,
      background: "var(--bg)", border: "0.5px solid var(--rule)",
      padding: "10px 12px", fontFamily: "var(--mono)", fontSize: 11,
      letterSpacing: "0.12em", textTransform: "uppercase",
      display: "flex", gap: 8, alignItems: "center",
    }}>
      <span style={{color: "var(--fg-3)", marginRight: 4}}>Paper</span>
      {options.map(o => (
        <button key={o.key} onClick={() => setChoice(o.key)} title={o.label}
          style={{
            width: 22, height: 22, borderRadius: 0,
            background: o.hex,
            border: choice === o.key ? "1.5px solid var(--fg)" : "0.5px solid var(--rule-soft)",
            cursor: "pointer", padding: 0,
            outline: choice === o.key ? "2px solid var(--bg)" : "none",
            outlineOffset: "-4px",
          }}/>
      ))}
    </div>
  );
}

/* ─── App ─── */
function App() {
  return (
    <>
      <Masthead/>
      <Front/>
      <Principles/>
      <LinkageThesis/>
      <Construction/>
      <Results/>
      <FiberPlate/>
      <Deployments/>
      <Agents/>
      <Builders/>
      <Paper/>
      <Colophon/>
    </>
  );
}

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