feat(frontend): align public homepage closer to legacy design
This commit is contained in:
parent
d746fe00e1
commit
632fc0c7e9
3 changed files with 791 additions and 135 deletions
375
src/app.css
375
src/app.css
|
|
@ -395,3 +395,378 @@ body {
|
||||||
padding: 12px 0;
|
padding: 12px 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.public-main {
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-header {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 60;
|
||||||
|
border-bottom: 1px solid rgba(16, 11, 47, 0.1);
|
||||||
|
background: rgba(255, 255, 255, 0.72);
|
||||||
|
backdrop-filter: blur(14px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-header-scrolled {
|
||||||
|
box-shadow: 0 12px 28px -24px rgba(2, 6, 23, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.desktop-only {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-menu {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-nav {
|
||||||
|
display: none;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-nav a {
|
||||||
|
display: block;
|
||||||
|
padding: 8px 0;
|
||||||
|
text-decoration: none;
|
||||||
|
color: #100b2f;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scene-dark {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scene-light {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scene-light::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
inset: 8px 0;
|
||||||
|
background: linear-gradient(180deg, rgba(255, 255, 255, 0.42), rgba(255, 255, 255, 0.2));
|
||||||
|
border-top: 1px solid rgba(255, 255, 255, 0.28);
|
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.16);
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-hero {
|
||||||
|
padding: 22px 0 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-grid-2 {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 16px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-stack {
|
||||||
|
display: grid;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.float-card {
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.24);
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 12px;
|
||||||
|
background: linear-gradient(150deg, rgba(16, 11, 47, 0.78), rgba(16, 11, 47, 0.55));
|
||||||
|
color: #fff;
|
||||||
|
backdrop-filter: blur(12px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.float-card h3 {
|
||||||
|
margin: 0 0 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.float-card p {
|
||||||
|
margin: 0;
|
||||||
|
color: rgba(255, 255, 255, 0.82);
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-section {
|
||||||
|
padding: 16px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel {
|
||||||
|
border-radius: 24px;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
padding: 18px;
|
||||||
|
backdrop-filter: blur(12px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-light {
|
||||||
|
border-color: #d9e2ef;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-dark {
|
||||||
|
border-color: rgba(255, 255, 255, 0.2);
|
||||||
|
background: rgba(16, 11, 47, 0.44);
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-dark,
|
||||||
|
.panel-dark h2,
|
||||||
|
.panel-dark h3,
|
||||||
|
.panel-dark h4,
|
||||||
|
.panel-dark .center,
|
||||||
|
.panel-dark .sub,
|
||||||
|
.panel-dark p,
|
||||||
|
.panel-dark span {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-head {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 10px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-head h2,
|
||||||
|
.center {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub {
|
||||||
|
color: #64748b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-dark .sub {
|
||||||
|
color: rgba(255, 255, 255, 0.78);
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-row {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chip-btn {
|
||||||
|
border: 1px solid rgba(253, 98, 22, 0.4);
|
||||||
|
background: rgba(253, 98, 22, 0.08);
|
||||||
|
color: #9a3412;
|
||||||
|
border-radius: 999px;
|
||||||
|
padding: 6px 10px;
|
||||||
|
font-weight: 700;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chip-btn.active {
|
||||||
|
background: #fd6216;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.path-grid {
|
||||||
|
margin-top: 14px;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.path-card {
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 16px;
|
||||||
|
border: 1px solid rgba(148, 163, 184, 0.34);
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.path-card img {
|
||||||
|
width: 100%;
|
||||||
|
height: 170px;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.path-body {
|
||||||
|
padding: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.path-body h3 {
|
||||||
|
margin: 8px 0;
|
||||||
|
color: #100b2f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.path-body p {
|
||||||
|
color: #475569;
|
||||||
|
}
|
||||||
|
|
||||||
|
.benefit-grid {
|
||||||
|
margin-top: 14px;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.benefit-card {
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.28);
|
||||||
|
border-radius: 14px;
|
||||||
|
padding: 12px;
|
||||||
|
background: rgba(255, 255, 255, 0.07);
|
||||||
|
}
|
||||||
|
|
||||||
|
.benefit-card h3 {
|
||||||
|
margin: 0 0 8px;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.benefit-card p {
|
||||||
|
margin: 0;
|
||||||
|
color: rgba(255, 255, 255, 0.85);
|
||||||
|
}
|
||||||
|
|
||||||
|
.flow-card {
|
||||||
|
margin-top: 12px;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 14px;
|
||||||
|
border: 1px solid #dbe1ec;
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flow-card > img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
max-height: 360px;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-list {
|
||||||
|
margin-top: 10px;
|
||||||
|
display: grid;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-item {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 32px 1fr;
|
||||||
|
gap: 8px;
|
||||||
|
border: 1px solid #dbe1ec;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-item.active {
|
||||||
|
border-color: #fd6216;
|
||||||
|
background: #fff7ed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-item span {
|
||||||
|
display: inline-flex;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: #fd6216;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-item h4 {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-item p {
|
||||||
|
margin: 4px 0 0;
|
||||||
|
color: #475569;
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-wrap {
|
||||||
|
max-width: 980px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-list {
|
||||||
|
margin-top: 12px;
|
||||||
|
display: grid;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-item {
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.24);
|
||||||
|
border-radius: 14px;
|
||||||
|
background: rgba(255, 255, 255, 0.08);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-item.open {
|
||||||
|
border-color: rgba(253, 98, 22, 0.66);
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-q {
|
||||||
|
width: 100%;
|
||||||
|
border: 0;
|
||||||
|
background: transparent;
|
||||||
|
color: #fff;
|
||||||
|
padding: 12px;
|
||||||
|
font-weight: 700;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.faq-a {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 12px 12px;
|
||||||
|
color: rgba(255, 255, 255, 0.82);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 12px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-footer {
|
||||||
|
border-top: 1px solid rgba(16, 11, 47, 0.1);
|
||||||
|
background: rgba(255, 255, 255, 0.78);
|
||||||
|
backdrop-filter: blur(12px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ghost-dark {
|
||||||
|
border-color: rgba(255, 255, 255, 0.28);
|
||||||
|
color: #fff;
|
||||||
|
background: rgba(255, 255, 255, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1024px) {
|
||||||
|
.path-grid,
|
||||||
|
.benefit-grid {
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 820px) {
|
||||||
|
.desktop-only {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-menu {
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-nav {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-grid-2,
|
||||||
|
.flow-card {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
.path-grid,
|
||||||
|
.benefit-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
414
src/components/PublicLanding.tsx
Normal file
414
src/components/PublicLanding.tsx
Normal file
|
|
@ -0,0 +1,414 @@
|
||||||
|
import { A } from '@solidjs/router';
|
||||||
|
import { createMemo, createSignal, For, onCleanup, onMount, Show } from 'solid-js';
|
||||||
|
|
||||||
|
type RoleCard = {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
button: string;
|
||||||
|
href: string;
|
||||||
|
image: string;
|
||||||
|
chip: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const roleCards: RoleCard[] = [
|
||||||
|
{
|
||||||
|
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',
|
||||||
|
image: 'https://images.unsplash.com/photo-1484480974693-6ca0a78fb36b?q=80&w=800&auto=format&fit=crop',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Apply for Jobs',
|
||||||
|
description: 'Build your profile and apply to approved opportunities quickly.',
|
||||||
|
button: 'Start as Job Seeker',
|
||||||
|
href: '/onboarding?schemaId=jobseeker_onboarding_v1',
|
||||||
|
chip: 'Job Seeker',
|
||||||
|
image: 'https://images.unsplash.com/photo-1586281380349-632531db7ed4?q=80&w=800&auto=format&fit=crop',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Hire a Professional',
|
||||||
|
description: 'Post your requirement and discover trusted specialists.',
|
||||||
|
button: 'Start as Customer',
|
||||||
|
href: '/onboarding?schemaId=customer_onboarding_v1',
|
||||||
|
chip: 'Customer',
|
||||||
|
image: 'https://images.unsplash.com/photo-1450101499163-c8848c66ca85?q=80&w=800&auto=format&fit=crop',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Join as Developer',
|
||||||
|
description: 'Build products and grow with verified client demand.',
|
||||||
|
button: 'Join Developer',
|
||||||
|
href: '/onboarding?schemaId=professional_onboarding_v1&profession=Developer',
|
||||||
|
chip: 'Professional',
|
||||||
|
image: 'https://images.unsplash.com/photo-1498050108023-c5249f4df085?q=80&w=800&auto=format&fit=crop',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Join as Photographer',
|
||||||
|
description: 'Capture events and campaigns with trusted bookings.',
|
||||||
|
button: 'Join Photographer',
|
||||||
|
href: '/onboarding?schemaId=professional_onboarding_v1&profession=Photographer',
|
||||||
|
chip: 'Professional',
|
||||||
|
image: 'https://images.unsplash.com/photo-1516035069371-29a1b244cc32?q=80&w=800&auto=format&fit=crop',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Join as Makeup Artist',
|
||||||
|
description: 'Offer styling services with profile-based trust signals.',
|
||||||
|
button: 'Join Makeup Artist',
|
||||||
|
href: '/onboarding?schemaId=professional_onboarding_v1&profession=Makeup%20Artist',
|
||||||
|
chip: 'Professional',
|
||||||
|
image: 'https://images.unsplash.com/photo-1522335789203-aabd1fc54bc9?q=80&w=800&auto=format&fit=crop',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Join as Tutor',
|
||||||
|
description: 'Teach learners and build your reputation with verified profiles.',
|
||||||
|
button: 'Join Tutor',
|
||||||
|
href: '/onboarding?schemaId=professional_onboarding_v1&profession=Tutor',
|
||||||
|
chip: 'Professional',
|
||||||
|
image: 'https://images.unsplash.com/photo-1497633762265-9d179a990aa6?q=80&w=800&auto=format&fit=crop',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Join as Video Editor',
|
||||||
|
description: 'Create compelling edits and work with quality clients.',
|
||||||
|
button: 'Join Video Editor',
|
||||||
|
href: '/onboarding?schemaId=professional_onboarding_v1&profession=Video%20Editor',
|
||||||
|
chip: 'Professional',
|
||||||
|
image: 'https://images.unsplash.com/photo-1574717024653-61fd2cf4d44d?q=80&w=800&auto=format&fit=crop',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Join as Graphic Designer',
|
||||||
|
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',
|
||||||
|
image: 'https://images.unsplash.com/photo-1558655146-d09347e92766?q=80&w=800&auto=format&fit=crop',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Join as Social Media Manager',
|
||||||
|
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',
|
||||||
|
image: 'https://images.unsplash.com/photo-1611162618071-b39a2ec055fb?q=80&w=800&auto=format&fit=crop',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Join as Fitness Trainer',
|
||||||
|
description: 'Coach clients with structured plans and trusted profiles.',
|
||||||
|
button: 'Join Trainer',
|
||||||
|
href: '/onboarding?schemaId=professional_onboarding_v1&profession=Fitness%20Trainer',
|
||||||
|
chip: 'Professional',
|
||||||
|
image: 'https://images.unsplash.com/photo-1517836357463-d25dfeac3438?q=80&w=800&auto=format&fit=crop',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Join as Catering Services',
|
||||||
|
description: 'Showcase event-ready menus to customers and companies.',
|
||||||
|
button: 'Join Catering',
|
||||||
|
href: '/onboarding?schemaId=professional_onboarding_v1&profession=Catering%20Services',
|
||||||
|
chip: 'Professional',
|
||||||
|
image: 'https://images.unsplash.com/photo-1555244162-803834f70033?q=80&w=800&auto=format&fit=crop',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const benefits = [
|
||||||
|
{ title: 'Verified profiles & businesses', body: 'Identity and profile checks reduce fake submissions and spam.' },
|
||||||
|
{ title: 'Approval-based quality (24-48 hours)', body: 'Profiles, requirements, and jobs are reviewed before visibility.' },
|
||||||
|
{ title: 'Smart matching using tags/skills', body: 'Tag-based relevance helps surface better opportunities faster.' },
|
||||||
|
{ 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.' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const flows = [
|
||||||
|
{
|
||||||
|
label: 'Customers',
|
||||||
|
title: 'Need to solution, with verified trust in the middle',
|
||||||
|
description: 'Post your requirement, pass quality checks, and receive focused responses.',
|
||||||
|
image: 'https://images.unsplash.com/photo-1454165804606-c3d57bc86b40?q=80&w=1200&auto=format&fit=crop',
|
||||||
|
steps: [
|
||||||
|
{ title: 'Create account', description: 'Sign up quickly with customer intent.' },
|
||||||
|
{ title: 'Share requirement', description: 'Add budget, scope, and timing.' },
|
||||||
|
{ title: 'Review and verify', description: 'Quality checks run before visibility.' },
|
||||||
|
{ title: 'Track responses', description: 'Monitor replies and status updates.' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Professionals',
|
||||||
|
title: 'Profile first, opportunity next',
|
||||||
|
description: 'Build profile quality once, then receive better-fit lead discovery.',
|
||||||
|
image: 'https://images.unsplash.com/photo-1461749280684-dccba630e2f6?q=80&w=1200&auto=format&fit=crop',
|
||||||
|
steps: [
|
||||||
|
{ title: 'Pick role and skills', description: 'Choose service category and specialization.' },
|
||||||
|
{ title: 'Build profile', description: 'Add portfolio, strengths, and proof.' },
|
||||||
|
{ title: 'Pass verification', description: 'Approval protects platform trust.' },
|
||||||
|
{ title: 'Respond to opportunities', description: 'Manage matching leads in one flow.' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Companies',
|
||||||
|
title: 'Hiring workflows without chaos',
|
||||||
|
description: 'Publish requirements, keep quality high, and track applicants clearly.',
|
||||||
|
image: 'https://images.unsplash.com/photo-1486406146926-c627a92ad1ab?q=80&w=1200&auto=format&fit=crop',
|
||||||
|
steps: [
|
||||||
|
{ title: 'Create company profile', description: 'Set hiring context and org details.' },
|
||||||
|
{ title: 'Post requirements', description: 'Publish role details and expectations.' },
|
||||||
|
{ title: 'Approval before publish', description: 'Listings are reviewed first.' },
|
||||||
|
{ title: 'Manage pipeline', description: 'Track candidates and responses.' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Job Seekers',
|
||||||
|
title: 'Onboard once, apply with confidence',
|
||||||
|
description: 'Get visible only after approval, then discover jobs with targeted filters.',
|
||||||
|
image: 'https://images.unsplash.com/photo-1450101499163-c8848c66ca85?q=80&w=1200&auto=format&fit=crop',
|
||||||
|
steps: [
|
||||||
|
{ title: 'Set up profile', description: 'Complete essentials and work preferences.' },
|
||||||
|
{ title: 'Approval check', description: 'Review keeps quality consistent.' },
|
||||||
|
{ title: 'Explore matching jobs', description: 'Filter by practical criteria.' },
|
||||||
|
{ title: 'Apply and track', description: 'Submit applications and watch status.' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const faqs = [
|
||||||
|
{
|
||||||
|
q: 'What is Nxtgauge?',
|
||||||
|
a: 'Nxtgauge connects customers, professionals, companies, and job seekers in one trusted platform.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
q: 'Who can join Nxtgauge?',
|
||||||
|
a: 'Customers, service professionals, companies, and job seekers can create an account and choose their path.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
q: 'Why does Nxtgauge require verification?',
|
||||||
|
a: 'Verification helps reduce fake profiles and improves trust across the platform.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
q: 'How long does account approval take?',
|
||||||
|
a: 'Most profile approvals are completed within 24-48 hours.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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.',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
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 [flowIndex, setFlowIndex] = createSignal(0);
|
||||||
|
const [stepIndex, setStepIndex] = createSignal(0);
|
||||||
|
const [openFaq, setOpenFaq] = createSignal(0);
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
const onScroll = () => setScrolled(window.scrollY > 10);
|
||||||
|
onScroll();
|
||||||
|
window.addEventListener('scroll', onScroll, { passive: true });
|
||||||
|
|
||||||
|
const timer = window.setInterval(() => {
|
||||||
|
setStepIndex((prev) => {
|
||||||
|
const active = flows[flowIndex()];
|
||||||
|
if (prev + 1 < active.steps.length) return prev + 1;
|
||||||
|
setFlowIndex((f) => (f + 1) % flows.length);
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
}, 3200);
|
||||||
|
|
||||||
|
onCleanup(() => {
|
||||||
|
window.removeEventListener('scroll', onScroll);
|
||||||
|
window.clearInterval(timer);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
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');
|
||||||
|
});
|
||||||
|
|
||||||
|
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>
|
||||||
|
|
||||||
|
<nav class="nav-links desktop-only">
|
||||||
|
<A href="/">Home</A>
|
||||||
|
<A href="/about">About Us</A>
|
||||||
|
<A href="/contact">Contact Us</A>
|
||||||
|
</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>
|
||||||
|
</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>
|
||||||
|
|
||||||
|
<section class="public-section scene-dark">
|
||||||
|
<div class="container panel">
|
||||||
|
<div class="section-head">
|
||||||
|
<div>
|
||||||
|
<h2>Choose Your Path</h2>
|
||||||
|
<p>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')}>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>
|
||||||
|
</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 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 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>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
|
</div>
|
||||||
|
<div class="actions">
|
||||||
|
<button class="btn" onClick={() => { setFlowIndex((flowIndex() - 1 + flows.length) % flows.length); setStepIndex(0); }}>←</button>
|
||||||
|
<button class="btn" onClick={() => { setFlowIndex((flowIndex() + 1) % flows.length); setStepIndex(0); }}>→</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</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>
|
||||||
|
</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>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -1,138 +1,5 @@
|
||||||
import { A } from '@solidjs/router';
|
import PublicLanding from '~/components/PublicLanding';
|
||||||
|
|
||||||
const roleCards = [
|
|
||||||
{
|
|
||||||
title: 'Customer',
|
|
||||||
description: 'Find verified professionals in Chennai and submit exact requirements by category.',
|
|
||||||
cta: '/onboarding?schemaId=customer_onboarding_v1',
|
|
||||||
badge: 'Hire',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Professional',
|
|
||||||
description: 'Create your profile, upload portfolio, and complete identity verification.',
|
|
||||||
cta: '/onboarding?schemaId=professional_onboarding_v1',
|
|
||||||
badge: 'Offer Services',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Company',
|
|
||||||
description: 'Set hiring preferences and verify your business documents for trusted recruitment.',
|
|
||||||
cta: '/onboarding?schemaId=company_onboarding_v1',
|
|
||||||
badge: 'Recruit',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Jobseeker',
|
|
||||||
description: 'Share your profile, experience and documents once, then continue from dashboard.',
|
|
||||||
cta: '/onboarding?schemaId=jobseeker_onboarding_v1',
|
|
||||||
badge: 'Apply',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const professionalCategories = [
|
|
||||||
'Photographer',
|
|
||||||
'Makeup Artist',
|
|
||||||
'Tutor',
|
|
||||||
'Developer',
|
|
||||||
'Video Editor',
|
|
||||||
'Graphic Designer',
|
|
||||||
'Social Media Manager',
|
|
||||||
'Fitness Trainer',
|
|
||||||
'Catering Services',
|
|
||||||
];
|
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return <PublicLanding />;
|
||||||
<main class="landing">
|
|
||||||
<header class="topbar">
|
|
||||||
<div class="container nav-row">
|
|
||||||
<img class="brand-logo" src="/nxtgauge-logo.png" alt="NXTGAUGE" />
|
|
||||||
<nav class="nav-links">
|
|
||||||
<A href="/about">About Us</A>
|
|
||||||
<A href="/contact">Contact Us</A>
|
|
||||||
</nav>
|
|
||||||
<div class="nav-actions">
|
|
||||||
<A class="btn" href="/onboarding?schemaId=customer_onboarding_v1">Start</A>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<section class="hero-wrap">
|
|
||||||
<div class="container hero-grid">
|
|
||||||
<div>
|
|
||||||
<p class="eyebrow">Launch City: Chennai, India</p>
|
|
||||||
<h1 class="hero-title">Verified Hiring and Services, Powered by Runtime Config</h1>
|
|
||||||
<p class="hero-copy">
|
|
||||||
NXTGAUGE connects customers, professionals, companies, and jobseekers with role-based onboarding,
|
|
||||||
document verification, and dashboard-ready profiles.
|
|
||||||
</p>
|
|
||||||
<div class="hero-actions">
|
|
||||||
<A class="btn primary" href="/onboarding?schemaId=customer_onboarding_v1">I Want To Hire</A>
|
|
||||||
<A class="btn" href="/onboarding?schemaId=professional_onboarding_v1">I Am A Professional</A>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="hero-panel">
|
|
||||||
<h3>Professional Categories</h3>
|
|
||||||
<div class="chip-grid">
|
|
||||||
{professionalCategories.map((item) => (
|
|
||||||
<span class="chip">{item}</span>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
<p class="note">Customer onboarding Step 1 starts with selecting one of these service categories.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="section">
|
|
||||||
<div class="container">
|
|
||||||
<h2 class="section-title">Choose Your Flow</h2>
|
|
||||||
<p class="section-copy">Each role stays separate and gets its own onboarding questions from runtime schema.</p>
|
|
||||||
<div class="role-grid">
|
|
||||||
{roleCards.map((card) => (
|
|
||||||
<article class="role-card">
|
|
||||||
<span class="role-badge">{card.badge}</span>
|
|
||||||
<h3>{card.title}</h3>
|
|
||||||
<p>{card.description}</p>
|
|
||||||
<A class="btn primary" href={card.cta}>Open {card.title} Onboarding</A>
|
|
||||||
</article>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="section soft">
|
|
||||||
<div class="container split">
|
|
||||||
<div class="card">
|
|
||||||
<h3>Verification First</h3>
|
|
||||||
<p>
|
|
||||||
Document steps are runtime controlled, with PDF-only validation for identity/business verification and
|
|
||||||
2MB limits.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="card">
|
|
||||||
<h3>Portfolio Ready</h3>
|
|
||||||
<p>
|
|
||||||
Professional onboarding supports image portfolio uploads up to 6 files, ready for 3x2 dashboard preview.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="card">
|
|
||||||
<h3>No Hardcoded Fallback</h3>
|
|
||||||
<p>
|
|
||||||
Forms load from runtime schemas. Admin-published config is picked first, then seeded runtime config for
|
|
||||||
local demo.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<footer class="footer">
|
|
||||||
<div class="container footer-row">
|
|
||||||
<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>
|
|
||||||
<A href="/onboarding?schemaId=customer_onboarding_v1">Get Started</A>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
</main>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue