// hero.jsx — Section 1
const { useState: _useS, useEffect: _useE, useRef: _useR } = React;

/** Jeu de cartes — uniquement les icônes fournies (public/hero-deck/01.png …) */
const HERO_DECK_LOGOS = Array.from({ length: 11 }, (_, i) => {
  const n = String(i + 1).padStart(2, '0');
  return { id: 'deck-' + n, src: '/hero-deck/' + n + '.png', cover: true };
});

const DECK_CYCLE_MS = 2000;

/** Ronds portrait à gauche de la ligne Trustpilot — fichiers dans `public/trust-avatars/`. */
const HERO_TRUST_AVATAR_SRCS = [
  '/trust-avatars/01.png',
  '/trust-avatars/02.png',
  '/trust-avatars/03.png',
  '/trust-avatars/04.png',
  '/trust-avatars/05.png',
];

const HERO_CHAT_AI_TICKER_ITEMS = [
  { name: 'GPT', icon: '/icons/lobehub/openai.svg' },
  { name: 'Claude', icon: '/icons/lobehub/claude.svg' },
  { name: 'Gemini', icon: '/icons/lobehub/gemini.svg' },
  { name: 'DeepSeek', icon: '/icons/lobehub/deepseek.svg' },
  { name: 'Mistral', icon: '/icons/lobehub/mistral.svg' },
  { name: 'Grok', icon: '/icons/lobehub/grok.svg' },
  { name: 'Qwen', icon: '/icons/lobehub/qwen-color.svg' },
  { name: 'Kimi', icon: '/icons/lobehub/kimi.svg' },
  { name: 'Perplexity', icon: '/icons/lobehub/perplexity.svg' },
  { name: 'Meta AI', icon: '/icons/lobehub/metaai-color.svg' },
];

const HERO_IMAGE_AI_TICKER_ITEMS = [
  { name: 'Flux', icon: '/icons/lobehub/flux.svg' },
  { name: 'Stable Diffusion', icon: '/icons/lobehub/stability-color.svg' },
  { name: 'Recraft', icon: '/icons/lobehub/recraft.svg' },
  { name: 'DALL·E', icon: '/icons/lobehub/dalle-color.svg' },
  { name: 'Imagen', label: 'IM' },
  { name: 'Midjourney', icon: '/icons/lobehub/midjourney.svg' },
  { name: 'Ideogram', icon: '/icons/lobehub/ideogram.svg' },
];

const HERO_VIDEO_AI_TICKER_ITEMS = [
  { name: 'Kling', icon: '/icons/lobehub/kling-color.svg' },
  { name: 'Minimax', icon: '/icons/lobehub/minimax-color.svg' },
  { name: 'Seedance', label: 'SE' },
  { name: 'Veo', label: 'VE' },
  { name: 'Sora', icon: '/icons/lobehub/sora-color.svg' },
  { name: 'Udio', icon: '/icons/lobehub/udio-color.svg' },
  { name: 'ElevenLabs', icon: '/icons/lobehub/elevenlabs.svg' },
];

/** Ligne avis sous les CTA — avatars + note + marque Trustpilot */
function HeroTrustpilotRow() {
  const n = HERO_TRUST_AVATAR_SRCS.length;
  return (
    <a
      href="https://www.trustpilot.com/review/chatflix.ai"
      target="_blank"
      rel="noopener noreferrer"
      className="hero-trust-row"
      aria-label="Voir les avis Chatflix sur Trustpilot"
    >
      <div className="hero-trust-row__avatars" aria-hidden="true">
        {HERO_TRUST_AVATAR_SRCS.map((src, i) => (
          <span key={src} className="hero-trust-row__avatar" style={{ zIndex: n - i }}>
            <img src={src} alt="" decoding="async" draggable={false} />
          </span>
        ))}
      </div>
      <span className="hero-trust-row__score">4.3</span>
      <span className="hero-trust-row__brand">
        <span className="hero-trust-stars" aria-hidden="true">
          {[0, 1, 2, 3, 4].map((i) => (
            <span key={i} className={'hero-trust-star-box' + (i === 4 ? ' hero-trust-star-box--partial' : '')}>
              <span className="hero-trust-star-fill" />
              <span className="hero-trust-star">★</span>
            </span>
          ))}
        </span>
        <span className="hero-trust-row__tp-word">Trustpilot</span>
      </span>
    </a>
  );
}

