/* ============ CONVERSION PAGES — /pricing, /start, /walkthrough, /referral ============
   Spec: CaliforniaJanitor_Conversion_Brief §4–6. */

/* ---- Numbers strip (§4.1) — the site-wide TrustBar already carries the
   numbers-strip copy (see TRUST_ITEMS in data-home.jsx); this alias exists so
   conversion pages/LPs read like the brief. ---- */
function NumbersStrip() {
  return <TrustBar/>;
}

/* ---- Capacity ticker (§4.3, honest scarcity) ----
   Set window.ESSENTIAL_SLOTS in shell.html to the REAL number of open
   Essential Clean slots (freed crew-hours ÷ package size). Leave null to hide
   the ticker entirely — never show an invented number. Update monthly. */
function CapacityTicker() {
  const n = window.ESSENTIAL_SLOTS;
  if (n == null) return null;
  return (
    <div className="capacity-ticker" role="status">
      <span className="capacity-dot" aria-hidden="true"/>
      <strong>{n} Essential Clean slot{n === 1 ? '' : 's'} open this month</strong>
      <span className="capacity-sub">— real crew capacity, not marketing. When it’s full, it’s full.</span>
    </div>
  );
}

/* ---- Interactive price scale (Zoe, Jul 2026) ----
   Slider in 500 sq ft steps. Same math as the Bid Engine: 3,000 sq ft/hr
   production rate, 1.15 safety factor, $35/hr, $1,000 floor, round UP to $50.
   <= 28 hrs/mo renders the Essential Clean; past it, a Custom Estimate with
   suggested frequency, crew size, and an optional day-porter line item. */
function PriceScale() {
  const MIN = 500, MAX = 20000, STEP = 500;
  const [sqft, setSqft] = useState(3000);
  const [freqOverride, setFreqOverride] = useState(null);
  const [porter, setPorter] = useState(false);
  const usedRef = useRef(false);
  const markUsed = () => {
    if (!usedRef.current) { usedRef.current = true; if (window.track) window.track('price_scale_used', {}); }
  };

  const roundUp50 = (n) => Math.ceil(n / 50) * 50;
  const suggestedFreq = sqft <= 2500 ? 2 : sqft <= 5000 ? 3 : 5;
  const freq = freqOverride || suggestedFreq;
  const perVisit = (sqft / 3000) * 1.15;
  const crew = Math.max(1, Math.ceil(perVisit / 3));
  const perPerson = perVisit / crew;
  // Same napkin engine as the quiz (see bid.jsx) — math stays backstage.
  const est = napkinEstimate({ sqft, visits: freq });
  const monthlyHours = est.hours;
  const isPackage = monthlyHours <= 28;
  const atMax = sqft >= MAX;

  const porterRecommended = sqft >= 10000;
  const porterEst = napkinEstimate({ porter: true });
  const porterPrice = roundUp50((porterEst.low + porterEst.high) / 2);
  const low = isPackage ? 1000 : est.low + (porter ? porterPrice : 0);
  const high = isPackage ? 1000 + (porter ? porterPrice : 0) : est.high + (porter ? porterPrice : 0);

  const fmt = (n) => n.toLocaleString('en-US');
  const fillPct = ((sqft - MIN) / (MAX - MIN)) * 100;

  return (
    <div className="scale">
      <div className="scale-slider-row">
        <input
          type="range" min={MIN} max={MAX} step={STEP} value={sqft}
          onChange={(e) => { markUsed(); setSqft(parseInt(e.target.value, 10)); setFreqOverride(null); }}
          className="quote-slider-range" style={{'--fill': fillPct + '%'}}
          aria-label="Square footage"
        />
        <div className="scale-sqft"><strong>{fmt(sqft)}{sqft >= MAX ? '+' : ''}</strong><span>sq ft</span></div>
      </div>

      <div className="scale-freq" role="radiogroup" aria-label="Visits per week">
        <span className="scale-freq-label">Visits/week</span>
        {[1, 2, 3, 5].map(f => (
          <button key={f} type="button"
            className={`scale-freq-pill ${freq === f ? 'on' : ''}`}
            onClick={() => { markUsed(); setFreqOverride(f); }}
            role="radio" aria-checked={freq === f}>
            {f}x{f === suggestedFreq && <em> · suggested</em>}
          </button>
        ))}
      </div>

      <div className={`scale-card ${isPackage ? 'scale-card-pkg' : ''}`}>
        <div className="label-mono" style={{color: isPackage ? 'var(--success)' : 'var(--accent)'}}>
          {isPackage ? 'THE ESSENTIAL CLEAN — YOUR SIZE FITS THE FLAT PACKAGE' : 'CUSTOM ESTIMATE — PRELIMINARY'}
        </div>
        <div className="scale-price">
          {isPackage
            ? <>${fmt(low + (porter ? porterPrice : 0))}<span>/mo{!porter ? ' flat' : ''}*</span></>
            : atMax
              ? <>from ${fmt(low)}<span>/mo*</span></>
              : <>${fmt(low)}–${fmt(high)}<span>/mo*</span></>}
        </div>
        <div className="scale-plan">
          <span className="scale-chip">{freq}x per week</span>
          <span className="scale-chip">{crew} cleaner{crew > 1 ? 's' : ''}</span>
          <span className="scale-chip">~{perPerson < 1 ? (Math.ceil(perPerson * 4) / 4).toFixed(2).replace(/0+$/, '').replace(/\.$/, '') : (Math.round(perPerson * 2) / 2)} hr{perPerson >= 1.75 ? 's' : ''} each per visit</span>
          {sqft > 5000 && <span className="scale-chip">after-hours</span>}
        </div>


        <label className={`scale-porter ${porterRecommended ? 'recommended' : ''}`}>
          <input type="checkbox" checked={porter} onChange={(e) => { markUsed(); setPorter(e.target.checked); }}/>
          <span>
            <strong>Add a day porter</strong> — on-site during business hours (4 hrs/day, Mon–Fri): +${fmt(porterPrice)}/mo
            {porterRecommended && !porter && <em> · recommended at this size</em>}
          </span>
        </label>
      </div>

      <p className="bid-disclaimer" style={{textAlign: 'left', margin: '14px 0 0'}}>*Preliminary estimate, subject to scope — confirmed at your free 20-minute walkthrough.</p>
      <Link
        to={`/start?sqft=${sqft}&freq=${freq}&porter=${porter ? 1 : 0}&plan=${isPackage ? 'essential' : 'custom'}&low=${low}&high=${high}${atMax ? '&min=1' : ''}`}
        className="btn btn-accent btn-lg" style={{width: '100%', textAlign: 'center', marginTop: 16}}>
        Get started
      </Link>
    </div>
  );
}

/* ---- Shared submit helper for the small conversion forms ---- */
async function postLead(type, payload) {
  try {
    const res = await fetch('/api/bid', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ type, ...payload, sid: (window.track && localStorage.getItem('lamj-sid')) || undefined })
    });
    return await res.json().catch(() => ({ ok: res.ok }));
  } catch (e) { return { ok: false }; }
}

/* ============ /start — signup after a pricing-page choice ============
   No quiz re-run: they already told us size/frequency on the slider (or chose
   the Essential Clean outright). This carries their selection through as a
   prefilled summary + one short contact form. */
