From d657a25ba742d5ab5277ce2d4c8184eb30f1522f Mon Sep 17 00:00:00 2001 From: "R.Eugenio" Date: Wed, 31 Dec 2025 12:15:13 +0100 Subject: [PATCH] =?UTF-8?q?fix(visual):=20T=C3=ADtulos=20legibles=20+=20bo?= =?UTF-8?q?tones=20centrados?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix legibilidad títulos: - title_color: 85% soft_white + 15% tinte del base_color - Antes: base.lightenHsl(90) → azul claro sobre azul oscuro (ilegible) - Ahora: blanco con tinte sutil → máximo contraste + identidad visual Fix centrado vertical botones: - Añadido char_height al Context (default 14px para TTF) - button.zig: usa char_height en vez de char_width - Offset visual -1px para compensar efecto 3D del bisel 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/core/context.zig | 8 ++++++++ src/core/style.zig | 9 +++++---- src/widgets/button.zig | 14 ++++++++------ 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/core/context.zig b/src/core/context.zig index 2307224..4e806b6 100644 --- a/src/core/context.zig +++ b/src/core/context.zig @@ -115,6 +115,9 @@ pub const Context = struct { /// Default character width for fallback measurement (bitmap fonts) char_width: u32 = 8, + /// Default character height for vertical centering (TTF fonts typically 1.2-1.5x width) + char_height: u32 = 14, + /// Idle timeout for cursor blinking (ms). After this time without input, /// cursor becomes solid and no animation frames are needed. pub const CURSOR_IDLE_TIMEOUT_MS: u64 = 20000; @@ -341,6 +344,11 @@ pub const Context = struct { self.char_width = width; } + /// Set character height for vertical centering (TTF fonts) + pub fn setCharHeight(self: *Self, height: u32) void { + self.char_height = height; + } + /// Get current time in milliseconds pub fn getTime(self: Self) u64 { return self.current_time_ms; diff --git a/src/core/style.zig b/src/core/style.zig index 02aebbc..7dd0937 100644 --- a/src/core/style.zig +++ b/src/core/style.zig @@ -1382,13 +1382,14 @@ pub fn derivePanelFrameColors(base: Color) DerivedPanelColors { // Blend fijo: 20% color con focus, 12% sin focus const focus_bg = base.blendTowards(black, 80); // 20% color - // Título adaptativo: contraste máximo según luminosidad del fondo - // Fondos oscuros (L < 0.5) → blanco teñido, claros → negro teñido + // Título: BLANCO con tinte sutil del color base para identidad + // El contraste viene del blanco, el tinte da coherencia visual + // Fondos oscuros → blanco teñido, claros → negro teñido const bg_luminance = focus_bg.perceptualLuminance(); const title_color = if (bg_luminance < 0.5) - base.lightenHsl(90) // Blanco teñido (mantiene tono del panel) + Color.soft_white.blendTowards(base, 15) // 85% blanco + 15% tinte del panel else - base.darkenHsl(90); // Negro teñido + Color.soft_black.blendTowards(base, 15); // 85% negro + 15% tinte return .{ .focus_bg = focus_bg, diff --git a/src/widgets/button.zig b/src/widgets/button.zig index ec2273a..3043346 100644 --- a/src/widgets/button.zig +++ b/src/widgets/button.zig @@ -132,12 +132,13 @@ pub fn buttonRect(ctx: *Context, bounds: Layout.Rect, text: []const u8, config: } // Draw text centered (con offset +1px cuando está pulsado = "se hunde") - // Z-Design V2: usar métricas del contexto para centrado correcto con TTF + // Z-Design V5: usar char_height real + offset -1 para compensar efecto 3D const text_width = ctx.measureText(text); - const char_height = ctx.char_width; // Para fuentes cuadradas, height ≈ width + const char_height = ctx.char_height; const press_offset: i32 = if (pressed) 1 else 0; + const visual_adjust: i32 = -1; // Compensa efecto 3D del bisel que "hunde" visualmente const text_x = bounds.x + @as(i32, @intCast((bounds.w -| text_width) / 2)) + press_offset; - const text_y = bounds.y + @as(i32, @intCast((bounds.h -| char_height) / 2)) + press_offset; + const text_y = bounds.y + @as(i32, @intCast((bounds.h -| char_height) / 2)) + press_offset + visual_adjust; ctx.pushCommand(Command.text(text_x, text_y, text, fg_color)); @@ -247,12 +248,13 @@ pub fn buttonStatefulRect( } // Draw text centered (con offset +1px cuando está pulsado = "se hunde") - // Z-Design V2: usar métricas del contexto para centrado correcto con TTF + // Z-Design V5: usar char_height real + offset -1 para compensar efecto 3D const text_width = ctx.measureText(text); - const char_height = ctx.char_width; // Para fuentes cuadradas, height ≈ width + const char_height = ctx.char_height; const press_offset: i32 = if (pressed) 1 else 0; + const visual_adjust: i32 = -1; // Compensa efecto 3D del bisel que "hunde" visualmente const text_x = bounds.x + @as(i32, @intCast((bounds.w -| text_width) / 2)) + press_offset; - const text_y = bounds.y + @as(i32, @intCast((bounds.h -| char_height) / 2)) + press_offset; + const text_y = bounds.y + @as(i32, @intCast((bounds.h -| char_height) / 2)) + press_offset + visual_adjust; ctx.pushCommand(Command.text(text_x, text_y, text, fg_color));