/**
* Yogurt Culture - Website Interactivity
* Theme: Mad Milk by Yogurt Culture
*/
document.addEventListener('DOMContentLoaded', () => {
initHeader();
initMobileMenu();
initScrollReveal();
initSmoothScroll();
initBackToTop();
initActiveNav();
initParallax();
});
/* ========================================
HEADER - Scroll Effect
======================================== */
function initHeader() {
const header = document.getElementById('header');
let lastScroll = 0;
window.addEventListener('scroll', () => {
const currentScroll = window.scrollY;
if (currentScroll > 60) {
header.classList.add('scrolled');
} else {
header.classList.remove('scrolled');
}
lastScroll = currentScroll;
}, { passive: true });
}
/* ========================================
MOBILE MENU
======================================== */
function initMobileMenu() {
const hamburger = document.getElementById('hamburger');
const mobileMenu = document.getElementById('mobile-menu');
const mobileLinks = mobileMenu.querySelectorAll('a');
hamburger.addEventListener('click', () => {
hamburger.classList.toggle('active');
mobileMenu.classList.toggle('active');
document.body.style.overflow = mobileMenu.classList.contains('active') ? 'hidden' : '';
});
// Close menu when a link is clicked
mobileLinks.forEach(link => {
link.addEventListener('click', () => {
hamburger.classList.remove('active');
mobileMenu.classList.remove('active');
document.body.style.overflow = '';
});
});
}
/* ========================================
SCROLL REVEAL ANIMATION
======================================== */
function initScrollReveal() {
const reveals = document.querySelectorAll('.scroll-reveal');
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
observer.unobserve(entry.target); // Only animate once
}
});
}, {
threshold: 0.1,
rootMargin: '0px 0px -50px 0px'
});
reveals.forEach(el => observer.observe(el));
}
/* ========================================
SMOOTH SCROLL
======================================== */
function initSmoothScroll() {
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
const target = this.getAttribute('href');
if (target === '#') return;
e.preventDefault();
const element = document.querySelector(target);
if (element) {
const headerOffset = 90;
const elementPosition = element.getBoundingClientRect().top + window.scrollY;
const offsetPosition = elementPosition - headerOffset;
window.scrollTo({
top: offsetPosition,
behavior: 'smooth'
});
}
});
});
}
/* ========================================
BACK TO TOP BUTTON
======================================== */
function initBackToTop() {
const backToTop = document.getElementById('back-to-top');
window.addEventListener('scroll', () => {
if (window.scrollY > 500) {
backToTop.classList.add('visible');
} else {
backToTop.classList.remove('visible');
}
}, { passive: true });
backToTop.addEventListener('click', () => {
window.scrollTo({ top: 0, behavior: 'smooth' });
});
}
/* ========================================
ACTIVE NAV HIGHLIGHT
======================================== */
function initActiveNav() {
const sections = document.querySelectorAll('section[id]');
const navLinks = document.querySelectorAll('.nav-links a');
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const id = entry.target.getAttribute('id');
navLinks.forEach(link => {
link.classList.remove('active');
if (link.getAttribute('href') === `#${id}`) {
link.classList.add('active');
}
});
}
});
}, {
threshold: 0.3,
rootMargin: '-100px 0px -50% 0px'
});
sections.forEach(section => observer.observe(section));
}
/* ========================================
SUBTLE PARALLAX ON HERO
======================================== */
function initParallax() {
const heroImage = document.querySelector('.hero-image');
const heroSplash1 = document.querySelector('.hero-splash--1');
const heroSplash2 = document.querySelector('.hero-splash--2');
const heroSplash3 = document.querySelector('.hero-splash--3');
window.addEventListener('scroll', () => {
const scrolled = window.scrollY;
if (scrolled < window.innerHeight) {
const factor = scrolled * 0.3;
if (heroImage) {
heroImage.style.transform = `translateY(${factor * 0.15}px)`;
}
if (heroSplash1) heroSplash1.style.transform = `translate(${factor * 0.1}px, ${factor * 0.05}px)`;
if (heroSplash2) heroSplash2.style.transform = `translate(${-factor * 0.08}px, ${-factor * 0.1}px)`;
if (heroSplash3) heroSplash3.style.transform = `translate(${factor * 0.05}px, ${factor * 0.12}px)`;
}
}, { passive: true });
}
/* ========================================
NEWSLETTER FORM HANDLER
======================================== */
function handleNewsletter() {
const emailInput = document.getElementById('newsletter-email');
const email = emailInput.value;
if (email) {
// Create a nice toast notification
showToast('Welcome to the Yogurt Culture community! 🎉');
emailInput.value = '';
}
}
/* ========================================
TOAST NOTIFICATION
======================================== */
function showToast(message) {
// Remove existing toast
const existingToast = document.querySelector('.toast-notification');
if (existingToast) existingToast.remove();
const toast = document.createElement('div');
toast.className = 'toast-notification';
toast.innerHTML = `
✓
${message}
`;
// Add animation keyframes if not exists
if (!document.querySelector('#toast-styles')) {
const style = document.createElement('style');
style.id = 'toast-styles';
style.textContent = `
@keyframes toastSlideIn {
from { transform: translateX(-50%) translateY(100px); opacity: 0; }
to { transform: translateX(-50%) translateY(0); opacity: 1; }
}
@keyframes toastSlideOut {
from { transform: translateX(-50%) translateY(0); opacity: 1; }
to { transform: translateX(-50%) translateY(100px); opacity: 0; }
}
`;
document.head.appendChild(style);
}
document.body.appendChild(toast);
// Auto-remove after 4 seconds
setTimeout(() => {
const inner = toast.querySelector('div');
if (inner) {
inner.style.animation = 'toastSlideOut 0.3s ease-in forwards';
}
setTimeout(() => toast.remove(), 350);
}, 4000);
}
/* ========================================
MENU CARD HOVER INTERACTIONS
======================================== */
document.querySelectorAll('.menu-card-btn').forEach(btn => {
btn.addEventListener('click', (e) => {
e.stopPropagation();
showToast('Item added to your order! 🥄');
});
});
/* ========================================
COUNTER ANIMATION
======================================== */
function animateCounters() {
const counters = document.querySelectorAll('.hero-stat-number');
counters.forEach(counter => {
const target = counter.textContent;
const hasPlus = target.includes('+');
const hasPercent = target.includes('%');
const numericValue = parseInt(target.replace(/[^0-9]/g, ''));
if (isNaN(numericValue)) return;
let current = 0;
const duration = 2000;
const increment = numericValue / (duration / 16);
const timer = setInterval(() => {
current += increment;
if (current >= numericValue) {
current = numericValue;
clearInterval(timer);
}
let displayValue = Math.floor(current);
if (numericValue >= 1000) {
displayValue = Math.floor(current / 1000) + 'K';
}
counter.textContent = displayValue + (hasPlus ? '+' : '') + (hasPercent ? '%' : '');
}, 16);
});
}
// Trigger counter animation when hero is visible
const heroObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
animateCounters();
heroObserver.unobserve(entry.target);
}
});
}, { threshold: 0.5 });
const heroSection = document.querySelector('.hero-stats');
if (heroSection) {
heroObserver.observe(heroSection);
}