// DiveDex — Dive Boutique screens + components

// ── Pearl glyph ────────────────────────────────────────────────────
function PearlIcon({ size = 14 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 16 16" style={{ display:'block' }}>
      <defs>
        <radialGradient id="p-g" cx="35%" cy="30%" r="70%">
          <stop offset="0" stopColor="#FFFFFF"/>
          <stop offset=".55" stopColor="#EAF5FF"/>
          <stop offset="1" stopColor="#7BB6D8"/>
        </radialGradient>
      </defs>
      <circle cx="8" cy="8" r="6" fill="url(#p-g)"/>
      <circle cx="6" cy="6" r="1.6" fill="#fff" opacity=".9"/>
    </svg>
  );
}

function PearlBalanceChip({ amount, big = false }) {
  return (
    <span className="dd-chip" style={{
      background: 'linear-gradient(180deg, rgba(234,245,255,0.10), rgba(130,236,255,0.04))',
      borderColor: 'rgba(234,245,255,0.28)',
      padding: big ? '8px 12px' : '6px 10px',
      fontSize: big ? 13 : 11.5,
    }}>
      <PearlIcon size={big ? 16 : 13}/>
      <span className="dd-num" style={{ color:'#EAF5FF', fontWeight: 700 }}>{amount.toLocaleString()}</span>
      <span style={{ color:'var(--ink-3)', fontWeight: 500 }}>Pearls</span>
    </span>
  );
}

function ItemRarityBadge({ rarity }) {
  return (
    <span className={`dd-rarity-${rarity}`} style={{
      fontSize: 9, fontWeight: 700, letterSpacing: '0.16em', textTransform: 'uppercase',
      padding: '3px 7px', borderRadius: 6,
      color: 'var(--r-color)',
      border: '1px solid var(--r-color)',
      background: 'rgba(0,0,0,0.25)',
    }}>{rarity}</span>
  );
}

function EquippedBadge() {
  return (
    <span style={{
      fontSize: 9, fontWeight: 800, letterSpacing: '0.14em',
      padding: '3px 6px', borderRadius: 6, color: '#021321',
      background: 'linear-gradient(180deg, #82ECFF, #31D7FF)',
      boxShadow: '0 0 10px rgba(49,215,255,0.55)',
    }}>EQUIPPED</span>
  );
}

function LockedRequirementPill({ text }) {
  return (
    <span style={{
      display:'inline-flex', alignItems:'center', gap: 5,
      fontSize: 10, fontWeight: 600, color: 'var(--ink-2)',
      padding: '3px 7px', borderRadius: 999,
      background: 'rgba(255,255,255,0.04)',
      border: '1px solid rgba(130,236,255,0.18)',
    }}>
      <svg width="9" height="9" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.6"><rect x="2.5" y="5.5" width="7" height="5" rx="1"/><path d="M4 5.5V4a2 2 0 0 1 4 0v1.5"/></svg>
      {text}
    </span>
  );
}

// ── Item thumbnail SVGs ────────────────────────────────────────────
function ItemArt({ kind, rarity = 'epic', size = 90 }) {
  const palette = ({
    common:['#B7CCDE','#7A93AB'], uncommon:['#63FFD2','#1FB6A0'], rare:['#82ECFF','#31D7FF'],
    epic:['#C8B6FF','#8B7BFF'], legendary:['#FBE6A6','#D7B46A'], mythic:['#82ECFF','#FF7A6B'],
  })[rarity] || ['#82ECFF','#31D7FF'];
  const a = palette[0], b = palette[1];
  return (
    <svg width={size} height={size} viewBox="0 0 100 100" style={{ display:'block' }}>
      <defs>
        <linearGradient id={`g-${kind}`} x1="0" y1="0" x2="100" y2="100">
          <stop offset="0" stopColor={a}/><stop offset="1" stopColor={b}/>
        </linearGradient>
        <radialGradient id={`bg-${kind}`} cx="50%" cy="35%" r="65%">
          <stop offset="0" stopColor={a} stopOpacity=".22"/>
          <stop offset="1" stopColor="#021321" stopOpacity="0"/>
        </radialGradient>
      </defs>
      <rect width="100" height="100" fill={`url(#bg-${kind})`}/>
      <Glyph kind={kind} grad={`g-${kind}`} a={a} b={b}/>
    </svg>
  );
}

