/* ui.jsx — shared marketing chrome + product metadata for the Gigi Money site.
   Exports nav, footer, hero visuals, and the MKT product registry to window. */
const { Icon } = window.GigiMoneyDesignSystem_b54949;
const _G = window.GIGI;
const fmtK = (n) => _G ? _G.fmtKES(n, { compact: true }) : 'KES ' + n;

/* ── Per-device submission dedupe ──
   Every form routes through submitForm, so we fingerprint each submission and
   remember the id Firestore returned. An identical resubmission from the same
   device (same form type + the same identity fields) short-circuits to the
   stored result instead of creating a duplicate Firestore doc — e.g. a
   double-click, a refresh-and-retry, or the same lead filling the form twice.
   Entries are pruned by age so a legitimate later resubmission still goes
   through. */
const SUBMIT_LS_KEY = 'gigi_form_submissions';
const SUBMIT_TTL_MS = 24 * 60 * 60 * 1000;   // 24h dedupe window

const lsGet = (k) => { try { return localStorage.getItem(k); } catch { return null; } };
const lsSet = (k, v) => { try { localStorage.setItem(k, v); } catch { /* private mode */ } };

/* Compact, stable hash (FNV-1a) of a string → unsigned base-36. */
function fnv1a(str) {
  let h = 0x811c9dc5;
  for (let i = 0; i < str.length; i++) {
    h ^= str.charCodeAt(i);
    h = Math.imul(h, 0x01000193);
  }
  return (h >>> 0).toString(36);
}

/* Fingerprint from form type + payload, normalised so key order and trivial
   whitespace/case differences still collide. */
function submissionFingerprint(type, payload) {
  const norm = {};
  Object.keys(payload).sort().forEach((k) => {
    const v = payload[k];
    norm[k] = typeof v === 'string' ? v.trim().toLowerCase() : v;
  });
  return type + ':' + fnv1a(JSON.stringify(norm));
}

/* Load the dedupe map, dropping expired entries so it can't grow unbounded. */
function loadSubmissions() {
  let map;
  try { map = JSON.parse(lsGet(SUBMIT_LS_KEY)); } catch { map = null; }
  if (!map || typeof map !== 'object') return {};
  const now = Date.now();
  let changed = false;
  for (const k of Object.keys(map)) {
    if (!map[k] || now - (map[k].ts || 0) > SUBMIT_TTL_MS) { delete map[k]; changed = true; }
  }
  if (changed) lsSet(SUBMIT_LS_KEY, JSON.stringify(map));
  return map;
}

function rememberSubmission(fp, id) {
  const map = loadSubmissions();
  map[fp] = { id, ts: Date.now() };
  lsSet(SUBMIT_LS_KEY, JSON.stringify(map));
}

/* ── Form intake → Firebase function (writes to Firestore) ──
   POSTs to the `submitForm` Cloud Function. The function runs in africa-south1,
   which Firebase Hosting can't serve via a same-origin rewrite, so we call it
   directly (CORS is enabled on the function). Override with
   window.GIGI_FORMS_ENDPOINT for the local emulator. */
async function submitForm(type, payload) {
  const fp = submissionFingerprint(type, payload);
  const seen = loadSubmissions()[fp];
  if (seen) return { ok: true, id: seen.id, deduped: true };

  const endpoint = window.GIGI_FORMS_ENDPOINT || 'https://africa-south1-gigi-money.cloudfunctions.net/submitForm';
  const headers = { 'Content-Type': 'application/json' };
  // App Check attestation (anti-bot / anti-replay); null until configured.
  const appCheck = window.gigiAppCheckToken ? await window.gigiAppCheckToken() : null;
  if (appCheck) headers['X-Firebase-AppCheck'] = appCheck;

  const res = await fetch(endpoint, {
    method: 'POST',
    headers,
    body: JSON.stringify({
      type,
      page: location.pathname,
      source: 'website',
      // Server-side replay guard: same key ⇒ no duplicate Firestore doc.
      idempotencyKey: fp,
      ...payload,
    }),
  });
  let data = {};
  try { data = await res.json(); } catch (e) { /* non-JSON response */ }
  if (!res.ok || !data.ok) {
    throw new Error(data.error || 'Something went wrong. Please try again.');
  }
  rememberSubmission(fp, data.id);
  return data;
}
window.gigiSubmitForm = submitForm;

