//! Built-in theme presets. Each function returns a fully-populated [`Theme`]; `[theme]
//! preset = "name"` selects one as the base, and any sibling keys in `[theme]` override
//! individual tokens on top (see [`super::Theme::from_config`]).
//!
//! Adding a preset: pick the palette's hex values, map them to semantic tokens by the
//! conventions below, add the `fn`, list it in [`by_name`], and add the name to the
//! `KNOWN` slice. No registry — just functions — keeps each preset self-contained and
//! grep-able.
//!
//! Mapping conventions (applied uniformly across presets so swapping one for another gives a
//! predictable shift rather than a surprise):
//! - `bg` / `bg_subtle` = palette background + one step lifted.
//! - `text` = palette foreground; `text_dim` = comment tone; `text_secondary` = a step
//!   brighter than `text_dim`.
//! - `panel_border` = the palette's "panel / surface" tone (slightly dimmer than `text`).
//! - `panel_title` = the palette's primary accent blue/purple.
//! - `status_ok` / `status_warn` / `status_error` = the palette's green / yellow / red.
//! - `accent_today` = yellow; `accent_event` = cyan.
//! - `palette_series` = 10-entry cycle drawn from the palette's accent colours.
//! - `palette_heatmap` = 5-step gradient from a near-background tone up to the palette's
//!   green.
//!
//! Light presets keep the same mapping but anchor `bg` on the palette's lightest tone and
//! darken the accent triad so contrast still reads on a bright surface.

use ratatui::style::Color;

use super::Theme;

/// Names of every built-in preset, alphabetical. Used for `[theme] preset = "..."`
/// lookups and the "unknown preset" error message. `"default"` resolves to
/// [`Theme::default`] (the Splash signature palette) so preset-switching tools don't
/// have to special-case the built-in; the same palette is also reachable by omitting
/// `[theme] preset = "..."` entirely.
pub const KNOWN: &[&str] = &[
    "ayu_mirage",
    "catppuccin_frappe",
    "catppuccin_latte",
    "catppuccin_macchiato",
    "catppuccin_mocha",
    "default",
    "dracula",
    "everforest_dark",
    "github_dark",
    "github_light",
    "gruvbox_dark",
    "gruvbox_light",
    "kanagawa",
    "material_palenight",
    "monokai",
    "night_owl",
    "nord",
    "one_dark",
    "rose_pine",
    "rose_pine_dawn",
    "rose_pine_moon",
    "solarized_dark",
    "solarized_light",
    "synthwave_84",
    "tokyo_night",
    "tokyo_night_storm",
];

/// Resolve a preset by name. Returns `None` for unknown names — the caller ([`super::Theme::
/// from_config`]) surfaces that as a config error rather than silently falling through to the
/// default theme.
pub fn by_name(name: &str) -> Option<Theme> {
    match name {
        "ayu_mirage" => Some(ayu_mirage()),
        "catppuccin_frappe" => Some(catppuccin_frappe()),
        "catppuccin_latte" => Some(catppuccin_latte()),
        "catppuccin_macchiato" => Some(catppuccin_macchiato()),
        "catppuccin_mocha" => Some(catppuccin_mocha()),
        "default" => Some(Theme::default()),
        "dracula" => Some(dracula()),
        "everforest_dark" => Some(everforest_dark()),
        "github_dark" => Some(github_dark()),
        "github_light" => Some(github_light()),
        "gruvbox_dark" => Some(gruvbox_dark()),
        "gruvbox_light" => Some(gruvbox_light()),
        "kanagawa" => Some(kanagawa()),
        "material_palenight" => Some(material_palenight()),
        "monokai" => Some(monokai()),
        "night_owl" => Some(night_owl()),
        "nord" => Some(nord()),
        "one_dark" => Some(one_dark()),
        "rose_pine" => Some(rose_pine()),
        "rose_pine_dawn" => Some(rose_pine_dawn()),
        "rose_pine_moon" => Some(rose_pine_moon()),
        "solarized_dark" => Some(solarized_dark()),
        "solarized_light" => Some(solarized_light()),
        "synthwave_84" => Some(synthwave_84()),
        "tokyo_night" => Some(tokyo_night()),
        "tokyo_night_storm" => Some(tokyo_night_storm()),
        _ => None,
    }
}

pub fn ayu_mirage() -> Theme {
    Theme {
        bg: hex(0x1f, 0x24, 0x30),
        bg_subtle: hex(0x23, 0x28, 0x34),
        text: hex(0xcb, 0xcc, 0xc6),
        panel_border: hex(0x3d, 0x44, 0x53),
        panel_title: hex(0x5c, 0xcf, 0xe6),
        status_ok: hex(0xba, 0xe6, 0x7e),
        status_warn: hex(0xff, 0xd5, 0x80),
        status_error: hex(0xf2, 0x87, 0x79),
        text_dim: hex(0x5c, 0x67, 0x73),
        text_secondary: hex(0xb8, 0xcf, 0xe6),
        accent_today: hex(0xff, 0xd5, 0x80),
        accent_event: hex(0x95, 0xe6, 0xcb),
        palette_series: vec![
            hex(0xf2, 0x87, 0x79),
            hex(0x5c, 0xcf, 0xe6),
            hex(0xba, 0xe6, 0x7e),
            hex(0xff, 0xd5, 0x80),
            hex(0xd4, 0xbf, 0xff),
            hex(0x95, 0xe6, 0xcb),
            hex(0xff, 0xa7, 0x59),
            hex(0x73, 0xd0, 0xff),
            hex(0xf2, 0x9e, 0x74),
            hex(0xcb, 0xcc, 0xc6),
        ],
        palette_heatmap: vec![
            hex(0x1f, 0x24, 0x30),
            hex(0x35, 0x57, 0x4d),
            hex(0x5d, 0x83, 0x55),
            hex(0x8b, 0xb5, 0x6a),
            hex(0xba, 0xe6, 0x7e),
        ],
    }
}

