Alerts tab: fix hurricane/tropical storm bugs; rich alert cards matching the dashboard
Publish Container / publish (push) Successful in 2m44s

Hurricane / tropical storm fixes
- NHC intensity is in knots: show real mph (80 kt = 92 mph) instead of mislabelled 'mph'
- Real Saffir-Simpson category from wind (was always cat 1); subtropical, post-tropical and
  potential-cyclone types no longer shown as 'depression'; each storm shows movement
  (direction + mph, previously a non-existent field), distance from you, update time, advisory link
- Forecast track points coloured by their own forecast strength (not the current class)
- Map click handlers registered once (popups stacked on every refresh); overlays wait for the
  map to settle instead of silently not drawing while tiles load; stale renders superseded
- Subtropical/tropical advice added to alert guidance; escaped storm names

Alert cards (active alerts only)
- What it's for, area, window, time remaining, plain-language meaning, what to do, and a
  Full details expander (headline, text, instructions, severity/urgency/certainty, issuer)
- No longer drops alerts beyond 6 per severity group; expired alerts are filtered out
- Shared plain-language alert glossary (alert-info.js, 64 products incl. tropical and surge)
  now used by both the app and the dashboard history

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Nate EmmertandClaude Sonnet 5.5 committed 2026-10-15 14:00:41 -04:00
1 parent 8252017417
commit 72a4a3fe38
8 files changed
+359 -196

No files matched your search

+26
View File
@@ -298,3 +298,29 @@ body.map-fs #tab-unified-map { padding: 0; }
#unified-map .maplibregl-ctrl-top-right { margin-top: calc(var(--hud-top) + 166px); margin-right: max(var(--hud-side), env(safe-area-inset-right, 0px)); }
#unified-map .maplibregl-ctrl-top-right .maplibregl-ctrl { margin: 0; }
@media (pointer: coarse) { #unified-map .maplibregl-ctrl-top-right { display: none; } }
/* ── Alerts tab: hurricane cards + rich alert cards ── */
.hurricane-storm-card { border-radius: 16px; padding: 0.9rem 1rem; }
.hurricane-name { font-weight: 800; font-size: 1.05rem; }
.hurricane-stats b { color: var(--ink); font-size: 0.95rem; }
.hurricane-stats small { opacity: .75; }
.hurricane-meta { display: flex; flex-wrap: wrap; gap: 0.3rem 0.9rem; align-items: center; margin-top: 0.5rem; font-size: 0.74rem; color: var(--ink-light); }
.hurricane-link { color: var(--accent); font-weight: 600; text-decoration: none; }
.hurricane-link:hover { text-decoration: underline; }
.hurricane-map-hint { margin-left: auto; color: var(--accent); font-weight: 600; }
.alert-rich { border-radius: 16px; padding: 0.95rem 1.05rem; }
.alert-why { font-size: 0.95rem; font-weight: 600; line-height: 1.4; margin: 0.35rem 0 0.5rem; }
.alert-facts { display: flex; flex-wrap: wrap; gap: 0.25rem 1rem; font-size: 0.8rem; color: var(--ink-light); margin-bottom: 0.55rem; }
.alert-left { font-weight: 700; color: var(--accent); }
.alert-meaning { font-size: 0.84rem; line-height: 1.45; padding: 0.55rem 0.75rem; border-radius: 12px; background: color-mix(in srgb, var(--accent) 9%, transparent); margin-bottom: 0.5rem; }
.alert-rich .alert-action { font-size: 0.86rem; line-height: 1.45; }
.alert-more { margin-top: 0.6rem; border-top: 1px dashed var(--border); padding-top: 0.5rem; }
.alert-more summary { cursor: pointer; font-size: 0.8rem; font-weight: 700; color: var(--accent); min-height: 36px; display: flex; align-items: center; list-style: none; }
.alert-more summary::-webkit-details-marker { display: none; }
.alert-more summary::before { content: '▸'; margin-right: 0.4rem; transition: transform .15s; }
.alert-more[open] summary::before { transform: rotate(90deg); }
.alert-full { font-size: 0.84rem; line-height: 1.5; }
.alert-full p { margin: 0 0 0.6rem; }
.alert-pre { white-space: pre-wrap; }
.alert-meta { font-size: 0.74rem; color: var(--ink-light); }