Improve homepage light theme map
This commit is contained in:
@@ -2394,6 +2394,164 @@
|
|||||||
filter: drop-shadow(0 0 8px rgba(34, 211, 238, 0.22));
|
filter: drop-shadow(0 0 8px rgba(34, 211, 238, 0.22));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── Light Theme Dashboard Overrides ── */
|
||||||
|
:global(html.light) .root {
|
||||||
|
background:
|
||||||
|
radial-gradient(circle at 22% 12%, rgba(14, 165, 233, 0.16), transparent 28%),
|
||||||
|
radial-gradient(circle at 78% 0%, rgba(59, 130, 246, 0.12), transparent 24%),
|
||||||
|
linear-gradient(180deg, #f8fbff 0%, #e7f1fb 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(html.light) .root :global(.map) {
|
||||||
|
background: #dfeefa;
|
||||||
|
border-color: rgba(36, 68, 104, 0.18);
|
||||||
|
filter: none;
|
||||||
|
box-shadow:
|
||||||
|
0 28px 80px rgba(31, 64, 104, 0.18),
|
||||||
|
inset 0 1px 0 rgba(255, 255, 255, 0.86);
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(html.light) .root :global(.map .leaflet-tile) {
|
||||||
|
filter: saturate(1.08) contrast(0.98) brightness(1.02);
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(html.light) .weatherAura {
|
||||||
|
opacity: 0.22;
|
||||||
|
mix-blend-mode: multiply;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(html.light) .weatherAuraScrim {
|
||||||
|
background:
|
||||||
|
linear-gradient(
|
||||||
|
180deg,
|
||||||
|
rgba(248, 252, 255, 0.2) 0%,
|
||||||
|
rgba(248, 252, 255, 0.08) 42%,
|
||||||
|
rgba(226, 239, 250, 0.28) 100%
|
||||||
|
),
|
||||||
|
radial-gradient(
|
||||||
|
circle at 50% 58%,
|
||||||
|
rgba(14, 165, 233, 0.08) 0%,
|
||||||
|
rgba(14, 165, 233, 0) 52%
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(html.light) .root :global(.home-map-title strong),
|
||||||
|
:global(html.light) .root :global(.home-panel-city h2),
|
||||||
|
:global(html.light) .root :global(.home-weather-main strong),
|
||||||
|
:global(html.light) .root :global(.home-weather-stat strong),
|
||||||
|
:global(html.light) .root :global(.home-deb-card strong),
|
||||||
|
:global(html.light) .root :global(.home-card-section h3),
|
||||||
|
:global(html.light) .root :global(.home-summary-card-head strong),
|
||||||
|
:global(html.light) .root :global(.opportunity-strip-heading strong),
|
||||||
|
:global(html.light) .root :global(.opportunity-city),
|
||||||
|
:global(html.light) .root :global(.home-summary-stat b),
|
||||||
|
:global(html.light) .root :global(.city-item .city-name-text) {
|
||||||
|
color: #0b1726;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(html.light) .root :global(.home-map-title span),
|
||||||
|
:global(html.light) .root :global(.home-panel-subtitle),
|
||||||
|
:global(html.light) .root :global(.home-weather-sub),
|
||||||
|
:global(html.light) .root :global(.home-weather-label),
|
||||||
|
:global(html.light) .root :global(.home-weather-stat span),
|
||||||
|
:global(html.light) .root :global(.home-weather-stat small),
|
||||||
|
:global(html.light) .root :global(.home-deb-card small),
|
||||||
|
:global(html.light) .root :global(.home-card-section h3 small),
|
||||||
|
:global(html.light) .root :global(.home-summary-stat span),
|
||||||
|
:global(html.light) .root :global(.opportunity-strip-heading span),
|
||||||
|
:global(html.light) .root :global(.opportunity-meta),
|
||||||
|
:global(html.light) .root :global(.city-group-title),
|
||||||
|
:global(html.light) .root :global(.home-panel-kicker),
|
||||||
|
:global(html.light) .root :global(.home-panel-airport) {
|
||||||
|
color: rgba(66, 84, 108, 0.86);
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(html.light) .root :global(.header) {
|
||||||
|
background: rgba(248, 252, 255, 0.9);
|
||||||
|
border-bottom-color: rgba(36, 68, 104, 0.14);
|
||||||
|
box-shadow: 0 12px 34px rgba(31, 64, 104, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(html.light) .root :global(.city-list),
|
||||||
|
:global(html.light) .root :global(.home-intelligence-panel),
|
||||||
|
:global(html.light) .root :global(.home-opportunity-strip) {
|
||||||
|
background:
|
||||||
|
radial-gradient(circle at 12% 0%, rgba(14, 165, 233, 0.08), transparent 34%),
|
||||||
|
rgba(248, 252, 255, 0.9);
|
||||||
|
border-color: rgba(36, 68, 104, 0.16);
|
||||||
|
box-shadow: 0 28px 70px rgba(31, 64, 104, 0.14);
|
||||||
|
color: #0b1726;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(html.light) .root :global(.home-summary-card),
|
||||||
|
:global(html.light) .root :global(.opportunity-card),
|
||||||
|
:global(html.light) .root :global(.home-deb-card),
|
||||||
|
:global(html.light) .root :global(.home-card-section),
|
||||||
|
:global(html.light) .root :global(.home-metric-card),
|
||||||
|
:global(html.light) .root :global(.home-forecast-item),
|
||||||
|
:global(html.light) .root :global(.home-intraday-reports span) {
|
||||||
|
background:
|
||||||
|
radial-gradient(circle at 100% 0%, rgba(14, 165, 233, 0.08), transparent 36%),
|
||||||
|
rgba(255, 255, 255, 0.92);
|
||||||
|
border-color: rgba(36, 68, 104, 0.14);
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.82);
|
||||||
|
color: #0b1726;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(html.light) .root :global(.home-weather-hero) {
|
||||||
|
background:
|
||||||
|
linear-gradient(135deg, rgba(238, 246, 255, 0.98), rgba(216, 233, 248, 0.92));
|
||||||
|
border-color: rgba(36, 68, 104, 0.14);
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(html.light) .root :global(.home-card-section.intraday),
|
||||||
|
:global(html.light) .root :global(.home-card-section.probability) {
|
||||||
|
background:
|
||||||
|
radial-gradient(circle at 0% 25%, rgba(14, 165, 233, 0.1), transparent 42%),
|
||||||
|
rgba(255, 255, 255, 0.92);
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(html.light) .root :global(.home-intraday-chart line) {
|
||||||
|
stroke: rgba(66, 84, 108, 0.16);
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(html.light) .root :global(.home-intraday-reports strong),
|
||||||
|
:global(html.light) .root :global(.home-probability-threshold),
|
||||||
|
:global(html.light) .root :global(.home-market-question strong),
|
||||||
|
:global(html.light) .root :global(.home-market-metrics strong),
|
||||||
|
:global(html.light) .root :global(.home-forecast-item strong) {
|
||||||
|
color: #0b1726;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(html.light) .root :global(.home-probability-row div),
|
||||||
|
:global(html.light) .root :global(.home-probability-track) {
|
||||||
|
background: rgba(37, 57, 82, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(html.light) .root :global(.city-group) {
|
||||||
|
background: rgba(255, 255, 255, 0.54);
|
||||||
|
border-color: rgba(36, 68, 104, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(html.light) .root :global(.city-group-header:hover),
|
||||||
|
:global(html.light) .root :global(.city-item:hover) {
|
||||||
|
background: rgba(221, 235, 250, 0.86);
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(html.light) .root :global(.city-item.active) {
|
||||||
|
background:
|
||||||
|
linear-gradient(90deg, rgba(14, 165, 233, 0.18), rgba(14, 165, 233, 0.06)),
|
||||||
|
rgba(255, 255, 255, 0.88);
|
||||||
|
border-color: rgba(14, 165, 233, 0.42);
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(html.light) .root :global(.leaflet-control-attribution),
|
||||||
|
:global(html.light) .root :global(.leaflet-control-zoom a) {
|
||||||
|
background: rgba(248, 252, 255, 0.86) !important;
|
||||||
|
border-color: rgba(36, 68, 104, 0.16) !important;
|
||||||
|
color: #0b1726 !important;
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes home-panel-enter {
|
@keyframes home-panel-enter {
|
||||||
from {
|
from {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
|||||||
@@ -34,6 +34,10 @@ const AUTO_NEARBY_MAX_DISTANCE_M = 120000;
|
|||||||
const AUTO_NEARBY_IDLE_REFRESH_DELAY_MS = 10_000;
|
const AUTO_NEARBY_IDLE_REFRESH_DELAY_MS = 10_000;
|
||||||
const AUTO_NEARBY_MIN_REFRESH_INTERVAL_MS = 60_000;
|
const AUTO_NEARBY_MIN_REFRESH_INTERVAL_MS = 60_000;
|
||||||
const MAP_MAX_ZOOM = 19;
|
const MAP_MAX_ZOOM = 19;
|
||||||
|
const MAP_TILE_URLS = {
|
||||||
|
dark: "https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png",
|
||||||
|
light: "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png",
|
||||||
|
} as const;
|
||||||
const CITY_MARKER_DISPLAY_OFFSETS: Record<
|
const CITY_MARKER_DISPLAY_OFFSETS: Record<
|
||||||
string,
|
string,
|
||||||
{ x: number; y: number; zIndexOffset?: number }
|
{ x: number; y: number; zIndexOffset?: number }
|
||||||
@@ -52,6 +56,16 @@ function getMarkerDisplayOffset(cityName: string) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getMapTileUrl() {
|
||||||
|
if (
|
||||||
|
typeof document !== "undefined" &&
|
||||||
|
document.documentElement.classList.contains("light")
|
||||||
|
) {
|
||||||
|
return MAP_TILE_URLS.light;
|
||||||
|
}
|
||||||
|
return MAP_TILE_URLS.dark;
|
||||||
|
}
|
||||||
|
|
||||||
function pickMarkerTemperature(
|
function pickMarkerTemperature(
|
||||||
snapshot?: Pick<CityDetail, "current" | "temp_symbol"> | CitySummary,
|
snapshot?: Pick<CityDetail, "current" | "temp_symbol"> | CitySummary,
|
||||||
) {
|
) {
|
||||||
@@ -382,6 +396,7 @@ export function useLeafletMap({
|
|||||||
}: UseLeafletMapArgs) {
|
}: UseLeafletMapArgs) {
|
||||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||||
const mapRef = useRef<L.Map | null>(null);
|
const mapRef = useRef<L.Map | null>(null);
|
||||||
|
const tileLayerRef = useRef<L.TileLayer | null>(null);
|
||||||
const markersRef = useRef<
|
const markersRef = useRef<
|
||||||
Record<string, { city: CityListItem; marker: L.Marker }>
|
Record<string, { city: CityListItem; marker: L.Marker }>
|
||||||
>({});
|
>({});
|
||||||
@@ -444,18 +459,16 @@ export function useLeafletMap({
|
|||||||
});
|
});
|
||||||
|
|
||||||
L.control.zoom({ position: "bottomright" }).addTo(map);
|
L.control.zoom({ position: "bottomright" }).addTo(map);
|
||||||
L.tileLayer(
|
const tileLayer = L.tileLayer(getMapTileUrl(), {
|
||||||
"https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png",
|
attribution:
|
||||||
{
|
'© <a href="https://www.openstreetmap.org/">OSM</a> © <a href="https://carto.com/">CARTO</a>',
|
||||||
attribution:
|
maxZoom: 19,
|
||||||
'© <a href="https://www.openstreetmap.org/">OSM</a> © <a href="https://carto.com/">CARTO</a>',
|
subdomains: "abcd",
|
||||||
maxZoom: 19,
|
}).addTo(map);
|
||||||
subdomains: "abcd",
|
|
||||||
},
|
|
||||||
).addTo(map);
|
|
||||||
|
|
||||||
const nearbyLayer = L.layerGroup().addTo(map);
|
const nearbyLayer = L.layerGroup().addTo(map);
|
||||||
mapRef.current = map;
|
mapRef.current = map;
|
||||||
|
tileLayerRef.current = tileLayer;
|
||||||
nearbyLayerRef.current = nearbyLayer;
|
nearbyLayerRef.current = nearbyLayer;
|
||||||
|
|
||||||
// Track which city we've already moved to for the current selection
|
// Track which city we've already moved to for the current selection
|
||||||
@@ -515,11 +528,30 @@ export function useLeafletMap({
|
|||||||
map.off("click", handleMapClick);
|
map.off("click", handleMapClick);
|
||||||
map.remove();
|
map.remove();
|
||||||
mapRef.current = null;
|
mapRef.current = null;
|
||||||
|
tileLayerRef.current = null;
|
||||||
nearbyLayerRef.current = null;
|
nearbyLayerRef.current = null;
|
||||||
markersRef.current = {};
|
markersRef.current = {};
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const tileLayer = tileLayerRef.current;
|
||||||
|
if (!tileLayer || typeof MutationObserver === "undefined") return;
|
||||||
|
|
||||||
|
const syncMapTheme = () => {
|
||||||
|
tileLayer.setUrl(getMapTileUrl());
|
||||||
|
};
|
||||||
|
syncMapTheme();
|
||||||
|
|
||||||
|
const observer = new MutationObserver(syncMapTheme);
|
||||||
|
observer.observe(document.documentElement, {
|
||||||
|
attributeFilter: ["class"],
|
||||||
|
attributes: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => observer.disconnect();
|
||||||
|
}, []);
|
||||||
|
|
||||||
// Handle initial view if cities are loaded
|
// Handle initial view if cities are loaded
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const map = mapRef.current;
|
const map = mapRef.current;
|
||||||
|
|||||||
Reference in New Issue
Block a user