pub fn catppuccin_frappe() -> Theme {
    Theme {
        bg: hex(0x30, 0x34, 0x46),
        bg_subtle: hex(0x41, 0x45, 0x59),
        text: hex(0xc6, 0xd0, 0xf5),
        panel_border: hex(0x51, 0x57, 0x6d),
        panel_title: hex(0x8c, 0xaa, 0xee),
        status_ok: hex(0xa6, 0xd1, 0x89),
        status_warn: hex(0xe5, 0xc8, 0x90),
        status_error: hex(0xe7, 0x82, 0x84),
        text_dim: hex(0x62, 0x68, 0x80),
        text_secondary: hex(0xb5, 0xbf, 0xe2),
        accent_today: hex(0xe5, 0xc8, 0x90),
        accent_event: hex(0x81, 0xc8, 0xbe),
        palette_series: vec![
            hex(0xe7, 0x82, 0x84),
            hex(0x8c, 0xaa, 0xee),
            hex(0xa6, 0xd1, 0x89),
            hex(0xe5, 0xc8, 0x90),
            hex(0xca, 0x9e, 0xe6),
            hex(0x81, 0xc8, 0xbe),
            hex(0xef, 0x9f, 0x76),
            hex(0x85, 0xc1, 0xdc),
            hex(0xf4, 0xb8, 0xe4),
            hex(0xc6, 0xd0, 0xf5),
        ],
        palette_heatmap: vec![
            hex(0x30, 0x34, 0x46),
            hex(0x4a, 0x6e, 0x4d),
            hex(0x6e, 0x9c, 0x60),
            hex(0x8a, 0xbb, 0x74),
            hex(0xa6, 0xd1, 0x89),
        ],
    }
}

pub fn catppuccin_latte() -> Theme {
    Theme {
        bg: hex(0xef, 0xf1, 0xf5),
        bg_subtle: hex(0xe6, 0xe9, 0xef),
        text: hex(0x4c, 0x4f, 0x69),
        panel_border: hex(0xbc, 0xc0, 0xcc),
        panel_title: hex(0x1e, 0x66, 0xf5),
        status_ok: hex(0x40, 0xa0, 0x2b),
        status_warn: hex(0xdf, 0x8e, 0x1d),
        status_error: hex(0xd2, 0x0f, 0x39),
        text_dim: hex(0x9c, 0xa0, 0xb0),
        text_secondary: hex(0x6c, 0x6f, 0x85),
        accent_today: hex(0xdf, 0x8e, 0x1d),
        accent_event: hex(0x17, 0x92, 0x99),
        palette_series: vec![
            hex(0xd2, 0x0f, 0x39),
            hex(0x1e, 0x66, 0xf5),
            hex(0x40, 0xa0, 0x2b),
            hex(0xdf, 0x8e, 0x1d),
            hex(0x88, 0x39, 0xef),
            hex(0x17, 0x92, 0x99),
            hex(0xfe, 0x64, 0x0b),
            hex(0x04, 0xa5, 0xe5),
            hex(0xea, 0x76, 0xcb),
            hex(0x4c, 0x4f, 0x69),
        ],
        palette_heatmap: vec![
            hex(0xef, 0xf1, 0xf5),
            hex(0xc7, 0xe1, 0xc1),
            hex(0x90, 0xc8, 0x88),
            hex(0x66, 0xb4, 0x55),
            hex(0x40, 0xa0, 0x2b),
        ],
    }
}

pub fn catppuccin_macchiato() -> Theme {
    Theme {
        bg: hex(0x24, 0x27, 0x3a),
        bg_subtle: hex(0x36, 0x3a, 0x4f),
        text: hex(0xca, 0xd3, 0xf5),
        panel_border: hex(0x49, 0x4d, 0x64),
        panel_title: hex(0x8a, 0xad, 0xf4),
        status_ok: hex(0xa6, 0xda, 0x95),
        status_warn: hex(0xee, 0xd4, 0x9f),
        status_error: hex(0xed, 0x87, 0x96),
        text_dim: hex(0x5b, 0x60, 0x78),
        text_secondary: hex(0xb8, 0xc0, 0xe0),
        accent_today: hex(0xee, 0xd4, 0x9f),
        accent_event: hex(0x8b, 0xd5, 0xca),
        palette_series: vec![
            hex(0xed, 0x87, 0x96),
            hex(0x8a, 0xad, 0xf4),
            hex(0xa6, 0xda, 0x95),
            hex(0xee, 0xd4, 0x9f),
            hex(0xc6, 0xa0, 0xf6),
            hex(0x8b, 0xd5, 0xca),
            hex(0xf5, 0xa9, 0x7f),
            hex(0x7d, 0xc4, 0xe4),
            hex(0xf5, 0xbd, 0xe6),
            hex(0xca, 0xd3, 0xf5),
        ],
        palette_heatmap: vec![
            hex(0x24, 0x27, 0x3a),
            hex(0x44, 0x6b, 0x42),
            hex(0x66, 0x96, 0x55),
            hex(0x86, 0xb8, 0x75),
            hex(0xa6, 0xda, 0x95),
        ],
    }
}

pub fn catppuccin_mocha() -> Theme {
    Theme {
        bg: hex(0x1e, 0x1e, 0x2e),
        bg_subtle: hex(0x31, 0x32, 0x44),
        text: hex(0xcd, 0xd6, 0xf4),
        panel_border: hex(0x45, 0x47, 0x5a),
        panel_title: hex(0x89, 0xb4, 0xfa),
        status_ok: hex(0xa6, 0xe3, 0xa1),
        status_warn: hex(0xf9, 0xe2, 0xaf),
        status_error: hex(0xf3, 0x8b, 0xa8),
        text_dim: hex(0x58, 0x5b, 0x70),
        text_secondary: hex(0xa6, 0xad, 0xc8),
        accent_today: hex(0xf9, 0xe2, 0xaf),
        accent_event: hex(0x94, 0xe2, 0xd5),
        palette_series: vec![
            hex(0xf3, 0x8b, 0xa8),
            hex(0x89, 0xb4, 0xfa),
            hex(0xa6, 0xe3, 0xa1),
            hex(0xf9, 0xe2, 0xaf),
            hex(0xcb, 0xa6, 0xf7),
            hex(0x94, 0xe2, 0xd5),
            hex(0xfa, 0xb3, 0x87),
            hex(0x74, 0xc7, 0xec),
            hex(0xf5, 0xc2, 0xe7),
            hex(0xcd, 0xd6, 0xf4),
        ],
        palette_heatmap: vec![
            hex(0x1e, 0x1e, 0x2e),
            hex(0x40, 0x6a, 0x3d),
            hex(0x60, 0x92, 0x4e),
            hex(0x80, 0xba, 0x60),
            hex(0xa6, 0xe3, 0xa1),
        ],
    }
}

