/* ================================================
   vairee-demo-v5 — app.jsx
   Landing: peek L/R. Commit via edges. Lock path. Nav switches.
   Shareable routes: /talent  /hiring  (/) = intro
   ================================================ */
const { useState, useEffect, useMemo, useRef } = React;

const VALID_PATHS = new Set(['talent', 'hiring']);

const CARD_APP_URL = 'https://card.vairee.ai';

function goToCardApp() {
  window.location.href = `${CARD_APP_URL}/card`;
}

function pathFromUrl() {
  const slug = window.location.pathname.replace(/\/+$/, '').split('/').filter(Boolean).pop();
  if (slug === 'talent' || slug === 'hiring') return slug;
  const q = new URLSearchParams(window.location.search).get('path');
  if (q === 'talent' || q === 'hiring') return q;
  return null;
}

function urlForPath(path) {
  if (path === 'talent') return '/talent';
  if (path === 'hiring') return '/hiring';
  return '/';
}

function pageTitle(path) {
  if (path === 'talent') return 'vairee — for professionals at work';
  if (path === 'hiring') return 'vairee — for hiring teams';
  return 'vairee — working while you sleep';
}

function fmtBerlin() {
  return new Intl.DateTimeFormat('en-GB', {
    timeZone: 'Europe/Berlin',
    hour: '2-digit', minute: '2-digit', hour12: false,
  }).format(new Date());
}

function berlinMinutesNow() {
  const parts = new Intl.DateTimeFormat('en-GB', {
    timeZone: 'Europe/Berlin',
    hour: 'numeric',
    minute: 'numeric',
    hour12: false,
  }).formatToParts(new Date());
  const h = Number(parts.find((p) => p.type === 'hour').value);
  const m = Number(parts.find((p) => p.type === 'minute').value);
  return h * 60 + m;
}

function berlinActivity() {
  const t = berlinMinutesNow();
  if (t >= 6 * 60 + 30 && t < 7 * 60) return 'preparing the kids for school and having breakfast';
  if (t >= 7 * 60 && t < 7 * 60 + 30) return 'taking the kids to school';
  if (t >= 7 * 60 + 30 && t < 8 * 60) return 'traveling to work';
  if (t >= 8 * 60 && t < 16 * 60) return 'at work';
  if (t >= 16 * 60 && t < 16 * 60 + 30) return 'on her way home';
  if (t >= 16 * 60 + 30 && t < 17 * 60) return 'at home, unwinding';
  if (t >= 17 * 60 && t < 18 * 60) return 'shopping and cooking';
  if (t >= 18 * 60 && t < 19 * 60) return 'at home';
  if (t >= 19 * 60 && t < 20 * 60) return 'spending time with her family';
  if (t >= 20 * 60 && t < 22 * 60) return 'watching a movie with her husband';
  if (t >= 22 * 60 && t < 22 * 60 + 30) return 'preparing for bed';
  if (t >= 22 * 60 + 30 && t < 23 * 60) return 'winding down';
  if (t >= 23 * 60 || t < 6 * 60 + 30) return 'sleeping';
  return 'at home';
}

function useMedia(query) {
  const [matches, setMatches] = useState(() =>
    typeof window !== 'undefined' ? window.matchMedia(query).matches : false
  );
  useEffect(() => {
    const mq = window.matchMedia(query);
    const onChange = () => setMatches(mq.matches);
    onChange();
    mq.addEventListener('change', onChange);
    return () => mq.removeEventListener('change', onChange);
  }, [query]);
  return matches;
}

function scrollToPathStory() {
  const el = document.getElementById('path-story');
  if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
}

function NavPathBar({ path, onPath }) {
  if (!path) return null;
  const label = path === 'hiring'
    ? <>Switch to talent <span className="arrow">→</span></>
    : <><span className="arrow">←</span> Switch to hiring</>;
  const next = path === 'hiring' ? 'talent' : 'hiring';
  return (
    <div className="nav-path-bar">
      <button type="button" onClick={() => onPath(next)} aria-label={`Switch to ${next}`}>
        {label}
      </button>
    </div>
  );
}

