'use client'; import React, { forwardRef } from 'react'; import { cn, Surface, useEffectiveSurface, surfaceClasses } from '../common'; import { tone, ToneKey, rhythm } from '../tokens'; import { PixelContainer } from '../layout/PixelContainer'; import { PixelTwoColumn } from '../layout/PixelTwoColumn'; import { PixelCluster } from '../layout/PixelCluster'; type HeadlineEffect = 'typewriter' | 'glitch' | 'none'; type HeroVariant = 'centered' | 'split' | 'parallax'; type HeroDensity = 'compact' | 'comfortable'; type HeroMinHeight = 'sm' | 'md' | 'lg' | 'fullscreen'; const minHeightMap: Record = { sm: 'min-h-[400px]', md: 'min-h-[480px]', lg: 'min-h-[640px]', fullscreen: 'min-h-screen', }; const headlineSize = { compact: 'text-3xl sm:text-4xl lg:text-5xl', comfortable: 'text-4xl sm:text-5xl lg:text-6xl', } as const; const eyebrowSize = 'text-xs sm:text-sm'; const sublineSize = { compact: 'text-base sm:text-lg', comfortable: 'text-lg sm:text-xl', } as const; const densityRhythm = { compact: { eyebrowToHeadline: 'mt-3', headlineToSubline: 'mt-2', sublineToCtas: 'mt-5', ctasToInstall: 'mt-6', installToMeta: 'mt-4', }, comfortable: { eyebrowToHeadline: rhythm.eyebrowToHeadline, headlineToSubline: rhythm.headlineToSubline, sublineToCtas: rhythm.sublineToCtas, ctasToInstall: rhythm.ctasToMeta, installToMeta: rhythm.metaToInstall, }, } as const; export interface PixelHeroSectionProps extends React.HTMLAttributes { variant?: HeroVariant; eyebrow?: string; headline: string; headlineEffect?: HeadlineEffect; subline?: string; primaryCta?: React.ReactNode; secondaryCta?: React.ReactNode; install?: React.ReactNode; meta?: React.ReactNode; media?: React.ReactNode; tone?: ToneKey; density?: HeroDensity; minHeight?: HeroMinHeight; surface?: Surface; } export const PixelHeroSection = forwardRef( function PixelHeroSection( { variant = 'centered', eyebrow, headline, headlineEffect: _headlineEffect = 'none', subline, primaryCta, secondaryCta, install, meta, media, tone: toneProp = 'neutral', density = 'comfortable', minHeight = 'md', surface: surfaceProp, className, ...rest }, ref, ) { const surface = useEffectiveSurface(surfaceProp); const s = surfaceClasses(surface); const sp = densityRhythm[density]; const t = tone[toneProp]; const isCentered = variant === 'centered'; const isSplit = variant === 'split' && media; const isParallax = variant === 'parallax'; const align = isCentered || isParallax ? 'center' : 'start'; const eyebrowNode = eyebrow ? ( {eyebrow} ) : null; const headlineNode = (

{headline}

); const sublineNode = subline ? (

{subline}

) : null; const ctaNode = (primaryCta || secondaryCta) ? ( {primaryCta} {secondaryCta} ) : null; const installNode = install ? (
{install}
) : null; const metaNode = meta ? (
{meta}
) : null; const textColumn = (
{eyebrowNode} {headlineNode} {sublineNode} {ctaNode} {installNode} {metaNode}
); const body = isSplit ? ( {media}} surface={surface} /> ) : isParallax ? (
{media && (
{media}
)} {textColumn}
) : ( <> {textColumn} {media && (
{media}
)} ); return (
} className={cn( 'relative w-full flex flex-col justify-center', minHeightMap[minHeight], s.transition, className, )} {...rest} > {body}
); }, ); PixelHeroSection.displayName = 'PixelHeroSection';