function BetaAccessPage() {
  const [code, setCode] = _useS('');
  const [error, setError] = _useS('');
  const inputRefs = _useR([]);
  const codeDigits = code.padEnd(6, ' ').slice(0, 6).split('');
  const canSubmit = code.length === 6;
  const betaCode = '061324';

  const updateDigit = (index, value) => {
    const digits = codeDigits.map((digit) => digit.trim());
    const clean = value.replace(/\D/g, '').slice(0, 6 - index);
    if (!clean) {
      digits[index] = '';
      setCode(digits.join('').slice(0, 6));
      if (error) setError('');
      return;
    }

    clean.split('').forEach((digit, offset) => {
      digits[index + offset] = digit;
    });
    const nextCode = digits.join('').slice(0, 6);
    setCode(nextCode);
    if (error) setError('');
    const nextIndex = Math.min(index + clean.length, 5);
    inputRefs.current[nextIndex]?.focus();
  };

  const handleDigitKeyDown = (event, index) => {
    if (event.key !== 'Backspace') return;
    const digits = codeDigits.map((digit) => digit.trim());
    if (digits[index]) return;
    if (index > 0) {
      digits[index - 1] = '';
      setCode(digits.join('').slice(0, 6));
      if (error) setError('');
      inputRefs.current[index - 1]?.focus();
    }
  };

  const submit = (event) => {
    event.preventDefault();
    if (!canSubmit) return;
    if (code !== betaCode) {
      setError('Code incorrect');
      inputRefs.current[0]?.focus();
      return;
    }
    navigateBeta('/beta-username');
  };

  return (
    <BetaStepLayout
      titleTop="Rentre le code"
      titleGradient="de la bêta privée."
      copy="Entre le code d'accès partagé par l'équipe Chatflix pour ouvrir l'espace réservé aux premiers invités."
    >
      <form className="beta-access-form" onSubmit={submit}>
        <label className="beta-access-form__label" htmlFor="beta-access-code">
          Code d&apos;accès
        </label>
        <div className="beta-access-code-grid" role="group" aria-label="Code d'accès à six chiffres">
          {codeDigits.map((digit, index) => (
            <input
              key={index}
              ref={(node) => {
                inputRefs.current[index] = node;
              }}
              id={index === 0 ? 'beta-access-code' : undefined}
              className="beta-access-code-grid__input"
              type="text"
              inputMode="numeric"
              pattern="[0-9]*"
              maxLength="1"
              autoComplete={index === 0 ? 'one-time-code' : 'off'}
              value={digit.trim()}
              aria-label={`Chiffre ${index + 1} du code d'accès`}
              onChange={(e) => updateDigit(index, e.target.value)}
              onKeyDown={(e) => handleDigitKeyDown(e, index)}
              onFocus={(e) => e.target.select()}
            />
          ))}
        </div>
        {error ? <div className="beta-access-error">{error}</div> : null}
        <BetaStepActions disabled={!canSubmit} label="Accéder à la bêta" />
      </form>
    </BetaStepLayout>
  );
}

function navigateBeta(path) {
  window.history.pushState(null, '', path);
  window.dispatchEvent(typeof PopStateEvent === 'function' ? new PopStateEvent('popstate') : new Event('popstate'));
}

function BetaStepLayout({ titleTop, titleGradient, copy, children }) {
  return (
    <section className="beta-access-page" aria-labelledby="beta-access-title">
      <div className="beta-access-page__shell">
        <h1 id="beta-access-title" className="beta-access-page__title display">
          <span className="display-ink">{titleTop}</span>
          <span className="display-brand-serif brand-grad-text hero-accent-aura">{titleGradient}</span>
        </h1>
        <p className="beta-access-page__copy">{copy}</p>
        <div className="beta-access-page__card surface-glass-shadow">{children}</div>
      </div>
    </section>
  );
}

