// Vibe Den — components (multi-page hash-routed React)
const { useState, useEffect, useRef, useCallback } = React;

// ---------- shared ----------
const Eyebrow = ({ children, center }) => (
  <div className={`flex items-center gap-3 ${center ? 'justify-center' : ''}`}>
    <div className="h-px w-12 bg-accent" />
    <span className="text-xs md:text-sm font-medium tracking-widest text-muted uppercase">{children}</span>
    {center && <div className="h-px w-12 bg-accent" />}
  </div>
);

const GlitchText = ({ children, className = "", as: Tag = "h2" }) => {
  const ref = React.useRef(null);
  const [seen, setSeen] = React.useState(false);
  React.useEffect(() => {
    if (!ref.current || seen) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (e.isIntersecting) {
          setSeen(true);
          const el = ref.current;
          el.classList.remove('glitch-enter');
          void el.offsetWidth;
          el.classList.add('glitch-enter');
          io.disconnect();
        }
      });
    }, { threshold: 0.3, rootMargin: '0px 0px -10% 0px' });
    io.observe(ref.current);
    return () => io.disconnect();
  }, []);
  return (
    <Tag ref={ref} className={`glitch-text ${className}`}>
      <span className="glitch-base">{children}</span>
      <span className="glitch-layer glitch-layer-r" aria-hidden="true">{children}</span>
      <span className="glitch-layer glitch-layer-c" aria-hidden="true">{children}</span>
    </Tag>
  );
};

// ---------- routing (hash) ----------
function useRoute() {
  const get = () => {
    const h = window.location.hash.replace(/^#/, '') || '/';
    return h.startsWith('/') ? h : '/' + h;
  };
  const [route, setRoute] = useState(get());
  useEffect(() => {
    const onHash = () => { setRoute(get()); window.scrollTo(0, 0); };
    window.addEventListener('hashchange', onHash);
    return () => window.removeEventListener('hashchange', onHash);
  }, []);
  return route;
}

// ---------- nav ----------
const Nav = ({ route }) => {
  const [scrolled, setScrolled] = useState(false);
  const [open, setOpen] = useState(false);
  const [megaOpen, setMegaOpen] = useState(false);
  const [active, setActive] = useState(null); // active mega column index
  const [trailing, setTrailing] = useState(null); // index of menu showing the cyan leave-trail
  const closeTimer = useRef(null);
  const trailTimer = useRef(null);

  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 20);
    window.addEventListener('scroll', onScroll);
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  useEffect(() => { setOpen(false); setMegaOpen(false); setActive(null); }, [route]);

  const columns = [
    { label: 'About',       href: '#/',            items: [
      ['Vibe Den',    '#/'],
      ['The Crew',    '#/#crew'],
      ['New Releases','#/#releases'],
      ['Events',      '#/#events'],
      ['Gallery',     '#/#gallery'],
      ['Testimonials','#/#press'],
      ['Creator',     '#/#creator'],
    ]},
    { label: 'Artists',     href: '#/artists',     items: [
      ['All Artists', '#/artists'],
      ['NOVA',        '#/artists/nova'],
      ['ZEPHYR',      '#/artists/zephyr'],
      ['PULSE',       '#/artists/pulse'],
    ]},
    { label: 'Discography', href: '#/discography', items: [
      ['All Releases','#/discography'],
      ['Albums',      '#/discography'],
      ['EPs',         '#/discography'],
      ['Singles',     '#/discography'],
    ]},
    { label: 'Media',       href: '#/media',       items: [
      ['All Media',   '#/media'],
      ['Videos',      '#/media'],
      ['Photos',      '#/media'],
    ]},
    { label: 'Connect',     href: '#/connect',     items: [
      ['Contact',     '#/connect'],
      ['Send Message','#/connect'],
    ]},
    { label: 'The Town',    href: '#/the-town',    items: [
      ['Community',   '#/the-town'],
      ['From the Crew','#/the-town'],
    ]},
  ];

  const isCurrent = (href) => {
    const path = href.replace('#/', '/').split('#')[0] || '/';
    if (path === '/') return route === '/';
    return route === path || route.startsWith(path + '/');
  };

  const handleEnter = (i) => {
    if (closeTimer.current) { clearTimeout(closeTimer.current); closeTimer.current = null; }
    // If we're hovering this same item again, kill any pending trail for it
    if (trailing === i) {
      if (trailTimer.current) { clearTimeout(trailTimer.current); trailTimer.current = null; }
      setTrailing(null);
    } else if (active !== null && active !== i && active !== trailing) {
      // The previously-hovered item starts a leave-trail (cyan filled circle fading)
      if (trailTimer.current) { clearTimeout(trailTimer.current); }
      setTrailing(active);
      trailTimer.current = setTimeout(() => { setTrailing(null); trailTimer.current = null; }, 280);
    }
    setMegaOpen(true);
    setActive(i);
  };
  const handleLeave = () => {
    closeTimer.current = setTimeout(() => {
      // When leaving the whole nav, the last hovered item also gets a trail
      if (active !== null) {
        const last = active;
        if (trailTimer.current) { clearTimeout(trailTimer.current); }
        setTrailing(last);
        trailTimer.current = setTimeout(() => { setTrailing(null); trailTimer.current = null; }, 280);
      }
      setMegaOpen(false);
      setActive(null);
    }, 120);
  };

  return (
    <React.Fragment>
      <nav
        className={`fixed top-0 left-0 right-0 z-40 transition-all duration-300 py-7 nav-blur ${megaOpen ? 'nav-mega-open' : ''}`}
        onMouseLeave={handleLeave}
      >
        <div className="mx-auto max-w-7xl px-6 lg:px-8 flex items-center justify-between">
          <a href="#/" className="vibe-brand text-xl font-bold tracking-tight relative">
            <img src="images/logo.png?v=4" alt="" className="vibe-logo-mark -mr-0.5" />
            <span className="inline-block">VIBE</span>
            <span className="text-accent inline-block ml-1">DEN</span>
          </a>

          <div className="hidden md:flex items-center gap-3 text-sm">
            {columns.map((c, i) => {
              const current = isCurrent(c.href);
              const isHover = active === i && !current;
              const isTrail = trailing === i && !current && !isHover;
              return (
                <a
                  key={c.label}
                  href={c.href}
                  onMouseEnter={() => handleEnter(i)}
                  className={`relative px-5 py-3 transition-colors duration-200 ${current ? 'text-white' : isHover ? 'text-fg' : 'text-muted hover:text-fg'}`}
                >
                  {/* Filled green disc — only when current page */}
                  <span className={`nav-orb-disc ${current ? 'is-active' : ''}`} />
                  {/* Magenta outline ring — only while hovered */}
                  <span className={`nav-orb-ring ${isHover ? 'is-on' : ''}`} />
                  {/* Cyan filled trail — only after leaving a hovered item */}
                  <span className={`nav-orb-trail ${isTrail ? 'is-on' : ''}`} />
                  {current && <span className="nav-orbit-inner is-active" />}
                  {current && <span className="nav-orbit-outer is-active" />}
                  <span className={`relative z-10 ${current ? 'nav-label-active' : ''}`}>{c.label}</span>
                </a>
              );
            })}
          </div>

          <div className="flex items-center gap-3">
            <VibeTweaks />
            <button className="hidden md:inline-flex items-center gap-2 text-xs font-medium text-bg bg-fg hover:bg-white transition-colors relative group px-4 py-2 rounded-full">
              <span className="w-1.5 h-1.5 rounded-full bg-bg/60 group-hover:bg-accent transition-colors" />
              Login
            </button>
            <button
              aria-label="Menu"
              onClick={() => setOpen(o => !o)}
              className="md:hidden w-10 h-10 flex flex-col items-center justify-center gap-1.5 rounded-full border border-border"
            >
              <span className={`block w-4 h-px bg-fg transition-all ${open ? 'translate-y-[3px] rotate-45' : ''}`} />
              <span className={`block w-4 h-px bg-fg transition-all ${open ? '-translate-y-[3px] -rotate-45' : ''}`} />
            </button>
          </div>
        </div>

        {/* Mega menu — full width. Outer panel slides down (blind / roll-down),
            inner content fades in with a small stagger after the panel opens. */}
        <div
          data-dropdown="mega"
          className={`mega-wrap absolute left-0 right-0 top-full ${megaOpen ? 'is-open' : ''}`}
          onMouseEnter={() => { if (closeTimer.current) { clearTimeout(closeTimer.current); closeTimer.current = null; } setMegaOpen(true); }}
        >
          <div className="mega-dropdown-bg">
            <div className="mega-inner mx-auto max-w-7xl px-6 lg:px-8 py-10">
              <div className="grid grid-cols-6 gap-x-12 lg:gap-x-16 gap-y-8">
                {columns.map((c, i) => {
                  const isActiveCol = active === i;
                  return (
                    <div
                      key={c.label}
                      onMouseEnter={() => setActive(i)}
                      className="relative"
                    >
                      <div className={`text-[11px] font-mono tracking-[0.2em] uppercase mb-5 transition-colors ${isActiveCol ? 'text-accentB' : 'text-muted'}`}>
                        {c.label}
                        {isActiveCol && <span className="ml-2 inline-block w-1 h-1 rounded-full bg-accentB align-middle" />}
                      </div>
                      <ul className="space-y-1">
                        {c.items.map(([label, href], j) => (
                          <li key={label}>
                            <a
                              href={href}
                              className={`mega-link group/m flex items-center gap-2 text-[15px] font-medium py-1.5 -mx-2 px-2 rounded-md whitespace-nowrap transition-colors ${isActiveCol ? 'text-fg' : 'text-muted hover:text-fg'}`}
                              style={{ transitionDelay: megaOpen ? `${j * 30}ms` : '0ms' }}
                            >
                              <span className="mega-glitch" aria-hidden="true">A</span>
                              <span className="group-hover/m:translate-x-0.5 transition-transform">{label}</span>
                            </a>
                          </li>
                        ))}
                      </ul>
                    </div>
                  );
                })}
              </div>
            </div>
          </div>
        </div>
      </nav>

      {/* Mobile drawer */}
      <div data-dropdown="mobile" className={`md:hidden fixed inset-0 z-30 transition-opacity duration-300 ${open ? 'opacity-100 pointer-events-auto' : 'opacity-0 pointer-events-none'}`}>
        <div className="absolute inset-0 bg-bg/80 backdrop-blur-xl" onClick={() => setOpen(false)} />
        <div className={`absolute top-20 left-4 right-4 rounded-2xl border border-border bg-bg/95 backdrop-blur-xl p-4 transition-all duration-300 ${open ? 'translate-y-0' : '-translate-y-4'}`}>
          {columns.map((c) => (
            <details key={c.label} className="border-b border-border/50 last:border-0 group">
              <summary className="flex items-center justify-between px-3 py-3.5 cursor-pointer text-base font-medium list-none">
                {c.label}
                <span className="text-muted transition-transform group-open:rotate-90">→</span>
              </summary>
              <ul className="pb-3 px-3 space-y-2">
                {c.items.map(([label, href]) => (
                  <li key={label}>
                    <a href={href} className="block py-2 text-sm text-muted hover:text-fg">{label}</a>
                  </li>
                ))}
              </ul>
            </details>
          ))}
          <div className="flex gap-2 pt-3">
            <button className="flex-1 px-4 py-3 text-sm font-medium bg-fg text-bg rounded-full">Login</button>
          </div>
        </div>
      </div>
    </React.Fragment>
  );
};

