/* Page sections below the hero scroll-story.
   Voice rules per docs/design/heyBob-brand-guide-v3.html and .claude/agents/bob-voice.md:
   - No em-dashes, no exclamation, no emoji, no celebration, no streaks. */

function HowItWorks(){
  // Capabilities, not steps. Bob is a presence, not a workflow. Each card
  // describes a way Bob shows up across the day, in any order. No numbering
  // (the old 01/02/03 implied sequence and locked Bob into a morning brief).
  const caps = [
    {
      title: 'Bob holds the context.',
      body: "Mail. Calendar. Slack. Teams. Court letters. School emails. Contractor invoices. Bob reads the pile and keeps the thread, so when something matters he knows why.",
    },
    {
      title: 'Bob surfaces what needs you.',
      body: 'Most of it can wait. Some of it is already handled by an agent. Bob shows you what actually needs your attention right now, not all of it at once.',
    },
    {
      title: 'You ask Bob anything.',
      body: 'A reminder. A draft. A read on something. Help thinking through a decision. Bob responds when you need him, not on a schedule.',
    },
    {
      title: 'Bob learns how you work.',
      body: "You're not a morning person. You think better at 11 PM. Some weeks are heavier than others. Bob adapts. You don't have to.",
    },
  ];
  return (
    <section className="page-section" id="how">
      <div className="eyebrow-row anim-up"><span className="num">02</span> How Bob shows up</div>
      <h2 className="anim-up delay-1">Spend less time managing your life.<br/><span className="hiw-h2-accent">More time living it.</span></h2>
      <p className="hiw-intro anim-up delay-2">
        Bob holds the context of your day. He surfaces what actually needs you, responds when you ask, and simplifies the chaos that otherwise piles up. Throughout the day, not just morning.
      </p>
      <div className="hiw-grid">
        {caps.map((s, i) => (
          <div className={`hiw-card anim-up delay-${i + 3}`} key={i}>
            <div className="hiw-title">{s.title}</div>
            <div className="hiw-body">{s.body}</div>
          </div>
        ))}
      </div>
    </section>
  );
}

function VoiceSection(){
  const lines = [
    "Quinn shipped it. You're clear to call them back.",
    "Margo wrote two drafts. Both are short. The second is better.",
    "The vendor email can wait. It's not actually due Friday.",
    "Reply to Pat first. Standup can run without you.",
  ];
  return (
    <section className="page-section voice-section" id="voice">
      <div className="eyebrow-row anim-up"><span className="num">03</span> Bob's voice</div>
      <h2 className="anim-up delay-1">Direct. Blunt. Warm underneath.</h2>
      <p className="voice-intro anim-up delay-2">Bob doesn't summarize. Bob doesn't list. Bob tells you the thing.</p>
      <div className="voice-grid">
        {lines.map((l, i) => (
          <div className={`voice-card anim-up delay-${i + 3}`} key={i}>
            <div className="mono voice-meta">Bob says · {['09:41', '10:02', '11:18', '14:30'][i]}</div>
            {/* Each word in the quote gets its own span with --i index so
                CSS can stagger the reveal. The animation runs when
                .voice-section gains .is-visible (set by the IntersectionObserver
                in app.jsx). Inline-block spans preserve native word-wrap. */}
            {/* Spaces between words are emitted as text-node siblings BETWEEN
                spans, not as trailing whitespace inside each span. Adjacent
                inline-block spans collapse trailing intra-span whitespace in
                most browsers — that bug rendered the quote as
                "Quinnshippedit.You're..." Putting the space outside the span
                preserves it as a real text-node space the browser respects. */}
            <p className="voice-line">
              {l.split(' ').flatMap((word, w, arr) => {
                const span = (
                  <span className="word" style={{ '--i': w }} key={`w-${w}`}>{word}</span>
                );
                return w < arr.length - 1 ? [span, ' '] : [span];
              })}
            </p>
          </div>
        ))}
      </div>
    </section>
  );
}

