// app.jsx — BRRR landing page

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

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "ticker": "BRRR",
  "accentColor": "#1fae5a",
  "feePercent": 3,
  "buybackSplit": 80,
  "liveTicker": true
}/*EDITMODE-END*/;

// ---------- shared helpers ----------
const fmtUSD = (n, dp = 0) =>
  "$" + n.toLocaleString("en-US", { minimumFractionDigits: dp, maximumFractionDigits: dp });
const fmtNum = (n, dp = 0) =>
  n.toLocaleString("en-US", { minimumFractionDigits: dp, maximumFractionDigits: dp });

// deterministic pseudorandom for ledger rows
const rand = (seed) => {
  let s = seed; return () => { s = (s * 9301 + 49297) % 233280; return s / 233280; };
};

// ---------- NAV ----------
function Nav({ t }) {
  return (
    <nav className="nav">
      <div className="nav-inner">
        <a className="brand" href="#top">
          <span className="brand-mark">B</span>
          <span>{t.ticker}</span>
          <span className="mono" style={{ fontSize: 11, color: "var(--mute)", marginLeft: 2 }}>
            /usd · 0.0428
          </span>
        </a>
        <div className="nav-links" style={{}}>
          <a href="#how">How it works</a>
          <a href="#ledger">Buybacks</a>
          <a href="#roadmap">Roadmap</a>
          <a href="#buy">Buy</a>
          <a href="#faq">FAQ</a>
        </div>
        <div style={{ display: "flex", gap: 8 }}>
          <a className="btn" href="#ledger">Live feed</a>
          <a className="btn btn-accent" href="#buy">Buy {t.ticker} →</a>
        </div>
      </div>
    </nav>
  );
}

// ---------- HERO ----------
function Hero({ t }) {
  const [live, setLive] = useState({
    lastBuyback: 12480,
    totalBought: 2_418_902,
    pending: 248.32,
  });

  // tick live numbers
  useEffect(() => {
    if (!t.liveTicker) return;
    const id = setInterval(() => {
      setLive((p) => ({
        lastBuyback: p.lastBuyback + Math.round(Math.random() * 40),
        totalBought: p.totalBought + Math.round(Math.random() * 60),
        pending: +(p.pending + Math.random() * 2.3).toFixed(2),
      }));
    }, 1400);
    return () => clearInterval(id);
  }, [t.liveTicker]);

  // ASCII ticker sparkline
  const chart = useMemo(() => {
    const blocks = "▁▂▃▄▅▆▇█";
    const points = 48;
    const r = rand(42);
    let out = "";
    let v = 4;
    for (let i = 0; i < points; i++) {
      v = Math.max(0, Math.min(7, v + Math.round((r() - 0.4) * 2)));
      out += blocks[v];
    }
    return out;
  }, []);

  return (
    <section id="top" className="hero">
      <div>
        <span className="eyebrow">
          <span className="pulse"></span>
          BUYBACK ACTIVE · BLOCK #8,421,904
        </span>
        <h1 className="display">
          Every fee<br />
          <span className="stroke">buys more</span><br />
          <em>{t.ticker}</em>.
        </h1>
        <p className="lede">
          {t.ticker} is a self-reinforcing token. {t.feePercent}% fee on every trade.
          {" "}{t.buybackSplit}% of it is routed on-chain to buy back and lock supply.
          The printer doesn't stop — it just runs in reverse.
        </p>
        <div className="hero-cta">
          <a className="btn btn-accent" href="#buy">
            Buy {t.ticker}
            <span className="mono" style={{ opacity: .7 }}>↗</span>
          </a>
          <a className="btn" href="#how">See the mechanism</a>
          <a className="btn" href="#ledger">
            <span className="mono" style={{ color: "var(--accent)" }}>●</span> Live buybacks
          </a>
        </div>

        <div className="hero-meta">
          <div>
            <div className="k">Market cap</div>
            <div className="v tnum">{fmtUSD(4_280_000)}</div>
          </div>
          <div>
            <div className="k">Bought back · 30d</div>
            <div className="v tnum" style={{ color: "var(--accent)" }}>
              {fmtUSD(live.totalBought)}
            </div>
          </div>
          <div>
            <div className="k">Holders</div>
            <div className="v tnum">{fmtNum(12_408)}</div>
          </div>
          <div>
            <div className="k">Chain</div>
            <div className="v">Solana · SPL</div>
          </div>
        </div>

        <pre className="ascii" style={{ marginTop: 36, maxWidth: 520 }}>
{`  PRICE · 24H                                       +${(12.4).toFixed(1)}%
  ${chart}
  00:00          06:00          12:00          18:00          NOW`}
        </pre>
      </div>

      <Receipt live={live} t={t} />
    </section>
  );
}

