// components.jsx — Logo, ProductImage (silhouettes), Avatar, OutfitCard, Nav, etc.
// Exports to window for cross-file access.

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

// ─── Product silhouette library ────────────────────────────────────────────
// Each silhouette is drawn into a 100x100 viewBox so it scales to any container.
// Style: monochrome line + soft fill — reads as editorial fashion sketch.

function Silhouette({ kind, tone = '#1a1a18' }) {
  const stroke = tone;
  const fill = 'rgba(26,26,24,0.04)';
  const sw = 1.4;

  const map = {
    tee: (
      <g>
        <path d="M22 22 L34 14 L42 22 Q50 28 58 22 L66 14 L78 22 L72 36 L66 32 L66 82 Q50 86 34 82 L34 32 L28 36 Z"
              fill={fill} stroke={stroke} strokeWidth={sw} strokeLinejoin="round"/>
      </g>
    ),
    'tee-graphic': (
      <g>
        <path d="M22 22 L34 14 L42 22 Q50 28 58 22 L66 14 L78 22 L72 36 L66 32 L66 82 Q50 86 34 82 L34 32 L28 36 Z"
              fill="#fafaf7" stroke={stroke} strokeWidth={sw} strokeLinejoin="round"/>
        <text x="50" y="56" textAnchor="middle" fontSize="9" fontStyle="italic" fontFamily="'Instrument Serif', serif" fill="#c0392b">Consultant</text>
        <text x="50" y="64" textAnchor="middle" fontSize="3.5" fontFamily="ui-monospace, monospace" fill="#8a8580">SOFT MERCH</text>
      </g>
    ),
    'tee-print': (
      <g>
        <path d="M22 22 L34 14 L42 22 Q50 28 58 22 L66 14 L78 22 L72 36 L66 32 L66 82 Q50 86 34 82 L34 32 L28 36 Z"
              fill="#fafaf7" stroke={stroke} strokeWidth={sw} strokeLinejoin="round"/>
        <circle cx="50" cy="56" r="9" fill="none" stroke="#8a8580" strokeWidth="1"/>
        <circle cx="46" cy="54" r="1.2" fill="#1a1a18"/>
        <circle cx="54" cy="54" r="1.2" fill="#1a1a18"/>
        <path d="M44 60 Q50 64 56 60" fill="none" stroke="#1a1a18" strokeWidth="0.8"/>
      </g>
    ),
    longsleeve: (
      <g>
        <path d="M22 22 L34 14 L42 22 Q50 28 58 22 L66 14 L78 22 L74 70 L66 68 L66 88 Q50 92 34 88 L34 68 L26 70 Z"
              fill={fill} stroke={stroke} strokeWidth={sw} strokeLinejoin="round"/>
      </g>
    ),
    hoodie: (
      <g>
        <path d="M22 26 L34 16 Q42 12 50 16 Q58 12 66 16 L78 26 L72 40 L66 36 L66 86 Q50 90 34 86 L34 36 L28 40 Z"
              fill={fill} stroke={stroke} strokeWidth={sw}/>
        <path d="M40 18 Q50 26 60 18 L58 30 Q50 36 42 30 Z" fill="rgba(26,26,24,.08)" stroke={stroke} strokeWidth="1"/>
      </g>
    ),
    jacket: (
      <g>
        <path d="M22 22 L34 14 L42 22 L42 84 L34 86 L28 36 Z" fill={fill} stroke={stroke} strokeWidth={sw}/>
        <path d="M78 22 L66 14 L58 22 L58 84 L66 86 L72 36 Z" fill={fill} stroke={stroke} strokeWidth={sw}/>
        <path d="M42 22 L50 28 L58 22 L58 84 L50 86 L42 84 Z" fill="rgba(26,26,24,.02)" stroke={stroke} strokeWidth={sw}/>
        <line x1="50" y1="34" x2="50" y2="82" stroke={stroke} strokeWidth="0.6" strokeDasharray="1 1.5"/>
      </g>
    ),
    'leather-jacket': (
      <g>
        <path d="M22 22 L34 14 L42 22 L42 84 L34 86 L28 36 Z" fill="#1a1a18" stroke={stroke} strokeWidth={sw}/>
        <path d="M78 22 L66 14 L58 22 L58 84 L66 86 L72 36 Z" fill="#1a1a18" stroke={stroke} strokeWidth={sw}/>
        <path d="M42 22 L52 30 L58 22 L58 84 L50 86 L42 84 Z" fill="#2a2a26" stroke={stroke} strokeWidth={sw}/>
      </g>
    ),
    coat: (
      <g>
        <path d="M22 22 L34 14 L46 22 L46 92 L34 92 L28 36 Z" fill={fill} stroke={stroke} strokeWidth={sw}/>
        <path d="M78 22 L66 14 L54 22 L54 92 L66 92 L72 36 Z" fill={fill} stroke={stroke} strokeWidth={sw}/>
        <line x1="50" y1="22" x2="50" y2="90" stroke={stroke} strokeWidth="0.6"/>
        <circle cx="50" cy="36" r="0.8" fill={stroke}/><circle cx="50" cy="50" r="0.8" fill={stroke}/>
        <circle cx="50" cy="64" r="0.8" fill={stroke}/><circle cx="50" cy="78" r="0.8" fill={stroke}/>
      </g>
    ),
    jeans: (
      <g>
        <path d="M30 12 L70 12 L72 50 L66 92 L54 92 L50 56 L46 92 L34 92 L28 50 Z"
              fill="rgba(40,55,90,.18)" stroke={stroke} strokeWidth={sw} strokeLinejoin="round"/>
        <line x1="50" y1="14" x2="50" y2="54" stroke={stroke} strokeWidth="0.6" strokeDasharray="1 1"/>
        <path d="M34 22 L66 22" stroke={stroke} strokeWidth="0.6"/>
      </g>
    ),
    'jeans-light': (
      <g>
        <path d="M30 12 L70 12 L72 50 L66 92 L54 92 L50 56 L46 92 L34 92 L28 50 Z"
              fill="rgba(120,140,170,.18)" stroke={stroke} strokeWidth={sw}/>
        <line x1="50" y1="14" x2="50" y2="54" stroke={stroke} strokeWidth="0.6" strokeDasharray="1 1"/>
        <path d="M34 22 L66 22" stroke={stroke} strokeWidth="0.6"/>
        <path d="M36 60 Q40 65 38 70" stroke="rgba(26,26,24,.3)" strokeWidth="0.5" fill="none"/>
        <path d="M62 60 Q60 65 62 70" stroke="rgba(26,26,24,.3)" strokeWidth="0.5" fill="none"/>
      </g>
    ),
    pants: (
      <g>
        <path d="M32 14 L68 14 L70 50 L66 92 L54 92 L50 56 L46 92 L34 92 L30 50 Z"
              fill="rgba(110,100,80,.18)" stroke={stroke} strokeWidth={sw}/>
        <line x1="50" y1="14" x2="50" y2="54" stroke={stroke} strokeWidth="0.5"/>
      </g>
    ),
    'pants-white': (
      <g>
        <path d="M32 14 L68 14 L70 50 L66 92 L54 92 L50 56 L46 92 L34 92 L30 50 Z"
              fill="#fafaf7" stroke={stroke} strokeWidth={sw}/>
        <line x1="50" y1="14" x2="50" y2="54" stroke={stroke} strokeWidth="0.4"/>
        <path d="M40 12 L40 4 M60 12 L60 4" stroke={stroke} strokeWidth="0.6"/>
      </g>
    ),
    shorts: (
      <g>
        <path d="M30 18 L70 18 L72 38 L66 58 L54 58 L50 38 L46 58 L34 58 L28 38 Z"
              fill={fill} stroke={stroke} strokeWidth={sw}/>
      </g>
    ),
    sneakers: (
      <g>
        <path d="M18 56 Q26 42 50 44 Q72 46 80 56 Q82 64 78 68 L22 68 Q16 64 18 56 Z"
              fill="rgba(180,140,90,.25)" stroke={stroke} strokeWidth={sw}/>
        <path d="M24 60 Q40 64 56 60 Q70 58 78 60" stroke={stroke} strokeWidth="0.6" fill="none"/>
        <path d="M40 48 L42 56 M48 46 L48 54 M56 47 L54 55" stroke={stroke} strokeWidth="0.5"/>
      </g>
    ),
    loafers: (
      <g>
        <path d="M14 56 Q22 46 50 46 Q74 46 82 56 Q84 64 78 66 L20 66 Q12 64 14 56 Z"
              fill="#1a1a18" stroke={stroke} strokeWidth={sw}/>
        <path d="M28 50 Q50 56 72 50" stroke="rgba(250,249,247,0.4)" strokeWidth="0.6" fill="none"/>
      </g>
    ),
    boots: (
      <g>
        <path d="M30 28 L46 28 L46 60 L72 60 Q78 60 78 68 L72 72 L28 72 L22 68 L26 60 Z"
              fill="#1a1a18" stroke={stroke} strokeWidth={sw}/>
        <line x1="38" y1="32" x2="38" y2="56" stroke="rgba(250,249,247,.3)" strokeWidth="0.4"/>
      </g>
    ),
    sandals: (
      <g>
        <path d="M22 54 Q26 44 50 46 Q72 46 78 56 Q80 64 76 66 L24 66 Q18 64 22 54 Z"
              fill="rgba(110,80,50,.6)" stroke={stroke} strokeWidth={sw}/>
        <path d="M34 50 Q50 56 66 50" stroke="#fafaf7" strokeWidth="1.2" fill="none"/>
        <path d="M40 48 Q50 44 60 48" stroke="#fafaf7" strokeWidth="1.2" fill="none"/>
      </g>
    ),
    heels: (
      <g>
        <path d="M22 54 Q40 40 64 46 L78 52 Q80 60 76 64 L24 64 Q20 60 22 54 Z" fill={fill} stroke={stroke} strokeWidth={sw}/>
        <path d="M70 64 L72 80 L66 80 L64 66" fill={fill} stroke={stroke} strokeWidth={sw}/>
      </g>
    ),
    belt: (
      <g>
        <rect x="8" y="44" width="78" height="14" fill="#1a1a18" stroke={stroke} strokeWidth={sw} rx="2"/>
        <rect x="82" y="40" width="12" height="22" fill="none" stroke={stroke} strokeWidth={sw} rx="2"/>
        <line x1="86" y1="44" x2="86" y2="58" stroke={stroke} strokeWidth="1"/>
      </g>
    ),
    glasses: (
      <g>
        <rect x="14" y="38" width="30" height="24" rx="6" fill="rgba(120,160,200,.18)" stroke={stroke} strokeWidth={sw}/>
        <rect x="56" y="38" width="30" height="24" rx="6" fill="rgba(120,160,200,.18)" stroke={stroke} strokeWidth={sw}/>
        <line x1="44" y1="44" x2="56" y2="44" stroke={stroke} strokeWidth={sw}/>
      </g>
    ),
    hat: (
      <g>
        <path d="M22 60 Q30 30 50 30 Q70 30 78 60" fill={fill} stroke={stroke} strokeWidth={sw}/>
        <ellipse cx="50" cy="62" rx="34" ry="6" fill={fill} stroke={stroke} strokeWidth={sw}/>
      </g>
    ),
    cap: (
      <g>
        <path d="M22 58 Q22 36 50 32 Q78 34 78 58 Z" fill={fill} stroke={stroke} strokeWidth={sw}/>
        <path d="M22 58 L8 64 L8 68 L22 64 Z" fill={fill} stroke={stroke} strokeWidth={sw}/>
      </g>
    ),
    bag: (
      <g>
        <path d="M34 16 Q34 8 50 8 Q66 8 66 16" fill="none" stroke={stroke} strokeWidth={sw}/>
        <rect x="22" y="16" width="56" height="60" rx="4" fill={fill} stroke={stroke} strokeWidth={sw}/>
        <line x1="22" y1="30" x2="78" y2="30" stroke={stroke} strokeWidth="0.6"/>
      </g>
    ),
    watch: (
      <g>
        <rect x="30" y="14" width="40" height="14" fill={fill} stroke={stroke} strokeWidth={sw}/>
        <rect x="30" y="72" width="40" height="14" fill={fill} stroke={stroke} strokeWidth={sw}/>
        <circle cx="50" cy="50" r="20" fill="#1a1a18" stroke={stroke} strokeWidth={sw}/>
        <circle cx="50" cy="50" r="14" fill="#fafaf7"/>
        <line x1="50" y1="50" x2="50" y2="40" stroke={stroke} strokeWidth="1"/>
        <line x1="50" y1="50" x2="58" y2="50" stroke={stroke} strokeWidth="1"/>
      </g>
    ),
    ring: (
      <g>
        <circle cx="50" cy="56" r="24" fill="none" stroke={stroke} strokeWidth="3"/>
        <path d="M40 36 L60 36 L52 26 L48 26 Z" fill="rgba(220,200,160,.4)" stroke={stroke} strokeWidth={sw}/>
      </g>
    ),
    scarf: (
      <g>
        <path d="M18 30 Q50 22 82 30 L78 50 Q50 42 22 50 Z" fill={fill} stroke={stroke} strokeWidth={sw}/>
        <path d="M22 50 L18 90 L34 88 L36 54" fill={fill} stroke={stroke} strokeWidth={sw}/>
        <path d="M78 50 L82 90 L66 88 L64 54" fill={fill} stroke={stroke} strokeWidth={sw}/>
      </g>
    ),
    necklace: (
      <g>
        <path d="M22 18 Q50 56 78 18" fill="none" stroke={stroke} strokeWidth="1.2"/>
        <circle cx="50" cy="54" r="6" fill="rgba(220,200,160,.5)" stroke={stroke} strokeWidth={sw}/>
      </g>
    ),
    dress: (
      <g>
        <path d="M34 14 L66 14 L62 30 L78 90 L22 90 L38 30 Z" fill={fill} stroke={stroke} strokeWidth={sw}/>
      </g>
    ),
    skirt: (
      <g>
        <path d="M30 20 L70 20 L82 88 L18 88 Z" fill={fill} stroke={stroke} strokeWidth={sw}/>
      </g>
    ),
    // "Art" placeholders — color blocks that read as printed artwork
    'art-orange': (
      <g>
        <rect x="10" y="10" width="80" height="80" fill="#fafaf7" stroke={stroke} strokeWidth="0.6"/>
        <rect x="18" y="18" width="64" height="64" fill="#E8521C"/>
        <text x="50" y="56" textAnchor="middle" fontSize="9" fontFamily="'Instrument Serif',serif" fontStyle="italic" fill="#fafaf7">Untitled</text>
      </g>
    ),
    'art-blue': (
      <g>
        <rect x="10" y="10" width="80" height="80" fill="#fafaf7" stroke={stroke} strokeWidth="0.6"/>
        <rect x="18" y="18" width="64" height="64" fill="#7FA4C4"/>
        <path d="M18 60 Q35 50 50 58 Q65 66 82 56 L82 82 L18 82 Z" fill="#3E5E7C"/>
        <circle cx="32" cy="40" r="2" fill="#fafaf7"/><circle cx="56" cy="38" r="2" fill="#fafaf7"/>
      </g>
    ),
    'art-mono': (
      <g>
        <rect x="10" y="10" width="80" height="80" fill="#fafaf7" stroke={stroke} strokeWidth="0.6"/>
        <rect x="18" y="18" width="64" height="64" fill="#1a1a18"/>
        <text x="50" y="50" textAnchor="middle" fontSize="6" fontFamily="ui-monospace,monospace" fill="#fafaf7">— ALINE —</text>
        <text x="50" y="60" textAnchor="middle" fontSize="4" fontFamily="ui-monospace,monospace" fill="#8a8580">studio print</text>
      </g>
    ),
    'art-red': (
      <g>
        <rect x="10" y="10" width="80" height="80" fill="#D62828"/>
        <path d="M44 26 L56 26 L56 42 L72 42 L72 54 L56 54 L56 78 L44 78 L44 54 L28 54 L28 42 L44 42 Z" fill="#1a3a8a"/>
      </g>
    ),
    'art-yellow': (
      <g>
        <rect x="10" y="10" width="80" height="80" fill="#F2B233"/>
        <ellipse cx="62" cy="58" rx="22" ry="14" fill="#C73E1D"/>
        <path d="M48 56 L52 70 L56 56 Z" fill="#1a1a18"/>
      </g>
    ),
    'art-portrait': (
      <g>
        <rect x="10" y="10" width="80" height="80" fill="#0d0d0d"/>
        <ellipse cx="50" cy="46" rx="18" ry="22" fill="#fafaf7" opacity="0.92"/>
        <ellipse cx="44" cy="42" rx="1.5" ry="2.5" fill="#0d0d0d"/>
        <ellipse cx="56" cy="42" rx="1.5" ry="2.5" fill="#0d0d0d"/>
        <path d="M42 56 Q50 62 58 56" stroke="#0d0d0d" strokeWidth="1.2" fill="none"/>
        <text x="50" y="84" textAnchor="middle" fontSize="5" fontFamily="'Instrument Serif',serif" fontStyle="italic" fill="#fafaf7">EROTICA</text>
      </g>
    ),
    jersey: (
      <g>
        <path d="M22 22 L34 14 L42 22 Q50 28 58 22 L66 14 L78 22 L72 36 L66 32 L66 82 Q50 86 34 82 L34 32 L28 36 Z"
              fill="rgba(216,52,52,0.92)" stroke={stroke} strokeWidth={sw} strokeLinejoin="round"/>
        <path d="M34 32 L66 32" stroke="rgba(250,249,247,.45)" strokeWidth="0.8"/>
        <path d="M28 38 L72 38" stroke="rgba(250,249,247,.3)" strokeWidth="0.5"/>
        <text x="50" y="62" textAnchor="middle" fontSize="16" fontWeight="700" fill="#fafaf7" fontFamily="ui-monospace,monospace">10</text>
      </g>
    ),
    cargo: (
      <g>
        <path d="M30 14 L70 14 L72 50 L66 92 L54 92 L50 56 L46 92 L34 92 L28 50 Z"
              fill="rgba(70,75,55,0.32)" stroke={stroke} strokeWidth={sw}/>
        <line x1="50" y1="14" x2="50" y2="54" stroke={stroke} strokeWidth="0.4"/>
        <rect x="30" y="46" width="10" height="14" fill="rgba(70,75,55,0.5)" stroke={stroke} strokeWidth="0.6"/>
        <rect x="60" y="46" width="10" height="14" fill="rgba(70,75,55,0.5)" stroke={stroke} strokeWidth="0.6"/>
        <line x1="30" y1="50" x2="40" y2="50" stroke={stroke} strokeWidth="0.4"/>
        <line x1="60" y1="50" x2="70" y2="50" stroke={stroke} strokeWidth="0.4"/>
      </g>
    ),
    beanie: (
      <g>
        <path d="M22 54 Q22 22 50 22 Q78 22 78 54 Z" fill={fill} stroke={stroke} strokeWidth={sw}/>
        <rect x="22" y="50" width="56" height="16" fill="rgba(26,26,24,.1)" stroke={stroke} strokeWidth={sw}/>
        <path d="M30 50 L30 64 M40 50 L40 64 M50 50 L50 64 M60 50 L60 64 M70 50 L70 64" stroke="rgba(26,26,24,.3)" strokeWidth="0.5"/>
        <circle cx="50" cy="20" r="2.5" fill={fill} stroke={stroke} strokeWidth={sw}/>
      </g>
    ),
    tote: (
      <g>
        <path d="M28 24 Q28 8 38 8 Q44 14 44 24" fill="none" stroke={stroke} strokeWidth="1.2"/>
        <path d="M56 24 Q56 8 62 8 Q72 8 72 24" fill="none" stroke={stroke} strokeWidth="1.2"/>
        <path d="M22 24 L78 24 L72 86 L28 86 Z" fill="#FAFAF7" stroke={stroke} strokeWidth={sw}/>
        <text x="50" y="58" textAnchor="middle" fontSize="6" fontFamily="ui-monospace,monospace" fill="#8a8580" letterSpacing="0.1em">CANVAS</text>
      </g>
    ),
    polaroid: (
      <g>
        <rect x="20" y="14" width="60" height="72" fill="#fafaf7" stroke={stroke} strokeWidth={sw}/>
        <rect x="26" y="20" width="48" height="44" fill="rgba(110,130,150,0.55)"/>
        <ellipse cx="42" cy="36" rx="6" ry="5" fill="rgba(250,249,247,0.55)"/>
        <path d="M26 64 Q40 56 58 58 Q70 60 74 64 L74 64 L26 64 Z" fill="rgba(70,90,110,0.4)"/>
        <text x="50" y="78" textAnchor="middle" fontSize="5.5" fontFamily="'Instrument Serif',serif" fontStyle="italic" fill="#5a5550">Sunday afternoon</text>
      </g>
    ),
    trail: (
      <g>
        <path d="M12 56 Q22 40 50 42 Q74 44 86 58 Q88 70 82 72 L16 72 Q10 68 12 56 Z"
              fill="rgba(40,42,38,0.88)" stroke={stroke} strokeWidth={sw}/>
        <path d="M16 64 L82 64" stroke="rgba(250,249,247,.45)" strokeWidth="0.8"/>
        <path d="M14 70 L20 70 M24 70 L30 70 M34 70 L40 70 M44 70 L50 70 M54 70 L60 70 M64 70 L70 70 M74 70 L80 70" stroke="rgba(250,249,247,.65)" strokeWidth="1.2"/>
        <path d="M48 46 L48 56 M58 44 L56 56 M40 48 L42 56" stroke="rgba(250,249,247,.4)" strokeWidth="0.6"/>
        <circle cx="22" cy="52" r="3" fill="rgba(216,80,40,0.85)"/>
      </g>
    ),
  };

  return (
    <svg viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet" style={{ width: '100%', height: '100%', display: 'block' }}>
      {map[kind] || map.tee}
    </svg>
  );
}

