// ============================================================
//  Happy Fence Quote Quiz — React 18 + Babel Standalone
//  Loaded as an external script so WordPress doesn't mangle
//  the && operators in this file.
//
//  Update log:
//  2026-05-08 - Promoted A2P 10DLC SMS consent to its own dedicated
//    final screen, but kept the user-facing step counter at 5 (not 6)
//    so the consent reads as a final-confirmation continuation of
//    Step 5 rather than a new piece of information being collected.
//    Implementation: TOTAL = 6 internally for state navigation, but
//    TOTAL_DISPLAY = 5 drives the progress bar fill, "Step X of Y"
//    label, and time estimate. The consent screen's StepHeading
//    kicker shows "Final step" (no number). Step 6 renders a yellow
//    "One last thing" card with custom 26px brand checkbox, a
//    state-aware helper line ("↑ Check the box to unlock submit"
//    -> "✓ All set - click submit below"), and a full-width submit
//    button whose disabled vs active treatment is unmistakable.
//    Step 5 (contact form) needs a manual "Next ->" button since it
//    no longer holds submit. Auto-advance still applies to steps
//    1-4. Modal disclosure + Zapier consent payload (sms_consent,
//    sms_consent_text, sms_consent_at) carry forward unchanged.
// ============================================================

// ZAPIER WEBHOOK
// 1. In Zapier: Create Zap -> "Webhooks by Zapier" -> "Catch Hook"
// 2. Copy the webhook URL
// 3. Paste it below, replacing PASTE_YOUR_ZAPIER_WEBHOOK_URL_HERE
const ZAPIER_WEBHOOK_URL = "PASTE_YOUR_ZAPIER_WEBHOOK_URL_HERE";

// Internal step count includes the consent screen as step 6.
// TOTAL_DISPLAY is what the user sees in the progress bar / counter
// — we keep it at 5 so the consent screen reads as a continuation
// of step 5, not a new step.
const TOTAL = 6;
const TOTAL_DISPLAY = 5;

// A2P 10DLC required disclosure shown in the consent popup.
// Must match what the visible UI tells the user they're agreeing to.
const SMS_CONSENT_TEXT = "By submitting, you authorize Happy Fence Company LLC to text/call the number above for informational/transactional messages, possibly using automated means. Msg/data rates apply, msg frequency varies. Consent is not a condition of purchase. See terms (https://www.leadconnectorhq.com/terms2) and privacy policy (https://www.leadconnectorhq.com/privacy-policy). Text HELP for help and STOP to unsubscribe.";

const MATERIALS = [
  { key:'wood', name:'Wood', price:'$', life:'Lasts 10\u201315 years',
    blurb:'Pressure-treated pine or cedar. Classic look, warm character.',
    color:'#a0785a' },
  { key:'durafence', name:'Durafence', price:'$$', life:'Lasts 40+ years',
    blurb:'Galvanized steel. Hurricane-tough. Bulletproof.',
    color:'var(--yellow-dk)' },
  { key:'vinyl', name:'Vinyl', price:'$$$', life:'Lasts 20\u201330 years',
    blurb:'Zero maintenance, fade-resistant. HOA favorite.',
    color:'var(--blue-dk)' },
  { key:'aluminum', name:'Custom Aluminum', price:'$$$$', life:'Lasts 30+ years',
    blurb:'Decorative, pool-code compliant. Built to last.',
    color:'#8a8f99' },
  { key:'unsure', name:'Not sure \u2014 help me decide', price:'\u2014', life:'Expert recommends on the call',
    blurb:"Tell us the goal \u2014 we'll match the right material.",
    color:'#ccd5de' },
];

const FEET = [
  { key:'u80',    name:'Under 80 ft',        sub:'Small yard / partial section' },
  { key:'80_150', name:'80 \u2013 150 ft',   sub:'Typical backyard' },
  { key:'150_250',name:'150 \u2013 250 ft',  sub:'Full property perimeter' },
  { key:'250p',   name:'250+ ft',            sub:'Large lot / double lot' },
  { key:'unsure', name:'Not sure',           sub:"We'll measure on the walkthrough" },
];

const TIMELINE = [
  { key:'asap',   name:'ASAP',               sub:'Within 2 weeks', tag:'Priority' },
  { key:'2_6',    name:'2 \u2013 6 weeks',   sub:'Standard booking' },
  { key:'1_3m',   name:'1 \u2013 3 months',  sub:'Planning ahead' },
  { key:'browse', name:'Just exploring',     sub:'Gathering info' },
];

const PERMITS = [
  { key:'yes',    name:'Yes, please',    sub:'Pull permits for me' },
  { key:'no',     name:'No thanks',      sub:"I've got it handled" },
  { key:'unsure', name:'Not sure',       sub:"We'll walk you through it" },
];

