105 lines
2.4 KiB
TypeScript
105 lines
2.4 KiB
TypeScript
"use client"
|
|
|
|
import type { ElementType, HTMLAttributes, ReactNode } from "react"
|
|
import { cn } from "@/lib/utils"
|
|
|
|
type PublicPageHeaderProps = {
|
|
eyebrow?: string
|
|
title: string
|
|
description?: string
|
|
align?: "left" | "center"
|
|
className?: string
|
|
children?: ReactNode
|
|
}
|
|
|
|
export function PublicPageHeader({
|
|
eyebrow,
|
|
title,
|
|
description,
|
|
align = "left",
|
|
className,
|
|
children,
|
|
}: PublicPageHeaderProps) {
|
|
const isCentered = align === "center"
|
|
|
|
return (
|
|
<header className={cn("space-y-4", isCentered && "mx-auto max-w-3xl text-center", className)}>
|
|
{eyebrow ? (
|
|
<p className="text-xs font-semibold uppercase tracking-[0.22em] text-primary/80">{eyebrow}</p>
|
|
) : null}
|
|
<div className="space-y-3">
|
|
<h1 className="text-4xl font-bold tracking-tight text-balance text-foreground md:text-5xl">{title}</h1>
|
|
{description ? (
|
|
<p
|
|
className={cn(
|
|
"text-base leading-relaxed text-muted-foreground md:text-lg",
|
|
isCentered ? "mx-auto max-w-3xl" : "max-w-3xl",
|
|
)}
|
|
>
|
|
{description}
|
|
</p>
|
|
) : null}
|
|
</div>
|
|
{children}
|
|
</header>
|
|
)
|
|
}
|
|
|
|
export function PublicSurface({
|
|
as: Component = "div",
|
|
className,
|
|
children,
|
|
...props
|
|
}: HTMLAttributes<HTMLDivElement> & { as?: ElementType }) {
|
|
return (
|
|
<Component
|
|
className={cn(
|
|
"rounded-[2rem] border border-border/70 bg-white p-5 shadow-[0_20px_48px_rgba(15,23,42,0.08)] md:p-7",
|
|
className,
|
|
)}
|
|
{...props}
|
|
>
|
|
{children}
|
|
</Component>
|
|
)
|
|
}
|
|
|
|
export function PublicInset({
|
|
className,
|
|
children,
|
|
...props
|
|
}: HTMLAttributes<HTMLDivElement>) {
|
|
return (
|
|
<div
|
|
className={cn(
|
|
"rounded-[1.5rem] border border-border/60 bg-white p-4 shadow-sm",
|
|
className,
|
|
)}
|
|
{...props}
|
|
>
|
|
{children}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
type PublicSectionHeaderProps = {
|
|
eyebrow: string
|
|
title: string
|
|
description: string
|
|
className?: string
|
|
}
|
|
|
|
export function PublicSectionHeader({
|
|
eyebrow,
|
|
title,
|
|
description,
|
|
className,
|
|
}: PublicSectionHeaderProps) {
|
|
return (
|
|
<div className={cn("space-y-1", className)}>
|
|
<p className="text-xs font-semibold uppercase tracking-[0.18em] text-primary/80">{eyebrow}</p>
|
|
<h2 className="text-lg font-semibold text-foreground">{title}</h2>
|
|
<p className="text-sm leading-relaxed text-muted-foreground">{description}</p>
|
|
</div>
|
|
)
|
|
}
|