function Receipt({ live, t }) {
  const txid = useMemo(
    () => "0x" + Math.random().toString(16).slice(2, 10) + "…" + Math.random().toString(16).slice(2, 6),
    []
  );
  return (
    <div className="receipt">
      <div className="r-head">
        <div className="r-title">Buyback receipt</div>
        <div className="r-id">#{String(Math.floor(live.lastBuyback % 99999)).padStart(5, "0")}</div>
      </div>
      <div className="r-stamp">Executed</div>

      <div style={{ paddingTop: 10 }}>
        <div className="r-row">
          <span className="lbl">Block</span>
          <span className="val tnum">8,421,904</span>
        </div>
        <div className="r-row">
          <span className="lbl">Trade volume</span>
          <span className="val tnum">{fmtUSD(520_420)}</span>
        </div>
        <div className="r-row">
          <span className="lbl">Fees collected ({t.feePercent}%)</span>
          <span className="val tnum">{fmtUSD(15_612, 2)}</span>
        </div>
        <div className="r-row">
          <span className="lbl">Routed to buyback ({t.buybackSplit}%)</span>
          <span className="val tnum">{fmtUSD(15_612 * (t.buybackSplit / 100), 2)}</span>
        </div>
        <div className="r-row">
          <span className="lbl">{t.ticker} acquired</span>
          <span className="val tnum">291,428.40</span>
        </div>
        <div className="r-row">
          <span className="lbl">Destination</span>
          <span className="val mono" style={{ fontSize: 11 }}>burn · 0x0000…dead</span>
        </div>
        <div className="r-row">
          <span className="lbl">Txn</span>
          <span className="val mono" style={{ fontSize: 11 }}>{txid}</span>
        </div>

        <div className="r-total">
          <span>Total · bought</span>
          <span className="big tnum">{fmtUSD(live.lastBuyback, 0)}</span>
        </div>

        <div className="r-foot">
          Auto-generated · every 200 blocks · thank you for your trade
        </div>
      </div>
    </div>
  );
}

// ---------- LIVE TICKER BAR ----------
function TickerBar({ t }) {
  const items = [
    `${t.ticker}/USD  0.04281`,
    `24H  +12.4%`,
    `VOL  $1.28M`,
    `BUYBACK POOL  $${(248).toFixed(0)}.32`,
    `LAST BB  $12,480`,
    `HOLDERS  12,408`,
    `FEE  ${t.feePercent}%`,
    `SPLIT  ${t.buybackSplit}% → BB / ${100 - t.buybackSplit}% → LP`,
    `CHAIN  SOLANA`,
    `STATUS  PRINTER RUNNING IN REVERSE`,
  ];
  const row = [...items, ...items].map((x, i) => (
    <span key={i}>
      <span className="dot"></span>{x}
    </span>
  ));
  return (
    <div className="ticker">
      <div className="ticker-track">{row}</div>
    </div>
  );
}

