Extract generic UI components

Reduces duplication across marketing pages by converting sections into
reusable components like CtaSection and HeaderBg. Consolidates styling
patterns to improve maintainability and consistency of the user interface.
This commit is contained in:
2026-02-28 04:55:25 +08:00
parent b199f89998
commit 173905ecd3
14 changed files with 902 additions and 1413 deletions

View File

@@ -4,21 +4,73 @@
* Pixel-perfect implementation based on Webflow design
*/
interface Props {
title?: string
subtitle?: string
title?: string;
subtitle?: string;
backgroundImage?: {
url?: string;
alt?: string;
};
}
const {
title = '恩群大本營',
subtitle = 'Team members of Enchun',
} = Astro.props
title = "恩群大本營",
subtitle = "Team members of Enchun",
backgroundImage,
} = Astro.props;
// Determine if we have a background image
const hasBackgroundImage = backgroundImage?.url;
const bgImageUrl = backgroundImage?.url || "";
---
<header class="bg-[var(--color-dark-blue)] pt-[120px] pb-20 px-5 lg:pt-20 lg:pb-15 md:pt-15 md:pb-10 md:px-4 text-center">
<div class="max-w-[1200px] mx-auto">
<div class="flex flex-col items-center">
<h1 class="text-white font-['Noto_Sans_TC'] font-bold text-[3.39em] lg:text-[2.45em] md:text-[7vw] leading-tight mb-4">{title}</h1>
<p class="text-[var(--color-gray-100)] font-['Quicksand','Noto_Sans_TC'] font-normal text-[1.5em] lg:text-[1.15em] md:text-[3.4vw] leading-tight">{subtitle}</p>
</div>
<section
class:list={[
// Base styles - relative positioning for overlay
"relative",
"flex",
"items-center",
"justify-center",
"overflow-hidden",
"text-center",
"px-5",
// Background color fallback
!hasBackgroundImage && "bg-(--color-dark-blue)",
// Background image styles
hasBackgroundImage && "bg-size-[120vw] bg-center bg-no-repeat",
// Pull up to counteract layout's pt-20 padding (80px)
"-mt-20",
// Full viewport height
"min-h-dvh",
"z-0",
]}
style={hasBackgroundImage
? `background-image: url('${bgImageUrl}')`
: undefined}
>
{/* Background image overlay for text readability */}
{
hasBackgroundImage && (
<div
class="absolute inset-0 bg-linear-to-b from-black/80 to-transparent z-1"
aria-hidden="true"
/>
)
}
{/* Content container - relative z-index above overlay */}
<div class="relative z-2 max-w-6xl mx-auto">
<!-- Main Title -->
<h1
class="text-white text-shadow-md font-['Noto_Sans_TC',sans-serif]! font-bold leading-[1.2] -mb-1 text-6xl! md:text-5xl"
>
{title}
</h1>
<!-- Subtitle -->
<p
class="text-gray-100 text-shadow-md font-['Quicksand'] font-thin leading-[1.2] max-w-3xl mx-auto text-3xl! md:text-2xl"
>
{subtitle}
</p>
</div>
</header>
</section>