[object Object]

← back to Rentv 2026

hub: RENTV Intelligence Hub (/hub) — single landing for the whole tool suite, grouped cards (Market Intelligence / Deal Tools / Directory & Search / Read & Share) + live stat strip (firms/brokers/markets/volume); home nav now leads with the hub

1ada599822ff752f76d4525fb1857eeec8ead27a · 2026-07-24 07:19:32 -0700 · Steve

Files touched

Diff

commit 1ada599822ff752f76d4525fb1857eeec8ead27a
Author: Steve <steve@designerwallcoverings.com>
Date:   Fri Jul 24 07:19:32 2026 -0700

    hub: RENTV Intelligence Hub (/hub) — single landing for the whole tool suite, grouped cards (Market Intelligence / Deal Tools / Directory & Search / Read & Share) + live stat strip (firms/brokers/markets/volume); home nav now leads with the hub
---
 data/markets.json    |  14 ++---
 data/news.json       |   2 +-
 data/ticker.json     |   8 +--
 public/hub.html      | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++
 public/index.html    |   2 +-
 tools/specs/hub.json |  23 ++++++++
 6 files changed, 185 insertions(+), 13 deletions(-)

diff --git a/data/markets.json b/data/markets.json
index 9763a9d6..942bf65c 100644
--- a/data/markets.json
+++ b/data/markets.json
@@ -1,5 +1,5 @@
 {
-  "fetched_at": "2026-07-24T13:46:47.250Z",
+  "fetched_at": "2026-07-24T14:06:48.040Z",
   "source": "Yahoo Finance — live (CBOE Treasury yields, Dow Jones/MSCI REIT indices)",
   "curve": [
     {
@@ -16,13 +16,13 @@
     },
     {
       "label": "10-Year",
-      "value": "4.69%",
+      "value": "4.68%",
       "change_bps": -2,
       "dir": "down"
     },
     {
       "label": "30-Year",
-      "value": "5.17%",
+      "value": "5.16%",
       "change_bps": -1,
       "dir": "down"
     }
@@ -42,8 +42,8 @@
   "reits": [
     {
       "label": "DJ U.S. Real Estate",
-      "value": "402.12",
-      "change_pct": 1.84,
+      "value": "403.07",
+      "change_pct": 2.08,
       "dir": "up"
     },
     {
@@ -54,8 +54,8 @@
     },
     {
       "label": "Vanguard REIT ETF (VNQ)",
-      "value": "$100.40",
-      "change_pct": 1.39,
+      "value": "$100.64",
+      "change_pct": 1.64,
       "dir": "up"
     }
   ],
diff --git a/data/news.json b/data/news.json
index bf690e84..aebc4ce2 100644
--- a/data/news.json
+++ b/data/news.json
@@ -1,6 +1,6 @@
 {
  "source": "rentv.com — live",
- "fetched_at": "2026-07-24T13:46:47.048Z",
+ "fetched_at": "2026-07-24T14:06:47.815Z",
  "count": 23,
  "items": [
   {
diff --git a/data/ticker.json b/data/ticker.json
index 3a60d537..e45c862b 100644
--- a/data/ticker.json
+++ b/data/ticker.json
@@ -1,5 +1,5 @@
 {
-  "fetched_at": "2026-07-24T13:46:47.221Z",
+  "fetched_at": "2026-07-24T14:06:48.015Z",
   "la_office_vac": {
     "label": "LA OFFICE VAC",
     "value": "23.1%",
@@ -14,14 +14,14 @@
   },
   "cre_index": {
     "label": "CRE INDEX",
-    "value": "4,226",
-    "change_pct": 1.84,
+    "value": "4,236",
+    "change_pct": 2.08,
     "dir": "up",
     "source": "Dow Jones U.S. Real Estate"
   },
   "ten_yr": {
     "label": "10-YR",
-    "value": "4.69%",
+    "value": "4.68%",
     "change_bps": -2,
     "dir": "down",
     "source": "CBOE 10-Yr (^TNX)"
diff --git a/public/hub.html b/public/hub.html
new file mode 100644
index 00000000..3595c6ab
--- /dev/null
+++ b/public/hub.html
@@ -0,0 +1,149 @@
+<!doctype html><html lang="en"><head>
+<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
+<title>RENTV Intelligence — CRE Tools for the Western U.S.</title>
+<meta name="description" content="The RENTV Intelligence hub — search, market pulse, sector deep-dives, deal flow by metro, calculators, watchlists, the broker directory, deal comparison and the shareable Brief, all in one place.">
+<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:ital,wght@0,700;0,800;1,600&family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
+<style>
+  :root{--red:#c8102e;--ink:#14171a;--sub:#5b636b;--line:#e4e7ea;--wash:#f5f6f8;--up:#0f8a4d}
+  *{box-sizing:border-box;margin:0}
+  body{font-family:'Inter',system-ui,sans-serif;color:var(--ink);background:#fbfbfc;line-height:1.45}
+  a{color:inherit;text-decoration:none}
+  .top{position:sticky;top:0;z-index:900;display:flex;align-items:center;justify-content:space-between;height:54px;padding:0 16px;background:#fff;border-bottom:1px solid var(--line)}
+  .burger{display:inline-flex;align-items:center;gap:10px;border:0;background:none;cursor:pointer;font:inherit;color:inherit;padding:7px 9px;border-radius:8px}
+  .burger:hover{background:rgba(0,0,0,.06)}
+  .burger .lbl{font-size:12px;font-weight:800;letter-spacing:.14em;text-transform:uppercase;color:var(--sub)}
+  .brand{position:absolute;left:50%;transform:translateX(-50%);font-family:'Playfair Display',Georgia,serif;font-weight:800;font-size:25px;letter-spacing:.02em}.brand span{color:var(--red)}
+  .user{width:37px;height:37px;border-radius:50%;border:1.5px solid var(--line);background:#fff;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;color:var(--ink)}
+  .user:hover{border-color:var(--red);color:var(--red)}
+  .scrim{position:fixed;inset:0;background:rgba(6,9,12,.5);opacity:0;pointer-events:none;transition:opacity .22s;z-index:950}
+  .scrim.open{opacity:1;pointer-events:auto}
+  .drawer{position:fixed;top:0;left:0;height:100%;width:360px;max-width:88vw;background:#0b0e12;color:#e7ecf1;transform:translateX(-102%);transition:transform .26s cubic-bezier(.4,0,.2,1);z-index:951;display:flex;flex-direction:column;overflow-y:auto;box-shadow:2px 0 40px rgba(0,0,0,.4)}
+  .drawer.open{transform:none}
+  .drawer .dh{display:flex;align-items:center;justify-content:space-between;padding:16px 18px;border-bottom:1px solid #1c232b}
+  .drawer .dh .w{font-family:'Playfair Display',serif;font-size:23px;font-weight:800}.drawer .dh .w span{color:var(--red)}
+  .drawer .dh button{background:none;border:0;color:#8b949e;font-size:22px;cursor:pointer;line-height:1}
+  .grp{padding:14px 18px 4px}.grp .gt{font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:#6b747d;margin-bottom:6px}
+  .drawer nav a{display:block;padding:9px 18px;color:#dbe1e7;font-size:14.5px;border-left:3px solid transparent}
+  .drawer nav a:hover{background:#141a21;border-left-color:var(--red);color:#fff}
+  .drawer nav a.active{background:#141a21;border-left-color:var(--red);color:#fff;font-weight:700}
+  .drawer .df{margin-top:auto;padding:16px 18px;border-top:1px solid #1c232b;font-size:11px;color:#6b747d}
+
+  .hero{background:#0b0e12;color:#fff;padding:44px 0 40px;border-bottom:3px solid var(--red)}
+  .wrap{max-width:1120px;margin:0 auto;padding:0 22px;width:100%}
+  .hero .k{color:var(--red);font-weight:800;font-size:12px;letter-spacing:.2em;text-transform:uppercase}
+  .hero h1{font-family:'Playfair Display',serif;font-size:clamp(38px,5.4vw,60px);font-weight:800;letter-spacing:-.01em;margin:8px 0 8px;line-height:1.05}
+  .hero h1 span{color:var(--red)}
+  .hero p{color:#aab2ba;font-size:16px;max-width:600px}
+  .stats{display:flex;gap:30px;flex-wrap:wrap;margin-top:24px}
+  .stats .s .v{font-family:'Playfair Display',serif;font-size:30px;font-weight:800}
+  .stats .s .l{color:#7b848d;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;margin-top:1px}
+
+  .sec{padding:30px 0 6px}
+  .sec .gt{font-size:12px;text-transform:uppercase;letter-spacing:.1em;font-weight:800;color:var(--sub);margin-bottom:14px;display:flex;align-items:center;gap:10px}
+  .sec .gt::after{content:'';flex:1;height:1px;background:var(--line)}
+  .cards{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;padding-bottom:8px}
+  @media(max-width:860px){.cards{grid-template-columns:1fr 1fr}.stats{gap:20px}}
+  @media(max-width:560px){.cards{grid-template-columns:1fr}}
+  .card{display:flex;flex-direction:column;background:#fff;border:1px solid var(--line);border-radius:14px;padding:20px;transition:.16s;position:relative}
+  .card:hover{border-color:var(--red);transform:translateY(-2px);box-shadow:0 10px 30px -18px rgba(0,0,0,.3)}
+  .card .ic{font-size:26px;margin-bottom:12px}
+  .card h3{font-family:'Playfair Display',serif;font-size:21px;font-weight:800;letter-spacing:-.01em}
+  .card p{color:var(--sub);font-size:13.5px;margin-top:6px;flex:1}
+  .card .go{color:var(--red);font-weight:800;font-size:12.5px;letter-spacing:.04em;text-transform:uppercase;margin-top:14px}
+  .card:hover .go::after{content:' →'}
+  .foot{padding:30px 0 60px;color:var(--sub);font-size:12.5px}
+</style></head><body>
+
+<header class="top">
+  <button class="burger" id="burger" aria-label="Menu">
+    <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"><path d="M3 6h18M3 12h18M3 18h18"/></svg>
+    <span class="lbl">Menu</span>
+  </button>
+  <a class="brand" href="/">REN<span>TV</span></a>
+  <a class="user" href="/search" aria-label="Search" title="Search">
+    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"><circle cx="11" cy="11" r="7"/><path d="M21 21l-4.3-4.3"/></svg>
+  </a>
+</header>
+
+<div class="scrim" id="scrim"></div>
+<aside class="drawer" id="drawer">
+  <div class="dh"><div class="w">REN<span>TV</span></div><button id="dx" aria-label="Close">&times;</button></div>
+  <div class="grp"><div class="gt">Intelligence Hub</div></div>
+  <nav><a href="/hub" class="active">All Tools</a><a href="/search">Search</a><a href="/pulse">Market Pulse</a><a href="/sector">Sector Deep-Dives</a><a href="/metros">Deal Flow by Metro</a><a href="/tools">CRE Toolkit</a><a href="/watchlist">Deal Watchlist</a><a href="/directory">CRE Directory</a><a href="/compare">Deal Comparison</a><a href="/brief">The RENTV Brief</a></nav>
+  <div class="grp"><div class="gt">Sections</div></div>
+  <nav><a href="/deals">Deals</a><a href="/markets">Markets</a><a href="/la-commercial">LA Commercial</a><a href="/desk">Broker &amp; Owner Desk</a><a href="/conferences">Conferences</a><a href="/blog">Blog</a></nav>
+  <div class="grp"><div class="gt">Company</div></div>
+  <nav><a href="/about">About</a><a href="/advertise">Advertise</a><a href="/subscribe">Subscribe / Newsletters</a></nav>
+  <div class="df">RENTV.com — Commercial real estate news, Western U.S.</div>
+</aside>
+
+<section class="hero">
+  <div class="wrap">
+    <div class="k">RENTV Intelligence</div>
+    <h1>Everything to work the <span>Western U.S.</span> CRE market</h1>
+    <p>Search, stats, deal tools and a live broker directory — one hub over RENTV's live commercial real estate data.</p>
+    <div class="stats" id="stats"></div>
+  </div>
+</section>
+
+<main class="wrap">
+  <div class="sec"><div class="gt">Market Intelligence</div><div class="cards" id="g-market"></div></div>
+  <div class="sec" id="deal-tools"><div class="gt">Deal Tools</div><div class="cards" id="g-tools"></div></div>
+  <div class="sec"><div class="gt">Directory &amp; Search</div><div class="cards" id="g-dir"></div></div>
+  <div class="sec"><div class="gt">Read &amp; Share</div><div class="cards" id="g-read"></div></div>
+  <div class="foot">All tools run over RENTV's live Western-U.S. deal &amp; news feed. Built for brokers, owners, investors and developers.</div>
+</main>
+
+<script>
+const $=id=>document.getElementById(id);
+const drawer=$('drawer'),scrim=$('scrim');
+$('burger').onclick=()=>{drawer.classList.add('open');scrim.classList.add('open')};
+const close=()=>{drawer.classList.remove('open');scrim.classList.remove('open')};
+$('dx').onclick=close;scrim.onclick=close;document.addEventListener('keydown',e=>{if(e.key==='Escape')close()});
+
+const TOOLS={
+  market:[
+    {ic:'📊',t:'Market Pulse',d:'Tracked volume, deal count and sector mix at a glance.',h:'/pulse'},
+    {ic:'🏙️',t:'Sector Deep-Dives',d:'Multifamily, office, industrial & retail — each on its own page.',h:'/sector'},
+    {ic:'📍',t:'Deal Flow by Metro',d:'Where the capital is moving, ranked by metro.',h:'/metros'},
+  ],
+  tools:[
+    {ic:'⭐',t:'Deal Watchlist',d:'Pin the sectors & markets you care about; see only matching deals.',h:'/watchlist'},
+    {ic:'⚖️',t:'Deal Comparison',d:'Put up to four deals side by side on the numbers that matter.',h:'/compare'},
+    {ic:'🧮',t:'CRE Toolkit',d:'Cap rate, price per unit/SF, and lender-style loan sizing.',h:'/tools'},
+  ],
+  dir:[
+    {ic:'🏢',t:'CRE Directory',d:'Search thousands of California firms and licensed brokers.',h:'/directory'},
+    {ic:'🔎',t:'Global Search',d:'One box across every deal, story, video and firm.',h:'/search'},
+  ],
+  read:[
+    {ic:'📰',t:'The RENTV Brief',d:'A shareable, print-ready snapshot of the market — perfect to forward.',h:'/brief'},
+  ],
+};
+const card=t=>`<a class="card" href="${t.h}"><div class="ic">${t.ic}</div><h3>${t.t}</h3><p>${t.d}</p><div class="go">Open</div></a>`;
+$('g-market').innerHTML=TOOLS.market.map(card).join('');
+$('g-tools').innerHTML=TOOLS.tools.map(card).join('');
+$('g-dir').innerHTML=TOOLS.dir.map(card).join('');
+$('g-read').innerHTML=TOOLS.read.map(card).join('');
+
+(async function(){
+  const fmt=n=>n>=1e6?(Math.round(n/1e5)/10+'M'):n>=1e3?(Math.round(n/100)/10+'k'):(''+n);
+  let stats=[['—','Firms'],['—','Brokers'],['—','Markets'],['—','Tracked vol']];
+  try{
+    const [firms,brokers,pulse]=await Promise.all([
+      fetch('/api/firms?limit=1').then(r=>r.json()),
+      fetch('/api/brokers?limit=1').then(r=>r.json()),
+      fetch('/api/pulse').then(r=>r.json()),
+    ]);
+    stats=[
+      [fmt(firms.total||0),'CA firms'],
+      [fmt(brokers.total||0),'CA brokers'],
+      [String(pulse.kpis?.marketCount||'—'),'Markets'],
+      [pulse.kpis?.totalVolumeLabel||'—','Tracked vol'],
+    ];
+  }catch(e){/* keep placeholders */}
+  $('stats').innerHTML=stats.map(([v,l])=>`<div class="s"><div class="v">${v}</div><div class="l">${l}</div></div>`).join('');
+})();
+</script>
+</body></html>
diff --git a/public/index.html b/public/index.html
index c9007804..3d9efdb4 100644
--- a/public/index.html
+++ b/public/index.html
@@ -104,7 +104,7 @@
   <div class="dh"><span class="w">REN<span>TV</span></span><button id="dclose" aria-label="Close">✕</button></div>
   <div class="snap" id="snap"></div>
   <div class="grp"><div class="gt">Discover</div></div>
-  <nav><a href="/search">🔎 Search</a><a href="/pulse">📊 Market Pulse</a><a href="/sector">🏙️ Sector Deep-Dives</a><a href="/metros">📍 Deal Flow by Metro</a><a href="/tools">🧮 CRE Toolkit</a><a href="/watchlist">⭐ Deal Watchlist</a><a href="/directory">🏢 CRE Directory</a><a href="/compare">⚖️ Deal Comparison</a><a href="/brief">📰 The RENTV Brief</a></nav>
+  <nav><a href="/hub" style="font-weight:700">✨ Intelligence Hub — all tools</a><a href="/search">🔎 Search</a><a href="/pulse">📊 Market Pulse</a><a href="/sector">🏙️ Sector Deep-Dives</a><a href="/metros">📍 Deal Flow by Metro</a><a href="/tools">🧮 CRE Toolkit</a><a href="/watchlist">⭐ Deal Watchlist</a><a href="/directory">🏢 CRE Directory</a><a href="/compare">⚖️ Deal Comparison</a><a href="/brief">📰 The RENTV Brief</a></nav>
   <div class="grp"><div class="gt">Sections</div></div>
   <nav><a href="/sales">Sales</a><a href="/leases">Leases</a><a href="/financing">Financing</a><a href="/development">Development</a><a href="/multifamily">Multifamily</a><a href="/industrial">Industrial</a><a href="/retail">Retail</a></nav>
   <div class="grp"><div class="gt">Intelligence</div></div>
diff --git a/tools/specs/hub.json b/tools/specs/hub.json
new file mode 100644
index 00000000..55b0b737
--- /dev/null
+++ b/tools/specs/hub.json
@@ -0,0 +1,23 @@
+{
+  "slug": "hub",
+  "title": "RENTV Intelligence Hub",
+  "subtitle": "The whole toolkit, one home",
+  "voice": "Samantha",
+  "scenes": [
+    {
+      "url": "/hub",
+      "say": "The RENTV Intelligence Hub brings the whole toolkit under one roof — with live stats up top: nearly thirty-five thousand firms, over three hundred thousand brokers, and every tracked deal.",
+      "caption": "One home for every RENTV tool — with live stats"
+    },
+    {
+      "url": "/hub#deal-tools",
+      "say": "The tools are grouped by job — market intelligence, deal tools, directory and search, and read-and-share — so you always know where to go.",
+      "caption": "Grouped by job — intelligence, deal tools, directory, share"
+    },
+    {
+      "url": "/pulse",
+      "say": "And every card is a single click from the live tool — like Market Pulse — turning RENTV's news feed into a real commercial real estate command center.",
+      "caption": "Every card is one click from the live tool"
+    }
+  ]
+}

← bdc976b1 auto-save: 2026-07-24T06:55:55 (3 files) — data/markets.json  ·  back to Rentv 2026  ·  tools: full 10-scene walkthrough spec (Hub + all 9 tools gui 52ea90e7 →