document.addEventListener("DOMContentLoaded", () => { function initCardClicks() { document.querySelectorAll(".w-condition-invisible").forEach(el => { el.style.display = "none"; }); function handleCardClick(card) { const offsite = card.querySelector(".offsite-link:not(.w-condition-invisible)"); const internal = card.querySelector(".inner-liner:not(.w-condition-invisible)"); if (offsite && offsite.href && offsite.href !== "#") { window.open(offsite.href, "_self"); } else if (internal && internal.href && internal.href !== "#") { window.open(internal.href, "_self"); } } const cards = document.querySelectorAll( ".card-blog-wrapper, .item-featured-child" ); cards.forEach(card => { card.addEventListener("click", (e) => { if (e.target.closest("a")) return; handleCardClick(card); }); }); document.querySelectorAll(".image-wrapper-featured, .image-item-featured").forEach(imgWrapper => { imgWrapper.addEventListener("click", (e) => { const card = imgWrapper.closest(".item-featured-child, .card-blog-wrapper"); if (card) handleCardClick(card); }); }); } initCardClicks(); document.addEventListener("render", initCardClicks); }); window.Webflow ||= []; window.Webflow.push(() => { // --- Card click logic --- function initCardClicks() { document.querySelectorAll(".w-condition-invisible").forEach(el => { el.style.display = "none"; }); function handleCardClick(card) { const offsite = card.querySelector(".offsite-link:not(.w-condition-invisible)"); const internal = card.querySelector(".inner-liner:not(.w-condition-invisible)"); if (offsite && offsite.href && offsite.href !== "#") { window.open(offsite.href, "_self"); } else if (internal && internal.href && internal.href !== "#") { window.open(internal.href, "_self"); } } const cards = document.querySelectorAll(".card-blog-wrapper, .item-featured-child"); cards.forEach(card => { card.addEventListener("click", (e) => { if (e.target.closest("a")) return; handleCardClick(card); }); }); document.querySelectorAll(".image-wrapper-featured, .image-item-featured").forEach(imgWrapper => { imgWrapper.addEventListener("click", (e) => { const card = imgWrapper.closest(".item-featured-child, .card-blog-wrapper"); if (card) handleCardClick(card); }); }); } initCardClicks(); document.addEventListener("render", initCardClicks); // --- HERO animation --- document .querySelectorAll("[data-headline-split-appear-hero]") .forEach((el) => { new SplitType(el, { types: "words", lineClass: "word" }); }); const firstElsHero = document.querySelectorAll("[data-first-el-appear-hero]"); const opacityElsHero = document.querySelectorAll("[data-opacity-el-appear-hero]"); const linesHero = document.querySelectorAll("[data-headline-split-appear-hero] .word"); const secondElsHero = document.querySelectorAll("[data-second-el-appear-hero]"); const secondaryElsHero = document.querySelectorAll("[data-appear-hero-secondary]"); if ( firstElsHero.length || linesHero.length || secondElsHero.length || secondaryElsHero.length ) { const tlHero = gsap.timeline(); if (firstElsHero.length) { tlHero.to(firstElsHero, { opacity: 1, duration: 1, ease: "power2.out" }); } if (opacityElsHero.length) { tlHero.to(opacityElsHero, { opacity: 1, duration: 0, ease: "power2.out" }, 0); } if (linesHero.length) { tlHero.to( linesHero, { y: 0, opacity: 1, duration: 1, ease: "power2.out", stagger: 0.2, }, 0.1 ); } if (secondElsHero.length) { tlHero.to( secondElsHero, { y: 0, opacity: 1, duration: 1, ease: "power2.out", stagger: 0.05, }, 0 ); } if (secondaryElsHero.length) { tlHero.to( secondaryElsHero, { y: 0, opacity: 1, duration: 1, ease: "power2.out", stagger: 0.05, }, 0 ); } } // --- Scroll animations --- gsap.registerPlugin(ScrollTrigger); document.querySelectorAll("[data-animation-wrap]").forEach((wrap) => { const headlineEls = wrap.querySelectorAll("[data-headline-split-appear]"); if (headlineEls.length) { headlineEls.forEach((el) => { new SplitType(el, { types: "words", wordClass: "word" }); }); ScrollTrigger.refresh(); } const firstEls = wrap.querySelectorAll("[data-first-el-appear]"); const words = wrap.querySelectorAll("[data-headline-split-appear] .word"); const secondEls = wrap.querySelectorAll("[data-second-el-appear]"); if (!firstEls.length && !words.length && !secondEls.length) return; const tl = gsap.timeline({ scrollTrigger: { trigger: wrap, start: "top 80%", toggleActions: "play none none none", }, }); if (firstEls.length) { tl.to(firstEls, { opacity: 1, y: 0, duration: 1, ease: "power2.out", onStart() { firstEls.forEach((el) => el.classList.add("is-animated")); }, }); } if (words.length) { tl.to( words, { y: 0, opacity: 1, duration: 1, ease: "power2.out", stagger: 0.1, onStart() { words.forEach((w) => w.classList.add("is-animated")); }, }, 0.1 ); } if (secondEls.length) { tl.to( secondEls, { y: 0, opacity: 1, duration: 1, ease: "power2.out", stagger: 0.1, onStart() { secondEls.forEach((el) => el.classList.add("is-animated")); }, }, 0 ); } const numEls = wrap.querySelectorAll("[anime-numbers]"); if (numEls.length) { numEls.forEach((el) => { const rawText = el.textContent.trim(); const match = rawText.match(/-?\d+(?:\.\d+)?/); if (!match) return; const endStr = match[0]; const endValue = parseFloat(endStr); const decimals = (endStr.split(".")[1] || "").length; const prefix = rawText.slice(0, match.index); const suffix = rawText.slice(match.index + endStr.length); let startRatio = parseFloat(el.getAttribute("anime-numbers")) || 0.7; if (!isFinite(startRatio)) startRatio = 0.7; startRatio = Math.max(0, Math.min(1, startRatio)); const startValue = endValue * startRatio; el.textContent = decimals ? `${prefix}${startValue.toFixed(decimals)}${suffix}` : `${prefix}${Math.floor(startValue)}${suffix}`; const obj = { value: startValue }; gsap.set(el, { scale: 1, transformOrigin: "50% 50%" }); const pulseEnabled = (el.getAttribute("numbers-pulse") || "").toLowerCase().trim() === "true"; tl.to( obj, { value: endValue, duration: 1.5, ease: "power1.in", onUpdate() { const current = decimals ? obj.value.toFixed(decimals) : Math.floor(obj.value); el.textContent = `${prefix}${current}${suffix}`; }, onComplete() { if (!pulseEnabled) return; gsap.to(el, { scale: 1.2, duration: 0.25, ease: "power2.out", yoyo: true, repeat: 1, delay: 0.05, }); }, }, 0 ); }); } }); gsap.utils.toArray("[data-samefirts-el-appear]").forEach((el) => { gsap.to(el, { scrollTrigger: { trigger: el, start: "top 80%", toggleActions: "play none none none", }, opacity: 1, duration: 1, ease: "power2.out", onStart() { el.classList.add("is-animated"); }, }); }); // --- Reveal text on scroll --- const splitTypes = document.querySelectorAll("[reveal-type]"); if (splitTypes.length > 0) { splitTypes.forEach((char) => { const text = new SplitType(char, { types: ["chars", "words"] }); gsap.fromTo( text.chars, { opacity: 0.4 }, { scrollTrigger: { trigger: char, start: "top 90%", end: "bottom 40%", scrub: true, markers: false, }, opacity: 1, stagger: 0.05, ease: "power2.out", } ); }); } // --- Grow CTA animation --- (function () { if (typeof gsap === "undefined" || typeof ScrollTrigger === "undefined") return; gsap.registerPlugin(ScrollTrigger); const wrappers = document.querySelectorAll(".anime-grow-wrapper"); if (!wrappers.length) return; const prefersReduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches; if (prefersReduced) { wrappers.forEach((wrap) => { const child = wrap.querySelector(".is-anime-grow"); gsap.set(wrap, { padding: "0" }); if (child) gsap.set(child, { maxWidth: "100%", borderRadius: "0rem" }); }); return; } const mm = gsap.matchMedia(); wrappers.forEach((wrap) => { const child = wrap.querySelector(".is-anime-grow"); mm.add( { isMobile: "(max-width: 766px)", isDesktop: "(min-width: 767px)", }, (ctx) => { const { isMobile } = ctx.conditions; if (isMobile) { gsap.set(wrap, { padding: 0 }); if (child) gsap.set(child, { maxWidth: "100%", borderRadius: "0rem" }); return; } const startPad = "2.5rem"; gsap.set(wrap, { paddingLeft: startPad, paddingRight: startPad, paddingTop: 0, paddingBottom: 0, }); if (child) gsap.set(child, { maxWidth: "82rem", borderRadius: "1.25rem" }); const tl = gsap.timeline({ defaults: { ease: "power2.out" }, scrollTrigger: { trigger: wrap, start: "top 75%", end: "top 30%", scrub: true, invalidateOnRefresh: true, }, }); tl.to(wrap, { paddingLeft: 0, paddingRight: 0, paddingTop: "0rem", paddingBottom: "0rem", duration: 1.1, }); if (child) { tl.to(child, { maxWidth: "100%", duration: 1.1 }, 0); tl.to(child, { borderRadius: "0rem", duration: 0.1 }, 1); } } ); }); window.addEventListener("load", () => { setTimeout(() => ScrollTrigger.refresh(), 50); }); window.addEventListener("orientationchange", () => { setTimeout(() => ScrollTrigger.refresh(), 100); }); })(); });