[object Object]

← back to Rentv 2026

sector: Sector Deep-Dives (/sector) — per-property-type page (Multifamily/Office/Industrial/Retail) with sector KPIs, % market share, top deals, keyword-matched news, and cross-links to Watchlist/Compare/Search; deep-linkable ?type=

a0ad97ecc76f966a5272c774d2340713ccc44e14 · 2026-07-23 18:15:13 -0700 · Steve

Files touched

Diff

commit a0ad97ecc76f966a5272c774d2340713ccc44e14
Author: Steve <steve@designerwallcoverings.com>
Date:   Thu Jul 23 18:15:13 2026 -0700

    sector: Sector Deep-Dives (/sector) — per-property-type page (Multifamily/Office/Industrial/Retail) with sector KPIs, % market share, top deals, keyword-matched news, and cross-links to Watchlist/Compare/Search; deep-linkable ?type=
---
 data/markets.json       |   2 +-
 data/news.json          |   2 +-
 data/ticker.json        |   2 +-
 public/index.html       |   2 +-
 public/sector.html      | 167 ++++++++++++++++++++++++++++++++++++++++++++++++
 tools/specs/sector.json |  23 +++++++
 6 files changed, 194 insertions(+), 4 deletions(-)

diff --git a/data/markets.json b/data/markets.json
index 8621a7c5..3cef3279 100644
--- a/data/markets.json
+++ b/data/markets.json
@@ -1,5 +1,5 @@
 {
-  "fetched_at": "2026-07-24T00:46:09.667Z",
+  "fetched_at": "2026-07-24T01:06:10.639Z",
   "source": "Yahoo Finance — live (CBOE Treasury yields, Dow Jones/MSCI REIT indices)",
   "curve": [
     {
diff --git a/data/news.json b/data/news.json
index 499ba4e8..f33ce5a3 100644
--- a/data/news.json
+++ b/data/news.json
@@ -1,6 +1,6 @@
 {
  "source": "rentv.com — live",
- "fetched_at": "2026-07-24T00:46:09.388Z",
+ "fetched_at": "2026-07-24T01:06:10.309Z",
  "count": 30,
  "items": [
   {
diff --git a/data/ticker.json b/data/ticker.json
index 0781f45e..f6d92dd2 100644
--- a/data/ticker.json
+++ b/data/ticker.json
@@ -1,5 +1,5 @@
 {
-  "fetched_at": "2026-07-24T00:46:09.636Z",
+  "fetched_at": "2026-07-24T01:06:10.617Z",
   "la_office_vac": {
     "label": "LA OFFICE VAC",
     "value": "23.1%",
diff --git a/public/index.html b/public/index.html
index eb567b82..c9007804 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="/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="/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/public/sector.html b/public/sector.html
new file mode 100644
index 00000000..906f6974
--- /dev/null
+++ b/public/sector.html
@@ -0,0 +1,167 @@
+<!doctype html><html lang="en"><head>
+<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
+<title>Sector Deep-Dive — RENTV.com</title>
+<meta name="description" content="RENTV sector deep-dives — multifamily, office, industrial and retail commercial real estate deal flow, stats and news across the Western U.S.">
+<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}
+
+  .wrap{max-width:1080px;margin:0 auto;padding:0 22px;width:100%}
+  .pills{display:flex;gap:8px;flex-wrap:wrap;padding:22px 0 4px}
+  .pill{border:1.5px solid var(--line);background:#fff;border-radius:22px;padding:9px 18px;font:800 13.5px 'Inter';color:var(--ink);cursor:pointer;transition:.14s}
+  .pill:hover{border-color:var(--red)}
+  .pill.on{background:var(--red);border-color:var(--red);color:#fff}
+  .shead{padding:16px 0 2px}
+  .shead .k{color:var(--red);font-weight:800;font-size:12px;letter-spacing:.16em;text-transform:uppercase}
+  .shead h1{font-family:'Playfair Display',serif;font-size:clamp(34px,4.4vw,52px);font-weight:700;letter-spacing:-.01em;margin-top:4px}
+  .shead p{color:var(--sub);font-size:15px;margin-top:4px;max-width:640px}
+  .kpis{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;padding:20px 0 6px}
+  .kpi{background:#fff;border:1px solid var(--line);border-radius:12px;padding:15px 16px}
+  .kpi .v{font-family:'Playfair Display',serif;font-size:27px;font-weight:800}
+  .kpi .l{color:var(--sub);font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;margin-top:3px}
+  .kpi.hot{background:var(--red);color:#fff;border-color:var(--red)}.kpi.hot .l{color:rgba(255,255,255,.85)}
+  .share{height:8px;background:var(--wash);border-radius:6px;overflow:hidden;margin:14px 0 2px}
+  .share .f{height:100%;background:var(--red);border-radius:6px;transition:width .6s}
+  .sharelbl{color:var(--sub);font-size:12px;font-weight:600;margin-bottom:6px}
+  .cta{display:flex;gap:10px;flex-wrap:wrap;padding:16px 0 0}
+  .cta a{display:inline-flex;align-items:center;gap:7px;border:1.5px solid var(--line);background:#fff;border-radius:9px;padding:10px 16px;font:800 12.5px 'Inter';color:var(--ink)}
+  .cta a:hover{border-color:var(--red);color:var(--red)}
+  .cta a.go{background:var(--red);border-color:var(--red);color:#fff}.cta a.go:hover{color:#fff}
+  .cols{display:grid;grid-template-columns:1.15fr 1fr;gap:28px;padding:26px 0 60px}
+  @media(max-width:820px){.cols{grid-template-columns:1fr}.kpis{grid-template-columns:1fr 1fr}}
+  .card h3{font-size:12px;text-transform:uppercase;letter-spacing:.09em;border-top:2px solid var(--ink);padding-top:10px;margin-bottom:8px;font-weight:800}
+  .deal{display:grid;grid-template-columns:1fr auto;gap:12px;padding:11px 0;border-bottom:1px solid var(--line);align-items:center}
+  .deal h4{font:600 15px/1.3 'Inter'}.deal .m{color:var(--sub);font-size:12px;margin-top:2px}
+  .deal .amt{font-family:'Playfair Display',serif;font-weight:800;font-size:17px;color:var(--red);white-space:nowrap}
+  .deal:hover h4{color:var(--red)}
+  .hl{display:grid;grid-template-columns:auto 1fr;gap:11px;padding:10px 0;border-bottom:1px solid var(--line);align-items:baseline}
+  .hl .c{font-size:9px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;color:#fff;background:#4a4f55;border-radius:20px;padding:3px 8px;white-space:nowrap}
+  .hl h4{font:600 14.5px/1.3 'Inter'}.hl:hover h4{color:var(--red)}
+  .none{color:var(--sub);font-size:13.5px;padding:14px 0}
+</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">Discover</div></div>
+  <nav><a href="/search">Search</a><a href="/pulse">Market Pulse</a><a href="/sector" class="active">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>
+  <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="/review">The REview</a><a href="/cre-talk">CRE Talk</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>
+
+<main class="wrap">
+  <div class="pills" id="pills"></div>
+  <div class="shead"><div class="k" id="kick">Sector Deep-Dive</div><h1 id="title">—</h1><p id="blurb"></p></div>
+  <div class="kpis" id="kpis"></div>
+  <div class="sharelbl" id="sharelbl"></div><div class="share"><div class="f" id="sharefill" style="width:0"></div></div>
+  <div class="cta" id="cta"></div>
+  <div class="cols">
+    <div class="card"><h3 id="dealsH">Top Deals</h3><div id="deals"></div></div>
+    <div class="card"><h3 id="newsH">Latest News</h3><div id="news"></div></div>
+  </div>
+</main>
+
+<script>
+const $=id=>document.getElementById(id);
+const esc=s=>String(s==null?'':s).replace(/[&<>"]/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;'}[c]));
+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 usd=n=>!n?'—':n>=1e9?('$'+(n/1e9).toFixed(1)+'B'):n>=1e6?('$'+(n/1e6).toFixed(1)+'M'):('$'+Math.round(n/1e3)+'K');
+
+const SECTORS={
+  Multifamily:{blurb:'Apartment and residential investment sales, financing and development across the Western U.S.',news:/multifamily|apartment|res community|residential|\bunit/i},
+  Office:{blurb:'Office towers, campuses and workplace assets — sales, leasing and refinancing.',news:/office|workplace|tower|high-rise/i},
+  Industrial:{blurb:'Warehouse, distribution and logistics real estate — the backbone of the supply chain.',news:/industrial|distribution|warehouse|logistics|manufacturing|msf|\bsf\b/i},
+  Retail:{blurb:'Shopping centers, storefronts and mixed-use retail assets.',news:/retail|shopping|storefront|mall|grocery|center/i},
+};
+let ALL={deals:[],news:[],pulse:{}}, cur='Multifamily';
+
+const p=new URLSearchParams(location.search);
+if(p.get('type')&&SECTORS[p.get('type')])cur=p.get('type');
+
+function pills(){
+  $('pills').innerHTML=Object.keys(SECTORS).map(s=>`<button class="pill${s===cur?' on':''}" data-s="${s}">${s}</button>`).join('');
+  $('pills').querySelectorAll('.pill').forEach(b=>b.onclick=()=>{cur=b.dataset.s;history.replaceState(null,'','/sector?type='+encodeURIComponent(cur));render();});
+}
+function render(){
+  pills();
+  const def=SECTORS[cur];
+  $('title').textContent=cur;
+  $('blurb').textContent=def.blurb;
+  $('dealsH').textContent='Top '+cur+' Deals';
+  $('newsH').textContent='Latest '+cur+' News';
+
+  const deals=ALL.deals.filter(d=>d.property_type===cur);
+  const priced=deals.filter(d=>d.amount);
+  const vol=priced.reduce((s,d)=>s+d.amount,0);
+  const totalVol=ALL.deals.filter(d=>d.amount).reduce((s,d)=>s+d.amount,0);
+  const markets=new Set(deals.map(d=>[d.city,d.state].filter(Boolean).join(', ')).filter(Boolean)).size;
+  const share=totalVol?vol/totalVol*100:0;
+  $('kpis').innerHTML=[
+    ['hot',usd(vol),'Tracked volume'],['',deals.length,'Deals'],
+    ['',priced.length?usd(vol/priced.length):'—','Avg size'],['',markets,'Markets'],
+  ].map(([c,v,l])=>`<div class="kpi ${c}"><div class="v">${esc(v)}</div><div class="l">${esc(l)}</div></div>`).join('');
+  $('sharelbl').innerHTML=`<b style="color:var(--ink)">${share.toFixed(0)}%</b> of all tracked deal volume`;
+  $('sharefill').style.width=Math.max(3,share)+'%';
+
+  $('cta').innerHTML=`<a class="go" href="/watchlist?types=${encodeURIComponent(cur)}">⭐ Watch ${esc(cur)} deals</a><a href="/compare">⚖️ Compare deals</a><a href="/search?q=${encodeURIComponent(cur)}">🔎 Search ${esc(cur)}</a>`;
+
+  const top=priced.sort((a,b)=>b.amount-a.amount).slice(0,6);
+  $('deals').innerHTML=top.length?top.map(d=>`<a class="deal" href="/deals"><div><h4>${esc(d.title)}</h4><div class="m">${[d.txn_type,[d.city,d.state].filter(Boolean).join(', ')].filter(Boolean).map(esc).join(' · ')}</div></div><div class="amt">${esc(d.amount_label||usd(d.amount))}</div></a>`).join(''):'<div class="none">No priced deals in this sector yet.</div>';
+
+  const nz=ALL.news.filter(n=>def.news.test(`${n.title} ${n.cat||''}`)).slice(0,8);
+  $('news').innerHTML=nz.length?nz.map(n=>`<a class="hl" href="/article.html?id=${encodeURIComponent(n.id)}"><span class="c">${esc(n.cat||'News')}</span><h4>${esc(n.title)}</h4></a>`).join(''):'<div class="none">No recent headlines in this sector.</div>';
+}
+
+(async function(){
+  try{ const [deals,news,pulse]=await Promise.all([
+    fetch('/api/deals?limit=200').then(r=>r.json()),
+    fetch('/api/news').then(r=>r.json()),
+    fetch('/api/pulse').then(r=>r.json()),
+  ]); ALL={deals:deals.deals||[],news:news.items||[],pulse:pulse}; }
+  catch(e){ $('kpis').innerHTML='<div class="none">Sector data unavailable.</div>'; return; }
+  render();
+})();
+</script>
+</body></html>
diff --git a/tools/specs/sector.json b/tools/specs/sector.json
new file mode 100644
index 00000000..94ec9011
--- /dev/null
+++ b/tools/specs/sector.json
@@ -0,0 +1,23 @@
+{
+  "slug": "sector",
+  "title": "Sector Deep-Dives",
+  "subtitle": "The market, by property type",
+  "voice": "Samantha",
+  "scenes": [
+    {
+      "url": "/sector",
+      "say": "Sector Deep-Dives break the market down by property type. Multifamily leads the West at fifty-seven percent of tracked volume, with its own deals, news and stats on one page.",
+      "caption": "Each property type — its volume, deals & news"
+    },
+    {
+      "url": "/sector?type=Industrial",
+      "say": "Switch to any sector — industrial, office or retail — and the whole page re-focuses on that slice of the market instantly.",
+      "caption": "One tap re-focuses the page on any sector"
+    },
+    {
+      "url": "/sector?type=Retail",
+      "say": "And every sector links you straight onward — watch it, compare its deals, or search it — tying the whole RENTV toolkit together.",
+      "caption": "Jump straight to Watch, Compare or Search the sector"
+    }
+  ]
+}

← cbaea83a fix(deals): correct city mis-assignment — shared parse-locat  ·  back to Rentv 2026  ·  auto-save: 2026-07-23T18:53:06 (3 files) — data/markets.json 35ee65ed →