// page-contact.jsx
const CCSS = `
.page .ct-grid{ padding:60px 56px 100px; display:grid; grid-template-columns:1.35fr 1fr; gap:64px; align-items:start; }
.page .ct-grid h2{ font-family:'Instrument Serif',serif; font-style:italic; font-size:48px; margin:0 0 18px; }
.page .ct-grid p{ font-size:17px; margin:0 0 18px; max-width:480px; }

/* ESTIMATOR */
.page .est{ background:var(--paper); padding:0; border-radius:10px; border:1px solid var(--rule); overflow:hidden; position:relative; }
.page .est .est-tape{ position:absolute; top:-14px; left:40px; width:90px; height:28px; background:rgba(217,170,87,.55); transform:rotate(-3deg); box-shadow:0 2px 6px rgba(0,0,0,.06); z-index:3; }
.page .est .est-head{ padding:32px 40px 24px; border-bottom:1px dashed var(--rule); display:flex; justify-content:space-between; align-items:flex-end; gap:24px; }
.page .est .est-head h3{ font-family:'Instrument Serif',serif; font-style:italic; font-size:32px; margin:0 0 6px; }
.page .est .est-head .sub{ font-family:'JetBrains Mono',monospace; font-size:11px; letter-spacing:.16em; text-transform:uppercase; color:var(--ink-soft); }
.page .est .est-total{ text-align:right; }
.page .est .est-total .lab{ font-family:'JetBrains Mono',monospace; font-size:10px; letter-spacing:.18em; text-transform:uppercase; color:var(--ink-soft); margin-bottom:4px; }
.page .est .est-total .num{ font-family:'Instrument Serif',serif; font-size:44px; font-weight:500; color:var(--terra); transition:transform .25s; display:inline-block; }
.page .est .est-total .num.bump{ transform:scale(1.08); }
.page .est .est-total .rng{ font-family:'JetBrains Mono',monospace; font-size:11px; color:var(--ink-soft); margin-top:2px; }

.page .est .est-body{ padding:8px 40px 0; }
.page .est .grp{ padding:24px 0; border-bottom:1px dashed var(--rule); }
.page .est .grp:last-child{ border-bottom:none; }
.page .est .grp-head{ display:flex; align-items:baseline; justify-content:space-between; margin-bottom:14px; gap:16px; }
.page .est .grp-head .num-tag{ font-family:'JetBrains Mono',monospace; font-size:10px; letter-spacing:.18em; color:var(--ink-soft); margin-right:10px; }
.page .est .grp-head h4{ font-family:'Instrument Serif',serif; font-style:italic; font-size:22px; margin:0; flex:1; }
.page .est .grp-head .hint{ font-family:'JetBrains Mono',monospace; font-size:10px; letter-spacing:.14em; text-transform:uppercase; color:var(--ink-soft); }

/* radio cards (project type) */
.page .est .opts{ display:grid; grid-template-columns:repeat(3,1fr); gap:10px; }
.page .est .opt{ position:relative; padding:14px 14px 16px; border:1px solid var(--rule); border-radius:6px; background:var(--bg); cursor:pointer; transition:all .15s; }
.page .est .opt:hover{ border-color:var(--ink-soft); }
.page .est .opt.on{ border-color:var(--terra); border-width:2px; padding:13px 13px 15px; background:color-mix(in srgb, var(--terra) 6%, var(--bg)); }
.page .est .opt .ot{ font-family:'Instrument Serif',serif; font-style:italic; font-size:17px; margin:0 0 4px; }
.page .est .opt .od{ font-size:11px; color:var(--ink-soft); margin:0 0 8px; line-height:1.4; }
.page .est .opt .op{ font-family:'JetBrains Mono',monospace; font-size:13px; color:var(--ink); font-weight:500; }
.page .est .opt .check{ position:absolute; top:8px; right:8px; width:14px; height:14px; border-radius:50%; border:1.5px solid var(--rule); background:var(--bg); }
.page .est .opt.on .check{ border-color:var(--terra); background:var(--terra); box-shadow:inset 0 0 0 3px var(--bg); }

/* checkboxes (add-ons) */
.page .est .addons{ display:grid; grid-template-columns:1fr 1fr; gap:10px; }
.page .est .addon{ display:flex; align-items:flex-start; gap:12px; padding:12px 14px; border:1px solid var(--rule); border-radius:6px; background:var(--bg); cursor:pointer; transition:all .15s; }
.page .est .addon:hover{ border-color:var(--ink-soft); }
.page .est .addon.on{ border-color:var(--ink); background:color-mix(in srgb, var(--terra) 5%, var(--bg)); }
.page .est .addon .box{ width:16px; height:16px; border:1.5px solid var(--rule); border-radius:3px; flex:none; margin-top:2px; display:flex; align-items:center; justify-content:center; transition:all .15s; }
.page .est .addon.on .box{ background:var(--ink); border-color:var(--ink); }
.page .est .addon.on .box::after{ content:''; width:8px; height:5px; border-left:2px solid var(--bg); border-bottom:2px solid var(--bg); transform:rotate(-45deg) translate(1px,-1px); }
.page .est .addon .at{ font-size:14px; color:var(--ink); display:block; line-height:1.3; }
.page .est .addon .ad{ font-size:11px; color:var(--ink-soft); margin-top:2px; line-height:1.35; }
.page .est .addon .ap{ font-family:'JetBrains Mono',monospace; font-size:11px; color:var(--ink-soft); margin-left:auto; flex:none; align-self:flex-start; padding-top:2px; }

/* counter (pages) */
.page .est .ctr{ display:flex; align-items:center; gap:18px; padding:14px 18px; border:1px solid var(--rule); border-radius:6px; background:var(--bg); }
.page .est .ctr .ctr-l{ flex:1; }
.page .est .ctr .ctr-l .ct{ font-size:14px; }
.page .est .ctr .ctr-l .cd{ font-size:11px; color:var(--ink-soft); margin-top:2px; }
.page .est .ctr .ctr-c{ display:flex; align-items:center; gap:14px; }
.page .est .ctr button{ width:32px; height:32px; border-radius:50%; border:1px solid var(--ink); background:var(--bg); font-size:18px; line-height:1; cursor:pointer; color:var(--ink); padding:0; transition:all .15s; }
.page .est .ctr button:hover{ background:var(--ink); color:var(--bg); }
.page .est .ctr button:disabled{ opacity:.3; cursor:not-allowed; }
.page .est .ctr .ctr-n{ font-family:'Instrument Serif',serif; font-size:24px; min-width:24px; text-align:center; }

/* segmented (timeline) */
.page .est .seg{ display:grid; grid-template-columns:repeat(3,1fr); gap:8px; }
.page .est .seg .sg{ padding:12px 10px; border:1px solid var(--rule); border-radius:6px; background:var(--bg); cursor:pointer; text-align:center; transition:all .15s; }
.page .est .seg .sg:hover{ border-color:var(--ink-soft); }
.page .est .seg .sg.on{ border-color:var(--ink); background:var(--ink); color:var(--bg); }
.page .est .seg .sg .sgt{ font-size:13px; }
.page .est .seg .sg .sgp{ font-family:'JetBrains Mono',monospace; font-size:10px; opacity:.7; margin-top:2px; }

/* contact small form below */
.page .est .est-foot{ background:color-mix(in srgb, var(--terra) 6%, var(--paper)); padding:28px 40px 32px; border-top:1px dashed var(--rule); }
.page .est .est-foot label{ display:block; font-family:'JetBrains Mono',monospace; font-size:11px; letter-spacing:.16em; text-transform:uppercase; color:var(--ink-soft); margin:0 0 8px; }
.page .est .est-foot input, .page .est .est-foot textarea{ width:100%; padding:12px 14px; font-family:'Manrope',sans-serif; font-size:15px; border:1px solid var(--rule); border-radius:6px; background:var(--bg); color:var(--ink); margin-bottom:16px; box-sizing:border-box; }
.page .est .est-foot textarea{ min-height:90px; resize:vertical; }
.page .est .est-foot .row{ display:grid; grid-template-columns:1fr 1fr; gap:14px; }
.page .est .send-btn{ display:inline-flex; align-items:center; gap:10px; padding:14px 28px; background:var(--ink); color:var(--bg); border:none; border-radius:999px; font-family:'Manrope',sans-serif; font-size:14px; font-weight:600; letter-spacing:.04em; cursor:pointer; transition:transform .15s; }
.page .est .send-btn:hover{ transform:translateY(-1px); }

/* contact info column */
.page .ct-info .it{ padding:22px 0; border-top:1px solid var(--rule); }
.page .ct-info .it:last-child{ border-bottom:1px solid var(--rule); }
.page .ct-info .l{ font-family:'JetBrains Mono',monospace; font-size:11px; letter-spacing:.16em; text-transform:uppercase; color:var(--ink-soft); margin-bottom:6px; }
.page .ct-info .v{ font-family:'Instrument Serif',serif; font-style:italic; font-size:24px; }
.page .ct-info .v a{ color:inherit; text-decoration:underline; text-underline-offset:4px; }
.page .ct-info .est-card{ background:var(--paper); border:1px solid var(--rule); border-radius:8px; padding:24px; margin-top:32px; position:relative; }
.page .ct-info .est-card .lab{ font-family:'JetBrains Mono',monospace; font-size:10px; letter-spacing:.18em; text-transform:uppercase; color:var(--ink-soft); margin-bottom:8px; }
.page .ct-info .est-card .lns{ font-size:13px; line-height:1.7; }
.page .ct-info .est-card .lns .ln{ display:flex; justify-content:space-between; padding:4px 0; border-bottom:1px dotted var(--rule); }
.page .ct-info .est-card .lns .ln:last-child{ border-bottom:none; }
.page .ct-info .est-card .lns .ln .lp{ font-family:'JetBrains Mono',monospace; color:var(--ink-soft); }
.page .ct-info .est-card .lns .ln.tot{ font-family:'Instrument Serif',serif; font-style:italic; font-size:18px; padding-top:10px; margin-top:6px; border-top:1px solid var(--ink); border-bottom:none; }
.page .ct-info .est-card .lns .ln.tot .lp{ font-family:'Instrument Serif',serif; font-style:normal; color:var(--terra); font-size:22px; }
.page .ct-info .empty{ font-family:'Caveat',cursive; color:var(--ink-soft); font-size:18px; padding:8px 0; }

@media (max-width:980px){
  .page .ct-grid{ grid-template-columns:1fr; gap:40px; padding:40px 24px 60px; }
  .page .est .opts, .page .est .addons, .page .est .seg{ grid-template-columns:1fr; }
}
`;

