/* SendIt landing page — Option C: dark mode primary + coral accents */
const { useState, useEffect, useRef } = React;
const SENDIT_BASE_URL = "https://www.sendit.money";

/* ===== Logo wordmark ===== */
function Wordmark({ size = 22 }) {
  return (
    <div style={{ display: "inline-flex", alignItems: "center", gap: size * 0.36 }}>
      <img src="assets/logo-mark-white.png" alt="" style={{ height: size * 1.05, width: "auto" }} />
      <span style={{
        fontFamily: "'General Sans', system-ui, sans-serif",
        fontSize: size, lineHeight: 1, letterSpacing: "-0.035em", color: "#fff",
      }}>
        <span style={{ fontWeight: 700 }}>send</span>
        <span style={{ fontWeight: 500, opacity: 0.92 }}>it</span>
      </span>
    </div>
  );
}

/* ===== Lucide-style icons ===== */
const Icon = ({ name, size = 20, stroke = 1.6, color = "currentColor" }) => {
  const paths = {
    send: <><path d="M22 2L11 13"/><path d="M22 2l-7 20-4-9-9-4 20-7z"/></>,
    "trending-up": <><polyline points="22 7 13.5 15.5 8.5 10.5 2 17"/><polyline points="16 7 22 7 22 13"/></>,
    card: <><rect x="2" y="5" width="20" height="14" rx="3"/><path d="M2 10h20"/></>,
    "piggy-bank": <><path d="M19 5c-1.5 0-2.8 1.4-3 2-3.5-1.5-7.5 0-9 2-1.5 1.5-2 3-2 4.5 0 1 .5 2 1.5 2.5l1.5.5v2c0 .8.7 1.5 1.5 1.5h2c.8 0 1.5-.7 1.5-1.5V19h3v.5c0 .8.7 1.5 1.5 1.5h2c.8 0 1.5-.7 1.5-1.5V17c1-.7 1.7-1.4 2-2.5h1.5c.3 0 .5-.2.5-.5v-3c0-.3-.2-.5-.5-.5H21c-.3-1-.7-2-1.5-3 .5-1 .5-2.5-.5-2.5z"/></>,
    arrow: <><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></>,
    "arrow-down": <><path d="M12 5v14"/><path d="m19 12-7 7-7-7"/></>,
    check: <><path d="M20 6 9 17l-5-5"/></>,
    x: <><path d="M18 6 6 18"/><path d="m6 6 12 12"/></>,
    plus: <><path d="M12 5v14"/><path d="M5 12h14"/></>,
    minus: <><path d="M5 12h14"/></>,
    bolt: <><path d="M13 2 3 14h7l-1 8 10-12h-7l1-8z"/></>,
    download: <><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></>,
    sparkles: <><path d="M12 3l1.9 5.6L19.5 10l-5.6 1.4L12 17l-1.9-5.6L4.5 10l5.6-1.4z"/><path d="M19 17l.7 2L22 19.7 20 20.4 19 22l-.7-2L16 19.3l2-.7z"/></>,
    globe: <><circle cx="12" cy="12" r="10"/><path d="M2 12h20"/><path d="M12 2a15 15 0 0 1 0 20"/><path d="M12 2a15 15 0 0 0 0 20"/></>,
    menu: <><path d="M4 6h16"/><path d="M4 12h16"/><path d="M4 18h16"/></>,
    "chevron-r": <><path d="m9 18 6-6-6-6"/></>,
    pin: <><path d="M12 22s-7-7.58-7-13a7 7 0 0 1 14 0c0 5.42-7 13-7 13z"/><circle cx="12" cy="9" r="2.5"/></>,
  };
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
      stroke={color} strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round">
      {paths[name] || null}
    </svg>
  );
};

/* ===== Cycling destination text ===== */
const DESTINATIONS = [
  { flag: "🌍", city: "Anywhere" },
  { flag: "🇮🇳", city: "India" },
  { flag: "🇳🇬", city: "Nigeria" },
  { flag: "🇵🇰", city: "Pakistan" },
  { flag: "🇻🇳", city: "Vietnam" },
  { flag: "🇮🇩", city: "Indonesia" },
  { flag: "🇹🇭", city: "Thailand" },
  { flag: "🇵🇭", city: "Philippines" },
  { flag: "🇰🇪", city: "Kenya" },
  { flag: "🇧🇷", city: "Brazil" },
  { flag: "🇬🇭", city: "Ghana" },
  { flag: "🇧🇩", city: "Bangladesh" },
  { flag: "🇱🇰", city: "Sri Lanka" },
  { flag: "🇪🇬", city: "Egypt" },
  { flag: "🇲🇽", city: "Mexico" },
  { flag: "🇨🇴", city: "Colombia" },
  { flag: "🇵🇪", city: "Peru" },
  { flag: "🇹🇷", city: "Türkiye" },
  { flag: "🇲🇦", city: "Morocco" },
  { flag: "🇿🇦", city: "South Africa" },
  { flag: "🇹🇿", city: "Tanzania" },
  { flag: "🇪🇹", city: "Ethiopia" },
  { flag: "🇳🇵", city: "Nepal" },
  { flag: "🇰🇭", city: "Cambodia" },
  { flag: "🇺🇬", city: "Uganda" },
  { flag: "🇸🇳", city: "Senegal" },
  { flag: "🇦🇷", city: "Argentina" },
];

function formatJoinDate(value) {
  try {
    return new Date(value).toLocaleDateString("en-GB", {
      day: "numeric",
      month: "short",
      year: "numeric",
    });
  } catch {
    return value;
  }
}

function getReferralCodeFromUrl() {
  try {
    const params = new URLSearchParams(window.location.search);
    return (params.get("ref") || "").trim().toUpperCase();
  } catch {
    return "";
  }
}

function CyclingDestination() {
  const [i, setI] = useState(0);
  const [animKey, setAnimKey] = useState(0);
  useEffect(() => {
    // Hold the first destination for ~3000ms on first paint, then cycle every 2200ms.
    let interval;
    const firstTimeout = setTimeout(() => {
      setI(v => (v + 1) % DESTINATIONS.length);
      setAnimKey(k => k + 1);
      interval = setInterval(() => {
        setI(v => (v + 1) % DESTINATIONS.length);
        setAnimKey(k => k + 1);
      }, 2200);
    }, 3000);
    return () => {
      clearTimeout(firstTimeout);
      if (interval) clearInterval(interval);
    };
  }, []);
  const d = DESTINATIONS[i];
  return (
    <span className="cycle">
      <span key={animKey} className="cycle-item cycle-item-active">
        <span className="cycle-flag">{d.flag}</span>
        <span className="cycle-city">{d.city}</span>
      </span>
    </span>
  );
}

/* ===== Speed-line motif (coral, decorative) ===== */
function SpeedLines({ opacity = 1, scale = 1, style }) {
  return (
    <div className="speedlines" style={{ opacity, transform: `scale(${scale})`, ...style }}>
      <span style={{ width: 220 }} />
      <span style={{ width: 140, opacity: 0.6 }} />
      <span style={{ width: 70, opacity: 0.32 }} />
    </div>
  );
}

