// Illusions — components.jsx
// Cinematic prototype components for the Illusions Lounge future site.

const { useState, useEffect, useRef, useCallback } = React;

/* ============== Brand mark ============== */
function BrandMark({ size = 'sm' }) {
  const top = size === 'lg' ? 28 : 22;
  const bot = size === 'lg' ? 11 : 9;
  return (
    <span className="brand-mark" aria-label="Illusions Lounge">
      <span className="top" style={{ fontSize: top }}>ILLUSIONS</span>
      <span className="bot" style={{ fontSize: bot }}>LOUNGE</span>
    </span>
  );
}

function GlyphIII({ size = 36 }) {
  return (
    <span className="glyph-iii" style={{ height: size }} aria-hidden="true">
      <i></i><i></i><i></i>
    </span>
  );
}

/* ============== ENVIRONMENTAL AUDIO ============== */
const ILLUSIONS_AUDIO_TRACKS = [
  { title: 'HOME', src: 'assets/illusions-home-005.mp3' },
];

const IllusionsAudio = (() => {
  let audio = null;
  let audioContext = null;
  let index = 0;
  let volume = 0.46;
  let outputVolume = 0.46;
  let playing = false;
  let fadeFrame = null;
  const listeners = new Set();

  const ensureAudio = () => {
    if (audio) return audio;
    audio = new Audio(ILLUSIONS_AUDIO_TRACKS[index].src);
    audio.loop = true;
    audio.preload = 'auto';
    audio.volume = outputVolume;
    audio.crossOrigin = 'anonymous';
    console.log('[Audio] Created audio element', {
      src: ILLUSIONS_AUDIO_TRACKS[index].src,
      volume: audio.volume,
      readyState: audio.readyState,
      networkState: audio.networkState,
    });
    audio.addEventListener('play', () => {
      console.log('[Audio] Play event fired');
      playing = true;
      emit();
    });
    audio.addEventListener('pause', () => {
      console.log('[Audio] Pause event fired');
      playing = false;
      emit();
    });
    audio.addEventListener('volumechange', () => {
      outputVolume = audio.volume;
      emit();
    });
    audio.addEventListener('error', (e) => {
      console.error('[Audio] Error event:', {
        code: audio.error?.code,
        message: audio.error?.message,
        networkState: audio.networkState,
        readyState: audio.readyState,
      });
    });
    audio.addEventListener('canplay', () => {
      console.log('[Audio] Can play event');
    });
    return audio;
  };

  const resumeContext = () => {
    const AudioContextClass = window.AudioContext || window.webkitAudioContext;
    if (!AudioContextClass) return null;
    if (!audioContext) audioContext = new AudioContextClass();
    if (audioContext.state === 'suspended') {
      audioContext.resume().catch(err => console.log('[Audio] Failed to resume context:', err));
    }
    return audioContext;
  };

  const getState = () => ({
    playing,
    volume: outputVolume,
    index,
    track: ILLUSIONS_AUDIO_TRACKS[index],
    trackCount: ILLUSIONS_AUDIO_TRACKS.length,
  });

  const emit = () => listeners.forEach((listener) => listener(getState()));

  const clearFade = () => {
    if (!fadeFrame) return;
    cancelAnimationFrame(fadeFrame);
    fadeFrame = null;
  };

  const fadeTo = (targetVolume, duration = 5200) => {
    const a = ensureAudio();
    clearFade();

    const target = Math.max(0, Math.min(1, targetVolume));
    const start = a.volume;
    const startedAt = performance.now();

    const step = (now) => {
      const progress = Math.min(1, (now - startedAt) / duration);
      const eased = 1 - Math.pow(1 - progress, 3);
      a.volume = start + ((target - start) * eased);
      if (progress < 1) {
        fadeFrame = requestAnimationFrame(step);
      } else {
        fadeFrame = null;
      }
    };

    fadeFrame = requestAnimationFrame(step);
  };

  const play = () => {
    resumeContext();
    const a = ensureAudio();
    const promise = a.play();
    if (promise && typeof promise.catch === 'function') {
      promise.catch(() => {
        playing = false;
        emit();
      });
    }
    return promise;
  };

  const startFromGesture = () => {
    console.log('[Audio] startFromGesture called');
    const ctx = resumeContext();
    const a = ensureAudio();
    clearFade();
    outputVolume = 0;
    a.volume = 0;

    console.log('[Audio] About to play', {
      contextState: ctx?.state,
      audioReadyState: a.readyState,
      audioNetworkState: a.networkState,
    });

    const playAudio = () => {
      console.log('[Audio] Playing...');
      const promise = a.play();
      if (promise && typeof promise.catch === 'function') {
        promise
          .then(() => {
            console.log('[Audio] Play promise resolved, fading in');
            fadeTo(volume, 8200);
          })
          .catch(err => {
            console.error('[Audio] Play promise rejected:', {
              name: err.name,
              message: err.message,
              code: err.code,
            });
            playing = false;
            emit();
          });
      } else {
        console.log('[Audio] No promise returned, fading in directly');
        fadeTo(volume, 8200);
      }
      return promise;
    };

    // On mobile, context might still be suspended, so wait a bit then play
    if (ctx && ctx.state === 'suspended') {
      console.log('[Audio] AudioContext suspended, waiting 100ms');
      setTimeout(playAudio, 100);
    } else {
      return playAudio();
    }
  };

  const pause = () => {
    if (!audio) return;
    clearFade();
    audio.pause();
  };

  const toggle = () => playing ? pause() : play();

  const next = () => {
    const wasPlaying = playing;
    index = (index + 1) % ILLUSIONS_AUDIO_TRACKS.length;
    const a = ensureAudio();
    a.src = ILLUSIONS_AUDIO_TRACKS[index].src;
    a.currentTime = 0;
    a.volume = outputVolume;
    emit();
    if (wasPlaying) play();
  };

  const setVolume = (value) => {
    volume = Math.max(0, Math.min(1, value));
    clearFade();
    outputVolume = volume;
    ensureAudio().volume = volume;
    emit();
  };

  const subscribe = (listener) => {
    listeners.add(listener);
    listener(getState());
    return () => listeners.delete(listener);
  };

  return { play, startFromGesture, pause, toggle, next, setVolume, subscribe, getState };
})();