function ProgressBar({ step, compact }) {
  // Clamp the displayed step to TOTAL_DISPLAY so the consent screen
  // (internal step 6) reads as "Step 5 of 5" with the bar at 100%.
  const displayStep = Math.min(step, TOTAL_DISPLAY);
  const pct = (displayStep / TOTAL_DISPLAY) * 100;
  return (
    <div style={{ width:'100%' }}>
      <div style={{
        display:'flex', justifyContent:'space-between', alignItems:'baseline',
        marginBottom: compact ? 8 : 10,
      }}>
        <div style={{
          fontFamily:'"Space Mono",monospace',
          fontSize: compact ? 11 : 12, letterSpacing:1.5, textTransform:'uppercase',
          color:'var(--ink)',
        }}>Step {displayStep} of {TOTAL_DISPLAY}</div>
        <div style={{
          fontFamily:'"Space Mono",monospace',
          fontSize: compact ? 10 : 11, letterSpacing:1, color:'var(--muted)',
        }}>~{Math.max(0, (TOTAL_DISPLAY - displayStep + 1) * 15)} sec left</div>
      </div>
      <div style={{
        height: compact ? 8 : 10, background:'var(--cream)',
        border:'2px solid var(--ink)', borderRadius:999, overflow:'hidden',
        position:'relative',
      }}>
        <div style={{
          width:`${pct}%`, height:'100%', background:'var(--yellow)',
          borderRight:'2px solid var(--ink)',
          transition:'width .35s cubic-bezier(.2,.8,.2,1)',
        }}/>
      </div>
    </div>
  );
}

function StepHeading({ kicker, title, subtitle, compact }) {
  return (
    <div style={{ marginBottom: compact ? 20 : 28 }}>
      <div style={{
        fontFamily:'"Space Mono",monospace',
        fontSize: compact ? 10 : 11, letterSpacing:2.5,
        textTransform:'uppercase', color:'var(--muted)', marginBottom:8,
      }}>{kicker}</div>
      <h2 style={{
        fontFamily:'"Bagel Fat One",sans-serif',
        fontSize: compact ? 28 : 40, lineHeight:1.05, color:'var(--ink)',
        marginBottom: 8,
      }}>{title}</h2>
      {subtitle ? <p style={{
        fontSize: compact ? 14 : 16, color:'var(--muted)', lineHeight:1.5,
      }}>{subtitle}</p> : null}
    </div>
  );
}

function Tile({ selected, onClick, children, minH }) {
  return (
    <button onClick={onClick} style={{
      position:'relative', textAlign:'left', cursor:'pointer',
      background: selected ? 'var(--yellow)' : 'var(--cream)',
      border:'2px solid var(--ink)', borderRadius:10,
      boxShadow: selected ? '6px 6px 0 var(--ink)' : '4px 4px 0 var(--ink)',
      padding:0, fontFamily:'inherit', color:'inherit',
      transform: selected ? 'translate(-2px,-2px)' : 'none',
      transition:'transform .12s, box-shadow .12s, background .12s',
      minHeight: minH,
      width:'100%',
    }}
    onMouseEnter={e=>{ if(!selected){ e.currentTarget.style.transform='translate(-2px,-2px)'; e.currentTarget.style.boxShadow='6px 6px 0 var(--ink)'; }}}
    onMouseLeave={e=>{ if(!selected){ e.currentTarget.style.transform='none'; e.currentTarget.style.boxShadow='4px 4px 0 var(--ink)'; }}}
    >
      {children}
      {selected ? (
        <div style={{
          position:'absolute', top:10, right:10,
          width:28, height:28, borderRadius:'50%',
          background:'var(--ink)', color:'var(--yellow)',
          display:'flex', alignItems:'center', justifyContent:'center',
          fontFamily:'"Bagel Fat One",sans-serif', fontSize:16,
        }}>{'\u2713'}</div>
      ) : null}
    </button>
  );
}

