1// conflict bug solution 2var $ = jQuery.noConflict(); 3 4$(function () { 5 /* ---------------------- GSAP + Lenis Setup ------------------------ */ 6 gsap.registerPlugin(ScrollTrigger); 7 8 const lenis = new Lenis(); 9 lenis.on("scroll", ScrollTrigger.update); 10 11 gsap.ticker.add((t) => lenis.raf(t * 1000)); 12 gsap.ticker.lagSmoothing(0); 13 /* ---------------------- GSAP + Lenis Setup End -------------------- */ 14 15 /* ---------------------- Text Reveal ------------------------ */ 16 $(".text-reveal").each(function () { 17 const $this = $(this); 18 const html = $this.html(); 19 20 if ($this.find("span").length) { 21 const spanHtml = $this.find("span")[0].outerHTML; 22 const parts = html.split(spanHtml); 23 const before = parts[0].trim(); 24 const after = parts[1]?.trim() || ""; 25 26 $this.html(` 27 ${spanHtml} 28 ${before || after ? `<span class="restText">${before || after}</span>` : ""} 29 `); 30 } else { 31 $this.html(`<span class="restText">${html}</span>`); 32 } 33 }); 34 /* ---------------------- Text Reveal End ------------------------ */ 35 36 /* -------------------- Show Header on Scroll Up -------------------- */ 37 var lastScrollTop = 0; 38 var $header = $("header"); 39 var $headerInner = $(".headerWrapper"); 40 var headerHeight = $headerInner.outerHeight(); 41 $header.css("height", `${headerHeight}px`); 42 43 $(window).on("scroll", function () { 44 if ($("body").hasClass("nav-expanded")) return; 45 46 var windowTop = $(window).scrollTop(); 47 48 if (windowTop >= headerHeight) { 49 $header.addClass("header-sticky"); 50 } else { 51 $header.removeClass("header-sticky header-show"); 52 } 53 54 if ($header.hasClass("header-sticky")) { 55 if (windowTop < lastScrollTop) { 56 $header.addClass("header-show"); 57 } else { 58 $header.removeClass("header-show"); 59 } 60 } 61 62 lastScrollTop = windowTop; 63 }); 64 /* -------------------- Show Header on Scroll Up End -------------------- */ 65 66 /* ------------------ Mobile Menu Toggle ------------------ */ 67 var isScrollingToAnchor = false; 68 69 function closeMobileNav() { 70 if ($(window).width() > 1024) return; 71 72 $("body").removeClass("nav-expanded").removeAttr("data-lenis-prevent"); 73 $( 74 ".menu-item-has-children .megaMenu, .menu-item-has-children .sub-menu", 75 ).slideUp(200); 76 } 77 78 if ($(window).width() > 1024) { 79 $(document).on( 80 "mouseover mouseleave", 81 ".menu-item-has-children", 82 function (e) { 83 $("body").toggleClass("menu-extended", e.type === "mouseover"); 84 $("header").toggleClass("menuShown", e.type === "mouseover"); 85 }, 86 ); 87 } else { 88 $(".toggleNav").on("click", function (e) { 89 if (isScrollingToAnchor) return; 90 e.preventDefault(); 91 92 $("body").toggleClass("nav-expanded"); 93 94 if ($("body").hasClass("nav-expanded")) { 95 $("body").attr("data-lenis-prevent", "true"); 96 } else { 97 // Close all submenus when nav is closed 98 $( 99 ".menu-item-has-children .megaMenu, .menu-item-has-children .sub-menu", 100 ).slideUp(200); 101 $("body").removeAttr("data-lenis-prevent"); 102 } 103 }); 104 105 $(".menu-item-has-children > a").on("click", function (e) { 106 e.preventDefault(); 107 108 const $parentLi = $(this).parent(); 109 const $siblings = $parentLi.siblings(".menu-item-has-children"); 110 111 // Close siblings' submenus 112 $siblings.find(".megaMenu, .sub-menu").slideUp(200); 113 114 // Toggle current submenu 115 $(this).next(".megaMenu").slideToggle(200); 116 $(this).next(".sub-menu").slideToggle(200); 117 }); 118 119 $(".main-menu").on("click", "a", function () { 120 const $parentLi = $(this).parent(".menu-item-has-children"); 121 122 if ( 123 $parentLi.length && 124 $parentLi.children(".megaMenu, .sub-menu").length && 125 $(this).is($parentLi.children("a").first()) 126 ) { 127 return; 128 } 129 130 closeMobileNav(); 131 }); 132 } 133 /* ------------------ Mobile Menu Toggle End ------------------ */ 134 135 /* ------------------ Smooth Scroll + Active Sync ------------------ */ 136 const headerOffset = 40; 137 const $menuItems = $(".main--menu > li"); 138 const $links = $(".main--menu > li > a[href*='#']"); 139 const $sections = $("section[id]"); 140 const $anchorLinks = $("a.achorLink[href^='#']"); 141 142 // Main menu anchor click 143 $links.on("click", function (e) { 144 if ( 145 window.location.pathname !== "/" && 146 window.location.pathname !== "/home" 147 ) 148 return; 149 150 e.preventDefault(); 151 152 const target = $(this).attr("href").split("#")[1]; 153 if (!target || $("#" + target).length === 0) return; 154 155 isScrollingToAnchor = true; 156 157 closeMobileNav(); 158 159 $menuItems.removeClass("active"); 160 $(this).parent().addClass("active"); 161 162 $("html, body") 163 .stop() 164 .animate( 165 { 166 scrollTop: $("#" + target).offset().top - headerOffset, 167 }, 168 600, 169 "swing", 170 function () { 171 isScrollingToAnchor = false;
172 }, 173 ); 174 }); 175 176 // Generic anchor link click 177 $anchorLinks.on("click", function (e) { 178 const href = $(this).attr("href"); 179 if (!href || href === "#") return; 180 181 const targetId = href.substring(1); 182 const $target = $("#" + targetId); 183 if (!$target.length) return; 184 185 e.preventDefault(); 186 isScrollingToAnchor = true; 187 188 closeMobileNav(); 189 190 $anchorLinks.removeClass("active"); 191 $(this).addClass("active"); 192 193 $("html, body") 194 .stop() 195 .animate( 196 { 197 scrollTop: $target.offset().top - headerOffset, 198 }, 199 600, 200 "swing", 201 function () { 202 isScrollingToAnchor = false; 203 }, 204 ); 205 }); 206 207 // Merged scroll handlers 208 $(window).on("scroll", function () { 209 if (isScrollingToAnchor) return; 210 211 const scrollTop = $(window).scrollTop(); 212 const scrollPos = scrollTop + headerOffset + 10; 213 214 // Anchor link active sync 215 let currentAnchorId = ""; 216 $anchorLinks.each(function () { 217 const href = $(this).attr("href"); 218 if (!href || href === "#") return; 219 220 const targetId = href.substring(1); 221 const $section = $("#" + targetId); 222 if (!$section.length) return; 223 224 if (scrollTop >= $section.offset().top - headerOffset - 200) { 225 currentAnchorId = targetId; 226 } 227 }); 228 229 $anchorLinks.removeClass("active"); 230 if (currentAnchorId) { 231 $(`a.achorLink[href="#${currentAnchorId}"]`).addClass("active"); 232 } 233 234 // Main menu active sync 235 let currentSection = ""; 236 $sections.each(function () { 237 if ($(this).offset().top <= scrollPos) { 238 currentSection = $(this).attr("id"); 239 } 240 }); 241 242 if (currentSection) { 243 $menuItems.removeClass("active"); 244 $links.each(function () { 245 if ( 246 $(this) 247 .attr("href") 248 .includes("#" + currentSection) 249 ) { 250 $(this).parent().addClass("active"); 251 } 252 }); 253 } 254 }); 255 /* ------------------ Smooth Scroll + Active Sync End ------------------ */ 256 257 /* ---------------------- Intersection Observer ------------------------ */ 258 const scrollers = document.querySelectorAll("[data-scroll], .wp-block-image"); 259 260 const observer = new IntersectionObserver(function (entries) { 261 entries.forEach((entry) => { 262 if (entry.isIntersecting) { 263 entry.target.classList.add("in-view"); 264 observer.unobserve(entry.target); 265 } 266 }); 267 }); 268
269 scrollers.forEach((scroller) => observer.observe(scroller)); 270 /* ---------------------- Intersection Observer End -------------------- */ 271 272 /* ---------------------- Accordion Block ------------------------ */ 273 const $accordionHeader = $(".accordion-header"); 274 const $accordionBody = $(".accordion-body"); 275 const activeClass = "accordion-active"; 276 277 $accordionHeader.on("click", function (e) { 278 e.stopPropagation(); 279 280 const $this = $(this); 281 282 if (!$this.hasClass(activeClass)) { 283 $accordionBody.slideUp(400); 284 $accordionHeader.removeClass(activeClass); 285 } 286 287 $this.toggleClass(activeClass); 288 $this.next().stop(true, true).slideToggle(400); 289 }); 290 /* ---------------------- Accordion Block End ------------------------ */ 291 292 /* ---------------------- Popup ------------------------ */ 293 function closeAllPopups() { 294 $(".teamPopup-wrap").removeClass("teamPopup-opened"); 295 $(".teamPopup").removeClass("teamPopup-active"); 296 $("body") 297 .removeClass("teamPopup-openeds formPopup-opened overflow-hidden") 298 .removeAttr("data-lenis-prevent"); 299 } 300 301 $(".teamPopupButton").on("click", function (event) { 302 event.preventDefault(); 303 event.stopPropagation(); 304 305 const targetIndex = $(this).data("index"); 306 const $teamBlock = $(this).closest(".teamBlock"); 307 const $popupContainer = $teamBlock.find(".teamPopup[data-popup-container]"); 308 309 $popupContainer.addClass("teamPopup-active"); 310 $popupContainer 311 .find(`.teamPopup-wrap[data-index="${targetIndex}"]`) 312 .addClass("teamPopup-opened"); 313 314 $("body") 315 .addClass("teamPopup-openeds overflow-hidden") 316 .attr("data-lenis-prevent", ""); 317 }); 318 319 $(".closePopup").on("click", function (event) { 320 event.preventDefault(); 321 closeAllPopups(); 322 }); 323 324 $(".teamPopup").on("click", function (e) { 325 if (!$(e.target).closest(".teamPopup-wrap").length) { 326 closeAllPopups(); 327 } 328 }); 329 330 $(".formPopupButton").on("click", function (event) { 331 event.preventDefault(); 332 event.stopPropagation(); 333 334 $("body") 335 .addClass("formPopup-opened overflow-hidden") 336 .attr("data-lenis-prevent", ""); 337 }); 338 /* ---------------------- Popup End ------------------------ */ 339 340 /* ---------------------- Copy Bio ------------------------ */ 341 $(document).on("click", ".copyBio", function (e) { 342 e.preventDefault(); 343 344 const $btn = $(this); 345 const text = $btn.data("copy"); 346 347 $btn.html("Copied!"); 348 349 navigator.clipboard.writeText(text).then(() => { 350 setTimeout(() => { 351 $btn.html(` 352 Copy bio 353 <svg xmlns="http://www.w3.org/2000/svg" width="16" height="13" viewBox="0 0 16 13" fill="none"> 354 <path d="M16 13H2V12H15V3H16V13ZM13 0V10H0V0H13ZM1 1V9H12V1H1Z" fill="#4E4E4F"/> 355 </svg> 356 `); 357 }, 1500); 358 }); 359 }); 360 /* ---------------------- Copy Bio End ------------------------ */ 361 362 /* ---------------------- Team Slider ------------------------ */ 363 let teamSlider; 364 365 function initTeamSlider() { 366 if (window.innerWidth >= 768 && !teamSlider) { 367 teamSlider = new Swiper(".teamSlider", { 368 slidesPerView: 3, 369 spaceBetween: 68, 370 navigation: { 371 nextEl: ".team-button-next", 372 prevEl: ".team-button-prev", 373 }, 374 breakpoints: { 375 768: { slidesPerView: 1, spaceBetween: 30 }, 376 840: { slidesPerView: 2, spaceBetween: 68 }, 377 1170: { slidesPerView: 3, spaceBetween: 68 }, 378 }, 379 }); 380 } else if (window.innerWidth < 768 && teamSlider) { 381 teamSlider.destroy(true, true); 382 teamSlider = null; 383 } 384 } 385 386 initTeamSlider(); 387 window.addEventListener("resize", initTeamSlider); 388 /* ---------------------- Team Slider End ------------------------ */ 389 390 /* ---------------------- Tab Slider ------------------------ */ 391 let tabSlider; 392 393 function initTabSlider() { 394 const $tabSliderEl = $(".tabSLider"); 395 if (!$tabSliderEl.length) return; 396 397 if (window.innerWidth < 1024 && !tabSlider) { 398 tabSlider = new Swiper(".tabSLider", { 399 autoHeight: true, 400 slidesPerView: 1, 401 spaceBetween: 20, 402 scrollbar: { el: ".tabSLider .swiper-scrollbar" }, 403 navigation: { 404 nextEl: ".tab-button-next", 405 prevEl: ".tab-button-prev", 406 }, 407 }); 408 } else if (window.innerWidth >= 1024 && tabSlider) { 409 tabSlider.destroy(true, true); 410 tabSlider = null; 411 } 412 } 413 414 initTabSlider(); 415 window.addEventListener("resize", initTabSlider); 416 /* ---------------------- Tab Slider End ------------------------ */ 417 418 /* ---------------------- Tab Block ------------------------ */ 419 const $tabs = $(".tab-item"); 420 const $panes = $(".tab-pane"); 421 const $images = $(".tab-image"); 422 const $line = $(".tabs .line"); 423 let $tabActive = $(".tab-item.active"); 424 425 function positionTabLine() { 426 if (!$tabActive.length || !$line.length) return; 427 if (!$tabActive.is(":visible")) return; 428 429 $line.css({ 430 left: $tabActive.position().left, 431 width: $tabActive.outerWidth(), 432 }); 433 } 434 435 if (window.requestIdleCallback) { 436 requestIdleCallback(positionTabLine); 437 } else { 438 setTimeout(positionTabLine, 0); 439 } 440 441 window.addEventListener("resize", positionTabLine); 442 443 $images.removeClass("visible").addClass("invisible"); 444 $images.first().removeClass("invisible").addClass("visible"); 445 446 $tabs.each(function (index) { 447 $(this).on("click", function () { 448 $(".tab-item.active").removeClass("active"); 449 $(".tab-pane.active").removeClass("active"); 450 $images.removeClass("visible").addClass("invisible"); 451 452 $line.css({ 453 left: $(this).position().left, 454 width: $(this).outerWidth(), 455 }); 456 457 $(this).addClass("active"); 458 $panes.eq(index).addClass("active"); 459 $images.eq(index).removeClass("invisible").addClass("visible"); 460 461 $tabActive = $(this); 462 }); 463 }); 464 /* ---------------------- Tab Block End ------------------------ */ 465 466 /* ---------------------- Portfolio Nested Scroll ------------------------ */ 467 document.querySelectorAll(".projects .custom-scrollbar").forEach((el) => { 468 el.addEventListener( 469 "wheel", 470 (e) => { 471 if (el.scrollHeight <= el.clientHeight) return; 472 473 const atTop = el.scrollTop <= 0; 474 const atBottom = 475 el.scrollTop + el.clientHeight >= el.scrollHeight - 1; 476 477 if ((e.deltaY < 0 && !atTop) || (e.deltaY > 0 && !atBottom)) { 478 e.stopPropagation(); 479 } 480 }, 481 { passive: true }, 482 ); 483 }); 484 /* ---------------------- Portfolio Nested Scroll End ------------------------ */ 485});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.