Skip to main content

core_glyph/
theme.rs

1use crate::view::Color;
2
3/// Semantic color tokens for a UI theme. Components should read from these
4/// rather than hardcoding colors so the entire app can be restyled by swapping
5/// one `Theme` value.
6#[derive(Clone, Debug)]
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8pub struct Theme {
9    /// Window/page background.
10    pub background: Color,
11    /// Elevated surface (cards, panels, inputs).
12    pub surface: Color,
13    /// Primary action color (buttons, focus rings, accents).
14    pub primary: Color,
15    /// Text on primary-colored backgrounds.
16    pub on_primary: Color,
17    /// Default body text.
18    pub text: Color,
19    /// Subdued / hint text.
20    pub text_muted: Color,
21    /// Default border and divider color.
22    pub border: Color,
23    /// Border color when a field is focused.
24    pub border_focused: Color,
25    /// Corner radius applied to buttons and inputs.
26    pub radius: f32,
27    /// Base font size for body text.
28    pub font_size: f32,
29}
30
31impl Theme {
32    /// A clean light theme.
33    pub fn light() -> Self {
34        Self {
35            background:    Color::rgb(1.0, 1.0, 1.0),
36            surface:       Color::rgb(0.94, 0.94, 0.96),
37            primary:       Color::rgb(0.0, 0.47, 1.0),
38            on_primary:    Color::WHITE,
39            text:          Color::BLACK,
40            text_muted:    Color::rgb(0.5, 0.5, 0.5),
41            border:        Color::rgb(0.75, 0.75, 0.75),
42            border_focused: Color::rgb(0.0, 0.47, 1.0),
43            radius:        8.0,
44            font_size:     16.0,
45        }
46    }
47
48    /// A dark theme.
49    pub fn dark() -> Self {
50        Self {
51            background:    Color::rgb(0.1,  0.1,  0.12),
52            surface:       Color::rgb(0.16, 0.16, 0.18),
53            primary:       Color::rgb(0.35, 0.55, 1.0),
54            on_primary:    Color::WHITE,
55            text:          Color::rgb(0.92, 0.92, 0.92),
56            text_muted:    Color::rgb(0.55, 0.55, 0.55),
57            border:        Color::rgb(0.3,  0.3,  0.32),
58            border_focused: Color::rgb(0.35, 0.55, 1.0),
59            radius:        8.0,
60            font_size:     16.0,
61        }
62    }
63}