/* Pages for Viktor Zaharov site */
const { useState: useStateP, useEffect: useEffectP, useRef: useRefP } = React;

/* ------------------------------------------------------------------ *
 *  KIT (formerly ConvertKit) NEWSLETTER INTEGRATION
 *  -----------------------------------------------------------------
 *  Signups from the homepage Newsletter form and the Contact form's
 *  "Join the weekly email" checkbox are POSTed to Kit's public form
 *  endpoint:  https://app.kit.com/forms/{FORM_ID}/subscriptions
 *
 *  Kit's built-in subscriber attributes:
 *    email_address  (required)
 *    first_name
 *
 *  Custom fields (must be created in Kit → Subscribers → settings):
 *    fields[last_name]   – text
 *    fields[topic]       – text (comma-joined when multiple selected)
 *
 *  If a custom field doesn't exist yet in Kit, Kit silently ignores it
 *  (no error), so the basic email + first_name capture works either way.
 *  Add the custom fields whenever you want; the values will start being
 *  saved automatically — no code change needed.
 *
 *  TO ROTATE TO A DIFFERENT KIT FORM: replace KIT_FORM_ID below with the
 *  number from your form's URL: app.kit.com/forms/XXXXXXX/edit
 * ------------------------------------------------------------------ */
const KIT_FORM_ID = '9476202'; // Website signup form (Viktor's Kit account)
const KIT_FORM_ENDPOINT = KIT_FORM_ID ? `https://app.kit.com/forms/${KIT_FORM_ID}/subscriptions` : '';
const KIT_LIVE = KIT_FORM_ID && KIT_FORM_ID.length > 0;

// Pure-function helper: posts a signup to Kit. Returns a Promise that
// resolves true on success, false on any error (network or Kit error).
// Both the Newsletter section and the Contact form call this.
async function kitSubscribe({ email, firstName, lastName, topic }) {
  if (!KIT_LIVE || !email) return false;
  try {
    const fd = new FormData();
    fd.append('email_address', email);
    if (firstName) fd.append('first_name', firstName);
    if (lastName) fd.append('fields[last_name]', lastName);
    if (topic) fd.append('fields[topic]', topic);
    const res = await fetch(KIT_FORM_ENDPOINT, { method: 'POST', body: fd });
    return res.ok;
  } catch (err) {
    return false;
  }
}

// Free guide download (post-confirmation link)
// ⚠ DEV NOTE: This URL points to the live Squarespace-hosted PDF.
// If the link is broken, re-upload the file in Squarespace and paste the new URL here.
// To use a local file instead: add free-guide.pdf to /assets and set the path to 'assets/free-guide.pdf'.
const FREE_GUIDE_PDF = 'https://viktorzaharov.com/s/Free-Guide-To-Time-Management.pdf';
const FREE_GUIDE_LIVE = FREE_GUIDE_PDF && !FREE_GUIDE_PDF.includes('PASTE_') && FREE_GUIDE_PDF.length > 0;

/* ------------------------------------------------------------------ *
 *  ACUITY SCHEDULING INTEGRATION
 *  -----------------------------------------------------------------
 *  Every booking button on the site reads from this single config.
 *  Swap the URLs below once you have them from Acuity.
 *
 *  HOW TO GET THE URLS:
 *    1. Log into Acuity → Appointment Types → click each type.
 *    2. Open "Direct scheduling link" — copy the full URL.
 *    3. Paste it into the matching slot below.
 *
 *  URL shape Acuity gives you looks like:
 *    https://app.acuityscheduling.com/schedule.php?owner=12345678&appointmentType=87654321
 *    (or your branded variant: https://viktorzaharov.as.me/30min)
 *
 *  Until the placeholder strings are replaced, the buttons still work —
 *  they fall back to scrolling to the contact form on /contact so the
 *  site never has a dead-link.
 * ------------------------------------------------------------------ */
const ACUITY = {
  video: {
    // 30-minute Video Editing review (free)
    url: 'https://viktorzaharov.as.me/Videocreation',
    label: 'Book 30-min video review',
    shortLabel: 'Video review · 30 min',
    duration: '30 min',
    price: 'Free',
    desc: 'Send a video or channel — I review thumbnails, hooks, retention, and the levers that move CTR.'
  },
  coaching: {
    // 90-minute Coaching deep-dive (free intro)
    url: 'https://viktorzaharov.as.me/FirstStep',
    label: 'Book 90-min coaching call',
    shortLabel: 'Coaching deep-dive · 90 min',
    duration: '90 min',
    price: 'Free intro',
    desc: 'For trucking and personal-development work. We map where you are, where you want to go, and the next 90 days.'
  }
};
// True once you've replaced the placeholder strings above.
const ACUITY_LIVE = (k) => !ACUITY[k].url.includes('PASTE_') && ACUITY[k].url.length > 0;

/* ------------------------------------------------------------------ *
 *  CONTACT FORM BACKEND
 *  -----------------------------------------------------------------
 *  Submissions land in viktorzaharov@pm.me. Two layers:
 *
 *   1. PRIMARY — Formspree (https://formspree.io). Sign up free, create a
 *      form pointed at viktorzaharov@pm.me, copy the form ID (looks like
 *      "xnqkglyz") and paste below. Free tier: 50 submissions/month.
 *
 *   2. FALLBACK — mailto: link. Opens the visitor's email client with
 *      the message pre-filled. Used when Formspree returns an error
 *      OR when CONTACT_FORMSPREE_ID is left blank.
 *
 *  HOW TO GET A FORMSPREE ID (one-time, ~2 min):
 *    1. Go to https://formspree.io → Sign up with viktorzaharov@pm.me
 *    2. New Form → name it "Website Contact" → save
 *    3. Copy the hashid from the form URL (the part after /forms/)
 *    4. Paste it below. That's it.
 * ------------------------------------------------------------------ */