// ---------- MECHANISM ----------
function Mechanism({ t }) {
  const steps = [
    { n: "01", icon: "$", h: "User trades", d: `Any buy or sell on ${t.ticker} triggers a ${t.feePercent}% fee, collected automatically at the protocol layer.` },
    { n: "02", icon: "/", h: "Fees pool", d: "Fees accumulate in a transparent on-chain vault. Anyone can read it. Nobody can withdraw it." },
    { n: "03", icon: "⇢", h: "Auto-route", d: `Every 200 blocks, ${t.buybackSplit}% of the vault market-buys ${t.ticker} from the open market.`, hot: true },
    { n: "04", icon: "×", h: "Supply burned", d: `The bought tokens are sent to a dead address. Float shrinks. Floor compounds.` },
  ];
  return (
    <section id="how" className="wrap">
      <div className="section-label">01 · Mechanism</div>
      <h2>The fees don't leave. They <em>come home.</em></h2>
      <p className="sub">
        Most tokens leak value to treasuries, LPs, or a dev wallet. {t.ticker} routes
        {" "}<b>{t.buybackSplit}%</b> of every fee directly into on-chain buybacks. It's a tight loop, written
        into the token itself — no multisig, no timelock, no trust required.
      </p>

      <div className="flow">
        {steps.map((s) => (
          <div key={s.n} className={"step" + (s.hot ? " hot" : "")}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start" }}>
              <div className="step-icon">{s.icon}</div>
              <div className="step-n">STEP {s.n}</div>
            </div>
            <div>
              <div className="step-h">{s.h}</div>
              <div className="step-d">{s.d}</div>
            </div>
          </div>
        ))}
      </div>

      <div className="divider-dashed" style={{ marginTop: 64 }}></div>

      <div style={{ display: "grid", gridTemplateColumns: "1.05fr .95fr", gap: 56, alignItems: "start" }}>
        <div>
          <div className="section-label" style={{ marginTop: 0 }}>Flow of funds</div>
          <pre className="mono" style={{
            fontSize: 13, lineHeight: 1.6, color: "var(--ink-2)", background: "rgba(255,255,255,.5)",
            padding: 22, borderRadius: 14, border: ".5px solid var(--line-2)", overflowX: "auto"
          }}>
{`   TRADE              FEE                VAULT
   ┌─────┐   ${t.feePercent}%    ┌─────┐           ┌──────────┐
   │ USD │ ───────→ │ FEE │ ────────→ │  VAULT   │
   └─────┘          └─────┘           └────┬─────┘
                                           │ every 200 blocks
                           ${t.buybackSplit}% ┌──────────┴──────────┐ ${100 - t.buybackSplit}%
                              ↓                           ↓
                         ┌────────┐                 ┌─────────┐
                         │ BUYBACK│ ──→ BURN       │   LP    │
                         └────────┘                 └─────────┘
`}
          </pre>
        </div>
        <div>
          <div className="section-label" style={{ marginTop: 0 }}>Why it works</div>
          <ul style={{ listStyle: "none", padding: 0, margin: 0, display: "flex", flexDirection: "column", gap: 18 }}>
            {[
              ["Demand floor", "Every fee becomes a buy. Volume alone sustains price pressure."],
              ["Supply sink", "Bought tokens go to a dead address. Float only shrinks."],
              ["No gatekeeper", "The buyback runs in the contract. No admin key. No pausing."],
              ["Fully auditable", "Every receipt is on-chain. We print them to the ledger below."],
            ].map(([h, d]) => (
              <li key={h} style={{ display: "grid", gridTemplateColumns: "24px 1fr", gap: 14 }}>
                <span className="mono" style={{ color: "var(--accent)", fontSize: 14 }}>→</span>
                <div>
                  <div style={{ fontSize: 16, fontWeight: 500, letterSpacing: "-0.01em" }}>{h}</div>
                  <div style={{ fontSize: 13.5, color: "var(--ink-2)", lineHeight: 1.55, marginTop: 3 }}>{d}</div>
                </div>
              </li>
            ))}
          </ul>
        </div>
      </div>
    </section>
  );
}

