create-frootkit 1.2.11 → 1.2.13

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.
Files changed (37) hide show
  1. package/package.json +1 -1
  2. package/templates/auth/src/app/dashboard/layout.tsx +8 -11
  3. package/templates/auth/src/app/dashboard/page.tsx +31 -27
  4. package/templates/auth/src/app/layout.tsx +5 -5
  5. package/templates/auth/src/app/login/page.tsx +11 -4
  6. package/templates/auth/src/app/page.tsx +278 -120
  7. package/templates/auth/src/app/signup/page.tsx +12 -6
  8. package/templates/auth/src/components/AuthForm.tsx +27 -34
  9. package/templates/auth/src/components/DashboardNav.tsx +41 -61
  10. package/templates/auth/src/components/MetricCard.tsx +12 -22
  11. package/templates/auth/src/components/Navbar.tsx +18 -21
  12. package/templates/auth/src/styles.css +157 -27
  13. package/templates/blog/src/app/blog/[slug]/page.tsx +85 -46
  14. package/templates/blog/src/app/layout.tsx +5 -5
  15. package/templates/blog/src/app/page.tsx +39 -26
  16. package/templates/blog/src/components/Footer.tsx +11 -9
  17. package/templates/blog/src/components/Navbar.tsx +21 -26
  18. package/templates/blog/src/components/Newsletter.tsx +11 -33
  19. package/templates/blog/src/components/PostCard.tsx +43 -76
  20. package/templates/blog/src/styles.css +113 -25
  21. package/templates/ecommerce/README.md +1 -0
  22. package/templates/ecommerce/src/app/cart/page.tsx +12 -4
  23. package/templates/ecommerce/src/app/layout.tsx +5 -5
  24. package/templates/ecommerce/src/app/page.tsx +92 -37
  25. package/templates/ecommerce/src/app/products/[id]/page.tsx +39 -31
  26. package/templates/ecommerce/src/components/CartDrawer.tsx +113 -45
  27. package/templates/ecommerce/src/components/Footer.tsx +11 -9
  28. package/templates/ecommerce/src/components/Navbar.tsx +32 -34
  29. package/templates/ecommerce/src/components/ProductCard.tsx +27 -38
  30. package/templates/ecommerce/src/styles.css +155 -36
  31. package/templates/starter/README.md +1 -0
  32. package/templates/starter/src/app/layout.tsx +5 -5
  33. package/templates/starter/src/app/page.tsx +114 -107
  34. package/templates/starter/src/components/FeatureCard.tsx +9 -15
  35. package/templates/starter/src/components/Footer.tsx +11 -9
  36. package/templates/starter/src/components/Header.tsx +15 -38
  37. package/templates/starter/src/styles.css +102 -27
@@ -1,156 +1,314 @@
1
1
  import { Navbar } from '../components/Navbar.js';
2
2
 
3
3
  export const metadata = {
4
- title: 'FrootAuth — Web Crypto Authentication & Dashboard',
5
- description: 'Pure Web Crypto PBKDF2 password hashing and secure session management for FrootKit.',
4
+ title: 'FrootAuth — Authentication & Revenue Infrastructure',
5
+ description: 'Pure Web Crypto PBKDF2 authentication, subscription billing, and real-time dashboard telemetry.',
6
6
  };
7
7
 
