feat(context): Títulos integrados con color adaptativo

Z-Design V5 - Títulos Adaptativos:
- derivePanelFrameColors: title_color según luminosidad del fondo
  - Fondo oscuro (L < 0.5) → base.lightenHsl(90) (blanco teñido)
  - Fondo claro → base.darkenHsl(90) (negro teñido)
- drawPanelFrame: siempre usa title_color (no border_unfocus)
- Márgenes título mejorados: x+10, y+5

Resultado: máximo contraste y legibilidad en todos los paneles.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
R.Eugenio 2025-12-31 01:54:58 +01:00
parent 203a1e6ee5
commit f7e1e346be
2 changed files with 22 additions and 6 deletions

View file

@ -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,
} });

View file

@ -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,
};
}