/* ===== iPhone device mockup (used in section 2) ===== */
function IPhoneFrame({ children }) {
  return (
    <div className="iphone">
      <div className="iphone-side iphone-side-l">
        <span style={{ top: "16%", height: "6%" }} />
        <span style={{ top: "26%", height: "11%" }} />
        <span style={{ top: "39%", height: "11%" }} />
      </div>
      <div className="iphone-side iphone-side-r">
        <span style={{ top: "22%", height: "13%" }} />
      </div>
      <div className="iphone-frame">
        <div className="iphone-screen">
          <div className="iphone-island" />
          <div className="iphone-status">
            <span className="num">9:41</span>
            <span className="iphone-status-r">
              <svg width="16" height="11" viewBox="0 0 16 11" fill="currentColor"><path d="M1 7h2v3H1zM4.5 5.5h2V10h-2zM8 4h2v6H8zM11.5 2.5h2V10h-2z"/></svg>
              <svg width="14" height="11" viewBox="0 0 14 11" fill="none" stroke="currentColor" strokeWidth="1"><path d="M.5 4.5C2.5 2.5 5 1.5 7 1.5s4.5 1 6.5 3"/><path d="M2.5 6.5C4 5 5.5 4.5 7 4.5s3 .5 4.5 2"/><circle cx="7" cy="9" r="1" fill="currentColor"/></svg>
              <svg width="24" height="11" viewBox="0 0 24 11" fill="none"><rect x="0.5" y="1" width="20" height="9" rx="2" stroke="currentColor" strokeOpacity="0.5"/><rect x="2" y="2.5" width="16" height="6" rx="1" fill="currentColor"/><rect x="21" y="3.5" width="1.5" height="4" rx="0.5" fill="currentColor" fillOpacity="0.5"/></svg>
            </span>
          </div>
          {children}
        </div>
      </div>
    </div>
  );
}

/* ===== Phone screens for the Stage ===== */

/* Screen 01 — Receipt / The $0 */
function ScreenZero() {
  return (
    <div className="scr scr-zero">
      <div className="scr-head">Transfer complete</div>
      <div className="scr-receipt-card">
        <div className="scr-rc-row">
          <div className="scr-rc-lbl">You sent</div>
          <div className="scr-rc-amt num">$1,000</div>
        </div>
        <div className="scr-rc-arrow"><Icon name="arrow-down" size={16} color="#FF5B47" /></div>
        <div className="scr-rc-row">
          <div className="scr-rc-lbl">Priya gets</div>
          <div className="scr-rc-amt num coral">$1,000</div>
        </div>
      </div>
      <div className="scr-strip">
        <span className="num">$0 fee</span>
        <span className="scr-strip-sep" />
        <span className="num">Arrived in 2.4s</span>
        <span className="scr-strip-sep" />
        <span>Real rate</span>
      </div>
      <div className="scr-noes">
        <div className="scr-no"><span className="scr-no-ic"><Icon name="x" size={11} color="#FF5B47" stroke={2.4} /></span><span>No fees</span></div>
        <div className="scr-no"><span className="scr-no-ic"><Icon name="x" size={11} color="#FF5B47" stroke={2.4} /></span><span>No margin</span></div>
        <div className="scr-no"><span className="scr-no-ic"><Icon name="x" size={11} color="#FF5B47" stroke={2.4} /></span><span>No money lost</span></div>
      </div>
    </div>
  );
}

/* Screen 02 — Send / recipient search */
function ScreenSend() {
  const matches = [
    { name: "Priya Patel",  handle: "@priyapatel" },
    { name: "Priya Sharma", handle: "@priya.s"    },
    { name: "Priya Nair",   handle: "@priyanair"  },
    { name: "Priya Kapoor", handle: "@priyakap"   },
  ];
  return (
    <div className="scr scr-send">
      <div className="scr-send-hdr">
        <span className="scr-back" aria-hidden="true">
          <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="m15 18-6-6 6-6"/></svg>
        </span>
        <span className="scr-send-title">Send</span>
        <span className="scr-back scr-back-ghost" />
      </div>
      <div className="scr-send-lbl">Send to</div>
      <div className="scr-search">
        <svg className="scr-search-ic" width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="11" cy="11" r="7"/><path d="m20 20-3-3"/></svg>
        <span className="scr-search-txt">Priya</span>
        <span className="scr-search-cursor" aria-hidden="true" />
      </div>
      <div className="scr-results">
        {matches.map((m, i) => (
          <div key={m.handle} className={"scr-result" + (i === 0 ? " is-selected" : "")}>
            <span className="scr-result-av">P</span>
            <div className="scr-result-mid">
              <div className="scr-result-name">{m.name}</div>
              <div className="scr-result-handle">{m.handle}</div>
            </div>
            <span className="scr-result-flag">🇮🇳</span>
          </div>
        ))}
      </div>
      <div className="scr-send-foot">
        <div className="scr-arrives num">Arrives in 2.4s · $0 fee</div>
        <button className="scr-send-btn">Continue <Icon name="arrow" size={12} /></button>
      </div>
    </div>
  );
}

/* Screen 03 — Spend / Home */
function ScreenSpend() {
  return (
    <div className="scr scr-spend">
      <div className="scr-topbar">
        <span className="scr-av">A</span>
        <span className="scr-topbar-icon" aria-hidden="true">
          <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/></svg>
        </span>
      </div>
      <div className="scr-balance">
        <div className="scr-balance-lbl">Cash Balance</div>
        <div className="scr-balance-num num">$4,128.50</div>
        <div className="scr-balance-sub num">
          <svg width="9" height="9" viewBox="0 0 24 24" fill="none" stroke="#FF5B47" strokeWidth="2.2" strokeLinecap="round"><path d="M3 20h18"/><path d="M6 20V11"/><path d="M11 20V7"/><path d="M16 20v-5"/></svg>
          <span>$182 in Savings</span>
          <svg width="8" height="8" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="m9 18 6-6-6-6"/></svg>
        </div>
      </div>
      <div className="scr-actions">
        <button className="scr-act scr-act-prim">+ Add Cash</button>
        <button className="scr-act scr-act-sec">Send</button>
      </div>
      <div className="scr-card-visual">
        <div className="scv-sheen" aria-hidden="true" />
        <div className="scv-top">
          <span className="scv-brand"><Wordmark size={11} /></span>
          <span className="scv-chip" aria-hidden="true" />
        </div>
        <div className="scv-mid">
          <div className="scv-amt num">
            $1,000.00 <span className="scv-amt-dot" />
          </div>
          <div className="scv-amt-lbl">Card balance</div>
        </div>
        <div className="scv-bottom">
          <div className="scv-cardno num">•••• 4209</div>
          <div className="scv-exp num">12/29</div>
        </div>
      </div>
      <div className="scr-txns">
        <div className="scr-txn">
          <span className="scr-txn-ic scr-txn-ic-bag">
            <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M6 2 3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4Z"/><path d="M3 6h18"/><path d="M16 10a4 4 0 0 1-8 0"/></svg>
          </span>
          <div className="scr-txn-mid">
            <div className="scr-txn-name">Coffee · Joe's</div>
            <div className="scr-txn-date">May 10</div>
          </div>
          <div className="scr-txn-right">
            <div className="scr-txn-amt num">-$4.50</div>
            <div className="scr-txn-cb num">+$0.09 <span className="scr-txn-tok" /></div>
          </div>
        </div>
        <div className="scr-txn-div" />
        <div className="scr-txn">
          <span className="scr-txn-ic scr-txn-ic-fork">
            <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M3 2v7a3 3 0 0 0 6 0V2"/><path d="M6 9v13"/><path d="M18 2v20"/><path d="M15 2v7c0 1.5 1 3 3 3"/></svg>
          </span>
          <div className="scr-txn-mid">
            <div className="scr-txn-name">Tesco · Groceries</div>
            <div className="scr-txn-date">May 9</div>
          </div>
          <div className="scr-txn-right">
            <div className="scr-txn-amt num">-$32.10</div>
            <div className="scr-txn-cb num">+$0.64 <span className="scr-txn-tok" /></div>
          </div>
        </div>
      </div>
    </div>
  );
}

/* Screen 04 — Markets / Trade */
function TickerGlyph({ sym }) {
  // Inline white glyph centred on the brand-coloured circle.
  switch (sym) {
    case "AAPL":
      return (
        <svg viewBox="0 0 24 24" fill="#fff" aria-hidden="true">
          <path d="M17.05 20.28c-.98.95-2.05.8-3.08.35-1.09-.46-2.09-.48-3.24 0-1.44.62-2.2.44-3.06-.35C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z"/>
        </svg>
      );
    case "ETH":
      return (
        <svg viewBox="0 0 24 24" fill="#fff" aria-hidden="true">
          <path d="M12 2L4.5 13.2l7.5 4.4 7.5-4.4L12 2z" opacity="0.75"/>
          <path d="M12 18.8L4.5 14.4 12 22l7.5-7.6L12 18.8z"/>
        </svg>
      );
    case "BTC":
      return <span className="scr-tok-letter scr-tok-letter-btc">₿</span>;
    case "NVDA":
      return <span className="scr-tok-letter">N</span>;
    case "SPX":
      return <span className="scr-tok-letter scr-tok-letter-sm">S&amp;P</span>;
    case "HYPE":
      return <span className="scr-tok-letter">H</span>;
    case "GOLD":
      return <span className="scr-tok-letter scr-tok-letter-sm">Au</span>;
    default:
      return <span className="scr-tok-letter">{sym.charAt(0)}</span>;
  }
}

function ScreenTrade() {
  const holdings = [
    { sym: "NVDA", name: "Nvidia",      price: "$1,142.80", pct: "+4.21%", bg: "#76B900" },
    { sym: "AAPL", name: "Apple",       price: "$248.62",   pct: "+1.34%", bg: "#1D1D1F" },
    { sym: "SPX",  name: "S&P 500",     price: "$5,842.10", pct: "+0.42%", bg: "#1B365D" },
    { sym: "BTC",  name: "Bitcoin",     price: "$96,140",   pct: "+1.82%", bg: "#F7931A" },
    { sym: "ETH",  name: "Ethereum",    price: "$3,420.50", pct: "+0.86%", bg: "#627EEA" },
    { sym: "HYPE", name: "Hyperliquid", price: "$28.40",    pct: "+6.12%", bg: "#07A78A" },
    { sym: "GOLD", name: "Gold",        price: "$2,684.10", pct: "+0.42%", bg: "#C9A36A" },
  ];
  return (
    <div className="scr scr-trade">
      <div className="scr-trade-hdr">
        <span className="scr-back" aria-hidden="true">
          <svg width="9" height="9" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="m15 18-6-6 6-6"/></svg>
        </span>
        <span className="scr-trade-title">Markets</span>
        <span className="scr-trade-hdr-spacer" aria-hidden="true" />
      </div>

      <div className="scr-portfolio">
        <div className="scr-portfolio-val num">$2,341.18</div>
        <div className="scr-portfolio-lbl">Portfolio value</div>
      </div>

      <div className="scr-holdings">
        {holdings.map(h => (
          <div key={h.sym} className="scr-hold">
            <span className="scr-tok-circle" style={{ background: h.bg }}>
              <TickerGlyph sym={h.sym} />
            </span>
            <div className="scr-hold-meta">
              <div className="scr-hold-sym">{h.sym}</div>
              <div className="scr-hold-name">{h.name}</div>
            </div>
            <div className="scr-hold-r">
              <div className="scr-hold-price num">{h.price}</div>
              <div className="scr-hold-pct num">{h.pct}</div>
            </div>
          </div>
        ))}
      </div>

      <div className="scr-trade-foot">
        <button className="scr-trade-buy">Buy</button>
        <button className="scr-trade-sell">Sell</button>
      </div>
    </div>
  );
}

/* Screen 05 — Savings / Save */
function ScreenSave() {
  // 22 bars increasing from left to right (compound growth-style curve).
  const bars = Array.from({ length: 22 }, (_, i) => {
    const t = i / 21;
    const h = 4 + Math.pow(t, 1.55) * 26; // 4 -> 30px range
    return { x: i * 4.5, h };
  });
  return (
    <div className="scr scr-save">
      <div className="scr-topbar">
        <span className="scr-av">A</span>
        <span className="scr-topbar-help" aria-hidden="true">?</span>
      </div>

      <div className="scr-earn">
        <div className="scr-earn-lbl">Earn Balance</div>
        <div className="scr-earn-num num">$5,420.18</div>
        <div className="scr-earn-apy num">
          <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="#FF5B47" strokeWidth="2.4" strokeLinecap="round"><path d="M3 20h18"/><path d="M6 20V11"/><path d="M11 20V7"/><path d="M16 20v-5"/></svg>
          <span>5.20% APY</span>
        </div>
      </div>

      <button className="scr-earn-cta">Start Earning</button>
      <div className="scr-earn-reassure">
        <svg width="9" height="9" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/><path d="m9 16 6 6"/><path d="m15 16-6 6"/></svg>
        <span>Withdraw anytime. No lockup.</span>
      </div>

      <div className="scr-sim">
        <div className="scr-sim-top">
          <span className="scr-sim-title">Simulate Earnings</span>
          <span className="scr-sim-step">
            <span className="scr-sim-step-btn">−</span>
            <span className="scr-sim-step-val num">$10,000.00</span>
            <span className="scr-sim-step-btn">+</span>
          </span>
        </div>
        <div className="scr-sim-div" />
        <div className="scr-sim-lbl">You would earn</div>
        <div className="scr-sim-num num">$520.00</div>
        <svg className="scr-sim-chart" viewBox="0 0 100 32" preserveAspectRatio="none">
          {bars.map((b, i) => (
            <rect key={i} x={b.x} y={32 - b.h} width="3" height={b.h} rx="0.6" fill="#FF5B47" />
          ))}
        </svg>
        <div className="scr-sim-tabs">
          <span>Day</span>
          <span>Week</span>
          <span>Month</span>
          <span className="is-active">Year</span>
        </div>
      </div>
    </div>
  );
}

