const { useState, useEffect, useRef, Icon, MagneticBtn, SplitText, BlurIn, NOTIF_SAMPLES, useLandingStats } = window;

/* ============================================================
   HERO — 3 variants, switched via the `variant` prop
   - orb        : dominant serif + living orb light + notifs floating
   - dashboard  : split hero, copy left, live dashboard right
   - notifs     : giant type with a 3D-layered notif stack
   ============================================================ */

function Hero({ variant = 'orb' }) {
  const isLight = typeof document !== 'undefined' && document.documentElement.getAttribute('data-theme') === 'light';
  const [theme, setTheme] = useState(isLight ? 'light' : 'dark');
  useEffect(() => {
    const obs = new MutationObserver(() => {
      setTheme(document.documentElement.getAttribute('data-theme') === 'light' ? 'light' : 'dark');
    });
    obs.observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] });
    return () => obs.disconnect();
  }, []);
  const lt = theme === 'light';
  const fillColor = lt ? '#1a1a1a' : 'white';
  const fillOpacity1 = lt ? 0.07 : 0.13;
  const fillOpacity2 = lt ? 0.03 : 0.04;

  return (
    <section id="hero" style={{ position: 'relative', minHeight: '100dvh', paddingTop: 'clamp(140px, 12vh, 200px)', paddingBottom: 'clamp(32px, 6vh, 80px)', overflow: 'hidden', display: 'flex', flexDirection: 'column', justifyContent: 'center' }}>
      {/* SVG V pleine page — tracé animé puis remplissage */}
      {variant === 'orb' && (
        <svg
          aria-hidden="true"
          className="hero-v-svg"
          style={{
            position: 'absolute', top: 0, left: 0,
            width: '100%', height: '100%',
            pointerEvents: 'none', userSelect: 'none',
            zIndex: 0,
          }}
          viewBox="0 0 1000 960"
          preserveAspectRatio="none"
        >
          <defs>
            {/* Remplissage bras gauche */}
            <linearGradient id="heroVLeft" x1="0" y1="0" x2="280" y2="720" gradientUnits="userSpaceOnUse">
              <stop offset="0%"   stopColor={fillColor} stopOpacity={fillOpacity1} />
              <stop offset="55%"  stopColor={fillColor} stopOpacity={fillOpacity2} />
              <stop offset="100%" stopColor={fillColor} stopOpacity="0" />
            </linearGradient>
            {/* Remplissage bras droit */}
            <linearGradient id="heroVRight" x1="1000" y1="0" x2="720" y2="720" gradientUnits="userSpaceOnUse">
              <stop offset="0%"   stopColor={fillColor} stopOpacity={fillOpacity1} />
              <stop offset="55%"  stopColor={fillColor} stopOpacity={fillOpacity2} />
              <stop offset="100%" stopColor={fillColor} stopOpacity="0" />
            </linearGradient>
            {/* Tracé lumineux — bord intérieur du V de gauche à droite */}
            <linearGradient id="heroVStroke" x1="0" y1="0" x2="1000" y2="0" gradientUnits="userSpaceOnUse">
              <stop offset="0%"   stopColor="#2DCD93" stopOpacity="0.9" />
              <stop offset="48%"  stopColor="#2DCD93" stopOpacity="0.6" />
              <stop offset="52%"  stopColor="#2DCD93" stopOpacity="0.6" />
              <stop offset="100%" stopColor="#2DCD93" stopOpacity="0.9" />
            </linearGradient>
            {/* Glow flou sur le tracé */}
            <linearGradient id="heroVStrokeGlow" x1="0" y1="0" x2="1000" y2="0" gradientUnits="userSpaceOnUse">
              <stop offset="0%"   stopColor="#2DCD93" stopOpacity="0.5" />
              <stop offset="50%"  stopColor="#2DCD93" stopOpacity="0.25" />
              <stop offset="100%" stopColor="#2DCD93" stopOpacity="0.5" />
            </linearGradient>
            <filter id="heroVBlur" x="-20%" y="-40%" width="140%" height="180%">
              <feGaussianBlur stdDeviation="10" />
            </filter>
            {/* Glow remplissage */}
            <linearGradient id="heroVLeftGlow" x1="0" y1="0" x2="320" y2="660" gradientUnits="userSpaceOnUse">
              <stop offset="0%"   stopColor="#2DCD93" stopOpacity="0.22" />
              <stop offset="60%"  stopColor="#2DCD93" stopOpacity="0.04" />
              <stop offset="100%" stopColor="#2DCD93" stopOpacity="0" />
            </linearGradient>
            <linearGradient id="heroVRightGlow" x1="1000" y1="0" x2="680" y2="660" gradientUnits="userSpaceOnUse">
              <stop offset="0%"   stopColor="#2DCD93" stopOpacity="0.22" />
              <stop offset="60%"  stopColor="#2DCD93" stopOpacity="0.04" />
              <stop offset="100%" stopColor="#2DCD93" stopOpacity="0" />
            </linearGradient>
            <filter id="heroVGlowBlur" x="-30%" y="-10%" width="160%" height="120%">
              <feGaussianBlur stdDeviation="18" />
            </filter>
          </defs>

          {/*
            V à largeur constante de 160px (±80 de chaque côté du coin).
            Pointe à y=880 → profonde, cachée derrière la VSL.

            Bras gauche : (-80,0) (80,0) (580,880) (420,880)
            Bras droit  : (920,0) (1080,0) (580,880) (420,880)

            Trace verte = bord EXTÉRIEUR réel de chaque bras :
              Gauche ext : (-80,0) → (420,880)   — part hors-écran gauche, clippé net
              Droite ext : (1080,0) → (580,880)  — part hors-écran droit, clippé net
            Path continu : M -80,0 L 420,880 L 580,880 L 1080,0
          */}

          {/* ── Couche 1 : remplissage blanc subtil ── */}
          <polygon className="hero-v-fill" points="-80,0 80,0 580,880 420,880" fill="url(#heroVLeft)"
            style={{ animation: 'heroVFillIn 0.7s ease-out 2.3s both' }} />
          <polygon className="hero-v-fill" points="920,0 1080,0 580,880 420,880" fill="url(#heroVRight)"
            style={{ animation: 'heroVFillIn 0.7s ease-out 2.3s both' }} />

          {/* ── Couche 2 : glow flou — bord extérieur réel ── */}
          <path
            d="M -80,0 L 420,880 L 580,880 L 1080,0"
            fill="none"
            stroke="url(#heroVStrokeGlow)"
            strokeWidth="24"
            strokeLinejoin="round"
            filter="url(#heroVBlur)"
            style={{
              strokeDasharray: 2200,
              strokeDashoffset: 2200,
              animation: 'heroVDraw 1.3s cubic-bezier(.4,.1,.2,1) 1.2s forwards',
            }}
          />

          {/* ── Couche 3 : trait net — bord extérieur réel ── */}
          <path
            d="M -80,0 L 420,880 L 580,880 L 1080,0"
            fill="none"
            stroke="url(#heroVStroke)"
            strokeWidth="2"
            strokeLinejoin="round"
            strokeLinecap="round"
            style={{
              strokeDasharray: 2200,
              strokeDashoffset: 2200,
              animation: 'heroVDraw 1.3s cubic-bezier(.4,.1,.2,1) 1.2s forwards',
            }}
          />
        </svg>
      )}
      {variant === 'orb' && <HeroOrb />}
      {variant === 'dashboard' && <HeroDashboard />}
      {variant === 'notifs' && <HeroNotifs />}
    </section>
  );
}