const CONTACT_FORMSPREE_ID = 'mnjrpvwp'; // <-- paste your Formspree form ID here (e.g. "xnqkglyz")
const CONTACT_EMAIL = 'viktorzaharov@pm.me';
const CONTACT_FORMSPREE_LIVE = CONTACT_FORMSPREE_ID && CONTACT_FORMSPREE_ID.length > 0;
// Build a mailto URL pre-filled with the form's contents — used as fallback.
function buildContactMailto({ first, last, email, msg, list }) {
  const subject = `Coaching enquiry — ${first || ''} ${last || ''}`.trim();
  const body =
`Name: ${first || ''} ${last || ''}
Email: ${email || ''}
Newsletter opt-in: ${list || '—'}

Message:
${msg || ''}
`;
  return `mailto:${CONTACT_EMAIL}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;
}

const ORANGE_OPTIONS = {
  rust: { o: '#c64a23', s: '#e07050', d: '#8a3014' },
  signal: { o: '#e5532a', s: '#f08152', d: '#b13a17' },
  blood: { o: '#d63916', s: '#e8643a', d: '#931f08' },
  amber: { o: '#ef7a2e', s: '#f59556', d: '#bf5a18' }
};

/* ---- BookButton — every call-to-book CTA on the site reads from ACUITY config ---- *
 * Props:
 *   kind: 'video' | 'coaching'                            (required)
 *   variant: 'primary' | 'ghost' | 'dark'                 (default primary)
 *   size: 'md' | 'sm'                                     (default md)
 *   label: override the default label string              (optional)
 *   onClickFallback: called when ACUITY isn't live yet    (e.g. () => setPage('contact'))
 *   style/className: passthrough
 *
 * Behaviour: opens Acuity in a new tab if live; otherwise calls the fallback
 * (or scrolls to /contact) so the button is never dead. */
function BookButton({ kind, variant = 'primary', size = 'md', label, onClickFallback, style, className, children }) {
  const cfg = ACUITY[kind];
  const live = ACUITY_LIVE(kind);
  const txt = children || label || cfg.label;
  const cls = ['btn'];
  if (variant === 'primary') cls.push('btn-primary');
  if (variant === 'ghost') cls.push('btn-ghost');
  if (variant === 'dark') cls.push('btn-dark');
  if (size === 'sm') cls.push('btn-sm');
  if (className) cls.push(className);
  // If live, render as anchor — opens Acuity in new tab. If not, render as button → fallback.
  if (live) {
    return (
      <a href={cfg.url} target="_blank" rel="noopener noreferrer" className={cls.join(' ')} style={style} data-acuity-kind={kind}>
        {txt} <span className="arrow">→</span>
      </a>);
  }
  return (
    <button className={cls.join(' ')} style={style} data-acuity-kind={kind} onClick={(e) => { if (onClickFallback) onClickFallback(e); }}>
      {txt} <span className="arrow">→</span>
    </button>);
}

/* Small mono-style inline link — used under hero CTAs as a tertiary booking option */
function BookButtonLink({ kind, onClickFallback }) {
  const cfg = ACUITY[kind];
  const live = ACUITY_LIVE(kind);
  const txt = `or quick ${cfg.duration.toLowerCase()} ${kind === 'video' ? 'video review' : 'coaching call'} · ${cfg.price.toLowerCase()}`;
  const sx = { fontFamily: "'JetBrains Mono', monospace", fontSize: 11, letterSpacing: '0.14em', color: 'var(--text-mute)', textTransform: 'uppercase', textDecoration: 'none', display: 'inline-flex', alignItems: 'center', gap: 6, cursor: 'pointer', background: 'transparent', border: 0, padding: 0 };
  if (live) {
    return (
      <a href={cfg.url} target="_blank" rel="noopener noreferrer" style={sx} data-acuity-kind={kind}>
        {txt} <span style={{ color: 'var(--orange)' }}>→</span>
      </a>);
  }
  return (
    <button style={sx} onClick={onClickFallback} data-acuity-kind={kind}>
      {txt} <span style={{ color: 'var(--orange)' }}>→</span>
    </button>);
}

/* ============ HOME ============ */
function HomePage({ setPage, tweaks, mobile }) {
  return (
    <div className="fade-in">
      <Hero setPage={setPage} variant={tweaks.heroVariant} mobile={mobile} />
      <Marquee items={['Stop drifting', 'Build with intent', 'Trucking → Freedom', 'YouTube growth', 'Self-mastery', 'Discipline > Motivation', 'Long-haul mindset', 'Show up daily']} />
      <Credibility mobile={mobile} />
      <Offers setPage={setPage} mobile={mobile} />
      <PodcastStrip mobile={mobile} />
      <Testimonials mobile={mobile} setPage={setPage} />
      <Community mobile={mobile} setPage={setPage} />
      <Newsletter mobile={mobile} />
      <FAQ mobile={mobile} />
      <FinalCTA setPage={setPage} mobile={mobile} />
    </div>);

}

function Hero({ setPage, variant, mobile }) {
  // variant: 'split' | 'fullbleed' | 'editorial'
  if (variant === 'fullbleed') {
    return (
      <section style={{ position: 'relative', minHeight: mobile ? '92vh' : '92vh', overflow: 'hidden', background: 'var(--bg)' }}>
        <img src="assets/hero-bg-fullbleed.png" alt="Viktor Zaharov" loading="eager" decoding="async" fetchpriority="high" draggable="false" onError={(e)=>{e.currentTarget.style.display='none';}} style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', objectPosition: mobile ? '70% center' : 'right center', opacity: 0.85 }} />
        <div style={{ position: 'absolute', inset: 0, background: mobile ? 'linear-gradient(180deg, rgba(10,9,8,0.4), rgba(10,9,8,0.95))' : 'linear-gradient(90deg, rgba(10,9,8,0.92) 0%, rgba(10,9,8,0.6) 50%, transparent 100%)' }}></div>
        <div className="wrap" style={{ position: 'relative', zIndex: 2, paddingTop: mobile ? 60 : 140, paddingBottom: mobile ? 40 : 120 }}>
          <div style={{ maxWidth: 720 }}>
            <div className="tag" style={{ marginBottom: 24 }}><span className="dot"></span> Coaching · 1:1 + Cohort</div>
            <h1 className="display" style={{ fontSize: mobile ? 'clamp(40px, 11vw, 56px)' : 'clamp(64px, 9vw, 132px)', margin: 0 }}>
              Stop drifting.<br /><span style={{ color: 'var(--orange)' }}>{mobile ? <>Start<br />building.</> : 'Start building.'}</span>
            </h1>
            <p style={{ color: 'var(--text-mute)', fontSize: mobile ? 17 : 22, lineHeight: 1.4, maxWidth: 540, marginTop: 32 }}>
              For anyone tired of autopilot. I'll help you build discipline, momentum, and a life with weight to it.
            </p>
            <div style={{ display: 'flex', gap: 12, marginTop: 40, flexWrap: 'wrap' }}>
              <BookButton kind="coaching" onClickFallback={() => setPage('contact')}>Book 90-min coaching call</BookButton>
              <button className="btn btn-ghost" onClick={() => setPage('programs')}>See the programs</button>
            </div>
            <div style={{ marginTop: 14 }}>
              <BookButtonLink kind="video" onClickFallback={() => setPage('contact')} />
            </div>
          </div>
        </div>
        <HeroFootBar />
      </section>);

  }
  if (variant === 'editorial') {
    return (
      <section style={{ background: 'var(--bg)', paddingTop: mobile ? 40 : 80, paddingBottom: mobile ? 40 : 60, position: 'relative' }}>
        <div className="wrap">
          <div style={{ display: 'grid', gridTemplateColumns: mobile ? '1fr' : '1fr 1fr', gap: mobile ? 32 : 60, alignItems: 'center' }}>
            <div style={{ order: mobile ? 2 : 1 }}>
              <div className="tag" style={{ marginBottom: 24 }}><span className="dot"></span> COACHING · EST. 2024</div>
              <p className="serif-i" style={{ fontSize: mobile ? 22 : 30, color: 'var(--text-mute)', margin: 0, marginBottom: 24, lineHeight: 1.2 }}>
                Most people spend their best years asleep at the wheel.
              </p>
              <h1 className="display" style={{ fontSize: mobile ? 'clamp(38px, 10.5vw, 52px)' : 'clamp(60px, 7vw, 96px)', margin: 0 }}>
                Stop drifting.<br />Start <span style={{ color: 'var(--orange)' }}>building</span>.
              </h1>
              <p style={{ color: 'var(--text-mute)', fontSize: mobile ? 16 : 18, lineHeight: 1.55, marginTop: 28, maxWidth: 480 }}>
                Trucking career coaching. YouTube growth. Personal upgrade. Three ways to break out of autopilot — pick the one that gets you moving.
              </p>
              <div style={{ display: 'flex', gap: 12, marginTop: 32, flexWrap: 'wrap' }}>
                <BookButton kind="coaching" onClickFallback={() => setPage('contact')}>Book 90-min coaching call</BookButton>
                <button className="btn btn-ghost" onClick={() => setPage('programs')}>Programs</button>
              </div>
              <div style={{ marginTop: 14 }}>
                <BookButtonLink kind="video" onClickFallback={() => setPage('contact')} />
              </div>
            </div>
            <div style={{ order: mobile ? 1 : 2, position: 'relative' }}>
              <Photo eager src="assets/hero-editorial-portrait.png" alt="Viktor Zaharov" ratio="4/5" tag="VIKTOR ZAHAROV · COACHING" style={{ borderRadius: 18 }} />
              {/* Decorative offset frame — desktop only; on mobile its negative offsets push past the column gutter and create a visible sliver of overflow. */}
              {!mobile && <div aria-hidden="true" style={{ position: 'absolute', top: -12, left: -12, right: 12, bottom: 12, border: '1px solid var(--orange)', borderRadius: 18, zIndex: -1 }}></div>}
            </div>
          </div>
        </div>
      </section>);

  }
  // default: split — clean modern minimal premium
  return (
    <section style={{ background: 'var(--bg)', paddingTop: mobile ? 32 : 64, paddingBottom: mobile ? 32 : 64 }}>
      <div className="wrap" style={{ minHeight: mobile ? 'auto' : 720 }}>
        <div style={{ display: 'grid', gridTemplateColumns: mobile ? '1fr' : '1.15fr 1fr', gap: mobile ? 28 : 48, alignItems: 'stretch' }}>
          <div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'space-between', minHeight: mobile ? 'auto' : 600 }}>
            <div>
              <div className="tag" style={{ marginBottom: 28 }}><span className="dot"></span> NOW BOOKING · Q2 2026</div>
              <h1 className="display" style={{ fontSize: mobile ? 'clamp(40px, 11vw, 56px)' : 'clamp(68px, 8vw, 124px)', margin: 0, marginBottom: 24 }}>
                Stop<br />drifting.<br /><span style={{ color: 'var(--orange)' }}>{mobile ? <>Start<br />building.</> : 'Start building.'}</span>
              </h1>
              <p style={{ color: 'var(--text-mute)', fontSize: mobile ? 17 : 20, lineHeight: 1.45, maxWidth: 520, margin: 0 }}>
                I'm Viktor — long-haul driver turned coach. I help people trade autopilot living for discipline, momentum, and a life that <span className="serif-i" style={{ color: 'var(--text)' }}>actually means something</span>.
              </p>
              <div style={{ display: 'flex', gap: 12, marginTop: 36, flexWrap: 'wrap' }}>
                <BookButton kind="coaching" onClickFallback={() => setPage('contact')}>Book 90-min coaching call</BookButton>
                <button className="btn btn-ghost" onClick={() => setPage('programs')}>See the programs</button>
              </div>
              <div style={{ marginTop: 14 }}>
                <BookButtonLink kind="video" onClickFallback={() => setPage('contact')} />
              </div>
            </div>
            {!mobile &&
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 24, marginTop: 48, paddingTop: 32, borderTop: '1px solid var(--line)' }}>
                <MiniStat n="6" l="years on the road" suffix="yr" />
                <MiniStat n="10" l="podcast appearances" suffix="+" />
                <MiniStat n="100%" l="of clients still in motion" />
              </div>
            }
          </div>
          <div style={{ position: 'relative', minHeight: mobile ? 420 : 600, borderRadius: 20, overflow: 'hidden' }}>
            <img src="assets/hero-split-bg.png" alt="Viktor Zaharov" loading="eager" decoding="async" fetchpriority="high" draggable="false" onError={(e)=>{e.currentTarget.style.display='none';}} style={{ position: 'absolute', inset: 0, objectFit: 'cover', objectPosition: 'center', width: '100%', height: '100%' }} />
            <div style={{ position: 'absolute', inset: 0, background: "linear-gradient(180deg, rgba(10,9,8,0.15) 0%, rgba(10,9,8,0.45) 60%, rgba(10,9,8,0.92) 100%)" }}></div>
            <div style={{ position: 'relative', zIndex: 2, height: '100%', minHeight: mobile ? 420 : 600, display: 'flex', flexDirection: 'column', justifyContent: 'flex-end', padding: 24, textAlign: 'center', lineHeight: 1.4 }}>
              <div className="mono" style={{ fontSize: 11, color: 'rgba(255,255,255,0.7)', letterSpacing: '0.18em' }}>VIKTOR ZAHAROV</div>
              <div style={{ fontSize: 14, color: 'rgba(255,255,255,0.6)', marginTop: 6 }}>Coach · Driver · Builder</div>
            </div>
          </div>
        </div>
        {mobile &&
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 12, marginTop: 24, paddingTop: 24, borderTop: '1px solid var(--line)' }}>
            <MiniStat n="6" l="yrs road" suffix="yr" />
            <MiniStat n="10" l="podcasts" suffix="+" />
            <MiniStat n="100%" l="in motion" />
          </div>
        }
      </div>
    </section>);

}

function MiniStat({ n, l, suffix }) {
  return (
    <div>
      <div className="display num" style={{ fontSize: 'clamp(28px, 4vw, 44px)', lineHeight: 1 }}>{n}<span style={{ color: 'var(--orange)' }}>{suffix || ''}</span></div>
      <div style={{ color: 'var(--text-mute)', fontSize: 12, marginTop: 6, textTransform: 'uppercase', letterSpacing: '0.08em' }}>{l}</div>
    </div>);

}

function HeroFootBar() {
  return (
    <div style={{ position: 'absolute', left: 0, right: 0, bottom: 0, zIndex: 3, borderTop: '1px solid var(--line)', background: 'rgba(0,0,0,0.5)', backdropFilter: 'blur(8px)' }}>
      <div className="wrap" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: 12, paddingTop: 16, paddingBottom: 16 }}>
        <div className="mono" style={{ fontSize: 11, color: 'var(--text-mute)', letterSpacing: '0.18em' }}>SCROLL ↓</div>
        <div className="mono" style={{ fontSize: 11, color: 'var(--text-mute)', letterSpacing: '0.18em' }}>EST. 2024 · NORTH YORK, ON</div>
      </div>
    </div>);

}

function Credibility({ mobile }) {
  return (
    <section style={{ padding: mobile ? '60px 0' : '120px 0', background: 'var(--bg)' }}>
      <div className="wrap">
        <SectionHead num="01" kicker="Receipts, not promises" title={<>The work,<br />not the talk.</>} sub="Six years driving across North America. Two coaching clients in active partnership. Ten podcast appearances. One community of men who showed up — and stayed." />
        <div style={{ display: 'grid', gridTemplateColumns: mobile ? 'repeat(2,1fr)' : 'repeat(4,1fr)', gap: mobile ? 20 : 40, borderTop: '1px solid var(--line)', borderBottom: '1px solid var(--line)', padding: '8px 0' }}>
          <Stat value="6" suffix="yr" label="Long-haul on the road — the school nobody applies to." />
          <Stat value="10" suffix="+" label="Podcast appearances — the message keeps landing." />
          <Stat value="2" suffix="" label="Coaching clients in active partnership." />
          <Stat value="∞" suffix="" label="Conversations with people who stopped drifting." />
        </div>
        <div style={{ marginTop: 48, display: 'grid', gridTemplateColumns: mobile ? '1fr' : '1.4fr 1fr', gap: 32, alignItems: 'center' }}>
          <p className="serif-i" style={{ fontSize: mobile ? 22 : 32, color: 'var(--text)', margin: 0, lineHeight: 1.25, letterSpacing: '-0.01em' }}>
            "I'm not a guru. I'm a guy who refused to fall asleep at the wheel — and now I help others do the same."
          </p>
          <div style={{ textAlign: mobile ? 'left' : 'right' }}>
            <div className="mono" style={{ fontSize: 11, letterSpacing: '0.16em', color: 'var(--text-mute)' }}>— VIKTOR ZAHAROV</div>
            <div className="mono" style={{ fontSize: 11, letterSpacing: '0.16em', color: 'var(--text-dim)', marginTop: 4 }}>FOUNDER · COACH</div>
          </div>
        </div>
      </div>
    </section>);

}

function Offers({ setPage, mobile }) {
  const offers = [
  { tag: '01 · SELF-UPGRADE', title: 'Build boundaries. Find peace.', desc: 'For anyone who has everything except direction. We rebuild your week, your routines, and the rules you live by.', bullets: ['Boundaries that hold', 'Time management that works', 'Emotional resilience', 'Productivity with peace of mind'], img: 'assets/program-1-self.png' },
  { tag: '02 · TRUCKING', title: 'A new path through trucking.', desc: 'Use the road as a tool. Stack real savings, learn the discipline of long-haul, and build your exit from wherever you\'re stuck.', bullets: ['Find the right company', 'Live efficiently in the truck', 'Stack real savings with intent', 'Build the routines that hold'], img: 'assets/program-2-trucking.png' },
  { tag: '03 · YOUTUBE GROWTH', title: 'Build a channel that actually grows.', desc: 'Most creators die in the first 100 videos. I\'ll show you the frameworks that compound — set up, retention, thumbnails, hooks.', bullets: ['Set up for growth from day one', 'Hooks, retention, CTR', 'Build a content engine', 'Frameworks I use myself'], img: 'assets/program-3-youtube.png' },
  { tag: '04 · VIDEO EDITING', title: 'Send raw. Receive polished.', desc: 'Send your raw recording. Viktor edits it into a professional, publish-ready video — hooks, pacing, retention cuts, thumbnail. You film; he does the rest.', bullets: ['Professional edit from your raw footage', 'Hooks, pacing, retention cuts', 'Thumbnails and titles that earn clicks', 'Fast turnaround, publish-ready'], img: 'assets/program-4-editing.png' },
  { tag: '05 · MEET-UPS & EVENTS', title: 'You bring the people. I run the room.', desc: 'Retreats, offsites, private meet-ups — venue to vendors to day-of execution. You bring the vision. I make it real.', bullets: ['Venue and vendor sourcing', 'Guest comms and logistics', 'Itinerary and on-site management', 'Budget tracking, end-to-end'], img: 'assets/program-5-events.png' }];

  const [idx, setIdx] = useStateP(0);
  const [paused, setPaused] = useStateP(false);
  const n = offers.length;
  const go = (d) => setIdx((i) => (i + d + n) % n);
  const o = offers[idx];

  useEffectP(() => {
    if (paused) return;
    const id = setInterval(() => setIdx((i) => (i + 1) % n), 7000);
    return () => clearInterval(id);
  }, [paused, n]);

  return (
    <section onMouseEnter={() => setPaused(true)} onMouseLeave={() => setPaused(false)} style={{ padding: mobile ? '60px 0' : '120px 0', background: 'var(--bg-2)', borderTop: '1px solid var(--line)', borderBottom: '1px solid var(--line)' }}>
      <div className="wrap">
        <SectionHead num="02" kicker="Five doors. One shift." title={<>What can I help<br />you with?</>} sub="Five programs, each built for a different kind of stuck. Swipe through — or get on a call and we'll find which one fits." />

        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: mobile ? 20 : 28, gap: 16, flexWrap: 'wrap' }}>
          <div className="mono" style={{ fontSize: 11, color: 'var(--text-mute)', letterSpacing: '0.16em' }}>{String(idx + 1).padStart(2, '0')} / {String(n).padStart(2, '0')}</div>
          <div style={{ display: 'flex', gap: 8 }}>
            <button onClick={() => go(-1)} aria-label="Previous" className="nav-arrow ghost">←</button>
            <button onClick={() => go(1)} aria-label="Next" className="nav-arrow solid" style={{ fontWeight: 700 }}>→</button>
          </div>
        </div>

        <div key={idx} className="card offer-card fade-in" onClick={() => setPage('programs')} style={{ cursor: 'pointer', maxWidth: 760, margin: '0 auto', padding: 0, overflow: 'hidden' }}>
          <div className="glow"></div>
          <Photo src={o.img} alt={o.title} ratio={mobile ? '16/10' : '16/9'} style={{ borderRadius: 0, marginBottom: 0 }} />
          <div style={{ padding: mobile ? '28px 24px 32px' : '40px 48px 44px' }}>
            <div className="mono" style={{ fontSize: 11, color: 'var(--orange)', letterSpacing: '0.18em', marginBottom: 18 }}>{o.tag}</div>
            <h3 className="display" style={{ fontSize: mobile ? 32 : 44, lineHeight: 1.08, margin: 0, marginBottom: 20, letterSpacing: '-0.02em', textWrap: 'balance' }}>{o.title}</h3>
            <p style={{ color: 'var(--text-mute)', fontSize: mobile ? 16 : 18, lineHeight: 1.6, margin: 0, marginBottom: 28, textWrap: 'pretty', maxWidth: 580 }}>{o.desc}</p>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', paddingTop: 20, borderTop: '1px solid var(--line)' }}>
              <span style={{ fontSize: 14, color: 'var(--text)', fontWeight: 600 }}>Explore program</span>
              <span style={{ color: 'var(--orange)', fontSize: 20 }}>→</span>
            </div>
          </div>
        </div>

        <div style={{ display: 'flex', gap: 8, justifyContent: 'center', marginTop: mobile ? 28 : 40 }}>
          {offers.map((_, i) =>
          <button key={i} className="dot-btn" onClick={(e) => { e.stopPropagation(); setIdx(i); }} aria-label={`Go to program ${i + 1}`} style={{ width: i === idx ? 28 : 8, background: i === idx ? 'var(--orange)' : 'var(--line-strong)', padding: 0 }} />
          )}
        </div>
      </div>
    </section>);

}

function PodcastStrip({ mobile }) {
  const CHANNEL = 'https://youtube.com/@viktortimewolf';
  // TODO: replace titles + guests with the real text from each video.
  // Thumbnails are already live — they pull from YouTube's CDN using each video ID.
  // To reorder: put the most recent episode first.
  const episodes = [
  { id: 'xbaNUCtHpXM', ep: 'EP. 10', title: 'Why Most Men Fail in Relationships (And How to Fix It)', guest: 'TC', url: 'https://www.youtube.com/watch?v=xbaNUCtHpXM' },
  { id: 'C6GsTD4dJ8I', ep: 'EP. 09', title: 'Could Saying "No" Save Your Career?', guest: 'Denis Ulanov', url: 'https://www.youtube.com/watch?v=C6GsTD4dJ8I' },
  { id: 'Ye_qL6FTtIg', ep: 'EP. 08', title: 'This Is What Happens When You Travel Without Insurance!', guest: 'Michael Modelevsky', url: 'https://www.youtube.com/watch?v=Ye_qL6FTtIg' },
  { id: 'KLOkNu0yMd8', ep: 'EP. 07', title: 'From Nobody to 21K Subs: My Biggest YouTube Secret!', guest: 'Sean Ficken', url: 'https://www.youtube.com/watch?v=KLOkNu0yMd8' },
  { id: '5fKPbzXD4Ls', ep: 'EP. 06', title: 'He Lost Everything — Then Built An Empire!', guest: 'Nick Pitruzzello', url: 'https://www.youtube.com/watch?v=5fKPbzXD4Ls' },
  { id: 'bEiKMEhQHx4', ep: 'EP. 05', title: 'Are You Ignoring the Signs of Poor Health?', guest: 'George Tsakiris', url: 'https://www.youtube.com/watch?v=bEiKMEhQHx4' },
  { id: 'yVu9kwuvVQs', ep: 'EP. 04', title: "What's Stopping You from Delegating Financial Stress?", guest: 'Svetlana Strizheva', url: 'https://www.youtube.com/watch?v=yVu9kwuvVQs' },
  { id: 'n2Bd7Y0yH0U', ep: 'EP. 03', title: 'How to Choose a Signature Scent', guest: 'Dimitri Ressin', url: 'https://www.youtube.com/watch?v=n2Bd7Y0yH0U' },
  { id: 'GX_QtNXyP9M', ep: 'EP. 02', title: 'How to Unlock Your Inner Power and Take Control of Your Life?', guest: 'Brian Dyer', url: 'https://www.youtube.com/watch?v=GX_QtNXyP9M' },
  { id: 'sCGcbk5eZ-M', ep: 'EP. 01', title: 'Could Instagram Mastery Improve Your Future in Dating?', guest: 'Spencer Keene', url: 'https://www.youtube.com/watch?v=sCGcbk5eZ-M' },
  ];

  const perPage = mobile ? 1 : 2;
  const pages = [];
  for (let i = 0; i < episodes.length; i += perPage) pages.push(episodes.slice(i, i + perPage));
  const n = pages.length;

  const [idx, setIdx] = useStateP(0);
  const [paused, setPaused] = useStateP(false);
  const [playing, setPlaying] = useStateP(null);
  const go = (d) => setIdx((i) => (i + d + n) % n);

  useEffectP(() => {
    if (paused) return;
    const id = setInterval(() => setIdx((i) => (i + 1) % n), 5000);
    return () => clearInterval(id);
  }, [paused, n]);

  useEffectP(() => {
    const onKey = (e) => { if (e.key === 'Escape') setPlaying(null); };
    document.addEventListener('keydown', onKey);
    return () => document.removeEventListener('keydown', onKey);
  }, []);

  const current = pages[Math.min(idx, n - 1)] || [];

  return (
    <React.Fragment>
      {/* Video lightbox */}
      {playing && (
        <div
          onClick={() => setPlaying(null)}
          style={{
            position: 'fixed', inset: 0, zIndex: 9999,
            background: 'rgba(10,9,8,0.92)', backdropFilter: 'blur(10px)',
            display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
            padding: mobile ? 16 : 40,
          }}
        >
          <div
            onClick={(e) => e.stopPropagation()}
            style={{ width: '100%', maxWidth: 900, display: 'flex', flexDirection: 'column', gap: 16 }}
          >
            {/* Header */}
            <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 16 }}>
              <div>
                <div className="mono" style={{ fontSize: 10.5, color: 'var(--orange)', letterSpacing: '0.18em', marginBottom: 6 }}>{playing.ep}</div>
                <div style={{ fontSize: mobile ? 17 : 20, fontWeight: 600, color: 'var(--text)', lineHeight: 1.25 }}>{playing.title}</div>
              </div>
              <button
                onClick={() => setPlaying(null)}
                aria-label="Close"
                style={{ flexShrink: 0, width: 36, height: 36, borderRadius: '50%', border: '1px solid var(--line-strong)', background: 'transparent', color: 'var(--text-mute)', fontSize: 18, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center' }}
              >✕</button>
            </div>
            {/* Embed */}
            <div style={{ position: 'relative', paddingBottom: '56.25%', background: '#000', borderRadius: 10, overflow: 'hidden' }}>
              <iframe
                src={`https://www.youtube-nocookie.com/embed/${playing.id}?autoplay=1&rel=0`}
                allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
                allowFullScreen
                style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', border: 'none' }}
                title={playing.title}
              ></iframe>
            </div>
            {/* Footer */}
            <div style={{ display: 'flex', justifyContent: 'flex-end' }}>
              <a href={playing.url} target="_blank" rel="noreferrer" style={{ fontSize: 13, color: 'var(--text-mute)', textDecoration: 'none', display: 'flex', alignItems: 'center', gap: 6 }}>
                Open on YouTube <span style={{ color: 'var(--orange)' }}>↗</span>
              </a>
            </div>
          </div>
        </div>
      )}

      <section onMouseEnter={() => setPaused(true)} onMouseLeave={() => setPaused(false)} style={{ padding: mobile ? '60px 0' : '100px 0', background: 'var(--bg)' }}>
        <div className="wrap">
          <SectionHead num="03" kicker="The Viktor Time Wolf Podcast" title={<>Where I've shown up.</>} sub={<>Long-form conversations on YouTube. <a href={CHANNEL} target="_blank" rel="noreferrer" style={{ color: 'var(--orange)', textDecoration: 'underline', textUnderlineOffset: 4 }}>@viktortimewolf</a> — new episodes monthly.</>} />

          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: mobile ? 20 : 28, gap: 16, flexWrap: 'wrap' }}>
            <div className="mono" style={{ fontSize: 11, color: 'var(--text-mute)', letterSpacing: '0.16em' }}>{String(idx + 1).padStart(2, '0')} / {String(n).padStart(2, '0')}</div>
            <div style={{ display: 'flex', gap: 8 }}>
              <button onClick={() => go(-1)} aria-label="Previous episodes" className="nav-arrow ghost">←</button>
              <button onClick={() => go(1)} aria-label="Next episodes" className="nav-arrow solid" style={{ fontWeight: 700 }}>→</button>
            </div>
          </div>

          <div key={idx} className="fade-in" style={{ display: 'grid', gridTemplateColumns: mobile ? '1fr' : 'repeat(2, 1fr)', gap: 20, marginBottom: 28 }}>
            {current.map((e, k) =>
            <div
              key={`${idx}-${k}`}
              className="card"
              onClick={() => setPlaying(e)}
              style={{ padding: 0, overflow: 'hidden', textDecoration: 'none', color: 'inherit', display: 'flex', flexDirection: 'column', cursor: 'pointer' }}
            >
                <div style={{ position: 'relative' }}>
                  <Photo src={`https://img.youtube.com/vi/${e.id}/maxresdefault.jpg`} alt={e.title} ratio="16/9" style={{ borderRadius: 0 }} />
                  <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(180deg, rgba(10,9,8,0) 35%, rgba(10,9,8,0.75) 100%)', pointerEvents: 'none' }}></div>
                  <div className="mono" style={{ position: 'absolute', top: 14, left: 14, padding: '6px 10px', background: 'rgba(10,9,8,0.78)', backdropFilter: 'blur(8px)', borderRadius: 6, fontSize: 10.5, letterSpacing: '0.18em', color: 'var(--orange)', fontWeight: 600 }}>{e.ep}</div>
                  <div style={{ position: 'absolute', top: 14, right: 14, padding: '6px 10px', background: 'rgba(10,9,8,0.78)', backdropFilter: 'blur(8px)', borderRadius: 6, fontSize: 10.5, letterSpacing: '0.18em', color: 'var(--text)', fontWeight: 600, display: 'flex', alignItems: 'center', gap: 6 }} className="mono">
                    <svg width="12" height="12" viewBox="0 0 24 24" fill="#ff0000"><path d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.546 15.568V8.432L15.818 12l-6.272 3.568z"/></svg>
                    YOUTUBE
                  </div>
                  <div style={{ position: 'absolute', bottom: 16, right: 16, width: 56, height: 56, borderRadius: '50%', background: 'var(--orange)', display: 'flex', alignItems: 'center', justifyContent: 'center', boxShadow: '0 8px 24px rgba(217,119,87,0.4)' }}>
                    <svg width="18" height="18" viewBox="0 0 24 24" fill="#0a0908"><path d="M8 5v14l11-7z" /></svg>
                  </div>
                </div>
                <div style={{ padding: '22px 22px 24px', display: 'flex', flexDirection: 'column', gap: 8, flex: 1 }}>
                  <div className="mono" style={{ fontSize: 10.5, color: 'var(--text-dim)', letterSpacing: '0.18em' }}>GUEST · {e.guest.toUpperCase()}</div>
                  <div style={{ fontSize: mobile ? 19 : 21, fontWeight: 600, letterSpacing: '-0.01em', lineHeight: 1.25, color: 'var(--text)', textWrap: 'balance' }}>{e.title}</div>
                  <div style={{ marginTop: 6, display: 'flex', justifyContent: 'space-between', alignItems: 'center', borderTop: '1px solid var(--line)', paddingTop: 14 }}>
                    <span style={{ fontSize: 13, color: 'var(--text-mute)' }}>Watch episode</span>
                    <span style={{ color: 'var(--orange)', fontSize: 18 }}>▶</span>
                  </div>
                </div>
              </div>
            )}
          </div>

          <div style={{ display: 'flex', gap: 8, justifyContent: 'center' }}>
            {pages.map((_, i) =>
            <button key={i} className="dot-btn" onClick={() => setIdx(i)} aria-label={`Go to slide ${i + 1}`} style={{ width: i === idx ? 28 : 8, background: i === idx ? 'var(--orange)' : 'var(--line-strong)', padding: 0 }} />
            )}
          </div>

          <div style={{ marginTop: mobile ? 32 : 48, textAlign: 'center' }}>
            <a href={CHANNEL} target="_blank" rel="noreferrer" className="btn btn-ghost">All episodes on YouTube <span className="arrow">↗</span></a>
          </div>
        </div>
      </section>
    </React.Fragment>);

}

