@kood/claude-code 0.3.6 → 0.3.8
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/index.js +1 -1
- package/package.json +1 -1
- package/templates/.claude/agents/code-reviewer.md +124 -124
- package/templates/.claude/agents/dependency-manager.md +85 -85
- package/templates/.claude/agents/deployment-validator.md +56 -56
- package/templates/.claude/agents/git-operator.md +64 -64
- package/templates/.claude/agents/implementation-executor.md +95 -95
- package/templates/.claude/agents/ko-to-en-translator.md +74 -0
- package/templates/.claude/agents/lint-fixer.md +78 -78
- package/templates/.claude/agents/refactor-advisor.md +122 -122
- package/templates/.claude/commands/agent-creator.md +185 -185
- package/templates/.claude/commands/bug-fix.md +193 -193
- package/templates/.claude/commands/command-creator.md +54 -54
- package/templates/.claude/commands/docs-creator.md +57 -57
- package/templates/.claude/commands/docs-refactor.md +26 -26
- package/templates/.claude/commands/execute.md +12 -12
- package/templates/.claude/commands/git-all.md +32 -32
- package/templates/.claude/commands/git-session.md +42 -42
- package/templates/.claude/commands/git.md +34 -34
- package/templates/.claude/commands/lint-fix.md +138 -138
- package/templates/.claude/commands/lint-init.md +61 -61
- package/templates/.claude/commands/plan.md +260 -260
- package/templates/.claude/commands/prd.md +24 -24
- package/templates/.claude/commands/pre-deploy.md +109 -109
- package/templates/.claude/commands/refactor.md +147 -147
- package/templates/.claude/commands/version-update.md +17 -17
- package/templates/hono/CLAUDE.md +27 -27
- package/templates/hono/docs/architecture.md +24 -24
- package/templates/hono/docs/deployment/cloudflare.md +18 -18
- package/templates/hono/docs/deployment/docker.md +13 -13
- package/templates/hono/docs/deployment/index.md +19 -19
- package/templates/hono/docs/deployment/railway.md +32 -32
- package/templates/hono/docs/deployment/vercel.md +29 -29
- package/templates/hono/docs/guides/conventions.md +57 -57
- package/templates/hono/docs/guides/env-setup.md +47 -47
- package/templates/hono/docs/guides/getting-started.md +27 -27
- package/templates/hono/docs/library/hono/error-handling.md +11 -11
- package/templates/hono/docs/library/hono/index.md +4 -4
- package/templates/hono/docs/library/hono/middleware.md +18 -18
- package/templates/hono/docs/library/hono/rpc.md +7 -7
- package/templates/hono/docs/library/hono/validation.md +6 -6
- package/templates/hono/docs/library/prisma/cloudflare-d1.md +29 -29
- package/templates/hono/docs/library/prisma/config.md +16 -16
- package/templates/hono/docs/library/prisma/index.md +32 -32
- package/templates/hono/docs/library/t3-env/index.md +22 -22
- package/templates/hono/docs/library/zod/index.md +31 -31
- package/templates/nextjs/CLAUDE.md +228 -0
- package/templates/nextjs/docs/design.md +558 -0
- package/templates/nextjs/docs/guides/conventions.md +343 -0
- package/templates/nextjs/docs/guides/getting-started.md +367 -0
- package/templates/nextjs/docs/guides/routes.md +342 -0
- package/templates/nextjs/docs/library/better-auth/index.md +541 -0
- package/templates/nextjs/docs/library/nextjs/app-router.md +269 -0
- package/templates/nextjs/docs/library/nextjs/caching.md +351 -0
- package/templates/nextjs/docs/library/nextjs/index.md +291 -0
- package/templates/nextjs/docs/library/nextjs/middleware.md +391 -0
- package/templates/nextjs/docs/library/nextjs/route-handlers.md +382 -0
- package/templates/nextjs/docs/library/nextjs/server-actions.md +366 -0
- package/templates/nextjs/docs/library/prisma/cloudflare-d1.md +76 -0
- package/templates/nextjs/docs/library/prisma/config.md +77 -0
- package/templates/nextjs/docs/library/prisma/crud.md +90 -0
- package/templates/nextjs/docs/library/prisma/index.md +73 -0
- package/templates/nextjs/docs/library/prisma/relations.md +69 -0
- package/templates/nextjs/docs/library/prisma/schema.md +98 -0
- package/templates/nextjs/docs/library/prisma/setup.md +49 -0
- package/templates/nextjs/docs/library/prisma/transactions.md +50 -0
- package/templates/nextjs/docs/library/tanstack-query/index.md +66 -0
- package/templates/nextjs/docs/library/tanstack-query/invalidation.md +54 -0
- package/templates/nextjs/docs/library/tanstack-query/optimistic-updates.md +77 -0
- package/templates/nextjs/docs/library/tanstack-query/use-mutation.md +63 -0
- package/templates/nextjs/docs/library/tanstack-query/use-query.md +70 -0
- package/templates/nextjs/docs/library/zod/complex-types.md +61 -0
- package/templates/nextjs/docs/library/zod/index.md +56 -0
- package/templates/nextjs/docs/library/zod/transforms.md +51 -0
- package/templates/nextjs/docs/library/zod/validation.md +70 -0
- package/templates/npx/CLAUDE.md +37 -37
- package/templates/npx/docs/library/commander/index.md +12 -12
- package/templates/npx/docs/library/fs-extra/index.md +9 -9
- package/templates/npx/docs/library/prompts/index.md +3 -3
- package/templates/npx/docs/references/patterns.md +12 -12
- package/templates/tanstack-start/CLAUDE.md +53 -49
- package/templates/tanstack-start/docs/architecture.md +128 -128
- package/templates/tanstack-start/docs/design.md +169 -169
- package/templates/tanstack-start/docs/guides/conventions.md +43 -43
- package/templates/tanstack-start/docs/guides/env-setup.md +35 -35
- package/templates/tanstack-start/docs/guides/getting-started.md +19 -19
- package/templates/tanstack-start/docs/guides/hooks.md +63 -35
- package/templates/tanstack-start/docs/guides/routes.md +61 -42
- package/templates/tanstack-start/docs/guides/services.md +45 -45
- package/templates/tanstack-start/docs/library/better-auth/index.md +68 -68
- package/templates/tanstack-start/docs/library/prisma/cloudflare-d1.md +19 -19
- package/templates/tanstack-start/docs/library/prisma/config.md +16 -16
- package/templates/tanstack-start/docs/library/prisma/crud.md +17 -17
- package/templates/tanstack-start/docs/library/prisma/index.md +17 -17
- package/templates/tanstack-start/docs/library/prisma/relations.md +16 -16
- package/templates/tanstack-start/docs/library/prisma/schema.md +23 -23
- package/templates/tanstack-start/docs/library/prisma/setup.md +6 -6
- package/templates/tanstack-start/docs/library/prisma/transactions.md +10 -10
- package/templates/tanstack-start/docs/library/t3-env/index.md +21 -160
- package/templates/tanstack-start/docs/library/tanstack-query/index.md +6 -6
- package/templates/tanstack-start/docs/library/tanstack-query/invalidation.md +19 -19
- package/templates/tanstack-start/docs/library/tanstack-query/optimistic-updates.md +4 -4
- package/templates/tanstack-start/docs/library/tanstack-query/use-mutation.md +14 -14
- package/templates/tanstack-start/docs/library/tanstack-query/use-query.md +21 -21
- package/templates/tanstack-start/docs/library/tanstack-router/error-handling.md +9 -9
- package/templates/tanstack-start/docs/library/tanstack-router/hooks.md +11 -11
- package/templates/tanstack-start/docs/library/tanstack-router/index.md +18 -18
- package/templates/tanstack-start/docs/library/tanstack-router/navigation.md +17 -17
- package/templates/tanstack-start/docs/library/tanstack-router/route-context.md +5 -5
- package/templates/tanstack-start/docs/library/tanstack-router/search-params.md +10 -10
- package/templates/tanstack-start/docs/library/tanstack-start/auth-patterns.md +8 -8
- package/templates/tanstack-start/docs/library/tanstack-start/index.md +15 -15
- package/templates/tanstack-start/docs/library/tanstack-start/middleware.md +9 -9
- package/templates/tanstack-start/docs/library/tanstack-start/routing.md +6 -6
- package/templates/tanstack-start/docs/library/tanstack-start/server-functions.md +18 -18
- package/templates/tanstack-start/docs/library/tanstack-start/setup.md +4 -4
- package/templates/tanstack-start/docs/library/zod/complex-types.md +11 -11
- package/templates/tanstack-start/docs/library/zod/index.md +8 -8
- package/templates/tanstack-start/docs/library/zod/transforms.md +11 -11
- package/templates/tanstack-start/docs/library/zod/validation.md +9 -9
|
@@ -0,0 +1,558 @@
|
|
|
1
|
+
# UI/UX & Tailwind Guidelines
|
|
2
|
+
|
|
3
|
+
> TanStack Start + Tailwind CSS v4 + iOS Safe Area
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
<forbidden>
|
|
8
|
+
|
|
9
|
+
| Category | Forbidden |
|
|
10
|
+
|----------|-----------|
|
|
11
|
+
| **Spacing** | Arbitrary values (`mt-[13px]`), non-theme values |
|
|
12
|
+
| **Components** | Different style combinations for same element |
|
|
13
|
+
| **@apply** | Usage in individual screens, outside base components |
|
|
14
|
+
| **Responsive** | Desktop-first approach |
|
|
15
|
+
| **Safe Area** | Apply inside components, direct `env(safe-area-inset-*)` usage |
|
|
16
|
+
| **Shadows** | `shadow-lg` or higher (except special cases) |
|
|
17
|
+
| **Fonts** | 4+ font families, `text-xs` overuse |
|
|
18
|
+
| **Colors** | Using Primary for regular text/backgrounds, heavy borders |
|
|
19
|
+
| **Accessibility** | Color-only distinction, `outline-none`, placeholder-only labels |
|
|
20
|
+
| **Errors** | Technical term messages ("code: 500") |
|
|
21
|
+
| **Buttons** | 2+ Primary buttons per screen |
|
|
22
|
+
|
|
23
|
+
</forbidden>
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
<required>
|
|
28
|
+
|
|
29
|
+
| Category | Required |
|
|
30
|
+
|----------|----------|
|
|
31
|
+
| **Spacing** | Tailwind default scale only (4px units) |
|
|
32
|
+
| **Responsive** | Mobile-first → `sm:` → `md:` → `lg:` |
|
|
33
|
+
| **Safe Area** | Use `tailwindcss-safe-area`, apply at layout level |
|
|
34
|
+
| **Viewport** | Set `viewport-fit=cover` |
|
|
35
|
+
| **Accessibility** | 4.5:1+ contrast, required labels, keyboard access |
|
|
36
|
+
| **Button States** | Clearly distinguish Default/Hover/Active/Disabled/Loading |
|
|
37
|
+
| **Errors** | User action-focused messages |
|
|
38
|
+
| **Focus** | Clear indicators like `focus:ring-2` |
|
|
39
|
+
| **Loading** | Loading states for major actions, prevent duplicate clicks |
|
|
40
|
+
| **Class Order** | Layout → Box → Typography → Color → State |
|
|
41
|
+
|
|
42
|
+
</required>
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
<design_tokens>
|
|
47
|
+
|
|
48
|
+
## Design Tokens (Tailwind @theme)
|
|
49
|
+
|
|
50
|
+
```css
|
|
51
|
+
@import "tailwindcss";
|
|
52
|
+
@import "tailwindcss-safe-area";
|
|
53
|
+
|
|
54
|
+
@theme {
|
|
55
|
+
/* Colors (60-30-10 rule) */
|
|
56
|
+
--color-primary-500: oklch(0.55 0.2 250);
|
|
57
|
+
--color-primary-600: oklch(0.48 0.22 250);
|
|
58
|
+
--color-primary-700: oklch(0.42 0.2 250);
|
|
59
|
+
|
|
60
|
+
/* Fonts (max 2-3) */
|
|
61
|
+
--font-sans: "Pretendard", "Inter", system-ui, sans-serif;
|
|
62
|
+
--font-mono: "JetBrains Mono", monospace;
|
|
63
|
+
|
|
64
|
+
/* Radius */
|
|
65
|
+
--radius: 0.5rem; /* 8px */
|
|
66
|
+
|
|
67
|
+
/* Shadows */
|
|
68
|
+
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
69
|
+
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
| Token | Value |
|
|
74
|
+
|-------|-------|
|
|
75
|
+
| Spacing | 4px grid (`gap-2`=8px, `p-4`=16px) |
|
|
76
|
+
| Colors | Primary (action), Neutral (background), Semantic (state) |
|
|
77
|
+
| Font Size | `text-2xl` (heading), `text-base` (body), `text-sm` (secondary) |
|
|
78
|
+
| Container | `max-w-md` (form), `max-w-3xl` (blog), `max-w-7xl` (dashboard) |
|
|
79
|
+
|
|
80
|
+
</design_tokens>
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
<patterns>
|
|
85
|
+
|
|
86
|
+
## Tailwind Patterns
|
|
87
|
+
|
|
88
|
+
### Buttons
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
// Primary
|
|
92
|
+
<button className="px-4 py-2 text-sm font-medium text-white bg-primary-600 rounded-lg
|
|
93
|
+
hover:bg-primary-700 focus:ring-2 focus:ring-primary-500 focus:ring-offset-2
|
|
94
|
+
disabled:opacity-50 disabled:cursor-not-allowed">
|
|
95
|
+
Save
|
|
96
|
+
</button>
|
|
97
|
+
|
|
98
|
+
// Secondary
|
|
99
|
+
<button className="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg
|
|
100
|
+
hover:bg-gray-50 focus:ring-2 focus:ring-gray-300">
|
|
101
|
+
Cancel
|
|
102
|
+
</button>
|
|
103
|
+
|
|
104
|
+
// Destructive
|
|
105
|
+
<button className="px-4 py-2 text-sm font-medium text-white bg-red-600 rounded-lg hover:bg-red-700">
|
|
106
|
+
Delete
|
|
107
|
+
</button>
|
|
108
|
+
|
|
109
|
+
// Loading state
|
|
110
|
+
<button disabled={isLoading} className="flex items-center gap-2">
|
|
111
|
+
{isLoading && <Spinner className="w-4 h-4 animate-spin" />}
|
|
112
|
+
{isLoading ? 'Saving...' : 'Save'}
|
|
113
|
+
</button>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
| Size | Classes |
|
|
117
|
+
|------|---------|
|
|
118
|
+
| Small | `px-3 py-1.5 text-sm` |
|
|
119
|
+
| Medium | `px-4 py-2 text-base` |
|
|
120
|
+
| Large | `px-6 py-3 text-lg` |
|
|
121
|
+
|
|
122
|
+
### Input Fields
|
|
123
|
+
|
|
124
|
+
```tsx
|
|
125
|
+
// Basic
|
|
126
|
+
<div>
|
|
127
|
+
<label htmlFor="email" className="block text-sm font-medium text-gray-700 mb-1">
|
|
128
|
+
Email
|
|
129
|
+
</label>
|
|
130
|
+
<input
|
|
131
|
+
id="email"
|
|
132
|
+
type="email"
|
|
133
|
+
className="w-full px-3 py-2 text-base border border-gray-300 rounded-lg
|
|
134
|
+
focus:ring-2 focus:ring-blue-500 focus:border-blue-500
|
|
135
|
+
placeholder:text-gray-400"
|
|
136
|
+
placeholder="example@email.com"
|
|
137
|
+
/>
|
|
138
|
+
</div>
|
|
139
|
+
|
|
140
|
+
// Error state
|
|
141
|
+
<input
|
|
142
|
+
className="w-full px-3 py-2 border border-red-500 rounded-lg
|
|
143
|
+
focus:ring-2 focus:ring-red-500"
|
|
144
|
+
aria-invalid="true"
|
|
145
|
+
aria-describedby="email-error"
|
|
146
|
+
/>
|
|
147
|
+
<p id="email-error" className="mt-1 text-sm text-red-600" role="alert">
|
|
148
|
+
Please enter a valid email
|
|
149
|
+
</p>
|
|
150
|
+
|
|
151
|
+
// With icon
|
|
152
|
+
<div className="relative">
|
|
153
|
+
<SearchIcon className="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-400" />
|
|
154
|
+
<input className="pl-10 pr-3 py-2 w-full border border-gray-300 rounded-lg" />
|
|
155
|
+
</div>
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Cards
|
|
159
|
+
|
|
160
|
+
```tsx
|
|
161
|
+
<div className="bg-white rounded-lg border border-gray-200 shadow-sm overflow-hidden">
|
|
162
|
+
<div className="px-6 py-4 border-b border-gray-200">
|
|
163
|
+
<h3 className="text-lg font-semibold text-gray-900">Title</h3>
|
|
164
|
+
</div>
|
|
165
|
+
<div className="px-6 py-4">
|
|
166
|
+
<p className="text-base text-gray-600">Content</p>
|
|
167
|
+
</div>
|
|
168
|
+
<div className="px-6 py-4 bg-gray-50 border-t border-gray-200">
|
|
169
|
+
<button>Footer Button</button>
|
|
170
|
+
</div>
|
|
171
|
+
</div>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Modals
|
|
175
|
+
|
|
176
|
+
```tsx
|
|
177
|
+
<div className="fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4">
|
|
178
|
+
<div className="bg-white rounded-lg shadow-xl w-full max-w-md">
|
|
179
|
+
<div className="px-6 py-4 border-b border-gray-200 flex items-center justify-between">
|
|
180
|
+
<h2 className="text-lg font-semibold text-gray-900">Title</h2>
|
|
181
|
+
<button><XIcon className="w-5 h-5" /></button>
|
|
182
|
+
</div>
|
|
183
|
+
<div className="px-6 py-4">Content</div>
|
|
184
|
+
<div className="px-6 py-4 bg-gray-50 flex justify-end gap-3">
|
|
185
|
+
<button className="px-4 py-2 border border-gray-300 rounded-lg">Cancel</button>
|
|
186
|
+
<button className="px-4 py-2 bg-primary-600 text-white rounded-lg">Confirm</button>
|
|
187
|
+
</div>
|
|
188
|
+
</div>
|
|
189
|
+
</div>
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Alerts
|
|
193
|
+
|
|
194
|
+
```tsx
|
|
195
|
+
// Success
|
|
196
|
+
<div className="p-4 bg-green-50 border border-green-200 rounded-lg flex gap-3">
|
|
197
|
+
<CheckCircleIcon className="w-5 h-5 text-green-600 flex-shrink-0" />
|
|
198
|
+
<p className="text-sm text-green-800">Saved successfully</p>
|
|
199
|
+
</div>
|
|
200
|
+
|
|
201
|
+
// Error
|
|
202
|
+
<div className="p-4 bg-red-50 border border-red-200 rounded-lg flex gap-3">
|
|
203
|
+
<XCircleIcon className="w-5 h-5 text-red-600 flex-shrink-0" />
|
|
204
|
+
<p className="text-sm text-red-800">Something went wrong. Please try again later.</p>
|
|
205
|
+
</div>
|
|
206
|
+
|
|
207
|
+
// Warning
|
|
208
|
+
<div className="p-4 bg-yellow-50 border border-yellow-200 rounded-lg flex gap-3">
|
|
209
|
+
<AlertIcon className="w-5 h-5 text-yellow-600 flex-shrink-0" />
|
|
210
|
+
<p className="text-sm text-yellow-800">Confirmation needed</p>
|
|
211
|
+
</div>
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Empty States
|
|
215
|
+
|
|
216
|
+
```tsx
|
|
217
|
+
<div className="py-12 text-center">
|
|
218
|
+
<InboxIcon className="mx-auto w-12 h-12 text-gray-400" />
|
|
219
|
+
<h3 className="mt-4 text-lg font-medium text-gray-900">No items yet</h3>
|
|
220
|
+
<p className="mt-2 text-sm text-gray-600">Add your first item</p>
|
|
221
|
+
<button className="mt-6 px-4 py-2 bg-primary-600 text-white rounded-lg">
|
|
222
|
+
Add Item
|
|
223
|
+
</button>
|
|
224
|
+
</div>
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
</patterns>
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
<safe_area>
|
|
232
|
+
|
|
233
|
+
## iOS Safe Area
|
|
234
|
+
|
|
235
|
+
### Installation & Setup
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
yarn add tailwindcss-safe-area
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
```tsx
|
|
242
|
+
// __root.tsx
|
|
243
|
+
export const Route = createRootRoute({
|
|
244
|
+
head: () => ({
|
|
245
|
+
meta: [{
|
|
246
|
+
name: 'viewport',
|
|
247
|
+
content: 'width=device-width, initial-scale=1, viewport-fit=cover',
|
|
248
|
+
}],
|
|
249
|
+
}),
|
|
250
|
+
})
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Utility Classes
|
|
254
|
+
|
|
255
|
+
| Class | Purpose |
|
|
256
|
+
|-------|---------|
|
|
257
|
+
| `pt-safe` | Top safe area (notch) |
|
|
258
|
+
| `pb-safe` | Bottom safe area (home indicator) |
|
|
259
|
+
| `px-safe` | Horizontal safe area |
|
|
260
|
+
| `h-screen-safe` | Height excluding safe area |
|
|
261
|
+
| `min-h-screen-safe` | Min height |
|
|
262
|
+
| `pt-safe-or-4` | Safe area or 1rem (larger value) |
|
|
263
|
+
| `pb-safe-offset-4` | Safe area + 1rem |
|
|
264
|
+
|
|
265
|
+
### Layout Patterns
|
|
266
|
+
|
|
267
|
+
```tsx
|
|
268
|
+
// Basic app layout
|
|
269
|
+
<div className="min-h-screen-safe flex flex-col">
|
|
270
|
+
<header className="pt-safe-or-2 px-safe-or-4 bg-white border-b">
|
|
271
|
+
<nav className="h-14 flex items-center">Header</nav>
|
|
272
|
+
</header>
|
|
273
|
+
|
|
274
|
+
<main className="flex-1 px-safe-or-4 py-6">
|
|
275
|
+
{children}
|
|
276
|
+
</main>
|
|
277
|
+
|
|
278
|
+
<footer className="pb-safe-or-2 px-safe-or-4 bg-white border-t">
|
|
279
|
+
<nav className="h-14 flex items-center justify-around">Tab Bar</nav>
|
|
280
|
+
</footer>
|
|
281
|
+
</div>
|
|
282
|
+
|
|
283
|
+
// Fixed bottom button
|
|
284
|
+
<div className="fixed bottom-0 left-0 right-0 pb-safe-or-4 px-safe-or-4 bg-white border-t">
|
|
285
|
+
<button className="w-full h-12 bg-primary-600 text-white rounded-lg">
|
|
286
|
+
Confirm
|
|
287
|
+
</button>
|
|
288
|
+
</div>
|
|
289
|
+
|
|
290
|
+
// Fullscreen modal
|
|
291
|
+
<div className="fixed inset-0 bg-white z-50">
|
|
292
|
+
<div className="h-screen-safe flex flex-col p-safe">
|
|
293
|
+
{children}
|
|
294
|
+
</div>
|
|
295
|
+
</div>
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### ✅ / ❌ Safe Area
|
|
299
|
+
|
|
300
|
+
```tsx
|
|
301
|
+
// ❌ Covered by notch
|
|
302
|
+
<header className="fixed top-0">
|
|
303
|
+
|
|
304
|
+
// ✅ Safe area applied
|
|
305
|
+
<header className="fixed top-0 pt-safe">
|
|
306
|
+
|
|
307
|
+
// ❌ Overlaps home indicator
|
|
308
|
+
<button className="fixed bottom-4">
|
|
309
|
+
|
|
310
|
+
// ✅ Safe area applied
|
|
311
|
+
<div className="fixed bottom-0 pb-safe-or-4">
|
|
312
|
+
<button>...</button>
|
|
313
|
+
</div>
|
|
314
|
+
|
|
315
|
+
// ❌ Applied inside component
|
|
316
|
+
<Button className="pb-safe">Button</Button>
|
|
317
|
+
|
|
318
|
+
// ✅ Applied in layout
|
|
319
|
+
<div className="pb-safe-or-4">
|
|
320
|
+
<Button>Button</Button>
|
|
321
|
+
</div>
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
</safe_area>
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
<guidelines>
|
|
329
|
+
|
|
330
|
+
## Core Principles
|
|
331
|
+
|
|
332
|
+
| Principle | Description |
|
|
333
|
+
|-----------|-------------|
|
|
334
|
+
| **Consistency** | Same role = same style |
|
|
335
|
+
| **Simplicity** | Remove unnecessary elements |
|
|
336
|
+
| **Responsive** | Mobile-first |
|
|
337
|
+
| **Accessibility** | WCAG AA (contrast 4.5:1+) |
|
|
338
|
+
|
|
339
|
+
### Colors (60-30-10)
|
|
340
|
+
|
|
341
|
+
| Ratio | Purpose | Example |
|
|
342
|
+
|-------|---------|---------|
|
|
343
|
+
| 60% | Background | `bg-white`, `bg-gray-50` |
|
|
344
|
+
| 30% | Secondary | Cards, sections |
|
|
345
|
+
| 10% | Accent | Primary buttons, CTA |
|
|
346
|
+
|
|
347
|
+
### Typography
|
|
348
|
+
|
|
349
|
+
| Purpose | Class | Size |
|
|
350
|
+
|---------|-------|------|
|
|
351
|
+
| Heading | `text-2xl` | 24px |
|
|
352
|
+
| Subheading | `text-xl` | 20px |
|
|
353
|
+
| Body | `text-base` | 16px |
|
|
354
|
+
| Secondary | `text-sm` | 14px |
|
|
355
|
+
|
|
356
|
+
### Spacing
|
|
357
|
+
|
|
358
|
+
| Purpose | Class | Size |
|
|
359
|
+
|---------|-------|------|
|
|
360
|
+
| Icon-text | `gap-1` | 4px |
|
|
361
|
+
| Inline elements | `gap-2` | 8px |
|
|
362
|
+
| Card padding | `p-4` | 16px |
|
|
363
|
+
| Card spacing | `gap-6` | 24px |
|
|
364
|
+
| Section spacing | `py-12` | 48px |
|
|
365
|
+
|
|
366
|
+
### Responsive
|
|
367
|
+
|
|
368
|
+
```tsx
|
|
369
|
+
<div className="p-4 md:p-6 lg:p-8">
|
|
370
|
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
| Breakpoint | Size | Purpose |
|
|
374
|
+
|------------|------|---------|
|
|
375
|
+
| `sm` | 640px | Mobile landscape |
|
|
376
|
+
| `md` | 768px | Tablet |
|
|
377
|
+
| `lg` | 1024px | Laptop |
|
|
378
|
+
| `xl` | 1280px | Desktop |
|
|
379
|
+
|
|
380
|
+
</guidelines>
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
<accessibility>
|
|
385
|
+
|
|
386
|
+
## Accessibility Checklist
|
|
387
|
+
|
|
388
|
+
```tsx
|
|
389
|
+
// ✅ Clear label
|
|
390
|
+
<label htmlFor="email">Email</label>
|
|
391
|
+
<input id="email" />
|
|
392
|
+
|
|
393
|
+
// ✅ Error connection
|
|
394
|
+
<input aria-invalid={hasError} aria-describedby="error" />
|
|
395
|
+
{hasError && <p id="error" role="alert">Error</p>}
|
|
396
|
+
|
|
397
|
+
// ✅ Focus indicator
|
|
398
|
+
<button className="focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
|
|
399
|
+
|
|
400
|
+
// ✅ Color + icon together
|
|
401
|
+
<span className="text-red-600 flex items-center gap-1">
|
|
402
|
+
<XCircleIcon className="w-4 h-4" />
|
|
403
|
+
Error
|
|
404
|
+
</span>
|
|
405
|
+
|
|
406
|
+
// ✅ Keyboard access
|
|
407
|
+
<div tabIndex={0} onKeyDown={handleKeyDown}>
|
|
408
|
+
|
|
409
|
+
// ❌ Never remove focus
|
|
410
|
+
<button className="outline-none focus:outline-none">
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
| Item | Criteria |
|
|
414
|
+
|------|----------|
|
|
415
|
+
| Text contrast | 4.5:1+ |
|
|
416
|
+
| Large text (18px+) | 3:1+ |
|
|
417
|
+
| Touch target | 44px × 44px+ |
|
|
418
|
+
| Focus indicator | Always visible |
|
|
419
|
+
|
|
420
|
+
</accessibility>
|
|
421
|
+
|
|
422
|
+
---
|
|
423
|
+
|
|
424
|
+
<examples>
|
|
425
|
+
|
|
426
|
+
## Real-World Examples
|
|
427
|
+
|
|
428
|
+
### Form Layout
|
|
429
|
+
|
|
430
|
+
```tsx
|
|
431
|
+
<form className="max-w-md mx-auto space-y-6">
|
|
432
|
+
{/* Input field */}
|
|
433
|
+
<div>
|
|
434
|
+
<label htmlFor="name" className="block text-sm font-medium text-gray-700 mb-1">
|
|
435
|
+
Name
|
|
436
|
+
</label>
|
|
437
|
+
<input
|
|
438
|
+
id="name"
|
|
439
|
+
type="text"
|
|
440
|
+
className="w-full px-3 py-2 border border-gray-300 rounded-lg
|
|
441
|
+
focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
|
442
|
+
/>
|
|
443
|
+
</div>
|
|
444
|
+
|
|
445
|
+
{/* Input with error */}
|
|
446
|
+
<div>
|
|
447
|
+
<label htmlFor="email" className="block text-sm font-medium text-gray-700 mb-1">
|
|
448
|
+
Email
|
|
449
|
+
</label>
|
|
450
|
+
<input
|
|
451
|
+
id="email"
|
|
452
|
+
type="email"
|
|
453
|
+
className="w-full px-3 py-2 border border-red-500 rounded-lg
|
|
454
|
+
focus:ring-2 focus:ring-red-500"
|
|
455
|
+
aria-invalid="true"
|
|
456
|
+
aria-describedby="email-error"
|
|
457
|
+
/>
|
|
458
|
+
<p id="email-error" className="mt-1 text-sm text-red-600" role="alert">
|
|
459
|
+
Please enter a valid email
|
|
460
|
+
</p>
|
|
461
|
+
</div>
|
|
462
|
+
|
|
463
|
+
{/* Button group */}
|
|
464
|
+
<div className="flex gap-3">
|
|
465
|
+
<button
|
|
466
|
+
type="button"
|
|
467
|
+
className="flex-1 px-4 py-2 border border-gray-300 rounded-lg hover:bg-gray-50"
|
|
468
|
+
>
|
|
469
|
+
Cancel
|
|
470
|
+
</button>
|
|
471
|
+
<button
|
|
472
|
+
type="submit"
|
|
473
|
+
className="flex-1 px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700"
|
|
474
|
+
>
|
|
475
|
+
Save
|
|
476
|
+
</button>
|
|
477
|
+
</div>
|
|
478
|
+
</form>
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
### Card List
|
|
482
|
+
|
|
483
|
+
```tsx
|
|
484
|
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
485
|
+
{items.map((item) => (
|
|
486
|
+
<div key={item.id} className="bg-white rounded-lg border border-gray-200 shadow-sm overflow-hidden">
|
|
487
|
+
<img src={item.image} className="w-full h-48 object-cover" />
|
|
488
|
+
<div className="p-4">
|
|
489
|
+
<h3 className="text-lg font-semibold text-gray-900">{item.title}</h3>
|
|
490
|
+
<p className="mt-2 text-sm text-gray-600">{item.description}</p>
|
|
491
|
+
<button className="mt-4 w-full px-4 py-2 bg-primary-600 text-white rounded-lg">
|
|
492
|
+
View Details
|
|
493
|
+
</button>
|
|
494
|
+
</div>
|
|
495
|
+
</div>
|
|
496
|
+
))}
|
|
497
|
+
</div>
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
### Dashboard Layout
|
|
501
|
+
|
|
502
|
+
```tsx
|
|
503
|
+
<div className="min-h-screen-safe bg-gray-50">
|
|
504
|
+
{/* Header */}
|
|
505
|
+
<header className="pt-safe-or-2 px-safe-or-4 bg-white border-b border-gray-200">
|
|
506
|
+
<div className="h-16 flex items-center justify-between">
|
|
507
|
+
<h1 className="text-xl font-bold">Dashboard</h1>
|
|
508
|
+
<button>Menu</button>
|
|
509
|
+
</div>
|
|
510
|
+
</header>
|
|
511
|
+
|
|
512
|
+
{/* Main */}
|
|
513
|
+
<main className="px-safe-or-4 py-6">
|
|
514
|
+
<div className="max-w-7xl mx-auto space-y-6">
|
|
515
|
+
{/* Stats cards */}
|
|
516
|
+
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
517
|
+
<div className="bg-white p-6 rounded-lg border border-gray-200">
|
|
518
|
+
<p className="text-sm text-gray-600">Total Users</p>
|
|
519
|
+
<p className="mt-2 text-3xl font-bold text-gray-900">1,234</p>
|
|
520
|
+
</div>
|
|
521
|
+
{/* ... */}
|
|
522
|
+
</div>
|
|
523
|
+
|
|
524
|
+
{/* Chart */}
|
|
525
|
+
<div className="bg-white p-6 rounded-lg border border-gray-200">
|
|
526
|
+
<h2 className="text-lg font-semibold text-gray-900">Activity</h2>
|
|
527
|
+
{/* Chart component */}
|
|
528
|
+
</div>
|
|
529
|
+
</div>
|
|
530
|
+
</main>
|
|
531
|
+
</div>
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
</examples>
|
|
535
|
+
|
|
536
|
+
---
|
|
537
|
+
|
|
538
|
+
<claude_requirements>
|
|
539
|
+
|
|
540
|
+
## Claude Code Requirements
|
|
541
|
+
|
|
542
|
+
**When Creating New Screens/Components:**
|
|
543
|
+
|
|
544
|
+
1. **Use Tailwind scale only** - No arbitrary values
|
|
545
|
+
2. **Mobile-first** - Base styles → `sm:` → `md:` → `lg:`
|
|
546
|
+
3. **Handle safe area in layout** - Not inside components
|
|
547
|
+
4. **Accessibility required** - Labels, contrast, focus, keyboard
|
|
548
|
+
5. **Consistent patterns** - Same elements use same class combinations
|
|
549
|
+
6. **Loading/error states** - Required for major actions
|
|
550
|
+
7. **Microcopy** - Suggest button/error messages together
|
|
551
|
+
|
|
552
|
+
**When Exceptions Occur:**
|
|
553
|
+
- Explain reason in code comments
|
|
554
|
+
|
|
555
|
+
**When Theme Extension Needed:**
|
|
556
|
+
- Suggest `@theme` extension instead of arbitrary values
|
|
557
|
+
|
|
558
|
+
</claude_requirements>
|