// Product Detail — Content Sections (v2)

const { useState, useEffect, useRef } = React;

// ─── SOCIAL PROOF BAR ───
// Handles two modes:
//   1. Populated (viewersThisWeek + reservedThisMonth) — standard listing chatter
//   2. Launch (sp.launch === true) — honest new-listing badge, no fake numbers
function SocialProofBar() {
  const sp = PRODUCT.socialProof;
  if (!sp) return null;

  if (sp.launch) {
    return React.createElement('div', { style: { display:'flex', gap:14, alignItems:'center', padding:'10px 0', fontSize:12, color:'var(--slate)' }},
      React.createElement('span', { style: { display:'inline-flex', alignItems:'center', gap:6, background:'var(--forest)', color:'var(--gold)', padding:'5px 12px', borderRadius:6, fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.12em', textTransform:'uppercase', fontWeight:500 }},
        React.createElement(PDPIcon, { name:'auto_awesome', size:13 }),
        sp.launchLabel || 'Newly listed'
      ),
    );
  }

  return React.createElement('div', { style: { display:'flex', gap:20, alignItems:'center', padding:'10px 0', fontSize:13, color:'var(--slate)' }},
    sp.viewersThisWeek ? React.createElement('span', { style: { display:'flex', alignItems:'center', gap:6 }},
      React.createElement(PDPIcon, { name:'visibility', size:15, style:{ color:'var(--sage)' }}),
      React.createElement('span', null, sp.viewersThisWeek + ' people viewed this week')
    ) : null,
    sp.reservedThisMonth ? React.createElement('span', { style: { display:'flex', alignItems:'center', gap:6 }},
      React.createElement(PDPIcon, { name:'bookmark_added', size:15, style:{ color:'var(--ember)' }}),
      React.createElement('span', null, sp.reservedThisMonth + ' reserved this month')
    ) : null,
  );
}

// ─── PHOTO LIGHTBOX ───
function Lightbox({ images, startIndex, onClose }) {
  const [idx, setIdx] = useState(startIndex || 0);

  useEffect(() => {
    const handler = (e) => {
      if (e.key === 'Escape') onClose();
      if (e.key === 'ArrowRight') setIdx(i => (i + 1) % images.length);
      if (e.key === 'ArrowLeft') setIdx(i => (i - 1 + images.length) % images.length);
    };
    window.addEventListener('keydown', handler);
    return () => window.removeEventListener('keydown', handler);
  }, [images.length]);

  return React.createElement('div', { onClick: onClose, style: { position:'fixed', inset:0, zIndex:300, background:'rgba(0,0,0,0.92)', display:'flex', alignItems:'center', justifyContent:'center', cursor:'zoom-out' }},
    React.createElement('button', { onClick:onClose, style: { position:'absolute', top:20, right:20, background:'none', border:'none', cursor:'pointer', zIndex:2 }},
      React.createElement(PDPIcon, { name:'close', size:32, style:{ color:'white' }})
    ),
    React.createElement('div', { onClick:e=>e.stopPropagation(), style: { width:'80vw', height:'80vh', maxWidth:1200, position:'relative', cursor:'default' }},
      React.createElement(PlaceholderImg, { index: idx, label: images[idx] }),
      React.createElement('button', { onClick:()=>setIdx((idx-1+images.length)%images.length), style: { position:'absolute', left:-60, top:'50%', transform:'translateY(-50%)', width:48, height:48, borderRadius:'50%', background:'rgba(255,255,255,0.15)', border:'none', cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'center' }},
        React.createElement(PDPIcon, { name:'chevron_left', size:28, style:{ color:'white' }})
      ),
      React.createElement('button', { onClick:()=>setIdx((idx+1)%images.length), style: { position:'absolute', right:-60, top:'50%', transform:'translateY(-50%)', width:48, height:48, borderRadius:'50%', background:'rgba(255,255,255,0.15)', border:'none', cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'center' }},
        React.createElement(PDPIcon, { name:'chevron_right', size:28, style:{ color:'white' }})
      ),
    ),
    React.createElement('div', { style: { position:'absolute', bottom:24, left:'50%', transform:'translateX(-50%)', display:'flex', gap:8 }},
      images.map((_, i) => React.createElement('button', { key:i, onClick:e=>{e.stopPropagation();setIdx(i)}, style: { width: idx===i?24:8, height:8, borderRadius:6, background: idx===i?'white':'rgba(255,255,255,0.4)', border:'none', cursor:'pointer', transition:'all 0.2s' }}))
    ),
    React.createElement('div', { style: { position:'absolute', bottom:24, right:40, color:'rgba(255,255,255,0.6)', fontFamily:'var(--font-mono)', fontSize:13 }}, (idx+1) + ' / ' + images.length)
  );
}

// ─── STICKY RESERVE SIDEBAR ───
// ─── BUY BOX ───
// Commerce-optimized sidebar. Value stack top, primary CTA one, financing snapshot,
// then quiet secondaries. Sticky at top:80 so it rides the scroll.
function ReserveSidebar({ isLoggedIn, userZip, onBuy, onPreApproval, onAsk, onExtendedRange, onEscrow, onPartner, onTurnKey, onContractor, onSignup, onScheduleCall }) {
  const p = PRODUCT;

  // ── Hoisted build state ── {qty, addOns} owned here so price + deposit + downstream Order Sheet stay live.
  const [qty, setQty] = useState(1);
  const [addOnState, setAddOnState] = useState({});

  const tier = (p.quantityTiers || []).find(t => t.qty === qty) || { qty:1, discountPct:0 };
  const unitPriceDiscounted = Math.round(p.price * (1 - tier.discountPct));
  const addOnPerUnitTotal = (p.addOns || []).reduce((s, i) => s + (addOnState[i.key] ? i.price : 0), 0);
  const buildTotal = (unitPriceDiscounted + addOnPerUnitTotal) * qty;
  const displayDeposit = Math.round(buildTotal * 0.20);

  // Publish to window so OrderSheet + other modals can read the current build spec on open.
  // Kept simple — no context provider needed for a single-parent tree.
  window.__PERCH_BUILD__ = { qty, unitPriceDiscounted, addOnState, addOnPerUnitTotal, buildTotal, displayDeposit, discountPct: tier.discountPct };

  // Sidebar chip only — uses conservative baseline (20% down / 20 yr / 7% APR).
  // Financing chip reflects the LIVE build total so estimate scales with qty + add-ons.
  const downAmountChip = displayDeposit;
  const loanAmountChip = buildTotal - downAmountChip;
  const calc = estimateMonthlyPDP(loanAmountChip, 20, 0.07);

  return React.createElement('div', { style: { background:'white', border:'1px solid var(--border)', borderRadius:8, position:'sticky', top:80, boxShadow:'0 2px 12px rgba(28,43,30,0.06)' }},

    // 1. Trust rail
    React.createElement('div', { style: { display:'flex', gap:14, padding:'11px 22px', background:'var(--parchment)', color:'var(--forest-deep)', borderRadius:'8px 8px 0 0', fontSize:10, fontFamily:'var(--font-mono)', letterSpacing:'0.16em', textTransform:'uppercase', alignItems:'center', justifyContent:'center', fontWeight:600, borderBottom:'1px solid var(--border)' }},
      React.createElement('span', { style: { display:'flex', alignItems:'center', gap:5 }}, React.createElement(PDPIcon, { name:'lock', size:12, style:{ color:'var(--ember)' }}), 'Milestone Escrow'),
      React.createElement('span', { style: { color:'rgba(28,61,38,0.25)' }}, '·'),
      React.createElement('span', { style: { display:'flex', alignItems:'center', gap:5 }}, React.createElement(PDPIcon, { name:'verified', size:12, style:{ color:'var(--ember)' }}), 'Licensed Dealer'),
      React.createElement('span', { style: { color:'rgba(28,61,38,0.25)' }}, '·'),
      React.createElement('span', { style: { display:'flex', alignItems:'center', gap:5 }}, React.createElement(PDPIcon, { name:'shield_person', size:12, style:{ color:'var(--ember)' }}), '10-Yr HomeCare'),
    ),

    // 2. Price · Live-updating with qty + add-ons
    React.createElement('div', { style: { padding:'22px 24px 12px' }},
      React.createElement('div', { style: { display:'flex', justifyContent:'space-between', alignItems:'baseline', marginBottom:6 }},
        React.createElement('div', { style: { fontSize:10, fontFamily:'var(--font-mono)', letterSpacing:'0.2em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700 }}, qty > 1 ? 'Build Total · ' + qty + ' units' : 'Base Price'),
        tier.discountPct > 0 && React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.14em', textTransform:'uppercase', color:'var(--sage)', fontWeight:700 }}, tier.savingsLabel),
      ),
      React.createElement('div', { style: { display:'flex', alignItems:'baseline', gap:8 }},
        React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:38, color:'var(--forest-deep)', fontWeight:600, letterSpacing:'-0.015em', lineHeight:1 }}, '$' + buildTotal.toLocaleString()),
        React.createElement('div', { style: { fontSize:11, color:'var(--stone)', fontFamily:'var(--font-mono)', letterSpacing:'0.14em' }}, 'USD'),
      ),
      (qty > 1 || addOnPerUnitTotal > 0) && React.createElement('div', { style: { marginTop:6, fontSize:11, fontFamily:'var(--font-mono)', color:'var(--stone)', letterSpacing:'0.04em' }},
        (qty > 1 ? qty + ' × $' + unitPriceDiscounted.toLocaleString() : '$' + unitPriceDiscounted.toLocaleString()) + (addOnPerUnitTotal > 0 ? ' + $' + addOnPerUnitTotal.toLocaleString() + ' add-ons/unit' : '')
      ),
    ),

    // 3. Freight communicator — chip only, blurb killed to reduce density
    React.createElement('div', { style: { padding:'0 24px 16px' }},
      React.createElement('div', { style: { display:'inline-flex', alignItems:'center', gap:7, padding:'7px 14px', background:'var(--forest-deep)', color:'var(--gold)', borderRadius:6, fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.18em', textTransform:'uppercase', fontWeight:600 }},
        React.createElement(PDPIcon, { name:'local_shipping', size:13 }),
        'Free delivery to 5 states'
      ),
    ),

    // 3b. Build slot counter — real-scarcity signal, sits above milestone payment per Cameron
    React.createElement('div', { style: { padding:'0 24px 16px' }},
      React.createElement(BuildSlotCounter)
    ),

    // 4+5. Milestone footnote (consolidated) — deposit anchor + escrow link on max 2 lines.
    // Full 20/40/40 milestone breakdown lives in the EscrowExplainerModal so the buy box stays light.
    React.createElement('div', { style: { margin:'6px 24px 0', fontFamily:'var(--font-mono)', fontSize:10.5, letterSpacing:'0.04em', color:'var(--forest-deep)', lineHeight:1.5, textAlign:'center' }},
      React.createElement('strong', null, '20% deposit'), ' · $', displayDeposit.toLocaleString(), ' · balance at milestones · ',
      onEscrow && React.createElement('button', {
        onClick: onEscrow,
        style: { background:'none', border:'none', padding:0, fontFamily:'inherit', fontSize:'inherit', letterSpacing:'inherit', color:'var(--forest-deep)', textDecoration:'underline', textDecorationColor:'var(--gold)', textUnderlineOffset:'4px', textDecorationThickness:'1.5px', cursor:'pointer', fontWeight:700, display:'inline' }
      }, 'How it works →')
    ),

    // 6. Specifications strip — sits right above the CTA per decision-hierarchy
    React.createElement('div', { style: { margin:'14px 24px 0', padding:'14px 16px', background:'white', border:'1px solid var(--border)', borderRadius:6 }},
      React.createElement('div', { style: { fontSize:9, fontFamily:'var(--font-mono)', letterSpacing:'0.2em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, marginBottom:10 }}, 'Specifications'),
      React.createElement('div', { style: { display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gap:8, textAlign:'left' }},
        [
          { icon:'straighten', label:'Sq Ft', val: p.sqft },
          { icon:'bed', label:'Bed', val: p.beds },
          { icon:'bathtub', label:'Bath', val: p.baths },
          { icon:'local_shipping', label:'Move-In', val: p.delivery },
        ].map(s =>
          React.createElement('div', { key:s.label, style: { display:'flex', flexDirection:'column', gap:2 }},
            React.createElement('div', { style: { fontSize:8, fontFamily:'var(--font-mono)', color:'var(--stone)', letterSpacing:'0.14em', textTransform:'uppercase', fontWeight:600 }}, s.label),
            React.createElement('div', { style: { fontSize:13, fontWeight:600, color:'var(--forest-deep)', lineHeight:1.15 }}, s.val),
          )
        )
      )
    ),

    // 6b. Quantity tiers — buy 1, 2, or 3 Nests with a factory-setup discount at scale.
    React.createElement(BuyBoxQuantityTiers, { qty, setQty }),

    // 6c. Add-ons — accessibility packages + Unico HVAC upgrade. Live-updates buy box total.
    React.createElement(BuyBoxAddOns, { checked: addOnState, setChecked: setAddOnState }),

    // 6d. Compressed trust cluster — the four verified layers, condensed to a single tight row.
    // The PERCH-Certified chip routes to the standalone /certified page.
    React.createElement(BuyBoxTrustCluster),

    // 7. PRIMARY CTA — Start Your Build (moved to bottom of top section per decision-hierarchy)
    React.createElement('div', { style: { padding:'16px 24px 18px' }},
      React.createElement('button', {
        onClick: onBuy,
        className: 'perch-cta-primary',
        style: { width:'100%', padding:'18px', background:'var(--forest-deep)', color:'var(--gold)', border:'none', fontFamily:'var(--font-mono)', fontSize:12, letterSpacing:'0.22em', textTransform:'uppercase', cursor:'pointer', fontWeight:700, borderRadius:6, boxShadow:'0 8px 24px -8px rgba(20,48,29,0.35), inset 0 1px 0 rgba(232,200,119,0.15)', position:'relative', overflow:'hidden' }
      },
        React.createElement('span', { className:'perch-cta-label' }, 'Start Your Build · $1,000'),
        React.createElement('span', { className:'perch-cta-arrow', style:{ display:'inline-block', marginLeft:8 }}, '→')
      ),

      // 7b. Get Financing — filled sage green (money-action) directly under Start Your Build.
      // Renamed from "Get Pre-Approved" — action-oriented, higher CTR (people are seeking financing, not approvals).
      React.createElement('button', {
        onClick: onPreApproval,
        style: { width:'100%', marginTop:10, padding:'15px', background:'var(--sage)', color:'white', border:'none', fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.22em', textTransform:'uppercase', cursor:'pointer', fontWeight:700, borderRadius:6, transition:'all 0.2s', boxShadow:'0 6px 18px -8px rgba(122,158,118,0.55), inset 0 1px 0 rgba(255,255,255,0.18)' },
        onMouseEnter: e=>{ e.currentTarget.style.filter='brightness(1.08)'; e.currentTarget.style.transform='translateY(-1px)'; },
        onMouseLeave: e=>{ e.currentTarget.style.filter='none'; e.currentTarget.style.transform='none'; }
      }, 'Get Financing →'),
      // Tiny inline monthly-est chip — keeps the price→payment psychological link right at the CTA
      React.createElement('div', { style: { display:'flex', justifyContent:'center', alignItems:'center', gap:6, marginTop:8, fontSize:10, fontFamily:'var(--font-mono)', letterSpacing:'0.14em', textTransform:'uppercase', color:'var(--forest-mid)', fontWeight:600 }},
        React.createElement('span', null, 'Est.'),
        React.createElement('span', { style: { color:'var(--forest-deep)', fontWeight:700 }}, '$' + calc.toLocaleString() + '/mo'),
        React.createElement('span', { style: { color:'var(--stone)' }}, '· 20% down · 20 yr'),
      ),

      // Secure-checkout trust rail — payment-security signal directly beneath CTAs
      React.createElement(SecureCheckoutTrustRail),

      // Share row — sits directly under CTA cluster. Save→Signup expected buyer flow.
      React.createElement(ShareRow, { onSave: onSignup }),
    ),

    // (Financing Snapshot moved to left column as FinancingCalculator component)

    // Quiet secondaries — Ask-a-Q killed (Wren FAB + top-nav CHAT cover it)
    React.createElement('div', { style: { padding:'14px 24px 20px', borderTop:'1px solid var(--border)', display:'flex', flexDirection:'column', gap:8 }},
      // Schedule a Call — founder-answered, bandwidth-preserving. Routes to Cameron with 24h reply.
      onScheduleCall && React.createElement('button', {
        onClick: onScheduleCall,
        style: { width:'100%', padding:'12px', background:'var(--parchment)', color:'var(--forest-deep)', border:'1px solid var(--forest-deep)', fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.16em', textTransform:'uppercase', cursor:'pointer', fontWeight:700, borderRadius:6, display:'flex', alignItems:'center', justifyContent:'center', gap:6 }
      },
        React.createElement(PDPIcon, { name:'phone', size:14 }),
        'Talk to a Human'
      ),
      React.createElement('button', {
        onClick: onContractor || onAsk,
        style: { width:'100%', padding:'11px', background:'none', color:'var(--forest-deep)', border:'1px solid var(--border-strong)', fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.16em', textTransform:'uppercase', cursor:'pointer', fontWeight:600, borderRadius:6, display:'flex', alignItems:'center', justifyContent:'center', gap:6 }
      },
        React.createElement(PDPIcon, { name:'engineering', size:14 }),
        'Share with Contractor'
      ),
      React.createElement('a', {
        href: '/homes/the-nest/spec-sheet',
        target: '_blank',
        rel: 'noopener',
        style: { width:'100%', padding:'10px', background:'none', color:'var(--slate)', border:'1px solid var(--border)', fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.1em', textTransform:'uppercase', cursor:'pointer', fontWeight:500, borderRadius:6, display:'flex', alignItems:'center', justifyContent:'center', gap:6, textDecoration:'none', boxSizing:'border-box' }
      },
        React.createElement(PDPIcon, { name:'picture_as_pdf', size:13 }),
        'Download Spec Sheet'
      ),
      React.createElement('a', {
        href: '/homes/the-nest/financing-worksheet',
        target: '_blank',
        rel: 'noopener',
        style: { width:'100%', padding:'10px', background:'none', color:'var(--slate)', border:'1px solid var(--border)', fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.1em', textTransform:'uppercase', cursor:'pointer', fontWeight:500, borderRadius:6, display:'flex', alignItems:'center', justifyContent:'center', gap:6, textDecoration:'none', boxSizing:'border-box' }
      },
        React.createElement(PDPIcon, { name:'account_balance', size:13 }),
        'Financing Worksheet'
      ),
    )
  );
}

// ─── ORDER SHEET MODAL ─── (Buy This Home)
// Three-step flow: delivery zip → financing method → confirm + deposit.
// Not a full checkout — validates fit and captures the intent to buy with a slot lock.
function OrderSheetModal({ open, onClose }) {
  // Read the live build spec from the buy box on open. Fallbacks keep the modal usable if opened cold.
  const build = (window.__PERCH_BUILD__) || { qty:1, unitPriceDiscounted:129000, addOnState:{}, addOnPerUnitTotal:0, buildTotal:129000, displayDeposit:25800, discountPct:0 };
  const p = window.PRODUCT || {};
  const qty = build.qty || 1;
  const isMulti = qty > 1;

  // Step numbering (preserves existing 1/2/3/4 blocks):
  //   0 = per-unit config (multi only)
  //   1 = delivery zip · 2 = payment method · 3 = review + confirm · 4 = success
  const [step, setStep] = useState(isMulti ? 0 : 1);
  const [activeUnit, setActiveUnit] = useState(0);
  const totalSteps = isMulti ? 4 : 3;
  const stepDisplay = isMulti ? (step + 1) : step;

  // Per-unit configs seeded from the buy-box add-on state so nothing is silently lost.
  const seedUnit = () => {
    const seed = { addOns: { ...(build.addOnState || {}) } };
    (p.customizations || []).forEach(c => { seed[c.category] = c.default; });
    return seed;
  };
  const [units, setUnits] = useState(() => Array.from({ length: qty }, seedUnit));

  const [zip, setZip] = useState('');
  const [financing, setFinancing] = useState('');
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [phone, setPhone] = useState('');
  const [payAmount, setPayAmount] = useState('deposit'); // 'deposit' | 'full'
  const [invoiceOpen, setInvoiceOpen] = useState(false);
  const [invCompany, setInvCompany] = useState('');
  const [invBilling, setInvBilling] = useState('');
  const [invPO, setInvPO] = useState('');
  const [invSent, setInvSent] = useState(false);

  // Recompute totals from per-unit add-on selections (units may diverge from the buy-box seed).
  const perUnitAddOnTotal = (u) => (p.addOns || []).reduce((s, i) => s + (u.addOns[i.key] ? i.price : 0), 0);
  const runningBuildTotal = units.reduce((s, u) => s + build.unitPriceDiscounted + perUnitAddOnTotal(u), 0);
  const runningDeposit = Math.round(runningBuildTotal * 0.20);

  const canFullPay = financing === 'cash';
  const payingAmount = (canFullPay && payAmount === 'full') ? runningBuildTotal : runningDeposit;
  const payingLabel = (canFullPay && payAmount === 'full')
    ? 'Pay in Full · $' + runningBuildTotal.toLocaleString()
    : 'Start Build · $' + runningDeposit.toLocaleString();

  const updateUnit = (idx, patch) => {
    setUnits(us => us.map((u, i) => i === idx ? { ...u, ...patch } : u));
  };
  const toggleUnitAddOn = (idx, key) => {
    setUnits(us => us.map((u, i) => i === idx ? { ...u, addOns: { ...u.addOns, [key]: !u.addOns[key] } } : u));
  };

  if (!open) return null;

  // Contiguous US = in-footprint. HI (967-968) and AK (995-999) get extended-quote treatment.
  const zipPrefix = zip.slice(0,3);
  const isHIAK = zip && (['967','968','995','996','997','998','999'].includes(zipPrefix));
  const inFootprint = zip.length === 5 && !isHIAK;

  const submit = () => {
    const payload = {
      product: 'perch-nest',
      qty,
      units: units.map((u, i) => {
        const selectedAddOns = (p.addOns || []).filter(a => u.addOns[a.key]).map(a => ({ key:a.key, title:a.title, price:a.price }));
        const customizations = {};
        (p.customizations || []).forEach(c => { customizations[c.category] = c.options[u[c.category]] || c.options[c.default]; });
        return { unitNumber: i+1, customizations, addOns: selectedAddOns, addOnTotal: perUnitAddOnTotal(u) };
      }),
      pricing: { unitPriceDiscounted: build.unitPriceDiscounted, discountPct: build.discountPct, buildTotal: runningBuildTotal, deposit: runningDeposit },
      delivery: { zip },
      financing,
      contact: { name, email, phone },
    };
    // eslint-disable-next-line no-console
    console.log('[PERCH] Order intent captured', payload);
    setStep(4);
  };

  return React.createElement('div', {
    onClick: onClose,
    style: { position:'fixed', inset:0, background:'rgba(28,43,30,0.55)', backdropFilter:'blur(6px)', zIndex:1000, display:'flex', alignItems:'center', justifyContent:'center', padding:20 }
  },
    React.createElement('div', {
      onClick: e => e.stopPropagation(),
      style: { background:'var(--cream)', borderRadius:8, maxWidth:520, width:'100%', maxHeight:'90vh', overflow:'auto', boxShadow:'0 20px 60px rgba(0,0,0,0.3)' }
    },
      // Header
      React.createElement('div', { style: { padding:'20px 28px', borderBottom:'1px solid var(--border)', display:'flex', justifyContent:'space-between', alignItems:'center' }},
        React.createElement('div', null,
          React.createElement('div', { style: { fontSize:10, fontFamily:'var(--font-mono)', letterSpacing:'0.14em', textTransform:'uppercase', color:'var(--stone)', fontWeight:600 }}, 'Start Your Build · Step ' + Math.min(stepDisplay, totalSteps) + ' of ' + totalSteps),
          React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:22, fontWeight:600, color:'var(--forest)', marginTop:4 }}, qty > 1 ? qty + ' × The Nest' : 'The Nest'),
        ),
        React.createElement('button', { onClick: onClose, style: { background:'none', border:'none', fontSize:22, cursor:'pointer', color:'var(--stone)', padding:4 }}, '×')
      ),

      // Step 0 — Per-unit configuration (multi only)
      step === 0 && isMulti && React.createElement('div', { style: { padding:'24px 28px' }},
        React.createElement('h3', { style: { fontFamily:'var(--font-display)', fontSize:20, fontWeight:600, marginBottom:6, color:'var(--forest)' }}, 'Configure each unit.'),
        React.createElement('p', { style: { fontSize:13, color:'var(--slate)', lineHeight:1.6, marginBottom:14 }}, 'Pick siding, floor, colors, and add-ons for each of your ' + qty + ' units. All units ship to the same address; each is configured on its own.'),
        // Unit tab strip
        React.createElement('div', { style: { display:'flex', gap:4, marginBottom:16, borderBottom:'1px solid var(--border)' }},
          units.map((u, i) =>
            React.createElement('button', {
              key: i,
              onClick: () => setActiveUnit(i),
              style: {
                padding:'10px 16px', background:'none', border:'none', borderBottom:'2px solid ' + (activeUnit === i ? 'var(--ember)' : 'transparent'),
                fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.14em', textTransform:'uppercase', fontWeight:700,
                color: activeUnit === i ? 'var(--forest-deep)' : 'var(--stone)', cursor:'pointer',
                marginBottom:-1
              }
            },
              'Unit ' + (i+1),
              perUnitAddOnTotal(u) > 0 && React.createElement('span', { style: { marginLeft:6, fontSize:9, color:'var(--sage)' }}, '+$' + perUnitAddOnTotal(u).toLocaleString())
            )
          )
        ),
        // Per-unit pickers — one select per customization category
        React.createElement('div', { style: { display:'flex', flexDirection:'column', gap:12, marginBottom:18 }},
          (p.customizations || []).map(c =>
            React.createElement('div', { key:c.category },
              React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.14em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, marginBottom:5 }}, c.category),
              React.createElement('select', {
                value: units[activeUnit][c.category] ?? c.default,
                onChange: e => updateUnit(activeUnit, { [c.category]: parseInt(e.target.value) }),
                style: { width:'100%', padding:'10px 12px', border:'1px solid var(--border-strong)', borderRadius:6, fontFamily:'var(--font-body)', fontSize:14, background:'white', color:'var(--forest-deep)', boxSizing:'border-box' }
              },
                c.options.map((opt, idx) => React.createElement('option', { key:idx, value:idx }, opt))
              )
            )
          )
        ),
        // Per-unit add-ons
        React.createElement('div', null,
          React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.14em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, marginBottom:8 }}, 'Add-ons for this unit'),
          React.createElement('div', { style: { display:'flex', flexDirection:'column', gap:6 }},
            (p.addOns || []).map(a => {
              const on = !!units[activeUnit].addOns[a.key];
              return React.createElement('label', {
                key: a.key,
                onClick: () => toggleUnitAddOn(activeUnit, a.key),
                style: {
                  display:'flex', gap:10, alignItems:'center', padding:'10px 12px',
                  border:'1px solid ' + (on ? 'var(--ember)' : 'var(--border-strong)'),
                  borderRadius:6, cursor:'pointer',
                  background: on ? 'rgba(196,98,45,0.05)' : 'white'
                }
              },
                React.createElement('div', { style: { width:16, height:16, borderRadius:6, border:'1.5px solid ' + (on ? 'var(--ember)' : 'var(--border-strong)'), background: on ? 'var(--ember)' : 'transparent', flexShrink:0, display:'flex', alignItems:'center', justifyContent:'center', color:'white', fontSize:11, fontWeight:700 }}, on ? '✓' : ''),
                React.createElement('div', { style: { flex:1 }},
                  React.createElement('div', { style: { display:'flex', justifyContent:'space-between', gap:8, alignItems:'baseline' }},
                    React.createElement('div', { style: { fontSize:12, fontWeight:700, color:'var(--forest-deep)' }}, a.title),
                    React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:12, fontWeight:700, color:'var(--forest-deep)' }}, '+$' + a.price.toLocaleString()),
                  )
                )
              );
            })
          )
        ),
        // Running total + nav
        React.createElement('div', { style: { display:'flex', justifyContent:'space-between', alignItems:'center', gap:10, marginTop:20, paddingTop:14, borderTop:'1px solid var(--border)' }},
          React.createElement('div', { style: { fontSize:12, color:'var(--slate)' }},
            'Running total: ',
            React.createElement('strong', { style: { color:'var(--forest-deep)', fontFamily:'var(--font-mono)' }}, '$' + runningBuildTotal.toLocaleString())
          ),
          React.createElement('div', { style: { display:'flex', gap:8 }},
            activeUnit > 0 && React.createElement('button', {
              onClick: () => setActiveUnit(activeUnit - 1),
              style: { padding:'12px 16px', background:'none', color:'var(--slate)', border:'1px solid var(--border-strong)', fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.1em', textTransform:'uppercase', cursor:'pointer', fontWeight:500, borderRadius:6 }
            }, '← Unit ' + activeUnit),
            activeUnit < qty - 1
              ? React.createElement('button', {
                  onClick: () => setActiveUnit(activeUnit + 1),
                  style: { padding:'12px 20px', background:'var(--forest-deep)', color:'var(--gold)', border:'none', fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.1em', textTransform:'uppercase', cursor:'pointer', fontWeight:700, borderRadius:6 }
                }, 'Unit ' + (activeUnit + 2) + ' →')
              : React.createElement('button', {
                  onClick: () => setStep(1),
                  style: { padding:'12px 20px', background:'var(--forest-deep)', color:'var(--gold)', border:'none', fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.14em', textTransform:'uppercase', cursor:'pointer', fontWeight:700, borderRadius:6 }
                }, 'Continue to delivery →'),
          )
        )
      ),

      // Step 1 — Delivery zip
      step === 1 && React.createElement('div', { style: { padding:'24px 28px' }},
        React.createElement('h3', { style: { fontFamily:'var(--font-display)', fontSize:20, fontWeight:600, marginBottom:8, color:'var(--forest)' }}, 'Where should we deliver?'),
        React.createElement('p', { style: { fontSize:13, color:'var(--slate)', lineHeight:1.6, marginBottom:16 }}, isMulti ? "All " + qty + " units ship to the same address. We'll confirm your zip is inside our free-freight states (NC · SC · GA · TN · VA) or quote extended freight within 24 hours." : "We'll confirm your zip is inside our free-freight states. Outside it, we'll quote extended freight within 24 hours."),
        React.createElement('input', { type:'text', value:zip, onChange:e=>setZip(e.target.value.replace(/\D/g,'').slice(0,5)), placeholder:'Delivery zip code', style: { width:'100%', padding:'14px', border:'1px solid var(--border-strong)', borderRadius:6, fontFamily:'var(--font-mono)', fontSize:16, boxSizing:'border-box' }}),
        zip.length === 5 ? React.createElement('div', { style: { marginTop:12, padding:'12px 14px', background: inFootprint ? 'rgba(58,109,88,0.08)' : 'rgba(196,98,45,0.08)', border: '1px solid ' + (inFootprint ? 'var(--sage)' : 'var(--ember)'), borderRadius:6, fontSize:13, color:'var(--slate)', lineHeight:1.6 }},
          inFootprint
            ? React.createElement(React.Fragment, null, React.createElement('strong', { style: { color:'var(--sage)' }}, '✓ Free delivery.'), ' Freight is included in the $129,000/unit sticker. 10–12 weeks to move-in.')
            : React.createElement(React.Fragment, null, React.createElement('strong', { style: { color:'var(--ember)' }}, '⤴ Extended range (HI / AK).'), " We'll quote freight and timeline within 24 hours — no obligation.")
        ) : null,
        React.createElement('div', { style: { display:'flex', gap:8, marginTop:20 }},
          isMulti && React.createElement('button', {
            onClick: () => setStep(0),
            style: { flex:1, padding:'14px', background:'none', color:'var(--slate)', border:'1px solid var(--border-strong)', fontFamily:'var(--font-mono)', fontSize:12, letterSpacing:'0.1em', textTransform:'uppercase', cursor:'pointer', fontWeight:500, borderRadius:6 }
          }, '← Edit units'),
          React.createElement('button', {
            onClick: () => zip.length === 5 && setStep(2),
            disabled: zip.length !== 5,
            style: { flex:isMulti ? 2 : 1, padding:'14px', background:'var(--forest-deep)', color:'var(--gold)', border:'none', fontFamily:'var(--font-mono)', fontSize:12, letterSpacing:'0.1em', textTransform:'uppercase', cursor: zip.length === 5 ? 'pointer' : 'not-allowed', fontWeight:600, borderRadius:6, opacity: zip.length === 5 ? 1 : 0.4 }
          }, 'Continue →'),
        )
      ),

      step === 2 && React.createElement('div', { style: { padding:'24px 28px' }},
        React.createElement('h3', { style: { fontFamily:'var(--font-display)', fontSize:20, fontWeight:600, marginBottom:8, color:'var(--forest)' }}, 'How are you paying?'),
        React.createElement('p', { style: { fontSize:13, color:'var(--slate)', lineHeight:1.6, marginBottom:16 }}, 'For planning only — nothing is charged yet. Balance settles at production milestones.'),
        React.createElement('div', { style: { display:'flex', flexDirection:'column', gap:10 }},
          [
            { key:'cash', label:'Cash / wire', desc:'Straight to escrow at slot confirm + production milestones.' },
            { key:'finance', label:'Modular financing', desc:"20–30 yr fixed via PERCH's lender network. Requires pre-approval." },
            { key:'construction', label:'Construction-to-perm loan', desc:'For buyers financing both land + module together.' },
            { key:'undecided', label:"I'm not sure yet", desc:"Concierge will walk you through options after slot confirms." },
          ].map(opt =>
            React.createElement('label', { key:opt.key, style: { display:'flex', gap:12, padding:'14px', border:'1px solid ' + (financing === opt.key ? 'var(--ember)' : 'var(--border-strong)'), borderRadius:6, cursor:'pointer', background: financing === opt.key ? 'rgba(196,98,45,0.05)' : 'white' }},
              React.createElement('input', { type:'radio', name:'fin', value:opt.key, checked: financing === opt.key, onChange: ()=>setFinancing(opt.key), style: { marginTop:3 }}),
              React.createElement('div', null,
                React.createElement('div', { style: { fontWeight:600, color:'var(--forest)', fontSize:14 }}, opt.label),
                React.createElement('div', { style: { fontSize:12, color:'var(--stone)', marginTop:3, lineHeight:1.5 }}, opt.desc),
              )
            )
          )
        ),
        React.createElement('div', { style: { display:'flex', gap:8, marginTop:20 }},
          React.createElement('button', { onClick: ()=>setStep(1), style: { flex:1, padding:'14px', background:'none', color:'var(--slate)', border:'1px solid var(--border-strong)', fontFamily:'var(--font-mono)', fontSize:12, letterSpacing:'0.1em', textTransform:'uppercase', cursor:'pointer', fontWeight:500, borderRadius:6 }}, '← Back'),
          React.createElement('button', { onClick: ()=>financing && setStep(3), disabled:!financing, style: { flex:2, padding:'14px', background:'var(--forest-deep)', color:'var(--gold)', border:'none', fontFamily:'var(--font-mono)', fontSize:12, letterSpacing:'0.1em', textTransform:'uppercase', cursor: financing ? 'pointer' : 'not-allowed', fontWeight:600, borderRadius:6, opacity: financing ? 1 : 0.4 }}, 'Continue →'),
        )
      ),

      step === 3 && React.createElement('div', { style: { padding:'24px 28px' }},
        React.createElement('h3', { style: { fontFamily:'var(--font-display)', fontSize:20, fontWeight:600, marginBottom:8, color:'var(--forest)' }}, 'Start your build.'),
        React.createElement('p', { style: { fontSize:13, color:'var(--slate)', lineHeight:1.6, marginBottom:16 }}, canFullPay
          ? "You're opening the production ticket for " + (qty > 1 ? qty + ' units of The Nest' : 'The Nest') + ". Pay 20% into licensed escrow to lock your build slot, or settle the full $" + runningBuildTotal.toLocaleString() + " up front — either lands in escrow, and every subsequent release requires dated factory proof + your digital sign-off. Concierge coordinates engineering + site-scope kickoff inside 24 hours."
          : "You're opening the production ticket for " + (qty > 1 ? qty + ' units of The Nest' : 'The Nest') + ". Your 20% production deposit ($" + runningDeposit.toLocaleString() + ") moves into licensed escrow at signing. Every subsequent tranche releases only after our manufacturing partner uploads dated video/photo proof of the milestone and you digitally sign it off. Concierge coordinates engineering + site-scope kickoff inside 24 hours."),

        // Payment amount selector — only when paying cash/wire (financing lanes cover the rest)
        canFullPay && React.createElement('div', { style: { display:'flex', gap:8, marginBottom:16 }},
          [
            { key:'deposit', title:'20% deposit', amount:'$' + runningDeposit.toLocaleString(), note:'Balance settles at milestones' },
            { key:'full',    title:'Pay in full', amount:'$' + runningBuildTotal.toLocaleString(), note:'Skip milestone tranches' },
          ].map(opt =>
            React.createElement('label', { key:opt.key, style: { flex:1, display:'block', padding:'12px 14px', border:'1px solid ' + (payAmount===opt.key?'var(--ember)':'var(--border-strong)'), borderRadius:6, cursor:'pointer', background: payAmount===opt.key?'rgba(196,98,45,0.05)':'white' }},
              React.createElement('input', { type:'radio', name:'payamt', value:opt.key, checked: payAmount===opt.key, onChange:()=>setPayAmount(opt.key), style: { display:'none' }}),
              React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:9, letterSpacing:'0.14em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, marginBottom:4 }}, opt.title),
              React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:18, fontWeight:600, color:'var(--forest-deep)' }}, opt.amount),
              React.createElement('div', { style: { fontSize:11, color:'var(--stone)', marginTop:4, lineHeight:1.4 }}, opt.note),
            )
          )
        ),

        React.createElement('div', { style: { display:'flex', flexDirection:'column', gap:10, marginBottom:12 }},
          React.createElement('input', { type:'text', value:name, onChange:e=>setName(e.target.value), placeholder:'Full name', style: { padding:'12px', border:'1px solid var(--border-strong)', borderRadius:6, fontSize:14, boxSizing:'border-box' }}),
          React.createElement('input', { type:'email', value:email, onChange:e=>setEmail(e.target.value), placeholder:'Email', style: { padding:'12px', border:'1px solid var(--border-strong)', borderRadius:6, fontSize:14, boxSizing:'border-box' }}),
          React.createElement('input', { type:'tel', value:phone, onChange:e=>setPhone(e.target.value), placeholder:'Phone', style: { padding:'12px', border:'1px solid var(--border-strong)', borderRadius:6, fontSize:14, boxSizing:'border-box' }}),
        ),

        React.createElement('div', { style: { padding:'12px 14px', background:'var(--parchment)', borderRadius:6, fontSize:12, color:'var(--slate)', lineHeight:1.6, marginBottom:10 }},
          React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.1em', textTransform:'uppercase', color:'var(--stone)', marginBottom:6, fontWeight:600 }}, 'Summary'),
          isMulti
            ? React.createElement('div', { style: { display:'flex', flexDirection:'column', gap:4, marginBottom:6 }},
                units.map((u, i) => {
                  const addOnCount = (p.addOns || []).filter(a => u.addOns[a.key]).length;
                  const perUnit = build.unitPriceDiscounted + perUnitAddOnTotal(u);
                  return React.createElement('div', { key:i, style: { display:'flex', justifyContent:'space-between', gap:8 }},
                    React.createElement('span', null, 'Unit ' + (i+1) + ' · ' + (addOnCount > 0 ? addOnCount + ' add-on' + (addOnCount>1?'s':'') : 'no add-ons')),
                    React.createElement('strong', { style: { fontFamily:'var(--font-mono)' }}, '$' + perUnit.toLocaleString())
                  );
                })
              )
            : React.createElement(React.Fragment, null,
                React.createElement('div', null, 'The Nest · 567 sq ft · 1BR/1BA'),
              ),
          React.createElement('div', null, 'Deliver to zip ', React.createElement('strong', null, zip)),
          React.createElement('div', null, 'Payment: ', React.createElement('strong', null, ({ cash:'Cash / wire', finance:'Modular financing', construction:'Construction-to-perm loan', undecided:'Decide later' })[financing])),
          React.createElement('div', { style: { marginTop:6, paddingTop:6, borderTop:'1px solid var(--border)' }},
            (canFullPay && payAmount==='full')
              ? React.createElement(React.Fragment, null, 'Paying in full: ', React.createElement('strong', null, '$' + runningBuildTotal.toLocaleString() + ' · to licensed escrow'))
              : React.createElement(React.Fragment, null, 'Production deposit: ', React.createElement('strong', null, '$' + runningDeposit.toLocaleString() + ' (20% of $' + runningBuildTotal.toLocaleString() + ') · to licensed escrow'))
          ),
        ),

        // Invoice request — for buyers who need Bill.com / procurement / PO workflow
        React.createElement('button', {
          onClick: ()=>setInvoiceOpen(true),
          style: { background:'none', border:'none', padding:'6px 0', margin:'0 0 12px', color:'var(--forest-deep)', fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.08em', textTransform:'uppercase', fontWeight:600, cursor:'pointer', textDecoration:'underline', textUnderlineOffset:3, display:'block' }
        }, 'Need an invoice? →'),

        React.createElement('div', { style: { display:'flex', gap:8 }},
          React.createElement('button', { onClick: ()=>setStep(2), style: { flex:1, padding:'14px', background:'none', color:'var(--slate)', border:'1px solid var(--border-strong)', fontFamily:'var(--font-mono)', fontSize:12, letterSpacing:'0.1em', textTransform:'uppercase', cursor:'pointer', fontWeight:500, borderRadius:6 }}, '← Back'),
          React.createElement('button', { onClick: submit, disabled: !(name && email && phone), style: { flex:2, padding:'14px', background:'var(--forest-deep)', color:'var(--gold)', border:'none', fontFamily:'var(--font-mono)', fontSize:12, letterSpacing:'0.1em', textTransform:'uppercase', cursor:(name&&email&&phone)?'pointer':'not-allowed', fontWeight:600, borderRadius:6, opacity:(name&&email&&phone)?1:0.4 }}, payingLabel),
        ),

        // Invoice request sub-modal
        invoiceOpen && React.createElement('div', {
          onClick: ()=>setInvoiceOpen(false),
          style: { position:'fixed', inset:0, background:'rgba(20,48,29,0.55)', backdropFilter:'blur(6px)', zIndex:1100, display:'flex', alignItems:'center', justifyContent:'center', padding:20 }
        },
          React.createElement('div', {
            onClick: e => e.stopPropagation(),
            style: { background:'var(--cream)', borderRadius:8, maxWidth:440, width:'100%', padding:'24px 28px', boxShadow:'0 20px 60px rgba(0,0,0,0.35)' }
          },
            invSent
              ? React.createElement('div', { style: { textAlign:'center', padding:'12px 0' }},
                  React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:20, fontWeight:600, color:'var(--forest)', marginBottom:8 }}, 'Invoice requested.'),
                  React.createElement('p', { style: { fontSize:13, color:'var(--slate)', lineHeight:1.6, marginBottom:16 }}, 'Concierge will send a hosted invoice to ' + invBilling + ' within one business day. Payable via ACH, wire, or check.'),
                  React.createElement('button', { onClick:()=>{ setInvoiceOpen(false); setInvSent(false); setInvCompany(''); setInvBilling(''); setInvPO(''); }, style: { padding:'10px 24px', background:'var(--forest)', color:'var(--gold)', border:'none', fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.1em', textTransform:'uppercase', cursor:'pointer', fontWeight:600, borderRadius:6 }}, 'Close')
                )
              : React.createElement(React.Fragment, null,
                  React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.16em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, marginBottom:6 }}, 'Procurement · Bill.com · PO'),
                  React.createElement('h4', { style: { fontFamily:'var(--font-display)', fontSize:20, fontWeight:600, color:'var(--forest)', marginBottom:8 }}, 'Request an invoice'),
                  React.createElement('p', { style: { fontSize:12, color:'var(--slate)', lineHeight:1.6, marginBottom:14 }}, "We'll email a hosted invoice payable by ACH, wire, or check. Include a PO if your accounting team needs it referenced."),
                  React.createElement('div', { style: { display:'flex', flexDirection:'column', gap:8, marginBottom:14 }},
                    React.createElement('input', { type:'text', value:invCompany, onChange:e=>setInvCompany(e.target.value), placeholder:'Company / entity name', style: { padding:'11px', border:'1px solid var(--border-strong)', borderRadius:6, fontSize:14, boxSizing:'border-box' }}),
                    React.createElement('input', { type:'email', value:invBilling, onChange:e=>setInvBilling(e.target.value), placeholder:'Billing email', style: { padding:'11px', border:'1px solid var(--border-strong)', borderRadius:6, fontSize:14, boxSizing:'border-box' }}),
                    React.createElement('input', { type:'text', value:invPO, onChange:e=>setInvPO(e.target.value), placeholder:'PO number (optional)', style: { padding:'11px', border:'1px solid var(--border-strong)', borderRadius:6, fontSize:14, boxSizing:'border-box' }}),
                  ),
                  React.createElement('div', { style: { display:'flex', gap:8 }},
                    React.createElement('button', { onClick:()=>setInvoiceOpen(false), style: { flex:1, padding:'12px', background:'none', color:'var(--slate)', border:'1px solid var(--border-strong)', fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.1em', textTransform:'uppercase', cursor:'pointer', fontWeight:500, borderRadius:6 }}, 'Cancel'),
                    React.createElement('button', {
                      onClick:()=>{
                        // eslint-disable-next-line no-console
                        console.log('[PERCH] Invoice request', { company:invCompany, billing:invBilling, po:invPO, amount:payingAmount, product:'perch-nest' });
                        setInvSent(true);
                      },
                      disabled: !(invCompany && invBilling),
                      style: { flex:2, padding:'12px', background:'var(--forest-deep)', color:'var(--gold)', border:'none', fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.1em', textTransform:'uppercase', cursor:(invCompany&&invBilling)?'pointer':'not-allowed', fontWeight:600, borderRadius:6, opacity:(invCompany&&invBilling)?1:0.4 }
                    }, 'Send Invoice →'),
                  )
                )
          )
        ),
      ),

      step === 4 && React.createElement('div', { style: { padding:'40px 28px', textAlign:'center' }},
        React.createElement('div', { style: { fontSize:48, marginBottom:12 }}, '✓'),
        React.createElement('h3', { style: { fontFamily:'var(--font-display)', fontSize:24, fontWeight:600, marginBottom:10, color:'var(--forest)' }}, 'Your build is starting.'),
        React.createElement('p', { style: { fontSize:14, color:'var(--slate)', lineHeight:1.7, marginBottom:20, maxWidth:440, margin:'0 auto 20px' }}, "A PERCH concierge will email " + email + " within 24 hours with your build number, engineering docs, escrow wiring instructions, and the milestone verification schedule. First proof upload from the factory lands in your PERCH inbox at the Frame milestone."),
        React.createElement('button', { onClick: onClose, style: { padding:'12px 28px', background:'var(--forest)', color:'var(--gold)', border:'none', fontFamily:'var(--font-mono)', fontSize:12, letterSpacing:'0.1em', textTransform:'uppercase', cursor:'pointer', fontWeight:600, borderRadius:6 }}, 'Close'),
      ),
    )
  );
}

// ─── PRE-APPROVAL MODAL ───
// Soft-inquiry lead capture. Writes to Firestore in prod; dual-purpose:
// (1) route to PERCH lender network partner, (2) captured in-house for follow-up.
// ─── FINANCING MODAL ─── (Get Financing → two-lane picker: Personal via Enhancify, Mortgage via lender intake)
// Kept exported as PreApprovalModal for backwards-compat with existing App wiring.
function PreApprovalModal({ open, onClose }) {
  const [lane, setLane] = useState(null); // null | 'personal' | 'mortgage'
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [phone, setPhone] = useState('');
  const [zip, setZip] = useState('');
  const [buildState, setBuildState] = useState('');
  const [downRange, setDownRange] = useState('');
  const [creditRange, setCreditRange] = useState('');
  const [timing, setTiming] = useState('');
  const [submitted, setSubmitted] = useState(false);

  // Enhancify: rendered via iframe pointing to enhancify-embed.html.
  // The iframe loads a page where the .realwidget div is in DOM *before* their script scans,
  // sidestepping the race condition that fails when we mount the div after page load.
  // Iframe also fires the same-origin fallback if the widget silently declines to render
  // (typically due to domain whitelisting on the Enhancify side).

  if (!open) return null;

  const submit = (e) => {
    e.preventDefault();
    // eslint-disable-next-line no-console
    console.log('[PERCH] Mortgage lender intake', { name, email, phone, zip, buildState, downRange, creditRange, timing, product:'perch-nest' });
    setSubmitted(true);
  };

  const close = () => { setLane(null); setSubmitted(false); onClose(); };

  const laneCard = (key, badge, title, desc, meta) =>
    React.createElement('button', {
      key: key,
      onClick: () => setLane(key),
      style: { display:'block', width:'100%', textAlign:'left', padding:'20px 22px', background:'white', border:'1px solid var(--border-strong)', borderRadius:8, cursor:'pointer', transition:'all 0.15s' },
      onMouseEnter: e => { e.currentTarget.style.borderColor='var(--forest-deep)'; e.currentTarget.style.background='var(--cream-soft)'; },
      onMouseLeave: e => { e.currentTarget.style.borderColor='var(--border-strong)'; e.currentTarget.style.background='white'; },
    },
      React.createElement('div', { style: { display:'inline-block', padding:'3px 8px', background:'var(--gold)', color:'var(--forest-deep)', fontFamily:'var(--font-mono)', fontSize:9, letterSpacing:'0.2em', textTransform:'uppercase', fontWeight:700, borderRadius:6, marginBottom:10 }}, badge),
      React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:20, fontWeight:600, color:'var(--forest-deep)', marginBottom:6, letterSpacing:'-0.005em' }}, title),
      React.createElement('p', { style: { fontSize:13, color:'var(--forest-mid)', lineHeight:1.6, marginBottom:10 }}, desc),
      React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.14em', textTransform:'uppercase', color:'var(--stone)', fontWeight:600 }}, meta)
    );

  return React.createElement('div', {
    onClick: close,
    style: { position:'fixed', inset:0, background:'rgba(20,48,29,0.65)', backdropFilter:'blur(8px)', zIndex:1000, display:'flex', alignItems:'center', justifyContent:'center', padding:20 }
  },
    React.createElement('div', {
      onClick: e => e.stopPropagation(),
      style: { background:'var(--cream)', borderRadius:8, maxWidth: lane === 'personal' ? 720 : 540, width:'100%', maxHeight:'90vh', overflow:'auto', boxShadow:'0 24px 70px rgba(0,0,0,0.35)' }
    },
      // Header
      React.createElement('div', { style: { padding:'20px 28px', borderBottom:'1px solid var(--border)', display:'flex', justifyContent:'space-between', alignItems:'flex-start' }},
        React.createElement('div', null,
          React.createElement('div', { style: { fontSize:10, fontFamily:'var(--font-mono)', letterSpacing:'0.2em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, marginBottom:6 }},
            lane === 'personal' ? 'Personal · Fast Funding via Enhancify' : lane === 'mortgage' ? 'Modular Mortgage · Lender Match' : 'Two Financing Lanes'
          ),
          React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:24, fontWeight:600, color:'var(--forest-deep)' }},
            lane ? (lane === 'personal' ? 'Fund your home fast' : 'Match with a modular lender') : 'Get Financing'
          ),
        ),
        React.createElement('button', { onClick: close, style: { background:'none', border:'none', fontSize:22, cursor:'pointer', color:'var(--stone)', padding:4, lineHeight:1 }}, '×')
      ),

      // Body — three views: picker / personal (Enhancify) / mortgage (intake form)
      !lane ? React.createElement('div', { style: { padding:'22px 28px' }},
        React.createElement('p', { style: { fontSize:13.5, color:'var(--forest-mid)', lineHeight:1.65, marginBottom:18 }},
          "Two paths, one home. Pick the one that fits how you want to fund it — you can switch later."
        ),
        React.createElement('div', { style: { display:'flex', flexDirection:'column', gap:12 }},
          laneCard('personal', 'Fast · Recommended', 'Personal Financing',
            "Up to $200,000 with soft credit check. Funds land in your account. Use it for the full home or just the deposit. No collateral, no lien.",
            'Approvals in minutes · Powered by Enhancify'
          ),
          laneCard('mortgage', 'Traditional', 'Modular Home Mortgage',
            "20–30 year fixed construction-to-perm. Funds released to PERCH milestone-by-milestone through escrow. Requires land + underwriting.",
            'Rate quote in 48h · Lender network'
          ),
        )
      ) : null,

      lane === 'personal' ? React.createElement('div', { style: { padding:'22px 28px' }},
        React.createElement('button', { onClick: () => setLane(null), style: { background:'none', border:'none', color:'var(--forest-deep)', fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.16em', textTransform:'uppercase', cursor:'pointer', padding:'4px 0', fontWeight:600, marginBottom:14 }}, '← Back'),
        React.createElement('p', { style: { fontSize:13.5, color:'var(--forest-mid)', lineHeight:1.65, marginBottom:18 }},
          "Instant soft-pull with our financing partner. Up to $200K. Funds direct to your account, then wire your PERCH deposit or full purchase."
        ),
        // Enhancify iframe — widget mounts in a fresh page context where the div is present at load
        React.createElement('iframe', {
          src: '/homes/the-nest/enhancify-embed',
          title: 'Enhancify · Get Financing',
          style: { width:'100%', border:0, height:560, display:'block', background:'transparent' },
          allow: 'payment'
        }),
        React.createElement('p', { style: { fontSize:10, color:'var(--stone)', textAlign:'center', lineHeight:1.6, marginTop:14, fontStyle:'italic' }},
          'Soft credit check only. Widget served by Enhancify · encrypted, PCI-compliant.'
        )
      ) : null,

      lane === 'mortgage' && !submitted ? React.createElement('form', { onSubmit: submit, style: { padding:'22px 28px' }},
        React.createElement('button', { type:'button', onClick: () => setLane(null), style: { background:'none', border:'none', color:'var(--forest-deep)', fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.16em', textTransform:'uppercase', cursor:'pointer', padding:'4px 0', fontWeight:600, marginBottom:14 }}, '← Back'),
        React.createElement('p', { style: { fontSize:14, color:'var(--forest-mid)', lineHeight:1.6, marginBottom:18, textAlign:'center', maxWidth:440, margin:'0 auto 18px' }},
          "Compare 3 modular specialists — or let us match you in 48h. No hard pull."
        ),

        // Modular-specialist lender comparison — honest courtesy panel, no paid affiliate claims (yet).
        React.createElement('div', { style: { marginBottom:20 }},
          React.createElement('div', { style: { display:'flex', justifyContent:'space-between', alignItems:'baseline', marginBottom:10, flexWrap:'wrap', gap:6 }},
            React.createElement('div', { style: { fontSize:10, fontFamily:'var(--font-mono)', letterSpacing:'0.18em', textTransform:'uppercase', color:'var(--forest-deep)', fontWeight:700 }}, '3 Modular-Specialist Lenders'),
            React.createElement('div', { style: { fontSize:9, fontFamily:'var(--font-mono)', letterSpacing:'0.14em', textTransform:'uppercase', color:'var(--stone)', fontStyle:'italic' }}, '20% down · 30 yr fixed est.'),
          ),
          React.createElement('div', { style: { display:'flex', flexDirection:'column', gap:8 }},
            [
              { name:'21st Mortgage',            rate:'7.25%', apr:'7.42%', badge:'Largest US Modular Lender · Berkshire Hathaway', link:'https://www.21stmortgage.com/' },
              { name:'Cascade Financial',        rate:'7.49%', apr:'7.68%', badge:'50-State C2P · Real Property + Chattel',       link:'https://www.cascadeloans.com/' },
              { name:'Triad Financial Services', rate:'7.75%', apr:'7.94%', badge:'Modular Purchase + Refi Specialist',           link:'https://www.triadfs.com/' },
            ].map(l =>
              React.createElement('a', {
                key: l.name, href: l.link, target: '_blank', rel: 'noopener',
                style: { display:'grid', gridTemplateColumns:'1fr auto auto', gap:14, alignItems:'center', padding:'12px 14px', background:'white', border:'1px solid var(--border-strong)', borderRadius:6, textDecoration:'none', color:'inherit', transition:'all 0.15s' },
                onMouseEnter: e => { e.currentTarget.style.borderColor='var(--forest-deep)'; e.currentTarget.style.background='var(--cream-soft)'; },
                onMouseLeave: e => { e.currentTarget.style.borderColor='var(--border-strong)'; e.currentTarget.style.background='white'; },
              },
                React.createElement('div', null,
                  React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:15, fontWeight:600, color:'var(--forest-deep)' }}, l.name),
                  React.createElement('div', { style: { fontSize:9, fontFamily:'var(--font-mono)', letterSpacing:'0.14em', textTransform:'uppercase', color:'var(--ember)', fontWeight:700, marginTop:2 }}, l.badge),
                ),
                React.createElement('div', { style: { textAlign:'right' }},
                  React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:15, color:'var(--forest-deep)', fontWeight:700 }}, l.rate),
                  React.createElement('div', { style: { fontSize:9, fontFamily:'var(--font-mono)', letterSpacing:'0.1em', textTransform:'uppercase', color:'var(--stone)' }}, l.apr + ' APR'),
                ),
                React.createElement('span', { style: { fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.18em', textTransform:'uppercase', color:'var(--forest-deep)', fontWeight:700 }}, 'Visit →')
              )
            )
          ),
          React.createElement('p', { style: { fontSize:10, color:'var(--stone)', fontStyle:'italic', marginTop:10, lineHeight:1.55 }},
            "Courtesy comparison. Rates shown are published daily averages, not personalized quotes. PERCH doesn't have paid partnerships with these lenders yet — we surface them because they actually finance state-labeled modular homes. Your real rate depends on credit + property."
          ),
        ),

        React.createElement('div', { style: { padding:'12px 14px', background:'var(--cream-soft)', border:'1px dashed var(--border-strong)', borderRadius:6, fontSize:11.5, color:'var(--forest-mid)', lineHeight:1.55, marginBottom:18 }},
          React.createElement('strong', null, 'Prefer we match you? '), "Fill out the intake below — Concierge routes to a modular-specialist lender inside 48h. No hard credit pull."
        ),
        React.createElement('div', { style: { display:'grid', gridTemplateColumns:'1fr 1fr', gap:10, marginBottom:10 }},
          React.createElement('input', { required:true, type:'text', value:name, onChange:e=>setName(e.target.value), placeholder:'Full name', style: { padding:'12px', border:'1px solid var(--border-strong)', borderRadius:6, fontSize:14, boxSizing:'border-box' }}),
          React.createElement('input', { required:true, type:'email', value:email, onChange:e=>setEmail(e.target.value), placeholder:'Email', style: { padding:'12px', border:'1px solid var(--border-strong)', borderRadius:6, fontSize:14, boxSizing:'border-box' }}),
          React.createElement('input', { required:true, type:'tel', value:phone, onChange:e=>setPhone(e.target.value), placeholder:'Phone', style: { padding:'12px', border:'1px solid var(--border-strong)', borderRadius:6, fontSize:14, boxSizing:'border-box' }}),
          React.createElement('input', { required:true, type:'text', value:zip, onChange:e=>setZip(e.target.value.replace(/\D/g,'').slice(0,5)), placeholder:'Property zip', style: { padding:'12px', border:'1px solid var(--border-strong)', borderRadius:6, fontFamily:'var(--font-mono)', fontSize:14, boxSizing:'border-box' }}),
        ),
        React.createElement('select', { required:true, value:downRange, onChange:e=>setDownRange(e.target.value), style: { width:'100%', padding:'12px', border:'1px solid var(--border-strong)', borderRadius:6, fontSize:14, marginBottom:10, background:'white', boxSizing:'border-box' }},
          React.createElement('option', { value:'' }, 'Down payment range'),
          React.createElement('option', { value:'lt-10' }, 'Less than 10% ($<12,900)'),
          React.createElement('option', { value:'10-20' }, '10–20% ($12,900–$25,800)'),
          React.createElement('option', { value:'20-30' }, '20–30% ($25,800–$38,700)'),
          React.createElement('option', { value:'gt-30' }, '30%+ ($38,700+)'),
        ),
        React.createElement('select', { required:true, value:creditRange, onChange:e=>setCreditRange(e.target.value), style: { width:'100%', padding:'12px', border:'1px solid var(--border-strong)', borderRadius:6, fontSize:14, marginBottom:10, background:'white', boxSizing:'border-box' }},
          React.createElement('option', { value:'' }, 'Credit score range'),
          React.createElement('option', { value:'gt-740' }, '740+'),
          React.createElement('option', { value:'700-740' }, '700–740'),
          React.createElement('option', { value:'660-700' }, '660–700'),
          React.createElement('option', { value:'620-660' }, '620–660'),
          React.createElement('option', { value:'lt-620' }, 'Under 620'),
          React.createElement('option', { value:'unsure' }, "Not sure"),
        ),
        React.createElement('select', { required:true, value:timing, onChange:e=>setTiming(e.target.value), style: { width:'100%', padding:'12px', border:'1px solid var(--border-strong)', borderRadius:6, fontSize:14, marginBottom:18, background:'white', boxSizing:'border-box' }},
          React.createElement('option', { value:'' }, 'When would you like to move in?'),
          React.createElement('option', { value:'asap' }, 'ASAP — ready to reserve'),
          React.createElement('option', { value:'3-6m' }, '3–6 months'),
          React.createElement('option', { value:'6-12m' }, '6–12 months'),
          React.createElement('option', { value:'12m+' }, '12+ months / exploring'),
        ),
        React.createElement('button', { type:'submit', style: { width:'100%', padding:'14px', background:'var(--forest-deep)', color:'var(--gold)', border:'none', fontFamily:'var(--font-mono)', fontSize:12, letterSpacing:'0.18em', textTransform:'uppercase', cursor:'pointer', fontWeight:700, borderRadius:6 }}, 'Match Me With a Lender'),
        React.createElement('p', { style: { fontSize:10, color:'var(--stone)', textAlign:'center', lineHeight:1.6, marginTop:10 }},
          'No credit pull. We share with our lender network only after you approve terms.'
        ),
      ) : null,

      lane === 'mortgage' && submitted ? React.createElement('div', { style: { padding:'40px 28px', textAlign:'center' }},
        React.createElement('div', { style: { fontSize:48, marginBottom:12 }}, '✓'),
        React.createElement('h3', { style: { fontFamily:'var(--font-display)', fontSize:22, fontWeight:600, marginBottom:10, color:'var(--forest-deep)' }}, "We're on it."),
        React.createElement('p', { style: { fontSize:14, color:'var(--forest-mid)', lineHeight:1.7, marginBottom:20, maxWidth:400, margin:'0 auto 20px' }}, "A PERCH financing concierge will email " + email + " within 48 hours with matched lender options and a rate range. No hard credit pull without your explicit approval."),
        React.createElement('button', { onClick: close, style: { padding:'12px 28px', background:'var(--forest-deep)', color:'var(--gold)', border:'none', fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.18em', textTransform:'uppercase', cursor:'pointer', fontWeight:700, borderRadius:6 }}, 'Close'),
      ) : null,
    )
  );
}

// ─── ASK MODAL ─── (concierge inbox)
function AskModal({ open, onClose }) {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [question, setQuestion] = useState('');
  const [submitted, setSubmitted] = useState(false);
  if (!open) return null;
  const submit = (e) => { e.preventDefault(); console.log('[PERCH] Ask', { name, email, question, product:'perch-nest' }); setSubmitted(true); };
  return React.createElement('div', { onClick:onClose, style: { position:'fixed', inset:0, background:'rgba(28,43,30,0.55)', backdropFilter:'blur(6px)', zIndex:1000, display:'flex', alignItems:'center', justifyContent:'center', padding:20 }},
    React.createElement('div', { onClick:e=>e.stopPropagation(), style: { background:'var(--cream)', borderRadius:8, maxWidth:480, width:'100%', boxShadow:'0 20px 60px rgba(0,0,0,0.3)' }},
      React.createElement('div', { style: { padding:'20px 28px', borderBottom:'1px solid var(--border)', display:'flex', justifyContent:'space-between', alignItems:'center' }},
        React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:22, fontWeight:600, color:'var(--forest)' }}, 'Ask the Concierge'),
        React.createElement('button', { onClick:onClose, style: { background:'none', border:'none', fontSize:22, cursor:'pointer', color:'var(--stone)', padding:4 }}, '×')
      ),
      !submitted ? React.createElement('form', { onSubmit:submit, style: { padding:'24px 28px' }},
        React.createElement('p', { style: { fontSize:13, color:'var(--slate)', lineHeight:1.6, marginBottom:16 }}, 'Same-day reply from a real person on our team. Not a bot.'),
        React.createElement('input', { required:true, value:name, onChange:e=>setName(e.target.value), placeholder:'Your name', style: { width:'100%', padding:'12px', border:'1px solid var(--border-strong)', borderRadius:6, fontSize:14, marginBottom:10, boxSizing:'border-box' }}),
        React.createElement('input', { required:true, type:'email', value:email, onChange:e=>setEmail(e.target.value), placeholder:'Your email', style: { width:'100%', padding:'12px', border:'1px solid var(--border-strong)', borderRadius:6, fontSize:14, marginBottom:10, boxSizing:'border-box' }}),
        React.createElement('textarea', { required:true, value:question, onChange:e=>setQuestion(e.target.value), placeholder:"What's on your mind?", rows:5, style: { width:'100%', padding:'12px', border:'1px solid var(--border-strong)', borderRadius:6, fontSize:14, marginBottom:16, boxSizing:'border-box', fontFamily:'var(--font-body)', resize:'vertical' }}),
        React.createElement('button', { type:'submit', style: { width:'100%', padding:'14px', background:'var(--forest-deep)', color:'var(--gold)', border:'none', fontFamily:'var(--font-mono)', fontSize:12, letterSpacing:'0.1em', textTransform:'uppercase', cursor:'pointer', fontWeight:600, borderRadius:6 }}, 'Send'),
      ) : React.createElement('div', { style: { padding:'40px 28px', textAlign:'center' }},
        React.createElement('div', { style: { fontSize:48, marginBottom:12 }}, '✓'),
        React.createElement('p', { style: { fontSize:14, color:'var(--slate)', lineHeight:1.7 }}, "Got it. You'll hear from us at " + email + " within the day."),
        React.createElement('button', { onClick:onClose, style: { marginTop:16, padding:'12px 28px', background:'var(--forest)', color:'var(--gold)', border:'none', fontFamily:'var(--font-mono)', fontSize:12, letterSpacing:'0.1em', textTransform:'uppercase', cursor:'pointer', fontWeight:600, borderRadius:6 }}, 'Close'),
      )
    )
  );
}

// ─── INCLUDED vs BUYER RESPONSIBILITY ───
function IncludedSection() {
  return React.createElement('div', { style: { marginTop:40 }},
    React.createElement('h2', { style: { fontFamily:'var(--font-display)', fontSize:28, fontWeight:600, marginBottom:20 }}, "What's Included"),
    React.createElement('div', { style: { display:'flex', flexDirection:'column', gap:16 }},
      // Included — cream card, sage-forest ink for AAA contrast
      React.createElement('div', { style: { background:'var(--cream-soft)', border:'1px solid var(--border)', borderRadius:8, padding:'24px 28px' }},
        React.createElement('div', { style: { display:'flex', alignItems:'center', gap:10, marginBottom:18, paddingBottom:14, borderBottom:'1px solid var(--border)' }},
          React.createElement('span', { style: { display:'inline-flex', width:28, height:28, borderRadius:'50%', background:'var(--forest-deep)', color:'var(--gold)', alignItems:'center', justifyContent:'center' }},
            React.createElement(PDPIcon, { name:'check', size:16 })
          ),
          React.createElement('span', { style: { fontSize:11, fontFamily:'var(--font-mono)', letterSpacing:'0.2em', textTransform:'uppercase', color:'var(--forest-deep)', fontWeight:700 }}, 'Included in $129,000 · Module + Freight'),
        ),
        React.createElement('div', { style: { display:'grid', gridTemplateColumns:'repeat(auto-fill, minmax(260px, 1fr))', gap:'10px 24px' }},
          PRODUCT.included.map(item =>
            React.createElement('div', { key:item, style: { display:'flex', alignItems:'flex-start', gap:10, fontSize:14, color:'var(--forest-deep)', lineHeight:1.55 }},
              React.createElement(PDPIcon, { name:'check', size:15, style:{ color:'var(--sage)', marginTop:3, flexShrink:0 }}),
              React.createElement('span', null, item)
            )
          )
        )
      ),
      // Buyer responsibility
      React.createElement('div', { style: { background:'var(--parchment)', border:'1px solid var(--border)', borderRadius:8, padding:'24px 28px' }},
        React.createElement('div', { style: { display:'flex', alignItems:'center', gap:10, marginBottom:18, paddingBottom:14, borderBottom:'1px solid var(--border)' }},
          React.createElement('span', { style: { display:'inline-flex', width:28, height:28, borderRadius:'50%', background:'var(--ember)', color:'white', alignItems:'center', justifyContent:'center' }},
            React.createElement(PDPIcon, { name:'handyman', size:16 })
          ),
          React.createElement('span', { style: { fontSize:11, fontFamily:'var(--font-mono)', letterSpacing:'0.2em', textTransform:'uppercase', color:'var(--forest-deep)', fontWeight:700 }}, 'Site Scope · $18,000–$28,000 est. · Buyer arranges'),
        ),
        React.createElement('div', { style: { display:'grid', gridTemplateColumns:'repeat(auto-fill, minmax(260px, 1fr))', gap:'10px 24px' }},
          PRODUCT.buyerResponsibility.map(item =>
            React.createElement('div', { key:item, style: { display:'flex', alignItems:'flex-start', gap:10, fontSize:14, color:'var(--forest-deep)', lineHeight:1.55 }},
              React.createElement(PDPIcon, { name:'arrow_forward', size:15, style:{ color:'var(--ember)', marginTop:3, flexShrink:0 }}),
              React.createElement('span', null, item)
            )
          )
        ),
        React.createElement('p', { style: { fontSize:12.5, color:'var(--forest-mid)', marginTop:16, paddingTop:14, borderTop:'1px solid var(--border)', lineHeight:1.6 }},
          'Our concierge team hands you a scoped GC checklist and 2–3 vetted site-partner intros for your county within 48 hours of slot confirm.'
        )
      )
    )
  );
}

// ─── DELIVERY TIMELINE ───
function DeliveryTimeline() {
  const steps = [
    { icon:'assignment', label:'Deposit + Kickoff', desc:'20% production deposit ($25,800) into escrow. Engineering signoff, options locked, build ticket opens.', duration:'Day 0' },
    { icon:'foundation', label:'Frame Milestone', desc:'Our manufacturing partner uploads dated video + photos of your frame. You sign digitally in your PERCH inbox. Next tranche releases.', duration:'Wk 3' },
    { icon:'roofing', label:'Dry-In Milestone', desc:'Sheathing, roof, windows, doors installed. Proof uploaded, signed off, next tranche releases.', duration:'Wk 5' },
    { icon:'electrical_services', label:'Systems Rough-In', desc:'HVAC, electrical, plumbing rough-in verified via proof upload + digital signoff.', duration:'Wk 7' },
    { icon:'local_shipping', label:'Ship + Set', desc:'Flatbed delivery + crane set on your prepared foundation. Final systems tie-in.', duration:'Wk 9' },
    { icon:'home', label:'Move In', desc:'Final signoff. Certificate of occupancy issued. Escrow closes.', duration:'Wk 10–12' },
  ];

  return React.createElement('div', { style: { marginTop:40 }},
    React.createElement('h2', { style: { fontFamily:'var(--font-display)', fontSize:28, fontWeight:600, marginBottom:20 }}, 'Your Timeline'),
    React.createElement('div', { style: { display:'flex', gap:0, position:'relative' }},
      // Connecting line
      React.createElement('div', { className:'timeline-line', style: { position:'absolute', top:26, left:40, right:40, height:1, background:'var(--border-strong)', zIndex:0 }}),
      steps.map((s, i) =>
        React.createElement('div', { key:s.label, style: { flex:1, display:'flex', flexDirection:'column', alignItems:'center', textAlign:'center', position:'relative', zIndex:1 }},
          React.createElement('div', { style: { width:52, height:52, borderRadius:'50%', background: i===steps.length-1 ? 'var(--gold)' : 'var(--forest-deep)', display:'flex', alignItems:'center', justifyContent:'center', marginBottom:12, border:'3px solid var(--cream)', boxShadow: i===steps.length-1 ? '0 4px 16px -4px rgba(232,200,119,0.4)' : '0 2px 8px -2px rgba(20,48,29,0.25)' }},
            React.createElement(PDPIcon, { name:s.icon, size:22, style:{ color: i===steps.length-1 ? 'var(--forest-deep)' : 'var(--gold)' }})
          ),
          React.createElement('div', { style: { fontSize:13, fontWeight:600, color:'var(--forest-deep)', marginBottom:3 }}, s.label),
          React.createElement('div', { style: { fontSize:10, fontFamily:'var(--font-mono)', color:'var(--forest-mid)', marginBottom:6, letterSpacing:'0.14em', textTransform:'uppercase', fontWeight:600 }}, s.duration),
          React.createElement('div', { style: { fontSize:12, color:'var(--forest-mid)', lineHeight:1.55, maxWidth:130, padding:'0 6px' }}, s.desc),
        )
      )
    )
  );
}

// ─── CUSTOMIZATION OPTIONS ───
function CustomizeSection({ onColorChange }) {
  const [selections, setSelections] = useState(
    PRODUCT.customizations.reduce((acc, c) => ({ ...acc, [c.category]: c.default }), {})
  );

  // Compute which options should be disabled in each category based on current selections.
  // Reads two dependency shapes from PRODUCT.customizations[i].dependencies:
  //   { optionIdx: { requires: { CategoryName: idx } } }   → this option requires that cat = idx
  //   { optionIdx: { disables:  { CategoryName: [idx,...] } } } → this option disables those cats' options
  const isDisabled = (cat, optIdx) => {
    // Rule A: another category's currently-selected option explicitly disables this one
    for (const other of PRODUCT.customizations) {
      if (other.category === cat) continue;
      const otherSel = selections[other.category];
      const dep = other.dependencies && other.dependencies[otherSel];
      if (dep && dep.disables && Array.isArray(dep.disables[cat]) && dep.disables[cat].includes(optIdx)) return true;
    }
    // Rule B: this option requires another cat to be at a specific idx, but it isn't
    const c = PRODUCT.customizations.find(x => x.category === cat);
    const dep = c && c.dependencies && c.dependencies[optIdx];
    if (dep && dep.requires) {
      for (const reqCat of Object.keys(dep.requires)) {
        if (selections[reqCat] !== dep.requires[reqCat]) return true;
      }
    }
    return false;
  };

  const pick = (cat, i) => {
    if (isDisabled(cat, i)) return;
    setSelections(s => {
      const next = { ...s, [cat]: i };
      // Auto-resolve: if this option `requires` other cats to be at specific idx, force those too
      const c = PRODUCT.customizations.find(x => x.category === cat);
      const dep = c && c.dependencies && c.dependencies[i];
      if (dep && dep.requires) {
        for (const reqCat of Object.keys(dep.requires)) next[reqCat] = dep.requires[reqCat];
      }
      // If Exterior Color changed (either directly or via requires), fire the color hook
      if (typeof onColorChange === 'function' && next['Exterior Color'] !== s['Exterior Color']) {
        onColorChange(next['Exterior Color']);
      }
      return next;
    });
    if (cat === 'Exterior Color' && typeof onColorChange === 'function') onColorChange(i);
  };

  const renderCard = (c) => {
    const selectedIdx = selections[c.category];
    const activeRender = c.renders && c.renders[selectedIdx];
    return React.createElement('div', { key:c.category, style: { background:'white', border:'1px solid var(--border)', borderRadius:8, padding:18 }},
      React.createElement('div', { style: { fontSize:10, fontFamily:'var(--font-mono)', letterSpacing:'0.18em', textTransform:'uppercase', color:'var(--forest-deep)', marginBottom:14, fontWeight:700 }}, c.category),
      activeRender ? React.createElement('div', { style: { borderRadius:6, overflow:'hidden', border:'1px solid var(--border)', marginBottom:14, aspectRatio:'3 / 2', background:'var(--cream-soft)' }},
        React.createElement('img', { src:'/homes/the-nest/images/' + activeRender, alt: 'The Nest in ' + c.options[selectedIdx].replace(' (included)',''), style: { width:'100%', height:'100%', objectFit:'cover', display:'block' }})
      ) : null,
      React.createElement('div', { style: { display:'flex', gap:8, flexWrap:'wrap' }},
        c.options.map((opt, i) => {
          const swatchStyle = { width:38, height:38, borderRadius:6, border:'1px solid rgba(28,61,38,0.14)', boxShadow:'inset 0 1px 2px rgba(0,0,0,0.08)', overflow:'hidden', flexShrink:0 };
          let swatch;
          if (c.textures && c.textures[i]) {
            swatch = React.createElement('div', { style: swatchStyle },
              React.createElement('img', { src:'/homes/the-nest/images/' + c.textures[i], alt:'', style: { width:'100%', height:'100%', objectFit:'cover', display:'block' }})
            );
          } else if (c.colors) {
            swatch = React.createElement('div', { style: Object.assign({}, swatchStyle, { borderRadius:'50%', background: c.colors[i] }) });
          } else {
            swatch = React.createElement('div', { style: Object.assign({}, swatchStyle, { background:`linear-gradient(135deg, ${PLACEHOLDER_COLORS_PDP[i%8][0]}, ${PLACEHOLDER_COLORS_PDP[i%8][1]})` }) });
          }
          const disabled = isDisabled(c.category, i);
          const selected = selections[c.category] === i;
          return React.createElement('button', {
            key: opt,
            onClick: () => pick(c.category, i),
            disabled,
            title: disabled ? 'Not compatible with your current selections' : undefined,
            style: {
              flex:'1 1 0', minWidth: 84,
              display:'flex', flexDirection:'column', alignItems:'center', gap:8, padding:10,
              border: selected ? '2px solid var(--forest-deep)' : '1px solid var(--border)',
              borderRadius:6,
              cursor: disabled ? 'not-allowed' : 'pointer',
              background: selected ? 'var(--cream-soft)' : 'white',
              opacity: disabled ? 0.35 : 1,
              filter: disabled ? 'grayscale(0.6)' : 'none',
              transition:'all 0.15s',
              position: 'relative',
            }
          },
            swatch,
            React.createElement('span', { style: { fontSize:11, color: selected ? 'var(--forest-deep)' : 'var(--forest-mid)', fontWeight: selected ? 600 : 400, textAlign:'center', lineHeight:1.3 }}, opt),
            disabled ? React.createElement('span', { style: { fontSize:8, fontFamily:'var(--font-mono)', letterSpacing:'0.14em', textTransform:'uppercase', color:'var(--ember)', fontWeight:700 }}, 'Requires Cedar') : null
          );
        })
      )
    );
  };

  // Split into columns: left stacks Siding → Flooring → Cabinet Finish to fill the vertical space
  // next to the tall Exterior Color preview card on the right.
  const rightCol = PRODUCT.customizations.find(c => c.category === 'Exterior Color');
  const leftCol = PRODUCT.customizations.filter(c => c !== rightCol);

  return React.createElement('div', { style: { marginTop:40 }},
    React.createElement('h2', { style: { fontFamily:'var(--font-display)', fontSize:32, fontWeight:600, marginBottom:4, letterSpacing:'-0.01em' }}, 'Customize Your Home'),
    React.createElement('p', { style: { fontSize:14, color:'var(--forest-mid)', marginBottom:22 }}, 'Select your preferred finishes. All options are included in the base price.'),
    React.createElement('div', { style: { display:'grid', gridTemplateColumns:'1fr 1fr', gap:16, alignItems:'start' }},
      React.createElement('div', { style: { display:'flex', flexDirection:'column', gap:16 }},
        leftCol.map(renderCard)
      ),
      rightCol ? renderCard(rightCol) : null
    )
  );
}

// ─── ZONING CHECKER ───
function ZoningChecker() {
  const [zip, setZip] = useState('');
  const [result, setResult] = useState(null);

  const check = () => {
    if (zip.length === 5) {
      const seed = parseInt(zip.slice(0,3));
      setResult({
        aduAllowed: seed % 3 !== 0,
        primaryAllowed: true,
        minLotSize: 4000 + (seed % 6) * 1000,
        setback: 5 + (seed % 10),
        maxHeight: 16 + (seed % 5),
        notes: seed % 3 === 0 ? 'ADU restrictions may apply in this area. Check with your local planning department.' : 'This zip is in a modular-friendly zone. ' + PRODUCT.name + ' meets dimensional requirements.'
      });
    }
  };

  return React.createElement('div', { style: { marginTop:40, padding:24, background:'var(--forest)', borderRadius:8, color:'var(--cream)' }},
    React.createElement('div', { style: { display:'flex', justifyContent:'space-between', alignItems:'flex-start', marginBottom:16 }},
      React.createElement('div', null,
        React.createElement('div', { style: { fontSize:10, fontFamily:'var(--font-mono)', letterSpacing:'0.14em', textTransform:'uppercase', color:'var(--gold)', marginBottom:6, fontWeight:500 }}, 'Zoning Compatibility'),
        React.createElement('h3', { style: { fontFamily:'var(--font-display)', fontSize:24, fontWeight:600 }}, 'Will this home work on your land?'),
      ),
    ),
    React.createElement('div', { style: { display:'flex', gap:10, marginBottom: result ? 20 : 0 }},
      React.createElement('div', { style: { flex:1, display:'flex', alignItems:'center', gap:8, background:'rgba(255,255,255,0.1)', border:'1px solid rgba(255,255,255,0.15)', borderRadius:6, padding:'12px 14px' }},
        React.createElement(PDPIcon, { name:'location_on', size:18, style:{ color:'var(--ember)' }}),
        React.createElement('input', { placeholder:'Enter your zip code', value:zip, onChange:e=>setZip(e.target.value.replace(/\D/g,'').slice(0,5)), onKeyDown:e=>e.key==='Enter'&&check(), style: { border:'none', outline:'none', flex:1, fontFamily:'var(--font-mono)', fontSize:14, background:'transparent', color:'var(--cream)' }}),
      ),
      React.createElement('button', { onClick:check, style: { padding:'12px 24px', background:'var(--forest-deep)', color:'var(--gold)', border:'none', fontFamily:'var(--font-mono)', fontSize:12, letterSpacing:'0.08em', textTransform:'uppercase', cursor:'pointer', fontWeight:500, borderRadius:6 }}, 'Check Zoning'),
    ),
    result && React.createElement('div', null,
      React.createElement('div', { style: { display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gap:12, marginBottom:16 }},
        [{l:'ADU Allowed',v:result.aduAllowed?'Yes':'Restricted',ok:result.aduAllowed},{l:'Primary Use',v:result.primaryAllowed?'Yes':'Check',ok:result.primaryAllowed},{l:'Min. Lot Size',v:result.minLotSize.toLocaleString()+' sq ft',ok:true},{l:'Max Height',v:result.maxHeight+"'",ok:true}].map(s =>
          React.createElement('div', { key:s.l, style: { textAlign:'center', padding:12, background:'rgba(255,255,255,0.06)', borderRadius:6, border:'1px solid rgba(255,255,255,0.1)' }},
            React.createElement('div', { style: { fontSize:10, fontFamily:'var(--font-mono)', letterSpacing:'0.08em', textTransform:'uppercase', color:'rgba(200,219,196,0.6)', marginBottom:4 }}, s.l),
            React.createElement('div', { style: { fontSize:16, fontFamily:'var(--font-mono)', fontWeight:500, color: s.ok ? 'var(--mist)' : 'var(--ember)' }}, s.v),
          )
        )
      ),
      React.createElement('p', { style: { fontSize:13, color:'rgba(251,248,242,0.7)', lineHeight:1.6 }}, result.notes),
      !result.aduAllowed && React.createElement('button', { style: { marginTop:12, padding:'10px 20px', background:'rgba(255,255,255,0.1)', border:'1px solid rgba(255,255,255,0.2)', color:'var(--cream)', fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.08em', textTransform:'uppercase', cursor:'pointer', borderRadius:6 }}, 'Talk to Our Zoning Expert →')
    )
  );
}

// ─── VIRTUAL TOUR PLACEHOLDER ───
function VirtualTourPlaceholder() {
  return React.createElement('div', { style: { marginTop:40, padding:32, background:'var(--parchment)', border:'1px solid var(--border)', borderRadius:8, textAlign:'center' }},
    React.createElement('div', { style: { width:64, height:64, borderRadius:'50%', background:'var(--mist)', display:'flex', alignItems:'center', justifyContent:'center', margin:'0 auto 16px' }},
      React.createElement(PDPIcon, { name:'view_in_ar', size:32, style:{ color:'var(--moss)' }})
    ),
    React.createElement('h3', { style: { fontFamily:'var(--font-display)', fontSize:22, fontWeight:600, marginBottom:6 }}, '3D Virtual Tour'),
    React.createElement('div', { style: { display:'inline-block', fontSize:10, fontFamily:'var(--font-mono)', letterSpacing:'0.1em', textTransform:'uppercase', color:'var(--ember)', padding:'4px 12px', border:'1px solid var(--ember)', borderRadius:20, marginBottom:10, fontWeight:500 }}, 'Coming Soon'),
    React.createElement('p', { style: { fontSize:14, color:'var(--slate)', maxWidth:400, margin:'0 auto', lineHeight:1.6 }}, 'Walk through ' + PRODUCT.name + ' from anywhere. We’ll notify you when the immersive tour is ready.'),
    React.createElement('button', { style: { marginTop:16, padding:'10px 24px', background:'var(--forest)', color:'white', border:'none', fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.08em', textTransform:'uppercase', cursor:'pointer', fontWeight:500, borderRadius:6 }}, 'Notify Me')
  );
}

// ─── DELIVERY ESTIMATOR ─── (logged-out users)
// Freight math is now spec-driven:
//   1) Unit dimensions decide category (standard / wide / super-load)
//   2) Distance = haversine (origin → zip centroid) via state-centroid lookup stub
//   3) Cost = distance × rate/mi for that category
//   4) In-footprint states (NC/SC/GA/TN/VA) return $0 — freight is baked into sticker
function DeliveryEstimator({ isLoggedIn }) {
  const [zipInput, setZipInput] = useState('');
  const [estimated, setEstimated] = useState(null);
  const [showSignup, setShowSignup] = useState(false);

  if (isLoggedIn) return null;

  const p = window.PRODUCT || {};
  const dims = p.unitDimensions || { freightCategory:'super' };
  const freight = p.freight || { origin:{lat:34.1953,lng:-82.1637}, ratePerMile:{standard:4,wide:11,super:20}, includedStates:['NC','SC','GA','TN','VA'], longHaulMiles:800 };

  // ZIP-prefix → { state, lat, lng } state-centroid table. Coarse but useful for an estimate.
  // Prod swaps in a real zip-to-coord lookup (USPS/Census); this keeps the client-side estimate honest to ±10%.
  const zipCentroids = [
    ['005 006 007 008 009 006', 'PR', 18.22, -66.59],
    ['010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027', 'MA', 42.41, -71.38],
    ['028 029', 'RI', 41.68, -71.51],
    ['030 031 032 033 034 035 036 037 038', 'NH', 43.45, -71.57],
    ['039 040 041 042 043 044 045 046 047 048 049', 'ME', 44.69, -69.38],
    ['050 051 052 053 054 056 057 058 059', 'VT', 44.07, -72.71],
    ['060 061 062 063 064 065 066 067 068 069', 'CT', 41.60, -72.76],
    ['070 071 072 073 074 075 076 077 078 079 080 081 082 083 084 085 086 087 088 089', 'NJ', 40.30, -74.52],
    ['100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149', 'NY', 42.17, -74.95],
    ['150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196', 'PA', 40.59, -77.21],
    ['197 198 199', 'DE', 39.32, -75.51],
    ['200 202 203 204 205', 'DC', 38.90, -77.03],
    ['206 207 208 209 210 211 212 214 215 216 217 218 219', 'MD', 39.06, -76.80],
    ['220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246', 'VA', 37.77, -78.17],
    ['247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268', 'WV', 38.49, -80.95],
    ['270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289', 'NC', 35.63, -79.81],
    ['290 291 292 293 294 295 296 297 298 299', 'SC', 33.86, -80.95],
    ['300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 398 399', 'GA', 33.04, -83.64],
    ['320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 341 342 344 346 347 349', 'FL', 27.77, -81.69],
    ['350 351 352 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369', 'AL', 32.81, -86.79],
    ['370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385', 'TN', 35.75, -86.70],
    ['386 387 388 389 390 391 392 393 394 395 396 397', 'MS', 32.74, -89.68],
    ['400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 420 421 422 423 424 425 426 427', 'KY', 37.67, -84.67],
    ['430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458', 'OH', 40.29, -82.79],
    ['460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479', 'IN', 39.85, -86.26],
    ['480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499', 'MI', 43.32, -84.54],
    ['500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 520 521 522 523 524 525 526 527 528', 'IA', 42.01, -93.21],
    ['530 531 532 534 535 537 538 539 540 541 542 543 544 545 546 547 548 549', 'WI', 44.27, -89.62],
    ['550 551 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567', 'MN', 45.69, -93.90],
    ['570 571 572 573 574 575 576 577', 'SD', 44.29, -99.44],
    ['580 581 582 583 584 585 586 587 588', 'ND', 47.53, -99.78],
    ['590 591 592 593 594 595 596 597 598 599', 'MT', 46.92, -110.45],
    ['600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 622 623 624 625 626 627 628 629', 'IL', 40.35, -88.99],
    ['630 631 633 634 635 636 637 638 639 640 641 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658', 'MO', 38.46, -92.29],
    ['660 661 662 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679', 'KS', 38.53, -96.73],
    ['680 681 683 684 685 686 687 688 689 690 691 692 693', 'NE', 41.13, -98.27],
    ['700 701 703 704 705 706 707 708 710 711 712 713 714', 'LA', 31.17, -91.87],
    ['716 717 718 719 720 721 722 723 724 725 726 727 728 729', 'AR', 34.97, -92.37],
    ['730 731 734 735 736 737 738 739 740 741 743 744 745 746 747 748 749', 'OK', 35.57, -96.93],
    ['750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 885', 'TX', 31.05, -97.64],
    ['800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816', 'CO', 39.06, -105.31],
    ['820 821 822 823 824 825 826 827 828 829 830 831', 'WY', 42.75, -107.30],
    ['832 833 834 835 836 837 838', 'ID', 44.24, -114.48],
    ['840 841 842 843 844 845 846 847', 'UT', 40.15, -111.86],
    ['850 852 853 855 856 857 859 860 863 864 865', 'AZ', 33.73, -111.43],
    ['870 871 873 874 875 877 878 879 880 881 882 883 884', 'NM', 34.84, -106.25],
    ['889 890 891 893 894 895 897 898', 'NV', 38.31, -117.06],
    ['900 901 902 903 904 905 906 907 908 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961', 'CA', 37.18, -119.47],
    ['967 968', 'HI', 20.79, -156.34],
    ['970 971 972 973 974 975 976 977 978 979', 'OR', 44.57, -122.07],
    ['980 981 982 983 984 985 986 988 989 990 991 992 993 994', 'WA', 47.40, -121.49],
    ['995 996 997 998 999', 'AK', 61.37, -152.40],
  ];

  const haversine = (lat1, lng1, lat2, lng2) => {
    const R = 3959; // miles
    const toRad = d => d * Math.PI / 180;
    const dLat = toRad(lat2 - lat1);
    const dLng = toRad(lng2 - lng1);
    const a = Math.sin(dLat/2)**2 + Math.cos(toRad(lat1))*Math.cos(toRad(lat2))*Math.sin(dLng/2)**2;
    return Math.round(R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)));
  };

  const estimate = () => {
    if (zipInput.length !== 5) return;
    const prefix = zipInput.slice(0,3);
    const hit = zipCentroids.find(row => row[0].split(' ').includes(prefix));
    if (!hit) return;
    const [, state, lat, lng] = hit;
    const dist = haversine(freight.origin.lat, freight.origin.lng, lat, lng);
    const cat = dims.freightCategory || 'super';
    const rate = freight.ratePerMile[cat] || 20;
    const inFootprint = freight.includedStates.includes(state);
    const longHaul = dist > freight.longHaulMiles;
    const rawCost = Math.round(dist * rate / 100) * 100;
    const cost = inFootprint ? 0 : rawCost;
    const weeks = dist > 1200 ? '12–16' : dist > 600 ? '11–14' : '10–12';
    setEstimated({ state, distance: dist, cost, rawCost, rate, cat, weeks, inFootprint, longHaul });
    setShowSignup(true);
  };

  const catLabel = { standard:'Standard (fits in a lane)', wide:'Wide load (permit)', super:'Super load (permit + pilot cars)' };

  return React.createElement('div', { style: { marginTop:40, padding:24, background:'var(--parchment)', border:'1px solid var(--border)', borderRadius:8 }},
    React.createElement('div', { style: { fontSize:10, fontFamily:'var(--font-mono)', letterSpacing:'0.14em', textTransform:'uppercase', color:'var(--stone)', marginBottom:12, fontWeight:500 }}, 'Delivery Estimate'),
    React.createElement('div', { style: { display:'flex', gap:10, marginBottom: estimated ? 16 : 0 }},
      React.createElement('div', { style: { flex:1, display:'flex', alignItems:'center', gap:8, background:'white', border:'1px solid var(--border-strong)', borderRadius:6, padding:'10px 14px' }},
        React.createElement(PDPIcon, { name:'location_on', size:18, style:{ color:'var(--ember)' }}),
        React.createElement('input', { placeholder:'Enter your zip code', value:zipInput, onChange:e=>setZipInput(e.target.value.replace(/\D/g,'').slice(0,5)), onKeyDown:e=>e.key==='Enter'&&estimate(), style: { border:'none', outline:'none', flex:1, fontFamily:'var(--font-mono)', fontSize:14, background:'transparent', color:'var(--forest)' }}),
      ),
      React.createElement('button', { onClick:estimate, style: { padding:'10px 20px', background:'var(--forest)', color:'white', border:'none', fontFamily:'var(--font-mono)', fontSize:12, letterSpacing:'0.08em', textTransform:'uppercase', cursor:'pointer', fontWeight:500, borderRadius:6 }}, 'Estimate'),
    ),
    estimated && React.createElement(React.Fragment, null,
      React.createElement('div', { style: { display:'grid', gridTemplateColumns:'1fr 1fr 1fr', gap:16, marginBottom:12 }},
        [
          { label:'Distance',       val: estimated.distance.toLocaleString() + ' mi' },
          { label:'Est. Freight',   val: estimated.inFootprint ? 'Included' : ('$' + estimated.cost.toLocaleString()) },
          { label:'Move-In',        val: estimated.weeks + ' wk' },
        ].map(s =>
          React.createElement('div', { key:s.label, style: { textAlign:'center' }},
            React.createElement('div', { style: { fontSize:10, fontFamily:'var(--font-mono)', letterSpacing:'0.08em', textTransform:'uppercase', color:'var(--stone)', marginBottom:4 }}, s.label),
            React.createElement('div', { style: { fontSize:18, fontFamily:'var(--font-mono)', color: s.val === 'Included' ? 'var(--sage)' : 'var(--forest)', fontWeight:500 }}, s.val),
          )
        )
      ),
      React.createElement('div', { style: { padding:'10px 14px', background:'white', border:'1px solid var(--border)', borderLeft:'3px solid ' + (estimated.inFootprint ? 'var(--sage)' : estimated.longHaul ? 'var(--ember)' : 'var(--gold)'), borderRadius:6, fontSize:12, color:'var(--slate)', lineHeight:1.6, marginBottom: showSignup ? 16 : 0 }},
        React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:9, letterSpacing:'0.14em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, marginBottom:6 }}, 'How this was calculated'),
        React.createElement('div', null, 'The Nest is ' + Math.round(dims.widthInches/12*10)/10 + '\' wide → ', React.createElement('strong', null, catLabel[estimated.cat]), '. Freight rate: ', React.createElement('span', { style:{ fontFamily:'var(--font-mono)' }}, '$' + estimated.rate + '/mile'), '. Distance from our SC factory to your zip: ', React.createElement('span', { style:{ fontFamily:'var(--font-mono)' }}, estimated.distance.toLocaleString() + ' mi'), '.'),
        estimated.inFootprint && React.createElement('div', { style: { marginTop:6, color:'var(--sage)', fontWeight:600 }}, '✓ Your state (', estimated.state, ') is one of our five free-freight states — the truck is built into the $', p.price.toLocaleString(), ' sticker.'),
        !estimated.inFootprint && !estimated.longHaul && React.createElement('div', { style: { marginTop:6 }}, 'Your address is outside our five free-freight states, so freight is quoted at ~$', estimated.cost.toLocaleString(), '. Concierge confirms the exact number when you reserve.'),
        estimated.longHaul && React.createElement('div', { style: { marginTop:6, color:'var(--ember)', fontWeight:600 }}, 'This is a long haul (over ', freight.longHaulMiles, ' miles). Concierge quotes freight case-by-case — real number lands within 24 hours of reserve.'),
      ),
      showSignup && React.createElement('div', { style: { padding:16, background:'white', border:'1px solid var(--border)', borderRadius:6, display:'flex', alignItems:'center', justifyContent:'space-between', gap:16 }},
        React.createElement('div', null,
          React.createElement('div', { style: { fontSize:14, fontWeight:500, color:'var(--forest)', marginBottom:2 }}, 'Save your delivery estimate'),
          React.createElement('div', { style: { fontSize:12, color:'var(--stone)' }}, 'Create a free account to lock in pricing and track availability.'),
        ),
        React.createElement('button', { style: { padding:'10px 20px', background:'var(--forest-deep)', color:'var(--gold)', border:'none', fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.08em', textTransform:'uppercase', cursor:'pointer', fontWeight:500, borderRadius:6, whiteSpace:'nowrap' }}, 'Create Account')
      )
    )
  );
}

// ─── FAQ SECTION ───
function FAQSection() {
  const [openIdx, setOpenIdx] = useState(null);
  const [q, setQ] = useState('');
  const filtered = q.trim()
    ? PRODUCT.faqs.map((f, i) => ({ f, i })).filter(({f}) => (f.q + ' ' + f.a).toLowerCase().includes(q.trim().toLowerCase()))
    : PRODUCT.faqs.map((f, i) => ({ f, i }));

  return React.createElement('div', { style: { marginTop:40 }},
    React.createElement('h2', { style: { fontFamily:'var(--font-display)', fontSize:28, fontWeight:600, marginBottom:14 }}, 'Frequently Asked Questions'),
    React.createElement('div', { style: { marginBottom:14, position:'relative' }},
      React.createElement('input', {
        type:'search', value:q, onChange:e=>setQ(e.target.value),
        placeholder:'Search the FAQ — try "escrow", "financing", "warranty"…',
        style: { width:'100%', padding:'12px 16px 12px 40px', border:'1px solid var(--border-strong)', borderRadius:6, fontFamily:'var(--font-body)', fontSize:14, boxSizing:'border-box', background:'white' }
      }),
      React.createElement('span', { style: { position:'absolute', left:14, top:'50%', transform:'translateY(-50%)', fontSize:16, color:'var(--stone)', pointerEvents:'none' }}, '⌕')
    ),
    filtered.length === 0 && React.createElement('div', { style: { padding:'24px', textAlign:'center', color:'var(--stone)', fontSize:13, background:'var(--parchment)', border:'1px solid var(--border)', borderRadius:6 }},
      'No FAQs match "' + q + '". Try a different word — or ', React.createElement('a', { href:'#', onClick:(e)=>{e.preventDefault(); window.dispatchEvent(new CustomEvent('perch:open-schedule-call'));}, style:{ color:'var(--forest-deep)', textDecoration:'underline' }}, 'ask a human'), '.'
    ),
    filtered.length > 0 && React.createElement('div', { style: { display:'flex', flexDirection:'column', gap:0, border:'1px solid var(--border)', borderRadius:8, overflow:'hidden' }},
      filtered.map(({f: faq, i}) =>
        React.createElement('div', { key:i, style: { borderBottom: i < PRODUCT.faqs.length-1 ? '1px solid var(--border)' : 'none' }},
          React.createElement('button', { onClick:()=>setOpenIdx(openIdx===i?null:i), style: { width:'100%', padding:'16px 20px', background: openIdx===i ? 'var(--parchment)' : 'white', border:'none', cursor:'pointer', display:'flex', justifyContent:'space-between', alignItems:'center', textAlign:'left', transition:'background 0.15s' }},
            React.createElement('span', { style: { fontSize:15, fontWeight:500, color:'var(--forest)' }}, faq.q),
            React.createElement(PDPIcon, { name: openIdx===i ? 'expand_less' : 'expand_more', size:20, style:{ color:'var(--stone)' }})
          ),
          openIdx===i && React.createElement('div', { style: { padding:'0 20px 16px', background:'var(--parchment)' }},
            React.createElement('p', { style: { fontSize:14, color:'var(--slate)', lineHeight:1.7 }}, faq.a)
          )
        )
      )
    )
  );
}

// ─── SPECS TABLE ───
function SpecsSection() {
  return React.createElement('div', { style: { marginTop:40 }},
    React.createElement('h2', { style: { fontFamily:'var(--font-display)', fontSize:32, fontWeight:600, marginBottom:20, letterSpacing:'-0.01em' }}, 'Specifications'),
    // Cleaner two-col table: consistent label width via grid, no zebra stripes, subtle hairline dividers
    React.createElement('div', { style: { border:'1px solid var(--border)', borderRadius:8, overflow:'hidden', background:'var(--cream-soft)' }},
      React.createElement('div', { style: { display:'grid', gridTemplateColumns:'1fr 1fr' }},
        PRODUCT.specs.map((s, i) => {
          const isLastRow = i >= PRODUCT.specs.length - 2;
          const isRightCol = i % 2 === 1;
          return React.createElement('div', { key:s.label, style: { padding:'16px 22px', display:'grid', gridTemplateColumns:'130px 1fr', gap:16, alignItems:'baseline', borderBottom: isLastRow ? 'none' : '1px solid var(--border)', borderLeft: isRightCol ? '1px solid var(--border)' : 'none' }},
            React.createElement('span', { style: { fontSize:10, fontFamily:'var(--font-mono)', color:'var(--stone)', letterSpacing:'0.16em', textTransform:'uppercase', fontWeight:600 }}, s.label),
            React.createElement('span', { style: { fontSize:14, color:'var(--forest-deep)', fontWeight:500, lineHeight:1.45 }}, s.value),
          );
        })
      )
    ),
    // Features
    React.createElement('div', { style: { marginTop:24 }},
      React.createElement('h3', { style: { fontSize:10, fontFamily:'var(--font-mono)', letterSpacing:'0.14em', textTransform:'uppercase', color:'var(--stone)', marginBottom:12, fontWeight:500 }}, 'Included Features'),
      React.createElement('div', { style: { display:'flex', gap:8, flexWrap:'wrap' }},
        PRODUCT.features.map(f =>
          React.createElement('span', { key:f, style: { display:'flex', alignItems:'center', gap:4, fontSize:13, padding:'6px 14px', background:'var(--parchment)', border:'1px solid var(--border)', borderRadius:6, color:'var(--forest)' }},
            React.createElement(PDPIcon, { name:'check_circle', size:14, style:{ color:'var(--sage)' }}), f
          )
        )
      )
    ),
    // Floor plan — styled card w/ caption band + hover-interactive overlay on the image.
    // Sizing/grid preserved exactly per Cameron. Overlay = absolute regions over image + micro-callout in caption band.
    React.createElement(SpecsFloorPlanCard)
  );
}

// Extracted so the state (hovered room) lives cleanly without threading through SpecsSection.
function SpecsFloorPlanCard() {
  const rooms = PRODUCT.floorplanRooms || [];
  const [hover, setHover] = useState(null);
  const hovered = hover !== null ? rooms[hover] : null;
  return React.createElement('div', { style: { marginTop:32, border:'1px solid var(--border)', borderRadius:8, overflow:'hidden', background:'var(--cream-soft)' }},
    React.createElement('div', { style: { padding:'14px 22px', borderBottom:'1px solid var(--border)', background:'white', display:'flex', justifyContent:'space-between', alignItems:'center', flexWrap:'wrap', gap:12 }},
      React.createElement('div', { style: { display:'flex', alignItems:'center', gap:10, flexWrap:'wrap' }},
        React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.2em', textTransform:'uppercase', color:'var(--forest-deep)', fontWeight:700 }}, 'Floor Plan · 36\'-0" × 16\'-0" outside walls'),
        React.createElement('span', { style: { display:'inline-flex', alignItems:'center', gap:4, fontFamily:'var(--font-mono)', fontSize:9, letterSpacing:'0.14em', textTransform:'uppercase', color:'var(--ember)', fontWeight:700, padding:'2px 8px', background:'rgba(196,98,45,0.08)', border:'1px solid var(--ember)', borderRadius:6 }},
          React.createElement('span', { style: { fontSize:10 }}, '⌘'), 'Hover a room'
        ),
      ),
      React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.16em', textTransform:'uppercase', color:'var(--stone)', fontWeight:600 }}, 'Sheet 1 / 1 · Rev A · PERCH'),
    ),
    React.createElement('div', { style: { display:'grid', gridTemplateColumns:'1fr 240px' }},
      React.createElement('div', { style: { padding:28, display:'flex', alignItems:'center', justifyContent:'center', borderRight:'1px solid var(--border)', position:'relative' }},
        // Wrapper matches img bounds exactly (inline-block + no letterboxing) so overlay tracks image, not container.
        React.createElement('div', { style: { position:'relative', display:'inline-block', maxWidth:'100%', maxHeight:360, borderRadius:8, overflow:'hidden' }},
          React.createElement('img', { src:'/homes/the-nest/images/floor-plan.png', alt:'The Nest floor plan — 36\' × 16\' outside walls, bedroom 10×13, bath, kitchen 16×6, living 13×14', style: { display:'block', maxWidth:'100%', maxHeight:360, height:'auto', width:'auto', mixBlendMode:'multiply' }, loading:'lazy' }),
          // Hover regions positioned as % of image bounds. Tune coords in PRODUCT.floorPlanRooms.
          React.createElement('div', { style: { position:'absolute', inset:0, pointerEvents:'none' }},
            rooms.map((r, i) =>
              React.createElement('div', {
                key: r.name,
                onMouseEnter: ()=>setHover(i),
                onMouseLeave: ()=>setHover(prev => prev === i ? null : prev),
                style: {
                  position:'absolute',
                  left: r.xPct + '%', top: r.yPct + '%', width: r.wPct + '%', height: r.hPct + '%',
                  border: '1.5px solid ' + (hover === i ? 'var(--ember)' : 'transparent'),
                  background: hover === i ? 'rgba(196,98,45,0.12)' : 'transparent',
                  pointerEvents:'auto', cursor:'pointer', transition:'all 0.15s', borderRadius:6,
                }
              })
            )
          ),
          // Micro-tooltip anchored to hovered region (top-right of the region if space, else top-left)
          hovered && React.createElement('div', {
            style: {
              position:'absolute',
              left: (hovered.xPct + hovered.wPct + 1) + '%',
              top: hovered.yPct + '%',
              maxWidth: 180,
              padding:'8px 10px',
              background:'var(--forest-deep)', color:'var(--gold)',
              fontFamily:'var(--font-mono)', fontSize:10, lineHeight:1.4, fontWeight:600,
              borderRadius:6, boxShadow:'0 6px 18px rgba(20,48,29,0.35)',
              pointerEvents:'none', zIndex:2,
            }
          },
            React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:13, marginBottom:3, color:'white' }}, hovered.name),
            React.createElement('div', { style: { color:'var(--gold)', marginBottom:4, letterSpacing:'0.1em' }}, hovered.sqft),
            React.createElement('div', { style: { fontSize:10, fontFamily:'var(--font-body)', color:'rgba(232,200,119,0.85)', lineHeight:1.5, textTransform:'none', letterSpacing:0, fontWeight:400 }}, hovered.notes),
          )
        )
      ),
      React.createElement('div', { style: { padding:'22px 24px', display:'flex', flexDirection:'column', gap:0 }},
        React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:9, letterSpacing:'0.18em', textTransform:'uppercase', color:'var(--stone)', fontWeight:600, marginBottom:12 }}, 'Rooms · Sq Ft'),
        (PRODUCT.floorplanRooms || []).map((r, i) =>
          React.createElement('div', { key:r.name, style: { padding:'12px 0', borderBottom: i < (PRODUCT.floorplanRooms || []).length-1 ? '1px solid var(--border)' : 'none', display:'flex', justifyContent:'space-between', alignItems:'baseline' }},
            React.createElement('span', { style: { fontSize:14, color:'var(--forest-deep)', fontWeight:500 }}, r.name),
            React.createElement('span', { style: { fontSize:11, fontFamily:'var(--font-mono)', color:'var(--forest-mid)', letterSpacing:'0.06em' }}, r.sqft),
          )
        )
      )
    )
  );
}

// ─── BUILDER PROFILE ───
function BuilderSection() {
  const b = PRODUCT.builder;
  const meta = [];
  if (b.rating) meta.push(React.createElement('span', { key:'r', style: { display:'flex', alignItems:'center', gap:4 }}, React.createElement('span', { style:{ color:'var(--gold)', fontWeight:600 }}, '★ ' + b.rating), ' (' + b.reviews + ' reviews)'));
  if (b.deliveries) meta.push(React.createElement('span', { key:'d' }, b.deliveries + ' homes delivered'));
  if (b.since) meta.push(React.createElement('span', { key:'s' }, 'Since ' + b.since));
  if (b.location) meta.push(React.createElement('span', { key:'l' }, b.location));

  return React.createElement('div', { style: { marginTop:40, padding:24, background:'white', border:'1px solid var(--border)', borderRadius:8 }},
    React.createElement('div', { style: { fontSize:10, fontFamily:'var(--font-mono)', letterSpacing:'0.14em', textTransform:'uppercase', color:'var(--stone)', marginBottom:12, fontWeight:500 }}, 'Listed By'),
    React.createElement('div', { style: { display:'flex', gap:16, alignItems:'flex-start', marginBottom:16 }},
      React.createElement('div', { style: { width:56, height:56, borderRadius:'50%', background:'var(--forest)', display:'flex', alignItems:'center', justifyContent:'center', color:'var(--gold)', fontFamily:'var(--font-display)', fontSize:22, fontWeight:600, flexShrink:0 }}, b.name.split(' ').map(w=>w[0]).join('')),
      React.createElement('div', { style: { flex:1 }},
        React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:22, fontWeight:600 }}, b.name),
        meta.length ? React.createElement('div', { style: { display:'flex', gap:16, fontSize:12, color:'var(--slate)', marginTop:4, flexWrap:'wrap' }}, meta) : null,
      )
    ),
    React.createElement('p', { style: { fontSize:14, color:'var(--slate)', lineHeight:1.7, marginBottom:16 }}, b.bio),
    React.createElement('div', { style: { display:'flex', gap:16, fontSize:12, fontFamily:'var(--font-mono)', color:'var(--sage)', flexWrap:'wrap', marginBottom: PRODUCT.regulatoryPositioning ? 18 : 0 }},
      React.createElement('span', { style: { display:'flex', alignItems:'center', gap:4 }}, React.createElement(PDPIcon, { name:'schedule', size:14 }), b.responseTime),
      React.createElement('span', { style: { display:'flex', alignItems:'center', gap:4 }}, React.createElement(PDPIcon, { name:'verified', size:14 }), 'Licensed modular dealer'),
      React.createElement('span', { style: { display:'flex', alignItems:'center', gap:4 }}, React.createElement(PDPIcon, { name:'lock', size:14 }), 'Escrow-guaranteed'),
    ),
    // "Who you're buying from" ribbon — merged in from the standalone RegulatoryStrip to consolidate page length.
    PRODUCT.regulatoryPositioning && React.createElement('div', { style: { padding:'16px 20px', background:'var(--forest-deep)', color:'var(--gold)', borderRadius:6 }},
      React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:9, letterSpacing:'0.22em', textTransform:'uppercase', fontWeight:700, marginBottom:6, opacity:0.75 }}, 'Who you’re buying from'),
      React.createElement('p', { style: { fontFamily:'var(--font-display)', fontSize:14.5, lineHeight:1.55, margin:0, fontWeight:400 }}, PRODUCT.regulatoryPositioning)
    )
  );
}

