feat(replay): add HC bump for WIN MOVE scrub-bar marker; extend HighContrastBackground

HighContrastBackground gains an optional hc_color field so sites can
specify a domain-specific HC variant rather than always bumping to
BORDER_SUBTLE_HC (gray). with_default() fills hc_color = BORDER_SUBTLE_HC
preserving all existing behaviour; new with_hc(default, hc) lets callers
specify both ends. update_high_contrast_backgrounds reads marker.hc_color
instead of the hardcoded constant.

STATE_SUCCESS_HC (#c8e862, L≈0.73) added to ui_theme — a brighter lime
that maintains the success hue while standing out from bumped notch
ticks (BORDER_SUBTLE_HC gray, L≈0.60) under HC mode.

WIN MOVE marker now carries HighContrastBackground::with_hc(STATE_SUCCESS,
STATE_SUCCESS_HC): lime stays lime under HC instead of turning gray.
Unit test pins both the default and hc color fields on the spawned marker.

1276 tests pass / 0 failing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
funman300
2026-05-08 18:19:00 -07:00
parent b44d2777ec
commit c50eaf81f7
3 changed files with 81 additions and 10 deletions
+45 -2
View File
@@ -38,8 +38,8 @@ use solitaire_data::ReplayMove;
use crate::ui_modal::{spawn_modal_button, ButtonVariant};
use crate::ui_theme::{
ACCENT_PRIMARY, BG_ELEVATED_HI, BORDER_SUBTLE, HighContrastBackground, HighContrastBorder,
STATE_SUCCESS, TEXT_PRIMARY, TEXT_PRIMARY_HC, TEXT_SECONDARY, TYPE_BODY, TYPE_CAPTION,
TYPE_HEADLINE, VAL_SPACE_1, VAL_SPACE_2, VAL_SPACE_4, Z_DROP_OVERLAY,
STATE_SUCCESS, STATE_SUCCESS_HC, TEXT_PRIMARY, TEXT_PRIMARY_HC, TEXT_SECONDARY, TYPE_BODY,
TYPE_CAPTION, TYPE_HEADLINE, VAL_SPACE_1, VAL_SPACE_2, VAL_SPACE_4, Z_DROP_OVERLAY,
};
// ---------------------------------------------------------------------------
@@ -779,6 +779,11 @@ fn spawn_overlay(
..default()
},
BackgroundColor(STATE_SUCCESS),
// HC bump: lime → brighter lime so the win
// marker reads clearly above the bumped
// notch ticks (BORDER_SUBTLE_HC gray) under
// high-contrast mode.
HighContrastBackground::with_hc(STATE_SUCCESS, STATE_SUCCESS_HC),
));
}
// Fixed quarter-mark notches: five 1px vertical
@@ -2349,6 +2354,44 @@ mod tests {
);
}
/// The WIN MOVE marker carries `HighContrastBackground::with_hc(
/// STATE_SUCCESS, STATE_SUCCESS_HC)` so the lime bumps to brighter
/// lime under HC mode rather than to a neutral gray. Pin the
/// presence of the marker so a future refactor can't accidentally
/// drop it and silently regress HC legibility.
#[test]
fn win_move_marker_carries_hc_background_marker() {
let mut app = headless_app();
set_state(
&mut app,
ReplayPlaybackState::Playing {
replay: synthetic_replay(8).with_win_move_index(Some(7)),
cursor: 0,
secs_to_next: 0.5,
paused: false,
},
);
app.update();
let mut q = app
.world_mut()
.query_filtered::<&HighContrastBackground, With<ReplayOverlayWinMoveMarker>>();
let marker = q
.iter(app.world())
.next()
.expect("WIN MOVE marker must carry HighContrastBackground");
assert_eq!(
marker.default_color,
STATE_SUCCESS,
"default colour must be STATE_SUCCESS"
);
assert_eq!(
marker.hc_color,
STATE_SUCCESS_HC,
"HC colour must be STATE_SUCCESS_HC (brighter lime, not gray)"
);
}
// -----------------------------------------------------------------------
// scrub_notch_positions + ReplayOverlayScrubNotch spawn behaviour
// -----------------------------------------------------------------------