// Additional pages: Beta, About, Manifesto, Roadmap, Press, Contact, Help, Terms, Privacy, Playbook, FieldGuide
// Plus the floating SupportChat widget.
// Exposes: window.PAGES, window.SupportChat, window.PageNav, window.PageFooter

const { useState: usePg, useEffect: useEpg, useRef: useRpg } = React;

// ---- shared bits used by sub-pages ----
const pageWrap = { maxWidth: 1100, margin: '0 auto' }; // padding via .page-pad class (responsive)
const pageHeadKicker = { color: 'var(--mute)' };
const pageH1 = { fontFamily: 'var(--serif)', fontSize: 'clamp(56px, 7vw, 110px)', lineHeight: 0.95, letterSpacing: '-0.03em', margin: '12px 0 0' };
const proseP = { fontSize: 17, lineHeight: 1.7, color: 'var(--mute-2)', maxWidth: 720 };
const proseH2 = { fontFamily: 'var(--serif)', fontSize: 36, fontWeight: 400, margin: '48px 0 12px', letterSpacing: '-0.01em' };
const proseH3 = { fontFamily: 'var(--serif)', fontSize: 24, fontWeight: 400, margin: '32px 0 8px' };
const hairLine = { border: 0, borderTop: '1px solid var(--hair)', margin: '32px 0' };

function PageHero({ kicker, title, sub }) {
  return (
    <header style={{ borderBottom: '1px solid var(--ink)', paddingBottom: 48, marginBottom: 32 }}>
      <div className="mono" style={pageHeadKicker}>{kicker}</div>
      <h1 style={pageH1}>{title}</h1>
      {sub && <p style={{ ...proseP, marginTop: 24 }}>{sub}</p>}
    </header>
  );
}

// =============== BETA PROGRAM (full detail) ===============
function BetaPage({ go }) {
  return (
    <div className="page-pad" style={pageWrap}>
      <PageHero
        kicker="THE BETA PROGRAM · COHORT 03 · MAY 2026"
        title={<>The beta is small <span style={{ fontStyle: 'italic' }}>on purpose.</span></>}
        sub="We're inviting a few hundred small business owners at a time so we can hand-tune Caddie to real catalogs, real audiences, and real budgets. Here's exactly how the program works, what you get, and what we ask in return."
      />

      <section>
        <h2 style={proseH2}>What you get</h2>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 0, border: '1px solid var(--ink)', borderRadius: 12, overflow: 'hidden', marginTop: 16 }}>
          {[
            ['Free during beta', 'Unlimited campaigns, all integrations, every feature unlocked. No card on file.'],
            ['6 months free, after', 'When paid plans launch, beta members get 6 months on the highest tier — gratis.'],
            ['Founder-led onboarding', 'Optional 25-minute setup call with one of us — or a written walkthrough if you\u2019d rather skip the call. We help you connect accounts and tune your voice.'],
            ['Direct line', 'A personal messenger with the team. Bug reports get fixed in days, not quarters.'],
            ['Roadmap input', 'Vote on what we build next. Feature requests from beta users skip the queue.'],
            ['Founding-member badge', 'Permanent badge in-app and in your account history. A small thank-you for the early bet.'],
          ].map(([t, b], i) => (
            <div key={t} style={{
              padding: '22px 24px',
              borderRight: (i % 2 === 0) ? '1px solid var(--hair)' : 'none',
              borderTop: i > 1 ? '1px solid var(--hair)' : 'none',
              minHeight: 120
            }}>
              <div style={{ fontFamily: 'var(--serif)', fontSize: 22, marginBottom: 6 }}>{t}</div>
              <div style={{ fontSize: 14, lineHeight: 1.55, color: 'var(--mute-2)' }}>{b}</div>
            </div>
          ))}
        </div>
      </section>

      <section>
        <h2 style={proseH2}>What we ask in return</h2>
        <ol style={{ listStyle: 'none', padding: 0, margin: 0, display: 'grid', gap: 12, counterReset: 'beta' }}>
          {[
            ['Use it.', 'Run at least one real campaign in your first 30 days. Caddie gets smarter the more it sees.'],
            ['Tell us when it\'s wrong.', 'A one-line bug report or a quick screenshot in chat. We don\'t need polished feedback.'],
            ['One short call a month.', '15 minutes. We watch you work. You complain. We take notes.'],
            ['Patience with the rough edges.', 'This is a beta. Things will occasionally look weird, move slowly, or need a refresh.'],
          ].map(([t, b], i) => (
            <li key={t} style={{ display: 'grid', gridTemplateColumns: '64px 1fr', gap: 20, padding: '18px 0', borderTop: '1px solid var(--hair)' }}>
              <span style={{ fontFamily: 'var(--serif)', fontSize: 40, lineHeight: 1, color: 'var(--mute)' }}>0{i+1}</span>
              <div>
                <div style={{ fontFamily: 'var(--serif)', fontSize: 24 }}>{t}</div>
                <div style={{ fontSize: 14.5, lineHeight: 1.6, color: 'var(--mute-2)', marginTop: 4 }}>{b}</div>
              </div>
            </li>
          ))}
        </ol>
      </section>

      <section>
        <h2 style={proseH2}>The timeline</h2>
        <div style={{ borderTop: '1px solid var(--ink)', borderBottom: '1px solid var(--ink)', display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)' }}>
          {[
            ['MAY 2026', 'Cohort 03 invites', 'You apply this month. Invites go out in waves of ~75 every two weeks.'],
            ['JUN — AUG', 'Hand-tuning', 'You run real campaigns. We ship updates weekly based on what you trip over.'],
            ['SEPT 2026', 'Cohort 04 opens', 'A wider invite round. Beta members help us spot rough edges before then.'],
            ['LATE 2026', 'Paid plans launch', 'Pricing goes live ($20–$50/mo). Beta members lock in 6 months free, automatically.'],
          ].map(([d, t, b], i) => (
            <div key={d} style={{ padding: '28px 22px', borderRight: i < 3 ? '1px solid var(--hair)' : 'none' }}>
              <div className="mono" style={{ color: 'var(--mute)' }}>{d}</div>
              <div style={{ fontFamily: 'var(--serif)', fontSize: 22, margin: '6px 0 6px' }}>{t}</div>
              <div style={{ fontSize: 13, lineHeight: 1.55, color: 'var(--mute-2)' }}>{b}</div>
            </div>
          ))}
        </div>
      </section>

      <section>
        <h2 style={proseH2}>Eligibility</h2>
        <p style={proseP}>We're optimizing the beta for businesses where Caddie can actually move the needle in 30 days. Right now that means:</p>
        <ul style={{ ...proseP, paddingLeft: 20, marginTop: 12 }}>
          <li>Small business or solo operator (1 to ~20 people)</li>
          <li>Selling something — physical product, digital product, service, or local</li>
          <li>At least one active social or email channel</li>
          <li>English-speaking markets for now (more languages by Q4 2026)</li>
        </ul>
      </section>

      <section>
        <h2 style={proseH2}>FAQ</h2>
        <BetaFAQ />
      </section>

      <section style={{ marginTop: 64, background: 'var(--ink)', color: 'var(--paper)', padding: '48px 40px', borderRadius: 14, display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 40, flexWrap: 'wrap' }}>
        <div>
          <div className="mono" style={{ opacity: 0.6 }}>READY?</div>
          <div style={{ fontFamily: 'var(--serif)', fontSize: 44, lineHeight: 1.05, marginTop: 6 }}>Apply for cohort 03.</div>
        </div>
        <button onClick={() => go('home', '#waitlist')} style={{
          background: 'var(--paper)', color: 'var(--ink)', border: 'none',
          padding: '16px 26px', borderRadius: 999, fontSize: 14, fontWeight: 500, cursor: 'pointer',
          display: 'inline-flex', alignItems: 'center', gap: 8
        }}>
          Apply to the beta <Icon name="arrow" size={16}/>
        </button>
      </section>
    </div>
  );
}

function BetaFAQ() {
  const items = [
    ['Do I need a credit card?', 'No. Beta is free. We won\'t ask for billing info until paid plans launch — and beta members get 6 months free past that.'],
    ['What if I drop out?', 'No problem. Cancel anytime in-app. We keep your data for 30 days in case you change your mind, then delete it.'],
    ['Can I invite a teammate?', 'Yes — beta accounts include up to 3 seats. Add a designer, a VA, or your co-founder.'],
    ['Will you charge me retroactively?', 'No. Whatever you used during beta is free, full stop. Year one of paid plans is also free for beta members.'],
    ['How do I get in faster?', 'Refer another small business owner. Each accepted referral bumps you up the queue.'],
  ];
  const [open, setOpen] = usePg(0);
  return (
    <div style={{ borderTop: '1px solid var(--ink)' }}>
      {items.map(([q, a], i) => {
        const isOpen = open === i;
        return (
          <div key={q} style={{ borderBottom: '1px solid var(--hair)' }}>
            <button onClick={() => setOpen(isOpen ? -1 : i)} style={{
              width: '100%', display: 'flex', justifyContent: 'space-between', alignItems: 'center',
              padding: '18px 4px', background: 'none', border: 'none', cursor: 'pointer',
              fontFamily: 'inherit', textAlign: 'left'
            }}>
              <span style={{ fontFamily: 'var(--serif)', fontSize: 22 }}>{q}</span>
              <span style={{ fontFamily: 'var(--serif)', fontSize: 28, color: 'var(--mute)' }}>{isOpen ? '−' : '+'}</span>
            </button>
            {isOpen && (
              <div style={{ padding: '0 4px 22px', maxWidth: 720, fontSize: 15, lineHeight: 1.6, color: 'var(--mute-2)' }}>{a}</div>
            )}
          </div>
        );
      })}
    </div>
  );
}