// ---------- Brand Intro (huge logo + wordmark, first thing on home) ----------
const BrandIntro = () => (
  <section className="relative overflow-hidden pt-20 lg:pt-24 pb-10">
    <div className="relative z-10 mx-auto max-w-7xl px-6 lg:px-8 w-full flex flex-col items-center text-center">
      {/* HUGE logo mark — RGB glitch (different rhythm than the wordmark) */}
      <img
        src="images/logo.png?v=4"
        alt=""
        className="w-[clamp(280px,44vw,600px)] h-auto -mb-2 brand-intro-mark"
      />

      {/* HUGE wordmark — VIBE DEN on a single line */}
      <h1
        className="leading-[0.85] font-black tracking-tight whitespace-nowrap flex items-baseline justify-center gap-[0.18em]"
        style={{ fontSize: 'clamp(44px, 8vw, 120px)' }}
      >
        <GlitchText as="span" className="text-fg">VIBE</GlitchText>
        <GlitchText as="span" className="text-accent">DEN</GlitchText>
      </h1>

      {/* tagline */}
      <p className="mt-4 text-base md:text-lg text-muted max-w-xl tracking-wide">
        Where 3D meets beats. Born in the metaverse, crafting sounds for the future.
      </p>

      {/* scroll cue — sexy lines, sci-fi tracking brackets + long thread */}
      <div className="mt-10 flex flex-col items-center gap-5 scroll-cue">
        {/* SCROLL with corner brackets */}
        <div className="relative inline-flex items-center px-6 py-1">
          {/* corner brackets */}
          <span className="absolute left-0 top-0 w-3 h-3 border-t border-l border-accent/80" />
          <span className="absolute right-0 top-0 w-3 h-3 border-t border-r border-accent/80" />
          <span className="absolute left-0 bottom-0 w-3 h-3 border-b border-l border-accent/80" />
          <span className="absolute right-0 bottom-0 w-3 h-3 border-b border-r border-accent/80" />
          <div
            className="font-light tracking-[0.55em] text-fg/90"
            style={{ fontSize: 'clamp(24px, 3.4vw, 44px)' }}
          >
            SCROLL
          </div>
        </div>

        {/* tiny meta caption */}
        <div className="font-mono text-[10px] tracking-[0.4em] text-accent/70 uppercase">
          ↓ enter the den ↓
        </div>

        {/* long sexy line with diamond + traveling pulse */}
        <div className="relative h-24 w-px overflow-hidden">
          {/* base line — gradient fade */}
          <div className="absolute inset-0 bg-gradient-to-b from-accent via-accent/60 to-transparent" />
          {/* traveling pulse */}
          <div className="scroll-pulse absolute -top-4 left-1/2 -translate-x-1/2 w-px h-8 bg-gradient-to-b from-transparent via-white to-transparent" />
        </div>
        {/* diamond at the end */}
        <div className="relative -mt-3 w-3 h-3 rotate-45 border border-accent bg-bg shadow-[0_0_12px_rgba(182,255,0,0.7)]" />
      </div>
    </div>
  </section>
);