/* ===== Number ticker (animated up on view) ===== */
function CountUp({ to, prefix = "", suffix = "", duration = 1600, incrementing = false, onDone, pulseOnDone = false }) {
  const [n, setN] = useState(0);
  const [done, setDone] = useState(false);
  const [floaters, setFloaters] = useState([]);
  const [pulse, setPulse] = useState(false);
  const ref = useRef(null);
  const started = useRef(false);
  const incTimer = useRef(null);

  useEffect(() => {
    const reduce = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting && !started.current) {
        started.current = true;
        if (reduce) {
          setN(to);
          setDone(true);
          if (pulseOnDone) { setPulse(true); setTimeout(() => setPulse(false), 900); }
          if (onDone) onDone();
          return;
        }
        const start = performance.now();
        const tick = (now) => {
          const p = Math.min(1, (now - start) / duration);
          const eased = 1 - Math.pow(1 - p, 3);
          setN(Math.round(to * eased));
          if (p < 1) requestAnimationFrame(tick);
          else {
            setDone(true);
            if (pulseOnDone) { setPulse(true); setTimeout(() => setPulse(false), 900); }
            if (onDone) onDone();
          }
        };
        requestAnimationFrame(tick);
      }
    }, { threshold: 0.3 });
    if (ref.current) io.observe(ref.current);
    return () => io.disconnect();
  }, [to, duration, onDone, pulseOnDone]);

  useEffect(() => {
    if (!incrementing || !done) return;
    const reduce = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    if (reduce) return;
    const schedule = () => {
      const delay = 3000 + Math.random() * 2000;
      incTimer.current = setTimeout(() => {
        setN(v => v + 1);
        const id = Date.now() + Math.random();
        setFloaters(f => [...f, { id }]);
        setTimeout(() => setFloaters(f => f.filter(x => x.id !== id)), 750);
        schedule();
      }, delay);
    };
    schedule();
    return () => { if (incTimer.current) clearTimeout(incTimer.current); };
  }, [incrementing, done]);

  return (
    <span ref={ref} className={"num count-wrap" + (pulse ? " count-pulse" : "")}>
      {prefix}{n.toLocaleString("en-GB")}{suffix}
      {incrementing && floaters.map(f => (
        <span key={f.id} className="count-floater">+1</span>
      ))}
    </span>
  );
}

/* ===== Waitlist flow ===== */
function WaitlistModal({ onClose, initialEmail = "", initialSource = null }) {
  const [email, setEmail] = useState(initialEmail);
  const [referralCode, setReferralCode] = useState(getReferralCodeFromUrl());
  const [submitted, setSubmitted] = useState(false);
  const [alreadyRegistered, setAlreadyRegistered] = useState(false);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [submitError, setSubmitError] = useState(null);
  const [submitNote, setSubmitNote] = useState(null);
  const [temporaryUsername, setTemporaryUsername] = useState("");
  const [issuedReferralCode, setIssuedReferralCode] = useState("");
  const [shareUrl, setShareUrl] = useState("");
  const [leaderboardUrl, setLeaderboardUrl] = useState("/leaderboard");
  const [copied, setCopied] = useState(false);
  const inputRef = useRef(null);

  useEffect(() => {
    const onKey = (e) => {
      if (e.key === "Escape") {
        onClose();
        return;
      }
      if (e.key !== "Tab") return;
      const dialog = inputRef.current?.closest('[role="dialog"]');
      if (!dialog) return;
      const focusables = dialog.querySelectorAll(
        'button:not([disabled]), input:not([disabled]), a[href]'
      );
      if (!focusables.length) return;
      const first = focusables[0];
      const last = focusables[focusables.length - 1];
      if (e.shiftKey && document.activeElement === first) {
        e.preventDefault();
        last.focus();
      } else if (!e.shiftKey && document.activeElement === last) {
        e.preventDefault();
        first.focus();
      }
    };

    document.addEventListener("keydown", onKey);
    const prevOverflow = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    inputRef.current?.focus();

    return () => {
      document.removeEventListener("keydown", onKey);
      document.body.style.overflow = prevOverflow;
    };
  }, [onClose]);

  const copyReferralLink = async () => {
    if (!shareUrl) return;
    try {
      await navigator.clipboard.writeText(shareUrl);
      setCopied(true);
      setTimeout(() => setCopied(false), 1800);
    } catch {
      setSubmitNote("Referral link ready, but this browser blocked clipboard access.");
    }
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    const normalizedEmail = email.trim();
    if (!normalizedEmail || isSubmitting) return;

    setIsSubmitting(true);
    setSubmitError(null);
    setSubmitNote(null);

    try {
      const response = await fetch("/api/waitlist", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          email: normalizedEmail,
          referralCode: referralCode.trim() || undefined,
          source: initialSource,
          pagePath: window.location.pathname,
        }),
      });

      const payload = await response.json().catch(() => null);
      if (!response.ok) {
        throw new Error(payload?.error || "Unable to submit right now. Please try again.");
      }

      setAlreadyRegistered(Boolean(payload?.alreadyRegistered));
      setTemporaryUsername(payload?.temporaryUsername || "");
      setIssuedReferralCode(payload?.referralCode || "");
      setShareUrl(payload?.shareUrl || "");
      setLeaderboardUrl(payload?.leaderboardUrl || "/leaderboard");
      setSubmitNote(payload?.warning || null);
      setSubmitted(true);
    } catch (error) {
      setSubmitError(error instanceof Error ? error.message : "Unable to submit right now. Please try again.");
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div
        className="modal modal-waitlist-upgrade"
        role="dialog"
        aria-modal="true"
        aria-labelledby="ea-title"
        onClick={(e) => e.stopPropagation()}
      >
        <button className="modal-close" onClick={onClose} aria-label="Close">
          <Icon name="x" size={18} />
        </button>

        {!submitted ? (
          <>
            <div className="modal-eyebrow">
              <Icon name="sparkles" size={14} color="#FF5B47" />
              <span>Early bird waitlist</span>
            </div>
            <h3 id="ea-title" className="modal-title">Get early access.</h3>
            <p className="modal-sub">
              Enter your email and we'll add you to the SendIt waitlist. If a friend referred you,
              drop their code in too so they move up the board.
            </p>
            <form className="modal-stack" onSubmit={handleSubmit}>
              <input
                ref={inputRef}
                type="email"
                required
                placeholder="you@email.com"
                value={email}
                onChange={(e) => setEmail(e.target.value)}
              />
              <div className="modal-referral-block">
                <p className="modal-referral-label">Referral code (optional)</p>
                <input
                  type="text"
                  value={referralCode}
                  onChange={(e) => setReferralCode(e.target.value.toUpperCase())}
                  placeholder="SIT-XXXXXXXX"
                />
              </div>
              <button className="btn-coral modal-submit" type="submit" disabled={isSubmitting}>
                {isSubmitting ? "Submitting..." : "Submit"}
              </button>
            </form>
            {submitError && <p className="modal-error">{submitError}</p>}
            <p className="modal-fine">
              By joining you agree to our terms and privacy policy.
            </p>
          </>
        ) : (
          <>
            <div className="modal-success-icon">
              <Icon name="check" size={28} color="#FF5B47" stroke={2.4} />
            </div>
            <h3 id="ea-title" className="modal-title">
              {alreadyRegistered ? "You're already on the waitlist." : "Congrats, you're on the waitlist."}
            </h3>
            <p className="modal-sub">
              {alreadyRegistered
                ? `We already have ${email} on file.`
                : `We'll email ${email} with your early-access updates and referral link.`}
            </p>

            {(temporaryUsername || issuedReferralCode) && (
              <div className="modal-detail-card">
                {temporaryUsername && (
                  <div className="modal-detail-row">
                    <span>Temporary username</span>
                    <strong>{temporaryUsername}</strong>
                  </div>
                )}
                {issuedReferralCode && (
                  <div className="modal-detail-row">
                    <span>Referral code</span>
                    <strong>{issuedReferralCode}</strong>
                  </div>
                )}
              </div>
            )}

            <div className="modal-actions">
              {shareUrl && (
                <button className="btn-ghost modal-action-btn" type="button" onClick={copyReferralLink}>
                  {copied ? "Copied link" : "Copy referral link"}
                </button>
              )}
              <a className="btn-ghost modal-action-btn" href={leaderboardUrl}>
                View leaderboard
              </a>
            </div>

            {submitNote && <p className="modal-note">{submitNote}</p>}
            <button className="btn-coral modal-done" onClick={onClose}>Done</button>
          </>
        )}
      </div>
    </div>
  );
}

