forked from UKSOURCE/ipv6
sponsor from nhat
This commit is contained in:
@@ -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>
|
||||
);
|
||||
}
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user