function Glyph({ kind, grad, a, b }) {
  const g = `url(#${grad})`;
  switch (kind) {
    case 'suit-baroque': return <g>
      <path d="M30 20 Q 50 10 70 20 L 76 38 L 72 70 Q 60 84 50 84 Q 40 84 28 70 L 24 38 Z" fill={g}/>
      {[30,40,50,60,70].map(y=><path key={y} d={`M34 ${y} Q 50 ${y-4} 66 ${y}`} stroke="#021321" strokeWidth="0.8" fill="none" opacity=".4"/>)}
      <circle cx="50" cy="46" r="2.5" fill="#021321" opacity=".5"/>
    </g>;
    case 'suit-champagne': return <g>
      <path d="M30 20 Q 50 10 70 20 L 76 70 Q 60 84 50 84 Q 40 84 24 70 Z" fill={g}/>
      <path d="M50 18 L 50 84" stroke="#021321" strokeWidth="1.2" opacity=".35"/>
      <path d="M32 30 L 68 30 M 30 42 L 70 42" stroke="#021321" strokeWidth="0.6" opacity=".3"/>
    </g>;
    case 'suit-neon': return <g>
      <path d="M30 20 Q 50 10 70 20 L 76 70 Q 60 84 50 84 Q 40 84 24 70 Z" fill="#0B2A44" stroke={g} strokeWidth="2"/>
      <path d="M30 38 L 70 38 M 30 52 L 70 52 M 30 66 L 70 66" stroke={a} strokeWidth="1.4" opacity=".9"/>
    </g>;
    case 'suit-stealth': return <g>
      <path d="M30 20 Q 50 10 70 20 L 76 70 Q 60 84 50 84 Q 40 84 24 70 Z" fill="#0A1622" stroke="#1B3A56"/>
      <path d="M50 18 L 50 84" stroke="#1B3A56" strokeWidth="1"/>
      <circle cx="50" cy="44" r="2" fill={a} opacity=".7"/>
    </g>;
    case 'bcd-quilt': return <g>
      <path d="M20 32 L 80 32 L 80 76 Q 50 86 20 76 Z" fill={g}/>
      {[40,52,64].map(y=><path key={y} d={`M22 ${y} L 78 ${y}`} stroke="#021321" strokeWidth="0.6" opacity=".4"/>)}
      {[32,46,60,74].map(x=><path key={x} d={`M${x} 32 L ${x} 78`} stroke="#021321" strokeWidth="0.6" opacity=".4"/>)}
      <circle cx="50" cy="32" r="3" fill={b}/>
    </g>;
    case 'bcd-gold': return <g>
      <path d="M20 32 L 80 32 L 80 76 Q 50 86 20 76 Z" fill="#0B2A44"/>
      <path d="M20 32 L 80 32 M 20 76 Q 50 86 80 76" stroke={g} strokeWidth="2.5"/>
      <path d="M24 44 L 76 44" stroke={g} strokeWidth="1"/>
      <circle cx="50" cy="56" r="6" fill="none" stroke={g} strokeWidth="1.5"/>
    </g>;
    case 'bcd-tactical': return <g>
      <path d="M20 32 L 80 32 L 80 76 Q 50 86 20 76 Z" fill="#1B2A3A"/>
      <rect x="34" y="42" width="32" height="8" fill={g}/>
      <rect x="34" y="56" width="32" height="8" fill={g} opacity=".6"/>
      <circle cx="28" cy="38" r="2" fill={a}/><circle cx="72" cy="38" r="2" fill={a}/>
    </g>;
    case 'bcd-couture': return <g>
      <path d="M20 32 L 80 32 L 80 76 Q 50 86 20 76 Z" fill={g}/>
      <path d="M50 34 L 42 76 M 50 34 L 58 76" stroke="#021321" strokeWidth="1.2" opacity=".5"/>
      <circle cx="50" cy="50" r="3" fill="#fff" opacity=".7"/>
    </g>;
    case 'fins-pearl': case 'fins-coral': return <g>
      <path d="M28 76 L 36 24 Q 44 22 46 30 L 42 76 Z" fill={g}/>
      <path d="M54 76 L 58 30 Q 60 22 68 24 L 72 76 Z" fill={g}/>
      <path d="M30 70 L 44 70 M 56 70 L 70 70" stroke="#021321" strokeWidth="0.6" opacity=".4"/>
    </g>;
    case 'mask-tokyo': case 'mask-gold': return <g>
      <path d="M20 38 Q 50 28 80 38 L 76 62 Q 50 70 24 62 Z" fill={g}/>
      <ellipse cx="36" cy="50" rx="8" ry="6" fill="#021321" opacity=".6"/>
      <ellipse cx="64" cy="50" rx="8" ry="6" fill="#021321" opacity=".6"/>
      <path d="M44 50 Q 50 54 56 50" stroke="#021321" strokeWidth="0.8" opacity=".5" fill="none"/>
    </g>;
    case 'acc-charm': return <g>
      <circle cx="50" cy="58" r="14" fill={g}/>
      <path d="M50 44 L 50 28" stroke={b} strokeWidth="2"/>
      <circle cx="50" cy="26" r="3" fill="none" stroke={b} strokeWidth="1.5"/>
      <circle cx="46" cy="54" r="2" fill="#fff" opacity=".8"/>
    </g>;
    case 'acc-camera': return <g>
      <rect x="20" y="34" width="60" height="36" rx="6" fill={g}/>
      <circle cx="50" cy="52" r="11" fill="#021321"/>
      <circle cx="50" cy="52" r="6" fill={a}/>
      <rect x="64" y="30" width="10" height="6" fill={g}/>
    </g>;
    case 'acc-snack': return <g>
      <rect x="26" y="26" width="48" height="56" rx="4" fill={g}/>
      <path d="M26 38 L 74 38" stroke="#021321" strokeWidth="1.2"/>
      <text x="50" y="56" textAnchor="middle" fill="#021321" fontFamily="Space Grotesk" fontWeight="700" fontSize="10">7-11</text>
      <path d="M30 64 L 70 64 M 30 72 L 60 72" stroke="#021321" strokeWidth="0.8" opacity=".5"/>
    </g>;
    case 'acc-blanket': return <g>
      <rect x="18" y="32" width="64" height="40" rx="3" fill={g}/>
      {[24,32,40,48,56,64,72].map(x=><path key={x} d={`M${x} 32 L ${x} 72`} stroke="#021321" strokeWidth="0.6" opacity=".35"/>)}
      <path d="M18 52 L 82 52" stroke="#021321" strokeWidth="0.6" opacity=".35"/>
    </g>;
    case 'title-shark': return <g>
      <path d="M16 50 Q 40 38 64 50 L 84 46 L 78 52 L 84 58 L 64 54 Q 40 64 16 54 Z" fill={g}/>
      <circle cx="68" cy="50" r="1.4" fill="#021321"/>
      <text x="50" y="78" textAnchor="middle" fill={a} fontFamily="Space Grotesk" fontWeight="700" fontSize="8" letterSpacing=".1em">WHISPERER</text>
    </g>;
    case 'title-snack': return <g>
      <rect x="20" y="38" width="60" height="24" rx="4" fill={g}/>
      <text x="50" y="54" textAnchor="middle" fill="#021321" fontFamily="Space Grotesk" fontWeight="700" fontSize="9">SNACK</text>
      <text x="50" y="74" textAnchor="middle" fill={a} fontFamily="Space Grotesk" fontWeight="600" fontSize="7" letterSpacing=".12em">CHAMPION</text>
    </g>;
    case 'title-zen': return <g>
      <circle cx="50" cy="50" r="22" fill="none" stroke={g} strokeWidth="2"/>
      <path d="M30 50 Q 50 32 70 50 Q 50 68 30 50 Z" fill={g} opacity=".4"/>
      <text x="50" y="82" textAnchor="middle" fill={a} fontFamily="Space Grotesk" fontWeight="700" fontSize="7" letterSpacing=".14em">AIR ZEN</text>
    </g>;
    case 'title-crown': case 'crown': return <g>
      <path d="M22 56 L 30 32 L 42 50 L 50 26 L 58 50 L 70 32 L 78 56 Z" fill={g}/>
      <rect x="22" y="56" width="56" height="8" fill={b}/>
      <circle cx="30" cy="32" r="2.5" fill="#fff"/><circle cx="50" cy="26" r="2.5" fill="#fff"/><circle cx="70" cy="32" r="2.5" fill="#fff"/>
      <circle cx="50" cy="60" r="2" fill={a}/>
    </g>;
    case 'frame-hammer': return <g>
      <rect x="20" y="20" width="60" height="60" rx="4" fill="none" stroke={g} strokeWidth="3"/>
      <path d="M28 50 Q 40 44 52 50 L 64 48 L 60 52 L 64 56 L 52 54 Q 40 60 28 54 Z" fill={g}/>
    </g>;
    case 'frame-manta': return <g>
      <rect x="18" y="18" width="64" height="64" rx="6" fill="none" stroke={g} strokeWidth="3"/>
      <path d="M30 50 Q 50 38 70 50 Q 50 62 30 50 Z" fill={g}/>
    </g>;
    case 'frame-tokyo': return <g>
      <rect x="20" y="20" width="60" height="60" rx="2" fill="none" stroke={g} strokeWidth="3"/>
      <path d="M28 36 L 72 36 M 28 50 L 72 50 M 28 64 L 72 64" stroke={a} strokeWidth="1.2"/>
    </g>;
    case 'frame-champ': return <g>
      <rect x="20" y="20" width="60" height="60" rx="3" fill="none" stroke={g} strokeWidth="4"/>
      <path d="M26 26 L 74 26 M 26 74 L 74 74" stroke={b} strokeWidth="1.5"/>
    </g>;
    case 'frame-zen': return <g>
      <rect x="22" y="22" width="56" height="56" rx="2" fill="none" stroke={g} strokeWidth="2"/>
      <circle cx="50" cy="50" r="14" fill="none" stroke={g} strokeWidth="1.4"/>
    </g>;
    case 'trophy-shark': return <g>
      <path d="M30 28 L 70 28 L 64 56 Q 50 64 36 56 Z" fill={g}/>
      <path d="M44 56 L 44 70 L 56 70 L 56 56" fill={g}/>
      <rect x="36" y="70" width="28" height="6" fill={b}/>
      <path d="M40 36 Q 50 32 60 36" stroke="#021321" strokeWidth="1.4" fill="none" opacity=".5"/>
    </g>;
    case 'crest': return <g>
      <path d="M30 24 L 70 24 L 70 56 Q 50 80 30 56 Z" fill={g}/>
      <path d="M50 28 L 50 70" stroke="#021321" strokeWidth="1" opacity=".4"/>
      <text x="42" y="50" fill="#021321" fontFamily="Space Grotesk" fontWeight="700" fontSize="11">R</text>
      <text x="54" y="56" fill="#021321" fontFamily="Space Grotesk" fontWeight="700" fontSize="11">S</text>
    </g>;
    case 'sash': return <g>
      <path d="M20 28 L 36 24 L 72 76 L 56 80 Z" fill={g}/>
      <path d="M22 32 L 70 76" stroke="#021321" strokeWidth="0.8" opacity=".4"/>
      <circle cx="62" cy="70" r="3" fill={b}/>
    </g>;
    case 'halo': return <g>
      <ellipse cx="50" cy="38" rx="22" ry="6" fill="none" stroke={g} strokeWidth="3"/>
      <ellipse cx="50" cy="38" rx="14" ry="3.5" fill="none" stroke={a} strokeWidth="1.4" opacity=".7"/>
      <path d="M36 52 Q 50 78 64 52" stroke={g} strokeWidth="2" fill="none" opacity=".6"/>
    </g>;
    default: return <circle cx="50" cy="50" r="22" fill={g}/>;
  }
}

