Align site colors with GRV brand book palette.
Some checks failed
Deploy to Cloudflare Workers (OpenNext) / deploy (push) Has been cancelled
Some checks failed
Deploy to Cloudflare Workers (OpenNext) / deploy (push) Has been cancelled
Centralize primary, secondary, tertiary, and neutral tokens and apply them across theme variables and UI components. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
6bdb2204b3
commit
cb404ec079
|
|
@ -33,7 +33,7 @@ export default function ContactPage() {
|
|||
<CardContent>
|
||||
<a
|
||||
href={`mailto:${ch.email}`}
|
||||
className="font-medium text-[#1f3d7e] hover:underline"
|
||||
className="font-medium text-[#30614c] hover:underline"
|
||||
>
|
||||
{ch.email}
|
||||
</a>
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ export default function ExhibitPage() {
|
|||
<ul className="space-y-3 text-left">
|
||||
{benefits.map((b) => (
|
||||
<li key={b} className="flex gap-2 text-sm">
|
||||
<span className="text-[#ffb300]">→</span>
|
||||
<span className="text-[#37a47a]">→</span>
|
||||
{b}
|
||||
</li>
|
||||
))}
|
||||
|
|
|
|||
164
app/globals.css
164
app/globals.css
|
|
@ -30,39 +30,53 @@
|
|||
--font-display: var(--font-display);
|
||||
--font-wordmark: "Google Sans Flex Variable", system-ui, sans-serif;
|
||||
--font-hero-serif: var(--font-hero-serif);
|
||||
--color-brand-green: #1a5c38;
|
||||
--color-brand-green-dark: #0d3d26;
|
||||
--color-brand-gold: #ffb300;
|
||||
--color-brand-blue: #1f3d7e;
|
||||
--color-brand-navy: #0f0404;
|
||||
--color-surface-muted: #f7f7f7;
|
||||
--color-text-muted: #767676;
|
||||
--color-brand-primary: #37a47a;
|
||||
--color-brand-secondary: #b9d8c9;
|
||||
--color-brand-tertiary: #30614c;
|
||||
--color-brand-black: #000000;
|
||||
--color-brand-grey-1: #5b5b5b;
|
||||
--color-brand-grey-2: #a0a0a0;
|
||||
--color-brand-grey-3: #dbdbdb;
|
||||
--color-brand-white: #ffffff;
|
||||
--color-brand-green: var(--color-brand-primary);
|
||||
--color-brand-green-dark: var(--color-brand-tertiary);
|
||||
--color-surface-muted: #e8f2ec;
|
||||
--color-text-muted: #5b5b5b;
|
||||
}
|
||||
|
||||
:root {
|
||||
--radius: 0.75rem;
|
||||
--background: #ffffff;
|
||||
--foreground: #0d3d26;
|
||||
--card: #ffffff;
|
||||
--card-foreground: #0d3d26;
|
||||
--popover: #ffffff;
|
||||
--popover-foreground: #0d3d26;
|
||||
/* Primary: brand green · Secondary: white */
|
||||
--primary: #1a5c38;
|
||||
--primary-foreground: #ffffff;
|
||||
--secondary: #ffffff;
|
||||
--secondary-foreground: #1a5c38;
|
||||
--muted: #f0f5f2;
|
||||
--muted-foreground: #5a6b62;
|
||||
--accent: #ffb300;
|
||||
--accent-foreground: #0d3d26;
|
||||
--brand-primary: #37a47a;
|
||||
--brand-secondary: #b9d8c9;
|
||||
--brand-tertiary: #30614c;
|
||||
--brand-black: #000000;
|
||||
--brand-grey-1: #5b5b5b;
|
||||
--brand-grey-2: #a0a0a0;
|
||||
--brand-grey-3: #dbdbdb;
|
||||
--brand-white: #ffffff;
|
||||
--brand-white-soft: #fafafa;
|
||||
--brand-surface-muted: #e8f2ec;
|
||||
--background: var(--brand-white);
|
||||
--foreground: var(--brand-tertiary);
|
||||
--card: var(--brand-white);
|
||||
--card-foreground: var(--brand-tertiary);
|
||||
--popover: var(--brand-white);
|
||||
--popover-foreground: var(--brand-tertiary);
|
||||
--primary: var(--brand-primary);
|
||||
--primary-foreground: var(--brand-white);
|
||||
--secondary: var(--brand-secondary);
|
||||
--secondary-foreground: var(--brand-tertiary);
|
||||
--muted: var(--brand-surface-muted);
|
||||
--muted-foreground: var(--brand-grey-1);
|
||||
--accent: var(--brand-primary);
|
||||
--accent-foreground: var(--brand-white);
|
||||
--destructive: #dc2626;
|
||||
--border: #dce8e0;
|
||||
--input: #dce8e0;
|
||||
--ring: #1a5c38;
|
||||
--hero: #0d3d26;
|
||||
--section-muted: #f0f5f2;
|
||||
--section-inverse: #1a5c38;
|
||||
--border: var(--brand-grey-3);
|
||||
--input: var(--brand-grey-3);
|
||||
--ring: var(--brand-primary);
|
||||
--hero: var(--brand-tertiary);
|
||||
--section-muted: var(--brand-surface-muted);
|
||||
--section-inverse: var(--brand-primary);
|
||||
}
|
||||
|
||||
@layer base {
|
||||
|
|
@ -96,12 +110,12 @@
|
|||
text-wrap: balance;
|
||||
}
|
||||
.section-inverse {
|
||||
background-color: #1a5c38;
|
||||
color: #fafafa;
|
||||
background-color: var(--brand-primary);
|
||||
color: var(--brand-white-soft);
|
||||
}
|
||||
.section-green {
|
||||
background-color: #1a5c38;
|
||||
color: #fafafa;
|
||||
background-color: var(--brand-primary);
|
||||
color: var(--brand-white-soft);
|
||||
}
|
||||
|
||||
@keyframes geometric-mess-drift {
|
||||
|
|
@ -249,10 +263,10 @@
|
|||
/* Admission ticket — side notches + rounded body */
|
||||
.ticket-admission {
|
||||
border-radius: 1rem;
|
||||
--ticket-notch-fill: var(--section-inverse, #1a5c38);
|
||||
--ticket-notch-fill: var(--section-inverse, var(--brand-primary));
|
||||
}
|
||||
.ticket-admission[data-ticket-notch="light"] {
|
||||
--ticket-notch-fill: #f0f5f2;
|
||||
--ticket-notch-fill: var(--brand-surface-muted);
|
||||
}
|
||||
.ticket-admission::before,
|
||||
.ticket-admission::after {
|
||||
|
|
@ -278,11 +292,11 @@
|
|||
:root {
|
||||
--rift-scroll: 0;
|
||||
--rift-canvas: #fbfdfb;
|
||||
--rift-stroke: rgba(26, 92, 56, 0.18);
|
||||
--rift-stroke-minor: rgba(26, 92, 56, 0.26);
|
||||
--rift-stroke: rgba(55, 164, 122, 0.18);
|
||||
--rift-stroke-minor: rgba(55, 164, 122, 0.26);
|
||||
--rift-stroke-inverse: rgba(255, 255, 255, 0.25);
|
||||
--rift-accent: #ffb300;
|
||||
--rift-channel: #1a5c38;
|
||||
--rift-accent: var(--brand-secondary);
|
||||
--rift-channel: var(--brand-primary);
|
||||
}
|
||||
|
||||
.rift-profile-partners .rift-contour-minor,
|
||||
|
|
@ -469,7 +483,7 @@
|
|||
background: radial-gradient(
|
||||
ellipse 80% 60% at 50% 55%,
|
||||
rgba(45, 122, 82, 0.14) 0%,
|
||||
rgba(26, 92, 56, 0.06) 45%,
|
||||
rgba(55, 164, 122, 0.06) 45%,
|
||||
transparent 72%
|
||||
);
|
||||
mix-blend-mode: soft-light;
|
||||
|
|
@ -584,7 +598,7 @@
|
|||
|
||||
/* Readable brand-green copy on all white sections */
|
||||
.section-white {
|
||||
color: #0d3d26;
|
||||
color: var(--brand-tertiary);
|
||||
}
|
||||
|
||||
.section-white .topo-content-layer,
|
||||
|
|
@ -599,26 +613,26 @@
|
|||
.section-white .topo-content-readable :is(h1, h2, h3, h4, h5, h6, p, li, label, summary),
|
||||
.section-white .topo-content-layer a:not([data-slot="button"]),
|
||||
.section-white .topo-content-readable a:not([data-slot="button"]) {
|
||||
color: #0d3d26;
|
||||
color: var(--brand-tertiary);
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.section-white .topo-content-layer .text-foreground,
|
||||
.section-white .topo-content-readable .text-foreground {
|
||||
color: #1a5c38;
|
||||
color: var(--brand-primary);
|
||||
}
|
||||
|
||||
.section-white .topo-content-layer .text-muted-foreground,
|
||||
.section-white .topo-content-readable .text-muted-foreground {
|
||||
color: #3d5248;
|
||||
color: var(--brand-grey-1);
|
||||
}
|
||||
|
||||
.section-white .topo-prose-surface-light :is(h1, h2, h3, h4, p, li, span) {
|
||||
color: #0d3d26;
|
||||
color: var(--brand-tertiary);
|
||||
}
|
||||
|
||||
.section-white .topo-prose-surface-light .text-muted-foreground {
|
||||
color: #3d5248;
|
||||
color: var(--brand-grey-1);
|
||||
}
|
||||
|
||||
.section-white .topo-card-surface,
|
||||
|
|
@ -626,41 +640,41 @@
|
|||
.section-white .bg-white.topo-card-surface :is(h1, h2, h3, h4, p, span),
|
||||
.section-white [data-slot="card"],
|
||||
.section-white [data-slot="card"] :is(h1, h2, h3, h4, p, span, li, label) {
|
||||
color: #1a5c38;
|
||||
color: var(--brand-primary);
|
||||
}
|
||||
|
||||
.section-white .topo-card-surface .text-muted-foreground,
|
||||
.section-white [data-slot="card"] .text-muted-foreground,
|
||||
.section-white .bg-white .text-muted-foreground {
|
||||
color: #3d5248;
|
||||
color: var(--brand-grey-1);
|
||||
}
|
||||
|
||||
.section-white [data-slot="accordion-trigger"] {
|
||||
color: #0d3d26;
|
||||
color: var(--brand-tertiary);
|
||||
}
|
||||
|
||||
.section-white [data-slot="button"][data-variant="outline"],
|
||||
.section-white [data-slot="button"][data-variant="ghost"],
|
||||
.section-white [data-slot="button"][data-variant="link"] {
|
||||
color: #1a5c38;
|
||||
color: var(--brand-primary);
|
||||
}
|
||||
|
||||
.section-white [data-slot="button"][data-variant="outline"] {
|
||||
border-color: rgba(26, 92, 56, 0.35);
|
||||
border-color: rgba(55, 164, 122, 0.35);
|
||||
}
|
||||
|
||||
.section-white [data-slot="button"][data-variant="ghost"]:hover,
|
||||
.section-white [data-slot="button"][data-variant="link"]:hover {
|
||||
color: #0d3d26;
|
||||
background-color: rgba(26, 92, 56, 0.06);
|
||||
color: var(--brand-tertiary);
|
||||
background-color: rgba(55, 164, 122, 0.06);
|
||||
}
|
||||
|
||||
header.section-white {
|
||||
color: #0d3d26;
|
||||
color: var(--brand-tertiary);
|
||||
}
|
||||
|
||||
header.section-white .text-muted-foreground {
|
||||
color: #3d5248;
|
||||
color: var(--brand-grey-1);
|
||||
}
|
||||
|
||||
.section-white:has(.topo-curvy-extend) {
|
||||
|
|
@ -673,7 +687,7 @@
|
|||
|
||||
.topo-prose-surface-light {
|
||||
background: #ffffff;
|
||||
border: 1px solid rgba(26, 92, 56, 0.12);
|
||||
border: 1px solid rgba(55, 164, 122, 0.12);
|
||||
box-shadow: none;
|
||||
backdrop-filter: none;
|
||||
}
|
||||
|
|
@ -730,7 +744,7 @@
|
|||
.section-green .bg-white :is(h1, h2, h3, h4, p, span, li, label),
|
||||
.section-green [data-slot="card"],
|
||||
.section-green [data-slot="card"] :is(h1, h2, h3, h4, p, span, li, label, a) {
|
||||
color: #1a5c38;
|
||||
color: var(--brand-primary);
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
|
|
@ -739,27 +753,27 @@
|
|||
.section-green [data-slot="card"] .text-muted-foreground,
|
||||
.section-green [data-slot="card"] [data-slot="card-description"],
|
||||
.section-green .topo-card-surface [data-slot="card-description"] {
|
||||
color: #3d5248;
|
||||
color: var(--brand-grey-1);
|
||||
}
|
||||
|
||||
.section-green .ticket-admission,
|
||||
.section-green .ticket-admission :is(h1, h2, h3, h4, p, span, li, label) {
|
||||
color: #1a5c38;
|
||||
color: var(--brand-primary);
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.section-green .ticket-admission .text-muted-foreground,
|
||||
.section-green .ticket-admission p {
|
||||
color: #3d5248;
|
||||
color: var(--brand-grey-1);
|
||||
}
|
||||
|
||||
.topo-card-link,
|
||||
.topo-card-link svg {
|
||||
color: #1a5c38;
|
||||
color: var(--brand-primary);
|
||||
}
|
||||
.topo-card-link:hover,
|
||||
.topo-card-link:hover svg {
|
||||
color: #0d3d26;
|
||||
color: var(--brand-tertiary);
|
||||
}
|
||||
|
||||
.section-green .topo-on-green-bg [data-slot="button"][data-variant="outline"] {
|
||||
|
|
@ -799,30 +813,30 @@
|
|||
.section-green .topo-card-surface [data-slot="button"][data-variant="link"],
|
||||
.section-green .bg-white [data-slot="button"][data-variant="ghost"],
|
||||
.section-green .bg-white [data-slot="button"][data-variant="link"] {
|
||||
color: #1a5c38;
|
||||
color: var(--brand-primary);
|
||||
}
|
||||
|
||||
.section-green [data-slot="card"] [data-slot="button"][data-variant="ghost"]:hover,
|
||||
.section-green [data-slot="card"] [data-slot="button"][data-variant="link"]:hover,
|
||||
.section-green .topo-card-surface [data-slot="button"][data-variant="ghost"]:hover,
|
||||
.section-green .topo-card-surface [data-slot="button"][data-variant="link"]:hover {
|
||||
color: #0d3d26;
|
||||
background-color: rgba(26, 92, 56, 0.06);
|
||||
color: var(--brand-tertiary);
|
||||
background-color: rgba(55, 164, 122, 0.06);
|
||||
}
|
||||
|
||||
.section-green [data-slot="card"] [data-slot="button"][data-variant="outline"],
|
||||
.section-green .topo-card-surface [data-slot="button"][data-variant="outline"],
|
||||
.section-green .bg-white [data-slot="button"][data-variant="outline"] {
|
||||
border-color: rgba(26, 92, 56, 0.4);
|
||||
color: #1a5c38;
|
||||
border-color: rgba(55, 164, 122, 0.4);
|
||||
color: var(--brand-primary);
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.section-green [data-slot="card"] [data-slot="button"][data-variant="outline"]:hover,
|
||||
.section-green .topo-card-surface [data-slot="button"][data-variant="outline"]:hover {
|
||||
border-color: rgba(26, 92, 56, 0.55);
|
||||
color: #0d3d26;
|
||||
background-color: rgba(26, 92, 56, 0.06);
|
||||
border-color: rgba(55, 164, 122, 0.55);
|
||||
color: var(--brand-tertiary);
|
||||
background-color: rgba(55, 164, 122, 0.06);
|
||||
}
|
||||
|
||||
.section-green [data-slot="card"] [data-slot="button"] svg,
|
||||
|
|
@ -830,14 +844,14 @@
|
|||
color: currentColor;
|
||||
}
|
||||
|
||||
.section-green .topo-on-green-bg [data-slot="button"][data-variant="default"]:not([class*="bg-[#ffb300]"]) {
|
||||
background-color: #ffb300;
|
||||
color: #0f0404;
|
||||
.section-green .topo-on-green-bg [data-slot="button"][data-variant="default"]:not([class*="bg-white"]) {
|
||||
background-color: var(--brand-white);
|
||||
color: var(--brand-tertiary);
|
||||
}
|
||||
|
||||
.section-green .topo-on-green-bg [data-slot="button"][data-variant="default"]:not([class*="bg-[#ffb300]"]):hover {
|
||||
background-color: #e6a200;
|
||||
color: #0f0404;
|
||||
.section-green .topo-on-green-bg [data-slot="button"][data-variant="default"]:not([class*="bg-white"]):hover {
|
||||
background-color: var(--brand-white-soft);
|
||||
color: var(--brand-tertiary);
|
||||
}
|
||||
|
||||
.topo-pattern-clearance-section {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ export default function PartnersPage() {
|
|||
description={<p className="text-lg leading-relaxed">{partnersIntro.subheadline}</p>}
|
||||
>
|
||||
<div className="flex flex-wrap gap-3">
|
||||
<Button className="rounded-full bg-[#ffb300] text-[#0f0404] hover:bg-[#ffb300]/90" asChild>
|
||||
<Button className="rounded-full bg-[#37a47a] text-[#ffffff] hover:bg-[#37a47a]/90" asChild>
|
||||
<Link href="#partnership-form">Become a partner</Link>
|
||||
</Button>
|
||||
<ChampionStartupModal />
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ export default async function PaymentSuccessPage({ searchParams }: Props) {
|
|||
/>
|
||||
<Section>
|
||||
<div className="mx-auto max-w-lg text-center">
|
||||
<CheckCircle2 className="mx-auto size-16 text-[#1a5c38]" />
|
||||
<CheckCircle2 className="mx-auto size-16 text-[#37a47a]" />
|
||||
<p className="mt-6 text-muted-foreground">
|
||||
Your registration has been received. Order reference:{" "}
|
||||
<span className="font-mono font-medium text-foreground">{orderId}</span>
|
||||
|
|
|
|||
|
|
@ -30,12 +30,12 @@ export default function PitchCompetitionPage() {
|
|||
}
|
||||
description={
|
||||
<>
|
||||
<p className="text-xl text-[#1f3d7e]">{pitchCompetition.subheadline}</p>
|
||||
<p className="text-xl text-[#30614c]">{pitchCompetition.subheadline}</p>
|
||||
<p className="mt-4 leading-relaxed">{pitchCompetition.description}</p>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<Button className="rounded-full bg-[#ffb300] text-[#0f0404] hover:bg-[#ffb300]/90" asChild>
|
||||
<Button className="rounded-full bg-[#37a47a] text-[#ffffff] hover:bg-[#37a47a]/90" asChild>
|
||||
<Link href={site.links.pitchApplyUrl}>Apply now</Link>
|
||||
</Button>
|
||||
</PageRiftHeader>
|
||||
|
|
@ -45,7 +45,7 @@ export default function PitchCompetitionPage() {
|
|||
<ul className="mt-6 space-y-3">
|
||||
{pitchCompetition.criteria.map((c) => (
|
||||
<li key={c} className="flex gap-2 text-muted-foreground">
|
||||
<span className="text-[#ffb300]">✓</span>
|
||||
<span className="text-[#37a47a]">✓</span>
|
||||
{c}
|
||||
</li>
|
||||
))}
|
||||
|
|
|
|||
|
|
@ -19,31 +19,31 @@ export default function PrivacyPage() {
|
|||
eyebrow="Legal"
|
||||
title={<h1 className="text-4xl font-bold">{privacyPolicy.title}</h1>}
|
||||
description={
|
||||
<p className="text-sm text-[#3d5248]">Last updated: {privacyPolicy.updated}</p>
|
||||
<p className="text-sm text-[#5b5b5b]">Last updated: {privacyPolicy.updated}</p>
|
||||
}
|
||||
/>
|
||||
|
||||
<Section>
|
||||
<TopoProseSurface className="max-w-2xl space-y-6">
|
||||
<p className="text-[#3d5248] leading-relaxed">{privacyPolicy.intro}</p>
|
||||
<p className="text-[#5b5b5b] leading-relaxed">{privacyPolicy.intro}</p>
|
||||
|
||||
{privacyPolicy.sections.map((section) => (
|
||||
<section key={section.heading}>
|
||||
<h2 className="text-lg font-semibold text-[#1a5c38]">{section.heading}</h2>
|
||||
<p className="mt-2 text-[#3d5248] leading-relaxed">{section.body}</p>
|
||||
<h2 className="text-lg font-semibold text-[#37a47a]">{section.heading}</h2>
|
||||
<p className="mt-2 text-[#5b5b5b] leading-relaxed">{section.body}</p>
|
||||
</section>
|
||||
))}
|
||||
|
||||
<p className="border-t border-[#1a5c38]/12 pt-6 text-[#3d5248] leading-relaxed">
|
||||
<p className="border-t border-[#37a47a]/12 pt-6 text-[#5b5b5b] leading-relaxed">
|
||||
{privacyPolicy.moreDetails}
|
||||
</p>
|
||||
</TopoProseSurface>
|
||||
|
||||
<div className="mt-8 flex flex-wrap gap-3">
|
||||
<Button className="rounded-full bg-[#1a5c38] text-white hover:bg-[#0d3d26]" asChild>
|
||||
<Button className="rounded-full bg-[#37a47a] text-white hover:bg-[#30614c]" asChild>
|
||||
<Link href="/contact">Contact us</Link>
|
||||
</Button>
|
||||
<Button variant="outline" className="rounded-full border-[#1a5c38]/30 text-[#1a5c38]" asChild>
|
||||
<Button variant="outline" className="rounded-full border-[#37a47a]/30 text-[#37a47a]" asChild>
|
||||
<Link href={`mailto:${privacyPolicy.contactEmail}`}>{privacyPolicy.contactEmail}</Link>
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ export default function ProgramPage() {
|
|||
/>
|
||||
</div>
|
||||
<CardHeader>
|
||||
<p className="text-xs font-semibold uppercase text-[#ffb300]">{day.date}</p>
|
||||
<p className="text-xs font-semibold uppercase text-[#37a47a]">{day.date}</p>
|
||||
<CardTitle>{day.title}</CardTitle>
|
||||
<CardDescription>{day.description}</CardDescription>
|
||||
</CardHeader>
|
||||
|
|
@ -73,7 +73,7 @@ export default function ProgramPage() {
|
|||
</Card>
|
||||
))}
|
||||
</div>
|
||||
<Button className="mt-10 rounded-full bg-[#ffb300] text-[#0f0404]" asChild>
|
||||
<Button className="mt-10 rounded-full bg-[#37a47a] text-[#ffffff]" asChild>
|
||||
<Link href="/pitch-competition">Pitch competition details</Link>
|
||||
</Button>
|
||||
</Section>
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ export default function SpeakersPage() {
|
|||
</h1>
|
||||
}
|
||||
description={
|
||||
<p className="text-lg text-[#3d5248]">
|
||||
<p className="text-lg text-[#5b5b5b]">
|
||||
{site.dates.label} · {site.venue.name}
|
||||
</p>
|
||||
}
|
||||
|
|
@ -64,7 +64,7 @@ export default function SpeakersPage() {
|
|||
)}
|
||||
</div>
|
||||
<div className="mt-16 text-center">
|
||||
<Button className="rounded-full bg-[#ffb300] text-[#0f0404]" asChild>
|
||||
<Button className="rounded-full bg-[#37a47a] text-[#ffffff]" asChild>
|
||||
<Link href="/payment">Get tickets</Link>
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -47,10 +47,10 @@ export function BrandLogo({
|
|||
|
||||
const primaryClass = isFooter
|
||||
? "text-white"
|
||||
: "text-[#1a5c38]";
|
||||
: "text-[#37a47a]";
|
||||
const secondaryClass = isFooter
|
||||
? "text-white/85"
|
||||
: "text-[#0d3d26]/90";
|
||||
: "text-[#30614c]/90";
|
||||
|
||||
const primarySize = compact
|
||||
? "text-[12px] sm:text-[13px] md:text-sm"
|
||||
|
|
@ -97,7 +97,7 @@ export function BrandLogo({
|
|||
return (
|
||||
<Link
|
||||
href={href}
|
||||
className="shrink-0 rounded-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#1a5c38] focus-visible:ring-offset-2"
|
||||
className="shrink-0 rounded-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#37a47a] focus-visible:ring-offset-2"
|
||||
aria-label={siteName}
|
||||
>
|
||||
{content}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ export function FooterTopoPattern({ className }: Props) {
|
|||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"pointer-events-none absolute inset-0 z-0 overflow-hidden bg-[#1a5c38]",
|
||||
"pointer-events-none absolute inset-0 z-0 overflow-hidden bg-[#37a47a]",
|
||||
className
|
||||
)}
|
||||
aria-hidden
|
||||
|
|
@ -37,7 +37,7 @@ export function FooterTopoPattern({ className }: Props) {
|
|||
))}
|
||||
</svg>
|
||||
<div
|
||||
className="absolute inset-0 bg-gradient-to-t from-[#0d3d26]/18 via-transparent to-transparent"
|
||||
className="absolute inset-0 bg-gradient-to-t from-[#30614c]/18 via-transparent to-transparent"
|
||||
aria-hidden
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ export function FooterTopographicBand({ className }: Props) {
|
|||
V76
|
||||
C1120 92 860 58 600 74
|
||||
S240 98 0 82 Z"
|
||||
fill="#1a5c38"
|
||||
fill="#37a47a"
|
||||
/>
|
||||
<path
|
||||
d="M0 82
|
||||
|
|
@ -56,7 +56,7 @@ export function FooterTopographicBand({ className }: Props) {
|
|||
V148
|
||||
C1000 164 740 136 480 152
|
||||
S160 172 0 156 Z"
|
||||
fill="#1a5c38"
|
||||
fill="#37a47a"
|
||||
/>
|
||||
<path
|
||||
d="M0 156
|
||||
|
|
@ -64,7 +64,7 @@ export function FooterTopographicBand({ className }: Props) {
|
|||
S1280 134 1440 158
|
||||
V220
|
||||
H0 Z"
|
||||
fill="#1a5c38"
|
||||
fill="#37a47a"
|
||||
/>
|
||||
|
||||
{/* Logo-like contour strokes */}
|
||||
|
|
@ -102,7 +102,7 @@ export function FooterTopographicBand({ className }: Props) {
|
|||
</svg>
|
||||
|
||||
{/* Fade into solid footer green */}
|
||||
<div className="absolute inset-x-0 bottom-0 h-16 bg-gradient-to-b from-transparent to-[#1a5c38]" />
|
||||
<div className="absolute inset-x-0 bottom-0 h-16 bg-gradient-to-b from-transparent to-[#37a47a]" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ export function PartnerLogoPlaceholder({ className, size = "md" }: Props) {
|
|||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"flex items-center justify-center rounded-xl border-2 border-dashed border-[#1f3d7e]/25 bg-[#f7f7f7]",
|
||||
"font-semibold uppercase tracking-wide text-[#1f3d7e]/45",
|
||||
"flex items-center justify-center rounded-xl border-2 border-dashed border-[#30614c]/25 bg-[#fafafa]",
|
||||
"font-semibold uppercase tracking-wide text-[#30614c]/45",
|
||||
sizeClasses[size],
|
||||
className
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ export function RiftFlowLines({
|
|||
export function RiftCardConnector({ className }: { className?: string }) {
|
||||
return (
|
||||
<div className={cn("relative flex justify-center py-0.5", className)} aria-hidden>
|
||||
<div className="h-6 w-px bg-gradient-to-b from-[#1a5c38]/20 via-[#1a5c38]/35 to-[#1a5c38]/20" />
|
||||
<div className="h-6 w-px bg-gradient-to-b from-[#37a47a]/20 via-[#37a47a]/35 to-[#37a47a]/20" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,9 +4,11 @@ import { useMemo } from "react";
|
|||
import { mixHex } from "@/lib/rift-colors";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const GREEN = "#1a5c38";
|
||||
const GOLD = "#ffb300";
|
||||
const BLUE = "#1f3d7e";
|
||||
import { BRAND_COLORS } from "@/content/brand-colors";
|
||||
|
||||
const GREEN: string = BRAND_COLORS.primary;
|
||||
const GOLD: string = BRAND_COLORS.secondary;
|
||||
const BLUE: string = BRAND_COLORS.tertiary;
|
||||
|
||||
/** Long curved paths that pulse across the page background */
|
||||
const PULSE_CURVES = [
|
||||
|
|
|
|||
|
|
@ -14,9 +14,11 @@ import {
|
|||
import { mixHex } from "@/lib/rift-colors";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const GREEN = "#1a5c38";
|
||||
const GOLD = "#ffb300";
|
||||
const BLUE = "#1f3d7e";
|
||||
import { BRAND_COLORS } from "@/content/brand-colors";
|
||||
|
||||
const GREEN: string = BRAND_COLORS.primary;
|
||||
const GOLD: string = BRAND_COLORS.secondary;
|
||||
const BLUE: string = BRAND_COLORS.tertiary;
|
||||
|
||||
type Props = {
|
||||
variant: "hero" | "ambient" | "header";
|
||||
|
|
@ -100,7 +102,7 @@ export function RiftTopographyLayer({
|
|||
{isHero && (
|
||||
<>
|
||||
<div
|
||||
className="absolute inset-0 bg-gradient-to-b from-[#fbfdfb] via-white to-[#f0f5f2]"
|
||||
className="absolute inset-0 bg-gradient-to-b from-[#fbfdfb] via-white to-[#e8f2ec]"
|
||||
aria-hidden
|
||||
/>
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -6,9 +6,11 @@ import { cn } from "@/lib/utils";
|
|||
const MESH_W = 140;
|
||||
const MESH_H = 100;
|
||||
|
||||
import { BRAND_GREEN_SHADES } from "@/content/brand-colors";
|
||||
|
||||
/** Narrow green range — low contrast between “stones” on section backgrounds */
|
||||
const ROCK_TONES = ["#1a5c38", "#1d5f3c", "#216342", "#246845", "#286a48", "#2b6e4b"] as const;
|
||||
const GROUT = "rgba(8, 38, 22, 0.2)";
|
||||
const ROCK_TONES = BRAND_GREEN_SHADES;
|
||||
const GROUT = "rgba(48, 97, 76, 0.2)";
|
||||
|
||||
const ROCK_MESH = buildVoronoiMesh(42, MESH_W, MESH_H, 0x475256, {
|
||||
siteGenerator: "poisson",
|
||||
|
|
@ -30,7 +32,7 @@ function rockFill(cell: VoronoiCell, index: number) {
|
|||
const cx = cell.points.reduce((s, p) => s + p[0], 0) / cell.points.length;
|
||||
const cy = cell.points.reduce((s, p) => s + p[1], 0) / cell.points.length;
|
||||
const yNorm = cy / MESH_H;
|
||||
const gradient = mixHex("#2a6f4a", "#1a5c38", Math.min(1, yNorm * 0.45 + 0.25));
|
||||
const gradient = mixHex("#2a6f4a", "#37a47a", Math.min(1, yNorm * 0.45 + 0.25));
|
||||
const tone = ROCK_TONES[(index * 11 + Math.floor(cx * 0.55)) % ROCK_TONES.length];
|
||||
return mixHex(gradient, tone, 0.38);
|
||||
}
|
||||
|
|
@ -55,7 +57,7 @@ export function RoundedRockVoronoiBackground({
|
|||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"pointer-events-none absolute overflow-hidden bg-[#1a5c38]",
|
||||
"pointer-events-none absolute overflow-hidden bg-[#37a47a]",
|
||||
style?.height != null ? "left-0 right-0" : "inset-0",
|
||||
className
|
||||
)}
|
||||
|
|
@ -83,7 +85,7 @@ export function RoundedRockVoronoiBackground({
|
|||
<div className="absolute inset-0 opacity-[0.18] grain" aria-hidden />
|
||||
{gradient && (
|
||||
<div
|
||||
className="absolute inset-0 bg-gradient-to-b from-[#2a6f4a]/8 via-transparent to-[#0d3d26]/10"
|
||||
className="absolute inset-0 bg-gradient-to-b from-[#2a6f4a]/8 via-transparent to-[#30614c]/10"
|
||||
aria-hidden
|
||||
/>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ export function TopoCurvyExtend({ className }: Props) {
|
|||
<path
|
||||
d="M-40 24 C 200 2, 480 44, 720 14 S 1180 4, 1480 28"
|
||||
fill="none"
|
||||
stroke="#1a5c38"
|
||||
stroke="#37a47a"
|
||||
strokeWidth="1.25"
|
||||
strokeOpacity="0.45"
|
||||
strokeLinecap="round"
|
||||
|
|
@ -34,7 +34,7 @@ export function TopoCurvyExtend({ className }: Props) {
|
|||
<path
|
||||
d="M0 8 C 280 32, 560 4, 880 28 S 1240 42, 1480 12"
|
||||
fill="none"
|
||||
stroke="#1a5c38"
|
||||
stroke="#37a47a"
|
||||
strokeWidth="1"
|
||||
strokeOpacity="0.32"
|
||||
strokeLinecap="round"
|
||||
|
|
@ -43,7 +43,7 @@ export function TopoCurvyExtend({ className }: Props) {
|
|||
<path
|
||||
d="M120 42 C 320 64, 520 34, 720 78 S 980 46, 1240 88, 1480 52"
|
||||
fill="none"
|
||||
stroke="#1a5c38"
|
||||
stroke="#37a47a"
|
||||
strokeWidth="1.2"
|
||||
strokeOpacity="0.38"
|
||||
strokeLinecap="round"
|
||||
|
|
@ -60,7 +60,7 @@ export function TopoCurvyExtend({ className }: Props) {
|
|||
<path
|
||||
d="M80 68 C 360 96, 600 72, 840 118 S 1100 86, 1380 128"
|
||||
fill="none"
|
||||
stroke="#1a5c38"
|
||||
stroke="#37a47a"
|
||||
strokeWidth="0.9"
|
||||
strokeOpacity="0.28"
|
||||
strokeLinecap="round"
|
||||
|
|
@ -77,7 +77,7 @@ export function TopoCurvyExtend({ className }: Props) {
|
|||
<path
|
||||
d="M360 38 L360 132"
|
||||
fill="none"
|
||||
stroke="#1a5c38"
|
||||
stroke="#37a47a"
|
||||
strokeWidth="0.75"
|
||||
strokeOpacity="0.3"
|
||||
strokeLinecap="round"
|
||||
|
|
@ -85,7 +85,7 @@ export function TopoCurvyExtend({ className }: Props) {
|
|||
<path
|
||||
d="M720 14 L720 148"
|
||||
fill="none"
|
||||
stroke="#1a5c38"
|
||||
stroke="#37a47a"
|
||||
strokeWidth="0.9"
|
||||
strokeOpacity="0.35"
|
||||
strokeLinecap="round"
|
||||
|
|
@ -101,7 +101,7 @@ export function TopoCurvyExtend({ className }: Props) {
|
|||
<path
|
||||
d="M520 34 L520 118"
|
||||
fill="none"
|
||||
stroke="#1a5c38"
|
||||
stroke="#37a47a"
|
||||
strokeWidth="0.65"
|
||||
strokeOpacity="0.25"
|
||||
strokeLinecap="round"
|
||||
|
|
|
|||
|
|
@ -1,12 +1,7 @@
|
|||
import { BRAND_GREEN_SHADES } from "@/content/brand-colors";
|
||||
|
||||
/** GRV greens for wavy interlocking footer tessellation. */
|
||||
export const WAVY_TESS_PALETTE = [
|
||||
"#1a5c38",
|
||||
"#1d5f3c",
|
||||
"#216342",
|
||||
"#246845",
|
||||
"#286a48",
|
||||
"#2b6e4b",
|
||||
] as const;
|
||||
export const WAVY_TESS_PALETTE = BRAND_GREEN_SHADES;
|
||||
|
||||
export type WavyTessCell = { d: string; fill: string };
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ export function AddToCalendar({ className, variant = "outline" }: Props) {
|
|||
variant === "inverse"
|
||||
? "rounded-full border-white/30 bg-transparent text-white hover:bg-white/10"
|
||||
: variant === "default"
|
||||
? "rounded-full bg-[#ffb300] text-[#0f0404] hover:bg-[#ffb300]/90"
|
||||
? "rounded-full bg-[#37a47a] text-[#ffffff] hover:bg-[#37a47a]/90"
|
||||
: "rounded-full";
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -5,17 +5,17 @@ export function BoothPackages() {
|
|||
return (
|
||||
<div className="grid gap-6 md:grid-cols-3">
|
||||
{boothPackages.map((pkg) => (
|
||||
<Card key={pkg.id} className="topo-card-surface border-border bg-white text-[#1a5c38]">
|
||||
<Card key={pkg.id} className="topo-card-surface border-border bg-white text-[#37a47a]">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-lg">{pkg.name}</CardTitle>
|
||||
<CardDescription className="font-medium text-[#1a5c38]/90">{pkg.size}</CardDescription>
|
||||
<CardDescription className="font-medium text-[#37a47a]/90">{pkg.size}</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<p className="text-sm text-[#3d5248] leading-relaxed">{pkg.description}</p>
|
||||
<p className="text-sm text-[#5b5b5b] leading-relaxed">{pkg.description}</p>
|
||||
<ul className="space-y-2">
|
||||
{pkg.highlights.map((h) => (
|
||||
<li key={h} className="flex gap-2 text-sm">
|
||||
<span className="text-[#ffb300]">✓</span>
|
||||
<span className="text-[#37a47a]">✓</span>
|
||||
{h}
|
||||
</li>
|
||||
))}
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ export function ExhibitorBoothForm() {
|
|||
</div>
|
||||
|
||||
<fieldset className="space-y-4">
|
||||
<legend className="text-sm font-semibold uppercase tracking-wider text-[#1f3d7e]">
|
||||
<legend className="text-sm font-semibold uppercase tracking-wider text-[#30614c]">
|
||||
Contact
|
||||
</legend>
|
||||
<div className="grid gap-4 sm:grid-cols-2">
|
||||
|
|
@ -134,7 +134,7 @@ export function ExhibitorBoothForm() {
|
|||
</fieldset>
|
||||
|
||||
<fieldset className="space-y-4">
|
||||
<legend className="text-sm font-semibold uppercase tracking-wider text-[#1f3d7e]">
|
||||
<legend className="text-sm font-semibold uppercase tracking-wider text-[#30614c]">
|
||||
Company & products
|
||||
</legend>
|
||||
<div className="space-y-2">
|
||||
|
|
@ -188,7 +188,7 @@ export function ExhibitorBoothForm() {
|
|||
</fieldset>
|
||||
|
||||
<fieldset className="space-y-4">
|
||||
<legend className="text-sm font-semibold uppercase tracking-wider text-[#1f3d7e]">
|
||||
<legend className="text-sm font-semibold uppercase tracking-wider text-[#30614c]">
|
||||
Booth requirements
|
||||
</legend>
|
||||
<div className="space-y-2">
|
||||
|
|
@ -247,14 +247,14 @@ export function ExhibitorBoothForm() {
|
|||
|
||||
{error && <p className="text-sm text-destructive">{error}</p>}
|
||||
{status === "success" && (
|
||||
<p className="text-sm text-[#1f3d7e]">
|
||||
<p className="text-sm text-[#30614c]">
|
||||
Thank you! We received your booth request and will follow up with availability and pricing.
|
||||
</p>
|
||||
)}
|
||||
|
||||
<Button
|
||||
type="submit"
|
||||
className="w-full rounded-full bg-[#ffb300] text-[#0f0404] hover:bg-[#ffb300]/90 sm:w-auto"
|
||||
className="w-full rounded-full bg-[#37a47a] text-[#ffffff] hover:bg-[#37a47a]/90 sm:w-auto"
|
||||
disabled={status === "loading"}
|
||||
>
|
||||
{status === "loading" ? "Submitting…" : "Submit booth request"}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ export function DataConsentField({
|
|||
/>
|
||||
<Label htmlFor={id} className="text-sm font-normal leading-snug text-muted-foreground">
|
||||
{labelPrefix}{" "}
|
||||
<Link href="/privacy" className="font-medium text-[#1a5c38] underline underline-offset-2">
|
||||
<Link href="/privacy" className="font-medium text-[#37a47a] underline underline-offset-2">
|
||||
{dataConsent.privacyLinkText}
|
||||
</Link>
|
||||
.
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ export function AttendSummitSection() {
|
|||
return (
|
||||
<Section id="attend" variant="muted" className="py-14 md:py-20">
|
||||
<div className="topo-on-green-bg mx-auto max-w-3xl text-center">
|
||||
<p className="text-xs font-semibold uppercase tracking-widest text-[#ffb300]">
|
||||
<p className="text-xs font-semibold uppercase tracking-widest text-[#b9d8c9]">
|
||||
{attendCopy.eyebrow}
|
||||
</p>
|
||||
<h2 className="mt-3 text-3xl font-bold tracking-tight text-white md:text-4xl">
|
||||
|
|
@ -33,15 +33,15 @@ export function AttendSummitSection() {
|
|||
delay={i * 75}
|
||||
as="article"
|
||||
className={cn(
|
||||
"topo-card-surface group flex flex-col rounded-2xl border border-border bg-white p-6 text-[#1a5c38] shadow-sm",
|
||||
"transition-shadow duration-200 hover:border-[#1a5c38]/25 hover:shadow-md"
|
||||
"topo-card-surface group flex flex-col rounded-2xl border border-border bg-white p-6 text-[#37a47a] shadow-sm",
|
||||
"transition-shadow duration-200 hover:border-[#37a47a]/25 hover:shadow-md"
|
||||
)}
|
||||
>
|
||||
<span className="inline-flex size-11 items-center justify-center rounded-xl bg-[#1a5c38]/10 text-[#1a5c38]">
|
||||
<span className="inline-flex size-11 items-center justify-center rounded-xl bg-[#37a47a]/10 text-[#37a47a]">
|
||||
<Icon className="size-5" strokeWidth={1.75} aria-hidden />
|
||||
</span>
|
||||
<h3 className="mt-4 text-lg font-bold text-[#0d3d26]">{path.title}</h3>
|
||||
<p className="mt-2 flex-1 text-sm leading-relaxed text-[#3d5248]">
|
||||
<h3 className="mt-4 text-lg font-bold text-[#30614c]">{path.title}</h3>
|
||||
<p className="mt-2 flex-1 text-sm leading-relaxed text-[#5b5b5b]">
|
||||
{path.description}
|
||||
</p>
|
||||
<Button
|
||||
|
|
@ -61,7 +61,7 @@ export function AttendSummitSection() {
|
|||
|
||||
<div className="mt-10 flex flex-wrap items-center justify-center gap-3">
|
||||
<Button
|
||||
className="rounded-full bg-[#ffb300] px-8 text-[#0f0404] hover:bg-[#ffb300]/90"
|
||||
className="rounded-full bg-[#37a47a] px-8 text-[#ffffff] hover:bg-[#37a47a]/90"
|
||||
asChild
|
||||
>
|
||||
<Link href="/payment">Get tickets</Link>
|
||||
|
|
|
|||
|
|
@ -17,13 +17,13 @@ export function BoothAcquisitionBand() {
|
|||
/>
|
||||
</div>
|
||||
<div className="order-1 lg:order-2">
|
||||
<p className="text-xs font-semibold uppercase tracking-widest text-[#ffb300]">
|
||||
<p className="text-xs font-semibold uppercase tracking-widest text-[#b9d8c9]">
|
||||
{exhibitCopy.eyebrow}
|
||||
</p>
|
||||
<h2 className="mt-3 text-3xl font-bold md:text-4xl">{exhibitCopy.headline}</h2>
|
||||
<p className="mt-4 text-[#3d5248] leading-relaxed">{exhibitCopy.subheadline}</p>
|
||||
<p className="mt-4 text-[#5b5b5b] leading-relaxed">{exhibitCopy.subheadline}</p>
|
||||
<div className="mt-8 flex flex-wrap gap-3">
|
||||
<Button className="rounded-full bg-[#ffb300] text-[#0f0404] hover:bg-[#ffb300]/90" asChild>
|
||||
<Button className="rounded-full bg-[#37a47a] text-[#ffffff] hover:bg-[#37a47a]/90" asChild>
|
||||
<Link href="/exhibit#reserve-booth">Reserve a booth</Link>
|
||||
</Button>
|
||||
<Button variant="outline" className="topo-card-link rounded-full" asChild>
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ export function ExperienceCards() {
|
|||
<div className="mt-12 grid gap-6 md:grid-cols-3">
|
||||
{experiences.map((exp, i) => (
|
||||
<ScrollReveal key={exp.id} variant="card" delay={i * 90} as="div">
|
||||
<Card className="topo-card-surface overflow-hidden border-0 bg-white text-[#1a5c38]">
|
||||
<Card className="topo-card-surface overflow-hidden border-0 bg-white text-[#37a47a]">
|
||||
<div className="relative h-48">
|
||||
<Image
|
||||
src="/branding/booth-mockup.png"
|
||||
|
|
@ -32,11 +32,11 @@ export function ExperienceCards() {
|
|||
/>
|
||||
</div>
|
||||
<CardHeader>
|
||||
<p className="text-xs font-medium uppercase text-[#3d5248]">
|
||||
<p className="text-xs font-medium uppercase text-[#5b5b5b]">
|
||||
Day {i + 1}
|
||||
</p>
|
||||
<CardTitle>{exp.title}</CardTitle>
|
||||
<CardDescription className="text-[#3d5248]">{exp.description}</CardDescription>
|
||||
<CardDescription className="text-[#5b5b5b]">{exp.description}</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Button
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@ export function Faq() {
|
|||
{faqs.map((faq, i) => (
|
||||
<AccordionItem key={faq.id} value={faq.id}>
|
||||
<AccordionTrigger className="text-left">
|
||||
<span className="mr-3 text-[#ffb300]">{String(i + 1).padStart(2, "0")}.</span>
|
||||
<span className="mr-3 text-[#37a47a]">{String(i + 1).padStart(2, "0")}.</span>
|
||||
{faq.question}
|
||||
</AccordionTrigger>
|
||||
<AccordionContent className="text-[#3d5248]">{faq.answer}</AccordionContent>
|
||||
<AccordionContent className="text-[#5b5b5b]">{faq.answer}</AccordionContent>
|
||||
</AccordionItem>
|
||||
))}
|
||||
</Accordion>
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ export function Hero() {
|
|||
<div className="topo-content-layer topo-content-readable relative z-20 mx-auto flex min-h-[min(100svh,900px)] w-full max-w-6xl flex-col items-center justify-center px-4 py-24 text-center md:px-6">
|
||||
<TopoProseSurface className="mx-auto flex w-full max-w-4xl flex-col items-center text-center">
|
||||
<ScrollReveal immediate variant="fade-up" delay={0}>
|
||||
<p className="text-xs font-semibold uppercase tracking-[0.2em] text-[#1a5c38]/80 md:text-sm">
|
||||
<p className="text-xs font-semibold uppercase tracking-[0.2em] text-[#37a47a]/80 md:text-sm">
|
||||
{site.dates.label} · {site.venue.address}
|
||||
</p>
|
||||
</ScrollReveal>
|
||||
|
|
@ -92,18 +92,18 @@ export function Hero() {
|
|||
<ScrollReveal immediate variant="fade-up" delay={200}>
|
||||
<h1
|
||||
className={cn(
|
||||
"rift-hero-heading rift-hero-title mt-6 font-display text-3xl font-bold leading-[1.05] tracking-tight text-[#0d3d26] sm:text-4xl md:text-5xl lg:text-6xl"
|
||||
"rift-hero-heading rift-hero-title mt-6 font-display text-3xl font-bold leading-[1.05] tracking-tight text-[#30614c] sm:text-4xl md:text-5xl lg:text-6xl"
|
||||
)}
|
||||
>
|
||||
<span className="font-wordmark block uppercase tracking-wide">
|
||||
Great Rift Valley
|
||||
</span>
|
||||
<span className="mt-1 block text-[#ffb300]">Innovation Summit</span>
|
||||
<span className="mt-1 block text-[#37a47a]">Innovation Summit</span>
|
||||
</h1>
|
||||
</ScrollReveal>
|
||||
|
||||
<ScrollReveal immediate variant="fade-up" delay={400}>
|
||||
<p className="mx-auto mt-6 max-w-2xl text-lg text-[#1a5c38]/80 md:text-xl">
|
||||
<p className="mx-auto mt-6 max-w-2xl text-lg text-[#37a47a]/80 md:text-xl">
|
||||
{site.tagline} Presented by {site.presentedBy}.
|
||||
</p>
|
||||
</ScrollReveal>
|
||||
|
|
@ -111,7 +111,7 @@ export function Hero() {
|
|||
<ScrollReveal immediate variant="fade-up" delay={500}>
|
||||
<div className="mt-8 flex flex-wrap items-center justify-center gap-3">
|
||||
<Button
|
||||
className="rounded-full bg-[#ffb300] px-8 text-[#0f0404] hover:bg-[#ffb300]/90"
|
||||
className="rounded-full bg-[#37a47a] px-8 text-[#ffffff] hover:bg-[#37a47a]/90"
|
||||
asChild
|
||||
>
|
||||
<Link href={site.links.pitchApplyUrl}>
|
||||
|
|
@ -120,13 +120,13 @@ export function Hero() {
|
|||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
className="rounded-full border-[#1a5c38]/30 bg-white/80 text-[#1a5c38] backdrop-blur-sm"
|
||||
className="rounded-full border-[#37a47a]/30 bg-white/80 text-[#37a47a] backdrop-blur-sm"
|
||||
asChild
|
||||
>
|
||||
<Link href="/payment">Get tickets</Link>
|
||||
</Button>
|
||||
</div>
|
||||
<p className="mt-4 text-sm text-[#1a5c38]/70">
|
||||
<p className="mt-4 text-sm text-[#37a47a]/70">
|
||||
<HeroGrantLine />
|
||||
</p>
|
||||
</ScrollReveal>
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ export function LastYearWinnerMark({
|
|||
type="button"
|
||||
data-winner-interactive
|
||||
className={cn(
|
||||
"shrink-0 rounded-lg outline-none focus-visible:ring-2 focus-visible:ring-[#1a5c38]/40",
|
||||
"shrink-0 rounded-lg outline-none focus-visible:ring-2 focus-visible:ring-[#37a47a]/40",
|
||||
isOpen && "relative z-30"
|
||||
)}
|
||||
aria-label={
|
||||
|
|
@ -98,14 +98,14 @@ export function LastYearWinnerMark({
|
|||
className={cn(
|
||||
"flex h-10 shrink-0 items-center gap-2 rounded-lg border px-2.5 shadow-sm transition-colors",
|
||||
onLight
|
||||
? "border-[#1a5c38]/15 bg-white/95 hover:border-[#1a5c38]/30 hover:bg-white"
|
||||
? "border-[#37a47a]/15 bg-white/95 hover:border-[#37a47a]/30 hover:bg-white"
|
||||
: "border-white/25 bg-white/90 hover:border-white/50 hover:bg-white",
|
||||
logoOnly && "px-2",
|
||||
isOpen &&
|
||||
(onLight
|
||||
? "border-[#1a5c38]/40 ring-2 ring-[#1a5c38]/15"
|
||||
? "border-[#37a47a]/40 ring-2 ring-[#37a47a]/15"
|
||||
: "border-white/60 ring-2 ring-white/25"),
|
||||
isPinned && "border-[#ffb300]/70 ring-2 ring-[#ffb300]/25",
|
||||
isPinned && "border-[#37a47a]/70 ring-2 ring-[#37a47a]/25",
|
||||
className
|
||||
)}
|
||||
>
|
||||
|
|
@ -120,7 +120,7 @@ export function LastYearWinnerMark({
|
|||
onError={() => setFailed(true)}
|
||||
/>
|
||||
) : company.initials ? (
|
||||
<span className="text-[10px] font-bold leading-none text-[#1a5c38]">
|
||||
<span className="text-[10px] font-bold leading-none text-[#37a47a]">
|
||||
{company.initials}
|
||||
</span>
|
||||
) : (
|
||||
|
|
@ -134,7 +134,7 @@ export function LastYearWinnerMark({
|
|||
)}
|
||||
</div>
|
||||
{company.name ? (
|
||||
<span className="max-w-[7.5rem] truncate text-[11px] font-medium text-[#1a5c38]">
|
||||
<span className="max-w-[7.5rem] truncate text-[11px] font-medium text-[#37a47a]">
|
||||
{company.name}
|
||||
</span>
|
||||
) : null}
|
||||
|
|
@ -148,7 +148,7 @@ export function LastYearWinnerMark({
|
|||
sideOffset={8}
|
||||
collisionPadding={12}
|
||||
data-winner-interactive
|
||||
className="z-50 w-72 max-w-[calc(100vw-2rem)] shrink-0 overflow-hidden border-[#1a5c38]/15 bg-white p-0 shadow-lg"
|
||||
className="z-50 w-72 max-w-[calc(100vw-2rem)] shrink-0 overflow-hidden border-[#37a47a]/15 bg-white p-0 shadow-lg"
|
||||
onMouseEnter={handleEnter}
|
||||
onMouseLeave={handleLeave}
|
||||
onOpenAutoFocus={(e) => e.preventDefault()}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ function FounderPhoto({ company }: { company: LastYearWinner }) {
|
|||
alt=""
|
||||
width={48}
|
||||
height={48}
|
||||
className="size-12 shrink-0 rounded-full border-2 border-[#1a5c38]/15 object-cover"
|
||||
className="size-12 shrink-0 rounded-full border-2 border-[#37a47a]/15 object-cover"
|
||||
onError={() => setFailed(true)}
|
||||
/>
|
||||
);
|
||||
|
|
@ -49,7 +49,7 @@ function FounderPhoto({ company }: { company: LastYearWinner }) {
|
|||
|
||||
return (
|
||||
<div
|
||||
className="flex size-12 shrink-0 items-center justify-center rounded-full border-2 border-[#1a5c38]/15 bg-[#f0f5f2] text-sm font-bold text-[#1a5c38]"
|
||||
className="flex size-12 shrink-0 items-center justify-center rounded-full border-2 border-[#37a47a]/15 bg-[#e8f2ec] text-sm font-bold text-[#37a47a]"
|
||||
aria-hidden
|
||||
>
|
||||
{initials}
|
||||
|
|
@ -72,24 +72,24 @@ export function LastYearWinnerTip({ company, className, showClose, onClose }: Pr
|
|||
<div className="flex min-w-0 gap-2.5 px-3 pt-3 pb-2">
|
||||
<FounderPhoto company={company} />
|
||||
<div className="min-w-0 flex-1">
|
||||
<p className="truncate text-[11px] font-semibold uppercase tracking-wider text-[#1a5c38]">
|
||||
<p className="truncate text-[11px] font-semibold uppercase tracking-wider text-[#37a47a]">
|
||||
{name}
|
||||
</p>
|
||||
{company.founderName ? (
|
||||
<p className="truncate text-[10px] text-[#3d5248]/80">{company.founderName}</p>
|
||||
<p className="truncate text-[10px] text-[#5b5b5b]/80">{company.founderName}</p>
|
||||
) : null}
|
||||
<p className="mt-1 line-clamp-2 text-[11px] leading-snug text-[#3d5248]">
|
||||
<p className="mt-1 line-clamp-2 text-[11px] leading-snug text-[#5b5b5b]">
|
||||
{impact.summary}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{headline ? (
|
||||
<div className="mx-3 mb-2 overflow-hidden rounded-lg border border-[#1a5c38]/12 bg-[#f0f5f2] px-2.5 py-2 text-center">
|
||||
<p className="truncate text-[10px] font-bold uppercase tracking-wider text-[#1a5c38]/75">
|
||||
<div className="mx-3 mb-2 overflow-hidden rounded-lg border border-[#37a47a]/12 bg-[#e8f2ec] px-2.5 py-2 text-center">
|
||||
<p className="truncate text-[10px] font-bold uppercase tracking-wider text-[#37a47a]/75">
|
||||
{headline.label}
|
||||
</p>
|
||||
<p className="winner-impact-value mt-0.5 truncate font-display text-xl font-extrabold tracking-tight text-[#0d3d26]">
|
||||
<p className="winner-impact-value mt-0.5 truncate font-display text-xl font-extrabold tracking-tight text-[#30614c]">
|
||||
{headline.value}
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -99,10 +99,10 @@ export function LastYearWinnerTip({ company, className, showClose, onClose }: Pr
|
|||
<dl className="grid min-w-0 grid-cols-2 gap-1.5 px-3 pb-2">
|
||||
{supporting.map((m) => (
|
||||
<div key={m.label} className="min-w-0 rounded-md bg-[#f7faf8] px-1.5 py-1.5 text-center">
|
||||
<dt className="truncate text-[9px] font-semibold uppercase tracking-wide text-[#1a5c38]/65">
|
||||
<dt className="truncate text-[9px] font-semibold uppercase tracking-wide text-[#37a47a]/65">
|
||||
{m.label}
|
||||
</dt>
|
||||
<dd className="truncate text-xs font-bold text-[#0d3d26]">{m.value}</dd>
|
||||
<dd className="truncate text-xs font-bold text-[#30614c]">{m.value}</dd>
|
||||
</div>
|
||||
))}
|
||||
</dl>
|
||||
|
|
@ -111,7 +111,7 @@ export function LastYearWinnerTip({ company, className, showClose, onClose }: Pr
|
|||
{showFooter ? (
|
||||
<div
|
||||
className={cn(
|
||||
"flex w-full min-w-0 items-center gap-1.5 border-t border-[#1a5c38]/10 bg-[#f7faf8]/80 px-2.5 py-2",
|
||||
"flex w-full min-w-0 items-center gap-1.5 border-t border-[#37a47a]/10 bg-[#f7faf8]/80 px-2.5 py-2",
|
||||
showClose && onClose ? "justify-between" : "justify-end"
|
||||
)}
|
||||
>
|
||||
|
|
@ -120,7 +120,7 @@ export function LastYearWinnerTip({ company, className, showClose, onClose }: Pr
|
|||
type="button"
|
||||
data-winner-interactive
|
||||
onClick={onClose}
|
||||
className="inline-flex size-7 shrink-0 items-center justify-center rounded-full border border-[#1a5c38]/15 bg-white text-[#1a5c38] shadow-sm transition-colors hover:bg-[#f0f5f2]"
|
||||
className="inline-flex size-7 shrink-0 items-center justify-center rounded-full border border-[#37a47a]/15 bg-white text-[#37a47a] shadow-sm transition-colors hover:bg-[#e8f2ec]"
|
||||
aria-label="Close impact details"
|
||||
>
|
||||
<X className="size-3.5" aria-hidden />
|
||||
|
|
@ -131,7 +131,7 @@ export function LastYearWinnerTip({ company, className, showClose, onClose }: Pr
|
|||
<Button
|
||||
variant="outline"
|
||||
size="icon-sm"
|
||||
className="rounded-full border-[#1a5c38]/20 text-[#1a5c38] hover:bg-[#f0f5f2]"
|
||||
className="rounded-full border-[#37a47a]/20 text-[#37a47a] hover:bg-[#e8f2ec]"
|
||||
asChild
|
||||
>
|
||||
<Link href={viewHref} aria-label="View startup" {...externalLinkProps(viewHref)}>
|
||||
|
|
@ -142,7 +142,7 @@ export function LastYearWinnerTip({ company, className, showClose, onClose }: Pr
|
|||
{donateHref ? (
|
||||
<Button
|
||||
size="icon-sm"
|
||||
className="rounded-full bg-[#1a5c38] text-white hover:bg-[#0d3d26]"
|
||||
className="rounded-full bg-[#37a47a] text-white hover:bg-[#30614c]"
|
||||
asChild
|
||||
>
|
||||
<Link href={donateHref} aria-label="Donate" {...externalLinkProps(donateHref)}>
|
||||
|
|
|
|||
|
|
@ -61,13 +61,13 @@ export function LastYearWinnersScroll({ variant = "on-green", className }: Props
|
|||
<div
|
||||
className={cn(
|
||||
"pt-8",
|
||||
onLight ? "mt-8 border-t border-[#1a5c38]/12" : "mt-10 border-t border-white/15",
|
||||
onLight ? "mt-8 border-t border-[#37a47a]/12" : "mt-10 border-t border-white/15",
|
||||
className
|
||||
)}
|
||||
>
|
||||
<p
|
||||
className={cn(
|
||||
"text-center text-[10px] font-semibold uppercase tracking-[0.2em] text-[#ffb300]"
|
||||
"text-center text-[10px] font-semibold uppercase tracking-[0.2em] text-[#37a47a]"
|
||||
)}
|
||||
>
|
||||
{lastYearWinnersCopy.eyebrow}
|
||||
|
|
@ -75,13 +75,13 @@ export function LastYearWinnersScroll({ variant = "on-green", className }: Props
|
|||
<p
|
||||
className={cn(
|
||||
"mt-2 text-center text-lg font-bold tracking-tight md:text-xl",
|
||||
onLight ? "text-[#0d3d26]" : "text-white"
|
||||
onLight ? "text-[#30614c]" : "text-white"
|
||||
)}
|
||||
>
|
||||
{lastYearWinnersCopy.headline}
|
||||
</p>
|
||||
<p className="mt-2 text-center">
|
||||
<span className="inline-block rounded-full bg-white px-3 py-1 text-[11px] font-medium text-[#1a5c38] shadow-sm">
|
||||
<span className="inline-block rounded-full bg-white px-3 py-1 text-[11px] font-medium text-[#37a47a] shadow-sm">
|
||||
{lastYearWinnersCopy.hoverHint}
|
||||
</span>
|
||||
</p>
|
||||
|
|
@ -92,13 +92,13 @@ export function LastYearWinnersScroll({ variant = "on-green", className }: Props
|
|||
<div
|
||||
className={cn(
|
||||
"pointer-events-none absolute inset-y-0 left-0 z-10 w-10 bg-gradient-to-r to-transparent",
|
||||
onLight ? "from-white" : "from-[#1a5c38]"
|
||||
onLight ? "from-white" : "from-[#37a47a]"
|
||||
)}
|
||||
/>
|
||||
<div
|
||||
className={cn(
|
||||
"pointer-events-none absolute inset-y-0 right-0 z-10 w-10 bg-gradient-to-l to-transparent",
|
||||
onLight ? "from-white" : "from-[#1a5c38]"
|
||||
onLight ? "from-white" : "from-[#37a47a]"
|
||||
)}
|
||||
/>
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ export function Newsletter() {
|
|||
</div>
|
||||
<Button
|
||||
type="submit"
|
||||
className="rounded-full bg-[#ffb300] text-[#0f0404] hover:bg-[#ffb300]/90"
|
||||
className="rounded-full bg-[#37a47a] text-[#ffffff] hover:bg-[#37a47a]/90"
|
||||
disabled={status === "loading"}
|
||||
>
|
||||
{status === "loading" ? "Signing up…" : "Sign up"}
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@ export function PartnerMarquee() {
|
|||
const slots = Array.from({ length: 8 }, (_, i) => i);
|
||||
|
||||
return (
|
||||
<section className="section-white relative overflow-hidden border-y border-border bg-white py-8 text-[#0d3d26]">
|
||||
<section className="section-white relative overflow-hidden border-y border-border bg-white py-8 text-[#30614c]">
|
||||
<WavyContourLinesBackground className="z-0" />
|
||||
<p className="relative z-10 mb-6 text-center text-xs font-semibold uppercase tracking-widest text-[#3d5248]">
|
||||
<p className="relative z-10 mb-6 text-center text-xs font-semibold uppercase tracking-widest text-[#5b5b5b]">
|
||||
With the support of
|
||||
</p>
|
||||
<div className="relative z-10 overflow-hidden">
|
||||
|
|
|
|||
|
|
@ -7,18 +7,18 @@ export function PurposeBand() {
|
|||
<Section id="about">
|
||||
<div className="grid items-center gap-10 lg:grid-cols-2">
|
||||
<TopoProseSurface>
|
||||
<p className="text-xs font-semibold uppercase tracking-widest text-[#ffb300]">
|
||||
<p className="text-xs font-semibold uppercase tracking-widest text-[#37a47a]">
|
||||
About this summit
|
||||
</p>
|
||||
<h2 className="mt-3 text-3xl font-bold md:text-4xl">
|
||||
A first-of-its-kind gathering for Ethiopia's innovators
|
||||
</h2>
|
||||
<p className="mt-4 text-[#3d5248] leading-relaxed">
|
||||
<p className="mt-4 text-[#5b5b5b] leading-relaxed">
|
||||
The Great Rift Valley Innovation Summit, presented by the Ethiopian Diaspora Trust
|
||||
Fund (EDTF), convenes entrepreneurs, investors, companies, startups, and jobseekers to
|
||||
advance tech-enabled innovation in agriculture, healthcare, and education.
|
||||
</p>
|
||||
<p className="mt-4 text-[#3d5248] leading-relaxed">
|
||||
<p className="mt-4 text-[#5b5b5b] leading-relaxed">
|
||||
Programming includes an exhibitor hall, workshops and panel discussions, and the
|
||||
inaugural Great Rift Valley Pitch Competition—<PurposeGrantText /> Ten companies will
|
||||
be selected from the most impactful ventures.
|
||||
|
|
|
|||
|
|
@ -24,13 +24,13 @@ export function Speakers() {
|
|||
return (
|
||||
<Section id="speakers">
|
||||
<TopoProseSurface className="max-w-3xl">
|
||||
<p className="text-xs font-semibold uppercase tracking-widest text-[#ffb300]">
|
||||
<p className="text-xs font-semibold uppercase tracking-widest text-[#37a47a]">
|
||||
Lineup
|
||||
</p>
|
||||
<h2 className="mt-2 text-4xl font-bold tracking-tight md:text-5xl">
|
||||
Meet the voices of GRV Summit
|
||||
</h2>
|
||||
<p className="mt-4 text-[#3d5248] leading-relaxed">
|
||||
<p className="mt-4 text-[#5b5b5b] leading-relaxed">
|
||||
Keynotes, panelists, judges, and opening speakers — {site.dates.label} at{" "}
|
||||
{site.venue.name}.
|
||||
</p>
|
||||
|
|
@ -40,12 +40,12 @@ export function Speakers() {
|
|||
{(Object.entries(grouped) as [SpeakerGroup, typeof speakers][]).map(
|
||||
([group, list]) => (
|
||||
<div key={group}>
|
||||
<div className="mb-2 flex flex-wrap items-end justify-between gap-4 border-b border-[#1a5c38]/15 pb-4">
|
||||
<div className="mb-2 flex flex-wrap items-end justify-between gap-4 border-b border-[#37a47a]/15 pb-4">
|
||||
<div>
|
||||
<h3 className="text-2xl font-bold md:text-3xl">
|
||||
{speakerGroupLabels[group]}
|
||||
</h3>
|
||||
<p className="mt-1 text-sm text-[#3d5248]">{site.dates.label}</p>
|
||||
<p className="mt-1 text-sm text-[#5b5b5b]">{site.dates.label}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
|
||||
|
|
@ -59,7 +59,7 @@ export function Speakers() {
|
|||
</div>
|
||||
|
||||
<div className="mt-12 flex flex-wrap justify-center gap-3">
|
||||
<Button className="rounded-full bg-[#ffb300] text-[#0f0404] hover:bg-[#ffb300]/90" asChild>
|
||||
<Button className="rounded-full bg-[#37a47a] text-[#ffffff] hover:bg-[#37a47a]/90" asChild>
|
||||
<Link href="/program">View full program</Link>
|
||||
</Button>
|
||||
<Button variant="outline" className="rounded-full" asChild>
|
||||
|
|
|
|||
|
|
@ -10,13 +10,13 @@ export function SponsorTiers() {
|
|||
return (
|
||||
<Section id="partners">
|
||||
<TopoProseSurface className="mx-auto max-w-3xl text-center">
|
||||
<p className="text-xs font-semibold uppercase tracking-widest text-[#ffb300]">
|
||||
<p className="text-xs font-semibold uppercase tracking-widest text-[#37a47a]">
|
||||
Partners
|
||||
</p>
|
||||
<h2 className="mt-2 text-3xl font-bold text-[#0d3d26] md:text-4xl">
|
||||
<h2 className="mt-2 text-3xl font-bold text-[#30614c] md:text-4xl">
|
||||
Partners & sponsors
|
||||
</h2>
|
||||
<p className="mt-3 text-[#3d5248]">
|
||||
<p className="mt-3 text-[#5b5b5b]">
|
||||
Logo slots below are open — partner with GRV Summit and feature your brand here.
|
||||
</p>
|
||||
</TopoProseSurface>
|
||||
|
|
@ -24,7 +24,7 @@ export function SponsorTiers() {
|
|||
{partnerTiers.slice(0, 2).map((tier) => (
|
||||
<div key={tier.id}>
|
||||
<Separator className="mb-6" />
|
||||
<h3 className="text-center text-sm font-semibold uppercase tracking-wider text-[#1a5c38]">
|
||||
<h3 className="text-center text-sm font-semibold uppercase tracking-wider text-[#37a47a]">
|
||||
{tier.name}
|
||||
</h3>
|
||||
<div className="mt-6 flex flex-wrap items-center justify-center gap-6">
|
||||
|
|
@ -32,7 +32,7 @@ export function SponsorTiers() {
|
|||
<PartnerLogoPlaceholder
|
||||
key={`${tier.id}-${i}`}
|
||||
size="md"
|
||||
className="border-[#1a5c38]/20 bg-[#f0f5f2] text-[#1a5c38]/50"
|
||||
className="border-[#37a47a]/20 bg-[#e8f2ec] text-[#37a47a]/50"
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
|
@ -40,7 +40,7 @@ export function SponsorTiers() {
|
|||
))}
|
||||
</div>
|
||||
<div className="mt-10 text-center">
|
||||
<Button className="rounded-full bg-[#ffb300] text-[#0f0404] hover:bg-[#ffb300]/90" asChild>
|
||||
<Button className="rounded-full bg-[#37a47a] text-[#ffffff] hover:bg-[#37a47a]/90" asChild>
|
||||
<Link href="/partners">Become a partner</Link>
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ export function StatsGrid() {
|
|||
return (
|
||||
<Section variant="muted" id="stats">
|
||||
<TopoProseSurface className="topo-on-green-bg mx-auto max-w-3xl text-center">
|
||||
<p className="text-xs font-semibold uppercase tracking-widest text-[#ffb300]">
|
||||
<p className="text-xs font-semibold uppercase tracking-widest text-[#b9d8c9]">
|
||||
The future starts here
|
||||
</p>
|
||||
<h2 className="mt-3 text-3xl font-bold text-white md:text-4xl">
|
||||
|
|
@ -17,18 +17,18 @@ export function StatsGrid() {
|
|||
{site.stats.map((stat) => (
|
||||
<div
|
||||
key={stat.label}
|
||||
className="topo-card-surface rounded-2xl border border-border bg-white p-6 text-center text-[#1a5c38] shadow-sm"
|
||||
className="topo-card-surface rounded-2xl border border-border bg-white p-6 text-center text-[#37a47a] shadow-sm"
|
||||
>
|
||||
{stat.type === "cycling" ? (
|
||||
<CyclingGrantAmount
|
||||
showCaption
|
||||
valueClassName="text-3xl font-bold text-[#1a5c38] md:text-4xl"
|
||||
captionClassName="text-[#3d5248]"
|
||||
valueClassName="text-3xl font-bold text-[#37a47a] md:text-4xl"
|
||||
captionClassName="text-[#5b5b5b]"
|
||||
/>
|
||||
) : (
|
||||
<p className="text-3xl font-bold text-[#1a5c38] md:text-4xl">{stat.value}</p>
|
||||
<p className="text-3xl font-bold text-[#37a47a] md:text-4xl">{stat.value}</p>
|
||||
)}
|
||||
<p className="mt-2 text-sm text-[#3d5248]">{stat.label}</p>
|
||||
<p className="mt-2 text-sm text-[#5b5b5b]">{stat.label}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ export function TicketsBand() {
|
|||
return (
|
||||
<Section variant="inverse" id="tickets">
|
||||
<div className="relative text-center">
|
||||
<p className="text-xs font-semibold uppercase tracking-widest text-[#ffb300]">
|
||||
<p className="text-xs font-semibold uppercase tracking-widest text-[#b9d8c9]">
|
||||
Tickets
|
||||
</p>
|
||||
<h2 className="mt-2 text-3xl font-bold uppercase tracking-tight md:text-4xl">
|
||||
|
|
@ -31,7 +31,7 @@ export function TicketsBand() {
|
|||
|
||||
<p className="mt-10 text-center text-sm text-white/50">
|
||||
Accepted: Visa, Mastercard, AMEX ·{" "}
|
||||
<Link href="/payment" className="text-[#ffb300] hover:underline">
|
||||
<Link href="/payment" className="text-[#b9d8c9] hover:underline">
|
||||
Bank transfer & invoice
|
||||
</Link>
|
||||
</p>
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ export function TopicMarquee() {
|
|||
return (
|
||||
<Section id="topics" className="overflow-hidden py-12">
|
||||
<TopoProseSurface className="mx-auto mb-8 max-w-3xl text-center">
|
||||
<p className="text-xs font-semibold uppercase tracking-widest text-[#ffb300]">
|
||||
<p className="text-xs font-semibold uppercase tracking-widest text-[#37a47a]">
|
||||
Program themes
|
||||
</p>
|
||||
<h2 className="mt-2 text-2xl font-bold text-[#0d3d26] md:text-3xl">
|
||||
<h2 className="mt-2 text-2xl font-bold text-[#30614c] md:text-3xl">
|
||||
Topics shaping the summit
|
||||
</h2>
|
||||
</TopoProseSurface>
|
||||
|
|
@ -21,7 +21,7 @@ export function TopicMarquee() {
|
|||
<Badge
|
||||
key={`${topic}-${i}`}
|
||||
variant="secondary"
|
||||
className="shrink-0 rounded-full border border-[#1a5c38]/15 bg-[#f0f5f2] px-4 py-2 text-sm text-[#1a5c38]"
|
||||
className="shrink-0 rounded-full border border-[#37a47a]/15 bg-[#e8f2ec] px-4 py-2 text-sm text-[#37a47a]"
|
||||
>
|
||||
{topic}
|
||||
</Badge>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ export function Venue() {
|
|||
<Section id="venue" variant="muted">
|
||||
<div className="grid gap-8 lg:grid-cols-2">
|
||||
<div className="topo-on-green-bg">
|
||||
<p className="text-xs font-semibold uppercase tracking-widest text-[#ffb300]">The venue</p>
|
||||
<p className="text-xs font-semibold uppercase tracking-widest text-[#b9d8c9]">The venue</p>
|
||||
<h2 className="mt-2 text-3xl font-bold text-white">{site.venue.name}</h2>
|
||||
<p className="mt-4 text-white/85">{site.venue.address}</p>
|
||||
<Button
|
||||
|
|
|
|||
|
|
@ -52,11 +52,11 @@ export function FooterNewsletter() {
|
|||
}
|
||||
|
||||
return (
|
||||
<div className="relative z-10 mx-auto max-w-5xl rounded-3xl border border-[#1a5c38]/14 bg-white p-6 shadow-md shadow-[#1a5c38]/6 md:p-10">
|
||||
<div className="relative z-10 mx-auto max-w-5xl rounded-3xl border border-[#37a47a]/14 bg-white p-6 shadow-md shadow-[#37a47a]/6 md:p-10">
|
||||
<div className="grid gap-8 lg:grid-cols-[1fr_1.2fr] lg:items-start">
|
||||
<div>
|
||||
<BrandLogo href={undefined} />
|
||||
<h2 className="mt-4 text-2xl font-bold text-[#0d3d26] md:text-3xl">Stay up to date!</h2>
|
||||
<h2 className="mt-4 text-2xl font-bold text-[#30614c] md:text-3xl">Stay up to date!</h2>
|
||||
<p className="mt-2 text-sm text-muted-foreground leading-relaxed">
|
||||
Get announcements about tickets, lineup, and the next Great Rift Valley Innovation
|
||||
Summit edition before anyone else.
|
||||
|
|
@ -91,11 +91,11 @@ export function FooterNewsletter() {
|
|||
/>
|
||||
{error && <p className="text-sm text-destructive">{error}</p>}
|
||||
{status === "done" && (
|
||||
<p className="text-sm text-[#1a5c38]">You're on the list — thank you!</p>
|
||||
<p className="text-sm text-[#37a47a]">You're on the list — thank you!</p>
|
||||
)}
|
||||
<Button
|
||||
type="submit"
|
||||
className="w-full rounded-full bg-[#1a5c38] text-white hover:bg-[#0d3d26] sm:w-auto"
|
||||
className="w-full rounded-full bg-[#37a47a] text-white hover:bg-[#30614c] sm:w-auto"
|
||||
disabled={status === "loading"}
|
||||
>
|
||||
{status === "loading" ? "Signing up…" : "Sign up"}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ export function FooterSocialLinks({ className }: Props) {
|
|||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
aria-label={label}
|
||||
className="inline-flex size-10 items-center justify-center rounded-full border border-[#1a5c38]/18 bg-[#f7faf8] text-[#1a5c38] shadow-sm transition-colors hover:border-[#1a5c38]/35 hover:bg-[#e8f2ec] hover:text-[#0d3d26]"
|
||||
className="inline-flex size-10 items-center justify-center rounded-full border border-[#37a47a]/18 bg-[#f7faf8] text-[#37a47a] shadow-sm transition-colors hover:border-[#37a47a]/35 hover:bg-[#e8f2ec] hover:text-[#30614c]"
|
||||
>
|
||||
<Icon className="size-[18px]" />
|
||||
</Link>
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ export function FooterSurface({ children, className }: Props) {
|
|||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"rounded-2xl border border-[#1a5c38]/14 bg-white p-6 shadow-md shadow-[#1a5c38]/6 md:p-8",
|
||||
"rounded-2xl border border-[#37a47a]/14 bg-white p-6 shadow-md shadow-[#37a47a]/6 md:p-8",
|
||||
className
|
||||
)}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ export function MobileNavDropdown({ open, onClose }: DropdownProps) {
|
|||
<Link
|
||||
href="/program"
|
||||
onClick={onClose}
|
||||
className="mt-1 block rounded-xl px-3 py-2.5 text-sm font-semibold text-[#ffb300] hover:bg-white/5"
|
||||
className="mt-1 block rounded-xl px-3 py-2.5 text-sm font-semibold text-[#b9d8c9] hover:bg-white/5"
|
||||
>
|
||||
View full program
|
||||
</Link>
|
||||
|
|
@ -138,7 +138,7 @@ export function MobileNavDropdown({ open, onClose }: DropdownProps) {
|
|||
>
|
||||
<span>{link.label}</span>
|
||||
{"badge" in link && link.badge && (
|
||||
<span className="rounded-md bg-[#ffb300] px-2 py-0.5 text-[10px] font-bold uppercase tracking-wide text-[#0f0404]">
|
||||
<span className="rounded-md bg-[#37a47a] px-2 py-0.5 text-[10px] font-bold uppercase tracking-wide text-[#ffffff]">
|
||||
{link.badge}
|
||||
</span>
|
||||
)}
|
||||
|
|
@ -152,7 +152,7 @@ export function MobileNavDropdown({ open, onClose }: DropdownProps) {
|
|||
onClick={onClose}
|
||||
className={cn(
|
||||
"flex h-12 min-w-0 flex-1 items-center justify-center rounded-full",
|
||||
"bg-white px-4 text-sm font-bold text-[#0f0404] transition-transform active:scale-[0.98]"
|
||||
"bg-white px-4 text-sm font-bold text-[#ffffff] transition-transform active:scale-[0.98]"
|
||||
)}
|
||||
>
|
||||
Apply to pitch
|
||||
|
|
|
|||
|
|
@ -32,10 +32,10 @@ export function TicketsMarqueeCta({
|
|||
onClick={onNavigate}
|
||||
aria-label={ariaLabel}
|
||||
className={cn(
|
||||
"relative flex items-center overflow-hidden rounded-full bg-[#ffb300] text-[#0f0404]",
|
||||
"shadow-md transition-colors hover:bg-[#ffb300]/90",
|
||||
"relative flex items-center overflow-hidden rounded-full bg-[#37a47a] text-[#ffffff]",
|
||||
"shadow-md transition-colors hover:bg-[#37a47a]/90",
|
||||
"[&:hover_.ticket-menu-marquee]:[animation-duration:6s]",
|
||||
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#ffb300] focus-visible:ring-offset-2",
|
||||
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#37a47a] focus-visible:ring-offset-2",
|
||||
className
|
||||
)}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ export function PageRiftHeader({
|
|||
return (
|
||||
<header
|
||||
className={cn(
|
||||
"section-white group/topo-section relative isolate min-h-[220px] overflow-x-hidden overflow-y-visible border-b border-[#1a5c38]/10 bg-white pt-24 pb-10 md:min-h-[260px] md:pb-12",
|
||||
"section-white group/topo-section relative isolate min-h-[220px] overflow-x-hidden overflow-y-visible border-b border-[#37a47a]/10 bg-white pt-24 pb-10 md:min-h-[260px] md:pb-12",
|
||||
className
|
||||
)}
|
||||
>
|
||||
|
|
@ -50,13 +50,13 @@ export function PageRiftHeader({
|
|||
<div className="topo-content-layer topo-content-readable relative z-10 mx-auto max-w-6xl px-4 pt-4 md:px-6">
|
||||
<TopoProseSurface className="max-w-3xl">
|
||||
{eyebrow && (
|
||||
<p className="text-xs font-semibold uppercase tracking-widest text-[#ffb300]">
|
||||
<p className="text-xs font-semibold uppercase tracking-widest text-[#37a47a]">
|
||||
{eyebrow}
|
||||
</p>
|
||||
)}
|
||||
<div className="mt-3">{title}</div>
|
||||
{description && (
|
||||
<div className="mt-4 text-[#3d5248] leading-relaxed">{description}</div>
|
||||
<div className="mt-4 text-[#5b5b5b] leading-relaxed">{description}</div>
|
||||
)}
|
||||
</TopoProseSurface>
|
||||
{children && <div className="relative z-[15] mt-8">{children}</div>}
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@ export function Section({
|
|||
id={id}
|
||||
className={cn(
|
||||
"group/topo-section relative isolate py-16 md:py-24",
|
||||
isGreen && "section-green bg-[#1a5c38]",
|
||||
!isGreen && "section-white bg-white text-[#0d3d26]",
|
||||
isGreen && "section-green bg-primary",
|
||||
!isGreen && "section-white bg-white text-[#30614c]",
|
||||
!isGreen && "overflow-x-hidden overflow-y-visible",
|
||||
isGreen && "overflow-hidden",
|
||||
className
|
||||
|
|
|
|||
|
|
@ -58,14 +58,14 @@ export function SiteEntryPrompt() {
|
|||
aria-labelledby="entry-consent-title"
|
||||
aria-describedby="entry-consent-desc"
|
||||
className={cn(
|
||||
"fixed bottom-4 right-4 z-[200] w-[min(calc(100vw-2rem),24rem)] rounded-2xl border border-[#1a5c38]/15 bg-white p-5 shadow-[0_12px_40px_rgba(13,61,38,0.18)] transition-all duration-500 ease-out",
|
||||
"fixed bottom-4 right-4 z-[200] w-[min(calc(100vw-2rem),24rem)] rounded-2xl border border-[#37a47a]/15 bg-white p-5 shadow-[0_12px_40px_rgba(13,61,38,0.18)] transition-all duration-500 ease-out",
|
||||
visible ? "translate-y-0 opacity-100" : "translate-y-3 opacity-0"
|
||||
)}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleDecline}
|
||||
className="absolute top-3 right-3 rounded-full p-1 text-[#3d5248] transition-colors hover:bg-[#1a5c38]/8 hover:text-[#0d3d26]"
|
||||
className="absolute top-3 right-3 rounded-full p-1 text-[#5b5b5b] transition-colors hover:bg-[#37a47a]/8 hover:text-[#30614c]"
|
||||
aria-label="Decline and close"
|
||||
>
|
||||
<X className="size-4" />
|
||||
|
|
@ -73,29 +73,29 @@ export function SiteEntryPrompt() {
|
|||
|
||||
<h2
|
||||
id="entry-consent-title"
|
||||
className="pr-6 text-lg font-bold leading-snug text-[#0d3d26]"
|
||||
className="pr-6 text-lg font-bold leading-snug text-[#30614c]"
|
||||
>
|
||||
{copy.title}
|
||||
</h2>
|
||||
<p id="entry-consent-desc" className="mt-2 text-sm leading-relaxed text-[#3d5248]">
|
||||
<p id="entry-consent-desc" className="mt-2 text-sm leading-relaxed text-[#5b5b5b]">
|
||||
{copy.description}
|
||||
</p>
|
||||
|
||||
<div className="mt-4 flex items-start gap-3 rounded-lg border border-[#1a5c38]/12 bg-[#f0f5f2]/80 p-3">
|
||||
<div className="mt-4 flex items-start gap-3 rounded-lg border border-[#37a47a]/12 bg-[#e8f2ec]/80 p-3">
|
||||
<Checkbox
|
||||
id="site-entry-consent"
|
||||
checked={checked}
|
||||
onCheckedChange={(v) => setChecked(v === true)}
|
||||
className="mt-0.5 border-[#1a5c38]/40 data-[state=checked]:border-[#1a5c38] data-[state=checked]:bg-[#1a5c38]"
|
||||
className="mt-0.5 border-[#37a47a]/40 data-[state=checked]:border-[#37a47a] data-[state=checked]:bg-[#37a47a]"
|
||||
/>
|
||||
<Label
|
||||
htmlFor="site-entry-consent"
|
||||
className="text-sm font-normal leading-snug text-[#3d5248]"
|
||||
className="text-sm font-normal leading-snug text-[#5b5b5b]"
|
||||
>
|
||||
{copy.checkboxLabel}{" "}
|
||||
<Link
|
||||
href={copy.privacyHref}
|
||||
className="font-medium text-[#1a5c38] underline underline-offset-2"
|
||||
className="font-medium text-[#37a47a] underline underline-offset-2"
|
||||
>
|
||||
{dataConsent.privacyLinkText}
|
||||
</Link>
|
||||
|
|
@ -108,7 +108,7 @@ export function SiteEntryPrompt() {
|
|||
type="button"
|
||||
disabled={!checked}
|
||||
onClick={handleAccept}
|
||||
className="rounded-full bg-[#1a5c38] text-white hover:bg-[#0d3d26] disabled:opacity-50"
|
||||
className="rounded-full bg-[#37a47a] text-white hover:bg-[#30614c] disabled:opacity-50"
|
||||
>
|
||||
{copy.acceptCta}
|
||||
</Button>
|
||||
|
|
@ -116,7 +116,7 @@ export function SiteEntryPrompt() {
|
|||
type="button"
|
||||
variant="outline"
|
||||
onClick={handleDecline}
|
||||
className="rounded-full border-[#1a5c38]/30 text-[#1a5c38] hover:bg-[#1a5c38]/6"
|
||||
className="rounded-full border-[#37a47a]/30 text-[#37a47a] hover:bg-[#37a47a]/6"
|
||||
>
|
||||
{copy.declineCta}
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ const footerColumns = [
|
|||
|
||||
export function SiteFooter() {
|
||||
return (
|
||||
<footer className="site-footer section-white relative overflow-hidden bg-white pt-8 text-[#0d3d26] md:pt-10">
|
||||
<footer className="site-footer section-white relative overflow-hidden bg-white pt-8 text-[#30614c] md:pt-10">
|
||||
<GeometricMessBackground />
|
||||
|
||||
<div className="relative z-10 space-y-6 px-4 pb-12 md:space-y-8 md:px-6">
|
||||
|
|
@ -57,13 +57,13 @@ export function SiteFooter() {
|
|||
<div className="grid gap-10 sm:grid-cols-2 lg:grid-cols-4">
|
||||
{footerColumns.map((col) => (
|
||||
<div key={col.title}>
|
||||
<h3 className="text-sm font-semibold text-[#1a5c38]">{col.title}</h3>
|
||||
<h3 className="text-sm font-semibold text-[#37a47a]">{col.title}</h3>
|
||||
<ul className="mt-4 space-y-2.5">
|
||||
{col.links.map((link) => (
|
||||
<li key={link.href}>
|
||||
<Link
|
||||
href={link.href}
|
||||
className="text-sm text-[#3d5248] transition-colors hover:text-[#0d3d26]"
|
||||
className="text-sm text-[#5b5b5b] transition-colors hover:text-[#30614c]"
|
||||
{...("external" in link && link.external
|
||||
? { target: "_blank", rel: "noopener noreferrer" }
|
||||
: {})}
|
||||
|
|
@ -77,9 +77,9 @@ export function SiteFooter() {
|
|||
))}
|
||||
</div>
|
||||
|
||||
<div className="mt-10 flex flex-col gap-6 border-t border-[#1a5c38]/12 pt-8 sm:flex-row sm:items-center sm:justify-between">
|
||||
<div className="mt-10 flex flex-col gap-6 border-t border-[#37a47a]/12 pt-8 sm:flex-row sm:items-center sm:justify-between">
|
||||
<div>
|
||||
<p className="text-xs font-semibold uppercase tracking-widest text-[#1a5c38]">
|
||||
<p className="text-xs font-semibold uppercase tracking-widest text-[#37a47a]">
|
||||
Follow us
|
||||
</p>
|
||||
<FooterSocialLinks className="mt-4" />
|
||||
|
|
@ -89,7 +89,7 @@ export function SiteFooter() {
|
|||
|
||||
<FooterSurface className="mt-6 py-5 md:py-6">
|
||||
<div className="flex flex-col items-center justify-between gap-4 sm:flex-row">
|
||||
<p className="text-center text-xs font-medium uppercase tracking-wider text-[#3d5248] sm:text-left">
|
||||
<p className="text-center text-xs font-medium uppercase tracking-wider text-[#5b5b5b] sm:text-left">
|
||||
{site.shortName} · {site.dates.label} · Presented by {site.presentedBy}
|
||||
</p>
|
||||
<p className="text-center text-xs text-[#5c6b62] sm:text-right">
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ const navPills = [
|
|||
];
|
||||
|
||||
const pillClass =
|
||||
"inline-flex items-center gap-1.5 rounded-full bg-[#1a5c38]/10 px-4 py-2 text-sm font-medium text-[#0d3d26] transition-colors hover:bg-[#1a5c38]/15";
|
||||
"inline-flex items-center gap-1.5 rounded-full bg-[#37a47a]/10 px-4 py-2 text-sm font-medium text-[#30614c] transition-colors hover:bg-[#37a47a]/15";
|
||||
|
||||
export function SiteHeader() {
|
||||
const [mobileOpen, setMobileOpen] = useState(false);
|
||||
|
|
@ -34,8 +34,8 @@ export function SiteHeader() {
|
|||
<div
|
||||
className={cn(
|
||||
"flex items-center gap-2 rounded-full",
|
||||
"border border-[#1a5c38]/10 bg-white/95 px-2 py-2",
|
||||
"shadow-lg shadow-[#1a5c38]/10 backdrop-blur-md"
|
||||
"border border-[#37a47a]/10 bg-white/95 px-2 py-2",
|
||||
"shadow-lg shadow-[#37a47a]/10 backdrop-blur-md"
|
||||
)}
|
||||
>
|
||||
<BrandLogo className="min-w-0 shrink pl-0.5" compact />
|
||||
|
|
@ -62,7 +62,7 @@ export function SiteHeader() {
|
|||
<DropdownMenuItem asChild>
|
||||
<Link
|
||||
href="/pitch-competition"
|
||||
className="mt-1 cursor-pointer rounded-xl bg-[#1a5c38] p-3 text-white"
|
||||
className="mt-1 cursor-pointer rounded-xl bg-[#37a47a] p-3 text-white"
|
||||
>
|
||||
Pitch Competition
|
||||
</Link>
|
||||
|
|
@ -74,7 +74,7 @@ export function SiteHeader() {
|
|||
<Link key={link.href} href={link.href} className={pillClass}>
|
||||
{link.label}
|
||||
{link.badge && (
|
||||
<span className="rounded bg-[#1a5c38] px-1.5 py-0.5 text-[10px] font-bold uppercase tracking-wide text-white">
|
||||
<span className="rounded bg-[#37a47a] px-1.5 py-0.5 text-[10px] font-bold uppercase tracking-wide text-white">
|
||||
{link.badge}
|
||||
</span>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -156,11 +156,11 @@ export function ChampionStartupModal() {
|
|||
/>
|
||||
{error && <p className="text-sm text-destructive">{error}</p>}
|
||||
{status === "success" && (
|
||||
<p className="text-sm text-[#1a5c38]">Thank you for championing this startup!</p>
|
||||
<p className="text-sm text-[#37a47a]">Thank you for championing this startup!</p>
|
||||
)}
|
||||
<Button
|
||||
type="submit"
|
||||
className="w-full rounded-full bg-[#1f3d7e] hover:bg-[#1f3d7e]/90"
|
||||
className="w-full rounded-full bg-[#30614c] hover:bg-[#30614c]/90"
|
||||
disabled={status === "loading"}
|
||||
>
|
||||
{status === "loading" ? "Submitting…" : "Submit recommendation"}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ type Props = {
|
|||
|
||||
export function PartnerCard({ partner, tierLabel }: Props) {
|
||||
return (
|
||||
<Card className="topo-card-surface h-full border-border/80 bg-white text-[#1a5c38]">
|
||||
<Card className="topo-card-surface h-full border-border/80 bg-white text-[#37a47a]">
|
||||
{tierLabel && (
|
||||
<p className="px-6 pt-6 text-xs font-semibold uppercase tracking-widest text-muted-foreground">
|
||||
{tierLabel}
|
||||
|
|
@ -20,7 +20,7 @@ export function PartnerCard({ partner, tierLabel }: Props) {
|
|||
<CardHeader className={tierLabel ? "pt-2" : undefined}>
|
||||
<PartnerLogoPlaceholder
|
||||
size="lg"
|
||||
className="w-full border-[#1a5c38]/20 bg-[#f0f5f2] text-[#1a5c38]/50"
|
||||
className="w-full border-[#37a47a]/20 bg-[#e8f2ec] text-[#37a47a]/50"
|
||||
/>
|
||||
</CardHeader>
|
||||
<CardContent className="flex flex-1 flex-col">
|
||||
|
|
|
|||
|
|
@ -12,14 +12,14 @@ export function PartnerSectionBlock({ section, showTitle = true }: Props) {
|
|||
<div className="space-y-8">
|
||||
{showTitle && (
|
||||
<>
|
||||
<h2 className="text-3xl font-bold tracking-tight text-[#0d3d26]">
|
||||
<h2 className="text-3xl font-bold tracking-tight text-[#30614c]">
|
||||
{section.title}
|
||||
</h2>
|
||||
<Separator />
|
||||
</>
|
||||
)}
|
||||
{section.tierLabel && (
|
||||
<p className="text-xs font-semibold uppercase tracking-widest text-[#1a5c38]">
|
||||
<p className="text-xs font-semibold uppercase tracking-widest text-[#37a47a]">
|
||||
{section.tierLabel}
|
||||
</p>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ export function PartnershipCtaBand() {
|
|||
return (
|
||||
<section
|
||||
id="partnership-form"
|
||||
className="group/topo-section section-green relative isolate overflow-hidden bg-[#1a5c38] py-16 md:py-24"
|
||||
className="group/topo-section section-green relative isolate overflow-hidden bg-[#37a47a] py-16 md:py-24"
|
||||
>
|
||||
<RoundedRockVoronoiBackground className="z-0" />
|
||||
<TopoSectionProvider tone="green">
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ export function PartnershipInquiryForm() {
|
|||
}
|
||||
|
||||
return (
|
||||
<div className="topo-card-surface rounded-2xl bg-white p-6 text-[#1a5c38] shadow-xl md:p-8">
|
||||
<div className="topo-card-surface rounded-2xl bg-white p-6 text-[#37a47a] shadow-xl md:p-8">
|
||||
<h3 className="text-xl font-bold text-foreground">Request Partnership Information</h3>
|
||||
<form onSubmit={onSubmit} className="mt-6 space-y-4">
|
||||
<div className="grid gap-4 sm:grid-cols-2">
|
||||
|
|
@ -105,13 +105,13 @@ export function PartnershipInquiryForm() {
|
|||
/>
|
||||
{error && <p className="text-sm text-destructive">{error}</p>}
|
||||
{status === "success" && (
|
||||
<p className="text-sm text-[#1a5c38]">
|
||||
<p className="text-sm text-[#37a47a]">
|
||||
Thank you! We received your request and will be in touch.
|
||||
</p>
|
||||
)}
|
||||
<Button
|
||||
type="submit"
|
||||
className="w-full rounded-lg bg-[#ffb300] py-6 text-base font-semibold text-[#0f0404] hover:bg-[#ffb300]/90"
|
||||
className="w-full rounded-lg bg-[#37a47a] py-6 text-base font-semibold text-[#ffffff] hover:bg-[#37a47a]/90"
|
||||
disabled={status === "loading"}
|
||||
>
|
||||
{status === "loading" ? "Sending…" : "Next"}
|
||||
|
|
|
|||
|
|
@ -87,13 +87,13 @@ export function PaymentForm() {
|
|||
className={cn(
|
||||
"rounded-xl border p-4 text-left transition-colors",
|
||||
ticketId === t.id
|
||||
? "border-[#1f3d7e] bg-[#1f3d7e]/5 ring-2 ring-[#1f3d7e]"
|
||||
: "border-border hover:border-[#1f3d7e]/40",
|
||||
? "border-[#30614c] bg-[#30614c]/5 ring-2 ring-[#30614c]"
|
||||
: "border-border hover:border-[#30614c]/40",
|
||||
t.soldOut && "opacity-50"
|
||||
)}
|
||||
>
|
||||
<p className="font-semibold">{t.name}</p>
|
||||
<p className="mt-1 text-lg font-bold text-[#1f3d7e]">${t.priceUsd}</p>
|
||||
<p className="mt-1 text-lg font-bold text-[#30614c]">${t.priceUsd}</p>
|
||||
{t.soldOut && <p className="text-xs text-destructive">Sold out</p>}
|
||||
</button>
|
||||
))}
|
||||
|
|
@ -132,7 +132,7 @@ export function PaymentForm() {
|
|||
className={cn(
|
||||
"rounded-xl border p-4 text-left",
|
||||
paymentMethod === m.id
|
||||
? "border-[#ffb300] ring-2 ring-[#ffb300]"
|
||||
? "border-[#37a47a] ring-2 ring-[#37a47a]"
|
||||
: "border-border"
|
||||
)}
|
||||
>
|
||||
|
|
@ -191,12 +191,12 @@ export function PaymentForm() {
|
|||
</div>
|
||||
<div className="mt-2 flex justify-between text-lg font-bold">
|
||||
<span>Total</span>
|
||||
<span className="text-[#1f3d7e]">${total} USD</span>
|
||||
<span className="text-[#30614c]">${total} USD</span>
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
type="submit"
|
||||
className="w-full rounded-full bg-[#ffb300] text-[#0f0404] hover:bg-[#ffb300]/90"
|
||||
className="w-full rounded-full bg-[#37a47a] text-[#ffffff] hover:bg-[#37a47a]/90"
|
||||
disabled={status === "loading" || tier.soldOut}
|
||||
>
|
||||
{status === "loading"
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ export function SpeakerCard({ speaker, className, revealDelay = 0 }: Props) {
|
|||
<ScrollReveal variant="card" delay={revealDelay} as="div" className={className}>
|
||||
<Link
|
||||
href="/speakers"
|
||||
className="topo-card-surface topo-card-layer group relative z-20 isolate block overflow-hidden rounded-2xl border border-border bg-white p-4 text-[#1a5c38] shadow-sm transition-all hover:border-[#1a5c38]/25 hover:shadow-md"
|
||||
className="topo-card-surface topo-card-layer group relative z-20 isolate block overflow-hidden rounded-2xl border border-border bg-white p-4 text-[#37a47a] shadow-sm transition-all hover:border-[#37a47a]/25 hover:shadow-md"
|
||||
>
|
||||
<div className="relative mx-auto aspect-[4/5] w-full max-h-[220px] overflow-hidden rounded-xl bg-muted/30">
|
||||
<Image
|
||||
|
|
@ -24,13 +24,13 @@ export function SpeakerCard({ speaker, className, revealDelay = 0 }: Props) {
|
|||
sizes="(max-width: 768px) 50vw, 25vw"
|
||||
/>
|
||||
</div>
|
||||
<h3 className="mt-4 text-lg font-bold leading-tight text-[#0d3d26] group-hover:text-[#1a5c38]">
|
||||
<h3 className="mt-4 text-lg font-bold leading-tight text-[#30614c] group-hover:text-[#37a47a]">
|
||||
{speaker.name}
|
||||
</h3>
|
||||
<p className="mt-1 text-sm text-[#3d5248]">{speaker.title}</p>
|
||||
<p className="mt-0.5 text-sm font-medium text-[#1a5c38]/90">{speaker.company}</p>
|
||||
<p className="mt-1 text-sm text-[#5b5b5b]">{speaker.title}</p>
|
||||
<p className="mt-0.5 text-sm font-medium text-[#37a47a]/90">{speaker.company}</p>
|
||||
{speaker.panel && (
|
||||
<p className="mt-2 line-clamp-2 text-xs text-[#3d5248]">{speaker.panel}</p>
|
||||
<p className="mt-2 line-clamp-2 text-xs text-[#5b5b5b]">{speaker.panel}</p>
|
||||
)}
|
||||
</Link>
|
||||
</ScrollReveal>
|
||||
|
|
|
|||
|
|
@ -40,14 +40,14 @@ export function TicketCard({ tier, index, featured, compact }: Props) {
|
|||
>
|
||||
<div
|
||||
className={cn(
|
||||
"topo-card-surface ticket-admission relative w-full overflow-hidden bg-white text-[#0f0404]",
|
||||
"topo-card-surface ticket-admission relative w-full overflow-hidden bg-white text-[#ffffff]",
|
||||
"shadow-[0_12px_40px_rgba(0,0,0,0.18)]",
|
||||
featured && "ring-2 ring-[#ffb300]/50"
|
||||
featured && "ring-2 ring-[#37a47a]/50"
|
||||
)}
|
||||
data-ticket-notch={compact ? "light" : "inverse"}
|
||||
>
|
||||
{featured && (
|
||||
<span className="absolute right-3 top-3 z-10 rounded-full bg-[#ffb300] px-2.5 py-0.5 text-[10px] font-bold uppercase tracking-wider text-[#0f0404]">
|
||||
<span className="absolute right-3 top-3 z-10 rounded-full bg-[#37a47a] px-2.5 py-0.5 text-[10px] font-bold uppercase tracking-wider text-[#ffffff]">
|
||||
Popular
|
||||
</span>
|
||||
)}
|
||||
|
|
@ -62,11 +62,11 @@ export function TicketCard({ tier, index, featured, compact }: Props) {
|
|||
<div
|
||||
className={cn(
|
||||
"relative flex shrink-0 md:w-[30%]",
|
||||
"border-b border-dashed border-[#1a5c38]/20 md:border-b-0 md:border-r"
|
||||
"border-b border-dashed border-[#37a47a]/20 md:border-b-0 md:border-r"
|
||||
)}
|
||||
>
|
||||
<div className="flex w-full flex-row items-center justify-between gap-3 p-4 md:flex-col md:items-stretch md:justify-between md:py-5 md:pl-5 md:pr-4">
|
||||
<div className="flex items-center gap-2 text-[#1a5c38] md:flex-col md:items-start">
|
||||
<div className="flex items-center gap-2 text-[#37a47a] md:flex-col md:items-start">
|
||||
<Ticket className="size-4 shrink-0" strokeWidth={2} aria-hidden />
|
||||
<span className="text-[10px] font-bold uppercase tracking-[0.18em]">
|
||||
Admit one
|
||||
|
|
@ -75,13 +75,13 @@ export function TicketCard({ tier, index, featured, compact }: Props) {
|
|||
<div className="text-right md:text-left">
|
||||
<p
|
||||
className={cn(
|
||||
"font-bold tabular-nums leading-none text-[#1f3d7e]",
|
||||
"font-bold tabular-nums leading-none text-[#30614c]",
|
||||
compact ? "text-2xl" : "text-3xl"
|
||||
)}
|
||||
>
|
||||
{price}
|
||||
</p>
|
||||
<p className="mt-1 text-[10px] font-medium uppercase tracking-wide text-[#3d5248]">
|
||||
<p className="mt-1 text-[10px] font-medium uppercase tracking-wide text-[#5b5b5b]">
|
||||
{schedule}
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -91,10 +91,10 @@ export function TicketCard({ tier, index, featured, compact }: Props) {
|
|||
{/* Main — name, one line, details popover, CTA */}
|
||||
<div className="flex flex-1 flex-col justify-between gap-4 p-4 md:p-5">
|
||||
<div className="min-w-0 pr-8 md:pr-0">
|
||||
<h3 className="text-lg font-bold leading-tight text-[#0d3d26] md:text-xl">
|
||||
<h3 className="text-lg font-bold leading-tight text-[#30614c] md:text-xl">
|
||||
{tier.name}
|
||||
</h3>
|
||||
<p className="mt-1.5 line-clamp-2 text-sm text-[#3d5248]">
|
||||
<p className="mt-1.5 line-clamp-2 text-sm text-[#5b5b5b]">
|
||||
{ticketTagline(tier)}
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -103,7 +103,7 @@ export function TicketCard({ tier, index, featured, compact }: Props) {
|
|||
<TicketInclusionsPopover tier={tier} serial={serial} />
|
||||
<Button
|
||||
className={cn(
|
||||
"w-full rounded-full bg-[#ffb300] text-[#0f0404] hover:bg-[#ffb300]/90",
|
||||
"w-full rounded-full bg-[#37a47a] text-[#ffffff] hover:bg-[#37a47a]/90",
|
||||
featured && "ticket-cta-pulse"
|
||||
)}
|
||||
disabled={tier.soldOut}
|
||||
|
|
@ -123,7 +123,7 @@ export function TicketCard({ tier, index, featured, compact }: Props) {
|
|||
</div>
|
||||
|
||||
<div
|
||||
className="h-1 w-full bg-gradient-to-r from-[#1a5c38] via-[#ffb300] to-[#1f3d7e]"
|
||||
className="h-1 w-full bg-gradient-to-r from-[#37a47a] via-[#37a47a] to-[#30614c]"
|
||||
aria-hidden
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ export function TicketInclusionsPopover({ tier, serial, className }: Props) {
|
|||
variant="ghost"
|
||||
size="sm"
|
||||
className={cn(
|
||||
"topo-card-link h-8 gap-1.5 rounded-full px-3 text-xs font-medium hover:bg-[#1a5c38]/8",
|
||||
"topo-card-link h-8 gap-1.5 rounded-full px-3 text-xs font-medium hover:bg-[#37a47a]/8",
|
||||
className
|
||||
)}
|
||||
aria-label={`What's included in ${tier.name}`}
|
||||
|
|
@ -37,10 +37,10 @@ export function TicketInclusionsPopover({ tier, serial, className }: Props) {
|
|||
</PopoverTrigger>
|
||||
<PopoverContent
|
||||
align="start"
|
||||
className="w-[min(calc(100vw-2rem),20rem)] border-[#1a5c38]/15 p-0"
|
||||
className="w-[min(calc(100vw-2rem),20rem)] border-[#37a47a]/15 p-0"
|
||||
>
|
||||
<div className="border-b border-border/80 px-4 py-3">
|
||||
<p className="text-xs font-semibold uppercase tracking-wider text-[#1a5c38]">
|
||||
<p className="text-xs font-semibold uppercase tracking-wider text-[#37a47a]">
|
||||
{tier.name}
|
||||
</p>
|
||||
<p className="mt-1 text-sm leading-relaxed text-muted-foreground">
|
||||
|
|
@ -50,7 +50,7 @@ export function TicketInclusionsPopover({ tier, serial, className }: Props) {
|
|||
<ul className="space-y-2 px-4 py-3">
|
||||
{tier.features.map((feature) => (
|
||||
<li key={feature} className="flex gap-2 text-sm text-foreground">
|
||||
<span className="font-bold text-[#ffb300]" aria-hidden>
|
||||
<span className="font-bold text-[#37a47a]" aria-hidden>
|
||||
✓
|
||||
</span>
|
||||
{feature}
|
||||
|
|
|
|||
30
content/brand-colors.ts
Normal file
30
content/brand-colors.ts
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* GRV Summit brand palette (brand book — COLOR PALETTE).
|
||||
* Primary / secondary / tertiary sampled from brand assets; neutrals per spec.
|
||||
*/
|
||||
export const BRAND_COLORS = {
|
||||
primary: "#37a47a",
|
||||
secondary: "#b9d8c9",
|
||||
tertiary: "#30614c",
|
||||
black: "#000000",
|
||||
grey1: "#5b5b5b",
|
||||
grey2: "#a0a0a0",
|
||||
grey3: "#dbdbdb",
|
||||
white: "#ffffff",
|
||||
/** Brand book lists RGB 250,250,250 for white */
|
||||
whiteSoft: "#fafafa",
|
||||
/** Tinted surfaces derived from secondary */
|
||||
surfaceMuted: "#e8f2ec",
|
||||
} as const;
|
||||
|
||||
/** Greens for wavy tessellation / footer depth */
|
||||
export const BRAND_GREEN_SHADES = [
|
||||
BRAND_COLORS.primary,
|
||||
"#3da67f",
|
||||
"#43a884",
|
||||
"#49aa89",
|
||||
"#4fac8e",
|
||||
"#55ae93",
|
||||
] as const;
|
||||
|
||||
export const BRAND_GREEN = BRAND_COLORS.primary;
|
||||
|
|
@ -12,7 +12,7 @@ export const SITE_TOPO_PATTERN = "topo-main" as const satisfies TopoPatternId;
|
|||
export const MAIN_WHITE_PATTERN_SRC = "/patterns/mainwhite.svg";
|
||||
export const MAIN_GREEN_PATTERN_SRC = "/patterns/main.svg";
|
||||
|
||||
export const BRAND_GREEN = "#1a5c38";
|
||||
export { BRAND_GREEN } from "@/content/brand-colors";
|
||||
|
||||
export type TopoPatternAsset = {
|
||||
src: string;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user