use ratatui::style::{Color, Modifier, Style};
pub const BG_DARK: Color = Color::Rgb(26, 27, 38);
pub const BG_PANEL: Color = Color::Rgb(36, 40, 59);
pub const BG_HIGHLIGHT: Color = Color::Rgb(41, 46, 66);
pub const BG_SELECTION: Color = Color::Rgb(52, 59, 88);
pub const FG: Color = Color::Rgb(169, 177, 214);
pub const FG_DIM: Color = Color::Rgb(86, 95, 137);
pub const FG_BRIGHT: Color = Color::Rgb(199, 208, 245);
pub const BLUE: Color = Color::Rgb(122, 162, 247);
pub const PURPLE: Color = Color::Rgb(187, 154, 247);
pub const CYAN: Color = Color::Rgb(125, 207, 255);
pub const GREEN: Color = Color::Rgb(158, 206, 106);
pub const YELLOW: Color = Color::Rgb(224, 175, 104);
pub const ORANGE: Color = Color::Rgb(255, 158, 100);
pub const RED: Color = Color::Rgb(247, 118, 142);
pub const PINK: Color = Color::Rgb(255, 117, 165);
pub const TEAL: Color = Color::Rgb(115, 218, 202);
pub const MODEL_COLORS: &[Color] = &[
Color::Rgb(122, 162, 247), Color::Rgb(158, 206, 106), Color::Rgb(255, 158, 100), Color::Rgb(187, 154, 247), Color::Rgb(125, 207, 255), ];
pub fn model_color(index: usize) -> Color {
MODEL_COLORS[index % MODEL_COLORS.len()]
}
pub fn quality_color(ratio: f32, good_high: bool) -> Color {
let r = if good_high { ratio } else { 1.0 - ratio };
let r = r.clamp(0.0, 1.0);
if r > 0.7 {
GREEN
} else if r > 0.4 {
YELLOW
} else {
RED
}
}
pub fn heat_color(v: f32) -> Color {
let v = v.clamp(0.0, 1.0);
if v < 0.25 {
Color::Rgb(36, 40, 59) } else if v < 0.5 {
Color::Rgb(86, 95, 137) } else if v < 0.75 {
YELLOW
} else {
ORANGE
}
}
pub fn title_style() -> Style {
Style::new().fg(FG_BRIGHT).add_modifier(Modifier::BOLD)
}
pub fn heading_style() -> Style {
Style::new().fg(BLUE).add_modifier(Modifier::BOLD)
}
pub fn dim_style() -> Style {
Style::new().fg(FG_DIM)
}
pub fn highlight_style() -> Style {
Style::new().bg(BG_SELECTION).fg(FG_BRIGHT)
}
pub fn key_style() -> Style {
Style::new().fg(YELLOW).add_modifier(Modifier::BOLD)
}
pub fn value_style() -> Style {
Style::new().fg(FG)
}
pub fn good_style() -> Style {
Style::new().fg(GREEN)
}
pub fn warn_style() -> Style {
Style::new().fg(YELLOW)
}
pub fn bad_style() -> Style {
Style::new().fg(RED)
}
pub fn accent_style() -> Style {
Style::new().fg(BLUE)
}
pub fn panel_block_style() -> Style {
Style::new().fg(FG_DIM).bg(BG_DARK)
}
pub fn dim_color(base: Color, intensity: f32) -> Color {
let intensity = intensity.clamp(0.0, 1.0);
match base {
Color::Rgb(r, g, b) => Color::Rgb(
(r as f32 * intensity) as u8,
(g as f32 * intensity) as u8,
(b as f32 * intensity) as u8,
),
other => other,
}
}
pub fn mini_bar(ratio: f32, width: usize) -> String {
let filled = (ratio.clamp(0.0, 1.0) * width as f32).round() as usize;
let empty = width.saturating_sub(filled);
format!("{}{}", "█".repeat(filled), "░".repeat(empty))
}
pub fn truncate(s: &str, max: usize) -> String {
if s.len() <= max {
s.to_string()
} else {
format!("{}…", &s[..max.saturating_sub(1)])
}
}