/* global React */ const { useState, useEffect, useRef, useMemo, useLayoutEffect } = React; // ───────────────────────── Icons ───────────────────────── const Icon = { Lock: ({ size = 14 }) => ( ), Arrow: ({ size = 14 }) => ( ), ArrowLeft: ({ size = 14 }) => ( ), Check: ({ size = 14 }) => ( ), Plus: ({ size = 14 }) => ( ), Calendar: ({ size = 16 }) => ( ), Menu: ({ size = 18 }) => ( ), Close: ({ size = 18 }) => ( ), Upload: ({ size = 14 }) => ( ), Caret: ({ size = 9, open = false }) => ( ), ExtLink: ({ size = 12 }) => ( ), Dot: () => , Search: ({ size = 14 }) => ( ), Filter: ({ size = 14 }) => ( ), }; // ───────────────────────── Wordmark ───────────────────────── const Wordmark = ({ size = 22, color, capex = false }) => ( Buy side {capex && FOR BUYERS} ); // ───────────────────────── Eyebrow / Section header ───────────────────────── const Eyebrow = ({ children, dot = true, color }) => (
{dot && }{children}
); // ───────────────────────── Lock pill ───────────────────────── const LockPill = ({ children = "100% confidential — no listing, no public exposure" }) => ( {children} ); // ───────────────────────── Mobile status bar ───────────────────────── const MobileStatusBar = () => (
9:41
); // ───────────────────────── Intent badge ───────────────────────── const INTENT_META = { actively: { cls: 'intent-actively', label: 'Actively exploring' }, soon: { cls: 'intent-soon', label: 'Planning 6–12 mo' }, later: { cls: 'intent-later', label: 'Planning 1–2 yr' }, curious: { cls: 'intent-curious', label: 'Just curious' }, }; const IntentBadge = ({ kind = 'curious' }) => { const m = INTENT_META[kind] || INTENT_META.curious; return {m.label}; }; // ───────────────────────── Lock tile (anonymous buyer card icon) ───────────────────────── const LockTile = ({ initials, size = 40 }) => (
{initials ? ( {initials} ) : ( )}
); // ───────────────────────── Trust strip ───────────────────────── const TrustStrip = ({ inverse = false }) => (
2,400+ owners matched · $4.2B in active buyer mandates · SOC 2 compliant
); // ───────────────────────── Footer ───────────────────────── const Footer = ({ variant = 'seller', navigate }) => (
A confidential matching service. {variant === 'seller' ? ' A confidential alternative to listing your business.' : ' For verified institutional buyers.'}
{ e.preventDefault(); navigate && navigate('about-story'); }}>Our Story { e.preventDefault(); navigate && navigate('about-team'); }}>Team { e.preventDefault(); navigate && navigate('about-contact'); }}>Contact {variant === 'seller' && { e.preventDefault(); navigate && navigate('data-handling'); }}>What happens next} {variant === 'buyer' && { e.preventDefault(); navigate && navigate('verification'); }}>Verification standards} { e.preventDefault(); navigate && navigate('privacy'); }}>Privacy { e.preventDefault(); navigate && navigate('terms'); }}>Terms
© 2025 Buyside, Inc. SOC 2 Type II · CCPA · GDPR
); // ───────────────────────── NavMenu (dropdown) ───────────────────────── const NavMenu = ({ items, navigate, onPick }) => (
{/* little tick mark up top */}
{items.map((it, i) => ( ))}
); // ───────────────────────── Mobile Nav Drawer ───────────────────────── const MobileNavDrawer = ({ open, onClose, navigate, currentScreen }) => { if (!open) return null; const go = (id) => { navigate(id); onClose(); }; return (
e.stopPropagation()} style={{ position: 'absolute', top: 0, right: 0, bottom: 0, width: 'min(86vw, 340px)', background: 'var(--paper)', boxShadow: '-10px 0 40px rgba(0,0,0,0.15)', display: 'flex', flexDirection: 'column', overflow: 'auto', animation: 'slideInRight 280ms cubic-bezier(0.2,0.8,0.2,1)' }}>

Takes about 90 seconds

); }; // Hamburger button — used in any compact header on mobile const MobileHamburger = ({ onClick }) => ( ); // ───────────────────────── Phone formatter ───────────────────────── const formatPhone = (value) => { const digits = value.replace(/\D/g, '').slice(0, 10); if (digits.length <= 3) return digits; if (digits.length <= 6) return `(${digits.slice(0, 3)}) ${digits.slice(3)}`; return `(${digits.slice(0, 3)}) ${digits.slice(3, 6)}-${digits.slice(6)}`; }; // ───────────────────────── Submit + Generate ───────────────────────── const submitAndGenerate = async (answers) => { const payload = { industry: answers.industry, revenue: answers.revenue, ebitda: answers.ebitda, years_owned: answers.years_owned, state: answers.state, transition: answers.transition, intent: answers.intent, email: answers.email, phone: answers.phone || '', }; // Fire both requests in parallel const [submitRes, generateRes] = await Promise.all([ fetch('/api/submit', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload), }), fetch('/api/generate-results', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload), }), ]); if (!generateRes.ok) throw new Error('Failed to generate results'); const results = await generateRes.json(); return results; }; // Export to window Object.assign(window, { Icon, Wordmark, Eyebrow, LockPill, MobileStatusBar, IntentBadge, INTENT_META, LockTile, TrustStrip, Footer, NavMenu, MobileNavDrawer, MobileHamburger, formatPhone, submitAndGenerate, });