/* ———————————————— Variant A : ORB ———————————————— */

// Vidéo de démo du hero
const HERO_VIDEO_SRC = '/lp/uploads/V1.mp4';
const HERO_VIDEO_POSTER = '/lp/uploads/pasted-1776522216734-0.png';

function HeroOrb() {
  useEffect(() => {
    const applyMask = () => {
      const section  = document.getElementById('hero');
      const vslWrap  = section?.querySelector('.hero-video-wrap');
      const svg      = section?.querySelector('.hero-v-svg');
      if (!section || !vslWrap || !svg) return;

      const sH = section.offsetHeight;

      // offsetTop traverse la chaîne — stable, indépendant du scroll
      let el = vslWrap;
      let offsetFromSection = 0;
      while (el && el !== section) {
        offsetFromSection += el.offsetTop;
        el = el.offsetParent;
      }
      const vBottom = offsetFromSection + vslWrap.offsetHeight;

      // clip-path inset coupe le rendu final incluant les filtres flou
      // inset(top right bottom left) — on coupe depuis le bas
      const clipFromBottom = Math.max(0, 100 - ((vBottom / sH) * 100));
      svg.style.clipPath = `inset(0 0 ${clipFromBottom.toFixed(2)}% 0)`;
    };

    // Premières passes pour layout stable
    const t1 = setTimeout(applyMask, 80);
    const t2 = setTimeout(applyMask, 400);
    const t3 = setTimeout(applyMask, 1200); // après toutes les animations
    window.addEventListener('resize', applyMask, { passive: true });
    return () => {
      clearTimeout(t1);
      clearTimeout(t2);
      clearTimeout(t3);
      window.removeEventListener('resize', applyMask);
    };
  }, []);

  return (
    <div style={{ position: 'relative' }}>
      {/* Orb glow — apparition retardée après les autres éléments */}
      <div className="hero-orb-blob" style={{
        position: 'absolute',
        top: 80, left: '50%', transform: 'translateX(-50%)',
        width: 720, height: 720,
        pointerEvents: 'none',
        animation: 'heroOrbIn 1.2s ease-out 1.4s both',
      }}>
        <div style={{
          position: 'absolute', inset: 0,
          background: 'radial-gradient(circle at center, var(--accent) 0%, transparent 65%)',
          filter: 'blur(48px)',
          opacity: 0.55,
          animation: 'breathe 6s ease-in-out infinite',
        }} />
        <div style={{
          position: 'absolute', inset: '30%',
          background: 'radial-gradient(circle at center, oklch(0.90 0.18 155 / 1) 0%, transparent 70%)',
          filter: 'blur(14px)',
          animation: 'breathe 4s ease-in-out infinite',
        }} />
      </div>

      {/* Notifs flottantes, gauche / droite, hors du flux */}
      <FloatingNotifs />

      {/* Headline */}
      <div className="container hero-headline" style={{ position: 'relative', zIndex: 2, textAlign: 'center', marginTop: 'var(--hero-headline-mt, clamp(12px, 1.8vh, 24px))' }}>
        <h1 className="h1" style={{
          fontSize: 'clamp(30px, min(4.2vw, 7vh), 76px)',
          lineHeight: 1.1,
          textTransform: 'none',
          letterSpacing: '-0.025em',
        }}>
          <SplitText text="Le " delay={0} />
          <span className="mrr-badge">
            {/* SVG rect qui trace le contour au dessin */}
            <svg className="mrr-trace-svg" preserveAspectRatio="none" aria-hidden="true">
              <rect
                className="mrr-trace-rect"
                x="1" y="1"
                width="calc(100% - 2px)"
                height="calc(100% - 2px)"
                rx="8" ry="8"
                fill="none"
                stroke="var(--accent)"
                strokeWidth="2"
                pathLength="100"
              />
            </svg>
            <span className="mrr-badge-text">
              <SplitText text="MRR 2.0" delay={0.1} />
            </span>
          </span>
          <SplitText text=" est enfin là" delay={0.2} />
          <br />
          <span className="serif-i" style={{
            fontWeight: 400,
            letterSpacing: '-0.01em',
            fontSize: '1.05em',
            whiteSpace: 'pre',
          }}>
            <SplitText text="et tu peux en " delay={0.45} />
            <span style={{ color: 'var(--accent)' }}>
              <SplitText text="profiter" delay={0.6} />
            </span>
          </span>
        </h1>
        <BlurIn delay={0.75} direction="up" distance={10} blur={6} style={{ marginTop: 0, textAlign: 'center' }}>
          <span className="h1" style={{
            fontSize: 'clamp(30px, min(4.2vw, 7vh), 76px)',
            lineHeight: 1.1,
            textTransform: 'none',
            letterSpacing: '-0.025em',
            display: 'block',
          }}>dès maintenant.</span>
        </BlurIn>

        {/* CTAs agrandis */}
        <BlurIn delay={0.85} direction="up" distance={14} blur={10} style={{ display: 'flex', gap: 14, justifyContent: 'center', marginTop: 'clamp(10px, 1.8vh, 20px)', flexWrap: 'wrap' }}>
          <MagneticBtn variant="primary" className="btn-lg" href="#pricing">
            Rejoindre maintenant <span className="btn-arrow"><Icon.Arrow size={14} /></span>
          </MagneticBtn>
          <MagneticBtn variant="ghost" className="btn-lg" href="/app" style={{
            background: 'color-mix(in oklab, var(--bg-card) 30%, transparent)',
            backdropFilter: 'blur(20px) saturate(1.6) brightness(1.08)',
            WebkitBackdropFilter: 'blur(20px) saturate(1.6) brightness(1.08)',
            border: '1px solid color-mix(in oklab, #ffffff 18%, transparent)',
            boxShadow: 'inset 0 1px 0 color-mix(in oklab, #ffffff 20%, transparent), 0 8px 32px -8px rgba(0,0,0,0.35)',
            color: 'var(--ink)',
          }}>
            <Icon.User size={14} /> Accéder à la plateforme
          </MagneticBtn>
        </BlurIn>

        {/* Sentinel : dès qu'il sort de l'écran, le sticky CTA apparaît */}
        <div id="hero-cta-sentinel" style={{ height: 1, width: 1 }} aria-hidden="true" />
      </div>

      {/* Vidéo de démo autoplay */}
      <BlurIn delay={1.05} direction="up" distance={24} blur={14} duration={1.1}
        className="container hero-video-wrap"
        style={{ position: 'relative', zIndex: 2, marginTop: 'clamp(20px, 2.5vh, 40px)', width: '100%', maxWidth: 'min(clamp(560px, 50vw, 900px), 65vh)', paddingLeft: 'clamp(16px, 3vw, 48px)', paddingRight: 'clamp(16px, 3vw, 48px)' }}>
        <HeroVideo />
      </BlurIn>
    </div>
  );
}

/* ─── VslTitle : barre URL-style typewriter avec curseur clignotant ─── */
function VslTitle() {
  const FULL = 'vizionmrr.fr/bienvenue-dans-une-nouvelle-ere';
  const [text, setText] = useState('');
  const [done, setDone] = useState(false);

  useEffect(() => {
    let i = 0;
    let cancelled = false;
    // Petit délai avant de démarrer le typing (attends que la vidéo charge)
    const start = setTimeout(() => {
      const tick = () => {
        if (cancelled) return;
        if (i <= FULL.length) {
          setText(FULL.slice(0, i));
          i++;
          setTimeout(tick, 28 + Math.random() * 22);
        } else {
          setDone(true);
        }
      };
      tick();
    }, 600);
    return () => { cancelled = true; clearTimeout(start); };
  }, []);

  return (
    <div className="vsl-title-bar" style={{
      flex: 1,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      gap: 8,
    }}>
      {/* Cadenas + https */}
      <div style={{
        display: 'flex', alignItems: 'center', gap: 5,
      }}>
        <svg width="10" height="10" viewBox="0 0 16 16" fill="none" style={{ color: 'var(--accent)', flexShrink: 0 }}>
          <rect x="3" y="7" width="10" height="7" rx="1.5" fill="currentColor" opacity="0.8"/>
          <path d="M5 7V5C5 3.34 6.34 2 8 2C9.66 2 11 3.34 11 5V7" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" fill="none"/>
        </svg>
      </div>
      {/* URL text — police plus grande, plus lisible */}
      <div style={{
        fontFamily: "'Geist Mono', monospace",
        fontSize: 13,
        fontWeight: 500,
        color: done ? 'var(--ink)' : 'var(--ink-dim)',
        letterSpacing: '0.02em',
        display: 'flex', alignItems: 'center',
        transition: 'color 0.4s ease',
        whiteSpace: 'nowrap',
        overflow: 'hidden',
      }}>
        <span style={{ color: 'var(--ink-mute)' }}>https://</span>
        <span>{text}</span>
        {/* Curseur clignotant */}
        <span style={{
          display: 'inline-block',
          width: 2, height: 15,
          background: 'var(--accent)',
          marginLeft: 1,
          borderRadius: 1,
          animation: done ? 'vslCursorBlink 1s step-end infinite' : 'none',
          opacity: done ? undefined : 1,
          flexShrink: 0,
        }} />
      </div>
    </div>
  );
}