function CallToAction(){
  return (
    <section className="page-section cta-section">
      <div className="cta-card">
        <div className="eyebrow-row anim-up"><span className="num">04</span> Get heyBob</div>
        <h2 className="anim-up delay-1">Less to manage.<br/><span className="cta-accent">More to live.</span></h2>
        <p className="cta-sub anim-up delay-2">iOS alpha coming soon.<br/>macOS companion to follow later this year.</p>
        <form className="cta-form anim-up delay-3" onSubmit={async e => {
          e.preventDefault();
          const form   = e.currentTarget;
          const input  = form.querySelector('input[type="email"]');
          const button = form.querySelector('button');
          const note   = form.parentElement.querySelector('.cta-note');
          const params = new URLSearchParams(window.location.search || '');
          const email  = (input && input.value || '').trim();
          if (!email) return;
          if (note) note.textContent = "Sending the confirm link...";
          if (button) button.disabled = true;
          try {
            const r = await fetch('/api/alpha', {
              method: 'POST',
              headers: { 'Content-Type': 'application/json' },
              body: JSON.stringify({
                email,
                consent_marketing: !!(form.elements.consent_marketing && form.elements.consent_marketing.checked),
                analytics_consent: false,
                referrer: document.referrer || '',
                utm_source: params.get('utm_source') || params.get('ref') || '',
                utm_medium: params.get('utm_medium') || '',
                utm_campaign: params.get('utm_campaign') || '',
                utm_content: params.get('utm_content') || '',
                utm_term: params.get('utm_term') || '',
                website: (form.elements.website && form.elements.website.value || '').trim(),
              }),
            });
            if (!r.ok) throw new Error('status ' + r.status);
            if (note) note.textContent = "Check your inbox. Confirm link in about 30 seconds.";
            form.reset();
            if (button) button.disabled = false;
            if (window.va) window.va('event', { name: 'waitlist-signup' });
          } catch (err) {
            if (note) note.textContent = "Something glitched. Try again, or email joshua.collard@icloud.com.";
            if (button) button.disabled = false;
          }
        }}>
          <div className="cta-fields">
            <input type="email" name="email" placeholder="you@yourdomain.com" required autoComplete="email" />
            <input className="cta-hp" type="text" name="website" tabIndex="-1" autoComplete="off" aria-hidden="true" />
          </div>
          <div className="consent-block">
            <p>Confirm below to join the waitlist. Unsubscribe one click, anytime.</p>
            <label>
              <input type="checkbox" name="consent_marketing" required />
              <span>Send me waitlist and product updates from heyBob.</span>
            </label>
          </div>
          <button type="submit">Join the waitlist</button>
        </form>
        <div className="cta-note mono anim-up delay-4">Confirm link first. Updates after that.</div>
      </div>
    </section>
  );
}

function PageFooter(){
  return (
    <footer>
      <div className="anim-up">
        <span className="wordmark"><span className="hey">hey</span><span className="bob">Bob</span></span>
        <span style={{ marginLeft: 16, color: 'var(--dim)' }}>© 2026 · Less noise. More finished.</span>
      </div>
      <div className="anim-up delay-1" style={{ display: 'flex', gap: 24 }}>
        <a href="/privacy" style={{ color: 'var(--dim)', textDecoration: 'none' }}>Privacy</a>
        <a href="/terms" style={{ color: 'var(--dim)', textDecoration: 'none' }}>Terms</a>
      </div>
    </footer>
  );
}

