create-frootkit 1.2.2 → 1.2.4

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 (40) hide show
  1. package/dist/index.js +1 -1
  2. package/package.json +1 -1
  3. package/templates/auth/src/app/dashboard/layout.tsx +9 -9
  4. package/templates/auth/src/app/dashboard/page.tsx +20 -20
  5. package/templates/auth/src/app/layout.tsx +7 -1
  6. package/templates/auth/src/app/login/page.tsx +2 -2
  7. package/templates/auth/src/app/page.tsx +78 -37
  8. package/templates/auth/src/app/signup/page.tsx +2 -2
  9. package/templates/auth/src/components/AuthForm.tsx +28 -17
  10. package/templates/auth/src/components/DashboardNav.tsx +66 -33
  11. package/templates/auth/src/components/MetricCard.tsx +9 -7
  12. package/templates/auth/src/components/Navbar.tsx +11 -8
  13. package/templates/auth/src/styles.css +29 -11
  14. package/templates/blog/src/app/blog/[slug]/page.tsx +11 -11
  15. package/templates/blog/src/app/layout.tsx +7 -1
  16. package/templates/blog/src/app/page.tsx +26 -12
  17. package/templates/blog/src/components/Footer.tsx +5 -5
  18. package/templates/blog/src/components/Navbar.tsx +8 -6
  19. package/templates/blog/src/components/Newsletter.tsx +16 -10
  20. package/templates/blog/src/components/PostCard.tsx +61 -14
  21. package/templates/blog/src/styles.css +29 -11
  22. package/templates/ecommerce/src/app/cart/page.tsx +2 -2
  23. package/templates/ecommerce/src/app/layout.tsx +7 -1
  24. package/templates/ecommerce/src/app/page.tsx +20 -29
  25. package/templates/ecommerce/src/app/products/[id]/page.tsx +21 -20
  26. package/templates/ecommerce/src/components/CartDrawer.tsx +13 -13
  27. package/templates/ecommerce/src/components/Footer.tsx +5 -5
  28. package/templates/ecommerce/src/components/Navbar.tsx +13 -8
  29. package/templates/ecommerce/src/components/ProductCard.tsx +14 -13
  30. package/templates/ecommerce/src/styles.css +29 -11
  31. package/templates/empty/src/app/layout.tsx +6 -0
  32. package/templates/empty/src/app/page.tsx +9 -9
  33. package/templates/empty/src/styles.css +29 -11
  34. package/templates/starter/src/app/layout.tsx +7 -1
  35. package/templates/starter/src/app/page.tsx +77 -76
  36. package/templates/starter/src/components/FeatureCard.tsx +10 -6
  37. package/templates/starter/src/components/Footer.tsx +5 -5
  38. package/templates/starter/src/components/Header.tsx +6 -6
  39. package/templates/starter/src/components/TerminalPreview.tsx +28 -28
  40. package/templates/starter/src/styles.css +29 -11
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import { scaffoldProject } from './scaffold.js';
11
11
  export * from './template.js';
12
12
  export * from './scaffold.js';
13
13
  export * from './ui.js';