// =============== SIMPLE STATIC PAGES ===============
function AboutPage() {
  return (
    <div className="page-pad" style={pageWrap}>
      <PageHero
        kicker="ABOUT"
        title={<>Built by one person <span style={{ fontStyle: 'italic' }}>who got tired</span> of watching small businesses get crushed by marketing.</>}
        sub="Campaign Caddie started as a side project to help a friend save her bakery. She didn't need analytics — she needed someone to tell her what to post on Tuesday. So I built that."
      />
      <h2 style={proseH2}>Our story</h2>
      <p style={proseP}>Most marketing software is built for marketers. The dashboards, the funnels, the "attribution windows" — they assume you already know what to do. The small business owners we know aren't marketers. They're bakers, jewelers, tutors, designers, plumbers. They start the day with a list of forty things and marketing is somewhere on it, sometimes.</p>
      <p style={{ ...proseP, marginTop: 16 }}>Caddie isn't another dashboard. It's a quiet, capable assistant that does the marketing while you do the work that made you start a business in the first place.</p>

      <h2 style={proseH2}>The team</h2>
      <div style={{ marginTop: 16, maxWidth: 540 }}>
        {[
          ['David', 'Founder', 'Built Campaign Caddie solo after watching too many small business owners drown in marketing tools designed for someone else. Writes the code, answers the support emails, and personally onboards every beta member.'],
        ].map(([n, r, b]) => (
          <div key={n} style={{ border: '1px solid var(--hair)', borderRadius: 12, padding: 24 }}>
            <div style={{ width: 64, height: 64, borderRadius: 999, background: 'var(--ink)', color: 'var(--paper)', display: 'grid', placeItems: 'center', fontFamily: 'var(--serif)', fontSize: 22, marginBottom: 16 }}>
              {n.split(' ').map(s => s[0]).join('')}
            </div>
            <div style={{ fontFamily: 'var(--serif)', fontSize: 24 }}>{n}</div>
            <div className="mono" style={{ color: 'var(--mute)', marginTop: 4 }}>{r.toUpperCase()}</div>
            <p style={{ fontSize: 14, lineHeight: 1.55, color: 'var(--mute-2)', marginTop: 12 }}>{b}</p>
          </div>
        ))}
      </div>

      <h2 style={proseH2}>What we believe</h2>
      <ul style={{ listStyle: 'none', padding: 0, margin: 0 }}>
        {[
          ['Software should do the work, not show the work.', 'A great tool finishes things. It doesn\'t hand you another to-do list dressed up as a chart.'],
          ['Small businesses are the economy.', 'They deserve software priced and designed for them, not enterprise hand-me-downs.'],
          ['Less is more, but only if it\'s the right less.', 'We say no to features that look impressive but don\'t move the needle on a Tuesday.'],
        ].map(([t, b], i) => (
          <li key={t} style={{ display: 'grid', gridTemplateColumns: '40px 1fr', gap: 20, padding: '18px 0', borderTop: i ? '1px solid var(--hair)' : '1px solid var(--ink)' }}>
            <span style={{ fontFamily: 'var(--serif)', fontSize: 28, color: 'var(--mute)' }}>0{i+1}</span>
            <div>
              <div style={{ fontFamily: 'var(--serif)', fontSize: 24 }}>{t}</div>
              <div style={{ fontSize: 14.5, lineHeight: 1.6, color: 'var(--mute-2)', marginTop: 4 }}>{b}</div>
            </div>
          </li>
        ))}
      </ul>
    </div>
  );
}

function ManifestoPage() {
  return (
    <div className="page-pad" style={pageWrap}>
      <PageHero
        kicker="MANIFESTO"
        title={<>Marketing should <span style={{ fontStyle: 'italic' }}>quiet down.</span></>}
      />
      <div style={{ fontFamily: 'var(--serif)', fontSize: 26, lineHeight: 1.5, letterSpacing: '-0.005em' }}>
        <p>The best marketing for a small business doesn't look like marketing. It looks like a baker showing you how she folds croissants on Tuesday morning. It looks like a jeweler answering your DM at 11 PM with a real opinion.</p>
        <p>For two decades, the tools small businesses can afford have asked them to <em>act like</em> Coca-Cola. Run funnels. Watch dashboards. A/B test. Most of it is noise.</p>
        <p>Campaign Caddie is built on a quieter premise: you already have the taste. You already know your customers. You don't need another graph. You need someone who can write the caption, schedule the post, run the boost, and tell you it's done.</p>
        <p>That's it. That's the whole thing. Software that handles the marketing so you can keep doing the thing that made the business worth marketing in the first place.</p>
      </div>
    </div>
  );
}

function RoadmapPage() {
  const items = [
    { q: 'Q2 2026', s: 'Live', list: ['Cohort 03 of beta opens', 'Video Reach Tracker (v1)', 'Klaviyo + Shopify integrations', 'Founder onboarding calls'] },
    { q: 'Q3 2026', s: 'Building', list: ['TikTok integration', 'Auto-send email engine', 'Campaign cost estimator (v2)', 'Mobile companion app'] },
    { q: 'Q4 2026', s: 'Planned', list: ['Paid plans launch ($20–$50/mo)', 'Google Ads integration', 'Multi-language support', 'Team seats (3+)'] },
    { q: 'Q1 2027', s: 'Wishlist', list: ['Pinterest + YouTube Shorts', 'White-label for agencies', 'Affiliate / referral marketing module', 'Voice memos → captions'] },
  ];
  return (
    <div className="page-pad" style={pageWrap}>
      <PageHero kicker="ROADMAP" title="What we're building, in the open." sub="The beta moves fast. This is what's live, what's next, and what's on the wish list. Beta members can vote on priorities — your votes are why the order shifts month to month." />
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
        {items.map(it => {
          const live = it.s === 'Live';
          return (
            <div key={it.q} style={{
              border: '1px solid var(--ink)', borderRadius: 12, padding: 24,
              background: live ? 'var(--ink)' : 'transparent', color: live ? 'var(--paper)' : 'var(--ink)'
            }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
                <div className="mono" style={{ opacity: live ? 0.7 : 0.55 }}>{it.q}</div>
                <span className="mono" style={{
                  padding: '3px 8px', borderRadius: 3, fontSize: 10,
                  border: live ? '1px solid var(--paper)' : '1px solid var(--ink)'
                }}>{it.s.toUpperCase()}</span>
              </div>
              <ul style={{ listStyle: 'none', padding: 0, margin: '20px 0 0', display: 'flex', flexDirection: 'column', gap: 10 }}>
                {it.list.map(x => (
                  <li key={x} style={{ display: 'flex', gap: 10, fontSize: 14 }}>
                    <Icon name="check" size={14} stroke={2}/> <span>{x}</span>
                  </li>
                ))}
              </ul>
            </div>
          );
        })}
      </div>
    </div>
  );
}

function PressPage() {
  return (
    <div className="page-pad" style={pageWrap}>
      <PageHero kicker="PRESS KIT" title="For writers, podcasters, and curious people." sub="Everything you need to write about, talk about, or link to Campaign Caddie. Email press@campaigncaddie.com for interviews, demos, or specific assets." />
      <h2 style={proseH2}>The short version</h2>
      <p style={proseP}>Campaign Caddie is an AI marketing assistant built for small business owners — the founder of one, the team of three, the local shop. It plans campaigns, drafts the copy, schedules the posts, and tells you what to do next. Founded 2025. Currently in invite-only beta.</p>

      <h2 style={proseH2}>Boilerplate</h2>
      <pre style={{ background: 'var(--paper-warm)', border: '1px solid var(--hair)', borderRadius: 8, padding: 20, fontSize: 13, lineHeight: 1.6, whiteSpace: 'pre-wrap', fontFamily: 'var(--mono)' }}>
{`Campaign Caddie is the AI marketing team for small business
owners. It replaces the agency, the freelancer, and the
five-tab marketing stack with a single quiet assistant that
plans, drafts, schedules, and reports. Founded 2026 by David.
Headquartered in San Diego. Currently in invite-only beta.`}
      </pre>

      <h2 style={proseH2}>Press contact</h2>
      <p style={proseP}>Press inquiries: <strong>press@campaigncaddie.com</strong><br/>Response time: 1–2 business days.</p>

      <h2 style={proseH2}>Quick facts</h2>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 0, border: '1px solid var(--hair)', borderRadius: 12, overflow: 'hidden' }}>
        {[['Founded', '2026'], ['Headcount', '1'], ['HQ', 'San Diego'], ['Stage', 'Invite-only beta']].map(([k, v], i) => (
          <div key={k} style={{ padding: 24, borderRight: i < 3 ? '1px solid var(--hair)' : 'none' }}>
            <div className="mono" style={{ color: 'var(--mute)' }}>{k.toUpperCase()}</div>
            <div style={{ fontFamily: 'var(--serif)', fontSize: 26, marginTop: 4 }}>{v}</div>
          </div>
        ))}
      </div>
    </div>
  );
}

