gridsmith-ui 0.22.0 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,21 +1,22 @@
1
- import { useAppShell, REACT_VERSION_PROBLEM, useOverlayMark, useDirtyGuard, OverlayMarkScope, OverlayCloseCtx, DiscardConfirm, OVERLAY_ROOT_ATTR, OverlayMarkCtx, DrawerFooterCtx, useCompact, useElementWidth, Sheet, useCloseSettle, Drawer, useRememberedWidth, pxOf, ResizeEdge, defaultMaxWidth } from './chunk-AAYCQXZQ.js';
2
- export { AppShell, Drawer, Sheet, SkipLink, useAppShell, useUnsavedChanges } from './chunk-AAYCQXZQ.js';
1
+ import { useAppShell, REACT_VERSION_PROBLEM, useOverlayMark, useDirtyGuard, useScrollbarInset, DrawerFooterCtx, OverlayMarkScope, OverlayCloseCtx, insetLessScrollbar, DiscardConfirm, OVERLAY_ROOT_ATTR, OverlayMarkCtx, useCompact, useElementWidth, DrawerPanel, useCloseSettle, Drawer, useRememberedWidth, pxOf, ResizeEdge, defaultMaxWidth } from './chunk-6PL7FXYH.js';
2
+ export { AppShell, Drawer, SkipLink, useAppShell, useUnsavedChanges } from './chunk-6PL7FXYH.js';
3
3
  import { Skeleton, TITLE_TEXT } from './chunk-NCIZQYXQ.js';
4
4
  export { Skeleton } from './chunk-NCIZQYXQ.js';
5
+ import { useScrollEdges, EDGE_FADE } from './chunk-3BRQRKDO.js';
5
6
  import { Link } from './chunk-EYMGLK4M.js';
6
7
  export { CodeBlock, Divider, Link } from './chunk-EYMGLK4M.js';
7
8
  import { Badge } from './chunk-SBTBMAIU.js';
8
9
  export { Badge } from './chunk-SBTBMAIU.js';
9
10
  import { inferColumnKinds, useCardsSwitch, CARDS_BELOW, kindOfRenderedText, CardValue } from './chunk-IVCVNAXG.js';
10
- import { useWholeListCheck, pagerPart, Pagination, Dropdown, useFieldControl, useField, warnOnce, Label, InlineFieldError, AddAnotherRowCtx, Input, Field } from './chunk-2RV23OBK.js';
11
- export { Dropdown, Field, InlineFieldError, Input, Label, NumberInput, Pagination, Popover, Textarea, Toggle, usePagination } from './chunk-2RV23OBK.js';
12
- import { SplitPaneCtx, TableCardCtx } from './chunk-RG4KUCRS.js';
11
+ import { useWholeListCheck, pagerPart, Pagination, CHECK_FILL, Dropdown, FilterRowContext, SWITCH_KNOB_ON, SWITCH_KNOB_OFF, SWITCH_KNOB_MOTION, SWITCH_TRACK_ON, SWITCH_TRACK_OFF, useFieldControl, useField, warnOnce, Label, InlineFieldError, AddAnotherRowCtx, Input, Field } from './chunk-ICNWPNMM.js';
12
+ export { Dropdown, Field, InlineFieldError, Input, Label, NumberInput, Pagination, Popover, Textarea, Toggle, usePagination } from './chunk-ICNWPNMM.js';
13
13
  import { Button, ControlSizeContext, triggerType, Spinner, useShellPreferences, preferenceActionKey } from './chunk-7TOJ4G7S.js';
14
14
  export { Button, ButtonSizeContext, ControlSizeContext, PreferencesContext, Spinner, preferenceActionKey, usePreferences } from './chunk-7TOJ4G7S.js';
15
15
  import { useBreakpoint, readBreakpointPx } from './chunk-CRQ6KCRD.js';
16
16
  export { BreakpointWidthProvider, useBreakpoint } from './chunk-CRQ6KCRD.js';
17
17
  import { FOCUSABLE, usePopupFocus, FIELD, ZOOM_KEYS, FormChangeCtx, useOverlayLayer, useFocusTrap, useFocusBeforeOpen, rememberFocus, focusInitial, OVERLAY_CLOSE_ATTR, useReportedChange, rovingTabStop, useGridKeyboard, useOptionalFormContext, focusAfterRemoval, FormCtx, useNonModalDialog, useReturnFocus, useCloseOnFocusOut } from './chunk-RT7RYGC3.js';
18
18
  export { useFormContext, useGridKeyboard } from './chunk-RT7RYGC3.js';
19
+ import { CardSurfaceCtx, useScrollsInside, SplitPaneCtx, SurfaceBoundary, useFramesItself, TableCardCtx } from './chunk-CKWITUSH.js';
19
20
  import { useTextOverflow, Tooltip, usePosition } from './chunk-CXMV7SXJ.js';
20
21
  export { Tooltip, useTextOverflow } from './chunk-CXMV7SXJ.js';
21
22
  import { mergeRefs, Slot } from './chunk-7Q46JXSK.js';
