HeroSection.tsx78 lines · main
| 1 | 'use client' |
| 2 | |
| 3 | import { Button, cn } from 'ui' |
| 4 | |
| 5 | import type { GoHeroSection } from '../schemas' |
| 6 | import MediaBlock from './MediaBlock' |
| 7 | |
| 8 | export default function HeroSection({ |
| 9 | section, |
| 10 | compact, |
| 11 | }: { |
| 12 | section: GoHeroSection |
| 13 | compact?: boolean |
| 14 | }) { |
| 15 | const hasMedia = !!(section.image || section.video || section.youtubeUrl) |
| 16 | |
| 17 | return ( |
| 18 | <header |
| 19 | className={cn( |
| 20 | 'flex flex-col border-b border-muted', |
| 21 | 'bg-[radial-gradient(circle_at_50%_240%,hsl(var(--brand-300)),transparent_70%)]', |
| 22 | 'md:bg-[radial-gradient(circle_at_50%_280%,hsl(var(--brand-300)),transparent_70%)]', |
| 23 | compact && 'items-center justify-center min-h-[35vh] lg:min-h-[50vh]' |
| 24 | )} |
| 25 | > |
| 26 | <div |
| 27 | className={cn( |
| 28 | 'max-w-7xl mx-auto px-8', |
| 29 | hasMedia |
| 30 | ? 'grid grid-cols-1 py-16 md:grid-cols-2 gap-10 md:gap-24 items-center md:py-32' |
| 31 | : 'flex flex-col items-center py-16 gap-4 sm:gap-8 text-center text-balance py-24' |
| 32 | )} |
| 33 | > |
| 34 | <div className={cn(hasMedia ? 'flex flex-col gap-4 sm:gap-6' : 'contents')}> |
| 35 | {section.subtitle && ( |
| 36 | <p className="text-sm text-brand-link uppercase font-mono tracking-wider"> |
| 37 | {section.subtitle} |
| 38 | </p> |
| 39 | )} |
| 40 | <h1 className="text-3xl md:text-4xl leading-tight tracking-tight text-balance"> |
| 41 | {section.title} |
| 42 | </h1> |
| 43 | {section.description && ( |
| 44 | <p |
| 45 | className={cn( |
| 46 | 'text-lg leading-relaxed text-foreground-light text-pretty', |
| 47 | !hasMedia && 'md:text-xl md:text-foreground max-w-2xl' |
| 48 | )} |
| 49 | > |
| 50 | {section.description} |
| 51 | </p> |
| 52 | )} |
| 53 | {section.ctas && section.ctas.length > 0 && ( |
| 54 | <div className="flex flex-wrap items-center gap-4 pt-2"> |
| 55 | {section.ctas.map((cta) => ( |
| 56 | <Button |
| 57 | key={cta.href} |
| 58 | asChild |
| 59 | type={cta.variant === 'secondary' ? 'default' : 'primary'} |
| 60 | size="medium" |
| 61 | > |
| 62 | <a href={cta.href}>{cta.label}</a> |
| 63 | </Button> |
| 64 | ))} |
| 65 | </div> |
| 66 | )} |
| 67 | </div> |
| 68 | |
| 69 | <MediaBlock |
| 70 | image={section.image} |
| 71 | video={section.video} |
| 72 | youtubeUrl={section.youtubeUrl} |
| 73 | className="p-1 bg-surface-300/30 rounded-2xl" |
| 74 | /> |
| 75 | </div> |
| 76 | </header> |
| 77 | ) |
| 78 | } |