← back to Commercialrealestate
deals-flow ticker: add reversible dismiss (deselect) control w/ session-scoped restore (DTD verdict C + contrarian constraint)
ba2514a9b91936e1843f37f8d6a9002c5ecc67d1 · 2026-07-31 14:30:13 -0700 · Steve Abrams
Files touched
Diff
commit ba2514a9b91936e1843f37f8d6a9002c5ecc67d1
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Fri Jul 31 14:30:13 2026 -0700
deals-flow ticker: add reversible dismiss (deselect) control w/ session-scoped restore (DTD verdict C + contrarian constraint)
---
public/deals-flow.html | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/public/deals-flow.html b/public/deals-flow.html
index aa9b8d4..1b45ee0 100644
--- a/public/deals-flow.html
+++ b/public/deals-flow.html
@@ -52,7 +52,13 @@ select{background:var(--card);border:1px solid var(--line);color:var(--ink);bord
.ticker.is-stopped .track{animation-play-state:paused}
.ticker .tk-ctrl{flex:0 0 auto;display:flex;align-items:center;justify-content:center;width:34px;background:#0b0e13;border:none;border-left:1px solid #20262f;color:var(--ink);font-size:13px;line-height:1;cursor:pointer;transition:background .15s,color .15s}
.ticker .tk-ctrl:hover{background:#161b22;color:#fff}
-.ticker.is-stopped .tk-ctrl{color:var(--acc)}
+.ticker.is-stopped #tkCtrl{color:var(--acc)}
+/* dismissed state: collapse to a clickable "show" strip — always restorable (no one-way door) */
+.ticker.is-dismissed .vp,.ticker.is-dismissed #tkCtrl,.ticker.is-dismissed #tkClose{display:none}
+.ticker.is-dismissed{cursor:pointer}
+.ticker.is-dismissed .lbl{flex:1;justify-content:flex-start;background:#0b0e13;color:var(--muted,#8b949e);font-weight:700}
+.ticker.is-dismissed .lbl::before{background:var(--acc)}
+.ticker.is-dismissed .lbl::after{content:"▸ show";margin-left:8px;color:var(--blue);font-weight:800}
.ticker .it{display:inline-flex;align-items:center;gap:8px;padding:0 20px;font-size:12px;color:var(--ink);border-right:1px solid #20262f}
.ticker .it .t{font-weight:800;font-size:9px;letter-spacing:.4px;padding:2px 6px;border-radius:5px}
.ticker .it .t.listed{background:rgba(63,185,80,.18);color:var(--acc)}
@@ -92,7 +98,7 @@ select{background:var(--card);border:1px solid var(--line);color:var(--ink);bord
<div class="nav"><a href="/just-listed.html">Just Listed</a><a href="/fha-leads.html">Assumable Leads</a><a href="/mls.html">Listings</a><a href="/">Explorer</a></div>
<span id="auth" style="margin-left:auto;font-size:12px;color:var(--blue);cursor:pointer">Sign in</span>
</header>
-<div class="ticker" id="ticker" style="display:none" aria-label="Breaking real estate headlines"><div class="lbl" aria-hidden="true">Breaking</div><div class="vp"><div class="track" id="tickTrack"></div></div><button class="tk-ctrl" id="tkCtrl" type="button" aria-pressed="false" aria-label="Stop ticker" title="Stop ticker to read">⏸</button></div>
+<div class="ticker" id="ticker" style="display:none" aria-label="Breaking real estate headlines"><div class="lbl" id="tkLbl">Breaking</div><div class="vp"><div class="track" id="tickTrack"></div></div><button class="tk-ctrl" id="tkCtrl" type="button" aria-pressed="false" aria-label="Stop ticker" title="Stop ticker to read">⏸</button><button class="tk-ctrl" id="tkClose" type="button" aria-label="Hide ticker" title="Hide ticker">✕</button></div>
<div class="shell">
<aside class="rail">
<div class="rsec" id="savedSec" style="display:none"><h4>My saved searches</h4><div class="chips" id="fSaved"></div></div>
@@ -273,8 +279,16 @@ async function loadTicker(){try{const r=await api('/api/ticker');const items=(r&
requestAnimationFrame(()=>{const oneSet=track.scrollWidth/2;const dur=Math.max(60,Math.round(oneSet/45));track.style.animationDuration=dur+'s';});
}
loadTicker();
-// ── stop / resume (deselect) control ──
-(function(){const t=$('#ticker'),b=$('#tkCtrl');if(!b)return;b.addEventListener('click',()=>{const stopped=t.classList.toggle('is-stopped');b.textContent=stopped?'▶':'⏸';b.setAttribute('aria-pressed',stopped?'true':'false');b.setAttribute('aria-label',stopped?'Resume ticker':'Stop ticker');b.title=stopped?'Resume ticker':'Stop ticker to read';});})();
+// ── stop / resume + dismiss (deselect) controls ──
+(function(){const t=$('#ticker'),b=$('#tkCtrl'),x=$('#tkClose'),lbl=$('#tkLbl');if(!t)return;
+ // stop / resume (freezes in place so it can be read)
+ if(b)b.addEventListener('click',()=>{const stopped=t.classList.toggle('is-stopped');b.textContent=stopped?'▶':'⏸';b.setAttribute('aria-pressed',stopped?'true':'false');b.setAttribute('aria-label',stopped?'Resume ticker':'Stop ticker');b.title=stopped?'Resume ticker':'Stop ticker to read';});
+ // dismiss (hide) — collapses to a clickable "show" strip; session-scoped so it always returns next visit
+ function setHidden(hide){t.classList.toggle('is-dismissed',hide);try{hide?sessionStorage.setItem('crcpTickerHidden','1'):sessionStorage.removeItem('crcpTickerHidden');}catch(e){}}
+ if(x)x.addEventListener('click',()=>setHidden(true));
+ if(lbl)lbl.addEventListener('click',()=>{if(t.classList.contains('is-dismissed'))setHidden(false);});
+ try{if(sessionStorage.getItem('crcpTickerHidden')==='1')t.classList.add('is-dismissed');}catch(e){}
+})();
async function loadSaved(){const r=await api('/api/saved-searches');const s=r.saved||[];window._saved=s;$('#fSaved').innerHTML=s.length?s.map(x=>`<span class="chip" data-sid="${x.id}" title="apply this search">${esc(x.name)}<span class="ct" data-del="${x.id}" title="delete">✕</span></span>`).join(''):'<span style="font-size:11px;color:var(--mut)">none yet — set filters, then ★ Save search</span>';}
async function loadWatch(){const r=await api('/api/watchlist');WATCH=new Set(r.ids||[]);render();}
$('#saveBtn').addEventListener('click',async()=>{if(!ME||!ME.email){signIn();return;}const name=prompt('Name this saved search:','My deal filter');if(name===null)return;const filters={src:[...F.src],use:[...F.use],year:[...F.year],conf:[...F.conf],pMin:F.pMin,uMin:F.uMin,q};await api('/api/saved-searches',{method:'POST',body:JSON.stringify({name,filters})});loadSaved();});
← 771efe6 deals-flow ticker: halve default speed, constant read-pace,
·
back to Commercialrealestate
·
condos: re-derive listing-level warrantability from embedded 8607626 →