//Andriy code /*Disable all dev mods for complex components if the user forgot to disable them in the admin area*/ document.addEventListener("DOMContentLoaded", () => { document.querySelectorAll(".dev-edite-mode").forEach((el) => { if (el.classList.contains("is-on")) { el.classList.remove("is-on"); } }); }); /* ========================================================= Bottom Bar (FULL) 1) Duplicate panel height synced to Webflow dropdown state 2) Label text synced to current (w--current) link - After first valid current is detected, NEVER fallback to "Menu" (keeps last label during "no-current" gaps while scrolling) 3) Mobile: after anchor navigation, close dropdown by clicking bar_dropdown-toggle ========================================================= */ window.Webflow ||= []; window.Webflow.push(() => { /* ========================== CONFIG ========================== */ const MOBILE_QUERY = "(max-width: 500px)"; const MOBILE_HEIGHT_VH = 60; const ANIMATION_DURATION = 280; const DEFAULT_TEXT = "Menu"; const CLOSE_AFTER_NAV_DELAY_MS = 0; // try 20-50 if you see flicker /* ========================== ELEMENTS ========================== */ const dropdown = document.querySelector(".menu-bottom-bar"); const dropdownToggle = document.querySelector(".bar_dropdown-toggle") || dropdown?.querySelector(".w-dropdown-toggle"); const duplicate = document.querySelector(".list-bottom-bar-dublicate"); const fixedBar = document.querySelector(".fixed-bottom-bar"); const label = document.querySelector(".text-bottom-bar"); const mq = window.matchMedia(MOBILE_QUERY); if (!dropdownToggle || !duplicate || !fixedBar || !label) { console.warn("Bottom bar elements not found"); return; } /* ========================== STATE (label) ========================== */ let hasEverHadCurrent = false; let lastValidLabel = DEFAULT_TEXT; /* ========================== HELPERS ========================== */ function isOpen() { const aria = dropdownToggle.getAttribute("aria-expanded"); if (aria === "true") return true; if (aria === "false") return false; return dropdownToggle.classList.contains("w--open"); } function getOpenHeight() { if (mq.matches) return window.innerHeight * (MOBILE_HEIGHT_VH / 100); return duplicate.scrollHeight; } function openDuplicate() { const height = getOpenHeight(); duplicate.style.transition = `height ${ANIMATION_DURATION}ms ease`; duplicate.style.height = `${height}px`; fixedBar.classList.add("is-on"); } function closeDuplicate() { duplicate.style.transition = `height ${ANIMATION_DURATION}ms ease`; duplicate.style.height = "0px"; fixedBar.classList.remove("is-on"); } function setLabel(text) { label.textContent = text; } function syncFromCurrent() { const current = duplicate.querySelector(".dropdown-link.w--current"); if (current) { const next = current.textContent.trim(); if (next) { hasEverHadCurrent = true; lastValidLabel = next; setLabel(next); return; } } // No current right now: // - Before user has ever reached any section: show DEFAULT ("Menu") // - After first real current: keep last label (NO fallback to Menu) if (!hasEverHadCurrent) { lastValidLabel = DEFAULT_TEXT; setLabel(DEFAULT_TEXT); } else { setLabel(lastValidLabel); } } /* ========================== INITIAL SYNC ========================== */ setLabel(DEFAULT_TEXT); requestAnimationFrame(() => { syncFromCurrent(); if (isOpen()) openDuplicate(); else closeDuplicate(); }); /* ========================== OBSERVE WEBFLOW STATE (aria-expanded) ========================== */ const ariaObserver = new MutationObserver(() => { if (isOpen()) openDuplicate(); else closeDuplicate(); }); ariaObserver.observe(dropdownToggle, { attributes: true, attributeFilter: ["aria-expanded", "class"], }); /* ========================== OBSERVE CURRENT LINK CHANGES (class) ========================== */ const classObserver = new MutationObserver((mutations) => { for (const m of mutations) { if ( m.type === "attributes" && m.attributeName === "class" && m.target instanceof Element && m.target.classList.contains("dropdown-link") ) { syncFromCurrent(); break; } } }); classObserver.observe(duplicate, { subtree: true, attributes: true, attributeFilter: ["class"], }); /* ========================== EXTRA SAFETY: periodic sync while scrolling (covers cases when class changes don't fire reliably) ========================== */ let rafId = null; function scheduleLabelSync() { if (rafId) return; rafId = requestAnimationFrame(() => { rafId = null; syncFromCurrent(); }); } window.addEventListener("scroll", scheduleLabelSync, { passive: true }); function closeAfterNav() { if (!mq.matches) return; if (!isOpen()) return; setTimeout(() => { if (isOpen()) dropdownToggle.click(); }, CLOSE_AFTER_NAV_DELAY_MS); } duplicate.addEventListener("click", (e) => { const link = e.target.closest(".dropdown-link"); if (!link) return; closeAfterNav(); // Also update label instantly on click (better UX) const txt = link.textContent?.trim(); if (txt) { hasEverHadCurrent = true; lastValidLabel = txt; setLabel(txt); } }); window.addEventListener("hashchange", closeAfterNav); mq.addEventListener("change", () => { if (isOpen()) openDuplicate(); }); }); /* ========================== CLICK DD CATEGORIES START ========================== */ /* ========================== CUSTOM DD CATEGORIES ========================== */ document.addEventListener("DOMContentLoaded", () => { const wrapper = document.querySelector(".custom-dd-categories-wrapper"); const list = document.querySelector(".block-list-categories"); const icon = document.querySelector(".icon-custom-dd"); const title = document.querySelector( ".box-title-dd-categories .label-20-semibold" ); const firstSwitch = document.querySelector( ".flex-filtres-left .switch_category" ); const switches = document.querySelectorAll(".switch_category"); if (!wrapper || !list) return; /* ========================== DEFAULT ACTIVE (FIRST) ========================== */ if (firstSwitch) { firstSwitch.classList.add("is-active"); const text = firstSwitch.querySelector(".w-form-label")?.textContent; if (text && title) title.textContent = text; } /* ========================== OPEN / CLOSE DD ========================== */ wrapper.addEventListener("click", (e) => { e.stopPropagation(); list.classList.toggle("is-on"); icon?.classList.toggle("is-rotate"); }); document.body.addEventListener("click", () => { list.classList.remove("is-on"); icon?.classList.remove("is-rotate"); }); list.addEventListener("click", (e) => { e.stopPropagation(); }); /* ========================== SWITCH CATEGORY ========================== */ switches.forEach((switchItem) => { switchItem.addEventListener("click", () => { const label = switchItem.querySelector(".w-form-label"); if (!label) return; const text = label.textContent; if (title) title.textContent = text; list.classList.remove("is-on"); icon?.classList.remove("is-rotate"); }); }); }); /* ========================== CLICK DD CATEGORIES END ========================== */ /* ========================== FAQ - NEW - START ========================== */ $(document).ready(function () { const ACTIVE_CLASS = "is-open"; const BG_CLASS = "is-bg"; const $accordions = $(".faq_accordion-new"); if (!$accordions.length) return; // Accordion that contains [data-open-faq] const $defaultAccordion = $accordions.has("[data-open-faq]").first(); function openAccordion($accordion) { const $answer = $accordion.find(".faq_answer-new"); $accordion.addClass(ACTIVE_CLASS).addClass(BG_CLASS); $answer.css("max-height", $answer.prop("scrollHeight") + "px"); } function closeAccordion($accordion) { const $answer = $accordion.find(".faq_answer-new"); $accordion.removeClass(ACTIVE_CLASS).removeClass(BG_CLASS); $answer.css("max-height", 0); } function refreshOpenHeights() { $accordions.each(function () { const $accordion = $(this); if ($accordion.hasClass(ACTIVE_CLASS)) { const $answer = $accordion.find(".faq_answer-new"); $answer.css("max-height", $answer.prop("scrollHeight") + "px"); } }); } function closeOthers($current) { $accordions.each(function () { const $accordion = $(this); // ❗ skip default accordion if (!$accordion.is($current) && !$accordion.is($defaultAccordion)) { closeAccordion($accordion); } }); } // Initial state $accordions.each(function () { const $accordion = $(this); const $answer = $accordion.find(".faq_answer-new"); $accordion.removeClass(ACTIVE_CLASS).removeClass(BG_CLASS); $answer.css("max-height", 0); }); // Open default accordion on start if ($defaultAccordion.length) { openAccordion($defaultAccordion); } $accordions.each(function () { const $accordion = $(this); const $question = $accordion.find(".faq_question-new"); $question.on("click", function () { const isDefault = $defaultAccordion.length && $accordion.is($defaultAccordion); const isOpen = $accordion.hasClass(ACTIVE_CLASS); // ❗ DEFAULT ACCORDION LOGIC if (isDefault) { if (isOpen) { closeAccordion($accordion); } else { openAccordion($accordion); } return; } // NORMAL ACCORDION if (isOpen) { closeAccordion($accordion); } else { closeOthers($accordion); openAccordion($accordion); } }); }); // Recalculate heights on resize $(window).on("resize", function () { refreshOpenHeights(); }); }); /* ========================== FAQ - NEW - END ========================== */ /* ========================== SLIDER BLOG and SOLUTION - START ========================== */ window.Webflow ||= []; window.Webflow.push(() => { const BREAKPOINT = 991; // slider works only 991px and below const SLIDERS = [ { wrapper: ".block-slider-blog-wrapper", swiper: ".swiper-wrapper.is-blog", }, { wrapper: ".slider-solution-wrapper", swiper: ".swiper-wrapper.is-solution", }, ]; const instances = new Map(); function isMobile() { return window.innerWidth <= BREAKPOINT; } function sliderExists(wrapperSelector, swiperSelector) { return ( document.querySelector(wrapperSelector) && document.querySelector(swiperSelector) ); } function initSlider(config) { if (!sliderExists(config.wrapper, config.swiper)) return; if (!isMobile()) return; if (instances.has(config.wrapper)) return; const wrapper = document.querySelector(config.wrapper); const instance = new Swiper(wrapper, { slidesPerView: "auto", spaceBetween: 8, speed: 800, grabCursor: true, watchOverflow: true, pagination: { el: wrapper.querySelector(".swiper-pagination"), clickable: true, }, navigation: { nextEl: wrapper.querySelector(".swiper-button-next"), prevEl: wrapper.querySelector(".swiper-button-prev"), }, breakpoints: { 0: { slidesPerView: "auto", }, 480: { slidesPerView: "auto", }, 768: { slidesPerView: "auto", }, }, }); instances.set(config.wrapper, instance); } function destroySlider(config) { if (!instances.has(config.wrapper)) return; const instance = instances.get(config.wrapper); instance.destroy(true, true); instances.delete(config.wrapper); } function handleResize() { SLIDERS.forEach((config) => { if (isMobile()) { initSlider(config); } else { destroySlider(config); } }); } handleResize(); window.addEventListener("resize", handleResize); }); /* ========================== SLIDER BLOG and SOLUTION - END ========================== */ /* ========================== TAB - SOLUTION - START ========================== */ document.addEventListener("DOMContentLoaded", () => { const cards = document.querySelectorAll(".card-transformation-wrap"); if (!cards.length) return; cards.forEach((card) => { const switches = card.querySelectorAll(".switch-transform"); const images = card.querySelectorAll(".image-transform"); if (!switches.length || !images.length) return; /* ================================ DEFAULT STATE (respect your HTML) ================================= */ let activeIndex = -1; switches.forEach((btn, index) => { if (btn.classList.contains("is-active")) { activeIndex = index; } }); // If no button has is-active → fallback to first if (activeIndex === -1) { activeIndex = 0; switches[0].classList.add("is-active"); } // Reset images images.forEach((img) => img.classList.remove("is-on")); // Activate correct image if (images[activeIndex]) { images[activeIndex].classList.add("is-on"); } /* ================================ HOVER LOGIC ================================= */ switches.forEach((btn, index) => { btn.addEventListener("mouseenter", () => { switches.forEach((s) => s.classList.remove("is-active")); images.forEach((img) => img.classList.remove("is-on")); btn.classList.add("is-active"); if (images[index]) { images[index].classList.add("is-on"); } }); }); }); }); /* ========================== TAB - SOLUTION - END ========================== */ /* ========================== TAB - WHY US - START ========================== */ document.addEventListener("DOMContentLoaded", () => { const wrappers = document.querySelectorAll(".table-and-switchs-wrapper"); if (!wrappers.length) return; wrappers.forEach((wrapper) => { const switches = wrapper.querySelectorAll(".switch-why-us"); // ❗ беремо тільки колонки БЕЗ is-first const columns = wrapper.querySelectorAll( ".colum-table-why-us:not(.is-first)" ); if (!switches.length || !columns.length) return; /* ================================ DEFAULT STATE (respect HTML) ================================= */ let activeIndex = -1; switches.forEach((btn, index) => { if (btn.classList.contains("is-active")) { activeIndex = index; } }); if (activeIndex === -1) { activeIndex = 0; switches[0].classList.add("is-active"); } columns.forEach((col) => { col.classList.remove("is-visible", "is-on"); }); if (columns[activeIndex]) { columns[activeIndex].classList.add("is-visible"); columns[activeIndex].classList.add("is-on"); } /* ================================ CLICK LOGIC ================================= */ switches.forEach((btn, index) => { btn.addEventListener("click", () => { switches.forEach((s) => s.classList.remove("is-active")); columns.forEach((col) => col.classList.remove("is-visible", "is-on")); btn.classList.add("is-active"); if (columns[index]) { columns[index].classList.add("is-visible"); columns[index].classList.add("is-on"); } }); }); }); }); /* ========================== TAB - WHY US - END ========================== */ /* ========================== SLIDER-IMPACT-START ========================== */ (function () { function initImpactSlider() { const sliderEl = document.querySelector(".slider-testimonial-impact"); if (!sliderEl) return; // prevent double init if (sliderEl.dataset.init === "true") return; sliderEl.dataset.init = "true"; // check Swiper if (typeof Swiper === "undefined") { console.warn("Swiper not found"); return; } const slides = sliderEl.querySelectorAll(".swiper-slide"); const bulletsWrapper = document.querySelector(".swiper-bullet-wrapper"); if (!slides.length || !bulletsWrapper) return; // ========================= // GENERATE BULLETS // ========================= bulletsWrapper.innerHTML = ""; slides.forEach(() => { const bullet = document.createElement("div"); bullet.className = "swiper-bullet"; const inner = document.createElement("div"); inner.className = "dotted-pagination-slider"; bullet.appendChild(inner); bulletsWrapper.appendChild(bullet); }); const bullets = bulletsWrapper.querySelectorAll(".swiper-bullet"); // ========================= // SETTINGS // ========================= const GAP = parseInt(sliderEl.getAttribute("data-gap")) || 24; // ========================= // INIT SWIPER // ========================= const swiper = new Swiper(sliderEl, { slidesPerView: 1, spaceBetween: GAP, speed: 600, autoHeight: true, watchSlidesProgress: true, // 👉 для prev/next класів observer: true, observeParents: true, on: { init: function () { updateBullets(this.activeIndex); }, slideChange: function () { updateBullets(this.activeIndex); }, }, }); // ========================= // BULLETS ACTIVE STATE // ========================= function updateBullets(index) { bullets.forEach((b, i) => { b.classList.toggle("is_active", i === index); }); } // ========================= // CLICK BULLETS // ========================= bullets.forEach((bullet, index) => { bullet.addEventListener("click", () => { swiper.slideTo(index); }); }); // ========================= // WEBFLOW FIX // ========================= setTimeout(() => swiper.update(), 100); } document.addEventListener("DOMContentLoaded", initImpactSlider); })(); /* ========================== SLIDER-IMPACT-END ========================== */ /* ========================== SLIDER-CAPABILITIES-START ========================== */ document.addEventListener("DOMContentLoaded", () => { let swiperInstance = null; const breakpoint = 991; function initSwiper() { const slider = document.querySelector(".slider-capabilities-wrapper"); // Safe guard if (!slider) return; const pagination = slider .closest(".slider-and-pagination-wrapper") ?.querySelector(".swiper-bullet-wrapper.is-slider-main"); if (!pagination) return; // Якщо вже ініціалізований → не дублюємо if (swiperInstance) return; swiperInstance = new Swiper(slider, { slidesPerView: 1, spaceBetween: 16, speed: 500, pagination: { el: pagination, clickable: true, bulletClass: "swiper-bullet", bulletActiveClass: "is_active", renderBullet: function (index, className) { return `
`; }, }, breakpoints: { 0: { slidesPerView: 1.1, spaceBetween: 12, }, 480: { slidesPerView: 1.1, spaceBetween: 16, }, 768: { slidesPerView: 1, spaceBetween: 20, }, }, }); } function destroySwiper() { if (swiperInstance) { swiperInstance.destroy(true, true); swiperInstance = null; } } function check() { if (window.innerWidth <= breakpoint) { initSwiper(); } else { destroySwiper(); } } // INIT check(); // RESIZE window.addEventListener("resize", check); }); /* ========================== SLIDER-CAPABILITIES-END ========================== */ /* ========================== OPEN_NAVIGATION_NAVBAR_START ========================== */ $(document).ready(function () { const $switch = $(".switch-nav-menu"); const $menuWrapper = $(".menu-navbar-wrapper"); const $navbarAnimation = $(".block-navbar-animation"); const $navbarMenu = $(".navbar-menu"); const $mask = $(".mask-nav"); const $lineTop = $(".line-nav-vertical"); const $lineBottom = $(".line-nav-vertical-bottom"); const $mobHover = $(".block-buttom-mob-hover"); // mobile element const $linerBg = $(".liner-bg-inner-menu"); // 👉 NEW if (!$switch.length || !$menuWrapper.length) return; // INITIAL STATE $menuWrapper.css({ "max-height": "0px", overflow: "hidden", opacity: "0", }); function openMenu() { const vh = window.innerWidth < 768 ? "90vh" : "80vh"; $menuWrapper.addClass("is-open").stop(true, true).animate( { "max-height": vh, opacity: 1, }, 500 ); $navbarAnimation.addClass("is-active"); $navbarMenu.addClass("is-off"); $mask.addClass("is-on"); $("body").addClass("no-scroll"); // 👉 ADD CLASS $linerBg.addClass("is-on"); // add class on mobile if (window.innerWidth < 768) { $mobHover.addClass("is-on-mob"); } // BURGER → X $lineTop.css("transform", "translate(0px,2px) rotate(-45deg)"); $lineBottom.css("transform", "translate(0px,-3px) rotate(45deg)"); } function closeMenu() { $menuWrapper.removeClass("is-open").stop(true, true).animate( { "max-height": "0px", opacity: 0, }, 400 ); $navbarMenu.removeClass("is-off"); $mask.removeClass("is-on"); $("body").removeClass("no-scroll"); // 👉 REMOVE CLASS $linerBg.removeClass("is-on"); // remove class on mobile if (window.innerWidth < 768) { $mobHover.removeClass("is-on-mob"); } setTimeout(function () { $navbarAnimation.removeClass("is-active"); }, 300); // RESET BURGER $lineTop.css("transform", ""); $lineBottom.css("transform", ""); } $switch.on("click", function () { if ($menuWrapper.hasClass("is-open")) { closeMenu(); } else { openMenu(); } }); $(".link-navbar, .link-navbar-huge").on("click", function () { closeMenu(); }); }); /* ========================== OPEN_NAVIGATION_NAVBAR_END ========================== */ /* ========================== CURSOR-MOVEMENT_START ========================== */ document.addEventListener("DOMContentLoaded", () => { /* Run only on desktop */ if (window.innerWidth <= 991) return; /* ============================== GLOBAL CURSOR ============================== */ const globalCursor = document.querySelector(".cursor-wrapper"); if (globalCursor) { /* Cursor follow */ window.addEventListener("mousemove", (e) => { globalCursor.style.left = `${e.clientX}px`; globalCursor.style.top = `${e.clientY}px`; }); function showCursor() { globalCursor.classList.add("is-visible"); } function hideCursor() { globalCursor.classList.remove("is-visible"); } /* Default cursor trigger */ document.addEventListener("mouseover", (e) => { const trigger = e.target.closest("[data-cursor-trigger]"); if (!trigger) return; showCursor(); }); document.addEventListener("mouseout", (e) => { const trigger = e.target.closest("[data-cursor-trigger]"); if (!trigger) return; hideCursor(); }); } /* ============================== VIEW MORE CURSOR ============================== */ const wrappersView = document.querySelectorAll("[data-view-more]"); if (wrappersView.length) { wrappersView.forEach((wrapper) => { const viewCursor = wrapper.querySelector(".cursor-view-more-wrapper"); if (!viewCursor) return; wrapper.addEventListener("mousemove", (e) => { const rect = wrapper.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; viewCursor.style.left = `${x}px`; viewCursor.style.top = `${y}px`; }); wrapper.addEventListener("mouseenter", () => { viewCursor.classList.add("is-visible"); }); wrapper.addEventListener("mouseleave", () => { viewCursor.classList.remove("is-visible"); }); }); } /* ============================== SEE MORE CURSOR ============================== */ const parent = document.body; parent.addEventListener("mousemove", (e) => { const wrapper = e.target.closest(".card-case-studie-wrapper"); if (!wrapper) return; const viewCursor = wrapper.querySelector(".cursor-see-more-wrapper"); if (!viewCursor) return; const rect = wrapper.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; viewCursor.style.left = `${x}px`; viewCursor.style.top = `${y}px`; }); parent.addEventListener( "mouseenter", (e) => { const wrapper = e.target.closest(".card-case-studie-wrapper"); if (!wrapper) return; const viewCursor = wrapper.querySelector(".cursor-see-more-wrapper"); if (!viewCursor) return; viewCursor.classList.add("is-visible"); }, true ); parent.addEventListener( "mouseleave", (e) => { const wrapper = e.target.closest(".card-case-studie-wrapper"); if (!wrapper) return; const viewCursor = wrapper.querySelector(".cursor-see-more-wrapper"); if (!viewCursor) return; viewCursor.classList.remove("is-visible"); }, true ); }); /* ========================== CURSOR-MOVEMENT_END ========================== */ /* ========================== NAVBAR-ICON-LOGO-MUVE-START ========================== */ document.addEventListener("DOMContentLoaded", () => { const logoBox = document.querySelector(".box-animat-logo-icon"); const logoMove = document.querySelector(".box-icon-muve-nav"); const navbarMenu = document.querySelector(".navbar-menu"); const linerBg = document.querySelector(".liner-bg-navbar"); // Safety checks if (!logoBox || !logoMove || !navbarMenu || !linerBg) return; let lastScroll = 0; const SCROLL_TRIGGER = 200; const DELTA = 2; function handleNavbarScroll() { let currentScroll = window.pageYOffset || document.documentElement.scrollTop || 0; currentScroll = Math.max(currentScroll, 0); if (currentScroll <= SCROLL_TRIGGER) { navbarMenu.classList.remove("is-off-new"); logoBox.style.width = "0rem"; logoMove.style.transform = "translateY(-100%)"; logoMove.style.opacity = "0"; linerBg.classList.remove("is-active"); lastScroll = currentScroll; return; } logoBox.style.width = "2.25rem"; logoMove.style.transform = "translateY(0)"; logoMove.style.opacity = "1"; linerBg.classList.add("is-active"); if (currentScroll > lastScroll + DELTA) { navbarMenu.classList.add("is-off-new"); } if (currentScroll < lastScroll - DELTA) { navbarMenu.classList.remove("is-off-new"); } lastScroll = currentScroll; } window.addEventListener("scroll", handleNavbarScroll, { passive: true }); handleNavbarScroll(); }); /* ========================== NAVBAR-ICON-LOGO-MUVE-END ========================== */ /*document.addEventListener("DOMContentLoaded", () => { if (window.innerWidth > 480) return; if (window.location.pathname.includes("/works")) return; const cards = document.querySelectorAll(".card-case-studie-wrapper"); if (!cards.length) return; const REM = parseFloat(getComputedStyle(document.documentElement).fontSize); const BASE_TOP_REM = 6; const baseTop = BASE_TOP_REM * REM; const STEP = 63; cards.forEach((card, index) => { card.style.position = "sticky"; card.style.top = `${baseTop + index * STEP}px`; card.style.zIndex = index + 1; }); });*/ /* ========================= END CODE STICKE MOBE CARD ========================= */ document.addEventListener("DOMContentLoaded", () => { /* ========================= ONLY DESKTOP 🔥 ========================= */ if (window.innerWidth <= 991) return; const TARGET_SELECTOR = ` [data-hover-text], .link-navbar-huge, .link-block-navbar, .link-footer, .item-benefit-lifecycie, .button-capabilities, .badge.is-blog, .badge.is-case, .button `; const TEXT_SELECTOR = ` .label-20-semibold, .label-16-semibold, .body-40-bold, .label-18-semibold `; /* ========================= HEIGHT CONFIG 🔥 👉 тут керуєш всіма варіантами ========================= */ const HEIGHT_CONFIG = [ { selector: ".button", value: "1.4em", }, { selector: ".badge.is-blog", value: "1.1em", }, { selector: ".badge.is-case", value: "1.1em", }, { selector: ".button-capabilities", value: "1.42em", }, { selector: ".item-benefit-lifecycie", value: "1.4em", }, ]; const elements = document.querySelectorAll(TARGET_SELECTOR); elements.forEach((el) => { if (el.hasAttribute("data-hover-initialized")) return; el.setAttribute("data-hover-initialized", "true"); const textEl = el.querySelector(TEXT_SELECTOR); if (!textEl) return; const text = textEl.textContent.trim(); /* ========================= CREATE WRAPPER ========================= */ const wrapper = document.createElement("div"); wrapper.classList.add("animation-hover-text"); /* ========================= HEIGHT LOGIC 🔥 ========================= */ const customHeight = el.getAttribute("data-hover-height"); if (customHeight) { const hasUnit = /[a-z%]+$/i.test(customHeight); wrapper.style.height = hasUnit ? customHeight : `${customHeight}em`; } else { // 👉 check config const matched = HEIGHT_CONFIG.find((item) => el.matches(item.selector)); if (matched) { wrapper.style.height = matched.value; } } /* ========================= CREATE TEXT ========================= */ const line1 = document.createElement("div"); const line2 = document.createElement("div"); line1.className = textEl.className; line2.className = textEl.className; line1.textContent = text; line2.textContent = text; wrapper.appendChild(line1); wrapper.appendChild(line2); textEl.replaceWith(wrapper); /* ========================= HOVER LOGIC ========================= */ el.addEventListener("mouseenter", () => { wrapper.classList.add("is-animate"); }); el.addEventListener("mouseleave", () => { wrapper.classList.remove("is-animate"); }); }); }); /* ========================= RICH TEXT MUVE -START ========================= */ /* document.addEventListener("DOMContentLoaded", () => { if (window.innerWidth <= 991) return; const links = document.querySelectorAll(".description-body a"); if (!links.length) return; links.forEach((link) => { if (link.hasAttribute("data-rt-hover")) return; link.setAttribute("data-rt-hover", "true"); const text = link.textContent.trim(); if (!text) return; const wrapper = document.createElement("span"); wrapper.classList.add("rt-link-hover"); const line1 = document.createElement("span"); const line2 = document.createElement("span"); line1.className = "rt-link-line"; line2.className = "rt-link-line"; line1.textContent = text; line2.textContent = text; wrapper.appendChild(line1); wrapper.appendChild(line2); link.innerHTML = ""; link.appendChild(wrapper); link.addEventListener("mouseenter", () => { wrapper.classList.add("is-hovered"); }); link.addEventListener("mouseleave", () => { wrapper.classList.remove("is-hovered"); }); }); }); */ /* ========================= RICH TEXT MUVE - END ========================= */