/* ============== CINEMATIC INTRO ============== */
function CinematicIntro({ onComplete }) {
  const SCROLL_LOCK_CLASS = 'intro-scroll-locked';
  const [phase, setPhase] = useState('entry'); // entry | starting | playing | exiting
  const [done, setDone] = useState(false);
  const videoRef = useRef(null);
  const timers = useRef([]);
  const exiting = useRef(false);
  const previousScrollStyles = useRef(null);

  // Expose scroll state debug helper to window
  useEffect(() => {
    window.__checkScrollState = () => {
      const html = document.documentElement;
      const body = document.body;
      console.log('[Scroll Debug]', {
        htmlClass: html.className,
        bodyClass: body.className,
        htmlHasLockClass: html.classList.contains(SCROLL_LOCK_CLASS),
        bodyHasLockClass: body.classList.contains(SCROLL_LOCK_CLASS),
        htmlStyleOverflow: html.style.overflow,
        bodyStyleOverflow: body.style.overflow,
        htmlComputedOverflow: window.getComputedStyle(html).overflow,
        bodyComputedOverflow: window.getComputedStyle(body).overflow,
        documentHeight: document.documentElement.scrollHeight,
        windowHeight: window.innerHeight,
        scrollTop: window.scrollY,
        isScrollable: document.documentElement.scrollHeight > window.innerHeight,
      });
    };
  }, []);

  const clearTimers = useCallback(() => {
    timers.current.forEach(clearTimeout);
    timers.current = [];
  }, []);

  const restoreScroll = useCallback(() => {
    const html = document.documentElement;
    const body = document.body;

    const stackTrace = new Error().stack;
    console.log('[CinematicIntro] Restoring scroll...', {
      beforeClass: html.className,
      beforeOverflow: html.style.overflow,
      hasLockClass: html.classList.contains(SCROLL_LOCK_CLASS),
      stackTrace: stackTrace.split('\n').slice(0, 4).join('\n'),
    });

    html.classList.remove(SCROLL_LOCK_CLASS);
    body.classList.remove(SCROLL_LOCK_CLASS);

    console.log('[CinematicIntro] Classes removed', {
      hasLockClassAfter: html.classList.contains(SCROLL_LOCK_CLASS),
    });

    // Always clear inline styles regardless of previousScrollStyles
    html.style.overflow = '';
    html.style.overflowY = '';
    body.style.overflow = '';
    body.style.overflowY = '';
    body.style.touchAction = '';

    console.log('[CinematicIntro] Scroll restored.', {
      afterClass: html.className,
      afterOverflow: html.style.overflow,
      computedOverflow: window.getComputedStyle(html).overflow,
      computedBodyOverflow: window.getComputedStyle(body).overflow,
      scrollHeight: html.scrollHeight,
      clientHeight: html.clientHeight,
      isScrollable: html.scrollHeight > html.clientHeight,
    });
  }, []);

  const beginExit = useCallback(() => {
    if (exiting.current) return;
    console.log('[CinematicIntro] Beginning exit sequence...');
    exiting.current = true;
    setPhase('exiting');
    timers.current.push(setTimeout(() => {
      console.log('[CinematicIntro] Exit delay complete, restoring scroll and setting done.');
      restoreScroll();
      document.documentElement.setAttribute('data-arrival', 'complete');
      setDone(true);
      onComplete && onComplete();
    }, 1700));
  }, [onComplete, restoreScroll]);

  const attemptPlay = useCallback(() => {
    const video = videoRef.current;
    if (!video) return;

    video.muted = false;
    video.volume = 1;

    console.log('[CinematicIntro] Attempting video play');

    const playPromise = video.play();
    if (playPromise && typeof playPromise.catch === 'function') {
      playPromise
        .then(() => {
          console.log('[CinematicIntro] Video play succeeded, starting audio');
          setPhase('playing');
          // Video (with voiceover) is now playing. Start background audio with a delay.
          // This gives iOS time to handle the gesture and allows both to play.
          setTimeout(() => {
            console.log('[CinematicIntro] Starting background audio');
            IllusionsAudio.startFromGesture();
          }, 50);
        })
        .catch((err) => {
          console.error('[CinematicIntro] Video play failed:', err);
          setPhase('playing');
          timers.current.push(setTimeout(beginExit, 2200));
        });
    } else {
      setPhase('playing');
    }
  }, [beginExit]);

  useEffect(() => {
    const html = document.documentElement;
    const body = document.body;

    html.setAttribute('data-arrival', 'ritual');

    console.log('[CinematicIntro] Locking scroll...', {
      htmlOverflow: html.style.overflow,
      htmlOverflowY: html.style.overflowY,
      bodyOverflow: body.style.overflow,
      bodyOverflowY: body.style.overflowY,
    });

    previousScrollStyles.current = {
      htmlOverflow: html.style.overflow,
      htmlOverflowY: html.style.overflowY,
      bodyOverflow: body.style.overflow,
      bodyOverflowY: body.style.overflowY,
      bodyTouchAction: body.style.touchAction,
    };

    html.classList.add('intro-scroll-locked');
    body.classList.add('intro-scroll-locked');
    html.style.overflow = 'hidden';
    html.style.overflowY = 'hidden';
    body.style.overflow = 'hidden';
    body.style.overflowY = 'hidden';
    body.style.touchAction = 'none';

    return () => {
      console.log('[CinematicIntro] Cleanup unmounting...');
      clearTimers();
      restoreScroll();
      if (html.getAttribute('data-arrival') === 'ritual') {
        html.setAttribute('data-arrival', 'complete');
      }
    };
  }, []);

  useEffect(() => {
    if (done) {
      console.log('[CinematicIntro] Done effect triggered, restoring scroll.');
      restoreScroll();
    }
  }, [done, restoreScroll]);

  const enterNetwork = () => {
    if (phase !== 'entry') return;
    setPhase('starting');
    // Play video first (which includes voiceover). Audio will start after video succeeds.
    attemptPlay();
    timers.current.push(setTimeout(beginExit, 22000));
  };

  const handleTimeUpdate = (e) => {
    const video = e.currentTarget;
    if (!Number.isFinite(video.duration) || video.duration <= 0) return;
    if (video.duration - video.currentTime <= 1.35) beginExit();
  };

  if (done) return null;

  return (
    <div className={`cinematic-intro ${phase}`} aria-hidden={phase === 'entry' ? 'false' : 'true'} data-screen-label="Intro Arrival Ritual">
      <video
        ref={videoRef}
        className="cinematic-intro-video"
        playsInline
        preload="auto"
        poster="assets/lounge-atmosphere.png"
        onTimeUpdate={handleTimeUpdate}
        onEnded={beginExit}
      >
        <source src="assets/cinematic-intro.mp4" type="video/mp4" />
      </video>
      <div className="cinematic-intro-vignette"></div>
      <div className="cinematic-intro-bloom"></div>
      <div className="cinematic-intro-grain"></div>
      <div className="cinematic-entry">
        <h1>ILLUSIONS</h1>
        <button type="button" onClick={enterNetwork}>
          <span>Enter the Network</span>
        </button>
      </div>
    </div>
  );
}