// ─── MANUFACTURER DISCLOSURE ───
// Public disclosure of manufacturing partnership (Priceline pattern — cert + label public, name revealed at Reserve).
// Includes anchor manufacturing partner drone shot so the manufacturing footprint is physical, not abstract.
function ManufacturerDisclosure() {
  const m = PRODUCT.manufacturer;
  if (!m) return null;
  return React.createElement('div', { style: { marginTop:24, background:'var(--parchment)', border:'1px solid var(--border)', borderLeft:'3px solid var(--forest-deep)', borderRadius:6, overflow:'hidden' }},
    // Factory drone shot header
    React.createElement('div', { style: { position:'relative', width:'100%', height:220, overflow:'hidden', background:'var(--forest-deep)' }},
      React.createElement('img', {
        src: '/homes/the-nest/images/biltwise-factory.webp',
        alt: 'Our anchor manufacturing partner facility',
        style: { width:'100%', height:'100%', objectFit:'cover', display:'block' }
      }),
      React.createElement('div', {
        style: { position:'absolute', inset:0, background:'linear-gradient(to bottom, rgba(20,48,29,0.15) 0%, rgba(20,48,29,0.55) 75%, rgba(20,48,29,0.85) 100%)' }
      }),
      React.createElement('div', { style: { position:'absolute', bottom:16, left:22, right:22, color:'var(--cream)' }},
        React.createElement('div', { style: { fontSize:10, fontFamily:'var(--font-mono)', letterSpacing:'0.2em', textTransform:'uppercase', color:'var(--gold)', fontWeight:700, marginBottom:4 }}, 'Anchor Manufacturing Partner'),
        React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:20, fontWeight:600, letterSpacing:'-0.005em' }}, 'NC modular state-labeled · NTA-certified'),
      )
    ),

    // Body
    React.createElement('div', { style: { padding:'22px 26px' }},
      React.createElement('div', { style: { fontSize:10, fontFamily:'var(--font-mono)', letterSpacing:'0.2em', textTransform:'uppercase', color:'var(--forest-deep)', marginBottom:14, fontWeight:700 }}, 'Manufacturing Partnership'),
      React.createElement('p', { style: { fontSize:14, color:'var(--forest-mid)', lineHeight:1.75, marginBottom:18 }}, m.disclosure),
      React.createElement('div', { style: { display:'grid', gridTemplateColumns:'repeat(auto-fit, minmax(170px, 1fr))', gap:14, borderTop:'1px solid var(--border)', paddingTop:16 }},
        React.createElement('div', null,
          React.createElement('div', { style: { fontSize:9, fontFamily:'var(--font-mono)', letterSpacing:'0.16em', textTransform:'uppercase', color:'var(--stone)', marginBottom:5, fontWeight:600 }}, 'Certification'),
          React.createElement('div', { style: { fontSize:13, color:'var(--forest-deep)', fontWeight:500 }}, m.stateLabel)
        ),
        React.createElement('div', null,
          React.createElement('div', { style: { fontSize:9, fontFamily:'var(--font-mono)', letterSpacing:'0.16em', textTransform:'uppercase', color:'var(--stone)', marginBottom:5, fontWeight:600 }}, 'NTA Certified'),
          React.createElement('div', { style: { fontSize:13, color:'var(--forest-deep)', fontWeight:500 }}, m.ntaCertDate)
        ),
        React.createElement('div', null,
          React.createElement('div', { style: { fontSize:9, fontFamily:'var(--font-mono)', letterSpacing:'0.16em', textTransform:'uppercase', color:'var(--stone)', marginBottom:5, fontWeight:600 }}, 'Full Disclosure'),
          React.createElement('div', { style: { fontSize:13, color:'var(--forest-deep)', fontWeight:500 }}, 'At Reserve / signing')
        )
      )
    )
  );
}

