108 lines
4.9 KiB
TypeScript
108 lines
4.9 KiB
TypeScript
'use client';
|
|
|
|
import { useRef, ReactNode } from 'react';
|
|
import Container from '@/components/ui/Container';
|
|
import Heading from '@/components/ui/Heading';
|
|
import { useParallax } from '../../hooks/useScrollProgress';
|
|
|
|
interface AlternatingSectionProps {
|
|
heading: string;
|
|
description: string | ReactNode;
|
|
mockup: ReactNode;
|
|
layout: 'text-left' | 'text-right';
|
|
backgroundImage?: string;
|
|
backgroundVideo?: string;
|
|
}
|
|
|
|
export default function AlternatingSection({
|
|
heading,
|
|
description,
|
|
mockup,
|
|
layout,
|
|
backgroundImage,
|
|
backgroundVideo
|
|
}: AlternatingSectionProps) {
|
|
const sectionRef = useRef<HTMLElement>(null);
|
|
|
|
const bgParallax = useParallax(sectionRef, 0.2);
|
|
|
|
return (
|
|
<section ref={sectionRef} className="relative overflow-hidden bg-deep-graphite px-[calc(1rem+var(--sal))] pr-[calc(1rem+var(--sar))] py-20 sm:py-24 md:py-32 md:px-[calc(2rem+var(--sal))] md:pr-[calc(2rem+var(--sar))] lg:px-8">
|
|
{backgroundVideo && (
|
|
<>
|
|
<video
|
|
autoPlay
|
|
loop
|
|
muted
|
|
playsInline
|
|
className="absolute inset-0 w-full h-full object-cover opacity-20 md:opacity-30"
|
|
style={{
|
|
maskImage: 'radial-gradient(ellipse at center, black 0%, rgba(0,0,0,0.8) 40%, transparent 70%)',
|
|
WebkitMaskImage: 'radial-gradient(ellipse at center, black 0%, rgba(0,0,0,0.8) 40%, transparent 70%)',
|
|
}}
|
|
>
|
|
<source src={backgroundVideo} type="video/mp4" />
|
|
</video>
|
|
{/* Racing red accent for sections with background videos */}
|
|
<div className="absolute top-0 left-0 right-0 h-px bg-gradient-to-r from-transparent via-red-500/30 to-transparent" />
|
|
</>
|
|
)}
|
|
{backgroundImage && !backgroundVideo && (
|
|
<>
|
|
<div
|
|
className="absolute inset-0 bg-cover bg-center"
|
|
style={{
|
|
backgroundImage: `url(${backgroundImage})`,
|
|
maskImage: 'radial-gradient(ellipse at center, rgba(0,0,0,0.18) 0%, rgba(0,0,0,0.1) 40%, transparent 70%)',
|
|
WebkitMaskImage: 'radial-gradient(ellipse at center, rgba(0,0,0,0.18) 0%, rgba(0,0,0,0.1) 40%, transparent 70%)',
|
|
transform: `translateY(${bgParallax * 0.3}px)`
|
|
}}
|
|
/>
|
|
{/* Racing red accent for sections with background images */}
|
|
<div className="absolute top-0 left-0 right-0 h-px bg-gradient-to-r from-transparent via-red-500/30 to-transparent" />
|
|
</>
|
|
)}
|
|
|
|
{/* Carbon fiber texture on sections without images or videos */}
|
|
{!backgroundImage && !backgroundVideo && (
|
|
<div className="absolute inset-0 carbon-fiber opacity-30" />
|
|
)}
|
|
|
|
{/* Checkered pattern accent */}
|
|
<div className="absolute inset-0 checkered-pattern opacity-10" />
|
|
|
|
<Container size="lg" className="relative z-10">
|
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8 md:gap-12 lg:gap-16 items-center">
|
|
{/* Text Content - Always first on mobile, respects layout on desktop */}
|
|
<div
|
|
className={`space-y-4 md:space-y-6 lg:space-y-8 ${layout === 'text-right' ? 'lg:order-2' : ''}`}
|
|
style={{
|
|
opacity: 1,
|
|
transform: 'translateX(0)'
|
|
}}
|
|
>
|
|
<Heading level={2} className="text-xl md:text-2xl lg:text-3xl xl:text-4xl bg-gradient-to-r from-red-600 via-white to-blue-600 bg-clip-text text-transparent font-medium drop-shadow-[0_0_15px_rgba(220,0,0,0.4)] static-racing-gradient" style={{ WebkitTextStroke: '0.5px rgba(220,0,0,0.2)' }}>
|
|
{heading}
|
|
</Heading>
|
|
<div className="text-sm md:text-base lg:text-lg text-slate-400 font-light leading-relaxed md:leading-loose space-y-3 md:space-y-5">
|
|
{description}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Mockup - Always second on mobile, respects layout on desktop */}
|
|
<div
|
|
className={`relative group ${layout === 'text-right' ? 'lg:order-1' : ''}`}
|
|
style={{
|
|
opacity: 1,
|
|
transform: 'translateX(0) scale(1)'
|
|
}}
|
|
>
|
|
<div className={`w-full min-h-[240px] md:min-h-[380px] lg:min-h-[440px] transition-transform duration-speed group-hover:scale-[1.02] ${layout === 'text-left' ? 'md:[mask-image:linear-gradient(to_right,white_50%,rgba(255,255,255,0.8)_70%,rgba(255,255,255,0.4)_85%,transparent_100%)] md:[-webkit-mask-image:linear-gradient(to_right,white_50%,rgba(255,255,255,0.8)_70%,rgba(255,255,255,0.4)_85%,transparent_100%)]' : 'md:[mask-image:linear-gradient(to_left,white_50%,rgba(255,255,255,0.8)_70%,rgba(255,255,255,0.4)_85%,transparent_100%)] md:[-webkit-mask-image:linear-gradient(to_left,white_50%,rgba(255,255,255,0.8)_70%,rgba(255,255,255,0.4)_85%,transparent_100%)]'}`}>
|
|
{mockup}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</Container>
|
|
</section>
|
|
);
|
|
} |