function openLegalModal() { const modal = document.getElementById("legal-modal"); if (modal) { modal.classList.remove("hidden"); document.body.classList.add("overflow-hidden"); } } function closeCaseModal() { const modal = document.getElementById("case-modal"); if (modal) { modal.classList.add("hidden"); } document.body.classList.remove("overflow-hidden"); } document.addEventListener("DOMContentLoaded", () => { function loadScript(src) { return new Promise((resolve, reject) => { const script = document.createElement("script"); script.src = src; script.onload = resolve; script.onerror = reject; document.head.appendChild(script); }); } const currentScript = document.currentScript || document.querySelector("script[src$='script.js']"); const scriptBaseUrl = currentScript ? new URL("./", currentScript.src) : new URL("./", window.location.href); const assetsBaseUrl = new URL("assets/", scriptBaseUrl).toString(); loadScript(`${assetsBaseUrl}lucide.min.js`).then(() => { lucide.createIcons(); }); const wordElement = document.getElementById("hero-changing-word"); if (wordElement) { const words = [ "affidabile", "veloce", "puntuale", "efficiente", "innovativo", "flessibile", "proattivo", ]; let currentIndex = 0; const intervalTime = 1500; const flipDuration = 600; // deve combaciare con la durata dell'animazione CSS (0.6s) wordElement.textContent = words[currentIndex]; const flipWord = () => { wordElement.classList.add("hero-flip-animate"); setTimeout(() => { currentIndex = (currentIndex + 1) % words.length; wordElement.textContent = words[currentIndex]; }, flipDuration * 0.5); setTimeout(() => { wordElement.classList.remove("hero-flip-animate"); }, flipDuration); }; setInterval(flipWord, intervalTime); } // Logo carousel loadScript(`${assetsBaseUrl}swiper-bundle.min.js`).then(() => { const swiper = new Swiper(".swiper", { slidesPerView: 6, spaceBetween: 10, // Responsive breakpoints breakpoints: { 320: { slidesPerView: 3, spaceBetween: 20, }, 480: { slidesPerView: 3, spaceBetween: 30, }, 640: { slidesPerView: 6, spaceBetween: 40, }, }, loop: true, centeredSlides: true, autoplay: { delay: 1100, }, }); }); // Mobile menu const menuToggle = document.getElementById("menu-toggle"); const mobileMenu = document.getElementById("mobile-menu"); const menuIconOpen = document.getElementById("menu-icon-open"); const menuIconClose = document.getElementById("menu-icon-close"); if (menuToggle && mobileMenu && menuIconOpen && menuIconClose) { const toggleMenu = () => { const isHidden = mobileMenu.classList.contains("hidden"); // Toggle visibility mobileMenu.classList.toggle("hidden"); // Toggle pointer events for overlay if (isHidden) { mobileMenu.classList.remove("pointer-events-none"); } else { mobileMenu.classList.add("pointer-events-none"); } // Swap icons menuIconOpen.classList.toggle("hidden"); menuIconClose.classList.toggle("hidden"); // Lock/unlock body scroll if (isHidden) { document.body.classList.add("overflow-hidden"); } else { document.body.classList.remove("overflow-hidden"); } }; menuToggle.addEventListener("click", toggleMenu); // Close menu when a mobile nav link is clicked document.querySelectorAll("#mobile-menu a").forEach((link) => { link.addEventListener("click", () => { if (!mobileMenu.classList.contains("hidden")) { toggleMenu(); } }); }); } let codeatGalleryItems = []; let codeatGalleryIndex = 0; const updateCodeatOverlay = (item) => { const codeatOverlay = document.getElementById("codeat-gallery-overlay"); const codeatOverlayImage = document.getElementById("codeat-gallery-image"); const codeatOverlayCaption = document.getElementById( "codeat-gallery-caption", ); if (!codeatOverlay || !codeatOverlayImage) { return; } codeatOverlayImage.src = item.src; codeatOverlayImage.alt = item.caption || "Codeat Gallery"; if (codeatOverlayCaption) { codeatOverlayCaption.textContent = item.caption || ""; } }; const openCodeatGallery = (src, caption, index) => { const codeatOverlay = document.getElementById("codeat-gallery-overlay"); if (!codeatOverlay) { return; } codeatGalleryIndex = index; updateCodeatOverlay({ src, caption }); codeatOverlay.classList.remove("hidden"); document.body.classList.add("overflow-hidden"); }; const closeCodeatGallery = () => { const codeatOverlay = document.getElementById("codeat-gallery-overlay"); if (!codeatOverlay) { return; } codeatOverlay.classList.add("hidden"); document.body.classList.remove("overflow-hidden"); }; document.addEventListener("click", (event) => { const button = event.target.closest("[data-codeat-image]"); if (button) { const src = button.getAttribute("data-codeat-image"); const caption = button.getAttribute("data-codeat-caption"); codeatGalleryItems = Array.from( document.querySelectorAll("[data-codeat-image]"), ).map((item) => ({ src: item.getAttribute("data-codeat-image"), caption: item.getAttribute("data-codeat-caption"), })); const index = codeatGalleryItems.findIndex( (item) => item.src === src && item.caption === caption, ); if (src) { openCodeatGallery(src, caption, index >= 0 ? index : 0); } return; } if (event.target.closest("[data-codeat-prev]")) { if (codeatGalleryItems.length) { codeatGalleryIndex = (codeatGalleryIndex - 1 + codeatGalleryItems.length) % codeatGalleryItems.length; updateCodeatOverlay(codeatGalleryItems[codeatGalleryIndex]); } return; } if (event.target.closest("[data-codeat-next]")) { if (codeatGalleryItems.length) { codeatGalleryIndex = (codeatGalleryIndex + 1) % codeatGalleryItems.length; updateCodeatOverlay(codeatGalleryItems[codeatGalleryIndex]); } return; } if (event.target.closest("[data-codeat-close]")) { closeCodeatGallery(); return; } const codeatOverlay = document.getElementById("codeat-gallery-overlay"); if (codeatOverlay && event.target === codeatOverlay) { closeCodeatGallery(); } }); // HTMX modal helper document.addEventListener("click", function (event) { const target = event.target; // Close when clicking on elements with .modal-close if (target.closest(".modal-close")) { const caseModal = document.getElementById("case-modal"); if (caseModal) { caseModal.classList.add("hidden"); } const legalModal = document.getElementById("legal-modal"); if (legalModal) { legalModal.classList.add("hidden"); } document.body.classList.remove("overflow-hidden"); } // Close when clicking on backdrop outside modal content const backdrop = target.closest(".modal-backdrop"); if (backdrop && target === backdrop) { backdrop.classList.add("hidden"); document.body.classList.remove("overflow-hidden"); } }); });