← back to Dw Yolo Loop
artmura-site/public/product.html
142 lines
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Designer Wallcoverings</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Lora:ital,wght@0,400;0,500;0,600;1,400;1,500&family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/styles.css">
</head>
<body>
<a class="corner ul wordmark" href="https://www.designerwallcoverings.com">Designer Wallcoverings</a>
<nav class="corner ur">
<a href="/">The Collection</a>
<a href="https://www.designerwallcoverings.com/collections/all" target="_blank" rel="noopener">All Wallcoverings</a>
<a href="https://www.designerwallcoverings.com/pages/trade" target="_blank" rel="noopener">Trade</a>
</nav>
<main class="pdp" id="pdp"><div class="crumbs">Loading…</div></main>
<a class="shopbar" href="https://www.designerwallcoverings.com" target="_blank" rel="noopener">Shop the collection at <b>Designer Wallcoverings</b> →</a>
<script>
const handle=location.pathname.split('/').pop();
const esc=s=>(s||'').replace(/[&<>"]/g,c=>({'&':'&','<':'<','>':'>','"':'"'}[c]));
function specRow(k,v){return v?`<div class="row"><span class="k">${k}</span><span class="v">${esc(v)}</span></div>`:'';}
(async()=>{
const [cfg,r]=await Promise.all([fetch('/api/config').then(x=>x.json()).catch(()=>({})), fetch('/api/product/'+handle)]);
const LINE = cfg.line || cfg.vendor || 'Designer Wallcoverings';
if(cfg.palette){const rs=document.documentElement.style;['bg','paper','ink','accent','gold','line','taupe'].forEach(k=>{if(cfg.palette[k])rs.setProperty('--'+k,cfg.palette[k]);});}
const COLL = cfg.collectionUrl || cfg.storeBase || 'https://www.designerwallcoverings.com';
document.querySelector('.corner.ul').setAttribute('href', cfg.houseUrl || 'https://www.designerwallcoverings.com');
const sbar=document.querySelector('.shopbar'); if(sbar){ sbar.href=COLL; sbar.innerHTML=`Shop the full ${LINE} collection at <b>Designer Wallcoverings</b> →`; }
if(!r.ok){document.getElementById('pdp').innerHTML='<div class="crumbs"><a href="/">← Back</a></div><h1 style="font-family:var(--serif)">Not found</h1>';return;}
const p=await r.json();
document.title=`${p.display_name||p.color||p.title} · ${LINE} | Designer Wallcoverings`;
const imgs=p.images.length?p.images:[p.swatch].filter(Boolean);
const main=imgs[0];
document.getElementById('pdp').innerHTML=`
<div class="crumbs"><a href="https://www.designerwallcoverings.com">Designer Wallcoverings</a> / <a href="/">${esc(LINE)}</a> / <a href="/#catalog">${esc(p.display_eyebrow||p.series)}</a> / ${esc(p.display_name||p.color||p.title)}</div>
<div class="pdp-top">
<div class="gallery">
<div class="main" id="main" style="background-image:url('${main}')"></div>
${imgs.length>1?`<div class="thumbs">${imgs.map((s,i)=>`<div class="t ${i===0?'on':''}" data-s="${s}" style="background-image:url('${s}')"></div>`).join('')}</div>`:''}
</div>
<div class="rail">
<div class="ser">${esc(p.display_eyebrow||p.book||LINE)}</div>
<h1>${esc(p.display_name||p.color||p.title)}</h1>
<div class="colr">${esc(p.sku)} · ${esc(p.substrate||'Non-Woven')}</div>
<a class="cta" href="${esc(p.store_url)}" target="_blank" rel="noopener">View & price on Designer Wallcoverings →</a>
<a class="cta ghost" href="${esc(p.store_url)}" target="_blank" rel="noopener">Order a sample</a>
<div class="share" id="share" data-url="${esc(p.store_url)}" data-title="${esc((p.color||p.title)+' · '+LINE+' | Designer Wallcoverings')}" data-img="${esc(main)}"></div>
<div class="spec">
${specRow('Item code',p.sku)}
${specRow('Grade',p.grade)}
${specRow('Format',p.sold_by)}
${specRow('Dimensions',p.width)}
${specRow('Substrate',p.substrate)}
${specRow('Wall coverage',p.coverage)}
${specRow('Lead-time',p.lead_time)}
${specRow('Origin',p.origin)}
</div>
</div>
</div>
<div class="story">
<div><h3>The story</h3><div>${p.body_html||'<p>'+esc(p.title)+' by '+esc(LINE)+'.</p>'}</div></div>
<div><h3>Specifications</h3><p>${esc(p.width||'')} · ${esc(p.substrate||'Non-Woven')} · ${esc(p.grade||'Residential')} grade · ${esc(p.coverage||'')} · ${esc(p.origin||'Made in Italy')}.</p></div>
<div><h3>Care & install</h3><p>Paste-the-wall non-woven · spongeable · lead-time ${esc(p.lead_time||'3–4 weeks')}. Order a sample before specifying.</p></div>
</div>
<section class="pairs" id="pairs" hidden>
<h3>Pairs well with</h3>
<div class="pair-grid" id="pairGrid"></div>
</section>`;
// JSON-LD Product schema
// No price in JSON-LD — pricing lives on the canonical DW product page (offers → its URL)
const ld={ "@context":"https://schema.org","@type":"Product",name:p.title+" by "+LINE,sku:p.sku,
brand:{"@type":"Brand",name:LINE},category:"Wallcoverings",image:imgs,
description:(p.body_html||'').replace(/<[^>]+>/g,'').slice(0,300),
offers:{"@type":"Offer",availability:"https://schema.org/InStock",url:p.store_url}};
const s=document.createElement('script');s.type='application/ld+json';s.textContent=JSON.stringify(ld);document.head.appendChild(s);
// pairs well with
try{
const pr=await (await fetch('/api/pairs/'+handle)).json();
if(pr.pairs&&pr.pairs.length){
document.getElementById('pairGrid').innerHTML=pr.pairs.map(q=>`
<a class="pcard" href="/product/${q.handle}">
<img loading="lazy" decoding="async" alt="${esc(q.title)}" src="${q.swatch||q.room||''}">
<div class="pc-b"><span class="pc-s">${esc(q.series||'')}</span><span class="pc-n">${esc(q.color||q.title)}</span></div>
</a>`).join('');
document.getElementById('pairs').hidden=false;
}
}catch(e){}
// gallery swap
document.querySelectorAll('.thumbs .t').forEach(t=>t.onclick=()=>{
document.getElementById('main').style.backgroundImage=`url('${t.dataset.s}')`;
document.querySelectorAll('.thumbs .t').forEach(x=>x.classList.remove('on'));t.classList.add('on');
});
// SEO: canonical → the live Shopify product (this landing complements, not competes)
if(p.store_url){const c=document.createElement('link');c.rel='canonical';c.href=p.store_url;document.head.appendChild(c);}
// social share — every target shares the REAL Designer Wallcoverings product page
renderShare();
})();
function renderShare(){
const el=document.getElementById('share'); if(!el)return;
const url=el.dataset.url, title=el.dataset.title||'', img=el.dataset.img||'';
const U=encodeURIComponent(url), T=encodeURIComponent(title), I=encodeURIComponent(img);
const ic={
pin:'<svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor"><path d="M12 2C6.5 2 4 5.8 4 8.9c0 1.9.7 3.6 2.3 4.2.3.1.5 0 .6-.3l.2-.9c.1-.3 0-.4-.2-.6-.4-.5-.7-1.2-.7-2.1 0-2.7 2-5.1 5.3-5.1 2.9 0 4.5 1.8 4.5 4.1 0 3.1-1.4 5.7-3.4 5.7-1.1 0-1.9-.9-1.7-2 .3-1.3.9-2.7.9-3.6 0-.8-.4-1.5-1.4-1.5-1.1 0-2 1.1-2 2.7 0 1 .3 1.6.3 1.6l-1.4 5.7c-.4 1.6 0 3.7 0 3.9 0 .1.2.2.3.1.1-.1 1.6-2 2.1-3.8l.8-3c.4.8 1.5 1.4 2.7 1.4 3.6 0 6-3.3 6-7.6C20.4 5 17 2 12 2z"/></svg>',
fb:'<svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor"><path d="M22 12a10 10 0 10-11.6 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.2c-1.2 0-1.6.8-1.6 1.6V12h2.7l-.4 2.9h-2.3v7A10 10 0 0022 12z"/></svg>',
x:'<svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor"><path d="M18.9 2H22l-7.3 8.3L23.3 22h-6.8l-5.3-7-6.1 7H2l7.8-8.9L1.2 2H8l4.8 6.3L18.9 2zm-1.2 18h1.9L7.1 4H5.1l12.6 16z"/></svg>',
mail:'<svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor"><path d="M4 4h16a2 2 0 012 2v12a2 2 0 01-2 2H4a2 2 0 01-2-2V6a2 2 0 012-2zm8 7L4 6.5V18h16V6.5L12 11z"/></svg>',
link:'<svg viewBox="0 0 24 24" width="17" height="17" fill="currentColor"><path d="M10.6 13.4a1 1 0 001.4 0l4-4a3 3 0 00-4.2-4.2l-1.3 1.3a1 1 0 101.4 1.4l1.3-1.3a1 1 0 011.4 1.4l-4 4a1 1 0 000 1.4zm2.8-2.8a1 1 0 00-1.4 0l-4 4a3 3 0 004.2 4.2l1.3-1.3a1 1 0 10-1.4-1.4l-1.3 1.3a1 1 0 01-1.4-1.4l4-4a1 1 0 000-1.4z"/></svg>',
};
el.innerHTML=`<span class="share-lbl">Share</span>
<a class="sbtn pin" title="Pin on Pinterest" target="_blank" rel="noopener" href="https://pinterest.com/pin/create/button/?url=${U}&media=${I}&description=${T}">${ic.pin}</a>
<a class="sbtn fb" title="Share on Facebook" target="_blank" rel="noopener" href="https://www.facebook.com/sharer/sharer.php?u=${U}">${ic.fb}</a>
<a class="sbtn x" title="Share on X" target="_blank" rel="noopener" href="https://twitter.com/intent/tweet?url=${U}&text=${T}">${ic.x}</a>
<a class="sbtn mail" title="Email" href="mailto:?subject=${T}&body=${T}%20${U}">${ic.mail}</a>
<button class="sbtn copy" title="Copy link" type="button">${ic.link}</button>`;
const copy=el.querySelector('.copy');
copy.addEventListener('click',async()=>{
try{
if(navigator.share){await navigator.share({title:el.dataset.title,url});return;}
await navigator.clipboard.writeText(url); copy.classList.add('done');
copy.title='Copied!'; setTimeout(()=>{copy.classList.remove('done');copy.title='Copy link';},1600);
}catch(e){}
});
}
</script>
</body>
</html>