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/app/layout.tsx
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Metadata } from "next";
|
|
2
|
+
import "@/app/globals.css";
|
|
3
|
+
import { ThemeProvider } from "@/components/theme/theme-context";
|
|
4
|
+
import { ToastProvider } from "@/components/ui/toast";
|
|
5
|
+
import { CommandPalette } from "@/components/ui/command-palette";
|
|
6
|
+
|
|
7
|
+
export const metadata: Metadata = {
|
|
8
|
+
title: "Shadcn Gradient Forge",
|
|
9
|
+
description:
|
|
10
|
+
"A production-ready gradient theming system for shadcn components.",
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default function RootLayout({
|
|
14
|
+
children,
|
|
15
|
+
}: {
|
|
16
|
+
children: React.ReactNode;
|
|
17
|
+
}) {
|
|
18
|
+
return (
|
|
19
|
+
<html
|
|
20
|
+
lang="en"
|
|
21
|
+
className="dark theme-nitro-midnight-blurple"
|
|
22
|
+
data-theme="theme-nitro-midnight-blurple"
|
|
23
|
+
data-color-mode="dark"
|
|
24
|
+
suppressHydrationWarning
|
|
25
|
+
>
|
|
26
|
+
<body>
|
|
27
|
+
<ThemeProvider>
|
|
28
|
+
<ToastProvider>
|
|
29
|
+
{children}
|
|
30
|
+
<CommandPalette />
|
|
31
|
+
</ToastProvider>
|
|
32
|
+
</ThemeProvider>
|
|
33
|
+
</body>
|
|
34
|
+
</html>
|
|
35
|
+
);
|
|
36
|
+
}
|
package/app/page.tsx
ADDED
|
@@ -0,0 +1,600 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useRef } from "react";
|
|
4
|
+
import gsap from "gsap";
|
|
5
|
+
import { ScrollTrigger } from "gsap/ScrollTrigger";
|
|
6
|
+
import { SiteHeader } from "@/components/site/site-header";
|
|
7
|
+
import { ThemeExporter } from "@/components/theme/theme-exporter";
|
|
8
|
+
import { Badge } from "@/components/ui/badge";
|
|
9
|
+
import { Button } from "@/components/ui/button";
|
|
10
|
+
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
11
|
+
import {
|
|
12
|
+
ArrowRight,
|
|
13
|
+
Sparkles,
|
|
14
|
+
Zap,
|
|
15
|
+
Palette,
|
|
16
|
+
Code2,
|
|
17
|
+
Layers,
|
|
18
|
+
GitBranch,
|
|
19
|
+
Coffee,
|
|
20
|
+
Terminal,
|
|
21
|
+
FileJson,
|
|
22
|
+
Wand2
|
|
23
|
+
} from "lucide-react";
|
|
24
|
+
import { featureCards, roadmapItems, useCases, workflowSteps } from "@/components/site/site-data";
|
|
25
|
+
import {
|
|
26
|
+
AnimatedSection,
|
|
27
|
+
StaggerContainer,
|
|
28
|
+
MagneticButton,
|
|
29
|
+
FloatingElement,
|
|
30
|
+
TextReveal
|
|
31
|
+
} from "@/components/ui/gsap-animated";
|
|
32
|
+
|
|
33
|
+
if (typeof window !== "undefined") {
|
|
34
|
+
gsap.registerPlugin(ScrollTrigger);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export default function HomePage() {
|
|
38
|
+
const heroRef = useRef<HTMLDivElement>(null);
|
|
39
|
+
const floatingCardsRef = useRef<HTMLDivElement>(null);
|
|
40
|
+
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
// Hero entrance animation
|
|
43
|
+
const hero = heroRef.current;
|
|
44
|
+
if (hero) {
|
|
45
|
+
const tl = gsap.timeline({ defaults: { ease: "power3.out" } });
|
|
46
|
+
|
|
47
|
+
tl.fromTo(
|
|
48
|
+
hero.querySelectorAll(".hero-badge"),
|
|
49
|
+
{ opacity: 0, scale: 0.8 },
|
|
50
|
+
{ opacity: 1, scale: 1, duration: 0.5 }
|
|
51
|
+
)
|
|
52
|
+
.fromTo(
|
|
53
|
+
hero.querySelectorAll(".hero-title"),
|
|
54
|
+
{ opacity: 0, y: 30 },
|
|
55
|
+
{ opacity: 1, y: 0, duration: 0.7 },
|
|
56
|
+
"-=0.3"
|
|
57
|
+
)
|
|
58
|
+
.fromTo(
|
|
59
|
+
hero.querySelectorAll(".hero-description"),
|
|
60
|
+
{ opacity: 0, y: 20 },
|
|
61
|
+
{ opacity: 1, y: 0, duration: 0.6 },
|
|
62
|
+
"-=0.4"
|
|
63
|
+
)
|
|
64
|
+
.fromTo(
|
|
65
|
+
hero.querySelectorAll(".hero-cta"),
|
|
66
|
+
{ opacity: 0, y: 20 },
|
|
67
|
+
{ opacity: 1, y: 0, duration: 0.5, stagger: 0.1 },
|
|
68
|
+
"-=0.3"
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Floating cards animation
|
|
73
|
+
const floatingCards = floatingCardsRef.current;
|
|
74
|
+
if (floatingCards) {
|
|
75
|
+
const cards = floatingCards.querySelectorAll(".floating-card");
|
|
76
|
+
|
|
77
|
+
gsap.fromTo(
|
|
78
|
+
cards,
|
|
79
|
+
{ opacity: 0, scale: 0.9, y: 30 },
|
|
80
|
+
{
|
|
81
|
+
opacity: 1,
|
|
82
|
+
scale: 1,
|
|
83
|
+
y: 0,
|
|
84
|
+
duration: 0.6,
|
|
85
|
+
stagger: 0.15,
|
|
86
|
+
ease: "back.out(1.7)",
|
|
87
|
+
scrollTrigger: {
|
|
88
|
+
trigger: floatingCards,
|
|
89
|
+
start: "top 80%",
|
|
90
|
+
},
|
|
91
|
+
}
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
// Add floating animation to each card
|
|
95
|
+
cards.forEach((card, index) => {
|
|
96
|
+
gsap.to(card, {
|
|
97
|
+
y: index % 2 === 0 ? 8 : -8,
|
|
98
|
+
duration: 2 + index * 0.3,
|
|
99
|
+
ease: "sine.inOut",
|
|
100
|
+
yoyo: true,
|
|
101
|
+
repeat: -1,
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return () => {
|
|
107
|
+
ScrollTrigger.getAll().forEach((trigger) => trigger.kill());
|
|
108
|
+
};
|
|
109
|
+
}, []);
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<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">
|
|
113
|
+
<section className="mx-auto flex w-full max-w-7xl flex-col gap-8 sm:gap-12">
|
|
114
|
+
<SiteHeader />
|
|
115
|
+
|
|
116
|
+
{/* Hero Section */}
|
|
117
|
+
<div ref={heroRef} className="grid gap-6 sm:gap-8 lg:grid-cols-[1.1fr_0.9fr] lg:items-center">
|
|
118
|
+
<div className="space-y-4 sm:space-y-5">
|
|
119
|
+
<div className="hero-badge">
|
|
120
|
+
<Badge variant="glass" className="gap-1 text-xs sm:text-sm">
|
|
121
|
+
<Sparkles className="h-3 w-3 sm:h-4 sm:w-4" />
|
|
122
|
+
Nitro Gradient Forge
|
|
123
|
+
</Badge>
|
|
124
|
+
</div>
|
|
125
|
+
|
|
126
|
+
<h1 className="hero-title text-2xl sm:text-3xl md:text-4xl lg:text-5xl xl:text-6xl font-semibold tracking-tight leading-tight">
|
|
127
|
+
<span className="bg-gradient-to-br from-foreground via-foreground to-muted-foreground bg-clip-text text-transparent">
|
|
128
|
+
Build shadcn components that glow with cinematic gradients.
|
|
129
|
+
</span>
|
|
130
|
+
</h1>
|
|
131
|
+
|
|
132
|
+
<p className="hero-description text-sm sm:text-base text-muted-foreground max-w-xl leading-relaxed">
|
|
133
|
+
A polished studio for custom shadcn theming. Light and dark modes,
|
|
134
|
+
export-ready tokens, and surface-aware overlays designed for
|
|
135
|
+
production design systems.
|
|
136
|
+
</p>
|
|
137
|
+
|
|
138
|
+
<div className="flex flex-wrap items-center gap-2 sm:gap-3">
|
|
139
|
+
<MagneticButton className="hero-cta" strength={0.2}>
|
|
140
|
+
<Button variant="glow" size="sm" className="sm:size-lg gap-1.5 sm:gap-2 text-xs sm:text-sm" asChild>
|
|
141
|
+
<a href="/studio">
|
|
142
|
+
Launch Studio <ArrowRight className="h-3.5 w-3.5 sm:h-4 sm:w-4" />
|
|
143
|
+
</a>
|
|
144
|
+
</Button>
|
|
145
|
+
</MagneticButton>
|
|
146
|
+
<MagneticButton className="hero-cta" strength={0.2}>
|
|
147
|
+
<Button variant="secondary" size="sm" className="sm:size-lg text-xs sm:text-sm" asChild>
|
|
148
|
+
<a href="/showcase">View Showcase</a>
|
|
149
|
+
</Button>
|
|
150
|
+
</MagneticButton>
|
|
151
|
+
<MagneticButton className="hero-cta" strength={0.2}>
|
|
152
|
+
<Button variant="outline" size="sm" className="sm:size-lg text-xs sm:text-sm" asChild>
|
|
153
|
+
<a href="/docs">Read Docs</a>
|
|
154
|
+
</Button>
|
|
155
|
+
</MagneticButton>
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
158
|
+
|
|
159
|
+
{/* Floating Cards Preview - Desktop Only */}
|
|
160
|
+
<div
|
|
161
|
+
ref={floatingCardsRef}
|
|
162
|
+
className="hidden lg:block relative min-h-[400px] xl:min-h-[500px] w-full"
|
|
163
|
+
>
|
|
164
|
+
<div className="absolute inset-0 rounded-2xl sm:rounded-3xl border border-border/40 bg-background/40 shadow-[0_0_60px_hsl(var(--primary)_/_0.12)]" />
|
|
165
|
+
|
|
166
|
+
<div className="floating-card absolute left-0 top-4 w-[52%]">
|
|
167
|
+
<Card className="border-border/40 bg-card/70 hover:shadow-lg transition-shadow cursor-pointer">
|
|
168
|
+
<CardHeader className="pb-2 px-3 sm:px-4">
|
|
169
|
+
<CardTitle className="text-xs sm:text-sm flex items-center gap-1.5 sm:gap-2">
|
|
170
|
+
<Zap className="h-3 w-3 sm:h-4 sm:w-4 text-primary" />
|
|
171
|
+
Pricing Tier
|
|
172
|
+
</CardTitle>
|
|
173
|
+
</CardHeader>
|
|
174
|
+
<CardContent className="space-y-2 px-3 sm:px-4 pb-3 sm:pb-4">
|
|
175
|
+
<p className="text-[10px] sm:text-xs text-muted-foreground">Launch-ready plan for teams.</p>
|
|
176
|
+
<p className="text-lg sm:text-xl font-semibold">$29</p>
|
|
177
|
+
<Button className="w-full text-xs" size="sm">Start free trial</Button>
|
|
178
|
+
</CardContent>
|
|
179
|
+
</Card>
|
|
180
|
+
</div>
|
|
181
|
+
|
|
182
|
+
<div className="floating-card absolute right-0 top-12 w-[48%]">
|
|
183
|
+
<Card className="border-border/40 bg-card/70 hover:shadow-lg transition-shadow cursor-pointer">
|
|
184
|
+
<CardHeader className="pb-2 px-3 sm:px-4">
|
|
185
|
+
<CardTitle className="text-xs sm:text-sm flex items-center gap-1.5 sm:gap-2">
|
|
186
|
+
<Layers className="h-3 w-3 sm:h-4 sm:w-4 text-accent" />
|
|
187
|
+
Inline Alert
|
|
188
|
+
</CardTitle>
|
|
189
|
+
</CardHeader>
|
|
190
|
+
<CardContent className="space-y-2 px-3 sm:px-4 pb-3 sm:pb-4">
|
|
191
|
+
<p className="text-[10px] sm:text-xs text-muted-foreground">
|
|
192
|
+
Gradient tokens keep alerts readable across themes.
|
|
193
|
+
</p>
|
|
194
|
+
<Badge variant="outline" className="text-[10px]">System Update</Badge>
|
|
195
|
+
<Button variant="secondary" className="w-full text-xs" size="sm">
|
|
196
|
+
Review changes
|
|
197
|
+
</Button>
|
|
198
|
+
</CardContent>
|
|
199
|
+
</Card>
|
|
200
|
+
</div>
|
|
201
|
+
|
|
202
|
+
<div className="floating-card absolute left-4 sm:left-6 top-[180px] sm:top-[200px] w-[56%]">
|
|
203
|
+
<Card className="border-border/40 bg-card/70 hover:shadow-lg transition-shadow cursor-pointer">
|
|
204
|
+
<CardHeader className="pb-2 px-3 sm:px-4">
|
|
205
|
+
<CardTitle className="text-xs sm:text-sm flex items-center gap-1.5 sm:gap-2">
|
|
206
|
+
<Palette className="h-3 w-3 sm:h-4 sm:w-4 text-secondary" />
|
|
207
|
+
Status Panel
|
|
208
|
+
</CardTitle>
|
|
209
|
+
</CardHeader>
|
|
210
|
+
<CardContent className="grid grid-cols-3 gap-1.5 sm:gap-2 px-3 sm:px-4 pb-3 sm:pb-4">
|
|
211
|
+
{[
|
|
212
|
+
{ label: "Themes", value: "23" },
|
|
213
|
+
{ label: "Layers", value: "5" },
|
|
214
|
+
{ label: "Exports", value: "8" },
|
|
215
|
+
].map((stat) => (
|
|
216
|
+
<div key={stat.label} className="rounded-xl border border-border/40 bg-background/50 p-1.5 sm:p-2">
|
|
217
|
+
<p className="text-[8px] sm:text-[10px] text-muted-foreground">{stat.label}</p>
|
|
218
|
+
<p className="text-xs sm:text-sm font-semibold">{stat.value}</p>
|
|
219
|
+
</div>
|
|
220
|
+
))}
|
|
221
|
+
</CardContent>
|
|
222
|
+
</Card>
|
|
223
|
+
</div>
|
|
224
|
+
|
|
225
|
+
<div className="floating-card absolute right-2 sm:right-4 top-[280px] sm:top-[300px] w-[44%]">
|
|
226
|
+
<Card className="border-border/40 bg-card/70 hover:shadow-lg transition-shadow cursor-pointer">
|
|
227
|
+
<CardHeader className="pb-2 px-3 sm:px-4">
|
|
228
|
+
<CardTitle className="text-xs sm:text-sm flex items-center gap-1.5 sm:gap-2">
|
|
229
|
+
<Code2 className="h-3 w-3 sm:h-4 sm:w-4 text-primary" />
|
|
230
|
+
Launch Checklist
|
|
231
|
+
</CardTitle>
|
|
232
|
+
</CardHeader>
|
|
233
|
+
<CardContent className="space-y-1.5 sm:space-y-2 px-3 sm:px-4 pb-3 sm:pb-4 text-[10px] sm:text-xs text-muted-foreground">
|
|
234
|
+
{[
|
|
235
|
+
{ label: "Theme synced", done: true },
|
|
236
|
+
{ label: "Tokens mapped", done: true },
|
|
237
|
+
{ label: "Export ready", done: false },
|
|
238
|
+
].map((item) => (
|
|
239
|
+
<div key={item.label} className="flex items-center justify-between rounded-lg border border-border/40 bg-background/50 p-1.5 sm:p-2">
|
|
240
|
+
<span>{item.label}</span>
|
|
241
|
+
<Badge variant={item.done ? "glass" : "outline"} className="text-[8px] sm:text-[10px]">
|
|
242
|
+
{item.done ? "Done" : "Pending"}
|
|
243
|
+
</Badge>
|
|
244
|
+
</div>
|
|
245
|
+
))}
|
|
246
|
+
</CardContent>
|
|
247
|
+
</Card>
|
|
248
|
+
</div>
|
|
249
|
+
</div>
|
|
250
|
+
|
|
251
|
+
{/* Mobile Preview Cards */}
|
|
252
|
+
<div className="grid gap-3 sm:gap-4 lg:hidden">
|
|
253
|
+
<StaggerContainer className="grid gap-3 sm:gap-4" stagger={0.1}>
|
|
254
|
+
<Card className="border-border/40 bg-card/70">
|
|
255
|
+
<CardHeader className="pb-2 px-3 sm:px-4">
|
|
256
|
+
<CardTitle className="text-xs sm:text-sm">Pricing Tier</CardTitle>
|
|
257
|
+
</CardHeader>
|
|
258
|
+
<CardContent className="space-y-2 px-3 sm:px-4 pb-3 sm:pb-4">
|
|
259
|
+
<p className="text-[10px] sm:text-xs text-muted-foreground">Launch-ready plan for teams.</p>
|
|
260
|
+
<p className="text-xl sm:text-2xl font-semibold">$29</p>
|
|
261
|
+
<Button className="w-full text-xs" size="sm">Start free trial</Button>
|
|
262
|
+
</CardContent>
|
|
263
|
+
</Card>
|
|
264
|
+
<Card className="border-border/40 bg-card/70">
|
|
265
|
+
<CardHeader className="pb-2 px-3 sm:px-4">
|
|
266
|
+
<CardTitle className="text-xs sm:text-sm">Status Panel</CardTitle>
|
|
267
|
+
</CardHeader>
|
|
268
|
+
<CardContent className="grid grid-cols-3 gap-2 px-3 sm:px-4 pb-3 sm:pb-4">
|
|
269
|
+
{[
|
|
270
|
+
{ label: "Themes", value: "23" },
|
|
271
|
+
{ label: "Layers", value: "5" },
|
|
272
|
+
{ label: "Exports", value: "8" },
|
|
273
|
+
].map((stat) => (
|
|
274
|
+
<div key={stat.label} className="rounded-xl border border-border/40 bg-background/50 p-2">
|
|
275
|
+
<p className="text-[10px] text-muted-foreground">{stat.label}</p>
|
|
276
|
+
<p className="text-sm font-semibold">{stat.value}</p>
|
|
277
|
+
</div>
|
|
278
|
+
))}
|
|
279
|
+
</CardContent>
|
|
280
|
+
</Card>
|
|
281
|
+
</StaggerContainer>
|
|
282
|
+
</div>
|
|
283
|
+
</div>
|
|
284
|
+
|
|
285
|
+
{/* Feature Cards */}
|
|
286
|
+
<AnimatedSection>
|
|
287
|
+
<StaggerContainer className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3 sm:gap-4" stagger={0.08}>
|
|
288
|
+
{featureCards.map((feature, index) => (
|
|
289
|
+
<Card
|
|
290
|
+
key={feature.title}
|
|
291
|
+
className="border-border/50 bg-background/60 h-full hover:shadow-lg hover:shadow-primary/5 transition-all"
|
|
292
|
+
>
|
|
293
|
+
<CardHeader className="px-3 sm:px-4 pt-3 sm:pt-4 pb-2">
|
|
294
|
+
<CardTitle className="text-sm sm:text-base flex items-center gap-2">
|
|
295
|
+
{index === 0 && <Palette className="h-4 w-4 text-primary" />}
|
|
296
|
+
{index === 1 && <Layers className="h-4 w-4 text-secondary" />}
|
|
297
|
+
{index === 2 && <Code2 className="h-4 w-4 text-accent" />}
|
|
298
|
+
{index === 3 && <Zap className="h-4 w-4 text-primary" />}
|
|
299
|
+
{feature.title}
|
|
300
|
+
</CardTitle>
|
|
301
|
+
</CardHeader>
|
|
302
|
+
<CardContent className="px-3 sm:px-4 pb-3 sm:pb-4">
|
|
303
|
+
<p className="text-xs sm:text-sm text-muted-foreground">{feature.description}</p>
|
|
304
|
+
</CardContent>
|
|
305
|
+
</Card>
|
|
306
|
+
))}
|
|
307
|
+
</StaggerContainer>
|
|
308
|
+
</AnimatedSection>
|
|
309
|
+
|
|
310
|
+
{/* Workflow & Use Cases */}
|
|
311
|
+
<div className="grid gap-4 sm:gap-6 lg:grid-cols-[1.05fr_1fr]">
|
|
312
|
+
<AnimatedSection animation="slideLeft">
|
|
313
|
+
<Card className="border-border/50 bg-background/60">
|
|
314
|
+
<CardHeader className="px-3 sm:px-4 pt-3 sm:pt-4 pb-2">
|
|
315
|
+
<CardTitle className="flex items-center gap-2 text-sm sm:text-base">
|
|
316
|
+
<GitBranch className="h-4 w-4 sm:h-5 sm:w-5 text-primary" />
|
|
317
|
+
Workflow
|
|
318
|
+
</CardTitle>
|
|
319
|
+
<p className="text-xs sm:text-sm text-muted-foreground">
|
|
320
|
+
A clean, repeatable flow for shipping gradients across shadcn components.
|
|
321
|
+
</p>
|
|
322
|
+
</CardHeader>
|
|
323
|
+
<CardContent className="px-3 sm:px-4 pb-3 sm:pb-4">
|
|
324
|
+
<StaggerContainer className="grid gap-2 sm:gap-3" stagger={0.08}>
|
|
325
|
+
{workflowSteps.map((step, index) => (
|
|
326
|
+
<div
|
|
327
|
+
key={step.title}
|
|
328
|
+
className="rounded-xl sm:rounded-2xl border border-border/40 bg-background/50 p-2.5 sm:p-4 hover:border-primary/30 transition-colors"
|
|
329
|
+
>
|
|
330
|
+
<div className="flex items-start gap-2 sm:gap-3">
|
|
331
|
+
<span className="flex h-5 w-5 sm:h-6 sm:w-6 shrink-0 items-center justify-center rounded-full bg-primary/10 text-[10px] sm:text-xs font-semibold text-primary">
|
|
332
|
+
{index + 1}
|
|
333
|
+
</span>
|
|
334
|
+
<div>
|
|
335
|
+
<p className="text-xs sm:text-sm font-semibold">{step.title}</p>
|
|
336
|
+
<p className="text-[10px] sm:text-xs text-muted-foreground">{step.description}</p>
|
|
337
|
+
</div>
|
|
338
|
+
</div>
|
|
339
|
+
</div>
|
|
340
|
+
))}
|
|
341
|
+
</StaggerContainer>
|
|
342
|
+
</CardContent>
|
|
343
|
+
</Card>
|
|
344
|
+
</AnimatedSection>
|
|
345
|
+
|
|
346
|
+
<AnimatedSection animation="slideRight">
|
|
347
|
+
<Card className="border-border/50 bg-background/60">
|
|
348
|
+
<CardHeader className="px-3 sm:px-4 pt-3 sm:pt-4 pb-2">
|
|
349
|
+
<CardTitle className="flex items-center gap-2 text-sm sm:text-base">
|
|
350
|
+
<Layers className="h-4 w-4 sm:h-5 sm:w-5 text-secondary" />
|
|
351
|
+
Use Cases
|
|
352
|
+
</CardTitle>
|
|
353
|
+
<p className="text-xs sm:text-sm text-muted-foreground">Where this theming system fits best.</p>
|
|
354
|
+
</CardHeader>
|
|
355
|
+
<CardContent className="px-3 sm:px-4 pb-3 sm:pb-4">
|
|
356
|
+
<StaggerContainer className="space-y-2 sm:space-y-3" stagger={0.08}>
|
|
357
|
+
{useCases.map((item) => (
|
|
358
|
+
<div
|
|
359
|
+
key={item}
|
|
360
|
+
className="rounded-xl sm:rounded-2xl border border-border/40 bg-background/50 p-2.5 sm:p-3 text-xs sm:text-sm text-muted-foreground hover:border-secondary/30 transition-colors"
|
|
361
|
+
>
|
|
362
|
+
{item}
|
|
363
|
+
</div>
|
|
364
|
+
))}
|
|
365
|
+
</StaggerContainer>
|
|
366
|
+
</CardContent>
|
|
367
|
+
</Card>
|
|
368
|
+
</AnimatedSection>
|
|
369
|
+
</div>
|
|
370
|
+
|
|
371
|
+
{/* Roadmap & Jump In */}
|
|
372
|
+
<div className="grid gap-4 sm:gap-6 lg:grid-cols-[1fr_1.1fr]">
|
|
373
|
+
<AnimatedSection animation="fadeUp">
|
|
374
|
+
<Card className="border-border/50 bg-background/60">
|
|
375
|
+
<CardHeader className="px-3 sm:px-4 pt-3 sm:pt-4 pb-2">
|
|
376
|
+
<CardTitle className="flex items-center gap-2 text-sm sm:text-base">
|
|
377
|
+
<GitBranch className="h-4 w-4 sm:h-5 sm:w-5 text-accent" />
|
|
378
|
+
What's Available
|
|
379
|
+
</CardTitle>
|
|
380
|
+
<p className="text-xs sm:text-sm text-muted-foreground">
|
|
381
|
+
Features already live and coming soon.
|
|
382
|
+
</p>
|
|
383
|
+
</CardHeader>
|
|
384
|
+
<CardContent className="px-3 sm:px-4 pb-3 sm:pb-4">
|
|
385
|
+
<StaggerContainer className="grid gap-2 sm:gap-3" stagger={0.08}>
|
|
386
|
+
{roadmapItems.map((item) => (
|
|
387
|
+
<div
|
|
388
|
+
key={item.title}
|
|
389
|
+
className="rounded-xl sm:rounded-2xl border border-border/40 bg-background/50 p-2.5 sm:p-4 hover:border-accent/30 transition-colors"
|
|
390
|
+
>
|
|
391
|
+
<div className="flex items-center justify-between gap-2 mb-1">
|
|
392
|
+
<p className="text-xs sm:text-sm font-semibold">{item.title}</p>
|
|
393
|
+
<Badge
|
|
394
|
+
variant="outline"
|
|
395
|
+
className={`text-[9px] sm:text-[10px] ${item.status === 'done' ? 'bg-emerald-500/10 text-emerald-500 border-emerald-500/30' : 'bg-amber-500/10 text-amber-500 border-amber-500/30'}`}
|
|
396
|
+
>
|
|
397
|
+
{item.status === 'done' ? '✓ Live' : 'Coming Soon'}
|
|
398
|
+
</Badge>
|
|
399
|
+
</div>
|
|
400
|
+
<p className="text-[10px] sm:text-xs text-muted-foreground">{item.detail}</p>
|
|
401
|
+
</div>
|
|
402
|
+
))}
|
|
403
|
+
</StaggerContainer>
|
|
404
|
+
</CardContent>
|
|
405
|
+
</Card>
|
|
406
|
+
</AnimatedSection>
|
|
407
|
+
|
|
408
|
+
<AnimatedSection animation="fadeUp">
|
|
409
|
+
<Card className="border-border/50 bg-background/60">
|
|
410
|
+
<CardHeader className="px-3 sm:px-4 pt-3 sm:pt-4 pb-2">
|
|
411
|
+
<CardTitle className="flex items-center gap-2 text-sm sm:text-base">
|
|
412
|
+
<Sparkles className="h-4 w-4 sm:h-5 sm:w-5 text-primary" />
|
|
413
|
+
Jump In
|
|
414
|
+
</CardTitle>
|
|
415
|
+
<p className="text-xs sm:text-sm text-muted-foreground">
|
|
416
|
+
Explore the full studio, gallery, and documentation.
|
|
417
|
+
</p>
|
|
418
|
+
</CardHeader>
|
|
419
|
+
<CardContent className="px-3 sm:px-4 pb-3 sm:pb-4 space-y-3 sm:space-y-4">
|
|
420
|
+
<div className="rounded-xl sm:rounded-2xl border border-border/40 bg-background/50 p-3 sm:p-4 text-xs sm:text-sm text-muted-foreground">
|
|
421
|
+
The documentation includes CLI setup, manual install steps, and examples for integrating the
|
|
422
|
+
token layer into any shadcn project.
|
|
423
|
+
</div>
|
|
424
|
+
<div className="flex flex-wrap gap-2 sm:gap-3">
|
|
425
|
+
<MagneticButton strength={0.15}>
|
|
426
|
+
<Button variant="glow" size="sm" className="sm:size-default text-xs sm:text-sm" asChild>
|
|
427
|
+
<a href="/studio">Open Studio</a>
|
|
428
|
+
</Button>
|
|
429
|
+
</MagneticButton>
|
|
430
|
+
<MagneticButton strength={0.15}>
|
|
431
|
+
<Button variant="secondary" size="sm" className="sm:size-default text-xs sm:text-sm" asChild>
|
|
432
|
+
<a href="/showcase">View Templates</a>
|
|
433
|
+
</Button>
|
|
434
|
+
</MagneticButton>
|
|
435
|
+
<MagneticButton strength={0.15}>
|
|
436
|
+
<Button variant="outline" size="sm" className="sm:size-default text-xs sm:text-sm" asChild>
|
|
437
|
+
<a href="/gallery">Theme Gallery</a>
|
|
438
|
+
</Button>
|
|
439
|
+
</MagneticButton>
|
|
440
|
+
</div>
|
|
441
|
+
</CardContent>
|
|
442
|
+
</Card>
|
|
443
|
+
</AnimatedSection>
|
|
444
|
+
</div>
|
|
445
|
+
|
|
446
|
+
{/* CLI Section */}
|
|
447
|
+
<AnimatedSection animation="fadeUp">
|
|
448
|
+
<div className="grid gap-4 sm:gap-6 lg:grid-cols-[1.05fr_1fr]">
|
|
449
|
+
<Card className="border-border/50 bg-background/60">
|
|
450
|
+
<CardHeader className="px-3 sm:px-4 pt-3 sm:pt-4 pb-2">
|
|
451
|
+
<div className="flex flex-wrap items-center gap-2">
|
|
452
|
+
<CardTitle className="flex items-center gap-2 text-sm sm:text-base">
|
|
453
|
+
<Terminal className="h-4 w-4 sm:h-5 sm:w-5 text-primary" />
|
|
454
|
+
CLI Export
|
|
455
|
+
</CardTitle>
|
|
456
|
+
<Badge variant="outline" className="text-[10px] sm:text-xs bg-amber-500/10 text-amber-500 border-amber-500/30">Coming Soon</Badge>
|
|
457
|
+
</div>
|
|
458
|
+
<p className="text-xs sm:text-sm text-muted-foreground">
|
|
459
|
+
CLI launching soon! Use the Studio to export themes in 8+ formats now.
|
|
460
|
+
</p>
|
|
461
|
+
</CardHeader>
|
|
462
|
+
<CardContent className="px-3 sm:px-4 pb-3 sm:pb-4 space-y-2 sm:space-y-3">
|
|
463
|
+
{[
|
|
464
|
+
{ cmd: "init", desc: "Scaffolds theme files and context", comingSoon: true },
|
|
465
|
+
{ cmd: "export", desc: "Generates CSS, JSON, Tailwind, W3C tokens", comingSoon: true },
|
|
466
|
+
{ cmd: "--inject", desc: "Adds theme CSS automatically", comingSoon: true },
|
|
467
|
+
].map((item) => (
|
|
468
|
+
<div
|
|
469
|
+
key={item.cmd}
|
|
470
|
+
className="rounded-xl sm:rounded-2xl border border-border/40 bg-background/50 p-2 sm:p-3 hover:border-primary/30 transition-colors opacity-70"
|
|
471
|
+
>
|
|
472
|
+
<code className="text-xs sm:text-sm font-semibold text-foreground">{item.cmd}</code>
|
|
473
|
+
<span className="text-[10px] sm:text-xs text-muted-foreground ml-2">{item.desc}</span>
|
|
474
|
+
<Badge variant="outline" className="ml-2 text-[8px] sm:text-[9px] bg-amber-500/10 text-amber-500 border-amber-500/30">Coming Soon</Badge>
|
|
475
|
+
</div>
|
|
476
|
+
))}
|
|
477
|
+
<pre className="overflow-x-auto rounded-xl sm:rounded-2xl border border-border/40 bg-black/70 p-2 sm:p-3 text-[10px] sm:text-xs text-white/90 opacity-50">
|
|
478
|
+
<code>npx gradient-forge export --theme theme-nitro-midnight-blurple --format all</code>
|
|
479
|
+
</pre>
|
|
480
|
+
<div className="rounded-lg sm:rounded-xl border border-primary/20 bg-primary/5 p-2 sm:p-3">
|
|
481
|
+
<p className="text-[10px] sm:text-xs text-foreground">
|
|
482
|
+
🎉 Use <a href="/studio" className="text-primary underline">/studio</a> now to export themes!
|
|
483
|
+
</p>
|
|
484
|
+
</div>
|
|
485
|
+
</CardContent>
|
|
486
|
+
</Card>
|
|
487
|
+
|
|
488
|
+
<Card className="border-border/50 bg-background/60">
|
|
489
|
+
<CardHeader className="px-3 sm:px-4 pt-3 sm:pt-4 pb-2">
|
|
490
|
+
<CardTitle className="flex items-center gap-2 text-sm sm:text-base">
|
|
491
|
+
<FileJson className="h-4 w-4 sm:h-5 sm:w-5 text-secondary" />
|
|
492
|
+
Export Formats
|
|
493
|
+
</CardTitle>
|
|
494
|
+
<p className="text-xs sm:text-sm text-muted-foreground">
|
|
495
|
+
Multiple formats to fit any workflow or design tool.
|
|
496
|
+
</p>
|
|
497
|
+
</CardHeader>
|
|
498
|
+
<CardContent className="px-3 sm:px-4 pb-3 sm:pb-4">
|
|
499
|
+
<StaggerContainer className="grid grid-cols-2 gap-2 sm:gap-3" stagger={0.05}>
|
|
500
|
+
{["CSS Theme", "SCSS", "JSON Tokens", "Tailwind", "W3C Tokens", "Figma"].map((format) => (
|
|
501
|
+
<div
|
|
502
|
+
key={format}
|
|
503
|
+
className="rounded-xl sm:rounded-2xl border border-border/40 bg-background/50 p-2 sm:p-3 hover:border-secondary/30 transition-colors flex items-center gap-2"
|
|
504
|
+
>
|
|
505
|
+
<div className="h-1.5 w-1.5 sm:h-2 sm:w-2 rounded-full bg-primary" />
|
|
506
|
+
<span className="text-[10px] sm:text-xs">{format}</span>
|
|
507
|
+
</div>
|
|
508
|
+
))}
|
|
509
|
+
</StaggerContainer>
|
|
510
|
+
</CardContent>
|
|
511
|
+
</Card>
|
|
512
|
+
</div>
|
|
513
|
+
</AnimatedSection>
|
|
514
|
+
|
|
515
|
+
{/* Theme Exporter & Live Preview */}
|
|
516
|
+
<AnimatedSection animation="fadeUp">
|
|
517
|
+
<div className="grid gap-4 sm:gap-6 lg:grid-cols-[1.05fr_1fr]">
|
|
518
|
+
<ThemeExporter />
|
|
519
|
+
<Card className="border-border/50 bg-background/60">
|
|
520
|
+
<CardHeader className="px-3 sm:px-4 pt-3 sm:pt-4 pb-2">
|
|
521
|
+
<CardTitle className="flex items-center gap-2 text-sm sm:text-base">
|
|
522
|
+
<Sparkles className="h-4 w-4 sm:h-5 sm:w-5 text-primary" />
|
|
523
|
+
Live Preview
|
|
524
|
+
</CardTitle>
|
|
525
|
+
<p className="text-xs sm:text-sm text-muted-foreground">
|
|
526
|
+
Export tokens and watch the hero preview respond instantly.
|
|
527
|
+
</p>
|
|
528
|
+
</CardHeader>
|
|
529
|
+
<CardContent className="px-3 sm:px-4 pb-3 sm:pb-4 space-y-2 sm:space-y-3">
|
|
530
|
+
<div className="rounded-xl sm:rounded-2xl border border-border/40 bg-background/50 p-3 sm:p-4 text-xs sm:text-sm text-muted-foreground">
|
|
531
|
+
Use the studio to swap palettes and see the floating cards update in real time.
|
|
532
|
+
</div>
|
|
533
|
+
<MagneticButton strength={0.15}>
|
|
534
|
+
<Button variant="outline" size="sm" className="sm:size-default text-xs sm:text-sm" asChild>
|
|
535
|
+
<a href="/studio">Open Studio</a>
|
|
536
|
+
</Button>
|
|
537
|
+
</MagneticButton>
|
|
538
|
+
</CardContent>
|
|
539
|
+
</Card>
|
|
540
|
+
</div>
|
|
541
|
+
</AnimatedSection>
|
|
542
|
+
|
|
543
|
+
{/* Support & Quick Copy */}
|
|
544
|
+
<AnimatedSection animation="fadeUp">
|
|
545
|
+
<div className="grid gap-4 sm:gap-6 lg:grid-cols-[1.1fr_0.9fr]">
|
|
546
|
+
<Card className="border-border/50 bg-background/60">
|
|
547
|
+
<CardHeader className="px-3 sm:px-4 pt-3 sm:pt-4 pb-2">
|
|
548
|
+
<CardTitle className="flex items-center gap-2 text-sm sm:text-base">
|
|
549
|
+
<Coffee className="h-4 w-4 sm:h-5 sm:w-5 text-primary" />
|
|
550
|
+
Buy Me a Coffee
|
|
551
|
+
</CardTitle>
|
|
552
|
+
<p className="text-xs sm:text-sm text-muted-foreground">
|
|
553
|
+
Support the project and help fund new gradient packs.
|
|
554
|
+
</p>
|
|
555
|
+
</CardHeader>
|
|
556
|
+
<CardContent className="px-3 sm:px-4 pb-3 sm:pb-4 space-y-3 sm:space-y-4">
|
|
557
|
+
<div className="rounded-xl sm:rounded-2xl border border-border/40 bg-background/50 p-3 sm:p-4 text-xs sm:text-sm text-muted-foreground">
|
|
558
|
+
If this theming system helps your project, consider supporting the work. Your support keeps the
|
|
559
|
+
CLI, presets, and documentation growing.
|
|
560
|
+
</div>
|
|
561
|
+
<div className="flex flex-wrap gap-2 sm:gap-3">
|
|
562
|
+
<MagneticButton strength={0.15}>
|
|
563
|
+
<Button variant="glow" size="sm" className="sm:size-default text-xs sm:text-sm" asChild>
|
|
564
|
+
<a href="https://buymeacoffee.com/karannn" target="_blank" rel="noopener noreferrer">Buy a coffee</a>
|
|
565
|
+
</Button>
|
|
566
|
+
</MagneticButton>
|
|
567
|
+
<MagneticButton strength={0.15}>
|
|
568
|
+
<Button variant="outline" size="sm" className="sm:size-default text-xs sm:text-sm">Sponsor</Button>
|
|
569
|
+
</MagneticButton>
|
|
570
|
+
</div>
|
|
571
|
+
</CardContent>
|
|
572
|
+
</Card>
|
|
573
|
+
|
|
574
|
+
<Card className="border-border/50 bg-background/60">
|
|
575
|
+
<CardHeader className="px-3 sm:px-4 pt-3 sm:pt-4 pb-2">
|
|
576
|
+
<CardTitle className="flex items-center gap-2 text-sm sm:text-base">
|
|
577
|
+
<Code2 className="h-4 w-4 sm:h-5 sm:w-5 text-secondary" />
|
|
578
|
+
Quick Copy
|
|
579
|
+
</CardTitle>
|
|
580
|
+
<p className="text-xs sm:text-sm text-muted-foreground">
|
|
581
|
+
Grab the theme tokens and drop them into your next project.
|
|
582
|
+
</p>
|
|
583
|
+
</CardHeader>
|
|
584
|
+
<CardContent className="px-3 sm:px-4 pb-3 sm:pb-4 space-y-2 sm:space-y-3">
|
|
585
|
+
<div className="rounded-xl sm:rounded-2xl border border-border/40 bg-background/50 p-3 sm:p-4 text-[10px] sm:text-xs text-muted-foreground">
|
|
586
|
+
Use the export panel to copy CSS, Tailwind aliases, and the root theme hook.
|
|
587
|
+
</div>
|
|
588
|
+
<MagneticButton strength={0.15}>
|
|
589
|
+
<Button variant="outline" size="sm" className="sm:size-default text-xs sm:text-sm" asChild>
|
|
590
|
+
<a href="/docs">Read the install guide</a>
|
|
591
|
+
</Button>
|
|
592
|
+
</MagneticButton>
|
|
593
|
+
</CardContent>
|
|
594
|
+
</Card>
|
|
595
|
+
</div>
|
|
596
|
+
</AnimatedSection>
|
|
597
|
+
</section>
|
|
598
|
+
</main>
|
|
599
|
+
);
|
|
600
|
+
}
|