Welcome to WordPress. This is your first post. Edit or delete it, then start writing!

Scroll to Top
(function () { "use strict"; var reduceMotion = window.matchMedia( "(prefers-reduced-motion: reduce)" ).matches; var canHover = window.matchMedia( "(hover: hover) and (pointer: fine)" ).matches; /* ========================================================= FOOTER YEAR ========================================================= */ var yearEl = document.getElementById("year") || document.querySelector("[data-barqon-year]"); if (yearEl) { yearEl.textContent = new Date().getFullYear(); } /* ========================================================= STICKY HEADER STATE ========================================================= */ var header = document.getElementById("site-header"); if (header) { var lastScrolled = null; function updateHeader() { var scrolled = window.scrollY > 12; if (scrolled !== lastScrolled) { header.classList.toggle("is-scrolled", scrolled); lastScrolled = scrolled; } } updateHeader(); window.addEventListener("scroll", updateHeader, { passive: true }); } /* ========================================================= MOBILE NAVIGATION Elementor's Nav Menu widget provides the desktop links. This script automatically creates the mobile toggle and mobile navigation if they do not already exist. ========================================================= */ function setupMobileNav() { if (!header) { return; } var nav = header.querySelector(".barqon-nav"); if (!nav) { return; } var links = Array.prototype.slice.call( nav.querySelectorAll("a") ); if (!links.length) { return; } var menuToggle = document.getElementById("menu-toggle"); var mobileNav = document.getElementById("mobile-nav"); /* ---------- Create mobile toggle ---------- */ if (!menuToggle) { menuToggle = document.createElement("button"); menuToggle.id = "menu-toggle"; menuToggle.className = "barqon-menu-toggle"; menuToggle.type = "button"; menuToggle.setAttribute( "aria-label", "Open menu" ); menuToggle.setAttribute( "aria-expanded", "false" ); menuToggle.innerHTML = "" + "" + ""; var actions = header.querySelector( ".barqon-header-actions" ); if (actions) { actions.appendChild(menuToggle); } else { var container = header.querySelector(".barqon-container"); if (container) { container.appendChild(menuToggle); } } } /* ---------- Create mobile navigation ---------- */ if (!mobileNav) { mobileNav = document.createElement("nav"); mobileNav.id = "mobile-nav"; mobileNav.className = "barqon-mobile-nav"; mobileNav.setAttribute( "aria-label", "Mobile navigation" ); links.forEach(function (sourceLink) { var link = document.createElement("a"); link.href = sourceLink.href || "#"; link.textContent = sourceLink.textContent.trim(); mobileNav.appendChild(link); }); document.body.appendChild(mobileNav); } /* ---------- Close menu ---------- */ function closeMenu() { mobileNav.classList.remove("is-open"); menuToggle.setAttribute( "aria-expanded", "false" ); menuToggle.setAttribute( "aria-label", "Open menu" ); document.body.style.overflow = ""; } /* ---------- Toggle menu ---------- */ menuToggle.addEventListener( "click", function () { var open = mobileNav.classList.toggle("is-open"); menuToggle.setAttribute( "aria-expanded", String(open) ); menuToggle.setAttribute( "aria-label", open ? "Close menu" : "Open menu" ); document.body.style.overflow = open ? "hidden" : ""; } ); /* ---------- Close after clicking a link ---------- */ mobileNav .querySelectorAll("a") .forEach(function (link) { link.addEventListener( "click", closeMenu ); }); /* ---------- Close when returning to desktop ---------- */ window.addEventListener( "resize", function () { if (window.innerWidth > 900) { closeMenu(); } }, { passive: true } ); } setupMobileNav(); /* ========================================================= SCROLL REVEAL ========================================================= */ var revealEls = document.querySelectorAll( ".barqon-reveal" ); if ( "IntersectionObserver" in window && revealEls.length && !reduceMotion ) { var revealObserver = new IntersectionObserver( function (entries) { entries.forEach( function (entry) { if (entry.isIntersecting) { entry.target.classList.add( "is-visible" ); revealObserver.unobserve( entry.target ); } } ); }, { threshold: 0.15, rootMargin: "0px 0px -60px 0px" } ); revealEls.forEach( function (element) { revealObserver.observe(element); } ); } else { revealEls.forEach( function (element) { element.classList.add( "is-visible" ); } ); } /* ========================================================= PORTFOLIO FILTER Elementor buttons do not need custom data attributes. Their visible text is converted into filter values. ========================================================= */ var filterButtons = document.querySelectorAll( ".barqon-filter" ); var projectCards = document.querySelectorAll( ".barqon-project-card" ); /* ---------- Generate filter values ---------- */ filterButtons.forEach( function (button) { var label = button.textContent .trim() .toLowerCase(); button.setAttribute( "data-filter", label === "all" ? "all" : label ); } ); /* ---------- Generate project categories ---------- */ projectCards.forEach( function (card) { var categoryEl = card.querySelector( ".barqon-project-meta > .elementor-widget-text-editor, " + ".barqon-project-meta span, " + ".barqon-project-meta p" ); var category = categoryEl ? categoryEl.textContent .trim() .toLowerCase() : ""; if (category) { card.setAttribute( "data-category", category ); } } ); /* ---------- Filter projects ---------- */ filterButtons.forEach( function (button) { button.addEventListener( "click", function (event) { var href = button.getAttribute("href"); if (href === "#work") { event.preventDefault(); } if ( button.classList.contains( "is-active" ) ) { return; } filterButtons.forEach( function (otherButton) { otherButton.classList.remove( "is-active" ); } ); button.classList.add( "is-active" ); var filter = button.getAttribute( "data-filter" ) || "all"; projectCards.forEach( function (card) { var match = filter === "all" || card.getAttribute( "data-category" ) === filter; if (match) { card.classList.remove( "is-hidden" ); requestAnimationFrame( function () { card.classList.remove( "is-filtering-out" ); } ); } else { card.classList.add( "is-filtering-out" ); window.setTimeout( function () { if ( card.classList.contains( "is-filtering-out" ) ) { card.classList.add( "is-hidden" ); } }, reduceMotion ? 0 : 220 ); } } ); } ); } ); /* ========================================================= PROJECT MODAL The modal is created automatically. No extra Elementor HTML widget is required. ========================================================= */ function createModal() { var backdrop = document.getElementById( "modal-backdrop" ); if (backdrop) { return backdrop; } backdrop = document.createElement("div"); backdrop.id = "modal-backdrop"; backdrop.className = "barqon-modal-backdrop"; backdrop.setAttribute( "role", "dialog" ); backdrop.setAttribute( "aria-modal", "true" ); backdrop.setAttribute( "aria-label", "Project details" ); backdrop.innerHTML = '
' + '" + '
' + "
" + '
' + '' + "
" + '' + '' + "
"; document.body.appendChild( backdrop ); return backdrop; } if (projectCards.length) { var modalBackdrop = createModal(); var modalClose = document.getElementById( "modal-close" ); var modalThumb = document.getElementById( "modal-thumb" ); var modalTag = document.getElementById( "modal-tag" ); var modalTitle = document.getElementById( "modal-title" ); var modalDesc = document.getElementById( "modal-desc" ); var lastFocused = null; /* ---------- Open modal ---------- */ function openModal(card) { lastFocused = document.activeElement; var titleEl = card.querySelector( ".barqon-project-meta h3" ); var tagEl = card.querySelector( ".barqon-project-meta .elementor-widget-text-editor, " + ".barqon-project-meta span, " + ".barqon-project-meta p" ); var art = card.querySelector( "[class*='barqon-art-']" ); var title = titleEl ? titleEl.textContent.trim() : ""; var tag = tagEl ? tagEl.textContent.trim() : ""; var artClass = art ? Array.prototype.find.call( art.classList, function (className) { return /^barqon-art-/.test( className ); } ) : "barqon-art-1"; modalTitle.textContent = title; modalTag.textContent = tag; modalDesc.textContent = title + ( tag ? " — " + tag + " project by BarqON Tech." : " — selected project by BarqON Tech." ); modalThumb.innerHTML = ""; var artEl = document.createElement( "span" ); artEl.className = artClass; modalThumb.appendChild( artEl ); modalBackdrop.classList.add( "is-open" ); document.body.style.overflow = "hidden"; if (modalClose) { modalClose.focus(); } } /* ---------- Close modal ---------- */ function closeModal() { modalBackdrop.classList.remove( "is-open" ); document.body.style.overflow = ""; if ( lastFocused && typeof lastFocused.focus === "function" ) { lastFocused.focus(); } } /* ---------- Project card click ---------- */ projectCards.forEach( function (card) { card.addEventListener( "click", function () { openModal(card); } ); } ); /* ---------- Close button ---------- */ if (modalClose) { modalClose.addEventListener( "click", closeModal ); } /* ---------- Click backdrop ---------- */ modalBackdrop.addEventListener( "click", function (event) { if ( event.target === modalBackdrop ) { closeModal(); } } ); /* ---------- Escape key ---------- */ document.addEventListener( "keydown", function (event) { if ( event.key === "Escape" && modalBackdrop.classList.contains( "is-open" ) ) { closeModal(); } } ); } /* ========================================================= FAQ Elementor's native Accordion controls its own FAQ interaction. This only supports the older hand-built FAQ structure if it exists. ========================================================= */ document .querySelectorAll( ".barqon-faq-item" ) .forEach( function (item) { var question = item.querySelector( ".barqon-faq-q" ); if (!question) { return; } question.addEventListener( "click", function () { var isOpen = item.classList.contains( "is-open" ); item.parentElement .querySelectorAll( ".barqon-faq-item" ) .forEach( function (other) { other.classList.remove( "is-open" ); var otherQuestion = other.querySelector( ".barqon-faq-q" ); if ( otherQuestion ) { otherQuestion.setAttribute( "aria-expanded", "false" ); } } ); if (!isOpen) { item.classList.add( "is-open" ); question.setAttribute( "aria-expanded", "true" ); } } ); } ); /* ========================================================= BACK TO TOP ========================================================= */ var toTop = document.getElementById( "to-top" ); if (!toTop) { toTop = document.createElement( "button" ); toTop.id = "to-top"; toTop.className = "barqon-to-top"; toTop.type = "button"; toTop.setAttribute( "aria-label", "Back to top" ); toTop.innerHTML = '' + '' + ""; document.body.appendChild( toTop ); } function toggleToTop() { toTop.classList.toggle( "is-visible", window.scrollY > 560 ); } toggleToTop(); window.addEventListener( "scroll", toggleToTop, { passive: true } ); toTop.addEventListener( "click", function () { window.scrollTo({ top: 0, behavior: reduceMotion ? "auto" : "smooth" }); } ); /* ========================================================= HERO CURSOR PARALLAX The original version could overwrite the CSS rotation of the hero cards. This version preserves the rotations. ========================================================= */ var heroArt = document.getElementById( "hero-art" ); if ( heroArt && canHover && !reduceMotion ) { var cards = heroArt.querySelectorAll( ".barqon-hero-card" ); var raf = null; var rotations = [ -4, 3, -1 ]; heroArt.addEventListener( "mousemove", function (event) { var rect = heroArt.getBoundingClientRect(); var px = (event.clientX - rect.left) / rect.width - 0.5; var py = (event.clientY - rect.top) / rect.height - 0.5; if (raf) { cancelAnimationFrame( raf ); } raf = requestAnimationFrame( function () { cards.forEach( function ( card, index ) { var depth = (index + 1) * 6; var rotation = rotations[index] || 0; card.style.transform = "rotate(" + rotation + "deg) translate3d(" + px * depth + "px," + py * depth + "px,0)"; } ); } ); } ); heroArt.addEventListener( "mouseleave", function () { cards.forEach( function ( card, index ) { card.style.transform = "rotate(" + ( rotations[index] || 0 ) + "deg)"; } ); } ); } /* ========================================================= ELEMENTOR PRO FORM COMPATIBILITY IMPORTANT: We DO NOT intercept the Elementor form. Elementor Pro handles: - AJAX submission - validation - email sending - success/error messages - spam protection The old custom fetch() handler has intentionally been removed because it could interfere with the native Elementor form. ========================================================= */ })();