gridsmith-ui 0.8.0 → 0.9.1

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 (40) hide show
  1. package/dist/charts.d.ts +22 -12
  2. package/dist/charts.js +86 -17
  3. package/dist/charts.js.map +1 -1
  4. package/dist/chat.js +4 -3
  5. package/dist/chat.js.map +1 -1
  6. package/dist/{chunk-RLNIRPOH.js → chunk-CQADS7JZ.js} +5 -45
  7. package/dist/chunk-CQADS7JZ.js.map +1 -0
  8. package/dist/{chunk-VXKSQ56H.js → chunk-ENBESZS2.js} +3 -3
  9. package/dist/{chunk-VXKSQ56H.js.map → chunk-ENBESZS2.js.map} +1 -1
  10. package/dist/chunk-FDIFQ5UF.js +67 -0
  11. package/dist/chunk-FDIFQ5UF.js.map +1 -0
  12. package/dist/{chunk-QVNGQ64Q.js → chunk-OVVRMMCO.js} +13 -5
  13. package/dist/chunk-OVVRMMCO.js.map +1 -0
  14. package/dist/chunk-PKLVP5ZB.js +49 -0
  15. package/dist/chunk-PKLVP5ZB.js.map +1 -0
  16. package/dist/chunk-RG4KUCRS.js +9 -0
  17. package/dist/chunk-RG4KUCRS.js.map +1 -0
  18. package/dist/chunk-Z37HO5NU.js +950 -0
  19. package/dist/chunk-Z37HO5NU.js.map +1 -0
  20. package/dist/data-grid.d.ts +3 -1
  21. package/dist/data-grid.js +40 -10
  22. package/dist/data-grid.js.map +1 -1
  23. package/dist/index.d.ts +76 -65
  24. package/dist/index.js +874 -1321
  25. package/dist/index.js.map +1 -1
  26. package/dist/kanban.d.ts +7 -1
  27. package/dist/kanban.js +23 -6
  28. package/dist/kanban.js.map +1 -1
  29. package/dist/resizable.d.ts +48 -2
  30. package/dist/resizable.js +151 -4
  31. package/dist/resizable.js.map +1 -1
  32. package/dist/roots.css +8 -4
  33. package/dist/{use-breakpoint-BfKzmkxx.d.ts → table-utils-GounRE6s.d.ts} +4 -1
  34. package/dist/tokens.css +6 -4
  35. package/dist-static/tokens.css +6 -4
  36. package/package.json +1 -1
  37. package/dist/chunk-5B2ZFL2H.js +0 -89
  38. package/dist/chunk-5B2ZFL2H.js.map +0 -1
  39. package/dist/chunk-QVNGQ64Q.js.map +0 -1
  40. package/dist/chunk-RLNIRPOH.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,163 +1,26 @@
1
- import { ResizablePanelGroup, ResizablePanel, ResizableHandle } from './chunk-5B2ZFL2H.js';
1
+ import { useAppShell, ControlSizeContext, Button, Spinner, DrawerFooterCtx, useCompact, useElementWidth, Sheet, useCloseSettle, Drawer, useRememberedWidth, pxOf, ResizeEdge, useDirtyGuard, DiscardConfirm, defaultMaxWidth } from './chunk-Z37HO5NU.js';
2
+ export { AppShell, Button, ButtonSizeContext, ControlSizeContext, Drawer, Sheet, SkipLink, Spinner, useAppShell } from './chunk-Z37HO5NU.js';
2
3
  import { Skeleton } from './chunk-M3AARGLI.js';
3
4
  export { Skeleton } from './chunk-M3AARGLI.js';
4
- import { useOverlayLayer, useCloseOnFocusOut, useReturnFocus, focusInitial, useFocusTrap, OVERLAY_CLOSE_ATTR, useNonModalDialog, rovingTabStop } from './chunk-RLUK575N.js';
5
- import { Link } from './chunk-VXKSQ56H.js';
6
- export { CodeBlock, Divider, Link } from './chunk-VXKSQ56H.js';
7
- import { Badge } from './chunk-QVNGQ64Q.js';
8
- export { Badge } from './chunk-QVNGQ64Q.js';
9
- import { useBreakpoint, readBreakpointPx } from './chunk-CRQ6KCRD.js';
5
+ import { useOverlayLayer, useCloseOnFocusOut, focusInitial, rovingTabStop, OVERLAY_CLOSE_ATTR, useNonModalDialog, useFocusTrap } from './chunk-RLUK575N.js';
6
+ import { Link } from './chunk-ENBESZS2.js';
7
+ export { CodeBlock, Divider, Link } from './chunk-ENBESZS2.js';
8
+ import { Badge } from './chunk-OVVRMMCO.js';
9
+ export { Badge } from './chunk-OVVRMMCO.js';
10
+ import { inferColumnKinds, CardValue } from './chunk-FDIFQ5UF.js';
11
+ import { SplitPaneCtx, TableCardCtx } from './chunk-RG4KUCRS.js';
12
+ import { useBreakpoint } from './chunk-CRQ6KCRD.js';
10
13
  export { BreakpointWidthProvider, useBreakpoint } from './chunk-CRQ6KCRD.js';
11
- import { Tooltip, useTextOverflow, usePosition, Slot } from './chunk-RLNIRPOH.js';
12
- export { Tooltip, useTextOverflow } from './chunk-RLNIRPOH.js';
14
+ import { useTextOverflow, Tooltip, usePosition } from './chunk-CQADS7JZ.js';
15
+ export { Tooltip, useTextOverflow } from './chunk-CQADS7JZ.js';
16
+ import { mergeRefs, Slot } from './chunk-PKLVP5ZB.js';
13
17
  import { useLatest } from './chunk-WH2FUFAC.js';
14
18
  import { Icon } from './chunk-X4CNZFWC.js';
15
- import { cn, GLASS_SURFACE, ACTIVE_RING, GLASS_BACKDROP, GLASS_DROPDOWN, lockBodyScroll, unlockBodyScroll, GLASS_OVERLAY, ERROR_ACTIVE_RING, ERROR_FOCUS_RING, FOCUS_RING, ERROR_HAS_FOCUS_RING, HAS_FOCUS_RING, ERROR_FOCUS_WITHIN_RING, FOCUS_WITHIN_RING } from './chunk-4KVFH5KC.js';
16
- import { createContext, forwardRef, useContext, useState, memo, useCallback, useRef, useEffect, useLayoutEffect, Children, useId, isValidElement, cloneElement, Fragment as Fragment$1, useMemo, useSyncExternalStore } from 'react';
17
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
19
+ import { cn, GLASS_SURFACE, ACTIVE_RING, GLASS_BACKDROP, GLASS_DROPDOWN, ERROR_ACTIVE_RING, ERROR_FOCUS_RING, FOCUS_RING, ERROR_HAS_FOCUS_RING, HAS_FOCUS_RING, ERROR_FOCUS_WITHIN_RING, FOCUS_WITHIN_RING, lockBodyScroll, unlockBodyScroll, GLASS_OVERLAY } from './chunk-4KVFH5KC.js';
20
+ import { createContext, forwardRef, useState, useContext, memo, useEffect, useRef, useCallback, useLayoutEffect, Children, useMemo, useId, isValidElement, cloneElement, Fragment as Fragment$1, useSyncExternalStore } from 'react';
18
21
  import { createPortal } from 'react-dom';
22
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
19
23
 
20
- var sizes = {
21
- sm: "h-4 w-4 border-[1.5px]",
22
- md: "h-6 w-6 border-2",
23
- lg: "h-8 w-8 border-[2.5px]"
24
- };
25
- function Spinner({ size = "md", color = "default", label = "Loading", className }) {
26
- return /* @__PURE__ */ jsx(
27
- "span",
28
- {
29
- role: "status",
30
- "aria-label": label,
31
- className: cn(
32
- "inline-block rounded-[var(--ds-radius-full)] animate-spin",
33
- color === "inherit" ? "border-current/30 border-t-current" : "border-[var(--ds-bg-emphasis)] border-t-[var(--ds-accent-primary)]",
34
- sizes[size],
35
- className
36
- )
37
- }
38
- );
39
- }
40
- var ButtonSizeContext = createContext(null);
41
- var variantStyles = {
42
- default: "bg-[var(--ds-accent-primary)] [background-image:var(--ds-gradient)] [background-origin:border-box] text-[var(--ds-text-on-primary)] border-transparent hover:bg-[var(--ds-accent-primary-hover)] hover:brightness-110",
43
- secondary: "bg-[var(--ds-bg-surface)] text-[var(--ds-text-primary)] border-[var(--ds-border-default)] hover:bg-[var(--ds-bg-muted)]",
44
- tertiary: "bg-[var(--ds-bg-muted)] text-[var(--ds-text-primary)] border-transparent hover:brightness-95",
45
- outline: "bg-[var(--ds-input-bg)] text-[var(--ds-text-primary)] border-[var(--ds-border-default)] hover:bg-[var(--ds-bg-muted)]",
46
- ghost: "bg-transparent text-[var(--ds-text-primary)] border-transparent hover:bg-[var(--ds-bg-muted)] shadow-none",
47
- destructive: "bg-[var(--ds-status-error)] text-[var(--ds-text-on-error)] border-transparent hover:opacity-90",
48
- success: "bg-[var(--ds-status-success)] text-[var(--ds-text-on-success)] border-transparent hover:opacity-90",
49
- warning: "bg-[var(--ds-status-warning)] text-[var(--ds-text-on-warning)] border-transparent hover:opacity-90",
50
- link: "bg-transparent text-[var(--ds-accent-primary)] hover:text-[var(--ds-accent-primary-hover)] hover:underline"
51
- };
52
- var sizeStyles = {
53
- // xs / icon-xs: dense tool chrome (builder toolbars, inline row actions).
54
- xs: "h-ds-6 px-ds-3 py-0 text-xs",
55
- sm: "h-ds-8 px-ds-4 py-ds-1 text-xs",
56
- md: "h-ds-10 px-ds-6 py-ds-2 text-sm",
57
- lg: "h-ds-12 px-ds-8 py-ds-3 text-base",
58
- "icon-xs": "h-ds-6 w-ds-6 p-0",
59
- "icon-sm": "h-ds-8 w-ds-8 p-0",
60
- icon: "h-ds-10 w-ds-10 p-0",
61
- "icon-lg": "h-ds-12 w-ds-12 p-0"
62
- };
63
- var linkSizeStyles = {
64
- xs: "text-xs",
65
- sm: "text-xs",
66
- md: "text-sm",
67
- lg: "text-base",
68
- "icon-xs": "text-xs",
69
- "icon-sm": "text-xs",
70
- icon: "text-sm",
71
- "icon-lg": "text-base"
72
- };
73
- var iconPaddingReduce = {
74
- xs: 2,
75
- sm: 2,
76
- md: 4,
77
- lg: 6
78
- };
79
- var HOVER_SCALE_CAP = { "--_btn-scale": "min(var(--ds-hover-scale), 1.02)" };
80
- var Button = forwardRef(function Button2({ variant = "default", size: sizeProp, iconLeft, iconRight, loading, className, children, disabled, style, onClick, ...props }, ref) {
81
- const contextSize = useContext(ButtonSizeContext);
82
- const size = sizeProp ?? contextSize ?? "md";
83
- const isLink = variant === "link";
84
- const spinnerSize = size === "lg" || size === "icon-lg" ? "md" : "sm";
85
- let paddingStyle;
86
- const isIconSize = size === "icon" || size === "icon-xs" || size === "icon-sm" || size === "icon-lg";
87
- if (!isIconSize && !isLink && (iconLeft || iconRight)) {
88
- const reduce = iconPaddingReduce[size];
89
- paddingStyle = {};
90
- if (iconLeft) paddingStyle.paddingLeft = `calc(${getCssPadding(size)} - ${reduce}px)`;
91
- if (iconRight) paddingStyle.paddingRight = `calc(${getCssPadding(size)} - ${reduce}px)`;
92
- }
93
- const isLoading = loading && !disabled;
94
- const isDisabled = !!disabled;
95
- const handleClick = isLoading ? (e) => {
96
- e.preventDefault();
97
- } : onClick;
98
- const ariaLabel = props["aria-label"];
99
- const btn = /* @__PURE__ */ jsxs(
100
- "button",
101
- {
102
- ref,
103
- "data-variant": variant,
104
- className: cn(
105
- "relative inline-flex items-center justify-center gap-ds-2 whitespace-nowrap font-medium",
106
- isLink ? cn(
107
- "px-0 py-ds-0.5 h-auto",
108
- linkSizeStyles[size],
109
- "transition-colors duration-[var(--ds-transition-speed)]",
110
- "focus-visible:outline-2 focus-visible:outline-[var(--ds-accent-primary)] focus-visible:outline-offset-2",
111
- "cursor-pointer",
112
- "active:text-[var(--ds-accent-primary-active)]"
113
- ) : cn(
114
- "border-[length:var(--ds-border-width)]",
115
- "rounded-[var(--ds-radius-md)]",
116
- "shadow-[var(--ds-shadow-button)]",
117
- "hover:scale-[var(--_btn-scale)] hover:-translate-y-[var(--ds-hover-lift)]",
118
- "active:shadow-[var(--ds-shadow-button-pressed)] active:translate-x-[var(--ds-press-depth)] active:translate-y-[var(--ds-press-depth)]",
119
- "[transition:var(--ds-transition-interactive)]",
120
- "focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]",
121
- "cursor-pointer disabled:cursor-not-allowed disabled:opacity-disabled",
122
- sizeStyles[size]
123
- ),
124
- variantStyles[variant],
125
- isLoading && !isLink && "cursor-wait pointer-events-none",
126
- className
127
- ),
128
- disabled: isDisabled,
129
- "aria-busy": isLoading || void 0,
130
- "aria-disabled": isLoading && !disabled ? true : void 0,
131
- onClick: handleClick,
132
- style: isLink ? style : { ...HOVER_SCALE_CAP, ...paddingStyle, ...style },
133
- ...props,
134
- children: [
135
- loading && !isLink && /* @__PURE__ */ jsx("span", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx(Spinner, { size: spinnerSize, color: "inherit" }) }),
136
- /* @__PURE__ */ jsxs("span", { className: cn("inline-flex items-center gap-ds-2 min-w-0", loading && !isLink && "invisible"), children: [
137
- iconLeft,
138
- children,
139
- iconRight
140
- ] })
141
- ]
142
- }
143
- );
144
- if (isIconSize && ariaLabel) {
145
- return /* @__PURE__ */ jsx(Tooltip, { content: ariaLabel, children: btn });
146
- }
147
- return btn;
148
- });
149
- function getCssPadding(size) {
150
- switch (size) {
151
- case "xs":
152
- return "var(--ds-space-3)";
153
- case "sm":
154
- return "var(--ds-space-4)";
155
- case "md":
156
- return "var(--ds-space-6)";
157
- case "lg":
158
- return "var(--ds-space-8)";
159
- }
160
- }
161
24
  function isDivider(entry) {
162
25
  return "type" in entry && entry.type === "divider";
163
26
  }
@@ -233,6 +96,7 @@ function DropdownMenu({ trigger, items, align = "end", className, container }) {
233
96
  {
234
97
  ref: menuRef,
235
98
  role: "menu",
99
+ "data-gs": "menu",
236
100
  onKeyDown: handleMenuKeyDown,
237
101
  className: cn(
238
102
  "fixed z-[var(--ds-z-popover)] min-w-[180px] p-ds-1",
@@ -337,7 +201,19 @@ function BulkActionBar({ selectedCount, actions, onClearSelection, className })
337
201
  }
338
202
  );
339
203
  }
