Spaces:
Running
Running
| """Centralized color palette + minimal CSS tweaks for the dashboard. | |
| Only essential overrides live here. No custom theming beyond the palette | |
| constants the brief permits. ``apply_global_styles`` is called once from | |
| ``app.py`` on first render. | |
| """ | |
| from __future__ import annotations | |
| import streamlit as st | |
| # Single source of truth for source-coloring across every chart on every page. | |
| # Keep these in sync with the constants imported in ``plots.py``. | |
| MAEST_COLOR = "#5B5EA6" | |
| CLAP_COLOR = "#1FB3A5" | |
| MUQ_COLOR = "#9B5DE5" | |
| MUQ_REVIEW_COLOR = "#C77DFF" | |
| PASST_COLOR = "#F59E0B" | |
| TAXONOMY_ADAPTER_COLOR = "#2563EB" | |
| LYRICS_COLOR = "#E07B39" | |
| STEM_COLOR = "#E07B39" | |
| # Theme tags from the lyrics-llm extractor (Tier 2). Sage green deliberately | |
| # sits outside the MAEST indigo / CLAP teal / Whisper orange palette so the | |
| # fifth tag category is immediately distinguishable in small-multiples. | |
| THEME_COLOR = "#8DAA7B" | |
| # Neutral chrome. | |
| INK_COLOR = "#1F2933" | |
| MUTED_COLOR = "#6B7280" | |
| ACCENT_BG = "#F5F7FA" | |
| CARD_BG = "#FFFFFF" | |
| DIVIDER = "#E5E7EB" | |
| # Category color (used when a chart isn't source-split but category-split). | |
| CATEGORY_COLORS = { | |
| "genre": "#5B5EA6", | |
| "mood": "#9B5DE5", | |
| "instrument": "#1FB3A5", | |
| "vocal": "#E07B39", | |
| "other": "#6B7280", | |
| } | |
| # Reviewer badge palette (taxonomy "open questions" cards). | |
| REVIEWER_COLORS = { | |
| "Aran": "#5B5EA6", | |
| "Murat": "#1FB3A5", | |
| "Emre": "#E07B39", | |
| } | |
| _GLOBAL_CSS = """ | |
| <style> | |
| /* Tighten the default Streamlit padding so wide content breathes. */ | |
| .main .block-container { | |
| padding-top: 1.4rem; | |
| padding-bottom: 3rem; | |
| max-width: 1400px; | |
| } | |
| /* Cards used on the overview and track pages. */ | |
| .sync-card { | |
| background: #FFFFFF; | |
| border: 1px solid #E5E7EB; | |
| border-radius: 12px; | |
| padding: 18px 20px; | |
| margin-bottom: 14px; | |
| } | |
| .sync-card h4 { | |
| margin: 0 0 8px 0; | |
| font-size: 0.95rem; | |
| color: #1F2933; | |
| font-weight: 600; | |
| letter-spacing: 0.02em; | |
| text-transform: uppercase; | |
| } | |
| /* Ground-truth panel — wider, with a left accent stripe and theme-agnostic | |
| colours. The explicit white background protects the body text from | |
| becoming invisible when Streamlit auto-picks the user's dark OS theme. */ | |
| .sync-gt-card { | |
| background: #FFFFFF; | |
| border: 1px solid #E5E7EB; | |
| border-left: 4px solid #5B5EA6; | |
| border-radius: 10px; | |
| padding: 18px 22px 6px 22px; | |
| margin-bottom: 18px; | |
| box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04); | |
| } | |
| .sync-gt-card .sync-gt-label { | |
| font-size: 0.74rem; | |
| color: #6B7280; | |
| text-transform: uppercase; | |
| letter-spacing: 0.06em; | |
| font-weight: 600; | |
| } | |
| .sync-gt-card .sync-gt-value { | |
| font-size: 1.0rem; | |
| color: #0F172A; | |
| font-weight: 500; | |
| line-height: 1.35; | |
| } | |
| .sync-gt-card .sync-gt-value-muted { | |
| color: #9CA3AF; | |
| font-weight: 400; | |
| font-style: italic; | |
| } | |
| /* Quiet header eyebrow above page titles. */ | |
| .sync-eyebrow { | |
| font-size: 0.75rem; | |
| color: #6B7280; | |
| letter-spacing: 0.12em; | |
| text-transform: uppercase; | |
| margin-bottom: 4px; | |
| } | |
| .sync-track-picker-eyebrow { | |
| margin: 0 0 6px 0; | |
| color: #94A3B8; | |
| font-size: 0.76rem; | |
| font-weight: 750; | |
| letter-spacing: 0.12em; | |
| text-transform: uppercase; | |
| } | |
| .sync-track-picker-summary { | |
| margin: 6px 0 10px 0; | |
| color: #94A3B8; | |
| font-size: 0.88rem; | |
| } | |
| .sync-track-picker-summary strong { | |
| color: #E5E7EB; | |
| font-weight: 750; | |
| } | |
| .sync-track-picker-summary code { | |
| color: #6EE7B7; | |
| background: rgba(16, 185, 129, 0.10); | |
| border-radius: 5px; | |
| padding: 2px 6px; | |
| } | |
| /* Description blockquote on the track page. */ | |
| .sync-description { | |
| background: #F5F7FA; | |
| border-left: 4px solid #5B5EA6; | |
| padding: 14px 18px; | |
| border-radius: 4px; | |
| font-size: 1.02rem; | |
| line-height: 1.55; | |
| color: #1F2933; | |
| font-style: italic; | |
| } | |
| .sync-youtube-link { | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 6px; | |
| margin: 2px 0 10px 0; | |
| padding: 5px 11px; | |
| border: 1px solid #CBD5E1; | |
| border-radius: 999px; | |
| color: #334155 !important; | |
| background: #F8FAFC; | |
| font-size: 0.86rem; | |
| font-weight: 650; | |
| text-decoration: none !important; | |
| } | |
| .sync-youtube-link:hover { | |
| border-color: #94A3B8; | |
| background: #F1F5F9; | |
| color: #0F172A !important; | |
| } | |
| .sync-brief { | |
| background: #EFF6FF; | |
| border-left: 4px solid #2563EB; | |
| padding: 14px 18px; | |
| border-radius: 4px; | |
| font-size: 1.02rem; | |
| line-height: 1.55; | |
| color: #1E3A8A; | |
| } | |
| /* Reviewer badge (taxonomy open-questions page). */ | |
| .sync-badge { | |
| display: inline-block; | |
| padding: 2px 10px; | |
| border-radius: 999px; | |
| font-size: 0.75rem; | |
| font-weight: 600; | |
| color: white; | |
| letter-spacing: 0.04em; | |
| margin-right: 6px; | |
| } | |
| /* Confidence pill — used inline next to GT field values. Bordered and | |
| weighted for legibility against a white card, with each confidence level | |
| carrying both a hue and a saturation step so they're distinguishable in | |
| greyscale / colour-blind viewing too. */ | |
| .sync-pill { | |
| display: inline-block; | |
| padding: 2px 9px; | |
| border-radius: 999px; | |
| font-size: 0.7rem; | |
| font-weight: 700; | |
| letter-spacing: 0.04em; | |
| text-transform: uppercase; | |
| margin-left: 8px; | |
| vertical-align: middle; | |
| border: 1px solid transparent; | |
| line-height: 1.4; | |
| } | |
| .sync-pill-high { | |
| background: #ECFDF5; | |
| color: #065F46; | |
| border-color: #6EE7B7; | |
| } | |
| .sync-pill-medium { | |
| background: #FEF3C7; | |
| color: #92400E; | |
| border-color: #FCD34D; | |
| } | |
| .sync-pill-low { | |
| background: #FFEDD5; | |
| color: #9A3412; | |
| border-color: #FDBA74; | |
| } | |
| .sync-pill-uncertain { | |
| background: #F1F5F9; | |
| color: #475569; | |
| border-color: #CBD5E1; | |
| } | |
| .sync-pill-alert { | |
| background: #FEE2E2; | |
| color: #991B1B; | |
| border-color: #FCA5A5; | |
| } | |
| /* Instrumentation / category chips — deeper indigo than before so the | |
| chip stands out cleanly on the white card without competing with the | |
| accent stripe colour. */ | |
| .sync-chip { | |
| display: inline-block; | |
| padding: 4px 12px; | |
| border-radius: 999px; | |
| background: #EEF2FF; | |
| color: #3730A3; | |
| border: 1px solid #C7D2FE; | |
| font-size: 0.84rem; | |
| font-weight: 500; | |
| margin: 3px 6px 3px 0; | |
| } | |
| /* Stat cell on overview pipeline grid. */ | |
| .sync-stat { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 2px; | |
| } | |
| .sync-stat-label { | |
| font-size: 0.72rem; | |
| color: #6B7280; | |
| text-transform: uppercase; | |
| letter-spacing: 0.06em; | |
| } | |
| .sync-stat-value { | |
| font-size: 1.35rem; | |
| color: #1F2933; | |
| font-weight: 600; | |
| } | |
| .sync-stat-sub { | |
| font-size: 0.78rem; | |
| color: #6B7280; | |
| } | |
| </style> | |
| """ | |
| def apply_global_styles() -> None: | |
| """Inject the small set of CSS overrides we rely on. | |
| Idempotent — safe to call from every page; Streamlit's rerun model means | |
| pages re-execute top-to-bottom anyway. | |
| """ | |
| st.markdown(_GLOBAL_CSS, unsafe_allow_html=True) | |