function HeroVideo() {
  const { landing } = useLandingStats();
  const videoSrc = landing?.videoUrl || HERO_VIDEO_SRC; // fallback local en dev si rien dans la DB
  const videoRef = useRef(null);
  const rootRef = useRef(null);
  const [loaded, setLoaded] = useState(false);
  const [scrollScale, setScrollScale] = useState(1);
  const [muted, setMuted] = useState(true);

  // Au clic sur l'overlay : unmute + redémarre depuis le début pour que le viewer entende tout
  const handleUnmute = () => {
    const v = videoRef.current;
    if (!v) return;
    v.muted = false;
    v.volume = 1;
    v.currentTime = 0;
    v.play().catch(() => {});
    setMuted(false);
  };

  // Si aucune URL vidéo n'est configurée ni en dev ni en prod, ne rien rendre
  if (!videoSrc) return null;

  useEffect(() => {
    const v = videoRef.current;
    if (!v) return;
    // Démarrage auto garanti (muted + playsinline)
    const tryPlay = () => { v.play().catch(() => {}); };
    tryPlay();
    v.addEventListener('loadeddata', () => setLoaded(true));
    return () => v.removeEventListener('loadeddata', () => setLoaded(true));
  }, []);

  // Parallax subtil : le cadre VSL s'agrandit légèrement au scroll
  useEffect(() => {
    const onScroll = () => {
      const el = rootRef.current;
      if (!el) return;
      const rect = el.getBoundingClientRect();
      const vh = window.innerHeight;
      // Progression : 0 quand la vidéo est sous l'écran, ~1 quand elle est au-dessus
      const raw = (vh - rect.top) / (vh + rect.height);
      const p = Math.max(0, Math.min(1, raw));
      // Scale de 1 → 1.04 — léger mais perceptible
      setScrollScale(1 + p * 0.04);
    };
    onScroll();
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);

  return (
    <div ref={rootRef} className="beam-border" style={{
      position: 'relative',
      borderRadius: 28,
      border: '1px solid var(--line)',
      background: 'var(--bg-card)',
      padding: 6,
      boxShadow: '0 20px 50px -24px rgba(0,0,0,0.5)',
      overflow: 'hidden',
      transform: `scale(${scrollScale})`,
      transformOrigin: 'center top',
      transition: 'transform 0.12s linear',
      willChange: 'transform',
    }}>
      {/* Browser chrome façon macOS — caché sur mobile via CSS */}
      <div className="vsl-chrome" style={{
        display: 'flex', alignItems: 'center', gap: 8,
        padding: '10px 14px',
      }}>
        <div className="mac-dots">
          <button className="mac-dot mac-dot--close" aria-label="Fermer">
            <svg width="6" height="6" viewBox="0 0 6 6" fill="none"><path d="M1 1L5 5M5 1L1 5" stroke="rgba(0,0,0,0.55)" strokeWidth="1" strokeLinecap="round"/></svg>
          </button>
          <button className="mac-dot mac-dot--minimize" aria-label="Réduire">
            <svg width="6" height="6" viewBox="0 0 6 6" fill="none"><path d="M1 3H5" stroke="rgba(0,0,0,0.55)" strokeWidth="1" strokeLinecap="round"/></svg>
          </button>
          <button className="mac-dot mac-dot--maximize" aria-label="Agrandir">
            <svg width="6" height="6" viewBox="0 0 6 6" fill="none"><path d="M1 3H5M3 1V5" stroke="rgba(0,0,0,0.55)" strokeWidth="1" strokeLinecap="round"/></svg>
          </button>
        </div>
        <div style={{ flex: 1 }} />
        <div style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: 10, color: 'var(--accent)' }} className="mono">
          <span style={{ width: 6, height: 6, borderRadius: '50%', background: 'var(--accent)', animation: 'breathe 1.6s infinite' }} />
          LIVE
        </div>
      </div>

      {/* Conteneur vidéo 16/10 avec bords intérieurs arrondis */}
      <div style={{
        position: 'relative',
        aspectRatio: '16 / 10',
        borderRadius: 20,
        overflow: 'hidden',
        background: 'var(--bg)',
      }}>
        <video
          ref={videoRef}
          src={videoSrc}
          poster={HERO_VIDEO_POSTER}
          autoPlay
          muted
          loop
          playsInline
          preload="metadata"
          style={{
            position: 'absolute',
            inset: 0,
            width: '100%',
            height: '100%',
            objectFit: 'cover',
            opacity: loaded ? 1 : 0,
            transition: 'opacity 0.6s ease',
          }}
        />
        {/* Overlay vignette pour fondre avec le fond */}
        <div style={{
          position: 'absolute', inset: 0, pointerEvents: 'none',
          background: 'radial-gradient(ellipse at center, transparent 55%, color-mix(in oklab, var(--bg) 30%, transparent) 100%)',
        }} />

        {/* Overlay "Activer le son" — visible tant que la vidéo est mute */}
        {muted && loaded && (
          <button
            onClick={handleUnmute}
            data-cursor="hover"
            aria-label="Activer le son"
            style={{
              position: 'absolute', inset: 0,
              display: 'flex', flexDirection: 'column',
              alignItems: 'center', justifyContent: 'center',
              gap: 16,
              background: 'color-mix(in oklab, #000 35%, transparent)',
              backdropFilter: 'blur(1.5px)',
              WebkitBackdropFilter: 'blur(1.5px)',
              border: 'none',
              cursor: 'pointer',
              color: '#fff',
              transition: 'background 0.25s ease',
              zIndex: 3,
            }}
            onMouseEnter={(e) => { e.currentTarget.style.background = 'color-mix(in oklab, #000 20%, transparent)'; }}
            onMouseLeave={(e) => { e.currentTarget.style.background = 'color-mix(in oklab, #000 35%, transparent)'; }}
          >
            <div style={{
              width: 84, height: 84, borderRadius: '50%',
              background: 'var(--accent)',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              boxShadow: '0 0 0 10px color-mix(in oklab, var(--accent) 22%, transparent), 0 12px 40px -8px var(--accent-glow)',
              animation: 'breathe 2.4s ease-in-out infinite',
            }}>
              {/* Speaker icon inline */}
              <svg width="34" height="34" viewBox="0 0 24 24" fill="none" style={{ color: 'var(--bg)' }}>
                <path d="M11 5L6 9H3v6h3l5 4V5z" fill="currentColor" stroke="currentColor" strokeWidth="1.5" strokeLinejoin="round" />
                <path d="M15.5 8.5a4 4 0 010 7M18 6a7 7 0 010 12" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" fill="none" />
              </svg>
            </div>
            <div style={{ textAlign: 'center' }}>
              <div style={{
                fontSize: 16, fontWeight: 700,
                fontFamily: 'Geist, sans-serif',
                letterSpacing: '-0.01em',
                marginBottom: 4,
              }}>
                Activer le son
              </div>
              <div className="mono" style={{
                fontSize: 10, color: 'rgba(255,255,255,0.7)',
                letterSpacing: '0.12em', textTransform: 'uppercase',
              }}>
                Clique pour regarder avec le son
              </div>
            </div>
          </button>
        )}
      </div>
    </div>
  );
}

