diff --git a/src/theme.rs b/src/theme.rs index 9b1943d..6b115ac 100644 --- a/src/theme.rs +++ b/src/theme.rs @@ -60,6 +60,9 @@ pub enum AppTheme { GruvboxDark, SolarizedLight, GruvboxLight, + AyuDark, + AyuMirage, + AyuLight, } /// Build a `Color` from a packed `0xRRGGBB` literal — keeps the palette tables @@ -70,7 +73,7 @@ fn hex(c: u32) -> Color { impl AppTheme { /// Every theme, in picker order. - pub const ALL: [AppTheme; 10] = [ + pub const ALL: [AppTheme; 13] = [ AppTheme::Mocha, AppTheme::Macchiato, AppTheme::Frappe, @@ -81,6 +84,9 @@ impl AppTheme { AppTheme::GruvboxDark, AppTheme::SolarizedLight, AppTheme::GruvboxLight, + AppTheme::AyuDark, + AppTheme::AyuMirage, + AppTheme::AyuLight, ]; /// Human-readable name for the picker. @@ -96,6 +102,9 @@ impl AppTheme { AppTheme::GruvboxDark => "Gruvbox Dark", AppTheme::SolarizedLight => "Solarized Light", AppTheme::GruvboxLight => "Gruvbox Light", + AppTheme::AyuDark => "Ayu Dark", + AppTheme::AyuMirage => "Ayu Mirage", + AppTheme::AyuLight => "Ayu Light", } } @@ -103,7 +112,10 @@ impl AppTheme { pub fn is_dark(self) -> bool { !matches!( self, - AppTheme::Latte | AppTheme::SolarizedLight | AppTheme::GruvboxLight + AppTheme::Latte + | AppTheme::SolarizedLight + | AppTheme::GruvboxLight + | AppTheme::AyuLight ) } @@ -120,6 +132,8 @@ impl AppTheme { AppTheme::GruvboxDark => iced::Theme::GruvboxDark, AppTheme::SolarizedLight => iced::Theme::SolarizedLight, AppTheme::GruvboxLight => iced::Theme::GruvboxLight, + AppTheme::AyuDark | AppTheme::AyuMirage => iced::Theme::TokyoNight, + AppTheme::AyuLight => iced::Theme::Light, } } @@ -281,6 +295,52 @@ impl AppTheme { green: hex(0x79740e), yellow: hex(0xb57614), }, + AppTheme::AyuDark => Palette { + crust: hex(0x06080a), + mantle: hex(0x0b0e14), + base: hex(0x0d1017), + surface: hex(0x1c222b), + overlay: hex(0x565b66), + text: hex(0xbfbdb6), + subtext: hex(0x9da1a6), + blue: hex(0xe6b450), + lavender: hex(0x59c2ff), + red: hex(0xf07178), + maroon: hex(0xff8f40), + green: hex(0xaad94c), + yellow: hex(0xffb454), + }, + AppTheme::AyuMirage => Palette { + crust: hex(0x171b24), + mantle: hex(0x1a1f29), + base: hex(0x1f2430), + surface: hex(0x232834), + overlay: hex(0x707a8c), + text: hex(0xcccac2), + subtext: hex(0xa6abb4), + blue: hex(0xffcc66), + lavender: hex(0x73d0ff), + red: hex(0xf28779), + maroon: hex(0xffa759), + green: hex(0xd5ff80), + yellow: hex(0xffd173), + }, + // Ayu Light's canonical orange is deepened for legibility on white. + AppTheme::AyuLight => Palette { + crust: hex(0xe6e9ec), + mantle: hex(0xf3f4f5), + base: hex(0xfcfcfc), + surface: hex(0xe8eaed), + overlay: hex(0x8a9199), + text: hex(0x5c6166), + subtext: hex(0x737980), + blue: hex(0xc7500e), + lavender: hex(0x399ee6), + red: hex(0xf07171), + maroon: hex(0xfa8d3e), + green: hex(0x86b300), + yellow: hex(0xff9940), + }, } } } @@ -371,11 +431,11 @@ mod tests { fn all_themes_distinct_and_labeled() { // ALL covers exactly the variants once, each with a unique non-empty label // and a distinct base colour (so swatches don't look identical). - assert_eq!(AppTheme::ALL.len(), 10); + assert_eq!(AppTheme::ALL.len(), 13); let mut labels: Vec<&str> = AppTheme::ALL.iter().map(|t| t.label()).collect(); labels.sort_unstable(); labels.dedup(); - assert_eq!(labels.len(), 10, "labels must be unique + non-empty"); + assert_eq!(labels.len(), 13, "labels must be unique + non-empty"); assert!(labels.iter().all(|l| !l.is_empty())); }