/* Vurctne — commercial-film landing & portfolio.
   A pitch to brands who want ads that don't look AI-made.
   Built from the Vurctne DS components + tokens. */
const { Nav, Hero, FilmCard, Card, Button, Tag, Heading, Text, Logo, Footer } =
  window.VurctneDesignSystem_36565f;

/* Cinematic placeholder thumbnail — dark frame, faint off-center light, play glyph,
   a hairline of the pillar color. Swap `thumbnail` for a real still in production. */
function thumb({ base = '#0c0c10', glow = '#1c1c28', accent = '#6e56ff', code = '' }) {
  const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="640" height="360" viewBox="0 0 640 360">
    <defs>
      <radialGradient id="g" cx="36%" cy="30%" r="75%">
        <stop offset="0%" stop-color="${glow}"/>
        <stop offset="100%" stop-color="${base}"/>
      </radialGradient>
    </defs>
    <rect width="640" height="360" fill="url(#g)"/>
    <rect x="0" y="356" width="640" height="4" fill="${accent}" opacity="0.85"/>
    <g opacity="0.9">
      <circle cx="320" cy="172" r="34" fill="rgba(255,255,255,0.10)"/>
      <path d="M311 156 l24 16 l-24 16 z" fill="rgba(255,255,255,0.85)"/>
    </g>
    <text x="606" y="40" text-anchor="end" font-family="Inter, sans-serif" font-size="18"
      fill="rgba(255,255,255,0.45)" letter-spacing="2">${code}</text>
  </svg>`;
  return 'data:image/svg+xml;utf8,' + encodeURIComponent(svg);
}

const FILMS = [
  { title: 'Tuanzi Is Waiting', pillar: 'cinematic', tagLabel: 'Brand Films', meta: 'Smart-lock brand · 90s spot', dur: 90,
    synopsis: 'A branded film for a smart-lock brand. A quiet apartment, a dog named Tuanzi, and a door that knows when home is coming back — product as the quiet hero of a real story.',
    thumbnail: thumb({ base: '#0d0c14', glow: '#241f3a', accent: '#4f46e5', code: 'TZ·01' }) },
  { title: 'Is That Real?', pillar: 'real', tagLabel: 'Product', meta: 'Product reveal · 12s', dur: 12,
    synopsis: 'Twelve seconds you have to watch twice. A photoreal product reveal that blurs the line between footage and synthesis — the "is that real?" reaction, working for the brand.',
    thumbnail: thumb({ base: '#08121a', glow: '#103340', accent: '#22d3ee', code: 'PR·02' }) },
  { title: "Don't Open the Door", pillar: 'cinematic', tagLabel: 'Brand Films', meta: 'Narrative spot · 2 min', dur: 124,
    synopsis: 'A two-minute narrative spot. Tension built in the edit — a hallway, a sound, a decision. Prestige-drama mood in service of a single, sharp brand message.',
    thumbnail: thumb({ base: '#0c0a10', glow: '#221a30', accent: '#4f46e5', code: 'BF·03' }) },
  { title: 'When the AI Tried Comedy', pillar: 'funny', tagLabel: 'Social', meta: 'Social short · 30s', dur: 30,
    synopsis: 'A thirty-second social short built to be shared. The AI was asked to be funny — and this time it lands. Punchy, on-brand, made for the feed.',
    thumbnail: thumb({ base: '#14100a', glow: '#3a2c12', accent: '#ffb020', code: 'SO·04' }) },
  { title: 'Rain on Neon', pillar: 'real', tagLabel: 'Product', meta: 'Product hero · 15s', dur: 15,
    synopsis: 'Fifteen seconds of rain on neon — a hero shot for a product that never sat on a wet street. A soundstage look, without the soundstage.',
    thumbnail: thumb({ base: '#08121a', glow: '#123842', accent: '#22d3ee', code: 'PR·05' }) },
  { title: "The Pitch That Wasn't", pillar: 'funny', tagLabel: 'Social', meta: 'Social short · 45s', dur: 45,
    synopsis: 'A boardroom, a confident founder, and a deck that slowly falls apart. A forty-five-second social short with a wink — proof the brand doesn\u2019t take itself too seriously.',
    thumbnail: thumb({ base: '#14100a', glow: '#3a3014', accent: '#ffb020', code: 'SO·06' }) },
];

/* Hero background clips — fallback if content.json is unavailable. */
const DEFAULT_HERO_CLIPS = ['media/hero.mp4', 'media/hero-2.mp4'];

/* Turn a content.json film record into the runtime shape the UI expects:
   a ready `thumbnail` (uploaded poster if given, else the generated frame) and a
   normalized `video` descriptor ({ kind: 'none' | 'youtube' | 'file', ... }). */
function normalizeFilm(f) {
  return {
    ...f,
    video: f.video && f.video.kind ? f.video : { kind: 'none' },
    thumbnail: f.poster ? f.poster : thumb(f.thumb || {}),
  };
}

/* Extract an 11-char YouTube id from a full URL or a bare id. */
function youtubeId(s) {
  if (!s) return '';
  const str = String(s).trim();
  const m = str.match(/(?:youtu\.be\/|v=|\/embed\/|\/shorts\/)([A-Za-z0-9_-]{11})/);
  return m ? m[1] : (/^[A-Za-z0-9_-]{11}$/.test(str) ? str : '');
}

const FILTERS = [
  { key: 'all', label: 'All work' },
  { key: 'cinematic', label: 'Brand Films' },
  { key: 'real', label: 'Product' },
  { key: 'funny', label: 'Social' },
];

const OFFERINGS = [
  { num: '01', key: 'cinematic', color: 'var(--vk-cinematic)', name: 'Brand Films', deliverable: '15–90s · narrative spots',
    line: 'Cinematic brand stories with mood, performance, and a message that lands — the kind of ad people actually finish.' },
  { num: '02', key: 'real', color: 'var(--vk-real)', name: 'Product', deliverable: '6–20s · product hero',
    line: 'Ultra-real product shots that look shot on a soundstage. The “is that real?” reaction, pointed at your product.' },
  { num: '03', key: 'funny', color: 'var(--vk-funny)', name: 'Social', deliverable: '15–60s · short-form',
    line: 'Scroll-stopping short-form for feeds — punchy, sometimes funny, always on-brand.' },
];

const PROJECT_TYPES = ['Brand film', 'Product spot', 'Social short', 'Not sure yet'];

const EDGE = [
  { k: 'Cinema looks, startup budget', d: 'Broadcast-grade films for under 5% of what a conventional TV production costs. Big-brand polish on a budget that actually fits yours.' },
  { k: 'From brief to launch in days', d: 'Go from first conversation to finished film in days, not the months an agency and a shoot would take. Catch the moment while it’s still hot.' },
  { k: 'One director, no middlemen', d: 'You talk straight to the person making your film. No account managers, no creative-to-production telephone, nothing lost in the hand-offs.' },
  { k: 'Any market, 70+ languages', d: 'Launch the same film in 70+ languages with native-quality voice. One brief, every market you sell in — not a clumsy translation after the fact.' },
  { k: 'Nothing is off-limits', d: 'Any location, any era, any impossible shot — no sets, permits, travel, or talent logistics. If you can picture it, it can be filmed.' },
  { k: 'Product placement in short dramas', d: 'Beyond standalone ads: weave your product into bingeable short-drama episodes that audiences actually choose to watch.' },
];

const FAQ = [
  { q: 'What kind of films does Vurctne make?', a: 'Three kinds of AI-directed ad films — brand films (15–90s narrative spots), product films (6–20s ultra-real hero shots), and social shorts (15–60s) — plus product placement woven into bingeable short-drama episodes.' },
  { q: 'How much does an AI ad film cost?', a: 'Broadcast-grade films for under 5% of what a conventional TV production costs. The exact quote depends on length, scope, and number of deliverables — send a brief and you’ll get a figure back.' },
  { q: 'How fast can you deliver a film?', a: 'From the first conversation to a finished film in days, not the months a traditional agency and a shoot would take.' },
  { q: 'How do I get started?', a: 'Hit “Start a project” and send a short brief — your brand, what you need, and a rough timeline. You’ll hear back within a day with ideas and a rough timeline.' },
  { q: 'Who will I be working with?', a: 'One director, end to end. You talk straight to the person making your film — no account managers and no middlemen.' },
  { q: 'Can the films be made in other languages?', a: 'Yes. The same film can launch in 70+ languages with native-quality voice — one brief, every market you sell in.' },
  { q: 'What AI tools do you use?', a: 'A director-led pipeline of current generative video, image, and voice models, chosen per project. The craft is in the direction and the edit, not any single tool.' },
  { q: 'Who owns the finished film and the rights?', a: 'You do. You receive the finished film with the usage rights your campaign needs, agreed in writing before the work starts.' },
  { q: 'Is AI-generated ad content brand-safe?', a: 'Every film is directed and reviewed for your brand — tone, claims, and any likeness are agreed up front, so nothing ships that you haven’t signed off.' },
  { q: 'Can I see examples relevant to my brand?', a: 'The reel on this page shows the style and range. For work in your specific category, get in touch and ask.' },
];

function fmt(s) {
  const m = Math.floor(s / 60), ss = Math.floor(s % 60);
  return m + ':' + String(ss).padStart(2, '0');
}

const pad = (n) => String(n).padStart(2, '0');
const PILLAR_COLOR = { all: '#6e56ff', cinematic: '#4f46e5', real: '#22d3ee', funny: '#ffb020' };
const PILLAR_INK = { all: '#ffffff', cinematic: '#ffffff', real: '#08323a', funny: '#3a2600' };

/* Reveal-on-scroll wrapper */
function Reveal({ children, delay = 0, as = 'div', className = '', style = {} }) {
  const ref = React.useRef(null);
  const [shown, setShown] = React.useState(false);
  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    // Immediate check: anything already in/near the viewport on mount reveals
    // regardless of IntersectionObserver timing (async images/fonts can race it).
    const r = el.getBoundingClientRect();
    if (r.top < window.innerHeight && r.bottom > 0) { setShown(true); return; }
    const io = new IntersectionObserver(
      ([e]) => { if (e.isIntersecting) { setShown(true); io.disconnect(); } },
      { threshold: 0.12 }
    );
    io.observe(el);
    return () => io.disconnect();
  }, []);
  const Tag = as;
  return (
    <Tag
      ref={ref}
      className={className}
      style={{
        ...style,
        opacity: shown ? 1 : 0,
        transform: shown ? 'none' : 'translateY(26px)',
        transition: `opacity 760ms var(--vk-ease) ${delay}ms, transform 760ms var(--vk-ease) ${delay}ms`,
      }}
    >
      {children}
    </Tag>
  );
}

/* ---- Flippable "AI" token: mirrors top-to-bottom to reveal "VI", the inverse of the logo ---- */
function FlipAI() {
  const [flipped, setFlipped] = React.useState(false);
  return (
    <span
      className={'flip-ai' + (flipped ? ' is-flipped' : '')}
      onClick={(e) => { e.preventDefault(); e.stopPropagation(); setFlipped((f) => !f); }}
      role="text"
      aria-label="AI"
      title="VI ⇄ AI"
    >
      <span className="flip-ai__inner">
        <span className="flip-ai__front">AI</span>
        <span className="flip-ai__back" aria-hidden="true">VI</span>
      </span>
    </span>
  );
}

/* ---- Film card with hover-scrub: live timecode + scanline + progress, like scrubbing a clip ---- */
function ScrubCard({ film, onOpen }) {
  const [hover, setHover] = React.useState(false);
  const [tc, setTc] = React.useState('00:00:00');
  React.useEffect(() => {
    if (!hover) { setTc('00:00:00'); return; }
    let f = 0;
    const id = setInterval(() => {
      f += 1;
      const ff = f % 24, s = Math.floor(f / 24);
      setTc(`${pad(Math.floor(s / 60) % 60)}:${pad(s % 60)}:${pad(ff)}`);
    }, 1000 / 24);
    return () => clearInterval(id);
  }, [hover]);
  return (
    <div className="site-filmtrigger" role="button" tabIndex={0}
      onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
      onClick={() => onOpen(film)}
      onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onOpen(film); } }}>
      <FilmCard title={film.title} thumbnail={film.thumbnail} pillar={film.pillar} tagLabel={film.tagLabel} meta={film.meta} />
      <div className="scrub" aria-hidden="true">
        <span className="scrub__scan"></span>
        <span className="scrub__tc">{tc}</span>
        <span className="scrub__bar"><i></i></span>
      </div>
    </div>
  );
}

/* ---- Drifting wall of work behind the hero ---- */
function HeroReel({ films = FILMS }) {
  const rowA = [...films, ...films];
  const rowB = [...films.slice().reverse(), ...films.slice().reverse()];
  return (
    <div className="hero-reel" aria-hidden="true">
      <div className="hero-reel__tilt">
        <div className="hero-reel__row hero-reel__row--a">
          {rowA.map((f, i) => <img key={'a' + i} src={f.thumbnail} alt="" />)}
        </div>
        <div className="hero-reel__row hero-reel__row--b">
          {rowB.map((f, i) => <img key={'b' + i} src={f.thumbnail} alt="" />)}
        </div>
        <div className="hero-reel__row hero-reel__row--a">
          {rowA.map((f, i) => <img key={'c' + i} src={f.thumbnail} alt="" />)}
        </div>
      </div>
    </div>
  );
}

/* ---- Brand interstitial: "Vurctne Imagination" → VI → AI ---- */
function BrandMorph() {
  const [phase, setPhase] = React.useState(0); // 0 full · 1 VI · 2 AI · 3 out
  React.useEffect(() => {
    const t = [
      setTimeout(() => setPhase(1), 2000),
      setTimeout(() => setPhase(2), 3900),
      setTimeout(() => setPhase(3), 5600),
    ];
    return () => t.forEach(clearTimeout);
  }, []);
  const cap = phase >= 2 ? 'Artificial Imagination' : phase === 1 ? 'Vurctne · Imagination' : 'Where intelligence meets imagination';
  return (
    <div className={'brand-morph brand-morph--p' + phase} aria-hidden="true">
      <div className="brand-morph__glow"></div>
      <div className="brand-morph__stage">
        <div className="bm-full">
          <span className="bm-word"><b>V</b>urctne</span>
          <span className="bm-word"><b>I</b>magination</span>
        </div>
        <div className="bm-flip">
          <div className="bm-flip__inner">
            <span className="bm-flip__front">VI</span>
            <span className="bm-flip__back">AI</span>
          </div>
        </div>
      </div>
      <div className="brand-morph__cap">{cap}</div>
    </div>
  );
}

/* ---- Hero background: two clips cross-fading, with the brand morph between them ---- */
function HeroVideo({ clips }) {
  const list = (clips && clips.length) ? clips : DEFAULT_HERO_CLIPS;
  const [active, setActive] = React.useState(0);
  const [brand, setBrand] = React.useState(false);
  const [playing, setPlaying] = React.useState(false);
  const refs = React.useRef([]);
  const idx = active % list.length;
  React.useEffect(() => {
    if (brand) return;
    setPlaying(false); // show the reel placeholder until the new clip actually paints
    const v = refs.current[idx];
    if (v) { try { v.currentTime = 0; } catch (e) {} const p = v.play(); if (p && p.catch) p.catch(() => {}); }
  }, [idx, brand]);
  // when the brand morph finishes (~6.3s), advance to the next clip
  React.useEffect(() => {
    if (!brand) return;
    const id = setTimeout(() => { setActive((a) => (a + 1) % list.length); setBrand(false); }, 6300);
    return () => clearTimeout(id);
  }, [brand]);
  return (
    <div className="hero-video-wrap" aria-hidden="true">
      {list.map((src, i) => (
        <video key={src + i} ref={(el) => { refs.current[i] = el; }}
          className={'hero-video' + (idx === i && !brand && playing ? ' is-active' : '')}
          autoPlay={i === 0} muted playsInline preload={i === 0 ? 'auto' : 'metadata'}
          onPlaying={() => { if (idx === i) setPlaying(true); }}
          onEnded={() => setBrand(true)}>
          <source src={src} type="video/mp4" />
        </video>
      ))}
      {brand && <BrandMorph />}
    </div>
  );
}

/* ---- Film player modal ---- */
function Player({ film, onClose, onStart }) {
  const [playing, setPlaying] = React.useState(false);
  const [t, setT] = React.useState(0);

  React.useEffect(() => {
    function onKey(e) { if (e.key === 'Escape') onClose(); }
    window.addEventListener('keydown', onKey);
    document.body.style.overflow = 'hidden';
    return () => { window.removeEventListener('keydown', onKey); document.body.style.overflow = ''; };
  }, [onClose]);

  React.useEffect(() => {
    if (!playing) return;
    const step = 0.1;
    const id = setInterval(() => {
      setT((prev) => {
        const next = prev + step;
        if (next >= film.dur) { setPlaying(false); return film.dur; }
        return next;
      });
    }, 100);
    return () => clearInterval(id);
  }, [playing, film.dur]);

  const pct = Math.min(100, (t / film.dur) * 100);
  const ended = t >= film.dur;

  // Real video source, if one was set in the admin portal.
  const v = film.video || { kind: 'none' };
  const yt = v.kind === 'youtube' ? youtubeId(v.url || v.id) : '';
  const hasFile = v.kind === 'file' && v.src;

  return (
    <div className="vk-modal" onClick={onClose}>
      <div className="vk-player" onClick={(e) => e.stopPropagation()}>
        <button className="vk-modal__x" onClick={onClose} aria-label="Close">×</button>
        {yt ? (
          <div className="vk-player__stage vk-player__stage--embed">
            <iframe
              src={'https://www.youtube-nocookie.com/embed/' + yt + '?autoplay=1&rel=0&modestbranding=1&playsinline=1'}
              title={film.title} loading="lazy" allowFullScreen
              allow="autoplay; encrypted-media; picture-in-picture; fullscreen"></iframe>
          </div>
        ) : hasFile ? (
          <div className="vk-player__stage vk-player__stage--embed">
            <video src={v.src} poster={film.thumbnail} controls autoPlay playsInline></video>
          </div>
        ) : (
          <div className="vk-player__stage" onClick={() => setPlaying((p) => !p)}>
            <img src={film.thumbnail} alt={film.title} />
            <div className={'vk-player__scrim' + (playing ? ' is-playing' : '')}>
              <button
                className="vk-player__play"
                aria-label={playing ? 'Pause' : 'Play'}
                onClick={(e) => { e.stopPropagation(); if (ended) { setT(0); setPlaying(true); } else setPlaying((p) => !p); }}
              >
                {playing ? (
                  <svg viewBox="0 0 24 24" width="30" height="30" fill="currentColor"><rect x="6" y="5" width="4.4" height="14" rx="1.2"/><rect x="13.6" y="5" width="4.4" height="14" rx="1.2"/></svg>
                ) : (
                  <svg viewBox="0 0 24 24" width="30" height="30" fill="currentColor"><path d="M8 5.5 L18.5 12 L8 18.5 Z"/></svg>
                )}
              </button>
            </div>
            <div className="vk-player__bar"><div className="vk-player__fill" style={{ width: pct + '%' }}></div></div>
            <div className="vk-player__time">{fmt(t)} / {fmt(film.dur)}</div>
          </div>
        )}
        <div className="vk-player__info">
          <div className="vk-player__head">
            <Tag pillar={film.pillar}>{film.tagLabel}</Tag>
            <span className="vk-player__meta">{film.meta}</span>
          </div>
          <h3 className="vk-player__title">{film.title}</h3>
          <Text muted>{film.synopsis}</Text>
          <div className="vk-player__cta">
            <Button variant="primary" onClick={() => { onClose(); onStart(); }}>Brief me on something like this</Button>
          </div>
        </div>
      </div>
    </div>
  );
}

/* ---- Start-a-project brief modal ---- */
function Inquiry({ onClose }) {
  const [brand, setBrand] = React.useState('');
  const [email, setEmail] = React.useState('');
  const [type, setType] = React.useState(PROJECT_TYPES[0]);
  const [msg, setMsg] = React.useState('');
  const [done, setDone] = React.useState(false);
  const [sending, setSending] = React.useState(false);
  const [err, setErr] = React.useState('');
  const ok = brand.trim().length > 1 && /.+@.+\..+/.test(email);

  async function submit(e) {
    e.preventDefault();
    if (!ok || sending) return;
    setSending(true); setErr('');
    try {
      const res = await fetch('https://formsubmit.co/ajax/contact@vurctne.com', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
        body: JSON.stringify({
          Brand: brand.trim(),
          Email: email.trim(),
          'Project type': type,
          Message: msg.trim() || '(none)',
          _replyto: email.trim(),
          _subject: 'New brief — ' + brand.trim() + ' (' + type + ')',
          _template: 'table',
          _captcha: 'false',
        }),
      });
      if (!res.ok) throw new Error('status ' + res.status);
      setDone(true);
    } catch (_) {
      setErr('Couldn’t send your brief just now. Please email contact@vurctne.com directly.');
    } finally {
      setSending(false);
    }
  }

  React.useEffect(() => {
    function onKey(e) { if (e.key === 'Escape') onClose(); }
    window.addEventListener('keydown', onKey);
    document.body.style.overflow = 'hidden';
    return () => { window.removeEventListener('keydown', onKey); document.body.style.overflow = ''; };
  }, [onClose]);

  return (
    <div className="vk-modal" onClick={onClose}>
      <div className="vk-inquiry" onClick={(e) => e.stopPropagation()}>
        <button className="vk-modal__x" onClick={onClose} aria-label="Close">×</button>
        {done ? (
          <div className="vk-inquiry__done">
            <Heading level={3} onDark>Brief received.</Heading>
            <Text onDark muted style={{ marginTop: 10 }}>
              Thanks{brand ? ', ' + brand.trim() : ''} — I’ll reply within a day with ideas and a rough timeline.
            </Text>
            <div style={{ marginTop: 'var(--vk-space-3)' }}>
              <Button variant="primary" onClick={onClose}>Done</Button>
            </div>
          </div>
        ) : (
          <>
            <span className="site-hero__kicker">Start a project</span>
            <Heading level={3} onDark style={{ marginTop: 8 }}>Tell me about the ad</Heading>
            <Text onDark muted style={{ marginTop: 10 }}>
              A line about the brand and what you need. I reply within a day — no agency, no run-around.
            </Text>
            <form className="vk-inquiry__form" onSubmit={submit}>
              <div className="vk-field">
                <label className="vk-label">Brand / company</label>
                <input className="vk-input" value={brand} onChange={(e) => setBrand(e.target.value)} placeholder="Acme Co." autoFocus />
              </div>
              <div className="vk-field">
                <label className="vk-label">Work email</label>
                <input className="vk-input" type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="you@brand.com" />
              </div>
              <div className="vk-field">
                <label className="vk-label">What do you need?</label>
                <div className="vk-typegrid">
                  {PROJECT_TYPES.map((p) => (
                    <button type="button" key={p}
                      className={'vk-typechip' + (type === p ? ' is-active' : '')}
                      onClick={() => setType(p)}>{p}</button>
                  ))}
                </div>
              </div>
              <div className="vk-field">
                <label className="vk-label">Anything else <span className="vk-label__opt">(optional)</span></label>
                <textarea className="vk-input vk-textarea" value={msg} onChange={(e) => setMsg(e.target.value)} placeholder="Timeline, budget range, the vibe you're after…" rows={3}></textarea>
              </div>
              {err && <Text onDark style={{ color: '#ff6b6b' }}>{err}</Text>}
              <Button variant="primary" size="lg" type="submit" disabled={!ok || sending}>{sending ? 'Sending…' : 'Send brief'}</Button>
            </form>
          </>
        )}
      </div>
    </div>
  );
}

function Site() {
  const [filter, setFilter] = React.useState('all');
  const [active, setActive] = React.useState(null);
  const [inquiry, setInquiry] = React.useState(false);
  const [content, setContent] = React.useState(null);

  // Load editable content (hero videos + films) managed via /admin.
  // Falls back to the built-in defaults if it's missing or malformed.
  React.useEffect(() => {
    let alive = true;
    fetch('content.json', { cache: 'no-cache' })
      .then((r) => (r.ok ? r.json() : Promise.reject(r.status)))
      .then((j) => { if (alive && j && Array.isArray(j.films)) setContent(j); })
      .catch(() => {});
    return () => { alive = false; };
  }, []);

  const allFilms = React.useMemo(
    () => (content && Array.isArray(content.films) ? content.films.filter((f) => !f.hidden).map(normalizeFilm) : FILMS),
    [content]
  );
  // Only offer category filters / nav links for pillars that actually have films.
  const presentPillars = React.useMemo(() => new Set(allFilms.map((f) => f.pillar)), [allFilms]);
  const visibleFilters = FILTERS.filter((f) => f.key === 'all' || presentPillars.has(f.key));
  // If the active filter's pillar disappears (e.g. a film was taken down), fall back to all.
  React.useEffect(() => {
    if (filter !== 'all' && !presentPillars.has(filter)) setFilter('all');
  }, [presentPillars, filter]);
  const heroClips = React.useMemo(
    () => (content && content.hero && Array.isArray(content.hero.videos) && content.hero.videos.length
      ? content.hero.videos.map((vv) => vv && vv.src).filter(Boolean)
      : DEFAULT_HERO_CLIPS),
    [content]
  );

  const films = filter === 'all' ? allFilms : allFilms.filter((f) => f.pillar === filter);
  const featured = films[0];
  const rest = films.slice(1);

  // Hero cinematic FX: pointer spotlight + running 24fps timecode
  React.useEffect(() => {
    const hero = document.querySelector('.site-hero');
    if (!hero) return;
    const onMove = (e) => {
      const r = hero.getBoundingClientRect();
      hero.style.setProperty('--mx', ((e.clientX - r.left) / r.width * 100) + '%');
      hero.style.setProperty('--my', ((e.clientY - r.top) / r.height * 100) + '%');
    };
    hero.addEventListener('mousemove', onMove);
    const tcEl = document.getElementById('heroTc');
    let f = 24 * 3600; // start at 01:00:00:00, film convention
    const pad = (n) => String(n).padStart(2, '0');
    const id = setInterval(() => {
      f += 1;
      const ff = f % 24, s = Math.floor(f / 24);
      if (tcEl) tcEl.textContent = `${pad(Math.floor(s / 3600) % 24)}:${pad(Math.floor(s / 60) % 60)}:${pad(s % 60)}:${pad(ff)}`;
    }, 1000 / 24);
    return () => { hero.removeEventListener('mousemove', onMove); clearInterval(id); };
  }, []);

  function navTo(e, target, nextFilter) {
    e.preventDefault();
    if (nextFilter) setFilter(nextFilter);
    go(target);
  }

  return (
    <div className="site" style={{ '--pillar': PILLAR_COLOR[filter] }}>
      {/* NAV */}
      <header className="site-navwrap">
        <div className="site-shell">
          <Nav
            links={[
              { label: 'Work', href: '#films', onClick: (e) => navTo(e, '#films', 'all') },
              ...(presentPillars.has('real') ? [{ label: 'Product', href: '#films', onClick: (e) => navTo(e, '#films', 'real') }] : []),
              ...(presentPillars.has('funny') ? [{ label: 'Social', href: '#films', onClick: (e) => navTo(e, '#films', 'funny') }] : []),
              { label: 'Why', href: '#why', onClick: (e) => navTo(e, '#why') },
              { label: 'About', href: '#about', onClick: (e) => navTo(e, '#about') },
            ]}
            action={<Button size="sm" onClick={() => setInquiry(true)}>Start a project</Button>}
          />
        </div>
      </header>

      {/* HERO */}
      <section className="site-hero">
        <HeroReel films={allFilms} />
        <HeroVideo clips={heroClips} />
        <div className="site-hero__veil" aria-hidden="true"></div>
        <div className="site-hero__spot" aria-hidden="true"></div>
        <div className="grain" aria-hidden="true"></div>
        <div className="site-shell site-hero__inner">
          <div className="hero-anim" style={{ animationDelay: '0ms' }}>
            <span className="site-hero__kicker">Commercial films · made with <FlipAI /></span>
          </div>
          <div className="hero-anim" style={{ animationDelay: '90ms' }}>
            <h1 className="vk-h vk-h--1 vk-h--on-dark site-hero__title">
              Looks like millions.<br/>Costs a fraction.
            </h1>
          </div>
          <div className="hero-anim" style={{ animationDelay: '180ms' }}>
            <Text size="lg" onDark className="site-hero__sub">
              Cinematic brand films, ultra-real product shots, and scroll-stopping social —
              all directed with <FlipAI />.
            </Text>
          </div>
          <div className="hero-anim site-hero__actions" style={{ animationDelay: '270ms' }}>
            <Button variant="primary" size="lg" onClick={() => setInquiry(true)}>Start a project</Button>
            <Button variant="ghost" size="lg" className="site-ghost-light" onClick={() => { setFilter('all'); go('#films'); }}>Watch the reel</Button>
          </div>
          <div className="hero-anim site-hero__stats" style={{ animationDelay: '360ms' }}>
            <span className="stat"><b><span className="lt">&lt;</span>5%</b> the cost of a TV spot</span>
            <span className="stat"><b>Days</b>, not months</span>
            <span className="stat"><b>One</b> director, end to end</span>
          </div>
        </div>
        <div className="site-hero__scroll" aria-hidden="true">Scroll</div>
        <div className="hero-tc" aria-hidden="true"><i className="rec"></i><span id="heroTc">01:00:00:00</span></div>
      </section>

      {/* OFFERINGS */}
      <section id="offerings" className="site-section site-offerings">
        <div className="site-shell">
          <Reveal className="site-sectionhead">
            <span className="site-eyebrow"><span className="scene-no">SC. 01</span>What I make for brands</span>
            <Heading level={2} onDark>Three ways to use the camera that isn’t there</Heading>
          </Reveal>
          <div className="site-offergrid">
            {OFFERINGS.map((o, i) => (
              <Reveal key={o.key} delay={i * 90}>
                <div className="site-offer" role="button" tabIndex={0}
                  onClick={() => { setFilter(o.key); go('#films'); }}
                  onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); setFilter(o.key); go('#films'); } }}>
                  <span className="site-offer__rule" style={{ background: o.color }}></span>
                  <span className="site-offer__num">{o.num}</span>
                  <div className="site-offer__head">
                    <Tag pillar={o.key}>{o.name}</Tag>
                    <span className="site-offer__deliv">{o.deliverable}</span>
                  </div>
                  <Text onDark className="site-offer__line">{o.line}</Text>
                  <span className="site-offer__cta">See {o.name.toLowerCase()} work →</span>
                </div>
              </Reveal>
            ))}
          </div>
        </div>
      </section>

      {/* FILMS */}
      <section id="films" className="site-section site-films">
        <div className="site-shell">
          <Reveal className="site-sectionhead site-films__head">
            <div>
              <span className="site-eyebrow"><span className="scene-no">SC. 02</span>Selected work</span>
              <Heading level={2}>The reel</Heading>
            </div>
            <div className="site-filter" role="tablist" aria-label="Filter work">
              {visibleFilters.map((f) => (
                <button key={f.key}
                  className={'site-chip' + (filter === f.key ? ' is-active' : '')}
                  style={filter === f.key ? { background: PILLAR_COLOR[f.key], color: PILLAR_INK[f.key], borderColor: PILLAR_COLOR[f.key] } : undefined}
                  onClick={() => setFilter(f.key)}>{f.label}</button>
              ))}
            </div>
          </Reveal>

          {featured && (
            <Reveal>
              <div className="film-featured" role="button" tabIndex={0}
                onClick={() => setActive(featured)}
                onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); setActive(featured); } }}>
                <div className="film-featured__media">
                  <img src={featured.thumbnail} alt={featured.title} />
                  <span className="film-featured__play">
                    <svg viewBox="0 0 24 24" width="26" height="26" fill="currentColor"><path d="M8 5.5 L18.5 12 L8 18.5 Z"/></svg>
                  </span>
                </div>
                <div className="film-featured__body">
                  <div className="film-featured__head">
                    <Tag pillar={featured.pillar}>{featured.tagLabel}</Tag>
                    <span className="film-featured__meta">{featured.meta}</span>
                  </div>
                  <h3 className="film-featured__title">{featured.title}</h3>
                  <Text muted className="film-featured__synopsis">{featured.synopsis}</Text>
                  <span className="film-featured__watch">Watch film →</span>
                </div>
              </div>
            </Reveal>
          )}

          <div className="site-grid">
            {rest.map((f, i) => (
              <Reveal key={f.title} delay={(i % 3) * 70}>
                <ScrubCard film={f} onOpen={setActive} />
              </Reveal>
            ))}
          </div>
        </div>
      </section>

      {/* WHY VURCTNE */}
      <section id="why" className="site-section site-why">
        <div className="site-shell">
          <Reveal className="site-sectionhead">
            <span className="site-eyebrow"><span className="scene-no">SC. 03</span>Why brands pick this</span>
            <Heading level={2} onDark>Agency-grade films.<br/>Without the agency.</Heading>
          </Reveal>
          <div className="site-edgegrid">
            {EDGE.map((e, i) => (
              <Reveal key={e.k} delay={(i % 3) * 80}>
                <div className="site-edge">
                  <span className="site-edge__no">{String(i + 1).padStart(2, '0')}</span>
                  <h3 className="site-edge__k">{e.k}</h3>
                  <Text onDark muted className="site-edge__d">{e.d}</Text>
                </div>
              </Reveal>
            ))}
          </div>
        </div>
      </section>

      {/* ABOUT */}
      <section id="about" className="site-section site-about">
        <div className="site-shell site-about__grid">
          <Reveal>
            <span className="site-eyebrow"><span className="scene-no">SC. 04</span>About</span>
            <Heading level={2} className="site-about__title">
              V for Vurctne.<br/>I for Imagination.
            </Heading>
          </Reveal>
          <Reveal delay={120} className="site-about__body">
            <p className="site-about__lede">Not artificial intelligence.<br/>Artificial <em>imagination</em>.</p>
            <Text size="lg">
              A bilingual director using <FlipAI /> to turn a brief into a
              finished film — fast, on-brand, and built to sell, for less than 5% of what a conventional
              TV commercial costs. Big ideas, without the big production budget.
            </Text>
            <Text muted style={{ marginTop: 'var(--vk-space-3)' }}>
              The mark is an inverted <strong>A</strong> (a <strong>V</strong>) beside an <strong>I</strong> —
              flip it and it reads <strong>AI</strong>. A human director and a new kind of camera, working as one.
            </Text>
            <div className="site-about__cta">
              <Button variant="primary" onClick={() => setInquiry(true)}>Start a project</Button>
              <Button variant="ghost" onClick={() => { setFilter('all'); go('#films'); }}>Watch the reel</Button>
            </div>
          </Reveal>
        </div>
      </section>

      {/* FAQ */}
      <section id="faq" className="site-section site-faq">
        <div className="site-shell">
          <div className="site-sectionhead">
            <span className="site-eyebrow"><span className="scene-no">SC. 05</span>Questions</span>
            <Heading level={2} onDark>Good questions,<br/>straight answers.</Heading>
          </div>
          <div className="site-faqlist">
            {FAQ.map((f, i) => (
              <details className="site-faq__item" key={i}>
                <summary className="site-faq__q">{f.q}<span className="site-faq__mark" aria-hidden="true">+</span></summary>
                <div className="site-faq__a"><Text onDark muted>{f.a}</Text></div>
              </details>
            ))}
          </div>
        </div>
      </section>

      {/* FOOTER */}
      <footer className="site-footer">
        <div className="site-shell">
          <div className="site-footer__cta">
            <Heading level={2} onDark className="site-footer__big">Got a brief?<br/>Let’s make something real.</Heading>
            <Button variant="primary" size="lg" onClick={() => setInquiry(true)}>Start a project</Button>
          </div>
          <div className="site-footer__top">
            <Logo size={34} tone="light" />
            <div className="site-footer__contact">
              <span className="site-footer__label">For commercial films and collaborations</span>
              <a className="site-footer__email" href="mailto:contact@vurctne.com">contact@vurctne.com</a>
            </div>
          </div>
          <div className="site-footer__bottom">
            <span className="vk-footer__note">AI-generated films. Made by Vurctne.</span>
            <span className="vk-footer__note">Every film on this site is created with generative AI tools and directed by Vurctne. Yes — this website was made with AI as well.</span>
          </div>
        </div>
      </footer>

      {active && <Player film={active} onClose={() => setActive(null)} onStart={() => setInquiry(true)} />}
      {inquiry && <Inquiry onClose={() => setInquiry(false)} />}
    </div>
  );
}

function go(hash) {
  const el = document.querySelector(hash);
  if (el) window.scrollTo({ top: el.getBoundingClientRect().top + window.scrollY - 70, behavior: 'smooth' });
}

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