// ---------- HOME ----------
const Hero = () => (
  <section id="about" className="relative min-h-screen overflow-hidden">
    <div className="relative mx-auto max-w-7xl px-6 lg:px-8 pt-32 lg:pt-40 pb-20">
      <div className="grid lg:grid-cols-2 gap-12 lg:gap-20 items-center min-h-[80vh]">
        <div className="space-y-8 order-2 lg:order-1">
          <Eyebrow>Virtual DJ Crew</Eyebrow>
          <div className="space-y-2">
            <GlitchText as="h1" className="text-6xl md:text-7xl lg:text-8xl font-black tracking-tight leading-[0.95]">Vibe Den</GlitchText>
            <p className="text-3xl md:text-4xl lg:text-5xl font-light text-muted tracking-tight">Where 3D meets beats</p>
          </div>
          <p className="text-lg text-muted max-w-md leading-relaxed">
            Experience the future of electronic music with our crew of virtual 3D characters,
            pushing the boundaries of digital performance.
          </p>
          <div className="flex items-center gap-3 pt-2 flex-wrap">
            <a href="https://www.youtube.com/@VIBE_DEN_Official" target="_blank" rel="noopener noreferrer" className="group flex items-center gap-3 px-6 py-3.5 bg-fg text-bg font-medium rounded-full btn-sharp">
              <svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
              YouTube Channel
            </a>
            <a href="#/artists" className="px-6 py-3.5 text-sm font-medium border border-border rounded-full hover:border-fg transition-all btn-sharp">Explore Crew</a>
          </div>
          <div className="flex items-center gap-3 pt-8 border-t border-border flex-wrap">
            {[
              ['Instagram','https://www.instagram.com/vibeden_official'],
              ['Facebook','https://www.facebook.com/profile.php?id=61560331666068'],
              ['Discography','#/discography'],
            ].map(([l, h]) => (
              <a
                key={l}
                href={h}
                target={h.startsWith('http') ? '_blank' : undefined}
                rel={h.startsWith('http') ? 'noopener noreferrer' : undefined}
                className="px-5 py-3 text-sm font-medium border border-border rounded-full hover:bg-secondary transition-all"
              >{l}</a>
            ))}
          </div>
        </div>
        <div className="relative order-1 lg:order-2">
          <div className="relative aspect-[4/5] rounded-2xl overflow-hidden light-blur">
            <img src="images/crew-group.jpg" alt="Vibe Den crew" className="w-full h-full object-cover" />
            <div className="absolute inset-0 bg-gradient-to-t from-bg/40 to-transparent" />
            <div className="absolute top-4 left-4 flex items-center gap-2 text-xs font-mono text-fg/80">
              <span className="w-2 h-2 rounded-full bg-[#B6FF00] animate-pulse" />
              LIVE · METAVERSE
            </div>
          </div>
          <div className="absolute -bottom-6 -left-6 w-32 h-32 rounded-2xl bg-accentB/10 backdrop-blur-sm border border-accentB/30 flex items-center justify-center">
            <div className="text-center">
              <p className="text-2xl font-bold text-accentB">2026</p>
              <p className="text-xs text-muted">World Tour</p>
            </div>
          </div>
        </div>
      </div>
    </div>
  </section>
);

const CrewSection = () => (
  <section id="crew" className="py-24 md:py-32">
    <div className="mx-auto max-w-7xl px-6 lg:px-8">
      <div className="flex flex-col md:flex-row md:items-end md:justify-between gap-6 mb-16">
        <div>
          <Eyebrow>The Crew</Eyebrow>
          <GlitchText className="text-4xl md:text-5xl font-bold mt-4">Meet our virtual artists</GlitchText>
        </div>
        <p className="text-muted max-w-md md:text-right">
          Three unique 3D characters, each bringing their own style and energy to every performance.
        </p>
      </div>
      <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
        {window.CREW.map((m, i) => (
          <a key={m.name} href={`#/artists/${m.slug}`} data-track tabIndex={0} className="group relative bg-secondary/50 rounded-xl overflow-hidden hover:bg-secondary transition-all">
            <div className="relative aspect-[4/5] overflow-hidden">
              <img src={m.image} alt={m.name} className="w-full h-full object-cover transition-transform duration-500 group-hover:scale-105" />
              <div className="absolute top-3 left-3 px-2 py-1 text-[10px] font-mono tracking-widest bg-bg/70 backdrop-blur-sm rounded">{`0${i+1}`}</div>
            </div>
            <div className="p-6 flex items-start justify-between">
              <div>
                <p className="text-xs font-medium text-muted uppercase tracking-wide mb-1">{m.role}</p>
                <h3 className="text-2xl font-bold">{m.name}</h3>
                <p className="text-sm text-muted mt-2">{m.genre}</p>
              </div>
              <span className="w-10 h-10 rounded-full border border-border flex items-center justify-center group-hover:bg-fg group-hover:text-bg transition-all">↗</span>
            </div>
          </a>
        ))}
      </div>
      <div className="mt-24 py-16 border-t border-border">
        <p className="text-2xl md:text-3xl leading-relaxed text-muted max-w-3xl">
          We are <span className="text-fg font-medium">Vibe Den</span> —
          a collective of virtual artists pushing the boundaries of music and digital art.
          Born in the metaverse, creating sounds for the future.
        </p>
      </div>
    </div>
  </section>
);

const EventsSection = () => (
  <section id="events" className="bg-secondary/20 py-24 md:py-32">
    <div className="mx-auto max-w-7xl px-6 lg:px-8">
      <div className="flex flex-col md:flex-row md:items-end md:justify-between gap-6 mb-16">
        <div>
          <Eyebrow>Upcoming Shows</Eyebrow>
          <GlitchText className="text-4xl md:text-5xl font-bold mt-4">Live Events</GlitchText>
        </div>
        <p className="text-muted max-w-sm">Join us in the metaverse or catch a hybrid show. The future of concerts is here.</p>
      </div>
      <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
        {window.EVENTS.map(ev => (
          <div key={ev.title} data-track tabIndex={0} className="group relative bg-card rounded-xl overflow-hidden border border-border hover:border-accentR/60 transition-all">
            <div className="relative aspect-[4/3] overflow-hidden">
              <img src={ev.image} alt={ev.title} className="w-full h-full object-cover transition-transform duration-500 group-hover:scale-105" />
              <div className="absolute top-4 left-4 px-3 py-1.5 text-xs font-medium uppercase tracking-wide rounded-full bg-bg/80 backdrop-blur-sm">{ev.type}</div>
              {ev.soldOut && <div className="absolute top-4 right-4 px-3 py-1.5 text-xs font-medium uppercase tracking-wide rounded-full bg-fg text-bg">Sold Out</div>}
            </div>
            <div className="p-6">
              <h3 className="text-xl font-semibold mb-4">{ev.title}</h3>
              <div className="flex flex-col gap-2 text-sm text-muted mb-6">
                <div>📅 {ev.date}</div>
                <div>📍 {ev.location}</div>
              </div>
              <button disabled={ev.soldOut} className={`w-full py-3 rounded-full text-sm font-medium transition-all btn-sharp ${ev.soldOut ? 'bg-muted/30 text-muted cursor-not-allowed' : 'bg-fg text-bg hover:bg-fg/90'}`}>
                {ev.soldOut ? 'Sold Out' : 'Get Tickets ↗'}
              </button>
            </div>
          </div>
        ))}
      </div>
    </div>
  </section>
);

