const { useState, useEffect, useRef, useCallback } = React;

// ============ ICONS ============
const Icon = {
  Rain: (p) =>
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <path d="M16 14a4 4 0 1 0-4-7 5 5 0 0 0-9 3.5A4 4 0 0 0 6 14" />
      <line x1="8" y1="17" x2="8" y2="20" />
      <line x1="12" y1="17" x2="12" y2="21" />
      <line x1="16" y1="17" x2="16" y2="20" />
    </svg>,

  Sun: (p) =>
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <circle cx="12" cy="12" r="4" />
      <path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41" />
    </svg>,

  Snow: (p) =>
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <path d="M12 2v20M4 6l16 12M4 18L20 6" />
    </svg>,

  Wind: (p) =>
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <path d="M3 8h10a3 3 0 1 0-3-3" />
      <path d="M3 14h15a3 3 0 1 1-3 3" />
      <path d="M3 11h7" />
    </svg>,

  Cloud: (p) =>
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <path d="M17 18a4 4 0 0 0 0-8 6 6 0 0 0-11.5-1A4.5 4.5 0 0 0 6 18z" />
    </svg>,

  Restaurant: (p) =>
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <path d="M3 2v8a3 3 0 0 0 6 0V2" />
      <line x1="6" y1="10" x2="6" y2="22" />
      <path d="M16 2c-2 0-3 2-3 5s1 5 3 5v10" />
    </svg>,

  Mountain: (p) =>
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <path d="M3 20l6-10 4 6 3-4 5 8z" />
    </svg>,

  Tractor: (p) =>
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <circle cx="6" cy="17" r="4" />
      <circle cx="18" cy="18" r="3" />
      <path d="M10 17l1-7h6l3 5" />
      <path d="M11 10V5h4" />
    </svg>,

  Truck: (p) =>
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <rect x="2" y="6" width="13" height="10" rx="1" />
      <path d="M15 9h4l3 4v3h-7z" />
      <circle cx="7" cy="18" r="2" />
      <circle cx="18" cy="18" r="2" />
    </svg>,

  Ticket: (p) =>
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <path d="M3 8a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v2a2 2 0 0 0 0 4v2a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-2a2 2 0 0 0 0-4z" />
      <line x1="12" y1="6" x2="12" y2="18" strokeDasharray="2 2" />
    </svg>,

  Wave: (p) =>
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <path d="M2 12c2.5 0 2.5-3 5-3s2.5 3 5 3 2.5-3 5-3 2.5 3 5 3" />
      <path d="M2 17c2.5 0 2.5-3 5-3s2.5 3 5 3 2.5-3 5-3 2.5 3 5 3" />
    </svg>,

  Bolt: (p) =>
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <path d="M13 2L4 14h7l-1 8 9-12h-7z" />
    </svg>,

  Check: (p) =>
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <polyline points="20 6 9 17 4 12" />
    </svg>,

  Arrow: (p) =>
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <line x1="5" y1="12" x2="19" y2="12" />
      <polyline points="12 5 19 12 12 19" />
    </svg>,

  Close: (p) =>
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <line x1="18" y1="6" x2="6" y2="18" />
      <line x1="6" y1="6" x2="18" y2="18" />
    </svg>,

  Plus: (p) =>
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <line x1="12" y1="5" x2="12" y2="19" />
      <line x1="5" y1="12" x2="19" y2="12" />
    </svg>,

  Fuel: (p) =>
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <path d="M4 20V5a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v15" />
      <line x1="3" y1="20" x2="15" y2="20" />
      <line x1="5" y1="9" x2="13" y2="9" />
      <path d="M14 8l3 3v6a2 2 0 0 0 2 2 2 2 0 0 0 2-2V8l-3-3" />
    </svg>,

  Egg: (p) =>
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" {...p}>
      <path d="M12 3c-4 0-7 6.5-7 11 0 3.866 3.134 7 7 7s7-3.134 7-7c0-4.5-3-11-7-11z" />
    </svg>

};