const ALL_TESTIMONIALS = [
{
  name: 'Tatiana S.',
  handle: '',
  tag: 'YOUTUBE COACHING · BUSINESS OWNER',
  quote: 'I tried Viktor\'s personal training sessions, and they were very inspiring. I have a serious business and decided to hire Viktor as a YouTube coach, as he is a perfect fit. It\'s been amazing. I now feel like living in a new, beautiful world. He is professional and supportive. Most importantly, after each session, I gained much inspiration and felt I could push myself.'
},
{
  name: 'Denis U.',
  handle: '',
  tag: 'YOUTUBE GROWTH · FROM 0',
  quote: 'Viktor is a great coach who knows how to work with different clients — beginners and advanced. His workshops helped me start my YouTube channel from 0. I saved tons of time using the proven frameworks he explores in detail. He understands the lifecycle of YouTube channels and what\'s important at every stage.'
},
{
  name: 'Nick A.',
  handle: '',
  tag: 'PERSONAL DEVELOPMENT',
  quote: 'Viktor helped me tap into my creative side that gave me confidence to create my own YouTube channel using my artwork — and has become a friend that tells me the truth when I don\'t want to hear it. Refreshing in a world where people tend to run from their problems instead of facing them.'
},
{
  name: 'Sean Ficken',
  handle: '@seanficken',
  tag: 'YOUTUBE GROWTH · 9,400 SUBS',
  quote: 'Viktor has solid advice which I have been using to grow my YouTube channel to over 9,400 subscribers in 7 months. His thumbnail advice has gotten me two videos that are over 10k views and counting. If you want to take your YouTube game to the next level, you should take his advice.'
},
{
  name: 'AlgoCowboy',
  handle: '@algocowboy',
  tag: 'YOUTUBE GROWTH · CTR DOUBLED',
  quote: 'Spending just a handful of webinars with you has given me some very easy, fast tweaks. CTR up almost 100%. New subs went from 1/day to 10+/day. My first video broke 2,300 views in 2 days — for a newer channel that\'s phenomenal. I haven\'t even done half of what you told me yet.'
}];