function AudioControls({ visible }) {
  const [audioState, setAudioState] = useState(IllusionsAudio.getState());

  useEffect(() => IllusionsAudio.subscribe(setAudioState), []);

  return (
    <div className={`audio-orbit${visible ? ' visible' : ''}`} aria-label="Environmental audio controls">
      <button type="button" onClick={IllusionsAudio.toggle} aria-label={audioState.playing ? 'Pause soundtrack' : 'Play soundtrack'}>
        {audioState.playing ? 'Ⅱ' : '▶'}
      </button>
      <button type="button" onClick={IllusionsAudio.next} aria-label="Next soundtrack">
        ›
      </button>
      <label aria-label="Soundtrack volume">
        <span>{Math.round(audioState.volume * 100)}</span>
        <input
          type="range"
          min="0"
          max="1"
          step="0.01"
          value={audioState.volume}
          onChange={(e) => IllusionsAudio.setVolume(parseFloat(e.target.value))}
        />
      </label>
    </div>
  );
}

/* ============== ACCESS GATE ============== */
function AccessGate({ onComplete, skip }) {
  const [step, setStep] = useState('idle'); // idle | scanning | verified | enter
  const [hidden, setHidden] = useState(false);
  const timers = useRef([]);

  useEffect(() => {
    if (skip) {
      setHidden(true);
      onComplete && onComplete();
    }
  }, [skip]);

  const begin = () => {
    if (step !== 'idle') return;
    setStep('scanning');
    timers.current.push(setTimeout(() => setStep('verified'), 2400));
    timers.current.push(setTimeout(() => setStep('enter'), 4000));
    timers.current.push(setTimeout(() => {
      setHidden(true);
      onComplete && onComplete();
    }, 5400));
  };

  useEffect(() => () => timers.current.forEach(clearTimeout), []);

  // Replay handler — reset
  useEffect(() => {
    const handler = (e) => {
      if (e.detail && e.detail.replay) {
        timers.current.forEach(clearTimeout);
        timers.current = [];
        setStep('idle');
        setHidden(false);
      }
    };
    window.addEventListener('illusions:gate', handler);
    return () => window.removeEventListener('illusions:gate', handler);
  }, []);

  const headlineByStep = {
    idle:     { top: 'AWAITING IDENTITY', sub: 'HOLD TO VERIFY' },
    scanning: { top: 'SYNCHRONIZING',     sub: 'READING SIGNATURE' },
    verified: { top: 'IDENTITY VERIFIED', sub: 'CLEARANCE · LEVEL_02' },
    enter:    { top: 'WELCOME HOME',      sub: 'OPENING ENVIRONMENT' },
  }[step];

  return (
    <div className={"gate-overlay" + (hidden ? ' hide' : '')} data-screen-label="00 Access Gate">
      <div className="gate-bg"><img src="assets/lounge-atmosphere.png" alt="" /></div>
      <div className="gate-wash"></div>

      <div className="gate-tl">
        — RESTRICTED —<br />
        ILLUSIONS · NODE_17<br />
        SECURE CHANNEL
      </div>
      <div className="gate-tr">
        PRIVATE<br />
        EXCLUSIVE<br />
        INVITATION ONLY
      </div>
      <div className="gate-bl">
        EST. 2024<br />
        MEMBERSHIP NETWORK
      </div>
      <div className="gate-br">
        37.7892°N<br />
        075.1503°W<br />
        PHILADELPHIA
      </div>

      <div className="gate-content">
        <div className="eyebrow dash fade-in">— Identity Verification —</div>

        <div
          className={`scan-circle ${step}`}
          onClick={begin}
          role="button"
          tabIndex={0}
          onKeyDown={(e) => e.key === 'Enter' && begin()}
        >
          <span className="ring1"></span>
          <span className="ring2"></span>
          <span className="ring3"></span>
          <span className="core"></span>
          {step === 'scanning' && <span className="scan-bar"></span>}
        </div>

        <div style={{ display: 'flex', flexDirection: 'column', gap: 18, alignItems: 'center' }}>
          <h1 className="gate-h fade-in">
            {headlineByStep.top}
            <span className="ital">illusions lounge</span>
          </h1>
          <div className="gate-step-meta">{headlineByStep.sub}</div>
        </div>

        {step === 'idle' && (
          <button
            className="ghost-btn fade-in d2"
            onClick={begin}
            style={{ marginTop: -32 }}
          >
            Hold to Scan →
          </button>
        )}
      </div>
    </div>
  );
}

