gradient-forge 1.0.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/.eslintrc.json +3 -0
- package/.github/FUNDING.yml +2 -0
- package/README.md +140 -0
- package/app/docs/page.tsx +417 -0
- package/app/gallery/page.tsx +398 -0
- package/app/globals.css +1155 -0
- package/app/layout.tsx +36 -0
- package/app/page.tsx +600 -0
- package/app/showcase/page.tsx +730 -0
- package/app/studio/page.tsx +1310 -0
- package/cli/index.mjs +1141 -0
- package/cli/templates/theme-context.tsx +120 -0
- package/cli/templates/theme-engine.ts +237 -0
- package/cli/templates/themes.css +512 -0
- package/components/site/component-showcase.tsx +623 -0
- package/components/site/site-data.ts +103 -0
- package/components/site/site-header.tsx +270 -0
- package/components/templates/blog.tsx +198 -0
- package/components/templates/components-showcase.tsx +298 -0
- package/components/templates/dashboard.tsx +246 -0
- package/components/templates/ecommerce.tsx +199 -0
- package/components/templates/mail.tsx +275 -0
- package/components/templates/saas-landing.tsx +169 -0
- package/components/theme/studio-code-panel.tsx +485 -0
- package/components/theme/theme-context.tsx +120 -0
- package/components/theme/theme-engine.ts +237 -0
- package/components/theme/theme-exporter.tsx +369 -0
- package/components/theme/theme-panel.tsx +268 -0
- package/components/theme/token-export-utils.ts +1211 -0
- package/components/ui/animated.tsx +55 -0
- package/components/ui/avatar.tsx +38 -0
- package/components/ui/badge.tsx +32 -0
- package/components/ui/button.tsx +65 -0
- package/components/ui/card.tsx +56 -0
- package/components/ui/checkbox.tsx +19 -0
- package/components/ui/command-palette.tsx +245 -0
- package/components/ui/gsap-animated.tsx +436 -0
- package/components/ui/input.tsx +17 -0
- package/components/ui/select.tsx +176 -0
- package/components/ui/skeleton.tsx +102 -0
- package/components/ui/switch.tsx +43 -0
- package/components/ui/tabs.tsx +115 -0
- package/components/ui/toast.tsx +119 -0
- package/gradient-forge/theme-context.tsx +119 -0
- package/gradient-forge/theme-engine.ts +236 -0
- package/gradient-forge/themes.css +556 -0
- package/lib/animations.ts +50 -0
- package/lib/gsap.ts +426 -0
- package/lib/utils.ts +6 -0
- package/next-env.d.ts +6 -0
- package/next.config.mjs +6 -0
- package/package.json +53 -0
- package/postcss.config.mjs +5 -0
- package/tailwind.config.ts +15 -0
- package/tsconfig.json +43 -0
- package/tsconfig.tsbuildinfo +1 -0
package/.eslintrc.json
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://capsule-render.vercel.app/api?type=waving&color=0:7C5CFF,100:2ED1C4&height=220§ion=header&text=Gradient%20Forge&fontSize=48&fontAlignY=38&desc=Custom%20Shadcn%20Theming%20System&descAlignY=62" alt="Gradient Forge" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://buymeacoffee.com/karannn">
|
|
7
|
+
<img src="https://img.shields.io/badge/Buy%20Me%20a%20Coffee-Support-orange?style=for-the-badge&logo=buymeacoffee&logoColor=white" alt="Buy Me a Coffee" />
|
|
8
|
+
</a>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<div align="center">
|
|
12
|
+
<strong>Gradient Forge</strong>
|
|
13
|
+
<div>Production-ready theming system with Nitro-inspired gradients, surface-aware layers, and export-ready tokens.</div>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Highlights
|
|
19
|
+
|
|
20
|
+
- 20+ curated gradient themes with a secret Memory Lane unlock.
|
|
21
|
+
- Light/dark mode with persisted state.
|
|
22
|
+
- Surface overlays tuned for cards, sidebars, and popovers.
|
|
23
|
+
- Export snippets for CSS + Tailwind token mapping.
|
|
24
|
+
- Gallery-ready previews for each theme preset.
|
|
25
|
+
|
|
26
|
+
## Demo
|
|
27
|
+
|
|
28
|
+
The app is fully multi-page. Explore:
|
|
29
|
+
|
|
30
|
+
- `/` Home
|
|
31
|
+
- `/studio` Interactive theme studio
|
|
32
|
+
- `/gallery` Theme gallery
|
|
33
|
+
- `/showcase` Template showcase with live previews
|
|
34
|
+
- `/docs` Installation and CLI documentation
|
|
35
|
+
|
|
36
|
+
## Quick Start
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install
|
|
40
|
+
npm run dev
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## What You Get
|
|
44
|
+
|
|
45
|
+
- Theme engine with `data-theme` and `data-color-mode` attributes.
|
|
46
|
+
- Gradient tokens and surface layers in `app/globals.css`.
|
|
47
|
+
- A full preview dashboard showing shadcn-style components.
|
|
48
|
+
- Copy-ready export snippets for your own repos.
|
|
49
|
+
|
|
50
|
+
## Architecture
|
|
51
|
+
|
|
52
|
+
- `app/page.tsx` - Home experience and component previews.
|
|
53
|
+
- `app/studio/page.tsx` - Interactive theme studio.
|
|
54
|
+
- `app/gallery/page.tsx` - Gradient gallery.
|
|
55
|
+
- `app/showcase/page.tsx` - Template showcase with live theme previews.
|
|
56
|
+
- `app/docs/page.tsx` - Installation and CLI documentation.
|
|
57
|
+
- `app/globals.css` - Gradient tokens, theme classes, and surface overlays.
|
|
58
|
+
- `components/theme/theme-engine.ts` - Theme catalog + persistence helpers.
|
|
59
|
+
- `components/theme/theme-context.tsx` - Client state + unlock logic.
|
|
60
|
+
- `components/theme/theme-panel.tsx` - UI for theme selection and mode toggle.
|
|
61
|
+
- `components/theme/theme-exporter.tsx` - Copy-ready export blocks.
|
|
62
|
+
|
|
63
|
+
## Installation
|
|
64
|
+
|
|
65
|
+
### Option 1: CLI (Recommended)
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npx gradient-forge@latest init --inject
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
CLI options:
|
|
72
|
+
- `--inject` adds the theme CSS to `app/globals.css` automatically
|
|
73
|
+
- `--no-inject` skips modifying `app/globals.css`
|
|
74
|
+
- `--path` targets a custom project root
|
|
75
|
+
- `--force` overwrites existing generated files
|
|
76
|
+
- `--yes` skips prompts and applies defaults
|
|
77
|
+
- `--tui` enables arrow-key selector mode
|
|
78
|
+
|
|
79
|
+
### Option 2: Manual Installation
|
|
80
|
+
|
|
81
|
+
Copy these files to your project:
|
|
82
|
+
|
|
83
|
+
| File | Description |
|
|
84
|
+
|------|-------------|
|
|
85
|
+
| `components/theme/theme-engine.ts` | Core theme logic & 20+ theme definitions |
|
|
86
|
+
| `components/theme/theme-context.tsx` | React context provider with persistence |
|
|
87
|
+
| `components/theme/token-export-utils.ts` | Export utilities for all token formats |
|
|
88
|
+
| `app/globals.css` | CSS variables & theme classes (merge with your existing) |
|
|
89
|
+
|
|
90
|
+
**Integration Steps:**
|
|
91
|
+
|
|
92
|
+
1. Copy the 3 theme files to your `components/theme/` folder
|
|
93
|
+
2. Merge the CSS from `globals.css` into your `app/globals.css`
|
|
94
|
+
3. Wrap your app with `ThemeProvider`:
|
|
95
|
+
```tsx
|
|
96
|
+
import { ThemeProvider } from '@/components/theme/theme-context';
|
|
97
|
+
|
|
98
|
+
export default function RootLayout({ children }) {
|
|
99
|
+
return (
|
|
100
|
+
<ThemeProvider>
|
|
101
|
+
{children}
|
|
102
|
+
</ThemeProvider>
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
4. Add theme classes to your HTML root element:
|
|
107
|
+
```html
|
|
108
|
+
<html class="dark theme-nitro-midnight-blurple" data-theme="theme-nitro-midnight-blurple" data-color-mode="dark">
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Add A New Theme
|
|
112
|
+
|
|
113
|
+
1. Add a new entry in `components/theme/theme-engine.ts`.
|
|
114
|
+
2. Create the matching CSS class in `app/globals.css`.
|
|
115
|
+
3. The gallery and theme picker update automatically.
|
|
116
|
+
|
|
117
|
+
## Export Snippets
|
|
118
|
+
|
|
119
|
+
Open the Export section in the app to copy snippets for:
|
|
120
|
+
|
|
121
|
+
- Root theme attributes
|
|
122
|
+
- Surface tint styling
|
|
123
|
+
- Tailwind color token aliases
|
|
124
|
+
|
|
125
|
+
## Scripts
|
|
126
|
+
|
|
127
|
+
- `npm run dev` - Start the dev server.
|
|
128
|
+
- `npm run build` - Build for production.
|
|
129
|
+
- `npm run start` - Run the production build.
|
|
130
|
+
- `npm run lint` - Lint the codebase.
|
|
131
|
+
|
|
132
|
+
## Support
|
|
133
|
+
|
|
134
|
+
If Gradient Forge helps your project, you can support development here:
|
|
135
|
+
|
|
136
|
+
- `https://buymeacoffee.com/karannn`
|
|
137
|
+
|
|
138
|
+
## License
|
|
139
|
+
|
|
140
|
+
Add your preferred license before publishing.
|
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useRef, useState } from "react";
|
|
4
|
+
import gsap from "gsap";
|
|
5
|
+
import { ScrollTrigger } from "gsap/ScrollTrigger";
|
|
6
|
+
import { SiteHeader } from "@/components/site/site-header";
|
|
7
|
+
import { Badge } from "@/components/ui/badge";
|
|
8
|
+
import { Button } from "@/components/ui/button";
|
|
9
|
+
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
10
|
+
import {
|
|
11
|
+
AnimatedSection,
|
|
12
|
+
StaggerContainer,
|
|
13
|
+
MagneticButton
|
|
14
|
+
} from "@/components/ui/gsap-animated";
|
|
15
|
+
import {
|
|
16
|
+
FileText,
|
|
17
|
+
Terminal,
|
|
18
|
+
Copy,
|
|
19
|
+
Check,
|
|
20
|
+
ArrowRight,
|
|
21
|
+
Package,
|
|
22
|
+
Settings,
|
|
23
|
+
Trash2,
|
|
24
|
+
Sparkles,
|
|
25
|
+
ChevronRight,
|
|
26
|
+
BookOpen
|
|
27
|
+
} from "lucide-react";
|
|
28
|
+
import { useToast } from "@/components/ui/toast";
|
|
29
|
+
|
|
30
|
+
if (typeof window !== "undefined") {
|
|
31
|
+
gsap.registerPlugin(ScrollTrigger);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const runners = [
|
|
35
|
+
{ label: "npx", command: "npx gradient-forge@latest init --inject", comingSoon: true },
|
|
36
|
+
{ label: "pnpm", command: "pnpm dlx gradient-forge@latest init --inject", comingSoon: true },
|
|
37
|
+
{ label: "yarn", command: "yarn dlx gradient-forge@latest init --inject", comingSoon: true },
|
|
38
|
+
{ label: "bun", command: "bunx gradient-forge@latest init --inject", comingSoon: true },
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
const installationSteps = [
|
|
42
|
+
{
|
|
43
|
+
step: 1,
|
|
44
|
+
title: "Copy Theme Files",
|
|
45
|
+
description: "Copy the 3 theme files into your project",
|
|
46
|
+
action: "Copy Files",
|
|
47
|
+
files: [
|
|
48
|
+
"components/theme/theme-engine.ts",
|
|
49
|
+
"components/theme/theme-context.tsx",
|
|
50
|
+
"components/theme/token-export-utils.ts"
|
|
51
|
+
]
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
step: 2,
|
|
55
|
+
title: "Add CSS Variables",
|
|
56
|
+
description: "Merge theme CSS into your globals.css",
|
|
57
|
+
action: "Get CSS",
|
|
58
|
+
highlight: "Required for themes to work"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
step: 3,
|
|
62
|
+
title: "Wrap with Provider",
|
|
63
|
+
description: "Add ThemeProvider to your app layout",
|
|
64
|
+
action: "View Code",
|
|
65
|
+
code: `<ThemeProvider>
|
|
66
|
+
{children}
|
|
67
|
+
</ThemeProvider>`
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
step: 4,
|
|
71
|
+
title: "Set Theme Class",
|
|
72
|
+
description: "Add theme class to your HTML root",
|
|
73
|
+
action: "Copy Class",
|
|
74
|
+
code: `class="dark theme-nitro-midnight-blurple"`
|
|
75
|
+
}
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
const cliOptions = [
|
|
79
|
+
{ flag: "--inject", desc: "Adds theme CSS to app/globals.css" },
|
|
80
|
+
{ flag: "--no-inject", desc: "Keeps globals.css unchanged" },
|
|
81
|
+
{ flag: "--path", desc: "Targets custom project root" },
|
|
82
|
+
{ flag: "--force", desc: "Overwrites existing files" },
|
|
83
|
+
{ flag: "--yes", desc: "Skips prompts, uses defaults" },
|
|
84
|
+
{ flag: "--tui", desc: "Arrow-key selector mode" },
|
|
85
|
+
];
|
|
86
|
+
|
|
87
|
+
export default function DocsPage() {
|
|
88
|
+
const { showToast } = useToast();
|
|
89
|
+
const [copiedCommand, setCopiedCommand] = useState<string | null>(null);
|
|
90
|
+
const contentRef = useRef<HTMLDivElement>(null);
|
|
91
|
+
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
const content = contentRef.current;
|
|
94
|
+
if (!content) return;
|
|
95
|
+
|
|
96
|
+
// Animate cards on scroll
|
|
97
|
+
const cards = content.querySelectorAll(".doc-card");
|
|
98
|
+
gsap.fromTo(
|
|
99
|
+
cards,
|
|
100
|
+
{ opacity: 0, y: 30 },
|
|
101
|
+
{
|
|
102
|
+
opacity: 1,
|
|
103
|
+
y: 0,
|
|
104
|
+
duration: 0.5,
|
|
105
|
+
stagger: 0.1,
|
|
106
|
+
ease: "power3.out",
|
|
107
|
+
scrollTrigger: {
|
|
108
|
+
trigger: content,
|
|
109
|
+
start: "top 80%",
|
|
110
|
+
},
|
|
111
|
+
}
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
return () => {
|
|
115
|
+
ScrollTrigger.getAll().forEach((trigger) => trigger.kill());
|
|
116
|
+
};
|
|
117
|
+
}, []);
|
|
118
|
+
|
|
119
|
+
const handleCopy = (command: string, label: string) => {
|
|
120
|
+
navigator.clipboard.writeText(command);
|
|
121
|
+
setCopiedCommand(label);
|
|
122
|
+
showToast(`Copied ${label}`, "success");
|
|
123
|
+
setTimeout(() => setCopiedCommand(null), 2000);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
return (
|
|
127
|
+
<main className="min-h-screen px-3 sm:px-4 lg:px-6 xl:px-8 pb-12 sm:pb-20 pt-8 sm:pt-12">
|
|
128
|
+
<section className="mx-auto flex w-full max-w-7xl flex-col gap-6 sm:gap-8">
|
|
129
|
+
<SiteHeader />
|
|
130
|
+
|
|
131
|
+
{/* Header */}
|
|
132
|
+
<div className="flex flex-col gap-3">
|
|
133
|
+
<Badge variant="glass" className="w-fit gap-1 text-xs sm:text-sm">
|
|
134
|
+
<BookOpen className="h-3 w-3 sm:h-4 sm:w-4" />
|
|
135
|
+
Documentation
|
|
136
|
+
</Badge>
|
|
137
|
+
<h1 className="text-xl sm:text-2xl md:text-3xl lg:text-4xl font-semibold">
|
|
138
|
+
Install the Gradient Forge System
|
|
139
|
+
</h1>
|
|
140
|
+
<p className="max-w-2xl text-xs sm:text-sm text-muted-foreground">
|
|
141
|
+
Quick 4-step setup to add beautiful gradient themes to your shadcn project.
|
|
142
|
+
</p>
|
|
143
|
+
</div>
|
|
144
|
+
|
|
145
|
+
{/* Quick Install Hero */}
|
|
146
|
+
<div ref={contentRef}>
|
|
147
|
+
<div className="doc-card rounded-xl sm:rounded-2xl border border-border/50 bg-background/60 relative overflow-hidden">
|
|
148
|
+
<div className="absolute inset-0 bg-gradient-to-br from-primary/5 via-transparent to-accent/5 pointer-events-none" />
|
|
149
|
+
<CardHeader className="relative px-4 sm:px-6 pt-4 sm:pt-6 pb-2 sm:pb-3">
|
|
150
|
+
<CardTitle className="flex items-center gap-2 text-sm sm:text-base">
|
|
151
|
+
<Terminal className="h-4 w-4 sm:h-5 sm:w-5 text-primary" />
|
|
152
|
+
Quick Install
|
|
153
|
+
<Badge variant="outline" className="ml-1 text-[10px] bg-amber-500/10 text-amber-500 border-amber-500/30">Coming Soon</Badge>
|
|
154
|
+
</CardTitle>
|
|
155
|
+
<p className="text-[10px] sm:text-xs text-muted-foreground">
|
|
156
|
+
CLI launching soon! Use the simple copy method below for now.
|
|
157
|
+
</p>
|
|
158
|
+
</CardHeader>
|
|
159
|
+
<CardContent className="relative px-4 sm:px-6 pb-4 sm:pb-6">
|
|
160
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 gap-2 sm:gap-3 opacity-60">
|
|
161
|
+
{runners.map((runner) => (
|
|
162
|
+
<div
|
|
163
|
+
key={runner.label}
|
|
164
|
+
className="rounded-lg sm:rounded-xl border border-border/40 bg-background/50 p-2.5 sm:p-3 group relative"
|
|
165
|
+
>
|
|
166
|
+
<div className="absolute top-2 right-2">
|
|
167
|
+
<Badge variant="outline" className="text-[8px] sm:text-[9px] bg-amber-500/10 text-amber-500 border-amber-500/30">Coming Soon</Badge>
|
|
168
|
+
</div>
|
|
169
|
+
<div className="flex items-center justify-between mb-1.5 sm:mb-2 mt-3">
|
|
170
|
+
<span className="text-[10px] sm:text-xs font-semibold text-foreground">{runner.label}</span>
|
|
171
|
+
</div>
|
|
172
|
+
<code className="text-[10px] sm:text-xs text-muted-foreground block truncate font-mono">
|
|
173
|
+
{runner.command}
|
|
174
|
+
</code>
|
|
175
|
+
</div>
|
|
176
|
+
))}
|
|
177
|
+
</div>
|
|
178
|
+
</CardContent>
|
|
179
|
+
</div>
|
|
180
|
+
</div>
|
|
181
|
+
|
|
182
|
+
{/* Main Content Grid */}
|
|
183
|
+
<div className="grid gap-4 sm:gap-6 lg:grid-cols-[1.05fr_1fr]">
|
|
184
|
+
{/* CLI Install */}
|
|
185
|
+
<AnimatedSection animation="slideLeft">
|
|
186
|
+
<Card className="doc-card border-border/50 bg-background/60">
|
|
187
|
+
<CardHeader className="px-4 sm:px-6 pt-4 sm:pt-6 pb-2 sm:pb-3">
|
|
188
|
+
<CardTitle className="flex items-center gap-2 text-sm sm:text-base">
|
|
189
|
+
<Terminal className="h-4 w-4 sm:h-5 sm:w-5 text-primary" />
|
|
190
|
+
CLI Install
|
|
191
|
+
<Badge variant="outline" className="text-[10px] bg-amber-500/10 text-amber-500 border-amber-500/30">Coming Soon</Badge>
|
|
192
|
+
</CardTitle>
|
|
193
|
+
<p className="text-[10px] sm:text-xs text-muted-foreground">
|
|
194
|
+
CLI launching soon! Use the instant copy methods below instead.
|
|
195
|
+
</p>
|
|
196
|
+
</CardHeader>
|
|
197
|
+
<CardContent className="px-4 sm:px-6 pb-4 sm:pb-6 space-y-3 sm:space-y-4">
|
|
198
|
+
<div className="rounded-lg sm:rounded-xl border border-primary/20 bg-primary/5 p-3 sm:p-4">
|
|
199
|
+
<p className="text-[10px] sm:text-xs text-foreground font-medium mb-2">🚀 Easy 3-Second Setup:</p>
|
|
200
|
+
<ol className="text-[10px] sm:text-xs text-muted-foreground space-y-1 list-decimal list-inside">
|
|
201
|
+
<li>Go to <a href="/studio" className="text-primary hover:underline">/studio</a> and pick a theme</li>
|
|
202
|
+
<li>Click "Get Theme" to copy CSS + React code</li>
|
|
203
|
+
<li>Paste into your project - done!</li>
|
|
204
|
+
</ol>
|
|
205
|
+
</div>
|
|
206
|
+
|
|
207
|
+
<div className="relative group">
|
|
208
|
+
<pre className="overflow-x-auto rounded-lg sm:rounded-xl border border-border/40 bg-black/70 p-2.5 sm:p-3 text-[10px] sm:text-xs text-white/90">
|
|
209
|
+
<code>npm install gradient-forge (coming soon)</code>
|
|
210
|
+
</pre>
|
|
211
|
+
<Button
|
|
212
|
+
variant="ghost"
|
|
213
|
+
size="sm"
|
|
214
|
+
className="absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity h-6 sm:h-7"
|
|
215
|
+
onClick={() => handleCopy("npm install gradient-forge", "NPM Install")}
|
|
216
|
+
>
|
|
217
|
+
{copiedCommand === "NPM Install" ? (
|
|
218
|
+
<Check className="h-3 w-3 sm:h-3.5 sm:w-3.5 text-emerald-500" />
|
|
219
|
+
) : (
|
|
220
|
+
<Copy className="h-3 w-3 sm:h-3.5 sm:w-3.5" />
|
|
221
|
+
)}
|
|
222
|
+
</Button>
|
|
223
|
+
</div>
|
|
224
|
+
|
|
225
|
+
<StaggerContainer className="space-y-1.5 sm:space-y-2" stagger={0.05}>
|
|
226
|
+
{[
|
|
227
|
+
"CLI will scaffold theme files automatically",
|
|
228
|
+
"Import the generated CSS in your globals",
|
|
229
|
+
"Wrap your app with ThemeProvider",
|
|
230
|
+
"Set theme classes on root element",
|
|
231
|
+
].map((step, index) => (
|
|
232
|
+
<div
|
|
233
|
+
key={step}
|
|
234
|
+
className="rounded-lg sm:rounded-xl border border-border/40 bg-background/50 p-2 sm:p-3 flex items-start gap-2 sm:gap-3 text-[10px] sm:text-xs text-muted-foreground"
|
|
235
|
+
>
|
|
236
|
+
<span className="flex h-4 w-4 sm:h-5 sm:w-5 shrink-0 items-center justify-center rounded-full bg-primary/10 text-[8px] sm:text-[10px] font-semibold text-primary">
|
|
237
|
+
{index + 1}
|
|
238
|
+
</span>
|
|
239
|
+
{step}
|
|
240
|
+
</div>
|
|
241
|
+
))}
|
|
242
|
+
</StaggerContainer>
|
|
243
|
+
</CardContent>
|
|
244
|
+
</Card>
|
|
245
|
+
</AnimatedSection>
|
|
246
|
+
|
|
247
|
+
{/* Files to Copy */}
|
|
248
|
+
<AnimatedSection animation="slideRight">
|
|
249
|
+
<Card className="doc-card border-border/50 bg-background/60">
|
|
250
|
+
<CardHeader className="px-4 sm:px-6 pt-4 sm:pt-6 pb-2 sm:pb-3">
|
|
251
|
+
<CardTitle className="flex items-center gap-2 text-sm sm:text-base">
|
|
252
|
+
<Package className="h-4 w-4 sm:h-5 sm:w-5 text-secondary" />
|
|
253
|
+
Files to Copy
|
|
254
|
+
</CardTitle>
|
|
255
|
+
<p className="text-[10px] sm:text-xs text-muted-foreground">Copy these files to add the theming system to your project.</p>
|
|
256
|
+
</CardHeader>
|
|
257
|
+
<CardContent className="px-4 sm:px-6 pb-4 sm:pb-6 space-y-1.5 sm:space-y-2">
|
|
258
|
+
{[
|
|
259
|
+
{ file: "components/theme/theme-engine.ts", desc: "Core theme logic & definitions" },
|
|
260
|
+
{ file: "components/theme/theme-context.tsx", desc: "React context provider" },
|
|
261
|
+
{ file: "components/theme/token-export-utils.ts", desc: "Export utilities for tokens" },
|
|
262
|
+
{ file: "app/globals.css", desc: "CSS variables & theme classes (add to your existing)" },
|
|
263
|
+
].map((item, index) => (
|
|
264
|
+
<div
|
|
265
|
+
key={item.file}
|
|
266
|
+
className="rounded-lg sm:rounded-xl border border-border/40 bg-background/50 p-2 sm:p-3 text-[10px] sm:text-xs hover:border-secondary/30 transition-colors"
|
|
267
|
+
>
|
|
268
|
+
<div className="flex items-center gap-2 sm:gap-3">
|
|
269
|
+
<div className="h-6 w-6 sm:h-8 sm:w-8 rounded-md sm:rounded-lg bg-primary/10 flex items-center justify-center shrink-0">
|
|
270
|
+
<FileText className="h-3 w-3 sm:h-4 sm:w-4 text-primary" />
|
|
271
|
+
</div>
|
|
272
|
+
<div className="flex-1 min-w-0">
|
|
273
|
+
<code className="font-mono truncate block">{item.file}</code>
|
|
274
|
+
<p className="text-[9px] sm:text-[10px] text-muted-foreground mt-0.5">{item.desc}</p>
|
|
275
|
+
</div>
|
|
276
|
+
</div>
|
|
277
|
+
</div>
|
|
278
|
+
))}
|
|
279
|
+
<div className="rounded-lg sm:rounded-xl border border-border/40 bg-background/50 p-2 sm:p-3 mt-2">
|
|
280
|
+
<p className="text-[10px] sm:text-xs text-muted-foreground mb-2">Integration steps:</p>
|
|
281
|
+
<ol className="text-[10px] sm:text-xs text-muted-foreground space-y-1 list-decimal list-inside">
|
|
282
|
+
<li>Copy the 3 theme files to your components/theme/ folder</li>
|
|
283
|
+
<li>Merge the CSS from globals.css into your app/globals.css</li>
|
|
284
|
+
<li>Wrap your app with ThemeProvider</li>
|
|
285
|
+
<li>Add theme classes to your HTML root element</li>
|
|
286
|
+
</ol>
|
|
287
|
+
</div>
|
|
288
|
+
<MagneticButton strength={0.1}>
|
|
289
|
+
<Button variant="outline" size="sm" className="w-full mt-1 sm:mt-2 text-xs" asChild>
|
|
290
|
+
<a href="/studio">Preview Studio</a>
|
|
291
|
+
</Button>
|
|
292
|
+
</MagneticButton>
|
|
293
|
+
</CardContent>
|
|
294
|
+
</Card>
|
|
295
|
+
</AnimatedSection>
|
|
296
|
+
</div>
|
|
297
|
+
|
|
298
|
+
{/* CLI Options & Export Formats */}
|
|
299
|
+
<div className="grid gap-4 sm:gap-6 lg:grid-cols-[1fr_1.1fr]">
|
|
300
|
+
<AnimatedSection animation="fadeUp">
|
|
301
|
+
<Card className="doc-card border-border/50 bg-background/60">
|
|
302
|
+
<CardHeader className="px-4 sm:px-6 pt-4 sm:pt-6 pb-2 sm:pb-3">
|
|
303
|
+
<CardTitle className="flex items-center gap-2 text-sm sm:text-base">
|
|
304
|
+
<Settings className="h-4 w-4 sm:h-5 sm:w-5 text-accent" />
|
|
305
|
+
CLI Options
|
|
306
|
+
<Badge variant="outline" className="text-[10px] bg-amber-500/10 text-amber-500 border-amber-500/30">Coming Soon</Badge>
|
|
307
|
+
</CardTitle>
|
|
308
|
+
<p className="text-[10px] sm:text-xs text-muted-foreground">
|
|
309
|
+
Flags to control generation behavior (via CLI).
|
|
310
|
+
</p>
|
|
311
|
+
</CardHeader>
|
|
312
|
+
<CardContent className="px-4 sm:px-6 pb-4 sm:pb-6">
|
|
313
|
+
<StaggerContainer className="space-y-1.5 sm:space-y-2" stagger={0.05}>
|
|
314
|
+
{cliOptions.map((option) => (
|
|
315
|
+
<div
|
|
316
|
+
key={option.flag}
|
|
317
|
+
className="rounded-lg sm:rounded-xl border border-border/40 bg-background/50 p-2 sm:p-3 text-[10px] sm:text-xs text-muted-foreground hover:border-accent/30 transition-colors"
|
|
318
|
+
>
|
|
319
|
+
<code className="font-semibold text-foreground font-mono text-[10px] sm:text-xs">{option.flag}</code>
|
|
320
|
+
<span className="ml-1.5 sm:ml-2">{option.desc}</span>
|
|
321
|
+
</div>
|
|
322
|
+
))}
|
|
323
|
+
</StaggerContainer>
|
|
324
|
+
</CardContent>
|
|
325
|
+
</Card>
|
|
326
|
+
</AnimatedSection>
|
|
327
|
+
|
|
328
|
+
<AnimatedSection animation="fadeUp">
|
|
329
|
+
<Card className="doc-card border-border/50 bg-background/60">
|
|
330
|
+
<CardHeader className="px-4 sm:px-6 pt-4 sm:pt-6 pb-2 sm:pb-3">
|
|
331
|
+
<CardTitle className="flex items-center gap-2 text-sm sm:text-base">
|
|
332
|
+
<Sparkles className="h-4 w-4 sm:h-5 sm:w-5 text-primary" />
|
|
333
|
+
Export Formats
|
|
334
|
+
<Badge variant="outline" className="text-[10px] bg-amber-500/10 text-amber-500 border-amber-500/30">Web Only</Badge>
|
|
335
|
+
</CardTitle>
|
|
336
|
+
<p className="text-[10px] sm:text-xs text-muted-foreground">
|
|
337
|
+
Use the Studio to export in these formats.
|
|
338
|
+
</p>
|
|
339
|
+
</CardHeader>
|
|
340
|
+
<CardContent className="px-4 sm:px-6 pb-4 sm:pb-6">
|
|
341
|
+
<StaggerContainer className="grid grid-cols-2 gap-1.5 sm:gap-2" stagger={0.03}>
|
|
342
|
+
{["CSS Theme", "SCSS", "JSON Tokens", "Tailwind", "W3C Tokens", "Figma"].map((format) => (
|
|
343
|
+
<div
|
|
344
|
+
key={format}
|
|
345
|
+
className="rounded-lg sm:rounded-xl border border-border/40 bg-background/50 p-2 sm:p-3 hover:border-secondary/30 transition-colors flex items-center gap-1.5 sm:gap-2"
|
|
346
|
+
>
|
|
347
|
+
<div className="h-1.5 w-1.5 sm:h-2 sm:w-2 rounded-full bg-primary" />
|
|
348
|
+
<span className="text-[10px] sm:text-xs">{format}</span>
|
|
349
|
+
</div>
|
|
350
|
+
))}
|
|
351
|
+
</StaggerContainer>
|
|
352
|
+
</CardContent>
|
|
353
|
+
</Card>
|
|
354
|
+
</AnimatedSection>
|
|
355
|
+
</div>
|
|
356
|
+
|
|
357
|
+
{/* Root Setup */}
|
|
358
|
+
<AnimatedSection animation="fadeUp">
|
|
359
|
+
<Card className="doc-card border-border/50 bg-background/60">
|
|
360
|
+
<CardHeader className="px-4 sm:px-6 pt-4 sm:pt-6 pb-2 sm:pb-3">
|
|
361
|
+
<CardTitle className="flex items-center gap-2 text-sm sm:text-base">
|
|
362
|
+
<Settings className="h-4 w-4 sm:h-5 sm:w-5 text-accent" />
|
|
363
|
+
Required Root Setup
|
|
364
|
+
</CardTitle>
|
|
365
|
+
<p className="text-[10px] sm:text-xs text-muted-foreground">Make sure the root element carries theme classes.</p>
|
|
366
|
+
</CardHeader>
|
|
367
|
+
<CardContent className="px-4 sm:px-6 pb-4 sm:pb-6 space-y-2 sm:space-y-3">
|
|
368
|
+
<div className="relative group">
|
|
369
|
+
<pre className="overflow-x-auto rounded-lg sm:rounded-xl border border-border/40 bg-black/70 p-2.5 sm:p-3 text-[10px] sm:text-xs text-white/90">
|
|
370
|
+
<code>{`<html class="dark theme-nitro-midnight-blurple" data-theme="theme-nitro-midnight-blurple" data-color-mode="dark">`}</code>
|
|
371
|
+
</pre>
|
|
372
|
+
<Button
|
|
373
|
+
variant="ghost"
|
|
374
|
+
size="sm"
|
|
375
|
+
className="absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity h-6 sm:h-7"
|
|
376
|
+
onClick={() => handleCopy(`<html class="dark theme-nitro-midnight-blurple" data-theme="theme-nitro-midnight-blurple" data-color-mode="dark">`, "HTML Root")}
|
|
377
|
+
>
|
|
378
|
+
{copiedCommand === "HTML Root" ? (
|
|
379
|
+
<Check className="h-3 w-3 sm:h-3.5 sm:w-3.5 text-emerald-500" />
|
|
380
|
+
) : (
|
|
381
|
+
<Copy className="h-3 w-3 sm:h-3.5 sm:w-3.5" />
|
|
382
|
+
)}
|
|
383
|
+
</Button>
|
|
384
|
+
</div>
|
|
385
|
+
</CardContent>
|
|
386
|
+
</Card>
|
|
387
|
+
</AnimatedSection>
|
|
388
|
+
|
|
389
|
+
{/* Next Steps CTA */}
|
|
390
|
+
<AnimatedSection animation="fadeUp">
|
|
391
|
+
<div className="rounded-2xl sm:rounded-3xl border border-border/40 bg-background/50 p-5 sm:p-8 text-center">
|
|
392
|
+
<Sparkles className="h-8 w-8 sm:h-12 sm:w-12 text-primary mx-auto mb-3 sm:mb-4" />
|
|
393
|
+
<h2 className="text-lg sm:text-xl lg:text-2xl font-semibold mb-2 sm:mb-3">Ready to create?</h2>
|
|
394
|
+
<p className="text-xs sm:text-sm text-muted-foreground max-w-xl mx-auto mb-4 sm:mb-6">
|
|
395
|
+
Head over to the Studio to explore themes and export tokens for your project.
|
|
396
|
+
</p>
|
|
397
|
+
<div className="flex flex-wrap justify-center gap-2 sm:gap-3">
|
|
398
|
+
<MagneticButton strength={0.15}>
|
|
399
|
+
<Button variant="glow" size="sm" className="gap-1.5 sm:gap-2 text-xs sm:text-sm" asChild>
|
|
400
|
+
<a href="/studio">
|
|
401
|
+
Open Studio
|
|
402
|
+
<ArrowRight className="h-3.5 w-3.5 sm:h-4 sm:w-4" />
|
|
403
|
+
</a>
|
|
404
|
+
</Button>
|
|
405
|
+
</MagneticButton>
|
|
406
|
+
<MagneticButton strength={0.15}>
|
|
407
|
+
<Button variant="outline" size="sm" className="text-xs sm:text-sm" asChild>
|
|
408
|
+
<a href="/gallery">Browse Gallery</a>
|
|
409
|
+
</Button>
|
|
410
|
+
</MagneticButton>
|
|
411
|
+
</div>
|
|
412
|
+
</div>
|
|
413
|
+
</AnimatedSection>
|
|
414
|
+
</section>
|
|
415
|
+
</main>
|
|
416
|
+
);
|
|
417
|
+
}
|