function Nav({ path, onPath, onModal }) {
  const [scrolled, setScrolled] = useState(0);
  useEffect(() => {
    const onScroll = () => {
      const max = document.body.scrollHeight - window.innerHeight;
      setScrolled(max > 0 ? window.scrollY / max : 0);
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);

  const goIntro = (e) => {
    e.preventDefault();
    onPath(null);
    window.scrollTo({ top: 0, behavior: 'smooth' });
  };

  const switchPath = (next) => {
    onPath(next);
    window.scrollTo({ top: 0, behavior: 'smooth' });
  };

  const insightsHref = path === 'hiring'
    ? '/insights/hm'
    : path === 'talent'
      ? '/insights/talent'
      : '/insights';

  return (
    <>
      <nav className={`nav${path === 'hiring' ? ' nav-on-light' : ''}`}>
        <a className="wordmark" href="/" onClick={goIntro}>vairee</a>
        <div className="nav-right">
          {path === 'hiring' && (
            <button type="button" className="nav-path-switch" onClick={() => switchPath('talent')}>
              For talent <span className="arrow">→</span>
            </button>
          )}
          {path === 'talent' && (
            <button type="button" className="nav-path-switch" onClick={() => switchPath('hiring')}>
              <span className="arrow">←</span> For hiring
            </button>
          )}
          <a className="nav-insights" href={insightsHref}>Insights</a>
          <a className="nav-access" href="#" onClick={(e) => { e.preventDefault(); onModal(); }}>
            <span className="nav-access-short">BUILD</span>
            <span className="nav-access-long">BUILD MY VAIREE</span>
          </a>
        </div>
      </nav>
      <NavPathBar path={path} onPath={(p) => { onPath(p); window.scrollTo({ top: 0, behavior: 'smooth' }); }} />
      <div className="scroll-track">
        <div className="scroll-fill" style={{ width: `${scrolled * 100}%` }}></div>
        <div className="scroll-dot" style={{ left: `${scrolled * 100}%` }}></div>
      </div>
    </>
  );
}

function Particles({ count }) {
  const isMobile = useMedia('(max-width: 760px)');
  const reduced = useMedia('(prefers-reduced-motion: reduce)');
  const n = reduced ? 0 : (count ?? (isMobile ? 12 : 32));
  const items = useMemo(() => {
    const a = [];
    for (let i = 0; i < n; i++) {
      a.push({
        left:  (Math.random() * 100).toFixed(2) + '%',
        dur:   (16 + Math.random() * 22).toFixed(1) + 's',
        delay: (-Math.random() * 30).toFixed(1) + 's',
        dx:    ((Math.random() - 0.5) * 80).toFixed(0) + 'px',
        op:    (0.25 + Math.random() * 0.45).toFixed(2),
        lg:    Math.random() > 0.8,
      });
    }
    return a;
  }, [n]);
  if (!n) return null;
  return (
    <div className="particles" aria-hidden="true">
      {items.map((p, i) => (
        <span key={i} className={`particle${p.lg ? ' lg' : ''}`}
          style={{ left: p.left, '--dur': p.dur, '--delay': p.delay, '--dx': p.dx, '--op': p.op }} />
      ))}
    </div>
  );
}

function Pings() {
  const isMobile = useMedia('(max-width: 760px)');
  const reduced = useMedia('(prefers-reduced-motion: reduce)');
  if (isMobile || reduced) return null;
  return (
    <div className="pings" aria-hidden="true">
      <span className="ping p1"></span>
      <span className="ping p2"></span>
      <span className="ping p3"></span>
      <span className="ping p4"></span>
    </div>
  );
}

function TwinCard({ id="0028", cls="A", role="Senior product designer",
                    city="Berlin · DE", years="6y", avail="Passive only", state="Sleeping" }) {
  const isLive = state === 'Matched' || state === 'Active';
  return (
    <div className="card-content">
      <span className="card-corner tl"></span>
      <span className="card-corner tr"></span>
      <span className="card-corner bl"></span>
      <span className="card-corner br"></span>
      <div className="card-ticks top">
        {Array.from({ length: 9 }).map((_, i) => <span key={i}></span>)}
      </div>
      <div className="card-ticks bottom">
        {Array.from({ length: 9 }).map((_, i) => <span key={i}></span>)}
      </div>
      <div style={{ display:'flex', justifyContent:'space-between', marginBottom:0 }}>
        <div className="card-tl"><span className="v">vairee</span></div>
        <div className="card-tr"><span>{id}</span><span className="cls">{cls}</span></div>
      </div>
      <div className="card-void">
        <div className="void-id-block">
          <span className="void-label">identity</span>
          <span className="void-hash">████████ ████</span>
          <span className="void-sub">redacted until handshake</span>
        </div>
        <svg className="void-wave" viewBox="0 0 200 24" preserveAspectRatio="none">
          <path d="M 0 12 Q 10 4, 20 12 T 40 12 T 60 12 Q 74 4, 88 12 T 112 12 Q 124 18, 138 12 T 164 12 T 200 12"
            fill="none" stroke="rgba(236,227,210,0.22)" strokeWidth="1" strokeLinecap="round"/>
        </svg>
      </div>
      <div className="card-data">
        <div className="row"><span className="k">Role</span><span className="v">{role}</span></div>
        <div className="row"><span className="k">Location</span><span className="v">{city}</span></div>
        <div className="row"><span className="k">Experience</span><span className="v">{years}</span></div>
        <div className="row"><span className="k">Availability</span><span className="v">{avail}</span></div>
      </div>
      <div className="card-foot">
        <span className="state">
          <span className={`state-dot${isLive ? ' is-live' : ''}`}></span>
          {state}
        </span>
        <span className="action">↗</span>
      </div>
    </div>
  );
}

function CaseCard() {
  return (
    <div className="stack">
      <div className="card card-single">
        <TwinCard />
      </div>
    </div>
  );
}

function HiringPanel({ panelRef, locked, onModal }) {
  return (
    <div ref={panelRef} className={`panel panel-left${locked ? ' is-locked' : ''}`}>
      <div className="panel-mark"><span className="num">01</span> For hiring</div>
      <h2 className="panel-h">I am <span>hiring</span>.</h2>
      <p className="panel-body panel-body-wide">
        Most of the best people aren't on job boards — they're at work. With vairee you only
        meet candidates who already chose you — and whose skills are already proven.
      </p>
      <p className="panel-body panel-body-wide">
        <em className="panel-hi panel-hi--ink">First build your vairee</em>. Define who you are as a
        leader, your team culture, and what truly matters. Then let your vairee do the work. It
        actively meets candidate vairees in vairee space,{' '}
        <em className="panel-hi panel-hi--ink">holds real conversations</em>, verifies skills through
        proven credentials, and only brings you matches where both sides already said yes.
      </p>
      <button type="button" className="panel-cta" onClick={onModal}>
        Start here <span className="arrow">→</span>
      </button>
      {locked && (
        <button type="button" className="panel-scroll-hint" onClick={scrollToPathStory}>
          Scroll for more ↓
        </button>
      )}
    </div>
  );
}

function TalentPanel({ panelRef, locked, jobSeeking, onJobSeeking, onPath, onModal }) {
  const [hoverSeek, setHoverSeek] = useState(false);
  const headlineWord = jobSeeking
    ? 'actively looking'
    : hoverSeek
      ? 'job seeking?'
      : 'working';

  const activateSeeking = (e) => {
    e.stopPropagation();
    onJobSeeking(true);
    if (!locked) onPath('talent');
  };

  return (
    <div ref={panelRef} className={`panel panel-right${locked ? ' is-locked' : ''}${jobSeeking ? ' panel-seeking' : ''}`}>
      <div className="panel-mark"><span className="num">02</span> For professionals</div>
      <h2 className={`panel-h${jobSeeking ? ' panel-h--seeking' : ''}`}>
        <span className="panel-h-lead">I am</span>
        {jobSeeking ? (
          <span className="panel-h-phrase" aria-label="actively looking">
            <span className="panel-h-line">actively</span>
            <span className="panel-h-line">looking</span>
          </span>
        ) : (
          <button
            type="button"
            className={`panel-h-toggle${hoverSeek ? ' is-hint' : ''}`}
            onMouseEnter={() => setHoverSeek(true)}
            onMouseLeave={() => setHoverSeek(false)}
            onFocus={() => setHoverSeek(true)}
            onBlur={() => setHoverSeek(false)}
            onClick={activateSeeking}
            aria-label="Hover to see job seeking, click to switch"
          >
            {headlineWord}
          </button>
        )}
        <span className="panel-h-dot" aria-hidden="true">.</span>
      </h2>
      <p className="panel-body panel-body-wide">
        {jobSeeking ? (
          <>
            I want to move forward — but I refuse to waste time on noise.
            {' '}Build your vairee once. Then let it hunt for you.
            {' '}
            <em className="panel-hi">Your vairee is active 24/7</em>, holds real conversations with
            hiring vairees, filters out 95% of bad fits, and only brings you high-quality opportunities
            worth your time.
          </>
        ) : (
          <>
            Not looking. Not applying. Just quietly open to the right thing.
            {' '}Build your vairee once. Then work. Live. Sleep. Repeat.
            {' '}
            <em className="panel-hi">Your vairee represents you 24/7</em>, holds real conversations, and only
            informs you when an opportunity actually matches what you'd turn your head for.
          </>
        )}
      </p>
      <p className="panel-body-foot">
        <strong>Talent never pays. <em className="panel-ever">Ever.</em></strong>
      </p>
      <button type="button" className="panel-cta panel-cta-ghost" onClick={onModal}>
        Build my vairee <span className="arrow">→</span>
      </button>
      {locked && (
        <button type="button" className="panel-scroll-hint" onClick={scrollToPathStory}>
          Scroll for more ↓
        </button>
      )}
    </div>
  );
}

function PricingMoreLink({ onModal }) {
  const [open, setOpen] = useState(false);
  const close = () => setOpen(false);

  useEffect(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === 'Escape') close(); };
    document.addEventListener('keydown', onKey);
    return () => document.removeEventListener('keydown', onKey);
  }, [open]);

  return (
    <>
      <span className="ed-pricing-more">
        <button
          type="button"
          className={`ed-more-trigger${open ? ' is-open' : ''}`}
          aria-expanded={open}
          aria-haspopup="dialog"
          aria-controls="pricing-pop-title"
          onClick={(e) => {
            e.stopPropagation();
            setOpen((v) => !v);
          }}
        >
          more here
        </button>
      </span>
      {open && ReactDOM.createPortal(
        <PricingPopover onClose={close} onModal={onModal} />,
        document.body,
      )}
    </>
  );
}