// ── Card ───────────────────────────────────────────────────────────
function ShopItemCard({ item, onClick, compact = false }) {
  const r = item.rarity;
  const isEq = item.state === 'equipped';
  const isLocked = item.state === 'locked';
  const isAch = item.state === 'achievement';
  const owned = item.state === 'owned' || isEq;
  return (
    <div className={`dd-rarity-${r}`} onClick={onClick} style={{
      position: 'relative', borderRadius: 14, padding: 10, cursor: 'pointer',
      background: 'linear-gradient(180deg, rgba(16,30,46,0.92), rgba(7,18,30,0.96))',
      border: `1px solid var(--r-color)`,
      boxShadow: r==='legendary'||r==='mythic'
        ? `0 6px 22px -10px var(--r-glow), inset 0 1px 0 rgba(255,255,255,0.06)`
        : `0 3px 12px -8px var(--r-glow), inset 0 1px 0 rgba(255,255,255,0.04)`,
      overflow: 'hidden',
    }}>
      <div style={{
        position:'relative', borderRadius: 10, marginBottom: 8,
        background: `radial-gradient(70% 70% at 50% 40%, var(--r-glow), transparent 70%)`,
        display:'grid', placeItems:'center', height: compact ? 64 : 86,
        filter: isLocked ? 'grayscale(1) brightness(0.55)' : 'none',
      }}>
        <ItemArt kind={item.art} rarity={r} size={compact ? 56 : 72}/>
        {isLocked && (
          <div style={{ position:'absolute', inset:0, display:'grid', placeItems:'center',
                        background:'rgba(5,11,20,0.55)', borderRadius: 10 }}>
            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#82ECFF" strokeWidth="1.8"><rect x="5" y="11" width="14" height="10" rx="2"/><path d="M8 11V8a4 4 0 0 1 8 0v3"/></svg>
          </div>
        )}
        {/* When equipped, the EQUIPPED label takes the top — the card's
            colored frame already communicates rarity, so we hide the rarity
            badge to avoid an overlap on narrow phone widths. */}
        {isEq
          ? <div style={{ position:'absolute', top:6, left:6, right:6, display:'flex', justifyContent:'space-between', alignItems:'flex-start', gap:4 }}><EquippedBadge/></div>
          : <div style={{ position:'absolute', top:6, right:6 }}><ItemRarityBadge rarity={r}/></div>}
      </div>
      <div style={{ fontFamily:'Space Grotesk', fontWeight: 600, fontSize: 12.5, color:'#EAF5FF', lineHeight: 1.15 }}>{item.name}</div>
      <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginTop: 6, minHeight: 18 }}>
        {isLocked ? <LockedRequirementPill text={item.req || 'Locked'}/> :
         isAch    ? <span style={{ fontSize: 10, fontWeight: 700, color:'var(--gold)', letterSpacing:'.12em' }}>ACHIEVEMENT</span> :
         owned    ? <span style={{ fontSize: 10, fontWeight: 700, color:'var(--seafoam)', letterSpacing:'.12em' }}>{isEq?'IN LOCKER':'OWNED'}</span> :
                    <span style={{ display:'inline-flex', alignItems:'center', gap: 4 }}><PearlIcon size={11}/><span className="dd-num" style={{ fontSize: 12, fontWeight: 700, color:'#EAF5FF' }}>{item.price}</span></span>
        }
      </div>
    </div>
  );
}

