// APEX components — header, hero, marquee, product rail, cart drawer
const { useState, useEffect, useRef, useMemo } = React;

/* ---------- ICONS ---------- */
const Icon = {
  Search: ({size=16}) => (
    <svg width={size} height={size} viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.4">
      <circle cx="7" cy="7" r="5" /><path d="M11 11l4 4" />
    </svg>
  ),
  Bag: ({size=16}) => (
    <svg width={size} height={size} viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.4">
      <path d="M3 5h10l-1 9H4L3 5z" /><path d="M6 5V3a2 2 0 0 1 4 0v2" />
    </svg>
  ),
  Account: ({size=16}) => (
    <svg width={size} height={size} viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.4">
      <circle cx="8" cy="6" r="3" /><path d="M2 14c1-3 4-4 6-4s5 1 6 4" />
    </svg>
  ),
  Arrow: ({size=16, dir='right'}) => {
    const r = dir === 'left' ? 180 : dir === 'up' ? -90 : dir === 'down' ? 90 : 0;
    return (
      <svg width={size} height={size} viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.4" style={{transform:`rotate(${r}deg)`}}>
        <path d="M3 8h10M9 4l4 4-4 4" />
      </svg>
    );
  },
  Close: ({size=16}) => (
    <svg width={size} height={size} viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.4">
      <path d="M3 3l10 10M13 3L3 13" />
    </svg>
  ),
  Plus: ({size=12}) => (
    <svg width={size} height={size} viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.4">
      <path d="M6 1v10M1 6h10" />
    </svg>
  ),
  Minus: ({size=12}) => (
    <svg width={size} height={size} viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.4">
      <path d="M1 6h10" />
    </svg>
  ),
  Star: ({size=10}) => (
    <svg width={size} height={size} viewBox="0 0 10 10" fill="currentColor">
      <path d="M5 0l1.2 3.4L10 4l-2.6 2.4L8 10 5 8 2 10l.6-3.6L0 4l3.8-.6z" />
    </svg>
  ),
};

/* ---------- ANNOUNCEMENT BAR ---------- */
const AnnounceBar = () => {
  const items = [
    'DROP 04 — DARK MATTER LIVE',
    'COMPLIMENTARY EXPRESS ON ORDERS > $250',
    'NEXT DROP: 06.14.26 — 21:00 GMT',
    'MEMBERS UNLOCK +15% — JOIN APEX//ACCESS',
  ];
  return (
    <div style={{background:'var(--accent)', color:'#000', height:32, display:'flex', alignItems:'center', overflow:'hidden', fontFamily:'var(--mono)', fontSize:11, letterSpacing:'0.18em', textTransform:'uppercase', fontWeight:500}}>
      <div className="marquee-track">
        {[...Array(2)].map((_,k)=>(
          <React.Fragment key={k}>
            {items.map((it,i)=>(
              <span key={i} style={{display:'inline-flex', alignItems:'center', gap:18}}>
                <span style={{display:'inline-block', width:6, height:6, background:'#000', borderRadius:'50%'}} />
                {it}
              </span>
            ))}
          </React.Fragment>
        ))}
      </div>
    </div>
  );
};

/* ---------- HEADER ---------- */
const Header = ({ cartCount, onOpenCart, onSearch, palette }) => {
  const [scrolled, setScrolled] = useState(false);
  const [menuOpen, setMenuOpen] = useState(false);
  const isMobile = window.useIsMobile();

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

  const navItems = [
    { label: 'SHOP', href: 'shop.html' },
    { label: 'DROP 04', href: 'index.html' },
    { label: 'LOOKBOOK', href: 'lookbook.html' },
    { label: 'JOURNAL', href: 'journal.html' },
    { label: 'STORES', href: '#' },
    { label: 'ACCESS', href: 'access.html' },
  ];

  return (
    <header style={{
      position:'sticky', top:0, zIndex:50,
      background: scrolled || menuOpen ? 'rgba(5,5,5,0.96)' : 'rgba(5,5,5,0.0)',
      backdropFilter: scrolled ? 'blur(10px)' : 'none',
      borderBottom: `1px solid ${scrolled ? 'var(--line)' : 'transparent'}`,
      transition: 'all 0.3s ease',
    }}>
      {isMobile ? (
        <>
          <div style={{display:'flex', alignItems:'center', justifyContent:'space-between', padding:'14px 20px'}}>
            <button
              onClick={() => setMenuOpen(o => !o)}
              aria-label="menu"
              style={{display:'flex', flexDirection:'column', gap:5, padding:4}}
            >
              <span style={{display:'block', width:22, height:1, background: menuOpen ? palette : 'var(--ink)', transition:'all 0.2s', transform: menuOpen ? 'rotate(45deg) translate(4px,4px)' : 'none'}} />
              <span style={{display:'block', width:22, height:1, background: menuOpen ? palette : 'var(--ink)', transition:'all 0.2s', opacity: menuOpen ? 0 : 1}} />
              <span style={{display:'block', width:22, height:1, background: menuOpen ? palette : 'var(--ink)', transition:'all 0.2s', transform: menuOpen ? 'rotate(-45deg) translate(4px,-4px)' : 'none'}} />
            </button>

            <a href="index.html" style={{display:'flex', flexDirection:'column', alignItems:'center', lineHeight:0.85}}>
              <window.GlitchText accent={palette}>
                <span className="display" style={{fontSize:28, color:palette}}>APEX</span>
              </window.GlitchText>
            </a>

            <button onClick={onOpenCart} style={{display:'inline-flex', alignItems:'center', gap:6}}>
              <Icon.Bag size={18} />
              {cartCount > 0 && (
                <span className="mono" style={{fontSize:10, letterSpacing:'0.12em', color:palette}}>
                  ({String(cartCount).padStart(2,'0')})
                </span>
              )}
            </button>
          </div>

          {menuOpen && (
            <nav style={{
              borderTop:'1px solid var(--line)',
              padding:'8px 0 16px',
              display:'flex', flexDirection:'column',
            }}>
              {navItems.map(n => (
                <a
                  key={n.label}
                  href={n.href}
                  onClick={() => setMenuOpen(false)}
                  className="mono upper"
                  style={{
                    display:'block', padding:'14px 20px',
                    fontSize:12, letterSpacing:'0.2em',
                    borderBottom:'1px solid var(--line)',
                    color:'var(--ink)',
                  }}
                >{n.label}</a>
              ))}
              <div style={{padding:'14px 20px', display:'flex', gap:20}}>
                <button onClick={onSearch} style={{display:'inline-flex', alignItems:'center', gap:8}} className="mono upper" style={{fontSize:11, letterSpacing:'0.16em', color:'var(--ink-dim)'}}>
                  <Icon.Search /> SEARCH
                </button>
                <button style={{display:'inline-flex', alignItems:'center', gap:8}} className="mono upper" style={{fontSize:11, letterSpacing:'0.16em', color:'var(--ink-dim)'}}>
                  <Icon.Account /> ACCOUNT
                </button>
              </div>
            </nav>
          )}
        </>
      ) : (
        <div style={{display:'grid', gridTemplateColumns:'1fr auto 1fr', alignItems:'center', padding:'18px 32px', gap:32}}>
          <nav style={{display:'flex', gap:28, fontFamily:'var(--mono)', fontSize:11, letterSpacing:'0.16em'}}>
            {navItems.slice(0,3).map(n => (
              <a key={n.label} href={n.href} className="nav-link upper">{n.label}</a>
            ))}
          </nav>

          <a href="index.html" style={{display:'flex', flexDirection:'column', alignItems:'center', lineHeight:0.85}}>
            <window.GlitchText accent={palette}>
              <span className="display" style={{fontSize:34, color:palette}}>APEX</span>
            </window.GlitchText>
            <span className="mono" style={{fontSize:8, letterSpacing:'0.5em', color:'var(--ink-dim)', marginTop:2}}>BRANDS&nbsp;//&nbsp;EST&nbsp;19</span>
          </a>

          <div style={{display:'flex', justifyContent:'flex-end', alignItems:'center', gap:28}}>
            <nav style={{display:'flex', gap:28, fontFamily:'var(--mono)', fontSize:11, letterSpacing:'0.16em'}}>
              {navItems.slice(3).map(n => (
                <a key={n.label} href={n.href} className="nav-link upper">{n.label}</a>
              ))}
            </nav>
            <div style={{height:18, width:1, background:'var(--line-2)'}} />
            <div style={{display:'flex', gap:18, alignItems:'center'}}>
              <button onClick={onSearch} aria-label="search"><Icon.Search /></button>
              <button aria-label="account"><Icon.Account /></button>
              <button onClick={onOpenCart} style={{display:'inline-flex', alignItems:'center', gap:8}}>
                <Icon.Bag />
                <span className="mono" style={{fontSize:11, letterSpacing:'0.12em'}}>
                  ({String(cartCount).padStart(2,'0')})
                </span>
              </button>
            </div>
          </div>
        </div>
      )}
    </header>
  );
};

