From f41e502f9c67234aab5a839a0609dea9517bd48b Mon Sep 17 00:00:00 2001 From: "R.Eugenio" Date: Wed, 31 Dec 2025 00:43:24 +0100 Subject: [PATCH] =?UTF-8?q?fix(style):=20Z-Design=20V5=20-=20Blend=20fijo?= =?UTF-8?q?=20sin=20compensaci=C3=B3n=20perceptual?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simplificación consensuada: - Eliminar compensación perceptual (causaba más problemas) - Blend fijo para TODOS los colores: - Focus: 18% base / 82% negro - Unfocus: 6% base / 94% negro La fluidez viene de pasar bg_transition.current a widgets, no de compensar matemáticamente. --- src/core/style.zig | 85 ++++++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 52 deletions(-) diff --git a/src/core/style.zig b/src/core/style.zig index 9ac53ec..9ffdbdc 100644 --- a/src/core/style.zig +++ b/src/core/style.zig @@ -1375,46 +1375,31 @@ pub const DerivedPanelColors = struct { /// Derive panel frame colors from a single base color. /// -/// 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) +/// Z-Design V5: Sincronía Atmosférica (2025-12-31) +/// - SIN compensación perceptual (causaba más problemas que soluciones) +/// - Blend fijo y generoso para TODOS los colores: +/// - Fondo con focus: 18% base / 82% negro +/// - Fondo sin focus: 6% base / 94% negro /// -/// 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%) +/// La clave de la fluidez está en pasar bg_transition.current a los widgets, +/// NO en compensar matemáticamente los colores. pub fn derivePanelFrameColors(base: Color) DerivedPanelColors { - const L = base.perceptualLuminance(); - - // 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); - const black = Color.soft_black; + // Blend fijo: 18% color con focus, 6% sin focus + // blendTowards(black, 82) = 18% base + 82% black + // blendTowards(black, 94) = 6% base + 94% black return .{ - .focus_bg = base.blendTowards(black, focus_pct), - .unfocus_bg = base.blendTowards(black, unfocus_pct), + .focus_bg = base.blendTowards(black, 82), + .unfocus_bg = base.blendTowards(black, 94), .border_focus = base, .border_unfocus = base.darken(30), .title_color = base.lightenHsl(20), }; } -test "derivePanelFrameColors blue gets boost" { - // Pure blue has L ~= 0.07, which is < 0.2, so it gets 35% boost +test "derivePanelFrameColors fixed blend" { + // Z-Design V5: All colors use same fixed blend (18% focus, 6% unfocus) const blue = Color.rgb(0, 0, 255); const derived = derivePanelFrameColors(blue); @@ -1423,34 +1408,30 @@ test "derivePanelFrameColors blue gets boost" { try std.testing.expectEqual(blue.g, derived.border_focus.g); try std.testing.expectEqual(blue.b, derived.border_focus.b); - // 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 + // Focus bg: 18% blue + 82% soft_black(17,17,20) + // 0.18 * 255 + 0.82 * 20 = 45.9 + 16.4 = 62.3 + try std.testing.expect(derived.focus_bg.b > 50); + try std.testing.expect(derived.focus_bg.b < 80); } -test "derivePanelFrameColors red is standard" { - // Red has L ~= 0.21, which is > 0.2, so it gets standard 22% +test "derivePanelFrameColors same blend for all colors" { + // V5: No perceptual correction - same blend for red and blue + const blue = Color.rgb(0, 0, 255); const red = Color.rgb(255, 0, 0); - const derived = derivePanelFrameColors(red); - - // 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); + // Both should have ~18% 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 red_intensity = red_derived.focus_bg.r; + + // Should be approximately equal (within tolerance for soft_black blend) + const diff = if (blue_intensity > red_intensity) + blue_intensity - red_intensity + else + red_intensity - blue_intensity; + try std.testing.expect(diff < 10); // Close enough }