function StartPage({ query }) {
  useDocumentHead({
    title: 'Get Started — LA Maintenance & Janitorial',
    description: 'Start commercial cleaning service with LA Maintenance & Janitorial — tell us where to reach you and a real person sets up your walkthrough.',
    canonical: 'https://californiajanitor.com/start'
  });
  const plan = query.plan === 'essential' ? 'essential' : query.plan === 'custom' ? 'custom' : null;
  const sqft = parseInt(query.sqft, 10) || null;
  const freq = parseInt(query.freq, 10) || null;
  const porter = query.porter === '1';
  const low = parseInt(query.low, 10) || null;
  const high = parseInt(query.high, 10) || null;
  const minOnly = query.min === '1';
  const fmt = (n) => n ? n.toLocaleString('en-US') : '';

  const selectionText = plan === 'essential' && !sqft
    ? 'The Essential Clean — $1,000/mo flat'
    : plan
      ? [
          plan === 'essential' ? 'The Essential Clean — $1,000/mo flat' : (low ? (minOnly ? `Custom estimate — from $${fmt(low)}/mo` : low === high ? `Custom estimate — $${fmt(low)}/mo` : `Custom estimate — $${fmt(low)}–$${fmt(high)}/mo`) : 'Custom estimate'),
          sqft ? `${fmt(sqft)}${minOnly ? '+' : ''} sq ft` : null,
          freq ? `${freq}x per week` : null,
          porter ? '+ day porter' : null
        ].filter(Boolean).join(' · ')
      : null;

  const [form, setForm] = useState({ name: '', company: '', phone: '', email: '', notes: '' });
  const [state, setState] = useState('idle');
  const update = (k, v) => setForm(f => ({ ...f, [k]: v }));
  const isEmailValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email.trim());
  const canSubmit = form.name.trim().length >= 2 && isEmailValid && form.phone.replace(/\D/g, '').length >= 10;

  const submit = async (e) => {
    e.preventDefault();
    if (!canSubmit || state === 'sending') return;
    setState('sending');
    track('signup_submit', { plan: plan || 'unknown' });
    await postLead('signup', {
      answers: { ...form, plan: plan || 'unspecified', sqft, freq, porter, selection: selectionText || 'not specified' },
      estimate: plan === 'custom' && low ? { low, high, minOnly } : null
    });
    setState('done');
  };

  if (state === 'done') {
    return (
      <div>
        <section className="page-header no-border">
          <div className="container" style={{textAlign: 'center', maxWidth: 720}}>
            <div className="label-mono" style={{color: 'var(--success)', marginBottom: 16}}>YOU’RE IN</div>
            <h1>Welcome — we’ll take it from here.</h1>
            <div className="bid-next-step" style={{margin: '24px auto 0'}}>
              <strong>What happens next:</strong> a real person reaches out within business hours to schedule your free 20-minute walkthrough — in person or by video — and set your start date. A confirmation is on its way to your inbox.
            </div>
            <p style={{marginTop: 24}}>Need us sooner? Call <a href="tel:3232647800">(323) 264-7800</a>.</p>
          </div>
        </section>
        <NumbersStrip/>
      </div>
    );
  }

  return (
    <div>
      <section className="page-header no-border">
        <div className="container" style={{maxWidth: 760}}>
          <Breadcrumb items={[{ label: 'Home', href: '/' }, { label: 'Get started' }]}/>
          <div className="label-mono" style={{marginBottom: 20}}>GET STARTED</div>
          <h1>Tell us where to reach you.</h1>
          <p className="lead">That’s the whole form. A real person reaches out within business hours to schedule your walkthrough and set your start date.</p>
          {selectionText && (
            <div className="start-selection">
              <span className="label-mono" style={{fontSize: 10}}>YOUR SELECTION</span>
              <strong>{selectionText}</strong>
              <em>Preliminary until your free walkthrough confirms the scope.</em>
            </div>
          )}
        </div>
      </section>
      <section style={{paddingTop: 8}}>
        <div className="container" style={{maxWidth: 760}}>
          <form className="form" onSubmit={submit}>
            <div>
              <label htmlFor="st-name">Your name *</label>
              <input id="st-name" type="text" required autoComplete="name" value={form.name} onChange={e => update('name', e.target.value)}/>
            </div>
            <div>
              <label htmlFor="st-company">Company / building</label>
              <input id="st-company" type="text" autoComplete="organization" value={form.company} onChange={e => update('company', e.target.value)}/>
            </div>
            <div>
              <label htmlFor="st-phone">Mobile *</label>
              <input id="st-phone" type="tel" required autoComplete="tel" value={form.phone} onChange={e => update('phone', e.target.value)}/>
            </div>
            <div>
              <label htmlFor="st-email">Email *</label>
              <input id="st-email" type="email" required autoComplete="email" value={form.email} onChange={e => update('email', e.target.value)}/>
            </div>
            <div className="full">
              <label htmlFor="st-notes">Anything we should know? (address, timing, current vendor…)</label>
              <textarea id="st-notes" rows={3} value={form.notes} onChange={e => update('notes', e.target.value)}/>
            </div>
            <div className="full">
              <button type="submit" className="btn btn-primary btn-xl" disabled={!canSubmit || state === 'sending'}>
                {state === 'sending' ? 'Sending…' : 'Get started'}
              </button>
            </div>
          </form>
        </div>
      </section>
      <NumbersStrip/>
    </div>
  );
}

