[object Object]

← back to All Designerwallcoverings

all. cards: gallery count badge + hover-cycle through full Shopify image set

fe345ea31ea5200147ac350ad5913288221edbd1 · 2026-07-08 12:34:14 -0700 · Steve

Files touched

Diff

commit fe345ea31ea5200147ac350ad5913288221edbd1
Author: Steve <steve@designerwallcoverings.com>
Date:   Wed Jul 8 12:34:14 2026 -0700

    all. cards: gallery count badge + hover-cycle through full Shopify image set
---
 public/index.html | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/public/index.html b/public/index.html
index 96590f8..f404305 100644
--- a/public/index.html
+++ b/public/index.html
@@ -112,6 +112,8 @@
   .fmspec { margin-top:3px; font-size:calc(9.5px*var(--fs)); color:var(--mut); line-height:1.5; }
   .fmspec b { color:#8aa6c9; font-weight:600; letter-spacing:.02em; }
   .badge.disco { background:#3a1616; color:#e0b3b3; }
+  .imgcount { position:absolute; bottom:6px; right:6px; background:rgba(0,0,0,.62); color:#fff; font-size:10px;
+    font-weight:600; padding:1px 6px; border-radius:20px; letter-spacing:.02em; pointer-events:none; }
   /* discontinued → red banner (search yields no live grid results) + red-card successor line */
   #discoBanner { display:none; margin:12px 14px 0; padding:14px 16px; border:1px solid #c0392b;
     border-left:5px solid #c0392b; border-radius:10px; background:#2a1414; color:#f0d6d6; }
@@ -821,8 +823,11 @@ function card(r) {
   if (r.sku) el.dataset.sku = String(r.sku);
   const stBadge = (r.lifecycle && r.lifecycle !== 'Active on site') ? `<span class="badge ${lifeClass(r)}">${r.lifecycle}</span>` : '';
   const discoBadge = r.fm_discontinued ? `<span class="badge disco" title="FileMaker Pro: discontinued ${esc(r.fm_disco_date || '')}">FM Disco</span>` : '';
+  // gallery: hover the thumb to cycle every image (Shopify full image set)
+  const gcount = (r.image_count || (r.images ? r.images.length : (r.image ? 1 : 0)));
+  const galBadge = gcount > 1 ? `<span class="imgcount" title="${gcount} images — hover to cycle">⧉ ${gcount}</span>` : '';
   const thumb = r.image
-    ? `<div class="thumb" style="background-image:url('${r.image}')">${stBadge}${discoBadge}</div>`
+    ? `<div class="thumb" style="background-image:url('${r.image}')">${stBadge}${discoBadge}${galBadge}</div>`
     : `<div class="thumb empty">${stBadge}${discoBadge}no image</div>`;
   const vt = [r.vendor, r.type].filter(Boolean).join(' · ');
   const mfrn = mfrHTML(r);
@@ -833,6 +838,12 @@ function card(r) {
   el.innerHTML = `${thumb}<div class="meta"><div class="sku">${r.sku || '—'}</div><div class="ttl" title="${(r.title || '').replace(/"/g, '&quot;')}">${r.title || ''}</div>${vt ? `<div class="vt">${vt}</div>` : ''}${mfrn}${mfrname}${fmspec}${fac ? `<div class="fac">${fac}</div>` : ''}${price}${whenChip(r).html}</div><div class="acts">${actButtonsHTML(r)}</div>`;
   const acts = el.querySelector('.acts'); if (acts) acts.addEventListener('click', (e) => { e.stopPropagation(); handleActsClick(e); });
   if (r.url) { el.style.cursor = 'pointer'; el.onclick = () => window.open(r.url, '_blank', 'noopener,noreferrer'); }
+  // hover-cycle the full Shopify gallery on the thumb (no extra requests — urls already in the row)
+  if (gcount > 1 && r.images && r.images.length > 1) {
+    const th = el.querySelector('.thumb'); let iv = null, i = 0;
+    th.addEventListener('mouseenter', () => { iv = setInterval(() => { i = (i + 1) % r.images.length; th.style.backgroundImage = `url('${r.images[i]}')`; }, 700); });
+    th.addEventListener('mouseleave', () => { clearInterval(iv); i = 0; th.style.backgroundImage = `url('${r.images[0]}')`; });
+  }
   return el;
 }
 

← 08c6237 Full Shopify image galleries: bulk-sync product_images + ser  ·  back to All Designerwallcoverings  ·  Designtex dw_sku backfill on mac3 CANONICAL dw_unified: prov 287e09e →