340
- function Input({ className, size = "md", error = false, prefix, suffix, ...props }) {
204
+ var INPUT_HEIGHT = {
205
+ sm: "h-[var(--ds-control-height-sm)]",
206
+ md: "h-[var(--ds-control-height-md)]",
207
+ lg: "h-[var(--ds-control-height-lg)]"
208
+ };
209
+ var INPUT_TEXT = {
210
+ sm: "px-ds-2 py-ds-1 text-xs",
211
+ md: "px-ds-3 py-ds-2 text-sm",
212
+ lg: "px-ds-4 py-ds-3 text-base"
213
+ };
214
+ function Input({ className, size: sizeProp, error = false, prefix, suffix, ...props }) {
215
+ const contextSize = useContext(ControlSizeContext);
216
+ const size = sizeProp ?? contextSize ?? "md";
341
217
  const borderColor = error ? "border-[var(--ds-status-error)]" : "border-[var(--ds-input-border)]";
342
218
  const hoverBorder = !error && !props.disabled && !props.readOnly ? "hover:border-[var(--ds-input-border-hover)]" : "";
343
219
  if (prefix || suffix) {
@@ -346,7 +222,7 @@ function Input({ className, size = "md", error = false, prefix, suffix, ...props
346
222
  {
347
223
  className: cn(
348
224
  "flex items-center w-full",
349
- size === "sm" ? "h-[var(--ds-control-height-sm)]" : "h-[var(--ds-control-height-md)]",
225
+ INPUT_HEIGHT[size],
350
226
  "bg-[var(--ds-input-bg)]",
351
227
  "border-[length:var(--ds-border-width)]",
352
228
  borderColor,
@@ -367,7 +243,7 @@ function Input({ className, size = "md", error = false, prefix, suffix, ...props
367
243
  "aria-invalid": error || void 0,
368
244
  className: cn(
369
245
  "flex-1 min-w-0 bg-transparent outline-none",
370
- size === "sm" ? "px-ds-2 py-ds-1 text-xs" : "px-ds-3 py-ds-2 text-sm",
246
+ INPUT_TEXT[size],
371
247
  "text-[var(--ds-text-primary)]",
372
248
  "placeholder:text-[var(--ds-text-muted)]",
373
249
  "disabled:cursor-not-allowed",
@@ -387,7 +263,8 @@ function Input({ className, size = "md", error = false, prefix, suffix, ...props
387
263
  "aria-invalid": error || void 0,
388
264
  className: cn(
389
265
  "flex w-full",
390
- size === "sm" ? "px-ds-2 py-ds-1 text-xs h-[var(--ds-control-height-sm)]" : "px-ds-3 py-ds-2 text-sm h-[var(--ds-control-height-md)]",
266
+ INPUT_TEXT[size],
267
+ INPUT_HEIGHT[size],
391
268
  "bg-[var(--ds-input-bg)] text-[var(--ds-text-primary)]",
392
269
  "border-[length:var(--ds-border-width)]",
393
270
  borderColor,
@@ -429,7 +306,7 @@ function Textarea({ className, autoResize, maxRows, error = false, ref, ...props
429
306
  ref: textareaRef,
430
307
  "aria-invalid": error || void 0,
431
308
  className: cn(
432
- "flex min-h-[80px] w-full px-ds-3 py-ds-2 text-sm",
309
+ "flex min-h-[var(--ds-control-height-md)] w-full px-ds-3 py-ds-2 text-sm",
433
310
  "bg-[var(--ds-input-bg)] text-[var(--ds-text-primary)]",
434
311
  "border-[length:var(--ds-border-width)]",
435
312
  error ? "border-[var(--ds-status-error)]" : "border-[var(--ds-input-border)] hover:border-[var(--ds-input-border-hover)]",
@@ -527,6 +404,11 @@ function Toggle({ checked, onChange, label, disabled, error = false, layout = "f
527
404
  }
528
405
  );
529
406
  }
407
+ var DROPDOWN_HEIGHT = {
408
+ sm: "px-ds-2 py-ds-1 text-xs h-[var(--ds-control-height-sm)]",
409
+ md: "px-ds-3 py-ds-2 text-sm h-[var(--ds-control-height-md)]",
410
+ lg: "px-ds-4 py-ds-3 text-base h-[var(--ds-control-height-lg)]"
411
+ };
530
412
  function Dropdown({
531
413
  options,
532
414
  value,
@@ -536,7 +418,7 @@ function Dropdown({
536
418
  placeholder = "Select...",
537
419
  multiple,
538
420
  searchable,
539
- size = "md",
421
+ size: sizeProp,
540
422
  className,
541
423
  ref,
542
424
  container,
@@ -544,6 +426,8 @@ function Dropdown({
544
426
  showChips = true,
545
427
  "aria-label": ariaLabel
546
428
  }) {
429
+ const contextSize = useContext(ControlSizeContext);
430
+ const size = sizeProp ?? contextSize ?? "md";
547
431
  const [open, setOpen] = useState(false);
548
432
  const [search, setSearch] = useState("");
549
433
  const [positioned, setPositioned] = useState(false);
@@ -711,7 +595,7 @@ function Dropdown({
711
595
  "aria-label": ariaLabel,
712
596
  className: cn(
713
597
  "w-full flex items-center justify-between gap-ds-2",
714
- size === "sm" ? "px-ds-2 py-ds-1 text-xs h-[var(--ds-control-height-sm)]" : "px-ds-3 py-ds-2 text-sm h-[var(--ds-control-height-md)]",
598
+ DROPDOWN_HEIGHT[size],
715
599
  "bg-[var(--ds-input-bg)] text-[var(--ds-text-primary)]",
716
600
  "border-[length:var(--ds-border-width)]",
717
601
  error ? "border-[var(--ds-status-error)]" : "border-[var(--ds-input-border)]",
@@ -848,7 +732,19 @@ function OptionButton({
848
732
  }
849
733
  );
850
734
  }
851
- function Combobox({ value, onChange, options, placeholder = "Search\u2026", disabled, loading = false, className, ref, container, error = false }) {
735
+ var CONTROL_HEIGHT = {
736
+ sm: "h-[var(--ds-control-height-sm)]",
737
+ md: "h-[var(--ds-control-height-md)]",
738
+ lg: "h-[var(--ds-control-height-lg)]"
739
+ };
740
+ var TEXT_SIZE = {
741
+ sm: "text-xs",
742
+ md: "text-sm",
743
+ lg: "text-base"
744
+ };
745
+ function Combobox({ value, onChange, options, placeholder = "Search\u2026", disabled, loading = false, className, ref, container, error = false, size: sizeProp }) {
746
+ const contextSize = useContext(ControlSizeContext);
747
+ const size = sizeProp ?? contextSize ?? "md";
852
748
  const [open, setOpen] = useState(false);
853
749
  useOverlayLayer(open);
854
750
  const [query, setQuery] = useState("");
@@ -939,7 +835,7 @@ function Combobox({ value, onChange, options, placeholder = "Search\u2026", disa
939
835
  {
940
836
  className: cn(
941
837
  "flex items-center",
942
- "h-[var(--ds-control-height-md)]",
838
+ CONTROL_HEIGHT[size],
943
839
  "border-[length:var(--ds-border-width)]",
944
840
  error ? "border-[var(--ds-status-error)]" : "border-[var(--ds-input-border)]",
945
841
  "bg-[var(--ds-input-bg)] rounded-[var(--ds-radius-md)]",
@@ -975,7 +871,9 @@ function Combobox({ value, onChange, options, placeholder = "Search\u2026", disa
975
871
  onBlur: handleBlur,
976
872
  onKeyDown: handleKeyDown,
977
873
  className: cn(
978
- "flex-1 bg-transparent text-sm text-[var(--ds-text-primary)] placeholder:text-[var(--ds-text-muted)]",
874
+ "flex-1 bg-transparent",
875
+ TEXT_SIZE[size],
876
+ "text-[var(--ds-text-primary)] placeholder:text-[var(--ds-text-muted)]",
979
877
  "outline-none min-w-0",
980
878
  "py-ds-2 px-ds-2"
981
879
  )
@@ -1225,6 +1123,16 @@ function RadioGroup({ value, onChange, options, orientation = "vertical", classN
1225
1123
  )
1226
1124
  ] });
1227
1125
  }
1126
+ var CONTROL_HEIGHT2 = {
1127
+ sm: "h-[var(--ds-control-height-sm)]",
1128
+ md: "h-[var(--ds-control-height-md)]",
1129
+ lg: "h-[var(--ds-control-height-lg)]"
1130
+ };
1131
+ var TEXT_SIZE2 = {
1132
+ sm: "text-xs",
1133
+ md: "text-sm",
1134
+ lg: "text-base"
1135
+ };
1228
1136
  var DAYS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
1229
1137
  var MONTHS = [
1230
1138
  "January",
@@ -1252,7 +1160,9 @@ function isSameDay(a, b) {
1252
1160
  function formatDate(d) {
1253
1161
  return `${MONTHS[d.getMonth()].slice(0, 3)} ${d.getDate()}, ${d.getFullYear()}`;
1254
1162
  }
1255
- function DatePicker({ value, onChange, placeholder = "Pick a date", disabled, className, ref, container, error = false, label, id, min, max, range }) {
1163
+ function DatePicker({ value, onChange, placeholder = "Pick a date", disabled, className, ref, container, error = false, label, id, size: sizeProp, min, max, range }) {
1164
+ const contextSize = useContext(ControlSizeContext);
1165
+ const size = sizeProp ?? contextSize ?? "md";
1256
1166
  const [open, setOpen] = useState(false);
1257
1167
  const [hover, setHover] = useState(null);
1258
1168
  const [viewDate, setViewDate] = useState(() => value ?? range?.start ?? range?.end ?? /* @__PURE__ */ new Date());
@@ -1328,8 +1238,9 @@ function DatePicker({ value, onChange, placeholder = "Pick a date", disabled, cl
1328
1238
  "aria-haspopup": "dialog",
1329
1239
  "aria-expanded": open,
1330
1240
  className: cn(
1331
- "flex items-center gap-ds-2 text-sm w-full",
1332
- "h-[var(--ds-control-height-md)]",
1241
+ "flex items-center gap-ds-2 w-full",
1242
+ CONTROL_HEIGHT2[size],
1243
+ TEXT_SIZE2[size],
1333
1244
  "border-[length:var(--ds-border-width)]",
1334
1245
  error ? "border-[var(--ds-status-error)]" : "border-[var(--ds-input-border)]",
1335
1246
  "bg-[var(--ds-input-bg)] rounded-[var(--ds-radius-md)]",
@@ -1622,6 +1533,16 @@ function getOverlappingGroups(events) {
1622
1533
  function timeToFraction(d) {
1623
1534
  return (d.getHours() * 60 + d.getMinutes()) / (24 * 60);
1624
1535
  }
1536
+ var CONTROL_HEIGHT3 = {
1537
+ sm: "h-[var(--ds-control-height-sm)]",
1538
+ md: "h-[var(--ds-control-height-md)]",
1539
+ lg: "h-[var(--ds-control-height-lg)]"
1540
+ };
1541
+ var TEXT_SIZE3 = {
1542
+ sm: "text-xs",
1543
+ md: "text-sm",
1544
+ lg: "text-base"
1545
+ };
1625
1546
  var MONTHS2 = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
1626
1547
  function fmt(d) {
1627
1548
  return `${MONTHS2[d.getMonth()].slice(0, 3)} ${d.getDate()}, ${d.getFullYear()}`;
@@ -1662,8 +1583,11 @@ function DateRangePicker({
1662
1583
  min,
1663
1584
  max,
1664
1585
  presets = DEFAULT_DATE_RANGE_PRESETS,
1665
- weekStartsOn = 0
1586
+ weekStartsOn = 0,
1587
+ size: sizeProp
1666
1588
  }) {
1589
+ const contextSize = useContext(ControlSizeContext);
1590
+ const size = sizeProp ?? contextSize ?? "md";
1667
1591
  const [open, setOpen] = useState(false);
1668
1592
  const [viewDate, setViewDate] = useState(() => value.start ?? /* @__PURE__ */ new Date());
1669
1593
  const [hover, setHover] = useState(null);
@@ -1734,8 +1658,9 @@ function DateRangePicker({
1734
1658
  "aria-haspopup": "dialog",
1735
1659
  "aria-expanded": open,
1736
1660
  className: cn(
1737
- "flex items-center gap-ds-2 text-sm w-full",
1738
- "h-[var(--ds-control-height-md)]",
1661
+ "flex items-center gap-ds-2 w-full",
1662
+ CONTROL_HEIGHT3[size],
1663
+ TEXT_SIZE3[size],
1739
1664
  "border-[length:var(--ds-border-width)]",
1740
1665
  error ? "border-[var(--ds-status-error)]" : "border-[var(--ds-input-border)]",
1741
1666
  "bg-[var(--ds-input-bg)] rounded-[var(--ds-radius-md)]",
@@ -2155,6 +2080,16 @@ function SliderRange({
2155
2080
  )
2156
2081
  ] });
2157
2082
  }
2083
+ var CONTROL_HEIGHT4 = {
2084
+ sm: "h-[var(--ds-control-height-sm)]",
2085
+ md: "h-[var(--ds-control-height-md)]",
2086
+ lg: "h-[var(--ds-control-height-lg)]"
2087
+ };
2088
+ var TEXT_SIZE4 = {
2089
+ sm: "text-xs",
2090
+ md: "text-sm",
2091
+ lg: "text-base"
2092
+ };
2158
2093
  function pad(n) {
2159
2094
  return n.toString().padStart(2, "0");
2160
2095
  }
@@ -2190,8 +2125,11 @@ function TimePicker({
2190
2125
  ref,
2191
2126
  container,
2192
2127
  error = false,
2193
- id
2128
+ id,
2129
+ size: sizeProp
2194
2130
  }) {
2131
+ const contextSize = useContext(ControlSizeContext);
2132
+ const size = sizeProp ?? contextSize ?? "md";
2195
2133
  const [open, setOpen] = useState(false);
2196
2134
  const triggerRef = useRef(null);
2197
2135
  const panelRef = useRef(null);
@@ -2272,7 +2210,9 @@ function TimePicker({
2272
2210
  "aria-expanded": open,
2273
2211
  "aria-controls": open ? listboxId : void 0,
2274
2212
  className: cn(
2275
- "flex w-full items-center gap-ds-2 text-sm",
2213
+ "flex w-full items-center gap-ds-2",
2214
+ CONTROL_HEIGHT4[size],
2215
+ TEXT_SIZE4[size],
2276
2216
  "border-[length:var(--ds-border-width)]",
2277
2217
  error ? "border-[var(--ds-status-error)]" : "border-[var(--ds-input-border)]",
2278
2218
  "bg-[var(--ds-input-bg)] rounded-[var(--ds-radius-md)]",
@@ -2367,10 +2307,10 @@ function TimePicker({
2367
2307
  )
2368
2308
  ] });
2369
2309
  }
2370
- var sizes2 = {
2371
- sm: { input: "text-xs h-8", btn: "w-7 text-xs" },
2372
- md: { input: "text-sm h-10", btn: "w-9 text-sm" },
2373
- lg: { input: "text-base h-12", btn: "w-10 text-base" }
2310
+ var sizes = {
2311
+ sm: { box: "h-[var(--ds-control-height-sm)]", input: "text-xs self-stretch", btn: "w-7 text-xs" },
2312
+ md: { box: "h-[var(--ds-control-height-md)]", input: "text-sm self-stretch", btn: "w-9 text-sm" },
2313
+ lg: { box: "h-[var(--ds-control-height-lg)]", input: "text-base self-stretch", btn: "w-10 text-base" }
2374
2314
  };
2375
2315
  function NumberInput({
2376
2316
  value,
@@ -2382,12 +2322,14 @@ function NumberInput({
2382
2322
  placeholder = "0",
2383
2323
  prefix,
2384
2324
  suffix,
2385
- size = "md",
2325
+ size: sizeProp,
2386
2326
  className,
2387
2327
  error = false,
2388
2328
  allowDecimals,
2389
2329
  id
2390
2330
  }) {
2331
+ const contextSize = useContext(ControlSizeContext);
2332
+ const size = sizeProp ?? contextSize ?? "md";
2391
2333
  const intervalRef = useRef(void 0);
2392
2334
  const timeoutRef = useRef(void 0);
2393
2335
  const inputRef = useRef(null);
@@ -2399,18 +2341,18 @@ function NumberInput({
2399
2341
  setPrevSync({ value, focused });
2400
2342
  if (!focused) setDraft(String(value));
2401
2343
  }
2402
- const clamp2 = useCallback(
2344
+ const clamp = useCallback(
2403
2345
  (v) => Math.min(max, Math.max(min, v)),
2404
2346
  [min, max]
2405
2347
  );
2406
2348
  const valueRef = useLatest(value);
2407
2349
  const commitValue = useCallback((v) => {
2408
- const clamped = clamp2(v);
2350
+ const clamped = clamp(v);
2409
2351
  valueRef.current = clamped;
2410
2352
  setDraft(String(clamped));
2411
2353
  onChange(clamped);
2412
2354
  return clamped;
2413
- }, [onChange, clamp2, valueRef]);
2355
+ }, [onChange, clamp, valueRef]);
2414
2356
  const increment = useCallback(() => commitValue(valueRef.current + step), [commitValue, step, valueRef]);
2415
2357
  const decrement = useCallback(() => commitValue(valueRef.current - step), [commitValue, step, valueRef]);
2416
2358
  const startRepeat = useCallback(
@@ -2439,10 +2381,10 @@ function NumberInput({
2439
2381
  setDraft(raw);
2440
2382
  const parsed = parseFloat(raw);
2441
2383
  if (!isNaN(parsed) && isFinite(parsed)) {
2442
- onChange(clamp2(parsed));
2384
+ onChange(clamp(parsed));
2443
2385
  }
2444
2386
  },
2445
- [onChange, clamp2, decimals]
2387
+ [onChange, clamp, decimals]
2446
2388
  );
2447
2389
  const handleBlur = useCallback(() => {
2448
2390
  setFocused(false);
@@ -2472,7 +2414,7 @@ function NumberInput({
2472
2414
  },
2473
2415
  [increment, decrement]
2474
2416
  );
2475
- const s = sizes2[size];
2417
+ const s = sizes[size];
2476
2418
  const atMin = value <= min;
2477
2419
  const atMax = value >= max;
2478
2420
  return /* @__PURE__ */ jsxs(
@@ -2480,6 +2422,7 @@ function NumberInput({
2480
2422
  {
2481
2423
  className: cn(
2482
2424
  "flex items-center w-full",
2425
+ s.box,
2483
2426
  "border-[length:var(--ds-border-width)]",
2484
2427
  error ? "border-[var(--ds-status-error)]" : "border-[var(--ds-input-border)]",
2485
2428
  "rounded-[var(--ds-radius-md)]",
@@ -2579,7 +2522,7 @@ function NumberInput({
2579
2522
  }
2580
2523
  );
2581
2524
  }
2582
- var variantStyles2 = {
2525
+ var variantStyles = {
2583
2526
  default: "bg-[var(--ds-bg-emphasis)] text-[var(--ds-text-primary)]",
2584
2527
  subtle: "bg-[var(--ds-bg-muted)] text-[var(--ds-text-secondary)]",
2585
2528
  success: "bg-[var(--ds-status-success-bg)] text-[var(--ds-status-success)] border-[length:var(--ds-border-width)] border-[var(--ds-status-success)]/[0.2]",
@@ -2587,7 +2530,7 @@ var variantStyles2 = {
2587
2530
  error: "bg-[var(--ds-status-error-bg)] text-[var(--ds-status-error)] border-[length:var(--ds-border-width)] border-[var(--ds-status-error)]/[0.2]",
2588
2531
  outline: "bg-transparent text-[var(--ds-text-primary)] border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]"
2589
2532
  };
2590
- var sizeStyles2 = {
2533
+ var sizeStyles = {
2591
2534
  sm: "px-ds-1 py-[calc(var(--ds-space-1)*0.5)] text-[length:var(--ds-font-size-xs)] gap-[calc(var(--ds-space-1)*0.5)]",
2592
2535
  md: "px-ds-2 py-[calc(var(--ds-space-1)*0.5)] text-[length:var(--ds-font-size-xs)] gap-ds-1"
2593
2536
  };
@@ -2637,7 +2580,7 @@ var Tag = forwardRef(function Tag2({
2637
2580
  e.stopPropagation();
2638
2581
  onRemove?.();
2639
2582
  };
2640
- const colorClasses = color ? getPaletteClasses(color, variant) : variantStyles2[variant];
2583
+ const colorClasses = color ? getPaletteClasses(color, variant) : variantStyles[variant];
2641
2584
  const tag = /* @__PURE__ */ jsxs(
2642
2585
  "span",
2643
2586
  {
@@ -2656,7 +2599,7 @@ var Tag = forwardRef(function Tag2({
2656
2599
  "inline-flex items-center font-medium max-w-full whitespace-nowrap",
2657
2600
  "rounded-[var(--ds-radius-sm)]",
2658
2601
  "transition-colors duration-[var(--ds-transition-speed)]",
2659
- sizeStyles2[size],
2602
+ sizeStyles[size],
2660
2603
  colorClasses,
2661
2604
  onClick && !disabled && "cursor-pointer select-none hover:opacity-80",
2662
2605
  disabled && "opacity-disabled cursor-not-allowed",
@@ -2802,10 +2745,10 @@ function TagInput({
2802
2745
  }
2803
2746
  );
2804
2747
  }
2805
- var sizes3 = {
2806
- sm: "w-8 h-8 text-sm",
2807
- md: "w-10 h-10 text-base",
2808
- lg: "w-12 h-12 text-lg"
2748
+ var sizes2 = {
2749
+ sm: "w-[var(--ds-control-height-sm)] h-[var(--ds-control-height-sm)] text-sm",
2750
+ md: "w-[var(--ds-control-height-md)] h-[var(--ds-control-height-md)] text-base",
2751
+ lg: "w-[var(--ds-control-height-lg)] h-[var(--ds-control-height-lg)] text-lg"
2809
2752
  };
2810
2753
  function PinInput({
2811
2754
  value,
@@ -2813,11 +2756,13 @@ function PinInput({
2813
2756
  length = 6,
2814
2757
  mask = false,
2815
2758
  disabled = false,
2816
- size = "md",
2759
+ size: sizeProp,
2817
2760
  className,
2818
2761
  error = false,
2819
2762
  id
2820
2763
  }) {
2764
+ const contextSize = useContext(ControlSizeContext);
2765
+ const size = sizeProp ?? contextSize ?? "md";
2821
2766
  const inputsRef = useRef([]);
2822
2767
  const digits = value.padEnd(length, " ").slice(0, length).split("");
2823
2768
  const focusAt = useCallback((idx) => {
@@ -2903,7 +2848,7 @@ function PinInput({
2903
2848
  !error && !disabled && "hover:border-[var(--ds-input-border-hover)]",
2904
2849
  error ? ERROR_FOCUS_RING : FOCUS_RING,
2905
2850
  "placeholder:text-[var(--ds-text-muted)]",
2906
- sizes3[size],
2851
+ sizes2[size],
2907
2852
  disabled && "opacity-disabled cursor-not-allowed"
2908
2853
  )
2909
2854
  },
@@ -3346,7 +3291,7 @@ function Field({ label, children, hint, error, required, labelAction, id: idProp
3346
3291
  hasError && /* @__PURE__ */ jsx(InlineFieldError, { id: errorId, message: error, className: "mt-0" })
3347
3292
  ] });
3348
3293
  }
3349
- var variantStyles3 = {
3294
+ var variantStyles2 = {
3350
3295
  info: "border-[var(--ds-accent-primary)] bg-[var(--ds-accent-subtle)]",
3351
3296
  success: "border-[var(--ds-status-success)] bg-[var(--ds-status-success-bg)]",
3352
3297
  warning: "border-[var(--ds-status-warning)] bg-[var(--ds-status-warning-bg)]",
@@ -3391,7 +3336,7 @@ var Alert = forwardRef(function Alert2({
3391
3336
  "border-[length:var(--ds-border-width)]",
3392
3337
  "shadow-[var(--ds-shadow-sm)]",
3393
3338
  "text-sm text-[var(--ds-text-primary)]",
3394
- variantStyles3[variant],
3339
+ variantStyles2[variant],
3395
3340
  placementClasses,
3396
3341
  className
3397
3342
  ),
@@ -3487,6 +3432,13 @@ var Alert = forwardRef(function Alert2({
3487
3432
  }
3488
3433
  );
3489
3434
  });
3435
+ function stampFormId(node, formId) {
3436
+ return Children.map(node, (child) => {
3437
+ if (!isValidElement(child)) return child;
3438
+ if (child.type === Fragment$1) return stampFormId(child.props.children, formId);
3439
+ return cloneElement(child, { form: formId });
3440
+ });
3441
+ }
3490
3442
  var FormCtx = createContext(null);
3491
3443
  function useFormContext() {
3492
3444
  const ctx = useContext(FormCtx);
@@ -3516,6 +3468,13 @@ function FormWrapper({ onSubmit, validationMode = "onSubmit", children, actions,
3516
3468
  if (typeof ref === "function") ref(node);
3517
3469
  else if (ref) ref.current = node;
3518
3470
  }, [ref]);
3471
+ const drawerFooter = useContext(DrawerFooterCtx);
3472
+ const formId = useId();
3473
+ useEffect(() => {
3474
+ if (!drawerFooter || !actions) return;
3475
+ drawerFooter.registerActions(formId, stampFormId(actions, formId));
3476
+ return () => drawerFooter.unregisterActions(formId);
3477
+ }, [drawerFooter, actions, formId]);
3519
3478
  const pendingSubmit = useRef(false);
3520
3479
  const pendingFocus = useRef(false);
3521
3480
  const onSubmitRef = useLatest(onSubmit);
@@ -3588,10 +3547,11 @@ function FormWrapper({ onSubmit, validationMode = "onSubmit", children, actions,
3588
3547
  ": ",
3589
3548
  f.message
3590
3549
  ] }, f.id || f.label)) }) }) : null;
3591
- return /* @__PURE__ */ jsx(FormCtx.Provider, { value: { errors, setError, clearErrors, validationMode, submitted }, children: /* @__PURE__ */ jsxs("form", { ref: setRefs, onSubmit: handleSubmit, onFocusCapture: userActed, onInputCapture: userActed, className, noValidate: true, children: [
3550
+ const actionsNode = actions && !drawerFooter ? /* @__PURE__ */ jsx("div", { "data-form-actions": "", className: cn("flex flex-wrap items-center gap-ds-2 pt-ds-2", actionsAlign === "end" ? "justify-end" : "justify-start"), children: actions }) : null;
3551
+ return /* @__PURE__ */ jsx(FormCtx.Provider, { value: { errors, setError, clearErrors, validationMode, submitted }, children: /* @__PURE__ */ jsxs("form", { ref: setRefs, id: drawerFooter ? formId : void 0, onSubmit: handleSubmit, onFocusCapture: userActed, onInputCapture: userActed, className: cn("flex flex-col gap-ds-5", className), noValidate: true, children: [
3592
3552
  summaryNode && /* @__PURE__ */ jsx("div", { "data-form-error-summary": "", children: summaryNode }),
3593
3553
  children,
3594
- actions && /* @__PURE__ */ jsx("div", { "data-form-actions": "", className: cn("flex flex-wrap items-center gap-ds-2 pt-ds-4 mt-ds-2", actionsAlign === "end" ? "justify-end" : "justify-start"), children: actions })
3554
+ actionsNode
3595
3555
  ] }) });
3596
3556
  }
3597
3557
  function TransferList({
@@ -3891,7 +3851,7 @@ var StatusDot = forwardRef(function StatusDot2({
3891
3851
  }
3892
3852
  );
3893
3853
  });
3894
- var sizeStyles3 = {
3854
+ var sizeStyles2 = {
3895
3855
  sm: "h-8 w-8 text-xs",
3896
3856
  md: "h-10 w-10 text-sm",
3897
3857
  lg: "h-12 w-12 text-base"
@@ -3923,12 +3883,13 @@ function Avatar({ initials, src, alt, size = "md", status, color = "auto", class
3923
3883
  const base = cn(
3924
3884
  "inline-flex items-center justify-center font-medium shrink-0",
3925
3885
  "rounded-[var(--ds-radius-full)]",
3926
- sizeStyles3[size],
3886
+ sizeStyles2[size],
3927
3887
  className
3928
3888
  );
3929
3889
  const avatarElement = src ? /* @__PURE__ */ jsx(
3930
3890
  "img",
3931
3891
  {
3892
+ "data-avatar": "",
3932
3893
  src,
3933
3894
  alt: alt ?? initials ?? "",
3934
3895
  className: cn(base, "object-cover")
@@ -3936,6 +3897,7 @@ function Avatar({ initials, src, alt, size = "md", status, color = "auto", class
3936
3897
  ) : /* @__PURE__ */ jsx(
3937
3898
  "div",
3938
3899
  {
3900
+ "data-avatar": "",
3939
3901
  className: cn(
3940
3902
  base,
3941
3903
  colorStyles(color, alt ?? initials ?? ""),
@@ -4172,7 +4134,8 @@ function MentionInput({
4172
4134
  ] });
4173
4135
  }
4174
4136
  var CardCtx = createContext(false);
4175
- var variantStyles4 = {
4137
+ var CardSurfaceCtx = createContext(false);
4138
+ var variantStyles3 = {
4176
4139
  default: `bg-[var(--ds-bg-surface)] border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)] ${GLASS_SURFACE}`,
4177
4140
  featured: [
4178
4141
  `bg-[var(--ds-bg-surface)] border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)] ${GLASS_SURFACE}`,
@@ -4321,7 +4284,7 @@ var Card = forwardRef(function Card2({
4321
4284
  style: variant === "interactive" ? { ...INTERACTIVE_SCALE_CAP, ...style } : style,
4322
4285
  className: cn(
4323
4286
  "rounded-[var(--ds-radius-md)] flex flex-col relative",
4324
- variantStyles4[variant],
4287
+ variantStyles3[variant],
4325
4288
  isSelectable && !disabled && "cursor-pointer select-none transition-all duration-[var(--ds-transition-speed)] ease-[var(--ds-transition-ease)]",
4326
4289
  isSelectable && !disabled && !selected && "hover:border-[var(--ds-accent-primary)]",
4327
4290
  isSelectable && "focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]",
@@ -4355,11 +4318,11 @@ var Card = forwardRef(function Card2({
4355
4318
  children: /* @__PURE__ */ jsx(CheckboxIndicator, { checked: !!selected })
4356
4319
  }
4357
4320
  ),
4358
- /* @__PURE__ */ jsx(CardCtx, { value: checkable, children: loading ? /* @__PURE__ */ jsxs("div", { className: "space-y-ds-3", children: [
4321
+ /* @__PURE__ */ jsx(CardSurfaceCtx, { value: true, children: /* @__PURE__ */ jsx(CardCtx, { value: checkable, children: loading ? /* @__PURE__ */ jsxs("div", { className: "space-y-ds-3", children: [
4359
4322
  /* @__PURE__ */ jsx(Skeleton, { variant: "custom", className: "h-4 w-1/3" }),
4360
4323
  /* @__PURE__ */ jsx(Skeleton, { variant: "custom", className: "h-3 w-full" }),
4361
4324
  /* @__PURE__ */ jsx(Skeleton, { variant: "custom", className: "h-3 w-2/3" })
4362
- ] }) : children })
4325
+ ] }) : children }) })
4363
4326
  ]
4364
4327
  }
4365
4328
  );
@@ -4457,7 +4420,10 @@ var CardContent = forwardRef(function CardContent2({ className, children, ...pro
4457
4420
  });
4458
4421
  var CardFooter = forwardRef(function CardFooter2({ className, children, ...props }, ref) {
4459
4422
  const isCheckable = useContext(CardCtx);
4460
- return /* @__PURE__ */ jsx("div", { ref, className: cn("flex items-center pr-ds-5 pb-ds-4 pt-ds-2 mt-auto min-w-0", isCheckable ? "pl-ds-10" : "pl-ds-5", className), ...props, children });
4423
+ return (
4424
+ // a footer that holds only buttons puts them at the end (round 11: a lone Save sat on the left); text keeps the start
4425
+ /* @__PURE__ */ jsx("div", { ref, className: cn("flex items-center gap-ds-2 pr-ds-5 pb-ds-4 pt-ds-2 mt-auto min-w-0 [&:not(:has(>:not(button)))]:justify-end", isCheckable ? "pl-ds-10" : "pl-ds-5", className), ...props, children })
4426
+ );
4461
4427
  });
4462
4428
  function TruncLabel({ children }) {
4463
4429
  const { ref, isTruncated } = useTextOverflow({ lines: 1 });
@@ -4571,7 +4537,7 @@ function DataList({ items, columns = 1, className }) {
4571
4537
  }
4572
4538
  );
4573
4539
  }
4574
- var sizeStyles4 = {
4540
+ var sizeStyles3 = {
4575
4541
  sm: { gap: "gap-ds-0.5", label: "text-[length:var(--ds-font-size-xs)]", value: "text-[length:var(--ds-font-size-xs)]", iconSize: 12, py: "py-ds-1.5" },
4576
4542
  md: { gap: "gap-ds-1", label: "text-[length:var(--ds-font-size-sm)]", value: "text-[length:var(--ds-font-size-sm)]", iconSize: 14, py: "py-ds-2.5" },
4577
4543
  lg: { gap: "gap-ds-1.5", label: "text-[length:var(--ds-font-size-base)]", value: "text-[length:var(--ds-font-size-base)]", iconSize: 16, py: "py-ds-3" }
@@ -4601,7 +4567,7 @@ var DescriptionList = forwardRef(function DescriptionList2({
4601
4567
  stackBelow: stackBelowProp,
4602
4568
  className
4603
4569
  }, ref) {
4604
- const s = sizeStyles4[size];
4570
+ const s = sizeStyles3[size];
4605
4571
  const stackBelow = stackBelowProp ?? (columns > 1 ? "sm" : void 0);
4606
4572
  if (orientation === "vertical") {
4607
4573
  return /* @__PURE__ */ jsx(
@@ -4653,7 +4619,7 @@ var DescriptionList = forwardRef(function DescriptionList2({
4653
4619
  className: cn(
4654
4620
  "grid",
4655
4621
  columnClasses[columns],
4656
- "gap-x-ds-6",
4622
+ "gap-x-ds-8",
4657
4623
  stackBelow && stackBelow !== "none" && stackBreakpoints[stackBelow],
4658
4624
  dividers && "divide-y-[length:var(--ds-border-width)] divide-[var(--ds-border-subtle)]",
4659
4625
  className
@@ -4861,6 +4827,12 @@ function Table({
4861
4827
  return next;
4862
4828
  });
4863
4829
  };
4830
+ const columnKeys = useMemo(() => columns.map((c) => c.key), [columns]);
4831
+ const inferredKinds = useMemo(() => inferColumnKinds(data, columnKeys), [data, columnKeys]);
4832
+ const kindOf = useCallback(
4833
+ (col) => col.kind ?? inferredKinds.get(col.key),
4834
+ [inferredKinds]
4835
+ );
4864
4836
  const isMobile = useBreakpoint(mobileBreakpoint);
4865
4837
  if (isMobile) {
4866
4838
  if (loading) {
@@ -4869,7 +4841,7 @@ function Table({
4869
4841
  if (data.length === 0 && emptyState) {
4870
4842
  return /* @__PURE__ */ jsx("div", { ref, className: cn("py-ds-10 text-center text-sm text-[var(--ds-text-muted)]", className), children: emptyState });
4871
4843
  }
4872
- return /* @__PURE__ */ jsx("div", { ref, className: cn("flex flex-col gap-ds-3 overflow-y-auto", className), children: sortedWithIndices.map(({ row, originalIdx }, i) => {
4844
+ return /* @__PURE__ */ jsx(TableCardCtx, { value: true, children: /* @__PURE__ */ jsx("div", { ref, className: cn("flex flex-col gap-ds-3 overflow-y-auto", className), children: sortedWithIndices.map(({ row, originalIdx }, i) => {
4873
4845
  const isSelected = selectedSet.has(originalIdx);
4874
4846
  return /* @__PURE__ */ jsxs(
4875
4847
  "div",
@@ -4877,7 +4849,7 @@ function Table({
4877
4849
  className: cn(
4878
4850
  "border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]",
4879
4851
  "rounded-[var(--ds-radius-md)] bg-[var(--ds-bg-surface)]",
4880
- "p-ds-4 space-y-ds-2",
4852
+ "p-ds-4 space-y-ds-3",
4881
4853
  isSelected && ACTIVE_RING,
4882
4854
  onRowClick && "cursor-pointer hover:bg-[var(--ds-bg-muted)] focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]"
4883
4855
  ),
@@ -4893,15 +4865,15 @@ function Table({
4893
4865
  children: [
4894
4866
  selectable && /* @__PURE__ */ jsx(Checkbox, { checked: isSelected, onChange: () => toggleRow(originalIdx), label: "Select" }),
4895
4867
  columns.map((col) => /* @__PURE__ */ jsxs("div", { className: "flex justify-between gap-ds-2 text-sm", children: [
4896
- /* @__PURE__ */ jsx("span", { className: "text-[var(--ds-text-secondary)] font-medium text-xs uppercase tracking-wider", children: col.header }),
4897
- /* @__PURE__ */ jsx("span", { className: "text-[var(--ds-text-primary)] text-right", children: row[col.key] })
4868
+ /* @__PURE__ */ jsx("span", { className: "shrink-0 text-[var(--ds-text-secondary)] font-medium text-xs uppercase tracking-wider", children: col.header }),
4869
+ /* @__PURE__ */ jsx(CardValue, { value: row[col.key] })
4898
4870
  ] }, col.key)),
4899
4871
  expandable && renderExpanded && /* @__PURE__ */ jsx("div", { className: "pt-ds-2 border-t-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)] text-sm text-[var(--ds-text-secondary)]", children: renderExpanded(row, i) })
4900
4872
  ]
4901
4873
  },
4902
4874
  i
4903
4875
  );
4904
- }) });
4876
+ }) }) });
4905
4877
  }
4906
4878
  return /* @__PURE__ */ jsx(
4907
4879
  "div",
@@ -4929,14 +4901,18 @@ function Table({
4929
4901
  columns.map((col) => {
4930
4902
  const isSortable = sortable || col.sortable;
4931
4903
  const isActiveSort = sortKey === col.key;
4904
+ const headerKind = kindOf(col);
4905
+ const headerAlign = col.align ?? (headerKind === "number" ? "right" : "left");
4906
+ const shrink = (headerKind === "number" || headerKind === "date") && !col.maxWidth;
4932
4907
  return /* @__PURE__ */ jsx(
4933
4908
  "th",
4934
4909
  {
4935
4910
  className: cn(
4936
4911
  density === "compact" ? "px-ds-3 py-ds-2" : "px-ds-4 py-ds-3",
4912
+ shrink && "w-px whitespace-nowrap",
4937
4913
  "font-[var(--ds-weight-heading)] text-[var(--ds-text-secondary)]",
4938
4914
  "text-xs uppercase tracking-wider",
4939
- col.align === "right" ? "text-right" : col.align === "center" ? "text-center" : "text-left",
4915
+ headerAlign === "right" ? "text-right" : headerAlign === "center" ? "text-center" : "text-left",
4940
4916
  isSortable && "cursor-pointer select-none hover:text-[var(--ds-text-primary)]"
4941
4917
  ),
4942
4918
  style: col.maxWidth ? { maxWidth: col.maxWidth } : void 0,
@@ -5017,16 +4993,29 @@ function Table({
5017
4993
  ) }),
5018
4994
  columns.map((col) => {
5019
4995
  const truncLines = col.truncate === true ? 1 : col.truncate ? col.truncate.lines : 0;
4996
+ const kind = kindOf(col);
4997
+ const alignClass = col.align ? col.align === "right" ? "text-right" : col.align === "center" ? "text-center" : "text-left" : kind === "number" ? "text-right" : "text-left";
4998
+ const cellContent = row[col.key];
4999
+ const shrink = (kind === "number" || kind === "date") && !col.maxWidth;
5000
+ let inner;
5001
+ if (truncLines > 0) {
5002
+ inner = /* @__PURE__ */ jsx(TruncCell, { lines: truncLines, children: cellContent });
5003
+ } else if (kind === "email") {
5004
+ inner = /* @__PURE__ */ jsx("span", { className: "max-w-[40ch] truncate inline-block align-bottom", title: typeof cellContent === "string" ? cellContent : void 0, children: cellContent });
5005
+ } else {
5006
+ inner = cellContent;
5007
+ }
5020
5008
  return /* @__PURE__ */ jsx(
5021
5009
  "td",
5022
5010
  {
5023
5011
  className: cn(
5024
5012
  density === "compact" ? "px-ds-3 py-ds-2" : "px-ds-4 py-ds-3",
5025
5013
  "text-[var(--ds-text-primary)]",
5026
- col.align === "right" ? "text-right" : col.align === "center" ? "text-center" : "text-left"
5014
+ alignClass,
5015
+ shrink && "w-px whitespace-nowrap"
5027
5016
  ),
5028
5017
  style: col.maxWidth ? { maxWidth: col.maxWidth } : void 0,
5029
- children: truncLines > 0 ? /* @__PURE__ */ jsx(TruncCell, { lines: truncLines, children: row[col.key] }) : row[col.key]
5018
+ children: inner
5030
5019
  },
5031
5020
  col.key
5032
5021
  );
@@ -5048,11 +5037,14 @@ function Table({
5048
5037
  }
5049
5038
  );
5050
5039
  }
5051
- var sizes4 = {
5052
- xs: "text-xs h-5 px-ds-2",
5053
- sm: "text-xs h-7 px-ds-3",
5054
- md: "text-sm h-9 px-ds-3",
5055
- lg: "text-base h-11 px-ds-3"
5040
+ function optionsKeyForFit(options) {
5041
+ return options.map((o) => `${o.value}:${o.label}`).join("|");
5042
+ }
5043
+ var sizes3 = {
5044
+ xs: "text-xs px-ds-2",
5045
+ sm: "text-xs px-ds-3",
5046
+ md: "text-sm px-ds-3",
5047
+ lg: "text-base px-ds-3"
5056
5048
  };
5057
5049
  var containerPadding = {
5058
5050
  xs: "p-[2px] gap-[2px]",
@@ -5061,16 +5053,16 @@ var containerPadding = {
5061
5053
  lg: "p-ds-1 gap-ds-0.5"
5062
5054
  };
5063
5055
  var indicatorInset = {
5064
- xs: { top: "2px", height: "calc(100% - 4px)" },
5065
- sm: { top: "4px", height: "calc(100% - 8px)" },
5066
- md: { top: "4px", height: "calc(100% - 8px)" },
5067
- lg: { top: "4px", height: "calc(100% - 8px)" }
5056
+ xs: "2px",
5057
+ sm: "4px",
5058
+ md: "4px",
5059
+ lg: "4px"
5068
5060
  };
5069
5061
  function SegmentedControl({
5070
5062
  value,
5071
5063
  onChange,
5072
5064
  options,
5073
- size = "md",
5065
+ size: sizeProp,
5074
5066
  variant = "default",
5075
5067
  fullWidth = false,
5076
5068
  onHoverChange,
@@ -5078,9 +5070,36 @@ function SegmentedControl({
5078
5070
  "aria-label": ariaLabel,
5079
5071
  maxOptions = 6
5080
5072
  }) {
5081
- const collapsed = options.length > maxOptions;
5073
+ const contextSize = useContext(ControlSizeContext);
5074
+ const size = sizeProp ?? contextSize ?? "md";
5082
5075
  const containerRef = useRef(null);
5083
5076
  const [indicator, setIndicator] = useState({ left: 0, width: 0 });
5077
+ const parentRef = useRef(null);
5078
+ const neededRef = useRef(0);
5079
+ const [overflows, setOverflows] = useState(false);
5080
+ const measureFit = useCallback(() => {
5081
+ const row = containerRef.current;
5082
+ if (row) {
5083
+ parentRef.current = row.parentElement;
5084
+ if (row.scrollWidth > 0) neededRef.current = row.scrollWidth;
5085
+ }
5086
+ const parent = parentRef.current;
5087
+ const needed = neededRef.current;
5088
+ if (!parent || !needed) return;
5089
+ const style = getComputedStyle(parent);
5090
+ const available = parent.clientWidth - (parseFloat(style.paddingLeft) || 0) - (parseFloat(style.paddingRight) || 0);
5091
+ if (available <= 0) return;
5092
+ setOverflows((prev) => prev ? needed > available - 8 : needed > available);
5093
+ }, []);
5094
+ useLayoutEffect(() => {
5095
+ measureFit();
5096
+ const parent = parentRef.current;
5097
+ if (!parent || typeof ResizeObserver === "undefined") return;
5098
+ const observer = new ResizeObserver(measureFit);
5099
+ observer.observe(parent);
5100
+ return () => observer.disconnect();
5101
+ }, [measureFit, optionsKeyForFit(options)]);
5102
+ const collapsed = options.length > maxOptions || overflows;
5084
5103
  const updateIndicator = useCallback(() => {
5085
5104
  if (!containerRef.current) return;
5086
5105
  const active = containerRef.current.querySelector("[data-active='true']");
@@ -5095,6 +5114,22 @@ function SegmentedControl({
5095
5114
  useLayoutEffect(() => {
5096
5115
  updateIndicator();
5097
5116
  }, [value, optionsKey, updateIndicator]);
5117
+ useEffect(() => {
5118
+ const fonts = document.fonts;
5119
+ if (!fonts?.ready) return;
5120
+ let live = true;
5121
+ fonts.ready.then(() => {
5122
+ if (live) updateIndicator();
5123
+ });
5124
+ return () => {
5125
+ live = false;
5126
+ };
5127
+ }, [updateIndicator]);
5128
+ const [animate, setAnimate] = useState(false);
5129
+ const select = useCallback((v) => {
5130
+ setAnimate(true);
5131
+ onChange(v);
5132
+ }, [onChange]);
5098
5133
  useLayoutEffect(() => {
5099
5134
  if (collapsed || !containerRef.current || typeof ResizeObserver === "undefined") return;
5100
5135
  const observer = new ResizeObserver(updateIndicator);
@@ -5120,7 +5155,7 @@ function SegmentedControl({
5120
5155
  else if (e.key === "End") next = enabled.length - 1;
5121
5156
  if (next === null) return;
5122
5157
  e.preventDefault();
5123
- onChange(enabled[next].value);
5158
+ select(enabled[next].value);
5124
5159
  const buttons = containerRef.current?.querySelectorAll('[role="radio"]');
5125
5160
  buttons?.forEach((b) => {
5126
5161
  if (b.dataset.value === enabled[next].value) b.focus();
@@ -5164,14 +5199,15 @@ function SegmentedControl({
5164
5199
  "absolute rounded-[var(--ds-radius-md)]",
5165
5200
  "bg-[var(--ds-bg-surface)]",
5166
5201
  variant === "default" && "shadow-[var(--ds-shadow-sm)]",
5167
- "transition-all"
5202
+ "transition-all motion-reduce:transition-none"
5168
5203
  ),
5204
+ "data-animate": animate ? "true" : "false",
5169
5205
  style: {
5170
5206
  left: indicator.left,
5171
5207
  width: indicator.width,
5172
- top: indicatorInset[size].top,
5173
- height: indicatorInset[size].height,
5174
- transitionDuration: "var(--ds-transition-speed)",
5208
+ top: indicatorInset[size],
5209
+ bottom: indicatorInset[size],
5210
+ transitionDuration: animate ? "var(--ds-transition-speed)" : "0ms",
5175
5211
  transitionTimingFunction: "var(--ds-transition-ease)"
5176
5212
  }
5177
5213
  }
@@ -5186,16 +5222,16 @@ function SegmentedControl({
5186
5222
  "data-value": opt.value,
5187
5223
  tabIndex: i === tabStop ? 0 : -1,
5188
5224
  disabled: opt.disabled,
5189
- onClick: () => !opt.disabled && onChange(opt.value),
5225
+ onClick: () => !opt.disabled && select(opt.value),
5190
5226
  onMouseEnter: onHoverChange && !opt.disabled ? () => onHoverChange(opt.value) : void 0,
5191
5227
  onMouseLeave: onHoverChange ? () => onHoverChange(null) : void 0,
5192
5228
  className: cn(
5193
- "relative z-10 inline-flex items-center justify-center font-medium whitespace-nowrap",
5229
+ "relative z-10 inline-flex items-center justify-center self-stretch font-medium whitespace-nowrap",
5194
5230
  fullWidth && "flex-1",
5195
5231
  "rounded-[var(--ds-radius-md)]",
5196
5232
  "transition-colors cursor-pointer",
5197
5233
  "focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]",
5198
- sizes4[size],
5234
+ sizes3[size],
5199
5235
  opt.value === value ? "text-[var(--ds-text-primary)]" : "text-[var(--ds-text-muted)] hover:text-[var(--ds-text-secondary)]",
5200
5236
  opt.disabled && "opacity-disabled cursor-not-allowed"
5201
5237
  ),
@@ -6760,6 +6796,7 @@ function EmptyState({ icon, iconFrame = "circle", title, description, action, va
6760
6796
  return /* @__PURE__ */ jsxs(
6761
6797
  "div",
6762
6798
  {
6799
+ "data-gs": "empty-state",
6763
6800
  className: cn(
6764
6801
  "flex flex-col items-center justify-center py-[var(--ds-space-10)] px-[var(--ds-space-6)]",
6765
6802
  "rounded-[var(--ds-radius-md)] bg-[var(--ds-bg-surface)]",
@@ -6775,42 +6812,52 @@ function EmptyState({ icon, iconFrame = "circle", title, description, action, va
6775
6812
  }
6776
6813
  );
6777
6814
  }
6778
- function SkipLink({ href = "#main", children = "Skip to content", className }) {
6779
- return /* @__PURE__ */ jsx(
6780
- "a",
6815
+ function initialsOf(name) {
6816
+ return name.trim().split(/\s+/).slice(0, 2).map((w) => w[0] ?? "").join("").toUpperCase();
6817
+ }
6818
+ function looksLikeUrl(s) {
6819
+ return /^(?:https?:|data:|blob:|\/|\.{1,2}\/)/.test(s) || /\.[a-z]{2,5}(?:$|[?#])/i.test(s);
6820
+ }
6821
+ function EntityCell({ avatar, src, initials, primary, secondary, size = "md", className }) {
6822
+ const inTableCard = useContext(TableCardCtx);
6823
+ let avatarElement;
6824
+ if (typeof avatar === "string") {
6825
+ avatarElement = looksLikeUrl(avatar) ? /* @__PURE__ */ jsx(Avatar, { src: avatar, alt: primary, size }) : /* @__PURE__ */ jsx(Avatar, { initials: avatar, alt: primary, size });
6826
+ } else if (avatar != null) {
6827
+ avatarElement = avatar;
6828
+ } else if (src) {
6829
+ avatarElement = /* @__PURE__ */ jsx(Avatar, { src, alt: primary, size });
6830
+ } else {
6831
+ avatarElement = /* @__PURE__ */ jsx(Avatar, { initials: initials ?? initialsOf(primary), alt: primary, size });
6832
+ }
6833
+ return /* @__PURE__ */ jsxs(
6834
+ "div",
6781
6835
  {
6782
- href,
6783
6836
  className: cn(
6784
- "sr-only focus:not-sr-only focus:fixed focus:top-[var(--ds-space-2)] focus:left-[var(--ds-space-2)] focus:z-[var(--ds-z-tooltip)]",
6785
- "focus:px-[var(--ds-space-3)] focus:py-[var(--ds-space-2)] focus:rounded-[var(--ds-radius-md)] focus:text-sm focus:font-medium",
6786
- "focus:bg-[var(--ds-bg-surface-elevated)] focus:text-[var(--ds-text-primary)] focus:shadow-[var(--ds-shadow-md)]",
6787
- "focus:outline-none focus:ring-2 focus:ring-[var(--ds-accent-primary)]",
6837
+ "flex flex-row items-center gap-ds-2",
6838
+ // Inside a Table or DataGrid card (the phone layout) the cell keeps the avatar beside the text and sits
6839
+ // against the value column's right edge; the name may take two lines, the secondary line truncates
6840
+ // (Sprint 25.4, round 7: the owner's call, replacing decision 2's stacked cell).
6841
+ inTableCard && "justify-end text-right",
6788
6842
  className
6789
6843
  ),
6790
- children
6844
+ children: [
6845
+ /* @__PURE__ */ jsx("div", { className: "shrink-0", children: avatarElement }),
6846
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
6847
+ /* @__PURE__ */ jsx("p", { className: cn(
6848
+ "font-medium text-[var(--ds-text-primary)]",
6849
+ inTableCard ? "line-clamp-2 [overflow-wrap:anywhere]" : "truncate",
6850
+ size === "sm" ? "text-xs" : "text-sm"
6851
+ ), children: primary }),
6852
+ secondary && /* @__PURE__ */ jsx("p", { className: cn(
6853
+ "text-[var(--ds-text-secondary)] truncate",
6854
+ size === "sm" ? "text-xs" : "text-sm"
6855
+ ), children: secondary })
6856
+ ] })
6857
+ ]
6791
6858
  }
6792
6859
  );
6793
6860
  }
6794
- function useCompact(ref, breakpoint) {
6795
- const px = typeof breakpoint === "number" ? breakpoint : readBreakpointPx(breakpoint);
6796
- const width = useElementWidth(ref);
6797
- return width > 0 && width < px;
6798
- }
6799
- function useElementWidth(ref) {
6800
- const [width, setWidth] = useState(0);
6801
- const check = useCallback(() => {
6802
- const next = ref.current?.offsetWidth ?? 0;
6803
- if (next > 0) setWidth(next);
6804
- }, [ref]);
6805
- useLayoutEffect(() => {
6806
- check();
6807
- if (!ref.current || typeof ResizeObserver === "undefined") return;
6808
- const observer = new ResizeObserver(check);
6809
- observer.observe(ref.current);
6810
- return () => observer.disconnect();
6811
- }, [check, ref]);
6812
- return width;
6813
- }
6814
6861
  function TableToolbar({
6815
6862
  search,
6816
6863
  primaryFilter,
@@ -6839,7 +6886,9 @@ function TableToolbar({
6839
6886
  const iconSize = size === "sm" ? 14 : 16;
6840
6887
  const count = activeFilterCount ?? activeFilters?.length ?? 0;
6841
6888
  const hasChips = !!activeFilters?.length;
6842
- return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-ds-3 min-w-0", className), "data-table-toolbar": "", children: [
6889
+ const inPane = useContext(SplitPaneCtx);
6890
+ const searchFills = inPane || !primaryFilter && !filters && !actions;
6891
+ return /* @__PURE__ */ jsx(ControlSizeContext.Provider, { value: size, children: /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-ds-3 min-w-0", className), "data-table-toolbar": "", children: [
6843
6892
  /* @__PURE__ */ jsxs("div", { ref: rowRef, className: "flex items-center gap-ds-2 flex-wrap", children: [
6844
6893
  search && /* @__PURE__ */ jsx(
6845
6894
  Input,
@@ -6849,7 +6898,7 @@ function TableToolbar({
6849
6898
  value: search.value,
6850
6899
  size,
6851
6900
  onChange: (e) => search.onChange(e.target.value),
6852
- className: "flex-1 min-w-[160px] max-w-[280px]"
6901
+ className: cn("flex-1 min-w-[160px]", !searchFills && "max-w-[280px]")
6853
6902
  }
6854
6903
  ),
6855
6904
  primaryFilter && (compact ? /* @__PURE__ */ jsx(
@@ -6872,7 +6921,7 @@ function TableToolbar({
6872
6921
  onChange: primaryFilter.onChange
6873
6922
  }
6874
6923
  )),
6875
- (filters || actions) && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-2 flex-1 justify-end", children: [
6924
+ (filters || actions) && /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-ds-2 justify-end", inPane ? "flex-none" : "flex-1"), children: [
6876
6925
  filters && /* @__PURE__ */ jsxs(
6877
6926
  Button,
6878
6927
  {
@@ -6902,7 +6951,7 @@ function TableToolbar({
6902
6951
  activeFilters?.map((f) => /* @__PURE__ */ jsx(Tag, { size: "sm", variant: "subtle", onRemove: f.onRemove, children: f.label }, f.id)),
6903
6952
  hasChips && onClearAll && /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: onClearAll, children: "Clear all" })
6904
6953
  ] })
6905
- ] });
6954
+ ] }) });
6906
6955
  }
6907
6956
  var dotVariant = {
6908
6957
  default: "bg-[var(--ds-accent-primary)] shadow-[0_0_0_3px_var(--ds-accent-primary)]/20",
@@ -7280,7 +7329,7 @@ function TreeNodeRow({
7280
7329
  isSelected ? "bg-[var(--ds-tree-active-bg)] text-[var(--ds-tree-active-text)] font-medium border-[var(--ds-accent-primary)]" : "border-transparent text-[var(--ds-text-primary)] hover:bg-[var(--ds-tab-hover-bg)] hover:text-[var(--ds-text-primary)]",
7281
7330
  node.disabled && "opacity-disabled pointer-events-none"
7282
7331
  ),
7283
- style: { paddingLeft: `calc(var(--ds-space-5) * ${depth} + var(--ds-space-2))` },
7332
+ style: { paddingLeft: `calc(var(--ds-space-3) * ${depth} + var(--ds-space-2))` },
7284
7333
  onClick: () => {
7285
7334
  if (node.disabled) return;
7286
7335
  if (checkable) handleCheck(node);
@@ -7924,51 +7973,6 @@ function ChatPanel({
7924
7973
  )
7925
7974
  ] });
7926
7975
  }
7927
- function transitionMs(el) {
7928
- const cs = getComputedStyle(el);
7929
- const parse = (list) => list.split(",").map((raw) => {
7930
- const s = raw.trim();
7931
- if (!s) return 0;
7932
- const n = parseFloat(s);
7933
- if (Number.isNaN(n)) return 0;
7934
- return s.endsWith("ms") ? n : n * 1e3;
7935
- });
7936
- const durations = parse(cs.transitionDuration || "0s");
7937
- const delays = parse(cs.transitionDelay || "0s");
7938
- let max = 0;
7939
- durations.forEach((d, i) => {
7940
- const total = d + (delays[i] ?? delays[0] ?? 0);
7941
- if (total > max) max = total;
7942
- });
7943
- return max;
7944
- }
7945
- function useCloseSettle(open, elRef, onSettled) {
7946
- const cb = useLatest(onSettled);
7947
- useEffect(() => {
7948
- if (open) return;
7949
- const el = elRef.current;
7950
- const ms = el ? transitionMs(el) : 0;
7951
- let done = false;
7952
- const finish = () => {
7953
- if (done) return;
7954
- done = true;
7955
- cb.current();
7956
- };
7957
- if (!el || ms === 0) {
7958
- const t2 = setTimeout(finish, 0);
7959
- return () => clearTimeout(t2);
7960
- }
7961
- const onEnd = (e) => {
7962
- if (e.target === el) finish();
7963
- };
7964
- el.addEventListener("transitionend", onEnd);
7965
- const t = setTimeout(finish, ms + 50);
7966
- return () => {
7967
- el.removeEventListener("transitionend", onEnd);
7968
- clearTimeout(t);
7969
- };
7970
- }, [open, elRef, cb]);
7971
- }
7972
7976
  var TOAST_INSET_VARS = {
7973
7977
  "bottom-right": "--ds-toast-inset-bottom-right",
7974
7978
  "bottom-left": "--ds-toast-inset-bottom-left",
@@ -8019,194 +8023,6 @@ function useCornerInset(corner, inset, priority, target) {
8019
8023
  return claimCornerInset(corner, inset, priority, el);
8020
8024
  }, [corner, inset, priority, target]);
8021
8025
  }
8022
- function Sheet({ open, onClose, title, children, footer, confirm, snapPoints = [0.5, 0.92], container, flush, keepMounted = false, id, labelledBy }) {
8023
- const titleId = useId();
8024
- const panelRef = useRef(null);
8025
- const [mounted, setMounted] = useState(open);
8026
- const [hidden, setHidden] = useState(!open);
8027
- const [snapIdx, setSnapIdx] = useState(0);
8028
- const [dragOffset, setDragOffset] = useState(0);
8029
- const [dragging, setDragging] = useState(false);
8030
- const dragStartY = useRef(0);
8031
- const startHeight = useRef(0);
8032
- const onCloseRef = useLatest(onClose);
8033
- const [prevOpen, setPrevOpen] = useState(open);
8034
- if (open !== prevOpen) {
8035
- setPrevOpen(open);
8036
- if (open) {
8037
- setMounted(true);
8038
- setHidden(false);
8039
- setSnapIdx(0);
8040
- setDragOffset(0);
8041
- }
8042
- }
8043
- const viewportHeight = useCallback(
8044
- () => container instanceof HTMLElement ? container.clientHeight : window.innerHeight,
8045
- [container]
8046
- );
8047
- useCloseSettle(open, panelRef, () => {
8048
- if (keepMounted) setHidden(true);
8049
- else setMounted(false);
8050
- });
8051
- useReturnFocus(open);
8052
- useEffect(() => {
8053
- if (!open || !mounted) return;
8054
- const raf = requestAnimationFrame(() => focusInitial(panelRef.current));
8055
- return () => cancelAnimationFrame(raf);
8056
- }, [open, mounted]);
8057
- const isTopLayer = useOverlayLayer(open);
8058
- useFocusTrap(panelRef, open, isTopLayer);
8059
- useEffect(() => {
8060
- if (!open) return;
8061
- const onKeyDown = (e) => {
8062
- if (e.key === "Escape" && isTopLayer()) onCloseRef.current();
8063
- };
8064
- document.addEventListener("keydown", onKeyDown);
8065
- if (!container) lockBodyScroll();
8066
- return () => {
8067
- document.removeEventListener("keydown", onKeyDown);
8068
- if (!container) unlockBodyScroll();
8069
- };
8070
- }, [open, container, onCloseRef, isTopLayer]);
8071
- const handlePointerDown = useCallback((e) => {
8072
- setDragging(true);
8073
- dragStartY.current = e.clientY;
8074
- startHeight.current = (snapPoints[snapIdx] ?? snapPoints[0]) * viewportHeight();
8075
- setDragOffset(0);
8076
- e.target.setPointerCapture(e.pointerId);
8077
- }, [snapIdx, snapPoints, viewportHeight]);
8078
- const handlePointerMove = useCallback((e) => {
8079
- if (!dragging) return;
8080
- const delta = dragStartY.current - e.clientY;
8081
- setDragOffset(delta);
8082
- }, [dragging]);
8083
- const handlePointerUp = useCallback(() => {
8084
- if (!dragging) return;
8085
- setDragging(false);
8086
- const currentHeightPx = startHeight.current + dragOffset;
8087
- const currentFraction = currentHeightPx / viewportHeight();
8088
- if (currentFraction < snapPoints[0] * 0.6) {
8089
- onClose();
8090
- setDragOffset(0);
8091
- return;
8092
- }
8093
- let bestIdx = 0;
8094
- let bestDist = Math.abs(currentFraction - snapPoints[0]);
8095
- for (let i = 1; i < snapPoints.length; i++) {
8096
- const dist = Math.abs(currentFraction - snapPoints[i]);
8097
- if (dist < bestDist) {
8098
- bestDist = dist;
8099
- bestIdx = i;
8100
- }
8101
- }
8102
- setSnapIdx(bestIdx);
8103
- setDragOffset(0);
8104
- }, [dragging, dragOffset, snapPoints, onClose, viewportHeight]);
8105
- if (!mounted) return null;
8106
- const baseHeight = (snapPoints[snapIdx] ?? snapPoints[0]) * 100;
8107
- const heightUnit = container ? "%" : "vh";
8108
- const dragPx = dragging ? dragOffset : 0;
8109
- const positionClass = container ? "absolute" : "fixed";
8110
- return createPortal(
8111
- /* @__PURE__ */ jsxs(
8112
- "div",
8113
- {
8114
- hidden: keepMounted && hidden ? true : void 0,
8115
- className: cn(
8116
- `${positionClass} inset-0 z-[var(--ds-z-modal)] transition-opacity duration-[var(--ds-transition-speed)]`,
8117
- open ? "pointer-events-auto" : "pointer-events-none"
8118
- ),
8119
- children: [
8120
- /* @__PURE__ */ jsx(
8121
- "div",
8122
- {
8123
- className: cn(
8124
- "absolute inset-0 bg-black/50 transition-opacity duration-[var(--ds-transition-speed)]",
8125
- open ? "opacity-100" : "opacity-0"
8126
- ),
8127
- onClick: onClose
8128
- }
8129
- ),
8130
- /* @__PURE__ */ jsxs(
8131
- "div",
8132
- {
8133
- ref: panelRef,
8134
- id,
8135
- role: "dialog",
8136
- "aria-modal": "true",
8137
- "aria-labelledby": title ? titleId : labelledBy,
8138
- "data-ds-sheet": "",
8139
- className: cn(
8140
- `${positionClass} bottom-0 left-0 right-0 z-10 flex flex-col`,
8141
- "bg-[var(--ds-bg-surface)] text-[var(--ds-text-primary)]",
8142
- GLASS_OVERLAY,
8143
- "border-t-[length:var(--ds-border-width)] border-[var(--ds-border-default)]",
8144
- "rounded-t-[var(--ds-radius-xl)]",
8145
- !dragging && "transition-[transform,height] duration-[var(--ds-transition-speed)] ease-[var(--ds-transition-ease)]",
8146
- open ? "translate-y-0" : "translate-y-full"
8147
- ),
8148
- style: {
8149
- containerType: "inline-size",
8150
- height: dragPx ? `calc(${baseHeight}${heightUnit} + ${dragPx}px)` : `${baseHeight}${heightUnit}`
8151
- },
8152
- children: [
8153
- /* @__PURE__ */ jsx(
8154
- "div",
8155
- {
8156
- className: "flex justify-center pt-ds-2 pb-ds-1 cursor-grab active:cursor-grabbing touch-none",
8157
- onPointerDown: handlePointerDown,
8158
- onPointerMove: handlePointerMove,
8159
- onPointerUp: handlePointerUp,
8160
- onPointerCancel: handlePointerUp,
8161
- children: /* @__PURE__ */ jsx("div", { className: "w-10 h-1 rounded-[var(--ds-radius-full)] bg-[var(--ds-border-default)]" })
8162
- }
8163
- ),
8164
- title && /* @__PURE__ */ jsxs(
8165
- "div",
8166
- {
8167
- className: "flex items-center justify-between shrink-0 border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]",
8168
- style: { padding: "var(--ds-space-2) var(--ds-space-5)" },
8169
- children: [
8170
- /* @__PURE__ */ jsx("h2", { id: titleId, className: "font-[family-name:var(--ds-font-display)] text-lg font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)] truncate", children: title }),
8171
- /* @__PURE__ */ jsx(
8172
- "button",
8173
- {
8174
- onClick: onClose,
8175
- ...{ [OVERLAY_CLOSE_ATTR]: "" },
8176
- className: "text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)] transition-colors cursor-pointer",
8177
- "aria-label": "Close",
8178
- children: /* @__PURE__ */ jsx(Icon, { name: "close", size: 18 })
8179
- }
8180
- )
8181
- ]
8182
- }
8183
- ),
8184
- /* @__PURE__ */ jsx(
8185
- "div",
8186
- {
8187
- className: "flex-1 overflow-y-auto",
8188
- style: flush ? void 0 : { padding: "var(--ds-space-5)" },
8189
- children
8190
- }
8191
- ),
8192
- confirm,
8193
- footer && /* @__PURE__ */ jsx(
8194
- "div",
8195
- {
8196
- className: "shrink-0 flex items-center justify-end gap-ds-2 border-t-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]",
8197
- style: { padding: "var(--ds-space-3) var(--ds-space-5)" },
8198
- children: footer
8199
- }
8200
- )
8201
- ]
8202
- }
8203
- )
8204
- ]
8205
- }
8206
- ),
8207
- container ?? document.body
8208
- );
8209
- }
8210
8026
  var DEFAULT_OFFSET = "var(--ds-space-4)";
8211
8027
  var CORNER_PANEL_ANCHOR_INSET = "calc(var(--ds-space-12) + var(--ds-space-3))";
8212
8028
  function CornerPanel({
@@ -8319,494 +8135,6 @@ function CornerWindow({ open, onClose, edge, align, width, height, offset, ancho
8319
8135
  container ?? document.body
8320
8136
  );
8321
8137
  }
8322
- var STEP = 16;
8323
- var BIG_STEP = 64;
8324
- function clamp(v, min, max) {
8325
- return Math.min(Math.max(v, min), max);
8326
- }
8327
- function ResizeEdge({ edge, width, min, max, defaultWidth, onResize, label, onDraggingChange, className }) {
8328
- const [dragging, setDragging] = useState(false);
8329
- const start = useRef(null);
8330
- const latestOnResize = useLatest(onResize);
8331
- const direction = edge === "left" ? -1 : 1;
8332
- const onPointerDown = useCallback(
8333
- (e) => {
8334
- if (e.button !== 0) return;
8335
- e.preventDefault();
8336
- start.current = { x: e.clientX, width };
8337
- setDragging(true);
8338
- e.currentTarget.setPointerCapture(e.pointerId);
8339
- },
8340
- [width]
8341
- );
8342
- const onPointerMove = useCallback(
8343
- (e) => {
8344
- if (!start.current) return;
8345
- const next = clamp(start.current.width + direction * (e.clientX - start.current.x), min, max());
8346
- latestOnResize.current(next);
8347
- },
8348
- [direction, min, max, latestOnResize]
8349
- );
8350
- const endDrag = useCallback(() => {
8351
- start.current = null;
8352
- setDragging(false);
8353
- }, []);
8354
- const latestOnDraggingChange = useLatest(onDraggingChange);
8355
- useEffect(() => {
8356
- latestOnDraggingChange.current?.(dragging);
8357
- }, [dragging, latestOnDraggingChange]);
8358
- useEffect(() => {
8359
- if (!dragging) return;
8360
- const onKey = (e) => {
8361
- if (e.key !== "Escape" || !start.current) return;
8362
- latestOnResize.current(start.current.width);
8363
- endDrag();
8364
- };
8365
- document.addEventListener("keydown", onKey);
8366
- return () => document.removeEventListener("keydown", onKey);
8367
- }, [dragging, endDrag, latestOnResize]);
8368
- const onKeyDown = (e) => {
8369
- const step = e.shiftKey ? BIG_STEP : STEP;
8370
- let next = null;
8371
- if (e.key === "ArrowLeft") next = width - direction * step;
8372
- else if (e.key === "ArrowRight") next = width + direction * step;
8373
- else if (e.key === "Home") next = min;
8374
- else if (e.key === "End") next = max();
8375
- else if (e.key === "Enter") next = defaultWidth;
8376
- if (next === null) return;
8377
- e.preventDefault();
8378
- onResize(clamp(next, min, max()));
8379
- };
8380
- return /* @__PURE__ */ jsx(
8381
- "div",
8382
- {
8383
- role: "separator",
8384
- tabIndex: 0,
8385
- "aria-orientation": "vertical",
8386
- "aria-label": label,
8387
- "aria-valuemin": min,
8388
- "aria-valuemax": max(),
8389
- "aria-valuenow": Math.round(width),
8390
- "data-resize-edge": edge,
8391
- "data-dragging": dragging || void 0,
8392
- onPointerDown,
8393
- onPointerMove,
8394
- onPointerUp: endDrag,
8395
- onPointerCancel: endDrag,
8396
- onDoubleClick: () => onResize(clamp(defaultWidth, min, max())),
8397
- onKeyDown,
8398
- className: cn(
8399
- // A narrow absolutely-positioned strip over the edge — never a flex child that takes width.
8400
- "group/edge absolute top-0 bottom-0 z-10 w-ds-2 cursor-col-resize touch-none select-none outline-none",
8401
- edge === "left" ? "-left-ds-1" : "-right-ds-1",
8402
- className
8403
- ),
8404
- children: /* @__PURE__ */ jsx(
8405
- "div",
8406
- {
8407
- "aria-hidden": "true",
8408
- className: cn(
8409
- "absolute top-0 bottom-0 left-1/2 w-px -translate-x-1/2 transition-[width,background-color] duration-[var(--ds-transition-speed)]",
8410
- "group-hover/edge:w-[3px] group-hover/edge:bg-[var(--ds-accent-primary)]",
8411
- "group-focus-visible/edge:w-[3px] group-focus-visible/edge:bg-[var(--ds-accent-primary)]",
8412
- dragging && "w-[3px] bg-[var(--ds-accent-primary)]"
8413
- )
8414
- }
8415
- )
8416
- }
8417
- );
8418
- }
8419
- var remembered = /* @__PURE__ */ new Map();
8420
- function useRememberedWidth(key) {
8421
- const [width, setWidth] = useState(() => key ? remembered.get(key) ?? null : null);
8422
- const remember = useCallback(
8423
- (w) => {
8424
- setWidth(w);
8425
- if (!key) return;
8426
- if (w === null) remembered.delete(key);
8427
- else remembered.set(key, w);
8428
- },
8429
- [key]
8430
- );
8431
- return [width, remember];
8432
- }
8433
- function pxOf(length) {
8434
- if (!length) return null;
8435
- const m = /^(\d+(?:\.\d+)?)px$/.exec(length.trim());
8436
- return m ? parseFloat(m[1]) : null;
8437
- }
8438
- function defaultMaxWidth(container) {
8439
- const base = container instanceof HTMLElement ? container.clientWidth : typeof window !== "undefined" ? window.innerWidth : 1200;
8440
- return Math.round(base * 0.6);
8441
- }
8442
- function useDirtyGuard(dirty, onClose, onDiscard) {
8443
- const [confirming, setConfirming] = useState(false);
8444
- useEffect(() => {
8445
- if (!dirty) setConfirming(false);
8446
- }, [dirty]);
8447
- const requestClose = useCallback(() => {
8448
- if (!dirty) {
8449
- onClose();
8450
- return;
8451
- }
8452
- setConfirming((c) => !c);
8453
- }, [dirty, onClose]);
8454
- const keep = useCallback(() => setConfirming(false), []);
8455
- const discard = useCallback(() => {
8456
- setConfirming(false);
8457
- onDiscard?.();
8458
- onClose();
8459
- }, [onClose, onDiscard]);
8460
- return { confirming, requestClose, keep, discard };
8461
- }
8462
- function DiscardConfirm({ open, onKeep, onDiscard }) {
8463
- const keepRef = useRef(null);
8464
- const returnTo = useRef(null);
8465
- const overlay = useRef(null);
8466
- useEffect(() => {
8467
- if (!open) return;
8468
- const active = document.activeElement instanceof HTMLElement ? document.activeElement : null;
8469
- overlay.current = keepRef.current?.closest("[role='dialog'], [role='alertdialog']") ?? null;
8470
- returnTo.current = active && active !== document.body && overlay.current?.contains(active) ? active : null;
8471
- keepRef.current?.focus();
8472
- return () => {
8473
- if (document.activeElement !== document.body) return;
8474
- const back = returnTo.current;
8475
- if (back && back.isConnected) {
8476
- back.focus();
8477
- return;
8478
- }
8479
- const first = overlay.current?.querySelector("button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex='-1'])");
8480
- (first ?? overlay.current)?.focus();
8481
- };
8482
- }, [open]);
8483
- if (!open) return null;
8484
- return /* @__PURE__ */ jsxs(
8485
- "div",
8486
- {
8487
- role: "group",
8488
- "aria-label": "Unsaved changes",
8489
- "data-discard-confirm": "",
8490
- className: "shrink-0 flex flex-wrap items-center justify-between gap-ds-3 border-t-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)] bg-[var(--ds-status-warning-bg)]",
8491
- style: { padding: "var(--ds-space-3) var(--ds-space-5)" },
8492
- children: [
8493
- /* @__PURE__ */ jsx("p", { className: "text-sm text-[var(--ds-text-primary)]", children: "You have unsaved changes." }),
8494
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-2", children: [
8495
- /* @__PURE__ */ jsx(Button, { ref: keepRef, variant: "secondary", size: "sm", onClick: onKeep, children: "Keep editing" }),
8496
- /* @__PURE__ */ jsx(Button, { variant: "destructive", size: "sm", onClick: onDiscard, children: "Discard changes" })
8497
- ] })
8498
- ]
8499
- }
8500
- );
8501
- }
8502
- var slideClasses = {
8503
- right: {
8504
- panel: "top-0 right-0 h-full",
8505
- open: "translate-x-0",
8506
- closed: "translate-x-full"
8507
- },
8508
- left: {
8509
- panel: "top-0 left-0 h-full",
8510
- open: "translate-x-0",
8511
- closed: "-translate-x-full"
8512
- },
8513
- bottom: {
8514
- panel: "bottom-0 left-0 right-0",
8515
- open: "translate-y-0",
8516
- closed: "translate-y-full"
8517
- }
8518
- };
8519
- var borderByPosition = {
8520
- right: "border-l-[length:var(--ds-border-width)] border-l-[var(--ds-border-default)]",
8521
- left: "border-r-[length:var(--ds-border-width)] border-r-[var(--ds-border-default)]",
8522
- bottom: "border-t-[length:var(--ds-border-width)] border-t-[var(--ds-border-default)]"
8523
- };
8524
- function Drawer(props) {
8525
- const { position = "right", mobile, snapPoints, open, onClose, title, children, footer, container, flush, keepMounted, id, labelledBy, dirty, onDiscard } = props;
8526
- const isPhone = useBreakpoint("sm");
8527
- const mobileMode = mobile ?? (position === "left" ? "panel" : "sheet");
8528
- const guard = useDirtyGuard(dirty, onClose, onDiscard);
8529
- const confirm = /* @__PURE__ */ jsx(DiscardConfirm, { open: guard.confirming, onKeep: guard.keep, onDiscard: guard.discard });
8530
- if (isPhone && mobileMode === "sheet") {
8531
- return /* @__PURE__ */ jsx(Sheet, { open, onClose: guard.requestClose, title, footer, confirm, container, flush, snapPoints, keepMounted, id, labelledBy, children });
8532
- }
8533
- return /* @__PURE__ */ jsx(DrawerPanel, { ...props, onClose: guard.requestClose, confirm });
8534
- }
8535
- function DrawerPanel({ open, onClose, position = "right", width = "400px", title, children, footer, container, flush, lightBackdrop, topOffset, modal = true, keepMounted = false, id, labelledBy, resizable = false, maxWidth, confirm }) {
8536
- const nonModal = !modal;
8537
- const [chosen, remember] = useRememberedWidth(id ?? labelledBy);
8538
- const canResize = nonModal && resizable && position !== "bottom";
8539
- const effectiveWidth = canResize && chosen !== null ? `${chosen}px` : width;
8540
- const minPx = pxOf(width) ?? 320;
8541
- const maxPx = () => pxOf(maxWidth) ?? defaultMaxWidth(container instanceof Element ? container : null);
8542
- const titleId = useId();
8543
- const { ref: titleOverflowRef, isTruncated: titleTruncated } = useTextOverflow({ lines: 1 });
8544
- const isMobile = useBreakpoint("sm");
8545
- const panelRef = useRef(null);
8546
- const [mounted, setMounted] = useState(open);
8547
- const [hidden, setHidden] = useState(!open);
8548
- const onCloseRef = useLatest(onClose);
8549
- if (open && !mounted) setMounted(true);
8550
- if (open && hidden) setHidden(false);
8551
- const isTopLayer = useOverlayLayer(open);
8552
- useEffect(() => {
8553
- if (!open || nonModal) return;
8554
- const onKeyDown = (e) => {
8555
- if (e.key === "Escape" && isTopLayer()) onCloseRef.current();
8556
- };
8557
- document.addEventListener("keydown", onKeyDown);
8558
- if (!container) lockBodyScroll();
8559
- return () => {
8560
- document.removeEventListener("keydown", onKeyDown);
8561
- if (!container) unlockBodyScroll();
8562
- };
8563
- }, [open, nonModal, container, onCloseRef, isTopLayer]);
8564
- useReturnFocus(open && !nonModal);
8565
- useFocusTrap(panelRef, open && !topOffset && !nonModal, isTopLayer);
8566
- useEffect(() => {
8567
- if (!open || !mounted || nonModal) return;
8568
- const raf = requestAnimationFrame(() => focusInitial(panelRef.current));
8569
- return () => cancelAnimationFrame(raf);
8570
- }, [open, mounted, nonModal]);
8571
- useNonModalDialog(panelRef, open && mounted && nonModal, onClose, isTopLayer);
8572
- useCloseSettle(open, panelRef, () => {
8573
- if (keepMounted) setHidden(true);
8574
- else setMounted(false);
8575
- });
8576
- if (!mounted) return null;
8577
- const slide = slideClasses[position];
8578
- const isHorizontal = position === "left" || position === "right";
8579
- const positionClass = container ? "absolute" : "fixed";
8580
- return createPortal(
8581
- /* @__PURE__ */ jsxs(
8582
- "div",
8583
- {
8584
- hidden: keepMounted && hidden ? true : void 0,
8585
- className: cn(
8586
- `${positionClass} transition-opacity duration-[var(--ds-transition-speed)]`,
8587
- // A non-modal panel never intercepts the page: the wrapper is inert to the
8588
- // pointer and only the panel itself accepts events.
8589
- nonModal ? "z-[var(--ds-z-overlay)] pointer-events-none" : cn("z-[var(--ds-z-modal)]", open ? "pointer-events-auto" : "pointer-events-none"),
8590
- topOffset ? "left-0 right-0 bottom-0" : "inset-0"
8591
- ),
8592
- style: topOffset ? { top: topOffset } : void 0,
8593
- children: [
8594
- !nonModal && /* @__PURE__ */ jsx(
8595
- "div",
8596
- {
8597
- className: cn(
8598
- "absolute inset-0 transition-opacity duration-[var(--ds-transition-speed)]",
8599
- lightBackdrop ? "bg-black/15" : cn("bg-black/50", "[backdrop-filter:blur(calc(var(--ds-glass-blur)*0.3))] [-webkit-backdrop-filter:blur(calc(var(--ds-glass-blur)*0.3))]"),
8600
- open ? "opacity-100" : "opacity-0"
8601
- ),
8602
- onClick: onClose
8603
- }
8604
- ),
8605
- /* @__PURE__ */ jsxs(
8606
- "div",
8607
- {
8608
- ref: panelRef,
8609
- id,
8610
- role: "dialog",
8611
- "aria-modal": nonModal ? void 0 : "true",
8612
- "aria-labelledby": title ? titleId : labelledBy,
8613
- style: {
8614
- containerType: "inline-size",
8615
- width: isHorizontal ? effectiveWidth : void 0,
8616
- maxWidth: isHorizontal ? "100%" : void 0,
8617
- height: isMobile ? "100%" : void 0,
8618
- maxHeight: !isMobile && !isHorizontal ? "80vh" : void 0
8619
- },
8620
- className: cn(
8621
- `${positionClass} z-10 flex flex-col`,
8622
- nonModal && "pointer-events-auto",
8623
- "bg-[var(--ds-bg-surface)] text-[var(--ds-text-primary)]",
8624
- GLASS_OVERLAY,
8625
- // flush drops the edge border for children that draw their own (the mobile
8626
- // menu's Sidebar); a non-modal panel has no backdrop to separate it from
8627
- // the page, so it always keeps the border.
8628
- (!flush || nonModal) && borderByPosition[position],
8629
- "transition-transform duration-[var(--ds-transition-speed)] ease-[var(--ds-transition-ease)]",
8630
- isHorizontal && position === "left" && "rounded-r-[var(--ds-radius-lg)] overflow-hidden",
8631
- isHorizontal && position === "right" && "rounded-l-[var(--ds-radius-lg)] overflow-hidden",
8632
- !isHorizontal && "rounded-t-[var(--ds-radius-lg)] overflow-hidden",
8633
- (lightBackdrop || nonModal) && "shadow-[var(--ds-shadow-overlay)]",
8634
- slide.panel,
8635
- open ? slide.open : slide.closed
8636
- ),
8637
- children: [
8638
- canResize && open && /* @__PURE__ */ jsx(
8639
- ResizeEdge,
8640
- {
8641
- edge: position === "right" ? "left" : "right",
8642
- width: chosen ?? minPx,
8643
- min: minPx,
8644
- max: maxPx,
8645
- defaultWidth: minPx,
8646
- onResize: (w) => remember(w === minPx ? null : w),
8647
- label: "Resize panel"
8648
- }
8649
- ),
8650
- title && /* @__PURE__ */ jsxs(
8651
- "div",
8652
- {
8653
- className: "flex items-center justify-between shrink-0 border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]",
8654
- style: {
8655
- padding: "var(--ds-space-3) var(--ds-space-6)",
8656
- minHeight: "calc(var(--ds-space-unit) * 6 + 1.75rem + 2px + var(--ds-border-width))"
8657
- },
8658
- children: [
8659
- titleTruncated ? /* @__PURE__ */ jsx(Tooltip, { content: title, children: /* @__PURE__ */ jsx("h2", { ref: titleOverflowRef, id: titleId, className: "font-[family-name:var(--ds-font-display)] text-lg font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)] truncate", children: title }) }) : /* @__PURE__ */ jsx("h2", { ref: titleOverflowRef, id: titleId, className: "font-[family-name:var(--ds-font-display)] text-lg font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)] truncate", children: title }),
8660
- /* @__PURE__ */ jsx(
8661
- "button",
8662
- {
8663
- onClick: onClose,
8664
- ...{ [OVERLAY_CLOSE_ATTR]: "" },
8665
- className: "text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)] transition-colors cursor-pointer",
8666
- "aria-label": "Close",
8667
- children: /* @__PURE__ */ jsx(Icon, { name: "close", size: 18 })
8668
- }
8669
- )
8670
- ]
8671
- }
8672
- ),
8673
- /* @__PURE__ */ jsx(
8674
- "div",
8675
- {
8676
- className: "flex-1 overflow-y-auto",
8677
- style: flush ? void 0 : { padding: "var(--ds-space-5)" },
8678
- children
8679
- }
8680
- ),
8681
- confirm,
8682
- footer && /* @__PURE__ */ jsx(
8683
- "div",
8684
- {
8685
- className: "shrink-0 flex items-center justify-end gap-ds-2 border-t-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]",
8686
- style: { padding: "var(--ds-space-3) var(--ds-space-5)" },
8687
- children: footer
8688
- }
8689
- )
8690
- ]
8691
- }
8692
- )
8693
- ]
8694
- }
8695
- ),
8696
- container ?? document.body
8697
- );
8698
- }
8699
- var AppShellContext = createContext(null);
8700
- function useAppShell() {
8701
- return useContext(AppShellContext);
8702
- }
8703
- var AppShell = forwardRef(function AppShell2({
8704
- layout = "sidebar",
8705
- sidebar,
8706
- mobileMenu,
8707
- mobileMenuWidth,
8708
- mobileMenuLightBackdrop,
8709
- mobileMenuFlush = true,
8710
- navbar,
8711
- mobileNav,
8712
- footer,
8713
- skipLink = true,
8714
- mainId = "main",
8715
- aside,
8716
- asideSide = "right",
8717
- launcher,
8718
- children,
8719
- className,
8720
- scrollable = true,
8721
- theme,
8722
- currentPath,
8723
- homePath = "/"
8724
- }, ref) {
8725
- const [sidebarOpen, setSidebarOpen] = useState(false);
8726
- const [asideOpen, setAsideOpen] = useState(false);
8727
- const [asideFloating, setAsideFloating] = useState(false);
8728
- const isMobile = useBreakpoint("md");
8729
- const isSmallMobile = useBreakpoint("sm");
8730
- const isTablet = isMobile && !isSmallMobile;
8731
- const autoCollapsed = useBreakpoint("lg");
8732
- const [userCollapsed, setUserCollapsed] = useState(null);
8733
- const sidebarCollapsed = userCollapsed ?? autoCollapsed;
8734
- const hasSidebar = (layout === "sidebar" || layout === "sidebar-header") && sidebar != null;
8735
- const hasMobileMenu = mobileMenu != null;
8736
- const hasMobileNav = mobileNav != null;
8737
- const showMobileDrawer = hasMobileMenu && !(isSmallMobile && hasMobileNav);
8738
- const [shellEl, setShellEl] = useState(null);
8739
- const [chrome, setChrome] = useState({});
8740
- const registerChrome = useCallback((kind, position) => {
8741
- setChrome((c) => c[kind] === position ? c : { ...c, [kind]: position });
8742
- return () => setChrome((c) => {
8743
- if (!(kind in c)) return c;
8744
- const next = { ...c };
8745
- delete next[kind];
8746
- return next;
8747
- });
8748
- }, []);
8749
- const navbarFloating = (chrome.navbar ?? theme?.navbarPosition) === "floating";
8750
- const sidebarFloating = hasSidebar && !isMobile && (chrome.sidebar ?? theme?.sidebarPosition) === "floating";
8751
- const isHome = currentPath != null && currentPath === homePath;
8752
- return /* @__PURE__ */ jsx(
8753
- AppShellContext,
8754
- {
8755
- value: { hasSidebar, hasMobileMenu, hasMobileNav, sidebarOpen, setSidebarOpen, isMobile, isTablet, sidebarCollapsed, setSidebarCollapsed: setUserCollapsed, asideOpen, setAsideOpen, asideSide, asideFloating, setAsideFloating, container: shellEl, theme: theme ?? null, isHome, navbarFloating, sidebarFloating, registerChrome },
8756
- children: /* @__PURE__ */ jsxs("div", { ref: (el) => {
8757
- setShellEl(el);
8758
- if (typeof ref === "function") ref(el);
8759
- else if (ref) ref.current = el;
8760
- }, className: cn("relative h-screen flex flex-col bg-[var(--ds-bg-canvas)] overflow-hidden", className), children: [
8761
- skipLink && /* @__PURE__ */ jsx(SkipLink, { href: `#${mainId}` }),
8762
- layout === "sidebar-header" && navbar,
8763
- layout === "multi-column" && navbar,
8764
- /* @__PURE__ */ jsxs("div", { className: "flex flex-1 min-h-0", children: [
8765
- hasSidebar && !isMobile && /* @__PURE__ */ jsx("div", { className: "shrink-0 h-full", children: sidebar }),
8766
- aside && asideSide === "left" && aside,
8767
- /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col min-w-0 min-h-0", children: [
8768
- layout === "sidebar" && navbar,
8769
- layout === "stacked" && navbar,
8770
- /* @__PURE__ */ jsx(
8771
- "main",
8772
- {
8773
- id: mainId,
8774
- tabIndex: -1,
8775
- className: cn(
8776
- "flex-1 min-h-0 focus:outline-none",
8777
- scrollable ? "overflow-y-auto" : "relative",
8778
- layout === "multi-column" && "flex"
8779
- ),
8780
- style: { containerType: "inline-size" },
8781
- children: scrollable ? footer ? /* @__PURE__ */ jsxs("div", { className: "min-h-full flex flex-col", children: [
8782
- /* @__PURE__ */ jsx("div", { className: "flex-1", children }),
8783
- footer
8784
- ] }) : children : /* @__PURE__ */ jsx("div", { className: "absolute inset-0", children })
8785
- }
8786
- )
8787
- ] }),
8788
- aside && asideSide === "right" && aside
8789
- ] }),
8790
- showMobileDrawer && isMobile && /* @__PURE__ */ jsx(
8791
- Drawer,
8792
- {
8793
- open: sidebarOpen,
8794
- onClose: () => setSidebarOpen(false),
8795
- position: "left",
8796
- width: mobileMenuWidth ?? "var(--ds-drawer-width)",
8797
- container: shellEl ?? void 0,
8798
- flush: mobileMenuFlush,
8799
- lightBackdrop: mobileMenuLightBackdrop,
8800
- topOffset: layout !== "stacked" && navbar != null ? "var(--ds-navbar-height)" : void 0,
8801
- children: mobileMenu
8802
- }
8803
- ),
8804
- isSmallMobile && mobileNav && /* @__PURE__ */ jsx("div", { className: "sticky bottom-0 z-[var(--ds-z-sticky)]", children: mobileNav }),
8805
- !isSmallMobile && launcher
8806
- ] })
8807
- }
8808
- );
8809
- });
8810
8138
  var FALLBACK_MIN_PX = 320;
8811
8139
  var GUTTER = "var(--ds-space-3)";
8812
8140
  function AsidePanel({
@@ -8968,14 +8296,30 @@ function TruncText({ children, className }) {
8968
8296
  if (!isTruncated) return text;
8969
8297
  return /* @__PURE__ */ jsx(Tooltip, { content: children, children: text });
8970
8298
  }
8299
+ var warnedLegacyProps = false;
8971
8300
  var StackedList = forwardRef(function StackedList2({
8972
8301
  items,
8973
8302
  divided = true,
8974
- flush = false,
8303
+ variant: variantProp,
8975
8304
  selectedId,
8976
- hover = "tint",
8977
- className
8305
+ className,
8306
+ flush,
8307
+ hover
8978
8308
  }, ref) {
8309
+ const isPhone = useBreakpoint("sm");
8310
+ const inCard = useContext(CardSurfaceCtx);
8311
+ const inPane = useContext(SplitPaneCtx);
8312
+ const variant = variantProp ?? (flush || hover === "title" ? "articles" : "list");
8313
+ const legacy = flush !== void 0 || hover !== void 0;
8314
+ useEffect(() => {
8315
+ if (!legacy || warnedLegacyProps) return;
8316
+ warnedLegacyProps = true;
8317
+ console.warn('StackedList: `flush` and `hover` are deprecated \u2014 pass variant="articles" for an article list; the default variant takes its inset from the pane or card it sits in.');
8318
+ }, [legacy]);
8319
+ const articles = variant === "articles";
8320
+ const stackMeta = isPhone && articles;
8321
+ const selectable = selectedId !== void 0 || items.some((i) => i.selected !== void 0);
8322
+ const inset = articles ? inCard ? "px-ds-5" : "px-0" : inCard ? "px-ds-5" : inPane ? "pl-ds-3 pr-ds-4" : selectable ? "pl-ds-3 pr-0" : "px-0";
8979
8323
  return /* @__PURE__ */ jsx(
8980
8324
  "ul",
8981
8325
  {
@@ -8992,6 +8336,9 @@ var StackedList = forwardRef(function StackedList2({
8992
8336
  const multiline = !!item.description;
8993
8337
  const trailing = item.unread || item.meta ? /* @__PURE__ */ jsxs("div", { className: cn(
8994
8338
  "shrink-0 flex items-center gap-ds-2 text-sm",
8339
+ // Below sm an article's meta sits under the title, left-aligned, whatever alignment its own markup
8340
+ // carries (round 6: a builder's items-end column put its badge mid-row).
8341
+ stackMeta && "self-start [&>*]:items-start! [&>*]:text-left!",
8995
8342
  isSelected ? "text-[var(--ds-nav-v-active-muted)]" : "text-[var(--ds-text-muted)]"
8996
8343
  ), children: [
8997
8344
  item.unread && /* @__PURE__ */ jsx(
@@ -9010,18 +8357,20 @@ var StackedList = forwardRef(function StackedList2({
9010
8357
  className: cn(
9011
8358
  "flex gap-ds-3 py-ds-3",
9012
8359
  multiline ? "items-start" : "items-center",
9013
- flush ? "px-0" : "px-ds-5",
8360
+ inset,
9014
8361
  interactive && [
9015
8362
  "cursor-pointer [transition:var(--ds-transition-interactive)]",
9016
8363
  "focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]"
9017
8364
  ],
9018
- // Same colours as the vertical Tabs item — the theme's in-page vertical
9019
- // style decides rail, tint or pill via the --ds-nav-v-* tokens — but a
9020
- // list row is a full-width band: no radius, ever, and a heavier rail
9021
- // (1.5× the tab rail; still 0 under tint and pill). Every row carries
9022
- // the rail width as a transparent placeholder so content never shifts.
9023
- "border-l-[length:calc(var(--ds-nav-v-active-rail)*1.5)]",
9024
- isSelected ? "bg-[var(--ds-nav-v-active-bg)] text-[var(--ds-nav-v-active-text)] border-[var(--ds-accent-primary)]" : cn("border-transparent", interactive && hover === "tint" && "hover:bg-[var(--ds-tab-hover-bg)]", interactive && hover === "title" && "group/row")
8365
+ // list: same colours as the vertical Tabs item — the theme's in-page vertical style decides rail, tint
8366
+ // or pill via the --ds-nav-v-* tokens — but a list row is a full-width band: no radius, ever, and a
8367
+ // heavier rail (1.5× the tab rail; still 0 under tint and pill). Every row carries the rail width as a
8368
+ // transparent placeholder so content never shifts, and the inset keeps content off the rail.
8369
+ // articles: no rail, no tint; the title answers the pointer and the current row.
8370
+ // The placeholder exists only where a selection can appear, so a plain canvas list aligns exactly with its heading.
8371
+ !articles && selectable && "border-l-[length:calc(var(--ds-nav-v-active-rail)*1.5)]",
8372
+ !articles && (isSelected ? "bg-[var(--ds-nav-v-active-bg)] text-[var(--ds-nav-v-active-text)] border-[var(--ds-accent-primary)]" : cn("border-transparent", interactive && "hover:bg-[var(--ds-tab-hover-bg)]")),
8373
+ articles && interactive && "group/row"
9025
8374
  ),
9026
8375
  onClick: item.onClick,
9027
8376
  role: interactive ? "button" : void 0,
@@ -9036,25 +8385,25 @@ var StackedList = forwardRef(function StackedList2({
9036
8385
  children: [
9037
8386
  item.leading && /* @__PURE__ */ jsx("div", { className: cn("shrink-0", multiline && "mt-ds-0.5"), children: item.leading }),
9038
8387
  /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
9039
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-ds-2", children: [
8388
+ /* @__PURE__ */ jsxs("div", { className: cn("flex gap-ds-2", stackMeta ? "flex-col" : "items-center justify-between"), children: [
9040
8389
  /* @__PURE__ */ jsx(
9041
8390
  TruncText,
9042
8391
  {
9043
8392
  className: cn(
9044
8393
  "text-sm",
9045
- isSelected ? "font-medium text-[var(--ds-nav-v-active-text)]" : hasEmphasis && !item.unread ? "text-[var(--ds-text-secondary)]" : "font-medium text-[var(--ds-text-primary)]",
9046
- // hover="title": the title answers the pointer (accent, underline) instead of the row's background
9047
- interactive && hover === "title" && !isSelected && "transition-colors group-hover/row:text-[var(--ds-accent-primary)] group-hover/row:underline underline-offset-2"
8394
+ isSelected ? articles ? "font-medium text-[var(--ds-accent-primary)]" : "font-medium text-[var(--ds-nav-v-active-text)]" : hasEmphasis && !item.unread ? "text-[var(--ds-text-secondary)]" : "font-medium text-[var(--ds-text-primary)]",
8395
+ // articles: the title answers the pointer (accent, underline) instead of the row's background
8396
+ articles && interactive && !isSelected && "transition-colors group-hover/row:text-[var(--ds-accent-primary)] group-hover/row:underline underline-offset-2"
9048
8397
  ),
9049
8398
  children: item.title
9050
8399
  }
9051
8400
  ),
9052
- multiline && trailing
8401
+ (multiline || stackMeta) && trailing
9053
8402
  ] }),
9054
8403
  item.subtitle && /* @__PURE__ */ jsx(TruncText, { className: cn("text-sm", isSelected ? "text-[var(--ds-nav-v-active-muted)]" : "text-[var(--ds-text-secondary)]"), children: item.subtitle }),
9055
8404
  item.description && /* @__PURE__ */ jsx(TruncText, { className: cn("text-xs", isSelected ? "text-[var(--ds-nav-v-active-muted)]" : "text-[var(--ds-text-muted)]"), children: item.description })
9056
8405
  ] }),
9057
- !multiline && trailing,
8406
+ !multiline && !stackMeta && trailing,
9058
8407
  item.actions && /* @__PURE__ */ jsx(
9059
8408
  "div",
9060
8409
  {
@@ -9363,6 +8712,100 @@ function trackClasses(orientation) {
9363
8712
  "border-b-[length:var(--ds-nav-h-track-border)] border-[var(--ds-border-default)]"
9364
8713
  );
9365
8714
  }
8715
+ var FADE = 24;
8716
+ function useScrollTrack(activeTab, enabled) {
8717
+ const ref = useRef(null);
8718
+ const [edges, setEdges] = useState({ left: false, right: false });
8719
+ const measure = useCallback(() => {
8720
+ const el = ref.current;
8721
+ if (!el) return;
8722
+ const left = el.scrollLeft > 1;
8723
+ const right = el.scrollLeft + el.clientWidth < el.scrollWidth - 1;
8724
+ setEdges((prev) => prev.left === left && prev.right === right ? prev : { left, right });
8725
+ }, []);
8726
+ useLayoutEffect(() => {
8727
+ if (!enabled) return;
8728
+ measure();
8729
+ const el = ref.current;
8730
+ if (!el || typeof ResizeObserver === "undefined") return;
8731
+ const observer = new ResizeObserver(measure);
8732
+ observer.observe(el);
8733
+ return () => observer.disconnect();
8734
+ }, [enabled, measure]);
8735
+ useLayoutEffect(() => {
8736
+ if (!enabled) return;
8737
+ const el = ref.current;
8738
+ const tab = el?.querySelector('[role="tab"][aria-selected="true"]');
8739
+ if (!el || !tab) return;
8740
+ const start = tab.offsetLeft;
8741
+ const end = start + tab.offsetWidth;
8742
+ if (start < el.scrollLeft + FADE) el.scrollLeft = Math.max(0, start - FADE);
8743
+ else if (end > el.scrollLeft + el.clientWidth - FADE) el.scrollLeft = end - el.clientWidth + FADE;
8744
+ measure();
8745
+ }, [activeTab, enabled, measure]);
8746
+ useEffect(() => {
8747
+ if (!enabled) return;
8748
+ const el = ref.current;
8749
+ if (!el) return;
8750
+ const onWheel = (e) => {
8751
+ if (el.scrollWidth <= el.clientWidth || Math.abs(e.deltaY) <= Math.abs(e.deltaX)) return;
8752
+ el.scrollLeft += e.deltaY;
8753
+ e.preventDefault();
8754
+ };
8755
+ let startX = 0, startLeft = 0, dragged = false, down = false;
8756
+ const onDown = (e) => {
8757
+ if (e.pointerType === "mouse" && e.button !== 0) return;
8758
+ down = true;
8759
+ dragged = false;
8760
+ startX = e.clientX;
8761
+ startLeft = el.scrollLeft;
8762
+ };
8763
+ const onMove = (e) => {
8764
+ if (!down) return;
8765
+ const dx = e.clientX - startX;
8766
+ if (!dragged && Math.abs(dx) < 5) return;
8767
+ if (!dragged) {
8768
+ dragged = true;
8769
+ el.setPointerCapture?.(e.pointerId);
8770
+ }
8771
+ el.scrollLeft = startLeft - dx;
8772
+ };
8773
+ const onUp = (e) => {
8774
+ if (dragged) el.releasePointerCapture?.(e.pointerId);
8775
+ down = false;
8776
+ };
8777
+ const onClick = (e) => {
8778
+ if (dragged) {
8779
+ e.stopPropagation();
8780
+ e.preventDefault();
8781
+ dragged = false;
8782
+ }
8783
+ };
8784
+ el.addEventListener("wheel", onWheel, { passive: false });
8785
+ el.addEventListener("pointerdown", onDown);
8786
+ el.addEventListener("pointermove", onMove);
8787
+ el.addEventListener("pointerup", onUp);
8788
+ el.addEventListener("pointercancel", onUp);
8789
+ el.addEventListener("click", onClick, true);
8790
+ return () => {
8791
+ el.removeEventListener("wheel", onWheel);
8792
+ el.removeEventListener("pointerdown", onDown);
8793
+ el.removeEventListener("pointermove", onMove);
8794
+ el.removeEventListener("pointerup", onUp);
8795
+ el.removeEventListener("pointercancel", onUp);
8796
+ el.removeEventListener("click", onClick, true);
8797
+ };
8798
+ }, [enabled]);
8799
+ const fade = enabled ? [edges.left && "left", edges.right && "right"].filter(Boolean).join(" ") : "";
8800
+ const mask = fade ? `linear-gradient(to right, ${edges.left ? `transparent 0, black ${FADE}px` : "black 0"}, ${edges.right ? `black calc(100% - ${FADE}px), transparent 100%` : "black 100%"})` : void 0;
8801
+ return {
8802
+ ref,
8803
+ onScroll: measure,
8804
+ "data-fade": fade || void 0,
8805
+ style: mask ? { maskImage: mask, WebkitMaskImage: mask } : void 0
8806
+ };
8807
+ }
8808
+ var SCROLL_TRACK = "overflow-x-auto overflow-y-hidden [scrollbar-width:none] [&::-webkit-scrollbar]:hidden max-w-full";
9366
8809
  function getTabsFromDOM(el) {
9367
8810
  const tablist = el.closest('[role="tablist"]');
9368
8811
  if (!tablist) return [];
@@ -9502,7 +8945,8 @@ function TabButton({
9502
8945
  return btn;
9503
8946
  }
9504
8947
  function TabsList({ children, className }) {
9505
- const { orientation, fullWidth, overflow } = useTabsCtx();
8948
+ const { orientation, fullWidth, overflow, activeTab } = useTabsCtx();
8949
+ const track = useScrollTrack(activeTab, orientation === "horizontal" && overflow === "scroll");
9506
8950
  if (orientation === "vertical") {
9507
8951
  return /* @__PURE__ */ jsx(
9508
8952
  "div",
@@ -9518,10 +8962,11 @@ function TabsList({ children, className }) {
9518
8962
  "div",
9519
8963
  {
9520
8964
  role: "tablist",
8965
+ ...overflow === "scroll" ? track : {},
9521
8966
  className: cn(
9522
8967
  trackClasses("horizontal"),
9523
8968
  "max-w-full",
9524
- overflow === "hidden" ? "overflow-hidden" : overflow === "truncate" ? "overflow-hidden" : "overflow-x-auto overflow-y-hidden",
8969
+ overflow === "hidden" ? "overflow-hidden" : overflow === "truncate" ? "overflow-hidden" : SCROLL_TRACK,
9525
8970
  fullWidth && "w-full",
9526
8971
  className
9527
8972
  ),
@@ -9575,6 +9020,9 @@ function TabsRoot(props) {
9575
9020
  } = props;
9576
9021
  const isMobile = useBreakpoint("md");
9577
9022
  const effectiveOrientation = orientation === "responsive" ? "vertical" : orientation;
9023
+ const arrayApi = "tabs" in props && !!props.tabs;
9024
+ const arrayOverflow = arrayApi && props.tabs.some((t) => t.truncate) ? "truncate" : overflow;
9025
+ const track = useScrollTrack(activeTab, arrayApi && effectiveOrientation === "horizontal" && arrayOverflow === "scroll");
9578
9026
  if ("tabs" in props && props.tabs) {
9579
9027
  const { tabs, mobile = "scroll" } = props;
9580
9028
  const collapseToDropdown = isMobile && (orientation === "responsive" || mobile === "dropdown");
@@ -9613,14 +9061,15 @@ function TabsRoot(props) {
9613
9061
  }
9614
9062
  );
9615
9063
  }
9616
- const effectiveOverflow = tabs.some((t) => t.truncate) ? "truncate" : overflow;
9064
+ const effectiveOverflow = arrayOverflow;
9617
9065
  return /* @__PURE__ */ jsx(
9618
9066
  "div",
9619
9067
  {
9620
9068
  role: "tablist",
9069
+ ...effectiveOverflow === "scroll" ? track : {},
9621
9070
  className: cn(
9622
9071
  trackClasses("horizontal"),
9623
- effectiveOverflow === "scroll" ? "overflow-x-auto overflow-y-hidden" : "overflow-hidden",
9072
+ effectiveOverflow === "scroll" ? SCROLL_TRACK : "overflow-hidden",
9624
9073
  fullWidth && "w-full",
9625
9074
  className
9626
9075
  ),
@@ -9678,61 +9127,6 @@ function SettingsLayout({
9678
9127
  /* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children })
9679
9128
  ] });
9680
9129
  }
9681
- function SplitView({
9682
- list,
9683
- detail,
9684
- aside,
9685
- asideTitle = "Details",
9686
- detailOpen = false,
9687
- onDetailClose,
9688
- detailMode = "stack",
9689
- backLabel = "Back",
9690
- listWidth = 35,
9691
- listMinWidth = 25,
9692
- asideWidth = 25,
9693
- collapseBelow = 768,
9694
- asideCollapseBelow = 1024,
9695
- bordered = false,
9696
- "aria-label": ariaLabel,
9697
- className
9698
- }) {
9699
- const rootRef = useRef(null);
9700
- const compact = useCompact(rootRef, collapseBelow);
9701
- const asideCollapsed = useCompact(rootRef, asideCollapseBelow);
9702
- const [asideOpen, setAsideOpen] = useState(false);
9703
- useEffect(() => {
9704
- if (!asideCollapsed) setAsideOpen(false);
9705
- }, [asideCollapsed]);
9706
- const region = ariaLabel ? { role: "region", "aria-label": ariaLabel } : {};
9707
- const surface = cn(
9708
- "h-full min-h-0 w-full bg-[var(--ds-bg-surface)]",
9709
- bordered && "border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)] rounded-[var(--ds-radius-md)] overflow-hidden",
9710
- className
9711
- );
9712
- if (compact) {
9713
- const showDetail = detailMode === "stack" && detailOpen;
9714
- return /* @__PURE__ */ jsx("div", { ref: rootRef, "data-split-view": showDetail ? "detail" : "list", ...region, className: cn(surface, "flex flex-col"), children: showDetail ? /* @__PURE__ */ jsxs(Fragment, { children: [
9715
- /* @__PURE__ */ jsx("div", { className: "shrink-0 px-ds-3 py-ds-2 border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]", children: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", iconLeft: /* @__PURE__ */ jsx(Icon, { name: "arrow-left", size: 14 }), onClick: onDetailClose, children: backLabel }) }),
9716
- /* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 overflow-y-auto", children: detail })
9717
- ] }) : /* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 overflow-y-auto", children: list }) });
9718
- }
9719
- const asideToggle = aside && asideCollapsed ? /* @__PURE__ */ jsx("div", { className: "shrink-0 flex justify-end px-ds-3 py-ds-2 border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]", children: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", iconLeft: /* @__PURE__ */ jsx(Icon, { name: "info", size: 14 }), onClick: () => setAsideOpen(true), "aria-expanded": asideOpen, children: asideTitle }) }) : null;
9720
- return /* @__PURE__ */ jsxs("div", { ref: rootRef, "data-split-view": "split", ...region, className: surface, children: [
9721
- /* @__PURE__ */ jsxs(ResizablePanelGroup, { direction: "horizontal", stackOnMobile: false, className: "h-full", children: [
9722
- /* @__PURE__ */ jsx(ResizablePanel, { id: "list", defaultSize: `${listWidth}%`, minSize: `${listMinWidth}%`, children: /* @__PURE__ */ jsx("div", { className: "h-full min-h-0 overflow-y-auto", children: list }) }),
9723
- /* @__PURE__ */ jsx(ResizableHandle, { withHandle: true }),
9724
- /* @__PURE__ */ jsx(ResizablePanel, { id: "detail", minSize: "30%", children: /* @__PURE__ */ jsxs("div", { className: "h-full min-h-0 flex flex-col", children: [
9725
- asideToggle,
9726
- /* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 overflow-y-auto", children: detail })
9727
- ] }) }),
9728
- aside && !asideCollapsed && /* @__PURE__ */ jsxs(Fragment, { children: [
9729
- /* @__PURE__ */ jsx(ResizableHandle, { withHandle: true }),
9730
- /* @__PURE__ */ jsx(ResizablePanel, { id: "aside", defaultSize: `${asideWidth}%`, minSize: "15%", children: /* @__PURE__ */ jsx("div", { className: "h-full min-h-0 overflow-y-auto", children: aside }) })
9731
- ] })
9732
- ] }),
9733
- aside && asideCollapsed && /* @__PURE__ */ jsx(Drawer, { open: asideOpen, onClose: () => setAsideOpen(false), title: asideTitle, position: "right", children: aside })
9734
- ] });
9735
- }
9736
9130
  function SeparatorIcon({ type, size }) {
9737
9131
  const iconSize = size === "sm" ? 10 : 12;
9738
9132
  if (type === "chevron") return /* @__PURE__ */ jsx(Icon, { name: "chevron-right", size: iconSize });
@@ -9984,6 +9378,7 @@ function Popover({ open, onOpenChange, trigger, children, side = "bottom", align
9984
9378
  "div",
9985
9379
  {
9986
9380
  ref: floatingRef,
9381
+ "data-gs": "popover",
9987
9382
  className: cn(
9988
9383
  "fixed z-[var(--ds-z-popover)]",
9989
9384
  "bg-[var(--ds-bg-surface-elevated)]",
@@ -10143,7 +9538,7 @@ function EllipsisJumper({ totalPages, onPageChange }) {
10143
9538
  type: "button",
10144
9539
  onClick: handleGo,
10145
9540
  className: cn(
10146
- "px-ds-2.5 h-8 text-xs font-medium cursor-pointer",
9541
+ "px-ds-2.5 h-[var(--ds-control-height-sm)] text-xs font-medium cursor-pointer",
10147
9542
  "rounded-[var(--ds-radius-md)]",
10148
9543
  "bg-[var(--ds-accent-primary)] text-[var(--ds-text-on-primary)]",
10149
9544
  "transition-colors duration-[var(--ds-transition-speed)]",
@@ -10579,9 +9974,11 @@ var Sidebar = forwardRef(function Sidebar2({
10579
9974
  }
10580
9975
  return /* @__PURE__ */ jsx(SidebarContext, { value: { collapsed, onCollapsedChange: handleCollapsedChange, portalContainer: portalEl, type, position: "flush", navbarFloating: !!navbarFloating, navSize }, children: aside });
10581
9976
  });
10582
- function TruncLabel3({ children, className, side = "right", container }) {
10583
- const { ref, isTruncated } = useTextOverflow({ lines: 1 });
10584
- const label = /* @__PURE__ */ jsx("span", { ref, className: cn("truncate", className), children });
9977
+ function TruncLabel3({ children, className, side = "right", container, lines = 1 }) {
9978
+ const { ref, isTruncated } = useTextOverflow({ lines });
9979
+ const clampMap = { 2: "line-clamp-2", 3: "line-clamp-3" };
9980
+ const clampClass = lines <= 1 ? "truncate" : clampMap[lines] ?? "truncate";
9981
+ const label = /* @__PURE__ */ jsx("span", { ref, className: cn(clampClass, className), children });
10585
9982
  if (!isTruncated) return label;
10586
9983
  return /* @__PURE__ */ jsx(Tooltip, { content: children, side, delay: 200, container, children: label });
10587
9984
  }
@@ -11054,7 +10451,7 @@ function CompactNavItem({
11054
10451
  className: cn((item.active || childActive) && "text-[var(--ds-sidebar-active-accent)]")
11055
10452
  }
11056
10453
  ),
11057
- /* @__PURE__ */ jsx(TruncLabel3, { className: "text-[clamp(9px,var(--ds-font-size-2xs),12px)] leading-tight max-w-full", side: "right", container: portalContainer ?? void 0, children: item.label }),
10454
+ /* @__PURE__ */ jsx(TruncLabel3, { className: "text-[clamp(9px,var(--ds-font-size-2xs),12px)] leading-tight max-w-full text-center", lines: 2, side: "right", container: portalContainer ?? void 0, children: item.label }),
11058
10455
  mobile && hasChildren && /* @__PURE__ */ jsx(
11059
10456
  Icon,
11060
10457
  {
@@ -11228,7 +10625,8 @@ function resolvePageHeader(theme, props, facts) {
11228
10625
  breadcrumbSeparator: props.breadcrumbSeparator ?? b.separator ?? "chevron",
11229
10626
  navbarFloating,
11230
10627
  sidebarFloating,
11231
- outside: variant === "colourful" || behavior === "snapping" || position === "floating"
10628
+ outside: variant === "colourful" || behavior === "snapping" || position === "floating",
10629
+ overlap: variant === "colourful" && (t.overlap ?? false)
11232
10630
  };
11233
10631
  }
11234
10632
  var maxWidthValues = {
@@ -11258,6 +10656,11 @@ var bottomPaddingClasses = {
11258
10656
  default: "pb-ds-12",
11259
10657
  spacious: "pb-ds-16"
11260
10658
  };
10659
+ var bottomPaddingValues = {
10660
+ none: "0px",
10661
+ default: "var(--ds-space-12)",
10662
+ spacious: "var(--ds-space-16)"
10663
+ };
11261
10664
  var FLOATING_BLOCK = cn(
11262
10665
  "rounded-[var(--ds-radius-md)]",
11263
10666
  "border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]",
@@ -11273,6 +10676,26 @@ function isPageHeaderElement(node) {
11273
10676
  const type = node.type;
11274
10677
  return !!type && typeof type !== "string" && type[PAGE_HEADER_MARK] === true;
11275
10678
  }
10679
+ var OVERLAP_MIN = 24;
10680
+ var OVERLAP_MAX = 64;
10681
+ var ROW_MAX = 56;
10682
+ function firstCardIn(el) {
10683
+ let cur = el;
10684
+ for (let depth = 0; cur && depth < 6; depth++) {
10685
+ if (cur.hasAttribute("data-card")) return cur;
10686
+ cur = cur.firstElementChild;
10687
+ }
10688
+ return null;
10689
+ }
10690
+ function overlapCard(column) {
10691
+ if (!column) return null;
10692
+ for (const child of Array.from(column.children)) {
10693
+ const card = firstCardIn(child);
10694
+ if (card) return card;
10695
+ if (child.getBoundingClientRect().height > ROW_MAX) return null;
10696
+ }
10697
+ return null;
10698
+ }
11276
10699
  function floatingBlockPadding(navbarFloating, sidebarFloating, overlap) {
11277
10700
  return {
11278
10701
  paddingTop: navbarFloating ? 0 : "var(--ds-space-3)",
@@ -11307,7 +10730,51 @@ var PageContainer = forwardRef(function PageContainer2({
11307
10730
  const maxWidthValue = maxWidthValues[resolvedMaxWidth];
11308
10731
  const kids = Children.toArray(children);
11309
10732
  const headerIdx = kids.findIndex(isPageHeaderElement);
11310
- if (headerIdx === -1) {
10733
+ const launcherCorner = shell?.launcherCorner ?? null;
10734
+ const vPad = verticalPadding ?? "default";
10735
+ const launcherPadding = launcherCorner ? { paddingBottom: `max(${bottomPaddingValues[vPad]}, var(--ds-toast-inset-${launcherCorner}, 0px))` } : {};
10736
+ const headerEl = headerIdx === -1 ? null : kids[headerIdx];
10737
+ const r = headerEl ? resolvePageHeader(shell?.theme, headerEl.props, {
10738
+ isHome: shell?.isHome ?? false,
10739
+ isMobile: shell?.isMobile ?? false,
10740
+ navbarFloating: shell?.navbarFloating ?? false,
10741
+ sidebarFloating: shell?.sidebarFloating ?? false
10742
+ }) : null;
10743
+ const overlapActive = !!r && r.variant === "colourful" && r.overlap;
10744
+ const columnRef = useRef(null);
10745
+ const observedRef = useRef(null);
10746
+ useEffect(() => {
10747
+ const stop = () => {
10748
+ observedRef.current?.ro.disconnect();
10749
+ observedRef.current = null;
10750
+ };
10751
+ const column2 = columnRef.current;
10752
+ const card = overlapActive ? overlapCard(column2) : null;
10753
+ if (!card || !column2) {
10754
+ stop();
10755
+ rootRef.current?.style.removeProperty("--ds-overlap");
10756
+ rootRef.current?.style.removeProperty("--ds-overlap-gap");
10757
+ return;
10758
+ }
10759
+ if (observedRef.current?.target === card) return;
10760
+ stop();
10761
+ if (typeof ResizeObserver === "undefined") return;
10762
+ const ro = new ResizeObserver((entries) => {
10763
+ const cardHeight = card.getBoundingClientRect().height || (entries.find((e) => e.target === card)?.contentRect.height ?? 0);
10764
+ const rowsAbove = Math.max(0, Math.round(card.getBoundingClientRect().top - column2.getBoundingClientRect().top));
10765
+ const half = Math.min(OVERLAP_MAX, Math.max(OVERLAP_MIN, Math.round(cardHeight / 2)));
10766
+ rootRef.current?.style.setProperty("--ds-overlap", `${rowsAbove + half}px`);
10767
+ rootRef.current?.style.setProperty("--ds-overlap-gap", "0px");
10768
+ });
10769
+ ro.observe(card);
10770
+ ro.observe(column2);
10771
+ observedRef.current = { target: card, ro };
10772
+ });
10773
+ useEffect(() => () => {
10774
+ observedRef.current?.ro.disconnect();
10775
+ observedRef.current = null;
10776
+ }, []);
10777
+ if (headerIdx === -1 || !headerEl || !r) {
11311
10778
  return /* @__PURE__ */ jsx(
11312
10779
  "div",
11313
10780
  {
@@ -11315,23 +10782,16 @@ var PageContainer = forwardRef(function PageContainer2({
11315
10782
  className: cn(
11316
10783
  "w-full",
11317
10784
  paddingClasses[padding],
11318
- verticalPaddingClasses[verticalPadding ?? "default"],
10785
+ verticalPaddingClasses[vPad],
11319
10786
  centered && "mx-auto",
11320
10787
  className
11321
10788
  ),
11322
- style: { maxWidth: maxWidthValue, containerType: "inline-size" },
10789
+ style: { maxWidth: maxWidthValue, containerType: "inline-size", ...launcherPadding },
11323
10790
  children
11324
10791
  }
11325
10792
  );
11326
10793
  }
11327
- const headerEl = kids[headerIdx];
11328
10794
  const rest = kids.filter((_, i) => i !== headerIdx);
11329
- const r = resolvePageHeader(shell?.theme, headerEl.props, {
11330
- isHome: shell?.isHome ?? false,
11331
- isMobile: shell?.isMobile ?? false,
11332
- navbarFloating: shell?.navbarFloating ?? false,
11333
- sidebarFloating: shell?.sidebarFloating ?? false
11334
- });
11335
10795
  const snapping = r.behavior === "snapping";
11336
10796
  const floatingHeader = r.position === "floating";
11337
10797
  const colourful = r.variant === "colourful";
@@ -11340,22 +10800,18 @@ var PageContainer = forwardRef(function PageContainer2({
11340
10800
  const block = floatingHeader && contained && !snapping;
11341
10801
  const placement = block ? "block" : r.outside ? "outside" : "inside";
11342
10802
  const breadcrumbsInsideHeader = snapping && floatingHeader && contained;
11343
- const overlap = colourful && typeof headerEl.props.overlapHeight === "number" && headerEl.props.overlapHeight > 0 ? headerEl.props.overlapHeight : 0;
11344
- const strip = contained && !breadcrumbsInsideHeader && crumbs ? (
11345
- // The strip is the whole trail: the path, then this page as the current item (Breadcrumbs renders the last item as text).
11346
- /* @__PURE__ */ jsx(Breadcrumbs, { variant: "contained", itemVariant: r.breadcrumbStyle, bleed: true, contentMaxWidth: maxWidthValue, separator: r.breadcrumbSeparator, items: headerEl.props.title ? [...crumbs, { label: headerEl.props.title }] : crumbs })
11347
- ) : null;
10803
+ const strip = contained && !breadcrumbsInsideHeader && crumbs ? /* @__PURE__ */ jsx(Breadcrumbs, { variant: "contained", itemVariant: r.breadcrumbStyle, bleed: true, contentMaxWidth: maxWidthValue, separator: r.breadcrumbSeparator, items: headerEl.props.title ? [...crumbs, { label: headerEl.props.title }] : crumbs }) : null;
11348
10804
  const columnClass = (pad2) => cn("w-full", paddingClasses[pad2], centered && "mx-auto");
11349
10805
  const columnStyle = { maxWidth: maxWidthValue, containerType: "inline-size" };
11350
- const header = /* @__PURE__ */ jsx(PageContainerContext, { value: { contentMaxWidth: maxWidthValue, placement, containedBreadcrumbs: contained, breadcrumbsInsideHeader, noBottomMargin: block, setPinnedHeight }, children: renderHeader ? renderHeader(headerEl) : headerEl });
10806
+ const header = /* @__PURE__ */ jsx(PageContainerContext, { value: { contentMaxWidth: maxWidthValue, placement, containedBreadcrumbs: contained, breadcrumbsInsideHeader, noBottomMargin: block, overlap: overlapActive, setPinnedHeight }, children: renderHeader ? renderHeader(headerEl) : headerEl });
11351
10807
  const contentPadding = floatingHeader && shell?.isMobile ? "none" : padding;
11352
- const wrapperStyle = floatingHeader || overlap ? {
10808
+ const wrapperStyle = floatingHeader || overlapActive ? {
11353
10809
  ...floatingHeader ? { paddingRight: "var(--ds-space-3)", paddingLeft: r.sidebarFloating ? 0 : "var(--ds-space-3)" } : {},
11354
- ...overlap ? { marginTop: -overlap, position: "relative", zIndex: 1 } : {}
10810
+ ...overlapActive ? { marginTop: "calc(-1 * var(--ds-overlap, 0px))", position: "relative", zIndex: 1 } : {}
11355
10811
  } : void 0;
11356
- const column = /* @__PURE__ */ jsx("div", { className: cn(columnClass(contentPadding), bottomPaddingClasses[verticalPadding ?? "default"], className), style: columnStyle, children: rest });
10812
+ const column = /* @__PURE__ */ jsx("div", { ref: columnRef, className: cn(columnClass(contentPadding), bottomPaddingClasses[vPad], className), style: { ...columnStyle, ...launcherPadding }, children: rest });
11357
10813
  return /* @__PURE__ */ jsxs("div", { ref: setRoot, "data-page-container": "", className: "w-full", children: [
11358
- placement === "block" ? /* @__PURE__ */ jsx("div", { style: floatingBlockPadding(r.navbarFloating, r.sidebarFloating, overlap > 0), children: /* @__PURE__ */ jsxs("div", { className: FLOATING_BLOCK, children: [
10814
+ placement === "block" ? /* @__PURE__ */ jsx("div", { style: floatingBlockPadding(r.navbarFloating, r.sidebarFloating, overlapActive), children: /* @__PURE__ */ jsxs("div", { className: FLOATING_BLOCK, children: [
11359
10815
  strip,
11360
10816
  colourful ? header : /* @__PURE__ */ jsx("div", { className: columnClass(padding), style: columnStyle, children: header })
11361
10817
  ] }) }) : placement === "outside" ? /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -11496,7 +10952,6 @@ var PageHeader = forwardRef(function PageHeader2({
11496
10952
  behavior: behaviorProp,
11497
10953
  intensity: intensityProp,
11498
10954
  backgroundImage,
11499
- overlapHeight,
11500
10955
  expandedContent,
11501
10956
  collapseOffset = 100,
11502
10957
  pinned = true,
@@ -11535,6 +10990,7 @@ var PageHeader = forwardRef(function PageHeader2({
11535
10990
  const hideExpandedBreadcrumbs = hideExpandedBreadcrumbsProp ?? (!!container?.containedBreadcrumbs && snapping);
11536
10991
  const containedBreadcrumbs = containedBreadcrumbsProp ?? (container?.breadcrumbsInsideHeader && breadcrumbs?.length ? /* @__PURE__ */ jsx(Breadcrumbs, { variant: "contained", itemVariant: r.breadcrumbStyle, bleed: true, contentMaxWidth, separator: bcSep, items: [...breadcrumbs, { label: title }] }) : void 0);
11537
10992
  const noBottomMargin = noBottomMarginProp ?? container?.noBottomMargin;
10993
+ const overlapActive = container?.overlap ?? false;
11538
10994
  if (behavior === "snapping") {
11539
10995
  return /* @__PURE__ */ jsx(
11540
10996
  SnappingHeader,
@@ -11554,7 +11010,7 @@ var PageHeader = forwardRef(function PageHeader2({
11554
11010
  variant,
11555
11011
  intensity,
11556
11012
  backgroundImage,
11557
- overlapHeight,
11013
+ overlapActive,
11558
11014
  tabs,
11559
11015
  breadcrumbPill: bcPill,
11560
11016
  breadcrumbSeparator: bcSep,
@@ -11608,7 +11064,7 @@ var PageHeader = forwardRef(function PageHeader2({
11608
11064
  filters,
11609
11065
  intensity,
11610
11066
  backgroundImage,
11611
- overlapHeight,
11067
+ overlapActive,
11612
11068
  contentMaxWidth,
11613
11069
  breadcrumbPill: bcPill,
11614
11070
  breadcrumbSeparator: bcSep,
@@ -11643,7 +11099,6 @@ var PageHeader = forwardRef(function PageHeader2({
11643
11099
  );
11644
11100
  }
11645
11101
  if (isFloating) {
11646
- const overlapActive = variant === "colourful" && !!overlapHeight;
11647
11102
  return /* @__PURE__ */ jsx(
11648
11103
  "div",
11649
11104
  {
@@ -11724,7 +11179,7 @@ function DefaultHeader({
11724
11179
  ] }),
11725
11180
  actions && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-2 shrink-0", children: actions })
11726
11181
  ] }),
11727
- filters && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-3 mt-ds-4", children: filters })
11182
+ filters && /* @__PURE__ */ jsx(ControlSizeContext.Provider, { value: "sm", children: /* @__PURE__ */ jsx("div", { className: "flex items-center flex-wrap gap-ds-3 mt-ds-4", children: filters }) })
11728
11183
  ] })
11729
11184
  ]
11730
11185
  }
@@ -11752,7 +11207,7 @@ function MinimalHeader({
11752
11207
  /* @__PURE__ */ jsx(TruncHeading, { as: Heading, lines: 1, className: "font-[family-name:var(--ds-font-display)] text-xl font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)]", children: title }),
11753
11208
  badge
11754
11209
  ] }),
11755
- actions && /* @__PURE__ */ jsx(ButtonSizeContext.Provider, { value: "sm", children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-2 shrink-0", children: actions }) })
11210
+ actions && /* @__PURE__ */ jsx(ControlSizeContext.Provider, { value: "sm", children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-2 shrink-0", children: actions }) })
11756
11211
  ] })
11757
11212
  ] }) });
11758
11213
  }
@@ -11767,7 +11222,7 @@ function ColourfulHeader({
11767
11222
  filters,
11768
11223
  intensity = "bold",
11769
11224
  backgroundImage,
11770
- overlapHeight,
11225
+ overlapActive,
11771
11226
  contentMaxWidth,
11772
11227
  breadcrumbPill,
11773
11228
  breadcrumbSeparator,
@@ -11785,7 +11240,7 @@ function ColourfulHeader({
11785
11240
  ref: headerRef,
11786
11241
  className: cn(
11787
11242
  "relative overflow-hidden w-full",
11788
- !isFloating && !overlapHeight && !noBottomMargin && "mb-ds-6",
11243
+ !isFloating && !overlapActive && !noBottomMargin && "mb-ds-6",
11789
11244
  isBold ? "bg-[var(--ds-accent-primary)] [background-image:var(--ds-gradient)] [background-origin:border-box]" : "bg-[var(--ds-tint-base)]",
11790
11245
  isFloating ? cn(
11791
11246
  "rounded-[var(--ds-radius-md)]",
@@ -11795,6 +11250,7 @@ function ColourfulHeader({
11795
11250
  ) : isBold ? "border-b-[2px] border-[color-mix(in_srgb,var(--ds-accent-primary)_70%,black)]" : "border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]",
11796
11251
  className
11797
11252
  ),
11253
+ style: overlapActive && !isFloating && !noBottomMargin ? { marginBottom: "var(--ds-overlap-gap, var(--ds-space-6))" } : void 0,
11798
11254
  children: [
11799
11255
  backgroundImage && /* @__PURE__ */ jsxs(Fragment, { children: [
11800
11256
  /* @__PURE__ */ jsx(
@@ -11820,7 +11276,7 @@ function ColourfulHeader({
11820
11276
  style: {
11821
11277
  maxWidth: contentMaxWidth ?? "var(--ds-bp-xl)",
11822
11278
  containerType: "inline-size",
11823
- ...overlapHeight ? { paddingBottom: `calc(var(--ds-space-6) + ${overlapHeight}px)` } : {}
11279
+ ...overlapActive ? { paddingBottom: `calc(var(--ds-space-6) + var(--ds-overlap, 0px))` } : {}
11824
11280
  },
11825
11281
  children: [
11826
11282
  hasBreadcrumbs && /* @__PURE__ */ jsx(Breadcrumbs3, { items: breadcrumbs, onLight: isBold, onTint: !isBold, pill: breadcrumbPill, separator: breadcrumbSeparator }),
@@ -11847,7 +11303,7 @@ function ColourfulHeader({
11847
11303
  ] }),
11848
11304
  actions && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-2 shrink-0", children: actions })
11849
11305
  ] }),
11850
- filters && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-3 mt-ds-4", children: filters })
11306
+ filters && /* @__PURE__ */ jsx(ControlSizeContext.Provider, { value: "sm", children: /* @__PURE__ */ jsx("div", { className: "flex items-center flex-wrap gap-ds-3 mt-ds-4", children: filters }) })
11851
11307
  ]
11852
11308
  }
11853
11309
  )
@@ -11871,7 +11327,7 @@ function SnappingHeader({
11871
11327
  variant = "default",
11872
11328
  intensity = "bold",
11873
11329
  backgroundImage,
11874
- overlapHeight,
11330
+ overlapActive,
11875
11331
  tabs,
11876
11332
  breadcrumbPill,
11877
11333
  breadcrumbSeparator,
@@ -11890,9 +11346,11 @@ function SnappingHeader({
11890
11346
  const stickyRef = useRef(null);
11891
11347
  const setStickyRef = useCallback((node) => {
11892
11348
  stickyRef.current = node;
11349
+ }, []);
11350
+ const mergedRef = headerRef ? (node) => {
11351
+ setStickyRef(node);
11893
11352
  if (typeof headerRef === "function") headerRef(node);
11894
- else if (headerRef) headerRef.current = node;
11895
- }, [headerRef]);
11353
+ } : setStickyRef;
11896
11354
  useLayoutEffect(() => {
11897
11355
  const report = container?.setPinnedHeight;
11898
11356
  if (!report) return;
@@ -11979,7 +11437,7 @@ function SnappingHeader({
11979
11437
  const headerEl = /* @__PURE__ */ jsxs(
11980
11438
  "header",
11981
11439
  {
11982
- ref: !isFloating ? setStickyRef : void 0,
11440
+ ref: !isFloating ? mergedRef : void 0,
11983
11441
  className: cn(
11984
11442
  "transition-all duration-[var(--ds-transition-speed)] ease-[var(--ds-transition-ease)]",
11985
11443
  !isFloating && pinned && collapsed && cn("sticky", stickyTop, "z-[calc(var(--ds-z-sticky,40)-1)]"),
@@ -11991,12 +11449,13 @@ function SnappingHeader({
11991
11449
  isBoldColourful ? "border-[color-mix(in_srgb,var(--ds-accent-primary)_70%,black)] bg-[var(--ds-accent-primary)] [background-image:var(--ds-gradient)] [background-origin:border-box]" : cn("border-[var(--ds-border-subtle)] bg-[var(--ds-tint-base)]", GLASS_SURFACE)
11992
11450
  ] : [
11993
11451
  "relative overflow-hidden",
11994
- !overlapHeight && !wrapperHasCard && "mb-ds-6",
11452
+ !overlapActive && !wrapperHasCard && "mb-ds-6",
11995
11453
  isBoldColourful ? "bg-[var(--ds-accent-primary)] [background-image:var(--ds-gradient)] [background-origin:border-box] border-b-[2px] border-[color-mix(in_srgb,var(--ds-accent-primary)_70%,black)]" : "bg-[var(--ds-tint-base)] border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]"
11996
11454
  ]),
11997
11455
  !collapsed && !isColourful && isFloating && !wrapperHasCard && FLOATING_HEADER,
11998
11456
  className
11999
11457
  ),
11458
+ style: !collapsed && isColourful && overlapActive && !(isFloating && !wrapperHasCard) && !wrapperHasCard ? { marginBottom: "var(--ds-overlap-gap, var(--ds-space-6))" } : void 0,
12000
11459
  children: [
12001
11460
  !collapsed && isColourful && backgroundImage && /* @__PURE__ */ jsxs(Fragment, { children: [
12002
11461
  /* @__PURE__ */ jsx(
@@ -12021,9 +11480,9 @@ function SnappingHeader({
12021
11480
  /* @__PURE__ */ jsx(TruncHeading, { as: Heading, className: "font-[family-name:var(--ds-font-display)] text-xl font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)]", children: title }),
12022
11481
  badge
12023
11482
  ] }),
12024
- actions && /* @__PURE__ */ jsx(ButtonSizeContext.Provider, { value: "sm", children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-2 shrink-0", children: actions }) })
11483
+ actions && /* @__PURE__ */ jsx(ControlSizeContext.Provider, { value: "sm", children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-2 shrink-0", children: actions }) })
12025
11484
  ] }),
12026
- filters && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-3 mt-ds-3", children: filters }),
11485
+ filters && /* @__PURE__ */ jsx(ControlSizeContext.Provider, { value: "sm", children: /* @__PURE__ */ jsx("div", { className: "flex items-center flex-wrap gap-ds-3 mt-ds-3", children: filters }) }),
12027
11486
  expandedContent && /* @__PURE__ */ jsx("div", { className: "mt-ds-3", children: expandedContent }),
12028
11487
  tabs && /* @__PURE__ */ jsx("div", { className: "mt-ds-3 -mx-ds-1", children: tabs })
12029
11488
  ] }) : /* @__PURE__ */ jsxs(
@@ -12033,11 +11492,11 @@ function SnappingHeader({
12033
11492
  "transition-all duration-[var(--ds-transition-speed)] ease-[var(--ds-transition-ease)]",
12034
11493
  isColourful && !collapsed && "relative z-10",
12035
11494
  collapsed ? cn("flex items-center justify-between gap-ds-4 py-ds-2", !effectiveMaxWidth && "px-ds-4") : [
12036
- (!isColourful || !overlapHeight) && "pb-ds-6",
11495
+ (!isColourful || !overlapActive) && "pb-ds-6",
12037
11496
  hasBreadcrumbs && !hideExpandedBreadcrumbs ? "pt-ds-3" : "pt-ds-6"
12038
11497
  ]
12039
11498
  ),
12040
- style: !collapsed && isColourful && overlapHeight ? { paddingBottom: `calc(var(--ds-space-6) + ${overlapHeight}px)` } : void 0,
11499
+ style: !collapsed && isColourful && overlapActive ? { paddingBottom: `calc(var(--ds-space-6) + var(--ds-overlap, 0px))` } : void 0,
12041
11500
  children: [
12042
11501
  !collapsed && hasBreadcrumbs && !hideExpandedBreadcrumbs && /* @__PURE__ */ jsx(Breadcrumbs3, { items: breadcrumbs, onLight, onTint, pill: breadcrumbPill, separator: breadcrumbSeparator }),
12043
11502
  /* @__PURE__ */ jsxs("div", { className: cn(
@@ -12088,9 +11547,9 @@ function SnappingHeader({
12088
11547
  ), children: description })
12089
11548
  ] })
12090
11549
  ] }),
12091
- actions && (collapsed ? /* @__PURE__ */ jsx(ButtonSizeContext.Provider, { value: "sm", children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-2 shrink-0", children: actions }) }) : /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-2 shrink-0", children: actions }))
11550
+ actions && (collapsed ? /* @__PURE__ */ jsx(ControlSizeContext.Provider, { value: "sm", children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-2 shrink-0", children: actions }) }) : /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-2 shrink-0", children: actions }))
12092
11551
  ] }),
12093
- !collapsed && filters && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-3 mt-ds-4", children: filters }),
11552
+ !collapsed && filters && /* @__PURE__ */ jsx(ControlSizeContext.Provider, { value: "sm", children: /* @__PURE__ */ jsx("div", { className: "flex items-center flex-wrap gap-ds-3 mt-ds-4", children: filters }) }),
12094
11553
  !collapsed && expandedContent && /* @__PURE__ */ jsx("div", { className: "mt-ds-4", children: expandedContent }),
12095
11554
  !collapsed && tabs && /* @__PURE__ */ jsx("div", { className: "mt-ds-4 -mx-ds-1", children: tabs })
12096
11555
  ]
@@ -12105,7 +11564,6 @@ function SnappingHeader({
12105
11564
  }
12106
11565
  );
12107
11566
  if (isFloating) {
12108
- const overlapActive = !collapsed && isColourful && !!overlapHeight;
12109
11567
  const floatingStyle = collapsed ? {
12110
11568
  paddingTop: navbarFloating ? 0 : "var(--ds-space-3)",
12111
11569
  paddingRight: "var(--ds-space-3)",
@@ -12117,7 +11575,7 @@ function SnappingHeader({
12117
11575
  /* @__PURE__ */ jsx(
12118
11576
  "div",
12119
11577
  {
12120
- ref: setStickyRef,
11578
+ ref: mergedRef,
12121
11579
  className: cn(
12122
11580
  pinned && collapsed && "sticky z-[calc(var(--ds-z-sticky,40)-1)]",
12123
11581
  pinned && collapsed && "top-0"
@@ -12324,205 +11782,6 @@ function Dock({
12324
11782
  }
12325
11783
  );
12326
11784
  }
12327
- function resolveNavItemType(type) {
12328
- return type === "default" ? "tint" : type;
12329
- }
12330
- var NavbarTypeContext = createContext("tint");
12331
- var NavItem = forwardRef(function NavItem2({ label, icon, active = false, href, onClick, type: typeProp, className, children }, ref) {
12332
- const contextType = useContext(NavbarTypeContext);
12333
- const type = resolveNavItemType(typeProp ?? contextType);
12334
- const baseClasses = cn(
12335
- "inline-flex items-center gap-ds-2 cursor-pointer select-none",
12336
- "transition-colors duration-[var(--ds-transition-speed)] ease-[var(--ds-transition-ease)]",
12337
- "focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]",
12338
- "text-[length:var(--ds-font-size-sm)]"
12339
- );
12340
- const typeClasses = getTypeClasses(type, active);
12341
- return /* @__PURE__ */ jsxs(
12342
- "a",
12343
- {
12344
- ref,
12345
- href: href ?? "#",
12346
- onClick,
12347
- "aria-current": active ? "page" : void 0,
12348
- className: cn(baseClasses, typeClasses, className),
12349
- children: [
12350
- icon && /* @__PURE__ */ jsx(Icon, { name: icon, size: 16 }),
12351
- children ?? label,
12352
- type === "underline" && active && /* @__PURE__ */ jsx(
12353
- "span",
12354
- {
12355
- className: "absolute bottom-0 left-ds-1 right-ds-1 rounded-t-full bg-[var(--ds-accent-primary)]",
12356
- style: { height: "2px" }
12357
- }
12358
- )
12359
- ]
12360
- }
12361
- );
12362
- });
12363
- function getTypeClasses(type, active) {
12364
- switch (type) {
12365
- case "pill":
12366
- return cn(
12367
- "px-ds-2 py-ds-1 rounded-[var(--ds-radius-sm)]",
12368
- active ? "bg-[var(--ds-accent-primary)] text-[var(--ds-text-on-primary)] font-[var(--ds-weight-heading)]" : "text-[var(--ds-text-secondary)] hover:text-[var(--ds-text-primary)] hover:bg-[var(--ds-bg-muted)]"
12369
- );
12370
- case "underline":
12371
- return cn(
12372
- "px-ds-2 py-ds-2 relative",
12373
- active ? "text-[var(--ds-text-primary)] font-[var(--ds-weight-heading)]" : "text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)]"
12374
- );
12375
- case "minimal":
12376
- return cn(
12377
- "px-ds-2 py-ds-1",
12378
- active ? "text-[var(--ds-accent-primary)] font-medium" : "text-[var(--ds-text-muted)] hover:text-[var(--ds-text-secondary)]"
12379
- );
12380
- case "tint":
12381
- return cn(
12382
- "px-ds-2 py-ds-1 rounded-[var(--ds-radius-sm)]",
12383
- active ? "bg-[var(--ds-accent-subtle)] text-[var(--ds-accent-primary)] font-[var(--ds-weight-heading)]" : "text-[var(--ds-text-secondary)] hover:text-[var(--ds-text-primary)] hover:bg-[var(--ds-bg-muted)]"
12384
- );
12385
- }
12386
- }
12387
- function HamburgerButton({ onClick, open, className: cls }) {
12388
- return /* @__PURE__ */ jsx(
12389
- "button",
12390
- {
12391
- onClick,
12392
- "aria-label": open ? "Close navigation menu" : "Open navigation menu",
12393
- "aria-expanded": open ?? void 0,
12394
- className: cn(
12395
- "flex items-center justify-center shrink-0",
12396
- "w-10 h-10 rounded-[var(--ds-radius-md)]",
12397
- "text-[var(--ds-text-secondary)] hover:text-[var(--ds-text-primary)]",
12398
- "hover:bg-[var(--ds-bg-muted)] transition-colors",
12399
- "focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]",
12400
- "cursor-pointer",
12401
- cls
12402
- ),
12403
- children: /* @__PURE__ */ jsx(Icon, { name: open ? "close" : "menu", size: 20 })
12404
- }
12405
- );
12406
- }
12407
- var Navbar = forwardRef(function Navbar2({
12408
- logo,
12409
- navLinks,
12410
- search,
12411
- actions,
12412
- userMenu,
12413
- variant = "default",
12414
- type: typeProp = "tint",
12415
- align = "left",
12416
- size,
12417
- position = "flush",
12418
- bordered,
12419
- sticky = true,
12420
- className,
12421
- onMenuClick
12422
- }, ref) {
12423
- const appShell = useAppShell();
12424
- useLayoutEffect(() => appShell?.registerChrome("navbar", position), [appShell?.registerChrome, position]);
12425
- const isSmallPhone = appShell?.isMobile && !appShell.isTablet;
12426
- const showHamburger = appShell?.isMobile && appShell.hasMobileMenu && !(isSmallPhone && appShell.hasMobileNav) || !!onMenuClick;
12427
- const handleHamburger = () => onMenuClick ? onMenuClick() : appShell?.setSidebarOpen(!appShell.sidebarOpen);
12428
- const hideNavLinks = appShell?.isMobile && (appShell.hasMobileMenu || appShell.hasMobileNav);
12429
- const type = resolveNavItemType(typeProp);
12430
- const isMinimal = type === "minimal";
12431
- const isFloating = position === "floating";
12432
- const resolvedSize = size ?? (variant === "compact" ? "sm" : "md");
12433
- const heightClass = resolvedSize === "sm" ? "min-h-[var(--ds-navbar-height-compact)]" : resolvedSize === "lg" ? "min-h-[var(--ds-size-14,3.5rem)]" : "min-h-[var(--ds-navbar-height)]";
12434
- const hasBorder = bordered ?? (!isFloating && variant !== "transparent" && !isMinimal);
12435
- const bgClasses = isMinimal ? "bg-transparent" : variant === "transparent" ? "bg-transparent" : variant === "elevated" ? cn(
12436
- "bg-[var(--ds-bg-surface)]",
12437
- "text-[var(--ds-text-primary)]",
12438
- "shadow-[var(--ds-shadow-elevated)]",
12439
- hasBorder && "border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]"
12440
- ) : variant === "blurred" ? cn(
12441
- "bg-[var(--ds-bg-canvas)]/80 [backdrop-filter:var(--ds-glass-filter)] [-webkit-backdrop-filter:var(--ds-glass-filter)]",
12442
- "text-[var(--ds-text-primary)]",
12443
- hasBorder && "border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]"
12444
- ) : cn(
12445
- "bg-[var(--ds-bg-surface)]",
12446
- "text-[var(--ds-text-primary)]",
12447
- hasBorder && "border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]",
12448
- GLASS_BACKDROP
12449
- );
12450
- const isMobile = appShell?.isMobile;
12451
- const padStyle = resolvedSize === "sm" ? "var(--ds-space-2) var(--ds-space-4)" : resolvedSize === "lg" ? `var(--ds-space-2) var(${isMobile ? "--ds-space-3" : "--ds-space-6"})` : `var(--ds-space-1) var(${isMobile ? "--ds-space-3" : "--ds-space-6"})`;
12452
- const floatingClasses = isFloating ? cn("rounded-[var(--ds-radius-md)] border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]", GLASS_SURFACE) : void 0;
12453
- let headerEl;
12454
- if (align === "center") {
12455
- headerEl = /* @__PURE__ */ jsxs(
12456
- "header",
12457
- {
12458
- ref: isFloating ? void 0 : ref,
12459
- className: cn(
12460
- "shrink-0 grid grid-cols-[1fr_auto_1fr] items-center z-[var(--ds-z-sticky)]",
12461
- !isFloating && sticky && "sticky top-0",
12462
- bgClasses,
12463
- heightClass,
12464
- floatingClasses,
12465
- !isFloating && className
12466
- ),
12467
- style: { padding: padStyle, gap: "var(--ds-space-4)" },
12468
- children: [
12469
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-4", children: [
12470
- showHamburger && /* @__PURE__ */ jsx(HamburgerButton, { onClick: handleHamburger, open: appShell?.sidebarOpen }),
12471
- logo && /* @__PURE__ */ jsx("div", { className: "flex items-center shrink-0", children: logo })
12472
- ] }),
12473
- navLinks && !hideNavLinks ? /* @__PURE__ */ jsx(NavbarTypeContext.Provider, { value: type, children: /* @__PURE__ */ jsx("nav", { className: "flex items-center gap-ds-2 min-w-0 overflow-x-clip justify-center", "data-navbar-type": type, children: navLinks }) }) : /* @__PURE__ */ jsx("div", {}),
12474
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-4 justify-end", children: [
12475
- search && /* @__PURE__ */ jsx("div", { className: "flex items-center shrink-0", children: search }),
12476
- actions && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-2 shrink-0", children: actions }),
12477
- userMenu && /* @__PURE__ */ jsx("div", { className: cn("flex items-center", resolvedSize === "sm" ? "min-w-0 max-w-[180px]" : "shrink-0"), children: userMenu })
12478
- ] })
12479
- ]
12480
- }
12481
- );
12482
- } else {
12483
- headerEl = /* @__PURE__ */ jsxs(
12484
- "header",
12485
- {
12486
- ref: isFloating ? void 0 : ref,
12487
- className: cn(
12488
- "shrink-0 flex items-center z-[var(--ds-z-sticky)]",
12489
- !isFloating && sticky && "sticky top-0",
12490
- bgClasses,
12491
- heightClass,
12492
- floatingClasses,
12493
- !isFloating && className
12494
- ),
12495
- style: { padding: padStyle, gap: "var(--ds-space-4)" },
12496
- children: [
12497
- showHamburger && /* @__PURE__ */ jsx(HamburgerButton, { onClick: handleHamburger, open: appShell?.sidebarOpen }),
12498
- logo && /* @__PURE__ */ jsx("div", { className: "flex items-center shrink-0", children: logo }),
12499
- align === "right" && /* @__PURE__ */ jsx("div", { className: "flex-1" }),
12500
- navLinks && !hideNavLinks && /* @__PURE__ */ jsx(NavbarTypeContext.Provider, { value: type, children: /* @__PURE__ */ jsx("nav", { className: cn("flex items-center gap-ds-2 min-w-0 overflow-x-clip", align === "left" && "flex-1"), "data-navbar-type": type, children: navLinks }) }),
12501
- (!navLinks || hideNavLinks) && /* @__PURE__ */ jsx("div", { className: "flex-1" }),
12502
- search && /* @__PURE__ */ jsx("div", { className: "flex items-center shrink-0", children: search }),
12503
- actions && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-2 shrink-0", children: actions }),
12504
- userMenu && /* @__PURE__ */ jsx("div", { className: cn("flex items-center", resolvedSize === "sm" ? "min-w-0 max-w-[180px]" : "shrink-0"), children: userMenu })
12505
- ]
12506
- }
12507
- );
12508
- }
12509
- if (isFloating) {
12510
- return /* @__PURE__ */ jsx(
12511
- "div",
12512
- {
12513
- ref,
12514
- className: cn(
12515
- "shrink-0 z-[var(--ds-z-sticky)]",
12516
- sticky && "sticky top-0",
12517
- className
12518
- ),
12519
- style: { padding: "var(--ds-space-3)" },
12520
- children: headerEl
12521
- }
12522
- );
12523
- }
12524
- return headerEl;
12525
- });
12526
11785
  function TruncSpan({ children, className }) {
12527
11786
  const { ref, isTruncated } = useTextOverflow({ lines: 1 });
12528
11787
  const el = /* @__PURE__ */ jsx("span", { ref, className: cn("truncate", className), children });
@@ -12632,6 +11891,7 @@ function NavMenu({
12632
11891
  {
12633
11892
  ref: panelRef,
12634
11893
  role: "menu",
11894
+ "data-gs": "menu",
12635
11895
  className: cn(
12636
11896
  "fixed z-[var(--ds-z-popover)] py-ds-1.5",
12637
11897
  "bg-[var(--ds-bg-surface)] rounded-[var(--ds-radius-md)]",
@@ -12732,6 +11992,286 @@ function NavMenuGroup({
12732
11992
  ))
12733
11993
  ] });
12734
11994
  }
11995
+ function resolveNavItemType(type) {
11996
+ return type === "default" ? "tint" : type;
11997
+ }
11998
+ var NavbarTypeContext = createContext("tint");
11999
+ var NavItem = forwardRef(function NavItem2({ label, icon, active = false, href, onClick, type: typeProp, className, children }, ref) {
12000
+ const contextType = useContext(NavbarTypeContext);
12001
+ const type = resolveNavItemType(typeProp ?? contextType);
12002
+ const baseClasses = cn(
12003
+ "inline-flex items-center gap-ds-2 cursor-pointer select-none whitespace-nowrap",
12004
+ // one line: the navbar measures each link (round 12)
12005
+ "transition-colors duration-[var(--ds-transition-speed)] ease-[var(--ds-transition-ease)]",
12006
+ "focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]",
12007
+ "text-[length:var(--ds-font-size-sm)]"
12008
+ );
12009
+ const typeClasses = getTypeClasses(type, active);
12010
+ return /* @__PURE__ */ jsxs(
12011
+ "a",
12012
+ {
12013
+ ref,
12014
+ href: href ?? "#",
12015
+ onClick,
12016
+ "aria-current": active ? "page" : void 0,
12017
+ className: cn(baseClasses, typeClasses, className),
12018
+ children: [
12019
+ icon && /* @__PURE__ */ jsx(Icon, { name: icon, size: 16 }),
12020
+ children ?? label,
12021
+ type === "underline" && active && /* @__PURE__ */ jsx(
12022
+ "span",
12023
+ {
12024
+ className: "absolute bottom-0 left-ds-1 right-ds-1 rounded-t-full bg-[var(--ds-accent-primary)]",
12025
+ style: { height: "2px" }
12026
+ }
12027
+ )
12028
+ ]
12029
+ }
12030
+ );
12031
+ });
12032
+ function getTypeClasses(type, active) {
12033
+ switch (type) {
12034
+ case "pill":
12035
+ return cn(
12036
+ "px-ds-2 py-ds-1 rounded-[var(--ds-radius-sm)]",
12037
+ active ? "bg-[var(--ds-accent-primary)] text-[var(--ds-text-on-primary)] font-[var(--ds-weight-heading)]" : "text-[var(--ds-text-secondary)] hover:text-[var(--ds-text-primary)] hover:bg-[var(--ds-bg-muted)]"
12038
+ );
12039
+ case "underline":
12040
+ return cn(
12041
+ "px-ds-2 py-ds-2 relative",
12042
+ active ? "text-[var(--ds-text-primary)] font-[var(--ds-weight-heading)]" : "text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)]"
12043
+ );
12044
+ case "minimal":
12045
+ return cn(
12046
+ "px-ds-2 py-ds-1",
12047
+ active ? "text-[var(--ds-accent-primary)] font-medium" : "text-[var(--ds-text-muted)] hover:text-[var(--ds-text-secondary)]"
12048
+ );
12049
+ case "tint":
12050
+ return cn(
12051
+ "px-ds-2 py-ds-1 rounded-[var(--ds-radius-sm)]",
12052
+ active ? "bg-[var(--ds-accent-subtle)] text-[var(--ds-accent-primary)] font-[var(--ds-weight-heading)]" : "text-[var(--ds-text-secondary)] hover:text-[var(--ds-text-primary)] hover:bg-[var(--ds-bg-muted)]"
12053
+ );
12054
+ }
12055
+ }
12056
+ function HamburgerButton({ onClick, open, className: cls }) {
12057
+ return /* @__PURE__ */ jsx(
12058
+ "button",
12059
+ {
12060
+ onClick,
12061
+ "aria-label": open ? "Close navigation menu" : "Open navigation menu",
12062
+ "aria-expanded": open ?? void 0,
12063
+ className: cn(
12064
+ "flex items-center justify-center shrink-0",
12065
+ "w-10 h-10 rounded-[var(--ds-radius-md)]",
12066
+ "text-[var(--ds-text-secondary)] hover:text-[var(--ds-text-primary)]",
12067
+ "hover:bg-[var(--ds-bg-muted)] transition-colors",
12068
+ "focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]",
12069
+ "cursor-pointer",
12070
+ cls
12071
+ ),
12072
+ children: /* @__PURE__ */ jsx(Icon, { name: open ? "close" : "menu", size: 20 })
12073
+ }
12074
+ );
12075
+ }
12076
+ function flattenLinks(node) {
12077
+ const out = [];
12078
+ Children.forEach(node, (child) => {
12079
+ if (!isValidElement(child)) return;
12080
+ if (child.type === Fragment$1) out.push(...flattenLinks(child.props.children));
12081
+ else out.push(child);
12082
+ });
12083
+ return out;
12084
+ }
12085
+ var Navbar = forwardRef(function Navbar2({
12086
+ logo,
12087
+ navLinks,
12088
+ search,
12089
+ actions,
12090
+ userMenu,
12091
+ variant = "default",
12092
+ type: typeProp = "tint",
12093
+ align = "left",
12094
+ size,
12095
+ position = "flush",
12096
+ bordered,
12097
+ sticky = true,
12098
+ className,
12099
+ onMenuClick
12100
+ }, ref) {
12101
+ const appShell = useAppShell();
12102
+ useLayoutEffect(() => appShell?.registerChrome("navbar", position), [appShell?.registerChrome, position]);
12103
+ const isSmallPhone = appShell?.isMobile && !appShell.isTablet;
12104
+ const headerRef = useRef(null);
12105
+ const navRef = useRef(null);
12106
+ const widthsRef = useRef([]);
12107
+ const moreWidthRef = useRef(88);
12108
+ const [visibleCount, setVisibleCount] = useState(null);
12109
+ const links = useMemo(() => flattenLinks(navLinks), [navLinks]);
12110
+ const mobileHidesLinks = !!appShell?.isMobile && (appShell.hasMobileMenu || appShell.hasMobileNav);
12111
+ useEffect(() => {
12112
+ const header = headerRef.current;
12113
+ if (!header || mobileHidesLinks || links.length === 0 || typeof ResizeObserver === "undefined") return;
12114
+ const measure = () => {
12115
+ const nav = navRef.current;
12116
+ if (!nav) return;
12117
+ const items = Array.from(nav.children);
12118
+ for (let i = 0; i < links.length; i++) {
12119
+ const el = items[i];
12120
+ if (el && !el.hasAttribute("hidden") && el.offsetWidth) widthsRef.current[i] = el.offsetWidth;
12121
+ }
12122
+ const more = nav.querySelector("[data-navbar-more]");
12123
+ if (more?.offsetWidth) moreWidthRef.current = more.offsetWidth;
12124
+ const widths = widthsRef.current;
12125
+ if (widths.length < links.length || widths.some((w) => !w)) return;
12126
+ const style = getComputedStyle(header);
12127
+ const gap = parseFloat(style.columnGap) || parseFloat(style.gap) || 0;
12128
+ const kids = Array.from(header.children).filter((el) => el !== nav && !el.hasAttribute("data-navbar-spacer"));
12129
+ const used = kids.reduce((w, el) => w + Math.max(el.offsetWidth, el.scrollWidth), 0);
12130
+ const available = header.clientWidth - (parseFloat(style.paddingLeft) || 0) - (parseFloat(style.paddingRight) || 0) - used - gap * kids.length;
12131
+ const linkGap = parseFloat(getComputedStyle(nav).columnGap) || 8;
12132
+ const total = widths.reduce((a, w) => a + w, 0) + linkGap * (links.length - 1);
12133
+ if (total <= available) {
12134
+ setVisibleCount(null);
12135
+ return;
12136
+ }
12137
+ const room = available - moreWidthRef.current - linkGap;
12138
+ let n = 0, acc = 0;
12139
+ for (const w of widths) {
12140
+ const next = acc + (n ? linkGap : 0) + w;
12141
+ if (next > room) break;
12142
+ acc = next;
12143
+ n++;
12144
+ }
12145
+ setVisibleCount(n);
12146
+ };
12147
+ const ro = new ResizeObserver(measure);
12148
+ ro.observe(header);
12149
+ return () => ro.disconnect();
12150
+ }, [mobileHidesLinks, links]);
12151
+ const hidden = useMemo(() => {
12152
+ if (visibleCount === null || links.length === 0) return /* @__PURE__ */ new Set();
12153
+ return new Set(links.map((_, i) => i).filter((i) => i >= visibleCount));
12154
+ }, [visibleCount, links]);
12155
+ const showHamburger = appShell?.isMobile && appShell.hasMobileMenu && !(isSmallPhone && appShell.hasMobileNav) || !!onMenuClick;
12156
+ const handleHamburger = () => onMenuClick ? onMenuClick() : appShell?.setSidebarOpen(!appShell.sidebarOpen);
12157
+ const hideNavLinks = mobileHidesLinks;
12158
+ const type = resolveNavItemType(typeProp);
12159
+ const isMinimal = type === "minimal";
12160
+ const isFloating = position === "floating";
12161
+ const moreItems = links.filter((_, i) => hidden.has(i)).map((el) => {
12162
+ const p = el.props;
12163
+ return { label: p.label ?? "", href: p.href, active: p.active, icon: p.icon };
12164
+ });
12165
+ const linkRow = links.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
12166
+ links.map((el, i) => hidden.has(i) ? /* @__PURE__ */ jsx("span", { hidden: true, children: el }, el.key ?? i) : el),
12167
+ hidden.size > 0 && /* @__PURE__ */ jsx("div", { "data-navbar-more": "", className: "shrink-0", children: /* @__PURE__ */ jsx(
12168
+ NavMenu,
12169
+ {
12170
+ label: "More",
12171
+ items: moreItems,
12172
+ active: moreItems.some((m) => m.active),
12173
+ type,
12174
+ onItemClick: (item) => {
12175
+ const el = links.find((l) => l.props.label === item.label);
12176
+ el?.props?.onClick?.({});
12177
+ }
12178
+ }
12179
+ ) })
12180
+ ] }) : navLinks;
12181
+ const resolvedSize = size ?? (variant === "compact" ? "sm" : "md");
12182
+ const heightClass = resolvedSize === "sm" ? "min-h-[var(--ds-navbar-height-compact)]" : resolvedSize === "lg" ? "min-h-[var(--ds-size-14,3.5rem)]" : "min-h-[var(--ds-navbar-height)]";
12183
+ const hasBorder = bordered ?? (!isFloating && variant !== "transparent" && !isMinimal);
12184
+ const bgClasses = isMinimal ? "bg-transparent" : variant === "transparent" ? "bg-transparent" : variant === "elevated" ? cn(
12185
+ "bg-[var(--ds-bg-surface)]",
12186
+ "text-[var(--ds-text-primary)]",
12187
+ "shadow-[var(--ds-shadow-elevated)]",
12188
+ hasBorder && "border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]"
12189
+ ) : variant === "blurred" ? cn(
12190
+ "bg-[var(--ds-bg-canvas)]/80 [backdrop-filter:var(--ds-glass-filter)] [-webkit-backdrop-filter:var(--ds-glass-filter)]",
12191
+ "text-[var(--ds-text-primary)]",
12192
+ hasBorder && "border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]"
12193
+ ) : cn(
12194
+ "bg-[var(--ds-bg-surface)]",
12195
+ "text-[var(--ds-text-primary)]",
12196
+ hasBorder && "border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]",
12197
+ GLASS_BACKDROP
12198
+ );
12199
+ const isMobile = appShell?.isMobile;
12200
+ const padStyle = resolvedSize === "sm" ? "var(--ds-space-2) var(--ds-space-4)" : resolvedSize === "lg" ? `var(--ds-space-2) var(${isMobile ? "--ds-space-3" : "--ds-space-6"})` : `var(--ds-space-1) var(${isMobile ? "--ds-space-3" : "--ds-space-6"})`;
12201
+ const floatingClasses = isFloating ? cn("rounded-[var(--ds-radius-md)] border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]", GLASS_SURFACE) : void 0;
12202
+ let headerEl;
12203
+ if (align === "center") {
12204
+ headerEl = /* @__PURE__ */ jsxs(
12205
+ "header",
12206
+ {
12207
+ ref: mergeRefs(isFloating ? void 0 : ref, headerRef),
12208
+ className: cn(
12209
+ "shrink-0 grid grid-cols-[1fr_auto_1fr] items-center z-[var(--ds-z-sticky)]",
12210
+ !isFloating && sticky && "sticky top-0",
12211
+ bgClasses,
12212
+ heightClass,
12213
+ floatingClasses,
12214
+ !isFloating && className
12215
+ ),
12216
+ style: { padding: padStyle, gap: "var(--ds-space-4)" },
12217
+ children: [
12218
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-4 min-w-max", children: [
12219
+ showHamburger && /* @__PURE__ */ jsx(HamburgerButton, { onClick: handleHamburger, open: appShell?.sidebarOpen }),
12220
+ logo && /* @__PURE__ */ jsx("div", { className: "flex items-center shrink-0 whitespace-nowrap", children: logo })
12221
+ ] }),
12222
+ navLinks && !hideNavLinks ? /* @__PURE__ */ jsx(NavbarTypeContext.Provider, { value: type, children: /* @__PURE__ */ jsx("nav", { ref: navRef, className: "flex items-center gap-ds-2 min-w-0 overflow-x-clip justify-center", "data-navbar-type": type, children: linkRow }) }) : /* @__PURE__ */ jsx("div", { "data-navbar-spacer": "" }),
12223
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-4 justify-end", children: [
12224
+ search && /* @__PURE__ */ jsx("div", { className: "flex items-center shrink-0", children: search }),
12225
+ actions && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-2 shrink-0", children: actions }),
12226
+ userMenu && /* @__PURE__ */ jsx("div", { className: cn("flex items-center", resolvedSize === "sm" ? "min-w-0 max-w-[180px]" : "shrink-0"), children: userMenu })
12227
+ ] })
12228
+ ]
12229
+ }
12230
+ );
12231
+ } else {
12232
+ headerEl = /* @__PURE__ */ jsxs(
12233
+ "header",
12234
+ {
12235
+ ref: mergeRefs(isFloating ? void 0 : ref, headerRef),
12236
+ className: cn(
12237
+ "shrink-0 flex items-center z-[var(--ds-z-sticky)]",
12238
+ !isFloating && sticky && "sticky top-0",
12239
+ bgClasses,
12240
+ heightClass,
12241
+ floatingClasses,
12242
+ !isFloating && className
12243
+ ),
12244
+ style: { padding: padStyle, gap: "var(--ds-space-4)" },
12245
+ children: [
12246
+ showHamburger && /* @__PURE__ */ jsx(HamburgerButton, { onClick: handleHamburger, open: appShell?.sidebarOpen }),
12247
+ logo && /* @__PURE__ */ jsx("div", { className: "flex items-center shrink-0 whitespace-nowrap", children: logo }),
12248
+ align === "right" && /* @__PURE__ */ jsx("div", { "data-navbar-spacer": "", className: "flex-1" }),
12249
+ navLinks && !hideNavLinks && /* @__PURE__ */ jsx(NavbarTypeContext.Provider, { value: type, children: /* @__PURE__ */ jsx("nav", { ref: navRef, className: cn("flex items-center gap-ds-2 min-w-0 overflow-x-clip", align === "left" && "flex-1"), "data-navbar-type": type, children: linkRow }) }),
12250
+ (!navLinks || hideNavLinks) && /* @__PURE__ */ jsx("div", { "data-navbar-spacer": "", className: "flex-1" }),
12251
+ search && /* @__PURE__ */ jsx("div", { className: "flex items-center shrink-0", children: search }),
12252
+ actions && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-2 shrink-0", children: actions }),
12253
+ userMenu && /* @__PURE__ */ jsx("div", { className: cn("flex items-center", resolvedSize === "sm" ? "min-w-0 max-w-[180px]" : "shrink-0"), children: userMenu })
12254
+ ]
12255
+ }
12256
+ );
12257
+ }
12258
+ if (isFloating) {
12259
+ return /* @__PURE__ */ jsx(
12260
+ "div",
12261
+ {
12262
+ ref,
12263
+ className: cn(
12264
+ "shrink-0 z-[var(--ds-z-sticky)]",
12265
+ sticky && "sticky top-0",
12266
+ className
12267
+ ),
12268
+ style: { padding: "var(--ds-space-3)" },
12269
+ children: headerEl
12270
+ }
12271
+ );
12272
+ }
12273
+ return headerEl;
12274
+ });
12735
12275
  function MobileHeaderMenu({ items, type = "tint", onItemClick, className }) {
12736
12276
  return /* @__PURE__ */ jsx("nav", { className: cn("flex flex-col", className), style: { padding: "var(--ds-space-4)" }, children: /* @__PURE__ */ jsx("div", { className: "flex flex-col", style: { gap: type === "underline" ? 0 : "var(--ds-space-1)" }, children: items.map((item, i) => /* @__PURE__ */ jsx(
12737
12277
  MobileMenuItem,
@@ -12919,6 +12459,7 @@ function Dialog({ open, onClose: onCloseProp, title, description, children, foot
12919
12459
  ref: dialogRef,
12920
12460
  role: alert ? "alertdialog" : "dialog",
12921
12461
  "aria-modal": "true",
12462
+ "data-gs": "dialog",
12922
12463
  "aria-labelledby": titleId,
12923
12464
  "aria-describedby": description ? descriptionId : void 0,
12924
12465
  style: { containerType: "inline-size" },
@@ -13820,7 +13361,7 @@ function getPopoverPosition(rect, placement, padding) {
13820
13361
  top = Math.max(8, Math.min(top, window.innerHeight - popH - 8));
13821
13362
  return { top, left };
13822
13363
  }
13823
- var variantStyles5 = {
13364
+ var variantStyles4 = {
13824
13365
  default: "border-[var(--ds-border-default)] bg-[var(--ds-bg-surface)]",
13825
13366
  success: "border-[var(--ds-status-success)] bg-[var(--ds-status-success-bg)]",
13826
13367
  warning: "border-[var(--ds-status-warning)] bg-[var(--ds-status-warning-bg)]",
@@ -13891,7 +13432,7 @@ function Toast({ variant = "default", message, visible, onDismiss, duration = 5e
13891
13432
  GLASS_DROPDOWN,
13892
13433
  "rounded-[var(--ds-radius-md)]",
13893
13434
  "text-sm text-[var(--ds-text-primary)]",
13894
- variantStyles5[variant]
13435
+ variantStyles4[variant]
13895
13436
  ),
13896
13437
  children: [
13897
13438
  /* @__PURE__ */ jsx(Icon, { name: icon.name, size: 18, className: cn("shrink-0", icon.className) }),
@@ -14024,30 +13565,42 @@ var SectionHeading = forwardRef(function SectionHeading2({
14024
13565
  description,
14025
13566
  actions,
14026
13567
  badge,
13568
+ count,
14027
13569
  tabs,
14028
13570
  bordered = false,
13571
+ variant = "section",
14029
13572
  className
14030
13573
  }, ref) {
13574
+ const isPhone = useBreakpoint("sm");
13575
+ const pane = variant === "pane";
14031
13576
  return /* @__PURE__ */ jsxs(
14032
13577
  "div",
14033
13578
  {
14034
13579
  ref,
13580
+ "data-variant": variant,
14035
13581
  className: cn(
14036
- bordered && "border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)] pb-ds-4",
13582
+ pane ? "shrink-0 px-ds-4 pt-ds-4 pb-ds-3 border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]" : "mb-[var(--ds-heading-gap)]",
13583
+ !pane && bordered && "border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)] pb-ds-4",
14037
13584
  className
14038
13585
  ),
14039
13586
  children: [
14040
- /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-ds-4", children: [
13587
+ /* @__PURE__ */ jsxs("div", { className: cn(
13588
+ "flex gap-ds-4",
13589
+ // the actions wrap under the title when the two do not fit on one line (round 11: a search Input in a 284 px
13590
+ // pane's actions slot squeezed "Inbox" to "I."); below sm they always stack
13591
+ isPhone && actions ? "flex-col" : "flex-wrap items-start justify-between"
13592
+ ), children: [
14041
13593
  /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
14042
13594
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-ds-2", children: [
14043
13595
  /* @__PURE__ */ jsx("h2", { className: "font-[family-name:var(--ds-font-display)] text-lg font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)] truncate", children: title }),
14044
- badge
13596
+ badge,
13597
+ count !== void 0 && /* @__PURE__ */ jsx(Badge, { variant: "neutral", size: "sm", children: count })
14045
13598
  ] }),
14046
13599
  description && /* @__PURE__ */ jsx("p", { className: "mt-ds-1 text-sm text-[var(--ds-text-secondary)] line-clamp-2", children: description })
14047
13600
  ] }),
14048
- actions && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-2 shrink-0", children: actions })
13601
+ actions && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-2 shrink-0 max-w-full", children: pane ? /* @__PURE__ */ jsx(ControlSizeContext.Provider, { value: "sm", children: actions }) : actions })
14049
13602
  ] }),
14050
- tabs && /* @__PURE__ */ jsx("div", { className: "mt-ds-3", children: tabs })
13603
+ tabs && /* @__PURE__ */ jsx("div", { className: "mt-ds-3", children: pane ? /* @__PURE__ */ jsx(ControlSizeContext.Provider, { value: "sm", children: tabs }) : tabs })
14051
13604
  ]
14052
13605
  }
14053
13606
  );
@@ -14073,7 +13626,7 @@ var ActionPanel = forwardRef(function ActionPanel2({
14073
13626
  /* @__PURE__ */ jsx("p", { id: titleId, className: "text-sm font-medium text-[var(--ds-text-primary)]", children: title }),
14074
13627
  description && /* @__PURE__ */ jsx("p", { className: "mt-ds-1 text-sm text-[var(--ds-text-secondary)]", children: description })
14075
13628
  ] }),
14076
- /* @__PURE__ */ jsx("div", { className: "shrink-0", "aria-labelledby": titleId, children: action })
13629
+ /* @__PURE__ */ jsx("div", { className: "shrink-0 w-full @sm:w-auto @max-sm:[&>*]:max-w-none", "aria-labelledby": titleId, children: action })
14077
13630
  ]
14078
13631
  }
14079
13632
  );
@@ -14146,6 +13699,6 @@ var TextOverflow = forwardRef(function TextOverflow2({
14146
13699
  return /* @__PURE__ */ jsx(Tooltip, { content: resolvedTooltipContent, children: content });
14147
13700
  });
14148
13701
 
14149
- export { Accordion, ActionPanel, ActionPanelGroup, Alert, AppShell, AsidePanel, Avatar, AvatarGroup, BottomNav, Breadcrumbs, BulkActionBar, Button, ButtonSizeContext, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, ChatMessageList, ChatPanel, Checkbox, CheckboxGroup, CheckboxGroupItem, Collapsible, ColorPicker, Combobox, CommandPalette, ContextMenu, CornerPanel, DEFAULT_DATE_RANGE_PRESETS, DataList, DatePicker, DateRangePicker, DescriptionList, Dialog, Dock, Drawer, Dropdown, DropdownMenu, EmptyState, Field, FileUpload, FormWrapper, HoverCard, InlineFieldError, Input, Kbd, Label, Launcher, MentionInput, MobileHeaderMenu, NavItem, NavMenu, Navbar, NotificationCenter, NumberInput, PageContainer, PageHeader, Pagination, PinInput, Popover, Progress, RadioGroup, Rating, ScrollArea, SectionHeading, SegmentedControl, SettingsLayout, Sheet, Sidebar, SidebarNav, SkipLink, SliderRange, Spinner, SplitView, StackedList, StatsCard, StatusDot, Stepper, Table, TableToolbar, Tabs, Tag, TagInput, TextOverflow, Textarea, TimePicker, Timeline, Toast, ToastProvider, Toggle, Tour, TransferList, TreeView, useAppShell, useFormContext, useSidebar, useToast };
13702
+ export { Accordion, ActionPanel, ActionPanelGroup, Alert, AsidePanel, Avatar, AvatarGroup, BottomNav, Breadcrumbs, BulkActionBar, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, ChatMessageList, ChatPanel, Checkbox, CheckboxGroup, CheckboxGroupItem, Collapsible, ColorPicker, Combobox, CommandPalette, ContextMenu, CornerPanel, DEFAULT_DATE_RANGE_PRESETS, DataList, DatePicker, DateRangePicker, DescriptionList, Dialog, Dock, Dropdown, DropdownMenu, EmptyState, EntityCell, Field, FileUpload, FormWrapper, HoverCard, InlineFieldError, Input, Kbd, Label, Launcher, MentionInput, MobileHeaderMenu, NavItem, NavMenu, Navbar, NotificationCenter, NumberInput, PageContainer, PageHeader, Pagination, PinInput, Popover, Progress, RadioGroup, Rating, ScrollArea, SectionHeading, SegmentedControl, SettingsLayout, Sidebar, SidebarNav, SliderRange, StackedList, StatsCard, StatusDot, Stepper, Table, TableToolbar, Tabs, Tag, TagInput, TextOverflow, Textarea, TimePicker, Timeline, Toast, ToastProvider, Toggle, Tour, TransferList, TreeView, useFormContext, useSidebar, useToast };
14150
13703
  //# sourceMappingURL=index.js.map
14151
13704
  //# sourceMappingURL=index.js.map