@@ -508,7 +509,7 @@ function Checkbox({ checked, onChange: onChangeProp, label, size = "md", disable
508
509
  "border-[2px]",
509
510
  "transition-all",
510
511
  "peer-focus-visible:shadow-[var(--ds-shadow-focus)]",
511
- filled ? "bg-[var(--ds-check-bg)] [background-image:var(--ds-gradient)] border-[var(--ds-check-border)]" : "bg-[var(--ds-input-bg)] border-[var(--ds-input-border)]",
512
+ filled ? cn(CHECK_FILL, "border-[var(--ds-check-border)]") : "bg-[var(--ds-input-bg)] border-[var(--ds-input-border)]",
512
513
  disabled && "pointer-events-none"
513
514
  ),
514
515
  children: /* @__PURE__ */ jsx(
@@ -629,7 +630,8 @@ function RadioGroup({ value, onChange: onChangeProp, options, orientation = "ver
629
630
  selected && "border-[var(--ds-check-border)]",
630
631
  "group-focus-visible:shadow-[var(--ds-shadow-focus)]"
631
632
  ),
632
- children: selected && /* @__PURE__ */ jsx("span", { className: "h-2.5 w-2.5 rounded-[var(--ds-radius-full)] bg-[var(--ds-accent-primary)] [background-image:var(--ds-gradient)]" })
633
+ children: selected && // Sprint 25.14 A20: the checked colour, as a checkbox's fill (a preset whose accent falls short of 3:1 sets it)
634
+ /* @__PURE__ */ jsx("span", { className: cn("h-2.5 w-2.5 rounded-[var(--ds-radius-full)]", CHECK_FILL) })
633
635
  }
634
636
  ),
635
637
  /* @__PURE__ */ jsx("span", { className: "text-sm text-[var(--ds-text-primary)]", children: option.label })
@@ -1991,7 +1993,7 @@ function FileUpload({ onFiles, files, upload, onCancel, onRetry, onRemove, accep
1991
1993
  // The real file input is visually hidden inside; Tab lands on it and
1992
1994
  // Enter/Space open the picker natively, so the zone shows its focus.
1993
1995
  invalid ? ERROR_HAS_FOCUS_RING : HAS_FOCUS_RING,
1994
- dragOver ? `${ACTIVE_RING} bg-[var(--ds-accent-whisper)]` : invalid ? "border-[var(--ds-status-error)]" : "border-[var(--ds-border-default)] hover:border-[var(--ds-accent-primary)] hover:bg-[var(--ds-accent-whisper)]"
1996
+ dragOver ? `${ACTIVE_RING} bg-[var(--ds-accent-whisper)]` : invalid ? "border-[var(--ds-status-error)]" : "border-[var(--ds-input-border)] hover:border-[var(--ds-accent-primary)] hover:bg-[var(--ds-accent-whisper)]"
1995
1997
  ),
1996
1998
  style: { padding: "var(--ds-space-8) var(--ds-space-4)" },
1997
1999
  children: [
@@ -2165,7 +2167,7 @@ function SliderRange({
2165
2167
  !trackStyle && /* @__PURE__ */ jsx(
2166
2168
  "div",
2167
2169
  {
2168
- className: "absolute h-1.5 rounded-[var(--ds-radius-full)] bg-[var(--ds-accent-primary)] [background-image:var(--ds-gradient)]",
2170
+ className: cn("absolute h-1.5 rounded-[var(--ds-radius-full)]", CHECK_FILL),
2169
2171
  style: {
2170
2172
  left: `${isRange ? pct(low) : 0}%`,
2171
2173
  width: `${isRange ? pct(high) - pct(low) : pct(low)}%`
@@ -2189,7 +2191,7 @@ function SliderRange({
2189
2191
  className: cn(
2190
2192
  "absolute w-ds-4 h-ds-4 -translate-x-1/2 rounded-[var(--ds-radius-full)]",
2191
2193
  "bg-[var(--ds-bg-surface)] border-2",
2192
- error ? "border-[var(--ds-status-error)]" : "border-[var(--ds-accent-primary)]",
2194
+ error ? "border-[var(--ds-status-error)]" : "border-[var(--ds-check-border)]",
2193
2195
  "shadow-[var(--ds-shadow-sm)]",
2194
2196
  "transition-[shadow,transform] duration-200 ease-out",
2195
2197
  "focus-visible:shadow-[var(--ds-shadow-focus)]",
@@ -2215,7 +2217,7 @@ function SliderRange({
2215
2217
  className: cn(
2216
2218
  "absolute w-ds-4 h-ds-4 -translate-x-1/2 rounded-[var(--ds-radius-full)]",
2217
2219
  "bg-[var(--ds-bg-surface)] border-2",
2218
- error ? "border-[var(--ds-status-error)]" : "border-[var(--ds-accent-primary)]",
2220
+ error ? "border-[var(--ds-status-error)]" : "border-[var(--ds-check-border)]",
2219
2221
  "shadow-[var(--ds-shadow-sm)]",
2220
2222
  "transition-[shadow,transform] duration-200 ease-out",
2221
2223
  "focus-visible:shadow-[var(--ds-shadow-focus)]",
@@ -2988,7 +2990,7 @@ function PinInput({
2988
2990
  role: "group",
2989
2991
  "aria-label": "PIN input",
2990
2992
  "aria-invalid": error || void 0,
2991
- className: cn("inline-flex items-center gap-ds-2", className),
2993
+ className: cn("inline-flex w-fit items-center gap-ds-2", className),
2992
2994
  children: digits.map((digit, i) => /* @__PURE__ */ jsx(
2993
2995
  "input",
2994
2996
  {
@@ -3153,7 +3155,9 @@ function Rating({
3153
3155
  "aria-required": readOnly ? void 0 : control.required || void 0,
3154
3156
  onKeyDown: readOnly ? void 0 : handleKeyDown,
3155
3157
  className: cn(
3156
- "inline-flex items-center gap-ds-0.5",
3158
+ // Sprint 25.14 A21: its own width in a Field's column, not the field's; w-fit, not self-start, so a row or a
3159
+ // centred column still aligns it (the review of 30 September)
3160
+ "inline-flex w-fit items-center gap-ds-0.5",
3157
3161
  error && "border-[length:var(--ds-border-width)] border-[var(--ds-status-error)] rounded-[var(--ds-radius-sm)] p-ds-0.5",
3158
3162
  className
3159
3163
  ),
@@ -4373,7 +4377,6 @@ function holdsHeader(children) {
4373
4377
  }
4374
4378
  var CardActionCtx = createContext(null);
4375
4379
  var CARD_ACTION_ATTR = "data-card-action";
4376
- var CardSurfaceCtx = createContext(false);
4377
4380
  var variantStyles3 = {
4378
4381
  default: `bg-[var(--ds-bg-surface)] border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)] ${GLASS_SURFACE}`,
4379
4382
  featured: [
@@ -4409,7 +4412,8 @@ function RadioIndicator({ checked, disabled }) {
4409
4412
  {
4410
4413
  className: cn(
4411
4414
  "h-2.5 w-2.5 rounded-[var(--ds-radius-full)] transition-transform duration-[var(--ds-transition-speed)]",
4412
- checked ? "bg-[var(--ds-accent-primary)] [background-image:var(--ds-gradient)] scale-100" : "scale-0"
4415
+ // Sprint 25.14 A20: the radio's selected dot (lib/control-looks.ts)
4416
+ checked ? cn(CHECK_FILL, "scale-100") : "scale-0"
4413
4417
  )
4414
4418
  }
4415
4419
  )
@@ -4427,7 +4431,8 @@ function CheckboxIndicator({ checked, indeterminate, disabled }) {
4427
4431
  "rounded-[calc(var(--ds-radius-sm)*0.6)]",
4428
4432
  "border-[2px] transition-all duration-[var(--ds-transition-speed)]",
4429
4433
  disabled && "opacity-disabled",
4430
- filled ? "bg-[var(--ds-check-bg)] [background-image:var(--ds-gradient)] border-[var(--ds-check-border)]" : "bg-[var(--ds-input-bg)] border-[var(--ds-input-border)]"
4434
+ // Sprint 25.14 A20: the checkbox's checked fill (lib/control-looks.ts)
4435
+ filled ? cn(CHECK_FILL, "border-[var(--ds-check-border)]") : "bg-[var(--ds-input-bg)] border-[var(--ds-input-border)]"
4431
4436
  ),
4432
4437
  children: /* @__PURE__ */ jsx(
4433
4438
  "svg",
@@ -4455,13 +4460,14 @@ function ToggleIndicator({ checked, disabled }) {
4455
4460
  "border-[length:var(--ds-border-width)] rounded-[var(--ds-radius-full)]",
4456
4461
  "transition-colors duration-[var(--ds-transition-speed)]",
4457
4462
  disabled && "opacity-disabled",
4458
- checked ? "bg-[var(--ds-accent-primary)] border-transparent" : "bg-[var(--ds-bg-muted)] border-[var(--ds-border-default)]"
4463
+ // Sprint 25.14 A20: the Toggle's track and knob, on and off (lib/control-looks.ts)
4464
+ checked ? SWITCH_TRACK_ON : SWITCH_TRACK_OFF
4459
4465
  ),
4460
4466
  style: { width: 44, height: 24 },
4461
4467
  children: /* @__PURE__ */ jsx(
4462
4468
  "span",
4463
4469
  {
4464
- className: "pointer-events-none inline-block shrink-0 bg-[var(--ds-bg-surface)] rounded-[var(--ds-radius-full)] transition-transform",
4470
+ className: cn("pointer-events-none inline-block shrink-0 rounded-[var(--ds-radius-full)]", checked ? SWITCH_KNOB_ON : SWITCH_KNOB_OFF, SWITCH_KNOB_MOTION),
4465
4471
  style: {
4466
4472
  width: 16,
4467
4473
  height: 16,
@@ -4647,9 +4653,9 @@ var Card = forwardRef(function Card2({
4647
4653
  ...props,
4648
4654
  children: [
4649
4655
  !loading && !hasHeader && checkbox && /* @__PURE__ */ jsxs("div", { "data-card-header-row": "", className: "flex items-center gap-ds-2 px-ds-5 pt-ds-4", children: [
4650
- checkbox,
4651
4656
  /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "grow" }),
4652
- check && /* @__PURE__ */ jsx("span", { "data-card-selection": "", className: "shrink-0 flex", children: check })
4657
+ check && /* @__PURE__ */ jsx("span", { "data-card-selection": "", className: "shrink-0 flex", children: check }),
4658
+ checkbox
4653
4659
  ] }),
4654
4660
  !loading && !hasHeader && !checkbox && check && /* @__PURE__ */ jsx("div", { "data-card-selection": "", className: "absolute top-ds-3 right-ds-3 z-[1] flex", children: check }),
4655
4661
  /* @__PURE__ */ jsx(CardSurfaceCtx, { value: true, children: /* @__PURE__ */ jsx(CardActionCtx, { value: action, children: /* @__PURE__ */ jsx(CardRowCtx, { value: rowParts, children: loading ? (
@@ -4724,7 +4730,7 @@ var CardHeader = forwardRef(function CardHeader2(allProps, ref) {
4724
4730
  }
4725
4731
  ) : null;
4726
4732
  const band = (order) => cn("shrink-0 self-start flex items-center", TITLE_LINE, order);
4727
- const checkbox = owns && row.checkbox ? /* @__PURE__ */ jsx("span", { className: band("order-0"), children: row.checkbox }) : null;
4733
+ const checkbox = owns && row.checkbox ? /* @__PURE__ */ jsx("span", { className: band("order-5"), children: row.checkbox }) : null;
4728
4734
  const check = owns && row.check ? /* @__PURE__ */ jsx("span", { "data-card-selection": "", className: band("order-4"), children: row.check }) : null;
4729
4735
  const menuPart = menu ? /* @__PURE__ */ jsx("span", { className: band("order-6"), children: menu }) : null;
4730
4736
  const { lead, title, rest } = splitTitle(children);
@@ -4734,15 +4740,14 @@ var CardHeader = forwardRef(function CardHeader2(allProps, ref) {
4734
4740
  const actionsSlot = "actions" in allProps ? /* @__PURE__ */ jsx("div", { "data-header-actions": "", className: "contents", children: partsOf(actions).map((item, i) => /* @__PURE__ */ jsx("span", { className: cn("flex items-center shrink-0", TITLE_LINE), children: item }, isValidElement(item) && item.key !== null ? item.key : i)) }) : null;
4735
4741
  return /* @__PURE__ */ jsxs("div", { ref, "data-card-header": "", className: cn("flex flex-col px-ds-5 pt-ds-4 last:pb-ds-4 min-w-0", className), ...props, children: [
4736
4742
  topLine && /* @__PURE__ */ jsxs("div", { "data-card-icon-row": iconBlock ? "" : void 0, "data-card-lead-row": iconBlock ? void 0 : "", className: cn("flex items-start gap-ds-2", iconBlock ? "mb-ds-2.5" : "mb-ds-1.5"), children: [
4737
- checkbox,
4738
4743
  topLine,
4739
4744
  iconBlock && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "grow -ml-ds-2" }),
4740
4745
  check,
4746
+ checkbox,
4741
4747
  menuPart
4742
4748
  ] }),
4743
4749
  iconBlock && leadBlock && /* @__PURE__ */ jsx("div", { className: "flex mb-ds-1.5", children: leadBlock }),
4744
4750
  /* @__PURE__ */ jsxs("div", { "data-card-header-row": "", className: "flex items-start gap-ds-2 min-w-0", children: [
4745
- !topLine && checkbox,
4746
4751
  /* @__PURE__ */ jsxs("div", { "data-card-title-line": "", className: TITLE_ROW, children: [
4747
4752
  title && /* @__PURE__ */ jsx(
4748
4753
  "div",
@@ -4756,6 +4761,7 @@ var CardHeader = forwardRef(function CardHeader2(allProps, ref) {
4756
4761
  !ownBlock && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "order-3 grow basis-0 -ml-ds-2" })
4757
4762
  ] }),
4758
4763
  !topLine && check,
4764
+ !topLine && checkbox,
4759
4765
  !topLine && menuPart
4760
4766
  ] }),
4761
4767
  rest.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-col space-y-ds-1.5 break-words mt-ds-1.5 min-w-0", children: rest })
@@ -4842,7 +4848,7 @@ var CardFooter = forwardRef(function CardFooter2({ className, children, ...props
4842
4848
  });
4843
4849
  function TruncLabel({ children }) {
4844
4850
  const { ref, isTruncated } = useTextOverflow({ lines: 1 });
4845
- const el = /* @__PURE__ */ jsx("span", { ref, className: "text-xs font-medium text-[var(--ds-text-muted)] uppercase tracking-wider truncate min-w-0", children });
4851
+ const el = /* @__PURE__ */ jsx("span", { ref, className: "block text-xs font-medium text-[var(--ds-text-muted)] uppercase tracking-wider truncate min-w-0", children });
4846
4852
  if (!isTruncated) return el;
4847
4853
  return /* @__PURE__ */ jsx(Tooltip, { content: children, children: el });
4848
4854
  }
@@ -4887,13 +4893,15 @@ function StatsCard({ value, label, trend, icon, layout = "card", interactive, on
4887
4893
  } : void 0,
4888
4894
  children: [
4889
4895
  /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-ds-2 min-w-0", children: [
4890
- /* @__PURE__ */ jsx(TruncLabel, { children: label }),
4896
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
4897
+ /* @__PURE__ */ jsx(TruncLabel, { children: label }),
4898
+ /* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-ds-2 mt-ds-2 flex-wrap", children: [
4899
+ /* @__PURE__ */ jsx("span", { className: "font-[family-name:var(--ds-font-display)] text-2xl font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)] leading-none tabular-nums", children: value }),
4900
+ trend && /* @__PURE__ */ jsx(TrendBadge, { trend })
4901
+ ] })
4902
+ ] }),
4891
4903
  icon && /* @__PURE__ */ jsx("div", { className: "shrink-0 flex items-center justify-center w-8 h-8 rounded-[var(--ds-radius-sm)] bg-[var(--ds-bg-muted)]", children: /* @__PURE__ */ jsx(Icon, { name: icon, size: 16, className: "text-[var(--ds-text-muted)]" }) })
4892
4904
  ] }),
4893
- /* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-ds-2 mt-ds-2 flex-wrap", children: [
4894
- /* @__PURE__ */ jsx("span", { className: "font-[family-name:var(--ds-font-display)] text-2xl font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)] leading-none tabular-nums", children: value }),
4895
- trend && /* @__PURE__ */ jsx(TrendBadge, { trend })
4896
- ] }),
4897
4905
  children && /* @__PURE__ */ jsx("div", { className: "mt-ds-3 text-xs text-[var(--ds-text-muted)]", children })
4898
4906
  ]
4899
4907
  }
@@ -4978,6 +4986,7 @@ function countCards(children) {
4978
4986
  return n;
4979
4987
  }
4980
4988
  function CardGrid({ minWidth, maxColumns = 4, compare = false, gap = "var(--ds-space-4)", fill: fill2 = true, className, style, children, ref, ...props }) {
4989
+ useFramesItself();
4981
4990
  const most = Math.max(1, Math.floor(maxColumns));
4982
4991
  const drawn = "var(--gs-cards, var(--gs-cards-counted))";
4983
4992
  const min = "var(--gs-card-min)";
@@ -5286,71 +5295,6 @@ function Accordion({ items, type = "single", defaultOpen = [], open: controlledO
5286
5295
  ] }, i);
5287
5296
  }) });
5288
5297
  }
5289
- var EDGE_FADE = 24;
5290
- var NONE = { left: false, right: false, vertical: false, gutterRight: 0, gutterBottom: 0 };
5291
- var same = (a, b) => a.left === b.left && a.right === b.right && a.vertical === b.vertical && a.gutterRight === b.gutterRight && a.gutterBottom === b.gutterBottom;
5292
- function useScrollEdges(options = {}) {
5293
- const { enabled = true, fade = EDGE_FADE, noFade } = options;
5294
- const elRef = useRef(null);
5295
- const observer = useRef(null);
5296
- const borders = useRef({ x: 0, y: 0 });
5297
- const [state, setState] = useState(NONE);
5298
- const measure = useCallback(() => {
5299
- const el = elRef.current;
5300
- if (!el) return;
5301
- const next = {
5302
- left: el.scrollLeft > 1,
5303
- right: el.scrollLeft + el.clientWidth < el.scrollWidth - 1,
5304
- vertical: el.scrollHeight > el.clientHeight + 1,
5305
- gutterRight: Math.max(0, el.offsetWidth - el.clientWidth - borders.current.x),
5306
- gutterBottom: Math.max(0, el.offsetHeight - el.clientHeight - borders.current.y)
5307
- };
5308
- setState((prev) => same(prev, next) ? prev : next);
5309
- }, []);
5310
- const ref = useCallback((el) => {
5311
- observer.current?.disconnect();
5312
- observer.current = null;
5313
- elRef.current = el;
5314
- if (!el || !enabled) return;
5315
- const style = getComputedStyle(el);
5316
- const px = (v) => parseFloat(v) || 0;
5317
- borders.current = { x: px(style.borderLeftWidth) + px(style.borderRightWidth), y: px(style.borderTopWidth) + px(style.borderBottomWidth) };
5318
- measure();
5319
- if (typeof ResizeObserver === "undefined") return;
5320
- const o = new ResizeObserver(measure);
5321
- o.observe(el);
5322
- for (const child of Array.from(el.children)) o.observe(child);
5323
- observer.current = o;
5324
- }, [enabled, measure]);
5325
- const fadeLeft = state.left && !noFade?.left;
5326
- const fadeRight = state.right && !noFade?.right;
5327
- const shown = enabled && (fadeLeft || fadeRight);
5328
- const { gutterRight: gr, gutterBottom: gb } = state;
5329
- const fadeLayer = `linear-gradient(to right, ${fadeLeft ? `transparent 0, black ${fade}px` : "black 0"}, ${fadeRight ? `black calc(100% - ${gr + fade}px), transparent calc(100% - ${gr}px)` : "black 100%"})`;
5330
- const gutters = [gb > 0 && { size: `100% ${gb}px`, position: "0 100%" }, gr > 0 && { size: `${gr}px 100%`, position: "100% 0" }].filter(Boolean);
5331
- const mask = shown ? {
5332
- image: [fadeLayer, ...gutters.map(() => "linear-gradient(black, black)")].join(", "),
5333
- size: ["100% 100%", ...gutters.map((g) => g.size)].join(", "),
5334
- position: ["0 0", ...gutters.map((g) => g.position)].join(", ")
5335
- } : void 0;
5336
- return {
5337
- /** The scroller's ref (a callback). */
5338
- ref,
5339
- /** The scroller itself, for code that moves it. */
5340
- elRef,
5341
- measure,
5342
- /** Content hides past a side edge: the scroller moves sideways, and its edges fade (but those in `noFade`). */
5343
- overflowing: enabled && (state.left || state.right),
5344
- /** It scrolls either way, sideways or up and down: a keyboard needs to reach it. */
5345
- scrollable: enabled && (state.left || state.right || state.vertical),
5346
- edges: { left: state.left, right: state.right },
5347
- /** For the scroller: `data-fade` names the faded edges ("left", "right" or "left right"), the style masks them. */
5348
- fadeProps: {
5349
- "data-fade": shown ? [fadeLeft && "left", fadeRight && "right"].filter(Boolean).join(" ") : void 0,
5350
- style: mask ? { maskImage: mask.image, WebkitMaskImage: mask.image, maskSize: mask.size, WebkitMaskSize: mask.size, maskPosition: mask.position, WebkitMaskPosition: mask.position, maskRepeat: "no-repeat", WebkitMaskRepeat: "no-repeat" } : void 0
5351
- }
5352
- };
5353
- }
5354
5298
  var HEADER_LAYOUT = {
5355
5299
  row: "flex flex-wrap items-start justify-between gap-ds-4",
5356
5300
  block: "flex flex-col space-y-ds-1.5 grow basis-1/2 break-words max-w-full has-[[data-title-one-line]]:min-w-0",
@@ -5511,8 +5455,11 @@ function TableHeading({ title, description, actions, titleId, descriptionId, ins
5511
5455
  descriptionText(HEADER_LAYOUT.below)
5512
5456
  ] }) });
5513
5457
  }
5514
- var NO_PINS = { start: [], end: [], nameFits: false, frame: 0 };
5515
- var samePins = (a, b) => a.nameFits === b.nameFits && a.frame === b.frame && a.start.join() === b.start.join() && a.end.join() === b.end.join();
5458
+ var NO_PINS = { start: [], end: [], nameFits: false, frame: 0, panel: null };
5459
+ var samePins = (a, b) => a.nameFits === b.nameFits && a.frame === b.frame && a.start.join() === b.start.join() && a.end.join() === b.end.join() && a.panel?.join() === b.panel?.join();
5460
+ function PanelContent({ children }) {
5461
+ return /* @__PURE__ */ jsx(SurfaceBoundary, { children });
5462
+ }
5516
5463
  function Table({
5517
5464
  columns: columnsProp,
5518
5465
  data,
@@ -5545,6 +5492,7 @@ function Table({
5545
5492
  "aria-label": ariaLabel,
5546
5493
  ref
5547
5494
  }) {
5495
+ useFramesItself();
5548
5496
  const headingId = useId();
5549
5497
  const titleId = `${headingId}-title`;
5550
5498
  const descriptionId = `${headingId}-description`;
@@ -5686,6 +5634,7 @@ function Table({
5686
5634
  const cells = Array.from(table2.querySelectorAll(":scope > thead > tr > th"));
5687
5635
  if (!cells.length) return;
5688
5636
  const widths = cells.map((c) => c.getBoundingClientRect().width);
5637
+ if (!widths.some((w) => w > 0)) return;
5689
5638
  const start = [];
5690
5639
  let at = 0;
5691
5640
  for (let i = 0; i < lead; i++) {
@@ -5702,7 +5651,9 @@ function Table({
5702
5651
  const frame = scroller.clientWidth;
5703
5652
  const nameFits = nameIndex >= 0 && frame > 0 && at + nameWidth + fromRight <= frame / 2;
5704
5653
  if (nameFits) start.push(at);
5705
- const next = { start, end, nameFits, frame };
5654
+ const pad3 = (cell, side) => cell ? parseFloat(getComputedStyle(cell)[side]) || 0 : 0;
5655
+ const panel = cells.length > lead ? [at + pad3(cells[lead], "paddingLeft"), pad3(cells[cells.length - 1], "paddingRight")] : null;
5656
+ const next = { start, end, nameFits, frame, panel };
5706
5657
  setPins((prev) => samePins(prev, next) ? prev : next);
5707
5658
  };
5708
5659
  measure();
@@ -5806,8 +5757,8 @@ function Table({
5806
5757
  const row = rootRef.current?.querySelector(was.row);
5807
5758
  if (!row) return;
5808
5759
  const controls = Array.from(row.querySelectorAll(FOCUSABLE));
5809
- const same2 = was.control === null ? null : controls.find((el) => (el.getAttribute("aria-labelledby") ?? el.getAttribute("aria-label") ?? el.textContent) === was.control);
5810
- (same2 ?? (row.tabIndex >= 0 ? row : controls[0]))?.focus({ preventScroll: true });
5760
+ const same = was.control === null ? null : controls.find((el) => (el.getAttribute("aria-labelledby") ?? el.getAttribute("aria-label") ?? el.textContent) === was.control);
5761
+ (same ?? (row.tabIndex >= 0 ? row : controls[0]))?.focus({ preventScroll: true });
5811
5762
  }, [isMobile, rootRef]);
5812
5763
  if (isMobile) {
5813
5764
  if (loading) {
@@ -5853,7 +5804,7 @@ function Table({
5853
5804
  /* @__PURE__ */ jsx("span", { className: "shrink-0 text-[var(--ds-text-secondary)] font-medium text-xs uppercase tracking-wider", children: col.header }),
5854
5805
  /* @__PURE__ */ jsx(CardValue, { value: row[col.key], id: lead + c === nameIndex ? `${headingId}-card-name-${idPart(id)}` : void 0 })
5855
5806
  ] }, col.key)),
5856
- 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, originalIdx) })
5807
+ 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: /* @__PURE__ */ jsx(PanelContent, { children: renderExpanded(row, originalIdx) }) })
5857
5808
  ]
5858
5809
  },
5859
5810
  String(id)
@@ -5953,7 +5904,8 @@ function Table({
5953
5904
  {
5954
5905
  ...marksOf(row, originalIdx),
5955
5906
  className: cn(
5956
- "border-b-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)] last:border-b-0",
5907
+ // an opened row's divider is under its panel (A6)
5908
+ !(expandable && isExpanded && renderExpanded) && "border-b-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)] last:border-b-0",
5957
5909
  // the row's background and its tint change together, so its pinned cells and the rest fade as one
5958
5910
  // (roots.css registers --gs-row-tint as a colour so it can)
5959
5911
  "transition-[background-color,--gs-row-tint]",
@@ -6038,12 +5990,21 @@ function Table({
6038
5990
  ]
6039
5991
  }
6040
5992
  ),
6041
- expandable && isExpanded && renderExpanded && /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
5993
+ expandable && isExpanded && renderExpanded && /* @__PURE__ */ jsx("tr", { className: "border-b-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)] last:border-b-0", children: /* @__PURE__ */ jsx(
6042
5994
  "td",
6043
5995
  {
6044
5996
  colSpan: cellCount,
6045
- className: "bg-[var(--ds-bg-muted)] px-ds-6 py-ds-4 text-sm text-[var(--ds-text-primary)]",
6046
- children: /* @__PURE__ */ jsx("div", { "data-row-panel": "", className: "sticky left-ds-6", style: pins.frame ? { maxWidth: `calc(${pins.frame}px - 2 * var(--ds-space-6))` } : void 0, children: renderExpanded(row, originalIdx) })
5997
+ className: cn("py-ds-4 text-sm text-[var(--ds-text-primary)]", !pins.panel && (density === "compact" ? "px-ds-3" : "px-ds-4")),
5998
+ style: pins.panel ? { paddingLeft: pins.panel[0], paddingRight: pins.panel[1] } : void 0,
5999
+ children: /* @__PURE__ */ jsx(
6000
+ "div",
6001
+ {
6002
+ "data-row-panel": "",
6003
+ className: "sticky",
6004
+ style: pins.panel ? { left: pins.panel[0], maxWidth: pins.frame ? pins.frame - pins.panel[0] - pins.panel[1] : void 0 } : { left: 0 },
6005
+ children: /* @__PURE__ */ jsx(PanelContent, { children: renderExpanded(row, originalIdx) })
6006
+ }
6007
+ )
6047
6008
  }
6048
6009
  ) })
6049
6010
  ] }, String(id));
@@ -6244,12 +6205,15 @@ function SegmentedControl({
6244
6205
  onKeyDown: handleKeyDown,
6245
6206
  className: cn(
6246
6207
  "relative items-center",
6247
- fullWidth ? "flex w-full" : "inline-flex",
6208
+ // Sprint 25.14 A21: in a Field's column a track that isn't full width keeps its own width; w-fit, not self-start,
6209
+ // so a row or a centred column still aligns it (the review of 30 September)
6210
+ fullWidth ? "flex w-full" : "inline-flex w-fit",
6248
6211
  containerPadding[size],
6249
6212
  containerHeight[size],
6250
6213
  "bg-[var(--ds-bg-muted)]",
6251
6214
  "rounded-[var(--ds-radius-lg)]",
6252
- variant === "default" && "border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]",
6215
+ // Sprint 25.14 A20: the track's edge is a control's, at 3:1
6216
+ variant === "default" && "border-[length:var(--ds-border-width)] border-[var(--ds-input-border)]",
6253
6217
  control.invalid && "border-[length:var(--ds-border-width)] border-[var(--ds-status-error)]",
6254
6218
  className
6255
6219
  ),
@@ -6736,6 +6700,7 @@ function WeekView({
6736
6700
  const hasAllDay = allDayEvents.some((d) => d.length > 0);
6737
6701
  const containerRef = useRef(null);
6738
6702
  const syncingScroll = useRef(false);
6703
+ const { ref: edgesRef, measure: measureEdges, fadeProps: edgeFade } = useScrollEdges();
6739
6704
  const handleScroll = useCallback((e) => {
6740
6705
  if (syncingScroll.current) return;
6741
6706
  syncingScroll.current = true;
@@ -6761,7 +6726,7 @@ function WeekView({
6761
6726
  return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: "flex flex-col h-full overflow-hidden", children: [
6762
6727
  /* @__PURE__ */ jsxs("div", { className: "flex border-b-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)]", children: [
6763
6728
  /* @__PURE__ */ jsx("div", { className: "w-14 shrink-0 border-r-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)]" }),
6764
- /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-x-auto gs-scrollbar-none", "data-week-scroll": true, children: /* @__PURE__ */ jsx(
6729
+ /* @__PURE__ */ jsx("div", { ref: edgesRef, onScroll: measureEdges, ...edgeFade, className: "flex-1 overflow-x-auto gs-scrollbar-none", "data-week-scroll": true, children: /* @__PURE__ */ jsx(
6765
6730
  "div",
6766
6731
  {
6767
6732
  className: "grid",
@@ -6801,7 +6766,7 @@ function WeekView({
6801
6766
  ] }),
6802
6767
  hasAllDay && /* @__PURE__ */ jsxs("div", { className: "flex border-b-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)] bg-[var(--ds-bg-muted)]/30", children: [
6803
6768
  /* @__PURE__ */ jsx("div", { className: "w-14 shrink-0 border-r-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)] text-2xs text-[var(--ds-text-muted)] px-ds-1 py-ds-1 text-right", children: "all-day" }),
6804
- /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-x-auto gs-scrollbar-none", "data-week-scroll": true, children: /* @__PURE__ */ jsx(
6769
+ /* @__PURE__ */ jsx("div", { ...edgeFade, className: "flex-1 overflow-x-auto gs-scrollbar-none", "data-week-scroll": true, children: /* @__PURE__ */ jsx(
6805
6770
  "div",
6806
6771
  {
6807
6772
  className: "grid",
@@ -6838,7 +6803,7 @@ function WeekView({
6838
6803
  },
6839
6804
  h
6840
6805
  )) }),
6841
- /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-x-auto gs-scrollbar-none", "data-week-scroll": true, children: /* @__PURE__ */ jsx(
6806
+ /* @__PURE__ */ jsx("div", { ...edgeFade, className: "flex-1 overflow-x-auto gs-scrollbar-none", "data-week-scroll": true, children: /* @__PURE__ */ jsx(
6842
6807
  "div",
6843
6808
  {
6844
6809
  className: "relative",
@@ -7882,7 +7847,6 @@ function AvatarGroup({ items, max = 4, size = "sm", ring = "canvas", onOverflowC
7882
7847
  alt: item.alt ?? item.name ?? initials,
7883
7848
  initials,
7884
7849
  size,
7885
- status: item.status,
7886
7850
  color: item.color,
7887
7851
  className: ringClass
7888
7852
  },
@@ -8201,6 +8165,7 @@ function VerticalLayout({ items, className }) {
8201
8165
  ] }, i)) });
8202
8166
  }
8203
8167
  function Timeline({ items: allItems, orientation = "vertical", minItemWidth = 200, className, ref, pager }) {
8168
+ useScrollsInside();
8204
8169
  useWholeListCheck("Timeline", allItems.length, pager);
8205
8170
  const items = pagerPart(allItems, pager);
8206
8171
  const measureRef = useRef(null);
@@ -8287,12 +8252,27 @@ var Collapsible = Object.assign(CollapsibleRoot, {
8287
8252
  Trigger: CollapsibleTrigger,
8288
8253
  Content: CollapsibleContent
8289
8254
  });
8255
+ var SYMBOL = /[⌘⇧⌥⌃⎋⏎↵⌫⌦⇥↑↓←→]/u;
8256
+ function keyParts(text) {
8257
+ const parts = [];
8258
+ let run = "";
8259
+ for (const ch of Array.from(text)) {
8260
+ if (SYMBOL.test(ch)) {
8261
+ if (run.trim()) parts.push(run.trim());
8262
+ run = "";
8263
+ parts.push(ch);
8264
+ } else run += ch;
8265
+ }
8266
+ if (run.trim()) parts.push(run.trim());
8267
+ return parts;
8268
+ }
8290
8269
  function Kbd({ children, className }) {
8270
+ const parts = typeof children === "string" ? keyParts(children) : null;
8291
8271
  return /* @__PURE__ */ jsx(
8292
8272
  "kbd",
8293
8273
  {
8294
8274
  className: cn(
8295
- "inline-flex items-center justify-center min-w-[2.5em] px-ds-1.5 py-ds-0.5",
8275
+ "inline-flex items-center justify-center gap-[0.25em] min-w-[2.5em] px-ds-1.5 py-ds-0.5",
8296
8276
  "text-xs leading-none font-[family-name:var(--ds-font-mono)]",
8297
8277
  "text-[var(--ds-text-secondary)]",
8298
8278
  "bg-[var(--ds-bg-surface)]",
@@ -8301,7 +8281,7 @@ function Kbd({ children, className }) {
8301
8281
  "rounded-[var(--ds-radius-sm)]",
8302
8282
  className
8303
8283
  ),
8304
- children
8284
+ children: parts && parts.length > 1 ? parts.map((p, i) => /* @__PURE__ */ jsx("span", { children: p }, i)) : children
8305
8285
  }
8306
8286
  );
8307
8287
  }
@@ -8898,7 +8878,8 @@ function ChatInputBar({ onSend, busy, onStop, onAttach, onVoice, placeholder })
8898
8878
  className: cn(
8899
8879
  "flex flex-col",
8900
8880
  "rounded-[var(--ds-radius-lg)]",
8901
- "border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]",
8881
+ // Sprint 25.14 A20: the composer is a field, its edge at 3:1 like every other control's
8882
+ "border-[length:var(--ds-border-width)] border-[var(--ds-input-border)]",
8902
8883
  "bg-[var(--ds-input-bg)]",
8903
8884
  "shadow-[var(--ds-input-shadow)]",
8904
8885
  FOCUS_WITHIN_RING,
@@ -9191,6 +9172,28 @@ function useCornerInset(corner, inset, priority, target) {
9191
9172
  return claimCornerInset(corner, inset, priority, el);
9192
9173
  }, [corner, inset, priority, target]);
9193
9174
  }
9175
+ function Sheet({ open, onClose: onCloseProp, title, children, footer, dirty, onDiscard, snapPoints = [0.5, 0.92], container, flush, keepMounted = false, id, labelledBy }) {
9176
+ const { marked, mark } = useOverlayMark(open);
9177
+ const guard = useDirtyGuard(dirty ?? marked, onCloseProp, onDiscard);
9178
+ return /* @__PURE__ */ jsx(
9179
+ DrawerPanel,
9180
+ {
9181
+ form: "sheet",
9182
+ open,
9183
+ onClose: guard.requestClose,
9184
+ title,
9185
+ footer,
9186
+ container,
9187
+ flush,
9188
+ snapPoints,
9189
+ keepMounted,
9190
+ id,
9191
+ labelledBy,
9192
+ confirm: /* @__PURE__ */ jsx(DiscardConfirm, { open: guard.confirming, onKeep: guard.keep, onDiscard: guard.discard }),
9193
+ children: /* @__PURE__ */ jsx(DrawerFooterCtx, { value: null, children: /* @__PURE__ */ jsx(OverlayCloseCtx, { value: guard.requestClose, children: /* @__PURE__ */ jsx(OverlayMarkScope, { mark, children }) }) })
9194
+ }
9195
+ );
9196
+ }
9194
9197
  var DEFAULT_OFFSET = "var(--ds-space-4)";
9195
9198
  var CORNER_PANEL_ANCHOR_INSET = "calc(var(--ds-space-12) + var(--ds-space-3))";
9196
9199
  function CornerPanel({
@@ -9475,6 +9478,7 @@ var StackedList = forwardRef(function StackedList2({
9475
9478
  hover,
9476
9479
  pager
9477
9480
  }, ref) {
9481
+ useScrollsInside();
9478
9482
  const isPhone = useBreakpoint("sm");
9479
9483
  const inCard = useContext(CardSurfaceCtx);
9480
9484
  const inPane = useContext(SplitPaneCtx);
@@ -10706,6 +10710,7 @@ function Gantt({
10706
10710
  "aria-label": ariaLabel,
10707
10711
  className
10708
10712
  }) {
10713
+ useScrollsInside();
10709
10714
  const [zoomState, setZoomState] = useState(defaultZoom);
10710
10715
  const zoom = zoomProp ?? zoomState;
10711
10716
  const changeZoom = (next) => {
@@ -11523,14 +11528,17 @@ function TabButton({
11523
11528
  onClick: disabled ? void 0 : () => onTabChange(id),
11524
11529
  onKeyDown,
11525
11530
  className: cn(
11526
- "px-ds-4 py-ds-2.5 text-sm font-medium",
11531
+ // Sprint 25.14 A38: a flex box, so the label sits in the middle of the tab. On a text line an icon's baseline
11532
+ // pushed the line 3 px taller and the label to its top (R28-72); a tab with an icon is now as tall as one
11533
+ // without, as a truncating tab (flex already) always was.
11534
+ "flex items-center justify-center px-ds-4 py-ds-2.5 text-sm font-medium",
11527
11535
  // never wrap: the strip scrolls when the tabs do not fit (round 17, 54.4)
11528
11536
  !fullWidth && !truncate && "shrink-0 whitespace-nowrap",
11529
11537
  disabled ? "cursor-not-allowed opacity-disabled" : "cursor-pointer",
11530
11538
  "transition-colors duration-[var(--ds-transition-speed)]",
11531
11539
  "focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]",
11532
11540
  fullWidth && "flex-1",
11533
- truncate && "flex-1 min-w-0 flex items-center",
11541
+ truncate && "flex-1 min-w-0 justify-start",
11534
11542
  "rounded-[var(--ds-nav-h-item-radius)]",
11535
11543
  isActive ? "bg-[var(--ds-nav-h-active-bg)] text-[var(--ds-nav-h-active-text)] border-[var(--ds-accent-primary)]" : "text-[var(--ds-nav-h-inactive-text)] hover:text-[var(--ds-text-primary)] hover:bg-[var(--ds-nav-h-hover-bg)]",
11536
11544
  className
@@ -13737,7 +13745,8 @@ function pageMaxWidth(resolved) {
13737
13745
  }
13738
13746
  var paddingClasses = {
13739
13747
  none: "",
13740
- default: "px-ds-6",
13748
+ // the page's gutter, which an overlay's header, body and footer share (Sprint 25.14 A36)
13749
+ default: "px-[var(--ds-page-gutter)]",
13741
13750
  wide: "px-ds-10"
13742
13751
  };
13743
13752
  var verticalPaddingClasses = {
@@ -14065,10 +14074,18 @@ function Caption({ children, onLight, onTint }) {
14065
14074
  onLight ? "text-[var(--ds-text-on-primary)]/80" : onTint ? "text-[var(--ds-text-muted-on-tint)]" : "text-[var(--ds-text-secondary)]"
14066
14075
  ), children });
14067
14076
  }
14077
+ var ON_BAND_STRIP = cn(
14078
+ "rounded-[var(--ds-radius-md)] px-ds-3 py-ds-2 border-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]",
14079
+ "bg-[var(--ds-bg-surface)] supports-[color:oklch(from_red_l_c_h)]:bg-[oklch(from_var(--ds-bg-surface)_l_c_h_/_max(alpha,min(1,alpha*1000)*0.6))]",
14080
+ GLASS_SURFACE
14081
+ );
14068
14082
  function TabRow({ children, hasCaption, className, onBand }) {
14069
14083
  const [row, setRow] = useState(null);
14070
14084
  const value = useMemo(() => ({ row, hasCaption }), [row, hasCaption]);
14071
- return /* @__PURE__ */ jsx("div", { ref: setRow, className: cn(className, onBand && "mx-0 rounded-[var(--ds-radius-md)] bg-[var(--ds-bg-surface)] px-ds-3 py-ds-2"), children: /* @__PURE__ */ jsx(HeaderTabRowContext.Provider, { value, children }) });
14085
+ return /* @__PURE__ */ jsx("div", { ref: setRow, className: cn(className, onBand && cn("mx-0", ON_BAND_STRIP)), children: /* @__PURE__ */ jsx(HeaderTabRowContext.Provider, { value, children }) });
14086
+ }
14087
+ function FilterRow({ children, className, onBand }) {
14088
+ return /* @__PURE__ */ jsx(ControlSizeContext.Provider, { value: "sm", children: /* @__PURE__ */ jsx(FilterRowContext.Provider, { value: true, children: /* @__PURE__ */ jsx("div", { "data-gs": "filter-row", className: cn("flex items-center flex-wrap gap-ds-3", className, onBand && cn("w-fit max-w-full", ON_BAND_STRIP)), children }) }) });
14072
14089
  }
14073
14090
  var FLOATING_HEADER = cn(
14074
14091
  "rounded-[var(--ds-radius-md)]",
@@ -14356,7 +14373,7 @@ function DefaultHeader({
14356
14373
  ] }),
14357
14374
  actions && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-2 shrink-0", children: actions })
14358
14375
  ] }),
14359
- 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 }) }),
14376
+ filters && /* @__PURE__ */ jsx(FilterRow, { className: "mt-ds-4", children: filters }),
14360
14377
  tabs && /* @__PURE__ */ jsx(TabRow, { hasCaption: !!caption, className: "mt-ds-4 -mx-ds-1", children: tabs })
14361
14378
  ] })
14362
14379
  ]
@@ -14468,7 +14485,9 @@ function ColourfulHeader({
14468
14485
  style: {
14469
14486
  maxWidth: gutter ? contentMaxWidth ?? "var(--ds-bp-xl)" : void 0,
14470
14487
  containerType: "inline-size",
14471
- ...overlapActive ? { paddingBottom: `calc(var(--ds-space-6) + var(--ds-overlap, 0px))` } : {}
14488
+ // under the overlap, the gap from the header's last row to the cards is the page's own (space-6): the band's
14489
+ // bottom edge counts in it (the owner, 30 September: 26 px above the cards, 24 below)
14490
+ ...overlapActive ? { paddingBottom: `calc(var(--ds-space-6) + var(--ds-overlap, 0px) - ${isBold && !isFloating ? "2px" : "var(--ds-border-width)"})` } : {}
14472
14491
  },
14473
14492
  children: [
14474
14493
  focusBack && /* @__PURE__ */ jsx(BackLink, { onClick: focusBack, onLight: isBold }),
@@ -14497,7 +14516,7 @@ function ColourfulHeader({
14497
14516
  ] }),
14498
14517
  actions && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-2 shrink-0", children: actions })
14499
14518
  ] }),
14500
- 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 }) }),
14519
+ filters && /* @__PURE__ */ jsx(FilterRow, { className: "mt-ds-4", onBand: isBold, children: filters }),
14501
14520
  tabs && /* @__PURE__ */ jsx(TabRow, { hasCaption: !!caption, className: "mt-ds-4 -mx-ds-1", onBand: isBold, children: tabs })
14502
14521
  ]
14503
14522
  }
@@ -14683,7 +14702,7 @@ function SnappingHeader({
14683
14702
  actions && /* @__PURE__ */ jsx(ControlSizeContext.Provider, { value: "sm", children: /* @__PURE__ */ jsx("div", { className: "flex items-center gap-ds-2 shrink-0", children: actions }) })
14684
14703
  ] }),
14685
14704
  description && /* @__PURE__ */ jsx(ClampedText, { className: "mt-ds-1 text-sm text-[var(--ds-text-secondary)]", children: description }),
14686
- 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 }) }),
14705
+ filters && /* @__PURE__ */ jsx(FilterRow, { className: "mt-ds-3", children: filters }),
14687
14706
  expandedContent && /* @__PURE__ */ jsx("div", { className: "mt-ds-3", children: expandedContent }),
14688
14707
  tabs && /* @__PURE__ */ jsx(TabRow, { hasCaption: !!caption, className: "mt-ds-3 -mx-ds-1", children: tabs })
14689
14708
  ] }) : /* @__PURE__ */ jsxs(
@@ -14697,7 +14716,7 @@ function SnappingHeader({
14697
14716
  hasBreadcrumbs && !hideExpandedBreadcrumbs ? "pt-ds-3" : "pt-ds-6"
14698
14717
  ]
14699
14718
  ),
14700
- style: !collapsed && isColourful && overlapActive ? { paddingBottom: `calc(var(--ds-space-6) + var(--ds-overlap, 0px))` } : void 0,
14719
+ style: !collapsed && isColourful && overlapActive ? { paddingBottom: `calc(var(--ds-space-6) + var(--ds-overlap, 0px) - ${isBoldColourful && !(isFloating && !wrapperHasCard) ? "2px" : "var(--ds-border-width)"})` } : void 0,
14701
14720
  children: [
14702
14721
  !collapsed && focusBack && /* @__PURE__ */ jsx(BackLink, { onClick: focusBack, onLight }),
14703
14722
  !collapsed && hasBreadcrumbs && !hideExpandedBreadcrumbs && /* @__PURE__ */ jsx(Breadcrumbs3, { items: breadcrumbs, onLight, onTint, pill: breadcrumbPill, separator: breadcrumbSeparator }),
@@ -14752,7 +14771,7 @@ function SnappingHeader({
14752
14771
  ] }),
14753
14772
  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 }))
14754
14773
  ] }),
14755
- !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 }) }),
14774
+ !collapsed && filters && /* @__PURE__ */ jsx(FilterRow, { className: "mt-ds-4", onBand: isBoldColourful, children: filters }),
14756
14775
  !collapsed && expandedContent && /* @__PURE__ */ jsx("div", { className: "mt-ds-4", children: expandedContent }),
14757
14776
  !collapsed && tabs && /* @__PURE__ */ jsx(TabRow, { hasCaption: !!caption, className: "mt-ds-4 -mx-ds-1", onBand: isBoldColourful, children: tabs })
14758
14777
  ]
@@ -14989,6 +15008,73 @@ function Dock({
14989
15008
  }
14990
15009
  );
14991
15010
  }
15011
+ function resolveNavItemType(type) {
15012
+ return type === "default" ? "tint" : type;
15013
+ }
15014
+ var NavbarTypeContext = createContext("tint");
15015
+ var NavItem = forwardRef(function NavItem2({ label, icon, active = false, href, onClick, type: typeProp, className, children }, ref) {
15016
+ const contextType = useContext(NavbarTypeContext);
15017
+ const type = resolveNavItemType(typeProp ?? contextType);
15018
+ const baseClasses = cn(
15019
+ "inline-flex items-center gap-ds-2 cursor-pointer select-none whitespace-nowrap",
15020
+ // one line: the navbar measures each link (round 12)
15021
+ "transition-colors duration-[var(--ds-transition-speed)] ease-[var(--ds-transition-ease)]",
15022
+ "focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]",
15023
+ "text-[length:var(--ds-font-size-sm)]"
15024
+ );
15025
+ const typeClasses = getTypeClasses(type, active);
15026
+ return /* @__PURE__ */ jsxs(
15027
+ "a",
15028
+ {
15029
+ ref,
15030
+ href: href ?? "#",
15031
+ onClick,
15032
+ "aria-current": active ? "page" : void 0,
15033
+ className: cn(baseClasses, typeClasses, className),
15034
+ children: [
15035
+ icon && /* @__PURE__ */ jsx(Icon, { name: icon, size: 16 }),
15036
+ children ?? label,
15037
+ type === "underline" && active && /* @__PURE__ */ jsx(NavUnderline, {})
15038
+ ]
15039
+ }
15040
+ );
15041
+ });
15042
+ function getTypeClasses(type, active) {
15043
+ switch (type) {
15044
+ case "pill":
15045
+ return cn(
15046
+ "px-ds-2 py-ds-1 rounded-[var(--ds-radius-sm)]",
15047
+ 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)]"
15048
+ );
15049
+ case "underline":
15050
+ return cn(
15051
+ "px-ds-2 py-ds-2 relative",
15052
+ active ? "text-[var(--ds-text-primary)] font-[var(--ds-weight-heading)]" : "text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)]"
15053
+ );
15054
+ case "minimal":
15055
+ return cn(
15056
+ "px-ds-2 py-ds-1",
15057
+ active ? "text-[var(--ds-accent-primary)] font-medium" : "text-[var(--ds-text-muted)] hover:text-[var(--ds-text-secondary)]"
15058
+ );
15059
+ case "tint":
15060
+ return cn(
15061
+ "px-ds-2 py-ds-1 rounded-[var(--ds-radius-sm)]",
15062
+ 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)]"
15063
+ );
15064
+ }
15065
+ }
15066
+ function NavUnderline() {
15067
+ return /* @__PURE__ */ jsx(
15068
+ "span",
15069
+ {
15070
+ className: "absolute bottom-0 left-ds-1 right-ds-1 rounded-t-full bg-[var(--ds-accent-primary)]",
15071
+ style: { height: "2px" }
15072
+ }
15073
+ );
15074
+ }
15075
+ function navItemClasses(type, active) {
15076
+ return cn("text-[length:var(--ds-font-size-sm)]", getTypeClasses(type, active));
15077
+ }
14992
15078
  function TruncSpan({ children, className }) {
14993
15079
  const { ref, isTruncated } = useTextOverflow({ lines: 1 });
14994
15080
  const el = /* @__PURE__ */ jsx("span", { ref, className: cn("truncate", className), children });
@@ -14999,7 +15085,7 @@ function NavMenu({
14999
15085
  label,
15000
15086
  items,
15001
15087
  active = false,
15002
- type = "tint",
15088
+ type: typeProp,
15003
15089
  onItemClick,
15004
15090
  className
15005
15091
  }) {
@@ -15047,27 +15133,14 @@ function NavMenu({
15047
15133
  const hasActiveChild = active || items.some(
15048
15134
  (it) => it.active || it.children?.some((c) => c.active)
15049
15135
  );
15136
+ const contextType = useContext(NavbarTypeContext);
15137
+ const type = resolveNavItemType(typeProp ?? contextType);
15050
15138
  const isUnderline = type === "underline";
15051
- const isMinimal = type === "minimal";
15052
- const isPill = type === "pill";
15053
15139
  const triggerClasses = cn(
15054
- "inline-flex items-center gap-ds-1 cursor-pointer transition-colors whitespace-nowrap",
15140
+ "inline-flex items-center gap-ds-1 cursor-pointer select-none whitespace-nowrap",
15141
+ "transition-colors duration-[var(--ds-transition-speed)] ease-[var(--ds-transition-ease)]",
15055
15142
  "focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]",
15056
- isUnderline ? cn(
15057
- "px-ds-3 py-ds-2 text-sm border-b-2 -mb-[2px]",
15058
- hasActiveChild ? "border-[var(--ds-accent-primary)] text-[var(--ds-text-primary)] font-medium" : "border-transparent text-[var(--ds-text-secondary)] hover:text-[var(--ds-text-primary)] hover:border-[var(--ds-border-default)]"
15059
- ) : isMinimal ? cn(
15060
- "px-ds-2 py-ds-1 text-sm",
15061
- hasActiveChild ? "text-[var(--ds-text-primary)] font-medium" : "text-[var(--ds-text-secondary)] hover:text-[var(--ds-text-primary)]"
15062
- ) : isPill ? cn(
15063
- "px-ds-3 py-ds-1.5 text-sm rounded-[var(--ds-radius-md)]",
15064
- hasActiveChild ? "bg-[var(--ds-accent-primary)] text-[var(--ds-text-on-primary)] font-medium" : "text-[var(--ds-text-secondary)] hover:bg-[var(--ds-bg-muted)] hover:text-[var(--ds-text-primary)]"
15065
- ) : cn(
15066
- // tint (and the deprecated `default` alias) — the same soft accent fill
15067
- // NavItem uses, so a menu trigger and a link read as one row (decision 30).
15068
- "px-ds-3 py-ds-1.5 text-sm rounded-[var(--ds-radius-md)]",
15069
- hasActiveChild ? "bg-[var(--ds-accent-subtle)] text-[var(--ds-accent-primary)] font-medium" : "text-[var(--ds-text-secondary)] hover:bg-[var(--ds-bg-muted)] hover:text-[var(--ds-text-primary)]"
15070
- ),
15143
+ navItemClasses(type, hasActiveChild),
15071
15144
  className
15072
15145
  );
15073
15146
  return /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -15089,7 +15162,8 @@ function NavMenu({
15089
15162
  size: 12,
15090
15163
  className: cn("transition-transform", open && "rotate-180")
15091
15164
  }
15092
- )
15165
+ ),
15166
+ isUnderline && hasActiveChild && /* @__PURE__ */ jsx(NavUnderline, {})
15093
15167
  ]
15094
15168
  }
15095
15169
  ),
@@ -15200,67 +15274,6 @@ function NavMenuGroup({
15200
15274
  )) })
15201
15275
  ] });
15202
15276
  }