/* ============== NAV ============== */
function Nav() {
  const [scrolled, setScrolled] = useState(false);
  const [mobileMenuOpen, setMobileMenuOpen] = useState(false);

  useEffect(() => {
    const fn = () => setScrolled(window.scrollY > 40);
    window.addEventListener('scroll', fn);
    return () => window.removeEventListener('scroll', fn);
  }, []);

  const closeMenu = () => setMobileMenuOpen(false);

  useEffect(() => {
    const handleLinkClick = (e) => {
      if (e.target.tagName === 'A') closeMenu();
    };
    document.addEventListener('click', handleLinkClick);
    return () => document.removeEventListener('click', handleLinkClick);
  }, []);

  return (
    <>
      <nav className={"nav" + (scrolled ? ' scrolled' : '')} data-screen-label="Nav">
        <BrandMark />
        <div className="nav-links">
          <a href="#tonight">Tonight</a>
          <a href="#philosophy">Network</a>
          <a href="#clearance">Access</a>
          <a href="#vault">Vault</a>
          <a href="#identity">Identity</a>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 24 }}>
          <span className="nav-status"><span className="dot"></span>Verified · Level_02</span>
          <a href="#apply" className="ghost-btn" style={{ padding: '9px 22px' }}>Apply</a>
        </div>
        <button className="nav-toggle" onClick={() => setMobileMenuOpen(!mobileMenuOpen)} aria-label="Toggle menu">☰</button>
      </nav>

      <div className={`nav-overlay${mobileMenuOpen ? ' open' : ''}`} onClick={closeMenu}></div>

      <div className={`mobile-menu${mobileMenuOpen ? ' open' : ''}`}>
        <a href="#tonight">Tonight</a>
        <a href="#philosophy">Network</a>
        <a href="#clearance">Access</a>
        <a href="#vault">Vault</a>
        <a href="#identity">Identity</a>
        <div className="status">Verified · Level_02</div>
        <a href="#apply" className="ghost-btn apply-btn">Apply →</a>
      </div>
    </>
  );
}

