document.addEventListener('DOMContentLoaded', function() {

    /**
     * ===================================================================
     * 1. OSNOVNA FUNKCIONALNOST MOBILNE NAVIGACIJE
     * ===================================================================
     */

    // === MOBILNI MENI: Preklop vidnosti menija ===
    try {
        const icon = document.querySelector('.mobile-menu-icon');
        const root = document.documentElement;

        if (!icon) {
            console.error('Mobile menu icon not found.');
        } else {
            // Accessibility: the icon is a <div>, so expose it to keyboard and
            // screen-reader users as a button (focusable, labelled, toggle state).
            if (!icon.hasAttribute('role')) icon.setAttribute('role', 'button');
            if (!icon.hasAttribute('tabindex')) icon.setAttribute('tabindex', '0');
            if (!icon.hasAttribute('aria-label')) icon.setAttribute('aria-label', 'Open menu');
            icon.setAttribute('aria-expanded', 'false');

            const setMenu = (open) => {
                root.classList.toggle('nav-open', open);
                icon.setAttribute('aria-expanded', open ? 'true' : 'false');
                icon.setAttribute('aria-label', open ? 'Close menu' : 'Open menu');
            };

            icon.addEventListener('click', (e) => {
                e.preventDefault();
                e.stopPropagation();
                setMenu(!root.classList.contains('nav-open'));
            });

            // Activate with Enter / Space like a native button.
            icon.addEventListener('keydown', (e) => {
                if (e.key === 'Enter' || e.key === ' ' || e.key === 'Spacebar') {
                    e.preventDefault();
                    setMenu(!root.classList.contains('nav-open'));
                }
            });

            document.addEventListener('click', (e) => {
                if (root.classList.contains('nav-open') && !e.target.closest('.mobile-nav-panel') && !e.target.closest('.mobile-menu-icon')) {
                    setMenu(false);
                }
            });

            document.addEventListener('keydown', (e) => {
                if (e.key === 'Escape') {
                    setMenu(false);
                }
            });
        }
    } catch (err) {
        console.error('Error in Mobile Menu Toggle:', err);
    }

    // --- Mobilni Accordion podmeni ---
    try {
        const mobileNav = document.querySelector('.mobile-nav-panel .mobile-nav');
        if (mobileNav) {
            const menuItemsWithChildren = mobileNav.querySelectorAll('.menu-item-has-children');

            menuItemsWithChildren.forEach(item => {
                const link = item.querySelector('a');
                if (link) {
                    link.addEventListener('click', (event) => {
                        if (event.currentTarget.parentElement.classList.contains('menu-item-has-children')) {
                            event.preventDefault();
                        }

                        const parentLi = event.currentTarget.parentElement;

                        menuItemsWithChildren.forEach(otherItem => {
                            if (otherItem !== parentLi && otherItem.classList.contains('open')) {
                                otherItem.classList.remove('open');
                            }
                        });

                        parentLi.classList.toggle('open');
                    });
                }
            });
        }
    } catch (error) {
        console.error('Error in Mobile Accordion Menu:', error);
    }

    // Desktop: top-level dropdown parents (Who We Are, What We Do, For Students) are
    // triggers, not real pages. Their href="#" caused a dead "/en/#" navigation on click.
    // The submenu already opens on hover, so just cancel the navigation.
    try {
        document.querySelectorAll('.desktop-nav .menu-item-has-children > a').forEach((a) => {
            a.addEventListener('click', (e) => { e.preventDefault(); });
        });
    } catch (error) {
        console.error('Error disabling desktop dropdown parent links:', error);
    }


    /**
     * ===================================================================
     * 2. IZBOLJŠAVE UPORABNIŠKE IZKUŠNJE (UX/UI)
     * ===================================================================
     */

    // --- Funkcija za poudarjanje aktivne povezave v navigaciji ---
    function highlightActiveLink() {
        try {
            const currentPath = window.location.pathname;
            const navLinks = document.querySelectorAll('.navigation a');
            let bestMatch = null;
            let longestMatch = 0;

            navLinks.forEach(link => {
                if (link.closest('.dropdown-menu')) return;
                
                const linkPath = new URL(link.href, window.location.origin).pathname;

                if (currentPath.startsWith(linkPath) && linkPath.length > longestMatch) {
                    longestMatch = linkPath.length;
                    bestMatch = link;
                }
            });
            
            if (bestMatch) {
                const parentMenuItem = bestMatch.closest('.menu-item');
                if (parentMenuItem) {
                    parentMenuItem.classList.add('active-page');
                }
            }
        } catch (error) {
            console.error("Error highlighting active link:", error);
        }
    }


    // --- Funkcionalnost za preklopnik jezika (Desktop Dropdown + Mobile Modal) ---
    function setupLanguageSwitcher() {
        try {
            const path = window.location.pathname;
            const pathParts = path.split('/').filter(Boolean);
            const validLangs = ['en', 'si', 'mk'];
            let pathWithoutLang = '/';

            if (pathParts.length > 0 && validLangs.includes(pathParts[0])) {
                pathWithoutLang = '/' + pathParts.slice(1).join('/');
                if (path.endsWith('/') && pathWithoutLang !== '/') {
                    pathWithoutLang += '/';
                }
            } else {
                pathWithoutLang = path;
            }

            let docLang = (document.documentElement.getAttribute('lang') || 'en').toLowerCase();
            if (docLang === 'sl') docLang = 'si'; // <html lang="sl"> (correct ISO for Slovene) maps to the site's /si/ locale
            document.querySelectorAll('a[data-lang]').forEach(link => {
                const targetLang = link.getAttribute('data-lang');
                const newUrl = `/${targetLang}${pathWithoutLang}`;
                link.setAttribute('href', newUrl.replace(/\/{2,}/g, '/'));
                link.classList.toggle('is-current', targetLang === docLang);
                // Manually choosing a language is a deliberate preference — don't nag with the banner afterwards.
                link.addEventListener('click', () => {
                    try { localStorage.setItem('msos-lang-banner', 'dismissed'); } catch (e) {}
                });
            });

            const desktopSelectors = document.querySelectorAll('.header-right-wrapper .language-selector');
            desktopSelectors.forEach(selector => {
                const currentLang = selector.querySelector('.current-lang');
                if (currentLang) {
                    currentLang.addEventListener('click', (event) => {
                        event.stopPropagation();
                        const isActive = selector.classList.contains('active');
                        document.querySelectorAll('.language-selector.active').forEach(s => s.classList.remove('active'));
                        if (!isActive) {
                            selector.classList.add('active');
                        }
                    });
                }
            });
            
            window.addEventListener('click', () => {
                desktopSelectors.forEach(s => s.classList.remove('active'));
            });

            const mobileLangButton = document.getElementById('mobile-lang-trigger');
            const languageModal = document.getElementById('language-modal-overlay');
            const closeModalButton = document.getElementById('language-modal-close');

            if (mobileLangButton && languageModal && closeModalButton) {
                mobileLangButton.addEventListener('click', (e) => {
                    e.preventDefault();
                    e.stopPropagation();
                    languageModal.classList.add('active');
                });

                const closeModal = () => {
                    languageModal.classList.remove('active');
                };

                closeModalButton.addEventListener('click', closeModal);
                languageModal.addEventListener('click', (e) => {
                    if (e.target === languageModal) closeModal();
                });
                document.addEventListener('keydown', (e) => {
                    if (e.key === 'Escape' && languageModal.classList.contains('active')) closeModal();
                });
            }

        } catch (error) {
            console.error('Error in Language Switcher setup:', error);
        }
    }


    /**
     * ===================================================================
     * 3. OSTALE FUNKCIONALNOSTI (FAQ, ACTIVITIES, ITD.)
     * ===================================================================
     */

    // --- FAQ Accordion ---
    try {
        document.querySelectorAll('.faq-item h3').forEach(header => {
            header.addEventListener('click', () => {
                const faqItem = header.parentElement;
                faqItem.classList.toggle('open');
            });
        });
    } catch (error) {
        console.error('Error in FAQ Accordion:', error);
    }

    // --- Activities Tabs ---
    // Index-based: content lives in the HTML panels (one per language),
    // so switching works regardless of the tab label language.
    try {
        const activityTabs = document.querySelectorAll('.activities-nav .activity-tab');
        const activityPanels = document.querySelectorAll('.activities-panels .activity-panel');

        if (activityTabs.length > 0 && activityPanels.length > 0) {
            activityTabs.forEach(tab => {
                tab.addEventListener('click', () => {
                    const idx = tab.getAttribute('data-panel');

                    activityTabs.forEach(t => {
                        t.classList.remove('active');
                        t.setAttribute('aria-selected', 'false');
                    });
                    activityPanels.forEach(p => {
                        p.classList.remove('active');
                        p.hidden = true;
                    });

                    tab.classList.add('active');
                    tab.setAttribute('aria-selected', 'true');

                    const panel = document.querySelector(
                        `.activities-panels .activity-panel[data-panel="${idx}"]`
                    );
                    if (panel) {
                        panel.hidden = false;
                        panel.classList.add('active');
                    }
                });
            });
        }
    } catch (error) {
        console.error('Error in Activities Tabs:', error);
    }

    /**
     * ===================================================================
     * 4. INTERAKTIVNA SEKCIJA "MISSION & VISION"
     * ===================================================================
     */
    try {
        const missionVisionContainer = document.getElementById('mission-vision-interactive');
        
        if (missionVisionContainer) {
            const missionBox = missionVisionContainer.querySelector('.mission-box');
            const visionBox = missionVisionContainer.querySelector('.vision-box');

            missionBox.addEventListener('mouseenter', () => {
                missionVisionContainer.classList.remove('show-vision');
            });

            visionBox.addEventListener('mouseenter', () => {
                missionVisionContainer.classList.add('show-vision');
            });
        }
    } catch(error) {
        console.error('Error in Mission/Vision interaction setup:', error);
    }
    
    /**
     * ===================================================================
     * 5. SCROLLSPY IN PROGRESS BAR ZA STRANI ČLANKOV (POSODOBLJENO)
     * ===================================================================
     */
    try {
        const articlePage = document.querySelector('.article-page');
        if (articlePage) {
            const articleContainer = articlePage.querySelector('.article-container');
            const articleBody = articlePage.querySelector('.article-body');
            const headings = articleBody ? Array.from(articleBody.querySelectorAll('h2')) : [];
            const articleTitleEl = articlePage.querySelector('.article-header h1');
            const articleTitle = articleTitleEl ? articleTitleEl.textContent.trim()
                                                : (document.title || '').trim();

            // Label for a heading in the table of contents. An optional
            // data-nav-title attribute lets an article override the full <h2>
            // text with a shorter label; otherwise we use the heading text.
            const navLabel = (heading) =>
                (heading.getAttribute('data-nav-title') || heading.textContent).trim();

            // --- 5a. Zagotovi, da ima vsak naslov enoličen id (za sidra) ---
            // Transliterate then slugify so anchors are readable in every language:
            // Slovenian diacritics (č/š/ž/…) and Macedonian Cyrillic map to ASCII.
            // Anything still unmapped is dropped and falls back to section-N below.
            const TRANSLIT = {
                // Slovenian / Latin diacritics
                'č':'c','ć':'c','š':'s','ž':'z','đ':'dj',
                'á':'a','à':'a','â':'a','ä':'a','ã':'a','é':'e','è':'e','ê':'e','ë':'e',
                'í':'i','ì':'i','î':'i','ï':'i','ó':'o','ò':'o','ô':'o','ö':'o','õ':'o',
                'ú':'u','ù':'u','û':'u','ü':'u','ñ':'n','ç':'c','ß':'ss',
                // Macedonian Cyrillic
                'а':'a','б':'b','в':'v','г':'g','д':'d','ѓ':'gj','е':'e','ж':'zh','з':'z',
                'ѕ':'dz','и':'i','ј':'j','к':'k','л':'l','љ':'lj','м':'m','н':'n','њ':'nj',
                'о':'o','п':'p','р':'r','с':'s','т':'t','ќ':'kj','у':'u','ф':'f','х':'h',
                'ц':'c','ч':'ch','џ':'dj','ш':'sh'
            };
            const usedIds = new Set();
            const transliterate = (text) =>
                text.replace(/[^\x00-\x7F]/g, (ch) => (ch in TRANSLIT ? TRANSLIT[ch] : ''));
            const slugify = (text) => transliterate(text.toLowerCase())
                .replace(/[^a-z0-9]+/g, '-')
                .replace(/^-+|-+$/g, '');
            headings.forEach((heading, i) => {
                let id = heading.id || slugify(heading.textContent);
                if (id.length < 2) id = 'section-' + (i + 1);
                let unique = id, n = 2;
                while (usedIds.has(unique)) { unique = id + '-' + (n++); }
                usedIds.add(unique);
                heading.id = unique;
            });

            // --- 5b. Zagotovi postavitveni ovoj in stransko vrstico (Desktop) ---
            // Older article pages (SI/MK and some EN) ship without the TOC
            // scaffolding, so we build it here from the page's own headings.
            let layoutContainer = articlePage.querySelector('.article-layout-container');
            if (!layoutContainer && articleContainer) {
                layoutContainer = document.createElement('div');
                layoutContainer.className = 'article-layout-container';
                articleContainer.parentNode.insertBefore(layoutContainer, articleContainer);
                layoutContainer.appendChild(articleContainer);
            }

            let sidebar = articlePage.querySelector('.article-sidebar');
            if (!sidebar && layoutContainer && headings.length > 0) {
                sidebar = document.createElement('aside');
                sidebar.className = 'article-sidebar';
                sidebar.innerHTML = '<nav class="scrollspy-nav"><ul></ul></nav>';
                layoutContainer.insertBefore(sidebar, layoutContainer.firstChild);
            }

            const scrollspyNav = sidebar ? sidebar.querySelector('.scrollspy-nav') : null;
            const desktopUl = scrollspyNav ? scrollspyNav.querySelector('ul') : null;

            // --- 5c. Napolni namizni seznam, če je prazen (ohrani ročno napisanega) ---
            if (desktopUl && desktopUl.children.length === 0 && headings.length > 0) {
                headings.forEach(heading => {
                    const li = document.createElement('li');
                    const a = document.createElement('a');
                    a.href = '#' + heading.id;
                    a.textContent = navLabel(heading);
                    li.appendChild(a);
                    desktopUl.appendChild(li);
                });
            }

            // --- 5d. Naslov članka nad kazalom (Desktop) ---
            if (sidebar && !sidebar.querySelector('.article-sidebar-title') && articleTitle) {
                const titleEl = document.createElement('p');
                titleEl.className = 'article-sidebar-title';
                titleEl.textContent = articleTitle;
                sidebar.insertBefore(titleEl, sidebar.firstChild);
            }

            // --- 5e. Zagotovi lepljivo mobilno glavo z naslovom + progress bar ---
            let mobileHeader = articlePage.querySelector('.mobile-article-header');
            if (!mobileHeader && headings.length > 0) {
                mobileHeader = document.createElement('div');
                mobileHeader.className = 'mobile-article-header';
                mobileHeader.innerHTML =
                    '<span id="mobile-article-title"></span>' +
                    '<i class="fas fa-chevron-down"></i>' +
                    '<div class="progress-bar-container"><div class="progress-bar"></div></div>' +
                    '<div class="mobile-scrollspy-dropdown"><ul id="mobile-scrollspy-links"></ul></div>';
                articlePage.insertBefore(mobileHeader, articlePage.firstChild);
            }

            const mobileTitle = document.getElementById('mobile-article-title');
            if (mobileTitle && !mobileTitle.textContent.trim()) {
                mobileTitle.textContent = articleTitle; // known at load; scrollspy refines it
            }
            const mobileDropdown = articlePage.querySelector('.mobile-scrollspy-dropdown');
            const mobileLinksContainer = document.getElementById('mobile-scrollspy-links');
            const progressBar = articlePage.querySelector('.progress-bar');
            const desktopNavLinks = desktopUl ? Array.from(desktopUl.querySelectorAll('a')) : [];

            // --- 5f. Napolni mobilni spustni seznam ---
            if (headings.length > 0 && mobileLinksContainer && mobileLinksContainer.children.length === 0) {
                headings.forEach(heading => {
                    const listItem = document.createElement('li');
                    const link = document.createElement('a');
                    link.href = '#' + heading.id;
                    link.textContent = navLabel(heading);
                    listItem.appendChild(link);
                    mobileLinksContainer.appendChild(listItem);
                });
            }

            // --- 5g. Odpiranje/zapiranje mobilnega spustnega seznama ---
            if (mobileHeader && mobileDropdown) {
                mobileHeader.addEventListener('click', (e) => {
                    if (!e.target.closest('a')) {
                        mobileHeader.classList.toggle('open');
                        mobileDropdown.classList.toggle('open');
                    }
                });
                mobileDropdown.querySelectorAll('a').forEach(link => {
                    link.addEventListener('click', () => {
                        mobileHeader.classList.remove('open');
                        mobileDropdown.classList.remove('open');
                    });
                });
            }

            // --- 5h. Progress Bar ---
            function updateProgressBar() {
                if (!progressBar) return;
                const scrollableHeight = document.documentElement.scrollHeight - window.innerHeight;
                const scrollTop = window.scrollY;
                progressBar.style.width = scrollableHeight > 0
                    ? `${(scrollTop / scrollableHeight) * 100}%`
                    : '0%';
            }

            // --- 5i. Scrollspy (posodobi navigacijo, naslov in URL sidro) ---
            if (headings.length > 0) {
                let activeId = null;
                const observer = new IntersectionObserver((entries) => {
                    entries.forEach(entry => {
                        if (!entry.isIntersecting) return;
                        const id = entry.target.id;
                        if (id === activeId) return;
                        activeId = id;

                        // Namizna navigacija
                        const desktopNavLink = desktopNavLinks.find(link => link.getAttribute('href') === `#${id}`);
                        if (desktopNavLink) {
                            desktopNavLinks.forEach(link => link.classList.remove('active'));
                            desktopNavLink.classList.add('active');
                        }
                        // Mobilni naslov + aktivna povezava
                        if (mobileTitle) mobileTitle.textContent = navLabel(entry.target);
                        if (mobileLinksContainer) {
                            const mobileNavLink = mobileLinksContainer.querySelector(`a[href="#${id}"]`);
                            if (mobileNavLink) {
                                mobileLinksContainer.querySelectorAll('a').forEach(link => link.classList.remove('active'));
                                mobileNavLink.classList.add('active');
                            }
                        }
                        // Posodobi URL sidro brez skoka in brez polnjenja zgodovine
                        if (window.history && history.replaceState) {
                            history.replaceState(null, '', '#' + id);
                        }
                    });
                }, {
                    rootMargin: "-100px 0px -55% 0px" // Sproži, ko je naslov v zgornjem delu zaslona
                });

                headings.forEach(heading => observer.observe(heading));
            }

            window.addEventListener('scroll', updateProgressBar);
            updateProgressBar();
        }
    } catch (error) {
        console.error('Error in Article Scrollspy/Progress Bar setup:', error);
    }

    /**
     * ===================================================================
     * 6. FILTER KATEGORIJ ZA SEZNAM PROJEKTOV / OBJAV
     * ===================================================================
     *
     * Deluje na katerikoli strani s seznamom (projekti, novice, ...).
     * Popolnoma jezikovno neodvisen: gumbi nosijo stabilni ključ
     * (data-filter / data-subfilter), kartice pa data-category /
     * data-subcategory. Oznake so lahko v katerem koli jeziku.
     */
    try {
        const grid = document.querySelector('.posts-grid');

        if (grid) {
            const filterSection = document.querySelector('.filter-section');
            const pagination = document.querySelector('.pagination');
            const cards = Array.from(grid.querySelectorAll('.post-card'));
            const emptyMsg = document.querySelector('.filter-empty');

            // Koliko kartic na stran. Ko bo objav več kot toliko, se
            // paginacija samodejno vklopi; do takrat prikaže eno stran.
            const PAGE_SIZE = 9;

            let activeCat = 'all';
            let activeSub = 'all';
            let currentPage = 1;
            let matching = cards.slice();

            // --- Paginacija ---
            const pageNumbers = pagination ? pagination.querySelector('.pagination-numbers') : null;
            const arrows = pagination ? pagination.querySelectorAll('.pagination-arrow') : [];
            const prevArrow = arrows.length ? arrows[0] : null;
            const nextArrow = arrows.length > 1 ? arrows[arrows.length - 1] : null;

            const totalPages = () => Math.max(1, Math.ceil(matching.length / PAGE_SIZE));

            const renderPageNumbers = (total) => {
                if (!pageNumbers) return;
                pageNumbers.innerHTML = '';
                const addNum = (n) => {
                    const a = document.createElement('a');
                    a.href = '#';
                    a.className = 'page-number' + (n === currentPage ? ' active' : '');
                    a.textContent = n;
                    a.addEventListener('click', (e) => { e.preventDefault(); goToPage(n); });
                    pageNumbers.appendChild(a);
                };
                const addDots = () => {
                    const s = document.createElement('span');
                    s.className = 'page-dots';
                    s.textContent = '...';
                    pageNumbers.appendChild(s);
                };
                // Do 7 strani pokažemo vse; sicer okno okoli trenutne strani.
                const seq = [];
                if (total <= 7) {
                    for (let i = 1; i <= total; i++) seq.push(i);
                } else {
                    seq.push(1);
                    const start = Math.max(2, currentPage - 1);
                    const end = Math.min(total - 1, currentPage + 1);
                    if (start > 2) seq.push('...');
                    for (let i = start; i <= end; i++) seq.push(i);
                    if (end < total - 1) seq.push('...');
                    seq.push(total);
                }
                seq.forEach(p => (p === '...' ? addDots() : addNum(p)));
            };

            const render = () => {
                const total = totalPages();
                if (currentPage > total) currentPage = total;
                if (currentPage < 1) currentPage = 1;

                cards.forEach(c => { c.hidden = true; });
                const start = (currentPage - 1) * PAGE_SIZE;
                matching.slice(start, start + PAGE_SIZE).forEach(c => { c.hidden = false; });

                if (emptyMsg) emptyMsg.hidden = matching.length !== 0;

                if (pagination) {
                    // Skrij paginacijo, ko ni zadetkov.
                    pagination.hidden = matching.length === 0;
                    renderPageNumbers(total);
                    if (prevArrow) prevArrow.classList.toggle('disabled', currentPage <= 1);
                    if (nextArrow) nextArrow.classList.toggle('disabled', currentPage >= total);
                }
            };

            function goToPage(n) {
                const total = totalPages();
                currentPage = Math.min(Math.max(1, n), total);
                render();
                // Po menjavi strani se pomaknemo na vrh seznama.
                const anchor = filterSection || grid;
                const y = anchor.getBoundingClientRect().top + window.scrollY - 100;
                window.scrollTo({ top: y, behavior: 'smooth' });
            }

            if (prevArrow) {
                prevArrow.addEventListener('click', (e) => {
                    e.preventDefault();
                    if (currentPage > 1) goToPage(currentPage - 1);
                });
            }
            if (nextArrow) {
                nextArrow.addEventListener('click', (e) => {
                    e.preventDefault();
                    if (currentPage < totalPages()) goToPage(currentPage + 1);
                });
            }

            // --- Filter (če je na strani) ---
            const computeMatching = () => {
                matching = cards.filter(card => {
                    const cat = (card.getAttribute('data-category') || '').trim();
                    const sub = (card.getAttribute('data-subcategory') || '').trim();
                    let show = activeCat === 'all' || cat === activeCat;
                    if (show && activeCat !== 'all' && activeSub !== 'all') {
                        show = sub === activeSub;
                    }
                    return show;
                });
            };

            if (filterSection) {
                const pills = Array.from(filterSection.querySelectorAll('.filter-pill'));
                const subnavs = Array.from(filterSection.querySelectorAll('.filter-subnav'));

                const showSubnavFor = (cat) => {
                    subnavs.forEach(sn => {
                        const match = sn.getAttribute('data-parent') === cat;
                        sn.hidden = !match;
                        if (match) {
                            sn.querySelectorAll('.filter-chip').forEach(chip =>
                                chip.classList.toggle('active',
                                    (chip.getAttribute('data-subfilter') || 'all') === 'all'));
                        }
                    });
                };

                pills.forEach(pill => {
                    pill.addEventListener('click', () => {
                        activeCat = pill.getAttribute('data-filter') || 'all';
                        activeSub = 'all';
                        currentPage = 1;
                        pills.forEach(p => {
                            const on = p === pill;
                            p.classList.toggle('active', on);
                            p.setAttribute('aria-pressed', on ? 'true' : 'false');
                        });
                        showSubnavFor(activeCat);
                        computeMatching();
                        render();
                    });
                });

                subnavs.forEach(sn => {
                    sn.querySelectorAll('.filter-chip').forEach(chip => {
                        chip.addEventListener('click', () => {
                            activeSub = chip.getAttribute('data-subfilter') || 'all';
                            currentPage = 1;
                            sn.querySelectorAll('.filter-chip').forEach(c =>
                                c.classList.toggle('active', c === chip));
                            computeMatching();
                            render();
                        });
                    });
                });

                // Začetno stanje: "Vse" aktivno, podfiltri skriti.
                showSubnavFor(activeCat);
            }

            computeMatching();
            render();
        }
    } catch (error) {
        console.error('Error in Project Filter/Pagination setup:', error);
    }

    /**
     * ===================================================================
     * 7. NEWSLETTER (MailerLite)
     * ===================================================================
     */
    function setupNewsletter() {
        // --- MailerLite configuration -----------------------------------
        // Fill these in from your MailerLite embedded form
        // (Forms > Embedded forms > your form > Embed code). Both values
        // appear in the embed's subscribe URL:
        //   https://assets.mailerlite.com/jsonp/<ACCOUNT>/forms/<FORM>/subscribe
        const ML_ACCOUNT = '1253161';
        const ML_FORM = '194374752800868123';
        // ----------------------------------------------------------------

        const forms = document.querySelectorAll('form.subscribe-form, form.subscribe-form-bottom');
        if (!forms.length) return;

        let lang = (document.documentElement.getAttribute('lang') || 'en').toLowerCase();
        if (lang === 'sl') lang = 'si'; // <html lang="sl"> maps to the site's /si/ locale
        if (['en', 'si', 'mk'].indexOf(lang) === -1) lang = 'en';

        const T = {
            invalid:  { en: 'Please enter a valid email address.', si: 'Vnesite veljaven e-poštni naslov.', mk: 'Внесете важечка е-адреса.' },
            sending:  { en: 'Sending…', si: 'Pošiljanje…', mk: 'Се испраќа…' },
            success:  { en: 'Thank you! Please check your inbox to confirm your subscription.', si: 'Hvala! Za potrditev naročnine preverite svoj e-poštni predal.', mk: 'Ви благодариме! Проверете го вашето сандаче за да ја потврдите претплатата.' },
            error:    { en: 'Something went wrong. Please try again later.', si: 'Nekaj je šlo narobe. Poskusite znova pozneje.', mk: 'Нешто не успеа. Обидете се повторно подоцна.' },
            notready: { en: 'The newsletter is being set up. Please check back soon.', si: 'Novice se pravkar nastavljajo. Preverite kmalu znova.', mk: 'Билтенот се поставува. Проверете повторно наскоро.' }
        };
        const t = (k) => (T[k][lang] || T[k].en);

        forms.forEach((form) => {
            const input = form.querySelector('input[type="email"], input[type="text"], input');
            if (!input) return;
            input.setAttribute('type', 'email');
            input.setAttribute('name', 'fields[email]');
            input.setAttribute('required', '');
            input.setAttribute('autocomplete', 'email');

            const status = document.createElement('p');
            status.className = 'subscribe-status';
            status.setAttribute('role', 'status');
            status.setAttribute('aria-live', 'polite');
            status.hidden = true;
            form.parentNode.insertBefore(status, form.nextSibling);

            const show = (msg, type) => {
                status.textContent = msg;
                status.className = 'subscribe-status is-' + type;
                status.hidden = false;
            };

            form.addEventListener('submit', (e) => {
                e.preventDefault();
                const email = (input.value || '').trim();
                if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
                    show(t('invalid'), 'error');
                    input.focus();
                    return;
                }
                if (!ML_ACCOUNT || !ML_FORM) { show(t('notready'), 'error'); return; }

                const button = form.querySelector('button[type="submit"], button');
                if (button) button.disabled = true;
                show(t('sending'), 'info');

                const url = 'https://assets.mailerlite.com/jsonp/' + ML_ACCOUNT + '/forms/' + ML_FORM + '/subscribe';
                const body = new URLSearchParams();
                body.append('fields[email]', email);
                body.append('ml-submit', '1');
                body.append('anticsrf', 'true');

                fetch(url, { method: 'POST', body: body, mode: 'no-cors' })
                    .then(() => {
                        // Double opt-in: MailerLite emails a confirmation link, so we
                        // optimistically confirm here (the opt-in email is the real check).
                        form.reset();
                        show(t('success'), 'success');
                    })
                    .catch(() => show(t('error'), 'error'))
                    .finally(() => { if (button) button.disabled = false; });
            });
        });
    }

    /**
     * ===================================================================
     * LANGUAGE SUGGESTION BANNER (browser-language based, dismissible)
     * ===================================================================
     */
    function setupLanguageSuggestion() {
        try {
            var STORE = 'msos-lang-banner';
            if (localStorage.getItem(STORE) === 'dismissed') return;

            var validLangs = ['en', 'si', 'mk'];

            // Current page language (<html lang>; site uses /si/ for Slovene "sl").
            var docLang = (document.documentElement.getAttribute('lang') || 'en').toLowerCase();
            if (docLang === 'sl') docLang = 'si';

            // Detect the visitor's preferred language from the browser.
            var navLangs = navigator.languages || [navigator.language || ''];
            var detected = null;
            for (var i = 0; i < navLangs.length; i++) {
                var l = (navLangs[i] || '').toLowerCase();
                if (l.indexOf('mk') === 0) { detected = 'mk'; break; }
                if (l.indexOf('sl') === 0) { detected = 'si'; break; }
                if (l.indexOf('en') === 0) { detected = 'en'; break; }
            }
            if (!detected || detected === docLang) return; // unknown or already correct

            // Build the equivalent URL in the detected language (same logic as the switcher).
            var path = window.location.pathname;
            var parts = path.split('/').filter(Boolean);
            var pathWithoutLang = path;
            if (parts.length > 0 && validLangs.indexOf(parts[0]) !== -1) {
                pathWithoutLang = '/' + parts.slice(1).join('/');
                if (path.endsWith('/') && pathWithoutLang !== '/') pathWithoutLang += '/';
            }
            var targetUrl = ('/' + detected + pathWithoutLang).replace(/\/{2,}/g, '/');

            var MSG = {
                en: { text: 'This page is also available in English.', btn: 'View in English', flag: 'gb', aria: 'Language suggestion' },
                mk: { text: 'Оваа страница е достапна и на македонски.', btn: 'Прикажи на македонски', flag: 'mk', aria: 'Предлог за јазик' },
                si: { text: 'Ta stran je na voljo tudi v slovenščini.', btn: 'Prikaži v slovenščini', flag: 'si', aria: 'Predlog jezika' }
            };
            var m = MSG[detected];

            function showBanner() {
                if (document.querySelector('.lang-suggest')) return;
                var bar = document.createElement('div');
                bar.className = 'lang-suggest';
                bar.setAttribute('role', 'region');
                bar.setAttribute('aria-label', m.aria);
                bar.innerHTML =
                    '<span class="lang-flag lang-flag-' + m.flag + '" aria-hidden="true"></span>' +
                    '<p class="lang-suggest-text">' + m.text + '</p>' +
                    '<a class="lang-suggest-btn" href="' + targetUrl + '">' + m.btn + '</a>' +
                    '<button type="button" class="lang-suggest-close" aria-label="Dismiss">&times;</button>';
                document.body.appendChild(bar);
                requestAnimationFrame(function () { bar.classList.add('is-visible'); });

                function remember() { try { localStorage.setItem(STORE, 'dismissed'); } catch (e) {} }
                bar.querySelector('.lang-suggest-btn').addEventListener('click', remember);
                bar.querySelector('.lang-suggest-close').addEventListener('click', function () {
                    remember();
                    bar.classList.remove('is-visible');
                    setTimeout(function () { bar.remove(); }, 300);
                });
            }

            // Don't collide with the cookie-consent card (also a bottom-centred fixed card).
            // If the visitor hasn't answered consent yet, wait until they do, then show.
            var consentDecided;
            try {
                var c = localStorage.getItem('msos-consent');
                consentDecided = (c === 'granted' || c === 'denied');
            } catch (e) { consentDecided = true; }

            if (consentDecided && !document.querySelector('.msos-cc')) {
                showBanner();
            } else if ('MutationObserver' in window) {
                var obs = new MutationObserver(function () {
                    if (!document.querySelector('.msos-cc')) { obs.disconnect(); showBanner(); }
                });
                obs.observe(document.body, { childList: true });
            } else {
                // Fallback: poll until the consent card is gone.
                var tries = 0;
                var iv = setInterval(function () {
                    if (!document.querySelector('.msos-cc') || ++tries > 120) { clearInterval(iv); showBanner(); }
                }, 500);
            }
        } catch (error) {
            console.error('Error in language suggestion banner:', error);
        }
    }

    /**
     * ===================================================================
     * REUSABLE LIGHTBOX (for .event-gallery-grid.js-lightbox blocks)
     * ===================================================================
     */
    function setupLightbox() {
        var grids = document.querySelectorAll('.js-lightbox');
        if (!grids.length) return;

        var lb = document.createElement('div');
        lb.className = 'lightbox';
        lb.setAttribute('role', 'dialog');
        lb.setAttribute('aria-label', 'Photo viewer');
        lb.setAttribute('aria-hidden', 'true');
        lb.innerHTML =
            '<button type="button" class="lightbox-close" aria-label="Close">&times;</button>' +
            '<button type="button" class="lightbox-prev" aria-label="Previous">&#10094;</button>' +
            '<img class="lightbox-img" src="" alt="">' +
            '<button type="button" class="lightbox-next" aria-label="Next">&#10095;</button>' +
            '<a class="lightbox-project" href="#" hidden></a>' +
            '<div class="lightbox-caption"></div>';
        document.body.appendChild(lb);

        var img = lb.querySelector('.lightbox-img');
        var cap = lb.querySelector('.lightbox-caption');
        var proj = lb.querySelector('.lightbox-project');
        var group = [];
        var idx = 0;

        function render() {
            var it = group[idx];
            img.setAttribute('src', it.full);
            img.setAttribute('alt', it.caption || '');
            cap.textContent = (it.caption || '') + (group.length > 1 ? '  (' + (idx + 1) + '/' + group.length + ')' : '');
        }
        function open(grid, start) {
            group = Array.prototype.map.call(grid.querySelectorAll('.eg-thumb'), function (b) {
                return { full: b.getAttribute('data-full'), caption: b.getAttribute('data-caption') || '' };
            });
            idx = start;
            // Optional "go to project" link (present on gallery-page albums).
            var purl = grid.getAttribute('data-project-url');
            if (purl) {
                proj.setAttribute('href', purl);
                proj.textContent = grid.getAttribute('data-project-label') || 'View project';
                proj.hidden = false;
            } else {
                proj.hidden = true;
            }
            render();
            lb.classList.add('is-open');
            lb.setAttribute('aria-hidden', 'false');
            document.documentElement.style.overflow = 'hidden';
        }
        function close() {
            lb.classList.remove('is-open');
            lb.setAttribute('aria-hidden', 'true');
            document.documentElement.style.overflow = '';
            img.setAttribute('src', '');
        }
        function step(d) { idx = (idx + d + group.length) % group.length; render(); }

        grids.forEach(function (grid) {
            grid.querySelectorAll('.eg-thumb').forEach(function (b, i) {
                b.addEventListener('click', function () { open(grid, i); });
            });
        });
        // Triggers that open a target gallery (e.g. gallery-page album covers).
        document.querySelectorAll('[data-lightbox-target]').forEach(function (trig) {
            trig.addEventListener('click', function () {
                var g = document.getElementById(trig.getAttribute('data-lightbox-target'));
                if (g) open(g, 0);
            });
        });
        lb.querySelector('.lightbox-close').addEventListener('click', close);
        lb.querySelector('.lightbox-prev').addEventListener('click', function () { step(-1); });
        lb.querySelector('.lightbox-next').addEventListener('click', function () { step(1); });
        lb.addEventListener('click', function (e) { if (e.target === lb) close(); });
        document.addEventListener('keydown', function (e) {
            if (!lb.classList.contains('is-open')) return;
            if (e.key === 'Escape') close();
            else if (e.key === 'ArrowLeft') step(-1);
            else if (e.key === 'ArrowRight') step(1);
        });
        // Swipe on touch devices
        var sx = 0;
        lb.addEventListener('touchstart', function (e) { sx = e.changedTouches[0].clientX; }, { passive: true });
        lb.addEventListener('touchend', function (e) {
            var dx = e.changedTouches[0].clientX - sx;
            if (Math.abs(dx) > 40) step(dx < 0 ? 1 : -1);
        }, { passive: true });
    }

    /**
     * ===================================================================
     * HUB USE-CASE CAROUSEL (auto-scrolling + drag + position dots)
     * ===================================================================
     * Drives every .hub-carousel on the page (Hub "What you can do here"
     * and the "ways to be part of MSOS" slider). The track is built from
     * three identical .hub-group copies so the scroll loops seamlessly in
     * both directions; auto-scroll is JS-driven (not a CSS animation) so it
     * can co-exist with click-and-drag and touch swiping.
     */
    function setupHubCarousel() {
        const carousels = document.querySelectorAll('.hub-carousel');
        if (!carousels.length) return;
        const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
        const LOOP_MS = 55000; // time to travel one group width (matches old 55s marquee)

        carousels.forEach(function (carousel) {
            if (carousel.dataset.carouselInit) return;
            carousel.dataset.carouselInit = '1';

            const scroller = carousel.querySelector('.hub-uses');
            const track = carousel.querySelector('.hub-track');
            if (!scroller || !track) return;
            const firstGroup = track.querySelector('.hub-group');
            if (!firstGroup) return;

            // Need 3 identical groups so a full neighbour is always visible at each wrap point.
            while (track.querySelectorAll('.hub-group').length < 3) {
                const clone = firstGroup.cloneNode(true);
                clone.setAttribute('aria-hidden', 'true');
                track.appendChild(clone);
            }

            const cards = firstGroup.children;
            const cardCount = cards.length;
            if (!cardCount) return;

            // --- Position dots ---
            const dotsWrap = document.createElement('div');
            dotsWrap.className = 'hub-dots';
            dotsWrap.setAttribute('role', 'tablist');
            dotsWrap.setAttribute('aria-label', 'Carousel position');
            const dotEls = [];
            for (let i = 0; i < cardCount; i++) {
                const b = document.createElement('button');
                b.type = 'button';
                b.className = 'hub-dot';
                b.setAttribute('aria-label', 'Go to item ' + (i + 1));
                b.addEventListener('click', (function (idx) {
                    return function () { goTo(idx); };
                })(i));
                dotsWrap.appendChild(b);
                dotEls.push(b);
            }
            carousel.appendChild(dotsWrap);

            // --- Measurements (recomputed on resize / image load) ---
            let groupWidth = 0, step = 0;
            function measure() {
                groupWidth = firstGroup.offsetWidth;
                step = cardCount > 1 ? (cards[1].offsetLeft - cards[0].offsetLeft) : groupWidth;
                if (!step) step = groupWidth / cardCount;
            }

            // Keep scroll within the middle copy [groupWidth, 2*groupWidth) so it loops both ways.
            function wrap() {
                if (!groupWidth) return;
                if (scroller.scrollLeft >= 2 * groupWidth) scroller.scrollLeft -= groupWidth;
                else if (scroller.scrollLeft < groupWidth) scroller.scrollLeft += groupWidth;
            }

            function updateDots() {
                if (!step || !groupWidth) return;
                const within = ((scroller.scrollLeft % groupWidth) + groupWidth) % groupWidth;
                const active = Math.round(within / step) % cardCount;
                for (let i = 0; i < cardCount; i++) {
                    const dist = Math.min(Math.abs(i - active), cardCount - Math.abs(i - active));
                    dotEls[i].classList.toggle('is-active', i === active);
                    dotEls[i].classList.toggle('is-near', dist === 1);
                    dotEls[i].classList.toggle('is-far', dist >= 2);
                }
            }

            function reset() {
                measure();
                if (groupWidth) scroller.scrollLeft = groupWidth;
                updateDots();
            }
            reset();
            window.addEventListener('load', reset);
            window.addEventListener('resize', function () { measure(); wrap(); updateDots(); });

            // --- Jump to a specific card when a dot is clicked ---
            // Custom eased scroll (not native smooth) so it never fights the
            // rAF auto-scroll loop. Target always sits in the middle copy
            // [groupWidth, 2*groupWidth), so wrap() stays a no-op during it.
            let programmatic = 0; // ms remaining where auto-scroll yields
            let animId = 0;
            function goTo(idx) {
                if (!step) measure();
                const start = scroller.scrollLeft;
                const target = groupWidth + idx * step;
                const dur = 450, t0 = performance.now();
                const ease = function (t) { return 1 - Math.pow(1 - t, 3); };
                cancelAnimationFrame(animId);
                programmatic = dur + 80;
                (function anim(now) {
                    const t = Math.min(1, (now - t0) / dur);
                    scroller.scrollLeft = start + (target - start) * ease(t);
                    updateDots();
                    if (t < 1) animId = requestAnimationFrame(anim);
                })(t0);
            }

            // --- Auto-scroll loop ---
            let paused = false;
            let dragging = false;
            let last = null;
            function tick(ts) {
                if (last == null) last = ts;
                const dt = ts - last;
                last = ts;
                if (!reduceMotion && !paused && programmatic <= 0 && groupWidth) {
                    scroller.scrollLeft += (groupWidth / LOOP_MS) * dt;
                }
                if (programmatic > 0) programmatic -= dt;
                wrap();
                updateDots();
                requestAnimationFrame(tick);
            }
            requestAnimationFrame(tick);

            // Pause on hover (desktop).
            carousel.addEventListener('mouseenter', function () { paused = true; });
            carousel.addEventListener('mouseleave', function () { if (!dragging) paused = false; });

            // --- Click-and-drag (mouse) + pause during touch (native scroll handles the swipe) ---
            let lastX = 0;
            scroller.addEventListener('pointerdown', function (e) {
                paused = true;
                if (e.pointerType !== 'mouse') return; // touch/pen: let the browser scroll natively
                dragging = true;
                lastX = e.clientX;
                scroller.classList.add('is-dragging');
                try { scroller.setPointerCapture(e.pointerId); } catch (err) {}
            });
            scroller.addEventListener('pointermove', function (e) {
                if (!dragging) return;
                const dx = e.clientX - lastX;
                lastX = e.clientX;
                scroller.scrollLeft -= dx;
                wrap();
                updateDots();
                e.preventDefault();
            });
            function endDrag(e) {
                if (dragging) {
                    dragging = false;
                    scroller.classList.remove('is-dragging');
                    try { scroller.releasePointerCapture(e.pointerId); } catch (err) {}
                }
                // Resume auto-scroll unless the cursor is still hovering the carousel.
                if (!carousel.matches(':hover')) paused = false;
            }
            scroller.addEventListener('pointerup', endDrag);
            scroller.addEventListener('pointercancel', endDrag);

            // Prevent the browser's native image drag-ghost while dragging.
            track.addEventListener('dragstart', function (e) { e.preventDefault(); });
        });
    }

    /**
     * ===================================================================
     * ABOUT US TEAM HERO (auto-rotating crossfade slideshow)
     * ===================================================================
     */
    function setupAboutHero() {
        if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
        document.querySelectorAll('.about-hero').forEach(function (hero) {
            const slides = hero.querySelectorAll('.about-hero-slide');
            if (slides.length < 2) return;
            let i = 0;
            setInterval(function () {
                slides[i].classList.remove('is-active');
                i = (i + 1) % slides.length;
                slides[i].classList.add('is-active');
            }, 4500);
        });
    }

    /**
     * ===================================================================
     * APPRECIATION MARQUEE (Apple-style focal zoom)
     * The strip auto-scrolls via CSS; here we scale + brighten each card
     * by its distance from the horizontal centre, so whichever photo is
     * in the middle grows and lightens, then shrinks as it moves on.
     * ===================================================================
     */
    function setupApprMarquee() {
        if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
        const marquee = document.querySelector('.appr-marquee');
        if (!marquee) return;
        const cards = marquee.querySelectorAll('.appr-card');
        if (!cards.length) return;

        // scale: 1.0 at centre -> MIN_SCALE at the edges; brightness likewise
        const MIN_SCALE = 0.72;
        const MIN_BRIGHT = 0.5;

        function frame() {
            const vpCenter = window.innerWidth / 2;
            for (let n = 0; n < cards.length; n++) {
                const r = cards[n].getBoundingClientRect();
                const cardCenter = r.left + r.width / 2;
                // 0 at centre, ~1 near the edges of the viewport
                let d = Math.abs(cardCenter - vpCenter) / vpCenter;
                if (d > 1) d = 1;
                const e = d * d; // ease so only the very centre is full size
                const scale = 1 - (1 - MIN_SCALE) * e;
                const bright = 1 - (1 - MIN_BRIGHT) * e;
                cards[n].style.transform = 'scale(' + scale.toFixed(3) + ')';
                cards[n].style.filter = 'brightness(' + bright.toFixed(3) + ')';
            }
            rafId = requestAnimationFrame(frame);
        }
        let rafId = requestAnimationFrame(frame);
    }

    /**
     * ===================================================================
     * 8. ZAGON FUNKCIJ PO NALOŽITVI STRANI
     * ===================================================================
     */
    highlightActiveLink();
    setupLanguageSwitcher();
    setupLanguageSuggestion();
    setupNewsletter();
    setupHubCarousel();
    setupAboutHero();
    setupApprMarquee();
    setupLightbox();

});