/* ---------- HERO PRODUCT VISUAL ---------- */
const HeroProductVisual = ({ palette, accent }) => {
  return (
    <div style={{position:'relative', width:'100%', height:'100%', minHeight:560}} className="grain">
      <div className="hatch" style={{position:'absolute', inset:0}} />

      <div style={{
        position:'absolute', top:'50%', left:'50%', transform:'translate(-50%,-50%)',
        width: 'min(46vw, 560px)', height:'min(46vw, 560px)',
        borderRadius:'50%',
        border: `1px dashed ${accent}`,
        opacity:0.4,
      }} />
      <div style={{
        position:'absolute', top:'50%', left:'50%', transform:'translate(-50%,-50%)',
        width:'min(34vw, 420px)', height:'min(34vw, 420px)',
        borderRadius:'50%',
        background: `radial-gradient(circle at 50% 30%, ${accent}11 0%, transparent 70%)`,
      }} />

      <div style={{
        position:'absolute', top:'50%', left:'50%', transform:'translate(-50%,-46%)',
        width:'min(32vw, 380px)', aspectRatio: '5/6',
        background: `linear-gradient(180deg, #16160f 0%, #0a0a0a 100%)`,
        clipPath: 'polygon(20% 8%, 80% 8%, 96% 22%, 100% 36%, 92% 100%, 8% 100%, 0% 36%, 4% 22%)',
        boxShadow: `inset 0 0 80px rgba(0,0,0,0.8), 0 30px 80px rgba(0,0,0,0.6)`,
      }}>
        <div style={{position:'absolute', left:'50%', top:'10%', bottom:'5%', width:1, background:`${accent}66`}} />
        <div style={{position:'absolute', left:'calc(50% - 4px)', top:'8%', width:8, height:8, background:accent, borderRadius:1}} />
        <div style={{position:'absolute', top:'30%', right:'18%', width:'22%', height:'12%', border:`1px solid #333`, background:'#0d0d0a'}} />
        <div style={{position:'absolute', top:'32%', left:'18%', display:'flex', flexDirection:'column', gap:2}}>
          <span className="mono" style={{fontSize:7, color:accent, letterSpacing:'0.3em'}}>OBJ-04</span>
          <span className="mono" style={{fontSize:7, color:'#666', letterSpacing:'0.3em'}}>VOIDSHELL</span>
        </div>
        <div style={{position:'absolute', left:0, right:0, bottom:0, height:'8%',
          background: 'repeating-linear-gradient(90deg, #0a0a0a 0, #0a0a0a 3px, #1a1a17 3px, #1a1a17 4px)'}} />
      </div>

      <div style={{position:'absolute', top:'18%', right:'8%', display:'flex', alignItems:'flex-start', gap:8}}>
        <span style={{display:'inline-block', width:8, height:8, borderRadius:'50%', background:accent, marginTop:6}} className="pulse" />
        <div style={{borderLeft:`1px solid ${accent}55`, paddingLeft:10, fontFamily:'var(--mono)', fontSize:10, letterSpacing:'0.1em', color:'var(--ink-dim)'}}>
          <div style={{color:accent}}>SPEC // 01</div>
          <div>NYLON RIPSTOP</div>
          <div>440 GSM</div>
        </div>
      </div>

      <div style={{position:'absolute', bottom:'22%', left:'8%', display:'flex', alignItems:'flex-start', gap:8}}>
        <span style={{display:'inline-block', width:8, height:8, borderRadius:'50%', background:accent, marginTop:6}} className="pulse" />
        <div style={{borderLeft:`1px solid ${accent}55`, paddingLeft:10, fontFamily:'var(--mono)', fontSize:10, letterSpacing:'0.1em', color:'var(--ink-dim)'}}>
          <div style={{color:accent}}>SPEC // 02</div>
          <div>HAND ASSEMBLED</div>
          <div>OSAKA, JP</div>
        </div>
      </div>

      {[
        {top:24, left:24, brT:1, brL:1},
        {top:24, right:24, brT:1, brR:1},
        {bottom:24, left:24, brB:1, brL:1},
        {bottom:24, right:24, brB:1, brR:1},
      ].map((p,i)=>(
        <div key={i} style={{position:'absolute', width:18, height:18,
          borderTop: p.brT ? `1px solid ${accent}` : 'none',
          borderRight: p.brR ? `1px solid ${accent}` : 'none',
          borderBottom: p.brB ? `1px solid ${accent}` : 'none',
          borderLeft: p.brL ? `1px solid ${accent}` : 'none',
          top:p.top, left:p.left, right:p.right, bottom:p.bottom}} />
      ))}
    </div>
  );
};