/* ============== HERO ============== */
function Hero() {
  return (
    <section id="hero" className="hero" data-screen-label="01 Hero">
      <div className="hero-bg"><img src="assets/skyline-hero.png" alt="" /></div>

      <div className="hero-corner tl">
        — MEMBERSHIP NETWORK —<br />
        EST. 2024
      </div>
      <div className="hero-corner tr">
        PRIVATE<br />
        EXCLUSIVE<br />
        INVITATION ONLY
      </div>
      <div className="hero-corner bl">
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, color: 'var(--amber)' }}>
          <GlyphIII size={28} />
          <span style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
            <span style={{ color: 'var(--amber)' }}>IDENTITY VERIFIED</span>
            <span style={{ color: 'var(--fg-3)' }}>WELCOME HOME</span>
          </span>
        </div>
      </div>
      <div className="hero-corner br">
        LEVEL_02<br />
        CLEARANCE AUTHORIZED
      </div>

      <div className="eyebrow dash fade-in" style={{ marginBottom: 56 }}>
        Membership Network · Philadelphia
      </div>

      <h1 className="hero-mark flicker fade-in d1">
        ILLUSIONS
        <span className="hero-lounge">Lounge</span>
      </h1>

      <p className="hero-tag fade-in d3">
        A members-only environment built for creators, operators, and visionaries who move
        differently. Three access levels. One identity. A completely elevated network.
      </p>

      <div className="hero-cta fade-in d4">
        <a href="#clearance" className="ghost-btn">Enter the Network →</a>
        <a href="#vault" className="text-link">The Vault<span className="l"></span></a>
      </div>

      <div className="scroll-ind">Scroll · 01 / 06</div>
    </section>
  );
}

/* ============== TONIGHT STRIP ============== */
function TonightStrip() {
  return (
    <section id="tonight" className="tonight" data-screen-label="01b Tonight Strip">
      <div className="tonight-row">
        <div className="tonight-label">
          <span className="now"><span className="dot"></span>Tonight at Illusions</span>
          <span className="ts">Friday · 08 May · Live</span>
        </div>
        <div className="tonight-events">
          <div className="t-event">
            <span className="meta">— Sound in Motion —</span>
            <span className="ttl">Aurora · Live Set</span>
            <span className="time">10:00 PM · Main Floor</span>
          </div>
          <div className="t-event">
            <span className="meta">— Afterglow —</span>
            <span className="ttl">Private Experience</span>
            <span className="time">12:30 AM · Garden</span>
          </div>
          <div className="t-event">
            <span className="meta">— The Vault —</span>
            <span className="ttl">Members Only</span>
            <span className="time">02:00 AM · Restricted</span>
          </div>
          <div className="t-event">
            <span className="meta">— Studio 04 —</span>
            <span className="ttl">Open Floor</span>
            <span className="time">All Night · Creator</span>
          </div>
        </div>
        <a href="#identity" className="text-link">Open in App<span className="l"></span></a>
      </div>
    </section>
  );
}