/* ============ /pricing ============ */
function PricingPage() {
  useDocumentHead({
    title: 'Commercial Cleaning Pricing — Public Rates & the $1,000/mo Essential Clean | LA Maintenance & Janitorial',
    description: 'Our janitorial pricing is public: $35/hr standard, $45/hr specialty, and the Essential Clean — $1,000/month flat for 28 service hours with supplies, backup coverage, and monthly QC included. LA & Orange County.',
    canonical: 'https://californiajanitor.com/pricing'
  });
  return (
    <div>
      <section className="page-header no-border">
        <div className="container">
          <Breadcrumb items={[{ label: 'Home', href: '/' }, { label: 'Pricing' }]}/>
          <div className="label-mono" style={{marginBottom: 20}}>PRICING · MATH OUT IN THE OPEN</div>
          <h1>The only janitorial pricing page in LA that shows its math.</h1>
          <p className="lead">Every competitor says “it depends” and hides the number. It does depend — on hours. So here are the rates, the package, and the exact math. Screenshot it. Use it against other vendors. That’s what it’s for.</p>
          <div className="hero-cta-row">
            <Link to="/bid" className="btn btn-primary btn-lg">Get my price</Link>
            <Link to="/walkthrough" className="btn btn-secondary btn-lg">Book a free walkthrough</Link>
          </div>
        </div>
      </section>
      <NumbersStrip/>

      <section>
        <div className="container">
          <CapacityTicker/>
          <div className="pricing-grid">
            {/* Package card */}
            <div className="pricing-card pricing-card-hero">
              <div className="label-mono" style={{color: 'var(--accent)'}}>THE ESSENTIAL CLEAN</div>
              <div className="pricing-price">$1,000<span>/month flat</span></div>
              <ul className="pricing-list">
                <li><strong>28 service hours</strong> every month</li>
                <li>All supplies &amp; consumables included</li>
                <li>Backup coverage — a sick day on our side is invisible on yours</li>
                <li>Quarterly business review — what changed, what we noticed, what we recommend</li>
                <li>No contracts that need a lawyer, no surprise line items</li>
              </ul>
              <Link to="/start?plan=essential" className="btn btn-accent btn-lg" style={{width: '100%', textAlign: 'center'}}>Get started →</Link>
              <p className="bid-disclaimer">Fits most offices and retail spaces up to ~8,000 sq ft. Preliminary and subject to scope — confirmed at your free walkthrough.</p>
            </div>

            {/* Interactive scale — the math, out in the open, live */}
            <div className="pricing-card">
              <div className="label-mono">SLIDE TO YOUR SIZE — LIVE ESTIMATE</div>
              <PriceScale/>
              <div className="label-mono" style={{marginTop: 28}}>PUBLIC RATES</div>
              <table className="pricing-rates">
                <tbody>
                  <tr><td>Standard janitorial</td><td>$35/hr</td></tr>
                  <tr><td>Specialty (floors, medical protocol, post-construction)</td><td>$45/hr</td></tr>
                  <tr><td>Essential Clean package</td><td>$1,000/mo flat</td></tr>
                </tbody>
              </table>
            </div>
          </div>

          {/* LA cost context for bigger spaces */}
          <div className="pricing-context">
            <h2>Over 8,000 sq ft? Here’s the honest context.</h2>
            <p>Larger LA/OC spaces run on hours, and hours depend on density, floors, restrooms, and tenants — which is why anyone who quotes a big space without seeing it is guessing low to win, then cutting corners to survive. Typical full-service janitorial for larger LA commercial space lands around <strong>$0.10–$0.25 per sq ft per month</strong> depending on frequency and finish level. We’ll give you the real number after a 20-minute walkthrough — on-site, or by video call the same day.</p>
            <div className="hero-cta-row">
              <Link to="/walkthrough" className="btn btn-primary btn-lg">Book a walkthrough</Link>
              <Link to="/walkthrough?type=video" className="btn btn-secondary btn-lg">Video walkthrough — fastest</Link>
            </div>
          </div>
        </div>
      </section>

      {/* Hospitality-grade philosophy (§4.2) */}
      <section className="on-ink">
        <div className="container">
          <div className="section-head">
            <div>
              <div className="eyebrow">The Standard</div>
              <h2 style={{marginTop: 16}}>We clean like the building is ours.</h2>
            </div>
            <p className="lead">Your crew knows your office manager’s name, which conference room has the 9am standing meeting, and that the lobby glass shows every fingerprint by 2pm. That’s not in the contract. It’s just how we work.</p>
          </div>
          <div className="pillars">
            <div className="pillar">
              <h3>Quarterly</h3>
              <p>A sit-down business review — what changed in your space, what we noticed, what we recommend, and where your hours are going. In writing, from hello@.</p>
            </div>
            <div className="pillar">
              <h3>Same-day</h3>
              <p>When something’s off, a real person answers same day — often same hour. A miss gets re-performed, not explained.</p>
            </div>
            <div className="pillar">
              <h3>Always</h3>
              <p>Backup coverage, so a sick day on our side is invisible on yours. Excellence, on a schedule.</p>
            </div>
          </div>
        </div>
      </section>

      {/* Quiz embed */}
      <section>
        <div className="container">
          <div className="section-head">
            <div>
              <div className="eyebrow">Under 1 minute</div>
              <h2 style={{marginTop: 16}}>Find out where your space lands.</h2>
            </div>
            <p className="lead">Six questions. If your space fits the package you’ll see a real preliminary number. If it deserves a walkthrough, we’ll say so — never a naked guess on a big job.</p>
          </div>
          <BidQuiz embedded source="pricing"/>
        </div>
      </section>
      <FinalCTA/>
    </div>
  );
}