// ─── REVIEWS ───
function ReviewsSection() {
  const hasReviews = PRODUCT.reviews && PRODUCT.reviews.length > 0;
  const empty = PRODUCT.reviewsEmptyState || { title: 'Be the first.', body: 'Reviews open at first delivery.' };

  return React.createElement('div', { style: { marginTop:40 }},
    React.createElement('div', { style: { display:'flex', justifyContent:'space-between', alignItems:'baseline', marginBottom:20 }},
      React.createElement('h2', { style: { fontFamily:'var(--font-display)', fontSize:28, fontWeight:600 }}, 'Reviews'),
      hasReviews ? React.createElement('div', { style: { display:'flex', alignItems:'center', gap:8 }},
        React.createElement('span', { style: { fontFamily:'var(--font-mono)', fontSize:18, color:'var(--gold)', fontWeight:600 }}, '★ ' + (PRODUCT.reviews.reduce((s,r)=>s+r.rating,0)/PRODUCT.reviews.length).toFixed(1)),
        React.createElement('span', { style: { fontSize:13, color:'var(--stone)' }}, PRODUCT.reviews.length + ' reviews'),
      ) : null
    ),
    hasReviews
      ? React.createElement('div', { style: { display:'flex', flexDirection:'column', gap:12 }},
          PRODUCT.reviews.map((r, i) =>
            React.createElement('div', { key:i, style: { padding:20, background:'white', border:'1px solid var(--border)', borderRadius:6 }},
              React.createElement('div', { style: { display:'flex', justifyContent:'space-between', marginBottom:8 }},
                React.createElement('div', null,
                  React.createElement('span', { style: { fontWeight:600, fontSize:14 }}, r.name),
                  React.createElement('span', { style: { fontSize:12, color:'var(--stone)', marginLeft:8 }}, r.location),
                ),
                React.createElement('div', { style: { display:'flex', alignItems:'center', gap:4 }},
                  React.createElement('span', { style: { color:'var(--gold)', fontSize:13, fontWeight:600 }}, '★'.repeat(r.rating)),
                  React.createElement('span', { style: { fontSize:11, color:'var(--stone)', fontFamily:'var(--font-mono)' }}, r.date),
                )
              ),
              React.createElement('p', { style: { fontSize:14, color:'var(--slate)', lineHeight:1.7 }}, r.text)
            )
          )
        )
      : React.createElement('div', { style: { padding:'40px 32px', background:'var(--parchment)', border:'1px solid var(--border)', borderRadius:6, display:'grid', gridTemplateColumns:'auto 1fr', gap:24, alignItems:'center' }},
          // Editorial placeholder mark — half-tone paper shield with quiet gold hairline
          React.createElement('div', { style: { flexShrink:0, width:88, height:88, borderRadius:'50%', background:'white', border:'1px solid var(--gold)', display:'flex', alignItems:'center', justifyContent:'center' }},
            React.createElement('span', { style: { fontFamily:'var(--font-display)', fontSize:32, color:'var(--forest-deep)', fontWeight:600 }}, '★')
          ),
          React.createElement('div', null,
            React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.14em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, marginBottom:6 }}, 'Reviews open at first delivery'),
            React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:22, fontWeight:600, color:'var(--forest-deep)', marginBottom:8 }}, empty.title),
            React.createElement('p', { style: { fontSize:14, color:'var(--slate)', lineHeight:1.7, maxWidth:560, margin:0 }}, empty.body)
          )
        )
  );
}