// ---------- STATS + LEDGER ----------
function StatsAndLedger({ t }) {
  const stats = [
    { k: "Fees collected · all-time", v: fmtUSD(3_124_820), d: "+$8,240 today" },
    { k: `${t.ticker} bought back`, v: fmtNum(58_204_910), d: "73.2% of fee pool" },
    { k: `${t.ticker} burned`, v: fmtNum(58_204_910), d: "100% of buybacks" },
    { k: "Buyback events", v: fmtNum(1842), d: "every ~200 blocks" },
  ];

  const rows = useMemo(() => {
    const r = rand(11);
    const out = [];
    for (let i = 0; i < 8; i++) {
      const amt = Math.round((120 + r() * 24_000));
      const tokens = Math.round(amt / 0.0428);
      const mins = Math.round(r() * 600);
      out.push({
        id: `BB-${String(8421904 - i * 200).slice(-6)}`,
        time: mins < 60 ? `${mins}m ago` : `${Math.floor(mins / 60)}h ${mins % 60}m ago`,
        amt, tokens,
        addr: "0x" + r().toString(16).slice(2, 6) + "…" + r().toString(16).slice(2, 6),
        status: "BURN",
      });
    }
    return out;
  }, []);

  return (
    <section id="ledger" className="wrap" style={{ paddingTop: 60 }}>
      <div className="section-label">02 · By the numbers</div>
      <h2>Proof, not <em>promises.</em></h2>
      <p className="sub">
        Every fee collected, every token bought, every burn — printed to the ledger.
        Updated block-by-block. This page reflects the on-chain state.
      </p>

      <div className="stats-strip">
        {stats.map((s) => (
          <div className="stat" key={s.k}>
            <div className="stat-k">{s.k}</div>
            <div className="stat-v">{s.v}</div>
            <div className="stat-delta">{s.d}</div>
          </div>
        ))}
      </div>

      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginTop: 56, marginBottom: 8 }}>
        <div className="section-label" style={{ margin: 0 }}>Recent buybacks</div>
        <div className="mono" style={{ fontSize: 11, color: "var(--mute)" }}>
          <span style={{ color: "var(--accent)" }}>●</span> LIVE · refreshes every block
        </div>
      </div>

      <div className="ledger">
        <div className="ledger-head">
          <span>ID</span>
          <span>Time</span>
          <span>Tokens bought</span>
          <span>USD routed</span>
          <span>Status</span>
        </div>
        {rows.map((r) => (
          <div className="ledger-row" key={r.id}>
            <span>{r.id}</span>
            <span>{r.time}</span>
            <span className="tnum">{fmtNum(r.tokens)} {t.ticker}</span>
            <span className="tnum amt">{fmtUSD(r.amt)}</span>
            <span className="addr">→ {r.status}</span>
          </div>
        ))}
      </div>
    </section>
  );
}

// ---------- WORDMARK BANNER ----------
function Banner({ t }) {
  const items = [
    <span key="a" className="stroke">PRINTING IN REVERSE</span>,
    <span key="b" className="sep">///</span>,
    <span key="c"><em>{t.ticker}</em></span>,
    <span key="d" className="sep">●</span>,
    <span key="e" className="stroke">FEES IN · SUPPLY OUT</span>,
    <span key="f" className="sep">●</span>,
  ];
  return (
    <div className="banner">
      <div className="banner-track">
        {[...items, ...items, ...items]}
      </div>
    </div>
  );
}

// ---------- ROADMAP ----------
function Roadmap({ t }) {
  const phases = [
    {
      n: "Phase 01", title: "Press start", done: true,
      items: ["Token deployed on Solana", "Buyback contract audited", "Liquidity locked · 24 months", "First 100k holders"],
    },
    {
      n: "Phase 02", title: "Distribute", done: true,
      items: ["CEX listings · 3 major", "Ledger explorer v1", "Auto-burn activated", "Community grants open"],
    },
    {
      n: "Phase 03", title: "Print loop", done: false,
      items: ["Cross-chain buybacks · Base, BNB", "On-chain receipts widget", "Partner integrations", "Dashboard v2"],
    },
    {
      n: "Phase 04", title: "The endgame", done: false,
      items: ["Buyback-as-a-service SDK", "Public index of BB tokens", "Sub-second settlement", "Float approaches zero"],
    },
  ];
  return (
    <section id="roadmap" className="wrap">
      <div className="section-label">03 · Roadmap</div>
      <h2>From fee loop to <em>infrastructure.</em></h2>
      <p className="sub">
        {t.ticker} starts as a memecoin with a working mechanism. The goal is to make that
        mechanism the default — a standard every new token can plug into.
      </p>

      <div className="roadmap">
        {phases.map((p) => (
          <div key={p.n} className={"phase" + (p.done ? " done" : "")}>
            <span className="phase-dot"></span>
            <div className="phase-h">{p.n} {p.done ? "· shipped" : "· in flight"}</div>
            <div className="phase-title">{p.title}</div>
            <ul>
              {p.items.map((it) => <li key={it}>{it}</li>)}
            </ul>
          </div>
        ))}
      </div>
    </section>
  );
}

