create-lego-one 2.0.12 → 2.0.13

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 (78) hide show
  1. package/dist/index.cjs +34 -0
  2. package/dist/index.cjs.map +1 -1
  3. package/package.json +1 -1
  4. package/template/.cursor/rules/rules.mdc +639 -0
  5. package/template/.dockerignore +58 -0
  6. package/template/.env.example +18 -0
  7. package/template/.eslintignore +5 -0
  8. package/template/.eslintrc.js +28 -0
  9. package/template/.prettierignore +6 -0
  10. package/template/.prettierrc +11 -0
  11. package/template/CLAUDE.md +634 -0
  12. package/template/Dockerfile +67 -0
  13. package/template/PROMPT.md +457 -0
  14. package/template/README.md +325 -0
  15. package/template/docker-compose.yml +48 -0
  16. package/template/docker-entrypoint.sh +23 -0
  17. package/template/docs/checkpoints/.template.md +64 -0
  18. package/template/docs/checkpoints/framework/01-infrastructure-setup.md +132 -0
  19. package/template/docs/checkpoints/framework/02-pocketbase-setup.md +155 -0
  20. package/template/docs/checkpoints/framework/03-host-kernel.md +170 -0
  21. package/template/docs/checkpoints/framework/04-auth-system.md +163 -0
  22. package/template/docs/checkpoints/framework/phase-05-multitenancy-rbac.md +223 -0
  23. package/template/docs/checkpoints/framework/phase-06-ui-components.md +260 -0
  24. package/template/docs/checkpoints/framework/phase-07-communication-system.md +276 -0
  25. package/template/docs/checkpoints/framework/phase-08-plugin-system.md +91 -0
  26. package/template/docs/checkpoints/framework/phase-09-dashboard-plugin.md +111 -0
  27. package/template/docs/checkpoints/framework/phase-10-todo-plugin.md +169 -0
  28. package/template/docs/checkpoints/framework/phase-11-testing.md +264 -0
  29. package/template/docs/checkpoints/framework/phase-12-deployment.md +294 -0
  30. package/template/docs/checkpoints/framework/phase-13-documentation.md +312 -0
  31. package/template/docs/framework/plans/00-index.md +164 -0
  32. package/template/docs/framework/plans/01-infrastructure-setup.md +855 -0
  33. package/template/docs/framework/plans/02-pocketbase-setup.md +1374 -0
  34. package/template/docs/framework/plans/03-host-kernel.md +1518 -0
  35. package/template/docs/framework/plans/04-auth-system.md +1466 -0
  36. package/template/docs/framework/plans/05-multitenancy-rbac.md +1527 -0
  37. package/template/docs/framework/plans/06-ui-components.md +1478 -0
  38. package/template/docs/framework/plans/07-communication-system.md +1106 -0
  39. package/template/docs/framework/plans/08-plugin-system.md +1179 -0
  40. package/template/docs/framework/plans/09-dashboard-plugin.md +1137 -0
  41. package/template/docs/framework/plans/10-todo-plugin.md +1343 -0
  42. package/template/docs/framework/plans/11-testing.md +935 -0
  43. package/template/docs/framework/plans/12-deployment.md +896 -0
  44. package/template/docs/framework/prompts/0-boilerplate-modernjs.md +151 -0
  45. package/template/docs/framework/research/00-modernjs-audit.md +488 -0
  46. package/template/docs/framework/research/01-system-blueprint.md +721 -0
  47. package/template/docs/framework/research/02-data-migration-protocol.md +699 -0
  48. package/template/docs/framework/research/03-host-setup.md +714 -0
  49. package/template/docs/framework/research/04-plugin-architecture.md +645 -0
  50. package/template/docs/framework/research/05-slot-injection-pattern.md +671 -0
  51. package/template/docs/framework/research/06-cli-strategy.md +615 -0
  52. package/template/docs/framework/research/07-deployment.md +629 -0
  53. package/template/docs/framework/research/README.md +282 -0
  54. package/template/docs/framework/setup/00-index.md +210 -0
  55. package/template/docs/framework/setup/01-framework-structure.md +308 -0
  56. package/template/docs/framework/setup/02-development-workflow.md +405 -0
  57. package/template/docs/framework/setup/03-environment-setup.md +215 -0
  58. package/template/docs/framework/setup/04-kernel-architecture.md +499 -0
  59. package/template/docs/framework/setup/05-plugin-system.md +620 -0
  60. package/template/docs/framework/setup/06-communication-patterns.md +451 -0
  61. package/template/docs/framework/setup/07-plugin-development.md +582 -0
  62. package/template/docs/framework/setup/08-component-library.md +658 -0
  63. package/template/docs/framework/setup/09-data-integration.md +609 -0
  64. package/template/docs/framework/setup/10-auth-rbac.md +497 -0
  65. package/template/docs/framework/setup/11-hooks-api.md +393 -0
  66. package/template/docs/framework/setup/12-components-api.md +665 -0
  67. package/template/docs/framework/setup/13-deployment-guide.md +566 -0
  68. package/template/docs/framework/setup/README.md +548 -0
  69. package/template/host/package.json +1 -1
  70. package/template/nginx.conf +72 -0
  71. package/template/package.json +1 -1
  72. package/template/packages/plugins/@lego/plugin-dashboard/package.json +1 -1
  73. package/template/packages/plugins/@lego/plugin-todo/package.json +1 -1
  74. package/template/pocketbase/CHANGELOG.md +911 -0
  75. package/template/pocketbase/LICENSE.md +17 -0
  76. package/template/scripts/create-plugin.js +221 -0
  77. package/template/scripts/deploy.sh +56 -0
  78. package/template/tsconfig.base.json +26 -0
