← back to Designer Wallcoverings
auto-save: 2026-07-07T08:59:35 (6 files) — pending-approval/boost-filter-consolidation-2026-06-25 shopify/theme-LIVE-591/snippets/product-gallery.liquid vendor-scrapers/china-seas-refresh scripts/wallquest-refresh/carl-robinson-viewer/rooms-local/GRS-100020-kontext.png scripts/wallquest-refresh/carl-robinson-viewer/rooms-local/NET-100042-sdxl.png
7ffe7cc17925a76af76eab9ea437cfdeff0d4aa1 · 2026-07-07 08:59:40 -0700 · Steve Abrams
Files touched
A scripts/wallquest-refresh/carl-robinson-viewer/rooms-local/GRS-100020-kontext.pngA scripts/wallquest-refresh/carl-robinson-viewer/rooms-local/NET-100042-sdxl.pngA shopify/theme-LIVE-591/snippets/color-palette.liquidM shopify/theme-LIVE-591/snippets/product-gallery.liquid
Diff
commit 7ffe7cc17925a76af76eab9ea437cfdeff0d4aa1
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue Jul 7 08:59:40 2026 -0700
auto-save: 2026-07-07T08:59:35 (6 files) — pending-approval/boost-filter-consolidation-2026-06-25 shopify/theme-LIVE-591/snippets/product-gallery.liquid vendor-scrapers/china-seas-refresh scripts/wallquest-refresh/carl-robinson-viewer/rooms-local/GRS-100020-kontext.png scripts/wallquest-refresh/carl-robinson-viewer/rooms-local/NET-100042-sdxl.png
---
.../rooms-local/GRS-100020-kontext.png | Bin 0 -> 1415428 bytes
.../rooms-local/NET-100042-sdxl.png | Bin 0 -> 1426151 bytes
.../theme-LIVE-591/snippets/color-palette.liquid | 192 +++++++++++++++++++++
.../theme-LIVE-591/snippets/product-gallery.liquid | 3 +-
4 files changed, 194 insertions(+), 1 deletion(-)
diff --git a/scripts/wallquest-refresh/carl-robinson-viewer/rooms-local/GRS-100020-kontext.png b/scripts/wallquest-refresh/carl-robinson-viewer/rooms-local/GRS-100020-kontext.png
new file mode 100644
index 00000000..632ade49
Binary files /dev/null and b/scripts/wallquest-refresh/carl-robinson-viewer/rooms-local/GRS-100020-kontext.png differ
diff --git a/scripts/wallquest-refresh/carl-robinson-viewer/rooms-local/NET-100042-sdxl.png b/scripts/wallquest-refresh/carl-robinson-viewer/rooms-local/NET-100042-sdxl.png
new file mode 100644
index 00000000..25156178
Binary files /dev/null and b/scripts/wallquest-refresh/carl-robinson-viewer/rooms-local/NET-100042-sdxl.png differ
diff --git a/shopify/theme-LIVE-591/snippets/color-palette.liquid b/shopify/theme-LIVE-591/snippets/color-palette.liquid
new file mode 100644
index 00000000..b7eff06a
--- /dev/null
+++ b/shopify/theme-LIVE-591/snippets/color-palette.liquid
@@ -0,0 +1,192 @@
+{% comment %}
+ color-palette — "Colors In This Pattern" big-swatch-card breakdown.
+ Shows ALL colors in the pattern with a % coverage under each card.
+
+ Data tiers (mirrors color-dots.liquid, kept in sync):
+ Tier 1 custom.color_dots_json / custom.color_details (Gemini-enriched JSON: [{hex,name,pct}])
+ Tier 2 custom.primary_color_hex + dwc.ai_generated_colors (name list → hex map)
+ Tier 3 custom.color_hex (single)
+ Tier 4 Canvas pixel extraction from the product image (always yields real % — reliable fallback)
+
+ Replaces the small "color-dots" strip. Percentages come from the metafield
+ `pct`/`percentage` field when present, else are computed live from the image.
+{% endcomment %}
+
+{% assign color_dots_json_val = product.metafields.custom.color_dots_json.value %}
+{% assign color_details_val = product.metafields.custom.color_details.value %}
+{% if color_dots_json_val != blank %}
+ {% assign color_details_raw = color_dots_json_val | json %}
+{% elsif color_details_val != blank %}
+ {% assign color_details_raw = color_details_val | json %}
+{% else %}
+ {% assign color_details_raw = blank %}
+{% endif %}
+{% assign color_hex = product.metafields.custom.color_hex.value %}
+{% assign primary_hex = product.metafields.custom.primary_color_hex.value %}
+{% assign ai_colors_raw = product.metafields.dwc.ai_generated_colors.value | json %}
+{% assign color_name = product.metafields.custom.color_name.value %}
+
+<div class="dw-color-palette" data-dw-color-palette
+ {% if color_details_raw != blank and color_details_raw != 'null' %}data-colors='{{ color_details_raw | json }}'{% endif %}
+ {% if primary_hex != blank %}data-primary-hex="{{ primary_hex }}"{% endif %}
+ {% if ai_colors_raw != blank and ai_colors_raw != 'null' %}data-ai-colors='{{ ai_colors_raw }}'{% endif %}
+ {% if color_name != blank %}data-color-name="{{ color_name }}"{% endif %}
+ {% if color_hex != blank %}data-color-hex="{{ color_hex }}"{% endif %}
+ {% if product.featured_image %}data-product-image="{{ product.featured_image | img_url: '400x400' }}"{% endif %}
+>
+ <p class="dw-color-palette__title">Colors In This Pattern</p>
+ <div class="dw-color-palette__cards" data-dw-color-palette-cards aria-live="polite"></div>
+</div>
+
+<style>
+ .dw-color-palette{padding:16px 0 10px;text-align:center;min-height:10px;}
+ .dw-color-palette__title{font-family:Lora,serif;font-size:15px;font-weight:500;color:#3D4246;margin:0 0 12px;letter-spacing:-0.01em;}
+ .dw-color-palette__cards{display:flex;gap:14px;justify-content:center;flex-wrap:wrap;max-width:640px;margin:0 auto;}
+ .dw-color-palette__card{display:flex;flex-direction:column;align-items:center;gap:6px;text-decoration:none;width:88px;}
+ .dw-color-palette__swatch{width:84px;height:84px;border-radius:10px;border:2px solid #e5e2dc;box-shadow:0 1px 4px rgba(0,0,0,.06);transition:transform .15s ease,border-color .15s ease,box-shadow .15s ease;position:relative;overflow:hidden;}
+ .dw-color-palette__card:hover .dw-color-palette__swatch{transform:translateY(-2px);border-color:#3D4246;box-shadow:0 4px 12px rgba(0,0,0,.14);}
+ .dw-color-palette__name{font-family:Lora,serif;font-size:12px;color:#3D4246;line-height:1.2;max-width:88px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-transform:capitalize;}
+ .dw-color-palette__pct{font-size:12px;font-weight:600;color:#8a8577;letter-spacing:.02em;}
+ .dw-color-palette__bar{display:flex;height:6px;border-radius:4px;overflow:hidden;max-width:640px;margin:14px auto 0;box-shadow:inset 0 0 0 1px rgba(0,0,0,.04);}
+ .dw-color-palette__bar span{display:block;height:100%;}
+ .dw-color-palette:empty{display:none;}
+ @media (max-width:600px){
+ .dw-color-palette__cards{gap:10px;}
+ .dw-color-palette__card{width:70px;}
+ .dw-color-palette__swatch{width:66px;height:66px;}
+ }
+</style>
+
+<script>
+(function(){
+ function init(){
+ var root = document.querySelector('[data-dw-color-palette]');
+ if(!root || root.dataset.rendered) return;
+ var cards = root.querySelector('[data-dw-color-palette-cards]');
+ if(!cards) return;
+ root.dataset.rendered = '1';
+
+ /* name -> hex fallback map (kept in sync with color-dots.liquid) */
+ var N = {
+ 'red':'#DC2626','crimson':'#DC143C','burgundy':'#800020','wine':'#722F37','maroon':'#800000',
+ 'blue':'#2563EB','navy':'#1B2A4A','cobalt':'#0047AB','indigo':'#3F51B5','sky blue':'#87CEEB','steel blue':'#4682B4','royal blue':'#4169E1','blue frost':'#BcorD','deep indigo':'#1B2A4A','dark navy':'#1B2A4A','midnight':'#191970',
+ 'green':'#16A34A','sage':'#87AE73','olive':'#808000','forest green':'#228B22','emerald':'#50C878','mint':'#98FF98','moss':'#8A9A5B','sea glass':'#C6D8CE',
+ 'gold':'#D4AF37','golden':'#FFD700','amber':'#FFBF00',
+ 'yellow':'#EAB308','mustard':'#FFDB58',
+ 'orange':'#EA580C','rust':'#B7410E','terracotta':'#E2725B','melon':'#FDBCB4','soft melon':'#F6C9A8',
+ 'pink':'#EC4899','blush':'#DE5D83','rose':'#FF007F','salmon':'#FA8072','fuchsia':'#FF00FF',
+ 'purple':'#9333EA','violet':'#7C3AED','plum':'#8E4585','lavender':'#E6E6FA','lilac':'#C8A2C8','mauve':'#E0B0FF',
+ 'black':'#1A1A1A','charcoal':'#36454F','ebony':'#555D50','onyx':'#353839',
+ 'white':'#FAFAFA','ivory':'#FFFFF0','cream':'#FFFDD0','pearl':'#F0EAD6','off-white':'#FAF9F6','eggshell':'#F0EAD6',
+ 'gray':'#6B7280','grey':'#6B7280','silver':'#C0C0C0','slate':'#708090','metallic silver':'#BFC1C2',
+ 'brown':'#92400E','chocolate':'#7B3F00','espresso':'#3C1414','walnut':'#5C3A1D','mocha':'#967969','sienna':'#A0522D',
+ 'beige':'#F5F5DC','tan':'#D2B48C','taupe':'#483C32','sand':'#C2B280','khaki':'#F0E68C','camel':'#C19A6B','oatmeal':'#B8AB8C','linen':'#FAF0E6',
+ 'coral':'#FF6F61','peach':'#FFCBA4',
+ 'teal':'#0D9488','aqua':'#00FFFF','turquoise':'#40E0D0','cyan':'#06B6D4',
+ 'metallic':'#AAA9AD','copper':'#B87333','bronze':'#CD7F32'
+ };
+ /* fix bad placeholder above */
+ N['blue frost']='#C4D3E0';
+
+ function esc(s){return (s||'').toString().replace(/[<>&"]/g,function(c){return {'<':'<','>':'>','&':'&','"':'"'}[c];});}
+ function pctOf(c){ var p = (c.pct!=null?c.pct:(c.percentage!=null?c.percentage:null)); if(p==null) return null; p=parseFloat(p); return isNaN(p)?null:Math.round(p); }
+
+ /* Build a card. Receives the WHOLE color object (fixes the color-dots `c` bug). */
+ function makeCard(c){
+ var hex = c.hex || N[(c.name||'').toLowerCase()] || '#ccc';
+ var name = c.name || '';
+ var pct = pctOf(c);
+ var card = document.createElement('div');
+ card.className = 'dw-color-palette__card';
+ card.title = name + (pct!=null? ' — '+pct+'%':'') + ' ('+hex+')';
+ var sw = document.createElement('div');
+ sw.className = 'dw-color-palette__swatch';
+ sw.style.background = hex;
+ card.appendChild(sw);
+ if(name){ var nm=document.createElement('span'); nm.className='dw-color-palette__name'; nm.textContent=name; card.appendChild(nm); }
+ if(pct!=null){ var pc=document.createElement('span'); pc.className='dw-color-palette__pct'; pc.textContent=pct+'%'; card.appendChild(pc); }
+ return card;
+ }
+
+ function render(colors){
+ if(!colors || !colors.length) return false;
+ /* de-dupe by hex, sort by pct desc when available */
+ var seen={}, list=[];
+ colors.forEach(function(c){
+ if(!c) return;
+ var key=(c.hex|| c.name ||'').toString().toLowerCase();
+ if(!key || seen[key]) return; seen[key]=1; list.push(c);
+ });
+ if(!list.length) return false;
+ var hasPct = list.some(function(c){return pctOf(c)!=null;});
+ if(hasPct) list.sort(function(a,b){return (pctOf(b)||0)-(pctOf(a)||0);});
+ list = list.slice(0,8);
+ list.forEach(function(c){ cards.appendChild(makeCard(c)); });
+ /* proportion bar when we have percentages */
+ if(hasPct){
+ var bar=document.createElement('div'); bar.className='dw-color-palette__bar';
+ var tot=list.reduce(function(s,c){return s+(pctOf(c)||0);},0)||1;
+ list.forEach(function(c){ var s=document.createElement('span'); s.style.background=c.hex||N[(c.name||'').toLowerCase()]||'#ccc'; s.style.flex=(pctOf(c)||0)/tot; bar.appendChild(s); });
+ root.appendChild(bar);
+ }
+ return true;
+ }
+
+ /* ── Tier 1: color_details / color_dots_json metafield ── */
+ var raw = root.dataset.colors;
+ if(raw){
+ try { if(render(JSON.parse(raw.replace(/=>/g,':')))) return; } catch(e){}
+ }
+
+ /* ── Tier 2: primary_color_hex + ai_generated_colors ── */
+ var ph = root.dataset.primaryHex, aiRaw = root.dataset.aiColors;
+ if(ph || aiRaw){
+ var list2=[];
+ if(ph) list2.push({hex:ph, name:root.dataset.colorName||'Primary'});
+ try { JSON.parse((aiRaw||'[]').replace(/=>/g,':')).forEach(function(nm){ var h=N[(''+nm).toLowerCase()]; if(h) list2.push({hex:h,name:nm}); }); } catch(e){}
+ if(render(list2)) return;
+ }
+
+ /* ── Tier 2.5: single color_hex ── */
+ var sh = root.dataset.colorHex;
+ if(sh){ if(render([{hex:sh, name:root.dataset.colorName||'Color'}])) return; }
+
+ /* ── Tier 3: Canvas extraction from the product image (always yields %) ── */
+ var REF={'red':[220,38,38],'navy':[27,42,74],'blue':[37,99,235],'green':[22,163,74],'sage':[135,174,115],'gold':[212,175,55],'yellow':[234,179,8],'orange':[234,88,12],'pink':[236,72,153],'purple':[147,51,234],'black':[26,26,26],'charcoal':[54,69,79],'white':[250,250,250],'ivory':[255,255,240],'cream':[255,253,208],'gray':[107,114,128],'silver':[192,192,192],'brown':[146,64,14],'beige':[245,245,220],'tan':[210,180,140],'taupe':[72,60,50],'teal':[13,148,136],'coral':[255,111,97],'olive':[128,128,0],'sand':[194,178,128],'mint':[152,255,152],'turquoise':[64,224,208]};
+ function closestName(r,g,b){var best='',bd=1e9;for(var n in REF){var c=REF[n],d=Math.pow(r-c[0],2)+Math.pow(g-c[1],2)+Math.pow(b-c[2],2);if(d<bd){bd=d;best=n;}}return best;}
+ function hx(r,g,b){return '#'+[r,g,b].map(function(x){return x.toString(16).padStart(2,'0');}).join('');}
+ function fromCanvas(url){
+ var img=new Image(); img.crossOrigin='anonymous';
+ img.onload=function(){
+ try{
+ var sz=60,cv=document.createElement('canvas');cv.width=sz;cv.height=sz;
+ var ctx=cv.getContext('2d');ctx.drawImage(img,0,0,sz,sz);
+ var px=ctx.getImageData(0,0,sz,sz).data,bk={};
+ for(var i=0;i<px.length;i+=4){var kr=Math.round(px[i]/32)*32,kg=Math.round(px[i+1]/32)*32,kb=Math.round(px[i+2]/32)*32,k=kr+','+kg+','+kb;if(!bk[k])bk[k]={r:0,g:0,b:0,n:0};bk[k].r+=px[i];bk[k].g+=px[i+1];bk[k].b+=px[i+2];bk[k].n++;}
+ var sorted=Object.keys(bk).map(function(k){return bk[k];}).sort(function(a,b){return b.n-a.n;});
+ var tot=sz*sz,out=[],seen={};
+ for(var j=0;j<sorted.length && out.length<6;j++){var s=sorted[j],ar=Math.round(s.r/s.n),ag=Math.round(s.g/s.n),ab=Math.round(s.b/s.n),nm=closestName(ar,ag,ab);if(seen[nm])continue;seen[nm]=1;out.push({name:nm,hex:hx(ar,ag,ab),pct:Math.round(s.n/tot*100)});}
+ render(out);
+ }catch(e){}
+ };
+ img.onerror=function(){};
+ img.src=url;
+ }
+ function imgUrl(){
+ var u=root.dataset.productImage;
+ if(u&&u.length>5) return u.indexOf('//')===0?'https:'+u:u;
+ var sels=['.product-gallery--viewport img[src]','.product-gallery img[src]','[data-product-gallery] img[src]','.media-gallery__slide img[src]'];
+ for(var i=0;i<sels.length;i++){var el=document.querySelector(sels[i]);if(el&&el.src)return el.src;}
+ return null;
+ }
+ var u=imgUrl();
+ if(u){ fromCanvas(u); }
+ else {
+ var obs=new MutationObserver(function(m,o){var v=imgUrl();if(v){o.disconnect();fromCanvas(v);}});
+ obs.observe(document.body,{childList:true,subtree:true});
+ setTimeout(function(){obs.disconnect();},5000);
+ }
+ }
+ if(document.readyState==='loading'){document.addEventListener('DOMContentLoaded',init);}else{init();}
+})();
+</script>
diff --git a/shopify/theme-LIVE-591/snippets/product-gallery.liquid b/shopify/theme-LIVE-591/snippets/product-gallery.liquid
index d73ffb12..988fdc82 100644
--- a/shopify/theme-LIVE-591/snippets/product-gallery.liquid
+++ b/shopify/theme-LIVE-591/snippets/product-gallery.liquid
@@ -135,8 +135,9 @@
</div>
+ {% comment %} Colors In This Pattern — big swatch cards w/ % (replaces color-dots). Sits between the product images and Other Colorways. {% endcomment %}
+ {% render 'color-palette' %}
{% render 'colorway-siblings' %}
- {% render 'color-dots' %}
{% if images_layout == 'slideshow' and product.media.size > 1 %}
<div class="product-gallery-navigation-outer-wrapper">
← 10cc4fda auto-save: 2026-07-07T08:56:34 (10 files) — DW-Programming/I
·
back to Designer Wallcoverings
·
Gated Shopify room push + judge label-normalize fix bb62c10f →