[object Object]

← back to Wallco Ai

yolo-queue: DP-2 ✓ static 96x96 thumbs + stash + click-swap

e0bff671f751c3c54d22791b9904d713c8affecd · 2026-05-25 20:04:46 -0700 · Steve Abrams

Files touched

Diff

commit e0bff671f751c3c54d22791b9904d713c8affecd
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Mon May 25 20:04:46 2026 -0700

    yolo-queue: DP-2 ✓ static 96x96 thumbs + stash + click-swap
---
 .yolo-queue.md |  8 +++++-
 server.js      | 81 ++++++++++++++++++++++++++++++++++------------------------
 2 files changed, 54 insertions(+), 35 deletions(-)

diff --git a/.yolo-queue.md b/.yolo-queue.md
index 4bc5f13..7107b95 100644
--- a/.yolo-queue.md
+++ b/.yolo-queue.md
@@ -25,7 +25,7 @@ never silently pause overnight.
   > admin-sheet-body has 10 children (5 tagged + recolor-wheel + 4 scripts).
   > 0 stray buyer cards, 0 stray admin cards. All movers fired cleanly.
 
-- [ ] **DP-2** Resize image-stack gallery thumbnails. Current implementation
+- [x] **DP-2** Resize image-stack gallery thumbnails. Current implementation
   uses `transform: scale(.18)` on the live UI, which crops content and
   shows too big (~50% width each). Replace with 96×96 static thumbnails
   using `design.image_url` as background + label overlay. Click-to-swap
@@ -33,6 +33,12 @@ never silently pause overnight.
   rather than into the thumb. Selector: `.img-stack-gallery .img-stack-thumb`
   in server.js around the `.img-stack-thumbs` CSS block.
 
+  > NOTE 2026-05-25 ✓ Static 96×96 thumbnails shipped. Verified via
+  > chrome-devtools: 2 thumbs sized correctly w/ bg image + icon + label,
+  > stash holds 2 inactive views, click-to-swap flips `.wallfit-crop`
+  > into main and other 2 stay as thumbs. Handlers preserved (appendChild
+  > moves live element rather than cloning).
+
 - [ ] **DP-3** Replace fashion-house brand buttons in the ADMIN drawer
   tone-on-tone block (server.js line ~10854 area, `.recolor-wheel`) with:
   a flat grid of all UNIQUE hex colors aggregated from