/* ============== PHILOSOPHY ============== */
function Philosophy() {
  return (
    <section id="philosophy" className="section philosophy" data-screen-label="02 Philosophy">
      <div className="split-2">
        <div className="fade-up">
          <div className="section-label">— The Difference —</div>
          <h2 className="h-display">
            The space is only<br />
            the <em className="h-italic">beginning.</em>
          </h2>
          <p className="lead">
            Standard lounges give you access to a room.{' '}
            <strong>Illusions gives you access to an environment.</strong>{' '}
            A space where identity, access and atmosphere are synchronized.
          </p>
          <p className="lead">
            This isn't about being inside a venue. It's about being recognized inside it.
          </p>
          <div style={{ marginTop: 56, display: 'flex', gap: 48, flexWrap: 'wrap' }}>
            <div>
              <div className="h-display" style={{ fontSize: 56, color: 'var(--amber)' }}>
                <em className="h-italic">312</em>
              </div>
              <div className="micro" style={{ marginTop: 8 }}>Member capacity · current</div>
            </div>
            <div>
              <div className="h-display" style={{ fontSize: 56, color: 'var(--amber)' }}>
                <em className="h-italic">37</em>
              </div>
              <div className="micro" style={{ marginTop: 8 }}>Seats remaining · this cycle</div>
            </div>
          </div>
        </div>

        <div className="photo fade-up d2">
          <img src="assets/social-energy.png" alt="" />
          <div className="frame-corners"><i></i></div>
          <div className="corner">03 LEVELS<br />01 IDENTITY</div>
        </div>
      </div>
    </section>
  );
}

/* ============== CLEARANCE LEVELS ============== */
const LEVELS = [
  {
    code: 'LEVEL_01',
    name: 'General',
    role: 'Lounge Access',
    pos: '01 / 03',
    image: 'assets/lounge-atmosphere.png',
    pitch: <>Be inside <span className="gold">the room.</span> 24/7 access to the lounge floor — you arrive, you're recognized, the night begins.</>,
    price: '$199',
    term: 'Annual',
    monthlyPrice: '$25',
    monthlyTerm: 'Monthly',
    perks: [
      '24/7 lounge access · NFC identity card',
      'Member-only events · automatic entry',
      'Apple & Google Wallet credential',
      '3 guest passes per month',
      '10% on all bar purchases',
    ],
    cta: 'Join General →',
  },
  {
    code: 'LEVEL_02',
    name: 'Creator',
    role: 'Lounge + Content Floor',
    pos: '02 / 03',
    image: 'assets/social-energy.png',
    pitch: <>The most selected level. <span className="gold">Move freely</span> between the lounge and the content floor — studios, streams, and the network around them.</>,
    price: '$499',
    term: 'Annual',
    monthlyPrice: '$50',
    monthlyTerm: 'Monthly',
    perks: [
      'Everything in General',
      '24/7 access to content creation floor',
      'Priority studio booking · $50/hr',
      '5 guest passes · 15% bar discount',
      'Featured creator spotlight network',
      'Streaming & recording technical support',
    ],
    cta: 'Upgrade to Creator →',
  },
  {
    code: 'VAULT_CLEARANCE',
    name: 'Vault',
    role: 'Invitation Only',
    pos: '03 / 03',
    image: 'assets/vault.png',
    pitch: <><span className="gold">Earned, not purchased.</span> Priority entry across every environment. Private booking. Experiences that are not publicly listed.</>,
    price: 'By Invitation',
    term: 'Application Required',
    perks: [
      'All Creator-level access',
      'Priority entry across all environments',
      'Private booking capabilities',
      'Concierge-level support',
      'Experiences not publicly listed',
      'The Vault — restricted floor access',
    ],
    cta: 'Request Access →',
  },
];