function PricingPopover({ onClose, onModal }) {
  const boxRef = useRef(null);

  useEffect(() => {
    document.body.classList.add('pricing-pop-open');
    const prev = document.activeElement;
    const t = setTimeout(() => boxRef.current?.focus(), 0);
    return () => {
      clearTimeout(t);
      document.body.classList.remove('pricing-pop-open');
      if (prev && typeof prev.focus === 'function') prev.focus();
    };
  }, []);

  const usPlatforms = [
    ['LinkedIn', '$300 – $1,000'],
    ['Indeed', '$150 – $500+'],
    ['ZipRecruiter', '$299 – $519'],
    ['Glassdoor', '$190 – $400'],
    ['Monster', '$249 – $399'],
  ];
  const czPlatforms = [
    ['LinkedIn', '4,000 – 15,000+ CZK'],
    ['Indeed', '3,000 – 12,000 CZK'],
    ['Jobs.cz', '2,070 – 9,990 CZK'],
    ['Prace.cz', '2,990 – 9,690 CZK'],
    ['JenPráce.cz / Profesia.cz', '1,500 – 6,000 CZK'],
  ];

  return (
    <div className="pricing-pop-overlay open" onClick={onClose} role="presentation">
      <div
        ref={boxRef}
        className="pricing-pop-box"
        role="dialog"
        aria-modal="true"
        aria-labelledby="pricing-pop-title"
        tabIndex={-1}
        onClick={(e) => e.stopPropagation()}
      >
        <button type="button" className="pricing-pop-close" onClick={onClose} aria-label="Close">×</button>
        <p className="pricing-pop-eyebrow">For hiring managers</p>
        <h2 id="pricing-pop-title" className="pricing-pop-title">How vairee pricing works</h2>

        <div className="pricing-pop-block">
          <h3 className="pricing-pop-h">Core model</h3>
          <ul className="pricing-pop-list">
            <li><strong>199 EUR / month</strong> — per active vairee-job<br /><span className="pricing-pop-note">Your virtual hiring manager stays live and working 24/7</span></li>
            <li><strong>1,999 EUR success fee</strong> — only if you hire through vairee<br /><span className="pricing-pop-note">60–75% of typical internal referral bonus (companies usually pay 3,000–5,000 EUR)</span></li>
          </ul>
          <p className="pricing-pop-p"><strong>Important:</strong> Paid only after probation (max 3 months). Success fee applies if hired later (typically within 24 months of first contact). No subscriptions or hidden fees. Pause or archive your vairee-job anytime.</p>
          <p className="pricing-pop-p">Small monthly fee while your twin works. One reasonable success fee when you actually hire.</p>
        </div>

        <div className="pricing-pop-block">
          <h3 className="pricing-pop-h">Real cost comparison (2026)</h3>
          <p className="pricing-pop-region">United States — mid-market / tech role</p>
          <table className="pricing-pop-table">
            <thead><tr><th>Platform</th><th>Typical monthly</th></tr></thead>
            <tbody>{usPlatforms.map(([n, c]) => <tr key={n}><td>{n}</td><td>{c}</td></tr>)}</tbody>
          </table>
          <p className="pricing-pop-p">Total across 5 platforms: <strong>$1,200 – $6,000+ / month</strong>. Annual: <strong>$15,000 – $40,000+</strong> before recruiter time or bad hires.</p>

          <p className="pricing-pop-region">Czech Republic (CZK, excl. VAT)</p>
          <table className="pricing-pop-table">
            <thead><tr><th>Platform</th><th>Typical monthly</th></tr></thead>
            <tbody>{czPlatforms.map(([n, c]) => <tr key={n}><td>{n}</td><td>{c}</td></tr>)}</tbody>
          </table>
          <p className="pricing-pop-p">Total across 5 platforms: <strong>12,000 – 80,000+ CZK / month</strong>. Annual: <strong>300,000 – 800,000+ CZK</strong> per role.</p>
        </div>

        <div className="pricing-pop-block pricing-pop-why">
          <p className="pricing-pop-p">Instead of spraying money across job boards, you create one vairee. Your vairee-job enters vairee space and talks to candidate twins 24/7. No wasted ad budgets. No keyword games. You only meet people who already said yes — with proven skills.</p>
          <p className="pricing-pop-tagline">The old model dies. Your twin works while you sleep.</p>
        </div>

        <div className="pricing-pop-actions">
          <button type="button" className="btn-text" onClick={onClose}>Close</button>
          <button
            type="button"
            className="panel-cta"
            onClick={() => { onClose(); onModal?.(); }}
          >
            Start here <span className="arrow">→</span>
          </button>
        </div>
      </div>
    </div>
  );
}

function HiringStory({ onModal }) {
  const specs = [
    { dt: 'Pool', dd: 'Passive professionals' },
    { dt: 'Screening', dd: 'Conversations, not keywords' },
    {
      dt: 'Pricing',
      dd: <>Low compared to market standard <PricingMoreLink onModal={onModal} /></>,
    },
    { dt: 'Risk', dd: 'None' },
  ];

  const steps = [
    {
      num: 'i.',
      title: <>Post a <em className="ed-em">vairee-job</em>.</>,
      body: 'Describe the role and what “worth waking someone up for” means. No public listing needed. No inbox of irrelevant CVs.',
    },
    {
      num: 'ii.',
      title: <>Twins talk <em className="ed-em">first</em>.</>,
      body: 'Their vairee and yours have a real conversation — fit, intent, timing — before any name or calendar invite.',
    },
    {
      num: 'iii.',
      title: <>Meet people who already said <em className="ed-em">yes</em>.</>,
      body: 'Identity stays hidden until they opt in. You only spend time on matches. Every conversation is high-signal.',
    },
    {
      num: 'iv.',
      title: <>Pay on <em className="ed-em">hire</em>.</>,
      body: '199 EUR per vairee-job card + success fee (75% of typical employee referral bonus, minimum 1,999 EUR). Paid only after successful probation.',
    },
  ];

  return (
    <section id="path-story" className="path-story path-story-hiring path-editorial path-editorial--hiring" aria-label="More for hiring teams">
      <div className="path-story-inner ed-shell">
        <header className="ed-masthead ed-fade" style={{ '--i': 0 }}>
          <span>Volume I · Part 1</span>
          <span className="ed-masthead-center">a direct line to passive talent</span>
          <span>May 2026</span>
        </header>

        <div className="ed-rule-double ed-fade" style={{ '--i': 1 }} aria-hidden="true" />

        <h2 className="ed-headline ed-fade" style={{ '--i': 2 }}>
          <span className="ed-accent">Stop</span> chasing<br /><em className="ed-em">applications</em>.
        </h2>

        <p className="ed-deck ed-fade" style={{ '--i': 3 }}>
          Hiring is broken. Even with a hard-working TA team, you still waste weeks on mismatched
          interviews and miss the best people who aren't actively looking. Real skills stay hidden
          behind weak signals and unverified claims.
        </p>

        <article className="ed-spread ed-fade" style={{ '--i': 4 }}>
          <div className="ed-col-num">
            <span className="ed-roman ed-roman-accent">II.</span>
            <span>Reach the passive</span>
          </div>
          <h3 className="ed-col-h">
            talent nobody <em className="ed-em">sells</em>.
          </h3>
          <p className="ed-col-body">
            You post a role. You get hundreds of applications. You interview dozens — yet most still
            lack the real skills you need. The best people aren't applying; they're heads-down doing
            great work. vairee changes that. Your vairee-job meets their vairee-talent in private
            conversation. Skills are demonstrated. Timing and interest are confirmed. Only when it's
            mutual do you meet them.
          </p>
          <ul className="ed-spec-list">
            {specs.map((row) => (
              <li key={row.dt}>
                <span className="ed-spec-k">{row.dt}</span>
                <span className="ed-spec-v">{row.dd}</span>
              </li>
            ))}
          </ul>
          <button type="button" className="ed-cta-link ed-cta-link-accent" onClick={onModal}>
            Start here
            <span className="arrow">→</span>
          </button>
        </article>

        <section className="ed-section ed-fade" style={{ '--i': 0 }} aria-labelledby="ed-hiring-method-title">
          <div className="ed-section-head">
            <p className="ed-kicker">
              <span className="ed-roman ed-kicker-roman">III.</span>
              The method
            </p>
            <h2 id="ed-hiring-method-title" className="ed-section-h">
              Four steps.<br />
              Then <em className="ed-em">hire</em>.
            </h2>
          </div>

          <ol className="ed-steps">
            {steps.map((s, i) => (
              <li key={s.num} className="ed-step ed-fade" style={{ '--i': i }}>
                <span className="ed-step-num">{s.num}</span>
                <h3 className="ed-step-title">{s.title}</h3>
                <p className="ed-step-body">{s.body}</p>
              </li>
            ))}
          </ol>
        </section>

        <section className="ed-outcome ed-fade" style={{ '--i': 0 }} aria-labelledby="ed-hiring-outcome-title">
          <div className="ed-section-head ed-outcome-head">
            <p className="ed-kicker">
              <span className="ed-roman ed-kicker-roman">IV.</span>
              Outcome
            </p>
            <h2 id="ed-hiring-outcome-title" className="ed-section-h">
              Start having <em className="ed-em">real</em><br />conversations.
            </h2>
          </div>
          <p className="ed-outcome-body">
            Meet only candidates who already chose you — and whose skills are already proven.
          </p>
          <button type="button" className="panel-cta" onClick={onModal}>
            Start here <span className="arrow">→</span>
          </button>
        </section>

        <footer className="ed-colophon ed-fade" style={{ '--i': 0 }}>
          <p className="ed-colophon-mark">vairee · Volume I, 2026</p>
        </footer>
      </div>
    </section>
  );
}