// ── Screens ────────────────────────────────────────────────────────
function BoutiqueScreen({ nav }) {
  const { state } = useDiveDex();
  const [cat, setCat] = React.useState('all');
  // Decorate each catalog entry with its effective per-user state so
  // ShopItemCard reads owned/buy/equipped from the live store.
  const decorated = BOUTIQUE_ITEMS.map(it => ({ ...it, state: selectBoutiqueItemState(state, it) }));
  const items = cat === 'all' ? decorated : decorated.filter(i => i.cat === cat);
  const pearls = state.currencies.pearls;
  return (
    <div className="dd-screen" style={{ paddingBottom: 110 }}>
      <TopBar
        title="Dive Boutique"
        sub="Vanity only. No buoyancy stats."
        left={<IconBtn onClick={()=>nav('back')}><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M15 6l-6 6 6 6"/></svg></IconBtn>}
        right={<button className="dd-btn" onClick={()=>nav('locker')} style={{ background:'rgba(130,236,255,0.08)', border:'1px solid rgba(130,236,255,0.22)', color:'#EAF5FF', height:32, padding:'0 10px', borderRadius:16, fontSize:11, fontWeight:700, letterSpacing:'.08em' }}>LOCKER</button>}
      />
      <div style={{ padding: '0 16px 8px', display:'flex', justifyContent:'space-between', alignItems:'center', gap: 8 }}>
        <div>
          <div style={{ fontSize: 10, fontWeight: 700, color:'var(--ink-3)', letterSpacing:'.16em' }}>BALANCE</div>
          <div style={{ marginTop: 4 }}><PearlBalanceChip amount={pearls} big/></div>
        </div>
        <div style={{ textAlign:'right' }}>
          <div style={{ fontSize: 10, fontWeight: 700, color:'var(--ink-3)', letterSpacing:'.16em' }}>HOW PEARLS WORK</div>
          <div style={{ fontSize: 10.5, color:'var(--ink-2)', marginTop: 4, maxWidth: 170, lineHeight: 1.35 }}>Earn by logging dives & milestones. Spend on cosmetics only.</div>
        </div>
      </div>

      <div style={{ padding: '6px 12px 10px', display:'flex', gap: 6, overflowX:'auto', scrollbarWidth:'none' }}>
        {[{id:'all',label:'All'}, ...BOUTIQUE_CATEGORIES].map(c => {
          const on = cat === c.id;
          return (
            <button key={c.id} onClick={()=>setCat(c.id)} className="dd-btn" style={{
              padding: '7px 12px', borderRadius: 999, whiteSpace:'nowrap', fontSize: 11.5, fontWeight: 600,
              background: on ? 'linear-gradient(180deg, rgba(49,215,255,0.22), rgba(49,215,255,0.08))' : 'rgba(255,255,255,0.04)',
              border: `1px solid ${on?'rgba(49,215,255,0.45)':'rgba(130,236,255,0.14)'}`,
              color: on ? '#EAF5FF' : 'var(--ink-2)',
              boxShadow: on ? '0 0 14px rgba(49,215,255,0.25) inset' : 'none',
            }}>{c.label}</button>
          );
        })}
      </div>

      <div style={{ padding: '4px 12px 20px', display:'grid', gridTemplateColumns:'1fr 1fr', gap: 10 }}>
        {items.map(it => <ShopItemCard key={it.id} item={it} onClick={()=>nav('item', it.id)}/>)}
      </div>

      <div style={{ padding: '0 16px 12px' }}>
        <div className="dd-glass" style={{ padding: 12, borderRadius: 14 }}>
          <div style={{ fontSize: 10, fontWeight: 700, color:'var(--cyan)', letterSpacing:'.16em' }}>HOW THE SHOP WORKS</div>
          <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap: 6, marginTop: 8, fontSize: 11, color:'var(--ink-2)' }}>
            <div><span style={{ color:'var(--gold)', fontWeight:700 }}>XP</span> · progression</div>
            <div><span style={{ color:'#EAF5FF', fontWeight:700 }}>Pearls</span> · cosmetics</div>
            <div><span style={{ color:'var(--violet)', fontWeight:700 }}>Achievements</span> · prestige unlocks</div>
            <div><span style={{ color:'var(--seafoam)', fontWeight:700 }}>Equip</span> · profile flair only</div>
          </div>
        </div>
      </div>
    </div>
  );
}