// ─── SIMILAR HOMES ─── (honest empty state — no fake marketplace inventory)
function SimilarHomes() {
  return React.createElement('div', { style: { marginTop:40 }},
    React.createElement('h2', { style: { fontFamily:'var(--font-display)', fontSize:28, fontWeight:600, marginBottom:14 }}, 'Similar Homes'),
    React.createElement('div', { style: { padding:'32px', background:'var(--parchment)', border:'1px solid var(--border)', borderRadius:6, display:'grid', gridTemplateColumns:'auto 1fr auto', gap:24, alignItems:'center' }},
      React.createElement('div', { style: { flexShrink:0, width:72, height:72, borderRadius:'50%', background:'white', border:'1px solid var(--forest-deep)', display:'flex', alignItems:'center', justifyContent:'center', fontFamily:'var(--font-display)', fontSize:28, color:'var(--forest-deep)', fontWeight:600 }}, '◐'),
      React.createElement('div', null,
        React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.14em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, marginBottom:6 }}, 'Marketplace inventory'),
        React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:20, fontWeight:600, color:'var(--forest-deep)', marginBottom:6 }}, 'More listings arrive as builders join PERCH-Certified.'),
        React.createElement('p', { style: { fontSize:13, color:'var(--slate)', lineHeight:1.6, margin:0 }}, "We won't fill this space with placeholder inventory. Real listings from real Certified builders — announced as they clear the standard.")
      ),
      React.createElement('a', { href:'#', onClick:(e)=>{e.preventDefault(); window.dispatchEvent(new CustomEvent('perch:open-signup'));}, style: { padding:'12px 18px', background:'var(--forest-deep)', color:'var(--gold)', border:'none', fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.14em', textTransform:'uppercase', cursor:'pointer', fontWeight:700, borderRadius:6, textDecoration:'none', whiteSpace:'nowrap' }}, 'Notify me'),
    )
  );
}