pub fn dracula() -> Theme {
    Theme {
        bg: hex(0x28, 0x2a, 0x36),
        bg_subtle: hex(0x44, 0x47, 0x5a),
        text: hex(0xf8, 0xf8, 0xf2),
        panel_border: hex(0x44, 0x47, 0x5a),
        panel_title: hex(0xbd, 0x93, 0xf9),
        status_ok: hex(0x50, 0xfa, 0x7b),
        status_warn: hex(0xf1, 0xfa, 0x8c),
        status_error: hex(0xff, 0x55, 0x55),
        text_dim: hex(0x62, 0x72, 0xa4),
        text_secondary: hex(0xf8, 0xf8, 0xf2),
        accent_today: hex(0xf1, 0xfa, 0x8c),
        accent_event: hex(0x8b, 0xe9, 0xfd),
        palette_series: vec![
            hex(0xff, 0x79, 0xc6),
            hex(0x8b, 0xe9, 0xfd),
            hex(0x50, 0xfa, 0x7b),
            hex(0xff, 0xb8, 0x6c),
            hex(0xbd, 0x93, 0xf9),
            hex(0xf1, 0xfa, 0x8c),
            hex(0xff, 0x55, 0x55),
            hex(0x62, 0x72, 0xa4),
            hex(0x44, 0x47, 0x5a),
            hex(0xf8, 0xf8, 0xf2),
        ],
        palette_heatmap: vec![
            hex(0x28, 0x2a, 0x36),
            hex(0x37, 0x4c, 0x3e),
            hex(0x3d, 0x7a, 0x52),
            hex(0x3f, 0xb5, 0x65),
            hex(0x50, 0xfa, 0x7b),
        ],
    }
}

pub fn everforest_dark() -> Theme {
    Theme {
        bg: hex(0x2d, 0x35, 0x3b),
        bg_subtle: hex(0x34, 0x3f, 0x44),
        text: hex(0xd3, 0xc6, 0xaa),
        panel_border: hex(0x47, 0x52, 0x58),
        panel_title: hex(0x7f, 0xbb, 0xb3),
        status_ok: hex(0xa7, 0xc0, 0x80),
        status_warn: hex(0xdb, 0xbc, 0x7f),
        status_error: hex(0xe6, 0x7e, 0x80),
        text_dim: hex(0x7a, 0x84, 0x78),
        text_secondary: hex(0x9d, 0xa9, 0xa0),
        accent_today: hex(0xdb, 0xbc, 0x7f),
        accent_event: hex(0x83, 0xc0, 0x92),
        palette_series: vec![
            hex(0xe6, 0x7e, 0x80),
            hex(0x7f, 0xbb, 0xb3),
            hex(0xa7, 0xc0, 0x80),
            hex(0xdb, 0xbc, 0x7f),
            hex(0xd6, 0x99, 0xb6),
            hex(0x83, 0xc0, 0x92),
            hex(0xe6, 0x98, 0x75),
            hex(0x85, 0x92, 0x89),
            hex(0xbf, 0xa3, 0x88),
            hex(0xd3, 0xc6, 0xaa),
        ],
        palette_heatmap: vec![
            hex(0x2d, 0x35, 0x3b),
            hex(0x40, 0x55, 0x42),
            hex(0x66, 0x83, 0x5e),
            hex(0x86, 0xa1, 0x6f),
            hex(0xa7, 0xc0, 0x80),
        ],
    }
}

pub fn github_dark() -> Theme {
    Theme {
        bg: hex(0x0d, 0x11, 0x17),
        bg_subtle: hex(0x16, 0x1b, 0x22),
        text: hex(0xc9, 0xd1, 0xd9),
        panel_border: hex(0x30, 0x36, 0x3d),
        panel_title: hex(0x58, 0xa6, 0xff),
        status_ok: hex(0x3f, 0xb9, 0x50),
        status_warn: hex(0xd2, 0x99, 0x22),
        status_error: hex(0xf8, 0x51, 0x49),
        text_dim: hex(0x6e, 0x76, 0x81),
        text_secondary: hex(0x8b, 0x94, 0x9e),
        accent_today: hex(0xe3, 0xb3, 0x41),
        accent_event: hex(0x39, 0xc5, 0xcf),
        palette_series: vec![
            hex(0xf8, 0x51, 0x49),
            hex(0x58, 0xa6, 0xff),
            hex(0x56, 0xd3, 0x64),
            hex(0xe3, 0xb3, 0x41),
            hex(0xbc, 0x8c, 0xff),
            hex(0x39, 0xc5, 0xcf),
            hex(0xff, 0x9d, 0x5c),
            hex(0x79, 0xc0, 0xff),
            hex(0xf7, 0x78, 0xba),
            hex(0xc9, 0xd1, 0xd9),
        ],
        palette_heatmap: vec![
            hex(0x0d, 0x11, 0x17),
            hex(0x0e, 0x44, 0x29),
            hex(0x00, 0x6d, 0x32),
            hex(0x26, 0xa6, 0x41),
            hex(0x39, 0xd3, 0x53),
        ],
    }
}