const PROJECT_TYPES = [
  { id:'oneweek', t:'One-Week Site', d:'Squarespace, fixed scope, fast.', p:1800 },
  { id:'custom',  t:'Custom Build',  d:'Designed + coded for you.',       p:5400 },
  { id:'brand',   t:'Brand & Site',  d:'Identity + custom website.',     p:9500 },
];

const ADDONS = [
  { id:'cms',      t:'CMS / editable content', d:'You update text & images yourself.', p:600 },
  { id:'blog',     t:'Journal / blog',         d:'Posts, tags, RSS.',                    p:800 },
  { id:'shop_s',   t:'Small shop (≤10 items)', d:'Stripe checkout, simple catalog.',     p:900,  group:'shop' },
  { id:'shop_m',   t:'Shop (10–50 items)',     d:'Categories, search, variants.',        p:1800, group:'shop' },
  { id:'shop_l',   t:'Shop (50+ items)',       d:'Full e-com, inventory.',              p:3200, group:'shop' },
  { id:'multi',    t:'Multilingual',           d:'EN + 1 additional language.',          p:900 },
  { id:'anim',     t:'Custom animations',      d:'Hover states, scroll moments.',        p:700 },
  { id:'illus',    t:'Custom illustrations',   d:'2–4 spot illustrations.',              p:1200 },
  { id:'copy',     t:'Copywriting help',       d:'Editing pass on your draft.',          p:600 },
  { id:'photo',    t:'Photo direction',        d:'Mood-board + shot list for shoot.',    p:500 },
  { id:'a11y',     t:'Accessibility audit',    d:'WCAG AA review + fixes.',              p:600 },
  { id:'seo',      t:'SEO setup',              d:'Meta, schema, redirects, sitemap.',    p:400 },
];

