@@ -319,7 +319,8 @@ const statusMessageState = {
319319 pendingMessage : null , // Pending message to display after minimum visibility
320320 pendingTimer : null , // Timer for pending message
321321 currentText : '' , // Current status text
322- currentColor : '' // Current status color
322+ currentColor : '' , // Current status color
323+ outsideZoneError : null // Persistent "outside zone" error message (blocks other messages until cleared)
323324} ;
324325
325326/**
@@ -841,11 +842,19 @@ function setConnStatus(text, color) {
841842 * Connection status words (Connected/Connecting/Disconnecting/Disconnected) are blocked
842843 * and replaced with em dash (—) placeholder.
843844 *
845+ * When outsideZoneError is set, all other messages are blocked until the error is cleared.
846+ *
844847 * @param {string } text - Status message text (null/empty shows "—")
845848 * @param {string } color - Status color class from STATUS_COLORS
846849 * @param {boolean } immediate - If true, bypass minimum visibility (for countdown timers)
847850 */
848851function setDynamicStatus ( text , color = STATUS_COLORS . idle , immediate = false ) {
852+ // If outside zone error is active, block all other messages (except clearing it)
853+ if ( statusMessageState . outsideZoneError && text !== statusMessageState . outsideZoneError ) {
854+ debugLog ( `[UI] Dynamic status blocked by persistent outside zone error: "${ text } "` ) ;
855+ return ;
856+ }
857+
849858 // Normalize empty/null/whitespace to em dash
850859 if ( ! text || text . trim ( ) === '' ) {
851860 text = '—' ;
@@ -888,6 +897,13 @@ function updateZoneStatusUI(zoneData) {
888897 const slotsText = `Zone: ${ zone . code } ` ;
889898 const statusColor = atCapacity ? "text-amber-300" : "text-emerald-300" ;
890899
900+ // Clear persistent outside zone error if it was set
901+ if ( statusMessageState . outsideZoneError ) {
902+ debugLog ( `[GEO AUTH] [UI] Clearing persistent outside zone error - now in zone ${ zone . code } ` ) ;
903+ statusMessageState . outsideZoneError = null ;
904+ setDynamicStatus ( "—" , STATUS_COLORS . idle ) ; // Clear the dynamic status bar
905+ }
906+
891907 zoneStatus . textContent = slotsText ;
892908 zoneStatus . className = `text-xs ${ statusColor } ` ;
893909
@@ -905,8 +921,19 @@ function updateZoneStatusUI(zoneData) {
905921 const nearest = zoneData . nearest_zone ;
906922 const distText = `Outside zone (${ nearest . distance_km } km to ${ nearest . code } )` ;
907923
908- zoneStatus . textContent = distText ;
909- zoneStatus . className = "text-xs text-yellow-400" ;
924+ // Clear zone status in connection bar (don't show distance there)
925+ zoneStatus . textContent = "" ;
926+ zoneStatus . className = "text-xs text-slate-400" ;
927+
928+ // Set persistent outside zone error - blocks all other dynamic status messages
929+ statusMessageState . outsideZoneError = distText ;
930+ debugLog ( `[GEO AUTH] [UI] Set persistent outside zone error: "${ distText } "` ) ;
931+
932+ // Show error in dynamic status bar (red) - this overrides "Select external antenna" message
933+ setDynamicStatus ( distText , STATUS_COLORS . error ) ;
934+
935+ // Log as error
936+ debugError ( `[GEO AUTH] [UI] ${ distText } ` ) ;
910937
911938 locationDisplay . textContent = "—" ;
912939 locationDisplay . className = "font-medium text-slate-400" ;
0 commit comments