@withmata/blueprints 0.3.5 → 0.5.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.
Files changed (62) hide show
  1. package/.claude/skills/audit/SKILL.md +4 -4
  2. package/.claude/skills/blueprint-catalog/SKILL.md +17 -7
  3. package/.claude/skills/copywrite/SKILL.md +187 -0
  4. package/.claude/skills/copywrite-landing/SKILL.md +489 -0
  5. package/.claude/skills/design-system/SKILL.md +970 -0
  6. package/.claude/skills/new-project/SKILL.md +168 -112
  7. package/.claude/skills/scaffold-auth/SKILL.md +9 -9
  8. package/.claude/skills/scaffold-db/SKILL.md +14 -14
  9. package/.claude/skills/scaffold-env/SKILL.md +4 -4
  10. package/.claude/skills/scaffold-foundation/SKILL.md +15 -15
  11. package/.claude/skills/scaffold-tailwind/SKILL.md +17 -3
  12. package/.claude/skills/scaffold-ui/SKILL.md +155 -36
  13. package/ENGINEERING.md +2 -2
  14. package/blueprints/discovery/design-system/BLUEPRINT.md +1479 -0
  15. package/blueprints/discovery/marketing-copywriting/BLUEPRINT.md +664 -0
  16. package/blueprints/features/auth-better-auth/BLUEPRINT.md +20 -22
  17. package/blueprints/features/db-drizzle-postgres/BLUEPRINT.md +12 -12
  18. package/blueprints/features/db-drizzle-postgres/files/db/src/example-entity.ts +1 -1
  19. package/blueprints/features/db-drizzle-postgres/files/db/src/scripts/seed.ts +1 -1
  20. package/blueprints/features/env-t3/BLUEPRINT.md +1 -1
  21. package/blueprints/features/tailwind-v4/BLUEPRINT.md +9 -2
  22. package/blueprints/features/tailwind-v4/files/tailwind-config/shared-styles.css +80 -1
  23. package/blueprints/features/ui-shared-components/BLUEPRINT.md +411 -78
  24. package/blueprints/features/ui-shared-components/files/ui/components/ui/alert-dialog.tsx +192 -0
  25. package/blueprints/features/ui-shared-components/files/ui/components/ui/avatar.tsx +71 -0
  26. package/blueprints/features/ui-shared-components/files/ui/components/ui/badge.tsx +52 -0
  27. package/blueprints/features/ui-shared-components/files/ui/components/ui/breadcrumb.tsx +122 -0
  28. package/blueprints/features/ui-shared-components/files/ui/components/ui/button.tsx +56 -0
  29. package/blueprints/features/ui-shared-components/files/ui/components/ui/card-select.tsx +72 -0
  30. package/blueprints/features/ui-shared-components/files/ui/components/ui/card.tsx +100 -0
  31. package/blueprints/features/ui-shared-components/files/ui/components/ui/collapsible.tsx +34 -0
  32. package/blueprints/features/ui-shared-components/files/ui/components/ui/combobox.tsx +301 -0
  33. package/blueprints/features/ui-shared-components/files/ui/components/ui/dropdown-menu.tsx +264 -0
  34. package/blueprints/features/ui-shared-components/files/ui/components/ui/empty-state.tsx +43 -0
  35. package/blueprints/features/ui-shared-components/files/ui/components/ui/entity-select.tsx +110 -0
  36. package/blueprints/features/ui-shared-components/files/ui/components/ui/field.tsx +237 -0
  37. package/blueprints/features/ui-shared-components/files/ui/components/ui/form-field.tsx +217 -0
  38. package/blueprints/features/ui-shared-components/files/ui/components/ui/input-group.tsx +161 -0
  39. package/blueprints/features/ui-shared-components/files/ui/components/ui/input.tsx +20 -0
  40. package/blueprints/features/ui-shared-components/files/ui/components/ui/label.tsx +20 -0
  41. package/blueprints/features/ui-shared-components/files/ui/components/ui/org-switcher.tsx +114 -0
  42. package/blueprints/features/ui-shared-components/files/ui/components/ui/page-header.tsx +45 -0
  43. package/blueprints/features/ui-shared-components/files/ui/components/ui/pagination.tsx +52 -0
  44. package/blueprints/features/ui-shared-components/files/ui/components/ui/pill-select.tsx +151 -0
  45. package/blueprints/features/ui-shared-components/files/ui/components/ui/popover.tsx +41 -0
  46. package/blueprints/features/ui-shared-components/files/ui/components/ui/search-input.tsx +49 -0
  47. package/blueprints/features/ui-shared-components/files/ui/components/ui/select.tsx +205 -0
  48. package/blueprints/features/ui-shared-components/files/ui/components/ui/selected-entity-card.tsx +47 -0
  49. package/blueprints/features/ui-shared-components/files/ui/components/ui/separator.tsx +25 -0
  50. package/blueprints/features/ui-shared-components/files/ui/components/ui/sidebar.tsx +389 -0
  51. package/blueprints/features/ui-shared-components/files/ui/components/ui/status-filter.tsx +43 -0
  52. package/blueprints/features/ui-shared-components/files/ui/components/ui/tag-input.tsx +131 -0
  53. package/blueprints/features/ui-shared-components/files/ui/components/ui/textarea.tsx +18 -0
  54. package/blueprints/features/ui-shared-components/files/ui/components/ui/user-menu.tsx +149 -0
  55. package/blueprints/features/ui-shared-components/files/ui/components.json +11 -8
  56. package/blueprints/features/ui-shared-components/files/ui/package.json +20 -11
  57. package/blueprints/foundation/monorepo-turbo/BLUEPRINT.md +19 -20
  58. package/blueprints/foundation/monorepo-turbo/files/root/package.json +1 -1
  59. package/dist/index.js +27 -10
  60. package/package.json +1 -1
  61. package/blueprints/features/tailwind-v4/files/tailwind-config/package.json +0 -20
  62. package/blueprints/foundation/monorepo-turbo/files/root/pnpm-workspace.yaml +0 -5