function ShareReferralPage() {
  const [copied, setCopied] = useState(false);
  const [shareError, setShareError] = useState(null);
  const referralCode = getReferralCodeFromUrl();
  const searchParams = new URLSearchParams(window.location.search);
  const shouldAutoShare = searchParams.get("auto") === "1";
  const referralLink = referralCode ? `${SENDIT_BASE_URL}/?ref=${encodeURIComponent(referralCode)}` : `${SENDIT_BASE_URL}/`;
  const shareMessage = "I just joined the SendIt waitlist. Use my referral link to move up the leaderboard too:";
  const shareBody = `${shareMessage}\n${referralLink}`;

  const shareNow = async () => {
    if (!referralCode) return;
    setShareError(null);

    if (typeof navigator !== "undefined" && typeof navigator.share === "function") {
      try {
        await navigator.share({
          title: "Join me on the SendIt waitlist",
          text: shareMessage,
          url: referralLink,
        });
        return;
      } catch {
        // Fall through to clipboard below if the share sheet is dismissed.
      }
    }

    try {
      await navigator.clipboard.writeText(shareBody);
      setCopied(true);
      setTimeout(() => setCopied(false), 1800);
    } catch {
      setShareError("Unable to open share options on this device. Use the social buttons below.");
    }
  };

  useEffect(() => {
    if (!shouldAutoShare || !referralCode) return;
    void shareNow();
  }, []);

  const xShareUrl = `https://twitter.com/intent/tweet?text=${encodeURIComponent(shareBody)}`;
  const whatsappShareUrl = `https://wa.me/?text=${encodeURIComponent(shareBody)}`;
  const telegramShareUrl = `https://t.me/share/url?url=${encodeURIComponent(referralLink)}&text=${encodeURIComponent(shareMessage)}`;
  const linkedinShareUrl = `https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(referralLink)}`;
  const emailShareUrl = `mailto:?subject=${encodeURIComponent("Join me on the SendIt waitlist")}&body=${encodeURIComponent(shareBody)}`;

  return (
    <main className="route-page">
      <div className="container">
        <section className="route-shell">
          <a className="route-home" href="/">Back to SendIt</a>
          <p className="route-kicker">Share referral</p>
          <h1 className="route-title">Invite friends to SendIt.</h1>
          <p className="route-copy">
            Share your waitlist link and help people skip the usual remittance fees with you.
          </p>

          {!referralCode ? (
            <div className="route-panel">
              <p className="route-copy route-copy-tight">
                This referral link is missing a code. Open the link from your waitlist confirmation again.
              </p>
              <a className="btn-ghost modal-action-btn" href="/leaderboard">Open leaderboard</a>
            </div>
          ) : (
            <>
              <div className="route-panel">
                <div className="modal-detail-row">
                  <span>Referral code</span>
                  <strong>{referralCode}</strong>
                </div>
                <div className="modal-detail-row modal-detail-row-break">
                  <span>Referral link</span>
                  <strong>{referralLink}</strong>
                </div>
              </div>

              <div className="route-actions">
                <button className="btn-coral modal-action-btn" type="button" onClick={() => void shareNow()}>
                  Share now
                </button>
                <button
                  className="btn-ghost modal-action-btn"
                  type="button"
                  onClick={async () => {
                    try {
                      await navigator.clipboard.writeText(referralLink);
                      setCopied(true);
                      setTimeout(() => setCopied(false), 1800);
                    } catch {
                      setShareError("Unable to copy link on this device.");
                    }
                  }}
                >
                  {copied ? "Copied" : "Copy link"}
                </button>
              </div>

              <div className="route-socials">
                <a href={xShareUrl} target="_blank" rel="noreferrer">X</a>
                <a href={whatsappShareUrl} target="_blank" rel="noreferrer">WhatsApp</a>
                <a href={telegramShareUrl} target="_blank" rel="noreferrer">Telegram</a>
                <a href={linkedinShareUrl} target="_blank" rel="noreferrer">LinkedIn</a>
                <a href={emailShareUrl}>Email</a>
              </div>
            </>
          )}

          {shareError && <p className="modal-error route-error">{shareError}</p>}
        </section>
      </div>
    </main>
  );
}

function LeaderboardPage({ onEarlyAccess }) {
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(null);
  const [rows, setRows] = useState([]);
  const [totalSignups, setTotalSignups] = useState(0);
  const [topReferrals, setTopReferrals] = useState(0);

  useEffect(() => {
    let cancelled = false;

    const load = async () => {
      try {
        const response = await fetch("/api/leaderboard");
        const payload = await response.json().catch(() => null);
        if (!response.ok) {
          throw new Error(payload?.error || "Unable to load leaderboard.");
        }
        if (cancelled) return;
        setRows(payload?.rows || []);
        setTotalSignups(payload?.totalSignups || 0);
        setTopReferrals(payload?.topReferrals || 0);
        setError(null);
      } catch (nextError) {
        if (cancelled) return;
        setError(nextError instanceof Error ? nextError.message : "Unable to load leaderboard.");
      } finally {
        if (!cancelled) setIsLoading(false);
      }
    };

    void load();
    return () => {
      cancelled = true;
    };
  }, []);

  return (
    <main className="route-page">
      <div className="container">
        <section className="route-shell">
          <a className="route-home" href="/">Back to SendIt</a>
          <p className="route-kicker">Waitlist leaderboard</p>
          <h1 className="route-title">Who’s moving up the line.</h1>
          <p className="route-copy">
            Refer friends, climb the board, and get early access sooner.
          </p>

          <div className="leaderboard-stats">
            <div className="route-panel">
              <p className="leaderboard-stat-label">Total signups</p>
              <p className="leaderboard-stat-value num">{isLoading ? "..." : totalSignups.toLocaleString()}</p>
            </div>
            <div className="route-panel">
              <p className="leaderboard-stat-label">Top referrals</p>
              <p className="leaderboard-stat-value num">{isLoading ? "..." : topReferrals.toLocaleString()}</p>
            </div>
          </div>

          <div className="route-actions route-actions-top">
            <button className="btn-coral modal-action-btn" type="button" onClick={() => onEarlyAccess("Leaderboard")}>
              Join the waitlist
            </button>
          </div>

          <div className="leaderboard-table">
            <div className="leaderboard-head">
              <span>Rank</span>
              <span>Username</span>
              <span>Referrals</span>
              <span>Joined</span>
            </div>

            {isLoading && <div className="leaderboard-empty">Loading leaderboard...</div>}
            {!isLoading && error && <div className="leaderboard-empty leaderboard-error">{error}</div>}
            {!isLoading && !error && !rows.length && <div className="leaderboard-empty">No signups yet. Be the first on the board.</div>}

            {!isLoading && !error && rows.map((row) => (
              <div className="leaderboard-row" key={`${row.rank}-${row.username}`}>
                <span className="num">#{row.rank}</span>
                <span>{row.username}</span>
                <span className="num">{row.referrals}</span>
                <span>{formatJoinDate(row.joinedAt)}</span>
              </div>
            ))}
          </div>
        </section>
      </div>
    </main>
  );
}

