feat(ui): glowing border pulse for search highlights (#1586)

* feat(ui): add glowing border pulse effect for search highlights

Replace subtle background fade with a 3-pulse blue glow animation
(3s duration) on panels and map countries when navigating via search
or breaking news alerts. Helps users spot the target result.

* fix(map): reset country highlight opacity after pulse animation ends

Without this, fill-opacity decays to near-zero at animation end,
leaving the country nearly invisible until the brief panel closes.

* fix(ui): cancel stale highlight timers and clean up pulse RAF on destroy

- Cancel previous setTimeout before scheduling new highlight, preventing
  premature class removal on rapid re-search (Codex P2)
- Extract shared applyHighlight() in SearchManager with WeakMap tracking
- Cancel countryPulseRaf in DeckGLMap.destroy() to prevent orphaned RAF

* fix(ui): theme-aware highlight opacity and per-element timer tracking

- Use getHighlightRestOpacity() to read current map theme instead of
  hardcoded dark-theme values (0.12), fixing light-theme regression
- Pulse animation base values now scale from theme-correct resting opacity
- BreakingNewsBanner: switch from single timer slot to WeakMap per-element
  tracking, preventing permanent highlight on rapid alert clicks
This commit is contained in:
Elie Habib
2026-03-14 19:36:42 +04:00
committed by GitHub
parent b255672fee
commit 79ae930eba
4 changed files with 97 additions and 14 deletions

View File

@@ -10208,19 +10208,36 @@ a.prediction-link:hover {
border-left-color: var(--accent);
}
/* Flash highlight animation (for search results) */
.flash-highlight {
animation: flash-highlight 1.5s ease-out;
/* Search result highlight — glowing border pulse */
.search-highlight {
animation: search-glow-pulse 3s ease-in-out forwards;
}
@keyframes flash-highlight {
0% {
background: var(--overlay-heavy);
@keyframes search-glow-pulse {
0%,
100% {
box-shadow: 0 0 0 0 transparent;
border-color: var(--border);
}
100% {
background: transparent;
15%,
45%,
75% {
box-shadow: 0 0 20px 4px #3b82f6, inset 0 0 12px 0 rgba(59, 130, 246, 0.15);
border-color: #3b82f6;
}
30%,
60%,
90% {
box-shadow: 0 0 6px 1px rgba(59, 130, 246, 0.3);
border-color: rgba(59, 130, 246, 0.4);
}
}
/* Legacy alias */
.flash-highlight {
animation: search-glow-pulse 3s ease-in-out forwards;
}
/* Panel flash when new items arrive */