create-frootkit 1.2.12 → 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 (35) 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/src/app/cart/page.tsx +12 -4
  22. package/templates/ecommerce/src/app/layout.tsx +5 -5
  23. package/templates/ecommerce/src/app/page.tsx +92 -37
  24. package/templates/ecommerce/src/app/products/[id]/page.tsx +39 -31
  25. package/templates/ecommerce/src/components/CartDrawer.tsx +113 -45
  26. package/templates/ecommerce/src/components/Footer.tsx +11 -9
  27. package/templates/ecommerce/src/components/Navbar.tsx +32 -34
  28. package/templates/ecommerce/src/components/ProductCard.tsx +27 -38
  29. package/templates/ecommerce/src/styles.css +155 -36
  30. package/templates/starter/src/app/layout.tsx +5 -5
  31. package/templates/starter/src/app/page.tsx +114 -107
  32. package/templates/starter/src/components/FeatureCard.tsx +9 -15
  33. package/templates/starter/src/components/Footer.tsx +11 -9
  34. package/templates/starter/src/components/Header.tsx +15 -38
  35. package/templates/starter/src/styles.css +102 -27
@@ -2,59 +2,48 @@ import type { Product } from '../data/products.js';
2
2
 
3
3
  export function ProductCard({ product }: { product: Product }) {
4
4
  return (
5
- <div class="group rounded-xl border border-white/[0.08] bg-[#0f1117] overflow-hidden hover:border-white/[0.18] transition-all duration-200 flex flex-col justify-between shadow-[inset_0_1px_0_0_rgba(255,255,255,0.05)]">
6
- {/* Product Image Frame */}
7
- <a href={`/products/${product.id}`} class="block relative aspect-[4/3] overflow-hidden bg-zinc-950/60">
5
+ <article class="group">
6
+ <a href={`/products/${product.id}`} class="relative block w-full overflow-hidden rounded-lg aspect-square bg-[#f6f9fc] border border-[#e6ebf1]">
8
7
  <img
9
8
  src={product.image}
10
9
  alt={product.name}
11
- class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500 ease-out"
10
+ class="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
12
11
  loading="lazy"
13
12
  />
14
- <div class="absolute inset-0 bg-gradient-to-t from-black/40 via-transparent to-transparent pointer-events-none" />
15
- <span class="absolute top-3 left-3 px-2.5 py-0.5 rounded-full bg-[#090a0f]/85 backdrop-blur-md text-[10px] uppercase tracking-wider font-semibold text-zinc-300 border border-white/[0.08]">
16
- {product.category}
13
+ {product.inStock && (
14
+ <span class="bd absolute left-3 top-3 bg-white text-[#635bff] shadow-[0_2px_5px_-1px_rgba(50,50,93,0.25),0_1px_3px_-1px_rgba(0,0,0,0.3)]">
15
+ {product.category}
16
+ </span>
17
+ )}
18
+ <span class="absolute inset-x-3 bottom-3 rounded-md bg-white/95 py-1.5 text-center text-[13px] font-medium text-[#0a2540] opacity-0 shadow-[0_2px_5px_-1px_rgba(50,50,93,0.25),0_1px_3px_-1px_rgba(0,0,0,0.3)] transition-opacity group-hover:opacity-100">
19
+ Quick view
17
20
  </span>
18
21
  </a>
19
22
 
20
- {/* Product Details */}
21
- <div class="p-5 flex-1 flex flex-col justify-between">
23
+ <div class="mt-3 flex items-start justify-between gap-2">
22
24
  <div>
23
- {/* Subtle star & reviews */}
24
- <div class="flex items-center gap-1.5 mb-2 text-xs text-zinc-400 font-medium">
25
- <span class="text-amber-400 text-xs">★</span>
26
- <span class="text-zinc-200 tabular-nums">{product.rating.toFixed(1)}</span>
27
- <span class="text-zinc-600">•</span>
28
- <span class="text-zinc-500 tabular-nums">{product.reviewsCount} reviews</span>
29
- </div>
30
-
31
- <h3 class="font-semibold text-zinc-100 text-sm mb-2 group-hover:text-white transition-colors line-clamp-1">
32
- <a href={`/products/${product.id}`}>
25
+ <h3 class="font-medium text-[#0a2540] line-clamp-1">
26
+ <a href={`/products/${product.id}`} class="hover:text-[#635bff] transition-colors">
33
27
  {product.name}
34
28
  </a>
35
29
  </h3>
36
-
37
- <p class="text-zinc-400 text-xs leading-relaxed mb-4 line-clamp-2">
38
- {product.description}
30
+ <p class="text-[13px] text-[#425466]">
31
+ <span class="text-[#f5a623]">★</span> {product.rating.toFixed(1)} · {product.reviewsCount} reviews
39
32
  </p>
40
33
  </div>
34
+ <p class="font-mono text-[14px] text-[#0a2540] shrink-0 font-medium">
35
+ ${product.price.toFixed(2)}
36
+ </p>
37
+ </div>
41
38
 
42
- {/* Price & Action Row */}
43
- <div class="pt-4 border-t border-white/[0.06] flex items-center justify-between">
44
- <div>
45
- <span class="text-[10px] text-zinc-500 block uppercase tracking-wider font-medium">Price</span>
46
- <span class="text-base font-semibold text-white tabular-nums">${product.price.toFixed(2)}</span>
47
- </div>
48
-
49
- <a
50
- href={`/products/${product.id}`}
51
- class="px-3.5 py-1.5 rounded-lg bg-white text-zinc-950 font-medium text-xs hover:bg-zinc-200 transition-all shadow-sm flex items-center gap-1.5 group-hover:shadow"
52
- >
53
- <span>View</span>
54
- <span class="text-zinc-500">→</span>
55
- </a>
56
- </div>
39
+ <div class="mt-2.5 flex items-center gap-2">
40
+ <a
41
+ href="/cart"
42
+ class="btn btn-s w-full text-center py-1.5 text-xs font-medium"
43
+ >
44
+ Add to cart
45
+ </a>
57
46
  </div>
58
- </div>
47
+ </article>
59
48
  );
60
49
  }
