diff --git a/frontend/components/dashboard/ScanTerminalDashboard.tsx b/frontend/components/dashboard/ScanTerminalDashboard.tsx
index 40d7f542..7e80fc05 100644
--- a/frontend/components/dashboard/ScanTerminalDashboard.tsx
+++ b/frontend/components/dashboard/ScanTerminalDashboard.tsx
@@ -289,8 +289,15 @@ function ScanTerminalScreen() {
setMapSelectedCityName(cityName);
lastMapSelectedCityRef.current = normalizeCityKey(cityName);
const matchedRow = findRowForCity(timeSortedRows, cityName);
- if (matchedRow) store.preloadCityFromRow(matchedRow);
- setSelectedRowId(matchedRow?.id || null);
+ if (matchedRow) {
+ store.preloadCityFromRow(matchedRow);
+ setSelectedRowId(matchedRow.id);
+ } else {
+ // City not in scan rows — still preload its detail so the decision
+ // card can render immediately instead of showing a loading spinner.
+ void store.ensureCityDetail(cityName, false, "panel").catch(() => {});
+ setSelectedRowId(null);
+ }
addAiPinnedCity(cityName);
setActiveView("analysis");
}, [addAiPinnedCity, store, timeSortedRows]);
@@ -352,30 +359,6 @@ function ScanTerminalScreen() {
/>
);
}
- if (resolvedView === "map") {
- return (
-
- );
- }
- if (resolvedView === "analysis") {
- return (
-
- );
- }
if (!isPro) {
return (
@@ -392,7 +375,35 @@ function ScanTerminalScreen() {
);
}
- return null;
+
+ // Keep MapCanvas always mounted — hiding with CSS avoids Leaflet
+ // reinitialization that causes a white background on tab switches.
+ // The analysis view overlays on top when active.
+ return (
+ <>
+
+ {resolvedView === "analysis" ? (
+
+ ) : null}
+ >
+ );
};
if (proAccess.loading) {
diff --git a/frontend/components/dashboard/scan-terminal/__tests__/temperatureChartData.test.ts b/frontend/components/dashboard/scan-terminal/__tests__/temperatureChartData.test.ts
index ea79446d..9be53fa2 100644
--- a/frontend/components/dashboard/scan-terminal/__tests__/temperatureChartData.test.ts
+++ b/frontend/components/dashboard/scan-terminal/__tests__/temperatureChartData.test.ts
@@ -78,7 +78,7 @@ export function runTests() {
"Ankara chart should build the DEB original path from MGM hourly data when Open-Meteo hourly is unavailable",
);
assert(
- ankaraChartData?.datasets.debSeries.length >= 4,
+ (ankaraChartData?.datasets.debSeries.length ?? 0) >= 4,
"Ankara chart should build the DEB original path from MGM hourly data",
);
assert(