const ReleasesSection = () => {
  const [selected, setSelected] = useState(null);
  return (
    <section id="releases" className="py-24 md:py-32">
      <div className="mx-auto max-w-7xl px-6 lg:px-8">
        <div className="flex flex-col md:flex-row md:items-end md:justify-between gap-6 mb-12">
          <div>
            <Eyebrow>Latest</Eyebrow>
            <GlitchText className="text-4xl md:text-5xl font-bold mt-4">New Releases</GlitchText>
          </div>
          <p className="text-muted max-w-md">Click any album to listen on your favorite streaming platform.</p>
        </div>
        <div className="grid grid-cols-2 md:grid-cols-3 gap-4 md:gap-6">
          {window.ALBUMS.slice(0, 6).map(a => (
            <div key={a.id} data-track role="button" tabIndex={0} onClick={() => setSelected(a)} className="group cursor-pointer">
              <div className="relative aspect-square overflow-hidden rounded-lg mb-4 light-blur-hover">
                <img src={a.coverUrl} alt={a.title} className="w-full h-full object-cover transition-transform duration-500 group-hover:scale-105" />
                <div className="absolute inset-0 bg-fg/0 group-hover:bg-fg/20 transition-all duration-300 flex items-center justify-center">
                  <div className="w-14 h-14 rounded-full bg-bg/90 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-all duration-300 scale-75 group-hover:scale-100">
                    <svg viewBox="0 0 24 24" width="22" height="22" fill="currentColor" style={{marginLeft: 2}}><path d="M8 5v14l11-7z"/></svg>
                  </div>
                </div>
                <div className="absolute top-3 left-3 px-2 py-1 text-[10px] uppercase tracking-wider font-medium bg-bg/80 backdrop-blur-sm rounded">{a.type}</div>
              </div>
              <h3 className="text-base font-semibold truncate group-hover:text-accentB transition-colors">{a.title}</h3>
              <p className="text-sm text-muted truncate">{a.artist} · {a.year}</p>
            </div>
          ))}
        </div>
        <div className="mt-12 text-center">
          <a href="#/discography" className="inline-flex items-center gap-2 px-6 py-3 text-sm font-medium rounded-full border border-border hover:bg-secondary transition-all">View All Releases →</a>
        </div>
      </div>
      {selected && <StreamingModal album={selected} onClose={() => setSelected(null)} />}
    </section>
  );
};

const StreamingModal = ({ album, onClose }) => (
  <div onClick={onClose} className="fixed inset-0 z-50 bg-black/80 backdrop-blur-sm flex items-center justify-center p-6">
    <div onClick={e => e.stopPropagation()} className="bg-card border border-border rounded-2xl p-8 max-w-md w-full">
      <div className="flex gap-4 mb-6">
        <img src={album.coverUrl} alt={album.title} className="w-24 h-24 rounded-lg object-cover" />
        <div>
          <p className="text-xs uppercase tracking-wider text-muted">{album.type}</p>
          <h3 className="text-xl font-bold">{album.title}</h3>
          <p className="text-sm text-muted">{album.artist} · {album.year}</p>
        </div>
      </div>
      <div className="space-y-2">
        {[
          ['Spotify', '#'],
          ['Apple Music', '#'],
          ['YouTube Music', 'https://www.youtube.com/@VIBE_DEN_Official'],
          ['SoundCloud', '#'],
        ].map(([s, href]) => (
          <a
            key={s}
            href={href}
            target={href.startsWith('http') ? '_blank' : undefined}
            rel={href.startsWith('http') ? 'noopener noreferrer' : undefined}
            className="w-full py-3 px-4 text-left rounded-lg bg-secondary hover:bg-fg hover:text-bg transition-all text-sm font-medium flex items-center justify-between"
          >
            {s} <span>↗</span>
          </a>
        ))}
      </div>
      <button onClick={onClose} className="mt-4 w-full py-2 text-sm text-muted hover:text-fg transition-colors">Close</button>
    </div>
  </div>
);

const HorizontalGallery = () => {
  const containerRef = useRef(null);
  const trackRef = useRef(null);
  const [progress, setProgress] = useState(0);

  const items = [
    { src: 'images/dj-character-1.jpg', label: 'NEON performing' },
    { src: 'images/event-1.jpg',        label: 'Virtual concert' },
    { src: 'images/dj-character-2.jpg', label: 'PULSE in action' },
    { src: 'images/event-2.jpg',        label: 'Club atmosphere' },
    { src: 'images/dj-character-3.jpg', label: 'BASS dropping beats' },
    { src: 'images/crew-group.jpg',     label: 'Full crew' },
    { src: 'images/hero-dj-stage.jpg',  label: 'Main stage' },
  ];

  useEffect(() => {
    const onScroll = () => {
      const el = containerRef.current;
      const track = trackRef.current;
      if (!el || !track) return;
      const rect = el.getBoundingClientRect();
      const vh = window.innerHeight;
      const total = el.offsetHeight - vh;
      const scrolled = Math.min(Math.max(-rect.top, 0), total);
      const p = total > 0 ? scrolled / total : 0;
      setProgress(p);
      const trackWidth = track.scrollWidth - window.innerWidth + 96;
      track.style.transform = `translate3d(${-p * trackWidth}px, 0, 0)`;
    };
    onScroll();
    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('resize', onScroll);
    return () => {
      window.removeEventListener('scroll', onScroll);
      window.removeEventListener('resize', onScroll);
    };
  }, []);

  return (
    <section id="gallery" ref={containerRef} className="relative" style={{ height: `${items.length * 60}vh` }}>
      <div className="sticky top-0 h-screen overflow-hidden flex flex-col">
        <div className="mx-auto max-w-7xl px-6 lg:px-8 w-full pt-28 pb-6 flex items-end justify-between gap-6">
          <div>
            <Eyebrow>Gallery</Eyebrow>
            <GlitchText className="text-4xl md:text-5xl font-bold mt-3">Behind the Scenes</GlitchText>
          </div>
          <div className="hidden md:flex flex-col items-end gap-2 min-w-[200px]">
            <div className="text-xs font-mono text-muted tracking-widest">{String(Math.round(progress * 100)).padStart(3, '0')} / 100</div>
            <div className="w-full h-px bg-border relative overflow-hidden">
              <div className="absolute inset-y-0 left-0 bg-accent transition-[width] duration-100" style={{ width: `${progress * 100}%` }} />
            </div>
          </div>
        </div>
        <div className="flex-1 relative overflow-hidden">
          <div ref={trackRef} className="absolute top-0 bottom-0 left-0 flex items-center gap-6 pl-6 lg:pl-8 will-change-transform">
            {items.map((it, i) => (
              <figure
                key={i}
                data-track
                tabIndex={0}
                className="relative shrink-0 w-[60vw] md:w-[42vw] lg:w-[34vw] aspect-[4/5] rounded-2xl overflow-hidden bg-secondary group"
              >
                <img src={it.src} alt={it.label} className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-105" />
                <div className="absolute inset-0 bg-gradient-to-t from-bg/70 via-transparent to-transparent" />
                <figcaption className="absolute bottom-5 left-5 right-5 flex items-end justify-between gap-3">
                  <div>
                    <div className="text-[10px] font-mono text-accentB tracking-widest mb-1">{String(i + 1).padStart(2, '0')} / {String(items.length).padStart(2, '0')}</div>
                    <p className="text-lg font-medium text-white">{it.label}</p>
                  </div>
                  <span className="w-8 h-8 rounded-full border border-white/30 flex items-center justify-center text-white/80 text-xs">↗</span>
                </figcaption>
              </figure>
            ))}
            <div className="shrink-0 w-24 lg:w-32" />
          </div>
        </div>
        <div className="mx-auto max-w-7xl px-6 lg:px-8 w-full pb-8 flex items-center justify-between text-xs text-muted">
          <span className="font-mono">↓ scroll to pan ↓</span>
          <span className="font-mono">{items.length} frames</span>
        </div>
      </div>
    </section>
  );
};

const Editorial = () => (
  <section className="border-t border-border">
    <div className="mx-auto max-w-7xl px-6 lg:px-8 py-24 md:py-32">
      <div className="grid grid-cols-2 md:grid-cols-4 gap-8 md:gap-12">
        {window.STATS.map((s, i) => (
          <div key={s.label} className="text-center">
            <div className={`w-1 h-1 mx-auto mb-4 rounded-full ${i % 3 === 0 ? 'bg-accent' : i % 3 === 1 ? 'bg-accentR' : 'bg-accentB'}`} />
            <p className="text-4xl md:text-5xl font-bold mb-2 font-mono">{s.value}</p>
            <p className="text-xs uppercase tracking-widest text-muted">{s.label}</p>
          </div>
        ))}
      </div>
    </div>
  </section>
);

