document.addEventListener("DOMContentLoaded", () => { // Fix double H1: demote hidden Magento page-title h1 to
const magH1 = document.querySelector(".page-title-wrapper h1"); if (magH1) { const p = document.createElement("p"); p.className = magH1.className; p.innerHTML = magH1.innerHTML; magH1.parentNode.replaceChild(p, magH1); } // Hamburger menu toggle const hamburgerBtn = document.querySelector(".hamburger-btn"); const navMenu = document.querySelector(".nav-links"); const navBackdrop = document.getElementById("nav-backdrop"); function closeNavMenu() { navMenu.classList.remove("open"); hamburgerBtn.classList.remove("open"); hamburgerBtn.setAttribute("aria-expanded", "false"); if (navBackdrop) navBackdrop.classList.remove("open"); } if (hamburgerBtn && navMenu) { hamburgerBtn.addEventListener("click", () => { const isOpen = navMenu.classList.toggle("open"); hamburgerBtn.classList.toggle("open", isOpen); hamburgerBtn.setAttribute("aria-expanded", String(isOpen)); if (navBackdrop) navBackdrop.classList.toggle("open", isOpen); }); navMenu.querySelectorAll("a").forEach((a) => { a.addEventListener("click", closeNavMenu); }); if (navBackdrop) navBackdrop.addEventListener("click", closeNavMenu); } const sections = document.querySelectorAll(".section"); const navLinks = document.querySelectorAll(".nav-links a"); const scrollIndicator = document.querySelector(".scroll-indicator"); const heroInput = document.getElementById("hero-input"); const typewriterEl = document.getElementById("typewriter-title"); // Multi-stage Typewriter Sequence const typeStrings = [ "Network hardware sourcing made simple", "for every site", "for every need", "for every environment", ]; async function runTypewriter() { if (!typewriterEl) return; async function typeInto(element, text, speed) { element.classList.add("typing-cursor"); for (const char of text) { element.textContent += char; await new Promise((r) => setTimeout(r, speed)); } element.classList.remove("typing-cursor"); } async function fadeStep() { typewriterEl.style.opacity = "0"; await new Promise((r) => setTimeout(r, 600)); typewriterEl.innerHTML = ""; typewriterEl.style.opacity = "1"; await new Promise((r) => setTimeout(r, 200)); } // Delay for server animation await new Promise((r) => setTimeout(r, 3500)); // -- Text Phases -- for (let i = 0; i < typeStrings.length; i++) { const span = document.createElement("span"); typewriterEl.appendChild(span); await typeInto(span, typeStrings[i], 45); await new Promise((r) => setTimeout(r, 1200)); await fadeStep(); } // -- FINAL PHASE: BRAND LOGO -- const brandBox = document.createElement("div"); brandBox.style.display = "flex"; brandBox.style.flexDirection = "column"; brandBox.style.alignItems = "center"; brandBox.style.gap = "15px"; brandBox.style.opacity = "0"; // Start invisible brandBox.style.transition = "opacity 0.6s ease-out"; const brandImg = document.createElement("img"); brandImg.src = window.PROLOGY_CONFIG.LOGO_SRC; brandImg.style.height = "80px"; brandImg.style.width = "auto"; brandImg.style.filter = "none"; // Logo full màu const finalTag = document.createElement("div"); finalTag.style.fontSize = "1.6rem"; finalTag.style.fontWeight = "600"; finalTag.style.color = "var(--primary)"; finalTag.style.letterSpacing = "0.15em"; finalTag.style.textTransform = "uppercase"; brandBox.appendChild(brandImg); brandBox.appendChild(finalTag); typewriterEl.appendChild(brandBox); // 1. Kick off Logo Fade-in setTimeout(() => { brandBox.style.opacity = "1"; }, 200); await new Promise((r) => setTimeout(r, 1000)); // 2. Type the final tagline await typeInto(finalTag, "Your Network Hardware Partner", 50); // 3. Wait a moment so user can read it, then fade out the tagline/logo await new Promise((r) => setTimeout(r, 1500)); brandBox.style.opacity = "0"; // 4. Wait for fade out, hide it, and show the eBay Banner await new Promise((r) => setTimeout(r, 600)); brandBox.style.display = "none"; const ebayBanner = document.getElementById("hero-ebay-integrated"); if (ebayBanner) { // Typewriter xong hẳn — giờ mới hide wrapper và show banner const wrapper = document.querySelector(".hero-animation-wrapper"); if (wrapper) wrapper.style.display = "none"; ebayBanner.classList.add("visible"); } } runTypewriter(); // Đã hủy bỏ bộ hẹn giờ auto-focus ở đây. // Việc auto-focus sau 19s khiến trình duyệt tự động cuộn giật ngược lên đầu trang nếu user đang đọc ở dưới. // Switch between Source (Buy) and Sell Modes window.switchTab = function (mode) { const buySection = document.getElementById("buy-section"); const sellSection = document.getElementById("sell-section"); const tabs = document.querySelectorAll(".search-tab"); // Toggle tabs tabs.forEach((tab) => { tab.classList.toggle( "active", tab.textContent.toLowerCase().includes(mode), ); }); // Toggle sections with a small fade if (mode === "buy") { sellSection.style.display = "none"; buySection.style.display = "block"; document.getElementById("hero-input").focus(); } else { buySection.style.display = "none"; sellSection.style.display = "block"; document.getElementById("sell-email-init").focus(); } }; let isScrolling = false; let currentSectionIndex = 0; function updateUI(index) { currentSectionIndex = index; const currentSection = sections[index]; const id = currentSection.getAttribute("id"); // Update Top Nav based on href matches, not raw index parity navLinks.forEach((link) => { link.classList.remove("active", "past"); const targetId = link.getAttribute("href"); if (targetId === `#${id}`) { link.classList.add("active"); } else if (id === "warehouse" && targetId === "#quality") { link.classList.add("active"); } }); // Toggle light color for scroll indicator on dark sections (1, 3, 5) if (scrollIndicator) { if (index % 2 !== 0) { scrollIndicator.classList.add("light"); } else { scrollIndicator.classList.remove("light"); } } // Hide Scroll Indicator on last page if (scrollIndicator) { if (index === sections.length - 1) { scrollIndicator.style.opacity = "0"; } else { scrollIndicator.style.opacity = "1"; } } } // Logic cuộn tự động đã được chuyển qua CSS scroll-snap để tối ưu hiệu năng và tương thích màn hình function scrollToSection(index) { isScrolling = true; updateUI(index); sections[index].scrollIntoView({ behavior: "smooth" }); setTimeout(() => { isScrolling = false; }, 800); // Wait for animation to finish } // ============ SECTION OBSERVER ============ const observerOptions = { threshold: 0.5, }; const observer = new IntersectionObserver((entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { const id = entry.target.getAttribute("id"); const index = Array.from(sections).indexOf(entry.target); // Update internal index for wheel/space navigation if (!isScrolling) currentSectionIndex = index; // Update Top Nav navLinks.forEach((link) => { link.classList.remove("active"); const targetId = link.getAttribute("href"); if (targetId === `#${id}`) { link.classList.add("active"); } // Special case: Keep 'Why Us' highlighted when inside Global Logistics if (id === "warehouse" && targetId === "#quality") { link.classList.add("active"); } }); entry.target.classList.add("visible"); } }); }, observerOptions); sections.forEach((section) => observer.observe(section)); // ============ SMOOTH SCROLL (Navbar) ============ document.querySelectorAll('a[href^="#"]').forEach((anchor) => { anchor.addEventListener("click", function (e) { e.preventDefault(); const targetId = this.getAttribute("href"); const target = document.querySelector(targetId); if (target) { const index = Array.from(sections).indexOf(target); if (index !== -1) scrollToSection(index); } }); }); // ============ ANIMATE PORT SEQUENCE ============ const switchPanel = document.getElementById("animated-switch-panel"); if (switchPanel) { const totalColumns = 24; const totalRows = 2; for (let r = 0; r < totalRows; r++) { const rowDiv = document.createElement("div"); rowDiv.className = "port-row"; for (let c = 0; c < totalColumns; c++) { const portDiv = document.createElement("div"); // Randomly decide if this port gets a cable ( ~40% chance ) // EXCLUDE Port 22 of Bottom Row (r=1, c=21) for the master cable if (Math.random() < 0.4 && !(r === 1 && c === 21)) { portDiv.className = "port-front active-port"; // Random drop-in delay between 0 and 2.5 seconds const plugDelay = Math.random() * 2.5; portDiv.style.setProperty("--delay", `${plugDelay}s`); portDiv.innerHTML = `