@@ -4,58 +4,177 @@
4
4
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
5
5
  --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
6
6
 
7
- --color-brand-primary: #f4f4f5;
8
- --color-brand-hover: #ffffff;
7
+ --color-brand: #635bff;
8
+ --color-brand-hover: #5249e6;
9
+ --color-navy: #0a2540;
10
+ --color-slate: #425466;
11
+ --color-surface: #f6f9fc;
12
+ --color-hairline: #e6ebf1;
13
+ --color-cyan: #00d4ff;
14
+ --color-success: #24b47e;
15
+ --color-error: #cd3d64;
16
+ --color-warn: #c98a00;
9
17
  }
10
18
 
11
19
  :root {
12
- color-scheme: dark;
13
- --bg-canvas: #090a0f;
14
- --bg-surface: #0f1117;
15
- --bg-elevated: #151822;
16
- --border-subtle: rgba(255, 255, 255, 0.08);
17
- --border-strong: rgba(255, 255, 255, 0.16);
18
- --text-primary: #f4f4f5;
19
- --text-secondary: #9496a1;
20
- --text-muted: #5c6370;
21
- }
22
-
23
- html {
24
- background-color: var(--bg-canvas);
25
- color: var(--text-primary);
26
- font-family: var(--font-sans);
27
- scroll-behavior: smooth;
20
+ color-scheme: light;
21
+ --brand: #635bff;
22
+ --navy: #0a2540;
23
+ --slate: #425466;
24
+ --surface: #f6f9fc;
25
+ --hairline: #e6ebf1;
26
+ --cyan: #00d4ff;
27
+ --success: #24b47e;
28
+ --error: #cd3d64;
29
+
30
+ --shadow-card: 0 2px 5px -1px rgba(50, 50, 93, 0.25), 0 1px 3px -1px rgba(0, 0, 0, 0.3);
31
+ --shadow-pop: 0 13px 27px -5px rgba(50, 50, 93, 0.25), 0 8px 16px -8px rgba(0, 0, 0, 0.3);
32
+ }
33
+
34
+ body {
35
+ font-size: 15px;
36
+ line-height: 24px;
37
+ background-color: #ffffff;
38
+ color: #425466;
28
39
  -webkit-font-smoothing: antialiased;
29
40
  -moz-osx-font-smoothing: grayscale;
30
41
  }
