diff --git a/src/core/context.zig b/src/core/context.zig index be8a152..2307224 100644 --- a/src/core/context.zig +++ b/src/core/context.zig @@ -657,11 +657,12 @@ pub const Context = struct { break :blk config.border_color; }; + // Título adaptativo: siempre alta legibilidad (blanco teñido sobre fondo oscuro) const title_color: ?Style.Color = blk: { if (config.title_color) |tc| break :blk tc; if (config.base_color) |base| { const derived = Style.derivePanelFrameColors(base); - break :blk if (config.has_focus) derived.title_color else derived.border_unfocus; + break :blk derived.title_color; // Siempre legible, focus o no } break :blk border_color; }; @@ -698,12 +699,12 @@ pub const Context = struct { self.pushCommand(Command.rectOutline(rect.x, rect.y, rect.w, rect.h, border)); } - // 5. Draw title if specified + // 5. Draw title if specified (margen 10,5 para aire visual) if (config.title) |title| { if (title_color) |tc| { self.pushCommand(.{ .text = .{ - .x = rect.x + 8, - .y = rect.y + 4, + .x = rect.x + 10, + .y = rect.y + 5, .text = title, .color = tc, } }); diff --git a/src/core/style.zig b/src/core/style.zig index 4df93e2..02aebbc 100644 --- a/src/core/style.zig +++ b/src/core/style.zig @@ -1369,18 +1369,33 @@ pub const DerivedPanelColors = struct { /// - Fondo con focus: 20% base / 80% negro /// - Fondo sin focus: 12% base / 88% negro /// +/// Títulos Adaptativos (2025-12-31): +/// - El title_color se calcula para máximo contraste +/// - Fondo oscuro → blanco teñido (lightenHsl 90) +/// - Fondo claro → negro teñido (darkenHsl 90) +/// /// Los widgets usan bg_transition.current DIRECTAMENTE (mismo fondo que panel) /// con bisel de 1px para verse como "huecos" o "relieves" integrados. pub fn derivePanelFrameColors(base: Color) DerivedPanelColors { const black = Color.soft_black; // 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 + const bg_luminance = focus_bg.perceptualLuminance(); + const title_color = if (bg_luminance < 0.5) + base.lightenHsl(90) // Blanco teñido (mantiene tono del panel) + else + base.darkenHsl(90); // Negro teñido + return .{ - .focus_bg = base.blendTowards(black, 80), // 20% color + .focus_bg = focus_bg, .unfocus_bg = base.blendTowards(black, 88), // 12% color .border_focus = base, .border_unfocus = base.darken(30), - .title_color = base.lightenHsl(20), + .title_color = title_color, }; }