diff --git a/server.js b/server.js
index 13f7fe0..270070f 100644
--- a/server.js
+++ b/server.js
@@ -9664,30 +9664,34 @@ ${htmlHeader('/designs')}
         .ps-dot:hover::after { opacity:1; }
         .detail-img-wrap.ps-drop-active { outline: 3px dashed #c8b89a; outline-offset: -3px; }
 
-        /* Image-stack gallery: main slot + thumbs strip below.
-           At runtime the gallery script collects the hero / scale-preview /
-           wallfit-crop blocks, places one in .img-stack-main and renders
-           the other two as 96px tall thumbs in .img-stack-thumbs. Click a
-           thumb to swap it with the main. Steve 2026-05-25: "stack these
-           into a main image then 2 thumbs below, until you click on the
-           thumb and it becomes the main image". */
+        /* Image-stack gallery: main slot + static thumbs strip below.
+           Live views live in a hidden stash; thumbs are 96×96 image-based
+           buttons (background = design.image_url) with a label overlay.
+           Click a thumb → its corresponding live view swaps into the main
+           slot (so handlers stay alive). 2026-05-25 DP-2 revision: prior
+           transform:scale(.18) cropped content badly. Steve: "stack these
+           into a main image then 2 thumbs below". */
         .img-stack-gallery { margin-bottom:14px; }
         .img-stack-gallery .img-stack-main { margin:0; padding:0; }
         .img-stack-gallery .img-stack-main > * { display:block; margin:0 !important; padding-top:0 !important; }
-        /* Thumbs sit FLUSH directly under the hero — no gap, no separator
-           content. Steve 2026-05-25: "move both thumbs to directly below
-           the hero image". */
-        .img-stack-gallery .img-stack-thumbs { display:flex; gap:6px; margin:6px 0 0; padding:0; }
+        .img-stack-stash { display:none !important; }
+        .img-stack-gallery .img-stack-thumbs { display:flex; gap:8px; margin:8px 0 0; padding:0; justify-content:flex-start; }
         .img-stack-gallery .img-stack-thumb {
-          flex:1 1 0; min-width:0; max-height:108px; overflow:hidden;
+          width:96px; height:96px; flex:0 0 96px;
           border:1px solid var(--line,#ddd); border-radius:6px; cursor:pointer;
-          position:relative; background:#f5f0e4; transition:border-color .15s, transform .15s;
+          position:relative; overflow:hidden; background:#f5f0e4 center/cover no-repeat;
+          transition:border-color .15s, transform .15s, box-shadow .15s;
+        }
+        .img-stack-gallery .img-stack-thumb:hover { border-color:var(--gold,#c9a14b); transform:translateY(-1px); box-shadow:0 4px 12px rgba(0,0,0,.12); }
+        .img-stack-gallery .img-stack-thumb-icon {
+          position:absolute; top:6px; right:6px; width:22px; height:22px;
+          background:rgba(0,0,0,.55); color:#fff; border-radius:4px;
+          display:flex; align-items:center; justify-content:center;
+          font:600 12px var(--sans); pointer-events:none;
         }
-        .img-stack-gallery .img-stack-thumb:hover { border-color:var(--gold,#c9a14b); transform:translateY(-1px); }
-        .img-stack-gallery .img-stack-thumb > * { pointer-events:none; transform-origin:top left; transform:scale(.18); width:556%; height:556%; }
         .img-stack-gallery .img-stack-thumb-label {
-          position:absolute; bottom:0; left:0; right:0; padding:3px 6px;
-          background:linear-gradient(transparent, rgba(0,0,0,.62));
+          position:absolute; bottom:0; left:0; right:0; padding:4px 6px;
+          background:linear-gradient(transparent, rgba(0,0,0,.72));
           color:#fff; font:600 9.5px var(--sans); letter-spacing:.08em;
           text-transform:uppercase; text-align:center; pointer-events:none;
         }
@@ -9702,46 +9706,55 @@ ${htmlHeader('/designs')}
       </div>
       <script>
       (function(){
-        // Collect the 3 image blocks once DOM is built.
+        // DP-2 (2026-05-25): static thumbnails. Live views live in a hidden
+        // .img-stack-stash; thumbs are pure buttons (96×96 with
+        // design.image_url background + icon + label). Click → move that
+        // view from stash → main. Old main moves back to stash. Handlers
+        // stay live because appendChild moves the same element.
         function init() {
           var gal = document.querySelector('.img-stack-gallery');
           if (!gal) return;
           var main = gal.querySelector('.img-stack-main');
           var thumbs = gal.querySelector('.img-stack-thumbs');
+          // Discover the design image URL once (used as thumb background).
+          var heroImg = document.querySelector('.detail-img-wrap img.detail-img');
+          var bgUrl = heroImg ? heroImg.getAttribute('src') : '';
           var sources = [
-            { sel: '.detail-img-wrap', label: 'Pattern' },
-            { sel: '.scale-preview',   label: 'Scale' },
-            { sel: '.wallfit-crop',    label: 'Wall fit' },
+            { sel: '.detail-img-wrap', label: 'Pattern',  icon: '◧' },
+            { sel: '.scale-preview',   label: 'Scale',    icon: '▦' },
+            { sel: '.wallfit-crop',    label: 'Wall fit', icon: '□' },
           ];
           var views = sources.map(function(s){
             var el = document.querySelector(s.sel);
-            return el ? { el: el, label: s.label, sel: s.sel } : null;
+            return el ? { el: el, label: s.label, sel: s.sel, icon: s.icon } : null;
           }).filter(Boolean);
           if (views.length < 2) return; // not worth a gallery
-          // Move all view elements into a hidden wrapper so we can swap freely.
+          // Stash for inactive views (kept in DOM so handlers persist).
           var stash = document.createElement('div');
-          stash.style.display = 'none';
+          stash.className = 'img-stack-stash';
           gal.appendChild(stash);
           views.forEach(function(v){ stash.appendChild(v.el); });
-          // Pick active = the first view (hero / pattern).
           var activeIdx = 0;
           function render() {
-            // Move active into main, rest into thumbs.
-            main.innerHTML = ''; thumbs.innerHTML = '';
+            // Pop active view into main; everything else stays in stash.
+            var current = main.firstElementChild;
+            if (current) stash.appendChild(current);
             main.appendChild(views[activeIdx].el);
             main.dataset.active = views[activeIdx].sel;
+            // Rebuild thumb strip — pure buttons, no live UI inside.
+            thumbs.innerHTML = '';
             views.forEach(function(v, i){
               if (i === activeIdx) return;
-              var t = document.createElement('div');
+              var t = document.createElement('button');
+              t.type = 'button';
               t.className = 'img-stack-thumb';
               t.dataset.idx = i;
               t.title = 'Show: ' + v.label;
-              // Move v.el into the thumb (rendered at .18 scale via CSS).
-              t.appendChild(v.el);
-              var lab = document.createElement('div');
-              lab.className = 'img-stack-thumb-label';
-              lab.textContent = v.label;
-              t.appendChild(lab);
+              t.setAttribute('aria-label', 'Switch to ' + v.label + ' view');
+              if (bgUrl) t.style.backgroundImage = "url('" + bgUrl + "')";
+              t.innerHTML =
+                '<span class="img-stack-thumb-icon">' + v.icon + '</span>' +
+                '<span class="img-stack-thumb-label">' + v.label + '</span>';
               thumbs.appendChild(t);
             });
           }

← f73bb22 drunk-animals + drunk-zoo-36: alcohol + lit joint + swinging  ·  back to Wallco Ai  ·  design page: Texture tab — 5,034 DW textures, sort + density 705ca06 →