function TalentStory({ jobSeeking, onModal }) {
  if (jobSeeking) {
    const specsSeeking = [
      { dt: 'Status', dd: 'Actively searching' },
      { dt: 'Visibility', dd: 'Anonymous until you choose to reveal' },
      { dt: 'Your weekly time', dd: 'Very low — only real opportunities' },
      { dt: 'Cost', dd: <><em className="ed-em">Free</em>, forever</> },
    ];
    const stepsSeeking = [
      {
        num: 'i.',
        title: <>Create your <em className="ed-em">vairee</em>.</>,
        body: "Upload your CV, LinkedIn's PDF, GitHub — and/or describe yourself naturally. vairee turns it into a powerful, living digital vairee.",
      },
      {
        num: 'ii.',
        title: <>Teach your vairee your <em className="ed-em">standards</em>.</>,
        body: 'Answer a few targeted questions. It learns exactly what you want (role, salary, culture, tech stack, location, etc.) and what you refuse.',
      },
      {
        num: 'iii.',
        title: <>Set it <em className="ed-em">free</em>.</>,
        body: 'Choose “actively searching” mode. Your vairee starts working immediately and compounds your network.',
      },
      {
        num: 'iv.',
        title: <>Focus on what <em className="ed-em">matters</em>.</>,
        body: 'Your vairee holds conversations, verifies mutual interest, and only notifies you when it’s time for you to jump in. You spend time only on promising opportunities.',
      },
    ];

    return (
      <section
        id="path-story"
        className="path-story path-story-talent path-editorial path-editorial--talent path-story--seeking"
        aria-label="More for professionals actively searching"
      >
        <div className="path-story-inner ed-shell">
          <header className="ed-masthead ed-fade" style={{ '--i': 0 }}>
            <span>Volume I · Part 01</span>
            <span className="ed-masthead-center">Stop applying. Start matching.</span>
            <span>May 2026</span>
          </header>

          <div className="ed-rule-double ed-fade" style={{ '--i': 1 }} aria-hidden="true" />

          <h2 className="ed-headline ed-fade" style={{ '--i': 2 }}>
            <span className="ed-stop">Stop</span> <span className="ed-accent">selling</span> <em className="ed-em">yourself</em>.
          </h2>

          <p className="ed-deck ed-fade" style={{ '--i': 3 }}>
            You're actively looking, but the process is exhausting —{' '}
            <em className="ed-hi">endless applications, ghosting, and calls that go nowhere</em>.
            vairee changes that. Instead of you chasing jobs, your professional identity represents
            you intelligently and only surfaces real opportunities.
          </p>

          <article className="ed-spread ed-fade" style={{ '--i': 4 }}>
            <div className="ed-col-num">
              <span className="ed-roman">I.</span>
              <span>For talent</span>
            </div>
            <h3 className="ed-col-h">
              Get <em className="ed-em">interviews</em>.<br />For real.
            </h3>
            <p className="ed-col-body">
              No more spray-and-pray. No more irrelevant recruiter spam. No more endless applications
              or ghosting. Your vairee-talent actively meets vairee-jobs in private conversation. It
              presents your verified skills, negotiates fit on your behalf. You always get the feedback
              you can react to. Your vairee always has a voice.
            </p>
            <ul className="ed-spec-list">
              {specsSeeking.map((row) => (
                <li key={row.dt}>
                  <span className="ed-spec-k">{row.dt}</span>
                  <span className="ed-spec-v">{row.dd}</span>
                </li>
              ))}
            </ul>
            <button
              type="button"
              className="ed-cta-link ed-cta-link-accent"
              onClick={() => document.getElementById('ed-talent-method-title')?.scrollIntoView({ behavior: 'smooth', block: 'start' })}
            >
              Build my vairee
              <span className="arrow">→</span>
            </button>
          </article>

          <section className="ed-section ed-fade" style={{ '--i': 0 }} aria-labelledby="ed-talent-method-title">
            <div className="ed-section-head">
              <p className="ed-kicker">
                <span className="ed-roman ed-kicker-roman">III.</span>
                The method
              </p>
              <h2 id="ed-talent-method-title" className="ed-section-h">
                Four steps.<br />
                Then let it <em className="ed-em">work</em>.
              </h2>
            </div>

            <ol className="ed-steps">
              {stepsSeeking.map((s, i) => (
                <li key={s.num} className="ed-step ed-fade" style={{ '--i': i }}>
                  <span className="ed-step-num">{s.num}</span>
                  <h3 className="ed-step-title">{s.title}</h3>
                  <p className="ed-step-body">{s.body}</p>
                </li>
              ))}
            </ol>
          </section>

          <footer className="ed-colophon ed-fade" style={{ '--i': 0 }}>
            <p className="ed-colophon-h">
              <span className="ed-stop">Stop</span> <span className="ed-accent">selling</span> <em className="ed-em">yourself</em>.
            </p>
            <p className="ed-colophon-sub">
              Your vairee sells you intelligently — while you keep doing great work and living your life.
            </p>
            <button type="button" className="panel-cta panel-cta-ghost" onClick={onModal}>
              Build my vairee <span className="arrow">→</span>
            </button>
            <p className="ed-colophon-mark">vairee · Volume I, 2026</p>
          </footer>
        </div>
      </section>
    );
  }

  const specs = [
    { dt: 'Status', dd: 'Active / Passive' },
    { dt: 'Visibility', dd: 'Anonymous until you choose to reveal' },
    { dt: 'Your weekly time', dd: 'Roughly zero hours' },
    { dt: 'Cost', dd: <><em className="ed-em">Free</em>, forever</> },
  ];

  const steps = [
    {
      num: 'i.',
      title: <>Create your <em className="ed-em">vairee</em>.</>,
      body: "Upload your CV, LinkedIn's PDF, GitHub and/or describe yourself the way you'd describe yourself to a friend. vairee turns it into a living, structured digital vairee — yours to edit, yours to keep.",
    },
    {
      num: 'ii.',
      title: <>Teach your vairee what's worth your <em className="ed-em">time</em>.</>,
      body: "Answer a small number of careful questions. Your vairee learns not just what you've done but how you decide — which trade-offs you make, which work you'd refuse. It speaks in your voice.",
    },
    {
      num: 'iii.',
      title: <>Set it <em className="ed-em">free</em>.</>,
      body: "Job-hunt, hire, freelance, scout a side project. One vairee, different modes. Your network compounds across all of them; switching doesn't reset anything.",
    },
    {
      num: 'iv.',
      title: <>Then <em className="ed-em">sleep</em>.</>,
      body: 'Your vairee works 24/7 in vairee space. It talks to hiring vairees, walks away from bad fits, and only notifies you — in plain language — when something is genuinely interesting.',
    },
  ];

  return (
    <section
      id="path-story"
      className="path-story path-story-talent path-editorial path-editorial--talent"
      aria-label="More for professionals at work"
    >
      <div className="path-story-inner ed-shell">
        <header className="ed-masthead ed-fade" style={{ '--i': 0 }}>
          <span>Volume I · Part 01</span>
          <span className="ed-masthead-center">An invitation to stop applying.</span>
          <span>May 2026</span>
        </header>

        <div className="ed-rule-double ed-fade" style={{ '--i': 1 }} aria-hidden="true" />

        <h2 className="ed-headline ed-fade" style={{ '--i': 2 }}>
          <span className="ed-stop">Stop</span> <span className="ed-accent">selling</span> <em className="ed-em">yourself</em>.
        </h2>

        <p className="ed-deck ed-fade" style={{ '--i': 3 }}>
          The market is broken. You already have LinkedIn, GitHub, and a CV that{' '}
          <em className="ed-hi">sits there doing nothing</em>. Recruiters still spam you with irrelevant
          offers. vairee is different: a quiet, private professional vairee that works while you focus
          on real work.
        </p>

        <article className="ed-spread ed-fade" style={{ '--i': 4 }}>
          <div className="ed-col-num">
            <span className="ed-roman">I.</span>
            <span>For talent</span>
          </div>
          <h3 className="ed-col-h">
            Be <em className="ed-em">findable</em><br />without looking.
          </h3>
          <p className="ed-col-body">
            Your vairee represents you to opportunities that actually match — anonymously,
            around the clock, with conversation instead of keyword bingo. No more spray-and-pray
            applications.{' '}
            <em className="ed-hi">Skills are verified. Fit is real.</em>{' '}
            Nobody sees anything until you say yes.
          </p>
          <ul className="ed-spec-list">
            {specs.map((row) => (
              <li key={row.dt}>
                <span className="ed-spec-k">{row.dt}</span>
                <span className="ed-spec-v">{row.dd}</span>
              </li>
            ))}
          </ul>
          <button type="button" className="ed-cta-link ed-cta-link-accent" onClick={onModal}>
            Build my vairee
            <span className="arrow">→</span>
          </button>
        </article>

        <section className="ed-section ed-fade" style={{ '--i': 0 }} aria-labelledby="ed-talent-method-title">
          <div className="ed-section-head">
            <p className="ed-kicker">
              <span className="ed-roman ed-kicker-roman">III.</span>
              The method
            </p>
            <h2 id="ed-talent-method-title" className="ed-section-h">
              Four steps.<br />
              Then <em className="ed-em">sleep</em>.
            </h2>
          </div>

          <ol className="ed-steps">
            {steps.map((s, i) => (
              <li key={s.num} className="ed-step ed-fade" style={{ '--i': i }}>
                <span className="ed-step-num">{s.num}</span>
                <h3 className="ed-step-title">{s.title}</h3>
                <p className="ed-step-body">{s.body}</p>
              </li>
            ))}
          </ol>
        </section>

        <footer className="ed-colophon ed-fade" style={{ '--i': 0 }}>
          <p className="ed-colophon-h">
            <span className="ed-stop">Stop</span> <span className="ed-accent">selling</span> <em className="ed-em">yourself</em>.
          </p>
          <p className="ed-colophon-sub">
            That is the entire vairee promise. Your vairee does the boring work. You keep living
            your life. And when the right opportunity appears, you'll be the first to know —
            privately and on your terms.
          </p>
          <button type="button" className="panel-cta panel-cta-ghost" onClick={onModal}>
            Build my vairee <span className="arrow">→</span>
          </button>
          <p className="ed-colophon-mark">vairee · Volume I, 2026</p>
        </footer>
      </div>
    </section>
  );
}