// ─── STICKY MOBILE CTA ───
function MobileCTA({ onBuy }) {
  return React.createElement('div', { className:'mobile-cta', style: { position:'fixed', bottom:0, left:0, right:0, background:'white', borderTop:'1px solid var(--border)', padding:'12px 20px', display:'none', justifyContent:'space-between', alignItems:'center', zIndex:150, boxShadow:'0 -4px 20px rgba(0,0,0,0.08)' }},
    React.createElement('div', null,
      React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:22, color:'var(--forest)', fontWeight:600 }}, '$' + PRODUCT.price.toLocaleString()),
      React.createElement('div', { style: { fontSize:11, color:'var(--stone)', fontFamily:'var(--font-mono)' }}, 'module + freight'),
    ),
    React.createElement('button', { onClick: onBuy, style: { background:'var(--forest-deep)', color:'var(--gold)', border:'none', padding:'12px 24px', fontFamily:'var(--font-mono)', fontSize:12, letterSpacing:'0.08em', textTransform:'uppercase', cursor:'pointer', fontWeight:600, borderRadius:6 }}, 'Start Your Build →')
  );
}

// ─── TURN-KEY ESTIMATOR MODAL ───
// Opened on demand from a small link near the CTA. Kept out of the buy box
// so we don't headline a $152K number when only $129K is what we actually charge.
function TurnKeyEstimatorModal({ open, onClose }) {
  const p = PRODUCT;
  const [prep, setPrep] = useState(23000);
  if (!open) return null;
  const lo = p.siteScopeEstimate?.low || 18000;
  const hi = p.siteScopeEstimate?.high || 28000;
  const total = p.price + prep;
  return React.createElement('div', {
    onClick: onClose,
    style: { position:'fixed', inset:0, background:'rgba(20,48,29,0.65)', backdropFilter:'blur(8px)', zIndex:1000, display:'flex', alignItems:'center', justifyContent:'center', padding:20 }
  },
    React.createElement('div', {
      onClick: e => e.stopPropagation(),
      style: { background:'var(--cream)', borderRadius:8, maxWidth:520, width:'100%', boxShadow:'0 24px 70px rgba(0,0,0,0.35)', overflow:'hidden' }
    },
      React.createElement('div', { style: { padding:'22px 28px', borderBottom:'1px solid var(--border)', display:'flex', justifyContent:'space-between', alignItems:'flex-start' }},
        React.createElement('div', null,
          React.createElement('div', { style: { fontSize:10, fontFamily:'var(--font-mono)', letterSpacing:'0.2em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, marginBottom:6 }}, 'Estimator · Not a Quote'),
          React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:24, fontWeight:600, color:'var(--forest-deep)' }}, 'Estimate your turn-key total'),
        ),
        React.createElement('button', { onClick:onClose, style: { background:'none', border:'none', fontSize:22, cursor:'pointer', color:'var(--stone)', padding:4, lineHeight:1 }}, '×')
      ),
      React.createElement('div', { style: { padding:'22px 28px 26px' }},
        React.createElement('p', { style: { fontSize:13.5, color:'var(--forest-mid)', lineHeight:1.65, marginBottom:20 }},
          "The $129,000 base price covers your module + free site delivery. Site prep — foundation, hookups, set crew, HVAC install, permits — is arranged separately by your GC or the PERCH site-partner network. Slide to see a range for your terrain."
        ),
        React.createElement('div', { style: { padding:'18px 20px', background:'var(--cream-soft)', border:'1px solid var(--border)', borderRadius:6 }},
          React.createElement('div', { style: { display:'flex', justifyContent:'space-between', alignItems:'baseline', marginBottom:12 }},
            React.createElement('div', { style: { fontSize:10, fontFamily:'var(--font-mono)', letterSpacing:'0.18em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700 }}, 'Turn-Key Total (est.)'),
            React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:32, fontWeight:600, color:'var(--forest-deep)', letterSpacing:'-0.015em' }}, '$' + total.toLocaleString()),
          ),
          React.createElement('div', { style: { display:'flex', justifyContent:'space-between', fontSize:12, color:'var(--forest-mid)', fontFamily:'var(--font-mono)', marginBottom:8 }},
            React.createElement('span', null, '$' + p.price.toLocaleString() + ' home'),
            React.createElement('span', null, '+ $' + prep.toLocaleString() + ' site prep'),
          ),
          React.createElement('input', {
            type:'range', min:lo, max:hi, step:500, value:prep,
            onChange: e => setPrep(+e.target.value),
            style: { width:'100%', accentColor:'var(--forest-deep)', margin:'6px 0 4px', cursor:'pointer' },
            'aria-label': 'Estimated site prep cost'
          }),
          React.createElement('div', { style: { display:'flex', justifyContent:'space-between', fontSize:9, color:'var(--stone)', fontFamily:'var(--font-mono)', letterSpacing:'0.14em', textTransform:'uppercase', fontWeight:700 }},
            React.createElement('span', null, '$' + (lo/1000) + 'k · simple site'),
            React.createElement('span', null, 'complex · $' + (hi/1000) + 'k'),
          ),
        ),
        React.createElement('p', { style: { fontSize:11, color:'var(--stone)', marginTop:14, lineHeight:1.6, fontStyle:'italic' }},
          "Illustrative only. Concierge quotes real site scope from your address, soil test, and GC bids. Nothing above the $129,000 base is charged by PERCH."
        ),
        React.createElement('button', { onClick: onClose, style: { display:'block', margin:'18px auto 0', padding:'12px 28px', background:'var(--forest-deep)', color:'var(--gold)', border:'none', fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.2em', textTransform:'uppercase', cursor:'pointer', fontWeight:700, borderRadius:6 }}, 'Got it')
      )
    )
  );
}

// ─── PERCH VERIFIED SVG BADGE ───
// Replaces text chip with a real mark. Shield + check, gold-on-forest.
function VerifiedBadge({ size = 20, label = 'PERCH Verified', showLabel = true, href = '/certified' }) {
  const inner = React.createElement(React.Fragment, null,
    React.createElement('svg', { width:size, height:size, viewBox:'0 0 24 24', 'aria-hidden':true, style:{ flexShrink:0 }},
      React.createElement('defs', null,
        React.createElement('linearGradient', { id:'verified-shield-grad', x1:'0', y1:'0', x2:'0', y2:'1' },
          React.createElement('stop', { offset:'0%', stopColor:'#14301D' }),
          React.createElement('stop', { offset:'100%', stopColor:'#1C3D26' })
        )
      ),
      React.createElement('path', {
        d: 'M12 1.5 L20.5 4.2 C21 4.4 21.3 4.9 21.3 5.4 L21.3 12 C21.3 17.2 17.5 21.5 12 22.5 C6.5 21.5 2.7 17.2 2.7 12 L2.7 5.4 C2.7 4.9 3 4.4 3.5 4.2 Z',
        fill: 'url(#verified-shield-grad)', stroke: '#E8C877', strokeWidth: 0.8, strokeLinejoin: 'round'
      }),
      React.createElement('path', {
        d: 'M7.5 12.2 L10.4 15.1 L16.5 8.5',
        fill: 'none', stroke: '#E8C877', strokeWidth: 2.2, strokeLinecap: 'round', strokeLinejoin: 'round'
      })
    ),
    (showLabel && label) ? React.createElement('span', { style: { fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.2em', textTransform:'uppercase', color:'var(--forest-deep)', fontWeight:700 }}, label) : null
  );
  if (href) {
    return React.createElement('a', { href, title:'Read the PERCH Standard', style: { display:'inline-flex', alignItems:'center', gap:8, textDecoration:'none', cursor:'pointer' }}, inner);
  }
  return React.createElement('span', { style: { display:'inline-flex', alignItems:'center', gap:8 }}, inner);
}

// ─── HOMECARE PLUS ─── (bundled warranty proof block)
// High-ticket buyers underweight 1-year manufacturer warranties. HomeCare Plus
// puts real coverage tiers (10 / 7 / 7) forward as a differentiator, at zero add-on.
function HomeCareSection() {
  const w = PRODUCT.warrantyPackage;
  if (!w) return null;
  return React.createElement('div', { style: { marginTop:32, background:'var(--forest-deep)', color:'var(--cream)', borderRadius:8, overflow:'hidden', padding:'32px 36px' }},
    React.createElement('div', { style: { display:'flex', alignItems:'center', gap:18, marginBottom:24, paddingBottom:20, borderBottom:'1px solid rgba(232,200,119,0.22)' }},
      // Shield ICON LEFT of the title (large, gold-on-forest)
      React.createElement('div', { style: { flexShrink:0, width:56, height:56, display:'flex', alignItems:'center', justifyContent:'center', background:'rgba(232,200,119,0.10)', border:'1px solid rgba(232,200,119,0.30)', borderRadius:'50%' }},
        React.createElement(VerifiedBadge, { size: 32, label: '', showLabel: false })
      ),
      React.createElement('div', { style: { flex:1 }},
        React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:30, fontWeight:600, letterSpacing:'-0.01em', color:'var(--cream)', lineHeight:1.1 }}, w.name),
        React.createElement('div', { style: { fontSize:14, color:'rgba(245,235,216,0.72)', marginTop:4, fontStyle:'italic' }}, w.subtitle),
      ),
    ),
    React.createElement('p', { style: { fontSize:14, color:'rgba(245,235,216,0.82)', lineHeight:1.7, marginBottom:22, maxWidth:640 }}, w.intro),
    React.createElement('div', { style: { display:'grid', gridTemplateColumns:'repeat(auto-fit, minmax(220px, 1fr))', gap:16 }},
      w.tiers.map((t, i) =>
        React.createElement('div', { key: t.label, style: { padding:20, background:'rgba(245,235,216,0.06)', border:'1px solid rgba(232,200,119,0.18)', borderRadius:6 }},
          React.createElement('div', { style: { display:'flex', alignItems:'baseline', gap:8, marginBottom:10 }},
            React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:44, fontWeight:600, color:'var(--gold)', lineHeight:1, letterSpacing:'-0.02em' }}, t.years),
            React.createElement('div', { style: { fontSize:11, fontFamily:'var(--font-mono)', color:'rgba(245,235,216,0.7)', letterSpacing:'0.16em', textTransform:'uppercase', fontWeight:600 }}, 'yr'),
          ),
          React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:16, fontWeight:600, color:'var(--cream)', marginBottom:6 }}, t.label),
          React.createElement('p', { style: { fontSize:13, color:'rgba(245,235,216,0.72)', lineHeight:1.6 }}, t.desc),
        )
      )
    ),
    React.createElement('p', { style: { fontSize:11.5, color:'rgba(245,235,216,0.6)', marginTop:20, fontStyle:'italic', lineHeight:1.6 }}, w.footnote),
  );
}