// ─── Avatar (initial-based, soft tone) ─────────────────────────────────────
function Avatar({ creator, size = 32 }) {
  if (!creator) return null;
  const hue = (creator.handle?.charCodeAt(0) || 0) * 17 % 360;
  const [broken, setBroken] = useState(false);
  const src = !broken && creator.avatarUrl ? creator.avatarUrl : null;
  return (
    <div style={{
      width: size, height: size, borderRadius: '50%',
      background: `oklch(0.82 0.04 ${hue})`,
      color: '#1a1a18',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      fontFamily: "'Instrument Serif', serif", fontStyle: 'italic',
      fontSize: size * 0.5, lineHeight: 1, flexShrink: 0,
      letterSpacing: '0.01em', overflow: 'hidden',
    }}>
      {/* An uploaded picture when there is one; the initial otherwise, and
          again if the image fails to load rather than a broken-image icon. */}
      {src
        ? <img src={src} alt="" loading="lazy" onError={() => setBroken(true)}
               style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }}/>
        : creator.avatar}
    </div>
  );
}

// ─── Product image (real photo or silhouette fallback) ────────────────────
// Raw store photos (.jpg/.webp on white) are run through DripcheckBG to produce
// a true transparent cutout so only the product shows. Already-transparent
// items (data: PNGs / transparentImage) render as-is.
function ProductImage({ item, shadow = true }) {
  const [src, setSrc] = React.useState(() => {
    if (!item || !item.image) return null;
    if (item.transparentImage) return item.transparentImage;
    return item.image;
  });
  const alreadyClean = !!item?.transparentImage || (item?.image || '').startsWith('data:');
  const [cut, setCut] = React.useState(alreadyClean);

  React.useEffect(() => {
    if (!item || !item.image || alreadyClean) { setSrc(item?.transparentImage || item?.image || null); setCut(alreadyClean); return; }
    let alive = true;
    setSrc(item.image); setCut(false);
    if (window.DripcheckBG) {
      window.DripcheckBG.removeBackground(item.image)
        .then(png => { if (alive && png) { setSrc(png); setCut(true); } })
        .catch(() => {});
    }
    return () => { alive = false; };
  }, [item && item.image, item && item.transparentImage]);

  if (item && item.image) {
    return <img src={src} alt={item.name}
                draggable={false}
                style={{
                  width: '100%', height: '100%', objectFit: 'contain', display: 'block',
                  mixBlendMode: cut ? 'normal' : 'multiply',
                  filter: shadow ? 'drop-shadow(0 6px 14px rgba(20,20,18,0.10))' : 'none',
                }}/>;
  }
  return <Silhouette kind={item?.kind}/>;
}