const MerchSection = () => {
  const items = [
    { name: 'Vibe Den Hoodie', desc: 'Neon logo embroidered',  price: '$89', tag: 'Bestseller', img: 'images/dj-character-1.jpg' },
    { name: 'Crew Tee',        desc: 'Limited edition print',   price: '$45', tag: null,         img: 'images/dj-character-2.jpg' },
    { name: 'Neon Cap',        desc: 'Glow-in-the-dark logo',   price: '$35', tag: 'New',        img: 'images/dj-character-3.jpg' },
    { name: 'VR Poster Pack',  desc: 'Set of 3 AR posters',     price: '$25', tag: null,         img: 'images/crew-group.jpg' },
  ];
  return (
    <section id="merch" className="py-24 md:py-32">
      <div className="mx-auto max-w-7xl px-6 lg:px-8">
        <div className="flex items-end justify-between mb-12 gap-6 flex-wrap">
          <div>
            <Eyebrow>Official Merch</Eyebrow>
            <GlitchText className="text-4xl md:text-5xl font-bold mt-3">Rep the Crew</GlitchText>
          </div>
          <a href="#" className="text-sm text-muted hover:text-fg inline-flex items-center gap-2 transition-colors">View all products →</a>
        </div>
        <div className="grid grid-cols-2 lg:grid-cols-4 gap-4 md:gap-6">
          {items.map((it) => (
            <div key={it.name} data-track tabIndex={0} className="group relative rounded-2xl overflow-hidden bg-secondary/50 hover:bg-secondary transition-all">
              <div className="aspect-square relative overflow-hidden">
                <img src={it.img} alt={it.name} className="w-full h-full object-cover transition-transform duration-700 group-hover:scale-105" />
                {it.tag && (
                  <span className={`absolute top-3 left-3 text-[10px] font-mono tracking-widest uppercase px-2.5 py-1 rounded-full ${it.tag === 'Bestseller' ? 'bg-accent text-white' : 'bg-fg text-bg'}`}>{it.tag}</span>
                )}
                <button className="absolute bottom-3 right-3 px-3 py-1.5 text-xs font-medium bg-bg/90 backdrop-blur rounded-full opacity-0 group-hover:opacity-100 translate-y-1 group-hover:translate-y-0 transition-all">+ Add to Cart</button>
              </div>
              <div className="p-4 flex items-start justify-between gap-3">
                <div>
                  <h3 className="font-medium text-sm">{it.name}</h3>
                  <p className="text-xs text-muted mt-0.5">{it.desc}</p>
                </div>
                <span className="font-mono text-sm font-semibold whitespace-nowrap">{it.price}</span>
              </div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
};

const MusicVideoSection = () => (
  <section id="video" className="py-24 md:py-32 border-t border-border">
    <div className="mx-auto max-w-7xl px-6 lg:px-8">
      <div className="grid lg:grid-cols-3 gap-10 items-end mb-10">
        <div className="lg:col-span-2">
          <Eyebrow>Watch Now</Eyebrow>
          <GlitchText className="text-4xl md:text-6xl font-bold mt-4 leading-[1]">Latest Music Video</GlitchText>
        </div>
        <p className="text-sm text-muted">"Neon Dreams" — Official 4K virtual concert capture. NOVA × PULSE, dropped 2024.</p>
      </div>
      <div data-track role="button" tabIndex={0} className="relative aspect-video rounded-2xl overflow-hidden bg-secondary group cursor-pointer">
        <img src="images/hero-dj-stage.jpg" alt="Music video thumbnail" className="absolute inset-0 w-full h-full object-cover transition-transform duration-700 group-hover:scale-[1.02]" />
        <div className="absolute inset-0 bg-gradient-to-t from-bg/80 via-bg/20 to-transparent" />
        <div className="absolute inset-0 flex items-center justify-center">
          <div className="relative">
            <span className="absolute inset-0 rounded-full bg-accent/30 animate-ping" />
            <button className="relative w-20 h-20 rounded-full bg-accent flex items-center justify-center group-hover:scale-110 transition-transform">
              <svg viewBox="0 0 24 24" width="28" height="28" fill="white" className="ml-1"><path d="M8 5v14l11-7z"/></svg>
            </button>
          </div>
        </div>
        <div className="absolute bottom-6 left-6 right-6 flex items-end justify-between gap-4">
          <div>
            <div className="text-xs font-mono text-accentR tracking-widest mb-2">04:21 · OFFICIAL VIDEO</div>
            <p className="text-xl md:text-2xl font-semibold text-white">Neon Dreams (Live from the Metaverse)</p>
          </div>
          <span className="hidden md:inline-flex items-center gap-2 text-xs text-white/80 font-mono">
            <span className="w-2 h-2 rounded-full bg-accentR animate-pulse" /> 4K · HDR
          </span>
        </div>
      </div>
    </div>
  </section>
);

const BornInMetaverse = () => (
  <section id="story" className="py-24 md:py-32 border-t border-border">
    <div className="mx-auto max-w-7xl px-6 lg:px-8 grid lg:grid-cols-2 gap-12 lg:gap-20 items-center">
      <div className="relative aspect-[4/5] rounded-2xl overflow-hidden light-blur">
        <img src="images/crew-group.jpg" alt="Vibe Den Crew" className="w-full h-full object-cover" />
        <div className="absolute inset-0 bg-gradient-to-t from-bg/40 to-transparent" />
        <div className="absolute top-4 left-4 flex items-center gap-2 text-xs font-mono text-fg/80">
          <span className="w-2 h-2 rounded-full bg-accentB animate-pulse" />
          EST · 2023
        </div>
      </div>
      <div className="space-y-6">
        <Eyebrow>The Story</Eyebrow>
        <GlitchText as="h2" className="text-4xl md:text-6xl font-bold leading-[1.05]">Born in the Metaverse</GlitchText>
        <p className="text-lg text-muted leading-relaxed">
          Vibe Den started as an experiment in virtual artistry. Today, we're a movement — three digital souls connected by a love for electronic music and the endless possibilities of the virtual world.
        </p>
        <div className="grid grid-cols-3 gap-3 pt-4">
          {[['2023', 'Founded'], ['3', 'Artists'], ['∞', 'Possibilities']].map(([v, l]) => (
            <div key={l} className="border-t border-border pt-4">
              <p className="text-2xl md:text-3xl font-mono font-bold">{v}</p>
              <p className="text-xs text-muted uppercase tracking-widest mt-1">{l}</p>
            </div>
          ))}
        </div>
      </div>
    </div>
  </section>
);

const CreatorSection = () => (
  <section id="creator" className="py-24 md:py-32 border-t border-border bg-secondary/20">
    <div className="mx-auto max-w-7xl px-6 lg:px-8 grid lg:grid-cols-2 gap-12 lg:gap-20 items-center">
      <div className="space-y-6 order-2 lg:order-1">
        <Eyebrow>The Creator</Eyebrow>
        <GlitchText as="h2" className="text-4xl md:text-6xl font-bold leading-[1.05]">One vision,<br/>endless possibilities</GlitchText>
        <p className="text-lg text-muted leading-relaxed">
          Vibe Den is a solo creative project where 3D characters, original music, and visual experiences come together. From modeling and animation to production and direction, every element is crafted by a single creator with a passion for blending art and technology.
        </p>
        <ul className="space-y-2 pt-2">
          {['3D Modeling & Animation', 'Music Production', 'Visual Direction', 'Creative Development'].map((d, i) => (
            <li key={d} className="flex items-center gap-3 text-sm">
              <span className={`w-1.5 h-1.5 rounded-full ${i % 3 === 0 ? 'bg-accent' : i % 3 === 1 ? 'bg-accentR' : 'bg-accentB'}`} />
              {d}
            </li>
          ))}
        </ul>
        <div className="flex items-center gap-3 pt-4">
          <span className="text-xs text-muted">Follow:</span>
          {[
            ['Instagram', 'https://www.instagram.com/vibeden_official'],
            ['YouTube', 'https://www.youtube.com/@VIBE_DEN_Official'],
            ['Twitter', '#'],
          ].map(([s, href]) => (
            <a
              key={s}
              href={href}
              target={href.startsWith('http') ? '_blank' : undefined}
              rel={href.startsWith('http') ? 'noopener noreferrer' : undefined}
              className="px-4 py-2 text-xs font-medium border border-border rounded-full hover:bg-secondary transition-all"
            >{s}</a>
          ))}
        </div>
      </div>
      <div className="relative aspect-[4/5] rounded-2xl overflow-hidden order-1 lg:order-2">
        <img src="images/creator-portrait.jpg" alt="Creator" className="w-full h-full object-cover" onError={(e) => { e.currentTarget.src = 'images/dj-character-1.jpg'; }} />
        <div className="absolute inset-0 bg-gradient-to-t from-bg/30 to-transparent" />
      </div>
    </div>
  </section>
);

const Press = () => {
  const [idx, setIdx] = useState(0);
  useEffect(() => {
    const t = setInterval(() => setIdx(p => (p + 1) % window.PRESS.length), 5000);
    return () => clearInterval(t);
  }, []);
  return (
    <section className="mx-auto max-w-7xl px-6 lg:px-8 py-24 md:py-32">
      <div className="max-w-3xl mx-auto text-center">
        <div className="mb-12"><Eyebrow center>Press</Eyebrow></div>
        <div className="relative h-48 md:h-40">
          {window.PRESS.map((q, i) => (
            <div key={i} className={`absolute inset-0 transition-all duration-500 ${idx === i ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-4 pointer-events-none'}`}>
              <blockquote className="text-2xl md:text-3xl leading-relaxed">"{q.text}"</blockquote>
              <div className="mt-8">
                <p className="font-semibold">{q.author}</p>
                <p className="text-sm text-muted">{q.role}</p>
              </div>
            </div>
          ))}
        </div>
        <div className="flex items-center justify-center gap-2 mt-12">
          {window.PRESS.map((_, i) => (
            <button key={i} onClick={() => setIdx(i)} className={`h-1.5 rounded-full transition-all ${idx === i ? 'bg-fg w-8' : 'bg-border w-1.5'}`} />
          ))}
        </div>
      </div>
    </section>
  );
};

// ---------- ARTISTS LIST ----------
const ArtistsPage = () => (
  <section className="pt-32 pb-24 md:pb-32">
    <div className="mx-auto max-w-7xl px-6 lg:px-8">
      <Eyebrow>The Crew</Eyebrow>
      <GlitchText as="h1" className="text-5xl md:text-7xl font-bold mt-4 mb-12">Artists</GlitchText>
      <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
        {window.CREW.map((m, i) => (
          <a key={m.slug} href={`#/artists/${m.slug}`} data-track tabIndex={0} className="group relative bg-secondary/50 rounded-xl overflow-hidden hover:bg-secondary transition-all">
            <div className="relative aspect-[3/4] overflow-hidden">
              <img src={m.image} alt={m.name} className="w-full h-full object-cover transition-transform duration-500 group-hover:scale-105" />
              <div className="absolute inset-0 bg-gradient-to-t from-black/80 via-black/20 to-transparent" />
              <div className="absolute bottom-0 left-0 right-0 p-6">
                <p className="text-xs font-mono text-fg/60 mb-2">{`0${i+1} / 0${window.CREW.length}`}</p>
                <h3 className="text-3xl font-bold mb-1">{m.name}</h3>
                <p className="text-sm text-muted">{m.role}</p>
                <div className="flex items-center gap-4 mt-4 text-xs text-muted">
                  <span>{m.stats.tracks} tracks</span>
                  <span>{m.stats.releases} releases</span>
                  <span>{m.stats.events} events</span>
                </div>
              </div>
            </div>
          </a>
        ))}
      </div>
    </div>
  </section>
);

// ---------- ARTIST DETAIL ----------
const ArtistDetail = ({ slug }) => {
  const m = window.CREW.find(c => c.slug === slug);
  if (!m) return <div className="pt-32 px-6">Not found</div>;
  const albums = window.ALBUMS.filter(a => m.discog.some(d => a.coverUrl.includes(d)));
  return (
    <section className="pt-28 pb-24">
      <div className="mx-auto max-w-7xl px-6 lg:px-8">
        <a href="#/artists" className="text-sm text-muted hover:text-fg transition-colors inline-flex items-center gap-2 mb-10">← Back to Crew</a>
        <div className="grid lg:grid-cols-2 gap-12 lg:gap-20 items-start">
          <div className="aspect-[4/5] rounded-2xl overflow-hidden light-blur sticky top-28">
            <img src={m.image} alt={m.name} className="w-full h-full object-cover" />
          </div>
          <div>
            <p className="text-xs uppercase tracking-widest text-accentR mb-3">{m.role}</p>
            <GlitchText as="h1" className="text-6xl md:text-8xl font-black tracking-tight mb-8">{m.name}</GlitchText>
            <p className="text-lg text-muted leading-relaxed mb-12">{m.bio}</p>
            <div className="grid grid-cols-3 gap-4 mb-12 py-8 border-y border-border">
              {[['Tracks', m.stats.tracks], ['Releases', m.stats.releases], ['Events', m.stats.events]].map(([l, v]) => (
                <div key={l} className="text-center">
                  <p className="text-4xl font-mono font-bold text-fg">{v}</p>
                  <p className="text-xs uppercase tracking-widest text-muted mt-2">{l}</p>
                </div>
              ))}
            </div>
            <h2 className="text-sm uppercase tracking-widest text-muted mb-6">Discography</h2>
            <div className="grid grid-cols-2 gap-4">
              {albums.map(a => (
                <a key={a.id} href="#/discography" data-track tabIndex={0} className="group">
                  <div className="aspect-square rounded-lg overflow-hidden mb-3">
                    <img src={a.coverUrl} alt={a.title} className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500" />
                  </div>
                  <h3 className="font-semibold group-hover:text-accentR transition-colors">{a.title}</h3>
                  <p className="text-sm text-muted">{a.year}</p>
                </a>
              ))}
            </div>
          </div>
        </div>
      </div>
    </section>
  );
};

// ---------- DISCOGRAPHY ----------
const DiscographyPage = () => {
  const [filter, setFilter] = useState('All');
  const filters = ['All', 'Albums', 'EPs', 'Singles'];
  const matched = window.ALBUMS.filter(a => filter === 'All' || a.type + 's' === filter || a.type === filter.slice(0, -1));
  const byYear = matched.reduce((acc, a) => { (acc[a.year] = acc[a.year] || []).push(a); return acc; }, {});
  const years = Object.keys(byYear).sort((a, b) => b.localeCompare(a));
  return (
    <section className="pt-32 pb-24">
      <div className="mx-auto max-w-7xl px-6 lg:px-8">
        <Eyebrow>Music</Eyebrow>
        <GlitchText as="h1" className="text-5xl md:text-7xl font-bold mt-4 mb-10">Discography</GlitchText>
        <div className="flex items-center gap-2 mb-12 border-b border-border pb-4 overflow-x-auto">
          {filters.map(f => (
            <button key={f} onClick={() => setFilter(f)}
              className={`px-4 py-2 text-sm rounded-full transition-all whitespace-nowrap ${filter === f ? 'bg-fg text-bg' : 'text-muted hover:text-fg'}`}>
              {f}
            </button>
          ))}
        </div>
        {years.map(y => (
          <div key={y} className="mb-16">
            <div className="flex items-baseline gap-4 mb-6">
              <h2 className="text-4xl md:text-5xl font-mono font-bold">{y}</h2>
              <div className="h-px flex-1 bg-border" />
              <span className="text-xs text-muted uppercase tracking-widest">{byYear[y].length} releases</span>
            </div>
            <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-4 md:gap-6">
              {byYear[y].map(a => (
                <div key={a.id} data-track role="button" tabIndex={0} className="group cursor-pointer">
                  <div className="relative aspect-square overflow-hidden rounded-lg mb-3">
                    <img src={a.coverUrl} alt={a.title} className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500" />
                    <div className="absolute top-2 left-2 px-2 py-0.5 text-[10px] uppercase tracking-wider bg-bg/80 backdrop-blur-sm rounded">{a.type}</div>
                  </div>
                  <h3 className="font-semibold text-sm truncate group-hover:text-accentB transition-colors">{a.title}</h3>
                  <p className="text-xs text-muted truncate">{a.artist}</p>
                </div>
              ))}
            </div>
          </div>
        ))}
      </div>
    </section>
  );
};

// ---------- MEDIA ----------
const MediaPage = () => {
  const [filter, setFilter] = useState('All');
  const filters = ['All', 'Photos', 'Videos'];
  const items = window.MEDIA.filter(m => filter === 'All' || m.kind === filter.slice(0, -1));
  return (
    <section className="pt-32 pb-24">
      <div className="mx-auto max-w-7xl px-6 lg:px-8">
        <Eyebrow>Gallery</Eyebrow>
        <GlitchText as="h1" className="text-5xl md:text-7xl font-bold mt-4 mb-10">Media</GlitchText>
        <div className="flex items-center gap-2 mb-12 border-b border-border pb-4">
          {filters.map(f => (
            <button key={f} onClick={() => setFilter(f)}
              className={`px-4 py-2 text-sm rounded-full transition-all ${filter === f ? 'bg-fg text-bg' : 'text-muted hover:text-fg'}`}>
              {f}
            </button>
          ))}
        </div>
        <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4 md:gap-6">
          {items.map((item, i) => (
            <div key={i} data-track role="button" tabIndex={0} className="group cursor-pointer relative">
              <div className="relative aspect-square overflow-hidden rounded-xl">
                <img src={item.src} alt={item.title} className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500" />
                <div className="absolute inset-0 bg-black/0 group-hover:bg-black/40 transition-all" />
                <div className="absolute top-3 left-3 px-2 py-1 text-[10px] font-mono uppercase tracking-widest rounded bg-bg/80 backdrop-blur-sm">{item.kind}</div>
                {item.kind === 'Video' && (
                  <div className="absolute inset-0 flex items-center justify-center">
                    <div className="w-12 h-12 rounded-full bg-bg/80 backdrop-blur-sm flex items-center justify-center">
                      <svg viewBox="0 0 24 24" width="20" height="20" fill="currentColor" style={{marginLeft: 2}}><path d="M8 5v14l11-7z"/></svg>
                    </div>
                  </div>
                )}
              </div>
              <p className="mt-3 text-sm font-medium">{item.title}</p>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
};

// ---------- CONNECT ----------
const ConnectPage = () => (
  <section className="pt-32 pb-24">
    <div className="mx-auto max-w-4xl px-6 lg:px-8">
      <Eyebrow>Get In Touch</Eyebrow>
      <GlitchText as="h1" className="text-5xl md:text-7xl font-bold mt-4 mb-6">Connect</GlitchText>
      <p className="text-lg text-muted mb-16 max-w-2xl">For bookings, press, collaborations, and general inquiries. We'd love to hear from you.</p>

      <div className="grid md:grid-cols-2 gap-8 mb-16">
        {[
          { label: 'Booking',       email: 'booking@vibeden.io',  desc: 'Live shows, festivals, club nights' },
          { label: 'Press',         email: 'press@vibeden.io',    desc: 'Interviews, features, press kit'   },
          { label: 'Collaboration', email: 'collab@vibeden.io',   desc: 'Producers, vocalists, visuals'     },
          { label: 'Management',    email: 'mgmt@vibeden.io',     desc: 'Business & partnership inquiries'  },
        ].map(c => (
          <div key={c.label} className="bg-card border border-border rounded-xl p-6 hover:border-accentR/60 transition-all">
            <p className="text-xs uppercase tracking-widest text-muted mb-2">{c.label}</p>
            <p className="font-mono text-accentR text-lg mb-2">{c.email}</p>
            <p className="text-sm text-muted">{c.desc}</p>
          </div>
        ))}
      </div>

      <div className="bg-card border border-border rounded-2xl p-8 md:p-12">
        <h2 className="text-2xl font-bold mb-2">Send a message</h2>
        <p className="text-sm text-muted mb-8">We'll get back to you within 48 hours.</p>
        <div className="grid md:grid-cols-2 gap-4 mb-4">
          <input className="vd-crt-input w-full px-4 py-3 bg-bg border border-border rounded-lg focus:outline-none transition-colors" placeholder="Name" />
          <input className="vd-crt-input w-full px-4 py-3 bg-bg border border-border rounded-lg focus:outline-none transition-colors" placeholder="Email" />
        </div>
        <input className="vd-crt-input w-full px-4 py-3 bg-bg border border-border rounded-lg focus:outline-none transition-colors mb-4" placeholder="Subject" />
        <textarea rows={6} className="vd-crt-input w-full px-4 py-3 bg-bg border border-border rounded-lg focus:outline-none transition-colors mb-4" placeholder="Message" />
        <button className="px-8 py-3 bg-fg text-bg font-medium rounded-full hover:bg-fg/90 transition-all btn-sharp">Send Message →</button>
      </div>
    </div>
  </section>
);

// ---------- THE TOWN ----------
const TheTownPage = () => {
  const [filter, setFilter] = useState('All');
  const [crewFilter, setCrewFilter] = useState('All');
  const community = window.TOWN_COMMUNITY.filter(p => filter === 'All' || p.category === filter);
  const fromCrew = window.TOWN_FROM_CREW.filter(p => crewFilter === 'All' || p.author === crewFilter);
  return (
    <section className="pt-32 pb-24">
      <div className="mx-auto max-w-7xl px-6 lg:px-8">
        <div className="flex items-end justify-between mb-10 flex-wrap gap-4">
          <div>
            <Eyebrow>Community</Eyebrow>
            <GlitchText as="h1" className="text-5xl md:text-7xl font-bold mt-4">The Town</GlitchText>
          </div>
          <button className="px-5 py-3 bg-accentB text-bg font-medium rounded-full text-sm hover:opacity-90 transition-all">+ New Post</button>
        </div>

        {/* From the Crew */}
        <div className="mb-16">
          <div className="flex items-center justify-between mb-6 flex-wrap gap-4">
            <h2 className="text-2xl font-bold">From the Crew</h2>
            <div className="flex items-center gap-2">
              <button onClick={() => setCrewFilter('All')} className={`px-3 py-1.5 text-xs rounded-full transition-all ${crewFilter === 'All' ? 'bg-fg text-bg' : 'text-muted hover:text-fg border border-border'}`}>All</button>
              {window.CREW.map(c => (
                <button key={c.name} onClick={() => setCrewFilter(c.name)} className={`px-2 py-1 text-xs rounded-full transition-all flex items-center gap-2 ${crewFilter === c.name ? 'bg-fg text-bg' : 'text-muted hover:text-fg border border-border'}`}>
                  <img src={c.image} alt={c.name} className="w-5 h-5 rounded-full object-cover" />
                  {c.name}
                </button>
              ))}
            </div>
          </div>
          <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
            {fromCrew.map(p => (
              <article key={p.id} data-track tabIndex={0} className="group bg-card border border-accentB/20 rounded-xl overflow-hidden hover:border-accentB/60 transition-all">
                <div className="relative aspect-[16/10] overflow-hidden">
                  <img src={p.image} alt={p.title} className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500" />
                  <div className="absolute top-3 left-3 px-2 py-1 text-[10px] uppercase tracking-widest rounded bg-accentB text-bg">{p.category}</div>
                </div>
                <div className="p-5">
                  <h3 className="font-semibold mb-2 line-clamp-2">{p.title}</h3>
                  <p className="text-sm text-muted line-clamp-2 mb-4">{p.excerpt}</p>
                  <div className="flex items-center justify-between text-xs">
                    <div className="flex items-center gap-2">
                      <img src={p.avatar} alt={p.author} className="w-7 h-7 rounded-full object-cover" />
                      <div>
                        <p className="font-medium">{p.author}<span className="ml-1 text-[9px] px-1.5 py-0.5 rounded bg-accentB text-bg align-middle">CREW</span></p>
                        <p className="text-muted">{p.time}</p>
                      </div>
                    </div>
                    <div className="flex items-center gap-3 text-muted">
                      <span>♥ {p.likes}</span>
                      <span>💬 {p.comments}</span>
                      <span>↗ {p.shares}</span>
                    </div>
                  </div>
                </div>
              </article>
            ))}
          </div>
        </div>

        {/* Community */}
        <div>
          <div className="flex items-center justify-between mb-6 flex-wrap gap-4">
            <h2 className="text-2xl font-bold">Community</h2>
            <div className="flex items-center gap-2 flex-wrap">
              {window.TOWN_CATEGORIES.map(c => (
                <button key={c.label} onClick={() => setFilter(c.label)}
                  className={`px-3 py-1.5 text-xs rounded-full transition-all flex items-center gap-1.5 ${filter === c.label ? 'bg-fg text-bg' : 'text-muted hover:text-fg border border-border'}`}>
                  {c.label}
                  {c.count !== null && <span className={`text-[10px] ${filter === c.label ? 'text-bg/60' : 'text-muted/60'}`}>{c.count}</span>}
                </button>
              ))}
            </div>
          </div>
          <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
            {community.map(p => (
              <article key={p.id} data-track tabIndex={0} className="group bg-secondary/30 border border-border rounded-xl overflow-hidden hover:border-fg/30 transition-all">
                <div className="relative aspect-[16/10] overflow-hidden">
                  <img src={p.image} alt={p.title} className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500" />
                  <div className="absolute top-3 left-3 px-2 py-1 text-[10px] uppercase tracking-widest rounded bg-bg/80 backdrop-blur-sm">{p.category}</div>
                </div>
                <div className="p-5">
                  <h3 className="font-semibold mb-2 line-clamp-2">{p.title}</h3>
                  <p className="text-sm text-muted line-clamp-2 mb-4">{p.excerpt}</p>
                  <div className="flex items-center justify-between text-xs">
                    <div className="flex items-center gap-2">
                      <div className="w-7 h-7 rounded-full bg-secondary border border-border flex items-center justify-center text-[10px] font-bold">{p.initials}</div>
                      <div>
                        <p className="font-medium">{p.author}</p>
                        <p className="text-muted">{p.time}</p>
                      </div>
                    </div>
                    <div className="flex items-center gap-3 text-muted">
                      <span>♥ {p.likes}</span>
                      <span>💬 {p.comments}</span>
                      <span>↗ {p.shares}</span>
                    </div>
                  </div>
                </div>
              </article>
            ))}
          </div>
          <div className="mt-12 text-center">
            <button className="px-6 py-3 text-sm font-medium border border-border rounded-full hover:bg-secondary transition-all">Load More</button>
          </div>
        </div>
      </div>
    </section>
  );
};

// ---------- footer ----------
const Footer = () => (
  <footer data-no-track className="bg-fg text-bg mt-20">
    <div className="mx-auto max-w-7xl px-6 lg:px-8 py-16 md:py-20">
      <div className="grid grid-cols-2 gap-12 md:grid-cols-4 lg:grid-cols-5">
        <div className="col-span-2 md:col-span-1 lg:col-span-2">
          <span className="text-2xl font-bold tracking-tight">Vibe Den</span>
          <p className="mt-4 max-w-xs text-sm leading-relaxed text-bg/60">
            Virtual DJ Crew pushing the boundaries of music and digital art. Join us in the metaverse.
          </p>
          <div className="flex gap-3 mt-6">
            {[
              ['IG', 'https://www.instagram.com/vibeden_official'],
              ['FB', 'https://www.facebook.com/profile.php?id=61560331666068'],
              ['YT', 'https://www.youtube.com/@VIBE_DEN_Official'],
              ['SP', '#'],
            ].map(([s, href]) => (
              <a
                key={s}
                href={href}
                target={href.startsWith('http') ? '_blank' : undefined}
                rel={href.startsWith('http') ? 'noopener noreferrer' : undefined}
                className="w-10 h-10 rounded-full bg-bg/10 flex items-center justify-center text-xs font-mono hover:bg-bg hover:text-fg transition-all"
              >{s}</a>
            ))}
          </div>
        </div>
        {[
          ['Navigation', [['Home','#/'], ['Crew','#/artists'], ['Events','#/#events'], ['Music','#/discography']]],
          ['Listen',     [['Spotify','#'], ['Apple Music','#'], ['SoundCloud','#'], ['YouTube Music','https://www.youtube.com/@VIBE_DEN_Official']]],
          ['Connect',    [['Discord','#'], ['Booking','#/connect'], ['Press Kit','#'], ['Contact','#/connect']]],
        ].map(([title, links]) => (
          <div key={title}>
            <h4 className="mb-4 text-sm font-medium">{title}</h4>
            <ul className="space-y-3">
              {links.map(([l, h]) => (
                <li key={l}>
                  <a
                    href={h}
                    target={h.startsWith('http') ? '_blank' : undefined}
                    rel={h.startsWith('http') ? 'noopener noreferrer' : undefined}
                    className="text-sm text-bg/60 hover:text-bg transition-colors"
                  >{l}</a>
                </li>
              ))}
            </ul>
          </div>
        ))}
      </div>
    </div>
    <div className="border-t border-bg/10 mx-auto max-w-7xl px-6 lg:px-8 py-6 flex flex-col md:flex-row items-center justify-between gap-4">
      <p className="text-xs text-bg/40">© 2026 Vibe Den. All rights reserved.</p>
      <div className="flex items-center gap-6">
        <a href="#" className="text-xs text-bg/40 hover:text-bg transition-colors">Privacy Policy</a>
        <a href="#" className="text-xs text-bg/40 hover:text-bg transition-colors">Terms of Service</a>
      </div>
    </div>
  </footer>
);

// ---------- HOME composition ----------
const HomePage = () => (
  <React.Fragment>
    <BrandIntro />
    <Hero />
    <CrewSection />
    <EventsSection />
    <ReleasesSection />
    <HorizontalGallery />
    <MerchSection />
    <Editorial />
    <MusicVideoSection />
    <Press />
    <BornInMetaverse />
    <CreatorSection />
  </React.Fragment>
);

Object.assign(window, {
  Nav, Footer, useRoute,
  HomePage, ArtistsPage, ArtistDetail,
  DiscographyPage, MediaPage, ConnectPage, TheTownPage,
});
