dex-demo / src /dex_studio /theme.py
data-literate's picture
chore: add workspace config, update CI, gitignore, README
de32734
Raw History Blame Contribute Delete
3.2 kB
"""DEX Studio UI theme and shared styles.
Centralises colour palette, typography, and recurring CSS so that
all pages render consistently.
"""
from __future__ import annotations
from string import Template
__all__ = [
"COLORS",
"apply_global_styles",
]
# -- Colour palette (dark-first, inspired by DEX brand) -------------------
COLORS = {
"bg_primary": "#0f1117",
"bg_secondary": "#1a1d27",
"bg_card": "#1e2130",
"bg_hover": "#252838",
"accent": "#6366f1", # indigo-500
"accent_light": "#818cf8", # indigo-400
"accent_muted": "#4f46e5", # indigo-600
"success": "#22c55e",
"warning": "#f59e0b",
"error": "#ef4444",
"text_primary": "#f1f5f9",
"text_secondary": "#94a3b8",
"text_muted": "#64748b",
"border": "#2e3347",
"divider": "#313652",
}
# -- Global CSS injected once at app startup ------------------------------
_GLOBAL_CSS = Template("""
:root {
--bg-primary: $bg_primary;
--bg-secondary: $bg_secondary;
--bg-card: $bg_card;
--accent: $accent;
--accent-light: $accent_light;
--success: $success;
--warning: $warning;
--error: $error;
--text-primary: $text_primary;
--text-secondary: $text_secondary;
--text-muted: $text_muted;
--border: $border;
}
body {
background-color: var(--bg-primary) !important;
color: var(--text-primary) !important;
font-family: 'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif;
}
.nicegui-content {
background-color: var(--bg-primary) !important;
}
/* Card styling */
.dex-card {
background-color: var(--bg-card);
border: 1px solid var(--border);
border-radius: 12px;
padding: 1.25rem;
transition: border-color 0.2s ease;
}
.dex-card:hover {
border-color: var(--accent);
}
/* Status indicators */
.status-healthy { color: var(--success); }
.status-degraded { color: var(--warning); }
.status-unhealthy { color: var(--error); }
/* Section headers */
.section-title {
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--text-muted);
margin-bottom: 0.5rem;
}
/* Sidebar */
.sidebar-nav {
background-color: var(--bg-secondary);
border-right: 1px solid var(--border);
height: 100vh;
padding: 1rem 0;
}
.sidebar-link {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 0.6rem 1.25rem;
color: var(--text-secondary);
text-decoration: none;
font-size: 0.875rem;
transition: all 0.15s ease;
border-left: 3px solid transparent;
}
.sidebar-link:hover {
color: var(--text-primary);
background-color: var(--bg-card);
}
.sidebar-link.active {
color: var(--accent-light);
background-color: var(--bg-card);
border-left-color: var(--accent);
}
/* Metric cards */
.metric-value {
font-size: 2rem;
font-weight: 700;
line-height: 1;
color: var(--text-primary);
}
.metric-label {
font-size: 0.8rem;
color: var(--text-muted);
margin-top: 0.25rem;
}
""").substitute(COLORS)
def apply_global_styles() -> None:
"""Inject global CSS into the current NiceGUI page."""
from nicegui import ui
ui.add_css(_GLOBAL_CSS)