function BoutiqueItemScreen({ nav, id }) {
  const { state, actions } = useDiveDex();
  const catalogItem = BOUTIQUE_ITEMS.find(i => i.id === id) || BOUTIQUE_ITEMS[0];
  const effective = selectBoutiqueItemState(state, catalogItem);
  const item = { ...catalogItem, state: effective };
  const r = item.rarity;
  const equippedByList = selectItemEquippedBy(state, item.id); // ['rick','siet'] subset
  const owned = state.inventory.indexOf(item.id) >= 0;

  const [banner, setBanner] = React.useState(null);
  const flash = (kind, msg) => {
    setBanner({ kind, msg });
    setTimeout(() => setBanner(b => (b && b.msg === msg ? null : b)), 2800);
  };

  const onBuy = () => {
    const result = actions.buyShopItem(item.id);
    flash(result.ok ? 'ok' : 'err', result.ok ? 'Purchased.' : (result.reason || 'Could not buy.'));
  };
  const onEquip = (userId) => {
    const result = actions.equipShopItem(item.id, userId);
    flash(result.ok ? 'ok' : 'err', result.ok ? `Equipped on ${userId === 'rick' ? 'Rick' : 'Siet'}.` : (result.reason || 'Could not equip.'));
  };
  const onUnequip = (userId) => {
    actions.unequipShopItem(item.id, userId);
    flash('ok', `Unequipped from ${userId === 'rick' ? 'Rick' : 'Siet'}.`);
  };

  return (
    <div className="dd-screen" style={{ paddingBottom: 110 }}>
      <TopBar title={item.name} sub={item.cat}
        left={<IconBtn onClick={()=>nav('back')}><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M15 6l-6 6 6 6"/></svg></IconBtn>}
        right={<PearlBalanceChip amount={state.currencies.pearls}/>}
      />
      <div style={{ padding: '4px 16px 20px' }}>
        <div className={`dd-rarity-${r}`} style={{
          position:'relative', borderRadius: 22, padding: 18, marginTop: 4,
          background: `radial-gradient(80% 60% at 50% 35%, var(--r-glow), transparent 70%), linear-gradient(180deg, rgba(16,30,46,0.92), rgba(5,11,20,0.96))`,
          border: `1px solid var(--r-color)`,
          boxShadow: `0 12px 32px -14px var(--r-glow), inset 0 1px 0 rgba(255,255,255,0.05)`,
        }}>
          <div style={{ display:'flex', justifyContent:'space-between', alignItems:'flex-start' }}>
            <ItemRarityBadge rarity={r}/>
            {item.state==='equipped' && <EquippedBadge/>}
          </div>
          <div style={{ display:'grid', placeItems:'center', padding:'18px 0 14px' }}>
            <ItemArt kind={item.art} rarity={r} size={180}/>
          </div>
          <div style={{ textAlign:'center' }}>
            <div className="dd-h1" style={{ fontSize: 22, color:'#EAF5FF' }}>{item.name}</div>
            <div style={{ fontSize: 11, color:'var(--ink-3)', letterSpacing:'.14em', textTransform:'uppercase', marginTop: 4 }}>{item.cat}</div>
          </div>
        </div>

        <div className="dd-glass" style={{ marginTop: 12, padding: 14, borderRadius: 16 }}>
          <div style={{ fontSize: 13.5, color:'var(--ink)', lineHeight: 1.45 }}>"{item.flavor}"</div>
          <div style={{ display:'flex', gap: 6, flexWrap:'wrap', marginTop: 10 }}>
            <Chip variant="aqua">Cosmetic only</Chip>
            <Chip variant="default">No stats</Chip>
            {item.state==='achievement' && <Chip variant="gold">Achievement</Chip>}
            {(item.state==='locked' || item.state==='achievement') && item.req && <LockedRequirementPill text={item.req}/>}
            {item.state==='not-enough' && <Chip variant="coral">Not enough Pearls</Chip>}
          </div>
        </div>

        <div className="dd-glass" style={{ marginTop: 10, padding: 12, borderRadius: 14 }}>
          <div style={{ fontSize: 10, fontWeight: 700, color:'var(--cyan)', letterSpacing:'.16em' }}>PREVIEW · STORY CARD</div>
          <div style={{ marginTop: 8 }}><StoryFramePreview item={item}/></div>
        </div>

        {/* Primary action area */}
        {item.state === 'buy' && (
          <div style={{ display:'flex', gap: 8, marginTop: 14 }}>
            <button className="dd-btn dd-btn-ghost" onClick={()=>nav('back')} style={{ height: 44, borderRadius: 14, padding:'0 14px', fontSize: 13 }}>Back</button>
            <button onClick={onBuy} className="dd-btn" style={{
              flex: 1, height: 44, borderRadius: 14, fontSize: 13.5, fontWeight: 700,
              background: 'linear-gradient(180deg, #4DDFFF 0%, #1FB6E6 100%)', border: 'none', color: '#021321',
              display:'inline-flex', alignItems:'center', justifyContent:'center', gap: 6,
            }}><PearlIcon size={14}/>Buy · {item.price} Pearls</button>
          </div>
        )}

        {item.state === 'not-enough' && (
          <div style={{ display:'flex', gap: 8, marginTop: 14 }}>
            <button className="dd-btn dd-btn-ghost" onClick={()=>nav('back')} style={{ height: 44, borderRadius: 14, padding:'0 14px', fontSize: 13 }}>Back</button>
            <button disabled className="dd-btn" style={{
              flex: 1, height: 44, borderRadius: 14, fontSize: 13.5, fontWeight: 700,
              background: 'rgba(255,122,107,0.10)', border: '1px solid rgba(255,122,107,0.28)',
              color: '#FF7A6B', opacity: 0.85,
              display:'inline-flex', alignItems:'center', justifyContent:'center', gap: 6, cursor: 'not-allowed',
            }}>Need {item.price - state.currencies.pearls} more Pearls</button>
          </div>
        )}

        {(item.state === 'locked' || item.state === 'achievement') && (
          <div style={{ marginTop: 14 }}>
            <button disabled className="dd-btn" style={{
              width: '100%', height: 44, borderRadius: 14, fontSize: 13.5, fontWeight: 700,
              background: 'rgba(255,255,255,0.04)', border: '1px solid rgba(130,236,255,0.18)',
              color: 'var(--ink-3)', opacity: 0.7, cursor: 'not-allowed',
            }}>{item.state === 'achievement' ? 'Unlock via achievement' : 'Locked'}</button>
          </div>
        )}

        {owned && (
          <div style={{ marginTop: 14 }}>
            <div className="dd-h-section" style={{ marginBottom: 8 }}>Equip on</div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 }}>
              {['rick','siet'].map(uid => {
                const u = state.users.find(x => x.id === uid);
                const isOn = equippedByList.indexOf(uid) >= 0;
                return (
                  <button key={uid} onClick={() => (isOn ? onUnequip(uid) : onEquip(uid))} className="dd-btn" style={{
                    height: 56, borderRadius: 14, padding: '0 12px',
                    background: isOn ? `linear-gradient(180deg, ${u.color}28, ${u.color}10)` : 'rgba(255,255,255,0.04)',
                    border: isOn ? `1px solid ${u.color}66` : '1px solid rgba(130,236,255,0.14)',
                    color: '#EAF5FF', display: 'flex', alignItems: 'center', gap: 10,
                  }}>
                    <Avatar name={u.displayName} color={u.color} size={28}/>
                    <div style={{ textAlign: 'left', flex: 1 }}>
                      <div style={{ fontSize: 12.5, fontWeight: 700 }}>{u.displayName}</div>
                      <div style={{ fontSize: 10, color: isOn ? u.color : 'var(--ink-3)', fontWeight: 700, letterSpacing: '0.08em' }}>{isOn ? 'EQUIPPED · TAP TO REMOVE' : 'TAP TO EQUIP'}</div>
                    </div>
                  </button>
                );
              })}
            </div>
            <button className="dd-btn dd-btn-ghost" onClick={()=>nav('locker')} style={{ width:'100%', height: 40, marginTop: 8, borderRadius: 12, fontSize: 12, fontWeight: 700 }}>Open Gear Locker →</button>
          </div>
        )}

        {banner && (
          <div style={{
            marginTop: 10, padding: '10px 12px', borderRadius: 12, fontSize: 12, fontWeight: 600,
            background: banner.kind === 'ok' ? 'rgba(99,255,210,0.10)' : 'rgba(255,122,107,0.10)',
            border: '1px solid ' + (banner.kind === 'ok' ? 'rgba(99,255,210,0.32)' : 'rgba(255,122,107,0.32)'),
            color: banner.kind === 'ok' ? '#9bffdf' : '#FF7A6B',
          }}>{banner.msg}</div>
        )}
      </div>
    </div>
  );
}