// ============ RAIN OVERLAY ============
const Rain = ({ count = 26 }) => {
  const drops = Array.from({ length: count }).map((_, i) => {
    const left = i * 97 % 100;
    const dur = 0.9 + i * 7 % 14 / 10;
    const delay = i * 53 % 100 / 50;
    return <i key={i} style={{ left: `${left}%`, animationDuration: `${dur}s`, animationDelay: `-${delay}s`, opacity: 0.6 + i % 4 / 10 }} />;
  });
  return <div className="raindrops" aria-hidden="true">{drops}</div>;
};

// ============ NAV ============
const Nav = ({ onJoin }) =>
<header className="nav">
    <div className="container nav-inner">
      <a href="#" className="brand" aria-label="Steadycanopy">
        <span className="brand-mark">S</span>
        <span>Steadycanopy</span>
      </a>
      <nav className="nav-links" aria-label="Primary">
        <a href="#how">How it works</a>
        <a href="#who">Who it's for</a>
        <a href="#examples">Examples</a>
        <a href="#faq">FAQ</a>
        <a href="/fuel">Fuel</a>
      </nav>
      <button className="btn btn-primary btn-sm" onClick={onJoin}>
        Join waitlist
      </button>
    </div>
  </header>;


// ============ HERO ============
const Hero = ({ onJoin }) =>
<section className="hero">
    <Rain count={22} />
    <div className="container" style={{ position: 'relative', zIndex: 1 }}>
      <div className="hero-grid">
        <div>
          <span className="eyebrow">Built for weather-sensitive businesses</span>
          <h1 className="display mega" style={{ marginTop: 22 }}>
            Bad weather shouldn't&nbsp;ruin your month.
          </h1>
          <p className="lede">
            Steadycanopy pays you when the rain, cold, or heat shows up uninvited.
            Pick the kind of weather that hurts sales, set a budget, and get paid the day the threshold is met. No claims. No paperwork.
          </p>
          <div className="hero-ctas">
            <button className="btn btn-primary" onClick={onJoin}>
              Join the waitlist
              <Icon.Arrow style={{ width: 16, height: 16 }} />
            </button>
            <a href="#how" className="btn btn-secondary">See how it works</a>
          </div>
          <div className="hero-meta">
            <span>Available nationwide.</span>
            <span aria-hidden="true" style={{ width: 4, height: 4, borderRadius: 999, background: 'var(--mute)' }} />
            <span>Early access opens this fall.</span>
          </div>
        </div>

        <div className="hero-art">
          <div className="rain-bg" aria-hidden="true" />
          <ProtCard />
        </div>
      </div>
    </div>
  </section>;


// signature hero card — the "protection picker"
const ProtCard = () =>
<div className="prot-card">
    <div className="prot-head">
      <div className="prot-head-main">
        <div className="prot-kicker">Sample protection</div>
        <div className="prot-title">Wet month protection</div>
        <div className="prot-sub">Nov 2026</div>
      </div>
      <span className="badge"><span className="dot" />Live</span>
    </div>

    <div className="prot-amount">
      <div className="trigger">
        If rainfall in San Francisco is <span className="b">≥ 6"</span> in November
      </div>
      <div className="payout-label">You get</div>
      <div className="num">$1,800</div>
      <div className="footnote">paid within hours — no claims, no inspections</div>
    </div>

    <div className="prot-row" style={{ marginTop: 6 }}>
      <span className="k">Cost for the month</span>
      <span className="v">$214</span>
    </div>
    <div className="prot-row">
      <span className="k">Measured by</span>
      <span className="v">NOAA — nearest station</span>
    </div>

    <div className="chip-row">
      <span className="chip"><Icon.Rain /> Rain</span>
      <span className="chip"><Icon.Cloud /> Overcast</span>
      <span className="chip"><Icon.Snow /> Cold snap</span>
      <span className="chip"><Icon.Sun /> Heat wave</span>
      <span className="chip"><Icon.Wind /> Wind</span>
    </div>
  </div>;


