use crate::display_list::Color; pub const BG: Color = Color::rgb(255, 255, 255); // A visibly separate chrome layer against the warm, near-white content canvas. pub const BAR: Color = Color::rgb(230, 233, 237); pub const BORDER: Color = Color::rgb(226, 226, 226); pub const TEXT: Color = Color::rgb(35, 42, 53); pub const MUTED: Color = Color::rgb(103, 114, 130); pub const ERROR: Color = Color::rgb(175, 42, 49); pub const OK: Color = Color::rgb(31, 121, 80); pub const PALETTE: [Color; 6] = [ Color::rgb(22, 113, 213), Color::rgb(0, 132, 143), Color::rgb(115, 76, 189), Color::rgb(180, 68, 115), Color::rgb(168, 94, 24), Color::rgb(52, 123, 78), ]; #[derive(Clone, Copy, Debug)] pub struct Theme { pub accent: Color, } impl Theme { pub fn new(accent: Color) -> Self { Self { accent: readable_accent(accent), } } pub fn soft(self) -> Color { mix(BG, self.accent, 0.10) } pub fn hover(self) -> Color { mix(BG, self.accent, 0.17) } pub fn pressed(self) -> Color { mix(BG, self.accent, 0.29) } } pub fn mix(a: Color, b: Color, amount: f32) -> Color { let channel = |a: u8, b: u8| (a as f32 + (b as f32 - a as f32) * amount.clamp(0.0, 1.0)).round() as u8; Color::rgb( channel(a.red, b.red), channel(a.green, b.green), channel(a.blue, b.blue), ) } pub fn readable_accent(mut c: Color) -> Color { while (c.red as u32 * 299 + c.green as u32 * 587 + c.blue as u32 * 114) / 1000 > 155 { c = Color::rgb( (c.red as f32 * 0.94) as u8, (c.green as f32 * 0.94) as u8, (c.blue as f32 * 0.94) as u8, ); } c }