function Step1_Material({ value, onPick, compact }) {
  return (
    <div>
      <StepHeading
        kicker={'Step 1 of 5 \u00b7 Material'}
        title="What material are you thinking?"
        subtitle={"Pick what speaks to you \u2014 or tell us you're not sure. Anthony will walk you through trade-offs on the Zoom call."}
        compact={compact}
      />
      <div style={{
        display:'grid',
        gridTemplateColumns: compact ? '1fr' : 'repeat(2, 1fr)',
        gap: compact ? 12 : 16,
      }}>
        {MATERIALS.map(m => (
          <Tile key={m.key} selected={value === m.key} onClick={() => onPick(m.key)} minH={compact ? 120 : 150}>
            <div style={{ display:'flex', alignItems:'stretch', height:'100%' }}>
              <div style={{
                width: compact ? 10 : 12, background:m.color,
                borderRight:'2px solid var(--ink)', flexShrink:0,
              }}/>
              <div style={{
                padding: compact ? '14px 16px' : '18px 22px', flex:1,
                display:'flex', flexDirection:'column', justifyContent:'center',
              }}>
                <div style={{
                  display:'flex', alignItems:'baseline', gap:10, flexWrap:'wrap',
                  marginBottom:4,
                }}>
                  <span style={{
                    fontFamily:'"Bagel Fat One",sans-serif',
                    fontSize: compact ? 22 : 28, lineHeight:1.1, color:'var(--ink)',
                  }}>{m.name}</span>
                  <span style={{
                    fontFamily:'"Space Mono",monospace', fontWeight:700,
                    fontSize: compact ? 14 : 16, letterSpacing:1,
                    color:'var(--ink)',
                    background:'var(--yellow)', border:'1.5px solid var(--ink)',
                    borderRadius:4, padding:'2px 7px',
                  }}>{m.price}</span>
                </div>
                <div style={{
                  fontFamily:'"Space Mono",monospace',
                  fontSize: compact ? 10 : 11, letterSpacing:1.2,
                  textTransform:'uppercase', color:'var(--muted)', marginBottom:6,
                }}>{m.life}</div>
                <p style={{
                  fontSize: compact ? 13 : 14, color:'var(--muted)', lineHeight:1.45,
                }}>{m.blurb}</p>
              </div>
            </div>
          </Tile>
        ))}
      </div>
    </div>
  );
}

function Step2_Feet({ value, onPick, compact }) {
  return (
    <div>
      <StepHeading
        kicker={'Step 2 of 5 \u00b7 Size'}
        title="Roughly how much fence?"
        subtitle={"A ballpark is fine \u2014 we'll measure exactly during the walkthrough."}
        compact={compact}
      />
      <div style={{
        display:'grid',
        gridTemplateColumns: compact ? '1fr' : 'repeat(2, 1fr)',
        gap: compact ? 12 : 14,
      }}>
        {FEET.map(f => (
          <Tile key={f.key} selected={value === f.key} onClick={() => onPick(f.key)} minH={compact ? 72 : 92}>
            <div style={{ padding: compact ? '14px 18px' : '18px 22px' }}>
              <div style={{
                fontFamily:'"Bagel Fat One",sans-serif',
                fontSize: compact ? 22 : 26, lineHeight:1.1, marginBottom:4,
              }}>{f.name}</div>
              <div style={{
                fontFamily:'"Space Mono",monospace',
                fontSize: compact ? 11 : 12, letterSpacing:1, color:'var(--muted)',
                textTransform:'uppercase',
              }}>{f.sub}</div>
            </div>
          </Tile>
        ))}
      </div>
    </div>
  );
}

function Step3_Timeline({ value, onPick, compact }) {
  return (
    <div>
      <StepHeading
        kicker={'Step 3 of 5 \u00b7 Timeline'}
        title="When are you looking to install?"
        subtitle={"No pressure \u2014 this just helps us prioritize the right spot on the schedule."}
        compact={compact}
      />
      <div style={{
        display:'grid',
        gridTemplateColumns: compact ? '1fr' : 'repeat(2, 1fr)',
        gap: compact ? 12 : 14,
      }}>
        {TIMELINE.map(t => (
          <Tile key={t.key} selected={value === t.key} onClick={() => onPick(t.key)} minH={compact ? 80 : 100}>
            <div style={{ padding: compact ? '14px 18px' : '18px 22px' }}>
              <div style={{
                display:'flex', alignItems:'baseline', gap:10, flexWrap:'wrap',
                marginBottom:4,
              }}>
                <span style={{
                  fontFamily:'"Bagel Fat One",sans-serif',
                  fontSize: compact ? 22 : 26, lineHeight:1.1,
                }}>{t.name}</span>
                {t.tag ? <span style={{
                  background:'var(--ink)', color:'var(--yellow)',
                  fontFamily:'"Space Mono",monospace',
                  fontSize:10, letterSpacing:1.5, textTransform:'uppercase',
                  padding:'2px 7px', borderRadius:3,
                }}>{t.tag}</span> : null}
              </div>
              <div style={{
                fontFamily:'"Space Mono",monospace',
                fontSize: compact ? 11 : 12, letterSpacing:1, color:'var(--muted)',
                textTransform:'uppercase',
              }}>{t.sub}</div>
            </div>
          </Tile>
        ))}
      </div>
    </div>
  );
}

function Step4_Permits({ value, onPick, compact }) {
  return (
    <div>
      <StepHeading
        kicker={'Step 4 of 5 \u00b7 Permits'}
        title="Will you need help with permits?"
        subtitle={"Most South Florida municipalities require one. We can handle the whole process if you'd like us to."}
        compact={compact}
      />
      <div style={{
        display:'grid',
        gridTemplateColumns: compact ? '1fr' : 'repeat(3, 1fr)',
        gap: compact ? 12 : 14,
      }}>
        {PERMITS.map(p => (
          <Tile key={p.key} selected={value === p.key} onClick={() => onPick(p.key)} minH={compact ? 80 : 110}>
            <div style={{ padding: compact ? '14px 18px' : '18px 20px' }}>
              <div style={{
                fontFamily:'"Bagel Fat One",sans-serif',
                fontSize: compact ? 22 : 24, lineHeight:1.1, marginBottom:4,
              }}>{p.name}</div>
              <div style={{
                fontFamily:'"Space Mono",monospace',
                fontSize: compact ? 11 : 12, letterSpacing:1, color:'var(--muted)',
                textTransform:'uppercase',
              }}>{p.sub}</div>
            </div>
          </Tile>
        ))}
      </div>
    </div>
  );
}