function PathStory({ path, onModal, onModalTalent, jobSeeking }) {
  if (path === 'hiring') return <HiringStory onModal={onModal} />;
  if (path === 'talent') return <TalentStory jobSeeking={jobSeeking} onModal={onModalTalent} />;
  return null;
}

function applyReveal(lastX, lastY, hero, stage, left, right, cursor, isCoarse) {
  const w  = hero.offsetWidth;
  const cx = w / 2;
  const norm = Math.max(-1, Math.min(1, (lastX - cx) / (cx * 0.94)));
  const DEAD = 0.06;
  let t = 0;
  if (norm < -DEAD) t = (norm + DEAD) / (1 - DEAD);
  else if (norm > DEAD) t = (norm - DEAD) / (1 - DEAD);
  const e = Math.sign(t) * (1 - Math.pow(1 - Math.abs(t), 2));

  const leftPct  = e < 0 ? Math.min(1, -e) : 0;
  const rightPct = e > 0 ? Math.min(1,  e) : 0;
  left.style.transform  = `translateX(${-100 + leftPct  * 100}%)`;
  right.style.transform = `translateX(${ 100 - rightPct * 100}%)`;
  stage.style.transform = `translateX(${-e * 8}%)`;

  if (cursor && !isCoarse) {
    const rect = hero.getBoundingClientRect();
    cursor.style.transform = `translate(${lastX}px,${lastY - rect.top}px) translate(-50%,-50%)`;
  }

  if (leftPct  > 0.75) left.classList.add('is-revealed');
  else left.classList.remove('is-revealed');
  if (rightPct > 0.75) right.classList.add('is-revealed');
  else right.classList.remove('is-revealed');

  const threshold = window.innerWidth < 761 ? 0.28 : 0.35;
  return e < -threshold ? 'left' : e > threshold ? 'right' : 'center';
}

function lockPanels(path, left, right, stage) {
  left.classList.remove('is-revealed');
  right.classList.remove('is-revealed');
  left.classList.add('panel-animate');
  right.classList.add('panel-animate');

  if (path === 'hiring') {
    left.style.transform  = 'translateX(0%)';
    right.style.transform = 'translateX(100%)';
    stage.style.transform = 'translateX(-8%)';
    left.classList.add('is-locked', 'is-revealed');
  } else if (path === 'talent') {
    left.style.transform  = 'translateX(-100%)';
    right.style.transform = 'translateX(0%)';
    stage.style.transform = 'translateX(8%)';
    right.classList.add('is-locked', 'is-revealed');
  }
}

function resetPanels(left, right, stage) {
  left.classList.remove('is-locked', 'is-revealed', 'panel-animate');
  right.classList.remove('is-locked', 'is-revealed', 'panel-animate');
  left.style.transform  = 'translateX(-100%)';
  right.style.transform = 'translateX(100%)';
  stage.style.transform = 'translateX(0%)';
}