/* ===== Sections ===== */
function Nav({ onEarlyAccess }) {
  return (
    <header className="nav">
      <a className="nav-brand" href="#"><Wordmark size={20} /></a>
      <nav className="nav-links">
        <a href="#stage" onClick={(e) => { e.preventDefault(); window.__sendit_stageGoTo?.(1); }}>Send</a>
        <a href="#stage" onClick={(e) => { e.preventDefault(); window.__sendit_stageGoTo?.(2); }}>Spend</a>
        <a href="#stage" onClick={(e) => { e.preventDefault(); window.__sendit_stageGoTo?.(3); }}>Trade</a>
        <a href="#stage" onClick={(e) => { e.preventDefault(); window.__sendit_stageGoTo?.(4); }}>Save</a>
      </nav>
      <div className="nav-right">
        <button className="btn-coral btn-sm" onClick={() => onEarlyAccess("Nav CTA")}>Get early access</button>
      </div>
    </header>
  );
}

function Hero({ onEarlyAccess }) {
  return (
    <section className="hero">
      <div className="hero-bg" />
      <div className="hero-bg-overlay" />
      <div className="hero-glow" aria-hidden="true" />

      <div className="hero-content">
        <h1 className="hero-headline">
          <span className="hl-line hl-1">
            <span className="hl-inner">Send money to</span>
          </span>
          <span className="hl-line hl-2 cycle-line">
            <span className="hl-inner">
              <CyclingDestination />
            </span>
          </span>
          <span className="hl-line hl-3">
            <span className="hl-inner">Pay nothing.</span>
          </span>
        </h1>

        <p className="hero-sub">
          The money app for people whose lives cross borders. The full amount
          arrives, instantly. Spend, trade, or save it on the other side.
        </p>

        <div className="hero-ctas">
          <button className="btn-coral" onClick={() => onEarlyAccess("Hero CTA")}>Get early access <Icon name="arrow" size={18} /></button>
          <button className="btn-ghost" onClick={() => window.__sendit_stageGoTo?.(0)}>See how it works</button>
        </div>
      </div>

    </section>
  );
}

/* ===== Stage — scroll-driven evolving phone section ===== */
const CHAPTERS = [
  {
    id: "zero",
    eyebrow: "01 · The $0",
    title: "What you send is what they get.",
    body: "Your recipient gets the full amount in their SendIt account and chooses what to do with it: spend it, save it, trade it, or withdraw it.",
    Screen: ScreenZero,
    receipt: "$0 fee · Real exchange rate",
    icon: null,
  },
  {
    id: "send",
    eyebrow: "02 · Send",
    title: "Send money home in seconds.",
    body: "Send to anyone across the globe at no extra cost. What you send is what arrives on the other side. Nothing taken off the top. Their money, their call.",
    Screen: ScreenSend,
    receipt: "Sent to Priya · 2.4s ago",
    icon: "arrow",
  },
  {
    id: "spend",
    eyebrow: "03 · Spend",
    title: "One account, every currency. Cashback on every purchase.",
    body: "Spend anywhere your life takes you with your SendIt Visa card. No conversion costs, no hidden fees. Earn cashback every time you tap.",
    Screen: ScreenSpend,
    receipt: "+$0.20 cashback just now",
    icon: "card",
  },
  {
    id: "trade",
    eyebrow: "04 · Trade",
    title: "Own Nvidia, Bitcoin, and more from any amount.",
    body: "Buy crypto and US stocks without a foreign brokerage, without minimums, and without the paperwork. Start with whatever you have.",
    Screen: ScreenTrade,
    receipt: "NVDA +4.21% today",
    icon: "trending-up",
  },
  {
    id: "save",
    eyebrow: "05 · Save",
    title: "Earn dynamic interest on your savings.",
    body: "Your money grows while it sits. Dynamic APY rates that reflect the real market, not a teaser that vanishes after 30 days. No lock-ins, no minimums.",
    Screen: ScreenSave,
    receipt: "+$28.40 this month",
    icon: "piggy-bank",
  },
];