// ─── Outfit board (visual collage of items at percent coords) ──────────────
function OutfitBoard({ outfit, interactive = false, scale = 1 }) {
  return (
    <div style={{ position: 'relative', width: '100%', aspectRatio: '1 / 1', background: '#FAFAF7' }}>
      {outfit.items.map((it) => (
        <div key={it.id}
             style={{
               position: 'absolute',
               left: `${it.x}%`, top: `${it.y}%`,
               width: `${it.w}%`, height: `${it.h}%`,
               transform: `rotate(${it.rot}deg)`,
               transformOrigin: 'center',
             }}>
          <ProductImage item={it} shadow={!!it.image}/>
        </div>
      ))}
    </div>
  );
}

// ─── Outfit card (used on home + explore + profile grids) ──────────────────
function OutfitCard({ outfit, onClick, density = 'regular' }) {
  const [hover, setHover] = useState(false);
  const [saved, setSaved] = useState(false);

  return (
    <div
      onClick={onClick}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      style={{
        position: 'relative', cursor: 'pointer',
        borderRadius: 14, overflow: 'hidden',
        background: '#FAFAF7',
        boxShadow: hover
          ? '0 24px 60px -20px rgba(20,20,18,0.18), 0 2px 0 rgba(20,20,18,0.04)'
          : '0 12px 36px -18px rgba(20,20,18,0.10), 0 1px 0 rgba(20,20,18,0.04)',
        transition: 'box-shadow .35s ease, transform .35s ease',
        transform: hover ? 'translateY(-2px)' : 'translateY(0)',
      }}>
      <OutfitBoard outfit={outfit} />
      {/* Bottom gradient + button */}
      <div style={{
        position: 'absolute', left: 0, right: 0, bottom: 0, height: '38%',
        background: 'linear-gradient(to top, rgba(250,249,247,0.96) 0%, rgba(250,249,247,0.78) 35%, rgba(250,249,247,0) 100%)',
        pointerEvents: 'none',
      }}/>
      <div style={{
        position: 'absolute', left: 14, right: 14, bottom: 14,
        display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between',
        gap: 10,
      }}>
        {/* No byline: these example boards have no author, and inventing one
            was the point of the demo-creator data that used to live here. */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 0 }}>
          <div style={{ minWidth: 0 }}>
            <div style={{ fontSize: 12, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', fontFamily: "'Instrument Serif',serif", fontStyle: 'italic' }}>{outfit.title}</div>
            {outfit.mood && (
              <div style={{ fontSize: 10, color: '#8a8580', letterSpacing: '0.08em', textTransform: 'uppercase' }}>{outfit.mood}</div>
            )}
          </div>
        </div>
        <button
          onClick={(e) => { e.stopPropagation(); onClick?.(); }}
          style={{
            appearance: 'none', border: '1px solid #1a1a18', background: '#1a1a18',
            color: '#FAFAF7', fontSize: 10.5, padding: '8px 12px',
            letterSpacing: '0.14em', textTransform: 'uppercase', fontWeight: 500,
            borderRadius: 999, cursor: 'pointer', whiteSpace: 'nowrap',
            transition: 'background .2s, color .2s',
          }}>View Outfit</button>
      </div>
      {/* Top-right: save + share */}
      <div style={{
        position: 'absolute', top: 12, right: 12,
        display: 'flex', gap: 6,
        opacity: hover ? 1 : 0, transition: 'opacity .2s',
      }}>
        <IconButton title="Save" onClick={(e) => { e.stopPropagation(); setSaved(!saved); }} active={saved}>
          <svg width="14" height="14" viewBox="0 0 24 24" fill={saved ? '#1a1a18' : 'none'} stroke="#1a1a18" strokeWidth="1.6"><path d="M6 4h12v17l-6-4-6 4z"/></svg>
        </IconButton>
        <IconButton title="Share" onClick={(e) => e.stopPropagation()}>
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#1a1a18" strokeWidth="1.6"><path d="M4 12v7h16v-7M16 6l-4-4-4 4M12 2v14"/></svg>
        </IconButton>
      </div>
      {/* Mood tag */}
      <div style={{
        position: 'absolute', top: 12, left: 12,
        fontSize: 9.5, letterSpacing: '0.16em', textTransform: 'uppercase',
        padding: '4px 8px', borderRadius: 999,
        background: 'rgba(250,249,247,0.86)', color: '#1a1a18',
        backdropFilter: 'blur(6px)',
      }}>{outfit.mood}</div>
    </div>
  );
}

function IconButton({ children, onClick, title, active }) {
  return (
    <button onClick={onClick} title={title} style={{
      width: 30, height: 30, borderRadius: '50%',
      border: 'none',
      background: active ? '#FAFAF7' : 'rgba(250,249,247,0.86)',
      backdropFilter: 'blur(6px)',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      cursor: 'pointer', padding: 0,
      boxShadow: '0 1px 6px rgba(20,20,18,0.08)',
    }}>{children}</button>
  );
}

// ─── Logo wordmark ─────────────────────────────────────────────────────────
function Logo({ size = 18, onClick }) {
  return (
    <div onClick={onClick} style={{
      cursor: onClick ? 'pointer' : 'default',
      fontSize: size, letterSpacing: '-0.02em', fontWeight: 500,
      display: 'flex', alignItems: 'baseline', gap: 0,
      color: '#1a1a18', userSelect: 'none',
    }}>
      <span>modaBoard</span>
      <span style={{ width: 5, height: 5, borderRadius: '50%', background: '#1a1a18', marginLeft: 2, transform: 'translateY(-1px)', display: 'inline-block' }}/>
    </div>
  );
}

// ─── Top nav ───────────────────────────────────────────────────────────────
function Nav({ screen, go, signedIn, onSignOut, onStudio }) {
  const [menuOpen, setMenuOpen] = useState(false);
  const items = [
    { id: 'home', label: 'Home' },
    { id: 'explore', label: 'Explore' },
    { id: 'creators', label: 'Creators' },
    { id: 'brands', label: 'Brands' },
  ];
  const goClose = (s) => { setMenuOpen(false); go(s); };

  return (
    <nav style={{
      position: 'sticky', top: 0, zIndex: 50,
      background: 'rgba(250,249,247,0.86)',
      backdropFilter: 'blur(16px) saturate(140%)',
      borderBottom: '1px solid rgba(20,20,18,0.06)',
    }}>
      {/* Desktop bar */}
      <div className="dc-nav-desktop" style={{
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        padding: '18px 40px',
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 36 }}>
          <Logo onClick={() => go({ name: 'home' })}/>
          <div style={{ display: 'flex', gap: 22 }}>
            {items.map(it => (
              <button key={it.id}
                onClick={() => go({ name: it.id })}
                style={{
                  appearance: 'none', border: 'none', background: 'transparent',
                  padding: 0, cursor: 'pointer',
                  fontSize: 12, letterSpacing: '0.14em', textTransform: 'uppercase',
                  fontWeight: 500,
                  color: screen.name === it.id ? '#1a1a18' : '#8a8580',
                  fontFamily: 'inherit',
                }}>{it.label}</button>
            ))}
          </div>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
          {signedIn && (
            <button onClick={onStudio} style={{
              appearance: 'none', border: 'none', background: 'transparent', cursor: 'pointer', padding: 0,
              fontSize: 12, letterSpacing: '0.14em', textTransform: 'uppercase', fontWeight: 500,
              color: '#1a1a18', fontFamily: 'inherit',
              display: 'inline-flex', alignItems: 'center', gap: 6,
            }}>
              <span style={{ width: 6, height: 6, borderRadius: '50%', background: '#1a6b3a' }}/>
              Studio
            </button>
          )}
          {signedIn && (
            <button onClick={() => go({ name: 'myoutfits' })} style={{
              appearance: 'none', border: 'none', background: 'transparent', cursor: 'pointer', padding: 0,
              fontSize: 12, letterSpacing: '0.14em', textTransform: 'uppercase', fontWeight: 500,
              color: screen.name === 'myoutfits' ? '#1a1a18' : '#8a8580', fontFamily: 'inherit',
            }}>My outfits</button>
          )}
          <button onClick={() => go({ name: signedIn ? 'dashboard' : 'login' })} style={{
            appearance: 'none', border: '1px solid rgba(20,20,18,0.18)', background: 'transparent',
            color: '#1a1a18', fontSize: 11.5, padding: '9px 14px',
            letterSpacing: '0.14em', textTransform: 'uppercase', fontWeight: 500,
            borderRadius: 999, cursor: 'pointer',
          }}>Create outfit</button>
          {signedIn ? (
            <>
              <button onClick={onStudio} title="Open your Studio" style={{
                appearance: 'none', border: 'none', background: 'transparent', cursor: 'pointer',
                display: 'flex', alignItems: 'center', gap: 8, padding: 0,
              }}>
                <Avatar creator={navCreator()} size={32}/>
              </button>
              <button onClick={() => onSignOut?.()} style={{
                appearance: 'none', border: 'none', background: 'transparent', cursor: 'pointer', padding: 0,
                fontSize: 11.5, letterSpacing: '0.14em', textTransform: 'uppercase', fontWeight: 500,
                color: '#8a8580', fontFamily: 'inherit',
              }}>Log out</button>
            </>
          ) : (
            <>
              <button onClick={() => go({ name: 'login' })} style={{
                appearance: 'none', border: 'none', background: 'transparent', cursor: 'pointer', padding: 0,
                fontSize: 11.5, letterSpacing: '0.14em', textTransform: 'uppercase', fontWeight: 500,
                color: '#1a1a18', fontFamily: 'inherit',
              }}>Log in</button>
              <button onClick={() => go({ name: 'signup' })} style={{
                appearance: 'none', border: 'none', background: '#1a1a18',
                color: '#FAFAF7', fontSize: 11.5, padding: '9px 16px',
                letterSpacing: '0.14em', textTransform: 'uppercase', fontWeight: 500,
                borderRadius: 999, cursor: 'pointer',
              }}>Sign up</button>
            </>
          )}
        </div>
      </div>

      {/* Mobile bar */}
      <div className="dc-nav-mobile" style={{
        alignItems: 'center', justifyContent: 'space-between',
        padding: '14px 18px',
      }}>
        <Logo onClick={() => go({ name: 'home' })}/>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <button onClick={() => go({ name: 'explore' })} title="Search" style={{
            appearance: 'none', border: '1px solid rgba(20,20,18,0.12)', background: 'transparent',
            width: 40, height: 40, borderRadius: '50%', cursor: 'pointer',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#1a1a18" strokeWidth="1.8"><circle cx="11" cy="11" r="7"/><path d="M21 21l-5-5"/></svg>
          </button>
          <button onClick={() => setMenuOpen(true)} title="Menu" style={{
            appearance: 'none', border: '1px solid rgba(20,20,18,0.12)', background: 'transparent',
            width: 40, height: 40, borderRadius: '50%', cursor: 'pointer',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#1a1a18" strokeWidth="1.8"><path d="M3 6h18M3 12h18M3 18h18"/></svg>
          </button>
        </div>
      </div>

      {/* Mobile drawer */}
      {menuOpen && (
        <div onClick={() => setMenuOpen(false)} style={{
          position: 'fixed', inset: 0, zIndex: 120, background: 'rgba(20,20,18,0.4)',
        }}>
          <div onClick={(e) => e.stopPropagation()} style={{
            position: 'absolute', top: 0, right: 0, bottom: 0, width: 'min(86vw, 360px)',
            background: '#FAFAF7', padding: '20px 22px',
            display: 'flex', flexDirection: 'column', gap: 4,
            boxShadow: '-20px 0 60px rgba(20,20,18,0.18)',
            animation: 'dc-drawer-in .26s ease',
          }}>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 18 }}>
              <Logo size={18}/>
              <button onClick={() => setMenuOpen(false)} style={{
                appearance: 'none', border: 'none', background: 'transparent', cursor: 'pointer',
                fontSize: 26, lineHeight: 1, color: '#1a1a18', padding: 4,
              }}>×</button>
            </div>
            {items.map(it => (
              <button key={it.id} onClick={() => goClose({ name: it.id })} style={{
                appearance: 'none', border: 'none', background: 'transparent', cursor: 'pointer',
                textAlign: 'left', padding: '14px 6px', fontFamily: 'inherit',
                fontSize: 22, letterSpacing: '-0.02em', fontWeight: 400,
                color: screen.name === it.id ? '#1a1a18' : '#5a5a54',
                borderBottom: '1px solid rgba(20,20,18,0.06)',
              }}>{it.label}</button>
            ))}
            <button onClick={() => goClose({ name: 'contact' })} style={{
              appearance: 'none', border: 'none', background: 'transparent', cursor: 'pointer',
              textAlign: 'left', padding: '14px 6px', fontFamily: 'inherit',
              fontSize: 22, letterSpacing: '-0.02em', color: '#5a5a54',
              borderBottom: '1px solid rgba(20,20,18,0.06)',
            }}>Contact</button>

            <div style={{ marginTop: 22, display: 'flex', flexDirection: 'column', gap: 10 }}>
              <button onClick={() => goClose({ name: signedIn ? 'dashboard' : 'login' })} style={{
                appearance: 'none', border: '1px solid rgba(20,20,18,0.18)', background: 'transparent',
                color: '#1a1a18', fontSize: 12, padding: '14px 18px',
                letterSpacing: '0.14em', textTransform: 'uppercase', fontWeight: 500,
                borderRadius: 999, cursor: 'pointer',
              }}>Create outfit</button>
              {signedIn && (
                <button onClick={() => goClose({ name: 'myoutfits' })} style={{
                  appearance: 'none', border: '1px solid rgba(20,20,18,0.18)', background: 'transparent',
                  color: '#1a1a18', fontSize: 12, padding: '14px 18px',
                  letterSpacing: '0.14em', textTransform: 'uppercase', fontWeight: 500,
                  borderRadius: 999, cursor: 'pointer',
                }}>My outfits</button>
              )}
              {signedIn ? (
                <>
                  <button onClick={() => { setMenuOpen(false); onStudio(); }} style={{
                    appearance: 'none', border: 'none', background: '#1a1a18', color: '#FAFAF7',
                    fontSize: 12, padding: '14px 18px', letterSpacing: '0.14em', textTransform: 'uppercase',
                    fontWeight: 500, borderRadius: 999, cursor: 'pointer',
                    display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8,
                  }}><span style={{ width: 6, height: 6, borderRadius: '50%', background: '#7fd1a0' }}/> Open Studio</button>
                  <button onClick={() => { setMenuOpen(false); onSignOut?.(); }} style={{
                    appearance: 'none', border: 'none', background: 'transparent', color: '#8a8580',
                    fontSize: 12, padding: '8px', letterSpacing: '0.12em', textTransform: 'uppercase',
                    cursor: 'pointer', fontFamily: 'inherit',
                  }}>Log out</button>
                </>
              ) : (
                <>
                  <button onClick={() => goClose({ name: 'signup' })} style={{
                    appearance: 'none', border: 'none', background: '#1a1a18', color: '#FAFAF7',
                    fontSize: 12, padding: '14px 18px', letterSpacing: '0.14em', textTransform: 'uppercase',
                    fontWeight: 500, borderRadius: 999, cursor: 'pointer',
                  }}>Sign up</button>
                  <button onClick={() => goClose({ name: 'login' })} style={{
                    appearance: 'none', border: '1px solid rgba(20,20,18,0.18)', background: 'transparent',
                    color: '#1a1a18', fontSize: 12, padding: '14px 18px', letterSpacing: '0.14em',
                    textTransform: 'uppercase', fontWeight: 500, borderRadius: 999, cursor: 'pointer',
                  }}>Log in</button>
                </>
              )}
            </div>
          </div>
          <style>{`@keyframes dc-drawer-in { from { transform: translateX(20px); opacity: .4; } to { transform: translateX(0); opacity: 1; } }`}</style>
        </div>
      )}
    </nav>
  );
}

// The avatar in the nav is the signed-in account's own initial. It is only
// rendered when signed in, so there is no demo creator to fall back to.
function navCreator() {
  const s = window.MBAuth?.get?.();
  if (!s) return null;
  const name = s.creatorName || s.fullName || s.email || '';
  const profile = window.MBProfile && window.MBProfile.cachedProfile
    ? window.MBProfile.cachedProfile()
    : null;
  return {
    handle: (profile && profile.username) || s.handle || 'me',
    avatar: ((profile && profile.displayName) || name || 'M')[0].toUpperCase(),
    avatarUrl: profile ? profile.avatarUrl : null,
  };
}

// ─── Public share link ─────────────────────────────────────────────────────
// Shown wherever an outfit is listed. A published outfit gets its real, live
// URL — clickable and copyable. An unpublished one gets a hint, never a URL:
// showing a link that 404s would be worse than showing none.

// The username half of every share URL. Cached in MBProfile, so the several
// places this renders don't each hit the network.
function useMyUsername() {
  const [username, setUsername] = useState(() => (window.MBProfile ? window.MBProfile.cached() : null));
  useEffect(() => {
    if (username) return;
    if (!window.MBAuth || !window.MBAuth.isSignedIn()) return;
    let cancelled = false;
    (async () => {
      const res = await window.MBProfile.get();
      if (!cancelled && res && res.username) setUsername(res.username);
    })();
    return () => { cancelled = true; };
  }, [username]);
  return username;
}

function PublicUrl({ published, slug, compact = false, hint = true }) {
  const username = useMyUsername();
  const [copied, setCopied] = useState(false);

  if (!published || !slug) {
    if (!hint) return null;
    return (
      <div style={{ fontSize: 11, color: '#a8a39d', letterSpacing: '0.02em' }}>
        Publish to get a shareable link
      </div>
    );
  }
  // Published, but the username hasn't resolved yet — say so rather than
  // rendering half a URL.
  if (!username) {
    return <div style={{ fontSize: 11, color: '#a8a39d' }}>Loading link…</div>;
  }

  const url = window.MBOutfits.shareUrl(username, slug);
  const copy = async (e) => {
    e.preventDefault();
    e.stopPropagation();
    try {
      await navigator.clipboard.writeText(url);
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    } catch { /* clipboard blocked — the URL is on screen to copy by hand */ }
  };

  return (
    <div onClick={(e) => e.stopPropagation()} style={{
      display: 'flex', alignItems: 'center', gap: 6, minWidth: 0,
    }}>
      <a href={url} target="_blank" rel="noopener noreferrer"
         title={url}
         style={{
           flex: 1, minWidth: 0, fontSize: compact ? 11 : 12,
           fontFamily: 'ui-monospace, monospace', color: '#5a5a54',
           background: '#F2EFE7', borderRadius: 8,
           padding: compact ? '5px 8px' : '8px 11px',
           overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
           textDecoration: 'none',
         }}>{url.replace(/^https:\/\//, '')}</a>
      <button onClick={copy} title="Copy link" style={{
        appearance: 'none', border: '1px solid rgba(20,20,18,0.18)', background: 'transparent',
        color: '#1a1a18', fontSize: 10, padding: compact ? '5px 9px' : '8px 13px',
        letterSpacing: '0.12em', textTransform: 'uppercase', fontWeight: 500,
        borderRadius: 999, cursor: 'pointer', fontFamily: 'inherit', flexShrink: 0,
      }}>{copied ? 'Copied' : 'Copy'}</button>
    </div>
  );
}

// ─── Footer ────────────────────────────────────────────────────────────────
function Footer() {
  return (
    <footer style={{
      padding: '64px 40px 40px', marginTop: 80,
      borderTop: '1px solid rgba(20,20,18,0.06)',
      display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', gap: 40, flexWrap: 'wrap',
    }}>
      <div>
        <Logo size={28}/>
        <div style={{ marginTop: 14, fontSize: 12, color: '#8a8580', maxWidth: 320, lineHeight: 1.6 }}>
          A shoppable outfit board for creators. Paste a URL, build a look, get paid when your audience shops it.
        </div>
      </div>
      <div style={{ display: 'flex', gap: 56, fontSize: 11, letterSpacing: '0.14em', textTransform: 'uppercase', color: '#8a8580' }}>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          <a style={{ color: '#1a1a18', textDecoration: 'none', cursor: 'pointer' }} onClick={() => window.__dripcheckGo?.({ name: 'creators' })}>Creators</a>
          <a style={{ cursor: 'pointer' }} onClick={() => window.__dripcheckGo?.({ name: 'brands' })}>Brands</a>
          <a style={{ cursor: 'pointer' }} onClick={() => window.__dripcheckGo?.({ name: 'press' })}>Press</a>
        </div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          <a style={{ cursor: 'pointer' }}>Instagram</a><a style={{ cursor: 'pointer' }}>TikTok</a><a style={{ cursor: 'pointer' }}>Newsletter</a>
        </div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          <a style={{ cursor: 'pointer' }} onClick={() => window.__dripcheckGo?.({ name: 'privacy' })}>Privacy</a><a style={{ cursor: 'pointer' }} onClick={() => window.__dripcheckGo?.({ name: 'terms' })}>Terms</a>
          <a style={{ cursor: 'pointer' }} onClick={() => window.__dripcheckGo?.({ name: 'contact' })}>Contact</a>
        </div>
      </div>
    </footer>
  );
}

Object.assign(window, {
  Silhouette, ProductImage, Avatar, OutfitBoard, OutfitCard, IconButton, Logo, Nav, Footer,
  PublicUrl, useMyUsername,
});