/* ============ /walkthrough ============ */
function WalkthroughPage({ type }) {
  useDocumentHead({
    title: 'Book a Free 20-Minute Walkthrough — On-Site or Video | LA Maintenance & Janitorial',
    description: 'Book a free 20-minute commercial cleaning walkthrough — on-site, or by video call with a same-day quote. Your written quote arrives within 2 business hours after the walkthrough. LA & Orange County.',
    canonical: 'https://californiajanitor.com/walkthrough'
  });
  const [mode, setMode] = useState(type === 'video' ? 'video' : 'onsite');
  const [form, setForm] = useState({ name: '', company: '', phone: '', email: '', address: '', times: '', notes: '' });
  const [state, setState] = useState('idle');
  const update = (k, v) => setForm(f => ({ ...f, [k]: v }));
  const isEmailValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email.trim());
  const canSubmit = form.name.trim().length >= 2 && isEmailValid && form.phone.replace(/\D/g, '').length >= 10;

  const submit = async (e) => {
    e.preventDefault();
    if (!canSubmit || state === 'sending') return;
    setState('sending');
    track('walkthrough_booked', { mode });
    const res = await postLead('walkthrough', { answers: { ...form, walkthroughType: mode } });
    setState(res && res.ok !== false ? 'done' : 'done');
  };

  if (state === 'done') {
    return (
      <div>
        <section className="page-header no-border">
          <div className="container" style={{textAlign: 'center', maxWidth: 720}}>
            <div className="label-mono" style={{color: 'var(--success)', marginBottom: 16}}>WALKTHROUGH REQUESTED</div>
            <h1>Done — we’ll confirm your time shortly.</h1>
            <p className="lead">A confirmation is on its way from hello@californiajanitor.com. {mode === 'video' ? 'Have your phone charged — the video walkthrough takes about 10 minutes and your quote lands the same day.' : 'After the walkthrough, your written quote arrives within 2 business hours.'}</p>
            <p style={{marginTop: 24}}>Need it faster? Call <a href="tel:3232647800">(323) 264-7800</a>.</p>
          </div>
        </section>
        <NumbersStrip/>
      </div>
    );
  }

  return (
    <div>
      <section className="page-header no-border">
        <div className="container">
          <Breadcrumb items={[{ label: 'Home', href: '/' }, { label: 'Walkthrough' }]}/>
          <div className="label-mono" style={{marginBottom: 20}}>FREE 20-MINUTE WALKTHROUGH · QUOTE WITHIN 2 BUSINESS HOURS AFTER</div>
          <h1>The walkthrough decides the hours, never the rate.</h1>
          <p className="lead">Twenty minutes of eyes on your space is the difference between an honest bid and a guess. Do it on-site — or point your phone at the space on a 10-minute video call and get your quote the same day.</p>
        </div>
      </section>
      <NumbersStrip/>

      <div className="container">
        <div className="page-body">
          <div>
            <div className="walk-modes" role="radiogroup" aria-label="Walkthrough type">
              <button type="button" className={`walk-mode ${mode === 'onsite' ? 'on' : ''}`} onClick={() => setMode('onsite')} role="radio" aria-checked={mode === 'onsite'}>
                <strong>On-site walkthrough</strong>
                <span>We come to you. Quote within 2 business hours after.</span>
              </button>
              <button type="button" className={`walk-mode ${mode === 'video' ? 'on' : ''}`} onClick={() => setMode('video')} role="radio" aria-checked={mode === 'video'}>
                <strong>Video walkthrough — fastest</strong>
                <span>10-minute video call, phone camera on the space. Same-day quote.</span>
              </button>
            </div>

            <form className="form" onSubmit={submit} style={{marginTop: 32}}>
              <div>
                <label htmlFor="w-name">Your name *</label>
                <input id="w-name" type="text" required autoComplete="name" value={form.name} onChange={e => update('name', e.target.value)}/>
              </div>
              <div>
                <label htmlFor="w-company">Company / building</label>
                <input id="w-company" type="text" autoComplete="organization" value={form.company} onChange={e => update('company', e.target.value)}/>
              </div>
              <div>
                <label htmlFor="w-phone">Mobile *</label>
                <input id="w-phone" type="tel" required autoComplete="tel" value={form.phone} onChange={e => update('phone', e.target.value)}/>
              </div>
              <div>
                <label htmlFor="w-email">Email *</label>
                <input id="w-email" type="email" required autoComplete="email" value={form.email} onChange={e => update('email', e.target.value)}/>
              </div>
              <div className="full">
                <label htmlFor="w-address">{mode === 'onsite' ? 'Building address *' : 'Building address (city is fine)'}</label>
                <input id="w-address" type="text" required={mode === 'onsite'} value={form.address} onChange={e => update('address', e.target.value)}/>
              </div>
              <div className="full">
                <label htmlFor="w-times">Best days / times for you</label>
                <input id="w-times" type="text" placeholder={mode === 'video' ? 'e.g. tomorrow 10am–12pm, or “anytime today”' : 'e.g. Tue/Thu mornings, or before the building opens'} value={form.times} onChange={e => update('times', e.target.value)}/>
              </div>
              <div className="full">
                <label htmlFor="w-notes">Anything we should know?</label>
                <textarea id="w-notes" rows={3} value={form.notes} onChange={e => update('notes', e.target.value)}/>
              </div>
              <div className="full">
                <button type="submit" className="btn btn-primary btn-xl" disabled={!canSubmit || state === 'sending'}>
                  {state === 'sending' ? 'Booking…' : mode === 'video' ? 'Request my video walkthrough' : 'Book my walkthrough'}
                </button>
              </div>
            </form>
          </div>
          <aside>
            <div className="sidebar-card">
              <h4>What we check in 20 minutes</h4>
              <ul>
                <li>Floor types &amp; finish condition</li>
                <li>Restroom count &amp; fixtures</li>
                <li>Kitchen / break areas</li>
                <li>Traffic patterns &amp; tenant expectations</li>
                <li>Trash volume &amp; dumpster access</li>
                <li>After-hours access &amp; alarms</li>
                <li>Anything your current vendor is missing</li>
              </ul>
              <p style={{marginTop: 16}}>Then the hours get mathed at public rates — $35/hr standard, $45/hr specialty — and your written quote arrives within 2 business hours.</p>
            </div>
          </aside>
        </div>
      </div>
      <FinalCTA/>
    </div>
  );
}

