// Product card component + data
const PRODUCTS = [
  { id:'p1', name:'Печь для бани Торнадо-14 сетка дровяная', brand:'Торнадо', art:'УП-00032226', price:113400, oldPrice:null, stock:13, rating:4.5, reviews:23, badges:[], category:'Печи для бани дровяные', specs:['Объём парилки: 8–14 м³','Сталь топки: 6 мм','Камни: до 60 кг','Дымоход: ∅115'] },
  { id:'p2', name:'Печь для бани GFS Авангард Ураган 25П2С ЗК круглая чугунная', brand:'GFS', art:'УП-00032227', price:103400, oldPrice:133800, stock:5, rating:4.8, reviews:41, badges:['hit','new','sale'], category:'Печи для бани дровяные', specs:['Объём парилки: 14–25 м³','Чугун, панорамное стекло','Камни: до 90 кг','Гарантия 10 лет'] },
  { id:'p3', name:'Печь для бани Сибирь Копеечка', brand:'Сибирь', art:'УП-00032228', price:113400, oldPrice:null, stock:8, rating:4.3, reviews:12, badges:['hit'], category:'Печи для бани дровяные', specs:['Объём парилки: 8–16 м³','Сталь: 8 мм','Конвекционный кожух','Нагрев за 45 мин'] },
  { id:'p4', name:'Термокрышка POLAR Spa COMFORT 160', brand:'POLAR', art:'УП-00032229', price:41000, oldPrice:null, stock:1, rating:5.0, reviews:7, badges:['new'], category:'Банные аксессуары', specs:['Диаметр: Ø160 см','Изоляция: 80 мм','Удержание тепла: 12 ч','Антискользящее покрытие'] },
  { id:'p5', name:'Дымоход нержавеющая сталь AISI 439 ∅115', brand:'Феррум', art:'УП-00030014', price:4280, oldPrice:4890, stock:47, rating:4.6, reviews:58, badges:['sale'], category:'Дымоходы нержавеющие', specs:['∅ внутренний: 115 мм','Длина: 1000 мм','AISI 439, 0,8 мм','До 750 °C'] },
  { id:'p6', name:'Камни для каменки Габбро-диабаз колотый 20 кг', brand:'КАМ', art:'УП-00030215', price:980, oldPrice:null, stock:120, rating:4.9, reviews:204, badges:['hit'], category:'Камни для каменки', specs:['Фракция: 70–120 мм','Упаковка: 20 кг','Колотый, отмытый','Сертификат в комплекте'] },
  { id:'p7', name:'Дверь для бани стеклянная Эстет 700×1900', brand:'Эстет', art:'УП-00028811', price:18900, oldPrice:null, stock:6, rating:4.7, reviews:19, badges:[], category:'Двери для бани стеклянные', specs:['Размер: 700×1900 мм','Стекло: закалённое 8 мм','Коробка: осина','Ручка-скоба в комплекте'] },
  { id:'p8', name:'Печь банная Везувий Скиф Стандарт 22 антрацит', brand:'Везувий', art:'УП-00031902', price:52700, oldPrice:58900, stock:9, rating:4.4, reviews:33, badges:['sale'], category:'Печи для бани дровяные', specs:['Объём парилки: 12–22 м³','Сталь: 4 мм','Бак для воды: 65 л','Ковка «антрацит»'] },
  { id:'p9', name:'Огнезащитный экран ЗВИ-У 1000×600', brand:'ЗВИ', art:'УП-00030507', price:6450, oldPrice:null, stock:23, rating:4.5, reviews:14, badges:['new'], category:'Огнезащита', specs:['Размер: 1000×600 мм','Базальт + нержавейка','До 900 °C','Сертификат МЧС'] },
  { id:'p10', name:'Чугунная плита одноконфорочная 410×360', brand:'ЛИТКОМ', art:'УП-00029118', price:3200, oldPrice:null, stock:0, rating:4.2, reviews:8, badges:[], category:'Чугунное литьё для печей', specs:['Размер: 410×360 мм','Вес: 8,2 кг','Съёмное кольцо','Чугун СЧ-20'] },
  { id:'p11', name:'Бондарное изделие: ушат кедр 15 л', brand:'БаняКедр', art:'УП-00028322', price:4100, oldPrice:null, stock:14, rating:4.8, reviews:27, badges:['hit'], category:'Бондарные изделия для бани', specs:['Объём: 15 л','Материал: алтайский кедр','Нерж. обручи','Льняное масло'] },
  { id:'p12', name:'Обливное устройство «Водопад» 15 л нерж.', brand:'БаняПро', art:'УП-00028655', price:5980, oldPrice:null, stock:0, rating:4.6, reviews:11, badges:[], category:'Обливное устройство', specs:['Объём: 15 л','Нержавеющая сталь','Пуск за цепочку','Монтажные петли'] },
];

