const App = () => {
            const [selectedLoc, setSelectedLoc] = useState(null);
            const [selectedWebcam, setSelectedWebcam] = useState(null);
            const [isLocating, setIsLocating] = useState(false);
            const [layerMode, setLayerMode] = useState('standard');
            const [showLayers, setShowLayers] = useState(false);
            const [showLegend, setShowLegend] = useState(false);
            
            // Search Feature State
            const [searchQuery, setSearchQuery] = useState("");
            const [searchResults, setSearchResults] = useState([]);
            const [isSearching, setIsSearching] = useState(false);
            const searchRef = useRef(null);
            
            // Saved Spots feature
            const [savedSpots, setSavedSpots] = useState(() => JSON.parse(localStorage.getItem('northernPixlSaved')) || []);
            const [showSaved, setShowSaved] = useState(false);
            
            // Radar Playback State
            const [radarFrames, setRadarFrames] = useState([]);
            const [currentFrame, setCurrentFrame] = useState(0);
            const [isPlaying, setIsPlaying] = useState(false);
            
            // Toast notification
            const [toastMsg, setToastMsg] = useState(null);

            const mapContainerRef = useRef(null);
            const mapInstanceRef = useRef(null);
            const clickMarkerRef = useRef(null);
            const userMarkerRef = useRef(null);
            
            const lightLayerRef = useRef(null);
            const darkMapLayerRef = useRef(null);
            const topoLayerRef = useRef(null);
            const astroLayerRef = useRef(null);
            const darkLabelsLayerRef = useRef(null);
            
            const radarLayerDictRef = useRef({}); 

            const showToast = (msg) => {
                setToastMsg(msg);
                setTimeout(() => setToastMsg(null), 3000);
            };

            // Close search results when clicking outside
            useEffect(() => {
                const handleClickOutside = (event) => {
                    if (searchRef.current && !searchRef.current.contains(event.target)) {
                        setSearchResults([]);
                    }
                };
                document.addEventListener("mousedown", handleClickOutside);
                return () => document.removeEventListener("mousedown", handleClickOutside);
            }, []);

            const handleSearch = async (e) => {
                e.preventDefault();
                if (!searchQuery.trim()) return;
                setIsSearching(true);
                try {
                    // Removed &countrycodes=gb to enable worldwide search
                    // Added User-Agent header to comply with Nominatim API policy
                    const res = await fetch(`https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(searchQuery)}`, {
                        headers: {
                            "User-Agent": "NorthernPixlWeatherApp/1.0"
                        }
                    });
                    const data = await res.json();
                    setSearchResults(data);
                    if (data.length === 0) showToast("No locations found.");
                } catch (err) {
                    showToast("Search failed. Please try again.");
                } finally {
                    setIsSearching(false);
                }
            };

            const handleSelectSearchResult = (result) => {
                const lat = parseFloat(result.lat);
                const lng = parseFloat(result.lon);
                setSearchResults([]);
                setSearchQuery("");
                reverseGeocodeAndSelect(lat, lng, false);
            };

            const reverseGeocodeAndSelect = async (lat, lng, isUserLocation = false) => {
                const defaultName = isUserLocation ? "Your Location" : "Custom Location";
                setSelectedLoc({ lat, lng, name: "Loading...", type: isUserLocation ? "Current Location" : "Custom Pin" });
                try {
                    // Added User-Agent header to comply with Nominatim API policy
                    const res = await fetch(`https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=${lat}&lon=${lng}`, {
                        headers: {
                            "User-Agent": "NorthernPixlWeatherApp/1.0"
                        }
                    });
                    const data = await res.json();
                    let locName = defaultName;
                    if (data && data.name) {
                        locName = data.name;
                    } else if (data && data.address) {
                        // Expanded address fields to better support global remote areas
                        locName = data.address.village || data.address.town || data.address.city || data.address.municipality || data.address.county || data.address.state || data.address.country || defaultName;
                    }
                    setSelectedLoc({ lat, lng, name: locName, type: isUserLocation ? "Current Location" : "Custom Pin" });
                } catch (err) {
                    setSelectedLoc({ lat, lng, name: defaultName, type: isUserLocation ? "Current Location" : "Custom Pin" });
                }
                
                if (clickMarkerRef.current) {
                    clickMarkerRef.current.setLatLng([lat, lng]);
                } else if (mapInstanceRef.current) {
                    const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#0ea5e9" stroke="#ffffff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" style="width: 32px; height: 32px; filter: drop-shadow(0px 4px 4px rgba(0,0,0,0.25));"><path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z"></path><circle cx="12" cy="10" r="3" fill="#ffffff" stroke="none"></circle></svg>`;
                    clickMarkerRef.current = L.marker([lat, lng], {
                        icon: L.divIcon({ className: 'custom-map-marker', html: svg, iconSize: [32, 32], iconAnchor: [16, 32] })
                    }).addTo(mapInstanceRef.current);
                }
            };

            const getSafeUrl = (url) => {
                if (!url) return "";
                let safeUrl = url;
                try {
                    if (url.includes('youtube.com/watch?v=')) {
                        const urlObj = new URL(url);
                        const videoId = urlObj.searchParams.get('v');
                        safeUrl = `https://www.youtube.com/embed/${videoId}?autoplay=1&mute=1`;
                    } else if (url.includes('youtu.be/')) {
                        const videoId = url.split('youtu.be/')[1].split('?')[0];
                        safeUrl = `https://www.youtube.com/embed/${videoId}?autoplay=1&mute=1`;
                    }
                } catch (e) {
                    console.error("URL parsing error", e);
                }
                return safeUrl;
            };

            const getOriginalUrl = (url) => {
                if (!url) return "#";
                if (url.includes('/embed/')) {
                    const videoId = url.split('/embed/')[1].split('?')[0];
                    return `https://www.youtube.com/watch?v=${videoId}`;
                }
                return url;
            };

            useEffect(() => {
                const onPopState = () => {
                    setSelectedLoc(null);
                    setSelectedWebcam(null);
                };
                window.addEventListener('popstate', onPopState);
                return () => window.removeEventListener('popstate', onPopState);
            }, []);

            // Setup Map Base Layers
            useEffect(() => {
                const timer = setTimeout(() => {
                    if (mapContainerRef.current && !mapInstanceRef.current) {
                        const map = L.map(mapContainerRef.current, { zoomControl: false }).setView([54.5, -3.5], 6);
                        mapInstanceRef.current = map;
                        
                        lightLayerRef.current = L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png', { attribution: '&copy; OpenStreetMap, &copy; CARTO' });
                        darkMapLayerRef.current = L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', { attribution: '&copy; CARTO' });
                        topoLayerRef.current = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', { 
                            attribution: 'Map data: &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, <a href="http://viewfinderpanoramas.org">SRTM</a> | Map style: &copy; <a href="https://opentopomap.org">OpenTopoMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)', 
                            maxZoom: 17 
                        });
                        
                        // NASA Black Marble (True Light Pollution) + Dark Labels
                        astroLayerRef.current = L.tileLayer('https://gibs.earthdata.nasa.gov/wmts/epsg3857/best/VIIRS_CityLights_2012/default/2012-05-01/GoogleMapsCompatible_Level8/{z}/{y}/{x}.jpg', { 
                            attribution: '&copy; NASA',
                            maxNativeZoom: 8,
                            maxZoom: 18
                        });
                        darkLabelsLayerRef.current = L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_only_labels/{z}/{x}/{y}{r}.png', { 
                            attribution: '&copy; CARTO',
                            maxZoom: 18
                        });

                        lightLayerRef.current.addTo(map);

                        // --- Fetch and Add Webcams to map ---
                        fetch('data/webcams.json')
                            .then(res => res.json())
                            .then(data => {
                                if (!mapInstanceRef.current) return;
                                data.forEach(cam => {
                                    const cameraIconHtml = `<div class="bg-slate-900 text-white rounded-full p-2 shadow-lg border-2 border-white flex items-center justify-center w-8 h-8"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.5 4h-5L7 7H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3l-2.5-3z"/><circle cx="12" cy="13" r="3"/></svg></div>`;
                                    const camIcon = L.divIcon({
                                        className: 'custom-webcam-marker',
                                        html: cameraIconHtml,
                                        iconSize: [32, 32],
                                        iconAnchor: [16, 16]
                                    });
                                    const marker = L.marker([cam.lat, cam.lng], { icon: camIcon, zIndexOffset: 500 }).addTo(map);
                                    marker.on('click', () => {
                                        setSelectedWebcam(cam);
                                    });
                                });
                            })
                            .catch(err => console.warn('Error loading webcams JSON:', err));
                        // --------------------------
                        
                        map.on('click', async (e) => {
                            // Fix out-of-bounds coordinates caused by continuous horizontal panning
                            const wrapped = e.latlng.wrap();
                            reverseGeocodeAndSelect(wrapped.lat, wrapped.lng, false);
                        });

                        const params = new URLSearchParams(window.location.search);
                        const urlLat = parseFloat(params.get('lat'));
                        const urlLng = parseFloat(params.get('lng'));
                        if (!isNaN(urlLat) && !isNaN(urlLng)) {
                            // Mathematically wrap URL parameters to prevent crash on bad sharing links
                            const wrapped = L.latLng(urlLat, urlLng).wrap();
                            reverseGeocodeAndSelect(wrapped.lat, wrapped.lng, false);
                        }
                    }
                }, 100);

                return () => {
                    clearTimeout(timer);
                    if (mapInstanceRef.current) {
                        mapInstanceRef.current.remove();
                        mapInstanceRef.current = null;
                    }
                };
            }, []);

            // Handle Layer Switching (Robust Async/Await dual-provider system)
            useEffect(() => {
                if (!mapInstanceRef.current) return;
                const map = mapInstanceRef.current;
                let isCancelled = false;
                
                const safeRemove = (layerRef) => {
                    if (layerRef.current && map.hasLayer(layerRef.current)) map.removeLayer(layerRef.current);
                };
                const safeAdd = (layerRef) => {
                    if (layerRef.current && !map.hasLayer(layerRef.current)) layerRef.current.addTo(map);
                };

                const fetchMapData = async () => {
                    if (layerMode === 'dark') {
                        safeRemove(lightLayerRef);
                        safeRemove(topoLayerRef);
                        safeRemove(darkMapLayerRef);
                        safeAdd(astroLayerRef);
                        safeAdd(darkLabelsLayerRef);
                        setIsPlaying(false);
                        setRadarFrames([]);
                        
                    } else if (layerMode === 'topo') {
                        safeRemove(lightLayerRef);
                        safeRemove(darkMapLayerRef);
                        safeRemove(astroLayerRef);
                        safeRemove(darkLabelsLayerRef);
                        safeAdd(topoLayerRef);
                        setIsPlaying(false);
                        setRadarFrames([]);

                    } else if (layerMode === 'cloud') {
                        safeRemove(lightLayerRef);
                        safeRemove(topoLayerRef);
                        safeRemove(astroLayerRef);
                        safeRemove(darkLabelsLayerRef);
                        safeAdd(darkMapLayerRef); 
                        
                        let frames = [];
                        
                        try {
                            const res = await fetch('https://api.rainviewer.com/public/weather-maps.json');
                            const data = await res.json();
                            if (isCancelled) return;
                            
                            const satData = data?.satellite?.infrared || [];
                            
                            if (satData.length > 1) {
                                frames = satData.slice(-8).map(f => ({
                                    time: f.time,
                                    path: f.path,
                                    type: 'past',
                                    provider: 'rainviewer_sat'
                                }));
                            }
                        } catch (err) {
                            console.warn("Rainviewer satellite API unavailable.", err);
                        }

                        if (frames.length <= 1) {
                            const now = new Date();
                            const buffer = new Date(now.getTime() - 45 * 60000); 
                            buffer.setUTCMinutes(Math.floor(buffer.getUTCMinutes() / 15) * 15, 0, 0);

                            for (let i = 7; i >= 0; i--) {
                                const t = new Date(buffer.getTime() - i * 15 * 60000);
                                frames.push({
                                    time: Math.floor(t.getTime() / 1000),
                                    timeStr: t.toISOString(),
                                    type: 'past',
                                    provider: 'eumetsat_wms'
                                });
                            }
                        }

                        if (isCancelled) return;

                        setRadarFrames(frames);
                        
                        if (radarLayerDictRef.current) {
                            Object.values(radarLayerDictRef.current).forEach(layer => {
                                if (map.hasLayer(layer)) map.removeLayer(layer);
                            });
                        }
                        radarLayerDictRef.current = {};

                        setCurrentFrame(frames.length - 1);
                        setIsPlaying(true); 

                    } else if (layerMode === 'radar') {
                        safeRemove(lightLayerRef);
                        safeRemove(topoLayerRef);
                        safeRemove(astroLayerRef);
                        safeRemove(darkLabelsLayerRef);
                        safeAdd(darkMapLayerRef); 
                        
                        try {
                            const res = await fetch('https://api.rainviewer.com/public/weather-maps.json');
                            const data = await res.json();
                            if (isCancelled) return;
                            
                            const past = data?.radar?.past || [];
                            const nowcast = data?.radar?.nowcast || [];
                            const frames = [
                                ...past.map(f => ({ ...f, type: 'past', provider: 'rainviewer_radar' })),
                                ...nowcast.map(f => ({ ...f, type: 'future', provider: 'rainviewer_radar' }))
                            ];
                            
                            if (frames.length === 0) {
                                showToast(`Radar data temporarily unavailable`);
                                setLayerMode('standard');
                                return;
                            }
                            
                            setRadarFrames(frames);
                            
                            if (radarLayerDictRef.current) {
                                Object.values(radarLayerDictRef.current).forEach(layer => {
                                    if (map.hasLayer(layer)) map.removeLayer(layer);
                                });
                            }
                            radarLayerDictRef.current = {};

                            setCurrentFrame(frames.length - 1);
                            setIsPlaying(true);
                            
                        } catch (err) {
                            console.warn("Fetch error:", err);
                            if (!isCancelled) {
                                showToast(`Failed to load radar data`);
                                setLayerMode('standard');
                            }
                        }
                    } else {
                        safeAdd(lightLayerRef);
                        safeRemove(topoLayerRef);
                        safeRemove(darkMapLayerRef);
                        safeRemove(astroLayerRef);
                        safeRemove(darkLabelsLayerRef);
                        setIsPlaying(false);
                        setRadarFrames([]);
                        if (radarLayerDictRef.current) {
                            Object.values(radarLayerDictRef.current).forEach(layer => {
                                if (map.hasLayer(layer)) map.removeLayer(layer);
                            });
                            radarLayerDictRef.current = {};
                        }
                    }
                };

                fetchMapData();

                return () => {
                    isCancelled = true;
                    if (layerMode === 'radar' || layerMode === 'cloud') {
                        if (radarLayerDictRef.current) {
                            Object.values(radarLayerDictRef.current).forEach(layer => {
                                if (mapInstanceRef.current && mapInstanceRef.current.hasLayer(layer)) {
                                    mapInstanceRef.current.removeLayer(layer);
                                }
                            });
                            radarLayerDictRef.current = {};
                        }
                        setRadarFrames([]);
                        setIsPlaying(false);
                    }
                };
            }, [layerMode]);

            // Animation Loop Controller
            useEffect(() => {
                let interval;
                if (isPlaying && radarFrames.length > 1) {
                    interval = setInterval(() => {
                        setCurrentFrame(prev => (prev + 1) % radarFrames.length);
                    }, 1000); 
                }
                return () => clearInterval(interval);
            }, [isPlaying, radarFrames.length]);

            // Highly Optimized Double-Buffered Pre-caching Layer Renderer
            useEffect(() => {
                if ((layerMode !== 'radar' && layerMode !== 'cloud') || radarFrames.length === 0 || !mapInstanceRef.current) return;
                const map = mapInstanceRef.current;

                const getLayer = (f) => {
                    if (!f) return null;
                    
                    if (f.provider === 'rainviewer_sat') {
                        const path = f.path;
                        if (!radarLayerDictRef.current[path]) {
                            const host = 'https://tilecache.rainviewer.com';
                            radarLayerDictRef.current[path] = L.tileLayer(`${host}${path}/256/{z}/{x}/{y}/0/0_0.png`, {
                                opacity: 0,
                                className: 'cloud-tile weather-layer-transition',
                                maxNativeZoom: 3,
                                maxZoom: 18,
                                attribution: '&copy; RainViewer Satellite',
                                errorTileUrl: 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
                            });
                        }
                        return radarLayerDictRef.current[path];

                    } else if (f.provider === 'eumetsat_wms') {
                        const key = `eumetsat_${f.timeStr}`;
                        if (!radarLayerDictRef.current[key]) {
                            radarLayerDictRef.current[key] = L.tileLayer.wms('https://view.eumetsat.int/geoserver/wms', {
                                layers: 'msg_fes:ir108',
                                format: 'image/png',
                                transparent: true,
                                version: '1.3.0',
                                time: f.timeStr,
                                opacity: 0,
                                className: 'cloud-tile weather-layer-transition',
                                maxNativeZoom: 5,
                                maxZoom: 18,
                                attribution: '&copy; EUMETSAT'
                            });
                        }
                        return radarLayerDictRef.current[key];

                    } else if (f.provider === 'rainviewer_radar') {
                        const path = f.path;
                        if (!radarLayerDictRef.current[path]) {
                            let host = f.host || 'https://tilecache.rainviewer.com';
                            host = host.replace('http://', 'https://'); 
                            
                            radarLayerDictRef.current[path] = L.tileLayer(`${host}${path}/256/{z}/{x}/{y}/2/1_1.png`, {
                                opacity: 0,
                                className: 'weather-layer-transition radar-tile', 
                                maxNativeZoom: 6, 
                                maxZoom: 18,
                                zIndex: 10,
                                attribution: '&copy; RainViewer Radar',
                                errorTileUrl: 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
                            });
                        }
                        return radarLayerDictRef.current[path];
                    }
                };

                radarFrames.forEach(f => {
                    const layer = getLayer(f);
                    if (layer && !map.hasLayer(layer)) {
                        layer.setOpacity(0);
                        layer.addTo(map);
                    }
                });

                radarFrames.forEach((f, idx) => {
                    const layer = getLayer(f);
                    if (layer) {
                        if (idx === currentFrame) {
                            layer.setOpacity(layerMode === 'cloud' ? 1.0 : 0.85); 
                        } else {
                            layer.setOpacity(0);
                        }
                    }
                });

            }, [currentFrame, radarFrames, layerMode]);

            useEffect(() => {
                if (mapInstanceRef.current && selectedLoc) {
                    const map = mapInstanceRef.current;
                    const isDesktop = window.innerWidth >= 768;
                    const targetZoom = 12;
                    const targetPoint = map.project([selectedLoc.lat, selectedLoc.lng], targetZoom);
                    const offsetX = isDesktop ? -200 : 0;
                    const offsetY = isDesktop ? 0 : 200;
                    const offsetPoint = L.point(targetPoint.x + offsetX, targetPoint.y + offsetY);
                    const offsetLatLng = map.unproject(offsetPoint, targetZoom);
                    map.flyTo(offsetLatLng, targetZoom, { duration: 1.2 });
                }
            }, [selectedLoc]);

            const handleLocateMe = () => {
                if (!mapInstanceRef.current || isLocating) return;
                setIsLocating(true);
                mapInstanceRef.current.locate({ setView: true, maxZoom: 12 });
                
                mapInstanceRef.current.once('locationfound', async (e) => {
                    setIsLocating(false);
                    const wrapped = e.latlng.wrap();
                    const { lat, lng } = wrapped;
                    if (userMarkerRef.current) {
                        userMarkerRef.current.setLatLng([lat, lng]);
                    } else {
                        userMarkerRef.current = L.circleMarker([lat, lng], { radius: 8, fillColor: '#ef4444', color: '#ffffff', weight: 3, fillOpacity: 1 }).addTo(mapInstanceRef.current).bindTooltip("You are here", { permanent: false, direction: 'top' });
                    }
                    reverseGeocodeAndSelect(lat, lng, true);
                });
                
                mapInstanceRef.current.once('locationerror', () => {
                    setIsLocating(false);
                    console.warn("Location access denied.");
                });
            };

            const toggleSaveSpot = () => {
                if (!selectedLoc) return;
                const exists = savedSpots.find(s => s.lat === selectedLoc.lat && s.lng === selectedLoc.lng);
                let updated;
                if (exists) {
                    updated = savedSpots.filter(s => s.lat !== selectedLoc.lat || s.lng !== selectedLoc.lng);
                    showToast("Spot removed from bookmarks");
                } else {
                    updated = [...savedSpots, { lat: selectedLoc.lat, lng: selectedLoc.lng, name: selectedLoc.name }];
                    showToast("Spot bookmarked!");
                }
                setSavedSpots(updated);
                localStorage.setItem('northernPixlSaved', JSON.stringify(updated));
            };

            const copyShareLink = () => {
                if (!selectedLoc) return;
                const url = `${window.location.origin}${window.location.pathname}?lat=${selectedLoc.lat.toFixed(5)}&lng=${selectedLoc.lng.toFixed(5)}`;
                const el = document.createElement('textarea');
                el.value = url;
                document.body.appendChild(el);
                el.select();
                document.execCommand('copy');
                document.body.removeChild(el);
                showToast("Location link copied to clipboard!");
            };

            const isNearHolyIsland = (lat, lng) => {
                const holyLat = 55.6694;
                const holyLng = -1.7856;
                const dLatMiles = (lat - holyLat) * 69;
                const dLngMiles = (lng - holyLng) * 39;
                const distanceMiles = Math.sqrt(dLatMiles * dLatMiles + dLngMiles * dLngMiles);
                return distanceMiles <= 7;
            };

            const isSaved = selectedLoc ? savedSpots.some(s => s.lat === selectedLoc.lat && s.lng === selectedLoc.lng) : false;

            return (
                <div className="fixed inset-0 bg-slate-50 overflow-hidden">
                    {/* Fixed Navbar Stacking Context to prevent map from covering mobile menus */}
                    <div className="relative z-[9999]">
                        <Navbar />
                    </div>
                    
                    <main className="absolute top-[calc(4rem+env(safe-area-inset-top))] md:top-[calc(5rem+env(safe-area-inset-top))] bottom-0 left-0 right-0 z-10">
                        <h1 className="sr-only">Northumberland Photography Weather Map, Rain Radar & Aurora Forecast</h1>
                        
                        <div className="absolute inset-0 z-0">
                            <div ref={mapContainerRef} className="w-full h-full"></div>
                        </div>

                        {/* Floating Toast Notification */}
                        <div className={`absolute top-6 left-1/2 -translate-x-1/2 z-[3000] transition-all duration-300 pointer-events-none ${toastMsg ? 'opacity-100 translate-y-0' : 'opacity-0 -translate-y-4'}`}>
                            <div className="bg-slate-900 text-white px-5 py-3 rounded-full shadow-xl flex items-center gap-2">
                                <Icon name="check" size={16} className="textemerald-400" />
                                <span className="text-[11px] md:text-xs font-bold uppercase tracking-widest">{toastMsg}</span>
                            </div>
                        </div>

                        {/* Search Bar Overlay */}
                        <div ref={searchRef} className={`absolute top-4 md:top-6 left-4 right-4 md:left-6 md:right-auto md:w-[320px] z-[500] transition-all duration-300 ${selectedWebcam || layerMode === 'radar' || layerMode === 'cloud' ? 'opacity-0 pointer-events-none -translate-y-4' : 'opacity-100 translate-y-0'}`}>
                            <form onSubmit={handleSearch} className="relative w-full">
                                <div className="absolute inset-y-0 left-0 pl-3.5 flex items-center pointer-events-none">
                                    <Icon name="search" size={18} className="text-slate-400" />
                                </div>
                                <input 
                                    type="text" 
                                    value={searchQuery}
                                    onChange={(e) => setSearchQuery(e.target.value)}
                                    placeholder="Search for a location..." 
                                    className="w-full bg-white/95 backdrop-blur-md border border-slate-200 text-slate-800 text-[13px] md:text-sm font-bold rounded-2xl pl-10 pr-12 py-3.5 md:py-3 shadow-lg focus:outline-none focus:ring-2 focus:ring-sky-500/50 transition-all placeholder:text-slate-400 placeholder:font-medium"
                                />
                                {isSearching ? (
                                    <div className="absolute inset-y-0 right-0 pr-3.5 flex items-center">
                                        <div className="w-4 h-4 border-2 border-slate-300 border-t-sky-500 rounded-full animate-spin"></div>
                                    </div>
                                ) : searchQuery && (
                                    <button type="button" onClick={() => {setSearchQuery(''); setSearchResults([]);}} className="absolute inset-y-0 right-0 pr-3.5 flex items-center text-slate-400 hover:text-slate-600 transition-colors">
                                        <Icon name="x" size={16} />
                                    </button>
                                )}
                            </form>

                            {/* Search Results Dropdown */}
                            {searchResults.length > 0 && (
                                <div className="absolute top-full left-0 right-0 mt-2 bg-white/95 backdrop-blur-xl border border-slate-200 rounded-2xl shadow-2xl overflow-hidden max-h-[40vh] md:max-h-[50vh] overflow-y-auto custom-scrollbar animate-in slide-in-from-top-2">
                                    {searchResults.map((res, i) => (
                                        <button 
                                            key={i}
                                            onClick={() => handleSelectSearchResult(res)}
                                            className="w-full text-left px-4 py-3 border-b border-slate-100 hover:bg-sky-50 transition-colors flex items-start gap-3 group last:border-0"
                                        >
                                            <Icon name="mapPin" size={16} className="text-slate-400 group-hover:text-sky-500 shrink-0 mt-0.5" />
                                            <div className="flex flex-col">
                                                <span className="text-sm font-bold text-slate-800 line-clamp-1">{res.name}</span>
                                                <span className="text-[10px] font-medium text-slate-500 line-clamp-1 mt-0.5">{res.display_name.split(',').slice(1).join(',').trim()}</span>
                                            </div>
                                        </button>
                                    ))}
                                </div>
                            )}
                        </div>

                        {/* Floating "Select a location" hint */}
                        <div className={`absolute top-[5.5rem] md:top-6 left-1/2 -translate-x-1/2 z-[400] transition-all duration-500 pointer-events-none ${selectedLoc || selectedWebcam || toastMsg || layerMode === 'radar' || layerMode === 'cloud' || searchQuery.length > 0 ? 'opacity-0 -translate-y-4' : 'opacity-100 translate-y-0'}`}>
                            <div className="bg-white/95 backdrop-blur-md px-5 py-3 rounded-full shadow-lg border border-slate-200 flex items-center gap-3">
                                <Icon name="mapPin" size={18} className="text-sky-500 animate-bounce" />
                                <span className="text-[11px] md:text-xs font-black uppercase tracking-widest text-slate-700">Tap anywhere on the map</span>
                            </div>
                        </div>

                        {/* Webcam Live Feed Modal */}
                        {selectedWebcam && (
                            <div className="fixed inset-0 z-[2000] bg-slate-900/80 backdrop-blur-sm flex items-center justify-center p-4 animate-in fade-in" onClick={() => setSelectedWebcam(null)}>
                                <div className="bg-white rounded-2xl shadow-2xl overflow-hidden w-full max-w-4xl flex flex-col" onClick={(e) => e.stopPropagation()}>
                                    <div className="flex items-center justify-between p-4 md:p-5 border-b border-slate-100 bg-slate-50">
                                        <div className="flex items-center gap-3">
                                            <div className="bg-sky-500 text-white p-2.5 rounded-xl shadow-sm">
                                                <Icon name="camera" size={20} />
                                            </div>
                                            <div>
                                                <h3 className="font-black text-lg md:text-xl text-slate-800 leading-none mb-1">{selectedWebcam.name}</h3>
                                                <div className="flex items-center gap-3">
                                                    <span className="text-[9px] md:text-[10px] font-black uppercase tracking-widest text-sky-500 flex items-center gap-1.5">
                                                        <span className="w-1.5 h-1.5 rounded-full bg-red-500 animate-pulse"></span> Live Stream
                                                    </span>
                                                    <a href={getOriginalUrl(selectedWebcam.url)} target="_blank" rel="noopener noreferrer" className="text-[9px] md:text-[10px] font-bold text-slate-500 hover:text-sky-600 underline transition-colors">
                                                        Watch on YouTube &#8599;
                                                    </a>
                                                </div>
                                            </div>
                                        </div>
                                        <button onClick={() => setSelectedWebcam(null)} className="p-2.5 hover:bg-slate-200 rounded-full transition-colors text-slate-500 hover:text-slate-900">
                                            <Icon name="x" size={20} />
                                        </button>
                                    </div>
                                    <div className="w-full aspect-video bg-slate-900 relative">
                                        <iframe 
                                            src={getSafeUrl(selectedWebcam.url)} 
                                            className="absolute inset-0 w-full h-full border-0" 
                                            allowFullScreen 
                                            allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
                                            title={selectedWebcam.name}
                                        ></iframe>
                                    </div>
                                </div>
                            </div>
                        )}

                        {/* Radar/Cloud Playback Controls */}
                        {(layerMode === 'radar' || layerMode === 'cloud') && radarFrames.length > 0 && (
                            <div className="absolute top-4 md:top-6 left-4 md:left-1/2 md:-translate-x-1/2 z-[400] bg-white/95 backdrop-blur-md px-4 py-3 md:px-5 md:py-4 rounded-2xl md:rounded-3xl shadow-xl border border-slate-200 flex flex-col items-center gap-2 md:gap-3 w-[calc(100%-5.5rem)] md:w-[320px] animate-in">
                                <div className="flex items-center justify-between w-full">
                                    <button 
                                        onClick={() => radarFrames.length > 1 && setIsPlaying(!isPlaying)} 
                                        className={`p-2 md:p-2.5 rounded-full transition-colors shadow-sm ${radarFrames.length <= 1 ? 'opacity-50 cursor-not-allowed bg-slate-100 text-slate-400' : (layerMode === 'cloud' ? 'bg-slate-50 text-slate-600 hover:bg-slate-200' : 'bg-sky-50 text-sky-600 hover:bg-sky-100')}`}
                                    >
                                        <Icon name={isPlaying ? "pause" : "play"} size={16} className={isPlaying ? "animate-pulse" : ""} />
                                    </button>
                                    <div className="flex flex-col items-center text-center">
                                        <span className={`text-[8px] md:text-[9px] font-black uppercase tracking-widest ${radarFrames[currentFrame]?.type === 'future' ? 'text-indigo-500' : (layerMode === 'cloud' ? 'text-slate-500' : 'text-sky-500')}`}>
                                            {layerMode === 'cloud' ? 'Satellite Cloud Cover' : (radarFrames[currentFrame]?.type === 'future' ? 'Future Forecast' : 'Past Radar')}
                                        </span>
                                        <span className="text-xs md:text-sm font-bold text-slate-800 font-mono tracking-tight mt-0.5">
                                            {new Date((radarFrames[currentFrame]?.time || 0) * 1000).toLocaleTimeString('en-GB', {timeZone: 'Europe/London', hour: '2-digit', minute:'2-digit'})}
                                        </span>
                                    </div>
                                    <button onClick={() => setLayerMode('standard')} className="p-2 text-slate-400 hover:text-slate-600 hover:bg-slate-100 rounded-full transition-colors">
                                        <Icon name="x" size={16} />
                                    </button>
                                </div>
                                
                                {/* Timeline Bar */}
                                <div className="w-full flex items-center gap-1 mt-1 md:mt-0">
                                    {radarFrames.map((f, i) => {
                                        let activeColor = f.type === 'future' ? 'bg-indigo-500' : 'bg-sky-500';
                                        let inactiveColor = f.type === 'future' ? 'bg-indigo-100' : 'bg-slate-200';
                                        
                                        if (layerMode === 'cloud') {
                                            activeColor = 'bg-slate-600';
                                            inactiveColor = 'bg-slate-200';
                                        }
                                        
                                        return (
                                            <div 
                                                key={i} 
                                                className={`h-1.5 md:h-2 rounded-full transition-all duration-300 flex-1 ${
                                                    i === currentFrame ? `${activeColor} scale-y-125` : inactiveColor
                                                }`} 
                                            />
                                        )
                                    })}
                                </div>
                            </div>
                        )}

                        {/* Right Side Floating Controls */}
                        <div className={`absolute right-4 md:right-6 z-[400] flex flex-col gap-3 transition-all duration-500 ${selectedLoc ? 'bottom-[calc(75vh+1rem+env(safe-area-inset-bottom))] md:bottom-6' : 'bottom-[calc(1.5rem+env(safe-area-inset-bottom))] md:bottom-6'}`}>
                            
                            {/* Topo Legend Control */}
                            {layerMode === 'topo' && (
                                <div className="relative">
                                    {showLegend && (
                                        <div className="absolute bottom-full right-0 mb-3 bg-white/95 backdrop-blur-md rounded-2xl shadow-xl border border-slate-200 p-3 w-56 animate-in origin-bottom-right">
                                            <div className="flex items-center justify-between mb-2 pb-2 border-b border-slate-100">
                                                <span className="text-[10px] font-black uppercase tracking-widest text-slate-500">Topo Map Key</span>
                                                <button onClick={() => setShowLegend(false)} className="text-slate-400 hover:text-slate-700 transition-colors"><Icon name="x" size={14}/></button>
                                            </div>
                                            <div className="space-y-2">
                                                <div className="flex items-center"><span className="w-5 h-0.5 bg-[#a37c58] mr-2"></span><span className="text-[10px] font-bold text-slate-600">Contour Lines (Elevation)</span></div>
                                                <div className="flex items-center"><span className="w-5 h-3 bg-[#c3e6c3] border border-[#a1d6a1] mr-2"></span><span className="text-[10px] font-bold text-slate-600">Forest / Woods</span></div>
                                                <div className="flex items-center"><span className="w-5 h-0.5 bg-[#73c8d4] mr-2"></span><span className="text-[10px] font-bold text-slate-600">Rivers / Lakes</span></div>
                                                <div className="flex items-center"><span className="w-5 h-0.5 border-t-2 border-dashed border-[#ff0000] mr-2"></span><span className="text-[10px] font-bold text-slate-600">Footpaths / Trails</span></div>
                                                <div className="flex items-center"><span className="w-5 h-1 bg-[#ffb3b3] border border-[#ff0000] mr-2"></span><span className="text-[10px] font-bold text-slate-600">Main Roads</span></div>
                                            </div>
                                            <a href="https://opentopomap.org/about#legende" target="_blank" rel="noopener noreferrer" className="mt-3 py-1.5 px-2 bg-slate-50 rounded-lg border border-slate-100 block text-[9px] font-black uppercase tracking-widest text-sky-500 hover:text-sky-600 hover:bg-slate-100 flex items-center justify-center transition-colors no-underline">
                                                Full Legend <Icon name="externalLink" size={12} className="ml-1.5 inline-block" />
                                            </a>
                                        </div>
                                    )}
                                    <button onClick={() => { setShowLegend(!showLegend); setShowLayers(false); setShowSaved(false); }} className={`bg-white p-3.5 rounded-2xl shadow-xl border border-slate-200 transition-all focus:outline-none flex items-center justify-center ${showLegend ? 'text-amber-500' : 'text-slate-700 hover:text-amber-500 hover:scale-105'}`} title="Topo Map Legend">
                                        <Icon name="info" size={24} />
                                    </button>
                                </div>
                            )}

                            {/* Layers Control */}
                            <div className="relative">
                                {showLayers && (
                                    <div className="absolute bottom-full right-0 mb-3 bg-white rounded-2xl shadow-xl border border-slate-200 p-2 w-52 md:w-48 animate-in origin-bottom-right">
                                        <button onClick={() => { setLayerMode('standard'); setShowLayers(false); setShowLegend(false); }} className={`w-full text-left px-4 py-3 rounded-xl text-xs font-bold uppercase tracking-widest transition-colors ${layerMode === 'standard' ? 'bg-sky-50 text-sky-700' : 'hover:bg-slate-50 text-slate-600'}`}>Standard Map</button>
                                        <button onClick={() => { setLayerMode('topo'); setShowLayers(false); setShowLegend(false); }} className={`w-full text-left px-4 py-3 rounded-xl text-xs font-bold uppercase tracking-widest transition-colors mt-1 ${layerMode === 'topo' ? 'bg-emerald-50 text-emerald-700' : 'hover:bg-slate-50 text-slate-600'}`}>Topographic Map</button>
                                        <button onClick={() => { setLayerMode('dark'); setShowLayers(false); setShowLegend(false); }} className={`w-full text-left px-4 py-3 rounded-xl text-xs font-bold uppercase tracking-widest transition-colors mt-1 ${layerMode === 'dark' ? 'bg-slate-800 text-white' : 'hover:bg-slate-50 text-slate-600'}`}>Light Pollution (Astro)</button>
                                        <button onClick={() => { setLayerMode('radar'); setShowLayers(false); setShowLegend(false); }} className={`w-full flex items-center justify-between px-4 py-3 rounded-xl text-xs font-bold uppercase tracking-widest transition-colors mt-1 ${layerMode === 'radar' ? 'bg-indigo-50 text-indigo-700' : 'hover:bg-slate-50 text-slate-600'}`}>
                                            Rain Radar <span className="w-2 h-2 rounded-full bg-red-500 animate-pulse"></span>
                                        </button>
                                        <button onClick={() => { setLayerMode('cloud'); setShowLayers(false); setShowLegend(false); }} className={`w-full flex items-center justify-between px-4 py-3 rounded-xl text-xs font-bold uppercase tracking-widest transition-colors mt-1 ${layerMode === 'cloud' ? 'bg-slate-100 text-slate-900' : 'hover:bg-slate-50 text-slate-600'}`}>
                                            Cloud Cover <Icon name="cloud" size={14} className={layerMode === 'cloud' ? 'text-slate-900' : 'text-slate-400'} />
                                        </button>
                                    </div>
                                )}
                                <button onClick={() => { setShowLayers(!showLayers); setShowSaved(false); setShowLegend(false); }} className={`bg-white p-3.5 rounded-2xl shadow-xl border border-slate-200 transition-all focus:outline-none flex items-center justify-center ${showLayers ? 'text-sky-500' : 'text-slate-700 hover:text-sky-500 hover:scale-105'}`} title="Map Layers">
                                    <Icon name="layers" size={24} />
                                </button>
                            </div>

                            {/* Saved Spots Control */}
                            <div className="relative">
                                {showSaved && (
                                    <div className="absolute bottom-full right-0 mb-3 bg-white rounded-2xl shadow-xl border border-slate-200 p-2 w-64 animate-in origin-bottom-right max-h-64 overflow-y-auto custom-scrollbar">
                                        <div className="px-3 py-2 border-b border-slate-100 mb-1">
                                            <span className="text-[10px] font-black text-slate-400 uppercase tracking-widest">Bookmarked Spots</span>
                                        </div>
                                        {savedSpots.length === 0 ? (
                                            <div className="p-4 text-center text-xs font-medium text-slate-400">No saved locations yet. Tap the heart icon on any pin to save it.</div>
                                        ) : (
                                            savedSpots.map((spot, idx) => (
                                                <button key={idx} onClick={() => { reverseGeocodeAndSelect(spot.lat, spot.lng, false); setShowSaved(false); setShowLegend(false); }} className="w-full text-left px-3 py-3 rounded-xl hover:bg-slate-50 transition-colors flex flex-col group">
                                                    <span className="text-xs font-bold text-slate-700 group-hover:text-sky-600 truncate w-full">{spot.name}</span>
                                                </button>
                                            ))
                                        )}
                                    </div>
                                )}
                                <button onClick={() => { setShowSaved(!showSaved); setShowLayers(false); setShowLegend(false); }} className={`bg-white p-3.5 rounded-2xl shadow-xl border border-slate-200 transition-all focus:outline-none flex items-center justify-center ${showSaved ? 'text-rose-500' : 'text-slate-700 hover:text-rose-500 hover:scale-105'}`} title="Saved Spots">
                                    <Icon name="bookmark" size={24} />
                                    {savedSpots.length > 0 && <span className="absolute top-2 right-2.5 w-2.5 h-2.5 bg-rose-500 rounded-full border-2 border-white"></span>}
                                </button>
                            </div>

                            {/* Locate Me */}
                            <button onClick={handleLocateMe} disabled={isLocating} className={`bg-white p-3.5 rounded-2xl shadow-xl border border-slate-200 transition-all focus:outline-none flex items-center justify-center ${isLocating ? 'text-sky-500 opacity-80' : 'text-slate-700 hover:text-sky-500 hover:scale-105'}`} title="Locate Me">
                                <Icon name="locate" size={24} className={isLocating ? 'animate-pulse' : ''} />
                            </button>
                        </div>

                        {/* Smart Overlay Panel */}
                        <div className={`absolute z-[500] pointer-events-auto bg-white/95 backdrop-blur-2xl shadow-[0_-10px_40px_rgba(0,0,0,0.1)] md:shadow-2xl transition-all duration-500 ease-[cubic-bezier(0.32,0.72,0,1)] flex flex-col
                            ${selectedLoc ? 'translate-y-0 md:translate-x-0 opacity-100' : 'translate-y-full md:translate-y-0 md:-translate-x-[120%] opacity-0 md:opacity-100'}
                            bottom-0 left-0 right-0 h-[75vh] md:h-auto md:top-6 md:bottom-6 md:left-6 md:right-auto md:w-[420px] lg:w-[480px] md:rounded-3xl rounded-t-[2.5rem] border border-slate-200 overflow-hidden`}
                        >
                            {selectedLoc && (
                                <>
                                    <div className="w-full flex justify-center pt-4 pb-2 md:hidden absolute top-0 left-0 bg-white/50 backdrop-blur-md z-20">
                                        <div className="w-12 h-1.5 bg-slate-300/80 rounded-full"></div>
                                    </div>

                                    <button onClick={() => setSelectedLoc(null)} className="absolute top-4 md:top-6 right-4 md:right-6 z-20 p-2.5 bg-white/80 backdrop-blur-md border border-slate-200 hover:bg-slate-100 text-slate-700 rounded-full transition-all shadow-sm hover:scale-105 hidden md:flex">
                                        <Icon name="x" size={20} />
                                    </button>

                                    <div className="flex-1 overflow-y-auto custom-scrollbar p-6 md:p-8 pt-10 md:pt-8 pb-[calc(2rem+env(safe-area-inset-bottom))] md:pb-8 relative z-10">
                                        <button onClick={() => setSelectedLoc(null)} className="flex items-center text-slate-500 hover:text-slate-900 font-bold text-[11px] md:text-xs uppercase tracking-widest mb-5 p-2 -ml-2 transition-colors bg-slate-100/50 rounded-lg pr-4 w-fit">
                                            <Icon name="arrowLeft" size={14} className="mr-2" /> Back to Map
                                        </button>

                                        <div className="flex items-start justify-between gap-4 mb-1">
                                            <h3 className="text-3xl md:text-4xl font-black leading-tight pr-2">{selectedLoc.name}</h3>
                                        </div>
                                        
                                        <div className="flex items-center justify-between mb-6">
                                            <p className="text-[10px] md:text-[11px] text-slate-400 font-mono tracking-widest uppercase flex items-center">
                                                <Icon name="mapPin" size={12} className="mr-1" /> {selectedLoc.lat.toFixed(5)}, {selectedLoc.lng.toFixed(5)}
                                            </p>
                                            
                                            {/* Action Buttons */}
                                            <div className="flex gap-2">
                                                <button onClick={copyShareLink} className="p-2 rounded-xl bg-slate-100 text-slate-600 hover:bg-sky-50 hover:text-sky-600 transition-colors" title="Share Location">
                                                    <Icon name="share" size={16} />
                                                </button>
                                                <button onClick={toggleSaveSpot} className={`p-2 rounded-xl transition-colors ${isSaved ? 'bg-rose-50 text-rose-500' : 'bg-slate-100 text-slate-600 hover:bg-rose-50 hover:text-rose-500'}`} title={isSaved ? "Remove Bookmark" : "Save Spot"}>
                                                    <Icon name={isSaved ? "bookmarkFilled" : "bookmark"} size={16} />
                                                </button>
                                            </div>
                                        </div>
                                        
                                        <div className="space-y-6">
                                            <LiveConditionsWidget lat={selectedLoc.lat} lng={selectedLoc.lng} />
                                            
                                            {isNearHolyIsland(selectedLoc.lat, selectedLoc.lng) && <HolyIslandCrossingWidget />}
                                            
                                            <div className="mt-8 mb-4 border-t border-slate-100 pt-6">
                                                <button onClick={() => setSelectedLoc(null)} className="w-full bg-slate-900 text-white font-bold text-xs uppercase tracking-widest py-4 px-6 rounded-xl hover:bg-slate-800 transition-colors shadow-lg flex items-center justify-center group">
                                                    <Icon name="arrowLeft" size={16} className="mr-3 group-hover:-translate-x-1 transition-transform" /> Back to Map
                                                </button>
                                            </div>
                                        </div>
                                    </div>
                                </>
                            )}
                        </div>
                    </main>
                </div>
            );
        };

        const root = ReactDOM.createRoot(document.getElementById('root'));
        root.render(<App />);
