create-brainerce-store 1.52.0 → 1.52.1

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/README.md CHANGED
@@ -22,7 +22,7 @@ It's a starting point, not a lock-in: the entire look lives in `src/ui/` + `glob
22
22
  npm create brainerce-store@latest my-store -- --connection-id vc_xxx --canvas
23
23
  ```
24
24
 
25
- `--canvas` ships `src/ui/` as bare, semantic, essentially-unstyled skeletons (`DESIGN ME` markers included) with zero aesthetic opinion — commerce stays fully wired. It's the starting point for designing a storefront from scratch with an AI session, and the authoring substrate for new gallery designs. Canvas mode skips design packs and theme overlays entirely.
25
+ `--canvas` ships `src/ui/` as bare, semantic, essentially-unstyled skeletons (`DESIGN ME` markers included) with zero aesthetic opinion — commerce stays fully wired. It's the starting point for designing a storefront from scratch with an AI session, and the authoring substrate for new gallery designs. Canvas mode skips the design pack entirely.
26
26
 
27
27
  ## AI-first by default
28
28
 
@@ -51,7 +51,6 @@ Full details: [TEMPLATE-ARCHITECTURE.md](./TEMPLATE-ARCHITECTURE.md).
51
51
  | `--language <lang>` | Store language (`en`, `he`) | fetched from store |
52
52
  | `--pkg-manager <pm>` | `npm`, `pnpm`, `yarn`, `bun` | auto-detected |
53
53
  | `--framework <fw>` | `nextjs` (Vite/Remix coming) | `nextjs` |
54
- | `--theme <name>` | Token theme (`minimal`, `luxury`, `playful`) — kept for backward compat | `minimal` |
55
54
  | `--api-url <url>` | Brainerce API base URL (or `BRAINERCE_API_URL` env) | auto-discovered |
56
55
  | `--no-git` | Skip git initialization | git on |
57
56
  | `--no-install` | Skip dependency installation | install on |
package/dist/index.js CHANGED
@@ -31,7 +31,7 @@ var require_package = __commonJS({
31
31
  "package.json"(exports2, module2) {
32
32
  module2.exports = {
33
33
  name: "create-brainerce-store",
34
- version: "1.52.0",
34
+ version: "1.52.1",
35
35
  description: "Scaffold a production-ready e-commerce storefront connected to Brainerce",
36
36
  bin: {
37
37
  "create-brainerce-store": "dist/index.js"
@@ -322,7 +322,6 @@ async function runInteractive(defaults) {
322
322
  connectionId: defaults.connectionId || response.connectionId,
323
323
  language: response.language || defaults.language || "en",
324
324
  framework: defaults.framework || "nextjs",
325
- theme: response.theme || defaults.theme || "minimal",
326
325
  design: response.design || defaults.design || "atelier",
327
326
  pkgManager: response.pkgManager || defaults.pkgManager || detectInvokingPackageManager()
328
327
  };
@@ -721,7 +720,7 @@ var program = new import_commander.Command();
721
720
  program.name("create-brainerce-store").description("Scaffold a production-ready e-commerce storefront connected to Brainerce").version(pkg.version).argument("[project-name]", "Name for the project directory").option("--connection-id <id>", "Brainerce vibe-coded connection ID (vc_*)").option(
722
721
  "--api-url <url>",
723
722
  "Brainerce API base URL (overrides BRAINERCE_API_URL env, defaults to https://api.brainerce.com)"
724
- ).option("--language <lang>", "Store language (en, he)").addOption(new import_commander.Option("--framework <framework>", "Framework to use").default("nextjs").hideHelp()).option("--theme <theme>", "Token theme to apply (kept for backward compat)", "minimal").addOption(new import_commander.Option("--design <design>", "Storefront design pack").hideHelp()).option("--pkg-manager <manager>", "Package manager (npm, pnpm, yarn, bun)").option(
723
+ ).option("--language <lang>", "Store language (en, he)").addOption(new import_commander.Option("--framework <framework>", "Framework to use").default("nextjs").hideHelp()).addOption(new import_commander.Option("--design <design>", "Storefront design pack").hideHelp()).option("--pkg-manager <manager>", "Package manager (npm, pnpm, yarn, bun)").option(
725
724
  "--canvas",
726
725
  "Scaffold src/ui as bare unstyled skeletons \u2014 a blank canvas for AI-driven design (commerce stays fully wired)"
727
726
  ).option("--no-git", "Skip git initialization").option("--no-install", "Skip dependency installation").action(async (projectNameArg, options) => {
@@ -755,7 +754,6 @@ program.name("create-brainerce-store").description("Scaffold a production-ready
755
754
  const VALID_LANGUAGES = ["en", "he"];
756
755
  const VALID_PKG_MANAGERS = ["npm", "pnpm", "yarn", "bun"];
757
756
  const VALID_FRAMEWORKS = ["nextjs"];
758
- const VALID_THEMES = ["minimal", "luxury", "playful"];
759
757
  const VALID_DESIGNS = ["minimal", "atelier"];
760
758
  let language = options.language;
761
759
  if (language && !VALID_LANGUAGES.includes(language)) {
@@ -771,11 +769,6 @@ program.name("create-brainerce-store").description("Scaffold a production-ready
771
769
  );
772
770
  process.exit(1);
773
771
  }
774
- let theme = options.theme;
775
- if (!VALID_THEMES.includes(theme)) {
776
- logger.error(`Invalid --theme "${theme}". Expected one of: ${VALID_THEMES.join(", ")}`);
777
- process.exit(1);
778
- }
779
772
  let design = options.design;
780
773
  if (design && !VALID_DESIGNS.includes(design)) {
781
774
  logger.error(`Invalid --design "${design}". Expected one of: ${VALID_DESIGNS.join(", ")}`);
@@ -829,7 +822,6 @@ program.name("create-brainerce-store").description("Scaffold a production-ready
829
822
  connectionId,
830
823
  language: languageDefault,
831
824
  framework,
832
- theme,
833
825
  design,
834
826
  pkgManager,
835
827
  canvas
@@ -838,7 +830,6 @@ program.name("create-brainerce-store").description("Scaffold a production-ready
838
830
  connectionId = answers.connectionId;
839
831
  language = answers.language;
840
832
  framework = answers.framework;
841
- theme = answers.theme;
842
833
  design = answers.design;
843
834
  pkgManager = answers.pkgManager;
844
835
  }
@@ -886,7 +877,6 @@ program.name("create-brainerce-store").description("Scaffold a production-ready
886
877
  connectionId,
887
878
  apiBaseUrl: resolvedApiUrl,
888
879
  framework,
889
- theme,
890
880
  storeName: storeInfo.name,
891
881
  currency: storeInfo.currency,
892
882
  language: language || storeInfo.language,
@@ -907,9 +897,16 @@ program.name("create-brainerce-store").description("Scaffold a production-ready
907
897
  const gitOpts = { cwd, stdio: ["ignore", "ignore", "pipe"] };
908
898
  execFileSync("git", ["init"], gitOpts);
909
899
  execFileSync("git", ["add", "-A"], gitOpts);
900
+ let hasIdentity = true;
901
+ try {
902
+ execFileSync("git", ["config", "user.email"], gitOpts);
903
+ } catch {
904
+ hasIdentity = false;
905
+ }
906
+ const identityArgs = hasIdentity ? [] : ["-c", "user.name=Brainerce", "-c", "user.email=scaffold@brainerce.com"];
910
907
  execFileSync(
911
908
  "git",
912
- ["commit", "-m", "Initial commit from create-brainerce-store"],
909
+ [...identityArgs, "commit", "-m", "Initial commit from create-brainerce-store"],
913
910
  gitOpts
914
911
  );
915
912
  gitSpinner.succeed("Git initialized");
@@ -922,8 +919,14 @@ program.name("create-brainerce-store").description("Scaffold a production-ready
922
919
  if (!skipInstall) {
923
920
  const installSpinner = createSpinner(`Installing dependencies with ${pkgManager}...`);
924
921
  installSpinner.start();
922
+ const installDir = scaffoldInPlace ? "." : projectName;
925
923
  try {
926
- await installDependencies(scaffoldInPlace ? "." : projectName, pkgManager);
924
+ const installArgs = pkgManager === "pnpm" ? ["--ignore-workspace"] : [];
925
+ await installDependencies(installDir, pkgManager, { args: installArgs });
926
+ const fsExtra = require("fs-extra");
927
+ if (!await fsExtra.pathExists(import_path2.default.join(installDir, "node_modules"))) {
928
+ throw new Error("Install completed but node_modules was not created.");
929
+ }
927
930
  installSpinner.succeed("Dependencies installed");
928
931
  } catch (err) {
929
932
  installSpinner.fail("Dependency installation failed");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-brainerce-store",
3
- "version": "1.52.0",
3
+ "version": "1.52.1",
4
4
  "description": "Scaffold a production-ready e-commerce storefront connected to Brainerce",
5
5
  "bin": {
6
6
  "create-brainerce-store": "dist/index.js"
@@ -1,405 +0,0 @@
1
- @tailwind base;
2
- @tailwind components;
3
- @tailwind utilities;
4
-
5
- @layer base {
6
- :root {
7
- --background: 20 14% 4%;
8
- --foreground: 38 25% 86%;
9
- --primary: 38 60% 55%;
10
- --primary-foreground: 20 14% 4%;
11
- --secondary: 20 10% 10%;
12
- --secondary-foreground: 38 25% 86%;
13
- --muted: 20 10% 12%;
14
- --muted-foreground: 30 10% 50%;
15
- --accent: 38 60% 55%;
16
- --accent-foreground: 20 14% 4%;
17
- --destructive: 0 72% 51%;
18
- --destructive-foreground: 38 25% 86%;
19
- --border: 30 10% 16%;
20
- --input: 30 10% 16%;
21
- --ring: 38 60% 55%;
22
- --card: 20 12% 7%;
23
- --card-foreground: 38 25% 86%;
24
- --popover: 20 10% 10%;
25
- --popover-foreground: 38 25% 86%;
26
- --radius: 0.25rem;
27
-
28
- /* Luxury-specific tokens */
29
- --gold: 38 60% 55%;
30
- --gold-light: 38 50% 72%;
31
- --gold-dark: 38 70% 40%;
32
- --surface: 20 12% 7%;
33
- --surface-elevated: 20 10% 10%;
34
- }
35
-
36
- * {
37
- @apply border-border;
38
- }
39
-
40
- body {
41
- @apply bg-background text-foreground antialiased;
42
- letter-spacing: 0.01em;
43
- line-height: 1.7;
44
- }
45
-
46
- /* Luxury typography — editorial serif hierarchy */
47
- h1,
48
- h2,
49
- h3,
50
- h4 {
51
- letter-spacing: 0.04em;
52
- font-weight: 500;
53
- line-height: 1.2;
54
- }
55
-
56
- h1 {
57
- text-transform: uppercase;
58
- letter-spacing: 0.1em;
59
- font-weight: 400;
60
- line-height: 1.1;
61
- }
62
-
63
- h2 {
64
- text-transform: uppercase;
65
- letter-spacing: 0.06em;
66
- }
67
-
68
- /* Elegant link underline animation */
69
- a:not([class*="bg-"]) {
70
- position: relative;
71
- transition: color 0.3s ease, opacity 0.3s ease;
72
- }
73
-
74
- main a:not([class*="bg-"]):not([class*="group"])::after {
75
- content: '';
76
- position: absolute;
77
- bottom: -1px;
78
- left: 0;
79
- width: 0;
80
- height: 1px;
81
- background: hsl(var(--gold));
82
- transition: width 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
83
- }
84
-
85
- main a:not([class*="bg-"]):not([class*="group"]):hover::after {
86
- width: 100%;
87
- }
88
-
89
- /* Refined text selection */
90
- ::selection {
91
- background: hsl(var(--gold) / 0.3);
92
- color: hsl(38 25% 96%);
93
- }
94
-
95
- /* Subtle body texture overlay */
96
- body::before {
97
- content: '';
98
- position: fixed;
99
- inset: 0;
100
- background: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)' opacity='0.015'/%3E%3C/svg%3E");
101
- pointer-events: none;
102
- z-index: 9999;
103
- }
104
-
105
- /* Custom scrollbar */
106
- ::-webkit-scrollbar {
107
- width: 5px;
108
- }
109
-
110
- ::-webkit-scrollbar-track {
111
- background: hsl(20 14% 4%);
112
- }
113
-
114
- ::-webkit-scrollbar-thumb {
115
- background: hsl(30 10% 18%);
116
- border-radius: 3px;
117
- }
118
-
119
- ::-webkit-scrollbar-thumb:hover {
120
- background: hsl(var(--gold) / 0.5);
121
- }
122
-
123
- /* Smooth focus states */
124
- :focus-visible {
125
- outline: 1px solid hsl(var(--gold) / 0.5);
126
- outline-offset: 3px;
127
- }
128
- }
129
-
130
- @layer components {
131
- /* ─── Buttons ─── */
132
-
133
- /* Primary CTA — gold with shimmer sweep */
134
- button[class*="bg-primary"],
135
- a[class*="bg-primary"] {
136
- position: relative;
137
- overflow: hidden;
138
- font-weight: 500;
139
- letter-spacing: 0.08em;
140
- text-transform: uppercase;
141
- font-size: 0.78rem;
142
- border: 1px solid hsl(var(--gold) / 0.3);
143
- transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
144
- }
145
-
146
- button[class*="bg-primary"]:hover,
147
- a[class*="bg-primary"]:hover {
148
- box-shadow:
149
- 0 0 20px hsl(var(--gold) / 0.2),
150
- 0 4px 16px hsl(0 0% 0% / 0.3);
151
- border-color: hsl(var(--gold) / 0.6);
152
- opacity: 1 !important;
153
- }
154
-
155
- button[class*="bg-primary"]::after,
156
- a[class*="bg-primary"]::after {
157
- content: '';
158
- position: absolute;
159
- top: -50%;
160
- left: -75%;
161
- width: 50%;
162
- height: 200%;
163
- background: linear-gradient(
164
- 90deg,
165
- transparent,
166
- hsl(var(--gold-light) / 0.12),
167
- hsl(var(--gold-light) / 0.2),
168
- transparent
169
- );
170
- transform: skewX(-20deg);
171
- transition: left 0.7s ease;
172
- pointer-events: none;
173
- }
174
-
175
- button[class*="bg-primary"]:hover::after,
176
- a[class*="bg-primary"]:hover::after {
177
- left: 130%;
178
- }
179
-
180
- /* Secondary/ghost buttons — thin border, minimal */
181
- [class*="bg-secondary"] {
182
- border: 1px solid hsl(var(--border));
183
- transition: all 0.3s ease;
184
- letter-spacing: 0.04em;
185
- text-transform: uppercase;
186
- font-size: 0.8rem;
187
- }
188
-
189
- [class*="bg-secondary"]:hover {
190
- border-color: hsl(var(--gold) / 0.4);
191
- background: hsl(var(--surface-elevated)) !important;
192
- }
193
-
194
- /* ─── Product Cards ─── */
195
-
196
- [class*="group"][class*="border"] {
197
- transition: all 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94);
198
- border-color: hsl(var(--border) / 0.5);
199
- background: hsl(var(--surface));
200
- }
201
-
202
- [class*="group"][class*="border"]:hover {
203
- border-color: hsl(var(--gold) / 0.25);
204
- box-shadow:
205
- 0 8px 40px hsl(0 0% 0% / 0.5),
206
- 0 0 0 1px hsl(var(--gold) / 0.08);
207
- }
208
-
209
- /* Product image — slow cinematic zoom */
210
- [class*="group-hover\\:scale-105"] {
211
- transition: transform 1s cubic-bezier(0.25, 0.46, 0.45, 0.94) !important;
212
- }
213
-
214
- /* Product image overlay on hover — subtle dark gradient */
215
- [class*="group"] [class*="aspect-square"] {
216
- position: relative;
217
- }
218
-
219
- [class*="group"]:hover [class*="aspect-square"]::after {
220
- content: '';
221
- position: absolute;
222
- inset: 0;
223
- background: linear-gradient(
224
- to top,
225
- hsl(20 14% 4% / 0.3),
226
- transparent 50%
227
- );
228
- pointer-events: none;
229
- transition: opacity 0.5s ease;
230
- }
231
-
232
- /* ─── Form Elements ─── */
233
-
234
- input[class*="border-border"],
235
- select[class*="border-border"],
236
- textarea[class*="border-border"] {
237
- background: hsl(var(--surface)) !important;
238
- transition: all 0.3s ease;
239
- }
240
-
241
- input[class*="border-border"]:focus,
242
- select[class*="border-border"]:focus,
243
- textarea[class*="border-border"]:focus {
244
- border-color: hsl(var(--gold) / 0.5) !important;
245
- box-shadow: 0 0 0 3px hsl(var(--gold) / 0.08);
246
- background: hsl(var(--surface-elevated)) !important;
247
- }
248
-
249
- /* Placeholder text */
250
- input::placeholder,
251
- textarea::placeholder {
252
- letter-spacing: 0.03em;
253
- font-size: 0.85rem;
254
- }
255
-
256
- /* ─── Navigation & Header ─── */
257
-
258
- header[class*="sticky"] {
259
- backdrop-filter: blur(16px) saturate(1.2);
260
- background: hsl(20 14% 4% / 0.8) !important;
261
- border-bottom: 1px solid hsl(var(--gold) / 0.08) !important;
262
- }
263
-
264
- /* Nav links */
265
- nav a {
266
- letter-spacing: 0.06em;
267
- text-transform: uppercase;
268
- font-size: 0.75rem;
269
- font-weight: 500;
270
- }
271
-
272
- /* ─── Badges & Tags ─── */
273
-
274
- [class*="bg-muted"][class*="text-xs"] {
275
- text-transform: uppercase;
276
- letter-spacing: 0.1em;
277
- font-size: 0.6rem;
278
- font-weight: 600;
279
- border: 1px solid hsl(var(--border));
280
- }
281
-
282
- /* Sale badges — dark red, refined */
283
- [class*="bg-destructive"] {
284
- background: hsl(0 60% 38%) !important;
285
- font-weight: 600;
286
- letter-spacing: 0.06em;
287
- text-transform: uppercase;
288
- font-size: 0.65rem;
289
- }
290
-
291
- /* ─── Price Display ─── */
292
-
293
- /* Gold gradient on prices */
294
- [class*="font-bold"][class*="text-lg"],
295
- [class*="font-bold"][class*="text-xl"],
296
- [class*="font-bold"][class*="text-2xl"] {
297
- background: linear-gradient(
298
- 135deg,
299
- hsl(var(--gold-light)),
300
- hsl(var(--gold)),
301
- hsl(var(--gold-dark))
302
- );
303
- -webkit-background-clip: text;
304
- -webkit-text-fill-color: transparent;
305
- background-clip: text;
306
- }
307
-
308
- /* Strikethrough original prices */
309
- [class*="line-through"] {
310
- opacity: 0.4;
311
- }
312
-
313
- /* ─── Dividers & Separators ─── */
314
-
315
- hr {
316
- border-color: hsl(var(--border) / 0.3);
317
- }
318
-
319
- /* Decorative gold separator */
320
- main > section + section {
321
- border-top: 1px solid hsl(var(--gold) / 0.06);
322
- }
323
-
324
- /* ─── Cart & Checkout ─── */
325
-
326
- /* Sticky summary panel */
327
- [class*="sticky"][class*="top-"] {
328
- background: hsl(var(--surface));
329
- border: 1px solid hsl(var(--border) / 0.5);
330
- }
331
- }
332
-
333
- /* ─── Animations ─── */
334
-
335
- /* Elegant fade-in-up */
336
- @keyframes luxury-fade-in {
337
- from {
338
- opacity: 0;
339
- transform: translateY(16px);
340
- }
341
- to {
342
- opacity: 1;
343
- transform: translateY(0);
344
- }
345
- }
346
-
347
- main > * {
348
- animation: luxury-fade-in 0.7s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
349
- }
350
-
351
- main > *:nth-child(2) {
352
- animation-delay: 0.1s;
353
- }
354
-
355
- main > *:nth-child(3) {
356
- animation-delay: 0.2s;
357
- }
358
-
359
- main > *:nth-child(4) {
360
- animation-delay: 0.3s;
361
- }
362
-
363
- /* Staggered grid item reveal */
364
- @keyframes luxury-grid-item {
365
- from {
366
- opacity: 0;
367
- transform: translateY(12px) scale(0.98);
368
- }
369
- to {
370
- opacity: 1;
371
- transform: translateY(0) scale(1);
372
- }
373
- }
374
-
375
- [class*="grid"] > [class*="group"] {
376
- animation: luxury-grid-item 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
377
- }
378
-
379
- [class*="grid"] > [class*="group"]:nth-child(2) {
380
- animation-delay: 0.08s;
381
- }
382
-
383
- [class*="grid"] > [class*="group"]:nth-child(3) {
384
- animation-delay: 0.16s;
385
- }
386
-
387
- [class*="grid"] > [class*="group"]:nth-child(4) {
388
- animation-delay: 0.24s;
389
- }
390
-
391
- [class*="grid"] > [class*="group"]:nth-child(5) {
392
- animation-delay: 0.32s;
393
- }
394
-
395
- [class*="grid"] > [class*="group"]:nth-child(6) {
396
- animation-delay: 0.4s;
397
- }
398
-
399
- [class*="grid"] > [class*="group"]:nth-child(7) {
400
- animation-delay: 0.48s;
401
- }
402
-
403
- [class*="grid"] > [class*="group"]:nth-child(8) {
404
- animation-delay: 0.56s;
405
- }
@@ -1,23 +0,0 @@
1
- {
2
- "name": "Luxury",
3
- "description": "Dark, sophisticated design with Cormorant Garamond serif font and warm gold accents",
4
- "font": {
5
- "family": "Cormorant Garamond",
6
- "import": "next/font/google"
7
- },
8
- "colors": {
9
- "background": "20 14% 4%",
10
- "foreground": "38 25% 86%",
11
- "primary": "38 60% 55%",
12
- "primary-foreground": "20 14% 4%",
13
- "secondary": "20 10% 10%",
14
- "secondary-foreground": "38 25% 86%",
15
- "muted": "20 10% 12%",
16
- "muted-foreground": "30 10% 50%",
17
- "accent": "38 60% 55%",
18
- "accent-foreground": "20 14% 4%",
19
- "destructive": "0 72% 51%",
20
- "border": "30 10% 16%"
21
- },
22
- "radius": "0.25rem"
23
- }
@@ -1,36 +0,0 @@
1
- @tailwind base;
2
- @tailwind components;
3
- @tailwind utilities;
4
-
5
- @layer base {
6
- :root {
7
- --background: 0 0% 100%;
8
- --foreground: 0 0% 9%;
9
- --primary: 0 0% 9%;
10
- --primary-foreground: 0 0% 98%;
11
- --secondary: 0 0% 96%;
12
- --secondary-foreground: 0 0% 9%;
13
- --muted: 0 0% 96%;
14
- --muted-foreground: 0 0% 45%;
15
- --accent: 0 0% 96%;
16
- --accent-foreground: 0 0% 9%;
17
- --destructive: 0 84% 60%;
18
- --destructive-foreground: 0 0% 98%;
19
- --border: 0 0% 90%;
20
- --input: 0 0% 90%;
21
- --ring: 0 0% 9%;
22
- --card: 0 0% 100%;
23
- --card-foreground: 0 0% 9%;
24
- --popover: 0 0% 100%;
25
- --popover-foreground: 0 0% 9%;
26
- --radius: 0.5rem;
27
- }
28
-
29
- * {
30
- @apply border-border;
31
- }
32
-
33
- body {
34
- @apply bg-background text-foreground antialiased;
35
- }
36
- }
@@ -1,23 +0,0 @@
1
- {
2
- "name": "Minimal",
3
- "description": "Clean, neutral design with Inter font and medium radius",
4
- "font": {
5
- "family": "Inter",
6
- "import": "next/font/google"
7
- },
8
- "colors": {
9
- "background": "0 0% 100%",
10
- "foreground": "0 0% 9%",
11
- "primary": "0 0% 9%",
12
- "primary-foreground": "0 0% 98%",
13
- "secondary": "0 0% 96%",
14
- "secondary-foreground": "0 0% 9%",
15
- "muted": "0 0% 96%",
16
- "muted-foreground": "0 0% 45%",
17
- "accent": "0 0% 96%",
18
- "accent-foreground": "0 0% 9%",
19
- "destructive": "0 84% 60%",
20
- "border": "0 0% 90%"
21
- },
22
- "radius": "0.5rem"
23
- }
@@ -1,406 +0,0 @@
1
- @tailwind base;
2
- @tailwind components;
3
- @tailwind utilities;
4
-
5
- @layer base {
6
- :root {
7
- --background: 0 0% 99%;
8
- --foreground: 260 25% 16%;
9
- --primary: 330 75% 56%;
10
- --primary-foreground: 0 0% 100%;
11
- --secondary: 260 50% 94%;
12
- --secondary-foreground: 260 25% 16%;
13
- --muted: 270 30% 95%;
14
- --muted-foreground: 260 10% 45%;
15
- --accent: 280 60% 60%;
16
- --accent-foreground: 0 0% 100%;
17
- --destructive: 0 84% 60%;
18
- --destructive-foreground: 0 0% 100%;
19
- --border: 270 20% 88%;
20
- --input: 270 20% 88%;
21
- --ring: 330 75% 56%;
22
- --card: 0 0% 100%;
23
- --card-foreground: 260 25% 16%;
24
- --popover: 0 0% 100%;
25
- --popover-foreground: 260 25% 16%;
26
- --radius: 1rem;
27
-
28
- /* Playful-specific tokens */
29
- --pink: 330 75% 56%;
30
- --purple: 280 60% 60%;
31
- --lavender: 260 50% 94%;
32
- --peach: 20 80% 88%;
33
- --mint: 160 50% 88%;
34
- }
35
-
36
- * {
37
- @apply border-border;
38
- }
39
-
40
- body {
41
- @apply bg-background text-foreground antialiased;
42
- line-height: 1.65;
43
- }
44
-
45
- /* Playful typography — friendly, bold, tight */
46
- h1,
47
- h2,
48
- h3,
49
- h4 {
50
- font-weight: 700;
51
- letter-spacing: -0.02em;
52
- line-height: 1.2;
53
- }
54
-
55
- h1 {
56
- font-weight: 800;
57
- letter-spacing: -0.03em;
58
- }
59
-
60
- /* Fun colorful selection */
61
- ::selection {
62
- background: hsl(var(--pink) / 0.25);
63
- color: hsl(260 25% 16%);
64
- }
65
-
66
- /* Colorful focus rings */
67
- :focus-visible {
68
- outline: 2.5px solid hsl(var(--purple));
69
- outline-offset: 3px;
70
- border-radius: var(--radius);
71
- }
72
-
73
- /* Playful scrollbar */
74
- ::-webkit-scrollbar {
75
- width: 8px;
76
- }
77
-
78
- ::-webkit-scrollbar-track {
79
- background: hsl(var(--lavender));
80
- }
81
-
82
- ::-webkit-scrollbar-thumb {
83
- background: linear-gradient(
84
- 180deg,
85
- hsl(var(--pink)),
86
- hsl(var(--purple))
87
- );
88
- border-radius: 999px;
89
- }
90
- }
91
-
92
- @layer components {
93
- /* ─── Buttons ─── */
94
-
95
- /* Primary CTA — gradient with bounce and glow */
96
- button[class*="bg-primary"],
97
- a[class*="bg-primary"] {
98
- font-weight: 700;
99
- letter-spacing: 0.01em;
100
- background: linear-gradient(
101
- 135deg,
102
- hsl(var(--pink)),
103
- hsl(330 80% 52%),
104
- hsl(var(--purple))
105
- ) !important;
106
- background-size: 200% 200%;
107
- box-shadow:
108
- 0 4px 14px hsl(var(--pink) / 0.3),
109
- 0 2px 6px hsl(var(--purple) / 0.15);
110
- transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
111
- border: none;
112
- }
113
-
114
- button[class*="bg-primary"]:hover,
115
- a[class*="bg-primary"]:hover {
116
- transform: translateY(-3px) scale(1.03);
117
- box-shadow:
118
- 0 8px 28px hsl(var(--pink) / 0.4),
119
- 0 4px 12px hsl(var(--purple) / 0.2);
120
- background-position: 100% 0;
121
- opacity: 1 !important;
122
- }
123
-
124
- button[class*="bg-primary"]:active,
125
- a[class*="bg-primary"]:active {
126
- transform: translateY(0) scale(0.97);
127
- box-shadow: 0 2px 8px hsl(var(--pink) / 0.2);
128
- }
129
-
130
- /* Secondary buttons — soft pill with hover pop */
131
- [class*="bg-secondary"] {
132
- border-radius: 999px !important;
133
- font-weight: 600;
134
- transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
135
- }
136
-
137
- [class*="bg-secondary"]:hover {
138
- background: hsl(var(--lavender)) !important;
139
- transform: translateY(-2px);
140
- box-shadow: 0 4px 16px hsl(var(--purple) / 0.12);
141
- }
142
-
143
- /* ─── Product Cards ─── */
144
-
145
- [class*="group"][class*="border"] {
146
- border-radius: var(--radius);
147
- overflow: hidden;
148
- border: 2px solid hsl(var(--border));
149
- background: white;
150
- transition: all 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
151
- }
152
-
153
- [class*="group"][class*="border"]:hover {
154
- transform: translateY(-6px) rotate(-0.5deg);
155
- border-color: hsl(var(--pink) / 0.3);
156
- box-shadow:
157
- 0 16px 40px hsl(var(--purple) / 0.12),
158
- 0 6px 16px hsl(var(--pink) / 0.1);
159
- }
160
-
161
- /* Product image hover — fun overshoot zoom */
162
- [class*="group-hover\\:scale-105"] {
163
- transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) !important;
164
- }
165
-
166
- [class*="group"]:hover [class*="group-hover\\:scale-105"] {
167
- transform: scale(1.08) !important;
168
- }
169
-
170
- /* ─── Form Elements ─── */
171
-
172
- input[class*="border-border"],
173
- select[class*="border-border"],
174
- textarea[class*="border-border"] {
175
- border-radius: var(--radius);
176
- border-width: 2px;
177
- transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
178
- }
179
-
180
- input[class*="border-border"]:focus,
181
- select[class*="border-border"]:focus,
182
- textarea[class*="border-border"]:focus {
183
- border-color: hsl(var(--purple)) !important;
184
- box-shadow: 0 0 0 4px hsl(var(--purple) / 0.1);
185
- transform: scale(1.01);
186
- }
187
-
188
- input::placeholder,
189
- textarea::placeholder {
190
- color: hsl(var(--muted-foreground) / 0.6);
191
- }
192
-
193
- /* ─── Navigation & Header ─── */
194
-
195
- header[class*="sticky"] {
196
- border-bottom: none !important;
197
- box-shadow: 0 4px 20px hsl(var(--purple) / 0.06);
198
- background: hsl(0 0% 99% / 0.9) !important;
199
- backdrop-filter: blur(10px);
200
- }
201
-
202
- /* Nav link hover — colorful underline */
203
- nav a {
204
- position: relative;
205
- font-weight: 600;
206
- transition: color 0.2s ease;
207
- }
208
-
209
- nav a::after {
210
- content: '';
211
- position: absolute;
212
- bottom: -2px;
213
- left: 50%;
214
- width: 0;
215
- height: 3px;
216
- background: linear-gradient(90deg, hsl(var(--pink)), hsl(var(--purple)));
217
- border-radius: 999px;
218
- transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
219
- transform: translateX(-50%);
220
- }
221
-
222
- nav a:hover::after {
223
- width: 100%;
224
- }
225
-
226
- nav a:hover {
227
- color: hsl(var(--pink));
228
- }
229
-
230
- /* ─── Badges & Tags ─── */
231
-
232
- /* Category/filter pills */
233
- [class*="bg-muted"][class*="text-xs"] {
234
- border-radius: 999px;
235
- font-weight: 700;
236
- padding-left: 0.85rem;
237
- padding-right: 0.85rem;
238
- transition: all 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
239
- }
240
-
241
- [class*="bg-muted"][class*="text-xs"]:hover {
242
- background: hsl(var(--lavender)) !important;
243
- transform: scale(1.05);
244
- }
245
-
246
- /* Sale/discount badges — fun wiggle + pill */
247
- [class*="bg-destructive"] {
248
- border-radius: 999px;
249
- font-weight: 800;
250
- box-shadow: 0 2px 8px hsl(0 84% 60% / 0.3);
251
- animation: playful-wiggle 3s ease-in-out infinite;
252
- }
253
-
254
- /* ─── Price Display ─── */
255
-
256
- [class*="font-bold"][class*="text-lg"],
257
- [class*="font-bold"][class*="text-xl"],
258
- [class*="font-bold"][class*="text-2xl"] {
259
- color: hsl(var(--pink));
260
- }
261
-
262
- /* Strikethrough — more playful */
263
- [class*="line-through"] {
264
- opacity: 0.4;
265
- text-decoration-color: hsl(var(--purple) / 0.4);
266
- text-decoration-thickness: 2px;
267
- }
268
-
269
- /* ─── Dividers ─── */
270
-
271
- hr {
272
- border: none;
273
- height: 3px;
274
- background: linear-gradient(
275
- 90deg,
276
- transparent,
277
- hsl(var(--lavender)),
278
- hsl(var(--pink) / 0.2),
279
- hsl(var(--lavender)),
280
- transparent
281
- );
282
- border-radius: 999px;
283
- }
284
-
285
- /* ─── Cart & Checkout ─── */
286
-
287
- /* Sticky summary — playful card */
288
- [class*="sticky"][class*="top-"] {
289
- border-radius: var(--radius);
290
- border: 2px solid hsl(var(--border));
291
- box-shadow: 0 4px 20px hsl(var(--purple) / 0.06);
292
- }
293
-
294
- /* Quantity buttons */
295
- button[class*="h-8"][class*="w-8"],
296
- button[class*="h-10"][class*="w-10"] {
297
- border-radius: 999px !important;
298
- transition: all 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
299
- }
300
-
301
- button[class*="h-8"][class*="w-8"]:hover,
302
- button[class*="h-10"][class*="w-10"]:hover {
303
- transform: scale(1.1);
304
- background: hsl(var(--lavender)) !important;
305
- }
306
-
307
- /* ─── Images ─── */
308
-
309
- /* Product images — rounded */
310
- [class*="aspect-square"] {
311
- border-radius: calc(var(--radius) - 2px);
312
- overflow: hidden;
313
- }
314
- }
315
-
316
- /* ─── Animations ─── */
317
-
318
- /* Bouncy slide-up entrance */
319
- @keyframes playful-slide-up {
320
- from {
321
- opacity: 0;
322
- transform: translateY(24px) scale(0.96);
323
- }
324
- 50% {
325
- transform: translateY(-6px) scale(1.01);
326
- }
327
- to {
328
- opacity: 1;
329
- transform: translateY(0) scale(1);
330
- }
331
- }
332
-
333
- /* Wiggle for discount badges */
334
- @keyframes playful-wiggle {
335
- 0%,
336
- 85%,
337
- 100% {
338
- transform: rotate(0deg);
339
- }
340
- 90% {
341
- transform: rotate(-3deg);
342
- }
343
- 95% {
344
- transform: rotate(3deg);
345
- }
346
- }
347
-
348
- /* Pop-in for grid items */
349
- @keyframes playful-pop-in {
350
- from {
351
- opacity: 0;
352
- transform: scale(0.9) translateY(16px);
353
- }
354
- 60% {
355
- transform: scale(1.02) translateY(-2px);
356
- }
357
- to {
358
- opacity: 1;
359
- transform: scale(1) translateY(0);
360
- }
361
- }
362
-
363
- main > * {
364
- animation: playful-slide-up 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) both;
365
- }
366
-
367
- main > *:nth-child(2) {
368
- animation-delay: 0.06s;
369
- }
370
-
371
- main > *:nth-child(3) {
372
- animation-delay: 0.12s;
373
- }
374
-
375
- /* Staggered grid items — playful pop */
376
- [class*="grid"] > [class*="group"] {
377
- animation: playful-pop-in 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) both;
378
- }
379
-
380
- [class*="grid"] > [class*="group"]:nth-child(2) {
381
- animation-delay: 0.06s;
382
- }
383
-
384
- [class*="grid"] > [class*="group"]:nth-child(3) {
385
- animation-delay: 0.12s;
386
- }
387
-
388
- [class*="grid"] > [class*="group"]:nth-child(4) {
389
- animation-delay: 0.18s;
390
- }
391
-
392
- [class*="grid"] > [class*="group"]:nth-child(5) {
393
- animation-delay: 0.24s;
394
- }
395
-
396
- [class*="grid"] > [class*="group"]:nth-child(6) {
397
- animation-delay: 0.3s;
398
- }
399
-
400
- [class*="grid"] > [class*="group"]:nth-child(7) {
401
- animation-delay: 0.36s;
402
- }
403
-
404
- [class*="grid"] > [class*="group"]:nth-child(8) {
405
- animation-delay: 0.42s;
406
- }
@@ -1,23 +0,0 @@
1
- {
2
- "name": "Playful",
3
- "description": "Warm, vibrant design with Nunito rounded font and energetic pink-purple palette",
4
- "font": {
5
- "family": "Nunito",
6
- "import": "next/font/google"
7
- },
8
- "colors": {
9
- "background": "0 0% 99%",
10
- "foreground": "260 25% 16%",
11
- "primary": "330 75% 56%",
12
- "primary-foreground": "0 0% 100%",
13
- "secondary": "260 50% 94%",
14
- "secondary-foreground": "260 25% 16%",
15
- "muted": "270 30% 95%",
16
- "muted-foreground": "260 10% 45%",
17
- "accent": "280 60% 60%",
18
- "accent-foreground": "0 0% 100%",
19
- "destructive": "0 84% 60%",
20
- "border": "270 20% 88%"
21
- },
22
- "radius": "1rem"
23
- }