|
|
|
|
@@ -3,7 +3,6 @@
|
|
|
|
|
import React from 'react';
|
|
|
|
|
import Image from 'next/image';
|
|
|
|
|
import { usePathname } from 'next/navigation';
|
|
|
|
|
import { m } from 'framer-motion';
|
|
|
|
|
import { Badge, Container, Heading } from '@/components/ui';
|
|
|
|
|
import { Button } from '@/components/ui/Button';
|
|
|
|
|
|
|
|
|
|
@@ -17,25 +16,7 @@ export interface HeroSectionProps {
|
|
|
|
|
ctaHref?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const containerVariants = {
|
|
|
|
|
hidden: { opacity: 0 },
|
|
|
|
|
visible: {
|
|
|
|
|
opacity: 1,
|
|
|
|
|
transition: {
|
|
|
|
|
staggerChildren: 0.15,
|
|
|
|
|
delayChildren: 0.1,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const itemVariants = {
|
|
|
|
|
hidden: { opacity: 0, y: 30 },
|
|
|
|
|
visible: {
|
|
|
|
|
opacity: 1,
|
|
|
|
|
y: 0,
|
|
|
|
|
transition: { duration: 0.8, ease: [0.16, 1, 0.3, 1] as const }
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
// CSS animations replace Framer Motion for better LCP
|
|
|
|
|
|
|
|
|
|
export const HeroSection: React.FC<HeroSectionProps> = (props) => {
|
|
|
|
|
const { title, badge, subtitle, backgroundImage, alignment, ctaLabel, ctaHref } = props;
|
|
|
|
|
@@ -47,12 +28,9 @@ export const HeroSection: React.FC<HeroSectionProps> = (props) => {
|
|
|
|
|
className={`relative min-h-[35vh] md:min-h-[50vh] flex items-center pt-28 pb-10 md:pt-36 md:pb-24 overflow-hidden bg-neutral-dark ${alignment === 'center' ? 'justify-center text-center' : ''}`}
|
|
|
|
|
>
|
|
|
|
|
{bgSrc && (
|
|
|
|
|
<m.div
|
|
|
|
|
<div
|
|
|
|
|
key={`hero-bg-${pathname}`}
|
|
|
|
|
className="absolute inset-0 z-0"
|
|
|
|
|
initial={{ scale: 1.05, opacity: 1 }}
|
|
|
|
|
animate={{ scale: 1, opacity: 1 }}
|
|
|
|
|
transition={{ duration: 1.5, ease: "easeOut" }}
|
|
|
|
|
className="absolute inset-0 z-0 animate-hero-zoom-out"
|
|
|
|
|
>
|
|
|
|
|
<Image
|
|
|
|
|
src={bgSrc}
|
|
|
|
|
@@ -74,37 +52,34 @@ export const HeroSection: React.FC<HeroSectionProps> = (props) => {
|
|
|
|
|
|
|
|
|
|
{/* Top Fade for Header Navigation Readability */}
|
|
|
|
|
<div className="absolute top-0 left-0 w-full h-48 bg-gradient-to-b from-black/70 to-transparent z-[3] pointer-events-none" />
|
|
|
|
|
</m.div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
<Container className={`relative z-10 ${alignment === 'center' ? 'max-w-5xl' : ''}`}>
|
|
|
|
|
<m.div
|
|
|
|
|
<div
|
|
|
|
|
key={`hero-content-${pathname}`}
|
|
|
|
|
className={`max-w-4xl ${alignment === 'center' ? 'mx-auto' : ''}`}
|
|
|
|
|
variants={containerVariants}
|
|
|
|
|
initial="hidden"
|
|
|
|
|
animate="visible"
|
|
|
|
|
>
|
|
|
|
|
{badge && (
|
|
|
|
|
<m.div variants={itemVariants}>
|
|
|
|
|
<div className="animate-hero-fade-in-up" style={{ animationDelay: '0.1s', opacity: 0, animationFillMode: 'forwards' }}>
|
|
|
|
|
<Badge variant="saturated" className="mb-4 md:mb-8 shadow-lg">
|
|
|
|
|
{badge}
|
|
|
|
|
</Badge>
|
|
|
|
|
</m.div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
<m.div variants={itemVariants}>
|
|
|
|
|
<Heading level={1} size="section" variant="white" align={alignment || 'left'} className="mb-4 md:mb-8">
|
|
|
|
|
{title}
|
|
|
|
|
</Heading>
|
|
|
|
|
</m.div>
|
|
|
|
|
<div className="animate-hero-fade-in-up" style={{ animationDelay: badge ? '0.25s' : '0.1s', opacity: 0, animationFillMode: 'forwards' }}>
|
|
|
|
|
<Heading level={1} size="section" variant="white" align={alignment || 'left'} className="mb-4 md:mb-8">
|
|
|
|
|
{title}
|
|
|
|
|
</Heading>
|
|
|
|
|
</div>
|
|
|
|
|
{subtitle && (
|
|
|
|
|
<m.div variants={itemVariants}>
|
|
|
|
|
<div className="animate-hero-fade-in-up" style={{ animationDelay: badge ? '0.4s' : '0.25s', opacity: 0, animationFillMode: 'forwards' }}>
|
|
|
|
|
<p className={`text-lg md:text-2xl text-white/70 font-medium leading-relaxed max-w-2xl ${alignment === 'center' ? 'mx-auto' : ''}`}>
|
|
|
|
|
{subtitle}
|
|
|
|
|
</p>
|
|
|
|
|
</m.div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
{ctaLabel && ctaHref && (
|
|
|
|
|
<m.div variants={itemVariants} className={`mt-8 ${alignment === 'center' ? 'flex flex-wrap justify-center gap-4' : 'flex flex-wrap gap-4'}`}>
|
|
|
|
|
<div className={`mt-8 animate-hero-fade-in-up ${alignment === 'center' ? 'flex flex-wrap justify-center gap-4' : 'flex flex-wrap gap-4'}`} style={{ animationDelay: badge ? '0.55s' : '0.4s', opacity: 0, animationFillMode: 'forwards' }}>
|
|
|
|
|
<Button
|
|
|
|
|
href={ctaHref}
|
|
|
|
|
variant="accent"
|
|
|
|
|
@@ -115,9 +90,9 @@ export const HeroSection: React.FC<HeroSectionProps> = (props) => {
|
|
|
|
|
→
|
|
|
|
|
</span>
|
|
|
|
|
</Button>
|
|
|
|
|
</m.div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</m.div>
|
|
|
|
|
</div>
|
|
|
|
|
</Container>
|
|
|
|
|
</section>
|
|
|
|
|
);
|
|
|
|
|
|