| 273 |
273 |
|
let mut derived: Vec<(String, Rgb)> = Vec::new();
|
| 274 |
274 |
|
if let Some(action) = get(&intents, "action") {
|
| 275 |
275 |
|
derived.push(("action-hover".into(), lighten(action, 0.05)));
|
| 276 |
|
- |
derived.push(("action-active".into(), darken(action, 0.05)));
|
| 277 |
276 |
|
derived.push(("content-on-action".into(), readable_on(action)));
|
| 278 |
277 |
|
derived.push(("focus-ring".into(), action));
|
| 279 |
|
- |
if let Some(page) = get(&intents, "surface-page") {
|
| 280 |
|
- |
derived.push(("selection".into(), mix(page, action, 0.2)));
|
| 281 |
|
- |
}
|
| 282 |
278 |
|
}
|
| 283 |
279 |
|
if let Some(page) = get(&intents, "surface-page") {
|
| 284 |
|
- |
if let Some(overlay) = get(&intents, "surface-overlay") {
|
| 285 |
|
- |
derived.push(("row-stripe".into(), mix(page, overlay, 0.5)));
|
| 286 |
|
- |
}
|
| 287 |
|
- |
for status in ["danger", "success", "warning", "info"] {
|
| 288 |
|
- |
if let Some(c) = get(&intents, status) {
|
| 289 |
|
- |
derived.push((format!("{status}-surface"), mix(page, c, 0.15)));
|
| 290 |
|
- |
}
|
| 291 |
|
- |
}
|
|
280 |
+ |
// Modal scrim: a near-black tone carrying a faint hint of the theme's
|
|
281 |
+ |
// hue, at 50% alpha. Anchored very dark (OKLab L=0.08) so it dims the
|
|
282 |
+ |
// page on light *and* dark themes. Emitted as rgba (not a flat hex), so
|
|
283 |
+ |
// it is inserted directly rather than through the hex loop below.
|
|
284 |
+ |
let mut o = page.to_oklab();
|
|
285 |
+ |
o.l = 0.08;
|
|
286 |
+ |
let s = Rgb::from_oklab(o);
|
|
287 |
+ |
intents.insert("overlay".into(), format!("rgba({}, {}, {}, 0.5)", s.r, s.g, s.b));
|
| 292 |
288 |
|
}
|
| 293 |
289 |
|
if let Some(sunken) = get(&intents, "surface-sunken") {
|
| 294 |
290 |
|
derived.push(("hover-surface".into(), sunken));
|
| 786 |
782 |
|
let t = resolve(&theme);
|
| 787 |
783 |
|
let action = Rgb::from_hex("#81a1c1").unwrap();
|
| 788 |
784 |
|
let page = Rgb::from_hex("#2e3440").unwrap();
|
|
785 |
+ |
let _ = page;
|
| 789 |
786 |
|
assert_eq!(t.hex("action-hover").unwrap(), lighten(action, 0.05).to_hex());
|
| 790 |
|
- |
assert_eq!(t.hex("action-active").unwrap(), darken(action, 0.05).to_hex());
|
| 791 |
787 |
|
assert_eq!(t.hex("content-on-action").unwrap(), readable_on(action).to_hex());
|
| 792 |
788 |
|
assert_eq!(t.hex("focus-ring"), Some("#81a1c1"));
|
| 793 |
|
- |
assert_eq!(t.hex("selection").unwrap(), mix(page, action, 0.2).to_hex());
|
| 794 |
789 |
|
assert_eq!(t.hex("hover-surface"), Some("#434c5e")); // = surface.sunken
|
| 795 |
|
- |
assert_eq!(t.hex("danger-surface").unwrap(),
|
| 796 |
|
- |
mix(page, Rgb::from_hex("#bf616a").unwrap(), 0.15).to_hex());
|
|
790 |
+ |
// Pruned by the usage audit (0 consumers): action-active, the *-surface
|
|
791 |
+ |
// tints, selection, row-stripe. Apps that need them derive inline via
|
|
792 |
+ |
// the shared mix().
|
|
793 |
+ |
assert!(t.hex("action-active").is_none());
|
|
794 |
+ |
assert!(t.hex("danger-surface").is_none());
|
|
795 |
+ |
assert!(t.hex("selection").is_none());
|
|
796 |
+ |
assert!(t.hex("row-stripe").is_none());
|
|
797 |
+ |
}
|
|
798 |
+ |
|
|
799 |
+ |
#[test]
|
|
800 |
+ |
fn resolve_overlay_is_dark_translucent_scrim() {
|
|
801 |
+ |
let theme = parse_theme_str("nord", nord_toml(), false).unwrap();
|
|
802 |
+ |
let t = resolve(&theme);
|
|
803 |
+ |
let overlay = t.hex("overlay").unwrap();
|
|
804 |
+ |
assert!(overlay.starts_with("rgba("), "overlay is translucent: {overlay}");
|
|
805 |
+ |
assert!(overlay.ends_with(", 0.5)"));
|
|
806 |
+ |
// The scrim tone is anchored very dark regardless of theme.
|
|
807 |
+ |
let inner = overlay.trim_start_matches("rgba(").trim_end_matches(", 0.5)");
|
|
808 |
+ |
let parts: Vec<u8> = inner.split(", ").map(|p| p.parse().unwrap()).collect();
|
|
809 |
+ |
let scrim = Rgb { r: parts[0], g: parts[1], b: parts[2] };
|
|
810 |
+ |
assert!(scrim.to_oklab().l < 0.2, "scrim must be near-black");
|
| 797 |
811 |
|
}
|
| 798 |
812 |
|
|
| 799 |
813 |
|
#[test]
|
| 829 |
843 |
|
assert!(css.starts_with(":root {\n"));
|
| 830 |
844 |
|
assert!(css.contains(" --surface-page: #2e3440;\n"));
|
| 831 |
845 |
|
assert!(css.contains(" --danger: #bf616a;\n"));
|
| 832 |
|
- |
assert!(css.contains(" --selection: "));
|
|
846 |
+ |
assert!(css.contains(" --action-hover: "));
|
| 833 |
847 |
|
assert!(css.trim_end().ends_with('}'));
|
| 834 |
848 |
|
}
|
| 835 |
849 |
|
|