@zerotal/arch 1.7.4 → 1.7.5

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 (119) hide show
  1. package/CHANGELOG.md +34 -2
  2. package/README.md +4 -2
  3. package/docs/about.md +16 -16
  4. package/docs/admin/actions.md +9 -9
  5. package/docs/admin/auth.md +2 -2
  6. package/docs/admin/dashboard.md +5 -5
  7. package/docs/admin/extending-ui.md +12 -12
  8. package/docs/admin/extending.md +16 -7
  9. package/docs/admin/forms.md +4 -4
  10. package/docs/admin/index.md +2 -2
  11. package/docs/admin/operations.md +9 -9
  12. package/docs/admin/resources.md +3 -3
  13. package/docs/admin/structure.md +6 -6
  14. package/docs/admin/tables.md +8 -8
  15. package/docs/admin/testing.md +4 -4
  16. package/docs/ai.md +118 -11
  17. package/docs/application.md +12 -12
  18. package/docs/arch.md +25 -3
  19. package/docs/assets.md +11 -11
  20. package/docs/audit.md +13 -13
  21. package/docs/authentication.md +39 -39
  22. package/docs/authorization.md +13 -13
  23. package/docs/broadcasting/channels.md +2 -2
  24. package/docs/broadcasting/client.md +2 -2
  25. package/docs/broadcasting/events.md +9 -10
  26. package/docs/broadcasting/index.md +1 -1
  27. package/docs/broadcasting/testing.md +5 -5
  28. package/docs/cache.md +15 -13
  29. package/docs/carbon.md +35 -35
  30. package/docs/changelog.md +105 -1
  31. package/docs/client/index.md +13 -13
  32. package/docs/commands.md +4 -4
  33. package/docs/components.md +116 -115
  34. package/docs/config-system.md +4 -4
  35. package/docs/container.md +27 -27
  36. package/docs/context.md +27 -27
  37. package/docs/contributing.md +28 -0
  38. package/docs/controllers.md +10 -10
  39. package/docs/conventions.md +23 -15
  40. package/docs/cookies.md +3 -3
  41. package/docs/csrf.md +6 -6
  42. package/docs/database.md +22 -17
  43. package/docs/deployment.md +2 -2
  44. package/docs/devtools.md +16 -16
  45. package/docs/email-verification.md +8 -8
  46. package/docs/encryption.md +7 -7
  47. package/docs/errors.md +6 -6
  48. package/docs/events.md +12 -11
  49. package/docs/flow/components.md +32 -32
  50. package/docs/flow/decorators.md +18 -18
  51. package/docs/flow/events.md +16 -16
  52. package/docs/flow/forms.md +17 -17
  53. package/docs/flow/icons.md +5 -5
  54. package/docs/flow/index.md +20 -20
  55. package/docs/flow/layouts.md +35 -35
  56. package/docs/flow/lifecycle.md +16 -16
  57. package/docs/flow/models.md +9 -9
  58. package/docs/flow/pagination.md +8 -8
  59. package/docs/flow/performance.md +7 -7
  60. package/docs/flow/references.md +3 -3
  61. package/docs/flow/routing.md +26 -26
  62. package/docs/flow/testing.md +20 -20
  63. package/docs/getting-started.md +18 -13
  64. package/docs/health.md +17 -8
  65. package/docs/helpers.md +17 -17
  66. package/docs/i18n.md +10 -10
  67. package/docs/inertia/devtools.md +4 -4
  68. package/docs/inertia/index.md +6 -6
  69. package/docs/inertia/props.md +21 -21
  70. package/docs/inertia/rendering.md +9 -9
  71. package/docs/inertia/ssr.md +2 -2
  72. package/docs/lifecycle.md +2 -2
  73. package/docs/lock.md +11 -11
  74. package/docs/logger.md +12 -12
  75. package/docs/media.md +22 -22
  76. package/docs/middleware.md +17 -17
  77. package/docs/migrations.md +13 -13
  78. package/docs/monitor.md +6 -6
  79. package/docs/notifications.md +24 -24
  80. package/docs/orm/casts.md +14 -14
  81. package/docs/orm/factories.md +8 -8
  82. package/docs/orm/index.md +22 -20
  83. package/docs/orm/lifecycle.md +13 -13
  84. package/docs/orm/queries.md +28 -28
  85. package/docs/orm/relationships.md +16 -16
  86. package/docs/orm/serialization.md +11 -11
  87. package/docs/package-development.md +10 -10
  88. package/docs/pagination.md +14 -14
  89. package/docs/password-reset.md +6 -6
  90. package/docs/providers.md +11 -11
  91. package/docs/query-builder.md +18 -18
  92. package/docs/queue.md +14 -12
  93. package/docs/rate-limiting.md +6 -6
  94. package/docs/responses.md +14 -14
  95. package/docs/roles-and-2fa.md +9 -9
  96. package/docs/routing.md +44 -44
  97. package/docs/scaffolding.md +1 -1
  98. package/docs/scheduler.md +10 -10
  99. package/docs/seeding.md +6 -6
  100. package/docs/session.md +16 -14
  101. package/docs/social.md +14 -14
  102. package/docs/storage.md +25 -13
  103. package/docs/structure.md +2 -2
  104. package/docs/support-policy.md +23 -10
  105. package/docs/telemetry.md +12 -12
  106. package/docs/tenancy.md +34 -40
  107. package/docs/testing/browser.md +6 -6
  108. package/docs/testing/console.md +3 -3
  109. package/docs/testing/database.md +10 -10
  110. package/docs/testing/flow-browser.md +6 -6
  111. package/docs/testing/http.md +12 -12
  112. package/docs/testing/index.md +3 -3
  113. package/docs/testing/mocking.md +8 -8
  114. package/docs/upgrade.md +1 -1
  115. package/docs/validator.md +19 -19
  116. package/docs/view.md +14 -14
  117. package/package.json +4 -4
  118. package/src/index.ts +25 -1
  119. package/src/tools/searchDocs.ts +7 -0
@@ -43,7 +43,7 @@ chose, not the six months you browsed to find it.
43
43
 
44
44
  In practice that means most components bind rather than call:
45
45
 
46
- ```tsx
46
+ ```tsx fragment
47
47
  <Slider bind={this.volume} showValue /> {/* live while dragging, synced on release */}
48
48
  <ToggleGroup bind={this.view} options={…} /> {/* presses instantly, syncs after */}
49
49
  <DatePicker bind={this.due} /> {/* months page client-side, day syncs once */}
@@ -95,8 +95,9 @@ bun zt flow:init
95
95
 
96
96
  Components are written against design tokens — `bg-card`, `text-muted-foreground`, `border-input`, `bg-primary` — so _defining_ those tokens themes the whole kit at once. `theme.css` does that for a real Tailwind build. When you have no build step, `flowUiHead()` does the same job as a `<head>` payload: it loads the Tailwind Play CDN, configures it with the identical token mapping, and emits the palette inline.
97
97
 
98
- ```ts
99
- import { Layout, flowUiHead } from "@zerotal/flow-ui";
98
+ ```ts fragment
99
+ import { Layout } from "@zerotal/flow";
100
+ import { flowUiHead } from "@zerotal/flow-ui";
100
101
 