// ─── SHARE ROW ─── (P1 + P2: copy link / email / save / partner invite)
function ShareRow({ onSave }) {
  const [copied, setCopied] = useState(false);
  const copyLink = () => {
    if (typeof navigator !== 'undefined' && navigator.clipboard) {
      navigator.clipboard.writeText(typeof window !== 'undefined' ? window.location.href : 'https://ownperch.com/homes/perch-nest')
        .then(() => { setCopied(true); setTimeout(() => setCopied(false), 1800); })
        .catch(() => {});
    }
  };
  // Save routes to the buyer-signup flow — you can't save homes without an account.
  const save = () => { if (typeof onSave === 'function') onSave(); };
  const actions = [
    { key:'copy', label: copied ? 'Copied' : 'Copy link',  icon:'link',            onClick: copyLink, active: copied },
    { key:'save', label: 'Save to board',                   icon:'bookmark_border', onClick: save },
  ];
  return React.createElement('div', { style: { marginTop:14, paddingTop:14, borderTop:'1px solid var(--border)' }},
    React.createElement('div', { style: { display:'grid', gridTemplateColumns:'repeat(2, 1fr)', gap:6 }},
      actions.map(a =>
        React.createElement('button', {
          key: a.key,
          onClick: a.onClick,
          style: { display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center', gap:5, padding:'10px 4px', background: a.active ? 'var(--forest-deep)' : 'transparent', color: a.active ? 'var(--gold)' : 'var(--forest-deep)', border:'1px solid var(--border-strong)', borderRadius:6, cursor:'pointer', transition:'all 0.15s' },
          onMouseEnter: e=>{ if(!a.active) e.currentTarget.style.background='rgba(28,61,38,0.06)'; },
          onMouseLeave: e=>{ if(!a.active) e.currentTarget.style.background='transparent'; },
        },
          React.createElement(PDPIcon, { name:a.icon, size:16 }),
          React.createElement('span', { style: { fontFamily:'var(--font-mono)', fontSize:9, letterSpacing:'0.14em', textTransform:'uppercase', fontWeight:600 }}, a.label)
        )
      )
    )
  );
}

// ─── PARTNER INVITE MODAL ─── (P2)
function PartnerInviteModal({ open, onClose }) {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [note, setNote] = useState('');
  const [sent, setSent] = useState(false);
  if (!open) return null;
  const submit = e => { e.preventDefault(); console.log('[PERCH] Partner invite', { name, email, note, product:'perch-nest' }); setSent(true); };
  return React.createElement('div', { onClick:onClose, style: { position:'fixed', inset:0, background:'rgba(20,48,29,0.65)', backdropFilter:'blur(8px)', zIndex:1000, display:'flex', alignItems:'center', justifyContent:'center', padding:20 }},
    React.createElement('div', { onClick:e=>e.stopPropagation(), style: { background:'var(--cream)', borderRadius:8, maxWidth:480, width:'100%', boxShadow:'0 20px 60px rgba(0,0,0,0.3)' }},
      React.createElement('div', { style: { padding:'22px 28px', borderBottom:'1px solid var(--border)', display:'flex', justifyContent:'space-between', alignItems:'flex-start' }},
        React.createElement('div', null,
          React.createElement('div', { style: { fontSize:10, fontFamily:'var(--font-mono)', letterSpacing:'0.2em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, marginBottom:6 }}, 'Bring a co-buyer in'),
          React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:22, fontWeight:600, color:'var(--forest-deep)' }}, 'Share this listing with a partner'),
        ),
        React.createElement('button', { onClick:onClose, style: { background:'none', border:'none', fontSize:22, cursor:'pointer', color:'var(--stone)', padding:4 }}, '×')
      ),
      !sent ? React.createElement('form', { onSubmit:submit, style: { padding:'22px 28px' }},
        React.createElement('p', { style: { fontSize:13, color:'var(--forest-mid)', lineHeight:1.6, marginBottom:16 }}, "They'll get a private view of The Nest with your notes, saved options, and a shared decision inbox. No account required to view."),
        React.createElement('input', { required:true, value:name, onChange:e=>setName(e.target.value), placeholder:'Their name', style: { width:'100%', padding:'12px', border:'1px solid var(--border-strong)', borderRadius:6, fontSize:14, marginBottom:10, boxSizing:'border-box' }}),
        React.createElement('input', { required:true, type:'email', value:email, onChange:e=>setEmail(e.target.value), placeholder:'Their email', style: { width:'100%', padding:'12px', border:'1px solid var(--border-strong)', borderRadius:6, fontSize:14, marginBottom:10, boxSizing:'border-box' }}),
        React.createElement('textarea', { value:note, onChange:e=>setNote(e.target.value), placeholder:'Optional note — what do you want them to look at first?', rows:4, style: { width:'100%', padding:'12px', border:'1px solid var(--border-strong)', borderRadius:6, fontSize:14, marginBottom:16, boxSizing:'border-box', fontFamily:'var(--font-body)', resize:'vertical' }}),
        React.createElement('button', { type:'submit', style: { width:'100%', padding:'14px', background:'var(--forest-deep)', color:'var(--gold)', border:'none', fontFamily:'var(--font-mono)', fontSize:12, letterSpacing:'0.18em', textTransform:'uppercase', cursor:'pointer', fontWeight:700, borderRadius:6 }}, 'Send Private Invite →'),
      ) : React.createElement('div', { style: { padding:'40px 28px', textAlign:'center' }},
        React.createElement('div', { style: { fontSize:44, marginBottom:10, color:'var(--forest-deep)' }}, '✓'),
        React.createElement('p', { style: { fontSize:14, color:'var(--forest-mid)', lineHeight:1.7 }}, "Sent to " + email + ". They'll get the private view within a minute."),
        React.createElement('button', { onClick:onClose, style: { marginTop:16, padding:'12px 28px', background:'var(--forest-deep)', color:'var(--gold)', border:'none', fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.18em', textTransform:'uppercase', cursor:'pointer', fontWeight:700, borderRadius:6 }}, 'Close'),
      )
    )
  );
}

// ─── ESCROW EXPLAINER MODAL ─── (3-stage milestone release)
function EscrowExplainerModal({ open, onClose }) {
  if (!open) return null;
  // Generic 20 / 40 / 40 escrow split — applies to every home in the marketplace, not just The Nest.
  // Factory is 100% paid BEFORE the module ships (final 40% funds the ship-out, not the site delivery).
  const stages = [
    { pct: '20%', label: 'Kickoff Deposit',      desc: 'At signing. Deposit funds into licensed escrow. Engineering signoff, option lock, and the factory build ticket opens. No funds have released to the manufacturer yet.' },
    { pct: '40%', label: 'Mid-Build Verified',   desc: 'The manufacturer uploads dated video + photo proof of the frame and dry-in stage to your PERCH inbox. You review and digitally sign off. Escrow releases this tranche.' },
    { pct: '40%', label: 'Factory Complete',     desc: 'Systems installed, module finished, third-party inspection passed. Final proof uploaded, you sign off. Escrow pays the manufacturer in full — the module ships fully paid.' },
  ];
  return React.createElement('div', {
    onClick: onClose,
    style: { position:'fixed', inset:0, background:'rgba(20,48,29,0.65)', backdropFilter:'blur(8px)', zIndex:1000, display:'flex', alignItems:'center', justifyContent:'center', padding:20 }
  },
    React.createElement('div', {
      onClick: e => e.stopPropagation(),
      style: { background:'var(--cream)', borderRadius:8, maxWidth:640, width:'100%', maxHeight:'90vh', overflow:'auto', boxShadow:'0 24px 70px rgba(0,0,0,0.35)' }
    },
      React.createElement('div', { style: { padding:'22px 32px', borderBottom:'1px solid var(--border)', display:'flex', justifyContent:'space-between', alignItems:'flex-start' }},
        React.createElement('div', null,
          React.createElement('div', { style: { display:'inline-flex', alignItems:'center', gap:8, fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.2em', textTransform:'uppercase', color:'var(--forest-deep)', fontWeight:700, marginBottom:8 }},
            React.createElement(PDPIcon, { name:'lock', size:14, style:{ color:'var(--ember)' }}),
            'Licensed Escrow · Digital-First Milestone Verification'
          ),
          React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:26, fontWeight:600, color:'var(--forest-deep)', letterSpacing:'-0.01em' }}, 'How your money moves'),
        ),
        React.createElement('button', { onClick:onClose, style: { background:'none', border:'none', fontSize:24, cursor:'pointer', color:'var(--stone)', padding:4, lineHeight:1 }}, '×')
      ),
      React.createElement('div', { style: { padding:'22px 32px 28px' }},
        React.createElement('p', { style: { fontSize:14, color:'var(--forest-mid)', lineHeight:1.7, marginBottom:22 }},
          "Your funds sit in escrow. The manufacturer uploads dated proof at each stage. You sign off — then escrow releases. The factory is paid in full before your home ships."
        ),
        React.createElement('ol', { style: { listStyle:'none', display:'flex', flexDirection:'column', gap:14 }},
          stages.map((s, i) =>
            React.createElement('li', { key:s.label, style: { display:'grid', gridTemplateColumns:'auto 1fr', gap:16, padding:16, background:'var(--cream-soft)', border:'1px solid var(--border)', borderRadius:6 }},
              React.createElement('div', { style: { display:'flex', flexDirection:'column', alignItems:'center', gap:4, minWidth:64 }},
                React.createElement('div', { style: { width:56, height:56, borderRadius:'50%', background:'var(--forest-deep)', color:'var(--gold)', display:'flex', alignItems:'center', justifyContent:'center', fontFamily:'var(--font-mono)', fontSize:14, fontWeight:700, letterSpacing:'0.02em' }}, s.pct),
              ),
              React.createElement('div', null,
                React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:18, fontWeight:600, color:'var(--forest-deep)', marginBottom:4 }}, s.label),
                React.createElement('div', { style: { fontSize:13, color:'var(--forest-mid)', lineHeight:1.6 }}, s.desc),
              )
            )
          )
        ),
        React.createElement('div', { style: { marginTop:20, padding:14, background:'var(--parchment)', borderLeft:'3px solid var(--gold)', borderRadius:6, fontSize:12.5, color:'var(--forest-deep)', lineHeight:1.65 }},
          React.createElement('strong', null, 'What this means for you:'), " every dollar past your 20% deposit stays in escrow until you personally approve the proof of work. If our manufacturing partner misses a milestone or the proof doesn't match spec, the tranche doesn't move. You can also request an in-person third-party inspection at any stage — Concierge will coordinate."
        ),
        React.createElement('button', {
          onClick: onClose,
          style: { display:'block', margin:'22px auto 0', padding:'13px 28px', background:'var(--forest-deep)', color:'var(--gold)', border:'none', fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.2em', textTransform:'uppercase', cursor:'pointer', fontWeight:700, borderRadius:6 }
        }, 'Got it')
      )
    )
  );
}

// ─── FINANCING CALCULATOR ─── (left-column card, moved out of the sticky sidebar)
// The interactive down%/term/APR sliders live here so the sidebar stays action-focused.
function FinancingCalculator({ onGetFinancing }) {
  const p = PRODUCT;
  const [years, setYears] = useState(20);
  const [rate, setRate] = useState(7.0);
  const [downPct, setDownPct] = useState(20);
  const downAmount = Math.round(p.price * (downPct/100));
  const loanAmount = p.price - downAmount;
  const monthly = estimateMonthlyPDP(loanAmount, years, rate/100);

  return React.createElement('div', { style: { marginTop:32, background:'var(--cream-soft)', border:'1px solid var(--border)', borderRadius:8, padding:'26px 28px' }},
    React.createElement('div', { style: { display:'flex', justifyContent:'space-between', alignItems:'baseline', marginBottom:20 }},
      React.createElement('div', null,
        React.createElement('div', { style: { fontSize:10, fontFamily:'var(--font-mono)', letterSpacing:'0.2em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, marginBottom:4 }}, 'Financing · Estimate'),
        React.createElement('h2', { style: { fontFamily:'var(--font-display)', fontSize:26, fontWeight:600, color:'var(--forest-deep)', letterSpacing:'-0.01em' }}, 'Run your monthly'),
      ),
      React.createElement('div', { style: { textAlign:'right' }},
        React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:36, color:'var(--forest-deep)', fontWeight:600, letterSpacing:'-0.015em', lineHeight:1 }}, '$' + monthly.toLocaleString()),
        React.createElement('div', { style: { fontSize:11, color:'var(--stone)', fontFamily:'var(--font-mono)', letterSpacing:'0.14em', marginTop:4 }}, 'PER MONTH'),
      )
    ),
    React.createElement('div', { style: { display:'grid', gridTemplateColumns:'1fr 1fr 1fr', gap:14, marginBottom:16 }},
      React.createElement('label', { style: { display:'flex', flexDirection:'column', gap:6 }},
        React.createElement('span', { style: { fontSize:10, color:'var(--forest-mid)', fontFamily:'var(--font-mono)', letterSpacing:'0.14em', textTransform:'uppercase', fontWeight:600 }}, 'Down %'),
        React.createElement('select', { value:downPct, onChange:e=>setDownPct(+e.target.value), style: { padding:'11px 12px', border:'1px solid var(--border-strong)', borderRadius:6, fontFamily:'var(--font-mono)', fontSize:14, background:'white' }},
          [5,10,15,20,25,30].map(v => React.createElement('option', { key:v, value:v }, v + '%'))
        )
      ),
      React.createElement('label', { style: { display:'flex', flexDirection:'column', gap:6 }},
        React.createElement('span', { style: { fontSize:10, color:'var(--forest-mid)', fontFamily:'var(--font-mono)', letterSpacing:'0.14em', textTransform:'uppercase', fontWeight:600 }}, 'Term'),
        React.createElement('select', { value:years, onChange:e=>setYears(+e.target.value), style: { padding:'11px 12px', border:'1px solid var(--border-strong)', borderRadius:6, fontFamily:'var(--font-mono)', fontSize:14, background:'white' }},
          [10,15,20,30].map(y => React.createElement('option', { key:y, value:y }, y + ' yr'))
        )
      ),
      React.createElement('label', { style: { display:'flex', flexDirection:'column', gap:6 }},
        React.createElement('span', { style: { fontSize:10, color:'var(--forest-mid)', fontFamily:'var(--font-mono)', letterSpacing:'0.14em', textTransform:'uppercase', fontWeight:600 }}, 'APR %'),
        React.createElement('input', { type:'number', step:0.1, min:1, max:20, value:rate, onChange:e=>setRate(+e.target.value), style: { padding:'11px 12px', border:'1px solid var(--border-strong)', borderRadius:6, fontFamily:'var(--font-mono)', fontSize:14, background:'white', boxSizing:'border-box' }})
      ),
    ),
    React.createElement('div', { style: { display:'flex', justifyContent:'space-between', paddingTop:14, borderTop:'1px solid var(--border)', fontSize:12, color:'var(--forest-mid)', fontFamily:'var(--font-mono)' }},
      React.createElement('span', null, 'Down · $' + downAmount.toLocaleString()),
      React.createElement('span', null, 'Financed · $' + loanAmount.toLocaleString()),
      React.createElement('span', { style: { color:'var(--stone)', fontStyle:'italic' }}, 'Illustrative · not a rate quote'),
    ),
    onGetFinancing ? React.createElement('button', {
      onClick: onGetFinancing,
      style: { width:'100%', marginTop:18, padding:'14px', background:'var(--sage)', color:'white', border:'none', fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.22em', textTransform:'uppercase', cursor:'pointer', fontWeight:700, borderRadius:6, transition:'all 0.2s', boxShadow:'0 6px 18px -8px rgba(122,158,118,0.55)' },
      onMouseEnter: e=>{ e.currentTarget.style.filter='brightness(1.08)'; e.currentTarget.style.transform='translateY(-1px)'; },
      onMouseLeave: e=>{ e.currentTarget.style.filter='none'; e.currentTarget.style.transform='none'; }
    }, 'Get a real financing quote →') : null,
  );
}

// ─── SIGNUP MODAL ─── (buyer account creation, opened from Save-to-Board)
// Google Auth primary + magic-link email fallback. Uses shared .pdp-modal system.
function SignupModal({ open, onClose, homeName }) {
  const [email, setEmail] = useState('');
  const [name, setName] = useState('');
  const [sent, setSent] = useState(false);
  if (!open) return null;
  const submit = e => { e.preventDefault(); console.log('[PERCH] Signup magic-link', { email, name, savedHome: homeName || 'perch-nest' }); setSent(true); };
  const google = () => { console.log('[PERCH] Signup via Google', { savedHome: homeName || 'perch-nest' }); /* Firebase Auth GoogleAuthProvider wire here */ setSent(true); };
  const close = () => { setSent(false); setEmail(''); setName(''); onClose(); };

  const GoogleIcon = React.createElement('svg', { width: 18, height: 18, viewBox: '0 0 48 48', 'aria-hidden': true },
    React.createElement('path', { fill: '#FFC107', d: 'M43.611 20.083H42V20H24v8h11.303c-1.649 4.657-6.08 8-11.303 8-6.627 0-12-5.373-12-12s5.373-12 12-12c3.059 0 5.842 1.154 7.961 3.039l5.657-5.657C34.046 6.053 29.268 4 24 4 12.955 4 4 12.955 4 24s8.955 20 20 20 20-8.955 20-20c0-1.341-.138-2.65-.389-3.917z' }),
    React.createElement('path', { fill: '#FF3D00', d: 'M6.306 14.691l6.571 4.819C14.655 15.108 18.961 12 24 12c3.059 0 5.842 1.154 7.961 3.039l5.657-5.657C34.046 6.053 29.268 4 24 4 16.318 4 9.656 8.337 6.306 14.691z' }),
    React.createElement('path', { fill: '#4CAF50', d: 'M24 44c5.166 0 9.86-1.977 13.409-5.192l-6.19-5.238A11.91 11.91 0 0 1 24 36c-5.202 0-9.619-3.317-11.283-7.946l-6.522 5.025C9.505 39.556 16.227 44 24 44z' }),
    React.createElement('path', { fill: '#1976D2', d: 'M43.611 20.083H42V20H24v8h11.303a12.04 12.04 0 0 1-4.087 5.571l.003-.002 6.19 5.238C36.971 39.205 44 34 44 24c0-1.341-.138-2.65-.389-3.917z' })
  );

  return React.createElement('div', { className: 'pdp-modal-scrim', onClick: close },
    React.createElement('div', { className: 'pdp-modal', onClick: e=>e.stopPropagation(), style: { maxWidth: 460 }},
      React.createElement('div', { className: 'pdp-modal-header' },
        React.createElement('div', null,
          React.createElement('div', { className: 'pdp-modal-eyebrow' }, 'Save to Board'),
          React.createElement('div', { className: 'pdp-modal-title' }, sent ? 'Check your email' : 'Create your account'),
        ),
        React.createElement('button', { className: 'pdp-modal-close', onClick: close, 'aria-label': 'Close' }, '×')
      ),

      !sent ? React.createElement('div', { className: 'pdp-modal-body' },
        React.createElement('p', { className: 'pdp-modal-lede' },
          "Save homes, get inquiry updates, and pick up right where you left off."
        ),
        React.createElement('button', { className: 'pdp-btn pdp-btn-google', onClick: google, type: 'button' },
          GoogleIcon,
          'Continue with Google'
        ),
        React.createElement('div', { className: 'pdp-or' }, 'or'),
        React.createElement('form', { onSubmit: submit, style: { display:'flex', flexDirection:'column', gap:10 }},
          React.createElement('input', { className: 'pdp-input', required: true, value: name, onChange: e=>setName(e.target.value), placeholder: 'Your name', autoComplete: 'name' }),
          React.createElement('input', { className: 'pdp-input', required: true, type: 'email', value: email, onChange: e=>setEmail(e.target.value), placeholder: 'you@email.com', autoComplete: 'email' }),
          React.createElement('button', { className: 'pdp-btn pdp-btn-primary', type: 'submit', style: { marginTop: 4 }}, 'Send magic link →')
        ),
        React.createElement('p', { className: 'pdp-microcopy' }, 'No password. Existing account? Same email logs you in.'),
      ) : React.createElement('div', { className: 'pdp-success' },
        React.createElement('div', { className: 'pdp-success-mark' }, '✓'),
        React.createElement('div', { className: 'pdp-success-title' }, "You're in."),
        React.createElement('p', { className: 'pdp-success-body' },
          email ? "Magic link sent to " + email + ". Click it to log in — your board will have The Nest saved when you land."
                : "You're signed in. The Nest is saved to your board."
        ),
        React.createElement('button', { className: 'pdp-btn pdp-btn-primary', onClick: close, style: { maxWidth: 200, margin: '0 auto' }}, 'Close')
      )
    )
  );
}

// ─── CONTRACTOR SHARE MODAL ─── (send buyer's contractor a package of everything they need)
function ContractorShareModal({ open, onClose }) {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [company, setCompany] = useState('');
  const [state, setState] = useState('');
  const [sent, setSent] = useState(false);
  if (!open) return null;
  const submit = e => { e.preventDefault(); console.log('[PERCH] Contractor share', { name, email, company, state, product: 'perch-nest' }); setSent(true); };
  return React.createElement('div', { onClick:onClose, style: { position:'fixed', inset:0, background:'rgba(20,48,29,0.65)', backdropFilter:'blur(8px)', zIndex:1000, display:'flex', alignItems:'center', justifyContent:'center', padding:20 }},
    React.createElement('div', { onClick:e=>e.stopPropagation(), style: { background:'var(--cream)', borderRadius:8, maxWidth:520, width:'100%', maxHeight:'90vh', overflow:'auto', boxShadow:'0 24px 70px rgba(0,0,0,0.35)' }},
      React.createElement('div', { style: { padding:'22px 28px', borderBottom:'1px solid var(--border)', display:'flex', justifyContent:'space-between', alignItems:'flex-start' }},
        React.createElement('div', null,
          React.createElement('div', { style: { fontSize:10, fontFamily:'var(--font-mono)', letterSpacing:'0.2em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, marginBottom:6 }}, 'Site Scope · Pass to Your GC'),
          React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:24, fontWeight:600, color:'var(--forest-deep)' }}, 'Share with your contractor'),
        ),
        React.createElement('button', { onClick:onClose, style: { background:'none', border:'none', fontSize:22, cursor:'pointer', color:'var(--stone)', padding:4, lineHeight:1 }}, '×')
      ),
      !sent ? React.createElement('form', { onSubmit:submit, style: { padding:'22px 28px' }},
        React.createElement('p', { style: { fontSize:14, color:'var(--forest-mid)', lineHeight:1.6, marginBottom:16 }},
          "We'll email your GC the contractor package: engineering specs, foundation drawings, code refs, and the site-scope checklist."
        ),
        React.createElement('div', { style: { display:'grid', gridTemplateColumns:'1fr 1fr', gap:10, marginBottom:10 }},
          React.createElement('input', { required:true, value:name, onChange:e=>setName(e.target.value), placeholder:'Contractor name', style: { padding:'12px', border:'1px solid var(--border-strong)', borderRadius:6, fontSize:14, boxSizing:'border-box' }}),
          React.createElement('input', { required:true, type:'email', value:email, onChange:e=>setEmail(e.target.value), placeholder:'Contractor email', style: { padding:'12px', border:'1px solid var(--border-strong)', borderRadius:6, fontSize:14, boxSizing:'border-box' }}),
          React.createElement('input', { value:company, onChange:e=>setCompany(e.target.value), placeholder:'Company (optional)', style: { padding:'12px', border:'1px solid var(--border-strong)', borderRadius:6, fontSize:14, boxSizing:'border-box' }}),
          React.createElement('select', { required:true, value:state, onChange:e=>setState(e.target.value), style: { padding:'12px', border:'1px solid var(--border-strong)', borderRadius:6, fontSize:14, background:'white', boxSizing:'border-box' }},
            React.createElement('option', { value:'' }, 'Build state'),
            ['NC (as-built)','SC','GA','TN','VA','FL','TX','AL','KY','WV','MD','DE','PA','OH','Other'].map(s => React.createElement('option', { key:s, value:s }, s))
          ),
        ),
        React.createElement('div', { style: { padding:'10px 12px', background:'var(--parchment)', border:'1px solid var(--border)', borderLeft:'3px solid var(--gold)', borderRadius:6, fontSize:12, color:'var(--forest-deep)', lineHeight:1.55, marginBottom:16 }},
          React.createElement('strong', null, 'Engineered to IRC 2021 + NC Residential Code 2018.'), ' Non-NC builds may need re-engineering — our manufacturing partner handles it, Concierge coordinates.'
        ),
        React.createElement('button', { type:'submit', style: { width:'100%', padding:'14px', background:'var(--forest-deep)', color:'var(--gold)', border:'none', fontFamily:'var(--font-mono)', fontSize:12, letterSpacing:'0.2em', textTransform:'uppercase', cursor:'pointer', fontWeight:700, borderRadius:6 }}, 'Send Contractor Package →')
      ) : React.createElement('div', { style: { padding:'40px 28px', textAlign:'center' }},
        React.createElement('div', { style: { fontSize:44, marginBottom:10, color:'var(--forest-deep)' }}, '✓'),
        React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:22, fontWeight:600, color:'var(--forest-deep)', marginBottom:8 }}, 'Package sent'),
        React.createElement('p', { style: { fontSize:13, color:'var(--forest-mid)', lineHeight:1.7 }}, name + " will receive the contractor package at " + email + " within a minute. Full dashboard access unlocks after slot confirms."),
        React.createElement('button', { onClick:onClose, style: { marginTop:16, padding:'12px 28px', background:'var(--forest-deep)', color:'var(--gold)', border:'none', fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.18em', textTransform:'uppercase', cursor:'pointer', fontWeight:700, borderRadius:6 }}, 'Close'),
      )
    )
  );
}

// ─── TRUST CHIP ROW ───
// Nutriiva-inspired trust column, adapted to horizontal chip row (better mobile behavior).
// Placed directly under hero gallery so the first thing after image is who stands behind the unit.
function TrustChipRow() {
  const p = window.PRODUCT;
  const cs = p.certificationStack;
  const chips = [
    { label: 'PERCH-Certified Builder',      status: cs.builder.status,  detail: cs.builder.detail },
    { label: 'Third-Party Inspected Unit',   status: cs.unit.status,     detail: cs.unit.detail },
    { label: 'Site-Verified at Reserve',     status: cs.delivery.status, detail: cs.delivery.detail },
    { label: 'Component-Approved for Delivery', status: 'per-state',     detail: 'Doors, windows, roof, siding, tie-downs pre-checked against your destination-state approval regime before dispatch. FL + TX require re-verification.' },
  ];
  const [openIdx, setOpenIdx] = useState(null);
  return React.createElement('div', { style: { padding:'20px 0 24px', borderBottom:'1px solid var(--border)' }},
    React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.16em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, marginBottom:12 }}, 'Trust stack · third-party verified'),
    React.createElement('div', { style: { display:'flex', flexWrap:'wrap', gap:8 }},
      chips.map((c, i) =>
        React.createElement('button', {
          key: c.label,
          onClick: () => setOpenIdx(openIdx === i ? null : i),
          style: {
            display:'inline-flex', alignItems:'center', gap:8,
            padding:'8px 14px', borderRadius:999,
            border:'1px solid ' + (c.status === 'held' ? 'var(--sage)' : c.status === 'per-buyer' ? 'var(--forest)' : 'var(--border-strong)'),
            background: c.status === 'held' ? 'rgba(58,109,88,0.06)' : c.status === 'per-buyer' ? 'rgba(28,61,38,0.04)' : 'white',
            fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.06em', textTransform:'uppercase', fontWeight:600,
            color: c.status === 'held' ? 'var(--sage)' : 'var(--forest-deep)',
            cursor:'pointer'
          }
        },
          React.createElement('span', { style: { fontSize:12, lineHeight:1 }}, c.status === 'held' ? '✓' : c.status === 'per-buyer' ? '◐' : '⌂'),
          c.label
        )
      )
    ),
    openIdx !== null && React.createElement('div', { style: { marginTop:12, padding:'12px 14px', background:'var(--parchment)', borderRadius:6, fontSize:13, color:'var(--slate)', lineHeight:1.6 }}, chips[openIdx].detail)
  );
}

// ─── ADDRESS AUTOCOMPLETE ─── (debounced suggestion dropdown)
// Prod: swap the stub inside effect() for Mapbox Geocoding autocomplete:
//   fetch('https://api.mapbox.com/geocoding/v5/mapbox.places/' + encodeURIComponent(q) + '.json?autocomplete=true&country=us&types=address&limit=5&access_token=' + TOKEN)
// Returned features map to { label, lat, lng, state } — the rest of the flow is unchanged.
function AddressAutocomplete({ value, onChange, onSelect, placeholder }) {
  const [suggestions, setSuggestions] = useState([]);
  const [show, setShow] = useState(false);
  const [active, setActive] = useState(-1);
  const debounceRef = useRef(null);
  const boxRef = useRef(null);

  useEffect(() => {
    if (!value || value.trim().length < 4) { setSuggestions([]); return; }
    clearTimeout(debounceRef.current);
    debounceRef.current = setTimeout(() => {
      // STUB — Mapbox swap-point. Returns 4 plausible completions across the Southeast + FL for the demo.
      const q = value.trim();
      const cities = [
        { city:'Charlotte, NC',  zip:'28202', state:'NC', lat:35.2271, lng:-80.8431 },
        { city:'Atlanta, GA',    zip:'30303', state:'GA', lat:33.7490, lng:-84.3880 },
        { city:'Nashville, TN',  zip:'37201', state:'TN', lat:36.1627, lng:-86.7816 },
        { city:'Raleigh, NC',    zip:'27601', state:'NC', lat:35.7796, lng:-78.6382 },
        { city:'Miami, FL',      zip:'33101', state:'FL', lat:25.7617, lng:-80.1918 },
        { city:'Austin, TX',     zip:'78701', state:'TX', lat:30.2672, lng:-97.7431 },
      ];
      const stripped = q.replace(/,\s*(Charlotte|Atlanta|Nashville|Raleigh|Miami|Austin).*$/i,'').trim();
      setSuggestions(cities.slice(0,4).map(c => ({
        label: (stripped || '123 Main St') + ', ' + c.city + ' ' + c.zip,
        lat: c.lat + (Math.random()-0.5)*0.04,
        lng: c.lng + (Math.random()-0.5)*0.04,
        state: c.state,
      })));
      setShow(true);
      setActive(-1);
    }, 300);
    return () => clearTimeout(debounceRef.current);
  }, [value]);

  // Close on outside click
  useEffect(() => {
    const h = (e) => { if (boxRef.current && !boxRef.current.contains(e.target)) setShow(false); };
    document.addEventListener('mousedown', h);
    return () => document.removeEventListener('mousedown', h);
  }, []);

  const pick = (s) => { onSelect(s); setShow(false); setSuggestions([]); };

  const onKey = (e) => {
    if (!show || !suggestions.length) return;
    if (e.key === 'ArrowDown') { e.preventDefault(); setActive((active + 1) % suggestions.length); }
    else if (e.key === 'ArrowUp') { e.preventDefault(); setActive((active - 1 + suggestions.length) % suggestions.length); }
    else if (e.key === 'Enter' && active >= 0) { e.preventDefault(); pick(suggestions[active]); }
    else if (e.key === 'Escape') setShow(false);
  };

  return React.createElement('div', { ref: boxRef, style: { position:'relative', flex:'1 1 320px' }},
    React.createElement('input', {
      type:'text', value, onChange:e=>onChange(e.target.value),
      onFocus: ()=>suggestions.length && setShow(true),
      onKeyDown: onKey,
      placeholder,
      autoComplete: 'off',
      style: { width:'100%', padding:'14px 16px', border:'1px solid var(--border-strong)', borderRadius:6, fontFamily:'var(--font-body)', fontSize:15, boxSizing:'border-box' }
    }),
    show && suggestions.length > 0 && React.createElement('div', {
      style: { position:'absolute', top:'calc(100% + 4px)', left:0, right:0, background:'white', border:'1px solid var(--border-strong)', borderRadius:6, boxShadow:'0 8px 24px rgba(20,48,29,0.15)', zIndex:20, overflow:'hidden' }
    },
      suggestions.map((s, i) =>
        React.createElement('button', {
          key: i,
          onMouseDown: (e) => { e.preventDefault(); pick(s); },
          onMouseEnter: () => setActive(i),
          style: {
            width:'100%', display:'flex', alignItems:'center', gap:10,
            padding:'11px 14px', border:'none',
            background: active === i ? 'var(--parchment)' : 'white',
            textAlign:'left', cursor:'pointer',
            borderBottom: i < suggestions.length - 1 ? '1px solid var(--border)' : 'none'
          }
        },
          React.createElement('span', { style: { fontSize:14, color:'var(--stone)' }}, '📍'),
          React.createElement('span', { style: { fontSize:13, color:'var(--forest-deep)', fontFamily:'var(--font-body)' }}, s.label)
        )
      )
    )
  );
}