function GearPreviewCard({ name, color, title, suit, frame, trophy, onChange }) {
  return (
    <div className="dd-glass" style={{ padding: 12, borderRadius: 16 }}>
      <div style={{ display:'flex', alignItems:'center', gap: 10 }}>
        <Avatar name={name} color={color} size={40}/>
        <div style={{ flex: 1 }}>
          <div style={{ fontFamily:'Space Grotesk', fontWeight: 700, fontSize: 16, color:'#EAF5FF' }}>{name}</div>
          <div style={{ fontSize: 10.5, color: 'var(--gold)', letterSpacing:'.12em', textTransform:'uppercase', fontWeight: 700, marginTop: 1 }}>{title?.name || '—'}</div>
        </div>
        <button onClick={onChange} className="dd-btn" style={{ padding:'6px 10px', borderRadius:10, background:'rgba(130,236,255,0.08)', border:'1px solid rgba(130,236,255,0.22)', color:'#EAF5FF', fontSize: 10.5, fontWeight: 700, letterSpacing:'.08em', cursor: onChange ? 'pointer' : 'default' }}>CHANGE</button>
      </div>
      <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr 1fr', gap: 8, marginTop: 10 }}>
        {[suit, frame, trophy].map((it, i) => it ? (
          <div key={i} className={`dd-rarity-${it.rarity}`} style={{
            borderRadius: 12, padding: 8, textAlign:'center',
            border:'1px solid var(--r-color)',
            background:'linear-gradient(180deg, rgba(16,30,46,0.92), rgba(7,18,30,0.96))',
            boxShadow:'0 2px 10px -6px var(--r-glow)',
          }}>
            <div style={{ display:'grid', placeItems:'center', height: 56 }}><ItemArt kind={it.art} rarity={it.rarity} size={50}/></div>
            <div style={{ fontSize: 9.5, fontWeight: 700, color:'var(--ink-2)', letterSpacing:'.04em', marginTop: 4, lineHeight: 1.2 }}>{it.name}</div>
            <div style={{ fontSize: 8.5, fontWeight: 700, color:'var(--r-color)', letterSpacing:'.14em', marginTop: 2 }}>{['SUIT','FRAME','TROPHY'][i]}</div>
          </div>
        ) : <div key={i} style={{ borderRadius:12, padding:8, height: 96, border:'1px dashed rgba(130,236,255,0.18)', display:'grid', placeItems:'center', color:'var(--ink-3)', fontSize: 10 }}>+ add</div>)}
      </div>
    </div>
  );
}

