diff --git a/src/app/page.tsx b/src/app/page.tsx index ee20e5e..771cb88 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -2,8 +2,6 @@ import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider"; import { useState, useEffect } from "react"; -import gsap from "gsap"; -import ScrollTrigger from "gsap/dist/ScrollTrigger"; import NavbarStyleApple from "@/components/navbar/NavbarStyleApple/NavbarStyleApple"; import HeroCentered from "@/components/sections/hero/HeroCentered"; import MetricSplitMediaAbout from "@/components/sections/about/MetricSplitMediaAbout"; @@ -14,127 +12,168 @@ import FaqBase from "@/components/sections/faq/FaqBase"; import ContactSplit from "@/components/sections/contact/ContactSplit"; import FooterLogoEmphasis from "@/components/sections/footer/FooterLogoEmphasis"; import TimelineProcessFlow from "@/components/cardStack/layouts/timelines/TimelineProcessFlow"; -import { Moon, Sun, Sparkles } from "lucide-react"; +import { Moon, Sun } from "lucide-react"; +import gsap from "gsap"; +import ScrollTrigger from "gsap/ScrollTrigger"; gsap.registerPlugin(ScrollTrigger); const lightTheme = { - "--background": "#ffffff", "--card": "#f9f9f9", "--foreground": "#000000", "--primary-cta": "#000000", "--secondary-cta": "#f9f9f9", "--accent": "#e2e2e2", "--background-accent": "#c4c4c4", "--primary-cta-text": "#ffffff", "--secondary-cta-text": "#000000"}; + "--background": "#ffffff", "--card": "#f9f9f9", "--foreground": "#000000", "--primary-cta": "#000000", "--secondary-cta": "#f9f9f9", "--accent": "#e2e2e2", "--background-accent": "#c4c4c4", "--primary-cta-text": "#ffffff", "--secondary-cta-text": "#000000" +}; const darkTheme = { - "--background": "#0a0a0a", "--card": "#1a1a1a", "--foreground": "#ffffff", "--primary-cta": "#ffffff", "--secondary-cta": "#1a1a1a", "--accent": "#737373", "--background-accent": "#737373", "--primary-cta-text": "#0a0a0a", "--secondary-cta-text": "#ffffff"}; + "--background": "#0a0a0a", "--card": "#1a1a1a", "--foreground": "#ffffff", "--primary-cta": "#ffffff", "--secondary-cta": "#1a1a1a", "--accent": "#737373", "--background-accent": "#737373", "--primary-cta-text": "#0a0a0a", "--secondary-cta-text": "#ffffff" +}; export default function LandingPage() { const [isDarkMode, setIsDarkMode] = useState(false); - const [mounted, setMounted] = useState(false); const theme = isDarkMode ? darkTheme : lightTheme; - useEffect(() => { - setMounted(true); - }, []); + const toggleTheme = () => { + setIsDarkMode(!isDarkMode); + Object.entries(theme).forEach(([key, value]) => { + document.documentElement.style.setProperty(key, value); + }); + }; useEffect(() => { - if (!mounted) return; - - // Apply theme colors + // Apply initial theme Object.entries(theme).forEach(([key, value]) => { document.documentElement.style.setProperty(key, value); }); - // Enhanced GSAP animations - gsap.utils.toArray("[data-section]").forEach((section: any) => { - // Fade in sections on scroll - gsap.fromTo( - section, - { opacity: 0, y: 50 }, - { - opacity: 1, - y: 0, - duration: 1, - scrollTrigger: { - trigger: section, - start: "top 80%", toggleActions: "play none none reverse", once: false, + // Initialize GSAP animations + const initGsapAnimations = () => { + // Stagger animation for section elements + const sections = document.querySelectorAll('[data-section]'); + sections.forEach((section) => { + const elements = section.querySelectorAll('h1, h2, h3, p, button, [data-animate]'); + elements.forEach((el, index) => { + gsap.set(el, { opacity: 0, y: 20 }); + ScrollTrigger.create({ + trigger: el, + onEnter: () => { + gsap.to(el, { + opacity: 1, + y: 0, + duration: 0.6, + delay: index * 0.05, + ease: "power3.out" + }); + }, + once: true + }); + }); + }); + + // Hero section parallax + const hero = document.querySelector('#hero'); + if (hero) { + const heroContent = hero.querySelector('[data-animate]'); + if (heroContent) { + gsap.to(heroContent, { + scrollTrigger: { + trigger: hero, + start: "top center", end: "bottom center", scrub: 1 + }, + y: -50, + opacity: 0.8 + }); + } + } + + // Card scale animation on scroll + const cards = document.querySelectorAll('[class*="card"], [class*="Card"]'); + cards.forEach((card) => { + gsap.set(card, { scale: 0.95, opacity: 0 }); + ScrollTrigger.create({ + trigger: card, + onEnter: () => { + gsap.to(card, { + scale: 1, + opacity: 1, + duration: 0.8, + ease: "back.out" + }); }, - } - ); - }); - - // Animate text elements with stagger - gsap.utils.toArray("h1, h2, h3").forEach((element: any) => { - gsap.fromTo( - element, - { opacity: 0, y: 20 }, - { - opacity: 1, - y: 0, - duration: 0.8, - scrollTrigger: { - trigger: element, - start: "top 85%", toggleActions: "play none none reverse"}, - } - ); - }); - - // Animate cards with parallax effect - gsap.utils.toArray("[class*='card']").forEach((card: any) => { - gsap.fromTo( - card, - { opacity: 0, scale: 0.95, y: 30 }, - { - opacity: 1, - scale: 1, - y: 0, - duration: 0.6, - scrollTrigger: { - trigger: card, - start: "top 75%", toggleActions: "play none none reverse"}, - } - ); - }); - - // Hover effects on buttons - gsap.utils.toArray("button[type='submit'], a[href*='#']").forEach((btn: any) => { - btn.addEventListener("mouseenter", () => { - gsap.to(btn, { scale: 1.05, duration: 0.3 }); + once: true + }); }); - btn.addEventListener("mouseleave", () => { - gsap.to(btn, { scale: 1, duration: 0.3 }); - }); - }); - // Parallax scroll for hero section - const heroSection = document.getElementById("hero"); - if (heroSection) { - gsap.to(heroSection, { - backgroundPosition: "50% 50%", ease: "none", scrollTrigger: { - trigger: heroSection, - start: "top top", end: "bottom top", scrub: 1, - markers: false, - }, + // Floating animation for images + const images = document.querySelectorAll('img[data-animate], [class*="image"] img'); + images.forEach((img) => { + gsap.to(img, { + y: -10, + duration: 3, + repeat: -1, + yoyo: true, + ease: "sine.inOut" + }); }); + + // Text reveal animation + const textElements = document.querySelectorAll('h1, h2, h3'); + textElements.forEach((text) => { + ScrollTrigger.create({ + trigger: text, + onEnter: () => { + gsap.to(text, { + backgroundPosition: "200% center", duration: 1.5, + ease: "power2.out" + }); + }, + once: true + }); + }); + + // Button hover glow effect + const buttons = document.querySelectorAll('button'); + buttons.forEach((btn) => { + btn.addEventListener('mouseenter', () => { + gsap.to(btn, { + boxShadow: "0 0 20px rgba(0, 0, 0, 0.3)", duration: 0.3 + }); + }); + btn.addEventListener('mouseleave', () => { + gsap.to(btn, { + boxShadow: "0 0 0px rgba(0, 0, 0, 0)", duration: 0.3 + }); + }); + }); + + // Scroll-triggered counter animations + const counters = document.querySelectorAll('[data-count]'); + counters.forEach((counter) => { + ScrollTrigger.create({ + trigger: counter, + onEnter: () => { + const target = parseInt(counter.getAttribute('data-count')) || 0; + gsap.to(counter, { + textContent: target, + duration: 2, + snap: { textContent: 1 }, + ease: "power2.out" + }); + }, + once: true + }); + }); + }; + + // Wait for DOM to be fully loaded + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', initGsapAnimations); + } else { + initGsapAnimations(); } - // Floating animation for decorative elements - gsap.utils.toArray("[data-float]").forEach((element: any) => { - gsap.to(element, { - y: -20, - duration: 3, - repeat: -1, - yoyo: true, - ease: "sine.inOut"}); - }); - return () => { - ScrollTrigger.getAll().forEach((trigger) => trigger.kill()); + ScrollTrigger.getAll().forEach(trigger => trigger.kill()); }; - }, [mounted, isDarkMode]); - - const toggleTheme = () => { - setIsDarkMode(!isDarkMode); - }; - - if (!mounted) return null; + }, [isDarkMode]); return (