sponsor from nhat

This commit is contained in:
2026-05-13 19:47:14 +07:00
parent a01aebd8bd
commit 778f5f735d
6 changed files with 432 additions and 0 deletions
+80
View File
@@ -0,0 +1,80 @@
type SponsorContactData = {
id: string;
title: string;
description: string;
phone: { label: string; value: string };
email: { label: string; value: string };
cta: string;
image: { src: string; alt: string };
};
export default function SponsorContact({ data }: { data: SponsorContactData }) {
return (
<section id={data.id} className="py-16 lg:py-32 relative">
<div className="max-w-[1280px] mx-auto px-gutter">
{/* glass-panel gold-border — p-stack-lg lg:p-section-gap */}
<div className="glass-panel gold-border p-stack-lg lg:p-section-gap rounded-3xl overflow-hidden relative">
{/* Glow */}
<div className="absolute -bottom-24 -right-24 w-64 h-64 bg-primary/20 blur-[100px] rounded-full" />
<div className="relative z-10 grid grid-cols-1 lg:grid-cols-2 gap-stack-lg items-center">
{/* Left */}
<div>
<h2 className="font-display-lg text-display-lg mb-6">{data.title}</h2>
<p className="font-body-base text-body-base text-on-surface-variant/80 mb-8">
{data.description}
</p>
<div className="space-y-6 mb-12">
{/* Phone */}
<div className="flex items-center gap-4">
<div className="w-10 h-10 border border-primary/30 rounded-full flex items-center justify-center">
<span className="material-symbols-outlined text-primary">call</span>
</div>
<div>
<p className="text-label-caps opacity-60">{data.phone.label}</p>
<p className="font-title-sm">{data.phone.value}</p>
</div>
</div>
{/* Email */}
<div className="flex items-center gap-4">
<div className="w-10 h-10 border border-primary/30 rounded-full flex items-center justify-center">
<span className="material-symbols-outlined text-primary">mail</span>
</div>
<div>
<p className="text-label-caps opacity-60">{data.email.label}</p>
<p className="font-title-sm">{data.email.value}</p>
</div>
</div>
</div>
<button
type="button"
className="gold-gradient-bg text-on-primary font-title-sm px-12 py-5 rounded-lg hover:opacity-90 transition-all active:scale-95 flex items-center gap-3"
>
{data.cta}
<span className="material-symbols-outlined">arrow_forward</span>
</button>
</div>
{/* Right: image */}
<div className="hidden lg:block">
<div className="relative aspect-square">
{/* eslint-disable-next-line @next/next/no-img-element */}
<img
src={data.image.src}
alt={data.image.alt}
className="w-full h-full object-cover rounded-2xl opacity-60 mix-blend-luminosity"
/>
<div className="absolute inset-0 ring-1 ring-inset ring-white/10 rounded-2xl" />
</div>
</div>
</div>
</div>
</div>
</section>
);
}
+51
View File
@@ -0,0 +1,51 @@
import Link from "next/link";
type SponsorHeroData = {
eyebrow: string;
title: string;
subtitle: string;
description: string;
primaryCta: { label: string; href: string };
secondaryCta: { label: string; href: string };
};
export default function SponsorHero({ data }: { data: SponsorHeroData }) {
return (
<section className="relative py-16 lg:py-32 overflow-hidden">
<div className="absolute inset-0 bg-[radial-gradient(circle_at_50%_50%,rgba(197,160,89,0.08),transparent_70%)]" />
<div className="max-w-[1280px] mx-auto px-gutter relative z-10 text-center">
<span className="font-label-caps text-label-caps text-primary mb-4 block">
{data.eyebrow}
</span>
<h1 className="font-display-lg text-display-lg mb-6">
{data.title}
</h1>
<h2 className="font-headline-md text-headline-md text-on-surface-variant mb-8 max-w-3xl mx-auto">
{data.subtitle}
</h2>
<p className="font-body-base text-body-base text-on-surface-variant/80 max-w-2xl mx-auto mb-12">
{data.description}
</p>
<div className="flex flex-col sm:flex-row justify-center gap-stack-md">
<Link
href={data.primaryCta.href}
className="gold-gradient-bg text-on-primary font-title-sm px-10 py-4 rounded-lg hover:opacity-90 transition-all active:scale-95 text-center"
>
{data.primaryCta.label}
</Link>
<Link
href={data.secondaryCta.href}
className="border border-primary text-primary font-title-sm px-10 py-4 rounded-lg hover:bg-primary/5 transition-all active:scale-95 text-center"
>
{data.secondaryCta.label}
</Link>
</div>
</div>
</section>
);
}
@@ -0,0 +1,68 @@
type ItemCard = {
icon: string;
title: string;
status: string;
};
type Highlight = {
eyebrow: string;
title: string;
icon: string;
};
type SponsorItemBasedData = {
eyebrow: string;
title: string;
description: string;
items: ItemCard[];
highlights: Highlight[];
};
export default function SponsorItemBased({ data }: { data: SponsorItemBasedData }) {
return (
<section className="py-16 lg:py-32">
<div className="max-w-[1280px] mx-auto px-gutter">
{/* Header — text-center mb-stack-lg */}
<div className="text-center mb-stack-lg">
<h2 className="font-headline-md text-headline-md mb-2">{data.title}</h2>
<p className="text-on-surface-variant opacity-70">{data.description}</p>
</div>
{/* 4-col cards — gap-gutter = 24px, mb-stack-lg = 32px */}
<div className="grid grid-cols-2 lg:grid-cols-4 gap-gutter mb-stack-lg">
{data.items.map((item) => (
<div
key={item.title}
className="glass-panel p-stack-md rounded-lg text-center group hover:bg-surface-container transition-colors"
>
<div className="w-12 h-12 gold-gradient-bg rounded-full flex items-center justify-center mx-auto mb-4">
<span className="material-symbols-outlined text-on-primary">{item.icon}</span>
</div>
<h4 className="font-title-sm text-body-base mb-1">{item.title}</h4>
<p className="text-label-caps text-primary">{item.status}</p>
</div>
))}
</div>
{/* Highlights — gap-gutter = 24px */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-gutter">
{data.highlights.map((h) => (
<div
key={h.eyebrow}
className="bg-primary/5 border border-primary/20 p-stack-lg rounded-xl flex items-center justify-between"
>
<div>
<p className="font-label-caps text-primary mb-1">{h.eyebrow}</p>
<p className="font-title-sm">{h.title}</p>
</div>
<span className="material-symbols-outlined text-primary text-4xl">
{h.icon}
</span>
</div>
))}
</div>
</div>
</section>
);
}
@@ -0,0 +1,96 @@
type PackageItem = {
id: string;
tier: string;
badge: string | null;
price: string;
featured: boolean;
cta: string;
benefits: string[];
boldBenefit: string | null;
};
type SponsorPackagesData = {
eyebrow: string;
title: string;
items: PackageItem[];
};
export default function SponsorPackages({ data }: { data: SponsorPackagesData }) {
return (
<section className="py-16 lg:py-32 bg-surface-container-lowest">
<div className="max-w-[1280px] mx-auto px-gutter">
{/* Header — flex items-center justify-between mb-stack-lg */}
<div className="flex items-center justify-between mb-stack-lg">
<h2 className="font-headline-md text-headline-md">{data.title}</h2>
<div className="hidden lg:block h-px flex-grow mx-stack-lg bg-outline-variant/30" />
</div>
{/* Grid — gap-stack-lg = 32px */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-stack-lg">
{data.items.map((pkg) => (
<div
key={pkg.id}
className={`glass-panel p-stack-lg rounded-xl flex flex-col h-full ${
pkg.featured ? "gold-border gold-glow ring-2 ring-primary/20" : ""
}`}
>
<div className="mb-stack-lg">
{pkg.badge && (
<span className="bg-primary/20 text-primary px-3 py-1 rounded text-label-caps mb-4 inline-block">
{pkg.badge}
</span>
)}
<h3
className={`font-display-lg text-headline-md ${
pkg.featured ? "text-primary" : ""
}`}
>
{pkg.tier}
</h3>
<div className="text-on-surface font-display-lg text-title-sm mt-2">
{pkg.price}
</div>
</div>
<ul className="space-y-4 mb-stack-lg flex-grow">
{pkg.benefits.map((benefit) => (
<li key={benefit} className="flex items-start gap-3">
<span
className="material-symbols-outlined text-primary text-[20px]"
style={
pkg.featured
? { fontVariationSettings: "'FILL' 1" }
: undefined
}
>
check_circle
</span>
<span
className={`text-on-surface-variant ${
benefit === pkg.boldBenefit ? "font-bold" : ""
}`}
>
{benefit}
</span>
</li>
))}
</ul>
<button
type="button"
className={`w-full py-4 rounded font-title-sm transition-all active:scale-95 ${
pkg.featured
? "gold-gradient-bg text-on-primary hover:opacity-90"
: "border border-outline-variant text-on-surface hover:border-primary transition-colors"
}`}
>
{pkg.cta}
</button>
</div>
))}
</div>
</div>
</section>
);
}