@ship-it-ui/ui 0.0.4 → 0.0.6

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
@@ -201,14 +201,29 @@ var buttonStyles = cva(
201
201
  md: "h-[32px] px-3 text-[12px] gap-[6px] rounded-md",
202
202
  lg: "h-[38px] px-4 text-[13px] gap-[7px] rounded-[7px]"
203
203
  },
204
+ density: {
205
+ comfortable: "",
206
+ touch: ""
207
+ },
204
208
  fullWidth: {
205
209
  true: "w-full",
206
210
  false: ""
207
211
  }
208
212
  },
213
+ compoundVariants: [
214
+ // Mobile density — bumps every size to meet 44pt minimum touch target.
215
+ {
216
+ size: "sm",
217
+ density: "touch",
218
+ class: "h-[36px] px-[14px] text-[13px] gap-[7px] rounded-base"
219
+ },
220
+ { size: "md", density: "touch", class: "h-touch px-[18px] text-m-body gap-2 rounded-base" },
221
+ { size: "lg", density: "touch", class: "h-[52px] px-[22px] text-[16px] gap-2 rounded-base" }
222
+ ],
209
223
  defaultVariants: {
210
224
  variant: "primary",
211
225
  size: "md",
226
+ density: "comfortable",
212
227
  fullWidth: false
213
228
  }
214
229
  }
@@ -223,10 +238,14 @@ function Spinner({ size }) {
223
238
  }
224
239
  );
225
240
  }