function ContactPage() {
  const [sent, setSent] = usePg(false);
  const [topic, setTopic] = usePg('General');
  return (
    <div className="page-pad" style={pageWrap}>
      <PageHero kicker="CONTACT" title="Talk to a human." sub="Real people read everything you send. We aim to reply within one business day — usually faster." />
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 40 }}>
        <div>
          <h3 style={proseH3}>By email</h3>
          <ul style={{ listStyle: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: 14 }}>
            {[
              ['hello@campaigncaddie.com', 'General questions, beta access, hellos'],
              ['support@campaigncaddie.com', 'Help using the product (faster than email — try the chat ↘)'],
              ['press@campaigncaddie.com', 'Journalists, podcasters, partnerships'],
              ['privacy@campaigncaddie.com', 'Data requests, deletion, GDPR / CCPA'],
            ].map(([e, b]) => (
              <li key={e} style={{ borderTop: '1px solid var(--hair)', paddingTop: 12 }}>
                <div style={{ fontFamily: 'var(--serif)', fontSize: 22 }}>{e}</div>
                <div className="mono" style={{ color: 'var(--mute)', marginTop: 4 }}>{b.toUpperCase()}</div>
              </li>
            ))}
          </ul>
        </div>
        <div style={{ border: '1px solid var(--ink)', borderRadius: 12, padding: 24, background: 'var(--paper-warm)' }}>
          {sent ? (
            <div style={{ textAlign: 'center', padding: 20 }}>
              <div style={{ width: 52, height: 52, borderRadius: 999, background: 'var(--ink)', color: 'var(--paper)', display: 'grid', placeItems: 'center', margin: '0 auto 14px' }}>
                <Icon name="check" size={22} stroke={2}/>
              </div>
              <div style={{ fontFamily: 'var(--serif)', fontSize: 28 }}>Got it.</div>
              <p style={{ fontSize: 14, lineHeight: 1.6, color: 'var(--mute-2)', marginTop: 10 }}>We'll get back to you within one business day.</p>
            </div>
          ) : (
            <form onSubmit={e => { e.preventDefault(); setSent(true); }} style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
              <div className="mono" style={{ color: 'var(--mute)' }}>OR USE THE FORM</div>
              <label style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                <span className="mono" style={{ color: 'var(--mute)' }}>YOUR EMAIL</span>
                <input required type="email" placeholder="you@business.com" style={inputCss}/>
              </label>
              <label style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                <span className="mono" style={{ color: 'var(--mute)' }}>TOPIC</span>
                <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
                  {['General', 'Beta access', 'Press', 'Partnership'].map(t => (
                    <button type="button" key={t} onClick={() => setTopic(t)} className="mono" style={{
                      padding: '7px 12px', borderRadius: 999, border: '1px solid var(--ink)',
                      background: topic === t ? 'var(--ink)' : 'transparent',
                      color: topic === t ? 'var(--paper)' : 'var(--ink)',
                      cursor: 'pointer', fontSize: 10
                    }}>{t}</button>
                  ))}
                </div>
              </label>
              <label style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                <span className="mono" style={{ color: 'var(--mute)' }}>MESSAGE</span>
                <textarea required rows={5} placeholder="Tell us what's on your mind…" style={{ ...inputCss, resize: 'vertical', fontFamily: 'inherit' }}/>
              </label>
              <button type="submit" style={{
                marginTop: 4, padding: '14px 20px', background: 'var(--ink)', color: 'var(--paper)',
                border: 'none', borderRadius: 999, cursor: 'pointer', fontSize: 14, fontWeight: 500
              }}>Send message</button>
            </form>
          )}
        </div>
      </div>
    </div>
  );
}

function HelpPage() {
  const cats = [
    { t: 'Getting started', items: ['How do I set up my account?', 'What integrations do you support?', 'Connecting Instagram and Meta Ads', 'Importing past campaigns'] },
    { t: 'Campaigns', items: ['Launching your first campaign', 'Editing scripts Caddie drafted', 'Approving posts before they go live', 'Pausing or ending a campaign'] },
    { t: 'AI Coach', items: ['How Caddie learns your voice', 'Re-training on a new product line', 'Asking for caption rewrites', 'Privacy of your chat history'] },
    { t: 'Billing & beta', items: ['Will I be charged during beta?', 'How do I refer a friend?', 'Cancelling your beta account', 'When do paid plans launch?'] },
    { t: 'Data & privacy', items: ['Where is my data stored?', 'Exporting your campaigns', 'Deleting your account and data', 'GDPR and CCPA requests'] },
    { t: 'Troubleshooting', items: ['Integration says "disconnected"', 'My posts didn\'t schedule', 'Caddie\'s tone feels off', 'Reporting a bug'] },
  ];
  return (
    <div className="page-pad" style={pageWrap}>
      <PageHero kicker="HELP CENTER" title="What can we help with?" />
      <div style={{ display: 'flex', alignItems: 'center', gap: 12, border: '1px solid var(--ink)', borderRadius: 999, padding: '10px 18px', maxWidth: 600, marginBottom: 32 }}>
        <Icon name="spark" size={16}/>
        <input placeholder="Search help articles…" style={{ flex: 1, border: 'none', background: 'transparent', outline: 'none', fontSize: 15, fontFamily: 'inherit' }}/>
        <span className="mono" style={{ color: 'var(--mute)' }}>⌘ K</span>
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
        {cats.map(c => (
          <div key={c.t} style={{ border: '1px solid var(--hair)', borderRadius: 12, padding: 20 }}>
            <h3 style={{ ...proseH3, margin: '0 0 10px' }}>{c.t}</h3>
            <ul style={{ listStyle: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: 10 }}>
              {c.items.map(x => (
                <li key={x}><a href="#" style={{ textDecoration: 'none', fontSize: 14, lineHeight: 1.5, display: 'flex', justifyContent: 'space-between', gap: 12 }}>
                  <span>{x}</span><span style={{ color: 'var(--mute)' }}>→</span>
                </a></li>
              ))}
            </ul>
          </div>
        ))}
      </div>
      <div style={{ marginTop: 32, padding: 24, border: '1px solid var(--ink)', borderRadius: 12, display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 20, flexWrap: 'wrap' }}>
        <div>
          <div style={{ fontFamily: 'var(--serif)', fontSize: 24 }}>Still stuck?</div>
          <p style={{ fontSize: 14, color: 'var(--mute-2)', margin: '4px 0 0' }}>Open the support chat — usually a real human within a few minutes.</p>
        </div>
        <button onClick={() => window.dispatchEvent(new CustomEvent('open-support'))} style={{
          background: 'var(--ink)', color: 'var(--paper)', border: 'none',
          padding: '12px 20px', borderRadius: 999, fontSize: 14, fontWeight: 500, cursor: 'pointer',
          display: 'inline-flex', alignItems: 'center', gap: 8
        }}>
          Chat with us <Icon name="send" size={14}/>
        </button>
      </div>
    </div>
  );
}