(function injectSectionStyles(){
  if (document.getElementById('section-styles')) return;
  const css = `
    .hiw-h2-accent{ color: var(--red); }
    .hiw-intro{
      font-family: var(--serif);
      font-size: 19px;
      line-height: 1.55;
      color: var(--dim);
      max-width: 64ch;
      margin-top: 28px;
    }
    .hiw-grid{
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      gap: 20px;
      margin-top: 56px;
    }
    @media (max-width: 800px){ .hiw-grid{ grid-template-columns: 1fr; } }
    .hiw-card{
      padding: 32px 32px 30px;
      background: var(--surface);
      border-radius: 14px;
      border-left: 3px solid var(--red);
    }
    .hiw-title{
      font: 700 22px/1.2 var(--sans);
      letter-spacing: -0.02em;
      margin-bottom: 12px;
      color: var(--ink);
    }
    .hiw-body{
      font: 400 15.5px/1.6 var(--sans);
      color: var(--dim);
    }

    .voice-section{ background: var(--paper); }
    .voice-intro{
      font: 400 18px/1.5 var(--sans);
      color: var(--dim);
      margin-top: 24px;
      max-width: 56ch;
    }
    .voice-grid{
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      gap: 24px;
      margin-top: 56px;
    }
    @media (max-width: 800px){ .voice-grid{ grid-template-columns: 1fr; } }
    .voice-card{
      padding: 36px 32px;
      background: var(--surface);
      border-radius: 14px;
    }
    .voice-meta{
      color: var(--red);
      margin-bottom: 16px;
    }
    .voice-line{
      font-family: var(--serif);
      font-weight: 400;
      font-size: 26px;
      line-height: 1.35;
      letter-spacing: -0.01em;
      color: var(--ink);
      max-width: none;
    }
    /* Word-by-word reveal for voice quotes — Apple product-page treatment.
       Each word starts blurred, slightly translated down, transparent.
       When .voice-section gains .is-visible (via the IntersectionObserver
       in app.jsx), each word animates in with a per-word delay set by the
       inline --i custom property in sections.jsx. The stagger is 55ms per
       word and a 600ms ease, so a 9-word quote completes in just over 1s
       — long enough to feel deliberate, short enough not to drag. */
    .voice-line .word{
      display: inline-block;
      opacity: 0;
      transform: translateY(14px);
      filter: blur(8px);
      transition:
        opacity .6s cubic-bezier(.2,.7,.3,1),
        transform .6s cubic-bezier(.2,.7,.3,1),
        filter .6s cubic-bezier(.2,.7,.3,1);
      transition-delay: calc(var(--i, 0) * 55ms);
      will-change: opacity, transform, filter;
    }
    .voice-section.is-visible .voice-line .word{
      opacity: 1;
      transform: translateY(0);
      filter: blur(0);
    }
    @media (prefers-reduced-motion: reduce){
      .voice-line .word{
        opacity: 1;
        transform: none;
        filter: none;
        transition: none;
      }
    }

    .cta-section{ padding-top: 80px; padding-bottom: 80px; }
    .cta-card{
      background: var(--ink);
      color: #fff;
      border-radius: 24px;
      padding: 80px 60px;
      position: relative;
      overflow: hidden;
    }
    .cta-card::before{
      content: '';
      position: absolute;
      right: -120px; top: -120px;
      width: 400px; height: 400px;
      background: radial-gradient(circle, rgba(65,182,230,0.5), transparent 60%);
    }
    .cta-card::after{
      content: '';
      position: absolute;
      left: -80px; bottom: -120px;
      width: 320px; height: 320px;
      background: radial-gradient(circle, rgba(200,16,46,0.3), transparent 60%);
    }
    .cta-card .eyebrow-row{ color: rgba(255,255,255,0.6); }
    .cta-card .eyebrow-row .num{ border-color: rgba(255,255,255,0.2); color: #fff; }
    .cta-card h2{ color: #fff; position: relative; z-index: 1; max-width: none; }
    .cta-accent{ color: var(--blue); }
    .cta-sub{
      color: rgba(255,255,255,0.7);
      font-size: 17px;
      margin-top: 24px;
      max-width: 48ch;
      position: relative; z-index: 1;
    }
    .cta-form{
      display: grid;
      gap: 14px;
      margin-top: 36px;
      max-width: 620px;
      position: relative; z-index: 1;
    }
    .cta-fields{
      display: grid;
      grid-template-columns: 1fr;
      gap: 12px;
    }
    .cta-form input,
    .cta-form textarea{
      width: 100%;
      padding: 14px 18px;
      border-radius: 10px;
      border: 1px solid rgba(255,255,255,0.18);
      background: rgba(255,255,255,0.06);
      color: #fff;
      /* 16px is the iOS Safari zoom-on-focus threshold. Anything below
         triggers a viewport zoom when the field gets focus on iPhone. */
      font: 400 16px var(--sans);
      outline: none;
    }
    .cta-form input::placeholder,
    .cta-form textarea::placeholder{ color: rgba(255,255,255,0.4); }
    .cta-form input:focus,
    .cta-form textarea:focus{ border-color: var(--blue); }
    .cta-hp{ position: absolute; left: -9999px; opacity: 0; }
    .consent-block{
      display: grid;
      gap: 10px;
      color: rgba(255,255,255,0.72);
      font: 400 13px/1.45 var(--sans);
    }
    .consent-block p{ margin: 0 0 2px; color: rgba(255,255,255,0.68); }
    .consent-block label{
      display: grid;
      grid-template-columns: 18px 1fr;
      gap: 10px;
      align-items: start;
    }
    .consent-block input{ width: 16px; height: 16px; padding: 0; margin-top: 2px; accent-color: var(--blue); }
    .cta-form button{
      padding: 14px 24px;
      border-radius: 10px;
      background: var(--red);
      color: #fff;
      border: 0;
      font: 600 14px var(--sans);
      cursor: pointer;
      transition: background .15s;
    }
    .cta-form button:hover{ background: var(--red-deep); }
    .cta-form button:disabled{ opacity: .62; cursor: default; }
    .cta-note{
      margin-top: 18px;
      color: rgba(255,255,255,0.5);
      position: relative; z-index: 1;
    }
    @media (max-width: 640px){
      .cta-fields{ grid-template-columns: 1fr; }
    }
  `;
  const tag = document.createElement('style');
  tag.id = 'section-styles';
  tag.textContent = css;
  document.head.appendChild(tag);
})();

window.HowItWorks = HowItWorks;
window.VoiceSection = VoiceSection;
window.CallToAction = CallToAction;
window.PageFooter = PageFooter;
