"""Shared visual style: page config, dark-mode CSS, palette.""" from __future__ import annotations import streamlit as st # Polished dark palette inspired by analyst-tool surfaces (Looker, Hex, Mode). PALETTE = { "primary": "#E15A63", # accent crimson "secondary": "#5BA3DA", # accent steel-blue "accent": "#E0B458", # mountain gold "good": "#3FAE7B", "warn": "#E0B458", "bad": "#D9534F", "muted": "#9CA3AF", "bg": "#0B0E13", "surface": "#141821", "surface2": "#1A1F2A", "border": "#262C38", "text": "#E6E8EB", "text_dim": "#9CA3AF", "treated": "#5BA3DA", "control": "#E15A63", } INITIATIVE_COLOR = { 1: "#E0B458", # workforce (gold) 2: "#5BA3DA", # facility (blue) 3: "#3FAE7B", # innovative (green) 4: "#D679A4", # prevention (rose) 5: "#A487E0", # technology (violet) } def page_setup(title: str, layout: str = "wide") -> None: st.set_page_config( page_title=f"RHTP Evaluation — {title}", layout=layout, initial_sidebar_state="expanded", ) st.markdown(_CSS, unsafe_allow_html=True) _CSS = """ """ def header(title: str, subtitle: str | None = None, pill: tuple[str, str] | None = None) -> None: pill_html = "" if pill: text, kind = pill pill_html = f' {text}' st.markdown(f"# {title}{pill_html}", unsafe_allow_html=True) if subtitle: st.markdown( f"
{subtitle}
", unsafe_allow_html=True, ) st.markdown("
", unsafe_allow_html=True) def section(title: str, kicker: str | None = None) -> None: st.markdown(f"## {title}") if kicker: st.markdown( f"
" f"{kicker}
", unsafe_allow_html=True, ) def callout(body: str, kind: str = "info", title: str | None = None) -> None: cls = {"info": " info", "success": " success", "warn": " warn", "bad": " bad"}.get(kind, "") head = f"{title}
" if title else "" st.markdown( f"
{head}{body}
", unsafe_allow_html=True, ) def formula(latex: str, caption: str | None = None) -> None: st.latex(latex) if caption: st.caption(caption) # Plain-text verdict labels (no emojis). Callers can pass these to a styler # inside dataframes, or embed them in markdown via verdict_chip(). VERDICT_LABELS = { "pass": "Effective", "partial": "Right direction", "weak": "Imprecise", "fail": "Wrong direction", "context": "Contextual", } def verdict_chip(kind: str, text: str | None = None) -> str: """Return an HTML chip with the right CSS class. Used inside markdown.""" cls = kind if kind in {"pass", "partial", "weak", "fail", "context"} else "context" label = text or VERDICT_LABELS.get(kind, kind) return f"{label}" def section_divider(label: str | None = None) -> None: """Visible divider used between major page sections.""" st.markdown("
", unsafe_allow_html=True) if label: st.markdown( f"
{label}
", unsafe_allow_html=True, ) def initiative_scope( *, initiative_no: int, title: str, kpos: list[dict], inputs: list[dict], ) -> None: """Render the KPO table and the treatment-input table side-by-side. Each kpo dict: name, level, baseline, target. Each input dict: name, level, notes. """ st.markdown(f"## Initiative scope") st.markdown( f"
" f"What this initiative is trying to move and the levers it pulls. " f"All baselines and FY2031 targets are derived from the synthetic " f"data in /data/ and the RHTP plan structure.
", unsafe_allow_html=True, ) def _kpo_row(k: dict) -> str: return ( "" f"{k['name']}" f"{k['level']}" f"{k['baseline']}" f"{k['target']}" "" ) def _input_row(i: dict) -> str: notes = i.get("notes", "") return ( "" f"{i['name']}" f"{i['level']}" f"{notes}" "" ) # Stacked vertically: KPOs first (full width), then inputs. kpo_body = ( "
" "
" "Initiative " + f"{initiative_no:02d} · KPOs" + "" "Key Program Outcomes monitored" "
" "" "" "" "" + "".join(_kpo_row(k) for k in kpos) + "
OutcomeLevelBaselineFY2031 target
" ) st.markdown(kpo_body, unsafe_allow_html=True) input_body = ( "
" "
" "Initiative " + f"{initiative_no:02d} · inputs" + "" "Treatment / intervention levers" "
" "" "" "" + "".join(_input_row(i) for i in inputs) + "
InputLevelNotes
" ) st.markdown(input_body, unsafe_allow_html=True) def equation_legend(rows: list[tuple[str, str]]) -> None: """Render an equation symbol -> definition legend.""" body = "
" for sym, defn in rows: body += ( "
" f"
{sym}
" f"
{defn}
" "
" ) body += "
" st.markdown(body, unsafe_allow_html=True) def role_box(rows: list[tuple[str, str]], title: str | None = None) -> None: """Small box labeling the role each model component plays.""" body = "
" if title: body += ( f"
{title}
" ) for label, desc in rows: body += ( "
" f"
{label}
" f"
{desc}
" "
" ) body += "
" st.markdown(body, unsafe_allow_html=True) def glossary(title: str, rows: list[tuple[str, str]]) -> None: """Render a term/definition glossary card.""" body = ( "
" f"
{title}
" ) for term, defn in rows: body += ( "
" f"
{term}
" f"
{defn}
" "
" ) body += "
" st.markdown(body, unsafe_allow_html=True)