aboutsummaryrefslogtreecommitdiff
path: root/components/market_bar.py
diff options
context:
space:
mode:
Diffstat (limited to 'components/market_bar.py')
-rw-r--r--components/market_bar.py84
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,
)