function Testimonials({ mobile, setPage }) {
  // Home page: Tatiana S, Denis U, Nick A, Sean F (AlgoCowboy lives on /testimonials)
  const data = ALL_TESTIMONIALS.slice(0, 4);

  const [idx, setIdx] = useStateP(0);
  return (
    <section style={{ padding: mobile ? '60px 0' : '120px 0', background: 'var(--bg-2)', borderTop: '1px solid var(--line)', borderBottom: '1px solid var(--line)' }}>
      <div className="wrap">
        <SectionHead num="04" kicker="Real people. Real results." title={<>The receipts.</>} sub="No screenshots of fake DMs. No paid actors. Just the people who actually did the work — and what changed." />
        <div style={{ display: 'grid', gridTemplateColumns: mobile ? '1fr' : '1fr 1fr', gap: 20 }}>
          {data.map((t, i) =>
          <figure key={i} className="card" style={{ display: 'flex', flexDirection: 'column', gap: 24, margin: 0 }}>
              <div className="mono" style={{ fontSize: 11, color: 'var(--orange)', letterSpacing: '0.16em' }}>{t.tag}</div>
              <blockquote style={{ margin: 0, fontSize: mobile ? 17 : 19, lineHeight: 1.55, letterSpacing: '-0.01em', color: 'var(--text)' }}>
                <span style={{ color: 'var(--orange)', fontSize: 32, lineHeight: 0, verticalAlign: '-12px', marginRight: 6 }}>"</span>{t.quote}
              </blockquote>
              <figcaption style={{ display: 'flex', alignItems: 'center', gap: 14, marginTop: 'auto', paddingTop: 20, borderTop: '1px solid var(--line)' }}>
                <div style={{ width: 44, height: 44, borderRadius: '50%', background: 'var(--bg)', border: '1px solid var(--line-strong)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontWeight: 700, color: 'var(--orange)' }}>
                  {t.name[0]}
                </div>
                <div>
                  <div style={{ fontWeight: 600, fontSize: 15 }}>{t.name}</div>
                  {t.handle && <div style={{ color: 'var(--text-mute)', fontSize: 13 }}>{t.handle}</div>}
                </div>
              </figcaption>
            </figure>
          )}
        </div>
        {setPage && (
          <div style={{ marginTop: 40, display: 'flex', justifyContent: 'center' }}>
            <button onClick={() => setPage('testimonials')} className="btn btn-ghost">
              Read all testimonials <span className="arrow">→</span>
            </button>
          </div>
        )}
      </div>
    </section>);

}

/* ------------------------------------------------------------------ *
 *  MEET-UP EVENTS (Section 05)
 *
 *  Each event declares the folder where its real photos LIVE (or WILL live),
 *  and the list of filenames inside that folder. The page resolves each image
 *  to `<folder><file>` at render time. Until those files exist, a placeholder
 *  asset is shown via <Photo>'s onError chain (real → placeholder → alt block).
 *
 *  HOW TO ADD REAL PHOTOS — no code changes required:
 *    1. Create the folder shown in `folder` (e.g.  meetups/circle-gathering-aspen-2024/ )
 *    2. Drop images named 01.jpg / 02.jpg / 03.jpg / … (or rename in `gallery` below).
 *    3. Refresh. The gallery auto-prefers the real files; placeholders disappear.
 *
 *  Folder slug convention:  <event-name>-<city>-<year>/   (lowercase, hyphenated).
 *  Filenames default to numeric 01.jpg … so a non-technical handoff is trivial.
 * ------------------------------------------------------------------ */
const MEETUPS_BASE = 'meetups/';
const MEETUPS = [
  {
    slug: 'tampa-2024',
    name: 'Tampa Meetup', location: 'Tampa, FL', year: 2024, dates: '2024',
    blurb: 'A waterfront weekend with the Florida circle — dawn workouts, long conversations under the palms, and the kind of dinner where everyone finally said the thing they\'d been carrying.',
    gallery: [
      { file: 'image-1.jpg', alt: 'Viktor on the Tampa waterfront at sunset' },
      { file: 'image-2.jpg', alt: 'Viktor stepping out of a McLaren, Tampa'   },
      { file: 'image-3.jpg', alt: 'Group photo at the gym — Tampa meetup'       }]
  },
  {
    slug: 'algonquin-2025',
    name: 'Algonquin Retreat', location: 'Algonquin Park, ON', year: 2025, dates: '2025',
    blurb: 'Three days off-grid in Algonquin Park — canoes at first light, fires that ran past midnight, and the kind of stillness most men haven\'t felt since they were kids. No service. No noise. Just the work.',
    gallery: [
      { file: 'image-1.jpg', alt: 'The group — canoe at the water\'s edge, Algonquin' },
      { file: 'image-2.jpg', alt: 'Algonquin lake at sunset'                           },
      { file: 'image-3.jpg', alt: 'Stars reflected on the lake at night'               },
      { file: 'image-4.jpg', alt: 'Algonquin wilderness'                               }]
  },
  {
    slug: 'mont-tremblant-2025',
    name: 'Mont-Tremblant', location: 'Mont-Tremblant, QC', year: 2025, dates: '2025',
    blurb: 'A long weekend in the Laurentians — mountain runs, working sessions in a cabin under the ski hill, and a room of men who finally stopped performing and started telling the truth about where they actually are.',
    gallery: [
      { file: 'image-1.jpg', alt: 'Group at Mont-Tremblant — ski mountain behind'  },
      { file: 'image-2.jpg', alt: 'Group portrait indoors, Mont-Tremblant'         },
      { file: 'image-3.jpg', alt: 'Viktor speaking at the session'                 },
      { file: 'image-4.jpg', alt: 'Mont-Tremblant 2025'                            }]
  },
  // TODO: Viktor — add more photos to meetups/dinners/ (image-2.jpg, image-3.jpg …) when ready.
  {
    slug: 'dinners',
    name: 'The Dinners', location: 'US & Canada', year: 2025, dates: 'Recurring',
    blurb: 'Small, invite-only dinners across the US and Canada. Eight to twelve people around one table, three hours, one rule: be honest or be quiet. The room I trust most.',
    gallery: [
      { file: 'image-1.jpg', alt: 'Circle fireside gathering at night' }]
  }];

// Resolve an event's gallery to renderable { src, alt } records.
// `src` points at the real photo folder. EventImg shows a dark placeholder
// div automatically if the file hasn't been uploaded yet.
function resolveMeetup(event) {
  const folder = `${MEETUPS_BASE}${event.slug}/`;
  return {
    ...event,
    folder,
    images: event.gallery.map((g) => ({
      src: `${folder}${g.file}`,
      alt: g.alt
    }))
  };
}

function Community({ mobile, setPage }) {
  // Resolve once per render — cheap, and keeps the modal + card in lockstep.
  const events = MEETUPS.map(resolveMeetup);

  const [openIdx, setOpenIdx] = useStateP(null);
  const modalOpen = openIdx !== null;
  const cardW = mobile ? 220 : 360;

  return (
    <section style={{ padding: mobile ? '60px 0' : '120px 0', background: 'var(--bg)' }}>
      <div className="wrap">
        <SectionHead num="05" kicker="You don't do this alone" title={<>People who showed up.<br />And stayed.</>} />
      </div>
      <div className="meetup-strip" data-paused={modalOpen ? '1' : '0'} style={{ overflow: 'hidden', marginBottom: 48, position: 'relative' }}>
        <div className="marquee" style={{ gap: 8 }}>
          {[...events, ...events].map((e, i) =>
            <button
              type="button"
              key={i}
              className="meetup-card"
              onClick={() => setOpenIdx(i % events.length)}
              aria-label={`${e.name} — ${e.location}, ${e.year}. Open gallery.`}
              style={{ flex: `0 0 ${cardW}px`, width: cardW, padding: 0, background: 'transparent', border: 0, font: 'inherit', color: 'inherit', textAlign: 'left', cursor: 'pointer', borderRadius: 14 }}>
              <div style={{ position: 'relative' }}>
                <Photo src={e.images[0].src} alt={e.images[0].alt} ratio="1/1" />
                <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(180deg, rgba(10,9,8,0) 45%, rgba(10,9,8,0.82) 100%)', pointerEvents: 'none', borderRadius: 14 }}></div>
                <div style={{ position: 'absolute', left: 14, right: 14, bottom: 14, display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', gap: 10, pointerEvents: 'none' }}>
                  <div style={{ minWidth: 0 }}>
                    <div style={{ fontSize: mobile ? 14 : 17, fontWeight: 600, letterSpacing: '-0.01em', lineHeight: 1.2, color: 'var(--text)', textWrap: 'balance' }}>{e.name}</div>
                    <div className="mono" style={{ marginTop: 6, fontSize: 10.5, letterSpacing: '0.16em', color: 'var(--text-mute)', textTransform: 'uppercase' }}>{e.location} · {e.year}</div>
                  </div>
                  <span className="meetup-arrow" aria-hidden="true" style={{ flex: '0 0 auto', width: 32, height: 32, borderRadius: '50%', background: 'rgba(10,9,8,0.72)', backdropFilter: 'blur(6px)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', color: 'var(--orange)', fontSize: 14, lineHeight: 1, transition: 'transform .2s ease, background .2s ease' }}>→</span>
                </div>
              </div>
            </button>
          )}
        </div>
        <div style={{ position: 'absolute', top: 0, bottom: 0, left: 0, width: 80, background: 'linear-gradient(90deg, var(--bg), transparent)', pointerEvents: 'none', zIndex: 2 }}></div>
        <div style={{ position: 'absolute', top: 0, bottom: 0, right: 0, width: 80, background: 'linear-gradient(270deg, var(--bg), transparent)', pointerEvents: 'none', zIndex: 2 }}></div>
      </div>
      <div className="wrap">
        <div style={{ display: 'grid', gridTemplateColumns: mobile ? '1fr' : '1fr 1fr', gap: 48, alignItems: 'center' }}>
          <p style={{ fontSize: mobile ? 20 : 26, lineHeight: 1.4, letterSpacing: '-0.02em', margin: 0 }}>
            Real change happens when you stop trying to do it alone. Around the fire, on the water, in the room — the people I work with sharpen each other. <span className="serif-i" style={{ color: 'var(--orange)' }}>That's the whole point.</span>
          </p>
          <div style={{ padding: 32, border: '1px solid var(--line-strong)', borderRadius: 16, background: 'var(--bg-2)' }}>
            <div className="eyebrow" style={{ marginBottom: 10 }}>Next event · invite only</div>
            <h3 style={{ margin: '0 0 14px', fontSize: mobile ? 22 : 26, fontWeight: 700, letterSpacing: '-0.02em', lineHeight: 1.2 }}>Want in on the next meetup?</h3>
            <p style={{ margin: 0, color: 'var(--text-mute)', fontSize: 15, lineHeight: 1.55, marginBottom: 24 }}>
              Leave your contact info and let's talk. These are small, invite-only — I want to know who's coming.
            </p>
            <button className="btn btn-primary btn-sm" onClick={() => setPage('contact')}>Leave your info <span className="arrow">→</span></button>
          </div>
        </div>
      </div>

      {modalOpen &&
        <MeetupModal
          event={events[openIdx]}
          onClose={() => setOpenIdx(null)}
          mobile={mobile}
          setPage={setPage} />
      }
    </section>);

}

/* ---- Meet-up gallery modal ---- */
// If the real photo hasn't been uploaded yet, shows a dark placeholder div
// instead of a broken image. Resets on src change so navigating retries.
function EventImg({ src, alt, style }) {
  const [failed, setFailed] = useStateP(false);
  useEffectP(() => { setFailed(false); }, [src]);
  if (failed) return (
    <div style={{ ...style, background: '#111009', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
      <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="rgba(255,255,255,0.12)" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
        <rect x="3" y="3" width="18" height="18" rx="2" />
        <path d="M3 15l5-5 4 4 3-3 6 5" />
        <circle cx="8.5" cy="8.5" r="1.5" />
      </svg>
    </div>
  );
  return (
    <img
      src={src}
      alt={alt || ''}
      draggable="false"
      onError={() => setFailed(true)}
      style={style} />
  );
}

function MeetupModal({ event, onClose, mobile, setPage }) {
  const [imgIdx, setImgIdx] = useStateP(0);
  const closeBtnRef = useRefP(null);
  const lastFocusedRef = useRefP(null);
  // 'keyboard' (Esc) → restore focus to trigger (a11y).
  // 'mouse' (X / backdrop click) → let focus fall to body so :focus-within
  // on .meetup-strip doesn't latch and keep the marquee paused.
  const closeReasonRef = useRefP('mouse');
  const gallery = event.images;
  const n = gallery.length;
  const go = (d) => setImgIdx((i) => (i + d + n) % n);

  // Body scroll lock + conditional focus restore
  useEffectP(() => {
    lastFocusedRef.current = document.activeElement;
    // Note: page scroll is intentionally NOT locked — the dialog feels less
    // trapping and you can scroll the site behind if you need a reference.
    // Focus the close button so keyboard users land somewhere sensible.
    const t = setTimeout(() => closeBtnRef.current?.focus(), 0);
    return () => {
      clearTimeout(t);
      // Only refocus the trigger card on keyboard close — otherwise the
      // resulting :focus-within would keep .meetup-strip's marquee paused.
      if (closeReasonRef.current === 'keyboard' &&
          lastFocusedRef.current && typeof lastFocusedRef.current.focus === 'function') {
        lastFocusedRef.current.focus();
      }
    };
  }, []);

  // Keyboard: Esc closes, ←/→ navigate
  useEffectP(() => {
    const onKey = (e) => {
      if (e.key === 'Escape') { closeReasonRef.current = 'keyboard'; onClose(); }
      else if (e.key === 'ArrowRight') go(1);
      else if (e.key === 'ArrowLeft') go(-1);
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [n]);

  const current = gallery[imgIdx];

  return (
    <div
      className="meetup-modal fade-in"
      role="dialog"
      aria-modal="true"
      aria-labelledby="meetup-modal-title"
      onClick={onClose}>
      {/* Floating close button — lives on the backdrop, not the dialog, so it
          stays in the top-right of the viewport even if the dialog scrolls. */}
      <button
        ref={closeBtnRef}
        type="button"
        className="meetup-modal__close"
        onClick={(e) => { e.stopPropagation(); onClose(); }}
        aria-label="Close gallery (Esc)">
        <svg width="18" height="18" viewBox="0 0 16 16" aria-hidden="true" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><path d="M3 3l10 10M13 3L3 13" /></svg>
      </button>
      <div className="meetup-modal__dialog" onClick={(e) => e.stopPropagation()}>
        {/* Header */}
        <div className="meetup-modal__header">
          <div style={{ minWidth: 0 }}>
            <div className="mono" style={{ fontSize: 10.5, letterSpacing: '0.18em', color: 'var(--orange)', marginBottom: 6, textTransform: 'uppercase' }}>{event.location} · {event.dates || event.year}</div>
            <h3 id="meetup-modal-title" className="display" style={{ margin: 0, fontSize: mobile ? 24 : 32, letterSpacing: '-0.02em', lineHeight: 1.1 }}>{event.name}</h3>
          </div>
        </div>

        {/* Hero image with prev/next */}
        <div className="meetup-modal__hero">
          <div key={imgIdx} className="fade-in" style={{ position: 'absolute', inset: 0 }}>
            <EventImg
              src={current.src}
              alt={current.alt}
              style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }} />
          </div>
          {n > 1 &&
            <>
              <button type="button" className="nav-arrow ghost meetup-modal__nav meetup-modal__nav--prev" onClick={() => go(-1)} aria-label="Previous image">←</button>
              <button type="button" className="nav-arrow solid meetup-modal__nav meetup-modal__nav--next" onClick={() => go(1)} aria-label="Next image">→</button>
              <div className="mono meetup-modal__counter">{String(imgIdx + 1).padStart(2, '0')} / {String(n).padStart(2, '0')}</div>
            </>
          }
        </div>

        {/* Caption + thumbnails + CTA */}
        <div className="meetup-modal__body">
          {event.blurb &&
            <p style={{ margin: 0, marginBottom: 18, color: 'var(--text-mute)', fontSize: mobile ? 14 : 15, lineHeight: 1.55, maxWidth: 620 }}>{event.blurb}</p>
          }
          <div className="meetup-modal__thumbs">
            {gallery.map((g, i) =>
              <button
                key={i}
                type="button"
                className="meetup-modal__thumb"
                data-on={i === imgIdx ? '1' : '0'}
                onClick={() => setImgIdx(i)}
                aria-label={`View image ${i + 1}: ${g.alt}`}>
                <EventImg src={g.src} alt="" />
              </button>
            )}
          </div>
          <div className="meetup-modal__footer">
            <span className="mono" style={{ fontSize: 11, letterSpacing: '0.14em', color: 'var(--text-dim)', textTransform: 'uppercase' }}>Want in on the next one?</span>
            <button className="btn btn-ghost btn-sm" onClick={() => { onClose(); setPage('contact'); }}>Apply to join <span className="arrow">→</span></button>
          </div>
        </div>
      </div>
    </div>);

}

function Newsletter({ mobile }) {
  const [firstName, setFirstName] = useStateP('');
  const [lastName, setLastName] = useStateP('');
  const [email, setEmail] = useStateP('');
  const [topics, setTopics] = useStateP([]);
  const toggleTopic = (t) => setTopics((prev) => prev.includes(t) ? prev.filter((x) => x !== t) : [...prev, t]);
  const [sent, setSent] = useStateP(false);
  const [sending, setSending] = useStateP(false);
  const [sendError, setSendError] = useStateP(null);

  const handleSubmit = async (e) => {
    e.preventDefault();
    if (sending || sent) return;
    setSendError(null);
    setSending(true);
    const ok = await kitSubscribe({
      email,
      firstName,
      lastName,
      topic: topics.join(', ')
    });
    setSending(false);
    if (ok) {
      setSent(true);
    } else if (KIT_LIVE) {
      setSendError(`Couldn't reach the mailing list. Try again, or email ${CONTACT_EMAIL}.`);
    } else {
      // Dev fallback: optimistic confirm so the form never feels broken locally
      setSent(true);
    }
  };

  return (
    <section style={{ padding: mobile ? '60px 0' : '100px 0', background: 'var(--bg-2)', borderTop: '1px solid var(--line)', borderBottom: '1px solid var(--line)' }}>
      <div className="wrap">
        <div style={{ display: 'grid', gridTemplateColumns: mobile ? '1fr' : '1.2fr 1fr', gap: mobile ? 28 : 60, alignItems: 'center' }}>
          <div>
            <div className="eyebrow" style={{ marginBottom: 14, color: 'var(--orange)' }}>06 · FREE GUIDE</div>
            <h2 className="display" style={{ fontSize: mobile ? 'clamp(36px, 9vw, 48px)' : 'clamp(48px, 5vw, 72px)', margin: 0, marginBottom: 20 }}>
              Stop wasting time.<br />Start moving <span style={{ color: 'var(--orange)' }}>forward</span>.
            </h2>
            <p style={{ color: 'var(--text-mute)', fontSize: mobile ? 16 : 18, lineHeight: 1.5, margin: 0, maxWidth: 480 }}>
              The exact strategies I use to balance trucking, the gym, YouTube, coaching, and a real life — without burning out. Free guide, delivered to your inbox.
            </p>
          </div>
          <form onSubmit={handleSubmit} style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
            <div className="card" style={{ padding: 24 }}>
              {sent ?
                <div style={{ padding: '8px 0' }}>
                  <div className="eyebrow" style={{ color: 'var(--orange)', marginBottom: 10 }}>✓ ALMOST THERE</div>
                  <p style={{ margin: 0, marginBottom: 16, fontSize: 17, lineHeight: 1.45 }}>
                    Thank you, <span style={{ color: 'var(--orange)' }}>{firstName || 'friend'}</span>. Confirm your email to receive the free guide.
                  </p>
                  <p style={{ margin: 0, marginBottom: 16, color: 'var(--text-mute)', fontSize: 14, lineHeight: 1.5 }}>
                    Check your inbox (and spam folder) for a confirmation link. Once confirmed you'll get the PDF and the weekly email.
                  </p>
                  {FREE_GUIDE_LIVE ?
                    <a href={FREE_GUIDE_PDF} target="_blank" rel="noreferrer" className="btn btn-ghost btn-sm" style={{ justifyContent: 'center' }}>
                      Download the guide now <span className="arrow">→</span>
                    </a> :
                    <div style={{ padding: '12px 14px', border: '1px dashed var(--line-strong)', borderRadius: 10, background: 'rgba(229,83,42,0.04)' }}>
                      <div className="mono" style={{ fontSize: 10, color: 'var(--orange)', letterSpacing: '0.16em', marginBottom: 6 }}>⚠ PDF LINK NOT SET</div>
                      <p style={{ margin: 0, fontSize: 13, color: 'var(--text-mute)', lineHeight: 1.5 }}>Add <code style={{ color: 'var(--text)' }}>free-guide.pdf</code> to <code style={{ color: 'var(--text)' }}>/assets</code> and update <code style={{ color: 'var(--text)' }}>FREE_GUIDE_PDF</code> in <code style={{ color: 'var(--text)' }}>pages.jsx</code>.</p>
                    </div>
                  }
                </div>
                :
                <>
                  <div style={{ display: 'grid', gridTemplateColumns: mobile ? '1fr 1fr' : '1fr 1fr', gap: 10, marginBottom: 12 }}>
                    <div>
                      <label className="lbl">First name</label>
                      <input name="first_name" required value={firstName} onChange={(e) => setFirstName(e.target.value)} placeholder="Viktor" className="input" />
                    </div>
                    <div>
                      <label className="lbl">Last name</label>
                      <input name="last_name" required value={lastName} onChange={(e) => setLastName(e.target.value)} placeholder="Zaharov" className="input" />
                    </div>
                  </div>
                  <label className="lbl">Email address</label>
                  <input type="email" name="email_address" required value={email} onChange={(e) => setEmail(e.target.value)} placeholder="you@domain.com" className="input" />
                  <label className="lbl" style={{ marginTop: 12 }}>What are you here for?</label>
                  <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
                    {['Self-upgrade', 'Trucking', 'YouTube', 'Video Creation', 'Events'].map((t) =>
                      <button type="button" key={t} className="pill" data-on={topics.includes(t) ? '1' : '0'} onClick={() => toggleTopic(t)} style={{ padding: '8px 14px', fontSize: 13 }}>{t}</button>
                    )}
                  </div>
                  <button type="submit" disabled={sending} className="btn btn-primary" style={{ marginTop: 16, width: '100%', justifyContent: 'center', opacity: sending ? 0.7 : 1 }}>
                    {sending ? 'Sending…' : <>Start saving time <span className="arrow">→</span></>}
                  </button>
                  <p className="mono" style={{ fontSize: 11, color: 'var(--text-dim)', marginTop: 14, marginBottom: 0, letterSpacing: '0.06em' }}>
                    NO SPAM · UNSUBSCRIBE ANYTIME · ~1 EMAIL/WEEK
                  </p>
                  {sendError &&
                    <p className="mono" style={{ fontSize: 11, color: 'var(--orange)', marginTop: 10, marginBottom: 0, letterSpacing: '0.04em' }}>
                      ⚠ {sendError}
                    </p>
                  }
                  {!KIT_LIVE &&
                    <p className="mono" style={{ fontSize: 10, color: 'var(--orange)', marginTop: 10, marginBottom: 0, letterSpacing: '0.06em', opacity: 0.75 }}>
                      ⚠ DEV MODE — set KIT_FORM_ID in pages.jsx to wire signups to Kit.
                    </p>
                  }
                </>
              }
            </div>
          </form>
        </div>
      </div>
    </section>);

}

function FAQ({ mobile }) {
  const qs = [
  ['Who is this actually for?', 'Anyone tired of running on autopilot. You don\'t need to be in trouble — you need to be willing to do the work. If you\'re looking for vibes, motivation, or quick tricks, this isn\'t it.'],
  ['How is this different from another life coach?', 'I\'m not a "life coach." I\'m a long-haul driver who built an exit from the road, built a YouTube channel, and pulled others along the way. The work I give you is the work I do myself.'],
  ['What does a coaching engagement look like?', 'Two ways in: a free 30-minute call for video editing & YouTube help, or a 90-minute deep-dive coaching call for trucking and personal-development work. From there we decide whether 1:1 weekly sessions, a focused 8-week sprint, or a group cohort makes sense. No high-pressure pitch.'],
  ['Do you guarantee results?', 'I guarantee I\'ll show up fully and tell you the truth. The results come from the work you put in. The people with results on this page did the work — that\'s the whole formula.'],
  ['How much does it cost?', 'It depends on the program and the depth. The discovery call is free and you\'ll leave it knowing whether we\'re a fit and what the investment looks like. No surprise pricing.'],
  ['I\'m not in trucking — is the YouTube program still for me?', 'Yes. The YouTube work is industry-agnostic. Most clients aren\'t drivers — they\'re entrepreneurs, creators, and professionals using video to grow what they already have.']];

  return (
    <section style={{ padding: mobile ? '60px 0' : '120px 0', background: 'var(--bg)' }}>
      <div className="wrap">
        <SectionHead num="07" kicker="Common questions" title={<>The questions people<br />actually ask first.</>} />
        <div style={{ maxWidth: 920 }}>
          {qs.map(([q, a], i) =>
          <details className="faq" key={i} {...i === 0 ? { open: true } : {}}>
              <summary><span>{q}</span><span className="pl">+</span></summary>
              <p>{a}</p>
            </details>
          )}
        </div>
      </div>
    </section>);

}

function FinalCTA({ setPage, mobile }) {
  return (
    <section style={{ padding: mobile ? '80px 0' : '160px 0', background: 'var(--orange)', color: '#0a0908', position: 'relative', overflow: 'hidden' }}>
      <div style={{ position: 'absolute', inset: 0, background: 'radial-gradient(circle at 20% 50%, rgba(0,0,0,0.15), transparent 50%)' }}></div>
      <div className="wrap" style={{ position: 'relative' }}>

        <h2 className="display" style={{ fontSize: mobile ? 'clamp(40px, 11vw, 56px)' : 'clamp(72px, 11vw, 180px)', margin: 0, maxWidth: 1200, color: '#0a0908' }}>
          The drift<br />ends here.
        </h2>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 48, marginTop: 48, alignItems: 'flex-end', justifyContent: 'space-between' }}>
          <p style={{ fontSize: mobile ? 18 : 22, lineHeight: 1.4, margin: 0, maxWidth: 560, color: '#1a1410' }}>
            Two call options: 30-minute video-editing review, or 90-minute coaching deep-dive. Pick the one that matches what you need — no pitch either way.
          </p>
          <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>
            <BookButton kind="coaching" variant="dark" onClickFallback={() => setPage('contact')}>Book 90-min coaching call</BookButton>
            <BookButton kind="video" variant="dark" onClickFallback={() => setPage('contact')}>Or 30-min video review</BookButton>
          </div>
        </div>
      </div>
    </section>);

}

/* ============ PROGRAMS ============ */
function ProgramsPage({ setPage, mobile }) {
  const programs = [
  {
    id: 'self',
    num: '01',
    name: 'Self-Upgrade Coaching',
    shortName: 'Self-Upgrade',
    applyLabel: 'Apply for Self-Upgrade',
    tagline: 'Build boundaries. Find peace. Move.',
    img: 'assets/program-1-self.png',
    who: 'People with the resources but not the direction. The plateau-breakers.',
    outcomes: [
    'Build boundaries that actually hold under pressure',
    'Cut the white noise — focus on what matters this season',
    'Time management that fits a real adult life',
    'Emotional resilience without the therapy-speak',
    'A daily rhythm that produces both output and peace'],

    schedule: [
      { label: 'Session', value: '90 min' },
      { label: 'Frequency', value: 'Bi-weekly' },
      { label: 'Duration', value: '6 months' }
    ],
    price: 'From $500 USD / month'
  },
  {
    id: 'trucking',
    num: '02',
    name: 'Trucking Career Coaching',
    shortName: 'Trucking',
    applyLabel: 'Apply for Trucking Coaching',
    tagline: 'Use the road as your reset button.',
    img: 'assets/program-2-trucking.png',
    who: 'Anyone stuck in dead-end jobs or environments dragging them backward — who wants a real path out.',
    outcomes: [
    'Pick the right company for your lifestyle',
    'Live efficiently in the truck — eat, sleep, train',
    'Avoid the rookie mistakes that wash drivers out',
    'Stack real savings and build financial momentum for the first time',
    'Treat long-haul as the school, not the sentence'],

    schedule: [
      { label: 'Session', value: '1:1 call + Signal' },
      { label: 'Frequency', value: 'Weekly' },
      { label: 'Duration', value: '6 months' }
    ],
    price: 'From $500 USD / month'
  },
  {
    id: 'youtube',
    num: '03',
    name: 'YouTube Growth Coaching',
    shortName: 'YouTube Growth',
    applyLabel: 'Apply for YouTube Growth',
    tagline: 'Build a channel that compounds.',
    img: 'assets/program-3-youtube.png',
    who: 'Entrepreneurs, creators, and professionals serious about a video presence.',
    outcomes: [
    'Set your channel up for growth from day one',
    'Hooks, thumbnails, titles, retention — the levers that move CTR',
    'Build a sustainable content engine — not a burnout cycle',
    'Apply the frameworks I use myself',
    'Move from random uploads to a real strategy'],

    schedule: [
      { label: 'Session', value: '1:1 + async review' },
      { label: 'Frequency', value: 'Weekly' },
      { label: 'Duration', value: '12 months' }
    ],
    price: 'From $500 USD / month'
  },
  {
    id: 'video',
    num: '04',
    name: 'Video Editing',
    shortName: 'Video Editing',
    applyLabel: 'Book Video Review',
    tagline: 'Send the raw file. Get back a finished video.',
    img: 'assets/program-4-editing.png',
    who: 'Creators who film but never ship — because the edit is where it dies. Send your raw recording; Viktor turns it into a polished, publish-ready video.',
    outcomes: [
    'Professional edit delivered from your raw recording',
    'Hooks, pacing, and retention cuts that hold viewers',
    'Thumbnails and title copy that earn the click',
    'Fast turnaround — back in your hands, ready to publish',
    'Notes on what to sharpen for next time'],

    schedule: [
      { label: 'Session', value: '30 min review' },
      { label: 'Booking', value: 'As needed' }
    ]
  },
  {
    id: 'meetups',
    num: '05',
    name: 'Meet-Ups & Events',
    shortName: 'Meet-Ups & Events',
    applyLabel: 'Apply for Meet-Ups',
    tagline: 'You bring the people. I run the room.',
    img: 'assets/program-5-events.png',
    who: 'Anyone who wants a real gathering — retreats, offsites, intimate meet-ups. I can organize a meet-up for anyone.',
    outcomes: [
    'Venue research and booking',
    'Vendor sourcing and coordination',
    'Guest communication and logistics',
    'Itinerary planning and scheduling',
    'On-site management and problem-solving',
    'Budget tracking and reporting'],

    schedule: [
      { label: 'Scope', value: 'End-to-end' },
      { label: 'Basis', value: 'Project-based' }
    ]
  }];

  return (
    <div className="fade-in">
      <section style={{ padding: mobile ? '48px 0 32px' : '96px 0 48px', background: 'var(--bg)' }}>
        <div className="wrap">
          <div className="eyebrow" style={{ marginBottom: 18 }}>PROGRAMS · Q2 2026 INTAKE</div>
          <h1 className="display" style={{ fontSize: mobile ? 'clamp(36px, 10vw, 52px)' : 'clamp(64px, 8vw, 120px)', margin: 0, maxWidth: 1100 }}>
            Five doors out of <span style={{ color: 'var(--orange)' }}>drift.</span>
          </h1>
          <p style={{ color: 'var(--text-mute)', fontSize: mobile ? 17 : 20, maxWidth: 680, marginTop: 32, lineHeight: 1.5 }}>
            Each program is built around one of the ways I see people get stuck. Read them honestly — then book a call and we'll find which one fits your season.
          </p>
        </div>
      </section>
      <ProgramsCarousel programs={programs} mobile={mobile} setPage={setPage} />
      <FinalCTA setPage={setPage} mobile={mobile} />
    </div>);

}

function ProgramsCarousel({ programs, mobile, setPage }) {
  return (
    <section style={{ padding: mobile ? '24px 0 60px' : '40px 0 120px', background: 'var(--bg)' }}>
      <div className="wrap" style={{ display: 'flex', flexDirection: 'column', gap: mobile ? 24 : 32 }}>
        {programs.map((p, i) =>
          <article key={p.id} className="card" id={p.id} style={{ padding: 0, overflow: 'hidden', display: 'grid', gridTemplateColumns: mobile ? '1fr' : (i % 2 === 0 ? '1.1fr 1fr' : '1fr 1.1fr'), gap: 0 }}>
            <div style={{ order: mobile ? 1 : (i % 2 === 0 ? 1 : 2), position: 'relative', minHeight: mobile ? 240 : 'auto' }}>
              <Photo src={p.img} alt={p.name} ratio={mobile ? '16/10' : '4/5'} style={{ borderRadius: 0, height: '100%' }} tag={`${p.num} · ${p.shortName.toUpperCase()}`} />
            </div>
            <div style={{ order: mobile ? 2 : (i % 2 === 0 ? 2 : 1), padding: mobile ? '28px 24px 32px' : '48px 48px 44px', display: 'flex', flexDirection: 'column', gap: 18 }}>
              <div className="mono" style={{ fontSize: 11, color: 'var(--orange)', letterSpacing: '0.18em' }}>{p.num} · {p.name.toUpperCase()}</div>
              <h3 className="display" style={{ fontSize: mobile ? 'clamp(28px, 7vw, 36px)' : 'clamp(36px, 3.5vw, 52px)', margin: 0, letterSpacing: '-0.03em' }}>{p.tagline}</h3>
              <p style={{ margin: 0, color: 'var(--text-mute)', fontSize: 15, lineHeight: 1.55 }}>
                <span style={{ color: 'var(--text)', fontWeight: 600 }}>Who this is for · </span>{p.who}
              </p>
              <ul style={{ listStyle: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: 8 }}>
                {p.outcomes.map((o, k) =>
                  <li key={k} style={{ display: 'flex', gap: 12, alignItems: 'flex-start', fontSize: 14.5, lineHeight: 1.5, color: 'var(--text)' }}>
                    <span style={{ color: 'var(--orange)', fontWeight: 700, flex: '0 0 auto' }}>→</span>
                    <span>{o}</span>
                  </li>
                )}
              </ul>
              <div style={{ display: 'flex', flexWrap: 'wrap', gap: 24, paddingTop: 12, borderTop: '1px solid var(--line)', marginTop: 8 }}>
                <div style={{ flex: '1 1 auto' }}>
                  <div className="eyebrow" style={{ marginBottom: 10 }}>Format</div>
                  <div style={{ display: 'flex', gap: 20, flexWrap: 'wrap' }}>
                    {p.schedule.map((s, k) =>
                      <div key={k} style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
                        <div className="mono" style={{ fontSize: 10, color: 'var(--text-mute)', letterSpacing: '0.14em', textTransform: 'uppercase' }}>{s.label}</div>
                        <div style={{ fontSize: 15, color: 'var(--text)', fontWeight: 600, letterSpacing: '-0.01em' }}>{s.value}</div>
                      </div>
                    )}
                  </div>
                </div>
                {p.price &&
                  <div>
                    <div className="eyebrow" style={{ marginBottom: 6 }}>Investment</div>
                    <div style={{ fontSize: 14, color: 'var(--text)' }}>{p.price}</div>
                  </div>
                }
              </div>
              <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap', marginTop: 4 }}>
                <BookButton kind={p.id === 'video' ? 'video' : 'coaching'} size="sm" onClickFallback={() => setPage('contact')}>{p.applyLabel}</BookButton>
                <button className="btn btn-ghost btn-sm" onClick={() => setPage('testimonials')}>See results</button>
              </div>
            </div>
          </article>
        )}
      </div>
    </section>);

}

/* ============ ABOUT ============ */
function AboutPage({ setPage, mobile }) {
  return (
    <div className="fade-in">
      <section style={{ padding: mobile ? '48px 0' : '96px 0', background: 'var(--bg)' }}>
        <div className="wrap">
          <div className="eyebrow" style={{ marginBottom: 18 }}>ABOUT · VIKTOR ZAHAROV</div>
          <h1 className="display" style={{ fontSize: mobile ? 'clamp(36px, 10vw, 52px)' : 'clamp(64px, 8vw, 120px)', margin: 0, maxWidth: 1100 }}>
            Six years on the road.<br />One way out: <span style={{ color: 'var(--orange)' }}>do the work.</span>
          </h1>
        </div>
      </section>
      <section style={{ padding: mobile ? '40px 0' : '60px 0', background: 'var(--bg)' }}>
        <div className="wrap" style={{ display: 'grid', gridTemplateColumns: mobile ? '1fr' : '1.35fr 1fr', gap: mobile ? 28 : 60, alignItems: 'flex-start' }}>
          <Photo eager src="uploads/DSC_6104-Enhanced-NR.jpg" alt="Viktor on the canyon" ratio="4/5" style={mobile ? {} : { position: 'sticky', top: 96 }} imgStyle={{ objectPosition: '18% 82%' }} />
          <div style={{ display: 'flex', flexDirection: 'column', gap: 32 }}>
            <Chapter num="01" title="The drift" body="I came to North America with nothing settled and everything to prove. For a while I drifted — taking jobs, paying bills, not really moving. The kind of stuck that doesn't feel like stuck because the days still pass." />
            <Chapter num="02" title="The road" body="I got into long-haul trucking because it gave me something most jobs don't: silence and forward motion. Six years of crossing this continent taught me discipline the hard way. The truck became my school." />
            <Chapter num="03" title="The work" body="On the road I started reading, building, recording. I built a YouTube channel. I went from long-haul driver to full-time coach. I stopped pretending the life I had was the life I wanted. The same frameworks I used on myself are the ones I now hand to clients." />
            <Chapter num="04" title="The coaching" body="Today I work with people who feel the same thing I felt — that the days are passing without weight. Trucking, YouTube, self-mastery — whichever door fits. The work is the same: do today what your future self would thank you for." />
            <Chapter num="05" title="The family" body="None of this matters without the people you're building for. My family is the why. The discipline isn't punishment — it's how I show up for them." />
          </div>
        </div>
      </section>
      <section style={{ padding: mobile ? '60px 0' : '120px 0', background: 'var(--bg-2)', borderTop: '1px solid var(--line)', borderBottom: '1px solid var(--line)' }}>
        <div className="wrap">
          <SectionHead kicker="WHAT I LIVE BY" title="Five rules. No exceptions." />
          <div style={{ display: 'grid', gridTemplateColumns: mobile ? '1fr' : 'repeat(2, 1fr)', gap: 1, background: 'var(--line)', border: '1px solid var(--line)', borderRadius: 14, overflow: 'hidden' }}>
            {[
            ['Coming late, you\'re fired.', 'Time is the first contract you sign with anyone. Break it once and every other promise you make gets discounted. Build your week backwards from your commitments — be early, or be honest about cancelling. There is no third option.'],
            ['Discipline beats motivation.', 'Motivation shows up when it\'s easy and disappears when it isn\'t — you cannot build a life on top of weather. Discipline is the system you set on a good day so the bad day doesn\'t get a vote. Decide once, then execute. Feelings don\'t get a seat at the table.'],
            ['Speak less. Build more.', 'Announcing a plan gives you the same dopamine as finishing it, except nothing ships. Stop performing the work and start shipping it. Receipts out-argue opinions every time — and the people who matter can read either one.'],
            ['No autopilot.', 'The day you stop choosing, the world chooses for you — and the world\'s defaults are not yours. Every week, look at the last seven days and ask if you actually picked them. If you didn\'t, you drifted. Drift compounds into decades.'],
            ['Family first. Always.', 'Everything else — the income, the reps, the channel — is the means. The people you\'re building for are the why. When the calendar gets crowded, the family line is the one you protect. Every win without them is a souvenir from a war you didn\'t need to be in.']].
            map(([t, d], i, arr) =>
            <div key={i} style={{ background: 'var(--bg)', padding: mobile ? '24px 22px' : '32px 28px', gridColumn: !mobile && i === arr.length - 1 ? '1 / -1' : 'auto' }}>
                <div className="mono" style={{ fontSize: 11, color: 'var(--orange)', letterSpacing: '0.16em', marginBottom: 12 }}>RULE 0{i + 1}</div>
                <div style={{ fontSize: 22, fontWeight: 600, letterSpacing: '-0.02em', marginBottom: 12, textWrap: 'balance' }}>{t}</div>
                <div style={{ fontSize: 14.5, color: 'var(--text-mute)', lineHeight: 1.6, textWrap: 'pretty', maxWidth: 640 }}>{d}</div>
              </div>
            )}
          </div>
        </div>
      </section>
      <FinalCTA setPage={setPage} mobile={mobile} />
    </div>);

}
function Chapter({ num, title, body }) {
  return (
    <div style={{ display: 'grid', gridTemplateColumns: '60px 1fr', gap: 20, paddingBottom: 32, borderBottom: '1px solid var(--line)' }}>
      <div className="mono" style={{ fontSize: 12, color: 'var(--orange)', letterSpacing: '0.16em', paddingTop: 4 }}>{num}</div>
      <div>
        <h3 className="display" style={{ fontSize: 28, margin: 0, marginBottom: 12, letterSpacing: '-0.02em' }}>{title}</h3>
        <p style={{ color: 'var(--text-mute)', fontSize: 17, lineHeight: 1.6, margin: 0, maxWidth: 620 }}>{body}</p>
      </div>
    </div>);

}

/* ============ CONTACT ============ */
function ContactPage({ setPage, mobile }) {
  const [form, setForm] = useStateP({ first: '', last: '', email: '', msg: '', list: '' });
  const [sent, setSent] = useStateP(false);
  const [sending, setSending] = useStateP(false);
  const [sendError, setSendError] = useStateP(null);
  const [callType, setCallType] = useStateP('coaching');
  const active = ACUITY[callType];
  const live = ACUITY_LIVE(callType);

  // Submit handler — Formspree primary, mailto fallback.
  const handleContactSubmit = async (e) => {
    e.preventDefault();
    if (sending || sent) return;
    setSendError(null);

    // Side-effect: opt-in to newsletter (fire-and-forget Kit signup)
    if (form.list === 'Yes' && KIT_LIVE) {
      kitSubscribe({
        email: form.email,
        firstName: form.first,
        lastName: form.last,
        topic: 'Contact form'
      }).catch(() => {});
    }

    if (CONTACT_FORMSPREE_LIVE) {
      // Path A — Formspree.
      setSending(true);
      try {
        const res = await fetch(`https://formspree.io/f/${CONTACT_FORMSPREE_ID}`, {
          method: 'POST',
          headers: { Accept: 'application/json', 'Content-Type': 'application/json' },
          body: JSON.stringify({
            firstName: form.first,
            lastName: form.last,
            email: form.email,
            message: form.msg,
            newsletterOptIn: form.list || 'No',
            _replyto: form.email,
            _subject: `Coaching enquiry — ${form.first} ${form.last}`.trim()
          })
        });
        if (!res.ok) throw new Error(`Formspree returned ${res.status}`);
        setSent(true);
      } catch (err) {
        // Fall through to mailto so the user is never stranded
        setSendError(err.message || 'Send failed');
        window.location.href = buildContactMailto(form);
      } finally {
        setSending(false);
      }
    } else {
      // Path B — pure mailto. Opens user's email client with everything pre-filled.
      window.location.href = buildContactMailto(form);
      // Optimistic — most clients open in a new window; we mark sent so the UI updates.
      setSent(true);
    }
  };
  return (
    <div className="fade-in">
      <section style={{ padding: mobile ? '48px 0 24px' : '96px 0 48px', background: 'var(--bg)' }}>
        <div className="wrap">
          <div className="eyebrow" style={{ marginBottom: 18 }}>CONTACT · BOOK A CALL</div>
          <h1 className="display" style={{ fontSize: mobile ? 'clamp(36px, 10vw, 52px)' : 'clamp(64px, 8vw, 120px)', margin: 0, maxWidth: 1100 }}>
            Let's get on a call.<br /><span style={{ color: 'var(--orange)' }}>Two options. No pitch.</span>
          </h1>
          <p style={{ color: 'var(--text-mute)', fontSize: mobile ? 17 : 20, maxWidth: 680, marginTop: 32, lineHeight: 1.5 }}>
            Pick the call that matches what you need — a 30-minute video editing review, or a 90-minute coaching deep-dive. You'll leave with a clear picture of the next move.
          </p>
        </div>
      </section>
      <section style={{ padding: mobile ? '24px 0 60px' : '40px 0 120px', background: 'var(--bg)' }}>
        <div className="wrap" style={{ display: 'grid', gridTemplateColumns: mobile ? '1fr' : '1.15fr 1fr', gap: mobile ? 32 : 48 }}>
          {/* Booking — Acuity embed */}
          <div className="card" style={{ padding: mobile ? 20 : 28 }}>
            <div className="eyebrow" style={{ marginBottom: 16 }}>STEP 01 · PICK A CALL</div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10, marginBottom: 18 }}>
              {Object.entries(ACUITY).map(([key, c]) =>
              <button key={key} className="box-pick" data-on={callType === key ? '1' : '0'} onClick={() => setCallType(key)} style={{ padding: '14px 16px', borderRadius: 12, border: '1px solid var(--line-strong)', background: 'transparent', textAlign: 'left' }}>
                  <div className="mono" style={{ fontSize: 10, color: callType === key ? 'var(--orange)' : 'var(--text-mute)', letterSpacing: '0.14em', marginBottom: 6 }}>{c.duration.toUpperCase()} · {c.price.toUpperCase()}</div>
                  <div style={{ fontWeight: 600, fontSize: 15, letterSpacing: '-0.01em' }}>{key === 'video' ? 'Video editing review' : 'Coaching deep-dive'}</div>
                </button>
              )}
            </div>
            <p style={{ color: 'var(--text-mute)', margin: 0, marginBottom: 16, fontSize: 14, lineHeight: 1.5 }}>{active.desc}</p>
            <div className="eyebrow" style={{ marginBottom: 12 }}>STEP 02 · PICK A TIME</div>
            {live ?
              <div style={{ position: 'relative', background: '#fff', borderRadius: 12, overflow: 'hidden', minHeight: mobile ? 680 : 760 }}>
                {/* Acuity Scheduling iframe embed.
                    Keyed on `callType` so switching tabs forces a clean reload to the right appointmentType. */}
                <iframe
                  key={callType}
                  src={active.url}
                  title={`Book ${active.shortLabel}`}
                  width="100%"
                  height={mobile ? 680 : 760}
                  frameBorder="0"
                  style={{ width: '100%', border: 0, display: 'block' }}
                  loading="lazy"
                ></iframe>
              </div>
              :
              <div style={{ padding: '24px', border: '1px dashed var(--line-strong)', borderRadius: 12, background: 'rgba(229,83,42,0.04)' }}>
                <div className="mono" style={{ fontSize: 10, color: 'var(--orange)', letterSpacing: '0.16em', marginBottom: 10 }}>⚠ DEV MODE — ACUITY URL NOT SET</div>
                <p style={{ margin: 0, marginBottom: 14, color: 'var(--text-mute)', fontSize: 14, lineHeight: 1.55 }}>
                  Paste the {active.shortLabel.toLowerCase()} URL into <span className="mono" style={{ color: 'var(--text)' }}>ACUITY.{callType}.url</span> at the top of <span className="mono" style={{ color: 'var(--text)' }}>pages.jsx</span> — the live calendar embed will appear here.
                </p>
                <a href={active.url} target="_blank" rel="noopener noreferrer" className="btn btn-ghost btn-sm">Preview Acuity link <span className="arrow">↗</span></a>
              </div>
            }
            <div className="mono" style={{ fontSize: 11, color: 'var(--text-dim)', marginTop: 16, letterSpacing: '0.08em' }}>POWERED BY ACUITY · TIMES SHOWN IN: {Intl.DateTimeFormat().resolvedOptions().timeZone.toUpperCase()}</div>
          </div>
          {/* Form */}
          <div className="card" id="contact-message-form" style={{ padding: mobile ? 24 : 32 }}>
            <div className="eyebrow" style={{ marginBottom: 16 }}>OR · SEND A NOTE</div>
            <h2 className="display" style={{ fontSize: 28, margin: 0, marginBottom: 24 }}>Get in touch</h2>
            <form onSubmit={handleContactSubmit} style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
                <div>
                  <label className="lbl">First name</label>
                  <input className="input" required value={form.first} onChange={(e) => setForm({ ...form, first: e.target.value })} />
                </div>
                <div>
                  <label className="lbl">Last name</label>
                  <input className="input" required value={form.last} onChange={(e) => setForm({ ...form, last: e.target.value })} />
                </div>
              </div>
              <div>
                <label className="lbl">Email</label>
                <input type="email" className="input" required value={form.email} onChange={(e) => setForm({ ...form, email: e.target.value })} />
              </div>
              <div>
                <label className="lbl">What are you stuck on?</label>
                <textarea className="input" required value={form.msg} onChange={(e) => setForm({ ...form, msg: e.target.value })} placeholder="Tell me where you are and where you want to go." />
              </div>
              <div>
                <label className="lbl">Join the weekly email?</label>
                <div style={{ display: 'flex', gap: 8 }}>
                  {['Yes', 'No'].map((o) =>
                  <button type="button" key={o} className="pill" data-on={form.list === o ? '1' : '0'} onClick={() => setForm({ ...form, list: o })}>{o}</button>
                  )}
                </div>
              </div>
              <button type="submit" disabled={sending || sent} className="btn btn-primary" style={{ marginTop: 8, justifyContent: 'center', opacity: sending ? 0.7 : 1, cursor: (sending || sent) ? 'default' : 'pointer' }}>
                {sent ? '✓ Sent — I\'ll get back within 24h' : sending ? 'Sending…' : <>Send the message <span className="arrow">→</span></>}
              </button>
              {sendError &&
                <p className="mono" style={{ fontSize: 11, color: 'var(--orange)', margin: 0, letterSpacing: '0.06em', lineHeight: 1.5 }}>
                  ⚠ Couldn't reach the server — opening your email client as a fallback. Or email {CONTACT_EMAIL} directly.
                </p>
              }
              {!CONTACT_FORMSPREE_LIVE &&
                <p className="mono" style={{ fontSize: 10, color: 'var(--text-dim)', margin: 0, marginTop: -4, letterSpacing: '0.06em', opacity: 0.8 }}>
                  ⚠ DEV MODE — paste your Formspree ID into CONTACT_FORMSPREE_ID in pages.jsx. Submitting now opens the visitor's email client (mailto).
                </p>
              }
            </form>
          </div>
        </div>
        <div className="wrap" style={{ marginTop: 60, display: 'grid', gridTemplateColumns: mobile ? '1fr' : 'repeat(3, 1fr)', gap: 20 }}>
          <ContactCard title="Email" body="viktorzaharov@pm.me" tag="USUALLY REPLIES WITHIN 24H" />
          <ContactCard title="Location" body="North York, ON · M3J 2B9 · Canada" tag="GMT-5" />
          <ContactCard title="Social" body="@viktortimewolf — IG · YT · LI · X" tag="DM ME" />
        </div>
      </section>
    </div>);

}
function ContactCard({ title, body, tag }) {
  return (
    <div className="card" style={{ padding: 24 }}>
      <div className="eyebrow" style={{ marginBottom: 10 }}>{title}</div>
      <div style={{ fontSize: 17, fontWeight: 500, letterSpacing: '-0.01em', marginBottom: 10 }}>{body}</div>
      <div className="mono" style={{ fontSize: 10, color: 'var(--text-dim)', letterSpacing: '0.14em' }}>{tag}</div>
    </div>);

}

/* ============ TESTIMONIALS PAGE ============ */
function TestimonialsPage({ setPage, mobile }) {
  return (
    <div className="fade-in">
      <section style={{ padding: mobile ? '48px 0 32px' : '96px 0 48px', background: 'var(--bg)' }}>
        <div className="wrap">
          <div className="eyebrow" style={{ marginBottom: 18 }}>TESTIMONIALS · {ALL_TESTIMONIALS.length} VOICES</div>
          <h1 className="display" style={{ fontSize: mobile ? 'clamp(36px, 10vw, 52px)' : 'clamp(64px, 8vw, 120px)', margin: 0, maxWidth: 1100 }}>
            The <span style={{ color: 'var(--orange)' }}>receipts.</span><br />In full.
          </h1>
          <p style={{ color: 'var(--text-mute)', fontSize: mobile ? 17 : 20, maxWidth: 680, marginTop: 32, lineHeight: 1.5 }}>
            Every word here is from someone who actually did the work. No screenshots of fake DMs. No paid actors. Just the people who showed up — and what changed.
          </p>
        </div>
      </section>

      <section style={{ padding: mobile ? '24px 0 80px' : '40px 0 120px', background: 'var(--bg)' }}>
        <div className="wrap">
          <div style={{ display: 'grid', gridTemplateColumns: mobile ? '1fr' : '1fr 1fr', gap: 20 }}>
            {ALL_TESTIMONIALS.map((t, i) =>
            <figure key={i} className="card" style={{ display: 'flex', flexDirection: 'column', gap: 24, margin: 0 }}>
                <div className="mono" style={{ fontSize: 11, color: 'var(--orange)', letterSpacing: '0.16em' }}>{t.tag}</div>
                <blockquote style={{ margin: 0, fontSize: mobile ? 17 : 19, lineHeight: 1.55, letterSpacing: '-0.01em', color: 'var(--text)' }}>
                  <span style={{ color: 'var(--orange)', fontSize: 32, lineHeight: 0, verticalAlign: '-12px', marginRight: 6 }}>"</span>{t.quote}
                </blockquote>
                <figcaption style={{ display: 'flex', alignItems: 'center', gap: 14, marginTop: 'auto', paddingTop: 20, borderTop: '1px solid var(--line)' }}>
                  <div style={{ width: 44, height: 44, borderRadius: '50%', background: 'var(--bg)', border: '1px solid var(--line-strong)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontWeight: 700, color: 'var(--orange)' }}>
                    {t.name[0]}
                  </div>
                  <div>
                    <div style={{ fontWeight: 600, fontSize: 15 }}>{t.name}</div>
                    {t.handle && <div style={{ color: 'var(--text-mute)', fontSize: 13 }}>{t.handle}</div>}
                  </div>
                </figcaption>
              </figure>
            )}
          </div>
        </div>
      </section>

      <section style={{ padding: mobile ? '60px 0' : '100px 0', background: 'var(--bg-2)', borderTop: '1px solid var(--line)', borderBottom: '1px solid var(--line)' }}>
        <div className="wrap" style={{ textAlign: 'center' }}>
          <div className="eyebrow" style={{ marginBottom: 18 }}>YOUR TURN</div>
          <h2 className="display" style={{ fontSize: mobile ? 'clamp(32px, 9vw, 44px)' : 'clamp(40px, 5vw, 72px)', margin: 0, maxWidth: 900, marginLeft: 'auto', marginRight: 'auto' }}>
            Want your name on this page?
          </h2>
          <p style={{ color: 'var(--text-mute)', fontSize: mobile ? 17 : 20, maxWidth: 600, margin: '24px auto 32px', lineHeight: 1.5 }}>
            Book a discovery call. We'll find out if it's a fit — no pressure, no pitch.
          </p>
          <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap', justifyContent: 'center' }}>
            <BookButton kind="coaching" onClickFallback={() => setPage('contact')}>Book 90-min coaching call</BookButton>
            <BookButton kind="video" variant="ghost" onClickFallback={() => setPage('contact')}>Book 30-min video review</BookButton>
          </div>
        </div>
      </section>
    </div>);

}

Object.assign(window, { HomePage, ProgramsPage, AboutPage, ContactPage, TestimonialsPage, ORANGE_OPTIONS });