[object Object]

← back to Designerwallcoverings

polish: tech-violet palette, editorial hero, 3-step how-it-works section

7ace0829a0bb8a69a46a17682d6aac7578e12f8f · 2026-05-13 13:52:48 -0700 · steve

Files touched

Diff

commit 7ace0829a0bb8a69a46a17682d6aac7578e12f8f
Author: steve <steve@designerwallcoverings.com>
Date:   Wed May 13 13:52:48 2026 -0700

    polish: tech-violet palette, editorial hero, 3-step how-it-works section
---
 server.js | 66 ++++++++++++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 51 insertions(+), 15 deletions(-)

diff --git a/server.js b/server.js
index 22c7ebc..b4f315c 100644
--- a/server.js
+++ b/server.js
@@ -258,7 +258,7 @@ function topMatches(signal, n = 24) {
 
 function layout({ title, description, body, ogImage }) {
   const pageTitle = `${title} — designerwallcoverings.ai`;
-  const desc = description || 'Upload a room photo. We read its palette + style with Gemini Vision and surface the wallcoverings that fit. Memo samples free.';
+  const desc = description || 'Show us the room. Gemini Vision reads its palette, light, and material story — and surfaces the wallcoverings from our 8,200-SKU library that belong there. Memo samples free.';
   return `<!doctype html>
 <html lang="en">
 <head>
@@ -280,14 +280,14 @@ ${ogImage ? `<meta property="og:image" content="${esc(ogImage)}">` : ''}
 <link rel="preconnect" href="https://cdn.shopify.com">
 <style>
 :root[data-theme="light"] {
-  --bg:#f6f3ed; --fg:#171513; --muted:#6f6759; --rule:#dccec0; --card:#ffffff;
-  --accent:#7d3c00; --accent-soft:#b8865c; --hi:#fff;
-  --shadow:0 8px 32px rgba(0,0,0,.07);
+  --bg:#f7f5fb; --fg:#14121a; --muted:#6a627a; --rule:#d8d3e6; --card:#ffffff;
+  --accent:#5d3dff; --accent-soft:#b4a8ed; --hi:#fff;
+  --shadow:0 10px 40px rgba(40,28,120,.10);
 }
 :root[data-theme="dark"] {
-  --bg:#0e0d0b; --fg:#ece6d8; --muted:#90867a; --rule:#272320; --card:#1a1714;
-  --accent:#d29554; --accent-soft:#7e6238; --hi:#0e0d0b;
-  --shadow:0 8px 32px rgba(0,0,0,.55);
+  --bg:#0b0a14; --fg:#ece8f5; --muted:#8a82a3; --rule:#25212e; --card:#16131f;
+  --accent:#9b7dff; --accent-soft:#5d4ab8; --hi:#0b0a14;
+  --shadow:0 10px 40px rgba(0,0,0,.6);
 }
 * { box-sizing: border-box; margin:0; padding:0; }
 html,body { font-family:-apple-system,'Inter','Segoe UI',system-ui,sans-serif; background:var(--bg); color:var(--fg); line-height:1.55; -webkit-font-smoothing:antialiased; }
@@ -317,7 +317,7 @@ button.theme-toggle:hover { border-color:var(--accent); }
 .dropzone .big { font-family:'Cormorant Garamond',Georgia,serif; font-size:32px; line-height:1.1; margin-bottom:12px; }
 .dropzone .small { color:var(--muted); font-size:14px; margin-bottom:24px; }
 .dropzone button { background:var(--accent); color:#fff; border:0; padding:14px 28px; font-size:13px; letter-spacing:.14em; text-transform:uppercase; font-weight:600; cursor:pointer; }
-.dropzone button:hover { background:#5e2d00; }
+.dropzone button:hover { background:#4528d4; }
 .dropzone input[type=file] { display:none; }
 .preview { display:grid; grid-template-columns:300px 1fr; gap:32px; margin-top:32px; align-items:start; }
 @media (max-width:780px) { .preview { grid-template-columns:1fr; } }
@@ -376,6 +376,20 @@ footer.fp .legal { grid-column:1/-1; padding-top:28px; border-top:1px solid var(
 .sample-pics .pic { aspect-ratio:1/1; background:var(--rule); cursor:pointer; overflow:hidden; transition:transform .12s; }
 .sample-pics .pic:hover { transform:scale(1.04); outline:2px solid var(--accent); }
 .sample-pics .pic img { width:100%; height:100%; object-fit:cover; }
+
+.howitworks { max-width:1480px; margin:0 auto; padding:48px 32px 80px; }
+.howitworks .eyebrow { font-family:'JetBrains Mono','SF Mono',ui-monospace,monospace; font-size:11px; letter-spacing:.22em; text-transform:uppercase; color:var(--accent); margin-bottom:18px; }
+.howitworks h2 { font-family:'Cormorant Garamond',Georgia,serif; font-weight:500; font-size:clamp(28px,4vw,44px); line-height:1.08; letter-spacing:-.005em; max-width:780px; margin-bottom:48px; }
+.howitworks h2 em { font-style:italic; color:var(--accent); }
+.howitworks .steps { display:grid; grid-template-columns:repeat(3,1fr); gap:32px; }
+@media (max-width:880px) { .howitworks .steps { grid-template-columns:1fr; gap:24px; } }
+.howitworks .step { border:1px solid var(--rule); background:var(--card); padding:32px 28px; position:relative; overflow:hidden; }
+.howitworks .step::before { content:""; position:absolute; left:0; top:0; bottom:0; width:3px; background:var(--accent); opacity:0; transition:opacity .15s; }
+.howitworks .step:hover::before { opacity:1; }
+.howitworks .step .n { font-family:'JetBrains Mono','SF Mono',ui-monospace,monospace; font-size:13px; letter-spacing:.18em; color:var(--accent); margin-bottom:18px; }
+.howitworks .step h3 { font-family:'Cormorant Garamond',Georgia,serif; font-weight:500; font-size:26px; line-height:1.12; margin-bottom:10px; }
+.howitworks .step p { font-size:14px; line-height:1.6; color:var(--muted); }
+.howitworks .step .ms { display:inline-block; margin-top:14px; font-family:'JetBrains Mono','SF Mono',ui-monospace,monospace; font-size:10px; letter-spacing:.16em; text-transform:uppercase; color:var(--accent-soft); border:1px solid var(--rule); padding:3px 8px; }
 </style>
 </head>
 <body>
@@ -452,11 +466,9 @@ const SAMPLE_PICKS = PRODUCTS
 app.get('/', (_req, res) => {
   const body = `
     <section class="hero">
-      <div class="kicker">designerwallcoverings.ai · room match</div>
-      <h1>Drop a photo of your room.<br>We'll find the <em>wallcovering</em> that fits.</h1>
-      <p class="lede">An AI vision model reads your room's palette, materials, and mood,
-      then surfaces the wallcoverings from our 8,200+ SKU catalog that match.
-      Memo samples are always free.</p>
+      <div class="kicker">_camera_roll → wallcovering · vision match</div>
+      <h1>Show us the room.<br>We'll find the <em>wallcovering</em>.</h1>
+      <p class="lede">Vision model in, catalog out. One photo of your space — Gemini reads its palette, light, and material story, then surfaces the 24 patterns from our 8,200-SKU library that actually belong there. Memo samples free.</p>
     </section>
     <section class="upload-wrap">
       <div id="zone" class="dropzone" tabindex="0" role="button" aria-label="Upload a room photo">
@@ -475,6 +487,30 @@ app.get('/', (_req, res) => {
         </div>
       </div>
     </section>
+    <section class="howitworks">
+      <div class="eyebrow">_how_it_works</div>
+      <h2>Three steps from a room photo to a <em>wallcovering</em> that belongs there.</h2>
+      <div class="steps">
+        <div class="step">
+          <div class="n">STEP_01 · READ</div>
+          <h3>Gemini Vision reads the room.</h3>
+          <p>One structured pass — dominant colors with hex codes, mood, visible materials, and style descriptors that could match a wallpaper title. Image processed once, never stored.</p>
+          <span class="ms">~2.5s · 1 vision call</span>
+        </div>
+        <div class="step">
+          <div class="n">STEP_02 · MATCH</div>
+          <h3>Score 8,200 SKUs against the read.</h3>
+          <p>Each catalog product is scored on color bucket overlap, style tags, and keyword hits in the title. Color contributes the most; style next. The top 24 surface as a sortable, density-adjustable grid.</p>
+          <span class="ms">~80ms · local index</span>
+        </div>
+        <div class="step">
+          <div class="n">STEP_03 · SAMPLE</div>
+          <h3>Order free memo samples in one click.</h3>
+          <p>Every match links back to the canonical product page on designerwallcoverings.com — order, payment, and shipping live on Shopify. This site is purely the discovery surface.</p>
+          <span class="ms">free · hands back to DW</span>
+        </div>
+      </div>
+    </section>
     <script>
     (function(){
       var zone = document.getElementById('zone');
@@ -602,8 +638,8 @@ app.get('/', (_req, res) => {
   res.set('Cache-Control', 'no-store, must-revalidate')
     .set('Content-Type', 'text/html; charset=utf-8')
     .send(layout({
-      title: 'Match a Room with AI',
-      description: 'Upload a room photo. Gemini Vision reads its palette + style and we surface matching wallcoverings from 8,200+ SKUs. Memo samples free.',
+      title: 'Vision-Match a Room to Wallcovering',
+      description: 'Show us the room. Gemini Vision reads its palette, light, and material story — and surfaces the 24 wallcoverings from the 8,200-SKU Designer Wallcoverings catalog that actually belong there. Memo samples free.',
       body,
     }));
 });

← 579e226 dw site: log Gemini image-classify usage to cost-tracker  ·  back to Designerwallcoverings  ·  scrub vendor name leaks from products.json source (176 produ b4b5920 →