← back to Commercialrealestate
public/firecities.html
148 lines
<!doctype html>
<html lang="en">
<head>
<script>(function(){try{var t=localStorage.getItem('crcp-theme');document.documentElement.setAttribute('data-theme',t==='light'?'light':'dark');}catch(e){document.documentElement.setAttribute('data-theme','dark');}})();</script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CRCP · Fire Cities</title>
<style>
:root{
--bg:#160f0d; --panel:#221513; --panel2:#2c1a16; --edge:#43261f;
--ink:#f3e9e6; --mut:#c39a8e; --accent:#ff7a45; --accent2:#c2410c; --ember:#ff5722;
}
/* LIGHT mode surface flips — keep the bespoke fire/ember ACCENT, only re-point generic
surfaces to light so day mode has no dark islands (Cycle-6 lesson). Accents unchanged. */
html[data-theme="light"]{
--bg:#fff4ef; --panel:#ffffff; --panel2:#fff0e9; --edge:#f0d3c6;
--ink:#2a1712; --mut:#8a5c48;
}
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--ink);
font:15px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;min-height:100vh}
.wrap{max-width:1080px;margin:0 auto;padding:40px 20px 80px}
header.top{display:flex;align-items:baseline;gap:14px;flex-wrap:wrap;margin-bottom:6px}
header.top h1{font-size:26px;font-weight:700;margin:0;letter-spacing:.2px}
header.top h1 .fl{color:var(--ember)}
header.top .tag{color:var(--mut);font-size:14px}
.sub{color:var(--mut);margin:0 0 24px;max-width:70ch}
.panel{background:var(--panel);border:1px solid var(--edge);border-radius:14px;padding:22px;box-shadow:0 8px 30px rgba(0,0,0,.35)}
.pickrow{display:flex;gap:12px;flex-wrap:wrap;align-items:center}
label.lbl{color:var(--mut);font-size:13px;text-transform:uppercase;letter-spacing:.6px;display:block;margin-bottom:8px}
select,button{font:inherit}
select#city{flex:1 1 320px;min-width:240px;background:var(--panel2);color:var(--ink);border:1px solid var(--edge);
border-radius:10px;padding:13px 14px;appearance:none;
background-image:linear-gradient(45deg,transparent 50%,var(--mut) 50%),linear-gradient(135deg,var(--mut) 50%,transparent 50%);
background-position:calc(100% - 20px) 20px,calc(100% - 14px) 20px;background-size:6px 6px,6px 6px;background-repeat:no-repeat}
button.go{background:var(--accent2);color:#fff;border:1px solid var(--accent);border-radius:10px;padding:13px 22px;cursor:pointer;font-weight:600}
button.go:hover{background:var(--accent)}
.count{color:var(--mut);font-size:13px;margin:16px 0 6px}
.group{margin-top:22px}
.group h2{font-size:13px;text-transform:uppercase;letter-spacing:.8px;color:var(--ember);margin:0 0 10px;display:flex;align-items:center;gap:8px}
.group h2 .dot{width:8px;height:8px;border-radius:50%;background:var(--ember);box-shadow:0 0 8px var(--ember)}
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:10px}
a.city{display:flex;justify-content:space-between;align-items:center;gap:10px;text-decoration:none;color:var(--ink);
background:var(--panel2);border:1px solid var(--edge);border-radius:10px;padding:12px 14px;transition:.12s}
a.city:hover{border-color:var(--accent);background:var(--panel);transform:translateY(-1px)}
a.city.empty{opacity:.55}
a.city .nm{font-weight:600}
a.city .host{display:block;color:var(--mut);font-size:12px;margin-top:2px;font-weight:400}
a.city .n{flex:0 0 auto;font-size:12px;color:var(--mut);background:var(--bg);border:1px solid var(--edge);border-radius:20px;padding:2px 9px}
a.city .n.has{color:#ffcaa8;border-color:var(--accent2)}
.links{margin-top:26px;display:flex;gap:12px;flex-wrap:wrap}
.links a{color:#ffb38a;text-decoration:none;border:1px solid var(--edge);border-radius:8px;padding:6px 12px;font-size:13px}
.links a:hover{border-color:var(--accent)}
footer{color:var(--mut);font-size:12px;margin-top:30px}
</style>
<link rel="stylesheet" href="/crcp-theme.css"><!-- CRCP day/night tokens: load LAST so html[data-theme] wins -->
<link rel="stylesheet" href="/nav-agent/nav-agent.css"><!-- nav-agent -->
</head>
<body>
<div class="wrap">
<header class="top">
<h1><span class="fl">🔥</span> CRCP · Fire Cities</h1>
<span class="tag">Commercial real estate in the 2025 LA burn zones</span>
</header>
<p class="sub">The fire-affected markets from the January 2025 Eaton and Palisades fires. Choose a
city to open its scoped CRE dashboard — rebuild activity, listings, and broker coverage.</p>
<div class="panel">
<label class="lbl" for="city">Jump to a burn-zone city</label>
<div class="pickrow">
<select id="city" aria-label="Select a fire-affected city"></select>
<button class="go" id="go">Open →</button>
</div>
<div class="count" id="count"></div>
<div id="groups"></div>
<div class="links">
<a href="https://recities.crcp.agentabrams.com/">← All cities (recities)</a>
<a href="https://crcp.agentabrams.com/">All markets (base CRCP)</a>
</div>
</div>
<footer id="foot"></footer>
</div>
<script src="/crcp-cities.js"></script>
<script>
var FIRE = window.CRCP_CITIES.FIRE_CITIES.slice(); // burn-zone cities from the shared module
var sameCity = window.CRCP_CITIES.sameCity;
var counts = {}, loaded = false;
var urlOf = function (c) { return "https://" + c.host + "/"; };
var sel = document.getElementById('city'), groups = document.getElementById('groups'),
count = document.getElementById('count'), foot = document.getElementById('foot');
fetch('/data/ranked.json').then(function (r) { return r.json(); }).then(function (d) {
var arr = (d && d.ranked) || [];
FIRE.forEach(function (c) { counts[c.slug] = arr.filter(function (p) { return sameCity(p.city, c); }).length; });
loaded = true; render();
}).catch(function () { loaded = true; render(); });
function ordered() {
return FIRE.slice().sort(function (a, b) {
var na = counts[a.slug] || 0, nb = counts[b.slug] || 0;
if (nb !== na) return nb - na;
return a.label.localeCompare(b.label);
});
}
function fillSelect() {
sel.innerHTML = '';
ordered().forEach(function (c) {
var o = document.createElement('option'); o.value = c.slug;
o.textContent = c.label + (loaded ? ' (' + (counts[c.slug] || 0) + ')' : '');
sel.appendChild(o);
});
}
function card(c) {
var n = counts[c.slug] || 0;
return '<a class="city' + (loaded && n === 0 ? ' empty' : '') + '" href="' + urlOf(c) + '">' +
'<span><span class="nm">' + c.label + '</span><span class="host">' + c.host + '</span></span>' +
'<span class="n' + (n ? ' has' : '') + '">' + (loaded ? n : '·') + '</span></a>';
}
function render() {
fillSelect();
// group by incident (fire label)
var byFire = {};
ordered().forEach(function (c) { (byFire[c.fire] = byFire[c.fire] || []).push(c); });
var html = '';
Object.keys(byFire).forEach(function (fire) {
var tot = byFire[fire].reduce(function (s, c) { return s + (counts[c.slug] || 0); }, 0);
html += '<div class="group"><h2><span class="dot"></span>' + fire +
(loaded ? ' · ' + tot + ' listings' : '') + '</h2><div class="grid">' +
byFire[fire].map(card).join('') + '</div></div>';
});
groups.innerHTML = html;
var total = FIRE.reduce(function (s, c) { return s + (counts[c.slug] || 0); }, 0);
count.textContent = loaded ? (FIRE.length + ' burn-zone cities · ' + total + ' listings') : (FIRE.length + ' burn-zone cities');
foot.textContent = 'CRCP · firecities.crcp.agentabrams.com';
}
function open() { var c = FIRE.find(function (x) { return x.slug === sel.value; }); if (c) window.location.href = urlOf(c); }
document.getElementById('go').addEventListener('click', open);
sel.addEventListener('keydown', function (e) { if (e.key === 'Enter') open(); });
render();
</script>
<script src="/crcp-theme.js" defer></script><!-- CRCP day/night toggle (auto-injects into header) -->
<script src="/corner-nav.js" defer></script>
<script src="/nav-agent/nav-agent.js" defer></script><!-- nav-agent -->
</body>
</html>