/* ---------- HERO ---------- */
const Hero = ({ accent, onShop }) => {
  const [time, setTime] = useState(new Date());
  const isMobile = window.useIsMobile();

  useEffect(() => {
    const t = setInterval(() => setTime(new Date()), 1000);
    return () => clearInterval(t);
  }, []);
  const tStr = time.toUTCString().split(' ').slice(4,5)[0]?.slice(0,8) || '00:00:00';

  const [parRef, parPos] = window.useMouseParallax(20);
  const spotRef = useRef(null);
  useEffect(() => {
    if (isMobile) return;
    const el = parRef.current; if (!el || !spotRef.current) return;
    const onMove = (e) => {
      const r = el.getBoundingClientRect();
      spotRef.current.style.left = (e.clientX - r.left) + 'px';
      spotRef.current.style.top = (e.clientY - r.top) + 'px';
      spotRef.current.style.opacity = 1;
    };
    const onLeave = () => { if (spotRef.current) spotRef.current.style.opacity = 0; };
    el.addEventListener('mousemove', onMove);
    el.addEventListener('mouseleave', onLeave);
    return () => { el.removeEventListener('mousemove', onMove); el.removeEventListener('mouseleave', onLeave); };
  }, [isMobile]);

  const pad = isMobile ? '32px 20px 28px' : '56px 56px 40px 56px';

  return (
    <section style={{position:'relative', borderTop:'1px solid var(--line)', borderBottom:'1px solid var(--line)'}}>
      <div style={{
        display:'grid',
        gridTemplateColumns: isMobile ? '1fr' : '1.05fr 1fr',
        minHeight: isMobile ? 'auto' : '82vh',
      }}>
        <div style={{
          position:'relative', padding: pad,
          display:'flex', flexDirection:'column', justifyContent:'space-between', gap: isMobile ? 28 : 0,
          borderRight: isMobile ? 'none' : '1px solid var(--line)',
          borderBottom: isMobile ? '1px solid var(--line)' : 'none',
        }}>
          <div style={{display:'flex', justifyContent:'space-between', alignItems:'flex-start'}}>
            <div className="mono" style={{fontSize:10, letterSpacing:'0.18em', color:'var(--ink-dim)', display:'flex', alignItems:'center', gap:10}}>
              <span style={{display:'inline-block', width:6, height:6, borderRadius:'50%', background:accent}} className="pulse" />
              LIVE&nbsp;//&nbsp;{tStr}&nbsp;UTC
            </div>
            <div className="mono" style={{fontSize:10, letterSpacing:'0.18em', color:'var(--ink-dim)', textAlign:'right'}}>
              CHAPTER 04 / 12<br />
              <span style={{color:accent}}>↓ NOW SHOWING</span>
            </div>
          </div>

          <div style={{margin: isMobile ? '0' : '40px 0'}}>
            <div className="mono flicker" style={{fontSize:10, letterSpacing:'0.4em', color:accent, marginBottom:18}}>
              ▶ <window.ScrambleText>OBJ-04 // DARK MATTER</window.ScrambleText>
            </div>
            <h1 className="display" style={{margin:0, lineHeight:0.82, fontSize: isMobile ? 'clamp(72px, 20vw, 120px)' : 'clamp(96px, 13.5vw, 240px)', color:'var(--ink)'}}>
              <span style={{display:'block', overflow:'hidden'}}>
                <window.RevealWords text="FORM" delay={100} />
              </span>
              <span style={{display:'block', overflow:'hidden', color:'transparent', WebkitTextStroke:`1.5px ${accent}`}}>
                <window.RevealWords text="FOLLOWS" delay={260} />
              </span>
              <span style={{display:'inline-flex', alignItems:'center', gap:'0.18em'}}>
                <span style={{display:'inline-block', overflow:'hidden'}}>
                  <window.RevealWords text="FORCE" delay={420} />
                </span>
                <span style={{
                  display:'inline-block', width:'0.55em', height:'0.55em', background:accent, borderRadius:'50%',
                  transform:'translateY(-0.05em)',
                  animation:'pulseDot 1.4s ease-in-out infinite',
                }} />
              </span>
            </h1>
            <window.Reveal delay={620}>
              <p style={{maxWidth:520, marginTop:24, color:'#9a9a92', fontSize: isMobile ? 14 : 15, lineHeight:1.55}}>
                A 14-piece capsule built around weight, weather and the architecture of the body. Hand-assembled in Osaka. Numbered. Limited.
              </p>
            </window.Reveal>
          </div>

          <window.Reveal delay={780}>
            <div style={{display:'flex', flexDirection: isMobile ? 'column' : 'row', alignItems: isMobile ? 'stretch' : 'flex-end', justifyContent:'space-between', gap:24}}>
              <div style={{display:'flex', gap:12, alignItems:'center'}}>
                <button onClick={onShop} className="btn-yellow" data-cursor="ENTER" style={{
                  flex: isMobile ? 1 : 'none',
                  padding: isMobile ? '16px 20px' : '18px 28px', fontSize: isMobile ? 16 : 18,
                  display:'inline-flex', alignItems:'center', justifyContent:'space-between', gap:14,
                }}>
                  <span className="hover-shift">SHOP THE DROP</span> <Icon.Arrow size={14} />
                </button>
                <a href="lookbook.html" className="btn-ghost upper mono" data-cursor="WATCH" style={{padding: isMobile ? '16px 16px' : '18px 22px', fontSize:11, letterSpacing:'0.18em', display:'inline-flex', alignItems:'center'}}>
                  <span className="hover-shift">LOOKBOOK</span>
                </a>
              </div>

              <div style={{display:'flex', gap: isMobile ? 24 : 32}}>
                <div>
                  <div className="mono" style={{fontSize:9, color:'var(--ink-dim)', letterSpacing:'0.2em'}}>PIECES</div>
                  <div className="display" style={{fontSize: isMobile ? 28 : 36, lineHeight:1}}><window.Counter to={14} /></div>
                </div>
                <div>
                  <div className="mono" style={{fontSize:9, color:'var(--ink-dim)', letterSpacing:'0.2em'}}>EDITION</div>
                  <div className="display" style={{fontSize: isMobile ? 28 : 36, lineHeight:1, color:accent}}>/<window.Counter to={240} /></div>
                </div>
                <div>
                  <div className="mono" style={{fontSize:9, color:'var(--ink-dim)', letterSpacing:'0.2em'}}>PRICE FROM</div>
                  <div className="display" style={{fontSize: isMobile ? 28 : 36, lineHeight:1}}>$<window.Counter to={140} /></div>
                </div>
              </div>
            </div>
          </window.Reveal>
        </div>

        {!isMobile && (
          <div ref={parRef} style={{position:'relative', background:'#080807', overflow:'hidden'}}>
            <div ref={spotRef} className="spotlight" style={{opacity:0}} />
            <div style={{
              position:'absolute', inset:0,
              transform:`translate3d(${parPos.x}px, ${parPos.y}px, 0)`,
              transition:'transform 0.3s cubic-bezier(0.2,0.8,0.2,1)',
            }}>
              <HeroProductVisual palette="#fff" accent={accent} />
            </div>
          </div>
        )}
      </div>

      <div style={{height:1, background:'var(--line)'}}>
        <div className="shimmer-bar" style={{height:1, width:'100%'}} />
      </div>
    </section>
  );
};