const TIMELINES = [
  { id:'flex',  t:'Flexible',   d:'8+ weeks',   mult:1.0  },
  { id:'norm',  t:'Standard',   d:'5–8 weeks',  mult:1.0  },
  { id:'rush',  t:'Rush',       d:'≤ 4 weeks',  mult:1.18 },
];

function fmt(n){ return '$' + Math.round(n).toLocaleString('en-US'); }

function ContactPage(){
  const [type, setType] = React.useState('custom');
  const [pages, setPages] = React.useState(6);
  const [addons, setAddons] = React.useState(['cms']);
  const [timeline, setTimeline] = React.useState('norm');
  const [sent, setSent] = React.useState(false);
  const [sending, setSending] = React.useState(false);
  const [bump, setBump] = React.useState(0);
  const [errors, setErrors] = React.useState({});
  const nameRef = React.useRef();
  const emailRef = React.useRef();
  const msgRef = React.useRef();

  function validate(){
    const e = {};
    if (!nameRef.current?.value.trim()) e.name = 'Name is required';
    const email = emailRef.current?.value.trim() || '';
    if (!email) e.email = 'Email is required';
    else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) e.email = 'Please enter a valid email';
    setErrors(e);
    return Object.keys(e).length === 0;
  }

  async function handleSubmit(e){
    e.preventDefault();
    if (!validate()) return;
    setSending(true);
    const name = nameRef.current?.value || '';
    const email = emailRef.current?.value || '';
    const message = msgRef.current?.value || '';
    const estimateStr = fmt(total);

    // Send via PHP mailer
    try {
      await fetch('send.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          name:         name,
          email:        email,
          estimate:     estimateStr,
          project_type: proj.t,
          message:      message || '(no message)',
        })
      });
    } catch(err){ console.warn('Send failed:', err); }

    setSending(false);
    setSent(true);
  }

  const proj = PROJECT_TYPES.find(p => p.id === type) || PROJECT_TYPES[1];
  const includedPages = type === 'oneweek' ? 4 : type === 'custom' ? 6 : 8;
  const extraPages = Math.max(0, pages - includedPages);
  const pagesCost = extraPages * 250;
  const addonsCost = addons.reduce((s, id) => {
    const a = ADDONS.find(x => x.id === id); return s + (a ? a.p : 0);
  }, 0);
  const subtotal = proj.p + pagesCost + addonsCost;
  const tl = TIMELINES.find(t => t.id === timeline) || TIMELINES[1];
  const rushCost = subtotal * (tl.mult - 1);
  const total = subtotal + rushCost;

  React.useEffect(() => { setBump(b => b + 1); }, [type, pages, addons, timeline]);
  const isBumping = bump > 0;

  // shop is single-select within group
  function toggleAddon(a){
    setAddons(prev => {
      const has = prev.includes(a.id);
      if (has) return prev.filter(x => x !== a.id);
      let next = [...prev, a.id];
      if (a.group){
        next = next.filter(id => {
          const o = ADDONS.find(x => x.id === id);
          return o && (id === a.id || o.group !== a.group);
        });
      }
      return next;
    });
  }

  return (
    <PageShell active="contact">
      <style>{CCSS}</style>
      <header className="pghdr">
        <div className="eyebrow">Contact · Booking June 2026</div>
        <h1>Tell me what<br/>you’re <em>building</em>.</h1>
        <p className="lede">Use the estimator below to get a rough number — it’s not a quote, just a friendly ballpark. Real proposals come after we talk.</p>
        <Sticker at={{ bottom: 44, right: 70 }} rot={6} color="olive">replies in ~1 day ✨</Sticker>
        <Arrow at={{ bottom: 80, right: 200 }} rot={20} color="olive" />
        <StarDoodle at={{ top: 24, left: 240 }} rot={12} size={24} color="terra" />
        <Squiggle at={{ bottom: 20, left: 56 }} rot={-3} color="rose" w={100} />
        <Note at={{ top: 60, right: 180 }} rot={-8} mobileHide={true}>no pitch<br/>decks here ✦</Note>
      </header>

      <section className="ct-grid">
        <div className="est">
          <div className="est-tape"></div>
          <div className="est-head">
            <div>
              <h3>Project estimator</h3>
              <div className="sub">~ a friendly ballpark, not a quote ~</div>
            </div>
            <div className="est-total">
              <div className="lab">Estimated total</div>
              <div className={'num' + (isBumping ? ' bump' : '')} key={total}>{fmt(total)}</div>
              <div className="rng">~ {fmt(total * 0.9)} – {fmt(total * 1.15)}</div>
            </div>
          </div>

          <div className="est-body">
            {/* 1. Project type */}
            <div className="grp">
              <div className="grp-head">
                <h4><span className="num-tag">01</span>What are we making?</h4>
                <span className="hint">Pick one</span>
              </div>
              <div className="opts">
                {PROJECT_TYPES.map(p => (
                  <div key={p.id} className={'opt' + (type===p.id ? ' on' : '')} onClick={()=>setType(p.id)}>
                    <div className="check"></div>
                    <div className="ot">{p.t}</div>
                    <div className="od">{p.d}</div>
                    <div className="op">{fmt(p.p)}</div>
                  </div>
                ))}
              </div>
            </div>

            {/* 2. Pages */}
            <div className="grp">
              <div className="grp-head">
                <h4><span className="num-tag">02</span>How many pages?</h4>
                <span className="hint">{includedPages} included · +$250 each</span>
              </div>
              <div className="ctr">
                <div className="ctr-l">
                  <div className="ct">{pages} {pages === 1 ? 'page' : 'pages'}</div>
                  <div className="cd">{extraPages > 0 ? `${extraPages} extra × $250 = ${fmt(pagesCost)}` : `Within the ${includedPages} included`}</div>
                </div>
                <div className="ctr-c">
                  <button onClick={()=>setPages(p => Math.max(1, p-1))} disabled={pages<=1}>−</button>
                  <div className="ctr-n">{pages}</div>
                  <button onClick={()=>setPages(p => Math.min(40, p+1))} disabled={pages>=40}>+</button>
                </div>
              </div>
            </div>

            {/* 3. Add-ons */}
            <div className="grp">
              <div className="grp-head">
                <h4><span className="num-tag">03</span>Anything extra?</h4>
                <span className="hint">Pick any · shop options are mutually exclusive</span>
              </div>
              <div className="addons">
                {ADDONS.map(a => (
                  <div key={a.id} className={'addon' + (addons.includes(a.id) ? ' on' : '')} onClick={()=>toggleAddon(a)}>
                    <div className="box"></div>
                    <div style={{flex:1}}>
                      <span className="at">{a.t}</span>
                      <div className="ad">{a.d}</div>
                    </div>
                    <span className="ap">+{fmt(a.p)}</span>
                  </div>
                ))}
              </div>
            </div>

            {/* 4. Timeline */}
            <div className="grp">
              <div className="grp-head">
                <h4><span className="num-tag">04</span>How urgent?</h4>
                <span className="hint">Rush adds ~18%</span>
              </div>
              <div className="seg">
                {TIMELINES.map(t => (
                  <div key={t.id} className={'sg' + (timeline===t.id ? ' on' : '')} onClick={()=>setTimeline(t.id)}>
                    <div className="sgt">{t.t} <span style={{opacity:.6}}>· {t.d}</span></div>
                    <div className="sgp">{t.mult > 1 ? `+${Math.round((t.mult-1)*100)}%` : 'no rush fee'}</div>
                  </div>
                ))}
              </div>
            </div>
          </div>

          {/* contact form */}
          {sent ? (
            <div className="est-foot" style={{textAlign:'center', padding:'48px 40px'}}>
              <div style={{fontFamily:'Caveat,cursive',fontSize:48,color:'var(--terra)',marginBottom:8}}>thanks! ✨</div>
              <p style={{margin:0,fontSize:15}}>Got it — your estimate of <strong>{fmt(total)}</strong> is on its way. I’ll be in touch within a day.</p>
            </div>
          ) : (
            <form className="est-foot" onSubmit={handleSubmit} noValidate>
              <div className="row">
                <div>
                  <label htmlFor="ct-name">Name *</label>
                  <input id="ct-name" ref={nameRef} required placeholder="Lauren Park" aria-required="true"
                    style={errors.name ? {borderColor:'var(--terra)'} : {}}
                    onChange={() => errors.name && setErrors(p => ({...p, name: null}))}/>
                  {errors.name && <div style={{color:'var(--terra)',fontSize:12,marginTop:4}}>{errors.name}</div>}
                </div>
                <div>
                  <label htmlFor="ct-email">Email *</label>
                  <input id="ct-email" ref={emailRef} required type="email" placeholder="lauren@beautygrass.co" aria-required="true"
                    style={errors.email ? {borderColor:'var(--terra)'} : {}}
                    onChange={() => errors.email && setErrors(p => ({...p, email: null}))}/>
                  {errors.email && <div style={{color:'var(--terra)',fontSize:12,marginTop:4}}>{errors.email}</div>}
                </div>
              </div>
              <label htmlFor="ct-msg">A few sentences about it (optional)</label>
              <textarea id="ct-msg" ref={msgRef} placeholder="What you're working on, when you'd like to launch, anything else…"/>
              <button className="send-btn" type="submit" disabled={sending} aria-busy={sending}>{sending ? 'Sending… ✦' : 'Send my estimate ↗'}</button>
            </form>
          )}
        </div>

        <aside className="ct-info">
          <h2>Or just say <em>hi</em>.</h2>
          <Squiggle at={{ top: 58, left: 0 }} rot={2} color="terra" w={80} />
          <p>The form is the fastest way to reach me. Slow Mondays, but otherwise within a day.</p>
          <div className="it"><div className="l">Located in</div><div className="v">Los Angeles, CA</div></div>
          <div className="it"><div className="l">Hours</div><div className="v">Mon–Thu, 9 – 5 PT</div></div>
          <div className="it"><div className="l">Currently</div><div className="v">Booking June 2026</div></div>

          <div className="est-card">
            <div className="lab">Your estimate so far</div>
            <div className="lns">
              <div className="ln"><span>{proj.t}</span><span className="lp">{fmt(proj.p)}</span></div>
              {extraPages > 0 && <div className="ln"><span>{extraPages} extra page{extraPages>1?'s':''}</span><span className="lp">{fmt(pagesCost)}</span></div>}
              {addons.map(id => {
                const a = ADDONS.find(x => x.id === id);
                if (!a) return null;
                return <div key={id} className="ln"><span>{a.t}</span><span className="lp">+{fmt(a.p)}</span></div>;
              })}
              {tl.mult > 1 && <div className="ln"><span>Rush ({tl.t})</span><span className="lp">+{fmt(rushCost)}</span></div>}
              <div className="ln tot"><span>Total</span><span className="lp">{fmt(total)}</span></div>
            </div>
          </div>
        </aside>
      </section>
    </PageShell>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<ContactPage/>);