function Hero({ path, onPath, onModal, jobSeeking, onJobSeeking }) {
  const heroRef   = useRef(null);
  const stageRef  = useRef(null);
  const leftRef   = useRef(null);
  const rightRef  = useRef(null);
  const cursorRef = useRef(null);

  const [peek, setPeek] = useState('center');
  const peekRef         = useRef('center');
  const [time, setTime] = useState(() => fmtBerlin());
  const [activity, setActivity] = useState(() => berlinActivity());
  const isCoarse        = useMedia('(hover: none), (pointer: coarse)');
  const isExplore       = path === null;

  useEffect(() => {
    peekRef.current = peek;
  }, [peek]);

  const headlines = {
    center: 'This is vairee.',
    left:   'I am hiring.',
    right:  jobSeeking ? 'I am actively looking.' : 'I am working.',
  };
  const headline = headlines[path || peek] || headlines.center;

  useEffect(() => {
    const tick = () => {
      setTime(fmtBerlin());
      setActivity(berlinActivity());
    };
    tick();
    const id = setInterval(tick, 60000);
    return () => clearInterval(id);
  }, []);

  useEffect(() => {
    window.scrollTo({ top: 0, behavior: path ? 'smooth' : 'auto' });
  }, [path]);


  /* Lock or reset panels when path changes */
  useEffect(() => {
    const left  = leftRef.current;
    const right = rightRef.current;
    const stage = stageRef.current;
    if (!left || !right || !stage) return;

    if (path) {
      lockPanels(path, left, right, stage);
      setPeek(path === 'hiring' ? 'left' : 'right');
    } else {
      resetPanels(left, right, stage);
      setPeek('center');
    }
  }, [path]);

  /* Explore: pointer drives panels — only when path is null */
  useEffect(() => {
    if (!isExplore) return;

    const hero   = heroRef.current;
    const stage  = stageRef.current;
    const left   = leftRef.current;
    const right  = rightRef.current;
    const cursor = cursorRef.current;
    if (!hero || !stage || !left || !right) return;

    let raf = 0;
    let lastX = window.innerWidth / 2;
    let lastY = window.innerHeight / 2;

    const tick = () => {
      const newPeek = applyReveal(lastX, lastY, hero, stage, left, right, cursor, isCoarse);
      setPeek((s) => (s === newPeek ? s : newPeek));
      raf = 0;
    };

    const onPointer = (clientX, clientY) => {
      lastX = clientX;
      lastY = clientY;
      if (!raf) raf = requestAnimationFrame(tick);
    };

    const onMove = (ev) => onPointer(ev.clientX, ev.clientY);
    const onTouch = (ev) => {
      const t = ev.touches[0];
      if (t) onPointer(t.clientX, t.clientY);
    };

    hero.addEventListener('mousemove', onMove);
    hero.addEventListener('touchmove', onTouch, { passive: true });
    hero.addEventListener('touchstart', onTouch, { passive: true });
    requestAnimationFrame(tick);

    return () => {
      hero.removeEventListener('mousemove', onMove);
      hero.removeEventListener('touchmove', onTouch);
      hero.removeEventListener('touchstart', onTouch);
      cancelAnimationFrame(raf);
    };
  }, [isExplore, isCoarse]);

  const commit = (p) => {
    try { navigator.vibrate?.(10); } catch (_) {}
    onPath(p);
  };

  /* Tap / click on hero while peeking left/right → lock that path */
  useEffect(() => {
    if (!isExplore) return;
    const hero = heroRef.current;
    if (!hero) return;

    let touchHandledAt = 0;
    let touchStartX = 0;
    let touchStartY = 0;

    const tryLock = (ev) => {
      if (ev.target.closest('button, a, input, select, textarea, label')) return false;
      const side = peekRef.current;
      if (side === 'left') { commit('hiring'); return true; }
      if (side === 'right') { commit('talent'); return true; }
      return false;
    };

    const onClick = (ev) => {
      if (ev.button !== 0) return;
      if (isCoarse && Date.now() - touchHandledAt < 600) return;
      tryLock(ev);
    };

    const onTouchStart = (ev) => {
      const t = ev.touches[0];
      if (!t) return;
      touchStartX = t.clientX;
      touchStartY = t.clientY;
    };

    const onTouchEnd = (ev) => {
      const t = ev.changedTouches[0];
      if (!t) return;
      if (Math.hypot(t.clientX - touchStartX, t.clientY - touchStartY) > 14) return;
      if (tryLock(ev)) touchHandledAt = Date.now();
    };

    hero.addEventListener('click', onClick);
    hero.addEventListener('touchstart', onTouchStart, { passive: true });
    hero.addEventListener('touchend', onTouchEnd, { passive: true });
    return () => {
      hero.removeEventListener('click', onClick);
      hero.removeEventListener('touchstart', onTouchStart);
      hero.removeEventListener('touchend', onTouchEnd);
    };
  }, [isExplore, onPath, isCoarse]);

  return (
    <section
      className={`hero hero-intro${path ? ' hero-locked' : ' hero-explore'}${isCoarse && isExplore ? ' hero-touch' : ''}${path === 'hiring' ? ' hero-locked-hiring' : ''}`}
      ref={heroRef}
    >
      <Particles />
      <Pings />
      <div className="floor"></div>
      <div className="ring r1"></div>
      <div className="ring r2"></div>
      <div className="ring r3"></div>
      <div className="ring r4"></div>

      {isExplore && (
        <>
          <p className="explore-hint" aria-live="polite">
            {peek === 'center' && 'Drag left or right · tap to enter'}
            {peek === 'left' && 'Tap to enter hiring'}
            {peek === 'right' && 'Tap to enter talent'}
          </p>
          <div className="explore-dock">
            <button
              type="button"
              className={`edge-tap edge-tap-left${peek === 'left' ? ' active' : ''}`}
              onClick={() => commit('hiring')}
              aria-label="Hiring manager — enter hiring flow"
            >
              <span className="eh-arrow">←</span>
              <span className="eh-num">01</span>
              <span className="eh-text">Hiring manager</span>
            </button>
            <button
              type="button"
              className={`edge-tap edge-tap-right${peek === 'right' ? ' active' : ''}`}
              onClick={() => commit('talent')}
              aria-label="Talent — enter talent flow"
            >
              <span className="eh-text">Talent</span>
              <span className="eh-num">02</span>
              <span className="eh-arrow">→</span>
            </button>
          </div>
        </>
      )}

      <div className="stage" ref={stageRef}>
        <div className="stage-intro-top">
          <div className="chamber-meta">
            <span>vairee — viewer</span>
            <div className="right">
              <span>vairee 0028</span>
              <span className="meta-hide-mobile">4 conversations · last 24h</span>
              <span>berlin · <strong>{time}</strong></span>
            </div>
          </div>

          <h1 className="headline">
            {Object.values(headlines).map((h) => (
              <span key={h} className={headline === h ? 'show' : ''}>{h}</span>
            ))}
          </h1>
        </div>

        <CaseCard />

        <p className="intro-lead">
          It is <span className="glow">{time}</span> in Berlin. She's {activity} — not applying anywhere.
          No job hunting. Her vairee is active, watching for opportunities for her.
        </p>

        {isExplore && (
          <div className="intro-ctas">
            <button type="button" className="btn-primary" onClick={() => commit('hiring')}>
              I'm hiring
            </button>
            <button type="button" className="btn-ghost" onClick={() => commit('talent')}>
              I'm talent
            </button>
          </div>
        )}
      </div>

      <HiringPanel panelRef={leftRef} locked={path === 'hiring'} onModal={onModal} />
      <TalentPanel
        panelRef={rightRef}
        locked={path === 'talent'}
        jobSeeking={jobSeeking}
        onJobSeeking={onJobSeeking}
        onPath={onPath}
        onModal={onModal}
      />

      {isExplore && !isCoarse && <div className="hero-cursor" ref={cursorRef}></div>}
    </section>
  );
}

const ARCHITECT_TYPEFORM = 'https://7gu26qrncuv.typeform.com/to/MHtXBV3x';
const PRIVACY_URL = 'https://vairee.ai/legal/privacy';

function AttributionAndNotesFields({
  heardFrom, onHeardFromChange,
  referredByName, setReferredByName,
  heardFromOther, setHeardFromOther,
  notes, setNotes,
}) {
  return (
    <>
      <label className="modal-field">
        <span className="modal-label">Where did you hear about us?</span>
        <select
          className="modal-input"
          required
          value={heardFrom}
          onChange={(e) => onHeardFromChange(e.target.value)}
        >
          <option value="">Select…</option>
          <option value="linkedin">A post on LinkedIn</option>
          <option value="x">A post on X (Twitter)</option>
          <option value="barbora_invite">I received a direct invitation link from Barbora</option>
          <option value="referral">Referred by someone</option>
          <option value="search">Found when searching (Google, etc.)</option>
          <option value="other">Other</option>
        </select>
      </label>
      {heardFrom === 'referral' && (
        <label className="modal-field">
          <span className="modal-label">Who referred you?</span>
          <input
            className="modal-input"
            type="text"
            required
            placeholder="Name or how they introduced vairee"
            value={referredByName}
            onChange={(e) => setReferredByName(e.target.value)}
          />
        </label>
      )}
      {heardFrom === 'other' && (
        <label className="modal-field">
          <span className="modal-label">Please tell us</span>
          <input
            className="modal-input"
            type="text"
            required
            placeholder="e.g. podcast, newsletter, event, direct link…"
            value={heardFromOther}
            onChange={(e) => setHeardFromOther(e.target.value)}
          />
        </label>
      )}
      <label className="modal-field">
        <span className="modal-label">
          Notes <span className="modal-label-note">(optional)</span>
        </span>
        <textarea
          className="modal-input modal-textarea"
          rows={3}
          placeholder="Ask a question, add context, or send us a message…"
          value={notes}
          onChange={(e) => setNotes(e.target.value)}
        />
      </label>
    </>
  );
}

