130 lines
4.3 KiB
TypeScript
130 lines
4.3 KiB
TypeScript
interface BreadcrumbItem {
|
|
label: string;
|
|
href?: string;
|
|
}
|
|
|
|
interface PageTitleBannerProps {
|
|
/** Page title — "About us", "Services", "Contacts" */
|
|
title: string;
|
|
/** Breadcrumb trail */
|
|
breadcrumbs: BreadcrumbItem[];
|
|
}
|
|
|
|
/**
|
|
* PageTitleBanner — shared inner-page hero banner.
|
|
*
|
|
* Used by: About, Services, Contacts pages.
|
|
*
|
|
* Structure (from reference):
|
|
* - Full-width rounded card with gradient background
|
|
* - Centered "/ Title /" text
|
|
* - Breadcrumbs bottom-left
|
|
* - Decorative "tenext" outline text right side
|
|
* - Top-left and bottom-right rounded corner decorations
|
|
*/
|
|
export function PageTitleBanner({ title, breadcrumbs }: PageTitleBannerProps) {
|
|
return (
|
|
<div className="relative mx-5 overflow-hidden rounded-[25px] bg-tenext-dark">
|
|
{/* Background image */}
|
|
<div
|
|
className="absolute inset-0 bg-cover bg-center opacity-80"
|
|
style={{
|
|
backgroundImage: "url(/images/tenext/page-top-bg-min.png)",
|
|
}}
|
|
/>
|
|
|
|
{/* Gradient overlay */}
|
|
<div className="absolute inset-0 bg-gradient-to-b from-transparent via-transparent to-tenext-dark/60" />
|
|
|
|
{/* Top-left corner decoration */}
|
|
<div className="absolute left-0 top-0 h-20 w-20">
|
|
<div className="absolute left-0 top-0 h-full w-full rounded-br-[25px] bg-white" />
|
|
<div className="absolute left-0 top-0 h-full w-full rounded-tl-[25px] bg-tenext-dark">
|
|
<div
|
|
className="absolute inset-0 bg-cover bg-center opacity-80"
|
|
style={{
|
|
backgroundImage: "url(/images/tenext/page-top-bg-min.png)",
|
|
}}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Bottom-right corner decoration */}
|
|
<div className="absolute bottom-0 right-0 h-20 w-20">
|
|
<div className="absolute bottom-0 right-0 h-full w-full rounded-tl-[25px] bg-white" />
|
|
<div className="absolute bottom-0 right-0 h-full w-full rounded-br-[25px] bg-tenext-dark">
|
|
<div
|
|
className="absolute inset-0 bg-cover bg-center opacity-80"
|
|
style={{
|
|
backgroundImage: "url(/images/tenext/page-top-bg-min.png)",
|
|
}}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Content */}
|
|
<div className="relative z-10 flex min-h-[320px] flex-col items-center justify-center px-8 py-16 md:min-h-[400px] lg:min-h-[460px]">
|
|
{/* Title */}
|
|
<h1
|
|
className="text-center text-white"
|
|
style={{
|
|
fontFamily: "var(--font-sora)",
|
|
fontSize: "clamp(36px, 5vw, 72px)",
|
|
fontWeight: 700,
|
|
lineHeight: 1.1,
|
|
}}
|
|
>
|
|
<span className="mr-3 text-tenext-text-muted">/</span>
|
|
{title}
|
|
<span className="ml-3 text-tenext-text-muted">/</span>
|
|
</h1>
|
|
|
|
{/* Breadcrumbs */}
|
|
<nav
|
|
className="absolute bottom-8 left-8 md:bottom-10 md:left-12"
|
|
aria-label="Breadcrumb"
|
|
>
|
|
<ol className="flex items-center gap-2 text-sm text-white/70">
|
|
{breadcrumbs.map((crumb, index) => (
|
|
<li key={crumb.label} className="flex items-center gap-2">
|
|
{index > 0 && (
|
|
<span className="mx-1 inline-block h-1 w-1 rounded-full bg-tenext-teal" />
|
|
)}
|
|
{index < breadcrumbs.length - 1 && crumb.href ? (
|
|
<a
|
|
href={crumb.href}
|
|
className="transition-colors hover:text-tenext-teal"
|
|
>
|
|
{crumb.label}
|
|
</a>
|
|
) : (
|
|
<span className="text-white">{crumb.label}</span>
|
|
)}
|
|
</li>
|
|
))}
|
|
</ol>
|
|
</nav>
|
|
|
|
{/* Decorative vertical "tenext" text */}
|
|
<div
|
|
className="absolute bottom-8 right-8 hidden select-none lg:block"
|
|
style={{
|
|
writingMode: "vertical-rl",
|
|
textOrientation: "mixed",
|
|
}}
|
|
>
|
|
<span
|
|
className="font-sora text-[clamp(48px,5vw,72px)] font-bold leading-none tracking-tight"
|
|
style={{
|
|
WebkitTextStroke: "1px rgba(255,255,255,0.1)",
|
|
WebkitTextFillColor: "transparent",
|
|
}}
|
|
>
|
|
tenext
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|