pub fn github_light() -> Theme {
    Theme {
        bg: hex(0xff, 0xff, 0xff),
        bg_subtle: hex(0xf6, 0xf8, 0xfa),
        text: hex(0x1f, 0x23, 0x28),
        panel_border: hex(0xd0, 0xd7, 0xde),
        panel_title: hex(0x09, 0x69, 0xda),
        status_ok: hex(0x1a, 0x7f, 0x37),
        status_warn: hex(0x9a, 0x67, 0x00),
        status_error: hex(0xcf, 0x22, 0x2e),
        text_dim: hex(0x8c, 0x95, 0x9f),
        text_secondary: hex(0x57, 0x60, 0x6a),
        accent_today: hex(0xbf, 0x87, 0x00),
        accent_event: hex(0x1b, 0x7c, 0x83),
        palette_series: vec![
            hex(0xcf, 0x22, 0x2e),
            hex(0x09, 0x69, 0xda),
            hex(0x1a, 0x7f, 0x37),
            hex(0x9a, 0x67, 0x00),
            hex(0x82, 0x50, 0xdf),
            hex(0x1b, 0x7c, 0x83),
            hex(0xbc, 0x49, 0x00),
            hex(0x05, 0x50, 0xae),
            hex(0xbf, 0x39, 0x89),
            hex(0x1f, 0x23, 0x28),
        ],
        palette_heatmap: vec![
            hex(0xeb, 0xed, 0xf0),
            hex(0x9b, 0xe9, 0xa8),
            hex(0x40, 0xc4, 0x63),
            hex(0x30, 0xa1, 0x4e),
            hex(0x21, 0x6e, 0x39),
        ],
    }
}

pub fn gruvbox_dark() -> Theme {
    Theme {
        bg: hex(0x28, 0x28, 0x28),
        bg_subtle: hex(0x3c, 0x38, 0x36),
        text: hex(0xeb, 0xdb, 0xb2),
        panel_border: hex(0x7c, 0x6f, 0x64),
        panel_title: hex(0xfa, 0xbd, 0x2f),
        status_ok: hex(0xb8, 0xbb, 0x26),
        status_warn: hex(0xfa, 0xbd, 0x2f),
        status_error: hex(0xfb, 0x49, 0x34),
        text_dim: hex(0x66, 0x5c, 0x54),
        text_secondary: hex(0xa8, 0x99, 0x84),
        accent_today: hex(0xfa, 0xbd, 0x2f),
        accent_event: hex(0x83, 0xa5, 0x98),
        palette_series: vec![
            hex(0xfb, 0x49, 0x34),
            hex(0x83, 0xa5, 0x98),
            hex(0xb8, 0xbb, 0x26),
            hex(0xfa, 0xbd, 0x2f),
            hex(0xd3, 0x86, 0x9b),
            hex(0x8e, 0xc0, 0x7c),
            hex(0xfe, 0x80, 0x19),
            hex(0x45, 0x85, 0x88),
            hex(0xb1, 0x62, 0x86),
            hex(0xeb, 0xdb, 0xb2),
        ],
        palette_heatmap: vec![
            hex(0x28, 0x28, 0x28),
            hex(0x3c, 0x38, 0x36),
            hex(0x68, 0x9d, 0x6a),
            hex(0x98, 0x97, 0x1a),
            hex(0xb8, 0xbb, 0x26),
        ],
    }
}

pub fn gruvbox_light() -> Theme {
    Theme {
        bg: hex(0xfb, 0xf1, 0xc7),
        bg_subtle: hex(0xeb, 0xdb, 0xb2),
        text: hex(0x3c, 0x38, 0x36),
        panel_border: hex(0xa8, 0x99, 0x84),
        panel_title: hex(0xb5, 0x76, 0x14),
        status_ok: hex(0x79, 0x74, 0x0e),
        status_warn: hex(0xb5, 0x76, 0x14),
        status_error: hex(0x9d, 0x00, 0x06),
        text_dim: hex(0x92, 0x83, 0x74),
        text_secondary: hex(0x50, 0x49, 0x45),
        accent_today: hex(0xb5, 0x76, 0x14),
        accent_event: hex(0x07, 0x66, 0x78),
        palette_series: vec![
            hex(0x9d, 0x00, 0x06),
            hex(0x07, 0x66, 0x78),
            hex(0x79, 0x74, 0x0e),
            hex(0xb5, 0x76, 0x14),
            hex(0x8f, 0x3f, 0x71),
            hex(0x42, 0x7b, 0x58),
            hex(0xaf, 0x3a, 0x03),
            hex(0x45, 0x85, 0x88),
            hex(0xb1, 0x62, 0x86),
            hex(0x3c, 0x38, 0x36),
        ],
        palette_heatmap: vec![
            hex(0xfb, 0xf1, 0xc7),
            hex(0xd5, 0xc4, 0xa1),
            hex(0xa8, 0xb1, 0x55),
            hex(0x8b, 0x99, 0x2f),
            hex(0x79, 0x74, 0x0e),
        ],
    }
}

pub fn kanagawa() -> Theme {
    Theme {
        bg: hex(0x1f, 0x1f, 0x28),
        bg_subtle: hex(0x2a, 0x2a, 0x37),
        text: hex(0xdc, 0xd7, 0xba),
        panel_border: hex(0x54, 0x54, 0x6d),
        panel_title: hex(0x7e, 0x9c, 0xd8),
        status_ok: hex(0x76, 0x94, 0x6a),
        status_warn: hex(0xe6, 0xc3, 0x84),
        status_error: hex(0xc3, 0x40, 0x43),
        text_dim: hex(0x54, 0x54, 0x6d),
        text_secondary: hex(0xc8, 0xc0, 0x93),
        accent_today: hex(0xff, 0xa0, 0x66),
        accent_event: hex(0x7f, 0xb4, 0xca),
        palette_series: vec![
            hex(0xc3, 0x40, 0x43),
            hex(0x7e, 0x9c, 0xd8),
            hex(0x76, 0x94, 0x6a),
            hex(0xe6, 0xc3, 0x84),
            hex(0x95, 0x7f, 0xb8),
            hex(0x7f, 0xb4, 0xca),
            hex(0xff, 0xa0, 0x66),
            hex(0x6a, 0x95, 0x89),
            hex(0xd2, 0x7e, 0x99),
            hex(0xdc, 0xd7, 0xba),
        ],
        palette_heatmap: vec![
            hex(0x1f, 0x1f, 0x28),
            hex(0x2b, 0x3d, 0x36),
            hex(0x4c, 0x6b, 0x4f),
            hex(0x65, 0x80, 0x5d),
            hex(0x76, 0x94, 0x6a),
        ],
    }
}