14
- const VERSION = '1.2.2';
14
+ const VERSION = '1.2.3';
15
15
  function parseCliArgs(argv) {
16
16
  const raw = argv.slice(2);
17
17
  const args = {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-frootkit",
3
- "version": "1.2.2",
3
+ "version": "1.2.4",
4
4
  "description": "Interactive CLI for scaffolding high-performance FrootKit (Next.js Alternative) applications",
5
5
  "type": "module",
6
6
  "bin": {
@@ -3,24 +3,24 @@ import { DashboardNav } from '../../components/DashboardNav.js';
3
3
 
4
4
  export default function DashboardLayout({ children }: { children: ComponentChildren }) {
5
5
  return (
6
- <div class="min-h-screen flex bg-[#030712] text-slate-100">
6
+ <div class="min-h-screen flex bg-[#06090f] text-slate-100">
7
7
  <DashboardNav />
8
8
  <div class="flex-1 flex flex-col min-w-0">
9
- <header class="h-16 border-b border-slate-800/80 px-8 flex items-center justify-between bg-slate-950/40 backdrop-blur-md">
9
+ <header class="h-16 border-b border-[#1a2333] px-8 flex items-center justify-between bg-[#06090f]">
10
10
  <div class="flex items-center gap-3">
11
- <h1 class="text-sm font-bold text-white">Production Cluster</h1>
12
- <span class="px-2 py-0.5 rounded-full bg-emerald-500/10 text-emerald-400 text-[10px] font-mono border border-emerald-500/20">
13
- US-East (N. Virginia)
11
+ <h1 class="text-sm font-semibold text-white">Cluster: US-East Production</h1>
12
+ <span class="px-2 py-0.5 rounded bg-emerald-500/10 text-emerald-400 text-[10px] font-mono border border-emerald-500/20 font-semibold">
13
+ Live • 99.99% Uptime
14
14
  </span>
15
15
  </div>
16
16
 
17
- <div class="flex items-center gap-4 text-xs">
18
- <span class="text-slate-400">Logged in as <strong class="text-white">admin@frootkit.dev</strong></span>
17
+ <div class="flex items-center gap-4 text-xs font-mono">
18
+ <span class="text-slate-400">User: <strong class="text-white">admin@frootkit.dev</strong></span>
19
19
  <a
20
20
  href="/api/auth"
21
- class="px-2.5 py-1 rounded-lg bg-slate-900 border border-slate-800 text-slate-300 font-mono hover:text-emerald-400"
21
+ class="px-2.5 py-1 rounded bg-[#0a0f18] border border-[#1a2333] text-slate-300 hover:text-emerald-400 transition-colors"
22
22
  >
23
- Session API
23
+ /api/auth
24
24
  </a>
25
25
  </div>
26
26
  </header>
@@ -1,29 +1,29 @@
1
1
  import { MetricCard } from '../../components/MetricCard.js';
2
2
 
3
3
  export const metadata = {
4
- title: 'Workspace Overview — FrootSaaS',
4
+ title: 'Workspace Overview — FrootAuth',
5
5
  };
6
6
 
7
7
  export default function DashboardOverviewPage() {
8
8
  const metrics = [
9
9
  { label: 'Monthly Recurring Revenue', value: '$42,850', change: '+14.2%', isPositive: true },
10
10
  { label: 'Active Subscribers', value: '1,280', change: '+8.1%', isPositive: true },
11
- { label: 'API Requests (24h)', value: '3.42M', change: '+22.4%', isPositive: true },
12
- { label: 'Average Latency', value: '0.42ms', change: '-12.0%', isPositive: true },
11
+ { label: 'API Invocations (24h)', value: '3.42M', change: '+22.4%', isPositive: true },
12
+ { label: 'P99 Dispatch Latency', value: '0.42ms', change: '-12.0%', isPositive: true },
13
13
  ];
14
14
 
15
15
  const recentUsers = [
16
16
  { name: 'Sarah Connor', email: 'sarah@frootkit.dev', role: 'Owner', date: 'Just now' },
17
- { name: 'John Doe', email: 'john@acme.corp', role: 'Developer', date: '2 hours ago' },
18
- { name: 'Alex Wong', email: 'alex@startup.io', role: 'Designer', date: '1 day ago' },
19
- { name: 'Maria Garcia', email: 'maria@scale.dev', role: 'Admin', date: '3 days ago' },
17
+ { name: 'Marcus Chen', email: 'marcus@infra.org', role: 'Developer', date: '2 hours ago' },
18
+ { name: 'Elena Rostova', email: 'elena@design.io', role: 'Staff Eng', date: '1 day ago' },
19
+ { name: 'Alex Rivera', email: 'alex@systems.net', role: 'Admin', date: '3 days ago' },
20
20
  ];
21
21
 
22
22
  return (
23
23
  <div class="space-y-8">
24
24
  <div>
25
- <h2 class="text-2xl font-bold text-white mb-1">Metrics & Operations</h2>
26
- <p class="text-xs text-slate-400">Real-time performance and subscriber growth analytics.</p>
25
+ <h2 class="text-2xl font-bold text-white mb-1.5 tracking-tight">Metrics & Telemetry</h2>
26
+ <p class="text-sm text-slate-400">Real-time throughput and workspace subscriber analytics.</p>
27
27
  </div>
28
28
 
29
29
  <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
@@ -38,29 +38,29 @@ export default function DashboardOverviewPage() {
38
38
  ))}
39
39
  </div>
40
40
 
41
- <div class="rounded-2xl border border-slate-800 bg-slate-900/40 p-6 backdrop-blur-sm">
42
- <h3 class="text-sm font-bold text-white mb-4">Recent Workspace Activity</h3>
41
+ <div class="rounded-xl border border-[#1a2333] bg-[#0a0f18] p-6 shadow-sm">
42
+ <h3 class="text-base font-semibold text-white mb-4">Recent Workspace Activity</h3>
43
43
  <div class="overflow-x-auto">
44
- <table class="w-full text-left text-xs">
44
+ <table class="w-full text-left text-sm">
45
45
  <thead>
46
- <tr class="border-b border-slate-800 text-slate-500 font-mono">
46
+ <tr class="border-b border-[#1a2333] text-slate-400 text-xs uppercase font-mono tracking-wider">
47
47
  <th class="pb-3 font-semibold">User</th>
48
48
  <th class="pb-3 font-semibold">Email</th>
49
49
  <th class="pb-3 font-semibold">Role</th>
50
- <th class="pb-3 font-semibold">Time</th>
50
+ <th class="pb-3 font-semibold text-right">Timestamp</th>
51
51
  </tr>
52
52
  </thead>
53
- <tbody class="divide-y divide-slate-800/60">
53
+ <tbody class="divide-y divide-[#1a2333]/70">
54
54
  {recentUsers.map((u) => (
55
- <tr key={u.email} class="hover:bg-slate-900/60">
56
- <td class="py-3 font-medium text-white">{u.name}</td>
57
- <td class="py-3 text-slate-400 font-mono">{u.email}</td>
58
- <td class="py-3">
59
- <span class="px-2 py-0.5 rounded-full bg-slate-800 text-slate-300 font-mono text-[10px]">
55
+ <tr key={u.email} class="hover:bg-[#0f1624]/40 transition-colors">
56
+ <td class="py-3.5 font-medium text-white">{u.name}</td>
57
+ <td class="py-3.5 text-slate-400 font-mono text-xs">{u.email}</td>
58
+ <td class="py-3.5">
59
+ <span class="px-2 py-0.5 rounded-md bg-[#0f1624] text-slate-300 border border-[#1a2333] text-xs font-mono">
60
60
  {u.role}
61
61
  </span>
62
62
  </td>
63
- <td class="py-3 text-slate-500">{u.date}</td>
63
+ <td class="py-3.5 text-slate-500 text-xs text-right font-mono">{u.date}</td>
64
64
  </tr>
65
65
  ))}
66
66
  </tbody>
@@ -21,9 +21,15 @@ export default function RootLayout({ children, metadata }: RootLayoutProps) {
21
21
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
22
22
  <title>{title}</title>
23
23
  <meta name="description" content={description} />
24
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
25
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
26
+ <link
27
+ href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap"
28
+ rel="stylesheet"
29
+ />
24
30
  <link rel="stylesheet" href="/styles.css" />
25
31
  </head>
26
- <body class="bg-[#030712] text-slate-100 min-h-screen antialiased selection:bg-emerald-500/20 selection:text-emerald-300">
32
+ <body class="bg-[#030712] text-slate-100 min-h-screen antialiased selection:bg-emerald-500/20 selection:text-emerald-300 font-sans">
27
33
  {children}
28
34
  </body>
29
35
  </html>
@@ -2,12 +2,12 @@ import { Navbar } from '../../components/Navbar.js';
2
2
  import { AuthForm } from '../../components/AuthForm.js';
3
3
 
4
4
  export const metadata = {
5
- title: 'Sign In — FrootSaaS',
5
+ title: 'Sign In — FrootAuth',
6
6
  };
7
7
 
8
8
  export default function LoginPage() {
9
9
  return (
10
- <div class="min-h-screen flex flex-col justify-between">
10
+ <div class="min-h-screen bg-[#06090f] text-slate-100 flex flex-col justify-between">
11
11
  <Navbar />
12
12
 
13
13
  <main class="max-w-md mx-auto px-6 py-16 flex-1 w-full flex flex-col justify-center">
@@ -1,57 +1,98 @@
1
1
  import { Navbar } from '../components/Navbar.js';
2
2
 
3
3
  export const metadata = {
4
- title: 'FrootSaaS — Next Generation Cloud Infrastructure',
5
- description: 'Deploy lightning fast web services with enterprise grade observability.',
4
+ title: 'FrootAuth — Web Crypto Authentication & Dashboard',
5
+ description: 'Pure Web Crypto PBKDF2 password hashing and secure session management for FrootKit.',
6
6
  };
7
7
 
8
8
  export default function SaaSMarketingPage() {
9
9
  return (
10
- <div class="min-h-screen flex flex-col justify-between">
10
+ <div class="min-h-screen bg-[#06090f] text-slate-100 flex flex-col justify-between">
11
11
  <Navbar />
12
12
 
13
- <main class="max-w-6xl mx-auto px-6 py-20 flex-1 flex flex-col justify-center">
14
- <div class="text-center max-w-3xl mx-auto mb-16">
15
- <div class="inline-flex items-center gap-2 px-3.5 py-1.5 rounded-full bg-emerald-500/10 border border-emerald-500/25 text-xs font-semibold text-emerald-400 mb-8 shadow-sm">
16
- <span class="w-1.5 h-1.5 rounded-full bg-emerald-400 animate-pulse" />
17
- Fullstack Authentication & Dashboard
13
+ <main class="max-w-6xl mx-auto px-6 py-16 flex-1 flex flex-col justify-center">
14
+ <div class="grid grid-cols-1 lg:grid-cols-12 gap-12 items-center">
15
+ {/* Left Column (7 cols) */}
16
+ <div class="lg:col-span-7">
17
+ <div class="text-xs font-mono font-medium text-emerald-400 mb-3 uppercase tracking-wide">
18
+ Security Architecture • Pure Web Crypto
19
+ </div>
20
+
21
+ <h1 class="text-4xl sm:text-5xl lg:text-6xl font-extrabold text-white tracking-tight leading-tight mb-6">
22
+ Fullstack Authentication & Administration.
23
+ </h1>
24
+
25
+ <p class="text-base sm:text-lg text-slate-300 leading-relaxed mb-8 max-w-xl">
26
+ Zero external C++ dependencies. Real PBKDF2 password hashing (100,000 iterations), cryptographically random session tokens, protected layout routes, and administrative dashboard metrics.
27
+ </p>
28
+
29
+ <div class="flex flex-wrap items-center gap-4 mb-8">
30
+ <a
31
+ href="/signup"
32
+ class="px-5 py-2.5 rounded-lg bg-emerald-500 text-slate-950 font-semibold hover:bg-emerald-400 transition-colors text-sm flex items-center gap-1.5"
33
+ >
34
+ <span>Create Account</span>
35
+ <span>→</span>
36
+ </a>
37
+ <a
38
+ href="/dashboard"
39
+ class="px-5 py-2.5 rounded-lg bg-[#0a0f18] border border-[#1a2333] text-slate-200 font-semibold hover:border-slate-700 hover:text-white transition-colors text-sm"
40
+ >
41
+ View Dashboard
42
+ </a>
43
+ </div>
44
+
45
+ <div class="text-xs font-mono text-slate-400 flex items-center gap-2">
46
+ <span class="text-emerald-400 font-bold">✓</span>
47
+ <span>Demo Account ready: admin@frootkit.dev / password123</span>
48
+ </div>
18
49
  </div>
19
50
 
20
- <h1 class="text-4xl sm:text-6xl font-black text-white tracking-tight mb-6 leading-tight">
21
- The Complete Platform for{' '}
22
- <span class="bg-gradient-to-r from-emerald-400 via-teal-300 to-cyan-400 bg-clip-text text-transparent">
23
- Modern SaaS
24
- </span>
25
- </h1>
26
-
27
- <p class="text-slate-300 text-lg sm:text-xl leading-relaxed mb-10 max-w-2xl mx-auto">
28
- Real Web Crypto password hashing, secure session cookies, protected routes, and an administrative dashboard layout ready out of the box.
29
- </p>
30
-
31
- <div class="flex flex-wrap items-center justify-center gap-4">
32
- <a
33
- href="/signup"
34
- class="px-6 py-3 rounded-xl bg-emerald-500 text-slate-950 font-bold hover:bg-emerald-400 transition-all shadow-lg shadow-emerald-500/25 hover:-translate-y-0.5"
35
- >
36
- Start Free Trial &rarr;
37
- </a>
38
- <a
39
- href="/dashboard"
40
- class="px-6 py-3 rounded-xl bg-slate-900 border border-slate-800 text-slate-200 font-semibold hover:bg-slate-800 transition-all hover:-translate-y-0.5"
41
- >
42
- View Live Dashboard
43
- </a>
51
+ {/* Right Column: Mini Dashboard Card (5 cols) */}
52
+ <div class="lg:col-span-5">
53
+ <div class="rounded-xl border border-[#1a2333] bg-[#0a0f18] p-6 shadow-xl space-y-4">
54
+ <div class="flex items-center justify-between pb-3 border-b border-[#1a2333]">
55
+ <span class="text-xs font-mono text-slate-400">Security Telemetry</span>
56
+ <span class="text-[10px] font-mono text-emerald-400 px-2 py-0.5 rounded bg-emerald-500/10 border border-emerald-500/20 font-semibold">
57
+ PBKDF2-SHA256
58
+ </span>
59
+ </div>
60
+
61
+ <div class="space-y-3 font-mono text-xs">
62
+ <div class="flex justify-between">
63
+ <span class="text-slate-400">Iterations:</span>
64
+ <span class="text-white font-bold">100,000</span>
65
+ </div>
66
+ <div class="flex justify-between">
67
+ <span class="text-slate-400">Salt Length:</span>
68
+ <span class="text-white font-bold">128-bit (16 bytes)</span>
69
+ </div>
70
+ <div class="flex justify-between">
71
+ <span class="text-slate-400">Key Derivation:</span>
72
+ <span class="text-white font-bold">256-bit SubtleCrypto</span>
73
+ </div>
74
+ <div class="flex justify-between">
75
+ <span class="text-slate-400">Cookie Security:</span>
76
+ <span class="text-emerald-400 font-bold">HttpOnly; SameSite=Lax</span>
77
+ </div>
78
+ </div>
79
+
80
+ <div class="pt-3 border-t border-[#1a2333] flex justify-between items-center text-xs">
81
+ <span class="text-slate-400">Endpoint:</span>
82
+ <code class="text-emerald-400 font-mono">/api/auth?action=login</code>
83
+ </div>
84
+ </div>
44
85
  </div>
45
86
  </div>
46
87
  </main>
47
88
 
48
- <footer class="border-t border-slate-900 bg-slate-950/60 py-8 text-center text-xs text-slate-500">
89
+ <footer class="border-t border-[#1a2333] bg-[#06090f] py-8 text-xs text-slate-400">
49
90
  <div class="max-w-6xl mx-auto px-6 flex justify-between">
50
- <div>FrootSaaS &copy; {new Date().getFullYear()} OrbitNorth LLC</div>
91
+ <div>FrootAuth © {new Date().getFullYear()} OrbitNorth LLC</div>
51
92
  <div class="flex gap-4">
52
- <a href="/login" class="hover:text-slate-400">Sign In</a>
53
- <a href="/signup" class="hover:text-slate-400">Sign Up</a>
54
- <a href="/dashboard" class="hover:text-slate-400">Dashboard</a>
93
+ <a href="/login" class="hover:text-white transition-colors">Sign In</a>
94
+ <a href="/signup" class="hover:text-white transition-colors">Sign Up</a>
95
+ <a href="/dashboard" class="hover:text-white transition-colors">Dashboard</a>
55
96
  </div>
56
97
  </div>
57
98
  </footer>
@@ -2,12 +2,12 @@ import { Navbar } from '../../components/Navbar.js';
2
2
  import { AuthForm } from '../../components/AuthForm.js';
3
3
 
4
4
  export const metadata = {
5
- title: 'Create Account — FrootSaaS',
5
+ title: 'Create Account — FrootAuth',
6
6
  };
7
7
 
8
8
  export default function SignupPage() {
9
9
  return (
10
- <div class="min-h-screen flex flex-col justify-between">
10
+ <div class="min-h-screen bg-[#06090f] text-slate-100 flex flex-col justify-between">
11
11
  <Navbar />
12
12
 
13
13
  <main class="max-w-md mx-auto px-6 py-16 flex-1 w-full flex flex-col justify-center">
@@ -6,13 +6,13 @@ export function AuthForm({ mode }: AuthFormProps) {
6
6
  const isLogin = mode === 'login';
7
7
 
8
8
  return (
9
- <div class="rounded-3xl border border-slate-800 bg-slate-900/60 p-8 backdrop-blur-xl shadow-2xl">
10
- <div class="text-center mb-8">
11
- <h1 class="text-2xl font-bold text-white mb-2">
12
- {isLogin ? 'Sign in to your account' : 'Create your account'}
9
+ <div class="rounded-xl border border-[#1a2333] bg-[#0a0f18] p-8 shadow-xl">
10
+ <div class="mb-6">
11
+ <h1 class="text-2xl font-bold text-white mb-1.5">
12
+ {isLogin ? 'Sign in to workspace' : 'Create workspace account'}
13
13
  </h1>
14
14
  <p class="text-slate-400 text-xs">
15
- {isLogin ? "Don't have an account? " : 'Already have an account? '}
15
+ {isLogin ? 'Need an account? ' : 'Already registered? '}
16
16
  <a href={isLogin ? '/signup' : '/login'} class="text-emerald-400 font-semibold hover:underline">
17
17
  {isLogin ? 'Sign up' : 'Sign in'}
18
18
  </a>
@@ -20,9 +20,10 @@ export function AuthForm({ mode }: AuthFormProps) {
20
20
  </div>
21
21
 
22
22
  {isLogin && (
23
- <div class="mb-6 p-3 rounded-xl bg-emerald-500/10 border border-emerald-500/20 text-xs text-emerald-300 flex items-center justify-between">
24
- <div>
25
- <span class="font-bold">Demo:</span> admin@frootkit.dev &bull; password123
23
+ <div class="mb-6 p-3.5 rounded-lg bg-[#06090f] border border-[#1a2333] text-xs text-slate-300">
24
+ <span class="text-emerald-400 font-bold block mb-1">Demo Credentials:</span>
25
+ <div class="font-mono text-slate-300 text-[11px]">
26
+ admin@frootkit.dev <span class="text-slate-500 mx-1">•</span> password123
26
27
  </div>
27
28
  </div>
28
29
  )}
@@ -30,46 +31,56 @@ export function AuthForm({ mode }: AuthFormProps) {
30
31
  <form action={`/api/auth?action=${mode}`} method="POST" class="space-y-4">
31
32
  {!isLogin && (
32
33
  <div>
33
- <label class="block text-xs font-medium text-slate-300 mb-1.5">Full Name</label>
34
+ <label class="block text-xs font-medium text-slate-300 mb-1.5" for="name">
35
+ Full Name
36
+ </label>
34
37
  <input
38
+ id="name"
35
39
  type="text"
36
40
  name="name"
37
- placeholder="Sarah Connor"
41
+ placeholder="Developer Name"
38
42
  required
39
- class="w-full px-4 py-2.5 rounded-xl bg-slate-950 border border-slate-800 text-white text-sm focus:outline-none focus:border-emerald-500"
43
+ class="w-full px-3.5 py-2 rounded-lg bg-[#06090f] border border-[#1a2333] text-white text-sm focus:outline-none focus:border-emerald-500 transition-colors"
40
44
  />
41
45
  </div>
42
46
  )}
43
47
 
44
48
  <div>
45
- <label class="block text-xs font-medium text-slate-300 mb-1.5">Email Address</label>
49
+ <label class="block text-xs font-medium text-slate-300 mb-1.5" for="email">
50
+ Email Address
51
+ </label>
46
52
  <input
53
+ id="email"
47
54
  type="email"
48
55
  name="email"
49
56
  placeholder="admin@frootkit.dev"
50
57
  defaultValue={isLogin ? 'admin@frootkit.dev' : ''}
51
58
  required
52
- class="w-full px-4 py-2.5 rounded-xl bg-slate-950 border border-slate-800 text-white text-sm focus:outline-none focus:border-emerald-500"
59
+ class="w-full px-3.5 py-2 rounded-lg bg-[#06090f] border border-[#1a2333] text-white text-sm focus:outline-none focus:border-emerald-500 transition-colors"
53
60
  />
54
61
  </div>
55
62
 
56
63
  <div>
57
- <label class="block text-xs font-medium text-slate-300 mb-1.5">Password</label>
64
+ <label class="block text-xs font-medium text-slate-300 mb-1.5" for="password">
65
+ Password
66
+ </label>
58
67
  <input
68
+ id="password"
59
69
  type="password"
60
70
  name="password"
61
71
  placeholder="••••••••••••"
62
72
  defaultValue={isLogin ? 'password123' : ''}
63
73
  required
64
- class="w-full px-4 py-2.5 rounded-xl bg-slate-950 border border-slate-800 text-white text-sm focus:outline-none focus:border-emerald-500"
74
+ class="w-full px-3.5 py-2 rounded-lg bg-[#06090f] border border-[#1a2333] text-white text-sm focus:outline-none focus:border-emerald-500 transition-colors"
65
75
  />
66
76
  </div>
67
77
 
68
78
  <button
69
79
  type="submit"
70
- class="w-full py-3 rounded-xl bg-emerald-500 text-slate-950 font-bold text-sm hover:bg-emerald-400 transition-colors shadow-lg shadow-emerald-500/20 mt-2"
80
+ class="w-full py-2.5 rounded-lg bg-emerald-500 text-slate-950 font-semibold text-sm hover:bg-emerald-400 transition-colors mt-2 flex items-center justify-center gap-2"
71
81
  >
72
- {isLogin ? 'Sign In &rarr;' : 'Create Account &rarr;'}
82
+ <span>{isLogin ? 'Sign In' : 'Create Account'}</span>
83
+ <span>→</span>
73
84
  </button>
74
85
  </form>
75
86
  </div>
@@ -1,48 +1,81 @@
1
1
  export function DashboardNav() {
2
- const links = [
3
- { label: 'Overview', href: '/dashboard', icon: '📊' },
4
- { label: 'Analytics', href: '/dashboard#analytics', icon: '📈' },
5
- { label: 'Team', href: '/dashboard#team', icon: '👥' },
6
- { label: 'API Keys', href: '/api/auth', icon: '🔑' },
7
- ];
8
-
9
2
  return (
10
- <aside class="w-64 border-r border-slate-800/80 bg-slate-950/80 p-6 flex flex-col justify-between shrink-0">
3
+ <aside class="w-64 border-r border-[#1a2333] bg-[#0a0f18] p-5 flex flex-col justify-between shrink-0 min-h-screen">
11
4
  <div>
12
- <div class="flex items-center gap-2.5 font-bold text-white text-lg mb-8">
13
- <span class="w-7 h-7 rounded-lg bg-emerald-500 flex items-center justify-center text-slate-950 font-black text-xs">
14
- F
15
- </span>
16
- <span>Workspace</span>
5
+ {/* Brand Header */}
6
+ <div class="flex items-center gap-3 font-bold text-white text-base mb-6 px-1">
7
+ <div class="w-8 h-8 rounded-lg bg-emerald-500/10 border border-emerald-500/30 flex items-center justify-center text-emerald-400 shrink-0">
8
+ <svg width="18" height="18" class="w-4.5 h-4.5 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
9
+ <path stroke-linecap="round" stroke-linejoin="round" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
10
+ </svg>
11
+ </div>
12
+ <span class="tracking-tight">Workspace</span>
17
13
  </div>
18
14
 
15
+ {/* Navigation Links */}
19
16
  <nav class="space-y-1 text-sm font-medium">
20
- {links.map((link) => (
21
- <a
22
- key={link.label}
23
- href={link.href}
24
- class="flex items-center gap-3 px-3.5 py-2.5 rounded-xl text-slate-300 hover:text-white hover:bg-slate-900/80 transition-colors"
25
- >
26
- <span>{link.icon}</span>
27
- <span>{link.label}</span>
28
- </a>
29
- ))}
17
+ <a
18
+ href="/dashboard"
19
+ class="flex items-center gap-3 px-3 py-2 rounded-lg bg-emerald-500/10 text-emerald-400 border border-emerald-500/25 transition-colors"
20
+ >
21
+ <svg width="18" height="18" class="w-4.5 h-4.5 shrink-0 text-emerald-400" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2">
22
+ <path stroke-linecap="round" stroke-linejoin="round" d="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z" />
23
+ </svg>
24
+ <span>Overview</span>
25
+ </a>
26
+
27
+ <a
28
+ href="/dashboard#analytics"
29
+ class="flex items-center gap-3 px-3 py-2 rounded-lg text-slate-400 hover:text-white hover:bg-white/[0.04] transition-colors"
30
+ >
31
+ <svg width="18" height="18" class="w-4.5 h-4.5 shrink-0 text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2">
32
+ <path stroke-linecap="round" stroke-linejoin="round" d="M13 7h8m0 0v8m0-8l-8 8-4-4-6 6" />
33
+ </svg>
34
+ <span>Telemetry</span>
35
+ </a>
36
+
37
+ <a
38
+ href="/dashboard#team"
39
+ class="flex items-center gap-3 px-3 py-2 rounded-lg text-slate-400 hover:text-white hover:bg-white/[0.04] transition-colors"
40
+ >
41
+ <svg width="18" height="18" class="w-4.5 h-4.5 shrink-0 text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2">
42
+ <path stroke-linecap="round" stroke-linejoin="round" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z" />
43
+ </svg>
44
+ <span>Members</span>
45
+ </a>
46
+
47
+ <a
48
+ href="/api/auth"
49
+ class="flex items-center gap-3 px-3 py-2 rounded-lg text-slate-400 hover:text-white hover:bg-white/[0.04] transition-colors"
50
+ >
51
+ <svg width="18" height="18" class="w-4.5 h-4.5 shrink-0 text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2">
52
+ <path stroke-linecap="round" stroke-linejoin="round" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z" />
53
+ </svg>
54
+ <span>Session API</span>
55
+ </a>
30
56
  </nav>
31
57
  </div>
32
58
 
33
- <div class="pt-6 border-t border-slate-800/80 flex items-center justify-between">
34
- <div class="flex items-center gap-2.5">
35
- <div class="w-8 h-8 rounded-full bg-emerald-500/20 border border-emerald-500/30 flex items-center justify-center font-bold text-xs text-emerald-400">
36
- SC
59
+ {/* User profile & Sign out */}
60
+ <div class="pt-4 border-t border-[#1a2333] flex items-center justify-between">
61
+ <div class="flex items-center gap-2.5 min-w-0">
62
+ <div class="w-8 h-8 rounded-full bg-emerald-500/10 border border-emerald-500/30 flex items-center justify-center font-bold text-xs text-emerald-400 font-mono shrink-0">
63
+ AD
37
64
  </div>
38
- <div class="text-xs">
39
- <div class="font-bold text-white">Sarah Connor</div>
40
- <div class="text-slate-500">Pro Plan</div>
65
+ <div class="text-xs truncate">
66
+ <div class="font-semibold text-white truncate">admin@frootkit.dev</div>
67
+ <div class="text-slate-400 text-[11px]">Administrator</div>
41
68
  </div>
42
69
  </div>
43
- <form action="/api/auth?action=logout" method="POST">
44
- <button type="submit" class="text-slate-500 hover:text-rose-400 text-xs transition-colors" title="Sign out">
45
- &rarr;
70
+ <form action="/api/auth?action=logout" method="POST" class="shrink-0 ml-2">
71
+ <button
72
+ type="submit"
73
+ class="p-1.5 rounded-md text-slate-400 hover:text-rose-400 hover:bg-rose-500/10 transition-colors"
74
+ title="Sign out"
75
+ >
76
+ <svg width="16" height="16" class="w-4 h-4 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2">
77
+ <path stroke-linecap="round" stroke-linejoin="round" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1" />
78
+ </svg>
46
79
  </button>
47
80
  </form>
48
81
  </div>
@@ -7,15 +7,17 @@ export interface MetricCardProps {
7
7
 
8
8
  export function MetricCard({ label, value, change, isPositive }: MetricCardProps) {
9
9
  return (
10
- <div class="rounded-2xl border border-slate-800 bg-slate-900/40 p-6 backdrop-blur-sm">
11
- <div class="text-xs font-medium text-slate-400 mb-2">{label}</div>
12
- <div class="flex items-baseline justify-between">
13
- <div class="text-2xl sm:text-3xl font-black text-white">{value}</div>
10
+ <div class="rounded-xl border border-[#1a2333] bg-[#0a0f18] p-5 flex flex-col justify-between">
11
+ <div class="text-[11px] font-mono uppercase tracking-wider text-slate-400 mb-3 font-semibold">
12
+ {label}
13
+ </div>
14
+ <div class="flex items-baseline justify-between gap-3">
15
+ <div class="text-2xl sm:text-3xl font-bold text-white font-mono tracking-tight">{value}</div>
14
16
  <span
15
- class={`text-xs font-mono font-bold px-2 py-0.5 rounded-full ${
17
+ class={`text-xs font-mono font-semibold px-2 py-0.5 rounded-md border shrink-0 ${
16
18
  isPositive
17
- ? 'bg-emerald-500/10 text-emerald-400 border border-emerald-500/20'
18
- : 'bg-rose-500/10 text-rose-400 border border-rose-500/20'
19
+ ? 'bg-emerald-500/10 text-emerald-400 border-emerald-500/20'
20
+ : 'bg-rose-500/10 text-rose-400 border-rose-500/20'
19
21
  }`}
20
22
  >
21
23
  {change}
@@ -1,12 +1,14 @@
1
1
  export function Navbar() {
2
2
  return (
3
- <header class="border-b border-slate-800/80 bg-slate-950/70 backdrop-blur-md sticky top-0 z-50">
3
+ <header class="border-b border-[#1a2333] bg-[#06090f]/95 sticky top-0 z-50">
4
4
  <div class="max-w-6xl mx-auto px-6 h-16 flex items-center justify-between">
5
- <a href="/" class="flex items-center gap-2.5 font-bold text-white text-lg tracking-tight hover:opacity-90">
6
- <span class="w-8 h-8 rounded-xl bg-gradient-to-tr from-emerald-500 to-cyan-400 flex items-center justify-center text-slate-950 font-black text-sm">
7
- F
8
- </span>
9
- <span>Froot<span class="text-emerald-400">SaaS</span></span>
5
+ <a href="/" class="flex items-center gap-2.5 font-bold text-white text-base tracking-tight hover:text-emerald-400 transition-colors">
6
+ <div class="w-8 h-8 rounded-lg bg-emerald-500/10 border border-emerald-500/30 flex items-center justify-center text-emerald-400 shrink-0">
7
+ <svg width="18" height="18" class="w-4.5 h-4.5 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
8
+ <path stroke-linecap="round" stroke-linejoin="round" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />
9
+ </svg>
10
+ </div>
11
+ <span>Froot<span class="text-emerald-400">Auth</span></span>
10
12
  </a>
11
13
 
12
14
  <nav class="flex items-center gap-6 text-sm font-medium">
@@ -18,9 +20,10 @@ export function Navbar() {
18
20
  </a>
19
21
  <a
20
22
  href="/signup"
21
- class="px-4 py-2 rounded-xl bg-emerald-500 text-slate-950 font-bold hover:bg-emerald-400 transition-all shadow-md shadow-emerald-500/20"
23
+ class="px-4 py-2 rounded-lg bg-emerald-500 text-slate-950 font-semibold hover:bg-emerald-400 transition-colors text-xs flex items-center gap-1.5"
22
24
  >
23
- Get Started
25
+ <span>Get Started</span>
26
+ <span>→</span>
24
27
  </a>
25
28
  </nav>
26
29
  </div>