/* ---------- MARQUEE STRIP ---------- */
const Marquee = ({ accent }) => (
  <div style={{overflow:'hidden', borderBottom:'1px solid var(--line)', background:'#0a0a0a', padding:'18px 0'}}>
    <div className="marquee-track display" style={{fontSize:60, lineHeight:1, letterSpacing:'0.01em'}}>
      {[...Array(2)].map((_, k) => (
        <React.Fragment key={k}>
          {['DARK MATTER','OBJ-04','APEX//ACCESS','OSAKA · LONDON · NYC','HAND ASSEMBLED','LIMITED 240','DARK MATTER','OBJ-04'].map((w,i)=>(
            <span key={i} style={{display:'inline-flex', alignItems:'center', gap:36}}>
              {i % 3 === 1 ? <span style={{color:accent}}>{w}</span> : w}
              <span style={{display:'inline-block', width:10, height:10, background:accent, borderRadius:'50%'}} />
            </span>
          ))}
        </React.Fragment>
      ))}
    </div>
  </div>
);

/* ---------- PRODUCT CARD ---------- */
const ProductMockup = ({ product, accent, hover }) => {
  const isOuter = product.category === 'Outerwear';
  const isFoot = product.category === 'Footwear';
  const isBottom = product.category === 'Bottoms';
  const isTee = product.category === 'Essentials';
  const isHood = product.name.includes('Hood');
  const isCap = product.category === 'Accessories';

  let clip = 'polygon(22% 6%, 78% 6%, 92% 22%, 100% 38%, 92% 100%, 8% 100%, 0% 38%, 8% 22%)';
  if (isFoot) clip = 'polygon(0% 60%, 18% 50%, 36% 38%, 60% 32%, 100% 30%, 100% 100%, 0% 100%)';
  if (isBottom) clip = 'polygon(15% 0%, 85% 0%, 92% 100%, 60% 100%, 50% 30%, 40% 100%, 8% 100%)';
  if (isTee) clip = 'polygon(20% 8%, 36% 4%, 64% 4%, 80% 8%, 95% 20%, 88% 28%, 78% 22%, 78% 100%, 22% 100%, 22% 22%, 12% 28%, 5% 20%)';
  if (isHood) clip = 'polygon(28% 0%, 72% 0%, 86% 14%, 96% 28%, 100% 100%, 0% 100%, 4% 28%, 14% 14%)';
  if (isCap) clip = 'polygon(15% 50%, 25% 30%, 50% 22%, 75% 30%, 85% 50%, 95% 60%, 95% 70%, 5% 70%, 5% 60%)';

  return (
    <div style={{position:'relative', width:'100%', height:'100%'}}>
      <div className="hatch" style={{position:'absolute', inset:0}} />
      <div style={{
        position:'absolute', top:'50%', left:'50%', transform: `translate(-50%, -50%) ${hover ? 'scale(1.04)' : 'scale(1)'}`,
        width:'66%', aspectRatio: isFoot ? '5/3' : isCap ? '3/2' : '4/5',
        background:`linear-gradient(180deg, ${product.palette[1]} 0%, ${product.palette[0]} 100%)`,
        clipPath: clip,
        transition:'transform 0.5s cubic-bezier(0.2, 0.8, 0.2, 1)',
        boxShadow:'inset 0 0 50px rgba(0,0,0,0.6)',
      }}>
        <div style={{position:'absolute', top:'18%', left:'18%', fontFamily:'var(--mono)', fontSize:6, letterSpacing:'0.2em', color: hover ? accent : '#555'}}>
          {product.code}
        </div>
        {!isCap && !isFoot && (
          <div style={{position:'absolute', left:'50%', top:'12%', bottom:'8%', width:1, background:'#222'}} />
        )}
      </div>
      <div style={{position:'absolute', top:14, left:14, fontFamily:'var(--mono)', fontSize:9, color:'var(--ink-dim)', letterSpacing:'0.16em'}}>
        {String(parseInt(product.id.split('-')[1])).padStart(2,'0')} / 08
      </div>
    </div>
  );
};

const ProductCard = ({ product, index, accent, onAdd, onSelect, big }) => {
  const [hover, setHover] = useState(false);
  const [size, setSize] = useState(null);
  const isMobile = window.useIsMobile();
  const tiltRef = (!isMobile && window.useTilt) ? window.useTilt(6) : useRef(null);

  const cardW = isMobile ? 260 : (big ? 480 : 360);
  const cardH = isMobile ? 380 : (big ? 640 : 540);

  return (
    <article
      ref={tiltRef}
      className="pcard"
      style={{ width: cardW, height: cardH, transition:'transform 0.4s cubic-bezier(0.2,0.8,0.2,1), background 0.3s', transformStyle: isMobile ? 'flat' : 'preserve-3d' }}
      onMouseEnter={()=>setHover(true)}
      onMouseLeave={()=>setHover(false)}
    >
      <div style={{position:'absolute', top:14, right:14, zIndex:3, display:'flex', gap:6}}>
        {product.tag && (
          <span className={`chip ${['NEW','HERO'].includes(product.tag) ? 'hot' : ''}`}>
            {product.tag === 'HERO' && <Icon.Star size={9} />}
            {product.tag}
          </span>
        )}
      </div>

      <div style={{position:'relative', width:'100%', height:'70%', overflow:'hidden', cursor:'pointer'}} onClick={()=>onSelect(product)}>
        <ProductMockup product={product} accent={accent} hover={hover} />

        <div className="pcard-overlay" style={{padding:14, background:'linear-gradient(180deg, transparent, rgba(5,5,5,0.95) 30%)'}}>
          <div className="mono upper" style={{fontSize:9, color:'var(--ink-dim)', marginBottom:8, letterSpacing:'0.18em'}}>
            QUICK ADD — SIZE
          </div>
          <div style={{display:'flex', gap:6, flexWrap:'wrap', marginBottom:10}}>
            {product.sizes.map(s => {
              const sold = product.soldOut.includes(s);
              const active = size === s;
              return (
                <button
                  key={s}
                  className={`pill mono ${active?'active':''} ${sold?'sold':''}`}
                  disabled={sold}
                  onClick={(e)=>{e.stopPropagation(); !sold && setSize(s);}}
                  style={{padding:'6px 10px', fontSize:10, letterSpacing:'0.1em', minWidth:36}}
                >{s}</button>
              );
            })}
          </div>
          <button
            disabled={!size}
            onClick={(e)=>{e.stopPropagation(); onAdd(product, size);}}
            className="btn-yellow"
            style={{
              width:'100%', padding:'12px 14px', fontSize:14,
              opacity: size ? 1 : 0.4, cursor: size ? 'pointer' : 'not-allowed',
              display:'inline-flex', alignItems:'center', justifyContent:'space-between',
            }}>
            <span>{size ? `ADD — ${size}` : 'SELECT SIZE'}</span>
            <Icon.Plus />
          </button>
        </div>
      </div>

      <div style={{padding:'18px 18px 16px', display:'flex', flexDirection:'column', gap:6, height:'30%'}}>
        <div className="mono" style={{fontSize:10, color:'var(--ink-dim)', letterSpacing:'0.2em', display:'flex', justifyContent:'space-between'}}>
          <span>{product.code} · {product.category.toUpperCase()}</span>
          <span>{product.fabric.split(' ')[0].toUpperCase()}</span>
        </div>
        <div className="pcard-meta display" style={{fontSize:30, lineHeight:1, color:'var(--ink)'}}>
          {product.name}
        </div>
        <div style={{display:'flex', justifyContent:'space-between', alignItems:'flex-end', marginTop:'auto'}}>
          <div className="mono" style={{fontSize:11, color:'var(--ink)', letterSpacing:'0.08em'}}>
            ${product.price}.00 USD
          </div>
          <div style={{display:'flex', gap:4}}>
            {product.sizes.slice(0,5).map((s,i)=>(
              <span key={i} className="mono" style={{fontSize:8, color: product.soldOut.includes(s) ? '#333' : 'var(--ink-dim)', letterSpacing:'0.1em', textDecoration: product.soldOut.includes(s) ? 'line-through' : 'none'}}>{s}</span>
            )).reduce((acc,x,i)=>acc.concat(i ? [<span key={'d'+i} style={{color:'#333'}}>·</span>, x] : [x]), [])}
          </div>
        </div>
      </div>
    </article>
  );
};