15203
- function resolveNavItemType(type) {
15204
- return type === "default" ? "tint" : type;
15205
- }
15206
- var NavbarTypeContext = createContext("tint");
15207
- var NavItem = forwardRef(function NavItem2({ label, icon, active = false, href, onClick, type: typeProp, className, children }, ref) {
15208
- const contextType = useContext(NavbarTypeContext);
15209
- const type = resolveNavItemType(typeProp ?? contextType);
15210
- const baseClasses = cn(
15211
- "inline-flex items-center gap-ds-2 cursor-pointer select-none whitespace-nowrap",
15212
- // one line: the navbar measures each link (round 12)
15213
- "transition-colors duration-[var(--ds-transition-speed)] ease-[var(--ds-transition-ease)]",
15214
- "focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]",
15215
- "text-[length:var(--ds-font-size-sm)]"
15216
- );
15217
- const typeClasses = getTypeClasses(type, active);
15218
- return /* @__PURE__ */ jsxs(
15219
- "a",
15220
- {
15221
- ref,
15222
- href: href ?? "#",
15223
- onClick,
15224
- "aria-current": active ? "page" : void 0,
15225
- className: cn(baseClasses, typeClasses, className),
15226
- children: [
15227
- icon && /* @__PURE__ */ jsx(Icon, { name: icon, size: 16 }),
15228
- children ?? label,
15229
- type === "underline" && active && /* @__PURE__ */ jsx(
15230
- "span",
15231
- {
15232
- className: "absolute bottom-0 left-ds-1 right-ds-1 rounded-t-full bg-[var(--ds-accent-primary)]",
15233
- style: { height: "2px" }
15234
- }
15235
- )
15236
- ]
15237
- }
15238
- );
15239
- });
15240
- function getTypeClasses(type, active) {
15241
- switch (type) {
15242
- case "pill":
15243
- return cn(
15244
- "px-ds-2 py-ds-1 rounded-[var(--ds-radius-sm)]",
15245
- 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)]"
15246
- );
15247
- case "underline":
15248
- return cn(
15249
- "px-ds-2 py-ds-2 relative",
15250
- active ? "text-[var(--ds-text-primary)] font-[var(--ds-weight-heading)]" : "text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)]"
15251
- );
15252
- case "minimal":
15253
- return cn(
15254
- "px-ds-2 py-ds-1",
15255
- active ? "text-[var(--ds-accent-primary)] font-medium" : "text-[var(--ds-text-muted)] hover:text-[var(--ds-text-secondary)]"
15256
- );
15257
- case "tint":
15258
- return cn(
15259
- "px-ds-2 py-ds-1 rounded-[var(--ds-radius-sm)]",
15260
- 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)]"
15261
- );
15262
- }
15263
- }
15264
15277
  var DEFAULT_BUTTON_ATTR = "data-dialog-default-button";