31
42
 
43
+ :focus-visible {
44
+ outline: 2px solid #635bff;
45
+ outline-offset: 2px;
46
+ }
47
+
32
48
  /* Strict SVG safety to prevent flex ballooning */
33
49
  svg {
34
50
  flex-shrink: 0;
35
51
  max-width: 100%;
36
52
  }
37
53
 
38
- /* Stripe/Linear refined product card */
39
- .product-card {
40
- background-color: var(--bg-surface);
41
- border: 1px solid var(--border-subtle);
42
- border-radius: 0.75rem;
43
- box-shadow: inset 0 1px 0 0 rgba(255, 255, 255, 0.04);
44
- transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
54
+ /* Stripe Design Tokens & Utility Classes */
55
+ .btn {
56
+ display: inline-flex;
57
+ align-items: center;
58
+ justify-content: center;
59
+ gap: 0.5rem;
60
+ border-radius: 6px;
61
+ padding: 0.5rem 1rem;
62
+ font-size: 14px;
63
+ font-weight: 500;
64
+ transition: all 150ms cubic-bezier(0.215, 0.61, 0.355, 1);
65
+ cursor: pointer;
66
+ }
67
+ .btn:disabled {
68
+ opacity: 0.5;
69
+ cursor: not-allowed;
45
70
  }
46
71
 
47
- .product-card:hover {
48
- border-color: var(--border-strong);
49
- transform: translateY(-2px);
50
- box-shadow: 0 12px 24px -10px rgba(0, 0, 0, 0.5), inset 0 1px 0 0 rgba(255, 255, 255, 0.08);
72
+ .btn-p {
73
+ background-color: #635bff;
74
+ color: #ffffff;
75
+ box-shadow: var(--shadow-card);
76
+ }
77
+ .btn-p:hover:not(:disabled) {
78
+ background-color: #5249e6;
51
79
  }
52
80
 
53
- /* Accessibility: Mandatory Reduced Motion */
54
- @media (prefers-reduced-motion: reduce) {
55
- *, *::before, *::after {
56
- animation-duration: 0.01ms !important;
57
- animation-iteration-count: 1 !important;
58
- transition-duration: 0.01ms !important;
59
- scroll-behavior: auto !important;
81
+ .btn-s {
82
+ border: 1px solid #e6ebf1;
83
+ background-color: #ffffff;
84
+ color: #0a2540;
85
+ box-shadow: var(--shadow-card);
86
+ }
87
+ .btn-s:hover:not(:disabled) {
88
+ background-color: #f6f9fc;
89
+ }
90
+
91
+ .btn-n {
92
+ background-color: #0a2540;
93
+ color: #ffffff;
94
+ box-shadow: var(--shadow-card);
95
+ }
96
+ .btn-n:hover:not(:disabled) {
97
+ background-color: #425466;
98
+ }
99
+
100
+ .inp {
101
+ width: 100%;
102
+ border-radius: 6px;
103
+ border: 1px solid #e6ebf1;
104
+ background-color: #ffffff;
105
+ padding: 0.5rem 0.75rem;
106
+ font-size: 15px;
107
+ color: #0a2540;
108
+ outline: none;
109
+ transition: all 150ms cubic-bezier(0.215, 0.61, 0.355, 1);
110
+ }
111
+ .inp:focus {
112
+ border-color: #635bff;
113
+ box-shadow: 0 0 0 3px rgba(99, 91, 255, 0.25);
114
+ }
115
+ .inp.bad {
116
+ border-color: #cd3d64;
117
+ }
118
+ .inp.bad:focus {
119
+ box-shadow: 0 0 0 3px rgba(205, 61, 100, 0.2);
120
+ }
121
+
122
+ .bd {
123
+ display: inline-flex;
124
+ align-items: center;
125
+ border-radius: 9999px;
126
+ padding: 0.125rem 0.625rem;
127
+ font-size: 12px;
128
+ font-weight: 500;
129
+ }
130
+
131
+ .shadow-card {
132
+ box-shadow: var(--shadow-card);
133
+ }
134
+
135
+ .shadow-pop {
136
+ box-shadow: var(--shadow-pop);
137
+ }
138
+
139
+ dialog {
140
+ margin: auto;
141
+ width: calc(100% - 2rem);
142
+ max-width: 32rem;
143
+ border-radius: 8px;
144
+ border: 0;
145
+ background-color: #ffffff;
146
+ padding: 1.5rem;
147
+ color: #425466;
148
+ box-shadow: var(--shadow-pop);
149
+ }
150
+
151
+ dialog::backdrop {
152
+ background: rgba(10, 37, 64, 0.5);
153
+ }
154
+
155
+ dialog[open] {
156
+ animation: dlg 0.15s cubic-bezier(0.215, 0.61, 0.355, 1);
157
+ }
158
+
159
+ @keyframes dlg {
160
+ from {
161
+ opacity: 0;
162
+ transform: translateY(8px);
60
163
  }
61
164
  }
165
+
166
+ dialog.drawer {
167
+ margin-top: 0;
168
+ margin-bottom: 0;
169
+ margin-right: 0;
170
+ margin-left: auto;
171
+ display: flex;
172
+ height: 100%;
173
+ max-height: none;
174
+ width: 420px;
175
+ max-width: 100%;
176
+ flex-direction: column;
177
+ border-radius: 0;
178
+ border-top-left-radius: 8px;
179
+ border-bottom-left-radius: 8px;
180
+ }
@@ -9,13 +9,13 @@ export interface RootLayoutProps {
9
9
  }
10
10
 
11
11
  export default function RootLayout({ children, metadata }: RootLayoutProps) {
12
- const title = metadata?.title || 'FrootKit — Next.js Alternative for Preact';
12
+ const title = metadata?.title || 'FrootKit — The Preact Fullstack Framework';
13
13
  const description =
14
14
  metadata?.description ||
15
- 'Sub-millisecond Preact SSR, nested file-based layouts, native Tailwind CSS v4, and dynamic API routes.';
15
+ 'Sub-millisecond Preact SSR, native Tailwind CSS v4, and App Router conventions.';
16
16
 
17
17
  return (
18
- <html lang="en" class="dark scroll-smooth">
18
+ <html lang="en" class="scroll-smooth">
19
19
  <head>
20
20
  <meta charSet="UTF-8" />
21
21
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
@@ -24,12 +24,12 @@ export default function RootLayout({ children, metadata }: RootLayoutProps) {
24
24
  <link rel="preconnect" href="https://fonts.googleapis.com" />
25
25
  <link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
26
26
  <link
27
- href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap"
27
+ href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&family=JetBrains+Mono:wght@400;500&display=swap"
28
28
  rel="stylesheet"
29
29
  />
30
30
  <link rel="stylesheet" href="/styles.css" />
31
31
  </head>
32
- <body class="bg-[#08090a] text-zinc-100 min-h-screen antialiased selection:bg-indigo-500/20 selection:text-indigo-300 font-sans">
32
+ <body class="bg-white font-sans text-[#425466] antialiased">
33
33
  {children}
34
34
  </body>
35
35
  </html>
@@ -1,129 +1,136 @@
1
1
  import { Header } from '../components/Header.js';
2
2
  import { FeatureCard } from '../components/FeatureCard.js';
3
- import { TerminalPreview } from '../components/TerminalPreview.js';
4
3
  import { Footer } from '../components/Footer.js';
5
4
 
6
5
  export const metadata = {
7
- title: 'FrootKit — Next.js Alternative for Preact',
8
- description: 'Sub-millisecond Preact SSR, nested file-based layouts, native Tailwind CSS v4, and dynamic API routes.',
6
+ title: 'FrootKit — The Fullstack Preact Framework',
7
+ description: 'Sub-millisecond Preact SSR, native Tailwind CSS v4, and App Router conventions.',
9
8
  };
10
9
 
11
- export default function HomePage() {
10
+ export default function StarterPage() {
11
+ const features = [
12
+ {
13
+ title: 'Sub-Millisecond SSR',
14
+ description: 'Preact VNode rendering tuned for ultra-fast TTFB and zero unnecessary hydration overhead.',
15
+ icon: (
16
+ <svg class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
17
+ <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" />
18
+ </svg>
19
+ ),
20
+ badge: '0.42ms TTFB',
21
+ },
22
+ {
23
+ title: 'App Router Conventions',
24
+ description: 'Nested layouts, dynamic segments, loading boundaries, and standard web Request/Response route handlers.',
25
+ icon: (
26
+ <svg class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
27
+ <rect x="3" y="3" width="7" height="7" />
28
+ <rect x="14" y="3" width="7" height="7" />
29
+ <rect x="14" y="14" width="7" height="7" />
30
+ <rect x="3" y="14" width="7" height="7" />
31
+ </svg>
32
+ ),
33
+ badge: 'Next.js Parity',
34
+ },
35
+ {
36
+ title: 'Stripe Design System',
37
+ description: 'Polished FrootUI component library with multi-layer blue shadows and semantic tints built-in.',
38
+ icon: (
39
+ <svg class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
40
+ <path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5" />
41
+ </svg>
42
+ ),
43
+ badge: 'Zero Slop',
44
+ },
45
+ ];
46
+
12
47
  return (
13
- <div class="min-h-screen bg-[#08090a] text-zinc-100 flex flex-col justify-between selection:bg-indigo-500/20 selection:text-indigo-300">
48
+ <div class="bg-white font-sans text-[#425466]">
14
49
  <Header />
15
50
 
16
- <main class="max-w-6xl mx-auto px-6 py-16 sm:py-24 flex-1 flex flex-col justify-center">
17
- {/* Hero Section */}
18
- <div class="max-w-3xl mb-16">
19
- <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">
20
- <span class="w-1.5 h-1.5 rounded-full bg-indigo-400 animate-pulse" />
21
- <span>Next.js App Router Conventions • Zero Overhead</span>
51
+ {/* HERO SECTION */}
52
+ <section class="hero relative pb-44 pt-32 text-white md:pb-56">
53
+ <div class="mx-auto max-w-6xl px-6 grid items-center gap-14 lg:grid-cols-2">
54
+ <div class="rise">
55
+ <span class="bd bg-white/15 text-white">FrootKit 1.2 · Stripe Design System</span>
56
+ <h1 class="mt-5 text-[42px] font-light leading-[1.08] tracking-tight md:text-[56px] md:leading-[64px]">
57
+ The web framework built for precision engineering
58
+ </h1>
59
+ <p class="mt-6 max-w-md text-[18px] font-light leading-7 text-white/90">
60
+ Zero-bloat Preact SSR, native Tailwind CSS v4, and standard Web Crypto APIs packaged into a high-performance developer runtime.
61
+ </p>
62
+ <div class="mt-8 flex flex-wrap gap-3">
63
+ <a href="https://frootjs.org" class="btn btn-w">Read the Documentation</a>
64
+ <a href="/api/health" class="btn btn-gl font-mono text-xs">Test Health API</a>
65
+ </div>
66
+ <p class="mt-4 text-[13px] text-white/75">
67
+ Edit <code class="font-mono bg-white/10 px-1.5 py-0.5 rounded">src/app/page.tsx</code> to start building your application.
68
+ </p>
22
69
  </div>
23
70
 
24
- <h1 class="text-4xl sm:text-5xl lg:text-6xl font-semibold text-white tracking-[-0.03em] leading-[1.1] mb-6">
25
- The Next.js Alternative Built for Speed & Simplicity.
26
- </h1>
71
+ <div class="rise overflow-hidden rounded-lg bg-[#06182b] text-white/90 shadow-[0_13px_27px_-5px_rgba(50,50,93,0.25),0_8px_16px_-8px_rgba(0,0,0,0.3)]">
72
+ <div class="flex items-center gap-1.5 border-b border-white/10 bg-[#0a2540] px-4 py-2.5">
73
+ <i class="h-2.5 w-2.5 rounded-full bg-white/20" />
74
+ <i class="h-2.5 w-2.5 rounded-full bg-white/20" />
75
+ <i class="h-2.5 w-2.5 rounded-full bg-white/20" />
76
+ <span class="ml-3 font-mono text-[12px] text-white/70">terminal ~ frootkit dev</span>
77
+ </div>
78
+ <pre class="p-5 font-mono text-[13px] leading-6 overflow-x-auto">
79
+ <code>{`$ npx create-frootkit my-app
80
+ $ cd my-app && npm run dev
27
81
 
28
- <p class="text-base sm:text-lg text-zinc-400 leading-relaxed mb-8 max-w-2xl">
29
- Sub-millisecond Preact SSR, nested file-based layouts, native Tailwind CSS v4, dynamic API routes, and instant static site generation.
30
- </p>
82
+ ⚡ FrootKit v1.2.12 [Preact SSR Engine]
83
+ - Local: http://localhost:3000
84
+ - Network: http://192.168.1.5:3000
31
85
 
32
- <div class="flex flex-wrap items-center gap-3.5">
33
- <a
34
- href="https://frootjs.org"
35
- target="_blank"
36
- rel="noreferrer"
37
- 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"
38
- >
39
- <span>Explore Documentation</span>
40
- <span class="text-zinc-500 group-hover:translate-x-0.5 transition-transform">→</span>
41
- </a>
42
- <a
43
- href="https://github.com/orbitnorth/frootkit"
44
- target="_blank"
45
- rel="noreferrer"
46
- 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 flex items-center gap-2"
47
- >
48
- <svg style="width: 14px; height: 14px;" class="fill-current shrink-0" viewBox="0 0 24 24">
49
- <path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" />
50
- </svg>
51
- <span>Star on GitHub</span>
52
- </a>
86
+ ✓ Compiled src/app/page.tsx in 1.2ms
87
+ ✓ Tailwind CSS v4 styles active
88
+ ✓ Zero hydration mismatch`}</code>
89
+ </pre>
53
90
  </div>
54
91
  </div>
92
+ </section>
55
93
 
56
- <TerminalPreview />
57
-
58
- {/* Feature Grid with Precision 16px SVG Icons */}
59
- <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5">
60
- <FeatureCard
61
- badge="0.1ms render"
62
- title="Sub-Millisecond SSR"
63
- description="Preact VNode streaming and monomorphic rendering ensure blistering response times with near-zero memory footprint."
64
- >
65
- <svg style="width: 16px; height: 16px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
66
- <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" />
67
- </svg>
68
- </FeatureCard>
69
-
70
- <FeatureCard
71
- badge="Tailwind v4"
72
- title="Native CSS Pipeline"
73
- description="Zero postcss or tailwind config files required. Native Tailwind CSS v4 compiles in single-digit milliseconds."
74
- >
75
- <svg style="width: 16px; height: 16px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
76
- <path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5" />
77
- </svg>
78
- </FeatureCard>
79
-
80
- <FeatureCard
81
- badge="App Router"
82
- title="Nested File Layouts"
83
- description="Intuitive file-based routing with layout.tsx, page.tsx, and loading.tsx mirroring modern Next.js conventions."
84
- >
85
- <svg style="width: 16px; height: 16px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
86
- <rect x="3" y="3" width="18" height="18" rx="2" ry="2" />
87
- <line x1="9" y1="3" x2="9" y2="21" />
88
- </svg>
89
- </FeatureCard>
90
-
91
- <FeatureCard
92
- badge="Fullstack API"
93
- title="Dynamic Route Handlers"
94
- description="First-class Web Standard Request/Response handlers inside src/app/api/**/route.ts with JSON and SSE streaming."
95
- >
96
- <svg style="width: 16px; height: 16px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
97
- <polyline points="16 18 22 12 16 6" />
98
- <polyline points="8 6 2 12 8 18" />
99
- </svg>
100
- </FeatureCard>
101
-
102
- <FeatureCard
103
- badge="Pure Web Standards"
104
- title="Zero C++ Dependencies"
105
- description="Built entirely on pure ECMAScript and Web Crypto. Clean deployments to Node.js, Bun, and Edge runners."
106
- >
107
- <svg style="width: 16px; height: 16px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
108
- <circle cx="12" cy="12" r="10" />
109
- <line x1="2" y1="12" x2="22" y2="12" />
110
- <path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" />
111
- </svg>
112
- </FeatureCard>
94
+ {/* STATS */}
95
+ <section class="bg-[#f6f9fc] py-14">
96
+ <div class="mx-auto max-w-6xl px-6 grid gap-8 text-center sm:grid-cols-3">
97
+ <div>
98
+ <p class="font-mono text-[40px] font-light text-[#0a2540]">0.42ms</p>
99
+ <p class="text-[14px]">Sub-millisecond server rendering</p>
100
+ </div>
101
+ <div>
102
+ <p class="font-mono text-[40px] font-light text-[#0a2540]">3.2 kB</p>
103
+ <p class="text-[14px]">Ultra-lean Preact client runtime</p>
104
+ </div>
105
+ <div>
106
+ <p class="font-mono text-[40px] font-light text-[#0a2540]">100%</p>
107
+ <p class="text-[14px]">Web Standards API compatibility</p>
108
+ </div>
109
+ </div>
110
+ </section>
113
111
 
114
- <FeatureCard
115
- badge="Instant SSG"
116
- title="Static Site Export"
117
- description="Deterministic pre-rendering of static paths into deployable HTML assets with zero configuration."
118
- >
119
- <svg style="width: 16px; height: 16px;" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
120
- <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
121
- <polyline points="7 10 12 15 17 10" />
122
- <line x1="12" y1="15" x2="12" y2="3" />
123
- </svg>
124
- </FeatureCard>
112
+ {/* FEATURES */}
113
+ <section id="features" class="scroll-mt-16 py-24">
114
+ <div class="mx-auto max-w-6xl px-6">
115
+ <h2 class="text-[32px] font-light leading-[1.15] tracking-tight text-[#0a2540] md:text-[40px] max-w-2xl">
116
+ Engineered for high velocity, built with zero AI slop
117
+ </h2>
118
+ <p class="mt-4 max-w-xl text-[17px] leading-7">
119
+ Every token, font, shadow, and component has been modeled after Stripe's award-winning design system.
120
+ </p>
121
+ <div class="mt-12 grid gap-6 md:grid-cols-3">
122
+ {features.map((f) => (
123
+ <FeatureCard
124
+ key={f.title}
125
+ title={f.title}
126
+ description={f.description}
127
+ icon={f.icon}
128
+ badge={f.badge}
129
+ />
130
+ ))}
131
+ </div>
125
132
  </div>
126
- </main>
133
+ </section>
127
134
 
128
135
  <Footer />
129
136
  </div>
@@ -1,29 +1,23 @@
1
1
  import type { ComponentChildren } from 'preact';
2
2
 
3
3
  export interface FeatureCardProps {
4
- badge: string;
5
4
  title: string;
6
5
  description: string;
7
- children?: ComponentChildren;
6
+ icon?: ComponentChildren;
7
+ badge?: string;
8
8
  }
9
9
 
10
- export function FeatureCard({ badge, title, description, children }: FeatureCardProps) {
10
+ export function FeatureCard({ title, description, icon, badge }: FeatureCardProps) {
11
11
  return (
12
- <div class="rounded-xl border border-white/[0.08] bg-[#0f1117] p-5 hover:border-white/[0.18] transition-all shadow-[inset_0_1px_0_0_rgba(255,255,255,0.05)]">
12
+ <div 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)]">
13
13
  <div class="flex items-center justify-between mb-4">
14
- <div class="w-8 h-8 rounded-lg bg-indigo-500/10 border border-indigo-500/25 flex items-center justify-center text-indigo-400">
15
- {children}
16
- </div>
17
- <span class="text-[11px] font-medium px-2 py-0.5 rounded-full bg-white/[0.04] text-zinc-300 border border-white/[0.06]">
18
- {badge}
14
+ <span class="grid h-10 w-10 place-items-center rounded-md bg-[#635bff]/10 text-[#635bff]">
15
+ {icon}
19
16
  </span>
17
+ {badge && <span class="bd bg-[#635bff]/10 text-[#635bff]">{badge}</span>}
20
18
  </div>
21
- <h3 class="text-sm font-semibold text-white mb-1.5">
22
- {title}
23
- </h3>
24
- <p class="text-zinc-400 text-xs leading-relaxed">
25
- {description}
26
- </p>
19
+ <h3 class="text-[17px] font-medium text-[#0a2540]">{title}</h3>
20
+ <p class="mt-1 text-[14px] text-[#425466] leading-relaxed">{description}</p>
27
21
  </div>
28
22
  );
29
23
  }
@@ -1,14 +1,16 @@
1
1
  export function Footer() {
2
2
  return (
3
- <footer class="border-t border-white/[0.08] bg-[#08090a] py-8 text-xs text-zinc-500">
4
- <div class="max-w-6xl mx-auto px-6 flex flex-col sm:flex-row items-center justify-between gap-4">
5
- <div>
6
- FrootKit © {new Date().getFullYear()} OrbitNorth LLC. Built for high performance.
7
- </div>
8
- <div class="flex items-center gap-6">
9
- <a href="https://github.com/orbitnorth/frootkit" class="hover:text-zinc-300 transition-colors">GitHub</a>
10
- <a href="https://frootjs.org" class="hover:text-zinc-300 transition-colors">Documentation</a>
11
- <a href="/api/health" class="hover:text-zinc-300 transition-colors font-mono text-[11px]">/api/health</a>
3
+ <footer class="border-t border-[#e6ebf1] py-10 text-[14px] bg-white">
4
+ <div class="mx-auto max-w-6xl px-6 flex flex-wrap justify-between gap-4 text-xs text-[#425466]">
5
+ <span>
6
+ <b class="text-[#635bff] font-semibold text-sm">frootkit</b> · High-performance Preact fullstack web framework.
7
+ </span>
8
+ <div class="flex items-center gap-4">
9
+ <a href="https://frootjs.org" class="hover:text-[#0a2540]">Docs</a>
10
+ <span>·</span>
11
+ <a href="https://github.com/orbitnorth/frootkit" class="hover:text-[#0a2540]">GitHub</a>
12
+ <span>·</span>
13
+ <a href="/api/health" class="font-mono hover:text-[#0a2540]">/api/health</a>
12
14
  </div>
13
15
  </div>
14
16
  </footer>