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:
parent
f41e502f9c
commit
203a1e6ee5
1 changed files with 25 additions and 41 deletions
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue