@utopia-studio-design/design-system-cli 0.6.2 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -14
- package/bin/utopia-ds-mcp.mjs +6 -2
- package/bin/utopia-ds.mjs +94 -21
- package/data/docs/arabic-friendly.md +19 -2
- package/data/docs/billing-setup.md +80 -0
- package/data/docs/cer-003-032-033-round-8-repair.md +41 -0
- package/data/docs/cer-007-checkout.md +51 -0
- package/data/docs/cer-008-011-qa-repair.md +64 -0
- package/data/docs/cer-016-023-round-6-repair.md +92 -0
- package/data/docs/cer-024-031-round-7-repair.md +51 -0
- package/data/docs/cer-033-035-036-round-12-repair.md +37 -0
- package/data/docs/cer-035-037-round-10-repair.md +34 -0
- package/data/docs/charts.md +34 -3
- package/data/docs/chat-service-methodology.md +181 -0
- package/data/docs/code-block.md +20 -0
- package/data/docs/creative-production.md +149 -0
- package/data/docs/designer-agent-backend-contract.md +552 -0
- package/data/docs/email-resend.md +29 -0
- package/data/docs/foundations.md +46 -8
- package/data/docs/guide.md +9 -9
- package/data/docs/handover-billing-aiden.md +132 -0
- package/data/docs/logo-maker-methodology.md +109 -0
- package/data/docs/presentation-asset-repository.md +53 -0
- package/data/docs/product-architecture.md +42 -0
- package/data/docs/quick-start-ai.md +4 -4
- package/data/docs/shadcn-conversion.md +1 -1
- package/data/docs/sidebar-placement.md +56 -0
- package/data/docs/theme-authoring.md +6 -3
- package/data/manifests/catalog.json +42 -46
- package/data/manifests/components.json +317 -66
- package/data/manifests/logo-skills.json +174 -0
- package/data/manifests/motion-profiles.json +2 -2
- package/data/manifests/patterns.json +201 -7
- package/data/manifests/presentation-assets.schema.json +44 -0
- package/data/manifests/templates.json +87 -1
- package/data/manifests/theme-dextrum.json +7 -7
- package/data/manifests/theme-prism-mono.json +19 -0
- package/data/manifests/theme-utopia-cloudblur.json +135 -0
- package/data/manifests/theme-utopia-default.json +31 -31
- package/data/manifests/theme-vyapti.json +17 -1
- package/data/manifests/theme-y2k-pop.json +18 -0
- package/data/manifests/themes.json +285 -57
- package/data/templates/analytics-dashboard/main.tsx +14 -1
- package/data/templates/calendar-application/main.tsx +14 -1
- package/data/templates/chat-workspace/README.md +12 -0
- package/data/templates/chat-workspace/index.html +11 -0
- package/data/templates/chat-workspace/main.tsx +97 -0
- package/data/templates/chat-workspace/styles.css +19 -0
- package/data/templates/chat-workspace/template.manifest.json +13 -0
- package/data/templates/composition-registry-lab/main.tsx +12 -1
- package/data/templates/dashboard-composer/main.tsx +14 -1
- package/data/templates/database-workspace/main.tsx +14 -1
- package/data/templates/interaction-lab/main.tsx +12 -1
- package/data/templates/quantum-verification-story/README.md +12 -0
- package/data/templates/quantum-verification-story/components.json +21 -0
- package/data/templates/quantum-verification-story/eslint.config.mjs +13 -0
- package/data/templates/quantum-verification-story/next-env.d.ts +7 -0
- package/data/templates/quantum-verification-story/next.config.mjs +11 -0
- package/data/templates/quantum-verification-story/package-lock.json +7535 -0
- package/data/templates/quantum-verification-story/package.json +46 -0
- package/data/templates/quantum-verification-story/postcss.config.js +6 -0
- package/data/templates/quantum-verification-story/src/app/assessment/page.tsx +138 -0
- package/data/templates/quantum-verification-story/src/app/ceramic-theme.css +48 -0
- package/data/templates/quantum-verification-story/src/app/deployment/page.tsx +178 -0
- package/data/templates/quantum-verification-story/src/app/fonts/IBMPlexSansArabic-Bold.ttf +0 -0
- package/data/templates/quantum-verification-story/src/app/fonts/IBMPlexSansArabic-Medium.ttf +0 -0
- package/data/templates/quantum-verification-story/src/app/fonts/IBMPlexSansArabic-Regular.ttf +0 -0
- package/data/templates/quantum-verification-story/src/app/fonts/ReadexPro-Variable.ttf +0 -0
- package/data/templates/quantum-verification-story/src/app/fonts/TWKLausanne-350.ttf +0 -0
- package/data/templates/quantum-verification-story/src/app/fonts/TWKLausanne-500.ttf +0 -0
- package/data/templates/quantum-verification-story/src/app/fonts/TWKLausanne-700.ttf +0 -0
- package/data/templates/quantum-verification-story/src/app/globals.css +175 -0
- package/data/templates/quantum-verification-story/src/app/layout.tsx +45 -0
- package/data/templates/quantum-verification-story/src/app/not-found.tsx +39 -0
- package/data/templates/quantum-verification-story/src/app/page.tsx +24 -0
- package/data/templates/quantum-verification-story/src/app/products/page.tsx +132 -0
- package/data/templates/quantum-verification-story/src/app/utopia-default.css +312 -0
- package/data/templates/quantum-verification-story/src/components/RotatingText.css +36 -0
- package/data/templates/quantum-verification-story/src/components/RotatingText.tsx +189 -0
- package/data/templates/quantum-verification-story/src/components/brand-mark.tsx +14 -0
- package/data/templates/quantum-verification-story/src/components/console-preview-section.tsx +57 -0
- package/data/templates/quantum-verification-story/src/components/console-preview.tsx +72 -0
- package/data/templates/quantum-verification-story/src/components/fade-up.tsx +54 -0
- package/data/templates/quantum-verification-story/src/components/floating-network.tsx +125 -0
- package/data/templates/quantum-verification-story/src/components/footer.tsx +83 -0
- package/data/templates/quantum-verification-story/src/components/harvest-timeline.tsx +70 -0
- package/data/templates/quantum-verification-story/src/components/lattice-diagram.tsx +73 -0
- package/data/templates/quantum-verification-story/src/components/lattice-field.tsx +129 -0
- package/data/templates/quantum-verification-story/src/components/nav.tsx +104 -0
- package/data/templates/quantum-verification-story/src/components/presentation-layout.tsx +91 -0
- package/data/templates/quantum-verification-story/src/components/readiness-estimator.tsx +135 -0
- package/data/templates/quantum-verification-story/src/components/scramble-text.tsx +60 -0
- package/data/templates/quantum-verification-story/src/components/section-backdrop.tsx +38 -0
- package/data/templates/quantum-verification-story/src/components/sections/clients.tsx +140 -0
- package/data/templates/quantum-verification-story/src/components/sections/contact.tsx +125 -0
- package/data/templates/quantum-verification-story/src/components/sections/hero.tsx +92 -0
- package/data/templates/quantum-verification-story/src/components/sections/moat.tsx +73 -0
- package/data/templates/quantum-verification-story/src/components/sections/offer.tsx +113 -0
- package/data/templates/quantum-verification-story/src/components/sections/pilot.tsx +63 -0
- package/data/templates/quantum-verification-story/src/components/sections/problem.tsx +53 -0
- package/data/templates/quantum-verification-story/src/components/text-particle.tsx +204 -0
- package/data/templates/quantum-verification-story/src/components/ticker.tsx +27 -0
- package/data/templates/quantum-verification-story/src/components/ui/badge.tsx +29 -0
- package/data/templates/quantum-verification-story/src/components/ui/button.tsx +55 -0
- package/data/templates/quantum-verification-story/src/components/ui/card.tsx +46 -0
- package/data/templates/quantum-verification-story/src/components/ui/cursor-driven-particle-typography.tsx +288 -0
- package/data/templates/quantum-verification-story/src/components/ui/input.tsx +20 -0
- package/data/templates/quantum-verification-story/src/components/ui/label.tsx +21 -0
- package/data/templates/quantum-verification-story/src/components/ui/separator.tsx +25 -0
- package/data/templates/quantum-verification-story/src/components/ui/textarea.tsx +19 -0
- package/data/templates/quantum-verification-story/src/lib/utils.ts +6 -0
- package/data/templates/quantum-verification-story/tailwind.config.js +95 -0
- package/data/templates/quantum-verification-story/template.manifest.json +23 -0
- package/data/templates/quantum-verification-story/tsconfig.json +42 -0
- package/data/templates/saas-solution-homepage/main.tsx +91 -14
- package/data/templates/saas-solution-homepage/privacy/index.html +1 -0
- package/data/templates/saas-solution-homepage/styles.css +47 -2
- package/data/templates/saas-solution-homepage/team/index.html +1 -0
- package/data/templates/saas-solution-homepage/template.manifest.json +41 -0
- package/data/templates/saas-solution-homepage/terms/index.html +1 -0
- package/lib/api.mjs +52 -3
- package/lib/template-runtime.mjs +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { Landmark, Building2, Globe } from "lucide-react"
|
|
2
|
+
import { ScrambleText } from "@/components/scramble-text"
|
|
3
|
+
import { SectionBackdrop } from "@/components/section-backdrop"
|
|
4
|
+
import { FadeUp } from "@/components/fade-up"
|
|
5
|
+
|
|
6
|
+
const CX = 230
|
|
7
|
+
const CY = 250
|
|
8
|
+
const R = 162
|
|
9
|
+
|
|
10
|
+
function nodePos(deg: number) {
|
|
11
|
+
const r = (deg * Math.PI) / 180
|
|
12
|
+
return { x: CX + R * Math.cos(r), y: CY + R * Math.sin(r) }
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const nodes = [
|
|
16
|
+
{ angle: -90, num: "01", lines: ["Government", "Contractors"], tag: "Mandate-driven" },
|
|
17
|
+
{ angle: 30, num: "02", lines: ["Regional Banks", "& NBFCs"], tag: "RBI framework" },
|
|
18
|
+
{ angle: 150, num: "03", lines: ["IT Services", "Firms"], tag: "10× reach" },
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
const clients = [
|
|
22
|
+
{
|
|
23
|
+
tag: "Profile 01",
|
|
24
|
+
icon: Landmark,
|
|
25
|
+
name: "Government IT Contractors",
|
|
26
|
+
desc: "Mandates are live. Internal PQC capability is near-zero. Budget is allocated.",
|
|
27
|
+
deal: [{ l: "Entry Point", v: "Assessment" }, { l: "Urgency", v: "Mandate-driven" }],
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
tag: "Profile 02",
|
|
31
|
+
icon: Building2,
|
|
32
|
+
name: "Regional Banks & NBFCs",
|
|
33
|
+
desc: "Regulators are watching. Attackers aren't waiting. Give your CISO a defensible plan.",
|
|
34
|
+
deal: [{ l: "Entry Point", v: "CISO Briefing" }, { l: "Urgency", v: "RBI framework" }],
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
tag: "Profile 03",
|
|
38
|
+
icon: Globe,
|
|
39
|
+
name: "Tier-2 IT Services Firms",
|
|
40
|
+
desc: "Your US and EU clients demand PQC-ready vendors — we become your white-label capability.",
|
|
41
|
+
deal: [{ l: "Entry Point", v: "BD / Alliance" }, { l: "Multiplier", v: "10× reach" }],
|
|
42
|
+
},
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
export function ClientsSection() {
|
|
46
|
+
return (
|
|
47
|
+
<section
|
|
48
|
+
id="clients"
|
|
49
|
+
className="relative min-h-screen md:h-screen flex flex-col justify-center md:overflow-hidden border-b border-[var(--color-border)] bg-white"
|
|
50
|
+
>
|
|
51
|
+
<SectionBackdrop />
|
|
52
|
+
<div className="container-main relative z-10 py-6">
|
|
53
|
+
<div className="grid md:grid-cols-[1fr_1fr] gap-6 items-center">
|
|
54
|
+
|
|
55
|
+
{/* Left: header + orbital diagram */}
|
|
56
|
+
<div>
|
|
57
|
+
<FadeUp className="mb-4">
|
|
58
|
+
<ScrambleText text="Who We Serve" className="eyebrow mb-2 block" />
|
|
59
|
+
<h2 className="font-bold leading-[1.1] tracking-tight text-[var(--color-text-primary)]"
|
|
60
|
+
style={{ fontSize: "clamp(1.5rem, 2vw + 0.5rem, 2.5rem)" }}>
|
|
61
|
+
Three clients.{" "}
|
|
62
|
+
<span className="text-[var(--primary-500)]">Urgent</span> need. Right now.
|
|
63
|
+
</h2>
|
|
64
|
+
</FadeUp>
|
|
65
|
+
<FadeUp delay={0.05}>
|
|
66
|
+
<div className="overflow-hidden">
|
|
67
|
+
<svg viewBox="0 0 460 430" className="w-full block">
|
|
68
|
+
{/* Outer dashed orbit */}
|
|
69
|
+
<circle cx={CX} cy={CY} r={R} fill="none" stroke="var(--primary-500)" strokeWidth="1.4" strokeDasharray="7 5" opacity="0.58" />
|
|
70
|
+
{/* Inner dashed orbit */}
|
|
71
|
+
<circle cx={CX} cy={CY} r={R * 0.57} fill="none" stroke="var(--primary-500)" strokeWidth="1" strokeDasharray="5 4" opacity="0.28" />
|
|
72
|
+
{/* Inner fill */}
|
|
73
|
+
<circle cx={CX} cy={CY} r={R * 0.54} fill="rgba(0,0,0,0.03)" />
|
|
74
|
+
{/* Brand center circle */}
|
|
75
|
+
<circle cx={CX} cy={CY} r={R * 0.37} fill="var(--deep-900)" />
|
|
76
|
+
|
|
77
|
+
{/* Theme-driven neutral mark */}
|
|
78
|
+
<rect x={CX - 24} y={CY - 24} width="48" height="48" rx="8" fill="var(--primary-500)" transform={`rotate(45 ${CX} ${CY})`} />
|
|
79
|
+
|
|
80
|
+
{/* Client nodes */}
|
|
81
|
+
{nodes.map((n) => {
|
|
82
|
+
const p = nodePos(n.angle)
|
|
83
|
+
return (
|
|
84
|
+
<g key={n.num}>
|
|
85
|
+
<circle cx={p.x} cy={p.y} r={17} fill="var(--background)" stroke="var(--primary-400)" strokeWidth="1.5" />
|
|
86
|
+
<text x={p.x} y={p.y + 4.5} textAnchor="middle" fill="var(--primary-500)" fontSize="9.5" fontWeight="700" fontFamily="var(--font-mono)">
|
|
87
|
+
{n.num}
|
|
88
|
+
</text>
|
|
89
|
+
{n.lines.map((line, i) => (
|
|
90
|
+
<text key={i} x={p.x} y={p.y + 30 + i * 12} textAnchor="middle" fill="var(--foreground)" fontSize="9.5" fontWeight="600" fontFamily="var(--font-sans)">
|
|
91
|
+
{line}
|
|
92
|
+
</text>
|
|
93
|
+
))}
|
|
94
|
+
<text x={p.x} y={p.y + 60} textAnchor="middle" fill="var(--primary-600)" fontSize="8" fontFamily="var(--font-sans)" letterSpacing="0.05em">
|
|
95
|
+
{n.tag}
|
|
96
|
+
</text>
|
|
97
|
+
</g>
|
|
98
|
+
)
|
|
99
|
+
})}
|
|
100
|
+
</svg>
|
|
101
|
+
</div>
|
|
102
|
+
</FadeUp>
|
|
103
|
+
</div>
|
|
104
|
+
|
|
105
|
+
{/* Right: client profile cards */}
|
|
106
|
+
<div className="flex flex-col gap-3">
|
|
107
|
+
{clients.map((c, i) => {
|
|
108
|
+
const Icon = c.icon
|
|
109
|
+
return (
|
|
110
|
+
<FadeUp key={c.name} delay={i * 0.18}>
|
|
111
|
+
<div className="rounded-xl border border-[var(--color-border)] bg-white hover:shadow-md hover:border-[var(--color-border-strong)] transition-all p-5">
|
|
112
|
+
<div className="flex items-center justify-between mb-3">
|
|
113
|
+
<span className="inline-block px-2.5 py-1 text-[10px] font-mono font-semibold uppercase tracking-[0.1em] rounded-full bg-[var(--primary-50)] text-[var(--primary-700)] border border-[var(--primary-200)]">
|
|
114
|
+
{c.tag}
|
|
115
|
+
</span>
|
|
116
|
+
<div className="flex items-center justify-center w-8 h-8 rounded-lg bg-[var(--deep-900)]">
|
|
117
|
+
<Icon size={15} className="text-[var(--primary-400)]" strokeWidth={2} />
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|
|
120
|
+
<h3 className="text-[14px] font-bold mb-1.5 tracking-tight text-[var(--color-text-primary)]">{c.name}</h3>
|
|
121
|
+
<p className="text-[12px] leading-[1.6] text-[var(--color-text-secondary)] mb-3">{c.desc}</p>
|
|
122
|
+
<div className="border-t border-[var(--color-border)] pt-3 grid grid-cols-2 gap-2">
|
|
123
|
+
{c.deal.map((d) => (
|
|
124
|
+
<div key={d.l}>
|
|
125
|
+
<label className="block font-mono text-[9px] tracking-[0.1em] text-[var(--color-text-muted)] uppercase mb-0.5">{d.l}</label>
|
|
126
|
+
<span className="text-[11.5px] font-semibold text-[var(--color-text-primary)]">{d.v}</span>
|
|
127
|
+
</div>
|
|
128
|
+
))}
|
|
129
|
+
</div>
|
|
130
|
+
</div>
|
|
131
|
+
</FadeUp>
|
|
132
|
+
)
|
|
133
|
+
})}
|
|
134
|
+
</div>
|
|
135
|
+
|
|
136
|
+
</div>
|
|
137
|
+
</div>
|
|
138
|
+
</section>
|
|
139
|
+
)
|
|
140
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { useState } from "react"
|
|
4
|
+
import { Button } from "@/components/ui/button"
|
|
5
|
+
import { Input } from "@/components/ui/input"
|
|
6
|
+
import { Textarea } from "@/components/ui/textarea"
|
|
7
|
+
import { Label } from "@/components/ui/label"
|
|
8
|
+
import { ScrambleText } from "@/components/scramble-text"
|
|
9
|
+
import { SectionBackdrop } from "@/components/section-backdrop"
|
|
10
|
+
import { FadeUp } from "@/components/fade-up"
|
|
11
|
+
|
|
12
|
+
export function ContactSection() {
|
|
13
|
+
const [status, setStatus] = useState<"idle" | "sending" | "ok" | "err">("idle")
|
|
14
|
+
|
|
15
|
+
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
|
16
|
+
e.preventDefault()
|
|
17
|
+
setStatus("sending")
|
|
18
|
+
const form = e.currentTarget
|
|
19
|
+
try {
|
|
20
|
+
const res = await fetch("https://formspree.io/f/xwvaqyvb", {
|
|
21
|
+
method: "POST",
|
|
22
|
+
body: new FormData(form),
|
|
23
|
+
headers: { Accept: "application/json" },
|
|
24
|
+
})
|
|
25
|
+
setStatus(res.ok ? "ok" : "err")
|
|
26
|
+
if (res.ok) form.reset()
|
|
27
|
+
} catch {
|
|
28
|
+
setStatus("err")
|
|
29
|
+
}
|
|
30
|
+
setTimeout(() => setStatus("idle"), 4000)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<section id="contact" className="relative min-h-screen md:h-screen flex flex-col justify-center md:overflow-hidden border-b border-[var(--color-border)] bg-[var(--gray-50)]">
|
|
35
|
+
<SectionBackdrop />
|
|
36
|
+
<div className="container-main relative z-10 py-6">
|
|
37
|
+
<div className="grid md:grid-cols-2 gap-12 lg:gap-20">
|
|
38
|
+
|
|
39
|
+
{/* Left */}
|
|
40
|
+
<FadeUp>
|
|
41
|
+
<div>
|
|
42
|
+
<ScrambleText text="Get in Touch" className="eyebrow mb-2 block" />
|
|
43
|
+
<h2 className="font-bold leading-[1.1] tracking-tight text-[var(--color-text-primary)] mb-4"
|
|
44
|
+
style={{ fontSize: "clamp(1.5rem, 2vw + 0.5rem, 2.5rem)" }}>
|
|
45
|
+
Let's start<br />
|
|
46
|
+
the <span className="text-[var(--primary-500)]">conversation.</span>
|
|
47
|
+
</h2>
|
|
48
|
+
<p className="text-[14px] leading-[1.7] text-[var(--color-text-secondary)] mb-6">
|
|
49
|
+
CISO, CTO, or security leader wondering if you're exposed? You almost certainly are.
|
|
50
|
+
The fastest way to know is a scan — see your exposure in days, not months.
|
|
51
|
+
</p>
|
|
52
|
+
<div className="space-y-0 divide-y divide-[var(--color-border)] border-t border-[var(--color-border)]">
|
|
53
|
+
{[
|
|
54
|
+
{ l: "Focus", v: "Post-Quantum Cryptography, Behavioral Identity, PQC Talent" },
|
|
55
|
+
{ l: "Markets", v: "APAC · Middle East · United States · European Union" },
|
|
56
|
+
{ l: "Plans", v: "Self-serve scan or enterprise verification" },
|
|
57
|
+
].map((d) => (
|
|
58
|
+
<div key={d.l} className="flex gap-5 items-start py-3">
|
|
59
|
+
<span className="font-mono text-[10px] tracking-[0.12em] text-[var(--primary-500)] uppercase w-24 shrink-0 pt-0.5 font-semibold">
|
|
60
|
+
{d.l}
|
|
61
|
+
</span>
|
|
62
|
+
<span className="text-[13px] text-[var(--color-text-primary)]">{d.v}</span>
|
|
63
|
+
</div>
|
|
64
|
+
))}
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
</FadeUp>
|
|
68
|
+
|
|
69
|
+
{/* Right: form */}
|
|
70
|
+
<FadeUp delay={0.15}>
|
|
71
|
+
<form onSubmit={handleSubmit} className="bg-white rounded-xl border border-[var(--color-border)] p-6 space-y-4 shadow-sm">
|
|
72
|
+
<div>
|
|
73
|
+
<Label htmlFor="name">Your Name</Label>
|
|
74
|
+
<Input id="name" name="name" placeholder="Full name" required />
|
|
75
|
+
</div>
|
|
76
|
+
<div className="grid grid-cols-2 gap-3">
|
|
77
|
+
<div>
|
|
78
|
+
<Label htmlFor="org">Organisation</Label>
|
|
79
|
+
<Input id="org" name="organisation" placeholder="Company name" />
|
|
80
|
+
</div>
|
|
81
|
+
<div>
|
|
82
|
+
<Label htmlFor="role">Role</Label>
|
|
83
|
+
<Input id="role" name="role" placeholder="CISO, CTO, etc." />
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
<div>
|
|
87
|
+
<Label htmlFor="email">Work Email</Label>
|
|
88
|
+
<Input id="email" name="email" type="email" placeholder="you@organisation.com" required />
|
|
89
|
+
</div>
|
|
90
|
+
<div>
|
|
91
|
+
<Label>I am interested in</Label>
|
|
92
|
+
<select
|
|
93
|
+
name="interest"
|
|
94
|
+
className="flex h-10 w-full rounded-md border border-[var(--color-border)] bg-white px-3 py-2 text-[14px] text-[var(--color-text-primary)] focus-visible:outline-none focus-visible:border-[var(--deep-900)] transition-colors"
|
|
95
|
+
>
|
|
96
|
+
<option>Run a scan of my stack</option>
|
|
97
|
+
<option>See a demo of the platform</option>
|
|
98
|
+
<option>Pricing & plans</option>
|
|
99
|
+
<option>Partnership / white-label</option>
|
|
100
|
+
<option>Just learning more</option>
|
|
101
|
+
</select>
|
|
102
|
+
</div>
|
|
103
|
+
<div>
|
|
104
|
+
<Label htmlFor="msg">Context (optional)</Label>
|
|
105
|
+
<Textarea id="msg" name="message"
|
|
106
|
+
placeholder="Any context about your current security posture, timeline, or specific concerns..." />
|
|
107
|
+
</div>
|
|
108
|
+
<input type="text" name="_gotcha" className="hidden" tabIndex={-1} autoComplete="off" />
|
|
109
|
+
<Button
|
|
110
|
+
type="submit"
|
|
111
|
+
className="w-full rounded-full bg-[var(--deep-900)] text-white hover:bg-[var(--deep-800)] h-10 font-semibold"
|
|
112
|
+
disabled={status === "sending"}
|
|
113
|
+
>
|
|
114
|
+
{status === "idle" && "Request a Demo →"}
|
|
115
|
+
{status === "sending" && "Sending..."}
|
|
116
|
+
{status === "ok" && "Message sent ✓"}
|
|
117
|
+
{status === "err" && "Error — please retry"}
|
|
118
|
+
</Button>
|
|
119
|
+
</form>
|
|
120
|
+
</FadeUp>
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
</section>
|
|
124
|
+
)
|
|
125
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import Link from "next/link"
|
|
4
|
+
import { Button } from "@/components/ui/button"
|
|
5
|
+
import RotatingText from "@/components/RotatingText"
|
|
6
|
+
import { LatticeField } from "@/components/lattice-field"
|
|
7
|
+
import { ConsolePreview } from "@/components/console-preview"
|
|
8
|
+
|
|
9
|
+
export function HeroSection() {
|
|
10
|
+
return (
|
|
11
|
+
<div className="min-h-screen md:h-screen flex flex-col md:overflow-hidden bg-[var(--gray-950)]">
|
|
12
|
+
{/* Framed hero fills full height */}
|
|
13
|
+
<div className="flex-1 px-2 sm:px-3 pb-2 sm:pb-3 min-h-0 pt-3">
|
|
14
|
+
<div className="relative h-full overflow-hidden rounded-[20px] sm:rounded-[28px] bg-[var(--deep-900)]">
|
|
15
|
+
{/* Theme-driven base wash */}
|
|
16
|
+
<div className="absolute inset-0 pointer-events-none"
|
|
17
|
+
style={{ background: "linear-gradient(180deg, var(--deep-800) 0%, var(--deep-900) 55%, var(--deep-950) 100%)" }} />
|
|
18
|
+
{/* Light gradient glow */}
|
|
19
|
+
<div className="absolute inset-x-0 bottom-0 h-[75%] pointer-events-none"
|
|
20
|
+
style={{ background: "radial-gradient(62% 80% at 50% 118%, color-mix(in srgb, var(--primary-foreground) 55%, transparent) 0%, color-mix(in srgb, var(--primary) 28%, transparent) 32%, color-mix(in srgb, var(--primary) 10%, transparent) 55%, transparent 72%)" }} />
|
|
21
|
+
<LatticeField />
|
|
22
|
+
|
|
23
|
+
<div className="container-main relative z-10 h-full flex flex-col pt-12 sm:pt-16 lg:pt-20">
|
|
24
|
+
|
|
25
|
+
{/* Top: headline + intro row (Linear-style, left-aligned) */}
|
|
26
|
+
<div className="shrink-0">
|
|
27
|
+
{/* Eyebrow */}
|
|
28
|
+
<div className="inline-flex items-center gap-2 px-3 py-1 rounded-full border border-white/20 text-[11px] font-mono uppercase tracking-[0.12em] text-[var(--primary-300)] mb-5 backdrop-blur-sm">
|
|
29
|
+
<span className="w-1.5 h-1.5 rounded-full bg-[var(--primary-400)]" />
|
|
30
|
+
Post-Quantum Verification Platform
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
{/* Headline */}
|
|
34
|
+
<h1 className="text-white font-bold leading-[1.04] tracking-tight"
|
|
35
|
+
style={{ fontSize: "clamp(2.25rem, 4.5vw + 0.5rem, 5rem)", maxWidth: "18ch" }}>
|
|
36
|
+
<span className="block">Your encryption has a</span>
|
|
37
|
+
<span className="flex items-end" style={{ minHeight: "1.15em" }}>
|
|
38
|
+
<RotatingText
|
|
39
|
+
texts={["deadline.", "countdown.", "expiry date.", "shelf life."]}
|
|
40
|
+
mainClassName="font-serif italic font-normal text-[var(--primary-300)] border-b-2 border-[var(--primary-400)]/70 pr-0.5"
|
|
41
|
+
splitLevelClassName="overflow-hidden pb-1.5"
|
|
42
|
+
staggerFrom="last"
|
|
43
|
+
initial={{ y: "100%", opacity: 0 }}
|
|
44
|
+
animate={{ y: 0, opacity: 1 }}
|
|
45
|
+
exit={{ y: "-120%", opacity: 0 }}
|
|
46
|
+
staggerDuration={0.02}
|
|
47
|
+
transition={{ type: "spring", damping: 30, stiffness: 360 }}
|
|
48
|
+
rotationInterval={2400}
|
|
49
|
+
splitBy="characters"
|
|
50
|
+
auto
|
|
51
|
+
loop
|
|
52
|
+
/>
|
|
53
|
+
</span>
|
|
54
|
+
</h1>
|
|
55
|
+
|
|
56
|
+
{/* Subtitle + CTAs row */}
|
|
57
|
+
<div className="mt-6 flex flex-col gap-5 md:flex-row md:items-center md:justify-between">
|
|
58
|
+
<p className="text-white/65 leading-[1.6]"
|
|
59
|
+
style={{ fontSize: "clamp(0.95rem, 1vw + 0.3rem, 1.15rem)", maxWidth: "46ch" }}>
|
|
60
|
+
Harvest-now, decrypt-later is already underway. Scan your stack,
|
|
61
|
+
diagnose what's quantum-vulnerable, and verify your readiness — for certain.
|
|
62
|
+
</p>
|
|
63
|
+
<div className="flex flex-wrap items-center gap-3 shrink-0">
|
|
64
|
+
<Button asChild
|
|
65
|
+
className="rounded-full bg-[var(--primary-500)] text-[var(--primary-foreground)] hover:bg-[var(--primary-400)] font-semibold h-10 px-6 text-[14px]"
|
|
66
|
+
>
|
|
67
|
+
<Link href="#pilot">Run a Free Scan</Link>
|
|
68
|
+
</Button>
|
|
69
|
+
<Button asChild variant="outline"
|
|
70
|
+
className="rounded-full border-white/25 text-white hover:bg-white/10 hover:border-white/40 h-10 px-6 text-[14px] bg-transparent"
|
|
71
|
+
>
|
|
72
|
+
<Link href="#offer">See How It Works</Link>
|
|
73
|
+
</Button>
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
{/* Large live console preview — sits at the bottom, bleeds off the frame edge */}
|
|
79
|
+
<div className="mt-8 sm:mt-10">
|
|
80
|
+
<ConsolePreview
|
|
81
|
+
className="w-full max-w-none mb-0"
|
|
82
|
+
height={620}
|
|
83
|
+
scale={0.82}
|
|
84
|
+
/>
|
|
85
|
+
</div>
|
|
86
|
+
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
)
|
|
92
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Check, X } from "lucide-react"
|
|
2
|
+
import { ScrambleText } from "@/components/scramble-text"
|
|
3
|
+
import { SectionBackdrop } from "@/components/section-backdrop"
|
|
4
|
+
import { FadeUp } from "@/components/fade-up"
|
|
5
|
+
|
|
6
|
+
const rows = [
|
|
7
|
+
{ cap: "Point-in-time assessment", bigCo: true, ours: true },
|
|
8
|
+
{ cap: "Automated, agentless scanning", bigCo: false, ours: true },
|
|
9
|
+
{ cap: "Continuous re-verification", bigCo: false, ours: true },
|
|
10
|
+
{ cap: "Verifiable readiness certificate", bigCo: false, ours: true },
|
|
11
|
+
{ cap: "Self-serve — no engagement fee", bigCo: false, ours: true },
|
|
12
|
+
{ cap: "Maps to RBI, CERT-In & US mandates", bigCo: false, ours: true },
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
export function MoatSection() {
|
|
16
|
+
return (
|
|
17
|
+
<section id="moat" className="relative min-h-screen md:h-screen flex flex-col justify-center md:overflow-hidden bg-[var(--gray-50)] border-b border-[var(--color-border)]">
|
|
18
|
+
<SectionBackdrop />
|
|
19
|
+
<div className="container-main relative z-10 py-6">
|
|
20
|
+
<div className="grid md:grid-cols-2 gap-12 items-center">
|
|
21
|
+
<FadeUp>
|
|
22
|
+
<div>
|
|
23
|
+
<ScrambleText text="Why continuous verification" className="eyebrow mb-3 block" />
|
|
24
|
+
<h2 className="font-bold leading-[1.1] tracking-tight text-[var(--color-text-primary)] mb-4"
|
|
25
|
+
style={{ fontSize: "clamp(1.5rem, 2vw + 0.5rem, 2.5rem)" }}>
|
|
26
|
+
Reports go stale.<br />
|
|
27
|
+
<span className="text-[var(--primary-500)]">Verification</span> doesn't.
|
|
28
|
+
</h2>
|
|
29
|
+
<p className="text-[14px] leading-[1.7] text-[var(--color-text-secondary)]">
|
|
30
|
+
A consultant's report is outdated the day they leave. The platform re-verifies continuously — your posture is always provable, not just promised.
|
|
31
|
+
</p>
|
|
32
|
+
</div>
|
|
33
|
+
</FadeUp>
|
|
34
|
+
|
|
35
|
+
<FadeUp delay={0.15}>
|
|
36
|
+
<div className="rounded-xl border border-[var(--color-border)] overflow-hidden shadow-sm">
|
|
37
|
+
{/* Header */}
|
|
38
|
+
<div className="grid grid-cols-[2fr_1fr_1fr] bg-[var(--gray-950)]">
|
|
39
|
+
{["Capability", "Big Consulting", "Your Company"].map((h, i) => (
|
|
40
|
+
<div key={h} className={`px-4 py-3 text-[11px] font-mono tracking-[0.1em] uppercase border-r border-white/10 last:border-r-0 ${
|
|
41
|
+
i === 2 ? "text-white bg-[var(--primary-500)]/20" : "text-white/60"
|
|
42
|
+
}`}>
|
|
43
|
+
{h}
|
|
44
|
+
</div>
|
|
45
|
+
))}
|
|
46
|
+
</div>
|
|
47
|
+
{/* Rows */}
|
|
48
|
+
{rows.map((r, idx) => (
|
|
49
|
+
<div key={r.cap} className={`grid grid-cols-[2fr_1fr_1fr] border-t border-[var(--color-border)] ${
|
|
50
|
+
idx % 2 === 0 ? "bg-white" : "bg-[var(--gray-50)]"
|
|
51
|
+
}`}>
|
|
52
|
+
<div className="px-4 py-3.5 text-[13px] text-[var(--color-text-primary)] border-r border-[var(--color-border)]">
|
|
53
|
+
{r.cap}
|
|
54
|
+
</div>
|
|
55
|
+
<div className="px-4 py-3.5 flex items-center justify-center border-r border-[var(--color-border)]">
|
|
56
|
+
{r.bigCo
|
|
57
|
+
? <Check size={16} className="text-[var(--deep-600)]" strokeWidth={3} />
|
|
58
|
+
: <X size={16} className="text-[var(--gray-400)]" strokeWidth={3} />}
|
|
59
|
+
</div>
|
|
60
|
+
<div className="px-4 py-3.5 flex items-center justify-center bg-[var(--deep-50)]/40">
|
|
61
|
+
<span className="flex items-center justify-center w-5 h-5 rounded-full bg-[var(--deep-600)]">
|
|
62
|
+
<Check size={12} className="text-white" strokeWidth={3.5} />
|
|
63
|
+
</span>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
))}
|
|
67
|
+
</div>
|
|
68
|
+
</FadeUp>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
</section>
|
|
72
|
+
)
|
|
73
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import Link from "next/link"
|
|
2
|
+
import { cn } from "@/lib/utils"
|
|
3
|
+
import { ScrambleText } from "@/components/scramble-text"
|
|
4
|
+
import { SectionBackdrop } from "@/components/section-backdrop"
|
|
5
|
+
import { CursorDrivenParticleTypography } from "@/components/ui/cursor-driven-particle-typography"
|
|
6
|
+
import { FadeUp, FadeUpGroup, FadeUpItem } from "@/components/fade-up"
|
|
7
|
+
|
|
8
|
+
const services = [
|
|
9
|
+
{
|
|
10
|
+
num: "01 — Scan",
|
|
11
|
+
particleText: "SCAN",
|
|
12
|
+
title: "Cryptographic Inventory",
|
|
13
|
+
desc: "Map every key, certificate, and cipher across your stack — agentless.",
|
|
14
|
+
cta: "See How Scanning Works",
|
|
15
|
+
href: "/assessment",
|
|
16
|
+
featured: false,
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
num: "02 — Diagnose",
|
|
20
|
+
particleText: "SCORE",
|
|
21
|
+
title: "Quantum Risk Scoring",
|
|
22
|
+
desc: "Every asset scored against NIST tiers and your data's shelf-life.",
|
|
23
|
+
cta: "Explore the Platform",
|
|
24
|
+
href: "/products",
|
|
25
|
+
featured: true,
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
num: "03 — Verify",
|
|
29
|
+
particleText: "VERIFY",
|
|
30
|
+
title: "Readiness Certification",
|
|
31
|
+
desc: "A verifiable, board-ready report — provable to regulators and auditors.",
|
|
32
|
+
cta: "View a Sample Report",
|
|
33
|
+
href: "/assessment",
|
|
34
|
+
featured: false,
|
|
35
|
+
},
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
export function OfferSection() {
|
|
39
|
+
return (
|
|
40
|
+
<section id="offer" className="relative min-h-screen md:h-screen flex flex-col justify-center md:overflow-hidden border-b border-[var(--color-border)] bg-white">
|
|
41
|
+
<SectionBackdrop />
|
|
42
|
+
<div className="container-main relative z-10 py-6">
|
|
43
|
+
<FadeUp className="mb-8">
|
|
44
|
+
<ScrambleText text="How It Works" className="eyebrow mb-2 block" />
|
|
45
|
+
<h2 className="font-bold leading-[1.1] tracking-tight text-[var(--color-text-primary)]"
|
|
46
|
+
style={{ fontSize: "clamp(1.5rem, 2vw + 0.5rem, 2.5rem)" }}>
|
|
47
|
+
Scan. <span className="text-[var(--primary-500)]">Diagnose.</span> Verify.
|
|
48
|
+
</h2>
|
|
49
|
+
</FadeUp>
|
|
50
|
+
|
|
51
|
+
<FadeUpGroup className="grid md:grid-cols-3 gap-4">
|
|
52
|
+
{services.map((s) => (
|
|
53
|
+
<FadeUpItem key={s.num}>
|
|
54
|
+
<Link
|
|
55
|
+
href={s.href}
|
|
56
|
+
className={cn(
|
|
57
|
+
"group flex flex-col rounded-xl border no-underline transition-all duration-200 overflow-hidden",
|
|
58
|
+
s.featured
|
|
59
|
+
? "bg-[var(--deep-900)] border-[var(--deep-900)] text-white hover:bg-[var(--deep-800)]"
|
|
60
|
+
: "bg-white border-[var(--color-border)] hover:border-[var(--color-border-strong)] hover:shadow-md"
|
|
61
|
+
)}
|
|
62
|
+
>
|
|
63
|
+
{/* Visual header */}
|
|
64
|
+
<div className={cn(
|
|
65
|
+
"w-full relative",
|
|
66
|
+
s.featured ? "bg-[var(--deep-900)]" : "bg-white"
|
|
67
|
+
)}>
|
|
68
|
+
<CursorDrivenParticleTypography
|
|
69
|
+
text={s.particleText!}
|
|
70
|
+
fontSize={55}
|
|
71
|
+
particleSize={2}
|
|
72
|
+
particleDensity={4}
|
|
73
|
+
dispersionStrength={0}
|
|
74
|
+
color={s.featured ? "rgb(196,146,58)" : "rgb(160,110,30)"}
|
|
75
|
+
className="!min-h-[160px]"
|
|
76
|
+
/>
|
|
77
|
+
</div>
|
|
78
|
+
|
|
79
|
+
{/* Card content */}
|
|
80
|
+
<div className="p-6 flex flex-col flex-1">
|
|
81
|
+
<div className={cn(
|
|
82
|
+
"font-mono text-[10px] tracking-[0.14em] uppercase font-semibold mb-3",
|
|
83
|
+
s.featured ? "text-[var(--primary-400)]" : "text-[var(--primary-500)]"
|
|
84
|
+
)}>
|
|
85
|
+
{s.num}
|
|
86
|
+
</div>
|
|
87
|
+
<h3 className={cn(
|
|
88
|
+
"text-[17px] font-bold mb-2 leading-tight tracking-tight",
|
|
89
|
+
s.featured ? "text-white" : "text-[var(--color-text-primary)]"
|
|
90
|
+
)}>
|
|
91
|
+
{s.title}
|
|
92
|
+
</h3>
|
|
93
|
+
<p className={cn(
|
|
94
|
+
"text-[13px] leading-[1.6] mb-4 flex-1",
|
|
95
|
+
s.featured ? "text-white/60" : "text-[var(--color-text-secondary)]"
|
|
96
|
+
)}>
|
|
97
|
+
{s.desc}
|
|
98
|
+
</p>
|
|
99
|
+
<div className={cn(
|
|
100
|
+
"font-mono text-[11px] font-semibold tracking-[0.1em] uppercase mt-auto",
|
|
101
|
+
s.featured ? "text-[var(--primary-400)]" : "text-[var(--primary-500)]"
|
|
102
|
+
)}>
|
|
103
|
+
{s.cta} →
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
</Link>
|
|
107
|
+
</FadeUpItem>
|
|
108
|
+
))}
|
|
109
|
+
</FadeUpGroup>
|
|
110
|
+
</div>
|
|
111
|
+
</section>
|
|
112
|
+
)
|
|
113
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import Link from "next/link"
|
|
2
|
+
import { Button } from "@/components/ui/button"
|
|
3
|
+
import { LatticeField } from "@/components/lattice-field"
|
|
4
|
+
import { ScrambleText } from "@/components/scramble-text"
|
|
5
|
+
import { FadeUp, FadeUpGroup, FadeUpItem } from "@/components/fade-up"
|
|
6
|
+
|
|
7
|
+
const phases = [
|
|
8
|
+
{ n: "1", title: "Connect & Scan", body: "Agentless inventory across your full stack.", time: "Week 1–2" },
|
|
9
|
+
{ n: "2", title: "Diagnose & Score", body: "Every asset rated against NIST tiers.", time: "Week 3–4" },
|
|
10
|
+
{ n: "3", title: "Prioritized Roadmap", body: "Highest-risk gaps, sequenced to fix first.", time: "Week 5–6" },
|
|
11
|
+
{ n: "4", title: "Verified Report", body: "Board-ready, re-verifiable readiness certificate.", time: "Week 7–8" },
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
export function PilotSection() {
|
|
15
|
+
return (
|
|
16
|
+
<section id="pilot" className="min-h-screen md:h-screen flex flex-col justify-center md:overflow-hidden bg-[var(--deep-900)] text-white relative border-b border-white/10">
|
|
17
|
+
<LatticeField className="opacity-35" />
|
|
18
|
+
|
|
19
|
+
<div className="container-main relative z-10 py-6">
|
|
20
|
+
<div className="grid md:grid-cols-2 gap-12 items-center">
|
|
21
|
+
<FadeUp>
|
|
22
|
+
<div>
|
|
23
|
+
<ScrambleText text="Low Risk Entry" className="eyebrow mb-3 text-[var(--primary-400)] block" />
|
|
24
|
+
<h2 className="font-bold leading-[1.1] tracking-tight text-white mb-4"
|
|
25
|
+
style={{ fontSize: "clamp(1.5rem, 2vw + 0.5rem, 2.5rem)" }}>
|
|
26
|
+
From scan to{" "}
|
|
27
|
+
<span className="text-[var(--primary-400)]">verified</span>
|
|
28
|
+
{" "}in 8 weeks.
|
|
29
|
+
</h2>
|
|
30
|
+
<p className="text-[14px] leading-[1.7] text-white/60 mb-7">
|
|
31
|
+
Fixed scope. No long-term commitment.
|
|
32
|
+
</p>
|
|
33
|
+
<Button asChild
|
|
34
|
+
className="rounded-full bg-[var(--primary-500)] text-[var(--gray-950)] hover:bg-[var(--primary-400)] font-semibold h-10 px-6"
|
|
35
|
+
>
|
|
36
|
+
<Link href="#contact">Start Your Pilot</Link>
|
|
37
|
+
</Button>
|
|
38
|
+
</div>
|
|
39
|
+
</FadeUp>
|
|
40
|
+
|
|
41
|
+
<FadeUpGroup className="rounded-xl border border-white/10 overflow-hidden divide-y divide-white/10">
|
|
42
|
+
{phases.map((p) => (
|
|
43
|
+
<FadeUpItem key={p.n}>
|
|
44
|
+
<div className="bg-white/5 hover:bg-white/10 transition-colors px-6 py-5 flex gap-4 items-start">
|
|
45
|
+
<span className="text-[24px] font-bold text-[var(--primary-400)] leading-none w-7 shrink-0">
|
|
46
|
+
{p.n}
|
|
47
|
+
</span>
|
|
48
|
+
<div className="flex-1 min-w-0">
|
|
49
|
+
<h4 className="text-[13px] font-semibold text-white mb-1">{p.title}</h4>
|
|
50
|
+
<p className="text-[12px] text-white/55 leading-[1.6]">{p.body}</p>
|
|
51
|
+
</div>
|
|
52
|
+
<span className="font-mono text-[10px] tracking-[0.1em] text-[var(--primary-500)] shrink-0 pt-0.5">
|
|
53
|
+
{p.time}
|
|
54
|
+
</span>
|
|
55
|
+
</div>
|
|
56
|
+
</FadeUpItem>
|
|
57
|
+
))}
|
|
58
|
+
</FadeUpGroup>
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
</section>
|
|
62
|
+
)
|
|
63
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { LatticeField } from "@/components/lattice-field"
|
|
2
|
+
import { ScrambleText } from "@/components/scramble-text"
|
|
3
|
+
import { FadeUp, FadeUpGroup, FadeUpItem } from "@/components/fade-up"
|
|
4
|
+
|
|
5
|
+
const problems = [
|
|
6
|
+
{
|
|
7
|
+
title: "Your data is being stolen now.",
|
|
8
|
+
body: "Adversaries capture encrypted traffic today to crack the moment quantum hardware lands.",
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
title: "You don't know what's exposed.",
|
|
12
|
+
body: "Most organizations can't name every key, certificate, and cipher in their stack.",
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
title: "Regulators aren't waiting.",
|
|
16
|
+
body: "NIST standards are final. Compliance mandates are live. The clock is already running.",
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
title: "Saying it isn't proving it.",
|
|
20
|
+
body: "Boards and auditors need verifiable evidence — not a consultant's slide deck.",
|
|
21
|
+
},
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
export function ProblemSection() {
|
|
25
|
+
return (
|
|
26
|
+
<section id="problem" className="min-h-screen md:h-screen flex flex-col justify-center md:overflow-hidden relative bg-[var(--gray-950)] text-white">
|
|
27
|
+
<LatticeField className="opacity-40" />
|
|
28
|
+
<div className="container-main relative z-10 py-6">
|
|
29
|
+
<FadeUp className="mb-10">
|
|
30
|
+
<ScrambleText text="The Problem" className="eyebrow mb-3 text-[var(--primary-400)] block" />
|
|
31
|
+
<h2 className="text-white font-bold leading-[1.1] tracking-tight"
|
|
32
|
+
style={{ fontSize: "clamp(1.75rem, 2.5vw + 0.5rem, 3rem)" }}>
|
|
33
|
+
You're exposed.<br />
|
|
34
|
+
<span className="text-[var(--primary-400)]">You just don't know it.</span>
|
|
35
|
+
</h2>
|
|
36
|
+
</FadeUp>
|
|
37
|
+
<FadeUpGroup className="grid sm:grid-cols-2 md:grid-cols-4 gap-3">
|
|
38
|
+
{problems.map((p) => (
|
|
39
|
+
<FadeUpItem key={p.title}>
|
|
40
|
+
<div className="rounded-xl border border-white/10 bg-[var(--deep-950)] p-6 hover:border-white/20 hover:bg-white/[0.03] transition-colors h-full flex flex-col gap-3">
|
|
41
|
+
<h3 className="text-white font-bold leading-[1.25] tracking-tight"
|
|
42
|
+
style={{ fontSize: "clamp(1rem, 1.1vw + 0.3rem, 1.2rem)" }}>
|
|
43
|
+
{p.title}
|
|
44
|
+
</h3>
|
|
45
|
+
<p className="text-[13px] text-white/50 leading-[1.65]">{p.body}</p>
|
|
46
|
+
</div>
|
|
47
|
+
</FadeUpItem>
|
|
48
|
+
))}
|
|
49
|
+
</FadeUpGroup>
|
|
50
|
+
</div>
|
|
51
|
+
</section>
|
|
52
|
+
)
|
|
53
|
+
}
|