101
102
  export class AppLayout extends Layout {
102
103
  static override get head() {
@@ -107,7 +108,7 @@ export class AppLayout extends Layout {
107
108
 
108
109
  Re-brand by passing `tokensCss`; it is appended after the defaults, so overriding one variable recolours everything that reads it:
109
110
 
110
- ```ts
111
+ ```ts fragment
111
112
  flowUiHead("Acme", {
112
113
  tokensCss: `
113
114
  :root { --primary: 21 90% 48%; --ring: 21 90% 48%; }
@@ -249,13 +250,13 @@ Or import directly from the package: `import { Button } from "@zerotal/flow-ui";
249
250
 
250
251
  ### Button preview
251
252
 
252
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
253
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
253
254
  <div class="flex flex-wrap items-center gap-3"><button type="button" class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground hover:bg-primary/90 h-9 px-4 py-2">Default</button><button type="button" class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 bg-secondary text-secondary-foreground hover:bg-secondary/80 h-9 px-4 py-2">Secondary</button><button type="button" class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 bg-destructive text-destructive-foreground hover:bg-destructive/90 h-9 px-4 py-2">Destructive</button><button type="button" class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 border border-input bg-background hover:bg-accent hover:text-accent-foreground h-9 px-4 py-2">Outline</button><button type="button" class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 hover:bg-accent hover:text-accent-foreground h-9 px-4 py-2">Ghost</button><button type="button" class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 text-primary underline-offset-4 hover:underline h-9 px-4 py-2">Link</button></div>
254
255
  </div>
255
256
 
256
257
  ### Button usage
257
258
 
258
- ```tsx
259
+ ```tsx fragment
259
260
  <Button onClick={this.save}>Save</Button>
260
261
  <Button variant="secondary">Secondary</Button>
261
262
  <Button variant="destructive">Delete</Button>
@@ -292,13 +293,13 @@ Or import directly from the package: `import { Badge } from "@zerotal/flow-ui";`
292
293
 
293
294
  ### Badge preview
294
295
 
295
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
296
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
296
297
  <div class="flex flex-wrap items-center gap-3"><span class="inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 border-transparent bg-primary text-primary-foreground hover:bg-primary/80">Default</span><span class="inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80">Secondary</span><span class="inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80">Destructive</span><span class="inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 text-foreground">Outline</span></div>
297
298
  </div>
298
299
 
299
300
  ### Badge usage
300
301
 
301
- ```tsx
302
+ ```tsx fragment
302
303
  <Badge>New</Badge>
303
304
  <Badge variant="secondary">Beta</Badge>
304
305
  <Badge variant="destructive">Overdue</Badge>
@@ -331,13 +332,13 @@ Or import directly from the package: `import { Card } from "@zerotal/flow-ui";`
331
332
 
332
333
  ### Card preview
333
334
 
334
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
335
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
335
336
  <div class="rounded-xl border bg-card text-card-foreground shadow w-80"><div class="flex flex-col space-y-1.5 p-6"><h3 class="font-semibold leading-none tracking-tight">Create project</h3><p class="text-sm text-muted-foreground">Deploy your new project in one click.</p></div><div class="p-6 pt-0"><p class="text-sm text-muted-foreground">Project settings go here.</p></div><div class="flex items-center p-6 pt-0"><button type="button" class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground hover:bg-primary/90 h-9 px-4 py-2">Deploy</button></div></div>
336
337
  </div>
337
338
 
338
339
  ### Card usage
339
340
 
340
- ```tsx
341
+ ```tsx fragment
341
342
  <Card>
342
343
  <CardHeader>
343
344
  <CardTitle>Create project</CardTitle>
@@ -376,13 +377,13 @@ Or import directly from the package: `import { Input } from "@zerotal/flow-ui";`
376
377
 
377
378
  ### Input preview
378
379
 
379
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
380
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
380
381
  <div class="flex w-72 flex-col gap-1.5"><label class="flow-label text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">Email</label><input type="text" data-slot="input" class="flex h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none selection:bg-primary selection:text-primary-foreground file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:bg-input/30 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40" placeholder="you@example.com"></div>
381
382
  </div>
382
383
 
383
384
  ### Input usage
384
385
 
385
- ```tsx
386
+ ```tsx fragment
386
387
  <Field label="Email">
387
388
  <Input value={this.form.email} placeholder="you@example.com" />
388
389
  </Field>
@@ -415,13 +416,13 @@ Or import directly from the package: `import { Textarea } from "@zerotal/flow-ui
415
416
 
416
417
  ### Textarea preview
417
418
 
418
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
419
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
419
420
  <div class="w-72"><textarea class="flex min-h-16 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50" placeholder="Tell us about yourself" rows="4"></textarea></div>
420
421
  </div>
421
422
 
422
423
  ### Textarea usage
423
424
 
424
- ```tsx
425
+ ```tsx fragment
425
426
  <Textarea value={this.form.bio} placeholder="Tell us about yourself" rows={4} />
426
427
  ```
427
428
 
@@ -451,13 +452,13 @@ Or import directly from the package: `import { Label } from "@zerotal/flow-ui";`
451
452
 
452
453
  ### Label preview
453
454
 
454
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
455
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
455
456
  <div class="flex flex-col gap-1.5"><label for="email" class="flow-label text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">Email address</label><input type="text" data-slot="input" class="flex h-9 min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none selection:bg-primary selection:text-primary-foreground file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:bg-input/30 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 w-64" id="email" placeholder="you@example.com"></div>
456
457
  </div>
457
458
 
458
459
  ### Label usage
459
460
 
460
- ```tsx
461
+ ```tsx fragment
461
462
  <Label for="email">Email</Label>
462
463
  ```
463
464
 
@@ -487,13 +488,13 @@ Or import directly from the package: `import { Separator } from "@zerotal/flow-u
487
488
 
488
489
  ### Separator preview
489
490
 
490
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
491
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
491
492
  <div class="w-72"><p class="text-sm font-medium text-foreground">Radix Primitives</p><p class="text-sm text-muted-foreground">An open-source UI component library.</p><div role="none" class="shrink-0 bg-border h-px w-full my-3"></div><div class="flex h-5 items-center gap-3 text-sm"><span>Blog</span><div role="none" class="shrink-0 bg-border h-full w-px"></div><span>Docs</span><div role="none" class="shrink-0 bg-border h-full w-px"></div><span>Source</span></div></div>
492
493
  </div>
493
494
 
494
495
  ### Separator usage
495
496
 
496
- ```tsx
497
+ ```tsx fragment
497
498
  <Separator />
498
499
  <Separator orientation="vertical" class="h-6" />
499
500
  ```
@@ -524,13 +525,13 @@ Or import directly from the package: `import { Skeleton } from "@zerotal/flow-ui
524
525
 
525
526
  ### Skeleton preview
526
527
 
527
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
528
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
528
529
  <div class="flex items-center gap-3"><div class="animate-pulse bg-muted h-12 w-12 rounded-full"></div><div class="flex flex-col gap-2"><div class="animate-pulse rounded-md bg-muted h-4 w-40"></div><div class="animate-pulse rounded-md bg-muted h-4 w-28"></div></div></div>
529
530
  </div>
530
531
 
531
532
  ### Skeleton usage
532
533
 
533
- ```tsx
534
+ ```tsx fragment
534
535
  <Skeleton class="h-12 w-12 rounded-full" />
535
536
  <Skeleton class="h-4 w-48" />
536
537
  ```
@@ -560,13 +561,13 @@ Or import directly from the package: `import { Avatar } from "@zerotal/flow-ui";
560
561
 
561
562
  ### Avatar preview
562
563
 
563
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
564
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
564
565
  <div class="flex flex-wrap items-center gap-3"><span class="relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full"><img src="https://i.pravatar.cc/64?img=11" alt="Ada Mokoena" class="aspect-square h-full w-full object-cover"></span><span class="relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full"><span class="flex h-full w-full items-center justify-center rounded-full bg-muted text-sm font-medium text-muted-foreground">AL</span></span><span class="relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full bg-primary text-primary-foreground"><span class="flex h-full w-full items-center justify-center rounded-full bg-muted text-sm font-medium text-muted-foreground">GH</span></span></div>
565
566
  </div>
566
567
 
567
568
  ### Avatar usage
568
569
 
569
- ```tsx
570
+ ```tsx fragment
570
571
  <Avatar src={user.avatarUrl} alt={user.name} fallback="AL" />
571
572
  <Avatar fallback="GH" />
572
573
  ```
@@ -598,13 +599,13 @@ Or import directly from the package: `import { Switch } from "@zerotal/flow-ui";
598
599
 
599
600
  ### Switch preview
600
601
 
601
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
602
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
602
603
  <label class="flex items-center gap-2 text-sm"><button type="button" role="switch" tabindex="0" aria-checked="true" class="flow-switch group inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background bg-input data-checked:bg-primary" data-checked=""><span class="pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform translate-x-0 group-data-checked:translate-x-4"></span></button>Airplane mode</label>
603
604
  </div>
604
605
 
605
606
  ### Switch usage
606
607
 
607
- ```tsx
608
+ ```tsx fragment
608
609
  <Switch bind={this.notifications} />
609
610
  ```
610
611
 
@@ -634,13 +635,13 @@ Or import directly from the package: `import { Checkbox } from "@zerotal/flow-ui
634
635
 
635
636
  ### Checkbox preview
636
637
 
637
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
638
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
638
639
  <label class="flex items-center gap-2 text-sm"><button type="button" role="checkbox" tabindex="0" aria-checked="true" class="flow-checkbox grid h-4 w-4 shrink-0 place-items-center rounded-sm border border-primary text-transparent shadow outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-checked:bg-primary data-checked:text-primary-foreground" data-checked=""><svg viewBox="0 0 16 16" fill="none" class="h-3.5 w-3.5" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3.5 8.5l3 3 6-7"></path></svg></button>Accept terms and conditions</label>
639
640
  </div>
640
641
 
641
642
  ### Checkbox usage
642
643
 
643
- ```tsx
644
+ ```tsx fragment
644
645
  <Checkbox bind={this.agree} />
645
646
  ```
646
647
 
@@ -670,13 +671,13 @@ Or import directly from the package: `import { Select } from "@zerotal/flow-ui";
670
671
 
671
672
  ### Select preview
672
673
 
673
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
674
- <div class="w-56"><select class="flow-select flex h-9 w-full items-center rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"><option value="ca" selected>Canada</option><option value="br">Brazil</option><option value="jp">Japan</option></select></div>
674
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
675
+ <div class="w-56"><select aria-label="Country" class="flow-select flex h-9 w-full items-center rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"><option value="ca" selected>Canada</option><option value="br">Brazil</option><option value="jp">Japan</option></select></div>
675
676
  </div>
676
677
 
677
678
  ### Select usage
678
679
 
679
- ```tsx
680
+ ```tsx fragment
680
681
  <Select bind={this.country} options={[{ label: "Canada", value: "ca" }]} />
681
682
  ```
682
683
 
@@ -707,13 +708,13 @@ Or import directly from the package: `import { RadioGroup } from "@zerotal/flow-
707
708
 
708
709
  ### RadioGroup preview
709
710
 
710
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
711
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
711
712
  <div role="radiogroup" x-data="{}" class="flow-radiogroup grid gap-2 w-56"><div role="radio" aria-checked="false" class="flow-radio flex cursor-pointer items-center justify-center rounded-md border border-input bg-background px-3 py-2 text-sm outline-none transition-colors focus-visible:ring-2 focus-visible:ring-ring data-[checked]:border-primary data-[checked]:bg-primary data-[checked]:text-primary-foreground" tabindex="-1">Free</div><div role="radio" aria-checked="true" class="flow-radio flex cursor-pointer items-center justify-center rounded-md border border-input bg-background px-3 py-2 text-sm outline-none transition-colors focus-visible:ring-2 focus-visible:ring-ring data-[checked]:border-primary data-[checked]:bg-primary data-[checked]:text-primary-foreground" data-checked="" tabindex="0">Pro</div><div role="radio" aria-checked="false" class="flow-radio flex cursor-pointer items-center justify-center rounded-md border border-input bg-background px-3 py-2 text-sm outline-none transition-colors focus-visible:ring-2 focus-visible:ring-ring data-[checked]:border-primary data-[checked]:bg-primary data-[checked]:text-primary-foreground" tabindex="-1">Enterprise</div></div>
712
713
  </div>
713
714
 
714
715
  ### RadioGroup usage
715
716
 
716
- ```tsx
717
+ ```tsx fragment
717
718
  <RadioGroup bind={this.plan} options={[{ label: "Pro", value: "pro" }]} />
718
719
  ```
719
720
 
@@ -744,13 +745,13 @@ Or import directly from the package: `import { Dialog } from "@zerotal/flow-ui";
744
745
 
745
746
  ### Dialog preview
746
747
 
747
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
748
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
748
749
  <button type="button" class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 border border-input bg-background hover:bg-accent hover:text-accent-foreground h-9 px-4 py-2">Edit profile</button>
749
750
  </div>
750
751
 
751
752
  ### Dialog usage
752
753
 
753
- ```tsx
754
+ ```tsx fragment
754
755
  <Button onClick={() => (this.open = true)}>Edit profile</Button>
755
756
 
756
757
  <Dialog show={this.open} title="Edit profile" description="Make changes here.">
@@ -789,13 +790,13 @@ Or import directly from the package: `import { Sheet } from "@zerotal/flow-ui";`
789
790
 
790
791
  ### Sheet preview
791
792
 
792
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
793
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
793
794
  <button type="button" class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 border border-input bg-background hover:bg-accent hover:text-accent-foreground h-9 px-4 py-2">Open sheet</button>
794
795
  </div>
795
796
 
796
797
  ### Sheet usage
797
798
 
798
- ```tsx
799
+ ```tsx fragment
799
800
  <Button onClick={() => (this.open = true)}>Open</Button>
800
801
 
801
802
  <Sheet show={this.open} side="right" title="Edit profile">…</Sheet>
@@ -828,13 +829,13 @@ Or import directly from the package: `import { DropdownMenu } from "@zerotal/flo
828
829
 
829
830
  ### DropdownMenu preview
830
831
 
831
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
832
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
832
833
  <button type="button" class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 border border-input bg-background hover:bg-accent hover:text-accent-foreground h-9 px-4 py-2">Options ▾</button>
833
834
  </div>
834
835
 
835
836
  ### DropdownMenu usage
836
837
 
837
- ```tsx
838
+ ```tsx fragment
838
839
  <DropdownMenu label="Options">
839
840
  <DropdownMenuLabel>My account</DropdownMenuLabel>
840
841
  <DropdownMenuItem onClick={this.profile}>Profile</DropdownMenuItem>
@@ -871,13 +872,13 @@ Or import directly from the package: `import { Tabs } from "@zerotal/flow-ui";`
871
872
 
872
873
  ### Tabs preview
873
874
 
874
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
875
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
875
876
  <div class="w-80"><div x-data="flowTabs({ tab: &quot;0&quot; })" class="flex flex-col"><div role="tablist" x-on:keydown="onKey($event)" class="inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground"><button type="button" role="tab" id="flow-tab-0" aria-controls="flow-tabpanel-0" :aria-selected="tab === &quot;0&quot;" :tabindex="tab === &quot;0&quot; ? 0 : -1" x-on:click="tab = &quot;0&quot;" :class="tab === &quot;0&quot; ? 'bg-background text-foreground shadow-sm' : 'text-muted-foreground'" class="inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium outline-none transition-all focus-visible:ring-2 focus-visible:ring-ring">Account</button><button type="button" role="tab" id="flow-tab-1" aria-controls="flow-tabpanel-1" :aria-selected="tab === &quot;1&quot;" :tabindex="tab === &quot;1&quot; ? 0 : -1" x-on:click="tab = &quot;1&quot;" :class="tab === &quot;1&quot; ? 'bg-background text-foreground shadow-sm' : 'text-muted-foreground'" class="inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium outline-none transition-all focus-visible:ring-2 focus-visible:ring-ring">Password</button></div><div role="tabpanel" id="flow-tabpanel-0" aria-labelledby="flow-tab-0" tabindex="0" x-show="tab === &quot;0&quot;" x-cloak class="mt-2 outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-md"><p class="text-sm text-muted-foreground">Account settings.</p></div><div role="tabpanel" id="flow-tabpanel-1" aria-labelledby="flow-tab-1" tabindex="0" x-show="tab === &quot;1&quot;" x-cloak class="mt-2 outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-md"><p class="text-sm text-muted-foreground">Change your password.</p></div></div></div>
876
877
  </div>
877
878
 
878
879
  ### Tabs usage
879
880
 
880
- ```tsx
881
+ ```tsx fragment
881
882
  <Tabs
882
883
  items={[
883
884
  { label: "Account", content: <AccountForm /> },
@@ -912,13 +913,13 @@ Or import directly from the package: `import { Alert } from "@zerotal/flow-ui";`
912
913
 
913
914
  ### Alert preview
914
915
 
915
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
916
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
916
917
  <div class="flex w-96 flex-col gap-3"><div role="status" x-data="{ shown: true }" x-show="shown" class="relative w-full rounded-lg border px-4 py-3 text-sm bg-background text-foreground flex items-start gap-3"><div class="min-w-0 flex-1"><div class="mb-1 font-medium leading-none tracking-tight">Heads up!</div><div class="text-sm [&amp;_p]:leading-relaxed">You can add components to your app using the CLI.</div></div></div><div role="alert" x-data="{ shown: true }" x-show="shown" class="relative w-full rounded-lg border px-4 py-3 text-sm border-destructive/50 text-destructive flex items-start gap-3"><div class="min-w-0 flex-1"><div class="mb-1 font-medium leading-none tracking-tight">Error</div><div class="text-sm [&amp;_p]:leading-relaxed">Your session has expired.</div></div></div></div>
917
918
  </div>
918
919
 
919
920
  ### Alert usage
920
921
 
921
- ```tsx
922
+ ```tsx fragment
922
923
  <Alert title="Heads up!">You can add components to your app.</Alert>
923
924
  <Alert variant="destructive" title="Error">Something went wrong.</Alert>
924
925
  ```
@@ -950,13 +951,13 @@ Or import directly from the package: `import { Tooltip } from "@zerotal/flow-ui"
950
951
 
951
952
  ### Tooltip preview
952
953
 
953
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
954
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
954
955
  <button type="button" class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 border border-input bg-background hover:bg-accent hover:text-accent-foreground h-9 w-9">+</button>
955
956
  </div>
956
957
 
957
958
  ### Tooltip usage
958
959
 
959
- ```tsx
960
+ ```tsx fragment
960
961
  <Tooltip content="Add to library">
961
962
  <Button size="icon">+</Button>
962
963
  </Tooltip>
@@ -988,13 +989,13 @@ Or import directly from the package: `import { Table } from "@zerotal/flow-ui";`
988
989
 
989
990
  ### Table preview
990
991
 
991
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
992
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
992
993
  <div class="w-96"><table class="w-full caption-bottom border-collapse text-sm"><thead class="[&amp;_tr]:border-b [&amp;_tr]:border-border"><tr><th scope="col" class="h-10 px-2 text-left align-middle font-medium text-muted-foreground">Name</th><th scope="col" class="h-10 px-2 text-left align-middle font-medium text-muted-foreground">Role</th></tr></thead><tbody><tr flow:key="Ada Lovelace" class="border-b border-border transition-colors hover:bg-muted/50"><td class="p-2 align-middle">Ada Lovelace</td><td class="p-2 align-middle">Engineer</td></tr><tr flow:key="Alan Turing" class="border-b border-border transition-colors hover:bg-muted/50"><td class="p-2 align-middle">Alan Turing</td><td class="p-2 align-middle">Researcher</td></tr></tbody></table></div>
993
994
  </div>
994
995
 
995
996
  ### Table usage
996
997
 
997
- ```tsx
998
+ ```tsx fragment
998
999
  <Table
999
1000
  columns={[
1000
1001
  { key: "name", label: "Name", sortable: true },
@@ -1034,13 +1035,13 @@ Or import directly from the package: `import { Popover } from "@zerotal/flow-ui"
1034
1035
 
1035
1036
  ### Popover preview
1036
1037
 
1037
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
1038
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
1038
1039
  <div x-data="{ open: false }" class="flow-popover relative inline-block"><span x-on:click="open = !open" :aria-expanded="open" :data-open="open ? '' : null" role="button" tabindex="0" class="flow-popover-button cursor-pointer outline-none"><button type="button" class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 border border-input bg-background hover:bg-accent hover:text-accent-foreground h-9 px-4 py-2">Options</button></span><div x-show="open" x-cloak x-transition x-on:click.outside="open = false" x-on:keydown.escape.window="open = false" :data-open="open ? '' : null" class="flow-popover-panel absolute top-full mt-2 left-0 z-50 min-w-[8rem] rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md outline-none"><p class="text-sm">Anything at all.</p></div></div>
1039
1040
  </div>
1040
1041
 
1041
1042
  ### Popover usage
1042
1043
 
1043
- ```tsx
1044
+ ```tsx fragment
1044
1045
  <Popover trigger={<Button variant="outline">Options</Button>}>
1045
1046
  <p class="text-sm">Anything at all.</p>
1046
1047
  </Popover>
@@ -1074,7 +1075,7 @@ Or import directly from the package: `import { HoverCard } from "@zerotal/flow-u
1074
1075
 
1075
1076
  ### HoverCard preview
1076
1077
 
1077
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
1078
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
1078
1079
  <div x-data="{
1079
1080
  open: false,
1080
1081
  t: null,
@@ -1085,7 +1086,7 @@ Or import directly from the package: `import { HoverCard } from "@zerotal/flow-u
1085
1086
 
1086
1087
  ### HoverCard usage
1087
1088
 
1088
- ```tsx
1089
+ ```tsx fragment
1089
1090
  <HoverCard trigger={<a href="/users/1">@ada</a>}>
1090
1091
  <p class="text-sm font-medium">Ada Mokoena</p>
1091
1092
  </HoverCard>
@@ -1119,13 +1120,13 @@ Or import directly from the package: `import { AlertDialog } from "@zerotal/flow
1119
1120
 
1120
1121
  ### AlertDialog preview
1121
1122
 
1122
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
1123
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
1123
1124
  <div role="dialog" aria-modal="true" class="fixed inset-0 z-50 flex items-center justify-center p-4"><div class="absolute inset-0 bg-black/50"></div><div class="relative z-10 w-full max-w-lg rounded-lg border border-border bg-background p-6 text-foreground shadow-lg" flow:transition><div class="mb-4 flex flex-col gap-1.5 pr-6"><h2 class="text-lg font-semibold leading-none tracking-tight">Delete this product?</h2><p class="text-sm text-muted-foreground">It will be removed from every order. This cannot be undone.</p></div><div class="mt-6 flex flex-col-reverse gap-2 sm:flex-row sm:justify-end"><button type="button" class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 border border-input bg-background hover:bg-accent hover:text-accent-foreground h-9 px-4 py-2">Cancel</button><button type="button" class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 bg-destructive text-destructive-foreground hover:bg-destructive/90 h-9 px-4 py-2">Delete</button></div></div></div>
1124
1125
  </div>
1125
1126
 
1126
1127
  ### AlertDialog usage
1127
1128
 
1128
- ```tsx
1129
+ ```tsx fragment
1129
1130
  <AlertDialog
1130
1131
  show={this.confirming}
1131
1132
  title="Delete this product?"
@@ -1164,13 +1165,13 @@ Or import directly from the package: `import { Command } from "@zerotal/flow-ui"
1164
1165
 
1165
1166
  ### Command preview
1166
1167
 
1167
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
1168
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
1168
1169
  <p class="text-sm text-muted-foreground">Mounted hidden; press <kbd class="pointer-events-none inline-flex h-5 min-w-5 select-none items-center justify-center gap-1 rounded border border-border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground" x-data="{ mac: false }" x-init="mac = /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent)" x-text="mac ? '⌘' : 'Ctrl'">Ctrl</kbd> <kbd class="pointer-events-none inline-flex h-5 min-w-5 select-none items-center justify-center gap-1 rounded border border-border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground">K</kbd> to open it.</p><div x-data="flowCommand({&quot;items&quot;:[{&quot;label&quot;:&quot;Products&quot;,&quot;href&quot;:&quot;#&quot;,&quot;group&quot;:&quot;Go to&quot;},{&quot;label&quot;:&quot;Orders&quot;,&quot;href&quot;:&quot;#&quot;,&quot;group&quot;:&quot;Go to&quot;},{&quot;label&quot;:&quot;New order&quot;,&quot;href&quot;:&quot;#&quot;,&quot;group&quot;:&quot;Create&quot;}],&quot;hotkey&quot;:&quot;k&quot;})" x-show="open" x-cloak x-transition.opacity x-on:click="if ($event.target === $el) hide()" x-on:keydown.escape.window="hide()" class="fixed inset-0 z-50 flex items-start justify-center bg-black/50 p-4 pt-[12vh]"><div role="dialog" aria-modal="true" aria-label="Command menu" class="w-full max-w-lg overflow-hidden rounded-xl border border-border bg-popover text-popover-foreground shadow-2xl"><div class="flex items-center gap-2 border-b border-border px-3"><svg class="h-4 w-4 shrink-0 text-muted-foreground" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><circle cx="11" cy="11" r="8"></circle><path d="m21 21-4.3-4.3"></path></svg><input x-ref="field" type="text" role="combobox" aria-expanded="true" aria-controls="flow-command-list" autocomplete="off" placeholder="Search…" x-model="query" x-on:input="active = 0" x-on:keydown.arrow-down.prevent="move(1)" x-on:keydown.arrow-up.prevent="move(-1)" x-on:keydown.enter.prevent="choose()" class="h-12 w-full bg-transparent text-sm outline-none placeholder:text-muted-foreground"></div><div id="flow-command-list" role="listbox" class="max-h-80 overflow-y-auto p-2"><template x-for="(item, i) in results()" :key="item.label + i"><div><div x-show="startsGroup(i)" x-text="item.group" class="px-2 pb-1 pt-3 text-[11px] font-medium uppercase tracking-wide text-muted-foreground"></div><div role="option" :aria-selected="active === i" x-on:click="choose(i)" x-on:mousemove="active = i" :class="active === i &amp;&amp; 'bg-accent text-accent-foreground'" class="flex cursor-pointer items-center gap-2 rounded-md px-2 py-2 text-sm"><span class="flex-1 truncate" x-text="item.label"></span><span x-show="item.shortcut" x-text="item.shortcut" class="text-[11px] text-muted-foreground"></span></div></div></template><p x-show="results().length === 0" class="px-4 py-8 text-center text-sm text-muted-foreground">Nothing found.</p></div></div></div>
1169
1170
  </div>
1170
1171
 
1171
1172
  ### Command usage
1172
1173
 
1173
- ```tsx
1174
+ ```tsx fragment
1174
1175
  <Command
1175
1176
  items={[
1176
1177
  { label: "Products", href: "/admin/products", group: "Go to" },
@@ -1207,13 +1208,13 @@ Or import directly from the package: `import { ContextMenu } from "@zerotal/flow
1207
1208
 
1208
1209
  ### ContextMenu preview
1209
1210
 
1210
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
1211
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
1211
1212
  <div x-data="{ open: false, x: 0, y: 0 }" x-on:contextmenu=" $event.preventDefault(); open = true; $nextTick(() =&gt; { const menu = $refs.menu; const w = menu.offsetWidth, h = menu.offsetHeight; x = Math.min($event.clientX, window.innerWidth - w - 8); y = Math.min($event.clientY, window.innerHeight - h - 8); }); " class="contents"><div class="rounded-md border border-dashed border-border px-4 py-6 text-center text-sm text-muted-foreground">Right-click me</div><div x-ref="menu" x-show="open" x-cloak x-on:click.outside="open = false" x-on:keydown.escape.window="open = false" x-bind:style="`position:fixed;left:${x}px;top:${y}px`" role="menu" class="z-50 min-w-44 rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md"><button type="button" role="menuitem" class="flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm outline-none hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50"><span class="flex-1">Open</span><span class="text-xs text-muted-foreground">↵</span></button><div role="separator" class="-mx-1 my-1 h-px bg-border"></div><button type="button" role="menuitem" class="flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm outline-none hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 text-destructive hover:bg-destructive/10"><span class="flex-1">Delete</span></button></div></div>
1212
1213
  </div>
1213
1214
 
1214
1215
  ### ContextMenu usage
1215
1216
 
1216
- ```tsx
1217
+ ```tsx fragment
1217
1218
  <ContextMenu
1218
1219
  items={[
1219
1220
  { label: "Open", action: "$flow.open(id)" },
@@ -1251,13 +1252,13 @@ Or import directly from the package: `import { Menubar } from "@zerotal/flow-ui"
1251
1252
 
1252
1253
  ### Menubar preview
1253
1254
 
1254
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
1255
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
1255
1256
  <div x-data="{ open: -1 }" x-on:click.outside="open = -1" x-on:keydown.escape.window="open = -1" role="menubar" class="flex items-center gap-0.5 rounded-md border border-border bg-card p-1"><div class="relative"><button type="button" role="menuitem" x-on:click="open = open === 0 ? -1 : 0" x-on:mouseenter="if (open !== -1) open = 0" x-bind:aria-expanded="open === 0" x-bind:class="open === 0 &amp;&amp; 'bg-accent text-accent-foreground'" class="rounded-sm px-3 py-1 text-sm font-medium outline-none transition-colors hover:bg-accent hover:text-accent-foreground">File</button><div x-show="open === 0" x-cloak x-transition role="menu" class="absolute left-0 top-full z-50 mt-1 min-w-48 rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md"><button type="button" role="menuitem" class="flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm outline-none hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50"><span class="flex-1">New</span><span class="text-xs text-muted-foreground">⌘N</span></button><div role="separator" class="-mx-1 my-1 h-px bg-border"></div><button type="button" role="menuitem" class="flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm outline-none hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50"><span class="flex-1">Export</span></button></div></div><div class="relative"><button type="button" role="menuitem" x-on:click="open = open === 1 ? -1 : 1" x-on:mouseenter="if (open !== -1) open = 1" x-bind:aria-expanded="open === 1" x-bind:class="open === 1 &amp;&amp; 'bg-accent text-accent-foreground'" class="rounded-sm px-3 py-1 text-sm font-medium outline-none transition-colors hover:bg-accent hover:text-accent-foreground">Edit</button><div x-show="open === 1" x-cloak x-transition role="menu" class="absolute left-0 top-full z-50 mt-1 min-w-48 rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md"><button type="button" role="menuitem" class="flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm outline-none hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50"><span class="flex-1">Undo</span><span class="text-xs text-muted-foreground">⌘Z</span></button><button type="button" role="menuitem" class="flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm outline-none hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50"><span class="flex-1">Redo</span><span class="text-xs text-muted-foreground">⇧⌘Z</span></button></div></div><div class="relative"><button type="button" role="menuitem" x-on:click="open = open === 2 ? -1 : 2" x-on:mouseenter="if (open !== -1) open = 2" x-bind:aria-expanded="open === 2" x-bind:class="open === 2 &amp;&amp; 'bg-accent text-accent-foreground'" class="rounded-sm px-3 py-1 text-sm font-medium outline-none transition-colors hover:bg-accent hover:text-accent-foreground">View</button><div x-show="open === 2" x-cloak x-transition role="menu" class="absolute left-0 top-full z-50 mt-1 min-w-48 rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md"><button type="button" role="menuitem" class="flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm outline-none hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50"><span class="flex-1">Zoom in</span></button><button type="button" role="menuitem" class="flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm outline-none hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50"><span class="flex-1">Zoom out</span></button></div></div></div>
1256
1257
  </div>
1257
1258
 
1258
1259
  ### Menubar usage
1259
1260
 
1260
- ```tsx
1261
+ ```tsx fragment
1261
1262
  <Menubar
1262
1263
  menus={[
1263
1264
  { label: "File", items: [{ label: "New", shortcut: "⌘N" }] },
@@ -1292,13 +1293,13 @@ Or import directly from the package: `import { NavigationMenu } from "@zerotal/f
1292
1293
 
1293
1294
  ### NavigationMenu preview
1294
1295
 
1295
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
1296
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
1296
1297
  <nav class="relative flex items-center gap-1"><a href="#" flow:navigate class="inline-flex h-9 items-center gap-1 rounded-md px-3 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground outline-none focus-visible:ring-2 focus-visible:ring-ring">Docs</a><div x-data="{ open: false }" x-on:mouseenter="open = true" x-on:mouseleave="open = false" x-on:focusin="open = true" x-on:focusout="open = false" class="relative"><button type="button" x-bind:aria-expanded="open" class="inline-flex h-9 items-center gap-1 rounded-md px-3 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground outline-none focus-visible:ring-2 focus-visible:ring-ring">Products<svg class="h-3 w-3 transition-transform" x-bind:class="open &amp;&amp; 'rotate-180'" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="m6 9 6 6 6-6"></path></svg></button><div x-show="open" x-cloak x-transition class="absolute left-0 top-full z-50 mt-1.5 rounded-lg border border-border bg-popover p-2 text-popover-foreground shadow-lg w-72 space-y-1"><a href="#" flow:navigate class="flex gap-3 rounded-md p-3 transition-colors hover:bg-accent hover:text-accent-foreground"><span class="min-w-0"><span class="block text-sm font-medium">Admin</span><span class="mt-0.5 block text-xs leading-snug text-muted-foreground">Declarative back office</span></span></a><a href="#" flow:navigate class="flex gap-3 rounded-md p-3 transition-colors hover:bg-accent hover:text-accent-foreground"><span class="min-w-0"><span class="block text-sm font-medium">Flow</span><span class="mt-0.5 block text-xs leading-snug text-muted-foreground">Server-driven reactivity</span></span></a></div></div></nav>
1297
1298
  </div>
1298
1299
 
1299
1300
  ### NavigationMenu usage
1300
1301
 
1301
- ```tsx
1302
+ ```tsx fragment
1302
1303
  <NavigationMenu
1303
1304
  items={[
1304
1305
  { label: "Docs", href: "/docs" },
@@ -1333,13 +1334,13 @@ Or import directly from the package: `import { Sidebar } from "@zerotal/flow-ui"
1333
1334
 
1334
1335
  ### Sidebar preview
1335
1336
 
1336
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
1337
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
1337
1338
  <div class="h-64 overflow-hidden rounded-lg border border-border"><aside class="flex w-64 flex-col border-r border-border bg-card"><a href="/" flow:navigate class="flex h-14 shrink-0 items-center gap-2 border-b border-border px-4"><span class="min-w-0"><span class="block truncate text-sm font-semibold">Zerotal</span><span class="block truncate text-[11px] text-muted-foreground">Back office</span></span></a><nav class="flex-1 space-y-4 overflow-y-auto p-3"><div class="space-y-1"><p class="px-2.5 pb-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground/70">Shop</p><a href="/admin/products" flow:navigate aria-current="page" class="group flex items-center gap-2.5 rounded-md px-2.5 py-2 text-sm font-medium transition-colors hover:bg-accent/50 hover:text-foreground [&amp;[aria-current]]:bg-accent [&amp;[aria-current]]:text-accent-foreground bg-accent text-accent-foreground"><span class="truncate">Products</span><span class="ml-auto inline-flex min-w-5 items-center justify-center rounded-full px-1.5 py-0.5 text-[10px] font-semibold leading-none bg-muted text-muted-foreground">12</span></a><a href="/admin/orders" flow:navigate class="group flex items-center gap-2.5 rounded-md px-2.5 py-2 text-sm font-medium transition-colors text-muted-foreground hover:bg-accent/50 hover:text-foreground [&amp;[aria-current]]:bg-accent [&amp;[aria-current]]:text-accent-foreground"><span class="truncate">Orders</span></a></div><div class="space-y-1"><p class="px-2.5 pb-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground/70">System</p><a href="/admin/settings" flow:navigate class="group flex items-center gap-2.5 rounded-md px-2.5 py-2 text-sm font-medium transition-colors text-muted-foreground hover:bg-accent/50 hover:text-foreground [&amp;[aria-current]]:bg-accent [&amp;[aria-current]]:text-accent-foreground"><span class="truncate">Settings</span></a></div></nav></aside></div>
1338
1339
  </div>
1339
1340
 
1340
1341
  ### Sidebar usage
1341
1342
 
1342
- ```tsx
1343
+ ```tsx fragment
1343
1344
  <Sidebar
1344
1345
  brand="Zerotal"
1345
1346
  tagline="Back office"
@@ -1376,13 +1377,13 @@ Or import directly from the package: `import { Breadcrumb } from "@zerotal/flow-
1376
1377
 
1377
1378
  ### Breadcrumb preview
1378
1379
 
1379
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
1380
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
1380
1381
  <nav aria-label="Breadcrumb" class="text-xs text-muted-foreground"><ol class="flex flex-wrap items-center gap-1.5"><li class="inline-flex items-center gap-1.5"><a href="#" flow:navigate class="inline-flex items-center gap-1 transition-colors hover:text-foreground">Dashboard</a></li><li class="inline-flex items-center gap-1.5"><svg class="h-3.5 w-3.5 shrink-0 text-muted-foreground/60" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 18 6-6-6-6"></path></svg><a href="#" flow:navigate class="inline-flex items-center gap-1 transition-colors hover:text-foreground">Products</a></li><li class="inline-flex items-center gap-1.5"><svg class="h-3.5 w-3.5 shrink-0 text-muted-foreground/60" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 18 6-6-6-6"></path></svg><span aria-current="page" class="inline-flex items-center gap-1 text-foreground">Desk Lamp</span></li></ol></nav>
1381
1382
  </div>
1382
1383
 
1383
1384
  ### Breadcrumb usage
1384
1385
 
1385
- ```tsx
1386
+ ```tsx fragment
1386
1387
  <Breadcrumb
1387
1388
  items={[
1388
1389
  { label: "Dashboard", href: "/admin" },
@@ -1419,13 +1420,13 @@ Or import directly from the package: `import { Pagination } from "@zerotal/flow-
1419
1420
 
1420
1421
  ### Pagination preview
1421
1422
 
1422
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
1423
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
1423
1424
  <nav aria-label="Pagination" class="flex flex-wrap items-center justify-between gap-3"><p class="text-sm text-muted-foreground">61–80 of 231</p><div class="flex items-center gap-1"><a href="#" flow:navigate aria-label="Previous page" class="inline-flex h-8 min-w-8 items-center justify-center rounded-md px-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground"><svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m15 18-6-6 6-6"></path></svg></a><a href="#" flow:navigate aria-label="Page 1" class="inline-flex h-8 min-w-8 items-center justify-center rounded-md px-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground">1</a><a href="#" flow:navigate aria-label="Page 2" class="inline-flex h-8 min-w-8 items-center justify-center rounded-md px-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground">2</a><a href="#" flow:navigate aria-label="Page 3" class="inline-flex h-8 min-w-8 items-center justify-center rounded-md px-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground">3</a><a href="#" flow:navigate aria-current="page" class="inline-flex h-8 min-w-8 items-center justify-center rounded-md px-2 text-sm font-medium transition-colors bg-primary text-primary-foreground">4</a><a href="#" flow:navigate aria-label="Page 5" class="inline-flex h-8 min-w-8 items-center justify-center rounded-md px-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground">5</a><a href="#" flow:navigate aria-label="Page 6" class="inline-flex h-8 min-w-8 items-center justify-center rounded-md px-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground">6</a><span class="px-1 text-sm text-muted-foreground" aria-hidden="true">…</span><a href="#" flow:navigate aria-label="Page 12" class="inline-flex h-8 min-w-8 items-center justify-center rounded-md px-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground">12</a><a href="#" flow:navigate aria-label="Next page" class="inline-flex h-8 min-w-8 items-center justify-center rounded-md px-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground"><svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 18 6-6-6-6"></path></svg></a></div></nav>
1424
1425
  </div>
1425
1426
 
1426
1427
  ### Pagination usage
1427
1428
 
1428
- ```tsx
1429
+ ```tsx fragment
1429
1430
  <Pagination
1430
1431
  page={p.page}
1431
1432
  lastPage={p.lastPage}
@@ -1464,13 +1465,13 @@ Or import directly from the package: `import { Field } from "@zerotal/flow-ui";`
1464
1465
 
1465
1466
  ### Field preview
1466
1467
 
1467
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
1468
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
1468
1469
  <div class="w-full max-w-sm space-y-4"><div class="space-y-1.5"><label for="flow-field-1" class="block text-sm font-medium leading-none text-foreground">Email<span class="ml-0.5 text-destructive" aria-hidden="true">*</span></label><div class="space-y-1.5"><input type="email" data-slot="input" class="flex h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none selection:bg-primary selection:text-primary-foreground file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:bg-input/30 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40" placeholder="ada@example.com" id="flow-field-1" aria-describedby="flow-field-1-description" aria-required="true"><p id="flow-field-1-description" class="text-xs text-muted-foreground">We never share it.</p></div></div><div class="space-y-1.5"><label for="flow-field-2" class="block text-sm font-medium leading-none text-foreground">Password</label><div class="space-y-1.5"><input type="password" data-slot="input" class="flex h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none selection:bg-primary selection:text-primary-foreground file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:bg-input/30 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40" id="flow-field-2" aria-describedby="flow-field-2-error" aria-invalid="true"><p id="flow-field-2-error" role="alert" class="text-xs font-medium text-destructive">Must be at least 8 characters.</p></div></div></div>
1469
1470
  </div>
1470
1471
 
1471
1472
  ### Field usage
1472
1473
 
1473
- ```tsx
1474
+ ```tsx fragment
1474
1475
  <Field label="Email" description="We never share it." error={errors.email} required>
1475
1476
  <Input type="email" flow:model="form.email" />
1476
1477
  </Field>
@@ -1505,13 +1506,13 @@ Or import directly from the package: `import { InputGroup } from "@zerotal/flow-
1505
1506
 
1506
1507
  ### InputGroup preview
1507
1508
 
1508
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
1509
- <div class="w-full max-w-sm space-y-3"><div class="flex w-full items-stretch"><div class="relative flex-1"><span class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3 text-sm text-muted-foreground">R</span><div class="[&amp;&gt;input]:w-full [&amp;&gt;input]:pl-8"><input type="text" data-slot="input" class="flex h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none selection:bg-primary selection:text-primary-foreground file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:bg-input/30 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40" placeholder="0.00"></div></div></div><div class="flex w-full items-stretch"><div class="relative flex-1"><div class="[&amp;&gt;input]:w-full [&amp;&gt;input]:rounded-r-none"><input type="text" data-slot="input" class="flex h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none selection:bg-primary selection:text-primary-foreground file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:bg-input/30 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40" value="kln_live_8f3a"></div></div><span class="inline-flex shrink-0 items-center [&amp;&gt;button]:rounded-l-none"><button type="button" class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 border border-input bg-background hover:bg-accent hover:text-accent-foreground h-9 px-4 py-2">Copy</button></span></div></div>
1509
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
1510
+ <div class="w-full max-w-sm space-y-3"><div class="flex w-full items-stretch"><div class="relative flex-1"><span class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3 text-sm text-muted-foreground">R</span><div class="[&amp;&gt;input]:w-full [&amp;&gt;input]:pl-8"><input type="text" data-slot="input" class="flex h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none selection:bg-primary selection:text-primary-foreground file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:bg-input/30 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40" placeholder="0.00" aria-label="Price in rands"></div></div></div><div class="flex w-full items-stretch"><div class="relative flex-1"><div class="[&amp;&gt;input]:w-full [&amp;&gt;input]:rounded-r-none"><input type="text" data-slot="input" class="flex h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none selection:bg-primary selection:text-primary-foreground file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:bg-input/30 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40" value="kln_live_8f3a" aria-label="API key"></div></div><span class="inline-flex shrink-0 items-center [&amp;&gt;button]:rounded-l-none"><button type="button" class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 border border-input bg-background hover:bg-accent hover:text-accent-foreground h-9 px-4 py-2">Copy</button></span></div></div>
1510
1511
  </div>
1511
1512
 
1512
1513
  ### InputGroup usage
1513
1514
 
1514
- ```tsx
1515
+ ```tsx fragment
1515
1516
  <InputGroup prefix="R"><Input flow:model="form.price" /></InputGroup>
1516
1517
  <InputGroup addonAfter={<Button>Copy</Button>}><Input value={key} /></InputGroup>
1517
1518
  ```
@@ -1544,13 +1545,13 @@ Or import directly from the package: `import { InputOTP } from "@zerotal/flow-ui
1544
1545
 
1545
1546
  ### InputOTP preview
1546
1547
 
1547
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
1548
- <div x-data="{ value: '' }" class="relative inline-flex" x-on:click="$refs.field.focus()"><input x-ref="field" type="text" inputmode="numeric" autocomplete="one-time-code" maxlength="6" pattern="[0-9]*" x-model="value" class="absolute inset-0 z-10 h-full w-full cursor-default opacity-0"><div class="flex items-center gap-2"><div class="flex h-10 w-10 items-center justify-center rounded-md border border-input bg-background text-sm font-medium tabular-nums transition-colors" x-bind:class="value.length === 0 &amp;&amp; 'ring-2 ring-ring border-ring'"><span x-text="value[0] || ''"></span></div><div class="flex h-10 w-10 items-center justify-center rounded-md border border-input bg-background text-sm font-medium tabular-nums transition-colors" x-bind:class="value.length === 1 &amp;&amp; 'ring-2 ring-ring border-ring'"><span x-text="value[1] || ''"></span></div><div class="flex h-10 w-10 items-center justify-center rounded-md border border-input bg-background text-sm font-medium tabular-nums transition-colors" x-bind:class="value.length === 2 &amp;&amp; 'ring-2 ring-ring border-ring'"><span x-text="value[2] || ''"></span></div><span class="w-2"></span><div class="flex h-10 w-10 items-center justify-center rounded-md border border-input bg-background text-sm font-medium tabular-nums transition-colors" x-bind:class="value.length === 3 &amp;&amp; 'ring-2 ring-ring border-ring'"><span x-text="value[3] || ''"></span></div><div class="flex h-10 w-10 items-center justify-center rounded-md border border-input bg-background text-sm font-medium tabular-nums transition-colors" x-bind:class="value.length === 4 &amp;&amp; 'ring-2 ring-ring border-ring'"><span x-text="value[4] || ''"></span></div><div class="flex h-10 w-10 items-center justify-center rounded-md border border-input bg-background text-sm font-medium tabular-nums transition-colors" x-bind:class="value.length === 5 &amp;&amp; 'ring-2 ring-ring border-ring'"><span x-text="value[5] || ''"></span></div></div></div>
1548
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
1549
+ <div x-data="{ value: '' }" class="relative inline-flex" x-on:click="$refs.field.focus()"><input x-ref="field" type="text" inputmode="numeric" autocomplete="one-time-code" maxlength="6" pattern="[0-9]*" x-model="value" class="absolute inset-0 z-10 h-full w-full cursor-default opacity-0" aria-label="One-time code"><div class="flex items-center gap-2"><div class="flex h-10 w-10 items-center justify-center rounded-md border border-input bg-background text-sm font-medium tabular-nums transition-colors" x-bind:class="value.length === 0 &amp;&amp; 'ring-2 ring-ring border-ring'"><span x-text="value[0] || ''"></span></div><div class="flex h-10 w-10 items-center justify-center rounded-md border border-input bg-background text-sm font-medium tabular-nums transition-colors" x-bind:class="value.length === 1 &amp;&amp; 'ring-2 ring-ring border-ring'"><span x-text="value[1] || ''"></span></div><div class="flex h-10 w-10 items-center justify-center rounded-md border border-input bg-background text-sm font-medium tabular-nums transition-colors" x-bind:class="value.length === 2 &amp;&amp; 'ring-2 ring-ring border-ring'"><span x-text="value[2] || ''"></span></div><span class="w-2"></span><div class="flex h-10 w-10 items-center justify-center rounded-md border border-input bg-background text-sm font-medium tabular-nums transition-colors" x-bind:class="value.length === 3 &amp;&amp; 'ring-2 ring-ring border-ring'"><span x-text="value[3] || ''"></span></div><div class="flex h-10 w-10 items-center justify-center rounded-md border border-input bg-background text-sm font-medium tabular-nums transition-colors" x-bind:class="value.length === 4 &amp;&amp; 'ring-2 ring-ring border-ring'"><span x-text="value[4] || ''"></span></div><div class="flex h-10 w-10 items-center justify-center rounded-md border border-input bg-background text-sm font-medium tabular-nums transition-colors" x-bind:class="value.length === 5 &amp;&amp; 'ring-2 ring-ring border-ring'"><span x-text="value[5] || ''"></span></div></div></div>
1549
1550
  </div>
1550
1551
 
1551
1552
  ### InputOTP usage
1552
1553
 
1553
- ```tsx
1554
+ ```tsx fragment
1554
1555
  <InputOTP length={6} groupAfter={3} flow:model="form.code" />
1555
1556
  ```
1556
1557
 
@@ -1581,13 +1582,13 @@ Or import directly from the package: `import { Combobox } from "@zerotal/flow-ui
1581
1582
 
1582
1583
  ### Combobox preview
1583
1584
 
1584
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
1585
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
1585
1586
  <div class="w-full max-w-sm"><div x-data="{ open: false, active: -1, query: '' }" class="flow-combobox relative"><input type="text" role="combobox" autocomplete="off" aria-autocomplete="list" aria-controls="flow-combobox-list" :aria-expanded="open" placeholder="Search brands…" :value="query" x-on:input="onInput($event)" x-on:focus="openList()" x-on:click="openList()" x-on:keydown="onKey($event)" class="flow-combobox-input flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm shadow-sm transition-colors placeholder:text-muted-foreground outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50"><ul id="flow-combobox-list" role="listbox" x-show="open" x-cloak x-on:click.outside="close()" :aria-activedescendant="null" class="flow-combobox-options absolute z-50 mt-1 max-h-60 w-full overflow-y-auto rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md"><li role="option" data-value="&quot;1&quot;" data-label="Acme" aria-selected="false" :aria-selected="isSelected(&quot;1&quot;)" :data-selected="isSelected(&quot;1&quot;) ? '' : null" :data-active="active === 0 ? '' : null" x-on:click="selectEl($event.currentTarget)" x-on:mousemove="active = 0" class="flow-combobox-option cursor-pointer rounded-sm px-2 py-1.5 text-sm outline-none data-active:bg-accent data-active:text-accent-foreground data-selected:font-medium data-disabled:pointer-events-none data-disabled:opacity-50" x-show="!query || &quot;acme&quot;.includes(query.toLowerCase())">Acme</li><li role="option" data-value="&quot;2&quot;" data-label="Globex" aria-selected="false" :aria-selected="isSelected(&quot;2&quot;)" :data-selected="isSelected(&quot;2&quot;) ? '' : null" :data-active="active === 1 ? '' : null" x-on:click="selectEl($event.currentTarget)" x-on:mousemove="active = 1" class="flow-combobox-option cursor-pointer rounded-sm px-2 py-1.5 text-sm outline-none data-active:bg-accent data-active:text-accent-foreground data-selected:font-medium data-disabled:pointer-events-none data-disabled:opacity-50" x-show="!query || &quot;globex&quot;.includes(query.toLowerCase())">Globex</li><li role="option" data-value="&quot;3&quot;" data-label="Initech" aria-selected="false" :aria-selected="isSelected(&quot;3&quot;)" :data-selected="isSelected(&quot;3&quot;) ? '' : null" :data-active="active === 2 ? '' : null" x-on:click="selectEl($event.currentTarget)" x-on:mousemove="active = 2" class="flow-combobox-option cursor-pointer rounded-sm px-2 py-1.5 text-sm outline-none data-active:bg-accent data-active:text-accent-foreground data-selected:font-medium data-disabled:pointer-events-none data-disabled:opacity-50" x-show="!query || &quot;initech&quot;.includes(query.toLowerCase())">Initech</li></ul></div></div>
1586
1587
  </div>
1587
1588
 
1588
1589
  ### Combobox usage
1589
1590
 
1590
- ```tsx
1591
+ ```tsx fragment
1591
1592
  <Combobox bind={this.brandId} options={brands} placeholder="Search brands…" />
1592
1593
  ```
1593
1594
 
@@ -1618,13 +1619,13 @@ Or import directly from the package: `import { Slider } from "@zerotal/flow-ui";
1618
1619
 
1619
1620
  ### Slider preview
1620
1621
 
1621
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
1622
- <div class="w-full max-w-sm"><div value="64" x-data="flowSlider({&quot;name&quot;:null,&quot;min&quot;:0,&quot;max&quot;:100,&quot;step&quot;:1})" :data-dragging="dragging ? '' : null" class="flow-slider flex items-center gap-3"><input type="range" min="0" max="100" step="1" value="0" style="background:linear-gradient(to right, var(--primary) 0%, var(--secondary) 0%)" :style="`background:linear-gradient(to right, var(--primary) ${percent()}%, var(--secondary) ${percent()}%)`" x-model.number="value" x-on:input="onInput($event)" x-on:change="commit()" x-on:keyup.debounce.200ms="commit()" class="flow-slider-input h-2 w-full cursor-pointer appearance-none rounded-full outline-none disabled:cursor-not-allowed disabled:opacity-50 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background [&amp;::-webkit-slider-thumb]:h-4 [&amp;::-webkit-slider-thumb]:w-4 [&amp;::-webkit-slider-thumb]:appearance-none [&amp;::-webkit-slider-thumb]:rounded-full [&amp;::-webkit-slider-thumb]:border-2 [&amp;::-webkit-slider-thumb]:border-primary [&amp;::-webkit-slider-thumb]:bg-background [&amp;::-webkit-slider-thumb]:shadow [&amp;::-webkit-slider-thumb]:transition-transform [&amp;::-webkit-slider-thumb]:hover:scale-110 [&amp;::-moz-range-thumb]:h-4 [&amp;::-moz-range-thumb]:w-4 [&amp;::-moz-range-thumb]:rounded-full [&amp;::-moz-range-thumb]:border-2 [&amp;::-moz-range-thumb]:border-primary [&amp;::-moz-range-thumb]:bg-background [&amp;::-moz-range-thumb]:shadow"><span class="w-14 shrink-0 text-right text-sm tabular-nums text-muted-foreground"><span x-text="value"></span></span></div></div>
1622
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
1623
+ <div class="w-full max-w-sm"><div value="64" aria-label="Volume" x-data="flowSlider({&quot;name&quot;:null,&quot;min&quot;:0,&quot;max&quot;:100,&quot;step&quot;:1})" :data-dragging="dragging ? '' : null" class="flow-slider flex items-center gap-3"><input type="range" min="0" max="100" step="1" value="0" style="background:linear-gradient(to right, var(--primary) 0%, var(--secondary) 0%)" :style="`background:linear-gradient(to right, var(--primary) ${percent()}%, var(--secondary) ${percent()}%)`" x-model.number="value" x-on:input="onInput($event)" x-on:change="commit()" x-on:keyup.debounce.200ms="commit()" class="flow-slider-input h-2 w-full cursor-pointer appearance-none rounded-full outline-none disabled:cursor-not-allowed disabled:opacity-50 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background [&amp;::-webkit-slider-thumb]:h-4 [&amp;::-webkit-slider-thumb]:w-4 [&amp;::-webkit-slider-thumb]:appearance-none [&amp;::-webkit-slider-thumb]:rounded-full [&amp;::-webkit-slider-thumb]:border-2 [&amp;::-webkit-slider-thumb]:border-primary [&amp;::-webkit-slider-thumb]:bg-background [&amp;::-webkit-slider-thumb]:shadow [&amp;::-webkit-slider-thumb]:transition-transform [&amp;::-webkit-slider-thumb]:hover:scale-110 [&amp;::-moz-range-thumb]:h-4 [&amp;::-moz-range-thumb]:w-4 [&amp;::-moz-range-thumb]:rounded-full [&amp;::-moz-range-thumb]:border-2 [&amp;::-moz-range-thumb]:border-primary [&amp;::-moz-range-thumb]:bg-background [&amp;::-moz-range-thumb]:shadow"><span class="w-14 shrink-0 text-right text-sm tabular-nums text-muted-foreground"><span x-text="value"></span></span></div></div>
1623
1624
  </div>
1624
1625
 
1625
1626
  ### Slider usage
1626
1627
 
1627
- ```tsx
1628
+ ```tsx fragment
1628
1629
  <Slider value={this.volume} max={100} showValue />
1629
1630
  ```
1630
1631
 
@@ -1656,13 +1657,13 @@ Or import directly from the package: `import { Toggle } from "@zerotal/flow-ui";
1656
1657
 
1657
1658
  ### Toggle preview
1658
1659
 
1659
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
1660
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
1660
1661
  <div class="flex flex-wrap items-center gap-3"><button type="button" aria-pressed="true" class="inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 hover:bg-muted hover:text-muted-foreground h-9 px-2.5 bg-accent text-accent-foreground">B</button><button type="button" aria-pressed="false" class="inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 hover:bg-muted hover:text-muted-foreground border border-input bg-transparent h-9 px-2.5">I</button><div value="grid" role="radiogroup" x-data="flowToggleGroup({&quot;name&quot;:null,&quot;multiple&quot;:false})" class="flow-toggle-group inline-flex items-center gap-1 rounded-md"><button type="button" aria-pressed="false" :aria-pressed="isOn(&quot;list&quot;)" :data-pressed="isOn(&quot;list&quot;) ? '' : null" x-on:click="toggle(&quot;list&quot;)" class="flow-toggle inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 hover:bg-muted hover:text-muted-foreground border border-input bg-transparent h-9 px-2.5 data-pressed:bg-accent data-pressed:text-accent-foreground">List</button><button type="button" aria-pressed="false" :aria-pressed="isOn(&quot;grid&quot;)" :data-pressed="isOn(&quot;grid&quot;) ? '' : null" x-on:click="toggle(&quot;grid&quot;)" class="flow-toggle inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 hover:bg-muted hover:text-muted-foreground border border-input bg-transparent h-9 px-2.5 data-pressed:bg-accent data-pressed:text-accent-foreground">Grid</button></div></div>
1661
1662
  </div>
1662
1663
 
1663
1664
  ### Toggle usage
1664
1665
 
1665
- ```tsx
1666
+ ```tsx fragment
1666
1667
  <Toggle pressed={this.bold}>B</Toggle>
1667
1668
  <ToggleGroup value={this.view} options={[
1668
1669
  { value: "list", label: "List" }, { value: "grid", label: "Grid" },
@@ -1697,13 +1698,13 @@ Or import directly from the package: `import { ButtonGroup } from "@zerotal/flow
1697
1698
 
1698
1699
  ### ButtonGroup preview
1699
1700
 
1700
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
1701
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
1701
1702
  <div role="group" class="inline-flex flex-row [&amp;&gt;*:not(:first-child)]:rounded-l-none [&amp;&gt;*:not(:last-child)]:rounded-r-none [&amp;&gt;*:not(:first-child)]:-ml-px [&amp;&gt;*:focus-visible]:relative [&amp;&gt;*:focus-visible]:z-10"><button type="button" class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 border border-input bg-background hover:bg-accent hover:text-accent-foreground h-9 px-4 py-2">Day</button><button type="button" class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 border border-input bg-background hover:bg-accent hover:text-accent-foreground h-9 px-4 py-2">Week</button><button type="button" class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 border border-input bg-background hover:bg-accent hover:text-accent-foreground h-9 px-4 py-2">Month</button></div>
1702
1703
  </div>
1703
1704
 
1704
1705
  ### ButtonGroup usage
1705
1706
 
1706
- ```tsx
1707
+ ```tsx fragment
1707
1708
  <ButtonGroup>
1708
1709
  <Button variant="outline">Day</Button>
1709
1710
  <Button variant="outline">Week</Button>
@@ -1736,13 +1737,13 @@ Or import directly from the package: `import { Calendar } from "@zerotal/flow-ui
1736
1737
 
1737
1738
  ### Calendar preview
1738
1739
 
1739
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
1740
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
1740
1741
  <div class="rounded-lg border border-border bg-card p-3"><div class="mb-2 flex items-center justify-between px-1"><span class="w-7"></span><p class="text-sm font-medium">July 2026</p><span class="w-7"></span></div><div class="grid grid-cols-7 gap-px"><div class="pb-1 text-center text-[11px] font-medium text-muted-foreground">Mon</div><div class="pb-1 text-center text-[11px] font-medium text-muted-foreground">Tue</div><div class="pb-1 text-center text-[11px] font-medium text-muted-foreground">Wed</div><div class="pb-1 text-center text-[11px] font-medium text-muted-foreground">Thu</div><div class="pb-1 text-center text-[11px] font-medium text-muted-foreground">Fri</div><div class="pb-1 text-center text-[11px] font-medium text-muted-foreground">Sat</div><div class="pb-1 text-center text-[11px] font-medium text-muted-foreground">Sun</div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors text-muted-foreground/40"><span class="">29</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors text-muted-foreground/40"><span class="">30</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">1</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">2</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">3</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">4</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">5</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">6</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">7</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">8</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">9</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">10</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">11</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">12</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">13</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors bg-primary text-primary-foreground"><span class="">14</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">15</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">16</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">17</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">18</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">19</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">20</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">21</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">22</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">23</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">24</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">25</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">26</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">27</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">28</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">29</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">30</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">31</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors text-muted-foreground/40"><span class="">1</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors text-muted-foreground/40"><span class="">2</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors text-muted-foreground/40"><span class="">3</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors text-muted-foreground/40"><span class="">4</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors text-muted-foreground/40"><span class="">5</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors text-muted-foreground/40"><span class="">6</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors text-muted-foreground/40"><span class="">7</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors text-muted-foreground/40"><span class="">8</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors text-muted-foreground/40"><span class="">9</span></div></div></div>
1741
1742
  </div>
1742
1743
 
1743
1744
  ### Calendar usage
1744
1745
 
1745
- ```tsx
1746
+ ```tsx fragment
1746
1747
  <Calendar value={this.due} onSelect={this.pick} />
1747
1748
  <Calendar month="2026-07" events={[{ date: "2026-07-14", label: "Launch" }]} />
1748
1749
  ```
@@ -1776,13 +1777,13 @@ Or import directly from the package: `import { DatePicker } from "@zerotal/flow-
1776
1777
 
1777
1778
  ### DatePicker preview
1778
1779
 
1779
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
1780
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
1780
1781
  <div class="w-56"><div x-data="{ open: false }" class="flow-popover relative inline-block"><span x-on:click="open = !open" :aria-expanded="open" :data-open="open ? '' : null" role="button" tabindex="0" class="flow-popover-button cursor-pointer outline-none"><span class="inline-flex h-9 w-full items-center gap-2 rounded-md border border-input bg-background px-3 text-sm transition-colors hover:bg-accent hover:text-accent-foreground"><svg class="h-4 w-4 shrink-0 text-muted-foreground" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><rect x="3" y="4" width="18" height="18" rx="2"></rect><path d="M16 2v4M8 2v4M3 10h18"></path></svg><span>14 Jul 2026</span></span></span><div x-show="open" x-cloak x-transition x-on:click.outside="open = false" x-on:keydown.escape.window="open = false" :data-open="open ? '' : null" class="flow-popover-panel absolute top-full mt-2 left-0 z-50 min-w-[8rem] rounded-md border border-border bg-popover text-popover-foreground shadow-md outline-none p-0"><div class="rounded-lg border-border bg-card p-3 border-0"><div class="mb-2 flex items-center justify-between px-1"><span class="w-7"></span><p class="text-sm font-medium">July 2026</p><span class="w-7"></span></div><div class="grid grid-cols-7 gap-px"><div class="pb-1 text-center text-[11px] font-medium text-muted-foreground">Mon</div><div class="pb-1 text-center text-[11px] font-medium text-muted-foreground">Tue</div><div class="pb-1 text-center text-[11px] font-medium text-muted-foreground">Wed</div><div class="pb-1 text-center text-[11px] font-medium text-muted-foreground">Thu</div><div class="pb-1 text-center text-[11px] font-medium text-muted-foreground">Fri</div><div class="pb-1 text-center text-[11px] font-medium text-muted-foreground">Sat</div><div class="pb-1 text-center text-[11px] font-medium text-muted-foreground">Sun</div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors text-muted-foreground/40"><span class="">29</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors text-muted-foreground/40"><span class="">30</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">1</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">2</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">3</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">4</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">5</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">6</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">7</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">8</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">9</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">10</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">11</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">12</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">13</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors bg-primary text-primary-foreground"><span class="">14</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">15</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">16</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">17</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">18</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">19</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">20</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">21</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">22</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">23</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">24</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">25</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">26</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">27</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">28</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">29</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">30</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors"><span class="">31</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors text-muted-foreground/40"><span class="">1</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors text-muted-foreground/40"><span class="">2</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors text-muted-foreground/40"><span class="">3</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors text-muted-foreground/40"><span class="">4</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors text-muted-foreground/40"><span class="">5</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors text-muted-foreground/40"><span class="">6</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors text-muted-foreground/40"><span class="">7</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors text-muted-foreground/40"><span class="">8</span></div><div class="h-9 items-center justify-center flex flex-col rounded-md text-sm transition-colors text-muted-foreground/40"><span class="">9</span></div></div></div></div></div></div>
1781
1782
  </div>
1782
1783
 
1783
1784
  ### DatePicker usage
1784
1785
 
1785
- ```tsx
1786
+ ```tsx fragment
1786
1787
  <DatePicker value={this.due} onSelect={this.setDue} />
1787
1788
  ```
1788
1789
 
@@ -1814,13 +1815,13 @@ Or import directly from the package: `import { Toaster } from "@zerotal/flow-ui"
1814
1815
 
1815
1816
  ### Toaster preview
1816
1817
 
1817
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
1818
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
1818
1819
  <p class="text-sm text-muted-foreground">Mounted once per layout; every <code class="font-mono text-xs">page.flash()</code> lands in it.</p>
1819
1820
  </div>
1820
1821
 
1821
1822
  ### Toaster usage
1822
1823
 
1823
- ```tsx
1824
+ ```tsx fragment
1824
1825
  <Toaster position="bottom-right" />;
1825
1826
  // then anywhere on the server:
1826
1827
  page.flash("Saved.", "success");
@@ -1853,13 +1854,13 @@ Or import directly from the package: `import { Progress } from "@zerotal/flow-ui
1853
1854
 
1854
1855
  ### Progress preview
1855
1856
 
1856
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
1857
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
1857
1858
  <div class="w-full max-w-sm space-y-3"><div class="flex items-center gap-3"><div role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="62" class="relative h-2 w-full overflow-hidden rounded-full bg-secondary"><div class="h-full rounded-full bg-primary transition-[width] duration-300 ease-out" style="width:62%"></div></div><span class="shrink-0 text-xs tabular-nums text-muted-foreground">62%</span></div><div class="flex items-center gap-3"><div role="progressbar" aria-valuemin="0" aria-valuemax="100" class="relative h-2 w-full overflow-hidden rounded-full bg-secondary"><div class="h-full rounded-full bg-primary transition-[width] duration-300 ease-out w-1/3 animate-[flow-progress_1.2s_ease-in-out_infinite]"></div></div></div></div>
1858
1859
  </div>
1859
1860
 
1860
1861
  ### Progress usage
1861
1862
 
1862
- ```tsx
1863
+ ```tsx fragment
1863
1864
  <Progress value={imported} max={total} showValue />
1864
1865
  <Progress /> {/* indeterminate */}
1865
1866
  ```
@@ -1892,13 +1893,13 @@ Or import directly from the package: `import { Spinner } from "@zerotal/flow-ui"
1892
1893
 
1893
1894
  ### Spinner preview
1894
1895
 
1895
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
1896
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
1896
1897
  <div class="flex flex-wrap items-center gap-3"><span role="status" class="inline-flex items-center"><svg class="animate-spin text-current h-3.5 w-3.5" viewBox="0 0 24 24" fill="none" aria-hidden="true"><circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="3" opacity="0.2"></circle><path d="M22 12a10 10 0 0 1-10 10" stroke="currentColor" stroke-width="3" stroke-linecap="round"></path></svg><span class="sr-only">Loading</span></span><span role="status" class="inline-flex items-center"><svg class="animate-spin text-current h-5 w-5" viewBox="0 0 24 24" fill="none" aria-hidden="true"><circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="3" opacity="0.2"></circle><path d="M22 12a10 10 0 0 1-10 10" stroke="currentColor" stroke-width="3" stroke-linecap="round"></path></svg><span class="sr-only">Loading</span></span><span role="status" class="inline-flex items-center"><svg class="animate-spin text-current h-8 w-8" viewBox="0 0 24 24" fill="none" aria-hidden="true"><circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="3" opacity="0.2"></circle><path d="M22 12a10 10 0 0 1-10 10" stroke="currentColor" stroke-width="3" stroke-linecap="round"></path></svg><span class="sr-only">Loading</span></span></div>
1897
1898
  </div>
1898
1899
 
1899
1900
  ### Spinner usage
1900
1901
 
1901
- ```tsx
1902
+ ```tsx fragment
1902
1903
  <Spinner />
1903
1904
  <Button disabled><Spinner size="sm" /> Saving…</Button>
1904
1905
  ```
@@ -1929,13 +1930,13 @@ Or import directly from the package: `import { Empty } from "@zerotal/flow-ui";`
1929
1930
 
1930
1931
  ### Empty preview
1931
1932
 
1932
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
1933
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
1933
1934
  <div class="flex flex-col items-center justify-center px-6 py-12 text-center rounded-lg border border-dashed border-border"><p class="text-sm font-medium text-foreground">No orders yet</p><p class="mt-1 max-w-sm text-sm text-muted-foreground">Orders appear here as customers place them.</p><div class="mt-4 flex items-center gap-2"><button type="button" class="inline-flex items-center justify-center gap-2 whitespace-nowrap font-medium transition-colors outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground hover:bg-primary/90 h-8 rounded-md px-3 text-xs">New order</button></div></div>
1934
1935
  </div>
1935
1936
 
1936
1937
  ### Empty usage
1937
1938
 
1938
- ```tsx
1939
+ ```tsx fragment
1939
1940
  <Empty
1940
1941
  icon={icon}
1941
1942
  title="No orders yet"
@@ -1972,13 +1973,13 @@ Or import directly from the package: `import { Kbd } from "@zerotal/flow-ui";`
1972
1973
 
1973
1974
  ### Kbd preview
1974
1975
 
1975
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
1976
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
1976
1977
  <div class="flex flex-wrap items-center gap-3"><span class="inline-flex items-center gap-1"><kbd class="pointer-events-none inline-flex h-5 min-w-5 select-none items-center justify-center gap-1 rounded border border-border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground" x-data="{ mac: false }" x-init="mac = /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent)" x-text="mac ? '⌘' : 'Ctrl'">Ctrl</kbd><kbd class="pointer-events-none inline-flex h-5 min-w-5 select-none items-center justify-center gap-1 rounded border border-border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground">K</kbd></span><span class="inline-flex items-center gap-1"><kbd class="pointer-events-none inline-flex h-5 min-w-5 select-none items-center justify-center gap-1 rounded border border-border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground">⇧</kbd><kbd class="pointer-events-none inline-flex h-5 min-w-5 select-none items-center justify-center gap-1 rounded border border-border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground">↵</kbd></span></div>
1977
1978
  </div>
1978
1979
 
1979
1980
  ### Kbd usage
1980
1981
 
1981
- ```tsx
1982
+ ```tsx fragment
1982
1983
  <KbdMod /> <Kbd>K</Kbd>
1983
1984
  ```
1984
1985
 
@@ -2008,13 +2009,13 @@ Or import directly from the package: `import { Accordion } from "@zerotal/flow-u
2008
2009
 
2009
2010
  ### Accordion preview
2010
2011
 
2011
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
2012
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
2012
2013
  <div class="w-full max-w-md"><div x-data="{ active: 0 }" class="flow-accordion divide-y divide-border border-y border-border"><div class="flow-accordion-item" x-id="['flow-accordion']"><button type="button" x-on:click="active = active === 0 ? -1 : 0" :aria-expanded="active === 0" :data-open="active === 0 ? '' : null" :aria-controls="$id('flow-accordion')" class="flow-accordion-button flex w-full items-center justify-between gap-4 py-4 text-left text-sm font-medium transition-colors hover:underline outline-none focus-visible:ring-2 focus-visible:ring-ring [&amp;[data-open]&gt;svg]:rotate-180">Shipping</button><div :id="$id('flow-accordion')" x-show="active === 0" x-cloak :data-open="active === 0 ? '' : null" class="flow-accordion-panel pb-4 text-sm text-muted-foreground"><p>Ships in 2–3 days.</p></div></div><div class="flow-accordion-item" x-id="['flow-accordion']"><button type="button" x-on:click="active = active === 1 ? -1 : 1" :aria-expanded="active === 1" :data-open="active === 1 ? '' : null" :aria-controls="$id('flow-accordion')" class="flow-accordion-button flex w-full items-center justify-between gap-4 py-4 text-left text-sm font-medium transition-colors hover:underline outline-none focus-visible:ring-2 focus-visible:ring-ring [&amp;[data-open]&gt;svg]:rotate-180">Returns</button><div :id="$id('flow-accordion')" x-show="active === 1" x-cloak :data-open="active === 1 ? '' : null" class="flow-accordion-panel pb-4 text-sm text-muted-foreground"><p>30 days, no questions.</p></div></div></div></div>
2013
2014
  </div>
2014
2015
 
2015
2016
  ### Accordion usage
2016
2017
 
2017
- ```tsx
2018
+ ```tsx fragment
2018
2019
  <Accordion
2019
2020
  items={[
2020
2021
  { label: "Shipping", content: <p>Ships in 2–3 days.</p> },
@@ -2050,13 +2051,13 @@ Or import directly from the package: `import { Collapsible } from "@zerotal/flow
2050
2051
 
2051
2052
  ### Collapsible preview
2052
2053
 
2053
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
2054
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
2054
2055
  <div class="w-full max-w-md"><div x-data="{ open: false }" x-id="['flow-disclosure']" class="flow-disclosure"><button type="button" x-on:click="open = !open" :aria-expanded="open" :data-open="open ? '' : null" :aria-controls="$id('flow-disclosure')" class="flow-disclosure-button inline-flex items-center gap-1.5 rounded-md text-sm font-medium text-foreground transition-colors hover:text-muted-foreground outline-none focus-visible:ring-2 focus-visible:ring-ring [&amp;[data-open]&gt;svg]:rotate-180">Advanced</button><div :id="$id('flow-disclosure')" x-show="open" x-cloak :data-open="open ? '' : null" class="flow-disclosure-panel pt-2"><p class="text-sm text-muted-foreground">Rarely-changed settings live here.</p></div></div></div>
2055
2056
  </div>
2056
2057
 
2057
2058
  ### Collapsible usage
2058
2059
 
2059
- ```tsx
2060
+ ```tsx fragment
2060
2061
  <Collapsible label="Advanced">
2061
2062
  <Field label="Timeout">
2062
2063
  <Input />
@@ -2091,13 +2092,13 @@ Or import directly from the package: `import { ScrollArea } from "@zerotal/flow-
2091
2092
 
2092
2093
  ### ScrollArea preview
2093
2094
 
2094
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
2095
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
2095
2096
  <div class="relative overflow-y-auto overflow-x-hidden [scrollbar-width:thin] [scrollbar-color:var(--border)_transparent] [&amp;::-webkit-scrollbar]:h-2 [&amp;::-webkit-scrollbar]:w-2 [&amp;::-webkit-scrollbar-track]:bg-transparent [&amp;::-webkit-scrollbar-thumb]:rounded-full [&amp;::-webkit-scrollbar-thumb]:bg-border [&amp;::-webkit-scrollbar-thumb:hover]:bg-muted-foreground/40 h-32 w-full max-w-sm rounded-md border border-border p-3"><div class="space-y-2 text-sm"><p>Row 1</p><p>Row 2</p><p>Row 3</p><p>Row 4</p><p>Row 5</p><p>Row 6</p><p>Row 7</p><p>Row 8</p><p>Row 9</p><p>Row 10</p><p>Row 11</p><p>Row 12</p></div></div>
2096
2097
  </div>
2097
2098
 
2098
2099
  ### ScrollArea usage
2099
2100
 
2100
- ```tsx
2101
+ ```tsx fragment
2101
2102
  <ScrollArea class="h-72">…long list…</ScrollArea>
2102
2103
  ```
2103
2104
 
@@ -2128,13 +2129,13 @@ Or import directly from the package: `import { Resizable } from "@zerotal/flow-u
2128
2129
 
2129
2130
  ### Resizable preview
2130
2131
 
2131
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
2132
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
2132
2133
  <div x-data="{ size: 35, dragging: false, start(e) { this.dragging = true; e.target.setPointerCapture(e.pointerId); }, move(e) { if (!this.dragging) return; const box = $el.getBoundingClientRect(); const raw = ((e.clientX - box.left) / box.width) * 100; this.size = Math.min(90, Math.max(10, raw)); }, stop(e) { this.dragging = false; if (e.pointerId != null) e.target.releasePointerCapture?.(e.pointerId); }, nudge(by) { this.size = Math.min(90, Math.max(10, this.size + by)); } }" x-on:pointermove="move($event)" x-on:pointerup="stop($event)" class="flex w-full flex-row h-32 rounded-md border border-border"><div x-bind:style="`flex-basis:${size}%`" class="min-w-0 overflow-hidden"><div class="h-full bg-muted/40 p-3 text-sm">Sidebar</div></div><div role="separator" tabindex="0" aria-orientation="vertical" x-bind:aria-valuenow="Math.round(size)" aria-valuemin="10" aria-valuemax="90" aria-label="Resize panes" x-on:pointerdown="start($event)" x-on:keydown="if ($event.key === 'ArrowLeft') { $event.preventDefault(); nudge(-2) } if ($event.key === 'ArrowRight') { $event.preventDefault(); nudge(2) }" x-bind:class="dragging &amp;&amp; 'bg-primary'" class="group relative shrink-0 bg-border transition-colors hover:bg-primary/50 outline-none focus-visible:bg-primary w-px cursor-col-resize"><span class="absolute -inset-x-1.5 inset-y-0"></span></div><div class="min-w-0 flex-1 overflow-hidden"><div class="h-full p-3 text-sm">Content</div></div></div>
2133
2134
  </div>
2134
2135
 
2135
2136
  ### Resizable usage
2136
2137
 
2137
- ```tsx
2138
+ ```tsx fragment
2138
2139
  <Resizable start={<Tree />} end={<Editor />} defaultSize={30} />
2139
2140
  ```
2140
2141
 
@@ -2166,13 +2167,13 @@ Or import directly from the package: `import { Carousel } from "@zerotal/flow-ui
2166
2167
 
2167
2168
  ### Carousel preview
2168
2169
 
2169
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
2170
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
2170
2171
  <div x-data="{ atStart: true, atEnd: false, sync() { const el = $refs.track; this.atStart = el.scrollLeft &lt;= 1; this.atEnd = el.scrollLeft + el.clientWidth &gt;= el.scrollWidth - 1; }, page(dir) { $refs.track.scrollBy({ left: dir * $refs.track.clientWidth * 0.9, behavior: 'smooth' }); } }" x-init="sync()" role="region" aria-roledescription="carousel" aria-label="Carousel" class="relative"><div x-ref="track" x-on:scroll.debounce.50ms="sync()" class="flex snap-x snap-mandatory gap-4 overflow-x-auto scroll-smooth pb-2 [scrollbar-width:none] [&amp;::-webkit-scrollbar]:hidden"><div class="shrink-0 snap-start w-40"><div class="flex h-24 items-center justify-center rounded-lg border border-border bg-muted/40 text-sm">Slide 1</div></div><div class="shrink-0 snap-start w-40"><div class="flex h-24 items-center justify-center rounded-lg border border-border bg-muted/40 text-sm">Slide 2</div></div><div class="shrink-0 snap-start w-40"><div class="flex h-24 items-center justify-center rounded-lg border border-border bg-muted/40 text-sm">Slide 3</div></div><div class="shrink-0 snap-start w-40"><div class="flex h-24 items-center justify-center rounded-lg border border-border bg-muted/40 text-sm">Slide 4</div></div><div class="shrink-0 snap-start w-40"><div class="flex h-24 items-center justify-center rounded-lg border border-border bg-muted/40 text-sm">Slide 5</div></div><div class="shrink-0 snap-start w-40"><div class="flex h-24 items-center justify-center rounded-lg border border-border bg-muted/40 text-sm">Slide 6</div></div></div><button type="button" aria-label="Previous" x-on:click="page(-1)" x-bind:disabled="atStart" class="absolute top-1/2 z-10 inline-flex h-8 w-8 -translate-y-1/2 items-center justify-center rounded-full border border-border bg-background shadow-sm transition-opacity hover:bg-accent disabled:pointer-events-none disabled:opacity-0 left-0 -translate-x-1/2"><svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m15 18-6-6 6-6"></path></svg></button><button type="button" aria-label="Next" x-on:click="page(1)" x-bind:disabled="atEnd" class="absolute top-1/2 z-10 inline-flex h-8 w-8 -translate-y-1/2 items-center justify-center rounded-full border border-border bg-background shadow-sm transition-opacity hover:bg-accent disabled:pointer-events-none disabled:opacity-0 right-0 translate-x-1/2"><svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9 18 6-6-6-6"></path></svg></button></div>
2171
2172
  </div>
2172
2173
 
2173
2174
  ### Carousel usage
2174
2175
 
2175
- ```tsx
2176
+ ```tsx fragment
2176
2177
  <Carousel
2177
2178
  items={products.map((p) => (
2178
2179
  <ProductCard product={p} />
@@ -2207,13 +2208,13 @@ Or import directly from the package: `import { AspectRatio } from "@zerotal/flow
2207
2208
 
2208
2209
  ### AspectRatio preview
2209
2210
 
2210
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
2211
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
2211
2212
  <div class="w-64"><div style="aspect-ratio:1.7777777777777777" class="relative w-full overflow-hidden rounded-lg border border-border bg-muted/40"><div class="flex h-full items-center justify-center text-sm text-muted-foreground">16 / 9</div></div></div>
2212
2213
  </div>
2213
2214
 
2214
2215
  ### AspectRatio usage
2215
2216
 
2216
- ```tsx
2217
+ ```tsx fragment
2217
2218
  <AspectRatio ratio={16 / 9}>
2218
2219
  <img src={cover} class="h-full w-full object-cover" />
2219
2220
  </AspectRatio>
@@ -2245,13 +2246,13 @@ Or import directly from the package: `import { Item } from "@zerotal/flow-ui";`
2245
2246
 
2246
2247
  ### Item preview
2247
2248
 
2248
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
2249
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
2249
2250
  <div class="w-full max-w-md rounded-lg border border-border p-1"><div class="flex w-full items-center gap-3 rounded-md px-3 py-2 text-left"><span class="min-w-0 flex-1"><span class="block truncate text-sm font-medium">Team</span><span class="block truncate text-xs text-muted-foreground">4 members</span></span><span class="flex shrink-0 items-center gap-2"><span class="inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80">Owner</span></span></div><div class="flex w-full items-center gap-3 rounded-md px-3 py-2 text-left transition-colors hover:bg-accent hover:text-accent-foreground"><span class="min-w-0 flex-1"><span class="block truncate text-sm font-medium">Billing</span><span class="block truncate text-xs text-muted-foreground">Visa ending 4242</span></span></div></div>
2250
2251
  </div>
2251
2252
 
2252
2253
  ### Item usage
2253
2254
 
2254
- ```tsx
2255
+ ```tsx fragment
2255
2256
  <Item title="Team" description="4 members" action={<Button size="sm">Manage</Button>} />
2256
2257
  ```
2257
2258
 
@@ -2283,13 +2284,13 @@ Or import directly from the package: `import { Chart } from "@zerotal/flow-ui";`
2283
2284
 
2284
2285
  ### Chart preview
2285
2286
 
2286
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
2287
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
2287
2288
  <div class="w-full space-y-6"><figure class="relative w-full" x-data="flowChart({&quot;points&quot;:[{&quot;x&quot;:0.07333333333333333,&quot;label&quot;:&quot;Mon&quot;,&quot;values&quot;:[{&quot;label&quot;:&quot;Orders&quot;,&quot;value&quot;:&quot;12&quot;,&quot;color&quot;:&quot;var(--primary)&quot;}]},{&quot;x&quot;:0.2277777777777778,&quot;label&quot;:&quot;Tue&quot;,&quot;values&quot;:[{&quot;label&quot;:&quot;Orders&quot;,&quot;value&quot;:&quot;19&quot;,&quot;color&quot;:&quot;var(--primary)&quot;}]},{&quot;x&quot;:0.38222222222222224,&quot;label&quot;:&quot;Wed&quot;,&quot;values&quot;:[{&quot;label&quot;:&quot;Orders&quot;,&quot;value&quot;:&quot;14&quot;,&quot;color&quot;:&quot;var(--primary)&quot;}]},{&quot;x&quot;:0.5366666666666666,&quot;label&quot;:&quot;Thu&quot;,&quot;values&quot;:[{&quot;label&quot;:&quot;Orders&quot;,&quot;value&quot;:&quot;27&quot;,&quot;color&quot;:&quot;var(--primary)&quot;}]},{&quot;x&quot;:0.6911111111111111,&quot;label&quot;:&quot;Fri&quot;,&quot;values&quot;:[{&quot;label&quot;:&quot;Orders&quot;,&quot;value&quot;:&quot;22&quot;,&quot;color&quot;:&quot;var(--primary)&quot;}]},{&quot;x&quot;:0.8455555555555556,&quot;label&quot;:&quot;Sat&quot;,&quot;values&quot;:[{&quot;label&quot;:&quot;Orders&quot;,&quot;value&quot;:&quot;31&quot;,&quot;color&quot;:&quot;var(--primary)&quot;}]},{&quot;x&quot;:1,&quot;label&quot;:&quot;Sun&quot;,&quot;values&quot;:[{&quot;label&quot;:&quot;Orders&quot;,&quot;value&quot;:&quot;25&quot;,&quot;color&quot;:&quot;var(--primary)&quot;}]}]})" x-on:pointermove="onMove($event)" x-on:pointerleave="onLeave()"><svg viewBox="0 0 600 160" width="100%" height="160" preserveAspectRatio="none" role="img" aria-label="Orders: 12, 19, 14, 27, 22, 31, 25" class="overflow-visible"><line x1="44" y1="138" x2="600" y2="138" stroke="var(--border)" stroke-width="1"></line><text x="36" y="142" text-anchor="end" font-size="11" fill="var(--muted-foreground)">0</text><line x1="44" y1="103.5" x2="600" y2="103.5" stroke="var(--border)" stroke-width="1"></line><text x="36" y="107.5" text-anchor="end" font-size="11" fill="var(--muted-foreground)">13</text><line x1="44" y1="69" x2="600" y2="69" stroke="var(--border)" stroke-width="1"></line><text x="36" y="73" text-anchor="end" font-size="11" fill="var(--muted-foreground)">25</text><line x1="44" y1="34.5" x2="600" y2="34.5" stroke="var(--border)" stroke-width="1"></line><text x="36" y="38.5" text-anchor="end" font-size="11" fill="var(--muted-foreground)">38</text><line x1="44" y1="0" x2="600" y2="0" stroke="var(--border)" stroke-width="1"></line><text x="36" y="4" text-anchor="end" font-size="11" fill="var(--muted-foreground)">50</text><g transform="translate(44,0)"><path d="M0.00,104.88 L92.67,85.56 L185.33,99.36 L278.00,63.48 L370.67,77.28 L463.33,52.44 L556.00,69.00 L556,138 L0,138 Z" fill="var(--primary)" opacity="0.12"></path><path d="M0.00,104.88 L92.67,85.56 L185.33,99.36 L278.00,63.48 L370.67,77.28 L463.33,52.44 L556.00,69.00" fill="none" stroke="var(--primary)" stroke-width="2" stroke-linejoin="round" stroke-linecap="round" vector-effect="non-scaling-stroke" x-bind:style="`stroke-dasharray:2000;stroke-dashoffset:${ready ? 0 : 2000};transition:stroke-dashoffset .7s ease-out`"></path></g><text x="44" y="154" text-anchor="middle" font-size="11" fill="var(--muted-foreground)">Mon</text><text x="136.66666666666669" y="154" text-anchor="middle" font-size="11" fill="var(--muted-foreground)">Tue</text><text x="229.33333333333334" y="154" text-anchor="middle" font-size="11" fill="var(--muted-foreground)">Wed</text><text x="322" y="154" text-anchor="middle" font-size="11" fill="var(--muted-foreground)">Thu</text><text x="414.6666666666667" y="154" text-anchor="middle" font-size="11" fill="var(--muted-foreground)">Fri</text><text x="507.33333333333337" y="154" text-anchor="middle" font-size="11" fill="var(--muted-foreground)">Sat</text><text x="600" y="154" text-anchor="middle" font-size="11" fill="var(--muted-foreground)">Sun</text></svg><div x-show="hover &gt;= 0" x-cloak class="pointer-events-none absolute inset-y-0 w-px bg-border" x-bind:style="`left:${tipX}px`"></div><div x-show="hover &gt;= 0" x-cloak x-transition.opacity class="pointer-events-none absolute top-2 z-10 min-w-32 -translate-x-1/2 rounded-md border border-border bg-popover px-2.5 py-2 text-xs shadow-md" x-bind:style="`left:${tipX}px`"><p class="mb-1 font-medium" x-text="tip()?.label"></p><template x-for="row in (tip()?.values ?? [])" :key="row.label"><span class="flex items-center gap-1.5"><span class="h-2 w-2 shrink-0 rounded-sm" x-bind:style="`background:${row.color}`"></span><span class="text-muted-foreground" x-text="row.label"></span><span class="ml-auto font-medium tabular-nums" x-text="row.value"></span></span></template></div></figure><figure class="flex items-center gap-6"><svg viewBox="0 0 140 140" width="140" height="140" role="img" aria-label="Series: 82, 24, 6"><path d="M70,2 A68,68 0 1 1 2.4275697272595096,77.61358437502494 L28.1050932309009,74.72042231251547 A42.16,42.16 0 1 0 70,27.840000000000003 Z" fill="var(--primary)"></path><path d="M2.4275697272595096,77.61358437502494 A68,68 0 0 1 47.54102378704863,5.815933539031008 L56.07543474797015,30.20587879419923 A42.16,42.16 0 0 0 28.1050932309009,74.72042231251547 Z" fill="var(--flow-toast-success, #16a34a)"></path><path d="M47.54102378704863,5.815933539031008 A68,68 0 0 1 69.99999999999999,2 L69.99999999999999,27.840000000000003 A42.16,42.16 0 0 0 56.07543474797015,30.20587879419923 Z" fill="var(--flow-toast-warning, #d97706)"></path></svg><figcaption class="space-y-1.5 text-sm"><span class="flex items-center gap-2"><span class="h-2.5 w-2.5 shrink-0 rounded-sm" style="background:var(--primary)"></span><span class="text-muted-foreground">Paid</span><span class="ml-auto font-medium tabular-nums">82</span></span><span class="flex items-center gap-2"><span class="h-2.5 w-2.5 shrink-0 rounded-sm" style="background:var(--flow-toast-success, #16a34a)"></span><span class="text-muted-foreground">Pending</span><span class="ml-auto font-medium tabular-nums">24</span></span><span class="flex items-center gap-2"><span class="h-2.5 w-2.5 shrink-0 rounded-sm" style="background:var(--flow-toast-warning, #d97706)"></span><span class="text-muted-foreground">Refunded</span><span class="ml-auto font-medium tabular-nums">6</span></span></figcaption></figure></div>
2288
2289
  </div>
2289
2290
 
2290
2291
  ### Chart usage
2291
2292
 
2292
- ```tsx
2293
+ ```tsx fragment
2293
2294
  <Chart type="line" labels={days} datasets={[{ label: "Orders", data: counts }]} />
2294
2295
  <Chart type="donut" labels={["Paid","Pending"]} datasets={[{ data: [82, 18] }]} />
2295
2296
  ```
@@ -2323,13 +2324,13 @@ Or import directly from the package: `import { Prose } from "@zerotal/flow-ui";`
2323
2324
 
2324
2325
  ### Prose preview
2325
2326
 
2326
- <div class="not-prose my-6 flex min-h-32 items-center justify-center gap-4 rounded-lg border border-border bg-background p-10">
2327
+ <div class="not-prose my-6 flex min-h-32 max-w-full flex-wrap items-center justify-center gap-4 overflow-x-auto rounded-lg border border-border bg-background p-6 sm:p-10">
2327
2328
  <div class="text-foreground [&amp;_h1]:mt-8 [&amp;_h1]:scroll-m-20 [&amp;_h1]:text-3xl [&amp;_h1]:font-semibold [&amp;_h1]:tracking-tight [&amp;_h2]:mt-8 [&amp;_h2]:scroll-m-20 [&amp;_h2]:border-b [&amp;_h2]:border-border [&amp;_h2]:pb-2 [&amp;_h2]:text-2xl [&amp;_h2]:font-semibold [&amp;_h3]:mt-6 [&amp;_h3]:scroll-m-20 [&amp;_h3]:text-xl [&amp;_h3]:font-semibold [&amp;_p]:leading-7 [&amp;_p:not(:first-child)]:mt-4 [&amp;_a]:font-medium [&amp;_a]:text-primary [&amp;_a]:underline [&amp;_a]:underline-offset-4 [&amp;_ul]:my-4 [&amp;_ul]:ml-6 [&amp;_ul]:list-disc [&amp;_ol]:my-4 [&amp;_ol]:ml-6 [&amp;_ol]:list-decimal [&amp;_li]:mt-2 [&amp;_blockquote]:mt-4 [&amp;_blockquote]:border-l-2 [&amp;_blockquote]:border-border [&amp;_blockquote]:pl-4 [&amp;_blockquote]:italic [&amp;_code]:rounded [&amp;_code]:bg-muted [&amp;_code]:px-[0.3rem] [&amp;_code]:py-[0.2rem] [&amp;_code]:font-mono [&amp;_code]:text-sm [&amp;_pre]:mt-4 [&amp;_pre]:overflow-x-auto [&amp;_pre]:rounded-lg [&amp;_pre]:border [&amp;_pre]:border-border [&amp;_pre]:bg-muted [&amp;_pre]:p-4 [&amp;_pre_code]:bg-transparent [&amp;_pre_code]:p-0 [&amp;_hr]:my-8 [&amp;_hr]:border-border [&amp;_table]:w-full [&amp;_table]:text-sm [&amp;_th]:border-b [&amp;_th]:border-border [&amp;_th]:px-3 [&amp;_th]:py-2 [&amp;_th]:text-left [&amp;_td]:border-b [&amp;_td]:border-border [&amp;_td]:px-3 [&amp;_td]:py-2 [&amp;_img]:rounded-lg max-w-md"><h2>A rendered document</h2><p>Prose styles its descendants, for content that arrives as a blob — Markdown, a CMS field, a rich-text column.</p><ul><li>Headings, lists and quotes</li><li>Inline <code>code</code> and code blocks</li></ul></div>
2328
2329
  </div>
2329
2330
 
2330
2331
  ### Prose usage
2331
2332
 
2332
- ```tsx
2333
+ ```tsx fragment
2333
2334
  <Prose dangerouslySetInnerHTML={{ __html: rendered }} />
2334
2335
  <H1>Page title</H1>
2335
2336
  <Muted>Last updated yesterday</Muted>
@@ -2375,7 +2376,7 @@ component _you_ composed from them, and the props you pass it.
2375
2376
  lives in your repo, it is application code — it changes when you edit it, and
2376
2377
  nothing upstream will catch a regression you introduce:
2377
2378
 
2378
- ```typescript
2379
+ ```typescript fragment
2379
2380
  // tests/components/StatusBadge.test.ts
2380
2381
  import { test, expect } from "bun:test";
2381
2382
  import { StatusBadge } from "../../resources/components/StatusBadge.tsx";