/* ---------- PRODUCT RAIL ---------- */
const ProductRail = ({ accent, onAdd, onSelect, products }) => {
  const railRef = useRef(null);
  const [progress, setProgress] = useState(0);
  const [activeCat, setActiveCat] = useState('all');
  const isMobile = window.useIsMobile();
  const pad = isMobile ? 16 : 56;
  const endCardW = isMobile ? 240 : 360;
  const endCardH = isMobile ? 380 : 540;

  const filtered = useMemo(() => {
    if (activeCat === 'all') return products;
    return products.filter(p => p.category === activeCat);
  }, [activeCat, products]);

  const onScroll = () => {
    if (!railRef.current) return;
    const el = railRef.current;
    const max = el.scrollWidth - el.clientWidth;
    setProgress(max > 0 ? el.scrollLeft / max : 0);
  };

  useEffect(() => {
    const el = railRef.current;
    if (!el) return;
    el.addEventListener('scroll', onScroll, { passive: true });
    onScroll();
    return () => el.removeEventListener('scroll', onScroll);
  }, [filtered]);

  const scrollBy = (dir) => {
    if (!railRef.current) return;
    railRef.current.scrollBy({ left: dir * (isMobile ? 280 : 380), behavior: 'smooth' });
  };

  return (
    <section id="shop" style={{borderBottom:'1px solid var(--line)'}}>
      <div style={{padding:`${pad}px ${pad}px ${Math.round(pad/2)}px`, display:'flex', justifyContent:'space-between', alignItems:'flex-end', gap:16, flexWrap:'wrap'}}>
        <div>
          <div className="mono" style={{fontSize:11, letterSpacing:'0.3em', color:accent, marginBottom:14, display:'flex', alignItems:'center', gap:10}}>
            <span style={{display:'inline-block', width:6, height:6, background:accent, borderRadius:'50%'}} className="pulse" />
            INDEX // 04 — DARK MATTER
          </div>
          <h2 className="display" style={{margin:0, fontSize: isMobile ? 'clamp(48px, 14vw, 80px)' : 'clamp(56px, 7vw, 120px)', lineHeight:0.86}}>
            THE&nbsp;DROP
          </h2>
        </div>

        <div style={{display:'flex', gap:8, alignItems:'center'}}>
          <button onClick={()=>scrollBy(-1)} className="rail-arrow" disabled={progress < 0.01}>
            <Icon.Arrow dir="left" />
          </button>
          <button onClick={()=>scrollBy(1)} className="rail-arrow" disabled={progress > 0.99}>
            <Icon.Arrow />
          </button>
        </div>
      </div>

      <div style={{padding:`0 ${pad}px ${Math.round(pad/2)}px`, display:'flex', gap: isMobile ? 16 : 24, alignItems:'center', flexWrap: isMobile ? 'nowrap' : 'wrap', overflowX: isMobile ? 'auto' : 'visible', borderBottom:'1px solid var(--line)', scrollbarWidth:'none'}}>
        {window.APEX_CATEGORIES.map(c => (
          <button
            key={c.id}
            onClick={()=>setActiveCat(c.id)}
            className="mono"
            style={{
              padding:'10px 0', whiteSpace:'nowrap', flexShrink:0,
              fontSize:11, letterSpacing:'0.2em',
              color: activeCat === c.id ? accent : 'var(--ink-dim)',
              borderBottom: `1px solid ${activeCat === c.id ? accent : 'transparent'}`,
              transition:'all 0.18s ease',
              display:'inline-flex', alignItems:'center', gap:6,
            }}
          >
            {c.label}
            <sup style={{fontSize:8, opacity:0.7}}>{String(c.count).padStart(2,'0')}</sup>
          </button>
        ))}
        {!isMobile && (
          <>
            <div style={{flex:1}} />
            <div className="mono" style={{fontSize:10, letterSpacing:'0.2em', color:'var(--ink-dim)'}}>
              SHOWING {String(filtered.length).padStart(2,'0')} / {String(products.length).padStart(2,'0')} →
            </div>
          </>
        )}
      </div>

      <div ref={railRef} className="rail" style={{borderBottom:'1px solid var(--line)'}}>
        <div style={{width:pad, flex:`0 0 ${pad}px`}} />
        {filtered.map((p, i) => (
          <ProductCard key={p.id} product={p} index={i} accent={accent} onAdd={onAdd} onSelect={onSelect} />
        ))}
        <div style={{
          width:endCardW, height:endCardH, padding:isMobile ? 20 : 32,
          display:'flex', flexDirection:'column', justifyContent:'space-between',
          background: `linear-gradient(180deg, ${accent}11 0%, transparent 60%)`,
          borderRight:'1px solid var(--line)',
        }}>
          <div className="mono" style={{fontSize:10, letterSpacing:'0.3em', color:accent}}>INDEX END</div>
          <div>
            <div className="display" style={{fontSize: isMobile ? 48 : 64, lineHeight:0.9, color:accent}}>NEXT<br/>DROP</div>
            <div className="mono" style={{fontSize:10, color:'var(--ink-dim)', letterSpacing:'0.2em', marginTop:14}}>
              06.14.26 // 21:00 GMT<br/>OBJ-05 // ASH KINGDOM
            </div>
            <a href="access.html" className="btn-ghost upper mono" style={{marginTop:20, padding:'12px 16px', fontSize:11, letterSpacing:'0.2em', display:'inline-flex', alignItems:'center', gap:10}}>
              SET REMINDER <Icon.Arrow size={12} />
            </a>
          </div>
        </div>
        <div style={{width:pad, flex:`0 0 ${pad}px`}} />
      </div>

      <div style={{padding:`0 ${pad}px`, height:48, display:'flex', alignItems:'center', gap:18}}>
        <div className="mono" style={{fontSize:10, color:'var(--ink-dim)', letterSpacing:'0.2em'}}>SCROLL</div>
        <div style={{flex:1, height:1, background:'var(--line-2)', position:'relative'}}>
          <div style={{position:'absolute', left:0, top:-1, height:3, width:`${Math.max(8, progress*100)}%`, background:accent, transition:'width 0.1s linear'}} />
        </div>
        <div className="mono" style={{fontSize:10, color:'var(--ink-dim)', letterSpacing:'0.2em'}}>
          {String(Math.round(progress*100)).padStart(2,'0')}%
        </div>
      </div>
    </section>
  );
};

