@famgia/omnify-laravel 0.0.119 → 0.0.120
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-7I6UNXOD.js → chunk-NMX3TLZT.js} +8 -1
- package/dist/{chunk-7I6UNXOD.js.map → chunk-NMX3TLZT.js.map} +1 -1
- package/dist/index.cjs +7 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/plugin.cjs +7 -0
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.js +1 -1
- package/package.json +4 -4
- package/stubs/ai-guides/claude-checklists/react.md.stub +108 -0
- package/stubs/ai-guides/cursor/omnify-schema.mdc.stub +339 -0
- package/stubs/ai-guides/cursor/react-design.mdc.stub +693 -0
- package/stubs/ai-guides/cursor/react-form.mdc.stub +277 -0
- package/stubs/ai-guides/cursor/react-services.mdc.stub +304 -0
- package/stubs/ai-guides/cursor/react.mdc.stub +336 -0
- package/stubs/ai-guides/cursor/schema-create.mdc.stub +344 -0
- package/stubs/ai-guides/react/README.md.stub +221 -0
- package/stubs/ai-guides/react/antd-guide.md.stub +457 -0
- package/stubs/ai-guides/react/checklist.md.stub +108 -0
- package/stubs/ai-guides/react/datetime-guide.md.stub +137 -0
- package/stubs/ai-guides/react/design-philosophy.md.stub +363 -0
- package/stubs/ai-guides/react/i18n-guide.md.stub +211 -0
- package/stubs/ai-guides/react/laravel-integration.md.stub +181 -0
- package/stubs/ai-guides/react/service-pattern.md.stub +180 -0
- package/stubs/ai-guides/react/tanstack-query.md.stub +339 -0
- package/stubs/ai-guides/react/types-guide.md.stub +671 -0
|
@@ -0,0 +1,693 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Japanese Business UI Design System: 4px spacing grid, Ant Design theme tokens (NO custom colors!), 間(Ma) whitespace philosophy. Apply when designing layouts, choosing colors, or setting spacing."
|
|
3
|
+
globs: ["{{TYPESCRIPT_BASE}}/**/*.tsx", "{{TYPESCRIPT_BASE}}/**/*.css"]
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# React Design System
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
This design system follows **Japanese Business UI principles**: compact, functional, and minimal.
|
|
12
|
+
Primary color: Violet (#7C3AED).
|
|
13
|
+
|
|
14
|
+
> ⚠️ **CRITICAL RULES:**
|
|
15
|
+
> 1. **ALL colors MUST come from Ant Design theme tokens** - Never hardcode colors!
|
|
16
|
+
> 2. **Minimize inline styles** - Use Ant Design components and `styles` prop with tokens
|
|
17
|
+
> 3. **Use 4px grid system** - All spacing must be multiples of 4px
|
|
18
|
+
|
|
19
|
+
## Design Principles
|
|
20
|
+
|
|
21
|
+
### 日本のビジネスUI (Japanese Business UI)
|
|
22
|
+
|
|
23
|
+
1. **コンパクト (Compact)** - High information density, minimal wasted space
|
|
24
|
+
2. **機能的 (Functional)** - Prioritize usability and efficiency
|
|
25
|
+
3. **シンプル (Simple)** - Minimize visual noise, flat design
|
|
26
|
+
4. **高密度 (High Density)** - More information visible on screen
|
|
27
|
+
|
|
28
|
+
## Color System
|
|
29
|
+
|
|
30
|
+
### HSL-Based Color Harmony
|
|
31
|
+
|
|
32
|
+
All colors follow HSL color theory with consistent saturation (~84%) for harmony.
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
Primary Hue: 258° (Violet)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Brand Colors
|
|
39
|
+
|
|
40
|
+
| Role | Hex | HSL | Usage |
|
|
41
|
+
| ----------------- | --------- | -------------- | -------------------------------- |
|
|
42
|
+
| **Primary** | `#7C3AED` | 258°, 84%, 58% | Buttons, links, sidebar, accents |
|
|
43
|
+
| **Primary Light** | `#9061F9` | 258°, 84%, 68% | Hover states, selected items |
|
|
44
|
+
| **Primary Dark** | `#6D28D9` | 258°, 84%, 50% | Active states, sub-menus |
|
|
45
|
+
|
|
46
|
+
### Semantic Colors (Complementary Harmony)
|
|
47
|
+
|
|
48
|
+
| Role | Hex | HSL | Usage |
|
|
49
|
+
| ----------- | --------- | -------------- | ---------------------------------- |
|
|
50
|
+
| **Success** | `#10B981` | 160°, 84%, 39% | Success messages, positive actions |
|
|
51
|
+
| **Warning** | `#F59E0B` | 38°, 92%, 50% | Warnings, caution states |
|
|
52
|
+
| **Error** | `#EF4444` | 0°, 84%, 60% | Errors, destructive actions |
|
|
53
|
+
|
|
54
|
+
### Neutral Colors (Violet Undertone)
|
|
55
|
+
|
|
56
|
+
| Role | Hex | Usage |
|
|
57
|
+
| ------------------------ | --------- | ----------------------------- |
|
|
58
|
+
| **Text Primary** | `#1E1B2E` | Main text, headings |
|
|
59
|
+
| **Text Secondary** | `#4B5563` | Secondary text, labels |
|
|
60
|
+
| **Text Tertiary** | `#9CA3AF` | Placeholder, disabled text |
|
|
61
|
+
| **Background Layout** | `#F8F7FA` | Page background (violet-gray) |
|
|
62
|
+
| **Background Container** | `#FFFFFF` | Cards, containers |
|
|
63
|
+
| **Border** | `#E5E7EB` | Borders, dividers |
|
|
64
|
+
| **Border Secondary** | `#F3F4F6` | Subtle borders |
|
|
65
|
+
|
|
66
|
+
### Color Usage Rules
|
|
67
|
+
|
|
68
|
+
1. **60-30-10 Rule**: 60% neutral, 30% primary, 10% accent
|
|
69
|
+
2. **Same Saturation Family**: Keep semantic colors at ~84% saturation
|
|
70
|
+
3. **Cool Tone Neutrals**: Grays should have slight violet undertone
|
|
71
|
+
4. **WCAG AA Compliance**: Maintain contrast ratio ≥ 4.5:1 for text
|
|
72
|
+
|
|
73
|
+
## Typography
|
|
74
|
+
|
|
75
|
+
### Locale-Specific Font Stacks
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
const fontFamilies = {
|
|
79
|
+
// Japanese - CJK optimized
|
|
80
|
+
ja: "'Noto Sans JP', 'Hiragino Sans', 'Hiragino Kaku Gothic ProN', Meiryo, sans-serif",
|
|
81
|
+
|
|
82
|
+
// English - Modern western
|
|
83
|
+
en: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
|
|
84
|
+
|
|
85
|
+
// Vietnamese - Light, clean font with diacritics support
|
|
86
|
+
vi: "'Inter', 'Nunito Sans', -apple-system, BlinkMacSystemFont, sans-serif",
|
|
87
|
+
};
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Font Sizes (Compact)
|
|
91
|
+
|
|
92
|
+
| Token | Size | Usage |
|
|
93
|
+
| ------------------ | ---- | -------------- |
|
|
94
|
+
| `fontSize` | 13px | Base text |
|
|
95
|
+
| `fontSizeLG` | 14px | Large text |
|
|
96
|
+
| `fontSizeHeading1` | 24px | Page titles |
|
|
97
|
+
| `fontSizeHeading2` | 20px | Section titles |
|
|
98
|
+
| `fontSizeHeading3` | 16px | Card titles |
|
|
99
|
+
| `fontSizeHeading4` | 14px | Sub-headings |
|
|
100
|
+
| `fontSizeHeading5` | 13px | Small headings |
|
|
101
|
+
|
|
102
|
+
### Line Height
|
|
103
|
+
|
|
104
|
+
- Default: `1.5` (compact, suitable for Japanese text)
|
|
105
|
+
|
|
106
|
+
## Spacing System
|
|
107
|
+
|
|
108
|
+
### 間 (Ma) - Japanese Whitespace Philosophy
|
|
109
|
+
|
|
110
|
+
Japanese design embraces **間 (Ma)** - the concept of meaningful negative space. Unlike Western design that fills every gap, Japanese design uses whitespace purposefully:
|
|
111
|
+
|
|
112
|
+
1. **機能的余白 (Functional Whitespace)** - Empty space that guides the eye
|
|
113
|
+
2. **呼吸 (Breathing Room)** - Allowing elements to "breathe"
|
|
114
|
+
3. **密度バランス (Density Balance)** - High info density WITH visual rest
|
|
115
|
+
|
|
116
|
+
> **Key Insight**: Japanese business UIs are compact but NOT cramped. Every margin has purpose.
|
|
117
|
+
|
|
118
|
+
### 4px Base Grid System
|
|
119
|
+
|
|
120
|
+
All spacing values are multiples of **4px** for consistency and alignment:
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
Base Unit: 4px
|
|
124
|
+
Scale: 4, 8, 12, 16, 24, 32, 48, 64, 96
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Spacing Scale
|
|
128
|
+
|
|
129
|
+
| Token | Value | px | Usage |
|
|
130
|
+
| ----------- | ----- | ---- | ---------------------------------- |
|
|
131
|
+
| `space-1` | 0.25 | 4px | Micro spacing (icon-text gap) |
|
|
132
|
+
| `space-2` | 0.5 | 8px | Tight spacing (related items) |
|
|
133
|
+
| `space-3` | 0.75 | 12px | Default internal spacing |
|
|
134
|
+
| `space-4` | 1 | 16px | Component spacing |
|
|
135
|
+
| `space-6` | 1.5 | 24px | Section spacing |
|
|
136
|
+
| `space-8` | 2 | 32px | Large section gaps |
|
|
137
|
+
| `space-12` | 3 | 48px | Page section dividers |
|
|
138
|
+
| `space-16` | 4 | 64px | Major layout sections |
|
|
139
|
+
|
|
140
|
+
### Ant Design Token Mapping
|
|
141
|
+
|
|
142
|
+
| Token | Value | Usage |
|
|
143
|
+
| --------------- | ----- | ------------------------ |
|
|
144
|
+
| `paddingXXS` | 4px | Micro padding |
|
|
145
|
+
| `paddingXS` | 8px | Tight padding |
|
|
146
|
+
| `paddingSM` | 12px | Small padding |
|
|
147
|
+
| `padding` | 16px | Default padding |
|
|
148
|
+
| `paddingMD` | 20px | Medium padding |
|
|
149
|
+
| `paddingLG` | 24px | Large padding |
|
|
150
|
+
| `paddingXL` | 32px | Extra large padding |
|
|
151
|
+
| `marginXXS` | 4px | Micro margin |
|
|
152
|
+
| `marginXS` | 8px | Tight margin |
|
|
153
|
+
| `marginSM` | 12px | Small margin |
|
|
154
|
+
| `margin` | 16px | Default margin |
|
|
155
|
+
| `marginMD` | 20px | Medium margin |
|
|
156
|
+
| `marginLG` | 24px | Large margin |
|
|
157
|
+
| `marginXL` | 32px | Extra large margin |
|
|
158
|
+
|
|
159
|
+
### Layout Spacing Guidelines
|
|
160
|
+
|
|
161
|
+
#### Content Areas
|
|
162
|
+
|
|
163
|
+
| Element | Padding | Margin |
|
|
164
|
+
| -------------------- | ------------- | -------------- |
|
|
165
|
+
| Page content | 24px | - |
|
|
166
|
+
| Card content | 16px | 0 0 16px |
|
|
167
|
+
| Modal content | 24px | - |
|
|
168
|
+
| Sidebar content | 12px | - |
|
|
169
|
+
| Table cell | 8px 12px | - |
|
|
170
|
+
| Form item | - | 0 0 16px |
|
|
171
|
+
| Button | 4px 12px | - |
|
|
172
|
+
| Input | 4px 8px | - |
|
|
173
|
+
|
|
174
|
+
#### Vertical Rhythm (Japanese Business UI)
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
Header height: 48px (compact)
|
|
178
|
+
Breadcrumb: 36px
|
|
179
|
+
Page title area: 48px
|
|
180
|
+
Card title: 40px
|
|
181
|
+
Table header: 40px
|
|
182
|
+
Table row: 44px (compact)
|
|
183
|
+
Form row: 40px
|
|
184
|
+
Footer: 48px
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Component Internal Spacing
|
|
188
|
+
|
|
189
|
+
#### Cards
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
// Japanese business style - compact but clear
|
|
193
|
+
Card: {
|
|
194
|
+
paddingLG: 16, // ✅ NOT 24px (too spacious)
|
|
195
|
+
headerHeight: 40,
|
|
196
|
+
actionsBorderTop: true,
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
#### Forms
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
// Dense but organized
|
|
204
|
+
Form: {
|
|
205
|
+
itemMarginBottom: 16, // Row spacing
|
|
206
|
+
verticalLabelPadding: "0 0 4px", // Label-input gap
|
|
207
|
+
labelHeight: 24,
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
#### Tables
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
// High-density data display
|
|
215
|
+
Table: {
|
|
216
|
+
cellPaddingBlock: 8, // Vertical
|
|
217
|
+
cellPaddingInline: 12, // Horizontal
|
|
218
|
+
headerBg: "#F8F7FA",
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Spacing Patterns
|
|
223
|
+
|
|
224
|
+
#### 親子関係 (Parent-Child Relationship)
|
|
225
|
+
|
|
226
|
+
```css
|
|
227
|
+
/* Parent containers have larger padding than children */
|
|
228
|
+
.page-container { padding: 24px; } /* Outer */
|
|
229
|
+
.section { padding: 16px; margin-bottom: 24px; } /* Middle */
|
|
230
|
+
.card { padding: 16px; margin-bottom: 16px; } /* Inner */
|
|
231
|
+
.card-item { padding: 8px; } /* Deepest */
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
#### 近接の法則 (Law of Proximity)
|
|
235
|
+
|
|
236
|
+
Related items should be closer together than unrelated items:
|
|
237
|
+
|
|
238
|
+
```css
|
|
239
|
+
/* ✅ GOOD: Related items grouped */
|
|
240
|
+
.form-group { margin-bottom: 24px; } /* Group separation */
|
|
241
|
+
.form-item { margin-bottom: 12px; } /* Item separation within group */
|
|
242
|
+
|
|
243
|
+
/* ❌ BAD: Equal spacing loses relationship */
|
|
244
|
+
.form-item { margin-bottom: 16px; } /* Everything looks the same */
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
#### 段落間隔 (Section Spacing)
|
|
248
|
+
|
|
249
|
+
```css
|
|
250
|
+
/* Page sections */
|
|
251
|
+
.section + .section { margin-top: 32px; }
|
|
252
|
+
|
|
253
|
+
/* Card sections */
|
|
254
|
+
.card + .card { margin-top: 16px; }
|
|
255
|
+
|
|
256
|
+
/* Within card sections */
|
|
257
|
+
.card-section + .card-section { margin-top: 16px; }
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Gap Utilities (CSS/Tailwind)
|
|
261
|
+
|
|
262
|
+
Use `gap` instead of margins for flex/grid layouts:
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
// ✅ GOOD: Use gap
|
|
266
|
+
<Space size={8}> {/* or "small" */}
|
|
267
|
+
<Flex gap={12}>
|
|
268
|
+
<div style={{ display: 'flex', gap: '16px' }}>
|
|
269
|
+
|
|
270
|
+
// ❌ BAD: Margin on children
|
|
271
|
+
<div style={{ marginRight: 16 }}>
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
| Ant Design Space | Value | Usage |
|
|
275
|
+
| ---------------- | ----- | ------------------- |
|
|
276
|
+
| `small` | 8px | Tight grouping |
|
|
277
|
+
| `middle` | 16px | Default grouping |
|
|
278
|
+
| `large` | 24px | Loose grouping |
|
|
279
|
+
|
|
280
|
+
### Responsive Spacing
|
|
281
|
+
|
|
282
|
+
Japanese design maintains density across breakpoints:
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
const responsiveSpacing = {
|
|
286
|
+
// Mobile-first, then scale up slightly
|
|
287
|
+
mobile: {
|
|
288
|
+
pagePadding: 16,
|
|
289
|
+
cardPadding: 12,
|
|
290
|
+
gap: 12,
|
|
291
|
+
},
|
|
292
|
+
tablet: {
|
|
293
|
+
pagePadding: 20,
|
|
294
|
+
cardPadding: 16,
|
|
295
|
+
gap: 16,
|
|
296
|
+
},
|
|
297
|
+
desktop: {
|
|
298
|
+
pagePadding: 24,
|
|
299
|
+
cardPadding: 16,
|
|
300
|
+
gap: 16,
|
|
301
|
+
},
|
|
302
|
+
};
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
> **Note**: Japanese business UIs don't dramatically increase spacing on larger screens. Maintain density.
|
|
306
|
+
|
|
307
|
+
### Layout Structure
|
|
308
|
+
|
|
309
|
+
- Content margin: `24px` (page level)
|
|
310
|
+
- Content padding: `16px` (component level)
|
|
311
|
+
- Header height: `48px`
|
|
312
|
+
- Sidebar width: `200px`
|
|
313
|
+
- Gutter (column gap): `16px`
|
|
314
|
+
|
|
315
|
+
## Border Radius
|
|
316
|
+
|
|
317
|
+
### Subtle, Professional Corners
|
|
318
|
+
|
|
319
|
+
| Token | Value | Usage |
|
|
320
|
+
| ---------------- | ----- | ------------------------ |
|
|
321
|
+
| `borderRadiusSM` | 2px | Tags, badges |
|
|
322
|
+
| `borderRadius` | 4px | Buttons, inputs, cards |
|
|
323
|
+
| `borderRadiusLG` | 6px | Modals, large containers |
|
|
324
|
+
|
|
325
|
+
> **Note**: Japanese business UIs prefer subtle corners over heavily rounded designs.
|
|
326
|
+
|
|
327
|
+
## Shadows
|
|
328
|
+
|
|
329
|
+
### Almost Flat Design
|
|
330
|
+
|
|
331
|
+
```css
|
|
332
|
+
/* Primary shadow - very subtle */
|
|
333
|
+
boxShadow: "0 1px 2px rgba(0, 0, 0, 0.03)"
|
|
334
|
+
|
|
335
|
+
/* Secondary shadow - hover states */
|
|
336
|
+
boxShadowSecondary: "0 1px 3px rgba(0, 0, 0, 0.04)"
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
> **Note**: Prefer borders over shadows for Japanese business style.
|
|
340
|
+
|
|
341
|
+
## Control Sizes
|
|
342
|
+
|
|
343
|
+
### Compact Controls
|
|
344
|
+
|
|
345
|
+
| Token | Value | Usage |
|
|
346
|
+
| ----------------- | ----- | --------------------- |
|
|
347
|
+
| `controlHeightSM` | 28px | Small buttons, inputs |
|
|
348
|
+
| `controlHeight` | 32px | Default controls |
|
|
349
|
+
| `controlHeightLG` | 36px | Large controls |
|
|
350
|
+
|
|
351
|
+
## Component Guidelines
|
|
352
|
+
|
|
353
|
+
### Buttons
|
|
354
|
+
|
|
355
|
+
```typescript
|
|
356
|
+
Button: {
|
|
357
|
+
controlHeight: 32,
|
|
358
|
+
paddingInline: 12,
|
|
359
|
+
fontWeight: 500,
|
|
360
|
+
}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
### Inputs
|
|
364
|
+
|
|
365
|
+
```typescript
|
|
366
|
+
Input: {
|
|
367
|
+
controlHeight: 32,
|
|
368
|
+
paddingInline: 8,
|
|
369
|
+
}
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### Tables
|
|
373
|
+
|
|
374
|
+
```typescript
|
|
375
|
+
Table: {
|
|
376
|
+
cellPaddingBlock: 8,
|
|
377
|
+
cellPaddingInline: 8,
|
|
378
|
+
headerBg: "#F8F7FA",
|
|
379
|
+
}
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
### Forms
|
|
383
|
+
|
|
384
|
+
```typescript
|
|
385
|
+
Form: {
|
|
386
|
+
itemMarginBottom: 16,
|
|
387
|
+
verticalLabelPadding: "0 0 4px",
|
|
388
|
+
}
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### Menu (Dark Theme for Sidebar)
|
|
392
|
+
|
|
393
|
+
```typescript
|
|
394
|
+
Menu: {
|
|
395
|
+
itemHeight: 36,
|
|
396
|
+
itemMarginBlock: 2,
|
|
397
|
+
itemMarginInline: 4,
|
|
398
|
+
darkItemBg: "#7C3AED",
|
|
399
|
+
darkSubMenuItemBg: "#6D28D9",
|
|
400
|
+
darkItemSelectedBg: "#9061F9",
|
|
401
|
+
darkItemSelectedColor: "#FFFFFF",
|
|
402
|
+
darkItemColor: "rgba(255, 255, 255, 0.9)",
|
|
403
|
+
darkItemHoverBg: "rgba(144, 97, 249, 0.6)",
|
|
404
|
+
darkItemHoverColor: "#FFFFFF",
|
|
405
|
+
}
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
### Layout
|
|
409
|
+
|
|
410
|
+
```typescript
|
|
411
|
+
Layout: {
|
|
412
|
+
siderBg: "#7C3AED",
|
|
413
|
+
headerPadding: "0 16px",
|
|
414
|
+
headerHeight: 48,
|
|
415
|
+
}
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
## Implementation
|
|
419
|
+
|
|
420
|
+
### Ant Design Theme Configuration
|
|
421
|
+
|
|
422
|
+
All design tokens are configured in:
|
|
423
|
+
```
|
|
424
|
+
frontend/src/components/AntdThemeProvider.tsx
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
### Google Fonts Loading
|
|
428
|
+
|
|
429
|
+
Fonts are loaded in:
|
|
430
|
+
```
|
|
431
|
+
frontend/src/app/layout.tsx
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
Required fonts:
|
|
435
|
+
- Noto Sans JP (Japanese)
|
|
436
|
+
- Inter (English)
|
|
437
|
+
- Be Vietnam Pro (Vietnamese)
|
|
438
|
+
|
|
439
|
+
## 🚫 CRITICAL: Forbidden Practices
|
|
440
|
+
|
|
441
|
+
### ❌ ABSOLUTELY FORBIDDEN: Custom Colors
|
|
442
|
+
|
|
443
|
+
**NEVER add colors that are not from the Ant Design theme system.**
|
|
444
|
+
|
|
445
|
+
```tsx
|
|
446
|
+
// ❌ FORBIDDEN: Hardcoded colors
|
|
447
|
+
<div style={{ color: '#333333' }}>
|
|
448
|
+
<div style={{ backgroundColor: 'blue' }}>
|
|
449
|
+
<div style={{ borderColor: 'rgb(200, 200, 200)' }}>
|
|
450
|
+
<Text style={{ color: '#ff6b6b' }}>Error</Text>
|
|
451
|
+
|
|
452
|
+
// ❌ FORBIDDEN: Tailwind color classes
|
|
453
|
+
<div className="text-gray-500 bg-blue-100">
|
|
454
|
+
<div className="border-red-500">
|
|
455
|
+
|
|
456
|
+
// ✅ CORRECT: Use Ant Design theme tokens
|
|
457
|
+
import { theme } from 'antd';
|
|
458
|
+
const { token } = theme.useToken();
|
|
459
|
+
|
|
460
|
+
<div style={{ color: token.colorText }}>
|
|
461
|
+
<div style={{ backgroundColor: token.colorBgContainer }}>
|
|
462
|
+
<div style={{ borderColor: token.colorBorder }}>
|
|
463
|
+
<Text type="danger">Error</Text> // Use Ant Design's built-in types
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
**Available Ant Design Color Tokens:**
|
|
467
|
+
|
|
468
|
+
| Token | Usage |
|
|
469
|
+
|-------|-------|
|
|
470
|
+
| `token.colorPrimary` | Primary brand color |
|
|
471
|
+
| `token.colorSuccess` | Success states |
|
|
472
|
+
| `token.colorWarning` | Warning states |
|
|
473
|
+
| `token.colorError` | Error states |
|
|
474
|
+
| `token.colorText` | Primary text |
|
|
475
|
+
| `token.colorTextSecondary` | Secondary text |
|
|
476
|
+
| `token.colorTextTertiary` | Tertiary/disabled text |
|
|
477
|
+
| `token.colorBgContainer` | Container background |
|
|
478
|
+
| `token.colorBgLayout` | Layout background |
|
|
479
|
+
| `token.colorBorder` | Borders |
|
|
480
|
+
| `token.colorBorderSecondary` | Subtle borders |
|
|
481
|
+
|
|
482
|
+
### ❌ FORBIDDEN: Excessive Inline Styles
|
|
483
|
+
|
|
484
|
+
**Minimize `style` prop usage. Prefer Ant Design's component API.**
|
|
485
|
+
|
|
486
|
+
```tsx
|
|
487
|
+
// ❌ BAD: Inline styles everywhere
|
|
488
|
+
<Card style={{ padding: 24, margin: 16, borderRadius: 8 }}>
|
|
489
|
+
<div style={{ display: 'flex', gap: 16, alignItems: 'center' }}>
|
|
490
|
+
<span style={{ fontSize: 14, fontWeight: 500 }}>Title</span>
|
|
491
|
+
</div>
|
|
492
|
+
</Card>
|
|
493
|
+
|
|
494
|
+
// ✅ GOOD: Use Ant Design component props
|
|
495
|
+
<Card
|
|
496
|
+
styles={{ body: { padding: token.paddingLG } }}
|
|
497
|
+
style={{ marginBottom: token.marginLG }} // Only when necessary
|
|
498
|
+
>
|
|
499
|
+
<Flex gap="middle" align="center">
|
|
500
|
+
<Typography.Text strong>Title</Typography.Text>
|
|
501
|
+
</Flex>
|
|
502
|
+
</Card>
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
**When to use inline styles:**
|
|
506
|
+
|
|
507
|
+
| Situation | Allowed? | Alternative |
|
|
508
|
+
|-----------|----------|-------------|
|
|
509
|
+
| Component layout (flex, grid) | ⚠️ Limited | Use `<Flex>`, `<Space>`, `<Row>`/`<Col>` |
|
|
510
|
+
| Colors | ❌ NO | Use theme tokens or component types |
|
|
511
|
+
| Typography | ❌ NO | Use `<Typography.Text>`, `<Typography.Title>` |
|
|
512
|
+
| Spacing | ⚠️ Limited | Use Ant Design `styles` prop with tokens |
|
|
513
|
+
| Responsive | ❌ NO | Use Ant Design Grid or CSS modules |
|
|
514
|
+
|
|
515
|
+
**Allowed inline style patterns:**
|
|
516
|
+
|
|
517
|
+
```tsx
|
|
518
|
+
// ✅ Allowed: Token-based values only
|
|
519
|
+
<div style={{ marginBottom: token.marginLG }}>
|
|
520
|
+
<div style={{ padding: token.paddingMD }}>
|
|
521
|
+
|
|
522
|
+
// ✅ Allowed: Layout properties
|
|
523
|
+
<div style={{ flex: 1 }}>
|
|
524
|
+
<div style={{ width: '100%', maxWidth: 800 }}>
|
|
525
|
+
|
|
526
|
+
// ✅ Allowed: Component-specific overrides via styles prop
|
|
527
|
+
<Table styles={{ header: { background: token.colorBgLayout } }} />
|
|
528
|
+
<Card styles={{ body: { padding: 0 } }} />
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
### ❌ FORBIDDEN: CSS-in-JS Libraries for Styling
|
|
532
|
+
|
|
533
|
+
```tsx
|
|
534
|
+
// ❌ FORBIDDEN: Don't use styled-components, emotion, etc. for colors/spacing
|
|
535
|
+
const StyledCard = styled.div`
|
|
536
|
+
background: #f5f5f5; // NO!
|
|
537
|
+
padding: 20px; // NO!
|
|
538
|
+
`;
|
|
539
|
+
|
|
540
|
+
// ✅ CORRECT: Use Ant Design components + theme
|
|
541
|
+
<Card styles={{ body: { padding: token.paddingLG } }}>
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
## 🚨 Common Spacing Mistakes
|
|
545
|
+
|
|
546
|
+
### ❌ Mistake 1: Inconsistent Base Unit
|
|
547
|
+
|
|
548
|
+
```css
|
|
549
|
+
/* ❌ BAD: Random values */
|
|
550
|
+
padding: 13px;
|
|
551
|
+
margin: 7px;
|
|
552
|
+
gap: 15px;
|
|
553
|
+
|
|
554
|
+
/* ✅ GOOD: 4px multiples */
|
|
555
|
+
padding: 12px; /* 4 × 3 */
|
|
556
|
+
margin: 8px; /* 4 × 2 */
|
|
557
|
+
gap: 16px; /* 4 × 4 */
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
### ❌ Mistake 2: Too Much Whitespace
|
|
561
|
+
|
|
562
|
+
```css
|
|
563
|
+
/* ❌ BAD: Western "airy" design */
|
|
564
|
+
.card { padding: 32px; }
|
|
565
|
+
.section { margin-bottom: 48px; }
|
|
566
|
+
|
|
567
|
+
/* ✅ GOOD: Japanese compact design */
|
|
568
|
+
.card { padding: 16px; }
|
|
569
|
+
.section { margin-bottom: 24px; }
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
### ❌ Mistake 3: Using Margin Instead of Gap
|
|
573
|
+
|
|
574
|
+
```tsx
|
|
575
|
+
// ❌ BAD: Margin on each child (last-child issues)
|
|
576
|
+
{items.map(item => <Item style={{ marginRight: 16 }} />)}
|
|
577
|
+
|
|
578
|
+
// ✅ GOOD: Gap on parent
|
|
579
|
+
<Flex gap={16}>
|
|
580
|
+
{items.map(item => <Item />)}
|
|
581
|
+
</Flex>
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
### ❌ Mistake 4: Ignoring Visual Hierarchy
|
|
585
|
+
|
|
586
|
+
```css
|
|
587
|
+
/* ❌ BAD: Same spacing everywhere */
|
|
588
|
+
.page { padding: 16px; }
|
|
589
|
+
.card { padding: 16px; }
|
|
590
|
+
.item { padding: 16px; }
|
|
591
|
+
|
|
592
|
+
/* ✅ GOOD: Decreasing spacing as you nest deeper */
|
|
593
|
+
.page { padding: 24px; }
|
|
594
|
+
.card { padding: 16px; }
|
|
595
|
+
.item { padding: 8px; }
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
### ❌ Mistake 5: Fixed Padding Everywhere
|
|
599
|
+
|
|
600
|
+
```typescript
|
|
601
|
+
// ❌ BAD: Hardcoding
|
|
602
|
+
<Card style={{ padding: 24 }}>
|
|
603
|
+
|
|
604
|
+
// ✅ GOOD: Use design tokens
|
|
605
|
+
<Card styles={{ body: { padding: token.paddingLG } }}>
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
## Do's and Don'ts
|
|
609
|
+
|
|
610
|
+
### ✅ Do
|
|
611
|
+
|
|
612
|
+
- **Colors**: Use ONLY `token.*` from `theme.useToken()`
|
|
613
|
+
- **Spacing**: Use 4px grid (4, 8, 12, 16, 24, 32...)
|
|
614
|
+
- **Layout**: Use Ant Design `<Flex>`, `<Space>`, `<Row>`/`<Col>`
|
|
615
|
+
- **Typography**: Use `<Typography.Text>`, `<Typography.Title>`
|
|
616
|
+
- **Styles**: Use component `styles` prop with tokens
|
|
617
|
+
- Use compact spacing (8-16px for components)
|
|
618
|
+
- Use `gap` for flex/grid layouts
|
|
619
|
+
- Decrease spacing as you nest deeper
|
|
620
|
+
- Maintain consistent spacing ratios
|
|
621
|
+
- Keep shadows minimal or none
|
|
622
|
+
- Use subtle border radius (2-6px)
|
|
623
|
+
- Maintain high information density
|
|
624
|
+
- Use locale-specific fonts
|
|
625
|
+
|
|
626
|
+
### ❌ Don't (FORBIDDEN)
|
|
627
|
+
|
|
628
|
+
- **NEVER** use hardcoded colors (`#333`, `blue`, `rgb()`)
|
|
629
|
+
- **NEVER** use Tailwind color classes (`text-gray-500`)
|
|
630
|
+
- **NEVER** create custom styled-components for basic styling
|
|
631
|
+
- **AVOID** excessive inline `style` props
|
|
632
|
+
- Use random pixel values (13px, 17px, etc.)
|
|
633
|
+
- Use excessive padding (>24px on components)
|
|
634
|
+
- Use margins on flex children (use gap instead)
|
|
635
|
+
- Apply same spacing at all nesting levels
|
|
636
|
+
- Hardcode spacing values in components
|
|
637
|
+
- Use heavy shadows
|
|
638
|
+
- Use large border radius (>10px)
|
|
639
|
+
- Leave large empty spaces without purpose
|
|
640
|
+
- Mix warm and cool grays
|
|
641
|
+
|
|
642
|
+
## Quick Reference
|
|
643
|
+
|
|
644
|
+
```typescript
|
|
645
|
+
// Primary colors
|
|
646
|
+
const primary = "#7C3AED";
|
|
647
|
+
const primaryLight = "#9061F9";
|
|
648
|
+
const primaryDark = "#6D28D9";
|
|
649
|
+
|
|
650
|
+
// Semantic colors
|
|
651
|
+
const success = "#10B981";
|
|
652
|
+
const warning = "#F59E0B";
|
|
653
|
+
const error = "#EF4444";
|
|
654
|
+
|
|
655
|
+
// Neutrals
|
|
656
|
+
const textPrimary = "#1E1B2E";
|
|
657
|
+
const bgLayout = "#F8F7FA";
|
|
658
|
+
const border = "#E5E7EB";
|
|
659
|
+
|
|
660
|
+
// Control sizes
|
|
661
|
+
const controlHeight = 32;
|
|
662
|
+
const borderRadius = 4;
|
|
663
|
+
|
|
664
|
+
// Spacing (4px grid) - 間 (Ma)
|
|
665
|
+
const spacing = {
|
|
666
|
+
xxs: 4, // Micro
|
|
667
|
+
xs: 8, // Tight
|
|
668
|
+
sm: 12, // Small
|
|
669
|
+
md: 16, // Default ⭐
|
|
670
|
+
lg: 24, // Large
|
|
671
|
+
xl: 32, // Extra large
|
|
672
|
+
xxl: 48, // Section divider
|
|
673
|
+
};
|
|
674
|
+
|
|
675
|
+
// Common use cases
|
|
676
|
+
const pagePadding = 24; // Page content
|
|
677
|
+
const cardPadding = 16; // Card body
|
|
678
|
+
const componentGap = 16; // Between components
|
|
679
|
+
const itemGap = 8; // Between items in list
|
|
680
|
+
const iconTextGap = 4; // Icon to text
|
|
681
|
+
```
|
|
682
|
+
|
|
683
|
+
### Spacing Cheat Sheet
|
|
684
|
+
|
|
685
|
+
```
|
|
686
|
+
Icon ↔ Text: 4px
|
|
687
|
+
Related items: 8px
|
|
688
|
+
Form items: 12px
|
|
689
|
+
Components: 16px
|
|
690
|
+
Sections: 24px
|
|
691
|
+
Page sections: 32px
|
|
692
|
+
Major areas: 48px
|
|
693
|
+
```
|