// ============ WHO IT'S FOR ============
const Who = ({ onJoin }) => {
  const items = [
  {
    icon: <Icon.Restaurant />,
    title: "Patio & rooftop restaurants",
    tag: "Most popular",
    body: "Cover the patio nights you'd lose to a wet month. Funds land in hours \u2014 no claims, no inspections.",
    featured: true
  },
  {
    icon: <Icon.Wave />,
    title: "Waterfront & event venues",
    tag: "Demand-sensitive",
    body: "Cover private events, weddings, and ticketed runs of nights when the forecast turns against you."
  },
  {
    icon: <Icon.Mountain />,
    title: "Ski lodges & resorts",
    tag: "Seasonal protection",
    body: "Get paid when the storm doesn't show up. Backstop the holiday months your season relies on."
  },
  {
    icon: <Icon.Truck />,
    title: "Food trucks & markets",
    tag: "Footfall protection",
    body: "A wet month wrecks the regular route. Lock in your month's revenue before the forecast turns."
  },
  {
    icon: <Icon.Tractor />,
    title: "Farms & u-picks",
    tag: "Season-long cover",
    body: "Hail, drought, an early frost. Choose the trigger that hurts the most and set a budget you can live with."
  },
  {
    icon: <Icon.Ticket />,
    title: "Outdoor events & festivals",
    tag: "Multi-week cover",
    body: "From a festival run to a summer concert series. Cover the gate take when the forecast turns."
  }];

  return (
    <section className="section band-soft" id="who">
      <div className="container">
        <div className="grid-2" style={{ marginBottom: 56 }}>
          <div>
            <span className="eyebrow">Who it's for</span>
            <h2 className="display xl" style={{ marginTop: 18 }}>
              If the weather decides your month, Steadycanopy is for&nbsp;you.
            </h2>
          </div>
          <div>
            <p className="lede">
              Steadycanopy is built for independent operators and small chains across the country — the kind of business
              where the owner or GM can read a forecast and make a decision in five minutes.
            </p>
            <button className="btn btn-secondary mt-24" onClick={onJoin}>
              Get on the list for your category
            </button>
          </div>
        </div>

        <div className="who-grid">
          {items.map((it, i) =>
          <div key={i} className={`who-card${it.featured ? ' featured' : ''}`}>
              <div className="who-icon">{it.icon}</div>
              <h3>{it.title}</h3>
              <p>{it.body}</p>
              <div className="who-tag">{it.tag}</div>
            </div>
          )}
        </div>
      </div>
    </section>);

};

// ============ HOW IT WORKS ============
const How = () =>
<section className="section" id="how" style={{ background: 'var(--canvas)' }}>
    <div className="container">
      <div className="center max-680" style={{ margin: '0 auto 64px' }}>
        <span className="eyebrow">How it works</span>
        <h2 className="display xl" style={{ marginTop: 18 }}>
          Three steps. No&nbsp;adjusters.
        </h2>
        <p className="lede" style={{ margin: '24px auto 0' }}>
          Pick the kind of bad weather that hurts your sales. If the threshold trips, money lands in your account that day.
        </p>
      </div>

      <div className="steps-grid">
        {/* Step 1 */}
        <div className="step card-soft">
          <div className="step-num">1</div>
          <div>
            <h3>Choose what you want covered.</h3>
            <p style={{ marginTop: 10 }}>
              Pick a clear, measurable trigger — like "Six inches of rain in November." Pick the month that matters and the budget that's worth it to you.
            </p>
          </div>
          <div className="step-art stack gap-8">
            <div className="step-pill"><span className="k">Trigger</span><span>Rain ≥ 6"</span></div>
            <div className="step-pill"><span className="k">Period</span><span>in Nov 2026</span></div>
            <div className="step-pill"><span className="k">Your cost</span><span style={{ color: 'var(--positive-deep)' }}>$214</span></div>
          </div>
        </div>

        {/* Step 2 */}
        <div className="step card-soft">
          <div className="step-num">2</div>
          <div>
            <h3>The trigger trips. Or it doesn't.</h3>
            <p style={{ marginTop: 10 }}>
              We watch the data — NOAA stations, official sources — automatically. No phone calls, no paperwork, no claims to file.
            </p>
          </div>
          <div className="step-art">
            <div className="step-bar">
              <div className="row"><span data-comment-anchor="row-rainfall-label" style={{ color: 'var(--mute)' }}>November rainfall</span><strong data-comment-anchor="row-rainfall-strong">7.2"</strong></div>
              <div className="track"><div className="fill" /></div>
              <div className="row" style={{ marginTop: 8, color: 'var(--mute)', fontSize: 12 }}>
                <span>Threshold 6"</span><span style={{ color: 'var(--positive-deep)', fontWeight: 700 }}>Trigger met</span>
              </div>
            </div>
          </div>
        </div>

        {/* Step 3 */}
        <div className="step card-soft">
          <div className="step-num">3</div>
          <div>
            <h3>You get paid the same day.</h3>
            <p style={{ marginTop: 10 }}>
              The agreed amount lands in your account within hours of the trigger. No adjuster, no hassles, no questions.
            </p>
          </div>
          <div className="step-art">
            <div className="step-paid">
              <div>
                <div className="lbl">Deposited Nov 23 · 8:14 pm</div>
                <div className="num">+$1,800.00</div>
              </div>
              <Icon.Check style={{ width: 28, height: 28, color: 'var(--primary)' }} />
            </div>
          </div>
        </div>
      </div>
    </div>
  </section>;