function FloatingNotifs() {
  const leftRef  = useRef(null);
  const rightRef = useRef(null);
  const [winW, setWinW] = useState(typeof window !== 'undefined' ? window.innerWidth : 1440);

  useEffect(() => {
    const onResize = () => setWinW(window.innerWidth);
    window.addEventListener('resize', onResize, { passive: true });
    return () => window.removeEventListener('resize', onResize);
  }, []);

  useEffect(() => {
    const update = () => {
      const hero = document.getElementById('hero');
      if (!hero || !leftRef.current || !rightRef.current) return;

      // Révélation complète après 130% de la hauteur du hero (scroll ultra lent)
      const trigger = hero.offsetHeight * 1.30;
      const raw  = Math.min(1, Math.max(0, window.scrollY / trigger));
      // Ease-out quart — très smooth, démarre doucement
      const ease = 1 - Math.pow(1 - raw, 4);

      const w    = window.innerWidth;
      const dx   = Math.min(520, Math.max(220, Math.floor(w / 2) - 240));
      const hideX = dx + 40; // pousse les notifs derrière la VSL, moins de dispersion
      const offset  = hideX * (1 - ease);
      const opacity = Math.min(1, ease * 1.2);

      leftRef.current.style.transform  = `translateX(calc(-100% + ${offset}px))`;
      leftRef.current.style.opacity    = opacity;
      rightRef.current.style.transform = `translateX(${-offset}px)`;
      rightRef.current.style.opacity   = opacity;
    };

    window.addEventListener('scroll', update, { passive: true });
    update();
    return () => window.removeEventListener('scroll', update);
  }, []);

  if (winW < 640) return null;

  const dx = Math.min(520, Math.max(220, Math.floor(winW / 2) - 240));

  const cards = [
    { ref: leftRef,  side: 'left',  rot: -5, bobDelay: 0   },
    { ref: rightRef, side: 'right', rot: 4,  bobDelay: 0.5 },
  ];

  return (
    <>
      {cards.map((p, i) => (
        <div key={i} ref={p.ref} style={{
          position: 'absolute',
          /* Milieu de la VSL — après le titre + CTAs + moitié de la vidéo */
          top: 'clamp(400px, 50vh, 600px)',
          ...(p.side === 'left'
            ? { left: `calc(50% - ${dx}px)` }
            : { left: `calc(50% + ${dx}px)` }),
          zIndex: 1,          /* derrière la VSL (zIndex:2) */
          pointerEvents: 'none',
          opacity: 0,         /* caché au départ */
          willChange: 'transform, opacity',
        }}>
          <div style={{ animation: `floatBob 7s ease-in-out ${p.bobDelay}s infinite` }}>
            <NotifCard notif={NOTIF_SAMPLES[i % NOTIF_SAMPLES.length]} rot={p.rot} />
          </div>
        </div>
      ))}
      <style>{`
        @keyframes floatBob {
          0%, 100% { transform: translateY(0px); }
          50%       { transform: translateY(-12px); }
        }
      `}</style>
    </>
  );
}

