feat(frontend): rebuild landing with parallax and carousel parity

This commit is contained in:
Ashwin Kumar 2026-03-17 00:32:44 +01:00
parent 10385d2e5d
commit 973ec59b69
2 changed files with 574 additions and 195 deletions

View file

@ -812,3 +812,242 @@ body {
.glass-dark .subtitle {
color: rgba(255, 255, 255, 0.82);
}
/* Landing Parity Layer */
.lp-main {
position: relative;
min-height: 100vh;
overflow-x: clip;
}
.lp-bg {
pointer-events: none;
position: fixed;
inset: 0;
z-index: 0;
}
.lp-dark-base {
position: absolute;
inset: 0;
background:
radial-gradient(110% 85% at 6% 0%, rgba(253, 98, 22, 0.2), transparent 56%),
radial-gradient(90% 70% at 96% 10%, rgba(253, 98, 22, 0.16), transparent 58%),
linear-gradient(180deg, #100b2f 0%, #0b0824 58%, #07051a 100%);
}
.lp-mesh {
position: absolute;
inset: -12% -12%;
background:
radial-gradient(42% 36% at 14% 26%, rgba(2, 6, 23, 0.46), transparent 76%),
radial-gradient(34% 30% at 82% 14%, rgba(253, 98, 22, 0.2), transparent 74%),
radial-gradient(40% 32% at 66% 80%, rgba(2, 6, 23, 0.4), transparent 74%);
opacity: 0.58;
}
.lp-ribbon {
position: absolute;
inset: -18% -6%;
background: linear-gradient(120deg, transparent 35%, rgba(253, 98, 22, 0.18) 55%, transparent 74%);
filter: blur(14px);
opacity: 0.38;
}
.lp-noise {
position: absolute;
inset: 0;
opacity: 0.05;
background-image: radial-gradient(circle at 1px 1px, rgba(255, 255, 255, 0.38) 1px, transparent 0);
background-size: 4px 4px;
mix-blend-mode: soft-light;
}
.lp-chips {
position: absolute;
inset: 0;
}
.lp-chip {
position: absolute;
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 44px;
height: 44px;
border-radius: 999px;
border: 1px solid rgba(253, 98, 22, 0.46);
background: rgba(255, 255, 255, 0.14);
color: #fd6216;
font-size: 12px;
font-weight: 700;
backdrop-filter: blur(14px);
box-shadow:
0 18px 36px -22px rgba(2, 6, 23, 0.8),
0 0 0 1px rgba(253, 98, 22, 0.46) inset;
opacity: 0.52;
}
.lp-chip-slow {
animation: lp-float-slow 8s ease-in-out infinite;
}
.lp-chip-mid {
animation: lp-float-mid 6.4s ease-in-out infinite;
}
.lp-chip-fast {
animation: lp-float-fast 5.6s ease-in-out infinite;
}
.lp-content {
position: relative;
z-index: 10;
}
.lp-hero-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
align-items: center;
}
.lp-hero-title {
margin: 0;
color: #fff;
font-size: clamp(34px, 5vw, 56px);
line-height: 1.08;
font-weight: 800;
}
.lp-hero-copy {
margin-top: 14px;
color: rgba(255, 255, 255, 0.8);
font-size: 17px;
line-height: 1.6;
}
.lp-hero-slider {
position: relative;
min-height: 370px;
}
.lp-float-card {
position: absolute;
inset: 0;
border-radius: 20px;
border: 1px solid rgba(255, 255, 255, 0.18);
background: linear-gradient(145deg, rgba(16, 11, 47, 0.72), rgba(16, 11, 47, 0.5));
padding: 18px;
color: #fff;
backdrop-filter: blur(18px);
opacity: 0;
transform: translateY(14px) scale(0.98);
transition: all 380ms ease;
}
.lp-float-card.active {
opacity: 1;
transform: translateY(0) scale(1);
}
.lp-float-card h3 {
margin: 0;
font-size: 22px;
}
.lp-float-card ul {
margin: 10px 0 16px;
padding-left: 18px;
color: rgba(255, 255, 255, 0.86);
line-height: 1.6;
}
.lp-carousel-nav {
margin-top: 10px;
display: flex;
align-items: center;
justify-content: flex-end;
gap: 8px;
}
.lp-benefit-panel {
max-width: 980px;
}
.lp-benefit-hero {
margin-top: 14px;
border: 1px solid rgba(255, 255, 255, 0.24);
border-radius: 18px;
padding: 16px;
background: rgba(255, 255, 255, 0.08);
}
.lp-benefit-hero h3 {
margin: 0;
font-size: 28px;
}
.lp-benefit-hero p {
margin-top: 8px;
color: rgba(255, 255, 255, 0.88);
}
.lp-benefit-dots {
margin-top: 12px;
display: flex;
gap: 6px;
}
.lp-dot {
width: 10px;
height: 10px;
border: 0;
border-radius: 999px;
background: rgba(255, 255, 255, 0.34);
cursor: pointer;
}
.lp-dot.active {
background: #fd6216;
}
@keyframes lp-float-slow {
0%,
100% {
transform: translateY(0px);
}
50% {
transform: translateY(-7px);
}
}
@keyframes lp-float-mid {
0%,
100% {
transform: translateY(0px);
}
50% {
transform: translateY(-10px);
}
}
@keyframes lp-float-fast {
0%,
100% {
transform: translateY(0px);
}
50% {
transform: translateY(-12px);
}
}
@media (max-width: 980px) {
.lp-hero-grid {
grid-template-columns: 1fr;
}
.lp-hero-slider {
min-height: 340px;
}
}

View file

@ -1,22 +1,57 @@
import { A } from '@solidjs/router';
import { createMemo, createSignal, For, onCleanup, onMount, Show } from 'solid-js';
type RoleCard = {
type PathCard = {
title: string;
description: string;
button: string;
href: string;
image: string;
chip: string;
audience: 'customer' | 'professional' | 'company' | 'job_seeker';
};
const roleCards: RoleCard[] = [
type Flow = {
label: string;
title: string;
description: string;
image: string;
steps: Array<{ title: string; description: string }>;
};
const heroSlides = [
{
title: 'Customers',
bullets: ['Post requirements with clear intent', 'Receive verified responses after review'],
href: '/onboarding?schemaId=customer_onboarding_v1',
cta: 'Hire a Professional',
},
{
title: 'Professionals',
bullets: ['Complete role onboarding and verification', 'Discover leads with focused matching'],
href: '/onboarding?schemaId=professional_onboarding_v1',
cta: 'Join as Professional',
},
{
title: 'Companies',
bullets: ['Create approved job listings', 'Track applications in one workflow'],
href: '/onboarding?schemaId=company_onboarding_v1',
cta: 'Post a Job',
},
{
title: 'Job Seekers',
bullets: ['Build profile and clear approvals', 'Apply and monitor opportunities'],
href: '/onboarding?schemaId=jobseeker_onboarding_v1',
cta: 'Apply for Jobs',
},
] as const;
const pathCards: PathCard[] = [
{
title: 'Post a Job',
description: 'Create verified job openings and find the right talent faster.',
button: 'Start as Company',
href: '/onboarding?schemaId=company_onboarding_v1',
chip: 'Company',
audience: 'company',
image: 'https://images.unsplash.com/photo-1484480974693-6ca0a78fb36b?q=80&w=800&auto=format&fit=crop',
},
{
@ -24,7 +59,7 @@ const roleCards: RoleCard[] = [
description: 'Build your profile and apply to approved opportunities quickly.',
button: 'Start as Job Seeker',
href: '/onboarding?schemaId=jobseeker_onboarding_v1',
chip: 'Job Seeker',
audience: 'job_seeker',
image: 'https://images.unsplash.com/photo-1586281380349-632531db7ed4?q=80&w=800&auto=format&fit=crop',
},
{
@ -32,7 +67,7 @@ const roleCards: RoleCard[] = [
description: 'Post your requirement and discover trusted specialists.',
button: 'Start as Customer',
href: '/onboarding?schemaId=customer_onboarding_v1',
chip: 'Customer',
audience: 'customer',
image: 'https://images.unsplash.com/photo-1450101499163-c8848c66ca85?q=80&w=800&auto=format&fit=crop',
},
{
@ -40,7 +75,7 @@ const roleCards: RoleCard[] = [
description: 'Build products and grow with verified client demand.',
button: 'Join Developer',
href: '/onboarding?schemaId=professional_onboarding_v1&profession=Developer',
chip: 'Professional',
audience: 'professional',
image: 'https://images.unsplash.com/photo-1498050108023-c5249f4df085?q=80&w=800&auto=format&fit=crop',
},
{
@ -48,7 +83,7 @@ const roleCards: RoleCard[] = [
description: 'Capture events and campaigns with trusted bookings.',
button: 'Join Photographer',
href: '/onboarding?schemaId=professional_onboarding_v1&profession=Photographer',
chip: 'Professional',
audience: 'professional',
image: 'https://images.unsplash.com/photo-1516035069371-29a1b244cc32?q=80&w=800&auto=format&fit=crop',
},
{
@ -56,7 +91,7 @@ const roleCards: RoleCard[] = [
description: 'Offer styling services with profile-based trust signals.',
button: 'Join Makeup Artist',
href: '/onboarding?schemaId=professional_onboarding_v1&profession=Makeup%20Artist',
chip: 'Professional',
audience: 'professional',
image: 'https://images.unsplash.com/photo-1522335789203-aabd1fc54bc9?q=80&w=800&auto=format&fit=crop',
},
{
@ -64,7 +99,7 @@ const roleCards: RoleCard[] = [
description: 'Teach learners and build your reputation with verified profiles.',
button: 'Join Tutor',
href: '/onboarding?schemaId=professional_onboarding_v1&profession=Tutor',
chip: 'Professional',
audience: 'professional',
image: 'https://images.unsplash.com/photo-1497633762265-9d179a990aa6?q=80&w=800&auto=format&fit=crop',
},
{
@ -72,7 +107,7 @@ const roleCards: RoleCard[] = [
description: 'Create compelling edits and work with quality clients.',
button: 'Join Video Editor',
href: '/onboarding?schemaId=professional_onboarding_v1&profession=Video%20Editor',
chip: 'Professional',
audience: 'professional',
image: 'https://images.unsplash.com/photo-1574717024653-61fd2cf4d44d?q=80&w=800&auto=format&fit=crop',
},
{
@ -80,7 +115,7 @@ const roleCards: RoleCard[] = [
description: 'Design brand-ready visuals and collaborate with growing businesses.',
button: 'Join Graphic Designer',
href: '/onboarding?schemaId=professional_onboarding_v1&profession=Graphic%20Designer',
chip: 'Professional',
audience: 'professional',
image: 'https://images.unsplash.com/photo-1558655146-d09347e92766?q=80&w=800&auto=format&fit=crop',
},
{
@ -88,7 +123,7 @@ const roleCards: RoleCard[] = [
description: 'Plan campaigns and scale audience growth for clients.',
button: 'Join Social Manager',
href: '/onboarding?schemaId=professional_onboarding_v1&profession=Social%20Media%20Manager',
chip: 'Professional',
audience: 'professional',
image: 'https://images.unsplash.com/photo-1611162618071-b39a2ec055fb?q=80&w=800&auto=format&fit=crop',
},
{
@ -96,7 +131,7 @@ const roleCards: RoleCard[] = [
description: 'Coach clients with structured plans and trusted profiles.',
button: 'Join Trainer',
href: '/onboarding?schemaId=professional_onboarding_v1&profession=Fitness%20Trainer',
chip: 'Professional',
audience: 'professional',
image: 'https://images.unsplash.com/photo-1517836357463-d25dfeac3438?q=80&w=800&auto=format&fit=crop',
},
{
@ -104,7 +139,7 @@ const roleCards: RoleCard[] = [
description: 'Showcase event-ready menus to customers and companies.',
button: 'Join Catering',
href: '/onboarding?schemaId=professional_onboarding_v1&profession=Catering%20Services',
chip: 'Professional',
audience: 'professional',
image: 'https://images.unsplash.com/photo-1555244162-803834f70033?q=80&w=800&auto=format&fit=crop',
},
];
@ -116,9 +151,9 @@ const benefits = [
{ title: 'Focused discovery with filters', body: 'Search and filter tools keep opportunity discovery focused.' },
{ title: 'Controlled contact visibility', body: 'Sensitive contact flow remains controlled by role and workflow.' },
{ title: 'Notifications & updates', body: 'Track approvals, responses, applications, and key updates.' },
];
] as const;
const flows = [
const flows: Flow[] = [
{
label: 'Customers',
title: 'Need to solution, with verified trust in the middle',
@ -190,225 +225,330 @@ const faqs = [
q: 'Do I need to choose my role during signup?',
a: 'No. You can sign up once and continue with the role flow that fits you best.',
},
];
] as const;
const chipNodes = [
{ label: '</>', left: '3%', top: '14%', cls: 'lp-chip-slow' },
{ label: 'Cam', left: '95%', top: '20%', cls: 'lp-chip-mid' },
{ label: 'Job', left: '5%', top: '78%', cls: 'lp-chip-fast' },
{ label: 'Pro', left: '92%', top: '74%', cls: 'lp-chip-slow' },
{ label: 'AI', left: '48%', top: '7%', cls: 'lp-chip-mid' },
] as const;
export default function PublicLanding() {
const [scrolled, setScrolled] = createSignal(false);
const [mobileOpen, setMobileOpen] = createSignal(false);
const [filter, setFilter] = createSignal<'all' | 'customer' | 'professional' | 'company' | 'jobseeker'>('all');
const [scrollY, setScrollY] = createSignal(0);
const [heroIdx, setHeroIdx] = createSignal(0);
const [filter, setFilter] = createSignal<'all' | 'customer' | 'professional' | 'company' | 'job_seeker'>('all');
const [pathPage, setPathPage] = createSignal(0);
const [cardsPerPage, setCardsPerPage] = createSignal(3);
const [benefitIdx, setBenefitIdx] = createSignal(0);
const [flowIndex, setFlowIndex] = createSignal(0);
const [stepIndex, setStepIndex] = createSignal(0);
const [flowStepIndex, setFlowStepIndex] = createSignal(0);
const [openFaq, setOpenFaq] = createSignal(0);
onMount(() => {
const onScroll = () => setScrolled(window.scrollY > 10);
onScroll();
window.addEventListener('scroll', onScroll, { passive: true });
const onScroll = () => {
setScrolled(window.scrollY > 10);
setScrollY(window.scrollY || 0);
};
const timer = window.setInterval(() => {
setStepIndex((prev) => {
const active = flows[flowIndex()];
if (prev + 1 < active.steps.length) return prev + 1;
const syncCardsPerPage = () => {
const w = window.innerWidth;
if (w < 640) {
setCardsPerPage(1);
return;
}
if (w < 1024) {
setCardsPerPage(2);
return;
}
setCardsPerPage(3);
};
onScroll();
syncCardsPerPage();
window.addEventListener('scroll', onScroll, { passive: true });
window.addEventListener('resize', syncCardsPerPage);
const heroTimer = window.setInterval(() => setHeroIdx((x) => (x + 1) % heroSlides.length), 3500);
const pathTimer = window.setInterval(() => setPathPage((x) => x + 1), 4200);
const benefitTimer = window.setInterval(() => setBenefitIdx((x) => (x + 1) % benefits.length), 4200);
const flowTimer = window.setInterval(() => {
const active = flows[flowIndex()];
setFlowStepIndex((prev) => {
const next = prev + 1;
if (next < active.steps.length) return next;
setFlowIndex((f) => (f + 1) % flows.length);
return 0;
});
}, 3200);
}, 3000);
onCleanup(() => {
window.removeEventListener('scroll', onScroll);
window.clearInterval(timer);
window.removeEventListener('resize', syncCardsPerPage);
window.clearInterval(heroTimer);
window.clearInterval(pathTimer);
window.clearInterval(benefitTimer);
window.clearInterval(flowTimer);
});
});
const filteredCards = createMemo(() => {
const active = filter();
if (active === 'all') return roleCards;
if (active === 'customer') return roleCards.filter((x) => x.chip === 'Customer');
if (active === 'professional') return roleCards.filter((x) => x.chip === 'Professional');
if (active === 'company') return roleCards.filter((x) => x.chip === 'Company');
return roleCards.filter((x) => x.chip === 'Job Seeker');
const filteredPaths = createMemo(() => {
const value = filter();
if (value === 'all') return pathCards;
return pathCards.filter((card) => card.audience === value);
});
return (
<main class="public-main">
<header class={`public-header ${scrolled() ? 'public-header-scrolled' : ''}`}>
<div class="container nav-row">
<A href="/"><img class="brand-logo" src="/nxtgauge-logo.png" alt="NXTGAUGE" /></A>
const pagedPaths = createMemo(() => {
const cards = filteredPaths();
const per = cardsPerPage();
const pages: PathCard[][] = [];
for (let i = 0; i < cards.length; i += per) pages.push(cards.slice(i, i + per));
return pages;
});
<nav class="nav-links desktop-only">
<A href="/">Home</A>
<A href="/about">About Us</A>
<A href="/contact">Contact Us</A>
const activePathPage = createMemo(() => {
const pages = pagedPaths();
if (pages.length === 0) return 0;
return pathPage() % pages.length;
});
const pathCardsVisible = createMemo(() => {
const pages = pagedPaths();
if (pages.length === 0) return [];
return pages[activePathPage()];
});
const parallax = createMemo(() => ({
mesh: Math.min(36, scrollY() * 0.1),
ribbon: Math.min(52, scrollY() * 0.18),
chips: Math.min(70, scrollY() * 0.23),
}));
return (
<main class="lp-main">
<div class="lp-bg" aria-hidden="true">
<div class="lp-dark-base" />
<div class="lp-mesh" style={{ transform: `translate3d(0, ${parallax().mesh}px, 0)` }} />
<div class="lp-ribbon" style={{ transform: `translate3d(0, ${parallax().ribbon}px, 0)` }} />
<div class="lp-chips" style={{ transform: `translate3d(0, ${parallax().chips}px, 0)` }}>
<For each={chipNodes}>
{(chip) => (
<span class={`lp-chip ${chip.cls}`} style={{ left: chip.left, top: chip.top }}>
{chip.label}
</span>
)}
</For>
</div>
<div class="lp-noise" />
</div>
<div class="lp-content">
<header class={`public-header ${scrolled() ? 'public-header-scrolled' : ''}`}>
<nav class="container nav-row">
<A href="/"><img class="brand-logo" src="/nxtgauge-logo.png" alt="NXTGAUGE" /></A>
<div class="desktop-only nav-links">
<A href="/">Home</A>
<A href="/about">About Us</A>
<A href="/help-center">Help Center</A>
<A href="/contact">Contact Us</A>
</div>
<div class="desktop-only nav-actions">
<A class="btn" href="/auth/login">Login</A>
<A class="btn primary" href="/auth/register">Sign Up</A>
</div>
<button class="btn mobile-menu" onClick={() => setMobileOpen(!mobileOpen())}>Menu</button>
</nav>
<div class="nav-actions desktop-only">
<A class="btn" href="/onboarding?schemaId=professional_onboarding_v1">Login</A>
<A class="btn primary" href="/onboarding?schemaId=customer_onboarding_v1">Sign Up</A>
</div>
<button class="btn mobile-menu" onClick={() => setMobileOpen(!mobileOpen())}>Menu</button>
</div>
<Show when={mobileOpen()}>
<div class="mobile-nav container">
<A href="/" onClick={() => setMobileOpen(false)}>Home</A>
<A href="/about" onClick={() => setMobileOpen(false)}>About Us</A>
<A href="/contact" onClick={() => setMobileOpen(false)}>Contact Us</A>
</div>
</Show>
</header>
<section class="public-hero scene-dark">
<div class="container hero-grid-2">
<div>
<h1 class="hero-title">Hire verified professionals. Post jobs. Get approvals in 24-48 hours.</h1>
<p class="hero-copy">Nxtgauge connects customers, companies, job seekers, and professionals through a trusted approval workflow.</p>
<div class="hero-actions">
<A class="btn primary" href="/onboarding?schemaId=customer_onboarding_v1">Hire a Professional</A>
<A class="btn ghost-dark" href="/onboarding?schemaId=jobseeker_onboarding_v1">Apply for Jobs</A>
<Show when={mobileOpen()}>
<div class="mobile-nav container">
<A href="/" onClick={() => setMobileOpen(false)}>Home</A>
<A href="/about" onClick={() => setMobileOpen(false)}>About Us</A>
<A href="/help-center" onClick={() => setMobileOpen(false)}>Help Center</A>
<A href="/contact" onClick={() => setMobileOpen(false)}>Contact Us</A>
<A href="/auth/login" onClick={() => setMobileOpen(false)}>Login</A>
<A href="/auth/register" onClick={() => setMobileOpen(false)}>Sign Up</A>
</div>
</div>
<div class="hero-stack">
<article class="float-card">
<h3>Customers</h3>
<p>Post requirements with clear intent and receive verified responses.</p>
</article>
<article class="float-card">
<h3>Professionals</h3>
<p>Complete onboarding and verification, then discover relevant leads.</p>
</article>
<article class="float-card">
<h3>Companies</h3>
<p>Create approved job listings and track applications in one workflow.</p>
</article>
<article class="float-card">
<h3>Job Seekers</h3>
<p>Build profile, clear approvals, apply and track opportunities.</p>
</article>
</div>
</div>
</section>
</Show>
</header>
<section class="public-section scene-dark">
<div class="container panel">
<div class="section-head">
<section class="public-hero scene-dark">
<div class="container lp-hero-grid">
<div>
<h2>Choose Your Path</h2>
<p>One account, multiple journeys. Pick your goal and get started.</p>
<h1 class="lp-hero-title">Hire verified professionals. Post jobs. Get approvals in 24-48 hours.</h1>
<p class="lp-hero-copy">
Nxtgauge connects customers, companies, job seekers, and professionals through a trusted approval workflow.
</p>
<div class="hero-actions">
<A class="btn primary" href="/onboarding?schemaId=customer_onboarding_v1">Hire a Professional</A>
<A class="btn ghost-dark" href="/onboarding?schemaId=jobseeker_onboarding_v1">Apply for Jobs</A>
</div>
</div>
<div class="filter-row">
<button class={`chip-btn ${filter() === 'all' ? 'active' : ''}`} onClick={() => setFilter('all')}>All Paths</button>
<button class={`chip-btn ${filter() === 'customer' ? 'active' : ''}`} onClick={() => setFilter('customer')}>Customers</button>
<button class={`chip-btn ${filter() === 'professional' ? 'active' : ''}`} onClick={() => setFilter('professional')}>Professionals</button>
<button class={`chip-btn ${filter() === 'company' ? 'active' : ''}`} onClick={() => setFilter('company')}>Companies</button>
<button class={`chip-btn ${filter() === 'jobseeker' ? 'active' : ''}`} onClick={() => setFilter('jobseeker')}>Job Seekers</button>
<div class="lp-hero-slider">
<For each={heroSlides}>
{(slide, idx) => (
<article class={`lp-float-card ${idx() === heroIdx() ? 'active' : ''}`}>
<h3>{slide.title}</h3>
<ul>
<For each={slide.bullets}>{(b) => <li>{b}</li>}</For>
</ul>
<A class="btn" href={slide.href}>{slide.cta}</A>
</article>
)}
</For>
</div>
</div>
<div class="path-grid">
<For each={filteredCards()}>
{(card) => (
<article class="path-card">
<img src={card.image} alt={card.title} />
<div class="path-body">
<span class="role-badge">{card.chip}</span>
<h3>{card.title}</h3>
<p>{card.description}</p>
<A class="btn primary" href={card.href}>{card.button}</A>
</div>
</article>
)}
</For>
</div>
</div>
</section>
</section>
<section class="public-section scene-dark">
<div class="container panel panel-dark">
<h2 class="center">Why Nxtgauge</h2>
<p class="center sub">Trust, approvals, and better matching in one flow.</p>
<div class="benefit-grid">
<For each={benefits}>{(item) => <article class="benefit-card"><h3>{item.title}</h3><p>{item.body}</p></article>}</For>
</div>
</div>
</section>
<section id="choose-path" class="public-section scene-dark">
<div class="container panel">
<div class="section-head">
<div>
<h2>Choose Your Path</h2>
<p class="sub">One account, multiple journeys. Pick your goal and get started.</p>
</div>
<div class="filter-row">
<button class={`chip-btn ${filter() === 'all' ? 'active' : ''}`} onClick={() => { setFilter('all'); setPathPage(0); }}>All Paths</button>
<button class={`chip-btn ${filter() === 'customer' ? 'active' : ''}`} onClick={() => { setFilter('customer'); setPathPage(0); }}>Customers</button>
<button class={`chip-btn ${filter() === 'professional' ? 'active' : ''}`} onClick={() => { setFilter('professional'); setPathPage(0); }}>Professionals</button>
<button class={`chip-btn ${filter() === 'company' ? 'active' : ''}`} onClick={() => { setFilter('company'); setPathPage(0); }}>Companies</button>
<button class={`chip-btn ${filter() === 'job_seeker' ? 'active' : ''}`} onClick={() => { setFilter('job_seeker'); setPathPage(0); }}>Job Seekers</button>
</div>
</div>
<section class="public-section scene-light">
<div class="container panel panel-light">
<h2 class="center">How It Works</h2>
<p class="center sub">Clear journey, zero confusion.</p>
<article class="flow-card">
<img src={flows[flowIndex()].image} alt={flows[flowIndex()].label} />
<div>
<p class="eyebrow">{flows[flowIndex()].label}</p>
<h3>{flows[flowIndex()].title}</h3>
<p class="sub">{flows[flowIndex()].description}</p>
<div class="step-list">
<For each={flows[flowIndex()].steps}>
{(step, idx) => (
<div class={`step-item ${idx() === stepIndex() ? 'active' : ''}`}>
<span>{idx() + 1}</span>
<div>
<h4>{step.title}</h4>
<p>{step.description}</p>
</div>
<div class="lp-carousel-nav">
<button class="btn" onClick={() => setPathPage((x) => Math.max(0, x - 1))}></button>
<span class="note">Page {activePathPage() + 1} / {Math.max(1, pagedPaths().length)}</span>
<button class="btn" onClick={() => setPathPage((x) => x + 1)}></button>
</div>
<div class="path-grid">
<For each={pathCardsVisible()}>
{(card) => (
<article class="path-card">
<img src={card.image} alt={card.title} />
<div class="path-body">
<h3>{card.title}</h3>
<p>{card.description}</p>
<A class="btn primary" href={card.href}>{card.button}</A>
</div>
</article>
)}
</For>
</div>
</div>
</section>
<section id="why-nxtgauge" class="public-section scene-dark">
<div class="container panel panel-dark lp-benefit-panel">
<h2 class="center">Why Nxtgauge</h2>
<p class="center sub">Trust, approvals, and better matching in one flow.</p>
<article class="lp-benefit-hero">
<h3>{benefits[benefitIdx()].title}</h3>
<p>{benefits[benefitIdx()].body}</p>
<div class="lp-benefit-dots">
<For each={benefits}>
{(_, idx) => (
<button
class={`lp-dot ${idx() === benefitIdx() ? 'active' : ''}`}
onClick={() => setBenefitIdx(idx())}
aria-label={`Benefit ${idx() + 1}`}
/>
)}
</For>
</div>
<div class="actions">
<button class="btn" onClick={() => { setFlowIndex((flowIndex() - 1 + flows.length) % flows.length); setStepIndex(0); }}>&larr;</button>
<button class="btn" onClick={() => { setFlowIndex((flowIndex() + 1) % flows.length); setStepIndex(0); }}>&rarr;</button>
</article>
</div>
</section>
<section id="how-it-works" class="public-section scene-light">
<div class="container panel panel-light">
<h2 class="center">How it works</h2>
<p class="center sub">Clear journey, zero confusion.</p>
<article class="flow-card">
<img src={flows[flowIndex()].image} alt={flows[flowIndex()].label} />
<div>
<p class="eyebrow">{flows[flowIndex()].label}</p>
<h3>{flows[flowIndex()].title}</h3>
<p class="sub">{flows[flowIndex()].description}</p>
<div class="step-list">
<For each={flows[flowIndex()].steps}>
{(step, idx) => (
<div class={`step-item ${idx() === flowStepIndex() ? 'active' : ''}`}>
<span>{idx() + 1}</span>
<div>
<h4>{step.title}</h4>
<p>{step.description}</p>
</div>
</div>
)}
</For>
</div>
<div class="actions">
<button class="btn" onClick={() => { setFlowIndex((flowIndex() - 1 + flows.length) % flows.length); setFlowStepIndex(0); }}></button>
<button class="btn" onClick={() => { setFlowIndex((flowIndex() + 1) % flows.length); setFlowStepIndex(0); }}></button>
</div>
</div>
</article>
</div>
</section>
<section id="faqs" class="public-section scene-dark">
<div class="container panel panel-dark faq-wrap">
<h2 class="center">Frequently asked questions</h2>
<p class="center sub">Quick answers before you create your account.</p>
<div class="faq-list">
<For each={faqs}>
{(item, idx) => (
<article class={`faq-item ${openFaq() === idx() ? 'open' : ''}`}>
<button class="faq-q" onClick={() => setOpenFaq(openFaq() === idx() ? -1 : idx())}>
<span>{item.q}</span>
<span>{openFaq() === idx() ? '' : '+'}</span>
</button>
<Show when={openFaq() === idx()}>
<p class="faq-a">{item.a}</p>
</Show>
</article>
)}
</For>
</div>
</article>
</div>
</section>
</div>
</section>
<section class="public-section scene-dark">
<div class="container panel panel-dark faq-wrap">
<h2 class="center">Frequently asked questions</h2>
<p class="center sub">Quick answers before you create your account.</p>
<div class="faq-list">
<For each={faqs}>
{(item, idx) => (
<article class={`faq-item ${openFaq() === idx() ? 'open' : ''}`}>
<button class="faq-q" onClick={() => setOpenFaq(openFaq() === idx() ? -1 : idx())}>
<span>{item.q}</span>
<span>{openFaq() === idx() ? '-' : '+'}</span>
</button>
<Show when={openFaq() === idx()}><p class="faq-a">{item.a}</p></Show>
</article>
)}
</For>
<section class="public-section scene-dark">
<div class="container panel panel-dark cta-row">
<div>
<p class="eyebrow">Quick Actions</p>
<h2>Ready to get started?</h2>
<p class="sub">Pick your next action and continue with the correct role flow.</p>
</div>
<div class="hero-actions">
<A class="btn primary" href="/onboarding?schemaId=customer_onboarding_v1">Hire a Professional</A>
<A class="btn ghost-dark" href="/onboarding?schemaId=jobseeker_onboarding_v1">Apply for Jobs</A>
<A class="btn ghost-dark" href="/onboarding?schemaId=company_onboarding_v1">Post a Job</A>
</div>
</div>
</div>
</section>
</section>
<section class="public-section scene-dark">
<div class="container panel panel-dark cta-row">
<div>
<p class="eyebrow">Quick Actions</p>
<h2>Ready to get started?</h2>
<p class="sub">Pick your next action and continue with the correct role flow.</p>
<footer class="public-footer">
<div class="container footer-row">
<img class="brand-logo" src="/nxtgauge-logo.png" alt="NXTGAUGE" />
<p>© {new Date().getFullYear()} Nxtgauge. All rights reserved.</p>
<div class="footer-links">
<A href="/about">About Us</A>
<A href="/terms">Terms</A>
<A href="/privacy">Privacy</A>
<A href="/help-center">Help Center</A>
<A href="/contact">Contact Us</A>
</div>
</div>
<div class="hero-actions">
<A class="btn primary" href="/onboarding?schemaId=customer_onboarding_v1">Hire a Professional</A>
<A class="btn ghost-dark" href="/onboarding?schemaId=jobseeker_onboarding_v1">Apply for Jobs</A>
<A class="btn ghost-dark" href="/onboarding?schemaId=company_onboarding_v1">Post a Job</A>
</div>
</div>
</section>
<footer class="public-footer">
<div class="container footer-row">
<img class="brand-logo" src="/nxtgauge-logo.png" alt="NXTGAUGE" />
<p>© {new Date().getFullYear()} Nxtgauge. All rights reserved.</p>
<div class="footer-links">
<A href="/about">About Us</A>
<A href="/contact">Contact Us</A>
</div>
</div>
</footer>
</footer>
</div>
</main>
);
}