From f4992c8a2b2708f6de366e40ba0f910838a7528b Mon Sep 17 00:00:00 2001 From: CodeWithEugene Date: Mon, 28 Sep 2026 12:20:58 +0300 Subject: [PATCH] feat(ui): rebuild landing page on a Stripe-style grid Restructure the home page around one continuous ruled frame with two-tone statement headings, keeping HackVillage fonts, colours and pill buttons: - hero with a brand-blue SVG ribbon and a left-aligned navbar that lines up with the frame - partner logo marquee (Salamander, Technetium Kenya, SkillsSync) - bento product cards with mock screens (vault, payouts, judging, Proof-of-Work, ledger, organizer dashboard) - photo banner, interactive trust stats (tab menu, sliding indicator, canvas burst that illustrates each stat and follows the cursor) - organizer / builder / hiring sections, navy open-infrastructure band, latest blog posts and a closing call to action The "What Is HackVillage?" copy is unchanged for search and answer engines. Old landing components and their CSS are removed. Co-Authored-By: Claude Opus 5.5 --- app/(marketing)/page.tsx | 37 +- app/globals.css | 2377 ++++++++++++++----- components/landing/audience-sections.tsx | 336 +++ components/landing/get-started.tsx | 49 + components/landing/journey-carousel.tsx | 47 + components/landing/landing-about.tsx | 31 + components/landing/landing-banner.tsx | 36 + components/landing/landing-hero.tsx | 110 + components/landing/landing-link.tsx | 68 + components/landing/latest-posts.tsx | 62 + components/landing/open-infrastructure.tsx | 249 ++ components/landing/partner-strip.tsx | 67 + components/landing/platform-grid.tsx | 323 +++ components/landing/trust-band.tsx | 43 + components/landing/trust-stats.tsx | 305 +++ components/patterns/builder-journey.tsx | 121 - components/patterns/landing-about.tsx | 24 - components/patterns/landing-hero.tsx | 107 - components/patterns/sparkle.tsx | 2 +- components/patterns/trust-impact.tsx | 112 - public/partners/skillssync-global-logo.webp | Bin 0 -> 32656 bytes public/partners/technetium-kenya-logo.png | Bin 0 -> 14130 bytes 22 files changed, 3516 insertions(+), 990 deletions(-) create mode 100644 components/landing/audience-sections.tsx create mode 100644 components/landing/get-started.tsx create mode 100644 components/landing/journey-carousel.tsx create mode 100644 components/landing/landing-about.tsx create mode 100644 components/landing/landing-banner.tsx create mode 100644 components/landing/landing-hero.tsx create mode 100644 components/landing/landing-link.tsx create mode 100644 components/landing/latest-posts.tsx create mode 100644 components/landing/open-infrastructure.tsx create mode 100644 components/landing/partner-strip.tsx create mode 100644 components/landing/platform-grid.tsx create mode 100644 components/landing/trust-band.tsx create mode 100644 components/landing/trust-stats.tsx delete mode 100644 components/patterns/builder-journey.tsx delete mode 100644 components/patterns/landing-about.tsx delete mode 100644 components/patterns/landing-hero.tsx delete mode 100644 components/patterns/trust-impact.tsx create mode 100644 public/partners/skillssync-global-logo.webp create mode 100644 public/partners/technetium-kenya-logo.png diff --git a/app/(marketing)/page.tsx b/app/(marketing)/page.tsx index 6ea5dbe..e1ec378 100644 --- a/app/(marketing)/page.tsx +++ b/app/(marketing)/page.tsx @@ -1,10 +1,15 @@ import type { Metadata } from "next"; -import { BuilderJourney } from "@/components/patterns/builder-journey"; -import { CtaBanner } from "@/components/patterns/cta-banner"; -import { LandingAbout } from "@/components/patterns/landing-about"; -import { LandingHero } from "@/components/patterns/landing-hero"; -import { TrustImpact } from "@/components/patterns/trust-impact"; +import { AudienceSections } from "@/components/landing/audience-sections"; +import { GetStarted } from "@/components/landing/get-started"; +import { LandingAbout } from "@/components/landing/landing-about"; +import { LandingBanner } from "@/components/landing/landing-banner"; +import { LandingHero } from "@/components/landing/landing-hero"; +import { LatestPosts } from "@/components/landing/latest-posts"; +import { OpenInfrastructure } from "@/components/landing/open-infrastructure"; +import { PartnerStrip } from "@/components/landing/partner-strip"; +import { PlatformGrid } from "@/components/landing/platform-grid"; +import { TrustBand } from "@/components/landing/trust-band"; import { pageOpenGraph } from "@/lib/seo/metadata"; export const metadata: Metadata = { @@ -16,18 +21,24 @@ export const metadata: Metadata = { openGraph: pageOpenGraph("/"), }; +/* + * The landing page follows one continuous frame: every section's content + * sits inside `.lp-frame`, whose hairline side rules run the full height + * of the page, with horizontal rules marking where one idea ends. + */ export default function LandingPage() { return ( -
+
- + + + + - - - - - - + + + +
); } diff --git a/app/globals.css b/app/globals.css index 76cdc21..1da0875 100644 --- a/app/globals.css +++ b/app/globals.css @@ -47,6 +47,17 @@ @layer base { :root { --site-header-height: 4rem; + /* The landing page frame (and the header aligned to it): a hairline-ruled + column with a narrow edge outside the rules and a gutter inside them. */ + --frame-max: 1440px; + --frame-edge: clamp(12px, 2vw, 32px); + --frame-gutter: clamp(16px, 1.5vw, 24px); + } + @media (max-width: 1023px) { + :root { + --frame-edge: 0px; + --frame-gutter: clamp(16px, 3vw, 24px); + } } html { color-scheme: light; @@ -167,7 +178,7 @@ .how-it-works-heading-block { min-width: 0; } - /* Home page stars (see .journey-star), flanking the centered heading block. */ + /* Brand stars flanking the centered heading block. */ .how-it-works-star { position: absolute; width: clamp(36px, 3.6vw, 56px); @@ -202,7 +213,7 @@ letter-spacing: 0.18em; text-transform: uppercase; } - /* Same scale as the home page hero heading (.hero-heading), at every breakpoint below. */ + /* Display-scale page heading, resized at the breakpoints further down. */ .how-it-works-title { max-width: 1100px; font-size: clamp(2.75rem, 4.6vw, 5.5rem); @@ -310,174 +321,6 @@ } } - /* Editorial three-column section: copy + pill photos flanking an arced centerpiece. */ - .builder-journey { - display: grid; - grid-template-columns: minmax(0, 1fr) min(29vw, 416px) minmax(0, 1fr); - gap: clamp(40px, 5vw, 72px); - padding-block: clamp(48px, 6vw, 88px); - } - .journey-column { - display: flex; - flex-direction: column; - justify-content: space-between; - gap: 40px; - } - .journey-copy { - position: relative; - display: flex; - flex-direction: column; - align-items: flex-start; - gap: 32px; - max-width: 356px; - } - .journey-copy-right { - gap: 28px; - max-width: 360px; - margin-inline-start: clamp(0px, 1.8vw, 24px); - } - .journey-final-row { - display: flex; - flex-wrap: wrap; - align-items: center; - gap: clamp(16px, 1.6vw, 24px); - } - .journey-display { - color: var(--color-ink); - font-family: var(--font-display); - font-size: clamp(28px, 2.6vw, 40px); - font-weight: 600; - letter-spacing: -0.03em; - line-height: 1.15; - } - .journey-heading-mobile { - display: none; - } - .journey-text { - color: var(--color-body-copy); - font-family: var(--font-body); - font-size: clamp(15px, 1vw, 17px); - line-height: 1.55; - } - .journey-action { - position: relative; - isolation: isolate; - display: inline-flex; - align-items: center; - gap: 8px; - overflow: hidden; - padding: clamp(12px, 1vw, 14px) clamp(20px, 1.6vw, 26px); - border-radius: 999px; - background: var(--color-brand); - color: var(--color-brand-ink); - font-family: var(--font-display); - font-size: clamp(14px, 0.85vw, 16px); - font-weight: 600; - line-height: 1; - --btn-fill-color: var(--color-brand-soft); - } - .journey-pair { - display: flex; - align-items: flex-start; - gap: clamp(12px, 1.4vw, 22px); - } - .journey-pill { - position: relative; - overflow: hidden; - border-radius: 999px; - background: var(--color-surface); - } - .journey-pair > .journey-pill { - flex: 1 1 0; - max-width: 184px; - aspect-ratio: 176 / 298; - } - .journey-pair-left > .journey-pill:first-child { - margin-top: clamp(32px, 4.6vw, 66px); - } - .journey-pair-right > .journey-pill:last-child { - margin-top: clamp(48px, 7.3vw, 105px); - } - .journey-center { - position: relative; - align-self: center; - aspect-ratio: 416 / 709; - } - .journey-pill-center { - position: absolute; - top: 9.73%; - left: 5.05%; - width: 89.9%; - height: 90.27%; - } - .journey-arc { - position: absolute; - inset: 0; - width: 100%; - height: 100%; - overflow: visible; - fill: var(--color-ink); - font-family: var(--font-display); - font-size: 22px; - font-weight: 500; - letter-spacing: 0.02em; - } - .journey-star { - position: absolute; - z-index: 1; - width: clamp(36px, 3.6vw, 56px); - height: auto; - fill: var(--color-brand); - } - .journey-star-left { - top: clamp(28px, 3.4vw, 48px); - left: calc(100% - 24px); - } - .journey-star-right { - top: calc(-1 * clamp(44px, 5vw, 68px)); - left: 0; - } - @media (max-width: 1023px) { - .builder-journey { - grid-template-columns: minmax(0, 1fr); - gap: 48px; - } - .journey-copy, - .journey-copy-right { - max-width: 560px; - margin-inline-start: 0; - } - .journey-pair { - justify-content: center; - } - .journey-center { - justify-self: center; - width: min(100%, 416px); - } - .journey-star { - display: none; - } - } - - @media (max-width: 599px) { - .journey-column-left .journey-copy { - align-items: center; - text-align: center; - } - .journey-heading-desktop { - display: none; - } - .journey-heading-mobile { - display: inline; - font-size: clamp(20px, 6vw, 30px); - white-space: nowrap; - } - .journey-text { - align-self: center; - text-align: center; - } - } - /* * Final CTA banner: a solid logo-navy card split in half, the platform's * promise and a working newsletter signup on the left, and a photo that @@ -648,255 +491,28 @@ font-weight: 600; } - /* - * Trust & Impact — sits between How It Works and the newsletter banner. - * Built from the reference frame's arrangement (text column, photo group, - * photo strip; 500x688 photo, 200x262 strip photos), with the photo - * columns trimmed so the images sit smaller in a full-width section. - * Everything scales as one piece: - * - columns are fr units (text 480 : photo group 560 : strip 150), - * - type, padding and card sizes are container units (cqi) of the - * section's own width, so text scales with the photos instead of - * staying viewport-sized. - * Full width like every other section (site-container gutters only). - * Stat cards run beneath the text and photo, not under the strip. - */ - .trust-impact { - container-type: inline-size; - display: grid; - grid-template-columns: minmax(0, 480fr) minmax(0, 560fr) minmax(0, 150fr); - grid-template-rows: auto auto; - column-gap: 3.2%; - align-items: start; - padding-block: clamp(48px, 5vw, 80px); - } - .trust-impact-content { - grid-column: 1; - grid-row: 1; - align-self: center; - display: flex; - flex-direction: column; - align-items: flex-start; - gap: clamp(16px, 2.4cqi, 32px); - } - .trust-impact-eyebrow { - display: flex; - align-items: center; - gap: 8px; - margin-bottom: calc(-1 * clamp(8px, 1.8cqi, 24px)); - font-family: var(--font-body); - font-size: clamp(13px, 1.37cqi, 18px); - font-weight: 500; - color: var(--color-ink); - } - .trust-impact-eyebrow span { - color: var(--color-brand); - } - .trust-impact-heading { - font-family: var(--font-display); - font-weight: 600; - font-size: clamp(28px, 4.27cqi, 56px); - line-height: 1.2; - letter-spacing: -0.01em; - color: var(--color-ink); - } - .trust-impact-text { - font-size: clamp(14px, 1.3cqi, 17px); - line-height: 1.55; - color: var(--color-body-copy); - } - .trust-impact-visual { - position: relative; - isolation: isolate; - grid-column: 2; - grid-row: 1; - } - .trust-impact-star { - position: absolute; - z-index: 0; - top: 3%; - left: -12.5%; - width: 21%; - height: auto; - aspect-ratio: 139 / 150; - fill: var(--color-brand); - } - .trust-impact-frame { - position: relative; - z-index: 1; - width: 70%; - margin-left: 10%; - aspect-ratio: 500 / 688; - /* Matte: the photo sits inset inside a larger arch outline. Padding - percentages resolve against the photo group's width, sized so the - insets keep the reference's ratio to the frame (about 6% / 9%). */ - padding: 6% 4.6% 4.6% 4.3%; - border: 1px solid var(--color-ink); - /* Arch: browsers cap a too-large radius at 50% of the box, so the top - corners always resolve to a perfect half-circle regardless of width. */ - border-radius: 999px 999px 0 0; - } - .trust-impact-photo { - position: relative; - width: 100%; - height: 100%; - overflow: hidden; - border-radius: 999px 999px 0 0; - } - .trust-float-card { - position: absolute; - z-index: 2; - display: flex; - align-items: center; - gap: clamp(8px, 1.2cqi, 16px); - padding: clamp(10px, 1.83cqi, 24px); - border: 1px solid var(--color-ink); - border-radius: clamp(10px, 1.2cqi, 16px); - background: color-mix(in srgb, var(--color-surface) 80%, transparent); - backdrop-filter: blur(8px); - } - .trust-float-card p { - margin: 0; - font-size: clamp(11px, 1.07cqi, 14px); - line-height: 1.25; - color: var(--color-ink); - } - .trust-float-icon { - display: flex; - flex-shrink: 0; - align-items: center; - justify-content: center; - width: clamp(28px, 3.66cqi, 48px); - height: clamp(28px, 3.66cqi, 48px); - border-radius: 999px; - background: var(--color-brand-soft); - color: var(--color-ink); - } - .trust-float-icon svg { - width: 45%; - height: 45%; - } - .trust-float-card-top { - top: 24%; - left: 56.5%; - width: 40.8%; - } - .trust-float-card-bottom { - top: 45.5%; - left: -0.75%; - width: 39.2%; - } - .trust-impact-strip { - grid-column: 3; - grid-row: 1 / span 2; - display: flex; - flex-direction: column; - gap: clamp(10px, 1.83cqi, 24px); - } - .trust-strip-photo { - position: relative; - aspect-ratio: 200 / 262; - overflow: hidden; - border: 1px solid var(--color-ink); - border-radius: clamp(16px, 2.44cqi, 32px); - } - .trust-stats { - grid-column: 1 / span 2; - grid-row: 2; - display: flex; - gap: clamp(14px, 2.44cqi, 32px); - width: 90%; - margin: clamp(24px, 3.66cqi, 48px) 0 0; - padding: 0; - list-style: none; - } - .trust-stat { - flex: 1 1 0; - min-width: 0; - display: flex; - align-items: center; - gap: clamp(10px, 1.22cqi, 16px); - min-height: clamp(60px, 6.3cqi, 83px); - padding: clamp(10px, 1.22cqi, 16px); - /* Logo navy fill + logo bright-blue hard shadow. brand-ink stays navy in - both themes (ink flips light in dark mode), so the cards keep their - fill whichever theme is active. */ - border: 1px solid var(--color-brand-ink); - border-radius: clamp(10px, 1.22cqi, 16px); - background: var(--color-brand-ink); - box-shadow: 6px 6px 0 var(--color-brand); - } - .trust-stat-value { - flex-shrink: 0; - font-family: var(--font-display); - font-size: clamp(17px, 1.68cqi, 22px); - font-weight: 600; - color: #ffffff; - } - .trust-stat-label { - font-size: clamp(11px, 1.07cqi, 14px); - line-height: 1.25; - color: rgb(255 255 255 / 80%); - } - @media (max-width: 1023px) { - .trust-impact { - grid-template-columns: minmax(0, 1fr); - grid-template-rows: auto; - row-gap: clamp(32px, 5vw, 48px); - } - .trust-impact-content, - .trust-impact-visual, - .trust-impact-strip, - .trust-stats { - grid-column: 1; - grid-row: auto; - } - /* Mobile reads as a stacked, centered story: eyebrow, heading, copy and - CTA all align to the middle instead of hugging the left edge. */ - .trust-impact-content { - align-items: center; - text-align: center; - } - .trust-impact-visual { - width: min(100%, 460px); - margin-inline: auto; - } - .trust-impact-strip { - flex-direction: row; - } - .trust-strip-photo { - flex: 1 1 0; - min-width: 0; - } - .trust-stats { - width: 100%; - margin-top: 0; - } - } - @media (max-width: 599px) { - .trust-float-card { - display: none; - } - .trust-stats { - flex-direction: column; - } - } - + /* Left-aligned bar: logo, then the links beside it, actions pushed right. */ .site-header-grid { display: grid; - grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); + grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; height: var(--site-header-height); gap: 16px; } + /* On the landing page the bar lines up with the ruled frame below it. */ + body:has(.lp) .site-header-grid { + width: min(100% - 2 * var(--frame-edge), var(--frame-max)); + padding-inline: var(--frame-gutter); + } .site-header-links, .site-header-actions { display: flex; align-items: center; } .site-header-links { - justify-content: center; + justify-content: flex-start; gap: 28px; + margin-left: clamp(8px, 1.6vw, 24px); } /* From 1024px (where the inline links return) to 1279px, the six links and the actions are tight, so the links sit closer rather than overlap. */ @@ -1221,78 +837,6 @@ padding-inline: clamp(1rem, 3vw, 3.5rem); } - .landing-hero { - --collage-gap: clamp(0.5rem, 1.65vw, 1.75rem); - display: flex; - flex-direction: column; - width: 100%; - height: calc(100svh - var(--site-header-height)); - min-height: 620px; - padding: clamp(1rem, 2.5vh, 2rem) clamp(1rem, 3vw, 3.5rem) 1.75rem; - gap: clamp(1.25rem, 3vh, 2.5rem); - } - - .hero-intro { - position: relative; - flex-shrink: 0; - } - .hero-copy { - position: relative; - z-index: 1; - max-width: 780px; - margin-inline: auto; - text-align: center; - } - /* Home page stars (see .journey-star), just outside the centered hero copy. */ - .hero-star { - position: absolute; - width: clamp(36px, 3.6vw, 56px); - height: auto; - fill: var(--color-brand); - pointer-events: none; - } - .hero-star-left { - top: 26%; - right: calc(100% + clamp(24px, 3vw, 56px)); - } - .hero-star-right { - top: 60%; - left: calc(100% + clamp(24px, 3vw, 56px)); - } - @media (max-width: 1023px) { - .hero-star { - display: none; - } - } - .hero-eyebrow { - font-size: 10px; - font-weight: 600; - letter-spacing: 0.19em; - text-transform: uppercase; - color: var(--color-ink-soft); - } - .hero-heading { - margin-top: 12px; - font-size: clamp(2.75rem, 4.6vw, 5.5rem); - line-height: 1.06; - letter-spacing: -0.045em; - font-weight: 700; - } - .hero-heading span { - color: var(--color-ink-soft); - } - .hero-description { - max-width: 540px; - margin: 18px auto 0; - font-size: 14px; - line-height: 1.7; - color: var(--color-body-copy); - text-wrap: pretty; - } - .hero-description strong { - color: var(--color-ink); - font-weight: 600; - } .hero-actions { display: flex; justify-content: center; @@ -1330,82 +874,13 @@ .hero-action-secondary:hover { color: var(--color-ink-soft); } - .hero-collage { - display: grid; - grid-template-columns: 0.7fr 1fr 1.13fr 1fr 0.7fr; - gap: var(--collage-gap); - flex: 1; - min-height: 0; - } - .hero-column { - display: flex; - flex-direction: column; - min-height: 0; - gap: var(--collage-gap); - } - .hero-photo { - position: relative; - flex: 1; - min-height: 0; - overflow: hidden; - border-radius: clamp(10px, 1.2vw, 22px); - background: #deedf3; - } - .hero-photo-center img { - object-position: center 35%; - } - .hero-column-left { - padding-bottom: 7%; - } - .hero-column-right { - padding-top: 14%; - } - .hero-column-edge-left { - padding-bottom: 36%; - } - .hero-column-edge-right { - padding-top: 42%; - } - .hero-side-note { - padding: 0 0 12px; - font-size: clamp(14px, 1.65vw, 29px); - line-height: 1.75; - font-weight: 500; - } - .hero-side-note::after { - content: ""; - display: block; - margin-top: 14px; - height: 3px; - width: 65%; - background: var(--color-ink); - } - .hero-column-edge-right .hero-side-note { - align-self: flex-end; - padding-top: 5px; - padding-bottom: 0; - } - @media (min-width: 1024px) and (min-height: 900px) { - .landing-hero { - padding-top: 4vh; - padding-bottom: 3vh; - gap: 4vh; - } - .hero-heading, .how-it-works-title { font-size: clamp(4rem, 5vw, 6rem); } - .hero-description { - font-size: 16px; - } } @media (max-width: 1023px) { - .hero-copy { - max-width: 70%; - } - .hero-heading, .how-it-works-title { font-size: clamp(2.5rem, 5.3vw, 3.4rem); } @@ -1422,34 +897,10 @@ } @media (max-width: 639px) { - .landing-hero { - min-height: 464px; - padding: 20px 14px 22px; - gap: 22px; - } - .hero-copy { - max-width: 100%; - } - .hero-eyebrow { - font-size: 8px; - letter-spacing: 0.16em; - } - .hero-heading { - margin-top: 13px; - font-size: clamp(2rem, 8.8vw, 3.5rem); - line-height: 1.1; - } .how-it-works-title { font-size: clamp(2rem, 8.8vw, 3.5rem); line-height: 1.1; } - .hero-description { - max-width: 360px; - margin-top: 14px; - font-size: 12px; - line-height: 1.65; - padding-inline: 8px; - } .hero-actions { flex-direction: column; gap: 0; @@ -1464,47 +915,6 @@ min-height: 44px; font-size: 11px; } - .hero-collage { - gap: 7px; - grid-template-columns: 0.6fr 1fr 1.3fr 1fr 0.6fr; - max-height: 360px; - margin-block: auto; - } - .hero-column { - gap: 7px; - } - .hero-column-edge-left { - padding-top: 70%; - padding-bottom: 85%; - } - .hero-column-edge-right { - padding-top: 100%; - padding-bottom: 45%; - } - .hero-column-left { - padding-bottom: 25%; - } - .hero-column-right { - padding-top: 28%; - } - .hero-side-note { - display: none; - } - .hero-photo { - border-radius: 10px; - } - } - - /* Let short landscape windows and zoomed text scroll without clipping content. */ - @media (max-height: 600px) and (min-width: 640px) { - .landing-hero { - height: auto; - min-height: calc(100svh - var(--site-header-height)); - } - .hero-collage { - flex: none; - height: 300px; - } } /* Long-form legal document typography (Privacy Policy, Terms of Service) — @@ -1841,3 +1251,1746 @@ color: rgb(255 255 255 / 0.88); } } + +/* + * Landing page (app/(marketing)/page.tsx, components/landing/*). + * Structure borrowed from the classic fintech landing grid: one continuous + * frame whose hairline side rules run the height of the page, full-bleed + * rules around the track strip and bands, two-tone statement headings, and + * product cards carrying small mock screens. Colours and type stay ours. + */ +@layer components { + .lp { + --lp-line: color-mix(in srgb, var(--color-ink) 10%, transparent); + --lp-quiet: color-mix(in srgb, var(--color-body-copy) 78%, var(--color-ink-soft)); + --lp-tint: color-mix(in srgb, var(--color-brand) 6%, var(--color-paper)); + /* Fixed brand blues for gradient art, which must not flip with the theme. */ + --lp-blue-deep: #0272d4; + --lp-navy: #000092; + --lp-gutter: var(--frame-gutter); + --lp-space: clamp(56px, 7vw, 96px); + overflow-x: clip; + } + + .btn-pill-inverse { + --btn-fill-color: color-mix(in srgb, var(--color-on-inverse) 12%, transparent); + } + + .lp-frame { + position: relative; + width: min(100% - 2 * var(--frame-edge), var(--frame-max)); + margin-inline: auto; + padding-inline: var(--lp-gutter); + border-inline: 1px solid var(--lp-line); + } + .lp-block { + padding-block: var(--lp-space); + } + .lp-block-tight { + padding-top: 0; + } + .lp-block-flush { + padding-bottom: var(--lp-space); + } + .lp-divided { + border-top: 1px solid var(--lp-line); + } + + /* Two-tone statement heading: the claim in ink, the detail in a quieter tone. */ + .lp-statement { + max-width: 780px; + font-family: var(--font-display); + font-size: clamp(26px, 2.6vw, 36px); + font-weight: 500; + line-height: 1.2; + letter-spacing: -0.02em; + color: var(--color-ink); + text-wrap: pretty; + } + .lp-statement span { + color: var(--lp-quiet); + } + .lp-statement-sm { + max-width: 700px; + font-size: clamp(21px, 1.9vw, 26px); + line-height: 1.3; + } + .lp-statement-stack span { + display: block; + } + + .lp-text-link { + display: inline-flex; + align-items: center; + gap: 2px; + color: var(--color-ink-soft); + font-size: 14.5px; + font-weight: 600; + transition: color 150ms ease; + } + .lp-text-link:hover { + color: var(--color-ink); + } + .lp-text-link-chevron { + width: 15px; + height: 15px; + transition: transform 150ms ease; + } + .lp-text-link:hover .lp-text-link-chevron { + transform: translateX(3px); + } + .lp-text-link-inverse { + color: var(--color-brand-soft); + } + .lp-text-link-inverse:hover { + color: var(--color-on-inverse); + } + + /* ---- Hero ---- */ + .lp-hero { + position: relative; + overflow: hidden; + } + .lp-ribbon { + position: absolute; + top: 0; + right: 0; + width: min(64vw, 1000px); + height: 100%; + pointer-events: none; + } + .lp-hero-inner { + padding-block: clamp(72px, 10vw, 148px) clamp(64px, 8vw, 112px); + } + .lp-hero-ticker { + font-size: 14px; + font-weight: 500; + color: var(--color-ink); + } + .lp-hero-ticker span { + margin-left: 4px; + color: var(--color-ink-soft); + font-variant-numeric: tabular-nums; + font-weight: 600; + } + .lp-hero-heading { + position: relative; + max-width: 900px; + margin-top: 28px; + font-family: var(--font-display); + font-size: clamp(32px, 3.6vw, 52px); + font-weight: 500; + line-height: 1.1; + letter-spacing: -0.03em; + color: var(--color-ink); + text-wrap: pretty; + } + .lp-hero-heading span { + color: var(--lp-quiet); + } + .lp-hero-actions { + display: flex; + flex-wrap: wrap; + gap: 12px; + margin-top: 36px; + } + + /* ---- Partner logo strip ---- */ + .lp-tracks { + border-block: 1px solid var(--lp-line); + } + .lp-tracks-frame { + overflow: hidden; + padding-inline: 0; + mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); + } + .lp-tracks-row { + display: flex; + width: max-content; + animation: lp-marquee 48s linear infinite; + } + .lp-tracks-row:hover { + animation-play-state: paused; + } + .lp-partner { + display: flex; + flex-shrink: 0; + align-items: center; + height: 96px; + padding-inline: clamp(40px, 5vw, 72px); + } + .lp-partner-logo { + width: auto; + height: 40px; + } + /* Technetium's mark carries a tagline under the wordmark, so it runs taller. */ + .lp-partner-logo.lp-partner-technetium { + height: 52px; + } + .lp-partner-logo.lp-partner-skillssync { + height: 38px; + } + @keyframes lp-marquee { + to { + transform: translateX(-50%); + } + } + + /* ---- Product cards (bento) ---- */ + .lp-bento { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 16px; + margin-top: clamp(40px, 5vw, 64px); + } + .lp-bento-wide { + grid-column: span 2; + } + .lp-bento-full { + grid-column: 1 / -1; + } + .lp-card { + position: relative; + display: flex; + flex-direction: column; + min-height: 440px; + overflow: hidden; + border: 1px solid var(--lp-line); + border-radius: var(--radius-card); + background: var(--color-surface); + transition: border-color 200ms ease, box-shadow 200ms ease; + } + .lp-card:hover { + border-color: color-mix(in srgb, var(--color-brand) 45%, transparent); + box-shadow: var(--shadow-card); + } + .lp-card:has(.lp-card-link:focus-visible) { + outline: 2px solid var(--color-brand); + outline-offset: 2px; + } + .lp-card-head { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 16px; + padding: 24px 24px 0; + } + .lp-card-title { + max-width: 22ch; + font-family: var(--font-display); + font-size: 20px; + font-weight: 500; + line-height: 1.3; + letter-spacing: -0.01em; + color: var(--color-ink); + } + .lp-card-link { + outline: none; + } + .lp-card-link::after { + content: ""; + position: absolute; + inset: 0; + z-index: 2; + } + .lp-card-chip { + display: grid; + flex-shrink: 0; + place-items: center; + width: 32px; + height: 32px; + border-radius: var(--radius-control); + background: color-mix(in srgb, var(--color-brand) 12%, transparent); + color: var(--color-ink-soft); + transition: background 200ms ease, color 200ms ease; + } + .lp-card:hover .lp-card-chip { + background: var(--color-brand); + color: var(--color-brand-ink); + } + .lp-card-visual { + position: relative; + display: flex; + flex: 1; + align-items: flex-end; + justify-content: center; + margin-top: 24px; + padding: 24px; + background: + radial-gradient(120% 90% at 100% 100%, color-mix(in srgb, var(--color-brand) 26%, transparent), transparent 62%), + radial-gradient(90% 70% at 0% 100%, color-mix(in srgb, var(--color-brand-soft) 30%, transparent), transparent 60%); + } + .lp-bento-full { + display: grid; + grid-template-columns: 260px minmax(0, 1fr); + min-height: 0; + } + .lp-bento-full .lp-card-head { + padding-bottom: 24px; + } + .lp-bento-full .lp-card-chip { + position: absolute; + top: 24px; + right: 24px; + z-index: 1; + } + .lp-bento-full .lp-card-visual { + margin-top: 0; + padding: 56px 32px 0; + } + + /* Mock screens inside the cards: sample data, real rules. */ + .lp-mock { + width: 100%; + padding: 16px; + border: 1px solid var(--lp-line); + border-radius: 10px; + background: var(--color-surface); + box-shadow: var(--shadow-card); + color: var(--color-body-copy); + font-size: 12px; + line-height: 1.45; + text-align: left; + } + .lp-mock-kicker { + color: var(--color-muted); + font-size: 10.5px; + font-weight: 600; + letter-spacing: 0.06em; + text-transform: uppercase; + } + .lp-mock-title { + margin-top: 6px; + color: var(--color-ink); + font-size: 13px; + font-weight: 600; + } + .lp-mock-amount { + margin-top: 4px; + color: var(--color-ink); + font-family: var(--font-display); + font-size: 24px; + font-weight: 600; + letter-spacing: -0.02em; + font-variant-numeric: tabular-nums; + } + .lp-mock-pair { + display: grid; + grid-template-columns: minmax(0, 0.8fr) minmax(0, 1fr); + align-items: end; + gap: 16px; + width: 100%; + } + .lp-mock-progress { + height: 6px; + margin-top: 14px; + overflow: hidden; + border-radius: 999px; + background: var(--lp-line); + } + .lp-mock-progress span { + display: block; + height: 100%; + border-radius: inherit; + background: linear-gradient(90deg, var(--color-brand-soft), var(--color-brand)); + } + .lp-mock-row { + display: flex; + justify-content: space-between; + margin-top: 8px; + } + .lp-mock-row strong { + color: var(--color-ink); + } + .lp-mock-badge { + display: inline-flex; + align-items: center; + gap: 4px; + margin-top: 14px; + padding: 3px 9px; + border-radius: 999px; + background: color-mix(in srgb, var(--color-success) 12%, transparent); + color: var(--color-success); + font-size: 11px; + font-weight: 600; + } + .lp-mock-browser { + display: flex; + align-items: center; + gap: 4px; + margin: -4px 0 14px; + } + .lp-mock-browser span { + width: 7px; + height: 7px; + border-radius: 50%; + background: var(--lp-line); + } + .lp-mock-browser em { + margin-left: 10px; + padding: 2px 10px; + border-radius: 999px; + background: var(--lp-tint); + color: var(--color-muted); + font-size: 10px; + font-style: normal; + } + .lp-mock-lines { + margin-top: 8px; + } + .lp-mock-lines div { + display: flex; + justify-content: space-between; + padding-block: 7px; + border-bottom: 1px dashed var(--lp-line); + } + .lp-mock-lines dd { + color: var(--color-ink); + font-variant-numeric: tabular-nums; + } + .lp-mock-lines .lp-mock-total { + border-bottom: 0; + font-weight: 600; + } + .lp-mock-lines .lp-mock-total dt { + color: var(--color-ink); + } + .lp-mock-methods { + display: flex; + gap: 6px; + margin-top: 8px; + } + .lp-mock-method { + padding: 4px 10px; + border: 1px solid var(--lp-line); + border-radius: 6px; + font-size: 11px; + } + .lp-mock-method-on { + border-color: var(--color-brand); + background: color-mix(in srgb, var(--color-brand) 10%, transparent); + color: var(--color-ink); + font-weight: 600; + } + .lp-mock-locked { + display: flex; + align-items: center; + gap: 6px; + margin-top: 12px; + color: var(--color-ink-soft); + font-size: 11px; + font-weight: 500; + } + .lp-mock-payout { + max-width: 300px; + } + .lp-mock-tranches { + display: grid; + gap: 12px; + margin-top: 14px; + } + .lp-mock-tranches li { + display: flex; + gap: 10px; + } + .lp-mock-tranches strong { + display: block; + color: var(--color-ink); + font-size: 12.5px; + } + .lp-mock-tranches span:not(.lp-mock-dot) { + font-size: 11px; + } + .lp-mock-dot { + display: grid; + flex-shrink: 0; + place-items: center; + width: 20px; + height: 20px; + border-radius: 50%; + background: var(--lp-line); + color: var(--color-muted); + } + .lp-mock-tranche-done .lp-mock-dot { + background: var(--color-success); + color: #fff; + } + .lp-mock-split { + display: flex; + height: 26px; + margin-top: 16px; + overflow: hidden; + border-radius: 6px; + font-size: 10.5px; + font-weight: 600; + } + .lp-mock-split span { + display: grid; + place-items: center; + } + .lp-mock-split span:first-child { + background: var(--color-brand); + color: var(--color-brand-ink); + } + .lp-mock-split span:last-child { + flex: 1; + background: var(--lp-line); + color: var(--color-body-copy); + } + .lp-mock-rubric { + display: grid; + gap: 8px; + margin-top: 12px; + } + .lp-mock-rubric li { + display: grid; + grid-template-columns: 64px minmax(0, 1fr) 14px; + align-items: center; + gap: 10px; + } + .lp-mock-rubric strong { + color: var(--color-ink); + text-align: right; + } + .lp-mock-meter { + height: 6px; + overflow: hidden; + border-radius: 999px; + background: var(--lp-line); + } + .lp-mock-meter span { + display: block; + height: 100%; + border-radius: inherit; + background: linear-gradient(90deg, var(--color-brand-soft), var(--color-brand)); + } + .lp-mock-feedback { + display: flex; + align-items: center; + gap: 6px; + margin-top: 14px; + color: var(--color-success); + font-size: 11.5px; + font-weight: 500; + } + .lp-mock-person { + display: flex; + align-items: center; + gap: 10px; + } + .lp-mock-person strong { + display: block; + color: var(--color-ink); + font-size: 13px; + } + .lp-mock-person span:not(.lp-mock-avatar) { + font-size: 11px; + color: var(--color-muted); + } + .lp-mock-avatar { + display: grid; + flex-shrink: 0; + place-items: center; + width: 36px; + height: 36px; + border-radius: 50%; + background: var(--color-ink); + color: var(--color-paper); + font-family: var(--font-display); + font-size: 13px; + font-weight: 700; + } + .lp-mock-pills { + display: flex; + flex-wrap: wrap; + gap: 6px; + margin-top: 12px; + } + .lp-mock-pills li { + padding: 3px 9px; + border: 1px solid var(--lp-line); + border-radius: 999px; + color: var(--color-ink); + font-size: 10.5px; + font-weight: 500; + } + .lp-mock-graph { + display: grid; + grid-template-columns: repeat(14, minmax(0, 1fr)); + gap: 3px; + margin-top: 14px; + } + .lp-mock-graph span { + aspect-ratio: 1; + border-radius: 2px; + background: var(--lp-line); + } + .lp-mock-graph span[data-level="1"] { + background: color-mix(in srgb, var(--color-brand-soft) 60%, transparent); + } + .lp-mock-graph span[data-level="2"] { + background: var(--color-brand); + } + .lp-mock-graph span[data-level="3"] { + background: var(--color-ink-soft); + } + .lp-mock-ledger ul { + margin-top: 8px; + } + .lp-mock-ledger li { + display: grid; + grid-template-columns: minmax(0, 1fr) auto auto; + align-items: center; + gap: 10px; + padding-block: 8px; + border-bottom: 1px solid var(--lp-line); + font-size: 11px; + } + .lp-mock-ledger li:last-child { + border-bottom: 0; + } + .lp-mock-ledger code { + overflow: hidden; + color: var(--color-ink-soft); + font-size: 11px; + text-overflow: ellipsis; + white-space: nowrap; + } + .lp-mock-ledger strong { + color: var(--color-ink); + font-variant-numeric: tabular-nums; + } + .lp-mock-dashboard { + max-width: 880px; + padding-bottom: 0; + border-bottom: 0; + border-radius: 10px 10px 0 0; + } + .lp-mock-dash-body { + display: grid; + grid-template-columns: 160px minmax(0, 1fr); + } + .lp-mock-dash-nav { + display: flex; + flex-direction: column; + gap: 2px; + padding: 0 14px 16px 0; + border-right: 1px solid var(--lp-line); + font-size: 11.5px; + } + .lp-mock-dash-nav strong { + margin-bottom: 8px; + color: var(--color-ink); + font-size: 12px; + } + .lp-mock-dash-nav span { + padding: 4px 8px; + border-radius: 6px; + } + .lp-mock-dash-nav .lp-mock-dash-active { + background: color-mix(in srgb, var(--color-brand) 12%, transparent); + color: var(--color-ink); + font-weight: 600; + } + .lp-mock-dash-main { + padding-left: 16px; + } + .lp-mock-dash-stats { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 10px; + } + .lp-mock-dash-stats div { + padding: 10px; + border: 1px solid var(--lp-line); + border-radius: 8px; + } + .lp-mock-dash-stats span { + display: block; + font-size: 10.5px; + } + .lp-mock-dash-stats strong { + color: var(--color-ink); + font-family: var(--font-display); + font-size: 18px; + font-weight: 600; + } + .lp-mock-table { + width: 100%; + margin-top: 14px; + font-size: 11.5px; + border-collapse: collapse; + } + .lp-mock-table th { + padding: 6px 0; + border-bottom: 1px solid var(--lp-line); + font-weight: 500; + text-align: left; + } + .lp-mock-table td { + padding: 8px 0; + border-bottom: 1px solid var(--lp-line); + color: var(--color-ink); + } + .lp-mock-status { + padding: 2px 8px; + border-radius: 999px; + font-size: 10.5px; + font-weight: 600; + } + .lp-mock-status-done { + background: color-mix(in srgb, var(--color-success) 13%, transparent); + color: var(--color-success); + } + .lp-mock-status-idle { + background: var(--lp-line); + color: var(--color-body-copy); + } + + /* ---- Feature banner ---- */ + .lp-banner { + position: relative; + min-height: 320px; + aspect-ratio: 1216 / 400; + overflow: hidden; + border-radius: var(--radius-card); + isolation: isolate; + } + .lp-banner-scrim { + position: absolute; + inset: 0; + background: linear-gradient( + 90deg, + rgb(0 0 70 / 0.85) 0%, + rgb(0 0 70 / 0.5) 45%, + rgb(0 0 70 / 0.05) 80% + ); + } + /* Vertically centred on the left, over the darkest part of the scrim. */ + .lp-banner-content { + position: absolute; + inset: 0 24px 0 clamp(24px, 3.5vw, 44px); + display: flex; + flex-direction: column; + align-items: flex-start; + justify-content: center; + } + .lp-banner-heading { + color: #fff; + font-family: var(--font-display); + font-size: clamp(28px, 3.3vw, 46px); + font-weight: 500; + line-height: 1.1; + letter-spacing: -0.025em; + } + .lp-banner-mark { + position: absolute; + right: clamp(20px, 3vw, 36px); + bottom: clamp(16px, 2.5vw, 28px); + color: #fff; + font-family: var(--font-display); + font-size: 20px; + font-weight: 700; + letter-spacing: -0.02em; + } + .lp-banner-mark span { + font-weight: 400; + opacity: 0.8; + } + + /* ---- Tinted bands ---- */ + .lp-band { + background: linear-gradient(180deg, var(--color-paper) 0%, var(--lp-tint) 22%, var(--lp-tint) 100%); + } + .lp-band-frame { + padding-top: var(--lp-space); + } + .lp-band-heading { + font-family: var(--font-display); + font-size: clamp(30px, 3.4vw, 48px); + font-weight: 500; + line-height: 1.1; + letter-spacing: -0.025em; + color: var(--color-ink); + text-align: center; + } + /* Stats menu: one stat active at a time, marked by a gradient indicator + that slides along both rules (components/landing/trust-stats.tsx). */ + .lp-stats { + position: relative; + margin-top: clamp(40px, 5vw, 64px); + margin-inline: calc(-1 * var(--lp-gutter)); + border-block: 1px solid var(--lp-line); + } + .lp-stats-list { + display: grid; + grid-template-columns: repeat(var(--lp-count, 4), minmax(0, 1fr)); + } + .lp-stats-indicator { + position: absolute; + left: 0; + width: calc(100% / var(--lp-count, 4)); + height: 1px; + background: linear-gradient(90deg, transparent, var(--color-brand) 30%, var(--color-brand-soft) 70%, transparent); + transform: translateX(calc(var(--lp-active, 0) * 100%)); + transition: transform 600ms cubic-bezier(0.65, 0, 0.35, 1); + pointer-events: none; + } + .lp-stats-indicator-top { + top: -1px; + } + .lp-stats-indicator-bottom { + bottom: -1px; + } + .lp-stat { + display: flex; + flex-direction: column; + align-items: center; + padding: 28px 16px 20px; + text-align: center; + } + .lp-stat-button { + display: flex; + flex-direction: column; + align-items: center; + gap: 6px; + border-radius: var(--radius-control); + cursor: pointer; + } + .lp-stat-value { + color: var(--lp-quiet); + font-family: var(--font-display); + font-size: clamp(34px, 3.2vw, 46px); + font-weight: 500; + line-height: 1; + letter-spacing: -0.03em; + transition: color 300ms ease; + } + .lp-stat-label { + max-width: 20ch; + color: var(--color-body-copy); + font-size: 13.5px; + line-height: 1.45; + } + .lp-stat-button:hover .lp-stat-value, + .lp-stat-active .lp-stat-value { + color: var(--color-ink); + } + .lp-stat-link { + display: inline-flex; + align-items: center; + gap: 2px; + margin-top: 10px; + color: var(--color-ink-soft); + font-size: 13px; + font-weight: 600; + opacity: 0; + transform: translateY(4px); + transition: opacity 300ms ease, transform 300ms ease; + pointer-events: none; + } + .lp-stat-active .lp-stat-link { + opacity: 1; + transform: none; + pointer-events: auto; + } + .lp-stat-link:hover { + color: var(--color-ink); + } + .lp-burst { + display: block; + width: calc(100% + 2 * var(--lp-gutter)); + height: clamp(220px, 26vw, 340px); + margin-inline: calc(-1 * var(--lp-gutter)); + cursor: crosshair; + touch-action: pan-y; + } + + /* ---- Split rows (heading + action | paragraph) ---- */ + .lp-split { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); + align-items: start; + gap: clamp(24px, 6vw, 96px); + padding-bottom: clamp(32px, 4vw, 48px); + } + .lp-split-solo { + padding-bottom: var(--lp-space); + } + .lp-split-heading { + max-width: 22ch; + font-family: var(--font-display); + font-size: clamp(22px, 2vw, 28px); + font-weight: 500; + line-height: 1.25; + letter-spacing: -0.015em; + color: var(--color-ink); + } + .lp-split-text { + max-width: 52ch; + color: var(--color-body-copy); + font-size: 16px; + line-height: 1.65; + } + .lp-split-text strong { + color: var(--color-ink); + } + + /* ---- Case study ---- */ + .lp-story-head { + display: flex; + align-items: center; + gap: 12px; + margin-bottom: 16px; + } + .lp-story-head p { + flex: 1; + color: var(--color-ink); + font-family: var(--font-display); + font-size: 18px; + font-weight: 500; + } + .lp-story-mark { + display: grid; + flex-shrink: 0; + place-items: center; + width: 32px; + height: 32px; + border-radius: var(--radius-control); + background: var(--color-brand); + color: var(--color-brand-ink); + } + .lp-story-link { + padding: 6px 14px; + border: 1px solid var(--lp-line); + border-radius: 999px; + font-size: 13.5px; + } + .lp-story-photo { + position: relative; + aspect-ratio: 1216 / 440; + overflow: hidden; + border-radius: var(--radius-card); + } + .lp-story-facts { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 16px; + margin: 16px 0 32px; + } + .lp-story-facts div { + display: flex; + flex-wrap: wrap; + align-items: baseline; + gap: 6px; + } + .lp-story-facts dt { + color: var(--color-ink); + font-family: var(--font-display); + font-size: 15px; + font-weight: 600; + } + .lp-story-facts dd { + color: var(--color-body-copy); + font-size: 13.5px; + } + .lp-accordion { + border-top: 1px solid var(--lp-line); + } + .lp-accordion-row { + border-bottom: 1px solid var(--lp-line); + } + .lp-accordion-row summary { + display: flex; + align-items: center; + gap: 14px; + padding-block: 16px; + cursor: pointer; + list-style: none; + } + .lp-accordion-row summary::-webkit-details-marker { + display: none; + } + .lp-accordion-mark { + display: grid; + flex-shrink: 0; + place-items: center; + width: 32px; + height: 32px; + border: 1px solid var(--lp-line); + border-radius: var(--radius-control); + background: var(--lp-tint); + color: var(--color-ink-soft); + } + .lp-accordion-title { + flex: 1; + color: var(--color-ink); + font-family: var(--font-display); + font-size: 17px; + font-weight: 500; + } + .lp-accordion-toggle { + display: grid; + flex-shrink: 0; + place-items: center; + width: 28px; + height: 28px; + border-radius: 6px; + background: color-mix(in srgb, var(--color-brand) 12%, transparent); + color: var(--color-ink-soft); + transition: transform 200ms ease; + } + .lp-accordion-row[open] .lp-accordion-toggle { + transform: rotate(45deg); + } + .lp-accordion-row p { + max-width: 70ch; + padding: 0 0 20px 46px; + color: var(--color-body-copy); + font-size: 15px; + line-height: 1.65; + } + + /* ---- Journey carousel ---- */ + .lp-carousel-controls { + display: flex; + justify-content: flex-end; + gap: 8px; + margin-bottom: 16px; + } + .lp-carousel-button { + display: grid; + place-items: center; + width: 32px; + height: 32px; + border: 1px solid var(--lp-line); + border-radius: var(--radius-control); + background: var(--color-surface); + color: var(--color-ink-soft); + transition: background 150ms ease; + } + .lp-carousel-button:hover { + background: color-mix(in srgb, var(--color-brand) 12%, var(--color-surface)); + } + .lp-carousel-track { + display: grid; + grid-auto-columns: calc((100% - 3 * 16px) / 3.5); + grid-auto-flow: column; + gap: 16px; + margin-right: calc(-1 * var(--lp-gutter)); + padding-right: var(--lp-gutter); + overflow-x: auto; + overscroll-behavior-x: contain; + scroll-snap-type: x mandatory; + scrollbar-width: none; + } + .lp-carousel-track::-webkit-scrollbar { + display: none; + } + .lp-journey-card { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 12px; + scroll-snap-align: start; + } + .lp-journey-photo { + position: relative; + width: 100%; + aspect-ratio: 3 / 4; + overflow: hidden; + border-radius: var(--radius-card); + } + .lp-journey-text { + color: var(--color-body-copy); + font-size: 14.5px; + line-height: 1.55; + } + .lp-journey-text strong { + color: var(--color-ink); + } + + .lp-promos { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 16px; + margin-top: 40px; + } + .lp-promo { + position: relative; + display: flex; + flex-direction: column; + justify-content: space-between; + gap: 16px; + min-height: 160px; + padding: 24px 44% 24px 24px; + overflow: hidden; + border: 1px solid var(--lp-line); + border-radius: var(--radius-card); + background: var(--lp-tint); + transition: border-color 200ms ease; + } + .lp-promo:hover { + border-color: color-mix(in srgb, var(--color-brand) 45%, transparent); + } + .lp-promo p { + color: var(--color-body-copy); + font-size: 14.5px; + line-height: 1.55; + } + .lp-promo strong { + color: var(--color-ink); + } + .lp-promo-art { + position: absolute; + top: 0; + right: 0; + bottom: 0; + width: 40%; + } + .lp-promo-art-a { + background: linear-gradient(135deg, var(--color-brand-soft), var(--color-brand) 45%, var(--lp-navy)); + clip-path: polygon(38% 0, 100% 0, 100% 100%, 0 100%); + } + .lp-promo-art-b { + background: linear-gradient(200deg, var(--lp-blue-deep), var(--color-brand) 50%, var(--color-brand-soft)); + clip-path: polygon(100% 0, 100% 100%, 0 100%); + } + + /* ---- Hiring showcase ---- */ + .lp-showcase { + position: relative; + display: flex; + align-items: center; + justify-content: center; + min-height: 340px; + padding: clamp(24px, 5vw, 56px); + overflow: hidden; + border-radius: var(--radius-card); + background: + repeating-linear-gradient(115deg, rgb(255 255 255 / 0.1) 0 1px, transparent 1px 7px), + linear-gradient(120deg, var(--color-brand-soft), var(--color-brand) 38%, var(--lp-blue-deep) 72%, var(--lp-navy)); + } + .lp-showcase-card { + width: min(460px, 100%); + padding: 20px; + border-radius: var(--radius-card); + background: var(--color-surface); + box-shadow: 0 24px 48px -12px rgb(0 0 70 / 0.35); + color: var(--color-body-copy); + font-size: 12.5px; + } + .lp-showcase-rows { + margin-top: 14px; + } + .lp-showcase-rows li { + display: grid; + grid-template-columns: 70px minmax(0, 1fr) auto; + align-items: center; + gap: 10px; + padding-block: 10px; + border-bottom: 1px solid var(--lp-line); + } + .lp-showcase-rows strong { + color: var(--color-ink); + font-weight: 600; + } + .lp-showcase-rows em { + padding: 2px 9px; + border-radius: 999px; + background: color-mix(in srgb, var(--color-success) 13%, transparent); + color: var(--color-success); + font-size: 11px; + font-style: normal; + font-weight: 600; + } + .lp-showcase-cta { + margin-top: 16px; + padding: 9px; + border-radius: 999px; + background: var(--color-brand); + color: var(--color-brand-ink); + font-weight: 600; + text-align: center; + } + + .lp-features { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 32px; + margin-top: 40px; + } + .lp-features li { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 10px; + } + .lp-features p { + color: var(--color-body-copy); + font-size: 14.5px; + line-height: 1.6; + } + .lp-features strong { + color: var(--color-ink); + } + .lp-feature-icon { + display: grid; + place-items: center; + width: 32px; + height: 32px; + border: 1px solid var(--lp-line); + border-radius: var(--radius-control); + background: var(--lp-tint); + color: var(--color-ink-soft); + } + + .lp-quote { + display: flex; + flex-direction: column; + align-items: center; + gap: 16px; + max-width: 760px; + margin: clamp(56px, 7vw, 88px) auto 0; + text-align: center; + } + .lp-quote blockquote { + color: var(--lp-quiet); + font-family: var(--font-display); + font-size: clamp(20px, 2vw, 26px); + line-height: 1.4; + letter-spacing: -0.01em; + } + .lp-quote figcaption { + color: var(--color-body-copy); + font-size: 14px; + } + .lp-quote figcaption strong { + color: var(--color-ink); + } + + /* ---- Navy infrastructure band ---- */ + .lp-dark { + --lp-line: color-mix(in srgb, var(--color-on-inverse) 14%, transparent); + --lp-quiet: color-mix(in srgb, var(--color-on-inverse) 58%, var(--color-brand-soft)); + background: color-mix(in srgb, var(--lp-navy) 72%, #000); + color: var(--color-on-inverse); + } + /* On the black dark-theme page the band needs its own navy to read as a band. */ + [data-theme="dark"] .lp-dark { + background: color-mix(in srgb, var(--lp-navy) 36%, #000); + } + .lp-dark .lp-statement { + color: var(--color-on-inverse); + } + .lp-dark-actions { + display: flex; + flex-wrap: wrap; + gap: 12px; + margin-top: 32px; + } + .lp-flow { + margin-top: 48px; + padding: clamp(28px, 4vw, 48px) clamp(16px, 3vw, 32px); + border: 1px solid var(--lp-line); + border-radius: var(--radius-card); + background-image: radial-gradient(color-mix(in srgb, var(--color-on-inverse) 14%, transparent) 1px, transparent 1px); + background-size: 16px 16px; + } + .lp-flow-row { + display: flex; + align-items: center; + justify-content: center; + gap: 10px; + } + .lp-flow-node { + padding: 10px 14px; + border: 1px solid color-mix(in srgb, var(--color-brand) 50%, transparent); + border-radius: var(--radius-control); + background: color-mix(in srgb, var(--color-brand) 16%, transparent); + text-align: center; + } + .lp-flow-node span { + display: block; + color: var(--color-on-inverse); + font-size: 13px; + font-weight: 600; + white-space: nowrap; + } + .lp-flow-node em { + display: block; + margin-top: 2px; + color: var(--lp-quiet); + font-size: 11px; + font-style: normal; + white-space: nowrap; + } + .lp-flow-node-core { + border-color: var(--color-brand); + background: var(--color-brand); + box-shadow: 0 0 0 6px color-mix(in srgb, var(--color-brand) 22%, transparent); + } + .lp-flow-node-core span, + .lp-flow-node-core em { + color: var(--color-brand-ink); + } + .lp-flow-split { + display: flex; + flex-direction: column; + gap: 10px; + } + .lp-flow-arrow { + flex-shrink: 0; + color: var(--lp-quiet); + } + .lp-flow-ledger { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: center; + gap: 10px 14px; + width: fit-content; + max-width: 100%; + margin: 32px auto 0; + padding: 10px 18px; + border: 1px dashed var(--lp-line); + border-radius: 999px; + color: var(--lp-quiet); + font-size: 13px; + text-align: center; + } + .lp-flow-ledger strong { + color: var(--color-on-inverse); + } + .lp-flow-tag { + padding: 2px 9px; + border-radius: 999px; + background: color-mix(in srgb, var(--color-brand) 24%, transparent); + color: var(--color-brand-soft); + font-size: 11px; + font-weight: 600; + } + .lp-flow-ledger-link { + display: inline-flex; + align-items: center; + gap: 4px; + color: var(--color-brand-soft); + font-weight: 600; + } + .lp-flow-ledger-link:hover { + color: var(--color-on-inverse); + } + .lp-waves { + display: block; + width: calc(100% + 2 * var(--lp-gutter)); + height: clamp(150px, 20vw, 260px); + margin: 16px calc(-1 * var(--lp-gutter)) 8px; + } + .lp-dark-stats { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 24px; + } + .lp-dark-stats li { + display: flex; + flex-direction: column; + gap: 6px; + color: var(--lp-quiet); + font-size: 14px; + } + .lp-dark-stat-value { + width: fit-content; + background: linear-gradient(90deg, var(--color-brand-soft), var(--color-brand)); + -webkit-background-clip: text; + background-clip: text; + color: transparent; + font-family: var(--font-display); + font-size: clamp(40px, 4.4vw, 60px); + font-weight: 500; + line-height: 1.05; + letter-spacing: -0.03em; + } + .lp-paths { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 16px; + margin-top: 40px; + } + .lp-path { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 14px; + } + .lp-path p { + color: var(--lp-quiet); + font-size: 14.5px; + line-height: 1.6; + } + .lp-path strong { + color: var(--color-on-inverse); + } + .lp-path-visual { + display: flex; + flex-direction: column; + justify-content: center; + gap: 8px; + width: 100%; + height: 200px; + margin: 0; + padding: 20px; + overflow: hidden; + border: 1px solid var(--lp-line); + border-radius: var(--radius-card); + background: color-mix(in srgb, var(--color-brand) 10%, transparent); + } + .lp-path-event { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; + padding: 10px 12px; + border: 1px solid var(--lp-line); + border-radius: var(--radius-control); + background: color-mix(in srgb, var(--color-on-inverse) 7%, transparent); + font-size: 12px; + font-weight: 500; + } + .lp-path-event em { + display: inline-flex; + flex-shrink: 0; + align-items: center; + gap: 4px; + color: var(--color-brand-soft); + font-size: 10.5px; + font-style: normal; + font-weight: 600; + } + .lp-path-step { + display: flex; + align-items: center; + gap: 10px; + color: var(--lp-quiet); + font-size: 12.5px; + } + .lp-path-step span { + display: grid; + place-items: center; + width: 22px; + height: 22px; + border: 1px solid var(--lp-line); + border-radius: 50%; + font-size: 10.5px; + font-weight: 600; + } + .lp-path-step-done { + color: var(--color-on-inverse); + } + .lp-path-step-done span { + border-color: var(--color-brand); + background: var(--color-brand); + color: var(--color-brand-ink); + } + .lp-path-code { + justify-content: flex-start; + color: var(--color-on-inverse); + font-family: ui-monospace, SFMono-Regular, Menlo, monospace; + font-size: 12.5px; + line-height: 1.85; + white-space: pre; + } + .lp-code-dim { + margin-right: 6px; + opacity: 0.4; + } + .lp-code-key { + color: var(--color-brand-soft); + } + .lp-code-ok { + color: #36d399; + } + + /* ---- Latest posts ---- */ + .lp-latest { + display: grid; + grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); + gap: 16px 32px; + margin-top: 40px; + } + .lp-latest-feature { + position: relative; + min-height: 300px; + aspect-ratio: 16 / 8; + overflow: hidden; + border-radius: var(--radius-card); + isolation: isolate; + } + .lp-latest-feature img { + transition: transform 500ms ease; + } + .lp-latest-feature:hover img { + transform: scale(1.03); + } + .lp-latest-scrim { + position: absolute; + inset: 0; + background: linear-gradient(180deg, transparent 35%, rgb(0 0 70 / 0.82)); + } + .lp-latest-category { + position: absolute; + top: 16px; + left: 16px; + padding: 3px 10px; + border-radius: 999px; + background: rgb(255 255 255 / 0.88); + color: #000092; + font-size: 11px; + font-weight: 600; + } + .lp-latest-title { + position: absolute; + right: 24px; + bottom: 22px; + left: 24px; + color: #fff; + font-family: var(--font-display); + font-size: clamp(22px, 2.4vw, 32px); + font-weight: 500; + line-height: 1.15; + letter-spacing: -0.02em; + } + .lp-latest-list { + border-top: 1px solid var(--lp-line); + } + .lp-latest-list li { + border-bottom: 1px solid var(--lp-line); + } + .lp-latest-item { + display: block; + padding-block: 18px; + } + .lp-latest-meta { + display: block; + color: var(--color-muted); + font-size: 12px; + font-weight: 500; + } + .lp-latest-item-title { + display: block; + margin-top: 4px; + color: var(--color-ink); + font-family: var(--font-display); + font-size: 17px; + font-weight: 500; + line-height: 1.35; + transition: color 150ms ease; + } + .lp-latest-item:hover .lp-latest-item-title { + color: var(--color-ink-soft); + } + .lp-latest-foot { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 24px; + margin-top: 24px; + } + .lp-latest-foot p { + max-width: 64ch; + color: var(--color-body-copy); + font-size: 15px; + line-height: 1.6; + } + .lp-latest-foot strong { + color: var(--color-ink); + } + + /* ---- Get started ---- */ + .lp-band-end { + background: var(--lp-tint); + } + .lp-start { + display: grid; + grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr) minmax(0, 1fr); + align-items: start; + gap: 40px; + } + .lp-start-heading { + color: var(--color-ink); + font-family: var(--font-display); + font-size: clamp(26px, 2.6vw, 34px); + font-weight: 500; + line-height: 1.2; + letter-spacing: -0.02em; + } + .lp-start-text { + max-width: 44ch; + margin-top: 14px; + color: var(--color-body-copy); + font-size: 16px; + line-height: 1.6; + } + .lp-start-item { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 8px; + padding-top: 8px; + color: var(--color-body-copy); + font-size: 14.5px; + line-height: 1.6; + } + .lp-start-item-title { + margin-top: 6px; + color: var(--color-ink); + font-weight: 600; + } + + /* ---- Responsive ---- */ + @media (max-width: 1023px) { + .lp-frame { + border-inline-color: transparent; + } + .lp-bento { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + .lp-bento-wide { + grid-column: 1 / -1; + } + .lp-bento-full { + grid-template-columns: minmax(0, 1fr); + } + .lp-bento-full .lp-card-visual { + padding-top: 0; + } + .lp-stats-list { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + .lp-stat:nth-child(-n + 2) { + border-bottom: 1px solid var(--lp-line); + } + /* In the 2x2 grid the sliding rule has no single track, so the active + stat gets a tint instead. */ + .lp-stats-indicator { + display: none; + } + .lp-stat-active { + background: color-mix(in srgb, var(--color-brand) 7%, transparent); + } + .lp-split, + .lp-latest, + .lp-promos { + grid-template-columns: minmax(0, 1fr); + } + .lp-carousel-track { + grid-auto-columns: calc((100% - 16px) / 2.3); + } + .lp-features, + .lp-paths { + grid-template-columns: minmax(0, 1fr); + gap: 32px; + } + .lp-flow-row { + flex-direction: column; + } + .lp-flow-arrow { + transform: rotate(90deg); + } + .lp-flow-split { + flex-direction: row; + } + .lp-start { + grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); + } + .lp-start > :first-child { + grid-column: 1 / -1; + } + } + + @media (max-width: 639px) { + .lp-ribbon { + width: 120vw; + height: 58%; + right: -30vw; + opacity: 0.85; + } + .lp-hero-inner { + padding-top: 42vw; + } + .lp-hero-actions > * { + flex: 1 1 100%; + } + .lp-bento { + grid-template-columns: minmax(0, 1fr); + } + .lp-card { + min-height: 380px; + } + .lp-mock-pair { + grid-template-columns: minmax(0, 1fr); + } + .lp-mock-vault { + display: none; + } + .lp-mock-dash-body { + grid-template-columns: minmax(0, 1fr); + } + .lp-mock-dash-nav { + display: none; + } + .lp-mock-dash-main { + padding-left: 0; + } + .lp-mock-dash-stats { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + .lp-banner { + aspect-ratio: auto; + min-height: 360px; + } + .lp-banner-scrim { + background: linear-gradient(180deg, rgb(0 0 70 / 0.85), rgb(0 0 70 / 0.35)); + } + .lp-story-head { + flex-wrap: wrap; + } + .lp-story-head p { + flex-basis: calc(100% - 44px); + } + .lp-story-photo { + aspect-ratio: 4 / 3; + } + .lp-story-facts { + grid-template-columns: minmax(0, 1fr); + gap: 8px; + } + .lp-carousel-track { + grid-auto-columns: 75%; + } + .lp-promo { + padding-right: 24px; + padding-bottom: 96px; + } + .lp-promo-art { + top: auto; + width: 100%; + height: 72px; + } + .lp-dark-stats { + grid-template-columns: minmax(0, 1fr); + } + .lp-flow-split { + flex-direction: column; + } + .lp-latest-feature { + min-height: 0; + aspect-ratio: 4 / 3; + } + .lp-latest-foot { + flex-direction: column; + } + .lp-start { + grid-template-columns: minmax(0, 1fr); + } + } +} diff --git a/components/landing/audience-sections.tsx b/components/landing/audience-sections.tsx new file mode 100644 index 0000000..c6279d4 --- /dev/null +++ b/components/landing/audience-sections.tsx @@ -0,0 +1,336 @@ +import Image from "next/image"; +import Link from "next/link"; +import { + BadgeCheck, + CalendarCheck, + Camera, + Handshake, + ListChecks, + Plus, + ShieldCheck, + Sparkles, + type LucideIcon, +} from "lucide-react"; + +import { JourneyCarousel } from "@/components/landing/journey-carousel"; +import { LandingLink, TextLink } from "@/components/landing/landing-link"; + +const GITHUB_URL = "https://github.com/CodeWithEugene/HackVillage"; + +const ORGANIZER_FACTS = [ + { value: "100%", label: "deposited before launch" }, + { value: "5%", label: "platform fee, paid on top of the pool" }, + { value: "30 days", label: "for each winner's milestone" }, +] as const; + +const ORGANIZER_ROWS: { Icon: LucideIcon; title: string; body: string }[] = [ + { + Icon: ListChecks, + title: "Judges score every team against the same rubric.", + body: "Invite judges by email, set weighted criteria, and send every team written feedback alongside its scores, so results are something people can check rather than argue about.", + }, + { + Icon: Camera, + title: "Photos and recaps are due within 48 hours of the close.", + body: "Media lands on the hackathon page while people still care, and the deadline counts toward the organizer's public Trust Score.", + }, + { + Icon: CalendarCheck, + title: "Three months later, winners check in on what they shipped.", + body: "Legacy check-ins keep a record of what happened after demo day, and disputes go to the HackVillage team with the money still locked in escrow.", + }, +]; + +const JOURNEY = [ + { + image: "kenyan-developer-building-hackathon-project", + alt: "Kenyan software engineer building her hackathon project", + title: "Build with a team.", + body: "Form a team or join one with an invite code, then ship before the deadline.", + href: "/hackathons", + link: "Find a hackathon", + }, + { + image: "developer-demoing-mobile-app", + alt: "Kenyan developer demonstrating the mobile app he built", + title: "Demo to real judges.", + body: "Every team is scored on the same published rubric and gets written feedback.", + href: "/blog/judging-scorecards-teams-trust", + link: "How judging works", + }, + { + image: "hackathon-winner-with-trophy-and-laptop", + alt: "Kenyan hackathon winner holding her trophy and laptop", + title: "Win a funded prize.", + body: "The prize was deposited in escrow before you wrote a single line of code.", + href: "/how-escrow-works", + link: "How escrow works", + }, + { + image: "developer-receiving-hackathon-prize-payout", + alt: "Kenyan developer checking his phone after receiving a prize payout", + title: "Get paid in minutes.", + body: "Half your prize goes to M-Pesa or your bank the moment results are announced.", + href: "/blog/how-winners-get-paid", + link: "How winners get paid", + }, + { + image: "engineer-presenting-portfolio-to-hiring-manager", + alt: "Kenyan engineer presenting her project portfolio to a hiring manager", + title: "Get hired on proof.", + body: "Hiring teams request intros from your verified Proof-of-Work profile.", + href: "/blog/proof-of-work-portfolio", + link: "Build your portfolio", + }, +] as const; + +const HIRING_FEATURES: { + Icon: LucideIcon; + title: string; + body: string; + href: string; + link: string; +}[] = [ + { + Icon: BadgeCheck, + title: "Verified results.", + body: "Every win on a profile is tied to a real hackathon with a funded, escrowed prize.", + href: "/how-escrow-works", + link: "How results are verified", + }, + { + Icon: Sparkles, + title: "Judge endorsements.", + body: "Judges who scored a project can endorse its builders, on the record and by name.", + href: "/blog/proof-of-work-portfolio", + link: "Read about Proof-of-Work", + }, + { + Icon: Handshake, + title: "Warm introductions.", + body: "Request an intro from a builder's profile. They decide whether to reply, and when.", + href: "/hiring/join", + link: "Become a hiring partner", + }, +]; + +function OrganizersBlock() { + return ( + <> +
+
+

Host a hackathon people trust from day one

+ + HackVillage For Organizers + +
+

+ Deposit the prize pool once through Paystack and HackVillage handles the rest: the Prize + Verified badge, judge invitations, results, payouts and a paper trail anyone can check. +

+
+ +
+
+
+ + + +

Every prize pool is funded before registration opens.

+ + Read how escrow works + +
+
+ Kenyan organizers planning a hackathon challenge at a laptop +
+
+ {ORGANIZER_FACTS.map((fact) => ( +
+
{fact.value}
+
{fact.label}
+
+ ))} +
+
+ {ORGANIZER_ROWS.map(({ Icon, title, body }) => ( +
+ + + {title} + + +

{body}

+
+ ))} +
+
+
+ + ); +} + +function BuildersBlock() { + return ( + <> +
+
+

Build a portfolio that proves what you shipped

+ + Explore Hackathons + +
+

+ Join a team, ship your project and get half your prize the moment you win. Every result, + endorsement and payout lands on your public developer profile. +

+
+ +
+ + {JOURNEY.map((step) => ( +
  • +
    + {step.alt} +
    +

    + {step.title} {step.body} +

    + {step.link} +
  • + ))} +
    + +
    + +

    + Open source, end to end. Read every line of the escrow and payout + code, open an issue, or ship a fix. +

    + View on GitHub +
    + +

    + New to hackathons? What to bring, how teams form, and how to finish + your first one with something you are proud of. +

    + Read the guide +
    +
    + + ); +} + +function HiringBlock() { + return ( + <> +
    +
    +

    Hire from verified Proof-of-Work, not CVs

    + + Join The Hiring Network + +
    +

    + Every HackVillage profile is built from real results: projects scored by judges, prizes + actually paid, and follow-ups three months on. Find builders by what they shipped. +

    +
    + +
    + + +
      + {HIRING_FEATURES.map(({ Icon, title, body, href, link }) => ( +
    • + + + +

      + {title} {body} +

      + {link} +
    • + ))} +
    + +
    +
    + “If the prize isn't in the vault, the hackathon doesn't go live. Every + payout after that is on the record.” +
    +
    + The HackVillage escrow rule, enforced in code since v1.0 +
    + See the public ledger +
    +
    + + ); +} + +export function AudienceSections() { + return ( +
    +
    +

    + Built for everyone in the room.{" "} + + Organizers, builders, judges and hiring teams each get tools that fit how they already + work. + +

    +
    + + + +
    + ); +} diff --git a/components/landing/get-started.tsx b/components/landing/get-started.tsx new file mode 100644 index 0000000..b1c3175 --- /dev/null +++ b/components/landing/get-started.tsx @@ -0,0 +1,49 @@ +import { Code2, ReceiptText } from "lucide-react"; + +import { LandingLink, TextLink } from "@/components/landing/landing-link"; + +const CONTACT_EMAIL = "info@hackvillage.xyz"; + +/** Closing call to action, Stripe's "Ready to get started?" block. */ +export function GetStarted() { + return ( +
    +
    +
    +

    + Ready to run a hackathon people trust? +

    +

    + Create an account in minutes, or talk to us about a hackathon series for your community, + campus or company. +

    +
    + Sign Up + + Contact Us + +
    +
    +
    + + + +

    Transparent pricing

    +

    + A flat 5% platform fee, paid by the organizer on top of the prize pool. Winners keep + every shilling. +

    + How escrow works +
    +
    + + + +

    Start contributing

    +

    Open source and ready to run locally, with seeded demo data, in a few commands.

    + Contributor guide +
    +
    +
    + ); +} diff --git a/components/landing/journey-carousel.tsx b/components/landing/journey-carousel.tsx new file mode 100644 index 0000000..e6b7d86 --- /dev/null +++ b/components/landing/journey-carousel.tsx @@ -0,0 +1,47 @@ +"use client"; + +import { useRef } from "react"; +import { ArrowLeft, ArrowRight } from "lucide-react"; + +/** + * A horizontally scrolling row with Stripe-style prev/next buttons. The + * cards are server-rendered children; this only adds the scroll controls, + * and the row still scrolls by touch, trackpad or keyboard without them. + */ +export function JourneyCarousel({ label, children }: { label: string; children: React.ReactNode }) { + const trackRef = useRef(null); + + const scroll = (direction: 1 | -1) => { + const track = trackRef.current; + if (!track) return; + const card = track.querySelector("li"); + const step = card ? card.getBoundingClientRect().width + 16 : track.clientWidth * 0.8; + track.scrollBy({ left: direction * step, behavior: "smooth" }); + }; + + return ( +
    +
    + + +
    +
      + {children} +
    +
    + ); +} diff --git a/components/landing/landing-about.tsx b/components/landing/landing-about.tsx new file mode 100644 index 0000000..a9d2439 --- /dev/null +++ b/components/landing/landing-about.tsx @@ -0,0 +1,31 @@ +import { LandingLink } from "@/components/landing/landing-link"; + +/** + * A short, plain answer to "What is HackVillage?" for visitors, search + * engines and AI answer engines. It names the brand both ways people search + * for it and states only what the platform already enforces in code, so an + * engine quoting it never repeats something that isn't true. + */ +export function LandingAbout() { + return ( +
    +
    +
    +

    + What Is HackVillage? +

    + + How It Works + +
    +

    + HackVillage (also written Hack Village) is an open-source hackathon + platform for Kenya and Africa. Organizers deposit the full prize pool into escrow before a + hackathon goes live, so every prize listed here is funded, and winners are paid half of + their prize as soon as results are announced. Every result also builds the winner's + Proof-of-Work developer profile. +

    +
    +
    + ); +} diff --git a/components/landing/landing-banner.tsx b/components/landing/landing-banner.tsx new file mode 100644 index 0000000..cde8997 --- /dev/null +++ b/components/landing/landing-banner.tsx @@ -0,0 +1,36 @@ +import Image from "next/image"; + +import { LandingLink } from "@/components/landing/landing-link"; + +/** The full-width feature banner: one photo, one promise, one next step. */ +export function LandingBanner() { + return ( +
    +
    +
    + Kenyan developers planning their hackathon project together in Nairobi + +
    +
    + ); +} diff --git a/components/landing/landing-hero.tsx b/components/landing/landing-hero.tsx new file mode 100644 index 0000000..83819f3 --- /dev/null +++ b/components/landing/landing-hero.tsx @@ -0,0 +1,110 @@ +import { LandingLink } from "@/components/landing/landing-link"; +import { HOST_HACKATHON_HREF } from "@/lib/auth/signup-links"; + +/* + * The ribbon's two edges, as cubic Béziers from the top of the hero to its + * right edge. Strands are drawn by interpolating between them, so they + * always sit inside the band and follow its curve. + */ +const EDGE_A = [ + [330, -20], + [400, 250], + [620, 420], + [1020, 430], +] as const; +const EDGE_B = [ + [610, -20], + [480, 330], + [650, 650], + [1020, 720], +] as const; + +function lerpCurve(t: number): string { + const p = EDGE_A.map(([ax, ay], i) => { + const [bx, by] = EDGE_B[i]; + return `${(ax + (bx - ax) * t).toFixed(1)} ${(ay + (by - ay) * t).toFixed(1)}`; + }); + return `M ${p[0]} C ${p[1]}, ${p[2]}, ${p[3]}`; +} + +const STRANDS = Array.from({ length: 48 }, (_, i) => lerpCurve(i / 47)); + +const BAND = `M 330 -20 C 400 250, 620 420, 1020 430 L 1020 720 C 650 650, 480 330, 610 -20 Z`; +const FOLD = `M 520 -20 C 540 250, 700 470, 1020 560 L 1020 660 C 700 600, 560 330, 600 -20 Z`; + +/** + * The hero ribbon: a broad band in the brand blues, a darker fold across + * it, and combed strands for the silky texture, bleeding off the top-right + * corner. Pure SVG, so it themes with the tokens and costs nothing to load. + */ +function HeroRibbon() { + return ( + + ); +} + +export function LandingHero() { + return ( +
    + +
    +

    + Prize pools escrowed before a hackathon goes live: 100% +

    +

    + Hackathon infrastructure that pays winners on time.{" "} + + Escrow the full prize pool before launch, pay winners half the moment results land, and + turn every submission into a verified Proof-of-Work portfolio. + +

    +
    + Browse Hackathons + + Host A Hackathon + +
    +
    +
    + ); +} diff --git a/components/landing/landing-link.tsx b/components/landing/landing-link.tsx new file mode 100644 index 0000000..3e24891 --- /dev/null +++ b/components/landing/landing-link.tsx @@ -0,0 +1,68 @@ +import Link from "next/link"; +import { ArrowUpRight, ChevronRight } from "lucide-react"; + +import { buttonVariants } from "@/components/ui/button"; +import { cn } from "@/lib/utils"; + +interface LandingLinkProps { + href: string; + children: React.ReactNode; + variant?: "primary" | "secondary" | "inverse"; + className?: string; + external?: boolean; +} + +/** + * A navigation link dressed as the pill button, so the landing page keeps the + * button design system (sweep fill + nudging arrow) without nesting a + * + + {stat.link} + + + + ); + })} + +
    + + + ); +} diff --git a/components/patterns/builder-journey.tsx b/components/patterns/builder-journey.tsx deleted file mode 100644 index 1e3d981..0000000 --- a/components/patterns/builder-journey.tsx +++ /dev/null @@ -1,121 +0,0 @@ -import Image from "next/image"; -import Link from "next/link"; -import { ArrowUpRight } from "lucide-react"; -import { Sparkle } from "@/components/patterns/sparkle"; -import { HOST_HACKATHON_HREF } from "@/lib/auth/signup-links"; - -const ARC_TEXT = "Verified. Paid. Proven."; - -interface PillPhotoProps { - name: string; - alt: string; - className?: string; -} - -function PillPhoto({ name, alt, className }: PillPhotoProps) { - return ( -
    - {alt} -
    - ); -} - -export function BuilderJourney() { - return ( -
    -
    -
    - -

    - - Build -
    - Ship -
    - Win -
    - Build, Ship, Win -

    -

    - Every prize is fully deposited before the first line of code, so builders across - Africa compete for money that is already there. -

    - - - - Host A Hackathon - - -
    -
    - - -
    -
    - -
    - -
    - Kenyan hackathon winner holding her trophy and laptop -
    -
    - -
    -
    - - -
    -
    - -

    - Half your prize lands the moment you win. Ship your milestone and the rest follows, with - every payout recorded on a public ledger. -

    -
    -

    - Get Paid -
    - Get Seen -
    - Get Hired -

    - - - - Explore Hackathons - - -
    -
    -
    -
    - ); -} diff --git a/components/patterns/landing-about.tsx b/components/patterns/landing-about.tsx deleted file mode 100644 index c390036..0000000 --- a/components/patterns/landing-about.tsx +++ /dev/null @@ -1,24 +0,0 @@ -/** - * A short, plain answer to "What is HackVillage?" for visitors, search - * engines and AI answer engines. It names the brand both ways people search - * for it and states only what the platform already enforces in code, so an - * engine quoting it never repeats something that isn't true. - */ -export function LandingAbout() { - return ( -
    -
    -

    - What Is HackVillage? -

    -

    - HackVillage (also written Hack Village) is an - open-source hackathon platform for Kenya and Africa. Organizers deposit the full prize - pool into escrow before a hackathon goes live, so every prize listed here is funded, and - winners are paid half of their prize as soon as results are announced. Every result also - builds the winner's Proof-of-Work developer profile. -

    -
    -
    - ); -} diff --git a/components/patterns/landing-hero.tsx b/components/patterns/landing-hero.tsx deleted file mode 100644 index 50f7db5..0000000 --- a/components/patterns/landing-hero.tsx +++ /dev/null @@ -1,107 +0,0 @@ -import Image from "next/image"; -import Link from "next/link"; -import { ArrowUpRight } from "lucide-react"; - -import { Sparkle } from "@/components/patterns/sparkle"; -import { HOST_HACKATHON_HREF } from "@/lib/auth/signup-links"; - -function Photo({ name, alt, center = false }: { name: string; alt: string; center?: boolean }) { - return ( -
    - {alt} -
    - ); -} - -export function LandingHero() { - return ( -
    -
    -
    - - -

    Open source. Real people. Real impact.

    -

    - Great Hackathons. -
    - From Start to Finish. -

    -

    - From team formation to judging and payouts, bring your hackathon together in one place. - Every hackathon is Prize Verified, with funds secured before the building - begins. -

    -
    - - - - Browse Hackathons - - - Host A Hackathon
    -
    -
    - -
    -
    -

    - Great people. -
    - Bold ideas. -
    - Real rewards. -

    - -
    -
    - - -
    - -
    - - -
    -
    - -

    - Connect. -
    - Create. -
    - Grow. -

    -
    -
    -
    - ); -} diff --git a/components/patterns/sparkle.tsx b/components/patterns/sparkle.tsx index 8ca936b..e09dc9b 100644 --- a/components/patterns/sparkle.tsx +++ b/components/patterns/sparkle.tsx @@ -1,4 +1,4 @@ -/** The four point brand star used as decoration on the home and How It Works pages. */ +/** The four point brand star used as decoration on the How It Works page. */ export function Sparkle({ className }: { className?: string }) { return (
    -

    - Escrow · Payouts -

    -

    - Trust Is Built Into Every Step. -

    -

    - From the first deposit to the final payout, every action is verifiable, on the record, and - impossible to fake. -

    - - - -
    - -
    - - -
    -
    - Kenyan organizer reviewing hackathon prize funding at her laptop -
    -
    - -
    - - - -

    Funds locked before Day 1, not promised.

    -
    - -
    - - - -

    Every payout attested on a public ledger.

    -
    -
    - -
    -
    - Kenyan organizer funding a prize pool from his phone -
    -
    - Kenyan developer celebrating a prize payout on her phone -
    -
    - Kenyan engineer checking a transaction record on his laptop -
    -
    - -
      - {STATS.map((stat) => ( -
    • - {stat.value} - {stat.label} -
    • - ))} -
    - - ); -} diff --git a/public/partners/skillssync-global-logo.webp b/public/partners/skillssync-global-logo.webp new file mode 100644 index 0000000000000000000000000000000000000000..40a5444bc26d6dcc94b1cf0011944fb6777b42ff GIT binary patch literal 32656 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 literal 0 HcmV?d00001