// ---------- BUY ----------
function Buy({ t }) {
  const [copied, setCopied] = useState(false);
  const addr = "BrRRfeeP1nTrXm0n3yP0w3rM1ntF33dL00pS0l";
  const copy = () => {
    navigator.clipboard?.writeText(addr);
    setCopied(true);
    setTimeout(() => setCopied(false), 1500);
  };

  return (
    <section id="buy" className="wrap" style={{ paddingTop: 60 }}>
      <div className="section-label">04 · How to buy</div>
      <h2>Four steps. <em>No permission slip.</em></h2>

      <div className="buy-grid" style={{ marginTop: 48 }}>
        <div className="buy-steps">
          {[
            ["Get a Solana wallet", "Phantom, Solflare, Backpack — any SPL-compatible wallet works. Fund it with SOL from your exchange of choice."],
            [`Copy the ${t.ticker} contract`, "Use the official contract address on the right. Always verify the first and last 6 characters — impostors are inevitable."],
            ["Swap on Jupiter or Raydium", "Paste the contract into your DEX of choice. Set slippage to 2%. Hit confirm. Your trade itself contributes to the next buyback."],
            ["Hold. Watch the ledger.", `Every 200 blocks you'll see a new entry in the ledger above. That's your fee — coming home as a buyback.`],
          ].map(([h, d], i) => (
            <div className="buy-step" key={h}>
              <div className="n">0{i + 1}</div>
              <div>
                <h4>{h}</h4>
                <p>{d}</p>
              </div>
            </div>
          ))}
        </div>

        <div className="addr-box">
          <div>
            <div className="lbl">Contract · Solana</div>
            <div className="addr-row">
              <code>{addr}</code>
              <button className="copy-btn" onClick={copy}>{copied ? "✓ COPIED" : "COPY"}</button>
            </div>
          </div>
          <div className="divider"></div>
          <div style={{ display: "flex", flexDirection: "column", gap: 4 }}>
            <div className="minirow"><span>Chain</span><b>Solana · SPL</b></div>
            <div className="minirow"><span>Supply</span><b className="tnum">1,000,000,000</b></div>
            <div className="minirow"><span>Fee</span><b>{t.feePercent}% · buy + sell</b></div>
            <div className="minirow"><span>Buyback split</span><b>{t.buybackSplit}%</b></div>
            <div className="minirow"><span>Burn</span><b>Automatic</b></div>
            <div className="minirow"><span>LP lock</span><b>24 months</b></div>
            <div className="minirow"><span>Taxes</span><b>Immutable</b></div>
          </div>
          <div className="divider"></div>
          <div style={{ display: "flex", gap: 8 }}>
            <a className="btn" style={{ flex: 1, background: "transparent", color: "var(--bg)", borderColor: "rgba(243,241,234,.3)", justifyContent: "center" }} href="#">Jupiter ↗</a>
            <a className="btn" style={{ flex: 1, background: "var(--accent)", color: "var(--accent-ink)", borderColor: "transparent", justifyContent: "center" }} href="#">Raydium ↗</a>
          </div>
        </div>
      </div>
    </section>
  );
}

// ---------- FAQ ----------
function FAQ({ t }) {
  const [open, setOpen] = useState(0);
  const qs = [
    [`Is ${t.ticker} a memecoin or a utility token?`,
      `Both. The meme is the mechanism. ${t.ticker} is transparently a memecoin — no pretense of product-market fit — but it carries a working buyback loop that behaves more like protocol infrastructure than marketing copy.`],
    ["Where does the fee go if it's not buying back?",
      `The ${100 - 80 /* static ref */}% that doesn't go to buybacks refills the liquidity pool, which keeps slippage low and trades deep. Nothing is sent to a team wallet. There is no team wallet.`],
    ["Can the buyback be paused or rug-pulled?",
      "No. The buyback logic lives inside the token itself, not a separate contract controlled by an admin. There is no pause function, no upgrade proxy, and no admin key. The code is the contract."],
    ["How often does the buyback execute?",
      "Every 200 blocks on Solana — roughly every 80 seconds. Each execution prints a receipt to the on-chain ledger, which is mirrored on this page."],
    ["What happens to the bought tokens?",
      `They're sent to 0x000…dead — a provably-unspendable address. This permanently shrinks float. Every fee makes the remaining supply scarcer.`],
    ["What about gas? Who pays for the buyback tx?",
      "The buyback tx is paid from the fee vault itself — never from users. On Solana, the cost is under a cent per execution."],
  ];
  return (
    <section id="faq" className="wrap">
      <div className="section-label">05 · FAQ</div>
      <h2>Questions, answered <em>on the record.</em></h2>
      <div className="faq" style={{ marginTop: 40 }}>
        {qs.map(([q, a], i) => (
          <div key={q} className={"q" + (open === i ? " open" : "")} onClick={() => setOpen(open === i ? -1 : i)}>
            <div className="q-h">
              <h4>{q}</h4>
              <div className="q-toggle">+</div>
            </div>
            <div className="q-a">{a}</div>
          </div>
        ))}
      </div>
    </section>
  );
}