function LockerScreen({ nav }) {
  const { state } = useDiveDex();
  const byId = (id) => BOUTIQUE_ITEMS.find(i => i.id === id);
  const slotFor = (userId, slot) => {
    const itemId = (state.equippedItems[userId] || {})[slot];
    return itemId ? byId(itemId) : null;
  };
  const rick = state.users.find(u => u.id === 'rick');
  const siet = state.users.find(u => u.id === 'siet');
  return (
    <div className="dd-screen" style={{ paddingBottom: 110 }}>
      <TopBar title="Gear Locker" sub="Equipped cosmetics"
        left={<IconBtn onClick={()=>nav('back')}><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M15 6l-6 6 6 6"/></svg></IconBtn>}
        right={<button onClick={()=>nav('boutique')} className="dd-btn" style={{ background:'rgba(130,236,255,0.08)', border:'1px solid rgba(130,236,255,0.22)', color:'#EAF5FF', height:32, padding:'0 10px', borderRadius:16, fontSize:11, fontWeight:700, letterSpacing:'.08em' }}>SHOP</button>}
      />
      <div style={{ padding:'4px 16px 16px', display:'flex', flexDirection:'column', gap: 10 }}>
        <GearPreviewCard name={rick.displayName} color={rick.color}
          title={slotFor('rick','title')}
          suit={slotFor('rick','suit') || slotFor('rick','bcd')}
          frame={slotFor('rick','frame')}
          trophy={slotFor('rick','trophy') || slotFor('rick','special')}
          onChange={() => nav('boutique')}/>
        <GearPreviewCard name={siet.displayName} color={siet.color}
          title={slotFor('siet','title')}
          suit={slotFor('siet','suit') || slotFor('siet','bcd')}
          frame={slotFor('siet','frame')}
          trophy={slotFor('siet','trophy') || slotFor('siet','special')}
          onChange={() => nav('boutique')}/>

        <div className="dd-glass" style={{ padding: 12, borderRadius: 14 }}>
          <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between' }}>
            <div className="dd-h-section">Prestige shelf</div>
            <button onClick={()=>nav('prestige')} className="dd-btn" style={{ background:'transparent', color:'var(--cyan)', fontSize: 11, fontWeight:700, letterSpacing:'.08em' }}>VIEW ALL →</button>
          </div>
          <div style={{ display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gap: 8, marginTop: 8 }}>
            {['pelagic-crown','sharknado','whisperer-sash','zen-halo'].map(id => {
              const it = byId(id);
              if (!it) return null;
              const decorated = { ...it, state: selectBoutiqueItemState(state, it) };
              return <PrestigeTrophyCard key={id} item={decorated} mini onClick={()=>nav('item', id)}/>;
            })}
          </div>
        </div>
      </div>
    </div>
  );
}

function PrestigeTrophyCard({ item, mini = false, onClick }) {
  const r = item.rarity;
  const locked = item.state === 'locked';
  return (
    <div onClick={onClick} className={`dd-rarity-${r}`} style={{
      borderRadius: mini ? 10 : 14, padding: mini ? 6 : 10,
      background:'linear-gradient(180deg, rgba(16,30,46,0.92), rgba(7,18,30,0.96))',
      border:'1px solid var(--r-color)',
      boxShadow:`0 4px 14px -8px var(--r-glow)`,
      cursor:'pointer', textAlign:'center',
    }}>
      <div style={{ position:'relative', display:'grid', placeItems:'center', height: mini ? 48 : 88,
                    filter: locked ? 'grayscale(1) brightness(0.55)' : 'none' }}>
        <ItemArt kind={item.art} rarity={r} size={mini ? 44 : 80}/>
        {locked && <div style={{ position:'absolute', inset:0, display:'grid', placeItems:'center' }}>
          <svg width={mini?14:18} height={mini?14:18} viewBox="0 0 24 24" fill="none" stroke="#82ECFF" strokeWidth="1.8"><rect x="5" y="11" width="14" height="10" rx="2"/><path d="M8 11V8a4 4 0 0 1 8 0v3"/></svg>
        </div>}
      </div>
      {!mini && <div style={{ fontFamily:'Space Grotesk', fontWeight: 700, fontSize: 12.5, color:'#EAF5FF', marginTop: 6, lineHeight: 1.15 }}>{item.name}</div>}
      {mini && <div style={{ fontSize: 8.5, fontWeight: 700, color:'var(--r-color)', marginTop: 2, letterSpacing:'.1em' }}>{r.toUpperCase()}</div>}
    </div>
  );
}

function PrestigeScreen({ nav }) {
  const { state } = useDiveDex();
  const list = BOUTIQUE_ITEMS
    .filter(i => i.cat === 'trophies' || i.cat === 'specials' || (i.cat === 'frames' && i.state === 'achievement'))
    .map(i => ({ ...i, state: selectBoutiqueItemState(state, i) }));
  return (
    <div className="dd-screen" style={{ paddingBottom: 110 }}>
      <TopBar title="Prestige" sub="Earned, not bought."
        left={<IconBtn onClick={()=>nav('back')}><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M15 6l-6 6 6 6"/></svg></IconBtn>}/>
      <div style={{ padding:'4px 16px 20px' }}>
        <div className="dd-glass" style={{ padding: 14, borderRadius: 16, background:'linear-gradient(160deg, rgba(215,180,106,0.16), rgba(11,42,68,0.5))', borderColor: 'rgba(215,180,106,0.32)' }}>
          <div style={{ fontSize: 10, color:'var(--gold)', fontWeight:700, letterSpacing:'.18em' }}>TROPHY SHELF</div>
          <div className="dd-h1" style={{ fontSize: 22, marginTop: 4 }}>Things you can't buy.</div>
          <div style={{ fontSize: 12, color:'var(--ink-2)', marginTop: 6, lineHeight: 1.5 }}>Unlocked through legendary encounters, expedition milestones and Air Zen streaks. No Pearls accepted.</div>
        </div>
        <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap: 10, marginTop: 12 }}>
          {list.map(it => <PrestigeTrophyCard key={it.id} item={it} onClick={()=>nav('item', it.id)}/>)}
        </div>
      </div>
    </div>
  );
}