function TextField({ label, name, placeholder, value, onChange, type, required, compact }) {
  const t = type || 'text';
  return (
    <div style={{ marginBottom: compact ? 14 : 18 }}>
      <label style={{
        display:'block', fontFamily:'"Space Mono",monospace',
        fontSize: compact ? 11 : 12, letterSpacing:1.5,
        textTransform:'uppercase', color:'var(--ink)', marginBottom:6,
      }}>{label}{required ? <span style={{ color:'var(--yellow-dk)' }}>*</span> : null}</label>
      <input
        type={t} name={name} placeholder={placeholder}
        value={value||''} onChange={e=>onChange(e.target.value)}
        style={{
          width:'100%', padding: compact ? '12px 14px' : '14px 16px',
          fontFamily:'"Quicksand",sans-serif', fontSize: compact ? 15 : 16,
          background:'var(--cream)',
          border:'2px solid var(--ink)', borderRadius:8,
          boxShadow:'3px 3px 0 var(--ink)', boxSizing:'border-box',
          color:'var(--ink)',
          outline:'none',
        }}
        onFocus={e=>e.target.style.boxShadow='5px 5px 0 var(--ink)'}
        onBlur={e=>e.target.style.boxShadow='3px 3px 0 var(--ink)'}
      />
    </div>
  );
}

function ConsentModal({ open, onClose, compact }) {
  React.useEffect(() => {
    if (!open) return;
    const onKey = e => { if (e.key === 'Escape') onClose(); };
    document.addEventListener('keydown', onKey);
    const prevOverflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => {
      document.removeEventListener('keydown', onKey);
      document.body.style.overflow = prevOverflow;
    };
  }, [open, onClose]);

  if (!open) return null;

  return (
    <div onClick={onClose} role="dialog" aria-modal="true" aria-labelledby="hf-q-sms-title" style={{
      position:'fixed', inset:0, background:'rgba(28,37,51,0.7)',
      display:'flex', alignItems:'center', justifyContent:'center',
      padding:16, zIndex:9999,
    }}>
      <div onClick={e=>e.stopPropagation()} style={{
        background:'var(--cream)', border:'2px solid var(--ink)',
        borderRadius:12, boxShadow:'6px 6px 0 var(--ink)',
        maxWidth:540, width:'100%', maxHeight:'85vh', overflowY:'auto',
        padding: compact ? '24px 22px 22px' : '28px 30px 26px',
        position:'relative', boxSizing:'border-box',
      }}>
        <button onClick={onClose} aria-label="Close SMS terms" style={{
          position:'absolute', top:10, right:10,
          width:32, height:32, borderRadius:'50%',
          background:'var(--cream)', border:'2px solid var(--ink)',
          boxShadow:'2px 2px 0 var(--ink)', cursor:'pointer',
          fontFamily:'"Bagel Fat One",sans-serif', fontSize:16, lineHeight:1,
          color:'var(--ink)', padding:0,
        }}>{'×'}</button>
        <div style={{
          fontFamily:'"Space Mono",monospace',
          fontSize:10, letterSpacing:2.5, textTransform:'uppercase',
          color:'var(--muted)', marginBottom:8,
        }}>Messaging consent</div>
        <h3 id="hf-q-sms-title" style={{
          fontFamily:'"Bagel Fat One",sans-serif',
          fontSize: compact ? 22 : 26, lineHeight:1.1, marginBottom:14,
          color:'var(--ink)', marginRight:30,
        }}>SMS Terms</h3>
        <p style={{
          fontSize: compact ? 13 : 14, lineHeight:1.6, color:'var(--ink)',
          fontFamily:'"Quicksand",sans-serif', margin:0,
        }}>
          {"By submitting, you authorize Happy Fence Company LLC to text/call the number above for informational/transactional messages, possibly using automated means. Msg/data rates apply, msg frequency varies. Consent is not a condition of purchase. "}
          <a href="https://www.leadconnectorhq.com/terms2" target="_blank" rel="noopener noreferrer" style={{ color:'var(--ink)', textDecoration:'underline', textUnderlineOffset:2 }}>See terms</a>
          {" and "}
          <a href="https://www.leadconnectorhq.com/privacy-policy" target="_blank" rel="noopener noreferrer" style={{ color:'var(--ink)', textDecoration:'underline', textUnderlineOffset:2 }}>privacy policy</a>
          {". Text HELP for help and STOP to unsubscribe."}
        </p>
      </div>
    </div>
  );
}