function Stage() {
  const [active, setActive] = useState(0);
  const [isTilting, setIsTilting] = useState(false);
  const sectionRef = useRef(null);
  const dotsRef = useRef(null);
  const phoneWrapRef = useRef(null);
  const prevActiveRef = useRef(0);
  const lastProgressRef = useRef(0);
  const tiltTimerRef = useRef(null);

  useEffect(() => {
    const onScroll = () => {
      const el = sectionRef.current;
      if (!el) return;
      const rect = el.getBoundingClientRect();
      const sectionHeight = rect.height;
      const viewportHeight = window.innerHeight;
      const scrollable = sectionHeight - viewportHeight;
      if (scrollable <= 0) return;
      const progress = Math.max(0, Math.min(1, -rect.top / scrollable));

      // Write progress to CSS var on the dots rail (avoids re-render thrash).
      if (dotsRef.current && Math.abs(progress - lastProgressRef.current) > 0.003) {
        dotsRef.current.style.setProperty("--progress", progress.toFixed(4));
        lastProgressRef.current = progress;
      }

      // Distribute 5 chapters evenly. Cap to 4 to avoid overshoot at progress=1.
      const next = Math.min(4, Math.floor(progress * 5));
      setActive(prev => (prev === next ? prev : next));
    };
    window.addEventListener("scroll", onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener("scroll", onScroll);
  }, []);

  // Phone tilt micro-animation on chapter change.
  useEffect(() => {
    if (prevActiveRef.current === active) return;
    prevActiveRef.current = active;
    const reduce = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    if (reduce) return;
    setIsTilting(true);
    if (tiltTimerRef.current) clearTimeout(tiltTimerRef.current);
    tiltTimerRef.current = setTimeout(() => setIsTilting(false), 620);
    return () => {
      if (tiltTimerRef.current) clearTimeout(tiltTimerRef.current);
    };
  }, [active]);

  const goTo = (i) => {
    const el = sectionRef.current;
    if (!el) return;
    const sectionHeight = el.offsetHeight;
    const viewportHeight = window.innerHeight;
    const scrollable = sectionHeight - viewportHeight;
    // Aim for the middle of the i-th segment so the chapter is comfortably active.
    const segment = scrollable / 5;
    const offsetTop = el.offsetTop + (segment * i) + (segment * 0.5);
    window.scrollTo({ top: offsetTop, behavior: "smooth" });
  };

  // Expose goTo globally so Nav anchors and the hero CTA can drive chapter scrolls
  // without prop-drilling. Cleaned up on unmount.
  useEffect(() => {
    window.__sendit_stageGoTo = goTo;
    return () => {
      if (window.__sendit_stageGoTo === goTo) delete window.__sendit_stageGoTo;
    };
  }, []);

  return (
    <section className="stage" id="stage" ref={sectionRef} aria-label="Everything in one app">
      <div className="stage-sticky">
        <div className="stage-grid container">
          <div className="stage-copy">
            {CHAPTERS.map((ch, i) => (
              <article
                key={ch.id}
                className={"chapter" + (active === i ? " is-active" : "")}
                aria-hidden={active !== i}
              >
                <div className="chapter-eyebrow eyebrow">{ch.eyebrow}</div>
                <h2 className="chapter-title display-lg">{ch.title}</h2>
                <p className="chapter-body">{ch.body}</p>
              </article>
            ))}
          </div>

          <div className="stage-phone-col">
            <div
              ref={phoneWrapRef}
              className={"stage-phone-wrap" + (isTilting ? " is-tilting" : "")}
            >
              <IPhoneFrame>
                {CHAPTERS.map((ch, i) => {
                  const Screen = ch.Screen;
                  // Only mount the previous, current, and next screens. Inactive
                  // screens stay as empty wrappers so the crossfade CSS still
                  // has positioning targets.
                  const shouldMount = Math.abs(active - i) <= 1;
                  return (
                    <div
                      key={ch.id}
                      className={"phone-screen" + (active === i ? " is-active" : "")}
                      aria-hidden={active !== i}
                    >
                      {shouldMount ? <Screen /> : null}
                    </div>
                  );
                })}
                <div className="stage-receipt" aria-live="polite">
                  <span key={active} className="stage-receipt-inner">
                    {CHAPTERS[active].icon ? (
                      <span className="stage-receipt-icon" aria-hidden="true">
                        <Icon name={CHAPTERS[active].icon} size={10} color="#FF5B47" />
                      </span>
                    ) : (
                      <span className="stage-receipt-dot" aria-hidden="true" />
                    )}
                    <span className="stage-receipt-text">{CHAPTERS[active].receipt}</span>
                  </span>
                </div>
              </IPhoneFrame>
            </div>
          </div>
        </div>

        <nav ref={dotsRef} className="stage-dots" aria-label="Chapters" style={{ "--progress": 0 }}>
          {CHAPTERS.map((ch, i) => (
            <button
              key={ch.id}
              type="button"
              className={"stage-dot" + (active >= i ? " is-passed" : "") + (active === i ? " is-active" : "")}
              aria-label={ch.eyebrow}
              aria-current={active === i ? "true" : undefined}
              onClick={() => goTo(i)}
            />
          ))}
        </nav>
      </div>
    </section>
  );
}

function HowItWorks() {
  const steps = [
    { n: "01", title: "Download.", body: "Get the app and set up your account in under two minutes. ID check, done." },
    { n: "02", title: "Top up.", body: "Add money from your bank, card, or a kiosk near you. Over 100,000 in India." },
    { n: "03", title: "Send. Spend. Trade. Save.", body: "All from one place. Real exchange rate. Real instant. Real free." },
  ];
  return (
    <section className="how">
      <div className="container">
        <div className="how-head">
          <div className="eyebrow">06 · How it works</div>
          <h2 className="display-lg" style={{ marginTop: 14 }}>Three steps. That's it.</h2>
        </div>
        <div className="how-grid">
          {steps.map((s, i) => (
            <div key={s.n} className="step">
              <div className="step-num num">{s.n}</div>
              <div className="step-line">{i < steps.length - 1 && <span />}</div>
              <h3 className="step-title">{s.title}</h3>
              <p className="step-body">{s.body}</p>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

function Comparison() {
  const rows = [
    { label: "Transfer fee",    sendit: "Free",    wise: "0.4–1.5%", remitly: "Varies",  bank: "£5–£25" },
    { label: "Lost in transit", sendit: "Nothing", wise: "0.4–0.6%", remitly: "1–3%",    bank: "2–5%" },
    { label: "Speed",           sendit: "Seconds", wise: "Hours",    remitly: "1–3 days", bank: "3–5 days" },
    { label: "Recipient chooses how to use it", sendit: true, wise: false, remitly: false, bank: false },
    { label: "Invest from the same app",        sendit: true, wise: false, remitly: false, bank: false },
  ];

  const Cell = ({ v, hero }) => {
    if (v === true)  return <span className={`cmp-badge cmp-yes ${hero ? "cmp-yes-hero" : ""}`}><Icon name="check" size={12} stroke={2.4} /></span>;
    if (v === false) return <span className="cmp-badge cmp-no"><Icon name="x" size={12} stroke={2.2} /></span>;
    return <span className={hero ? "cmp-val cmp-val-hero num" : "cmp-val num"}>{v}</span>;
  };

  return (
    <section className="compare" id="compare">
      <div className="container">
        <div className="compare-head">
          <div className="eyebrow">07 · The receipts</div>
          <h2 className="display-lg" style={{ marginTop: 14, maxWidth: 880 }}>
            What you actually pay to send money.
          </h2>
        </div>

        <div className="cmp">
          <div className="cmp-row cmp-head-row">
            <div className="cmp-cell cmp-label-cell" />
            <div className="cmp-cell cmp-col-hero">
              <Wordmark size={15} />
            </div>
            <div className="cmp-cell cmp-col-other">Wise</div>
            <div className="cmp-cell cmp-col-other">Remitly</div>
            <div className="cmp-cell cmp-col-other">Your bank</div>
          </div>
          {rows.map((r, i) => (
            <div key={i} className="cmp-row">
              <div className="cmp-cell cmp-label-cell">{r.label}</div>
              <div className="cmp-cell cmp-hero-cell"><Cell v={r.sendit} hero /></div>
              <div className="cmp-cell"><Cell v={r.wise} /></div>
              <div className="cmp-cell"><Cell v={r.remitly} /></div>
              <div className="cmp-cell"><Cell v={r.bank} /></div>
            </div>
          ))}
        </div>

        <div className="lifetime">
          <div className="lifetime-num num"><CountUp to={15000} prefix="£" duration={2000} pulseOnDone /><span style={{ color: "#7C849F" }}>+</span></div>
          <p className="lifetime-body">
            Over a lifetime of sending money home, the average person in the UK-to-India
            corridor pays this much in fees and forced currency conversions. With SendIt,
            that number is <span style={{ color: "#FF5B47" }}>zero</span>.
          </p>
        </div>
      </div>
    </section>
  );
}

function FinalCta({ onEarlyAccess }) {
  const [email, setEmail] = useState("");

  return (
    <section className="final">
      <SpeedLines style={{ position: "absolute", top: 60, right: -200 }} opacity={0.6} />
      <SpeedLines style={{ position: "absolute", bottom: 60, left: -240 }} opacity={0.4} scale={0.7} />

      <div className="container">
        <div className="final-inner">
          <h2 className="display-xl final-headline">
            Money that moves the way you do.
          </h2>
          <p className="final-body">
            Join <span className="final-count num"><CountUp to={42876} incrementing /></span> people who are done paying
            to move their own money.
          </p>

          <form
            className="waitlist"
            onSubmit={(e) => {
              e.preventDefault();
              onEarlyAccess("Final CTA", email);
            }}
          >
            <input
              type="email"
              placeholder="you@email.com"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
            />
            <button className="btn-coral" type="submit">Get early access</button>
          </form>

          <a className="referral" href="/leaderboard">
            <Icon name="sparkles" size={16} color="#FF5B47" />
            <span>Refer a friend, skip the line</span>
            <Icon name="chevron-r" size={14} />
          </a>
        </div>
      </div>
    </section>
  );
}

function Footer() {
  return (
    <footer className="footer">
      <div className="container footer-grid">
        <div className="footer-brand">
          <Wordmark size={22} />
          <p className="footer-tag">Money that moves the way you do.</p>
        </div>
        <div className="footer-cols">
          <div>
            <h3 className="footer-title">Product</h3>
            <a href="#">Send</a><a href="#">Spend</a><a href="#">Trade</a><a href="#">Save</a><a href="#">Card</a>
          </div>
          <div>
            <h3 className="footer-title">Socials</h3>
            <a href="#" className="footer-social">
              <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M22 12a10 10 0 1 0-11.56 9.88v-6.99H7.9V12h2.54V9.8c0-2.51 1.5-3.9 3.78-3.9 1.1 0 2.24.2 2.24.2v2.46h-1.26c-1.24 0-1.63.77-1.63 1.56V12h2.77l-.44 2.89h-2.33v6.99A10 10 0 0 0 22 12z"/></svg>
              <span>Facebook</span>
            </a>
            <a href="#" className="footer-social">
              <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M19.59 6.69a4.83 4.83 0 0 1-3.77-4.25V2h-3.45v13.67a2.89 2.89 0 0 1-5.2 1.74 2.89 2.89 0 0 1 2.31-4.64 2.93 2.93 0 0 1 .88.13V9.4a6.84 6.84 0 0 0-1-.05A6.33 6.33 0 0 0 5.8 20.1a6.34 6.34 0 0 0 10.86-4.43v-7a8.16 8.16 0 0 0 4.77 1.52v-3.4a4.85 4.85 0 0 1-1.84-.1z"/></svg>
              <span>TikTok</span>
            </a>
            <a href="#" className="footer-social">
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" aria-hidden="true"><rect x="3" y="3" width="18" height="18" rx="5"/><circle cx="12" cy="12" r="4"/><circle cx="17.5" cy="6.5" r="1" fill="currentColor" stroke="none"/></svg>
              <span>Instagram</span>
            </a>
            <a href="#" className="footer-social">
              <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg>
              <span>X</span>
            </a>
          </div>
          <div>
            <h3 className="footer-title">Company</h3>
            <a href="#">About</a><a href="#">Careers</a><a href="#">Press</a><a href="#">Help centre</a><a href="#">Refer a friend</a>
          </div>
          <div>
            <h3 className="footer-title">Legal</h3>
            <a href="#">Terms</a><a href="#">Privacy</a><a href="#">Cookie policy</a><a href="#">Licences</a>
          </div>
        </div>
      </div>
      <div className="container footer-fine">
        <span>© 2026 SendIt Money Ltd.</span>
        <span className="num">FRN 987654 · Authorised by the FCA</span>
        <span>Built for people whose lives cross borders.</span>
      </div>
    </footer>
  );
}

function App() {
  const [waitlistState, setWaitlistState] = useState({
    open: false,
    source: null,
    initialEmail: "",
  });
  const pathname = window.location.pathname.replace(/\/+$/, "") || "/";
  const openEarlyAccess = (source, initialEmail = "") => {
    setWaitlistState({
      open: true,
      source: source || null,
      initialEmail: initialEmail || "",
    });
  };
  const closeEarlyAccess = () => {
    setWaitlistState((state) => ({ ...state, open: false }));
  };

  useEffect(() => {
    // Skip the magnetic-hover rig entirely on touch-only devices — no mouse,
    // no point wiring up mousemove listeners.
    if (!window.matchMedia("(hover: hover) and (pointer: fine)").matches) return;
    const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    if (reduce) return;
    const cleanups = [];
    // Re-bind shortly after mount so any post-render DOM exists.
    const bindId = setTimeout(() => {
      const buttons = document.querySelectorAll(".btn-coral:not(.btn-sm)");
      buttons.forEach(btn => {
        let raf = 0;
        let tx = 0, ty = 0;
        const onMove = (e) => {
          const rect = btn.getBoundingClientRect();
          const cx = rect.left + rect.width / 2;
          const cy = rect.top + rect.height / 2;
          const dx = e.clientX - cx;
          const dy = e.clientY - cy;
          const dist = Math.sqrt(dx * dx + dy * dy);
          const range = 80 + Math.max(rect.width, rect.height) / 2;
          if (dist < range) {
            const strength = Math.min(1, 1 - dist / range);
            tx = (dx / range) * 12 * strength;
            ty = (dy / range) * 12 * strength - 1; // bias upward slightly
            // clamp to ~5px max as spec
            const max = 5;
            const mag = Math.sqrt(tx * tx + ty * ty);
            if (mag > max) { tx = tx * max / mag; ty = ty * max / mag; }
          } else {
            tx = 0; ty = 0;
          }
          if (!raf) {
            raf = requestAnimationFrame(() => {
              btn.style.transform = `translate(${tx}px, ${ty}px)`;
              raf = 0;
            });
          }
        };
        const onLeave = () => {
          tx = 0; ty = 0;
          btn.style.transition = "transform 350ms cubic-bezier(0.22, 1, 0.36, 1)";
          btn.style.transform = "translate(0,0)";
          setTimeout(() => { btn.style.transition = ""; }, 360);
        };
        const onEnter = () => {
          btn.style.transition = "transform 180ms cubic-bezier(0.22, 1, 0.36, 1)";
        };
        window.addEventListener("mousemove", onMove);
        btn.addEventListener("mouseenter", onEnter);
        btn.addEventListener("mouseleave", onLeave);
        cleanups.push(() => {
          window.removeEventListener("mousemove", onMove);
          btn.removeEventListener("mouseenter", onEnter);
          btn.removeEventListener("mouseleave", onLeave);
          if (raf) cancelAnimationFrame(raf);
          btn.style.transform = "";
          btn.style.transition = "";
        });
      });
    }, 50);
    return () => {
      clearTimeout(bindId);
      cleanups.forEach(fn => fn());
    };
  }, [waitlistState.open]);

  if (pathname === "/share-referral") {
    return <ShareReferralPage />;
  }

  if (pathname === "/leaderboard") {
    return (
      <div className="page">
        <div className="film-grain" aria-hidden="true" />
        <LeaderboardPage onEarlyAccess={openEarlyAccess} />
        {waitlistState.open && (
          <WaitlistModal
            onClose={closeEarlyAccess}
            initialEmail={waitlistState.initialEmail}
            initialSource={waitlistState.source}
          />
        )}
      </div>
    );
  }

  return (
    <div className="page">
      <div className="film-grain" aria-hidden="true" />
      <Nav onEarlyAccess={openEarlyAccess} />
      <Hero onEarlyAccess={openEarlyAccess} />
      <Stage />
      <HowItWorks />
      <Comparison />
      <FinalCta onEarlyAccess={openEarlyAccess} />
      <Footer />
      {waitlistState.open && (
        <WaitlistModal
          onClose={closeEarlyAccess}
          initialEmail={waitlistState.initialEmail}
          initialSource={waitlistState.source}
        />
      )}
    </div>
  );
}

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