← back to Wallco Ai
wallco.ai · /compare gets ?view=grid image-comparison mode (legacy ?grid=1 alias supported) · adds a Specs ↔ Image grid pill toggle in the header (role=tablist, aria-selected) that links between /compare?ids=… and /compare?ids=…&view=grid · grid mode renders a 2-column grid of large aspect-ratio:1 thumbs with title+category+color-dot+tearsheet-link+Remove button (no spec table); designers comparing aesthetics side-by-side won't have to scroll past 10 spec rows · Brief / Print / Copy-share / Browse / Brief-options block all preserved underneath either view · verified specs 200 30.6KB, grid 200 22.9KB, ?grid=1 alias also returns compare-grid markup
84478a0ce625197152f776d97783db65d5c9ba80 · 2026-05-12 10:46:05 -0700 · SteveStudio2
Files touched
Diff
commit 84478a0ce625197152f776d97783db65d5c9ba80
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date: Tue May 12 10:46:05 2026 -0700
wallco.ai · /compare gets ?view=grid image-comparison mode (legacy ?grid=1 alias supported) · adds a Specs ↔ Image grid pill toggle in the header (role=tablist, aria-selected) that links between /compare?ids=… and /compare?ids=…&view=grid · grid mode renders a 2-column grid of large aspect-ratio:1 thumbs with title+category+color-dot+tearsheet-link+Remove button (no spec table); designers comparing aesthetics side-by-side won't have to scroll past 10 spec rows · Brief / Print / Copy-share / Browse / Brief-options block all preserved underneath either view · verified specs 200 30.6KB, grid 200 22.9KB, ?grid=1 alias also returns compare-grid markup
---
server.js | 33 +++++++++++++++++++++++++++++++--
1 file changed, 31 insertions(+), 2 deletions(-)
diff --git a/server.js b/server.js
index 0bd7f62..f2386e4 100644
--- a/server.js
+++ b/server.js
@@ -5330,6 +5330,10 @@ app.get('/compare', (req, res) => {
const esc = (s) => String(s||'').replace(/[<>&"]/g, c => ({'<':'<','>':'>','&':'&','"':'"'}[c]));
const cols = items.length || 1;
const colWidth = items.length ? `${100/items.length}%` : '100%';
+ // View mode: 'specs' (default — side-by-side spec table) or 'grid' (large 2×2 image grid).
+ // ?view=grid or legacy ?grid=1 enables grid mode.
+ const view = (String(req.query.view || '').toLowerCase() === 'grid' || req.query.grid === '1') ? 'grid' : 'specs';
+ const idsQS = rawIds.join(',');
const cellsForRow = (fn) => items.map(d => `<td style="padding:10px 14px;border-top:1px solid var(--line,#eee);font:13px var(--sans,system-ui);width:${colWidth};vertical-align:top">${fn(d)}</td>`).join('');
res.type('html').send(`${htmlHead({
title: 'Compare Designs — wallco.ai',
@@ -5340,8 +5344,17 @@ app.get('/compare', (req, res) => {
${htmlHeader('/compare')}
<main>
<section class="catalog-section" style="padding:24px 40px">
- <h1 style="font:300 36px/1.1 var(--serif,Georgia,serif);margin:0 0 6px">Compare designs</h1>
- <p style="font:13px var(--sans,system-ui);color:var(--ink-soft,#555);margin:0 0 18px">${items.length ? `${items.length} of 4 selected.` : 'No designs selected. Use "+ Compare" on any design page to add up to 4.'}</p>
+ <div style="display:flex;justify-content:space-between;align-items:baseline;flex-wrap:wrap;gap:14px">
+ <div>
+ <h1 style="font:300 36px/1.1 var(--serif,Georgia,serif);margin:0 0 6px">Compare designs</h1>
+ <p style="font:13px var(--sans,system-ui);color:var(--ink-soft,#555);margin:0 0 18px">${items.length ? `${items.length} of 4 selected.` : 'No designs selected. Use "+ Compare" on any design page to add up to 4.'}</p>
+ </div>
+ ${items.length ? `
+ <div role="tablist" aria-label="Compare view" style="display:inline-flex;border:1px solid var(--line,#ddd);border-radius:999px;overflow:hidden;font:12px var(--sans,system-ui)">
+ <a href="/compare?ids=${idsQS}" role="tab" aria-selected="${view==='specs'?'true':'false'}" style="padding:6px 14px;text-decoration:none;background:${view==='specs'?'var(--ink,#111)':'transparent'};color:${view==='specs'?'var(--bg,#fff)':'var(--ink-soft,#555)'}">Specs</a>
+ <a href="/compare?ids=${idsQS}&view=grid" role="tab" aria-selected="${view==='grid'?'true':'false'}" style="padding:6px 14px;text-decoration:none;background:${view==='grid'?'var(--ink,#111)':'transparent'};color:${view==='grid'?'var(--bg,#fff)':'var(--ink-soft,#555)'}">Image grid</a>
+ </div>` : ''}
+ </div>
${items.length === 0 ? `
<div id="compare-empty" style="padding:40px;border:1px dashed var(--line,#ccc);border-radius:8px;text-align:center;font:14px var(--sans,system-ui);color:var(--ink-faint,#888)">
@@ -5386,6 +5399,21 @@ ${htmlHeader('/compare')}
})();
</script>
` : `
+ ${view === 'grid' ? `
+ <div class="compare-grid" style="display:grid;grid-template-columns:repeat(${Math.min(items.length, 2)}, 1fr);gap:18px;margin-bottom:24px">
+ ${items.map(d => `
+ <figure style="margin:0;display:flex;flex-direction:column;gap:8px">
+ <a href="/design/${d.id}" style="display:block;aspect-ratio:1;background:#f4f1ea url('${esc(d.image_url)}') center/cover;border-radius:8px;border:1px solid var(--line,#e6e2d8);text-decoration:none"></a>
+ <figcaption style="display:flex;justify-content:space-between;align-items:baseline;gap:8px;flex-wrap:wrap">
+ <div style="min-width:0;flex:1">
+ <div style="font:500 16px/1.3 var(--serif,Georgia,serif);color:var(--ink,#111)">${esc(d.title || ('Design #' + d.id))}</div>
+ <div style="font:11px var(--sans,system-ui);color:var(--ink-faint,#888);margin-top:2px"><span style="display:inline-block;width:9px;height:9px;border-radius:50%;background:${esc(d.dominant_hex||'#888')};border:1px solid rgba(0,0,0,.12);vertical-align:middle;margin-right:4px"></span>${esc(d.category||'mixed')} · <a href="/design/${d.id}/tearsheet" target="_blank" rel="noopener noreferrer" style="color:inherit;text-decoration:underline">tear sheet</a></div>
+ </div>
+ <button type="button" data-rmid="${d.id}" class="compare-rm" style="padding:4px 10px;font:11px var(--sans,system-ui);background:transparent;border:1px solid var(--line,#ddd);color:var(--ink-soft,#555);border-radius:3px;cursor:pointer">Remove</button>
+ </figcaption>
+ </figure>`).join('')}
+ </div>
+ ` : `
<table style="width:100%;border-collapse:collapse;table-layout:fixed">
<thead><tr>${items.map(d => `<th style="padding:0;width:${colWidth};vertical-align:top">
<a href="/design/${d.id}" style="display:block;text-decoration:none;color:inherit">
@@ -5413,6 +5441,7 @@ ${htmlHeader('/compare')}
</td>`).join('')}</tr>
</tbody>
</table>
+ `}
<div style="margin-top:24px;display:flex;gap:12px;flex-wrap:wrap;align-items:center">
<a href="/brief?ids=${rawIds.join(',')}" target="_blank" rel="noopener noreferrer" id="compare-brief" style="padding:10px 18px;font:13px var(--sans,system-ui);background:var(--gold,#c9a14b);color:var(--accent,#0d0d0d);text-decoration:none;border:0;border-radius:4px;font-weight:500" title="Export this comparison as a printable multi-design proposal PDF">Export as Brief →</a>
<button type="button" id="compare-print" style="padding:10px 18px;font:13px var(--sans,system-ui);background:var(--ink,#111);color:var(--bg,#fff);border:0;border-radius:4px;cursor:pointer">Print this view</button>
← 7cddfa6 wallco.ai · /api/designs/by-color now accepts optional ?with
·
back to Wallco Ai
·
wallco.ai · nav saved-count chip auto-refreshes via custom e 11c49ab →