function StoryFramePreview({ item }) {
  // Show a mini fake story card with the frame applied
  const r = item.rarity;
  const isFrame = item.cat === 'frames';
  return (
    <div className={`dd-rarity-${r}`} style={{
      position:'relative', borderRadius: 14, padding: isFrame ? 3 : 0,
      background: isFrame ? 'linear-gradient(135deg, var(--r-color), transparent 70%)' : 'transparent',
    }}>
      <div style={{
        borderRadius: 12, padding: 12,
        background: 'linear-gradient(160deg, rgba(11,42,68,0.92), rgba(5,11,20,0.96))',
        border: isFrame ? `1.5px solid var(--r-color)` : '1px solid rgba(130,236,255,0.12)',
        boxShadow: isFrame ? `inset 0 0 18px var(--r-glow)` : 'none',
      }}>
        <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between' }}>
          <div style={{ fontSize: 10, color:'var(--r-color)', fontWeight: 700, letterSpacing:'.16em' }}>{isFrame ? r.toUpperCase()+' FRAME' : 'STORY CARD'}</div>
          <div style={{ fontSize: 10, color:'var(--ink-3)' }}>Mikomoto · 26 m</div>
        </div>
        <div style={{ display:'flex', alignItems:'center', gap: 10, marginTop: 8 }}>
          <div style={{ width: 50, height: 50, borderRadius: 10, background:'radial-gradient(60% 60% at 50% 40%, rgba(49,215,255,0.4), transparent 70%)', display:'grid', placeItems:'center', border:'1px solid rgba(130,236,255,0.2)' }}>
            <svg width="44" height="28" viewBox="0 0 60 30"><path d="M48 16 Q 38 8 20 12 Q 8 14 4 18 L 14 16 L 8 22 L 18 20 Q 30 22 44 20 Z M 50 12 L 56 6 L 54 16 L 56 22 L 50 18 Z" fill="#82ECFF"/></svg>
          </div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontFamily:'Space Grotesk', fontWeight: 700, fontSize: 14, color:'#EAF5FF' }}>Scalloped Hammerhead</div>
            <div style={{ fontSize: 11, color:'var(--ink-3)' }}>"Siet spotted it first. Obviously."</div>
          </div>
        </div>
      </div>
    </div>
  );
}

// ── QA panel for design canvas ─────────────────────────────────────
function BoutiqueQAPanel() {
  const cell = { display:'flex', flexDirection:'column', alignItems:'center', gap: 6, padding: 6,
                 borderRadius: 12, background:'rgba(130,236,255,0.04)', border:'1px solid rgba(130,236,255,0.10)' };
  const label = { fontFamily:'JetBrains Mono', fontSize: 8, color:'rgba(255,255,255,0.55)', letterSpacing:'.06em', textAlign:'center', lineHeight: 1.2 };
  return (
    <div className="brand-panel">
      <div style={{ fontFamily:'JetBrains Mono', fontSize: 10, color:'rgba(130,236,255,0.6)', letterSpacing:'.18em' }}>QA · DIVE BOUTIQUE</div>
      <div style={{ fontFamily:'Space Grotesk', fontWeight: 700, fontSize: 30, letterSpacing:'-0.025em', marginTop: 4 }}>20 cosmetic items + states</div>
      <div style={{ fontFamily:'Manrope', fontSize: 12, color:'rgba(234,245,255,0.65)', marginTop: 6, maxWidth: 760, lineHeight: 1.5 }}>
        Thumbnails grouped by category. Card states: buy · owned · equipped · locked · achievement · not-enough-pearls.
      </div>

      <div style={{ marginTop: 16, display:'flex', alignItems:'center', gap: 10 }}>
        <PearlBalanceChip amount={1240} big/>
        <PearlBalanceChip amount={140}/>
        <ItemRarityBadge rarity="legendary"/>
        <ItemRarityBadge rarity="mythic"/>
        <EquippedBadge/>
        <LockedRequirementPill text="Siet · 50 dives"/>
      </div>

      {BOUTIQUE_CATEGORIES.map(c => {
        const list = BOUTIQUE_ITEMS.filter(i => i.cat === c.id);
        if (!list.length) return null;
        return (
          <div key={c.id} style={{ marginTop: 18 }}>
            <div style={{ fontFamily:'JetBrains Mono', fontSize: 10, color:'#82ECFF', letterSpacing:'.18em', marginBottom: 8 }}>{c.label.toUpperCase()}</div>
            <div style={{ display:'grid', gridTemplateColumns:'repeat(6, 1fr)', gap: 8 }}>
              {list.map(it => (
                <div key={it.id} style={cell}>
                  <ItemArt kind={it.art} rarity={it.rarity} size={72}/>
                  <div style={label}>{it.name}</div>
                  <div style={{ ...label, color:'var(--r-color)' }} className={`dd-rarity-${it.rarity}`}>{it.rarity} · {it.state}</div>
                </div>
              ))}
            </div>
          </div>
        );
      })}

      <div style={{ marginTop: 18 }}>
        <div style={{ fontFamily:'JetBrains Mono', fontSize: 10, color:'#82ECFF', letterSpacing:'.18em', marginBottom: 8 }}>CARD STATES</div>
        <div style={{ display:'grid', gridTemplateColumns:'repeat(5, 1fr)', gap: 10 }}>
          {['buy','owned','equipped','locked','achievement'].map((st, i) => {
            const sample = { ...BOUTIQUE_ITEMS.find(x => x.state === st) || BOUTIQUE_ITEMS[0], state: st };
            return <ShopItemCard key={st} item={sample} onClick={()=>{}}/>;
          })}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, {
  PearlIcon, PearlBalanceChip, ItemRarityBadge, EquippedBadge, LockedRequirementPill,
  ItemArt, ShopItemCard, GearPreviewCard, PrestigeTrophyCard, StoryFramePreview,
  BoutiqueScreen, BoutiqueItemScreen, LockerScreen, PrestigeScreen, BoutiqueQAPanel,
});