function BetaStepActions({ disabled, label }) {
  return (
    <div className="beta-access-form__actions">
      <button
        type="submit"
        className="btn btn-hero-primary beta-access-form__submit"
        disabled={disabled}
        aria-disabled={disabled}
      >
        <span className="btn-hero-primary__label">{label}</span>
        <svg className="btn-hero-primary__icon" width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" aria-hidden="true">
          <path d="M5 12h14M13 5l7 7-7 7" />
        </svg>
      </button>
      <a className="beta-access-form__back" href="/">Retour à l’accueil</a>
    </div>
  );
}

function BetaUsernamePage() {
  const [username, setUsername] = _useS('');
  const canSubmit = username.trim().length >= 2;

  const submit = (event) => {
    event.preventDefault();
    if (!canSubmit) return;
    window.sessionStorage.setItem('chatflixBetaUsername', username.trim());
    navigateBeta('/beta-pin');
  };

  return (
    <BetaStepLayout
      titleTop="Choisis ton"
      titleGradient="nom d'utilisateur."
      copy="Ce nom permettra de personnaliser ton espace Chatflix pendant la bêta privée."
    >
      <form className="beta-access-form" onSubmit={submit}>
        <label className="beta-access-form__label" htmlFor="beta-username">
          Nom d&apos;utilisateur
        </label>
        <input
          id="beta-username"
          className="beta-access-text-field"
          type="text"
          autoComplete="username"
          spellCheck="false"
          placeholder="ex : tanguy"
          value={username}
          onChange={(event) => setUsername(event.target.value)}
        />
        <BetaStepActions disabled={!canSubmit} label="Continuer" />
      </form>
    </BetaStepLayout>
  );
}

function BetaPinPage() {
  const [pin, setPin] = _useS('');
  const [submitted, setSubmitted] = _useS(false);
  const inputRefs = _useR([]);
  const pinDigits = pin.padEnd(4, ' ').slice(0, 4).split('');
  const canSubmit = pin.length === 4;
  const username = window.sessionStorage.getItem('chatflixBetaUsername') || 'ton compte';

  const updateDigit = (index, value) => {
    const digits = pinDigits.map((digit) => digit.trim());
    const clean = value.replace(/\D/g, '').slice(0, 4 - index);
    if (!clean) {
      digits[index] = '';
      setPin(digits.join('').slice(0, 4));
      if (submitted) setSubmitted(false);
      return;
    }
    clean.split('').forEach((digit, offset) => {
      digits[index + offset] = digit;
    });
    setPin(digits.join('').slice(0, 4));
    if (submitted) setSubmitted(false);
    inputRefs.current[Math.min(index + clean.length, 3)]?.focus();
  };

  const handleDigitKeyDown = (event, index) => {
    if (event.key !== 'Backspace') return;
    const digits = pinDigits.map((digit) => digit.trim());
    if (digits[index]) return;
    if (index > 0) {
      digits[index - 1] = '';
      setPin(digits.join('').slice(0, 4));
      if (submitted) setSubmitted(false);
      inputRefs.current[index - 1]?.focus();
    }
  };

  const submit = (event) => {
    event.preventDefault();
    if (!canSubmit) return;
    window.sessionStorage.setItem('chatflixBetaPinReady', 'true');
    setSubmitted(true);
  };

  return (
    <BetaStepLayout
      titleTop="Crée/rentre ton"
      titleGradient="code à 4 chiffres."
      copy={`Dernière étape pour sécuriser l'accès privé de ${username}.`}
    >
      <form className="beta-access-form" onSubmit={submit}>
        <label className="beta-access-form__label" htmlFor="beta-pin-code">
          Code personnel
        </label>
        <div className="beta-access-code-grid beta-access-code-grid--pin" role="group" aria-label="Code personnel à quatre chiffres">
          {pinDigits.map((digit, index) => (
            <input
              key={index}
              ref={(node) => {
                inputRefs.current[index] = node;
              }}
              id={index === 0 ? 'beta-pin-code' : undefined}
              className="beta-access-code-grid__input"
              type="text"
              inputMode="numeric"
              pattern="[0-9]*"
              maxLength="1"
              autoComplete="off"
              value={digit.trim()}
              aria-label={`Chiffre ${index + 1} du code personnel`}
              onChange={(e) => updateDigit(index, e.target.value)}
              onKeyDown={(e) => handleDigitKeyDown(e, index)}
              onFocus={(e) => e.target.select()}
            />
          ))}
        </div>
        <BetaStepActions disabled={!canSubmit} label="Finaliser l’accès" />
        <div className={'beta-access-success' + (submitted ? ' beta-access-success--visible' : '')}>
          <div className="beta-access-success__title">Accès prêt</div>
          <div className="beta-access-success__text">
            Ton espace bêta privé est configuré.
          </div>
        </div>
      </form>
    </BetaStepLayout>
  );
}

