← back to Chinoiseriewallpaper
public/index.html
526 lines
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Anti-flash: apply saved theme before paint -->
<script>
(function(){
var t = localStorage.getItem('cw-theme') || 'light';
document.documentElement.setAttribute('data-theme', t);
})();
</script>
<title>Chinoiserie Wallpaper | Heritage Oriental Wallcoverings | Designer Wallcoverings</title>
<link rel="canonical" href="https://chinoiseriewallpaper.com/">
<meta property="og:type" content="website">
<meta property="og:url" content="https://chinoiseriewallpaper.com/">
<meta property="og:title" content="Chinoiserie Wallpaper | Heritage Oriental Wallcoverings | Designer Wallcoverings">
<meta property="og:description" content="Discover museum-quality chinoiserie and oriental wallcoverings — peacocks, pagodas, peonies, and hand-painted-style motifs curated by Designer Wallcoverings. Free memo samples. Trade service available.">
<meta property="og:image" content="https://chinoiseriewallpaper.com/hero-bg.jpg">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Chinoiserie Wallpaper | Heritage Oriental Wallcoverings | Designer Wallcoverings">
<meta name="twitter:description" content="Discover museum-quality chinoiserie and oriental wallcoverings — peacocks, pagodas, peonies, and hand-painted-style motifs curated by Designer Wallcoverings. Free memo samples. Trade service available.">
<meta name="twitter:image" content="https://chinoiseriewallpaper.com/hero-bg.jpg">
<meta name="description" content="Discover museum-quality chinoiserie and oriental wallcoverings — peacocks, pagodas, peonies, and hand-painted-style motifs curated by Designer Wallcoverings. Free memo samples. Trade service available.">
<!-- Google Fonts: Cormorant (editorial serif) + Jost (clean sans) -->
<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=Cormorant+Garamond:ital,wght@0,300;0,400;0,600;1,300;1,400&family=Jost:wght@300;400;500&display=swap" rel="stylesheet">
<!-- JSON-LD Organization -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Organization",
"name": "Chinoiserie Wallpaper",
"url": "https://chinoiseriewallpaper.com",
"email": "info@chinoiseriewallpaper.com",
"parentOrganization": {
"@type": "Organization",
"name": "Designer Wallcoverings",
"url": "https://designerwallcoverings.com"
}
}
</script>
<link rel="stylesheet" href="/css/site.css">
<!-- corner-nav disabled (UL-hamburger rebuild) -->
<script src="/sku-redact.js" defer></script>
<style id="ns-modal-css">
/* ── Contact modal (.ns-modal) — added by fanout-12 ── */
.ns-modal {
display: none;
position: fixed; inset: 0; z-index: 1000;
background: rgba(10,10,10,0.78);
backdrop-filter: blur(6px);
align-items: center; justify-content: center;
padding: 24px;
font-family: -apple-system, "SF Pro Text", system-ui, sans-serif;
}
.ns-modal.show { display: flex; }
.ns-modal-card {
position: relative;
background: #f5f1e8;
color: #0a0a0a;
width: 100%; max-width: 480px;
padding: 36px 32px 32px;
border-radius: 4px;
box-shadow: 0 30px 80px rgba(0,0,0,0.55);
animation: nsModalIn 220ms cubic-bezier(.2,.7,.2,1);
}
@keyframes nsModalIn { from { opacity:0; transform: translateY(8px) scale(.985); } to { opacity:1; transform:none; } }
.ns-modal-card .close-x {
position: absolute; top: 10px; right: 12px;
width: 32px; height: 32px;
background: transparent; border: 0; cursor: pointer;
font-size: 22px; line-height: 1; color: #6e6e68;
}
.ns-modal-card .close-x:hover { color: #0a0a0a; }
.ns-modal-card h3 {
margin: 0 0 4px;
font: 300 22px/1.2 -apple-system, "SF Pro Display", system-ui, sans-serif;
letter-spacing: -0.005em;
color: #0a0a0a;
}
.ns-modal-card .sub {
margin: 0 0 22px;
font: 13px/1.45 -apple-system, "SF Pro Text", system-ui, sans-serif;
color: #6e6e68;
letter-spacing: 0.005em;
}
.ns-actions { display: flex; flex-direction: column; gap: 10px; }
.ns-action {
display: flex; align-items: center; gap: 14px;
padding: 14px 16px;
background: #ffffff;
border: 1px solid rgba(10,10,10,0.08);
border-radius: 3px;
color: #0a0a0a !important;
text-decoration: none !important;
font: 400 14px/1.3 -apple-system, "SF Pro Text", system-ui, sans-serif;
cursor: pointer;
}
.ns-action:hover { background: #fffdf7; border-color: rgba(10,10,10,0.18); }
.ns-action .ico {
flex-shrink: 0;
width: 38px; height: 38px;
display: inline-flex; align-items: center; justify-content: center;
background: rgba(10,10,10,0.04);
border-radius: 50%;
font-size: 18px;
}
.ns-action .txt { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.ns-action .txt b { font-weight: 500; font-size: 14px; color: #0a0a0a; }
.ns-action .txt span {
font-weight: 400; font-size: 12px; color: #6e6e68;
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
@media (max-width: 480px) {
.ns-modal { padding: 14px; }
.ns-modal-card { padding: 28px 22px 22px; }
}
[data-theme="dark"] .ns-modal-card { background: #14110c; color: #f5f1e8; }
[data-theme="dark"] .ns-modal-card h3 { color: #f5f1e8; }
[data-theme="dark"] .ns-modal-card .sub { color: #a39c8b; }
[data-theme="dark"] .ns-action { background: rgba(245,241,232,0.04); border-color: rgba(245,241,232,0.10); color: #f5f1e8 !important; }
[data-theme="dark"] .ns-action:hover { background: rgba(245,241,232,0.08); border-color: rgba(245,241,232,0.22); }
[data-theme="dark"] .ns-action .ico { background: rgba(245,241,232,0.08); }
[data-theme="dark"] .ns-action .txt b { color: #f5f1e8; }
[data-theme="dark"] .ns-action .txt span { color: #a39c8b; }
/* ── Motif rails (added 2026-05-26 — fleet rails sweep) ─────────────── */
.rail-section { margin-bottom: 56px; }
.rail-head { display:flex; align-items:baseline; justify-content:space-between; margin-bottom:18px; padding-bottom:10px; border-bottom:1px solid var(--line, rgba(0,0,0,.10)); }
.rail-title-h { font-size: 22px; letter-spacing: .18em; text-transform: uppercase; font-weight: 600; margin: 0; }
.rail-all { font-size: 11px; letter-spacing: .18em; text-transform: uppercase; color: var(--ink-soft, #888); font-weight: 500; cursor: pointer; background: transparent; border: 0; padding: 0; font-family: inherit; }
.rail-all:hover { color: var(--accent, #b89060); }
.rail-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 18px; }
.rail-card { display: block; aspect-ratio: 1/1; overflow: hidden; position: relative; }
.rail-card img { width: 100%; height: 100%; object-fit: cover; object-position: center 12%; transition: transform .4s ease; }
.rail-card:hover img { transform: scale(1.04); }
.rail-card-label { position: absolute; bottom: 0; left: 0; right: 0; padding: 12px 14px; background: linear-gradient(to top, rgba(0,0,0,0.7), transparent); color: #fff; font-size: 11px; letter-spacing: .12em; text-transform: uppercase; }
.rail-pill { display: inline-flex; align-items: center; gap: 8px; padding: 7px 14px; border: 1px solid var(--line, rgba(0,0,0,.18)); background: transparent; color: var(--ink-soft, #555); font: inherit; font-size: 11px; letter-spacing: .14em; text-transform: uppercase; font-weight: 500; cursor: pointer; border-radius: 0; transition: border-color .15s, color .15s, background .15s; }
.rail-pill:hover { border-color: var(--accent, #b89060); color: var(--ink, #111); }
.rail-pill.active { border-color: var(--accent, #b89060); color: var(--accent, #b89060); background: rgba(184,144,96,0.06); }
.rail-pill span { font-size: 10px; opacity: .7; font-weight: 600; }
[data-theme="dark"] .rail-pill { border-color: rgba(245,241,232,0.18); color: #a39c8b; }
[data-theme="dark"] .rail-pill:hover { color: #f5f1e8; }
[data-theme="dark"] .rail-pill.active { background: rgba(184,144,96,0.10); color: var(--accent, #b89060); }
[data-theme="dark"] .rail-head { border-bottom-color: rgba(245,241,232,0.10); }
</style>
<!-- Meta Pixel — INERT until set-fb-pixel.sh is run (does NOT load fbevents.js or hit Meta until flipped) -->
<script>
(function(){
var PIXEL_ID = '{{FACEBOOK_PIXEL_ID}}';
// Inert until flipped — the brace check prevents BOTH the loader IIFE
// AND the init call from running, so fbevents.js is never fetched.
if (PIXEL_ID.indexOf('{{') !== -1) return;
!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,
document,'script','https://connect.facebook.net/en_US/fbevents.js');
fbq('init', PIXEL_ID);
fbq('track', 'PageView');
})();
</script>
<!-- noscript fallback is added by set-fb-pixel.sh on flip (omitted here to avoid unflipped img phone-home) -->
<!-- End Meta Pixel -->
</head>
<body>
<!-- Theme toggle (theme1 / theme2) — query-param-gated preview surface
(Steve 2026-05-29). ?theme=2 in URL flips to theme2 and persists in
localStorage. Toggle UI hidden until theme2 mode active. Same key
('wallco-page-theme') as wallco.ai for cross-site continuity. -->
<script>
(function(){
var qs = new URLSearchParams(location.search);
var fromUrl = qs.get('theme');
var saved = null; try { saved = localStorage.getItem('wallco-page-theme'); } catch(e){}
var theme = null;
if (fromUrl === '2' || fromUrl === 'theme2') theme = 'theme2';
else if (fromUrl === '1' || fromUrl === 'theme1') theme = 'theme1';
else if (saved === 'theme2' || saved === 'theme1') theme = saved;
if (theme) {
document.documentElement.setAttribute('data-page-theme', theme);
if (fromUrl) { try { localStorage.setItem('wallco-page-theme', theme); } catch(e){} }
}
})();
</script>
<style id="page-theme-css-fleet">
[data-page-theme="theme2"] body{
background:#fff !important; color:#0a0a0a !important;
}
[data-page-theme="theme2"] h1,
[data-page-theme="theme2"] h2,
[data-page-theme="theme2"] h3{ letter-spacing:-0.01em; font-weight:500; }
[data-page-theme="theme2"] .card,
[data-page-theme="theme2"] [class*="card"]{
background:#fafafa !important; border:1px solid #e5e5e5 !important; box-shadow:none !important;
}
#page-theme-toggle{ display:none; }
[data-page-theme] #page-theme-toggle{ display:inline-flex; }
#page-theme-toggle{
position:fixed; top:96px; right:14px; z-index:90;
gap:0; align-items:center;
background:rgba(255,255,255,.92); border:1px solid #d8d2c5;
border-radius:999px; padding:3px; backdrop-filter:blur(6px);
box-shadow:0 2px 10px rgba(0,0,0,.08);
font:600 11px ui-sans-serif,system-ui; letter-spacing:.06em; text-transform:uppercase;
}
#page-theme-toggle button{
border:0; background:transparent; color:#5a5048; cursor:pointer;
padding:6px 14px; border-radius:999px; font:inherit; transition:all .15s;
}
#page-theme-toggle button[aria-pressed="true"]{ background:#1a1714; color:#faf7f2; }
#page-theme-toggle button:hover:not([aria-pressed="true"]){ color:#1a1714; }
</style>
<div id="page-theme-toggle" role="group" aria-label="Page theme">
<button type="button" data-theme="theme1" aria-pressed="false">Theme 1</button>
<button type="button" data-theme="theme2" aria-pressed="false">Theme 2</button>
</div>
<script>
(function(){
var cur = document.documentElement.getAttribute('data-page-theme') || 'theme1';
var btns = document.querySelectorAll('#page-theme-toggle button');
function sync(t){ btns.forEach(function(b){ b.setAttribute('aria-pressed', b.dataset.theme === t ? 'true' : 'false'); }); }
sync(cur);
btns.forEach(function(b){
b.addEventListener('click', function(){
var t = b.dataset.theme;
document.documentElement.setAttribute('data-page-theme', t);
try { localStorage.setItem('wallco-page-theme', t); } catch(e){}
sync(t);
});
});
})();
</script>
<!-- ── HEADER ─────────────────────────────────────────────────────────── -->
<header class="site-header">
<div class="header-inner">
<a class="brand" href="/">
<span class="brand-mark">ぢ</span>
<span class="brand-text">Chinoiserie<br><em>Wallpaper</em></span>
</a>
<nav class="header-nav">
<a href="#collection">Collection</a>
<a href="https://designerwallcoverings.com/pages/trade" target="_blank" rel="noopener noreferrer">Trade</a>
<a href="mailto:info@chinoiseriewallpaper.com">Contact</a>
</nav>
<div class="header-actions">
<button class="theme-toggle" id="themeToggle" aria-label="Toggle dark/light mode" title="Toggle dark/light">
<!-- Sun icon (shown in dark mode) -->
<svg class="icon-sun" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/>
<line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/>
</svg>
<!-- Moon icon (shown in light mode) -->
<svg class="icon-moon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
</svg>
</button>
</div>
</div>
</header>
<!-- ── HERO ───────────────────────────────────────────────────────────── -->
<section class="hero" id="hero">
<div class="hero-content">
<p class="hero-eyebrow">Heritage Oriental Wallcoverings</p>
<h1>The Art of<br><em>Chinoiserie</em></h1>
<p class="hero-sub">Museum-quality peonies, peacocks & pagodas — curated from the world's finest ateliers. Free memo samples. Trade service available.</p>
<a href="#collection" class="btn-primary">Explore the Collection</a>
</div>
<div class="hero-gradient"></div>
</section>
<!-- ── HOUSE MARKS ────────────────────────────────────────────────────── -->
<section class="house-marks">
<div class="marks-inner">
<div class="mark">
<span class="mark-icon">✦</span>
<span>Free Memo Samples</span>
</div>
<div class="mark">
<span class="mark-icon">✦</span>
<span>Trade Accounts Welcome</span>
</div>
<div class="mark">
<span class="mark-icon">✦</span>
<span>White-Glove Spec Service</span>
</div>
<div class="mark">
<span class="mark-icon">✦</span>
<span>1,100+ Chinoiserie Patterns</span>
</div>
</div>
</section>
<!-- ── BROWSE BY MOTIF (rail sections) ────────────────────────────────── -->
<section class="rails" id="motifRails" aria-label="Browse by motif" style="max-width:1400px;margin:0 auto;padding:48px 32px 0">
<div id="railSections"></div>
</section>
<!-- ── COLLECTION ─────────────────────────────────────────────────────── -->
<section class="collection" id="collection">
<div class="collection-header">
<h2>The Collection</h2>
<p class="collection-sub">Distilled from the world's finest wallcovering ateliers — every pattern curated for its fidelity to the chinoiserie tradition.</p>
</div>
<!-- Pills strip — wired to the Motif filter -->
<nav class="rail-pills" id="railPills" aria-label="Filter by motif" style="display:flex;gap:10px;flex-wrap:wrap;padding:14px 0 22px;margin-bottom:6px;border-bottom:1px solid var(--line,rgba(0,0,0,.08))"></nav>
<!-- Controls bar -->
<div class="controls-bar">
<div class="search-wrap">
<svg class="search-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
<input type="search" id="searchInput" placeholder="Search by name or motif…" autocomplete="off">
</div>
<div class="filter-wrap">
<label for="aestheticFilter">Motif</label>
<select id="aestheticFilter">
<option value="all">All Motifs</option>
<option value="green">Green</option>
<option value="commercial">Commercial</option>
<option value="white">White</option>
<option value="architectural">Architectural</option>
<option value="botanical">Botanical</option>
<option value="floral">Floral</option>
</select>
</div>
<div class="sort-wrap">
<label for="sortSelect">Sort</label>
<select id="sortSelect">
<option value="newest">Newest</option>
<option value="color">Color (grouped)</option>
<option value="style">Style</option>
<option value="light-dark">Light → Dark</option>
<option value="dark-light">Dark → Light</option>
<option value="wheel">Color Wheel</option>
<option value="sku">SKU A–Z</option>
<option value="title">Title A–Z</option>
<option value="price-asc">Price ↑</option>
<option value="price-desc">Price ↓</option>
</select>
</div>
<div class="density-wrap">
<label for="densitySlider">Density</label>
<input type="range" id="densitySlider" min="1" max="4" value="3" step="1">
</div>
</div>
<!-- Results count -->
<div class="results-bar">
<span id="resultsCount">Loading…</span>
</div>
<!-- Product grid -->
<div class="product-grid" id="productGrid" data-cols="3">
</div>
<!-- Pagination -->
<div class="pagination" id="pagination"></div>
</section>
<!-- ── EDITORIAL BREAK ─────────────────────────────────────────────────── -->
<section class="editorial-break">
<div class="editorial-inner">
<blockquote>
<p>"Chinoiserie represents the Western imagination's dialogue with the East — a centuries-long conversation conducted in lacquer, silk, and hand-applied pigment."</p>
<cite>— Designer Wallcoverings Editorial</cite>
</blockquote>
</div>
</section>
<!-- ── SAMPLE CTA BAND ─────────────────────────────────────────────────── -->
<section class="sample-band">
<div class="sample-band-inner">
<div class="sample-band-text">
<h3>Order Memo Samples — Free</h3>
<p>Touch the pattern before you commit. Every chinoiserie wallcovering in our collection is available as a complimentary memo sample, shipped to your studio or jobsite.</p>
</div>
<a href="https://designerwallcoverings.com/collections/wallcoverings" target="_blank" rel="noopener noreferrer" class="btn-primary btn-gold">Request Samples</a>
</div>
</section>
<!-- ── FOOTER ─────────────────────────────────────────────────────────── -->
<footer class="site-footer">
<div class="footer-inner">
<div class="footer-brand">
<span class="brand-text-sm">Chinoiserie Wallpaper</span>
<p>A curated vertical of <a href="https://designerwallcoverings.com" target="_blank" rel="noopener noreferrer">Designer Wallcoverings</a></p>
<p><a href="mailto:info@chinoiseriewallpaper.com">info@chinoiseriewallpaper.com</a></p>
</div>
<div class="footer-links">
<a href="https://designerwallcoverings.com/pages/trade" target="_blank" rel="noopener noreferrer">Trade Accounts</a>
<a href="https://designerwallcoverings.com/pages/contact" target="_blank" rel="noopener noreferrer">Contact DW</a>
<a href="https://designerwallcoverings.com/pages/privacy-policy" target="_blank" rel="noopener noreferrer">Privacy</a>
</div>
<div class="footer-mark">
<p>© 2026 Designer Wallcoverings. All rights reserved.</p>
</div>
</div>
</footer>
<script src="/js/site.js"></script>
<script>
/* ── Motif rails + pills (fleet rails sweep 2026-05-26) ──────────────
Fetches /api/sliders (rail sections) + /api/facets (pill counts),
renders them, and wires the pills to the existing #aestheticFilter
select so clicks scroll-to the grid filtered by motif. */
(function(){
function el(tag, props, html){ var n=document.createElement(tag); Object.assign(n, props||{}); if(html) n.innerHTML=html; return n; }
function esc(s){ return String(s).replace(/[&<>"]/g, function(c){ return ({'&':'&','<':'<','>':'>','"':'"'}[c]); }); }
function setMotif(m){
var sel = document.getElementById('aestheticFilter');
if (!sel) return;
sel.value = m || 'all';
// Trigger the existing change handler that re-renders the grid.
sel.dispatchEvent(new Event('change', { bubbles: true }));
var grid = document.getElementById('productGrid');
if (grid) grid.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
function renderPills(facets){
var bar = document.getElementById('railPills');
if (!bar || !facets) return;
var aesth = facets.aesthetics || {};
var total = facets.total || 0;
bar.innerHTML = '';
var current = (localStorage.getItem('cw-aesthetic') || 'all').toLowerCase();
var allBtn = el('button', { type:'button', className: 'rail-pill' + (current==='all' ? ' active' : '') });
allBtn.innerHTML = 'All <span>' + total.toLocaleString() + '</span>';
allBtn.addEventListener('click', function(){ setMotif('all'); document.querySelectorAll('#railPills .rail-pill').forEach(function(p){ p.classList.remove('active'); }); allBtn.classList.add('active'); });
bar.appendChild(allBtn);
var entries = Object.entries(aesth).filter(function(e){ return e[0] && e[1]>=4; }).sort(function(a,b){ return b[1]-a[1]; }).slice(0,8);
entries.forEach(function(e){
var key = e[0], count = e[1];
var p = el('button', { type:'button', className: 'rail-pill' + (current===key ? ' active' : '') });
p.innerHTML = esc(key.charAt(0).toUpperCase()+key.slice(1)) + ' <span>' + count.toLocaleString() + '</span>';
p.addEventListener('click', function(){ setMotif(key); document.querySelectorAll('#railPills .rail-pill').forEach(function(x){ x.classList.remove('active'); }); p.classList.add('active'); });
bar.appendChild(p);
});
}
function railCard(p){
var img = p.image_url || (p.images && p.images[0]) || '';
var title = p.title || p.handle || '';
var href = p.product_url || ('/sample/' + encodeURIComponent(p.handle_display || p.handle || p.sku || ''));
return '<a class="rail-card" href="' + esc(href) + '" target="_blank" rel="noopener noreferrer">' +
(img ? '<img src="' + esc(img) + '" alt="' + esc(title) + '" loading="lazy">' : '') +
'<span class="rail-card-label">' + esc(title) + '</span></a>';
}
function renderRails(rails){
var host = document.getElementById('railSections');
if (!host || !rails || !rails.length) return;
host.innerHTML = rails.slice(0, 4).map(function(r){
var cards = (r.items || []).slice(0, 8).map(railCard).join('');
var label = r.aesthetic.charAt(0).toUpperCase() + r.aesthetic.slice(1);
return '<section class="rail-section">' +
'<div class="rail-head"><h2 class="rail-title-h">' + esc(label) + '</h2>' +
'<button class="rail-all" type="button" data-motif="' + esc(r.aesthetic) + '">View all →</button></div>' +
'<div class="rail-grid">' + cards + '</div></section>';
}).join('');
host.querySelectorAll('.rail-all').forEach(function(b){
b.addEventListener('click', function(){ setMotif(b.dataset.motif); });
});
}
Promise.all([
fetch('/api/facets').then(function(r){ return r.json(); }).catch(function(){ return null; }),
fetch('/api/sliders').then(function(r){ return r.json(); }).catch(function(){ return null; })
]).then(function(results){
if (results[0]) renderPills(results[0]);
if (results[1] && results[1].rails) renderRails(results[1].rails);
});
})();
</script>
<!-- Big Red customer chat — lower-left, woman-avatar, vendor-redacted retail persona. -->
<script data-bigred-widget src="https://chat.designerwallcoverings.com/widget.js"
data-host="https://chat.designerwallcoverings.com"
data-mode="retail"
defer onerror="this.remove()"></script>
<!-- Contact modal — invisible until nsContactOpen() adds .show class. Added by fanout-12. -->
<div class="ns-modal" id="nsContactModal" role="dialog" aria-modal="true" aria-labelledby="nsContactTitle" onclick="if(event.target===this)nsContactClose()">
<div class="ns-modal-card">
<button type="button" class="close-x" onclick="nsContactClose()" aria-label="Close">×</button>
<h3 id="nsContactTitle">How can we help?</h3>
<p class="sub">Trade-account replies within one business day.</p>
<div class="ns-actions">
<a class="ns-action" href="mailto:info@chinoiseriewallpaper.com?subject=Chinoiseriewallpaper%20inquiry"><span class="ico">✉</span><div class="txt"><b>Email Us</b><span>info@chinoiseriewallpaper.com</span></div></a>
<a class="ns-action" href="tel:888-373-4564"><span class="ico">📞</span><div class="txt"><b>Call Us</b><span>(888) 373-4564 · M–F, 9–5 PT</span></div></a>
</div>
</div>
</div>
<script>
if (typeof window.nsContactOpen !== 'function') {
window.nsContactOpen = function () { var m = document.getElementById('nsContactModal'); if (m) m.classList.add('show'); };
window.nsContactClose = function () { var m = document.getElementById('nsContactModal'); if (m) m.classList.remove('show'); };
}
</script>
<script>window.DwHeaderConfig={siteName:"Chinoiserie Wallpaper",accent:"#9B7B4F",navLinks:[{name:'Home',url:'/'},{name:'Collections',url:'#shop'},{name:'About',url:'/about'},{name:'Care',url:'/care.html'},{name:'History',url:'/history.html'}],adminLinks:[{name:'Shopify admin',url:'https://admin.shopify.com',external:true},{name:'Edit hero',url:'#'},{name:'Analytics',url:'#'}]};</script>
<script src="/dw-header.js" defer></script>
<script src="/dw-theme-nav.js" defer></script>
</body>
</html>