← back to Wallco Ai
/design page: show full palette as paint chips + paint stripe
b6b1b00b91fc2811e794a31dc467b0dcbb352408 · 2026-05-19 14:38:05 -0700 · SteveStudio2
- All 5 extracted palette colors render as paint-chip cards with hex
code + coverage percentage; click to copy hex to clipboard
- Paint stripe below — each color at its actual coverage proportion
(hover any segment to expand it)
- Inserted directly under the existing .detail-palette single-swatch
block on /design/:id; styled to match the existing PDP aesthetic
- Safe no-op when design.palette is missing (older catalog entries
without enriched palette field)
Files touched
Diff
commit b6b1b00b91fc2811e794a31dc467b0dcbb352408
Author: SteveStudio2 <steve@designerwallcoverings.com>
Date: Tue May 19 14:38:05 2026 -0700
/design page: show full palette as paint chips + paint stripe
- All 5 extracted palette colors render as paint-chip cards with hex
code + coverage percentage; click to copy hex to clipboard
- Paint stripe below — each color at its actual coverage proportion
(hover any segment to expand it)
- Inserted directly under the existing .detail-palette single-swatch
block on /design/:id; styled to match the existing PDP aesthetic
- Safe no-op when design.palette is missing (older catalog entries
without enriched palette field)
---
server.js | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/server.js b/server.js
index 48db31e..059e33b 100644
--- a/server.js
+++ b/server.js
@@ -7143,6 +7143,64 @@ ${htmlHeader('/designs')}
<span class="hex-label">${design.dominant_hex}</span>
</div>
+ <!-- Full palette — every extracted color as a paint chip + a "paint" stripe -->
+ ${(() => {
+ const pal = Array.isArray(design.palette) ? design.palette.filter(p => p && p.hex) : [];
+ if (pal.length === 0) return '';
+ const chips = pal.map(p => `
+ <div class="paint-chip" data-hex="${p.hex}" title="${p.pct != null ? p.pct + '% of the design' : p.hex} — click to copy">
+ <div class="paint-chip-color" style="background:${p.hex}"></div>
+ <div class="paint-chip-label">
+ <span class="paint-chip-hex">${p.hex.toUpperCase()}</span>
+ <span class="paint-chip-pct">${p.pct != null ? p.pct + '%' : ''}</span>
+ </div>
+ </div>`).join('');
+ // Paint stripe — proportional widths matching each color's pct in the design.
+ const totalPct = pal.reduce((s, p) => s + (p.pct || 0), 0) || pal.length;
+ const stripe = pal.map(p => {
+ const w = ((p.pct || (100 / pal.length)) / totalPct * 100).toFixed(2);
+ return `<div class="paint-stripe-cell" style="background:${p.hex};flex:0 0 ${w}%" title="${p.hex} · ${p.pct || ''}%"></div>`;
+ }).join('');
+ return `
+ <div class="full-palette">
+ <div class="palette-header">
+ <span class="palette-label">Palette · ${pal.length} colors · click a chip to copy hex</span>
+ </div>
+ <div class="paint-chips">${chips}</div>
+ <div class="paint-stripe" title="Paint stripe — colors at their actual coverage in the design">${stripe}</div>
+ <div class="paint-stripe-caption">Paint stripe — each color at its actual coverage in the design</div>
+ </div>
+ <style>
+ .full-palette { margin:14px 0 4px; }
+ .palette-header { margin-bottom:8px; }
+ .palette-label { font:11px var(--sans, system-ui); text-transform:uppercase; letter-spacing:.08em; color:#888; }
+ .paint-chips { display:grid; grid-template-columns:repeat(auto-fit, minmax(120px, 1fr)); gap:10px; }
+ .paint-chip { border:1px solid #e0d8c4; border-radius:6px; overflow:hidden; background:#fff; cursor:pointer; transition:transform .12s, border-color .12s; }
+ .paint-chip:hover { transform:translateY(-1px); border-color:#c9a14b; }
+ .paint-chip-color { aspect-ratio:1.6/1; border-bottom:1px solid rgba(0,0,0,.08); }
+ .paint-chip-label { padding:7px 10px; display:flex; justify-content:space-between; align-items:center; font:11px ui-monospace, monospace; }
+ .paint-chip-hex { color:#1a1816; font-weight:600; letter-spacing:.04em; }
+ .paint-chip-pct { color:#888; font-size:10.5px; }
+ .paint-stripe { display:flex; height:64px; margin-top:14px; border:1px solid #e0d8c4; border-radius:6px; overflow:hidden; }
+ .paint-stripe-cell { transition:flex-grow .15s; }
+ .paint-stripe-cell:hover { flex-grow:1.6; }
+ .paint-stripe-caption { text-align:center; font:11px var(--sans, system-ui); color:#888; margin-top:6px; }
+ </style>
+ <script>
+ document.querySelectorAll('.paint-chip').forEach(el => {
+ el.addEventListener('click', async () => {
+ const hex = el.dataset.hex;
+ try { await navigator.clipboard.writeText(hex); } catch(_) {}
+ const lab = el.querySelector('.paint-chip-hex');
+ if (!lab) return;
+ const orig = lab.textContent;
+ lab.textContent = '✓ copied';
+ setTimeout(() => { lab.textContent = orig; }, 1200);
+ });
+ });
+ </script>`;
+ })()}
+
<!-- Width + material selector -->
<div class="material-picker" style="margin:18px 0 20px;padding:16px 18px;border:1px solid var(--line);border-radius:8px;background:var(--card-bg)">
<div style="font:11px var(--sans);text-transform:uppercase;letter-spacing:.08em;color:var(--ink-faint);margin-bottom:10px">Width</div>
← 7761399 admin/inspiration/generate: actionable 503 when Ollama is un
·
back to Wallco Ai
·
admin/inspiration: two-step flow + Export decisions.json d12476d →