15265
15278
  var sizeClasses = {
15266
15279
  // round 16 (the owner's item 5): the small dialog is 448 px, not 384 — a delete confirmation with a typed field was cramped
@@ -15281,6 +15294,7 @@ function Dialog({ open, onClose: onCloseProp, title, description, children, foot
15281
15294
  const dialogRef = useRef(null);
15282
15295
  const opener = useRef(null);
15283
15296
  const defaultButtonRef = useRef(null);
15297
+ const bodyRef = useScrollbarInset();
15284
15298
  const onCloseRef = useLatest(onClose);
15285
15299
  const onSubmitRef = useLatest(onSubmit);
15286
15300
  const isTopLayer = useOverlayLayer(open);
@@ -15326,7 +15340,7 @@ function Dialog({ open, onClose: onCloseProp, title, description, children, foot
15326
15340
  "div",
15327
15341
  {
15328
15342
  ref: overlayRef,
15329
- className: "fixed inset-0 z-[var(--ds-z-modal)] flex items-center justify-center p-ds-4",
15343
+ className: cn("fixed inset-0 z-[var(--ds-z-modal)] flex items-center justify-center", !isMobile && "p-ds-4"),
15330
15344
  children: [
15331
15345
  /* @__PURE__ */ jsx(
15332
15346
  "div",
@@ -15378,29 +15392,20 @@ function Dialog({ open, onClose: onCloseProp, title, description, children, foot
15378
15392
  "aria-describedby": description ? descriptionId : void 0,
15379
15393
  style: { containerType: "inline-size" },
15380
15394
  className: cn(
15381
- "relative z-10 w-full",
15395
+ // a column: the title row, a body that scrolls when it is taller than the room, and the footer (Sprint 25.14,
15396
+ // with A36's full-screen phone dialog: its content ran past the screen with the footer cut off)
15397
+ "relative z-10 w-full flex flex-col max-h-full",
15382
15398
  isMobile ? "max-w-none h-full" : sizeClasses[size],
15383
15399
  OVERLAY_SURFACE,
15384
15400
  "text-[var(--ds-text-primary)]",
15385
15401
  GLASS_OVERLAY,
15386
- "border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]",
15387
- isMobile ? "rounded-none" : "rounded-[var(--ds-radius-xl)]",
15402
+ // full screen on a phone: no edge to draw, so the content sits at the gutter from the screen's edge
15403
+ isMobile ? "rounded-none" : "rounded-[var(--ds-radius-xl)] border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]",
15388
15404
  "overflow-hidden",
15389
15405
  "animate-in fade-in-0 zoom-in-95"
15390
15406
  ),
15391
15407
  children: [
15392
- /* @__PURE__ */ jsx(
15393
- "button",
15394
- {
15395
- type: "button",
15396
- onClick: onClose,
15397
- ...{ [OVERLAY_CLOSE_ATTR]: "" },
15398
- className: "absolute right-4 top-4 text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)] transition-colors cursor-pointer",
15399
- "aria-label": "Close",
15400
- children: /* @__PURE__ */ jsx(Icon, { name: "close", size: 18 })
15401
- }
15402
- ),
15403
- /* @__PURE__ */ jsx("div", { className: "p-ds-6", children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-ds-3", children: [
15408
+ /* @__PURE__ */ jsxs("div", { className: cn("shrink-0 flex items-start gap-ds-3 pt-ds-6 px-[var(--ds-page-gutter)]", children ? "pb-ds-4" : "pb-ds-6"), children: [
15404
15409
  variant === "destructive" && /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center shrink-0 w-10 h-10 rounded-[var(--ds-radius-full)] bg-[var(--ds-status-error-bg)]", children: /* @__PURE__ */ jsx(Icon, { name: "warning", size: 20, className: "text-[var(--ds-status-error)]" }) }),
15405
15410
  /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
15406
15411
  /* @__PURE__ */ jsx(
@@ -15411,16 +15416,39 @@ function Dialog({ open, onClose: onCloseProp, title, description, children, foot
15411
15416
  children: title
15412
15417
  }
15413
15418
  ),
15414
- description && /* @__PURE__ */ jsx("p", { id: descriptionId, className: "mt-ds-2 text-sm text-[var(--ds-text-muted)]", children: description }),
15415
- children && /* @__PURE__ */ jsx("div", { className: "mt-ds-4", children: /* @__PURE__ */ jsx(OverlayMarkScope, { mark, children: /* @__PURE__ */ jsx(OverlayCloseCtx, { value: onClose, children }) }) })
15416
- ] })
15417
- ] }) }),
15419
+ description && /* @__PURE__ */ jsx("p", { id: descriptionId, className: "mt-ds-2 text-sm text-[var(--ds-text-muted)]", children: description })
15420
+ ] }),
15421
+ /* @__PURE__ */ jsx(
15422
+ "button",
15423
+ {
15424
+ type: "button",
15425
+ onClick: onClose,
15426
+ ...{ [OVERLAY_CLOSE_ATTR]: "" },
15427
+ className: "shrink-0 text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)] transition-colors cursor-pointer",
15428
+ "aria-label": "Close",
15429
+ children: /* @__PURE__ */ jsx(Icon, { name: "close", size: 18 })
15430
+ }
15431
+ )
15432
+ ] }),
15433
+ children && /* @__PURE__ */ jsx(
15434
+ "div",
15435
+ {
15436
+ ref: bodyRef,
15437
+ className: "min-h-0 flex-[0_1_auto] overflow-y-auto pb-ds-6",
15438
+ style: {
15439
+ paddingLeft: variant === "destructive" ? "calc(var(--ds-page-gutter) + 2.5rem + var(--ds-space-3))" : "var(--ds-page-gutter)",
15440
+ paddingRight: insetLessScrollbar("var(--ds-page-gutter)")
15441
+ },
15442
+ children: /* @__PURE__ */ jsx(SurfaceBoundary, { children: /* @__PURE__ */ jsx(DrawerFooterCtx, { value: null, children: /* @__PURE__ */ jsx(OverlayMarkScope, { mark, children: /* @__PURE__ */ jsx(OverlayCloseCtx, { value: onClose, children }) }) }) })
15443
+ }
15444
+ ),
15445
+ isMobile && /* @__PURE__ */ jsx("div", { "aria-hidden": true, className: "flex-1 min-h-0" }),
15418
15446
  /* @__PURE__ */ jsx(DiscardConfirm, { open: guard.confirming, onKeep: guard.keep, onDiscard: guard.discard }),
15419
15447
  footer && /* @__PURE__ */ jsx("div", { className: cn(
15420
- "flex justify-end gap-ds-2 p-ds-4",
15448
+ "shrink-0 flex justify-end gap-ds-2 py-ds-4 px-[var(--ds-page-gutter)]",
15421
15449
  "border-t-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]",
15422
15450
  "bg-[var(--ds-bg-muted)]",
15423
- "rounded-b-[var(--ds-radius-xl)]"
15451
+ !isMobile && "rounded-b-[var(--ds-radius-xl)]"
15424
15452
  ), children: footer })
15425
15453
  ]
15426
15454
  }
@@ -17010,6 +17038,6 @@ var TextOverflow = forwardRef(function TextOverflow2({
17010
17038
  return /* @__PURE__ */ jsx(Tooltip, { content: resolvedTooltipContent, children: content });
17011
17039
  });
17012
17040
 
17013
- export { Accordion, ActionPanel, ActionPanelGroup, AddAnother, Alert, AsidePanel, Avatar, AvatarGroup, BottomNav, Breadcrumbs, BulkActionBar, Calendar, Card, CardContent, CardDescription, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, ChatMessageList, ChatPanel, Checkbox, CheckboxGroup, CheckboxGroupItem, Collapsible, ColorPicker, Combobox, CommandPalette, ContextMenu, CornerPanel, DEFAULT_DATE_RANGE_PRESETS, DataList, DatePicker, DateRangePicker, DescriptionList, Dialog, Dock, DropdownMenu, EmptyState, EntityCell, FileUpload, FormWrapper, Gantt, HoverCard, Kbd, Launcher, MentionInput, MobileHeaderMenu, NavItem, NavMenu, Navbar, NotificationCenter, PageContainer, PageHeader, PinInput, Progress, RadioGroup, Rating, ScrollArea, SectionHeading, SegmentedControl, SettingsLayout, Sidebar, SidebarNav, SliderRange, StackedList, StatsCard, StatusDot, Stepper, TIME_ZOOMS, Table, TableToolbar, Tabs, Tag, TagInput, TextOverflow, TimeBar, TimePicker, TimeRow, TimeScaleHeader, TimeViewport, Timeline, Toast, ToastProvider, Tour, TransferList, TreeView, dateOfDay, dayOf, endDayOf, fitLabel, fitLabels, formatDateRange, timeExtent, useContentWidth, useDestructiveAction, useFittedLabels, useSidebar, useTextMeasure, useTimeScale, useTimeViewport, useTimeViewportLayout, useToast, useToastOptional };
17041
+ export { Accordion, ActionPanel, ActionPanelGroup, AddAnother, Alert, AsidePanel, Avatar, AvatarGroup, BottomNav, Breadcrumbs, BulkActionBar, Calendar, Card, CardContent, CardDescription, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, ChatMessageList, ChatPanel, Checkbox, CheckboxGroup, CheckboxGroupItem, Collapsible, ColorPicker, Combobox, CommandPalette, ContextMenu, CornerPanel, DEFAULT_DATE_RANGE_PRESETS, DataList, DatePicker, DateRangePicker, DescriptionList, Dialog, Dock, DropdownMenu, EmptyState, EntityCell, FileUpload, FormWrapper, Gantt, HoverCard, Kbd, Launcher, MentionInput, MobileHeaderMenu, NavItem, NavMenu, Navbar, NotificationCenter, PageContainer, PageHeader, PinInput, Progress, RadioGroup, Rating, ScrollArea, SectionHeading, SegmentedControl, SettingsLayout, Sheet, Sidebar, SidebarNav, SliderRange, StackedList, StatsCard, StatusDot, Stepper, TIME_ZOOMS, Table, TableToolbar, Tabs, Tag, TagInput, TextOverflow, TimeBar, TimePicker, TimeRow, TimeScaleHeader, TimeViewport, Timeline, Toast, ToastProvider, Tour, TransferList, TreeView, dateOfDay, dayOf, endDayOf, fitLabel, fitLabels, formatDateRange, timeExtent, useContentWidth, useDestructiveAction, useFittedLabels, useSidebar, useTextMeasure, useTimeScale, useTimeViewport, useTimeViewportLayout, useToast, useToastOptional };
17014
17042
  //# sourceMappingURL=index.js.map
17015
17043
  //# sourceMappingURL=index.js.map