/* ---------- EDITORIAL SPLIT ---------- */
const Editorial = ({ accent }) => {
  const isMobile = window.useIsMobile();
  const pad = isMobile ? 20 : 56;
  return (
    <section style={{display:'grid', gridTemplateColumns: isMobile ? '1fr' : '1fr 1fr', borderBottom:'1px solid var(--line)'}}>
      <div style={{position:'relative', minHeight: isMobile ? 280 : 560, borderRight: isMobile ? 'none' : '1px solid var(--line)', borderBottom: isMobile ? '1px solid var(--line)' : 'none'}}>
        <div className="hatch" style={{position:'absolute', inset:0}} />
        <div style={{position:'absolute', inset: isMobile ? 20 : 48, border:`1px solid ${accent}33`, padding:24, display:'flex', flexDirection:'column', justifyContent:'space-between'}}>
          <div className="mono" style={{fontSize:10, color:accent, letterSpacing:'0.3em'}}>FILM // 01:24</div>
          <div style={{textAlign:'center'}}>
            <div style={{
              width: isMobile ? 60 : 80, height: isMobile ? 60 : 80, borderRadius:'50%', background:accent, color:'#000',
              display:'inline-flex', alignItems:'center', justifyContent:'center', margin:'0 auto',
              fontFamily:'var(--display)', fontSize: isMobile ? 18 : 24, letterSpacing:'0.05em',
            }}>▶</div>
            <div className="display" style={{fontSize: isMobile ? 36 : 48, marginTop:18, lineHeight:0.9}}>WATCH<br/>THE FILM</div>
          </div>
          <div className="mono" style={{fontSize:10, color:'var(--ink-dim)', letterSpacing:'0.2em', display:'flex', justifyContent:'space-between'}}>
            <span>DIR. K. NAKAMURA</span><span>OSAKA · 2026</span>
          </div>
        </div>
      </div>
      <div style={{padding:`${isMobile ? 32 : 72}px ${pad}px`, display:'flex', flexDirection:'column', justifyContent:'center', gap:20}}>
        <div className="mono" style={{fontSize:11, color:accent, letterSpacing:'0.3em'}}>JOURNAL // 014</div>
        <h3 className="display" style={{fontSize: isMobile ? 'clamp(40px, 11vw, 64px)' : 'clamp(56px, 6vw, 96px)', margin:0, lineHeight:0.88}}>
          THE WEIGHT OF<br/>BLACK GARMENTS.
        </h3>
        <p style={{fontSize: isMobile ? 14 : 16, color:'#9a9a92', maxWidth:520, lineHeight:1.55}}>
          Every Apex piece begins with a single question: how heavy can a garment be before it stops being clothing? Drop 04 lives at that edge — 440gsm shells, oxidized hardware, hand-stitched panels you can feel through your fingertips.
        </p>
        <div style={{display:'flex', gap:24, alignItems:'center', marginTop:4}}>
          <a href="journal.html" className="btn-ghost upper mono" style={{padding:'12px 18px', fontSize:11, letterSpacing:'0.18em', display:'inline-flex', alignItems:'center', gap:10}}>
            READ ESSAY <Icon.Arrow size={12} />
          </a>
          <span className="mono" style={{fontSize:10, color:'var(--ink-dim)', letterSpacing:'0.2em'}}>8 MIN READ</span>
        </div>
      </div>
    </section>
  );
};

/* ---------- ACCESS / NEWSLETTER ---------- */
const Access = ({ accent }) => {
  const [email, setEmail] = useState('');
  const [done, setDone] = useState(false);
  const isMobile = window.useIsMobile();
  const pad = isMobile ? 20 : 56;
  return (
    <section style={{
      padding:`${isMobile ? 48 : 88}px ${pad}px`,
      borderBottom:'1px solid var(--line)',
      background:`radial-gradient(circle at 30% 50%, ${accent}0e 0%, transparent 50%)`,
      position:'relative',
    }}>
      <div style={{display:'grid', gridTemplateColumns: isMobile ? '1fr' : '1.2fr 1fr', gap: isMobile ? 32 : 64, alignItems:'center'}}>
        <div>
          <div className="mono" style={{fontSize:11, letterSpacing:'0.3em', color:accent, marginBottom:14}}>APEX // ACCESS</div>
          <h3 className="display" style={{margin:0, fontSize: isMobile ? 'clamp(56px, 16vw, 96px)' : 'clamp(64px, 8vw, 140px)', lineHeight:0.84}}>
            INSIDE<br/>
            <span style={{color:accent}}>THE GATE.</span>
          </h3>
          <p style={{maxWidth:520, fontSize:15, color:'#9a9a92', marginTop:24, lineHeight:1.55}}>
            Members get drops 24 hours early, +15% off every order, and access to the OBJ-Reserve archive — past pieces brought back, exactly once.
          </p>
        </div>
        <div>
          {!done ? (
            <form onSubmit={(e)=>{e.preventDefault(); if(email) setDone(true);}} style={{display:'flex', flexDirection:'column', gap:14}}>
              <label className="mono upper" style={{fontSize:10, letterSpacing:'0.2em', color:'var(--ink-dim)'}}>
                ENTER EMAIL TO REQUEST ACCESS
              </label>
              <div style={{display:'flex', alignItems:'center', borderBottom:`1px solid ${accent}`, paddingBottom:10}}>
                <input
                  type="email" required value={email}
                  onChange={(e)=>setEmail(e.target.value)}
                  placeholder="you@domain.io"
                  style={{flex:1, background:'transparent', border:0, color:'var(--ink)', fontSize:18, fontFamily:'var(--body)', outline:'none'}}
                />
                <button type="submit" className="display" style={{color:accent, fontSize:24, letterSpacing:'0.05em', display:'inline-flex', alignItems:'center', gap:8}}>
                  REQUEST <Icon.Arrow />
                </button>
              </div>
              <div className="mono" style={{fontSize:9, color:'var(--ink-dim)', letterSpacing:'0.18em', marginTop:6}}>
                BY SUBMITTING YOU AGREE TO THE APEX TERMS &amp; PRIVACY DOCTRINE.
              </div>
            </form>
          ) : (
            <div className="fade-in" style={{border:`1px solid ${accent}`, padding:24}}>
              <div className="mono" style={{fontSize:10, color:accent, letterSpacing:'0.3em', marginBottom:8}}>REQUEST RECEIVED</div>
              <div className="display" style={{fontSize:36, lineHeight:0.95}}>YOU'RE ON THE LIST.</div>
              <div className="mono" style={{fontSize:10, color:'var(--ink-dim)', letterSpacing:'0.2em', marginTop:14}}>
                CONFIRMATION SENT TO {email.toUpperCase()}
              </div>
            </div>
          )}
        </div>
      </div>
    </section>
  );
};