pub fn material_palenight() -> Theme {
    Theme {
        bg: hex(0x29, 0x2d, 0x3e),
        bg_subtle: hex(0x34, 0x32, 0x4a),
        text: hex(0xa6, 0xac, 0xcd),
        panel_border: hex(0x44, 0x42, 0x67),
        panel_title: hex(0x82, 0xaa, 0xff),
        status_ok: hex(0xc3, 0xe8, 0x8d),
        status_warn: hex(0xff, 0xcb, 0x6b),
        status_error: hex(0xf0, 0x71, 0x78),
        text_dim: hex(0x67, 0x6e, 0x95),
        text_secondary: hex(0xb2, 0xcc, 0xd6),
        accent_today: hex(0xff, 0xcb, 0x6b),
        accent_event: hex(0x89, 0xdd, 0xff),
        palette_series: vec![
            hex(0xf0, 0x71, 0x78),
            hex(0x82, 0xaa, 0xff),
            hex(0xc3, 0xe8, 0x8d),
            hex(0xff, 0xcb, 0x6b),
            hex(0xc7, 0x92, 0xea),
            hex(0x89, 0xdd, 0xff),
            hex(0xf7, 0x8c, 0x6c),
            hex(0xb2, 0xcc, 0xd6),
            hex(0xff, 0x55, 0x70),
            hex(0xa6, 0xac, 0xcd),
        ],
        palette_heatmap: vec![
            hex(0x29, 0x2d, 0x3e),
            hex(0x44, 0x6c, 0x4d),
            hex(0x70, 0x9c, 0x66),
            hex(0x99, 0xc1, 0x76),
            hex(0xc3, 0xe8, 0x8d),
        ],
    }
}

pub fn monokai() -> Theme {
    Theme {
        bg: hex(0x27, 0x28, 0x22),
        bg_subtle: hex(0x3e, 0x3d, 0x32),
        text: hex(0xf8, 0xf8, 0xf2),
        panel_border: hex(0x75, 0x71, 0x5e),
        panel_title: hex(0xf9, 0x26, 0x72),
        status_ok: hex(0xa6, 0xe2, 0x2e),
        status_warn: hex(0xe6, 0xdb, 0x74),
        status_error: hex(0xf9, 0x26, 0x72),
        text_dim: hex(0x75, 0x71, 0x5e),
        text_secondary: hex(0xcf, 0xcf, 0xc2),
        accent_today: hex(0xfd, 0x97, 0x1f),
        accent_event: hex(0x66, 0xd9, 0xef),
        palette_series: vec![
            hex(0xf9, 0x26, 0x72),
            hex(0x66, 0xd9, 0xef),
            hex(0xa6, 0xe2, 0x2e),
            hex(0xe6, 0xdb, 0x74),
            hex(0xae, 0x81, 0xff),
            hex(0xfd, 0x97, 0x1f),
            hex(0xff, 0x6e, 0xa9),
            hex(0x4d, 0xc7, 0xea),
            hex(0xc6, 0xa1, 0xff),
            hex(0xf8, 0xf8, 0xf2),
        ],
        palette_heatmap: vec![
            hex(0x27, 0x28, 0x22),
            hex(0x4d, 0x6e, 0x21),
            hex(0x71, 0x9b, 0x25),
            hex(0x8c, 0xbf, 0x29),
            hex(0xa6, 0xe2, 0x2e),
        ],
    }
}

pub fn night_owl() -> Theme {
    Theme {
        bg: hex(0x01, 0x16, 0x27),
        bg_subtle: hex(0x1d, 0x3b, 0x53),
        text: hex(0xd6, 0xde, 0xeb),
        panel_border: hex(0x5f, 0x7e, 0x97),
        panel_title: hex(0x82, 0xaa, 0xff),
        status_ok: hex(0xad, 0xdb, 0x67),
        status_warn: hex(0xec, 0xc4, 0x8d),
        status_error: hex(0xef, 0x53, 0x50),
        text_dim: hex(0x63, 0x77, 0x77),
        text_secondary: hex(0xb8, 0xc0, 0xd0),
        accent_today: hex(0xec, 0xc4, 0x8d),
        accent_event: hex(0x7f, 0xdb, 0xca),
        palette_series: vec![
            hex(0xef, 0x53, 0x50),
            hex(0x82, 0xaa, 0xff),
            hex(0xad, 0xdb, 0x67),
            hex(0xec, 0xc4, 0x8d),
            hex(0xc7, 0x92, 0xea),
            hex(0x7f, 0xdb, 0xca),
            hex(0xf7, 0x8c, 0x6c),
            hex(0x21, 0xc7, 0xa8),
            hex(0xff, 0xeb, 0x95),
            hex(0xd6, 0xde, 0xeb),
        ],
        palette_heatmap: vec![
            hex(0x01, 0x16, 0x27),
            hex(0x1d, 0x55, 0x47),
            hex(0x39, 0x82, 0x52),
            hex(0x73, 0xb1, 0x5b),
            hex(0xad, 0xdb, 0x67),
        ],
    }
}

