<div class="mol-contact-info-cta" data-contact-cta data-contact-cta-state="not-active">
<button class="contact-cta-toggle atm-button atm-button-primary button-md icon-only button-icon-only">
<div class="button-content-wrapper">
<span class="button-content">
<i class="atm-icon not-active far fa-message fa-fw" style="--scale: 1;"></i>
<i class="atm-icon active far fa-xmark fa-fw" style="--scale: 1;"></i>
</span>
</div>
<span class="button-triangle" style="--scale: 1;"></span>
</button>
<div id="contact-cta-link-wrapper">
<div id="back-to-top">
<a href="">
<svg viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="46" stroke="url(#gradient)" stroke-width="8" stroke-linecap="round" />
<defs>
<radialGradient id="gradient" cx="1" cy="1" r="1.5">
<stop offset="0%" stop-color="#990D7F" />
<stop offset="100%" stop-color="#990D7F" />
</radialGradient>
</defs>
</svg>
<span class="atm-icon fa-light fa-arrow-up"></span>
</a>
</div>
<a class="atm-button atm-button-primary contact-cta-link button-md icon-only button-icon-only ">
<div class="button-content-wrapper">
<span class="button-content">
<i class="atm-icon far fa-phone fa-fw"></i>
</span>
</div>
<span class="button-triangle"></span>
</a>
<a class="atm-button atm-button-primary contact-cta-link button-md icon-only button-icon-only ">
<div class="button-content-wrapper">
<span class="button-content">
<i class="atm-icon far fa-envelope fa-fw"></i>
</span>
</div>
<span class="button-triangle"></span>
</a>
</div>
</div>
<div class="mol-contact-info-cta" data-contact-cta data-contact-cta-state="not-active">
<button class="contact-cta-toggle atm-button atm-button-primary button-md icon-only button-icon-only">
<div class="button-content-wrapper">
<span class="button-content">
<i class="atm-icon not-active far fa-message fa-fw" style="--scale: 1;"></i>
<i class="atm-icon active far fa-xmark fa-fw" style="--scale: 1;"></i>
</span>
</div>
<span class="button-triangle" style="--scale: 1;"></span>
</button>
<div id="contact-cta-link-wrapper">
{{render "@back-to-top"}}
{{render "@button-primary--icon-only-md" phone merge=true}}
{{render "@button-primary--icon-only-md" mail merge=true}}
</div>
</div>
{
"url": "",
"contact": {
"icon": {
"style": "fal",
"icon": "fa-xmark"
}
},
"phone": {
"class": "contact-cta-link",
"icon": {
"style": "far",
"icon": "fa-phone"
}
},
"mail": {
"class": "contact-cta-link",
"icon": {
"style": "far",
"icon": "fa-envelope"
}
}
}
.mol-contact-info-cta {
@apply fixed z-50 right-4 bottom-16 flex flex-col-reverse cursor-pointer text-center;
* {
@apply transition-all;
}
.contact-cta-toggle {
@apply relative z-50;
}
&[data-contact-cta-state='not-active'] {
.contact-cta-toggle {
.active {
@apply hidden;
}
}
}
&[data-contact-cta-state='active'] {
.contact-cta-toggle {
@apply bg-[#F0CAE3];
.not-active {
@apply hidden;
}
.active {
@apply flex text-secondary-col-1;
}
}
}
#contact-cta-link-wrapper {
@apply flex flex-col-reverse;
.contact-cta-link,
.back-to-top {
@apply max-h-12 mb-2;
}
}
}
(function () {
'use strict';
const backToTop = document.getElementById('back-to-top');
const contactCta = document.querySelector('[data-contact-cta]');
const contactCtaLinks = '.contact-cta-link';
let hasScrolled = false;
// Initial GSAP settings
if (document.querySelector(contactCtaLinks)) {
gsap.set(contactCtaLinks, { scale: 0, y: '100%' });
}
if (backToTop) {
gsap.set('#back-to-top', { scale: 0, y: '100%' });
}
// Reusable GSAP Animations
const animateElement = (
targets,
{ scale, y, height = null, display = 'block', onComplete = null }
) => {
gsap.to(targets, {
duration: 0.2,
scale,
y,
height,
display,
onComplete,
ease: 'power1.inOut',
});
};
// Scroll Listener for triggering animations
const handleScroll = () => {
const isDesktop = window.innerWidth > 768; // Define desktop size threshold
if (!isDesktop) return; // Skip if not desktop
const scrollPosition = window.scrollY;
if (scrollPosition > 200 && !hasScrolled) {
// Trigger animations when user scrolls down
hasScrolled = true;
contactCta.dataset.contactCtaState = 'active';
animateElement(`${contactCtaLinks}, #back-to-top`, {
scale: 1,
y: 0,
stagger: 0.1,
});
} else if (scrollPosition <= 200 && hasScrolled) {
// Revert animations when user scrolls back up
hasScrolled = false;
contactCta.dataset.contactCtaState = 'not-active';
animateElement(`${contactCtaLinks}, #back-to-top`, {
scale: 0,
y: '100%',
stagger: -0.1,
onComplete: () => {
if (backToTop) backToTop.style.display = 'none'; // Optionally hide after animation
},
});
}
};
// Attach scroll event listener (desktop only)
const updateScrollListener = () => {
const isDesktop = window.innerWidth > 768; // Define desktop size threshold
if (isDesktop) {
window.addEventListener('scroll', handleScroll);
} else {
window.removeEventListener('scroll', handleScroll);
}
};
// Initialize scroll listener on page load and resize
window.addEventListener('resize', updateScrollListener);
updateScrollListener();
// Scroll Listener for Back to Top
if (backToTop) {
// Smooth scroll to top
backToTop.addEventListener('click', (e) => {
e.preventDefault();
window.scrollTo({ top: 0, behavior: 'smooth' });
});
}
// Contact CTA Click Handler
if (contactCta) {
contactCta.addEventListener('click', () => {
const isActive = contactCta.dataset.contactCtaState === 'active';
if (!isActive) {
contactCta.dataset.contactCtaState = 'active';
animateElement(`${contactCtaLinks}, #back-to-top`, {
scale: 1,
y: 0,
stagger: 0.1,
});
} else {
contactCta.dataset.contactCtaState = 'not-active';
animateElement(`${contactCtaLinks}, #back-to-top`, {
scale: 0,
y: '100%',
stagger: -0.1,
onComplete: () => {
backToTop.style.display = 'none'; // Hide after animation
},
});
}
});
}
})();
No notes defined.