1use ratatui::style::{Color, Modifier, Style};
7use ratatui::symbols;
8use ratatui::widgets::BorderType;
9
10#[derive(Debug, Clone, Copy)]
12pub struct Palette {
13 pub primary: Color,
15 pub secondary: Color,
17 pub surface: Color,
19 pub on_surface: Color,
21 pub on_surface_muted: Color,
23 pub border: Color,
25 pub border_focused: Color,
27 pub success: Color,
29 pub warning: Color,
31 pub error: Color,
33}
34
35impl Default for Palette {
36 fn default() -> Self {
37 Self::dark()
38 }
39}
40
41impl Palette {
42 pub fn dark() -> Self {
44 Self {
45 primary: Color::Rgb(129, 199, 132), secondary: Color::Rgb(144, 202, 249), surface: Color::Rgb(40, 42, 54), on_surface: Color::Rgb(248, 248, 242), on_surface_muted: Color::Rgb(120, 144, 156), border: Color::Rgb(96, 125, 139), border_focused: Color::Rgb(129, 199, 132), success: Color::Rgb(102, 187, 106), warning: Color::Rgb(255, 183, 77), error: Color::Rgb(239, 83, 80), }
56 }
57}
58
59pub const ROUNDED_BORDERS: symbols::border::Set = symbols::border::ROUNDED;
61
62pub const fn rounded_border_type() -> BorderType {
64 BorderType::Rounded
65}
66
67#[derive(Debug, Clone)]
69pub struct Theme {
70 pub palette: Palette,
72 pub user_message: Style,
74 pub assistant_message: Style,
76 pub system_message: Style,
78 pub code_block: Style,
80 pub success: Style,
82 pub warning: Style,
84 pub error: Style,
86 pub energy_high: Style,
88 pub energy_medium: Style,
90 pub energy_low: Style,
92 pub border: Style,
94 pub highlight: Style,
96 pub muted: Style,
98 pub cursor: Style,
100 pub tab_active: Style,
102 pub tab_inactive: Style,
104 pub user_message_bg: Style,
106}
107
108impl Default for Theme {
109 fn default() -> Self {
110 Self::dark()
111 }
112}
113
114impl Theme {
115 pub fn dark() -> Self {
117 let palette = Palette::dark();
118
119 Self {
120 palette,
121 user_message: Style::default()
123 .fg(palette.primary)
124 .add_modifier(Modifier::BOLD),
125 assistant_message: Style::default().fg(palette.secondary),
126 system_message: Style::default().fg(Color::Rgb(176, 190, 197)),
127
128 code_block: Style::default().fg(palette.on_surface).bg(palette.surface),
130
131 success: Style::default().fg(palette.success),
133 warning: Style::default().fg(palette.warning),
134 error: Style::default().fg(palette.error),
135
136 energy_high: Style::default()
138 .fg(palette.error)
139 .add_modifier(Modifier::BOLD),
140 energy_medium: Style::default().fg(palette.warning),
141 energy_low: Style::default()
142 .fg(palette.success)
143 .add_modifier(Modifier::BOLD),
144
145 border: Style::default().fg(palette.border),
147 highlight: Style::default()
148 .fg(Color::Rgb(224, 247, 250))
149 .bg(Color::Rgb(55, 71, 79))
150 .add_modifier(Modifier::BOLD),
151 muted: Style::default().fg(palette.on_surface_muted),
152
153 cursor: Style::default()
155 .fg(Color::Rgb(129, 212, 250))
156 .add_modifier(Modifier::SLOW_BLINK),
157
158 tab_active: Style::default()
160 .fg(palette.primary)
161 .add_modifier(Modifier::BOLD),
162 tab_inactive: Style::default().fg(palette.on_surface_muted),
163
164 user_message_bg: Style::default().bg(Color::Rgb(30, 35, 40)), }
167 }
168
169 pub fn energy_style(&self, energy: f32) -> Style {
171 if energy < 0.1 {
172 self.energy_low
173 } else if energy < 0.5 {
174 self.energy_medium
175 } else {
176 self.energy_high
177 }
178 }
179
180 pub fn status_style(&self, status: &str) -> Style {
182 match status.to_lowercase().as_str() {
183 "completed" | "stable" | "ok" => self.success,
184 "running" | "pending" | "converging" => self.warning,
185 "failed" | "error" | "escalated" => self.error,
186 _ => self.muted,
187 }
188 }
189}
190
191pub mod icons {
193 pub const USER: &str = "đ§";
194 pub const ASSISTANT: &str = "đ¤";
195 pub const SYSTEM: &str = "âšī¸";
196 pub const SUCCESS: &str = "â";
197 pub const FAILURE: &str = "â";
198 pub const WARNING: &str = "â ";
199 pub const PENDING: &str = "â";
200 pub const RUNNING: &str = "â";
201 pub const COMPLETED: &str = "â";
202 pub const ROCKET: &str = "đ";
203 pub const TREE: &str = "đŗ";
204 pub const FILE: &str = "đ";
205 pub const FOLDER: &str = "đ";
206 pub const ENERGY: &str = "âĄ";
207 pub const STABLE: &str = "đ";
208 pub const CURSOR: &str = "â";
209 pub const TREE_BRANCH: &str = "ââ";
211 pub const TREE_LAST: &str = "ââ";
212 pub const TREE_LINE: &str = "â ";
213 pub const TREE_SPACE: &str = " ";
214}