← back to Stars of Design
polish: editorial 2-line hero + by-era anthology section
f86aef56675bfd7a5b3c0ed5cf2da56aaa566a63 · 2026-05-13 14:25:08 -0700 · Steve Abrams
Hero — replace single-line tagline with 2-line italic editorial
headline ("The designers who set the room. / The wallcoverings that
set the tone.") plus 1-line sans subtitle naming Draper through
Wearstler. Bumps tagline color to #f0e3b8 + text-shadow for stronger
APCA on the dark hero ground.
New "By the era" section between the directory grid and the editorial
two-col. Four cards (Early 20th / Mid-Century / Late 20th /
Contemporary) each with a gold hairline rule, era blurb, 3 exemplar
designer names, and a count-deep-link to /designers?era=<bucket>.
Specific to the directory vertical — gives the homepage a real
"anthology by era" identity instead of template-fresh blocks.
Server passes eraIndex into the home view as a single in-memory
pass over data.load() — no DB hit. Hero-readability-auditor passes
APCA Lc 100/99 desktop/mobile, well above the 75 threshold.
Files touched
M public/css/site.cssM routes/public.jsM views/public/home.ejs
Diff
commit f86aef56675bfd7a5b3c0ed5cf2da56aaa566a63
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed May 13 14:25:08 2026 -0700
polish: editorial 2-line hero + by-era anthology section
Hero — replace single-line tagline with 2-line italic editorial
headline ("The designers who set the room. / The wallcoverings that
set the tone.") plus 1-line sans subtitle naming Draper through
Wearstler. Bumps tagline color to #f0e3b8 + text-shadow for stronger
APCA on the dark hero ground.
New "By the era" section between the directory grid and the editorial
two-col. Four cards (Early 20th / Mid-Century / Late 20th /
Contemporary) each with a gold hairline rule, era blurb, 3 exemplar
designer names, and a count-deep-link to /designers?era=<bucket>.
Specific to the directory vertical — gives the homepage a real
"anthology by era" identity instead of template-fresh blocks.
Server passes eraIndex into the home view as a single in-memory
pass over data.load() — no DB hit. Hero-readability-auditor passes
APCA Lc 100/99 desktop/mobile, well above the 75 threshold.
---
public/css/site.css | 96 +++++++++++++++++++++++++++++++++++++++++++++++++--
routes/public.js | 30 ++++++++++++++++
views/public/home.ejs | 31 ++++++++++++++++-
3 files changed, 153 insertions(+), 4 deletions(-)
diff --git a/public/css/site.css b/public/css/site.css
index 4205954..736d88b 100644
--- a/public/css/site.css
+++ b/public/css/site.css
@@ -164,10 +164,21 @@ html[data-theme='dark'] .theme-toggle-sun { display: none; }
font-family: var(--font-serif);
font-style: italic;
font-weight: 300;
- font-size: clamp(1rem, 1.9vw, 1.5rem);
+ font-size: clamp(1.05rem, 2.1vw, 1.6rem);
+ line-height: 1.35;
letter-spacing: .01em;
- color: #d9c89a; margin: 0;
- max-width: 56ch;
+ color: #f0e3b8; margin: 0;
+ max-width: 64ch;
+ text-shadow: 0 1px 18px rgba(0,0,0,.55);
+}
+.hero-gucci-subtitle {
+ font-family: var(--font-sans);
+ font-weight: 400;
+ font-size: clamp(.92rem, 1.15vw, 1.05rem);
+ letter-spacing: .02em;
+ color: #cdb98a; margin: .35rem 0 0;
+ max-width: 64ch;
+ line-height: 1.55;
}
.hero-gucci-cta { margin-top: 1.25rem; display: flex; gap: .9rem; flex-wrap: wrap; justify-content: center; }
.hero-gucci-cta .btn.primary { background: #f4ecd6; color: #0a0907; border-color: transparent; }
@@ -464,3 +475,82 @@ html[data-theme='dark'] .theme-toggle-sun { display: none; }
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
overflow: hidden;
}
+
+/* "By the era" editorial mini-index on the homepage.
+ Four cards in a row, each linking to /designers?era=<bucket>. Gold hairline
+ rule at top of each card; serif heading; sans body; gold deep-link arrow. */
+.era-section { background: var(--surface-1, #faf7f1); }
+[data-theme="dark"] .era-section { background: #14110b; }
+.era-section-lede {
+ font-family: var(--font-serif);
+ font-style: italic;
+ font-size: 1.05rem;
+ color: var(--muted-fg, #5a5346);
+ max-width: 70ch;
+ margin: -.5rem 0 1.75rem;
+}
+[data-theme="dark"] .era-section-lede { color: #b6a986; }
+.era-grid {
+ display: grid;
+ grid-template-columns: repeat(4, minmax(0, 1fr));
+ gap: 1.25rem;
+}
+@media (max-width: 980px) { .era-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
+@media (max-width: 560px) { .era-grid { grid-template-columns: 1fr; } }
+.era-card {
+ display: flex; flex-direction: column; gap: .6rem;
+ padding: 1.25rem 1.1rem 1.1rem;
+ background: var(--card-bg, #fff);
+ border: 1px solid var(--border, rgba(0,0,0,.08));
+ border-radius: 4px;
+ color: inherit; text-decoration: none;
+ transition: transform .18s ease, border-color .18s ease, box-shadow .18s ease;
+ position: relative;
+}
+[data-theme="dark"] .era-card { background: #1c1810; border-color: rgba(217,168,104,.18); }
+.era-card:hover {
+ transform: translateY(-2px);
+ border-color: var(--gold, #d9a868);
+ box-shadow: 0 6px 22px rgba(0,0,0,.06);
+ text-decoration: none;
+}
+.era-card-rule {
+ display: block; height: 2px; width: 38px;
+ background: var(--gold, #d9a868);
+ margin-bottom: .15rem;
+}
+.era-card-title {
+ font-family: var(--font-serif);
+ font-weight: 500;
+ font-size: 1.25rem;
+ margin: 0; line-height: 1.2;
+ letter-spacing: .005em;
+}
+.era-card-blurb {
+ font-family: var(--font-sans);
+ font-size: .88rem;
+ color: var(--muted-fg, #5a5346);
+ line-height: 1.5;
+ margin: 0;
+}
+[data-theme="dark"] .era-card-blurb { color: #c0b591; }
+.era-card-names {
+ list-style: none; padding: 0; margin: .15rem 0 0;
+ display: flex; flex-direction: column; gap: .15rem;
+ font-family: var(--font-serif);
+ font-style: italic;
+ font-size: .95rem;
+ color: var(--text-fg, #2a261e);
+}
+[data-theme="dark"] .era-card-names { color: #ece2c5; }
+.era-card-count {
+ margin-top: auto;
+ font-family: var(--font-sans);
+ font-size: .78rem;
+ letter-spacing: .08em;
+ text-transform: uppercase;
+ color: var(--gold, #d9a868);
+ font-weight: 500;
+ padding-top: .65rem;
+ border-top: 1px dotted rgba(217,168,104,.35);
+}
diff --git a/routes/public.js b/routes/public.js
index f14d8d6..e1bbb0c 100644
--- a/routes/public.js
+++ b/routes/public.js
@@ -91,10 +91,39 @@ router.get('/api/health', async (_req, res) => {
}
});
+// Editorial era index for the homepage — four anchored era cards (Early 20th,
+// Mid-Century, Late 20th, Contemporary) with a count and three exemplar
+// names per era, each linking to /designers?era=<bucket>. Built once at
+// request time from the in-memory dataset; cheap, no DB hit.
+const ERA_ORDER = ['Early 20th Century', 'Mid-Century', 'Late 20th Century', 'Contemporary'];
+const ERA_BLURB = {
+ 'Early 20th Century': 'When the profession of decoration was invented — chintz, pale silk, the Edith Wharton school.',
+ 'Mid-Century': 'Plaster, jungle prints, glazed bamboo — the era of Draper, Frances Elkins, and the Greenbrier.',
+ 'Late 20th Century': 'Chintz on chintz on chintz — Buatta, Hicks, Denning & Fourcade, the maximalist American salon.',
+ 'Contemporary': 'The working bench today — Wearstler, McGee, Vervoordt, Tarlow — pattern paired to current practice.',
+};
+function buildEraIndex(all) {
+ const buckets = {};
+ for (const d of all) {
+ if (!d.era) continue;
+ (buckets[d.era] = buckets[d.era] || []).push(d.name);
+ }
+ return ERA_ORDER
+ .filter((era) => buckets[era] && buckets[era].length)
+ .map((era) => ({
+ era,
+ blurb: ERA_BLURB[era] || '',
+ count: buckets[era].length,
+ exemplars:buckets[era].slice(0, 3),
+ href: `/designers?era=${encodeURIComponent(era)}`,
+ }));
+}
+
router.get('/', (req, res, next) => {
try {
const all = data.load();
const sortKey = SORTS[req.query.sort] ? req.query.sort : 'newest';
+ const eraIndex = buildEraIndex(all);
// WebSite + Organization JSON-LD. SearchAction declares the site's
// search endpoint to Google for sitelinks search-box eligibility.
// /designers acts as the search target (it accepts ?q=).
@@ -130,6 +159,7 @@ router.get('/', (req, res, next) => {
total: all.length,
sortKey,
filter: {},
+ eraIndex,
json_ld,
});
} catch (e) { next(e); }
diff --git a/views/public/home.ejs b/views/public/home.ejs
index fba0b09..4b25c84 100644
--- a/views/public/home.ejs
+++ b/views/public/home.ejs
@@ -10,7 +10,11 @@
<div class="hero-gucci-stars" aria-hidden="true"></div>
<div class="hero-gucci-stack">
<h1 id="hero-wordmark" class="hero-gucci-wordmark">Stars of Design</h1>
- <p class="hero-gucci-tagline"><em>The designers who shape interiors — and the walls behind them.</em></p>
+ <p class="hero-gucci-tagline">
+ <em>The designers who set the room.</em><br>
+ <em>The wallcoverings that set the tone.</em>
+ </p>
+ <p class="hero-gucci-subtitle">A working atlas of 150 interior designers — Draper through Wearstler — paired to the patterns they'd actually hang.</p>
<div class="hero-gucci-cta">
<a class="btn primary" href="/designers">Browse the directory →</a>
<a class="btn ghost" href="/about">How it works</a>
@@ -52,6 +56,31 @@
</div>
</section>
+ <% if (typeof eraIndex !== 'undefined' && eraIndex && eraIndex.length) { %>
+ <section class="section era-section" id="by-era">
+ <div class="wrap">
+ <div class="section-head">
+ <h2>By the era</h2>
+ <a class="muted" href="/designers">Filter the directory →</a>
+ </div>
+ <p class="era-section-lede">A working anthology, decade by decade — the designers who defined each chapter of the modern American interior, and the wallcoverings they put on the walls.</p>
+ <div class="era-grid">
+ <% eraIndex.forEach(function (e) { %>
+ <a class="era-card" href="<%= e.href %>">
+ <span class="era-card-rule" aria-hidden="true"></span>
+ <h3 class="era-card-title"><%= e.era %></h3>
+ <p class="era-card-blurb"><%= e.blurb %></p>
+ <ul class="era-card-names">
+ <% e.exemplars.forEach(function (n) { %><li><%= n %></li><% }) %>
+ </ul>
+ <span class="era-card-count"><%= e.count %> designer<%= e.count === 1 ? '' : 's' %> →</span>
+ </a>
+ <% }); %>
+ </div>
+ </div>
+ </section>
+ <% } %>
+
<section class="section alt">
<div class="wrap two-col">
<div>
← 03cea56 smoke: assert /api/{designers,firms,clients}/featured SWR Ca
·
back to Stars of Design
·
smoke: /api/health perf budget 500→1000ms af307bc →