// ---------- FOOTER ----------
function Footer({ t }) {
  return (
    <footer>
      <div className="ft-wrap">
        <div className="ft-big">
          PRINT. BURN. <em>REPEAT.</em>
        </div>
        <div className="ft-rows">
          <div className="ft-col">
            <b>{t.ticker}</b>
            <a href="#how">How it works</a>
            <a href="#ledger">Ledger</a>
            <a href="#roadmap">Roadmap</a>
            <a href="#buy">Buy</a>
          </div>
          <div className="ft-col">
            <b>Resources</b>
            <a href="#">Whitepaper</a>
            <a href="#">Audit report</a>
            <a href="#">Contract</a>
            <a href="#">Explorer</a>
          </div>
          <div className="ft-col">
            <b>Community</b>
            <a href="#">Twitter / X</a>
            <a href="#">Telegram</a>
            <a href="#">Discord</a>
            <a href="#">Farcaster</a>
          </div>
          <div className="ft-col" style={{ maxWidth: 280 }}>
            <b>Status</b>
            <span style={{ color: "var(--accent)" }}>● Buyback engine nominal</span>
            <span className="mono" style={{ fontSize: 11 }}>BLOCK 8,421,904</span>
            <span className="mono" style={{ fontSize: 11 }}>UPTIME 100.00%</span>
          </div>
        </div>
        <div className="disclaim">
          {t.ticker} is a memecoin. Crypto is volatile. You can lose everything you put into it.
          Nothing on this page is financial advice. The buyback mechanism is enforced by code, not by us —
          verify the contract before you trade. By interacting with {t.ticker} you accept that code is law,
          and that memes are, occasionally, infrastructure.
        </div>
      </div>
    </footer>
  );
}

// ---------- APP ----------
function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

  // apply tweaked accent color
  useEffect(() => {
    document.documentElement.style.setProperty("--accent", t.accentColor);
  }, [t.accentColor]);

  return (
    <>
      <Nav t={t} />
      <Hero t={t} />
      <TickerBar t={t} />
      <Mechanism t={t} />
      <Banner t={t} />
      <StatsAndLedger t={t} />
      <Roadmap t={t} />
      <Buy t={t} />
      <FAQ t={t} />
      <Footer t={t} />

      <TweaksPanel>
        <TweakSection label="Token" />
        <TweakText label="Ticker" value={t.ticker} onChange={(v) => setTweak("ticker", v.toUpperCase().slice(0, 6))} />
        <TweakSlider label="Trade fee" value={t.feePercent} min={1} max={10} step={0.5} unit="%"
          onChange={(v) => setTweak("feePercent", v)} />
        <TweakSlider label="→ Buyback split" value={t.buybackSplit} min={30} max={100} step={5} unit="%"
          onChange={(v) => setTweak("buybackSplit", v)} />

        <TweakSection label="Theme" />
        <TweakColor label="Accent" value={t.accentColor} onChange={(v) => setTweak("accentColor", v)} />
        <TweakRadio label="Preset"
          value={t.accentColor}
          options={["#1fae5a", "#d9431f", "#2d6cff", "#e4a000", "#121210"]}
          onChange={(v) => setTweak("accentColor", v)} />

        <TweakSection label="Motion" />
        <TweakToggle label="Live hero ticker" value={t.liveTicker}
          onChange={(v) => setTweak("liveTicker", v)} />
      </TweaksPanel>
    </>
  );
}

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