← back to Consulting Designerwallcoverings Com

public/portal.html

420 lines

<!doctype html><html lang="en"><head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Designer Wallcoverings — Growth Strategy</title>
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,500;1,400&family=Jost:wght@300;400;500&display=swap" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css">
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<style>
:root{--bg:#0e0c09;--panel:#171310;--ink:#f1ece3;--gold:#c9a24b;--line:rgba(201,162,75,.22);--dim:rgba(241,236,227,.66)}
*{margin:0;padding:0;box-sizing:border-box}
body{background:var(--bg);color:var(--ink);font-family:'Jost',system-ui,sans-serif;font-size:19px;line-height:1.75;-webkit-font-smoothing:antialiased}
.disp{font-family:'Cormorant Garamond',Georgia,serif}a{color:inherit;text-decoration:none}
.bar{position:fixed;top:0;left:0;right:0;z-index:40;display:flex;align-items:center;justify-content:space-between;padding:18px 34px;background:linear-gradient(180deg,rgba(14,12,9,.94),rgba(14,12,9,0))}
.burger{width:30px;height:20px;position:relative;cursor:pointer;background:none;border:0}.burger span{position:absolute;left:0;right:0;height:1.6px;background:var(--ink);transition:.35s}
.burger span:nth-child(1){top:1px}.burger span:nth-child(2){top:9px}.burger span:nth-child(3){top:17px}
body.nav .burger span:nth-child(1){transform:translateY(8px) rotate(45deg)}body.nav .burger span:nth-child(2){opacity:0}body.nav .burger span:nth-child(3){transform:translateY(-8px) rotate(-45deg)}
.stamp{font-size:10.5px;letter-spacing:.18em;text-transform:uppercase;color:var(--dim);display:flex;gap:10px;align-items:center}
.stamp button{background:none;border:1px solid var(--line);color:var(--gold);font-family:'Jost';font-size:10px;letter-spacing:.14em;text-transform:uppercase;padding:6px 12px;cursor:pointer}
.stamp button:hover{background:var(--gold);color:var(--bg)}
.menu{position:fixed;top:0;left:0;bottom:0;width:min(420px,86vw);z-index:39;background:var(--panel);border-right:1px solid var(--line);transform:translateX(-100%);transition:.42s cubic-bezier(.6,0,.2,1);padding:92px 40px;overflow:auto}
.mbrand{display:block;font-family:'Cormorant Garamond',serif;font-size:24px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink);margin-bottom:28px}
.mbrand span{color:var(--gold)}
.mbrand small{display:block;font-family:'Jost',system-ui,sans-serif;font-size:9px;letter-spacing:.32em;color:var(--gold);margin-top:4px}
body.nav .menu{transform:none}body.nav .scrim{opacity:1;pointer-events:auto}
.scrim{position:fixed;inset:0;z-index:38;background:rgba(0,0,0,.5);opacity:0;pointer-events:none;transition:.42s}
.menu .mh{font-family:'Cormorant Garamond',serif;font-size:13px;letter-spacing:.3em;text-transform:uppercase;color:var(--gold);margin-bottom:18px}
.menu a{display:block;font-family:'Cormorant Garamond',serif;font-size:23px;padding:9px 0;border-bottom:1px solid var(--line);opacity:.85;transition:.25s}
.menu a:hover{opacity:1;color:var(--gold);padding-left:8px}
.menu .minfo{margin-top:28px;border-top:1px solid var(--line);padding-top:20px}.menu .minfo p{font-size:13px;line-height:1.7;color:var(--dim);border:0;padding:2px 0}
.hero{min-height:96vh;position:relative;display:flex;flex-direction:column;justify-content:center;padding:0 clamp(24px,7vw,120px);overflow:hidden}
.slides{position:absolute;inset:0;z-index:0}
.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,.94),rgba(14,12,9,.90) 62%,rgba(14,12,9,.55));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;text-shadow:0 2px 22px rgba(0,0,0,.72),0 1px 3px rgba(0,0,0,.9)}
/* Hero-only champagne gold: sitewide --gold #c9a24b caps at APCA Lc≈-54 (fails the >=60 wordmark gate on any bg); this brighter tone clears |Lc|>=60 across the wordmark's real position over the dark-plateau gradient. Scoped to the hero so charts/accents keep the signature gold. */
.hero h1 span{color:#d7b968}
.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}
.metrics .l{font-size:10px;letter-spacing:.24em;text-transform:uppercase;color:rgba(201,162,75,.72);margin-top:7px}
section{padding:0 clamp(24px,7vw,120px);border-top:1px solid var(--line);scroll-margin-top:60px}
.accbar{display:flex;gap:12px;justify-content:flex-end;padding:14px clamp(24px,7vw,120px);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.accbar button{background:none;border:1px solid var(--line);color:var(--gold);font-family:'Jost';font-size:11px;letter-spacing:.18em;text-transform:uppercase;padding:9px 18px;cursor:pointer}.accbar button:hover{background:var(--gold);color:var(--bg)}
.acchead{width:100%;text-align:left;background:none;border:0;cursor:pointer;display:flex;gap:22px;padding:36px 0;color:var(--ink)}
.acchead .htext{flex:1;position:relative;padding-left:26px}
.acchead .htext:before{content:'';position:absolute;left:0;top:3px;bottom:3px;width:1px;background:linear-gradient(180deg,var(--gold),rgba(201,162,75,.14));opacity:.5;transition:opacity .28s}
.acchead:hover .htext:before,section.open .acchead .htext:before{opacity:1}
.eyebrow{font-size:12.5px;letter-spacing:.36em;text-transform:uppercase;color:var(--gold);margin-bottom:12px}
h2{font-family:'Cormorant Garamond',serif;font-weight:400;font-size:clamp(30px,4.4vw,54px);line-height:1.05;max-width:22ch}
.acchead .chev{font-family:'Cormorant Garamond',serif;font-size:36px;color:var(--gold);transition:.3s;line-height:.7}
section.open .chev{transform:rotate(45deg)}.acchead:hover h2{color:var(--gold);transition:.25s}
.accbody{display:none;padding-bottom:60px}section.open .accbody{display:block;animation:af .45s ease}
@keyframes af{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}
.lead2{max-width:72ch;color:var(--dim);margin-top:6px;font-size:20px}
table{width:100%;border-collapse:collapse;margin-top:34px;font-size:16px}th,td{text-align:left;padding:15px 14px;border-bottom:1px solid var(--line);vertical-align:top;font-size:15.5px}
th{font-size:11px;letter-spacing:.2em;text-transform:uppercase;color:var(--gold);font-weight:400}
tr.you{background:rgba(201,162,75,.09)}tr.you td:first-child{color:var(--gold)}
td.mo{font-family:'Cormorant Garamond',serif;color:var(--gold);font-size:18px;width:60px}
.chartwrap{margin-top:34px;background:var(--panel);border:1px solid var(--line);border-radius:8px;padding:22px 20px 14px;position:relative;height:340px}
.chartwrap.tall{height:410px}.chartwrap .ct{font-family:'Jost',sans-serif;font-size:10px;letter-spacing:.24em;text-transform:uppercase;color:rgba(241,236,227,.42);margin-bottom:12px}
.chartwrap.dgt{display:flex;flex-direction:column}
.chartwrap.dgt .cwrow{flex:1;min-height:0;display:flex;gap:18px;align-items:stretch}
.chartwrap.dgt .cwcanvas{position:relative;flex:1 1 auto;min-width:0;height:100%}
.hleg{list-style:none;margin:0;padding:0;flex:0 0 auto;max-width:52%;min-width:0;display:flex;flex-direction:column;justify-content:center;gap:10px;overflow:auto}
.hleg li{display:flex;align-items:center;cursor:pointer;font-size:11px;font-weight:500;letter-spacing:.02em;color:rgba(241,236,227,.62);transition:color .2s,opacity .2s;line-height:1.1}
.hleg li:hover{color:var(--ink)}
.hleg li.off{opacity:.38}
.hleg .lgmk{flex:0 0 16px;width:16px;height:2px;border-radius:1px;margin-right:10px;box-shadow:0 0 0 1px rgba(241,236,227,.18)}
.hleg .lgtx{flex:1 1 auto;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding-right:10px}
.hleg .lgvl{flex:0 0 auto;font-variant-numeric:tabular-nums;font-feature-settings:'tnum' 1;letter-spacing:.01em;color:rgba(201,162,75,.92);white-space:pre}
.hleg li.off .lgvl{color:rgba(241,236,227,.30)}
.cards2{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:1px;background:var(--line);margin-top:34px}
.cards2 .c{background:var(--bg);padding:32px 28px}.cards2 .c h3{font-family:'Cormorant Garamond',serif;font-size:22px;color:var(--gold);margin-bottom:10px}.cards2 .c p{color:var(--dim);font-size:16px;line-height:1.6}
.flag{color:#e8a0a0}.good{color:#9fd6b0}
.swotgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:1px;background:var(--line);margin-top:34px}
.swotq{background:var(--bg);padding:28px 26px}.swotq h3{font-family:'Cormorant Garamond',serif;font-size:22px;margin-bottom:12px}
.swotq.pos{border-top:2px solid #9fd6b0}.swotq.neg{border-top:2px solid #e8a0a0}
.swotq.pos h3{color:#9fd6b0}.swotq.neg h3{color:#e8a0a0}
.swotq ul{margin:0;padding-left:18px}.swotq li{color:var(--dim);font-size:15px;line-height:1.55;margin:6px 0}
.srclegend{display:flex;flex-wrap:wrap;gap:10px;margin:26px 0 4px}
.srcb{display:inline-block;font-size:10px;letter-spacing:.14em;text-transform:uppercase;padding:5px 11px;border-radius:3px;border:1px solid var(--line);white-space:nowrap}
.srcb.r{color:var(--gold)}.srcb.o{color:#78aaff;border-color:rgba(120,170,255,.4)}.srcb.d{color:#b78d3f}.srcb.a{color:var(--dim)}.srcb.e{color:#e8a0a0;border-color:rgba(232,160,160,.4)}
td.srccell{white-space:nowrap;vertical-align:middle}
.accbody td code{font-family:ui-monospace,Menlo,monospace;font-size:12.5px;color:var(--ink);background:rgba(201,162,75,.12);padding:1px 6px;border-radius:3px}
.srcnote{margin-top:34px;display:flex;gap:22px;padding:28px 30px;border:1px solid var(--line);background:var(--panel)}
.srcnote .i{font-size:26px;color:var(--gold);line-height:1}
.srcnote h4{font-family:'Cormorant Garamond',serif;font-size:21px;color:var(--gold);margin-bottom:8px}
.srcnote p{color:var(--dim);font-size:15px;line-height:1.6}
.srcnote code{font-family:ui-monospace,Menlo,monospace;font-size:12.5px;color:var(--ink);background:rgba(201,162,75,.12);padding:1px 6px;border-radius:3px}
.flagbox{display:flex;gap:22px;margin-top:34px;padding:30px 32px;border:1px solid var(--gold);background:rgba(201,162,75,.06)}
.flagbox .i{font-size:30px;color:var(--gold)}.flagbox h3{font-family:'Cormorant Garamond',serif;font-size:24px;color:var(--gold);margin-bottom:10px}.flagbox p{color:var(--ink);opacity:.92;font-size:16px;line-height:1.6}
.vgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:20px;margin-top:20px}
.vtile{background:var(--vb);border:1px solid var(--line);padding:28px 26px;transition:.3s;position:relative}.vtile:hover{transform:translateY(-5px);box-shadow:0 22px 60px rgba(0,0,0,.55)}
.vswatch{display:flex;height:36px;border-radius:3px;overflow:hidden;margin-bottom:20px}.vswatch span{flex:1}
.vname{font-family:'Cormorant Garamond',serif;font-size:26px;color:var(--vi)}.vmodel{font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--vg);margin-top:2px}
.vmood{color:var(--vi);opacity:.72;font-size:13px;margin-top:10px;min-height:38px}.vopen{margin-top:16px;font-size:11px;letter-spacing:.22em;text-transform:uppercase;color:var(--vg)}
.pcard{display:flex;gap:22px;padding:24px 0;border-bottom:1px solid var(--line)}.pnum{font-family:'Cormorant Garamond',serif;font-size:30px;color:var(--gold);min-width:44px}.pcard h4{font-family:'Cormorant Garamond',serif;font-size:21px;margin-bottom:6px}.pcard p{color:var(--dim);font-size:16px;line-height:1.6}
.sugg{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:1px;background:var(--line);margin-top:20px}.sugg .s{background:var(--bg);padding:26px 24px}.sugg .s .p{font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--gold)}.sugg .s h4{font-family:'Cormorant Garamond',serif;font-size:20px;margin:8px 0}.sugg .s p{font-size:15px;color:var(--dim);line-height:1.55}
.road{list-style:none;margin-top:20px;position:relative;padding-left:36px}
.road:before{content:'';position:absolute;left:9px;top:10px;bottom:10px;width:2px;background:linear-gradient(180deg,var(--gold),rgba(201,162,75,.14));transform:scaleY(0);transform-origin:top;transition:transform 1.5s cubic-bezier(.5,0,.2,1)}
.road.drawn:before{transform:scaleY(1)}
.road li{padding:22px 0;border-bottom:1px solid var(--line);display:flex;gap:26px;position:relative}
.road li:before{content:'';position:absolute;left:-32px;top:30px;width:12px;height:12px;border-radius:50%;background:var(--bg);border:2px solid var(--gold);box-shadow:0 0 0 4px var(--bg);transform:scale(0);transition:transform .5s cubic-bezier(.2,1.5,.4,1)}
.road.drawn li:before{transform:scale(1)}
.road.drawn li:nth-child(1):before{transition-delay:.30s}.road.drawn li:nth-child(2):before{transition-delay:.62s}.road.drawn li:nth-child(3):before{transition-delay:.94s}.road.drawn li:nth-child(4):before{transition-delay:1.26s}
.road .w{font-family:'Cormorant Garamond',serif;color:var(--gold);font-size:15px;letter-spacing:.2em;text-transform:uppercase;min-width:130px}.road .d{color:var(--dim)}
@media(prefers-reduced-motion:reduce){.slide.on{animation:none;transform:scale(1)}.road:before{transition:none;transform:scaleY(1)}.road li:before{transition:none;transform:scale(1)}.accbody{animation:none!important}}
.rv{opacity:0;transform:translateY(22px);transition:opacity .7s cubic-bezier(.2,.7,.2,1),transform .7s cubic-bezier(.2,.7,.2,1)}.rv.in{opacity:1;transform:none}
#compmap{height:420px;border:1px solid var(--line);border-radius:8px;margin-top:34px;background:#0a0908}
.leaflet-container{background:#0a0908;font-family:'Jost',sans-serif}
.leaflet-popup-content-wrapper{background:var(--panel);color:var(--ink);border:1px solid var(--line)}
.leaflet-popup-tip{background:var(--panel)}
.duo{display:grid;grid-template-columns:1fr 1fr;gap:20px}@media(max-width:900px){.duo{grid-template-columns:1fr}}
.mosaic{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:10px;margin-top:34px}
.mtile{position:relative;aspect-ratio:1;overflow:hidden;border-radius:5px;border:1px solid var(--line);display:block}
.mtile img{width:100%;height:100%;object-fit:cover;transition:transform .5s ease;display:block}
.mtile:hover img{transform:scale(1.06)}
.mtile span{position:absolute;left:0;right:0;bottom:0;font-size:10px;letter-spacing:.1em;text-transform:uppercase;padding:14px 10px 8px;background:linear-gradient(0deg,rgba(10,8,6,.85),transparent);color:var(--ink);opacity:0;transition:.3s}
.mtile:hover span{opacity:1}
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:14px;margin-top:34px}
.kpi{background:var(--panel);border:1px solid var(--line);border-radius:6px;padding:22px 20px}
.kpi .kv{font-family:'Cormorant Garamond',serif;font-size:34px;color:var(--gold);line-height:1}
.kpi .kl{font-size:10.5px;letter-spacing:.18em;text-transform:uppercase;color:var(--dim);margin-top:8px}
.fchips{display:flex;flex-wrap:wrap;gap:8px;margin-top:24px}
.fchip{font-size:11px;letter-spacing:.06em;border:1px solid var(--line);color:var(--dim);padding:5px 11px;border-radius:3px;display:inline-flex;align-items:center;gap:7px}
.fchip b{color:var(--gold);font-weight:600;letter-spacing:.02em;font-variant-numeric:tabular-nums}
footer{padding:56px clamp(24px,7vw,120px);border-top:1px solid var(--line);color:var(--dim);font-size:12px;letter-spacing:.14em;text-transform:uppercase;display:flex;justify-content:space-between;flex-wrap:wrap;gap:20px}
@media(max-width:640px){.metrics{gap:26px}}
</style></head><body>
<header class="bar">
  <div class="stamp"><span>Data collected Jul 27, 2026, 8:50 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>
<nav class="menu" id="portalmenu" onclick="if(event.target.closest('a'))document.body.classList.remove('nav')">
  <a class="mbrand" href="#summary">Designer <span>Wallcoverings</span><small>Growth Strategy · 2026</small></a>
  <div class="mh">Contents</div><a href="#summary">Executive Summary</a><a href="#swot">SWOT Analysis</a><a href="#empire">The Catalog Empire</a><a href="#integrity">Catalog Integrity — the 5-Field Read</a><a href="#competitors">Competitive Landscape</a><a href="#advertising">Channels &amp; Distribution</a><a href="#traffic">Traffic &amp; Search Reality</a><a href="#timing">Timing &amp; Cadence</a><a href="#audit">Website Audit</a><a href="#social">Social Audit</a><a href="#suggested">Suggested New Flagships</a><a href="#partners">Unlikely Partners</a><a href="#revenue">Unlikely Revenue</a><a href="#desk">Live Commerce Desk</a><a href="#roadmap">90-Day Roadmap</a><a href="#sources">Sources &amp; Methodology</a>
  <div class="minfo"><div class="mh">Designer Wallcoverings</div><p>Los Angeles · nationwide e-commerce + trade</p><p>steve@designerwallcoverings.com</p><p>designerwallcoverings.com</p></div>
</nav>

<div class="hero" id="summary">
  <div class="slides"><div class="slide on" style="background-image:url('https://images.unsplash.com/photo-1615873968403-89e068629265?auto=format&fit=crop&w=1920&q=68&sat=-25')"></div><div class="slide" style="background-image:url('https://images.unsplash.com/photo-1618221195710-dd6b41faaea6?auto=format&fit=crop&w=1920&q=68&sat=-25')"></div><div class="slide" style="background-image:url('https://images.unsplash.com/photo-1600210492486-724fe5c67fb0?auto=format&fit=crop&w=1920&q=68&sat=-25')"></div><div class="slide" style="background-image:url('https://images.unsplash.com/photo-1600585154340-be6161a56a0c?auto=format&fit=crop&w=1920&q=68&sat=-25')"></div><div class="slide" style="background-image:url('https://images.unsplash.com/photo-1600607687939-ce8a6c25118c?auto=format&fit=crop&w=1920&q=68&sat=-25')"></div></div>
  <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>81,260 live SKUs</b> across <b>175 vendor lines</b>, a <b>271-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 12,482-product sellable-variant backlog, 20,093 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="81260">0</div><div class="l">Live SKUs (active)</div></div>
      <div class="m"><div class="v" data-c="175">0</div><div class="l">Vendor lines</div></div>
      <div class="m"><div class="v" data-c="271">0</div><div class="l">Microsite fleet</div></div>
      <div class="m"><div class="v" data-c="20093">0</div><div class="l">Staged drafts (fuel)</div></div>
    </div>
  </div>
</div>

<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 27, 2026, 8:50 PM collection.</p>
  <div class="swotgrid"><div class="swotq pos"><h3>Strengths</h3><ul><li>81,260 live SKUs across 175 vendor lines — one of the deepest designer-wallcovering catalogs online</li><li>A 271-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>12,482 active products are sample-only WITHOUT a quote-only designation — browseable but not buyable</li><li>1,453 actives carry zero/null pricing; 277 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 12,482 sample-only backlog into sellable variants — the single largest dormant-revenue pool in the business</li><li>20,093 staged drafts (2,723 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>81,260</b> active products, <b>20,093</b> staged drafts, and <b>80,597</b> archived — a merchandising engine with more inventory in reserve than most competitors have in total. Distribution runs through the flagship plus a <b>271-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,823</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,535</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,760</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 81,260 actives. The palette runs <b>neutrals-first</b> — Beige + White alone account for ~44,475 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>
  </div>
  <div class="mosaic"><a class="mtile" title="Willow Pearl - Cream Wallcovering | 1838 Wallcoverings — 1838 Wallcoverings"><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=360" loading="lazy" alt="Willow Pearl - Cream Wallcovering | 1838 Wallcoverings"><span>1838 Wallcoverings</span></a><a class="mtile" title="Designdrop - Colourful Wallcovering | A.s. Création — A.S. Création"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/66e3a5f29fd1fd50090f5d5fce9b4ddc.jpg?v=1773629119&width=360" loading="lazy" alt="Designdrop - Colourful Wallcovering | A.s. Création"><span>A.S. Création</span></a><a class="mtile" title="Brown on Tint | Alan Campbell — Alan Campbell"><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=360" loading="lazy" alt="Brown on Tint | Alan Campbell"><span>Alan Campbell</span></a><a class="mtile" title="Riviera Wallcovering | Ananbo — Ananbo"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/riviera.webp?v=1761541180&width=360" loading="lazy" alt="Riviera Wallcovering | Ananbo"><span>Ananbo</span></a><a class="mtile" title="Ark - Parchment - beige Wallcovering | Andrew Martin — Andrew Martin"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/AMW10001_1611_11959302-5997-4bcd-9a99-c54a9b0919e8.jpg?v=1775761440&width=360" loading="lazy" alt="Ark - Parchment - beige Wallcovering | Andrew Martin"><span>Andrew Martin</span></a><a class="mtile" title="Gibson, Navy Wallcoverings | Anna French — Anna French"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/AT78793_4d4910ee-a9f9-4534-ae47-bed6b7d9942d.jpg?v=1782985244&width=360" loading="lazy" alt="Gibson, Navy Wallcoverings | Anna French"><span>Anna French</span></a><a class="mtile" title="Anthology - Stria Stone/Amber/Plum Wallcovering | Anthology — Anthology"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/ESHE131796.jpg?v=1784735551&width=360" loading="lazy" alt="Anthology - Stria Stone/Amber/Plum Wallcovering | Anthology"><span>Anthology</span></a><a class="mtile" title="Caswell Sage Green Wallcovering | Jeffrey Stevens — Apartment Wallpaper"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/PSW1213RL.jpg?v=1740775136&width=360" loading="lazy" alt="Caswell Sage Green Wallcovering | Jeffrey Stevens"><span>Apartment Wallpaper</span></a><a class="mtile" title="Atlantic Cay - Verdant | Architectural Fabrics — Architectural Fabrics"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/Skintex-SF_Aspect_Teal.jpg?v=1773218078&width=360" loading="lazy" alt="Atlantic Cay - Verdant | Architectural Fabrics"><span>Architectural Fabrics</span></a><a class="mtile" title="Agra Okra Wallcovering | Arte International — Arte International"><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=360" loading="lazy" alt="Agra Okra Wallcovering | Arte International"><span>Arte International</span></a><a class="mtile" title="Tabula Wax Yellow Wallcovering | Artmura — Artmura"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/TABW-002.jpg?v=1781283018&width=360" loading="lazy" alt="Tabula Wax Yellow Wallcovering | Artmura"><span>Artmura</span></a><a class="mtile" title="History of Art 2 - Green Wallcovering | AS Creation — AS Creation"><img src="https://cdn.shopify.com/s/files/1/0015/4117/7456/files/792889b95340fba909e80a1654dba520_26de4b84-bada-44c9-8ff0-d634e951ba3c.jpg?v=1776187521&width=360" loading="lazy" alt="History of Art 2 - Green Wallcovering | AS Creation"><span>AS Creation</span></a></div>
  <p class="lead2" style="font-size:14px;opacity:.6;margin-top:10px">Live catalog, not stock photography — one current product from each of twelve vendor lines, straight off the store's own CDN.</p>
  <div class="eyebrow" style="margin-top:52px">The discovery fleet</div>
  <p class="lead2">271 microsites — material-, era-, and city-specific storefront satellites that catch long-tail search and funnel to the flagship. The fleet indexes <b>125,624 product handles</b> across <b>163 feed-live sites</b>. Deepest sites, by real catalog depth:</p>
  <div class="fchips"><span class="fchip">japan<b>29,073</b></span><span class="fchip">astek<b>6,167</b></span><span class="fchip">pf-fabric-10110<b>5,350</b></span><span class="fchip">pierrefreyfabrics<b>5,350</b></span><span class="fchip">sangetsu<b>4,731</b></span><span class="fchip">china<b>3,745</b></span><span class="fchip">quadrille<b>3,653</b></span><span class="fchip">eijffinger<b>2,601</b></span><span class="fchip">murals<b>2,447</b></span><span class="fchip">philipjeffries<b>2,447</b></span><span class="fchip">goodrich<b>2,254</b></span><span class="fchip">thibaut<b>1,903</b></span><span class="fchip">omexco<b>1,796</b></span><span class="fchip">j-josephson<b>1,793</b></span><span class="fchip">koroseal-sg<b>1,595</b></span><span class="fchip">cole-son-sg<b>1,316</b></span><span class="fchip">coleandson<b>1,248</b></span><span class="fchip">kravet<b>200+</b></span><span class="fchip">cowtan<b>200+</b></span><span class="fchip">coastline-reserve<b>200+</b></span><span class="fchip">cowtan-tout<b>200+</b></span><span class="fchip">phillipe-romano-textiles<b>200+</b></span><span class="fchip">ascreation<b>200+</b></span><span class="fchip">wolfgordon<b>200+</b></span><span class="fchip">scalamandre<b>200+</b></span><span class="fchip">milton-king<b>200+</b></span><span class="fchip">phillipjeffries<b>200+</b></span><span class="fchip">rebelwalls<b>200+</b></span><span class="fchip">jeffreystevens<b>200+</b></span><span class="fchip">malibu<b>200+</b></span><span class="fchip">marburg<b>200+</b></span><span class="fchip">hollywood<b>200+</b></span><span class="fchip">sancar<b>200+</b></span><span class="fchip">philliperomano<b>200+</b></span><span class="fchip">graham-brown<b>200+</b></span><span class="fchip">coordonn<b>200+</b></span><span class="fchip">coordonne<b>200+</b></span><span class="fchip">designtex<b>200+</b></span><span class="fchip">chinaseas<b>200+</b></span><span class="fchip">jf-fabrics<b>200+</b></span><span class="fchip">koroseal<b>200+</b></span><span class="fchip">phillipe-romano-vinyls<b>200+</b></span><span class="fchip">holly-hunt<b>200+</b></span><span class="fchip">arte<b>200+</b></span><span class="fchip">maharam<b>200+</b></span><span class="fchip">trestintas<b>200+</b></span><span class="fchip">colour-design<b>200+</b></span><span class="fchip">colouranddesign<b>200+</b></span></div>
</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 81,260 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 12,482-product finding</h3><p><b>26,536</b> actives are sample-only. <b>14,054</b> of those are quote-only lines by design. The remaining <b>12,482</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,477</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>Designers Guild</b></td><td>840</td></tr><tr><td><b>Osborne & Little</b></td><td>818</td></tr><tr><td><b>Maya Romanoff</b></td><td>624</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,603</b> actives are tagged Needs-Width, <b>19,270</b> Needs-Price, <b>16,478</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>
</div></section>

<section id="competitors"><div class="eyebrow">03 · Competitive Landscape</div><h2 class="disp">Depth vs. polish: the field.</h2><div class="accbody">
  <p class="lead2">DW's tracked competitor registry, rendered verbatim, plus an analyst read: DW wins on catalog depth and trade authority; the DTC natives win on front-end polish and brand voice. The play is closing the polish gap without surrendering the depth moat.</p>
  <div class="chartwrap"><div class="ct">Catalog depth vs. digital polish — analyst-scored, 0–100</div><canvas id="compChart"></canvas></div>
  <table><thead><tr><th>Competitor</th><th>Domain</th><th>Watch status</th><th>Products found</th><th>Notes</th></tr></thead><tbody><tr><td><b>Decorators Best</b></td><td>decoratorsbest.com</td><td>Active watch</td><td>26,607</td><td>Large catalog, public pricing. Carries Thibaut, Cole & Son, Kravet</td></tr><tr><td><b>Wallpapers To Go</b></td><td>wallpaperstogo.com</td><td>Active watch</td><td>25,001</td><td>Major retailer. York, Thibaut, Brewster, Norwall</td></tr><tr><td><b>Mahones Wallpaper</b></td><td>mahoneswallpapershop.com</td><td>Active watch</td><td>24,990</td><td>Traditional dealer. Most major brands.</td></tr><tr><td><b>L.A. Design Concepts</b></td><td>ladesignconcepts.com</td><td>Active watch</td><td>13,826</td><td>Discount dealer (40% off). Thibaut, Anna French</td></tr><tr><td><b>Finest Wallpaper</b></td><td>finestwallpaper.com</td><td>Active watch</td><td>1,046</td><td>Ralph Lauren, Thibaut. US/Canada pricing.</td></tr><tr><td><b>Burke Decor</b></td><td>burkedecor.com</td><td>Active watch</td><td>0</td><td>Home decor + wallpaper. Cole & Son, Brewster, York</td></tr><tr><td><b>Wallpaper Wholesaler</b></td><td>wallpaperwholesaler.com</td><td>Active watch</td><td>0</td><td>Custom site (not Shopify). 32K+ products. JSON-LD structured data. Sitemap: /sitemaps/sitemap-products-{1,2}.xml. Brands: Brewster, MDC, Mind the Gap, Sancar, Eykon, National Wallcovering, Norwall. Quote-only: Astek, Fabricut, Innovations, PJ, S.Harris, Stroheim, Trend, Vervain.</td></tr><tr><td><b>Peelstick</b></td><td>peelstick.com</td><td>Paused</td><td>0</td><td>Peel & stick only — different category</td></tr></tbody></table>
  <div id="compmap"></div>
  <p class="lead2" style="font-size:15px;margin-top:14px;opacity:.7">The field, mapped: DW in Los Angeles vs. tracked competitor HQs (analyst-compiled geo). LA proximity to the design trade + studios is a structural advantage none of them share.</p>
</div></section>

<section id="advertising"><div class="eyebrow">04 · Channels &amp; Distribution</div><h2 class="disp">Seven channels, one command center.</h2><div class="accbody">
  <p class="lead2">Live from the marketing command center at collection time: <b>7 of 7</b> platforms connected. The Facebook page network alone spans <b>80</b> pages; Instagram <b>34</b> accounts. The infrastructure exists — the discipline to convert reach into attributed revenue is the build.</p>
  <div class="flagbox"><div class="i">◆</div><div><h3 class="disp">The paid-ads gap — measured, not guessed</h3><p>A $0 pixel scan of every tracked competitor's homepage (Jul 27): <b>5 of 8 rivals are paying to advertise</b> — Google Ads on five of them, Meta on one — while <b>DW's own homepage carries analytics but zero paid-ad pixels</b>. The field is buying the demand DW's catalog should own. With attribution wired first (below), a measured Google Shopping + brand-terms program is the obvious counter.</p></div></div>
  <table><thead><tr><th>Domain</th><th></th><th>Ad pixels detected</th><th>Analytics</th><th>Read</th></tr></thead><tbody><tr class="you"><td><b>Designer Wallcoverings (you)</b></td><td>designerwallcoverings.com</td><td>—</td><td>Yes</td><td>No paid-ad pixels detected on homepage</td></tr><tr><td><b>Decorators Best</b></td><td>decoratorsbest.com</td><td>google_ads · microsoft_bing</td><td>Yes</td><td>Paying to advertise (google_ads, microsoft_bing)</td></tr><tr><td><b>Wallpapers To Go</b></td><td>wallpaperstogo.com</td><td>google_ads · meta</td><td>—</td><td>Paying to advertise (google_ads, meta)</td></tr><tr><td><b>Mahones Wallpaper</b></td><td>mahoneswallpapershop.com</td><td>google_ads</td><td>Yes</td><td>Paying to advertise (google_ads)</td></tr><tr><td><b>L.A. Design Concepts</b></td><td>ladesignconcepts.com</td><td>google_ads · microsoft_bing</td><td>Yes</td><td>Paying to advertise (google_ads, microsoft_bing)</td></tr><tr><td><b>Finest Wallpaper</b></td><td>finestwallpaper.com</td><td>google_ads</td><td>Yes</td><td>Paying to advertise (google_ads)</td></tr><tr><td><b>Burke Decor</b></td><td>burkedecor.com</td><td>—</td><td>—</td><td>Homepage unreachable to scanner (fetch failed)</td></tr><tr><td><b>Wallpaper Wholesaler</b></td><td>wallpaperwholesaler.com</td><td>—</td><td>Yes</td><td>No paid-ad pixels detected on homepage</td></tr><tr><td><b>Peelstick</b></td><td>peelstick.com</td><td>—</td><td>—</td><td>Homepage unreachable to scanner (fetch failed)</td></tr></tbody></table>
  <div class="chartwrap"><div class="ct">Connected accounts per platform (live)</div><canvas id="chanChart"></canvas></div>
  <table><thead><tr><th>Platform</th><th>Status</th><th>Accounts</th><th>Note</th></tr></thead><tbody><tr><td><b>Facebook Pages</b></td><td><span class="good">Connected</span></td><td>80</td><td>Live in the marketing command center</td></tr><tr><td><b>Instagram</b></td><td><span class="good">Connected</span></td><td>34</td><td>Live in the marketing command center</td></tr><tr><td><b>TikTok</b></td><td><span class="good">Connected</span></td><td>1</td><td>Live in the marketing command center</td></tr><tr><td><b>YouTube</b></td><td><span class="good">Connected</span></td><td>1</td><td>Live in the marketing command center</td></tr><tr><td><b>Bluesky</b></td><td><span class="good">Connected</span></td><td>1</td><td>Live in the marketing command center</td></tr><tr><td><b>Threads</b></td><td><span class="good">Connected</span></td><td>1</td><td>Live in the marketing command center</td></tr><tr><td><b>LinkedIn</b></td><td><span class="good">Connected</span></td><td>1</td><td>Live in the marketing command center</td></tr></tbody></table>
  <div class="cards2">
    <div class="c"><h3>Attribution first</h3><p>Per-channel UTM + coupon discipline before spend scales. Today reach is broad but revenue attribution is dark — no channel can prove its keep.</p></div>
    <div class="c"><h3>New-arrivals engine</h3><p>The activation drip ships ~500 products/day. Each batch is a native "new" story for every channel — content fuel most brands would pay to manufacture.</p></div>
    <div class="c"><h3>AEO / AI answers</h3><p>The flagship already ships AI-answer-optimized collection copy. Extending AEO fleet-wide targets the search channel that's growing while classic SERP flattens.</p></div>
  </div>
</div></section>



<section id="timing"><div class="eyebrow">06 · Timing &amp; 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>11,126</b> in Jul — a 50× 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 81,260 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 (12,482 products) · zero-price actives surface in feeds (1,453) · 277 actives lack a featured image · curation layers (rooms, moods, designer picks) are thin relative to catalog depth.</p></div>
    <div class="c"><h3>Action</h3><p>Fix the integrity backlog (Section 02), then ship a guided-discovery layer: room/mood entry points, "pairs well with" on every PDP, and a designer-picks editorial tier — the concept directions in Section 09 show the face of it.</p></div>
  </div>
</div></section>

<section id="social"><div class="eyebrow">08 · Social Audit</div><h2 class="disp">Broad reach, quiet voice.</h2><div class="accbody">
  <p class="lead2">All major platforms are connected through one command center — a real infrastructure asset. The audit finding is consistent across platforms: <b>distribution exists, engagement discipline doesn't yet</b>. The page network posts; it doesn't yet converse, attribute, or convert.</p>
  <div class="cards2">
    <div class="c"><h3>Connected &amp; ready</h3><p class="good">Facebook Pages · Instagram · TikTok · YouTube · Bluesky · Threads · LinkedIn</p></div>
    <div class="c"><h3>The gap</h3><p class="flag">No per-channel revenue attribution · posting cadence not synced to the activation drip · reels/video formats underused relative to the category (interiors is a visual-first vertical).</p></div>
    <div class="c"><h3>The play</h3><p>One flagship voice + the page network as amplifiers. Daily new-arrival stories (auto-fed by the drip), weekly designer-pick reels, per-channel UTM coupons — measured, not sprayed.</p></div>
  </div>
</div></section>

<section id="suggested"><div class="eyebrow">09 · Suggested New Flagships</div><h2 class="disp">Six directions worthy of the catalog.</h2><div class="accbody">
  <p class="lead2">Six full front-page concepts — each after a house that owns its lane, each a working page with the mandatory sort + density controls on its grid. Not palette swaps: different merchandising philosophies. Open each live and pick the direction.</p>
  <div class="vgrid">
  <a class="vtile rv" href="/versions/atelier.html" target="_blank" style="--vb:#f4f0e6;--vi:#26221a;--vg:#8a7340">
    <div class="vswatch"><span style="background:#f4f0e6"></span><span style="background:#e9e2d0"></span><span style="background:#8a7340"></span><span style="background:#26221a"></span></div>
    <div class="vname">Atelier</div><div class="vmodel">after de Gournay</div>
    <div class="vmood">Scenic-house minimalism — ivory ground, celadon accents, art-object product pages.</div><div class="vopen">Open live concept →</div>
  </a>
  <a class="vtile rv" href="/versions/maison.html" target="_blank" style="--vb:#1c2331;--vi:#f2efe6;--vg:#d9b877">
    <div class="vswatch"><span style="background:#1c2331"></span><span style="background:#26304a"></span><span style="background:#d9b877"></span><span style="background:#f2efe6"></span></div>
    <div class="vname">Maison</div><div class="vmodel">after Pierre Frey</div>
    <div class="vmood">French maison energy — indigo + ochre, pattern-forward editorial storytelling.</div><div class="vopen">Open live concept →</div>
  </a>
  <a class="vtile rv" href="/versions/studio.html" target="_blank" style="--vb:#faf7f2;--vi:#1d1b17;--vg:#d96a3b">
    <div class="vswatch"><span style="background:#faf7f2"></span><span style="background:#f0e9dd"></span><span style="background:#d96a3b"></span><span style="background:#1d1b17"></span></div>
    <div class="vname">Studio</div><div class="vmodel">after Backdrop (DTC)</div>
    <div class="vmood">DTC-playful — bold color blocks, plain language, sample-first funnel.</div><div class="vopen">Open live concept →</div>
  </a>
  <a class="vtile rv" href="/versions/heritage.html" target="_blank" style="--vb:#232820;--vi:#efeee6;--vg:#b7a878">
    <div class="vswatch"><span style="background:#232820"></span><span style="background:#2e352a"></span><span style="background:#b7a878"></span><span style="background:#efeee6"></span></div>
    <div class="vname">Heritage</div><div class="vmodel">after Farrow & Ball</div>
    <div class="vmood">Estate heritage — muted greens, archival typography, room-story merchandising.</div><div class="vopen">Open live concept →</div>
  </a>
  <a class="vtile rv" href="/versions/texture.html" target="_blank" style="--vb:#0f0d0b;--vi:#f1ece3;--vg:#c9a24b">
    <div class="vswatch"><span style="background:#0f0d0b"></span><span style="background:#191510"></span><span style="background:#c9a24b"></span><span style="background:#f1ece3"></span></div>
    <div class="vname">Texture</div><div class="vmodel">after Arte International</div>
    <div class="vmood">Immersive texture — full-bleed material macros, dark gallery chrome, slow motion.</div><div class="vopen">Open live concept →</div>
  </a>
  <a class="vtile rv" href="/versions/gallery.html" target="_blank" style="--vb:#f7f5f1;--vi:#191919;--vg:#a3803c">
    <div class="vswatch"><span style="background:#f7f5f1"></span><span style="background:#ebe7df"></span><span style="background:#a3803c"></span><span style="background:#191919"></span></div>
    <div class="vname">Gallery</div><div class="vmodel">after 1stDibs</div>
    <div class="vmood">Marketplace-luxe — white-gallery ground, curated collections, provenance chips, designer-first navigation.</div><div class="vopen">Open live concept →</div>
  </a></div>
</div></section>

<section id="partners"><div class="eyebrow">10 · Unlikely Partners</div><h2 class="disp">Channels that don't look like channels.</h2><div class="accbody">
  <p class="lead2">Eight partnership lanes where DW's LA position and trade heritage do the acquisition work.</p>
  <div class="pcard rv"><div class="pnum">01</div><div><h4>Interior-design trade programs (ASID, IIDA chapters)</h4><p>The trade IS the buyer. Chapter sponsorships + a designer-net portal turn 30 years of relationships into a structured acquisition channel.</p></div></div><div class="pcard rv"><div class="pnum">02</div><div><h4>Professional installers / paper-hangers network</h4><p>An installer directory referral loop: DW sends install-ready clients, installers send spec-stage clients. Both sides win on every roll.</p></div></div><div class="pcard rv"><div class="pnum">03</div><div><h4>Boutique hotels & hospitality designers</h4><p>Contract lines (Type II) already in catalog — a hospitality lookbook + spec-sheet service opens recurring project-scale orders.</p></div></div><div class="pcard rv"><div class="pnum">04</div><div><h4>Real-estate stagers & luxury listing agents</h4><p>Statement walls sell listings. A stager program (rapid samples + the peel-and-stick line) creates repeat commercial buyers.</p></div></div><div class="pcard rv"><div class="pnum">05</div><div><h4>Art-print & framing houses</h4><p>The art-print line proves the adjacency: walls + art as one "finished room" offer, cross-sold at zero acquisition cost.</p></div></div><div class="pcard rv"><div class="pnum">06</div><div><h4>Paint brands & color consultants</h4><p>Color-matched pairings ("this paper + these three paints") — co-marketing that borrows the paint brand's search volume.</p></div></div><div class="pcard rv"><div class="pnum">07</div><div><h4>Design schools (LA trade programs)</h4><p>Student memo access + a young-designer program seeds the next decade of trade accounts for the cost of samples.</p></div></div><div class="pcard rv"><div class="pnum">08</div><div><h4>Film / TV set decorators</h4><p>LA-native advantage: a set-decorator fast lane (rush memos, buyout-friendly licensing) monetizes proximity to the studios.</p></div></div>
</div></section>

<section id="revenue"><div class="eyebrow">11 · Unlikely Revenue</div><h2 class="disp">The money already in the building.</h2><div class="accbody">
  <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>12,482 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,966</b> active products can be memo-sampled, but only <b>66.6%</b> have a roll a customer can then buy — leaving <b>12,324</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,093 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>
  </div>

  <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,966</div><div class="kl">Products a customer can memo-sample</div></div>
    <div class="kpi"><div class="kv">66.6%</div><div class="kl">…that also have a buyable roll (52,588)</div></div>
    <div class="kpi"><div class="kv">12,324</div><div class="kl">Recoverable dead-ends (sampled intent, no roll)</div></div>
    <div class="kpi"><div class="kv">14,054</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,378</b> products a customer can pay $4.25 to sample but cannot then buy. Of those, <b>14,054</b> are intentionally quote-only, leaving a <b>12,324</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>12,324 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>

  <div class="chartwrap"><div class="ct">Priced-subset architecture (basis: min variant &gt; $4.25 memo — partial, labeled)</div><canvas id="bandChart"></canvas></div>
</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 27, 2026, 8:50 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">81,260</div><div class="kl">Active products</div></div>
    <div class="kpi"><div class="kv">20,093</div><div class="kl">Staged drafts</div></div>
    <div class="kpi"><div class="kv">2,723</div><div class="kl">Stageable today (variant + image)</div></div>
    <div class="kpi"><div class="kv">12,482</div><div class="kl">Sample-only backlog (non-quote)</div></div>
    <div class="kpi"><div class="kv">1,453</div><div class="kl">Zero-price actives</div></div>
    <div class="kpi"><div class="kv">277</div><div class="kl">Image-less actives</div></div>
    <div class="kpi"><div class="kv">175</div><div class="kl">Vendor lines live</div></div>
    <div class="kpi"><div class="kv">271</div><div class="kl">Fleet microsites</div></div>
  </div>
  <div class="chartwrap"><div class="ct">Weekly activation cadence (same data as Section 05 — the desk's pulse line)</div><canvas id="deskChart"></canvas></div>
</div></section>

<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 12,482 sample-only backlog by vendor (top 8 lines = 16,750 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 &lt; 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 &amp; 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>
  </ul>
</div></section>

<section id="sources"><div class="eyebrow">14 · Sources &amp; Methodology</div><h2 class="disp">Where every number comes from.</h2><div class="accbody">
  <p class="lead2">Snapshot collected <b>Jul 27, 2026, 8:50 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 27, 2026, 8:50 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>271 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">&#9881;</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 27, 2026, 8:50 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);})();
var REDUCE=window.matchMedia&&window.matchMedia('(prefers-reduced-motion:reduce)').matches;
function countUp(el){var t=+el.dataset.c;if(!t)return;if(REDUCE){el.textContent=t.toLocaleString();return;}var d=1300,st=null;function step(ts){st=st||ts;var p=Math.min((ts-st)/d,1),e=1-Math.pow(1-p,3);el.textContent=Math.round(t*e).toLocaleString();if(p<1)requestAnimationFrame(step);}requestAnimationFrame(step);}
var secs=[].slice.call(document.querySelectorAll('section[id]'));var accs=[];
secs.forEach(function(sec){var eb=sec.querySelector(':scope>.eyebrow'),h2=sec.querySelector(':scope>h2');if(!eb&&!h2)return;accs.push(sec);
  var head=document.createElement('button');head.type='button';head.className='acchead';var txt=document.createElement('div');txt.className='htext';if(eb)txt.appendChild(eb);if(h2)txt.appendChild(h2);
  var chev=document.createElement('span');chev.className='chev';chev.textContent='+';head.appendChild(txt);head.appendChild(chev);sec.insertBefore(head,sec.querySelector('.accbody'));
  head.addEventListener('click',function(){var open=sec.classList.toggle('open');chev.textContent=open?'\u2013':'+';if(open){initCharts();initMap();drawRoad(sec);}});});
function drawRoad(sec){var rd=sec.querySelector('.road');if(rd)setTimeout(function(){rd.classList.add('drawn');},140);}
function setAll(o){accs.forEach(function(s){s.classList.toggle('open',o);var c=s.querySelector('.chev');if(c)c.textContent=o?'\u2013':'+';if(o)drawRoad(s);});if(o){initCharts();initMap();}}
document.getElementById('xall').onclick=function(){setAll(true);};document.getElementById('call').onclick=function(){setAll(false);};
if(location.hash==='#all'){setAll(true);} // deep-link: /portal#all opens the whole brief
document.querySelectorAll('.menu a[href^="#"]').forEach(function(a){a.addEventListener('click',function(){var id=a.getAttribute('href').slice(1),s=document.getElementById(id);if(s&&!s.classList.contains('open')&&s.querySelector('.acchead')){s.querySelector('.acchead').click();}if(s)setTimeout(function(){s.scrollIntoView({behavior:'smooth'});},80);});});
(function(){var burger=document.querySelector('.burger');if(!burger)return;function sync(){burger.setAttribute('aria-expanded',document.body.classList.contains('nav'));}new MutationObserver(sync).observe(document.body,{attributes:true,attributeFilter:['class']});sync();})();
var io=new IntersectionObserver(function(es){es.forEach(function(e){if(e.isIntersecting){e.target.classList.add('in');io.unobserve(e.target);}});},{threshold:.12});
document.querySelectorAll('.rv').forEach(function(el){io.observe(el);});
document.querySelectorAll('.metrics .v[data-c]').forEach(function(el){var mo=new IntersectionObserver(function(es){es.forEach(function(e){if(e.isIntersecting){countUp(el);mo.unobserve(el);}});});mo.observe(el);});
document.getElementById('refbtn').addEventListener('click',function(){var b=this;b.disabled=true;b.textContent='↻ Refreshing…';fetch('/api/refresh',{method:'POST'}).then(function(r){return r.json();}).then(function(d){if(d.ok){b.textContent='↻ Rebuilt — reloading';setTimeout(function(){location.reload();},600);}else{b.textContent='↻ '+(d.error||'unavailable here');b.disabled=false;}}).catch(function(){b.textContent='↻ Refresh unavailable';b.disabled=false;});});
var charted=false;
function initCharts(){if(charted||!window.Chart)return;charted=true;
  var gold='#c9a24b',dim='rgba(241,236,227,.6)',line='rgba(201,162,75,.08)';Chart.defaults.color='rgba(241,236,227,.55)';Chart.defaults.font.family='Jost,system-ui,sans-serif';Chart.defaults.font.weight=500;Chart.defaults.font.size=11;
  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","07-27"],"added":[490,3,492,924,1993,1510,1854,4269,1499,4045,87]},"vendors":{"labels":["Phillipe Romano","Rebel Walls","Clarke And Clarke","Hollywood Wallcoverings","Malibu Wallpaper","Thibaut","Jeffrey Stevens","Brunschwig & Fils","Kravet","Phillip Jeffries"],"counts":[11823,3770,3570,3535,3232,3000,2912,2760,2616,2469]},"types":{"labels":["Wallcovering","Fabric","Commercial Fabric","Mural","Wallcoverings","Memo Sample"],"counts":[59009,16207,1797,1305,453,451]},"integrity":{"labels":["Missing sellable variant","Missing sample variant","Zero / null price","Missing image","Missing description"],"counts":[26536,2294,1453,277,168]},"bands":{"labels":["Under $50","$50–150","$150–300","$300–600","$600+"],"counts":[2117,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é","Designers Guild","Osborne & Little","Maya Romanoff"],"counts":[6477,2461,2454,1776,1300,840,818,624]},"sampleRoll":{"labels":["Phillipe Romano","Coordonné","Designers Guild","Osborne & Little","Rebel Walls","Arte International","Harlequin","Scalamandre Wallpaper"],"converted":[4064,131,0,113,3276,46,0,464],"leak":[3468,1300,839,818,492,490,481,475]},"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,11126]},"needs":{"labels":["Needs Price","Needs Image","Needs Width","Needs Description"],"counts":[19270,16478,19603,27]},"styles":{"labels":["Contemporary","Textured","Traditional","Geometric","Floral","Grasscloth","Stripe","Mural","Metallic","Damask"],"counts":[32570,29293,22796,11720,10295,9897,9154,4764,3218,1902]},"colors":{"labels":["Beige","White","Gray","Blue","Green","Brown","Black","Gold","Pink","Red"],"counts":[22268,22207,12250,8595,7793,5285,4896,4433,3543,3070],"hex":["#d9c9a8","#f2efe8","#9a9a99","#5a7fa8","#6b8f6d","#8a6a4c","#2b2b2b","#c9a24b","#d3a0a6","#a84a44"]}};
  var TRD={"labels":[],"clicks":[]};
  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
  var htmlLegend={id:'htmlLegend',afterUpdate:function(chart){
    var ul=document.getElementById(chart.canvas.id+'-legend');if(!ul)return;ul.innerHTML='';
    var items=chart.options.plugins.legend.labels.generateLabels(chart);
    var ds=chart.data.datasets[0].data;
    // Total across only the VISIBLE arcs so percentages re-normalize as rows toggle off.
    var total=0;items.forEach(function(it){if(!it.hidden)total+=(+ds[it.index]||0);});
    items.forEach(function(item){
      var val=+ds[item.index]||0;
      var pct=total>0?Math.round(val/total*100):0;
      var li=document.createElement('li');if(item.hidden)li.className='off';
      li.onclick=function(){chart.toggleDataVisibility(item.index);chart.update();};
      var mk=document.createElement('span');mk.className='lgmk';mk.style.background=item.fillStyle;
      var tx=document.createElement('span');tx.className='lgtx';tx.textContent=item.text;
      var vl=document.createElement('span');vl.className='lgvl';
      vl.textContent=item.hidden?'—':(val.toLocaleString()+'  '+pct+'%');
      li.appendChild(mk);li.appendChild(tx);li.appendChild(vl);ul.appendChild(li);
    });
  }};
  // Vertical gold gradient for area fills — scriptable so it re-derives per chart area
  function goldFill(a){return function(c){var ch=c.chart,area=ch.chartArea;if(!area)return 'rgba(201,162,75,.12)';var g=ch.ctx.createLinearGradient(0,area.top,0,area.bottom);g.addColorStop(0,'rgba(201,162,75,'+a+')');g.addColorStop(1,'rgba(201,162,75,0)');return g;};}
  mk('rampChart',{type:'bar',data:{labels:D.monthly.labels,datasets:[{label:'New actives / month',data:D.monthly.added,backgroundColor:function(c){var ch=c.chart,area=ch.chartArea;if(!area)return 'rgba(201,162,75,.7)';var g=ch.ctx.createLinearGradient(0,area.bottom,0,area.top);g.addColorStop(0,'rgba(201,162,75,.25)');g.addColorStop(1,'rgba(201,162,75,.9)');return g;},borderRadius:5}]},options:{responsive:true,maintainAspectRatio:false,scales:{y:{grid:{color:line}},x:{grid:{display:false}}},plugins:{legend:{display:false}}}});
  mk('gscChart',{type:'line',data:{labels:TRD.labels,datasets:[{label:'Organic clicks / month',data:TRD.clicks,borderColor:'#d4647a',backgroundColor:function(c){var ch=c.chart,area=ch.chartArea;if(!area)return 'rgba(212,100,122,.10)';var g=ch.ctx.createLinearGradient(0,area.top,0,area.bottom);g.addColorStop(0,'rgba(212,100,122,.30)');g.addColorStop(1,'rgba(212,100,122,0)');return g;},fill:true,tension:.4,pointRadius:5,pointBackgroundColor:'#d4647a',pointBorderWidth:0}]},options:{responsive:true,maintainAspectRatio:false,scales:{y:{grid:{color:line}},x:{grid:{display:false}}},plugins:{legend:{display:false}}}});
  mk('needsChart',{type:'bar',data:{labels:D.needs.labels,datasets:[{label:'Actives tagged',data:D.needs.counts,backgroundColor:'rgba(212,100,122,.85)',borderRadius:5}]},options:{indexAxis:'y',responsive:true,maintainAspectRatio:false,scales:{x:{grid:{color:line}},y:{grid:{display:false}}},plugins:{legend:{display:false}}}});
  mk('styleChart',{type:'bar',data:{labels:D.styles.labels,datasets:[{label:'Actives tagged',data:D.styles.counts,backgroundColor:'rgba(201,162,75,.72)',borderRadius:5}]},options:{indexAxis:'y',responsive:true,maintainAspectRatio:false,scales:{x:{grid:{color:line}},y:{grid:{display:false}}},plugins:{legend:{display:false}}}});
  mk('colorChart',{type:'doughnut',plugins:[htmlLegend],data:{labels:D.colors.labels,datasets:[{data:D.colors.counts,backgroundColor:D.colors.hex,borderColor:'#0e0c09',borderWidth:2}]},options:{responsive:true,maintainAspectRatio:false,plugins:{legend:{display:false},htmlLegend:{}},cutout:'58%'}});
  mk('vendorChart',{type:'bar',data:{labels:D.vendors.labels,datasets:[{label:'Active products',data:D.vendors.counts,backgroundColor:'rgba(201,162,75,.75)'}]},options:{indexAxis:'y',responsive:true,maintainAspectRatio:false,scales:{x:{grid:{color:line}},y:{grid:{display:false}}},plugins:{legend:{display:false}}}});
  mk('typeChart',{type:'doughnut',plugins:[htmlLegend],data:{labels:D.types.labels,datasets:[{data:D.types.counts,backgroundColor:['#c9a24b','#b78d3f','#a67c32','#d9b877','#8f6d2c','#e3c98d'],borderColor:'#0e0c09',borderWidth:2}]},options:{responsive:true,maintainAspectRatio:false,plugins:{legend:{display:false},htmlLegend:{}},cutout:'58%'}});
  mk('ffChart',{type:'bar',data:{labels:D.integrity.labels,datasets:[{label:'Actives failing',data:D.integrity.counts,backgroundColor:D.integrity.counts.map(function(v){return v>10000?'rgba(212,100,122,.9)':'rgba(201,162,75,.6)';})}]},options:{indexAxis:'y',responsive:true,maintainAspectRatio:false,scales:{x:{grid:{color:line}},y:{grid:{display:false}}},plugins:{legend:{display:false}}}});
  mk('soChart',{type:'bar',data:{labels:D.sampleOnlyVendors.labels,datasets:[{label:'Sample-only actives',data:D.sampleOnlyVendors.counts,backgroundColor:'rgba(212,100,122,.8)'}]},options:{responsive:true,maintainAspectRatio:false,scales:{y:{grid:{color:line}},x:{grid:{display:false}}},plugins:{legend:{display:false}}}});
  mk('srChart',{type:'bar',data:{labels:D.sampleRoll.labels,datasets:[{label:'Roll available (sample converts)',data:D.sampleRoll.converted,backgroundColor:'rgba(201,162,75,.8)',borderRadius:3},{label:'Recoverable backlog (memo, no roll)',data:D.sampleRoll.leak,backgroundColor:'rgba(212,100,122,.85)',borderRadius:3}]},options:{indexAxis:'y',responsive:true,maintainAspectRatio:false,scales:{x:{stacked:true,grid:{color:line}},y:{stacked:true,grid:{display:false}}},plugins:{legend:{labels:{color:dim}}}}});
  mk('compChart',{type:'bar',data:{labels:D.comp.labels,datasets:[{label:'Catalog depth',data:D.comp.catalog,backgroundColor:'rgba(201,162,75,.75)'},{label:'Digital polish',data:D.comp.digital,backgroundColor:'rgba(120,170,255,.6)'}]},options:{responsive:true,maintainAspectRatio:false,scales:{y:{grid:{color:line},max:100},x:{grid:{display:false}}},plugins:{legend:{labels:{color:dim}}}}});
  mk('chanChart',{type:'bar',data:{labels:D.channels.labels,datasets:[{label:'Connected accounts',data:D.channels.accounts,backgroundColor:'rgba(201,162,75,.75)'}]},options:{responsive:true,maintainAspectRatio:false,scales:{y:{grid:{color:line}},x:{grid:{display:false}}},plugins:{legend:{display:false}}}});
  mk('cadenceChart',{type:'line',data:{labels:D.cadence.labels,datasets:[{label:'New actives / week',data:D.cadence.added,borderColor:gold,backgroundColor:goldFill(.30),fill:true,tension:.4,pointRadius:5,pointBackgroundColor:gold,pointBorderWidth:0}]},options:{responsive:true,maintainAspectRatio:false,scales:{y:{grid:{color:line}},x:{grid:{display:false}}},plugins:{legend:{display:false}}}});
  mk('deskChart',{type:'line',data:{labels:D.cadence.labels,datasets:[{label:'New actives / week',data:D.cadence.added,borderColor:gold,backgroundColor:goldFill(.30),fill:true,tension:.4,pointRadius:5,pointBackgroundColor:gold,pointBorderWidth:0}]},options:{responsive:true,maintainAspectRatio:false,scales:{y:{grid:{color:line}},x:{grid:{display:false}}},plugins:{legend:{display:false}}}});
  mk('bandChart',{type:'bar',data:{labels:D.bands.labels,datasets:[{label:'Products (priced subset)',data:D.bands.counts,backgroundColor:'rgba(201,162,75,.6)'}]},options:{responsive:true,maintainAspectRatio:false,scales:{y:{grid:{color:line}},x:{grid:{display:false}}},plugins:{legend:{display:false}}}});
}
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 · 81,260 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});
    mk.bindPopup('<b>'+p.name+'</b><br>'+(p.note||''));mk.addTo(m);});
  setTimeout(function(){m.invalidateSize();},300);
}
</script>
</body></html>