M6.21: Dark theme parity + card shadow polish + hover/selection fixes

--dark command-line flag swaps CodexTheme.DefaultPalette to Dark
before any UI mounts; both TitleScreen and Wizard pick it up via
the no-arg Build() overload.

Stepper colours track the active palette. ApplyStateColors and the
Active step's gild underline previously read from a stub that
hardcoded parchment values, so the Active label rendered as
brown-black ink against the dark bg (invisible). Both sites now
read CodexTheme.DefaultPalette directly.

Card hover stays applied while the cursor is over an inner Button.
PanelContainer.MouseExited fires when the cursor crosses onto a
child that captures input (Sire/Dam toggles, Sheep/Goat toggles,
trait pickers); the recheck defers and uses GetGlobalRect.HasPoint
on the cursor position so hover only drops when the cursor truly
leaves the card area.

Selection stylebox lands on first refresh. SetSelected was
previously called inside BuildCard before AddChild, so
HasThemeStylebox returned false (theme cascade unreachable) and
the override silently dropped — it only re-attached when
MouseEntered later re-ran Apply. Refactored SetSelected/SetHover
through a new ApplyOrDefer helper that uses CallDeferred when the
card isn't in tree yet, so the seal border + drop shadow appear
immediately on selection rather than only after the first hover.

Selection drop shadow refined. Was a 14px shadow at offset (0,14)
which overlapped the next card by 16px in the v_separation:12
grid. Now offset (4,4) + size 6 — diagonal "light from upper-left"
direction, total reach 10px, leaves a 2px clearance before the
next card so the shadow reads as a shadow on the surface below.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Christopher Wiebe
2026-05-09 22:55:40 -07:00
parent 2db442be7e
commit 83c6343783
4 changed files with 80 additions and 22 deletions
+18 -4
View File
@@ -29,7 +29,15 @@ public static class CodexTheme
private static FontFile? _mono;
private static bool _fontsLoaded;
public static Theme Build() => Build(CodexPalette.Parchment);
/// <summary>
/// Palette used by the no-arg <see cref="Build()"/>. Set this before any
/// UI mounts to swap the active codex palette globally — e.g. Main reads
/// the <c>--dark</c> command-line flag and assigns <see cref="CodexPalette.Dark"/>
/// here. Defaults to <see cref="CodexPalette.Parchment"/>.
/// </summary>
public static CodexPalette DefaultPalette { get; set; } = CodexPalette.Parchment;
public static Theme Build() => Build(DefaultPalette);
public static Theme Build(CodexPalette palette)
{
@@ -101,9 +109,15 @@ public static class CodexTheme
var cardSelected = (StyleBoxFlat)card.Duplicate();
cardSelected.BorderColor = p.Seal;
cardSelected.SetBorderWidthAll(3);
cardSelected.ShadowColor = WithAlpha(p.Seal, 0.6f);
cardSelected.ShadowSize = 14;
cardSelected.ShadowOffset = new Vector2(0, 14);
// Drop shadow: directional (light from upper-left) and sized so the
// shadow's bottom edge stays clear of the next card. Card grids
// separate cards by 12px (v_separation in StepClade / StepSpecies /
// StepClass / etc.) — offset.y + size ≤ 11 keeps a 1px-minimum gap
// before the next card so the shadow reads as a shadow on the
// surface below, not as a smudge between cards.
cardSelected.ShadowColor = WithAlpha(p.Seal, 0.55f);
cardSelected.ShadowSize = 6;
cardSelected.ShadowOffset = new Vector2(4, 4);
theme.SetStylebox("panel_selected", "Card", cardSelected);
// Popover frame — gild border + soft shadow + rounded corners.