function Modal({ open, onClose, variant, jobSeeking }) {
  const isTalent = variant === 'talent';
  const [sent, setSent] = useState(false);
  const [fullName, setFullName] = useState('');
  const [email, setEmail] = useState('');
  const [linkedin, setLinkedin] = useState('');
  const [github, setGithub] = useState('');
  const [describes, setDescribes] = useState('');
  const [urgency, setUrgency] = useState('');
  const [architect, setArchitect] = useState('');
  const [otherDescribe, setOtherDescribe] = useState('');
  const [position, setPosition] = useState('');
  const [company, setCompany] = useState('');
  const [roleHiring, setRoleHiring] = useState('');
  const [mobile, setMobile] = useState('');
  const [hireTimeline, setHireTimeline] = useState('');
  const [heardFrom, setHeardFrom] = useState('');
  const [referredByName, setReferredByName] = useState('');
  const [heardFromOther, setHeardFromOther] = useState('');
  const [notes, setNotes] = useState('');

  const onHeardFromChange = (value) => {
    setHeardFrom(value);
    if (value !== 'referral') setReferredByName('');
    if (value !== 'other') setHeardFromOther('');
  };

  const resetForm = () => {
    setSent(false);
    setFullName('');
    setEmail('');
    setLinkedin('');
    setGithub('');
    setDescribes('');
    setUrgency('');
    setArchitect('');
    setOtherDescribe('');
    setPosition('');
    setCompany('');
    setRoleHiring('');
    setMobile('');
    setHireTimeline('');
    setHeardFrom('');
    setReferredByName('');
    setHeardFromOther('');
    setNotes('');
  };

  const attributionPayload = () => ({
    heardFrom,
    referredByName: heardFrom === 'referral' ? referredByName.trim() : undefined,
    heardFromOther: heardFrom === 'other' ? heardFromOther.trim() : undefined,
    notes: notes.trim() || undefined,
  });

  useEffect(() => {
    if (!open) return;
    if (isTalent) {
      setDescribes(jobSeeking ? 'active' : 'working');
      setUrgency(jobSeeking ? 'soon' : '');
    }
  }, [open, isTalent, jobSeeking]);

  useEffect(() => {
    if (!open) {
      const t = setTimeout(resetForm, 400);
      return () => clearTimeout(t);
    }
    return undefined;
  }, [open]);

  const submit = async (e) => {
    e.preventDefault();
    if (!email) return;
    if (isTalent) {
      if (!fullName.trim() || !linkedin.trim() || !describes || !urgency) return;
      if (describes === 'other' && !otherDescribe.trim()) return;
    } else {
      if (!fullName.trim() || !position.trim() || !company.trim() || !linkedin.trim()
        || !roleHiring.trim() || !email.trim() || !hireTimeline) return;
    }
    if (!heardFrom) return;
    if (heardFrom === 'referral' && !referredByName.trim()) return;
    if (heardFrom === 'other' && !heardFromOther.trim()) return;

    const extra = attributionPayload();
    const payload = isTalent
      ? {
          email,
          fullName: fullName.trim(),
          linkedin: linkedin.trim(),
          github: github.trim() || undefined,
          describes,
          urgency,
          architect: architect || undefined,
          otherDescribe: describes === 'other' ? otherDescribe.trim() : undefined,
          role: describes === 'hiring' ? 'company' : 'talent',
          source: 'talent_early_access',
          jobSeeking: describes === 'active',
          ...extra,
        }
      : {
          email: email.trim(),
          fullName: fullName.trim(),
          position: position.trim(),
          company: company.trim(),
          linkedin: linkedin.trim(),
          roleHiring: roleHiring.trim(),
          mobile: mobile.trim() || undefined,
          hireTimeline,
          role: 'company',
          source: 'hiring_early_access',
          ...extra,
        };

    try {
      await fetch('/api/waitlist', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
      });
    } catch (_) { /* silent fail */ }
    setSent(true);
  };

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

  useEffect(() => {
    document.body.classList.toggle('modal-open', open);
    return () => document.body.classList.remove('modal-open');
  }, [open]);

  return (
    <div className={`modal-overlay${open ? ' open' : ''}`} onClick={onClose} role="dialog" aria-modal="true" aria-labelledby="modal-title">
      <div className={`modal-box${isTalent ? ' modal-box--talent' : ' modal-box--hiring'}`} onClick={(e) => e.stopPropagation()}>
        <span className="modal-close" onClick={onClose} role="button" tabIndex={0} aria-label="Close">×</span>
        {sent ? (
          <>
            <div className="modal-eyebrow">you're on the list</div>
            <h2 className="modal-title" id="modal-title">Done.</h2>
            <p className="modal-body">
              {isTalent ? (
                <>
                  No spam. One email when your vairee is ready.
                  {' '}If you're a strong early fit, we'll personally reach out within days.
                </>
              ) : (
                <>
                  No spam. One email when your vairee-job is ready.
                  {' '}Strong fits (especially companies with real open roles) will be contacted personally within days.
                </>
              )}
            </p>
          </>
        ) : isTalent ? (
          <>
            <div className="modal-eyebrow">Join the early access list</div>
            <h2 className="modal-title" id="modal-title">Build your vairee — Early Access</h2>
            <div className="modal-body modal-body-stack">
              <p>We are in process of building the vairee profile. Coming very soon.</p>
              <p>We're finalising the experience right now and onboarding people carefully.</p>
              <p>Leave your details below and we'll notify you the moment you can create your vairee.</p>
              <p>
                If you're especially interesting (actively looking right now), we may reach out earlier
                to build your vairee together — we'll do the heavy lifting and show you the result.
              </p>
            </div>
            <form className="modal-form" onSubmit={submit}>
              <label className="modal-field">
                <span className="modal-label">Full name</span>
                <input className="modal-input" type="text" autoComplete="name" required
                  value={fullName} onChange={(e) => setFullName(e.target.value)} />
              </label>
              <label className="modal-field">
                <span className="modal-label">Email</span>
                <input className="modal-input" type="email" autoComplete="email" required
                  value={email} onChange={(e) => setEmail(e.target.value)} />
              </label>
              <label className="modal-field">
                <span className="modal-label">LinkedIn URL <span className="modal-label-note">(so we can see your real experience)</span></span>
                <input className="modal-input" type="url" inputMode="url" placeholder="https://linkedin.com/in/…" required
                  value={linkedin} onChange={(e) => setLinkedin(e.target.value)} />
              </label>
              <label className="modal-field">
                <span className="modal-label">GitHub <span className="modal-label-note">(optional, but love to see)</span></span>
                <input className="modal-input" type="url" inputMode="url" placeholder="https://github.com/…"
                  value={github} onChange={(e) => setGithub(e.target.value)} />
              </label>
              <label className="modal-field">
                <span className="modal-label">What best describes you?</span>
                <select className="modal-input" required value={describes} onChange={(e) => setDescribes(e.target.value)}>
                  <option value="">Select…</option>
                  <option value="working">Working — quietly open to the right opportunity</option>
                  <option value="active">Actively looking for a new role (want help now)</option>
                  <option value="hiring">Hiring / building a team</option>
                  <option value="other">Other (describe)</option>
                </select>
              </label>
              {describes === 'other' && (
                <label className="modal-field">
                  <span className="modal-label">Please describe</span>
                  <input className="modal-input" type="text" required
                    value={otherDescribe} onChange={(e) => setOtherDescribe(e.target.value)} />
                </label>
              )}
              <label className="modal-field">
                <span className="modal-label">How urgent?</span>
                <select className="modal-input" required value={urgency} onChange={(e) => setUrgency(e.target.value)}>
                  <option value="">Select…</option>
                  <option value="exploring">Just exploring (no rush)</option>
                  <option value="months">Actively searching in the next 3–6 months</option>
                  <option value="soon">Need something soon (next 4–8 weeks)</option>
                </select>
              </label>
              <fieldset className="modal-field modal-fieldset">
                <legend className="modal-label">One optional question</legend>
                <p className="modal-field-hint">
                  Are you a software architect / tech lead with 15+ years of commercial experience?
                  {' '}(We're especially looking for people like you — a research project on better hiring.{' '}
                  <a href={ARCHITECT_TYPEFORM} target="_blank" rel="noopener noreferrer">Read more</a>)
                </p>
                <select className="modal-input" value={architect} onChange={(e) => setArchitect(e.target.value)}>
                  <option value="">Prefer not to say</option>
                  <option value="yes">Yes</option>
                  <option value="no">No</option>
                </select>
              </fieldset>
              <AttributionAndNotesFields
                heardFrom={heardFrom}
                onHeardFromChange={onHeardFromChange}
                referredByName={referredByName}
                setReferredByName={setReferredByName}
                heardFromOther={heardFromOther}
                setHeardFromOther={setHeardFromOther}
                notes={notes}
                setNotes={setNotes}
              />
              <p className="modal-legal">
                By submitting this form you consent to Recberry s.r.o. contacting you about vairee and
                processing your details as described in the{' '}
                <a href={PRIVACY_URL} target="_blank" rel="noopener noreferrer">
                  Privacy Notice for this website
                </a>
                . Submitting is a waitlist request only. It does not create a vairee-card account.
              </p>
              <button type="submit" className="panel-cta panel-cta-ghost modal-submit">
                Build my vairee <span className="arrow">→</span>
              </button>
            </form>
            <p className="modal-note">
              No spam. One email when your vairee is ready.
              {' '}If you're a strong early fit, we'll personally reach out within days.
            </p>
          </>
        ) : (
          <>
            <div className="modal-eyebrow">Join the early access list for hiring</div>
            <h2 className="modal-title" id="modal-title">For Hiring Managers — Early Access</h2>
            <div className="modal-body modal-body-stack">
              <p>Your virtual hiring vairee is almost ready.</p>
              <p>We're onboarding companies carefully.</p>
              <p>
                If you have open roles right now and want to fill them with high-quality, pre-vetted
                passive talent, leave your details below. We may reach out immediately to build your
                first vairee-job together.
              </p>
            </div>
            <form className="modal-form" onSubmit={submit}>
              <label className="modal-field">
                <span className="modal-label">Full name</span>
                <input className="modal-input" type="text" autoComplete="name" required
                  value={fullName} onChange={(e) => setFullName(e.target.value)} />
              </label>
              <label className="modal-field">
                <span className="modal-label">Role / Position</span>
                <input className="modal-input" type="text" required
                  value={position} onChange={(e) => setPosition(e.target.value)} />
              </label>
              <label className="modal-field">
                <span className="modal-label">Company</span>
                <input className="modal-input" type="text" autoComplete="organization" required
                  value={company} onChange={(e) => setCompany(e.target.value)} />
              </label>
              <label className="modal-field">
                <span className="modal-label">LinkedIn URL</span>
                <input className="modal-input" type="url" inputMode="url" placeholder="https://linkedin.com/in/…" required
                  value={linkedin} onChange={(e) => setLinkedin(e.target.value)} />
              </label>
              <label className="modal-field">
                <span className="modal-label">
                  Role you're hiring for{' '}
                  <span className="modal-label-note">(link to job description or short summary)</span>
                </span>
                <textarea className="modal-input modal-textarea" rows={3} required
                  value={roleHiring} onChange={(e) => setRoleHiring(e.target.value)} />
              </label>
              <label className="modal-field">
                <span className="modal-label">Email</span>
                <input className="modal-input" type="email" autoComplete="email" required
                  value={email} onChange={(e) => setEmail(e.target.value)} />
              </label>
              <label className="modal-field">
                <span className="modal-label">Mobile <span className="modal-label-note">(optional)</span></span>
                <input className="modal-input" type="tel" autoComplete="tel"
                  value={mobile} onChange={(e) => setMobile(e.target.value)} />
              </label>
              <label className="modal-field">
                <span className="modal-label">How soon do you need to fill the role?</span>
                <select className="modal-input" required value={hireTimeline} onChange={(e) => setHireTimeline(e.target.value)}>
                  <option value="">Select…</option>
                  <option value="weeks">Within 4–8 weeks (priority)</option>
                  <option value="months">Within 3 months</option>
                  <option value="exploring">Just exploring for now</option>
                </select>
              </label>
              <AttributionAndNotesFields
                heardFrom={heardFrom}
                onHeardFromChange={onHeardFromChange}
                referredByName={referredByName}
                setReferredByName={setReferredByName}
                heardFromOther={heardFromOther}
                setHeardFromOther={setHeardFromOther}
                notes={notes}
                setNotes={setNotes}
              />
              <p className="modal-legal">
                By submitting this form you consent to Recberry s.r.o. contacting you about vairee and
                processing your details as described in the{' '}
                <a href={PRIVACY_URL} target="_blank" rel="noopener noreferrer">
                  Privacy Notice for this website
                </a>
                . Submitting is a waitlist request only. It does not create a vairee-card account.
              </p>
              <button type="submit" className="panel-cta modal-submit">
                Start here <span className="arrow">→</span>
              </button>
            </form>
            <p className="modal-note">
              No spam. One email when your vairee-job is ready.
              {' '}Strong fits (especially companies with real open roles) will be contacted personally within days.
            </p>
          </>
        )}
      </div>
    </div>
  );
}

