[object Object]

← back to Rentv

rentv-v1: 10 full site VERSIONS (distinct homepage layouts on live data) + /versions picker — Wire/Broadsheet/Terminal/Magazine/Digest/Grid/Split/Dashboard/Minimal/Feed for Boomer to pick a direction

6b7158a3632b0dfa6bdba95a13b86a308523413e · 2026-07-21 15:03:52 -0700 · Steve Abrams

Files touched

Diff

commit 6b7158a3632b0dfa6bdba95a13b86a308523413e
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Tue Jul 21 15:03:52 2026 -0700

    rentv-v1: 10 full site VERSIONS (distinct homepage layouts on live data) + /versions picker — Wire/Broadsheet/Terminal/Magazine/Digest/Grid/Split/Dashboard/Minimal/Feed for Boomer to pick a direction
---
 data/markets.json               |  2 +-
 data/news.json                  |  2 +-
 data/ticker.json                |  2 +-
 public/versions/broadsheet.html | 24 ++++++++++++
 public/versions/dashboard.html  | 24 ++++++++++++
 public/versions/digest.html     | 24 ++++++++++++
 public/versions/feed.html       | 24 ++++++++++++
 public/versions/grid.html       | 24 ++++++++++++
 public/versions/index.html      | 33 ++++++++++++++++
 public/versions/magazine.html   | 24 ++++++++++++
 public/versions/minimal.html    | 24 ++++++++++++
 public/versions/render.js       | 81 ++++++++++++++++++++++++++++++++++++++
 public/versions/split.html      | 24 ++++++++++++
 public/versions/terminal.html   | 24 ++++++++++++
 public/versions/wire.html       | 24 ++++++++++++
 server.js                       |  2 +
 versions.mjs                    | 87 +++++++++++++++++++++++++++++++++++++++++
 17 files changed, 446 insertions(+), 3 deletions(-)

