@motor-cms/ui-admin 1.0.1-alpha.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 (103) hide show
  1. package/README.md +77 -0
  2. package/app/components/form/inputs/CategoryTreeInput.vue +154 -0
  3. package/app/components/form/inputs/CategoryTreePicker.vue +355 -0
  4. package/app/components/form/inputs/NestedDraggable.vue +217 -0
  5. package/app/components/form/inputs/QuicklinksInput.vue +186 -0
  6. package/app/lang/de/motor-admin/CLAUDE.md +21 -0
  7. package/app/lang/de/motor-admin/ai_system_prompts.json +12 -0
  8. package/app/lang/de/motor-admin/categories.json +12 -0
  9. package/app/lang/de/motor-admin/category_trees.json +14 -0
  10. package/app/lang/de/motor-admin/clients.json +26 -0
  11. package/app/lang/de/motor-admin/config_variables.json +14 -0
  12. package/app/lang/de/motor-admin/domains.json +19 -0
  13. package/app/lang/de/motor-admin/email_templates.json +38 -0
  14. package/app/lang/de/motor-admin/global.json +5 -0
  15. package/app/lang/de/motor-admin/languages.json +16 -0
  16. package/app/lang/de/motor-admin/permissions.json +14 -0
  17. package/app/lang/de/motor-admin/roles.json +15 -0
  18. package/app/lang/de/motor-admin/users.json +22 -0
  19. package/app/lang/en/motor-admin/CLAUDE.md +7 -0
  20. package/app/lang/en/motor-admin/ai_system_prompts.json +12 -0
  21. package/app/lang/en/motor-admin/categories.json +12 -0
  22. package/app/lang/en/motor-admin/category_trees.json +14 -0
  23. package/app/lang/en/motor-admin/clients.json +26 -0
  24. package/app/lang/en/motor-admin/config_variables.json +14 -0
  25. package/app/lang/en/motor-admin/domains.json +18 -0
  26. package/app/lang/en/motor-admin/email_templates.json +33 -0
  27. package/app/lang/en/motor-admin/global.json +5 -0
  28. package/app/lang/en/motor-admin/languages.json +16 -0
  29. package/app/lang/en/motor-admin/permissions.json +14 -0
  30. package/app/lang/en/motor-admin/roles.json +15 -0
  31. package/app/lang/en/motor-admin/users.json +22 -0
  32. package/app/pages/dashboard.vue +5 -0
  33. package/app/pages/index.vue +39 -0
  34. package/app/pages/login.vue +85 -0
  35. package/app/pages/motor-admin/ai-system-prompts/CLAUDE.md +7 -0
  36. package/app/pages/motor-admin/ai-system-prompts/[id]/edit.vue +48 -0
  37. package/app/pages/motor-admin/ai-system-prompts/create.vue +40 -0
  38. package/app/pages/motor-admin/ai-system-prompts/index.vue +68 -0
  39. package/app/pages/motor-admin/category-trees/CLAUDE.md +7 -0
  40. package/app/pages/motor-admin/category-trees/[id]/CLAUDE.md +7 -0
  41. package/app/pages/motor-admin/category-trees/[id]/categories/[categoryId]/edit.vue +73 -0
  42. package/app/pages/motor-admin/category-trees/[id]/categories/create.vue +64 -0
  43. package/app/pages/motor-admin/category-trees/[id]/edit.vue +45 -0
  44. package/app/pages/motor-admin/category-trees/[id]/index.vue +81 -0
  45. package/app/pages/motor-admin/category-trees/create.vue +37 -0
  46. package/app/pages/motor-admin/category-trees/index.vue +54 -0
  47. package/app/pages/motor-admin/clients/CLAUDE.md +11 -0
  48. package/app/pages/motor-admin/clients/[id]/CLAUDE.md +11 -0
  49. package/app/pages/motor-admin/clients/[id]/edit.vue +45 -0
  50. package/app/pages/motor-admin/clients/create.vue +37 -0
  51. package/app/pages/motor-admin/clients/index.vue +46 -0
  52. package/app/pages/motor-admin/config-variables/CLAUDE.md +11 -0
  53. package/app/pages/motor-admin/config-variables/[id]/edit.vue +44 -0
  54. package/app/pages/motor-admin/config-variables/create.vue +36 -0
  55. package/app/pages/motor-admin/config-variables/index.vue +66 -0
  56. package/app/pages/motor-admin/domains/CLAUDE.md +11 -0
  57. package/app/pages/motor-admin/domains/[id]/edit.vue +54 -0
  58. package/app/pages/motor-admin/domains/create.vue +46 -0
  59. package/app/pages/motor-admin/domains/index.vue +98 -0
  60. package/app/pages/motor-admin/email-templates/CLAUDE.md +12 -0
  61. package/app/pages/motor-admin/email-templates/[id]/CLAUDE.md +7 -0
  62. package/app/pages/motor-admin/email-templates/[id]/edit.vue +56 -0
  63. package/app/pages/motor-admin/email-templates/create.vue +48 -0
  64. package/app/pages/motor-admin/email-templates/index.vue +67 -0
  65. package/app/pages/motor-admin/index.vue +12 -0
  66. package/app/pages/motor-admin/languages/CLAUDE.md +7 -0
  67. package/app/pages/motor-admin/languages/[id]/edit.vue +44 -0
  68. package/app/pages/motor-admin/languages/create.vue +36 -0
  69. package/app/pages/motor-admin/languages/index.vue +44 -0
  70. package/app/pages/motor-admin/permission-groups/CLAUDE.md +14 -0
  71. package/app/pages/motor-admin/permission-groups/[id]/CLAUDE.md +11 -0
  72. package/app/pages/motor-admin/permission-groups/[id]/edit.vue +49 -0
  73. package/app/pages/motor-admin/permission-groups/create.vue +41 -0
  74. package/app/pages/motor-admin/permission-groups/index.vue +43 -0
  75. package/app/pages/motor-admin/roles/CLAUDE.md +7 -0
  76. package/app/pages/motor-admin/roles/[id]/edit.vue +47 -0
  77. package/app/pages/motor-admin/roles/create.vue +40 -0
  78. package/app/pages/motor-admin/roles/index.vue +45 -0
  79. package/app/pages/motor-admin/theme-preview/CLAUDE.md +7 -0
  80. package/app/pages/motor-admin/theme-preview/index.vue +4801 -0
  81. package/app/pages/motor-admin/theme-preview/themes/CLAUDE.md +11 -0
  82. package/app/pages/motor-admin/theme-preview/themes/asymmetric-brutalist.md +381 -0
  83. package/app/pages/motor-admin/theme-preview/themes/bold-modern.md +231 -0
  84. package/app/pages/motor-admin/theme-preview/themes/geometric-minimal.md +778 -0
  85. package/app/pages/motor-admin/theme-preview/themes/gradient-flow.md +1057 -0
  86. package/app/pages/motor-admin/theme-preview/themes/liquid-glass.md +823 -0
  87. package/app/pages/motor-admin/theme-preview/themes/neon-amber.md +1223 -0
  88. package/app/pages/motor-admin/theme-preview/themes/neon-terminal.md +779 -0
  89. package/app/pages/motor-admin/theme-preview/themes/neon-violet.md +1134 -0
  90. package/app/pages/motor-admin/theme-preview/themes/professional-clean.md +232 -0
  91. package/app/pages/motor-admin/theme-preview/themes/refined-brutalist.md +462 -0
  92. package/app/pages/motor-admin/theme-preview/themes/wild-card.md +263 -0
  93. package/app/pages/motor-admin/users/CLAUDE.md +17 -0
  94. package/app/pages/motor-admin/users/[id]/CLAUDE.md +11 -0
  95. package/app/pages/motor-admin/users/[id]/edit.vue +83 -0
  96. package/app/pages/motor-admin/users/create.vue +40 -0
  97. package/app/pages/motor-admin/users/index.vue +66 -0
  98. package/app/pages/profile.vue +363 -0
  99. package/app/pages/search.vue +91 -0
  100. package/app/types/generated/form-meta.ts +258 -0
  101. package/app/types/generated/grid-meta.ts +172 -0
  102. package/nuxt.config.ts +1 -0
  103. package/package.json +26 -0
