← back to Consulting Designerwallcoverings Com
auto-save: 2026-07-26T20:45:50 (11 files) — build.mjs data/dw-analysis.json public/portal.html public/versions/atelier.html public/versions/gallery.html
10291a7bdfe3c17dbbbd17422dac6d0ed38544bf · 2026-07-26 20:45:53 -0700 · Steve Abrams
Files touched
M build.mjsM data/dw-analysis.jsonM public/portal.htmlM public/versions/atelier.htmlM public/versions/gallery.htmlM public/versions/heritage.htmlM public/versions/maison.htmlM public/versions/studio.htmlM public/versions/texture.htmlA scripts/aeo-render.mjsM scripts/collect-dw.mjs
Diff
commit 10291a7bdfe3c17dbbbd17422dac6d0ed38544bf
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Sun Jul 26 20:45:53 2026 -0700
auto-save: 2026-07-26T20:45:50 (11 files) — build.mjs data/dw-analysis.json public/portal.html public/versions/atelier.html public/versions/gallery.html
---
build.mjs | 42 ++++---
data/dw-analysis.json | 260 ++++++++++++++++++++++++++++++++++++++----
public/portal.html | 64 +++++------
public/versions/atelier.html | 53 ++++-----
public/versions/gallery.html | 75 ++++++------
public/versions/heritage.html | 75 ++++++------
public/versions/maison.html | 63 +++++-----
public/versions/studio.html | 75 ++++++------
public/versions/texture.html | 75 ++++++------
scripts/aeo-render.mjs | 57 +++++++++
scripts/collect-dw.mjs | 4 +-
11 files changed, 547 insertions(+), 296 deletions(-)
diff --git a/build.mjs b/build.mjs
index c391d2f..7730823 100644
--- a/build.mjs
+++ b/build.mjs
@@ -274,10 +274,10 @@ body.nav .menu{transform:none}body.nav .scrim{opacity:1;pointer-events:auto}
.slide{position:absolute;inset:0;background-size:cover;background-position:center;opacity:0;transform:scale(1.04);transition:opacity 1.4s ease;will-change:transform,opacity}
.slide.on{opacity:1;animation:kenburns 13s ease-out forwards}
@keyframes kenburns{from{transform:scale(1.04) translate3d(0,0,0)}to{transform:scale(1.13) translate3d(-1.4%,-1.2%,0)}}
-.hero:after{content:'';position:absolute;inset:0;background:linear-gradient(90deg,rgba(14,12,9,.90),rgba(14,12,9,.48) 58%,rgba(14,12,9,.16));z-index:1}
+.hero:after{content:'';position:absolute;inset:0;background:linear-gradient(90deg,rgba(14,12,9,.93),rgba(14,12,9,.72) 60%,rgba(14,12,9,.40));z-index:1}
.hero .in{position:relative;z-index:2;max-width:960px}
.kick{font-size:12px;letter-spacing:.4em;text-transform:uppercase;color:var(--gold);margin-bottom:22px}
-.hero h1{font-family:'Cormorant Garamond',serif;font-weight:400;font-size:clamp(40px,6.6vw,92px);line-height:1.02}.hero h1 span{color:var(--gold)}
+.hero h1{font-family:'Cormorant Garamond',serif;font-weight:400;font-size:clamp(40px,6.6vw,92px);line-height:1.02;text-shadow:0 2px 22px rgba(0,0,0,.72),0 1px 3px rgba(0,0,0,.9)}.hero h1 span{color:var(--gold)}
.hero p{max-width:64ch;margin-top:24px;font-size:18px;color:var(--dim)}
.metrics{display:flex;flex-wrap:wrap;gap:46px;margin-top:46px}
.metrics .v{font-family:'Cormorant Garamond',serif;font-size:40px;color:var(--gold);line-height:1}
@@ -640,25 +640,32 @@ function initMap(){if(mapped||!window.L||!document.getElementById('compmap'))ret
</body></html>`;
/* ================================================== concept version pages === */
+const CONCEPT_CARDS = 10;
function versionPage(h, conceptIdx = 0) {
- // Real, already-customer-facing product imagery from the snapshot gallery —
- // each concept starts at a different offset so the six pages read distinct.
- const off = (conceptIdx * 4) % Math.max(GALLERY.length, 1);
- const pool = GALLERY.length >= 12
- ? [...GALLERY.slice(off), ...GALLERY.slice(0, off)].slice(0, 12)
+ // Real, already-customer-facing product imagery from the snapshot gallery.
+ // Each of the six concepts owns a DISJOINT slice (conceptIdx*10 .. +10), so no
+ // two concepts share a single card — the pages read as genuinely distinct
+ // merchandising sets, not palette swaps (DTD OPTION 1, 5/5, 2026-07-26). The
+ // collector pulls 60 distinct-on-vendor products so 6×10 fits with zero overlap;
+ // if a snapshot ever returns fewer, this degrades to a wrap-around (some overlap).
+ const off = GALLERY.length ? (conceptIdx * CONCEPT_CARDS) % GALLERY.length : 0;
+ const pool = GALLERY.length >= CONCEPT_CARDS
+ ? Array.from({ length: CONCEPT_CARDS }, (_, i) => GALLERY[(off + i) % GALLERY.length])
: null;
- const gridCards = Array.from({ length: 12 }, (_, i) => {
- const hue = [28, 152, 208, 12, 262, 88, 340, 190, 46, 300, 130, 20][i];
+ const gridCards = Array.from({ length: CONCEPT_CARDS }, (_, i) => {
+ const hue = [28, 152, 208, 12, 262, 88, 340, 190, 46, 300][i % 10];
const g = pool ? pool[i] : null;
- const title = g ? g.title.split('|')[0].replace(/\s*Wallcoverings?\b.*$/i, '').replace(/\s*[-–,]\s*$/, '').trim() : ['Chinois Garden', 'Venetian Plaster', 'Grasscloth No. 9', 'Deco Fan', 'Midnight Damask', 'Coastal Weave', 'Rosewood Toile', 'Celadon Silk', 'Gilt Trellis', 'Amethyst Moire', 'Sage Stripe', 'Terra Fresco'][i];
- const metaLeft = g ? g.vendor : ['Wallcovering', 'Fabric', 'Mural'][i % 3];
- const tierName = ['casual', 'signature', 'reserve'][i % 3];
+ const title = g ? g.title.split('|')[0].replace(/\s*Wallcoverings?\b.*$/i, '').replace(/\s*[-–,]\s*$/, '').trim() : ['Chinois Garden', 'Venetian Plaster', 'Grasscloth No. 9', 'Deco Fan', 'Midnight Damask', 'Coastal Weave', 'Rosewood Toile', 'Celadon Silk', 'Gilt Trellis', 'Amethyst Moire'][i];
+ // Only fields that actually exist on the gallery record (vendor + type) — no
+ // fabricated hue/tier. Sorts below are backed by these real values.
+ const vendor = g ? g.vendor : ['Atelier House', 'Maison Textile', 'Studio Mural'][i % 3];
+ const ptype = g ? (g.type || 'Wallcovering') : ['Wallcovering', 'Fabric', 'Mural'][i % 3];
const img = g
? `<div class="gimg"><img src="${g.image}&width=540" loading="lazy" alt="${String(title).replace(/"/g, '"')}"></div>`
: `<div class="gimg" style="background:linear-gradient(135deg,hsl(${hue},22%,${h.dark ? 24 : 78}%),hsl(${(hue + 40) % 360},30%,${h.dark ? 14 : 64}%))"></div>`;
- return `<article class="gcard" data-title="${String(title).replace(/"/g, '"')}" data-hue="${hue}" data-tier="${i % 3}">
+ return `<article class="gcard" data-title="${String(title).replace(/"/g, '"')}" data-vendor="${String(vendor).replace(/"/g, '"')}" data-type="${String(ptype).replace(/"/g, '"')}">
${img}
- <h4>${title}</h4><div class="gmeta"><span>${metaLeft}</span><span class="tier">${tierName}</span></div>
+ <h4>${title}</h4><div class="gmeta"><span>${vendor}</span><span class="tier">${ptype}</span></div>
</article>`;
}).join('');
return `<!doctype html><html lang="en"><head>
@@ -734,7 +741,7 @@ footer .in{max-width:1240px;margin:0 auto;padding:36px 22px;display:flex;justify
<div class="sh"><h2>Curated This Week</h2>
<div class="controls">
<label for="sortsel">Sort</label>
- <span class="selwrap"><select id="sortsel"><option value="newest">Newest</option><option value="color">Color</option><option value="title">Title A→Z</option><option value="tier">Collection tier</option></select></span>
+ <span class="selwrap"><select id="sortsel"><option value="newest">Newest</option><option value="title">Title A→Z</option><option value="vendor">Vendor A→Z</option><option value="type">Type</option></select></span>
<label for="dens">Density</label>
<input type="range" id="dens" min="2" max="6" step="1" value="4">
</div>
@@ -751,8 +758,9 @@ var grid=document.getElementById('grid'),sel=document.getElementById('sortsel'),
var KS='dwconcept-${h.key}-sort',KD='dwconcept-${h.key}-cols';
function apply(){var v=sel.value,cards=[].slice.call(grid.children);
cards.sort(function(a,b){if(v==='title')return a.dataset.title.localeCompare(b.dataset.title);
- if(v==='color')return (+a.dataset.hue)-(+b.dataset.hue);
- if(v==='tier')return (+a.dataset.tier)-(+b.dataset.tier);return 0;});
+ if(v==='vendor')return a.dataset.vendor.localeCompare(b.dataset.vendor);
+ if(v==='type')return (a.dataset.type||'').localeCompare(b.dataset.type||'')||a.dataset.title.localeCompare(b.dataset.title);
+ return 0;});
cards.forEach(function(c){grid.appendChild(c);});localStorage.setItem(KS,v);}
function densFill(){var mn=+dens.min||2,mx=+dens.max||6;dens.style.setProperty('--fill',((dens.value-mn)/(mx-mn)*100)+'%');}
sel.addEventListener('change',apply);
diff --git a/data/dw-analysis.json b/data/dw-analysis.json
index b67278c..6823a7e 100644
--- a/data/dw-analysis.json
+++ b/data/dw-analysis.json
@@ -1,5 +1,5 @@
{
- "collected_at": "2026-07-27T03:39:57.235Z",
+ "collected_at": "2026-07-27T03:42:51.507Z",
"sources": {
"mirror": "dw_unified local mirror (host=/tmp) — READ ONLY",
"mcc": "marketing.designerwallcoverings.com/api/channels/status",
@@ -9,9 +9,9 @@
},
"catalog": {
"statuses": {
- "ACTIVE": 80752,
+ "ACTIVE": 80773,
"ARCHIVED": 80477,
- "DRAFT": 20628,
+ "DRAFT": 20607,
"DELETED_FROM_SHOPIFY": 16203,
"UNLISTED": 1
},
@@ -19,7 +19,7 @@
"top_vendors": [
{
"vendor": "Phillipe Romano",
- "active": 11420
+ "active": 11439
},
{
"vendor": "Rebel Walls",
@@ -77,7 +77,7 @@
"types": [
{
"type": "Wallcovering",
- "active": 58499
+ "active": 58520
},
{
"type": "Fabric",
@@ -118,11 +118,11 @@
],
"five_field": {
"missing_sample": 2294,
- "missing_sellable": 26899,
+ "missing_sellable": 26918,
"missing_description": 168,
"missing_image": 333,
"zero_price": 1440,
- "active_total": 80752
+ "active_total": 80773
},
"activation_cadence": [
{
@@ -163,7 +163,7 @@
},
{
"week": "07-20",
- "added": 3588
+ "added": 3590
}
],
"price_bands": [
@@ -189,17 +189,17 @@
}
],
"price_bands_basis": "products whose minimum variant exceeds the $4.25 memo sample — the priced subset of the mirror (~3.8k); most actives resolve min-variant to the sample, and full variant-level pricing lives Shopify-side",
- "drafts_total": 20628,
- "drafts_stageable": 2802,
+ "drafts_total": 20607,
+ "drafts_stageable": 2800,
"sample_only": {
- "quote_only_by_design": 3951,
- "total": 26899,
+ "quote_only_by_design": 3970,
+ "total": 26918,
"backlog": 22948
},
"sample_only_vendors": [
{
"vendor": "Phillipe Romano",
- "count": 6074
+ "count": 6093
},
{
"vendor": "Phillip Jeffries",
@@ -232,17 +232,17 @@
],
"sample_roll": {
"funnel": {
- "sampleable": 78458,
- "converted": 51717,
- "gap": 26741,
- "gap_quote_only": 3951,
+ "sampleable": 78479,
+ "converted": 51719,
+ "gap": 26760,
+ "gap_quote_only": 3970,
"gap_backlog": 22790,
"conversion_pct": 65.9
},
"vendors": [
{
"vendor": "Phillipe Romano",
- "sampleable": 10138,
+ "sampleable": 10157,
"converted": 4064,
"leak": 3521
},
@@ -349,7 +349,7 @@
},
{
"month": "Jul",
- "added": 10563
+ "added": 10584
}
],
"needs_tags": [
@@ -381,7 +381,7 @@
},
{
"style": "Traditional",
- "count": 22721
+ "count": 22723
},
{
"style": "Geometric",
@@ -389,7 +389,7 @@
},
{
"style": "Floral",
- "count": 10292
+ "count": 10293
},
{
"style": "Grasscloth",
@@ -401,7 +401,7 @@
},
{
"style": "Mural",
- "count": 4796
+ "count": 4798
},
{
"style": "Metallic",
@@ -1030,6 +1030,222 @@
"vendor": "Charles Burger",
"type": "Fabric",
"image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/vert-1904_1_134404.jpg?v=1782672048"
+ },
+ {
+ "title": "Lulu Stripe Navy on White Linen Screen Printed | China Seas",
+ "vendor": "China Seas",
+ "type": "Fabric",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/navy-on-white-linen-1781_1_214246.jpg?v=1781635420"
+ },
+ {
+ "title": "Avant Le Mistral Panel | Christian Lacroix Europe",
+ "vendor": "Christian Lacroix Europe",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/160349_11f10447-e6d5-426b-aabf-07ca78428354.webp?v=1738951241"
+ },
+ {
+ "title": "Highland Wonder/Lagoon Wp | Clarke and Clarke",
+ "vendor": "Clarke and Clarke",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/W0202_01_CAC.jpg?v=1777020004"
+ },
+ {
+ "title": "Gray | Cloth and Paper",
+ "vendor": "Cloth and Paper",
+ "type": "Fabric",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/gray-313_1_155301.jpg?v=1782479480"
+ },
+ {
+ "title": "Soie Bois Tresse Epicéa | CMO Paris",
+ "vendor": "CMO Paris",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/cmo-soie-bois-mural-wso-03-68.jpg?v=1785007404"
+ },
+ {
+ "title": "Palm Jungle - Olive Green On White | Cole & Son",
+ "vendor": "Cole & Son",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/PalmJungle_Image_Flatshot_Item_95-1001.jpg?v=1779809928"
+ },
+ {
+ "title": "Mens Bomber Jacket",
+ "vendor": "Contrado",
+ "type": "Others",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/2643921_mens-bomber-jacket_0.jpg?v=1742242131"
+ },
+ {
+ "title": "Manor-Gardens Winter | Coordonné",
+ "vendor": "Coordonné",
+ "type": "Mural",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/YSP0546_01.jpg?v=1784738420"
+ },
+ {
+ "title": "Allure - Bronzy Taupe | Daisy Bennett",
+ "vendor": "Daisy Bennett",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/products/db11526.jpg?v=1602006818"
+ },
+ {
+ "title": "Coutts — Deep Rich Gold gilded Xuan paper",
+ "vendor": "De Gournay",
+ "type": "Wallpaper",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/06052020101555.jpg?v=1784731138"
+ },
+ {
+ "title": "Bambù Strié Wall - 002 Wallcovering | Dedar",
+ "vendor": "Dedar",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/1__74269.1773625470.jpg?v=1773712278"
+ },
+ {
+ "title": "Madagascar Cloth 3 Raffia",
+ "vendor": "Designer Wallcoverings",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/DWC-278566-DesignerWallcoverings-Los-Angeles-1_a3bede8c-b94d-477d-b0c2-97ad23dba752.png?v=1741881338"
+ },
+ {
+ "title": "Huerta Gitana Piedra - Piedra Wallcovering | Designers Guild",
+ "vendor": "Designers Guild",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/huerta-gitana-piedra.webp?v=1761090551"
+ },
+ {
+ "title": "Color Bars, Olive Wallcoverings | Designtex",
+ "vendor": "Designtex",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/6727501__26889.1730829023.jpg?v=1783690828"
+ },
+ {
+ "title": "Sol Carretto Mural Rocco By Dolce & Gabbana",
+ "vendor": "Dolce & Gabbana",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/TCW011TCAHPUC092.jpg?v=1711558473"
+ },
+ {
+ "title": "Gallery Walls - White wallcovering | Donghia",
+ "vendor": "Donghia",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/DG-09703_010.jpg?v=1772819030"
+ },
+ {
+ "title": "Accessorise Type Ii Vinyl Cadillac | Dupenny",
+ "vendor": "Dupenny",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Accessorise-CADILLAC-WP-Thumb-Shop.jpg?v=1775598529"
+ },
+ {
+ "title": "Anemone Opera - Powder Tide - Whimsical Wallcoverings",
+ "vendor": "DW Bespoke Studio",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/tidepool-bloom-v5-nano.png?v=1784779206"
+ },
+ {
+ "title": "Courtright Cranes Red and Cream",
+ "vendor": "DW Exclusive Wallpaper",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/DWC-211497-DesignerWallcoverings-Los-Angeles-4_7be9edb9-4fa6-4932-befb-1ff3ea511732.jpg?v=1694028327"
+ },
+ {
+ "title": "Chiba Bay Blue Throw Blanket on Vitali Velvet",
+ "vendor": "DW Home",
+ "type": "Others",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/products/11859510-dig-762164-chibabay-blue-by-designerwallcoverings_19-1_a3ea7102-1f49-4d97-9c9b-15dd0926b182.jpg?v=1630525797"
+ },
+ {
+ "title": "Mission Beach Polaris | DWHD",
+ "vendor": "DWHD",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/akasha-polaris.jpg?v=1775660108"
+ },
+ {
+ "title": "Edge Wallcovering - Blossom",
+ "vendor": "Edge Wallcovering",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/products/unnamed.jpg?v=1573747790"
+ },
+ {
+ "title": "Big Croco Métal Golden Brown | Elitis",
+ "vendor": "Elitis",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/mural-vibrations-big-croco-metal-fd3224e33b74b3b7acf840edd721.jpg?v=1783791056"
+ },
+ {
+ "title": "Emiliana Parati, Valentin Yudashkin 5 Wallcovering",
+ "vendor": "Emiliana Parati",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/emiliana-parati-valentin-yudashkin-5.jpg?v=1761090561"
+ },
+ {
+ "title": "Angles Geometric - Off White Wallcovering | Erika Wakerly",
+ "vendor": "Erika Wakerly",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/products/Angles010-gold-grey-1.jpg?v=1572310884"
+ },
+ {
+ "title": "Darling - 503 Wallcovering | Fabricut",
+ "vendor": "Fabricut",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/5151803_2x_79e1d63a-e405-4ae1-92a1-7a1261699736.jpg?v=1773710464"
+ },
+ {
+ "title": "Harlequin Cool Blue Wallcovering | FallingStar Studio",
+ "vendor": "FallingStar Studio",
+ "type": "Wallcoverings",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/product_harlequin_coolblue_4f31ade8-2e21-4998-a26a-d06f5a0a2816.jpg?v=1782000474"
+ },
+ {
+ "title": "Purnon Wallcovering | Farrow-ball",
+ "vendor": "Farrow & Ball",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/purnon.jpg?v=1761344027"
+ },
+ {
+ "title": "Asolo Pecan Grasscloth Wallcovering | Fentucci",
+ "vendor": "Fentucci",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/DWNAT-100190.jpg?v=1782322040"
+ },
+ {
+ "title": "Tellaro Flax II | Fentucci Naturals",
+ "vendor": "Fentucci Naturals",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/A-18002.jpg?v=1784772458"
+ },
+ {
+ "title": "Java Slate Blue | Franquemont London",
+ "vendor": "Franquemont London",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Java_SlateBlue_WallpaperSample_Franquemont_948a1aaa-ae30-4eb1-85ab-0e00b2144f5f.webp?v=1771008254"
+ },
+ {
+ "title": "Ming Dynasty by French Market",
+ "vendor": "French Market",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/products/WDB4138-ASM.jpg?v=1572310884"
+ },
+ {
+ "title": "Tall Trees Delft Blue | G P & J Baker",
+ "vendor": "G P & J Baker",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/BW45141_2_7598bef2-55ce-4530-80c2-706adbab8a89.jpg?v=1776795816"
+ },
+ {
+ "title": "Elefantes Agua | Gaston Y Daniela",
+ "vendor": "Gaston Y Daniela",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/GDW5772_007_1ab582ac-1f6b-4e40-b3ed-45e30b5c120c.jpg?v=1776795809"
+ },
+ {
+ "title": "Glambeads Phro Stone Glass Bead Wallcovering",
+ "vendor": "Glambeads by DW",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/IMG_8603_4acf5f3b-54a3-43d0-998c-a9a3c1edc0ce.jpg?v=1702848575"
+ },
+ {
+ "title": "Crystalabra Shards Small - Wallcovering",
+ "vendor": "Glass Beaded",
+ "type": "Wallcovering",
+ "image": "https://cdn.shopify.com/s/files/1/0015/4117/7456/products/ScreenShot2022-03-28at12.16.42PM.png?v=1648497345"
}
],
"traffic": {
diff --git a/public/portal.html b/public/portal.html
index e45bd29..687d1db 100644
--- a/public/portal.html
+++ b/public/portal.html
@@ -33,10 +33,10 @@ body.nav .menu{transform:none}body.nav .scrim{opacity:1;pointer-events:auto}
.slide{position:absolute;inset:0;background-size:cover;background-position:center;opacity:0;transform:scale(1.04);transition:opacity 1.4s ease;will-change:transform,opacity}
.slide.on{opacity:1;animation:kenburns 13s ease-out forwards}
@keyframes kenburns{from{transform:scale(1.04) translate3d(0,0,0)}to{transform:scale(1.13) translate3d(-1.4%,-1.2%,0)}}
-.hero:after{content:'';position:absolute;inset:0;background:linear-gradient(90deg,rgba(14,12,9,.90),rgba(14,12,9,.48) 58%,rgba(14,12,9,.16));z-index:1}
+.hero:after{content:'';position:absolute;inset:0;background:linear-gradient(90deg,rgba(14,12,9,.93),rgba(14,12,9,.72) 60%,rgba(14,12,9,.40));z-index:1}
.hero .in{position:relative;z-index:2;max-width:960px}
.kick{font-size:12px;letter-spacing:.4em;text-transform:uppercase;color:var(--gold);margin-bottom:22px}
-.hero h1{font-family:'Cormorant Garamond',serif;font-weight:400;font-size:clamp(40px,6.6vw,92px);line-height:1.02}.hero h1 span{color:var(--gold)}
+.hero h1{font-family:'Cormorant Garamond',serif;font-weight:400;font-size:clamp(40px,6.6vw,92px);line-height:1.02;text-shadow:0 2px 22px rgba(0,0,0,.72),0 1px 3px rgba(0,0,0,.9)}.hero h1 span{color:var(--gold)}
.hero p{max-width:64ch;margin-top:24px;font-size:18px;color:var(--dim)}
.metrics{display:flex;flex-wrap:wrap;gap:46px;margin-top:46px}
.metrics .v{font-family:'Cormorant Garamond',serif;font-size:40px;color:var(--gold);line-height:1}
@@ -130,7 +130,7 @@ footer{padding:56px clamp(24px,7vw,120px);border-top:1px solid var(--line);color
@media(max-width:640px){.metrics{gap:26px}}
</style></head><body>
<header class="bar">
- <div class="stamp"><span>Data collected Jul 26, 2026, 8:39 PM</span><button id="refbtn" title="Re-run the read-only collector">↻ Refresh data</button></div>
+ <div class="stamp"><span>Data collected Jul 26, 2026, 8:42 PM</span><button id="refbtn" title="Re-run the read-only collector">↻ Refresh data</button></div>
<button class="burger" onclick="document.body.classList.toggle('nav')" aria-label="Menu" aria-expanded="false" aria-controls="portalmenu"><span></span><span></span><span></span></button>
</header>
<div class="scrim" onclick="document.body.classList.remove('nav')"></div>
@@ -145,12 +145,12 @@ footer{padding:56px clamp(24px,7vw,120px);border-top:1px solid var(--line);color
<div class="in">
<div class="kick">Los Angeles · nationwide e-commerce + trade · Confidential strategy brief · prepared for Steve Abrams</div>
<h1 class="disp">Designer <span>Wallcoverings</span></h1>
- <p>Thirty years of trade authority, <b>80,752 live SKUs</b> across <b>174 vendor lines</b>, a <b>281-site</b> discovery fleet, and <b>7 connected social channels</b> — the deepest designer-wallcovering operation online. The opportunity isn't building an audience; it's converting the catalog's dormant depth (a 22,948-product sellable-variant backlog, 20,628 staged drafts) into measured revenue. This brief maps exactly that, from the live data.</p>
+ <p>Thirty years of trade authority, <b>80,773 live SKUs</b> across <b>174 vendor lines</b>, a <b>281-site</b> discovery fleet, and <b>7 connected social channels</b> — the deepest designer-wallcovering operation online. The opportunity isn't building an audience; it's converting the catalog's dormant depth (a 22,948-product sellable-variant backlog, 20,607 staged drafts) into measured revenue. This brief maps exactly that, from the live data.</p>
<div class="metrics">
- <div class="m"><div class="v" data-c="80752">0</div><div class="l">Live SKUs (active)</div></div>
+ <div class="m"><div class="v" data-c="80773">0</div><div class="l">Live SKUs (active)</div></div>
<div class="m"><div class="v" data-c="174">0</div><div class="l">Vendor lines</div></div>
<div class="m"><div class="v" data-c="281">0</div><div class="l">Microsite fleet</div></div>
- <div class="m"><div class="v" data-c="20628">0</div><div class="l">Staged drafts (fuel)</div></div>
+ <div class="m"><div class="v" data-c="20607">0</div><div class="l">Staged drafts (fuel)</div></div>
</div>
</div>
</div>
@@ -158,18 +158,18 @@ footer{padding:56px clamp(24px,7vw,120px);border-top:1px solid var(--line);color
<div class="accbar"><button id="xall">Expand all</button><button id="call">Collapse all</button></div>
<section id="swot"><div class="eyebrow">Strategic Snapshot · SWOT</div><h2 class="disp">The whole board on one screen.</h2><div class="accbody">
- <p class="lead2">Four lenses over the live snapshot — internal <b>Strengths</b> and <b>Weaknesses</b>, external <b>Opportunities</b> and <b>Threats</b> — so the strategy that follows starts from one honest picture. Every number here is from the Jul 26, 2026, 8:39 PM collection.</p>
- <div class="swotgrid"><div class="swotq pos"><h3>Strengths</h3><ul><li>80,752 live SKUs across 174 vendor lines — one of the deepest designer-wallcovering catalogs online</li><li>A 281-site microsite fleet feeding discovery back to the flagship</li><li>7/7 social channels connected through one marketing command center</li><li>Private-label lines with owned margin (Phillipe Romano, Hollywood Wallcoverings, Malibu Wallpaper)</li><li>30+ years of trade relationships; memo-sample program ($4.25) as a proven funnel entry</li><li>Automated activation drip already shipping ~500 products/day, textures-first</li></ul></div><div class="swotq neg"><h3>Weaknesses</h3><ul><li>22,948 active products are sample-only WITHOUT a quote-only designation — browseable but not buyable</li><li>1,440 actives carry zero/null pricing; 333 lack a featured image</li><li>Social reach is broad (80 FB pages, 34 IG accounts) but thin — distribution without engagement depth</li><li>No social→revenue attribution discipline (UTM/coupon per channel) yet</li><li>Flagship UX carries catalog weight — 80k SKUs need stronger guided curation for retail buyers</li></ul></div><div class="swotq pos"><h3>Opportunities</h3><ul><li>Convert the 22,948 sample-only backlog into sellable variants — the single largest dormant-revenue pool in the business</li><li>20,628 staged drafts (2,802 fully stageable today) = months of "New Arrivals" marketing fuel</li><li>AEO/AI-answer citations for wallcovering queries — the flagship already ships an AEO block; extend it fleet-wide</li><li>Sample-order → full-roll conversion funnel instrumentation (order sync to the back office already exists)</li><li>Licensing original design IP (settlement-gated) into marketplaces as a zero-inventory revenue line</li></ul></div><div class="swotq neg"><h3>Threats</h3><ul><li>DTC-native entrants own the "approachable wallpaper" narrative with modern brand voices</li><li>Marketplace aggregators (Amazon, Wayfair, Etsy) commoditize mid-tier patterns</li><li>AI answer engines could disintermediate catalog-depth advantages if citations go to competitors</li><li>Vendor MAP / brand-control tightening limits pricing latitude on marquee lines</li></ul></div></div>
+ <p class="lead2">Four lenses over the live snapshot — internal <b>Strengths</b> and <b>Weaknesses</b>, external <b>Opportunities</b> and <b>Threats</b> — so the strategy that follows starts from one honest picture. Every number here is from the Jul 26, 2026, 8:42 PM collection.</p>
+ <div class="swotgrid"><div class="swotq pos"><h3>Strengths</h3><ul><li>80,773 live SKUs across 174 vendor lines — one of the deepest designer-wallcovering catalogs online</li><li>A 281-site microsite fleet feeding discovery back to the flagship</li><li>7/7 social channels connected through one marketing command center</li><li>Private-label lines with owned margin (Phillipe Romano, Hollywood Wallcoverings, Malibu Wallpaper)</li><li>30+ years of trade relationships; memo-sample program ($4.25) as a proven funnel entry</li><li>Automated activation drip already shipping ~500 products/day, textures-first</li></ul></div><div class="swotq neg"><h3>Weaknesses</h3><ul><li>22,948 active products are sample-only WITHOUT a quote-only designation — browseable but not buyable</li><li>1,440 actives carry zero/null pricing; 333 lack a featured image</li><li>Social reach is broad (80 FB pages, 34 IG accounts) but thin — distribution without engagement depth</li><li>No social→revenue attribution discipline (UTM/coupon per channel) yet</li><li>Flagship UX carries catalog weight — 80k SKUs need stronger guided curation for retail buyers</li></ul></div><div class="swotq pos"><h3>Opportunities</h3><ul><li>Convert the 22,948 sample-only backlog into sellable variants — the single largest dormant-revenue pool in the business</li><li>20,607 staged drafts (2,800 fully stageable today) = months of "New Arrivals" marketing fuel</li><li>AEO/AI-answer citations for wallcovering queries — the flagship already ships an AEO block; extend it fleet-wide</li><li>Sample-order → full-roll conversion funnel instrumentation (order sync to the back office already exists)</li><li>Licensing original design IP (settlement-gated) into marketplaces as a zero-inventory revenue line</li></ul></div><div class="swotq neg"><h3>Threats</h3><ul><li>DTC-native entrants own the "approachable wallpaper" narrative with modern brand voices</li><li>Marketplace aggregators (Amazon, Wayfair, Etsy) commoditize mid-tier patterns</li><li>AI answer engines could disintermediate catalog-depth advantages if citations go to competitors</li><li>Vendor MAP / brand-control tightening limits pricing latitude on marquee lines</li></ul></div></div>
<div class="flagbox" style="margin-top:34px"><div class="i">⚡</div><div><h3 class="disp">The one-sentence thesis</h3><p>DW's moat is <b>catalog depth + trade authority</b>; its constraint is <b>conversion infrastructure</b>. The fastest wins activate what already exists — the sample-only backlog, the staged-draft drip, the connected-but-quiet channels — before building anything new.</p></div></div>
</div></section>
<section id="empire"><div class="eyebrow">01 · The Catalog Empire</div><h2 class="disp">Not a store. A catalog empire.</h2><div class="accbody">
- <p class="lead2">The live mirror shows <b>80,752</b> active products, <b>20,628</b> staged drafts, and <b>80,477</b> archived — a merchandising engine with more inventory in reserve than most competitors have in total. Distribution runs through the flagship plus a <b>281-site</b> microsite fleet.</p>
+ <p class="lead2">The live mirror shows <b>80,773</b> active products, <b>20,607</b> staged drafts, and <b>80,477</b> archived — a merchandising engine with more inventory in reserve than most competitors have in total. Distribution runs through the flagship plus a <b>281-site</b> microsite fleet.</p>
<div class="chartwrap tall"><div class="ct">Top vendor lines by live products</div><canvas id="vendorChart"></canvas></div>
<div class="chartwrap dgt"><div class="ct">Live catalog by product type</div><div class="cwrow"><div class="cwcanvas"><canvas id="typeChart"></canvas></div><ul class="hleg" id="typeChart-legend"></ul></div></div>
- <table><thead><tr><th>#</th><th>Vendor line</th><th>Active products</th></tr></thead><tbody><tr><td class="mo">01</td><td><b>Phillipe Romano</b></td><td>11,420</td></tr><tr><td class="mo">02</td><td><b>Rebel Walls</b></td><td>3,770</td></tr><tr><td class="mo">03</td><td><b>Clarke And Clarke</b></td><td>3,570</td></tr><tr><td class="mo">04</td><td><b>Hollywood Wallcoverings</b></td><td>3,515</td></tr><tr><td class="mo">05</td><td><b>Malibu Wallpaper</b></td><td>3,232</td></tr><tr><td class="mo">06</td><td><b>Thibaut</b></td><td>3,000</td></tr><tr><td class="mo">07</td><td><b>Jeffrey Stevens</b></td><td>2,912</td></tr><tr><td class="mo">08</td><td><b>Brunschwig & Fils</b></td><td>2,761</td></tr><tr><td class="mo">09</td><td><b>Kravet</b></td><td>2,616</td></tr><tr><td class="mo">10</td><td><b>Phillip Jeffries</b></td><td>2,469</td></tr><tr><td class="mo">11</td><td><b>Koroseal</b></td><td>2,455</td></tr><tr><td class="mo">12</td><td><b>Gaston Y Daniela</b></td><td>2,148</td></tr><tr><td class="mo">13</td><td><b>Lee Jofa</b></td><td>2,040</td></tr><tr><td class="mo">14</td><td><b>Los Angeles Fabrics</b></td><td>1,833</td></tr></tbody></table>
+ <table><thead><tr><th>#</th><th>Vendor line</th><th>Active products</th></tr></thead><tbody><tr><td class="mo">01</td><td><b>Phillipe Romano</b></td><td>11,439</td></tr><tr><td class="mo">02</td><td><b>Rebel Walls</b></td><td>3,770</td></tr><tr><td class="mo">03</td><td><b>Clarke And Clarke</b></td><td>3,570</td></tr><tr><td class="mo">04</td><td><b>Hollywood Wallcoverings</b></td><td>3,515</td></tr><tr><td class="mo">05</td><td><b>Malibu Wallpaper</b></td><td>3,232</td></tr><tr><td class="mo">06</td><td><b>Thibaut</b></td><td>3,000</td></tr><tr><td class="mo">07</td><td><b>Jeffrey Stevens</b></td><td>2,912</td></tr><tr><td class="mo">08</td><td><b>Brunschwig & Fils</b></td><td>2,761</td></tr><tr><td class="mo">09</td><td><b>Kravet</b></td><td>2,616</td></tr><tr><td class="mo">10</td><td><b>Phillip Jeffries</b></td><td>2,469</td></tr><tr><td class="mo">11</td><td><b>Koroseal</b></td><td>2,455</td></tr><tr><td class="mo">12</td><td><b>Gaston Y Daniela</b></td><td>2,148</td></tr><tr><td class="mo">13</td><td><b>Lee Jofa</b></td><td>2,040</td></tr><tr><td class="mo">14</td><td><b>Los Angeles Fabrics</b></td><td>1,833</td></tr></tbody></table>
<div class="eyebrow" style="margin-top:52px">Catalog DNA — what the shelves actually hold</div>
- <p class="lead2">Tag analysis across all 80,752 actives. The palette runs <b>neutrals-first</b> — Beige + White alone account for ~44,145 products — a texture-led, trade-calibrated assortment. The merchandising read: DW owns the "quiet luxury" wall; bolder saturated stories (the DTC entrants' lane) are the underweighted shelf.</p>
+ <p class="lead2">Tag analysis across all 80,773 actives. The palette runs <b>neutrals-first</b> — Beige + White alone account for ~44,145 products — a texture-led, trade-calibrated assortment. The merchandising read: DW owns the "quiet luxury" wall; bolder saturated stories (the DTC entrants' lane) are the underweighted shelf.</p>
<div class="duo">
<div class="chartwrap"><div class="ct">Style mix — tag-matched across actives</div><canvas id="styleChart"></canvas></div>
<div class="chartwrap dgt"><div class="ct">Color mix — rendered in the actual hues</div><div class="cwrow"><div class="cwcanvas"><canvas id="colorChart"></canvas></div><ul class="hleg" id="colorChart-legend"></ul></div></div>
@@ -182,11 +182,11 @@ footer{padding:56px clamp(24px,7vw,120px);border-top:1px solid var(--line);color
</div></section>
<section id="integrity"><div class="eyebrow">02 · Catalog Integrity — the 5-Field Read</div><h2 class="disp">Where the catalog leaks revenue.</h2><div class="accbody">
- <p class="lead2">The house rule: every active product needs a sample variant, a sellable variant, complete pricing, a description, and tags — plus a featured image. Against 80,752 actives, the live counts:</p>
+ <p class="lead2">The house rule: every active product needs a sample variant, a sellable variant, complete pricing, a description, and tags — plus a featured image. Against 80,773 actives, the live counts:</p>
<div class="chartwrap"><div class="ct">Actives failing each field (live mirror counts)</div><canvas id="ffChart"></canvas></div>
- <div class="flagbox"><div class="i">◆</div><div><h3 class="disp">The 22,948-product finding</h3><p><b>26,899</b> actives are sample-only. <b>3,951</b> of those are quote-only lines by design. The remaining <b>22,948</b> — a third of the live catalog — can be browsed and sampled but not bought. Every one is paid-for merchandising with the register removed. This is the single largest dormant-revenue pool in the business.</p></div></div>
+ <div class="flagbox"><div class="i">◆</div><div><h3 class="disp">The 22,948-product finding</h3><p><b>26,918</b> actives are sample-only. <b>3,970</b> of those are quote-only lines by design. The remaining <b>22,948</b> — a third of the live catalog — can be browsed and sampled but not bought. Every one is paid-for merchandising with the register removed. This is the single largest dormant-revenue pool in the business.</p></div></div>
<div class="chartwrap"><div class="ct">Sample-only actives — where they sit (top lines)</div><canvas id="soChart"></canvas></div>
- <table><thead><tr><th>Vendor line</th><th>Sample-only actives</th></tr></thead><tbody><tr><td><b>Phillipe Romano</b></td><td>6,074</td></tr><tr><td><b>Phillip Jeffries</b></td><td>2,461</td></tr><tr><td><b>Koroseal</b></td><td>2,454</td></tr><tr><td><b>China Seas</b></td><td>1,776</td></tr><tr><td><b>Coordonné</b></td><td>1,300</td></tr><tr><td><b>Hollywood Wallcoverings</b></td><td>1,089</td></tr><tr><td><b>Designers Guild</b></td><td>840</td></tr><tr><td><b>Osborne & Little</b></td><td>820</td></tr></tbody></table>
+ <table><thead><tr><th>Vendor line</th><th>Sample-only actives</th></tr></thead><tbody><tr><td><b>Phillipe Romano</b></td><td>6,093</td></tr><tr><td><b>Phillip Jeffries</b></td><td>2,461</td></tr><tr><td><b>Koroseal</b></td><td>2,454</td></tr><tr><td><b>China Seas</b></td><td>1,776</td></tr><tr><td><b>Coordonné</b></td><td>1,300</td></tr><tr><td><b>Hollywood Wallcoverings</b></td><td>1,089</td></tr><tr><td><b>Designers Guild</b></td><td>840</td></tr><tr><td><b>Osborne & Little</b></td><td>820</td></tr></tbody></table>
<div class="eyebrow" style="margin-top:52px">The catalog's own to-do list</div>
<p class="lead2">The workflow tags tell the story without an audit: <b>19,658</b> actives are tagged Needs-Width, <b>19,270</b> Needs-Price, <b>16,531</b> Needs-Image. These self-reported queues ARE the integrity sprint's work orders — pre-triaged, machine-readable, waiting.</p>
<div class="chartwrap"><div class="ct">Workflow-tag backlog on active products (live tag counts)</div><canvas id="needsChart"></canvas></div>
@@ -228,14 +228,14 @@ footer{padding:56px clamp(24px,7vw,120px);border-top:1px solid var(--line);color
</div></section>
<section id="timing"><div class="eyebrow">06 · Timing & Cadence</div><h2 class="disp">The drip is live. Point it at revenue.</h2><div class="accbody">
- <p class="lead2">The growth curve, measured: monthly activations ramped from <b>223</b> in Jan to <b>10,563</b> in Jul — a 47× ramp as the activation engine came online. The merchandising calendar below aligns campaigns to the category's natural intent cycle.</p>
+ <p class="lead2">The growth curve, measured: monthly activations ramped from <b>223</b> in Jan to <b>10,584</b> in Jul — a 47× ramp as the activation engine came online. The merchandising calendar below aligns campaigns to the category's natural intent cycle.</p>
<div class="chartwrap"><div class="ct">The ramp — new actives per month, last 7 months (live)</div><canvas id="rampChart"></canvas></div>
<div class="chartwrap"><div class="ct">New active products per week — last 12 weeks (live)</div><canvas id="cadenceChart"></canvas></div>
<table><thead><tr><th>Month</th><th>What the market is doing</th><th>The DW play</th></tr></thead><tbody><tr><td class="mo">Jan</td><td>New-year refresh intent peaks</td><td class="act">Push "one statement wall" entry offers; retarget Q4 samplers</td></tr><tr><td class="mo">Feb</td><td>Design-award season</td><td class="act">Editorial: trend reports off the catalog's own tag data</td></tr><tr><td class="mo">Mar</td><td>Spring project starts</td><td class="act">Trade outreach wave; hospitality spec season begins</td></tr><tr><td class="mo">Apr</td><td>High-intent renovation search</td><td class="act">Paid search on pattern + brand terms; AEO content sprint</td></tr><tr><td class="mo">May</td><td>Peak sample-ordering</td><td class="act">Sample-bundle promos; instrument sample→roll conversion</td></tr><tr><td class="mo">Jun</td><td>Mid-year new-arrivals surge</td><td class="act">The activation drip = daily "new" stories across channels</td></tr><tr><td class="mo">Jul</td><td>Summer install season</td><td class="act">Installer-partner co-marketing; project galleries</td></tr><tr><td class="mo">Aug</td><td>Pre-fall trade buying</td><td class="act">Designer-net program push; hospitality lookbook release</td></tr><tr><td class="mo">Sep</td><td>Fall flagship season</td><td class="act">Concept-direction launch (the new front page ships here)</td></tr><tr><td class="mo">Oct</td><td>Q4 project commits</td><td class="act">Retarget spring samplers; gift-adjacent art-line cross-sell</td></tr><tr><td class="mo">Nov</td><td>Holiday statement walls</td><td class="act">Peel-and-stick line forward; fast-ship messaging</td></tr><tr><td class="mo">Dec</td><td>Planning season</td><td class="act">Year-in-review design content; January intent capture</td></tr></tbody></table>
</div></section>
<section id="audit"><div class="eyebrow">07 · Website Audit</div><h2 class="disp">A strong engine that hides its best features.</h2><div class="accbody">
- <p class="lead2">Analyst audit of the live flagship (Shopify + Boost search): the merchandising infrastructure is genuinely advanced — the gap is guided discovery for the retail buyer facing 80,752 choices.</p>
+ <p class="lead2">Analyst audit of the live flagship (Shopify + Boost search): the merchandising infrastructure is genuinely advanced — the gap is guided discovery for the retail buyer facing 80,773 choices.</p>
<div class="cards2">
<div class="c"><h3>Working well</h3><p class="good">Left-rail collection navigation · shop-by-color wheel with type pills · AEO content blocks on collections · sort + density controls on grids · New Arrivals / Trending smart collections refreshed by daily tag-sync · $4.25 memo-sample funnel on every product.</p></div>
<div class="c"><h3>Gaps</h3><p class="flag">Sample-only products present a dead-end buy box (22,948 products) · zero-price actives surface in feeds (1,440) · 333 actives lack a featured image · curation layers (rooms, moods, designer picks) are thin relative to catalog depth.</p></div>
@@ -296,8 +296,8 @@ footer{padding:56px clamp(24px,7vw,120px);border-top:1px solid var(--line);color
<p class="lead2">Before any new audience is bought, six revenue pools sit inside the existing operation:</p>
<div class="sugg">
<div class="s"><div class="p">Pool 1 · largest</div><h4>The sellable-variant backlog</h4><p>22,948 active products browseable but not buyable. Even a 1% conversion at category AOV is a six-figure annual pool. Remediation is data work, not marketing spend.</p></div>
- <div class="s"><div class="p">Pool 2 · compounding</div><h4>Sample → roll funnel</h4><p>The $4.25 memo program is the top of the funnel. <b>78,458</b> active products can be memo-sampled, but only <b>65.9%</b> have a roll a customer can then buy — leaving <b>22,790</b> recoverable dead-ends. Quantified below.</p></div>
- <div class="s"><div class="p">Pool 3 · scheduled</div><h4>The staged-draft drip</h4><p>20,628 drafts activating ~500/day = a permanent "new arrivals" marketing engine. Sync email + social to the drip and every day ships its own campaign.</p></div>
+ <div class="s"><div class="p">Pool 2 · compounding</div><h4>Sample → roll funnel</h4><p>The $4.25 memo program is the top of the funnel. <b>78,479</b> active products can be memo-sampled, but only <b>65.9%</b> have a roll a customer can then buy — leaving <b>22,790</b> recoverable dead-ends. Quantified below.</p></div>
+ <div class="s"><div class="p">Pool 3 · scheduled</div><h4>The staged-draft drip</h4><p>20,607 drafts activating ~500/day = a permanent "new arrivals" marketing engine. Sync email + social to the drip and every day ships its own campaign.</p></div>
<div class="s"><div class="p">Pool 4 · zero-inventory</div><h4>Original design licensing</h4><p>Settlement-gated original pattern IP licensed to print-on-demand marketplaces — revenue without inventory, already piloted in the wider operation.</p></div>
<div class="s"><div class="p">Pool 5 · trade</div><h4>Designer-net portal</h4><p>Formalize trade pricing behind a designer login. Trade buyers are the highest-LTV segment and currently buy through the retail flow.</p></div>
<div class="s"><div class="p">Pool 6 · projects</div><h4>Hospitality / contract desk</h4><p>Type II contract lines already in catalog. A spec-sheet + quote desk turns one hotel corridor into 400 rolls.</p></div>
@@ -306,12 +306,12 @@ footer{padding:56px clamp(24px,7vw,120px);border-top:1px solid var(--line);color
<h3 class="disp" style="margin-top:38px">Pool 2, quantified — the sample → roll funnel</h3>
<p class="lead2">The $4.25 memo sample is a daily purchase-intent signal. The question is whether that intent has anywhere to convert. Measured from the live catalog mirror:</p>
<div class="kpis">
- <div class="kpi"><div class="kv">78,458</div><div class="kl">Products a customer can memo-sample</div></div>
- <div class="kpi"><div class="kv">65.9%</div><div class="kl">…that also have a buyable roll (51,717)</div></div>
+ <div class="kpi"><div class="kv">78,479</div><div class="kl">Products a customer can memo-sample</div></div>
+ <div class="kpi"><div class="kv">65.9%</div><div class="kl">…that also have a buyable roll (51,719)</div></div>
<div class="kpi"><div class="kv">22,790</div><div class="kl">Recoverable dead-ends (sampled intent, no roll)</div></div>
- <div class="kpi"><div class="kv">3,951</div><div class="kl">Quote-only by design (excluded — not a leak)</div></div>
+ <div class="kpi"><div class="kv">3,970</div><div class="kl">Quote-only by design (excluded — not a leak)</div></div>
</div>
- <p class="lead2">Two-thirds of the sampleable catalog converts cleanly; the remaining <b>26,741</b> products a customer can pay $4.25 to sample but cannot then buy. Of those, <b>3,951</b> are intentionally quote-only, leaving a <b>22,790</b>-product recoverable pool — concentrated in a handful of lines. Fixing the roll variant on a line a customer already sampled is data work, not ad spend.</p>
+ <p class="lead2">Two-thirds of the sampleable catalog converts cleanly; the remaining <b>26,760</b> products a customer can pay $4.25 to sample but cannot then buy. Of those, <b>3,970</b> are intentionally quote-only, leaving a <b>22,790</b>-product recoverable pool — concentrated in a handful of lines. Fixing the roll variant on a line a customer already sampled is data work, not ad spend.</p>
<div class="chartwrap"><div class="ct">Sample → roll by line (top 8 by recoverable backlog): gold = memo converts to a buyable roll · rose = memo hits a dead end</div><canvas id="srChart"></canvas></div>
<div class="flagbox"><div class="i">◆</div><div><h3 class="disp">Provenance — tiered honestly</h3><p><b>Tier A (measured, catalog structure):</b> the funnel counts above come straight from the read-only <code>dw_unified</code> mirror — every ACTIVE product's memo-sample and roll variant flags. Solid.<br><b>Tier B (proxy, labeled):</b> "recoverable backlog" is <i>sampleable-but-not-buyable minus the 'quotes'-tagged lines</i>. That tag under-captures reality — contract lines like Koroseal and Phillip Jeffries are quote-only in practice but untagged — so <b>22,790 is an upper bound</b>; the truly recoverable share is a subset, weighted toward the merchant private-label and residential lines.<br><b>Tier C (absent — the recommendation):</b> real memo-order-vs-roll-order <i>behavioral</i> conversion is <b>not in this mirror</b>. It is a catalog mirror — no <code>shopify_orders</code> table; <code>mp_orders</code> is 6 seed rows and <code>digital_sample_orders</code> only 25 thin digital-only rows. So the true conversion <i>rate</i> can't be computed here — <b>instrumenting the memo→roll path is itself the first move</b> (Roadmap, Weeks 3–6).</p></div></div>
@@ -319,11 +319,11 @@ footer{padding:56px clamp(24px,7vw,120px);border-top:1px solid var(--line);color
</div></section>
<section id="desk"><div class="eyebrow">12 · Live Commerce Desk</div><h2 class="disp">The operation, on one screen.</h2><div class="accbody">
- <p class="lead2">Live KPIs from the Jul 26, 2026, 8:39 PM snapshot — the numbers a weekly growth review should open with. Hit ↻ Refresh (top right) to re-collect on demand.</p>
+ <p class="lead2">Live KPIs from the Jul 26, 2026, 8:42 PM snapshot — the numbers a weekly growth review should open with. Hit ↻ Refresh (top right) to re-collect on demand.</p>
<div class="kpis">
- <div class="kpi"><div class="kv">80,752</div><div class="kl">Active products</div></div>
- <div class="kpi"><div class="kv">20,628</div><div class="kl">Staged drafts</div></div>
- <div class="kpi"><div class="kv">2,802</div><div class="kl">Stageable today (variant + image)</div></div>
+ <div class="kpi"><div class="kv">80,773</div><div class="kl">Active products</div></div>
+ <div class="kpi"><div class="kv">20,607</div><div class="kl">Staged drafts</div></div>
+ <div class="kpi"><div class="kv">2,800</div><div class="kl">Stageable today (variant + image)</div></div>
<div class="kpi"><div class="kv">22,948</div><div class="kl">Sample-only backlog (non-quote)</div></div>
<div class="kpi"><div class="kv">1,440</div><div class="kl">Zero-price actives</div></div>
<div class="kpi"><div class="kv">333</div><div class="kl">Image-less actives</div></div>
@@ -335,7 +335,7 @@ footer{padding:56px clamp(24px,7vw,120px);border-top:1px solid var(--line);color
<section id="roadmap"><div class="eyebrow">13 · 90-Day Roadmap</div><h2 class="disp">What to do, in order.</h2><div class="accbody">
<ul class="road">
- <li><div class="w">Weeks 1–2</div><div class="d"><b>Integrity sprint:</b> triage the 22,948 sample-only backlog by vendor (top 8 lines = 16,814 products); fix zero-price and image-less actives. Wire per-channel UTM + coupon attribution. Pick a concept direction from Section 09.<br><span style="color:var(--gold);font-size:14px">KPI · 2,500+ sellable variants added · zero-price actives < 500 · UTM live on all 7 channels · concept direction chosen (Week-2 decision gate)</span></div></li>
+ <li><div class="w">Weeks 1–2</div><div class="d"><b>Integrity sprint:</b> triage the 22,948 sample-only backlog by vendor (top 8 lines = 16,833 products); fix zero-price and image-less actives. Wire per-channel UTM + coupon attribution. Pick a concept direction from Section 09.<br><span style="color:var(--gold);font-size:14px">KPI · 2,500+ sellable variants added · zero-price actives < 500 · UTM live on all 7 channels · concept direction chosen (Week-2 decision gate)</span></div></li>
<li><div class="w">Weeks 3–6</div><div class="d"><b>Convert intent:</b> ship the sampled-but-didn't-buy email sequence off the memo funnel. Sync daily social posting to the activation drip. Start the designer-net trade portal build.<br><span style="color:var(--gold);font-size:14px">KPI · first attributed sample→roll conversion · sequence live with ≥25% open rate · 7 drip-synced posts/week shipping · re-collect this brief and re-baseline (↻)</span></div></li>
<li><div class="w">Weeks 6–10</div><div class="d"><b>Ship the face:</b> launch the chosen flagship direction (guided discovery: rooms, moods, designer picks). Extend AEO blocks fleet-wide. Sign 3 unlikely-partner deals (one installer network, one stager program, one hospitality designer).<br><span style="color:var(--gold);font-size:14px">KPI · new front page live · AEO blocks on 100+ fleet sites · 3 signed partner agreements · backlog under 15,000</span></div></li>
<li><div class="w">Weeks 10–13</div><div class="d"><b>Measure & double down:</b> channel-level revenue review off the new attribution; scale the winner. Open the contract/hospitality quote desk. Publish the first licensing-line results.<br><span style="color:var(--gold);font-size:14px">KPI · every channel shows attributed revenue (or is cut) · first contract quote issued · Week-13 review: backlog, conversion rate, channel ROI vs this brief's baseline</span></div></li>
@@ -343,13 +343,13 @@ footer{padding:56px clamp(24px,7vw,120px);border-top:1px solid var(--line);color
</div></section>
<section id="sources"><div class="eyebrow">14 · Sources & Methodology</div><h2 class="disp">Where every number comes from.</h2><div class="accbody">
- <p class="lead2">Snapshot collected <b>Jul 26, 2026, 8:39 PM</b> by a read-only collector. Live rows are measured; analyst rows are authored judgment; anything illustrative says so.</p>
+ <p class="lead2">Snapshot collected <b>Jul 26, 2026, 8:42 PM</b> by a read-only collector. Live rows are measured; analyst rows are authored judgment; anything illustrative says so.</p>
<div class="srclegend"><span class="srcb r">Live snapshot</span><span class="srcb o">Observed live</span><span class="srcb a">Analyst view</span><span class="srcb d">Computed</span><span class="srcb e">Illustrative</span></div>
- <table><thead><tr><th>Section</th><th>Where it comes from</th><th>How it's produced</th><th>Provenance</th></tr></thead><tbody><tr><td><b>Catalog KPIs — statuses, vendors, types, integrity, cadence</b></td><td>The dw_unified local mirror (READ-ONLY psql over the /tmp socket)</td><td>Collected by <code>scripts/collect-dw.mjs</code> at <b>Jul 26, 2026, 8:39 PM</b>; every number on this page renders from that snapshot</td><td class="srccell"><span class="srcb r">Live snapshot</span></td></tr><tr><td><b>5-field / sample-only split</b></td><td>Mirror rollup columns (has_sample_variant, has_product_variant, has_description, image_url) + the quotes tag</td><td>Direct SQL counts; quote-only lines (by-design sample-only) separated from true backlog</td><td class="srccell"><span class="srcb r">Live snapshot</span></td></tr><tr><td><b>Social channel status</b></td><td>The DW marketing command center API (marketing.designerwallcoverings.com)</td><td>Authenticated status read at collection time — connected flags + account counts per platform</td><td class="srccell"><span class="srcb r">Live snapshot</span></td></tr><tr><td><b>Microsite fleet</b></td><td>The fleet aggregator directory API (all.designerwallcoverings.com)</td><td>281 sites enumerated at collection time</td><td class="srccell"><span class="srcb r">Live snapshot</span></td></tr><tr><td><b>Competitor watch-list</b></td><td>The connie_competitors table (the DW competitor-scan registry)</td><td>Rendered verbatim: domain, watch status, products found by prior scans</td><td class="srccell"><span class="srcb r">Live snapshot</span></td></tr><tr><td><b>Competitor paid-ads table</b></td><td>A $0 homepage pixel scan of each tracked domain (Google/Meta/TikTok/Pinterest/Bing tag signatures)</td><td>Measured at seed time by <code>scripts/seed-buckets.mjs</code>; unreachable homepages say so rather than guessing</td><td class="srccell"><span class="srcb o">Observed live</span></td></tr><tr><td><b>Competitor scoring chart + map pins</b></td><td>Analyst assessment over public sites; HQ geo compiled from public records</td><td>Authored consulting view — NOT scraped metrics; the map is oriented, not surveyed</td><td class="srccell"><span class="srcb a">Analyst view</span></td></tr><tr><td><b>Price-band chart</b></td><td>products whose minimum variant exceeds the $4.25 memo sample — the priced subset of the mirror (~3.8k); most actives resolve min-variant to the sample, and full variant-level pricing lives Shopify-side</td><td>Partial-basis chart, labeled as such — full variant pricing lives Shopify-side</td><td class="srccell"><span class="srcb d">Computed</span></td></tr><tr><td><b>Website & social audits, partners, revenue plays, roadmap</b></td><td>Analyst strategy grounded in the operating knowledge of the DW stack</td><td>Consulting recommendations — models and plays, not measurements</td><td class="srccell"><span class="srcb a">Analyst view</span></td></tr><tr><td><b>Catalog DNA — style, color & workflow-tag charts</b></td><td>Tag-match SQL over all actives (the same tag buckets the storefront sort uses)</td><td>Live counts per style/color/Needs-* tag; the color doughnut renders in representative hues of the tag names</td><td class="srccell"><span class="srcb r">Live snapshot</span></td></tr><tr><td><b>Monthly activation ramp</b></td><td>created_at_shopify over the last 7 calendar months, live mirror</td><td>Direct SQL; the ramp multiplier in the copy is computed from the same series</td><td class="srccell"><span class="srcb r">Live snapshot</span></td></tr><tr><td><b>Product mosaic + concept-grid imagery</b></td><td>The store's own CDN (one current ACTIVE product per vendor line, forbidden-vendor-filtered)</td><td>Already customer-facing on the live store; hotlinked at thumbnail width</td><td class="srccell"><span class="srcb r">Live snapshot</span></td></tr><tr><td><b>Traffic & Search Reality</b></td><td>Google Search Console via the cached DW SEO report (age-labeled in the section footer)</td><td>Totals, branded split, striking-distance and page tables rendered verbatim; the decline copy is computed from the same monthly series</td><td class="srccell"><span class="srcb o">Observed live</span></td></tr><tr><td><b>Hero imagery</b></td><td>Unsplash editorial stock (luxury materials, per the luxe-only imagery rule)</td><td>Hotlinked, decorative only — carries no data meaning</td><td class="srccell"><span class="srcb e">Illustrative</span></td></tr></tbody></table>
+ <table><thead><tr><th>Section</th><th>Where it comes from</th><th>How it's produced</th><th>Provenance</th></tr></thead><tbody><tr><td><b>Catalog KPIs — statuses, vendors, types, integrity, cadence</b></td><td>The dw_unified local mirror (READ-ONLY psql over the /tmp socket)</td><td>Collected by <code>scripts/collect-dw.mjs</code> at <b>Jul 26, 2026, 8:42 PM</b>; every number on this page renders from that snapshot</td><td class="srccell"><span class="srcb r">Live snapshot</span></td></tr><tr><td><b>5-field / sample-only split</b></td><td>Mirror rollup columns (has_sample_variant, has_product_variant, has_description, image_url) + the quotes tag</td><td>Direct SQL counts; quote-only lines (by-design sample-only) separated from true backlog</td><td class="srccell"><span class="srcb r">Live snapshot</span></td></tr><tr><td><b>Social channel status</b></td><td>The DW marketing command center API (marketing.designerwallcoverings.com)</td><td>Authenticated status read at collection time — connected flags + account counts per platform</td><td class="srccell"><span class="srcb r">Live snapshot</span></td></tr><tr><td><b>Microsite fleet</b></td><td>The fleet aggregator directory API (all.designerwallcoverings.com)</td><td>281 sites enumerated at collection time</td><td class="srccell"><span class="srcb r">Live snapshot</span></td></tr><tr><td><b>Competitor watch-list</b></td><td>The connie_competitors table (the DW competitor-scan registry)</td><td>Rendered verbatim: domain, watch status, products found by prior scans</td><td class="srccell"><span class="srcb r">Live snapshot</span></td></tr><tr><td><b>Competitor paid-ads table</b></td><td>A $0 homepage pixel scan of each tracked domain (Google/Meta/TikTok/Pinterest/Bing tag signatures)</td><td>Measured at seed time by <code>scripts/seed-buckets.mjs</code>; unreachable homepages say so rather than guessing</td><td class="srccell"><span class="srcb o">Observed live</span></td></tr><tr><td><b>Competitor scoring chart + map pins</b></td><td>Analyst assessment over public sites; HQ geo compiled from public records</td><td>Authored consulting view — NOT scraped metrics; the map is oriented, not surveyed</td><td class="srccell"><span class="srcb a">Analyst view</span></td></tr><tr><td><b>Price-band chart</b></td><td>products whose minimum variant exceeds the $4.25 memo sample — the priced subset of the mirror (~3.8k); most actives resolve min-variant to the sample, and full variant-level pricing lives Shopify-side</td><td>Partial-basis chart, labeled as such — full variant pricing lives Shopify-side</td><td class="srccell"><span class="srcb d">Computed</span></td></tr><tr><td><b>Website & social audits, partners, revenue plays, roadmap</b></td><td>Analyst strategy grounded in the operating knowledge of the DW stack</td><td>Consulting recommendations — models and plays, not measurements</td><td class="srccell"><span class="srcb a">Analyst view</span></td></tr><tr><td><b>Catalog DNA — style, color & workflow-tag charts</b></td><td>Tag-match SQL over all actives (the same tag buckets the storefront sort uses)</td><td>Live counts per style/color/Needs-* tag; the color doughnut renders in representative hues of the tag names</td><td class="srccell"><span class="srcb r">Live snapshot</span></td></tr><tr><td><b>Monthly activation ramp</b></td><td>created_at_shopify over the last 7 calendar months, live mirror</td><td>Direct SQL; the ramp multiplier in the copy is computed from the same series</td><td class="srccell"><span class="srcb r">Live snapshot</span></td></tr><tr><td><b>Product mosaic + concept-grid imagery</b></td><td>The store's own CDN (one current ACTIVE product per vendor line, forbidden-vendor-filtered)</td><td>Already customer-facing on the live store; hotlinked at thumbnail width</td><td class="srccell"><span class="srcb r">Live snapshot</span></td></tr><tr><td><b>Traffic & Search Reality</b></td><td>Google Search Console via the cached DW SEO report (age-labeled in the section footer)</td><td>Totals, branded split, striking-distance and page tables rendered verbatim; the decline copy is computed from the same monthly series</td><td class="srccell"><span class="srcb o">Observed live</span></td></tr><tr><td><b>Hero imagery</b></td><td>Unsplash editorial stock (luxury materials, per the luxe-only imagery rule)</td><td>Hotlinked, decorative only — carries no data meaning</td><td class="srccell"><span class="srcb e">Illustrative</span></td></tr></tbody></table>
<div class="srcnote"><div class="i">⚙</div><div><h4>How this document is built</h4><p>Generated, not hand-typed. A read-only collector (<code>scripts/collect-dw.mjs</code>) snapshots the DW systems into <code>data/dw-analysis.json</code>; the build (<code>build.mjs</code>) renders that snapshot into this page. The ↻ Refresh button re-runs collector + build on demand. Nothing writes to any DW production system.</p></div></div>
</div></section>
-<footer><span>Designer Wallcoverings · Growth Strategy Brief</span><span>Data as of Jul 26, 2026, 8:39 PM</span><span>Confidential — for discussion</span></footer>
+<footer><span>Designer Wallcoverings · Growth Strategy Brief</span><span>Data as of Jul 26, 2026, 8:42 PM</span><span>Confidential — for discussion</span></footer>
<script>
(function(){var s=document.querySelectorAll('.hero .slide'),i=0;if(s.length<2)return;setInterval(function(){s[i].classList.remove('on');i=(i+1)%s.length;s[i].classList.add('on');},5200);})();
@@ -376,7 +376,7 @@ function initCharts(){if(charted||!window.Chart)return;charted=true;
var RM=window.matchMedia&&window.matchMedia('(prefers-reduced-motion:reduce)').matches;
Chart.defaults.animation=RM?false:{duration:1150,easing:'easeInOutQuart'};
if(!RM){Chart.defaults.animations={y:{from:function(c){return c.chart.scales.y?c.chart.scales.y.getPixelForValue(0):0;}}};}
- var D={"cadence":{"labels":["05-11","05-25","06-01","06-08","06-15","06-22","06-29","07-06","07-13","07-20"],"added":[490,3,492,924,1993,1510,1854,4269,1499,3588]},"vendors":{"labels":["Phillipe Romano","Rebel Walls","Clarke And Clarke","Hollywood Wallcoverings","Malibu Wallpaper","Thibaut","Jeffrey Stevens","Brunschwig & Fils","Kravet","Phillip Jeffries"],"counts":[11420,3770,3570,3515,3232,3000,2912,2761,2616,2469]},"types":{"labels":["Wallcovering","Fabric","Commercial Fabric","Mural","Wallcoverings","Memo Sample"],"counts":[58499,16209,1797,1305,453,451]},"integrity":{"labels":["Missing sellable variant","Missing sample variant","Zero / null price","Missing image","Missing description"],"counts":[26899,2294,1440,333,168]},"bands":{"labels":["Under $50","$50–150","$150–300","$300–600","$600+"],"counts":[2118,699,435,443,129]},"channels":{"labels":["Facebook Pages","Instagram","TikTok","YouTube","Bluesky","Threads","LinkedIn"],"accounts":[80,34,1,1,1,1,1]},"sampleOnlyVendors":{"labels":["Phillipe Romano","Phillip Jeffries","Koroseal","China Seas","Coordonné","Hollywood Wallcoverings","Designers Guild","Osborne & Little"],"counts":[6074,2461,2454,1776,1300,1089,840,820]},"sampleRoll":{"labels":["Phillipe Romano","Phillip Jeffries","Koroseal","China Seas","Coordonné","Hollywood Wallcoverings","Designers Guild","Osborne & Little"],"converted":[4064,8,1,0,131,2426,0,111],"leak":[3521,2461,2368,1776,1300,842,839,820]},"comp":{"labels":["Designer Wallcoverings","DecoratorsBest","Burke Decor","Mahones","Finest Wallpaper","Steve's B&W"],"catalog":[96,62,48,55,40,45],"digital":[58,82,78,60,42,55]},"monthly":{"labels":["Jan","Feb","Mar","Apr","May","Jun","Jul"],"added":[223,1363,4578,3416,493,5547,10563]},"needs":{"labels":["Needs Price","Needs Image","Needs Width","Needs Description"],"counts":[19270,16531,19658,27]},"styles":{"labels":["Contemporary","Textured","Traditional","Geometric","Floral","Grasscloth","Stripe","Mural","Metallic","Damask"],"counts":[32586,29302,22721,11746,10292,9848,9153,4796,3211,1925]},"colors":{"labels":["Beige","White","Gray","Blue","Green","Brown","Black","Gold","Pink","Red"],"counts":[22084,22061,12163,8553,7750,5189,4885,4326,3457,2945],"hex":["#d9c9a8","#f2efe8","#9a9a99","#5a7fa8","#6b8f6d","#8a6a4c","#2b2b2b","#c9a24b","#d3a0a6","#a84a44"]}};
+ var D={"cadence":{"labels":["05-11","05-25","06-01","06-08","06-15","06-22","06-29","07-06","07-13","07-20"],"added":[490,3,492,924,1993,1510,1854,4269,1499,3590]},"vendors":{"labels":["Phillipe Romano","Rebel Walls","Clarke And Clarke","Hollywood Wallcoverings","Malibu Wallpaper","Thibaut","Jeffrey Stevens","Brunschwig & Fils","Kravet","Phillip Jeffries"],"counts":[11439,3770,3570,3515,3232,3000,2912,2761,2616,2469]},"types":{"labels":["Wallcovering","Fabric","Commercial Fabric","Mural","Wallcoverings","Memo Sample"],"counts":[58520,16209,1797,1305,453,451]},"integrity":{"labels":["Missing sellable variant","Missing sample variant","Zero / null price","Missing image","Missing description"],"counts":[26918,2294,1440,333,168]},"bands":{"labels":["Under $50","$50–150","$150–300","$300–600","$600+"],"counts":[2118,699,435,443,129]},"channels":{"labels":["Facebook Pages","Instagram","TikTok","YouTube","Bluesky","Threads","LinkedIn"],"accounts":[80,34,1,1,1,1,1]},"sampleOnlyVendors":{"labels":["Phillipe Romano","Phillip Jeffries","Koroseal","China Seas","Coordonné","Hollywood Wallcoverings","Designers Guild","Osborne & Little"],"counts":[6093,2461,2454,1776,1300,1089,840,820]},"sampleRoll":{"labels":["Phillipe Romano","Phillip Jeffries","Koroseal","China Seas","Coordonné","Hollywood Wallcoverings","Designers Guild","Osborne & Little"],"converted":[4064,8,1,0,131,2426,0,111],"leak":[3521,2461,2368,1776,1300,842,839,820]},"comp":{"labels":["Designer Wallcoverings","DecoratorsBest","Burke Decor","Mahones","Finest Wallpaper","Steve's B&W"],"catalog":[96,62,48,55,40,45],"digital":[58,82,78,60,42,55]},"monthly":{"labels":["Jan","Feb","Mar","Apr","May","Jun","Jul"],"added":[223,1363,4578,3416,493,5547,10584]},"needs":{"labels":["Needs Price","Needs Image","Needs Width","Needs Description"],"counts":[19270,16531,19658,27]},"styles":{"labels":["Contemporary","Textured","Traditional","Geometric","Floral","Grasscloth","Stripe","Mural","Metallic","Damask"],"counts":[32586,29302,22723,11746,10293,9848,9153,4798,3211,1925]},"colors":{"labels":["Beige","White","Gray","Blue","Green","Brown","Black","Gold","Pink","Red"],"counts":[22084,22061,12163,8553,7750,5189,4885,4326,3457,2945],"hex":["#d9c9a8","#f2efe8","#9a9a99","#5a7fa8","#6b8f6d","#8a6a4c","#2b2b2b","#c9a24b","#d3a0a6","#a84a44"]}};
var TRD={"labels":["Jan","Feb","Mar","Apr","May","Jun","Jul"],"clicks":[4790,8903,7318,5477,4908,4249,2335]};
function mk(id,cfg){var el=document.getElementById(id);if(el)new Chart(el,cfg);}
// Custom HTML legend for the doughnuts — thin 2x16px line markers instead of box swatches, click-to-toggle
@@ -418,7 +418,7 @@ function initCharts(){if(charted||!window.Chart)return;charted=true;
}
var mapped=false;
function initMap(){if(mapped||!window.L||!document.getElementById('compmap'))return;mapped=true;
- var pts=[{"name":"Designer Wallcoverings — Los Angeles","lat":34.076,"lng":-118.377,"you":true,"note":"HQ · showroom · 80,752 live SKUs"},{"name":"DecoratorsBest","lat":40.752,"lng":-73.993,"note":"New York, NY — designer-brand e-commerce"},{"name":"Burke Decor","lat":41.099,"lng":-80.649,"note":"Youngstown, OH — home decor + wallpaper"},{"name":"Mahone's Wallpaper Shop","lat":37.089,"lng":-76.473,"note":"Newport News, VA — wallpaper specialist"},{"name":"Finest Wallpaper","lat":43.09,"lng":-79.08,"note":"Ontario, Canada — designer lines, US/CA pricing"},{"name":"Steve's Blinds & Wallpaper","lat":42.58,"lng":-83.03,"note":"Sterling Heights, MI — discount volume"}];
+ var pts=[{"name":"Designer Wallcoverings — Los Angeles","lat":34.076,"lng":-118.377,"you":true,"note":"HQ · showroom · 80,773 live SKUs"},{"name":"DecoratorsBest","lat":40.752,"lng":-73.993,"note":"New York, NY — designer-brand e-commerce"},{"name":"Burke Decor","lat":41.099,"lng":-80.649,"note":"Youngstown, OH — home decor + wallpaper"},{"name":"Mahone's Wallpaper Shop","lat":37.089,"lng":-76.473,"note":"Newport News, VA — wallpaper specialist"},{"name":"Finest Wallpaper","lat":43.09,"lng":-79.08,"note":"Ontario, Canada — designer lines, US/CA pricing"},{"name":"Steve's Blinds & Wallpaper","lat":42.58,"lng":-83.03,"note":"Sterling Heights, MI — discount volume"}];
var m=L.map('compmap',{scrollWheelZoom:false}).setView([38.5,-96],4);
L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png',{attribution:'© OpenStreetMap © CARTO',maxZoom:18}).addTo(m);
pts.forEach(function(p){var mk=L.circleMarker([p.lat,p.lng],{radius:p.you?10:7,color:p.you?'#c9a24b':'#78aaff',fillColor:p.you?'#c9a24b':'#78aaff',fillOpacity:.85,weight:1});
diff --git a/public/versions/atelier.html b/public/versions/atelier.html
index 411c87c..46e8e9c 100644
--- a/public/versions/atelier.html
+++ b/public/versions/atelier.html
@@ -71,47 +71,41 @@ footer .in{max-width:1240px;margin:0 auto;padding:36px 22px;display:flex;justify
<div class="sh"><h2>Curated This Week</h2>
<div class="controls">
<label for="sortsel">Sort</label>
- <span class="selwrap"><select id="sortsel"><option value="newest">Newest</option><option value="color">Color</option><option value="title">Title A→Z</option><option value="tier">Collection tier</option></select></span>
+ <span class="selwrap"><select id="sortsel"><option value="newest">Newest</option><option value="title">Title A→Z</option><option value="vendor">Vendor A→Z</option><option value="type">Type</option></select></span>
<label for="dens">Density</label>
<input type="range" id="dens" min="2" max="6" step="1" value="4">
</div>
</div>
- <div class="grid" id="grid"><article class="gcard" data-title="Willow Pearl - Cream" data-hue="28" data-tier="0">
+ <div class="grid" id="grid"><article class="gcard" data-title="Willow Pearl - Cream" data-vendor="1838 Wallcoverings" data-type="Wallcovering">
<div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/2008-148-04-Willow-Pearl-scaled_27cc3134-1291-4605-85ca-d870cd905b85.jpg?v=1773305872&width=540" loading="lazy" alt="Willow Pearl - Cream"></div>
- <h4>Willow Pearl - Cream</h4><div class="gmeta"><span>1838 Wallcoverings</span><span class="tier">casual</span></div>
- </article><article class="gcard" data-title="Designdrop - Colourful" data-hue="152" data-tier="1">
+ <h4>Willow Pearl - Cream</h4><div class="gmeta"><span>1838 Wallcoverings</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Designdrop - Colourful" data-vendor="A.S. Création" data-type="Wallcovering">
<div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/66e3a5f29fd1fd50090f5d5fce9b4ddc.jpg?v=1773629119&width=540" loading="lazy" alt="Designdrop - Colourful"></div>
- <h4>Designdrop - Colourful</h4><div class="gmeta"><span>A.S. Création</span><span class="tier">signature</span></div>
- </article><article class="gcard" data-title="Brown on Tint" data-hue="208" data-tier="2">
+ <h4>Designdrop - Colourful</h4><div class="gmeta"><span>A.S. Création</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Brown on Tint" data-vendor="Alan Campbell" data-type="Fabric">
<div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Criss-Cross-Brown-on-Tint-AC403-16_015244-sm-thumb.jpg?v=1783597230&width=540" loading="lazy" alt="Brown on Tint"></div>
- <h4>Brown on Tint</h4><div class="gmeta"><span>Alan Campbell</span><span class="tier">reserve</span></div>
- </article><article class="gcard" data-title="Riviera" data-hue="12" data-tier="0">
+ <h4>Brown on Tint</h4><div class="gmeta"><span>Alan Campbell</span><span class="tier">Fabric</span></div>
+ </article><article class="gcard" data-title="Riviera" data-vendor="Ananbo" data-type="Wallcovering">
<div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/riviera.webp?v=1761541180&width=540" loading="lazy" alt="Riviera"></div>
- <h4>Riviera</h4><div class="gmeta"><span>Ananbo</span><span class="tier">casual</span></div>
- </article><article class="gcard" data-title="Ark - Parchment - beige" data-hue="262" data-tier="1">
+ <h4>Riviera</h4><div class="gmeta"><span>Ananbo</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Ark - Parchment - beige" data-vendor="Andrew Martin" data-type="Wallcovering">
<div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/AMW10001_1611_11959302-5997-4bcd-9a99-c54a9b0919e8.jpg?v=1775761440&width=540" loading="lazy" alt="Ark - Parchment - beige"></div>
- <h4>Ark - Parchment - beige</h4><div class="gmeta"><span>Andrew Martin</span><span class="tier">signature</span></div>
- </article><article class="gcard" data-title="Gibson, Navy" data-hue="88" data-tier="2">
+ <h4>Ark - Parchment - beige</h4><div class="gmeta"><span>Andrew Martin</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Gibson, Navy" data-vendor="Anna French" data-type="Wallcovering">
<div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/AT78793_4d4910ee-a9f9-4534-ae47-bed6b7d9942d.jpg?v=1782985244&width=540" loading="lazy" alt="Gibson, Navy"></div>
- <h4>Gibson, Navy</h4><div class="gmeta"><span>Anna French</span><span class="tier">reserve</span></div>
- </article><article class="gcard" data-title="Anthology - Stria Stone/Amber/Plum" data-hue="340" data-tier="0">
+ <h4>Gibson, Navy</h4><div class="gmeta"><span>Anna French</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Anthology - Stria Stone/Amber/Plum" data-vendor="Anthology" data-type="Wallcovering">
<div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/ESHE131796.jpg?v=1784735551&width=540" loading="lazy" alt="Anthology - Stria Stone/Amber/Plum"></div>
- <h4>Anthology - Stria Stone/Amber/Plum</h4><div class="gmeta"><span>Anthology</span><span class="tier">casual</span></div>
- </article><article class="gcard" data-title="Caswell Sage Green" data-hue="190" data-tier="1">
+ <h4>Anthology - Stria Stone/Amber/Plum</h4><div class="gmeta"><span>Anthology</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Caswell Sage Green" data-vendor="Apartment Wallpaper" data-type="Wallcovering">
<div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/PSW1213RL.jpg?v=1740775136&width=540" loading="lazy" alt="Caswell Sage Green"></div>
- <h4>Caswell Sage Green</h4><div class="gmeta"><span>Apartment Wallpaper</span><span class="tier">signature</span></div>
- </article><article class="gcard" data-title="Atlantic Cay - Verdant" data-hue="46" data-tier="2">
+ <h4>Caswell Sage Green</h4><div class="gmeta"><span>Apartment Wallpaper</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Atlantic Cay - Verdant" data-vendor="Architectural Fabrics" data-type="Wallcovering">
<div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Skintex-SF_Aspect_Teal.jpg?v=1773218078&width=540" loading="lazy" alt="Atlantic Cay - Verdant"></div>
- <h4>Atlantic Cay - Verdant</h4><div class="gmeta"><span>Architectural Fabrics</span><span class="tier">reserve</span></div>
- </article><article class="gcard" data-title="Agra Okra" data-hue="300" data-tier="0">
+ <h4>Atlantic Cay - Verdant</h4><div class="gmeta"><span>Architectural Fabrics</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Agra Okra" data-vendor="Arte International" data-type="Wallcovering">
<div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Indienne_Agra_18310_Roomshot_Web_LR-medium-two-thirds.jpg?v=1775694511&width=540" loading="lazy" alt="Agra Okra"></div>
- <h4>Agra Okra</h4><div class="gmeta"><span>Arte International</span><span class="tier">casual</span></div>
- </article><article class="gcard" data-title="Tabula Wax Yellow" data-hue="130" data-tier="1">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/TABW-002.jpg?v=1781283018&width=540" loading="lazy" alt="Tabula Wax Yellow"></div>
- <h4>Tabula Wax Yellow</h4><div class="gmeta"><span>Artmura</span><span class="tier">signature</span></div>
- </article><article class="gcard" data-title="History of Art 2 - Green" data-hue="20" data-tier="2">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/792889b95340fba909e80a1654dba520_26de4b84-bada-44c9-8ff0-d634e951ba3c.jpg?v=1776187521&width=540" loading="lazy" alt="History of Art 2 - Green"></div>
- <h4>History of Art 2 - Green</h4><div class="gmeta"><span>AS Creation</span><span class="tier">reserve</span></div>
+ <h4>Agra Okra</h4><div class="gmeta"><span>Arte International</span><span class="tier">Wallcovering</span></div>
</article></div>
</div>
<div class="ns"><div><h3 class="disp">The Designer's Brief</h3><p>New arrivals, designer picks, and pattern stories — weekly, from Los Angeles.</p></div><form onsubmit="return false"><input type="email" placeholder="you@studio.com"><button>Subscribe</button></form></div>
@@ -124,8 +118,9 @@ var grid=document.getElementById('grid'),sel=document.getElementById('sortsel'),
var KS='dwconcept-atelier-sort',KD='dwconcept-atelier-cols';
function apply(){var v=sel.value,cards=[].slice.call(grid.children);
cards.sort(function(a,b){if(v==='title')return a.dataset.title.localeCompare(b.dataset.title);
- if(v==='color')return (+a.dataset.hue)-(+b.dataset.hue);
- if(v==='tier')return (+a.dataset.tier)-(+b.dataset.tier);return 0;});
+ if(v==='vendor')return a.dataset.vendor.localeCompare(b.dataset.vendor);
+ if(v==='type')return (a.dataset.type||'').localeCompare(b.dataset.type||'')||a.dataset.title.localeCompare(b.dataset.title);
+ return 0;});
cards.forEach(function(c){grid.appendChild(c);});localStorage.setItem(KS,v);}
function densFill(){var mn=+dens.min||2,mx=+dens.max||6;dens.style.setProperty('--fill',((dens.value-mn)/(mx-mn)*100)+'%');}
sel.addEventListener('change',apply);
diff --git a/public/versions/gallery.html b/public/versions/gallery.html
index f69fdda..9aa1748 100644
--- a/public/versions/gallery.html
+++ b/public/versions/gallery.html
@@ -65,53 +65,47 @@ footer .in{max-width:1240px;margin:0 auto;padding:36px 22px;display:flex;justify
<nav class="sec"><div class="in"><a>Wallcoverings</a><a>Fabrics</a><a>Murals</a><a>By Color</a><a>By Room</a><a>New Arrivals</a><a>Trade Program</a><a>Samples</a></div></nav>
<div class="heroc">
<div class="rv"><h1 class="disp">The marketplace of extraordinary walls.</h1><p>Marketplace-luxe — white-gallery ground, curated collections, provenance chips, designer-first navigation. A curated face for the deepest designer-wallcovering catalog online — every pattern sampled for $4.25, every order backed by thirty years of trade expertise.</p><a class="cta">Explore the collection</a></div>
- <div class="heroimg rv"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/riviera.webp?v=1761541180&width=1100" alt="" loading="eager"></div>
+ <div class="heroimg rv"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/GDW5772_007_1ab582ac-1f6b-4e40-b3ed-45e30b5c120c.jpg?v=1776795809&width=1100" alt="" loading="eager"></div>
</div>
<div class="wrap">
<div class="sh"><h2>Curated This Week</h2>
<div class="controls">
<label for="sortsel">Sort</label>
- <span class="selwrap"><select id="sortsel"><option value="newest">Newest</option><option value="color">Color</option><option value="title">Title A→Z</option><option value="tier">Collection tier</option></select></span>
+ <span class="selwrap"><select id="sortsel"><option value="newest">Newest</option><option value="title">Title A→Z</option><option value="vendor">Vendor A→Z</option><option value="type">Type</option></select></span>
<label for="dens">Density</label>
<input type="range" id="dens" min="2" max="6" step="1" value="4">
</div>
</div>
- <div class="grid" id="grid"><article class="gcard" data-title="Titik Wp Linen" data-hue="28" data-tier="0">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/CCP-2347_16.jpg?v=1777019997&width=540" loading="lazy" alt="Titik Wp Linen"></div>
- <h4>Titik Wp Linen</h4><div class="gmeta"><span>Caroline Cecil Textiles</span><span class="tier">casual</span></div>
- </article><article class="gcard" data-title="Posh Snakes Green" data-hue="152" data-tier="1">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Wallpaper-Behang-Posh-Snakes-gray-green-groen-grijs-Catchii-mockup_328e2e61-4b16-43d9-bf54-c100543af4bd.jpg?v=1744999054&width=540" loading="lazy" alt="Posh Snakes Green"></div>
- <h4>Posh Snakes Green</h4><div class="gmeta"><span>Catchii Netherlands Europe</span><span class="tier">signature</span></div>
- </article><article class="gcard" data-title="Tortoise" data-hue="208" data-tier="2">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/tortoise.jpg?v=1760721667&width=540" loading="lazy" alt="Tortoise"></div>
- <h4>Tortoise</h4><div class="gmeta"><span>Celerie Kemble</span><span class="tier">reserve</span></div>
- </article><article class="gcard" data-title="Diva Poplin, Vert" data-hue="12" data-tier="0">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/vert-1904_1_134404.jpg?v=1782672048&width=540" loading="lazy" alt="Diva Poplin, Vert"></div>
- <h4>Diva Poplin, Vert</h4><div class="gmeta"><span>Charles Burger</span><span class="tier">casual</span></div>
- </article><article class="gcard" data-title="Willow Pearl - Cream" data-hue="262" data-tier="1">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/2008-148-04-Willow-Pearl-scaled_27cc3134-1291-4605-85ca-d870cd905b85.jpg?v=1773305872&width=540" loading="lazy" alt="Willow Pearl - Cream"></div>
- <h4>Willow Pearl - Cream</h4><div class="gmeta"><span>1838 Wallcoverings</span><span class="tier">signature</span></div>
- </article><article class="gcard" data-title="Designdrop - Colourful" data-hue="88" data-tier="2">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/66e3a5f29fd1fd50090f5d5fce9b4ddc.jpg?v=1773629119&width=540" loading="lazy" alt="Designdrop - Colourful"></div>
- <h4>Designdrop - Colourful</h4><div class="gmeta"><span>A.S. Création</span><span class="tier">reserve</span></div>
- </article><article class="gcard" data-title="Brown on Tint" data-hue="340" data-tier="0">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Criss-Cross-Brown-on-Tint-AC403-16_015244-sm-thumb.jpg?v=1783597230&width=540" loading="lazy" alt="Brown on Tint"></div>
- <h4>Brown on Tint</h4><div class="gmeta"><span>Alan Campbell</span><span class="tier">casual</span></div>
- </article><article class="gcard" data-title="Riviera" data-hue="190" data-tier="1">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/riviera.webp?v=1761541180&width=540" loading="lazy" alt="Riviera"></div>
- <h4>Riviera</h4><div class="gmeta"><span>Ananbo</span><span class="tier">signature</span></div>
- </article><article class="gcard" data-title="Ark - Parchment - beige" data-hue="46" data-tier="2">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/AMW10001_1611_11959302-5997-4bcd-9a99-c54a9b0919e8.jpg?v=1775761440&width=540" loading="lazy" alt="Ark - Parchment - beige"></div>
- <h4>Ark - Parchment - beige</h4><div class="gmeta"><span>Andrew Martin</span><span class="tier">reserve</span></div>
- </article><article class="gcard" data-title="Gibson, Navy" data-hue="300" data-tier="0">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/AT78793_4d4910ee-a9f9-4534-ae47-bed6b7d9942d.jpg?v=1782985244&width=540" loading="lazy" alt="Gibson, Navy"></div>
- <h4>Gibson, Navy</h4><div class="gmeta"><span>Anna French</span><span class="tier">casual</span></div>
- </article><article class="gcard" data-title="Anthology - Stria Stone/Amber/Plum" data-hue="130" data-tier="1">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/ESHE131796.jpg?v=1784735551&width=540" loading="lazy" alt="Anthology - Stria Stone/Amber/Plum"></div>
- <h4>Anthology - Stria Stone/Amber/Plum</h4><div class="gmeta"><span>Anthology</span><span class="tier">signature</span></div>
- </article><article class="gcard" data-title="Caswell Sage Green" data-hue="20" data-tier="2">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/PSW1213RL.jpg?v=1740775136&width=540" loading="lazy" alt="Caswell Sage Green"></div>
- <h4>Caswell Sage Green</h4><div class="gmeta"><span>Apartment Wallpaper</span><span class="tier">reserve</span></div>
+ <div class="grid" id="grid"><article class="gcard" data-title="Harlequin Cool Blue" data-vendor="FallingStar Studio" data-type="Wallcoverings">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/product_harlequin_coolblue_4f31ade8-2e21-4998-a26a-d06f5a0a2816.jpg?v=1782000474&width=540" loading="lazy" alt="Harlequin Cool Blue"></div>
+ <h4>Harlequin Cool Blue</h4><div class="gmeta"><span>FallingStar Studio</span><span class="tier">Wallcoverings</span></div>
+ </article><article class="gcard" data-title="Purnon" data-vendor="Farrow & Ball" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/purnon.jpg?v=1761344027&width=540" loading="lazy" alt="Purnon"></div>
+ <h4>Purnon</h4><div class="gmeta"><span>Farrow & Ball</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Asolo Pecan Grasscloth" data-vendor="Fentucci" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/DWNAT-100190.jpg?v=1782322040&width=540" loading="lazy" alt="Asolo Pecan Grasscloth"></div>
+ <h4>Asolo Pecan Grasscloth</h4><div class="gmeta"><span>Fentucci</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Tellaro Flax II" data-vendor="Fentucci Naturals" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/A-18002.jpg?v=1784772458&width=540" loading="lazy" alt="Tellaro Flax II"></div>
+ <h4>Tellaro Flax II</h4><div class="gmeta"><span>Fentucci Naturals</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Java Slate Blue" data-vendor="Franquemont London" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Java_SlateBlue_WallpaperSample_Franquemont_948a1aaa-ae30-4eb1-85ab-0e00b2144f5f.webp?v=1771008254&width=540" loading="lazy" alt="Java Slate Blue"></div>
+ <h4>Java Slate Blue</h4><div class="gmeta"><span>Franquemont London</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Ming Dynasty by French Market" data-vendor="French Market" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/products/WDB4138-ASM.jpg?v=1572310884&width=540" loading="lazy" alt="Ming Dynasty by French Market"></div>
+ <h4>Ming Dynasty by French Market</h4><div class="gmeta"><span>French Market</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Tall Trees Delft Blue" data-vendor="G P & J Baker" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/BW45141_2_7598bef2-55ce-4530-80c2-706adbab8a89.jpg?v=1776795816&width=540" loading="lazy" alt="Tall Trees Delft Blue"></div>
+ <h4>Tall Trees Delft Blue</h4><div class="gmeta"><span>G P & J Baker</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Elefantes Agua" data-vendor="Gaston Y Daniela" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/GDW5772_007_1ab582ac-1f6b-4e40-b3ed-45e30b5c120c.jpg?v=1776795809&width=540" loading="lazy" alt="Elefantes Agua"></div>
+ <h4>Elefantes Agua</h4><div class="gmeta"><span>Gaston Y Daniela</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Glambeads Phro Stone Glass Bead" data-vendor="Glambeads by DW" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/IMG_8603_4acf5f3b-54a3-43d0-998c-a9a3c1edc0ce.jpg?v=1702848575&width=540" loading="lazy" alt="Glambeads Phro Stone Glass Bead"></div>
+ <h4>Glambeads Phro Stone Glass Bead</h4><div class="gmeta"><span>Glambeads by DW</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Crystalabra Shards Small" data-vendor="Glass Beaded" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/products/ScreenShot2022-03-28at12.16.42PM.png?v=1648497345&width=540" loading="lazy" alt="Crystalabra Shards Small"></div>
+ <h4>Crystalabra Shards Small</h4><div class="gmeta"><span>Glass Beaded</span><span class="tier">Wallcovering</span></div>
</article></div>
</div>
<div class="ns"><div><h3 class="disp">The Designer's Brief</h3><p>New arrivals, designer picks, and pattern stories — weekly, from Los Angeles.</p></div><form onsubmit="return false"><input type="email" placeholder="you@studio.com"><button>Subscribe</button></form></div>
@@ -124,8 +118,9 @@ var grid=document.getElementById('grid'),sel=document.getElementById('sortsel'),
var KS='dwconcept-gallery-sort',KD='dwconcept-gallery-cols';
function apply(){var v=sel.value,cards=[].slice.call(grid.children);
cards.sort(function(a,b){if(v==='title')return a.dataset.title.localeCompare(b.dataset.title);
- if(v==='color')return (+a.dataset.hue)-(+b.dataset.hue);
- if(v==='tier')return (+a.dataset.tier)-(+b.dataset.tier);return 0;});
+ if(v==='vendor')return a.dataset.vendor.localeCompare(b.dataset.vendor);
+ if(v==='type')return (a.dataset.type||'').localeCompare(b.dataset.type||'')||a.dataset.title.localeCompare(b.dataset.title);
+ return 0;});
cards.forEach(function(c){grid.appendChild(c);});localStorage.setItem(KS,v);}
function densFill(){var mn=+dens.min||2,mx=+dens.max||6;dens.style.setProperty('--fill',((dens.value-mn)/(mx-mn)*100)+'%');}
sel.addEventListener('change',apply);
diff --git a/public/versions/heritage.html b/public/versions/heritage.html
index 4073b04..f9dfaae 100644
--- a/public/versions/heritage.html
+++ b/public/versions/heritage.html
@@ -65,53 +65,47 @@ footer .in{max-width:1240px;margin:0 auto;padding:36px 22px;display:flex;justify
<nav class="sec"><div class="in"><a>Wallcoverings</a><a>Fabrics</a><a>Murals</a><a>By Color</a><a>By Room</a><a>New Arrivals</a><a>Trade Program</a><a>Samples</a></div></nav>
<div class="heroc">
<div class="rv"><h1 class="disp">Colour, considered for a century.</h1><p>Estate heritage — muted greens, archival typography, room-story merchandising. A curated face for the deepest designer-wallcovering catalog online — every pattern sampled for $4.25, every order backed by thirty years of trade expertise.</p><a class="cta">Explore the collection</a></div>
- <div class="heroimg rv"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/0146f618c045458f55fde3938e24a872_8d33407f-805e-4aaa-ac25-b833e713ab71.jpg?v=1688757110&width=1100" alt="" loading="eager"></div>
+ <div class="heroimg rv"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/DWC-278566-DesignerWallcoverings-Los-Angeles-1_a3bede8c-b94d-477d-b0c2-97ad23dba752.png?v=1741881338&width=1100" alt="" loading="eager"></div>
</div>
<div class="wrap">
<div class="sh"><h2>Curated This Week</h2>
<div class="controls">
<label for="sortsel">Sort</label>
- <span class="selwrap"><select id="sortsel"><option value="newest">Newest</option><option value="color">Color</option><option value="title">Title A→Z</option><option value="tier">Collection tier</option></select></span>
+ <span class="selwrap"><select id="sortsel"><option value="newest">Newest</option><option value="title">Title A→Z</option><option value="vendor">Vendor A→Z</option><option value="type">Type</option></select></span>
<label for="dens">Density</label>
<input type="range" id="dens" min="2" max="6" step="1" value="4">
</div>
</div>
- <div class="grid" id="grid"><article class="gcard" data-title="AT50-04 Unfinished" data-hue="28" data-tier="0">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/36-raw.webp?v=1773709468&width=540" loading="lazy" alt="AT50-04 Unfinished"></div>
- <h4>AT50-04 Unfinished</h4><div class="gmeta"><span>Atomic 50 Ceilings</span><span class="tier">casual</span></div>
- </article><article class="gcard" data-title="Puntini Sisal - Tanlines" data-hue="152" data-tier="1">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/puntini-sisal-tanlines.jpg?v=1761078002&width=540" loading="lazy" alt="Puntini Sisal - Tanlines"></div>
- <h4>Puntini Sisal - Tanlines</h4><div class="gmeta"><span>Backdrop</span><span class="tier">signature</span></div>
- </article><article class="gcard" data-title="Parvani Linen" data-hue="208" data-tier="2">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/PW78034_5_3f924781-0c2e-438b-9846-83f79e437024.jpg?v=1777019988&width=540" loading="lazy" alt="Parvani Linen"></div>
- <h4>Parvani Linen</h4><div class="gmeta"><span>Baker Lifestyle</span><span class="tier">reserve</span></div>
- </article><article class="gcard" data-title="Otoko Pewter" data-hue="12" data-tier="0">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/W930-03-otoko-wallcovering-pewter_01_5832ae5f-061c-4ca9-a0fd-a2cfae71fd80.jpg?v=1775598526&width=540" loading="lazy" alt="Otoko Pewter"></div>
- <h4>Otoko Pewter</h4><div class="gmeta"><span>Black Edition</span><span class="tier">casual</span></div>
- </article><article class="gcard" data-title="Tiger Lily Midnight" data-hue="262" data-tier="1">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/DWBM-260149.jpg?v=1773968873&width=540" loading="lazy" alt="Tiger Lily Midnight"></div>
- <h4>Tiger Lily Midnight</h4><div class="gmeta"><span>Brand McKenzie</span><span class="tier">signature</span></div>
- </article><article class="gcard" data-title="Wild Meadow - Plaster Pink" data-hue="88" data-tier="2">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/0146f618c045458f55fde3938e24a872_8d33407f-805e-4aaa-ac25-b833e713ab71.jpg?v=1688757110&width=540" loading="lazy" alt="Wild Meadow - Plaster Pink"></div>
- <h4>Wild Meadow - Plaster Pink</h4><div class="gmeta"><span>British Walls</span><span class="tier">reserve</span></div>
- </article><article class="gcard" data-title="Yasu Silver" data-hue="340" data-tier="0">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/P8015111_11_926bf78a-0113-4b3d-a601-d75cad06b09c.jpg?v=1777019993&width=540" loading="lazy" alt="Yasu Silver"></div>
- <h4>Yasu Silver</h4><div class="gmeta"><span>Brunschwig & Fils</span><span class="tier">casual</span></div>
- </article><article class="gcard" data-title="Carnegie Blair" data-hue="190" data-tier="1">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/3b939cb6099480f87495278c2df300f8_9a832cf5-8d1b-426c-89a1-7029d87520e7.jpg?v=1784740002&width=540" loading="lazy" alt="Carnegie Blair"></div>
- <h4>Carnegie Blair</h4><div class="gmeta"><span>Carnegie</span><span class="tier">signature</span></div>
- </article><article class="gcard" data-title="Titik Wp Linen" data-hue="46" data-tier="2">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/CCP-2347_16.jpg?v=1777019997&width=540" loading="lazy" alt="Titik Wp Linen"></div>
- <h4>Titik Wp Linen</h4><div class="gmeta"><span>Caroline Cecil Textiles</span><span class="tier">reserve</span></div>
- </article><article class="gcard" data-title="Posh Snakes Green" data-hue="300" data-tier="0">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Wallpaper-Behang-Posh-Snakes-gray-green-groen-grijs-Catchii-mockup_328e2e61-4b16-43d9-bf54-c100543af4bd.jpg?v=1744999054&width=540" loading="lazy" alt="Posh Snakes Green"></div>
- <h4>Posh Snakes Green</h4><div class="gmeta"><span>Catchii Netherlands Europe</span><span class="tier">casual</span></div>
- </article><article class="gcard" data-title="Tortoise" data-hue="130" data-tier="1">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/tortoise.jpg?v=1760721667&width=540" loading="lazy" alt="Tortoise"></div>
- <h4>Tortoise</h4><div class="gmeta"><span>Celerie Kemble</span><span class="tier">signature</span></div>
- </article><article class="gcard" data-title="Diva Poplin, Vert" data-hue="20" data-tier="2">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/vert-1904_1_134404.jpg?v=1782672048&width=540" loading="lazy" alt="Diva Poplin, Vert"></div>
- <h4>Diva Poplin, Vert</h4><div class="gmeta"><span>Charles Burger</span><span class="tier">reserve</span></div>
+ <div class="grid" id="grid"><article class="gcard" data-title="Mens Bomber Jacket" data-vendor="Contrado" data-type="Others">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/2643921_mens-bomber-jacket_0.jpg?v=1742242131&width=540" loading="lazy" alt="Mens Bomber Jacket"></div>
+ <h4>Mens Bomber Jacket</h4><div class="gmeta"><span>Contrado</span><span class="tier">Others</span></div>
+ </article><article class="gcard" data-title="Manor-Gardens Winter" data-vendor="Coordonné" data-type="Mural">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/YSP0546_01.jpg?v=1784738420&width=540" loading="lazy" alt="Manor-Gardens Winter"></div>
+ <h4>Manor-Gardens Winter</h4><div class="gmeta"><span>Coordonné</span><span class="tier">Mural</span></div>
+ </article><article class="gcard" data-title="Allure - Bronzy Taupe" data-vendor="Daisy Bennett" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/products/db11526.jpg?v=1602006818&width=540" loading="lazy" alt="Allure - Bronzy Taupe"></div>
+ <h4>Allure - Bronzy Taupe</h4><div class="gmeta"><span>Daisy Bennett</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Coutts — Deep Rich Gold gilded Xuan paper" data-vendor="De Gournay" data-type="Wallpaper">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/06052020101555.jpg?v=1784731138&width=540" loading="lazy" alt="Coutts — Deep Rich Gold gilded Xuan paper"></div>
+ <h4>Coutts — Deep Rich Gold gilded Xuan paper</h4><div class="gmeta"><span>De Gournay</span><span class="tier">Wallpaper</span></div>
+ </article><article class="gcard" data-title="Bambù Strié Wall - 002" data-vendor="Dedar" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/1__74269.1773625470.jpg?v=1773712278&width=540" loading="lazy" alt="Bambù Strié Wall - 002"></div>
+ <h4>Bambù Strié Wall - 002</h4><div class="gmeta"><span>Dedar</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Madagascar Cloth 3 Raffia" data-vendor="Designer Wallcoverings" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/DWC-278566-DesignerWallcoverings-Los-Angeles-1_a3bede8c-b94d-477d-b0c2-97ad23dba752.png?v=1741881338&width=540" loading="lazy" alt="Madagascar Cloth 3 Raffia"></div>
+ <h4>Madagascar Cloth 3 Raffia</h4><div class="gmeta"><span>Designer Wallcoverings</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Huerta Gitana Piedra - Piedra" data-vendor="Designers Guild" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/huerta-gitana-piedra.webp?v=1761090551&width=540" loading="lazy" alt="Huerta Gitana Piedra - Piedra"></div>
+ <h4>Huerta Gitana Piedra - Piedra</h4><div class="gmeta"><span>Designers Guild</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Color Bars, Olive" data-vendor="Designtex" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/6727501__26889.1730829023.jpg?v=1783690828&width=540" loading="lazy" alt="Color Bars, Olive"></div>
+ <h4>Color Bars, Olive</h4><div class="gmeta"><span>Designtex</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Sol Carretto Mural Rocco By Dolce & Gabbana" data-vendor="Dolce & Gabbana" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/TCW011TCAHPUC092.jpg?v=1711558473&width=540" loading="lazy" alt="Sol Carretto Mural Rocco By Dolce & Gabbana"></div>
+ <h4>Sol Carretto Mural Rocco By Dolce & Gabbana</h4><div class="gmeta"><span>Dolce & Gabbana</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Gallery Walls - White" data-vendor="Donghia" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/DG-09703_010.jpg?v=1772819030&width=540" loading="lazy" alt="Gallery Walls - White"></div>
+ <h4>Gallery Walls - White</h4><div class="gmeta"><span>Donghia</span><span class="tier">Wallcovering</span></div>
</article></div>
</div>
<div class="ns"><div><h3 class="disp">The Designer's Brief</h3><p>New arrivals, designer picks, and pattern stories — weekly, from Los Angeles.</p></div><form onsubmit="return false"><input type="email" placeholder="you@studio.com"><button>Subscribe</button></form></div>
@@ -124,8 +118,9 @@ var grid=document.getElementById('grid'),sel=document.getElementById('sortsel'),
var KS='dwconcept-heritage-sort',KD='dwconcept-heritage-cols';
function apply(){var v=sel.value,cards=[].slice.call(grid.children);
cards.sort(function(a,b){if(v==='title')return a.dataset.title.localeCompare(b.dataset.title);
- if(v==='color')return (+a.dataset.hue)-(+b.dataset.hue);
- if(v==='tier')return (+a.dataset.tier)-(+b.dataset.tier);return 0;});
+ if(v==='vendor')return a.dataset.vendor.localeCompare(b.dataset.vendor);
+ if(v==='type')return (a.dataset.type||'').localeCompare(b.dataset.type||'')||a.dataset.title.localeCompare(b.dataset.title);
+ return 0;});
cards.forEach(function(c){grid.appendChild(c);});localStorage.setItem(KS,v);}
function densFill(){var mn=+dens.min||2,mx=+dens.max||6;dens.style.setProperty('--fill',((dens.value-mn)/(mx-mn)*100)+'%');}
sel.addEventListener('change',apply);
diff --git a/public/versions/maison.html b/public/versions/maison.html
index bfa3c10..fa08dab 100644
--- a/public/versions/maison.html
+++ b/public/versions/maison.html
@@ -65,53 +65,47 @@ footer .in{max-width:1240px;margin:0 auto;padding:36px 22px;display:flex;justify
<nav class="sec"><div class="in"><a>Wallcoverings</a><a>Fabrics</a><a>Murals</a><a>By Color</a><a>By Room</a><a>New Arrivals</a><a>Trade Program</a><a>Samples</a></div></nav>
<div class="heroc">
<div class="rv"><h1 class="disp">The Parisian maison, digitized.</h1><p>French maison energy — indigo + ochre, pattern-forward editorial storytelling. A curated face for the deepest designer-wallcovering catalog online — every pattern sampled for $4.25, every order backed by thirty years of trade expertise.</p><a class="cta">Explore the collection</a></div>
- <div class="heroimg rv"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/PSW1213RL.jpg?v=1740775136&width=1100" alt="" loading="eager"></div>
+ <div class="heroimg rv"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/puntini-sisal-tanlines.jpg?v=1761078002&width=1100" alt="" loading="eager"></div>
</div>
<div class="wrap">
<div class="sh"><h2>Curated This Week</h2>
<div class="controls">
<label for="sortsel">Sort</label>
- <span class="selwrap"><select id="sortsel"><option value="newest">Newest</option><option value="color">Color</option><option value="title">Title A→Z</option><option value="tier">Collection tier</option></select></span>
+ <span class="selwrap"><select id="sortsel"><option value="newest">Newest</option><option value="title">Title A→Z</option><option value="vendor">Vendor A→Z</option><option value="type">Type</option></select></span>
<label for="dens">Density</label>
<input type="range" id="dens" min="2" max="6" step="1" value="4">
</div>
</div>
- <div class="grid" id="grid"><article class="gcard" data-title="Ark - Parchment - beige" data-hue="28" data-tier="0">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/AMW10001_1611_11959302-5997-4bcd-9a99-c54a9b0919e8.jpg?v=1775761440&width=540" loading="lazy" alt="Ark - Parchment - beige"></div>
- <h4>Ark - Parchment - beige</h4><div class="gmeta"><span>Andrew Martin</span><span class="tier">casual</span></div>
- </article><article class="gcard" data-title="Gibson, Navy" data-hue="152" data-tier="1">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/AT78793_4d4910ee-a9f9-4534-ae47-bed6b7d9942d.jpg?v=1782985244&width=540" loading="lazy" alt="Gibson, Navy"></div>
- <h4>Gibson, Navy</h4><div class="gmeta"><span>Anna French</span><span class="tier">signature</span></div>
- </article><article class="gcard" data-title="Anthology - Stria Stone/Amber/Plum" data-hue="208" data-tier="2">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/ESHE131796.jpg?v=1784735551&width=540" loading="lazy" alt="Anthology - Stria Stone/Amber/Plum"></div>
- <h4>Anthology - Stria Stone/Amber/Plum</h4><div class="gmeta"><span>Anthology</span><span class="tier">reserve</span></div>
- </article><article class="gcard" data-title="Caswell Sage Green" data-hue="12" data-tier="0">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/PSW1213RL.jpg?v=1740775136&width=540" loading="lazy" alt="Caswell Sage Green"></div>
- <h4>Caswell Sage Green</h4><div class="gmeta"><span>Apartment Wallpaper</span><span class="tier">casual</span></div>
- </article><article class="gcard" data-title="Atlantic Cay - Verdant" data-hue="262" data-tier="1">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Skintex-SF_Aspect_Teal.jpg?v=1773218078&width=540" loading="lazy" alt="Atlantic Cay - Verdant"></div>
- <h4>Atlantic Cay - Verdant</h4><div class="gmeta"><span>Architectural Fabrics</span><span class="tier">signature</span></div>
- </article><article class="gcard" data-title="Agra Okra" data-hue="88" data-tier="2">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Indienne_Agra_18310_Roomshot_Web_LR-medium-two-thirds.jpg?v=1775694511&width=540" loading="lazy" alt="Agra Okra"></div>
- <h4>Agra Okra</h4><div class="gmeta"><span>Arte International</span><span class="tier">reserve</span></div>
- </article><article class="gcard" data-title="Tabula Wax Yellow" data-hue="340" data-tier="0">
+ <div class="grid" id="grid"><article class="gcard" data-title="Tabula Wax Yellow" data-vendor="Artmura" data-type="Wallcovering">
<div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/TABW-002.jpg?v=1781283018&width=540" loading="lazy" alt="Tabula Wax Yellow"></div>
- <h4>Tabula Wax Yellow</h4><div class="gmeta"><span>Artmura</span><span class="tier">casual</span></div>
- </article><article class="gcard" data-title="History of Art 2 - Green" data-hue="190" data-tier="1">
+ <h4>Tabula Wax Yellow</h4><div class="gmeta"><span>Artmura</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="History of Art 2 - Green" data-vendor="AS Creation" data-type="Wallcovering">
<div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/792889b95340fba909e80a1654dba520_26de4b84-bada-44c9-8ff0-d634e951ba3c.jpg?v=1776187521&width=540" loading="lazy" alt="History of Art 2 - Green"></div>
- <h4>History of Art 2 - Green</h4><div class="gmeta"><span>AS Creation</span><span class="tier">signature</span></div>
- </article><article class="gcard" data-title="AT50-04 Unfinished" data-hue="46" data-tier="2">
+ <h4>History of Art 2 - Green</h4><div class="gmeta"><span>AS Creation</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="AT50-04 Unfinished" data-vendor="Atomic 50 Ceilings" data-type="Tin Ceiling Tile">
<div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/36-raw.webp?v=1773709468&width=540" loading="lazy" alt="AT50-04 Unfinished"></div>
- <h4>AT50-04 Unfinished</h4><div class="gmeta"><span>Atomic 50 Ceilings</span><span class="tier">reserve</span></div>
- </article><article class="gcard" data-title="Puntini Sisal - Tanlines" data-hue="300" data-tier="0">
+ <h4>AT50-04 Unfinished</h4><div class="gmeta"><span>Atomic 50 Ceilings</span><span class="tier">Tin Ceiling Tile</span></div>
+ </article><article class="gcard" data-title="Puntini Sisal - Tanlines" data-vendor="Backdrop" data-type="Wallcovering">
<div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/puntini-sisal-tanlines.jpg?v=1761078002&width=540" loading="lazy" alt="Puntini Sisal - Tanlines"></div>
- <h4>Puntini Sisal - Tanlines</h4><div class="gmeta"><span>Backdrop</span><span class="tier">casual</span></div>
- </article><article class="gcard" data-title="Parvani Linen" data-hue="130" data-tier="1">
+ <h4>Puntini Sisal - Tanlines</h4><div class="gmeta"><span>Backdrop</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Parvani Linen" data-vendor="Baker Lifestyle" data-type="Wallcovering">
<div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/PW78034_5_3f924781-0c2e-438b-9846-83f79e437024.jpg?v=1777019988&width=540" loading="lazy" alt="Parvani Linen"></div>
- <h4>Parvani Linen</h4><div class="gmeta"><span>Baker Lifestyle</span><span class="tier">signature</span></div>
- </article><article class="gcard" data-title="Otoko Pewter" data-hue="20" data-tier="2">
+ <h4>Parvani Linen</h4><div class="gmeta"><span>Baker Lifestyle</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Otoko Pewter" data-vendor="Black Edition" data-type="Wallcovering">
<div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/W930-03-otoko-wallcovering-pewter_01_5832ae5f-061c-4ca9-a0fd-a2cfae71fd80.jpg?v=1775598526&width=540" loading="lazy" alt="Otoko Pewter"></div>
- <h4>Otoko Pewter</h4><div class="gmeta"><span>Black Edition</span><span class="tier">reserve</span></div>
+ <h4>Otoko Pewter</h4><div class="gmeta"><span>Black Edition</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Tiger Lily Midnight" data-vendor="Brand McKenzie" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/DWBM-260149.jpg?v=1773968873&width=540" loading="lazy" alt="Tiger Lily Midnight"></div>
+ <h4>Tiger Lily Midnight</h4><div class="gmeta"><span>Brand McKenzie</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Wild Meadow - Plaster Pink" data-vendor="British Walls" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/0146f618c045458f55fde3938e24a872_8d33407f-805e-4aaa-ac25-b833e713ab71.jpg?v=1688757110&width=540" loading="lazy" alt="Wild Meadow - Plaster Pink"></div>
+ <h4>Wild Meadow - Plaster Pink</h4><div class="gmeta"><span>British Walls</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Yasu Silver" data-vendor="Brunschwig & Fils" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/P8015111_11_926bf78a-0113-4b3d-a601-d75cad06b09c.jpg?v=1777019993&width=540" loading="lazy" alt="Yasu Silver"></div>
+ <h4>Yasu Silver</h4><div class="gmeta"><span>Brunschwig & Fils</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Carnegie Blair" data-vendor="Carnegie" data-type="Upholstery">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/3b939cb6099480f87495278c2df300f8_9a832cf5-8d1b-426c-89a1-7029d87520e7.jpg?v=1784740002&width=540" loading="lazy" alt="Carnegie Blair"></div>
+ <h4>Carnegie Blair</h4><div class="gmeta"><span>Carnegie</span><span class="tier">Upholstery</span></div>
</article></div>
</div>
<div class="ns"><div><h3 class="disp">The Designer's Brief</h3><p>New arrivals, designer picks, and pattern stories — weekly, from Los Angeles.</p></div><form onsubmit="return false"><input type="email" placeholder="you@studio.com"><button>Subscribe</button></form></div>
@@ -124,8 +118,9 @@ var grid=document.getElementById('grid'),sel=document.getElementById('sortsel'),
var KS='dwconcept-maison-sort',KD='dwconcept-maison-cols';
function apply(){var v=sel.value,cards=[].slice.call(grid.children);
cards.sort(function(a,b){if(v==='title')return a.dataset.title.localeCompare(b.dataset.title);
- if(v==='color')return (+a.dataset.hue)-(+b.dataset.hue);
- if(v==='tier')return (+a.dataset.tier)-(+b.dataset.tier);return 0;});
+ if(v==='vendor')return a.dataset.vendor.localeCompare(b.dataset.vendor);
+ if(v==='type')return (a.dataset.type||'').localeCompare(b.dataset.type||'')||a.dataset.title.localeCompare(b.dataset.title);
+ return 0;});
cards.forEach(function(c){grid.appendChild(c);});localStorage.setItem(KS,v);}
function densFill(){var mn=+dens.min||2,mx=+dens.max||6;dens.style.setProperty('--fill',((dens.value-mn)/(mx-mn)*100)+'%');}
sel.addEventListener('change',apply);
diff --git a/public/versions/studio.html b/public/versions/studio.html
index fd6f870..b6c4456 100644
--- a/public/versions/studio.html
+++ b/public/versions/studio.html
@@ -65,53 +65,47 @@ footer .in{max-width:1240px;margin:0 auto;padding:36px 22px;display:flex;justify
<nav class="sec"><div class="in"><a>Wallcoverings</a><a>Fabrics</a><a>Murals</a><a>By Color</a><a>By Room</a><a>New Arrivals</a><a>Trade Program</a><a>Samples</a></div></nav>
<div class="heroc">
<div class="rv"><h1 class="disp">Wallpaper, without the intimidation.</h1><p>DTC-playful — bold color blocks, plain language, sample-first funnel. A curated face for the deepest designer-wallcovering catalog online — every pattern sampled for $4.25, every order backed by thirty years of trade expertise.</p><a class="cta">Explore the collection</a></div>
- <div class="heroimg rv"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/36-raw.webp?v=1773709468&width=1100" alt="" loading="eager"></div>
+ <div class="heroimg rv"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/navy-on-white-linen-1781_1_214246.jpg?v=1781635420&width=1100" alt="" loading="eager"></div>
</div>
<div class="wrap">
<div class="sh"><h2>Curated This Week</h2>
<div class="controls">
<label for="sortsel">Sort</label>
- <span class="selwrap"><select id="sortsel"><option value="newest">Newest</option><option value="color">Color</option><option value="title">Title A→Z</option><option value="tier">Collection tier</option></select></span>
+ <span class="selwrap"><select id="sortsel"><option value="newest">Newest</option><option value="title">Title A→Z</option><option value="vendor">Vendor A→Z</option><option value="type">Type</option></select></span>
<label for="dens">Density</label>
<input type="range" id="dens" min="2" max="6" step="1" value="4">
</div>
</div>
- <div class="grid" id="grid"><article class="gcard" data-title="Atlantic Cay - Verdant" data-hue="28" data-tier="0">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Skintex-SF_Aspect_Teal.jpg?v=1773218078&width=540" loading="lazy" alt="Atlantic Cay - Verdant"></div>
- <h4>Atlantic Cay - Verdant</h4><div class="gmeta"><span>Architectural Fabrics</span><span class="tier">casual</span></div>
- </article><article class="gcard" data-title="Agra Okra" data-hue="152" data-tier="1">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Indienne_Agra_18310_Roomshot_Web_LR-medium-two-thirds.jpg?v=1775694511&width=540" loading="lazy" alt="Agra Okra"></div>
- <h4>Agra Okra</h4><div class="gmeta"><span>Arte International</span><span class="tier">signature</span></div>
- </article><article class="gcard" data-title="Tabula Wax Yellow" data-hue="208" data-tier="2">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/TABW-002.jpg?v=1781283018&width=540" loading="lazy" alt="Tabula Wax Yellow"></div>
- <h4>Tabula Wax Yellow</h4><div class="gmeta"><span>Artmura</span><span class="tier">reserve</span></div>
- </article><article class="gcard" data-title="History of Art 2 - Green" data-hue="12" data-tier="0">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/792889b95340fba909e80a1654dba520_26de4b84-bada-44c9-8ff0-d634e951ba3c.jpg?v=1776187521&width=540" loading="lazy" alt="History of Art 2 - Green"></div>
- <h4>History of Art 2 - Green</h4><div class="gmeta"><span>AS Creation</span><span class="tier">casual</span></div>
- </article><article class="gcard" data-title="AT50-04 Unfinished" data-hue="262" data-tier="1">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/36-raw.webp?v=1773709468&width=540" loading="lazy" alt="AT50-04 Unfinished"></div>
- <h4>AT50-04 Unfinished</h4><div class="gmeta"><span>Atomic 50 Ceilings</span><span class="tier">signature</span></div>
- </article><article class="gcard" data-title="Puntini Sisal - Tanlines" data-hue="88" data-tier="2">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/puntini-sisal-tanlines.jpg?v=1761078002&width=540" loading="lazy" alt="Puntini Sisal - Tanlines"></div>
- <h4>Puntini Sisal - Tanlines</h4><div class="gmeta"><span>Backdrop</span><span class="tier">reserve</span></div>
- </article><article class="gcard" data-title="Parvani Linen" data-hue="340" data-tier="0">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/PW78034_5_3f924781-0c2e-438b-9846-83f79e437024.jpg?v=1777019988&width=540" loading="lazy" alt="Parvani Linen"></div>
- <h4>Parvani Linen</h4><div class="gmeta"><span>Baker Lifestyle</span><span class="tier">casual</span></div>
- </article><article class="gcard" data-title="Otoko Pewter" data-hue="190" data-tier="1">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/W930-03-otoko-wallcovering-pewter_01_5832ae5f-061c-4ca9-a0fd-a2cfae71fd80.jpg?v=1775598526&width=540" loading="lazy" alt="Otoko Pewter"></div>
- <h4>Otoko Pewter</h4><div class="gmeta"><span>Black Edition</span><span class="tier">signature</span></div>
- </article><article class="gcard" data-title="Tiger Lily Midnight" data-hue="46" data-tier="2">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/DWBM-260149.jpg?v=1773968873&width=540" loading="lazy" alt="Tiger Lily Midnight"></div>
- <h4>Tiger Lily Midnight</h4><div class="gmeta"><span>Brand McKenzie</span><span class="tier">reserve</span></div>
- </article><article class="gcard" data-title="Wild Meadow - Plaster Pink" data-hue="300" data-tier="0">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/0146f618c045458f55fde3938e24a872_8d33407f-805e-4aaa-ac25-b833e713ab71.jpg?v=1688757110&width=540" loading="lazy" alt="Wild Meadow - Plaster Pink"></div>
- <h4>Wild Meadow - Plaster Pink</h4><div class="gmeta"><span>British Walls</span><span class="tier">casual</span></div>
- </article><article class="gcard" data-title="Yasu Silver" data-hue="130" data-tier="1">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/P8015111_11_926bf78a-0113-4b3d-a601-d75cad06b09c.jpg?v=1777019993&width=540" loading="lazy" alt="Yasu Silver"></div>
- <h4>Yasu Silver</h4><div class="gmeta"><span>Brunschwig & Fils</span><span class="tier">signature</span></div>
- </article><article class="gcard" data-title="Carnegie Blair" data-hue="20" data-tier="2">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/3b939cb6099480f87495278c2df300f8_9a832cf5-8d1b-426c-89a1-7029d87520e7.jpg?v=1784740002&width=540" loading="lazy" alt="Carnegie Blair"></div>
- <h4>Carnegie Blair</h4><div class="gmeta"><span>Carnegie</span><span class="tier">reserve</span></div>
+ <div class="grid" id="grid"><article class="gcard" data-title="Titik Wp Linen" data-vendor="Caroline Cecil Textiles" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/CCP-2347_16.jpg?v=1777019997&width=540" loading="lazy" alt="Titik Wp Linen"></div>
+ <h4>Titik Wp Linen</h4><div class="gmeta"><span>Caroline Cecil Textiles</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Posh Snakes Green" data-vendor="Catchii Netherlands Europe" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Wallpaper-Behang-Posh-Snakes-gray-green-groen-grijs-Catchii-mockup_328e2e61-4b16-43d9-bf54-c100543af4bd.jpg?v=1744999054&width=540" loading="lazy" alt="Posh Snakes Green"></div>
+ <h4>Posh Snakes Green</h4><div class="gmeta"><span>Catchii Netherlands Europe</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Tortoise" data-vendor="Celerie Kemble" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/tortoise.jpg?v=1760721667&width=540" loading="lazy" alt="Tortoise"></div>
+ <h4>Tortoise</h4><div class="gmeta"><span>Celerie Kemble</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Diva Poplin, Vert" data-vendor="Charles Burger" data-type="Fabric">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/vert-1904_1_134404.jpg?v=1782672048&width=540" loading="lazy" alt="Diva Poplin, Vert"></div>
+ <h4>Diva Poplin, Vert</h4><div class="gmeta"><span>Charles Burger</span><span class="tier">Fabric</span></div>
+ </article><article class="gcard" data-title="Lulu Stripe Navy on White Linen Screen Printed" data-vendor="China Seas" data-type="Fabric">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/navy-on-white-linen-1781_1_214246.jpg?v=1781635420&width=540" loading="lazy" alt="Lulu Stripe Navy on White Linen Screen Printed"></div>
+ <h4>Lulu Stripe Navy on White Linen Screen Printed</h4><div class="gmeta"><span>China Seas</span><span class="tier">Fabric</span></div>
+ </article><article class="gcard" data-title="Avant Le Mistral Panel" data-vendor="Christian Lacroix Europe" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/160349_11f10447-e6d5-426b-aabf-07ca78428354.webp?v=1738951241&width=540" loading="lazy" alt="Avant Le Mistral Panel"></div>
+ <h4>Avant Le Mistral Panel</h4><div class="gmeta"><span>Christian Lacroix Europe</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Highland Wonder/Lagoon Wp" data-vendor="Clarke and Clarke" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/W0202_01_CAC.jpg?v=1777020004&width=540" loading="lazy" alt="Highland Wonder/Lagoon Wp"></div>
+ <h4>Highland Wonder/Lagoon Wp</h4><div class="gmeta"><span>Clarke and Clarke</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Gray" data-vendor="Cloth and Paper" data-type="Fabric">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/gray-313_1_155301.jpg?v=1782479480&width=540" loading="lazy" alt="Gray"></div>
+ <h4>Gray</h4><div class="gmeta"><span>Cloth and Paper</span><span class="tier">Fabric</span></div>
+ </article><article class="gcard" data-title="Soie Bois Tresse Epicéa" data-vendor="CMO Paris" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/cmo-soie-bois-mural-wso-03-68.jpg?v=1785007404&width=540" loading="lazy" alt="Soie Bois Tresse Epicéa"></div>
+ <h4>Soie Bois Tresse Epicéa</h4><div class="gmeta"><span>CMO Paris</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Palm Jungle - Olive Green On White" data-vendor="Cole & Son" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/PalmJungle_Image_Flatshot_Item_95-1001.jpg?v=1779809928&width=540" loading="lazy" alt="Palm Jungle - Olive Green On White"></div>
+ <h4>Palm Jungle - Olive Green On White</h4><div class="gmeta"><span>Cole & Son</span><span class="tier">Wallcovering</span></div>
</article></div>
</div>
<div class="ns"><div><h3 class="disp">The Designer's Brief</h3><p>New arrivals, designer picks, and pattern stories — weekly, from Los Angeles.</p></div><form onsubmit="return false"><input type="email" placeholder="you@studio.com"><button>Subscribe</button></form></div>
@@ -124,8 +118,9 @@ var grid=document.getElementById('grid'),sel=document.getElementById('sortsel'),
var KS='dwconcept-studio-sort',KD='dwconcept-studio-cols';
function apply(){var v=sel.value,cards=[].slice.call(grid.children);
cards.sort(function(a,b){if(v==='title')return a.dataset.title.localeCompare(b.dataset.title);
- if(v==='color')return (+a.dataset.hue)-(+b.dataset.hue);
- if(v==='tier')return (+a.dataset.tier)-(+b.dataset.tier);return 0;});
+ if(v==='vendor')return a.dataset.vendor.localeCompare(b.dataset.vendor);
+ if(v==='type')return (a.dataset.type||'').localeCompare(b.dataset.type||'')||a.dataset.title.localeCompare(b.dataset.title);
+ return 0;});
cards.forEach(function(c){grid.appendChild(c);});localStorage.setItem(KS,v);}
function densFill(){var mn=+dens.min||2,mx=+dens.max||6;dens.style.setProperty('--fill',((dens.value-mn)/(mx-mn)*100)+'%');}
sel.addEventListener('change',apply);
diff --git a/public/versions/texture.html b/public/versions/texture.html
index 26859e8..f6ff6d4 100644
--- a/public/versions/texture.html
+++ b/public/versions/texture.html
@@ -65,53 +65,47 @@ footer .in{max-width:1240px;margin:0 auto;padding:36px 22px;display:flex;justify
<nav class="sec"><div class="in"><a>Wallcoverings</a><a>Fabrics</a><a>Murals</a><a>By Color</a><a>By Room</a><a>New Arrivals</a><a>Trade Program</a><a>Samples</a></div></nav>
<div class="heroc">
<div class="rv"><h1 class="disp">Material is the message.</h1><p>Immersive texture — full-bleed material macros, dark gallery chrome, slow motion. A curated face for the deepest designer-wallcovering catalog online — every pattern sampled for $4.25, every order backed by thirty years of trade expertise.</p><a class="cta">Explore the collection</a></div>
- <div class="heroimg rv"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/tortoise.jpg?v=1760721667&width=1100" alt="" loading="eager"></div>
+ <div class="heroimg rv"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/mural-vibrations-big-croco-metal-fd3224e33b74b3b7acf840edd721.jpg?v=1783791056&width=1100" alt="" loading="eager"></div>
</div>
<div class="wrap">
<div class="sh"><h2>Curated This Week</h2>
<div class="controls">
<label for="sortsel">Sort</label>
- <span class="selwrap"><select id="sortsel"><option value="newest">Newest</option><option value="color">Color</option><option value="title">Title A→Z</option><option value="tier">Collection tier</option></select></span>
+ <span class="selwrap"><select id="sortsel"><option value="newest">Newest</option><option value="title">Title A→Z</option><option value="vendor">Vendor A→Z</option><option value="type">Type</option></select></span>
<label for="dens">Density</label>
<input type="range" id="dens" min="2" max="6" step="1" value="4">
</div>
</div>
- <div class="grid" id="grid"><article class="gcard" data-title="Tiger Lily Midnight" data-hue="28" data-tier="0">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/DWBM-260149.jpg?v=1773968873&width=540" loading="lazy" alt="Tiger Lily Midnight"></div>
- <h4>Tiger Lily Midnight</h4><div class="gmeta"><span>Brand McKenzie</span><span class="tier">casual</span></div>
- </article><article class="gcard" data-title="Wild Meadow - Plaster Pink" data-hue="152" data-tier="1">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/0146f618c045458f55fde3938e24a872_8d33407f-805e-4aaa-ac25-b833e713ab71.jpg?v=1688757110&width=540" loading="lazy" alt="Wild Meadow - Plaster Pink"></div>
- <h4>Wild Meadow - Plaster Pink</h4><div class="gmeta"><span>British Walls</span><span class="tier">signature</span></div>
- </article><article class="gcard" data-title="Yasu Silver" data-hue="208" data-tier="2">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/P8015111_11_926bf78a-0113-4b3d-a601-d75cad06b09c.jpg?v=1777019993&width=540" loading="lazy" alt="Yasu Silver"></div>
- <h4>Yasu Silver</h4><div class="gmeta"><span>Brunschwig & Fils</span><span class="tier">reserve</span></div>
- </article><article class="gcard" data-title="Carnegie Blair" data-hue="12" data-tier="0">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/3b939cb6099480f87495278c2df300f8_9a832cf5-8d1b-426c-89a1-7029d87520e7.jpg?v=1784740002&width=540" loading="lazy" alt="Carnegie Blair"></div>
- <h4>Carnegie Blair</h4><div class="gmeta"><span>Carnegie</span><span class="tier">casual</span></div>
- </article><article class="gcard" data-title="Titik Wp Linen" data-hue="262" data-tier="1">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/CCP-2347_16.jpg?v=1777019997&width=540" loading="lazy" alt="Titik Wp Linen"></div>
- <h4>Titik Wp Linen</h4><div class="gmeta"><span>Caroline Cecil Textiles</span><span class="tier">signature</span></div>
- </article><article class="gcard" data-title="Posh Snakes Green" data-hue="88" data-tier="2">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Wallpaper-Behang-Posh-Snakes-gray-green-groen-grijs-Catchii-mockup_328e2e61-4b16-43d9-bf54-c100543af4bd.jpg?v=1744999054&width=540" loading="lazy" alt="Posh Snakes Green"></div>
- <h4>Posh Snakes Green</h4><div class="gmeta"><span>Catchii Netherlands Europe</span><span class="tier">reserve</span></div>
- </article><article class="gcard" data-title="Tortoise" data-hue="340" data-tier="0">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/tortoise.jpg?v=1760721667&width=540" loading="lazy" alt="Tortoise"></div>
- <h4>Tortoise</h4><div class="gmeta"><span>Celerie Kemble</span><span class="tier">casual</span></div>
- </article><article class="gcard" data-title="Diva Poplin, Vert" data-hue="190" data-tier="1">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/vert-1904_1_134404.jpg?v=1782672048&width=540" loading="lazy" alt="Diva Poplin, Vert"></div>
- <h4>Diva Poplin, Vert</h4><div class="gmeta"><span>Charles Burger</span><span class="tier">signature</span></div>
- </article><article class="gcard" data-title="Willow Pearl - Cream" data-hue="46" data-tier="2">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/2008-148-04-Willow-Pearl-scaled_27cc3134-1291-4605-85ca-d870cd905b85.jpg?v=1773305872&width=540" loading="lazy" alt="Willow Pearl - Cream"></div>
- <h4>Willow Pearl - Cream</h4><div class="gmeta"><span>1838 Wallcoverings</span><span class="tier">reserve</span></div>
- </article><article class="gcard" data-title="Designdrop - Colourful" data-hue="300" data-tier="0">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/66e3a5f29fd1fd50090f5d5fce9b4ddc.jpg?v=1773629119&width=540" loading="lazy" alt="Designdrop - Colourful"></div>
- <h4>Designdrop - Colourful</h4><div class="gmeta"><span>A.S. Création</span><span class="tier">casual</span></div>
- </article><article class="gcard" data-title="Brown on Tint" data-hue="130" data-tier="1">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Criss-Cross-Brown-on-Tint-AC403-16_015244-sm-thumb.jpg?v=1783597230&width=540" loading="lazy" alt="Brown on Tint"></div>
- <h4>Brown on Tint</h4><div class="gmeta"><span>Alan Campbell</span><span class="tier">signature</span></div>
- </article><article class="gcard" data-title="Riviera" data-hue="20" data-tier="2">
- <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/riviera.webp?v=1761541180&width=540" loading="lazy" alt="Riviera"></div>
- <h4>Riviera</h4><div class="gmeta"><span>Ananbo</span><span class="tier">reserve</span></div>
+ <div class="grid" id="grid"><article class="gcard" data-title="Accessorise Type Ii Vinyl Cadillac" data-vendor="Dupenny" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Accessorise-CADILLAC-WP-Thumb-Shop.jpg?v=1775598529&width=540" loading="lazy" alt="Accessorise Type Ii Vinyl Cadillac"></div>
+ <h4>Accessorise Type Ii Vinyl Cadillac</h4><div class="gmeta"><span>Dupenny</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Anemone Opera - Powder Tide - Whimsical" data-vendor="DW Bespoke Studio" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/tidepool-bloom-v5-nano.png?v=1784779206&width=540" loading="lazy" alt="Anemone Opera - Powder Tide - Whimsical"></div>
+ <h4>Anemone Opera - Powder Tide - Whimsical</h4><div class="gmeta"><span>DW Bespoke Studio</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Courtright Cranes Red and Cream" data-vendor="DW Exclusive Wallpaper" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/DWC-211497-DesignerWallcoverings-Los-Angeles-4_7be9edb9-4fa6-4932-befb-1ff3ea511732.jpg?v=1694028327&width=540" loading="lazy" alt="Courtright Cranes Red and Cream"></div>
+ <h4>Courtright Cranes Red and Cream</h4><div class="gmeta"><span>DW Exclusive Wallpaper</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Chiba Bay Blue Throw Blanket on Vitali Velvet" data-vendor="DW Home" data-type="Others">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/products/11859510-dig-762164-chibabay-blue-by-designerwallcoverings_19-1_a3ea7102-1f49-4d97-9c9b-15dd0926b182.jpg?v=1630525797&width=540" loading="lazy" alt="Chiba Bay Blue Throw Blanket on Vitali Velvet"></div>
+ <h4>Chiba Bay Blue Throw Blanket on Vitali Velvet</h4><div class="gmeta"><span>DW Home</span><span class="tier">Others</span></div>
+ </article><article class="gcard" data-title="Mission Beach Polaris" data-vendor="DWHD" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/akasha-polaris.jpg?v=1775660108&width=540" loading="lazy" alt="Mission Beach Polaris"></div>
+ <h4>Mission Beach Polaris</h4><div class="gmeta"><span>DWHD</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Edge" data-vendor="Edge Wallcovering" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/products/unnamed.jpg?v=1573747790&width=540" loading="lazy" alt="Edge"></div>
+ <h4>Edge</h4><div class="gmeta"><span>Edge Wallcovering</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Big Croco Métal Golden Brown" data-vendor="Elitis" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/mural-vibrations-big-croco-metal-fd3224e33b74b3b7acf840edd721.jpg?v=1783791056&width=540" loading="lazy" alt="Big Croco Métal Golden Brown"></div>
+ <h4>Big Croco Métal Golden Brown</h4><div class="gmeta"><span>Elitis</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Emiliana Parati, Valentin Yudashkin 5" data-vendor="Emiliana Parati" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/emiliana-parati-valentin-yudashkin-5.jpg?v=1761090561&width=540" loading="lazy" alt="Emiliana Parati, Valentin Yudashkin 5"></div>
+ <h4>Emiliana Parati, Valentin Yudashkin 5</h4><div class="gmeta"><span>Emiliana Parati</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Angles Geometric - Off White" data-vendor="Erika Wakerly" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/products/Angles010-gold-grey-1.jpg?v=1572310884&width=540" loading="lazy" alt="Angles Geometric - Off White"></div>
+ <h4>Angles Geometric - Off White</h4><div class="gmeta"><span>Erika Wakerly</span><span class="tier">Wallcovering</span></div>
+ </article><article class="gcard" data-title="Darling - 503" data-vendor="Fabricut" data-type="Wallcovering">
+ <div class="gimg"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/5151803_2x_79e1d63a-e405-4ae1-92a1-7a1261699736.jpg?v=1773710464&width=540" loading="lazy" alt="Darling - 503"></div>
+ <h4>Darling - 503</h4><div class="gmeta"><span>Fabricut</span><span class="tier">Wallcovering</span></div>
</article></div>
</div>
<div class="ns"><div><h3 class="disp">The Designer's Brief</h3><p>New arrivals, designer picks, and pattern stories — weekly, from Los Angeles.</p></div><form onsubmit="return false"><input type="email" placeholder="you@studio.com"><button>Subscribe</button></form></div>
@@ -124,8 +118,9 @@ var grid=document.getElementById('grid'),sel=document.getElementById('sortsel'),
var KS='dwconcept-texture-sort',KD='dwconcept-texture-cols';
function apply(){var v=sel.value,cards=[].slice.call(grid.children);
cards.sort(function(a,b){if(v==='title')return a.dataset.title.localeCompare(b.dataset.title);
- if(v==='color')return (+a.dataset.hue)-(+b.dataset.hue);
- if(v==='tier')return (+a.dataset.tier)-(+b.dataset.tier);return 0;});
+ if(v==='vendor')return a.dataset.vendor.localeCompare(b.dataset.vendor);
+ if(v==='type')return (a.dataset.type||'').localeCompare(b.dataset.type||'')||a.dataset.title.localeCompare(b.dataset.title);
+ return 0;});
cards.forEach(function(c){grid.appendChild(c);});localStorage.setItem(KS,v);}
function densFill(){var mn=+dens.min||2,mx=+dens.max||6;dens.style.setProperty('--fill',((dens.value-mn)/(mx-mn)*100)+'%');}
sel.addEventListener('change',apply);
diff --git a/scripts/aeo-render.mjs b/scripts/aeo-render.mjs
new file mode 100644
index 0000000..a93f956
--- /dev/null
+++ b/scripts/aeo-render.mjs
@@ -0,0 +1,57 @@
+#!/usr/bin/env node
+// TK-20 — render an AEO draft (docs/aeo-drafts/<slug>.md) into the publishable
+// HTML block: direct-answer paragraph + visible FAQ accordion (<details>).
+// The visible FAQ text mirrors the FAQPage JSON-LD verbatim (Google match rule).
+// Steve rulings baked in (approve-all 2026-07-26): "wallpaper" allowed ONLY in
+// H1/FAQ questions (search-intent surfaces); internal links to not-yet-live
+// pages are stripped; JSON-LD ships separately via theme snippet, NOT body_html.
+import { readFileSync } from 'node:fs';
+import { dirname, join } from 'node:path';
+import { fileURLToPath } from 'node:url';
+
+const HERE = dirname(fileURLToPath(import.meta.url));
+const slug = process.argv[2];
+if (!slug) { console.error('usage: aeo-render.mjs <draft-slug>'); process.exit(1); }
+const md = readFileSync(join(HERE, '..', 'docs', 'aeo-drafts', slug + '.md'), 'utf8');
+
+const esc = s => s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
+// Inline markdown: bold, italics, strip links to not-yet-live internals, plain links kept as text.
+const inline = s => esc(s.trim())
+ .replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>')
+ .replace(/\*([^*]+)\*/g, '<em>$1</em>')
+ .replace(/\[([^\]]+)\]\([^)]*\)/g, '$1');
+
+// H1
+const h1 = (md.match(/^# (.+)$/m) || [])[1] || slug;
+
+// Direct answer: first blockquote after the "Direct answer" heading (skip editorial-note quotes).
+const daSection = md.split(/## Direct answer[^\n]*\n/)[1] || '';
+const daLines = [];
+for (const line of daSection.split('\n')) {
+ if (line.startsWith('>')) { const t = line.replace(/^>\s?/, ''); if (/editorial note/i.test(t)) break; daLines.push(t); }
+ else if (daLines.length) break;
+}
+const directAnswer = inline(daLines.join(' ').trim());
+
+// FAQ pairs: "**Q: ...**" then "A: ..." (answer runs to next Q or section break).
+const faqSection = md.split(/## FAQ[^\n]*\n/)[1] || '';
+const faq = [];
+const qRe = /\*\*Q:\s*([^*]+)\*\*\s*\n(?:A:\s*)?([\s\S]*?)(?=\n\*\*Q:|\n## |\n---|$)/g;
+let m;
+while ((m = qRe.exec(faqSection)) !== null) {
+ const q = m[1].trim();
+ let a = m[2].replace(/^A:\s*/, '').trim().replace(/\n+/g, ' ');
+ a = a.replace(/\*\(Editor:[^)]*\)\*/gi, '').trim(); // strip editor-only notes
+ if (q && a) faq.push([q, a]);
+}
+
+const faqHtml = faq.map(([q, a]) =>
+ `<details class="dw-aeo-faq"><summary><strong>${inline(q)}</strong></summary><p>${inline(a)}</p></details>`).join('\n');
+
+const block = `<div class="dw-aeo-block" data-aeo="${esc(slug)}">
+<p class="dw-aeo-answer">${directAnswer}</p>
+<h2>Frequently asked questions</h2>
+${faqHtml}
+</div>`;
+
+console.log(JSON.stringify({ slug, h1, faq_count: faq.length, html: block }));
diff --git a/scripts/collect-dw.mjs b/scripts/collect-dw.mjs
index 872de21..7ace07f 100644
--- a/scripts/collect-dw.mjs
+++ b/scripts/collect-dw.mjs
@@ -145,9 +145,9 @@ const gallery = sql(`select distinct on (vendor) title, vendor, coalesce(nullif(
from shopify_products
where status='ACTIVE' and image_url like 'https://cdn.shopify.com%' and title is not null
and vendor is not null and length(title) between 8 and 60
- order by vendor, created_at_shopify desc limit 40`)
+ order by vendor, created_at_shopify desc limit 90`)
.map(([title, vendor, type, image]) => ({ title, vendor, type, image }))
- .filter(g => !FORBIDDEN_NAMES.test(g.vendor + ' ' + g.title)).slice(0, 24);
+ .filter(g => !FORBIDDEN_NAMES.test(g.vendor + ' ' + g.title)).slice(0, 60);
// Activation cadence — new ACTIVEs per week, last 12 weeks (the rotation-activator drip)
const cadence = sql(`select to_char(date_trunc('week', created_at_shopify),'MM-DD'), count(*)
← ca97015 weekly snapshot refresh: dw-analysis + build + work-orders (
·
back to Consulting Designerwallcoverings Com
·
TK-20 PUBLISHED: AEO blocks live via Admin API (versace smar 788d55d →