function Step5_Contact({ data, onChange, compact }) {
  return (
    <div>
      <StepHeading
        kicker={'Step 5 of 5 \u00b7 Almost done'}
        title="Where should we call you?"
        subtitle={"A rep will call you shortly to grab some details and get a short video of your backyard. From there we'll book a Zoom walkthrough where you get your full quote."}
        compact={compact}
      />
      <div style={{
        display:'grid',
        gridTemplateColumns: compact ? '1fr' : '1fr 1fr', gap: compact ? 0 : 16,
      }}>
        <TextField label="Your name" name="name" placeholder="Jamie Rivera" required compact={compact}
          value={data.name} onChange={v=>onChange('name', v)} />
        <TextField label="Phone" name="phone" placeholder="(305) 555-0131" type="tel" required compact={compact}
          value={data.phone} onChange={v=>onChange('phone', v)} />
        <TextField label="Email" name="email" placeholder="jamie@email.com" type="email" required compact={compact}
          value={data.email} onChange={v=>onChange('email', v)} />
        <TextField label="Address" name="address" placeholder="City, ZIP is fine" required compact={compact}
          value={data.address} onChange={v=>onChange('address', v)} />
      </div>

      <div style={{ marginBottom: compact ? 14 : 18 }}>
        <label style={{
          display:'block', fontFamily:'"Space Mono",monospace',
          fontSize: compact ? 11 : 12, letterSpacing:1.5,
          textTransform:'uppercase', color:'var(--ink)', marginBottom:8,
        }}>Best time to talk</label>
        <div style={{ display:'flex', gap:8, flexWrap:'wrap' }}>
          {['Morning','Afternoon','Evening','Anytime'].map(t => (
            <button key={t} onClick={()=>onChange('time', t)} style={{
              padding: compact ? '8px 12px' : '10px 16px',
              fontFamily:'"Space Mono",monospace', fontSize: compact ? 11 : 12,
              letterSpacing:1, textTransform:'uppercase', cursor:'pointer',
              background: data.time === t ? 'var(--yellow)' : 'var(--cream)',
              border:'2px solid var(--ink)', borderRadius:999,
              boxShadow: data.time === t ? '3px 3px 0 var(--ink)' : '2px 2px 0 var(--ink)',
              color:'var(--ink)',
            }}>{t}</button>
          ))}
        </div>
      </div>

      <div style={{
        border:'2px solid var(--ink)', borderRadius:10,
        padding: compact ? '16px 14px' : '20px 22px',
        background:'var(--blue)',
        boxShadow:'4px 4px 0 var(--ink)',
      }}>
        <div style={{
          fontFamily:'"Space Mono",monospace', fontSize: compact?10:11,
          letterSpacing:1.8, textTransform:'uppercase', color:'var(--ink)',
          marginBottom: compact?10:12,
        }}>What happens next</div>
        <ol style={{
          listStyle:'none', padding:0, margin:0,
          display:'flex', flexDirection:'column', gap: compact?8:10,
        }}>
          {[
            'A rep calls you to grab the basics',
            'You send us a short backyard video',
            'We book a Zoom walkthrough (often within 48 hrs)',
            'You get your full quote on the Zoom',
          ].map((t,i) => (
            <li key={i} style={{
              display:'flex', alignItems:'center', gap:10,
              fontSize: compact?13:14, lineHeight:1.4, color:'var(--ink)',
            }}>
              <span style={{
                width: compact?22:26, height: compact?22:26, flexShrink:0,
                background:'var(--yellow)', border:'1.5px solid var(--ink)',
                borderRadius:'50%', display:'flex', alignItems:'center',
                justifyContent:'center',
                fontFamily:'"Bagel Fat One",sans-serif',
                fontSize: compact?12:14,
              }}>{i+1}</span>
              {t}
            </li>
          ))}
        </ol>
      </div>
    </div>
  );
}