// ============ EXAMPLES ============
const Examples = ({ onJoin }) => {
  const cards = [
  { icon: <Icon.Rain />, title: "Wet month protection", sub: "San Francisco \u2014 patio restaurant", cost: "$214", paid: "$1,800", trigger: "\u2265 6\" rainfall in November", prob: "\u224812% implied" },
  { icon: <Icon.Fuel />, title: "Fuel price protection", sub: "Food truck operator", cost: "$185", paid: "$2,000", trigger: "US avg diesel \u2265 $5.20/gal in July", prob: "\u22489% implied" },
  { icon: <Icon.Snow />, title: "Snowless season cover", sub: "Tahoe \u2014 ski lodge", cost: "$3,400", paid: "$22,000", trigger: "Season snowfall \u2264 250 inches", prob: "\u224815% implied" },
  { icon: <Icon.Egg />, title: "Egg price protection", sub: "Diner & bakery operators", cost: "$390", paid: "$2,400", trigger: "Wholesale eggs \u2265 $4.50/doz this quarter", prob: "\u224816% implied" }];

  return (
    <section className="section band-soft" id="examples">
      <div className="container">
        <div className="grid-2" style={{ marginBottom: 56 }}>
          <div>
            <span className="eyebrow">Example protections</span>
            <h2 className="display xl" style={{ marginTop: 18 }}>
              Real triggers, real money, plain&nbsp;English.
            </h2>
          </div>
          <div>
            <p className="lede">
              Every protection comes down to one sentence:
              <em style={{ color: 'var(--ink)', fontStyle: 'normal', fontWeight: 600 }}> "If this happens, you get paid this amount."</em>
              {' '}From rainfall to wholesale prices, here's a sample of what's possible at launch.
            
            </p>
          </div>
        </div>

        <div className="ex-grid">
          {cards.map((c, i) =>
          <article key={i} className="ex-card">
              <div className="ex-head">
                <div className="ex-icon">{c.icon}</div>
                <span className="badge" style={{ background: 'var(--canvas-soft)', color: 'var(--mute)' }}>Sample</span>
              </div>
              <div>
                <div className="ex-title">{c.title}</div>
                <div style={{ color: 'var(--mute)', fontSize: 13, marginTop: 6 }}>{c.sub}</div>
              </div>
              <div style={{ fontSize: 14, color: 'var(--body)', lineHeight: 1.45 }}>
                <strong style={{ color: 'var(--ink)' }}>If: </strong>{c.trigger}
                <div style={{ fontSize: 12, color: 'var(--mute)', marginTop: 4 }}>{c.prob}</div>
              </div>
              <div className="ex-meta">
                <div>
                  <div className="lbl">Cost</div>
                  <div className="val">{c.cost}</div>
                </div>
                <div style={{ textAlign: 'right' }}>
                  <div className="lbl">You get</div>
                  <div className="val" style={{ color: 'var(--positive-deep)' }}>{c.paid}</div>
                </div>
              </div>
            </article>
          )}
        </div>

        <div className="center mt-48">
          <button className="btn btn-primary" onClick={onJoin}>
            Build mine when you launch
            <Icon.Arrow style={{ width: 16, height: 16 }} />
          </button>
        </div>
      </div>
    </section>);

};

