Two-state node freshness: Active vs Stale
- roles.js: add getNodeStatus(role, lastSeenMs) helper returning 'active'/'stale'
- Repeaters/Rooms: stale after 72h
- Companions/Sensors: stale after 24h
- Backward compat: getHealthThresholds() with degradedMs/silentMs still works
- map.js: stale markers get .marker-stale CSS class (opacity 0.35, grayscale 70%)
- Applied to both SVG shape markers and hash label markers
- makeMarkerIcon() and makeRepeaterLabelIcon() accept isStale parameter
- nodes.js: visual aging in table, side pane, and full detail
- Table: Last Seen column colored green (active) or muted (stale)
- Side pane: status shows 🟢 Active or ⚪ Stale (was 🟢/🟡/🔴)
- Full detail: Status row with role-appropriate explanation
- Stale repeaters: 'not heard for Xd — repeaters typically advertise every 12-24h'
- Stale companions: 'companions only advertise when user initiates'
- Fixed lastHeard fallback to n.last_seen when health API has no stats
- style.css: .marker-stale, .last-seen-active, .last-seen-stale classes
Added miniMarkdown() — simple markdown→HTML (bold, italic, code,
links, lists, line breaks). Home page description/answer fields
render markdown. Customizer uses textareas with markdown hint
for description and answer fields.
Badge CSS (.badge-advert etc.) was hardcoded in style.css with
different colors than TYPE_COLORS. Now roles.js generates badge
CSS from TYPE_COLORS on page load via syncBadgeColors(). Customizer
calls syncBadgeColors() after changes. Badges always match the
color pickers and TYPE_COLORS, in both light and dark mode.
Added global window.TYPE_COLORS in roles.js. Live.js and audio-lab.js
now reference the global. Customizer shows packet type colors with
emoji + descriptions. Changes sync to TYPE_COLORS in real-time.
Saved/restored via localStorage alongside node colors.
Add window.IATA_CITIES with ~150 common airport codes covering US, Canada,
Europe, Asia, Oceania, South America, and Africa. The region filter now
falls back to this mapping when no user-configured label exists, so region
dropdowns show friendly city names out of the box.
Closes#116