/* ── Marketing copy layered over the offers catalogue (GIGI_OFFERS) ── */
const MKT = {
  rent_advance: {
    slug: 'rent-advance', nav: 'Rent advance', icon: 'bolt',
    eyebrow: 'For property owners',
    h1: ['Advance up to ', { hl: '24 months' }, ' of rent and watch the cash land in minutes.'],
    lede: 'Your tenants already pay you every month. A rent advance simply brings some of that future rent forward, so you can hold the lump sum today without taking on new debt or touching the title.',
    visual: 'preview',
    stat: { k: 'Lump sum, today', v: 'KES 5.5M', s: 'Riverside Court · 6 months assigned' },
    trust: [['percent', 'Lowest rates on the market'], ['shield', 'Verified via Ardhi Sasa']],
  },
  rent_guarantee: {
    slug: 'rent-guarantee', nav: 'Rent guarantee', icon: 'shield',
    eyebrow: 'For owners who want certainty',
    h1: ['Get your rent ', { hl: 'on schedule' }, ', whether the tenant pays or not.'],
    lede: 'Instead of holding a deposit, your tenant pays a small monthly fee. In return, the rent arrives on time every month. And if a tenant falls behind, chasing it stops being your problem and becomes ours.',
    visual: 'guarantee',
    stat: { k: 'Owner guaranteed', v: 'KES 1.02M', s: 'Every month · default-protected' },
    trust: [['check', 'Paid on schedule, every month'], ['users', 'Recovery handled for you'], ['shield', 'Backed by Gigi Money']],
  },
  heloc: {
    slug: 'heloc', nav: 'HELOC', icon: 'home',
    eyebrow: 'For property owners',
    h1: ['Release your ', { hl: 'property equity' }, ' as a revolving line of credit.'],
    lede: 'Your buildings are worth a lot, but that value usually just sits there. A HELOC turns it into a credit line you can draw on whenever you need, repaid from the rent you already collect.',
    visual: 'ring',
    stat: { k: 'Available credit line', v: 'KES 42M', s: 'Up to 50% of equity · Riverside Court' },
    trust: [['home', 'Secured by property equity'], ['sync', 'Serviced by your rent roll'], ['bolt', 'Draw down anytime']],
  },
  credit_card: {
    slug: 'credit-card', nav: 'Credit card', icon: 'box',
    eyebrow: 'For property owners',
    cta: 'Check your offer',
    h1: ['Credit card in the front. ', { hl: 'Property equity' }, ' in the back.'],
    lede: 'The credit card built for Kenyan property owners. Limits up to KES 6M, one of the lowest rates around, and cash back on every spend, all backed by the equity in your buildings.',
    visual: 'card',
    stat: { k: 'Credit limit', v: 'up to KES 6M', s: 'Backed by your property equity' },
    trust: [['box', 'Cash back on every spend'], ['percent', 'One of the lowest rates'], ['home', 'Backed by property equity']],
  },
};
const ORDER = ['rent_advance', 'rent_guarantee', 'heloc', 'credit_card'];
window.GIGI_MKT = MKT;
window.GIGI_ORDER = ORDER;
const offerById = (id) => (window.GIGI_OFFERS || []).find(o => o.id === id) || {};

/* ── small helpers ── */
function scrollToId(id) {
  const el = document.getElementById(id);
  if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
}

/* On a fresh load with a hash (#partner, #prequalify…), the target section is
   rendered client-side by Babel and doesn't exist yet when the browser resolves
   the anchor — so the jump is lost. Poll briefly until it mounts, then scroll
   (scroll-margin-top keeps it clear of the sticky nav). */