// ─── SITE VERIFICATION ─── (Land Check embedded on PDP — full address + map confirmation)
// Buyer types → autocomplete dropdown → select → geocode confirmed → map modal for visual parcel confirm → verdict.
// Per THT audience data: this is a closing mechanism, not TOFU acquisition.
function SiteVerification({ onVerified }) {
  const [address, setAddress] = useState('');
  const [mapOpen, setMapOpen] = useState(false);
  const [coords, setCoords] = useState(null); // { lat, lng, formatted, state }
  const [checking, setChecking] = useState(false);
  const [verdict, setVerdict] = useState(null);

  const geocodeStub = () => {
    // Stub — real impl hits Mapbox Geocoding API server-side (Referer: ownperch.com).
    // Kept client-side + heuristic so PERCH-chat can swap in one place without breaking the UI.
    if (address.trim().length < 8) return;
    setChecking(true);
    setTimeout(() => {
      // Rough state inference from trailing 2-letter code so the stub produces plausible verdicts.
      const m = address.match(/\b(AL|AK|AZ|AR|CA|CO|CT|DE|FL|GA|HI|ID|IL|IN|IA|KS|KY|LA|ME|MD|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|OH|OK|OR|PA|RI|SC|SD|TN|TX|UT|VT|VA|WA|WV|WI|WY)\b/i);
      const st = m ? m[1].toUpperCase() : 'NC';
      // Fake coords near Atlanta as a friendly stub center. Real API returns actual coords.
      setCoords({ lat: 33.749 + (Math.random()-0.5)*0.4, lng: -84.388 + (Math.random()-0.5)*0.4, formatted: address, state: st });
      setChecking(false);
      setMapOpen(true);
    }, 500);
  };

  const confirmParcelAndVerify = () => {
    const st = coords.state;
    const footprintStates = ['NC','SC','GA','TN','VA'];
    const highCodeStates = ['FL','TX','LA','MS','AL']; // Hurricane / windstorm re-engineering states
    let v;
    const econ = (window.PRODUCT && window.PRODUCT.listingEconomics) || {};
    const reEngNote = econ.reEngineeringCovered ? econ.coveredNote : econ.passThroughNote;
    if (footprintStates.includes(st)) {
      v = {
        level:'green',
        title:'Verified for ' + coords.formatted,
        body:'Your address sits in one of our free-freight states (NC · SC · GA · TN · VA). We ran your parcel against zoning, setbacks, wastewater availability, and destination-state component approvals — everything clears for The Nest as-designed. No re-engineering needed.',
        checklist: [
          { label: 'Zoning allows a modular one-bedroom', status: 'pass' },
          { label: 'Setbacks fit the 35\'-6" × 15\'-9" footprint', status: 'pass' },
          { label: 'Wastewater available (sewer or septic-eligible)', status: 'pass' },
          { label: 'State component approvals on file', status: 'pass' },
        ],
      };
    } else if (highCodeStates.includes(st)) {
      v = {
        level:'yellow',
        title:'Ships to ' + coords.formatted + ' — plans re-engineered for ' + st,
        body:'The Nest is available in every US state. ' + st + ' has a distinct hurricane/windstorm code, so entry door, windows, and tie-downs are re-engineered against the state approval regime before dispatch. Zoning, setbacks, and wastewater are checked below — a few items need confirmation with your county.',
        reEngNote,
        reEngCovered: !!econ.reEngineeringCovered,
        checklist: [
          { label: 'Zoning allows a modular one-bedroom', status: 'pass' },
          { label: 'Setbacks fit the 35\'-6" × 15\'-9" footprint', status: 'pass' },
          { label: 'Wastewater availability — check with county', status: 'ask' },
          { label: st + ' component re-engineering needed', status: 'ask' },
        ],
        questions:[
          'Is your parcel on public sewer or septic?',
          'What is the county wastewater minimum lot size?',
          'Does your county require additional state product-approval documentation at permit?'
        ]
      };
    } else {
      v = {
        level:'yellow',
        title:'Ships to ' + coords.formatted + ' — extended freight quoted',
        body:'The Nest is available in every US state. Your address sits outside our default freight lanes. We checked zoning, setbacks, and wastewater at the state level — a few items need county-specific confirmation before we can lock the build.',
        reEngNote,
        reEngCovered: !!econ.reEngineeringCovered,
        checklist: [
          { label: 'Zoning allows a modular one-bedroom', status: 'pass' },
          { label: 'Setbacks fit the 35\'-6" × 15\'-9" footprint', status: 'ask' },
          { label: 'Wastewater availability — check with county', status: 'ask' },
          { label: 'Local code re-verification may be required', status: 'ask' },
        ],
      };
    }
    setVerdict(v);
    setMapOpen(false);
    if (onVerified) onVerified(coords, v);
  };

  const color = verdict ? (verdict.level === 'green' ? 'var(--sage)' : '#c98b2a') : 'var(--forest-deep)';

  return React.createElement('section', { id:'site-verification', style: { padding:'32px 0', borderBottom:'1px solid var(--border)' }},
    React.createElement('div', { style: { display:'flex', alignItems:'baseline', gap:12, marginBottom:14, flexWrap:'wrap' }},
      React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.16em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700 }}, 'Site verification · The Land Check'),
      React.createElement('div', { style: { fontSize:11, color:'var(--stone)' }}, 'Zoning · setbacks · wastewater · state component approval'),
    ),
    React.createElement('h2', { style: { fontFamily:'var(--font-display)', fontSize:24, fontWeight:600, color:'var(--forest-deep)', marginBottom:8 }}, 'Will this work on your land?'),
    React.createElement('p', { style: { fontSize:14, color:'var(--slate)', lineHeight:1.6, marginBottom:16, maxWidth:640 }},
      'The Nest ships nationwide. This check runs your specific parcel against zoning, setbacks, wastewater availability, and destination-state component codes. States outside our default footprint may need re-engineering — that’s a quote, not a no. Free, and it takes about a minute.'
    ),
    React.createElement('div', { style: { display:'flex', gap:8, maxWidth:640, flexWrap:'wrap' }},
      React.createElement(AddressAutocomplete, {
        value: address,
        onChange: setAddress,
        onSelect: (s) => {
          // Autocomplete resolved to real coords → skip stub geocode entirely and open the map modal.
          setAddress(s.label);
          setCoords({ lat: s.lat, lng: s.lng, formatted: s.label, state: s.state });
          setMapOpen(true);
        },
        placeholder: 'Start typing your street address…'
      }),
      React.createElement('button', {
        onClick:geocodeStub,
        disabled: address.trim().length < 8 || checking,
        style: { padding:'0 24px', background:'var(--forest-deep)', color:'var(--gold)', border:'none', fontFamily:'var(--font-mono)', fontSize:12, letterSpacing:'0.1em', textTransform:'uppercase', cursor: address.trim().length >= 8 ? 'pointer' : 'not-allowed', fontWeight:600, borderRadius:6, opacity: address.trim().length >= 8 ? 1 : 0.4 }
      }, checking ? 'Locating…' : 'Verify site →')
    ),
    verdict && React.createElement('div', { style: { marginTop:16, padding:'16px 18px', background:'white', border:'1px solid ' + color, borderLeft:'4px solid ' + color, borderRadius:6 }},
      React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:16, fontWeight:600, color: color, marginBottom:6 }}, verdict.title),
      React.createElement('p', { style: { fontSize:13, color:'var(--slate)', lineHeight:1.6, marginBottom: (verdict.checklist || verdict.reEngNote || verdict.questions) ? 10 : 0 }}, verdict.body),
      verdict.checklist && React.createElement('div', { style: { marginTop:10, padding:'10px 12px', background:'var(--parchment)', borderRadius:6 }},
        React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.14em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, marginBottom:8 }}, 'What we checked'),
        React.createElement('ul', { style: { listStyle:'none', margin:0, padding:0, display:'flex', flexDirection:'column', gap:5 }},
          verdict.checklist.map((c, i) =>
            React.createElement('li', { key:i, style: { display:'flex', gap:8, alignItems:'center', fontSize:12.5, color:'var(--slate)' }},
              React.createElement('span', { style: { flexShrink:0, width:16, height:16, borderRadius:'50%', background: c.status === 'pass' ? 'var(--sage)' : '#c98b2a', color:'white', display:'flex', alignItems:'center', justifyContent:'center', fontSize:10, fontWeight:700 }}, c.status === 'pass' ? '✓' : '?'),
              c.label
            )
          )
        )
      ),
      verdict.reEngNote && React.createElement('div', { style: { marginTop:10, padding:'10px 12px', background: verdict.reEngCovered ? 'rgba(58,109,88,0.08)' : 'rgba(196,98,45,0.06)', border:'1px solid ' + (verdict.reEngCovered ? 'var(--sage)' : 'var(--ember)'), borderRadius:6, display:'flex', gap:8, alignItems:'flex-start' }},
        React.createElement('span', { style: { fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.14em', textTransform:'uppercase', fontWeight:700, color: verdict.reEngCovered ? 'var(--sage)' : 'var(--ember)', flexShrink:0, marginTop:1 }}, verdict.reEngCovered ? 'On us' : 'At cost'),
        React.createElement('div', { style: { fontSize:12, color:'var(--slate)', lineHeight:1.55 }}, verdict.reEngNote)
      ),
      verdict.questions && React.createElement('div', { style: { marginTop:10, paddingTop:10, borderTop:'1px solid var(--border)' }},
        React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.12em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, marginBottom:8 }}, 'Questions to answer with your county'),
        React.createElement('ul', { style: { margin:0, paddingLeft:18, fontSize:13, color:'var(--slate)', lineHeight:1.7 }},
          verdict.questions.map((q,i) => React.createElement('li', { key:i }, q))
        )
      )
    ),

    // Map modal — visual parcel confirmation before we return a verdict.
    // Stub uses Mapbox static image API preview. PERCH-chat swaps to interactive Mapbox GL JS with real parcel polygon overlay.
    mapOpen && coords && React.createElement('div', {
      onClick:()=>setMapOpen(false),
      style: { position:'fixed', inset:0, background:'rgba(20,48,29,0.65)', backdropFilter:'blur(6px)', zIndex:1050, display:'flex', alignItems:'center', justifyContent:'center', padding:20 }
    },
      React.createElement('div', {
        onClick:e=>e.stopPropagation(),
        style: { background:'var(--cream)', borderRadius:8, maxWidth:720, width:'100%', maxHeight:'92vh', overflow:'auto', boxShadow:'0 24px 70px rgba(0,0,0,0.35)' }
      },
        React.createElement('div', { style: { padding:'20px 24px', borderBottom:'1px solid var(--border)', display:'flex', justifyContent:'space-between', alignItems:'flex-start' }},
          React.createElement('div', null,
            React.createElement('div', { style: { fontSize:10, fontFamily:'var(--font-mono)', letterSpacing:'0.16em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, marginBottom:6 }}, 'Confirm your parcel'),
            React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:20, fontWeight:600, color:'var(--forest-deep)' }}, 'Is this the right lot?')
          ),
          React.createElement('button', { onClick:()=>setMapOpen(false), style: { background:'none', border:'none', fontSize:22, cursor:'pointer', color:'var(--stone)', padding:4 }}, '×')
        ),
        React.createElement('div', { style: { padding:'20px 24px' }},
          React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:12, color:'var(--forest-deep)', marginBottom:12, letterSpacing:'0.04em' }}, coords.formatted),
          // Static satellite preview — Mapbox static images API. On production, replace src with signed URL using Referer: ownperch.com.
          React.createElement('div', { style: { position:'relative', width:'100%', aspectRatio:'16/10', background:'#0d1f14', borderRadius:6, overflow:'hidden', border:'1px solid var(--border-strong)' }},
            React.createElement('img', {
              src: 'https://api.mapbox.com/styles/v1/mapbox/satellite-v9/static/pin-l+e8c877(' + coords.lng.toFixed(5) + ',' + coords.lat.toFixed(5) + ')/' + coords.lng.toFixed(5) + ',' + coords.lat.toFixed(5) + ',17,0/720x450@2x?access_token=pk.eyJ1Ijoiam92YW5jb25zdWx0aW5nIiwiYSI6ImNtc216bzJmMTFtZngyeW9xMGYxdDg1eG4ifQ.Sx8bkZ63nfQyGleNqcdfFQ',
              alt: 'Satellite view of ' + coords.formatted,
              style: { width:'100%', height:'100%', objectFit:'cover', display:'block' },
              onError: (e)=>{ e.currentTarget.style.display='none'; }
            }),
            React.createElement('div', { style: { position:'absolute', inset:0, display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center', color:'var(--gold)', textAlign:'center', padding:20, pointerEvents:'none' }},
              React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.16em', textTransform:'uppercase', fontWeight:700, opacity:0.85 }}, 'Satellite preview'),
              React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.06em', marginTop:6, opacity:0.7 }}, coords.lat.toFixed(5) + ' · ' + coords.lng.toFixed(5))
            )
          ),
          React.createElement('p', { style: { fontSize:12, color:'var(--stone)', lineHeight:1.6, marginTop:12 }}, 'We check zoning, setbacks, wastewater, and state component approvals against this parcel. If you’ve got the wrong lot pinned, adjust the address and try again.'),
          React.createElement('div', { style: { display:'flex', gap:8, marginTop:16 }},
            React.createElement('button', { onClick:()=>setMapOpen(false), style: { flex:1, padding:'13px', background:'none', color:'var(--slate)', border:'1px solid var(--border-strong)', fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.1em', textTransform:'uppercase', cursor:'pointer', fontWeight:500, borderRadius:6 }}, 'Wrong lot — edit address'),
            React.createElement('button', { onClick:confirmParcelAndVerify, style: { flex:2, padding:'13px', background:'var(--forest-deep)', color:'var(--gold)', border:'none', fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.14em', textTransform:'uppercase', cursor:'pointer', fontWeight:700, borderRadius:6 }}, 'Right lot — run verification →'),
          )
        )
      )
    )
  );
}

// ─── CONFIGURATION SELECTOR ─── (Nutriiva 1/2/3-pack, adapted for home pairs)
// Only "solo" is bookable today. Pair + Compound are stubbed with "Coming" state — unlock as more Certified builders join.
function ConfigurationSelector() {
  const p = window.PRODUCT;
  const [selected, setSelected] = useState('solo');
  return React.createElement('section', { id:'configurations', style: { padding:'32px 0', borderBottom:'1px solid var(--border)' }},
    React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.16em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, marginBottom:8 }}, 'Configurations'),
    React.createElement('h2', { style: { fontFamily:'var(--font-display)', fontSize:24, fontWeight:600, color:'var(--forest-deep)', marginBottom:8 }}, 'Buy it as a home. Or as a pair.'),
    React.createElement('p', { style: { fontSize:14, color:'var(--slate)', lineHeight:1.6, marginBottom:18, maxWidth:640 }}, 'Most PERCH buyers land at the same budget ceiling but want two structures on one parcel — a primary plus a studio or workshop. We only ship pairs where both units are PERCH-Certified and site-verify together.'),
    React.createElement('div', { style: { display:'grid', gridTemplateColumns:'repeat(auto-fit, minmax(220px, 1fr))', gap:12 }},
      p.configurations.map(c => {
        const isSelected = selected === c.key;
        const isDisabled = c.status !== 'available';
        return React.createElement('label', {
          key: c.key,
          onClick: () => !isDisabled && setSelected(c.key),
          style: {
            position:'relative', display:'block', padding:'18px 18px 16px',
            border:'1px solid ' + (isSelected ? 'var(--ember)' : 'var(--border-strong)'),
            borderRadius:6, cursor: isDisabled ? 'not-allowed' : 'pointer',
            background: isSelected ? 'rgba(196,98,45,0.05)' : 'white',
            opacity: isDisabled ? 0.6 : 1,
          }
        },
          c.badge && React.createElement('div', { style: { position:'absolute', top:-9, right:14, padding:'3px 10px', background:'var(--forest-deep)', color:'var(--gold)', fontFamily:'var(--font-mono)', fontSize:9, letterSpacing:'0.16em', textTransform:'uppercase', fontWeight:700, borderRadius:6 }}, c.badge),
          React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.12em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, marginBottom:6 }}, c.status === 'available' ? 'Available' : 'Coming'),
          React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:18, fontWeight:600, color:'var(--forest-deep)', marginBottom:4 }}, c.title),
          React.createElement('div', { style: { fontSize:12, color:'var(--stone)', lineHeight:1.5, marginBottom:10 }}, c.subtitle),
          React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:15, color:'var(--forest-deep)', fontWeight:600 }}, c.priceLabel),
        );
      })
    ),
    React.createElement('p', { style: { marginTop:14, fontSize:12, color:'var(--stone)', fontStyle:'italic' }}, 'Pair + Compound configurations unlock as PERCH-Certified companion units come online. Reserve The Nest solo now and lock the pair pricing when it opens.')
  );
}

// ─── CERTIFICATION STACK ─── (public standard section — the "who inspects, against what standard" doc)
function CertificationStackSection() {
  const p = window.PRODUCT;
  const cs = p.certificationStack;
  const tiers = [
    { key:'builder',  label:'Certified Builder',    obj: cs.builder },
    { key:'unit',     label:'Inspected Unit',       obj: cs.unit },
    { key:'delivery', label:'Site-Verified',        obj: cs.delivery },
  ];
  return React.createElement('section', { id:'certification-stack', style: { padding:'32px 0', borderBottom:'1px solid var(--border)' }},
    React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.16em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, marginBottom:8 }}, 'The PERCH standard'),
    React.createElement('h2', { style: { fontFamily:'var(--font-display)', fontSize:24, fontWeight:600, color:'var(--forest-deep)', marginBottom:8 }}, 'What "PERCH-Certified" actually means.'),
    React.createElement('p', { style: { fontSize:14, color:'var(--slate)', lineHeight:1.6, marginBottom:18, maxWidth:640 }}, 'Three separate certifications, each with a named inspector and liability insurance behind it. A unit only ships when all three clear for your specific parcel.'),
    React.createElement('div', { style: { display:'flex', flexDirection:'column', gap:12 }},
      tiers.map((t, i) =>
        React.createElement('div', { key:t.key, style: { display:'flex', gap:16, padding:'16px 18px', background:'white', border:'1px solid var(--border-strong)', borderRadius:6 }},
          React.createElement('div', { style: { flexShrink:0, width:36, height:36, borderRadius:'50%', background: t.obj.status === 'held' ? 'var(--sage)' : 'var(--parchment)', color: t.obj.status === 'held' ? 'white' : 'var(--forest-deep)', display:'flex', alignItems:'center', justifyContent:'center', fontFamily:'var(--font-mono)', fontSize:14, fontWeight:700, border: t.obj.status === 'held' ? 'none' : '1px solid var(--border-strong)' }}, i+1),
          React.createElement('div', { style: { flex:1 }},
            React.createElement('div', { style: { display:'flex', alignItems:'baseline', gap:10, flexWrap:'wrap', marginBottom:6 }},
              React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:16, fontWeight:600, color:'var(--forest-deep)' }}, t.obj.tier),
              React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.12em', textTransform:'uppercase', color: t.obj.status === 'held' ? 'var(--sage)' : 'var(--stone)', fontWeight:700 }}, t.obj.status === 'held' ? '✓ Held for The Nest' : 'Runs per buyer'),
            ),
            React.createElement('p', { style: { fontSize:13, color:'var(--slate)', lineHeight:1.6, margin:0 }}, t.obj.detail)
          )
        )
      )
    ),
    React.createElement('a', { href:'/certification/standard', style: { display:'inline-block', marginTop:16, fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.1em', textTransform:'uppercase', fontWeight:600, color:'var(--forest-deep)', textDecoration:'underline', textUnderlineOffset:3 }}, 'Read the full PERCH Standard →')
  );
}

// ─── COMPONENT × STATE APPROVAL MATRIX ─── (the third-wall failure Chris Penn identified)
function ComponentApprovalMatrix() {
  const p = window.PRODUCT;
  const m = p.componentApprovals;
  const cellFor = (row, st) => {
    const v = row[st];
    if (v === 'approved') return { label:'✓', color:'var(--sage)', bg:'rgba(58,109,88,0.08)' };
    if (v === 'on-request') return { label:'○', color:'var(--stone)', bg:'transparent' };
    return { label:'—', color:'var(--stone)', bg:'transparent' };
  };
  return React.createElement('section', { id:'component-approvals', style: { padding:'32px 0', borderBottom:'1px solid var(--border)' }},
    React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.16em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, marginBottom:8 }}, 'Component approvals · nationwide with re-engineering'),
    React.createElement('h2', { style: { fontFamily:'var(--font-display)', fontSize:24, fontWeight:600, color:'var(--forest-deep)', marginBottom:8 }}, 'Ships anywhere in the US. Cleared parts, per state.'),
    React.createElement('p', { style: { fontSize:14, color:'var(--slate)', lineHeight:1.6, marginBottom:18, maxWidth:680 }}, 'The Nest is available in every US state. States inside our default footprint (NC · SC · GA · TN · VA) use the existing component approvals below. States outside it — Florida, Texas, California, Arkansas, anywhere with a different code — may require plan re-engineering for windows, doors, tie-downs, or roof. That’s a quote and a timeline, not a no. Concierge scopes it within 24 hours of reserve.'),
    React.createElement('div', { style: { overflowX:'auto', border:'1px solid var(--border-strong)', borderRadius:6, background:'white' }},
      React.createElement('table', { style: { width:'100%', borderCollapse:'collapse', fontSize:13 }},
        React.createElement('thead', null,
          React.createElement('tr', { style: { background:'var(--parchment)' }},
            React.createElement('th', { style: { padding:'12px 14px', textAlign:'left', fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.1em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, borderBottom:'1px solid var(--border-strong)' }}, 'Component'),
            m.states.map(st =>
              React.createElement('th', { key:st, style: { padding:'12px 8px', textAlign:'center', fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.08em', color:'var(--forest-deep)', fontWeight:700, borderBottom:'1px solid var(--border-strong)', minWidth:52 }}, st)
            )
          )
        ),
        React.createElement('tbody', null,
          m.rows.map((r, ri) =>
            React.createElement('tr', { key:ri, style: { borderTop: ri > 0 ? '1px solid var(--border)' : 'none' }},
              React.createElement('td', { style: { padding:'12px 14px', color:'var(--forest-deep)', fontWeight:500 }}, r.component),
              m.states.map(st => {
                const c = cellFor(r, st);
                return React.createElement('td', { key:st, style: { padding:'12px 8px', textAlign:'center', color:c.color, background:c.bg, fontFamily:'var(--font-mono)', fontSize:15, fontWeight:600 }}, c.label);
              })
            )
          )
        )
      )
    ),
    React.createElement('div', { style: { marginTop:12, display:'flex', gap:16, flexWrap:'wrap', fontSize:11, fontFamily:'var(--font-mono)', color:'var(--stone)', letterSpacing:'0.06em' }},
      React.createElement('span', null, React.createElement('span', { style: { color:'var(--sage)', fontWeight:700 }}, '✓'), ' Approved'),
      React.createElement('span', null, React.createElement('span', { style: { fontWeight:700 }}, '○'), ' On request (24h)'),
      React.createElement('span', null, React.createElement('span', { style: { fontWeight:700 }}, '—'), ' Not in delivery footprint'),
    ),
    React.createElement('p', { style: { marginTop:14, fontSize:12, color:'var(--stone)', fontStyle:'italic', lineHeight:1.6 }}, m.footnote)
  );
}

// ─── C2PA SIGNED IMAGE CHIP ─── (only renders when image.provenance === 'signed')
// Used by gallery + lightbox. Renders nothing for provenance === 'render' (all Nest imagery today).
function C2PAChip({ image }) {
  if (!image || image.provenance !== 'signed') return null;
  return React.createElement('div', { style: { display:'inline-flex', alignItems:'center', gap:6, padding:'4px 10px', background:'rgba(28,61,38,0.85)', color:'var(--gold)', fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.12em', textTransform:'uppercase', fontWeight:700, borderRadius:6, backdropFilter:'blur(4px)' }},
    React.createElement('span', { style: { fontSize:11 }}, '⌘'),
    'Signed · C2PA'
  );
}

// ─── BUY-BOX QUANTITY TIERS ─── (buy 1, 2, or 3 Nests — factory-setup discount at scale)
// Horizontal 3-column card row, matching the Shopify pack-selector pattern (1-pack/2-pack/3-pack).
function BuyBoxQuantityTiers({ qty, setQty }) {
  const p = window.PRODUCT;
  const tiers = p.quantityTiers || [];
  return React.createElement('div', { style: { margin:'14px 24px 0' }},
    React.createElement('div', { style: { display:'flex', justifyContent:'space-between', alignItems:'baseline', marginBottom:8 }},
      React.createElement('div', { style: { fontSize:9, fontFamily:'var(--font-mono)', letterSpacing:'0.2em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700 }}, 'How many?'),
      React.createElement('div', { style: { fontSize:9, fontFamily:'var(--font-mono)', color:'var(--stone)', fontStyle:'italic' }}, 'Bulk pricing · factory saves'),
    ),
    React.createElement('div', { style: { display:'grid', gridTemplateColumns:'repeat(3, 1fr)', gap:6 }},
      tiers.map(t => {
        const isSelected = qty === t.qty;
        const perUnit = Math.round(p.price * (1 - t.discountPct));
        return React.createElement('label', {
          key: t.qty,
          onClick: () => setQty(t.qty),
          className: 'perch-tier-card' + (isSelected ? ' is-selected' : ''),
          style: {
            position:'relative', display:'flex', flexDirection:'column', justifyContent:'space-between',
            padding:'12px 8px 10px', minHeight:96,
            border:'1px solid ' + (isSelected ? 'var(--ember)' : 'var(--border-strong)'),
            borderRadius:6, cursor:'pointer',
            background: isSelected ? 'rgba(196,98,45,0.05)' : 'white',
            textAlign:'center',
          }
        },
          t.badge && React.createElement('div', { className:'perch-tier-badge', style: { position:'absolute', top:-8, left:'50%', transform:'translateX(-50%)', padding:'2px 8px', background:'var(--forest-deep)', color:'var(--gold)', fontFamily:'var(--font-mono)', fontSize:7.5, letterSpacing:'0.14em', textTransform:'uppercase', fontWeight:700, borderRadius:6, whiteSpace:'nowrap' }}, t.badge),
          React.createElement('div', null,
            React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:22, fontWeight:700, color:'var(--forest-deep)', lineHeight:1, marginBottom:4 }}, t.qty + '×'),
            React.createElement('div', { style: { fontSize:10, color:'var(--stone)', fontFamily:'var(--font-mono)', letterSpacing:'0.06em', textTransform:'uppercase', fontWeight:600 }}, t.qty === 1 ? 'Nest' : 'Nests'),
          ),
          React.createElement('div', { style: { marginTop:8 }},
            React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:10.5, color:'var(--forest-deep)', fontWeight:700 }}, '$' + perUnit.toLocaleString() + '/ea'),
            t.savingsLabel
              ? React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:8.5, color:'var(--sage)', letterSpacing:'0.1em', textTransform:'uppercase', fontWeight:700, marginTop:2 }}, t.savingsLabel)
              : React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:8.5, color:'var(--stone)', letterSpacing:'0.1em', textTransform:'uppercase', fontWeight:700, marginTop:2 }}, 'Sticker price'),
          ),
        );
      })
    ),
    qty > 1 && React.createElement('div', { style: { marginTop:8, padding:'8px 10px', background:'var(--parchment)', borderRadius:6, fontSize:11, color:'var(--slate)', lineHeight:1.5 }},
      React.createElement('strong', { style: { color:'var(--forest-deep)' }}, 'Buying more than one?'),
      ' You’ll configure each unit separately at Start Your Build — pick different siding, floor, or add-ons per unit.'
    )
  );
}

