fix(maestro): make TUI chrome contrast palette-controlled
This commit is contained in:
@@ -106,6 +106,10 @@ pub struct Palette {
|
||||
pub card: Surface,
|
||||
/// The surface the highlighted card swaps in.
|
||||
pub selection: Surface,
|
||||
/// Background for TUI-owned chrome outside cards. Fixed-RGB chrome must
|
||||
/// paint this background too; otherwise its contrast depends on the
|
||||
/// operator's terminal theme.
|
||||
pub chrome_bg: Color,
|
||||
/// Panel border while that panel holds focus.
|
||||
pub border_focused: Color,
|
||||
/// Panel border while it does not.
|
||||
@@ -148,8 +152,9 @@ impl Palette {
|
||||
awaiting: Color::Rgb(0xf2, 0xcc, 0x60),
|
||||
error: Color::Rgb(0xff, 0x94, 0x92),
|
||||
},
|
||||
chrome_bg: Color::Rgb(0x14, 0x16, 0x1b),
|
||||
border_focused: Color::Rgb(0x58, 0xa6, 0xff),
|
||||
border_unfocused: Color::Rgb(0x30, 0x36, 0x3d),
|
||||
border_unfocused: Color::Rgb(0x6b, 0x72, 0x80),
|
||||
focus_accent: Color::Rgb(0x58, 0xa6, 0xff),
|
||||
group_row: Color::Rgb(0x8f, 0xa3, 0xc8),
|
||||
mode_normal_bg: Color::Rgb(0x58, 0xa6, 0xff),
|
||||
@@ -172,15 +177,18 @@ impl Palette {
|
||||
/// Border style for a panel, by whether it holds focus.
|
||||
pub fn border_style(&self, focused: bool) -> Style {
|
||||
if focused {
|
||||
Style::default().fg(self.border_focused)
|
||||
Style::default().bg(self.chrome_bg).fg(self.border_focused)
|
||||
} else {
|
||||
Style::default().fg(self.border_unfocused)
|
||||
Style::default()
|
||||
.bg(self.chrome_bg)
|
||||
.fg(self.border_unfocused)
|
||||
}
|
||||
}
|
||||
|
||||
/// Style for a sidebar group heading.
|
||||
pub fn group_row_style(&self) -> Style {
|
||||
Style::default()
|
||||
.bg(self.chrome_bg)
|
||||
.fg(self.group_row)
|
||||
.add_modifier(Modifier::BOLD)
|
||||
}
|
||||
@@ -200,7 +208,7 @@ impl Palette {
|
||||
|
||||
/// Style for error text outside a card.
|
||||
pub fn error_style(&self) -> Style {
|
||||
Style::default().fg(self.error_text)
|
||||
Style::default().bg(self.chrome_bg).fg(self.error_text)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,10 +306,13 @@ mod tests {
|
||||
}
|
||||
|
||||
/// Other panels' roles are RGB too, so a preset swap moves all of them.
|
||||
/// Foregrounds are checked against the chrome background they are
|
||||
/// actually painted on; they must never rely on the terminal default.
|
||||
#[test]
|
||||
fn chrome_roles_are_rgb_values() {
|
||||
let p = active();
|
||||
for (name, color) in [
|
||||
("chrome_bg", p.chrome_bg),
|
||||
("border_focused", p.border_focused),
|
||||
("border_unfocused", p.border_unfocused),
|
||||
("focus_accent", p.focus_accent),
|
||||
@@ -325,6 +336,19 @@ mod tests {
|
||||
let ratio = contrast_ratio(fg, bg).unwrap();
|
||||
assert!(ratio >= 4.5, "mode {name} contrast {ratio:.2} is below 4.5");
|
||||
}
|
||||
for (name, fg, floor) in [
|
||||
("border_focused", p.border_focused, 3.0),
|
||||
("border_unfocused", p.border_unfocused, 3.0),
|
||||
("focus_accent", p.focus_accent, 3.0),
|
||||
("group_row", p.group_row, 4.5),
|
||||
("error_text", p.error_text, 4.5),
|
||||
] {
|
||||
let ratio = contrast_ratio(fg, p.chrome_bg).unwrap();
|
||||
assert!(
|
||||
ratio >= floor,
|
||||
"{name} contrast {ratio:.2} is below {floor} on chrome_bg"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user