Initial release: 7-tab simulator with synced animations on Reliability / OEP / Pricing / Economics + 16 paper figures
c561a2a verified | """Intelligent Actuaries palette + theme-aware Plotly helper. | |
| The IA visual identity: bone background, deep warm near-black headings, | |
| burnt-sienna accents. Used in both the paper PDF and this Space so the | |
| two stay visually consistent. | |
| """ | |
| from __future__ import annotations | |
| import plotly.graph_objects as go | |
| import streamlit as st | |
| # IA palette — must match dc_paper.tex \definecolor block. | |
| IA_BONE = "#FAFAF7" | |
| IA_DARK = "#1B1815" | |
| IA_ACCENT = "#A04A1F" | |
| IA_TAUPE = "#F2EDE6" | |
| IA_RULE = "#3A332D" | |
| IA_GREY = "#5A524A" | |
| # Supporting palette for multi-series plots. | |
| IA_BLUE = "#1F4F73" | |
| IA_TEAL = "#0E7C7B" | |
| IA_OLIVE = "#6B6E3B" | |
| IA_PLUM = "#5B3A4A" | |
| SERIES_COLORS = [IA_ACCENT, IA_BLUE, IA_TEAL, IA_OLIVE, IA_PLUM, IA_RULE] | |
| def _is_dark_theme() -> bool: | |
| """Detect whether Streamlit is in dark mode.""" | |
| try: | |
| base = st.get_option("theme.base") or "" | |
| except Exception: | |
| base = "" | |
| return base.lower() == "dark" | |
| def apply_theme(fig: go.Figure, *, ytype: str | None = None) -> go.Figure: | |
| """Stamp the IA look on a Plotly figure. | |
| - Transparent paper / plot so the Streamlit container colour shows | |
| through (bone in light mode, near-black in dark mode). | |
| - Readable text + grid colours per OS theme. | |
| - Optional yaxis type override (e.g. 'log'). | |
| """ | |
| dark = _is_dark_theme() | |
| text = "rgba(250,250,250,0.94)" if dark else IA_DARK | |
| grid = "rgba(255,255,255,0.10)" if dark else "rgba(27,24,21,0.10)" | |
| legend = "rgba(0,0,0,0)" | |
| fig.update_layout( | |
| template="plotly_dark" if dark else "plotly_white", | |
| paper_bgcolor="rgba(0,0,0,0)", | |
| plot_bgcolor="rgba(0,0,0,0)", | |
| font=dict(family="Helvetica, Arial, sans-serif", color=text, size=12), | |
| legend=dict(bgcolor=legend, bordercolor="rgba(0,0,0,0)"), | |
| margin=dict(l=50, r=20, t=40, b=50), | |
| xaxis=dict(gridcolor=grid, zerolinecolor=grid, linecolor=text), | |
| yaxis=dict(gridcolor=grid, zerolinecolor=grid, linecolor=text), | |
| ) | |
| if ytype is not None: | |
| fig.update_yaxes(type=ytype) | |
| return fig | |