function Clearance({ activeIndex, setActiveIndex }) {
  const lvl = LEVELS[activeIndex];
  return (
    <section id="clearance" className="clearance" data-screen-label="03 Access Clearance">
      <div className="head fade-up">
        <div>
          <div className="section-label">— Access Clearance —</div>
          <h2 className="h-display">
            Choose your<br />
            <em className="h-italic">tier.</em>
          </h2>
        </div>
        <p className="lead">
          Three distinct relationships to the room. Each level synchronizes a different
          surface area of the network — the lounge, the content floor, the vault.
        </p>
      </div>

      <div className="lvl-stage">
        <div className="lvl-list">
          {LEVELS.map((l, i) => (
            <div
              key={l.code}
              className={"lvl-row" + (i === activeIndex ? ' active' : '')}
              onClick={() => setActiveIndex(i)}
              role="button"
              tabIndex={0}
            >
              <span className="num">{l.pos}  ·  {l.code}</span>
              <span className="name">{l.name}</span>
              <span className="sub">{l.role}</span>
            </div>
          ))}
          <div style={{ padding: '32px 28px 8px', display: 'flex', flexDirection: 'column', gap: 12 }}>
            <span className="micro">— Network status —</span>
            <span className="code" style={{ color: 'var(--fg-2)' }}>312 / 350 active</span>
            <span className="code" style={{ color: 'var(--amber)' }}>37 seats remaining</span>
          </div>
        </div>

        <div className="lvl-cinematic">
          <div className="bg">
            {LEVELS.map((l, i) => (
              <img key={l.code} src={l.image} alt="" className={i === activeIndex ? 'active' : ''} />
            ))}
          </div>
          <div className="lvl-content">
            <div className="top">
              <span className="lvl-pos">{lvl.pos}  ·  {lvl.code}</span>
              <div className="titlerow">
                <span className="lvl-name">{lvl.name}</span>
              </div>
              <p className="pitch">{lvl.pitch}</p>
            </div>
            <div className="lvl-footer">
              <div className={"price-system" + (lvl.monthlyPrice ? ' has-monthly' : '')}>
                {lvl.monthlyPrice ? (
                  <>
                    <span className="monthly-line">
                      <span className="or">OR</span>
                      <span className="monthly-price">{lvl.monthlyPrice}</span>
                      <span className="monthly-term">{lvl.monthlyTerm}</span>
                    </span>
                    <span className="annual-line">
                      <span className="annual-price">{lvl.price}</span>
                      <span className="annual-term">{lvl.term}</span>
                    </span>
                  </>
                ) : (
                  <span className="price">
                    {lvl.price}
                    <span className="term">{lvl.term}</span>
                  </span>
                )}
              </div>
              <a href="#apply" className="text-link" style={{ color: 'var(--amber)' }}>
                {lvl.cta}<span className="l"></span>
              </a>
            </div>
          </div>
        </div>

        <div className="lvl-aside">
          <h5>— Included —</h5>
          <ul>
            {lvl.perks.map((p) => <li key={p}>{p}</li>)}
          </ul>
        </div>
      </div>
    </section>
  );
}

/* ============== VAULT ============== */
function Vault() {
  return (
    <section id="vault" className="vault" data-screen-label="04 The Vault">
      <div className="vault-grid">
        <div className="vault-img">
          <img src="assets/vault.png" alt="" />
        </div>
        <div className="vault-text">
          <div className="vault-meta">— Restricted —  ·  Floor 04  ·  Vault Clearance Required</div>
          <h2 className="vault-h">
            The Vault
            <span className="ital">is not explained.<br />it is earned.</span>
          </h2>
          <p className="vault-quote">
            "What happens inside depends on who has access. That's the difference."
          </p>
          <div className="vault-key">
            <div className="lock">
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
                <rect x="5" y="11" width="14" height="10" />
                <path d="M8 11V7a4 4 0 1 1 8 0v4" />
              </svg>
            </div>
            <div className="info">
              <span className="a">Sealed Until Authorization</span>
              <span className="b">Apply for invitation review</span>
            </div>
          </div>
          <a href="#apply" className="ghost-btn" style={{ alignSelf: 'flex-start', marginTop: 8 }}>
            Submit interest →
          </a>
        </div>
      </div>
    </section>
  );
}

/* ============== IDENTITY · MOBILE ============== */
function Identity() {
  return (
    <section id="identity" className="identity" data-screen-label="05 Identity · Mobile">
      <div className="identity-grid">
        <div className="id-copy fade-up">
          <div className="section-label">— Identity System —</div>
          <h2 className="h-display">
            One tap.<br />
            Identity recognized.<br />
            <em className="h-italic">access granted.</em>
          </h2>
          <p className="lead">
            Your card lives where you do. The environment doesn't ask who you are —
            it knows. NFC at the door. Wallet on the wrist. Biometric on the floor.
          </p>

          <div className="stat-row">
            <div className="stat">
              <div className="n"><em className="h-italic">0.4s</em></div>
              <div className="l">Average door verification</div>
            </div>
            <div className="stat">
              <div className="n"><em className="h-italic">3</em></div>
              <div className="l">Surfaces synchronized</div>
            </div>
          </div>

          <div style={{ marginTop: 56, display: 'flex', gap: 32, flexWrap: 'wrap' }}>
            <a href="#apply" className="ghost-btn">Provision your card →</a>
            <a className="text-link">View biometric flow<span className="l"></span></a>
          </div>
        </div>

        <div className="fade-up d2">
          <Phone />
        </div>
      </div>
    </section>
  );
}

