/* STATUS: DRAFT hero — the scroll-world engine mounted as the cain-site home hero.
   Replaces CAIN_HeroFlight (kept in hero-flight.jsx as the fallback / archive).

   Content is a straight port of landing/scroll-world/index.html, which is the page
   whose copy was approved. Skin lives in public/scroll-world-skin.css so its font
   url()s keep resolving two levels up, exactly as they did from landing/scroll-world/.

   Media: public/scroll-world/ is a LOCAL symlink → media-work/landing/scroll-world-lean/
   (CRF 26 re-encodes of the cut legs, same -g 8 scrub GOP). Full-rate masters stay in
   media-work/landing/scroll-world/. Real product ships must copy lean files into the
   product tree — REPO-MAP.md forbids deploying against a symlink out of media-work.

   Motion truth: tools/remotion-studio/WARGAME-flythrough.md. Lanes: REPO-MAP.md. */

const V = 'public/scroll-world/';

/* Scroll feel lives here and nowhere else. The engine reads every one of these per
   frame, so tuning is a reload, never a re-render of the film.
     scroll   — viewport-heights of wheel spent inside a landing
     linger   — 0..1, how hard the camera settles mid-landing while the copy peaks
     connectorScroll — per-leg wheel budget; the frame counts differ ~3.4x, so one
                       global width would make the long Baker->Tech leg fly. */
const SW_CONFIG = {
  brand: null,          // cain-site draws its own NavBar
  cta: null,            // ...and its own Join
  nav: false,           // ...and its own section nav. Route dots on the right stay.
  hint: 'scroll to fly the Hill',
  atmosphere: false,    // the footage is real campus video; particles fight it
  diveScroll: 2.2,
  connScroll: 2.7,

  // Real flight motion from flight_test.py --flyer-sheet: bank L/R, climb/dive,
  // gold wings + blue eyes, head up. cycles:1 = one full path pass per connector.
  // intro: large reading still on frame 0, then lift into the flight sheet on scroll.
  flyer: {
    src: V + 'flyer-flight.webp', cols: 6, rows: 6, frames: 36, cycles: 1,
    intro: {
      read: 'public/scroll/mascot-read.png',
      readEnd: 0.10,
      // 0.24 left the read still and the flight sprite both semi-transparent for ~14%
      // of a 3.4vh-long segment — two translucent robots on screen at once. A short
      // window keeps the lift-off arc without ever showing a ghost pair.
      liftEnd: 0.13,
    },
  },
  // Optical-flow pan curves (analyze_camera_motion.py v2). face_dir aims the nose
  // into travel; push/pull legs do not hard-flip him backward into campus.
  cameraMotion: V + 'flyer-camera-pack.json',

  sections: [
    {
      id: 'hill', label: 'the Hill',
      still: V + 's0-leadin.jpg', clip: V + 's0-leadin.mp4',
      accent: '#B31B1B', scroll: 3.4, linger: 0.35,
      bakedMascot: false,
      eyebrow: 'Cornell AI Network',
      title: 'The Heartbeat of the Cornell AI Community',
      body: 'Join fellow AI professionals, enthusiasts for events, networking and growth opportunities.',
    },
    {
      id: 'sage', label: 'Sage',
      still: V + 's1-sage.jpg', clip: V + 's1-sage.mp4',
      accent: '#B31B1B', scroll: 2.2, linger: 0.85,
      bakedMascot: true,
      eyebrow: 'What we do',
      title: "Connect Cornell's AI community",
      body: 'Through events, introductions, and knowledge. Plus a monthly newsletter with the latest AI-related Cornell events and jobs.',
      tags: ['Collaborations and partnerships', 'Serve diverse AI communities', 'Initiatives and programs'],
      cta: { primary: { label: 'Read the newsletter', href: '#' } },
    },
    {
      id: 'ezra', label: 'Ezra',
      still: V + 's2-ezra.jpg', clip: V + 's2-ezra.mp4',
      accent: '#B31B1B', scroll: 2.2, linger: 0.85,
      bakedMascot: true,
      eyebrow: 'Introducing — a Cornell AI Network program',
      title: 'Bridging the AI gap',
      body: 'Students know how to use AI, but lack the real-world experience to get hired. Faculty are sitting on hours of work AI could accelerate. We match them.',
      tags: ['Document workflows', 'Literature synthesis', 'Data cleanup'],
      cta: { primary:   { label: "I'm a student", href: '#' },
             secondary: { label: "I'm a lab or department", href: '#' } },
    },
    {
      id: 'baker', label: 'Baker',
      still: V + 's3-baker.jpg', clip: V + 's3-baker.mp4',
      accent: '#B31B1B', scroll: 2.2, linger: 0.85,
      bakedMascot: true,
      eyebrow: "But that's not all",
      title: 'Introductions that actually matter',
      body: "CAIN connects Cornell's AI community through events, introductions, and knowledge worth your time.",
      tags: ['Founders and builders — co-founders, early hires, investors',
             'Investors and allocators — vetted deal flow and technical diligence',
             'Talent leaders — top Cornell AI candidates before they hit the market'],
    },
    {
      id: 'tech', label: 'Cornell Tech',
      still: V + 's4-tech.jpg', clip: V + 's4-tech.mp4',
      accent: '#B31B1B', scroll: 2.4, linger: 0.85,
      bakedMascot: true,
      eyebrow: 'From the Hill to the city',
      title: 'Come for the AI, stay for the network.',
      body: 'The professional community where Cornell alumni and students connect around AI — to learn, build, hire, invest, and grow.',
      tags: [],
      cta: { primary:   { label: 'info@cornellainetwork.com', href: 'mailto:info@cornellainetwork.com' },
             secondary: { label: 'LinkedIn', href: 'https://www.linkedin.com/company/cornellainetwork' } },
    },
  ],

  // length === sections.length - 1. The lead-in ends where the Sage landing begins,
  // so the first connector is null.
  connectors: [
    null,
    V + 'c2-sage-to-ezra.mp4',
    V + 'c3-ezra-to-baker.mp4',
    V + 'c4-baker-to-tech.mp4',
  ],
  connectorScroll: [0, 2.7, 3.3, 4.3],
};

function HeroScrollWorld() {
  const ref = React.useRef(null);

  React.useEffect(() => {
    const host = ref.current;
    if (!host || typeof window.mountScrollWorld !== 'function') return;

    // cain-site scrolls an inner 100vh div, not the window. The vendored engine copy
    // reads config.scroller when given one (diff vs landing/scroll-world/ is 3 lines).
    let scroller = null;
    for (let n = host.parentElement; n; n = n.parentElement) {
      if (getComputedStyle(n).overflowY === 'auto') { scroller = n; break; }
    }

    host.__swScroller = scroller;   // tuning handle: $0.__swScroller in devtools
    window.mountScrollWorld(host, Object.assign({ scroller }, SW_CONFIG));

    // Kill the engine's fixed chrome once the hero's own track leaves the viewport.
    const io = new IntersectionObserver(
      ([e]) => host.classList.toggle('is-offscreen', !e.isIntersecting),
      { root: scroller || null }
    );
    io.observe(host);
    return () => io.disconnect();
  }, []);

  return <div ref={ref} />;
}

window.CAIN_HeroScrollWorld = HeroScrollWorld;