// ─── BUY-BOX ADD-ONS ─── (Tesla/car-configurator pattern — accessibility packages + premium upgrades)
// Controlled: parent owns {checked} so total updates live in the price section.
function BuyBoxAddOns({ checked, setChecked }) {
  const p = window.PRODUCT;
  const [expanded, setExpanded] = useState(false);
  const items = p.addOns || [];
  if (!items.length) return null;
  const activeTotal = items.reduce((s,i)=> s + (checked[i.key] ? i.price : 0), 0);
  const activeCount = items.filter(i => checked[i.key]).length;

  return React.createElement('div', { style: { margin:'12px 24px 0', border:'1px solid var(--border)', borderRadius:6, background:'white', overflow:'hidden' }},
    React.createElement('button', {
      onClick: ()=>setExpanded(!expanded),
      style: { width:'100%', display:'flex', justifyContent:'space-between', alignItems:'center', padding:'12px 14px', background:'none', border:'none', cursor:'pointer', textAlign:'left' }
    },
      React.createElement('div', null,
        React.createElement('div', { style: { fontSize:9, fontFamily:'var(--font-mono)', letterSpacing:'0.2em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700 }}, 'Add-ons · Accessibility + Premium'),
        React.createElement('div', { style: { fontSize:11, color:'var(--forest-deep)', marginTop:3, fontWeight:600 }},
          activeCount > 0
            ? activeCount + ' selected · +$' + activeTotal.toLocaleString() + '/unit'
            : 'Optional upgrades — added at the factory'
        ),
      ),
      React.createElement('span', { style: { fontSize:14, color:'var(--stone)', transform: expanded ? 'rotate(180deg)' : 'none', transition:'transform 0.15s' }}, '⌄')
    ),
    expanded && React.createElement('div', { style: { padding:'0 14px 14px', display:'flex', flexDirection:'column', gap:6, borderTop:'1px solid var(--border)' }},
      items.map(it => {
        const on = !!checked[it.key];
        return React.createElement('label', {
          key: it.key,
          onClick: ()=>setChecked({ ...checked, [it.key]: !on }),
          style: {
            display:'flex', gap:10, padding:'10px 12px',
            border:'1px solid ' + (on ? 'var(--ember)' : 'var(--border-strong)'),
            borderRadius:6, cursor:'pointer',
            background: on ? 'rgba(196,98,45,0.05)' : 'white',
            marginTop:8,
          }
        },
          React.createElement('div', { style: { width:16, height:16, borderRadius:6, border:'1.5px solid ' + (on ? 'var(--ember)' : 'var(--border-strong)'), background: on ? 'var(--ember)' : 'transparent', flexShrink:0, marginTop:2, display:'flex', alignItems:'center', justifyContent:'center', color:'white', fontSize:11, fontWeight:700 }}, on ? '✓' : ''),
          React.createElement('div', { style: { flex:1, minWidth:0 }},
            React.createElement('div', { style: { display:'flex', justifyContent:'space-between', alignItems:'baseline', gap:8, marginBottom:3 }},
              React.createElement('div', { style: { display:'flex', alignItems:'center', gap:6, flexWrap:'wrap' }},
                React.createElement('div', { style: { fontSize:12, fontWeight:700, color:'var(--forest-deep)' }}, it.title),
                React.createElement('span', { style: { fontFamily:'var(--font-mono)', fontSize:8, letterSpacing:'0.12em', textTransform:'uppercase', color: it.tag === 'Premium' ? 'var(--gold)' : 'var(--sage)', background: it.tag === 'Premium' ? 'var(--forest-deep)' : 'rgba(58,109,88,0.12)', padding:'2px 6px', borderRadius:6, fontWeight:700 }}, it.tag),
              ),
              React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:12, fontWeight:700, color:'var(--forest-deep)', whiteSpace:'nowrap' }}, '+$' + it.price.toLocaleString()),
            ),
            React.createElement('div', { style: { fontSize:11, color:'var(--stone)', lineHeight:1.5 }}, it.blurb),
          )
        );
      })
    )
  );
}

// ─── BUY-BOX TRUST CLUSTER ─── (single-line quiet ribbon — 4 seals-of-approval on one row)
// Redundancy note: each layer is elaborated deeper on the PDP (Certified/Inspected in Manufacturer + Builder,
// Site-Verified in the Land Check section, State-Approved via re-engineering copy in the Land Check verdict).
// This ribbon is a compressed re-affirmation right before the CTA — not a repeat.
function BuyBoxTrustCluster() {
  const chips = [
    { label: 'Certified',   href: '/certified',           title: 'PERCH-Certified · builder ops audit + third-party inspection' },
    { label: 'Inspected',   href: '#builder',             title: 'NTA state-label inspection completed 11/14/2023' },
    { label: 'Verified',    href: '#site-verification',   title: 'Zoning + setbacks + wastewater checked against your address' },
    { label: 'Approved',    href: '#specs',               title: 'Doors, windows, roof, siding, tie-downs pre-checked for delivery-state code' },
  ];
  return React.createElement('div', {
    className: 'perch-trust-ribbon',
    style: {
      margin:'12px 24px 0',
      display:'grid', gridTemplateColumns:'repeat(4, 1fr)',
      padding:'8px 4px', background:'var(--parchment)',
      borderRadius:6, gap:2
    }
  },
    chips.map(c =>
      React.createElement('a', {
        key: c.label,
        href: c.href,
        title: c.title,
        className:'perch-trust-chip',
        style: {
          display:'inline-flex', alignItems:'center', justifyContent:'center', gap:4,
          fontFamily:'var(--font-mono)', fontSize:9, letterSpacing:'0.12em', textTransform:'uppercase', fontWeight:700,
          color:'var(--forest-deep)', textDecoration:'none', cursor:'pointer',
          padding:'4px 0', minWidth:0, whiteSpace:'nowrap',
        }
      },
        React.createElement('span', { className:'perch-trust-check', style: { color:'var(--sage)', fontSize:11, lineHeight:1, display:'inline-block' }}, '✓'),
        React.createElement('span', { style:{ overflow:'hidden', textOverflow:'ellipsis' }}, c.label)
      )
    )
  );
}

// ─── BUILD SLOT COUNTER ─── (real-scarcity — no fake urgency, real production window)
// Animations (CSS-driven): pulsing ember indicator dot + progress bar fills from 0→pct on mount.
function BuildSlotCounter() {
  const s = (window.PRODUCT || {}).buildSlots;
  if (!s) return null;
  const pct = Math.round(((s.totalThisWindow - s.remainingThisWindow) / s.totalThisWindow) * 100);
  return React.createElement('div', { className:'perch-slot-counter', style: { display:'flex', alignItems:'center', gap:12, padding:'12px 16px', background:'var(--parchment)', border:'1px solid var(--border)', borderLeft:'3px solid var(--ember)', borderRadius:6 }},
    React.createElement('div', { style: { flexShrink:0, fontFamily:'var(--font-display)', fontSize:26, fontWeight:600, color:'var(--forest-deep)', lineHeight:1 }}, s.remainingThisWindow),
    React.createElement('div', { style: { flex:1 }},
      React.createElement('div', { style: { fontSize:12, fontWeight:600, color:'var(--forest-deep)' }}, 'build slot' + (s.remainingThisWindow === 1 ? '' : 's') + ' left this window (' + s.windowLabel + ')'),
      React.createElement('div', { style: { fontSize:11, color:'var(--stone)', marginTop:2 }}, 'Next production window opens ' + s.nextWindowLabel + '.'),
      React.createElement('div', { className:'perch-slot-bar', style: { marginTop:6, height:4, background:'white', border:'1px solid var(--border)', borderRadius:6, overflow:'hidden', position:'relative' }},
        React.createElement('div', { className:'perch-slot-bar-fill', style: { width: pct + '%', height:'100%', background:'linear-gradient(90deg, var(--ember) 0%, #d17742 100%)', position:'relative', overflow:'hidden' }},
          React.createElement('div', { className:'perch-slot-bar-shimmer' })
        )
      )
    )
  );
}

// ─── COMPARE TO SITE-BUILT ─── (buyer's biggest unspoken question: why not stick-built?)
function CompareToSiteBuilt() {
  const p = window.PRODUCT || {};
  const rows = p.compareRows || [];
  const sum = p.compareSummary;
  if (!rows.length) return null;
  return React.createElement('section', { style: { padding:'40px 0', borderBottom:'1px solid var(--border)' }},
    React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.16em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, marginBottom:8 }}, 'Head to head'),
    React.createElement('h2', { style: { fontFamily:'var(--font-display)', fontSize:28, fontWeight:600, color:'var(--forest-deep)', marginBottom:8, letterSpacing:'-0.01em' }}, 'The Nest vs. building on-site.'),
    React.createElement('p', { style: { fontSize:14, color:'var(--slate)', lineHeight:1.6, marginBottom:20, maxWidth:640 }}, 'Same one-bedroom, same lot. Two very different ways to get there.'),
    React.createElement('div', { style: { overflow:'auto', border:'1px solid var(--border-strong)', borderRadius:6, background:'white' }},
      React.createElement('table', { style: { width:'100%', borderCollapse:'collapse', fontSize:13 }},
        React.createElement('thead', null,
          React.createElement('tr', { style: { background:'var(--parchment)' }},
            React.createElement('th', { style: { padding:'14px 16px', textAlign:'left', fontFamily:'var(--font-mono)', fontSize:9, letterSpacing:'0.14em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, borderBottom:'1px solid var(--border-strong)', minWidth:180 }}, ''),
            React.createElement('th', { style: { padding:'14px 16px', textAlign:'left', fontFamily:'var(--font-display)', fontSize:15, color:'var(--forest-deep)', fontWeight:700, borderBottom:'1px solid var(--border-strong)', borderLeft:'1px solid var(--border-strong)', background:'rgba(232,200,119,0.12)' }}, 'The Nest'),
            React.createElement('th', { style: { padding:'14px 16px', textAlign:'left', fontFamily:'var(--font-display)', fontSize:15, color:'var(--stone)', fontWeight:600, borderBottom:'1px solid var(--border-strong)', borderLeft:'1px solid var(--border-strong)' }}, 'Site-built')
          )
        ),
        React.createElement('tbody', null,
          rows.map((r, i) =>
            React.createElement('tr', { key:i, style: { borderTop:'1px solid var(--border)' }},
              React.createElement('td', { style: { padding:'12px 16px', color:'var(--stone)', fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.06em', textTransform:'uppercase', fontWeight:600 }}, r.dim),
              React.createElement('td', { style: { padding:'12px 16px', color:'var(--forest-deep)', fontWeight:600, borderLeft:'1px solid var(--border)', background:'rgba(232,200,119,0.05)' }}, r.nest),
              React.createElement('td', { style: { padding:'12px 16px', color:'var(--slate)', borderLeft:'1px solid var(--border)' }}, r.siteBuilt),
            )
          ),
          // Winner + savings footer row
          sum && React.createElement('tr', { style: { borderTop:'2px solid var(--forest-deep)', background:'var(--forest-deep)' }},
            React.createElement('td', { style: { padding:'16px', color:'var(--gold)', fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.16em', textTransform:'uppercase', fontWeight:700 }}, 'Clear winner'),
            React.createElement('td', { colSpan:2, style: { padding:'16px', color:'var(--gold)', borderLeft:'1px solid rgba(232,200,119,0.3)' }},
              React.createElement('div', { style: { display:'flex', alignItems:'center', gap:14, flexWrap:'wrap' }},
                React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:20, fontWeight:600, color:'var(--gold)' }}, sum.winner),
                React.createElement('div', { style: { flex:1, minWidth:200 }},
                  React.createElement('div', { style: { fontSize:14, color:'white', fontWeight:600 }}, 'Saves you $' + sum.savingsLow.toLocaleString() + '–$' + sum.savingsHigh.toLocaleString()),
                  React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.1em', color:'rgba(232,200,119,0.8)', marginTop:3 }}, sum.monthsSaved),
                )
              )
            )
          )
        )
      )
    )
  );
}

// ─── SECURE-CHECKOUT TRUST RAIL ─── (payment-security signal under monthly-est chip)
// Chargeback chip intentionally omitted — PERCH takes wire / ACH / escrow only (no cards).
function SecureCheckoutTrustRail() {
  const chips = [
    { icon:'lock', label:'256-bit SSL' },
    { icon:'account_balance', label:'Licensed Escrow' },
    { icon:'verified_user', label:'PCI-Compliant' },
  ];
  return React.createElement('div', { style: { marginTop:12, padding:'10px 12px', background:'var(--parchment)', border:'1px solid var(--border)', borderRadius:6, display:'flex', flexWrap:'wrap', justifyContent:'center', gap:10 }},
    chips.map(c =>
      React.createElement('div', { key:c.label, style: { display:'inline-flex', alignItems:'center', gap:5, fontFamily:'var(--font-mono)', fontSize:9, letterSpacing:'0.12em', textTransform:'uppercase', color:'var(--forest-deep)', fontWeight:700 }},
        React.createElement(PDPIcon, { name:c.icon, size:11, style:{ color:'var(--sage)' }}),
        c.label
      )
    )
  );
}

// ─── TIMELINE GANTT ─── (visual gantt with YOU ARE HERE marker)
function TimelineGantt({ currentStep = 0 }) {
  const stages = [
    { label:'Browsing',       days:0,   note:'You are here' },
    { label:'Reserve',        days:1,   note:'20% into escrow' },
    { label:'Engineering',    days:14,  note:'Site plans + permit prep' },
    { label:'Frame',          days:21,  note:'Factory frame + rough-ins' },
    { label:'Finish',          days:28, note:'Cabinets · fixtures · trim' },
    { label:'Delivery',       days:10,  note:'Truck to site · set crew' },
    { label:'Move-in',        days:0,   note:'Certificate of Occupancy' },
  ];
  const totalDays = stages.reduce((s,st) => s + st.days, 0);
  return React.createElement('section', { style: { padding:'40px 0', borderBottom:'1px solid var(--border)' }},
    React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.16em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, marginBottom:8 }}, 'Your build timeline'),
    React.createElement('h2', { style: { fontFamily:'var(--font-display)', fontSize:28, fontWeight:600, color:'var(--forest-deep)', marginBottom:8, letterSpacing:'-0.01em' }}, 'From today to keys.'),
    React.createElement('p', { style: { fontSize:14, color:'var(--slate)', lineHeight:1.6, marginBottom:24, maxWidth:640 }}, 'Every stage releases from escrow only after dated video/photo proof and your digital sign-off. Weather never touches the schedule — the factory is indoors.'),
    // Horizontal gantt
    React.createElement('div', { style: { position:'relative', padding:'40px 0 20px' }},
      React.createElement('div', { style: { position:'absolute', top:44, left:20, right:20, height:2, background:'var(--border-strong)' }}),
      React.createElement('div', { style: { display:'grid', gridTemplateColumns:'repeat(' + stages.length + ', 1fr)', gap:8, position:'relative' }},
        stages.map((st, i) => {
          const isCurrent = i === currentStep;
          const isPast = i < currentStep;
          const dotColor = isCurrent ? 'var(--ember)' : isPast ? 'var(--sage)' : 'var(--stone)';
          const dotBg = isCurrent ? 'var(--ember)' : isPast ? 'var(--sage)' : 'white';
          return React.createElement('div', { key:i, style: { textAlign:'center', position:'relative' }},
            isCurrent && React.createElement('div', { style: { position:'absolute', top:-28, left:'50%', transform:'translateX(-50%)', padding:'3px 10px', background:'var(--ember)', color:'white', fontFamily:'var(--font-mono)', fontSize:9, letterSpacing:'0.14em', textTransform:'uppercase', fontWeight:700, borderRadius:6, whiteSpace:'nowrap' }}, 'You are here'),
            React.createElement('div', { style: { width:20, height:20, borderRadius:'50%', background:dotBg, border:'2.5px solid ' + dotColor, margin:'0 auto', boxSizing:'border-box', boxShadow: isCurrent ? '0 0 0 6px rgba(196,98,45,0.15)' : 'none' }}),
            React.createElement('div', { style: { fontSize:12, fontWeight:600, color:'var(--forest-deep)', marginTop:12 }}, st.label),
            st.days > 0 && React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:10, color:'var(--stone)', letterSpacing:'0.08em', marginTop:2 }}, '~' + st.days + 'd'),
            React.createElement('div', { style: { fontSize:11, color:'var(--slate)', marginTop:4, lineHeight:1.35, padding:'0 4px' }}, st.note),
          );
        })
      )
    ),
    React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:11, color:'var(--stone)', letterSpacing:'0.06em', textAlign:'right' }}, 'Total ~' + totalDays + ' days · 10–12 weeks typical')
  );
}

// ─── TRANSPARENCY BLOCK ─── ("What if..." four honest answers)
function TransparencyBlock() {
  const items = (window.PRODUCT || {}).transparencyFAQ || [];
  const [openIdx, setOpenIdx] = useState(0);
  if (!items.length) return null;
  return React.createElement('section', { style: { padding:'40px 0', borderBottom:'1px solid var(--border)' }},
    React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.16em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, marginBottom:8 }}, 'The honest questions'),
    React.createElement('h2', { style: { fontFamily:'var(--font-display)', fontSize:28, fontWeight:600, color:'var(--forest-deep)', marginBottom:8, letterSpacing:'-0.01em' }}, '"What if&hellip;"'),
    React.createElement('p', { style: { fontSize:14, color:'var(--slate)', lineHeight:1.6, marginBottom:20, maxWidth:640 }}, 'Four things buyers actually worry about. Four honest answers, on the record.'),
    React.createElement('div', { style: { border:'1px solid var(--border-strong)', borderRadius:6, background:'white', overflow:'hidden' }},
      items.map((it, i) =>
        React.createElement('div', { key:i, style: { borderTop: i > 0 ? '1px solid var(--border)' : 'none' }},
          React.createElement('button', {
            onClick: ()=>setOpenIdx(openIdx === i ? -1 : i),
            style: { width:'100%', padding:'16px 20px', display:'flex', justifyContent:'space-between', alignItems:'center', background: openIdx === i ? 'var(--parchment)' : 'white', border:'none', cursor:'pointer', textAlign:'left', transition:'background 0.15s' }
          },
            React.createElement('span', { style: { fontFamily:'var(--font-display)', fontSize:16, fontWeight:600, color:'var(--forest-deep)' }}, it.q),
            React.createElement('span', { style: { fontSize:16, color:'var(--stone)', transform: openIdx === i ? 'rotate(180deg)' : 'none', transition:'transform 0.2s' }}, '⌄')
          ),
          openIdx === i && React.createElement('div', { style: { padding:'0 20px 18px', background:'var(--parchment)' }},
            React.createElement('p', { style: { fontSize:14, color:'var(--slate)', lineHeight:1.7, margin:0 }}, it.a)
          )
        )
      )
    )
  );
}

// ─── FLOOR PLAN OVERLAY ─── (hover-to-reveal per-room tooltips over the floor plan image)
function FloorPlanOverlay() {
  const p = window.PRODUCT || {};
  const rooms = p.floorPlanRooms || [];
  const [hover, setHover] = useState(null);
  return React.createElement('section', { style: { padding:'40px 0', borderBottom:'1px solid var(--border)' }},
    React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.16em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, marginBottom:8 }}, 'Floor plan'),
    React.createElement('h2', { style: { fontFamily:'var(--font-display)', fontSize:28, fontWeight:600, color:'var(--forest-deep)', marginBottom:8, letterSpacing:'-0.01em' }}, 'Every room, on the record.'),
    React.createElement('p', { style: { fontSize:14, color:'var(--slate)', lineHeight:1.6, marginBottom:20, maxWidth:640 }}, 'Hover any room to see square footage, fixtures, and finish.'),
    React.createElement('div', { style: { display:'grid', gridTemplateColumns:'2fr 1fr', gap:24, alignItems:'start' }},
      React.createElement('div', { style: { position:'relative', background:'var(--parchment)', border:'1px solid var(--border-strong)', borderRadius:6, overflow:'hidden' }},
        React.createElement('img', { src:'/homes/the-nest/images/floor-plan.png', alt:'The Nest floor plan', style: { display:'block', width:'100%', height:'auto' }, loading:'lazy' }),
        rooms.map((r, i) =>
          React.createElement('div', {
            key: i,
            onMouseEnter: ()=>setHover(i),
            onMouseLeave: ()=>setHover(prev => prev === i ? null : prev),
            style: {
              position:'absolute',
              left: r.xPct + '%', top: r.yPct + '%', width: r.wPct + '%', height: r.hPct + '%',
              border: '1.5px solid ' + (hover === i ? 'var(--ember)' : 'rgba(196,98,45,0.35)'),
              background: hover === i ? 'rgba(196,98,45,0.15)' : 'rgba(196,98,45,0.05)',
              cursor:'pointer', transition:'all 0.15s', borderRadius:6,
              display:'flex', alignItems:'flex-start', justifyContent:'flex-start',
              padding:6,
            }
          },
            React.createElement('span', { style: { fontFamily:'var(--font-mono)', fontSize:9, letterSpacing:'0.1em', textTransform:'uppercase', color:'var(--forest-deep)', fontWeight:700, background:'rgba(255,255,255,0.85)', padding:'2px 5px', borderRadius:6 }}, r.name)
          )
        )
      ),
      React.createElement('div', { style: { minHeight:200, padding:'20px 22px', background:'white', border:'1px solid var(--border-strong)', borderRadius:6 }},
        hover !== null
          ? React.createElement(React.Fragment, null,
              React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.14em', textTransform:'uppercase', color:'var(--ember)', fontWeight:700, marginBottom:6 }}, rooms[hover].sqft),
              React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:20, fontWeight:600, color:'var(--forest-deep)', marginBottom:10 }}, rooms[hover].name),
              React.createElement('p', { style: { fontSize:13, color:'var(--slate)', lineHeight:1.6, margin:0 }}, rooms[hover].notes)
            )
          : React.createElement('div', { style: { fontSize:13, color:'var(--stone)', lineHeight:1.6, fontStyle:'italic' }}, 'Hover a room on the plan to see its details.')
      )
    )
  );
}

// ─── SCHEDULE-A-CALL MODAL ─── (bandwidth-preserving contact — routes to Cameron)
function ScheduleCallModal({ open, onClose }) {
  const sc = (window.PRODUCT || {}).scheduleContact || { email:'hello@ownperch.com', replyWindow:'24 hours' };
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [msg, setMsg] = useState('');
  const [sent, setSent] = useState(false);
  if (!open) return null;
  const submit = (e) => {
    e.preventDefault();
    const subject = encodeURIComponent('The Nest · Schedule a call · ' + (name || 'Buyer inquiry'));
    const body = encodeURIComponent('Name: ' + name + '\nEmail: ' + email + '\n\n' + msg + '\n\n— Sent from ownperch.com/homes/the-nest');
    // eslint-disable-next-line no-console
    console.log('[PERCH] Schedule-a-call intent', { name, email, msg });
    window.location.href = 'mailto:' + sc.email + '?subject=' + subject + '&body=' + body;
    setSent(true);
  };
  return React.createElement('div', {
    onClick: onClose,
    style: { position:'fixed', inset:0, background:'rgba(20,48,29,0.55)', backdropFilter:'blur(6px)', zIndex:1050, display:'flex', alignItems:'center', justifyContent:'center', padding:20 }
  },
    React.createElement('div', {
      onClick: e => e.stopPropagation(),
      style: { background:'var(--cream)', borderRadius:8, maxWidth:480, width:'100%', boxShadow:'0 24px 70px rgba(0,0,0,0.35)', overflow:'hidden' }
    },
      React.createElement('div', { style: { padding:'20px 24px', borderBottom:'1px solid var(--border)', display:'flex', justifyContent:'space-between', alignItems:'flex-start' }},
        React.createElement('div', null,
          React.createElement('div', { style: { fontSize:10, fontFamily:'var(--font-mono)', letterSpacing:'0.16em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, marginBottom:6 }}, 'Talk to a human · founder-answered'),
          React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:22, fontWeight:600, color:'var(--forest-deep)' }}, sent ? 'Your message is on the way.' : 'Schedule a call.')
        ),
        React.createElement('button', { onClick: onClose, style: { background:'none', border:'none', fontSize:22, cursor:'pointer', color:'var(--stone)', padding:4 }}, '×')
      ),
      React.createElement('div', { style: { padding:'20px 24px' }},
        sent
          ? React.createElement('div', null,
              React.createElement('p', { style: { fontSize:14, color:'var(--slate)', lineHeight:1.7, marginBottom:14 }}, 'Your email client just opened with a draft to ', React.createElement('strong', null, sc.email), '. Send it whenever you\'re ready — Cameron reads every one personally and replies within ' + sc.replyWindow + ' to set a call or answer in writing.'),
              React.createElement('button', { onClick:()=>{ setSent(false); onClose(); }, style: { padding:'12px 22px', background:'var(--forest)', color:'var(--gold)', border:'none', fontFamily:'var(--font-mono)', fontSize:11, letterSpacing:'0.1em', textTransform:'uppercase', cursor:'pointer', fontWeight:700, borderRadius:6 }}, 'Close')
            )
          : React.createElement('form', { onSubmit:submit },
              React.createElement('p', { style: { fontSize:13, color:'var(--slate)', lineHeight:1.6, marginBottom:14 }}, sc.note),
              React.createElement('div', { style: { display:'flex', flexDirection:'column', gap:10, marginBottom:14 }},
                React.createElement('input', { type:'text', required:true, value:name, onChange:e=>setName(e.target.value), placeholder:'Your name', style: { padding:'12px', border:'1px solid var(--border-strong)', borderRadius:6, fontSize:14, boxSizing:'border-box' }}),
                React.createElement('input', { type:'email', required:true, value:email, onChange:e=>setEmail(e.target.value), placeholder:'Email address', style: { padding:'12px', border:'1px solid var(--border-strong)', borderRadius:6, fontSize:14, boxSizing:'border-box' }}),
                React.createElement('textarea', { value:msg, onChange:e=>setMsg(e.target.value), placeholder:'What would you like to talk about? (optional)', rows:4, style: { padding:'12px', border:'1px solid var(--border-strong)', borderRadius:6, fontSize:14, boxSizing:'border-box', fontFamily:'var(--font-body)', resize:'vertical' }}),
              ),
              React.createElement('button', { type:'submit', style: { width:'100%', padding:'14px', background:'var(--forest-deep)', color:'var(--gold)', border:'none', fontFamily:'var(--font-mono)', fontSize:12, letterSpacing:'0.14em', textTransform:'uppercase', cursor:'pointer', fontWeight:700, borderRadius:6 }}, 'Send · reply within ' + sc.replyWindow)
            )
      )
    )
  );
}

// ─── WHO YOU'RE BUYING FROM ─── (durable, one-line, quotable — buyer-facing framing)
function RegulatoryStrip() {
  const p = window.PRODUCT || {};
  if (!p.regulatoryPositioning) return null;
  return React.createElement('div', { style: { padding:'22px 28px', background:'var(--forest-deep)', color:'var(--gold)', textAlign:'center', borderRadius:6, margin:'20px 0' }},
    React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:10, letterSpacing:'0.22em', textTransform:'uppercase', fontWeight:700, marginBottom:8, opacity:0.75 }}, 'Who you’re buying from'),
    React.createElement('p', { style: { fontFamily:'var(--font-display)', fontSize:16, lineHeight:1.55, margin:0, fontWeight:400, letterSpacing:'0.005em' }}, p.regulatoryPositioning)
  );
}

// ─── PERCH BY THE NUMBERS ─── (quiet investor-signal footer strip)
function PerchByNumbers() {
  const n = (window.PRODUCT || {}).perchByNumbers;
  if (!n) return null;
  const items = [
    { val: n.buildersCertified,     label: 'Builders Certified' },
    { val: n.waitlistBuyers.toLocaleString(), label: 'Waitlist Buyers' },
    { val: n.unitsInProduction,     label: 'Units in Production' },
    { val: n.footprintDefault,      label: 'Free-Freight States' },
    { val: n.footprintAvailable,    label: 'Nationwide' },
  ];
  return React.createElement('div', { style: { padding:'24px 0', borderTop:'1px solid var(--border)', borderBottom:'1px solid var(--border)', display:'flex', justifyContent:'space-around', gap:16, flexWrap:'wrap' }},
    items.map((it, i) =>
      React.createElement('div', { key:i, style: { textAlign:'center', minWidth:100 }},
        React.createElement('div', { style: { fontFamily:'var(--font-display)', fontSize:22, fontWeight:600, color:'var(--forest-deep)', letterSpacing:'-0.01em' }}, it.val),
        React.createElement('div', { style: { fontFamily:'var(--font-mono)', fontSize:9, letterSpacing:'0.16em', textTransform:'uppercase', color:'var(--stone)', fontWeight:700, marginTop:4 }}, it.label),
      )
    )
  );
}

Object.assign(window, {
  SocialProofBar, Lightbox, ReserveSidebar, IncludedSection, DeliveryTimeline,
  CustomizeSection, ZoningChecker, VirtualTourPlaceholder, DeliveryEstimator,
  FAQSection, SpecsSection, BuilderSection, ManufacturerDisclosure, ReviewsSection, SimilarHomes, MobileCTA,
  OrderSheetModal, PreApprovalModal, AskModal,
  TurnKeyEstimatorModal, VerifiedBadge, EscrowExplainerModal,
  HomeCareSection, ShareRow, PartnerInviteModal, ContractorShareModal, SignupModal,
  FinancingCalculator,
  SiteVerification, ComponentApprovalMatrix, C2PAChip,
  BuyBoxQuantityTiers, BuyBoxTrustCluster, BuyBoxAddOns,
  BuildSlotCounter, CompareToSiteBuilt, TimelineGantt, TransparencyBlock, FloorPlanOverlay, ScheduleCallModal, RegulatoryStrip, PerchByNumbers,
  SecureCheckoutTrustRail, SpecsFloorPlanCard
});