function HeroAiTickerRow({ items, direction = 'left', index = 0 }) {
  const row = items.concat(items);
  return (
    <div
      className={'hero-ai-ticker__row hero-ai-ticker__row--' + direction}
      style={{ '--ticker-row-delay': `${220 + index * 150}ms` }}
    >
      <div className="hero-ai-ticker__track">
        {row.map((item, i) => (
          <span className="hero-ai-ticker__pill" key={item.name + '-' + i}>
            <span className="hero-ai-ticker__icon" aria-hidden="true">
              {item.icon ? <img src={item.icon} alt="" decoding="async" draggable={false} /> : item.label}
            </span>
            <span>{item.name}</span>
          </span>
        ))}
      </div>
    </div>
  );
}

function HeroAiTicker({ active = false }) {
  return (
    <div className={'hero-ai-ticker' + (active ? ' hero-ai-ticker--visible' : '')} aria-label="IA disponibles dans Chatflix">
      <HeroAiTickerRow items={HERO_CHAT_AI_TICKER_ITEMS} direction="right" index={0} />
      <HeroAiTickerRow items={HERO_IMAGE_AI_TICKER_ITEMS} direction="left" index={1} />
      <HeroAiTickerRow items={HERO_VIDEO_AI_TICKER_ITEMS} direction="right" index={2} />
    </div>
  );
}

/** Après apparition complète du titre, on laisse respirer une fraction de seconde avant la vidéo. */
const WORD_REVEAL_STAGGER_MS = 24;
const WORD_REVEAL_MAX_MS = 460;
const HEADLINE_WORDS_PER_LINE = 5;
const HERO_VIDEO_AFTER_TITLE_MS =
  WORD_REVEAL_STAGGER_MS * (HEADLINE_WORDS_PER_LINE - 1) + WORD_REVEAL_MAX_MS + 100;

/** Réservés au bloc vidéo hero (ratio + largeur max, inchangés avec ChatflixHeroVideo) */
const HERO_VIDEO_W = 1880;
const HERO_VIDEO_H = 1080;
const MOCK_DISPLAY_MAX_W = 1340;

/** Distance circulaire depuis la carte du devant → slot -2…+2 ou masqué */
function deckSlotForIndex(logoIdx, frontIdx, len) {
  const diff = (logoIdx - frontIdx + len) % len;
  if (diff === 0) return 0;
  if (diff === 1) return 1;
  if (diff === 2) return 2;
  if (diff === len - 1) return -1;
  if (diff === len - 2) return -2;
  return null;
}

function slotClass(slot) {
  if (slot === null) return 'hero-deck-carousel__card--hidden';
  if (slot === 0) return 'hero-deck-carousel__card--s0';
  if (slot === 1) return 'hero-deck-carousel__card--s1';
  if (slot === 2) return 'hero-deck-carousel__card--s2';
  if (slot === -1) return 'hero-deck-carousel__card--sn1';
  return 'hero-deck-carousel__card--sn2';
}

