diff options
Diffstat (limited to 'components/market_bar.py')
| -rw-r--r-- | components/market_bar.py | 84 |
1 files changed, 74 insertions, 10 deletions
diff --git a/components/market_bar.py b/components/market_bar.py index cb813e5..411b232 100644 --- a/components/market_bar.py +++ b/components/market_bar.py @@ -1,25 +1,89 @@ """Market bar — displays major indices at the top of the app.""" import streamlit as st from services.data_service import get_market_indices -from utils.formatters import fmt_number + + +def _delta_class(change_pct: float | None) -> str: + if change_pct is None: + return "neutral" + return "positive" if change_pct >= 0 else "negative" + + +def _delta_text(change_pct: float | None) -> str: + if change_pct is None: + return "—" + arrow = "▲" if change_pct >= 0 else "▼" + return f"{arrow} {change_pct * 100:+.2f}%" def render_market_bar(): indices = get_market_indices() + st.markdown( + """ + <style> + .prism-market-card { + background: rgba(22, 28, 39, 0.92); + border: 1px solid rgba(255,255,255,0.06); + border-radius: 14px; + padding: 0.8rem 0.95rem; + min-height: 96px; + } + .prism-market-label { + color: #9aa0b0; + font-size: 0.78rem; + font-weight: 600; + letter-spacing: 0.06em; + text-transform: uppercase; + margin-bottom: 0.45rem; + } + .prism-market-value { + color: #f3f6fb; + font-size: 1.5rem; + font-weight: 700; + line-height: 1.15; + margin-bottom: 0.45rem; + } + .prism-market-delta { + display: inline-block; + border-radius: 999px; + font-size: 0.78rem; + font-weight: 600; + padding: 0.18rem 0.5rem; + } + .prism-market-delta.positive { + color: #7ce3a1; + background: rgba(28, 131, 72, 0.18); + } + .prism-market-delta.negative { + color: #ff8a8a; + background: rgba(180, 47, 47, 0.18); + } + .prism-market-delta.neutral { + color: #c6cfdd; + background: rgba(198, 207, 221, 0.12); + } + </style> + """, + unsafe_allow_html=True, + ) + cols = st.columns(len(indices)) for col, (name, data) in zip(cols, indices.items()): price = data.get("price") change_pct = data.get("change_pct") - if price is None: - col.metric(label=name, value="—") - continue + value = f"{price:,.2f}" if price is not None else "—" + delta_class = _delta_class(change_pct) + delta_text = _delta_text(change_pct) - price_str = f"{price:,.2f}" - delta_str = f"{change_pct * 100:+.2f}%" if change_pct is not None else None - col.metric( - label=name, - value=price_str, - delta=delta_str, + col.markdown( + f""" + <div class="prism-market-card"> + <div class="prism-market-label">{name}</div> + <div class="prism-market-value">{value}</div> + <span class="prism-market-delta {delta_class}">{delta_text}</span> + </div> + """, + unsafe_allow_html=True, ) |