8
8
  export default function SaaSMarketingPage() {
9
+ const features = [
10
+ {
11
+ title: 'Subscriptions',
12
+ desc: 'Flat, tiered or per-seat plans with trials, coupons and prorated upgrades.',
13
+ icon: 'M4 12a8 8 0 0 1 14-5M20 12a8 8 0 0 1-14 5M18 3v4h-4M6 21v-4h4',
14
+ },
15
+ {
16
+ title: 'Usage-based billing',
17
+ desc: 'Meter API calls or compute cycles and bill exactly what customers used.',
18
+ icon: 'M4 20V10M10 20V4M16 20v-7M22 20H2',
19
+ },
20
+ {
21
+ title: 'Smart retries',
22
+ desc: 'Failed cards retry at the best time, and customers get a link to update them.',
23
+ icon: 'M3 12a9 9 0 1 0 3-6.7M3 4v5h5',
24
+ },
25
+ {
26
+ title: 'Invoicing',
27
+ desc: 'Branded PDF invoices with payment links, reminders and automatic numbering.',
28
+ icon: 'M6 3h9l4 4v14H6zM14 3v5h5M9 13h6M9 17h6',
29
+ },
30
+ {
31
+ title: 'Tax and compliance',
32
+ desc: 'Calculate sales tax and VAT at checkout and file reports in one click.',
33
+ icon: 'M5 19 19 5M7 8h.01M17 16h.01',
34
+ },
35
+ {
36
+ title: 'Reconciliation',
37
+ desc: 'Match every payout to the payments inside it and export to your ledger.',
38
+ icon: 'M4 7h16M4 12h16M4 17h10',
39
+ },
40
+ ];
41
+
42
+ const plans = [
43
+ {
44
+ name: 'Starter',
45
+ price: 0,
46
+ desc: 'For side projects and first customers.',
47
+ features: ['2.9% + 30¢ per payment', 'Up to $10k monthly volume', 'Email support'],
48
+ popular: false,
49
+ },
50
+ {
51
+ name: 'Growth',
52
+ price: 49,
53
+ desc: 'For teams with recurring revenue.',
54
+ features: ['2.4% + 30¢ per payment', 'Smart retries and dunning', 'Usage-based billing', 'Tax calculation'],
55
+ popular: true,
56
+ },
57
+ {
58
+ name: 'Scale',
59
+ price: 199,
60
+ desc: 'For finance teams at volume.',
61
+ features: ['Custom volume pricing', 'Revenue recognition', 'SSO and audit logs', 'Dedicated manager'],
62
+ popular: false,
63
+ },
64
+ ];
65
+
9
66
  return (
10
- <div class="min-h-screen bg-[#08090a] text-zinc-100 flex flex-col justify-between selection:bg-indigo-500/20 selection:text-indigo-300">
67
+ <div class="bg-white font-sans text-[#425466]">
11
68
  <Navbar />
12
69
 
13
- <main class="max-w-6xl mx-auto px-6 py-16 sm:py-24 flex-1 flex flex-col justify-center w-full">
14
- <div class="grid grid-cols-1 lg:grid-cols-12 gap-12 lg:gap-16 items-center">
15
- {/* Left Column (7 cols) */}
16
- <div class="lg:col-span-7">
17
- <div class="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-indigo-500/10 border border-indigo-500/20 text-indigo-400 text-xs font-medium mb-6">
18
- <span class="w-1.5 h-1.5 rounded-full bg-indigo-400 animate-pulse" />
19
- <span>Pure Web Crypto Architecture</span>
70
+ {/* HERO SECTION */}
71
+ <section class="hero relative pb-44 pt-32 text-white md:pb-56">
72
+ <div class="mx-auto max-w-6xl px-6 grid items-center gap-14 lg:grid-cols-[1fr_1.05fr]">
73
+ <div class="rise">
74
+ <span class="bd bg-white/15 text-white">New: usage-based billing is live</span>
75
+ <h1 class="mt-5 text-[42px] font-light leading-[1.08] tracking-tight md:text-[56px] md:leading-[64px]">
76
+ Billing that keeps up with your revenue
77
+ </h1>
78
+ <p class="mt-6 max-w-md text-[18px] font-light leading-7 text-white/90">
79
+ Charge for subscriptions, usage, and one-off invoices from one unified system. Failed payments retry on their own, and every dollar reconciles to your bank.
80
+ </p>
81
+ <div class="mt-8 flex flex-wrap gap-3">
82
+ <a href="/signup" class="btn btn-w">Start free</a>
83
+ <a href="/dashboard" class="btn btn-gl">View Dashboard</a>
20
84
  </div>
85
+ <p class="mt-4 text-[13px] text-white/75">
86
+ No card needed. Free up to $10k in monthly volume. Demo: <code class="font-mono bg-white/10 px-1.5 py-0.5 rounded">admin@frootkit.dev</code>
87
+ </p>
88
+ </div>
21
89
 
22
- <h1 class="text-4xl sm:text-5xl lg:text-6xl font-semibold text-white tracking-[-0.03em] leading-[1.1] mb-6">
23
- Fullstack Authentication & Administration.
24
- </h1>
90
+ {/* Interactive Hero Dashboard Mock */}
91
+ <div class="rise relative [animation-delay:.15s]">
92
+ <div class="overflow-hidden rounded-lg bg-white text-[#425466] shadow-[0_13px_27px_-5px_rgba(50,50,93,0.25),0_8px_16px_-8px_rgba(0,0,0,0.3)]">
93
+ <div class="flex items-center gap-1.5 border-b border-[#e6ebf1] bg-[#f6f9fc] px-4 py-2.5">
94
+ <i class="h-2.5 w-2.5 rounded-full bg-[#e6ebf1]" />
95
+ <i class="h-2.5 w-2.5 rounded-full bg-[#e6ebf1]" />
96
+ <i class="h-2.5 w-2.5 rounded-full bg-[#e6ebf1]" />
97
+ <span class="ml-3 font-mono text-[12px] text-[#425466]">dashboard.frootauth.com</span>
98
+ </div>
99
+ <div class="p-5">
100
+ <div class="flex items-end justify-between">
101
+ <div>
102
+ <p class="text-[13px] text-[#425466]">Net volume · last 30 days</p>
103
+ <p class="font-mono text-[30px] font-light text-[#0a2540]">$482,190.40</p>
104
+ </div>
105
+ <span class="bd bg-[#24b47e]/15 text-[#0e6245]">+18.2%</span>
106
+ </div>
25
107
 
26
- <p class="text-base sm:text-lg text-zinc-400 leading-relaxed mb-8 max-w-xl">
27
- Zero external C++ dependencies. Real PBKDF2 password hashing (100,000 iterations), cryptographically random session tokens, protected layouts, and high-density telemetry.
28
- </p>
108
+ <svg viewBox="0 0 300 90" class="mt-3 h-24 w-full">
109
+ <defs>
110
+ <linearGradient id="g" x1="0" y1="0" x2="0" y2="1">
111
+ <stop offset="0" stop-color="#635bff" stop-opacity=".25" />
112
+ <stop offset="1" stop-color="#635bff" stop-opacity="0" />
113
+ </linearGradient>
114
+ </defs>
115
+ <path d="M0 70 C30 66 40 50 70 54 S120 30 150 36 S210 18 240 22 S285 8 300 6 V90 H0Z" fill="url(#g)" />
116
+ <path d="M0 70 C30 66 40 50 70 54 S120 30 150 36 S210 18 240 22 S285 8 300 6" fill="none" stroke="#635bff" stroke-width="2.5" stroke-linecap="round" />
117
+ </svg>
29
118
 
30
- <div class="flex flex-wrap items-center gap-3.5 mb-8">
31
- <a
32
- href="/signup"
33
- class="px-4 py-2.5 rounded-lg bg-white text-zinc-950 font-medium hover:bg-zinc-200 transition-all text-sm shadow-sm flex items-center gap-2 group"
34
- >
35
- <span>Create Account</span>
36
- <span class="text-zinc-500 group-hover:translate-x-0.5 transition-transform">→</span>
37
- </a>
38
- <a
39
- href="/dashboard"
40
- class="px-4 py-2.5 rounded-lg bg-white/[0.04] border border-white/[0.08] text-zinc-300 font-medium hover:bg-white/[0.08] hover:text-white transition-all text-sm"
41
- >
42
- Open Dashboard
43
- </a>
119
+ <div class="mt-3 divide-y divide-[#e6ebf1] text-[14px]">
120
+ <div class="flex items-center justify-between py-2">
121
+ <span class="font-medium text-[#0a2540]">Northwind Traders</span>
122
+ <span class="flex items-center gap-3">
123
+ <span class="font-mono">$1,240.00</span>
124
+ <span class="bd bg-[#24b47e]/15 text-[#0e6245]">Paid</span>
125
+ </span>
126
+ </div>
127
+ <div class="flex items-center justify-between py-2">
128
+ <span class="font-medium text-[#0a2540]">Kestrel Labs</span>
129
+ <span class="flex items-center gap-3">
130
+ <span class="font-mono">$89.50</span>
131
+ <span class="bd bg-[#cd3d64]/10 text-[#cd3d64]">Retrying</span>
132
+ </span>
133
+ </div>
134
+ <div class="flex items-center justify-between py-2">
135
+ <span class="font-medium text-[#0a2540]">Orbit Studio</span>
136
+ <span class="flex items-center gap-3">
137
+ <span class="font-mono">$2,150.00</span>
138
+ <span class="bd bg-[#24b47e]/15 text-[#0e6245]">Paid</span>
139
+ </span>
140
+ </div>
141
+ </div>
142
+ </div>
44
143
  </div>
45
144
 
46
- <div class="inline-flex items-center gap-2.5 px-3 py-1.5 rounded-md bg-white/[0.03] border border-white/[0.06] text-xs text-zinc-400">
47
- <span class="w-2 h-2 rounded-full bg-emerald-400" />
48
- <span>Demo Account ready:</span>
49
- <code class="text-zinc-200 font-mono text-[11px] bg-white/[0.04] px-1.5 py-0.5 rounded">admin@frootkit.dev</code>
50
- <span class="text-zinc-600">/</span>
51
- <code class="text-zinc-200 font-mono text-[11px] bg-white/[0.04] px-1.5 py-0.5 rounded">password123</code>
145
+ {/* Floating Recovery Notification */}
146
+ <div class="absolute -bottom-10 -left-4 hidden w-60 rounded-lg bg-white p-4 text-[13px] shadow-[0_13px_27px_-5px_rgba(50,50,93,0.25),0_8px_16px_-8px_rgba(0,0,0,0.3)] sm:block md:-left-10 text-[#425466]">
147
+ <p class="font-medium text-[#0a2540]">Payment recovered</p>
148
+ <p>Kestrel Labs paid on retry 2 of 4. Recovered $89.50.</p>
52
149
  </div>
53
150
  </div>
151
+ </div>
152
+ </section>
54
153
 
55
- {/* Right Column: Linear-Grade Security Inspector Card (5 cols) */}
56
- <div class="lg:col-span-5">
57
- <div class="rounded-xl border border-white/[0.08] bg-[#0f1117] p-6 shadow-2xl shadow-black/40 relative overflow-hidden">
58
- {/* Subtle top edge highlight */}
59
- <div class="absolute inset-x-0 top-0 h-px bg-gradient-to-r from-transparent via-indigo-500/40 to-transparent" />
154
+ {/* STATS SECTION */}
155
+ <section class="bg-[#f6f9fc] py-14">
156
+ <div class="mx-auto max-w-6xl px-6 grid gap-8 text-center sm:grid-cols-3">
157
+ <div>
158
+ <p class="font-mono text-[40px] font-light text-[#0a2540]">99.99%</p>
159
+ <p class="text-[14px]">API uptime over the last 12 months</p>
160
+ </div>
161
+ <div>
162
+ <p class="font-mono text-[40px] font-light text-[#0a2540]">+11%</p>
163
+ <p class="text-[14px]">Average revenue recovered from failed payments</p>
164
+ </div>
165
+ <div>
166
+ <p class="font-mono text-[40px] font-light text-[#0a2540]">0.42ms</p>
167
+ <p class="text-[14px]">P99 server-side dispatch latency</p>
168
+ </div>
169
+ </div>
170
+ </section>
60
171
 
61
- <div class="flex items-center justify-between pb-4 border-b border-white/[0.06] mb-5">
62
- <div class="flex items-center gap-2">
63
- <div class="w-2 h-2 rounded-full bg-emerald-400" />
64
- <span class="text-xs font-medium text-zinc-300">Security Subsystem</span>
65
- </div>
66
- <span class="text-[11px] text-indigo-400 font-medium px-2 py-0.5 rounded-full bg-indigo-500/10 border border-indigo-500/20">
67
- SubtleCrypto Active
172
+ {/* FEATURES SECTION */}
173
+ <section id="features" class="scroll-mt-16 py-24">
174
+ <div class="mx-auto max-w-6xl px-6">
175
+ <h2 class="text-[32px] font-light leading-[1.15] tracking-tight text-[#0a2540] md:text-[40px] max-w-2xl">
176
+ One system for every way you get paid
177
+ </h2>
178
+ <p class="mt-4 max-w-xl text-[17px] leading-7">
179
+ Start with simple subscriptions and add usage, invoicing, and tax as you grow, without changing your integration.
180
+ </p>
181
+ <div class="mt-12 grid gap-5 md:grid-cols-3">
182
+ {features.map((f) => (
183
+ <div
184
+ key={f.title}
185
+ class="rounded-lg border border-[#e6ebf1] bg-white p-6 shadow-[0_2px_5px_-1px_rgba(50,50,93,0.25),0_1px_3px_-1px_rgba(0,0,0,0.3)] transition hover:-translate-y-0.5 hover:shadow-[0_13px_27px_-5px_rgba(50,50,93,0.25),0_8px_16px_-8px_rgba(0,0,0,0.3)]"
186
+ >
187
+ <span class="grid h-10 w-10 place-items-center rounded-md bg-[#635bff]/10 text-[#635bff]">
188
+ <svg class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
189
+ <path d={f.icon} />
190
+ </svg>
68
191
  </span>
192
+ <h3 class="mt-4 text-[17px] font-medium text-[#0a2540]">{f.title}</h3>
193
+ <p class="mt-1 text-[14px] leading-relaxed">{f.desc}</p>
69
194
  </div>
195
+ ))}
196
+ </div>
197
+ </div>
198
+ </section>
70
199
 
71
- <div class="space-y-3.5 text-xs">
72
- <div class="flex justify-between items-center py-1">
73
- <span class="text-zinc-400">Algorithm</span>
74
- <span class="text-zinc-200 font-medium">PBKDF2-SHA256</span>
75
- </div>
76
- <div class="flex justify-between items-center py-1 border-t border-white/[0.04]">
77
- <span class="text-zinc-400">Iterations</span>
78
- <span class="text-zinc-200 font-medium tabular-nums">100,000 rounds</span>
79
- </div>
80
- <div class="flex justify-between items-center py-1 border-t border-white/[0.04]">
81
- <span class="text-zinc-400">Salt Length</span>
82
- <span class="text-zinc-200 font-medium tabular-nums">128-bit (16 bytes)</span>
83
- </div>
84
- <div class="flex justify-between items-center py-1 border-t border-white/[0.04]">
85
- <span class="text-zinc-400">Key Derivation</span>
86
- <span class="text-zinc-200 font-medium">256-bit SubtleCrypto</span>
87
- </div>
88
- <div class="flex justify-between items-center py-1 border-t border-white/[0.04]">
89
- <span class="text-zinc-400">Cookie Security</span>
90
- <span class="text-emerald-400 font-medium">HttpOnly; SameSite=Lax</span>
91
- </div>
92
- </div>
93
-
94
- <div class="mt-5 pt-4 border-t border-white/[0.06] flex justify-between items-center text-xs">
95
- <span class="text-zinc-500">Auth Route</span>
96
- <code class="text-indigo-400 font-mono text-[11px] bg-indigo-500/5 px-2 py-0.5 rounded border border-indigo-500/15">
97
- /api/auth?action=login
98
- </code>
99
- </div>
200
+ {/* DEVELOPERS SECTION */}
201
+ <section id="developers" class="scroll-mt-16 bg-[#0a2540] py-24 text-white">
202
+ <div class="mx-auto max-w-6xl px-6 grid items-center gap-12 lg:grid-cols-2">
203
+ <div>
204
+ <h2 class="text-[32px] font-light leading-[1.15] tracking-tight md:text-[40px]">
205
+ Built for developers, readable by finance
206
+ </h2>
207
+ <p class="mt-4 max-w-xl text-[17px] leading-7 text-white/75">
208
+ Create a customer, attach a plan, and bill them in a few lines. Every object has a test mode, so you can ship on day one.
209
+ </p>
210
+ <ul class="mt-6 space-y-2 text-[15px] text-white/90">
211
+ <li>• Idempotent requests and signed webhooks</li>
212
+ <li>• Pure Web Crypto PBKDF2 authentication</li>
213
+ <li>• A full sandbox with simulated test clocks</li>
214
+ </ul>
215
+ <a href="/dashboard" class="btn btn-w mt-8">Explore Dashboard</a>
216
+ </div>
217
+ <div class="overflow-hidden rounded-lg bg-[#06182b] shadow-[0_13px_27px_-5px_rgba(50,50,93,0.25),0_8px_16px_-8px_rgba(0,0,0,0.3)]">
218
+ <div class="flex gap-1 border-b border-white/10 px-3 pt-2">
219
+ <span class="rounded-t-md px-3 py-1.5 text-[13px] font-medium bg-[#0a2540] text-white">TypeScript</span>
100
220
  </div>
221
+ <pre class="overflow-x-auto p-5 font-mono text-[13px] leading-6 text-white/90">
222
+ <code>{`// Zero external C++ dependencies
223
+ import { hashPassword, verifyPassword } from '@/lib/auth.js';
224
+
225
+ // PBKDF2-SHA256 with 100,000 iterations
226
+ const salt = crypto.getRandomValues(new Uint8Array(16));
227
+ const hash = await hashPassword('password123', salt);
228
+
229
+ // Verified in pure Web Crypto
230
+ const isValid = await verifyPassword('password123', salt, hash);`}</code>
231
+ </pre>
101
232
  </div>
102
233
  </div>
234
+ </section>
103
235
 
104
- {/* Feature Grid Below */}
105
- <div class="mt-20 pt-12 border-t border-white/[0.06] grid grid-cols-1 md:grid-cols-3 gap-6">
106
- <div class="p-5 rounded-lg border border-white/[0.06] bg-white/[0.02]">
107
- <div class="w-8 h-8 rounded-md bg-indigo-500/10 border border-indigo-500/20 flex items-center justify-center text-indigo-400 mb-3">
108
- <svg style="width: 16px; height: 16px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
109
- <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" />
110
- </svg>
111
- </div>
112
- <h3 class="text-sm font-semibold text-zinc-100 mb-1">Standard Web Crypto</h3>
113
- <p class="text-xs text-zinc-400 leading-relaxed">
114
- Native PBKDF2 key derivation using the Web Cryptography API. Zero C++ native rebuilds across any architecture.
236
+ {/* PRICING SECTION */}
237
+ <section id="pricing" class="scroll-mt-16 py-24">
238
+ <div class="mx-auto max-w-6xl px-6">
239
+ <div class="text-center">
240
+ <h2 class="text-[32px] font-light leading-[1.15] tracking-tight text-[#0a2540] md:text-[40px]">
241
+ Pricing that scales with you
242
+ </h2>
243
+ <p class="mx-auto mt-4 max-w-md text-[17px]">
244
+ Pay a percentage of volume you process. No setup fees, no monthly minimums.
115
245
  </p>
116
246
  </div>
117
247
 
118
- <div class="p-5 rounded-lg border border-white/[0.06] bg-white/[0.02]">
119
- <div class="w-8 h-8 rounded-md bg-indigo-500/10 border border-indigo-500/20 flex items-center justify-center text-indigo-400 mb-3">
120
- <svg style="width: 16px; height: 16px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
121
- <rect x="3" y="3" width="18" height="18" rx="2" ry="2" />
122
- <line x1="9" y1="3" x2="9" y2="21" />
123
- </svg>
124
- </div>
125
- <h3 class="text-sm font-semibold text-zinc-100 mb-1">Protected Layouts</h3>
126
- <p class="text-xs text-zinc-400 leading-relaxed">
127
- Deterministic server-side session checks in nested Preact layout trees with instant redirect fallbacks.
128
- </p>
248
+ <div class="mt-12 grid items-stretch gap-6 md:grid-cols-3">
249
+ {plans.map((p) => (
250
+ <div
251
+ key={p.name}
252
+ class={`flex flex-col rounded-lg bg-white p-7 ${
253
+ p.popular
254
+ ? 'border-2 border-[#635bff] shadow-[0_13px_27px_-5px_rgba(50,50,93,0.25),0_8px_16px_-8px_rgba(0,0,0,0.3)]'
255
+ : 'border border-[#e6ebf1] shadow-[0_2px_5px_-1px_rgba(50,50,93,0.25),0_1px_3px_-1px_rgba(0,0,0,0.3)]'
256
+ }`}
257
+ >
258
+ <div class="flex items-center justify-between">
259
+ <h3 class="text-[18px] font-medium text-[#0a2540]">{p.name}</h3>
260
+ {p.popular && <span class="bd bg-[#635bff]/10 text-[#635bff]">Most popular</span>}
261
+ </div>
262
+ <p class="mt-1 text-[14px]">{p.desc}</p>
263
+ <p class="mt-5 text-[#0a2540]">
264
+ <span class="text-[44px] font-light">${p.price}</span>
265
+ <span class="text-[14px] text-[#425466]"> /month</span>
266
+ </p>
267
+ <ul class="my-6 flex-1 space-y-2.5 text-[14px]">
268
+ {p.features.map((feat) => (
269
+ <li key={feat} class="flex gap-2">
270
+ <svg class="mt-0.5 h-4 w-4 shrink-0 text-[#24b47e]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3">
271
+ <path d="m5 12 5 5 9-10" stroke-linecap="round" stroke-linejoin="round" />
272
+ </svg>
273
+ {feat}
274
+ </li>
275
+ ))}
276
+ </ul>
277
+ <a href="/signup" class={`btn ${p.popular ? 'btn-p' : 'btn-o'} w-full`}>
278
+ {p.price ? `Choose ${p.name}` : 'Start free'}
279
+ </a>
280
+ </div>
281
+ ))}
129
282
  </div>
283
+ </div>
284
+ </section>
130
285
 
131
- <div class="p-5 rounded-lg border border-white/[0.06] bg-white/[0.02]">
132
- <div class="w-8 h-8 rounded-md bg-indigo-500/10 border border-indigo-500/20 flex items-center justify-center text-indigo-400 mb-3">
133
- <svg style="width: 16px; height: 16px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
134
- <line x1="18" y1="20" x2="18" y2="10" />
135
- <line x1="12" y1="20" x2="12" y2="4" />
136
- <line x1="6" y1="20" x2="6" y2="14" />
137
- </svg>
138
- </div>
139
- <h3 class="text-sm font-semibold text-zinc-100 mb-1">SQLite Session Cache</h3>
140
- <p class="text-xs text-zinc-400 leading-relaxed">
141
- Local persistent storage with sub-millisecond lookup latency, automatic expiry purging, and single-file portability.
286
+ {/* FOOTER */}
287
+ <footer class="border-t border-[#e6ebf1] bg-[#f6f9fc] py-14 text-[14px]">
288
+ <div class="mx-auto max-w-6xl px-6 flex flex-wrap justify-between gap-6">
289
+ <div>
290
+ <p class="text-[20px] font-semibold tracking-tight text-[#635bff]">frootauth</p>
291
+ <p class="mt-2 max-w-xs text-xs text-[#425466]">
292
+ Stripe-inspired authentication and billing infrastructure powered by Preact & FrootKit.
142
293
  </p>
143
294
  </div>
144
- </div>
145
- </main>
146
-
147
- <footer class="border-t border-white/[0.06] bg-[#08090a] py-6 text-xs text-zinc-500">
148
- <div class="max-w-6xl mx-auto px-6 flex flex-col sm:flex-row items-center justify-between gap-4">
149
- <div>FrootAuth © {new Date().getFullYear()} OrbitNorth LLC. Built with FrootKit.</div>
150
- <div class="flex gap-5">
151
- <a href="/login" class="hover:text-zinc-300 transition-colors">Sign In</a>
152
- <a href="/signup" class="hover:text-zinc-300 transition-colors">Sign Up</a>
153
- <a href="/dashboard" class="hover:text-zinc-300 transition-colors">Dashboard</a>
295
+ <div class="flex gap-12">
296
+ <div>
297
+ <p class="mb-3 font-medium text-[#0a2540]">Product</p>
298
+ <ul class="space-y-2 text-xs">
299
+ <li><a href="#features" class="hover:text-[#635bff]">Billing</a></li>
300
+ <li><a href="#features" class="hover:text-[#635bff]">Invoicing</a></li>
301
+ <li><a href="#pricing" class="hover:text-[#635bff]">Pricing</a></li>
302
+ </ul>
303
+ </div>
304
+ <div>
305
+ <p class="mb-3 font-medium text-[#0a2540]">Platform</p>
306
+ <ul class="space-y-2 text-xs">
307
+ <li><a href="/dashboard" class="hover:text-[#635bff]">Dashboard</a></li>
308
+ <li><a href="/login" class="hover:text-[#635bff]">Sign In</a></li>
309
+ <li><a href="/signup" class="hover:text-[#635bff]">Register</a></li>
310
+ </ul>
311
+ </div>
154
312
  </div>
155
313
  </div>
156
314
  </footer>
@@ -1,21 +1,27 @@
1
- import { Navbar } from '../../components/Navbar.js';
2
1
  import { AuthForm } from '../../components/AuthForm.js';
3
2
 
4
3
  export const metadata = {
5
- title: 'Create Account — FrootAuth',
4
+ title: 'Sign Up — FrootAuth',
6
5
  };
7
6
 
8
7
  export default function SignupPage() {
9
8
  return (
10
- <div class="min-h-screen bg-[#08090a] text-zinc-100 flex flex-col justify-between selection:bg-indigo-500/20 selection:text-indigo-300">
11
- <Navbar />
9
+ <div class="min-h-screen bg-[#f6f9fc] text-[#425466] flex flex-col justify-between">
10
+ <header class="border-b border-[#e6ebf1] bg-white py-4 px-6 flex items-center justify-between">
11
+ <a href="/" class="text-[20px] font-semibold tracking-tight text-[#635bff]">
12
+ frootauth
13
+ </a>
14
+ <a href="/" class="text-xs text-[#425466] hover:text-[#0a2540]">
15
+ ← Back to home
16
+ </a>
17
+ </header>
12
18
 
13
19
  <main class="max-w-md mx-auto px-6 py-16 flex-1 w-full flex flex-col justify-center">
14
20
  <AuthForm mode="signup" />
15
21
  </main>
16
22
 
17
- <footer class="py-6 text-center text-xs text-zinc-600">
18
- FrootAuth • Web Crypto PBKDF2 Authentication
23
+ <footer class="py-6 text-center text-xs text-[#425466]">
24
+ FrootAuth · Web Crypto PBKDF2 Authentication
19
25
  </footer>
20
26
  </div>
21
27
  );
@@ -6,31 +6,28 @@ export function AuthForm({ mode }: AuthFormProps) {
6
6
  const isLogin = mode === 'login';
7
7
 
8
8
  return (
9
- <div class="rounded-xl border border-white/[0.08] bg-[#0f1117] p-7 sm:p-8 shadow-2xl shadow-black/50 relative overflow-hidden">
10
- {/* Top ambient highlight */}
11
- <div class="absolute inset-x-0 top-0 h-px bg-gradient-to-r from-transparent via-indigo-500/40 to-transparent" />
12
-
9
+ <div class="rounded-lg border border-[#e6ebf1] bg-white p-7 sm:p-8 shadow-[0_13px_27px_-5px_rgba(50,50,93,0.25),0_8px_16px_-8px_rgba(0,0,0,0.3)]">
13
10
  <div class="mb-6">
14
- <h1 class="text-xl font-semibold text-white tracking-tight mb-1">
15
- {isLogin ? 'Sign in to workspace' : 'Create your account'}
11
+ <h1 class="text-2xl font-light text-[#0a2540] tracking-tight mb-1">
12
+ {isLogin ? 'Sign in to FrootAuth' : 'Create your account'}
16
13
  </h1>
17
- <p class="text-zinc-400 text-xs">
14
+ <p class="text-sm text-[#425466]">
18
15
  {isLogin ? 'Need an account? ' : 'Already registered? '}
19
- <a href={isLogin ? '/signup' : '/login'} class="text-indigo-400 font-medium hover:text-indigo-300 transition-colors">
16
+ <a href={isLogin ? '/signup' : '/login'} class="text-[#635bff] font-medium hover:underline">
20
17
  {isLogin ? 'Sign up' : 'Sign in'}
21
18
  </a>
22
19
  </p>
23
20
  </div>
24
21
 
25
22
  {isLogin && (
26
- <div class="mb-5 p-3 rounded-lg bg-white/[0.02] border border-white/[0.06] text-xs">
27
- <div class="flex items-center gap-1.5 text-zinc-400 text-[11px] mb-1">
28
- <span class="w-1.5 h-1.5 rounded-full bg-emerald-400" />
29
- <span class="font-medium text-zinc-300">Quick Demo Credentials:</span>
23
+ <div class="mb-5 p-3 rounded-md bg-[#f6f9fc] border border-[#e6ebf1] text-xs">
24
+ <div class="flex items-center gap-1.5 text-[#425466] text-[12px] mb-1">
25
+ <span class="w-1.5 h-1.5 rounded-full bg-[#24b47e]" />
26
+ <span class="font-medium text-[#0a2540]">Demo Credentials:</span>
30
27
  </div>
31
- <div class="font-mono text-zinc-300 text-[11px] bg-white/[0.03] px-2 py-1 rounded flex items-center justify-between">
28
+ <div class="font-mono text-[#0a2540] text-[12px] bg-white px-2.5 py-1 rounded border border-[#e6ebf1] flex items-center justify-between">
32
29
  <span>admin@frootkit.dev</span>
33
- <span class="text-zinc-600">•</span>
30
+ <span class="text-[#425466]">/</span>
34
31
  <span>password123</span>
35
32
  </div>
36
33
  </div>
@@ -39,46 +36,39 @@ export function AuthForm({ mode }: AuthFormProps) {
39
36
  <form action={`/api/auth?action=${mode}`} method="POST" class="space-y-4">
40
37
  {!isLogin && (
41
38
  <div>
42
- <label class="block text-xs font-medium text-zinc-300 mb-1.5" for="name">
39
+ <label class="block text-xs font-medium text-[#0a2540] mb-1.5" for="name">
43
40
  Full Name
44
41
  </label>
45
42
  <input
46
43
  id="name"
47
44
  type="text"
48
45
  name="name"
49
- placeholder="Developer Name"
46
+ placeholder="Jane Doe"
50
47
  required
51
- class="w-full px-3 py-2 rounded-lg bg-[#08090a] border border-white/[0.08] text-white text-xs placeholder:text-zinc-600 focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition-colors"
48
+ class="inp"
52
49
  />
53
50
  </div>
54
51
  )}
55
52
 
56
53
  <div>
57
- <label class="block text-xs font-medium text-zinc-300 mb-1.5" for="email">
54
+ <label class="block text-xs font-medium text-[#0a2540] mb-1.5" for="email">
58
55
  Email Address
59
56
  </label>
60
57
  <input
61
58
  id="email"
62
59
  type="email"
63
60
  name="email"
64
- placeholder="admin@frootkit.dev"
61
+ placeholder="you@company.com"
65
62
  defaultValue={isLogin ? 'admin@frootkit.dev' : ''}
66
63
  required
67
- class="w-full px-3 py-2 rounded-lg bg-[#08090a] border border-white/[0.08] text-white text-xs placeholder:text-zinc-600 focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition-colors"
64
+ class="inp"
68
65
  />
69
66
  </div>
70
67
 
71
68
  <div>
72
- <div class="flex items-center justify-between mb-1.5">
73
- <label class="block text-xs font-medium text-zinc-300" for="password">
74
- Password
75
- </label>
76
- {isLogin && (
77
- <span class="text-[11px] text-zinc-500">
78
- min 8 characters
79
- </span>
80
- )}
81
- </div>
69
+ <label class="block text-xs font-medium text-[#0a2540] mb-1.5" for="password">
70
+ Password
71
+ </label>
82
72
  <input
83
73
  id="password"
84
74
  type="password"
@@ -86,18 +76,21 @@ export function AuthForm({ mode }: AuthFormProps) {
86
76
  placeholder="••••••••••••"
87
77
  defaultValue={isLogin ? 'password123' : ''}
88
78
  required
89
- class="w-full px-3 py-2 rounded-lg bg-[#08090a] border border-white/[0.08] text-white text-xs placeholder:text-zinc-600 focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition-colors"
79
+ class="inp"
90
80
  />
91
81
  </div>
92
82
 
93
83
  <button
94
84
  type="submit"
95
- class="w-full py-2.5 rounded-lg bg-white text-zinc-950 font-medium text-xs hover:bg-zinc-200 transition-all mt-3 flex items-center justify-center gap-2 group shadow-sm"
85
+ class="btn btn-p w-full py-2.5 text-sm font-medium mt-2"
96
86
  >
97
- <span>{isLogin ? 'Sign In' : 'Create Account'}</span>
98
- <span class="text-zinc-500 group-hover:translate-x-0.5 transition-transform">→</span>
87
+ {isLogin ? 'Sign In' : 'Create Account'}
99
88
  </button>
100
89
  </form>
90
+
91
+ <div class="mt-6 pt-4 border-t border-[#e6ebf1] text-center text-xs text-[#425466]">
92
+ Protected by Web Crypto PBKDF2 with 100,000 iterations.
93
+ </div>
101
94
  </div>
102
95
  );
103
96
  }