fix(style): Z-Design V4 - El rojo es el estándar, boost para azul
Corrección de rumbo consensuada: - Colores brillantes (L > 0.2): 22% intensidad (estándar del rojo) - Colores oscuros (L <= 0.2): 35% intensidad (boost para azul/violeta) El objetivo es que todos los paneles tengan la vibrancia del rojo. El azul debe 'saltar' del negro tanto como lo hace el rojo.
This commit is contained in:
parent
797cca736c
commit
23204bdd0a
1 changed files with 49 additions and 35 deletions
|
|
@ -1373,27 +1373,32 @@ pub const DerivedPanelColors = struct {
|
|||
title_color: Color,
|
||||
};
|
||||
|
||||
/// Derive panel frame colors from a single base color using generic luminance formula.
|
||||
/// Derive panel frame colors from a single base color.
|
||||
///
|
||||
/// The derivation is purely mathematical and works for ANY color:
|
||||
/// - Luminance L = 0.2126*R + 0.7152*G + 0.0722*B
|
||||
/// - Blend factor inversely proportional to L
|
||||
/// Z-Design V4: "El rojo es el estándar"
|
||||
/// - Colores brillantes (L > 0.2, ej: rojo): 22% color visible (el estándar bueno)
|
||||
/// - Colores oscuros (L <= 0.2, ej: azul): 35% color visible (boost para compensar)
|
||||
///
|
||||
/// Example values:
|
||||
/// - Blue (L=0.07): blend ~19% → more blue visible in dark background
|
||||
/// - Red (L=0.21): blend ~18% → moderate visibility
|
||||
/// - Green (L=0.72): blend ~13% → less green (already bright)
|
||||
/// - Yellow (L=0.93): blend ~11% → minimal (very bright)
|
||||
/// El objetivo es que TODOS los paneles tengan la vibrancia del rojo.
|
||||
/// El azul debe "saltar" del negro tanto como lo hace el rojo.
|
||||
///
|
||||
/// Luminance L = 0.2126*R + 0.7152*G + 0.0722*B
|
||||
/// - Rojo puro: L ~= 0.21 (justo en el límite, usa estándar 22%)
|
||||
/// - Azul puro: L ~= 0.07 (muy bajo, usa boost 35%)
|
||||
/// - Verde puro: L ~= 0.72 (alto, usa estándar 22%)
|
||||
pub fn derivePanelFrameColors(base: Color) DerivedPanelColors {
|
||||
const L = base.perceptualLuminance();
|
||||
|
||||
// Generic formula: blend inversely proportional to luminance
|
||||
// Base blend: 10% (bright colors), Max blend: 20% (dark colors)
|
||||
const base_blend: f32 = 0.10;
|
||||
const max_blend: f32 = 0.20;
|
||||
const blend_factor = base_blend + (max_blend - base_blend) * (1.0 - L);
|
||||
// Z-Design V4: Threshold-based boost
|
||||
// El rojo (~22%) es el estándar de "buena vibrancia"
|
||||
// Colores oscuros como el azul necesitan más intensidad para verse igual
|
||||
const blend_factor: f32 = if (L > 0.2)
|
||||
0.22 // Estándar: colores brillantes (rojo, verde, amarillo)
|
||||
else
|
||||
0.35; // Boost: colores oscuros (azul, violeta)
|
||||
|
||||
// Convert to percentage for blendTowards (inverted: 100% = all black)
|
||||
// focus: full blend, unfocus: half blend
|
||||
const focus_pct: u8 = @intFromFloat((1.0 - blend_factor) * 100.0);
|
||||
const unfocus_pct: u8 = @intFromFloat((1.0 - blend_factor * 0.5) * 100.0);
|
||||
|
||||
|
|
@ -1408,35 +1413,44 @@ pub fn derivePanelFrameColors(base: Color) DerivedPanelColors {
|
|||
};
|
||||
}
|
||||
|
||||
test "derivePanelFrameColors blue" {
|
||||
const blue = Color.rgb(59, 130, 246); // laravel_blue
|
||||
test "derivePanelFrameColors blue gets boost" {
|
||||
// Pure blue has L ~= 0.07, which is < 0.2, so it gets 35% boost
|
||||
const blue = Color.rgb(0, 0, 255);
|
||||
const derived = derivePanelFrameColors(blue);
|
||||
|
||||
// Blue has low luminance, should get more visible background
|
||||
// L ~= 0.07 * 0.23 + 0.51 * 0.72 + 0.96 * 0.07 = 0.016 + 0.37 + 0.067 = 0.45
|
||||
// Actually for laravel_blue: L = 59/255*0.2126 + 130/255*0.7152 + 246/255*0.0722
|
||||
// = 0.049 + 0.365 + 0.070 = 0.484
|
||||
|
||||
// Border focus should be the original color
|
||||
try std.testing.expectEqual(blue.r, derived.border_focus.r);
|
||||
try std.testing.expectEqual(blue.g, derived.border_focus.g);
|
||||
try std.testing.expectEqual(blue.b, derived.border_focus.b);
|
||||
|
||||
// Focus bg should be darker than unfocus bg (more blend towards black)
|
||||
// Actually focus has MORE color (less blend to black)
|
||||
try std.testing.expect(derived.focus_bg.r >= derived.unfocus_bg.r);
|
||||
// Focus bg should have significant blue visible (35% boost)
|
||||
// 35% of 255 = ~89, blended with soft_black (17,17,20)
|
||||
try std.testing.expect(derived.focus_bg.b > 70); // Should be vibrant blue
|
||||
}
|
||||
|
||||
test "derivePanelFrameColors generic formula" {
|
||||
// Test that brighter colors get less visibility (lower blend)
|
||||
const dark_blue = Color.rgb(0, 0, 200); // L ~= 0.057
|
||||
const bright_yellow = Color.rgb(255, 255, 0); // L ~= 0.93
|
||||
test "derivePanelFrameColors red is standard" {
|
||||
// Red has L ~= 0.21, which is > 0.2, so it gets standard 22%
|
||||
const red = Color.rgb(255, 0, 0);
|
||||
const derived = derivePanelFrameColors(red);
|
||||
|
||||
const blue_derived = derivePanelFrameColors(dark_blue);
|
||||
const yellow_derived = derivePanelFrameColors(bright_yellow);
|
||||
|
||||
// Blue background should have more color visible (less black blend)
|
||||
// This means blue's focus_bg should be brighter/more colorful than yellow's relative to base
|
||||
// We check that the formula produces different results
|
||||
try std.testing.expect(blue_derived.focus_bg.b != yellow_derived.focus_bg.b);
|
||||
// Focus bg should have standard red visibility (22%)
|
||||
// 22% of 255 = ~56, blended with soft_black
|
||||
try std.testing.expect(derived.focus_bg.r > 40);
|
||||
try std.testing.expect(derived.focus_bg.r < 100); // Not too bright
|
||||
}
|
||||
|
||||
test "derivePanelFrameColors threshold behavior" {
|
||||
// Test that blue (L < 0.2) gets MORE visibility than red (L > 0.2)
|
||||
const blue = Color.rgb(0, 0, 255); // L ~= 0.07
|
||||
const red = Color.rgb(255, 0, 0); // L ~= 0.21
|
||||
|
||||
const blue_derived = derivePanelFrameColors(blue);
|
||||
const red_derived = derivePanelFrameColors(red);
|
||||
|
||||
// Blue gets 35% blend, red gets 22%
|
||||
// So blue's color channel should be proportionally MORE visible
|
||||
// Blue: 35% of 255 ~= 89
|
||||
// Red: 22% of 255 ~= 56
|
||||
// Blue should have higher relative intensity
|
||||
try std.testing.expect(blue_derived.focus_bg.b > red_derived.focus_bg.r);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue