We use cookies to run the site reliably, protect it, remember preferences, and understand what content performs best. Where required, we ask for permission before using non-essential cookies.
Essential cookies keep the site working and secure.
Preference cookies remember settings (including cookie choices).
Analytics cookies help us improve performance and content (only where permitted).
Third-party tools (e.g., quote/scheduling, reviews, video embeds) may set their own cookies.
Need to update your cookie choices? Use your browser controls, or (if available) click the site’s “Cookie Preferences” link in the footer to revisit consent options.
Control non-essential cookiesWithdraw consent any timeEssential cookies always on
1) What cookies are
Cookies are small text files stored on your device when you visit a website. They help websites function, remember preferences, and understand how visitors interact with pages.
We also may use similar technologies, such as local storage, pixels/tags, and device identifiers. For simplicity, we refer to all of these as “cookies” in this policy.
2) How we use cookies
Strictly necessary (essential)
These cookies are required for core site functionality and security. Without them, parts of the website may not work.
Security and fraud prevention
Load balancing and performance stability
Consent management (storing your cookie choices)
Preferences / functional
These cookies remember choices you make so the experience feels consistent (for example, remembering a selection or form progress).
Analytics
Analytics cookies help us understand how visitors use the site (pages visited, time on page, traffic sources), so we can improve performance, content clarity, and user experience. Where required, analytics runs only after consent.
Marketing
Marketing cookies are typically used to measure ad performance or deliver targeted advertising. If we ever enable marketing cookies, we will do so only in line with applicable law and your cookie choices.
3) Vendors currently loaded on this site
The following vendors fire on this website via our Google Tag Manager container (GTM-53B434NQ) and related mechanisms. Each vendor may set cookies, pixels, or local-storage identifiers. Where a direct opt-out is available, the link is provided.
Vendor
Purpose
Identifier / Container
Typical duration
Opt-out
Google Tag Manager
Container that loads and manages other tracking tags on this site
GTM-53B434NQ
Session
Disable JavaScript or use browser cookie controls
Google Analytics 4
Aggregated site-usage analytics, session counts, and user-flow reports
This list represents the vendors currently wired into our site. Tags may be added, removed, or paused as we refine measurement; consult this page for the current state.
4) Cookie categories & examples
The exact cookies on your device can vary based on the page you visit, whether you interact with embedded tools, and your browser settings. Below is a representative list.
Cookies from scheduling/CRM (e.g., Jobber at clienthub.getjobber.com)
Varies by provider
Third-party
5) Third-party tools & embeds
Some site features rely on third-party platforms. If you interact with those features, the third party may collect information and set cookies under their own policies.
Quote requests / scheduling
Our quote request experience may be served through our scheduling/CRM platform. On our Contact page, the form routes to clienthub.getjobber.com. That service may use cookies to operate the form and maintain session integrity.
Reviews / reputation widgets
We may display verified customer reviews and rating widgets powered by third-party services that may set their own cookies.
Video embeds
If we embed videos, the video provider may set cookies when the embed loads or when you press play.
Maps and external links
Some pages may include maps or links to third-party resources. Clicking out to another website means that site’s cookies and policies apply.
6) Your choices & controls
Cookie preferences (consent tool)
Where required, we provide a consent choice before non-essential cookies are used. If a cookie preferences panel is available, you can revisit it any time via the “Cookie Preferences” link in the site footer.
Browser settings
You can control cookies directly in your browser (block, delete, or limit storage). Most browsers allow you to:
Delete cookies and site data
Block third-party cookies
Block cookies for specific websites
Clear data on exit
If you disable cookies, some features may not function as intended (especially forms, embedded tools, and preference settings).
Do Not Track / Global privacy signals
Some browsers offer “Do Not Track” or similar global privacy signals. Because there is no single uniform standard, our response may vary by jurisdiction.
7) Retention & lifespan
Cookies can be:
Session cookies (deleted when you close your browser)
Persistent cookies (remain until they expire or you delete them)
Lifespans vary by cookie purpose and provider configuration.
8) Updates to this policy
We may update this Cookie Policy from time to time. The “Last updated” date at the top shows when this page was most recently revised.
9) Contact
For questions about cookies or privacy on this site, contact:
This Cookie Policy should be read alongside our Privacy Policy, which explains how we collect, use, and protect personal information.
(function(){
function killRevealAnimations(){
document.querySelectorAll(‘.reveal’).forEach(function(el){
if(el.getAnimations){
el.getAnimations().forEach(function(a){a.cancel()});
}
el.removeAttribute(‘style’);
});
}
if(document.readyState===’loading’){
document.addEventListener(‘DOMContentLoaded’,function(){
killRevealAnimations();
setTimeout(killRevealAnimations,500);
setTimeout(killRevealAnimations,2000);
});
} else {
killRevealAnimations();
setTimeout(killRevealAnimations,500);
setTimeout(killRevealAnimations,2000);
}
/* Also kill animations when .is-visible is added (scroll reveal fires) */
if(typeof MutationObserver!==’undefined’){
var mo=new MutationObserver(function(mutations){
mutations.forEach(function(m){
if(m.type===’attributes’&&m.attributeName===’class’){
var el=m.target;
if(el.classList.contains(‘reveal’)&&el.classList.contains(‘is-visible’)){
if(el.getAnimations){
el.getAnimations().forEach(function(a){a.cancel()});
}
el.removeAttribute(‘style’);
}
}
});
});
function observeReveals(){
document.querySelectorAll(‘.reveal’).forEach(function(el){
mo.observe(el,{attributes:true,attributeFilter:[‘class’]});
});
}
if(document.readyState===’loading’){
document.addEventListener(‘DOMContentLoaded’,observeReveals);
} else {
observeReveals();
}
}
})();
/* ═══════════════════════════════════════════════════════════════════
FCPE MASTER SCRIPT — v1.0
Header interactivity + Premium luxury effects
═══════════════════════════════════════════════════════════════════ */
/* ─────────────────────────────────────────────────────────────────
SECTION 1: HEADER INTERACTIVITY
Mobile menu, mega dropdowns, scroll glass effect, sparkles
───────────────────────────────────────────────────────────────── */
function fcpeHdrInit(){
‘use strict’;
if(window._fcpeHdrDone)return true;window._fcpeHdrDone=true;
var wrap = document.querySelector(‘.fcpe-hdr-wrap’);
var hdr = document.querySelector(‘.fcpe-hdr’);
var burger = document.querySelector(‘.fcpe-hdr-burger’);
var panel = document.querySelector(‘.fcpe-hdr-panel’);
var overlay = document.querySelector(‘.fcpe-hdr-panel-overlay’);
if (!wrap || !hdr) return false;
/* Kill Elementor parent constraints */
(function(){
var el = wrap.parentElement;
while(el && el !== document.body){
el.style.background = ‘transparent’;
el.style.backgroundColor = ‘transparent’;
el.style.padding = ‘0’;
el.style.margin = ‘0’;
el.style.maxWidth = ‘none’;
el.style.overflow = ‘visible’;
el.style.border = ‘none’;
el.style.boxShadow = ‘none’;
el.style.minHeight = ‘0’;
el.style.transform = ‘none’;
el.style.webkitTransform = ‘none’;
el.style.willChange = ‘auto’;
el.style.filter = ‘none’;
el.style.perspective = ‘none’;
el.style.contain = ‘none’;
el.style.containerType = ‘normal’;
if(el.classList && (el.classList.contains(‘elementor-section’) || el.classList.contains(‘e-con’))) break;
el = el.parentElement;
}
if(el) el = el.parentElement;
while(el && el !== document.body){
el.style.transform = ‘none’;
el.style.webkitTransform = ‘none’;
el.style.willChange = ‘auto’;
el.style.filter = ‘none’;
el.style.perspective = ‘none’;
el.style.contain = ‘none’;
el.style.overflow = ‘visible’;
el = el.parentElement;
}
if(window.innerWidth 60);
ticking = false;
});
ticking = true;
}
}
window.addEventListener(‘scroll’, onScroll, { passive: true });
onScroll();
/* Desktop mega dropdowns */
var navItems = hdr.querySelectorAll(‘.fcpe-hdr-nav > li’);
var closeTimer = null;
navItems.forEach(function(item) {
var btn = item.querySelector(‘button’);
var mega = item.querySelector(‘.fcpe-hdr-mega’);
if (!btn || !mega) return;
function openMega() {
clearTimeout(closeTimer);
navItems.forEach(function(other) {
if (other !== item) {
other.classList.remove(‘fcpe-hdr-open’);
var ob = other.querySelector(‘button’);
if (ob) ob.setAttribute(‘aria-expanded’, ‘false’);
}
});
item.classList.add(‘fcpe-hdr-open’);
btn.setAttribute(‘aria-expanded’, ‘true’);
}
function closeMega() {
closeTimer = setTimeout(function() {
item.classList.remove(‘fcpe-hdr-open’);
btn.setAttribute(‘aria-expanded’, ‘false’);
}, 250);
}
item.addEventListener(‘mouseenter’, openMega);
item.addEventListener(‘mouseleave’, closeMega);
btn.addEventListener(‘click’, function(e) {
e.preventDefault();
if (item.classList.contains(‘fcpe-hdr-open’)) {
item.classList.remove(‘fcpe-hdr-open’);
btn.setAttribute(‘aria-expanded’, ‘false’);
} else {
openMega();
}
});
mega.addEventListener(‘mouseenter’, function() { clearTimeout(closeTimer); });
mega.addEventListener(‘mouseleave’, closeMega);
});
/* Close dropdowns on outside click */
document.addEventListener(‘click’, function(e) {
if (!hdr.contains(e.target)) {
navItems.forEach(function(item) {
item.classList.remove(‘fcpe-hdr-open’);
var b = item.querySelector(‘button’);
if (b) b.setAttribute(‘aria-expanded’, ‘false’);
});
}
});
/* Mobile hamburger */
function togglePanel() {
var isOpen = panel.classList.contains(‘fcpe-hdr-panel-open’);
panel.classList.toggle(‘fcpe-hdr-panel-open’);
overlay.classList.toggle(‘fcpe-hdr-panel-open’);
burger.classList.toggle(‘fcpe-hdr-active’);
burger.setAttribute(‘aria-expanded’, String(!isOpen));
burger.setAttribute(‘aria-label’, isOpen ? ‘Open menu’ : ‘Close menu’);
document.body.style.overflow = isOpen ? ” : ‘hidden’;
document.body.classList.toggle(‘fcpe-panel-is-open’, !isOpen);
}
var panelX = panel ? panel.querySelector(‘.fcpe-hdr-panel-x’) : null;
if (burger) {
burger.addEventListener(‘click’, function(e) {
e.stopPropagation();
togglePanel();
});
}
if (overlay) overlay.addEventListener(‘click’, togglePanel);
if (panelX) panelX.addEventListener(‘click’, togglePanel);
/* Mobile accordions */
var mnavBtns = panel ? panel.querySelectorAll(‘.fcpe-hdr-mnav > li > button’) : [];
mnavBtns.forEach(function(btn) {
btn.addEventListener(‘click’, function() {
var li = btn.parentElement;
var wasOpen = li.classList.contains(‘fcpe-hdr-mopen’);
panel.querySelectorAll(‘.fcpe-hdr-mnav > li’).forEach(function(item) {
item.classList.remove(‘fcpe-hdr-mopen’);
var b = item.querySelector(‘button’);
if (b) b.setAttribute(‘aria-expanded’, ‘false’);
});
if (!wasOpen) {
li.classList.add(‘fcpe-hdr-mopen’);
btn.setAttribute(‘aria-expanded’, ‘true’);
}
});
});
/* CTA Sparkle Magic */
var ctaBtn = document.querySelector(‘.fcpe-hdr-cta’);
if (ctaBtn && window.innerWidth > 980) {
var sparkleWrap = document.createElement(‘span’);
sparkleWrap.style.cssText = ‘position:absolute;inset:-8px;pointer-events:none;overflow:visible;z-index:0’;
ctaBtn.style.position = ‘relative’;
ctaBtn.appendChild(sparkleWrap);
function createSparkle() {
var s = document.createElement(‘span’);
var size = Math.random() * 4 + 2;
var x = Math.random() * 100;
var y = Math.random() * 100;
s.style.cssText = ‘position:absolute;width:’+size+’px;height:’+size+’px;’ +
‘background:radial-gradient(circle,#FFF8DC,#D4AF37);border-radius:50%;’ +
‘left:’+x+’%;top:’+y+’%;opacity:0;pointer-events:none;’ +
‘animation:fcpeSparkle ‘+(.6+Math.random()*.8)+’s ease-out forwards’;
sparkleWrap.appendChild(s);
setTimeout(function(){s.remove()}, 1400);
}
setInterval(function(){
if (document.visibilityState === ‘visible’) createSparkle();
}, 400);
ctaBtn.addEventListener(‘mouseenter’, function() {
for (var i = 0; i < 8; i++) {
setTimeout(createSparkle, i * 40);
}
});
var sparkleStyle = document.createElement('style');
sparkleStyle.textContent = '@keyframes fcpeSparkle{0%{opacity:0;transform:scale(0) translateY(0)}30%{opacity:1;transform:scale(1.2) translateY(-4px)}100%{opacity:0;transform:scale(0) translateY(-12px)}}';
document.head.appendChild(sparkleStyle);
}
/* Escape key closes everything */
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
navItems.forEach(function(item) {
item.classList.remove('fcpe-hdr-open');
var b = item.querySelector('button');
if (b) b.setAttribute('aria-expanded', 'false');
});
if (panel && panel.classList.contains('fcpe-hdr-panel-open')) {
togglePanel();
}
}
});
/* Sticky Floating Quote Button */
var stickyQuote = document.querySelector('.fcpe-hdr-sticky-quote');
if (stickyQuote && window.innerWidth showThreshold && !stickyVisible) {
stickyQuote.classList.add(‘fcpe-sticky-visible’);
stickyVisible = true;
} else if (scrollY <= showThreshold && stickyVisible) {
stickyQuote.classList.remove('fcpe-sticky-visible');
stickyVisible = false;
}
}, {passive: true});
}
return true;
}
/* Header init with retry */
function fcpeHdrInitOnce() {
if (window._fcpeHdrDone) return true;
var ok = fcpeHdrInit();
if (ok) window._fcpeHdrDone = true;
return ok;
}
if (!fcpeHdrInitOnce()) {
document.addEventListener('DOMContentLoaded', fcpeHdrInitOnce);
setTimeout(fcpeHdrInitOnce, 500);
setTimeout(fcpeHdrInitOnce, 1500);
}
/* ─────────────────────────────────────────────────────────────────
SECTION 2: PREMIUM EFFECTS (FIXED — with noReveal filter)
Lenis smooth scroll, GSAP reveals, gold particles,
before/after slider, 3D tilt, magnetic cursor, sticky nav,
CTA glow, horizontal scroll
NOTE: Uses _fcpeFixedPremiumDone guard (not _fcpePremiumDone)
so this ALWAYS runs even if the header template's broken copy
already executed. The CSS !important override above ensures
.reveal elements stay visible regardless.
───────────────────────────────────────────────────────────────── */
(function(){
'use strict';
if(window._fcpeFixedPremiumDone) return;
window._fcpeFixedPremiumDone=true;
var REDUCED=window.matchMedia&&window.matchMedia('(prefers-reduced-motion:reduce)').matches;
var IS_MOBILE=window.innerWidth0;
function ready(fn){
if(document.readyState!==’loading’) fn();
else document.addEventListener(‘DOMContentLoaded’,fn);
}
function waitForLib(name,cb,timeout){
timeout=timeout||8000;
var start=Date.now();
(function check(){
if(window[name]) return cb(window[name]);
if(Date.now()-start>timeout) return;
setTimeout(check,80);
})();
}
/* ═══════ 1. LENIS SMOOTH SCROLL ═══════ */
function initLenis(){
if(REDUCED) return;
waitForLib(‘Lenis’,function(Lenis){
var lenis=new Lenis({
duration:1.15,
easing:function(t){return Math.min(1,1.001-Math.pow(2,-10*t))},
orientation:’vertical’,
gestureOrientation:’vertical’,
smoothWheel:true,
touchMultiplier:1.5,
autoResize:true
});
waitForLib(‘ScrollTrigger’,function(ST){
lenis.on(‘scroll’,ST.update);
gsap.ticker.add(function(time){lenis.raf(time*1000)});
gsap.ticker.lagSmoothing(0);
});
if(!window.gsap){
function raf(time){lenis.raf(time);requestAnimationFrame(raf)}
requestAnimationFrame(raf);
}
document.querySelectorAll(‘a[href^=”#”]’).forEach(function(a){
a.addEventListener(‘click’,function(e){
var sel=this.getAttribute(‘href’);
if(!sel||sel.length<2) return;
var target=document.querySelector(sel);
if(!target) return;
e.preventDefault();
lenis.scrollTo(target,{offset:-80});
});
});
window._fcpeLenis=lenis;
});
}
/* ═══════ 2. GSAP CINEMATIC REVEALS (FIXED) ═══════
IMPORTANT: Skip elements with .reveal class — those already have
their own CSS IntersectionObserver system. GSAP inline styles
(opacity:0) would override the CSS and make cards invisible.
Also cleans up any broken GSAP animations from the header template. */
function initGSAPReveals(){
if(REDUCED) return;
waitForLib('gsap',function(){
waitForLib('ScrollTrigger',function(ST){
gsap.registerPlugin(ST);
/* ── CLEANUP: Remove broken GSAP inline styles from .reveal elements ──
The header template's unfixed premium effects JS may have already run
gsap.from({opacity:0}) on .reveal elements, setting inline opacity:0
that overrides the CSS animation system. Clean that up now. */
document.querySelectorAll('.reveal').forEach(function(el){
if(typeof gsap.killTweensOf==='function') gsap.killTweensOf(el);
el.style.removeProperty('opacity');
el.style.removeProperty('transform');
el.style.removeProperty('translate');
el.style.removeProperty('rotate');
el.style.removeProperty('scale');
});
/* Helper: filter out elements that use the .reveal CSS system */
function noReveal(els){
return Array.prototype.filter.call(els,function(el){
return !el.classList.contains('reveal');
});
}
/* Section headers stagger (skip if .reveal) */
document.querySelectorAll('.section-header').forEach(function(header){
var children=noReveal(header.children);
if(!children.length) return;
gsap.from(children,{
y:32,opacity:0,duration:.7,
stagger:.12,ease:'power2.out',
scrollTrigger:{trigger:header,start:'top 82%',toggleActions:'play none none none'}
});
});
/* Service cards stagger cascade (skip if .reveal) */
document.querySelectorAll('.service-grid,.trust-grid,.testimonials-grid,.gold-standard__pillars').forEach(function(grid){
var items=noReveal(grid.children);
if(!items.length) return;
gsap.from(items,{
y:48,opacity:0,duration:.65,
stagger:{each:.1,from:'start'},ease:'power2.out',
scrollTrigger:{trigger:grid,start:'top 78%',toggleActions:'play none none none'}
});
});
/* Gold rules grow from center (skip if .reveal) */
document.querySelectorAll('.gold-rule').forEach(function(rule){
if(rule.classList.contains('reveal')) return;
gsap.from(rule,{
scaleX:0,duration:.85,ease:'power2.out',
scrollTrigger:{trigger:rule,start:'top 88%',toggleActions:'play none none none'}
});
});
/* Cert badges cascade (skip if .reveal) */
var certBadges=document.querySelector('.cert-badges');
if(certBadges){
var badges=noReveal(certBadges.children);
if(badges.length){
gsap.from(badges,{
y:20,opacity:0,duration:.55,stagger:.08,ease:'power2.out',
scrollTrigger:{trigger:certBadges,start:'top 85%',toggleActions:'play none none none'}
});
}
}
/* Stats bar items (skip if .reveal) */
document.querySelectorAll('.stats-bar__item').forEach(function(item,i){
if(item.classList.contains('reveal')) return;
gsap.from(item,{
y:24,opacity:0,duration:.6,delay:i*.12,ease:'power2.out',
scrollTrigger:{trigger:item,start:'top 88%',toggleActions:'play none none none'}
});
});
/* Gift band entrance (skip if .reveal) */
var giftBand=document.querySelector('.gift-band');
if(giftBand && !giftBand.classList.contains('reveal')){
gsap.from(giftBand,{
y:40,opacity:0,scale:.97,duration:.8,ease:'power2.out',
scrollTrigger:{trigger:giftBand,start:'top 80%',toggleActions:'play none none none'}
});
}
/* God Standard badge + copy */
var godBadge=document.querySelector('.gold-standard__badge');
var godCopy=document.querySelector('.gold-standard__copy');
if(godBadge && !godBadge.classList.contains('reveal')){
gsap.from(godBadge,{
x:-60,opacity:0,rotation:-5,duration:.9,ease:'power2.out',
scrollTrigger:{trigger:godBadge,start:'top 78%',toggleActions:'play none none none'}
});
}
if(godCopy){
var copyKids=noReveal(godCopy.children);
if(copyKids.length){
gsap.from(copyKids,{
x:40,opacity:0,duration:.65,stagger:.12,ease:'power2.out',
scrollTrigger:{trigger:godCopy,start:'top 78%',toggleActions:'play none none none'}
});
}
}
});
});
}
/* ═══════ 3. GOLD PARTICLE ATMOSPHERE ═══════ */
function initParticles(){
if(REDUCED||IS_MOBILE) return;
var canvas=document.createElement('canvas');
canvas.className='fcpe-particles-canvas';
canvas.setAttribute('aria-hidden','true');
document.body.appendChild(canvas);
var ctx=canvas.getContext('2d');
var particles=[];
var PARTICLE_COUNT=22;
var dpr=window.devicePixelRatio||1;
function resize(){
canvas.width=window.innerWidth*dpr;
canvas.height=window.innerHeight*dpr;
canvas.style.width=window.innerWidth+'px';
canvas.style.height=window.innerHeight+'px';
ctx.scale(dpr,dpr);
}
resize();
window.addEventListener('resize',resize,{passive:true});
for(var i=0;i<PARTICLE_COUNT;i++){
particles.push({
x:Math.random()*window.innerWidth,
y:Math.random()*window.innerHeight,
size:Math.random()*1.8+0.5,
speedX:(Math.random()-0.5)*0.4,
speedY:(Math.random()-0.5)*0.3-0.15,
opacity:Math.random()*0.5+0.15,
pulse:Math.random()*Math.PI*2,
pulseSpeed:Math.random()*0.008+0.003
});
}
var running=true;
function draw(){
if(!running) return;
ctx.clearRect(0,0,window.innerWidth,window.innerHeight);
particles.forEach(function(p){
p.x+=p.speedX;p.y+=p.speedY;p.pulse+=p.pulseSpeed;
if(p.xwindow.innerWidth+10) p.x=-10;
if(p.ywindow.innerHeight+10) p.y=-10;
var op=p.opacity*(0.5+0.5*Math.sin(p.pulse));
ctx.beginPath();ctx.arc(p.x,p.y,p.size*3,0,Math.PI*2);
ctx.fillStyle=’rgba(212,170,55,’+op*0.15+’)’;ctx.fill();
ctx.beginPath();ctx.arc(p.x,p.y,p.size,0,Math.PI*2);
ctx.fillStyle=’rgba(245,223,162,’+op+’)’;ctx.fill();
});
requestAnimationFrame(draw);
}
document.addEventListener(‘visibilitychange’,function(){
if(document.hidden){running=false}
else{running=true;requestAnimationFrame(draw)}
});
requestAnimationFrame(draw);
}
/* ═══════ 4. BEFORE/AFTER SLIDER (dormant — activates when HTML exists) ═══════ */
function initBASliders(){
document.querySelectorAll(‘.fcpe-ba-slider’).forEach(function(slider){
var afterImg=slider.querySelector(‘.fcpe-ba-after’);
var handle=slider.querySelector(‘.fcpe-ba-handle’);
if(!afterImg||!handle) return;
var isDragging=false;
function setPosition(x){
var rect=slider.getBoundingClientRect();
var pct=Math.max(0,Math.min(1,(x-rect.left)/rect.width));
var percent=pct*100;
afterImg.style.clipPath=’inset(0 0 0 ‘+percent+’%)’;
handle.style.left=percent+’%’;
}
function onStart(e){
isDragging=true;
var x=e.touches?e.touches[0].clientX:e.clientX;
setPosition(x);
}
function onMove(e){
if(!isDragging) return;
e.preventDefault();
var x=e.touches?e.touches[0].clientX:e.clientX;
setPosition(x);
}
function onEnd(){isDragging=false}
slider.addEventListener(‘mousedown’,onStart);
slider.addEventListener(‘touchstart’,onStart,{passive:true});
window.addEventListener(‘mousemove’,onMove);
window.addEventListener(‘touchmove’,onMove,{passive:false});
window.addEventListener(‘mouseup’,onEnd);
window.addEventListener(‘touchend’,onEnd);
});
}
/* ═══════ 5. 3D TILT SERVICE CARDS ═══════ */
function initTiltCards(){
if(IS_TOUCH||IS_MOBILE) return;
document.querySelectorAll(‘.fcpe-card,.trust-card,.testimonial-card’).forEach(function(card){
var parent=card.parentElement;
if(parent) parent.classList.add(‘fcpe-tilt-active’);
var glow=document.createElement(‘div’);
glow.className=’fcpe-card-glow’;
card.style.position=’relative’;
card.appendChild(glow);
card.addEventListener(‘mousemove’,function(e){
var rect=card.getBoundingClientRect();
var x=(e.clientX-rect.left)/rect.width;
var y=(e.clientY-rect.top)/rect.height;
var tiltX=(y-0.5)*-8;
var tiltY=(x-0.5)*8;
card.style.transform=’perspective(800px) rotateX(‘+tiltX+’deg) rotateY(‘+tiltY+’deg) scale(1.02)’;
glow.style.background=’radial-gradient(circle at ‘+x*100+’% ‘+y*100+’%, rgba(212,170,55,.25), transparent 55%)’;
});
card.addEventListener(‘mouseleave’,function(){
card.style.transform=’perspective(800px) rotateX(0) rotateY(0) scale(1)’;
glow.style.background=’none’;
});
});
}
/* ═══════ 6. MAGNETIC CURSOR ═══════ */
function initMagneticCursor(){
if(IS_TOUCH||IS_MOBILE||REDUCED) return;
var cursor=document.createElement(‘div’);
cursor.className=’fcpe-mag-cursor’;
cursor.setAttribute(‘aria-hidden’,’true’);
document.body.appendChild(cursor);
var mouseX=0,mouseY=0,cursorX=0,cursorY=0,isVisible=false;
document.addEventListener(‘mousemove’,function(e){
mouseX=e.clientX;mouseY=e.clientY;
if(!isVisible){isVisible=true;cursor.classList.add(‘is-active’)}
},{passive:true});
document.addEventListener(‘mouseleave’,function(){
isVisible=false;cursor.classList.remove(‘is-active’);
});
function updateCursor(){
cursorX+=(mouseX-cursorX)*0.15;
cursorY+=(mouseY-cursorY)*0.15;
cursor.style.left=cursorX+’px’;
cursor.style.top=cursorY+’px’;
requestAnimationFrame(updateCursor);
}
requestAnimationFrame(updateCursor);
document.querySelectorAll(‘.btn–gold,.btn–ghost,.fcpe-card’).forEach(function(el){
el.addEventListener(‘mouseenter’,function(){
cursor.classList.add(el.classList.contains(‘btn–gold’)?’is-cta’:’is-hover’);
});
el.addEventListener(‘mouseleave’,function(){
cursor.classList.remove(‘is-hover’,’is-cta’);
});
if(el.classList.contains(‘btn–gold’)||el.classList.contains(‘btn–ghost’)){
el.addEventListener(‘mousemove’,function(e){
var rect=el.getBoundingClientRect();
var dx=(e.clientX-(rect.left+rect.width/2))*0.2;
var dy=(e.clientY-(rect.top+rect.height/2))*0.2;
el.style.transform=’translate(‘+dx+’px,’+dy+’px)’;
});
el.addEventListener(‘mouseleave’,function(){el.style.transform=”});
}
});
}
/* ═══════ 7. STICKY GLASSMORPHISM NAV ═══════ */
function initStickyNav(){
var chips=document.querySelectorAll(‘.anchor-chip[data-target]’);
if(!chips.length) return;
var stickyNav=document.createElement(‘div’);
stickyNav.className=’fcpe-sticky-nav’;
stickyNav.setAttribute(‘aria-label’,’Section navigation’);
chips.forEach(function(chip){
var a=document.createElement(‘a’);
a.href=chip.getAttribute(‘href’);
a.textContent=chip.textContent;
a.setAttribute(‘data-target’,chip.getAttribute(‘data-target’)||”);
stickyNav.appendChild(a);
});
document.body.appendChild(stickyNav);
var anchorSection=document.querySelector(‘.anchors’);
if(!anchorSection) return;
var showThreshold=anchorSection.getBoundingClientRect().bottom+window.scrollY+50;
var isShowing=false;
function checkScroll(){
var sy=window.scrollY||window.pageYOffset;
if(sy>showThreshold&&!isShowing){stickyNav.classList.add(‘is-visible’);isShowing=true}
else if(sy<=showThreshold&&isShowing){stickyNav.classList.remove('is-visible');isShowing=false}
}
window.addEventListener('scroll',checkScroll,{passive:true});
checkScroll();
if('IntersectionObserver' in window){
var stickyLinks=stickyNav.querySelectorAll('a[data-target]');
var obs=new IntersectionObserver(function(entries){
entries.forEach(function(entry){
if(entry.isIntersecting){
var id=entry.target.getAttribute('id');
stickyLinks.forEach(function(link){
link.classList.toggle('is-active',link.getAttribute('data-target')===id);
});
}
});
},{threshold:.1,rootMargin:'-80px 0px -55% 0px'});
stickyLinks.forEach(function(link){
var t=link.getAttribute('data-target');
if(t){var sec=document.getElementById(t);if(sec)obs.observe(sec)}
});
}
stickyNav.querySelectorAll('a').forEach(function(a){
a.addEventListener('click',function(e){
var sel=this.getAttribute('href');
if(!sel||sel.length<2||sel.indexOf('#')!==0) return;
var target=document.querySelector(sel);
if(!target) return;
e.preventDefault();
if(window._fcpeLenis){window._fcpeLenis.scrollTo(target,{offset:-80})}
else{target.scrollIntoView({behavior:'smooth',block:'start'})}
});
});
}
/* ═══════ 8. CTA GLOW PULSE ═══════ */
function initCTAGlow(){
if(REDUCED) return;
document.querySelectorAll('.btn–gold').forEach(function(btn){
btn.classList.add('fcpe-glow-pulse');
});
}
/* ═══════ 9. HORIZONTAL SCROLL (for .fcpe-hscroll-wrap) ═══════ */
function initHorizontalScroll(){
if(REDUCED) return;
var wraps=document.querySelectorAll('.fcpe-hscroll-wrap');
if(!wraps.length) return;
waitForLib('gsap',function(){
waitForLib('ScrollTrigger',function(ST){
gsap.registerPlugin(ST);
wraps.forEach(function(wrap){
var track=wrap.querySelector('.fcpe-hscroll-track');
if(!track) return;
var totalWidth=track.scrollWidth-wrap.offsetWidth;
gsap.to(track,{x:-totalWidth,ease:'none',
scrollTrigger:{trigger:wrap,pin:true,scrub:1,
start:'center center',end:'+='+totalWidth,invalidateOnRefresh:true}
});
});
});
});
}
/* ═══════ INIT ALL ═══════ */
ready(function(){
initLenis();
initGSAPReveals();
initParticles();
initBASliders();
initTiltCards();
initMagneticCursor();
initStickyNav();
initCTAGlow();
initHorizontalScroll();
});
})();
/* Hide the WordPress theme page-title H1 on all FCPE pages.
Our content already has its own H1; the theme’s entry-title creates
a duplicate H1 (bad for SEO). Targets GeneratePress/Astra page-header. */
.page-header { display: none !important; }
Manage Consent
To provide the best experiences, we use technologies like cookies to store and/or access device information. Consenting to these technologies will allow us to process data such as browsing behavior or unique IDs on this site. Not consenting or withdrawing consent, may adversely affect certain features and functions.
Functional
Always active
The technical storage or access is strictly necessary for the legitimate purpose of enabling the use of a specific service explicitly requested by the subscriber or user, or for the sole purpose of carrying out the transmission of a communication over an electronic communications network.
Preferences
The technical storage or access is necessary for the legitimate purpose of storing preferences that are not requested by the subscriber or user.
Statistics
The technical storage or access that is used exclusively for statistical purposes.The technical storage or access that is used exclusively for anonymous statistical purposes. Without a subpoena, voluntary compliance on the part of your Internet Service Provider, or additional records from a third party, information stored or retrieved for this purpose alone cannot usually be used to identify you.
Marketing
The technical storage or access is required to create user profiles to send advertising, or to track the user on a website or across several websites for similar marketing purposes.