// ============ PROOF / VALUE PROPS ============
const Proof = ({ onJoin }) =>
<section className="section">
    <div className="container">
      <div className="proof-grid">
        <div className="proof-cell proof-cta">
          <span className="eyebrow">Why Steady</span>
          <h3>One agreement. One payout. No paperwork.</h3>
          <p>Pick the weather that hurts your sales, set a budget, and let the data do the rest. If the threshold is met, the money lands the same day.</p>
          <button className="btn btn-primary" style={{ alignSelf: 'flex-start', marginTop: 8 }} onClick={onJoin}>
            Reserve my spot
          </button>
        </div>
        <div className="proof-cell">
          <div className="proof-num">Same day</div>
          <div className="proof-lbl">Payout lands the day the threshold is met</div>
        </div>
        <div className="proof-cell">
          <div className="proof-num">5 min</div>
          <div className="proof-lbl">To pick a trigger and set your budget</div>
        </div>
      </div>
    </div>
  </section>;


// ============ FAQ ============
const FAQ = () => {
  const items = [
  {
    q: "Is this insurance?",
    a: "No. Steadycanopy is a parametric protection product \u2014 a clear agreement that pays a fixed amount if a measurable trigger is met. There are no adjusters, no claims, no inspections. We'll always be transparent about how the product is structured."
  },
  {
    q: "How is the payout calculated?",
    a: "You pick the trigger and the amount up front. If the trigger is met by the official data source (e.g. an NOAA station), you receive exactly the amount agreed. No surprises, no negotiation."
  },
  {
    q: "What does it cost?",
    a: "Most monthly protections fall between $50 and $300. The price depends on the size of the payout you want and how likely the trigger is to be met. You always see the cost and the payout side-by-side before you commit."
  },
  {
    q: "How fast do I get paid?",
    a: "Same day the trigger is officially met. Funds typically land in your bank account within hours. No phone calls, no forms."
  },
  {
    q: "How do I get in touch?",
    a: "Drop us a line at hello@steadycanopy.com. We read every message and we'll get back to you within a business day."
  }];

  const [open, setOpen] = useState(0);
  return (
    <section className="section band-soft" id="faq">
      <div className="container">
        <div className="grid-2" style={{ alignItems: 'start', marginBottom: 48 }}>
          <div>
            <span className="eyebrow">Common questions</span>
            <h2 className="display xl" style={{ marginTop: 18 }}>
              Straight answers.
            </h2>
          </div>
          <p className="lede">Still have a question after this? Pop it in the notes field when you join the waitlist and we'll write back.</p>
        </div>
        <div className="faq-list">
          {items.map((it, i) =>
          <div key={i} className={`faq-item${open === i ? ' open' : ''}`}>
              <button className="faq-q" onClick={() => setOpen(open === i ? -1 : i)} aria-expanded={open === i}>
                <span>{it.q}</span>
                <span className="faq-toggle" aria-hidden="true"><Icon.Plus style={{ width: 14, height: 14 }} /></span>
              </button>
              <div className="faq-a" style={{ maxHeight: open === i ? 280 : 0 }}>
                {it.a}
              </div>
            </div>
          )}
        </div>
      </div>
    </section>);

};

// ============ FINAL CTA + FOOTER ============
const FinalCTA = ({ onJoin }) =>
<section className="section band-ink">
    <Rain count={18} />
    <div className="container center" style={{ position: 'relative', zIndex: 1 }}>
      <span className="eyebrow">Get on the list</span>
      <h2 className="display xl" style={{ marginTop: 18, color: 'var(--primary)' }}>
        Steady your month.
      </h2>
      <p className="lede" style={{ margin: '24px auto 0', color: '#b7b9b5' }}>
        We're opening to a small group of operators across the country this fall. Tell us where you are and we'll be in touch when Steadycanopy is live for your category.
      </p>
      <div style={{ marginTop: 36 }}>
        <button className="btn btn-primary" onClick={onJoin}>
          Join the waitlist
          <Icon.Arrow style={{ width: 16, height: 16 }} />
        </button>
      </div>
    </div>
  </section>;


