← back to Commercialrealestate
CRCP: fleet-wide day/night toggle + legibility pass across all pages
c99253266b82e83935cb223003b5a8e2920ff1bf · 2026-08-07 15:33:47 -0700 · Steve
Shared theme system (crcp-theme.css tokens + crcp-theme.js auto-injecting toggle),
wired into every page (index, condos, crcp, mls, graphics, fha-loans). Each page's
hardcoded dark colors swapped to themeable vars so the light/Day theme works, muted
text brightened for contrast, harsh white table borders removed, zebra striping +
row hover added. Toggle persists (localStorage crcp-theme) with a no-flash head guard.
Default stays dark; now every page reads cleanly and flips to a real Day mode.
Files touched
A public/crcp-theme.cssA public/crcp-theme.jsM public/crcp.htmlM public/fha-loans.htmlM public/graphics.htmlM public/index.htmlM public/mls.html
Diff
commit c99253266b82e83935cb223003b5a8e2920ff1bf
Author: Steve <steve@designerwallcoverings.com>
Date: Fri Aug 7 15:33:47 2026 -0700
CRCP: fleet-wide day/night toggle + legibility pass across all pages
Shared theme system (crcp-theme.css tokens + crcp-theme.js auto-injecting toggle),
wired into every page (index, condos, crcp, mls, graphics, fha-loans). Each page's
hardcoded dark colors swapped to themeable vars so the light/Day theme works, muted
text brightened for contrast, harsh white table borders removed, zebra striping +
row hover added. Toggle persists (localStorage crcp-theme) with a no-flash head guard.
Default stays dark; now every page reads cleanly and flips to a real Day mode.
---
public/crcp-theme.css | 22 +++++++++++++++++++
public/crcp-theme.js | 32 ++++++++++++++++++++++++++++
public/crcp.html | 19 ++++++++++++-----
public/fha-loans.html | 11 ++++++----
public/graphics.html | 16 ++++++++------
public/index.html | 59 +++++++++++++++++++++++++++------------------------
public/mls.html | 34 ++++++++++++++++++++---------
7 files changed, 140 insertions(+), 53 deletions(-)
diff --git a/public/crcp-theme.css b/public/crcp-theme.css
new file mode 100644
index 0000000..6f37bd0
--- /dev/null
+++ b/public/crcp-theme.css
@@ -0,0 +1,22 @@
+/* CRCP shared day/night theme tokens — single source of truth across all pages.
+ Load LAST (after each page's own <style>) so it overrides local :root values.
+ Defines BOTH naming conventions in use (--mut AND --muted) so every page themes. */
+html[data-theme="dark"]{
+ --bg:#0d1117; --bg2:#171d26; --card:#1c232e; --line:#33404f; --line2:#3f4c5c;
+ --ink:#f2f6fb; --text:#f2f6fb; --mut:#b3c0cf; --muted:#b3c0cf; --sub:#b3c0cf;
+ --headbg:rgba(13,17,23,.98); --stripe:rgba(255,255,255,.025); --hover:rgba(121,184,255,.10);
+ --acc:#4bd268; --blue:#79b8ff; --gold:#e3b341; --red:#ff7b72; --purp:#c8a2ff;
+}
+html[data-theme="light"]{
+ --bg:#f4f6f9; --bg2:#ffffff; --card:#ffffff; --line:#d5dbe2; --line2:#c2cad4;
+ --ink:#12171e; --text:#12171e; --mut:#525f6e; --muted:#525f6e; --sub:#525f6e;
+ --headbg:rgba(255,255,255,.98); --stripe:rgba(20,30,45,.028); --hover:rgba(9,105,218,.08);
+ --acc:#1a7f37; --blue:#0969da; --gold:#9a6700; --red:#cf222e; --purp:#8250df;
+}
+/* shared toggle button (auto-injected by crcp-theme.js into the page header) */
+#crcpThemeToggle{background:var(--card);color:var(--ink);border:1px solid var(--line);border-radius:8px;
+ padding:6px 11px;font-size:13px;cursor:pointer;display:inline-flex;align-items:center;gap:6px;font-family:inherit;}
+#crcpThemeToggle:hover{border-color:var(--blue);}
+/* readability lift that helps every list/table page (harmless where selectors don't exist) */
+.listtbl tbody tr:nth-child(even) td,tbody tr.row:nth-child(even),.tbl tbody tr:nth-child(even) td{background:var(--stripe);}
+.listtbl tbody tr:hover td,.tbl tbody tr:hover td{background:var(--hover);}
diff --git a/public/crcp-theme.js b/public/crcp-theme.js
new file mode 100644
index 0000000..bcc771c
--- /dev/null
+++ b/public/crcp-theme.js
@@ -0,0 +1,32 @@
+/* CRCP shared day/night toggle — auto-injects a button into the page header,
+ persists to localStorage (key: crcp-theme), applies before paint via the inline
+ head-guard each page also carries. Zero deps. */
+(function () {
+ var root = document.documentElement;
+ function label(t) {
+ var b = document.getElementById('crcpThemeToggle'); if (!b) return;
+ b.innerHTML = (t === 'light' ? '🌙' : '☀️') + ' <span>' + (t === 'light' ? 'Night' : 'Day') + '</span>';
+ }
+ function apply(t) {
+ root.setAttribute('data-theme', t);
+ try { localStorage.setItem('crcp-theme', t); } catch (e) { }
+ label(t);
+ }
+ function current() { var t; try { t = localStorage.getItem('crcp-theme'); } catch (e) { } return t === 'light' ? 'light' : 'dark'; }
+
+ function mount() {
+ if (document.getElementById('crcpThemeToggle')) { label(current()); return; }
+ var btn = document.createElement('button');
+ btn.id = 'crcpThemeToggle'; btn.type = 'button';
+ btn.title = 'Toggle day / night'; btn.setAttribute('aria-label', 'Toggle day / night theme');
+ btn.addEventListener('click', function () { apply(root.getAttribute('data-theme') === 'light' ? 'dark' : 'light'); });
+ // prefer an existing header nav; else the first <header>; else fixed top-right
+ var host = document.querySelector('header .nav') || document.querySelector('header');
+ if (host) { host.appendChild(btn); }
+ else { btn.style.cssText += ';position:fixed;top:12px;right:14px;z-index:99999'; document.body.appendChild(btn); }
+ label(current());
+ }
+ // ensure a theme is set even if a page lacks the inline head-guard
+ if (!root.getAttribute('data-theme')) root.setAttribute('data-theme', current());
+ if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', mount); else mount();
+})();
diff --git a/public/crcp.html b/public/crcp.html
index e846aa1..ae923b8 100644
--- a/public/crcp.html
+++ b/public/crcp.html
@@ -1,16 +1,18 @@
<!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">
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Crect width='16' height='16' rx='3' fill='%230a0d13'/%3E%3Ctext x='8' y='12' font-size='11' text-anchor='middle' fill='%23c8a24b'%3E%24%3C/text%3E%3C/svg%3E">
<title>CRCP — Commercial Real Estate Control Panel</title>
<style>
/* Emulates CNCP (localhost:3333): dark panels, gold accent, status colors. */
- :root{ --bg:#0c0f15; --panel:#141925; --panel2:#1d2230; --fg:#E6E8EC; --muted:#8A93A2; --gold:#C8A24B;
- --active:#70AD47; --staged:#E0A33E; --draft:#5B9BD5; --archived:#5A6472; --del:#E74C3C; --line:#232a38; }
+ /* Dark fallbacks (shared crcp-theme.css overrides these per html[data-theme] after load) */
+ :root{ --bg:#0d1117; --panel:#1c232e; --panel2:#171d26; --fg:#f2f6fb; --muted:#8A93A2; --gold:#C8A24B;
+ --active:#70AD47; --staged:#E0A33E; --draft:#5B9BD5; --archived:#5A6472; --del:#E74C3C; --line:#33404f; }
*{box-sizing:border-box;} body{margin:0;background:var(--bg);color:var(--fg);font:14px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;}
- header{display:flex;align-items:center;gap:14px;padding:14px 22px;border-bottom:1px solid var(--line);background:linear-gradient(180deg,#10141d,#0c0f15);position:sticky;top:0;z-index:10;}
+ header{display:flex;align-items:center;gap:14px;padding:14px 22px;border-bottom:1px solid var(--line);background:var(--bg);position:sticky;top:0;z-index:10;}
header h1{margin:0;font-size:18px;letter-spacing:.5px;} header h1 b{color:var(--gold);}
.live{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--muted);}
.pulse{width:9px;height:9px;border-radius:50%;background:var(--active);box-shadow:0 0 0 0 rgba(112,173,71,.6);animation:p 1.6s infinite;}
@@ -59,7 +61,7 @@
.atype.com{background:rgba(200,162,75,.14);color:var(--gold);border:1px solid rgba(200,162,75,.4);}
.atype.arc{background:rgba(127,174,106,.18);color:#8fd06f;border:1px solid rgba(127,174,106,.55);}
.has{color:var(--active);} .miss{color:var(--archived);}
- .bar{height:8px;background:#0a0d13;border-radius:5px;overflow:hidden;margin-top:4px;}
+ .bar{height:8px;background:var(--bg);border-radius:5px;overflow:hidden;margin-top:4px;}
.bar i{display:block;height:100%;background:linear-gradient(90deg,var(--gold),var(--active));}
.prog{display:flex;justify-content:space-between;font-size:12px;color:var(--muted);margin-top:10px;}
.meta{font-size:11px;color:var(--muted);margin-top:6px;}
@@ -123,7 +125,7 @@
.dscr .rentsum{font-size:12px;color:var(--muted);margin-top:7px;} .dscr .rentsum b{color:var(--active);font-variant-numeric:tabular-nums;}
.dscr .dtog{display:inline-flex;border:1px solid var(--line);border-radius:9px;overflow:hidden;}
.dscr .dtog button{background:var(--panel2);border:0;color:var(--muted);padding:6px 12px;font-size:12px;cursor:pointer;} .dscr .dtog button.on{background:rgba(200,162,75,.14);color:var(--gold);}
- .dscr .dresult{background:#0a0d13;border:1px solid var(--line);border-radius:12px;padding:18px 16px;text-align:center;}
+ .dscr .dresult{background:var(--bg);border:1px solid var(--line);border-radius:12px;padding:18px 16px;text-align:center;}
.dscr .dresult .ratio{font-size:48px;font-weight:800;font-variant-numeric:tabular-nums;line-height:1;margin-top:4px;}
.dscr .dbadge{display:inline-block;margin-top:12px;font-size:13px;font-weight:800;letter-spacing:.4px;text-transform:uppercase;padding:6px 14px;border-radius:20px;}
.dscr .dbadge.pass{background:rgba(112,173,71,.15);color:var(--active);border:1px solid rgba(112,173,71,.5);}
@@ -135,6 +137,12 @@
.dscr pre{white-space:pre-wrap;background:var(--panel2);border:1px solid var(--line);border-radius:9px;padding:12px;font:12.5px/1.6 ui-monospace,SFMono-Regular,Menlo,monospace;color:var(--fg);margin:6px 0 0;}
.dscr .dactions{display:flex;gap:8px;flex-wrap:wrap;margin-top:8px;} .dscr .dactions button{background:var(--panel2);border:1px solid var(--line);color:var(--fg);border-radius:8px;padding:7px 12px;font-size:12px;cursor:pointer;} .dscr .dactions .prime{background:var(--gold);color:#1a1206;border-color:var(--gold);font-weight:700;}
</style>
+<link rel="stylesheet" href="/crcp-theme.css">
+<style>
+ /* Bridge: map page-local aliases to shared tokens so JS inline styles using --fg/--panel still work */
+ html[data-theme="dark"] { --panel:var(--card); --panel2:var(--bg2); --fg:var(--ink); }
+ html[data-theme="light"] { --panel:var(--card); --panel2:var(--bg2); --fg:var(--ink); }
+</style>
</head>
<body>
<header>
@@ -793,5 +801,6 @@ loadSegments(); setInterval(loadSegments, 20000);
</script>
<script src="/col-resize.js" defer></script>
<script src="/corner-nav.js" defer></script>
+<script src="/crcp-theme.js" defer></script>
</body>
</html>
diff --git a/public/fha-loans.html b/public/fha-loans.html
index 52e7bec..3890d15 100644
--- a/public/fha-loans.html
+++ b/public/fha-loans.html
@@ -1,6 +1,7 @@
<!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">
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Crect width='16' height='16' rx='3' fill='%230a0d13'/%3E%3Ctext x='8' y='12' font-size='11' text-anchor='middle' fill='%23c8a24b'%3E%24%3C/text%3E%3C/svg%3E">
@@ -18,7 +19,7 @@
--cg-topbg:rgba(7,10,16,.72); --cg-red:#f85149;
}
*{box-sizing:border-box;margin:0;padding:0;}
- html,body{min-height:100%;background:#070a10;color:var(--ink);font:15px/1.5 -apple-system,'SF Pro Display',Segoe UI,Roboto,sans-serif;-webkit-font-smoothing:antialiased;}
+ html,body{min-height:100%;background:var(--bg);color:var(--ink);font:15px/1.5 -apple-system,'SF Pro Display',Segoe UI,Roboto,sans-serif;-webkit-font-smoothing:antialiased;}
body::before{content:'';position:fixed;inset:-25%;z-index:-2;
background:
radial-gradient(38vw 38vw at 18% 22%, rgba(139,124,246,.40), transparent 60%),
@@ -26,7 +27,7 @@
radial-gradient(40vw 40vw at 72% 86%, rgba(233,196,106,.30), transparent 62%),
radial-gradient(36vw 36vw at 24% 88%, rgba(96,165,250,.30), transparent 60%);
filter:saturate(1.25);animation:drift 26s ease-in-out infinite alternate;}
- body::after{content:'';position:fixed;inset:0;z-index:-1;backdrop-filter:blur(70px);background:rgba(7,10,16,.34);}
+ body::after{content:'';position:fixed;inset:0;z-index:-1;backdrop-filter:blur(70px);background:color-mix(in srgb,var(--bg) 34%,transparent);}
@keyframes drift{0%{transform:translate3d(0,0,0) scale(1) rotate(0deg);}
50%{transform:translate3d(2%,-2%,0) scale(1.08) rotate(4deg);}100%{transform:translate3d(-2%,2%,0) scale(1.04) rotate(-3deg);}}
.wrap{max-width:1320px;margin:0 auto;padding:32px 32px 60px;}
@@ -74,7 +75,7 @@
/* table */
.tablewrap{padding:6px;overflow-x:auto;}
table{width:100%;border-collapse:separate;border-spacing:0;font-size:var(--tsz,13px);font-variant-numeric:tabular-nums;}
- thead th{position:sticky;top:0;background:rgba(16,20,28,.92);backdrop-filter:blur(8px);text-align:left;
+ thead th{position:sticky;top:0;background:var(--headbg);backdrop-filter:blur(8px);text-align:left;
font-size:11px;font-weight:700;letter-spacing:.4px;text-transform:uppercase;color:var(--muted);
padding:11px 12px;border-bottom:1px solid var(--glassb);cursor:pointer;user-select:none;white-space:nowrap;}
thead th:hover{color:#fff;}
@@ -125,7 +126,7 @@
/* expandable-row detail modal */
#fov{display:none;position:fixed;inset:0;background:rgba(0,0,0,.62);z-index:80;align-items:flex-start;justify-content:center;padding:40px 14px;overflow-y:auto;}
#fov.on{display:flex;}
- #fmodal{width:min(640px,96vw);background:rgba(16,20,28,.98);border:1px solid var(--glassb);border-radius:16px;padding:20px 22px;position:relative;backdrop-filter:blur(22px);}
+ #fmodal{width:min(640px,96vw);background:var(--card);border:1px solid var(--line);border-radius:16px;padding:20px 22px;position:relative;backdrop-filter:blur(22px);}
#fmodal h3{margin:0 0 3px;font-size:19px;color:#fff;} #fmodal .msub{color:var(--gold);font-size:12.5px;margin-bottom:6px;}
#fmodal .x{position:absolute;top:12px;right:14px;background:none;border:0;color:var(--muted);font-size:22px;cursor:pointer;}
#fmodal .litem{display:flex;justify-content:space-between;gap:12px;padding:5px 0;border-bottom:1px solid rgba(255,255,255,.06);font-size:13px;}
@@ -135,6 +136,7 @@
.pill{display:inline-block;padding:2px 9px;border-radius:11px;background:var(--glass);border:1px solid var(--glassb);margin:0 3px;}
@media(prefers-reduced-motion:reduce){body::before{animation:none;}.glass{animation:none;opacity:1;transform:none;}}
</style>
+<link rel="stylesheet" href="/crcp-theme.css">
</head>
<body>
<div class="wrap">
@@ -498,5 +500,6 @@ load();
<script src="/col-resize.js" defer></script>
<script src="/global-search.js" defer></script>
<script src="/corner-nav.js" defer></script>
+<script src="/crcp-theme.js" defer></script>
</body>
</html>
diff --git a/public/graphics.html b/public/graphics.html
index 5645eea..2c39a58 100644
--- a/public/graphics.html
+++ b/public/graphics.html
@@ -1,22 +1,22 @@
<!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">
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Crect width='16' height='16' rx='3' fill='%230e1116'/%3E%3Ctext x='8' y='12' font-size='10' text-anchor='middle' fill='%233fb950'%3E%F0%9F%93%8A%3C/text%3E%3C/svg%3E">
<title>CRE Graphics — Brokers, Firms & Warrantability · LA County</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js"></script>
<style>
- :root{ --bg:#0e1116; --card:#161b22; --line:#2a313c; --ink:#e6edf3; --mut:#8b949e; --acc:#3fb950; --blue:#58a6ff; --gold:#d29922; --red:#f85149; }
*{box-sizing:border-box;} html,body{margin:0;}
body{background:var(--bg);color:var(--ink);font:14px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;}
- header{display:flex;align-items:center;gap:16px;padding:14px 22px;border-bottom:1px solid var(--line);position:sticky;top:0;background:var(--bg);z-index:5;}
+ header{display:flex;align-items:center;gap:16px;padding:14px 22px;border-bottom:1px solid var(--line);position:sticky;top:0;background:var(--headbg);backdrop-filter:blur(8px);z-index:5;}
header h1{font-size:18px;margin:0;} header a{color:var(--blue);text-decoration:none;font-size:13px;}
header .nav{margin-left:auto;display:flex;gap:18px;}
.stats{display:flex;gap:18px;font-size:12px;color:var(--mut);padding:10px 22px;flex-wrap:wrap;border-bottom:1px solid var(--line);}
.stats b{color:var(--ink);font-size:16px;}
main{padding:32px;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:26px;max-width:1400px;margin:0 auto;}
- .card{background:var(--card);border:2px solid #fff;border-radius:12px;padding:24px;min-height:340px;display:flex;flex-direction:column;}
+ .card{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:24px;min-height:340px;display:flex;flex-direction:column;}
.card.wide{grid-column:1 / -1;}
.card h2{font-size:14px;margin:0 0 4px;}
.card .sub{font-size:12px;color:var(--mut);margin:0 0 14px;}
@@ -39,6 +39,7 @@
.chartwrap canvas{cursor:default;}
@media(max-width:820px){ main{grid-template-columns:1fr;} }
</style>
+<link rel="stylesheet" href="/crcp-theme.css">
</head>
<body>
<header>
@@ -102,6 +103,8 @@
<script>
const $=s=>document.querySelector(s);
const GH={ ink:'#e6edf3', mut:'#8b949e', line:'#2a313c', acc:'#3fb950', blue:'#58a6ff', gold:'#d29922', red:'#f85149' };
+// Read CSS token for doughnut slice-gap — adapts to day/night theme.
+const CARD_BG=getComputedStyle(document.documentElement).getPropertyValue('--card').trim()||'#1c232e';
Chart.defaults.color=GH.mut; Chart.defaults.borderColor=GH.line; Chart.defaults.font.family='-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif';
const PALETTE=['#58a6ff','#3fb950','#d29922','#bc8cff','#f85149','#39c5cf','#db61a2','#7ee787','#ffa657','#a5d6ff','#ff7b72','#56d364'];
@@ -133,7 +136,7 @@ const HOVER=(evt,els)=>{ const t=evt&&evt.native&&evt.native.target; if(t) t.sty
: Array.isArray(firmsRaw&&firmsRaw.firms) ? firmsRaw.firms : [];
new Chart($('#firmChart'),{ type:'doughnut', data:{
labels: firms.map(f=>f.firm),
- datasets:[{ data:firms.map(f=>f.listings), backgroundColor:PALETTE, borderColor:'#161b22', borderWidth:2 }] },
+ datasets:[{ data:firms.map(f=>f.listings), backgroundColor:PALETTE, borderColor:CARD_BG, borderWidth:2 }] },
options:{ responsive:true, maintainAspectRatio:false, cutout:'52%',
onHover:HOVER, onClick:(e,els)=>{ if(els.length){ const f=firms[els[0].index]; if(f) go('/crcp.html?firm='+enc(f.firm||'')); } },
plugins:{ legend:{ position:'right', labels:{ boxWidth:10, font:{size:11} } },
@@ -146,7 +149,7 @@ const HOVER=(evt,els)=>{ const t=evt&&evt.native&&evt.native.target; if(t) t.sty
$('#listingWarrantLabel').textContent = '⚖️ ' + (cs.label||'') + ' · ' + (cs.total||0) + ' real listings · ' + (cs.source||'');
new Chart($('#listingWarrantChart'),{ type:'doughnut', data:{
labels: lwKeys.map(k=>lwLabels[k]||k),
- datasets:[{ data:lwKeys.map(k=>cs.byStatus[k]), backgroundColor:lwKeys.map(k=>k==='fha_approved'?GH.acc:k==='fha_expired'?GH.gold:k==='heuristic_flag'?GH.red:GH.mut), borderColor:'#161b22', borderWidth:2 }] },
+ datasets:[{ data:lwKeys.map(k=>cs.byStatus[k]), backgroundColor:lwKeys.map(k=>k==='fha_approved'?GH.acc:k==='fha_expired'?GH.gold:k==='heuristic_flag'?GH.red:GH.mut), borderColor:CARD_BG, borderWidth:2 }] },
options:{ responsive:true, maintainAspectRatio:false, cutout:'55%',
onHover:HOVER, onClick:(e,els)=>{ if(els.length){ go('/condos.html?status='+enc(lwKeys[els[0].index])); } },
plugins:{ legend:{ position:'bottom', labels:{ boxWidth:11, font:{size:11} } } } } });
@@ -170,7 +173,7 @@ const HOVER=(evt,els)=>{ const t=evt&&evt.native&&evt.native.target; if(t) t.sty
const wkeys=Object.keys(w.byStatus);
new Chart($('#warrantChart'),{ type:'doughnut', data:{
labels: wkeys.map(k=>wlabels[k]||k),
- datasets:[{ data:wkeys.map(k=>w.byStatus[k]), backgroundColor:wkeys.map(k=>k==='fha_approved'?GH.acc:k==='fha_expired'?GH.gold:GH.mut), borderColor:'#161b22', borderWidth:2 }] },
+ datasets:[{ data:wkeys.map(k=>w.byStatus[k]), backgroundColor:wkeys.map(k=>k==='fha_approved'?GH.acc:k==='fha_expired'?GH.gold:GH.mut), borderColor:CARD_BG, borderWidth:2 }] },
options:{ responsive:true, maintainAspectRatio:false, cutout:'55%',
onHover:HOVER, onClick:(e,els)=>{ if(els.length){ const k=wkeys[els[0].index]; go('/condos.html?status='+enc(k==='fha_other'?'all':k)); } },
plugins:{ legend:{ position:'bottom', labels:{ boxWidth:11, font:{size:11} } } } } });
@@ -209,5 +212,6 @@ const HOVER=(evt,els)=>{ const t=evt&&evt.native&&evt.native.target; if(t) t.sty
</script>
<script src="/col-resize.js" defer></script>
<script src="/corner-nav.js" defer></script>
+<script src="/crcp-theme.js" defer></script>
</body>
</html>
diff --git a/public/index.html b/public/index.html
index ebe31bc..ea91b62 100644
--- a/public/index.html
+++ b/public/index.html
@@ -1,19 +1,20 @@
<!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">
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Crect width='16' height='16' rx='3' fill='%230e1116'/%3E%3Ctext x='8' y='12' font-size='11' text-anchor='middle' fill='%233fb950'%3E%24%3C/text%3E%3C/svg%3E">
<title>LA County CRE — Investment Explorer</title>
<style>
- :root { --cols:3; --bg:#0e1116; --card:#161b22; --line:#2a313c; --ink:#e6edf3; --mut:#8b949e; --acc:#3fb950; --warn:#d29922; --bad:#f85149; --blue:#58a6ff; --drawerW:316px; }
+ :root { --cols:3; --drawerW:316px; }
* { box-sizing:border-box; }
:focus-visible { outline:2px solid var(--blue); outline-offset:2px; border-radius:4px; }
@media (prefers-reduced-motion: reduce){ *,*::before,*::after { animation-duration:.001ms !important; animation-iteration-count:1 !important; transition-duration:.001ms !important; scroll-behavior:auto !important; } }
body { margin:0; background:var(--bg); color:var(--ink); font:15px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif; }
/* ---- top bar ---- */
- header { display:flex; align-items:center; gap:14px; padding:12px 20px; border-bottom:1px solid var(--line); position:sticky; top:0; z-index:30; background:rgba(14,17,22,.97); backdrop-filter:blur(8px); }
+ header { display:flex; align-items:center; gap:14px; padding:12px 20px; border-bottom:1px solid var(--line); position:sticky; top:0; z-index:30; background:var(--headbg); backdrop-filter:blur(8px); }
.burger { display:inline-flex; align-items:center; gap:8px; background:var(--card); color:var(--ink); border:1px solid var(--line); border-radius:10px; padding:9px 13px; font-size:15px; cursor:pointer; font-weight:600; }
.burger:hover { border-color:var(--blue); }
.fcount { display:none; background:var(--blue); color:#04122b; font-size:11px; font-weight:700; border-radius:20px; padding:1px 7px; }
@@ -31,9 +32,9 @@
/* ---- left drawer ---- */
#scrim { position:fixed; inset:0; background:rgba(0,0,0,.5); opacity:0; pointer-events:none; transition:opacity .2s; z-index:38; }
#scrim.on { opacity:1; pointer-events:auto; }
- #drawer { position:fixed; top:0; left:0; height:100vh; width:var(--drawerW); background:#0b0e13; border-right:1px solid var(--line); transform:translateX(-100%); transition:transform .22s ease; z-index:40; overflow-y:auto; padding:0 0 40px; }
+ #drawer { position:fixed; top:0; left:0; height:100vh; width:var(--drawerW); background:var(--bg2); border-right:1px solid var(--line); transform:translateX(-100%); transition:transform .22s ease; z-index:40; overflow-y:auto; padding:0 0 40px; }
#drawer.open { transform:translateX(0); box-shadow:6px 0 30px rgba(0,0,0,.4); }
- .dhead { display:flex; align-items:center; justify-content:space-between; padding:16px 18px 10px; position:sticky; top:0; background:#0b0e13; border-bottom:1px solid var(--line); z-index:2; }
+ .dhead { display:flex; align-items:center; justify-content:space-between; padding:16px 18px 10px; position:sticky; top:0; background:var(--bg2); border-bottom:1px solid var(--line); z-index:2; }
.dhead b { font-size:15px; } .dhead .x { background:none; border:0; color:var(--mut); font-size:18px; cursor:pointer; }
.fsec { padding:14px 18px; border-bottom:1px solid var(--line); }
.fsec h4 { margin:0 0 9px; font-size:11px; text-transform:uppercase; letter-spacing:.6px; color:var(--mut); }
@@ -53,7 +54,7 @@
.resetbtn { width:calc(100% - 36px); margin:14px 18px 0; background:transparent; color:var(--bad); border:1px solid #7d2b28; border-radius:9px; padding:9px; font-size:13px; cursor:pointer; }
/* ---- results bar + grid ---- */
- .bar { display:flex; flex-wrap:wrap; align-items:center; gap:14px; padding:11px 20px; border-bottom:1px solid var(--line); position:sticky; top:57px; background:rgba(14,17,22,.95); backdrop-filter:blur(6px); z-index:20; }
+ .bar { display:flex; flex-wrap:wrap; align-items:center; gap:14px; padding:11px 20px; border-bottom:1px solid var(--line); position:sticky; top:57px; background:var(--headbg); backdrop-filter:blur(6px); z-index:20; }
.bar .count { font-size:13px; color:var(--mut); } .bar .count b { color:var(--ink); }
.bar label { font-size:11px; color:var(--mut); text-transform:uppercase; letter-spacing:.5px; }
.bar .right { margin-left:auto; display:flex; align-items:center; gap:12px; }
@@ -77,7 +78,7 @@
.bar{ max-width:100%; top:auto; } /* sort/density strip: no hairline overflow; un-stick so it can't tuck under the taller (burger+title) iPad header */
}
@media (max-width:620px){ .grid{ grid-template-columns:1fr;} }
- .card { background:var(--card); border:2px solid #fff; border-radius:14px; padding:24px; display:flex; flex-direction:column; gap:10px; position:relative; transition:box-shadow .2s,border-color .2s; }
+ .card { background:var(--card); border:1px solid var(--line); border-radius:14px; padding:24px; display:flex; flex-direction:column; gap:10px; position:relative; transition:box-shadow .2s,border-color .2s; }
.card.uc { opacity:.62; }
.card.flash { border-color:var(--blue); box-shadow:0 0 0 3px rgba(88,166,255,.35); }
.top { display:flex; justify-content:space-between; align-items:flex-start; gap:10px; }
@@ -101,7 +102,7 @@
.metrics .k { color:var(--mut); }
.metrics .v { font-variant-numeric:tabular-nums; font-weight:600; }
.pos { color:var(--acc); } .neg { color:var(--bad); } .na { color:var(--mut); }
- .thesis { font-size:13px; color:#cdd6e0; }
+ .thesis { font-size:13px; color:var(--ink); }
.lst { font-size:12px; color:var(--mut); margin:2px 0 0; padding-left:16px; }
.src { font-size:12px; } .src a { color:var(--blue); text-decoration:none; }
.lcbtn,.histbtn { background:transparent; color:var(--warn); border:1px dashed #6b5320; border-radius:14px; padding:2px 8px; font-size:11px; cursor:pointer; }
@@ -131,14 +132,14 @@
.brokerline strong { color:var(--blue); }
/* ---- docked chat ---- */
- #chatwrap { border-top:1px solid var(--line); background:#0b0e13; padding:16px 20px 40px; }
+ #chatwrap { border-top:1px solid var(--line); background:var(--bg2); padding:16px 20px 40px; }
#chatwrap h2 { font-size:15px; margin:0 0 2px; }
#chatwrap .hint { color:var(--mut); font-size:12px; margin-bottom:10px; }
#log { display:flex; flex-direction:column; gap:10px; max-height:42vh; overflow-y:auto; padding:4px 2px; }
.msg { max-width:80%; padding:9px 13px; border-radius:12px; font-size:14px; line-height:1.45; white-space:pre-wrap; word-wrap:break-word; }
.msg.u { align-self:flex-end; background:#1f6feb; color:#fff; border-bottom-right-radius:3px; }
.msg.a { align-self:flex-start; background:var(--card); border:1px solid var(--line); border-bottom-left-radius:3px; }
- .msg.a code { background:#0b0e13; padding:1px 5px; border-radius:4px; }
+ .msg.a code { background:var(--bg); padding:1px 5px; border-radius:4px; }
.msg.sys { align-self:center; color:var(--mut); font-size:12px; background:transparent; }
.actiontag { display:inline-block; margin-top:6px; font-size:11px; color:var(--acc); border:1px solid #1f6f37; border-radius:6px; padding:2px 7px; }
#chatform { display:flex; gap:10px; margin-top:12px; }
@@ -167,12 +168,12 @@
.minibtn:hover { border-color:var(--blue); color:var(--ink); }
/* ---- list view ---- */
.listhost { display:block; padding:20px 20px 30px; }
- .listwrap { overflow-x:auto; border:2px solid #fff; border-radius:12px; }
+ .listwrap { overflow-x:auto; border:1px solid var(--line); border-radius:12px; }
.listtbl { width:100%; border-collapse:collapse; font-size:12.5px; white-space:nowrap; }
.listtbl th, .listtbl td { text-align:right; padding:9px 13px; border-top:1px solid var(--line); }
- .listtbl th { position:sticky; top:0; background:#0b0e13; color:var(--mut); font-size:10px; text-transform:uppercase; letter-spacing:.5px; border-top:0; z-index:1; }
+ .listtbl th { position:sticky; top:0; background:var(--bg2); color:var(--mut); font-size:10px; text-transform:uppercase; letter-spacing:.5px; border-top:0; z-index:1; }
.listtbl td.stick, .listtbl th.stick { text-align:left; position:sticky; left:0; background:var(--card); }
- .listtbl th.stick { background:#0b0e13; z-index:2; }
+ .listtbl th.stick { background:var(--bg2); z-index:2; }
.listtbl th.sortable { cursor:pointer; } .listtbl th.sortable:hover { color:var(--ink); }
/* sort arrow via CSS ::after (not literal text) so the header TEXT stays stable and col-resize's tableSig-keyed saved widths survive re-render (TK-10089) */
.listtbl th.asc::after { content:' ▲'; color:var(--gold); } .listtbl th.desc::after { content:' ▼'; color:var(--gold); }
@@ -182,7 +183,7 @@
.listtbl th.dropL { box-shadow:inset 3px 0 0 var(--blue); }
.listtbl th.dropR { box-shadow:inset -3px 0 0 var(--blue); }
.listtbl tr.lrow:hover td { background:rgba(88,166,255,.06); }
- .listtbl tr.lrow:hover td.stick { background:#1b222c; }
+ .listtbl tr.lrow:hover td.stick { background:var(--card); }
.listtbl .la { font-weight:600; color:var(--ink); text-decoration:none; }
.listtbl .la:hover { color:var(--blue); }
.listtbl .lc { color:var(--mut); font-size:11px; }
@@ -190,14 +191,14 @@
.listtbl .flink:hover { color:var(--blue); border-bottom-color:var(--blue); }
.listtbl tr.lrow { cursor:pointer; }
.listtbl .exptog { display:inline-block; width:11px; color:var(--mut); font-size:10px; transition:transform .15s; }
- .listtbl tr.lrow.open td.stick { background:#1b222c; }
+ .listtbl tr.lrow.open td.stick { background:var(--card); }
.listtbl tr.lexp > td { padding:0; border-top:0; }
- .listtbl tr.lexp .lexpbody { max-height:0; overflow:hidden; transition:max-height .25s ease; background:#0c1017; }
+ .listtbl tr.lexp .lexpbody { max-height:0; overflow:hidden; transition:max-height .25s ease; background:var(--bg); }
.listtbl tr.lexp.open .lexpbody { max-height:1200px; padding:12px 16px; border-top:1px solid var(--line); }
.lexpbody .src { text-align:left; white-space:normal; font-size:12px; }
.lexpbody .deep { text-align:left; white-space:normal; margin-top:8px; display:flex; flex-wrap:wrap; gap:6px; align-items:center; }
.lexpbody .deeplbl { color:var(--mut); font-size:10px; text-transform:uppercase; letter-spacing:.5px; margin-right:2px; }
- .lexpbody .deep a, .lexpbody .deep button { font-size:11px; padding:3px 9px; border-radius:14px; border:1px solid #2a3340; background:#141a22; color:var(--ink); text-decoration:none; cursor:pointer; }
+ .lexpbody .deep a, .lexpbody .deep button { font-size:11px; padding:3px 9px; border-radius:14px; border:1px solid var(--line); background:var(--card); color:var(--ink); text-decoration:none; cursor:pointer; }
.lexpbody .deep a:hover, .lexpbody .deep button:hover { border-color:var(--blue); color:var(--blue); }
.lexpbody .lcout, .lexpbody .histout { text-align:left; white-space:normal; }
/* Agent · contact column cell */
@@ -207,21 +208,21 @@
.agentcell .ain { color:var(--mut); text-decoration:none; font-size:11px; }
.agentcell .ain:hover { color:var(--blue); }
.agentcell .chiprow:empty { display:none; }
- .agentcell .achip { display:inline-block; font-size:10px; color:var(--mut); background:#141a22; border:1px solid #2a3340; border-radius:10px; padding:1px 6px; margin-right:4px; }
+ .agentcell .achip { display:inline-block; font-size:10px; color:var(--mut); background:var(--card); border:1px solid var(--line); border-radius:10px; padding:1px 6px; margin-right:4px; }
.agentcell .achip.done { color:#3fb950; border-color:#264f2e; }
.agentcell .acts { display:flex; flex-wrap:wrap; gap:5px; margin-top:2px; }
- .abtn { font-size:10.5px; padding:2px 8px; border-radius:12px; border:1px solid #2a3340; background:#141a22; color:var(--ink); cursor:pointer; }
+ .abtn { font-size:10.5px; padding:2px 8px; border-radius:12px; border:1px solid var(--line); background:var(--card); color:var(--ink); cursor:pointer; }
.abtn:hover { border-color:var(--blue); color:var(--blue); }
.abtn.contactbtn { border-color:#2f5233; color:#8fdfa0; }
.abtn.markbtn { border-color:#284b7a; color:#8ec0ff; }
/* CRM block inside the inline panel */
.lexpbody .crm { margin-top:10px; border-top:1px solid var(--line); padding-top:10px; text-align:left; }
.crm-info { display:flex; flex-wrap:wrap; gap:6px; align-items:center; }
- .crm-info .crmf { background:#0b0e13; border:1px solid #2a3340; border-radius:8px; color:var(--ink); font-size:12px; padding:5px 8px; min-width:150px; }
+ .crm-info .crmf { background:var(--bg); border:1px solid var(--line); border-radius:8px; color:var(--ink); font-size:12px; padding:5px 8px; min-width:150px; }
.crm-info .crmf:focus { outline:none; border-color:var(--blue); }
.crm-acts { display:flex; flex-wrap:wrap; gap:6px; align-items:center; margin-top:8px; }
.crm-letters { margin-top:10px; }
- .crm-letters .lett { border:1px solid #232b36; border-radius:8px; padding:7px 9px; margin-top:6px; background:#0b0e13; }
+ .crm-letters .lett { border:1px solid var(--line); border-radius:8px; padding:7px 9px; margin-top:6px; background:var(--bg); }
.crm-letters .letth { display:flex; align-items:center; gap:8px; font-size:12px; }
.crm-letters .letts { color:var(--mut); font-size:10px; }
.crm-letters .letdel { margin-left:auto; background:transparent; border:0; color:var(--mut); cursor:pointer; font-size:12px; }
@@ -230,14 +231,14 @@
/* Compose-letter modal */
.composeM { position:fixed; inset:0; background:rgba(0,0,0,.55); display:none; align-items:center; justify-content:center; z-index:9000; }
.composeM.on { display:flex; }
- .composeCard { background:var(--card,#11161d); border:1px solid #2a3340; border-radius:14px; width:min(620px,92vw); max-height:88vh; overflow:auto; padding:16px; box-shadow:0 12px 40px rgba(0,0,0,.5); }
+ .composeCard { background:var(--card); border:1px solid var(--line); border-radius:14px; width:min(620px,92vw); max-height:88vh; overflow:auto; padding:16px; box-shadow:0 12px 40px rgba(0,0,0,.5); }
.composeH { display:flex; align-items:center; font-size:14px; margin-bottom:8px; }
.composeH .composeX { margin-left:auto; background:transparent; border:0; color:var(--mut); font-size:16px; cursor:pointer; }
.composeGate { font-size:11px; color:#e3b341; background:#241d0e; border:1px solid #5a4a1e; border-radius:8px; padding:6px 9px; margin-bottom:10px; }
- .composeCard input, .composeCard textarea { width:100%; box-sizing:border-box; background:#0b0e13; border:1px solid #2a3340; border-radius:8px; color:var(--ink); font-size:13px; padding:8px 10px; margin-bottom:8px; font-family:inherit; }
+ .composeCard input, .composeCard textarea { width:100%; box-sizing:border-box; background:var(--bg); border:1px solid var(--line); border-radius:8px; color:var(--ink); font-size:13px; padding:8px 10px; margin-bottom:8px; font-family:inherit; }
.composeCard textarea { resize:vertical; line-height:1.5; }
.composeActs { display:flex; gap:8px; justify-content:flex-end; }
- .composeActs button { font-size:12px; padding:6px 14px; border-radius:10px; border:1px solid #2a3340; background:#141a22; color:var(--ink); cursor:pointer; }
+ .composeActs button { font-size:12px; padding:6px 14px; border-radius:10px; border:1px solid var(--line); background:var(--card); color:var(--ink); cursor:pointer; }
.composeActs button.primary { border-color:#2f5233; color:#8fdfa0; }
.composeActs button.gated { border-color:#5a4a1e; color:#e3b341; }
.composeActs button.gated:hover:not([disabled]) { border-color:#e3b341; }
@@ -257,11 +258,11 @@
.tabpane .ain { color:var(--mut); text-decoration:none; font-size:12px; }
.tabpane .ain:hover { color:var(--blue); }
.findgrid { display:flex; flex-direction:column; gap:7px; }
- .findlink { display:inline-block; background:#141a22; border:1px solid #2a3340; border-radius:8px; color:var(--ink); text-decoration:none; font-size:12.5px; padding:8px 11px; cursor:pointer; text-align:left; }
+ .findlink { display:inline-block; background:var(--card); border:1px solid var(--line); border-radius:8px; color:var(--ink); text-decoration:none; font-size:12.5px; padding:8px 11px; cursor:pointer; text-align:left; }
.findlink:hover { border-color:var(--blue); color:var(--blue); }
.findlink.findloop { padding:8px 11px; }
.findlink.findloop a { color:inherit; text-decoration:none; }
- .crmToast { position:fixed; bottom:22px; left:50%; transform:translateX(-50%) translateY(12px); background:#11161d; border:1px solid #2a3340; color:var(--ink); font-size:12.5px; padding:9px 16px; border-radius:20px; opacity:0; transition:opacity .2s,transform .2s; z-index:9500; pointer-events:none; }
+ .crmToast { position:fixed; bottom:22px; left:50%; transform:translateX(-50%) translateY(12px); background:var(--bg2); border:1px solid var(--line); color:var(--ink); font-size:12.5px; padding:9px 16px; border-radius:20px; opacity:0; transition:opacity .2s,transform .2s; z-index:9500; pointer-events:none; }
.crmToast.on { opacity:1; transform:translateX(-50%) translateY(0); }
/* Card-view agent-contact block (every card, every asset type) */
.card .cardagent { margin-top:8px; border-top:1px solid var(--line); padding-top:8px; font-size:12px; }
@@ -272,7 +273,7 @@
.card .cardagent .acts { display:flex; flex-wrap:wrap; gap:6px; margin-top:6px; }
/* Full contact modal info row */
.composeCard .cm-info { display:flex; flex-wrap:wrap; gap:6px; align-items:center; margin-bottom:10px; }
- .composeCard .cm-info .crmf { background:#0b0e13; border:1px solid #2a3340; border-radius:8px; color:var(--ink); font-size:12px; padding:6px 8px; min-width:140px; flex:1 1 140px; margin:0; }
+ .composeCard .cm-info .crmf { background:var(--bg); border:1px solid var(--line); border-radius:8px; color:var(--ink); font-size:12px; padding:6px 8px; min-width:140px; flex:1 1 140px; margin:0; }
.composeCard .cm-info .crmf:focus { outline:none; border-color:var(--blue); }
.composeH .flink { font-size:11px; font-weight:400; margin-left:8px; }
/* Inline (no-outside-link) agent bits */
@@ -288,10 +289,10 @@
.city .drill:hover { color:var(--blue); border-bottom-color:var(--blue); }
.copyb { background:transparent; border:0; color:var(--mut); cursor:pointer; font-size:11px; padding:0 3px; border-radius:4px; }
.copyb:hover { color:var(--blue); }
- .crm-note, .lexpbody .crm-note { margin-top:6px; font-size:12px; color:var(--mut); white-space:pre-wrap; background:#0c1017; border:1px solid #232b36; border-radius:8px; padding:6px 9px; text-align:left; }
+ .crm-note, .lexpbody .crm-note { margin-top:6px; font-size:12px; color:var(--mut); white-space:pre-wrap; background:var(--bg); border:1px solid var(--line); border-radius:8px; padding:6px 9px; text-align:left; }
.composeCard .cm-notes { margin-bottom:10px; }
.composeCard .cm-notes .deeplbl { margin-bottom:4px; }
- .composeCard .cm-notes textarea { width:100%; box-sizing:border-box; background:#0b0e13; border:1px solid #2a3340; border-radius:8px; color:var(--ink); font-size:12.5px; padding:7px 9px; font-family:inherit; resize:vertical; line-height:1.5; }
+ .composeCard .cm-notes textarea { width:100%; box-sizing:border-box; background:var(--bg); border:1px solid var(--line); border-radius:8px; color:var(--ink); font-size:12.5px; padding:7px 9px; font-family:inherit; resize:vertical; line-height:1.5; }
.composeCard .cm-notes textarea:focus { outline:none; border-color:var(--blue); }
/* ---- Amazon-style docked left filter rail (desktop) ---- */
.shell { display:flex; align-items:flex-start; }
@@ -371,6 +372,7 @@
}
</style>
<script async src="https://www.googletagmanager.com/gtag/js?id=G-7R2X3B2V18"></script><script>window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);}gtag('js',new Date());gtag('config','G-7R2X3B2V18');</script>
+<link rel="stylesheet" href="/crcp-theme.css">
</head>
<body>
<header>
@@ -2016,5 +2018,6 @@ function loadRanked(_retry){ return fetch('data/ranked.json').then(r=>{ if(!r.ok
<script src="/col-resize.js" defer></script>
<script src="/global-search.js" defer></script>
<script src="/corner-nav.js" defer></script>
+<script src="/crcp-theme.js" defer></script>
</body>
</html>
diff --git a/public/mls.html b/public/mls.html
index 10b5562..7135dbc 100644
--- a/public/mls.html
+++ b/public/mls.html
@@ -1,28 +1,40 @@
<!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">
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Crect width='16' height='16' rx='3' fill='%230e1116'/%3E%3Ctext x='8' y='12' font-size='10' text-anchor='middle' fill='%233fb950'%3EMLS%3C/text%3E%3C/svg%3E">
<title>LA County Listings — Residential + CRE</title>
<style>
- :root{ --bg:#0e1116; --card:#161b22; --line:#2a313c; --ink:#e6edf3; --mut:#8b949e; --acc:#3fb950; --warn:#d29922; --bad:#f85149; --blue:#58a6ff; }
+ :root, :root[data-theme="dark"]{
+ --bg:#0d1117; --bg2:#171d26; --card:#1c232e; --line:#33404f; --line2:#3f4c5c;
+ --ink:#f2f6fb; --mut:#b3c0cf; --headbg:rgba(13,17,23,.98); --stripe:rgba(255,255,255,.025);
+ --hover:rgba(88,166,255,.10);
+ --acc:#4bd268; --warn:#d29922; --bad:#f85149; --blue:#58a6ff;
+ }
+ :root[data-theme="light"]{
+ --bg:#f4f6f9; --bg2:#ffffff; --card:#ffffff; --line:#d5dbe2; --line2:#c2cad4;
+ --ink:#12171e; --mut:#525f6e; --headbg:rgba(255,255,255,.98); --stripe:rgba(20,30,45,.028);
+ --hover:rgba(9,105,218,.08);
+ --acc:#1a7f37; --warn:#9a6700; --bad:#cf222e; --blue:#0969da; --muted:#525f6e;
+ }
*{box-sizing:border-box;} body{margin:0;background:var(--bg);color:var(--ink);font:14px/1.45 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;}
- header{display:flex;align-items:center;gap:12px;padding:11px 18px;border-bottom:1px solid var(--line);position:sticky;top:0;z-index:40;background:rgba(14,17,22,.98);backdrop-filter:blur(8px);flex-wrap:wrap;}
+ header{display:flex;align-items:center;gap:12px;padding:11px 18px;border-bottom:1px solid var(--line);position:sticky;top:0;z-index:40;background:var(--headbg);backdrop-filter:blur(8px);flex-wrap:wrap;}
header h1{font-size:16px;margin:0;} header h1 b{color:var(--acc);}
header .nav{display:flex;gap:12px;margin-left:6px;} header .nav a{color:var(--blue);text-decoration:none;font-size:13px;} header .nav a:hover{color:var(--warn);}
.spacer{flex:1;}
.search{background:var(--card);border:1px solid var(--line);color:var(--ink);border-radius:9px;padding:8px 12px;font-size:14px;min-width:220px;}
.toggle{display:flex;border:1px solid var(--line);border-radius:9px;overflow:hidden;}
.toggle button{background:var(--card);border:0;color:var(--mut);padding:8px 13px;font-size:13px;cursor:pointer;}
- .toggle button.on{background:var(--blue);color:#0b0e14;font-weight:700;}
+ .toggle button.on{background:var(--blue);color:var(--bg);font-weight:700;}
.csvbtn{background:var(--card);border:1px solid var(--line);color:var(--acc);border-radius:9px;padding:8px 12px;font-size:13px;cursor:pointer;} .csvbtn:hover{border-color:var(--acc);}
.count{color:var(--mut);font-size:12px;}
.wrap{padding:24px 28px 60px;}
/* TABLE (spreadsheet) */
.tblwrap{overflow:auto;max-height:calc(100vh - 130px);border:1px solid var(--line);border-radius:10px;}
table.mls{border-collapse:separate;border-spacing:0;width:100%;font-size:12.5px;white-space:nowrap;}
- table.mls thead th{position:sticky;top:0;background:#1b2230;color:var(--mut);text-transform:uppercase;letter-spacing:.3px;font-size:10.5px;padding:8px 10px;border-bottom:1px solid var(--line);cursor:pointer;user-select:none;z-index:2;}
+ table.mls thead th{position:sticky;top:0;background:var(--bg2);color:var(--mut);text-transform:uppercase;letter-spacing:.3px;font-size:10.5px;padding:8px 10px;border-bottom:1px solid var(--line);cursor:pointer;user-select:none;z-index:2;}
table.mls thead th:hover{color:var(--ink);}
table.mls thead th.asc::after{content:' ▲';color:var(--acc);} table.mls thead th.desc::after{content:' ▼';color:var(--acc);}
/* draggable column reorder (Steve rule 2026-07-31: move columns around) */
@@ -30,7 +42,7 @@
table.mls thead th.dragging{opacity:.45;}
table.mls thead th.dropL{box-shadow:inset 3px 0 0 var(--acc);}
table.mls thead th.dropR{box-shadow:inset -3px 0 0 var(--acc);}
- table.mls tbody td{padding:7px 10px;border-bottom:1px solid #20262f;}
+ table.mls tbody td{padding:7px 10px;border-bottom:1px solid var(--line);}
table.mls tbody tr:hover td{background:rgba(88,166,255,.07);}
table.mls td.n{text-align:right;font-variant-numeric:tabular-nums;}
table.mls a{color:var(--blue);text-decoration:none;} table.mls a:hover{text-decoration:underline;}
@@ -42,9 +54,9 @@
#sortsel{background:var(--card);color:var(--ink);border:1px solid var(--line);border-radius:7px;padding:5px 8px;font-size:12px}
#denswrap{display:none;align-items:center;gap:6px;font-size:13px;color:var(--mut)}
#denswrap input[type=range]{width:92px;accent-color:var(--acc)}
- .gc{background:var(--card);border:2px solid #fff;border-radius:11px;padding:18px 20px;}
+ .gc{background:var(--card);border:1px solid var(--line);border-radius:11px;padding:18px 20px;}
.gc .addr{font-weight:600;} .gc .sub{color:var(--mut);font-size:12px;margin-bottom:6px;}
- .gc .row{display:flex;justify-content:space-between;font-size:12.5px;padding:2px 0;border-top:1px solid #20262f;}
+ .gc .row{display:flex;justify-content:space-between;font-size:12.5px;padding:2px 0;border-top:1px solid var(--line);}
.gc .row .k{color:var(--mut);} .gc .row .v{font-variant-numeric:tabular-nums;}
.hide{display:none;}
#ov{display:none;position:fixed;inset:0;background:rgba(0,0,0,.6);z-index:60;align-items:flex-start;justify-content:center;padding:40px 14px;overflow-y:auto;}
@@ -54,10 +66,10 @@
.ph-x{position:absolute;top:12px;right:14px;background:none;border:0;color:var(--mut);font-size:22px;cursor:pointer;}
.ph-ci{display:flex;gap:14px;flex-wrap:wrap;margin:8px 0;font-size:13.5px;}
.ph-sec{margin-top:14px;} .ph-sec h4{margin:0 0 6px;font-size:12px;text-transform:uppercase;letter-spacing:.5px;color:var(--mut);}
- .ph-item{display:flex;justify-content:space-between;gap:10px;padding:4px 0;border-bottom:1px solid #20262f;font-size:13px;} .ph-mut{color:var(--mut);font-size:12.5px;}
+ .ph-item{display:flex;justify-content:space-between;gap:10px;padding:4px 0;border-bottom:1px solid var(--line);font-size:13px;} .ph-mut{color:var(--mut);font-size:12.5px;}
/* ---- Amazon-style left rail ---- */
.shell{display:flex;align-items:flex-start;}
- .rail{flex:0 0 260px;background:#0b0e13;border-right:1px solid var(--line);align-self:stretch;position:sticky;top:53px;height:calc(100vh - 53px);overflow-y:auto;padding:0 0 40px;}
+ .rail{flex:0 0 260px;background:var(--bg2);border-right:1px solid var(--line);align-self:stretch;position:sticky;top:53px;height:calc(100vh - 53px);overflow-y:auto;padding:0 0 40px;}
.rail .rsec{padding:13px 16px;border-bottom:1px solid var(--line);}
.rail h4{margin:0 0 9px;font-size:11px;text-transform:uppercase;letter-spacing:.6px;color:var(--mut);}
.chips{display:flex;flex-wrap:wrap;gap:6px;}
@@ -92,10 +104,11 @@
.heatleg.on { display:inline-flex; }
.heatleg .hb { width:52px; height:8px; border-radius:4px; background:linear-gradient(90deg,hsl(0,70%,45%),hsl(60,70%,45%),hsl(120,70%,45%)); }
</style>
+<link rel="stylesheet" href="/crcp-theme.css">
</head>
<body>
<header>
- <h1><b>LA County Listings</b> · Residential + CRE <span style="font-size:11px;font-weight:400;color:#8b949e">· Redfin-sourced</span></h1>
+ <h1><b>LA County Listings</b> · Residential + CRE <span style="font-size:11px;font-weight:400;color:var(--mut)">· Redfin-sourced</span></h1>
<div class="nav"><a href="/">← Explorer</a><a href="/deals-flow.html" title="Closed deal flow — public-record sales + FHA + SEC REIT">💰 Deal Flow</a><a href="/map.html">🗺️ Map</a><a href="/licensed-agents.html" title="Real-estate agents & brokers verified against the CA DRE public license roll">🎫 Licensed Agents</a><a href="/crcp.html">🛰️ CRCP</a></div>
<span class="spacer"></span>
<input class="search" id="q" type="text" placeholder="search all fields — address, city, firm, type, agent, source, year… (space = AND)">
@@ -615,5 +628,6 @@ document.addEventListener('click', async e=>{
<script src="/global-search.js" defer></script>
<script src="/sort-bar.js" defer></script>
<script src="/corner-nav.js" defer></script>
+<script src="/crcp-theme.js" defer></script>
</body>
</html>
← 1cb56be condos: rework colors for legibility + add day/night toggle
·
back to Commercialrealestate
·
condos: surface FHA expiration date as a toggleable grid col 4edfac9 →