226
- var iconSize = { sm: 11, md: 12, lg: 13 };
241
+ var iconSize = {
242
+ comfortable: { sm: 11, md: 12, lg: 13 },
243
+ touch: { sm: 13, md: 15, lg: 16 }
244
+ };
227
245
  var Button = forwardRef(function Button2({
228
246
  variant,
229
247
  size,
248
+ density,
230
249
  fullWidth,
231
250
  icon,
232
251
  trailing,
@@ -239,8 +258,8 @@ var Button = forwardRef(function Button2({
239
258
  ...props
240
259
  }, ref) {
241
260
  const isDisabled = disabled || loading;
242
- const iconPx = iconSize[size ?? "md"];
243
- const composedClassName = cn(buttonStyles({ variant, size, fullWidth }), className);
261
+ const iconPx = iconSize[density ?? "comfortable"][size ?? "md"];
262
+ const composedClassName = cn(buttonStyles({ variant, size, density, fullWidth }), className);
244
263
  if (asChild) {
245
264
  return /* @__PURE__ */ jsx(
246
265
  Slot,
@@ -301,18 +320,28 @@ var iconButtonStyles = cva2(
301
320
  sm: "h-[26px] w-[26px] text-[12px] rounded-[5px]",
302
321
  md: "h-[32px] w-[32px] text-[13px] rounded-md",
303
322
  lg: "h-[38px] w-[38px] text-[15px] rounded-[7px]"
323
+ },
324
+ density: {
325
+ comfortable: "",
326
+ touch: ""
304
327
  }
305
328
  },
306
- defaultVariants: { variant: "secondary", size: "md" }
329
+ compoundVariants: [
330
+ // Mobile density — 44pt minimum touch target, circular tap.
331
+ { size: "sm", density: "touch", class: "h-[36px] w-[36px] text-[14px] rounded-full" },
332
+ { size: "md", density: "touch", class: "h-touch w-touch text-[16px] rounded-full" },
333
+ { size: "lg", density: "touch", class: "h-[52px] w-[52px] text-[18px] rounded-full" }
334
+ ],
335
+ defaultVariants: { variant: "secondary", size: "md", density: "comfortable" }
307
336
  }
308
337
  );
309
- var IconButton = forwardRef2(function IconButton2({ variant, size, icon, type, className, ...props }, ref) {
338
+ var IconButton = forwardRef2(function IconButton2({ variant, size, density, icon, type, className, ...props }, ref) {
310
339
  return /* @__PURE__ */ jsx2(
311
340
  "button",
312
341
  {
313
342
  ref,
314
343
  type: type ?? "button",
315
- className: cn(iconButtonStyles({ variant, size }), className),
344
+ className: cn(iconButtonStyles({ variant, size, density }), className),
316
345
  ...props,
317
346
  children: icon
318
347
  }
@@ -432,14 +461,16 @@ FAB.displayName = "FAB";
432
461
  import * as RadixCheckbox from "@radix-ui/react-checkbox";
433
462
  import { forwardRef as forwardRef6, useId } from "react";
434
463
  import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
435
- var Checkbox = forwardRef6(function Checkbox2({ label, className, id: idProp, ...props }, ref) {
464
+ var Checkbox = forwardRef6(function Checkbox2({ label, density = "comfortable", className, id: idProp, ...props }, ref) {
436
465
  const reactId = useId();
437
466
  const id = idProp ?? `cb-${reactId}`;
467
+ const isTouch = density === "touch";
438
468
  return /* @__PURE__ */ jsxs3(
439
469
  "span",
440
470
  {
441
471
  className: cn(
442
- "inline-flex items-center gap-2 select-none",
472
+ "inline-flex items-center select-none",
473
+ isTouch ? "min-h-touch gap-3" : "gap-2",
443
474
  props.disabled && "cursor-not-allowed opacity-40",
444
475
  className
445
476
  ),
@@ -450,18 +481,32 @@ var Checkbox = forwardRef6(function Checkbox2({ label, className, id: idProp, ..
450
481
  ref,
451
482
  id,
452
483
  className: cn(
453
- "grid h-4 w-4 place-items-center rounded-xs",
454
- "bg-panel border-border-strong border",
484
+ "grid place-items-center",
485
+ isTouch ? "h-[22px] w-[22px] rounded-sm border-[1.5px]" : "h-4 w-4 rounded-xs border",
486
+ "bg-panel border-border-strong",
455
487
  "data-[state=checked]:bg-accent data-[state=checked]:border-accent",
456
488
  "data-[state=indeterminate]:bg-accent data-[state=indeterminate]:border-accent",
457
489
  "transition-[background,border-color] duration-(--duration-micro)",
458
490
  "focus-visible:ring-accent-dim outline-none focus-visible:ring-[3px]"
459
491
  ),
460
492
  ...props,
461
- children: /* @__PURE__ */ jsx6(RadixCheckbox.Indicator, { className: "text-on-accent text-[11px] leading-none", children: props.checked === "indeterminate" ? "\u2212" : "\u2713" })
493
+ children: /* @__PURE__ */ jsx6(
494
+ RadixCheckbox.Indicator,
495
+ {
496
+ className: cn("text-on-accent leading-none", isTouch ? "text-[14px]" : "text-[11px]"),
497
+ children: props.checked === "indeterminate" ? "\u2212" : "\u2713"
498
+ }
499
+ )
462
500
  }
463
501
  ),
464
- label && /* @__PURE__ */ jsx6("label", { htmlFor: id, className: "cursor-pointer text-[13px]", children: label })
502
+ label && /* @__PURE__ */ jsx6(
503
+ "label",
504
+ {
505
+ htmlFor: id,
506
+ className: cn("cursor-pointer", isTouch ? "text-m-body" : "text-[13px]"),
507
+ children: label
508
+ }
509
+ )
465
510
  ]
466
511
  }
467
512
  );
@@ -512,17 +557,28 @@ var inputWrapperStyles = cva3(
512
557
  tone: {
513
558
  default: "bg-panel border-border focus-within:border-accent focus-within:ring-accent-dim",
514
559
  err: "bg-panel border-err focus-within:border-err focus-within:ring-err/30"
560
+ },
561
+ density: {
562
+ comfortable: "",
563
+ touch: ""
515
564
  }
516
565
  },
517
- defaultVariants: { size: "md", tone: "default" }
566
+ compoundVariants: [
567
+ // Mobile density — 52px standard input height (MInput in the canvas);
568
+ // sm collapses to 44pt min, lg pushes to 56pt for prominent forms.
569
+ { size: "sm", density: "touch", class: "h-touch px-3 text-m-body rounded-m-tab" },
570
+ { size: "md", density: "touch", class: "h-[52px] px-[14px] text-m-body rounded-m-tab" },
571
+ { size: "lg", density: "touch", class: "h-row px-4 text-m-body-lg rounded-m-tab" }
572
+ ],
573
+ defaultVariants: { size: "md", tone: "default", density: "comfortable" }
518
574
  }
519
575
  );
520
- var Input = forwardRef7(function Input2({ size, tone, icon, trailing, error, width, className, style, disabled, ...props }, ref) {
576
+ var Input = forwardRef7(function Input2({ size, tone, density, icon, trailing, error, width, className, style, disabled, ...props }, ref) {
521
577
  const computedTone = error ? "err" : tone;
522
578
  return /* @__PURE__ */ jsxs5(
523
579
  "div",
524
580
  {
525
- className: cn(inputWrapperStyles({ size, tone: computedTone }), className),
581
+ className: cn(inputWrapperStyles({ size, tone: computedTone, density }), className),
526
582
  style: { width, ...style },
527
583
  children: [
528
584
  icon && /* @__PURE__ */ jsx8("span", { className: "text-text-dim leading-none", children: icon }),
@@ -551,27 +607,32 @@ Input.displayName = "Input";
551
607
  import { forwardRef as forwardRef8 } from "react";
552
608
  import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
553
609
  var SearchInput = forwardRef8(function SearchInput2({
554
- shortcut = "\u2318K",
555
- width = 360,
610
+ shortcut,
611
+ width,
612
+ density = "comfortable",
556
613
  className,
557
614
  style,
558
615
  placeholder = "Search\u2026",
559
616
  "aria-label": ariaLabel,
560
617
  ...props
561
618
  }, ref) {
619
+ const isTouch = density === "touch";
620
+ const resolvedWidth = width ?? (isTouch ? "100%" : 360);
621
+ const resolvedShortcut = shortcut ?? (isTouch ? void 0 : "\u2318K");
562
622
  return /* @__PURE__ */ jsxs6(
563
623
  "div",
564
624
  {
565
625
  className: cn(
566
- "rounded-base flex h-9 items-center gap-2 px-3 font-sans",
626
+ "flex items-center gap-2 font-sans",
627
+ isTouch ? "h-touch rounded-m-tab px-[14px]" : "rounded-base h-9 px-3",
567
628
  "bg-panel-2 border-border border",
568
629
  "focus-within:border-accent focus-within:ring-accent-dim focus-within:ring-[3px]",
569
630
  "transition-[border-color,box-shadow] duration-(--duration-micro)",
570
631
  className
571
632
  ),
572
- style: { width, ...style },
633
+ style: { width: resolvedWidth, ...style },
573
634
  children: [
574
- /* @__PURE__ */ jsx9("span", { className: "text-text-dim leading-none", "aria-hidden": true, children: "\u2315" }),
635
+ /* @__PURE__ */ jsx9("span", { className: cn("text-text-dim leading-none", isTouch && "text-[18px]"), "aria-hidden": true, children: "\u2315" }),
575
636
  /* @__PURE__ */ jsx9(
576
637
  "input",
577
638
  {
@@ -579,11 +640,14 @@ var SearchInput = forwardRef8(function SearchInput2({
579
640
  type: "search",
580
641
  placeholder,
581
642
  "aria-label": ariaLabel ?? (typeof placeholder === "string" ? placeholder : "Search"),
582
- className: "text-text placeholder:text-text-dim min-w-0 flex-1 border-none bg-transparent text-[13px] outline-none",
643
+ className: cn(
644
+ "text-text placeholder:text-text-dim min-w-0 flex-1 border-none bg-transparent outline-none",
645
+ isTouch ? "text-m-body" : "text-[13px]"
646
+ ),
583
647
  ...props
584
648
  }
585
649
  ),
586
- shortcut && /* @__PURE__ */ jsx9("kbd", { className: "text-text-dim border-border rounded-xs border px-[6px] py-[2px] font-mono text-[10px]", children: shortcut })
650
+ resolvedShortcut && /* @__PURE__ */ jsx9("kbd", { className: "text-text-dim border-border rounded-xs border px-[6px] py-[2px] font-mono text-[10px]", children: resolvedShortcut })
587
651
  ]
588
652
  }
589
653
  );
@@ -917,14 +981,26 @@ import * as RadixSwitch from "@radix-ui/react-switch";
917
981
  import { forwardRef as forwardRef13, useId as useId5 } from "react";
918
982
  import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
919
983
  var trackClasses = {
920
- sm: "h-4 w-7",
921
- md: "h-5 w-9"
984
+ comfortable: {
985
+ sm: "h-4 w-7",
986
+ md: "h-5 w-9"
987
+ },
988
+ touch: {
989
+ sm: "h-[26px] w-[44px]",
990
+ md: "h-[30px] w-[50px]"
991
+ }
922
992
  };
923
993
  var thumbClasses = {
924
- sm: "h-3 w-3 data-[state=checked]:translate-x-3",
925
- md: "h-4 w-4 data-[state=checked]:translate-x-4"
994
+ comfortable: {
995
+ sm: "h-3 w-3 data-[state=checked]:translate-x-3",
996
+ md: "h-4 w-4 data-[state=checked]:translate-x-4"
997
+ },
998
+ touch: {
999
+ sm: "h-[22px] w-[22px] data-[state=checked]:translate-x-[18px]",
1000
+ md: "h-[26px] w-[26px] data-[state=checked]:translate-x-5"
1001
+ }
926
1002
  };
927
- var Switch = forwardRef13(function Switch2({ label, size = "md", className, id: idProp, ...props }, ref) {
1003
+ var Switch = forwardRef13(function Switch2({ label, size = "md", density = "comfortable", className, id: idProp, ...props }, ref) {
928
1004
  const reactId = useId5();
929
1005
  const id = idProp ?? `sw-${reactId}`;
930
1006
  return /* @__PURE__ */ jsxs11(
@@ -946,7 +1022,7 @@ var Switch = forwardRef13(function Switch2({ label, size = "md", className, id:
946
1022
  "bg-panel-2 border-border data-[state=checked]:bg-accent data-[state=checked]:border-accent",
947
1023
  "focus-visible:ring-accent-dim outline-none focus-visible:ring-[3px]",
948
1024
  "disabled:cursor-not-allowed",
949
- trackClasses[size]
1025
+ trackClasses[density][size]
950
1026
  ),
951
1027
  ...props,
952
1028
  children: /* @__PURE__ */ jsx14(
@@ -955,13 +1031,20 @@ var Switch = forwardRef13(function Switch2({ label, size = "md", className, id:
955
1031
  className: cn(
956
1032
  "bg-text absolute top-1/2 left-[1px] -translate-y-1/2 rounded-full shadow-sm",
957
1033
  "data-[state=checked]:bg-on-accent transition-transform duration-(--duration-micro)",
958
- thumbClasses[size]
1034
+ thumbClasses[density][size]
959
1035
  )
960
1036
  }
961
1037
  )
962
1038
  }
963
1039
  ),
964
- label && /* @__PURE__ */ jsx14("label", { htmlFor: id, className: "cursor-pointer text-[13px]", children: label })
1040
+ label && /* @__PURE__ */ jsx14(
1041
+ "label",
1042
+ {
1043
+ htmlFor: id,
1044
+ className: cn("cursor-pointer", density === "touch" ? "text-m-body" : "text-[13px]"),
1045
+ children: label
1046
+ }
1047
+ )
965
1048
  ]
966
1049
  }
967
1050
  );
@@ -1229,7 +1312,7 @@ import { cva as cva6 } from "class-variance-authority";
1229
1312
  import { forwardRef as forwardRef19 } from "react";
1230
1313
  import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
1231
1314
  var cardStyles = cva6(
1232
- "block bg-panel border border-border rounded-base transition-[border-color,transform,box-shadow] duration-(--duration-step)",
1315
+ "block bg-panel border border-border transition-[border-color,transform,box-shadow] duration-(--duration-step)",
1233
1316
  {
1234
1317
  variants: {
1235
1318
  variant: {
@@ -1240,14 +1323,19 @@ var cardStyles = cva6(
1240
1323
  interactive: {
1241
1324
  true: "cursor-pointer hover:border-border-strong hover:-translate-y-px hover:shadow",
1242
1325
  false: ""
1326
+ },
1327
+ density: {
1328
+ comfortable: "rounded-base",
1329
+ touch: "rounded-m-card"
1243
1330
  }
1244
1331
  },
1245
- defaultVariants: { variant: "default", interactive: false }
1332
+ defaultVariants: { variant: "default", interactive: false, density: "comfortable" }
1246
1333
  }
1247
1334
  );
1248
1335
  var Card = forwardRef19(function Card2({
1249
1336
  variant,
1250
1337
  interactive,
1338
+ density,
1251
1339
  title,
1252
1340
  description,
1253
1341
  actions,
@@ -1284,7 +1372,11 @@ var Card = forwardRef19(function Card2({
1284
1372
  onKeyDown: handleKeyDown,
1285
1373
  role: isInteractive ? "button" : void 0,
1286
1374
  tabIndex: isInteractive ? 0 : void 0,
1287
- className: cn(cardStyles({ variant, interactive: wantsInteractive }), "p-[18px]", className),
1375
+ className: cn(
1376
+ cardStyles({ variant, interactive: wantsInteractive, density }),
1377
+ density === "touch" ? "p-4" : "p-[18px]",
1378
+ className
1379
+ ),
1288
1380
  ...props,
1289
1381
  children: [
1290
1382
  (title || actions) && /* @__PURE__ */ jsxs16("div", { className: cn("flex items-start gap-3", (description || children) && "mb-[10px]"), children: [
@@ -1299,15 +1391,16 @@ var Card = forwardRef19(function Card2({
1299
1391
  );
1300
1392
  });
1301
1393
  Card.displayName = "Card";
1302
- var CardLink = forwardRef19(function CardLink2({ variant, title, description, footer, className, children, href, ...props }, ref) {
1394
+ var CardLink = forwardRef19(function CardLink2({ variant, density, title, description, footer, className, children, href, ...props }, ref) {
1303
1395
  return /* @__PURE__ */ jsxs16(
1304
1396
  "a",
1305
1397
  {
1306
1398
  ref,
1307
1399
  href,
1308
1400
  className: cn(
1309
- cardStyles({ variant, interactive: true }),
1310
- "focus-visible:ring-accent-dim p-[18px] no-underline outline-none focus-visible:ring-[3px]",
1401
+ cardStyles({ variant, interactive: true, density }),
1402
+ "focus-visible:ring-accent-dim no-underline outline-none focus-visible:ring-[3px]",
1403
+ density === "touch" ? "p-4" : "p-[18px]",
1311
1404
  className
1312
1405
  ),
1313
1406
  ...props,
@@ -1358,19 +1451,21 @@ StatCard.displayName = "StatCard";
1358
1451
  // src/components/Chip/Chip.tsx
1359
1452
  import { forwardRef as forwardRef21 } from "react";
1360
1453
  import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
1361
- var Chip = forwardRef21(function Chip2({ icon, onRemove, className, children, ...props }, ref) {
1454
+ var Chip = forwardRef21(function Chip2({ icon, onRemove, density = "comfortable", className, children, ...props }, ref) {
1455
+ const isTouch = density === "touch";
1362
1456
  return /* @__PURE__ */ jsxs18(
1363
1457
  "span",
1364
1458
  {
1365
1459
  ref,
1366
1460
  className: cn(
1367
- "inline-flex h-[26px] items-center gap-[6px] py-[4px] pr-1 pl-[10px] font-sans text-[12px]",
1461
+ "inline-flex items-center gap-[6px] font-sans",
1462
+ isTouch ? "text-m-mono h-8 py-[5px] pr-[6px] pl-3" : "h-[26px] py-[4px] pr-1 pl-[10px] text-[12px]",
1368
1463
  "bg-panel-2 text-text border-border rounded-full border",
1369
1464
  className
1370
1465
  ),
1371
1466
  ...props,
1372
1467
  children: [
1373
- icon && /* @__PURE__ */ jsx22("span", { className: "text-text-dim inline-flex text-[10px]", children: icon }),
1468
+ icon && /* @__PURE__ */ jsx22("span", { className: cn("text-text-dim inline-flex", isTouch ? "text-[12px]" : "text-[10px]"), children: icon }),
1374
1469
  children,
1375
1470
  onRemove && /* @__PURE__ */ jsx22(
1376
1471
  "button",
@@ -1378,7 +1473,10 @@ var Chip = forwardRef21(function Chip2({ icon, onRemove, className, children, ..
1378
1473
  type: "button",
1379
1474
  onClick: onRemove,
1380
1475
  "aria-label": "Remove",
1381
- className: "bg-panel text-text-dim hover:text-text grid h-[18px] w-[18px] place-items-center rounded-full text-[10px] leading-none",
1476
+ className: cn(
1477
+ "bg-panel text-text-dim hover:text-text grid place-items-center rounded-full leading-none",
1478
+ isTouch ? "h-[22px] w-[22px] text-[12px]" : "h-[18px] w-[18px] text-[10px]"
1479
+ ),
1382
1480
  children: "\xD7"
1383
1481
  }
1384
1482
  )
@@ -1681,8 +1779,9 @@ import * as RadixDialog2 from "@radix-ui/react-dialog";
1681
1779
  import { forwardRef as forwardRef28 } from "react";
1682
1780
  import { jsx as jsx29, jsxs as jsxs23 } from "react/jsx-runtime";
1683
1781
  var sideClasses = {
1684
- left: "left-0 border-r border-border-strong data-[state=open]:animate-[ship-slide-in-left_220ms_var(--easing-out)]",
1685
- right: "right-0 border-l border-border-strong data-[state=open]:animate-[ship-slide-in-right_220ms_var(--easing-out)]"
1782
+ left: "top-0 bottom-0 left-0 border-r border-border-strong data-[state=open]:animate-[ship-slide-in-left_220ms_var(--easing-out)]",
1783
+ right: "top-0 bottom-0 right-0 border-l border-border-strong data-[state=open]:animate-[ship-slide-in-right_220ms_var(--easing-out)]",
1784
+ bottom: "bottom-0 left-0 right-0 border-t border-border-strong rounded-t-m-sheet data-[state=open]:animate-[ship-slide-in-bottom_240ms_var(--easing-out)]"
1686
1785
  };
1687
1786
  var DrawerHeader = ({ title, onClose }) => /* @__PURE__ */ jsxs23("div", { className: "border-border flex items-center justify-between border-b p-[16px] px-5", children: [
1688
1787
  /* @__PURE__ */ jsx29(RadixDialog2.Title, { className: "text-[14px] font-medium", children: title }),
@@ -1696,7 +1795,12 @@ var DrawerHeader = ({ title, onClose }) => /* @__PURE__ */ jsxs23("div", { class
1696
1795
  }
1697
1796
  )
1698
1797
  ] });
1699
- var Drawer = forwardRef28(function Drawer2({ side = "right", title, width = 420, children, ...rootProps }, ref) {
1798
+ var SheetHeader = ({ title }) => /* @__PURE__ */ jsx29("div", { className: "px-5 pb-3", children: /* @__PURE__ */ jsx29(RadixDialog2.Title, { className: "text-m-body-lg font-semibold tracking-tight", children: title }) });
1799
+ var DragHandle = () => /* @__PURE__ */ jsx29("div", { className: "flex justify-center pt-3 pb-2", "aria-hidden": true, children: /* @__PURE__ */ jsx29("span", { className: "bg-border-strong h-1 w-9 rounded-full" }) });
1800
+ var Drawer = forwardRef28(function Drawer2({ side = "right", title, width = 420, height = "85vh", handle, children, ...rootProps }, ref) {
1801
+ const isBottom = side === "bottom";
1802
+ const showHandle = isBottom && (handle ?? true);
1803
+ const dimensionStyle = isBottom ? { height } : { width };
1700
1804
  return /* @__PURE__ */ jsx29(DialogRoot, { ...rootProps, children: /* @__PURE__ */ jsxs23(DialogPortal, { children: [
1701
1805
  /* @__PURE__ */ jsx29(DialogOverlay, {}),
1702
1806
  /* @__PURE__ */ jsxs23(
@@ -1705,13 +1809,14 @@ var Drawer = forwardRef28(function Drawer2({ side = "right", title, width = 420,
1705
1809
  ref,
1706
1810
  "aria-describedby": void 0,
1707
1811
  className: cn(
1708
- "bg-panel z-modal fixed top-0 bottom-0 flex flex-col shadow-lg outline-none",
1812
+ "bg-panel z-modal fixed flex flex-col shadow-lg outline-none",
1709
1813
  sideClasses[side]
1710
1814
  ),
1711
- style: { width },
1815
+ style: dimensionStyle,
1712
1816
  children: [
1713
- title ? /* @__PURE__ */ jsx29(DrawerHeader, { title }) : /* @__PURE__ */ jsx29(RadixDialog2.Title, { className: "sr-only", children: "Drawer" }),
1714
- /* @__PURE__ */ jsx29("div", { className: "flex-1 overflow-auto p-5", children })
1817
+ showHandle && /* @__PURE__ */ jsx29(DragHandle, {}),
1818
+ title ? isBottom ? /* @__PURE__ */ jsx29(SheetHeader, { title }) : /* @__PURE__ */ jsx29(DrawerHeader, { title }) : /* @__PURE__ */ jsx29(RadixDialog2.Title, { className: "sr-only", children: isBottom ? "Sheet" : "Drawer" }),
1819
+ /* @__PURE__ */ jsx29("div", { className: cn("flex-1 overflow-auto", isBottom ? "px-5 pb-6" : "p-5"), children })
1715
1820
  ]
1716
1821
  }
1717
1822
  )
@@ -2045,7 +2150,7 @@ import * as RadixTooltip from "@radix-ui/react-tooltip";
2045
2150
  import { forwardRef as forwardRef35 } from "react";
2046
2151
  import { jsx as jsx36, jsxs as jsxs29 } from "react/jsx-runtime";
2047
2152
  var TooltipProvider = RadixTooltip.Provider;
2048
- var TooltipRoot = RadixTooltip.Root;
2153
+ var Tooltip = RadixTooltip.Root;
2049
2154
  var TooltipTrigger = RadixTooltip.Trigger;
2050
2155
  var TooltipPortal = RadixTooltip.Portal;
2051
2156
  var TooltipArrow = RadixTooltip.Arrow;
@@ -2068,8 +2173,13 @@ var TooltipContent = forwardRef35(
2068
2173
  }
2069
2174
  );
2070
2175
  TooltipContent.displayName = "TooltipContent";
2071
- function Tooltip({ content, children, side = "top", delayDuration = 400 }) {
2072
- return /* @__PURE__ */ jsx36(TooltipProvider, { delayDuration, children: /* @__PURE__ */ jsxs29(TooltipRoot, { children: [
2176
+ function SimpleTooltip({
2177
+ content,
2178
+ children,
2179
+ side = "top",
2180
+ delayDuration = 400
2181
+ }) {
2182
+ return /* @__PURE__ */ jsx36(TooltipProvider, { delayDuration, children: /* @__PURE__ */ jsxs29(Tooltip, { children: [
2073
2183
  /* @__PURE__ */ jsx36(TooltipTrigger, { asChild: true, children }),
2074
2184
  /* @__PURE__ */ jsx36(TooltipContent, { side, children: content })
2075
2185
  ] }) });
@@ -3612,12 +3722,34 @@ var HealthScore = forwardRef49(function HealthScore2({
3612
3722
  });
3613
3723
  HealthScore.displayName = "HealthScore";
3614
3724
 
3615
- // src/patterns/Menubar/Menubar.tsx
3616
- import * as RadixMenubar from "@radix-ui/react-menubar";
3725
+ // src/patterns/LargeTitle/LargeTitle.tsx
3617
3726
  import { forwardRef as forwardRef50 } from "react";
3618
3727
  import { jsx as jsx52, jsxs as jsxs44 } from "react/jsx-runtime";
3619
- var Menubar = forwardRef50(function Menubar2({ className, ...props }, ref) {
3620
- return /* @__PURE__ */ jsx52(
3728
+ var LargeTitle = forwardRef50(function LargeTitle2({ title, eyebrow, trailing, className, ...props }, ref) {
3729
+ return /* @__PURE__ */ jsxs44(
3730
+ "header",
3731
+ {
3732
+ ref,
3733
+ className: cn("px-screen flex items-end justify-between gap-3 py-3 pb-4", className),
3734
+ ...props,
3735
+ children: [
3736
+ /* @__PURE__ */ jsxs44("div", { className: "min-w-0 flex-1", children: [
3737
+ eyebrow && /* @__PURE__ */ jsx52("div", { className: "text-m-eyebrow text-accent mb-[6px] font-mono tracking-wide uppercase", children: eyebrow }),
3738
+ /* @__PURE__ */ jsx52("h1", { className: "text-m-h1 m-0 truncate leading-tight font-medium tracking-tight", children: title })
3739
+ ] }),
3740
+ trailing && /* @__PURE__ */ jsx52("div", { className: "shrink-0", children: trailing })
3741
+ ]
3742
+ }
3743
+ );
3744
+ });
3745
+ LargeTitle.displayName = "LargeTitle";
3746
+
3747
+ // src/patterns/Menubar/Menubar.tsx
3748
+ import * as RadixMenubar from "@radix-ui/react-menubar";
3749
+ import { forwardRef as forwardRef51 } from "react";
3750
+ import { jsx as jsx53, jsxs as jsxs45 } from "react/jsx-runtime";
3751
+ var Menubar = forwardRef51(function Menubar2({ className, ...props }, ref) {
3752
+ return /* @__PURE__ */ jsx53(
3621
3753
  RadixMenubar.Root,
3622
3754
  {
3623
3755
  ref,
@@ -3631,9 +3763,9 @@ var Menubar = forwardRef50(function Menubar2({ className, ...props }, ref) {
3631
3763
  });
3632
3764
  Menubar.displayName = "Menubar";
3633
3765
  var MenubarMenu = RadixMenubar.Menu;
3634
- var MenubarTrigger = forwardRef50(
3766
+ var MenubarTrigger = forwardRef51(
3635
3767
  function MenubarTrigger2({ className, ...props }, ref) {
3636
- return /* @__PURE__ */ jsx52(
3768
+ return /* @__PURE__ */ jsx53(
3637
3769
  RadixMenubar.Trigger,
3638
3770
  {
3639
3771
  ref,
@@ -3650,9 +3782,9 @@ var MenubarTrigger = forwardRef50(
3650
3782
  }
3651
3783
  );
3652
3784
  MenubarTrigger.displayName = "MenubarTrigger";
3653
- var MenubarContent = forwardRef50(
3785
+ var MenubarContent = forwardRef51(
3654
3786
  function MenubarContent2({ className, sideOffset = 6, align = "start", ...props }, ref) {
3655
- return /* @__PURE__ */ jsx52(RadixMenubar.Portal, { children: /* @__PURE__ */ jsx52(
3787
+ return /* @__PURE__ */ jsx53(RadixMenubar.Portal, { children: /* @__PURE__ */ jsx53(
3656
3788
  RadixMenubar.Content,
3657
3789
  {
3658
3790
  ref,
@@ -3674,24 +3806,24 @@ var itemBase3 = cn(
3674
3806
  "data-[highlighted]:bg-panel-2",
3675
3807
  "data-[disabled]:opacity-40 data-[disabled]:cursor-not-allowed"
3676
3808
  );
3677
- var MenubarItem = forwardRef50(function MenubarItem2({ trailing, destructive, className, children, ...props }, ref) {
3678
- return /* @__PURE__ */ jsxs44(
3809
+ var MenubarItem = forwardRef51(function MenubarItem2({ trailing, destructive, className, children, ...props }, ref) {
3810
+ return /* @__PURE__ */ jsxs45(
3679
3811
  RadixMenubar.Item,
3680
3812
  {
3681
3813
  ref,
3682
3814
  className: cn(itemBase3, destructive ? "text-err" : "text-text", className),
3683
3815
  ...props,
3684
3816
  children: [
3685
- /* @__PURE__ */ jsx52("span", { className: "flex-1", children }),
3686
- trailing && /* @__PURE__ */ jsx52("span", { className: "text-text-dim font-mono text-[10px]", children: trailing })
3817
+ /* @__PURE__ */ jsx53("span", { className: "flex-1", children }),
3818
+ trailing && /* @__PURE__ */ jsx53("span", { className: "text-text-dim font-mono text-[10px]", children: trailing })
3687
3819
  ]
3688
3820
  }
3689
3821
  );
3690
3822
  });
3691
3823
  MenubarItem.displayName = "MenubarItem";
3692
- var MenubarSeparator = forwardRef50(
3824
+ var MenubarSeparator = forwardRef51(
3693
3825
  function MenubarSeparator2({ className, ...props }, ref) {
3694
- return /* @__PURE__ */ jsx52(
3826
+ return /* @__PURE__ */ jsx53(
3695
3827
  RadixMenubar.Separator,
3696
3828
  {
3697
3829
  ref,
@@ -3706,7 +3838,7 @@ MenubarSeparator.displayName = "MenubarSeparator";
3706
3838
  // src/patterns/NavBar/NavBar.tsx
3707
3839
  import * as RadixNav from "@radix-ui/react-navigation-menu";
3708
3840
  import {
3709
- forwardRef as forwardRef52,
3841
+ forwardRef as forwardRef53,
3710
3842
  useCallback as useCallback10,
3711
3843
  useEffect as useEffect9,
3712
3844
  useRef as useRef7,
@@ -3715,13 +3847,13 @@ import {
3715
3847
 
3716
3848
  // src/patterns/Sidebar/Sidebar.tsx
3717
3849
  import {
3718
- forwardRef as forwardRef51,
3850
+ forwardRef as forwardRef52,
3719
3851
  useCallback as useCallback9,
3720
3852
  useState as useState13
3721
3853
  } from "react";
3722
- import { Fragment as Fragment2, jsx as jsx53, jsxs as jsxs45 } from "react/jsx-runtime";
3723
- var Sidebar = forwardRef51(function Sidebar2({ width = 240, className, style, ...props }, ref) {
3724
- return /* @__PURE__ */ jsx53(
3854
+ import { Fragment as Fragment2, jsx as jsx54, jsxs as jsxs46 } from "react/jsx-runtime";
3855
+ var Sidebar = forwardRef52(function Sidebar2({ width = 240, className, style, ...props }, ref) {
3856
+ return /* @__PURE__ */ jsx54(
3725
3857
  "aside",
3726
3858
  {
3727
3859
  ref,
@@ -3735,12 +3867,12 @@ var Sidebar = forwardRef51(function Sidebar2({ width = 240, className, style, ..
3735
3867
  );
3736
3868
  });
3737
3869
  Sidebar.displayName = "Sidebar";
3738
- var NavItem = forwardRef51(
3870
+ var NavItem = forwardRef52(
3739
3871
  function NavItem2({ icon, label, active, badge, href, disabled, className, ...props }, ref) {
3740
- const inner = /* @__PURE__ */ jsxs45(Fragment2, { children: [
3741
- icon && /* @__PURE__ */ jsx53("span", { "aria-hidden": true, className: "w-[14px] text-center opacity-80", children: icon }),
3742
- /* @__PURE__ */ jsx53("span", { className: "flex-1 truncate", children: label }),
3743
- badge != null && /* @__PURE__ */ jsx53(
3872
+ const inner = /* @__PURE__ */ jsxs46(Fragment2, { children: [
3873
+ icon && /* @__PURE__ */ jsx54("span", { "aria-hidden": true, className: "w-[14px] text-center opacity-80", children: icon }),
3874
+ /* @__PURE__ */ jsx54("span", { className: "flex-1 truncate", children: label }),
3875
+ badge != null && /* @__PURE__ */ jsx54(
3744
3876
  "span",
3745
3877
  {
3746
3878
  className: cn(
@@ -3761,7 +3893,7 @@ var NavItem = forwardRef51(
3761
3893
  );
3762
3894
  if (href) {
3763
3895
  const anchorProps = props;
3764
- return /* @__PURE__ */ jsx53(
3896
+ return /* @__PURE__ */ jsx54(
3765
3897
  "a",
3766
3898
  {
3767
3899
  ref,
@@ -3775,7 +3907,7 @@ var NavItem = forwardRef51(
3775
3907
  );
3776
3908
  }
3777
3909
  const buttonProps = props;
3778
- return /* @__PURE__ */ jsx53(
3910
+ return /* @__PURE__ */ jsx54(
3779
3911
  "button",
3780
3912
  {
3781
3913
  ref,
@@ -3790,7 +3922,7 @@ var NavItem = forwardRef51(
3790
3922
  }
3791
3923
  );
3792
3924
  NavItem.displayName = "NavItem";
3793
- var NavSection = forwardRef51(function NavSection2({
3925
+ var NavSection = forwardRef52(function NavSection2({
3794
3926
  label,
3795
3927
  icon,
3796
3928
  action,
@@ -3812,8 +3944,8 @@ var NavSection = forwardRef51(function NavSection2({
3812
3944
  onOpenChange?.(next);
3813
3945
  }, [isOpen, isControlled, onOpenChange]);
3814
3946
  const eyebrowClass = "text-text-dim flex items-center gap-[6px] px-2 pt-2 font-mono text-[9px] tracking-[1.4px] uppercase";
3815
- return /* @__PURE__ */ jsxs45("div", { ref, className: cn("flex flex-col gap-1", className), ...props, children: [
3816
- collapsible ? /* @__PURE__ */ jsxs45(
3947
+ return /* @__PURE__ */ jsxs46("div", { ref, className: cn("flex flex-col gap-1", className), ...props, children: [
3948
+ collapsible ? /* @__PURE__ */ jsxs46(
3817
3949
  "button",
3818
3950
  {
3819
3951
  type: "button",
@@ -3826,18 +3958,18 @@ var NavSection = forwardRef51(function NavSection2({
3826
3958
  "hover:text-text-muted"
3827
3959
  ),
3828
3960
  children: [
3829
- icon != null && /* @__PURE__ */ jsx53("span", { "aria-hidden": true, className: "opacity-80", children: icon }),
3830
- /* @__PURE__ */ jsx53("span", { className: "flex-1 text-left", children: label }),
3961
+ icon != null && /* @__PURE__ */ jsx54("span", { "aria-hidden": true, className: "opacity-80", children: icon }),
3962
+ /* @__PURE__ */ jsx54("span", { className: "flex-1 text-left", children: label }),
3831
3963
  action,
3832
- /* @__PURE__ */ jsx53("span", { "aria-hidden": true, className: "text-[10px] opacity-70", children: isOpen ? "\u25BE" : "\u25B8" })
3964
+ /* @__PURE__ */ jsx54("span", { "aria-hidden": true, className: "text-[10px] opacity-70", children: isOpen ? "\u25BE" : "\u25B8" })
3833
3965
  ]
3834
3966
  }
3835
- ) : /* @__PURE__ */ jsxs45("div", { className: eyebrowClass, children: [
3836
- icon != null && /* @__PURE__ */ jsx53("span", { "aria-hidden": true, className: "opacity-80", children: icon }),
3837
- /* @__PURE__ */ jsx53("span", { className: "flex-1", children: label }),
3967
+ ) : /* @__PURE__ */ jsxs46("div", { className: eyebrowClass, children: [
3968
+ icon != null && /* @__PURE__ */ jsx54("span", { "aria-hidden": true, className: "opacity-80", children: icon }),
3969
+ /* @__PURE__ */ jsx54("span", { className: "flex-1", children: label }),
3838
3970
  action
3839
3971
  ] }),
3840
- isOpen && /* @__PURE__ */ jsx53(
3972
+ isOpen && /* @__PURE__ */ jsx54(
3841
3973
  "div",
3842
3974
  {
3843
3975
  className: cn("flex flex-col gap-[2px]", indent > 0 && "border-border ml-2 border-l"),
@@ -3850,12 +3982,12 @@ var NavSection = forwardRef51(function NavSection2({
3850
3982
  NavSection.displayName = "NavSection";
3851
3983
 
3852
3984
  // src/patterns/NavBar/NavBar.tsx
3853
- import { Fragment as Fragment3, jsx as jsx54, jsxs as jsxs46 } from "react/jsx-runtime";
3985
+ import { Fragment as Fragment3, jsx as jsx55, jsxs as jsxs47 } from "react/jsx-runtime";
3854
3986
  function isActiveTree(item, activeId) {
3855
3987
  if (item.id === activeId) return true;
3856
3988
  return item.children?.some((c) => isActiveTree(c, activeId)) ?? false;
3857
3989
  }
3858
- var NavBar = forwardRef52(function NavBar2({
3990
+ var NavBar = forwardRef53(function NavBar2({
3859
3991
  orientation = "horizontal",
3860
3992
  items,
3861
3993
  brand,
@@ -3891,7 +4023,7 @@ var NavBar = forwardRef52(function NavBar2({
3891
4023
  // drawer is open on a viewport that's resizing past `md`, both navs can
3892
4024
  // sit in the DOM together. Identical accessible names would trip axe's
3893
4025
  // `landmark-unique` rule.
3894
- /* @__PURE__ */ jsx54("nav", { "aria-label": "Mobile navigation", className: "flex flex-col gap-1", children: items.map((item) => /* @__PURE__ */ jsx54(
4026
+ /* @__PURE__ */ jsx55("nav", { "aria-label": "Mobile navigation", className: "flex flex-col gap-1", children: items.map((item) => /* @__PURE__ */ jsx55(
3895
4027
  VerticalItem,
3896
4028
  {
3897
4029
  item,
@@ -3901,14 +4033,14 @@ var NavBar = forwardRef52(function NavBar2({
3901
4033
  item.id
3902
4034
  )) })
3903
4035
  );
3904
- const mobileBar = responsive ? /* @__PURE__ */ jsxs46(
4036
+ const mobileBar = responsive ? /* @__PURE__ */ jsxs47(
3905
4037
  "div",
3906
4038
  {
3907
4039
  className: cn(
3908
4040
  "border-border bg-panel z-overlay sticky top-0 flex h-[52px] items-center gap-4 border-b px-5 md:hidden"
3909
4041
  ),
3910
4042
  children: [
3911
- /* @__PURE__ */ jsx54(
4043
+ /* @__PURE__ */ jsx55(
3912
4044
  "button",
3913
4045
  {
3914
4046
  type: "button",
@@ -3918,15 +4050,15 @@ var NavBar = forwardRef52(function NavBar2({
3918
4050
  children: "\u2630"
3919
4051
  }
3920
4052
  ),
3921
- brand && /* @__PURE__ */ jsx54("div", { className: "flex flex-1 items-center text-[13px] font-medium whitespace-nowrap", children: brand }),
3922
- actions && /* @__PURE__ */ jsx54("div", { className: "flex items-center gap-3", children: actions })
4053
+ brand && /* @__PURE__ */ jsx55("div", { className: "flex flex-1 items-center text-[13px] font-medium whitespace-nowrap", children: brand }),
4054
+ actions && /* @__PURE__ */ jsx55("div", { className: "flex items-center gap-3", children: actions })
3923
4055
  ]
3924
4056
  }
3925
4057
  ) : null;
3926
4058
  if (orientation === "horizontal") {
3927
- return /* @__PURE__ */ jsxs46(Fragment3, { children: [
4059
+ return /* @__PURE__ */ jsxs47(Fragment3, { children: [
3928
4060
  mobileBar,
3929
- /* @__PURE__ */ jsxs46(
4061
+ /* @__PURE__ */ jsxs47(
3930
4062
  "header",
3931
4063
  {
3932
4064
  ref,
@@ -3937,10 +4069,10 @@ var NavBar = forwardRef52(function NavBar2({
3937
4069
  ),
3938
4070
  ...props,
3939
4071
  children: [
3940
- brand && /* @__PURE__ */ jsx54("div", { className: "shrink-0 text-[13px] font-medium whitespace-nowrap", children: brand }),
3941
- /* @__PURE__ */ jsxs46(RadixNav.Root, { className: "relative flex-1", delayDuration: 120, children: [
3942
- /* @__PURE__ */ jsx54(RadixNav.List, { className: "m-0! flex list-none! items-center gap-1 p-0! [&_li]:m-0!", children: items.map(
3943
- (item) => item.children?.length ? /* @__PURE__ */ jsx54(
4072
+ brand && /* @__PURE__ */ jsx55("div", { className: "shrink-0 text-[13px] font-medium whitespace-nowrap", children: brand }),
4073
+ /* @__PURE__ */ jsxs47(RadixNav.Root, { className: "relative flex-1", delayDuration: 120, children: [
4074
+ /* @__PURE__ */ jsx55(RadixNav.List, { className: "m-0! flex list-none! items-center gap-1 p-0! [&_li]:m-0!", children: items.map(
4075
+ (item) => item.children?.length ? /* @__PURE__ */ jsx55(
3944
4076
  HorizontalDropdown,
3945
4077
  {
3946
4078
  item,
@@ -3949,7 +4081,7 @@ var NavBar = forwardRef52(function NavBar2({
3949
4081
  onActivate: handleItemActivate
3950
4082
  },
3951
4083
  item.id
3952
- ) : /* @__PURE__ */ jsx54(RadixNav.Item, { children: /* @__PURE__ */ jsx54(
4084
+ ) : /* @__PURE__ */ jsx55(RadixNav.Item, { children: /* @__PURE__ */ jsx55(
3953
4085
  HorizontalLink,
3954
4086
  {
3955
4087
  item,
@@ -3958,13 +4090,13 @@ var NavBar = forwardRef52(function NavBar2({
3958
4090
  }
3959
4091
  ) }, item.id)
3960
4092
  ) }),
3961
- /* @__PURE__ */ jsx54("div", { className: "z-popover absolute top-full left-0 flex justify-start", children: /* @__PURE__ */ jsx54(RadixNav.Viewport, { className: "origin-top-left data-[state=open]:animate-[ship-fade-in_120ms_var(--easing-out)]" }) })
4093
+ /* @__PURE__ */ jsx55("div", { className: "z-popover absolute top-full left-0 flex justify-start", children: /* @__PURE__ */ jsx55(RadixNav.Viewport, { className: "origin-top-left data-[state=open]:animate-[ship-fade-in_120ms_var(--easing-out)]" }) })
3962
4094
  ] }),
3963
- actions && /* @__PURE__ */ jsx54("div", { className: "flex items-center gap-3", children: actions })
4095
+ actions && /* @__PURE__ */ jsx55("div", { className: "flex items-center gap-3", children: actions })
3964
4096
  ]
3965
4097
  }
3966
4098
  ),
3967
- responsive && /* @__PURE__ */ jsx54(
4099
+ responsive && /* @__PURE__ */ jsx55(
3968
4100
  Drawer,
3969
4101
  {
3970
4102
  open: drawerOpen,
@@ -3977,9 +4109,9 @@ var NavBar = forwardRef52(function NavBar2({
3977
4109
  )
3978
4110
  ] });
3979
4111
  }
3980
- return /* @__PURE__ */ jsxs46(Fragment3, { children: [
4112
+ return /* @__PURE__ */ jsxs47(Fragment3, { children: [
3981
4113
  mobileBar,
3982
- /* @__PURE__ */ jsxs46(
4114
+ /* @__PURE__ */ jsxs47(
3983
4115
  "aside",
3984
4116
  {
3985
4117
  ref,
@@ -3992,8 +4124,8 @@ var NavBar = forwardRef52(function NavBar2({
3992
4124
  ),
3993
4125
  ...props,
3994
4126
  children: [
3995
- brand && /* @__PURE__ */ jsx54("div", { className: "px-2 py-1 text-[13px] font-medium", children: brand }),
3996
- /* @__PURE__ */ jsx54("nav", { "aria-label": "Sidebar navigation", className: "flex flex-1 flex-col gap-1 overflow-y-auto", children: items.map((item) => /* @__PURE__ */ jsx54(
4127
+ brand && /* @__PURE__ */ jsx55("div", { className: "px-2 py-1 text-[13px] font-medium", children: brand }),
4128
+ /* @__PURE__ */ jsx55("nav", { "aria-label": "Sidebar navigation", className: "flex flex-1 flex-col gap-1 overflow-y-auto", children: items.map((item) => /* @__PURE__ */ jsx55(
3997
4129
  VerticalItem,
3998
4130
  {
3999
4131
  item,
@@ -4002,11 +4134,11 @@ var NavBar = forwardRef52(function NavBar2({
4002
4134
  },
4003
4135
  item.id
4004
4136
  )) }),
4005
- actions && /* @__PURE__ */ jsx54("div", { className: "border-border mt-auto flex flex-col gap-2 border-t pt-3", children: actions })
4137
+ actions && /* @__PURE__ */ jsx55("div", { className: "border-border mt-auto flex flex-col gap-2 border-t pt-3", children: actions })
4006
4138
  ]
4007
4139
  }
4008
4140
  ),
4009
- responsive && /* @__PURE__ */ jsx54(
4141
+ responsive && /* @__PURE__ */ jsx55(
4010
4142
  Drawer,
4011
4143
  {
4012
4144
  open: drawerOpen,
@@ -4035,13 +4167,13 @@ function HorizontalLink({ item, active, onActivate }) {
4035
4167
  }
4036
4168
  onActivate(item.id);
4037
4169
  };
4038
- const inner = /* @__PURE__ */ jsxs46(Fragment3, { children: [
4039
- item.icon != null && /* @__PURE__ */ jsx54("span", { "aria-hidden": true, className: "opacity-80", children: item.icon }),
4040
- /* @__PURE__ */ jsx54("span", { children: item.label }),
4041
- item.badge != null && /* @__PURE__ */ jsx54(ItemBadge, { active, children: item.badge })
4170
+ const inner = /* @__PURE__ */ jsxs47(Fragment3, { children: [
4171
+ item.icon != null && /* @__PURE__ */ jsx55("span", { "aria-hidden": true, className: "opacity-80", children: item.icon }),
4172
+ /* @__PURE__ */ jsx55("span", { children: item.label }),
4173
+ item.badge != null && /* @__PURE__ */ jsx55(ItemBadge, { active, children: item.badge })
4042
4174
  ] });
4043
4175
  if (item.href) {
4044
- return /* @__PURE__ */ jsx54(RadixNav.Link, { asChild: true, active, children: /* @__PURE__ */ jsx54(
4176
+ return /* @__PURE__ */ jsx55(RadixNav.Link, { asChild: true, active, children: /* @__PURE__ */ jsx55(
4045
4177
  "a",
4046
4178
  {
4047
4179
  href: item.href,
@@ -4053,7 +4185,7 @@ function HorizontalLink({ item, active, onActivate }) {
4053
4185
  }
4054
4186
  ) });
4055
4187
  }
4056
- return /* @__PURE__ */ jsx54(RadixNav.Link, { asChild: true, active, children: /* @__PURE__ */ jsx54(
4188
+ return /* @__PURE__ */ jsx55(RadixNav.Link, { asChild: true, active, children: /* @__PURE__ */ jsx55(
4057
4189
  "button",
4058
4190
  {
4059
4191
  type: "button",
@@ -4066,8 +4198,8 @@ function HorizontalLink({ item, active, onActivate }) {
4066
4198
  ) });
4067
4199
  }
4068
4200
  function HorizontalDropdown({ item, active, activeId, onActivate }) {
4069
- return /* @__PURE__ */ jsxs46(RadixNav.Item, { children: [
4070
- /* @__PURE__ */ jsxs46(
4201
+ return /* @__PURE__ */ jsxs47(RadixNav.Item, { children: [
4202
+ /* @__PURE__ */ jsxs47(
4071
4203
  RadixNav.Trigger,
4072
4204
  {
4073
4205
  className: cn(
@@ -4079,9 +4211,9 @@ function HorizontalDropdown({ item, active, activeId, onActivate }) {
4079
4211
  ),
4080
4212
  disabled: item.disabled,
4081
4213
  children: [
4082
- item.icon != null && /* @__PURE__ */ jsx54("span", { "aria-hidden": true, className: "opacity-80", children: item.icon }),
4083
- /* @__PURE__ */ jsx54("span", { children: item.label }),
4084
- /* @__PURE__ */ jsx54(
4214
+ item.icon != null && /* @__PURE__ */ jsx55("span", { "aria-hidden": true, className: "opacity-80", children: item.icon }),
4215
+ /* @__PURE__ */ jsx55("span", { children: item.label }),
4216
+ /* @__PURE__ */ jsx55(
4085
4217
  "span",
4086
4218
  {
4087
4219
  "aria-hidden": true,
@@ -4092,7 +4224,7 @@ function HorizontalDropdown({ item, active, activeId, onActivate }) {
4092
4224
  ]
4093
4225
  }
4094
4226
  ),
4095
- /* @__PURE__ */ jsx54(RadixNav.Content, { className: "border-border bg-panel min-w-[220px] rounded-xs border p-2 shadow-lg", children: /* @__PURE__ */ jsx54("ul", { className: "m-0! flex list-none! flex-col gap-[2px] p-0! [&_li]:m-0!", children: item.children.map((child) => /* @__PURE__ */ jsx54("li", { children: /* @__PURE__ */ jsx54(DropdownLink, { item: child, active: child.id === activeId, onActivate }) }, child.id)) }) })
4227
+ /* @__PURE__ */ jsx55(RadixNav.Content, { className: "border-border bg-panel min-w-[220px] rounded-xs border p-2 shadow-lg", children: /* @__PURE__ */ jsx55("ul", { className: "m-0! flex list-none! flex-col gap-[2px] p-0! [&_li]:m-0!", children: item.children.map((child) => /* @__PURE__ */ jsx55("li", { children: /* @__PURE__ */ jsx55(DropdownLink, { item: child, active: child.id === activeId, onActivate }) }, child.id)) }) })
4096
4228
  ] });
4097
4229
  }
4098
4230
  function DropdownLink({ item, active, onActivate }) {
@@ -4109,13 +4241,13 @@ function DropdownLink({ item, active, onActivate }) {
4109
4241
  }
4110
4242
  onActivate(item.id);
4111
4243
  };
4112
- const inner = /* @__PURE__ */ jsxs46(Fragment3, { children: [
4113
- item.icon != null && /* @__PURE__ */ jsx54("span", { "aria-hidden": true, className: "opacity-80", children: item.icon }),
4114
- /* @__PURE__ */ jsx54("span", { className: "flex-1", children: item.label }),
4115
- item.badge != null && /* @__PURE__ */ jsx54(ItemBadge, { active, children: item.badge })
4244
+ const inner = /* @__PURE__ */ jsxs47(Fragment3, { children: [
4245
+ item.icon != null && /* @__PURE__ */ jsx55("span", { "aria-hidden": true, className: "opacity-80", children: item.icon }),
4246
+ /* @__PURE__ */ jsx55("span", { className: "flex-1", children: item.label }),
4247
+ item.badge != null && /* @__PURE__ */ jsx55(ItemBadge, { active, children: item.badge })
4116
4248
  ] });
4117
4249
  if (item.href) {
4118
- return /* @__PURE__ */ jsx54(RadixNav.Link, { asChild: true, active, children: /* @__PURE__ */ jsx54(
4250
+ return /* @__PURE__ */ jsx55(RadixNav.Link, { asChild: true, active, children: /* @__PURE__ */ jsx55(
4119
4251
  "a",
4120
4252
  {
4121
4253
  href: item.href,
@@ -4127,7 +4259,7 @@ function DropdownLink({ item, active, onActivate }) {
4127
4259
  }
4128
4260
  ) });
4129
4261
  }
4130
- return /* @__PURE__ */ jsx54(RadixNav.Link, { asChild: true, active, children: /* @__PURE__ */ jsx54(
4262
+ return /* @__PURE__ */ jsx55(RadixNav.Link, { asChild: true, active, children: /* @__PURE__ */ jsx55(
4131
4263
  "button",
4132
4264
  {
4133
4265
  type: "button",
@@ -4156,7 +4288,7 @@ function VerticalItem({ item, activeId, onActivate }) {
4156
4288
  }
4157
4289
  onActivate(item.id);
4158
4290
  };
4159
- return /* @__PURE__ */ jsx54(
4291
+ return /* @__PURE__ */ jsx55(
4160
4292
  NavItem,
4161
4293
  {
4162
4294
  icon: item.icon,
@@ -4169,8 +4301,8 @@ function VerticalItem({ item, activeId, onActivate }) {
4169
4301
  }
4170
4302
  );
4171
4303
  }
4172
- return /* @__PURE__ */ jsxs46("div", { className: "flex flex-col", children: [
4173
- /* @__PURE__ */ jsxs46(
4304
+ return /* @__PURE__ */ jsxs47("div", { className: "flex flex-col", children: [
4305
+ /* @__PURE__ */ jsxs47(
4174
4306
  "button",
4175
4307
  {
4176
4308
  type: "button",
@@ -4186,18 +4318,18 @@ function VerticalItem({ item, activeId, onActivate }) {
4186
4318
  item.disabled && "pointer-events-none opacity-50"
4187
4319
  ),
4188
4320
  children: [
4189
- item.icon != null && /* @__PURE__ */ jsx54("span", { "aria-hidden": true, className: "w-[14px] text-center opacity-80", children: item.icon }),
4190
- /* @__PURE__ */ jsx54("span", { className: "flex-1 truncate", children: item.label }),
4191
- item.badge != null && /* @__PURE__ */ jsx54(ItemBadge, { active: treeActive, children: item.badge }),
4192
- /* @__PURE__ */ jsx54("span", { "aria-hidden": true, className: "text-[10px] opacity-60", children: open ? "\u25BE" : "\u25B8" })
4321
+ item.icon != null && /* @__PURE__ */ jsx55("span", { "aria-hidden": true, className: "w-[14px] text-center opacity-80", children: item.icon }),
4322
+ /* @__PURE__ */ jsx55("span", { className: "flex-1 truncate", children: item.label }),
4323
+ item.badge != null && /* @__PURE__ */ jsx55(ItemBadge, { active: treeActive, children: item.badge }),
4324
+ /* @__PURE__ */ jsx55("span", { "aria-hidden": true, className: "text-[10px] opacity-60", children: open ? "\u25BE" : "\u25B8" })
4193
4325
  ]
4194
4326
  }
4195
4327
  ),
4196
- open && /* @__PURE__ */ jsx54("div", { className: "border-border mt-1 ml-[18px] flex flex-col gap-[2px] border-l pl-3", children: item.children.map((child) => /* @__PURE__ */ jsx54(VerticalItem, { item: child, activeId, onActivate }, child.id)) })
4328
+ open && /* @__PURE__ */ jsx55("div", { className: "border-border mt-1 ml-[18px] flex flex-col gap-[2px] border-l pl-3", children: item.children.map((child) => /* @__PURE__ */ jsx55(VerticalItem, { item: child, activeId, onActivate }, child.id)) })
4197
4329
  ] });
4198
4330
  }
4199
4331
  function ItemBadge({ active, children }) {
4200
- return /* @__PURE__ */ jsx54(
4332
+ return /* @__PURE__ */ jsx55(
4201
4333
  "span",
4202
4334
  {
4203
4335
  className: cn(
@@ -4210,8 +4342,8 @@ function ItemBadge({ active, children }) {
4210
4342
  }
4211
4343
 
4212
4344
  // src/patterns/OnboardingChecklist/OnboardingChecklist.tsx
4213
- import { forwardRef as forwardRef53 } from "react";
4214
- import { Fragment as Fragment4, jsx as jsx55, jsxs as jsxs47 } from "react/jsx-runtime";
4345
+ import { forwardRef as forwardRef54 } from "react";
4346
+ import { Fragment as Fragment4, jsx as jsx56, jsxs as jsxs48 } from "react/jsx-runtime";
4215
4347
  var statusDot = {
4216
4348
  pending: "off",
4217
4349
  "in-progress": "sync",
@@ -4222,11 +4354,11 @@ var labelStateClass = {
4222
4354
  "in-progress": "text-text",
4223
4355
  done: "text-text-dim line-through"
4224
4356
  };
4225
- var OnboardingChecklist = forwardRef53(
4357
+ var OnboardingChecklist = forwardRef54(
4226
4358
  function OnboardingChecklist2({ items, onItemClick, title = "Get started", progressLabel, hideProgress, className, ...props }, ref) {
4227
4359
  const total = items.length;
4228
4360
  const done = items.filter((i) => i.status === "done").length;
4229
- return /* @__PURE__ */ jsxs47(
4361
+ return /* @__PURE__ */ jsxs48(
4230
4362
  "section",
4231
4363
  {
4232
4364
  ref,
@@ -4237,11 +4369,11 @@ var OnboardingChecklist = forwardRef53(
4237
4369
  ),
4238
4370
  ...props,
4239
4371
  children: [
4240
- /* @__PURE__ */ jsxs47("header", { className: "flex items-center gap-2", children: [
4241
- /* @__PURE__ */ jsx55("span", { className: "text-[14px] font-medium", children: title }),
4242
- /* @__PURE__ */ jsx55("span", { className: "text-text-dim ml-auto font-mono text-[11px] tabular-nums", children: progressLabel ?? `${done} of ${total} complete` })
4372
+ /* @__PURE__ */ jsxs48("header", { className: "flex items-center gap-2", children: [
4373
+ /* @__PURE__ */ jsx56("span", { className: "text-[14px] font-medium", children: title }),
4374
+ /* @__PURE__ */ jsx56("span", { className: "text-text-dim ml-auto font-mono text-[11px] tabular-nums", children: progressLabel ?? `${done} of ${total} complete` })
4243
4375
  ] }),
4244
- !hideProgress && total > 0 && /* @__PURE__ */ jsx55(
4376
+ !hideProgress && total > 0 && /* @__PURE__ */ jsx56(
4245
4377
  "div",
4246
4378
  {
4247
4379
  role: "progressbar",
@@ -4250,7 +4382,7 @@ var OnboardingChecklist = forwardRef53(
4250
4382
  "aria-valuenow": done,
4251
4383
  "aria-label": typeof title === "string" ? `${title} progress` : "Setup progress",
4252
4384
  className: "bg-panel-2 h-[3px] w-full overflow-hidden rounded-full",
4253
- children: /* @__PURE__ */ jsx55(
4385
+ children: /* @__PURE__ */ jsx56(
4254
4386
  "span",
4255
4387
  {
4256
4388
  "aria-hidden": true,
@@ -4263,10 +4395,10 @@ var OnboardingChecklist = forwardRef53(
4263
4395
  )
4264
4396
  }
4265
4397
  ),
4266
- /* @__PURE__ */ jsx55("ul", { className: "m-0 flex list-none flex-col gap-1 p-0", children: items.map((item) => {
4398
+ /* @__PURE__ */ jsx56("ul", { className: "m-0 flex list-none flex-col gap-1 p-0", children: items.map((item) => {
4267
4399
  const interactive = typeof onItemClick === "function";
4268
- const labelBlock = /* @__PURE__ */ jsxs47(Fragment4, { children: [
4269
- /* @__PURE__ */ jsx55(
4400
+ const labelBlock = /* @__PURE__ */ jsxs48(Fragment4, { children: [
4401
+ /* @__PURE__ */ jsx56(
4270
4402
  StatusDot,
4271
4403
  {
4272
4404
  state: statusDot[item.status],
@@ -4275,17 +4407,17 @@ var OnboardingChecklist = forwardRef53(
4275
4407
  className: "mt-[3px]"
4276
4408
  }
4277
4409
  ),
4278
- /* @__PURE__ */ jsxs47("div", { className: "flex min-w-0 flex-1 flex-col gap-[2px]", children: [
4279
- /* @__PURE__ */ jsx55("span", { className: cn("text-[13px]", labelStateClass[item.status]), children: item.label }),
4280
- item.description && /* @__PURE__ */ jsx55("span", { className: "text-text-muted text-[12px] leading-[1.45]", children: item.description })
4410
+ /* @__PURE__ */ jsxs48("div", { className: "flex min-w-0 flex-1 flex-col gap-[2px]", children: [
4411
+ /* @__PURE__ */ jsx56("span", { className: cn("text-[13px]", labelStateClass[item.status]), children: item.label }),
4412
+ item.description && /* @__PURE__ */ jsx56("span", { className: "text-text-muted text-[12px] leading-[1.45]", children: item.description })
4281
4413
  ] })
4282
4414
  ] });
4283
4415
  const labelRegionClass = cn(
4284
4416
  "flex flex-1 items-start gap-3 rounded-md px-2 py-2 text-left transition-colors duration-(--duration-micro)",
4285
4417
  interactive && "cursor-pointer outline-none hover:bg-panel-2 focus-visible:ring-[3px] focus-visible:ring-accent-dim"
4286
4418
  );
4287
- return /* @__PURE__ */ jsxs47("li", { className: "flex items-start gap-2", children: [
4288
- interactive ? /* @__PURE__ */ jsx55(
4419
+ return /* @__PURE__ */ jsxs48("li", { className: "flex items-start gap-2", children: [
4420
+ interactive ? /* @__PURE__ */ jsx56(
4289
4421
  "button",
4290
4422
  {
4291
4423
  type: "button",
@@ -4294,8 +4426,8 @@ var OnboardingChecklist = forwardRef53(
4294
4426
  className: labelRegionClass,
4295
4427
  children: labelBlock
4296
4428
  }
4297
- ) : /* @__PURE__ */ jsx55("div", { className: labelRegionClass, children: labelBlock }),
4298
- item.action && /* @__PURE__ */ jsx55("div", { className: "shrink-0 self-center", children: item.action })
4429
+ ) : /* @__PURE__ */ jsx56("div", { className: labelRegionClass, children: labelBlock }),
4430
+ item.action && /* @__PURE__ */ jsx56("div", { className: "shrink-0 self-center", children: item.action })
4299
4431
  ] }, item.id);
4300
4432
  }) })
4301
4433
  ]
@@ -4306,8 +4438,8 @@ var OnboardingChecklist = forwardRef53(
4306
4438
  OnboardingChecklist.displayName = "OnboardingChecklist";
4307
4439
 
4308
4440
  // src/patterns/Pagination/Pagination.tsx
4309
- import { forwardRef as forwardRef54 } from "react";
4310
- import { jsx as jsx56, jsxs as jsxs48 } from "react/jsx-runtime";
4441
+ import { forwardRef as forwardRef55 } from "react";
4442
+ import { jsx as jsx57, jsxs as jsxs49 } from "react/jsx-runtime";
4311
4443
  function buildRange(page, total, siblings) {
4312
4444
  if (total <= 0) return [];
4313
4445
  const items = [];
@@ -4320,9 +4452,9 @@ function buildRange(page, total, siblings) {
4320
4452
  if (total > 1) items.push(total);
4321
4453
  return items;
4322
4454
  }
4323
- var Pagination = forwardRef54(function Pagination2({ page, total, onPageChange, siblings = 1, className, ...props }, ref) {
4455
+ var Pagination = forwardRef55(function Pagination2({ page, total, onPageChange, siblings = 1, className, ...props }, ref) {
4324
4456
  const items = buildRange(page, total, siblings);
4325
- return /* @__PURE__ */ jsxs48(
4457
+ return /* @__PURE__ */ jsxs49(
4326
4458
  "nav",
4327
4459
  {
4328
4460
  ref,
@@ -4330,7 +4462,7 @@ var Pagination = forwardRef54(function Pagination2({ page, total, onPageChange,
4330
4462
  className: cn("inline-flex items-center gap-1", className),
4331
4463
  ...props,
4332
4464
  children: [
4333
- /* @__PURE__ */ jsx56(
4465
+ /* @__PURE__ */ jsx57(
4334
4466
  IconButton,
4335
4467
  {
4336
4468
  size: "sm",
@@ -4343,7 +4475,7 @@ var Pagination = forwardRef54(function Pagination2({ page, total, onPageChange,
4343
4475
  ),
4344
4476
  items.map((item, i) => {
4345
4477
  if (item === "start-ellipsis" || item === "end-ellipsis") {
4346
- return /* @__PURE__ */ jsx56(
4478
+ return /* @__PURE__ */ jsx57(
4347
4479
  "span",
4348
4480
  {
4349
4481
  "aria-hidden": true,
@@ -4354,7 +4486,7 @@ var Pagination = forwardRef54(function Pagination2({ page, total, onPageChange,
4354
4486
  );
4355
4487
  }
4356
4488
  const isActive = item === page;
4357
- return /* @__PURE__ */ jsx56(
4489
+ return /* @__PURE__ */ jsx57(
4358
4490
  "button",
4359
4491
  {
4360
4492
  type: "button",
@@ -4372,7 +4504,7 @@ var Pagination = forwardRef54(function Pagination2({ page, total, onPageChange,
4372
4504
  item
4373
4505
  );
4374
4506
  }),
4375
- /* @__PURE__ */ jsx56(
4507
+ /* @__PURE__ */ jsx57(
4376
4508
  IconButton,
4377
4509
  {
4378
4510
  size: "sm",
@@ -4391,8 +4523,8 @@ Pagination.displayName = "Pagination";
4391
4523
 
4392
4524
  // src/patterns/Progress/Progress.tsx
4393
4525
  import { cva as cva11 } from "class-variance-authority";
4394
- import { forwardRef as forwardRef55 } from "react";
4395
- import { jsx as jsx57, jsxs as jsxs49 } from "react/jsx-runtime";
4526
+ import { forwardRef as forwardRef56 } from "react";
4527
+ import { jsx as jsx58, jsxs as jsxs50 } from "react/jsx-runtime";
4396
4528
  var trackStyles = cva11("w-full rounded-full bg-panel-2 overflow-hidden", {
4397
4529
  variants: {
4398
4530
  size: {
@@ -4414,7 +4546,7 @@ var fillStyles = cva11("h-full rounded-full transition-[width] duration-(--durat
4414
4546
  },
4415
4547
  defaultVariants: { tone: "accent" }
4416
4548
  });
4417
- var Progress = forwardRef55(function Progress2({
4549
+ var Progress = forwardRef56(function Progress2({
4418
4550
  value = 0,
4419
4551
  max = 100,
4420
4552
  indeterminate = false,
@@ -4428,15 +4560,15 @@ var Progress = forwardRef55(function Progress2({
4428
4560
  const clamped = Math.min(max, Math.max(0, value));
4429
4561
  const pct = max > 0 ? clamped / max * 100 : 0;
4430
4562
  const display = Math.round(pct);
4431
- return /* @__PURE__ */ jsxs49("div", { ref, className: cn("flex w-full flex-col gap-2", className), ...props, children: [
4432
- label != null && /* @__PURE__ */ jsxs49("div", { className: "flex text-[12px]", children: [
4433
- /* @__PURE__ */ jsx57("span", { className: "text-text-muted", children: label }),
4434
- showValue && !indeterminate && /* @__PURE__ */ jsxs49("span", { className: "text-text ml-auto font-mono tabular-nums", children: [
4563
+ return /* @__PURE__ */ jsxs50("div", { ref, className: cn("flex w-full flex-col gap-2", className), ...props, children: [
4564
+ label != null && /* @__PURE__ */ jsxs50("div", { className: "flex text-[12px]", children: [
4565
+ /* @__PURE__ */ jsx58("span", { className: "text-text-muted", children: label }),
4566
+ showValue && !indeterminate && /* @__PURE__ */ jsxs50("span", { className: "text-text ml-auto font-mono tabular-nums", children: [
4435
4567
  display,
4436
4568
  "%"
4437
4569
  ] })
4438
4570
  ] }),
4439
- /* @__PURE__ */ jsx57(
4571
+ /* @__PURE__ */ jsx58(
4440
4572
  "div",
4441
4573
  {
4442
4574
  role: "progressbar",
@@ -4445,7 +4577,7 @@ var Progress = forwardRef55(function Progress2({
4445
4577
  "aria-valuenow": indeterminate ? void 0 : display,
4446
4578
  "aria-label": typeof label === "string" ? label : void 0,
4447
4579
  className: trackStyles({ size }),
4448
- children: indeterminate ? /* @__PURE__ */ jsx57(
4580
+ children: indeterminate ? /* @__PURE__ */ jsx58(
4449
4581
  "span",
4450
4582
  {
4451
4583
  "aria-hidden": true,
@@ -4455,16 +4587,61 @@ var Progress = forwardRef55(function Progress2({
4455
4587
  "animate-[ship-indeterminate_1.4s_linear_infinite]"
4456
4588
  )
4457
4589
  }
4458
- ) : /* @__PURE__ */ jsx57("span", { "aria-hidden": true, className: fillStyles({ tone }), style: { width: `${pct}%` } })
4590
+ ) : /* @__PURE__ */ jsx58("span", { "aria-hidden": true, className: fillStyles({ tone }), style: { width: `${pct}%` } })
4459
4591
  }
4460
4592
  )
4461
4593
  ] });
4462
4594
  });
4463
4595
  Progress.displayName = "Progress";
4464
4596
 
4597
+ // src/patterns/PullToRefresh/PullToRefresh.tsx
4598
+ import { forwardRef as forwardRef57 } from "react";
4599
+ import { jsx as jsx59, jsxs as jsxs51 } from "react/jsx-runtime";
4600
+ var labels = {
4601
+ idle: "Pull to refresh",
4602
+ pulling: "Pull to refresh",
4603
+ ready: "Release to refresh",
4604
+ loading: "Refreshing\u2026"
4605
+ };
4606
+ var PullToRefresh = forwardRef57(function PullToRefresh2({ state = "idle", label, className, ...props }, ref) {
4607
+ const isLoading = state === "loading";
4608
+ const transform = state === "ready" ? "rotate(180deg)" : state === "pulling" ? "rotate(90deg)" : "rotate(0deg)";
4609
+ return /* @__PURE__ */ jsxs51(
4610
+ "div",
4611
+ {
4612
+ ref,
4613
+ role: "status",
4614
+ "aria-live": "polite",
4615
+ "aria-busy": isLoading || void 0,
4616
+ className: cn("text-text-muted flex flex-col items-center gap-[6px] py-3", className),
4617
+ ...props,
4618
+ children: [
4619
+ /* @__PURE__ */ jsx59(
4620
+ "div",
4621
+ {
4622
+ "aria-hidden": true,
4623
+ className: cn(
4624
+ "border-border border-t-accent rounded-full border-2",
4625
+ isLoading && "animate-[ship-spin_700ms_linear_infinite]"
4626
+ ),
4627
+ style: {
4628
+ width: 22,
4629
+ height: 22,
4630
+ transform: isLoading ? void 0 : transform,
4631
+ transition: isLoading ? void 0 : "transform 200ms var(--easing-out)"
4632
+ }
4633
+ }
4634
+ ),
4635
+ /* @__PURE__ */ jsx59("span", { className: "text-m-eyebrow font-mono tracking-wide uppercase", children: label ?? labels[state] })
4636
+ ]
4637
+ }
4638
+ );
4639
+ });
4640
+ PullToRefresh.displayName = "PullToRefresh";
4641
+
4465
4642
  // src/patterns/Sparkline/Sparkline.tsx
4466
- import { forwardRef as forwardRef56, useMemo as useMemo5 } from "react";
4467
- import { jsx as jsx58, jsxs as jsxs50 } from "react/jsx-runtime";
4643
+ import { forwardRef as forwardRef58, useMemo as useMemo5 } from "react";
4644
+ import { jsx as jsx60, jsxs as jsxs52 } from "react/jsx-runtime";
4468
4645
  function buildPath(values, w, h) {
4469
4646
  if (values.length === 0) return { line: "", area: "" };
4470
4647
  const pad = 2;
@@ -4483,7 +4660,7 @@ function buildPath(values, w, h) {
4483
4660
  )} L${pad.toFixed(2)},${(h - pad).toFixed(2)} Z`;
4484
4661
  return { line, area };
4485
4662
  }
4486
- var Sparkline = forwardRef56(function Sparkline2({
4663
+ var Sparkline = forwardRef58(function Sparkline2({
4487
4664
  values,
4488
4665
  width = 160,
4489
4666
  height = 32,
@@ -4495,7 +4672,7 @@ var Sparkline = forwardRef56(function Sparkline2({
4495
4672
  ...props
4496
4673
  }, ref) {
4497
4674
  const { line, area } = useMemo5(() => buildPath(values, width, height), [values, width, height]);
4498
- return /* @__PURE__ */ jsxs50(
4675
+ return /* @__PURE__ */ jsxs52(
4499
4676
  "svg",
4500
4677
  {
4501
4678
  ref,
@@ -4507,8 +4684,8 @@ var Sparkline = forwardRef56(function Sparkline2({
4507
4684
  className: cn("inline-block", className),
4508
4685
  ...props,
4509
4686
  children: [
4510
- fill && /* @__PURE__ */ jsx58("path", { d: area, fill: stroke, fillOpacity: 0.16, stroke: "none" }),
4511
- /* @__PURE__ */ jsx58(
4687
+ fill && /* @__PURE__ */ jsx60("path", { d: area, fill: stroke, fillOpacity: 0.16, stroke: "none" }),
4688
+ /* @__PURE__ */ jsx60(
4512
4689
  "path",
4513
4690
  {
4514
4691
  d: line,
@@ -4526,16 +4703,16 @@ var Sparkline = forwardRef56(function Sparkline2({
4526
4703
  Sparkline.displayName = "Sparkline";
4527
4704
 
4528
4705
  // src/patterns/Spinner/Spinner.tsx
4529
- import { forwardRef as forwardRef57 } from "react";
4530
- import { jsx as jsx59 } from "react/jsx-runtime";
4706
+ import { forwardRef as forwardRef59 } from "react";
4707
+ import { jsx as jsx61 } from "react/jsx-runtime";
4531
4708
  var sizes = {
4532
4709
  sm: { box: "h-3 w-3", border: "border-[2px]" },
4533
4710
  md: { box: "h-4 w-4", border: "border-[2px]" },
4534
4711
  lg: { box: "h-5 w-5", border: "border-[2px]" }
4535
4712
  };
4536
- var Spinner2 = forwardRef57(function Spinner3({ size = "md", label = "Loading", className, ...props }, ref) {
4713
+ var Spinner2 = forwardRef59(function Spinner3({ size = "md", label = "Loading", className, ...props }, ref) {
4537
4714
  const s = sizes[size];
4538
- return /* @__PURE__ */ jsx59(
4715
+ return /* @__PURE__ */ jsx61(
4539
4716
  "span",
4540
4717
  {
4541
4718
  ref,
@@ -4543,7 +4720,7 @@ var Spinner2 = forwardRef57(function Spinner3({ size = "md", label = "Loading",
4543
4720
  "aria-label": label,
4544
4721
  className: cn("inline-block", className),
4545
4722
  ...props,
4546
- children: /* @__PURE__ */ jsx59(
4723
+ children: /* @__PURE__ */ jsx61(
4547
4724
  "span",
4548
4725
  {
4549
4726
  "aria-hidden": true,
@@ -4560,8 +4737,8 @@ var Spinner2 = forwardRef57(function Spinner3({ size = "md", label = "Loading",
4560
4737
  Spinner2.displayName = "Spinner";
4561
4738
 
4562
4739
  // src/patterns/Stepper/Stepper.tsx
4563
- import { forwardRef as forwardRef58, Fragment as Fragment5 } from "react";
4564
- import { jsx as jsx60, jsxs as jsxs51 } from "react/jsx-runtime";
4740
+ import { forwardRef as forwardRef60, Fragment as Fragment5 } from "react";
4741
+ import { jsx as jsx62, jsxs as jsxs53 } from "react/jsx-runtime";
4565
4742
  var dotBase = "h-6 w-6 rounded-full grid place-items-center text-[11px] font-mono font-semibold border";
4566
4743
  var dotStateClass = {
4567
4744
  done: "bg-accent text-on-accent border-accent",
@@ -4578,8 +4755,8 @@ function stateFor(index, current) {
4578
4755
  if (index === current) return "current";
4579
4756
  return "upcoming";
4580
4757
  }
4581
- var Stepper = forwardRef58(function Stepper2({ steps, current, className, ...props }, ref) {
4582
- return /* @__PURE__ */ jsx60(
4758
+ var Stepper = forwardRef60(function Stepper2({ steps, current, className, ...props }, ref) {
4759
+ return /* @__PURE__ */ jsx62(
4583
4760
  "ol",
4584
4761
  {
4585
4762
  ref,
@@ -4591,19 +4768,19 @@ var Stepper = forwardRef58(function Stepper2({ steps, current, className, ...pro
4591
4768
  const id = typeof step === "string" ? void 0 : step.id;
4592
4769
  const state = stateFor(i, current);
4593
4770
  const connectorActive = i < current;
4594
- return /* @__PURE__ */ jsxs51(Fragment5, { children: [
4595
- /* @__PURE__ */ jsxs51(
4771
+ return /* @__PURE__ */ jsxs53(Fragment5, { children: [
4772
+ /* @__PURE__ */ jsxs53(
4596
4773
  "li",
4597
4774
  {
4598
4775
  "aria-current": state === "current" ? "step" : void 0,
4599
4776
  className: "flex items-center gap-2",
4600
4777
  children: [
4601
- /* @__PURE__ */ jsx60("span", { "aria-hidden": true, className: cn(dotBase, dotStateClass[state]), children: state === "done" ? "\u2713" : i + 1 }),
4602
- /* @__PURE__ */ jsx60("span", { className: cn("text-[12px]", labelStateClass2[state]), children: label })
4778
+ /* @__PURE__ */ jsx62("span", { "aria-hidden": true, className: cn(dotBase, dotStateClass[state]), children: state === "done" ? "\u2713" : i + 1 }),
4779
+ /* @__PURE__ */ jsx62("span", { className: cn("text-[12px]", labelStateClass2[state]), children: label })
4603
4780
  ]
4604
4781
  }
4605
4782
  ),
4606
- i < steps.length - 1 && /* @__PURE__ */ jsx60(
4783
+ i < steps.length - 1 && /* @__PURE__ */ jsx62(
4607
4784
  "span",
4608
4785
  {
4609
4786
  "aria-hidden": true,
@@ -4617,11 +4794,113 @@ var Stepper = forwardRef58(function Stepper2({ steps, current, className, ...pro
4617
4794
  });
4618
4795
  Stepper.displayName = "Stepper";
4619
4796
 
4797
+ // src/patterns/TabBar/TabBar.tsx
4798
+ import {
4799
+ forwardRef as forwardRef61,
4800
+ useCallback as useCallback11,
4801
+ useState as useState15
4802
+ } from "react";
4803
+ import { jsx as jsx63, jsxs as jsxs54 } from "react/jsx-runtime";
4804
+ var TabBar = forwardRef61(function TabBar2({ items, value, defaultValue, onValueChange, className, ...props }, ref) {
4805
+ const isControlled = value !== void 0;
4806
+ const [internalValue, setInternalValue] = useState15(defaultValue);
4807
+ const activeId = isControlled ? value : internalValue;
4808
+ const handleSelect = useCallback11(
4809
+ (id, e) => {
4810
+ if (!isControlled) setInternalValue(id);
4811
+ onValueChange?.(id);
4812
+ e.stopPropagation();
4813
+ },
4814
+ [isControlled, onValueChange]
4815
+ );
4816
+ return /* @__PURE__ */ jsx63(
4817
+ "nav",
4818
+ {
4819
+ ref,
4820
+ "aria-label": "Primary",
4821
+ className: cn(
4822
+ "border-border bg-panel h-tabbar grid items-center border-t",
4823
+ "pb-[env(safe-area-inset-bottom)]",
4824
+ className
4825
+ ),
4826
+ style: { gridTemplateColumns: `repeat(${items.length}, minmax(0, 1fr))` },
4827
+ ...props,
4828
+ children: items.map((item) => {
4829
+ const isActive = item.id === activeId;
4830
+ if (item.elevated) {
4831
+ return /* @__PURE__ */ jsx63("div", { className: "grid place-items-center", children: /* @__PURE__ */ jsxs54(
4832
+ "button",
4833
+ {
4834
+ type: "button",
4835
+ "aria-current": isActive ? "page" : void 0,
4836
+ disabled: item.disabled,
4837
+ onClick: (e) => handleSelect(item.id, e),
4838
+ className: cn(
4839
+ "bg-accent text-on-accent grid place-items-center rounded-2xl shadow-lg",
4840
+ "-mt-[10px] h-[52px] w-[52px]",
4841
+ "transition-[filter,transform] duration-(--duration-micro)",
4842
+ "hover:brightness-110 active:scale-95",
4843
+ "focus-visible:ring-accent-dim outline-none focus-visible:ring-[3px]",
4844
+ "disabled:cursor-not-allowed disabled:opacity-40"
4845
+ ),
4846
+ children: [
4847
+ /* @__PURE__ */ jsx63("span", { "aria-hidden": true, children: item.icon }),
4848
+ /* @__PURE__ */ jsx63("span", { className: "sr-only", children: item.label })
4849
+ ]
4850
+ }
4851
+ ) }, item.id);
4852
+ }
4853
+ return /* @__PURE__ */ jsxs54(
4854
+ "button",
4855
+ {
4856
+ type: "button",
4857
+ "aria-current": isActive ? "page" : void 0,
4858
+ disabled: item.disabled,
4859
+ onClick: (e) => handleSelect(item.id, e),
4860
+ className: cn(
4861
+ "flex flex-col items-center justify-center gap-[3px] border-0 bg-transparent",
4862
+ "h-full cursor-pointer outline-none",
4863
+ "focus-visible:ring-accent-dim focus-visible:ring-[3px]",
4864
+ "disabled:cursor-not-allowed disabled:opacity-40",
4865
+ isActive ? "text-accent-text" : "text-text-muted hover:text-text"
4866
+ ),
4867
+ children: [
4868
+ /* @__PURE__ */ jsxs54("span", { className: "relative inline-flex", "aria-hidden": true, children: [
4869
+ item.icon,
4870
+ item.badge != null && /* @__PURE__ */ jsx63(
4871
+ "span",
4872
+ {
4873
+ className: cn(
4874
+ "absolute -top-1 -right-2 rounded-full font-mono leading-none",
4875
+ "bg-err text-on-accent min-w-[16px] px-[5px] py-[2px] text-center text-[9px]"
4876
+ ),
4877
+ children: item.badge
4878
+ }
4879
+ )
4880
+ ] }),
4881
+ /* @__PURE__ */ jsxs54("span", { className: "text-[10px] font-medium tracking-tight", children: [
4882
+ item.label,
4883
+ item.badge != null && /* @__PURE__ */ jsxs54("span", { className: "sr-only", children: [
4884
+ ", ",
4885
+ item.badge,
4886
+ " unread"
4887
+ ] })
4888
+ ] })
4889
+ ]
4890
+ },
4891
+ item.id
4892
+ );
4893
+ })
4894
+ }
4895
+ );
4896
+ });
4897
+ TabBar.displayName = "TabBar";
4898
+
4620
4899
  // src/patterns/Tabs/Tabs.tsx
4621
4900
  import * as RadixTabs from "@radix-ui/react-tabs";
4622
4901
  import { cva as cva12 } from "class-variance-authority";
4623
- import { createContext as createContext2, forwardRef as forwardRef59, useContext as useContext2 } from "react";
4624
- import { jsx as jsx61 } from "react/jsx-runtime";
4902
+ import { createContext as createContext2, forwardRef as forwardRef62, useContext as useContext2 } from "react";
4903
+ import { jsx as jsx64 } from "react/jsx-runtime";
4625
4904
  var TabsVariantContext = createContext2("underline");
4626
4905
  var tabsListStyles = cva12("", {
4627
4906
  variants: {
@@ -4652,8 +4931,8 @@ var tabsTriggerStyles = cva12(
4652
4931
  }
4653
4932
  }
4654
4933
  );
4655
- var Tabs = forwardRef59(function Tabs2({ variant = "underline", className, ...props }, ref) {
4656
- return /* @__PURE__ */ jsx61(TabsVariantContext.Provider, { value: variant, children: /* @__PURE__ */ jsx61(
4934
+ var Tabs = forwardRef62(function Tabs2({ variant = "underline", className, ...props }, ref) {
4935
+ return /* @__PURE__ */ jsx64(TabsVariantContext.Provider, { value: variant, children: /* @__PURE__ */ jsx64(
4657
4936
  RadixTabs.Root,
4658
4937
  {
4659
4938
  ref,
@@ -4663,14 +4942,14 @@ var Tabs = forwardRef59(function Tabs2({ variant = "underline", className, ...pr
4663
4942
  ) });
4664
4943
  });
4665
4944
  Tabs.displayName = "Tabs";
4666
- var TabsList = forwardRef59(function TabsList2({ className, ...props }, ref) {
4945
+ var TabsList = forwardRef62(function TabsList2({ className, ...props }, ref) {
4667
4946
  const variant = useContext2(TabsVariantContext);
4668
- return /* @__PURE__ */ jsx61(RadixTabs.List, { ref, className: cn(tabsListStyles({ variant }), className), ...props });
4947
+ return /* @__PURE__ */ jsx64(RadixTabs.List, { ref, className: cn(tabsListStyles({ variant }), className), ...props });
4669
4948
  });
4670
4949
  TabsList.displayName = "TabsList";
4671
- var Tab = forwardRef59(function Tab2({ className, ...props }, ref) {
4950
+ var Tab = forwardRef62(function Tab2({ className, ...props }, ref) {
4672
4951
  const variant = useContext2(TabsVariantContext);
4673
- return /* @__PURE__ */ jsx61(
4952
+ return /* @__PURE__ */ jsx64(
4674
4953
  RadixTabs.Trigger,
4675
4954
  {
4676
4955
  ref,
@@ -4680,9 +4959,9 @@ var Tab = forwardRef59(function Tab2({ className, ...props }, ref) {
4680
4959
  );
4681
4960
  });
4682
4961
  Tab.displayName = "Tab";
4683
- var TabsContent = forwardRef59(
4962
+ var TabsContent = forwardRef62(
4684
4963
  function TabsContent2({ className, ...props }, ref) {
4685
- return /* @__PURE__ */ jsx61(
4964
+ return /* @__PURE__ */ jsx64(
4686
4965
  RadixTabs.Content,
4687
4966
  {
4688
4967
  ref,
@@ -4698,8 +4977,8 @@ var TabsContent = forwardRef59(
4698
4977
  TabsContent.displayName = "TabsContent";
4699
4978
 
4700
4979
  // src/patterns/Timeline/Timeline.tsx
4701
- import { forwardRef as forwardRef60 } from "react";
4702
- import { jsx as jsx62, jsxs as jsxs52 } from "react/jsx-runtime";
4980
+ import { forwardRef as forwardRef63 } from "react";
4981
+ import { jsx as jsx65, jsxs as jsxs55 } from "react/jsx-runtime";
4703
4982
  var ringClass = {
4704
4983
  accent: "border-accent",
4705
4984
  ok: "border-ok",
@@ -4707,8 +4986,8 @@ var ringClass = {
4707
4986
  err: "border-err",
4708
4987
  muted: "border-text-dim"
4709
4988
  };
4710
- var Timeline = forwardRef60(function Timeline2({ events, className, children, ...props }, ref) {
4711
- return /* @__PURE__ */ jsx62(
4989
+ var Timeline = forwardRef63(function Timeline2({ events, className, children, ...props }, ref) {
4990
+ return /* @__PURE__ */ jsx65(
4712
4991
  "ol",
4713
4992
  {
4714
4993
  ref,
@@ -4718,14 +4997,14 @@ var Timeline = forwardRef60(function Timeline2({ events, className, children, ..
4718
4997
  className
4719
4998
  ),
4720
4999
  ...props,
4721
- children: events ? events.map((e, i) => /* @__PURE__ */ jsx62(TimelineItem, { tone: e.tone, time: e.time, description: e.description, children: e.title }, i)) : children
5000
+ children: events ? events.map((e, i) => /* @__PURE__ */ jsx65(TimelineItem, { tone: e.tone, time: e.time, description: e.description, children: e.title }, i)) : children
4722
5001
  }
4723
5002
  );
4724
5003
  });
4725
5004
  Timeline.displayName = "Timeline";
4726
- var TimelineItem = forwardRef60(function TimelineItem2({ tone = "accent", description, time, className, children, ...props }, ref) {
4727
- return /* @__PURE__ */ jsxs52("li", { ref, className: cn("relative mb-[18px] last:mb-0", className), ...props, children: [
4728
- /* @__PURE__ */ jsx62(
5005
+ var TimelineItem = forwardRef63(function TimelineItem2({ tone = "accent", description, time, className, children, ...props }, ref) {
5006
+ return /* @__PURE__ */ jsxs55("li", { ref, className: cn("relative mb-[18px] last:mb-0", className), ...props, children: [
5007
+ /* @__PURE__ */ jsx65(
4729
5008
  "span",
4730
5009
  {
4731
5010
  "aria-hidden": true,
@@ -4735,15 +5014,15 @@ var TimelineItem = forwardRef60(function TimelineItem2({ tone = "accent", descri
4735
5014
  )
4736
5015
  }
4737
5016
  ),
4738
- /* @__PURE__ */ jsx62("div", { className: "text-[13px] font-medium", children }),
4739
- description && /* @__PURE__ */ jsx62("div", { className: "text-text-muted text-[12px]", children: description }),
4740
- time && /* @__PURE__ */ jsx62("div", { className: "text-text-dim mt-[2px] font-mono text-[10px]", children: time })
5017
+ /* @__PURE__ */ jsx65("div", { className: "text-[13px] font-medium", children }),
5018
+ description && /* @__PURE__ */ jsx65("div", { className: "text-text-muted text-[12px]", children: description }),
5019
+ time && /* @__PURE__ */ jsx65("div", { className: "text-text-dim mt-[2px] font-mono text-[10px]", children: time })
4741
5020
  ] });
4742
5021
  });
4743
5022
  TimelineItem.displayName = "TimelineItem";
4744
5023
 
4745
5024
  // src/patterns/Timeline/ActivityTimeline.tsx
4746
- import { forwardRef as forwardRef61 } from "react";
5025
+ import { forwardRef as forwardRef64 } from "react";
4747
5026
 
4748
5027
  // src/patterns/Timeline/formatRelative.ts
4749
5028
  var SECOND = 1e3;
@@ -4778,7 +5057,7 @@ function formatRelative(input, now = /* @__PURE__ */ new Date()) {
4778
5057
  }
4779
5058
 
4780
5059
  // src/patterns/Timeline/ActivityTimeline.tsx
4781
- import { jsx as jsx63, jsxs as jsxs53 } from "react/jsx-runtime";
5060
+ import { jsx as jsx66, jsxs as jsxs56 } from "react/jsx-runtime";
4782
5061
  var ringClass2 = {
4783
5062
  accent: "border-accent",
4784
5063
  ok: "border-ok",
@@ -4786,10 +5065,10 @@ var ringClass2 = {
4786
5065
  err: "border-err",
4787
5066
  muted: "border-text-dim"
4788
5067
  };
4789
- var ActivityTimeline = forwardRef61(
5068
+ var ActivityTimeline = forwardRef64(
4790
5069
  function ActivityTimeline2({ events, relativeNow, className, ...props }, ref) {
4791
5070
  const now = relativeNow ?? /* @__PURE__ */ new Date();
4792
- return /* @__PURE__ */ jsx63(
5071
+ return /* @__PURE__ */ jsx66(
4793
5072
  "ol",
4794
5073
  {
4795
5074
  ref,
@@ -4802,8 +5081,8 @@ var ActivityTimeline = forwardRef61(
4802
5081
  children: events.map((event) => {
4803
5082
  const tone = event.tone ?? "accent";
4804
5083
  const time = formatRelative(event.at, now);
4805
- return /* @__PURE__ */ jsxs53("li", { className: "relative mb-4 last:mb-0", children: [
4806
- /* @__PURE__ */ jsx63(
5084
+ return /* @__PURE__ */ jsxs56("li", { className: "relative mb-4 last:mb-0", children: [
5085
+ /* @__PURE__ */ jsx66(
4807
5086
  "span",
4808
5087
  {
4809
5088
  "aria-hidden": true,
@@ -4813,16 +5092,16 @@ var ActivityTimeline = forwardRef61(
4813
5092
  )
4814
5093
  }
4815
5094
  ),
4816
- /* @__PURE__ */ jsxs53("div", { className: "flex items-baseline gap-2", children: [
4817
- event.icon && /* @__PURE__ */ jsx63("span", { "aria-hidden": true, className: "text-text-muted font-mono text-[12px]", children: event.icon }),
4818
- /* @__PURE__ */ jsx63("div", { className: "text-[13px] font-medium", children: event.title }),
4819
- time && /* @__PURE__ */ jsx63("time", { className: "text-text-dim ml-auto font-mono text-[10px]", children: time })
5095
+ /* @__PURE__ */ jsxs56("div", { className: "flex items-baseline gap-2", children: [
5096
+ event.icon && /* @__PURE__ */ jsx66("span", { "aria-hidden": true, className: "text-text-muted font-mono text-[12px]", children: event.icon }),
5097
+ /* @__PURE__ */ jsx66("div", { className: "text-[13px] font-medium", children: event.title }),
5098
+ time && /* @__PURE__ */ jsx66("time", { className: "text-text-dim ml-auto font-mono text-[10px]", children: time })
4820
5099
  ] }),
4821
- event.actor && /* @__PURE__ */ jsxs53("div", { className: "text-text-muted mt-[2px] flex items-center gap-[6px] text-[12px]", children: [
4822
- event.actor.avatar && /* @__PURE__ */ jsx63("span", { "aria-hidden": true, className: "inline-flex", children: event.actor.avatar }),
4823
- /* @__PURE__ */ jsx63("span", { children: event.actor.name })
5100
+ event.actor && /* @__PURE__ */ jsxs56("div", { className: "text-text-muted mt-[2px] flex items-center gap-[6px] text-[12px]", children: [
5101
+ event.actor.avatar && /* @__PURE__ */ jsx66("span", { "aria-hidden": true, className: "inline-flex", children: event.actor.avatar }),
5102
+ /* @__PURE__ */ jsx66("span", { children: event.actor.name })
4824
5103
  ] }),
4825
- event.payload && /* @__PURE__ */ jsx63("div", { className: "border-border bg-panel-2 mt-2 rounded-md border px-3 py-2 font-mono text-[11px] leading-[1.5]", children: event.payload })
5104
+ event.payload && /* @__PURE__ */ jsx66("div", { className: "border-border bg-panel-2 mt-2 rounded-md border px-3 py-2 font-mono text-[11px] leading-[1.5]", children: event.payload })
4826
5105
  ] }, event.id);
4827
5106
  })
4828
5107
  }
@@ -4832,23 +5111,77 @@ var ActivityTimeline = forwardRef61(
4832
5111
  ActivityTimeline.displayName = "ActivityTimeline";
4833
5112
 
4834
5113
  // src/patterns/Topbar/Topbar.tsx
4835
- import { forwardRef as forwardRef62 } from "react";
4836
- import { jsx as jsx64, jsxs as jsxs54 } from "react/jsx-runtime";
4837
- var Topbar = forwardRef62(function Topbar2({ title, leading, actions, className, children, ...props }, ref) {
4838
- return /* @__PURE__ */ jsxs54(
5114
+ import { forwardRef as forwardRef65 } from "react";
5115
+ import { jsx as jsx67, jsxs as jsxs57 } from "react/jsx-runtime";
5116
+ var Topbar = forwardRef65(function Topbar2({
5117
+ title,
5118
+ eyebrow,
5119
+ leading,
5120
+ back,
5121
+ onBack,
5122
+ actions,
5123
+ density = "comfortable",
5124
+ className,
5125
+ children,
5126
+ ...props
5127
+ }, ref) {
5128
+ const isTouch = density === "touch";
5129
+ const backHandler = typeof back === "function" ? back : back ? onBack : void 0;
5130
+ return /* @__PURE__ */ jsxs57(
4839
5131
  "header",
4840
5132
  {
4841
5133
  ref,
4842
5134
  className: cn(
4843
- "border-border bg-panel flex h-[52px] items-center gap-4 border-b px-5",
5135
+ "border-border bg-panel flex items-center border-b",
5136
+ isTouch ? "h-navbar gap-2 px-3" : "h-[52px] gap-4 px-5",
4844
5137
  className
4845
5138
  ),
4846
5139
  ...props,
4847
5140
  children: [
5141
+ isTouch && back && /* @__PURE__ */ jsx67(
5142
+ "button",
5143
+ {
5144
+ type: "button",
5145
+ onClick: backHandler,
5146
+ "aria-label": "Back",
5147
+ className: cn(
5148
+ "text-text inline-grid place-items-center rounded-md bg-transparent",
5149
+ // The back button is only rendered in touch density — use the
5150
+ // touch token (44pt) instead of `h-9 w-9` (36px) so it meets the
5151
+ // HIG minimum the rest of the touch surface enforces.
5152
+ "hover:bg-panel-2 h-touch w-touch",
5153
+ "focus-visible:ring-accent-dim outline-none focus-visible:ring-[3px]"
5154
+ ),
5155
+ children: /* @__PURE__ */ jsx67(
5156
+ "svg",
5157
+ {
5158
+ width: "20",
5159
+ height: "20",
5160
+ viewBox: "0 0 24 24",
5161
+ fill: "none",
5162
+ stroke: "currentColor",
5163
+ strokeWidth: "2",
5164
+ "aria-hidden": true,
5165
+ children: /* @__PURE__ */ jsx67("path", { d: "m15 18-6-6 6-6" })
5166
+ }
5167
+ )
5168
+ }
5169
+ ),
4848
5170
  leading,
4849
- title && /* @__PURE__ */ jsx64("div", { className: "text-[13px] font-medium", children: title }),
4850
- /* @__PURE__ */ jsx64("div", { className: "flex flex-1 items-center" }),
4851
- actions && /* @__PURE__ */ jsx64("div", { className: "flex items-center gap-3", children: actions }),
5171
+ (title || isTouch && eyebrow) && /* @__PURE__ */ jsxs57("div", { className: cn("min-w-0", isTouch && "flex-1"), children: [
5172
+ isTouch && eyebrow && /* @__PURE__ */ jsx67("div", { className: "text-m-eyebrow text-accent font-mono tracking-wide uppercase", children: eyebrow }),
5173
+ title && /* @__PURE__ */ jsx67(
5174
+ "div",
5175
+ {
5176
+ className: cn(
5177
+ isTouch ? "text-m-body-lg truncate font-semibold tracking-tight" : "text-[13px] font-medium"
5178
+ ),
5179
+ children: title
5180
+ }
5181
+ )
5182
+ ] }),
5183
+ !isTouch && /* @__PURE__ */ jsx67("div", { className: "flex flex-1 items-center" }),
5184
+ actions && /* @__PURE__ */ jsx67("div", { className: cn("flex items-center", isTouch ? "gap-1" : "gap-3"), children: actions }),
4852
5185
  children
4853
5186
  ]
4854
5187
  }
@@ -4858,14 +5191,14 @@ Topbar.displayName = "Topbar";
4858
5191
 
4859
5192
  // src/patterns/Tree/Tree.tsx
4860
5193
  import {
4861
- forwardRef as forwardRef63,
4862
- useCallback as useCallback11,
5194
+ forwardRef as forwardRef66,
5195
+ useCallback as useCallback12,
4863
5196
  useEffect as useEffect10,
4864
5197
  useMemo as useMemo6,
4865
5198
  useRef as useRef8,
4866
- useState as useState15
5199
+ useState as useState16
4867
5200
  } from "react";
4868
- import { jsx as jsx65, jsxs as jsxs55 } from "react/jsx-runtime";
5201
+ import { jsx as jsx68, jsxs as jsxs58 } from "react/jsx-runtime";
4869
5202
  var EMPTY_SET2 = /* @__PURE__ */ new Set();
4870
5203
  function flattenVisible(items, expanded, level, parentId, out) {
4871
5204
  for (const item of items) {
@@ -4876,7 +5209,7 @@ function flattenVisible(items, expanded, level, parentId, out) {
4876
5209
  }
4877
5210
  }
4878
5211
  }
4879
- var Tree = forwardRef63(function Tree2({
5212
+ var Tree = forwardRef66(function Tree2({
4880
5213
  items,
4881
5214
  expanded: expandedProp,
4882
5215
  defaultExpanded,
@@ -4904,7 +5237,7 @@ var Tree = forwardRef63(function Tree2({
4904
5237
  flattenVisible(items, expandedSet, 1, null, out);
4905
5238
  return out;
4906
5239
  }, [items, expandedSet]);
4907
- const [activeId, setActiveId] = useState15(null);
5240
+ const [activeId, setActiveId] = useState16(null);
4908
5241
  useEffect10(() => {
4909
5242
  if (activeId && !flatVisible.some((f) => f.id === activeId)) {
4910
5243
  setActiveId(null);
@@ -4916,7 +5249,7 @@ var Tree = forwardRef63(function Tree2({
4916
5249
  return flatVisible[0]?.id ?? null;
4917
5250
  }, [activeId, flatVisible, value]);
4918
5251
  const listRef = useRef8(null);
4919
- const setRefs = useCallback11(
5252
+ const setRefs = useCallback12(
4920
5253
  (node) => {
4921
5254
  listRef.current = node;
4922
5255
  if (typeof ref === "function") ref(node);
@@ -4924,20 +5257,20 @@ var Tree = forwardRef63(function Tree2({
4924
5257
  },
4925
5258
  [ref]
4926
5259
  );
4927
- const focusItem = useCallback11((id) => {
5260
+ const focusItem = useCallback12((id) => {
4928
5261
  const root = listRef.current;
4929
5262
  if (!root) return;
4930
5263
  const el = root.querySelector(`[data-treeitem-id="${CSS.escape(id)}"]`);
4931
5264
  el?.focus();
4932
5265
  }, []);
4933
- const moveActive = useCallback11(
5266
+ const moveActive = useCallback12(
4934
5267
  (id) => {
4935
5268
  setActiveId(id);
4936
5269
  queueMicrotask(() => focusItem(id));
4937
5270
  },
4938
5271
  [focusItem]
4939
5272
  );
4940
- const toggle = useCallback11(
5273
+ const toggle = useCallback12(
4941
5274
  (id) => {
4942
5275
  setExpanded((prev) => {
4943
5276
  const next = new Set(prev ?? EMPTY_SET2);
@@ -4948,7 +5281,7 @@ var Tree = forwardRef63(function Tree2({
4948
5281
  },
4949
5282
  [setExpanded]
4950
5283
  );
4951
- const expand = useCallback11(
5284
+ const expand = useCallback12(
4952
5285
  (id) => {
4953
5286
  setExpanded((prev) => {
4954
5287
  const base = prev ?? EMPTY_SET2;
@@ -4960,7 +5293,7 @@ var Tree = forwardRef63(function Tree2({
4960
5293
  },
4961
5294
  [setExpanded]
4962
5295
  );
4963
- const collapse = useCallback11(
5296
+ const collapse = useCallback12(
4964
5297
  (id) => {
4965
5298
  setExpanded((prev) => {
4966
5299
  const base = prev ?? EMPTY_SET2;
@@ -4972,13 +5305,13 @@ var Tree = forwardRef63(function Tree2({
4972
5305
  },
4973
5306
  [setExpanded]
4974
5307
  );
4975
- const selectItem = useCallback11(
5308
+ const selectItem = useCallback12(
4976
5309
  (id) => {
4977
5310
  setValue(id);
4978
5311
  },
4979
5312
  [setValue]
4980
5313
  );
4981
- const handleKeyDown = useCallback11(
5314
+ const handleKeyDown = useCallback12(
4982
5315
  (e) => {
4983
5316
  onKeyDown?.(e);
4984
5317
  if (e.defaultPrevented) return;
@@ -5058,7 +5391,7 @@ var Tree = forwardRef63(function Tree2({
5058
5391
  toggle
5059
5392
  ]
5060
5393
  );
5061
- return /* @__PURE__ */ jsx65(
5394
+ return /* @__PURE__ */ jsx68(
5062
5395
  "ul",
5063
5396
  {
5064
5397
  ref: setRefs,
@@ -5066,7 +5399,7 @@ var Tree = forwardRef63(function Tree2({
5066
5399
  className: cn("flex flex-col gap-px text-[12px]", className),
5067
5400
  onKeyDown: handleKeyDown,
5068
5401
  ...props,
5069
- children: items.map((item) => /* @__PURE__ */ jsx65(
5402
+ children: items.map((item) => /* @__PURE__ */ jsx68(
5070
5403
  TreeItemRow,
5071
5404
  {
5072
5405
  item,
@@ -5101,8 +5434,8 @@ function TreeItemRow({
5101
5434
  const isExpanded = hasChildren && expanded.has(item.id);
5102
5435
  const isSelected = selected === item.id;
5103
5436
  const isTabStop = tabStopId === item.id;
5104
- return /* @__PURE__ */ jsxs55("li", { role: "none", children: [
5105
- /* @__PURE__ */ jsxs55(
5437
+ return /* @__PURE__ */ jsxs58("li", { role: "none", children: [
5438
+ /* @__PURE__ */ jsxs58(
5106
5439
  "div",
5107
5440
  {
5108
5441
  role: "treeitem",
@@ -5125,14 +5458,14 @@ function TreeItemRow({
5125
5458
  isSelected ? "bg-accent-dim text-accent" : "text-text hover:bg-panel-2"
5126
5459
  ),
5127
5460
  children: [
5128
- /* @__PURE__ */ jsx65("span", { "aria-hidden": true, className: "text-text-dim grid w-3 place-items-center text-[10px]", children: hasChildren ? isExpanded ? "\u25BE" : "\u25B8" : "" }),
5129
- item.icon && /* @__PURE__ */ jsx65("span", { "aria-hidden": true, className: "text-[12px] opacity-80", children: item.icon }),
5130
- /* @__PURE__ */ jsx65("span", { className: "flex-1 truncate", children: item.label }),
5461
+ /* @__PURE__ */ jsx68("span", { "aria-hidden": true, className: "text-text-dim grid w-3 place-items-center text-[10px]", children: hasChildren ? isExpanded ? "\u25BE" : "\u25B8" : "" }),
5462
+ item.icon && /* @__PURE__ */ jsx68("span", { "aria-hidden": true, className: "text-[12px] opacity-80", children: item.icon }),
5463
+ /* @__PURE__ */ jsx68("span", { className: "flex-1 truncate", children: item.label }),
5131
5464
  item.trailing
5132
5465
  ]
5133
5466
  }
5134
5467
  ),
5135
- hasChildren && isExpanded && /* @__PURE__ */ jsx65("ul", { role: "group", className: "flex flex-col gap-px", children: (item.children ?? []).map((child) => /* @__PURE__ */ jsx65(
5468
+ hasChildren && isExpanded && /* @__PURE__ */ jsx68("ul", { role: "group", className: "flex flex-col gap-px", children: (item.children ?? []).map((child) => /* @__PURE__ */ jsx68(
5136
5469
  TreeItemRow,
5137
5470
  {
5138
5471
  item: child,
@@ -5151,9 +5484,9 @@ function TreeItemRow({
5151
5484
 
5152
5485
  // src/patterns/WizardDialog/WizardDialog.tsx
5153
5486
  import * as RadixDialog5 from "@radix-ui/react-dialog";
5154
- import { forwardRef as forwardRef64, useCallback as useCallback12, useMemo as useMemo7, useState as useState16 } from "react";
5155
- import { jsx as jsx66, jsxs as jsxs56 } from "react/jsx-runtime";
5156
- var WizardDialog = forwardRef64(function WizardDialog2({
5487
+ import { forwardRef as forwardRef67, useCallback as useCallback13, useMemo as useMemo7, useState as useState17 } from "react";
5488
+ import { jsx as jsx69, jsxs as jsxs59 } from "react/jsx-runtime";
5489
+ var WizardDialog = forwardRef67(function WizardDialog2({
5157
5490
  open,
5158
5491
  defaultOpen,
5159
5492
  onOpenChange,
@@ -5169,18 +5502,18 @@ var WizardDialog = forwardRef64(function WizardDialog2({
5169
5502
  cancelLabel,
5170
5503
  onCancel
5171
5504
  }, ref) {
5172
- const [current, setCurrent] = useState16(initialStep);
5505
+ const [current, setCurrent] = useState17(initialStep);
5173
5506
  const total = steps.length;
5174
5507
  const safeCurrent = Math.min(current, Math.max(0, total - 1));
5175
5508
  const step = steps[safeCurrent];
5176
- const goTo = useCallback12(
5509
+ const goTo = useCallback13(
5177
5510
  (index) => {
5178
5511
  setCurrent(Math.min(Math.max(0, index), Math.max(0, total - 1)));
5179
5512
  },
5180
5513
  [total]
5181
5514
  );
5182
- const goNext = useCallback12(() => setCurrent((c) => Math.min(c + 1, total - 1)), [total]);
5183
- const goBack = useCallback12(() => setCurrent((c) => Math.max(c - 1, 0)), []);
5515
+ const goNext = useCallback13(() => setCurrent((c) => Math.min(c + 1, total - 1)), [total]);
5516
+ const goBack = useCallback13(() => setCurrent((c) => Math.max(c - 1, 0)), []);
5184
5517
  const ctx = useMemo7(
5185
5518
  () => ({
5186
5519
  current: safeCurrent,
@@ -5204,23 +5537,23 @@ var WizardDialog = forwardRef64(function WizardDialog2({
5204
5537
  goNext();
5205
5538
  }
5206
5539
  };
5207
- return /* @__PURE__ */ jsx66(DialogRoot, { open, defaultOpen, onOpenChange, children: /* @__PURE__ */ jsxs56(DialogContent, { ref, width, children: [
5208
- title && /* @__PURE__ */ jsx66(WizardTitle, { children: title }),
5209
- description && /* @__PURE__ */ jsx66(WizardDescription, { children: description }),
5210
- /* @__PURE__ */ jsx66("div", { className: "mb-5", children: /* @__PURE__ */ jsx66(Stepper, { steps: stepperSteps, current: safeCurrent }) }),
5211
- /* @__PURE__ */ jsx66("div", { className: "mb-5", children: body }),
5212
- /* @__PURE__ */ jsxs56("div", { className: "flex justify-end gap-2", children: [
5213
- cancelLabel && /* @__PURE__ */ jsx66(Button, { type: "button", variant: "ghost", onClick: onCancel, children: cancelLabel }),
5214
- /* @__PURE__ */ jsx66(Button, { type: "button", variant: "secondary", onClick: goBack, disabled: ctx.isFirst, children: backLabel }),
5215
- /* @__PURE__ */ jsx66(Button, { type: "button", variant: "primary", onClick: handlePrimary, disabled: !canAdvance, children: ctx.isLast ? completeLabel : nextLabel })
5540
+ return /* @__PURE__ */ jsx69(DialogRoot, { open, defaultOpen, onOpenChange, children: /* @__PURE__ */ jsxs59(DialogContent, { ref, width, children: [
5541
+ title && /* @__PURE__ */ jsx69(WizardTitle, { children: title }),
5542
+ description && /* @__PURE__ */ jsx69(WizardDescription, { children: description }),
5543
+ /* @__PURE__ */ jsx69("div", { className: "mb-5", children: /* @__PURE__ */ jsx69(Stepper, { steps: stepperSteps, current: safeCurrent }) }),
5544
+ /* @__PURE__ */ jsx69("div", { className: "mb-5", children: body }),
5545
+ /* @__PURE__ */ jsxs59("div", { className: "flex justify-end gap-2", children: [
5546
+ cancelLabel && /* @__PURE__ */ jsx69(Button, { type: "button", variant: "ghost", onClick: onCancel, children: cancelLabel }),
5547
+ /* @__PURE__ */ jsx69(Button, { type: "button", variant: "secondary", onClick: goBack, disabled: ctx.isFirst, children: backLabel }),
5548
+ /* @__PURE__ */ jsx69(Button, { type: "button", variant: "primary", onClick: handlePrimary, disabled: !canAdvance, children: ctx.isLast ? completeLabel : nextLabel })
5216
5549
  ] })
5217
5550
  ] }) });
5218
5551
  });
5219
5552
  function WizardTitle({ children }) {
5220
- return /* @__PURE__ */ jsx66(RadixDialog5.Title, { className: "mb-2 text-[16px] font-medium", children });
5553
+ return /* @__PURE__ */ jsx69(RadixDialog5.Title, { className: "mb-2 text-[16px] font-medium", children });
5221
5554
  }
5222
5555
  function WizardDescription({ children }) {
5223
- return /* @__PURE__ */ jsx66(RadixDialog5.Description, { className: "text-text-muted mb-4 text-[13px] leading-[1.55]", children });
5556
+ return /* @__PURE__ */ jsx69(RadixDialog5.Description, { className: "text-text-muted mb-4 text-[13px] leading-[1.55]", children });
5224
5557
  }
5225
5558
  WizardDialog.displayName = "WizardDialog";
5226
5559
  export {
@@ -5287,6 +5620,7 @@ export {
5287
5620
  IconButton,
5288
5621
  Input,
5289
5622
  Kbd,
5623
+ LargeTitle,
5290
5624
  MenuCheckboxItem,
5291
5625
  MenuItem,
5292
5626
  MenuSeparator,
@@ -5311,6 +5645,7 @@ export {
5311
5645
  PopoverRoot,
5312
5646
  PopoverTrigger,
5313
5647
  Progress,
5648
+ PullToRefresh,
5314
5649
  RadialProgress,
5315
5650
  Radio,
5316
5651
  RadioGroup,
@@ -5326,6 +5661,7 @@ export {
5326
5661
  SelectValue,
5327
5662
  Sheet,
5328
5663
  Sidebar,
5664
+ SimpleTooltip,
5329
5665
  Skeleton,
5330
5666
  SkeletonGroup,
5331
5667
  Slider,
@@ -5337,6 +5673,7 @@ export {
5337
5673
  Stepper,
5338
5674
  Switch,
5339
5675
  Tab,
5676
+ TabBar,
5340
5677
  Tabs,
5341
5678
  TabsContent,
5342
5679
  TabsList,
@@ -5351,7 +5688,6 @@ export {
5351
5688
  TooltipContent,
5352
5689
  TooltipPortal,
5353
5690
  TooltipProvider,
5354
- TooltipRoot,
5355
5691
  TooltipTrigger,
5356
5692
  Topbar,
5357
5693
  Tree,