pub fn nord() -> Theme {
    Theme {
        bg: hex(0x2e, 0x34, 0x40),
        bg_subtle: hex(0x3b, 0x42, 0x52),
        text: hex(0xd8, 0xde, 0xe9),
        panel_border: hex(0x4c, 0x56, 0x6a),
        panel_title: hex(0x88, 0xc0, 0xd0),
        status_ok: hex(0xa3, 0xbe, 0x8c),
        status_warn: hex(0xeb, 0xcb, 0x8b),
        status_error: hex(0xbf, 0x61, 0x6a),
        text_dim: hex(0x43, 0x4c, 0x5e),
        text_secondary: hex(0xe5, 0xe9, 0xf0),
        accent_today: hex(0xeb, 0xcb, 0x8b),
        accent_event: hex(0x8f, 0xbc, 0xbb),
        palette_series: vec![
            hex(0x88, 0xc0, 0xd0),
            hex(0xa3, 0xbe, 0x8c),
            hex(0xeb, 0xcb, 0x8b),
            hex(0xbf, 0x61, 0x6a),
            hex(0xb4, 0x8e, 0xad),
            hex(0x8f, 0xbc, 0xbb),
            hex(0xd0, 0x87, 0x70),
            hex(0x81, 0xa1, 0xc1),
            hex(0x5e, 0x81, 0xac),
            hex(0xe5, 0xe9, 0xf0),
        ],
        palette_heatmap: vec![
            hex(0x3b, 0x42, 0x52),
            hex(0x4c, 0x56, 0x6a),
            hex(0x5e, 0x81, 0xac),
            hex(0x81, 0xa1, 0xc1),
            hex(0xa3, 0xbe, 0x8c),
        ],
    }
}

pub fn one_dark() -> Theme {
    Theme {
        bg: hex(0x28, 0x2c, 0x34),
        bg_subtle: hex(0x21, 0x25, 0x2b),
        text: hex(0xab, 0xb2, 0xbf),
        panel_border: hex(0x3b, 0x40, 0x48),
        panel_title: hex(0x61, 0xaf, 0xef),
        status_ok: hex(0x98, 0xc3, 0x79),
        status_warn: hex(0xe5, 0xc0, 0x7b),
        status_error: hex(0xe0, 0x6c, 0x75),
        text_dim: hex(0x5c, 0x63, 0x70),
        text_secondary: hex(0xab, 0xb2, 0xbf),
        accent_today: hex(0xe5, 0xc0, 0x7b),
        accent_event: hex(0x56, 0xb6, 0xc2),
        palette_series: vec![
            hex(0xe0, 0x6c, 0x75),
            hex(0x61, 0xaf, 0xef),
            hex(0x98, 0xc3, 0x79),
            hex(0xe5, 0xc0, 0x7b),
            hex(0xc6, 0x78, 0xdd),
            hex(0x56, 0xb6, 0xc2),
            hex(0xd1, 0x9a, 0x66),
            hex(0x4f, 0xa0, 0xd6),
            hex(0xbe, 0x5a, 0x66),
            hex(0xab, 0xb2, 0xbf),
        ],
        palette_heatmap: vec![
            hex(0x28, 0x2c, 0x34),
            hex(0x40, 0x6e, 0x3a),
            hex(0x5c, 0x91, 0x49),
            hex(0x7d, 0xab, 0x60),
            hex(0x98, 0xc3, 0x79),
        ],
    }
}

pub fn rose_pine() -> Theme {
    Theme {
        bg: hex(0x19, 0x17, 0x24),
        bg_subtle: hex(0x1f, 0x1d, 0x2e),
        text: hex(0xe0, 0xde, 0xf4),
        panel_border: hex(0x26, 0x23, 0x3a),
        panel_title: hex(0xc4, 0xa7, 0xe7),
        status_ok: hex(0x31, 0x74, 0x8f),
        status_warn: hex(0xf6, 0xc1, 0x77),
        status_error: hex(0xeb, 0x6f, 0x92),
        text_dim: hex(0x6e, 0x6a, 0x86),
        text_secondary: hex(0x90, 0x8c, 0xaa),
        accent_today: hex(0xf6, 0xc1, 0x77),
        accent_event: hex(0x9c, 0xcf, 0xd8),
        palette_series: vec![
            hex(0xeb, 0x6f, 0x92),
            hex(0x9c, 0xcf, 0xd8),
            hex(0x31, 0x74, 0x8f),
            hex(0xf6, 0xc1, 0x77),
            hex(0xc4, 0xa7, 0xe7),
            hex(0xeb, 0xbc, 0xba),
            hex(0xea, 0x9a, 0x97),
            hex(0x52, 0x9b, 0xb5),
            hex(0xb4, 0x91, 0xc8),
            hex(0xe0, 0xde, 0xf4),
        ],
        palette_heatmap: vec![
            hex(0x19, 0x17, 0x24),
            hex(0x2a, 0x42, 0x4f),
            hex(0x31, 0x74, 0x8f),
            hex(0x68, 0xa1, 0xa9),
            hex(0x9c, 0xcf, 0xd8),
        ],
    }
}

pub fn rose_pine_dawn() -> Theme {
    Theme {
        bg: hex(0xfa, 0xf4, 0xed),
        bg_subtle: hex(0xff, 0xfa, 0xf3),
        text: hex(0x57, 0x52, 0x79),
        panel_border: hex(0xdf, 0xd9, 0xc8),
        panel_title: hex(0x90, 0x7a, 0xa9),
        status_ok: hex(0x28, 0x69, 0x83),
        status_warn: hex(0xea, 0x9d, 0x34),
        status_error: hex(0xb4, 0x63, 0x7a),
        text_dim: hex(0x9c, 0x91, 0x88),
        text_secondary: hex(0x79, 0x75, 0x93),
        accent_today: hex(0xea, 0x9d, 0x34),
        accent_event: hex(0x56, 0x94, 0x9f),
        palette_series: vec![
            hex(0xb4, 0x63, 0x7a),
            hex(0x56, 0x94, 0x9f),
            hex(0x28, 0x69, 0x83),
            hex(0xea, 0x9d, 0x34),
            hex(0x90, 0x7a, 0xa9),
            hex(0xd7, 0x82, 0x7e),
            hex(0xa8, 0x52, 0x6c),
            hex(0x35, 0x7c, 0x91),
            hex(0xb1, 0x77, 0x9e),
            hex(0x57, 0x52, 0x79),
        ],
        palette_heatmap: vec![
            hex(0xfa, 0xf4, 0xed),
            hex(0xc6, 0xd6, 0xd6),
            hex(0x7c, 0xa9, 0xb2),
            hex(0x4f, 0x86, 0x96),
            hex(0x28, 0x69, 0x83),
        ],
    }
}