function Step6_Consent({ consent, onConsentToggle, onShowConsentTerms, onSubmit, sending, compact }) {
  return (
    <div>
      <StepHeading
        kicker={'Final step'}
        title="One quick consent"
        subtitle={"A fast compliance step before we call. Check the box to send your info and book your quote."}
        compact={compact}
      />

      <div style={{
        background:'var(--yellow)',
        border:'2px solid var(--ink)',
        borderRadius:10,
        padding: compact ? '16px 16px 14px' : '20px 20px 18px',
        boxShadow:'4px 4px 0 var(--ink)',
      }}>
        <div style={{
          display:'flex', alignItems:'center', gap:8,
          marginBottom: compact ? 12 : 14,
        }}>
          <span style={{
            width:24, height:24,
            background:'var(--ink)', color:'var(--yellow)',
            borderRadius:'50%',
            fontFamily:'"Bagel Fat One",sans-serif', fontSize:13,
            display:'inline-flex', alignItems:'center', justifyContent:'center',
            flexShrink:0,
          }}>!</span>
          <div style={{
            fontFamily:'"Space Mono",monospace',
            fontSize:10, letterSpacing:2, textTransform:'uppercase',
            color:'var(--ink)', fontWeight:700,
          }}>One last thing</div>
        </div>

        <div
          onClick={() => onConsentToggle(!consent)}
          role="button"
          aria-pressed={consent}
          tabIndex={0}
          onKeyDown={e => {
            if (e.key === ' ' || e.key === 'Enter') {
              e.preventDefault();
              onConsentToggle(!consent);
            }
          }}
          style={{
            display:'flex', alignItems:'flex-start', gap:12,
            background:'var(--cream)',
            border:'2px solid var(--ink)', borderRadius:8,
            padding:'12px 14px',
            marginBottom: compact ? 12 : 14,
            cursor:'pointer',
          }}
        >
          <div style={{
            flexShrink:0, width:26, height:26,
            background: consent ? 'var(--ink)' : 'var(--cream)',
            border:'2.5px solid var(--ink)', borderRadius:6,
            boxShadow:'2px 2px 0 var(--ink)', marginTop:1,
            display:'flex', alignItems:'center', justifyContent:'center',
            transition:'background .12s',
          }}>
            {consent ? (
              <svg width="16" height="16" viewBox="0 0 22 22" fill="none" aria-hidden="true">
                <path d="M4 11l5 5 9-11" stroke="#ffdf6b" strokeWidth="3.5" strokeLinecap="round" strokeLinejoin="round"/>
              </svg>
            ) : null}
          </div>
          <div style={{
            fontFamily:'"Quicksand",sans-serif',
            fontSize: compact ? 13 : 14, lineHeight:1.45, color:'var(--ink)',
          }}>
            {"I agree to receive "}<strong>SMS &amp; calls</strong>{" from Happy Fence Company at the number above. "}
            <button
              type="button"
              onClick={e => { e.stopPropagation(); onShowConsentTerms(); }}
              style={{
                background:'none', border:'none', padding:0, margin:0,
                color:'var(--ink)', textDecoration:'underline', textUnderlineOffset:2,
                fontWeight:700, fontFamily:'inherit', fontSize:'inherit',
                whiteSpace:'nowrap', cursor:'pointer',
              }}
            >View SMS Terms</button>
          </div>
        </div>

        <div style={{
          fontFamily:'"Space Mono",monospace',
          fontSize: compact ? 10 : 10.5, letterSpacing:1.3,
          textTransform:'uppercase', color:'var(--ink)',
          textAlign:'center', padding: compact ? '6px 0' : '8px 0',
          marginBottom: compact ? 4 : 6,
          display:'flex', alignItems:'center', justifyContent:'center', gap:6,
        }}>
          {consent ? (
            <React.Fragment>
              <svg width="14" height="14" viewBox="0 0 22 22" fill="none" aria-hidden="true">
                <path d="M4 11l5 5 9-11" stroke="#1c2533" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"/>
              </svg>
              {'All set — click submit below'}
            </React.Fragment>
          ) : '↑ Check the box to unlock submit'}
        </div>

        <button
          onClick={onSubmit}
          disabled={!consent || sending}
          style={{
            width:'100%', padding: compact ? '12px 16px' : '14px 18px',
            fontFamily:'"Bagel Fat One",sans-serif',
            fontSize: compact ? 15 : 17, letterSpacing:0.3,
            background: consent ? 'var(--cream)' : '#e8e0b8',
            border:'2px solid var(--ink)', borderRadius:8,
            boxShadow: consent ? '5px 5px 0 var(--ink)' : '3px 3px 0 var(--ink)',
            color:'var(--ink)', opacity: consent ? 1 : 0.55,
            cursor: (consent && !sending) ? 'pointer' : 'not-allowed',
            transition:'opacity .12s, box-shadow .12s, background .12s',
          }}
        >
          {sending ? 'Sending…' : 'Get a call from a fence expert →'}
        </button>
      </div>
    </div>
  );
}

