/**
 * ========================================
 * PARCEL LOCKER SELECTOR MODULE v2.34.0
 * ========================================
 * 
 * Moduł odpowiedzialny za:
 * - Wybór paczkomatu przez użytkownika
 * - Checkbox w marker popup i liście
 * - Status MARKED dla wybranego paczkomatu
 * - Success screen z countdown
 * - Animację bounce spadającej pinezki (3 odbicia)
 * - Ripple effect (żółte i zielone promienie)
 * 
 * @version 2.34.0
 * @author InPost Integration Team
 * @created 2026-01-19
 * @updated 2026-01-20 - Dodano animację bounce z zabezpieczeniami
 * 
 * CHANGELOG v2.34.0 (2026-01-20):
 * ✅ Animacja bounce - pinezka spada i odbija się 3 razy
 * ✅ Ripple effect - żółte i zielone koła rozchodzące się od paczkomatu
 * ✅ Zabezpieczenie przed wielokrotnymi animacjami (globalne flagi)
 * ✅ Null-safety w requestAnimationFrame (graceful exit)
 * ✅ Skalowanie przez width/height zamiast transform (zachowanie Leaflet positioning)
 * ✅ Timing - animacja startuje PO załadowaniu mapy i success panel
 * ✅ Fix scope issue (const self = this zamiast .bind())
 * 
 * KLUCZOWE MECHANIZMY BEZPIECZEŃSTWA:
 * - _bounceAnimationActive: zapobiega duplikacji animacji
 * - _currentAnimatingMarker: śledzi aktualnie animowany marker
 * - Null-check w każdej klatce animacji (marker może zniknąć podczas zoom)
 * - NIE DOTYKAMY marker._icon.style.transform (Leaflet zarządza positioning)
 * 
 * STATUS: ✅ PRODUCTION READY
 */