/* ============ /referral ============ */
function ReferralPage() {
  useDocumentHead({
    title: '$1,000 Referral Bonus — Introduce Us to a Building | LA Maintenance & Janitorial',
    description: 'Introduce us to a building that needs commercial cleaning. If they sign, you get $1,000 — no cap, no fine print maze. LA & Orange County.',
    canonical: 'https://californiajanitor.com/referral'
  });
  const [form, setForm] = useState({ name: '', email: '', phone: '', intro: '' });
  const [state, setState] = useState('idle');
  const update = (k, v) => setForm(f => ({ ...f, [k]: v }));
  const isEmailValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email.trim());
  const canSubmit = isEmailValid && form.intro.trim().length >= 3;

  const submit = async (e) => {
    e.preventDefault();
    if (!canSubmit || state === 'sending') return;
    setState('sending');
    track('referral_submit', {});
    await postLead('referral', { answers: form });
    setState('done');
  };

  return (
    <div>
      <section className="page-header no-border">
        <div className="container" style={{maxWidth: 800}}>
          <Breadcrumb items={[{ label: 'Home', href: '/' }, { label: 'Referral' }]}/>
          <div className="label-mono" style={{marginBottom: 20}}>REFERRAL BONUS</div>
          <h1>Know a building that needs us? That intro is worth $1,000.</h1>
          <p className="lead">One field. Tell us who to talk to — a property manager, an office admin, a friend whose cleaner keeps missing the corners. If they sign a recurring agreement, you get $1,000. That’s the whole program.</p>
        </div>
      </section>
      <NumbersStrip/>

      <section>
        <div className="container" style={{maxWidth: 720}}>
          {state === 'done' ? (
            <div style={{padding: 48, background: 'var(--bg-soft)', border: '1px solid var(--rule)', textAlign: 'center'}}>
              <div className="label-mono" style={{color: 'var(--success)', marginBottom: 12}}>INTRO RECEIVED</div>
              <h2 style={{fontFamily: 'var(--serif)'}}>Thank you — confirmation coming from hello@.</h2>
              <p style={{marginTop: 16}}>We’ll reach out to them gently (no hard-sell, ever — it’s your name on the intro), and you’ll hear from us the moment anything signs.</p>
            </div>
          ) : (
            <form className="form" onSubmit={submit}>
              <div className="full">
                <label htmlFor="r-intro">The intro *</label>
                <textarea id="r-intro" rows={3} required
                  placeholder="e.g. “Maria Lopez manages the office park at 400 N Brand in Glendale — mlopez@… — their cleaner just quit.”"
                  value={form.intro} onChange={e => update('intro', e.target.value)}/>
              </div>
              <div>
                <label htmlFor="r-name">Your name</label>
                <input id="r-name" type="text" value={form.name} onChange={e => update('name', e.target.value)}/>
              </div>
              <div>
                <label htmlFor="r-email">Your email * <span style={{fontWeight: 400, color: 'var(--muted)'}}>(where the $1,000 news goes)</span></label>
                <input id="r-email" type="email" required value={form.email} onChange={e => update('email', e.target.value)}/>
              </div>
              <div>
                <label htmlFor="r-phone">Your phone</label>
                <input id="r-phone" type="tel" value={form.phone} onChange={e => update('phone', e.target.value)}/>
              </div>
              <div className="full">
                <button type="submit" className="btn btn-primary btn-xl" disabled={!canSubmit || state === 'sending'}>
                  {state === 'sending' ? 'Sending…' : 'Send the intro'}
                </button>
              </div>
              <div className="full">
                <p className="q-help">Bonus pays after their first full month of service. Multiple intros welcome — there’s no cap.</p>
              </div>
            </form>
          )}
        </div>
      </section>
      <FinalCTA/>
    </div>
  );
}

Object.assign(window, { NumbersStrip, CapacityTicker, PricingPage, StartPage, WalkthroughPage, ReferralPage });