function NotifCard({ notif, rot = 0, small = false }) {
  const n = notif || NOTIF_SAMPLES[0];
  
  if (small) {
    // Version mobile : compacte carrée
    return (
      <div style={{
        padding: '9px 11px 10px',
        borderRadius: 12,
        background: 'color-mix(in oklab, var(--bg-card) 92%, transparent)',
        backdropFilter: 'blur(16px) saturate(1.2)',
        WebkitBackdropFilter: 'blur(16px) saturate(1.2)',
        border: '1px solid color-mix(in oklab, var(--line) 100%, transparent)',
        boxShadow: '0 10px 28px -8px rgba(0,0,0,0.45)',
        transform: `rotate(${rot}deg)`,
        width: 155,
        fontFamily: "'Geist', system-ui, sans-serif",
      }}>
        {/* Header compact */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 5 }}>
          <BrandIcon src={n.src} color={n.color} size={15} />
          <span style={{ fontSize: 9, fontWeight: 500, color: 'var(--ink-dim)', textTransform: 'uppercase', letterSpacing: '0.01em', flex: 1 }}>{n.src}</span>
          <span style={{ color: 'var(--ink-mute)', fontSize: 8.5 }}>{n.time}</span>
        </div>
        {/* Montant en évidence */}
        <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between' }}>
          <span style={{ fontSize: 10, color: 'var(--ink-dim)' }}>{n.customer}</span>
          <span style={{ fontFamily: "'Geist Mono', monospace", fontSize: 13, fontWeight: 700, color: 'var(--accent)', letterSpacing: '-0.02em' }}>+{n.amount}</span>
        </div>
      </div>
    );
  }
  
  return (
    <div style={{
      padding: '14px 16px 15px',
      borderRadius: 18,
      background: 'var(--bg-card)',
      border: '1px solid var(--line-strong)',
      boxShadow: '0 1px 0 0 rgba(255,255,255,0.04) inset, 0 16px 40px -12px rgba(0,0,0,0.55), 0 0 0 0.5px rgba(255,255,255,0.02)',
      transform: `rotate(${rot}deg)`,
      width: 250,
      fontSize: 12,
      fontFamily: "'Geist', system-ui, sans-serif",
    }}>
      {/* Header type notif système : icône app + nom app + time */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 9, marginBottom: 8 }}>
        <BrandIcon src={n.src} color={n.color} />
        <span style={{
          fontSize: 11,
          fontWeight: 500,
          color: 'var(--ink-dim)',
          letterSpacing: '0.01em',
          textTransform: 'uppercase',
          flex: 1,
        }}>{n.src}</span>
        <span style={{ color: 'var(--ink-mute)', fontSize: 10.5, fontWeight: 400 }}>{n.time}</span>
      </div>

      {/* Titre de la notif */}
      <div style={{
        fontSize: 13.5,
        fontWeight: 600,
        color: 'var(--ink)',
        lineHeight: 1.25,
        marginBottom: 3,
        letterSpacing: '-0.01em',
      }}>
        Paiement reçu
      </div>

      {/* Ligne de détail : client / contexte */}
      <div style={{
        fontSize: 12,
        color: 'var(--ink-dim)',
        lineHeight: 1.35,
        marginBottom: 10,
      }}>
        {n.customer} {n.country ? `· ${n.country}` : ''} <span style={{ color: 'var(--ink-mute)' }}>· {n.label}</span>
      </div>

      {/* Montant en bas, en vert, façon reçu */}
      <div style={{
        display: 'flex', alignItems: 'baseline', justifyContent: 'space-between',
        paddingTop: 8,
        borderTop: '1px solid color-mix(in oklab, var(--line) 80%, transparent)',
      }}>
        <span style={{
          fontFamily: "'Geist Mono', monospace",
          fontSize: 10,
          color: 'var(--ink-mute)',
          letterSpacing: '0.04em',
        }}>
          + CRÉDITÉ
        </span>
        <span style={{
          fontFamily: "'Instrument Serif', serif",
          fontSize: 22,
          lineHeight: 1,
          color: 'var(--accent)',
          letterSpacing: '-0.01em',
          fontWeight: 400,
        }}>
          +{n.amount}
        </span>
      </div>
    </div>
  );
}

