diff options
| -rw-r--r-- | app.py | 104 |
1 files changed, 90 insertions, 14 deletions
@@ -220,14 +220,53 @@ button[kind="secondary"]:hover { padding-bottom: 3rem !important; } -/* ── Sticky market bar ──────────────────────────────────────────────────── */ -.st-key-market_bar_sticky { - position: sticky !important; - top: 0 !important; - z-index: 200 !important; - background: var(--ink-0) !important; - padding-bottom: 0.5rem !important; - margin-bottom: -0.5rem !important; +/* ── Allow sticky positioning inside Streamlit's main column ────────────── */ +section[data-testid="stMain"] { overflow: visible !important; } + +/* ── TopBar ─────────────────────────────────────────────────────────────── */ +.psm-top { + position: sticky; top: 0; z-index: 200; + background: var(--ink-0); border-bottom: 1px solid var(--line-1); + padding: 10px 0; margin-bottom: 0.75rem; + display: flex; align-items: center; gap: 16px; +} +.psm-search-bar { + flex: 1; max-width: 460px; + display: flex; align-items: center; gap: 8px; + background: var(--ink-2); border: 1px solid var(--line-2); + border-radius: var(--r-2); padding: 7px 12px; +} +.psm-search-bar input { + flex: 1; background: transparent; border: none; outline: none; + font-family: var(--font-mono); font-size: var(--fs-13); color: var(--fg-1); + pointer-events: none; +} +.psm-search-bar input::placeholder { color: var(--fg-3); } +.psm-search-bar .kbd { + font-family: var(--font-mono); font-size: var(--fs-12); color: var(--fg-3); + border: 1px solid var(--line-2); padding: 1px 6px; + border-radius: var(--r-1); background: var(--ink-1); flex-shrink: 0; +} +.psm-topbar-clock { + font-family: var(--font-mono); font-size: var(--fs-12); color: var(--fg-2); + display: flex; gap: 10px; align-items: center; +} +.psm-topbar-dot { + width: 6px; height: 6px; border-radius: 50%; + background: var(--fg-4); flex-shrink: 0; +} +.psm-topbar-dot.open { background: var(--positive); box-shadow: 0 0 5px var(--positive); } +.psm-topbar-account { + display: flex; align-items: center; gap: 8px; + padding: 5px 12px; border: 1px solid var(--line-2); border-radius: var(--r-full); + font-family: var(--font-sans); font-size: var(--fs-13); color: var(--fg-1); + margin-left: auto; +} +.psm-topbar-av { + width: 20px; height: 20px; border-radius: 50%; + background: var(--brass); color: var(--brass-ink); + display: flex; align-items: center; justify-content: center; + font-family: var(--font-display); font-style: italic; font-size: 11px; } /* ── Tabs ───────────────────────────────────────────────────────────────── */ @@ -784,20 +823,57 @@ with st.sidebar: render_top_movers(True) +# ── TopBar ──────────────────────────────────────────────────────────────────── + +st.markdown( + "<div class='psm-top'>" + "<div class='psm-search-bar'>" + "<input type='text' placeholder='Search ticker, company, or filing…' tabindex='-1' />" + "<span class='kbd'>/</span>" + "</div>" + "<div class='psm-topbar-clock'>" + "<span class='psm-topbar-dot' id='psm-dot'></span>" + "<span id='psm-status'>NYSE · Closed</span>" + "<span id='psm-time'>--:--:-- ET</span>" + "</div>" + "<div class='psm-topbar-account'>" + "<span class='psm-topbar-av'>T</span>" + "<span>Tyler Hoang</span>" + "</div>" + "</div>", + unsafe_allow_html=True, +) + # ── Market Bar ──────────────────────────────────────────────────────────────── -with st.container(key="market_bar_sticky"): +with st.container(): render_market_bar() st.divider() -# ── ⌘K / Ctrl+K shortcut — focuses sidebar ticker search ───────────────────── +# ── TopBar clock + / shortcut ───────────────────────────────────────────────── components.html( "<script>" - "document.addEventListener('keydown', function(e) {" - " if (e.key === '/' && !e.metaKey && !e.ctrlKey && !e.altKey" - " && document.activeElement.tagName !== 'INPUT'" - " && document.activeElement.tagName !== 'TEXTAREA') {" + "function tickTopbar() {" + " var now = new Date();" + " var et = new Date(now.toLocaleString('en-US', { timeZone: 'America/New_York' }));" + " var hm = et.getHours() * 60 + et.getMinutes();" + " var day = et.getDay();" + " var isOpen = (day >= 1 && day <= 5) && hm >= 570 && hm < 960;" + " var ts = et.toLocaleTimeString('en-US', { hour:'2-digit', minute:'2-digit', second:'2-digit', hour12:false });" + " var pd = window.parent.document;" + " var dot = pd.getElementById('psm-dot');" + " var status = pd.getElementById('psm-status');" + " var time = pd.getElementById('psm-time');" + " if (dot) dot.className = isOpen ? 'psm-topbar-dot open' : 'psm-topbar-dot';" + " if (status) status.textContent = isOpen ? 'NYSE · Open' : 'NYSE · Closed';" + " if (time) time.textContent = ts + ' ET';" + "}" + "tickTopbar(); setInterval(tickTopbar, 1000);" + "window.parent.document.addEventListener('keydown', function(e) {" + " if (e.key === '/' && !e.metaKey && !e.ctrlKey && !e.altKey) {" + " var ae = window.parent.document.activeElement;" + " if (ae && (ae.tagName === 'INPUT' || ae.tagName === 'TEXTAREA')) return;" " var inputs = window.parent.document.querySelectorAll('input');" " for (var i = 0; i < inputs.length; i++) {" " if (inputs[i].placeholder && inputs[i].placeholder.indexOf('AAPL') > -1) {" |
