← back to Dw Marketing Reels
shop-by-color wheel: -50% wheel+dots, mobile+touch, >=80 SKUs (min:80), add-sample-to-cart per card
f7b39879dfe7094a3d7d08d281f0d9abb5345cdb · 2026-07-16 11:40:44 -0700 · Steve
Files touched
M colorwheel/colors-page.shopify.htmlM colorwheel/shop-by-color.page-body.html
Diff
commit f7b39879dfe7094a3d7d08d281f0d9abb5345cdb
Author: Steve <steve@designerwallcoverings.com>
Date: Thu Jul 16 11:40:44 2026 -0700
shop-by-color wheel: -50% wheel+dots, mobile+touch, >=80 SKUs (min:80), add-sample-to-cart per card
---
colorwheel/colors-page.shopify.html | 78 ++++++++++++++++++++++++++-------
colorwheel/shop-by-color.page-body.html | 78 ++++++++++++++++++++++++++-------
2 files changed, 126 insertions(+), 30 deletions(-)
diff --git a/colorwheel/colors-page.shopify.html b/colorwheel/colors-page.shopify.html
index a6990aa..10bce02 100644
--- a/colorwheel/colors-page.shopify.html
+++ b/colorwheel/colors-page.shopify.html
@@ -10,49 +10,65 @@
#sbc .sbc-head p{margin:6px 0 0;color:#7a7266;font-size:13px;letter-spacing:.04em}
#sbc .sbc-stage{display:flex;gap:40px;align-items:center;justify-content:center;flex-wrap:wrap;padding:22px 16px 8px}
#sbc .sbc-wheelcol{display:flex;flex-direction:column;align-items:center;gap:16px}
-#sbc .sbc-wheelwrap{position:relative;width:340px;height:340px;flex:0 0 auto}
+#sbc .sbc-wheelwrap{position:relative;width:170px;height:170px;flex:0 0 auto}
#sbc .sbc-spin{position:absolute;inset:0;animation:sbcspin 40s linear infinite}
#sbc .sbc-wheelwrap.sbc-dragging .sbc-spin{animation-play-state:paused}
#sbc .sbc-wheel{width:100%;height:100%;border-radius:50%;cursor:crosshair;
box-shadow:0 10px 40px rgba(0,0,0,.18),inset 0 0 0 1px rgba(0,0,0,.06)}
@keyframes sbcspin{to{transform:rotate(360deg)}}
-#sbc .sbc-pick{position:absolute;width:34px;height:34px;border-radius:50%;border:3px solid #fff;
+#sbc .sbc-pick{position:absolute;width:17px;height:17px;border-radius:50%;border:2px solid #fff;
box-shadow:0 2px 10px rgba(0,0,0,.35),0 0 0 1px rgba(0,0,0,.25);transform:translate(-50%,-50%);
left:50%;top:14%;pointer-events:none}
-#sbc .sbc-hub{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:118px;height:118px;
+#sbc .sbc-hub{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:59px;height:59px;
border-radius:50%;background:#fff;box-shadow:0 6px 22px rgba(0,0,0,.16),inset 0 0 0 1px var(--line);
display:flex;align-items:center;justify-content:center}
-#sbc .sbc-sw{width:78px;height:78px;border-radius:50%;box-shadow:inset 0 0 0 1px rgba(0,0,0,.12);
+#sbc .sbc-sw{width:39px;height:39px;border-radius:50%;box-shadow:inset 0 0 0 1px rgba(0,0,0,.12);
transition:background .2s;background:#8aa}
#sbc .sbc-side{max-width:300px}
#sbc .sbc-side h3{font-weight:400;font-size:15px;letter-spacing:.06em;text-transform:uppercase;margin:0 0 8px}
#sbc .sbc-side p{color:#7a7266;font-size:13px;line-height:1.6;margin:0}
-#sbc .sbc-palette{display:flex;align-items:center;justify-content:center;gap:14px}
-#sbc .sbc-nav{border:1px solid var(--line);background:#fff;color:var(--ink);width:32px;height:32px;
- border-radius:50%;font-size:20px;line-height:1;cursor:pointer;display:flex;align-items:center;
+#sbc .sbc-palette{display:flex;align-items:center;justify-content:center;gap:7px}
+#sbc .sbc-nav{border:1px solid var(--line);background:#fff;color:var(--ink);width:16px;height:16px;
+ border-radius:50%;font-size:13px;line-height:1;cursor:pointer;display:flex;align-items:center;
justify-content:center;box-shadow:0 1px 4px rgba(0,0,0,.08);transition:transform .12s,box-shadow .12s}
#sbc .sbc-nav:hover{transform:translateY(-2px);box-shadow:0 5px 14px rgba(0,0,0,.16)}
#sbc .sbc-nav:disabled{opacity:.28;cursor:default;transform:none;box-shadow:none}
-#sbc .sbc-dots{display:flex;gap:14px}
-#sbc .sbc-pdot{width:34px;height:34px;border-radius:50%;cursor:pointer;
+#sbc .sbc-dots{display:flex;gap:7px}
+#sbc .sbc-pdot{width:17px;height:17px;border-radius:50%;cursor:pointer;
box-shadow:inset 0 0 0 1px rgba(0,0,0,.14),0 1px 4px rgba(0,0,0,.12);
transition:transform .14s,box-shadow .14s}
#sbc .sbc-pdot:hover{transform:translateY(-3px) scale(1.1)}
#sbc .sbc-pdot.sbc-on{box-shadow:0 0 0 3px var(--gold),inset 0 0 0 1px rgba(0,0,0,.14)}
#sbc .sbc-grid{margin:16px auto 20px;padding:0 6px;display:grid;
grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:18px}
-#sbc .sbc-card{position:relative;text-decoration:none;color:inherit;background:#fff;border:1px solid var(--line);
+#sbc .sbc-card{position:relative;display:flex;flex-direction:column;background:#fff;border:1px solid var(--line);
border-radius:12px;overflow:hidden;opacity:0;transform:translateY(14px) scale(.98);
animation:sbcpop .5s forwards;box-shadow:0 1px 0 rgba(0,0,0,.03)}
@keyframes sbcpop{to{opacity:1;transform:none}}
#sbc .sbc-card:hover{box-shadow:0 12px 30px rgba(0,0,0,.12)}
+#sbc .sbc-card-link{display:block;text-decoration:none;color:inherit}
#sbc .sbc-card .sbc-im{aspect-ratio:1/1;width:100%;object-fit:cover;display:block;background:#f2efe9}
#sbc .sbc-card .sbc-cap{padding:10px 12px;font-size:12.5px;line-height:1.35}
#sbc .sbc-card .sbc-cap i{display:block;color:#9a9276;font-style:normal;font-size:11px;margin-top:3px}
#sbc .sbc-card .sbc-cdot{position:absolute;top:8px;right:8px;width:14px;height:14px;border-radius:50%;
box-shadow:0 0 0 2px #fff,inset 0 0 0 1px rgba(0,0,0,.15)}
+/* add-sample button — pinned to the bottom of every card so the grid stays even */
+#sbc .sbc-add{margin-top:auto;border:0;border-top:1px solid var(--line);background:#faf8f4;color:var(--ink);
+ font:600 11.5px/1 -apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;letter-spacing:.04em;
+ text-transform:uppercase;padding:11px 8px;cursor:pointer;transition:background .15s,color .15s}
+#sbc .sbc-add:hover{background:var(--gold);color:#fff}
+#sbc .sbc-add.sbc-added{background:#2e7d32;color:#fff;cursor:default}
#sbc .sbc-empty{grid-column:1/-1;text-align:center;color:#9a9276;padding:40px;font-size:14px}
#sbc .sbc-loading{grid-column:1/-1;text-align:center;color:var(--gold);padding:40px;font-size:13px;letter-spacing:.1em}
+ /* touch: let the wheel be dragged without scrolling the page */
+ #sbc .sbc-wheelwrap,#sbc .sbc-wheel,#sbc .sbc-spin{touch-action:none}
+ /* mobile */
+ @media(max-width:600px){
+ #sbc .sbc-stage{gap:20px;padding:16px 12px}
+ #sbc .sbc-side{max-width:92%}
+ #sbc .sbc-head h2{font-size:19px}
+ #sbc .sbc-grid{grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:12px;padding:0 10px}
+ }
</style>
<div id="sbc">
@@ -167,10 +183,37 @@
nextB.onclick=function(){pStart=Math.min(Math.max(0,PALETTE.length-PAGE),pStart+PAGE);renderDots();};
renderDots();
+ // add the product's SAMPLE variant ($4.25) straight to the Shopify cart,
+ // resolved from the storefront product JSON on click (no variant id needed upfront)
+ function addSample(handle, btn){
+ if(btn.dataset.busy) return; btn.dataset.busy='1';
+ var orig=btn.textContent; btn.textContent='Adding…';
+ fetch('/products/'+encodeURIComponent(handle)+'.js')
+ .then(function(r){return r.json();})
+ .then(function(pj){
+ var vs=pj.variants||[];
+ var sv=vs.filter(function(v){return v.available!==false;}).find(function(v){
+ return /sample/i.test(v.title||'')||/(^|[-\s])sample$/i.test(v.sku||'');})
+ || vs.find(function(v){return /sample/i.test(v.title||'')||/(^|[-\s])sample$/i.test(v.sku||'');})
+ || vs.find(function(v){return v.price===425;});
+ if(!sv){btn.textContent='View product';btn.onclick=function(){window.open('/products/'+encodeURIComponent(handle),'_blank');};delete btn.dataset.busy;return;}
+ return fetch('/cart/add.js',{method:'POST',headers:{'Content-Type':'application/json'},
+ body:JSON.stringify({items:[{id:sv.id,quantity:1}]})})
+ .then(function(r){if(!r.ok)throw new Error('add');return r.json();})
+ .then(function(){
+ btn.textContent='Added ✓'; btn.classList.add('sbc-added');
+ // nudge common theme cart-drawer listeners to refresh the count
+ document.dispatchEvent(new CustomEvent('cart:refresh'));
+ document.dispatchEvent(new CustomEvent('ajaxProduct:added'));
+ if(window.jQuery){try{window.jQuery(document).trigger('ajaxCart:afterCartLoad');}catch(e){}}
+ });
+ })
+ .catch(function(){btn.textContent='Try again';setTimeout(function(){btn.textContent=orig;delete btn.dataset.busy;},2000);});
+ }
function load(hex){
grid.innerHTML='<div class="sbc-loading">Finding wallcoverings in this color</div>';
fetch(API,{method:'POST',headers:{'Content-Type':'application/json'},
- body:JSON.stringify({hex:hex,ceiling:15,k:300})})
+ body:JSON.stringify({hex:hex,ceiling:15,min:80,k:300})}) // always surface at least 80 SKUs
.then(function(r){return r.json();})
.then(function(j){
var res=(j.results||[]);
@@ -178,16 +221,21 @@
grid.innerHTML='';
res.forEach(function(p,i){
if(!p.handle||!p.image)return;
- var a=document.createElement('a');a.className='sbc-card';
+ var card=document.createElement('div');card.className='sbc-card';
+ card.style.animationDelay=Math.min(i*8,700)+'ms';
+ var a=document.createElement('a');a.className='sbc-card-link';
a.href='/products/'+encodeURIComponent(p.handle);a.target='_blank';a.rel='noopener';
- a.style.animationDelay=Math.min(i*12,700)+'ms';
var im=document.createElement('img');im.className='sbc-im';im.loading='lazy';im.src=p.image;
- im.onerror=function(){a.remove();};
+ im.onerror=function(){card.remove();};
var dot=document.createElement('span');dot.className='sbc-cdot';dot.style.background=p.hex||hex;
var cap=document.createElement('div');cap.className='sbc-cap';
cap.textContent=(p.title||'').replace(/\s*\|\s*.*$/,'');
if(p.vendor){var v=document.createElement('i');v.textContent=p.vendor;cap.appendChild(v);}
- a.appendChild(im);a.appendChild(dot);a.appendChild(cap);grid.appendChild(a);
+ a.appendChild(im);a.appendChild(dot);a.appendChild(cap);
+ var add=document.createElement('button');add.className='sbc-add';add.type='button';
+ add.textContent='Add sample · $4.25';
+ add.onclick=function(){addSample(p.handle,add);};
+ card.appendChild(a);card.appendChild(add);grid.appendChild(card);
});
})
.catch(function(e){grid.innerHTML='<div class="sbc-empty">Could not load right now. '+e.message+'</div>';});
diff --git a/colorwheel/shop-by-color.page-body.html b/colorwheel/shop-by-color.page-body.html
index 980ef4f..5b62793 100644
--- a/colorwheel/shop-by-color.page-body.html
+++ b/colorwheel/shop-by-color.page-body.html
@@ -20,49 +20,65 @@
#sbc .sbc-head p{margin:6px 0 0;color:#7a7266;font-size:13px;letter-spacing:.04em}
#sbc .sbc-stage{display:flex;gap:40px;align-items:center;justify-content:center;flex-wrap:wrap;padding:22px 16px 8px}
#sbc .sbc-wheelcol{display:flex;flex-direction:column;align-items:center;gap:16px}
-#sbc .sbc-wheelwrap{position:relative;width:340px;height:340px;flex:0 0 auto}
+#sbc .sbc-wheelwrap{position:relative;width:170px;height:170px;flex:0 0 auto}
#sbc .sbc-spin{position:absolute;inset:0;animation:sbcspin 40s linear infinite}
#sbc .sbc-wheelwrap.sbc-dragging .sbc-spin{animation-play-state:paused}
#sbc .sbc-wheel{width:100%;height:100%;border-radius:50%;cursor:crosshair;
box-shadow:0 10px 40px rgba(0,0,0,.18),inset 0 0 0 1px rgba(0,0,0,.06)}
@keyframes sbcspin{to{transform:rotate(360deg)}}
-#sbc .sbc-pick{position:absolute;width:34px;height:34px;border-radius:50%;border:3px solid #fff;
+#sbc .sbc-pick{position:absolute;width:17px;height:17px;border-radius:50%;border:2px solid #fff;
box-shadow:0 2px 10px rgba(0,0,0,.35),0 0 0 1px rgba(0,0,0,.25);transform:translate(-50%,-50%);
left:50%;top:14%;pointer-events:none}
-#sbc .sbc-hub{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:118px;height:118px;
+#sbc .sbc-hub{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:59px;height:59px;
border-radius:50%;background:#fff;box-shadow:0 6px 22px rgba(0,0,0,.16),inset 0 0 0 1px var(--line);
display:flex;align-items:center;justify-content:center}
-#sbc .sbc-sw{width:78px;height:78px;border-radius:50%;box-shadow:inset 0 0 0 1px rgba(0,0,0,.12);
+#sbc .sbc-sw{width:39px;height:39px;border-radius:50%;box-shadow:inset 0 0 0 1px rgba(0,0,0,.12);
transition:background .2s;background:#8aa}
#sbc .sbc-side{max-width:300px}
#sbc .sbc-side h3{font-weight:400;font-size:15px;letter-spacing:.06em;text-transform:uppercase;margin:0 0 8px}
#sbc .sbc-side p{color:#7a7266;font-size:13px;line-height:1.6;margin:0}
-#sbc .sbc-palette{display:flex;align-items:center;justify-content:center;gap:14px}
-#sbc .sbc-nav{border:1px solid var(--line);background:#fff;color:var(--ink);width:32px;height:32px;
- border-radius:50%;font-size:20px;line-height:1;cursor:pointer;display:flex;align-items:center;
+#sbc .sbc-palette{display:flex;align-items:center;justify-content:center;gap:7px}
+#sbc .sbc-nav{border:1px solid var(--line);background:#fff;color:var(--ink);width:16px;height:16px;
+ border-radius:50%;font-size:13px;line-height:1;cursor:pointer;display:flex;align-items:center;
justify-content:center;box-shadow:0 1px 4px rgba(0,0,0,.08);transition:transform .12s,box-shadow .12s}
#sbc .sbc-nav:hover{transform:translateY(-2px);box-shadow:0 5px 14px rgba(0,0,0,.16)}
#sbc .sbc-nav:disabled{opacity:.28;cursor:default;transform:none;box-shadow:none}
-#sbc .sbc-dots{display:flex;gap:14px}
-#sbc .sbc-pdot{width:34px;height:34px;border-radius:50%;cursor:pointer;
+#sbc .sbc-dots{display:flex;gap:7px}
+#sbc .sbc-pdot{width:17px;height:17px;border-radius:50%;cursor:pointer;
box-shadow:inset 0 0 0 1px rgba(0,0,0,.14),0 1px 4px rgba(0,0,0,.12);
transition:transform .14s,box-shadow .14s}
#sbc .sbc-pdot:hover{transform:translateY(-3px) scale(1.1)}
#sbc .sbc-pdot.sbc-on{box-shadow:0 0 0 3px var(--gold),inset 0 0 0 1px rgba(0,0,0,.14)}
#sbc .sbc-grid{margin:16px auto 20px;padding:0 6px;display:grid;
grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:18px}
-#sbc .sbc-card{position:relative;text-decoration:none;color:inherit;background:#fff;border:1px solid var(--line);
+#sbc .sbc-card{position:relative;display:flex;flex-direction:column;background:#fff;border:1px solid var(--line);
border-radius:12px;overflow:hidden;opacity:0;transform:translateY(14px) scale(.98);
animation:sbcpop .5s forwards;box-shadow:0 1px 0 rgba(0,0,0,.03)}
@keyframes sbcpop{to{opacity:1;transform:none}}
#sbc .sbc-card:hover{box-shadow:0 12px 30px rgba(0,0,0,.12)}
+#sbc .sbc-card-link{display:block;text-decoration:none;color:inherit}
#sbc .sbc-card .sbc-im{aspect-ratio:1/1;width:100%;object-fit:cover;display:block;background:#f2efe9}
#sbc .sbc-card .sbc-cap{padding:10px 12px;font-size:12.5px;line-height:1.35}
#sbc .sbc-card .sbc-cap i{display:block;color:#9a9276;font-style:normal;font-size:11px;margin-top:3px}
#sbc .sbc-card .sbc-cdot{position:absolute;top:8px;right:8px;width:14px;height:14px;border-radius:50%;
box-shadow:0 0 0 2px #fff,inset 0 0 0 1px rgba(0,0,0,.15)}
+/* add-sample button — pinned to the bottom of every card so the grid stays even */
+#sbc .sbc-add{margin-top:auto;border:0;border-top:1px solid var(--line);background:#faf8f4;color:var(--ink);
+ font:600 11.5px/1 -apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;letter-spacing:.04em;
+ text-transform:uppercase;padding:11px 8px;cursor:pointer;transition:background .15s,color .15s}
+#sbc .sbc-add:hover{background:var(--gold);color:#fff}
+#sbc .sbc-add.sbc-added{background:#2e7d32;color:#fff;cursor:default}
#sbc .sbc-empty{grid-column:1/-1;text-align:center;color:#9a9276;padding:40px;font-size:14px}
#sbc .sbc-loading{grid-column:1/-1;text-align:center;color:var(--gold);padding:40px;font-size:13px;letter-spacing:.1em}
+ /* touch: let the wheel be dragged without scrolling the page */
+ #sbc .sbc-wheelwrap,#sbc .sbc-wheel,#sbc .sbc-spin{touch-action:none}
+ /* mobile */
+ @media(max-width:600px){
+ #sbc .sbc-stage{gap:20px;padding:16px 12px}
+ #sbc .sbc-side{max-width:92%}
+ #sbc .sbc-head h2{font-size:19px}
+ #sbc .sbc-grid{grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:12px;padding:0 10px}
+ }
</style>
<div id="sbc">
@@ -177,10 +193,37 @@
nextB.onclick=function(){pStart=Math.min(Math.max(0,PALETTE.length-PAGE),pStart+PAGE);renderDots();};
renderDots();
+ // add the product's SAMPLE variant ($4.25) straight to the Shopify cart,
+ // resolved from the storefront product JSON on click (no variant id needed upfront)
+ function addSample(handle, btn){
+ if(btn.dataset.busy) return; btn.dataset.busy='1';
+ var orig=btn.textContent; btn.textContent='Adding…';
+ fetch('/products/'+encodeURIComponent(handle)+'.js')
+ .then(function(r){return r.json();})
+ .then(function(pj){
+ var vs=pj.variants||[];
+ var sv=vs.filter(function(v){return v.available!==false;}).find(function(v){
+ return /sample/i.test(v.title||'')||/(^|[-\s])sample$/i.test(v.sku||'');})
+ || vs.find(function(v){return /sample/i.test(v.title||'')||/(^|[-\s])sample$/i.test(v.sku||'');})
+ || vs.find(function(v){return v.price===425;});
+ if(!sv){btn.textContent='View product';btn.onclick=function(){window.open('/products/'+encodeURIComponent(handle),'_blank');};delete btn.dataset.busy;return;}
+ return fetch('/cart/add.js',{method:'POST',headers:{'Content-Type':'application/json'},
+ body:JSON.stringify({items:[{id:sv.id,quantity:1}]})})
+ .then(function(r){if(!r.ok)throw new Error('add');return r.json();})
+ .then(function(){
+ btn.textContent='Added ✓'; btn.classList.add('sbc-added');
+ // nudge common theme cart-drawer listeners to refresh the count
+ document.dispatchEvent(new CustomEvent('cart:refresh'));
+ document.dispatchEvent(new CustomEvent('ajaxProduct:added'));
+ if(window.jQuery){try{window.jQuery(document).trigger('ajaxCart:afterCartLoad');}catch(e){}}
+ });
+ })
+ .catch(function(){btn.textContent='Try again';setTimeout(function(){btn.textContent=orig;delete btn.dataset.busy;},2000);});
+ }
function load(hex){
grid.innerHTML='<div class="sbc-loading">Finding wallcoverings in this color</div>';
fetch(API,{method:'POST',headers:{'Content-Type':'application/json'},
- body:JSON.stringify({hex:hex,ceiling:15,k:300})})
+ body:JSON.stringify({hex:hex,ceiling:15,min:80,k:300})}) // always surface at least 80 SKUs
.then(function(r){return r.json();})
.then(function(j){
var res=(j.results||[]);
@@ -188,16 +231,21 @@
grid.innerHTML='';
res.forEach(function(p,i){
if(!p.handle||!p.image)return;
- var a=document.createElement('a');a.className='sbc-card';
+ var card=document.createElement('div');card.className='sbc-card';
+ card.style.animationDelay=Math.min(i*8,700)+'ms';
+ var a=document.createElement('a');a.className='sbc-card-link';
a.href='/products/'+encodeURIComponent(p.handle);a.target='_blank';a.rel='noopener';
- a.style.animationDelay=Math.min(i*12,700)+'ms';
var im=document.createElement('img');im.className='sbc-im';im.loading='lazy';im.src=p.image;
- im.onerror=function(){a.remove();};
+ im.onerror=function(){card.remove();};
var dot=document.createElement('span');dot.className='sbc-cdot';dot.style.background=p.hex||hex;
var cap=document.createElement('div');cap.className='sbc-cap';
cap.textContent=(p.title||'').replace(/\s*\|\s*.*$/,'');
if(p.vendor){var v=document.createElement('i');v.textContent=p.vendor;cap.appendChild(v);}
- a.appendChild(im);a.appendChild(dot);a.appendChild(cap);grid.appendChild(a);
+ a.appendChild(im);a.appendChild(dot);a.appendChild(cap);
+ var add=document.createElement('button');add.className='sbc-add';add.type='button';
+ add.textContent='Add sample · $4.25';
+ add.onclick=function(){addSample(p.handle,add);};
+ card.appendChild(a);card.appendChild(add);grid.appendChild(card);
});
})
.catch(function(e){grid.innerHTML='<div class="sbc-empty">Could not load right now. '+e.message+'</div>';});
← 907a60d colorwheel: canonical /pages/shop-by-color body (new wheel,
·
back to Dw Marketing Reels
·
console: Video Studio — buttons to queue IG reel / URL→reel 1d2a1cb →