function PlaybookPage() {
  return (
    <div className="page-pad" style={pageWrap}>
      <PageHero kicker="MARKETING PLAYBOOK" title="Free reads for the founder of one." sub="A small library of essays, templates, and field notes from working with thousands of small business owners. No email gate." />
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
        {[
          ['ESSAY', 'The first 90 days of marketing', '12 min read', 'A simple cadence: month one is listening, month two is shipping, month three is doubling down.'],
          ['TEMPLATE', 'The two-Tuesday email rhythm', 'Free download', 'Why two emails a month outperforms one weekly newsletter for most small businesses.'],
          ['ESSAY', 'Pricing your launches', '8 min read', 'A framework for setting launch prices that don\'t make you wince two months later.'],
          ['FIELD NOTE', 'What 200 boutique owners told us about Reels', '6 min read', 'Surprises, regrets, and the three things they all stopped doing.'],
          ['TEMPLATE', 'The 14-day product launch calendar', 'Free download', 'The day-by-day calendar Caddie uses by default. Drop your dates in.'],
          ['ESSAY', 'Marketing without the panic', '10 min read', 'How to build a system that runs whether or not you have a good week.'],
        ].map(([k, t, m, b]) => (
          <a key={t} href="#" style={{ border: '1px solid var(--hair)', borderRadius: 12, padding: 24, textDecoration: 'none', color: 'inherit', display: 'block' }}>
            <div className="mono" style={{ color: 'var(--mute)' }}>{k} · {m.toUpperCase()}</div>
            <div style={{ fontFamily: 'var(--serif)', fontSize: 26, margin: '10px 0 8px', letterSpacing: '-0.01em' }}>{t}</div>
            <div style={{ fontSize: 14, lineHeight: 1.55, color: 'var(--mute-2)' }}>{b}</div>
            <div style={{ marginTop: 16, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
              <span className="mono" style={{ color: 'var(--mute)' }}>READ</span>
              <Icon name="arrow" size={14}/>
            </div>
          </a>
        ))}
      </div>
    </div>
  );
}

function FieldGuidePage() {
  return (
    <div className="page-pad" style={pageWrap}>
      <PageHero kicker="SMALL BIZ FIELD GUIDE" title="A reference, not a course." sub="Quick answers to the marketing questions small business owners actually ask. Sorted by situation, not by tactic." />
      {[
        ['I just launched. What do I post first?', 'A short story about why you made the thing. Not the thing\'s features. Customers buy stories about the thing far more often than they buy the thing.'],
        ['I have no idea what to charge.', 'Set a price slightly higher than feels comfortable. If nobody balks, raise it again. Discounts are easier than markups.'],
        ['Should I run paid ads?', 'Not until your organic posts are getting saves. Saves > likes. Saves are the strongest signal that it\'s worth amplifying.'],
        ['How often should I post?', 'Less than you think. Twice a week, well, beats six times a week, hastily.'],
        ['Email or social?', 'Both. Social brings strangers; email turns them into regulars. They aren\'t alternatives.'],
        ['When should I hire a marketer?', 'When you\'ve out-grown what software can do for you. For most small businesses, that\'s a long way off — which is why we built Caddie.'],
      ].map(([q, a], i) => (
        <div key={q} style={{ borderTop: i ? '1px solid var(--hair)' : '1px solid var(--ink)', padding: '32px 0' }}>
          <div style={{ fontFamily: 'var(--serif)', fontSize: 32, lineHeight: 1.15, letterSpacing: '-0.01em', textWrap: 'balance' }}>{q}</div>
          <p style={{ ...proseP, marginTop: 12, maxWidth: 760 }}>{a}</p>
        </div>
      ))}
    </div>
  );
}

// =============== TERMS ===============
function TermsPage() {
  return (
    <div className="page-pad" style={pageWrap}>
      <PageHero kicker="TERMS OF SERVICE · LAST UPDATED MAY 2, 2026" title="Terms of service." sub="Plain-language version below each section. The legal version is the one that controls — but we'll make sure you know what you're agreeing to." />
      {[
        ['1. The agreement', 'These Terms govern your access to and use of Campaign Caddie ("Caddie", "we", "us"). By creating an account or using the service, you agree to these Terms.', 'You\'re using Caddie. These are the rules.'],
        ['2. Beta program', 'Caddie is currently offered as an invite-only beta. The service is provided "as is" during beta, may change without notice, and may have bugs or downtime. Beta accounts are free; no payment is required.', 'It\'s a beta. Things will break sometimes. It\'s free while it does.'],
        ['3. Your account', 'You\'re responsible for what happens under your account, for keeping your password safe, and for the accuracy of the information you provide. You must be 18 or older.', 'Don\'t share your password. Be honest. Be over 18.'],
        ['4. Acceptable use', 'You agree not to use Caddie to send spam, market on behalf of someone without permission, violate any law, infringe on anyone\'s rights, or interfere with the service.', 'Don\'t use Caddie to spam, lie, or break laws.'],
        ['5. Your content', 'You keep all rights to the campaigns, copy, images, and other content you create or upload ("Your Content"). You grant us a limited license to host, display, and process Your Content so we can run the service for you.', 'Your stuff is your stuff. We just need permission to show it back to you.'],
        ['6. Caddie\'s content', 'AI-generated drafts, suggestions, and templates that Caddie produces for you are yours to use. We make no warranty that they\'ll perform well — that part is up to you and your audience.', 'You can use what Caddie writes. We can\'t promise it\'ll go viral.'],
        ['7. Termination', 'You can cancel anytime, no questions asked. We can terminate accounts that violate these Terms, with notice when reasonable.', 'You can leave whenever. We can ask people to leave if they\'re abusing the service.'],
        ['8. Disclaimers', 'Caddie is provided without warranties of any kind. We don\'t guarantee that it will be error-free or that it will achieve any particular marketing outcome.', 'No promises about results. Marketing is hard.'],
        ['9. Limitation of liability', 'To the maximum extent allowed by law, our liability is limited to the amount you paid us in the past 12 months (or, during beta, to USD $100).', 'If something goes wrong, the most we owe you is small.'],
        ['10. Changes', 'We may update these Terms occasionally. If we make material changes, we\'ll notify you at least 14 days before they take effect.', 'These can change. We\'ll tell you when they do.'],
        ['11. Governing law', 'These Terms are governed by the laws of the State of New York, without regard to conflict-of-laws principles.', 'New York rules apply.'],
        ['12. Contact', 'Questions? Email legal@campaigncaddie.com.', 'Reach out if anything is unclear.'],
      ].map(([t, body, plain]) => (
        <div key={t} style={{ borderTop: '1px solid var(--hair)', padding: '28px 0' }}>
          <h3 style={{ ...proseH3, margin: '0 0 12px' }}>{t}</h3>
          <p style={{ fontSize: 15, lineHeight: 1.65, color: 'var(--ink)', maxWidth: 760, margin: 0 }}>{body}</p>
          <div style={{ marginTop: 14, padding: '12px 16px', background: 'var(--paper-warm)', border: '1px solid var(--hair)', borderRadius: 8, maxWidth: 760 }}>
            <div className="mono" style={{ color: 'var(--mute)', marginBottom: 4 }}>IN PLAIN ENGLISH</div>
            <div style={{ fontFamily: 'var(--serif)', fontSize: 18 }}>{plain}</div>
          </div>
        </div>
      ))}
    </div>
  );
}

// =============== PRIVACY ===============
function PrivacyPage() {
  return (
    <div className="page-pad" style={pageWrap}>
      <PageHero kicker="PRIVACY POLICY · LAST UPDATED MAY 2, 2026" title="Privacy policy." sub="What we collect, what we don't, and what's yours. We've kept this short on purpose — and we don't sell anything." />
      <div style={{ background: 'var(--ink)', color: 'var(--paper)', borderRadius: 12, padding: 28, marginBottom: 32 }}>
        <div className="mono" style={{ opacity: 0.6 }}>THE SHORT VERSION</div>
        <ul style={{ listStyle: 'none', padding: 0, margin: '16px 0 0', display: 'flex', flexDirection: 'column', gap: 10 }}>
          {[
            'Your data is yours. We never sell it.',
            'We never use your business data to train AI for other users.',
            'Caddie learns about your business — to serve your business only.',
            'You can export everything, anytime.',
            'You can delete everything, anytime — and we\'ll honor it within 30 days.',
            'We use a small, vetted set of subprocessors. They\'re listed below.',
          ].map(x => (
            <li key={x} style={{ display: 'flex', gap: 10, fontSize: 15 }}>
              <Icon name="check" size={14} stroke={2}/> <span>{x}</span>
            </li>
          ))}
        </ul>
      </div>

      {[
        ['What we collect', 'Account info (name, email, business name), the content you create in Caddie (campaigns, scripts, calendar items), connected-account data (post performance, audience size, ad spend), and basic product analytics (which buttons you click, error logs).'],
        ['What we don\'t collect', 'We don\'t collect data outside Caddie via tracking pixels on third-party sites. We don\'t buy data. We don\'t sell data. We don\'t share your business\'s data with other Caddie customers.'],
        ['How we use your data', 'To provide the service, to make Caddie\'s suggestions better for you specifically, to send you product updates (you can opt out), and to comply with the law.'],
        ['How we train AI', 'Your data is yours. We never use your business data to train AI for other users. Caddie learns about your business — to serve your business only.'],
        ['Your rights', 'You can request a copy of your data, ask us to correct it, or ask us to delete it. Email privacy@campaigncaddie.com. We respond within 7 days.'],
        ['Cookies', 'We use the bare minimum: a session cookie to keep you logged in, and one analytics cookie (privacy-respecting; no cross-site tracking).'],
        ['Children', 'Caddie isn\'t for anyone under 18. We don\'t knowingly collect data from children.'],
        ['International transfers', 'We\'re based in the U.S. and store data in U.S. and EU regions. We use standard contractual clauses for transfers from the EU.'],
        ['Changes', 'If we change anything material here, we\'ll email you and update the date at the top.'],
        ['Contact', 'Privacy questions: privacy@campaigncaddie.com.'],
      ].map(([t, body]) => (
        <div key={t} style={{ borderTop: '1px solid var(--hair)', padding: '24px 0' }}>
          <h3 style={{ ...proseH3, margin: '0 0 8px' }}>{t}</h3>
          <p style={{ fontSize: 15, lineHeight: 1.65, color: 'var(--mute-2)', maxWidth: 760, margin: 0 }}>{body}</p>
        </div>
      ))}
    </div>
  );
}

// =============== SUPPORT CHAT WIDGET ===============
function SupportChat() {
  const [open, setOpen] = usePg(false);
  const [unread, setUnread] = usePg(() => {
    try { const s = JSON.parse(localStorage.getItem('cc:sup:msgs') || 'null'); if (Array.isArray(s) && s.length > 1) return 0; } catch (_) {}
    return 1;
  });
  const [msgs, setMsgs] = usePg(() => {
    try {
      const saved = JSON.parse(localStorage.getItem('cc:sup:msgs') || 'null');
      if (Array.isArray(saved) && saved.length) return saved;
    } catch (_) {}
    return [{ who: 'them', name: 'David', t: "Hey 👋 I'm David, the founder. What can I help you with today?", ts: 'now' }];
  });
  const [draft, setDraft] = usePg('');
  const [typing, setTyping] = usePg(false);
  const [live, setLive] = usePg(false);
  const [gotReply, setGotReply] = usePg(false);
  const scroller = useRpg(null);
  const lastAgentId = useRpg((() => { try { return parseInt(localStorage.getItem('cc:sup:lastAgent') || '0', 10) || 0; } catch (_) { return 0; } })());
  const misses = useRpg(0);
  const openRef = useRpg(open);
  openRef.current = open;

  // Stable anonymous session id for this browser.
  const [sid, setSid] = usePg(() => {
    try {
      let s = localStorage.getItem('cc:sup:sid');
      if (!s) { s = Math.random().toString(36).slice(2, 10); localStorage.setItem('cc:sup:sid', s); }
      return s;
    } catch (_) { return Math.random().toString(36).slice(2, 10); }
  });

  // Start a fresh conversation — new anonymous session, transcript cleared.
  const newChat = () => {
    let s;
    try {
      s = Math.random().toString(36).slice(2, 10);
      localStorage.setItem('cc:sup:sid', s);
      localStorage.removeItem('cc:sup:msgs');
      localStorage.removeItem('cc:sup:lastAgent');
      localStorage.removeItem('cc:sup:live');
    } catch (_) { s = Math.random().toString(36).slice(2, 10); }
    setSid(s);
    lastAgentId.current = 0; misses.current = 0;
    setLive(false); setGotReply(false); setTyping(false); setDraft(''); setUnread(0);
    setMsgs([{ who: 'them', name: 'David', t: "Hey 👋 I'm David, the founder. What can I help you with today?", ts: 'now' }]);
  };

  useEpg(() => {
    const handler = () => { setOpen(true); setUnread(0); };
    window.addEventListener('open-support', handler);
    try { if (localStorage.getItem('cc:sup:live') === '1') setLive(true); } catch (_) {} // resume across reloads
    return () => window.removeEventListener('open-support', handler);
  }, []);

  useEpg(() => { scroller.current?.scrollTo({ top: 99999, behavior: 'smooth' }); }, [msgs, typing, open]);

  // Persist the whole transcript (messages sent AND received) so a refresh
  // restores it instead of dropping everything the visitor typed.
  useEpg(() => {
    try {
      localStorage.setItem('cc:sup:msgs', JSON.stringify(msgs.slice(-200)));
      localStorage.setItem('cc:sup:lastAgent', String(lastAgentId.current));
    } catch (_) {}
  }, [msgs]);

  // While live, poll for the operator's replies (typed in the email reply console).
  useEpg(() => {
    if (!live) return;
    let stop = false, timer;
    const tick = async () => {
      try {
        const r = await fetch(`/api/support/poll?session=${encodeURIComponent(sid)}&after=${lastAgentId.current}`);
        if (r.ok) {
          const d = await r.json();
          if (d.messages && d.messages.length) {
            d.messages.forEach(mm => { lastAgentId.current = Math.max(lastAgentId.current, mm.id); });
            setMsgs(m => [...m, ...d.messages.map(mm => ({ who: 'them', name: 'David', t: mm.text, ts: 'now' }))]);
            setGotReply(true);
            if (!openRef.current) setUnread(u => u + d.messages.length);
          }
        }
      } catch (_) {}
      if (!stop) timer = setTimeout(tick, 3500);
    };
    tick();
    return () => { stop = true; clearTimeout(timer); };
  }, [live, sid]);

  const relay = async (text, history) => {
    try {
      const r = await fetch('/api/support/send', {
        method: 'POST', headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(history ? { session: sid, text, history } : { session: sid, text }),
      });
      if (r.status === 503) return 'unconfigured';
      return r.ok ? 'ok' : 'error';
    } catch (_) { return 'error'; }
  };

  const goLive = async (context) => {
    setTyping(true);
    // Hand the operator the conversation so far (the bot chat lives only in the
    // browser until now) so they can read the whole log in the reply console.
    const history = msgs.map(m => ({ who: m.who === 'me' ? 'visitor' : 'bot', text: m.t }));
    const status = await relay(context || 'A visitor would like to talk to a human.', history);
    setTyping(false);
    if (status === 'ok') {
      setLive(true); setGotReply(false);
      try { localStorage.setItem('cc:sup:live', '1'); } catch (_) {}
      setMsgs(m => [...m, { who: 'them', name: 'David', t: "Got it — I've pinged Dave, the founder. Sit tight, he'll reply right here. You can keep typing in the meantime.", ts: 'now' }]);
    } else {
      setMsgs(m => [...m, { who: 'them', name: 'David', t: emailFallbackNote(), ts: 'now' }]);
      emailFallback(context);
    }
  };

  const send = (text) => {
    const q = (typeof text === 'string' ? text : draft).trim();
    if (!q) return;
    setMsgs(m => [...m, { who: 'me', t: q, ts: 'now' }]);
    setDraft('');
    if (live) { relay(q); return; }             // already talking to a person
    if (wantsHuman(q)) { misses.current = 0; goLive(q); return; }   // explicit ask
    const answer = pickSupportReply(q);
    if (answer) {                                // scripted FAQ can handle it
      misses.current = 0;
      setTyping(true);
      setTimeout(() => {
        setMsgs(m => [...m, { who: 'them', name: 'David', t: answer, ts: 'now' }]);
        setTyping(false);
        if (!openRef.current) setUnread(u => u + 1);
      }, 1100);
      return;
    }
    // Unknown question: help first, only ping a human after two misses in a row
    // (or when they ask) — don't auto-ping the team for everything.
    misses.current += 1;
    if (misses.current >= 2) { misses.current = 0; goLive(q); return; }
    setTyping(true);
    setTimeout(() => {
      setMsgs(m => [...m, { who: 'them', name: 'David', t: "I might not have that exact answer 😅 — but I can help with what Caddie is, pricing, the beta, the channels it covers, privacy, or canceling. Ask me one of those, or say “talk to a human” and I'll bring in the team.", ts: 'now' }]);
      setTyping(false);
      if (!openRef.current) setUnread(u => u + 1);
    }, 900);
  };

  return (
    <>
      <button onClick={() => { setOpen(o => !o); setUnread(0); }} aria-label="Support chat" style={{
        position: 'fixed', bottom: 24, right: 24, zIndex: 100,
        width: 56, height: 56, borderRadius: 999,
        background: 'var(--ink)', color: 'var(--paper)',
        border: 'none', cursor: 'pointer',
        display: 'grid', placeItems: 'center',
        boxShadow: '0 12px 30px -10px rgba(0,0,0,0.35)',
      }}>
        <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
          <path d="M21 12a8 8 0 1 1-3.5-6.6L21 4l-1.4 3.5A8 8 0 0 1 21 12z"/>
          <circle cx="9" cy="12" r="1" fill="currentColor"/>
          <circle cx="13" cy="12" r="1" fill="currentColor"/>
          <circle cx="17" cy="12" r="1" fill="currentColor"/>
        </svg>
        {unread > 0 && (
          <span style={{
            position: 'absolute', top: -4, right: -4,
            width: 20, height: 20, borderRadius: 999,
            background: 'var(--paper)', color: 'var(--ink)',
            border: '1.5px solid var(--ink)',
            display: 'grid', placeItems: 'center',
            fontFamily: 'var(--mono)', fontSize: 10, fontWeight: 600
          }}>{unread}</span>
        )}
      </button>

      {open && (
        <div
          onClick={() => setOpen(false)}
          style={{ position: 'fixed', inset: 0, zIndex: 99, background: 'transparent' }}
          aria-hidden="true"
        />
      )}
      <div
        role="dialog"
        aria-hidden={!open}
        style={{
          position: 'fixed', bottom: 96, right: 24, zIndex: 100,
          width: 360, height: 520, maxHeight: 'calc(100vh - 120px)',
          background: 'var(--paper)', border: '1px solid var(--ink)',
          borderRadius: 14, overflow: 'hidden',
          display: 'flex', flexDirection: 'column',
          boxShadow: '0 30px 60px -20px rgba(0,0,0,0.35)',
          transformOrigin: 'bottom right',
          opacity: open ? 1 : 0,
          transform: open ? 'translateY(0) scale(1)' : 'translateY(12px) scale(0.96)',
          pointerEvents: open ? 'auto' : 'none',
          visibility: open ? 'visible' : 'hidden',
          transition: 'opacity 280ms cubic-bezier(0.22, 1, 0.36, 1), transform 280ms cubic-bezier(0.22, 1, 0.36, 1), visibility 0s linear ' + (open ? '0s' : '280ms'),
        }}
      >
        <div style={{ padding: '14px 16px', borderBottom: '1px solid var(--hair)', background: 'var(--ink)', color: 'var(--paper)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <div style={{ width: 32, height: 32, borderRadius: 999, background: 'var(--paper)', color: 'var(--ink)', display: 'grid', placeItems: 'center', fontFamily: 'var(--serif)', fontSize: 14 }}>D</div>
              <div>
                <div style={{ fontFamily: 'var(--serif)', fontSize: 16 }}>David · Caddie support</div>
                <div className="mono" style={{ opacity: 0.7, fontSize: 9 }}>● ONLINE · USUALLY REPLIES &lt; 5 MIN</div>
              </div>
            </div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
              <button onClick={newChat} title="Start a new chat" className="mono" style={{ background: 'transparent', border: '1px solid rgba(250,250,250,0.35)', color: 'var(--paper)', cursor: 'pointer', fontSize: 9, padding: '4px 9px', borderRadius: 999, letterSpacing: '0.06em' }}>NEW CHAT</button>
              <button onClick={() => setOpen(false)} aria-label="Close chat" style={{ background: 'none', border: 'none', color: 'var(--paper)', cursor: 'pointer', fontSize: 22, lineHeight: 1 }}>×</button>
            </div>
          </div>

          <div ref={scroller} style={{ flex: 1, overflowY: 'auto', padding: 14, display: 'flex', flexDirection: 'column', gap: 10, background: 'var(--paper-warm)' }}>
            {msgs.map((m, i) => (
              <div key={i} style={{
                alignSelf: m.who === 'me' ? 'flex-end' : 'flex-start',
                maxWidth: '85%',
                background: m.who === 'me' ? 'var(--ink)' : 'var(--paper)',
                color: m.who === 'me' ? 'var(--paper)' : 'var(--ink)',
                border: '1px solid ' + (m.who === 'me' ? 'var(--ink)' : 'var(--hair)'),
                padding: '9px 12px', borderRadius: 12, fontSize: 13.5, lineHeight: 1.5,
              }}>
                {m.t}
              </div>
            ))}
            {typing && (
              <div style={{ alignSelf: 'flex-start', background: 'var(--paper)', border: '1px solid var(--hair)', padding: '10px 12px', borderRadius: 12, display: 'flex', gap: 4 }}>
                {[0, 0.15, 0.3].map(d => (
                  <span key={d} style={{ width: 6, height: 6, borderRadius: 999, background: 'var(--ink)', opacity: 0.4, animation: `sc-dot 1.1s ${d}s infinite` }}/>
                ))}
                <style>{`@keyframes sc-dot { 0%,100% { opacity: 0.25; transform: translateY(0); } 50% { opacity: 1; transform: translateY(-2px); } }`}</style>
              </div>
            )}
          </div>

          <div style={{ padding: 12, borderTop: '1px solid var(--hair)' }}>
            {!live && (
              <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', marginBottom: 8 }}>
                {['Beta access?', 'Pricing?', 'Privacy question'].map(q => (
                  <button key={q} onClick={() => send(q)} className="mono" style={{
                    padding: '5px 10px', borderRadius: 999, border: '1px solid var(--ink)',
                    background: 'transparent', cursor: 'pointer', fontSize: 9.5
                  }}>{q}</button>
                ))}
              </div>
            )}
            {live && !gotReply && (
              <div className="mono" style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 8, fontSize: 10, color: 'var(--mute)' }}>
                <span style={{ width: 6, height: 6, borderRadius: 999, background: 'var(--ink)', animation: 'sc-pulse 1.2s infinite' }}/>
                WAITING FOR DAVE…
                <style>{`@keyframes sc-pulse { 0%,100% { opacity: 0.3 } 50% { opacity: 1 } }`}</style>
              </div>
            )}
            <form onSubmit={e => { e.preventDefault(); send(); }} style={{ display: 'flex', gap: 8, alignItems: 'center', border: '1px solid var(--ink)', borderRadius: 999, padding: '4px 4px 4px 14px', background: 'var(--paper)' }}>
              <input
                value={draft}
                onChange={e => setDraft(e.target.value)}
                placeholder="Type a message…"
                style={{ flex: 1, border: 'none', outline: 'none', fontSize: 13, background: 'transparent', fontFamily: 'inherit' }}
              />
              <button type="submit" style={{ width: 30, height: 30, borderRadius: 999, border: 'none', background: 'var(--ink)', color: 'var(--paper)', cursor: 'pointer', display: 'grid', placeItems: 'center' }}>
                <Icon name="send" size={14}/>
              </button>
            </form>
          </div>
        </div>
    </>
  );
}

// Does the message ask for a real person?
function wantsHuman(q) {
  return /\b(human|person|people|someone|somebody|agent|founder|david|real|talk to|speak|call|contact|sales|demo)\b/i.test(q || '');
}
function emailFallbackNote() {
  return "Our live chat isn't switched on right now — email us at hello@campaigncaddie.com and we'll come straight back to you.";
}
// Used only when the Telegram relay isn't configured: open a prefilled email.
function emailFallback(context) {
  const subject = encodeURIComponent('Question from campaigncaddie.com');
  const body = context ? '&body=' + encodeURIComponent('My question: ' + context) : '';
  window.location.href = 'mailto:hello@campaigncaddie.com?subject=' + subject + body;
  return false;
}

// Scripted FAQ — no AI, no abuse surface. Anything it can't answer routes to a human.
function pickSupportReply(q) {
  const Q = (q || '').toLowerCase();
  const has = (...w) => w.some(x => Q.includes(x));

  // greetings & smalltalk
  if (/^\s*(hi|hey+|hello|yo|hiya|howdy|good (morning|afternoon|evening))\b/.test(Q) && Q.length < 22)
    return "Hey! 👋 I'm here to help. Ask me about what Campaign Caddie is, pricing, the beta, the channels it covers, or privacy — or say “talk to a human” and I'll bring in the team.";
  if (has('thank', 'thanks', 'thx', 'cheers', 'appreciate'))
    return "Anytime! Anything else I can help with? If you'd rather talk to a person, just say “talk to a human.”";
  if (has('bye', 'goodbye', 'see ya', 'see you', 'cya', "that's all", 'that is all'))
    return "Take care! We're here whenever you need us — the beta waitlist is one tap away on the “Beta” button up top.";

  // what is it / how it works
  if (has('what is', "what's", 'what does', 'what can', 'explain', 'tell me about', 'overview', 'about caddie', 'about campaign') || (has('how') && has('work')))
    return "Caddie is a marketing team in software form. Tell it about your brand and it plans your week, writes the work — captions, emails, ad copy — and tells you exactly what to do next. You approve and post. No agency, no retainer.";

  // who it's for
  if (has('who is it for', 'who is this for', 'right for me', 'good for', 'for my', 'for me', 'small business', 'ecommerce', 'e-commerce', 'shopify', 'restaurant', 'agency', 'solo', 'startup', 'creator', 'freelanc'))
    return "It's built for small brands and solo founders without a marketing team — Shopify stores, local shops, creators, early startups. If you're writing and posting everything yourself, Caddie takes that off your plate.";

  // beta / access / getting started
  if (has('beta', 'invite', 'access', 'join', 'sign up', 'signup', 'waitlist', 'wait list', 'apply', 'application', 'get started', 'getting started', 'how do i start', 'onboard'))
    return "We're in private beta (Cohort 03), inviting people in waves. Apply with the “Beta” button up top — if you've already applied you should hear within 2–3 weeks. Want me to flag your spot? Say “talk to a human” and leave your email.";

  // pricing
  if (has('price', 'pricing', 'cost', 'cheap', 'expensive', 'pay', 'payment', 'free', 'plan', 'subscription', 'trial', 'card', 'billing', 'how much', 'afford'))
    return "Beta is fully free — no card required. When paid plans launch later this year they'll be about $20–$50/month, and beta members get 6 months free past that, automatically.";

  // launch / timeline
  if (has('launch', 'when ', 'available', 'release', 'timeline', 'eta', 'public', 'ready yet', 'live yet'))
    return "Private beta is live now; public launch is later this year. The fastest way in is the beta waitlist — accepted brands get full access as spots open.";

  // channels / integrations / publishing
  if (has('channel', 'instagram', 'insta', 'tiktok', 'facebook', 'youtube', 'shorts', 'linkedin', 'twitter', 'pinterest', 'integrat', 'connect', 'publish', 'post for me', 'auto post', 'autopost', 'schedul', 'newsletter') || (has('email') && !has('email you', 'your email')))
    return "Today Caddie drafts for Instagram, TikTok, Facebook, YouTube Shorts, and email — it writes everything and tells you when to post; you publish. Direct publishing, scheduling, and analytics are rolling out through the beta.";

  // AI / how the writing works
  if (has('ai', 'a.i', 'gpt', 'chatgpt', 'claude', 'llm', 'model', 'automated', 'automation', 'robot'))
    return "Caddie uses AI to plan and write, tuned to your brand — your voice, products, and goals — not a generic chatbot. You stay in control: it proposes, you approve, and nothing goes out without you.";

  // results / does it work
  if (has('results', 'roi', 'does it actually', 'really work', 'guarantee', 'proof', 'case study', 'example', 'grow', 'sales', 'followers', 'engagement'))
    return "Caddie won't promise overnight virality — what it does is keep you showing up consistently with on-brand work, which is what compounds. You always see the reasoning behind each suggestion, so you're never posting blind.";

  // privacy / security
  if (has('privacy', 'data', 'gdpr', 'secure', 'security', 'safe', 'private', 'train', 'own my'))
    return "Your data is yours. We never use your business data to train AI for other users — Caddie learns about your business to serve your business only. You can export or delete everything any time.";

  // cancel / delete / refund
  if (has('cancel', 'delete', 'refund', 'unsubscribe', 'opt out', 'remove my', 'close my account'))
    return "Totally fine — cancel any time from Settings → Account. We hold your data for 30 days in case you change your mind, then delete it for good.";

  // referral
  if (has('refer', 'referral', 'friend', 'invite code', 'affiliate'))
    return "Each accepted referral bumps you up the queue. You'll get a referral link once you're in.";

  // app / mobile
  if (has('app store', 'mobile', 'ios', 'android', 'iphone', 'download', 'desktop app'))
    return "Caddie runs in your browser on any device — there's nothing to download. A dedicated mobile app is on the roadmap.";

  // contact / support email
  if (has('contact', 'support', 'help desk', 'email you', 'your email', 'get in touch', 'reach you'))
    return "You can reach us at hello@campaigncaddie.com, or say “talk to a human” here and I'll connect you in this chat.";

  // language / location
  if (has('language', 'spanish', 'french', 'german', 'country', 'countries', 'where are you', 'available in', 'worldwide'))
    return "Caddie writes in English today, with more languages coming. It works anywhere with internet — the beta is open to brands worldwide.";

  return null; // genuinely unknown → caller nudges, then hands off to a human
}

// =============== ROUTING + NAV/FOOTER ===============
function PageNav({ page, go }) {
  const [menuOpen, setMenuOpen] = usePg(false);
  // Lock page scroll while the full-screen menu is open
  useEpg(() => {
    document.body.style.overflow = menuOpen ? 'hidden' : '';
    return () => { document.body.style.overflow = ''; };
  }, [menuOpen]);
  const links = [
    ['Features', 'home', '#features'],
    ['How it works', 'home', '#how'],
    ['Preview', 'home', '#preview'],
    ['Beta', 'beta'],
  ];
  const goAnd = (p, h) => { setMenuOpen(false); go(p, h); };
  const roundIconBtn = {
    background: 'transparent', border: '1px solid var(--hair-strong)', borderRadius: 999,
    width: 38, height: 38, alignItems: 'center', justifyContent: 'center',
    cursor: 'pointer', color: 'var(--ink)', padding: 0,
  };
  return (
    <header style={{ position: 'sticky', top: 0, zIndex: 50, background: 'rgba(250,250,250,0.85)', backdropFilter: 'saturate(120%) blur(10px)', borderBottom: '1px solid var(--hair)' }}>
      <div className="shell" style={{ padding: '14px 0', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <button onClick={() => go('home')} style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 0 }}><Logo /></button>
        <nav className="mono pn-links" style={{ display: 'flex', gap: 28 }}>
          {links.map(([label, p, h]) => (
            <button key={label} onClick={() => go(p, h)} style={{
              background: 'none', border: 'none', cursor: 'pointer',
              fontFamily: 'inherit', fontSize: 11, letterSpacing: '0.06em',
              textTransform: 'uppercase', color: page === p && !h ? 'var(--ink)' : 'var(--mute-2)',
              padding: 0
            }}>{label}</button>
          ))}
        </nav>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          {/* Log in routes to the real beta dashboard. Real magic-link auth
              lives at /app/ — there is no fake-login fallback. */}
          <a href="/app/" className="mono pn-login" style={{
            background: 'transparent', color: 'var(--mute-2)', padding: '10px 14px',
            border: '1px solid var(--hair-strong)', borderRadius: 999, cursor: 'pointer',
            fontFamily: 'inherit', textDecoration: 'none',
            fontSize: 11, letterSpacing: '0.06em', textTransform: 'uppercase',
            display: 'inline-flex', alignItems: 'center'
          }}>
            Log in
          </a>
          <button onClick={() => go('apply')} className="mono" style={{
            background: 'var(--ink)', color: 'var(--paper)', padding: '10px 16px',
            border: 'none', borderRadius: 999, cursor: 'pointer', fontFamily: 'inherit',
            fontSize: 11, letterSpacing: '0.06em', textTransform: 'uppercase'
          }}>
            Apply for Free Beta →
          </button>
          <button className="pn-burger" aria-label="Open menu" onClick={() => setMenuOpen(true)} style={{ ...roundIconBtn, display: 'none' }}>
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M3 8h18M3 16h18" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/></svg>
          </button>
        </div>
      </div>

      {menuOpen && ReactDOM.createPortal(
        <div className="pn-menu" role="dialog" aria-modal="true" aria-label="Menu">
          <div className="pn-menu-top">
            <button onClick={() => goAnd('home')} style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 0 }}><Logo /></button>
            <button aria-label="Close menu" onClick={() => setMenuOpen(false)} style={{ ...roundIconBtn, display: 'inline-flex' }}>
              <svg width="15" height="15" viewBox="0 0 24 24" fill="none"><path d="M6 6l12 12M18 6L6 18" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/></svg>
            </button>
          </div>
          <div className="pn-menu-body">
            <span className="mono" style={{ color: 'var(--mute)' }}>MENU — FOR THE FOUNDER OF ONE</span>
            <nav style={{ borderTop: '1px solid var(--ink)', marginTop: 14, display: 'flex', flexDirection: 'column' }}>
              {links.map(([label, p, h], i) => (
                <button key={label} onClick={() => goAnd(p, h)} style={{
                  display: 'flex', alignItems: 'baseline', gap: 20,
                  background: 'none', border: 'none', borderBottom: '1px solid var(--hair)',
                  padding: '20px 2px', cursor: 'pointer', textAlign: 'left',
                  color: 'var(--ink)', fontFamily: 'inherit'
                }}>
                  <span className="mono" style={{ color: 'var(--mute)' }}>0{i + 1}</span>
                  <span style={{ fontFamily: 'var(--serif)', fontSize: 'clamp(28px, 5.5vw, 40px)', lineHeight: 1, letterSpacing: '-0.02em', whiteSpace: 'nowrap' }}>{label}</span>
                </button>
              ))}
            </nav>
            <div style={{ marginTop: 'auto', paddingTop: 32, display: 'flex', flexDirection: 'column', gap: 10 }}>
              <button onClick={() => goAnd('apply')} className="mono" style={{
                background: 'var(--ink)', color: 'var(--paper)', padding: '16px 18px',
                border: 'none', borderRadius: 999, cursor: 'pointer', fontFamily: 'inherit',
                fontSize: 11, letterSpacing: '0.06em', textTransform: 'uppercase'
              }}>Apply for Free Beta →</button>
              <a href="/app/" className="mono" style={{
                background: 'transparent', color: 'var(--ink)', padding: '15px 18px',
                border: '1px solid var(--ink)', borderRadius: 999, cursor: 'pointer', fontFamily: 'inherit',
                fontSize: 11, letterSpacing: '0.06em', textTransform: 'uppercase',
                textDecoration: 'none', textAlign: 'center'
              }}>Log in</a>
            </div>
          </div>
        </div>,
        document.body
      )}
    </header>
  );
}