function HeroDeckCarousel({ active }) {
  const len = HERO_DECK_LOGOS.length;
  const [frontIdx, setFrontIdx] = _useS(0);
  const [reduceMotion, setReduceMotion] = _useS(false);

  _useE(() => {
    const mq = window.matchMedia('(prefers-reduced-motion: reduce)');
    const fn = () => setReduceMotion(!!mq.matches);
    fn();
    mq.addEventListener('change', fn);
    return () => mq.removeEventListener('change', fn);
  }, []);

  _useE(() => {
    if (!active || reduceMotion) return undefined;
    const id = setInterval(() => {
      setFrontIdx((i) => (i + 1) % len);
    }, DECK_CYCLE_MS);
    return () => clearInterval(id);
  }, [active, reduceMotion, len]);

  return (
    <div className={'hero-deck-carousel' + (active ? ' hero-deck-carousel--on' : '')} aria-hidden="true">
      <div className="hero-deck-carousel__bob">
        <div className="hero-deck-carousel__stage">
          {HERO_DECK_LOGOS.map((logo, idx) => {
            const slot = deckSlotForIndex(idx, frontIdx, len);
            return (
              <div key={logo.id} className={'hero-deck-carousel__card ' + slotClass(slot)}>
                <div className="hero-deck-carousel__card-inner">
                  <img
                    src={logo.src}
                    alt=""
                    decoding="async"
                    draggable={false}
                    className={logo.cover ? 'hero-deck-carousel__img--cover' : ''}
                  />
                </div>
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}

// Timeline intro hero (ms) — de haut en bas : ligne1 → ligne2 → CTA → Trustpilot/images → lignes IA
const T_DECK = 50;
const DECK_TO_L1 = 190;
const WORD = 24;
const GAP = 90;
const LINE_TO_COPY = 110;
const COPY_TO_CTA = 190;
const CTA_TO_TRUST = 220;
const T_L1 = T_DECK + DECK_TO_L1;
const T_L2 = T_L1 + 5 * WORD + GAP;
const T_COPY = T_L2 + 5 * WORD + LINE_TO_COPY;
const T_CTA = T_COPY + COPY_TO_CTA;
const T_TRUST = T_CTA + CTA_TO_TRUST;

function navIntroOffsetMs() {
  if (typeof window !== 'undefined' && typeof window.NAV_INTRO_MS === 'number') {
    return window.NAV_INTRO_MS;
  }
  return 1316;
}

function Hero() {
  const [showL1, setShowL1] = _useS(false);
  const [showL2, setShowL2] = _useS(false);
  const [showCopy, setShowCopy] = _useS(false);
  const [showCta, setShowCta] = _useS(false);
  const [showTrust, setShowTrust] = _useS(false);
  const [showHeroVideo, setShowHeroVideo] = _useS(false);

  _useE(() => {
    const navMs = navIntroOffsetMs();
    const reduced =
      typeof window !== 'undefined' &&
      window.matchMedia('(prefers-reduced-motion: reduce)').matches;

    if (reduced) {
      const t0 = navMs + 100;
      const ids = [
        setTimeout(() => setShowL1(true), t0 + 50),
        setTimeout(() => setShowL2(true), t0 + 100),
        setTimeout(() => setShowCopy(true), t0 + 150),
        setTimeout(() => setShowCta(true), t0 + 200),
        setTimeout(() => setShowTrust(true), t0 + 250)];
      return () => ids.forEach(clearTimeout);
    }

    const ids = [
      setTimeout(() => setShowL1(true), navMs + T_L1),
      setTimeout(() => setShowL2(true), navMs + T_L2),
      setTimeout(() => setShowCopy(true), navMs + T_COPY),
      setTimeout(() => setShowCta(true), navMs + T_CTA),
      setTimeout(() => setShowTrust(true), navMs + T_TRUST)];
    return () => ids.forEach(clearTimeout);
  }, []);

  _useE(() => {
    if (!showL2) return;
    const reduced =
      typeof window !== 'undefined' &&
      window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    const delayMs = reduced ? 320 : HERO_VIDEO_AFTER_TITLE_MS;
    const id = setTimeout(() => setShowHeroVideo(true), delayMs);
    return () => clearTimeout(id);
  }, [showL2]);

  const headline1 = ['Toutes', 'les', 'meilleures', 'IA'];
  const headline2 = ['Une', 'seule', 'application'];

  return (
    <section id="section-hero">
      {/* Bloc centré verticalement : logo modèle, titre, CTA */}
      <div
        className="hero-first-screen"
        style={{
        width: '100%',
        boxSizing: 'border-box',
        position: 'relative',
        zIndex: 1
      }}>
      <img
        className={'hero-side-illustration hero-side-illustration--left' + (showTrust ? ' hero-side-illustration--visible' : '')}
        src="/hero-side/sofa.png"
        alt=""
        aria-hidden="true"
      />
      <img
        className={'hero-side-illustration hero-side-illustration--right' + (showTrust ? ' hero-side-illustration--visible' : '')}
        src="/hero-side/desk.png"
        alt=""
        aria-hidden="true"
      />
      <div className="hero-foreground">
      <div className="hero-foreground-inner">
      {/* Headline */}
      <h1 className="display hero-headline" style={{ textAlign: 'center', margin: '0 auto' }}>
        <span style={{ display: 'block' }}>
          {headline1.map((w, i) =>
          <WordReveal key={i} word={w} lineReady={showL1} wordIndex={i} accent={w === 'IA'} />
          )}
        </span>
        <span style={{ display: 'block' }}>
          {headline2.map((w, i) =>
          <WordReveal key={i} word={w} lineReady={showL2} wordIndex={i} accent={w === 'Une'} />
          )}
        </span>
      </h1>

      <div className="hero-below-title">
      <p
        style={{
          textAlign: 'center',
          maxWidth: 720,
          margin: '30px auto 0',
          padding: '0 16px',
          fontSize: 18,
          fontWeight: 500,
          letterSpacing: '-0.02em',
          lineHeight: 1.4,
          color: 'var(--ink-3)',
          opacity: showCopy ? 1 : 0,
          transform: showCopy ? 'translate3d(0,0,0)' : 'translate3d(0,-26px,0)',
          transition: 'opacity 430ms cubic-bezier(.22,1,.36,1), transform 620ms cubic-bezier(.16,1.45,.32,1)',
        }}
      >
        Chats, Images, Vidéos, Code, Slide, Call, Groupe, Musique et d&apos;autres
      </p>
      <p
        style={{
          textAlign: 'center',
          maxWidth: 560,
          margin: '8px auto 0',
          padding: '0 16px',
          fontSize: 18,
          fontWeight: 500,
          letterSpacing: '-0.02em',
          lineHeight: 1.4,
          color: 'var(--ink-3)',
          opacity: showCopy ? 1 : 0,
          transform: showCopy ? 'translate3d(0,0,0)' : 'translate3d(0,-26px,0)',
          transition: 'opacity 430ms cubic-bezier(.22,1,.36,1) 70ms, transform 620ms cubic-bezier(.16,1.45,.32,1) 70ms',
        }}
      >
        + de 20 models, Une seule interface.
      </p>

      {/* CTAs */}
      <div style={{
        display: 'flex', gap: 16, marginTop: 40, flexWrap: 'wrap', justifyContent: 'center',
        opacity: showCta ? 1 : 0,
        transform: showCta ? 'scale(1) translate3d(0,10px,0)' : 'scale(0.94) translate3d(0,-28px,0)',
        transition: 'opacity 450ms cubic-bezier(.22,1,.36,1), transform 640ms cubic-bezier(.14,1.62,.32,1)'
      }}>
        <a id="hero-primary-cta" href="/beta-access" target="_top" className="btn btn-primary btn-hero-primary">
          <span className="btn-hero-primary__label">Essayer Chatflix gratuitement</span>
          <svg className="btn-hero-primary__icon" width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" aria-hidden="true">
            <path d="M5 12h14M13 5l7 7-7 7" />
          </svg>
        </a>
        <button type="button" className="btn btn-ghost btn-ghost-bubble">
          Voir comment ça marche
          <span className="arrow">↓</span>
        </button>
      </div>

      <div
        style={{
          display: 'flex',
          flexDirection: 'column',
          alignItems: 'center',
          justifyContent: 'center',
          marginTop: 18,
          opacity: showTrust ? 1 : 0,
          transform: showTrust ? 'translate3d(0,10px,0)' : 'translate3d(0,-22px,0)',
          transition:
            'opacity 460ms cubic-bezier(.22,1,.36,1), transform 660ms cubic-bezier(.14,1.5,.32,1)',
        }}
      >
        <HeroTrustpilotRow />
        <HeroAiTicker active={showTrust} />
      </div>
      </div>
      </div>
      </div>
      </div>

      {/* Vidéo hero — après apparition complète du titre (repère scroll pour la nav) */}
      <div
        id="hero-video-scroll-root"
        style={{
        width: '100%', maxWidth: 'min(100%, 1440px)',
        marginLeft: 'auto', marginRight: 'auto',
        boxSizing: 'border-box',
        position: 'relative',
        zIndex: 1,
        opacity: showHeroVideo ? 1 : 0,
        transform: showHeroVideo ? 'translate3d(0,0,0) scale(1)' : 'translate3d(0,40px,0) scale(0.96)',
        transition: 'opacity 670ms cubic-bezier(.22,1,.36,1) 0ms, transform 700ms cubic-bezier(.22,1,.36,1) 0ms',
        perspective: '2000px',
        pointerEvents: showHeroVideo ? 'auto' : 'none',
      }}>
        {showHeroVideo ? (
          <ChatflixHeroVideo />
        ) : (
          <div
            aria-hidden
            style={{
              width: '100%',
              maxWidth: MOCK_DISPLAY_MAX_W,
              marginLeft: 'auto',
              marginRight: 'auto',
              aspectRatio: `${HERO_VIDEO_W} / ${HERO_VIDEO_H}`,
              visibility: 'hidden',
              pointerEvents: 'none',
            }}
          />
        )}
      </div>
    </section>);

}

function WordReveal({ word, lineReady, wordIndex, accent = false }) {
  const d = wordIndex * WORD_REVEAL_STAGGER_MS;
  return (
    <span style={{
      display: 'inline-block',
      marginRight: '0.25em',
      opacity: lineReady ? 1 : 0,
      filter: lineReady ? 'blur(0)' : 'blur(7px)',
      transform: lineReady ? 'translate3d(0,0,0)' : 'translate3d(0,-34px,0)',
      transition: `opacity 450ms cubic-bezier(.22,1,.36,1) ${d}ms, filter 480ms cubic-bezier(.22,1,.36,1) ${d}ms, transform 620ms cubic-bezier(.14,1.58,.32,1) ${d}ms`
    }} className={accent ? 'brand-grad-text display-brand-serif hero-accent-aura hero-title-accent' : 'display-ink'}>
      {word}
    </span>);

}

function ChatflixHeroVideo() {
  const videoRef = _useR(null);
  const [reduceMotion, setReduceMotion] = _useS(false);

  _useE(() => {
    const mq = window.matchMedia('(prefers-reduced-motion: reduce)');
    const fn = () => setReduceMotion(!!mq.matches);
    fn();
    mq.addEventListener('change', fn);
    return () => mq.removeEventListener('change', fn);
  }, []);

  _useE(() => {
    const v = videoRef.current;
    if (!v) return;
    if (reduceMotion) {
      v.pause();
    } else {
      const p = v.play();
      if (p && typeof p.catch === 'function') p.catch(() => {});
    }
  }, [reduceMotion]);

  const restartVideo = () => {
    const v = videoRef.current;
    if (!v) return;
    v.currentTime = 0;
    const p = v.play();
    if (p && typeof p.catch === 'function') p.catch(() => {});
  };

  return (
    <div
      className="hero-video-shell mock-product-shot-wrap"
      style={{
        overflow: 'visible',
        width: '100%',
        maxWidth: MOCK_DISPLAY_MAX_W,
        marginLeft: 'auto',
        marginRight: 'auto',
      }}
    >
      <div className="hero-video-halo" aria-hidden="true">
        <span className="hero-video-halo__shadow" />
        <span className="hero-video-halo__glass" />
      </div>
      <div
        className="hero-video-interactive"
        style={{
          overflow: 'hidden',
          lineHeight: 0,
          background: '#000',
          aspectRatio: `${HERO_VIDEO_W} / ${HERO_VIDEO_H}`,
        }}
      >
        <video
          ref={videoRef}
          src="/hero-video.mp4"
          width={HERO_VIDEO_W}
          height={HERO_VIDEO_H}
          autoPlay
          muted
          loop
          playsInline
          preload="auto"
          aria-label="Démonstration de l’interface Chatflix"
          style={{
            display: 'block',
            width: '100%',
            height: 'auto',
            verticalAlign: 'top',
            userSelect: 'none',
            pointerEvents: 'none',
          }}
        />
        <button
          type="button"
          className="hero-video-restart"
          onClick={restartVideo}
        >
          <span className="hero-video-restart__label">Recommencer</span>
          <svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
            <path d="M1 4v6h6M23 20v-6h-6" />
            <path d="M20.49 9A9 9 0 0 0 5.64 5.64L1 10M23 14l-4.64 4.36A9 9 0 0 1 3.51 15" />
          </svg>
        </button>
      </div>
    </div>
  );
}

window.Hero = Hero;
