clear old assets, new ci/cd flow

This commit is contained in:
2026-05-26 11:54:41 -04:00
parent 82815009c9
commit 72609755f8
87 changed files with 4132 additions and 7158 deletions

297
web/src/routes/pricing.tsx Normal file
View File

@@ -0,0 +1,297 @@
import { createSignal, For, Show } from "solid-js";
import { Title } from "@solidjs/meta";
import { A, useSearchParams } from "@solidjs/router";
import { cn } from "~/lib/utils";
import { Badge, Button, Card } from "~/components/ui";
import PageContainer from "~/components/layout/PageContainer";
interface Plan {
name: string;
price: string;
period: string;
description: string;
features: string[];
cta: string;
popular: boolean;
}
interface FAQ {
q: string;
a: string;
}
const plans: Plan[] = [
{
name: "Basic",
price: "$9",
period: "/month",
description: "Essential identity protection for individuals",
features: ["Dark web monitoring", "Email breach alerts", "Basic scam call blocking", "Monthly reports"],
cta: "Start Free Trial",
popular: false,
},
{
name: "Plus",
price: "$19",
period: "/month",
description: "Advanced protection for you and your family",
features: ["Everything in Basic", "VoicePrint AI detection", "HomeTitle fraud alerts", "RemoveBrokers automation", "Family sharing (up to 5)"],
cta: "Start Free Trial",
popular: true,
},
{
name: "Premium",
price: "$39",
period: "/month",
description: "Maximum security for the whole household",
features: ["Everything in Plus", "Unlimited family members", "Priority support 24/7", "Real-time alert correlation", "Advanced analytics dashboard", "Data broker suppression"],
cta: "Start Free Trial",
popular: false,
},
];
const faqs: FAQ[] = [
{
q: "How does Kordant detect voice clones?",
a: "VoicePrint analyzes over 200 acoustic features in real-time, including micro-tremors and breathing patterns that AI clones can't replicate accurately.",
},
{
q: "Is my data encrypted?",
a: "Yes. All data is encrypted at rest using AES-256 and in transit using TLS 1.3. We never share or sell your personal information.",
},
{
q: "Can I protect my whole family?",
a: "Absolutely. Plus and Premium plans include family sharing with centralized monitoring and alert management for all household members.",
},
{
q: "How does dark web monitoring work?",
a: "DarkWatch continuously scans dark web forums, marketplaces, and data dumps for your email addresses, phone numbers, and other personal data.",
},
{
q: "What happens after my free trial?",
a: "Your trial includes full access to your selected plan for 14 days. You can cancel anytime before the trial ends with no charge.",
},
{
q: "Can I remove my data from brokers?",
a: "Yes. RemoveBrokers automates opt-out requests to over 200 data broker sites and verifies removal on your behalf.",
},
];
const comparisonFeatures = [
{ feature: "Dark web monitoring", basic: true, plus: true, premium: true },
{ feature: "Email breach alerts", basic: true, plus: true, premium: true },
{ feature: "Basic scam call blocking", basic: true, plus: true, premium: true },
{ feature: "Monthly reports", basic: true, plus: true, premium: true },
{ feature: "VoicePrint AI detection", basic: false, plus: true, premium: true },
{ feature: "HomeTitle fraud alerts", basic: false, plus: true, premium: true },
{ feature: "RemoveBrokers automation", basic: false, plus: true, premium: true },
{ feature: "Family sharing", basic: false, plus: "Up to 5", premium: "Unlimited" },
{ feature: "Priority support 24/7", basic: false, plus: false, premium: true },
{ feature: "Real-time alert correlation", basic: false, plus: false, premium: true },
{ feature: "Advanced analytics", basic: false, plus: false, premium: true },
{ feature: "Data broker suppression", basic: false, plus: false, premium: true },
];
function CheckIcon() {
return (
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" class="flex-shrink-0">
<path d="M6.5 11.5L3 8l1.1-1.1L6.5 9.3l5.9-5.9L13.5 4.5l-7 7z" fill="var(--color-success)"/>
</svg>
);
}
function XIcon() {
return (
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" class="flex-shrink-0">
<path d="M4 4l8 8M12 4l-8 8" stroke="var(--color-text-muted)" stroke-width="1.5" stroke-linecap="round"/>
</svg>
);
}
export default function PricingPage() {
const [searchParams] = useSearchParams();
const [openFaq, setOpenFaq] = createSignal<string | null>(null);
const signupUrl = () => `/signup${searchParams.utm_source ? `?utm_source=${searchParams.utm_source}&utm_medium=${searchParams.utm_medium || ""}&utm_campaign=${searchParams.utm_campaign || ""}` : ""}`;
return (
<main>
<Title>Kordant Pricing AI-Powered Identity Protection Plans</Title>
<section class="relative py-20 md:py-28 overflow-hidden">
<div class="absolute inset-0 bg-gradient-to-b from-[var(--color-brand-primary)]/5 to-transparent" />
<PageContainer class="relative z-10">
<div class="text-center max-w-3xl mx-auto">
<Badge variant="info" class="mb-4">Simple Pricing</Badge>
<h1 class="text-4xl md:text-5xl lg:text-6xl font-bold text-[var(--color-text-primary)] mb-6">
Protection That Fits{" "}
<span class="text-gradient-primary">Your Budget</span>
</h1>
<p class="text-xl text-[var(--color-text-secondary)] mb-8 max-w-2xl mx-auto">
Start with a 14-day free trial. No credit card required. Cancel anytime.
</p>
<div class="flex flex-wrap items-center justify-center gap-x-6 gap-y-2 text-sm text-[var(--color-text-tertiary)]">
<span class="flex items-center gap-1.5">
<CheckIcon />14-day free trial
</span>
<span class="flex items-center gap-1.5">
<CheckIcon />No credit card required
</span>
<span class="flex items-center gap-1.5">
<CheckIcon />Cancel anytime
</span>
</div>
</div>
</PageContainer>
</section>
<section class="py-20 md:py-28">
<PageContainer>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 max-w-5xl mx-auto">
<For each={plans}>
{(plan) => (
<Card
class={cn(
"relative flex flex-col",
plan.popular && "ring-2 ring-[var(--color-brand-primary)] shadow-glow-primary",
)}
>
<Show when={plan.popular}>
<div class="absolute -top-3 left-1/2 -translate-x-1/2">
<Badge variant="info">Most Popular</Badge>
</div>
</Show>
<div class="mb-6">
<h3 class="text-lg font-semibold text-[var(--color-text-primary)] mb-1">{plan.name}</h3>
<p class="text-sm text-[var(--color-text-secondary)] mb-4">{plan.description}</p>
<div class="flex items-baseline gap-0.5">
<span class="text-4xl font-bold text-[var(--color-text-primary)]">{plan.price}</span>
<span class="text-sm text-[var(--color-text-tertiary)]">{plan.period}</span>
</div>
</div>
<ul class="space-y-3 mb-8 flex-1">
<For each={plan.features}>
{(feature) => (
<li class="flex items-start gap-2 text-sm text-[var(--color-text-secondary)]">
<CheckIcon />
{feature}
</li>
)}
</For>
</ul>
<A href={signupUrl()}>
<Button variant={plan.popular ? "primary" : "secondary"} class="w-full">
{plan.cta}
</Button>
</A>
</Card>
)}
</For>
</div>
</PageContainer>
</section>
<section class="py-16 bg-[var(--color-bg-secondary)]">
<PageContainer>
<div class="text-center mb-12">
<h2 class="text-3xl md:text-4xl font-bold text-[var(--color-text-primary)] mb-4">
Compare Plans
</h2>
</div>
<div class="max-w-4xl mx-auto overflow-x-auto">
<table class="w-full">
<thead>
<tr class="border-b-2 border-[var(--color-border)]">
<th class="text-left px-4 py-3 text-sm font-medium text-[var(--color-text-secondary)]">Feature</th>
<th class="text-center px-4 py-3 text-sm font-medium text-[var(--color-text-secondary)]">Basic</th>
<th class="text-center px-4 py-3 text-sm font-semibold text-[var(--color-brand-primary)]">Plus</th>
<th class="text-center px-4 py-3 text-sm font-medium text-[var(--color-text-secondary)]">Premium</th>
</tr>
</thead>
<tbody>
<For each={comparisonFeatures}>
{(row) => (
<tr class="border-b border-[var(--color-border)]">
<td class="px-4 py-3 text-sm text-[var(--color-text-primary)]">{row.feature}</td>
<td class="text-center px-4 py-3">
{row.basic === true ? <CheckIcon /> : row.basic === false ? <XIcon /> : <span class="text-xs text-[var(--color-text-secondary)]">{row.basic}</span>}
</td>
<td class="text-center px-4 py-3">
{row.plus === true ? <CheckIcon /> : row.plus === false ? <XIcon /> : <span class="text-xs text-[var(--color-text-secondary)]">{row.plus}</span>}
</td>
<td class="text-center px-4 py-3">
{row.premium === true ? <CheckIcon /> : row.premium === false ? <XIcon /> : <span class="text-xs text-[var(--color-text-secondary)]">{row.premium}</span>}
</td>
</tr>
)}
</For>
</tbody>
</table>
</div>
</PageContainer>
</section>
<section class="py-20 md:py-28">
<PageContainer>
<div class="max-w-3xl mx-auto">
<div class="text-center mb-12">
<h2 class="text-3xl md:text-4xl font-bold text-[var(--color-text-primary)] mb-4">
Frequently Asked Questions
</h2>
</div>
<div class="space-y-3">
<For each={faqs}>
{(faq) => {
const isOpen = () => openFaq() === faq.q;
return (
<div class="border border-[var(--color-border)] rounded-xl overflow-hidden">
<button
type="button"
class="w-full flex items-center justify-between px-5 py-4 text-left text-sm font-medium text-[var(--color-text-primary)] hover:bg-[var(--color-bg-secondary)] transition-colors"
onClick={() => setOpenFaq(isOpen() ? null : faq.q)}
>
{faq.q}
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
class={cn("transition-transform duration-200", isOpen() && "rotate-180")}
>
<path d="M4 6l4 4 4-4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
<Show when={isOpen()}>
<div class="px-5 pb-4 text-sm text-[var(--color-text-secondary)] leading-relaxed">
{faq.a}
</div>
</Show>
</div>
);
}}
</For>
</div>
</div>
</PageContainer>
</section>
<section class="py-16 bg-[var(--color-brand-primary)]">
<PageContainer>
<div class="text-center">
<h2 class="text-3xl md:text-4xl font-bold text-white mb-4">
Ready to protect your identity?
</h2>
<p class="text-lg text-white/80 mb-8 max-w-2xl mx-auto">
Join 50,000+ users who trust Kordant for AI-powered identity protection.
</p>
<A href={signupUrl()}>
<Button variant="primary" size="lg" class="bg-white text-[var(--color-brand-primary)] hover:bg-white/90 shadow-lg">
Get Started Free
</Button>
</A>
</div>
</PageContainer>
</section>
</main>
);
}