@heyramzi/ui 2.20.0 → 2.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/README.md +2 -0
  2. package/dist/charts/dashboard/data-table.js +1 -2
  3. package/dist/components/list-page/filter-section.js +1 -1
  4. package/dist/components/list-page/list-table.js +5 -6
  5. package/dist/components/list-page/queue-rail.js +2 -1
  6. package/dist/components/picker/trigger.js +3 -3
  7. package/dist/components/segmented/segmented.js +5 -5
  8. package/dist/components/work-parts/looks.js +1 -1
  9. package/dist/shadcn/dialog/index.js +3 -2
  10. package/dist/shadcn/dropdown-menu/menu-item.js +1 -1
  11. package/dist/shadcn/sheet/index.js +3 -2
  12. package/dist/shadcn/skeleton/index.js +3 -2
  13. package/dist/status/index.js +1 -0
  14. package/dist/work/kanban-drag.js +13 -7
  15. package/package.json +1 -1
  16. package/src/ai/confirmation/ConfirmationTitle.svelte +1 -4
  17. package/src/ai/loading-state/PixelLoader.svelte +1 -1
  18. package/src/animations/dropdown.css +19 -10
  19. package/src/animations/modal.css +7 -2
  20. package/src/charts/charts.css +3 -5
  21. package/src/charts/dashboard/dashboard-section.svelte +1 -1
  22. package/src/charts/dashboard/data-table.ts +1 -2
  23. package/src/charts/dashboard/stat-tile.svelte +1 -1
  24. package/src/charts/number-chart.css +8 -7
  25. package/src/charts/pop-value.svelte +68 -0
  26. package/src/charts/primitives/chart-tooltip.svelte +1 -1
  27. package/src/charts/reference-line.css +1 -1
  28. package/src/charts/stat-card.css +4 -4
  29. package/src/components/copy/copy-button.svelte +11 -10
  30. package/src/components/data-table/row-arrow.svelte +1 -1
  31. package/src/components/data-table/row-context-menu.svelte +1 -1
  32. package/src/components/data-table/sortable-head.svelte +2 -2
  33. package/src/components/data-table/table-skeleton.svelte +5 -5
  34. package/src/components/docs/doc-page.svelte +1 -3
  35. package/src/components/docs/on-this-page.svelte +4 -4
  36. package/src/components/field-row/field-row.svelte +1 -1
  37. package/src/components/list-page/detail-empty.svelte +3 -8
  38. package/src/components/list-page/detail-header.svelte +1 -1
  39. package/src/components/list-page/detail-row.svelte +2 -1
  40. package/src/components/list-page/empty-state.svelte +15 -7
  41. package/src/components/list-page/filter-item.svelte +2 -2
  42. package/src/components/list-page/filter-popover.svelte +1 -1
  43. package/src/components/list-page/filter-section.ts +1 -4
  44. package/src/components/list-page/grouped-list.svelte +37 -8
  45. package/src/components/list-page/list-page-shell.svelte +1 -1
  46. package/src/components/list-page/list-table.ts +6 -6
  47. package/src/components/list-page/master-detail.svelte +1 -1
  48. package/src/components/list-page/queue-rail.ts +2 -2
  49. package/src/components/list-page/rail-empty.svelte +1 -1
  50. package/src/components/list-page/rail-row.svelte +5 -5
  51. package/src/components/open-in/open-in.svelte +2 -1
  52. package/src/components/picker/trigger.ts +6 -5
  53. package/src/components/section-card/section-card.svelte +1 -1
  54. package/src/components/section-header/section-header.svelte +4 -2
  55. package/src/components/section-header/section-label.svelte +2 -2
  56. package/src/components/segmented/animated-tabs.svelte +1 -1
  57. package/src/components/segmented/section-runs.svelte +1 -1
  58. package/src/components/segmented/segment.svelte +4 -6
  59. package/src/components/segmented/segmented-track.svelte +18 -52
  60. package/src/components/segmented/segmented.ts +5 -5
  61. package/src/components/table-view/table-view.svelte +43 -24
  62. package/src/components/tags-input/tags-input.svelte +17 -31
  63. package/src/components/work-parts/looks.ts +1 -1
  64. package/src/editor/content.css +3 -3
  65. package/src/editor/editor.svelte +1 -1
  66. package/src/inbox/thread-inbox.svelte +2 -9
  67. package/src/panel/side-panel.svelte +9 -4
  68. package/src/record/info-list.svelte +7 -8
  69. package/src/record/project-list.svelte +1 -1
  70. package/src/record/record-demo.svelte +2 -4
  71. package/src/record/record-shell.svelte +1 -1
  72. package/src/record/record-stats.svelte +9 -3
  73. package/src/record/steps-rail.svelte +7 -11
  74. package/src/shadcn/accordion/accordion-trigger.svelte +1 -1
  75. package/src/shadcn/alert-dialog/alert-dialog-content.svelte +5 -1
  76. package/src/shadcn/alert-dialog/alert-dialog-footer.svelte +12 -2
  77. package/src/shadcn/alert-dialog/alert-dialog-header.svelte +1 -1
  78. package/src/shadcn/alert-dialog/alert-dialog-title.svelte +1 -1
  79. package/src/shadcn/badge/badge.svelte +3 -1
  80. package/src/shadcn/bubble/bubble-content.svelte +1 -1
  81. package/src/shadcn/bubble/bubble.svelte +1 -1
  82. package/src/shadcn/button/button.svelte +11 -5
  83. package/src/shadcn/calendar/calendar-month-select.svelte +1 -1
  84. package/src/shadcn/calendar/calendar-year-select.svelte +1 -1
  85. package/src/shadcn/calendar/calendar.svelte +1 -1
  86. package/src/shadcn/card/card.svelte +2 -1
  87. package/src/shadcn/checkbox/checkbox.svelte +1 -1
  88. package/src/shadcn/code-block/code-block-actions.svelte +1 -1
  89. package/src/shadcn/command/command-dialog.svelte +2 -2
  90. package/src/shadcn/command/command-group.svelte +1 -1
  91. package/src/shadcn/command/command-input.svelte +1 -1
  92. package/src/shadcn/command/command-item.svelte +1 -1
  93. package/src/shadcn/dialog/dialog-body.svelte +22 -0
  94. package/src/shadcn/dialog/dialog-content.svelte +19 -4
  95. package/src/shadcn/dialog/dialog-footer.svelte +19 -1
  96. package/src/shadcn/dialog/dialog-header.svelte +6 -1
  97. package/src/shadcn/dialog/dialog-title.svelte +2 -1
  98. package/src/shadcn/dialog/index.ts +3 -0
  99. package/src/shadcn/dropdown-menu/dropdown-menu-content.svelte +5 -1
  100. package/src/shadcn/dropdown-menu/dropdown-menu-sub-content.svelte +1 -1
  101. package/src/shadcn/dropdown-menu/menu-item.ts +1 -1
  102. package/src/shadcn/field/field-separator.svelte +1 -1
  103. package/src/shadcn/hover-card/hover-card-content.svelte +1 -1
  104. package/src/shadcn/input/input.svelte +2 -2
  105. package/src/shadcn/input-otp/input-otp-slot.svelte +1 -1
  106. package/src/shadcn/message-scroller/message-scroller-button.svelte +1 -1
  107. package/src/shadcn/popover/popover-content.svelte +1 -1
  108. package/src/shadcn/radio-group/radio-group-item.svelte +1 -1
  109. package/src/shadcn/scroll-area/scroll-area.svelte +1 -1
  110. package/src/shadcn/select/select-content.svelte +6 -2
  111. package/src/shadcn/select/select-item.svelte +1 -1
  112. package/src/shadcn/select/select-trigger.svelte +1 -1
  113. package/src/shadcn/sheet/index.ts +3 -0
  114. package/src/shadcn/sheet/sheet-body.svelte +22 -0
  115. package/src/shadcn/sheet/sheet-content.svelte +27 -5
  116. package/src/shadcn/sheet/sheet-footer.svelte +14 -2
  117. package/src/shadcn/sheet/sheet-header.svelte +1 -1
  118. package/src/shadcn/sheet/sheet-title.svelte +1 -1
  119. package/src/shadcn/sheet/sheet.css +11 -5
  120. package/src/shadcn/sidebar/sidebar-group-action.svelte +1 -1
  121. package/src/shadcn/sidebar/sidebar-group-label.svelte +1 -1
  122. package/src/shadcn/sidebar/sidebar-inset.svelte +1 -1
  123. package/src/shadcn/sidebar/sidebar-menu-action.svelte +1 -1
  124. package/src/shadcn/sidebar/sidebar-menu-button.svelte +2 -2
  125. package/src/shadcn/sidebar/sidebar-menu-sub-button.svelte +1 -1
  126. package/src/shadcn/sidebar/sidebar-menu.svelte +1 -1
  127. package/src/shadcn/sidebar/sidebar.svelte +1 -1
  128. package/src/shadcn/skeleton/index.ts +3 -0
  129. package/src/shadcn/skeleton/skeleton-delay.svelte +63 -0
  130. package/src/shadcn/skeleton/skeleton-delay.svelte.test.ts +57 -0
  131. package/src/shadcn/skeleton/skeleton.svelte +5 -1
  132. package/src/shadcn/slider/slider.svelte +1 -1
  133. package/src/shadcn/switch/switch.svelte +2 -2
  134. package/src/shadcn/table/table-row.svelte +1 -1
  135. package/src/shadcn/tabs/tabs-list.svelte +1 -1
  136. package/src/shadcn/tabs/tabs-trigger.svelte +2 -1
  137. package/src/shadcn/textarea/textarea.svelte +1 -1
  138. package/src/shadcn/toggle/toggle.svelte +2 -2
  139. package/src/shadcn/toggle-group/toggle-group.svelte +1 -1
  140. package/src/shadcn/tooltip/tooltip-content.svelte +1 -1
  141. package/src/shadcn/trace/trace-collapsible-trigger.svelte +1 -1
  142. package/src/shadcn/trace/trace.svelte +1 -1
  143. package/src/status/README.md +1 -1
  144. package/src/status/index.ts +1 -0
  145. package/src/status/status-badge.svelte +21 -7
  146. package/src/status/status-dot.svelte +6 -11
  147. package/src/status/status-pill.svelte +50 -0
  148. package/src/thread/thread.svelte +54 -136
  149. package/src/tokens/craft.css +55 -36
  150. package/src/tokens/palette.css +16 -9
  151. package/src/work/demo.svelte +48 -42
  152. package/src/work/detail/detail-demo.svelte +33 -24
  153. package/src/work/detail/task-chip.svelte +4 -4
  154. package/src/work/detail/task-detail.svelte +41 -108
  155. package/src/work/detail/task-property.svelte +7 -13
  156. package/src/work/detail/task-thread.svelte +48 -119
  157. package/src/work/docs/doc-editor-page.svelte +5 -4
  158. package/src/work/docs/doc-menu.svelte +9 -4
  159. package/src/work/docs/docs-demo.svelte +4 -4
  160. package/src/work/docs/edited-chip.svelte +11 -4
  161. package/src/work/gantt/gantt-bar.svelte +18 -14
  162. package/src/work/gantt/gantt-grid.svelte +7 -7
  163. package/src/work/gantt/gantt-group-row.svelte +7 -10
  164. package/src/work/gantt/gantt-header.svelte +3 -1
  165. package/src/work/gantt/gantt-task-row.svelte +19 -9
  166. package/src/work/gantt/gantt.css +4 -5
  167. package/src/work/inbox/inbox-card.svelte +32 -10
  168. package/src/work/inbox/inbox-draft.svelte +2 -2
  169. package/src/work/kanban-column.svelte +7 -15
  170. package/src/work/kanban-drag.ts +13 -8
  171. package/src/work/task-gantt.svelte +2 -1
  172. package/src/work/task-list.svelte +54 -53
  173. package/src/work/time/time-chip.svelte +16 -19
  174. package/src/work/time/time-dot.svelte +2 -1
  175. package/src/work/time/time-ring.svelte +2 -3
  176. package/src/work/time/time-tracker.svelte +72 -166
@@ -245,21 +245,21 @@
245
245
  <Check class="size-2.5" weight="bold" />
246
246
  </span>
247
247
  {:else if kind === "current"}
248
- <span class="rounded-full bg-background p-0.75">
248
+ <span class="rounded-full bg-card p-0.75">
249
249
  <span
250
250
  class="block size-2 rounded-full bg-[color:var(--tone-accent,var(--color-primary))] ring-3 ring-[color-mix(in_oklab,var(--tone-accent,var(--color-primary))_20%,transparent)]"
251
251
  ></span>
252
252
  </span>
253
253
  {:else if kind === "late"}
254
- <span class="size-2 rounded-full border-2 border-warning bg-background"></span>
254
+ <span class="size-2 rounded-full border-2 border-warning bg-card"></span>
255
255
  {:else}
256
- <span class="size-2 rounded-full border border-muted-foreground/40 bg-background"></span>
256
+ <span class="size-2 rounded-full border border-muted-foreground/40 bg-card"></span>
257
257
  {/if}
258
258
  {/snippet}
259
259
 
260
260
  <div class={cn("flex flex-col", className)}>
261
261
  <div class="mb-2 flex min-h-7 items-center gap-2 px-2">
262
- <h2 class="text-xs font-medium tracking-wide text-muted-foreground uppercase">{t.steps}</h2>
262
+ <h2 class="text-xs font-medium text-muted-foreground">{t.steps}</h2>
263
263
  {#if !loading}
264
264
  <span class="text-xs tabular-nums text-muted-foreground">
265
265
  {t.stepsCount(progress.done, progress.total)}
@@ -290,9 +290,7 @@
290
290
  <Popover.Content align="end" class="w-64 p-1">
291
291
  {#each menuBuckets as bucket (bucket.key)}
292
292
  {#if bucket.label}
293
- <p
294
- class="px-2 pt-2 pb-1 text-xs font-medium tracking-wide text-muted-foreground uppercase"
295
- >
293
+ <p class="px-2 pt-2 pb-1 text-xs font-medium text-muted-foreground">
296
294
  {bucket.label}
297
295
  </p>
298
296
  {/if}
@@ -342,9 +340,7 @@
342
340
  {#each buckets as bucket (bucket.key)}
343
341
  <div class="flex flex-col">
344
342
  {#if bucket.label}
345
- <h3
346
- class="mb-1 px-2 text-xs font-medium tracking-wide text-muted-foreground uppercase select-none"
347
- >
343
+ <h3 class="mb-1 px-2 text-xs font-medium text-muted-foreground select-none">
348
344
  {bucket.label}
349
345
  </h3>
350
346
  {/if}
@@ -375,7 +371,7 @@
375
371
  draggable={canReorder && !renaming}
376
372
  class={cn(
377
373
  "relative flex min-h-9 w-full items-start gap-2.5 rounded-lg px-2 py-2 text-left transition-colors any-pointer-coarse:min-h-11 any-pointer-coarse:py-3",
378
- "outline-none focus-visible:ring-3 focus-visible:ring-ring/50",
374
+ "outline-none focus-visible:shadow-(--ring-focus)",
379
375
  canReorder && "active:cursor-grabbing",
380
376
  active ? "bg-muted" : "hover:bg-muted/60",
381
377
  )}
@@ -24,7 +24,7 @@
24
24
  data-slot="accordion-trigger"
25
25
  bind:ref
26
26
  class={cn(
27
- "focus-visible:ring-ring/50 focus-visible:border-ring focus-visible:after:border-ring **:data-[slot=accordion-trigger-icon]:text-muted-foreground rounded-md py-4 text-left text-sm font-medium hover:underline focus-visible:ring-3 **:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4 group/accordion-trigger relative flex flex-1 items-start justify-between border border-transparent transition-[color,background-color,border-color,box-shadow] duration-[var(--duration-quick)] ease-[var(--ease-smooth-out)] outline-none disabled:pointer-events-none disabled:opacity-50",
27
+ " focus-visible:border-ring focus-visible:after:border-ring **:data-[slot=accordion-trigger-icon]:text-muted-foreground rounded-md py-4 text-left text-sm font-medium hover:underline focus-visible:shadow-(--ring-focus) **:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4 group/accordion-trigger relative flex flex-1 items-start justify-between border border-transparent transition-[color,background-color,border-color,box-shadow] duration-[var(--duration-quick)] ease-[var(--ease-smooth-out)] outline-none disabled:pointer-events-none disabled:opacity-50",
28
28
  className,
29
29
  )}
30
30
  {...restProps}
@@ -21,7 +21,11 @@
21
21
  bind:ref
22
22
  data-slot="alert-dialog-content"
23
23
  class={cn(
24
- "t-modal bg-background fixed inset-0 z-50 m-auto grid h-fit w-full max-w-[calc(100%-2rem)] gap-4 rounded-lg border p-6 shadow-lg sm:max-w-lg",
24
+ // The dialog's surface: white popover, the edge and depth from `shadow-edge-overlay`,
25
+ // the overlay radius. `overflow-hidden` lets a banded footer follow the bottom corners.
26
+ "t-modal bg-popover text-popover-foreground shadow-edge-overlay fixed inset-0 z-50 m-auto grid h-fit w-full max-w-[calc(100%-2rem)] gap-4 overflow-hidden rounded-2xl text-sm outline-none sm:max-w-md",
27
+ // Same padding variable as the dialog, so `AlertDialog.Footer band` reads one number.
28
+ "[--dialog-pad:1.25rem] sm:[--dialog-pad:1.5rem] p-(--dialog-pad)",
25
29
  className,
26
30
  )}
27
31
  {...restProps}
@@ -6,14 +6,24 @@
6
6
  ref = $bindable(null),
7
7
  class: className,
8
8
  children,
9
+ band = false,
9
10
  ...restProps
10
- }: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
11
+ }: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
12
+ /** A hairline and a quiet surface out to both edges and the bottom corners. Last child only. */
13
+ band?: boolean;
14
+ } = $props();
11
15
  </script>
12
16
 
13
17
  <div
14
18
  bind:this={ref}
15
19
  data-slot="alert-dialog-footer"
16
- class={cn("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className)}
20
+ data-band={band || undefined}
21
+ class={cn(
22
+ "flex flex-col-reverse gap-2 sm:flex-row sm:items-center sm:justify-end",
23
+ "data-band:border-border data-band:bg-muted/50 data-band:mt-2 data-band:border-t",
24
+ "data-band:mx-[calc(-1*var(--dialog-pad))] data-band:mb-[calc(-1*var(--dialog-pad))] data-band:px-(--dialog-pad) data-band:py-4",
25
+ className,
26
+ )}
17
27
  {...restProps}
18
28
  >
19
29
  {@render children?.()}
@@ -13,7 +13,7 @@
13
13
  <div
14
14
  bind:this={ref}
15
15
  data-slot="alert-dialog-header"
16
- class={cn("flex flex-col gap-2 text-center sm:text-start", className)}
16
+ class={cn("flex flex-col gap-1.5 text-center sm:text-start", className)}
17
17
  {...restProps}
18
18
  >
19
19
  {@render children?.()}
@@ -12,6 +12,6 @@
12
12
  <AlertDialogPrimitive.Title
13
13
  bind:ref
14
14
  data-slot="alert-dialog-title"
15
- class={cn("text-lg font-semibold", className)}
15
+ class={cn("text-base leading-6 font-semibold tracking-tight", className)}
16
16
  {...restProps}
17
17
  />
@@ -2,7 +2,9 @@
2
2
  import { type VariantProps, tv } from "tailwind-variants";
3
3
 
4
4
  export const badgeVariants = tv({
5
- base: "h-5 gap-1 rounded-full border border-transparent px-2 py-0.5 text-xs font-medium has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&>svg]:size-3! focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive group/badge inline-flex w-fit max-w-full shrink-0 items-center justify-center overflow-hidden whitespace-nowrap transition-[background-color,border-color,color,box-shadow] focus-visible:ring-[3px] [&>svg]:pointer-events-none",
5
+ // The chip radius, not a pill: DESIGN.md keeps `rounded-full` for status and counts,
6
+ // which `StatusBadge` owns. Tabular figures so a count that ticks doesn't shift.
7
+ base: "h-5 gap-1 rounded-sm border border-transparent px-2 py-0.5 text-xs font-medium tabular-nums has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&>svg]:size-3! focus-visible:border-ring focus-visible:shadow-(--ring-focus) aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive group/badge inline-flex w-fit max-w-full shrink-0 items-center justify-center overflow-hidden whitespace-nowrap transition-[background-color,border-color,color,box-shadow] duration-[var(--duration-quick)] ease-[var(--ease-smooth-out)] [&>svg]:pointer-events-none",
6
8
  variants: {
7
9
  // Three weights a label can carry: filled, tinted, outlined. Severity is the
8
10
  // `tone` prop, which reads `TONE_CLASS`, not a variant.
@@ -14,7 +14,7 @@
14
14
 
15
15
  const mergedProps = $derived({
16
16
  class: cn(
17
- "cn-bubble-content w-fit max-w-full min-w-0 overflow-hidden wrap-break-word [button]:text-left [button,a]:transition-colors rounded-xl border border-transparent px-3 py-2 text-sm leading-relaxed [button,a]:outline-none [button,a]:focus-visible:border-ring [button,a]:focus-visible:ring-3 [button,a]:focus-visible:ring-ring/50 group-data-[align=end]/bubble:self-end",
17
+ "cn-bubble-content w-fit max-w-full min-w-0 overflow-hidden wrap-break-word [button]:text-left [button,a]:transition-colors rounded-xl border border-transparent px-3 py-2 text-sm leading-relaxed [button,a]:outline-none [button,a]:focus-visible:border-ring [button,a]:focus-visible:shadow-(--ring-focus) group-data-[align=end]/bubble:self-end",
18
18
  className,
19
19
  ),
20
20
  "data-slot": "bubble-content",
@@ -14,7 +14,7 @@
14
14
  tinted:
15
15
  "cn-bubble-variant-tinted *:data-[slot=bubble-content]:bg-[oklch(from_var(--primary)_0.93_calc(c*0.4)_h)] dark:*:data-[slot=bubble-content]:bg-[oklch(from_var(--primary)_0.3_calc(c*0.4)_h)] *:data-[slot=bubble-content]:text-foreground [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[oklch(from_var(--primary)_0.88_calc(c*0.5)_h)] dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-[oklch(from_var(--primary)_0.35_calc(c*0.5)_h)]",
16
16
  outline:
17
- "cn-bubble-variant-outline *:data-[slot=bubble-content]:bg-background *:data-[slot=bubble-content]:border-border [&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:text-foreground dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-input/30",
17
+ "cn-bubble-variant-outline *:data-[slot=bubble-content]:bg-card *:data-[slot=bubble-content]:border-border [&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:text-foreground dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-input/30",
18
18
  ghost:
19
19
  "cn-bubble-variant-ghost *:data-[slot=bubble-content]:rounded-none *:data-[slot=bubble-content]:bg-transparent *:data-[slot=bubble-content]:p-0 [&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:text-foreground dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted/50 border-none",
20
20
  destructive:
@@ -4,7 +4,9 @@
4
4
  import { type VariantProps, tv } from "tailwind-variants";
5
5
 
6
6
  export const buttonVariants = tv({
7
- base: "t-press focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-medium focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*='size-'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
7
+ // Focus is the kit's one ring, `--ring-focus`, written as a utility because the
8
+ // variant shadows (`shadow-key`, `shadow-btn`) would otherwise cover the base-layer rule.
9
+ base: "t-press focus-visible:shadow-(--ring-focus) aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-medium aria-invalid:ring-3 [&_svg:not([class*='size-'])]:size-4 group/button inline-flex shrink-0 items-center justify-center whitespace-nowrap outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
8
10
  variants: {
9
11
  // Five roles: fill, outline, ghost, destructive, and dashed for an empty
10
12
  // slot. `secondary` and `link` went on 4 Sep 2026, one real caller between
@@ -13,14 +15,18 @@
13
15
  default:
14
16
  "bg-primary text-primary-foreground shadow-key hover:bg-primary/90 active:shadow-none [a]:hover:bg-primary/80",
15
17
  outline:
16
- "border-border bg-background shadow-btn hover:bg-muted hover:text-foreground active:shadow-none dark:bg-input/30 dark:border-input dark:hover:bg-input/50 aria-expanded:bg-muted aria-expanded:text-foreground",
18
+ // `bg-card`, not `bg-background`: the background is the grey canvas now, so an
19
+ // outline button on a white panel read as a grey slab.
20
+ "border-border bg-card shadow-btn hover:bg-muted hover:border-foreground/15 hover:text-foreground active:shadow-none dark:bg-input/30 dark:border-input dark:hover:bg-input/50 aria-expanded:bg-muted aria-expanded:text-foreground",
21
+ // A foreground wash, not `bg-muted`: muted is L 0.94 and the canvas 0.945, so a
22
+ // ghost hover on the page drew nothing. The wash reads on canvas and card alike.
17
23
  ghost:
18
- "hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground",
24
+ "hover:bg-foreground/6 hover:text-foreground aria-expanded:bg-foreground/6 aria-expanded:text-foreground",
19
25
  destructive:
20
- "bg-destructive/10 hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/20 text-destructive dark:text-destructive focus-visible:border-destructive/40 dark:hover:bg-destructive/30",
26
+ "bg-destructive/10 hover:bg-destructive/20 dark:bg-destructive/20 text-destructive dark:text-destructive focus-visible:border-destructive/40 dark:hover:bg-destructive/30",
21
27
  // Quiet text that opens an editor or a menu: a ghost that wraps to as many lines as its
22
28
  // label needs, aligned left, never a fixed-height square.
23
- text: "hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground",
29
+ text: "hover:bg-foreground/6 hover:text-foreground aria-expanded:bg-foreground/6 aria-expanded:text-foreground",
24
30
  // WHY a variant and not a class every call site writes: "add another
25
31
 
26
32
  // row", "add a step", "attach a call" is one affordance, and it was hand-drawn eleven times across the app with four radii, three text sizes and three different hover hues.
@@ -14,7 +14,7 @@
14
14
 
15
15
  <span
16
16
  class={cn(
17
- "has-focus:border-ring border-input has-focus:ring-ring/50 relative flex rounded-md border shadow-xs has-focus:ring-[3px]",
17
+ "has-focus:border-ring border-input relative flex rounded-md border shadow-field has-focus:shadow-(--ring-focus)",
18
18
  className,
19
19
  )}
20
20
  >
@@ -13,7 +13,7 @@
13
13
 
14
14
  <span
15
15
  class={cn(
16
- "has-focus:border-ring border-input has-focus:ring-ring/50 relative flex rounded-md border shadow-xs has-focus:ring-[3px]",
16
+ "has-focus:border-ring border-input relative flex rounded-md border shadow-field has-focus:shadow-(--ring-focus)",
17
17
  className,
18
18
  )}
19
19
  >
@@ -59,7 +59,7 @@ get along, so we shut typescript up by casting `value` to `never`.
59
59
  {weekStartsOn}
60
60
  {fixedWeeks}
61
61
  class={cn(
62
- "bg-background group/calendar p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
62
+ "bg-card group/calendar p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
63
63
  className,
64
64
  )}
65
65
  {locale}
@@ -16,7 +16,8 @@
16
16
  data-slot="card"
17
17
  data-size={size}
18
18
  class={cn(
19
- "ring-foreground/10 bg-card text-card-foreground gap-6 overflow-hidden rounded-xl py-6 text-sm shadow-card ring-1 has-[>img:first-child]:pt-0 data-[size=sm]:gap-4 data-[size=sm]:py-4 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl group/card flex flex-col",
19
+ // `shadow-card` draws its own hairline, so a ring on top made a 2px edge.
20
+ "bg-card text-card-foreground gap-6 overflow-hidden rounded-xl py-6 text-sm shadow-card has-[>img:first-child]:pt-0 data-[size=sm]:gap-4 data-[size=sm]:py-4 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl group/card flex flex-col",
20
21
  className,
21
22
  )}
22
23
  {...restProps}
@@ -16,7 +16,7 @@
16
16
  bind:ref
17
17
  data-slot="checkbox"
18
18
  class={cn(
19
- "border-input dark:bg-input/30 data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary data-checked:border-primary aria-invalid:aria-checked:border-primary aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 flex size-4 items-center justify-center rounded-sm border shadow-btn transition-[background-color,border-color,box-shadow] duration-[var(--duration-quick)] ease-[var(--ease-smooth-out)] group-has-disabled/field:opacity-50 focus-visible:ring-3 aria-invalid:ring-3 peer relative shrink-0 outline-none after:absolute after:-inset-x-3 after:-inset-y-2 any-pointer-coarse:after:-inset-[15px] disabled:cursor-not-allowed disabled:opacity-50",
19
+ "border-input dark:bg-input/30 data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary data-checked:border-primary aria-invalid:aria-checked:border-primary aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 not-data-checked:enabled:hover:border-foreground/30 focus-visible:border-ring focus-visible:shadow-(--ring-focus) aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 flex size-4 items-center justify-center rounded-sm border shadow-btn transition-[background-color,border-color,box-shadow] duration-[var(--duration-quick)] ease-[var(--ease-smooth-out)] group-has-disabled/field:opacity-50 aria-invalid:ring-3 peer relative shrink-0 outline-none after:absolute after:-inset-x-3 after:-inset-y-2 any-pointer-coarse:after:-inset-[15px] disabled:cursor-not-allowed disabled:opacity-50",
20
20
  className,
21
21
  )}
22
22
  bind:checked
@@ -14,7 +14,7 @@
14
14
  bind:this={ref}
15
15
  data-slot="code-block-actions"
16
16
  class={cn(
17
- "-my-1 -me-1.5 gap-1 [[data-slot=code-block]>&]:m-0 [[data-slot=code-block]>&]:top-3 [[data-slot=code-block]>&]:end-3 group-data-[size=sm]/code-block:[[data-slot=code-block]>&]:top-2 group-data-[size=sm]/code-block:[[data-slot=code-block]>&]:end-2 [[data-slot=code-block]>&]:*:[button]:bg-background [[data-slot=code-block]>&]:*:[button]:ring-1 [[data-slot=code-block]>&]:*:[button]:ring-foreground/10 ms-auto flex shrink-0 items-center [[data-slot=code-block]>&]:absolute [[data-slot=code-block]>&]:z-10 [[data-slot=code-block]>&]:opacity-0 [[data-slot=code-block]>&]:transition-opacity [[data-slot=code-block]>&]:group-focus-within/code-block:opacity-100 [[data-slot=code-block]>&]:group-hover/code-block:opacity-100 [[data-slot=code-block]>&]:pointer-coarse:opacity-100",
17
+ "-my-1 -me-1.5 gap-1 [[data-slot=code-block]>&]:m-0 [[data-slot=code-block]>&]:top-3 [[data-slot=code-block]>&]:end-3 group-data-[size=sm]/code-block:[[data-slot=code-block]>&]:top-2 group-data-[size=sm]/code-block:[[data-slot=code-block]>&]:end-2 [[data-slot=code-block]>&]:*:[button]:bg-card [[data-slot=code-block]>&]:*:[button]:ring-1 [[data-slot=code-block]>&]:*:[button]:ring-foreground/10 ms-auto flex shrink-0 items-center [[data-slot=code-block]>&]:absolute [[data-slot=code-block]>&]:z-10 [[data-slot=code-block]>&]:opacity-0 [[data-slot=code-block]>&]:transition-opacity [[data-slot=code-block]>&]:group-focus-within/code-block:opacity-100 [[data-slot=code-block]>&]:group-hover/code-block:opacity-100 [[data-slot=code-block]>&]:pointer-coarse:opacity-100",
18
18
  className
19
19
  )}
20
20
  {...restProps}
@@ -37,13 +37,13 @@
37
37
  // WHY: search is the one dialog that must sit above the keyboard rather
38
38
 
39
39
  // than under it, so it stays top-anchored on phones instead of taking the shared bottom-sheet position, and hugs the safe area at the top.
40
- "rounded-xl! top-[max(0.5rem,env(safe-area-inset-top))] right-2 bottom-auto left-2 w-auto max-h-[70svh] translate-y-0 gap-0 overflow-hidden p-0 sm:p-0",
40
+ "rounded-2xl! top-[max(0.5rem,env(safe-area-inset-top))] right-2 bottom-auto left-2 w-auto max-h-[70svh] translate-y-0 gap-0 overflow-hidden p-0 sm:p-0",
41
41
  // WHY no border and no card background here: the palette is a floating
42
42
 
43
43
  // object, so its edge is a lit rim and a cast shadow rather than a drawn line, and the surface itself belongs to the Command root beneath so its translucency
44
44
 
45
45
  // can read the dimmed page through it.
46
- "border-0 bg-transparent ring-1 ring-foreground/15 shadow-overlay",
46
+ "border-0 bg-transparent shadow-edge-overlay",
47
47
  // WHY a third of the way down rather than centred: the eye is already at
48
48
 
49
49
  // the top of the screen when the shortcut is pressed, and a list that grows downward should not push its first row past the fold.
@@ -31,7 +31,7 @@
31
31
  >
32
32
  {#if heading}
33
33
  <CommandPrimitive.GroupHeading
34
- class="text-muted-foreground px-2.5 pt-2.5 pb-1.5 text-xs font-medium tracking-[0.09em] uppercase"
34
+ class="text-muted-foreground px-2.5 pt-2.5 pb-1.5 text-xs font-medium"
35
35
  >
36
36
  {heading}
37
37
  </CommandPrimitive.GroupHeading>
@@ -49,7 +49,7 @@
49
49
  "caret-brand placeholder:text-muted-foreground/70 w-full bg-transparent outline-hidden disabled:cursor-not-allowed disabled:opacity-50",
50
50
  // A combobox popover's search line is 36px, measured; `lg` is the
51
51
  // standalone palette header and keeps its own larger rhythm.
52
- size === "lg" ? "py-3.5 text-[15px]" : "py-2 text-[13px]",
52
+ size === "lg" ? "py-3.5 text-[15px]" : "py-2 text-(length:--text-control)",
53
53
  className,
54
54
  )}
55
55
  bind:ref
@@ -22,7 +22,7 @@
22
22
  // at half strength is a two-percent lightness step on the dark surface, so the one row the arrow keys are on was the hardest row to find.
23
23
 
24
24
  // A foreground wash plus an inset hairline works in both modes from one rule.
25
- "group/command-item data-selected:bg-foreground/6 data-selected:ring-foreground/10 data-selected:text-foreground data-selected:*:[svg]:text-foreground relative flex min-h-8 cursor-default items-center gap-2.5 rounded-lg px-2.5 py-1.5 text-[13px] outline-hidden transition-colors duration-[var(--duration-fast)] select-none active:translate-y-px data-selected:ring-1 data-selected:ring-inset data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
25
+ "group/command-item data-selected:bg-foreground/6 data-selected:ring-foreground/10 data-selected:text-foreground data-selected:*:[svg]:text-foreground relative flex min-h-8 cursor-default items-center gap-2.5 rounded-lg px-2.5 py-1.5 text-(length:--text-control) outline-hidden select-none active:translate-y-px data-selected:ring-1 data-selected:ring-inset data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
26
26
  className,
27
27
  )}
28
28
  {...restProps}
@@ -0,0 +1,22 @@
1
+ <script lang="ts">
2
+ import type { HTMLAttributes } from "svelte/elements";
3
+ import { cn, type WithElementRef } from "../../lib/utils.js";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ children,
9
+ ...restProps
10
+ }: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
11
+ </script>
12
+
13
+ <!-- The fields between the header and the footer. No padding of its own: the content's
14
+ `--dialog-pad` already lines it up with the title. -->
15
+ <div
16
+ bind:this={ref}
17
+ data-slot="dialog-body"
18
+ class={cn("flex min-w-0 flex-col gap-4", className)}
19
+ {...restProps}
20
+ >
21
+ {@render children?.()}
22
+ </div>
@@ -31,13 +31,20 @@
31
31
  <DialogPrimitive.Content
32
32
  bind:ref
33
33
  data-slot="dialog-content"
34
+ data-close={showCloseButton || undefined}
34
35
  class={cn(
35
- "t-modal bg-background ring-foreground/10 shadow-overlay fixed z-50 grid w-full gap-4 text-sm ring-1 outline-none",
36
+ // The popover surface, white on light: `bg-background` is the grey canvas now. The edge
37
+ // and the depth both come from `shadow-edge-overlay`, so no ring draws a second line.
38
+ "t-modal bg-popover text-popover-foreground shadow-edge-overlay fixed z-50 grid w-full gap-4 text-sm outline-none",
36
39
  // WHY: on a phone a centered card puts its controls at the top of the reach arc and leaves the on-screen keyboard fighting it for the middle of the screen.
37
40
 
38
41
  // Below sm the dialog docks to the bottom edge instead, scrolls inside itself, and clears the home indicator.
39
- "right-0 bottom-0 left-0 max-h-[88svh] overflow-y-auto overscroll-contain rounded-t-xl rounded-b-none p-4 pb-[max(1rem,env(safe-area-inset-bottom))]",
40
- "sm:top-1/2 sm:right-auto sm:bottom-auto sm:left-1/2 sm:max-h-[calc(100svh-4rem)] sm:max-w-md sm:-translate-x-1/2 sm:-translate-y-1/2 sm:rounded-xl sm:p-6",
42
+ "right-0 bottom-0 left-0 max-h-[88svh] overflow-y-auto overscroll-contain rounded-t-2xl rounded-b-none",
43
+ // One padding for every part, held in `--dialog-pad` so the header, the close button and a
44
+ // banded footer all read the same number. A single `p-` class, not `p-4 sm:p-6`: a caller's
45
+ // `p-0` used to cancel only the phone padding and leave 24px on desktop.
46
+ "[--dialog-pad:1rem] sm:[--dialog-pad:1.5rem] p-(--dialog-pad) pb-[max(var(--dialog-pad),env(safe-area-inset-bottom))]",
47
+ "sm:top-1/2 sm:right-auto sm:bottom-auto sm:left-1/2 sm:max-h-[calc(100svh-4rem)] sm:max-w-md sm:-translate-x-1/2 sm:-translate-y-1/2 sm:rounded-2xl",
41
48
  className,
42
49
  )}
43
50
  {...restProps}
@@ -46,7 +53,15 @@
46
53
  {#if showCloseButton}
47
54
  <DialogPrimitive.Close data-slot="dialog-close">
48
55
  {#snippet child({ props })}
49
- <Button variant="ghost" class="absolute top-4 right-4" size="sm" icon {...props}>
56
+ <!-- Centred on the title's 24px line, the glyph's right edge on the content edge:
57
+ a 32px button sits 4px above and 8px past the padding. -->
58
+ <Button
59
+ variant="ghost"
60
+ class="absolute top-[calc(var(--dialog-pad)-0.25rem)] right-[calc(var(--dialog-pad)-0.5rem)]"
61
+ size="sm"
62
+ icon
63
+ {...props}
64
+ >
50
65
  <X size={16} />
51
66
  <span class="sr-only">Close</span>
52
67
  </Button>
@@ -9,16 +9,34 @@
9
9
  class: className,
10
10
  children,
11
11
  showCloseButton = false,
12
+ band = false,
12
13
  ...restProps
13
14
  }: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
14
15
  showCloseButton?: boolean;
16
+ /**
17
+ * Draw the footer as a band: a hairline on top and a quiet surface out to both edges
18
+ * and the bottom corners. It cancels the content's `--dialog-pad` with a negative
19
+ * margin, so it only works as the content's last child. A bare `data-band` attribute
20
+ * does the same, for callers on a release that predates this prop.
21
+ */
22
+ band?: boolean;
15
23
  } = $props();
16
24
  </script>
17
25
 
18
26
  <div
19
27
  bind:this={ref}
20
28
  data-slot="dialog-footer"
21
- class={cn("gap-2 flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className)}
29
+ data-band={band || undefined}
30
+ class={cn(
31
+ "flex flex-col-reverse gap-2 sm:flex-row sm:items-center sm:justify-end",
32
+ // The band. The bottom margin matches the content's bottom padding, safe area included,
33
+ // so the surface reaches the edge on a phone docked over the home indicator too.
34
+ "data-band:border-border data-band:bg-muted/50 data-band:mt-2 data-band:border-t",
35
+ "data-band:mx-[calc(-1*var(--dialog-pad))] data-band:px-(--dialog-pad) data-band:py-4",
36
+ "data-band:mb-[calc(-1*max(var(--dialog-pad),env(safe-area-inset-bottom)))]",
37
+ "data-band:pb-[max(1rem,env(safe-area-inset-bottom))] sm:data-band:pb-4",
38
+ className,
39
+ )}
22
40
  {...restProps}
23
41
  >
24
42
  {@render children?.()}
@@ -10,10 +10,15 @@
10
10
  }: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
11
11
  </script>
12
12
 
13
+ <!-- The content pads it. With a close button the title stops 32px short of it,
14
+ so a long title wraps instead of running under the X. -->
13
15
  <div
14
16
  bind:this={ref}
15
17
  data-slot="dialog-header"
16
- class={cn("gap-2 flex flex-col", className)}
18
+ class={cn(
19
+ "flex flex-col gap-1.5 in-data-close:pe-8",
20
+ className,
21
+ )}
17
22
  {...restProps}
18
23
  >
19
24
  {@render children?.()}
@@ -9,9 +9,10 @@
9
9
  }: DialogPrimitive.TitleProps = $props();
10
10
  </script>
11
11
 
12
+ <!-- 16px on a 24px line: the close button centres on that line. -->
12
13
  <DialogPrimitive.Title
13
14
  bind:ref
14
15
  data-slot="dialog-title"
15
- class={cn("leading-none font-medium", className)}
16
+ class={cn("text-base leading-6 font-semibold tracking-tight", className)}
16
17
  {...restProps}
17
18
  />
@@ -8,6 +8,7 @@ import Content from "./dialog-content.svelte";
8
8
  import Description from "./dialog-description.svelte";
9
9
  import Trigger from "./dialog-trigger.svelte";
10
10
  import Close from "./dialog-close.svelte";
11
+ import Body from "./dialog-body.svelte";
11
12
 
12
13
  export {
13
14
  Root,
@@ -20,6 +21,7 @@ export {
20
21
  Content,
21
22
  Description,
22
23
  Close,
24
+ Body,
23
25
  //
24
26
  Root as Dialog,
25
27
  Title as DialogTitle,
@@ -31,4 +33,5 @@ export {
31
33
  Content as DialogContent,
32
34
  Description as DialogDescription,
33
35
  Close as DialogClose,
36
+ Body as DialogBody,
34
37
  };
@@ -8,6 +8,8 @@
8
8
  ref = $bindable(null),
9
9
  sideOffset = 4,
10
10
  align = "start",
11
+ // Keeps 8px between the menu and the viewport edge, matching the `100vw-1rem` width cap.
12
+ collisionPadding = 8,
11
13
  portalProps,
12
14
  class: className,
13
15
  ...restProps
@@ -22,8 +24,10 @@
22
24
  data-slot="dropdown-menu-content"
23
25
  {sideOffset}
24
26
  {align}
27
+ {collisionPadding}
25
28
  class={cn(
26
- "t-dropdown ring-foreground/10 bg-popover text-popover-foreground min-w-32 rounded-xl p-1 shadow-raised ring-1 z-50 w-(--bits-dropdown-menu-anchor-width) max-h-[var(--bits-floating-available-height,100svh)] max-w-[calc(100vw-1rem)] overflow-x-hidden overflow-y-auto overscroll-contain outline-none data-closed:overflow-hidden",
29
+ // 14px around 10px rows inside a 4px inset, so the corners run concentric.
30
+ "t-dropdown bg-popover text-popover-foreground min-w-32 rounded-xl p-1 shadow-edge-raised z-50 w-(--bits-dropdown-menu-anchor-width) max-h-[var(--bits-floating-available-height,100svh)] max-w-[calc(100vw-1rem)] overflow-x-hidden overflow-y-auto overscroll-contain outline-none data-closed:overflow-hidden",
27
31
  className,
28
32
  )}
29
33
  {...restProps}
@@ -13,7 +13,7 @@
13
13
  bind:ref
14
14
  data-slot="dropdown-menu-sub-content"
15
15
  class={cn(
16
- "t-dropdown ring-foreground/10 bg-popover text-popover-foreground min-w-[96px] rounded-xl p-1 shadow-raised ring-1 z-50 w-auto",
16
+ "t-dropdown bg-popover text-popover-foreground min-w-[96px] rounded-xl p-1 shadow-edge-raised z-50 w-auto",
17
17
  className,
18
18
  )}
19
19
  {...restProps}
@@ -24,7 +24,7 @@ import { tv, type VariantProps } from "tailwind-variants";
24
24
  * A row has to look the same either way, so it answers to both.
25
25
  */
26
26
  export const menuItemClass = tv({
27
- base: "relative flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-disabled:pointer-events-none data-disabled:opacity-50 disabled:pointer-events-none disabled:opacity-50",
27
+ base: "relative flex cursor-default items-center gap-1.5 rounded-lg px-1.5 py-1 text-sm outline-hidden select-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-disabled:pointer-events-none data-disabled:opacity-50 disabled:pointer-events-none disabled:opacity-50",
28
28
  variants: {
29
29
  variant: {
30
30
  default:
@@ -26,7 +26,7 @@
26
26
  <Separator class="absolute inset-0 top-1/2" />
27
27
  {#if children}
28
28
  <span
29
- class="bg-background text-muted-foreground relative mx-auto block w-fit px-2"
29
+ class="bg-card text-muted-foreground relative mx-auto block w-fit px-2"
30
30
  data-slot="field-separator-content"
31
31
  >
32
32
  {@render children()}
@@ -23,7 +23,7 @@
23
23
  {align}
24
24
  {sideOffset}
25
25
  class={cn(
26
- "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-end-2 data-[side=right]:slide-in-from-start-2 data-[side=top]:slide-in-from-bottom-2 z-50 mt-3 w-64 rounded-md border p-4 shadow-md outline-hidden outline-none",
26
+ "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-end-2 data-[side=right]:slide-in-from-start-2 data-[side=top]:slide-in-from-bottom-2 z-50 mt-3 w-64 rounded-2xl p-4 shadow-edge-raised outline-hidden outline-none",
27
27
  className,
28
28
  )}
29
29
  {...restProps}
@@ -25,7 +25,7 @@
25
25
  bind:this={ref}
26
26
  data-slot={dataSlot}
27
27
  class={cn(
28
- "dark:bg-input/30 border-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 disabled:bg-input/50 dark:disabled:bg-input/80 h-8 any-pointer-coarse:h-11 rounded-lg border bg-transparent px-2.5 py-1 text-base shadow-field transition-[color,background-color,box-shadow] duration-[var(--duration-quick)] ease-[var(--ease-smooth-out)] file:h-6 file:text-sm file:font-medium focus-visible:ring-3 aria-invalid:ring-3 md:text-sm file:text-foreground placeholder:text-muted-foreground w-full min-w-0 outline-none file:inline-flex file:border-0 file:bg-transparent disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
28
+ "dark:bg-input/30 border-input enabled:hover:border-foreground/20 focus-visible:border-ring focus-visible:shadow-(--ring-focus) aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 disabled:bg-input/50 dark:disabled:bg-input/80 h-8 any-pointer-coarse:h-11 rounded-lg border bg-transparent px-2.5 py-1 text-base shadow-field transition-[color,background-color,border-color,box-shadow] duration-[var(--duration-quick)] ease-[var(--ease-smooth-out)] file:h-6 file:text-sm file:font-medium aria-invalid:ring-3 md:text-sm file:text-foreground placeholder:text-muted-foreground w-full min-w-0 outline-none file:inline-flex file:border-0 file:bg-transparent disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
29
29
  className,
30
30
  )}
31
31
  type="file"
@@ -38,7 +38,7 @@
38
38
  bind:this={ref}
39
39
  data-slot={dataSlot}
40
40
  class={cn(
41
- "dark:bg-input/30 border-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 disabled:bg-input/50 dark:disabled:bg-input/80 h-8 any-pointer-coarse:h-11 rounded-lg border bg-transparent px-2.5 py-1 text-base shadow-field transition-[color,background-color,box-shadow] duration-[var(--duration-quick)] ease-[var(--ease-smooth-out)] file:h-6 file:text-sm file:font-medium focus-visible:ring-3 aria-invalid:ring-3 md:text-sm file:text-foreground placeholder:text-muted-foreground w-full min-w-0 outline-none file:inline-flex file:border-0 file:bg-transparent disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
41
+ "dark:bg-input/30 border-input enabled:hover:border-foreground/20 focus-visible:border-ring focus-visible:shadow-(--ring-focus) aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 disabled:bg-input/50 dark:disabled:bg-input/80 h-8 any-pointer-coarse:h-11 rounded-lg border bg-transparent px-2.5 py-1 text-base shadow-field transition-[color,background-color,border-color,box-shadow] duration-[var(--duration-quick)] ease-[var(--ease-smooth-out)] file:h-6 file:text-sm file:font-medium aria-invalid:ring-3 md:text-sm file:text-foreground placeholder:text-muted-foreground w-full min-w-0 outline-none file:inline-flex file:border-0 file:bg-transparent disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
42
42
  className,
43
43
  )}
44
44
  {type}
@@ -17,7 +17,7 @@
17
17
  class={cn(
18
18
  "border-input aria-invalid:border-destructive dark:bg-input/30 relative flex size-9 items-center justify-center border-y border-e text-sm transition-[border-color,box-shadow,background-color] outline-none first:rounded-s-md first:border-s last:rounded-e-md",
19
19
  cell.isActive &&
20
- "border-ring ring-ring/50 bg-accent/50 aria-invalid:border-destructive dark:aria-invalid:ring-destructive/40 aria-invalid:ring-destructive/20 ring-offset-background z-10 ring-[3px]",
20
+ "border-ring ring-ring/50 bg-accent/50 aria-invalid:border-destructive dark:aria-invalid:ring-destructive/40 aria-invalid:ring-destructive/20 ring-offset-card z-10 ring-[3px]",
21
21
  className,
22
22
  )}
23
23
  {...restProps}
@@ -28,7 +28,7 @@
28
28
  data-size={size}
29
29
  {direction}
30
30
  class={cn(
31
- "absolute inset-s-1/2 -translate-x-1/2 border-border bg-background text-foreground transition-[translate,scale,opacity] duration-200 hover:bg-muted hover:text-foreground data-[active=false]:pointer-events-none data-[active=false]:scale-95 data-[active=false]:opacity-0 data-[active=false]:duration-400 data-[active=false]:ease-[cubic-bezier(0.7,0,0.84,0)] data-[active=true]:translate-y-0 data-[active=true]:scale-100 data-[active=true]:opacity-100 data-[active=true]:ease-[cubic-bezier(0.23,1,0.32,1)] data-[direction=end]:bottom-4 data-[direction=end]:data-[active=false]:translate-y-full data-[direction=start]:top-4 data-[direction=start]:data-[active=false]:-translate-y-full rtl:translate-x-1/2 data-[direction=start]:[&_svg]:rotate-180",
31
+ "absolute inset-s-1/2 -translate-x-1/2 border-border bg-card text-foreground transition-[translate,scale,opacity] duration-200 hover:bg-muted hover:text-foreground data-[active=false]:pointer-events-none data-[active=false]:scale-95 data-[active=false]:opacity-0 data-[active=false]:duration-400 data-[active=false]:ease-[cubic-bezier(0.7,0,0.84,0)] data-[active=true]:translate-y-0 data-[active=true]:scale-100 data-[active=true]:opacity-100 data-[active=true]:ease-[cubic-bezier(0.23,1,0.32,1)] data-[direction=end]:bottom-4 data-[direction=end]:data-[active=false]:translate-y-full data-[direction=start]:top-4 data-[direction=start]:data-[active=false]:-translate-y-full rtl:translate-x-1/2 data-[direction=start]:[&_svg]:rotate-180",
32
32
  className
33
33
  )}
34
34
  {...restProps}
@@ -30,7 +30,7 @@
30
30
  {align}
31
31
  {collisionPadding}
32
32
  class={cn(
33
- "t-dropdown bg-popover text-popover-foreground ring-foreground/10 rounded-xl p-4 text-sm shadow-raised ring-1 z-50 w-72 max-h-[var(--bits-floating-available-height,100svh)] max-w-[calc(100vw-1rem)] overflow-y-auto overscroll-contain outline-hidden",
33
+ "t-dropdown bg-popover text-popover-foreground rounded-2xl p-4 text-sm shadow-edge-raised z-50 w-72 max-h-[var(--bits-floating-available-height,100svh)] max-w-[calc(100vw-1rem)] overflow-y-auto overscroll-contain outline-hidden",
34
34
  className,
35
35
  )}
36
36
  {...restProps}
@@ -14,7 +14,7 @@
14
14
  bind:ref
15
15
  data-slot="radio-group-item"
16
16
  class={cn(
17
- "border-input text-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 relative after:absolute after:-inset-2 any-pointer-coarse:after:-inset-3.5 aspect-square size-4 shrink-0 rounded-full border shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
17
+ "border-input text-primary focus-visible:border-ring aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 relative after:absolute after:-inset-2 any-pointer-coarse:after:-inset-3.5 aspect-square size-4 shrink-0 rounded-full border shadow-field transition-[color,box-shadow] outline-none focus-visible:shadow-(--ring-focus) disabled:cursor-not-allowed disabled:opacity-50",
18
18
  className,
19
19
  )}
20
20
  {...restProps}