/* ---------- FOOTER ---------- */
const Footer = ({ accent }) => {
  const isMobile = window.useIsMobile();
  const pad = isMobile ? 20 : 56;
  return (
    <footer style={{padding:`${isMobile ? 40 : 56}px ${pad}px ${isMobile ? 24 : 32}px`, borderTop:'1px solid var(--line)'}}>
      <div style={{
        display:'grid',
        gridTemplateColumns: isMobile ? '1fr 1fr' : '2fr 1fr 1fr 1fr 1fr',
        gap: isMobile ? 32 : 48,
        paddingBottom: isMobile ? 32 : 48,
        borderBottom:'1px solid var(--line)',
      }}>
        <div style={{gridColumn: isMobile ? '1 / -1' : 'auto'}}>
          <div className="display" style={{fontSize: isMobile ? 64 : 96, lineHeight:0.85, color:accent}}>APEX</div>
          <div className="mono" style={{fontSize:10, color:'var(--ink-dim)', letterSpacing:'0.3em', marginTop:8}}>BRANDS // EST 19 // OSAKA · LDN · NYC</div>
        </div>
        {[
          ['SHOP', [['New','shop.html'],['Drop 04','index.html'],['Outerwear','shop.html'],['Knitwear','shop.html'],['Footwear','shop.html'],['Archive','shop.html']]],
          ['ABOUT', [['Brand','#'],['Workshop','#'],['Materials','#'],['Press','#']]],
          ['SUPPORT', [['Sizing','#'],['Care','#'],['Repair','#'],['Returns','#'],['FAQ','#']]],
          ['CONNECT', [['Instagram','#'],['Telegram','#'],['Substack','#'],['Discord','#']]],
        ].map(([title, items]) => (
          <div key={title} style={{display:'flex', flexDirection:'column', gap:10}}>
            <div className="mono" style={{fontSize:10, color:'var(--ink-dim)', letterSpacing:'0.3em'}}>{title}</div>
            {items.map(([label, href]) => (
              <a key={label} href={href} style={{fontSize:13}} className="nav-link">{label}</a>
            ))}
          </div>
        ))}
      </div>
      {isMobile ? (
        <div style={{paddingTop:20, fontFamily:'var(--mono)', fontSize:10, color:'var(--ink-dim)', letterSpacing:'0.14em', textTransform:'uppercase', display:'flex', flexDirection:'column', gap:10}}>
          <span>© 2026 APEX BRANDS</span>
          <div style={{display:'flex', gap:16, flexWrap:'wrap'}}>
            <a href="#">Privacy</a><a href="#">Terms</a><a href="#">Cookies</a>
          </div>
        </div>
      ) : (
        <div style={{display:'flex', justifyContent:'space-between', alignItems:'center', paddingTop:24, fontFamily:'var(--mono)', fontSize:10, color:'var(--ink-dim)', letterSpacing:'0.18em', textTransform:'uppercase'}}>
          <span>© 2026 APEX BRANDS · ALL RIGHTS RESERVED</span>
          <span style={{display:'flex', gap:24}}>
            <a href="#">Privacy</a><a href="#">Terms</a><a href="#">Cookies</a><a href="#">Accessibility</a>
          </span>
          <span>USD · ENGLISH ↗</span>
        </div>
      )}
    </footer>
  );
};

/* ---------- CART DRAWER ---------- */
const CartDrawer = ({ open, items, onClose, onQty, onRemove, accent }) => {
  if (!open) return null;
  const subtotal = items.reduce((a,i)=>a + i.product.price * i.qty, 0);
  return (
    <div style={{position:'fixed', inset:0, zIndex:100}}>
      <div className="backdrop fade-in" onClick={onClose} />
      <aside className="cart-slide" style={{
        position:'absolute', right:0, top:0, bottom:0,
        width:'min(520px, 96vw)',
        background:'#0a0a0a',
        borderLeft:'1px solid var(--line)',
        display:'flex', flexDirection:'column',
      }}>
        <div style={{display:'flex', alignItems:'center', justifyContent:'space-between', padding:'20px 24px', borderBottom:'1px solid var(--line)'}}>
          <div style={{display:'flex', alignItems:'baseline', gap:10}}>
            <span className="display" style={{fontSize:32, lineHeight:1}}>BAG</span>
            <span className="mono" style={{fontSize:11, color:'var(--ink-dim)', letterSpacing:'0.2em'}}>
              ({String(items.reduce((a,i)=>a+i.qty,0)).padStart(2,'0')} ITEMS)
            </span>
          </div>
          <button onClick={onClose} aria-label="close" className="btn-ghost" style={{width:36, height:36, display:'inline-flex', alignItems:'center', justifyContent:'center'}}>
            <Icon.Close />
          </button>
        </div>

        <div style={{flex:1, overflowY:'auto'}}>
          {items.length === 0 && (
            <div style={{padding:'80px 24px', textAlign:'center'}}>
              <div className="display" style={{fontSize:48, lineHeight:0.95, color:'var(--ink-dim)'}}>YOUR BAG<br/>IS EMPTY.</div>
              <p className="mono" style={{fontSize:10, color:'var(--ink-dim)', letterSpacing:'0.2em', marginTop:18}}>BUILD A KIT FROM DROP 04</p>
              <button onClick={onClose} className="btn-yellow" style={{marginTop:24, padding:'14px 22px', fontSize:14}}>SHOP THE DROP</button>
            </div>
          )}
          {items.map((it, idx) => (
            <div key={idx} style={{display:'grid', gridTemplateColumns:'92px 1fr', gap:14, padding:'18px 24px', borderBottom:'1px solid var(--line)'}}>
              <div style={{width:92, height:108, position:'relative', overflow:'hidden'}}>
                <ProductMockup product={it.product} accent={accent} hover={false} />
              </div>
              <div style={{display:'flex', flexDirection:'column'}}>
                <div className="mono" style={{fontSize:9, color:'var(--ink-dim)', letterSpacing:'0.2em'}}>{it.product.code}</div>
                <div className="display" style={{fontSize:22, lineHeight:1.05, marginTop:2}}>{it.product.name}</div>
                <div className="mono" style={{fontSize:10, color:'var(--ink-dim)', letterSpacing:'0.16em', marginTop:4}}>SIZE {it.size} · {it.product.fabric.toUpperCase()}</div>
                <div style={{flex:1}} />
                <div style={{display:'flex', justifyContent:'space-between', alignItems:'center', marginTop:8}}>
                  <div style={{display:'flex', alignItems:'center', gap:0, border:'1px solid var(--line-2)'}}>
                    <button onClick={()=>onQty(idx, -1)} style={{width:30, height:28, display:'inline-flex', alignItems:'center', justifyContent:'center'}}><Icon.Minus /></button>
                    <span className="mono" style={{minWidth:24, textAlign:'center', fontSize:12}}>{String(it.qty).padStart(2,'0')}</span>
                    <button onClick={()=>onQty(idx, 1)} style={{width:30, height:28, display:'inline-flex', alignItems:'center', justifyContent:'center'}}><Icon.Plus /></button>
                  </div>
                  <div style={{display:'flex', alignItems:'center', gap:14}}>
                    <span className="mono" style={{fontSize:12}}>${it.product.price * it.qty}.00</span>
                    <button onClick={()=>onRemove(idx)} className="mono upper" style={{fontSize:9, letterSpacing:'0.2em', color:'var(--ink-dim)', textDecoration:'underline'}}>REMOVE</button>
                  </div>
                </div>
              </div>
            </div>
          ))}
        </div>

        {items.length > 0 && (
          <div style={{padding:'18px 24px', borderTop:'1px solid var(--line)', background:'#080808'}}>
            <div style={{display:'flex', justifyContent:'space-between', marginBottom:6, fontSize:13}}>
              <span style={{color:'var(--ink-dim)'}}>Subtotal</span><span>${subtotal}.00</span>
            </div>
            <div style={{display:'flex', justifyContent:'space-between', marginBottom:14, fontSize:13}}>
              <span style={{color:'var(--ink-dim)'}}>Express shipping</span><span style={{color:accent}}>FREE</span>
            </div>
            <div style={{display:'flex', justifyContent:'space-between', alignItems:'baseline', paddingTop:14, borderTop:'1px solid var(--line-2)'}}>
              <span className="mono upper" style={{fontSize:11, letterSpacing:'0.2em'}}>TOTAL</span>
              <span className="display" style={{fontSize:32}}>${subtotal}.00</span>
            </div>
            <button className="btn-yellow" style={{width:'100%', marginTop:18, padding:'18px', fontSize:18, display:'inline-flex', alignItems:'center', justifyContent:'space-between'}}>
              <span>CHECKOUT</span>
              <Icon.Arrow />
            </button>
            <div className="mono" style={{fontSize:9, color:'var(--ink-dim)', letterSpacing:'0.2em', marginTop:10, textAlign:'center'}}>
              SECURED BY APEX // PAY · KLARNA · CRYPTO
            </div>
          </div>
        )}
      </aside>
    </div>
  );
};

