This commit is contained in:
2026-03-29 10:26:38 -05:00
parent 05d4f6e78b
commit b1c99893a6
1628 changed files with 67782 additions and 60143 deletions

View File

@@ -1,88 +1,88 @@
/* ========================================
GreenLens Landing Page Interactions
======================================== */
document.addEventListener('DOMContentLoaded', () => {
// --- Navbar scroll effect ---
const navbar = document.querySelector('.navbar');
const handleScroll = () => {
navbar.classList.toggle('scrolled', window.scrollY > 60);
};
window.addEventListener('scroll', handleScroll, { passive: true });
handleScroll();
// --- Mobile hamburger ---
const hamburger = document.querySelector('.nav-hamburger');
const navLinks = document.querySelector('.nav-links');
if (hamburger) {
hamburger.addEventListener('click', () => {
navLinks.classList.toggle('active');
});
// close on link click
navLinks.querySelectorAll('a').forEach(link => {
link.addEventListener('click', () => {
navLinks.classList.remove('active');
});
});
}
// --- Scroll reveal ---
const revealElements = document.querySelectorAll('.reveal');
const revealObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('active');
revealObserver.unobserve(entry.target);
}
});
}, {
threshold: 0.15,
rootMargin: '0px 0px -50px 0px'
});
revealElements.forEach(el => revealObserver.observe(el));
// --- Counter animation ---
const counters = document.querySelectorAll('[data-count]');
const counterObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const el = entry.target;
const target = parseFloat(el.dataset.count);
const suffix = el.dataset.suffix || '';
const isDecimal = target % 1 !== 0;
const duration = 1500;
const start = performance.now();
const step = (now) => {
const progress = Math.min((now - start) / duration, 1);
const eased = 1 - Math.pow(1 - progress, 3); // ease-out cubic
const current = eased * target;
el.textContent = (isDecimal ? current.toFixed(1) : Math.floor(current)) + suffix;
if (progress < 1) requestAnimationFrame(step);
};
requestAnimationFrame(step);
counterObserver.unobserve(el);
}
});
}, { threshold: 0.5 });
counters.forEach(el => counterObserver.observe(el));
// --- Smooth scroll for anchor links ---
document.querySelectorAll('a[href^="#"]').forEach(link => {
link.addEventListener('click', (e) => {
const target = document.querySelector(link.getAttribute('href'));
if (target) {
e.preventDefault();
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
});
});
});
/* ========================================
GreenLens Landing Page Interactions
======================================== */
document.addEventListener('DOMContentLoaded', () => {
// --- Navbar scroll effect ---
const navbar = document.querySelector('.navbar');
const handleScroll = () => {
navbar.classList.toggle('scrolled', window.scrollY > 60);
};
window.addEventListener('scroll', handleScroll, { passive: true });
handleScroll();
// --- Mobile hamburger ---
const hamburger = document.querySelector('.nav-hamburger');
const navLinks = document.querySelector('.nav-links');
if (hamburger) {
hamburger.addEventListener('click', () => {
navLinks.classList.toggle('active');
});
// close on link click
navLinks.querySelectorAll('a').forEach(link => {
link.addEventListener('click', () => {
navLinks.classList.remove('active');
});
});
}
// --- Scroll reveal ---
const revealElements = document.querySelectorAll('.reveal');
const revealObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('active');
revealObserver.unobserve(entry.target);
}
});
}, {
threshold: 0.15,
rootMargin: '0px 0px -50px 0px'
});
revealElements.forEach(el => revealObserver.observe(el));
// --- Counter animation ---
const counters = document.querySelectorAll('[data-count]');
const counterObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const el = entry.target;
const target = parseFloat(el.dataset.count);
const suffix = el.dataset.suffix || '';
const isDecimal = target % 1 !== 0;
const duration = 1500;
const start = performance.now();
const step = (now) => {
const progress = Math.min((now - start) / duration, 1);
const eased = 1 - Math.pow(1 - progress, 3); // ease-out cubic
const current = eased * target;
el.textContent = (isDecimal ? current.toFixed(1) : Math.floor(current)) + suffix;
if (progress < 1) requestAnimationFrame(step);
};
requestAnimationFrame(step);
counterObserver.unobserve(el);
}
});
}, { threshold: 0.5 });
counters.forEach(el => counterObserver.observe(el));
// --- Smooth scroll for anchor links ---
document.querySelectorAll('a[href^="#"]').forEach(link => {
link.addEventListener('click', (e) => {
const target = document.querySelector(link.getAttribute('href'));
if (target) {
e.preventDefault();
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
});
});
});