@@ -0,0 +1,778 @@
1
+ # Geometric Minimal Theme
2
+
3
+ **Concept:** A Bauhaus/Suprematism-inspired admin panel that treats UI as abstract art. Every element is either a perfect circle/pill OR a razor-sharp rectangle — nothing in between. Oversized typography commands attention. A strict primary color palette (modernized Mondrian) creates bold visual hierarchy against vast white space. This is the admin panel Malevich would have built.
4
+
5
+ **Mood:** Confident, intellectual, striking. Like walking into a gallery where every wall is a perfectly composed grid.
6
+
7
+ ---
8
+
9
+ ## 1. Color Palette
10
+
11
+ A modernized Bauhaus/Mondrian palette: three bold primaries + black + white. Colors are used sparingly as accents against dominant white space. Black provides structure. Color = meaning.
12
+
13
+ ### Primary Palette
14
+
15
+ | Name | Hex | Tailwind | Usage |
16
+ |------|-----|----------|-------|
17
+ | **Bauhaus Red** | `#D62828` | `red-600` (custom) | Destructive actions, critical alerts, active states |
18
+ | **Bauhaus Blue** | `#003DA5` | `blue-800` (custom) | Primary actions, selected states, links |
19
+ | **Bauhaus Yellow** | `#F5B700` | `yellow-500` (custom) | Warnings, highlights, accent badges |
20
+ | **Pure Black** | `#0A0A0A` | `neutral-950` | Text, borders, structural lines, sidebar |
21
+ | **Pure White** | `#FFFFFF` | `white` | Canvas, backgrounds, breathing room |
22
+
23
+ ### Extended Neutrals (used sparingly)
24
+
25
+ | Name | Hex | Tailwind | Usage |
26
+ |------|-----|----------|-------|
27
+ | **Concrete** | `#F5F5F0` | `stone-100` (custom) | Subtle card backgrounds, table stripes |
28
+ | **Graphite** | `#404040` | `neutral-700` | Secondary text, muted labels |
29
+ | **Silver Line** | `#E0E0E0` | `neutral-300` | Dividers, borders (thin only) |
30
+
31
+ ### Color Rules
32
+ - **80% white/off-white**, 15% black, 5% color accents
33
+ - Color is ONLY used for meaning: blue = action, red = danger, yellow = attention
34
+ - Never use color decoratively — every colored element must communicate something
35
+ - Hover states intensify color (darker shade), never change hue
36
+ - Dark mode: invert canvas to `#0A0A0A`, text to `#F5F5F0`, keep accent colors identical
37
+
38
+ ### Tailwind v4 CSS Variables
39
+
40
+ ```css
41
+ @theme {
42
+ --color-bauhaus-red: #D62828;
43
+ --color-bauhaus-blue: #003DA5;
44
+ --color-bauhaus-yellow: #F5B700;
45
+ --color-canvas: #FFFFFF;
46
+ --color-ink: #0A0A0A;
47
+ --color-concrete: #F5F5F0;
48
+ --color-graphite: #404040;
49
+ --color-silver-line: #E0E0E0;
50
+ }
51
+ ```
52
+
53
+ ---
54
+
55
+ ## 2. Font Pairing
56
+
57
+ ### Heading: Syne (Google Fonts)
58
+ - **Why:** Syne is an experimental geometric sans-serif that gets wider as it gets bolder — a dramatic, architectural effect perfect for Bauhaus aesthetics. At ExtraBold 800, it has an imposing, almost brutalist presence. Designed for the Synesthesie art center in Paris.
59
+ - **Weights used:** Bold 700 (subheadings), ExtraBold 800 (page titles, hero numbers)
60
+ - **Character:** Geometric, widening, commanding. Looks stunning at 48px+.
61
+
62
+ ### Body: Plus Jakarta Sans (Google Fonts)
63
+ - **Why:** A modern geometric sans-serif with slightly taller x-height, open counters, and balanced spacing. Clean and highly legible at all sizes. Its geometric DNA harmonizes with Syne without competing.
64
+ - **Weights used:** Regular 400 (body), Medium 500 (labels, emphasis), SemiBold 600 (table headers, nav)
65
+ - **Character:** Precise, friendly, professional. Perfectly legible at 16px body size.
66
+
67
+ ### Mono: Space Mono (Google Fonts)
68
+ - **Why:** Geometric monospace with a techy character. Used sparingly for data, code, and numeric displays.
69
+ - **Weight:** Regular 400
70
+
71
+ ### Google Fonts URL
72
+ ```
73
+ https://fonts.googleapis.com/css2?family=Syne:wght@700;800&family=Plus+Jakarta+Sans:ital,wght@0,400;0,500;0,600;1,400&family=Space+Mono&display=swap
74
+ ```
75
+
76
+ ### Type Scale (Desktop)
77
+
78
+ | Element | Font | Weight | Size | Line Height | Letter Spacing | CSS |
79
+ |---------|------|--------|------|-------------|----------------|-----|
80
+ | **Page Title (H1)** | Syne | 800 | 48px (3rem) | 1.1 | -0.02em | `font-family: 'Syne'; font-weight: 800; font-size: 3rem; line-height: 1.1; letter-spacing: -0.02em;` |
81
+ | **Section Title (H2)** | Syne | 800 | 36px (2.25rem) | 1.15 | -0.01em | `font-family: 'Syne'; font-weight: 800; font-size: 2.25rem; line-height: 1.15; letter-spacing: -0.01em;` |
82
+ | **Card Title (H3)** | Syne | 700 | 24px (1.5rem) | 1.2 | 0 | `font-family: 'Syne'; font-weight: 700; font-size: 1.5rem; line-height: 1.2;` |
83
+ | **Subsection (H4)** | Plus Jakarta Sans | 600 | 18px (1.125rem) | 1.3 | 0.01em | `font-family: 'Plus Jakarta Sans'; font-weight: 600; font-size: 1.125rem;` |
84
+ | **Body** | Plus Jakarta Sans | 400 | 16px (1rem) | 1.6 | 0 | `font-family: 'Plus Jakarta Sans'; font-weight: 400; font-size: 1rem; line-height: 1.6;` |
85
+ | **Label / Caption** | Plus Jakarta Sans | 500 | 13px (0.8125rem) | 1.4 | 0.04em | `text-transform: uppercase; letter-spacing: 0.04em;` |
86
+ | **Data / Numbers** | Space Mono | 400 | 14px (0.875rem) | 1.5 | 0 | `font-family: 'Space Mono'; font-variant-numeric: tabular-nums;` |
87
+ | **Hero Number** | Syne | 800 | 72px (4.5rem) | 1.0 | -0.03em | `font-family: 'Syne'; font-weight: 800; font-size: 4.5rem;` |
88
+
89
+ ---
90
+
91
+ ## 3. Shape Language
92
+
93
+ **The Core Rule:** Everything is either **fully round** (border-radius: 9999px) or **completely sharp** (border-radius: 0). There is NO middle ground. No `rounded-md`, no `rounded-lg`. This binary creates visual tension and makes the interface feel like a composed geometric artwork.
94
+
95
+ ### Shape Assignment Table
96
+
97
+ | Element | Shape | Border Radius | Reasoning |
98
+ |---------|-------|---------------|-----------|
99
+ | **Buttons (primary)** | Pill | `border-radius: 9999px` | Pill shapes feel active, clickable, dynamic |
100
+ | **Buttons (secondary/ghost)** | Sharp rectangle | `border-radius: 0` | Creates contrast with primary buttons |
101
+ | **Cards** | Sharp rectangle | `border-radius: 0` | Cards are structural containers — architectural |
102
+ | **Input fields** | Sharp rectangle | `border-radius: 0` | Clean, precise, form-as-grid |
103
+ | **Select dropdowns** | Sharp rectangle | `border-radius: 0` | Consistent with input fields |
104
+ | **Dropdown menus** | Sharp rectangle | `border-radius: 0` | Architectural containers |
105
+ | **Badges / Tags** | Pill | `border-radius: 9999px` | Small, floating elements are round |
106
+ | **Avatars** | Circle | `border-radius: 9999px` | Always perfect circles |
107
+ | **Tooltips** | Sharp rectangle | `border-radius: 0` | Structural, informational |
108
+ | **Modals / Dialogs** | Sharp rectangle | `border-radius: 0` | Large containers are always sharp |
109
+ | **Toggle switches** | Pill track + circle knob | Track: `9999px`, Knob: `50%` | Organic, tactile elements are round |
110
+ | **Progress bars** | Pill | `border-radius: 9999px` | Linear flow, round ends |
111
+ | **Sidebar** | Sharp rectangle | `border-radius: 0` | Structural, architectural |
112
+ | **Navigation pills** | Pill | `border-radius: 9999px` | Active nav items are pill-shaped |
113
+ | **Stat cards** | Sharp rectangle | `border-radius: 0` | Grid blocks, Mondrian-like |
114
+ | **Notification dot** | Circle | `border-radius: 50%` | Tiny, round, orbital |
115
+ | **Checkbox** | Sharp square | `border-radius: 0` | Geometric, precise |
116
+ | **Tab bar** | Sharp underline (no radius) | N/A | Structural, no rounding needed |
117
+
118
+ ### Tailwind Classes
119
+
120
+ ```
121
+ /* Round elements */
122
+ .geo-round { @apply rounded-full; } /* border-radius: 9999px */
123
+
124
+ /* Sharp elements */
125
+ .geo-sharp { @apply rounded-none; } /* border-radius: 0 */
126
+
127
+ /* No other border-radius values exist in this theme */
128
+ ```
129
+
130
+ ---
131
+
132
+ ## 4. Component Styling
133
+
134
+ All components are oversized: 1.5-2x normal sizing. Buttons are big enough to feel confident. Inputs are tall enough to breathe. White space is generous. Everything feels deliberately placed, not crammed.
135
+
136
+ ### Buttons
137
+
138
+ ```css
139
+ /* Primary Button — Pill, oversized, bold */
140
+ .btn-primary {
141
+ font-family: 'Plus Jakarta Sans', sans-serif;
142
+ font-weight: 600;
143
+ font-size: 1rem; /* 16px — larger than typical 14px */
144
+ padding: 16px 40px; /* 1.5x normal padding */
145
+ border-radius: 9999px; /* Full pill */
146
+ background: #003DA5; /* Bauhaus Blue */
147
+ color: #FFFFFF;
148
+ border: none;
149
+ text-transform: none;
150
+ letter-spacing: 0;
151
+ transition: background 0.15s ease;
152
+ min-height: 56px; /* Oversized touch target */
153
+ }
154
+ .btn-primary:hover {
155
+ background: #002B75; /* Darker blue */
156
+ }
157
+
158
+ /* Secondary Button — Sharp rectangle, outlined */
159
+ .btn-secondary {
160
+ font-family: 'Plus Jakarta Sans', sans-serif;
161
+ font-weight: 600;
162
+ font-size: 1rem;
163
+ padding: 16px 40px;
164
+ border-radius: 0; /* Razor sharp */
165
+ background: transparent;
166
+ color: #0A0A0A;
167
+ border: 2px solid #0A0A0A;
168
+ min-height: 56px;
169
+ transition: all 0.15s ease;
170
+ }
171
+ .btn-secondary:hover {
172
+ background: #0A0A0A;
173
+ color: #FFFFFF;
174
+ }
175
+
176
+ /* Danger Button — Pill, red */
177
+ .btn-danger {
178
+ font-family: 'Plus Jakarta Sans', sans-serif;
179
+ font-weight: 600;
180
+ font-size: 1rem;
181
+ padding: 16px 40px;
182
+ border-radius: 9999px;
183
+ background: #D62828;
184
+ color: #FFFFFF;
185
+ border: none;
186
+ min-height: 56px;
187
+ }
188
+
189
+ /* Small Button — still oversized by normal standards */
190
+ .btn-sm {
191
+ font-size: 0.875rem;
192
+ padding: 10px 28px;
193
+ min-height: 44px;
194
+ }
195
+
196
+ /* Icon Button — perfect circle */
197
+ .btn-icon {
198
+ width: 56px;
199
+ height: 56px;
200
+ border-radius: 9999px;
201
+ display: flex;
202
+ align-items: center;
203
+ justify-content: center;
204
+ padding: 0;
205
+ }
206
+ ```
207
+
208
+ **Tailwind shorthand:**
209
+ ```
210
+ <!-- Primary pill button -->
211
+ <button class="rounded-full bg-bauhaus-blue text-white font-semibold text-base px-10 py-4 min-h-14 hover:bg-blue-900 transition-colors">
212
+ Create User
213
+ </button>
214
+
215
+ <!-- Secondary sharp button -->
216
+ <button class="rounded-none border-2 border-ink text-ink font-semibold text-base px-10 py-4 min-h-14 hover:bg-ink hover:text-white transition-colors">
217
+ Cancel
218
+ </button>
219
+ ```
220
+
221
+ ### Cards
222
+
223
+ ```css
224
+ /* Base Card — sharp, generous padding, subtle border */
225
+ .card {
226
+ border-radius: 0;
227
+ border: 1px solid #E0E0E0;
228
+ background: #FFFFFF;
229
+ padding: 32px; /* 2rem — generous internal space */
230
+ position: relative;
231
+ }
232
+
233
+ /* Stat Card — black background, white text, oversized number */
234
+ .card-stat {
235
+ border-radius: 0;
236
+ background: #0A0A0A;
237
+ color: #FFFFFF;
238
+ padding: 32px;
239
+ border: none;
240
+ }
241
+ .card-stat .stat-number {
242
+ font-family: 'Syne', sans-serif;
243
+ font-weight: 800;
244
+ font-size: 4.5rem; /* 72px hero number */
245
+ line-height: 1;
246
+ letter-spacing: -0.03em;
247
+ }
248
+ .card-stat .stat-label {
249
+ font-family: 'Plus Jakarta Sans', sans-serif;
250
+ font-weight: 500;
251
+ font-size: 0.8125rem;
252
+ text-transform: uppercase;
253
+ letter-spacing: 0.04em;
254
+ color: #999;
255
+ margin-top: 8px;
256
+ }
257
+
258
+ /* Colored accent card — thin color top border */
259
+ .card-accent-blue {
260
+ border-radius: 0;
261
+ border: 1px solid #E0E0E0;
262
+ border-top: 4px solid #003DA5;
263
+ padding: 32px;
264
+ }
265
+ .card-accent-red {
266
+ border-top-color: #D62828;
267
+ }
268
+ .card-accent-yellow {
269
+ border-top-color: #F5B700;
270
+ }
271
+ ```
272
+
273
+ **Tailwind shorthand:**
274
+ ```html
275
+ <!-- Sharp card -->
276
+ <div class="rounded-none border border-silver-line bg-white p-8">
277
+ ...
278
+ </div>
279
+
280
+ <!-- Stat card with hero number -->
281
+ <div class="rounded-none bg-ink text-white p-8">
282
+ <span class="font-syne font-extrabold text-7xl leading-none tracking-tight">2,847</span>
283
+ <p class="text-sm font-medium uppercase tracking-wider text-neutral-400 mt-2">Total Users</p>
284
+ </div>
285
+ ```
286
+
287
+ ### Input Fields
288
+
289
+ ```css
290
+ /* Text Input — sharp, tall, thick bottom border */
291
+ .input {
292
+ font-family: 'Plus Jakarta Sans', sans-serif;
293
+ font-size: 1rem;
294
+ font-weight: 400;
295
+ padding: 16px 20px; /* Tall and spacious */
296
+ border-radius: 0;
297
+ border: 2px solid #E0E0E0;
298
+ background: #FFFFFF;
299
+ min-height: 56px;
300
+ transition: border-color 0.15s ease;
301
+ }
302
+ .input:focus {
303
+ border-color: #003DA5;
304
+ outline: none;
305
+ box-shadow: none; /* No glow — just crisp border change */
306
+ }
307
+ .input::placeholder {
308
+ color: #999;
309
+ font-weight: 400;
310
+ }
311
+
312
+ /* Input Label — uppercase, small, spaced */
313
+ .input-label {
314
+ font-family: 'Plus Jakarta Sans', sans-serif;
315
+ font-weight: 500;
316
+ font-size: 0.8125rem;
317
+ text-transform: uppercase;
318
+ letter-spacing: 0.04em;
319
+ color: #404040;
320
+ margin-bottom: 8px;
321
+ display: block;
322
+ }
323
+ ```
324
+
325
+ **Tailwind shorthand:**
326
+ ```html
327
+ <label class="block text-xs font-medium uppercase tracking-wider text-graphite mb-2">Email Address</label>
328
+ <input class="rounded-none border-2 border-silver-line bg-white px-5 py-4 min-h-14 text-base w-full focus:border-bauhaus-blue focus:outline-none transition-colors" />
329
+ ```
330
+
331
+ ### Badges / Tags
332
+
333
+ ```css
334
+ /* Badge — pill, compact, bold color */
335
+ .badge {
336
+ font-family: 'Plus Jakarta Sans', sans-serif;
337
+ font-weight: 600;
338
+ font-size: 0.75rem;
339
+ padding: 6px 16px;
340
+ border-radius: 9999px;
341
+ text-transform: uppercase;
342
+ letter-spacing: 0.04em;
343
+ display: inline-flex;
344
+ align-items: center;
345
+ }
346
+ .badge-blue {
347
+ background: #003DA5;
348
+ color: #FFFFFF;
349
+ }
350
+ .badge-red {
351
+ background: #D62828;
352
+ color: #FFFFFF;
353
+ }
354
+ .badge-yellow {
355
+ background: #F5B700;
356
+ color: #0A0A0A;
357
+ }
358
+ .badge-outline {
359
+ background: transparent;
360
+ border: 2px solid #0A0A0A;
361
+ color: #0A0A0A;
362
+ }
363
+ ```
364
+
365
+ **Tailwind shorthand:**
366
+ ```html
367
+ <span class="rounded-full bg-bauhaus-blue text-white text-xs font-semibold uppercase tracking-wider px-4 py-1.5">Active</span>
368
+ <span class="rounded-full bg-bauhaus-red text-white text-xs font-semibold uppercase tracking-wider px-4 py-1.5">Blocked</span>
369
+ ```
370
+
371
+ ### Avatars
372
+
373
+ ```css
374
+ /* Avatar — always a perfect circle */
375
+ .avatar-lg {
376
+ width: 64px;
377
+ height: 64px;
378
+ border-radius: 9999px;
379
+ object-fit: cover;
380
+ border: 3px solid #0A0A0A;
381
+ }
382
+ .avatar-md {
383
+ width: 48px;
384
+ height: 48px;
385
+ border-radius: 9999px;
386
+ border: 2px solid #0A0A0A;
387
+ }
388
+ .avatar-sm {
389
+ width: 32px;
390
+ height: 32px;
391
+ border-radius: 9999px;
392
+ border: 2px solid #0A0A0A;
393
+ }
394
+ /* Avatar fallback (initials) */
395
+ .avatar-fallback {
396
+ background: #003DA5;
397
+ color: #FFFFFF;
398
+ font-family: 'Syne', sans-serif;
399
+ font-weight: 700;
400
+ display: flex;
401
+ align-items: center;
402
+ justify-content: center;
403
+ }
404
+ ```
405
+
406
+ ### Table
407
+
408
+ ```css
409
+ /* Table — sharp, structured, Mondrian grid */
410
+ .table {
411
+ width: 100%;
412
+ border-collapse: collapse;
413
+ border: 2px solid #0A0A0A;
414
+ }
415
+ .table th {
416
+ font-family: 'Plus Jakarta Sans', sans-serif;
417
+ font-weight: 600;
418
+ font-size: 0.8125rem;
419
+ text-transform: uppercase;
420
+ letter-spacing: 0.04em;
421
+ padding: 16px 20px;
422
+ text-align: left;
423
+ background: #0A0A0A;
424
+ color: #FFFFFF;
425
+ border-bottom: 2px solid #0A0A0A;
426
+ }
427
+ .table td {
428
+ padding: 16px 20px; /* Generous row height */
429
+ border-bottom: 1px solid #E0E0E0;
430
+ font-size: 0.9375rem;
431
+ }
432
+ .table tr:hover td {
433
+ background: #F5F5F0;
434
+ }
435
+ ```
436
+
437
+ ### Sidebar Navigation
438
+
439
+ ```css
440
+ /* Sidebar — black, sharp, dramatic */
441
+ .sidebar {
442
+ background: #0A0A0A;
443
+ color: #FFFFFF;
444
+ width: 280px;
445
+ min-height: 100vh;
446
+ padding: 32px 0;
447
+ border-right: none;
448
+ }
449
+ .sidebar-brand {
450
+ font-family: 'Syne', sans-serif;
451
+ font-weight: 800;
452
+ font-size: 1.5rem;
453
+ padding: 0 24px 32px;
454
+ border-bottom: 2px solid #333;
455
+ }
456
+ .sidebar-nav-item {
457
+ font-family: 'Plus Jakarta Sans', sans-serif;
458
+ font-weight: 500;
459
+ font-size: 0.9375rem;
460
+ padding: 14px 24px;
461
+ color: #999;
462
+ transition: all 0.15s ease;
463
+ border-radius: 0;
464
+ }
465
+ .sidebar-nav-item:hover {
466
+ color: #FFFFFF;
467
+ background: rgba(255, 255, 255, 0.05);
468
+ }
469
+ .sidebar-nav-item.active {
470
+ color: #FFFFFF;
471
+ background: #003DA5;
472
+ font-weight: 600;
473
+ }
474
+
475
+ /* Nav group label */
476
+ .sidebar-group-label {
477
+ font-size: 0.6875rem;
478
+ font-weight: 500;
479
+ text-transform: uppercase;
480
+ letter-spacing: 0.08em;
481
+ color: #666;
482
+ padding: 24px 24px 8px;
483
+ }
484
+ ```
485
+
486
+ ### Dividers / Separators
487
+
488
+ ```css
489
+ /* Bold structural divider — Mondrian-style line */
490
+ .divider-bold {
491
+ height: 3px;
492
+ background: #0A0A0A;
493
+ border: none;
494
+ margin: 32px 0;
495
+ }
496
+
497
+ /* Subtle divider */
498
+ .divider-subtle {
499
+ height: 1px;
500
+ background: #E0E0E0;
501
+ border: none;
502
+ margin: 24px 0;
503
+ }
504
+
505
+ /* Colored divider accent */
506
+ .divider-blue { background: #003DA5; height: 3px; }
507
+ .divider-red { background: #D62828; height: 3px; }
508
+ .divider-yellow { background: #F5B700; height: 3px; }
509
+ ```
510
+
511
+ ### Modal / Dialog
512
+
513
+ ```css
514
+ /* Modal — sharp, large, dramatic */
515
+ .modal-overlay {
516
+ background: rgba(10, 10, 10, 0.7);
517
+ }
518
+ .modal {
519
+ border-radius: 0;
520
+ background: #FFFFFF;
521
+ border: 2px solid #0A0A0A;
522
+ padding: 40px;
523
+ max-width: 560px;
524
+ width: 100%;
525
+ box-shadow: 8px 8px 0 #0A0A0A; /* Hard geometric shadow */
526
+ }
527
+ .modal-title {
528
+ font-family: 'Syne', sans-serif;
529
+ font-weight: 800;
530
+ font-size: 1.5rem;
531
+ margin-bottom: 16px;
532
+ }
533
+ ```
534
+
535
+ ### Toast / Notification
536
+
537
+ ```css
538
+ /* Toast — sharp rectangle, bold left border */
539
+ .toast {
540
+ border-radius: 0;
541
+ border: 1px solid #E0E0E0;
542
+ border-left: 4px solid #003DA5;
543
+ padding: 20px 24px;
544
+ background: #FFFFFF;
545
+ box-shadow: 4px 4px 0 rgba(0, 0, 0, 0.08);
546
+ min-width: 360px;
547
+ }
548
+ .toast-error { border-left-color: #D62828; }
549
+ .toast-warning { border-left-color: #F5B700; }
550
+ .toast-success { border-left-color: #003DA5; }
551
+ ```
552
+
553
+ ---
554
+
555
+ ## 5. Spacing & Layout
556
+
557
+ ### Grid System
558
+ - **Bento-style grid** inspired by Mondrian compositions
559
+ - Base unit: **8px**
560
+ - Standard gap between cards/sections: **24px** (3 units)
561
+ - Page padding: **32px** (4 units)
562
+ - Sidebar width: **280px**
563
+
564
+ ### Content Widths
565
+ - Max content width: **1200px**
566
+ - Form max width: **640px**
567
+ - Table container: full width with horizontal scroll
568
+
569
+ ### White Space Rules
570
+ - Sections separated by **48-64px** vertical space
571
+ - Card internal padding: **32px** minimum
572
+ - Between form fields: **24px**
573
+ - Page title to first content: **32px**
574
+
575
+ ---
576
+
577
+ ## 6. Interaction & Motion
578
+
579
+ ### Transitions
580
+ - **Duration:** 150ms (fast, decisive — no lingering)
581
+ - **Easing:** `ease` for color, `ease-out` for transforms
582
+ - **What animates:** Background color, border color, opacity, transform
583
+ - **What does NOT animate:** Border-radius (it never changes), box-shadow (it's architectural)
584
+
585
+ ### Hover States
586
+ | Element | Hover Effect |
587
+ |---------|-------------|
588
+ | Primary button | Background darkens one shade |
589
+ | Secondary button | Fills with black, text inverts to white |
590
+ | Card | Subtle background shift to `#F5F5F0` |
591
+ | Table row | Background shifts to `#F5F5F0` |
592
+ | Sidebar item | Text brightens to white, faint bg overlay |
593
+ | Badge | No hover change (badges are status, not actions) |
594
+ | Link | Underline appears (no color change) |
595
+
596
+ ### Focus States
597
+ ```css
598
+ /* Focus ring — blue, sharp, offset */
599
+ *:focus-visible {
600
+ outline: 3px solid #003DA5;
601
+ outline-offset: 2px;
602
+ }
603
+ ```
604
+
605
+ ---
606
+
607
+ ## 7. Iconography
608
+
609
+ - **Style:** Line icons, 2px stroke, geometric/minimal
610
+ - **Recommended set:** Lucide Icons (already used by NuxtUI) or Phosphor Icons
611
+ - **Size:** 20px standard, 24px in navigation, 16px inline
612
+ - **Color:** Inherits text color (`currentColor`)
613
+ - **Rule:** Icons are never decorative — every icon must have a functional purpose
614
+
615
+ ---
616
+
617
+ ## 8. Signature Patterns
618
+
619
+ ### The Mondrian Grid Dashboard
620
+ Stat cards arranged in a CSS Grid with varying spans, creating an asymmetric Mondrian-like composition:
621
+ ```css
622
+ .dashboard-grid {
623
+ display: grid;
624
+ grid-template-columns: repeat(4, 1fr);
625
+ grid-template-rows: auto;
626
+ gap: 24px;
627
+ }
628
+ /* Hero stat takes 2 columns */
629
+ .stat-hero { grid-column: span 2; grid-row: span 2; }
630
+ /* Accent block — pure color, no content */
631
+ .grid-accent-block {
632
+ background: #F5B700;
633
+ grid-column: span 1;
634
+ min-height: 120px;
635
+ }
636
+ ```
637
+
638
+ ### The Bauhaus Header
639
+ Page header with oversized title, thin uppercase subtitle, and a bold colored divider:
640
+ ```html
641
+ <div class="mb-12">
642
+ <p class="text-xs font-medium uppercase tracking-wider text-graphite mb-2">Administration</p>
643
+ <h1 class="font-syne font-extrabold text-5xl tracking-tight text-ink">Users</h1>
644
+ <div class="h-1 w-16 bg-bauhaus-blue mt-4"></div>
645
+ </div>
646
+ ```
647
+
648
+ ### The Geometric Empty State
649
+ A large circle (yellow) with a sharp-edged message box:
650
+ ```html
651
+ <div class="flex flex-col items-center py-20">
652
+ <div class="w-32 h-32 rounded-full bg-bauhaus-yellow flex items-center justify-center mb-8">
653
+ <Icon name="lucide:inbox" class="w-12 h-12 text-ink" />
654
+ </div>
655
+ <h3 class="font-syne font-bold text-2xl text-ink mb-2">No results</h3>
656
+ <p class="text-graphite text-base">Try adjusting your search or filters.</p>
657
+ </div>
658
+ ```
659
+
660
+ ### The Hard Shadow Card (for emphasis)
661
+ A card with a hard offset shadow, evoking neobrutalist Bauhaus energy:
662
+ ```css
663
+ .card-elevated {
664
+ border-radius: 0;
665
+ border: 2px solid #0A0A0A;
666
+ background: #FFFFFF;
667
+ padding: 32px;
668
+ box-shadow: 6px 6px 0 #0A0A0A;
669
+ }
670
+ ```
671
+
672
+ ---
673
+
674
+ ## 9. Design Inspirations
675
+
676
+ | Reference | What to borrow |
677
+ |-----------|---------------|
678
+ | **Piet Mondrian** — Composition with Red, Blue and Yellow | Grid layout with asymmetric colored blocks, thick black dividers |
679
+ | **Kazimir Malevich** — Suprematist compositions | Bold geometric shapes floating in white space, circle + square tension |
680
+ | **Bauhaus school** (Gropius, Moholy-Nagy, Albers) | Primary color palette, geometric typography, form = function |
681
+ | **Dieter Rams / Braun** | Oversized controls, generous white space, deliberate minimalism |
682
+ | **Figma "Neu Bauhaus" design system** | Fibonacci-based grid, parametric circle-and-line compositions |
683
+ | **Linear.app** | Sharp corners on cards, clean monochrome with rare color accents |
684
+ | **Vercel Dashboard** | Bold typography hierarchy, generous white space, dark/light contrast |
685
+ | **Neobrutalism trend** | Hard offset shadows, thick borders, unapologetic boldness |
686
+
687
+ ---
688
+
689
+ ## 10. Implementation Notes for NuxtUI 4.x
690
+
691
+ ### NuxtUI Component Overrides via `app.config.ts`
692
+
693
+ ```typescript
694
+ export default defineAppConfig({
695
+ ui: {
696
+ // Global: kill all default border-radius
697
+ button: {
698
+ slots: {
699
+ base: 'rounded-none' // Override per-variant below
700
+ },
701
+ variants: {
702
+ variant: {
703
+ solid: 'rounded-full', // Primary pills
704
+ outline: 'rounded-none', // Secondary sharp
705
+ ghost: 'rounded-none',
706
+ soft: 'rounded-full'
707
+ }
708
+ }
709
+ },
710
+ card: {
711
+ slots: {
712
+ root: 'rounded-none border border-silver-line'
713
+ }
714
+ },
715
+ input: {
716
+ slots: {
717
+ root: 'rounded-none',
718
+ base: 'rounded-none min-h-14 border-2'
719
+ }
720
+ },
721
+ badge: {
722
+ slots: {
723
+ base: 'rounded-full uppercase tracking-wider'
724
+ }
725
+ },
726
+ modal: {
727
+ slots: {
728
+ content: 'rounded-none border-2 border-ink shadow-[6px_6px_0_#0A0A0A]'
729
+ }
730
+ },
731
+ avatar: {
732
+ slots: {
733
+ root: 'rounded-full border-2 border-ink'
734
+ }
735
+ },
736
+ table: {
737
+ slots: {
738
+ root: 'rounded-none border-2 border-ink'
739
+ }
740
+ }
741
+ }
742
+ })
743
+ ```
744
+
745
+ ### Tailwind v4 CSS Setup (`main.css`)
746
+
747
+ ```css
748
+ @import "tailwindcss";
749
+ @import "@nuxt/ui";
750
+
751
+ @theme {
752
+ --font-syne: 'Syne', sans-serif;
753
+ --font-body: 'Plus Jakarta Sans', sans-serif;
754
+ --font-mono: 'Space Mono', monospace;
755
+
756
+ --color-bauhaus-red: #D62828;
757
+ --color-bauhaus-blue: #003DA5;
758
+ --color-bauhaus-yellow: #F5B700;
759
+ --color-ink: #0A0A0A;
760
+ --color-canvas: #FFFFFF;
761
+ --color-concrete: #F5F5F0;
762
+ --color-graphite: #404040;
763
+ --color-silver-line: #E0E0E0;
764
+ }
765
+ ```
766
+
767
+ ---
768
+
769
+ ## Summary: The Geometric Minimal Manifesto
770
+
771
+ 1. **Two shapes only:** Circle/pill (9999px) or sharp rectangle (0px). Nothing else.
772
+ 2. **Three colors + black + white:** Bauhaus Red, Blue, Yellow. Color = meaning, never decoration.
773
+ 3. **Oversized everything:** 56px button height, 48px page titles, 72px hero numbers, 32px card padding.
774
+ 4. **Syne for drama, Plus Jakarta Sans for clarity.** The heading font gets wider as it gets bolder.
775
+ 5. **White space is a material.** 80% of the canvas should breathe.
776
+ 6. **Every element is deliberate.** If it doesn't communicate, it doesn't exist.
777
+ 7. **Hard shadows, thick borders, bold dividers.** Structure is visible, not hidden.
778
+ 8. **The grid is the art.** Dashboard layouts are Mondrian compositions.