← back to Dw Domain Fleet
Add /info page, trim navpanel to 4 items, sun/moon theme toggle
26f2aef016b6a94f9177aca71a3088b51ed39fc6 · 2026-05-19 08:51:30 -0700 · SteveStudio2
TASK 1: New per-site /info page (infoPage in shared/render.js + /info
route in server.js) — Memo Samples, Trade Program, Shipping & Lead
Times, FAQ. cfg-driven, no vendor names, no banned 'wallpaper' word,
rel=canonical to the site's own /info.
TASK 2: Navpanel now exactly 4 items — Designs, About, Info, Contact.
TASK 3: Theme toggle shows a sun in light mode, moon in dark mode —
both SVGs in the button, swapped via CSS keyed on html[data-theme=dark],
no JS change so it survives the anti-flash inline script.
Verified: node -c passes both files; grassclothwallcovering booted on
:10999 — /, /info, /about, /catalog all 200; /info renders all 4
sections; nav shows the 4 items; no 'wallpaper' in /info copy.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Files touched
M server.jsM shared/render.js
Diff
commit 26f2aef016b6a94f9177aca71a3088b51ed39fc6
Author: SteveStudio2 <steve@designerwallcoverings.com>
Date: Tue May 19 08:51:30 2026 -0700
Add /info page, trim navpanel to 4 items, sun/moon theme toggle
TASK 1: New per-site /info page (infoPage in shared/render.js + /info
route in server.js) — Memo Samples, Trade Program, Shipping & Lead
Times, FAQ. cfg-driven, no vendor names, no banned 'wallpaper' word,
rel=canonical to the site's own /info.
TASK 2: Navpanel now exactly 4 items — Designs, About, Info, Contact.
TASK 3: Theme toggle shows a sun in light mode, moon in dark mode —
both SVGs in the button, swapped via CSS keyed on html[data-theme=dark],
no JS change so it survives the anti-flash inline script.
Verified: node -c passes both files; grassclothwallcovering booted on
:10999 — /, /info, /about, /catalog all 200; /info renders all 4
sections; nav shows the 4 items; no 'wallpaper' in /info copy.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---
server.js | 4 +++
shared/render.js | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 83 insertions(+), 7 deletions(-)
diff --git a/server.js b/server.js
index 82f57d5..caf7ff4 100644
--- a/server.js
+++ b/server.js
@@ -103,6 +103,10 @@ app.get('/about', (req, res) => {
res.type('html').send(render.aboutPage(cfg));
});
+app.get('/info', (req, res) => {
+ res.type('html').send(render.infoPage(cfg));
+});
+
app.get('/health', (req, res) => {
res.json({ ok: true, site: SITE, domain: cfg.domain, niche: NICHE.length, serving: POOL.length });
});
diff --git a/shared/render.js b/shared/render.js
index 1259af9..2164980 100644
--- a/shared/render.js
+++ b/shared/render.js
@@ -59,7 +59,11 @@ img{display:block;max-width:100%}
.navpanel.open{right:0}
.navpanel a{display:block;padding:13px 0;font-size:14px;letter-spacing:.06em;text-transform:uppercase;
border-bottom:1px solid rgba(255,255,255,.1)}
-.theme-toggle{background:transparent;border:0;cursor:pointer;color:var(--top-fg,#fff);padding:4px}
+.theme-toggle{background:transparent;border:0;cursor:pointer;color:var(--top-fg,#fff);padding:4px;
+ display:inline-flex;align-items:center}
+.theme-toggle .icon-moon{display:none}
+html[data-theme=dark] .theme-toggle .icon-sun{display:none}
+html[data-theme=dark] .theme-toggle .icon-moon{display:inline-block}
/* hero */
.cinema{position:relative;width:100%;min-height:clamp(560px,90vh,1080px);overflow:hidden;background:#111}
@@ -141,8 +145,10 @@ function chrome(cfg) {
<a class="brand" href="/">${esc(cfg.siteName)}</a>
<div style="display:flex;gap:14px;align-items:center">
<button class="theme-toggle" id="themeBtn" aria-label="Toggle theme">
- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
+ <svg class="icon-sun" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<circle cx="12" cy="12" r="5"/><path d="M12 1v2M12 21v2M4.2 4.2l1.4 1.4M18.4 18.4l1.4 1.4M1 12h2M21 12h2M4.2 19.8l1.4-1.4M18.4 5.6l1.4-1.4"/></svg>
+ <svg class="icon-moon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
+ <path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"/></svg>
</button>
</div>
</div>
@@ -151,12 +157,10 @@ function chrome(cfg) {
<span class="gucci-menu__label">Menu</span>
</button>
<nav class="navpanel" id="navpanel">
- <a href="/">Home</a>
- <a href="/catalog">Catalog</a>
+ <a href="/catalog">Designs</a>
<a href="/about">About</a>
- <a href="${DW}/pages/trade">Trade Program</a>
+ <a href="/info">Info</a>
<a href="mailto:${esc(cfg.siteEmail)}">Contact</a>
- <a href="${DW}">Designer Wallcoverings</a>
</nav>`;
}
@@ -350,6 +354,74 @@ function aboutPage(cfg){
${footer(cfg)}${script(cfg)}</body></html>`;
}
+/* ---------- info page ----------
+ * Per-site informational page: memo samples, trade program, shipping &
+ * lead times, and a short FAQ. Driven entirely by cfg so it reads well for
+ * any fleet site. rel=canonical points to this site's own /info.
+ */
+function infoPage(cfg){
+ const title=`Info — ${cfg.siteName}`;
+ const niche=clean(cfg.nicheLabel);
+ const desc=`Memo samples, trade program, shipping and lead times for ${clean(cfg.siteName)} — ${niche} from a Sherman Oaks design house.`;
+ const sec=(h,body)=>`
+ <section style="margin:34px 0;padding-bottom:30px;border-bottom:1px solid var(--rule)">
+ <h2 style="font-family:var(--serif);font-size:clamp(24px,3vw,34px);margin-bottom:12px">${h}</h2>
+ ${body}
+ </section>`;
+ const faq=[
+ ['Do memo samples cost anything?',
+ `No. Memo samples are free and mailed to you so you can judge colour, texture, and scale in your own light before committing.`],
+ ['How many samples can I request?',
+ `Request as many as your project needs. We would rather you see every ${niche} option in person than guess from a screen.`],
+ ['Can you help me choose?',
+ `Yes. Our team hand-holds every order — share your room, lighting, and palette and we will narrow the field with you.`],
+ ['Do you work with designers and architects?',
+ `Absolutely — the trade program below is built for designers, architects, and specifiers.`]
+ ];
+ return head(cfg,title,desc,'/info')+jsonld(cfg)+chrome(cfg)+`
+<div style="height:84px"></div>
+<div class="wrap" style="max-width:820px">
+ <div class="hero-mark" style="padding:40px 0 6px"><h1>Information</h1>
+ <p>${esc(clean(cfg.siteName))} · ${esc(niche)}</p></div>
+
+ ${sec('Memo Samples', `
+ <p style="font-size:16px;line-height:1.8;color:var(--fg)">
+ Every pattern in our catalogue ships with a <strong>free memo sample</strong> — a mailed
+ swatch you can hold against your wall, in your own light, before you order a single roll.
+ Browse the catalogue, request the swatches that interest you, and we will put them in the
+ post. There is no charge and no obligation.</p>
+ <p style="margin-top:16px"><a class="hero-cta__btn" style="position:static;background:var(--accent);color:#fff" href="/catalog">Browse & Request Samples</a></p>`)}
+
+ ${sec('Trade Program', `
+ <p style="font-size:16px;line-height:1.8;color:var(--fg)">
+ Designers, architects, and specifiers receive trade pricing, priority memo-sample
+ handling, and a dedicated point of contact for every project. If you work in the
+ trade, enrol once and the pricing applies across the full ${esc(niche)} collection.</p>
+ <p style="margin-top:14px"><a href="${DW}/pages/trade" rel="noopener noreferrer"
+ style="color:var(--accent);font-weight:500">View the Trade Program →</a></p>`)}
+
+ ${sec('Shipping & Lead Times', `
+ <p style="font-size:16px;line-height:1.8;color:var(--fg)">
+ Memo samples typically ship within one to two business days. Full orders are made to
+ order — most ${esc(niche)} ship in roughly two to four weeks, though hand-finished and
+ specialty lines can take longer. We confirm the lead time for your specific selection
+ before the order is placed, and our team keeps you posted from selection through
+ delivery and installation. We ship across the United States.</p>`)}
+
+ ${sec('Frequently Asked', faq.map(([q,a])=>`
+ <div style="margin:16px 0">
+ <div style="font-family:var(--serif);font-size:19px;color:var(--fg)">${q}</div>
+ <p style="font-size:15px;line-height:1.75;color:var(--muted);margin-top:5px">${a}</p>
+ </div>`).join(''))}
+
+ <p style="margin:6px 0 60px;font-size:15px;color:var(--muted);line-height:1.8">
+ Still have a question? Email
+ <a href="mailto:${esc(cfg.siteEmail)}" style="color:var(--accent)">${esc(cfg.siteEmail)}</a>
+ and a real person will answer.</p>
+</div>
+${footer(cfg)}${script(cfg)}</body></html>`;
+}
+
function footer(cfg){
return `<footer><div class="wrap">
<div><div class="fb">${esc(cfg.siteName)}</div>
@@ -479,4 +551,4 @@ ${script(cfg)}
</body></html>`;
}
-module.exports = { homePage, catalogPage, aboutPage, productPage, clean, esc };
+module.exports = { homePage, catalogPage, aboutPage, infoPage, productPage, clean, esc };
← 40eaabd DNS cutover batch 4 (idx 27-35): 9/9 live HTTPS 200
·
back to Dw Domain Fleet
·
DNS cutover batch 5 (idx 36-43): 8/8 live HTTPS 200 — fleet 8b73567 →