← back to Rentv V1

public/brief.html

178 lines

<!doctype html><html lang="en"><head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>The RENTV Brief — Commercial Real Estate Digest</title>
<meta name="description" content="The RENTV Brief — a shareable, print-ready snapshot of the latest commercial real estate news, deals and market stats 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}

  .issue{max-width:720px;margin:0 auto;padding:0 22px 60px;width:100%}
  .masthead{text-align:center;padding:34px 0 14px;border-bottom:3px double var(--ink)}
  .masthead .ey{color:var(--red);font-weight:800;font-size:11px;letter-spacing:.22em;text-transform:uppercase}
  .masthead h1{font-family:'Playfair Display',serif;font-size:clamp(38px,6vw,58px);font-weight:800;letter-spacing:-.01em;margin:6px 0 4px}.masthead h1 span{color:var(--red)}
  .masthead .dt{color:var(--sub);font-size:12.5px;font-weight:600;letter-spacing:.03em}
  .actions{display:flex;justify-content:center;gap:10px;padding:14px 0 2px}
  .actions button{display:inline-flex;align-items:center;gap:7px;border:1.5px solid var(--line);background:#fff;border-radius:8px;padding:9px 15px;font:700 12.5px 'Inter';color:var(--ink);cursor:pointer}
  .actions button:hover{border-color:var(--red);color:var(--red)}
  .actions .go{background:var(--red);border-color:var(--red);color:#fff}
  .actions .go:hover{color:#fff}
  .snapshot{display:grid;grid-template-columns:repeat(4,1fr);gap:0;margin:22px 0 6px;border:1px solid var(--line);border-radius:12px;overflow:hidden;background:#fff}
  .snapshot .s{padding:14px 10px;text-align:center;border-right:1px solid var(--line)}
  .snapshot .s:last-child{border-right:0}
  .snapshot .s .v{font-family:'Playfair Display',serif;font-size:24px;font-weight:800}
  .snapshot .s .l{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--sub);margin-top:2px}
  .sec{padding:26px 0 4px}
  .sec .rule{font-size:12px;text-transform:uppercase;letter-spacing:.1em;border-top:2px solid var(--ink);padding-top:9px;margin-bottom:14px;font-weight:800;display:flex;justify-content:space-between}
  .lead{display:block;margin-bottom:6px}
  .lead .im{height:300px;border-radius:8px;background:#12161a center/cover;display:block;margin-bottom:12px;box-shadow:inset 0 -80px 60px -46px rgba(0,0,0,.4)}
  .lead .tag{color:var(--red);font-weight:800;font-size:11px;letter-spacing:.12em;text-transform:uppercase}
  .lead h2{font-family:'Playfair Display',serif;font-size:clamp(26px,4vw,36px);line-height:1.12;font-weight:700;margin-top:6px}
  .lead:hover h2{color:var(--red)}
  .hl{display:grid;grid-template-columns:auto 1fr;gap:12px;padding:11px 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 9px;white-space:nowrap}
  .hl h4{font:600 16px/1.32 'Inter'}
  .hl:hover h4{color:var(--red)}
  .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:19px;color:var(--red);white-space:nowrap}
  .deal:hover h4{color:var(--red)}
  .cta{background:var(--red);color:#fff;border-radius:12px;padding:22px;text-align:center;margin:30px 0 0}
  .cta h3{font-family:'Playfair Display',serif;font-size:22px;margin-bottom:8px}
  .cta a{display:inline-block;background:#0b0e12;color:#fff;border-radius:7px;padding:11px 22px;font-weight:800;font-size:13px;margin-top:4px}
  .foot{text-align:center;color:var(--sub);font-size:11.5px;padding:20px 0 0}
  .toast{position:fixed;left:50%;bottom:26px;transform:translateX(-50%) translateY(20px);background:#0b0e12;color:#fff;padding:11px 20px;border-radius:9px;font-weight:700;font-size:13px;opacity:0;pointer-events:none;transition:.25s;z-index:960}
  .toast.on{opacity:1;transform:translateX(-50%) translateY(0)}
  @media print{
    .top,.drawer,.scrim,.actions,.cta{display:none!important}
    body{background:#fff}
    .issue{max-width:100%;padding:0}
    .lead .im{height:220px;box-shadow:none}
    a{color:#000}
  }
</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="/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" class="active">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="issue">
  <div class="masthead">
    <div class="ey">Commercial Real Estate · Western U.S.</div>
    <h1>The REN<span>TV</span> Brief</h1>
    <div class="dt" id="dt">Loading the latest issue…</div>
  </div>
  <div class="actions">
    <button class="go" id="print">🖨 Print / PDF</button>
    <button id="share">🔗 Share</button>
    <a href="/subscribe"><button>✉️ Subscribe</button></a>
  </div>

  <div class="snapshot" id="snapshot"></div>

  <div class="sec"><div class="rule">Top Story</div><div id="lead"></div></div>
  <div class="sec" id="more"><div class="rule">More Headlines <span id="hlcount" style="color:var(--sub)"></span></div><div id="headlines"></div></div>
  <div class="sec" id="biggest"><div class="rule">Biggest Deals</div><div id="deals"></div></div>

  <div class="cta"><h3>Get The RENTV Brief in your inbox</h3><div>The Western U.S. CRE market, distilled — free.</div><a href="/subscribe">Subscribe free →</a></div>
  <div class="foot" id="foot"></div>
</main>
<div class="toast" id="toast"></div>

<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()});

$('print').onclick=()=>window.print();
function toast(m){const t=$('toast');t.textContent=m;t.classList.add('on');setTimeout(()=>t.classList.remove('on'),1900);}
$('share').onclick=async()=>{
  const url=location.origin+'/brief';
  if(navigator.share){try{await navigator.share({title:'The RENTV Brief',url});return;}catch(e){}}
  try{await navigator.clipboard.writeText(url);toast('Link copied to clipboard');}catch(e){toast(url);}
};

const artHref=n=>'/article.html?id='+encodeURIComponent(n.id);
const usd=n=>n>=1e6?('$'+(n/1e6).toFixed(1)+'M'):n>=1e3?('$'+Math.round(n/1e3)+'K'):('$'+Math.round(n));

(async function(){
  let news={items:[]},pulse={kpis:{}},deals={deals:[]};
  try{ [news,pulse,deals]=await Promise.all([
    fetch('/api/news').then(r=>r.json()),
    fetch('/api/pulse').then(r=>r.json()),
    fetch('/api/deals?limit=200').then(r=>r.json()),
  ]); }catch(e){ $('dt').textContent='Could not load the latest issue.'; return; }

  const when=pulse.updated||news.fetched_at||Date.now();
  const d=new Date(when);
  $('dt').textContent=d.toLocaleDateString(undefined,{weekday:'long',month:'long',day:'numeric',year:'numeric'});

  const k=pulse.kpis||{};
  $('snapshot').innerHTML=[
    [k.totalVolumeLabel||'—','Tracked volume'],[k.dealCount||'—','Deals'],
    [k.avgSizeLabel||'—','Avg size'],[k.marketCount||'—','Markets'],
  ].map(([v,l])=>`<div class="s"><div class="v">${esc(v)}</div><div class="l">${esc(l)}</div></div>`).join('');

  const items=news.items||[];
  const lead=items[0];
  if(lead)$('lead').innerHTML=`<a class="lead" href="${artHref(lead)}">${lead.image?`<span class="im" style="background-image:url('${esc(lead.image)}')"></span>`:''}<span class="tag">${esc(lead.cat||'News')}</span><h2>${esc(lead.title)}</h2></a>`;

  const rest=items.slice(1,11);
  $('hlcount').textContent=rest.length?`(${rest.length})`:'';
  $('headlines').innerHTML=rest.map(n=>`<a class="hl" href="${artHref(n)}"><span class="c">${esc(n.cat||'News')}</span><h4>${esc(n.title)}</h4></a>`).join('');

  const big=(deals.deals||[]).filter(x=>x.amount).sort((a,b)=>b.amount-a.amount).slice(0,5);
  $('deals').innerHTML=big.map(x=>`<a class="deal" href="/deals"><div><h4>${esc(x.title)}</h4><div class="m">${[x.property_type,[x.city,x.state].filter(Boolean).join(', ')].filter(Boolean).map(esc).join(' · ')}</div></div><div class="amt">${esc(x.amount_label||usd(x.amount))}</div></a>`).join('');

  $('foot').innerHTML=`The RENTV Brief · generated ${d.toLocaleDateString()} · RENTV.com — Commercial real estate news, Western U.S.`;
})();
</script>
</body></html>