generated from Nicholai/astro-template
292 lines
17 KiB
TypeScript
292 lines
17 KiB
TypeScript
|
|
import React, { useEffect, useRef, useState } from 'react';
|
|
import { ArrowRight, Star, Users, Venus, Heart, PenTool, MoveRight } from 'lucide-react';
|
|
import { Reveal } from './Reveal';
|
|
|
|
interface HomeProps {
|
|
t: any;
|
|
}
|
|
|
|
const ScribbleStar = ({ className }: { className?: string }) => (
|
|
<svg viewBox="0 0 100 100" className={className} fill="currentColor">
|
|
<path d="M50 0L61 35L98 35L68 57L79 91L50 70L21 91L32 57L2 35L39 35L50 0Z" />
|
|
</svg>
|
|
);
|
|
|
|
export const Home: React.FC<HomeProps> = ({ t }) => {
|
|
// Refs for Scroll Animations
|
|
const heroRef = useRef<HTMLDivElement>(null);
|
|
const heroTextTopRef = useRef<HTMLDivElement>(null);
|
|
const heroTextBottomRef = useRef<HTMLDivElement>(null);
|
|
const heroImageRef = useRef<HTMLDivElement>(null);
|
|
|
|
const horizontalSectionRef = useRef<HTMLDivElement>(null);
|
|
const horizontalTrackRef = useRef<HTMLDivElement>(null);
|
|
|
|
const newsRef = useRef<HTMLDivElement>(null);
|
|
|
|
// State for horizontal scroll calculation
|
|
const [scrollProgress, setScrollProgress] = useState(0);
|
|
|
|
useEffect(() => {
|
|
const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
|
|
if (mediaQuery.matches) return;
|
|
|
|
let rafId: number;
|
|
|
|
const handleScroll = () => {
|
|
const scrollY = window.scrollY;
|
|
const viewportHeight = window.innerHeight;
|
|
|
|
rafId = requestAnimationFrame(() => {
|
|
// --- HERO ANIMATION ---
|
|
if (heroRef.current && heroTextTopRef.current && heroTextBottomRef.current && heroImageRef.current) {
|
|
const heroProgress = Math.min(scrollY / viewportHeight, 1);
|
|
|
|
heroTextTopRef.current.style.transform = `translateX(-${heroProgress * 30}vw) rotate(-2deg)`;
|
|
heroTextBottomRef.current.style.transform = `translateX(${heroProgress * 30}vw) rotate(2deg)`;
|
|
|
|
heroImageRef.current.style.transform = `translateY(${heroProgress * 50}px) rotate(${heroProgress * 5}deg)`;
|
|
}
|
|
|
|
// --- HORIZONTAL SCROLL CALCULATION ---
|
|
if (horizontalSectionRef.current && horizontalTrackRef.current) {
|
|
const sectionTop = horizontalSectionRef.current.offsetTop;
|
|
const sectionHeight = horizontalSectionRef.current.offsetHeight;
|
|
const scrollDistanceFromTop = scrollY - sectionTop;
|
|
|
|
let progress = scrollDistanceFromTop / (sectionHeight - viewportHeight);
|
|
progress = Math.max(0, Math.min(progress, 1));
|
|
|
|
setScrollProgress(progress);
|
|
}
|
|
});
|
|
};
|
|
|
|
window.addEventListener('scroll', handleScroll, { passive: true });
|
|
return () => {
|
|
window.removeEventListener('scroll', handleScroll);
|
|
cancelAnimationFrame(rafId);
|
|
};
|
|
}, []);
|
|
|
|
// Update Horizontal Transform
|
|
useEffect(() => {
|
|
if (horizontalTrackRef.current) {
|
|
const trackWidth = horizontalTrackRef.current.scrollWidth;
|
|
const viewportWidth = window.innerWidth;
|
|
const maxTranslate = trackWidth - viewportWidth;
|
|
|
|
if (maxTranslate > 0) {
|
|
horizontalTrackRef.current.style.transform = `translateX(-${scrollProgress * maxTranslate}px)`;
|
|
}
|
|
}
|
|
}, [scrollProgress]);
|
|
|
|
const newsImages = [
|
|
{ image: "https://images.unsplash.com/photo-1596700813955-442436d423e0?auto=format&fit=crop&q=80&w=600", height: "h-96" },
|
|
{ image: "https://images.unsplash.com/photo-1572691242698-b7f3001844b2?auto=format&fit=crop&q=80&w=600", height: "h-[32rem]" }
|
|
];
|
|
|
|
const currentNewsItems = t.news.items.map((item: any, index: number) => ({
|
|
...item,
|
|
...newsImages[index]
|
|
}));
|
|
|
|
return (
|
|
<>
|
|
{/* --- HERO SECTION --- */}
|
|
<div ref={heroRef} className="relative h-screen min-h-[800px] flex items-center justify-center bg-brand-lilac overflow-hidden">
|
|
|
|
<div className="absolute top-32 left-[10%] w-12 h-12 text-brand-deep animate-float">
|
|
<ScribbleStar className="w-full h-full" />
|
|
</div>
|
|
<div className="absolute bottom-32 right-[10%] w-16 h-16 text-brand-purple animate-float" style={{ animationDelay: '1s' }}>
|
|
<ScribbleStar className="w-full h-full" />
|
|
</div>
|
|
<div className="absolute top-1/4 right-20 w-8 h-8 text-brand-red animate-pulse">
|
|
<Star className="w-full h-full fill-current" />
|
|
</div>
|
|
|
|
<div ref={heroImageRef} className="relative z-10 will-change-transform">
|
|
<div className="w-[85vw] md:w-[50vw] h-[55vh] md:h-[65vh] border-[4px] border-brand-deep bg-brand-deep relative shadow-[12px_12px_0px_#6B2C91] rounded-[2rem] overflow-hidden group rotate-1 hover:rotate-0 transition-all duration-500">
|
|
<div className="absolute inset-0 bg-[url('https://images.unsplash.com/photo-1555848962-6e79363ec58f?auto=format&fit=crop&q=80&w=1600')] bg-cover bg-center transition-all duration-700"></div>
|
|
<div className="absolute inset-0 opacity-20 bg-[url('https://www.transparenttextures.com/patterns/dust.png')] pointer-events-none"></div>
|
|
<div className="absolute inset-0 bg-brand-purple/20 mix-blend-multiply pointer-events-none"></div>
|
|
|
|
<div className="absolute bottom-6 right-6 transform rotate-[-3deg]">
|
|
<div className="bg-brand-red text-white px-6 py-2 font-marker text-xl tracking-widest border-2 border-brand-deep shadow-[4px_4px_0px_#2D0F41] rounded-full">
|
|
{t.hero.est}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="absolute inset-0 z-20 pointer-events-none flex flex-col items-center justify-center">
|
|
<div className="w-full flex justify-center pb-20 md:pb-32">
|
|
<div ref={heroTextTopRef} className="origin-center transform -rotate-2">
|
|
<h1 className="text-5xl md:text-8xl lg:text-9xl font-display font-bold text-white bg-brand-deep px-8 py-4 border-4 border-white shadow-[8px_8px_0px_rgba(0,0,0,0.1)] rounded-xl inline-block tracking-tighter whitespace-nowrap leading-none">
|
|
{t.hero.women}
|
|
</h1>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="w-full flex justify-center pt-20 md:pt-32 absolute top-1/2 mt-16 md:mt-0">
|
|
<div ref={heroTextBottomRef} className="origin-center transform rotate-1">
|
|
<h1 className="text-5xl md:text-8xl lg:text-9xl font-display font-bold text-brand-deep bg-brand-lilac px-8 py-4 border-4 border-brand-deep shadow-[12px_12px_0px_#ED1C24] rounded-xl inline-block tracking-tighter whitespace-nowrap leading-none">
|
|
{t.hero.future}
|
|
</h1>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="absolute bottom-8 flex flex-col items-center gap-2 text-brand-deep z-30 animate-bounce">
|
|
<span className="font-display font-bold text-lg tracking-widest uppercase">{t.hero.scroll}</span>
|
|
<ArrowRight className="w-6 h-6 rotate-90" strokeWidth={3} />
|
|
</div>
|
|
</div>
|
|
|
|
{/* --- MARQUEE BANNER --- */}
|
|
<div className="bg-brand-deep py-6 overflow-hidden -rotate-1 scale-105 border-y-4 border-white z-30 relative shadow-xl">
|
|
<div className="flex animate-marquee w-fit">
|
|
{[...Array(2)].map((_, groupIndex) => (
|
|
<div key={groupIndex} className="flex gap-8 whitespace-nowrap px-4">
|
|
{[...Array(8)].map((_, i) => (
|
|
<span key={i} className="text-4xl font-display font-bold text-white uppercase tracking-widest flex items-center gap-8">
|
|
{t.marquee} <Heart className="fill-brand-red text-brand-red w-8 h-8" />
|
|
</span>
|
|
))}
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
{/* --- HORIZONTAL SCROLL SECTION --- */}
|
|
<div ref={horizontalSectionRef} className="relative h-[400vh] z-20">
|
|
<div className="sticky top-0 h-screen overflow-hidden flex items-center bg-brand-surface bg-[url('https://www.transparenttextures.com/patterns/cubes.png')] bg-fixed">
|
|
<div ref={horizontalTrackRef} className="flex gap-10 md:gap-20 px-10 md:px-20 items-center h-full will-change-transform">
|
|
<div className="flex-shrink-0 w-[80vw] md:w-[40vw] flex flex-col justify-center pl-12">
|
|
<div className="bg-brand-lilac p-8 border-4 border-brand-deep shadow-[12px_12px_0px_#2D0F41] rounded-[2rem] inline-block transform -rotate-2 max-w-full">
|
|
<h2 className="text-[clamp(3rem,8vw,6rem)] font-display font-bold text-brand-deep uppercase leading-[0.9] tracking-tighter break-words">
|
|
{t.values.title}
|
|
</h2>
|
|
</div>
|
|
<ArrowRight className="w-16 h-16 md:w-24 md:h-24 text-brand-purple mt-12 animate-pulse ml-8" />
|
|
</div>
|
|
|
|
{t.values.cards.map((card: any, idx: number) => (
|
|
<div key={idx} className="flex-shrink-0 w-[85vw] md:w-[45vw] h-[60vh] md:h-[70vh] bg-white border-4 border-brand-deep p-8 md:p-12 flex flex-col justify-between shadow-[20px_20px_0px_#6B2C91] relative rounded-3xl overflow-hidden group">
|
|
<div className={`absolute -top-10 -right-10 w-40 h-40 rounded-full opacity-20 ${idx === 1 ? 'bg-brand-red' : 'bg-brand-purple'}`}></div>
|
|
<div className="flex justify-between items-start">
|
|
{idx === 0 && <Venus className="w-20 h-20 text-brand-purple" strokeWidth={1.5} />}
|
|
{idx === 1 && <Users className="w-20 h-20 text-brand-red" strokeWidth={1.5} />}
|
|
{idx === 2 && <Star className="w-20 h-20 text-brand-deep" strokeWidth={1.5} />}
|
|
<span className="font-marker text-4xl text-brand-deep/20">#{card.id}</span>
|
|
</div>
|
|
<div>
|
|
<div className="bg-brand-lilac/50 inline-block px-4 py-2 rounded-lg mb-6 border border-brand-deep/10">
|
|
<h3 className="text-5xl md:text-7xl font-display font-bold text-brand-deep uppercase tracking-tight">{card.title}</h3>
|
|
</div>
|
|
<p className="text-xl md:text-2xl text-brand-deep font-medium leading-relaxed max-w-md font-sans">
|
|
{card.desc}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* --- NEWS SECTION --- */}
|
|
<div ref={newsRef} className="bg-brand-lilac py-32 relative z-20 overflow-hidden">
|
|
<div className="absolute top-0 left-0 w-full h-full opacity-10 pointer-events-none bg-[radial-gradient(#2D0F41_1px,transparent_1px)] [background-size:20px_20px]"></div>
|
|
|
|
<div className="max-w-7xl mx-auto px-6 lg:px-12 relative">
|
|
<Reveal className="mb-20 flex items-end justify-between border-b-4 border-brand-deep pb-6">
|
|
<div className="bg-brand-deep text-white px-8 py-4 transform -skew-x-12 inline-block shadow-[8px_8px_0px_#6B2C91]">
|
|
<h2 className="text-5xl md:text-8xl font-display font-bold uppercase tracking-tighter transform skew-x-12">
|
|
{t.news.header}
|
|
</h2>
|
|
</div>
|
|
<div className="hidden md:block">
|
|
<div className="bg-brand-red text-white font-marker text-3xl px-4 py-2 rotate-3 rounded-lg shadow-md border-2 border-brand-deep">
|
|
{t.news.year}
|
|
</div>
|
|
</div>
|
|
</Reveal>
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-12 lg:gap-24 relative z-10">
|
|
<div className="flex flex-col gap-16">
|
|
{currentNewsItems.map((item: any, idx: number) => (
|
|
<div key={idx} className="group cursor-pointer">
|
|
<div className={`${item.height} w-full overflow-hidden relative border-4 border-brand-deep bg-brand-deep rounded-2xl shadow-[12px_12px_0px_rgba(45,15,65,0.2)] group-hover:shadow-[16px_16px_0px_#6B2C91] group-hover:-translate-y-1 transition-all duration-300`}>
|
|
<img src={item.image} className="w-full h-full object-cover grayscale mix-blend-luminosity opacity-80 group-hover:grayscale-0 group-hover:opacity-100 transition-all duration-500" />
|
|
<div className="absolute top-4 left-4 bg-brand-purple text-white px-4 py-1 font-bold uppercase tracking-widest text-sm border-2 border-white rounded-full shadow-lg">
|
|
{item.category}
|
|
</div>
|
|
</div>
|
|
<div className="mt-6 pl-2">
|
|
<div className="flex items-center gap-3 text-brand-purple font-bold text-sm mb-2 font-mono">
|
|
<span>{item.date}</span>
|
|
<div className="h-px w-8 bg-brand-purple"></div>
|
|
</div>
|
|
<h3 className="text-3xl lg:text-4xl font-display font-bold text-brand-deep group-hover:text-brand-purple transition-colors leading-tight uppercase">
|
|
{item.title}
|
|
</h3>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
<div className="flex flex-col gap-16 pt-0 md:pt-32">
|
|
<div className="bg-[#FFF9C4] p-8 md:p-12 flex flex-col items-center justify-center text-center relative shadow-[0_10px_40px_rgba(0,0,0,0.1)] transform rotate-2 border border-gray-200">
|
|
<div className="absolute -top-6 left-1/2 -translate-x-1/2 w-32 h-10 bg-white/40 backdrop-blur-sm border-l border-r border-white/60 transform rotate-1 shadow-sm"></div>
|
|
<PenTool className="w-16 h-16 text-brand-deep mb-6" strokeWidth={1.5} />
|
|
<h3 className="text-5xl font-display font-bold text-brand-deep uppercase leading-[0.9] mb-4 tracking-tighter">
|
|
{t.news.sticky.title_1}<br/>{t.news.sticky.title_2}
|
|
</h3>
|
|
<p className="text-brand-deep font-medium mb-8 font-marker text-lg opacity-80">{t.news.sticky.desc}</p>
|
|
<button className="bg-brand-deep text-white px-8 py-3 font-bold uppercase tracking-widest hover:bg-brand-purple transition-colors rounded-lg shadow-lg">
|
|
{t.news.sticky.btn}
|
|
</button>
|
|
</div>
|
|
|
|
<div className="group cursor-pointer mt-8">
|
|
<div className="h-80 w-full overflow-hidden relative border-4 border-brand-deep rounded-2xl bg-white shadow-[12px_12px_0px_#9D4EDD] group-hover:-translate-y-1 transition-all">
|
|
<img src="https://images.unsplash.com/photo-1532012197267-da84d127e765?auto=format&fit=crop&q=80&w=600" className="w-full h-full object-cover opacity-90 group-hover:opacity-100 transition-all duration-500" />
|
|
<div className="absolute top-4 left-4 bg-white text-brand-deep px-4 py-2 font-bold uppercase tracking-widest text-xs border-2 border-brand-deep rounded-lg">
|
|
{t.news.secondary.category}
|
|
</div>
|
|
</div>
|
|
<h3 className="mt-6 text-3xl font-display font-bold text-brand-deep group-hover:text-brand-purple transition-colors leading-tight uppercase pl-2">
|
|
{t.news.secondary.title}
|
|
</h3>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* --- NEWSLETTER SECTION --- */}
|
|
<div className="relative z-30 bg-brand-purple py-24 border-y-4 border-brand-deep bg-[url('https://www.transparenttextures.com/patterns/diagmonds-light.png')]">
|
|
<div className="max-w-7xl mx-auto px-6 lg:px-12 flex flex-col md:flex-row items-center justify-between gap-12">
|
|
<div className="md:w-1/2 text-white">
|
|
<h2 className="text-6xl md:text-[7rem] font-display font-bold uppercase leading-[0.8] mb-6 tracking-tighter drop-shadow-lg">
|
|
{t.newsletter.title_1}<br/><span className="text-brand-lilac">{t.newsletter.title_2}</span>
|
|
</h2>
|
|
<p className="text-xl font-medium opacity-90 max-w-md">{t.newsletter.desc}</p>
|
|
</div>
|
|
<div className="md:w-1/2 w-full">
|
|
<div className="flex border-4 border-brand-deep shadow-[16px_16px_0px_#2D0F41] bg-white rounded-xl overflow-hidden transform rotate-1 hover:rotate-0 transition-transform">
|
|
<input type="email" placeholder={t.newsletter.placeholder} className="flex-1 px-8 py-6 bg-transparent font-bold text-brand-deep placeholder:text-gray-400 focus:outline-none text-lg uppercase" />
|
|
<button className="px-10 bg-brand-deep text-white font-bold text-2xl hover:bg-brand-red transition-colors border-l-4 border-brand-deep">
|
|
<MoveRight className="w-8 h-8" />
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
};
|