(function() {
    'use strict';

    // HTML attribute escape — prevents XSS in onclick handlers
    function _escAttr(str) {
        return String(str || '').replace(/&/g,'&amp;').replace(/'/g,'&#39;').replace(/"/g,'&quot;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
    }

    // ====================
    // KONFIGURACJA MODUŁU
    // ====================
    const ParcelLockerSelector = {
        // Wybrany paczkomat
        selectedLocker: null,
        
        // FLAGI ANIMACJI - zapobiegają wielokrotnym wywołaniom
        _bounceAnimationActive: false,
        _currentAnimatingMarker: null,
        
        // Konfiguracja z WordPress (może być nadpisana)
        config: {
            successMessage: 'Dziękujemy za wybranie paczkomatu! Twoja paczka zostanie wysłana po opłaceniu zamówienia.',
            deliveryTime: '2-3 dni robocze',
            countdownSeconds: 18,
            autoClose: true
        },
        
        // Inicjalizacja modułu
        init: function(customConfig) {
            window.PS_DEBUG&&console.log('[Parcel Locker Selector] 🚀 Inicjalizacja modułu');
            
            // Synchronizuj z adminConfig najpierw
            this.syncConfigWithAdmin();
            
            // Merge konfiguracji (customConfig ma najwyższy priorytet)
            if (customConfig) {
                this.config = {...this.config, ...customConfig};
            }
            
            // Dodaj style CSS
            this.injectStyles();
            
            window.PS_DEBUG&&console.log('[Parcel Locker Selector] ✅ Moduł zainicjalizowany');
            window.PS_DEBUG&&console.log('[Parcel Locker Selector] 📝 Config:', this.config);
        },
        
        // Synchronizuj konfigurację z adminConfig z głównego popup
        syncConfigWithAdmin: function() {
            try {
                // Pobierz adminConfig z głównego popup
                if (typeof window.IntroPopup !== 'undefined' && window.IntroPopup.getConfig) {
                    const adminConfig = window.IntroPopup.getConfig();
                    if (adminConfig && adminConfig.parcelLockerSelector) {
                        window.PS_DEBUG&&console.log('[Parcel Locker Selector] 🔄 Synchronizacja z adminConfig');
                        this.config = {...this.config, ...adminConfig.parcelLockerSelector};
                    }
                }
            } catch (error) {
                window.PS_DEBUG&&console.warn('[Parcel Locker Selector] ⚠️ Nie udało się zsynchronizować z adminConfig:', error);
            }
        },
        
        // ====================
        // TWORZENIE POPUP NA MARKERZE
        // ====================
        createMarkerPopup: function(point, labels) {
            labels = labels || {};
            const selectLabel  = labels.selectLabel  || 'WYBIERZ';
            const selectedLabel = labels.selectedLabel || 'OK';
            const isSelected = this.selectedLocker && this.selectedLocker.name === point.name;
            const statusClass = isSelected ? 'marked' : '';
            const ad = point.address_details || {};
            const city = ad.city || '';
            const street = ad.street || '';
            const postCode = ad.post_code || '';
            const buildingNumber = ad.building_number || '';

            return `
                <div class="parcel-locker-popup ${statusClass}">
                    <div class="popup-locker-id">${point.name}</div>
                    <div class="popup-city-postal">
                        <span class="city">${city}</span>
                        <span class="postal">${postCode}</span>
                    </div>
                    <div class="popup-street">
                        ${street}${buildingNumber ? ' ' + buildingNumber : ''}
                    </div>
                    <button class="popup-select-btn ${statusClass}"
                            onclick="event.preventDefault(); event.stopPropagation(); ParcelLockerSelector.selectLocker('${_escAttr(point.name)}', event);"
                            ${isSelected ? 'disabled' : ''}>
                        ${isSelected
                            ? '<span class="checkbox-icon selected-check">&#10003;</span>'
                            : '<span class="checkbox-icon">&#9744;</span>'
                        }
                        <span class="btn-text">${isSelected ? selectedLabel : selectLabel}</span>
                    </button>
                </div>
            `;
        },
        
        // ====================
        // TWORZENIE CHECKBOXA W LIŚCIE
        // ====================
        createListCheckbox: function(point) {
            const isSelected = this.selectedLocker && this.selectedLocker.name === point.name;
            return `
                <div class="list-checkbox ${isSelected ? 'checked' : ''}" 
                     onclick="ParcelLockerSelector.toggleFromList('${_escAttr(point.name)}', event)">
                    <span class="checkbox-icon">${isSelected ? '✅' : '☐'}</span>
                </div>
            `;
        },
        
        // ====================
        // WYBÓR PACZKOMATU Z MARKERA
        // ====================
        /**
         * =================================================================================
         * FUNKCJA: selectLocker(lockerName, event) - WYBÓR PACZKOMATU
         * =================================================================================
         *
         * PROBLEM W PIERWOTNEJ WERSJI:
         * - Funkcja nie wysyłała eventu do WooCommerce
         * - Dane paczkomatu nie trafiały do koszyka
         * - Brak integracji między INTRO a WooCommerce
         *
         * DLACZEGO TO BYŁO PROBLEMATICZNE:
         * - Użytkownik wybierał paczkomat ale dane nie były zapisane
         * - Koszyk pozostawał pusty
         * - Brak feedbacku o udanym wyborze
         *
         * ROZWIĄZANIE W TEJ WERSJI:
         * - Dodano wysyłanie CustomEvent 'inpost-point-selected'
         * - Event zawiera kompletne dane paczkomatu
         * - WooCommerce odbiera i zapisuje do session
         * - Koszyk odświeża się automatycznie
         *
         * PARAMETRY:
         * - lockerName: string - ID paczkomatu (np. "GDY01M")
         * - event: DOM Event - do stopPropagation (zapobiega zamykaniu popupu)
         *
         * DZIAŁANIE SEKWENCYJNE:
         * 1. Stop propagation - zapobiega zamykaniu popupu markera
         * 2. Znajdź paczkomat w allPoints[] z INTRO
         * 3. Ustaw selectedLocker = znaleziony paczkomat
         * 4. Pokaż success screen z countdown
         * 5. Zapisz dane lokalnie (WordPress + localStorage)
         * 6. WYŚLIJ EVENT DO WOOCOMMERCE (CustomEvent)
         *
         * SUCCESS SCREEN TIMING:
         * - Countdown: 10 sekund
         * - Po zakończeniu: zamyka INTRO popup
         * - Użytkownik może zamknąć wcześniej (X button)
         *
         * EVENT DO WOOCOMMERCE:
         * - CustomEvent: 'inpost-point-selected'
         * - Detail: {point: paczkomatData, country: 'pl'}
         * - Odbiorca: paczkomat-modal.js w naszej wtyczce
         *
         * UWAGI DLA PRZYSZŁYCH ROZWOJÓW:
         * - stopPropagation() kluczowe - bez tego popup zamyka się natychmiast
         * - selectedLocker musi być ustawiony PRZED success screen
         * - Event wysyłany PO zapisaniu lokalnym (timing critical)
         * - Testować z różnymi przeglądarkami (CustomEvent support)
         * - Consider error handling jeśli paczkomat nie zostanie znaleziony
         */
        selectLocker: function(lockerName, event) {
            window.PS_DEBUG&&console.log('[Parcel Locker Selector] 📦 WYBIERZ kliknięty dla:', lockerName);
            if (event) event.stopPropagation();

            window.PS_DEBUG&&console.log('[Parcel Locker Selector] 📦 Wybrano paczkomat:', lockerName);
            
            // Znajdź punkt w allPoints (musi być dostępne globalnie)
            if (typeof window.IntroPopup === 'undefined' || !window.IntroPopup.getAllPoints) {
                window.PS_DEBUG&&console.error('[Parcel Locker Selector] ❌ Brak dostępu do IntroPopup.getAllPoints()');
                return;
            }
            
            const allPoints = window.IntroPopup.getAllPoints();
            const point = allPoints.find(p => p.name === lockerName);
            
            if (!point) {
                window.PS_DEBUG&&console.error('[Parcel Locker Selector] ❌ Nie znaleziono punktu:', lockerName);
                return;
            }
            
            // Zapisz wybrany paczkomat
            this.selectedLocker = point;

            // ⏱️ Czas od otwarcia mapy do wyboru paczkomatu
            window._inpostSelectionTime = performance.now();

            // Zapisz czas (sekundy) w ukrytym polu checkout – PHP odczyta przy składaniu zamówienia
            var selSec = window._inpostMapOpenTime
                ? ((window._inpostSelectionTime - window._inpostMapOpenTime) / 1000).toFixed(1)
                : null;
            if (selSec !== null) {
                var hiddenEl = document.getElementById('parcselect_selection_time_seconds');
                if (!hiddenEl) {
                    hiddenEl = document.createElement('input');
                    hiddenEl.type  = 'hidden';
                    hiddenEl.name  = 'parcselect_selection_time_seconds';
                    hiddenEl.id    = 'parcselect_selection_time_seconds';
                    var form = document.querySelector('form.checkout, form#order_review, form.woocommerce-checkout');
                    if (form) form.appendChild(hiddenEl);
                    else document.body.appendChild(hiddenEl);
                }
                hiddenEl.value = selSec;
            }

            // ── SELECTION MODE: chowaj sidebar, footer i instrukcje ──────
            // Opóźnienie 3800ms – najpierw widać zaznaczony checkbox i sukces panel,
            // potem sidebar płynnie znika (1.4s CSS transition).
            var _selPopup = document.getElementById('inpost-universal-popup');
            var _selModeTimer = setTimeout(function() {
                if (_selPopup) _selPopup.classList.add('ps-selection-mode');
            }, 3800);
            // Zapamiętaj timer do anulowania przy ponownym otwarciu mapy
            if (!ParcelLockerSelector._pendingTimers) ParcelLockerSelector._pendingTimers = [];
            ParcelLockerSelector._pendingTimers.push(_selModeTimer);

            // Odśwież UI
            this.refreshUI();

            // Pokaż success screen
            this.showSuccessScreen(point);
            
            // Zapisz do WordPress
            this.saveToWordPress(point);
        },
        
        // ====================
        // TOGGLE Z LISTY (CHECKBOX W PODPOWIEDZIACH)
        // ====================
        toggleFromList: function(lockerName, event) {
            if (event) event.stopPropagation();

            // Jeśli już wybrany - odznacz (BEZ zamykania mapy!)
            if (this.selectedLocker && this.selectedLocker.name === lockerName) {
                window.PS_DEBUG&&console.log('[Parcel Locker Selector] ❌ Odznaczono paczkomat - ukrywam success panel, mapa pozostaje');
                this.selectedLocker = null;
                this.refreshUI();
                // Anuluj countdown jeśli aktywny
                if (this._countdownInterval) {
                    clearInterval(this._countdownInterval);
                    this._countdownInterval = null;
                }
                // Ukryj tylko panel sukcesu - NIE zamykaj mapy
                var panel = document.getElementById('parcel-locker-success');
                if (panel) {
                    panel.style.transition = 'opacity 0.2s ease-out';
                    panel.style.opacity = '0';
                    setTimeout(function() { panel.style.display = 'none'; }, 200);
                }
                return;
            }

            // Wybierz nowy
            this.selectLocker(lockerName, event);
        },
        
        // ====================
        // ZOOM MAPY NA WYBRANY PUNKT + CIĄGŁE PULSOWANIE
        // ====================
        zoomToSelectedPoint: function(point) {
            try {
                // Pobierz mapę z głównego popup
                if (window.IntroPopup && window.IntroPopup.getMap) {
                    const map = window.IntroPopup.getMap();
                    if (map && point.location) {
                        window.PS_DEBUG&&console.log('[Parcel Locker Selector] 🗺️ Start ciągłego zoom na paczkomat:', point.name);
                        
                        // SEKWENCJA ZOOM: stopniowo zwiększaj zoom aż do maksymalnego
                        this.animateMapZoomSequence(map, point, 0);
                        
                        // PULSOWANIE MARKERA przez cały czas
                        this.startContinuousMarkerPulse(point);
                    }
                }
            } catch (error) {
                window.PS_DEBUG&&console.warn('[Parcel Locker Selector] ⚠️ Nie można zoomować mapy:', error);
            }
        },
        
        // ====================
        // SEKWENCJA ZOOM MAPY (ZOOM IN/OUT DO MAKSYMALNEGO)
        // ====================
        animateMapZoomSequence: function(map, point, step) {
            // Zatrzymaj jeśli nie ma już success screen
            if (!document.getElementById('parcel-locker-success') || 
                document.getElementById('parcel-locker-success').style.display === 'none') {
                return;
            }
            
            // Sekwencja zoom levels: 14 → 16 → 15 → 17 → 16 → 18 (MAX)
            const zoomSequence = [
                { zoom: 14, duration: 1.2 },  // Start - zoom out
                { zoom: 16, duration: 1.0 },  // Zoom in
                { zoom: 15, duration: 0.8 },  // Zoom out
                { zoom: 17, duration: 1.0 },  // Zoom in
                { zoom: 16, duration: 0.8 },  // Zoom out
                { zoom: 18, duration: 1.5 }   // MAX ZOOM - zostaje tutaj
            ];
            
            if (step < zoomSequence.length) {
                const current = zoomSequence[step];
                
                map.flyTo([point.location.latitude, point.location.longitude], current.zoom, {
                    duration: current.duration,
                    easeLinearity: 0.25
                });
                
                window.PS_DEBUG&&console.log(`[Parcel Locker Selector] 🔄 Zoom step ${step + 1}/${zoomSequence.length}: zoom ${current.zoom}`);
                
                // Następny krok po zakończeniu animacji
                setTimeout(() => {
                    this.animateMapZoomSequence(map, point, step + 1);
                }, current.duration * 1000 + 200); // +200ms pauzy
            } else {
                window.PS_DEBUG&&console.log('[Parcel Locker Selector] ✅ Zoom sequence zakończona - mapa w MAX ZOOM 18');
            }
        },
        
        // ====================
        // CIĄGŁE PULSOWANIE MARKERA + RIPPLE EFFECT
        // ====================
        // NAPRAWA v2.31.2: Dodano FORCE KEEP VISIBLE + continuous retry
        // ====================
        startContinuousMarkerPulse: function(point, retryCount = 0) {
            try {
                // ✅ ZABEZPIECZENIE GLOBALNE - sprawdź czy animacja już działa!
                if (this._bounceAnimationActive && this._currentAnimatingMarker === point.name) {
                    window.PS_DEBUG&&console.log('[Parcel Locker Selector] ⚠️ Animacja dla', point.name, 'już aktywna - pomijam!');
                    return;
                }
                
                const markers = window.IntroPopup.getMarkers();
                window.PS_DEBUG&&console.log('[Parcel Locker Selector] 📍 Szukam markera dla paczkomatu:', point.name, 'Próba:', retryCount + 1, 'Ilość markerów:', markers ? markers.length : 0);
                
                const marker = markers.find(m => m.pointData && m.pointData.name === point.name);
                
                if (marker && marker._icon) {
                    // 🛡️ USTAW GLOBALNĄ FLAGĘ - animacja aktywna!
                    this._bounceAnimationActive = true;
                    this._currentAnimatingMarker = point.name;
                    
                    // 💛 DODAJ RIPPLE EFFECT (żółte promienie od punktu)
                    this.addRippleEffect(point);
                    
                    // 🔥 AGRESYWNA OCHRONA - FORCE KEEP MARKER VISIBLE!
                    // Ustaw wszystkie style z !important przez cssText
                    marker._icon.style.cssText += `
                        display: block !important;
                        visibility: visible !important;
                        opacity: 1 !important;
                        z-index: 999999 !important;
                        pointer-events: auto !important;
                    `;
                    
                    // 🎯 Dodaj klasę ciągłego pulsowania pinezki
                    marker._icon.classList.add('marker-pulse-continuous');
                    marker._icon.classList.add('force-visible-marker');
                    marker._icon.setAttribute('data-force-visible', 'true');
                    
                    // 🔥 ANIMACJA BOUNCE - 3 ODBICIA! (JavaScript zamiast CSS)
                    window.PS_DEBUG&&console.log('[Parcel Locker Selector] 🔍 DEBUG marker._icon tagName:', marker._icon.tagName);
                    
                    // ULTRA-AGRESYWNE WYMUSZANIE WIDOCZNOŚCI!
                    marker._icon.style.cssText += `
                        display: block !important;
                        visibility: visible !important;
                        opacity: 1 !important;
                        z-index: 999999 !important;
                        position: relative !important;
                    `;
                    
                    // Zachowaj oryginalny Leaflet transform
                    const originalTransform = marker._icon.style.transform;
                    window.PS_DEBUG&&console.log('[Parcel Locker Selector] 🔍 Oryginalny transform:', originalTransform);
                    
                    // Zachowaj context modułu
                    const self = this;
                    
                    // Dodaj cień
                    marker._icon.style.filter = 'drop-shadow(0 8px 16px rgba(0, 0, 0, 0.3))';
                    
                    // Ustaw transform-origin na dół pinezki
                    marker._icon.style.transformOrigin = 'center bottom';
                    
                    // Wrapper dla scale - nie dotykamy Leaflet transform!
                    // Używamy width/height do "scale" wizualnie
                    const originalWidth = marker._icon.offsetWidth;
                    const originalHeight = marker._icon.offsetHeight;
                    
                    // ANIMACJA BOUNCE - JavaScript (nie nadpisuje transform!)
                    const duration = 3000; // 3 sekundy - WOLNIEJ
                    const startTime = Date.now();
                    const baseScale = 2; // BAZOWY ROZMIAR 2X!
                    
                    const animateBounce = () => {
                        // ✅ BEZPIECZEŃSTWO - sprawdź czy marker nadal istnieje!
                        if (!marker._icon) {
                            window.PS_DEBUG&&console.log('[Parcel Locker Selector] ⚠️ Marker zniknął podczas animacji - bezpieczne zatrzymanie');
                            self._bounceAnimationActive = false;
                            self._currentAnimatingMarker = null;
                            return; // Wyjdź bezpiecznie
                        }
                        
                        const elapsed = Date.now() - startTime;
                        const progress = Math.min(elapsed / duration, 1);
                        
                        // DOKŁADNIE 3 ODBICIA
                        let top = 0;
                        let scale = baseScale;
                        
                        if (progress < 0.2) { // Spadanie z góry
                            const t = progress / 0.2;
                            top = -150 * (1 - t);
                            scale = baseScale * 0.8;
                        } else if (progress < 0.35) { // PIERWSZE ODBICIE
                            const t = (progress - 0.2) / 0.15;
                            top = t < 0.5 ? -80 * (t * 2) : -80 * (1 - (t - 0.5) * 2);
                            scale = baseScale * 1.1;
                        } else if (progress < 0.55) { // DRUGIE ODBICIE
                            const t = (progress - 0.35) / 0.2;
                            top = t < 0.5 ? -40 * (t * 2) : -40 * (1 - (t - 0.5) * 2);
                            scale = baseScale * 1.05;
                        } else if (progress < 0.75) { // TRZECIE ODBICIE
                            const t = (progress - 0.55) / 0.2;
                            top = t < 0.5 ? -15 * (t * 2) : -15 * (1 - (t - 0.5) * 2);
                            scale = baseScale * 1.02;
                        } else { // STABILNE 2X
                            top = 0;
                            scale = baseScale;
                        }
                        
                        // Aplikuj bez nadpisywania Leaflet transform!
                        marker._icon.style.top = `${top}px`;
                        
                        // 🎯 SCALE przez width/height zamiast transform!
                        // To nie nadpisze Leaflet translate3d()
                        marker._icon.style.width = `${originalWidth * scale}px`;
                        marker._icon.style.height = `${originalHeight * scale}px`;
                        
                        if (progress < 1) {
                            requestAnimationFrame(animateBounce);
                        } else {
                            window.PS_DEBUG&&console.log('[Parcel Locker Selector] ✅ Bounce zakończony!');
                            marker._icon.style.top = '0px';
                            // 🔓 RESETUJ FLAGĘ - animacja zakończona
                            self._bounceAnimationActive = false;
                            self._currentAnimatingMarker = null;
                        }
                    }; // Normalna funkcja - dostęp do marker przez closure
                    
                    requestAnimationFrame(animateBounce);
                    window.PS_DEBUG&&console.log('[Parcel Locker Selector] 📏 Pinezka odbija się 3 razy (JS)!');
                    
                    // 👁️ POJEDYNCZY MONITORING - nie tworzymy nowych!
                    if (marker._icon.monitoringInterval) {
                        clearInterval(marker._icon.monitoringInterval);
                    }
                    
                    marker._icon.monitoringInterval = setInterval(() => {
                        if (!marker._icon) {
                            window.PS_DEBUG&&console.log('[Parcel Locker Selector] ⚠️ Marker._icon zniknął!');
                            if (marker._icon && marker._icon.monitoringInterval) {
                                clearInterval(marker._icon.monitoringInterval);
                            }
                            return;
                        }
                        
                        // WYMUSZAJ WIDOCZNOŚĆ!
                        if (marker._icon.style.display !== 'block') {
                            marker._icon.style.display = 'block';
                            window.PS_DEBUG&&console.log('[Parcel Locker Selector] 🔧 NAPRAWIAM display!');
                        }
                        if (marker._icon.style.visibility !== 'visible') {
                            marker._icon.style.visibility = 'visible';
                            window.PS_DEBUG&&console.log('[Parcel Locker Selector] 🔧 NAPRAWIAM visibility!');
                        }
                        if (marker._icon.style.opacity !== '1') {
                            marker._icon.style.opacity = '1';
                            window.PS_DEBUG&&console.log('[Parcel Locker Selector] 🔧 NAPRAWIAM opacity!');
                        }
                    }, 100);
                    
                    // 🔥 KLUCZOWE: NIE ZAMYKAJ POPUPU! (to resetuje marker i pinezka znika)
                    // Zamiast zamykać - UKRYJ popup wizualnie CSS
                    if (marker.isPopupOpen()) {
                        const popup = marker.getPopup();
                        if (popup && popup._container) {
                            popup._container.style.display = 'none'; // Ukryj popup ale NIE zamykaj
                            window.PS_DEBUG&&console.log('[Parcel Locker Selector] 👻 Ukryto popup (ale NIE zamknięto - marker ZOSTAJE!)');
                        }
                    }
                    
                    // Zapisz reference do późniejszego usunięcia
                    this._pulsingMarker = marker;
                    this._pulsingPoint = point; // Zapisz punkt dla retry
                    
                    window.PS_DEBUG&&console.log('[Parcel Locker Selector] ✅ Start ciągłego pulsowania markera:', point.name);
                    window.PS_DEBUG&&console.log('[Parcel Locker Selector] 💛 Dodano ripple effect (żółte promienie)');
                    window.PS_DEBUG&&console.log('[Parcel Locker Selector] 🔒 AGRESYWNA OCHRONA - marker NIE MOŻE zniknąć!');
                    window.PS_DEBUG&&console.log('[Parcel Locker Selector] Klasy markera:', marker._icon.className);
                    window.PS_DEBUG&&console.log('[Parcel Locker Selector] Computed style display:', window.getComputedStyle(marker._icon).display);
                    window.PS_DEBUG&&console.log('[Parcel Locker Selector] Computed style visibility:', window.getComputedStyle(marker._icon).visibility);
                    
                    // 🚨 AGRESYWNY MONITOR - sprawdzaj co 200ms WSZYSTKIE właściwości!
                    if (this._pulseMonitor) {
                        clearInterval(this._pulseMonitor);
                    }
                    
                    // 🔍 ULTRA DEBUG - co 100ms szczegółowy raport
                    let debugCounter = 0;
                    this._pulseMonitor = setInterval(() => {
                        debugCounter++;
                        
                        if (this._pulsingMarker && this._pulsingMarker._icon) {
                            const icon = this._pulsingMarker._icon;
                            const computed = window.getComputedStyle(icon);
                            
                            // Raport co 5 sekund (50 * 100ms)
                            if (debugCounter % 50 === 0) {
                                window.PS_DEBUG&&console.log('[MARKER DEBUG] ==================');
                                window.PS_DEBUG&&console.log('[MARKER DEBUG] Marker ISTNIEJE');
                                window.PS_DEBUG&&console.log('[MARKER DEBUG] Display:', computed.display, '| Style:', icon.style.display);
                                window.PS_DEBUG&&console.log('[MARKER DEBUG] Visibility:', computed.visibility, '| Style:', icon.style.visibility);
                                window.PS_DEBUG&&console.log('[MARKER DEBUG] Opacity:', computed.opacity, '| Style:', icon.style.opacity);
                                window.PS_DEBUG&&console.log('[MARKER DEBUG] Transform:', computed.transform);
                                window.PS_DEBUG&&console.log('[MARKER DEBUG] Position:', computed.position, '| Top:', computed.top, '| Left:', computed.left);
                                window.PS_DEBUG&&console.log('[MARKER DEBUG] Z-index:', computed.zIndex);
                                window.PS_DEBUG&&console.log('[MARKER DEBUG] Width:', computed.width, '| Height:', computed.height);
                                window.PS_DEBUG&&console.log('[MARKER DEBUG] Klasy:', icon.className);
                                window.PS_DEBUG&&console.log('[MARKER DEBUG] W DOM:', document.body.contains(icon));
                                window.PS_DEBUG&&console.log('[MARKER DEBUG] Parent:', icon.parentElement ? icon.parentElement.className : 'BRAK');
                                window.PS_DEBUG&&console.log('[MARKER DEBUG] ==================');
                            }
                            
                            let needsFix = false;
                            
                            // Sprawdź WSZYSTKIE właściwości
                            if (computed.display === 'none' || icon.style.display === 'none') {
                                window.PS_DEBUG&&console.error('[Parcel Locker Selector] 🚨 MARKER UKRYTY (display: none) - PRZYWRACAM!');
                                needsFix = true;
                            }
                            
                            if (computed.visibility === 'hidden' || icon.style.visibility === 'hidden') {
                                window.PS_DEBUG&&console.error('[Parcel Locker Selector] 🚨 MARKER UKRYTY (visibility: hidden) - PRZYWRACAM!');
                                needsFix = true;
                            }
                            
                            if (parseFloat(computed.opacity) < 0.1) {
                                window.PS_DEBUG&&console.error('[Parcel Locker Selector] 🚨 MARKER PRZEZROCZYSTY (opacity < 0.1) - PRZYWRACAM!');
                                needsFix = true;
                            }
                            
                            if (!icon.classList.contains('marker-pulse-continuous')) {
                                window.PS_DEBUG&&console.error('[Parcel Locker Selector] 🚨 MARKER STRACIŁ KLASĘ - PRZYWRACAM!');
                                needsFix = true;
                            }
                            
                            // Sprawdź czy marker jest w DOM
                            if (!document.body.contains(icon)) {
                                window.PS_DEBUG&&console.error('[Parcel Locker Selector] 🚨 MARKER USUNIĘTY Z DOM!');
                                needsFix = true;
                            }
                            
                            // PRZYWRÓĆ jeśli coś jest nie tak
                            if (needsFix) {
                                icon.style.cssText += `
                                    display: block !important;
                                    visibility: visible !important;
                                    opacity: 1 !important;
                                    z-index: 999999 !important;
                                    pointer-events: auto !important;
                                `;
                                icon.classList.add('marker-pulse-continuous');
                                icon.classList.add('force-visible-marker');
                                window.PS_DEBUG&&console.log('[Parcel Locker Selector] ✅ Marker przywrócony!');
                                window.PS_DEBUG&&console.log('[Parcel Locker Selector] Nowy display:', window.getComputedStyle(icon).display);
                                window.PS_DEBUG&&console.log('[Parcel Locker Selector] Nowa visibility:', window.getComputedStyle(icon).visibility);
                            }
                        } else {
                            // Marker zniknął całkowicie - NIE URUCHAMIAJ PONOWNIE ANIMACJI!
                            // (zachowaj widoczność ale bez bounce - już był raz)
                            window.PS_DEBUG&&console.error('[Parcel Locker Selector] 🚨 MARKER ZNIKNĄŁ Z DOM - zachowuję czystość (bez re-animacji)');
                        }
                    }, 100); // Co 100ms - bardzo agresywne!
                    
                } else {
                    // RETRY LOGIC - próbuj ponownie jeśli markery jeszcze nie załadowane
                    // ALE tylko jeśli animacja nie jest aktywna!
                    if (retryCount < 10 && !this._bounceAnimationActive) { // Zwiększono do 10 prób
                        window.PS_DEBUG&&console.warn('[Parcel Locker Selector] ⚠️ Marker nie znaleziony, próbuję ponownie za 200ms...');
                        setTimeout(() => {
                            this.startContinuousMarkerPulse(point, retryCount + 1);
                        }, 200);
                    } else {
                        window.PS_DEBUG&&console.error('[Parcel Locker Selector] ❌ Nie znaleziono markera po 10 próbach:', point.name);
                    }
                }
            } catch (error) {
                window.PS_DEBUG&&console.warn('[Parcel Locker Selector] ⚠️ Nie można uruchomić pulsowania:', error);
            }
        },
        
        // ====================
        // RIPPLE EFFECT - ŻÓŁTE PROMIENIE OD PUNKTU
        // ====================
        // OPIS: Tworzy 3 żółte kręgi rozchodzące się od wybranego punktu na mapie
        // Efekt "fal na wodzie" - subtelny ale wyraźny, potwierdza wybór
        // NAPRAWA v2.31.2: Użyj CSS DIV overlay zamiast L.circle (100% kompatybilne)
        // ====================
        addRippleEffect: function(point) {
            try {
                const map = window.IntroPopup.getMap();
                if (!map) {
                    window.PS_DEBUG&&console.warn('[Parcel Locker Selector] ⚠️ Brak mapy dla ripple effect');
                    return;
                }
                
                const lat = point.location.latitude;
                const lng = point.location.longitude;
                
                window.PS_DEBUG&&console.log('[Parcel Locker Selector] 💛 Tworzenie ripple effect (CSS DIV) na:', lat, lng);
                
                // Usuń stare ripple jeśli istnieją
                if (this._rippleElements) {
                    this._rippleElements.forEach(el => el.remove());
                }
                this._rippleElements = [];
                
                // Znajdź kontener mapy
                const mapContainer = map.getContainer();
                if (!mapContainer) return;
                
                // Utwórz 3 ŻÓŁTE kręgi z różnymi opóźnieniami
                for (let i = 0; i < 3; i++) {
                    setTimeout(() => {
                        // Konwertuj współrzędne na pixel position
                        const point2D = map.latLngToContainerPoint([lat, lng]);
                        
                        // Twórz CSS DIV ripple
                        const ripple = document.createElement('div');
                        ripple.className = 'parcel-ripple-effect';
                        ripple.style.cssText = `
                            position: absolute;
                            left: ${point2D.x}px;
                            top: ${point2D.y}px;
                            width: 20px;
                            height: 20px;
                            margin-left: -10px;
                            margin-top: -10px;
                            border: 3px solid #FFD700;
                            border-radius: 50%;
                            background: rgba(255, 215, 0, 0.2);
                            pointer-events: none;
                            z-index: 9998;
                            animation: rippleExpand 2s ease-out forwards;
                        `;
                        
                        mapContainer.appendChild(ripple);
                        this._rippleElements.push(ripple);
                        
                        // Usuń po animacji
                        setTimeout(() => {
                            ripple.remove();
                            const index = this._rippleElements.indexOf(ripple);
                            if (index > -1) {
                                this._rippleElements.splice(index, 1);
                            }
                        }, 2000);
                        
                    }, i * 400); // Opóźnienie między kręgami: 400ms
                }
                
                // 🟢 ZIELONY RIPPLE na końcu (po 2 sekundach) - POTWIERDZENIE!
                setTimeout(() => {
                    const point2D = map.latLngToContainerPoint([lat, lng]);
                    
                    // Utwórz 2 zielone kręgi (mniejsze, subtelne)
                    for (let i = 0; i < 2; i++) {
                        setTimeout(() => {
                            const greenRipple = document.createElement('div');
                            greenRipple.className = 'parcel-ripple-effect parcel-green-ripple';
                            greenRipple.style.cssText = `
                                position: absolute;
                                left: ${point2D.x}px;
                                top: ${point2D.y}px;
                                width: 30px;
                                height: 30px;
                                margin-left: -15px;
                                margin-top: -15px;
                                border: 3px solid #10b981;
                                border-radius: 50%;
                                background: rgba(16, 185, 129, 0.3);
                                pointer-events: none;
                                z-index: 9999;
                            `;
                            
                            mapContainer.appendChild(greenRipple);
                            this._rippleElements.push(greenRipple);
                            
                            // Usuń po animacji
                            setTimeout(() => {
                                greenRipple.remove();
                                const index = this._rippleElements.indexOf(greenRipple);
                                if (index > -1) this._rippleElements.splice(index, 1);
                            }, 1500);
                        }, i * 300);
                    }
                }, 2000); // Start po 2 sekundach (po żółtych)
                
                window.PS_DEBUG&&console.log('[Parcel Locker Selector] ✨ Ripple effect uruchomiony: 3 żółte + 2 zielone (na końcu)');
                
            } catch (error) {
                window.PS_DEBUG&&console.warn('[Parcel Locker Selector] ⚠️ Błąd ripple effect:', error);
            }
        },
        
        // ====================
        // ZATRZYMAJ PULSOWANIE MARKERA + RIPPLE
        // ====================
        stopMarkerPulse: function() {
            // Zatrzymaj pulse monitor
            if (this._pulseMonitor) {
                clearInterval(this._pulseMonitor);
                this._pulseMonitor = null;
                window.PS_DEBUG&&console.log('[Parcel Locker Selector] 🛑 Zatrzymano pulse monitor');
            }
            
            // Usuń pulsowanie pinezki
            if (this._pulsingMarker && this._pulsingMarker._icon) {
                this._pulsingMarker._icon.classList.remove('marker-pulse-continuous');
                this._pulsingMarker._icon.classList.remove('force-visible-marker');
                this._pulsingMarker = null;
                this._pulsingPoint = null;
                window.PS_DEBUG&&console.log('[Parcel Locker Selector] ⏹️ Stop pulsowania markera');
            }
            
            // 💛 Usuń ripple effect DIVs
            if (this._rippleElements) {
                this._rippleElements.forEach(el => {
                    try {
                        el.remove();
                    } catch (e) {
                        // Ignore if already removed
                    }
                });
                this._rippleElements = [];
                window.PS_DEBUG&&console.log('[Parcel Locker Selector] 💛 Usunięto ripple effect DIVs');
            }
        },
        
        // ====================
        // ODŚWIEŻENIE UI (CHECKBOXY + MARKERY + STATUS)
        // ====================
        refreshUI: function() {
            window.PS_DEBUG&&console.log('[Parcel Locker Selector] 🔄 Odświeżanie UI');
            
            // Odśwież wszystkie checkboxy w liście
            document.querySelectorAll('.list-checkbox').forEach(checkbox => {
                const isChecked = checkbox.classList.contains('checked');
                const shouldBeChecked = this.selectedLocker && 
                    checkbox.closest('.inpost-point-item')?.textContent.includes(this.selectedLocker.name);
                
                if (shouldBeChecked && !isChecked) {
                    checkbox.classList.add('checked');
                    checkbox.querySelector('.checkbox-icon').textContent = '✅';
                } else if (!shouldBeChecked && isChecked) {
                    checkbox.classList.remove('checked');
                    checkbox.querySelector('.checkbox-icon').textContent = '☐';
                }
            });
            
            // Odśwież status panel na dole
            this.updateStatusPanel();
            
            // Odśwież wszystkie markery popup (wymaga przeładowania)
            if (window.IntroPopup && window.IntroPopup.refreshMarkers) {
                window.IntroPopup.refreshMarkers();
            }
        },
        
        // ====================
        // SUCCESS SCREEN Z COUNTDOWN + ZOOM NA MAPIE
        // ====================
        showSuccessScreen: function(point) {
            window.PS_DEBUG&&console.log('[Parcel Locker Selector] SEKWENCJA: ZOOM 1500ms → delay 500ms → success panel');

            // KROK 1: ZOOM MAPY NA WYBRANY PUNKT (1500ms)
            this.zoomToSelectedPointSmooth(point);

            // KROK 2: Poczekaj na zakończenie zoomu + bezpieczny delay
            // +800ms żeby marker popup (Leaflet) był widoczny dłużej przed success panelem
            var _showTimer = setTimeout(() => {
                this.displaySuccessPanel(point);
            }, 3300);
            if (!ParcelLockerSelector._pendingTimers) ParcelLockerSelector._pendingTimers = [];
            ParcelLockerSelector._pendingTimers.push(_showTimer);
        },
        
        // ====================
        // PŁYNNY ZOOM DO PUNKTU (1500ms)
        // ====================
        // NAPRAWA v2.31.4: startContinuousMarkerPulse PRZED zoom + ponownie PO zoom
        // ====================
        zoomToSelectedPointSmooth: function(point) {
            try {
                if (window.IntroPopup && window.IntroPopup.getMap) {
                    const map = window.IntroPopup.getMap();
                    if (map && point.location) {
                        window.PS_DEBUG&&console.log('[Parcel Locker Selector] 🗺️ ZOOM 1500ms na:', point.name);
                        
                        // ⏸️ Animacja bounce będzie uruchomiona DOPIERO po pokazaniu success panel
                        // (żeby mapa i UI były już gotowe)
                        
                        // PŁYNNY ZOOM do poziomu 17 (1500ms)
                        map.flyTo([point.location.latitude, point.location.longitude], 17, {
                            duration: 1.5,  // 1500ms!
                            easeLinearity: 0.2
                        });
                        
                        // 🔄 Listener na moveend - tylko logowanie (animacja będzie później)
                        const onMoveEnd = () => {
                            window.PS_DEBUG&&console.log('[Parcel Locker Selector] ✅ Zoom zakończony - mapa gotowa!');
                            // Usuń listener (tylko raz)
                            map.off('moveend', onMoveEnd);
                        };
                        
                        map.once('moveend', onMoveEnd);
                    }
                }
            } catch (error) {
                window.PS_DEBUG&&console.warn('[Parcel Locker Selector] ⚠️ Nie można zoomować mapy:', error);
            }
        },
        
        // ====================
        // WYŚWIETL SUCCESS PANEL (po zoomie)
        // ====================
        displaySuccessPanel: function(point) {
            window.PS_DEBUG&&console.log('[Parcel Locker Selector] 🎉 Pokazuję success panel');
            
            // ⏰ Opóźnij start animacji bounce o 800ms - żeby panel się załadował!
            setTimeout(() => {
                window.PS_DEBUG&&console.log('[Parcel Locker Selector] 🎬 START ANIMACJI BOUNCE - wszystko gotowe!');
                this.startContinuousMarkerPulse(point);
            }, 800);
            
            // �️ PŁYNNY ZOOM DO MAKSIMUM (18) przy success panel
            if (window.inpostPopup && window.inpostPopup.map) {
                const map = window.inpostPopup.map;
                const currentZoom = map.getZoom();
                const maxZoom = 20; // ABSOLUTNE MAKSIMUM dla super zbliżenia
                
                if (currentZoom < maxZoom) {
                    window.PS_DEBUG&&console.log(`[Parcel Locker Selector] 🔍 PŁYNNY ZOOM DO MAX: ${currentZoom} → ${maxZoom}`);
                    map.flyTo([point.location.latitude, point.location.longitude], maxZoom, {
                        duration: 4.0,  // 4 sekundy WOLNEGO płynnego zooma
                        easeLinearity: 0.1  // Bardzo płynne przejście
                    });
                }
            }
            
            // 🟢 ZMIEŃ PINEZKĘ NA ZIELONĄ + PROMIEŃ ŚWIETLNY (success state)
            const markers = window.inpostPopup?.currentMarkers || [];
            const marker = markers.find(m => m.pointData.name === point.name);
            if (marker && marker._icon) {
                marker._icon.classList.add('marker-success');
                
                window.PS_DEBUG&&console.log('[Parcel Locker Selector] 🔍 DEBUG success marker tagName:', marker._icon.tagName);
                
                // ULTRA-AGRESYWNE WYMUSZANIE WIDOCZNOŚCI!
                marker._icon.style.cssText += `
                    display: block !important;
                    visibility: visible !important;
                    opacity: 1 !important;
                    z-index: 999999 !important;
                    position: relative !important;
                `;
                
                // Zachowaj oryginalny Leaflet transform
                const originalTransform = marker._icon.style.transform;
                window.PS_DEBUG&&console.log('[Parcel Locker Selector] 🔍 Oryginalny transform (green):', originalTransform);
                
                // ZIELONY KOLOR + EFEKTY ŚWIETLNE
                marker._icon.style.filter = 'hue-rotate(95deg) saturate(2.0) brightness(1.3) drop-shadow(0 0 20px rgba(16, 185, 129, 0.9)) drop-shadow(0 8px 16px rgba(0, 0, 0, 0.3))';
                
                // ANIMACJA BOUNCE ZIELONA - JavaScript
                const duration = 3000; // 3 sekundy - WOLNIEJ
                const startTime = Date.now();
                const baseScale = 2; // BAZOWY ROZMIAR 2X!
                
                const animateBounceGreen = () => {
                    const elapsed = Date.now() - startTime;
                    const progress = Math.min(elapsed / duration, 1);
                    
                    // DOKŁADNIE 3 ODBICIA
                    let top = 0;
                    let scale = baseScale;
                    
                    if (progress < 0.2) { // Spadanie
                        const t = progress / 0.2;
                        top = -150 * (1 - t);
                        scale = baseScale * 0.8;
                    } else if (progress < 0.35) { // PIERWSZE ODBICIE
                        const t = (progress - 0.2) / 0.15;
                        top = t < 0.5 ? -80 * (t * 2) : -80 * (1 - (t - 0.5) * 2);
                        scale = baseScale * 1.1;
                    } else if (progress < 0.55) { // DRUGIE ODBICIE
                        const t = (progress - 0.35) / 0.2;
                        top = t < 0.5 ? -40 * (t * 2) : -40 * (1 - (t - 0.5) * 2);
                        scale = baseScale * 1.05;
                    } else if (progress < 0.75) { // TRZECIE ODBICIE
                        const t = (progress - 0.55) / 0.2;
                        top = t < 0.5 ? -15 * (t * 2) : -15 * (1 - (t - 0.5) * 2);
                        scale = baseScale * 1.02;
                    } else { // STABILNE 2X ZIELONE
                        top = 0;
                        scale = baseScale;
                    }
                    
                    marker._icon.style.top = `${top}px`;
                    
                    if (originalTransform && originalTransform !== 'none') {
                        marker._icon.style.transform = `${originalTransform} scale(${scale})`;
                    } else {
                        marker._icon.style.transform = `scale(${scale})`;
                    }
                    
                    if (progress < 1) {
                        requestAnimationFrame(animateBounceGreen);
                    } else {
                        marker._icon.style.top = '0px';
                        window.PS_DEBUG&&console.log('[Parcel Locker Selector] ✅ Zielony bounce zakończony!');
                    }
                };
                
                requestAnimationFrame(animateBounceGreen);
                
                // Dodaj ZIELONY PROMIEŃ ŚWIETLNY po 2.5s
                setTimeout(() => {
                    const beam = document.createElement('div');
                    beam.className = 'green-beam';
                    beam.style.cssText = `
                        position: absolute;
                        left: 50%;
                        bottom: 0;
                        width: 2px;
                        height: 100px;
                        background: linear-gradient(to top, rgba(16, 185, 129, 0.9), rgba(16, 185, 129, 0));
                        box-shadow: 0 0 20px rgba(16, 185, 129, 0.8);
                        transform: translateX(-50%);
                        animation: beamPulse 2s ease-in-out infinite;
                        pointer-events: none;
                        z-index: 9999;
                    `;
                    marker._icon.parentElement.appendChild(beam);
                    window.PS_DEBUG&&console.log('[Parcel Locker Selector] 🌟 ZIELONY PROMIEŃ dodany!');
                }, 2500);
                
                window.PS_DEBUG&&console.log('[Parcel Locker Selector] 🟢 Pinezka ZIELONA + bounce + promień!');
            }
            
            /**
             * =================================================================================
             * NAPRAWA: Success Panel - upewnij się że jest WEWNĄTRZ popupu
             * =================================================================================
             * 
             * PROBLEM: Success panel był dodawany do document.body jeśli nie znaleziono
             * kontenera mapy, co powodowało że panel opuszczał mapę INTRO_1.
             * 
             * ROZWIĄZANIE:
             * 1. Zawsze dodawaj panel do #inpost-universal-popup (główny kontener popupu)
             * 2. Upewnij się że popup ma position: relative
             * 3. Success panel będzie position: absolute względem popupu
             * 4. z-index niższy niż popup overlay (zwykle 9999), ale wyższy niż mapa
             * 
             * WNIOSKI:
             * - NIE dodawaj elementów do document.body jeśli są częścią popupu
             * - Zawsze sprawdzaj czy kontener popupu istnieje
             * - Używaj position: relative na kontenerze, absolute na dziecku
             * 
             * STATUS: ✅ NAPRAWIONE
             */
            let panel = document.getElementById('parcel-locker-success');
            if (!panel) {
                panel = document.createElement('div');
                panel.id = 'parcel-locker-success';
                panel.className = 'parcel-success-panel';
                
                // Dodaj panel DO KONTENERA MAPY (nie do całego popupu!)
                // Dzięki temu panel jest wewnątrz mapy i nie wylatuje na bok
                const mapContainer = document.querySelector('.inpost-popup-map-container');
                if (mapContainer) {
                    mapContainer.style.position = 'relative';
                    mapContainer.appendChild(panel);
                    window.PS_DEBUG&&console.log('[Parcel Locker Selector] ✅ Success panel dodany do .inpost-popup-map-container');
                } else {
                    const popupContainer = document.getElementById('inpost-universal-popup');
                    if (popupContainer) {
                        popupContainer.appendChild(panel);
                        window.PS_DEBUG&&console.log('[Parcel Locker Selector] ⚠️ Success panel dodany do #inpost-universal-popup (fallback)');
                    } else {
                        window.PS_DEBUG&&console.error('[Parcel Locker Selector] ❌ Brak kontenera dla success panel!');
                        return;
                    }
                }
            }
            
            // Helper – pobiera tłumaczenie z IntroPopup (z fallbackiem)
            var T = function(key, fallback) {
                if (window.IntroPopup && window.IntroPopup.translate) {
                    var result = window.IntroPopup.translate(key);
                    if (result && result !== key) return result;
                }
                return fallback;
            };

            var ad = point.address_details || {};

            // Zawartość success screen (floating panel)
            panel.innerHTML = `
                <div class="parcel-success-container">
                    <!-- Close button -->
                    <button class="success-close-btn" onclick="ParcelLockerSelector.hideSuccessScreen()" title="${T('closeButton','Zamknij')}">
                        &#10005;
                    </button>

                    <!-- Ikona sukcesu - PULSUJACY ZIELONY KRAG Z RYSUJACYM SIE FISTASZKIEM -->
                    <div class="success-icon pulsing-checkmark">
                        <svg class="check-svg" width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
                            <path class="check-path" d="M9 20L17 28L31 12" stroke="white" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
                        </svg>
                    </div>

                    <!-- Tytul -->
                    <h2 class="success-title">${T('successPanelTitle','Paczkomat wybrany!')}</h2>

                    <!-- Komunikat -->
                    <div class="success-message">${T('successTitle', this.config.successMessage)}</div>

                    <!-- Wybrany paczkomat -->
                    <div class="success-locker-info">
                        <div class="locker-name">${point.name}</div>
                        <div class="locker-address">
                            &#128206; ${ad.post_code || ''}<br>
                            &#128205; ${ad.city || ''}${ad.street ? ', ' + ad.street : ''}${ad.building_number ? ' ' + ad.building_number : ''}
                        </div>
                    </div>

                    <!-- Czas dostawy -->
                    <div class="success-delivery-time">
                        &#9203; ${T('successDeliveryLabel','Szacowany czas dostawy:')} <strong>${this.config.deliveryTime}</strong>
                    </div>

                    <!-- Countdown -->
                    ${this.config.autoClose ? `
                        <div class="success-countdown">
                            ${T('successCountdown','Okno zamknie sie automatycznie za')}
                            <span id="countdown-timer">${this.config.countdownSeconds}</span>
                            ${T('successSeconds','sekund')}
                        </div>
                    ` : ''}

                    <!-- Czas do wyboru paczkomatu (od otwarcia mapy) -->
                    <div style="text-align:center;margin-bottom:0">
                        <span class="success-finish-time" id="success-finish-time">&#127937; ${(window._inpostMapOpenTime && window._inpostSelectionTime)
                            ? ((window._inpostSelectionTime - window._inpostMapOpenTime) / 1000).toFixed(1) + 's'
                            : '&#8211;'}</span>
                    </div>

                    <!-- Stopwatch: czas od wyboru paczkomatu -->
                    <div class="success-stopwatch" id="success-stopwatch">
                        <span class="stopwatch-label">&#9201; Od wyboru:</span>
                        <span class="stopwatch-value" id="stopwatch-value">0.0s</span>
                    </div>

                    <!-- Przyciski -->
                    <div class="success-buttons">
                        <button class="success-btn-change" onclick="ParcelLockerSelector.clearSelection()">
                            &#128260; ${T('successBtnChange','Zmień paczkomat')}
                        </button>
                    </div>
                </div>
            `;
            
            // Pokaż panel niewidocznie żeby zmierzyć jego wysokość
            panel.style.visibility = 'hidden';
            panel.style.display    = 'block';

            // Panel ma position:fixed – liczymy współrzędne VIEWPORT (nie kontenera mapy)
            // Pozycja: GÓRA mapy (nie środek!), lewa krawędź to prawa krawędź mapy - szerokość panelu.
            // Repozycjonujemy też PO zakończeniu ps-selection-mode transition (~3800+1400ms).
            var _positionPanel = function() {
                try {
                    var mapEl2 = document.querySelector('.inpost-popup-map-container');
                    if (!mapEl2) return;
                    var rect2 = mapEl2.getBoundingClientRect();
                    var pw2   = panel.offsetWidth  || 292;
                    var ph2   = panel.offsetHeight || 460;
                    var margin2 = 20;

                    // Wycentruj panel pionowo względem widocznej mapy
                    // (ta sama oś co tooltip+pin na lewo od panelu)
                    var mapH2  = rect2.height;
                    var topIdeal = rect2.top + (mapH2 - ph2) / 2;

                    // Nie wyżej niż margin2 od góry mapy i nie niżej niż margin2 od dołu
                    var top2  = Math.max(rect2.top + margin2, Math.min(topIdeal, rect2.bottom - ph2 - margin2));
                    var left2 = rect2.right - pw2 - margin2;

                    // Clamp do granic viewport
                    top2  = Math.max(margin2, Math.min(top2,  window.innerHeight - ph2 - margin2));
                    left2 = Math.max(margin2, Math.min(left2, window.innerWidth  - pw2 - margin2));

                    panel.style.top   = top2  + 'px';
                    panel.style.left  = left2 + 'px';
                    panel.style.right = 'auto';
                } catch (e) {}
            };

            requestAnimationFrame(function() {
                _positionPanel();

                // Pokaż panel po pozycjonowaniu
                panel.style.visibility = 'visible';

                // Repozycjonuj po zakończeniu ps-selection-mode transition
                // (ps-selection-mode dodawany 3800ms po selectLocker, transition 1.4s → łącznie ~5.2s od selection)
                // displaySuccessPanel wywołany po 3300ms, więc tutaj dodajemy ~2000ms na resztę transition
                setTimeout(_positionPanel, 2000);
                setTimeout(_positionPanel, 3500);

                // 🗺️ Wymuś przerenderowanie mapy Leaflet (uzupełni puste kafelki po rozciągnięciu)
                try {
                    var leafMapInv = window.IntroPopup && window.IntroPopup.getMap ? window.IntroPopup.getMap() : null;
                    if (leafMapInv) {
                        leafMapInv.invalidateSize({ animate: false });
                        setTimeout(function() { leafMapInv.invalidateSize({ animate: false }); }, 300);
                    }
                } catch(e) {}

                // Konfetti z centrum ikony
                ParcelLockerSelector.spawnConfetti(panel);

                // ── ZIELONY PULSUJĄCY KRĄG na wybranym punkcie ────────────
                ParcelLockerSelector.addSuccessRing(point);

                // ── KINEMATYCZNY NAJAZD – po zakończeniu ps-selection-mode transition ─
                // ps-selection-mode dodawany ~500ms od displaySuccessPanel, transition 1.4s
                // → mapa ma FINALNE wymiary dopiero po ~1900ms → startujemy po 2100ms
                setTimeout(function() {
                    try {
                        var leafMap = window.IntroPopup && window.IntroPopup.getMap
                            ? window.IntroPopup.getMap() : null;
                        if (!leafMap || !point.location) return;

                        var ptLat = point.location.latitude;
                        var ptLng = point.location.longitude;

                        // Pobierz FINALNE wymiary mapy i panelu z DOM
                        var mapSize  = leafMap.getSize();
                        var panelEl3 = document.getElementById('parcel-locker-success');
                        var pw3      = (panelEl3 ? panelEl3.offsetWidth  : 0) || 292;
                        var ph3      = (panelEl3 ? panelEl3.offsetHeight : 0) || 460;
                        var margin3  = 20;

                        // Wymuś invalidateSize żeby Leaflet znał nowy rozmiar kontenera
                        leafMap.invalidateSize({ animate: false });
                        var mapSize2 = leafMap.getSize();

                        // Lewy obszar = mapa minus panel sukcesu i margines
                        var leftAreaW = mapSize2.x - pw3 - margin3 * 2;
                        var targetX   = leftAreaW / 2;

                        // Wycentruj tooltip WZGLĘDEM panelu sukcesu:
                        // iconAnchor y=155, tooltip_height≈80px → tooltip_center = pin - 115
                        // _positionPanel centruje panel pionowo: panel_center = mapH/2
                        // Chcemy: tooltip_center = panel_center → pin = mapH/2 + 115
                        var panelTop3    = Math.max(margin3, (mapSize2.y - ph3) / 2);
                        var panelCenter3 = panelTop3 + ph3 / 2;
                        var targetY      = panelCenter3 + 115;

                        var targetZoom = 18;

                        var ptPx      = leafMap.latLngToContainerPoint(L.latLng(ptLat, ptLng));
                        var offX      = ptPx.x - targetX;
                        var offY      = ptPx.y - targetY;
                        var cPx       = leafMap.latLngToContainerPoint(leafMap.getCenter());
                        var newCenter = leafMap.containerPointToLatLng([cPx.x + offX, cPx.y + offY]);

                        leafMap.flyTo(newCenter, targetZoom, {
                            duration:      1.8,
                            easeLinearity: 0.15
                        });
                    } catch (e) {}
                }, 2100);
            });

            // Start countdown
            if (this.config.autoClose) {
                this.startCountdown();
            }

            // Start stopwatch (od wyboru paczkomatu)
            this.startStopwatch();
        },

        // ====================
        // STOPWATCH – czas od wyboru (liczy w górę)
        // ====================
        startStopwatch: function() {
            var start = window._inpostSelectionTime || performance.now();
            var el = document.getElementById('stopwatch-value');
            if (!el) return;

            var tick = function() {
                var sec = (performance.now() - start) / 1000;
                el.textContent = sec.toFixed(1) + 's';
            };
            tick();
            this._stopwatchInterval = setInterval(tick, 100);
        },

        stopStopwatch: function(showFinal) {
            if (this._stopwatchInterval) {
                clearInterval(this._stopwatchInterval);
                this._stopwatchInterval = null;
            }
            if (showFinal) {
                var el = document.getElementById('stopwatch-value');
                var sw = document.getElementById('success-stopwatch');
                if (el && window._inpostSelectionTime) {
                    var total = ((performance.now() - window._inpostSelectionTime) / 1000).toFixed(1);
                    el.textContent = total + 's';
                    el.style.color = '#10b981';
                    el.style.fontWeight = '700';
                }
                if (sw) {
                    var label = sw.querySelector('.stopwatch-label');
                    if (label) label.textContent = '\u23F1 Czas wyboru:';
                }
            }
        },

        // ====================
        // COUNTDOWN TIMER
        // ====================
        startCountdown: function() {
            let seconds = this.config.countdownSeconds;
            const timerEl = document.getElementById('countdown-timer');
            
            if (!timerEl) return;
            
            const interval = setInterval(() => {
                seconds--;
                timerEl.textContent = seconds;
                
                if (seconds <= 0) {
                    clearInterval(interval);
                    // hideSuccessScreen() już zamyka cały popup - nie trzeba dodatkowego zamknięcia
                    this.hideSuccessScreen();
                }
            }, 1000);
            
            // Zapisz interval ID żeby móc anulować
            this._countdownInterval = interval;
        },
        
        // ====================
        // UKRYJ SUCCESS SCREEN I ZAMKNIJ POPUP
        // ====================
        /**
         * =================================================================================
         * UKRYJ SUCCESS SCREEN I ZAMKNIJ POPUP NATURALNIE
         * =================================================================================
         * 
         * PROBLEM W PIERWOTNEJ WERSJI:
         * - Success panel znikał zbyt wcześnie (opuszczał mapę)
         * - Mapa pozostawała otwarta po zniknięciu success panelu
         * - Użytkownik widział pustą mapę zamiast zamkniętego popupu
         * 
         * ROZWIĄZANIE:
         * - Najpierw ukryj success panel (animacja fade-out)
         * - Następnie zamknij cały popup naturalnie (przez IntroPopup.close())
         * - Dodaj małe opóźnienie między ukryciem panelu a zamknięciem popupu (lepsze UX)
         * - Upewnij się, że popup jest zamknięty przed przywróceniem scroll
         * 
         * TIMING:
         * - Ukryj panel → 200ms opóźnienie → zamknij popup → przywróć scroll
         * 
         * STATUS: ✅ NAPRAWIONE - success panel pozostaje widoczny przez cały countdown, potem zamyka mapę naturalnie
         */
        hideSuccessScreen: function() {
            window.PS_DEBUG&&console.log('[Parcel Locker Selector] 🚀 Zamykanie success screen i całego popupu...');
            
            // Anuluj countdown (jeśli jeszcze działa)
            if (this._countdownInterval) {
                clearInterval(this._countdownInterval);
                this._countdownInterval = null;
                window.PS_DEBUG&&console.log('[Parcel Locker Selector] ✅ Countdown anulowany');
            }

            // Zatrzymaj stoper – pokaż finalny czas
            this.stopStopwatch(true);
            
            // KROK 1: Ukryj success panel z animacją fade-out
            const panel = document.getElementById('parcel-locker-success');
            if (panel) {
                window.PS_DEBUG&&console.log('[Parcel Locker Selector] Ukrywam success panel...');
                // Dodaj klasę fade-out dla animacji
                panel.style.transition = 'opacity 0.3s ease-out';
                panel.style.opacity = '0';
                
                // Po animacji ukryj panel
                setTimeout(() => {
                    panel.style.display = 'none';
                    window.PS_DEBUG&&console.log('[Parcel Locker Selector] ✅ Success panel ukryty');
                }, 300);
            }
            
            // KROK 2: Zamknij cały popup INTRO_1 (po małym opóźnieniu dla lepszego UX)
            setTimeout(() => {
                window.PS_DEBUG&&console.log('[Parcel Locker Selector] Zamykam cały popup INTRO_1...');
                let popupClosed = false;
                
                // Metoda 1: Przez window.IntroPopup.close() - NAJLEPSZA METODA
                if (window.IntroPopup && typeof window.IntroPopup.close === 'function') {
                    try {
                        window.PS_DEBUG&&console.log('[Parcel Locker Selector] Zamykam popup przez IntroPopup.close()');
                        window.IntroPopup.close();
                        popupClosed = true;
                        window.PS_DEBUG&&console.log('[Parcel Locker Selector] ✅ Popup zamknięty przez IntroPopup.close()');
                    } catch (e) {
                        window.PS_DEBUG&&console.warn('[Parcel Locker Selector] ⚠️ Błąd przy IntroPopup.close():', e);
                    }
                }
                
                // Metoda 2: Przez bezpośrednie wywołanie closePopup() jeśli dostępne (fallback)
                if (!popupClosed && typeof closePopup === 'function') {
                    try {
                        window.PS_DEBUG&&console.log('[Parcel Locker Selector] Zamykam popup przez closePopup() (fallback)');
                        closePopup();
                        popupClosed = true;
                        window.PS_DEBUG&&console.log('[Parcel Locker Selector] ✅ Popup zamknięty przez closePopup()');
                    } catch (e) {
                        window.PS_DEBUG&&console.warn('[Parcel Locker Selector] ⚠️ Błąd przy closePopup():', e);
                    }
                }
                
                // Metoda 3: Bezpośrednie usunięcie popupu z DOM (ostateczny fallback)
                if (!popupClosed) {
                    const popup = document.getElementById('inpost-universal-popup');
                    if (popup) {
                        window.PS_DEBUG&&console.log('[Parcel Locker Selector] Zamykam popup przez bezpośrednie usunięcie z DOM (fallback)');
                        popup.remove();
                        popupClosed = true;
                        window.PS_DEBUG&&console.log('[Parcel Locker Selector] ✅ Popup usunięty z DOM');
                    }
                }
                
                // Metoda 4: Usuń wszystkie overlay elementy (ostateczny fallback)
                if (!popupClosed) {
                    const overlays = document.querySelectorAll('[class*="inpost-"][class*="overlay"], [id*="inpost"][id*="overlay"], .inpost-universal-popup');
                    if (overlays.length > 0) {
                        window.PS_DEBUG&&console.log('[Parcel Locker Selector] Zamykam popup przez usunięcie overlay elementów (fallback)');
                        overlays.forEach(overlay => overlay.remove());
                        popupClosed = true;
                        window.PS_DEBUG&&console.log('[Parcel Locker Selector] ✅ Overlay elementy usunięte');
                    }
                }
                
                // KROK 3: Przywróć scroll (tylko jeśli popup został zamknięty)
                if (popupClosed) {
                    document.body.style.overflow = '';
                    document.body.style.position = '';
                    document.body.style.width = '';
                    document.documentElement.style.overflow = '';
                    window.PS_DEBUG&&console.log('[Parcel Locker Selector] ✅ Scroll przywrócony');
                    window.PS_DEBUG&&console.log('[Parcel Locker Selector] ✅✅✅ Popup zamknięty pomyślnie!');
                } else {
                    window.PS_DEBUG&&console.warn('[Parcel Locker Selector] ⚠️ Nie udało się zamknąć popupu - sprawdź konsolę');
                }
            }, 200); // Małe opóźnienie dla lepszego UX (panel znika, potem popup)
        },
        
        // ====================
        // STATUS PANEL NA DOLE MAPKI
        // ====================
        updateStatusPanel: function() {
            let panel = document.getElementById('parcel-locker-status-panel');
            
            // Utwórz panel jeśli nie istnieje
            if (!panel) {
                panel = document.createElement('div');
                panel.id = 'parcel-locker-status-panel';
                panel.className = 'parcel-status-panel';
                
                // Dodaj do footera popup (przed przyciskami)
                const footer = document.querySelector('.inpost-footer-buttons');
                if (footer) {
                    footer.parentNode.insertBefore(panel, footer);
                }
            }
            
            // Jeśli wybrany paczkomat - pokaż info
            if (this.selectedLocker) {
                const slAd = this.selectedLocker.address_details || {};
                panel.innerHTML = `
                    <div class="status-panel-content">
                        <div class="status-label">✅ Wybrany paczkomat:</div>
                        <div class="status-locker">
                            <strong>${this.selectedLocker.name}</strong>
                            <span class="status-address">
                                ${slAd.city || ''}, ${slAd.street || ''}
                            </span>
                        </div>
                        <button class="status-change-btn" onclick="ParcelLockerSelector.clearSelection()">
                            Zmień
                        </button>
                    </div>
                `;
                panel.style.display = 'block';
            } else {
                panel.style.display = 'none';
            }
        },
        
        // ====================
        // WYCZYŚĆ WYBÓR
        // ====================
        clearSelection: function() {
            window.PS_DEBUG&&console.log('[Parcel Locker Selector] 🗑️ Czyszczenie wyboru');

            // Przywróć sidebar, footer i instrukcje
            var popup = document.getElementById('inpost-universal-popup');
            if (popup) popup.classList.remove('ps-selection-mode');

            // Usuń tooltip lokalizacji i ring marker z mapy
            try {
                var _lm = window.IntroPopup && window.IntroPopup.getMap ? window.IntroPopup.getMap() : null;
                if (_lm) {
                    if (this._successTooltipMarker) { _lm.removeLayer(this._successTooltipMarker); this._successTooltipMarker = null; }
                    if (this._successRingMarker)    { _lm.removeLayer(this._successRingMarker);    this._successRingMarker = null; }
                }
            } catch(e) {}

            // Zatrzymaj pulsowanie markera
            this.stopMarkerPulse();

            this.selectedLocker = null;
            this.refreshUI();
            this.hideSuccessScreen();
        },
        
        // ====================
        // ZAPISZ DO WORDPRESS
        // ====================
        saveToWordPress: function(point) {
            window.PS_DEBUG&&console.log('[Parcel Locker Selector] 💾 Zapisywanie do WordPress:', point.name);
            
            // Callback do WordPress (jeśli istnieje)
            if (typeof window.inpostCallback === 'function') {
                window.inpostCallback(point);
            }
            
            // AJAX do WordPress (opcjonalne)
            if (typeof jQuery !== 'undefined' && typeof wc_ajax_url !== 'undefined') {
                const ptAd = point.address_details || {};
                jQuery.post(wc_ajax_url + 'save_inpost_locker', {
                    locker_name: point.name,
                    locker_code: ptAd.post_code || '',
                    locker_city: ptAd.city || '',
                    locker_street: ptAd.street || '',
                    locker_building: ptAd.building_number || '',
                    locker_data: JSON.stringify(point)
                }, function(response) {
                    window.PS_DEBUG&&console.log('[Parcel Locker Selector] ✅ Zapisano w WordPress:', response);
                });
            }
            
            // LocalStorage backup
            try {
                const lsAd = point.address_details || {};
                localStorage.setItem('parcselect_selected_locker', JSON.stringify({
                    name: point.name,
                    postcode: lsAd.post_code || '',
                    city: lsAd.city || '',
                    street: lsAd.street || '',
                    building: lsAd.building_number || '',
                    timestamp: new Date().toISOString()
                }));
            } catch (e) {
                window.PS_DEBUG&&console.warn('[Parcel Locker Selector] ⚠️ Nie można zapisać do localStorage:', e);
            }

            /**
             * =================================================================================
             * WYSYŁANIE EVENTU DO WOOCOMMERCE - INTEGRACJA ZEWNĘTRZNA
             * =================================================================================
             *
             * PROBLEM W PIERWOTNEJ WERSJI:
             * - Brak wysyłania danych do WooCommerce
             * - INTRO działało w izolacji - dane nie trafiały do koszyka
             * - Użytkownik wybierał paczkomat ale WooCommerce nie wiedział
             *
             * DLACZEGO W SAVE TO WORDPRESS:
             * - Timing: PO zapisaniu lokalnym (localStorage + WordPress)
             * - Sequence: success screen → save local → send to WooCommerce
             * - Safety: dane są bezpieczne lokalnie PRZED wysłaniem
             *
             * EVENT: 'inpost-point-selected' (CustomEvent)
             *
             * STRUKTURA EVENTU:
             * event.detail = {
             *   point: {                           // Kompletne dane paczkomatu
             *     name: "GDY01M",                  // ID - klucz główny
             *     address_details: {              // Adres strukturalny
             *       city: "Gdynia",
             *       street: "Wójta Radtkego",
             *       building_number: "1",
             *       post_code: "81-342"
             *     },
             *     location: {latitude, longitude} // GPS (opcjonalne)
             *   },
             *   country: "pl"                     // Kod kraju ISO
             * }
             *
             * DLACZEGO CUSTOM EVENT:
             * - Standard web API - działa we wszystkich przeglądarkach
             * - Asynchronous - nie blokuje UI
             * - Extensible - można dodać więcej listenerów
             * - Debuggable - można logować w DevTools
             *
             * ODBIORCA EVENTU:
             * - paczkomat-modal.js (nasza wtyczka WooCommerce)
             * - document.addEventListener('inpost-point-selected', ...)
             * - processPointSelection() → AJAX → WooCommerce session
             *
             * TIMING KRYTYCZNY:
             * - PO saveToWordPress() - dane lokalne bezpieczne
             * - PO success screen - użytkownik widział potwierdzenie
             * - PRZED zamknięciem INTRO - popup jeszcze otwarty
             *
             * BEZPIECZEŃSTWO:
             * - Dane sanitizowane w PHP (sanitize_text_field)
             * - Brak wrażliwych danych w event (tylko adres)
             * - AJAX z nonce verification w PHP
             *
             * UWAGI DLA PRZYSZŁYCH ROZWOJÓW:
             * - Event name unikalny - 'inpost-point-selected'
             * - Struktura eventu immutable - zmiany breaking
             * - Testować event firing w różnych scenariuszach
             * - Consider event versioning (v2) dla backward compatibility
             * - Monitorować performance impact
             */
            window.PS_DEBUG&&console.log('[Parcel Locker Selector] 📤 Wysyłanie eventu inpost-point-selected do WooCommerce');
            const event = new CustomEvent('inpost-point-selected', {
                detail: {
                    point: point,
                    country: 'pl' // zakładamy Polskę, można to rozszerzyć
                }
            });
            document.dispatchEvent(event);
            window.PS_DEBUG&&console.log('[Parcel Locker Selector] ✅ Event wysłany do WooCommerce integration');
        },
        
        // ====================
        // GET WYBRANY PACZKOMAT
        // ====================
        getSelectedLocker: function() {
            return this.selectedLocker;
        },

        // ====================
        // ZIELONY PULSUJĄCY KRĄG NA MAPIE – wskazuje wybrany punkt
        // ====================
        addSuccessRing: function(point) {
            try {
                var leafMap = window.IntroPopup && window.IntroPopup.getMap
                    ? window.IntroPopup.getMap() : null;
                if (!leafMap || !point.location) return;

                var latlng = L.latLng(point.location.latitude, point.location.longitude);

                // DivIcon z pulsującymi pierścieniami
                var icon = L.divIcon({
                    className: 'success-ring-root',
                    iconSize:   [120, 120],
                    iconAnchor: [60, 60],
                    html: '<div class="success-ring-wave r1"></div>'
                        + '<div class="success-ring-wave r2"></div>'
                        + '<div class="success-ring-wave r3"></div>'
                        + '<div class="success-ring-dot"></div>'
                });

                // ── ZIELONY TOOLTIP NAD PINEZKĄ – nazwa + adres ───────────
                var ad      = point.address_details || {};
                var city    = ad.city || '';
                var street  = ad.street || '';
                var bldg    = ad.building_number || '';
                var postCode = ad.post_code || '';
                var addrLine = [street + (bldg ? ' ' + bldg : ''), postCode + (city ? ' ' + city : '')].filter(Boolean).join(', ');

                // Popup z pełnymi danymi punktu (zielony styl)
                var openHours = point.opening_hours || point.openingHours || '';
                var pointType = point.type || '';
                var pointStatus = point.status || '';
                var popupRows = '';
                if (addrLine) popupRows += '<div class="ps-info-row"><span class="ps-info-label">Adres</span><span class="ps-info-val">' + addrLine + '</span></div>';
                if (pointType) popupRows += '<div class="ps-info-row"><span class="ps-info-label">Typ</span><span class="ps-info-val">' + pointType + '</span></div>';
                if (pointStatus) popupRows += '<div class="ps-info-row"><span class="ps-info-label">Status</span><span class="ps-info-val">' + pointStatus + '</span></div>';
                if (openHours && typeof openHours === 'string') popupRows += '<div class="ps-info-row"><span class="ps-info-label">Godziny</span><span class="ps-info-val">' + openHours + '</span></div>';
                var ringPopupHtml =
                    '<div class="ps-detail-popup">' +
                        '<div class="ps-detail-name">' + point.name + '</div>' +
                        '<div class="ps-detail-body">' + popupRows + '</div>' +
                    '</div>';

                var ringMarker = L.marker(latlng, {
                    icon: icon,
                    zIndexOffset: 8000,
                    interactive: true
                }).addTo(leafMap);

                ringMarker.bindPopup(ringPopupHtml, {
                    maxWidth: 240,
                    minWidth: 200,
                    className: 'ps-detail-popup-leaflet',
                    autoPan: true,
                    closeButton: true
                });
                // Buduj tooltip – każda dana w osobnej linii
                var tooltipLines = '';
                if (postCode || city) {
                    var cityPostLine = [postCode, city].filter(Boolean).join(' ');
                    tooltipLines += '<div class="ps-loc-line ps-loc-city">' + cityPostLine + '</div>';
                }
                if (street) {
                    var streetLine = street + (bldg ? ' ' + bldg : '');
                    tooltipLines += '<div class="ps-loc-line ps-loc-street">' + streetLine + '</div>';
                }
                var tooltipHtml =
                    '<div class="ps-location-tooltip">' +
                        '<div class="ps-loc-name">' + point.name + '</div>' +
                        (tooltipLines ? '<div class="ps-loc-details">' + tooltipLines + '</div>' : '') +
                    '</div>';

                var tooltipIcon = L.divIcon({
                    className:  'ps-location-tooltip-root',
                    iconSize:   [0, 0],
                    // iconAnchor y=155: tooltip_height(80) + ring_top(60) + gap(15) = 155
                    // tooltip_center = pin - 115, wycentrowane z panelem sukcesu
                    iconAnchor: [0, 155],
                    html: tooltipHtml
                });
                var tooltipMarker = L.marker(latlng, {
                    icon: tooltipIcon,
                    zIndexOffset: 9000,
                    interactive: false
                }).addTo(leafMap);

                this._successTooltipMarker = tooltipMarker;

                // Usuń ring + tooltip po 18 sekundach (razem z countdown)
                setTimeout(function() {
                    try { leafMap.removeLayer(ringMarker); } catch(e) {}
                    try { leafMap.removeLayer(tooltipMarker); } catch(e) {}
                }, 18000);

                this._successRingMarker = ringMarker;
            } catch(e) {
                window.PS_DEBUG&&console.warn('[Parcel Locker Selector] addSuccessRing error:', e);
            }
        },

        // ====================
        // KONFETTI – wybuch czasteczek z centrum panelu sukces
        // ====================
        spawnConfetti: function(panel) {
            var colors = [
                '#FF6600','#FF8C00','#FFD700',
                '#10b981','#059669','#34d399',
                '#3b82f6','#8b5cf6','#f43f5e',
                '#ffffff','#fbbf24','#ec4899',
                '#06b6d4','#a855f7','#f97316'
            ];
            var container = panel.parentElement || document.body;
            var self = this;

            var _spawnWave = function(waveDelay, count, distMin, distMax, durMin, durMax, delayMax) {
                setTimeout(function() {
                    var rect  = panel.getBoundingClientRect();
                    var pRect = container.getBoundingClientRect();
                    var cx = (rect.left - pRect.left) + rect.width / 2;
                    var cy = (rect.top  - pRect.top)  + 68;

                    var shapes = [
                        { w:10, h:10, br:'2px' },
                        { w:16, h:7,  br:'1px' },
                        { w:9,  h:9,  br:'50%' },
                        { w:20, h:5,  br:'2px' },
                        { w:6,  h:15, br:'1px' },
                        { w:12, h:12, br:'3px' }
                    ];

                    for (var i = 0; i < count; i++) {
                        (function(i) {
                            var el    = document.createElement('div');
                            el.className = 'confetti-particle';
                            var sh    = shapes[Math.floor(Math.random() * shapes.length)];
                            var color = colors[Math.floor(Math.random() * colors.length)];
                            // Kąt biasowany ku górze, lekko na boki
                            var baseAngle = -90 + (Math.random() - 0.5) * 240;
                            var rad  = baseAngle * Math.PI / 180;
                            var dist = distMin + Math.random() * (distMax - distMin);
                            var tx   = Math.cos(rad) * dist;
                            var ty   = Math.sin(rad) * dist;
                            var rot  = (Math.random() - 0.5) * 1200 + 'deg';
                            var dur  = (durMin + Math.random() * (durMax - durMin)).toFixed(2) + 's';
                            var delay = (Math.random() * delayMax).toFixed(3) + 's';

                            el.style.cssText = [
                                'left:'       + cx + 'px',
                                'top:'        + cy + 'px',
                                'width:'      + sh.w + 'px',
                                'height:'     + sh.h + 'px',
                                'background:' + color,
                                '--tx:'       + tx.toFixed(1) + 'px',
                                '--ty:'       + ty.toFixed(1) + 'px',
                                '--rot:'      + rot,
                                '--dur:'      + dur,
                                '--delay:'    + delay,
                                '--br:'       + sh.br
                            ].join(';');
                            container.appendChild(el);
                            var removeAfter = (parseFloat(dur) + parseFloat(delay) + 0.3) * 1000;
                            setTimeout(function() { if (el.parentNode) el.parentNode.removeChild(el); }, removeAfter);
                        })(i);
                    }
                }, waveDelay);
            };

            // Fala 1 – główny wybuch (60 cząstek, duży zasięg, długi lot)
            _spawnWave(0,    60, 120, 320, 2.2, 3.8, 0.35);
            // Fala 2 – echo po 700ms (40 cząstek, mniejszy zasięg, powolne opadanie)
            _spawnWave(700,  40,  80, 220, 2.8, 4.5, 0.5);
            // Fala 3 – finalne iskry po 1600ms (25 cząstek, delikatne)
            _spawnWave(1600, 25,  50, 160, 3.0, 5.0, 0.7);
        },
        
        // ====================
        // INJECT CSS STYLES
        // ====================
        injectStyles: function() {
            if (document.getElementById('parcel-locker-selector-styles')) return;
            
            const style = document.createElement('style');
            style.id = 'parcel-locker-selector-styles';
            style.textContent = `
                /* ═══════════════════════════════════════
                   SYSTEM DESIGN - ZMIENNE WSPOLNE
                   ═══════════════════════════════════════ */
                :root {
                    --ps-orange:    #FF6600;
                    --ps-orange-dk: #CC4400;
                    --ps-green:     #10b981;
                    --ps-green-dk:  #059669;
                    --ps-bg:        #ffffff;
                    --ps-shadow:    0 8px 32px rgba(0,0,0,0.22), 0 2px 8px rgba(0,0,0,0.12);
                    --ps-radius:    14px;
                    --ps-font:      -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
                }

                /* ═══════════════════════════════════════
                   MARKER POPUP (okienko po kliknieciu pinezki)
                   ═══════════════════════════════════════ */
                .parcel-locker-popup {
                    min-width: 170px;
                    max-width: 190px;
                    font-family: var(--ps-font);
                    background: var(--ps-bg) !important;
                    border: none !important;
                    box-shadow: var(--ps-shadow) !important;
                    border-radius: var(--ps-radius) !important;
                    padding: 0 !important;
                    overflow: hidden;
                }

                /* Naglowek z ID - pomaranczowy pasek (domyslny) */
                .popup-locker-id {
                    font-size: 15px;
                    font-weight: 800;
                    color: #fff;
                    text-align: center;
                    background: linear-gradient(135deg, var(--ps-orange), #FF8800);
                    padding: 10px 12px 9px;
                    letter-spacing: 0.5px;
                    border-radius: var(--ps-radius) var(--ps-radius) 0 0;
                    transition: background 0.35s ease;
                }

                /* Naglowek z ID - ZIELONY gdy paczkomat wybrany */
                .parcel-locker-popup.marked .popup-locker-id {
                    background: linear-gradient(135deg, var(--ps-green), var(--ps-green-dk));
                }

                /* Body popupu */
                .popup-city-postal,
                .popup-street {
                    padding: 0 12px;
                }

                /* Miasto + Kod pocztowy w jednej linii */
                .popup-city-postal {
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    margin-top: 8px;
                    margin-bottom: 3px;
                    font-size: 12px;
                    font-family: var(--ps-font);
                }

                .popup-city-postal .city {
                    font-weight: 700;
                    color: #111;
                }

                .popup-city-postal .postal {
                    font-weight: 600;
                    color: var(--ps-orange);
                    background: #fff3eb;
                    padding: 2px 7px;
                    border-radius: 20px;
                    font-size: 11px;
                    border: 1px solid rgba(255,102,0,0.25);
                    white-space: nowrap;
                    flex-shrink: 0;
                }

                /* Ulica */
                .popup-street {
                    font-size: 11.5px;
                    color: #555;
                    margin-bottom: 10px;
                    line-height: 1.4;
                    font-family: var(--ps-font);
                }

                /* Status wybranego */
                .popup-status-selected {
                    background: linear-gradient(135deg, var(--ps-green), var(--ps-green-dk));
                    color: white;
                    padding: 4px 10px;
                    border-radius: 6px;
                    text-align: center;
                    font-weight: 700;
                    font-size: 10px;
                    margin: 0 12px 8px;
                }

                /* Animacja pulsowania przycisku WYBIERZ */
                @keyframes popupBtnPulse {
                    0%, 100% { box-shadow: 0 3px 12px rgba(255,102,0,0.4); }
                    50%       { box-shadow: 0 5px 22px rgba(255,102,0,0.7); }
                }
                @keyframes popupCheckBlink {
                    0%, 40%, 100% { opacity: 1; }
                    50%, 90%      { opacity: 0.25; }
                }

                /* Przycisk WYBIERZ */
                .popup-select-btn {
                    width: calc(100% - 24px);
                    margin: 0 12px 12px;
                    padding: 10px 8px;
                    background: linear-gradient(135deg, var(--ps-orange), #FF8800);
                    color: white;
                    border: none;
                    border-radius: 8px;
                    font-size: 13px;
                    font-weight: 800;
                    cursor: pointer;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    gap: 7px;
                    letter-spacing: 0.5px;
                    animation: popupBtnPulse 1.8s ease-in-out infinite;
                    transition: filter 0.15s;
                    font-family: var(--ps-font);
                }

                .popup-select-btn:hover:not(:disabled) {
                    filter: brightness(1.12);
                }

                .popup-select-btn:disabled,
                .popup-select-btn.marked {
                    background: linear-gradient(135deg, var(--ps-green), var(--ps-green-dk));
                    cursor: default;
                    animation: none;
                    box-shadow: 0 3px 12px rgba(16,185,129,0.4);
                }

                /* Checkbox mruga gdy niewybrany */
                .popup-select-btn:not(:disabled) .checkbox-icon {
                    font-size: 16px;
                    animation: popupCheckBlink 1.77s ease-in-out infinite;
                }

                /* Gdy wybrany - checkbox NIE mruga, PULSUJE */
                .popup-select-btn .selected-check {
                    font-size: 18px;
                    font-weight: 900;
                    animation: selectedCheckPulse 1.4s ease-in-out infinite !important;
                    display: inline-block;
                }

                @keyframes selectedCheckPulse {
                    0%, 100% { transform: scale(1);    opacity: 1;   }
                    50%       { transform: scale(1.35); opacity: 0.75; }
                }
                
                /* LIST CHECKBOX STYLES - ULEPSZONE */
                .list-checkbox {
                    width: 38px;
                    height: 38px;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    border: 3px solid #e5e7eb;
                    border-radius: 10px;
                    cursor: pointer;
                    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
                    flex-shrink: 0;
                    background: white;
                    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
                    position: relative;
                }
                
                .list-checkbox:hover {
                    border-color: #FF6600;
                    background: linear-gradient(135deg, #FFF5F0 0%, #FFE8D9 100%);
                    transform: translateY(-2px);
                    box-shadow: 0 4px 12px rgba(255, 102, 0, 0.2);
                }
                
                .list-checkbox.checked {
                    background: linear-gradient(135deg, #10b981 0%, #059669 100%);
                    border-color: #10b981;
                    box-shadow: 0 4px 16px rgba(16, 185, 129, 0.4);
                }
                
                .list-checkbox.checked:hover {
                    transform: translateY(-2px) scale(1.05);
                    box-shadow: 0 6px 20px rgba(16, 185, 129, 0.5);
                }
                
                .list-checkbox .checkbox-icon {
                    font-size: 20px;
                    color: #d1d5db;
                    transition: all 0.2s;
                }
                
                .list-checkbox:hover .checkbox-icon {
                    color: #FF6600;
                }
                
                .list-checkbox.checked .checkbox-icon {
                    color: white;
                    animation: checkPop 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
                }
                
                @keyframes checkPop {
                    0% { transform: scale(0); opacity: 0; }
                    50% { transform: scale(1.3); }
                    100% { transform: scale(1); opacity: 1; }
                }
                
                /**
                 * =================================================================================
                 * SUCCESS SCREEN STYLES - FLOATING PANEL (GLASSMORPHISM)
                 * =================================================================================
                 * 
                 * NAPRAWIONE:
                 * - z-index zmniejszony z 9999999 do 10000 (wystarczająco wysoki, ale nie za wysoki)
                 * - position: absolute względem #inpost-universal-popup (position: relative)
                 * - Panel jest WEWNĄTRZ popupu, nie opuszcza mapy
                 * 
                 * WNIOSKI:
                 * - z-index 9999999 jest ZBYT WYSOKIE - może powodować problemy z innymi elementami
                 * - Popup overlay zwykle ma z-index 9999, więc 10000 wystarczy dla success panelu
                 * - position: absolute wymaga position: relative na rodzicu
                 */
                .parcel-success-panel {
                    position: fixed;        /* FIXED – poza overflow:hidden rodziców */
                    width: 292px;
                    z-index: 100000;
                    display: none;
                    pointer-events: auto;
                    overflow: visible;
                    top: 20px;
                    right: 20px;
                    animation: successPanelIn 0.45s cubic-bezier(0.34, 1.56, 0.64, 1) both;
                    isolation: isolate;
                }

                @keyframes successPanelIn {
                    from { opacity: 0; transform: scale(0.82) translateY(-14px); }
                    to   { opacity: 1; transform: scale(1) translateY(0); }
                }

                .parcel-success-container {
                    background: var(--ps-bg);
                    border-radius: 18px;
                    padding: 22px 18px 16px;
                    text-align: center;
                    box-shadow:
                        0 2px 0 rgba(16,185,129,0.9),
                        0 12px 40px rgba(0,0,0,0.28),
                        0 24px 60px rgba(0,0,0,0.16),
                        0 0 0 1px rgba(16,185,129,0.15);
                    border-top: 5px solid var(--ps-green);
                    position: relative;
                    font-family: var(--ps-font);
                }

                /* Close button */
                .success-close-btn {
                    position: absolute;
                    top: 10px;
                    right: 10px;
                    width: 30px;
                    height: 30px;
                    border: none;
                    background: #f3f4f6;
                    border-radius: 50%;
                    font-size: 15px;
                    color: #9ca3af;
                    cursor: pointer;
                    transition: background 0.18s, color 0.18s, transform 0.2s;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    line-height: 1;
                }

                .success-close-btn:hover {
                    background: #fee2e2;
                    color: #ef4444;
                    transform: rotate(90deg);
                }

                /* ── ZIELONY KRAG NA MAPIE – pulsujace pierscienie ──────── */
                .success-ring-root {
                    background: none !important;
                    border: none !important;
                    position: relative;
                }
                .success-ring-wave {
                    position: absolute;
                    border-radius: 50%;
                    border: 3px solid #10b981;
                    width: 100%;
                    height: 100%;
                    top: 0; left: 0;
                    animation: ringExpand 2s ease-out infinite;
                    box-sizing: border-box;
                }
                .success-ring-wave.r1 { animation-delay: 0s; }
                .success-ring-wave.r2 { animation-delay: 0.55s; }
                .success-ring-wave.r3 { animation-delay: 1.1s; }
                @keyframes ringExpand {
                    0%   { transform: scale(0.2); opacity: 0.9; border-color: rgba(16,185,129,0.9); }
                    100% { transform: scale(1.6); opacity: 0;   border-color: rgba(16,185,129,0); }
                }
                .success-ring-dot {
                    position: absolute;
                    width: 18px;
                    height: 18px;
                    background: #10b981;
                    border-radius: 50%;
                    border: 3px solid #fff;
                    top: 50%; left: 50%;
                    transform: translate(-50%, -50%);
                    box-shadow: 0 0 12px rgba(16,185,129,0.8);
                    animation: dotPulse 1.8s ease-in-out infinite;
                }
                @keyframes dotPulse {
                    0%, 100% { box-shadow: 0 0 10px rgba(16,185,129,0.7); transform: translate(-50%,-50%) scale(1); }
                    50%       { box-shadow: 0 0 22px rgba(16,185,129,1);   transform: translate(-50%,-50%) scale(1.25); }
                }

                /* ── ZIELONY TOOLTIP LOKALIZACJI NAD PINEZKĄ ─────────────── */
                .ps-location-tooltip-root {
                    background: none !important;
                    border: none !important;
                }
                .ps-location-tooltip {
                    background: linear-gradient(135deg, #10b981, #059669);
                    color: #fff;
                    border-radius: 12px;
                    padding: 9px 14px 8px;
                    min-width: 160px;
                    max-width: 240px;
                    text-align: center;
                    box-shadow: 0 6px 20px rgba(16,185,129,0.5), 0 2px 8px rgba(0,0,0,0.22);
                    position: relative;
                    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
                    animation: tooltipFadeIn 0.4s ease both;
                    transform: translateX(-50%);
                    white-space: normal;
                }
                /* Strzalka w dol – wskazuje na pinezke */
                .ps-location-tooltip::after {
                    content: '';
                    position: absolute;
                    bottom: -9px;
                    left: 50%;
                    transform: translateX(-50%);
                    border-width: 9px 8px 0;
                    border-style: solid;
                    border-color: #059669 transparent transparent;
                }
                .ps-loc-name {
                    font-size: 14px;
                    font-weight: 900;
                    letter-spacing: 0.5px;
                    margin-bottom: 5px;
                    line-height: 1.2;
                }
                .ps-loc-details {
                    display: flex;
                    flex-direction: column;
                    gap: 2px;
                }
                .ps-loc-line {
                    font-size: 11px;
                    font-weight: 500;
                    opacity: 0.93;
                    line-height: 1.4;
                    white-space: normal;
                    word-break: break-word;
                }
                .ps-loc-city {
                    font-weight: 700;
                    font-size: 12px;
                    opacity: 1;
                }
                .ps-loc-street {
                    opacity: 0.88;
                }
                @keyframes tooltipFadeIn {
                    from { opacity: 0; transform: translateX(-50%) translateY(8px); }
                    to   { opacity: 1; transform: translateX(-50%) translateY(0); }
                }

                /* ── SZCZEGOLOWY POPUP PO KLIKNIECIU KREGU ─────────────── */
                .ps-detail-popup-leaflet .leaflet-popup-content-wrapper {
                    padding: 0 !important;
                    background: transparent !important;
                    box-shadow: none !important;
                    border-radius: 0 !important;
                }
                .ps-detail-popup-leaflet .leaflet-popup-content {
                    margin: 0 !important;
                }
                .ps-detail-popup-leaflet .leaflet-popup-tip-container {
                    display: none !important;
                }
                .ps-detail-popup {
                    font-family: var(--ps-font);
                    background: #fff;
                    border-radius: 14px;
                    overflow: hidden;
                    box-shadow: 0 8px 32px rgba(16,185,129,0.35), 0 0 0 2px #10b981;
                    min-width: 200px;
                    max-width: 240px;
                }
                .ps-detail-name {
                    background: linear-gradient(135deg, #10b981, #059669);
                    color: #fff;
                    font-size: 15px;
                    font-weight: 800;
                    text-align: center;
                    padding: 10px 14px 9px;
                    letter-spacing: 0.5px;
                }
                .ps-detail-body {
                    padding: 10px 14px 12px;
                }
                .ps-info-row {
                    display: flex;
                    gap: 8px;
                    margin-bottom: 5px;
                    align-items: flex-start;
                    font-size: 12px;
                }
                .ps-info-label {
                    color: #10b981;
                    font-weight: 700;
                    min-width: 60px;
                    flex-shrink: 0;
                    font-size: 11px;
                    text-transform: uppercase;
                }
                .ps-info-val {
                    color: #1a1a1a;
                    font-weight: 500;
                    line-height: 1.4;
                }

                /* ── SVG CHECKMARK – rysuje sie po wejsciu ikony ────────── */
                .check-path {
                    stroke-dasharray: 56;
                    stroke-dashoffset: 56;
                    animation: drawCheck 0.55s cubic-bezier(0.4, 0, 0.2, 1) 0.55s forwards;
                }
                @keyframes drawCheck {
                    to { stroke-dashoffset: 0; }
                }

                /* ── KONFETTI PARTICLE ───────────────────────────────────── */
                .confetti-particle {
                    position: absolute;
                    pointer-events: none;
                    animation: confettiFly var(--dur, 3s) cubic-bezier(0.15, 0.5, 0.3, 1) var(--delay, 0s) both;
                    transform-origin: center;
                    z-index: 10001;
                    border-radius: var(--br, 2px);
                }
                @keyframes confettiFly {
                    0%   {
                        opacity: 0;
                        transform: translate(0, 0) rotate(0deg) scale(0.5);
                    }
                    8%   {
                        opacity: 1;
                        transform: translate(calc(var(--tx,0px) * 0.15), calc(var(--ty,0px) * 0.15))
                                   rotate(calc(var(--rot,180deg) * 0.1)) scale(1.3);
                    }
                    25%  {
                        opacity: 1;
                        transform: translate(calc(var(--tx,0px) * 0.5), calc(var(--ty,0px) * 0.5))
                                   rotate(calc(var(--rot,180deg) * 0.35)) scale(1.05);
                    }
                    55%  {
                        opacity: 0.95;
                        transform: translate(calc(var(--tx,0px) * 0.82), calc(var(--ty,0px) * 0.82))
                                   rotate(calc(var(--rot,180deg) * 0.7)) scale(0.9);
                    }
                    78%  {
                        opacity: 0.7;
                        transform: translate(calc(var(--tx,0px) * 0.97), calc(var(--ty,0px) * 1.1))
                                   rotate(calc(var(--rot,180deg) * 0.9)) scale(0.65);
                    }
                    100% {
                        opacity: 0;
                        transform: translate(var(--tx,0px), calc(var(--ty,0px) + 70px))
                                   rotate(var(--rot,360deg)) scale(0.2);
                    }
                }

                /* ── IKONA – zielony krag z fistaszkiem ─────────────────── */
                .success-icon {
                    width: 80px;
                    height: 80px;
                    background: linear-gradient(145deg, #12d68f, #059669);
                    border-radius: 50%;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    margin: 4px auto 14px;
                    border: 4px solid #ffffff;
                    outline: 3px solid rgba(16,185,129,0.25);
                    box-shadow:
                        0 8px 24px rgba(16,185,129,0.45),
                        0 0 0 0px rgba(16,185,129,0.3);
                    animation: successPop 0.6s cubic-bezier(0.68,-0.55,0.265,1.55) both;
                }

                /* PULSUJACY ZIELONY KRAG z falujaca aureola */
                .pulsing-checkmark {
                    animation:
                        successPop  0.6s  cubic-bezier(0.68,-0.55,0.265,1.55) both,
                        circlePulse 2.0s  ease-in-out 0.7s infinite;
                    will-change: transform, box-shadow;
                }

                @keyframes circlePulse {
                    0%, 100% {
                        transform: scale(1);
                        box-shadow:
                            0 8px 24px rgba(16,185,129,0.45),
                            0 0 0  0px rgba(16,185,129,0.30);
                        outline-color: rgba(16,185,129,0.25);
                    }
                    50% {
                        transform: scale(1.09);
                        box-shadow:
                            0 12px 36px rgba(16,185,129,0.60),
                            0 0 0 16px rgba(16,185,129,0.10);
                        outline-color: rgba(16,185,129,0.45);
                    }
                }

                @keyframes successPop {
                    0%   { transform: scale(0) rotate(-180deg); opacity: 0; }
                    65%  { transform: scale(1.2) rotate(10deg); }
                    100% { transform: scale(1) rotate(0deg); opacity: 1; }
                }

                /* ── TYTUL ──────────────────────────────────────────────── */
                .success-title {
                    font-size: 21px;
                    font-weight: 800;
                    color: #059669;
                    margin: 0 0 6px;
                    letter-spacing: -0.4px;
                }

                /* ── KOMUNIKAT ──────────────────────────────────────────── */
                .success-message {
                    font-size: 12.5px;
                    color: #6b7280;
                    line-height: 1.55;
                    margin: 0 0 14px;
                }

                /* ── POLE PACZKOMATU ────────────────────────────────────── */
                @keyframes lockerBoxGlow {
                    0%, 100% {
                        border-color: rgba(255,102,0,0.6);
                        box-shadow: 0 2px 10px rgba(255,102,0,0.14);
                    }
                    50% {
                        border-color: #FF6600;
                        box-shadow: 0 5px 22px rgba(255,102,0,0.30);
                    }
                }

                .success-locker-info {
                    background: linear-gradient(135deg, #fff9f5, #fff3eb);
                    border: 2px solid #FF6600;
                    border-radius: 12px;
                    padding: 12px 14px;
                    margin-bottom: 10px;
                    text-align: left;
                    animation: lockerBoxGlow 2.5s ease-in-out infinite;
                }

                .success-locker-info .locker-name {
                    font-size: 18px;
                    font-weight: 900;
                    color: #FF6600;
                    margin-bottom: 5px;
                    letter-spacing: 0.6px;
                }

                .success-locker-info .locker-address {
                    font-size: 12.5px;
                    color: #374151;
                    line-height: 1.65;
                }

                /* ── CZAS DOSTAWY ───────────────────────────────────────── */
                .success-delivery-time {
                    font-size: 12.5px;
                    color: #374151;
                    margin-bottom: 10px;
                    padding: 8px 12px;
                    background: #f0fdf4;
                    border-radius: 9px;
                    border-left: 4px solid #10b981;
                    text-align: left;
                }

                .success-delivery-time strong {
                    color: #059669;
                    font-weight: 800;
                }

                /* ── COUNTDOWN ──────────────────────────────────────────── */
                .success-countdown {
                    font-size: 12px;
                    color: #9ca3af;
                    margin-bottom: 14px;
                    letter-spacing: 0.1px;
                }

                #countdown-timer {
                    font-weight: 900;
                    color: #FF6600;
                    font-size: 16px;
                }

                /* ── CZAS DO WYBORU (flaga finisz) ─────────────────────── */
                .success-finish-time {
                    background: linear-gradient(135deg, #10b981, #059669);
                    color: #fff;
                    font-size: 15px;
                    font-weight: 800;
                    text-align: center;
                    padding: 8px 20px;
                    border-radius: 30px;
                    margin: 0 auto 12px;
                    letter-spacing: 0.3px;
                    font-variant-numeric: tabular-nums;
                    box-shadow: 0 4px 16px rgba(16,185,129,0.4);
                    display: inline-block;
                }

                /* ── STOPWATCH (od wyboru) ───────────────────────────────── */
                .success-stopwatch {
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    gap: 6px;
                    font-size: 11px;
                    color: #6b7280;
                    margin-bottom: 14px;
                    letter-spacing: 0.1px;
                }
                .stopwatch-value {
                    font-weight: 700;
                    font-size: 13px;
                    color: #374151;
                    font-variant-numeric: tabular-nums;
                    min-width: 36px;
                    text-align: left;
                    transition: color 0.3s;
                }

                /* ── PRZYCISKI ──────────────────────────────────────────── */
                .success-buttons {
                    display: flex;
                    flex-direction: column;
                    gap: 8px;
                }

                .success-btn-change {
                    width: 100%;
                    padding: 12px 16px;
                    background: linear-gradient(135deg, #FF6600, #FF8C00);
                    color: #fff;
                    border: none;
                    border-radius: 10px;
                    font-size: 14px;
                    font-weight: 800;
                    cursor: pointer;
                    letter-spacing: 0.3px;
                    transition: transform 0.15s, box-shadow 0.15s;
                    box-shadow: 0 4px 14px rgba(255,102,0,0.40);
                    font-family: var(--ps-font);
                }

                .success-btn-change:hover {
                    transform: translateY(-2px);
                    box-shadow: 0 8px 22px rgba(255,102,0,0.55);
                }

                .success-btn-close {
                    width: 100%;
                    padding: 10px 16px;
                    background: #ffffff;
                    color: #6b7280;
                    border: 1.5px solid #e5e7eb;
                    border-radius: 10px;
                    font-size: 13px;
                    font-weight: 600;
                    cursor: pointer;
                    transition: border-color 0.15s, color 0.15s, transform 0.15s;
                    font-family: var(--ps-font);
                }

                .success-btn-close:hover {
                    border-color: #9ca3af;
                    color: #374151;
                    transform: translateY(-1px);
                }
                
                /* MARKER PULSE ANIMATION (ZOOM 1-600%) */
                @keyframes markerPulse {
                    0% {
                        transform: scale(1);
                    }
                    25% {
                        transform: scale(6);
                    }
                    50% {
                        transform: scale(1);
                    }
                    75% {
                        transform: scale(4);
                    }
                    100% {
                        transform: scale(1);
                    }
                }
                
                .marker-pulse-animation {
                    animation: markerPulse 3s ease-in-out;
                    transform-origin: center bottom;
                    z-index: 10000 !important;
                }
                
                /* ═══════════════════════════════════════════════════════════════
                   🎨 KOLORY PINEZEK - DEFINICJE
                   ═══════════════════════════════════════════════════════════════ */
                :root {
                    --marker-original-hue: 0deg;       /* Oryginalny kolor (czerwony) */
                    --marker-selected-hue: 0deg;       /* Podczas wyboru (czerwony) */
                    --marker-success-hue: 95deg;       /* Po akceptacji (ZIELONY) */
                    --marker-success-saturation: 1.8;
                    --marker-success-brightness: 1.2;
                    --marker-success-shadow: rgba(16, 185, 129, 0.9);
                }
                
                /* CIĄGŁE PULSOWANIE MARKERA (przez cały countdown) */
                /* FINALNA WERSJA v2.33.0: Oryginalna pinezka → ZIELONA tylko po success */
                
                .marker-pulse-continuous {
                    z-index: 10000 !important;
                }
                
                /* Statyczne powiększenie 3X - ORYGINALNY KOLOR podczas wyboru */
                .marker-pulse-continuous img {
                    transform: scale(3) !important;
                    transform-origin: center bottom !important;  /* Dół pinezki w miejscu */
                    /* BRAK FILTRA - oryginalny kolor pinezki */
                }
                
                /* ZIELONA pinezka PO POKAZANIU SUCCESS PANEL - statyczne 3X */
                .marker-pulse-continuous.marker-success img {
                    transform: scale(3) !important;
                    transform-origin: center bottom !important;
                    filter: 
                        hue-rotate(var(--marker-success-hue))  /* ZIELONY */
                        saturate(var(--marker-success-saturation)) 
                        brightness(var(--marker-success-brightness))
                        drop-shadow(0 0 15px var(--marker-success-shadow)) !important;
                }
                
                /* ============================================
                   ANIMACJA BOUNCE - PINEZKA ODBIJA SIĘ 3 RAZY
                   Używa TOP zamiast transform - nie nadpisuje Leaflet!
                   ============================================ */
                
                @keyframes pinezkaBounce {
                    0% {
                        top: -150px;
                        transform: scale(0.8);
                        opacity: 0;
                    }
                    /* Pierwsze odbicie - najwyższe */
                    15% {
                        top: 0;
                        transform: scale(1.3);
                    }
                    25% {
                        top: -80px;
                        transform: scale(1.1);
                    }
                    /* Drugie odbicie - średnie */
                    35% {
                        top: 0;
                        transform: scale(1.2);
                    }
                    45% {
                        top: -40px;
                        transform: scale(1.05);
                    }
                    /* Trzecie odbicie - najniższe */
                    55% {
                        top: 0;
                        transform: scale(1.1);
                    }
                    65% {
                        top: -15px;
                        transform: scale(1.02);
                    }
                    /* Lądowanie */
                    75%, 100% {
                        top: 0;
                        transform: scale(1);
                        opacity: 1;
                    }
                }
                
                /* Bounce dla ZIELONEJ pinezki */
                @keyframes pinezkaBounceGreen {
                    0% {
                        top: -150px;
                        transform: scale(0.8);
                        opacity: 0;
                    }
                    15% {
                        top: 0;
                        transform: scale(1.3);
                    }
                    25% {
                        top: -80px;
                        transform: scale(1.1);
                    }
                    35% {
                        top: 0;
                        transform: scale(1.2);
                    }
                    45% {
                        top: -40px;
                        transform: scale(1.05);
                    }
                    55% {
                        top: 0;
                        transform: scale(1.1);
                    }
                    65% {
                        top: -15px;
                        transform: scale(1.02);
                    }
                    75%, 100% {
                        top: 0;
                        transform: scale(1);
                        opacity: 1;
                    }
                }
                
                /* Delikatne pulsowanie PO bounce - oryginalna */
                @keyframes pinezkaPulse {
                    0%, 100% {
                        top: 0;
                        transform: scale(1);
                    }
                    50% {
                        top: 0;
                        transform: scale(1.1);
                    }
                }
                
                /* Delikatne pulsowanie PO bounce - zielona */
                @keyframes pinezkaGreenPulse {
                    0%, 100% {
                        top: 0;
                        transform: scale(1);
                        filter: hue-rotate(95deg) saturate(2.0) brightness(1.3) drop-shadow(0 0 20px rgba(16, 185, 129, 0.9)) drop-shadow(0 8px 16px rgba(0, 0, 0, 0.3));
                    }
                    50% {
                        top: 0;
                        transform: scale(1.15);
                        filter: hue-rotate(95deg) saturate(2.2) brightness(1.5) drop-shadow(0 0 30px rgba(16, 185, 129, 1)) drop-shadow(0 10px 20px rgba(0, 0, 0, 0.4));
                    }
                }
                
                /* ZIELONY PROMIEŃ ŚWIETLNY - pulsuje */
                @keyframes beamPulse {
                    0%, 100% {
                        opacity: 0.8;
                        height: 100px;
                        box-shadow: 0 0 20px rgba(16, 185, 129, 0.8);
                    }
                    50% {
                        opacity: 1;
                        height: 120px;
                        box-shadow: 0 0 40px rgba(16, 185, 129, 1);
                    }
                }
                
                /* ZIELONA KROPKA na końcu pinezki - wskazuje PUNKT */
                .marker-pulse-continuous.marker-success::after {
                    content: '';
                    position: absolute;
                    bottom: 0px;  /* Na samym dole pinezki */
                    left: 50%;
                    transform: translateX(-50%);
                    width: 12px;
                    height: 12px;
                    background: radial-gradient(circle, #10b981 0%, #059669 100%);
                    border: 2px solid white;
                    border-radius: 50%;
                    box-shadow: 0 0 15px rgba(16, 185, 129, 0.8);
                    z-index: 10001;
                    animation: kropkaPulse 2s ease-in-out infinite;
                }
                
                /* Pulsowanie zielonej kropki */
                @keyframes kropkaPulse {
                    0%, 100% {
                        transform: translateX(-50%) scale(1);
                        opacity: 1;
                    }
                    50% {
                        transform: translateX(-50%) scale(1.3);
                        opacity: 0.8;
                        box-shadow: 0 0 25px rgba(16, 185, 129, 1);
                    }
                }
                
                /* ZIELONA KROPKA na punkcie paczkomatu - TYLKO dla success! */
                .marker-pulse-continuous.marker-success::after {
                    content: '';
                    position: absolute;
                    bottom: 0px;               /* Na samym dole pinezki */
                    left: 50%;
                    transform: translateX(-50%);
                    width: 12px;
                    height: 12px;
                    background: radial-gradient(circle, #10b981 0%, #059669 100%);
                    border: 2px solid white;
                    border-radius: 50%;
                    box-shadow: 0 0 15px rgba(16, 185, 129, 0.8), 0 0 8px rgba(16, 185, 129, 1);
                    animation: kropkaPulse 2s ease-in-out infinite;
                    pointer-events: none;
                    z-index: 10001;
                }
                
                @keyframes kropkaPulse {
                    0%, 100% {
                        box-shadow: 0 0 15px rgba(16, 185, 129, 0.8), 0 0 8px rgba(16, 185, 129, 1);
                    }
                    50% {
                        box-shadow: 0 0 25px rgba(16, 185, 129, 1), 0 0 15px rgba(16, 185, 129, 1);
                    }
                }
                
                /* FORCE VISIBLE MARKER - NIE POZWÓL ZNIKNĄĆ! */
                .force-visible-marker {
                    display: block !important;
                    visibility: visible !important;
                    opacity: 1 !important;
                    pointer-events: auto !important;
                }
                
                /* RIPPLE EFFECT ANIMATION (CSS DIV) - ŻÓŁTY */
                @keyframes rippleExpand {
                    0% {
                        transform: scale(1);
                        opacity: 0.6;
                    }
                    100% {
                        transform: scale(25);
                        opacity: 0;
                    }
                }
                
                .parcel-ripple-effect {
                    animation: rippleExpand 2s ease-out forwards;
                }
                
                /* ZIELONY RIPPLE - POTWIERDZENIE (mniejszy, na końcu) */
                @keyframes greenRippleExpand {
                    0% {
                        transform: scale(1);
                        opacity: 0.8;
                        border-color: #10b981;
                        background: rgba(16, 185, 129, 0.3);
                    }
                    100% {
                        transform: scale(12);
                        opacity: 0;
                        border-color: #10b981;
                        background: rgba(16, 185, 129, 0);
                    }
                }
                
                .parcel-green-ripple {
                    animation: greenRippleExpand 1.5s ease-out forwards;
                    border-color: #10b981 !important;
                }
                
                /* STATUS PANEL NA DOLE */
                .parcel-status-panel {
                    display: none;
                    background: linear-gradient(135deg, #10b981 0%, #059669 100%);
                    color: white;
                    padding: 16px 20px;
                    border-radius: 12px;
                    margin-bottom: 16px;
                }
                
                .status-panel-content {
                    display: flex;
                    align-items: center;
                    gap: 12px;
                }
                
                .status-label {
                    font-size: 14px;
                    font-weight: 600;
                    flex-shrink: 0;
                }
                
                .status-locker {
                    flex: 1;
                    display: flex;
                    flex-direction: column;
                    gap: 4px;
                }
                
                .status-locker strong {
                    font-size: 15px;
                }
                
                .status-address {
                    font-size: 13px;
                    opacity: 0.9;
                }
                
                .status-change-btn {
                    padding: 8px 16px;
                    background: rgba(255, 255, 255, 0.2);
                    color: white;
                    border: 1px solid rgba(255, 255, 255, 0.4);
                    border-radius: 6px;
                    font-size: 13px;
                    font-weight: 600;
                    cursor: pointer;
                    transition: all 0.3s;
                    flex-shrink: 0;
                }
                
                .status-change-btn:hover {
                    background: rgba(255, 255, 255, 0.3);
                }
            `;
            
            document.head.appendChild(style);
            window.PS_DEBUG&&console.log('[Parcel Locker Selector] 🎨 Style CSS dodane');
        }
    };
    
    // ====================
    // EXPOSE DO GLOBAL SCOPE
    // ====================
    window.ParcelLockerSelector = ParcelLockerSelector;
    
    // Auto-inicjalizacja
    document.addEventListener('DOMContentLoaded', function() {
        ParcelLockerSelector.init();
    });
    
})();
