fix(style): Z-Design V5 final - Focus 20% / Unfocus 12%

Ajuste consensuado:
- deriveDarkPalette: 80% black (20% color) focus, 88% black (12% color) unfocus
- derivePanelFrameColors: mismos valores
- Elimina compensación perceptual completamente

Unfocus 12% es más visible que el anterior 4%.
This commit is contained in:
R.Eugenio 2025-12-31 01:29:06 +01:00
parent f41e502f9c
commit 203a1e6ee5

View file

@ -1120,10 +1120,11 @@ pub fn derivePanelPalette(base: Color, mode: ThemeMode) PanelColorScheme {
} }
/// Derive palette for dark mode (dark backgrounds, light text) /// Derive palette for dark mode (dark backgrounds, light text)
/// Z-Design V2 + Liquid UI: Mayor contraste para transiciones perceptibles /// Z-Design V5: Sincronía Atmosférica (2025-12-31)
/// - fondo_sin_focus: 4% base color (más oscuro, punto de partida bajo) /// - SIN compensación perceptual (causaba más problemas que soluciones)
/// - fondo_con_focus: 20% base color (brilla al ganar foco, destino alto) /// - Blend fijo para TODOS los colores:
/// Z-Design V3: Perceptual correction boosts low-luminance colors (red/magenta) /// - fondo_con_focus: 20% base color / 80% negro
/// - fondo_sin_focus: 12% base color / 88% negro
fn deriveDarkPalette(base: Color) PanelColorScheme { fn deriveDarkPalette(base: Color) PanelColorScheme {
// Reference colors for dark mode // Reference colors for dark mode
const black = Color.soft_black; // RGB(17, 17, 20) - not pure black const black = Color.soft_black; // RGB(17, 17, 20) - not pure black
@ -1131,27 +1132,14 @@ fn deriveDarkPalette(base: Color) PanelColorScheme {
const gray = Color.rgb(128, 128, 128); const gray = Color.rgb(128, 128, 128);
const dark_border = Color.rgb(60, 60, 65); const dark_border = Color.rgb(60, 60, 65);
// Perceptual correction: only for colors with VERY low luminance (like pure blue ~0.07) // Z-Design V5: Blend fijo sin compensación perceptual
// Red (~0.21) is above threshold and won't be affected // Focus: 20% color, Unfocus: 12% color (más visible que el anterior 4%)
const base_lum = base.perceptualLuminance(); const focus_blend: u8 = 80; // 80% hacia negro = 20% color
const threshold: f32 = 0.15; // Only affect colors below this (blue=0.07, red=0.21) const unfocus_blend: u8 = 88; // 88% hacia negro = 12% color
// Calculate correction factor: if luminance is VERY low, reduce blend %
// This makes more of the base color visible, preventing "goes to black" effect
const correction: f32 = if (perceptual_correction_enabled and base_lum < threshold)
@max(0.75, base_lum / threshold) // Subtle boost for very dark colors
else
1.0;
// Apply correction to blend percentages (lower % = more base color visible)
const focus_blend: u8 = @intFromFloat(80.0 * correction);
const unfocus_blend: u8 = @intFromFloat(96.0 * correction);
return .{ return .{
// Backgrounds: Liquid UI V2 - mayor recorrido para transición perceptible // Backgrounds: Z-Design V5 - blend fijo
// Focus: 20% base, 80% black (destino luminoso) - adjusted by correction
.fondo_con_focus = base.blendTowards(black, focus_blend), .fondo_con_focus = base.blendTowards(black, focus_blend),
// Sin focus: 4% base, 96% black (punto de partida oscuro) - adjusted
.fondo_sin_focus = base.blendTowards(black, unfocus_blend), .fondo_sin_focus = base.blendTowards(black, unfocus_blend),
// Text: high contrast // Text: high contrast
@ -1376,22 +1364,20 @@ pub const DerivedPanelColors = struct {
/// Derive panel frame colors from a single base color. /// Derive panel frame colors from a single base color.
/// ///
/// Z-Design V5: Sincronía Atmosférica (2025-12-31) /// Z-Design V5: Sincronía Atmosférica (2025-12-31)
/// - SIN compensación perceptual (causaba más problemas que soluciones) /// - SIN compensación perceptual
/// - Blend fijo y generoso para TODOS los colores: /// - Blend fijo para TODOS los colores:
/// - Fondo con focus: 18% base / 82% negro /// - Fondo con focus: 20% base / 80% negro
/// - Fondo sin focus: 6% base / 94% negro /// - Fondo sin focus: 12% base / 88% negro
/// ///
/// La clave de la fluidez está en pasar bg_transition.current a los widgets, /// Los widgets usan bg_transition.current DIRECTAMENTE (mismo fondo que panel)
/// NO en compensar matemáticamente los colores. /// con bisel de 1px para verse como "huecos" o "relieves" integrados.
pub fn derivePanelFrameColors(base: Color) DerivedPanelColors { pub fn derivePanelFrameColors(base: Color) DerivedPanelColors {
const black = Color.soft_black; const black = Color.soft_black;
// Blend fijo: 18% color con focus, 6% sin focus // Blend fijo: 20% color con focus, 12% sin focus
// blendTowards(black, 82) = 18% base + 82% black
// blendTowards(black, 94) = 6% base + 94% black
return .{ return .{
.focus_bg = base.blendTowards(black, 82), .focus_bg = base.blendTowards(black, 80), // 20% color
.unfocus_bg = base.blendTowards(black, 94), .unfocus_bg = base.blendTowards(black, 88), // 12% color
.border_focus = base, .border_focus = base,
.border_unfocus = base.darken(30), .border_unfocus = base.darken(30),
.title_color = base.lightenHsl(20), .title_color = base.lightenHsl(20),
@ -1399,7 +1385,7 @@ pub fn derivePanelFrameColors(base: Color) DerivedPanelColors {
} }
test "derivePanelFrameColors fixed blend" { test "derivePanelFrameColors fixed blend" {
// Z-Design V5: All colors use same fixed blend (18% focus, 6% unfocus) // Z-Design V5: All colors use same fixed blend (20% focus, 12% unfocus)
const blue = Color.rgb(0, 0, 255); const blue = Color.rgb(0, 0, 255);
const derived = derivePanelFrameColors(blue); const derived = derivePanelFrameColors(blue);
@ -1408,10 +1394,10 @@ test "derivePanelFrameColors fixed blend" {
try std.testing.expectEqual(blue.g, derived.border_focus.g); try std.testing.expectEqual(blue.g, derived.border_focus.g);
try std.testing.expectEqual(blue.b, derived.border_focus.b); try std.testing.expectEqual(blue.b, derived.border_focus.b);
// Focus bg: 18% blue + 82% soft_black(17,17,20) // Focus bg: 20% blue + 80% soft_black(17,17,20)
// 0.18 * 255 + 0.82 * 20 = 45.9 + 16.4 = 62.3 // 0.20 * 255 + 0.80 * 20 = 51 + 16 = 67
try std.testing.expect(derived.focus_bg.b > 50); try std.testing.expect(derived.focus_bg.b > 55);
try std.testing.expect(derived.focus_bg.b < 80); try std.testing.expect(derived.focus_bg.b < 85);
} }
test "derivePanelFrameColors same blend for all colors" { test "derivePanelFrameColors same blend for all colors" {
@ -1422,9 +1408,7 @@ test "derivePanelFrameColors same blend for all colors" {
const blue_derived = derivePanelFrameColors(blue); const blue_derived = derivePanelFrameColors(blue);
const red_derived = derivePanelFrameColors(red); const red_derived = derivePanelFrameColors(red);
// Both should have ~18% of their primary color channel // Both should have ~20% of their primary color channel
// Blue: ~18% of 255 = ~46, Red: ~18% of 255 = ~46
// (plus soft_black contribution)
const blue_intensity = blue_derived.focus_bg.b; const blue_intensity = blue_derived.focus_bg.b;
const red_intensity = red_derived.focus_bg.r; const red_intensity = red_derived.focus_bg.r;