/* ===== IQON — Interactive Scripts ===== */ // ——— Scroll Reveal ——— const reveals = document.querySelectorAll(".reveal"); const revealObserver = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { entry.target.classList.add("on"); revealObserver.unobserve(entry.target); } }); }, { threshold: 0.12, rootMargin: "0px 0px -40px 0px" } ); reveals.forEach((item) => { revealObserver.observe(item); }); // ——— Active Nav Section Tracking ——— const navLinks = document.querySelectorAll(".main-nav a"); const sectionIds = ["approach", "services", "cases", "contacts"]; const sectionObserver = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { navLinks.forEach((link) => { link.classList.toggle( "active", link.getAttribute("href") === `#${entry.target.id}` ); }); } }); }, { threshold: 0.35, rootMargin: "-80px 0px 0px 0px" } ); sectionIds.forEach((id) => { const section = document.getElementById(id); if (section) { sectionObserver.observe(section); } }); // ——— Navbar Shrink on Scroll ——— const topbar = document.getElementById("topbar") || document.querySelector(".topbar"); let lastScrollY = 0; let ticking = false; function handleScroll() { if (!topbar) { ticking = false; return; } const scrolled = window.scrollY > 60; topbar.classList.toggle("scrolled", scrolled); ticking = false; } window.addEventListener("scroll", () => { if (!ticking) { requestAnimationFrame(handleScroll); ticking = true; } }); // ——— Smooth Scroll for Anchor Links ——— document.querySelectorAll('a[href^="#"]').forEach((anchor) => { anchor.addEventListener("click", function (e) { const target = document.querySelector(this.getAttribute("href")); if (target) { e.preventDefault(); const offset = (topbar ? topbar.offsetHeight : 0) + 12; const top = target.getBoundingClientRect().top + window.scrollY - offset; window.scrollTo({ top, behavior: "smooth" }); } }); }); // ——— Chart Bar Animation ——— const chartBox = document.querySelector(".chart-box"); if (chartBox) { const chartObserver = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { const bars = chartBox.querySelectorAll("span"); bars.forEach((bar, i) => { bar.style.transition = `height 0.8s ${0.1 + i * 0.08}s cubic-bezier(0.34, 1.56, 0.64, 1)`; bar.style.height = bar.style.height; // trigger reflow }); chartObserver.unobserve(entry.target); } }); }, { threshold: 0.5 } ); chartObserver.observe(chartBox); } // ——— Service Tile Hover Glow ——— const serviceTiles = document.querySelectorAll(".service-tile"); serviceTiles.forEach((tile) => { tile.addEventListener("mousemove", (e) => { const rect = tile.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; tile.style.setProperty("--mouse-x", `${x}px`); tile.style.setProperty("--mouse-y", `${y}px`); }); });