diff --git a/data/markets.json b/data/markets.json
index eacbbef2..70eed234 100644
--- a/data/markets.json
+++ b/data/markets.json
@@ -1,5 +1,5 @@
 {
-  "fetched_at": "2026-07-21T21:43:33.955Z",
+  "fetched_at": "2026-07-21T22:03:35.067Z",
   "source": "Yahoo Finance — live (CBOE Treasury yields, Dow Jones/MSCI REIT indices)",
   "curve": [
     {
diff --git a/data/news.json b/data/news.json
index efdfe0e2..de1d25ad 100644
--- a/data/news.json
+++ b/data/news.json
@@ -1,6 +1,6 @@
 {
  "source": "rentv.com — live",
- "fetched_at": "2026-07-21T21:43:33.625Z",
+ "fetched_at": "2026-07-21T22:03:34.763Z",
  "count": 30,
  "items": [
   {
diff --git a/data/ticker.json b/data/ticker.json
index 4a73fd72..ac5df199 100644
--- a/data/ticker.json
+++ b/data/ticker.json
@@ -1,5 +1,5 @@
 {
-  "fetched_at": "2026-07-21T21:43:33.928Z",
+  "fetched_at": "2026-07-21T22:03:35.030Z",
   "la_office_vac": {
     "label": "LA OFFICE VAC",
     "value": "23.1%",
diff --git a/public/versions/broadsheet.html b/public/versions/broadsheet.html
new file mode 100644
index 00000000..ed603fbf
--- /dev/null
+++ b/public/versions/broadsheet.html
@@ -0,0 +1,24 @@
+<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
+<title>RENTV — Broadsheet (version)</title><meta name="description" content="Dense two-column serif columns, small images — a printed newspaper on the web.">
+<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=Playfair+Display:wght@400;700&family=Newsreader:wght@400;700&family=Libre+Franklin:wght@400;600;800&family=Source+Serif+4:wght@400;700&family=IBM+Plex+Serif:wght@400;700&family=IBM+Plex+Sans:wght@400;600;700&family=DM+Serif+Display&family=Archivo:wght@400;600;800&family=Spectral:wght@400;700&family=Space+Grotesk:wght@400;700&family=Fraunces:wght@400;700&family=Lora:wght@400;700&family=Inter:wght@300;400;600;800&display=swap" rel="stylesheet">
+<style>
+:root{--a:#8b1a1a;--ink:#111;--sub:#555;--ln:#d6cfc4;--bg:#faf7f2;--wa:#f0ece4;--se:'Newsreader',Georgia,serif;--sa:'Libre Franklin',system-ui,sans-serif}
+*{box-sizing:border-box;margin:0;padding:0}body{font-family:var(--sa);background:var(--bg);color:var(--ink);line-height:1.5}
+a{color:inherit;text-decoration:none}.wrap{max-width:1180px;margin:0 auto;padding:0 20px}
+.vbar{background:var(--ink);color:var(--bg);font-size:12px}.vbar .wrap{display:flex;justify-content:space-between;align-items:center;height:36px}
+.vbar a{color:var(--bg);opacity:.85}.vbar b{color:var(--a)}
+.mast{border-bottom:2px solid var(--ink);padding:18px 0 12px;text-align:center}
+.logo{font-family:var(--se);font-weight:700;font-size:40px;letter-spacing:-1px}.logo span{color:var(--a)}
+.logo small{display:block;font-family:var(--sa);font-size:10px;letter-spacing:3px;text-transform:uppercase;color:var(--sub);margin-top:3px}
+.chip{display:inline-block;font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:var(--a)}
+.byl{font-size:12px;color:var(--sub)}
+h1,h2,h3,h4{font-family:var(--se);font-weight:700;line-height:1.14}
+#app{padding:26px 0 60px;min-height:50vh}.load{color:var(--sub);padding:40px 0}
+.imgph{background:linear-gradient(135deg,var(--wa),var(--ln));border-radius:6px}
+footer{border-top:1px solid var(--ln);color:var(--sub);font-size:12px;padding:26px 0;text-align:center}
+</style></head><body data-ver="broadsheet">
+<div class="vbar"><div class="wrap"><span>RENTV · Version — <b>Broadsheet</b></span><a href="/versions">← compare all 10 versions</a></div></div>
+<header class="mast"><div class="wrap"><a class="logo" href="/">REN<span>TV</span>.com<small>Commercial Real Estate News · Broadsheet</small></a></div></header>
+<div class="wrap"><main id="app"><div class="load">Loading live rentv.com stories…</div></main></div>
+<footer><div class="wrap">RENTV.com · version preview · live data from rentv.com — <a href="/versions" style="color:var(--a)">back to all versions</a></div></footer>
+<script src="/versions/render.js"></script></body></html>
\ No newline at end of file
diff --git a/public/versions/dashboard.html b/public/versions/dashboard.html
new file mode 100644
index 00000000..e83d9ed0
--- /dev/null
+++ b/public/versions/dashboard.html
@@ -0,0 +1,24 @@
+<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
+<title>RENTV — Market Dashboard (version)</title><meta name="description" content="Metrics band on top, then the news list beside live market cards.">
+<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=Playfair+Display:wght@400;700&family=Newsreader:wght@400;700&family=Libre+Franklin:wght@400;600;800&family=Source+Serif+4:wght@400;700&family=IBM+Plex+Serif:wght@400;700&family=IBM+Plex+Sans:wght@400;600;700&family=DM+Serif+Display&family=Archivo:wght@400;600;800&family=Spectral:wght@400;700&family=Space+Grotesk:wght@400;700&family=Fraunces:wght@400;700&family=Lora:wght@400;700&family=Inter:wght@300;400;600;800&display=swap" rel="stylesheet">
+<style>
+:root{--a:#c9a84c;--ink:#f0f2f5;--sub:#8fa3b8;--ln:#1e2d40;--bg:#0d1b2a;--wa:#132336;--se:'DM Serif Display',Georgia,serif;--sa:'Archivo',system-ui,sans-serif}
+*{box-sizing:border-box;margin:0;padding:0}body{font-family:var(--sa);background:var(--bg);color:var(--ink);line-height:1.5}
+a{color:inherit;text-decoration:none}.wrap{max-width:1180px;margin:0 auto;padding:0 20px}
+.vbar{background:var(--ink);color:var(--bg);font-size:12px}.vbar .wrap{display:flex;justify-content:space-between;align-items:center;height:36px}
+.vbar a{color:var(--bg);opacity:.85}.vbar b{color:var(--a)}
+.mast{border-bottom:2px solid var(--ink);padding:18px 0 12px;text-align:center}
+.logo{font-family:var(--se);font-weight:700;font-size:40px;letter-spacing:-1px}.logo span{color:var(--a)}
+.logo small{display:block;font-family:var(--sa);font-size:10px;letter-spacing:3px;text-transform:uppercase;color:var(--sub);margin-top:3px}
+.chip{display:inline-block;font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:var(--a)}
+.byl{font-size:12px;color:var(--sub)}
+h1,h2,h3,h4{font-family:var(--se);font-weight:700;line-height:1.14}
+#app{padding:26px 0 60px;min-height:50vh}.load{color:var(--sub);padding:40px 0}
+.imgph{background:linear-gradient(135deg,var(--wa),var(--ln));border-radius:6px}
+footer{border-top:1px solid var(--ln);color:var(--sub);font-size:12px;padding:26px 0;text-align:center}
+</style></head><body data-ver="dashboard">
+<div class="vbar"><div class="wrap"><span>RENTV · Version — <b>Market Dashboard</b></span><a href="/versions">← compare all 10 versions</a></div></div>
+<header class="mast"><div class="wrap"><a class="logo" href="/">REN<span>TV</span>.com<small>Commercial Real Estate News · Market Dashboard</small></a></div></header>
+<div class="wrap"><main id="app"><div class="load">Loading live rentv.com stories…</div></main></div>
+<footer><div class="wrap">RENTV.com · version preview · live data from rentv.com — <a href="/versions" style="color:var(--a)">back to all versions</a></div></footer>
+<script src="/versions/render.js"></script></body></html>
\ No newline at end of file
diff --git a/public/versions/digest.html b/public/versions/digest.html
new file mode 100644
index 00000000..3d02412f
--- /dev/null
+++ b/public/versions/digest.html
@@ -0,0 +1,24 @@
+<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
+<title>RENTV — Daily Digest (version)</title><meta name="description" content="Numbered compact headline list — reads like the morning email.">
+<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=Playfair+Display:wght@400;700&family=Newsreader:wght@400;700&family=Libre+Franklin:wght@400;600;800&family=Source+Serif+4:wght@400;700&family=IBM+Plex+Serif:wght@400;700&family=IBM+Plex+Sans:wght@400;600;700&family=DM+Serif+Display&family=Archivo:wght@400;600;800&family=Spectral:wght@400;700&family=Space+Grotesk:wght@400;700&family=Fraunces:wght@400;700&family=Lora:wght@400;700&family=Inter:wght@300;400;600;800&display=swap" rel="stylesheet">
+<style>
+:root{--a:#2d5a27;--ink:#1a1a14;--sub:#5a5a40;--ln:#d8d8b8;--bg:#fdfde6;--wa:#f5f5d0;--se:'Lora',Georgia,serif;--sa:'IBM Plex Sans',system-ui,sans-serif}
+*{box-sizing:border-box;margin:0;padding:0}body{font-family:var(--sa);background:var(--bg);color:var(--ink);line-height:1.5}
+a{color:inherit;text-decoration:none}.wrap{max-width:1180px;margin:0 auto;padding:0 20px}
+.vbar{background:var(--ink);color:var(--bg);font-size:12px}.vbar .wrap{display:flex;justify-content:space-between;align-items:center;height:36px}
+.vbar a{color:var(--bg);opacity:.85}.vbar b{color:var(--a)}
+.mast{border-bottom:2px solid var(--ink);padding:18px 0 12px;text-align:center}
+.logo{font-family:var(--se);font-weight:700;font-size:40px;letter-spacing:-1px}.logo span{color:var(--a)}
+.logo small{display:block;font-family:var(--sa);font-size:10px;letter-spacing:3px;text-transform:uppercase;color:var(--sub);margin-top:3px}
+.chip{display:inline-block;font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:var(--a)}
+.byl{font-size:12px;color:var(--sub)}
+h1,h2,h3,h4{font-family:var(--se);font-weight:700;line-height:1.14}
+#app{padding:26px 0 60px;min-height:50vh}.load{color:var(--sub);padding:40px 0}
+.imgph{background:linear-gradient(135deg,var(--wa),var(--ln));border-radius:6px}
+footer{border-top:1px solid var(--ln);color:var(--sub);font-size:12px;padding:26px 0;text-align:center}
+</style></head><body data-ver="digest">
+<div class="vbar"><div class="wrap"><span>RENTV · Version — <b>Daily Digest</b></span><a href="/versions">← compare all 10 versions</a></div></div>
+<header class="mast"><div class="wrap"><a class="logo" href="/">REN<span>TV</span>.com<small>Commercial Real Estate News · Daily Digest</small></a></div></header>
+<div class="wrap"><main id="app"><div class="load">Loading live rentv.com stories…</div></main></div>
+<footer><div class="wrap">RENTV.com · version preview · live data from rentv.com — <a href="/versions" style="color:var(--a)">back to all versions</a></div></footer>
+<script src="/versions/render.js"></script></body></html>
\ No newline at end of file
diff --git a/public/versions/feed.html b/public/versions/feed.html
new file mode 100644
index 00000000..87651611
--- /dev/null
+++ b/public/versions/feed.html
@@ -0,0 +1,24 @@
+<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
+<title>RENTV — Big Feed (version)</title><meta name="description" content="One column of large-image stories you scroll — mobile-native, bold.">
+<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=Playfair+Display:wght@400;700&family=Newsreader:wght@400;700&family=Libre+Franklin:wght@400;600;800&family=Source+Serif+4:wght@400;700&family=IBM+Plex+Serif:wght@400;700&family=IBM+Plex+Sans:wght@400;600;700&family=DM+Serif+Display&family=Archivo:wght@400;600;800&family=Spectral:wght@400;700&family=Space+Grotesk:wght@400;700&family=Fraunces:wght@400;700&family=Lora:wght@400;700&family=Inter:wght@300;400;600;800&display=swap" rel="stylesheet">
+<style>
+:root{--a:#e82535;--ink:#f2f2f2;--sub:#9aa0a8;--ln:#2e3540;--bg:#181c22;--wa:#22282f;--se:'Playfair Display',Georgia,serif;--sa:'Inter',system-ui,sans-serif}
+*{box-sizing:border-box;margin:0;padding:0}body{font-family:var(--sa);background:var(--bg);color:var(--ink);line-height:1.5}
+a{color:inherit;text-decoration:none}.wrap{max-width:1180px;margin:0 auto;padding:0 20px}
+.vbar{background:var(--ink);color:var(--bg);font-size:12px}.vbar .wrap{display:flex;justify-content:space-between;align-items:center;height:36px}
+.vbar a{color:var(--bg);opacity:.85}.vbar b{color:var(--a)}
+.mast{border-bottom:2px solid var(--ink);padding:18px 0 12px;text-align:center}
+.logo{font-family:var(--se);font-weight:700;font-size:40px;letter-spacing:-1px}.logo span{color:var(--a)}
+.logo small{display:block;font-family:var(--sa);font-size:10px;letter-spacing:3px;text-transform:uppercase;color:var(--sub);margin-top:3px}
+.chip{display:inline-block;font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:var(--a)}
+.byl{font-size:12px;color:var(--sub)}
+h1,h2,h3,h4{font-family:var(--se);font-weight:700;line-height:1.14}
+#app{padding:26px 0 60px;min-height:50vh}.load{color:var(--sub);padding:40px 0}
+.imgph{background:linear-gradient(135deg,var(--wa),var(--ln));border-radius:6px}
+footer{border-top:1px solid var(--ln);color:var(--sub);font-size:12px;padding:26px 0;text-align:center}
+</style></head><body data-ver="feed">
+<div class="vbar"><div class="wrap"><span>RENTV · Version — <b>Big Feed</b></span><a href="/versions">← compare all 10 versions</a></div></div>
+<header class="mast"><div class="wrap"><a class="logo" href="/">REN<span>TV</span>.com<small>Commercial Real Estate News · Big Feed</small></a></div></header>
+<div class="wrap"><main id="app"><div class="load">Loading live rentv.com stories…</div></main></div>
+<footer><div class="wrap">RENTV.com · version preview · live data from rentv.com — <a href="/versions" style="color:var(--a)">back to all versions</a></div></footer>
+<script src="/versions/render.js"></script></body></html>
\ No newline at end of file
diff --git a/public/versions/grid.html b/public/versions/grid.html
new file mode 100644
index 00000000..9060f93e
--- /dev/null
+++ b/public/versions/grid.html
@@ -0,0 +1,24 @@
+<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
+<title>RENTV — Photo Grid (version)</title><meta name="description" content="Uniform image-forward card grid. Every story equal, visual-first.">
+<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=Playfair+Display:wght@400;700&family=Newsreader:wght@400;700&family=Libre+Franklin:wght@400;600;800&family=Source+Serif+4:wght@400;700&family=IBM+Plex+Serif:wght@400;700&family=IBM+Plex+Sans:wght@400;600;700&family=DM+Serif+Display&family=Archivo:wght@400;600;800&family=Spectral:wght@400;700&family=Space+Grotesk:wght@400;700&family=Fraunces:wght@400;700&family=Lora:wght@400;700&family=Inter:wght@300;400;600;800&display=swap" rel="stylesheet">
+<style>
+:root{--a:#1a3a6b;--ink:#0f1923;--sub:#5a6474;--ln:#e0e4eb;--bg:#fff;--wa:#f2f4f8;--se:'Source Serif 4',Georgia,serif;--sa:'Archivo',system-ui,sans-serif}
+*{box-sizing:border-box;margin:0;padding:0}body{font-family:var(--sa);background:var(--bg);color:var(--ink);line-height:1.5}
+a{color:inherit;text-decoration:none}.wrap{max-width:1180px;margin:0 auto;padding:0 20px}
+.vbar{background:var(--ink);color:var(--bg);font-size:12px}.vbar .wrap{display:flex;justify-content:space-between;align-items:center;height:36px}
+.vbar a{color:var(--bg);opacity:.85}.vbar b{color:var(--a)}
+.mast{border-bottom:2px solid var(--ink);padding:18px 0 12px;text-align:center}
+.logo{font-family:var(--se);font-weight:700;font-size:40px;letter-spacing:-1px}.logo span{color:var(--a)}
+.logo small{display:block;font-family:var(--sa);font-size:10px;letter-spacing:3px;text-transform:uppercase;color:var(--sub);margin-top:3px}
+.chip{display:inline-block;font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:var(--a)}
+.byl{font-size:12px;color:var(--sub)}
+h1,h2,h3,h4{font-family:var(--se);font-weight:700;line-height:1.14}
+#app{padding:26px 0 60px;min-height:50vh}.load{color:var(--sub);padding:40px 0}
+.imgph{background:linear-gradient(135deg,var(--wa),var(--ln));border-radius:6px}
+footer{border-top:1px solid var(--ln);color:var(--sub);font-size:12px;padding:26px 0;text-align:center}
+</style></head><body data-ver="grid">
+<div class="vbar"><div class="wrap"><span>RENTV · Version — <b>Photo Grid</b></span><a href="/versions">← compare all 10 versions</a></div></div>
+<header class="mast"><div class="wrap"><a class="logo" href="/">REN<span>TV</span>.com<small>Commercial Real Estate News · Photo Grid</small></a></div></header>
+<div class="wrap"><main id="app"><div class="load">Loading live rentv.com stories…</div></main></div>
+<footer><div class="wrap">RENTV.com · version preview · live data from rentv.com — <a href="/versions" style="color:var(--a)">back to all versions</a></div></footer>
+<script src="/versions/render.js"></script></body></html>
\ No newline at end of file
diff --git a/public/versions/index.html b/public/versions/index.html
new file mode 100644
index 00000000..851f92f1
--- /dev/null
+++ b/public/versions/index.html
@@ -0,0 +1,33 @@
+<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
+<title>RENTV — 10 Site Versions</title><link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;700&family=Inter:wght@400;600;800&display=swap" rel="stylesheet">
+<style>*{box-sizing:border-box;margin:0;padding:0}body{font-family:'Inter',system-ui,sans-serif;background:#0c1016;color:#eef1f6;line-height:1.5}
+.wrap{max-width:1180px;margin:0 auto;padding:0 22px}.hd{padding:44px 0 10px;text-align:center}
+.hd h1{font-family:'Playfair Display',serif;font-size:clamp(30px,5vw,52px)}.hd h1 span{color:#c8102e}
+.hd p{color:#aeb6bd;margin-top:10px}.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:18px;padding:30px 0 60px}
+.vc{background:#121722;border:1px solid rgba(255,255,255,.08);border-radius:10px;padding:22px;transition:.2s;display:block}
+.vc:hover{transform:translateY(-4px);border-color:#c8102e;box-shadow:0 18px 44px rgba(0,0,0,.4)}
+.sw{display:flex;height:40px;border-radius:6px;overflow:hidden;border:1px solid;margin-bottom:16px}.sw span{flex:1}
+.vc h3{font-family:'Playfair Display',serif;font-size:22px}.vc p{color:#aeb6bd;font-size:14px;margin:6px 0 12px}
+.vc .go{color:#c8102e;font-size:12px;font-weight:800;text-transform:uppercase;letter-spacing:.08em}</style></head><body>
+<header class="hd"><div class="wrap"><h1>REN<span>TV</span> · 10 Site Versions</h1><p>Ten complete directions for rentv.com — different layouts, not just colors. Open each; they all run on the live news feed. Pick the one that feels right.</p></div></header>
+<div class="wrap"><div class="grid"><a class="vc" href="/versions/wire">
+  <div class="sw" style="background:#fff;border-color:#e4e7ea"><span style="background:#c8102e"></span><span style="background:#14171a"></span><span style="background:#5b636b"></span><span style="background:#f5f6f8"></span></div>
+  <h3>The Wire</h3><p>Lead story + 3-column card river + right rail. The modern newsroom default.</p><span class="go">Open version →</span></a><a class="vc" href="/versions/broadsheet">
+  <div class="sw" style="background:#faf7f2;border-color:#d6cfc4"><span style="background:#8b1a1a"></span><span style="background:#111"></span><span style="background:#555"></span><span style="background:#f0ece4"></span></div>
+  <h3>Broadsheet</h3><p>Dense two-column serif columns, small images — a printed newspaper on the web.</p><span class="go">Open version →</span></a><a class="vc" href="/versions/terminal">
+  <div class="sw" style="background:#0a0f0a;border-color:#1e3a1e"><span style="background:#ff6600"></span><span style="background:#e8ffe8"></span><span style="background:#7fbf7f"></span><span style="background:#111a11"></span></div>
+  <h3>Terminal</h3><p>Dark, data-first deal rows with category tags — the CRE data-desk look.</p><span class="go">Open version →</span></a><a class="vc" href="/versions/magazine">
+  <div class="sw" style="background:#fdf8f3;border-color:#e0d4c8"><span style="background:#b84a1e"></span><span style="background:#1e1712"></span><span style="background:#6b5a4e"></span><span style="background:#f5ede3"></span></div>
+  <h3>Magazine</h3><p>One oversized hero feature + two secondaries. Editorial and image-led.</p><span class="go">Open version →</span></a><a class="vc" href="/versions/digest">
+  <div class="sw" style="background:#fdfde6;border-color:#d8d8b8"><span style="background:#2d5a27"></span><span style="background:#1a1a14"></span><span style="background:#5a5a40"></span><span style="background:#f5f5d0"></span></div>
+  <h3>Daily Digest</h3><p>Numbered compact headline list — reads like the morning email.</p><span class="go">Open version →</span></a><a class="vc" href="/versions/grid">
+  <div class="sw" style="background:#fff;border-color:#e0e4eb"><span style="background:#1a3a6b"></span><span style="background:#0f1923"></span><span style="background:#5a6474"></span><span style="background:#f2f4f8"></span></div>
+  <h3>Photo Grid</h3><p>Uniform image-forward card grid. Every story equal, visual-first.</p><span class="go">Open version →</span></a><a class="vc" href="/versions/split">
+  <div class="sw" style="background:#fff1e5;border-color:#d4c9b8"><span style="background:#00538b"></span><span style="background:#1a1a1a"></span><span style="background:#5c5c5c"></span><span style="background:#fde8d1"></span></div>
+  <h3>Split Desk</h3><p>Headlines column on the left, Most-Read + Markets rail on the right. No big hero.</p><span class="go">Open version →</span></a><a class="vc" href="/versions/dashboard">
+  <div class="sw" style="background:#0d1b2a;border-color:#1e2d40"><span style="background:#c9a84c"></span><span style="background:#f0f2f5"></span><span style="background:#8fa3b8"></span><span style="background:#132336"></span></div>
+  <h3>Market Dashboard</h3><p>Metrics band on top, then the news list beside live market cards.</p><span class="go">Open version →</span></a><a class="vc" href="/versions/minimal">
+  <div class="sw" style="background:#f8f9fb;border-color:#dce0e6"><span style="background:#3a5a8c"></span><span style="background:#1c2330"></span><span style="background:#586070"></span><span style="background:#edf0f4"></span></div>
+  <h3>Minimal</h3><p>Single centered column, generous whitespace, quiet typography.</p><span class="go">Open version →</span></a><a class="vc" href="/versions/feed">
+  <div class="sw" style="background:#181c22;border-color:#2e3540"><span style="background:#e82535"></span><span style="background:#f2f2f2"></span><span style="background:#9aa0a8"></span><span style="background:#22282f"></span></div>
+  <h3>Big Feed</h3><p>One column of large-image stories you scroll — mobile-native, bold.</p><span class="go">Open version →</span></a></div></div></body></html>
\ No newline at end of file
diff --git a/public/versions/magazine.html b/public/versions/magazine.html
new file mode 100644
index 00000000..89949d49
--- /dev/null
+++ b/public/versions/magazine.html
@@ -0,0 +1,24 @@
+<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
+<title>RENTV — Magazine (version)</title><meta name="description" content="One oversized hero feature + two secondaries. Editorial and image-led.">
+<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=Playfair+Display:wght@400;700&family=Newsreader:wght@400;700&family=Libre+Franklin:wght@400;600;800&family=Source+Serif+4:wght@400;700&family=IBM+Plex+Serif:wght@400;700&family=IBM+Plex+Sans:wght@400;600;700&family=DM+Serif+Display&family=Archivo:wght@400;600;800&family=Spectral:wght@400;700&family=Space+Grotesk:wght@400;700&family=Fraunces:wght@400;700&family=Lora:wght@400;700&family=Inter:wght@300;400;600;800&display=swap" rel="stylesheet">
+<style>
+:root{--a:#b84a1e;--ink:#1e1712;--sub:#6b5a4e;--ln:#e0d4c8;--bg:#fdf8f3;--wa:#f5ede3;--se:'Fraunces',Georgia,serif;--sa:'Libre Franklin',system-ui,sans-serif}
+*{box-sizing:border-box;margin:0;padding:0}body{font-family:var(--sa);background:var(--bg);color:var(--ink);line-height:1.5}
+a{color:inherit;text-decoration:none}.wrap{max-width:1180px;margin:0 auto;padding:0 20px}
+.vbar{background:var(--ink);color:var(--bg);font-size:12px}.vbar .wrap{display:flex;justify-content:space-between;align-items:center;height:36px}
+.vbar a{color:var(--bg);opacity:.85}.vbar b{color:var(--a)}
+.mast{border-bottom:2px solid var(--ink);padding:18px 0 12px;text-align:center}
+.logo{font-family:var(--se);font-weight:700;font-size:40px;letter-spacing:-1px}.logo span{color:var(--a)}
+.logo small{display:block;font-family:var(--sa);font-size:10px;letter-spacing:3px;text-transform:uppercase;color:var(--sub);margin-top:3px}
+.chip{display:inline-block;font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:var(--a)}
+.byl{font-size:12px;color:var(--sub)}
+h1,h2,h3,h4{font-family:var(--se);font-weight:700;line-height:1.14}
+#app{padding:26px 0 60px;min-height:50vh}.load{color:var(--sub);padding:40px 0}
+.imgph{background:linear-gradient(135deg,var(--wa),var(--ln));border-radius:6px}
+footer{border-top:1px solid var(--ln);color:var(--sub);font-size:12px;padding:26px 0;text-align:center}
+</style></head><body data-ver="magazine">
+<div class="vbar"><div class="wrap"><span>RENTV · Version — <b>Magazine</b></span><a href="/versions">← compare all 10 versions</a></div></div>
+<header class="mast"><div class="wrap"><a class="logo" href="/">REN<span>TV</span>.com<small>Commercial Real Estate News · Magazine</small></a></div></header>
+<div class="wrap"><main id="app"><div class="load">Loading live rentv.com stories…</div></main></div>
+<footer><div class="wrap">RENTV.com · version preview · live data from rentv.com — <a href="/versions" style="color:var(--a)">back to all versions</a></div></footer>
+<script src="/versions/render.js"></script></body></html>
\ No newline at end of file
diff --git a/public/versions/minimal.html b/public/versions/minimal.html
new file mode 100644
index 00000000..65cde12e
--- /dev/null
+++ b/public/versions/minimal.html
@@ -0,0 +1,24 @@
+<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
+<title>RENTV — Minimal (version)</title><meta name="description" content="Single centered column, generous whitespace, quiet typography.">
+<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=Playfair+Display:wght@400;700&family=Newsreader:wght@400;700&family=Libre+Franklin:wght@400;600;800&family=Source+Serif+4:wght@400;700&family=IBM+Plex+Serif:wght@400;700&family=IBM+Plex+Sans:wght@400;600;700&family=DM+Serif+Display&family=Archivo:wght@400;600;800&family=Spectral:wght@400;700&family=Space+Grotesk:wght@400;700&family=Fraunces:wght@400;700&family=Lora:wght@400;700&family=Inter:wght@300;400;600;800&display=swap" rel="stylesheet">
+<style>
+:root{--a:#3a5a8c;--ink:#1c2330;--sub:#586070;--ln:#dce0e6;--bg:#f8f9fb;--wa:#edf0f4;--se:'Spectral',Georgia,serif;--sa:'Space Grotesk',system-ui,sans-serif}
+*{box-sizing:border-box;margin:0;padding:0}body{font-family:var(--sa);background:var(--bg);color:var(--ink);line-height:1.5}
+a{color:inherit;text-decoration:none}.wrap{max-width:1180px;margin:0 auto;padding:0 20px}
+.vbar{background:var(--ink);color:var(--bg);font-size:12px}.vbar .wrap{display:flex;justify-content:space-between;align-items:center;height:36px}
+.vbar a{color:var(--bg);opacity:.85}.vbar b{color:var(--a)}
+.mast{border-bottom:2px solid var(--ink);padding:18px 0 12px;text-align:center}
+.logo{font-family:var(--se);font-weight:700;font-size:40px;letter-spacing:-1px}.logo span{color:var(--a)}
+.logo small{display:block;font-family:var(--sa);font-size:10px;letter-spacing:3px;text-transform:uppercase;color:var(--sub);margin-top:3px}
+.chip{display:inline-block;font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:var(--a)}
+.byl{font-size:12px;color:var(--sub)}
+h1,h2,h3,h4{font-family:var(--se);font-weight:700;line-height:1.14}
+#app{padding:26px 0 60px;min-height:50vh}.load{color:var(--sub);padding:40px 0}
+.imgph{background:linear-gradient(135deg,var(--wa),var(--ln));border-radius:6px}
+footer{border-top:1px solid var(--ln);color:var(--sub);font-size:12px;padding:26px 0;text-align:center}
+</style></head><body data-ver="minimal">
+<div class="vbar"><div class="wrap"><span>RENTV · Version — <b>Minimal</b></span><a href="/versions">← compare all 10 versions</a></div></div>
+<header class="mast"><div class="wrap"><a class="logo" href="/">REN<span>TV</span>.com<small>Commercial Real Estate News · Minimal</small></a></div></header>
+<div class="wrap"><main id="app"><div class="load">Loading live rentv.com stories…</div></main></div>
+<footer><div class="wrap">RENTV.com · version preview · live data from rentv.com — <a href="/versions" style="color:var(--a)">back to all versions</a></div></footer>
+<script src="/versions/render.js"></script></body></html>
\ No newline at end of file
diff --git a/public/versions/render.js b/public/versions/render.js
new file mode 100644
index 00000000..b3188aab
--- /dev/null
+++ b/public/versions/render.js
@@ -0,0 +1,81 @@
+/* rentv-v1 version renderer — one file, 10 distinct homepage layouts. Reads
+   document.body.dataset.ver and renders that layout from the live /api/news feed. */
+(function () {
+  var ver = document.body.dataset.ver || 'wire';
+  var esc = function (s) { return (s || '').replace(/[&<>"]/g, function (c) { return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' }[c]; }); };
+  var href = function (x) { return '/news/' + encodeURIComponent(x.id); };
+  var img = function (x, cls) { return x && x.image ? '<div class="' + (cls || 'imgph') + '" style="background:#12161a url(\'' + esc(x.image) + '\') center/cover"></div>' : '<div class="' + (cls || 'imgph') + '"></div>'; };
+  var css = function (t) { var s = document.createElement('style'); s.textContent = t; document.head.appendChild(s); };
+
+  var L = {
+    // 1. THE WIRE — lead + 3-col cards + rail
+    wire: function (a) {
+      css('.g{display:grid;grid-template-columns:1fr 300px;gap:34px}.lead .imgph{aspect-ratio:16/8;margin-bottom:12px}.lead h1{font-size:34px;margin:8px 0}.cards{display:grid;grid-template-columns:1fr 1fr 1fr;gap:20px;margin-top:24px}.cards .imgph{aspect-ratio:16/10}.cards h4{font-size:16px;margin:8px 0 4px}.mr{list-style:none;counter-reset:n}.mr li{counter-increment:n;display:flex;gap:10px;padding:10px 0;border-bottom:1px solid var(--ln)}.mr li:before{content:counter(n);color:var(--a);font-family:var(--se);font-size:24px}.mr a{font-size:14px;font-weight:600}@media(max-width:820px){.g{grid-template-columns:1fr}.cards{grid-template-columns:1fr 1fr}}');
+      var lead = a[0], rest = a.slice(1, 13);
+      return '<div class="g"><div><a class="lead" href="' + href(lead) + '">' + img(lead) + '<span class="chip">' + esc(lead.cat) + '</span><h1>' + esc(lead.title) + '</h1><div class="byl">RENTV Staff · live</div></a><div class="cards">' +
+        rest.map(function (x) { return '<a href="' + href(x) + '">' + img(x) + '<span class="chip">' + esc(x.cat) + '</span><h4>' + esc(x.title) + '</h4></a>'; }).join('') + '</div></div>' +
+        '<aside><h3 style="border-top:3px solid var(--ink);padding-top:8px">Most Read</h3><ol class="mr">' + a.slice(0, 6).map(function (x) { return '<li><a href="' + href(x) + '">' + esc(x.title) + '</a></li>'; }).join('') + '</ol></aside></div>';
+    },
+    // 2. BROADSHEET — dense two-column serif
+    broadsheet: function (a) {
+      css('.bs{column-count:2;column-gap:40px}.bs .it{break-inside:avoid;padding:14px 0;border-bottom:1px solid var(--ln)}.bs h3{font-size:21px;margin-bottom:4px}.bs .imgph{aspect-ratio:16/9;margin-bottom:8px}.bs .it:first-child{column-span:all;text-align:center;border-bottom:3px double var(--ink);padding-bottom:20px}.bs .it:first-child h3{font-size:36px}@media(max-width:720px){.bs{column-count:1}}');
+      return '<div class="bs">' + a.slice(0, 16).map(function (x, i) { return '<div class="it"><span class="chip">' + esc(x.cat) + '</span><a href="' + href(x) + '"><h3>' + esc(x.title) + '</h3></a>' + (i < 4 ? img(x) : '') + '<div class="byl">RENTV Staff</div></a></div>'; }).join('') + '</div>';
+    },
+    // 3. TERMINAL — dark data rows
+    terminal: function (a) {
+      css('.tm{font-family:var(--sa)}.tr{display:grid;grid-template-columns:90px 1fr 120px;gap:14px;align-items:center;padding:12px 10px;border-bottom:1px solid var(--ln)}.tr:hover{background:var(--wa)}.tr .c{font-size:11px;font-weight:800;text-transform:uppercase;color:var(--a);letter-spacing:.05em}.tr h4{font-size:15px;font-weight:600;font-family:var(--sa)}.tr .id{text-align:right;color:var(--sub);font-size:12px}.tmh{display:grid;grid-template-columns:90px 1fr 120px;gap:14px;padding:8px 10px;border-bottom:2px solid var(--a);font-size:11px;text-transform:uppercase;letter-spacing:.1em;color:var(--sub)}');
+      return '<div class="tm"><div class="tmh"><span>Sector</span><span>Headline</span><span style="text-align:right">Ref</span></div>' +
+        a.slice(0, 22).map(function (x) { return '<a class="tr" href="' + href(x) + '"><span class="c">' + esc(x.cat) + '</span><h4>' + esc(x.title) + '</h4><span class="id">#' + esc(x.id) + '</span></a>'; }).join('') + '</div>';
+    },
+    // 4. MAGAZINE — giant hero + 2 secondaries
+    magazine: function (a) {
+      css('.mg .hero{position:relative;border-radius:10px;overflow:hidden;aspect-ratio:16/7}.mg .hero .imgph{position:absolute;inset:0;border-radius:0}.mg .hero .ov{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:flex-end;padding:34px;background:linear-gradient(0deg,rgba(0,0,0,.72),transparent 65%);color:#fff}.mg .hero h1{font-size:clamp(28px,4vw,48px);max-width:20ch}.mg .two{display:grid;grid-template-columns:1fr 1fr;gap:26px;margin:26px 0}.mg .two .imgph{aspect-ratio:16/9;margin-bottom:10px}.mg .two h3{font-size:22px}.mg .rest{columns:3;column-gap:26px}.mg .rest a{display:block;break-inside:avoid;padding:8px 0;border-bottom:1px solid var(--ln);font-family:var(--se);font-size:16px}@media(max-width:720px){.mg .two,.mg .rest{grid-template-columns:1fr;columns:1}}');
+      var h = a[0];
+      return '<div class="mg"><a class="hero" href="' + href(h) + '">' + img(h) + '<div class="ov"><span class="chip" style="color:#fff">' + esc(h.cat) + '</span><h1>' + esc(h.title) + '</h1></div></a>' +
+        '<div class="two">' + a.slice(1, 3).map(function (x) { return '<a href="' + href(x) + '">' + img(x) + '<span class="chip">' + esc(x.cat) + '</span><h3>' + esc(x.title) + '</h3></a>'; }).join('') + '</div>' +
+        '<div class="rest">' + a.slice(3, 15).map(function (x) { return '<a href="' + href(x) + '">' + esc(x.title) + '</a>'; }).join('') + '</div></div>';
+    },
+    // 5. DIGEST — numbered compact list
+    digest: function (a) {
+      css('.dg{max-width:720px;margin:0 auto;counter-reset:d}.dg .it{counter-increment:d;display:flex;gap:16px;padding:16px 0;border-bottom:1px solid var(--ln)}.dg .it:before{content:counter(d);font-family:var(--se);font-size:28px;color:var(--a);min-width:40px}.dg h3{font-size:19px}.dg .c{font-size:11px;font-weight:800;text-transform:uppercase;color:var(--a);letter-spacing:.05em}');
+      return '<div class="dg"><p class="byl" style="text-align:center;margin-bottom:10px">The RENTV Daily — today\'s Western-U.S. CRE, in order.</p>' +
+        a.slice(0, 15).map(function (x) { return '<a class="it" href="' + href(x) + '"><div><span class="c">' + esc(x.cat) + '</span><h3>' + esc(x.title) + '</h3></div></a>'; }).join('') + '</div>';
+    },
+    // 6. GRID — uniform photo cards
+    grid: function (a) {
+      css('.gr{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:18px}.gr a{background:var(--wa);border:1px solid var(--ln);border-radius:8px;overflow:hidden}.gr .imgph{aspect-ratio:16/10;border-radius:0}.gr .b{padding:14px 16px}.gr .c{font-size:11px;font-weight:800;text-transform:uppercase;color:var(--a)}.gr h4{font-size:16px;margin-top:6px}');
+      return '<div class="gr">' + a.slice(0, 18).map(function (x) { return '<a href="' + href(x) + '">' + img(x) + '<div class="b"><span class="c">' + esc(x.cat) + '</span><h4>' + esc(x.title) + '</h4></div></a>'; }).join('') + '</div>';
+    },
+    // 7. SPLIT — headlines left, rail right, no hero
+    split: function (a) {
+      css('.sp{display:grid;grid-template-columns:1fr 320px;gap:40px}.sp .it{padding:16px 0;border-bottom:1px solid var(--ln)}.sp h3{font-size:23px}.sp .c{font-size:11px;font-weight:800;text-transform:uppercase;color:var(--a)}.sp aside h3{border-top:3px solid var(--ink);padding-top:8px}.sp .mr{list-style:none}.sp .mr li{padding:9px 0;border-bottom:1px solid var(--ln)}.sp .mr a{font-weight:600;font-size:14px}@media(max-width:820px){.sp{grid-template-columns:1fr}}');
+      return '<div class="sp"><div>' + a.slice(0, 12).map(function (x) { return '<a class="it" href="' + href(x) + '"><span class="c">' + esc(x.cat) + '</span><h3>' + esc(x.title) + '</h3><div class="byl">RENTV Staff · live</div></a>'; }).join('') +
+        '</div><aside><h3>Most Read</h3><ul class="mr">' + a.slice(0, 8).map(function (x) { return '<li><a href="' + href(x) + '">' + esc(x.title) + '</a></li>'; }).join('') + '</ul></aside></div>';
+    },
+    // 8. DASHBOARD — metrics band + list + market cards
+    dashboard: function (a) {
+      css('.mb{display:flex;flex-wrap:wrap;gap:30px;padding:18px 20px;background:var(--wa);border:1px solid var(--ln);border-radius:10px;margin-bottom:24px}.mb .v{font-family:var(--se);font-size:30px;color:var(--a)}.mb .l{font-size:11px;text-transform:uppercase;color:var(--sub)}.db{display:grid;grid-template-columns:1fr 300px;gap:30px}.db .it{padding:12px 0;border-bottom:1px solid var(--ln)}.db h4{font-size:17px}.db .c{font-size:11px;font-weight:800;text-transform:uppercase;color:var(--a)}.mc{background:var(--wa);border:1px solid var(--ln);border-radius:8px;padding:14px 16px;margin-bottom:12px}.mc .n{font-family:var(--se);font-size:22px}@media(max-width:820px){.db{grid-template-columns:1fr}}');
+      var band = [['3','Web properties'],['1998','Est.'],['600+','Conf. audience'],['Daily','Newsletter']];
+      return '<div class="mb">' + band.map(function (b) { return '<div><div class="v">' + b[0] + '</div><div class="l">' + b[1] + '</div></div>'; }).join('') + '</div>' +
+        '<div class="db"><div>' + a.slice(0, 14).map(function (x) { return '<a class="it" href="' + href(x) + '"><span class="c">' + esc(x.cat) + '</span><h4>' + esc(x.title) + '</h4></a>'; }).join('') +
+        '</div><aside><div class="mc"><div class="l" style="font-size:11px;text-transform:uppercase;color:var(--sub)">LA Office Vacancy</div><div class="n">23.1%</div></div><div class="mc"><div class="l" style="font-size:11px;text-transform:uppercase;color:var(--sub)">IE Industrial Cap</div><div class="n">5.2%</div></div><div class="mc"><div class="l" style="font-size:11px;text-transform:uppercase;color:var(--sub)">10-YR Treasury</div><div class="n">4.63%</div></div></aside></div>';
+    },
+    // 9. MINIMAL — single centered column, whitespace
+    minimal: function (a) {
+      css('.mn{max-width:640px;margin:0 auto}.mn .it{padding:26px 0;border-bottom:1px solid var(--ln)}.mn h3{font-size:24px;font-weight:400}.mn .c{font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--a)}.mn .byl{margin-top:8px}');
+      return '<div class="mn">' + a.slice(0, 12).map(function (x) { return '<a class="it" href="' + href(x) + '" style="display:block"><span class="c">' + esc(x.cat) + '</span><h3>' + esc(x.title) + '</h3><div class="byl">RENTV Staff · Western U.S.</div></a>'; }).join('') + '</div>';
+    },
+    // 10. BIG FEED — one column, large images
+    feed: function (a) {
+      css('.fd{max-width:680px;margin:0 auto}.fd a{display:block;margin-bottom:30px}.fd .imgph{aspect-ratio:16/9;margin-bottom:12px}.fd .c{font-size:11px;font-weight:800;text-transform:uppercase;color:var(--a)}.fd h2{font-size:26px;margin:6px 0}');
+      return '<div class="fd">' + a.slice(0, 12).map(function (x) { return '<a href="' + href(x) + '">' + img(x) + '<span class="c">' + esc(x.cat) + '</span><h2>' + esc(x.title) + '</h2><div class="byl">RENTV Staff · live from rentv.com</div></a>'; }).join('') + '</div>';
+    },
+  };
+
+  fetch('/api/news').then(function (r) { return r.json(); }).then(function (d) {
+    var items = (d.items || []);
+    var app = document.getElementById('app');
+    if (!items.length) { app.innerHTML = '<div class="load">Live feed is refreshing — check back shortly.</div>'; return; }
+    app.innerHTML = (L[ver] || L.wire)(items);
+  }).catch(function () { document.getElementById('app').innerHTML = '<div class="load">Live feed temporarily unavailable — retrying…</div>'; });
+})();
diff --git a/public/versions/split.html b/public/versions/split.html
new file mode 100644
index 00000000..0999eeca
--- /dev/null
+++ b/public/versions/split.html
@@ -0,0 +1,24 @@
+<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
+<title>RENTV — Split Desk (version)</title><meta name="description" content="Headlines column on the left, Most-Read + Markets rail on the right. No big hero.">
+<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=Playfair+Display:wght@400;700&family=Newsreader:wght@400;700&family=Libre+Franklin:wght@400;600;800&family=Source+Serif+4:wght@400;700&family=IBM+Plex+Serif:wght@400;700&family=IBM+Plex+Sans:wght@400;600;700&family=DM+Serif+Display&family=Archivo:wght@400;600;800&family=Spectral:wght@400;700&family=Space+Grotesk:wght@400;700&family=Fraunces:wght@400;700&family=Lora:wght@400;700&family=Inter:wght@300;400;600;800&display=swap" rel="stylesheet">
+<style>
+:root{--a:#00538b;--ink:#1a1a1a;--sub:#5c5c5c;--ln:#d4c9b8;--bg:#fff1e5;--wa:#fde8d1;--se:'Source Serif 4',Georgia,serif;--sa:'Inter',system-ui,sans-serif}
+*{box-sizing:border-box;margin:0;padding:0}body{font-family:var(--sa);background:var(--bg);color:var(--ink);line-height:1.5}
+a{color:inherit;text-decoration:none}.wrap{max-width:1180px;margin:0 auto;padding:0 20px}
+.vbar{background:var(--ink);color:var(--bg);font-size:12px}.vbar .wrap{display:flex;justify-content:space-between;align-items:center;height:36px}
+.vbar a{color:var(--bg);opacity:.85}.vbar b{color:var(--a)}
+.mast{border-bottom:2px solid var(--ink);padding:18px 0 12px;text-align:center}
+.logo{font-family:var(--se);font-weight:700;font-size:40px;letter-spacing:-1px}.logo span{color:var(--a)}
+.logo small{display:block;font-family:var(--sa);font-size:10px;letter-spacing:3px;text-transform:uppercase;color:var(--sub);margin-top:3px}
+.chip{display:inline-block;font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:var(--a)}
+.byl{font-size:12px;color:var(--sub)}
+h1,h2,h3,h4{font-family:var(--se);font-weight:700;line-height:1.14}
+#app{padding:26px 0 60px;min-height:50vh}.load{color:var(--sub);padding:40px 0}
+.imgph{background:linear-gradient(135deg,var(--wa),var(--ln));border-radius:6px}
+footer{border-top:1px solid var(--ln);color:var(--sub);font-size:12px;padding:26px 0;text-align:center}
+</style></head><body data-ver="split">
+<div class="vbar"><div class="wrap"><span>RENTV · Version — <b>Split Desk</b></span><a href="/versions">← compare all 10 versions</a></div></div>
+<header class="mast"><div class="wrap"><a class="logo" href="/">REN<span>TV</span>.com<small>Commercial Real Estate News · Split Desk</small></a></div></header>
+<div class="wrap"><main id="app"><div class="load">Loading live rentv.com stories…</div></main></div>
+<footer><div class="wrap">RENTV.com · version preview · live data from rentv.com — <a href="/versions" style="color:var(--a)">back to all versions</a></div></footer>
+<script src="/versions/render.js"></script></body></html>
\ No newline at end of file
diff --git a/public/versions/terminal.html b/public/versions/terminal.html
new file mode 100644
index 00000000..773b1bf9
--- /dev/null
+++ b/public/versions/terminal.html
@@ -0,0 +1,24 @@
+<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
+<title>RENTV — Terminal (version)</title><meta name="description" content="Dark, data-first deal rows with category tags — the CRE data-desk look.">
+<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=Playfair+Display:wght@400;700&family=Newsreader:wght@400;700&family=Libre+Franklin:wght@400;600;800&family=Source+Serif+4:wght@400;700&family=IBM+Plex+Serif:wght@400;700&family=IBM+Plex+Sans:wght@400;600;700&family=DM+Serif+Display&family=Archivo:wght@400;600;800&family=Spectral:wght@400;700&family=Space+Grotesk:wght@400;700&family=Fraunces:wght@400;700&family=Lora:wght@400;700&family=Inter:wght@300;400;600;800&display=swap" rel="stylesheet">
+<style>
+:root{--a:#ff6600;--ink:#e8ffe8;--sub:#7fbf7f;--ln:#1e3a1e;--bg:#0a0f0a;--wa:#111a11;--se:'IBM Plex Serif',Georgia,serif;--sa:'IBM Plex Sans',ui-monospace,monospace}
+*{box-sizing:border-box;margin:0;padding:0}body{font-family:var(--sa);background:var(--bg);color:var(--ink);line-height:1.5}
+a{color:inherit;text-decoration:none}.wrap{max-width:1180px;margin:0 auto;padding:0 20px}
+.vbar{background:var(--ink);color:var(--bg);font-size:12px}.vbar .wrap{display:flex;justify-content:space-between;align-items:center;height:36px}
+.vbar a{color:var(--bg);opacity:.85}.vbar b{color:var(--a)}
+.mast{border-bottom:2px solid var(--ink);padding:18px 0 12px;text-align:center}
+.logo{font-family:var(--se);font-weight:700;font-size:40px;letter-spacing:-1px}.logo span{color:var(--a)}
+.logo small{display:block;font-family:var(--sa);font-size:10px;letter-spacing:3px;text-transform:uppercase;color:var(--sub);margin-top:3px}
+.chip{display:inline-block;font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:var(--a)}
+.byl{font-size:12px;color:var(--sub)}
+h1,h2,h3,h4{font-family:var(--se);font-weight:700;line-height:1.14}
+#app{padding:26px 0 60px;min-height:50vh}.load{color:var(--sub);padding:40px 0}
+.imgph{background:linear-gradient(135deg,var(--wa),var(--ln));border-radius:6px}
+footer{border-top:1px solid var(--ln);color:var(--sub);font-size:12px;padding:26px 0;text-align:center}
+</style></head><body data-ver="terminal">
+<div class="vbar"><div class="wrap"><span>RENTV · Version — <b>Terminal</b></span><a href="/versions">← compare all 10 versions</a></div></div>
+<header class="mast"><div class="wrap"><a class="logo" href="/">REN<span>TV</span>.com<small>Commercial Real Estate News · Terminal</small></a></div></header>
+<div class="wrap"><main id="app"><div class="load">Loading live rentv.com stories…</div></main></div>
+<footer><div class="wrap">RENTV.com · version preview · live data from rentv.com — <a href="/versions" style="color:var(--a)">back to all versions</a></div></footer>
+<script src="/versions/render.js"></script></body></html>
\ No newline at end of file
diff --git a/public/versions/wire.html b/public/versions/wire.html
new file mode 100644
index 00000000..4738de59
--- /dev/null
+++ b/public/versions/wire.html
@@ -0,0 +1,24 @@
+<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
+<title>RENTV — The Wire (version)</title><meta name="description" content="Lead story + 3-column card river + right rail. The modern newsroom default.">
+<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=Playfair+Display:wght@400;700&family=Newsreader:wght@400;700&family=Libre+Franklin:wght@400;600;800&family=Source+Serif+4:wght@400;700&family=IBM+Plex+Serif:wght@400;700&family=IBM+Plex+Sans:wght@400;600;700&family=DM+Serif+Display&family=Archivo:wght@400;600;800&family=Spectral:wght@400;700&family=Space+Grotesk:wght@400;700&family=Fraunces:wght@400;700&family=Lora:wght@400;700&family=Inter:wght@300;400;600;800&display=swap" rel="stylesheet">
+<style>
+:root{--a:#c8102e;--ink:#14171a;--sub:#5b636b;--ln:#e4e7ea;--bg:#fff;--wa:#f5f6f8;--se:'Playfair Display',Georgia,serif;--sa:'Inter',system-ui,sans-serif}
+*{box-sizing:border-box;margin:0;padding:0}body{font-family:var(--sa);background:var(--bg);color:var(--ink);line-height:1.5}
+a{color:inherit;text-decoration:none}.wrap{max-width:1180px;margin:0 auto;padding:0 20px}
+.vbar{background:var(--ink);color:var(--bg);font-size:12px}.vbar .wrap{display:flex;justify-content:space-between;align-items:center;height:36px}
+.vbar a{color:var(--bg);opacity:.85}.vbar b{color:var(--a)}
+.mast{border-bottom:2px solid var(--ink);padding:18px 0 12px;text-align:center}
+.logo{font-family:var(--se);font-weight:700;font-size:40px;letter-spacing:-1px}.logo span{color:var(--a)}
+.logo small{display:block;font-family:var(--sa);font-size:10px;letter-spacing:3px;text-transform:uppercase;color:var(--sub);margin-top:3px}
+.chip{display:inline-block;font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:var(--a)}
+.byl{font-size:12px;color:var(--sub)}
+h1,h2,h3,h4{font-family:var(--se);font-weight:700;line-height:1.14}
+#app{padding:26px 0 60px;min-height:50vh}.load{color:var(--sub);padding:40px 0}
+.imgph{background:linear-gradient(135deg,var(--wa),var(--ln));border-radius:6px}
+footer{border-top:1px solid var(--ln);color:var(--sub);font-size:12px;padding:26px 0;text-align:center}
+</style></head><body data-ver="wire">
+<div class="vbar"><div class="wrap"><span>RENTV · Version — <b>The Wire</b></span><a href="/versions">← compare all 10 versions</a></div></div>
+<header class="mast"><div class="wrap"><a class="logo" href="/">REN<span>TV</span>.com<small>Commercial Real Estate News · The Wire</small></a></div></header>
+<div class="wrap"><main id="app"><div class="load">Loading live rentv.com stories…</div></main></div>
+<footer><div class="wrap">RENTV.com · version preview · live data from rentv.com — <a href="/versions" style="color:var(--a)">back to all versions</a></div></footer>
+<script src="/versions/render.js"></script></body></html>
\ No newline at end of file
diff --git a/server.js b/server.js
index 75f75d6b..4788f933 100644
--- a/server.js
+++ b/server.js
@@ -150,6 +150,8 @@ SECTIONS.forEach(s => app.get('/' + s, (_q, r) => r.redirect(301, '/?cat=' + s.c
 app.get('/news/:id', (_q, r) => r.sendFile(path.join(PUB, 'article.html')));
 // The REview — the folded-in video platform, served natively in the RENTV shell
 app.get('/review', (_q, r) => r.sendFile(path.join(PUB, 'review.html')));
+// 10 site VERSIONS — picker + per-version homepage layouts (all on live data)
+app.get('/versions', (_q, r) => r.sendFile(path.join(PUB, 'versions', 'index.html')));
 
 app.use(express.static(PUB, { extensions: ['html'] }));
 app.listen(PORT, () => console.log('rentv-v1 (full site, gated, live data) on ' + PORT));
diff --git a/versions.mjs b/versions.mjs
new file mode 100644
index 00000000..b0332f09
--- /dev/null
+++ b/versions.mjs
@@ -0,0 +1,87 @@
+#!/usr/bin/env node
+/* rentv-v1 — generate 10 distinct HOMEPAGE VERSIONS (different layouts, not just
+   palette) on live /api/news data, plus a /versions picker. Boomer opens the
+   picker and clicks into each to compare whole directions. $0/local. */
+import { writeFileSync, mkdirSync } from 'node:fs';
+import { dirname, join } from 'node:path';
+import { fileURLToPath } from 'node:url';
+const OUT = join(dirname(fileURLToPath(import.meta.url)), 'public', 'versions');
+mkdirSync(OUT, { recursive: true });
+
+// palette per version (drawn from the 10 themes) — accent, ink, sub, line, bg, wash, serif, sans, dark
+const PAL = {
+  wire:      { a:'#c8102e', ink:'#14171a', sub:'#5b636b', ln:'#e4e7ea', bg:'#fff', wa:'#f5f6f8', se:"'Playfair Display',Georgia,serif", sa:"'Inter',system-ui,sans-serif", dk:0 },
+  broadsheet:{ a:'#8b1a1a', ink:'#111', sub:'#555', ln:'#d6cfc4', bg:'#faf7f2', wa:'#f0ece4', se:"'Newsreader',Georgia,serif", sa:"'Libre Franklin',system-ui,sans-serif", dk:0 },
+  terminal:  { a:'#ff6600', ink:'#e8ffe8', sub:'#7fbf7f', ln:'#1e3a1e', bg:'#0a0f0a', wa:'#111a11', se:"'IBM Plex Serif',Georgia,serif", sa:"'IBM Plex Sans',ui-monospace,monospace", dk:1 },
+  magazine:  { a:'#b84a1e', ink:'#1e1712', sub:'#6b5a4e', ln:'#e0d4c8', bg:'#fdf8f3', wa:'#f5ede3', se:"'Fraunces',Georgia,serif", sa:"'Libre Franklin',system-ui,sans-serif", dk:0 },
+  digest:    { a:'#2d5a27', ink:'#1a1a14', sub:'#5a5a40', ln:'#d8d8b8', bg:'#fdfde6', wa:'#f5f5d0', se:"'Lora',Georgia,serif", sa:"'IBM Plex Sans',system-ui,sans-serif", dk:0 },
+  grid:      { a:'#1a3a6b', ink:'#0f1923', sub:'#5a6474', ln:'#e0e4eb', bg:'#fff', wa:'#f2f4f8', se:"'Source Serif 4',Georgia,serif", sa:"'Archivo',system-ui,sans-serif", dk:0 },
+  split:     { a:'#00538b', ink:'#1a1a1a', sub:'#5c5c5c', ln:'#d4c9b8', bg:'#fff1e5', wa:'#fde8d1', se:"'Source Serif 4',Georgia,serif", sa:"'Inter',system-ui,sans-serif", dk:0 },
+  dashboard: { a:'#c9a84c', ink:'#f0f2f5', sub:'#8fa3b8', ln:'#1e2d40', bg:'#0d1b2a', wa:'#132336', se:"'DM Serif Display',Georgia,serif", sa:"'Archivo',system-ui,sans-serif", dk:1 },
+  minimal:   { a:'#3a5a8c', ink:'#1c2330', sub:'#586070', ln:'#dce0e6', bg:'#f8f9fb', wa:'#edf0f4', se:"'Spectral',Georgia,serif", sa:"'Space Grotesk',system-ui,sans-serif", dk:0 },
+  feed:      { a:'#e82535', ink:'#f2f2f2', sub:'#9aa0a8', ln:'#2e3540', bg:'#181c22', wa:'#22282f', se:"'Playfair Display',Georgia,serif", sa:"'Inter',system-ui,sans-serif", dk:1 },
+};
+const VERSIONS = [
+  ['wire','The Wire','Lead story + 3-column card river + right rail. The modern newsroom default.'],
+  ['broadsheet','Broadsheet','Dense two-column serif columns, small images — a printed newspaper on the web.'],
+  ['terminal','Terminal','Dark, data-first deal rows with category tags — the CRE data-desk look.'],
+  ['magazine','Magazine','One oversized hero feature + two secondaries. Editorial and image-led.'],
+  ['digest','Daily Digest','Numbered compact headline list — reads like the morning email.'],
+  ['grid','Photo Grid','Uniform image-forward card grid. Every story equal, visual-first.'],
+  ['split','Split Desk','Headlines column on the left, Most-Read + Markets rail on the right. No big hero.'],
+  ['dashboard','Market Dashboard','Metrics band on top, then the news list beside live market cards.'],
+  ['minimal','Minimal','Single centered column, generous whitespace, quiet typography.'],
+  ['feed','Big Feed','One column of large-image stories you scroll — mobile-native, bold.'],
+];
+
+const GF = "https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;700&family=Newsreader:wght@400;700&family=Libre+Franklin:wght@400;600;800&family=Source+Serif+4:wght@400;700&family=IBM+Plex+Serif:wght@400;700&family=IBM+Plex+Sans:wght@400;600;700&family=DM+Serif+Display&family=Archivo:wght@400;600;800&family=Spectral:wght@400;700&family=Space+Grotesk:wght@400;700&family=Fraunces:wght@400;700&family=Lora:wght@400;700&family=Inter:wght@300;400;600;800&display=swap";
+
+function page(key, title, desc) {
+  const p = PAL[key];
+  return `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
+<title>RENTV — ${title} (version)</title><meta name="description" content="${desc}">
+<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="${GF}" rel="stylesheet">
+<style>
+:root{--a:${p.a};--ink:${p.ink};--sub:${p.sub};--ln:${p.ln};--bg:${p.bg};--wa:${p.wa};--se:${p.se};--sa:${p.sa}}
+*{box-sizing:border-box;margin:0;padding:0}body{font-family:var(--sa);background:var(--bg);color:var(--ink);line-height:1.5}
+a{color:inherit;text-decoration:none}.wrap{max-width:1180px;margin:0 auto;padding:0 20px}
+.vbar{background:var(--ink);color:var(--bg);font-size:12px}.vbar .wrap{display:flex;justify-content:space-between;align-items:center;height:36px}
+.vbar a{color:var(--bg);opacity:.85}.vbar b{color:var(--a)}
+.mast{border-bottom:2px solid var(--ink);padding:18px 0 12px;text-align:center}
+.logo{font-family:var(--se);font-weight:700;font-size:40px;letter-spacing:-1px}.logo span{color:var(--a)}
+.logo small{display:block;font-family:var(--sa);font-size:10px;letter-spacing:3px;text-transform:uppercase;color:var(--sub);margin-top:3px}
+.chip{display:inline-block;font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:var(--a)}
+.byl{font-size:12px;color:var(--sub)}
+h1,h2,h3,h4{font-family:var(--se);font-weight:700;line-height:1.14}
+#app{padding:26px 0 60px;min-height:50vh}.load{color:var(--sub);padding:40px 0}
+.imgph{background:linear-gradient(135deg,var(--wa),var(--ln));border-radius:6px}
+footer{border-top:1px solid var(--ln);color:var(--sub);font-size:12px;padding:26px 0;text-align:center}
+</style></head><body data-ver="${key}">
+<div class="vbar"><div class="wrap"><span>RENTV · Version — <b>${title}</b></span><a href="/versions">← compare all 10 versions</a></div></div>
+<header class="mast"><div class="wrap"><a class="logo" href="/">REN<span>TV</span>.com<small>Commercial Real Estate News · ${title}</small></a></div></header>
+<div class="wrap"><main id="app"><div class="load">Loading live rentv.com stories…</div></main></div>
+<footer><div class="wrap">RENTV.com · version preview · live data from rentv.com — <a href="/versions" style="color:var(--a)">back to all versions</a></div></footer>
+<script src="/versions/render.js"></script></body></html>`;
+}
+
+// picker
+const cards = VERSIONS.map(([k,t,d])=>{const p=PAL[k];return `<a class="vc" href="/versions/${k}">
+  <div class="sw" style="background:${p.bg};border-color:${p.ln}"><span style="background:${p.a}"></span><span style="background:${p.ink}"></span><span style="background:${p.sub}"></span><span style="background:${p.wa}"></span></div>
+  <h3>${t}</h3><p>${d}</p><span class="go">Open version →</span></a>`;}).join('');
+const picker = `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
+<title>RENTV — 10 Site Versions</title><link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;700&family=Inter:wght@400;600;800&display=swap" rel="stylesheet">
+<style>*{box-sizing:border-box;margin:0;padding:0}body{font-family:'Inter',system-ui,sans-serif;background:#0c1016;color:#eef1f6;line-height:1.5}
+.wrap{max-width:1180px;margin:0 auto;padding:0 22px}.hd{padding:44px 0 10px;text-align:center}
+.hd h1{font-family:'Playfair Display',serif;font-size:clamp(30px,5vw,52px)}.hd h1 span{color:#c8102e}
+.hd p{color:#aeb6bd;margin-top:10px}.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:18px;padding:30px 0 60px}
+.vc{background:#121722;border:1px solid rgba(255,255,255,.08);border-radius:10px;padding:22px;transition:.2s;display:block}
+.vc:hover{transform:translateY(-4px);border-color:#c8102e;box-shadow:0 18px 44px rgba(0,0,0,.4)}
+.sw{display:flex;height:40px;border-radius:6px;overflow:hidden;border:1px solid;margin-bottom:16px}.sw span{flex:1}
+.vc h3{font-family:'Playfair Display',serif;font-size:22px}.vc p{color:#aeb6bd;font-size:14px;margin:6px 0 12px}
+.vc .go{color:#c8102e;font-size:12px;font-weight:800;text-transform:uppercase;letter-spacing:.08em}</style></head><body>
+<header class="hd"><div class="wrap"><h1>REN<span>TV</span> · 10 Site Versions</h1><p>Ten complete directions for rentv.com — different layouts, not just colors. Open each; they all run on the live news feed. Pick the one that feels right.</p></div></header>
+<div class="wrap"><div class="grid">${cards}</div></div></body></html>`;
+
+for (const [k,t,d] of VERSIONS) writeFileSync(join(OUT, k + '.html'), page(k,t,d));
+writeFileSync(join(OUT, 'index.html'), picker);
+console.log('Wrote 10 versions + picker: ' + VERSIONS.map(v=>v[0]).join(', '));

← 88ae7aa2 rentv-v1: 10-theme live switcher (dropdown in util bar, loca  ·  back to Rentv  ·  rentv-v1 versions picker: reset anchor styling (titles white 6acf74cd →