function SuccessScreen({ compact }) {
  return (
    <div style={{ textAlign:'center', padding: compact ? '20px 8px' : '40px 20px' }}>
      <div style={{
        width: compact ? 68 : 88, height: compact ? 68 : 88,
        background:'var(--yellow)', border:'2px solid var(--ink)', borderRadius:'50%',
        display:'flex', alignItems:'center', justifyContent:'center',
        margin:'0 auto 20px', boxShadow:'5px 5px 0 var(--ink)',
      }}>
        <svg width={compact?30:40} height={compact?30:40} viewBox="0 0 22 22" fill="none">
          <path d="M4 11l5 5 9-11" stroke="#1c2533" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"/>
        </svg>
      </div>
      <h2 style={{
        fontFamily:'"Bagel Fat One",sans-serif',
        fontSize: compact ? 28 : 42, lineHeight:1.05, marginBottom:12,
      }}>You're in good hands.</h2>
      <p style={{
        fontSize: compact ? 14 : 16, color:'var(--muted)', marginBottom:24,
        maxWidth:480, margin:'0 auto 24px', lineHeight:1.55,
      }}>{"A rep will reach out shortly to grab your basics and request a short video of your backyard. Once we have it, we'll book a Zoom walkthrough \u2014 usually within 48 hours \u2014 and you'll get your full quote live on that call."}</p>
      <div style={{
        background:'var(--yellow)', border:'2px solid var(--ink)', borderRadius:10,
        padding: compact ? '10px 14px' : '12px 18px',
        maxWidth: 360, margin:'0 auto 22px',
        boxShadow:'4px 4px 0 var(--ink)',
        fontFamily:'"Quicksand",sans-serif',
      }}>
        <div style={{
          fontFamily:'"Space Mono",monospace', fontSize:10, letterSpacing:2,
          textTransform:'uppercase', color:'var(--ink)', marginBottom:4,
        }}>Don't want to wait?</div>
        <a href="tel:+17868826056" style={{
          fontFamily:'"Bagel Fat One",sans-serif', fontSize: compact ? 22 : 26,
          color:'var(--ink)', textDecoration:'none', letterSpacing:.5, lineHeight:1.05,
          display:'inline-block',
        }}>Call (786) 882-6056</a>
      </div>
      <div style={{
        display:'inline-flex', flexWrap:'wrap', gap:8, justifyContent:'center',
      }}>
        {['Quote on the Zoom call','$500 off','8/10 founder spots taken'].map(c => (
          <div key={c} style={{
            padding:'6px 12px', border:'2px solid var(--ink)', borderRadius:999,
            background:'var(--cream)', fontFamily:'"Space Mono",monospace',
            fontSize:11, letterSpacing:1,
          }}>{'\u2713 '}{c}</div>
        ))}
      </div>
    </div>
  );
}

