59 lines
2.1 KiB
TypeScript
59 lines
2.1 KiB
TypeScript
'use client';
|
|
|
|
interface HeaderProps {
|
|
title: string;
|
|
subtitle?: string;
|
|
imageUrl?: string;
|
|
actions?: React.ReactNode;
|
|
maxWidth?: 'max-w-5xl' | 'max-w-7xl';
|
|
}
|
|
|
|
export default function Header({ title, subtitle, imageUrl, actions, maxWidth = 'max-w-7xl' }: HeaderProps) {
|
|
return (
|
|
<>
|
|
<div className="relative overflow-hidden">
|
|
{/* Distant atmospheric haze */}
|
|
<div
|
|
aria-hidden
|
|
className="pointer-events-none absolute -top-16 -right-12 w-80 h-80 rounded-full opacity-50 blur-3xl"
|
|
style={{ background: 'radial-gradient(circle, var(--halo-1), transparent 65%)' }}
|
|
/>
|
|
<div
|
|
aria-hidden
|
|
className="pointer-events-none absolute -bottom-16 -left-10 w-72 h-72 rounded-full opacity-50 blur-3xl"
|
|
style={{ background: 'radial-gradient(circle, var(--halo-3), transparent 60%)' }}
|
|
/>
|
|
|
|
<div className={`${maxWidth} mx-auto relative py-14 px-4 sm:py-20 sm:px-6 lg:px-8`}>
|
|
<div className="flex flex-col md:flex-row items-center md:items-start gap-8">
|
|
{imageUrl && (
|
|
<div className="md:w-56 flex-shrink-0">
|
|
<img
|
|
src={imageUrl}
|
|
alt={title}
|
|
className="w-56 h-56 object-cover rounded-3xl shadow-lifted ring-1 ring-[color:var(--border)]"
|
|
/>
|
|
</div>
|
|
)}
|
|
<div className={imageUrl ? 'flex-1 text-left' : 'flex-1 text-center'}>
|
|
<h1 className="text-5xl sm:text-6xl lg:text-7xl font-bold text-[color:var(--ink)] mb-4 leading-tight">
|
|
{title}
|
|
</h1>
|
|
{subtitle && (
|
|
<p className={`text-xl sm:text-2xl text-[color:var(--ink-soft)] mb-6 ${imageUrl ? '' : 'max-w-3xl mx-auto'}`}>
|
|
{subtitle}
|
|
</p>
|
|
)}
|
|
{actions && (
|
|
<div className={`flex flex-col sm:flex-row items-center gap-3 ${imageUrl ? 'justify-start' : 'justify-center'}`}>
|
|
{actions}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|