@@ -0,0 +1,1479 @@
1
+ # Design System Blueprint — Visual Identity & Tailwind Tokens
2
+
3
+ ## Tier
4
+
5
+ Discovery — produces documentation and actionable CSS, not application code.
6
+
7
+ ## Problem
8
+
9
+ Technical founders scaffolding projects with the blueprint system get functional, accessible UI components — but every project looks identical. The Tailwind v4 blueprint provides a solid token structure (31 semantic color tokens, radius scale, font variables) but fills them with generic shadcn defaults. Without a deliberate design system, products lack visual identity: the colors don't reflect the brand, the typography doesn't match the audience, the spacing and rounding don't communicate the right personality. This blueprint defines a product's visual identity through a structured design conversation and outputs actual Tailwind CSS that replaces the defaults — so when UI components render, they look like YOUR product, not a template.
10
+
11
+ ## Status
12
+
13
+ Complete.
14
+
15
+ ## Blueprint Dependencies
16
+
17
+ | Blueprint | Type | Why |
18
+ |-----------|------|-----|
19
+ | `discovery/product-discovery` | recommended | Provides product type, customer archetypes, brand personality, and competitive landscape. The design system is strongest when grounded in validated product research. Without it, context is gathered conversationally. |
20
+ | `discovery/marketing-copywriting` | recommended | Provides brand voice and tone. Helps align visual identity with how the product communicates — a playful brand voice shouldn't live inside a corporate-looking interface. |
21
+
22
+ ## Output
23
+
24
+ ```
25
+ docs/
26
+ └── design/
27
+ ├── design-system.md # The "why" + "how to use" document
28
+ └── shared-styles.css # Actual Tailwind v4 CSS tokens
29
+ ```
30
+
31
+ The `shared-styles.css` is consumed by `/scaffold-tailwind` — if it exists when tailwind is scaffolded, it replaces the generic defaults. It follows the exact same CSS structure as the Tailwind v4 blueprint template: `@import` directives, `@custom-variant`, `@theme inline {}`, `@theme {}`, `:root {}`, `.dark {}`, and `@layer base {}`.
32
+
33
+ **File naming rules:**
34
+ - Output files go in `docs/design/` — this is the design system's source of truth
35
+ - `shared-styles.css` is a real, valid CSS file — not pseudocode or documentation
36
+ - `design-system.md` is the reference document explaining every decision
37
+ - Do NOT create files beyond what's specified above
38
+
39
+ ---
40
+
41
+ ## Process
42
+
43
+ This is a CONVERSATIONAL blueprint. Claude Code guides the user through a structured design session that produces a complete visual identity system and actionable Tailwind CSS tokens. The process adapts based on available context — product discovery docs, marketing copy docs, or direct conversation.
44
+
45
+ ### Phase 1: Context Gathering
46
+
47
+ **Goal:** Understand the product, audience, and personality before making any visual decisions.
48
+
49
+ Design without context produces decoration. Design with context produces identity. This phase maps everything known about the product into design-relevant inputs.
50
+
51
+ #### Path 1: Product Docs Available (recommended)
52
+
53
+ Auto-read `.project-context.md` + `docs/product/` + `docs/pages/` if available. Map them to design inputs:
54
+
55
+ - **Product type** -> aesthetic direction
56
+ - SaaS dashboard -> structured, information-dense, calm backgrounds, clear hierarchy
57
+ - Consumer app -> bold personality, playful interactions, memorable colors
58
+ - Developer tool -> monospace accents, high contrast, minimal chrome, dark-mode-first
59
+ - Marketplace -> warm and trustworthy, card-heavy, image-friendly layouts
60
+ - Content/media -> editorial typography, generous whitespace, reading-optimized
61
+ - Enterprise B2B -> conservative palette, accessibility-first, dense but organized
62
+
63
+ - **Primary archetype** -> audience sensibility
64
+ - Technical users -> appreciate subtlety, dislike gratuitous decoration, value density
65
+ - Non-technical users -> need visual cues for hierarchy, prefer clear affordances
66
+ - Enterprise buyers -> expect polish, trust conservative palettes, notice rough edges
67
+ - Startup users -> tolerate experimentation, respond to personality, forgive imperfection
68
+ - Young audience -> expects modern aesthetics, dark mode, bold color, animation
69
+ - Mature audience -> values clarity, readable typography, restrained color, stability
70
+
71
+ - **Core pillars** -> what the design should communicate
72
+ - "Speed" -> sharp edges, minimal decoration, fast transitions, reduced visual weight
73
+ - "Trust" -> blue-shifted palette, consistent spacing, conservative rounding, ample whitespace
74
+ - "Simplicity" -> limited palette, generous spacing, large type, few shadows
75
+ - "Power" -> deep colors, dense layouts, detailed controls, visible complexity
76
+ - "Creativity" -> vibrant accents, asymmetry, unexpected color, playful rounding
77
+ - "Warmth" -> earth tones, soft rounding, friendly type, textured surfaces
78
+
79
+ - **Brand voice** (from marketing copy if available) -> visual tone alignment
80
+ - Casual/playful voice -> rounded corners, warm colors, bouncy animations
81
+ - Professional/authoritative voice -> sharp geometry, cool colors, subtle transitions
82
+ - Technical/precise voice -> monospace accents, systematic spacing, minimal decoration
83
+ - Friendly/approachable voice -> medium rounding, warm neutrals, soft shadows
84
+
85
+ After reading, summarize what you found:
86
+ - "From your product discovery, I can see your product is a [type], your primary audience is [archetype description], and your core pillars are [X, Y, Z]. This tells me the design should communicate [qualities]. I'll use that as the foundation for creative direction."
87
+
88
+ Then ask only what's missing:
89
+ - Do you have any visual references — screenshots, sites you admire, or brands whose look you'd want to echo?
90
+ - Are there any colors you know you want or know you want to avoid?
91
+ - Is there an existing brand identity (logo, brand colors) this needs to work with?
92
+
93
+ #### Path 2: No Product Docs Available
94
+
95
+ Gather context conversationally. Ask about these four dimensions:
96
+
97
+ **Product Identity:**
98
+ - What does your product do in one sentence?
99
+ - Who is your primary user? (Job title, company size, technical level)
100
+ - What 3 words should someone use to describe your product's personality?
101
+ - Is this a dashboard, consumer app, developer tool, marketplace, content site, or something else?
102
+
103
+ **Brand Constraints:**
104
+ - Do you have an existing logo or brand colors? (If yes, the design system works around them)
105
+ - Are there brands whose visual style you admire? (This reveals aesthetic preferences faster than abstract questions)
106
+ - Are there visual styles you actively dislike? (Equally valuable — narrows the space)
107
+
108
+ **Audience Expectations:**
109
+ - What tools/apps does your audience use daily? (Reveals their visual baseline)
110
+ - Is your audience more Notion or more Bloomberg Terminal? More Linear or more Salesforce?
111
+ - Are they using your product under pressure (speed matters) or reflectively (calm matters)?
112
+
113
+ **Practical Needs:**
114
+ - Does your product have a lot of data density? (Tables, charts, dashboards)
115
+ - Is dark mode critical for your audience? (Developers, designers, night-use)
116
+ - Will you have a marketing site that needs to look different from the app?
117
+
118
+ **Push back when:**
119
+ - Personality words are generic ("modern, clean, professional" — that describes everything)
120
+ - No user context ("it's for everyone" — no product is for everyone)
121
+ - Visual references are wildly contradictory (ask them to pick a direction)
122
+ - They want to "look like Apple" without understanding what that means structurally
123
+
124
+ ---
125
+
126
+ ### Phase 2: Creative Direction
127
+
128
+ **Goal:** Define a Creative North Star — a one-paragraph description of the visual identity that guides every subsequent decision.
129
+
130
+ **Announce framework:** "I'm going to propose 2-3 creative directions based on what we've discussed. Each direction is a coherent visual personality — not just colors, but a whole way of looking and feeling. Your job is to pick one, or tell me which elements from different directions to combine. This becomes the Creative North Star that guides every decision in the design system."
131
+
132
+ Propose 2-3 creative direction options based on context. Each direction includes:
133
+ - **A name** — something evocative that captures the mood
134
+ - **A North Star paragraph** — a vivid description of how the product should feel
135
+ - **A mood** — 3-5 adjective clusters
136
+ - **Why it fits** — specific reasoning tied to the product, audience, and pillars
137
+
138
+ Example directions (adapt these to the actual product — never use these verbatim):
139
+
140
+ **"Cognitive Sanctuary"**
141
+ > A space that feels calm and expansive. Soft backgrounds with breathing room between elements. Muted violet tinted with warmth. Typography that's generous but never sprawling. Shadows that suggest depth without drama. The product feels like a quiet library with perfect lighting — focused, restful, and deeply functional.
142
+ >
143
+ > *Mood:* soft, breathing, violet-tinted, unhurried, precise
144
+ > *Why:* Your audience is knowledge workers under constant cognitive pressure. The product should feel like relief — a sanctuary from noisy, demanding interfaces. The violet primary differentiates from the sea of blue SaaS tools while retaining professionalism.
145
+
146
+ **"Precision Engine"**
147
+ > Every pixel earns its place. Sharp edges, systematic spacing, and a navy-slate palette that communicates engineering discipline. Monospace accents in headers. Minimal shadows — hierarchy comes from weight and space, not decoration. The product feels like a precision instrument — powerful, exact, and confidence-inspiring.
148
+ >
149
+ > *Mood:* sharp, structured, navy/slate, disciplined, exact
150
+ > *Why:* Your audience is technical — they notice details, respect systems, and distrust gratuitous decoration. The sharp aesthetic mirrors the precision they bring to their own work. Navy differentiates from the startup-blue default while feeling established.
151
+
152
+ **"Warm Workshop"**
153
+ > A product that feels handcrafted rather than manufactured. Rounded corners, amber and earth tones, friendly typography that invites exploration. Shadows are soft and warm. Interactions have a slight bounce — nothing stiff. The product feels like walking into a well-organized workshop where everything has its place but nothing feels sterile.
154
+ >
155
+ > *Mood:* rounded, amber/earth, friendly, handcrafted, inviting
156
+ > *Why:* Your audience is non-technical and potentially intimidated by tools. Warmth reduces anxiety. The rounded, friendly aesthetic signals "this won't bite" — critical for adoption when users have a choice to avoid the tool entirely.
157
+
158
+ **User picks one or mixes elements.** Document the final Creative North Star.
159
+
160
+ **Explain WHY each direction fits (or doesn't fit) the product's audience.** This is educational — the user should understand how audience characteristics translate to visual decisions:
161
+ - Enterprise audience -> conservative palette, because enterprise buyers equate visual conservatism with stability and reliability
162
+ - Developer audience -> high information density, because developers are comfortable scanning dense UIs and frustrated by "dumbed-down" interfaces
163
+ - Consumer audience -> memorable primary color, because consumer products need brand recognition in a crowded market
164
+ - Young audience -> dark mode first, because younger users overwhelmingly prefer dark interfaces and associate them with modernity
165
+
166
+ ---
167
+
168
+ ### Phase 3: Color System
169
+
170
+ **Goal:** Define every color token in the design system with oklch values, covering light mode, dark mode, and the reasoning behind each choice.
171
+
172
+ **Announce framework:** "I'm going to build the full color system now. We'll start with the primary color — the single most important decision — and build outward from there. Every color in the system will be in oklch, which is a perceptually uniform color space. That means: consistent vibrancy across the spectrum, better dark mode translations, and gradients that don't go muddy in the middle."
173
+
174
+ #### Primary Color Selection
175
+
176
+ Research: what colors do competitors and similar products use? This matters because:
177
+ - If every competitor uses blue, choosing blue makes you invisible in screenshots and reviews
178
+ - If the space expects blue (finance, enterprise), deviating too far signals "unserious"
179
+ - The right primary color balances audience expectation with competitive differentiation
180
+
181
+ Propose the primary color based on:
182
+
183
+ **Product personality:**
184
+ - Blue (hue ~240-260) -> trust, reliability, calm — universal enterprise default for a reason, but also the most overused
185
+ - Green (hue ~145-165) -> growth, health, nature, money — strong for fintech, health, sustainability
186
+ - Violet/purple (hue ~280-310) -> creativity, premium, imagination — differentiates from blue while retaining professionalism
187
+ - Orange (hue ~60-80) -> energy, warmth, urgency — bold and memorable, but can feel aggressive at high chroma
188
+ - Rose/pink (hue ~0-20) -> warmth, empathy, care — strong for health, community, consumer
189
+ - Teal (hue ~180-200) -> clarity, freshness, balance — modern alternative to blue
190
+ - Amber/gold (hue ~85-100) -> warmth, craft, quality — premium without being cold
191
+
192
+ **Audience expectations:**
193
+ - Enterprise expects blue/gray/green — deviating requires confidence and brand strength
194
+ - Consumer apps can be bold — personality matters more than convention
195
+ - Developer tools trend toward violet, teal, or desaturated palettes
196
+ - Health/wellness tends toward green, teal, or warm neutrals
197
+
198
+ **Competitive differentiation:**
199
+ - List the colors 3-5 direct competitors use
200
+ - Identify the gap — which hues are underrepresented?
201
+ - Propose a primary that occupies defensible visual territory
202
+
203
+ #### Full Palette Definition
204
+
205
+ Define all 31 semantic tokens in oklch. Explain the reasoning behind each group:
206
+
207
+ **Core tokens (6):**
208
+ - `--primary` + `--primary-foreground` — the brand color and text that sits on top of it
209
+ - `--secondary` + `--secondary-foreground` — complement or neutral, for supporting elements
210
+ - `--accent` + `--accent-foreground` — highlight color for emphasis, selection states, hover
211
+
212
+ *Why these three tiers:* Primary carries brand identity. Secondary provides visual rest — elements that need to be visible but shouldn't compete with primary. Accent is the "notice me" color used sparingly for interactive states and highlights. Without this hierarchy, everything screams at the same volume and nothing stands out.
213
+
214
+ **Feedback tokens (2):**
215
+ - `--destructive` — error and danger states. Red-shifted (hue ~20-30) regardless of brand, because red=danger is a universal human association. Adjust lightness to ensure WCAG AA contrast against both light and dark backgrounds.
216
+
217
+ *Why destructive is always red-adjacent:* Cultural universals in color semantics are rare, but red=danger/stop is one of them. Fighting this convention to match a brand palette creates confusion in critical moments (delete confirmations, error states, data loss warnings). Brand identity yields to safety signaling.
218
+
219
+ **Neutral tokens (6):**
220
+ - `--background` + `--foreground` — page-level backdrop and default text
221
+ - `--muted` + `--muted-foreground` — subdued backgrounds and secondary text
222
+ - `--card` + `--card-foreground` — surface for card components
223
+
224
+ *Why separate card from background:* Surface hierarchy. When a card sits on the page background, it needs to be visually distinct. In light mode, cards are often the same white as the background (differentiated by shadow or border). In dark mode, cards are typically one step lighter than the background. Having separate tokens enables this without conditional logic.
225
+
226
+ **Container tokens (4):**
227
+ - `--popover` + `--popover-foreground` — floating elements (dropdowns, tooltips, popovers)
228
+ - `--border` — lines separating elements
229
+ - `--input` — input field borders (often slightly different from general borders)
230
+
231
+ *Why popover is separate from card:* Popovers float above the page and need stronger visual separation. In dark mode, popovers are often lighter than cards to signal elevation. Separate tokens let you fine-tune this hierarchy.
232
+
233
+ **Interactive tokens (1):**
234
+ - `--ring` — focus ring color for keyboard navigation accessibility
235
+
236
+ *Why ring exists as a separate token:* Focus rings serve a specific accessibility purpose — they must be visible against ANY background in the application. A dedicated token lets you choose a ring color with guaranteed contrast, independent of the brand palette.
237
+
238
+ **Sidebar tokens (8):**
239
+ - `--sidebar`, `--sidebar-foreground` — sidebar background and text
240
+ - `--sidebar-primary`, `--sidebar-primary-foreground` — active item in sidebar
241
+ - `--sidebar-accent`, `--sidebar-accent-foreground` — hover/selected states
242
+ - `--sidebar-border` — sidebar divider lines
243
+ - `--sidebar-ring` — focus ring within sidebar context
244
+
245
+ *Why sidebar gets its own tokens:* Sidebars often have a different visual treatment than the main content area — slightly darker in light mode, slightly lighter in dark mode, or tinted with the brand color. Separate tokens enable sidebar-as-distinct-zone without CSS hacks.
246
+
247
+ **Chart tokens (5):**
248
+ - `--chart-1` through `--chart-5` — data visualization colors
249
+
250
+ *Why 5 chart colors:* Most data visualizations use 3-5 series. Beyond 5, colors become hard to distinguish and the chart needs a different approach (labels, patterns). These 5 should be harmonized with the primary color but distinct enough for accessibility. A good approach: spread across 60-120 degrees of hue from the primary, maintaining consistent lightness and chroma.
251
+
252
+ **Radius token (1):**
253
+ - `--radius` — the base radius from which all other radii are calculated
254
+
255
+ *Why a base radius:* The radius scale in `@theme inline` calculates `--radius-sm` through `--radius-4xl` from this single value. Changing `--radius` from `0.625rem` to `1rem` transforms the entire application from moderate to round. One variable, total control.
256
+
257
+ #### Dark Mode Strategy
258
+
259
+ Dark mode is NOT "just invert the lightness." Every color needs deliberate adjustment:
260
+
261
+ **Background strategy:**
262
+ - Dark background should be around L=0.12-0.18 in oklch — true black (L=0) causes eye strain and makes cards invisible
263
+ - Card surfaces 1-2 steps lighter (L=0.18-0.24) for visible elevation
264
+ - Popover surfaces another step lighter — floating elements must feel elevated
265
+
266
+ **Color adjustments for dark mode:**
267
+ - Primary color: reduce chroma slightly (saturated colors on dark backgrounds feel neon/electric), shift lightness up slightly for readability
268
+ - Muted foreground: increase lightness to ~0.65-0.72 (gray text on dark needs more contrast than gray text on light)
269
+ - Borders: use `oklch(1 0 0 / 10%)` (white at 10% opacity) for subtle, adaptive borders
270
+ - Input borders: slightly higher opacity (~15%) so input fields are clearly delineated
271
+ - Destructive: increase lightness (a dark red on a dark background is invisible)
272
+
273
+ **What NOT to do in dark mode:**
274
+ - Don't use pure black (`oklch(0 0 0)`) as background — it causes halation (text blooms) on OLED screens
275
+ - Don't keep the same chroma as light mode — saturated colors on dark backgrounds cause visual vibration
276
+ - Don't just flip lightness values — the relationship between surface layers matters more than individual values
277
+ - Don't forget sidebar tokens — a dark sidebar on a dark background becomes invisible without separate values
278
+
279
+ #### Surface Hierarchy Philosophy
280
+
281
+ Explain the "paper layers" approach:
282
+
283
+ ```
284
+ Layer 0: Page background (--background) — the base canvas
285
+ Layer 1: Content regions (--card) — cards, panels, content areas
286
+ Layer 2: Floating surfaces (--popover) — dropdowns, tooltips, modals
287
+ Layer 3: Elevated elements (sidebar, modals) — highest visual priority
288
+ ```
289
+
290
+ In light mode, surfaces differentiate through shadow (Layer 1 has shadow-sm, Layer 2 has shadow-lg). In dark mode, surfaces differentiate through lightness stepping (each layer is 2-4% lighter than the one below). This dual strategy ensures hierarchy is clear in both modes.
291
+
292
+ #### Surface Layering Stack
293
+
294
+ Document an explicit visual layering model showing which surface sits where:
295
+
296
+ ```
297
+ Layer 0 (deepest): background — Page canvas, the base everything rests on
298
+ Layer 1: sidebar — Persistent navigation surface
299
+ Layer 2: card — Content containers sitting on the page
300
+ Layer 3: popover — Floating elements (dropdowns, tooltips, selects)
301
+ Layer 4: overlay — Modal backdrop (semi-transparent)
302
+ Layer 5 (highest): dialog — Modal content surface with maximum elevation
303
+ ```
304
+
305
+ **Separation strategies** (in order of preference):
306
+ 1. **Tonal shifts** (preferred) — card on background creates natural contrast without explicit borders
307
+ 2. **Shadows** (for floating elements) — popovers get shadow-lg, modals get shadow-xl
308
+ 3. **Ghost borders** (accessibility fallback) — `ring-1 ring-foreground/10` when tonal shift alone isn't sufficient
309
+
310
+ This layering model must be applied consistently — a component should never use shadow elevation that doesn't match its layer position.
311
+
312
+ #### Evocative Color Naming
313
+
314
+ Every color token gets THREE identifiers: a **descriptive name** (evocative, memorable), the **functional role** (what it's used for), and the **exact value** (oklch). This serves both humans (the name creates emotional association) and AI agents (the functional role + value enables precise application).
315
+
316
+ Format in design-system.md:
317
+ ```
318
+ | Token | Name | Light | Dark | Usage | Tailwind |
319
+ |-------|------|-------|------|-------|----------|
320
+ | primary | Deep Indigo | oklch(0.488 0.243 264) | oklch(0.42 0.18 266) | CTAs, links, active states | `bg-primary` |
321
+ | muted | Whisper Gray | oklch(0.97 0 0) | oklch(0.269 0 0) | Subtle backgrounds, inactive areas | `bg-muted` |
322
+ | destructive | Alert Terracotta | oklch(0.58 0.22 27) | oklch(0.704 0.191 22) | Errors, destructive actions | `bg-destructive` |
323
+ ```
324
+
325
+ Format in shared-styles.css (as comments):
326
+ ```css
327
+ --primary: oklch(0.488 0.243 264.376); /* Deep Indigo — CTAs, active states */
328
+ --muted: oklch(0.97 0 0); /* Whisper Gray — subtle backgrounds */
329
+ ```
330
+
331
+ Naming convention: always **evocative adjective(s) + color family**. Never generic ("blue", "red"). Examples:
332
+ - "Deep Muted Teal-Navy" not "dark blue"
333
+ - "Warm Barely-There Cream" not "off-white"
334
+ - "Alert Terracotta" not "red"
335
+
336
+ ---
337
+
338
+ ### Phase 4: Typography
339
+
340
+ **Goal:** Select fonts that match the product personality and define the complete type scale.
341
+
342
+ **Announce framework:** "Typography is the most impactful design decision after color — it's on every screen, in every component, and it sets the tone before anyone reads a word. I'm going to recommend a font pairing (display + body, optionally + mono) and define the complete type scale with Tailwind v4 theme variables."
343
+
344
+ #### Font Research
345
+
346
+ Search for actual typefaces based on product personality and audience. Consider:
347
+
348
+ **Modern tech / SaaS:**
349
+ - Geist — the new standard for tech products (Next.js's house font), geometric but humanist, excellent at small sizes
350
+ - Satoshi — geometric sans with personality, stands out from Inter-sameness
351
+ - Cabinet Grotesk — bold and opinionated for display, clean at body sizes
352
+ - Inter — only recommend if it truly fits. It's the "safe choice" and makes everything look the same. When recommending Inter, be honest about why: "Inter is excellent technically but won't differentiate your product visually."
353
+
354
+ **Editorial / content-heavy:**
355
+ - Fraunces — a variable display serif with personality, great for headers paired with a clean sans body
356
+ - Newsreader — designed for long-form reading, excellent x-height
357
+ - Lora — workhorse serif with character, works at both display and body sizes
358
+ - Crimson Pro — elegant and readable, strong for premium content
359
+
360
+ **Friendly / approachable:**
361
+ - Plus Jakarta Sans — friendly geometry with good readability, slightly rounded terminals
362
+ - Nunito — rounded sans with warmth, approachable without being childish
363
+ - Quicksand — geometric with rounded terminals, distinctly friendly
364
+ - DM Sans — the structured friendly option, geometric but warm
365
+
366
+ **Premium / luxury:**
367
+ - Cormorant — a display serif with dramatic contrast, best paired with a simple sans
368
+ - Playfair Display — high-contrast serif, unmistakably editorial and premium
369
+ - EB Garamond — classic elegance, works at body sizes unlike most display serifs
370
+
371
+ **Developer / technical:**
372
+ - JetBrains Mono — excellent code font with ligatures, designed for extended reading
373
+ - Fira Code — the programmer favorite, with or without ligatures
374
+ - Berkeley Mono — premium monospace with character (not free)
375
+ - Geist Mono — pairs perfectly with Geist Sans (obviously)
376
+
377
+ #### Font Pairing Principles
378
+
379
+ Explain WHY the recommended pairing works:
380
+
381
+ - **Contrast creates interest** — pair a characterful display font with a neutral body font (or vice versa). Two fonts with similar personality feel redundant; two fonts with different personality create visual rhythm.
382
+ - **Shared structure creates harmony** — fonts should share structural DNA (x-height, stroke weight, proportions) even when their personality differs. A geometric display + geometric body feels more cohesive than geometric display + humanist body.
383
+ - **Body font carries the workload** — the body font appears in most UI text, so it must be readable at 14-16px, have a good set of weights (400, 500, 600, 700 minimum), and look clean at small sizes. Display fonts can be more expressive because they're used at larger sizes.
384
+ - **Mono is optional but valuable** — if the product shows any code, data, or tabular numbers, a dedicated mono font prevents the jarring fallback to system monospace. The mono font should share visual weight with the body font.
385
+
386
+ Propose the pairing with reasoning:
387
+ - "I recommend [Display] for headlines and [Body] for interface text because [specific reasoning tied to product personality and audience]. The [Display] font's [specific characteristic] communicates [quality], while [Body]'s [characteristic] ensures [practical benefit]."
388
+
389
+ #### Type Scale Definition
390
+
391
+ Define the complete scale using Tailwind v4 `@theme` variables. The scale maps to Tailwind's `text-*` utilities:
392
+
393
+ | Token | Default Value | Line Height | Usage | Tailwind Class |
394
+ |-------|---------------|-------------|-------|----------------|
395
+ | `--text-xs` | 0.75rem (12px) | 1rem | Fine print, captions, badges | `text-xs` |
396
+ | `--text-sm` | 0.875rem (14px) | 1.25rem | Secondary text, form labels, helper text | `text-sm` |
397
+ | `--text-base` | 1rem (16px) | 1.5rem | Body text, default paragraph | `text-base` |
398
+ | `--text-lg` | 1.125rem (18px) | 1.75rem | Emphasized body, section leads | `text-lg` |
399
+ | `--text-xl` | 1.25rem (20px) | 1.75rem | Card titles, small headings | `text-xl` |
400
+ | `--text-2xl` | 1.5rem (24px) | 2rem | Section headings | `text-2xl` |
401
+ | `--text-3xl` | 1.875rem (30px) | 2.25rem | Page headings | `text-3xl` |
402
+ | `--text-4xl` | 2.25rem (36px) | 2.5rem | Hero secondary | `text-4xl` |
403
+ | `--text-5xl` | 3rem (48px) | 1 | Hero headings | `text-5xl` |
404
+ | `--text-6xl` | 3.75rem (60px) | 1 | Display/marketing | `text-6xl` |
405
+ | `--text-7xl` | 4.5rem (72px) | 1 | Large display | `text-7xl` |
406
+ | `--text-8xl` | 6rem (96px) | 1 | Statement display | `text-8xl` |
407
+ | `--text-9xl` | 8rem (128px) | 1 | Extreme display | `text-9xl` |
408
+
409
+ Adjust the scale based on product needs:
410
+ - Data-dense products may tighten the scale (smaller increments) to fit more hierarchy into less space
411
+ - Marketing-heavy products may stretch the scale (larger display sizes) for dramatic headings
412
+ - Mobile-first products should verify the scale at 320px viewport width
413
+
414
+ **Weight scale:**
415
+
416
+ | Token | Value | Usage | Tailwind Class |
417
+ |-------|-------|-------|----------------|
418
+ | `--font-weight-thin` | 100 | Decorative display only | `font-thin` |
419
+ | `--font-weight-extralight` | 200 | Large display text | `font-extralight` |
420
+ | `--font-weight-light` | 300 | De-emphasized text | `font-light` |
421
+ | `--font-weight-normal` | 400 | Body text default | `font-normal` |
422
+ | `--font-weight-medium` | 500 | Labels, navigation items | `font-medium` |
423
+ | `--font-weight-semibold` | 600 | Headings, button text | `font-semibold` |
424
+ | `--font-weight-bold` | 700 | Strong emphasis, primary headings | `font-bold` |
425
+ | `--font-weight-extrabold` | 800 | Hero headings | `font-extrabold` |
426
+ | `--font-weight-black` | 900 | Display/marketing only | `font-black` |
427
+
428
+ **Tracking (letter spacing):**
429
+
430
+ | Token | Value | Usage |
431
+ |-------|-------|-------|
432
+ | `--tracking-tighter` | -0.05em | Large display headings (tighten at large sizes) |
433
+ | `--tracking-tight` | -0.025em | Headings, card titles |
434
+ | `--tracking-normal` | 0em | Body text |
435
+ | `--tracking-wide` | 0.025em | Uppercase labels, badges |
436
+ | `--tracking-wider` | 0.05em | Small uppercase text |
437
+ | `--tracking-widest` | 0.1em | Decorative uppercase, overlines |
438
+
439
+ **Leading (line height):**
440
+
441
+ | Token | Value | Usage |
442
+ |-------|-------|-------|
443
+ | `--leading-none` | 1 | Display headings (tight) |
444
+ | `--leading-tight` | 1.25 | Headings, short text |
445
+ | `--leading-snug` | 1.375 | Cards, compact layouts |
446
+ | `--leading-normal` | 1.5 | Body text default |
447
+ | `--leading-relaxed` | 1.625 | Long-form reading |
448
+ | `--leading-loose` | 2 | Wide-set text, open layouts |
449
+
450
+ ---
451
+
452
+ ### Phase 5: Spacing, Rounding & Borders
453
+
454
+ **Goal:** Define the spatial personality — how much breathing room, how round the corners, and when lines appear.
455
+
456
+ #### Base Spacing Unit
457
+
458
+ The default `--spacing` in Tailwind v4 is `0.25rem` (4px). This means `p-4` = `1rem` (16px), `gap-6` = `1.5rem` (24px), etc. Adjusting `--spacing` scales the entire system:
459
+
460
+ - `0.25rem` (default) — standard density, works for most applications
461
+ - `0.2rem` — tighter, for data-dense dashboards where screen real estate matters
462
+ - `0.3rem` — looser, for marketing/content sites where breathing room is the priority
463
+
464
+ *Why base spacing matters:* When every spacing value derives from one unit, the system stays proportional as it scales. Changing `--spacing` from 0.25rem to 0.3rem increases whitespace everywhere uniformly — you don't get the inconsistency of ad-hoc padding adjustments where some elements feel cramped while others feel loose.
465
+
466
+ #### Rounding Personality
467
+
468
+ Define the base `--radius` and explain the personality it creates:
469
+
470
+ **Sharp (--radius: 0-0.25rem / 0-4px):**
471
+ - Components: `rounded-sm` (2px) for buttons, `rounded-md` (4px) for cards, `rounded-none` for tables
472
+ - Personality: corporate, serious, editorial, architectural
473
+ - Best for: enterprise B2B, fintech, legal, media
474
+ - Why: sharp corners communicate precision and formality. They say "we mean business" — there's no softness to hide behind. Editorial design has used sharp corners for centuries because they create clean grid alignment.
475
+
476
+ **Moderate (--radius: 0.375-0.625rem / 6-10px):**
477
+ - Components: `rounded-md` (6px) for buttons, `rounded-lg` (8px) for cards, `rounded-xl` (12px) for modals
478
+ - Personality: balanced, professional, contemporary, approachable-but-serious
479
+ - Best for: SaaS, productivity tools, developer platforms, general B2B
480
+ - Why: the sweet spot — professional enough for enterprise, friendly enough for startups. This is the default for a reason: it works for most products without making a strong statement in either direction.
481
+
482
+ **Round (--radius: 0.75-1rem / 12-16px):**
483
+ - Components: `rounded-xl` (12px) for buttons, `rounded-2xl` (16px) for cards, `rounded-3xl` (20px) for modals
484
+ - Personality: friendly, modern, approachable, consumer
485
+ - Best for: consumer apps, social platforms, health/wellness, education
486
+ - Why: rounded corners reduce visual tension. Psychologically, humans prefer curved shapes over angular ones (studies by Bar & Neta, 2006) because sharp corners trigger a threat response. Rounded corners signal safety and approachability.
487
+
488
+ **Full (--radius: 1.25-1.5rem / 20-24px, pill shapes for buttons):**
489
+ - Components: `rounded-full` for buttons, `rounded-3xl` (24px) for cards, `rounded-4xl` for containers
490
+ - Personality: playful, bold, consumer, distinctive
491
+ - Best for: lifestyle apps, creative tools, social apps targeting younger audiences
492
+ - Why: pill-shaped buttons and aggressively rounded cards are a strong visual statement. This says "we're different" — which is powerful when intentional but distracting when accidental. Only recommend for products where visual personality is a competitive advantage.
493
+
494
+ #### Component-Specific Radius Mapping
495
+
496
+ Not every component uses the same radius. Define which components get which:
497
+
498
+ | Component | Sharp | Moderate | Round | Full |
499
+ |-----------|-------|----------|-------|------|
500
+ | Buttons | `rounded-sm` | `rounded-lg` | `rounded-xl` | `rounded-full` |
501
+ | Input fields | `rounded-sm` | `rounded-md` | `rounded-lg` | `rounded-xl` |
502
+ | Cards | `rounded-md` | `rounded-lg` | `rounded-2xl` | `rounded-3xl` |
503
+ | Modals/Dialogs | `rounded-md` | `rounded-xl` | `rounded-2xl` | `rounded-3xl` |
504
+ | Badges/Tags | `rounded-sm` | `rounded-md` | `rounded-full` | `rounded-full` |
505
+ | Avatars | `rounded-md` | `rounded-full` | `rounded-full` | `rounded-full` |
506
+ | Tooltips | `rounded-sm` | `rounded-md` | `rounded-lg` | `rounded-xl` |
507
+ | Dropdowns | `rounded-md` | `rounded-lg` | `rounded-xl` | `rounded-2xl` |
508
+
509
+ *Why components scale differently:* Buttons and badges are small — aggressive rounding at small sizes creates pill shapes naturally. Cards and modals are large — the same radius value that looks rounded on a button looks barely curved on a card. The mapping ensures consistent perceived roundness across different-sized components.
510
+
511
+ #### Border Philosophy
512
+
513
+ Borders are the most overused visual element in UI design. Every line on screen competes for attention with the content it's supposed to frame. Define the product's border strategy:
514
+
515
+ **"No-line" approach (Google Material Design / Apple approach):**
516
+ - Boundaries between elements come from tonal shifts (background color differences) and shadows, not lines
517
+ - Cards separate from background through elevation (shadow) or surface color difference
518
+ - Sections separate through whitespace and heading hierarchy
519
+ - When to use: clean, modern, content-focused interfaces
520
+ - Why: lines are visual noise. Every border is a distraction from content. When you remove borders, you force the design to use spacing and color to create hierarchy — which results in a cleaner, more intentional layout.
521
+
522
+ **"Intentional lines" approach (GitHub / Linear approach):**
523
+ - Borders appear only when they serve a specific purpose: separating interactive elements (table rows), creating containment (input fields), or providing a visual stop (section dividers)
524
+ - Border color is very subtle (low opacity) to avoid competing with content
525
+ - When to use: information-dense interfaces where spatial separation alone isn't sufficient
526
+ - Why: in data-dense UIs, removing all borders creates visual soup — elements blend together. Intentional borders provide just enough structure without the visual weight of a fully-bordered design.
527
+
528
+ **"Ghost border" fallback for accessibility:**
529
+ - Even in no-line designs, add a very low opacity outline (2-3%) for accessibility
530
+ - This ensures that color-blind users and those with contrast sensitivity can still perceive boundaries
531
+ - Implementation: `border: 1px solid oklch(0 0 0 / 3%)` (light mode) or `border: 1px solid oklch(1 0 0 / 5%)` (dark mode)
532
+ - Why: the WCAG standard for non-text contrast (1.4.11) requires a 3:1 ratio for UI component boundaries. Ghost borders provide this without visible lines for most users.
533
+
534
+ ---
535
+
536
+ ### Phase 5.5: Layout & Responsive Behavior
537
+
538
+ Define how the design system adapts across viewport sizes.
539
+
540
+ **Grid System:**
541
+ - Container max-width (typically 1280px or 1440px for desktop)
542
+ - Column count (12-column for flexibility, or simpler 4/8 for constrained layouts)
543
+ - Gutter width (derived from base spacing unit — typically 1rem or 1.5rem)
544
+ - Content max-width for readability (65ch for prose, full-width for dashboards)
545
+
546
+ **Breakpoints:**
547
+ Define responsive thresholds aligned with Tailwind's defaults or custom:
548
+ - **Mobile:** < 640px (`sm`) — single column, full-width elements, stacked navigation
549
+ - **Tablet:** 640px – 1024px (`sm` to `lg`) — 2-column grids, sidebar may collapse
550
+ - **Desktop:** 1024px – 1440px (`lg` to `2xl`) — full layout, sidebar expanded, multi-column
551
+ - **Large:** > 1440px — content centered, max-width constrains, generous margins
552
+
553
+ **Touch Targets:**
554
+ - Minimum 44x44px (WCAG AA), recommended 48x48px
555
+ - Interactive elements must have sufficient spacing to prevent mis-taps
556
+ - On mobile, CTAs should be full-width and thumb-reachable
557
+
558
+ **Responsive Component Behaviors:**
559
+ Document how each major component type adapts:
560
+
561
+ | Component | Mobile | Tablet | Desktop |
562
+ |-----------|--------|--------|---------|
563
+ | Sidebar | Hidden (hamburger menu) | Icon-only collapsed | Full expanded |
564
+ | Modals/Dialogs | Full-screen with slide-up | Centered, max-w-lg | Centered, max-w-md/lg |
565
+ | Navigation | Bottom tab bar or hamburger | Horizontal, condensed | Full horizontal with labels |
566
+ | Card Grid | 1 column, full width | 2 columns | 3-4 columns |
567
+ | Tables | Horizontal scroll or card view | Horizontal scroll | Full table |
568
+ | CTAs | Full width, sticky bottom | Auto width | Auto width |
569
+ | Forms | Single column, stacked | Single column | Optional 2-column for short fields |
570
+ | Page Header | Stacked (title above action) | Side-by-side | Side-by-side |
571
+
572
+ **Whitespace Scaling:**
573
+ - Section margins increase with viewport: 2rem (mobile) → 4rem (tablet) → 6-8rem (desktop)
574
+ - Card padding scales: p-4 (mobile) → p-6 (desktop)
575
+ - Typography may shift: text-sm body (mobile) → text-base (desktop)
576
+
577
+ ---
578
+
579
+ ### Phase 6: Component Styling Guidelines
580
+
581
+ **Goal:** Define specific visual treatment for every major component type, ensuring consistency and eliminating "how should this look?" decisions during development.
582
+
583
+ **Announce framework:** "Now I'll define how each component type should look in your design system. This goes deeper than just colors and rounding — I'll specify hover states, focus behavior, spacing conventions, and how variants relate to each other. These guidelines ensure that anyone building components produces consistent results without needing to reference screenshots."
584
+
585
+ #### Buttons
586
+
587
+ Buttons are the primary interactive element. Their styling communicates interactivity, hierarchy, and state.
588
+
589
+ **Primary button:**
590
+ - Background: `bg-primary`, text: `text-primary-foreground`
591
+ - Gradient vs flat? Decision based on personality:
592
+ - Flat (single color) -> clean, professional, developer-friendly
593
+ - Subtle gradient (2-3% lightness shift top to bottom) -> adds depth without flashiness
594
+ - Bold gradient (cross-hue, e.g., primary to accent) -> playful, consumer, high-energy
595
+ - Hover: darken background 8-12% (e.g., `bg-primary/90` or adjust oklch lightness)
596
+ - Active (pressed): darken further, slight scale reduction (`scale-[0.98]`)
597
+ - Focus: visible focus ring using `--ring` token, 2px offset
598
+ - Disabled: 50% opacity, `cursor-not-allowed`
599
+
600
+ **Secondary button:**
601
+ - Background: `bg-secondary`, text: `text-secondary-foreground`
602
+ - Lower visual weight than primary — it should clearly be "not the main action"
603
+ - Hover: subtle background shift toward primary tint
604
+ - Border: optional 1px border for definition in no-line designs
605
+
606
+ **Ghost/outline button:**
607
+ - Background: transparent, border: 1px `border-border`
608
+ - Hover: `bg-accent` background fill (ghost becomes solid on hover)
609
+ - This is the "de-emphasized" action — use for secondary or tertiary actions
610
+ - The hover state transition should be fast (100-150ms) so it feels responsive
611
+
612
+ **Destructive button:**
613
+ - Background: `bg-destructive`, text: white
614
+ - Reserve for irreversible actions (delete, remove, cancel subscription)
615
+ - Never place next to a primary button at the same visual weight — the destructive action should be visually subordinate unless it IS the primary action (e.g., a delete confirmation modal)
616
+
617
+ **Size scale:**
618
+
619
+ | Size | Padding | Height | Font Size | Icon Size |
620
+ |------|---------|--------|-----------|-----------|
621
+ | sm | `px-3 py-1.5` | 32px | `text-sm` | 16px |
622
+ | default | `px-4 py-2` | 40px | `text-sm` | 18px |
623
+ | lg | `px-6 py-2.5` | 44px | `text-base` | 20px |
624
+ | icon | `p-2` | 40px | — | 20px |
625
+
626
+ **Icon alignment:** icons in buttons sit 8px from text (gap-2). Left-aligned icons are for actions ("Save", "Download"). Right-aligned icons are for navigation ("Next", "Open"). Icon-only buttons must have an `aria-label`.
627
+
628
+ #### Cards
629
+
630
+ Cards are the primary container for grouped content.
631
+
632
+ - Surface: `bg-card text-card-foreground`
633
+ - Shadow vs border: based on border philosophy (see Phase 5)
634
+ - Shadow approach: `shadow-sm` for default, `shadow-md` on hover (if interactive)
635
+ - Border approach: `border border-border` with `rounded-lg`
636
+ - Tonal approach: card is a step lighter/darker than background, no shadow or border
637
+ - Rounding: use the component-specific radius from Phase 5
638
+ - Padding: `p-6` default (24px). Header/content/footer: `px-6 py-4` for each section
639
+ - Interactive cards: add `hover:shadow-md transition-shadow` and `cursor-pointer`
640
+ - Header: `font-semibold text-lg` with `pb-2` or a bottom border for separation
641
+ - Footer: `pt-4` with optional top border, typically contains actions aligned right
642
+
643
+ #### Inputs
644
+
645
+ Inputs are used constantly — their styling affects the entire feel of forms.
646
+
647
+ - **Fill vs outline style:**
648
+ - Outline (default): `border border-input bg-transparent` — clean, traditional, works everywhere
649
+ - Fill: `bg-muted border-transparent` — modern, reduces visual noise, works well when there are many fields
650
+ - Choice depends on form density: outline for 1-3 fields, fill for long forms
651
+
652
+ - **Focus state:** the focus state is THE most important input styling decision. It tells users where they are.
653
+ - Ring approach: `focus:ring-2 ring-ring ring-offset-2` — clear, accessible, standard
654
+ - Border glow: `focus:border-primary focus:shadow-[0_0_0_3px_var(--primary)/15%]` — softer, modern
655
+ - Background shift: `focus:bg-accent` — subtle, minimal, clean
656
+
657
+ - **Label placement:**
658
+ - Above (default): label sits above the input with `mb-1.5` spacing. Best for most forms.
659
+ - Floating: label inside the input that floats up on focus. Visually elegant but creates accessibility issues — only use with careful ARIA labeling.
660
+ - Inline: label and input on the same line. Only for very short forms (login, search).
661
+
662
+ - **Error state:**
663
+ - Border: `border-destructive` replaces the normal border
664
+ - Text: error message below in `text-destructive text-sm`
665
+ - Background tint: optional `bg-destructive/5` for emphasis on the field itself
666
+ - Icon: optional error icon inside the input (right-aligned)
667
+
668
+ - **Placeholder:** `text-muted-foreground` — never use placeholder as a label replacement. Placeholder text disappears on input, which means users lose context after typing.
669
+
670
+ #### Modals/Dialogs
671
+
672
+ Modals interrupt the user's flow — they should feel important but not aggressive.
673
+
674
+ - **Backdrop:** `bg-black/50` with optional `backdrop-blur-sm`
675
+ - Higher blur (backdrop-blur-md) for a frosted glass effect — modern, premium
676
+ - Lower opacity (bg-black/30) for less interruption — maintains context awareness
677
+ - The backdrop click-to-dismiss behavior should match the border philosophy: dismissive (casual) vs protected (enterprise)
678
+
679
+ - **Shadow depth:** `shadow-xl` or `shadow-2xl` — modals are the highest elevation surface
680
+ - **Max width:** `max-w-md` (448px) for confirmations, `max-w-lg` (512px) for forms, `max-w-2xl` (672px) for complex content
681
+ - **Padding:** `p-6` for content, `px-6 py-4` for header and footer
682
+ - **Entry animation:** fade-in + subtle scale (0.95 -> 1.0) over 200ms with ease-out
683
+ - **Exit animation:** fade-out over 150ms — exits should be faster than entrances
684
+
685
+ #### Navigation/Sidebar
686
+
687
+ Navigation sets the persistent visual frame for the entire application.
688
+
689
+ - **Active state indicator:**
690
+ - Background fill: `bg-sidebar-accent text-sidebar-accent-foreground` — clear, works everywhere
691
+ - Left border: `border-l-2 border-sidebar-primary` — minimal, editorial
692
+ - Icon fill: active icon uses `text-sidebar-primary`, inactive uses `text-sidebar-foreground/70`
693
+ - Which to use depends on the sidebar width and information density
694
+
695
+ - **Collapsed behavior:**
696
+ - Icons only with tooltips on hover
697
+ - Active state still visible (icon color or background dot)
698
+ - Transition: 200ms ease for width change
699
+
700
+ - **Section headers:** `text-xs font-medium uppercase tracking-wide text-sidebar-foreground/50` — section headers should recede, not compete with navigation items
701
+
702
+ - **Hover state:** `bg-sidebar-accent/50` — a lighter version of the active background, signaling interactivity without implying selection
703
+
704
+ #### Badges/Tags
705
+
706
+ Small visual indicators with multiple semantic variants.
707
+
708
+ - Default: `bg-secondary text-secondary-foreground` — neutral, informational
709
+ - Primary: `bg-primary/10 text-primary` — branded, highlighted (uses transparent primary background so it adapts to surface)
710
+ - Destructive: `bg-destructive/10 text-destructive` — errors, overdue items
711
+ - Outline: `border border-border bg-transparent` — subtle, minimal
712
+ - Size: `px-2.5 py-0.5 text-xs` — badges should be compact
713
+ - Rounding: follow the component-specific radius from Phase 5
714
+
715
+ #### Tables
716
+
717
+ Data presentation with clear hierarchy and comfortable density.
718
+
719
+ - **Header row:** `bg-muted/50 font-medium text-muted-foreground text-sm` — headers should recede visually. They're labels, not content.
720
+ - **Row hover:** `hover:bg-muted/30` — subtle background shift confirms the row the user is looking at
721
+ - **Cell padding:** `px-4 py-3` — enough breathing room for readability without wasting space
722
+ - **Border strategy:**
723
+ - Full grid: every cell bordered — traditional, high-density, data-focused
724
+ - Rows only: horizontal borders between rows — cleaner, modern, easier to scan
725
+ - Minimal: no borders, rows separated by subtle background alternation (`even:bg-muted/20`) — cleanest, works when data is sparse
726
+ - Choose based on data density: more data = more structure needed
727
+
728
+ #### Forms
729
+
730
+ Form layouts combining inputs, labels, and error states into coherent groups.
731
+
732
+ - **Field group spacing:** `space-y-4` (16px) between fields — enough separation for clarity without excessive scrolling
733
+ - **Section spacing:** `space-y-8` (32px) between form sections — clear grouping
734
+ - **Error state flow:** error messages appear below the field with `mt-1.5 text-sm text-destructive`, pushing content down (not overlaying)
735
+ - **Help text:** `mt-1.5 text-sm text-muted-foreground` — same position as errors but neutral color
736
+ - **Required indicator:** red asterisk after label text `<span class="text-destructive">*</span>` — universal convention, don't reinvent this
737
+ - **Submit button placement:** right-aligned for single-column forms, full-width for mobile or card-embedded forms
738
+
739
+ ---
740
+
741
+ ### Phase 7: Shadows & Depth
742
+
743
+ **Goal:** Define the shadow scale that creates visual hierarchy — the perception of elements floating above or below others.
744
+
745
+ **Announce framework:** "Shadows create the illusion of depth. Used well, they communicate hierarchy instantly — users know a dropdown floats above a card without thinking about it. I'll define the full shadow scale with values tuned to your design personality."
746
+
747
+ #### Shadow Scale
748
+
749
+ Define `--shadow-xs` through `--shadow-2xl` in the `@theme {}` block:
750
+
751
+ **Ambient/diffused style (modern, subtle):**
752
+ ```css
753
+ --shadow-xs: 0 1px 2px oklch(0 0 0 / 3%);
754
+ --shadow-sm: 0 1px 3px oklch(0 0 0 / 5%), 0 1px 2px oklch(0 0 0 / 3%);
755
+ --shadow: 0 4px 6px oklch(0 0 0 / 5%), 0 2px 4px oklch(0 0 0 / 3%);
756
+ --shadow-md: 0 6px 10px oklch(0 0 0 / 5%), 0 2px 4px oklch(0 0 0 / 2%);
757
+ --shadow-lg: 0 10px 15px oklch(0 0 0 / 5%), 0 4px 6px oklch(0 0 0 / 3%);
758
+ --shadow-xl: 0 20px 25px oklch(0 0 0 / 5%), 0 8px 10px oklch(0 0 0 / 2%);
759
+ --shadow-2xl: 0 25px 50px oklch(0 0 0 / 12%);
760
+ ```
761
+ *When to use:* clean, professional, minimal designs. Low-opacity, large-spread shadows feel airy and modern.
762
+
763
+ **Sharp/dramatic style (bold, high-contrast):**
764
+ ```css
765
+ --shadow-xs: 0 1px 2px oklch(0 0 0 / 8%);
766
+ --shadow-sm: 0 2px 4px oklch(0 0 0 / 10%);
767
+ --shadow: 0 4px 8px oklch(0 0 0 / 12%);
768
+ --shadow-md: 0 6px 12px oklch(0 0 0 / 12%);
769
+ --shadow-lg: 0 12px 24px oklch(0 0 0 / 15%);
770
+ --shadow-xl: 0 20px 40px oklch(0 0 0 / 15%);
771
+ --shadow-2xl: 0 25px 50px oklch(0 0 0 / 25%);
772
+ ```
773
+ *When to use:* bold, high-personality designs. Higher opacity and tighter spread create more defined edges and stronger depth perception.
774
+
775
+ **Brand-tinted style (premium, distinctive):**
776
+ - Replace `oklch(0 0 0 / N%)` with tinted shadows using the primary hue at very low chroma
777
+ - Example: `oklch(0.3 0.02 264 / 8%)` instead of pure black
778
+ - *When to use:* premium products where every detail should reinforce the brand. The tint is subtle — most users won't consciously notice it, but it contributes to a cohesive feeling.
779
+
780
+ #### Shadow Usage Guide
781
+
782
+ | Shadow | Usage | Example Components |
783
+ |--------|-------|-------------------|
784
+ | `shadow-xs` | Barely perceptible depth | Inline buttons, tags pressed into surface |
785
+ | `shadow-sm` | Default card elevation | Cards at rest, container sections |
786
+ | `shadow` | Default interactive elevation | Buttons, input focus glow |
787
+ | `shadow-md` | Moderate emphasis | Hovered cards, active dropdowns |
788
+ | `shadow-lg` | Floating elements | Dropdown menus, popovers, tooltips |
789
+ | `shadow-xl` | High-priority floating | Modals, command palettes |
790
+ | `shadow-2xl` | Maximum emphasis | Full-page overlays, onboarding modals |
791
+
792
+ #### Inset Shadows
793
+
794
+ For elements that feel pressed into the surface (input fields, embedded panels):
795
+ ```css
796
+ --shadow-inset: inset 0 2px 4px oklch(0 0 0 / 5%);
797
+ ```
798
+ *Use sparingly.* Inset shadows create a "pressed" effect that works for input fields in fill style but looks odd on most other elements.
799
+
800
+ #### Glassmorphism Recipe (if applicable)
801
+
802
+ For products with a modern, layered aesthetic:
803
+ ```css
804
+ backdrop-filter: blur(12px);
805
+ background: oklch(1 0 0 / 70%); /* light mode */
806
+ background: oklch(0.15 0 0 / 70%); /* dark mode */
807
+ border: 1px solid oklch(1 0 0 / 10%);
808
+ ```
809
+ *When to use:* sparingly. Glassmorphism is visually striking but computationally expensive (backdrop-blur triggers compositing layers) and can create readability issues. Best for navigation bars, sidebars, or floating toolbars — NOT for content-heavy cards or modal backdrops.
810
+
811
+ ---
812
+
813
+ ### Phase 8: Animation & Motion
814
+
815
+ **Goal:** Define how things move — transition timing, easing curves, and keyframe animations that match the product personality.
816
+
817
+ **Announce framework:** "Motion is the personality of your interface in action. Fast, sharp transitions feel efficient and precise. Slow, bouncy transitions feel playful and friendly. I'll define the timing scale, easing curves, and custom animations, all as Tailwind @theme variables and @keyframes."
818
+
819
+ #### Transition Duration Scale
820
+
821
+ Define via `@theme {}`:
822
+
823
+ | Token | Value | Usage |
824
+ |-------|-------|-------|
825
+ | `--duration-fast` | 100ms | Hover states, color changes, micro-interactions |
826
+ | `--duration-normal` | 200ms | Focus states, small element transitions, toggles |
827
+ | `--duration-slow` | 300ms | Modal entrances, sidebar expansion, page transitions |
828
+ | `--duration-slower` | 500ms | Complex multi-step animations, onboarding sequences |
829
+
830
+ *Why these values:* Human perception research shows that transitions under 100ms feel instant, 100-300ms feel responsive, and over 300ms feel deliberate. The scale maps to interaction urgency: hover states need instant feedback (fast), modals can take a beat to establish presence (slow).
831
+
832
+ #### Custom Easing Curves
833
+
834
+ ```css
835
+ --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
836
+ --ease-out: cubic-bezier(0, 0, 0.2, 1);
837
+ --ease-in: cubic-bezier(0.4, 0, 1, 1);
838
+ --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
839
+ --ease-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55);
840
+ --ease-smooth: cubic-bezier(0.25, 0.1, 0.25, 1);
841
+ ```
842
+
843
+ | Curve | Personality | When to Use |
844
+ |-------|-------------|-------------|
845
+ | `ease-out` | Professional, confident | Entrances — elements arrive confidently and settle |
846
+ | `ease-in-out` | Balanced, smooth | State transitions — toggles, color changes |
847
+ | `ease-in` | Departing, retreating | Exits — elements accelerate away (rarely used alone) |
848
+ | `ease-spring` | Playful, energetic | Fun interactions — toggle switches, badge appearance (only if personality fits) |
849
+ | `ease-bounce` | Very playful, attention-grabbing | Notification badges, celebration moments (use very sparingly) |
850
+ | `ease-smooth` | Subtle, refined | Default for most transitions — unnoticeable in the best way |
851
+
852
+ #### Custom @keyframes
853
+
854
+ Define these in the `@theme {}` block:
855
+
856
+ ```css
857
+ @keyframes fade-in {
858
+ from { opacity: 0; }
859
+ to { opacity: 1; }
860
+ }
861
+
862
+ @keyframes fade-out {
863
+ from { opacity: 1; }
864
+ to { opacity: 0; }
865
+ }
866
+
867
+ @keyframes slide-up {
868
+ from { transform: translateY(8px); opacity: 0; }
869
+ to { transform: translateY(0); opacity: 1; }
870
+ }
871
+
872
+ @keyframes slide-down {
873
+ from { transform: translateY(-8px); opacity: 0; }
874
+ to { transform: translateY(0); opacity: 1; }
875
+ }
876
+
877
+ @keyframes slide-in-from-left {
878
+ from { transform: translateX(-100%); }
879
+ to { transform: translateX(0); }
880
+ }
881
+
882
+ @keyframes slide-in-from-right {
883
+ from { transform: translateX(100%); }
884
+ to { transform: translateX(0); }
885
+ }
886
+
887
+ @keyframes slide-in-from-top {
888
+ from { transform: translateY(-100%); }
889
+ to { transform: translateY(0); }
890
+ }
891
+
892
+ @keyframes slide-in-from-bottom {
893
+ from { transform: translateY(100%); }
894
+ to { transform: translateY(0); }
895
+ }
896
+
897
+ @keyframes scale-in {
898
+ from { transform: scale(0.95); opacity: 0; }
899
+ to { transform: scale(1); opacity: 1; }
900
+ }
901
+
902
+ @keyframes spin {
903
+ from { transform: rotate(0deg); }
904
+ to { transform: rotate(360deg); }
905
+ }
906
+ ```
907
+
908
+ Map to animation utilities:
909
+
910
+ | Animation | Keyframe | Duration | Easing | Usage |
911
+ |-----------|----------|----------|--------|-------|
912
+ | `animate-fade-in` | `fade-in` | 200ms | ease-out | General element appearance |
913
+ | `animate-fade-out` | `fade-out` | 150ms | ease-in | General element disappearance |
914
+ | `animate-slide-up` | `slide-up` | 200ms | ease-out | Dropdown menus, tooltips from below |
915
+ | `animate-slide-down` | `slide-down` | 200ms | ease-out | Dropdown menus, tooltips from above |
916
+ | `animate-scale-in` | `scale-in` | 200ms | ease-out | Modals, popovers, dialog entrances |
917
+ | `animate-spin` | `spin` | 1000ms | linear | Loading spinners |
918
+
919
+ #### What Animates vs What Doesn't
920
+
921
+ **Always animate:**
922
+ - Modal/dialog entrances and exits
923
+ - Dropdown/popover appearance
924
+ - Focus ring transitions
925
+ - Hover state changes on interactive elements
926
+ - Sidebar collapse/expand
927
+ - Toast/notification entrances
928
+
929
+ **Never animate:**
930
+ - Page load (content should render instantly, not fade in piecemeal)
931
+ - Scrolling behavior (native scroll is always better than JS scroll animations)
932
+ - Text content changes (changing text should be instant, not crossfade)
933
+ - Error state appearance (errors need immediate attention, not a leisurely fade-in)
934
+
935
+ **Conditionally animate (based on product personality):**
936
+ - Card hover elevation changes (subtle lift effect)
937
+ - Button press feedback (scale down on click)
938
+ - Navigation transitions between routes
939
+ - Data visualization entrance (chart bars growing, lines drawing)
940
+
941
+ #### Motion Reduction Strategy
942
+
943
+ Always respect `prefers-reduced-motion`:
944
+
945
+ ```css
946
+ @media (prefers-reduced-motion: reduce) {
947
+ *, *::before, *::after {
948
+ animation-duration: 0.01ms !important;
949
+ animation-iteration-count: 1 !important;
950
+ transition-duration: 0.01ms !important;
951
+ }
952
+ }
953
+ ```
954
+
955
+ *Why this matters:* Motion sensitivity affects approximately 35% of adults to some degree. Vestibular disorders, migraine sensitivity, and other conditions make animation physically uncomfortable. The `prefers-reduced-motion` media query respects the user's OS-level setting. Setting durations to near-zero (not zero) ensures completion callbacks still fire.
956
+
957
+ ---
958
+
959
+ ### Phase 9: Generate Outputs
960
+
961
+ **Goal:** Produce the two deliverables — the design system document and the actual CSS file.
962
+
963
+ #### Step 1: Write `docs/design/design-system.md`
964
+
965
+ The comprehensive reference document. Follows the structure defined in the Output Format section below. Every design decision is annotated with reasoning — this document is both a reference and a teaching tool.
966
+
967
+ #### Step 2: Write `docs/design/shared-styles.css`
968
+
969
+ The actual Tailwind v4 CSS file. Must match the template structure EXACTLY:
970
+
971
+ ```css
972
+ @import "tailwindcss";
973
+ @import "tw-animate-css";
974
+ @import "shadcn/tailwind.css";
975
+ @import "tailwind-scrollbar-hide/v4";
976
+
977
+ @custom-variant dark (&:is(.dark *));
978
+
979
+ @theme inline {
980
+ /* Color token -> Tailwind utility mappings */
981
+ /* Radius scale */
982
+ /* Font family variables */
983
+ }
984
+
985
+ @theme {
986
+ /* Shadow scale */
987
+ /* Easing curves */
988
+ /* Animation definitions */
989
+ /* Typography overrides (if any) */
990
+ /* @keyframes */
991
+ }
992
+
993
+ :root {
994
+ /* All light mode CSS variables in oklch */
995
+ }
996
+
997
+ .dark {
998
+ /* All dark mode CSS variables in oklch */
999
+ }
1000
+
1001
+ @layer base {
1002
+ * {
1003
+ @apply border-border outline-ring/50;
1004
+ }
1005
+ body {
1006
+ @apply bg-background text-foreground;
1007
+ }
1008
+ }
1009
+ ```
1010
+
1011
+ This structure is non-negotiable — it must be a drop-in replacement for the Tailwind v4 blueprint's generic `shared-styles.css`.
1012
+
1013
+ #### Step 3: Update `.project-context.md`
1014
+
1015
+ Append the design system entry under `## Installed Blueprints` (or `## Product Discovery` if that section is more appropriate).
1016
+
1017
+ #### Step 4: Offer Sync (if applicable)
1018
+
1019
+ If `config/tailwind-config/shared-styles.css` (monorepo) or `src/styles/shared-styles.css` (single-repo) already exists from a previous tailwind scaffold, offer to sync immediately:
1020
+
1021
+ "I see you already have a tailwind config scaffolded. Would you like me to replace the generic tokens with your new design system tokens now? This will immediately update how all your components look."
1022
+
1023
+ #### Step 5: Suggest Component Improvements
1024
+
1025
+ Based on the design system decisions, suggest specific improvements to existing UI components:
1026
+ - "Your buttons would benefit from the rounded-xl radius we chose — the default rounded-md doesn't match the friendly personality."
1027
+ - "Consider adding a subtle hover:shadow-md to your cards — the current flat cards don't use the depth system we defined."
1028
+ - "Your sidebar should use the sidebar-specific tokens — right now it's using generic background colors."
1029
+
1030
+ ---
1031
+
1032
+ ## Output Format
1033
+
1034
+ ### design-system.md Structure
1035
+
1036
+ ```markdown
1037
+ # Design System — {Product Name}
1038
+
1039
+ ## Creative North Star
1040
+ [One paragraph defining the visual identity — the "north star" that guides every decision]
1041
+
1042
+ ## Color Philosophy
1043
+
1044
+ ### Palette Rationale
1045
+ [Why these colors for this product/audience — competitive analysis, audience expectations, personality alignment]
1046
+
1047
+ ### Surface Hierarchy
1048
+ [How surfaces layer: base -> container -> card -> elevated, with light/dark mode differences]
1049
+
1050
+ ### Dark Mode Strategy
1051
+ [How colors adapt — not just invert. Chroma reduction, lightness stepping, border opacity]
1052
+
1053
+ ### Color Reference
1054
+ | Token | Light Value | Dark Value | Usage | Tailwind Class |
1055
+ |-------|-------------|------------|-------|----------------|
1056
+ | --primary | oklch(...) | oklch(...) | Brand color, primary buttons | bg-primary |
1057
+ | ... | ... | ... | ... | ... |
1058
+
1059
+ ## Typography
1060
+
1061
+ ### Font Pairing
1062
+ [Display + body fonts with reasoning: why this pairing, what it communicates, how it serves the audience]
1063
+
1064
+ ### Type Scale
1065
+ | Size | Value | Line Height | Usage | Tailwind Class |
1066
+ |------|-------|-------------|-------|----------------|
1067
+ | xs | 0.75rem | 1rem | Captions, badges | text-xs |
1068
+ | ... | ... | ... | ... | ... |
1069
+
1070
+ ### Weight Scale
1071
+ | Weight | Value | Usage | Tailwind Class |
1072
+ |--------|-------|-------|----------------|
1073
+ | normal | 400 | Body text | font-normal |
1074
+ | ... | ... | ... | ... |
1075
+
1076
+ ## Spacing & Rhythm
1077
+
1078
+ ### Base Unit
1079
+ [What it is, why that value, how it scales]
1080
+
1081
+ ### Spacing Conventions
1082
+ [When to use which spacing values — component padding, section gaps, page margins]
1083
+
1084
+ ## Rounding
1085
+
1086
+ ### Personality
1087
+ [Description of the rounding character and why it fits]
1088
+
1089
+ ### Radius Scale
1090
+ | Token | Value | Usage | Tailwind Class |
1091
+ |-------|-------|-------|----------------|
1092
+ | --radius | Xrem | Base radius | -- |
1093
+ | sm | calc(base - 4px) | Small elements | rounded-sm |
1094
+ | ... | ... | ... | ... |
1095
+
1096
+ ## Elevation & Depth
1097
+
1098
+ ### Shadow Scale
1099
+ | Token | Value | Usage | Tailwind Class |
1100
+ |-------|-------|-------|----------------|
1101
+ | xs | ... | Tags, subtle depth | shadow-xs |
1102
+ | ... | ... | ... | ... |
1103
+
1104
+ ### Border Philosophy
1105
+ [Lines vs tonal shifts vs shadows — when and why]
1106
+
1107
+ ## Component Guidelines
1108
+
1109
+ ### Buttons
1110
+ [Deep styling: variants, sizes, states, icon alignment, gradient/flat decision]
1111
+
1112
+ ### Cards
1113
+ [Surface treatment, rounding, padding, hover behavior]
1114
+
1115
+ ### Inputs
1116
+ [Fill vs outline, focus states, error states, label placement]
1117
+
1118
+ ### Modals
1119
+ [Backdrop, shadow, animation, sizing]
1120
+
1121
+ ### Navigation
1122
+ [Active states, collapsed behavior, section headers]
1123
+
1124
+ ### Badges
1125
+ [Sizes, variants, color treatments]
1126
+
1127
+ ### Tables
1128
+ [Header styling, row hover, cell padding, border strategy]
1129
+
1130
+ ### Forms
1131
+ [Field spacing, error flow, help text, required indicators]
1132
+
1133
+ ## Animation & Motion
1134
+
1135
+ ### Duration Scale
1136
+ | Name | Value | Usage |
1137
+ |------|-------|-------|
1138
+ | fast | 100ms | Hover states |
1139
+ | ... | ... | ... |
1140
+
1141
+ ### Easing Curves
1142
+ | Name | Value | Personality | Usage |
1143
+ |------|-------|-------------|-------|
1144
+ | ease-out | cubic-bezier(...) | Confident | Entrances |
1145
+ | ... | ... | ... | ... |
1146
+
1147
+ ### Custom Animations
1148
+ [List of @keyframes with descriptions and usage guidance]
1149
+
1150
+ ### Motion Reduction
1151
+ [prefers-reduced-motion strategy]
1152
+
1153
+ ## Do's and Don'ts
1154
+
1155
+ ### Do
1156
+ - Use semantic color tokens (`bg-primary`, `text-muted-foreground`) — never raw oklch or hex values in components
1157
+ - Test every screen in both light and dark mode before considering it done
1158
+ - Use `cn()` for all className composition — never concatenate strings
1159
+ - Reference the Creative North Star when making ambiguous design decisions
1160
+ - Use the shadow scale consistently: cards=shadow-sm, dropdowns=shadow-lg, modals=shadow-xl
1161
+ - Respect the surface layering stack — each layer gets the right elevation treatment
1162
+ - Use `data-slot` attributes on every component element for CSS targeting
1163
+ - Maintain generous whitespace — if a layout feels empty, leave it
1164
+ - Tint neutrals with the brand undertone — never use pure achromatic grays unless the design specifically calls for it
1165
+ - Use the translation table to communicate design intent in plain language
1166
+
1167
+ ### Don't — Common AI Mistakes to Prevent
1168
+ - Never use `#000000` or pure black — use the `foreground` token (tinted dark)
1169
+ - Never use `#FFFFFF` directly — use the `background` token
1170
+ - Never use 1px solid borders to separate content sections — use tonal shifts, spacing, or ghost borders (`ring-1 ring-foreground/10`)
1171
+ - Never mix more than 2 typefaces on a single screen
1172
+ - Never center-align body text longer than 2 lines — left-align for readability
1173
+ - Never add shadows to elements resting on the same surface layer — shadows indicate floating
1174
+ - Never animate page-load content (causes layout shift) — reserve animation for user-triggered interactions
1175
+ - Never use generic Tailwind grays (`border-gray-200`, `bg-slate-100`) — always use semantic tokens (`border-border`, `bg-muted`)
1176
+ - Never create interactive elements without hover, focus, and active states
1177
+ - Never use `rounded-none` on interactive elements — minimum `rounded-sm`
1178
+ - Don't over-saturate — limit primary accent color to ~10-15% of visible screen area
1179
+ - Never skip the mobile viewport — every component must have a defined mobile behavior
1180
+ - Never hardcode breakpoint values — use Tailwind responsive prefixes (`sm:`, `md:`, `lg:`)
1181
+
1182
+ ## How to Use
1183
+
1184
+ ### Color Tokens in Code
1185
+ [Practical examples: bg-primary, text-muted-foreground, etc.]
1186
+
1187
+ ### Typography in Code
1188
+ [Practical examples: text-lg font-semibold tracking-tight, etc.]
1189
+
1190
+ ### Shadow Scale in Code
1191
+ [Practical examples: shadow-sm for cards, shadow-xl for modals]
1192
+
1193
+ ### Radius in Code
1194
+ [Practical examples: rounded-lg for cards, rounded-4xl for buttons]
1195
+
1196
+ ### Spacing in Code
1197
+ [Practical examples: p-4, gap-6, when to use which]
1198
+
1199
+ ### Dark Mode
1200
+ [How class-based dark mode works, what to test, common mistakes]
1201
+
1202
+ ### Quick Reference
1203
+ | What You Need | Token/Class | Example |
1204
+ |---------------|-------------|---------|
1205
+ | Brand color background | bg-primary | Primary buttons |
1206
+ | Subtle text | text-muted-foreground | Helper text, captions |
1207
+ | Card container | bg-card rounded-lg shadow-sm | Content cards |
1208
+ | Focus ring | ring-ring ring-2 ring-offset-2 | Keyboard focus |
1209
+ | ... | ... | ... |
1210
+
1211
+ ### Design Language Translation
1212
+
1213
+ When communicating design intent (in reviews, in the design doc, or when prompting AI), use these translations between technical values and natural language:
1214
+
1215
+ | Technical (Tailwind) | Design Language | When to Use |
1216
+ |---------------------|-----------------|-------------|
1217
+ | `rounded-full` | Pill-shaped | Badges, tags, avatar containers |
1218
+ | `rounded-4xl` | Generously rounded | Buttons, search bars |
1219
+ | `rounded-2xl` | Softly rounded | Cards, modals |
1220
+ | `rounded-xl` | Gently curved | Dropdowns, popovers |
1221
+ | `rounded-lg` | Subtly rounded corners | Inputs, smaller containers |
1222
+ | `rounded-none` | Sharp, squared-off edges | Avoid on interactive elements |
1223
+ | `shadow-2xs` | Barely visible lift | Subtle card definition |
1224
+ | `shadow-sm` | Whisper-soft shadow | Resting cards |
1225
+ | `shadow-md` | Gentle elevation | Hovered cards |
1226
+ | `shadow-lg` | Noticeable depth | Dropdowns, popovers |
1227
+ | `shadow-xl` | Prominent floating | Modals, dialogs |
1228
+ | `shadow-2xl` | Dramatic elevation | Full-screen overlays |
1229
+ | `bg-input/30` | Subtle tinted fill | Input field backgrounds |
1230
+ | `ring-1 ring-foreground/10` | Ghost border | When tonal shift alone isn't enough |
1231
+ | `font-medium` | Confident but not heavy | Labels, navigation |
1232
+ | `font-semibold` | Emphatic, attention-grabbing | Headings, CTAs |
1233
+ | `font-bold` | Strong authority | Hero headlines |
1234
+ | `tracking-tight` | Compact, modern feel | Display text |
1235
+ | `tracking-wide` | Spacious, editorial | Uppercase labels |
1236
+ | `leading-relaxed` | Breathing room for readability | Long-form body text |
1237
+ | `leading-tight` | Dense, compact | Headlines, UI labels |
1238
+ | `text-muted-foreground` | Recessive, supportive | Descriptions, timestamps, metadata |
1239
+ | `animate-fade-in` | Gentle appearance | Page section reveals |
1240
+ | `animate-slide-up` | Rising entrance | Toast notifications, bottom sheets |
1241
+ | `ease-spring` | Bouncy, playful snap | Playful interactions |
1242
+ | `ease-smooth` | Refined, buttery | Professional transitions |
1243
+
1244
+ ## Agent Context — Design System Quick Reference
1245
+
1246
+ *This section is formatted for AI agent consumption. When generating UI components, reference this section for quick token lookups and component recipes.*
1247
+
1248
+ ### Color Map
1249
+ [Flat list of every token with oklch value + primary Tailwind class. One line per token. No explanations — just the mapping.]
1250
+ ```
1251
+ - primary: oklch(0.488 0.243 264) → `bg-primary`, `text-primary`, `border-primary`
1252
+ - primary-foreground: oklch(0.97 0.014 254) → `text-primary-foreground`
1253
+ - background: oklch(1 0 0) → `bg-background`
1254
+ - foreground: oklch(0.145 0 0) → `text-foreground`
1255
+ [... all 31+ tokens]
1256
+ ```
1257
+
1258
+ ### Component Recipes
1259
+ [Ready-to-paste Tailwind class combinations for common component patterns. These are the "golden paths" — the exact class strings that produce correct results.]
1260
+ ```
1261
+ Primary Button: bg-primary text-primary-foreground rounded-4xl h-9 px-3 text-sm font-medium
1262
+ Secondary Button: bg-secondary text-secondary-foreground rounded-4xl h-9 px-3 text-sm font-medium
1263
+ Ghost Button: hover:bg-muted hover:text-foreground rounded-4xl h-9 px-3 text-sm font-medium
1264
+ Destructive Button: bg-destructive/10 text-destructive rounded-4xl h-9 px-3 text-sm font-medium
1265
+ Card: bg-card ring-1 ring-foreground/10 rounded-2xl p-6
1266
+ Card (compact): bg-card ring-1 ring-foreground/10 rounded-2xl p-4
1267
+ Input: bg-input/30 border-input rounded-4xl h-9 px-3 text-sm
1268
+ Badge: bg-primary text-primary-foreground rounded-4xl px-2 py-0.5 text-xs font-medium
1269
+ Separator: bg-border h-px w-full
1270
+ ```
1271
+
1272
+ ### Spacing Cheat Sheet
1273
+ ```
1274
+ Between form fields: gap-7
1275
+ Within a field (label→input→error): gap-1.5
1276
+ Between page sections: gap-12 or mt-12
1277
+ Card internal padding: p-6 (default), p-4 (compact)
1278
+ Page horizontal padding: px-6 (desktop), px-4 (mobile)
1279
+ Between cards in a grid: gap-4
1280
+ Between buttons in a row: gap-2
1281
+ ```
1282
+
1283
+ ### Surface Layering
1284
+ ```
1285
+ Page background: bg-background
1286
+ Sidebar: bg-sidebar
1287
+ Card on page: bg-card
1288
+ Input field: bg-input/30
1289
+ Popover/Dropdown: bg-popover + shadow-lg
1290
+ Modal backdrop: bg-black/50
1291
+ Modal content: bg-background + shadow-xl
1292
+ ```
1293
+
1294
+ ### Design Rules (for AI agents)
1295
+ ```
1296
+ 1. Always use cn() for className composition
1297
+ 2. Always use semantic tokens — never raw colors
1298
+ 3. Never use #000000 — use foreground token
1299
+ 4. Borders: prefer ring-1 ring-foreground/10 over border
1300
+ 5. Interactive elements: always include hover + focus states
1301
+ 6. Shadow usage: cards=shadow-sm, dropdowns=shadow-lg, modals=shadow-xl
1302
+ 7. Dark mode: test every component in both modes
1303
+ 8. Mobile: every component must work at 320px width
1304
+ 9. Typography: max 2 font families per screen
1305
+ 10. Accent: limit primary color to ~10-15% of visible area
1306
+ ```
1307
+ ```
1308
+
1309
+ ### shared-styles.css Structure
1310
+
1311
+ Must match the Tailwind v4 blueprint template structure exactly:
1312
+
1313
+ ```css
1314
+ /* 1. Imports */
1315
+ @import "tailwindcss";
1316
+ @import "tw-animate-css";
1317
+ @import "shadcn/tailwind.css";
1318
+ @import "tailwind-scrollbar-hide/v4";
1319
+
1320
+ /* 2. Custom variant */
1321
+ @custom-variant dark (&:is(.dark *));
1322
+
1323
+ /* 3. Theme inline — semantic token -> Tailwind utility mappings */
1324
+ @theme inline {
1325
+ --color-background: var(--background);
1326
+ --color-foreground: var(--foreground);
1327
+ --font-sans: var(--font-sans);
1328
+ --font-mono: var(--font-mono);
1329
+ /* ... all 31+ color mappings ... */
1330
+ /* ... radius scale ... */
1331
+ }
1332
+
1333
+ /* 4. Theme — shadows, easing, animations, keyframes */
1334
+ @theme {
1335
+ --shadow-xs: ...;
1336
+ --shadow-sm: ...;
1337
+ /* ... full shadow scale ... */
1338
+
1339
+ --ease-smooth: cubic-bezier(...);
1340
+ --ease-spring: cubic-bezier(...);
1341
+ /* ... custom easing ... */
1342
+
1343
+ --animate-fade-in: fade-in 200ms ease-out;
1344
+ --animate-slide-up: slide-up 200ms ease-out;
1345
+ /* ... animation definitions ... */
1346
+
1347
+ @keyframes fade-in { ... }
1348
+ @keyframes slide-up { ... }
1349
+ @keyframes scale-in { ... }
1350
+ /* ... all keyframes ... */
1351
+ }
1352
+
1353
+ /* 5. Light mode variables */
1354
+ :root {
1355
+ --background: oklch(... ... ...);
1356
+ --foreground: oklch(... ... ...);
1357
+ --primary: oklch(... ... ...);
1358
+ /* ... all 31+ tokens ... */
1359
+ --radius: ...rem;
1360
+ /* ... font variables ... */
1361
+ }
1362
+
1363
+ /* 6. Dark mode variables */
1364
+ .dark {
1365
+ --background: oklch(... ... ...);
1366
+ --foreground: oklch(... ... ...);
1367
+ --primary: oklch(... ... ...);
1368
+ /* ... all 31+ tokens ... */
1369
+ }
1370
+
1371
+ /* 7. Base layer */
1372
+ @layer base {
1373
+ * {
1374
+ @apply border-border outline-ring/50;
1375
+ }
1376
+ body {
1377
+ @apply bg-background text-foreground;
1378
+ }
1379
+ }
1380
+ ```
1381
+
1382
+ ---
1383
+
1384
+ ## Maintenance Hooks
1385
+
1386
+ ### Design System Hooks
1387
+
1388
+ | When you... | Then do... | Why |
1389
+ |---|---|---|
1390
+ | Change a color token in `docs/design/shared-styles.css` | Sync to `config/tailwind-config/shared-styles.css` (monorepo) or `src/styles/shared-styles.css` (single-repo) | Design source of truth must match deployed tokens |
1391
+ | Update light mode color | Update the corresponding dark mode value | Missing dark mode = broken in one mode |
1392
+ | Change font families | Ensure fonts are imported in the app layout (Google Fonts link or `@font-face`) | CSS variables reference fonts that must be loaded |
1393
+ | Add new CSS variables | Add corresponding entries to `@theme inline {}` | Tailwind utilities only work for mapped tokens |
1394
+ | Change the radius base value | Verify all component-specific radius classes still look correct | The entire radius scale recalculates from one value |
1395
+ | Update shadow values | Verify both light and dark mode look correct | Shadow opacity that works on white may be invisible on dark |
1396
+
1397
+ ### Condensed Rules for project maintenance skill
1398
+
1399
+ ```markdown
1400
+ ### design-system maintenance
1401
+ - When design tokens change in docs/design/shared-styles.css, sync to config/tailwind-config/shared-styles.css (monorepo) or src/styles/shared-styles.css (single-repo)
1402
+ - When updating colors/shadows/radius: verify both light and dark mode tokens are updated together
1403
+ - When changing font families: ensure fonts are imported in the app layout (Google Fonts link or @font-face)
1404
+ - When adding new CSS variables: add corresponding entries to the @theme inline {} block
1405
+ - docs/design/design-system.md is the source of truth for design decisions — update it when making visual changes
1406
+ - Run /design-system to regenerate tokens after significant brand or audience changes
1407
+ ```
1408
+
1409
+ ---
1410
+
1411
+ ## What's Configurable
1412
+
1413
+ - **Creative direction** — fully conversational, user picks from proposed options or mixes elements
1414
+ - **Primary color hue** — any oklch hue value (0-360), proposed based on product personality and competition
1415
+ - **Typography** — any font pairing (display + body + optional mono), researched based on audience
1416
+ - **Rounding personality** — sharp (0-4px), moderate (6-10px), round (12-16px), or full (20px+, pill buttons)
1417
+ - **Shadow style** — ambient/diffused (modern), sharp/dramatic (bold), or brand-tinted (premium)
1418
+ - **Animation personality** — subtle and professional or bouncy and playful
1419
+ - **Border philosophy** — no-line (tonal), intentional (sparse borders), or traditional (bordered)
1420
+ - **Level of component guideline depth** — comprehensive by default, concise on request
1421
+ - **Spacing density** — standard (0.25rem base), tight (0.2rem), or loose (0.3rem)
1422
+
1423
+ ---
1424
+
1425
+ ## What's Opinionated
1426
+
1427
+ - **Teach the why** — every design decision is annotated with reasoning. "Use blue" is useless. "Use blue because your enterprise audience equates blue with trust, and your competitors at [X] and [Y] already use green and violet, leaving blue as defensible territory" is educational. This blueprint is a design education disguised as a configuration tool.
1428
+
1429
+ - **oklch color space** — perceptually uniform, better dark mode translations, wider gamut than hex/RGB. Not negotiable. Colors defined as raw hex values are objectively inferior for design systems because they don't maintain perceptual consistency across lightness adjustments.
1430
+
1431
+ - **Semantic tokens, always** — never raw color values in components. Always through `--primary`, `--muted`, `--destructive`, etc. This is what makes themes changeable — swap the token values and every component updates. Hard-coded colors create un-maintainable design debt.
1432
+
1433
+ - **Surface hierarchy** — layered surfaces (background -> card -> popover -> elevated), not flat. The human visual system interprets depth naturally. Flat designs without hierarchy make users work harder to understand the structure.
1434
+
1435
+ - **Both light AND dark mode** — always, no exceptions. Light-only designs are incomplete. The shared-styles.css file always contains both `:root` and `.dark` blocks with every token defined in both.
1436
+
1437
+ - **CSS output matches Tailwind v4 template structure exactly** — the generated `shared-styles.css` is a drop-in replacement for the Tailwind v4 blueprint's generic file. Same imports, same blocks, same variable names. No creative reinterpretation of the structure.
1438
+
1439
+ - **Creative direction before any tokens** — the Creative North Star comes first. Without it, color and typography choices are arbitrary. With it, every subsequent decision is evaluated against a coherent vision.
1440
+
1441
+ - **Educational annotations** — the user learns design thinking through the process. Every "I recommend X" comes with "because Y, which matters for your product because Z." The goal is not just a design system but a designer who understands it.
1442
+
1443
+ - **Honest about tradeoffs** — rounded corners ARE friendlier but DO lose information density. Dark mode IS expected but DOES require more design work. Bold colors DO differentiate but CAN fatigue users. Every recommendation acknowledges what you give up.
1444
+
1445
+ ---
1446
+
1447
+ ## Project Context Output
1448
+
1449
+ After completion, appends to `.project-context.md` in the target project:
1450
+
1451
+ ```yaml
1452
+ ### design-system
1453
+ blueprint: design-system
1454
+ installed_at: <date>
1455
+ creative_direction: "<north star name>"
1456
+ primary_color_hue: <oklch hue value>
1457
+ font_display: "<font name>"
1458
+ font_body: "<font name>"
1459
+ rounding: "<personality: sharp/moderate/round/full>"
1460
+ artifacts:
1461
+ - docs/design/design-system.md
1462
+ - docs/design/shared-styles.css
1463
+ synced_to: config/tailwind-config/shared-styles.css # if synced
1464
+ ```
1465
+
1466
+ ---
1467
+
1468
+ ## References
1469
+
1470
+ - **Tailwind CSS v4 Theme:** https://tailwindcss.com/docs/theme
1471
+ - **OKLCH Color Space:** https://oklch.com
1472
+ - **OKLCH Color Picker:** https://oklch.com/#70,0.1,200,100
1473
+ - **Google Material Design 3:** https://m3.material.io
1474
+ - **Practical Typography:** https://practicaltypography.com
1475
+ - **Google Fonts:** https://fonts.google.com
1476
+ - **Type Scale Calculator:** https://typescale.com
1477
+ - **Bar & Neta (2006):** Humans prefer curved visual objects (Psychological Science) — the research behind rounding personality
1478
+ - **shadcn/ui Theming:** https://ui.shadcn.com/docs/theming
1479
+ - **WCAG Non-text Contrast (1.4.11):** https://www.w3.org/WAI/WCAG21/Understanding/non-text-contrast.html