/* ---------- TOAST ---------- */
const Toast = ({ msg, accent }) => msg ? (
  <div className="fade-in" style={{
    position:'fixed', bottom:24, left:'50%', transform:'translateX(-50%)',
    background:'#0e0e0e', border:`1px solid ${accent}`,
    padding:'12px 18px', zIndex:200,
    display:'flex', alignItems:'center', gap:10,
  }}>
    <span style={{display:'inline-block', width:6, height:6, background:accent, borderRadius:'50%'}} className="pulse" />
    <span className="mono upper" style={{fontSize:11, letterSpacing:'0.2em'}}>{msg}</span>
  </div>
) : null;

/* ---------- PRODUCT MODAL (focus view) ---------- */
const ProductFocus = ({ product, onClose, onAdd, accent }) => {
  const [size, setSize] = useState(null);
  const isMobile = window.useIsMobile();
  if (!product) return null;
  return (
    <div style={{position:'fixed', inset:0, zIndex:90}}>
      <div className="backdrop fade-in" onClick={onClose} />
      <div className="fade-in" style={{
        position:'absolute',
        inset: isMobile ? '0' : '40px',
        background:'#0a0a0a',
        border: isMobile ? 'none' : '1px solid var(--line)',
        display:'grid',
        gridTemplateColumns: isMobile ? '1fr' : '1.1fr 1fr',
        overflow:'hidden',
      }}>
        {!isMobile && (
          <div style={{position:'relative', borderRight:'1px solid var(--line)'}}>
            <ProductMockup product={product} accent={accent} hover />
            <div style={{position:'absolute', top:18, left:18}} className="mono">
              <span className="chip hot">{product.code}</span>
            </div>
          </div>
        )}
        <div style={{padding: isMobile ? '20px 20px 32px' : 36, display:'flex', flexDirection:'column', gap:12, overflowY:'auto'}}>
          <div style={{display:'flex', justifyContent:'space-between', alignItems:'center'}}>
            <div className="mono" style={{fontSize:10, color:accent, letterSpacing:'0.2em'}}>{product.category.toUpperCase()}</div>
            <button onClick={onClose} className="btn-ghost" style={{width:36, height:36, display:'inline-flex', alignItems:'center', justifyContent:'center'}}><Icon.Close /></button>
          </div>
          {isMobile && (
            <div style={{position:'relative', height:220, flexShrink:0, background:'#0d0d0a', borderBottom:'1px solid var(--line)', margin:'0 -20px'}}>
              <ProductMockup product={product} accent={accent} hover />
            </div>
          )}
          <h3 className="display" style={{fontSize: isMobile ? 56 : 84, lineHeight:0.86, margin:0}}>{product.name}</h3>
          <div className="mono" style={{fontSize:11, color:'var(--ink-dim)', letterSpacing:'0.16em'}}>
            {product.fabric.toUpperCase()} · HAND ASSEMBLED · LIMITED 240
          </div>
          <p style={{color:'#9a9a92', fontSize:14, lineHeight:1.5, marginTop:4}}>{product.desc}</p>

          <div style={{display:'flex', gap: isMobile ? 16 : 32, padding:'12px 0', borderTop:'1px solid var(--line)', borderBottom:'1px solid var(--line)', flexWrap:'wrap'}}>
            {[
              ['WEIGHT', '440 GSM'],
              ['ORIGIN', 'OSAKA, JP'],
              ['LEAD', '14 DAYS'],
              ['EDITION', '/240'],
            ].map(([l,v])=>(
              <div key={l}>
                <div className="mono" style={{fontSize:9, color:'var(--ink-dim)', letterSpacing:'0.2em'}}>{l}</div>
                <div className="display" style={{fontSize:16, marginTop:2}}>{v}</div>
              </div>
            ))}
          </div>

          <div className="mono" style={{fontSize:10, color:'var(--ink-dim)', letterSpacing:'0.2em'}}>SELECT SIZE</div>
          <div style={{display:'flex', gap:6, flexWrap:'wrap'}}>
            {product.sizes.map(s => {
              const sold = product.soldOut.includes(s);
              return (
                <button key={s}
                  className={`pill mono ${size===s?'active':''} ${sold?'sold':''}`}
                  disabled={sold}
                  onClick={()=>!sold && setSize(s)}
                  style={{padding:'10px 14px', fontSize:11, letterSpacing:'0.1em', minWidth:48}}
                >{s}</button>
              );
            })}
          </div>

          <div style={{flex:1}} />

          <div style={{display:'flex', justifyContent:'space-between', alignItems:'baseline', marginTop:8}}>
            <span className="mono upper" style={{fontSize:11, letterSpacing:'0.2em', color:'var(--ink-dim)'}}>PRICE</span>
            <span className="display" style={{fontSize: isMobile ? 36 : 48}}>${product.price}.00</span>
          </div>
          <button
            disabled={!size}
            onClick={()=>{onAdd(product, size); onClose();}}
            className="btn-yellow"
            style={{padding: isMobile ? '16px' : '20px', fontSize: isMobile ? 16 : 20, opacity:size?1:0.4, cursor:size?'pointer':'not-allowed', display:'inline-flex', alignItems:'center', justifyContent:'space-between'}}
          >
            <span>{size ? `ADD TO BAG — ${size}` : 'SELECT A SIZE'}</span>
            <Icon.Arrow size={18} />
          </button>
        </div>
      </div>
    </div>
  );
};

Object.assign(window, {
  Icon, AnnounceBar, Header, Hero, Marquee, ProductRail, Editorial, Access, Footer, CartDrawer, Toast, ProductFocus, ProductCard, ProductMockup,
});