function Quiz({ compact }) {
  const isCompact = compact === true;
  const [step, setStep] = React.useState(1);
  const [answers, setAnswers] = React.useState({ material:null, feet:null, timeline:null, permits:null, contact:{} });
  const [submitted, setSubmitted] = React.useState(false);
  const [sending, setSending] = React.useState(false);
  const [consent, setConsent] = React.useState(false);
  const [consentModalOpen, setConsentModalOpen] = React.useState(false);

  const setContact = (k, v) => setAnswers(a => ({ ...a, contact: { ...a.contact, [k]: v } }));

  const contactReady = Boolean(
    answers.contact.name
  ) && Boolean(
    answers.contact.phone
  ) && Boolean(
    answers.contact.email
  ) && Boolean(
    answers.contact.address
  );

  const canAdvance = ({
    1: answers.material,
    2: answers.feet,
    3: answers.timeline,
    4: answers.permits,
    5: contactReady,
    6: consent,
  })[step];

  const buildPayload = () => {
    const materialMap = Object.fromEntries(MATERIALS.map(m => [m.key, m.name]));
    const feetMap     = Object.fromEntries(FEET.map(f => [f.key, f.name]));
    const timelineMap = Object.fromEntries(TIMELINE.map(t => [t.key, t.name]));
    const permitsMap  = Object.fromEntries(PERMITS.map(p => [p.key, p.name]));
    return {
      name:    answers.contact.name    || '',
      phone:   answers.contact.phone   || '',
      email:   answers.contact.email   || '',
      address: answers.contact.address || '',
      best_time_to_call: answers.contact.time || '',
      material: materialMap[answers.material] || '',
      linear_feet: feetMap[answers.feet] || '',
      timeline: timelineMap[answers.timeline] || '',
      permits: permitsMap[answers.permits] || '',
      material_key: answers.material,
      feet_key: answers.feet,
      timeline_key: answers.timeline,
      permits_key: answers.permits,
      source: 'happyfencecompany.com /get-a-quote/',
      submitted_at: new Date().toISOString(),
      page_url: typeof window !== 'undefined' ? window.location.href : '',
      user_agent: typeof navigator !== 'undefined' ? navigator.userAgent : '',
      // A2P 10DLC / TCPA consent record — keep these so the Zap
      // logs the exact disclosure shown to the user and the time
      // they actively checked the consent box.
      sms_consent: consent ? 'yes' : 'no',
      sms_consent_text: SMS_CONSENT_TEXT,
      sms_consent_at: consent ? new Date().toISOString() : '',
    };
  };

  const submitToZapier = async () => {
    if (!ZAPIER_WEBHOOK_URL) return;
    if (ZAPIER_WEBHOOK_URL.indexOf('PASTE_YOUR_ZAPIER_WEBHOOK_URL_HERE') !== -1) {
      console.warn('Zapier webhook URL not set. Skipping webhook POST.');
      return;
    }
    try {
      setSending(true);
      await fetch(ZAPIER_WEBHOOK_URL, {
        method: 'POST',
        body: JSON.stringify(buildPayload()),
      });
    } catch (e) {
      console.warn('Zapier webhook failed:', e);
    } finally {
      setSending(false);
    }
  };

  const next = async () => {
    if (step < TOTAL) { setStep(s => s + 1); return; }
    if (!canAdvance) return;
    if (!consent) return; // safety — UI also disables the button
    await submitToZapier();
    setSubmitted(true);
  };
  const back = () => setStep(s => Math.max(1, s - 1));

  const autoAdvance = (val, key) => {
    setAnswers(a => ({ ...a, [key]: val }));
    setTimeout(() => setStep(s => Math.min(TOTAL, s + 1)), 260);
  };

  if (submitted) return <SuccessScreen compact={isCompact} />;

  const backDisabled = step === 1 || sending;

  return (
    <div>
      <div style={{ marginBottom: isCompact ? 20 : 28 }}>
        <ProgressBar step={step} compact={isCompact}/>
      </div>

      {step === 1 ? <Step1_Material value={answers.material} onPick={v=>autoAdvance(v,'material')} compact={isCompact}/> : null}
      {step === 2 ? <Step2_Feet     value={answers.feet}     onPick={v=>autoAdvance(v,'feet')}     compact={isCompact}/> : null}
      {step === 3 ? <Step3_Timeline value={answers.timeline} onPick={v=>autoAdvance(v,'timeline')} compact={isCompact}/> : null}
      {step === 4 ? <Step4_Permits  value={answers.permits}  onPick={v=>autoAdvance(v,'permits')}  compact={isCompact}/> : null}
      {step === 5 ? (
        <Step5_Contact
          data={answers.contact}
          onChange={setContact}
          compact={isCompact}
        />
      ) : null}
      {step === 6 ? (
        <Step6_Consent
          consent={consent}
          onConsentToggle={setConsent}
          onShowConsentTerms={() => setConsentModalOpen(true)}
          onSubmit={next}
          sending={sending}
          compact={isCompact}
        />
      ) : null}

      <div style={{
        display:'flex', justifyContent:'space-between', alignItems:'center',
        gap:12, marginTop: isCompact ? 22 : 32, flexWrap:'wrap',
      }}>
        <button onClick={back} disabled={backDisabled} style={{
          padding: isCompact ? '10px 14px' : '12px 18px',
          fontFamily:'"Space Mono",monospace', fontSize: isCompact ? 11 : 12,
          letterSpacing:1.5, textTransform:'uppercase', cursor: step===1?'default':'pointer',
          background:'transparent', border:'2px solid var(--ink)',
          borderRadius:8, boxShadow: step===1 ? 'none' : '3px 3px 0 var(--ink)',
          color:'var(--ink)', opacity: step===1 ? 0.35 : 1,
        }}>{'\u2190 Back'}</button>

        {step === TOTAL ? null : (
          step === 5 ? (
            <button onClick={next} disabled={!canAdvance || sending} style={{
              padding: isCompact ? '12px 18px' : '14px 22px',
              fontFamily:'"Bagel Fat One",sans-serif',
              fontSize: isCompact ? 14 : 16, letterSpacing:0.3,
              cursor: canAdvance && !sending ? 'pointer' : 'not-allowed',
              background: canAdvance ? 'var(--yellow)' : '#e8e0b8',
              border:'2px solid var(--ink)', borderRadius:8,
              boxShadow: canAdvance ? '4px 4px 0 var(--ink)' : '2px 2px 0 var(--ink)',
              color:'var(--ink)', opacity: canAdvance ? 1 : 0.55,
            }}>{'Next \u2192'}</button>
          ) : (
            <div style={{
              fontFamily:'"Space Mono",monospace', fontSize: isCompact ? 10 : 11,
              letterSpacing:1, color:'var(--muted)',
            }}>{'Pick to continue \u2192'}</div>
          )
        )}
      </div>

      <ConsentModal
        open={consentModalOpen}
        onClose={() => setConsentModalOpen(false)}
        compact={isCompact}
      />
    </div>
  );
}

function QuizRoot(){
  const q = '(max-width: 700px)';
  const [compact, setCompact] = React.useState(
    () => typeof window !== 'undefined' && window.matchMedia(q).matches
  );
  React.useEffect(() => {
    const mq = window.matchMedia(q);
    const handler = e => setCompact(e.matches);
    if (mq.addEventListener) {
      mq.addEventListener('change', handler);
    } else {
      mq.addListener(handler);
    }
    return () => {
      if (mq.removeEventListener) {
        mq.removeEventListener('change', handler);
      } else {
        mq.removeListener(handler);
      }
    };
  }, []);
  return <Quiz compact={compact} />;
}

ReactDOM.createRoot(document.getElementById('quiz-root')).render(<QuizRoot />);
