//! Palette definition and color mixing utilities. use ratatui::style::Color; /// RGB color triple. pub type Rgb = (u8, u8, u8); /// Base color palette that themes are derived from. pub struct Palette { // Core pub bg: Rgb, pub surface: Rgb, pub surface2: Rgb, pub fg: Rgb, pub fg_dim: Rgb, pub fg_muted: Rgb, // Semantic accents pub accent: Rgb, pub red: Rgb, pub green: Rgb, pub yellow: Rgb, pub blue: Rgb, pub purple: Rgb, pub cyan: Rgb, pub orange: Rgb, // Role assignments pub tempo_color: Rgb, pub bank_color: Rgb, pub pattern_color: Rgb, pub title_accent: Rgb, pub title_author: Rgb, pub secondary: Rgb, // Arrays pub link_bright: [Rgb; 5], pub link_dim: [Rgb; 5], pub sparkle: [Rgb; 5], pub meter: [Rgb; 3], } /// Convert an RGB triple to a ratatui [`Color`]. pub fn rgb(c: Rgb) -> Color { Color::Rgb(c.0, c.1, c.2) } /// Blend `bg` toward `accent` by `amount` (0.0–1.0). pub fn tint(bg: Rgb, accent: Rgb, amount: f32) -> Rgb { let mix = |b: u8, a: u8| -> u8 { let v = b as f32 + (a as f32 - b as f32) * amount; v.clamp(0.0, 255.0) as u8 }; (mix(bg.0, accent.0), mix(bg.1, accent.1), mix(bg.2, accent.2)) } /// Linearly interpolate between two colors. pub fn mid(a: Rgb, b: Rgb, t: f32) -> Rgb { tint(a, b, t) } /// Darken a color by reducing brightness. pub fn darken(c: Rgb, amount: f32) -> Rgb { let d = |v: u8| -> u8 { (v as f32 * (1.0 - amount)).clamp(0.0, 255.0) as u8 }; (d(c.0), d(c.1), d(c.2)) }