@@ -0,0 +1,658 @@
1
+ # Component Library
2
+
3
+ **UI Components, Styling, and Design System**
4
+
5
+ ---
6
+
7
+ ## Overview
8
+
9
+ Lego-One uses **Radix UI primitives** styled with **Tailwind CSS** for accessible, customizable UI components. All components support dark mode and follow WCAG accessibility guidelines.
10
+
11
+ ---
12
+
13
+ ## Design System
14
+
15
+ ### Colors
16
+
17
+ CSS variables enable theming and dark mode:
18
+
19
+ ```css
20
+ :root {
21
+ --background: 0 0% 100%; /* White background */
22
+ --foreground: 222.2 84% 4.9%; /* Dark text */
23
+ --primary: 221.2 83.2% 53.3%; /* Primary blue */
24
+ --primary-foreground: 210 40% 98%;
25
+ --secondary: 210 40% 96.1%;
26
+ --secondary-foreground: 222.2 47.4% 11.2%;
27
+ --muted: 210 40% 96.1%;
28
+ --muted-foreground: 215.4 16.3% 46.9%;
29
+ --accent: 210 40% 96.1%;
30
+ --accent-foreground: 222.2 47.4% 11.2%;
31
+ --destructive: 0 84.2% 60.2%;
32
+ --destructive-foreground: 210 40% 98%;
33
+ --border: 214.3 31.8% 91.4%;
34
+ --input: 214.3 31.8% 91.4%;
35
+ --ring: 221.2 83.2% 53.3%;
36
+ --radius: 0.5rem;
37
+ }
38
+ ```
39
+
40
+ **Usage:**
41
+ ```tsx
42
+ <div className="bg-background text-foreground">
43
+ <h1 className="text-primary">Primary colored heading</h1>
44
+ <p className="text-muted-foreground">Muted text</p>
45
+ </div>
46
+ ```
47
+
48
+ ### Dark Mode
49
+
50
+ Dark mode is automatic via the `dark:` class prefix:
51
+
52
+ ```tsx
53
+ <div className="bg-background dark:bg-gray-950">
54
+ <p className="text-foreground dark:text-gray-100">
55
+ Adapts to dark mode
56
+ </p>
57
+ </div>
58
+ ```
59
+
60
+ **Tailwind Config:**
61
+ ```typescript
62
+ darkMode: ['class'], // Enables .dark class on html element
63
+ ```
64
+
65
+ ### Typography
66
+
67
+ **Font:** Inter (via system fonts)
68
+
69
+ **Scale:**
70
+ ```tsx
71
+ <h1 className="text-3xl font-bold">Heading 1</h1>
72
+ <h2 className="text-2xl font-semibold">Heading 2</h2>
73
+ <h3 className="text-xl font-medium">Heading 3</h3>
74
+ <p className="text-sm">Body text</p>
75
+ <span className="text-xs">Small text</span>
76
+ ```
77
+
78
+ ### Spacing
79
+
80
+ **Scale:** 4px base unit (Tailwind default)
81
+
82
+ ```tsx
83
+ <div className="p-4"> /* 16px padding */
84
+ <div className="px-6"> /* 24px horizontal padding */
85
+ <div className="py-2"> /* 8px vertical padding */
86
+ <div className="m-8"> /* 32px margin */
87
+ <div className="gap-4"> /* 16px gap (flex/grid) */
88
+ ```
89
+
90
+ ---
91
+
92
+ ## Available Components
93
+
94
+ ### Form Components
95
+
96
+ #### Button
97
+
98
+ **Import:** `import { Button } from '@lego/kernel/components'`
99
+
100
+ **Variants:**
101
+ ```tsx
102
+ <Button>Default</Button>
103
+ <Button variant="secondary">Secondary</Button>
104
+ <Button variant="destructive">Delete</Button>
105
+ <Button variant="outline">Outline</Button>
106
+ <Button variant="ghost">Ghost</Button>
107
+ <Button variant="link">Link</Button>
108
+ ```
109
+
110
+ **Sizes:**
111
+ ```tsx
112
+ <Button size="default">Default</Button>
113
+ <Button size="sm">Small</Button>
114
+ <Button size="lg">Large</Button>
115
+ <Button size="icon"><Icon /></Button>
116
+ ```
117
+
118
+ **States:**
119
+ ```tsx
120
+ <Button disabled>Disabled</Button>
121
+ ```
122
+
123
+ ---
124
+
125
+ #### Input
126
+
127
+ **Import:** `import { Input } from '@lego/kernel/components'`
128
+
129
+ ```tsx
130
+ <Input placeholder="Enter text..." />
131
+ <Input type="password" placeholder="Password" />
132
+ <Input type="email" placeholder="Email" />
133
+ <Input disabled value="Disabled" />
134
+ ```
135
+
136
+ ---
137
+
138
+ #### Label
139
+
140
+ **Import:** `import { Label } from '@lego/kernel/components'`
141
+
142
+ ```tsx
143
+ <Label htmlFor="email">Email</Label>
144
+ <Input id="email" type="email" />
145
+ ```
146
+
147
+ ---
148
+
149
+ #### Textarea
150
+
151
+ **Import:** `import { Textarea } from '@lego/kernel/components'`
152
+
153
+ ```tsx
154
+ <Textarea placeholder="Enter description..." rows={5} />
155
+ ```
156
+
157
+ ---
158
+
159
+ #### Select
160
+
161
+ **Import:** `import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue }`
162
+
163
+ ```tsx
164
+ <Select>
165
+ <SelectTrigger>
166
+ <SelectValue placeholder="Select option" />
167
+ </SelectTrigger>
168
+ <SelectContent>
169
+ <SelectItem value="1">Option 1</SelectItem>
170
+ <SelectItem value="2">Option 2</SelectItem>
171
+ <SelectItem value="3">Option 3</SelectItem>
172
+ </SelectContent>
173
+ </Select>
174
+ ```
175
+
176
+ ---
177
+
178
+ #### Checkbox
179
+
180
+ **Import:** `import { Checkbox } from '@lego/kernel/components'`
181
+
182
+ ```tsx
183
+ <Checkbox checked={checked} onCheckedChange={setChecked} />
184
+ <Checkbox disabled />
185
+ ```
186
+
187
+ ---
188
+
189
+ #### Switch
190
+
191
+ **Import:** `import { Switch } from '@lego/kernel/components'`
192
+
193
+ ```tsx
194
+ <Switch checked={enabled} onCheckedChange={setEnabled} />
195
+ <Switch disabled />
196
+ ```
197
+
198
+ ---
199
+
200
+ ### Layout Components
201
+
202
+ #### Card
203
+
204
+ **Import:** `import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter }`
205
+
206
+ ```tsx
207
+ <Card>
208
+ <CardHeader>
209
+ <CardTitle>Card Title</CardTitle>
210
+ <CardDescription>Card description</CardDescription>
211
+ </CardHeader>
212
+ <CardContent>
213
+ <p>Card content</p>
214
+ </CardContent>
215
+ <CardFooter>
216
+ <Button>Action</Button>
217
+ </CardFooter>
218
+ </Card>
219
+ ```
220
+
221
+ ---
222
+
223
+ #### Separator
224
+
225
+ **Import:** `import { Separator } from '@lego/kernel/components'`
226
+
227
+ ```tsx
228
+ <Separator /> {/* Horizontal */}
229
+ <Separator orientation="vertical" className="h-8" /> {/* Vertical */}
230
+ ```
231
+
232
+ ---
233
+
234
+ #### ScrollArea
235
+
236
+ **Import:** `import { ScrollArea } from '@lego/kernel/components'`
237
+
238
+ ```tsx
239
+ <ScrollArea className="h-96">
240
+ <div className="p-4">
241
+ {/* Long content */}
242
+ </div>
243
+ </ScrollArea>
244
+ ```
245
+
246
+ ---
247
+
248
+ ### Feedback Components
249
+
250
+ #### Alert
251
+
252
+ **Import:** `import { Alert, AlertDescription, AlertTitle }`
253
+
254
+ ```tsx
255
+ <Alert>
256
+ <AlertCircle className="h-4 w-4" />
257
+ <AlertTitle>Info</AlertTitle>
258
+ <AlertDescription>This is an informational message.</AlertDescription>
259
+ </Alert>
260
+
261
+ <Alert variant="destructive">
262
+ <AlertTitle>Error</AlertTitle>
263
+ <AlertDescription>Something went wrong.</AlertDescription>
264
+ </Alert>
265
+ ```
266
+
267
+ ---
268
+
269
+ #### Badge
270
+
271
+ **Import:** `import { Badge } from '@lego/kernel/components'`
272
+
273
+ ```tsx
274
+ <Badge>Default</Badge>
275
+ <Badge variant="secondary">Secondary</Badge>
276
+ <Badge variant="destructive">Error</Badge>
277
+ <Badge variant="outline">Outline</Badge>
278
+ ```
279
+
280
+ ---
281
+
282
+ #### Progress
283
+
284
+ **Import:** `import { Progress } from '@lego/kernel/components'`
285
+
286
+ ```tsx
287
+ <Progress value={33} />
288
+ <Progress value={66} className="w-96" />
289
+ ```
290
+
291
+ ---
292
+
293
+ #### Skeleton
294
+
295
+ **Import:** `import { Skeleton } from '@lego/kernel/components'`
296
+
297
+ ```tsx
298
+ <Skeleton className="h-12 w-12 rounded-full" />
299
+ <Skeleton className="h-4 w-64" />
300
+ <Skeleton className="h-96 w-full" />
301
+ ```
302
+
303
+ ---
304
+
305
+ #### Toast
306
+
307
+ **Import:** `import { useToast } from '@lego/kernel/components'`
308
+
309
+ ```tsx
310
+ // In root App.tsx
311
+ <Toaster />
312
+
313
+ // In component
314
+ function MyComponent() {
315
+ const { toast } = useToast();
316
+
317
+ return (
318
+ <Button onClick={() => {
319
+ toast({
320
+ title: 'Success',
321
+ description: 'Operation completed',
322
+ });
323
+ }}>
324
+ Show Toast
325
+ </Button>
326
+ );
327
+ }
328
+ ```
329
+
330
+ ---
331
+
332
+ ### Navigation Components
333
+
334
+ #### Tabs
335
+
336
+ **Import:** `import { Tabs, TabsList, TabsTrigger, TabsContent }`
337
+
338
+ ```tsx
339
+ <Tabs defaultValue="tab1">
340
+ <TabsList>
341
+ <TabsTrigger value="tab1">Tab 1</TabsTrigger>
342
+ <TabsTrigger value="tab2">Tab 2</TabsTrigger>
343
+ </TabsList>
344
+ <TabsContent value="tab1">Content 1</TabsContent>
345
+ <TabsContent value="tab2">Content 2</TabsContent>
346
+ </Tabs>
347
+ ```
348
+
349
+ ---
350
+
351
+ #### Dropdown Menu
352
+
353
+ **Import:** `import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator }`
354
+
355
+ ```tsx
356
+ <DropdownMenu>
357
+ <DropdownMenuTrigger asChild>
358
+ <Button variant="ghost">Menu</Button>
359
+ </DropdownMenuTrigger>
360
+ <DropdownMenuContent>
361
+ <DropdownMenuLabel>My Account</DropdownMenuLabel>
362
+ <DropdownMenuSeparator />
363
+ <DropdownMenuItem>Profile</DropdownMenuItem>
364
+ <DropdownMenuItem>Settings</DropdownMenuItem>
365
+ <DropdownMenuSeparator />
366
+ <DropdownMenuItem>Logout</DropdownMenuItem>
367
+ </DropdownMenuContent>
368
+ </DropdownMenu>
369
+ ```
370
+
371
+ ---
372
+
373
+ ### Display Components
374
+
375
+ #### Avatar
376
+
377
+ **Import:** `import { Avatar, AvatarImage, AvatarFallback }`
378
+
379
+ ```tsx
380
+ <Avatar>
381
+ <AvatarImage src="/avatar.jpg" alt="User" />
382
+ <AvatarFallback>JD</AvatarFallback>
383
+ </Avatar>
384
+ ```
385
+
386
+ ---
387
+
388
+ #### Table
389
+
390
+ **Import:** `import { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell }`
391
+
392
+ ```tsx
393
+ <Table>
394
+ <TableHeader>
395
+ <TableRow>
396
+ <TableHead>Name</TableHead>
397
+ <TableHead>Email</TableHead>
398
+ </TableRow>
399
+ </TableHeader>
400
+ <TableBody>
401
+ <TableRow>
402
+ <TableCell>John Doe</TableCell>
403
+ <TableCell>john@example.com</TableCell>
404
+ </TableRow>
405
+ </TableBody>
406
+ </Table>
407
+ ```
408
+
409
+ ---
410
+
411
+ ### Overlay Components
412
+
413
+ #### Dialog
414
+
415
+ **Import:** `import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger }`
416
+
417
+ ```tsx
418
+ <Dialog>
419
+ <DialogTrigger asChild>
420
+ <Button>Open Dialog</Button>
421
+ </DialogTrigger>
422
+ <DialogContent>
423
+ <DialogHeader>
424
+ <DialogTitle>Confirm Action</DialogTitle>
425
+ <DialogDescription>
426
+ This action cannot be undone.
427
+ </DialogDescription>
428
+ </DialogHeader>
429
+ <div className="flex justify-end gap-2">
430
+ <Button variant="outline">Cancel</Button>
431
+ <Button>Confirm</Button>
432
+ </div>
433
+ </DialogContent>
434
+ </Dialog>
435
+ ```
436
+
437
+ ---
438
+
439
+ #### Popover
440
+
441
+ **Import:** `import { Popover, PopoverContent, PopoverTrigger }`
442
+
443
+ ```tsx
444
+ <Popover>
445
+ <PopoverTrigger asChild>
446
+ <Button variant="ghost">Trigger</Button>
447
+ </PopoverTrigger>
448
+ <PopoverContent>
449
+ <div className="grid gap-4">
450
+ <h4 className="font-medium">Popover Content</h4>
451
+ <p className="text-sm text-muted-foreground">
452
+ Additional information
453
+ </p>
454
+ </div>
455
+ </PopoverContent>
456
+ </Popover>
457
+ ```
458
+
459
+ ---
460
+
461
+ #### Tooltip
462
+
463
+ **Import:** `import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger }`
464
+
465
+ ```tsx
466
+ // Wrap app with TooltipProvider once
467
+ <TooltipProvider>
468
+ <App />
469
+ </TooltipProvider>
470
+
471
+ // Use tooltips
472
+ <Tooltip>
473
+ <TooltipTrigger>Hover me</TooltipTrigger>
474
+ <TooltipContent>
475
+ <p>Additional information</p>
476
+ </TooltipContent>
477
+ </Tooltip>
478
+ ```
479
+
480
+ ---
481
+
482
+ ## Utility Functions
483
+
484
+ ### cn() - Class Name Merger
485
+
486
+ **Import:** `import { cn } from '@lego/kernel/lib/utils'`
487
+
488
+ Merges Tailwind classes with conditional logic:
489
+
490
+ ```tsx
491
+ import { cn } from '@lego/kernel/lib/utils';
492
+
493
+ function MyComponent({ isActive }: { isActive: boolean }) {
494
+ return (
495
+ <div className={cn(
496
+ 'base-classes',
497
+ isActive && 'active-classes',
498
+ 'always-applied'
499
+ )}>
500
+ Content
501
+ </div>
502
+ );
503
+ }
504
+ ```
505
+
506
+ ---
507
+
508
+ ## Using Components in Plugins
509
+
510
+ Plugins can use kernel components via the window bridge or by importing if bundled:
511
+
512
+ ```typescript
513
+ // In plugin (bundled production)
514
+ import { Button, Card, Dialog } from '@lego/kernel/components';
515
+
516
+ function MyPluginComponent() {
517
+ return (
518
+ <Card>
519
+ <CardHeader>
520
+ <CardTitle>My Plugin</CardTitle>
521
+ </CardHeader>
522
+ <CardContent>
523
+ <Button>Click me</Button>
524
+ </CardContent>
525
+ </Card>
526
+ );
527
+ }
528
+ ```
529
+
530
+ ---
531
+
532
+ ## Component Patterns
533
+
534
+ ### Form with Validation
535
+
536
+ ```tsx
537
+ import { useForm } from 'react-hook-form';
538
+ import { zodResolver } from '@hookform/resolvers/zod';
539
+ import { z } from 'zod';
540
+ import { Button, Input, Label } from '@lego/kernel/components';
541
+
542
+ const schema = z.object({
543
+ email: z.string().email(),
544
+ password: z.string().min(8),
545
+ });
546
+
547
+ function LoginForm() {
548
+ const { register, handleSubmit, formState: { errors } } = useForm({
549
+ resolver: zodResolver(schema),
550
+ });
551
+
552
+ return (
553
+ <form onSubmit={handleSubmit(onSubmit)}>
554
+ <div>
555
+ <Label htmlFor="email">Email</Label>
556
+ <Input {...register('email')} />
557
+ {errors.email && <span className="text-destructive">{errors.email.message}</span>}
558
+ </div>
559
+ <Button type="submit">Submit</Button>
560
+ </form>
561
+ );
562
+ }
563
+ ```
564
+
565
+ ### Data Table with Actions
566
+
567
+ ```tsx
568
+ import { Button, DropdownMenu, Table } from '@lego/kernel/components';
569
+ import { MoreHorizontal } from 'lucide-react';
570
+
571
+ function DataTable({ data }: { data: Item[] }) {
572
+ return (
573
+ <Table>
574
+ <TableHeader>
575
+ <TableRow>
576
+ <TableHead>Name</TableHead>
577
+ <TableHead>Actions</TableHead>
578
+ </TableRow>
579
+ </TableHeader>
580
+ <TableBody>
581
+ {data.map((item) => (
582
+ <TableRow key={item.id}>
583
+ <TableCell>{item.name}</TableCell>
584
+ <TableCell>
585
+ <DropdownMenu>
586
+ <DropdownMenuTrigger asChild>
587
+ <Button size="icon" variant="ghost">
588
+ <MoreHorizontal className="h-4 w-4" />
589
+ </Button>
590
+ </DropdownMenuTrigger>
591
+ <DropdownMenuContent>
592
+ <DropdownMenuItem>Edit</DropdownMenuItem>
593
+ <DropdownMenuItem className="text-destructive">Delete</DropdownMenuItem>
594
+ </DropdownMenuContent>
595
+ </DropdownMenu>
596
+ </TableCell>
597
+ </TableRow>
598
+ ))}
599
+ </TableBody>
600
+ </Table>
601
+ );
602
+ }
603
+ ```
604
+
605
+ ### Loading States
606
+
607
+ ```tsx
608
+ import { Skeleton, Card, CardHeader, CardContent } from '@lego/kernel/components';
609
+
610
+ function LoadingCard() {
611
+ return (
612
+ <Card>
613
+ <CardHeader>
614
+ <Skeleton className="h-6 w-48" />
615
+ </CardHeader>
616
+ <CardContent>
617
+ <Skeleton className="h-4 w-full mb-2" />
618
+ <Skeleton className="h-4 w-3/4" />
619
+ </CardContent>
620
+ </Card>
621
+ );
622
+ }
623
+ ```
624
+
625
+ ---
626
+
627
+ ## Icons (Lucide React)
628
+
629
+ **Import:** `import { IconName } from 'lucide-react'`
630
+
631
+ ```tsx
632
+ import { Home, Settings, User, Search, Plus, Trash } from 'lucide-react';
633
+
634
+ <Home className="h-5 w-5" />
635
+ <Settings className="h-6 w-6" />
636
+ <User className="h-4 w-4" />
637
+ ```
638
+
639
+ **Common Icons:**
640
+ - **Navigation:** `Home`, `Settings`, `LayoutDashboard`, `CheckSquare`
641
+ - **Actions:** `Plus`, `Trash`, `Edit`, `Save`, `X`
642
+ - **UI:** `Menu`, `Bell`, `Search`, `ChevronDown`, `ChevronRight`
643
+ - **Status:** `Check`, `XCircle`, `AlertCircle`, `Loader2`
644
+
645
+ ---
646
+
647
+ ## Best Practices
648
+
649
+ 1. **Use existing components** - Don't recreate what exists
650
+ 2. **Follow accessibility** - All Radix components are accessible by default
651
+ 3. **Support dark mode** - Use `dark:` prefix for dark mode styles
652
+ 4. **Use semantic HTML** - Button, Dialog, etc. render proper elements
653
+ 5. **Handle loading/error states** - Use Skeleton, Alert for feedback
654
+ 6. **Responsive design** - Mobile-first approach with Tailwind breakpoints
655
+
656
+ ---
657
+
658
+ **Next:** Read [`09-data-integration.md`](./09-data-integration.md) for PocketBase and data fetching patterns.