Files
Kordant/web/src/components/landing/HowItWorksSection.tsx
Michael Freno 3f00dd6b28 feat: add landing page Features, How It Works, and CTA sections
- HowItWorksSection: 3-step staggered timeline with gradient circles
- FeaturesGridSection: 6-card responsive grid (DarkWatch, VoicePrint, SpamShield, HomeTitle, RemoveBrokers, Family Plans)
- ForUsersSection: Split panel for Individuals and Families with checkmark lists
- WhyShieldAISection: 3 value prop cards (Proactive, AI-Powered, Privacy First)
- CTABannerSection: Final CTA with Create Account and Sign In buttons
- Updated routes/index.tsx with clip-path polygon transitions between sections
- Added 49 unit tests for all new sections
2026-05-25 15:12:32 -04:00

159 lines
4.1 KiB
TypeScript

import { For } from "solid-js";
import type { JSX } from "solid-js";
import { cn } from "~/lib/utils";
import PageContainer from "~/components/layout/PageContainer";
interface Step {
number: number;
title: string;
description: string;
icon: () => JSX.Element;
}
function EnrollIcon() {
return (
<svg
width="32"
height="32"
viewBox="0 0 32 32"
fill="none"
xmlns="http://www.w3.org/2000/svg"
class="w-8 h-8 text-white"
>
<path
d="M16 4C9.373 4 4 9.373 4 16s5.373 12 12 12 12-5.373 12-12S22.627 4 16 4zm0 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S6 21.523 6 16 10.477 6 16 6zm-1 3v5H9v2h6v5h2v-5h6v-2h-6V9h-2z"
fill="currentColor"
/>
</svg>
);
}
function MonitorIcon() {
return (
<svg
width="32"
height="32"
viewBox="0 0 32 32"
fill="none"
xmlns="http://www.w3.org/2000/svg"
class="w-8 h-8 text-white"
>
<path
d="M4 8v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2H6a2 2 0 00-2 2zm2 0h20v12H6V8zm-4 4h4v2H4v-2zm16 0h4v2h-4v-2z"
fill="currentColor"
/>
</svg>
);
}
function AlertIcon() {
return (
<svg
width="32"
height="32"
viewBox="0 0 32 32"
fill="none"
xmlns="http://www.w3.org/2000/svg"
class="w-8 h-8 text-white"
>
<path
d="M16 2L4 8v10c0 7.4 5.1 14.1 12 16 6.9-1.9 12-8.6 12-16V8L16 2zm0 2.8L26 9.5v8.5c0 6.1-4.2 11.7-10 13.4C10.2 29.7 6 24.1 6 18V9.5L16 4.8zM15 10v2h2v-2h-2zm0 4v6h2v-6h-2z"
fill="currentColor"
/>
</svg>
);
}
const steps: Step[] = [
{
number: 1,
title: "Enroll Your Identity",
description:
"Sign up and add your emails, phone numbers, and family members to create your protection profile.",
icon: EnrollIcon,
},
{
number: 2,
title: "We Monitor 24/7",
description:
"Our system runs continuous dark web scans, voiceprint detection, and spam filtering to catch threats early.",
icon: MonitorIcon,
},
{
number: 3,
title: "Get Instant Alerts",
description:
"Receive real-time notifications the moment a threat is detected, with clear guidance on what to do next.",
icon: AlertIcon,
},
];
interface StepItemProps {
step: Step;
index: number;
}
function StepItem(props: StepItemProps) {
const isEven = props.index % 2 === 0;
const Icon = props.step.icon;
return (
<div
class={cn(
"flex items-center gap-8 md:gap-16",
isEven ? "md:flex-row" : "md:flex-row-reverse",
)}
>
<div class={cn("flex-shrink-0", isEven ? "" : "md:order-last")}>
<div class="w-16 h-16 rounded-full gradient-primary shadow-glow-primary flex items-center justify-center">
<Icon />
</div>
</div>
<div class={cn("flex-1", isEven ? "" : "md:text-right")}>
<div class="inline-flex items-center gap-2 mb-2">
<span class="text-sm font-semibold text-[var(--color-brand-primary)]">
Step {props.step.number}
</span>
</div>
<h3 class="text-2xl md:text-3xl font-bold text-[var(--color-text-primary)] mb-3">
{props.step.title}
</h3>
<p class="text-lg text-[var(--color-text-secondary)] leading-relaxed max-w-lg">
{props.step.description}
</p>
</div>
</div>
);
}
interface HowItWorksSectionProps {
class?: string;
}
export default function HowItWorksSection(props: HowItWorksSectionProps) {
return (
<section
id="how-it-works"
class={cn("bg-dot-grid py-20 md:py-28 scroll-mt-16", props.class)}
>
<PageContainer py="py-8">
<div class="text-center mb-16">
<h2 class="text-3xl md:text-4xl lg:text-5xl font-bold text-[var(--color-text-primary)] mb-4">
How It Works
</h2>
<p class="text-lg text-[var(--color-text-secondary)] max-w-2xl mx-auto">
Three simple steps to full identity protection
</p>
</div>
<div class="flex flex-col gap-12 md:gap-16">
<For each={steps}>
{(step, index) => <StepItem step={step} index={index()} />}
</For>
</div>
</PageContainer>
</section>
);
}