function PageFooter({ go }) {
  const cols = [
    ['Product', [
      ['Features', 'home', '#features'],
      ['How it works', 'home', '#how'],
      ['Dashboard preview', 'home', '#preview'],
      ['Integrations', 'home', '#integrations-row'],
      ['Beta program', 'beta'],
    ]],
    ['Company', [
      ['About', 'about'],
      ['Press kit', 'press'],
      ['Contact', 'contact'],
    ]],
    ['Resources', [
      ['Help center', 'help'],
      ['Terms', 'terms'],
      ['Privacy', 'privacy'],
    ]],
  ];
  return (
    <footer style={{ background: 'var(--paper)', borderTop: '1px solid var(--ink)' }}>
      <div className="shell stack-on-mobile footer-pad" style={{ display: 'grid', gridTemplateColumns: '1.2fr 1fr 1fr 1fr', gap: 40 }}>
        <div>
          <button onClick={() => go('home')} style={{ background: 'none', border: 'none', padding: 0, cursor: 'pointer' }}><Logo /></button>
          <p style={{ fontFamily: 'var(--serif)', fontSize: 22, lineHeight: 1.3, margin: '20px 0 0', maxWidth: 320, letterSpacing: '-0.01em' }}>
            A quiet, capable marketing team — for businesses small enough to know every customer's name.
          </p>
        </div>
        {cols.map(([title, items]) => (
          <div key={title}>
            <div className="mono" style={{ color: 'var(--mute)', marginBottom: 14 }}>{title.toUpperCase()}</div>
            <ul style={{ listStyle: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: 8 }}>
              {items.map(([label, p, h]) => (
                <li key={label}>
                  <button onClick={() => go(p, h)} style={{
                    background: 'none', border: 'none', padding: 0, cursor: 'pointer',
                    fontFamily: 'inherit', fontSize: 14, color: 'var(--ink)', textAlign: 'left'
                  }}>{label}</button>
                </li>
              ))}
            </ul>
          </div>
        ))}
      </div>
      <div style={{ borderTop: '1px solid var(--hair)' }}>
        <div className="shell" style={{ padding: '20px 0', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }} className="mono">
          <span style={{ color: 'var(--mute)' }}>© 2026 CAMPAIGN CADDIE — MADE FOR THE FOUNDER OF ONE</span>
          <span style={{ color: 'var(--mute)' }}>SAN DIEGO · REMOTE</span>
        </div>
      </div>
    </footer>
  );
}

// =============== APPLY PAGE — full beta application ===============
function ApplyPage({ go }) {
  const [step, setStep] = usePg(0);
  const [data, setData] = usePg(() => {
    let prefill = {};
    try {
      const e = sessionStorage.getItem('cc:applyEmail');
      const b = sessionStorage.getItem('cc:applyBiz');
      const s = sessionStorage.getItem('cc:applySize');
      if (e) prefill.email = e;
      if (b) prefill.business = b;
      if (s) prefill.size = s;
      sessionStorage.removeItem('cc:applyEmail');
      sessionStorage.removeItem('cc:applyBiz');
      sessionStorage.removeItem('cc:applySize');
    } catch (_) {}
    return {
      email: '', name: '', business: '', url: '',
      industry: '', size: 'Just me', stage: 'Already selling',
      revenue: 'Pre-revenue', goal: '', channels: [], stack: '',
      biggestPain: '', heard: '', referral: '',
      ...prefill,
    };
  });
  const set = (k, v) => setData(d => ({ ...d, [k]: v }));
  const toggleChannel = (c) => set('channels', data.channels.includes(c) ? data.channels.filter(x => x !== c) : [...data.channels, c]);

  const steps = ['You', 'The business', 'The work', 'Almost done'];
  const total = steps.length;
  const isLast = step === total - 1;

  // step validation
  const canAdvance = () => {
    if (step === 0) return /^\S+@\S+\.\S+$/.test(data.email) && data.name.trim().length >= 2;
    if (step === 1) return data.business.trim().length >= 2 && data.industry.trim().length >= 2;
    if (step === 2) return data.goal.trim().length >= 8 && data.channels.length >= 1;
    return true;
  };

  const [submitting, setSubmitting] = usePg(false);
  const [submitErr, setSubmitErr] = usePg('');

  const submit = async (e) => {
    e?.preventDefault();
    if (!canAdvance() || submitting) return;
    setSubmitting(true); setSubmitErr('');
    try {
      const r = await fetch('/api/applications', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(data),
      });
      const j = await r.json().catch(() => ({}));
      if (!r.ok) throw new Error(j?.error || 'submit_failed');
      setStep(total); // success state
    } catch (err) {
      setSubmitErr(err.message === 'invalid_email'
        ? 'That email looks invalid — double-check and resubmit.'
        : 'Something went wrong submitting your application. Please try again.');
    } finally {
      setSubmitting(false);
    }
  };

  if (step === total) {
    return (
      <div className="page-pad" style={pageWrap}>
        <div style={{ border: '1px solid var(--ink)', borderRadius: 14, padding: '64px 48px', textAlign: 'center', background: 'var(--paper-warm)' }}>
          <div className="mono" style={{ color: 'var(--mute)' }}>APPLICATION RECEIVED · COHORT 03</div>
          <h1 style={{ fontFamily: 'var(--serif)', fontSize: 'clamp(56px, 7vw, 110px)', lineHeight: 0.95, letterSpacing: '-0.03em', margin: '14px 0 0' }}>
            Got it, <span style={{ fontStyle: 'italic' }}>{data.name.split(' ')[0] || 'friend'}.</span>
          </h1>
          <p style={{ fontSize: 18, lineHeight: 1.6, color: 'var(--mute-2)', margin: '20px auto 0', maxWidth: 540 }}>
            Your application is in. I read every one personally — usually within 48 hours. If you're a fit, I'll be in touch with next steps to get you set up.
          </p>
          <div style={{ marginTop: 32, display: 'flex', gap: 12, justifyContent: 'center', flexWrap: 'wrap' }}>
            <button onClick={() => go('home')} style={{ ...ctaPrimary, border: 'none', cursor: 'pointer' }}>
              Back to home
            </button>
            <button onClick={() => go('beta')} style={{ ...ctaGhost, cursor: 'pointer' }}>
              Read about the beta
            </button>
          </div>
          <div className="mono" style={{ color: 'var(--mute)', marginTop: 28 }}>— DAVID</div>
        </div>
      </div>
    );
  }

  return (
    <div className="page-pad" style={pageWrap}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 24 }}>
        <span className="mono" style={{ color: 'var(--mute)' }}>BETA APPLICATION · COHORT 03 · MAY 2026</span>
        <span className="mono" style={{ color: 'var(--mute)' }}>STEP {step + 1} OF {total}</span>
      </div>

      <h1 style={{ fontFamily: 'var(--serif)', fontSize: 'clamp(48px, 6vw, 92px)', lineHeight: 0.95, letterSpacing: '-0.025em', margin: 0 }}>
        Apply for the <span style={{ fontStyle: 'italic' }}>free beta.</span>
      </h1>
      <p style={{ fontSize: 17, lineHeight: 1.6, color: 'var(--mute-2)', maxWidth: 580, marginTop: 18 }}>
        Four short steps. About 90 seconds. We hand-pick beta members so the product genuinely fits your business — the more you tell us, the better the fit.
      </p>

      {/* progress bar */}
      <div style={{ display: 'flex', gap: 6, marginTop: 28, marginBottom: 36 }}>
        {steps.map((s, i) => (
          <div key={s} style={{ flex: 1 }}>
            <div style={{
              height: 4, borderRadius: 999,
              background: i <= step ? 'var(--ink)' : 'var(--hair-strong)',
              transition: 'background 0.3s'
            }}/>
            <div className="mono" style={{ color: i === step ? 'var(--ink)' : 'var(--mute)', marginTop: 8, fontWeight: i === step ? 600 : 400 }}>
              0{i+1} · {s.toUpperCase()}
            </div>
          </div>
        ))}
      </div>

      <form onSubmit={(e) => { e.preventDefault(); if (isLast) submit(); else if (canAdvance()) setStep(step + 1); }} style={{ border: '1px solid var(--ink)', borderRadius: 14, padding: 36, background: 'var(--paper-warm)' }}>
        {step === 0 && (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>
            <ApplyField label="YOUR NAME" required>
              <input value={data.name} onChange={e => set('name', e.target.value)} placeholder="Your full name" style={applyInputCss} autoFocus/>
            </ApplyField>
            <ApplyField label="EMAIL" required>
              <input type="email" value={data.email} onChange={e => set('email', e.target.value)} placeholder="you@yourbusiness.com" style={applyInputCss}/>
            </ApplyField>
            <ApplyField label="HOW DID YOU HEAR ABOUT US?" hint="Optional">
              <select value={data.heard} onChange={e => set('heard', e.target.value)} style={applyInputCss}>
                <option value="">Pick one…</option>
                <option>A friend / referral</option>
                <option>Twitter / X</option>
                <option>Instagram</option>
                <option>TikTok</option>
                <option>Newsletter / blog</option>
                <option>Search</option>
                <option>Somewhere else</option>
              </select>
            </ApplyField>
            {data.heard === 'A friend / referral' && (
              <ApplyField label="WHO REFERRED YOU?" hint="Their email — bumps you up the queue">
                <input value={data.referral} onChange={e => set('referral', e.target.value)} placeholder="friend@theirbusiness.com" style={applyInputCss}/>
              </ApplyField>
            )}
          </div>
        )}

        {step === 1 && (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>
            <ApplyField label="BUSINESS NAME" required>
              <input value={data.business} onChange={e => set('business', e.target.value)} placeholder="Your business name" style={applyInputCss} autoFocus/>
            </ApplyField>
            <ApplyField label="WEBSITE" hint="Optional but helpful">
              <input value={data.url} onChange={e => set('url', e.target.value)} placeholder="yourbusiness.com" style={applyInputCss}/>
            </ApplyField>
            <ApplyField label="WHAT DO YOU SELL?" required hint="One sentence">
              <input value={data.industry} onChange={e => set('industry', e.target.value)} placeholder="Hand-block-printed linen home goods" style={applyInputCss}/>
            </ApplyField>
            <ApplyField label="TEAM SIZE">
              <PillRow value={data.size} options={['Just me', '2–5', '6–20', '20+']} onChange={v => set('size', v)} />
            </ApplyField>
            <ApplyField label="STAGE">
              <PillRow value={data.stage} options={['Pre-launch', 'Just launched', 'Already selling', 'Scaling']} onChange={v => set('stage', v)} />
            </ApplyField>
            <ApplyField label="MONTHLY REVENUE" hint="Roughly — won't be shared">
              <PillRow value={data.revenue} options={['Pre-revenue', '< $5k', '$5–25k', '$25–100k', '$100k+']} onChange={v => set('revenue', v)} />
            </ApplyField>
          </div>
        )}

        {step === 2 && (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>
            <ApplyField label="WHAT'S THE SINGLE BIGGEST MARKETING PROBLEM YOU'RE FACING?" required hint="Be specific — this helps us decide if Caddie is the right fit">
              <textarea value={data.goal} onChange={e => set('goal', e.target.value)} rows={4} placeholder="Honestly, I post when I remember to. There's no plan. I want a calendar I can trust and copy I don't dread writing." style={{ ...applyInputCss, resize: 'vertical', fontFamily: 'inherit', minHeight: 110 }} autoFocus/>
            </ApplyField>
            <ApplyField label="CHANNELS YOU'RE ON" required hint="Pick all that apply">
              <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
                {['Instagram', 'TikTok', 'Facebook', 'Email', 'Pinterest', 'YouTube', 'X / Twitter', 'LinkedIn', 'None yet'].map(c => {
                  const on = data.channels.includes(c);
                  return (
                    <button type="button" key={c} onClick={() => toggleChannel(c)} className="mono" style={{
                      padding: '8px 14px', borderRadius: 999, border: '1px solid var(--ink)',
                      background: on ? 'var(--ink)' : 'transparent',
                      color: on ? 'var(--paper)' : 'var(--ink)',
                      cursor: 'pointer', fontSize: 11
                    }}>{c}</button>
                  );
                })}
              </div>
            </ApplyField>
            <ApplyField label="CURRENT MARKETING STACK" hint="What tools / agencies / freelancers are you using today?">
              <textarea value={data.stack} onChange={e => set('stack', e.target.value)} rows={2} placeholder="Mailchimp, occasionally a freelancer for graphics, Shopify built-in stuff" style={{ ...applyInputCss, resize: 'vertical', fontFamily: 'inherit', minHeight: 70 }}/>
            </ApplyField>
          </div>
        )}

        {step === 3 && (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>
            <ApplyField label="ANYTHING ELSE WE SHOULD KNOW?" hint="Optional — context, deadlines, weird requests, etc.">
              <textarea value={data.biggestPain} onChange={e => set('biggestPain', e.target.value)} rows={4} placeholder="We have a big drop in July and I want a real plan in place by then." style={{ ...applyInputCss, resize: 'vertical', fontFamily: 'inherit', minHeight: 110 }} autoFocus/>
            </ApplyField>
            <div style={{ background: 'var(--ink)', color: 'var(--paper)', padding: 22, borderRadius: 10 }}>
              <div className="mono" style={{ opacity: 0.6 }}>WHAT YOU'RE SIGNING UP FOR</div>
              <ul style={{ listStyle: 'none', padding: 0, margin: '14px 0 0', display: 'flex', flexDirection: 'column', gap: 10 }}>
                {[
                  'Free beta access — every feature unlocked.',
                  '6 months free when paid plans launch.',
                  'Optional 25-minute onboarding call (or a written walkthrough).',
                  'Personal messenger — chat with the team directly.',
                  'Weekly product updates + a vote on what we build next.',
                ].map(x => (
                  <li key={x} style={{ display: 'flex', gap: 10, fontSize: 14 }}>
                    <Icon name="check" size={14} stroke={2}/><span style={{ opacity: 0.9 }}>{x}</span>
                  </li>
                ))}
              </ul>
            </div>
            <label style={{ display: 'flex', gap: 10, alignItems: 'flex-start', fontSize: 13, color: 'var(--mute-2)' }}>
              <input type="checkbox" required style={{ marginTop: 4 }}/>
              <span>I understand Caddie is in active beta — things will occasionally break. I'll report bugs. Cool.</span>
            </label>
          </div>
        )}

        {submitErr && (
          <div style={{
            marginTop: 20, background: 'rgba(200,40,40,0.07)', border: '1px solid rgba(200,40,40,0.3)',
            borderRadius: 8, padding: '10px 14px', fontSize: 13, color: '#b22222'
          }}>
            {submitErr}
          </div>
        )}

        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 32, paddingTop: 24, borderTop: '1px solid var(--hair)' }}>
          <button type="button" onClick={() => step === 0 ? go('home') : setStep(step - 1)} className="mono" style={{
            background: 'none', border: 'none', cursor: 'pointer', color: 'var(--mute-2)', padding: '8px 0'
          }}>← {step === 0 ? 'Cancel' : 'Back'}</button>

          <button type="submit" disabled={!canAdvance() || submitting} style={{
            ...ctaPrimary, border: 'none', cursor: (canAdvance() && !submitting) ? 'pointer' : 'not-allowed',
            opacity: (canAdvance() && !submitting) ? 1 : 0.4, fontFamily: 'inherit'
          }}>
            {submitting ? 'Submitting…' : (isLast ? 'Submit application' : 'Continue')} <Icon name="arrow" size={16}/>
          </button>
        </div>
      </form>

      <p className="mono" style={{ color: 'var(--mute)', textAlign: 'center', marginTop: 24 }}>
        ~90 SECONDS · ONLY 200 BETA SPOTS
      </p>
    </div>
  );
}

function ApplyField({ label, required, hint, children }) {
  return (
    <label style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
      <span style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
        <span className="mono" style={{ color: 'var(--ink)', fontWeight: 600 }}>
          {label}{required && <span style={{ color: 'var(--mute)', marginLeft: 6 }}>*</span>}
        </span>
        {hint && <span className="mono" style={{ color: 'var(--mute)' }}>{hint}</span>}
      </span>
      {children}
    </label>
  );
}

function PillRow({ value, options, onChange }) {
  return (
    <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
      {options.map(o => (
        <button type="button" key={o} onClick={() => onChange(o)} className="mono" style={{
          padding: '8px 14px', borderRadius: 999, border: '1px solid var(--ink)',
          background: value === o ? 'var(--ink)' : 'transparent',
          color: value === o ? 'var(--paper)' : 'var(--ink)',
          cursor: 'pointer', fontSize: 11
        }}>{o}</button>
      ))}
    </div>
  );
}

const applyInputCss = {
  width: '100%', padding: '13px 16px',
  border: '1px solid var(--ink)', borderRadius: 8,
  background: 'var(--paper)', fontSize: 15, fontFamily: 'inherit',
  outline: 'none', color: 'var(--ink)'
};

const ctaPrimary = {
  padding: '14px 22px', background: 'var(--ink)', color: 'var(--paper)',
  borderRadius: 999, fontSize: 14, fontWeight: 500,
  display: 'inline-flex', alignItems: 'center', gap: 8
};
const ctaGhost = {
  padding: '14px 22px', background: 'transparent', color: 'var(--ink)',
  border: '1px solid var(--ink)', borderRadius: 999, fontSize: 14, fontWeight: 500
};

// expose
Object.assign(window, {
  SupportChat, PageNav, PageFooter,
  PAGES: {
    apply: ApplyPage,
    beta: BetaPage,
    about: AboutPage,
    manifesto: ManifestoPage,
    roadmap: RoadmapPage,
    press: PressPage,
    contact: ContactPage,
    help: HelpPage,
    playbook: PlaybookPage,
    fieldguide: FieldGuidePage,
    terms: TermsPage,
    privacy: PrivacyPage,
  }
});
