""" Premium modern theme system for Streamlit. Goals: - Strong visual identity (gradient + subtle glow + glass effects) - Light/dark palettes via CSS variables - Backward compatible with existing app CSS class constants: SECTION_HEADER_CLASS, SECTION_SUBHEADER_CLASS, CARD_CLASS, CARD_HEADER_CLASS, CARD_BODY_CLASS - Best-effort styling of common Streamlit widgets and containers """ from __future__ import annotations from typing import Dict, Literal # ---------------------------- # Backward-compatible constants # ---------------------------- SECTION_HEADER_CLASS = "section-h" SECTION_SUBHEADER_CLASS = "section-sub" CARD_CLASS = "card" CARD_HEADER_CLASS = "card-header" CARD_BODY_CLASS = "card-body" ThemeMode = Literal["light", "dark"] LIGHT_THEME: Dict[str, str] = { "bg0": "#F7FBFF", "bg1": "#EEF6FF", "panel": "#FFFFFF", "panel2": "#F1F5F9", "text": "#0B1220", "muted": "#475569", "muted2": "#64748B", "border": "rgba(148, 163, 184, 0.35)", "border2": "rgba(148, 163, 184, 0.22)", "shadow": "0 18px 60px rgba(2, 6, 23, 0.08)", "shadow2": "0 8px 28px rgba(2, 6, 23, 0.06)", "brand": "#0ea5e9", "brand2": "#3b82f6", "brandSoft": "rgba(14,165,233,0.20)", "ring": "rgba(59,130,246,0.35)", "cardBorder": "rgba(14,165,233,0.18)", "danger": "#ef4444", "success": "#22c55e", "warning": "#f59e0b", } DARK_THEME: Dict[str, str] = { "bg0": "#070B14", "bg1": "#0B1630", "panel": "rgba(16, 24, 40, 0.70)", "panel2": "rgba(17, 30, 58, 0.65)", "text": "#E7EEF8", "muted": "#93A3B8", "muted2": "#7788A5", "border": "rgba(148, 163, 184, 0.22)", "border2": "rgba(148, 163, 184, 0.16)", "shadow": "0 24px 80px rgba(0, 0, 0, 0.45)", "shadow2": "0 14px 40px rgba(0, 0, 0, 0.30)", "brand": "#38BDF8", "brand2": "#60A5FA", "brandSoft": "rgba(56,189,248,0.20)", "ring": "rgba(96,165,250,0.35)", "cardBorder": "rgba(56,189,248,0.16)", "danger": "#fb7185", "success": "#34d399", "warning": "#fbbf24", } def _get_mode(default: ThemeMode = "light") -> ThemeMode: try: import streamlit as st mode = getattr(st.session_state, "theme", None) if mode in ("light", "dark"): return mode except Exception: pass return default def inject_css() -> None: """Inject premium CSS. Called once per page run from app.py.""" import streamlit as st mode = _get_mode("light") t = DARK_THEME if mode == "dark" else LIGHT_THEME # Avoid CSS features that may not work everywhere (e.g., color-mix). st.markdown( f"""
""", unsafe_allow_html=True, )