create-cronus-app 0.6.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/LICENSE +21 -0
- package/README.md +173 -0
- package/dist/compose.d.ts +56 -0
- package/dist/compose.js +92 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +255 -0
- package/dist/scaffold.d.ts +31 -0
- package/dist/scaffold.js +118 -0
- package/dist/utils.d.ts +121 -0
- package/dist/utils.js +285 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.js +3 -0
- package/package.json +56 -0
- package/templates/dashboard/README.md +61 -0
- package/templates/dashboard/app/globals.css +16 -0
- package/templates/dashboard/app/layout.tsx +40 -0
- package/templates/dashboard/app/page.tsx +77 -0
- package/templates/dashboard/app/settings/page.tsx +21 -0
- package/templates/dashboard/components/dashboard-shell.tsx +120 -0
- package/templates/dashboard/components/orders-table.tsx +132 -0
- package/templates/dashboard/components/revenue-chart.tsx +50 -0
- package/templates/dashboard/components/settings-form.tsx +167 -0
- package/templates/dashboard/cronus-ui.json +17 -0
- package/templates/dashboard/gitignore +34 -0
- package/templates/dashboard/next.config.mjs +11 -0
- package/templates/dashboard/package.json +30 -0
- package/templates/dashboard/postcss.config.mjs +7 -0
- package/templates/dashboard/tsconfig.json +23 -0
- package/templates/default/README.md +46 -0
- package/templates/default/app/globals.css +16 -0
- package/templates/default/app/layout.tsx +39 -0
- package/templates/default/app/page.tsx +112 -0
- package/templates/default/cronus-ui.json +17 -0
- package/templates/default/gitignore +34 -0
- package/templates/default/next.config.mjs +11 -0
- package/templates/default/package.json +27 -0
- package/templates/default/postcss.config.mjs +7 -0
- package/templates/default/tsconfig.json +23 -0
- package/templates/marketing/README.md +65 -0
- package/templates/marketing/app/globals.css +16 -0
- package/templates/marketing/app/layout.tsx +39 -0
- package/templates/marketing/app/page.tsx +25 -0
- package/templates/marketing/components/faq.tsx +62 -0
- package/templates/marketing/components/feature-grid.tsx +67 -0
- package/templates/marketing/components/hero.tsx +61 -0
- package/templates/marketing/components/pricing.tsx +116 -0
- package/templates/marketing/components/site-footer.tsx +91 -0
- package/templates/marketing/components/site-header.tsx +47 -0
- package/templates/marketing/components/testimonials.tsx +91 -0
- package/templates/marketing/components/waitlist-cta.tsx +93 -0
- package/templates/marketing/cronus-ui.json +17 -0
- package/templates/marketing/gitignore +34 -0
- package/templates/marketing/next.config.mjs +11 -0
- package/templates/marketing/package.json +28 -0
- package/templates/marketing/postcss.config.mjs +7 -0
- package/templates/marketing/tsconfig.json +23 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "__APP_NAME__",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "next dev",
|
|
8
|
+
"build": "next build",
|
|
9
|
+
"start": "next start"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@cronus-ui/theme": "^0.6.0",
|
|
13
|
+
"@cronus-ui/tokens": "^0.6.0",
|
|
14
|
+
"@cronus-ui/ui": "^0.6.0",
|
|
15
|
+
"@tanstack/react-table": "^8.21.3",
|
|
16
|
+
"lucide-react": "^0.577.0",
|
|
17
|
+
"next": "16.2.10",
|
|
18
|
+
"react": "^19.2.0",
|
|
19
|
+
"react-dom": "^19.2.0",
|
|
20
|
+
"recharts": "^3.9.2"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@tailwindcss/postcss": "^4.3.0",
|
|
24
|
+
"@types/node": "^22.10.0",
|
|
25
|
+
"@types/react": "^19.0.0",
|
|
26
|
+
"@types/react-dom": "^19.0.0",
|
|
27
|
+
"tailwindcss": "^4.3.0",
|
|
28
|
+
"typescript": "^6.0.3"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["dom", "dom.iterable", "ES2022"],
|
|
5
|
+
"allowJs": true,
|
|
6
|
+
"skipLibCheck": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"noEmit": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"module": "esnext",
|
|
11
|
+
"moduleResolution": "bundler",
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"isolatedModules": true,
|
|
14
|
+
"jsx": "preserve",
|
|
15
|
+
"incremental": true,
|
|
16
|
+
"plugins": [{ "name": "next" }],
|
|
17
|
+
"paths": {
|
|
18
|
+
"@/*": ["./*"]
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
|
22
|
+
"exclude": ["node_modules"]
|
|
23
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# __APP_NAME__
|
|
2
|
+
|
|
3
|
+
A [Next.js](https://nextjs.org) (App Router) app built with
|
|
4
|
+
[Cronus UI](https://www.npmjs.com/package/@cronus-ui/ui) — themeable, accessible React
|
|
5
|
+
components on Tailwind v4.
|
|
6
|
+
|
|
7
|
+
## Getting started
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm install # or: pnpm install / yarn / bun install
|
|
11
|
+
npm run dev
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Open [http://localhost:3000](http://localhost:3000) and edit `app/page.tsx` — the page
|
|
15
|
+
hot-reloads as you save.
|
|
16
|
+
|
|
17
|
+
## How it's wired
|
|
18
|
+
|
|
19
|
+
- **`app/globals.css`** imports Tailwind and the Cronus token CSS, plus the required
|
|
20
|
+
`@source "../node_modules/@cronus-ui/ui/dist/**/*.js";` line so Tailwind v4 emits the
|
|
21
|
+
component utility classes (it skips `node_modules` by default).
|
|
22
|
+
- **`app/layout.tsx`** mounts `<CronusUIProvider>` (theme: Aurora) and the anti-flash
|
|
23
|
+
`<CronusThemeScript>` so the right theme is applied before hydration.
|
|
24
|
+
- **`app/page.tsx`** is a sample dashboard using `Button`, `Card`, `Badge`, `Input`,
|
|
25
|
+
`Metric`, and `Table` from `@cronus-ui/ui`.
|
|
26
|
+
|
|
27
|
+
## Add more components
|
|
28
|
+
|
|
29
|
+
This app includes a `cronus-ui.json`, so you can pull any component from the registry:
|
|
30
|
+
|
|
31
|
+
```sh
|
|
32
|
+
npx cronus-ui add dialog tabs dropdown-menu
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Scripts
|
|
36
|
+
|
|
37
|
+
| Script | Description |
|
|
38
|
+
| --- | --- |
|
|
39
|
+
| `dev` | Start the dev server. |
|
|
40
|
+
| `build` | Production build. |
|
|
41
|
+
| `start` | Serve the production build. |
|
|
42
|
+
|
|
43
|
+
## Learn more
|
|
44
|
+
|
|
45
|
+
- [Next.js documentation](https://nextjs.org/docs)
|
|
46
|
+
- [Tailwind CSS v4](https://tailwindcss.com)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
2
|
+
@import "@cronus-ui/tokens/styles.css";
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
* REQUIRED on Tailwind v4.
|
|
6
|
+
*
|
|
7
|
+
* Tailwind v4 does not scan node_modules by default, and @cronus-ui/ui ships its
|
|
8
|
+
* Tailwind class strings baked into pre-compiled JS under dist. Without the
|
|
9
|
+
* @source below, none of the component utility classes (bg-primary, rounded-lg,
|
|
10
|
+
* bg-surface-raised, …) would be emitted and the components would render
|
|
11
|
+
* unstyled.
|
|
12
|
+
*/
|
|
13
|
+
@source "../node_modules/@cronus-ui/ui/dist/**/*.js";
|
|
14
|
+
|
|
15
|
+
/* Scan this app's own source too. */
|
|
16
|
+
@source "./**/*.{ts,tsx}";
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { CronusThemeScript, CronusUIProvider } from "@cronus-ui/theme";
|
|
2
|
+
import type { Metadata } from "next";
|
|
3
|
+
import type { ReactNode } from "react";
|
|
4
|
+
import "./globals.css";
|
|
5
|
+
|
|
6
|
+
export const metadata: Metadata = {
|
|
7
|
+
title: "__APP_NAME__",
|
|
8
|
+
description: "A Next.js app built with Cronus UI.",
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default function RootLayout({ children }: { children: ReactNode }) {
|
|
12
|
+
return (
|
|
13
|
+
<html
|
|
14
|
+
lang="en"
|
|
15
|
+
// CronusThemeScript mutates <html> (theme/mode/dark class) before hydration
|
|
16
|
+
// to prevent a flash of the wrong theme, so React must not warn about the
|
|
17
|
+
// resulting attribute mismatch.
|
|
18
|
+
suppressHydrationWarning
|
|
19
|
+
>
|
|
20
|
+
<head>
|
|
21
|
+
<CronusThemeScript
|
|
22
|
+
storageKey="theme"
|
|
23
|
+
defaultThemeName="__THEME__"
|
|
24
|
+
defaultModeName="__MODE__"
|
|
25
|
+
/>
|
|
26
|
+
</head>
|
|
27
|
+
<body>
|
|
28
|
+
<CronusUIProvider
|
|
29
|
+
asRoot
|
|
30
|
+
defaultThemeName="__THEME__"
|
|
31
|
+
defaultModeName="__MODE__"
|
|
32
|
+
storageKey="theme"
|
|
33
|
+
>
|
|
34
|
+
{children}
|
|
35
|
+
</CronusUIProvider>
|
|
36
|
+
</body>
|
|
37
|
+
</html>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { Badge } from "@cronus-ui/ui/badge";
|
|
2
|
+
import { Button } from "@cronus-ui/ui/button";
|
|
3
|
+
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@cronus-ui/ui/card";
|
|
4
|
+
import { Input } from "@cronus-ui/ui/input";
|
|
5
|
+
import { Metric, MetricDelta, MetricLabel, MetricValue } from "@cronus-ui/ui/metric";
|
|
6
|
+
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@cronus-ui/ui/table";
|
|
7
|
+
|
|
8
|
+
const stats = [
|
|
9
|
+
{ label: "Revenue", value: "R$ 48.2k", delta: "+12.5%", trend: "up" as const },
|
|
10
|
+
{ label: "Active users", value: "2,318", delta: "+4.1%", trend: "up" as const },
|
|
11
|
+
{ label: "Churn", value: "1.8%", delta: "-0.3%", trend: "down" as const },
|
|
12
|
+
{ label: "NPS", value: "72", delta: "+6", trend: "up" as const },
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
const orders = [
|
|
16
|
+
{ id: "#1042", customer: "Ana Lima", status: "Paid", amount: "R$ 320,00" },
|
|
17
|
+
{ id: "#1041", customer: "Bruno Sá", status: "Pending", amount: "R$ 89,90" },
|
|
18
|
+
{ id: "#1040", customer: "Carla Reis", status: "Paid", amount: "R$ 1.249,00" },
|
|
19
|
+
{ id: "#1039", customer: "Diego Melo", status: "Refunded", amount: "R$ 59,00" },
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
const statusVariant = {
|
|
23
|
+
Paid: "success",
|
|
24
|
+
Pending: "warning",
|
|
25
|
+
Refunded: "destructive",
|
|
26
|
+
} as const;
|
|
27
|
+
|
|
28
|
+
export default function Page() {
|
|
29
|
+
return (
|
|
30
|
+
<main className="mx-auto flex min-h-screen w-full max-w-5xl flex-col gap-8 px-6 py-12">
|
|
31
|
+
<header className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
|
|
32
|
+
<div className="flex flex-col gap-2">
|
|
33
|
+
<Badge variant="primary" className="w-fit">
|
|
34
|
+
Built with Cronus UI
|
|
35
|
+
</Badge>
|
|
36
|
+
<h1 className="text-3xl font-semibold tracking-tight text-fg">Dashboard</h1>
|
|
37
|
+
<p className="max-w-prose text-fg-secondary">
|
|
38
|
+
A starter wired with <code className="text-fg">@cronus-ui/ui</code>, tokens, and the
|
|
39
|
+
theme provider. Edit <code className="text-fg">app/page.tsx</code> to make it yours.
|
|
40
|
+
</p>
|
|
41
|
+
</div>
|
|
42
|
+
<div className="flex gap-3">
|
|
43
|
+
<Button variant="outline">Docs</Button>
|
|
44
|
+
<Button variant="primary">New project</Button>
|
|
45
|
+
</div>
|
|
46
|
+
</header>
|
|
47
|
+
|
|
48
|
+
<section className="grid grid-cols-2 gap-4 lg:grid-cols-4">
|
|
49
|
+
{stats.map((stat) => (
|
|
50
|
+
<Card key={stat.label}>
|
|
51
|
+
<CardContent className="pt-6">
|
|
52
|
+
<Metric>
|
|
53
|
+
<MetricLabel>{stat.label}</MetricLabel>
|
|
54
|
+
<MetricValue>{stat.value}</MetricValue>
|
|
55
|
+
<MetricDelta trend={stat.trend}>{stat.delta}</MetricDelta>
|
|
56
|
+
</Metric>
|
|
57
|
+
</CardContent>
|
|
58
|
+
</Card>
|
|
59
|
+
))}
|
|
60
|
+
</section>
|
|
61
|
+
|
|
62
|
+
<section className="grid gap-6 lg:grid-cols-3">
|
|
63
|
+
<Card className="lg:col-span-2">
|
|
64
|
+
<CardHeader>
|
|
65
|
+
<CardTitle>Recent orders</CardTitle>
|
|
66
|
+
<CardDescription>Latest activity across your store.</CardDescription>
|
|
67
|
+
</CardHeader>
|
|
68
|
+
<CardContent>
|
|
69
|
+
<Table>
|
|
70
|
+
<TableHeader>
|
|
71
|
+
<TableRow>
|
|
72
|
+
<TableHead>Order</TableHead>
|
|
73
|
+
<TableHead>Customer</TableHead>
|
|
74
|
+
<TableHead>Status</TableHead>
|
|
75
|
+
<TableHead className="text-right">Amount</TableHead>
|
|
76
|
+
</TableRow>
|
|
77
|
+
</TableHeader>
|
|
78
|
+
<TableBody>
|
|
79
|
+
{orders.map((order) => (
|
|
80
|
+
<TableRow key={order.id}>
|
|
81
|
+
<TableCell className="font-medium">{order.id}</TableCell>
|
|
82
|
+
<TableCell>{order.customer}</TableCell>
|
|
83
|
+
<TableCell>
|
|
84
|
+
<Badge variant={statusVariant[order.status as keyof typeof statusVariant]}>
|
|
85
|
+
{order.status}
|
|
86
|
+
</Badge>
|
|
87
|
+
</TableCell>
|
|
88
|
+
<TableCell className="text-right">{order.amount}</TableCell>
|
|
89
|
+
</TableRow>
|
|
90
|
+
))}
|
|
91
|
+
</TableBody>
|
|
92
|
+
</Table>
|
|
93
|
+
</CardContent>
|
|
94
|
+
</Card>
|
|
95
|
+
|
|
96
|
+
<Card>
|
|
97
|
+
<CardHeader>
|
|
98
|
+
<CardTitle>Invite a teammate</CardTitle>
|
|
99
|
+
<CardDescription>Send an invite to collaborate.</CardDescription>
|
|
100
|
+
</CardHeader>
|
|
101
|
+
<CardContent className="flex flex-col gap-3">
|
|
102
|
+
<Input type="email" placeholder="name@company.com" aria-label="Teammate email" />
|
|
103
|
+
<Button className="w-full">Send invite</Button>
|
|
104
|
+
<p className="text-sm text-fg-secondary">
|
|
105
|
+
Add components anytime with <code className="text-fg">npx cronus-ui add</code>.
|
|
106
|
+
</p>
|
|
107
|
+
</CardContent>
|
|
108
|
+
</Card>
|
|
109
|
+
</section>
|
|
110
|
+
</main>
|
|
111
|
+
);
|
|
112
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"aliases": {
|
|
3
|
+
"ui": "@/components/ui",
|
|
4
|
+
"lib": "@/lib",
|
|
5
|
+
"blocks": "@/components/blocks"
|
|
6
|
+
},
|
|
7
|
+
"paths": {
|
|
8
|
+
"ui": "components/ui",
|
|
9
|
+
"lib": "lib",
|
|
10
|
+
"blocks": "components/blocks"
|
|
11
|
+
},
|
|
12
|
+
"registry": "https://raw.githubusercontent.com/pedrogbraz/cronus-ui/v0.6.0/registry",
|
|
13
|
+
"theme": {
|
|
14
|
+
"name": "__THEME__",
|
|
15
|
+
"mode": "__MODE__"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# dependencies
|
|
2
|
+
/node_modules
|
|
3
|
+
/.pnp
|
|
4
|
+
.pnp.*
|
|
5
|
+
|
|
6
|
+
# next.js
|
|
7
|
+
/.next/
|
|
8
|
+
/out/
|
|
9
|
+
|
|
10
|
+
# production
|
|
11
|
+
/build
|
|
12
|
+
|
|
13
|
+
# misc
|
|
14
|
+
.DS_Store
|
|
15
|
+
*.pem
|
|
16
|
+
|
|
17
|
+
# debug
|
|
18
|
+
npm-debug.log*
|
|
19
|
+
yarn-debug.log*
|
|
20
|
+
yarn-error.log*
|
|
21
|
+
.pnpm-debug.log*
|
|
22
|
+
|
|
23
|
+
# env files
|
|
24
|
+
.env*.local
|
|
25
|
+
|
|
26
|
+
# typescript
|
|
27
|
+
*.tsbuildinfo
|
|
28
|
+
next-env.d.ts
|
|
29
|
+
|
|
30
|
+
# lockfiles (keep the one your package manager writes)
|
|
31
|
+
# package-lock.json
|
|
32
|
+
# pnpm-lock.yaml
|
|
33
|
+
# yarn.lock
|
|
34
|
+
# bun.lockb
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @cronus-ui/ui ships ESM with its `"use client"` boundaries already in place,
|
|
3
|
+
* so no `transpilePackages` is needed when it's installed (the normal case).
|
|
4
|
+
*
|
|
5
|
+
* @type {import('next').NextConfig}
|
|
6
|
+
*/
|
|
7
|
+
const nextConfig = {
|
|
8
|
+
reactStrictMode: true,
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default nextConfig;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "__APP_NAME__",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "next dev",
|
|
8
|
+
"build": "next build",
|
|
9
|
+
"start": "next start"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@cronus-ui/theme": "^0.6.0",
|
|
13
|
+
"@cronus-ui/tokens": "^0.6.0",
|
|
14
|
+
"@cronus-ui/ui": "^0.6.0",
|
|
15
|
+
"next": "16.2.10",
|
|
16
|
+
"react": "^19.2.0",
|
|
17
|
+
"react-dom": "^19.2.0"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@tailwindcss/postcss": "^4.3.0",
|
|
21
|
+
"@types/node": "^22.10.0",
|
|
22
|
+
"@types/react": "^19.0.0",
|
|
23
|
+
"@types/react-dom": "^19.0.0",
|
|
24
|
+
"tailwindcss": "^4.3.0",
|
|
25
|
+
"typescript": "^6.0.3"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["dom", "dom.iterable", "ES2022"],
|
|
5
|
+
"allowJs": true,
|
|
6
|
+
"skipLibCheck": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"noEmit": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"module": "esnext",
|
|
11
|
+
"moduleResolution": "bundler",
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"isolatedModules": true,
|
|
14
|
+
"jsx": "preserve",
|
|
15
|
+
"incremental": true,
|
|
16
|
+
"plugins": [{ "name": "next" }],
|
|
17
|
+
"paths": {
|
|
18
|
+
"@/*": ["./*"]
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
|
22
|
+
"exclude": ["node_modules"]
|
|
23
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# __APP_NAME__
|
|
2
|
+
|
|
3
|
+
A landing site built with [Next.js](https://nextjs.org) (App Router) and
|
|
4
|
+
[Cronus UI](https://www.npmjs.com/package/@cronus-ui/ui) — themeable, accessible React
|
|
5
|
+
components on Tailwind v4.
|
|
6
|
+
|
|
7
|
+
> **Screenshot placeholder** — run `npm run dev`, open http://localhost:3000, and drop a
|
|
8
|
+
> capture here (e.g. `docs/screenshot.png`) so your repo landing page shows the site.
|
|
9
|
+
|
|
10
|
+
## Getting started
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
npm install # or: pnpm install / yarn / bun install
|
|
14
|
+
npm run dev
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Open [http://localhost:3000](http://localhost:3000) — the page hot-reloads as you save.
|
|
18
|
+
|
|
19
|
+
## What's inside
|
|
20
|
+
|
|
21
|
+
One landing page (`app/page.tsx`) composed from real sections under `components/`:
|
|
22
|
+
|
|
23
|
+
| Section | File | Contents |
|
|
24
|
+
| --- | --- | --- |
|
|
25
|
+
| Header | `site-header.tsx` | Sticky translucent nav with anchor links and the CTA. |
|
|
26
|
+
| Hero | `hero.tsx` | Announcement badge, display headline, CTAs, social proof. |
|
|
27
|
+
| Features | `feature-grid.tsx` | Six capability cards with gradient icon chips. |
|
|
28
|
+
| Pricing | `pricing.tsx` | Three tiers with a featured card. |
|
|
29
|
+
| Testimonials | `testimonials.tsx` | Quote cards in a responsive grid. |
|
|
30
|
+
| FAQ | `faq.tsx` | Single-open `Accordion`. |
|
|
31
|
+
| Waitlist | `waitlist-cta.tsx` | Email capture with a joined confirmation state. |
|
|
32
|
+
| Footer | `site-footer.tsx` | Brand, link columns, legal bar. |
|
|
33
|
+
|
|
34
|
+
Every section is standalone — delete what you don't need, reorder freely, and swap the
|
|
35
|
+
copy for your product.
|
|
36
|
+
|
|
37
|
+
## How it's wired
|
|
38
|
+
|
|
39
|
+
- **`app/globals.css`** imports Tailwind and the Cronus token CSS, plus the required
|
|
40
|
+
`@source "../node_modules/@cronus-ui/ui/dist/**/*.js";` line so Tailwind v4 emits the
|
|
41
|
+
component utility classes (it skips `node_modules` by default).
|
|
42
|
+
- **`app/layout.tsx`** mounts `<CronusUIProvider>` and the anti-flash `<CronusThemeScript>`
|
|
43
|
+
so the right theme is applied before hydration.
|
|
44
|
+
- Only `waitlist-cta.tsx` is a client component — everything else renders on the server.
|
|
45
|
+
|
|
46
|
+
## Add more components
|
|
47
|
+
|
|
48
|
+
This app includes a `cronus-ui.json`, so you can pull any component from the registry:
|
|
49
|
+
|
|
50
|
+
```sh
|
|
51
|
+
npx cronus-ui add dialog tabs marquee
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Scripts
|
|
55
|
+
|
|
56
|
+
| Script | Description |
|
|
57
|
+
| --- | --- |
|
|
58
|
+
| `dev` | Start the dev server. |
|
|
59
|
+
| `build` | Production build. |
|
|
60
|
+
| `start` | Serve the production build. |
|
|
61
|
+
|
|
62
|
+
## Learn more
|
|
63
|
+
|
|
64
|
+
- [Next.js documentation](https://nextjs.org/docs)
|
|
65
|
+
- [Tailwind CSS v4](https://tailwindcss.com)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
2
|
+
@import "@cronus-ui/tokens/styles.css";
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
* REQUIRED on Tailwind v4.
|
|
6
|
+
*
|
|
7
|
+
* Tailwind v4 does not scan node_modules by default, and @cronus-ui/ui ships its
|
|
8
|
+
* Tailwind class strings baked into pre-compiled JS under dist. Without the
|
|
9
|
+
* @source below, none of the component utility classes (bg-primary, rounded-lg,
|
|
10
|
+
* bg-surface-raised, …) would be emitted and the components would render
|
|
11
|
+
* unstyled.
|
|
12
|
+
*/
|
|
13
|
+
@source "../node_modules/@cronus-ui/ui/dist/**/*.js";
|
|
14
|
+
|
|
15
|
+
/* Scan this app's own source too. */
|
|
16
|
+
@source "./**/*.{ts,tsx}";
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { CronusThemeScript, CronusUIProvider } from "@cronus-ui/theme";
|
|
2
|
+
import type { Metadata } from "next";
|
|
3
|
+
import type { ReactNode } from "react";
|
|
4
|
+
import "./globals.css";
|
|
5
|
+
|
|
6
|
+
export const metadata: Metadata = {
|
|
7
|
+
title: "__APP_NAME__",
|
|
8
|
+
description: "A landing site built with Cronus UI.",
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default function RootLayout({ children }: { children: ReactNode }) {
|
|
12
|
+
return (
|
|
13
|
+
<html
|
|
14
|
+
lang="en"
|
|
15
|
+
// CronusThemeScript mutates <html> (theme/mode/dark class) before hydration
|
|
16
|
+
// to prevent a flash of the wrong theme, so React must not warn about the
|
|
17
|
+
// resulting attribute mismatch.
|
|
18
|
+
suppressHydrationWarning
|
|
19
|
+
>
|
|
20
|
+
<head>
|
|
21
|
+
<CronusThemeScript
|
|
22
|
+
storageKey="theme"
|
|
23
|
+
defaultThemeName="__THEME__"
|
|
24
|
+
defaultModeName="__MODE__"
|
|
25
|
+
/>
|
|
26
|
+
</head>
|
|
27
|
+
<body>
|
|
28
|
+
<CronusUIProvider
|
|
29
|
+
asRoot
|
|
30
|
+
defaultThemeName="__THEME__"
|
|
31
|
+
defaultModeName="__MODE__"
|
|
32
|
+
storageKey="theme"
|
|
33
|
+
>
|
|
34
|
+
{children}
|
|
35
|
+
</CronusUIProvider>
|
|
36
|
+
</body>
|
|
37
|
+
</html>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Faq } from "../components/faq";
|
|
2
|
+
import { FeatureGrid } from "../components/feature-grid";
|
|
3
|
+
import { Hero } from "../components/hero";
|
|
4
|
+
import { Pricing } from "../components/pricing";
|
|
5
|
+
import { SiteFooter } from "../components/site-footer";
|
|
6
|
+
import { SiteHeader } from "../components/site-header";
|
|
7
|
+
import { Testimonials } from "../components/testimonials";
|
|
8
|
+
import { WaitlistCta } from "../components/waitlist-cta";
|
|
9
|
+
|
|
10
|
+
export default function LandingPage() {
|
|
11
|
+
return (
|
|
12
|
+
<div className="min-h-screen bg-surface-base text-fg">
|
|
13
|
+
<SiteHeader />
|
|
14
|
+
<main id="main-content">
|
|
15
|
+
<Hero />
|
|
16
|
+
<FeatureGrid />
|
|
17
|
+
<Pricing />
|
|
18
|
+
<Testimonials />
|
|
19
|
+
<Faq />
|
|
20
|
+
<WaitlistCta />
|
|
21
|
+
</main>
|
|
22
|
+
<SiteFooter />
|
|
23
|
+
</div>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Accordion,
|
|
3
|
+
AccordionContent,
|
|
4
|
+
AccordionItem,
|
|
5
|
+
AccordionTrigger,
|
|
6
|
+
} from "@cronus-ui/ui/accordion";
|
|
7
|
+
import { Badge } from "@cronus-ui/ui/badge";
|
|
8
|
+
|
|
9
|
+
const FAQ_ITEMS = [
|
|
10
|
+
{
|
|
11
|
+
question: "What exactly do I get?",
|
|
12
|
+
answer:
|
|
13
|
+
"A production-ready product with a themeable design system underneath. Add what you need with the CLI and everything inherits your tokens, radius, and color scale automatically.",
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
question: "Does it work with my existing stack?",
|
|
17
|
+
answer:
|
|
18
|
+
"Yes. The components are React built on accessible primitives and Tailwind, so they drop into Next.js, Remix, Vite, or any modern React setup.",
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
question: "How do themes work?",
|
|
22
|
+
answer:
|
|
23
|
+
"Themes are driven entirely by CSS tokens. Swap a palette and every surface, border, and gradient updates live — no per-component overrides and no rebuild required.",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
question: "Is everything accessible out of the box?",
|
|
27
|
+
answer:
|
|
28
|
+
"Accessibility is the default, not an add-on. Focus management, keyboard interaction, and ARIA semantics are built in, so you pass audits without a last-minute scramble.",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
question: "Can I cancel anytime?",
|
|
32
|
+
answer:
|
|
33
|
+
"Absolutely. Plans are month-to-month with no lock-in, and anything you've already added to your codebase is yours to keep.",
|
|
34
|
+
},
|
|
35
|
+
] as const;
|
|
36
|
+
|
|
37
|
+
/** Single-open accordion of the questions prospects actually ask. */
|
|
38
|
+
export function Faq() {
|
|
39
|
+
return (
|
|
40
|
+
<section id="faq" className="scroll-mt-16 px-6 py-20">
|
|
41
|
+
<div className="mx-auto max-w-2xl text-center">
|
|
42
|
+
<Badge variant="secondary">FAQ</Badge>
|
|
43
|
+
<h2 className="mt-4 font-display text-4xl font-semibold tracking-tight text-fg">
|
|
44
|
+
Frequently asked questions
|
|
45
|
+
</h2>
|
|
46
|
+
<p className="mt-4 text-balance text-fg-secondary">
|
|
47
|
+
Everything you need to know about the product and billing. Can't find an answer?
|
|
48
|
+
Reach out to our team.
|
|
49
|
+
</p>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<Accordion type="single" collapsible className="mx-auto mt-12 max-w-2xl">
|
|
53
|
+
{FAQ_ITEMS.map((item) => (
|
|
54
|
+
<AccordionItem key={item.question} value={item.question}>
|
|
55
|
+
<AccordionTrigger>{item.question}</AccordionTrigger>
|
|
56
|
+
<AccordionContent>{item.answer}</AccordionContent>
|
|
57
|
+
</AccordionItem>
|
|
58
|
+
))}
|
|
59
|
+
</Accordion>
|
|
60
|
+
</section>
|
|
61
|
+
);
|
|
62
|
+
}
|