pub fn rose_pine_moon() -> Theme {
    Theme {
        bg: hex(0x23, 0x21, 0x36),
        bg_subtle: hex(0x2a, 0x27, 0x3f),
        text: hex(0xe0, 0xde, 0xf4),
        panel_border: hex(0x39, 0x35, 0x52),
        panel_title: hex(0xc4, 0xa7, 0xe7),
        status_ok: hex(0x3e, 0x8f, 0xb0),
        status_warn: hex(0xf6, 0xc1, 0x77),
        status_error: hex(0xeb, 0x6f, 0x92),
        text_dim: hex(0x6e, 0x6a, 0x86),
        text_secondary: hex(0x90, 0x8c, 0xaa),
        accent_today: hex(0xf6, 0xc1, 0x77),
        accent_event: hex(0x9c, 0xcf, 0xd8),
        palette_series: vec![
            hex(0xeb, 0x6f, 0x92),
            hex(0x9c, 0xcf, 0xd8),
            hex(0x3e, 0x8f, 0xb0),
            hex(0xf6, 0xc1, 0x77),
            hex(0xc4, 0xa7, 0xe7),
            hex(0xea, 0x9a, 0x97),
            hex(0xea, 0x9a, 0x97),
            hex(0x52, 0x9b, 0xb5),
            hex(0xb4, 0x91, 0xc8),
            hex(0xe0, 0xde, 0xf4),
        ],
        palette_heatmap: vec![
            hex(0x23, 0x21, 0x36),
            hex(0x2c, 0x4e, 0x5b),
            hex(0x3e, 0x8f, 0xb0),
            hex(0x6f, 0xb1, 0xc4),
            hex(0x9c, 0xcf, 0xd8),
        ],
    }
}

pub fn solarized_dark() -> Theme {
    Theme {
        bg: hex(0x00, 0x2b, 0x36),
        bg_subtle: hex(0x07, 0x36, 0x42),
        text: hex(0x83, 0x94, 0x96),
        panel_border: hex(0x58, 0x6e, 0x75),
        panel_title: hex(0x26, 0x8b, 0xd2),
        status_ok: hex(0x85, 0x99, 0x00),
        status_warn: hex(0xb5, 0x89, 0x00),
        status_error: hex(0xdc, 0x32, 0x2f),
        text_dim: hex(0x58, 0x6e, 0x75),
        text_secondary: hex(0x93, 0xa1, 0xa1),
        accent_today: hex(0xb5, 0x89, 0x00),
        accent_event: hex(0x2a, 0xa1, 0x98),
        palette_series: vec![
            hex(0xdc, 0x32, 0x2f),
            hex(0x26, 0x8b, 0xd2),
            hex(0x85, 0x99, 0x00),
            hex(0xb5, 0x89, 0x00),
            hex(0x6c, 0x71, 0xc4),
            hex(0x2a, 0xa1, 0x98),
            hex(0xcb, 0x4b, 0x16),
            hex(0xd3, 0x36, 0x82),
            hex(0x83, 0x94, 0x96),
            hex(0x93, 0xa1, 0xa1),
        ],
        palette_heatmap: vec![
            hex(0x00, 0x2b, 0x36),
            hex(0x07, 0x4e, 0x42),
            hex(0x40, 0x73, 0x21),
            hex(0x68, 0x86, 0x10),
            hex(0x85, 0x99, 0x00),
        ],
    }
}

pub fn solarized_light() -> Theme {
    Theme {
        bg: hex(0xfd, 0xf6, 0xe3),
        bg_subtle: hex(0xee, 0xe8, 0xd5),
        text: hex(0x65, 0x7b, 0x83),
        panel_border: hex(0x93, 0xa1, 0xa1),
        panel_title: hex(0x26, 0x8b, 0xd2),
        status_ok: hex(0x85, 0x99, 0x00),
        status_warn: hex(0xb5, 0x89, 0x00),
        status_error: hex(0xdc, 0x32, 0x2f),
        text_dim: hex(0x93, 0xa1, 0xa1),
        text_secondary: hex(0x58, 0x6e, 0x75),
        accent_today: hex(0xb5, 0x89, 0x00),
        accent_event: hex(0x2a, 0xa1, 0x98),
        palette_series: vec![
            hex(0xdc, 0x32, 0x2f),
            hex(0x26, 0x8b, 0xd2),
            hex(0x85, 0x99, 0x00),
            hex(0xb5, 0x89, 0x00),
            hex(0x6c, 0x71, 0xc4),
            hex(0x2a, 0xa1, 0x98),
            hex(0xcb, 0x4b, 0x16),
            hex(0xd3, 0x36, 0x82),
            hex(0x65, 0x7b, 0x83),
            hex(0x58, 0x6e, 0x75),
        ],
        palette_heatmap: vec![
            hex(0xfd, 0xf6, 0xe3),
            hex(0xd9, 0xd6, 0x9e),
            hex(0xa9, 0xb0, 0x4a),
            hex(0x90, 0xa0, 0x1c),
            hex(0x85, 0x99, 0x00),
        ],
    }
}

pub fn synthwave_84() -> Theme {
    Theme {
        bg: hex(0x2a, 0x21, 0x39),
        bg_subtle: hex(0x34, 0x29, 0x4f),
        text: hex(0xf8, 0xf8, 0xf2),
        panel_border: hex(0x49, 0x54, 0x95),
        panel_title: hex(0xff, 0x7e, 0xdb),
        status_ok: hex(0x72, 0xf1, 0xb8),
        status_warn: hex(0xfe, 0xde, 0x5d),
        status_error: hex(0xfe, 0x44, 0x50),
        text_dim: hex(0x4f, 0x47, 0x73),
        text_secondary: hex(0xb8, 0x93, 0xce),
        accent_today: hex(0xfe, 0xde, 0x5d),
        accent_event: hex(0x03, 0xed, 0xf9),
        palette_series: vec![
            hex(0xff, 0x7e, 0xdb),
            hex(0x03, 0xed, 0xf9),
            hex(0x72, 0xf1, 0xb8),
            hex(0xfe, 0xde, 0x5d),
            hex(0xb3, 0x81, 0xc5),
            hex(0xf9, 0x7e, 0x72),
            hex(0xfe, 0x44, 0x50),
            hex(0x36, 0xf9, 0xf6),
            hex(0xff, 0xb1, 0xe7),
            hex(0xf8, 0xf8, 0xf2),
        ],
        palette_heatmap: vec![
            hex(0x2a, 0x21, 0x39),
            hex(0x4a, 0x6c, 0x6c),
            hex(0x55, 0xa3, 0x99),
            hex(0x66, 0xd4, 0xa9),
            hex(0x72, 0xf1, 0xb8),
        ],
    }
}