function Phone() {
  return (
    <div className="phone">
      <div className="phone-screen">
        <div className="phone-statusbar">
          <span>9:41</span>
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
            <span style={{ width: 6, height: 6, borderRadius: 999, background: 'var(--amber)', boxShadow: '0 0 6px var(--amber)' }}></span>
            Verified
          </span>
        </div>
        <div className="phone-content">
          <div className="welcome-h">
            <span>— Welcome Back —</span>
            <span style={{ color: 'var(--fg-3)' }}>FRI · 08 MAY</span>
          </div>
          <div className="welcome-name">
            Avery,
            <span className="ital">you are home.</span>
          </div>

          <div className="mcard">
            <div className="mcard-top">
              <span className="mcard-mark">
                ILLUSIONS
                <span className="b">LOUNGE</span>
              </span>
              <div className="mcard-iii"><i></i><i></i><i></i></div>
            </div>
            <div className="mcard-mid">AVERY · CHEN</div>
            <div className="mcard-bot">
              <div className="id">
                MEMBER · ID
                <strong>0247 · NODE 17</strong>
              </div>
              <div className="lvl">LEVEL_02</div>
            </div>
          </div>

          <div className="phone-tonight">
            <h6>
              <span>— Tonight —</span>
              <span style={{ color: 'var(--amber)' }}>3 transmissions</span>
            </h6>
            <div className="phone-evt">
              <div>
                <div className="l1">Sound in Motion</div>
                <div className="l2">Aurora · Live Set</div>
              </div>
              <span className="time">10:00 PM</span>
            </div>
            <div className="phone-evt">
              <div>
                <div className="l1">Afterglow</div>
                <div className="l2">Private Experience</div>
              </div>
              <span className="time">12:30 AM</span>
            </div>
            <div className="phone-evt">
              <div>
                <div className="l1">The Vault</div>
                <div className="l2">Members Only</div>
              </div>
              <span className="time">02:00 AM</span>
            </div>
          </div>

          <div className="phone-cta">
            Hold to Enter
          </div>
        </div>
      </div>
    </div>
  );
}

/* ============== FINAL ============== */
function FinalCTA() {
  return (
    <section id="apply" className="final" data-screen-label="06 Final CTA">
      <div className="eyebrow dash" style={{ display: 'inline-flex', justifyContent: 'center' }}>
        — Limited Intake · 37 Seats Remaining —
      </div>
      <h2 style={{ marginTop: 32 }}>
        <em>If you know,</em><br />
        <span className="know2"><em>you know.</em></span>
      </h2>
      <div className="final-form">
        <input placeholder="Full name" />
        <input placeholder="Email · encrypted" />
        <select defaultValue="LEVEL_02">
          <option value="LEVEL_01">LEVEL_01 · General</option>
          <option value="LEVEL_02">LEVEL_02 · Creator</option>
          <option value="VAULT_CLEARANCE">VAULT_CLEARANCE · Invite Only</option>
        </select>
        <button className="primary-btn" type="button">Submit Interest →</button>
      </div>
      <p className="micro" style={{ marginTop: 32 }}>
        Every application reviewed personally · Response within seven days
      </p>
    </section>
  );
}

/* ============== MARQUEE & FOOTER ============== */
function Marquee() {
  const words = ['ATMOSPHERIC', '·', 'IMMERSIVE', '·', 'DYNAMIC', '·', 'CINEMATIC', '·', 'ALIVE', '·'];
  const arr = [...words, ...words, ...words, ...words];
  return (
    <div className="marquee">
      <div className="marquee-track">
        {arr.map((w, i) => <span key={i}>{w}</span>)}
      </div>
    </div>
  );
}

function Footer() {
  return (
    <footer className="footer">
      <div className="footer-row">
        <div>
          <BrandMark />
          <p style={{ fontFamily: 'var(--font-sans)', fontWeight: 300, fontSize: 12, lineHeight: 1.7, color: 'var(--fg-3)', marginTop: 18, maxWidth: 280 }}>
            A private membership network. Philadelphia. Members-only.
          </p>
          <div style={{ marginTop: 24, display: 'flex', alignItems: 'center', gap: 16 }}>
            <GlyphIII size={28} />
            <span className="micro">NODE_17 · SECURE CHANNEL</span>
          </div>
        </div>
        <div>
          <h5>Network</h5>
          <ul><li>Membership</li><li>Tonight</li><li>Access</li><li>Vault</li><li>Process</li></ul>
        </div>
        <div>
          <h5>Identity</h5>
          <ul><li>System</li><li>Card</li><li>Wallet Pass</li><li>Biometric</li></ul>
        </div>
        <div>
          <h5>Channel</h5>
          <ul><li>Apply</li><li>Concierge</li><li>Press</li><li>Code of Conduct</li></ul>
        </div>
      </div>
      <div className="legal">
        <span>© Illusions Lounge · Members Only</span>
        <span>NODE_17 · SECURE CHANNEL · LEVEL_02 ACTIVE</span>
      </div>
    </footer>
  );
}

Object.assign(window, {
  CinematicIntro, AudioControls, AccessGate, Nav, Hero, TonightStrip, Philosophy, Clearance, Vault, Identity,
  FinalCTA, Marquee, Footer, BrandMark, GlyphIII, LEVELS,
});