/* Mini-icône de marque — style notif système (square rounded) */
function BrandIcon({ src, color, size = 22 }) {
  const common = {
    width: size, height: size, borderRadius: size > 16 ? 6 : 4,
    display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
    color: '#fff', fontWeight: 800,
    fontFamily: "'Geist', system-ui, sans-serif",
    letterSpacing: '-0.02em',
    flexShrink: 0,
    boxShadow: 'inset 0 0.5px 0 rgba(255,255,255,0.18), inset 0 -0.5px 0 rgba(0,0,0,0.15)',
  };
  const fontSize = size > 16 ? 13 : 9;
  if (src === 'Stripe') {
    return <span style={{ ...common, background: '#635bff', fontSize }}>S</span>;
  }
  if (src === 'PayPal') {
    return <span style={{ ...common, background: '#003087', fontSize }}>
      <span style={{ color: '#009cde', marginRight: -2 }}>P</span>
      <span>P</span>
    </span>;
  }
  if (src === 'Revolut') {
    return <span style={{ ...common, background: '#0a0a0b', fontSize, fontFamily: "'Instrument Serif', serif", fontWeight: 400 }}>R</span>;
  }
  if (src === 'Wise') {
    return <span style={{ ...common, background: '#9fe870', color: '#0a0a0b', fontSize: size > 16 ? 12 : 9 }}>w</span>;
  }
  return <span style={{ ...common, background: color || '#333', fontSize }}>{src[0]}</span>;
}

/* Inline mini dashboard teaser */
function HeroMiniDashboard() {
  return (
    <div style={{
      borderRadius: 28,
      border: '1px solid var(--line)',
      background: 'var(--bg-card)',
      padding: 6,
      boxShadow: 'var(--shadow)',
      position: 'relative',
    }}>
      <div style={{
        display: 'flex', alignItems: 'center', gap: 8,
        padding: '10px 14px', borderBottom: '1px solid var(--line)',
      }}>
        <div style={{ display: 'flex', gap: 5 }}>
          {[0,1,2].map(i => <div key={i} style={{ width: 10, height: 10, borderRadius: '50%', background: 'var(--line-strong)' }} />)}
        </div>
        <div className="mono" style={{ flex: 1, textAlign: 'center', fontSize: 11, color: 'var(--ink-mute)' }}>
          vizionmrr.fr / dashboard
        </div>
      </div>
      <div style={{ padding: 24, display: 'grid', gridTemplateColumns: '1fr 1.6fr 1fr', gap: 20 }}>
        <StatCard label="MRR ce mois" value="87 340,00 €" delta="+38,2%" accent />
        <ChartCard />
        <div style={{ display: 'grid', gap: 12 }}>
          <StatCard label="Filleuls" value="156" delta="+12" />
          <StatCard label="Commissions" value="9 870,00 €" delta="+24%" />
        </div>
      </div>
    </div>
  );
}

function StatCard({ label, value, delta, accent }) {
  return (
    <div style={{
      padding: 18, borderRadius: 16,
      background: 'var(--bg-elev)',
      border: '1px solid var(--line)',
      position: 'relative', overflow: 'hidden',
    }}>
      <div className="label" style={{ fontSize: 10, marginBottom: 10 }}>{label}</div>
      <div style={{
        fontFamily: 'Instrument Serif, serif',
        fontSize: 28, lineHeight: 1, letterSpacing: '-0.02em',
        color: accent ? 'var(--accent)' : 'var(--ink)',
        marginBottom: 8,
      }}>{value}</div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
        <span className="mono" style={{ fontSize: 11, color: 'var(--accent)' }}>{delta}</span>
        <span className="mono" style={{ fontSize: 11, color: 'var(--ink-mute)' }}>vs 30j</span>
      </div>
    </div>
  );
}

function ChartCard() {
  // smooth sinusoidal growing line
  const pts = Array.from({ length: 40 }, (_, i) => {
    const x = i / 39;
    const y = 0.85 - (0.65 * x) - Math.sin(x * Math.PI * 3) * 0.06 - Math.random() * 0.02;
    return [x * 100, y * 100];
  });
  const d = pts.map((p, i) => `${i === 0 ? 'M' : 'L'}${p[0].toFixed(2)},${p[1].toFixed(2)}`).join(' ');
  const area = `${d} L100,100 L0,100 Z`;
  return (
    <div style={{
      padding: 18, borderRadius: 16,
      background: 'var(--bg-elev)',
      border: '1px solid var(--line)',
      position: 'relative', minHeight: 130,
    }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 8 }}>
        <div className="label" style={{ fontSize: 10 }}>Commissions (90j)</div>
        <div className="mono" style={{ fontSize: 11, color: 'var(--accent)' }}>+38,2%</div>
      </div>
      <div style={{
        fontFamily: 'Instrument Serif, serif',
        fontSize: 26, lineHeight: 1,
        marginBottom: 10,
      }}>2 695 €</div>
      <svg viewBox="0 0 100 100" preserveAspectRatio="none" style={{ width: '100%', height: 60 }}>
        <defs>
          <linearGradient id="gradArea" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor="var(--accent)" stopOpacity="0.5" />
            <stop offset="100%" stopColor="var(--accent)" stopOpacity="0" />
          </linearGradient>
        </defs>
        <path d={area} fill="url(#gradArea)" />
        <path d={d} fill="none" stroke="var(--accent)" strokeWidth="1.2" vectorEffect="non-scaling-stroke" />
        <circle cx={pts[pts.length-1][0]} cy={pts[pts.length-1][1]} r="1.4" fill="var(--accent)" />
      </svg>
    </div>
  );
}