pub fn tokyo_night() -> Theme {
    Theme {
        bg: hex(0x1a, 0x1b, 0x26),
        bg_subtle: hex(0x24, 0x28, 0x3b),
        text: hex(0xc0, 0xca, 0xf5),
        panel_border: hex(0x41, 0x48, 0x68),
        panel_title: hex(0x7a, 0xa2, 0xf7),
        status_ok: hex(0x9e, 0xce, 0x6a),
        status_warn: hex(0xe0, 0xaf, 0x68),
        status_error: hex(0xf7, 0x76, 0x8e),
        text_dim: hex(0x56, 0x5f, 0x89),
        text_secondary: hex(0x9a, 0xa5, 0xce),
        accent_today: hex(0xe0, 0xaf, 0x68),
        accent_event: hex(0x7d, 0xcf, 0xff),
        palette_series: vec![
            hex(0xf7, 0x76, 0x8e),
            hex(0x7a, 0xa2, 0xf7),
            hex(0x9e, 0xce, 0x6a),
            hex(0xe0, 0xaf, 0x68),
            hex(0xbb, 0x9a, 0xf7),
            hex(0x7d, 0xcf, 0xff),
            hex(0xff, 0x9e, 0x64),
            hex(0x2a, 0xc3, 0xde),
            hex(0x73, 0xda, 0xca),
            hex(0xc0, 0xca, 0xf5),
        ],
        palette_heatmap: vec![
            hex(0x1f, 0x23, 0x35),
            hex(0x3d, 0x5a, 0x3d),
            hex(0x55, 0x7a, 0x4a),
            hex(0x7a, 0xa6, 0x54),
            hex(0x9e, 0xce, 0x6a),
        ],
    }
}

pub fn tokyo_night_storm() -> Theme {
    Theme {
        bg: hex(0x24, 0x28, 0x3b),
        bg_subtle: hex(0x1f, 0x23, 0x35),
        text: hex(0xc0, 0xca, 0xf5),
        panel_border: hex(0x41, 0x48, 0x68),
        panel_title: hex(0x7a, 0xa2, 0xf7),
        status_ok: hex(0x9e, 0xce, 0x6a),
        status_warn: hex(0xe0, 0xaf, 0x68),
        status_error: hex(0xf7, 0x76, 0x8e),
        text_dim: hex(0x56, 0x5f, 0x89),
        text_secondary: hex(0x9a, 0xa5, 0xce),
        accent_today: hex(0xe0, 0xaf, 0x68),
        accent_event: hex(0x7d, 0xcf, 0xff),
        palette_series: vec![
            hex(0xf7, 0x76, 0x8e),
            hex(0x7a, 0xa2, 0xf7),
            hex(0x9e, 0xce, 0x6a),
            hex(0xe0, 0xaf, 0x68),
            hex(0xbb, 0x9a, 0xf7),
            hex(0x7d, 0xcf, 0xff),
            hex(0xff, 0x9e, 0x64),
            hex(0x2a, 0xc3, 0xde),
            hex(0x73, 0xda, 0xca),
            hex(0xc0, 0xca, 0xf5),
        ],
        palette_heatmap: vec![
            hex(0x24, 0x28, 0x3b),
            hex(0x3d, 0x5a, 0x3d),
            hex(0x55, 0x7a, 0x4a),
            hex(0x7a, 0xa6, 0x54),
            hex(0x9e, 0xce, 0x6a),
        ],
    }
}

const fn hex(r: u8, g: u8, b: u8) -> Color {
    Color::Rgb(r, g, b)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn every_known_name_resolves() {
        // `KNOWN` is the source of truth consulted by error messages; if `by_name` can't
        // resolve a listed name, config validation would point users at a preset they can't
        // actually select.
        for name in KNOWN {
            assert!(
                by_name(name).is_some(),
                "preset {name} listed but not resolvable"
            );
        }
    }

    #[test]
    fn unknown_name_returns_none() {
        assert!(by_name("doesnotexist").is_none());
    }

    #[test]
    fn default_resolves_to_the_signature_palette() {
        // The `"default"` preset keyword must match the implicit default (no `[theme]
        // preset = "..."` line) so preset-switching UIs can cycle through every
        // option in `KNOWN` without special-casing the built-in.
        let explicit = by_name("default").unwrap();
        let implicit = Theme::default();
        assert_eq!(explicit.bg, implicit.bg);
        assert_eq!(explicit.panel_title, implicit.panel_title);
    }

    #[test]
    fn every_preset_populates_all_palette_arrays() {
        // Guard against a future preset accidentally shipping an empty series / ramp, which
        // would silently fall back to `Color::Cyan` / the default ramp at render time.
        for name in KNOWN {
            let t = by_name(name).unwrap();
            assert!(!t.palette_series.is_empty(), "{name}: series is empty");
            assert!(
                !t.palette_heatmap.is_empty(),
                "{name}: heatmap_ramp is empty"
            );
        }
    }

    #[test]
    fn known_list_is_sorted_and_unique() {
        // Alphabetical KNOWN keeps `--theme` help and error messages predictable; duplicate
        // entries would shadow `by_name` arms silently.
        for window in KNOWN.windows(2) {
            assert!(window[0] < window[1], "KNOWN not sorted: {window:?}");
        }
    }
}