function fmtPrice(n) {
  return n.toLocaleString('ru-RU') + ' ₽';
}

function StockLabel({ stock }) {
  if (stock === 0) return (
    <span style={{display:'inline-flex',alignItems:'center',gap:6,fontFamily:'var(--rc)',fontSize:14,color:'var(--text-2)'}}>
      <span style={{width:6,height:6,borderRadius:'50%',background:'var(--text-3)'}}/>
      Под заказ
    </span>
  );
  const color = stock > 5 ? 'var(--green)' : 'var(--orange)';
  return (
    <span style={{display:'inline-flex',alignItems:'center',gap:6,fontFamily:'var(--rc)',fontSize:14,color}}>
      <span style={{width:6,height:6,borderRadius:'50%',background:color}}/>
      В наличии: {stock}
    </span>
  );
}

function Bages({ list, dense = false }) {
  if (!list || !list.length) return null;
  const map = { hit: { label: 'ХИТ', cls: 'badge-hit' }, new: { label: 'НОВИНКА', cls: 'badge-new' }, sale: { label: '-10%', cls: 'badge-sale' } };
  return (
    <div style={{position:'absolute',top:8,left:8,display:'flex',gap:6,flexWrap:'wrap'}}>
      {list.map((b,i) => <span key={i} className={`badge ${map[b].cls}`}>{map[b].label}</span>)}
    </div>
  );
}

function QtyControl({ qty, onChange, size = 'md', style }) {
  const h = size === 'sm' ? 48 : 56;
  const inner = h - 8; // 2px border + 2px gap on each side
  const minusActive = qty > 0;
  return (
    <div className="qty-control" style={{
      display:'flex',alignItems:'center',width:'100%',
      height: h, borderRadius: h/2,
      background:'var(--bg-soft-2)', border:'2px solid var(--line-2)',
      padding: 2, boxSizing:'border-box',
      ...style
    }}>
      <button onClick={() => onChange(Math.max(0, qty - 1))} aria-label="Уменьшить" disabled={!minusActive} style={{
        flex:'0 0 auto', width: inner*1.35, height: inner, borderRadius: inner/2,
        background: minusActive ? 'var(--red)' : 'var(--bg-soft)',
        display:'inline-flex',alignItems:'center',justifyContent:'center',
        color: minusActive ? '#FFFFFF' : 'var(--text-3)',
        border:'none', cursor: minusActive ? 'pointer' : 'not-allowed',
        transition:'background .15s, color .15s'
      }}
      onMouseEnter={e=>{ if(minusActive){ e.currentTarget.style.background='var(--red-dark)'; } }}
      onMouseLeave={e=>{ if(minusActive){ e.currentTarget.style.background='var(--red)'; } }}
      ><Icon.Minus style={{width:22,height:22}}/></button>
      <div style={{flex:1, height: inner, background:'transparent',
        display:'flex',alignItems:'center',justifyContent:'center',
        fontFamily:'var(--rc)',fontWeight:500,fontSize:18,color:'var(--text)',letterSpacing:'-0.02em'
      }}>{qty}</div>
      <button onClick={() => onChange(qty + 1)} aria-label="Увеличить" style={{
        flex:'0 0 auto', width: inner*1.35, height: inner, borderRadius: inner/2, background:'var(--red)',
        display:'inline-flex',alignItems:'center',justifyContent:'center', color:'#FFFFFF',
        border:'none', cursor:'pointer', transition:'background .15s'
      }} onMouseEnter={e => e.currentTarget.style.background='var(--red-dark)'} onMouseLeave={e => e.currentTarget.style.background='var(--red)'}><Icon.Plus style={{width:22,height:22}}/></button>
    </div>
  );
}

function ProductCard({ p, idx = 0, variant = 'grid', favSet, compSet, onFav, onComp, cartMap, onQty, onOrder }) {
  const qty = cartMap[p.id] || 0;
  const isFav = favSet.has(p.id);
  const isComp = compSet.has(p.id);
  const [copied, setCopied] = useState(false);
  const [imgIdx, setImgIdx] = useState(0);
  const imgCount = 5;
  const handleImgMove = (e) => {
    const r = e.currentTarget.getBoundingClientRect();
    const x = e.clientX - r.left;
    const zone = Math.min(imgCount - 1, Math.max(0, Math.floor((x / r.width) * imgCount)));
    setImgIdx(zone);
  };
  const handleImgLeave = () => setImgIdx(0);
  // Тач-эквивалент hover-zones для мобиля: на мобильниках нет курсора,
  // поэтому проводим пальцем слева-направо по фото — миниатюры
  // переключаются как при hover-навигации. После окончания тача
  // последний индекс сохраняется (без handleImgLeave), как у Wildberries/OZON.
  const handleImgTouch = (e) => {
    const r = e.currentTarget.getBoundingClientRect();
    const t = e.touches?.[0] || e.changedTouches?.[0];
    if (!t) return;
    const x = t.clientX - r.left;
    const zone = Math.min(imgCount - 1, Math.max(0, Math.floor((x / r.width) * imgCount)));
    setImgIdx(zone);
  };
  const copyArt = (e) => { e.preventDefault(); e.stopPropagation(); navigator.clipboard?.writeText(p.art); setCopied(true); setTimeout(() => setCopied(false), 1200); };
  const bagesMap = { hit:{label:'ХИТ',cls:'badge-hit'}, new:{label:'НОВИНКА',cls:'badge-new'}, sale:{label:'-10%',cls:'badge-sale'} };

  if (variant === 'table') {
    return (
      <div className="table-row" style={{display:'grid',gap:12,alignItems:'center',background:'#FFFFFF',borderRadius:12,padding:'8px 12px',border:'1px solid var(--line-2)',transition:'border-color .15s, background .15s',fontFamily:'var(--rc)'}}
           onMouseEnter={e=>{e.currentTarget.style.borderColor='var(--line)';e.currentTarget.style.background='var(--bg-soft)';}}
           onMouseLeave={e=>{e.currentTarget.style.borderColor='var(--line-2)';e.currentTarget.style.background='#FFFFFF';}}>
        <a href={`product.html?id=${p.id}`} style={{position:'relative',width:56,height:56,borderRadius:8,overflow:'hidden',background:'#FFFFFF',border:'1px solid var(--line-2)',display:'block',flexShrink:0}}>
          <ProductPlaceholder variant={idx} label={p.brand}/>
        </a>
        <div style={{minWidth:0,display:'flex',flexDirection:'column',gap:2}}>
          <a href={`product.html?id=${p.id}`} style={{fontSize:14,lineHeight:1.25,color:'var(--text)',fontWeight:500,display:'-webkit-box',WebkitLineClamp:2,WebkitBoxOrient:'vertical',overflow:'hidden'}}>{p.name}</a>
          <div style={{display:'flex',alignItems:'center',gap:8,fontSize:12,color:'var(--text-3)'}}>
            <span>{p.brand}</span>
            <span style={{width:2,height:2,borderRadius:'50%',background:'var(--text-3)'}}/>
            <span>Арт. {p.art}</span>
            <button onClick={copyArt} title={copied?'Скопировано':'Скопировать артикул'} style={{width:22,height:22,borderRadius:5,background:'transparent',display:'inline-flex',alignItems:'center',justifyContent:'center',color:copied?'var(--green)':'var(--text-3)',border:'none',cursor:'pointer'}}>
              {copied ? <Icon.Check style={{width:15,height:15}}/> : <Icon.Copy style={{width:15,height:15}}/>}
            </button>
            {!!p.badges.length && p.badges.map((b,i)=><span key={i} className={`badge ${bagesMap[b].cls}`} style={{height:16,padding:'0 6px',fontSize:10}}>{bagesMap[b].label}</span>)}
          </div>
        </div>
        <div style={{fontSize:13,color:'var(--text-2)',display:'flex',alignItems:'center',gap:6}}>
          <Icon.Star style={{width:13,height:13,color:'var(--orange)'}}/>
          <span style={{color:'var(--text)'}}>{p.rating}</span>
          <span style={{color:'var(--text-3)'}}>· {p.reviews}</span>
        </div>
        <div style={{fontSize:13}}><StockLabel stock={p.stock}/></div>
        <div style={{textAlign:'right'}}>
          <div style={{fontWeight:700,fontSize:17,color:p.oldPrice?'var(--red)':'var(--text)',lineHeight:1,letterSpacing:'-0.01em'}}>{fmtPrice(p.price)}</div>
          {p.oldPrice && <div style={{fontSize:12,color:'var(--text-3)',textDecoration:'line-through',marginTop:2}}>{fmtPrice(p.oldPrice)}</div>}
        </div>
        <div style={{display:'flex',gap:4,justifyContent:'flex-end'}}>
          <button onClick={()=>onFav(p.id)} title="В избранное" style={{width:32,height:32,borderRadius:8,background:'transparent',display:'inline-flex',alignItems:'center',justifyContent:'center',color:isFav?'var(--red)':'var(--text-3)',border:'none',cursor:'pointer',transition:'background .15s, color .15s'}}
            onMouseEnter={e=>{e.currentTarget.style.background='var(--line)';e.currentTarget.style.color='var(--red)';}}
            onMouseLeave={e=>{e.currentTarget.style.background='transparent';e.currentTarget.style.color=isFav?'var(--red)':'var(--text-3)';}}>
            {isFav ? <Icon.HeartFill style={{width:16,height:16}}/> : <Icon.Heart style={{width:16,height:16}}/>}
          </button>
          <button onClick={()=>onComp(p.id)} title="Сравнить" style={{width:32,height:32,borderRadius:8,background:'transparent',display:'inline-flex',alignItems:'center',justifyContent:'center',color:isComp?'var(--red)':'var(--text-3)',border:'none',cursor:'pointer',transition:'background .15s, color .15s'}}
            onMouseEnter={e=>{e.currentTarget.style.background='var(--line)';e.currentTarget.style.color='var(--red)';}}
            onMouseLeave={e=>{e.currentTarget.style.background='transparent';e.currentTarget.style.color=isComp?'var(--red)':'var(--text-3)';}}>
            <Icon.BarChart style={{width:16,height:16}}/>
          </button>
        </div>
        <div>
          {p.stock > 0 ? (
            qty > 0 ? (
              <div style={{display:'inline-flex',alignItems:'center',height:36,borderRadius:18,background:'var(--bg-soft)',padding:2,width:'100%'}}>
                <button onClick={()=>onQty(p.id,Math.max(0,qty-1))} style={{flex:'0 0 auto',width:32,height:32,borderRadius:16,background:'var(--red)',color:'#FFFFFF',display:'inline-flex',alignItems:'center',justifyContent:'center',border:'none',cursor:'pointer'}}><Icon.Minus style={{width:14,height:14}}/></button>
                <div style={{flex:1,textAlign:'center',fontWeight:500,fontSize:14,color:'var(--text)'}}>{qty}</div>
                <button onClick={()=>onQty(p.id,qty+1)} style={{flex:'0 0 auto',width:32,height:32,borderRadius:16,background:'var(--red)',color:'#FFFFFF',display:'inline-flex',alignItems:'center',justifyContent:'center',border:'none',cursor:'pointer'}}><Icon.Plus style={{width:14,height:14}}/></button>
              </div>
            ) : (
              <button className="btn btn-primary" style={{width:'100%',height:36,borderRadius:18,fontSize:13,padding:'0 12px'}} onClick={()=>onQty(p.id,1)}>
                <Icon.Cart style={{width:14,height:14}}/> В корзину
              </button>
            )
          ) : (
            <button className="btn btn-primary" style={{width:'100%',height:36,borderRadius:18,fontSize:13}} onClick={()=>onOrder && onOrder(p)}>Заказать</button>
          )}
        </div>
      </div>
    );
  }

  if (variant === 'list') {
    return (
      <div style={{display:'grid',gridTemplateColumns:'220px 1fr 260px',gap:24,background:'var(--bg-card)',borderRadius:24,padding:16,border:'1px solid transparent',transition:'border-color .15s'}}
           onMouseEnter={e=>e.currentTarget.style.borderColor='var(--line)'}
           onMouseLeave={e=>e.currentTarget.style.borderColor='transparent'}>
        <a href={`product.html?id=${p.id}`} onMouseMove={handleImgMove} onMouseLeave={handleImgLeave} onTouchStart={handleImgTouch} onTouchMove={handleImgTouch} style={{position:'relative',aspectRatio:'1/1',borderRadius:16,overflow:'hidden',background:'#FFFFFF',border:'1px solid var(--line-2)',display:'block',touchAction:'pan-y'}}>
          <div style={{position:'absolute',inset:0}}>
            {Array.from({length:imgCount}).map((_,i) => (
              <div key={i} style={{
                position:'absolute',inset:0,
                opacity: imgIdx===i ? 1 : 0,
                transition:'opacity .25s ease'
              }}>
                <img src={`assets/bag-${i+1}.png`} alt="" style={{width:'100%',height:'100%',objectFit:'contain',display:'block'}}/>
              </div>
            ))}
          </div>
          {!!p.badges.length && <div style={{position:'absolute',top:8,left:8,display:'flex',gap:6}}>{p.badges.map((b,i)=><span key={i} className={`badge ${bagesMap[b].cls}`}>{bagesMap[b].label}</span>)}</div>}
          <div style={{position:'absolute',bottom:10,left:'50%',transform:'translateX(-50%)',display:'inline-flex',alignItems:'center',gap:5,background:'var(--bg-soft)',padding:4,borderRadius:999,pointerEvents:'none'}}>
            {Array.from({length:imgCount}).map((_,i) => (
              <span key={i} style={{width:6,height:6,borderRadius:'50%',background:imgIdx===i?'var(--red)':'var(--text-3)',display:'block',transition:'background .2s'}}/>
            ))}
          </div>
        </a>
        <div style={{display:'flex',flexDirection:'column',gap:10,minWidth:0}}>
          <a href={`product.html?id=${p.id}`} style={{fontFamily:'"Roboto Condensed", var(--rc)',fontWeight:500,fontSize:18,lineHeight:1.2,letterSpacing:0,color:'var(--text)',display:'block'}}>{p.name}</a>
          {p.specs && p.specs.length > 0 && (
            <ul style={{listStyle:'none',padding:0,margin:0,display:'flex',flexDirection:'column',gap:3,fontFamily:'var(--rc)',fontSize:13,color:'var(--text-2)',lineHeight:1.35}}>
              {p.specs.map((s,i) => (
                <li key={i} style={{display:'flex',alignItems:'flex-start',gap:8}}>
                  <span style={{width:3,height:3,borderRadius:'50%',background:'var(--orange)',marginTop:7,flexShrink:0}}/>
                  <span>{s}</span>
                </li>
              ))}
            </ul>
          )}
          <div style={{display:'flex',alignItems:'center',gap:12,flexWrap:'wrap'}}>
            <span style={{fontFamily:'var(--rc)',fontSize:13,color:'var(--text-2)'}}>Бренд: <a href={`catalog.html?brand=${encodeURIComponent(p.brand)}`} style={{color:'var(--text)',textDecoration:'none',borderBottom:'1px dashed var(--text-3)',transition:'color .15s, border-color .15s'}}
              onMouseEnter={e=>{e.currentTarget.style.color='var(--red)';e.currentTarget.style.borderBottomColor='var(--red)';}}
              onMouseLeave={e=>{e.currentTarget.style.color='var(--text)';e.currentTarget.style.borderBottomColor='var(--text-3)';}}>{p.brand}</a></span>
            <span style={{fontFamily:'var(--rc)',fontSize:13,color:'var(--text-2)',display:'inline-flex',alignItems:'center',gap:6}}>
              Арт.: {p.art}
              <button onClick={copyArt} title={copied?'Скопировано':'Скопировать артикул'} style={{width:22,height:22,borderRadius:4,background:copied?'var(--green)':'transparent',display:'inline-flex',alignItems:'center',justifyContent:'center',color:copied?'#FFFFFF':'var(--text-2)',border:'none',cursor:'pointer',transition:'background .15s, color .15s'}}
                onMouseEnter={e=>{if(!copied){e.currentTarget.style.background='var(--red)';e.currentTarget.style.color='#FFFFFF';}}}
                onMouseLeave={e=>{if(!copied){e.currentTarget.style.background='transparent';e.currentTarget.style.color='var(--text-2)';}}}>
                {copied ? <Icon.Check style={{width:13,height:13}}/> : <Icon.Copy style={{width:13,height:13}}/>}
              </button>
            </span>
          </div>
          <div style={{display:'flex',alignItems:'center',gap:12,fontFamily:'var(--rc)',fontSize:13,color:'var(--text-2)'}}>
            <span style={{display:'inline-flex',alignItems:'center',gap:4}}><Icon.Star style={{width:14,height:14,color:'var(--orange)'}}/> {p.rating}</span>
            <span>· {p.reviews} отзывов</span>
            <StockLabel stock={p.stock}/>
          </div>
        </div>
        <div style={{display:'flex',flexDirection:'column',justifyContent:'space-between',alignItems:'flex-end',gap:12}}>
          <div style={{display:'flex',flexDirection:'column',alignItems:'flex-end',gap:4}}>
            <div style={{display:'flex',alignItems:'baseline',gap:8,flexWrap:'wrap',justifyContent:'flex-end'}}>
              <span style={{fontFamily:'var(--rc)',fontWeight:700,fontSize:22,lineHeight:1,color:p.oldPrice?'var(--red)':'var(--text)',letterSpacing:'-0.02em'}}>
                {p.price.toLocaleString('ru-RU')} ₽<span style={{fontSize:16,color:p.oldPrice?'var(--red)':'var(--text)',fontWeight:500}}>/шт.</span>
              </span>
              {p.oldPrice && <span style={{fontFamily:'"Roboto Condensed", var(--rc)',fontWeight:400,fontSize:16,lineHeight:'120%',color:'var(--text)',textDecoration:'line-through'}}>{fmtPrice(p.oldPrice)}</span>}
            </div>
          </div>
          <div style={{display:'flex',gap:8,width:'100%'}}>
            <button onClick={()=>onFav(p.id)} title="В избранное" style={{width:44,height:44,borderRadius:12,background:'var(--bg-soft)',display:'inline-flex',alignItems:'center',justifyContent:'center',color:isFav?'var(--red)':'var(--text-2)',border:'none',cursor:'pointer',transition:'background .15s, color .15s'}}
              onMouseEnter={e=>{e.currentTarget.style.background='var(--line)';e.currentTarget.style.color='var(--red)';}}
              onMouseLeave={e=>{e.currentTarget.style.background='var(--bg-soft)';e.currentTarget.style.color=isFav?'var(--red)':'var(--text-2)';}}>
              {isFav ? <Icon.HeartFill style={{width:20,height:20}}/> : <Icon.Heart style={{width:20,height:20}}/>}
            </button>
            <button onClick={()=>onComp(p.id)} title="Сравнить" style={{width:44,height:44,borderRadius:12,background:'var(--bg-soft)',display:'inline-flex',alignItems:'center',justifyContent:'center',color:isComp?'var(--red)':'var(--text-2)',border:'none',cursor:'pointer',transition:'background .15s, color .15s'}}
              onMouseEnter={e=>{e.currentTarget.style.background='var(--line)';e.currentTarget.style.color='var(--red)';}}
              onMouseLeave={e=>{e.currentTarget.style.background='var(--bg-soft)';e.currentTarget.style.color=isComp?'var(--red)':'var(--text-2)';}}>
              <Icon.BarChart style={{width:20,height:20}}/>
            </button>
            {p.stock > 0 ? (qty > 0 ? <QtyControl qty={qty} onChange={n=>onQty(p.id,n)} size="sm"/> :
              <button className="btn btn-primary btn-sm" style={{flex:1}} onClick={()=>onQty(p.id,1)}>В корзину</button>
            ) : <button className="btn btn-primary btn-sm" style={{flex:1}} onClick={()=>onOrder && onOrder(p)}>Заказать</button>}
          </div>
        </div>
      </div>
    );
  }

  // GRID — matches Figma mockup
  return (
    <div style={{background:'var(--bg-card)',border:'1px solid var(--line)',borderRadius:28,padding:4,display:'flex',flexDirection:'column',gap:12,transition:'box-shadow .15s, border-color .15s'}}
         onMouseEnter={e=>{e.currentTarget.style.boxShadow='0 4px 16px rgba(0,0,0,0.06)';e.currentTarget.style.borderColor='var(--text-3)';}}
         onMouseLeave={e=>{e.currentTarget.style.boxShadow='none';e.currentTarget.style.borderColor='var(--line)';}}>
      <a href={`product.html?id=${p.id}`} onMouseMove={handleImgMove} onMouseLeave={handleImgLeave} onTouchStart={handleImgTouch} onTouchMove={handleImgTouch} style={{position:'relative',aspectRatio:'1/1',borderRadius:24,overflow:'hidden',background:'#FFFFFF',display:'block',touchAction:'pan-y'}}>
        <div style={{position:'absolute',inset:0}}>
          {Array.from({length:imgCount}).map((_,i) => (
            <div key={i} style={{
              position:'absolute',inset:0,
              opacity: imgIdx===i ? 1 : 0,
              transition:'opacity .25s ease'
            }}>
              <img src={`assets/bag-${i+1}.png`} alt="" style={{width:'100%',height:'100%',objectFit:'contain',display:'block'}}/>
            </div>
          ))}
        </div>
        <Bages list={p.badges.filter(b=>b!=='sale')}/>
        {p.badges.includes('sale') && <div style={{position:'absolute',bottom:12,left:12}}><span className="badge badge-sale">-10%</span></div>}
        <div style={{position:'absolute',bottom:12,right:12,display:'flex',flexDirection:'column',gap:8}}>
          <button onClick={(e)=>{e.preventDefault();onFav(p.id);}} aria-label="В избранное" style={{width:40,height:40,borderRadius:'50%',background:'var(--line-2)',display:'inline-flex',alignItems:'center',justifyContent:'center',color:isFav?'var(--red)':'var(--text-2)',transition:'color .15s, background .15s',border:'none',cursor:'pointer'}}
            onMouseEnter={e=>{e.currentTarget.style.background='var(--line)';e.currentTarget.style.color='var(--red)';}}
            onMouseLeave={e=>{e.currentTarget.style.background='var(--line-2)';e.currentTarget.style.color=isFav?'var(--red)':'var(--text-2)';}}>
            {isFav ? <Icon.HeartFill style={{width:18,height:18}}/> : <Icon.Heart style={{width:18,height:18}}/>}
          </button>
          <button onClick={(e)=>{e.preventDefault();onComp(p.id);}} aria-label="Сравнить" style={{width:40,height:40,borderRadius:'50%',background:'var(--line-2)',display:'inline-flex',alignItems:'center',justifyContent:'center',color:isComp?'var(--red)':'var(--text-2)',border:'none',transition:'color .15s, background .15s',cursor:'pointer'}}
            onMouseEnter={e=>{e.currentTarget.style.background='var(--line)';e.currentTarget.style.color='var(--red)';}}
            onMouseLeave={e=>{e.currentTarget.style.background='var(--line-2)';e.currentTarget.style.color=isComp?'var(--red)':'var(--text-2)';}}>
            <Icon.BarChart style={{width:18,height:18}}/>
          </button>
        </div>
        {/* pagination dots — bottom-center, wrapped in pill (visual only; image switches on hover zones) */}
        <div style={{position:'absolute',bottom:14,left:'50%',transform:'translateX(-50%)',display:'inline-flex',alignItems:'center',gap:5,background:'var(--bg-soft)',padding:4,borderRadius:999,pointerEvents:'none'}}>
          {Array.from({length:imgCount}).map((_,i) => (
            <span key={i} style={{width:6,height:6,borderRadius:'50%',background:imgIdx===i?'var(--red)':'var(--text-3)',display:'block',transition:'background .2s'}}/>
          ))}
        </div>
      </a>
      <div style={{padding:'0 11px',marginTop:3,display:'flex',flexDirection:'column',gap:12}}>
        <a href={`product.html?id=${p.id}`} style={{fontFamily:'"Roboto Condensed", var(--rc)',fontWeight:500,fontSize:18,lineHeight:1.2,letterSpacing:0,color:'var(--text)',minHeight:44,display:'-webkit-box',WebkitLineClamp:2,WebkitBoxOrient:'vertical',overflow:'hidden'}}>{p.name}</a>
        <div style={{display:'flex',flexDirection:'column',gap:8}}>
          <div style={{display:'flex',alignItems:'baseline',gap:8,flexWrap:'wrap'}}>
            <span style={{fontFamily:'var(--rc)',fontWeight:700,fontSize:22,lineHeight:1,color:p.oldPrice?'var(--red)':'var(--text)',letterSpacing:'-0.02em'}}>
              {p.price.toLocaleString('ru-RU')} ₽<span style={{fontSize:16,color:p.oldPrice?'var(--red)':'var(--text)',fontWeight:500}}>/шт.</span>
            </span>
            {p.oldPrice && <span style={{fontFamily:'"Roboto Condensed", var(--rc)',fontWeight:400,fontStyle:'normal',fontSize:16,lineHeight:'120%',letterSpacing:0,color:'var(--text)',textDecoration:'line-through'}}>{fmtPrice(p.oldPrice)}</span>}
          </div>
          <div style={{display:'flex',alignItems:'center',gap:8}}>
            <span style={{fontFamily:'"Roboto Condensed", var(--rc)',fontWeight:400,fontSize:14,lineHeight:1.2,letterSpacing:0,color:'var(--text-3)'}}>Арт.: {p.art}</span>
            <button onClick={copyArt} title={copied?'Скопировано':'Скопировать артикул'} style={{width:24,height:24,borderRadius:6,background:copied?'var(--green)':'transparent',display:'inline-flex',alignItems:'center',justifyContent:'center',color:copied?'#FFFFFF':'var(--text-3)',border:'none',cursor:'pointer',transition:'background .15s, color .15s'}}
              onMouseEnter={e=>{if(!copied){e.currentTarget.style.background='var(--red)';e.currentTarget.style.color='#FFFFFF';}}}
              onMouseLeave={e=>{if(!copied){e.currentTarget.style.background='transparent';e.currentTarget.style.color='var(--text-3)';}}}>
              {copied ? <Icon.Check style={{width:16,height:16}}/> : <Icon.Copy style={{width:16,height:16}}/>}
            </button>
          </div>
          <div style={{display:'flex',alignItems:'center',gap:12,justifyContent:'space-between'}}>
            <span style={{display:'inline-flex',alignItems:'center',gap:6,fontFamily:'var(--rc)',fontSize:14,color:'var(--text)'}}>
              <Icon.Star style={{width:16,height:16,color:'var(--orange)'}}/> {p.rating}
            </span>
            <StockLabel stock={p.stock}/>
          </div>
        </div>
      </div>
      {p.stock > 0 ? (
        qty > 0 ? (
          <QtyControl qty={qty} onChange={n=>onQty(p.id,n)} style={{marginTop:'auto'}}/>
        ) : (
          <button className="btn btn-primary" style={{width:'100%',height:52,borderRadius:26,fontSize:15,marginTop:'auto'}} onClick={()=>onQty(p.id,1)}>
            <Icon.Cart style={{width:18,height:18}}/> В корзину
          </button>
        )
      ) : (
        <button className="btn btn-primary" style={{width:'100%',height:52,borderRadius:26,marginTop:'auto'}} onClick={()=>onOrder && onOrder(p)}>Заказать</button>
      )}
    </div>
  );
}

Object.assign(window, { PRODUCTS, fmtPrice, StockLabel, QtyControl, ProductCard });