function LegalFooter() {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch('/legal-footer-content.json')
      .then((r) => r.json())
      .then(setData)
      .catch(() => {});
  }, []);

  if (!data) return null;

  return (
    <footer className="legal-footer">
      <p className="legal-footer-project">
        {data.projectLine}{' '}
        <a href={data.companyUrl} target="_blank" rel="noopener noreferrer">
          {data.companyName}
        </a>
      </p>
      <nav className="legal-footer-nav" aria-label="Legal">
        {(data.links || []).map((link, i) => (
          <span key={link.href}>
            {i > 0 ? ' · ' : null}
            {link.external ? (
              <a href={link.href} target="_blank" rel="noopener noreferrer">
                {link.label}
              </a>
            ) : (
              <a href={link.href}>{link.label}</a>
            )}
          </span>
        ))}
      </nav>
      <p className="legal-footer-registration">{data.registration}</p>
    </footer>
  );
}

function CookieConsent() {
  useEffect(() => {
    const s = document.createElement('script');
    s.src = '/scripts/cookie-consent.js';
    s.async = true;
    document.body.appendChild(s);
    return () => {
      s.remove();
    };
  }, []);
  return null;
}

function SiteFooter() {
  return <LegalFooter />;
}

function App() {
  const [path, setPathState] = useState(() => pathFromUrl());
  const [modalOpen, setModalOpen] = useState(false);
  const [modalVariant, setModalVariant] = useState('talent');
  const [jobSeeking, setJobSeeking] = useState(false);

  const openTalentModal = () => {
    goToCardApp();
  };
  const openHiringModal = () => {
    setModalVariant('hiring');
    setModalOpen(true);
  };

  const setPath = (next) => {
    const value = VALID_PATHS.has(next) ? next : null;
    setPathState(value);
    const target = urlForPath(value);
    const current = window.location.pathname.replace(/\/+$/, '') || '/';
    const normalized = target.replace(/\/+$/, '') || '/';
    if (current !== normalized) {
      window.history.pushState({ path: value }, '', target);
    }
  };

  useEffect(() => {
    const initial = pathFromUrl();
    if (initial) {
      window.history.replaceState({ path: initial }, '', urlForPath(initial));
    }
  }, []);

  useEffect(() => {
    const onPop = () => setPathState(pathFromUrl());
    window.addEventListener('popstate', onPop);
    return () => window.removeEventListener('popstate', onPop);
  }, []);

  useEffect(() => {
    if (path !== 'talent') setJobSeeking(false);
  }, [path]);

  useEffect(() => {
    const on = Boolean(path);
    document.documentElement.classList.toggle('has-path-story', on);
    document.body.classList.toggle('path-hiring', path === 'hiring');
    document.body.classList.toggle('path-talent', path === 'talent');
    document.body.classList.toggle('talent-seeking', path === 'talent' && jobSeeking);
    document.title = pageTitle(path);
    if (on) window.scrollTo({ top: 0, behavior: 'auto' });
    return () => {
      document.documentElement.classList.remove('has-path-story');
      document.body.classList.remove('path-hiring', 'path-talent', 'talent-seeking');
    };
  }, [path, jobSeeking]);

  return (
    <>
      <Nav path={path} onPath={setPath} onModal={openTalentModal} />
      <main className={path ? 'main-has-path' : ''}>
        {path ? (
          <div className="path-flow">
            <div className="path-screen">
              <Hero
                path={path}
                onPath={setPath}
                onModal={path === 'hiring' ? openHiringModal : openTalentModal}
                jobSeeking={jobSeeking}
                onJobSeeking={setJobSeeking}
              />
            </div>
            <PathStory
              path={path}
              onModal={openHiringModal}
              onModalTalent={openTalentModal}
              jobSeeking={jobSeeking}
            />
          </div>
        ) : (
          <Hero
            path={path}
            onPath={setPath}
            onModal={openTalentModal}
            jobSeeking={jobSeeking}
            onJobSeeking={setJobSeeking}
          />
        )}
      </main>
      <SiteFooter />
      <CookieConsent />
      <Modal
        open={modalOpen}
        onClose={() => setModalOpen(false)}
        variant={modalVariant}
        jobSeeking={jobSeeking}
      />
    </>
  );
}

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