function ModelCard({ m, idx, onOpen }) {
  const [hover, setHover] = React.useState(false);
  const isWomen = m.cat !== 'Men';

  const stats = [
    { k: 'Height', v: m.height },
    { k: isWomen ? 'Bust' : 'Chest', v: m.bust },
    { k: 'Waist',  v: m.waist },
    { k: 'Hips', v: m.hips },
    { k: 'Shoes',  v: m.shoes },
    { k: 'Hair',   v: m.hair },
    { k: 'Eyes',   v: m.eyes },
  ].filter(Boolean).filter(s => s.v);

  return (
    <a className="fade-in"
       role="link" tabIndex={0}
       onClick={() => onOpen(m)}
       onKeyDown={e => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onOpen(m); } }}
       onMouseEnter={() => setHover(true)}
       onMouseLeave={() => setHover(false)}
       style={{ cursor: 'pointer', display: 'block' }}>

      {/* Outer card — handles lift + shadow */}
      <div style={{
        transition: 'transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease)',
        transform:  hover ? 'translateY(-5px)' : 'none',
        boxShadow:  hover ? '0 26px 50px -28px rgba(11,11,11,0.42)' : '0 0 0 rgba(0,0,0,0)',
      }}>
        {/* Portrait + overlay wrapper */}
        <div style={{ position: 'relative', overflow: 'hidden' }}>
          <Portrait
            shade={m.shade}
            photoUrl={m.coverUrl}
            idx={idx + 1}
            label={m.isNew ? 'New' : null}
            hover={hover}
          />

          {/* Semi-transparent stats overlay */}
          <div style={{
            position:   'absolute',
            inset:       0,
            background:  'rgba(11,11,11,0.62)',
            opacity:     hover ? 1 : 0,
            transition:  'opacity 300ms ease',
            display:     'flex',
            flexDirection: 'column',
            justifyContent: 'flex-end',
            padding:    '16px 14px',
            pointerEvents: 'none',
          }}>
            {stats.map(s => (
              <div key={s.k} style={{
                display: 'flex',
                justifyContent: 'space-between',
                alignItems: 'baseline',
                padding: '4px 0',
                borderBottom: '1px solid rgba(255,255,255,0.14)',
              }}>
                <span style={{
                  fontSize: 10, fontWeight: 500,
                  letterSpacing: '0.13em', textTransform: 'uppercase',
                  color: 'rgba(255,255,255,0.52)',
                }}>{s.k}</span>
                <span style={{
                  fontSize: 11, fontWeight: 500,
                  color: '#fff', fontVariantNumeric: 'tabular-nums',
                }}>{s.v}</span>
              </div>
            ))}
          </div>
        </div>
      </div>

      {/* Name + height below card */}
      <div style={{
        display: 'flex', alignItems: 'baseline',
        justifyContent: 'space-between', gap: 8, marginTop: 3,
      }}>
        <span style={{
          fontSize: 15, fontWeight: 500, letterSpacing: '-0.01em', whiteSpace: 'nowrap',
          borderBottom: hover ? '1px solid var(--ink)' : '1px solid transparent',
          transition: 'border-color var(--dur-fast) var(--ease)', paddingBottom: 1,
        }}>{m.name}</span>
        <span className="ts-stat" style={{ color: 'var(--ink-3)', flex: 'none' }}>{m.height}</span>
      </div>
    </a>
  );
}

function Hero({ mode, setMode }) {
  return (
    <section className="shell" style={{ paddingTop: 'clamp(16px,2.6vw,36px)', paddingBottom: 'clamp(14px,2vw,22px)' }}>
      <div style={{
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        gap: 'clamp(24px,5vw,80px)', flexWrap: 'wrap',
      }}>
        <div style={{ flex: '1 1 380px', minWidth: 0 }}>
          <h1 style={{
            fontFamily: 'var(--font-sans)', fontWeight: 500, margin: 0,
            fontSize: 'clamp(2.5rem, 6vw, 5.5rem)', lineHeight: 0.95, letterSpacing: '-0.035em',
          }}>
            <span className="hero-mask"><span className="hero-line hl1">Boutique-sized,</span></span>
            <span className="hero-mask"><span className="hero-line hl2">on purpose</span></span>
          </h1>
        </div>
        <div className="hero-logo-mark" style={{ flex: 1, display: 'flex', justifyContent: 'flex-end', alignItems: 'flex-end' }}>
          <img src="assets/logo-mark.png" alt="The Other Side" style={{
            display: 'block',
            height: 'clamp(4.75rem, 11.4vw, 10.45rem)',
            width: 'auto',
            opacity: 0.92,
            marginRight: 'clamp(16px, 12.5%, 180px)',
          }} />
        </div>
      </div>

      <div style={{ display: 'flex', gap: 22, marginTop: 'clamp(16px,2.4vw,28px)' }}>
        {[['grid', 'Grid'], ['index', 'Index']].map(([id, label]) => (
          <button key={id} onClick={() => setMode(id)} style={{
            border: 0, background: 'transparent', cursor: 'pointer', padding: '0 0 8px',
            color: mode === id ? 'var(--ink)' : 'var(--ink-3)',
            transition: 'color var(--dur-fast) var(--ease)',
          }}>
            <span className="ts-label">{label}</span>
          </button>
        ))}
      </div>
    </section>
  );
}

function Board({ models, onOpen }) {
  const [mode, setMode] = React.useState('grid');
  const shown = models || [];
  return (
    <div>
      <Hero mode={mode} setMode={setMode} />

      {mode === 'grid' ? (
        <section className="shell" style={{ paddingTop: 8, paddingBottom: 96 }}>
          <div className="board-grid" style={{
            display: 'grid',
            rowGap: 'max(0px, calc(clamp(14px,1.6vw,26px) - 22px))',
            columnGap: 'clamp(14px,1.6vw,26px)',
          }}>
            {shown.map((m, i) => (
              <ModelCard key={m.slug || m._id} m={m} idx={i} onOpen={onOpen} />
            ))}
          </div>
        </section>
      ) : (
        <BoardIndex models={shown} onOpen={onOpen} />
      )}
    </div>
  );
}
window.Board  = Board;
window.ModelCard = ModelCard;