const Footer = () =>
<footer className="footer">
    <div className="container">
      <div className="footer-simple">
        <a href="https://steadycanopy.com" className="brand" style={{ color: 'var(--canvas)' }}>
          <span className="brand-mark">S</span>
          <span style={{ color: 'var(--canvas)' }}>Steadycanopy</span>
        </a>
        <p className="footer-tag">
          Event-based revenue protection for weather-sensitive businesses.
        </p>
        <div className="footer-contact">
          <a href="mailto:hello@steadycanopy.com" className="footer-url">hello@steadycanopy.com</a>
          <a href="https://steadycanopy.com" className="footer-url muted-url">steadycanopy.com</a>
        </div>
      </div>
      <div className="footer-bottom">
        <span>© 2026 Steadycanopy, Inc.</span>
        <span>Parametric protection product. Not insurance.</span>
      </div>
    </div>
  </footer>;


// ============ MODAL ============
const WaitlistModal = ({ open, onClose }) => {
  const [form, setForm] = useState({ name: '', business: '', email: '', notes: '' });
  const [submitting, setSubmitting] = useState(false);
  const [submitted, setSubmitted] = useState(false);
  const [error, setError] = useState('');
  const firstFieldRef = useRef(null);

  // Reset state when modal toggles open
  useEffect(() => {
    if (open) {
      setError('');
      setSubmitted(false);
      setSubmitting(false);
      // focus first field
      setTimeout(() => firstFieldRef.current && firstFieldRef.current.focus(), 60);
      document.body.style.overflow = 'hidden';
    } else {
      document.body.style.overflow = '';
    }
    return () => {document.body.style.overflow = '';};
  }, [open]);

  // Esc to close
  useEffect(() => {
    if (!open) return;
    const onKey = (e) => {
      if (e.key === 'Escape') {
        e.preventDefault();
        onClose();
      }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [open, onClose]);

  const onChange = (k) => (e) => setForm((f) => ({ ...f, [k]: e.target.value }));

  const submit = useCallback(async (e) => {
    if (e && e.preventDefault) e.preventDefault();
    setError('');
    if (!form.name.trim()) {
      setError('Please tell us your name.');
      return;
    }
    if (!form.business.trim()) {
      setError('Please tell us your business name.');
      return;
    }
    if (!form.email || !/^\S+@\S+\.\S+$/.test(form.email)) {
      setError('Please enter a valid email address.');
      return;
    }
    setSubmitting(true);
    try {
      await window.SteadyWaitlist.submitWaitlist({
        source: 'main',
        name: form.name.trim(),
        business: form.business.trim(),
        email: form.email.trim(),
        notes: form.notes.trim(),
      });
      setSubmitted(true);
    } catch (err) {
      setError(window.SteadyWaitlist.SUBMIT_FAILURE_MESSAGE);
    } finally {
      setSubmitting(false);
    }
  }, [form]);

  if (!open) return null;

  return (
    <div
      className="modal-backdrop"
      onClick={(e) => {if (e.target === e.currentTarget) onClose();}}
      role="dialog"
      aria-modal="true"
      aria-labelledby="waitlist-title"
      aria-label="Steadycanopy waitlist">
      
      <div className="modal" role="document">
        <button className="modal-close" onClick={onClose} aria-label="Close">
          <Icon.Close style={{ width: 16, height: 16 }} />
        </button>

        {!submitted ?
        <>
            <span className="eyebrow">Waitlist</span>
            <h3 id="waitlist-title" style={{ marginTop: 12 }}>Reserve early access.</h3>
            <p className="body-md" style={{ marginTop: 8 }}>
              Tell us where you operate. We'll reach out when Steadycanopy opens to your category.
            </p>
            <form className="form-fields" onSubmit={submit} noValidate>
              <div className="field">
                <label htmlFor="wf-name">Your name <span className="req" aria-hidden="true">*</span></label>
                <input
                ref={firstFieldRef}
                id="wf-name" type="text" autoComplete="name" required aria-required="true"
                value={form.name} onChange={onChange('name')}
                placeholder="Maria Chen" />
              
              </div>
              <div className="field">
                <label htmlFor="wf-business">Business name <span className="req" aria-hidden="true">*</span></label>
                <input
                id="wf-business" type="text" autoComplete="organization" required aria-required="true"
                value={form.business} onChange={onChange('business')}
                placeholder="Maple & Vine — Hayes Valley" />
              
              </div>
              <div className="field">
                <label htmlFor="wf-email">Email <span className="req" aria-hidden="true">*</span></label>
                <input
                id="wf-email" type="email" autoComplete="email" inputMode="email" required aria-required="true"
                value={form.email} onChange={onChange('email')}
                placeholder="maria@mapleandvine.com" />
              
              </div>
              <div className="field">
                <label htmlFor="wf-notes">Notes <span style={{ color: 'var(--mute)', fontWeight: 400 }}>(optional)</span></label>
                <textarea
                id="wf-notes"
                value={form.notes} onChange={onChange('notes')}
                placeholder="e.g. November is our biggest revenue month, and rain wrecks our patio bookings." />
              
              </div>
              {error &&
            <div role="alert" style={{ color: 'var(--negative)', fontSize: 13, fontWeight: 600 }}>
                  {window.SteadyWaitlist.renderErrorWithEmail(error)}
                </div>
            }
              <div className="form-actions">
                <button type="submit" className="btn btn-primary" disabled={submitting}>
                  {submitting ? 'Submitting…' : 'Join the waitlist'}
                </button>
                <span className="hint">Press <kbd style={kbd}>Enter</kbd> to submit · <kbd style={kbd}>Esc</kbd> to close</span>
              </div>
            </form>
          </> :

        <div className="success-state">
            <div className="success-check"><Icon.Check style={{ width: 30, height: 30, color: 'var(--ink)' }} /></div>
            <h3>You're on the list.</h3>
            <p className="body-md" style={{ marginTop: 10, maxWidth: 380, marginInline: 'auto' }}>
              Thanks, {form.name.split(' ')[0] || 'friend'}. We'll be in touch when Steadycanopy opens to your category — usually within a couple of weeks.
            </p>
            <button className="btn btn-secondary mt-24" onClick={onClose}>Close</button>
          </div>
        }
      </div>
    </div>);

};

const kbd = {
  fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',
  background: 'var(--canvas-soft)',
  border: '1px solid rgba(14,15,12,0.12)',
  borderRadius: 6,
  padding: '1px 6px',
  fontSize: 11,
  color: 'var(--ink)'
};

// ============ TOP BANNER ============
const Banner = ({ onJoin }) =>
<div className="banner-top">
    <span className="pill">New</span>
    <span>Steadycanopy opens to operators nationwide this fall.</span>
    <button onClick={onJoin} style={{ background: 'none', border: 0, color: 'var(--primary)', fontWeight: 700, cursor: 'pointer', textDecoration: 'underline', textUnderlineOffset: 3 }}>
      Reserve your spot →
    </button>
  </div>;


// ============ APP ============
const App = () => {
  const [modalOpen, setModalOpen] = useState(false);
  const openModal = useCallback(() => setModalOpen(true), []);
  const closeModal = useCallback(() => setModalOpen(false), []);

  return (
    <>
      <Banner onJoin={openModal} />
      <Nav onJoin={openModal} />
      <main>
        <Hero onJoin={openModal} />
        <How />
        <Who onJoin={openModal} />
        <Examples onJoin={openModal} />
        <Proof onJoin={openModal} />
        <FAQ />
        <FinalCTA onJoin={openModal} />
      </main>
      <Footer />
      <WaitlistModal open={modalOpen} onClose={closeModal} />
    </>);

};

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);