/* ———————————————— Variant B : DASHBOARD ———————————————— */

function HeroDashboard() {
  const { stats } = useLandingStats();
  const fmtMembres = stats.membres > 0 ? `${stats.membres}+` : '…';
  const fmtRevenus = stats.revenus > 0
    ? new Intl.NumberFormat('fr-FR').format(stats.revenus) + ' €'
    : '…';
  return (
    <div className="container" style={{ display: 'grid', gridTemplateColumns: '1fr 1.1fr', gap: 64, alignItems: 'center', paddingTop: 80 }}>
      <div>
        <div className="chip" style={{ marginBottom: 32 }}>
          <span style={{ width: 6, height: 6, borderRadius: '50%', background: 'var(--accent)', boxShadow: '0 0 10px var(--accent-glow)' }}></span>
          Plateforme active · 2 400 inscrits
        </div>
        <h1 className="h1" style={{ fontSize: 'clamp(56px, 6.5vw, 96px)' }}>
          <SplitText text="Un business" />
          <br />
          <span className="serif-i" style={{ color: 'var(--accent)' }}><SplitText text="qui tourne" delay={0.2} /></span>
          <br />
          <SplitText text="même quand tu dors." delay={0.4} />
        </h1>
        <p style={{ marginTop: 32, fontSize: 18, color: 'var(--ink-dim)', maxWidth: 480 }}>
          Formation, outils IA, page de vente, communauté, commissions.
          Tout réuni dans VIZION — paiement unique, accès à vie.
        </p>
        <div style={{ display: 'flex', gap: 12, marginTop: 40 }}>
          <MagneticBtn variant="primary" href="#pricing">Rejoindre <span className="btn-arrow"><Icon.Arrow /></span></MagneticBtn>
          <MagneticBtn variant="ghost"><Icon.Play size={10} /> Voir la démo</MagneticBtn>
        </div>
        <div style={{ marginTop: 48, display: 'flex', gap: 40 }}>
          <Stat n={fmtMembres} l="membres actifs" />
          <Stat n={fmtRevenus} l="revenus générés" />
          <Stat n="75%" l="commissions max" />
        </div>
      </div>
      <div style={{ position: 'relative' }}>
        <div style={{
          position: 'absolute', inset: '-10% -5%',
          background: 'radial-gradient(ellipse at center, var(--accent-glow) 0%, transparent 60%)',
          filter: 'blur(60px)',
        }} />
        <HeroMiniDashboard />
      </div>
    </div>
  );
}

function Stat({ n, l }) {
  return (
    <div>
      <div className="serif" style={{ fontSize: 40, lineHeight: 1 }}>{n}</div>
      <div className="label" style={{ marginTop: 6 }}>{l}</div>
    </div>
  );
}

/* ———————————————— Variant C : NOTIFS ———————————————— */

function HeroNotifs() {
  return (
    <div className="container" style={{ paddingTop: 100, position: 'relative' }}>
      <div style={{
        position: 'absolute', top: '20%', left: '50%', transform: 'translateX(-50%)',
        width: 800, height: 400,
        background: 'radial-gradient(ellipse at center, var(--accent-glow) 0%, transparent 60%)',
        filter: 'blur(80px)',
        pointerEvents: 'none',
      }} />
      <div style={{ textAlign: 'center', position: 'relative' }}>
        <div className="chip" style={{ marginBottom: 40 }}>
          <span style={{ width: 6, height: 6, borderRadius: '50%', background: 'var(--accent)', boxShadow: '0 0 10px var(--accent-glow)' }}></span>
          Plateforme active
        </div>
        <h1 className="h1" style={{ fontSize: 'clamp(68px, 10vw, 160px)' }}>
          <SplitText text="Des revenus" />
          <br />
          <span className="serif-i" style={{ color: 'var(--accent)' }}>qui rentrent.</span>
          <br />
          <SplitText text="Sans l'usine." delay={0.4} />
        </h1>
        <p style={{ maxWidth: 560, margin: '36px auto 0', fontSize: 18, color: 'var(--ink-dim)' }}>
          Un système clé en main pour vendre tes produits digitaux : formation,
          outils IA, page de vente, communauté, commissions.
        </p>
        <div style={{ display: 'flex', gap: 12, justifyContent: 'center', marginTop: 40 }}>
          <MagneticBtn variant="primary" href="#pricing">Accéder <span className="btn-arrow"><Icon.Arrow /></span></MagneticBtn>
          <MagneticBtn variant="ghost"><Icon.Play size={10} /> Démo</MagneticBtn>
        </div>
      </div>
      <div style={{
        display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 16,
        marginTop: 80, maxWidth: 900, marginLeft: 'auto', marginRight: 'auto',
      }}>
        {NOTIF_SAMPLES.slice(0, 6).map((n, i) => (
          <div key={i} style={{
            animation: `floatBob 6s ease-in-out ${i * 0.3}s infinite`,
            transform: `rotate(${(i % 2 ? 1 : -1) * (2 + i)}deg)`,
          }}>
            <NotifCard notif={n} rot={0} />
          </div>
        ))}
      </div>
    </div>
  );
}

Object.assign(window, { Hero, NotifCard, HeroMiniDashboard, StatCard, ChartCard });
