// ── LOADER window.addEventListener('load', () => { setTimeout(() => { document.getElementById('loader').classList.add('hidden'); }, 2000); }); // ── CUSTOM CURSOR const cursor = document.getElementById('cursor'); const follower = document.getElementById('cursor-follower'); let mouseX = 0, mouseY = 0; let followerX = 0, followerY = 0; document.addEventListener('mousemove', (e) => { mouseX = e.clientX; mouseY = e.clientY; cursor.style.transform = `translate(${mouseX - 4}px, ${mouseY - 4}px)`; }); function animateFollower() { followerX += (mouseX - followerX) * 0.12; followerY += (mouseY - followerY) * 0.12; follower.style.transform = `translate(${followerX - 18}px, ${followerY - 18}px)`; requestAnimationFrame(animateFollower); } animateFollower(); document.querySelectorAll('a, button, .portfolio-item, .filter-btn').forEach(el => { el.addEventListener('mouseenter', () => { cursor.style.transform += ' scale(2)'; follower.style.width = '60px'; follower.style.height = '60px'; follower.style.opacity = '0.5'; }); el.addEventListener('mouseleave', () => { follower.style.width = '36px'; follower.style.height = '36px'; follower.style.opacity = '1'; }); }); // ── NAV SCROLL const nav = document.getElementById('nav'); window.addEventListener('scroll', () => { nav.classList.toggle('scrolled', window.scrollY > 60); }); // ── MOBILE MENU const hamburger = document.getElementById('hamburger'); let mobileMenu = document.createElement('div'); mobileMenu.className = 'mobile-menu'; const menuLinks = ['#about|O Nas', '#portfolio|Portfolio', '#process|Proces', '#testimonials|Opinie', '#contact|Kontakt']; menuLinks.forEach(item => { const [href, label] = item.split('|'); const a = document.createElement('a'); a.href = href; a.textContent = label; a.addEventListener('click', () => mobileMenu.classList.remove('open')); mobileMenu.appendChild(a); }); document.body.appendChild(mobileMenu); hamburger.addEventListener('click', () => { mobileMenu.classList.toggle('open'); }); // ── COUNTER ANIMATION function animateCounter(el) { const target = parseInt(el.getAttribute('data-count')); const duration = 2000; const start = performance.now(); function update(time) { const elapsed = time - start; const progress = Math.min(elapsed / duration, 1); const eased = 1 - Math.pow(1 - progress, 3); el.textContent = Math.round(eased * target); if (progress < 1) requestAnimationFrame(update); } requestAnimationFrame(update); } // ── INTERSECTION OBSERVER const observerOptions = { threshold: 0.15, rootMargin: '0px 0px -60px 0px' }; const revealObserver = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('visible'); revealObserver.unobserve(entry.target); } }); }, observerOptions); document.querySelectorAll('.about-grid, .portfolio-item, .process-step, .testimonial-card, .award-item, .contact-grid, .fp-content, .section-header').forEach((el, i) => { el.classList.add('reveal'); revealObserver.observe(el); }); const counterObserver = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { animateCounter(entry.target); counterObserver.unobserve(entry.target); } }); }, { threshold: 0.5 }); document.querySelectorAll('.stat-num').forEach(el => counterObserver.observe(el)); // ── PORTFOLIO FILTER const filterBtns = document.querySelectorAll('.filter-btn'); const portfolioItems = document.querySelectorAll('.portfolio-item'); filterBtns.forEach(btn => { btn.addEventListener('click', () => { filterBtns.forEach(b => b.classList.remove('active')); btn.classList.add('active'); const filter = btn.getAttribute('data-filter'); portfolioItems.forEach(item => { const cat = item.getAttribute('data-category'); if (filter === 'all' || cat === filter) { item.style.opacity = '1'; item.style.transform = 'scale(1)'; item.style.display = ''; } else { item.style.opacity = '0'; item.style.transform = 'scale(0.95)'; setTimeout(() => { if (filter !== 'all' && cat !== filter) item.style.display = 'none'; }, 300); } }); }); }); // ── SMOOTH SCROLL document.querySelectorAll('a[href^="#"]').forEach(a => { a.addEventListener('click', (e) => { const target = document.querySelector(a.getAttribute('href')); if (target) { e.preventDefault(); target.scrollIntoView({ behavior: 'smooth', block: 'start' }); } }); }); // ── PARALLAX HERO window.addEventListener('scroll', () => { const scrollY = window.scrollY; const heroImg = document.querySelector('.hero-img'); const orbs = document.querySelectorAll('.hero-orb'); if (heroImg) heroImg.style.transform = `scale(1.05) translateY(${scrollY * 0.12}px)`; orbs.forEach((orb, i) => { orb.style.transform = `translateY(${scrollY * (0.05 + i * 0.03)}px)`; }); }); // ── FORM SUBMIT document.getElementById('contactForm')?.addEventListener('submit', (e) => { e.preventDefault(); const btn = e.target.querySelector('.btn-primary'); const original = btn.innerHTML; btn.innerHTML = 'Wysłano! Odezwiemy się wkrótce ✓'; btn.style.background = '#2D7A3A'; setTimeout(() => { btn.innerHTML = original; btn.style.background = ''; e.target.reset(); }, 4000); }); // ── STAGGER CHILDREN document.querySelectorAll('.process-steps .process-step').forEach((el, i) => { el.style.transitionDelay = `${i * 0.12}s`; }); document.querySelectorAll('.testimonials-grid .testimonial-card').forEach((el, i) => { el.style.transitionDelay = `${i * 0.1}s`; }); document.querySelectorAll('.portfolio-item').forEach((el, i) => { el.style.transitionDelay = `${i * 0.08}s`; });