[object Object]

← back to Embroideredwallpaper

chip-click → product details modal; vendor redacted in card overlay

07ca4d2d1c3b042cc6143adff39c99f7d5e01ead · 2026-05-13 13:59:58 -0700 · Steve Abrams

Files touched

Diff

commit 07ca4d2d1c3b042cc6143adff39c99f7d5e01ead
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed May 13 13:59:58 2026 -0700

    chip-click → product details modal; vendor redacted in card overlay
---
 public/index.html | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 100 insertions(+), 2 deletions(-)

diff --git a/public/index.html b/public/index.html
index 5606710..b8a293f 100644
--- a/public/index.html
+++ b/public/index.html
@@ -431,12 +431,62 @@ function cardHTML(p) {
   return '<img loading="' + (eager ? 'eager' : 'lazy') + '"' + (eager ? ' fetchpriority="high"' : '') + ' src="' + escAttr(safeImg(p.image_url)) + '" alt="' + escAttr(p.title) + '">'
     + '<div class="overlay">'
     + '<div class="pat">' + escAttr(p.pattern_name || p.title) + '</div>'
-    + '<div class="ven">' + escAttr((p.vendor || '').replace(/-/g, ' ')) + '</div>'
+    + '<div class="ven">Designer Wallcoverings · ' + escAttr(p.sku || p.handle || '') + '</div>'
     + '<div class="actions">'
     + '<button class="sample-btn" onclick="event.stopPropagation();dwmOpen(\'Sample\',' + JSON.stringify({sku:p.sku||p.handle, title:p.title, image_url:safeImg(p.image_url)}).replace(/"/g,'&quot;') + ')">Sample</button>'
     + '</div></div>';
 }
 
+// Click-to-open-full-details — every card opens a rich detail modal showing
+// the full image, pattern name, SKU, retail price (when known), aesthetic
+// chips, and CTAs for sample + Big Red chat. The modal NEVER reveals vendor.
+function openDetails(p) {
+  const safeP = {
+    sku: p.sku || p.handle || '',
+    title: p.title || '',
+    pattern: p.pattern_name || p.title || '',
+    image_url: safeImg(p.image_url),
+    price: p.price != null ? Number(p.price) : null,
+    aesthetic: Array.isArray(p.aesthetics) ? p.aesthetics : (p.aesthetic ? [p.aesthetic] : []),
+    width: p.width || p.roll_width || '',
+    repeat: p.repeat || p.pattern_repeat || '',
+    description: (p.description || '').slice(0, 600),
+  };
+  const m = document.getElementById('dwmDetails');
+  if (!m) return; // safety
+  m.querySelector('[data-d-img]').src = safeP.image_url;
+  m.querySelector('[data-d-img]').alt = safeP.title;
+  m.querySelector('[data-d-pat]').textContent = safeP.pattern;
+  m.querySelector('[data-d-brand]').textContent = 'Designer Wallcoverings · ' + safeP.sku;
+  const priceEl = m.querySelector('[data-d-price]');
+  priceEl.textContent = safeP.price != null && !isNaN(safeP.price) ? ('$' + safeP.price.toFixed(2) + ' / roll') : 'Pricing on request';
+  const chipsEl = m.querySelector('[data-d-chips]');
+  chipsEl.innerHTML = '';
+  for (const a of safeP.aesthetic) {
+    if (!a) continue;
+    const c = document.createElement('span');
+    c.className = 'd-chip';
+    c.textContent = ((typeof LABELS !== 'undefined' && LABELS[a]) || a).replace(/-/g, ' ');
+    chipsEl.appendChild(c);
+  }
+  const specsEl = m.querySelector('[data-d-specs]');
+  specsEl.innerHTML = '';
+  if (safeP.width) specsEl.insertAdjacentHTML('beforeend', '<dt>Width</dt><dd>' + escAttr(safeP.width) + '</dd>');
+  if (safeP.repeat) specsEl.insertAdjacentHTML('beforeend', '<dt>Repeat</dt><dd>' + escAttr(safeP.repeat) + '</dd>');
+  if (safeP.description) specsEl.insertAdjacentHTML('beforeend', '<dt>Notes</dt><dd>' + escAttr(safeP.description) + '</dd>');
+  m.querySelector('[data-d-sample]').onclick = () => {
+    dwmClose('Details');
+    dwmOpen('Sample', { sku: safeP.sku, title: safeP.title, image_url: safeP.image_url });
+  };
+  m.querySelector('[data-d-bigred]').onclick = () => {
+    dwmClose('Details');
+    try { if (window.BigRed && typeof window.BigRed.open === 'function') window.BigRed.open(); } catch(_){}
+  };
+  dwmOpen('Details');
+  try { if (typeof gtag === 'function') gtag('event', 'product_details_open', { sku: safeP.sku, pattern: safeP.pattern }); } catch(_){}
+}
+
+
 async function loadFacets() {
   let f;
   try {
@@ -502,7 +552,7 @@ async function loadGridPage() {
   const grid = document.getElementById('grid');
   for (const p of data.items) {
     const a = document.createElement('a');
-    a.className = 'card'; a.href = '#'; a.onclick = (e) => { e.preventDefault(); dwmOpen('Sample',{sku:p.sku||p.handle, title:p.title, image_url:safeImg(p.image_url)}); };
+    a.className = 'card'; a.href = '#'; a.onclick = (e) => { e.preventDefault(); openDetails(p); };
     a.innerHTML = cardHTML(p);
     grid.appendChild(a);
   }
@@ -599,6 +649,54 @@ loadGridPage();
 @media (max-width:720px) { #ideas .rail-card { flex:0 0 160px } }
 </style>
 
+<!-- Product details modal — opens on any chip click. Vendor-redacted. -->
+<style id="dwm-details-style">
+  #dwmDetails .dwm-box { max-width: 880px; padding: 0; overflow: hidden; }
+  #dwmDetails .d-wrap { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: 0; }
+  #dwmDetails .d-img-wrap { aspect-ratio: 1/1; background: #1a1714; overflow: hidden; }
+  #dwmDetails .d-img-wrap img { width: 100%; height: 100%; object-fit: cover; display: block; }
+  #dwmDetails .d-meta { padding: 32px 32px 28px; display: flex; flex-direction: column; gap: 14px; max-height: 600px; overflow-y: auto; }
+  #dwmDetails .d-brand { font-size: 10px; letter-spacing: 0.22em; text-transform: uppercase; color: rgba(0,0,0,0.55); font-weight: 600; }
+  #dwmDetails .d-pat { font-size: 24px; line-height: 1.15; font-weight: 400; color: #1a1714; margin: 0; }
+  #dwmDetails .d-price { font-size: 18px; font-weight: 500; color: #1a1714; }
+  #dwmDetails .d-chips { display: flex; flex-wrap: wrap; gap: 6px; }
+  #dwmDetails .d-chip { font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; padding: 5px 10px; border: 1px solid rgba(0,0,0,0.18); border-radius: 999px; color: rgba(0,0,0,0.7); }
+  #dwmDetails .d-specs { display: grid; grid-template-columns: 90px 1fr; gap: 6px 14px; font-size: 13px; color: rgba(0,0,0,0.75); margin: 4px 0 8px; }
+  #dwmDetails .d-specs dt { font-weight: 600; color: rgba(0,0,0,0.55); }
+  #dwmDetails .d-specs dd { margin: 0; }
+  #dwmDetails .d-ctas { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 6px; }
+  #dwmDetails .d-cta { padding: 13px 14px; font-family: inherit; font-size: 11px; letter-spacing: 0.22em; text-transform: uppercase; font-weight: 700; border: 1px solid #1a1714; cursor: pointer; transition: all .15s; text-align: center; }
+  #dwmDetails .d-cta.primary { background: #1a1714; color: #faf6ef; }
+  #dwmDetails .d-cta.primary:hover { background: var(--accent, #c4574d); border-color: var(--accent, #c4574d); }
+  #dwmDetails .d-cta.ghost { background: transparent; color: #1a1714; }
+  #dwmDetails .d-cta.ghost:hover { background: #1a1714; color: #faf6ef; }
+  @media (max-width: 720px) {
+    #dwmDetails .dwm-box { max-width: 96vw; }
+    #dwmDetails .d-wrap { grid-template-columns: 1fr; }
+    #dwmDetails .d-img-wrap { aspect-ratio: 4/3; }
+    #dwmDetails .d-meta { max-height: none; padding: 22px 20px 24px; }
+  }
+</style>
+<div class="dwm" id="dwmDetails" onclick="if(event.target===this)dwmClose('Details')">
+  <div class="dwm-box">
+    <button class="dwm-close" onclick="dwmClose('Details')" aria-label="Close" style="position:absolute;top:12px;right:14px;z-index:2;background:rgba(255,255,255,.85);border-radius:50%;width:32px;height:32px;display:flex;align-items:center;justify-content:center;border:0;cursor:pointer;font-size:20px;line-height:1">×</button>
+    <div class="d-wrap">
+      <div class="d-img-wrap"><img data-d-img alt="" loading="lazy"></div>
+      <div class="d-meta">
+        <div class="d-brand" data-d-brand>Designer Wallcoverings</div>
+        <h3 class="d-pat" data-d-pat></h3>
+        <div class="d-price" data-d-price></div>
+        <div class="d-chips" data-d-chips></div>
+        <dl class="d-specs" data-d-specs></dl>
+        <div class="d-ctas">
+          <button class="d-cta primary" type="button" data-d-sample>Order Memo Sample</button>
+          <button class="d-cta ghost" type="button" data-d-bigred>Ask Big Red</button>
+        </div>
+      </div>
+    </div>
+  </div>
+</div>
+
 <!-- Contact options modal -->
 <div class="dwm" id="dwmContact" onclick="if(event.target===this)dwmClose('Contact')">
   <div class="dwm-box" style="max-width:440px">

← 6329495 add universal corner-nav.js (UR 4-icon: bag/account/search/m  ·  back to Embroideredwallpaper  ·  embed Big Red customer chat (lower-left, retail mode, vendor 3970c4e →