get-shit-pretty 0.7.3 → 0.8.2
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/bin/theme-css.js +331 -0
- package/gsp/agents/gsp-brand-coherence.md +7 -0
- package/gsp/hooks/hooks.json +1 -1
- package/gsp/skills/gsp-brand-brief/SKILL.md +50 -5
- package/gsp/skills/gsp-brand-guidelines/SKILL.md +51 -31
- package/gsp/skills/gsp-brand-guidelines/design-tokens.md +2 -0
- package/gsp/skills/gsp-brand-guidelines/guidelines-structure.md +167 -0
- package/gsp/skills/gsp-brand-guidelines/methodology/gsp-brand-coherence.md +86 -0
- package/gsp/skills/gsp-brand-guidelines/methodology/gsp-brand-engineer.md +13 -5
- package/gsp/skills/gsp-brand-guidelines/token-mapping.md +16 -319
- package/gsp/skills/gsp-brand-identity/SKILL.md +1 -1
- package/gsp/skills/gsp-brand-refine/SKILL.md +5 -6
- package/gsp/skills/gsp-brand-research/SKILL.md +1 -1
- package/gsp/skills/gsp-brand-strategy/SKILL.md +1 -1
- package/gsp/skills/gsp-design-system/SKILL.md +1 -1
- package/gsp/skills/gsp-doctor/SKILL.md +51 -3
- package/gsp/skills/gsp-progress/SKILL.md +1 -1
- package/gsp/skills/gsp-project-brief/SKILL.md +40 -6
- package/gsp/skills/gsp-project-build/SKILL.md +27 -31
- package/gsp/skills/gsp-project-build/flows/figma.md +50 -0
- package/gsp/skills/gsp-project-build/flows/revision.md +64 -0
- package/gsp/skills/gsp-project-build/methodology/gsp-project-builder.md +84 -1
- package/gsp/skills/gsp-project-build/shadcn-composition.md +217 -0
- package/gsp/skills/gsp-project-critique/SKILL.md +3 -1
- package/gsp/skills/gsp-project-design/SKILL.md +3 -2
- package/gsp/skills/gsp-project-design/methodology/gsp-project-designer.md +28 -21
- package/gsp/skills/gsp-project-research/SKILL.md +3 -1
- package/gsp/skills/gsp-project-review/SKILL.md +10 -1
- package/gsp/skills/gsp-scaffold/SKILL.md +67 -11
- package/gsp/skills/gsp-scaffold/shadcn-rules.md +433 -0
- package/gsp/skills/gsp-scaffold/shadcn-theming.md +310 -0
- package/gsp/skills/gsp-start/SKILL.md +18 -2
- package/gsp/skills/gsp-style/SKILL.md +1 -1
- package/gsp/skills/gsp-style/style-preset-schema.md +59 -14
- package/gsp/skills/gsp-style/styles/academia.yml +58 -8
- package/gsp/skills/gsp-style/styles/art-deco.yml +39 -7
- package/gsp/skills/gsp-style/styles/bauhaus.yml +39 -8
- package/gsp/skills/gsp-style/styles/bold-typography.yml +39 -8
- package/gsp/skills/gsp-style/styles/botanical.yml +39 -9
- package/gsp/skills/gsp-style/styles/claymorphism.yml +39 -9
- package/gsp/skills/gsp-style/styles/cyberpunk.yml +39 -7
- package/gsp/skills/gsp-style/styles/enterprise.yml +39 -10
- package/gsp/skills/gsp-style/styles/flat-design.yml +39 -9
- package/gsp/skills/gsp-style/styles/fluent.yml +39 -10
- package/gsp/skills/gsp-style/styles/glassmorphism.yml +39 -8
- package/gsp/skills/gsp-style/styles/humanist-literary.yml +39 -9
- package/gsp/skills/gsp-style/styles/industrial.yml +59 -9
- package/gsp/skills/gsp-style/styles/kinetic.yml +32 -7
- package/gsp/skills/gsp-style/styles/liquid-glass.yml +59 -9
- package/gsp/skills/gsp-style/styles/luxury.yml +59 -9
- package/gsp/skills/gsp-style/styles/material.yml +59 -9
- package/gsp/skills/gsp-style/styles/maximalism.yml +32 -6
- package/gsp/skills/gsp-style/styles/minimal-dark.yml +32 -7
- package/gsp/skills/gsp-style/styles/modern-dark.yml +32 -7
- package/gsp/skills/gsp-style/styles/monochrome.yml +59 -10
- package/gsp/skills/gsp-style/styles/neubrutalism.yml +59 -9
- package/gsp/skills/gsp-style/styles/neumorphism.yml +32 -7
- package/gsp/skills/gsp-style/styles/newsprint.yml +32 -7
- package/gsp/skills/gsp-style/styles/nothing.yml +44 -13
- package/gsp/skills/gsp-style/styles/organic.yml +42 -9
- package/gsp/skills/gsp-style/styles/playful-geometric.yml +43 -9
- package/gsp/skills/gsp-style/styles/professional.yml +41 -10
- package/gsp/skills/gsp-style/styles/retro.yml +42 -8
- package/gsp/skills/gsp-style/styles/saas.yml +42 -9
- package/gsp/skills/gsp-style/styles/sketch.yml +42 -9
- package/gsp/skills/gsp-style/styles/swiss-minimalist.yml +41 -10
- package/gsp/skills/gsp-style/styles/terminal.yml +42 -8
- package/gsp/skills/gsp-style/styles/vaporwave.yml +42 -7
- package/gsp/skills/gsp-style/styles/web3.yml +42 -9
- package/gsp/templates/branding/brief.md +9 -0
- package/gsp/templates/branding/config.json +1 -1
- package/gsp/templates/design-claude.md +6 -0
- package/gsp/templates/phases/design.md +0 -8
- package/gsp/templates/phases/patterns.md +2 -2
- package/gsp/templates/projects/config.json +6 -3
- package/gsp/templates/projects/state.md +1 -1
- package/gsp/templates/system/STACK.md +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
# shadcn/ui Theming Reference
|
|
2
|
+
|
|
3
|
+
Agent reference for building and fixing shadcn/ui themes. Source: https://ui.shadcn.com/docs/theming
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## How theming works
|
|
8
|
+
|
|
9
|
+
shadcn uses **CSS custom properties** as semantic tokens. Components reference tokens like `bg-primary` or `text-muted-foreground` — never raw colors. Tokens are defined in `:root` (light) and `.dark` (dark), then aliased into Tailwind via `@theme inline`.
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
CSS custom property (:root / .dark)
|
|
13
|
+
↓
|
|
14
|
+
@theme inline alias (--color-primary: var(--primary))
|
|
15
|
+
↓
|
|
16
|
+
Tailwind utility (bg-primary, text-primary-foreground)
|
|
17
|
+
↓
|
|
18
|
+
Component (Button, Card, etc.)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Changing a token in `:root`/`.dark` immediately affects every component that uses it. Never hardcode colors in components.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Full token reference
|
|
26
|
+
|
|
27
|
+
All tokens are OKLCH values (`oklch(L C H)`). No `hsl()` wrapper.
|
|
28
|
+
|
|
29
|
+
### Surface tokens (background / foreground pairs)
|
|
30
|
+
|
|
31
|
+
| Token | Controls | Used by |
|
|
32
|
+
|-------|----------|---------|
|
|
33
|
+
| `--background` / `--foreground` | Default app background and text | Page shell, body |
|
|
34
|
+
| `--card` / `--card-foreground` | Elevated surfaces | `Card`, panels |
|
|
35
|
+
| `--popover` / `--popover-foreground` | Floating surfaces | `Popover`, `DropdownMenu`, `ContextMenu` |
|
|
36
|
+
| `--muted` / `--muted-foreground` | Subtle surfaces and subdued text | Descriptions, placeholders, helper text, empty states |
|
|
37
|
+
|
|
38
|
+
**Convention:** the base token is the surface color; `-foreground` is the text/icon color sitting on it. The `background` suffix is omitted from the surface token — `primary` is the surface, `primary-foreground` is the text on it.
|
|
39
|
+
|
|
40
|
+
### Semantic action tokens
|
|
41
|
+
|
|
42
|
+
| Token | Controls | Used by |
|
|
43
|
+
|-------|----------|---------|
|
|
44
|
+
| `--primary` / `--primary-foreground` | High-emphasis brand actions | Default `Button`, selected states, active accents |
|
|
45
|
+
| `--secondary` / `--secondary-foreground` | Lower-emphasis filled actions | Secondary buttons, supporting UI |
|
|
46
|
+
| `--accent` / `--accent-foreground` | Hover, focus, and active states | Ghost buttons, menu highlights, hovered rows |
|
|
47
|
+
| `--destructive` | Destructive actions and errors | Destructive `Button`, invalid states |
|
|
48
|
+
|
|
49
|
+
### Form and border tokens
|
|
50
|
+
|
|
51
|
+
| Token | Controls | Used by |
|
|
52
|
+
|-------|----------|---------|
|
|
53
|
+
| `--border` | Default borders and separators | Cards, menus, tables, separators |
|
|
54
|
+
| `--input` | Form control borders | `Input`, `Textarea`, `Select`, outline controls |
|
|
55
|
+
| `--ring` | Focus rings | Buttons, inputs, checkboxes, focusable elements |
|
|
56
|
+
|
|
57
|
+
### Chart tokens
|
|
58
|
+
|
|
59
|
+
| Token | Controls |
|
|
60
|
+
|-------|----------|
|
|
61
|
+
| `--chart-1` … `--chart-5` | Default chart palette |
|
|
62
|
+
|
|
63
|
+
**Chart token rules (Recharts v3):**
|
|
64
|
+
- Reference as `fill="var(--chart-1)"` or `fill="var(--color-chart-1)"` — **no `hsl()` wrapper**
|
|
65
|
+
- Must appear in both `:root` AND `.dark` blocks
|
|
66
|
+
- Use in `chartConfig` as `color: "var(--chart-1)"`
|
|
67
|
+
|
|
68
|
+
### Sidebar tokens
|
|
69
|
+
|
|
70
|
+
| Token | Controls |
|
|
71
|
+
|-------|----------|
|
|
72
|
+
| `--sidebar` / `--sidebar-foreground` | Sidebar surface and default text |
|
|
73
|
+
| `--sidebar-primary` / `--sidebar-primary-foreground` | Active items, icon tiles, badges |
|
|
74
|
+
| `--sidebar-accent` / `--sidebar-accent-foreground` | Hover states, open items |
|
|
75
|
+
| `--sidebar-border` | Sidebar borders and separators |
|
|
76
|
+
| `--sidebar-ring` | Focus rings inside sidebar |
|
|
77
|
+
|
|
78
|
+
**Sidebar width:** set via inline style on `<SidebarProvider>`, not as a global CSS token:
|
|
79
|
+
```tsx
|
|
80
|
+
<SidebarProvider style={{ "--sidebar-width": "19rem" } as React.CSSProperties}>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Radius tokens
|
|
84
|
+
|
|
85
|
+
`--radius` is the single source of truth. All other radius values derive from it:
|
|
86
|
+
|
|
87
|
+
```css
|
|
88
|
+
@theme inline {
|
|
89
|
+
--radius-sm: calc(var(--radius) * 0.6);
|
|
90
|
+
--radius-md: calc(var(--radius) * 0.8);
|
|
91
|
+
--radius-lg: var(--radius); /* base */
|
|
92
|
+
--radius-xl: calc(var(--radius) * 1.4);
|
|
93
|
+
--radius-2xl: calc(var(--radius) * 1.8);
|
|
94
|
+
--radius-3xl: calc(var(--radius) * 2.2);
|
|
95
|
+
--radius-4xl: calc(var(--radius) * 2.6);
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Change `--radius` in `:root` to shift the entire radius scale.
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Minimal globals.css structure (Tailwind v4)
|
|
104
|
+
|
|
105
|
+
```css
|
|
106
|
+
@import "tailwindcss";
|
|
107
|
+
@import "shadcn/tailwind.css"; /* NOT tw-animate-css */
|
|
108
|
+
|
|
109
|
+
@custom-variant dark (&:is(.dark *));
|
|
110
|
+
|
|
111
|
+
@theme inline {
|
|
112
|
+
/* Color aliases — do NOT put actual values here */
|
|
113
|
+
--color-background: var(--background);
|
|
114
|
+
--color-foreground: var(--foreground);
|
|
115
|
+
--color-card: var(--card);
|
|
116
|
+
--color-card-foreground: var(--card-foreground);
|
|
117
|
+
--color-popover: var(--popover);
|
|
118
|
+
--color-popover-foreground: var(--popover-foreground);
|
|
119
|
+
--color-primary: var(--primary);
|
|
120
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
121
|
+
--color-secondary: var(--secondary);
|
|
122
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
123
|
+
--color-muted: var(--muted);
|
|
124
|
+
--color-muted-foreground: var(--muted-foreground);
|
|
125
|
+
--color-accent: var(--accent);
|
|
126
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
127
|
+
--color-destructive: var(--destructive);
|
|
128
|
+
--color-border: var(--border);
|
|
129
|
+
--color-input: var(--input);
|
|
130
|
+
--color-ring: var(--ring);
|
|
131
|
+
--color-chart-1: var(--chart-1);
|
|
132
|
+
--color-chart-2: var(--chart-2);
|
|
133
|
+
--color-chart-3: var(--chart-3);
|
|
134
|
+
--color-chart-4: var(--chart-4);
|
|
135
|
+
--color-chart-5: var(--chart-5);
|
|
136
|
+
--color-sidebar: var(--sidebar);
|
|
137
|
+
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
138
|
+
--color-sidebar-primary: var(--sidebar-primary);
|
|
139
|
+
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
140
|
+
--color-sidebar-accent: var(--sidebar-accent);
|
|
141
|
+
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
142
|
+
--color-sidebar-border: var(--sidebar-border);
|
|
143
|
+
--color-sidebar-ring: var(--sidebar-ring);
|
|
144
|
+
/* Radius scale */
|
|
145
|
+
--radius-sm: calc(var(--radius) * 0.6);
|
|
146
|
+
--radius-md: calc(var(--radius) * 0.8);
|
|
147
|
+
--radius-lg: var(--radius);
|
|
148
|
+
--radius-xl: calc(var(--radius) * 1.4);
|
|
149
|
+
--radius-2xl: calc(var(--radius) * 1.8);
|
|
150
|
+
--radius-3xl: calc(var(--radius) * 2.2);
|
|
151
|
+
--radius-4xl: calc(var(--radius) * 2.6);
|
|
152
|
+
/* Fonts (literal values, not var() self-references) */
|
|
153
|
+
--font-sans: "Inter", sans-serif;
|
|
154
|
+
--font-mono: "JetBrains Mono", monospace;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
:root {
|
|
158
|
+
--radius: 0.625rem;
|
|
159
|
+
--background: oklch(1 0 0);
|
|
160
|
+
--foreground: oklch(0.145 0 0);
|
|
161
|
+
/* … all tokens … */
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.dark {
|
|
165
|
+
--background: oklch(0.145 0 0);
|
|
166
|
+
--foreground: oklch(0.985 0 0);
|
|
167
|
+
/* … all dark overrides … chart tokens MUST be here too … */
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
@layer base {
|
|
171
|
+
* {
|
|
172
|
+
@apply border-border outline-ring/50;
|
|
173
|
+
}
|
|
174
|
+
body {
|
|
175
|
+
@apply bg-background text-foreground;
|
|
176
|
+
}
|
|
177
|
+
button:not(:disabled), [role="button"]:not(:disabled) {
|
|
178
|
+
cursor: pointer;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Adding custom tokens
|
|
186
|
+
|
|
187
|
+
To add a new semantic token (e.g. `warning`):
|
|
188
|
+
|
|
189
|
+
```css
|
|
190
|
+
/* 1. Define values in :root and .dark */
|
|
191
|
+
:root {
|
|
192
|
+
--warning: oklch(0.84 0.16 84);
|
|
193
|
+
--warning-foreground: oklch(0.28 0.07 46);
|
|
194
|
+
}
|
|
195
|
+
.dark {
|
|
196
|
+
--warning: oklch(0.41 0.11 46);
|
|
197
|
+
--warning-foreground: oklch(0.99 0.02 95);
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**Tailwind v4** — alias in `@theme inline`:
|
|
202
|
+
|
|
203
|
+
```css
|
|
204
|
+
@theme inline {
|
|
205
|
+
--color-warning: var(--warning);
|
|
206
|
+
--color-warning-foreground: var(--warning-foreground);
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**Tailwind v3** — register in `tailwind.config.js` instead:
|
|
211
|
+
|
|
212
|
+
```js
|
|
213
|
+
module.exports = {
|
|
214
|
+
theme: {
|
|
215
|
+
extend: {
|
|
216
|
+
colors: {
|
|
217
|
+
warning: "oklch(var(--warning) / <alpha-value>)",
|
|
218
|
+
"warning-foreground": "oklch(var(--warning-foreground) / <alpha-value>)",
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Check `tailwindVersion` from `npx shadcn@latest info` to know which to use. Always edit the file at `tailwindCssFile` from the same output — never create a new CSS file.
|
|
226
|
+
|
|
227
|
+
Now use `bg-warning` and `text-warning-foreground` in components.
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## Changing the theme via preset
|
|
232
|
+
|
|
233
|
+
The fastest way to change the full theme is via `apply`:
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
# Apply a preset to an existing project (overwrites detected components, fonts, CSS vars)
|
|
237
|
+
npx shadcn@latest apply --preset a2r6bw
|
|
238
|
+
npx shadcn@latest apply nova # shorthand for named preset
|
|
239
|
+
|
|
240
|
+
# Preserve existing components — update config and CSS only
|
|
241
|
+
npx shadcn@latest init --preset nova --force --no-reinstall
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Named presets: `nova`, `vega`, `maia`, `lyra`, `mira`, `luma`
|
|
245
|
+
|
|
246
|
+
Preset codes (e.g. `a2r6bw`) come from `ui.shadcn.com/create`. Pass them directly — never decode them manually.
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Dark mode setup (Next.js)
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
npm install next-themes
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
```tsx
|
|
257
|
+
// components/theme-provider.tsx
|
|
258
|
+
"use client"
|
|
259
|
+
import { ThemeProvider as NextThemesProvider } from "next-themes"
|
|
260
|
+
export function ThemeProvider({ children, ...props }) {
|
|
261
|
+
return <NextThemesProvider {...props}>{children}</NextThemesProvider>
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
```tsx
|
|
266
|
+
// app/layout.tsx
|
|
267
|
+
import { ThemeProvider } from "@/components/theme-provider"
|
|
268
|
+
|
|
269
|
+
export default function RootLayout({ children }) {
|
|
270
|
+
return (
|
|
271
|
+
<html lang="en" suppressHydrationWarning>
|
|
272
|
+
<body>
|
|
273
|
+
<ThemeProvider attribute="class" defaultTheme="system" enableSystem disableTransitionOnChange>
|
|
274
|
+
{children}
|
|
275
|
+
</ThemeProvider>
|
|
276
|
+
</body>
|
|
277
|
+
</html>
|
|
278
|
+
)
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
- `attribute="class"` — sets `.dark` class on `<html>`
|
|
283
|
+
- `suppressHydrationWarning` — required to avoid SSR/client mismatch on theme class
|
|
284
|
+
- For dark-by-default or light-only apps, skip `ThemeProvider` and hardcode `<html className="dark">` or leave it unset
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## Common theming bugs and fixes
|
|
289
|
+
|
|
290
|
+
| Symptom | Cause | Fix |
|
|
291
|
+
|---------|-------|-----|
|
|
292
|
+
| Colors look washed out / all grey | `components.json` has `cssVariables: false` | Re-init with `cssVariables: true` (must delete + reinstall components) |
|
|
293
|
+
| Dark mode colors not applying | `.dark` block missing from `globals.css` | Add `.dark { }` block with all dark overrides |
|
|
294
|
+
| Chart colors ignore dark mode | Chart tokens only in `:root`, not `.dark` | Add `--chart-1` … `--chart-5` to `.dark` block |
|
|
295
|
+
| `bg-primary` renders nothing | Token missing from `@theme inline` | Add `--color-primary: var(--primary)` to `@theme inline` |
|
|
296
|
+
| Sidebar wrong color | Using old `--sidebar-background` token name | Rename to `--sidebar` (shadcn v2 token rename) |
|
|
297
|
+
| Font not applying | `--font-sans: var(--font-sans)` self-reference | Use literal value: `--font-sans: "Inter", sans-serif` |
|
|
298
|
+
| Tailwind v4 `hsl()` not resolving | Tokens are OKLCH but wrapped in `hsl()` | Remove `hsl()` wrapper — write `oklch(L C H)` directly |
|
|
299
|
+
| Animations missing / broken | Using `tw-animate-css` | Switch to `@import "shadcn/tailwind.css"` |
|
|
300
|
+
| `shadcn add` overwrites custom tokens | Components installed after token injection | Install all components first, then write tokens |
|
|
301
|
+
| Radius not scaling | `--radius-sm` etc. hardcoded instead of derived | Use `calc(var(--radius) * N)` in `@theme inline` |
|
|
302
|
+
| Buttons missing pointer cursor | Tailwind v4 changed button cursor default | Add cursor rule to `@layer base` (see template above) |
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## Base color options
|
|
307
|
+
|
|
308
|
+
`tailwind.baseColor` in `components.json` controls the default neutral values generated at init. Options: **Neutral**, **Stone**, **Zinc**, **Mauve**, **Olive**, **Mist**, **Taupe**.
|
|
309
|
+
|
|
310
|
+
This is set once at init and should not be changed — changing it requires deleting and reinstalling all components.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gsp-start
|
|
3
|
-
description: Start
|
|
3
|
+
description: Start the GSP pipeline — use when starting a new feature, I want to build X, help me design, let's work on, or kicking off any new work
|
|
4
4
|
user-invocable: true
|
|
5
5
|
allowed-tools:
|
|
6
6
|
- Read
|
|
@@ -39,7 +39,7 @@ Scan `.design/` for existing brands and projects:
|
|
|
39
39
|
- Check `.design/branding/` for brand directories (each has a `config.json` with `project_type: "brand"`)
|
|
40
40
|
- Check `.design/projects/` for project directories (each has a `config.json` with `project_type: "design"`)
|
|
41
41
|
- Check for legacy flat `.design/config.json` at root (pre-0.4.0 structure)
|
|
42
|
-
- For each brand/project found, read its `config.json`
|
|
42
|
+
- For each brand/project found, read its `config.json` for project metadata (name, created, preferences) and read its `STATE.md` for phase progress (the phase table with pending/complete/in-progress/needs-revision statuses)
|
|
43
43
|
|
|
44
44
|
### Step 1b: Quick codebase check (inline — no agents)
|
|
45
45
|
|
|
@@ -51,6 +51,15 @@ If `package.json` exists, read it to extract:
|
|
|
51
51
|
|
|
52
52
|
Quick glob for component count: `src/components/**/*` or `components/**/*`.
|
|
53
53
|
|
|
54
|
+
**Monorepo detection:** After reading root `package.json`, glob for `apps/*/package.json` and `packages/*/package.json`. If any are found:
|
|
55
|
+
- Set `REPO_TYPE = monorepo`
|
|
56
|
+
- Read each discovered package.json to extract app name + primary framework dependency
|
|
57
|
+
- Build an app list: `[(apps/web, Next.js), (apps/mobile, Expo), ...]`
|
|
58
|
+
|
|
59
|
+
If no nested package.json files found: set `REPO_TYPE = single`.
|
|
60
|
+
|
|
61
|
+
Also read `.design/system/STACK.md` if it exists — this is the **global stack declaration** for the workspace. When present, use it as the authoritative source for framework, styling, component library, and architecture. Surface it in the codebase summary box so every new project starts knowing the declared stack.
|
|
62
|
+
|
|
54
63
|
Also scan for brand-relevant assets:
|
|
55
64
|
- Logo files: glob for `**/logo*.{svg,png}`, `**/icon*.{svg,png}` in public/assets directories
|
|
56
65
|
- Font files: glob for `**/*.{woff,woff2,ttf,otf}` in public/fonts or similar
|
|
@@ -80,9 +89,16 @@ If codebase was detected, show a summary box:
|
|
|
80
89
|
│ components 47 detected │
|
|
81
90
|
│ assets logo.svg, 2 font files │
|
|
82
91
|
│ type existing codebase │
|
|
92
|
+
│ repo type monorepo (3 apps detected)│
|
|
93
|
+
│ apps web · mobile · docs │
|
|
94
|
+
│ stack declared (STACK.md ✓) │
|
|
83
95
|
└──────────────────────────────────────────┘
|
|
84
96
|
```
|
|
85
97
|
|
|
98
|
+
For single-app repos, show `repo type: single app` and omit the `apps` row.
|
|
99
|
+
|
|
100
|
+
Show `stack: declared (STACK.md ✓)` when `.design/system/STACK.md` exists — this signals to the user that every new project will inherit the workspace stack. If STACK.md is missing for an existing codebase, show `stack: undeclared — run /gsp-design-system`.
|
|
101
|
+
|
|
86
102
|
Use `AskUserQuestion` with:
|
|
87
103
|
- **New brand** — "Create a brand identity from scratch"
|
|
88
104
|
- **Evolve existing brand** — "I have brand materials to work with"
|
|
@@ -127,7 +127,7 @@ Copy the preset `.yml` to the output path as the brand's style source:
|
|
|
127
127
|
|
|
128
128
|
If a `.yml` already exists at the output path, use `AskUserQuestion`: "A style preset already exists — overwrite?" with options **Overwrite** and **Cancel**. If cancelled, skip and proceed.
|
|
129
129
|
|
|
130
|
-
The `.yml` IS the token source of truth — no separate `tokens.json` needed.
|
|
130
|
+
The `.yml` IS the token source of truth — no separate `tokens.json` needed. Token names in `.yml` map 1:1 to shadcn/ui CSS variable names. Run `node bin/theme-css.js {preset-name}.yml` to generate a ready-to-paste `:root`/`.dark` CSS block.
|
|
131
131
|
|
|
132
132
|
## Step 7: Write STYLE.md
|
|
133
133
|
|
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
Template for brand-derived style preset files (`{brand-name}.yml`). All token values must trace to foundation chunks. See any preset in `styles/` for a complete example.
|
|
4
4
|
|
|
5
|
+
Token names map 1:1 to shadcn/ui CSS variables — no translation layer. `bin/theme-css.js` reads this file and outputs a ready-to-paste `:root`/`.dark` block.
|
|
6
|
+
|
|
7
|
+
**Value formats:**
|
|
8
|
+
- Solid colors: `"#RRGGBB"` hex — theme-css.js converts to OKLCH
|
|
9
|
+
- Alpha colors (translucent presets): `"oklch(L% C H / A)"` — passed through as-is
|
|
10
|
+
- Shadows, borders, font stacks: raw CSS strings
|
|
11
|
+
|
|
5
12
|
```yaml
|
|
6
13
|
name: {brand-slug}
|
|
7
14
|
description: {one-line brand aesthetic summary}
|
|
@@ -10,18 +17,47 @@ source: brand # marks this as brand-derived, not a GSP preset
|
|
|
10
17
|
|
|
11
18
|
tokens:
|
|
12
19
|
color:
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
# Core — map directly to shadcn/ui :root CSS vars
|
|
21
|
+
background: "{hex}" # --background
|
|
22
|
+
foreground: "{hex}" # --foreground (primary text)
|
|
23
|
+
card: "{hex}" # --card (panel/card fill; use oklch/alpha for translucent)
|
|
24
|
+
card-foreground: "{hex}" # --card-foreground
|
|
25
|
+
popover: "{hex}" # --popover (usually same as card)
|
|
26
|
+
popover-foreground: "{hex}" # --popover-foreground
|
|
27
|
+
primary: "{hex}" # --primary
|
|
28
|
+
primary-foreground: "{hex}" # --primary-foreground
|
|
29
|
+
secondary: "{hex}" # --secondary
|
|
30
|
+
secondary-foreground: "{hex}" # --secondary-foreground
|
|
31
|
+
accent: "{hex}" # --accent
|
|
32
|
+
accent-foreground: "{hex}" # --accent-foreground
|
|
33
|
+
muted: "{hex}" # --muted
|
|
34
|
+
muted-foreground: "{hex}" # --muted-foreground
|
|
35
|
+
destructive: "{hex}" # --destructive (replaces legacy error)
|
|
36
|
+
border: "{hex}" # --border (absorbs legacy shape.border-color)
|
|
37
|
+
input: "{hex}" # --input (usually same as border)
|
|
38
|
+
ring: "{hex}" # --ring (focus ring, usually same as primary)
|
|
39
|
+
|
|
40
|
+
# Sidebar — explicit for full design control
|
|
41
|
+
sidebar: "{hex}" # --sidebar (shadcn uses --sidebar, not --sidebar-background)
|
|
42
|
+
sidebar-foreground: "{hex}" # --sidebar-foreground
|
|
43
|
+
sidebar-primary: "{hex}" # --sidebar-primary
|
|
44
|
+
sidebar-primary-foreground: "{hex}" # --sidebar-primary-foreground
|
|
45
|
+
sidebar-accent: "{hex}" # --sidebar-accent
|
|
46
|
+
sidebar-accent-foreground: "{hex}" # --sidebar-accent-foreground
|
|
47
|
+
sidebar-border: "{hex}" # --sidebar-border
|
|
48
|
+
sidebar-ring: "{hex}" # --sidebar-ring
|
|
49
|
+
|
|
50
|
+
# Chart — 5 intentional data-viz colors (distinct, accessible at small sizes)
|
|
51
|
+
chart-1: "{hex}" # --chart-1
|
|
52
|
+
chart-2: "{hex}" # --chart-2
|
|
53
|
+
chart-3: "{hex}" # --chart-3
|
|
54
|
+
chart-4: "{hex}" # --chart-4
|
|
55
|
+
chart-5: "{hex}" # --chart-5
|
|
56
|
+
|
|
57
|
+
# Extras — generate as custom properties (--success, --warning, --info)
|
|
21
58
|
success: "{hex}"
|
|
22
59
|
warning: "{hex}"
|
|
23
60
|
info: "{hex}"
|
|
24
|
-
muted: "{hex}"
|
|
25
61
|
|
|
26
62
|
typography:
|
|
27
63
|
font-family-primary: "{font stack}" # from identity/typography.md
|
|
@@ -32,11 +68,12 @@ tokens:
|
|
|
32
68
|
line-height-base: {number}
|
|
33
69
|
|
|
34
70
|
shape:
|
|
35
|
-
border-radius-
|
|
71
|
+
# border-radius-lg → --radius; sm/md used in pattern references
|
|
72
|
+
border-radius-sm: "{px}"
|
|
36
73
|
border-radius-md: "{px}"
|
|
37
74
|
border-radius-lg: "{px}"
|
|
38
75
|
border-width: "{px}"
|
|
39
|
-
border-color
|
|
76
|
+
# Note: border-color removed — use color.border above
|
|
40
77
|
|
|
41
78
|
elevation:
|
|
42
79
|
shadow-sm: "{value}"
|
|
@@ -55,11 +92,19 @@ tokens:
|
|
|
55
92
|
|
|
56
93
|
dark_mode:
|
|
57
94
|
color:
|
|
95
|
+
# Only list tokens that differ from light mode
|
|
58
96
|
background: "{hex}"
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
97
|
+
foreground: "{hex}"
|
|
98
|
+
card: "{hex}"
|
|
99
|
+
card-foreground: "{hex}"
|
|
62
100
|
muted: "{hex}"
|
|
101
|
+
muted-foreground: "{hex}"
|
|
102
|
+
border: "{hex}"
|
|
103
|
+
input: "{hex}"
|
|
104
|
+
sidebar: "{hex}"
|
|
105
|
+
sidebar-border: "{hex}"
|
|
106
|
+
# chart-1 through chart-5 only if they change in dark mode
|
|
107
|
+
# primary/accent/destructive only if they change in dark mode
|
|
63
108
|
|
|
64
109
|
intensity:
|
|
65
110
|
variance: {1-10} # layout creativity — 1=strict grid, 10=experimental
|
|
@@ -5,17 +5,44 @@ trend_ref: trends/academia.md
|
|
|
5
5
|
|
|
6
6
|
tokens:
|
|
7
7
|
color:
|
|
8
|
+
# Core — shadcn/ui CSS vars
|
|
9
|
+
background: "#FEF7ED"
|
|
10
|
+
foreground: "#1C1917"
|
|
11
|
+
card: "#F5F5F4"
|
|
12
|
+
card-foreground: "#1C1917"
|
|
13
|
+
popover: "#F5F5F4"
|
|
14
|
+
popover-foreground: "#1C1917"
|
|
8
15
|
primary: "#7C2D12"
|
|
16
|
+
primary-foreground: "#FFFFFF"
|
|
9
17
|
secondary: "#92400E"
|
|
18
|
+
secondary-foreground: "#FFFFFF"
|
|
10
19
|
accent: "#C9A962"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
20
|
+
accent-foreground: "#1C1917"
|
|
21
|
+
muted: "#E7E5E4"
|
|
22
|
+
muted-foreground: "#78716C"
|
|
23
|
+
destructive: "#DC2626"
|
|
24
|
+
border: "#D6D3D1"
|
|
25
|
+
input: "#D6D3D1"
|
|
26
|
+
ring: "#7C2D12"
|
|
27
|
+
# Sidebar
|
|
28
|
+
sidebar: "#F5F5F4"
|
|
29
|
+
sidebar-foreground: "#1C1917"
|
|
30
|
+
sidebar-primary: "#7C2D12"
|
|
31
|
+
sidebar-primary-foreground: "#FFFFFF"
|
|
32
|
+
sidebar-accent: "#E7E5E4"
|
|
33
|
+
sidebar-accent-foreground: "#1C1917"
|
|
34
|
+
sidebar-border: "#D6D3D1"
|
|
35
|
+
sidebar-ring: "#7C2D12"
|
|
36
|
+
# Extras
|
|
16
37
|
success: "#16A34A"
|
|
17
38
|
warning: "#D97706"
|
|
18
39
|
info: "#2563EB"
|
|
40
|
+
# Chart — data-viz colors (distinct, accessible at small sizes)
|
|
41
|
+
chart-1: "#7C2D12" # crimson mahogany (primary)
|
|
42
|
+
chart-2: "#C9A962" # burnished brass (accent)
|
|
43
|
+
chart-3: "#2563EB" # ink blue (info)
|
|
44
|
+
chart-4: "#16A34A" # library green (success)
|
|
45
|
+
chart-5: "#92400E" # dark amber (secondary)
|
|
19
46
|
|
|
20
47
|
typography:
|
|
21
48
|
font-family-primary: "EB Garamond, Georgia, serif"
|
|
@@ -31,7 +58,6 @@ tokens:
|
|
|
31
58
|
border-radius-md: "4px"
|
|
32
59
|
border-radius-lg: "8px"
|
|
33
60
|
border-width: "1px"
|
|
34
|
-
border-color: "#D6D3D1"
|
|
35
61
|
|
|
36
62
|
elevation:
|
|
37
63
|
shadow-sm: "0 1px 2px rgba(0,0,0,0.05)"
|
|
@@ -59,8 +85,32 @@ tokens:
|
|
|
59
85
|
dark_mode:
|
|
60
86
|
color:
|
|
61
87
|
background: "#1C1714"
|
|
62
|
-
|
|
63
|
-
|
|
88
|
+
foreground: "#E8DFD4"
|
|
89
|
+
card: "#251E19"
|
|
90
|
+
card-foreground: "#E8DFD4"
|
|
91
|
+
popover: "#251E19"
|
|
92
|
+
popover-foreground: "#E8DFD4"
|
|
93
|
+
primary: "#7C2D12"
|
|
94
|
+
primary-foreground: "#FFFFFF"
|
|
95
|
+
secondary: "#92400E"
|
|
96
|
+
secondary-foreground: "#FFFFFF"
|
|
97
|
+
accent: "#C9A962"
|
|
98
|
+
accent-foreground: "#1C1917"
|
|
99
|
+
muted: "#292524"
|
|
100
|
+
muted-foreground: "#A8A29E"
|
|
101
|
+
destructive: "#DC2626"
|
|
102
|
+
border: "#44403C"
|
|
103
|
+
input: "#44403C"
|
|
104
|
+
ring: "#7C2D12"
|
|
105
|
+
# Sidebar
|
|
106
|
+
sidebar: "#251E19"
|
|
107
|
+
sidebar-foreground: "#E8DFD4"
|
|
108
|
+
sidebar-primary: "#7C2D12"
|
|
109
|
+
sidebar-primary-foreground: "#FFFFFF"
|
|
110
|
+
sidebar-accent: "#292524"
|
|
111
|
+
sidebar-accent-foreground: "#E8DFD4"
|
|
112
|
+
sidebar-border: "#44403C"
|
|
113
|
+
sidebar-ring: "#7C2D12"
|
|
64
114
|
|
|
65
115
|
intensity:
|
|
66
116
|
variance: 3 # classical symmetry with occasional 60/40 splits, mostly balanced
|
|
@@ -5,17 +5,44 @@ trend_ref: trends/art-deco.md
|
|
|
5
5
|
|
|
6
6
|
tokens:
|
|
7
7
|
color:
|
|
8
|
+
# Core — shadcn/ui CSS vars
|
|
9
|
+
background: "#0A0A0A"
|
|
10
|
+
foreground: "#F2F0E4"
|
|
11
|
+
card: "#141414"
|
|
12
|
+
card-foreground: "#F2F0E4"
|
|
13
|
+
popover: "#141414"
|
|
14
|
+
popover-foreground: "#F2F0E4"
|
|
8
15
|
primary: "#D4AF37"
|
|
16
|
+
primary-foreground: "#000000"
|
|
9
17
|
secondary: "#1E3D59"
|
|
18
|
+
secondary-foreground: "#F2F0E4"
|
|
10
19
|
accent: "#F2F0E4"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
20
|
+
accent-foreground: "#000000"
|
|
21
|
+
muted: "#1F1F1F"
|
|
22
|
+
muted-foreground: "#A8A090"
|
|
23
|
+
destructive: "#DC2626"
|
|
24
|
+
border: "rgba(212, 175, 55, 0.3)"
|
|
25
|
+
input: "rgba(212, 175, 55, 0.3)"
|
|
26
|
+
ring: "#D4AF37"
|
|
27
|
+
# Sidebar
|
|
28
|
+
sidebar: "#141414"
|
|
29
|
+
sidebar-foreground: "#F2F0E4"
|
|
30
|
+
sidebar-primary: "#D4AF37"
|
|
31
|
+
sidebar-primary-foreground: "#000000"
|
|
32
|
+
sidebar-accent: "#1F1F1F"
|
|
33
|
+
sidebar-accent-foreground: "#F2F0E4"
|
|
34
|
+
sidebar-border: "rgba(212, 175, 55, 0.3)"
|
|
35
|
+
sidebar-ring: "#D4AF37"
|
|
36
|
+
# Extras
|
|
16
37
|
success: "#16A34A"
|
|
17
38
|
warning: "#F59E0B"
|
|
18
39
|
info: "#3B82F6"
|
|
40
|
+
# Chart — data-viz colors (distinct, accessible at small sizes)
|
|
41
|
+
chart-1: "#D4AF37" # radiant gold (primary)
|
|
42
|
+
chart-2: "#6BAED6" # dusty cerulean (secondary shifted)
|
|
43
|
+
chart-3: "#FF6B35" # burnished copper
|
|
44
|
+
chart-4: "#A8D5A2" # art nouveau sage
|
|
45
|
+
chart-5: "#C084FC" # amethyst
|
|
19
46
|
|
|
20
47
|
typography:
|
|
21
48
|
font-family-primary: "Josefin Sans, sans-serif"
|
|
@@ -31,7 +58,6 @@ tokens:
|
|
|
31
58
|
border-radius-md: "2px"
|
|
32
59
|
border-radius-lg: "6px"
|
|
33
60
|
border-width: "1px"
|
|
34
|
-
border-color: "rgba(212, 175, 55, 0.3)"
|
|
35
61
|
|
|
36
62
|
elevation:
|
|
37
63
|
shadow-sm: "0 0 10px rgba(212,175,55,0.1)"
|
|
@@ -55,7 +81,13 @@ tokens:
|
|
|
55
81
|
dark_mode:
|
|
56
82
|
color:
|
|
57
83
|
background: "#050505"
|
|
58
|
-
|
|
84
|
+
foreground: "#F2F0E4"
|
|
85
|
+
card: "#0A0A0A"
|
|
86
|
+
card-foreground: "#F2F0E4"
|
|
87
|
+
popover: "#0A0A0A"
|
|
88
|
+
popover-foreground: "#F2F0E4"
|
|
89
|
+
border: "rgba(212, 175, 55, 0.3)"
|
|
90
|
+
input: "rgba(212, 175, 55, 0.3)"
|
|
59
91
|
|
|
60
92
|
intensity:
|
|
61
93
|
variance: 3 # bilateral symmetry, centered axes, mathematical precision
|