function scrollToHashTarget() {
  const id = decodeURIComponent((location.hash || '').replace(/^#/, ''));
  if (!id) return;
  const start = Date.now();
  const tick = () => {
    const el = document.getElementById(id);
    if (el) { el.scrollIntoView({ behavior: 'auto', block: 'start' }); return; }
    if (Date.now() - start < 4000) requestAnimationFrame(tick);
  };
  tick();
}
if (typeof window !== 'undefined' && window.location.hash) {
  if (document.readyState === 'complete') scrollToHashTarget();
  else window.addEventListener('load', scrollToHashTarget);
}

/* ── Brand lockup ── */
function Brand({hideText = false} = {}) {
    return (
    <a className="brand" href="index.html" aria-label="Gigi Money home">
      <span className="mark"><Icon name="vault" size={18} /></span>
        {!hideText && (
            <span className="brand-row">
                <span className="word">Gigi</span>
                <span className="div" />
                <span className="sub">Money</span>
                <span className="brand-say" aria-hidden="true">&ldquo;jee-jee&rdquo;</span>
            </span>
        )}
    </a>
  );
}

/* ── Offerings dropdown ── */
function OfferingsMenu({ active }) {
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null);
  const closeT = React.useRef(null);
  const isActive = window.GIGI_ORDER.includes(active);

  const enter = () => { clearTimeout(closeT.current); setOpen(true); };
  const leave = () => { closeT.current = setTimeout(() => setOpen(false), 120); };

  React.useEffect(() => {
    const onDoc = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    const onEsc = (e) => { if (e.key === 'Escape') setOpen(false); };
    document.addEventListener('click', onDoc);
    document.addEventListener('keydown', onEsc);
    return () => { document.removeEventListener('click', onDoc); document.removeEventListener('keydown', onEsc); };
  }, []);

  return (
    <div className={`offerings ${open ? 'open' : ''}`} ref={ref} onMouseEnter={enter} onMouseLeave={leave}>
      <button className={`off-trigger ${isActive ? 'active' : ''}`} aria-expanded={open} aria-haspopup="true"
        onClick={() => setOpen(o => !o)}>
        Solutions <Icon name="chevD" size={15} stroke={2.1} />
      </button>
      <div className="off-panel" role="menu">
        <div className="off-grid">
          {ORDER.map(id => {
            const o = offerById(id), m = MKT[id];
            return (
              <a key={id} href={`${m.slug}.html`} role="menuitem" className={active === id ? 'cur' : ''}>
                <span className="oi"><Icon name={m.icon} size={20} /></span>
                <span className="ot">
                  <span className="otn">{o.title || m.nav}</span>
                  <span className="ots">{m.eyebrow}</span>
                </span>
              </a>
            );
          })}
        </div>
        <a className="off-foot" href="index.html#products">
          <span>See all solutions</span> <Icon name="chevR" size={15} />
        </a>
      </div>
    </div>
  );
}

/* ── Sticky nav ── */
function Nav({ active }) {
  React.useEffect(() => {
    const el = document.querySelector('.nav');
    const onScroll = () => el && el.classList.toggle('scrolled', window.scrollY > 8);
    onScroll();
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  const [mob, setMob] = React.useState(false);
  React.useEffect(() => {
    document.body.style.overflow = mob ? 'hidden' : '';
    document.body.classList.toggle('nav-open', mob);
    return () => { document.body.style.overflow = ''; document.body.classList.remove('nav-open'); };
  }, [mob]);
  const links = [
    ...window.GIGI_ORDER.map(id => [`${window.GIGI_MKT[id].slug}.html`, window.GIGI_MKT[id].nav]),
    ['personal.html', 'Personal'],
    ['business.html', 'Business'],
    ['pricing.html', 'Pricing'],
  ];
  return (
    <header className="nav">
      <div className="wrap nav-inner">
        <Brand />
        <nav className="nav-links">
          <OfferingsMenu active={active} />
          <a href="personal.html">Personal</a>
          <a href="business.html">Business</a>
          <a href="pricing.html">Pricing</a>
        </nav>
        <div className="nav-cta">
          <a className="btn btn-ghost partner-link" href="partners.html">Become a partner</a>
          <a className="btn btn-pill" href="#prequalify">Get funding</a>
        </div>
        <button className="nav-burger" aria-label="Menu" aria-expanded={mob} onClick={() => setMob(v => !v)}>
          <Icon name={mob ? 'x' : 'menu'} size={22} />
        </button>
      </div>
      <div className={`nav-mobile-panel ${mob ? 'open' : ''}`} onClick={() => setMob(false)}>
        <div className="nmp-inner" onClick={(e) => e.stopPropagation()}>
          <div className="nmp-label">Solutions</div>
          {window.GIGI_ORDER.map(id => (
            <a key={id} href={`${window.GIGI_MKT[id].slug}.html`} className={active === id ? 'cur' : ''}>{window.GIGI_MKT[id].nav}</a>
          ))}
          <div className="nmp-label">Customers</div>
          <a href="personal.html">Personal</a>
          <a href="business.html">Business</a>
          <a href="pricing.html">Pricing</a>
          <div className="nmp-acts">
            <a className="btn btn-pill btn-lg" href="#prequalify">Get funding</a>
            <a className="btn btn-ghost btn-lg" href="partners.html">Become a partner</a>
          </div>
        </div>
      </div>
    </header>
  );
}

/* ── Hero / product preview visuals (photography-free) ── */
function PreviewCard() {
  return (
    <div className="hero-visual">
      <div className="preview cardskin">
        <div className="pv-hw">
          <span className="pv-chip" />
          <svg className="pv-wifi" width="22" height="22" viewBox="0 0 22 22" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
            <path d="M7 7a7 7 0 0 1 0 8" /><path d="M11 4a11 11 0 0 1 0 14" />
          </svg>
        </div>
        <div className="pv-top">
          <div className="pv-prop">
            <span className="ic"><Icon name="building" size={20} /></span>
            <div>
              <div className="nm">Riverside Court</div>
              <div className="ad">Westlands, Nairobi</div>
            </div>
          </div>
          <span className="pv-badge">Eligible</span>
        </div>
        <div className="pv-label">Lump sum today</div>
        <div className="pv-amt">KES 5,508,000</div>
        <div className="pv-sub">6 months of rent assigned · disbursed to M-Pesa</div>
        <div className="pv-bar"><i /></div>
        <div className="pv-rows">
          <div className="pv-row"><span className="k">Gross future rent</span><span className="v">KES 6,120,000</span></div>
          <div className="pv-row"><span className="k">Discount</span><span className="v">– KES 612,000</span></div>
        </div>
      </div>
      <div className="float float-a">
        <span className="fic" style={{ background: 'var(--go-bg)', color: 'var(--go)' }}><Icon name="bolt" size={16} /></span>
        <span className="ft">Disbursed in 15 min<small>after approval</small></span>
      </div>
      <div className="float float-b">
        <span className="fic" style={{ background: 'var(--info-bg)', color: 'var(--info)' }}><Icon name="sync" size={16} /></span>
        <span className="ft">Repaid from rent<small>collected automatically</small></span>
      </div>
    </div>
  );
}

function RingVisual({ stat }) {
  return (
    <div className="hero-visual">
      <div className="ringwrap">
        <div className="glow" />
        <Ring pct={50} />
        <div className="rt">
          <div className="k">{stat.k}</div>
          <div className="v">{stat.v}</div>
          <div className="s">{stat.s}</div>
          <div className="rows">
            <div className="r"><span className="a">Property value</span><span className="b">KES 84M</span></div>
            <div className="r"><span className="a">Drawn</span><span className="b">KES 12M</span></div>
            <div className="r"><span className="a">Available</span><span className="b">KES 30M</span></div>
          </div>
        </div>
      </div>
      <div className="float float-a">
        <span className="fic" style={{ background: 'var(--go-bg)', color: 'var(--go)' }}><Icon name="home" size={16} /></span>
        <span className="ft">Secured by equity<small>verified via Ardhi Sasa</small></span>
      </div>
    </div>
  );
}

function Ring({ pct }) {
  const r = 46, c = 2 * Math.PI * r, off = c * (1 - pct / 100);
  return (
    <svg width="120" height="120" viewBox="0 0 120 120" style={{ flexShrink: 0 }}>
      <circle cx="60" cy="60" r={r} fill="none" stroke="rgba(255,255,255,.12)" strokeWidth="12" />
      <circle cx="60" cy="60" r={r} fill="none" stroke="var(--accent)" strokeWidth="12" strokeLinecap="round"
        strokeDasharray={c} strokeDashoffset={off} transform="rotate(-90 60 60)" />
      <text x="60" y="58" textAnchor="middle" fontFamily="var(--fd)" fontSize="26" fontWeight="700" fill="#fff">{pct}%</text>
      <text x="60" y="76" textAnchor="middle" fontFamily="var(--ff)" fontSize="10" fill="rgba(255,255,255,.55)">of equity</text>
    </svg>
  );
}

function CardVisual() {
  return (
    <div className="hero-visual" style={{ display: 'grid', placeItems: 'center' }}>
      <div className="cardmock-wrap">
        <div className="cardmock">
          <div className="glow" />
          <div className="cm-top">
            <span className="cm-brand"><span className="m"><Icon name="vault" size={15} /></span>Gigi</span>
            <span className="cm-chip" />
          </div>
          <div className="cm-access">
            <div className="cm-access-k">Available to access</div>
            <div className="cm-access-v">KES 6,000,000</div>
          </div>
          <div className="cm-num">4821&nbsp;&nbsp;••••&nbsp;&nbsp;••••&nbsp;&nbsp;0084</div>
          <div className="cm-bottom">
            <div><div className="k">Cardholder</div><div className="v">Meco Holdings</div></div>
            <div style={{ textAlign: 'right' }}><div className="k">Backed by</div><div className="v">Property equity</div></div>
          </div>
        </div>
        <div className="float float-a">
          <span className="fic" style={{ background: 'var(--go-bg)', color: 'var(--go)' }}><Icon name="box" size={16} /></span>
          <span className="ft">Cash back<small>on every spend</small></span>
        </div>
        <div className="float float-b">
          <span className="fic" style={{ background: 'var(--info-bg)', color: 'var(--info)' }}><Icon name="percent" size={16} /></span>
          <span className="ft">Low rate<small>one of the lowest around</small></span>
        </div>
      </div>
    </div>
  );
}

function GuaranteeVisual({ stat }) {
  const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'];
  return (
    <div className="hero-visual">
      <div className="preview">
        <div className="glow" />
        <div className="pv-top">
          <div className="pv-prop">
            <span className="ic"><Icon name="shield" size={20} /></span>
            <div>
              <div className="nm">Riverside Court · A1</div>
              <div className="ad">Grace Wanjiru · tenant</div>
            </div>
          </div>
          <span className="pv-badge">Protected</span>
        </div>
        <div className="pv-label">{stat.k}</div>
        <div className="pv-amt">{stat.v}</div>
        <div className="pv-sub">{stat.s}</div>
        <div style={{ display: 'flex', gap: 7, marginTop: 22 }}>
          {months.map((m, i) => (
            <div key={m} style={{ flex: 1, textAlign: 'center' }}>
              <div style={{ height: 46, borderRadius: 7, background: i === 5 ? 'var(--accent)' : 'rgba(255,255,255,.1)', display: 'grid', placeItems: 'end center', paddingBottom: 6 }}>
                <Icon name="check" size={14} stroke={2.4} style={{ color: i === 5 ? 'var(--accent-ink)' : 'var(--accent)' }} />
              </div>
              <div style={{ fontSize: 10.5, color: 'rgba(255,255,255,.5)', marginTop: 6 }}>{m}</div>
            </div>
          ))}
        </div>
      </div>
      <div className="float float-b">
        <span className="fic" style={{ background: 'var(--warn-bg)', color: 'var(--warn)' }}><Icon name="users" size={16} /></span>
        <span className="ft">Default? We recover<small>local PM presence</small></span>
      </div>
    </div>
  );
}

function ProductVisual({ id }) {
  const m = MKT[id];
  if (m.visual === 'preview') return <PreviewCard />;
  if (m.visual === 'ring') return <RingVisual stat={m.stat} />;
  if (m.visual === 'card') return <CardVisual />;
  if (m.visual === 'guarantee') return <GuaranteeVisual stat={m.stat} />;
  return null;
}

/* ── Footer ── */
function Footer() {
  return (
    <footer className="footer">
      <div className="wrap">
        <div className="footer-grid">
          <div className="col about">
            <Brand  hideText/>
            <p>Rent-backed financing and guarantee products for Kenyan property owners, built on the rent data Gigi Money already verifies. Turn your rent receivables and property equity into liquidity, secured by titles confirmed through Ardhi&nbsp;Sasa.</p>
            <a className="footer-email" href="mailto:hello@gigi.money"><Icon name="mail" size={15} />hello@gigi.money</a>
          </div>
          <div className="col">
            <h5>Products</h5>
            {ORDER.map(id => <a key={id} href={`${MKT[id].slug}.html`}>{MKT[id].nav}</a>)}
          </div>
          <div className="col">
            <h5>Company</h5>
            <a href="index.html#how">How it works</a>
            <a href="pricing.html">Pricing</a>
            <a href="partners.html">For partners</a>
            <a href="index.html#products">All solutions</a>
            <a href="mailto:hello@gigi.money">Contact</a>
          </div>
          <div className="col">
            <h5>Legal</h5>
            <a href="terms.html">Eligibility &amp; terms</a>
            <a href="privacy.html">Privacy policy</a>
            <a href="disclosures.html">Lending disclosures</a>
            <a href="risk.html">Risk &amp; recourse</a>
          </div>
        </div>
        <div className="footer-compliance">
          <Icon name="shield" size={15} />
          <span>
            <b>Gigi Money Limited</b> is licensed and regulated, and registered with the
            ODPC (Office of the Data Protection Commissioner).
          </span>
        </div>
        <div className="footer-bottom">
          <div className="secured"><Icon name="shield" size={15} /><span>Secured by <b>Gigi Money</b> · titles verified via <b>Ardhi Sasa</b></span></div>
          <div className="fine">© 2026 Gigi Money Limited. Nairobi, Kenya. Amounts in KES.</div>
        </div>
      </div>
    </footer>
  );
}

/* ── Public rent-advance estimator (no property / account required) ── */
function PubTiles({ options, value, onChange, cols }) {
  return (
    <div style={{ display: 'grid', gridTemplateColumns: `repeat(${cols},1fr)`, gap: 10 }}>
      {options.map(o => {
        const on = o.value === value;
        return (
          <div key={o.value} onClick={() => onChange(o.value)} className="g-tap" style={{
            padding: '14px 10px', borderRadius: 'var(--r-md)', textAlign: 'center',
            border: `1.5px solid ${on ? 'var(--accent-ink)' : 'var(--line)'}`, boxShadow: on ? 'var(--shadow)' : 'none',
          }}>
            <div className="g-num" style={{ fontSize: 20, fontWeight: 700 }}>{o.big}</div>
            <div style={{ fontSize: 11.5, color: 'var(--ink-3)', marginTop: 2 }}>{o.small}</div>
          </div>
        );
      })}
    </div>
  );
}

function PublicAdvanceForm({ onBack }) {
  const { Input, Button, Card, Field, Icon } = window.GigiMoneyDesignSystem_b54949;
  const fmt = (n) => window.GIGI ? window.GIGI.fmtKES(n) : 'KES ' + Math.round(n).toLocaleString();
  const [rent, setRent] = React.useState(250000);
  const [months, setMonths] = React.useState(6);
  const [done, setDone] = React.useState(false);

  const gross = rent * months;
  const discount = Math.round(gross * (0.015 * months));
  const net = gross - discount;

  const onRent = (v) => setRent(Number(String(v).replace(/[^\d]/g, '')) || 0);

  if (done) {
    return (
      <div style={{ textAlign: 'center', padding: '8px 0' }}>
        <div style={{ width: 64, height: 64, borderRadius: 18, background: 'var(--accent)', display: 'grid', placeItems: 'center', margin: '0 auto' }}>
          <Icon name="bolt" size={30} style={{ color: 'var(--accent-ink)' }} />
        </div>
        <h2 className="g-num" style={{ fontSize: 23, fontWeight: 700, margin: '16px 0 6px' }}>Your estimate: {fmt(net)}</h2>
        <p style={{ color: 'var(--ink-2)', fontSize: 14.5, lineHeight: 1.55, margin: '0 auto 22px', maxWidth: '34em' }}>
          That&rsquo;s a no-obligation estimate for {months} months of rent at {fmt(rent)} a month. When you&rsquo;re ready, Gigi checks your title with Ardhi&nbsp;Sasa and confirms your tenancy, then sends the money within 15 minutes of approval.
        </p>
        <div style={{ display: 'flex', gap: 10, justifyContent: 'center', flexWrap: 'wrap' }}>
          <a className="btn btn-pill btn-lg" href="index.html#partner">Become a partner</a>
          <button className="btn btn-ghost btn-lg" onClick={() => setDone(false)}>Adjust estimate</button>
        </div>
      </div>
    );
  }

  return (
    <>
      <Input label="Monthly rent on the property" prefix="KES" mono value={rent ? rent.toLocaleString() : ''} onChange={onRent} hint="Enter the verified monthly rent you'd advance against" />
      <div style={{ height: 18 }} />
      <div style={{ fontSize: 12.5, fontWeight: 600, color: 'var(--ink-2)', marginBottom: 8 }}>Months of future rent to assign</div>
      <PubTiles cols={4} value={months} onChange={setMonths} options={[6, 12, 18, 24].map(m => ({ value: m, big: m, small: 'months' }))} />
      <div style={{ height: 18 }} />
      <div style={{ background: 'var(--accent-ink)', color: '#fff', borderRadius: 'var(--r-lg)', padding: 20, textAlign: 'center', marginBottom: 16 }}>
        <div style={{ color: 'var(--pill-ink)', fontSize: 12.5, fontWeight: 600 }}>Lump sum today</div>
        <div className="g-num" style={{ fontSize: 36, fontWeight: 700, margin: '6px 0 4px', letterSpacing: '-.02em' }}>{fmt(net)}</div>
        <div style={{ fontSize: 12.5, color: 'rgba(255,255,255,.62)' }}>{months} months of rent assigned</div>
      </div>
      <Card style={{ boxShadow: 'none', background: 'var(--surface-2)' }}>
        <Field label="Gross future rent" value={fmt(gross)} mono />
        <Field label="Discount" value={'– ' + fmt(discount)} mono last />
      </Card>
      <div style={{ height: 18 }} />
      <Button kind="accent" icon="bolt" full onClick={() => setDone(true)} disabled={!rent}>Get my estimate</Button>
    </>
  );
}
window.GIGI_FORMS = window.GIGI_FORMS || {};
window.GIGI_FORMS.rent_advance = PublicAdvanceForm;

/* ── Public rent-guarantee estimator (no property / account required) ── */
function PublicGuaranteeForm({ onBack }) {
  const { Input, Button, Card, Field, Icon } = window.GigiMoneyDesignSystem_b54949;
  const fmt = (n) => window.GIGI ? window.GIGI.fmtKES(n) : 'KES ' + Math.round(n).toLocaleString();
  const [rent, setRent] = React.useState(120000);
  const [fee, setFee] = React.useState(7.5);
  const [done, setDone] = React.useState(false);
  const tenantFee = Math.round(rent * fee / 100);
  const onRent = (v) => setRent(Number(String(v).replace(/[^\d]/g, '')) || 0);

  if (done) {
    return (
      <div style={{ textAlign: 'center', padding: '8px 0' }}>
        <div style={{ width: 64, height: 64, borderRadius: 18, background: 'var(--accent)', display: 'grid', placeItems: 'center', margin: '0 auto' }}>
          <Icon name="shield" size={30} style={{ color: 'var(--accent-ink)' }} />
        </div>
        <h2 className="g-num" style={{ fontSize: 23, fontWeight: 700, margin: '16px 0 6px' }}>Guaranteed: {fmt(rent)}/mo</h2>
        <p style={{ color: 'var(--ink-2)', fontSize: 14.5, lineHeight: 1.55, margin: '0 auto 22px', maxWidth: '34em' }}>
          Your tenant would pay {fmt(tenantFee)} a month instead of a deposit, and your rent arrives on schedule every month. If a tenant falls behind, recovery becomes our job.
        </p>
        <div style={{ display: 'flex', gap: 10, justifyContent: 'center', flexWrap: 'wrap' }}>
          <a className="btn btn-pill btn-lg" href="index.html#partner">Become a partner</a>
          <button className="btn btn-ghost btn-lg" onClick={() => setDone(false)}>Adjust estimate</button>
        </div>
      </div>
    );
  }

  return (
    <>
      <Input label="Monthly rent on the property" prefix="KES" mono value={rent ? rent.toLocaleString() : ''} onChange={onRent} hint="Enter the monthly rent you'd want guaranteed" />
      <div style={{ height: 18 }} />
      <div style={{ fontSize: 12.5, fontWeight: 600, color: 'var(--ink-2)', marginBottom: 8 }}>Tenant fee (instead of a deposit)</div>
      <PubTiles cols={3} value={fee} onChange={setFee} options={[
        { value: 5, big: '5%', small: 'low risk' },
        { value: 7.5, big: '7.5%', small: 'standard' },
        { value: 10, big: '10%', small: 'higher risk' },
      ]} />
      <div style={{ height: 18 }} />
      <Card style={{ boxShadow: 'none', background: 'var(--surface-2)' }}>
        <Field label="Tenant pays (recurring)" value={fmt(tenantFee) + ' /mo'} mono />
        <Field label="You're guaranteed" value={fmt(rent) + ' /mo'} mono last />
      </Card>
      <div style={{ height: 18 }} />
      <Button kind="accent" icon="shield" full onClick={() => setDone(true)} disabled={!rent}>See my guarantee</Button>
    </>
  );
}
window.GIGI_FORMS.rent_guarantee = PublicGuaranteeForm;

/* ── Public HELOC estimator (no property / account required) ── */
function PublicHelocForm({ onBack }) {
  const { Input, Button, Icon } = window.GigiMoneyDesignSystem_b54949;
  const fmt = (n) => window.GIGI ? window.GIGI.fmtKES(n) : 'KES ' + Math.round(n).toLocaleString();
  const [value, setValue] = React.useState(40000000);
  const [done, setDone] = React.useState(false);
  const line = Math.round(value * 0.5);
  const onVal = (v) => setValue(Number(String(v).replace(/[^\d]/g, '')) || 0);

  if (done) {
    return (
      <div style={{ textAlign: 'center', padding: '8px 0' }}>
        <div style={{ width: 64, height: 64, borderRadius: 18, background: 'var(--accent)', display: 'grid', placeItems: 'center', margin: '0 auto' }}>
          <Icon name="home" size={30} style={{ color: 'var(--accent-ink)' }} />
        </div>
        <h2 className="g-num" style={{ fontSize: 23, fontWeight: 700, margin: '16px 0 6px' }}>Up to {fmt(line)}</h2>
        <p style={{ color: 'var(--ink-2)', fontSize: 14.5, lineHeight: 1.55, margin: '0 auto 22px', maxWidth: '34em' }}>
          That&rsquo;s an estimated revolving line of up to 50% of your equity. When you&rsquo;re ready, Gigi confirms your value with an Ardhi&nbsp;Sasa valuation, and drawdowns are serviced by the rent you already collect.
        </p>
        <div style={{ display: 'flex', gap: 10, justifyContent: 'center', flexWrap: 'wrap' }}>
          <a className="btn btn-pill btn-lg" href="index.html#partner">Become a partner</a>
          <button className="btn btn-ghost btn-lg" onClick={() => setDone(false)}>Adjust estimate</button>
        </div>
      </div>
    );
  }

  return (
    <>
      <Input label="Estimated property value" prefix="KES" mono value={value ? value.toLocaleString() : ''} onChange={onVal} hint="Your best estimate of what the property is worth today" />
      <div style={{ height: 18 }} />
      <div style={{ background: 'var(--accent-ink)', color: '#fff', borderRadius: 'var(--r-lg)', padding: 20, textAlign: 'center', marginBottom: 16 }}>
        <div style={{ color: 'var(--pill-ink)', fontSize: 12.5, fontWeight: 600 }}>Available credit line</div>
        <div className="g-num" style={{ fontSize: 36, fontWeight: 700, margin: '6px 0 4px', letterSpacing: '-.02em' }}>{fmt(line)}</div>
        <div style={{ fontSize: 12.5, color: 'rgba(255,255,255,.62)' }}>Up to 50% of your equity</div>
      </div>
      <Button kind="accent" icon="home" full onClick={() => setDone(true)} disabled={!value}>See my credit line</Button>
    </>
  );
}
window.GIGI_FORMS.heloc = PublicHelocForm;

/* ── Public credit-card estimator (no property / account required) ── */
function PublicCardForm({ onBack }) {
  const { Input, Button, Icon } = window.GigiMoneyDesignSystem_b54949;
  const fmt = (n) => window.GIGI ? window.GIGI.fmtKES(n) : 'KES ' + Math.round(n).toLocaleString();
  const [value, setValue] = React.useState(40000000);
  const [done, setDone] = React.useState(false);
  const limit = Math.min(6000000, Math.round(value * 0.5));
  const onVal = (v) => setValue(Number(String(v).replace(/[^\d]/g, '')) || 0);

  if (done) {
    return (
      <div style={{ textAlign: 'center', padding: '8px 0' }}>
        <div style={{ width: 64, height: 64, borderRadius: 18, background: 'var(--accent)', display: 'grid', placeItems: 'center', margin: '0 auto' }}>
          <Icon name="box" size={30} style={{ color: 'var(--accent-ink)' }} />
        </div>
        <h2 className="g-num" style={{ fontSize: 23, fontWeight: 700, margin: '16px 0 6px' }}>A card with up to {fmt(limit)}</h2>
        <p style={{ color: 'var(--ink-2)', fontSize: 14.5, lineHeight: 1.55, margin: '0 auto 22px', maxWidth: '34em' }}>
          That&rsquo;s an estimated credit limit backed by your equity, with cash back on every spend. When you&rsquo;re ready, Gigi confirms your value via Ardhi&nbsp;Sasa and a specialist gets your card moving.
        </p>
        <div style={{ display: 'flex', gap: 10, justifyContent: 'center', flexWrap: 'wrap' }}>
          <a className="btn btn-pill btn-lg" href="index.html#prequalify">Check your offer</a>
          <button className="btn btn-ghost btn-lg" onClick={() => setDone(false)}>Adjust estimate</button>
        </div>
      </div>
    );
  }

  return (
    <>
      <Input label="Estimated property value" prefix="KES" mono value={value ? value.toLocaleString() : ''} onChange={onVal} hint="Your best estimate of what the property is worth today" />
      <div style={{ height: 18 }} />
      <div style={{ background: 'var(--accent-ink)', color: '#fff', borderRadius: 'var(--r-lg)', padding: 20, textAlign: 'center', marginBottom: 16 }}>
        <div style={{ color: 'var(--pill-ink)', fontSize: 12.5, fontWeight: 600 }}>Estimated credit limit</div>
        <div className="g-num" style={{ fontSize: 36, fontWeight: 700, margin: '6px 0 4px', letterSpacing: '-.02em' }}>{fmt(limit)}</div>
        <div style={{ fontSize: 12.5, color: 'rgba(255,255,255,.62)' }}>Up to 50% of equity · cash back on every spend</div>
      </div>
      <Button kind="accent" icon="box" full onClick={() => setDone(true)} disabled={!value}>Check your offer</Button>
    </>
  );
}
window.GIGI_FORMS.credit_card = PublicCardForm;


/* ── Lead pre-qualification form ── */
function LeadForm({ defaultInterest }) {
  const { Input, Select, Button, Icon } = window.GigiMoneyDesignSystem_b54949;
  const fmt = (n) => window.GIGI ? window.GIGI.fmtKES(n) : 'KES ' + Math.round(n).toLocaleString();
  const [f, setF] = React.useState({ first: '', last: '', email: '', mobile: '', props: '1', rent: '', interest: defaultInterest || 'rent_advance' });
  const [done, setDone] = React.useState(false);
  const [busy, setBusy] = React.useState(false);
  const [err, setErr] = React.useState(null);
  const set = (k) => (v) => setF(s => ({ ...s, [k]: v }));
  const num = (s) => Number(String(s).replace(/[^\d]/g, '')) || 0;

  const properties = Math.max(1, num(f.props));
  const rent = num(f.rent);
  const monthly = properties * rent;
  const advance = Math.round(monthly * 6 * 0.91);
  const valid = f.first && f.last && /.+@.+\..+/.test(f.email) && num(f.mobile) > 0 && rent > 0;

  const submit = async () => {
    if (!valid || busy) return;
    setBusy(true); setErr(null);
    try {
      await window.gigiSubmitForm('lead', {
        first: f.first, last: f.last, email: f.email, mobile: f.mobile,
        props: properties, rent, interest: f.interest,
      });
      setDone(true);
    } catch (e) {
      setErr(e.message || 'Could not submit your details. Please try again.');
    } finally {
      setBusy(false);
    }
  };

  const interestOpts = [
    { value: 'rent_advance', label: 'Rent advance' },
    { value: 'rent_guarantee', label: 'Rent guarantee' },
    { value: 'heloc', label: 'HELOC (equity line)' },
    { value: 'credit_card', label: 'Credit card' },
  ];

  if (done) {
    let line;
    if (f.interest === 'rent_advance') line = <>you could unlock up to <b>{fmt(advance)}</b> today against {properties} {properties > 1 ? 'properties' : 'property'}.</>;
    else if (f.interest === 'rent_guarantee') line = <>we could guarantee <b>{fmt(monthly)}</b> of rent every month across {properties} {properties > 1 ? 'properties' : 'property'}.</>;
    else line = <>you look like a strong fit for an equity line backed by your {properties} {properties > 1 ? 'properties' : 'property'}.</>;
    return (
      <div style={{ textAlign: 'center', padding: '8px 0' }}>
        <div style={{ width: 64, height: 64, borderRadius: 18, background: 'var(--accent)', display: 'grid', placeItems: 'center', margin: '0 auto' }}>
          <Icon name="check" size={32} stroke={2.6} style={{ color: 'var(--accent-ink)' }} />
        </div>
        <h3 className="g-num" style={{ fontSize: 24, fontWeight: 700, margin: '16px 0 8px', fontFamily: 'var(--fd)' }}>Congratulations, you have been prequalified!</h3>
        <p style={{ color: 'var(--ink-2)', fontSize: 15, lineHeight: 1.6, margin: '0 auto 22px', maxWidth: '34em' }}>
          Based on what you shared, {line} A Gigi specialist will reach out on +254{f.mobile} to take it further. No obligation.
        </p>
        <button className="btn btn-ghost btn-lg" onClick={() => setDone(false)}>Edit my details</button>
      </div>
    );
  }

  return (
    <>
      <div className="lead-grid">
        <Input label="First name" value={f.first} onChange={set('first')} placeholder="James" />
        <Input label="Last name" value={f.last} onChange={set('last')} placeholder="Meco" />
        <Input label="Email address" value={f.email} onChange={set('email')} placeholder="james@gigi.money" />
        <Input label="Mobile number" prefix="+254" value={f.mobile} onChange={set('mobile')} placeholder="722 000 000" />
        <Input label="Number of properties" mono value={f.props} onChange={set('props')} placeholder="1" />
        <Input label="Average monthly rent" prefix="KES" mono value={f.rent ? num(f.rent).toLocaleString() : ''} onChange={set('rent')} placeholder="120,000" />
        <div className="lead-full">
          <Select label="What are you interested in?" value={f.interest} onChange={set('interest')} options={interestOpts} />
        </div>
      </div>
      <div style={{ height: 20 }} />
      {err && (
        <div role="alert" style={{ display: 'flex', alignItems: 'center', gap: 8, background: 'var(--warn-bg, #fdecec)', color: 'var(--warn, #b3261e)', borderRadius: 'var(--r-md)', padding: '10px 14px', fontSize: 13, marginBottom: 12 }}>
          <Icon name="info" size={16} /> {err}
        </div>
      )}
      <Button kind="accent" icon="bolt" full onClick={submit} disabled={!valid || busy}>
        {busy ? 'Checking…' : 'Check if I pre-qualify'}
      </Button>
      <p style={{ fontSize: 12, color: 'var(--ink-3)', textAlign: 'center', marginTop: 14, lineHeight: 1.5 }}>
        No obligation, no credit-score impact. We use your details only to assess eligibility and follow up.
      </p>
    </>
  );
}

/* ── Pre-qualify section (shared across pages) ── */
function Prequalify({ interest }) {
  return (
    <section className="block" id="prequalify">
      <div className="wrap prequal">
        <div className="prequal-head">
          <span className="eyebrow"><span className="dot" /> Pre-qualify in a minute</span>
          <h2>A smarter home for your property investments.</h2>
          <p>Tell us a little about your portfolio. We&rsquo;ll show what you could unlock, then a specialist follows up, with no obligation.</p>
        </div>
        <div className="prequal-card">
          <LeadForm defaultInterest={interest} />
        </div>
      </div>
    </section>
  );
}

/* ── Waitlist / partner sign-up form (writes to Firestore `waitlist`) ── */
function WaitlistForm({ kind = 'waitlist', onDark = false }) {
  const { Input, Button, Icon } = window.GigiMoneyDesignSystem_b54949;
  const isPartner = kind === 'partner';
  const [f, setF] = React.useState({ name: '', company: '', email: '', phone: '' });
  const [done, setDone] = React.useState(false);
  const [busy, setBusy] = React.useState(false);
  const [err, setErr] = React.useState(null);
  const set = (k) => (v) => setF(s => ({ ...s, [k]: v }));
  const emailOk = /.+@.+\..+/.test(f.email);
  const valid = emailOk && (!isPartner || (f.name && f.company));

  const submit = async () => {
    if (!valid || busy) return;
    setBusy(true); setErr(null);
    try {
      await window.gigiSubmitForm('waitlist', {
        kind, email: f.email, name: f.name, company: f.company, phone: f.phone,
      });
      setDone(true);
    } catch (e) {
      setErr(e.message || 'Could not add you right now. Please try again.');
    } finally {
      setBusy(false);
    }
  };

  if (done) {
    return (
      <div style={{ textAlign: onDark ? 'left' : 'center', padding: '6px 0', color: onDark ? '#fff' : 'inherit' }}>
        <div style={{ width: 56, height: 56, borderRadius: 16, background: 'var(--accent)', display: 'grid', placeItems: 'center', margin: onDark ? '0 0 14px' : '0 auto 14px' }}>
          <Icon name="check" size={28} stroke={2.6} style={{ color: 'var(--accent-ink)' }} />
        </div>
        <h3 className="g-num" style={{ fontSize: 20, fontWeight: 700, margin: '0 0 6px' }}>
          {isPartner ? 'Thanks — request received' : 'You’re on the list'}
        </h3>
        <p style={{ fontSize: 14, lineHeight: 1.55, margin: 0, color: onDark ? 'rgba(255,255,255,.72)' : 'var(--ink-2)' }}>
          {isPartner
            ? 'A Gigi partnerships specialist will reach out shortly to get you set up.'
            : 'We’ll email you the moment Gigi Money opens up for you.'}
        </p>
      </div>
    );
  }

  return (
    <div style={{ display: 'grid', gap: 12, minWidth: 0 }}>
      {isPartner && <Input label="Your name" value={f.name} onChange={set('name')} placeholder="James Meco" />}
      {isPartner && <Input label="Company / agency" value={f.company} onChange={set('company')} placeholder="Meco Holdings" />}
      <Input label="Email address" value={f.email} onChange={set('email')} placeholder="james@gigi.money" />
      {isPartner && <Input label="Mobile number" prefix="+254" value={f.phone} onChange={set('phone')} placeholder="722 000 000" />}
      {err && (
        <div role="alert" style={{ display: 'flex', alignItems: 'center', gap: 8, background: 'var(--warn-bg, #fdecec)', color: 'var(--warn, #b3261e)', borderRadius: 'var(--r-md)', padding: '10px 14px', fontSize: 13 }}>
          <Icon name="info" size={16} /> {err}
        </div>
      )}
      <Button kind="accent" icon={isPartner ? 'users' : 'bolt'} full onClick={submit} disabled={!valid || busy}>
        {busy ? 'Sending…' : (isPartner ? 'Request partnership' : 'Join the waitlist')}
      </Button>
    </div>
  );
}

/* ── Dedicated waitlist section (home) ── */
function Waitlist() {
  return (
    <section className="block" id="waitlist">
      <div className="wrap prequal">
        <div className="prequal-head">
          <span className="eyebrow"><span className="dot" /> Early access</span>
          <h2>Be first to put your rent to work.</h2>
          <p>Gigi Money is rolling out to property owners across Kenya. Join the waitlist and we&rsquo;ll let you know the moment it opens up for you.</p>
        </div>
        <div className="prequal-card">
          <WaitlistForm kind="waitlist" />
          <p style={{ fontSize: 12, color: 'var(--ink-3)', textAlign: 'center', marginTop: 14, lineHeight: 1.5 }}>
            No spam. Just one email when we&rsquo;re ready for you.
          </p>
        </div>
      </div>
    </section>
  );
}

Object.assign(window, {
  GNav: Nav, GFooter: Footer, GBrand: Brand, GProductVisual: ProductVisual,
  GPreviewCard: PreviewCard, gScrollToId: scrollToId, gFmtK: fmtK, gOfferById: offerById,
  GLeadForm: LeadForm, GPrequalify: Prequalify,
  GWaitlistForm: WaitlistForm, GWaitlist: Waitlist,
});
