Files
gridpilot.gg/apps/website/components/landing/AlternatingSection.tsx
2025-12-02 21:17:22 +01:00

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 { useScrollProgress, 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>
);
}