@ship-it-ui/ui 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
  )
@@ -3612,12 +3717,34 @@ var HealthScore = forwardRef49(function HealthScore2({
3612
3717
  });
3613
3718
  HealthScore.displayName = "HealthScore";
3614
3719
 
3615
- // src/patterns/Menubar/Menubar.tsx
3616
- import * as RadixMenubar from "@radix-ui/react-menubar";
3720
+ // src/patterns/LargeTitle/LargeTitle.tsx
3617
3721
  import { forwardRef as forwardRef50 } from "react";
3618
3722
  import { jsx as jsx52, jsxs as jsxs44 } from "react/jsx-runtime";
3619
- var Menubar = forwardRef50(function Menubar2({ className, ...props }, ref) {
3620
- return /* @__PURE__ */ jsx52(
3723
+ var LargeTitle = forwardRef50(function LargeTitle2({ title, eyebrow, trailing, className, ...props }, ref) {
3724
+ return /* @__PURE__ */ jsxs44(
3725
+ "header",
3726
+ {
3727
+ ref,
3728
+ className: cn("px-screen flex items-end justify-between gap-3 py-3 pb-4", className),
3729
+ ...props,
3730
+ children: [
3731
+ /* @__PURE__ */ jsxs44("div", { className: "min-w-0 flex-1", children: [
3732
+ eyebrow && /* @__PURE__ */ jsx52("div", { className: "text-m-eyebrow text-accent mb-[6px] font-mono tracking-wide uppercase", children: eyebrow }),
3733
+ /* @__PURE__ */ jsx52("h1", { className: "text-m-h1 m-0 truncate leading-tight font-medium tracking-tight", children: title })
3734
+ ] }),
3735
+ trailing && /* @__PURE__ */ jsx52("div", { className: "shrink-0", children: trailing })
3736
+ ]
3737
+ }
3738
+ );
3739
+ });
3740
+ LargeTitle.displayName = "LargeTitle";
3741
+
3742
+ // src/patterns/Menubar/Menubar.tsx
3743
+ import * as RadixMenubar from "@radix-ui/react-menubar";
3744
+ import { forwardRef as forwardRef51 } from "react";
3745
+ import { jsx as jsx53, jsxs as jsxs45 } from "react/jsx-runtime";
3746
+ var Menubar = forwardRef51(function Menubar2({ className, ...props }, ref) {
3747
+ return /* @__PURE__ */ jsx53(
3621
3748
  RadixMenubar.Root,
3622
3749
  {
3623
3750
  ref,
@@ -3631,9 +3758,9 @@ var Menubar = forwardRef50(function Menubar2({ className, ...props }, ref) {
3631
3758
  });
3632
3759
  Menubar.displayName = "Menubar";
3633
3760
  var MenubarMenu = RadixMenubar.Menu;
3634
- var MenubarTrigger = forwardRef50(
3761
+ var MenubarTrigger = forwardRef51(
3635
3762
  function MenubarTrigger2({ className, ...props }, ref) {
3636
- return /* @__PURE__ */ jsx52(
3763
+ return /* @__PURE__ */ jsx53(
3637
3764
  RadixMenubar.Trigger,
3638
3765
  {
3639
3766
  ref,
@@ -3650,9 +3777,9 @@ var MenubarTrigger = forwardRef50(
3650
3777
  }
3651
3778
  );
3652
3779
  MenubarTrigger.displayName = "MenubarTrigger";
3653
- var MenubarContent = forwardRef50(
3780
+ var MenubarContent = forwardRef51(
3654
3781
  function MenubarContent2({ className, sideOffset = 6, align = "start", ...props }, ref) {
3655
- return /* @__PURE__ */ jsx52(RadixMenubar.Portal, { children: /* @__PURE__ */ jsx52(
3782
+ return /* @__PURE__ */ jsx53(RadixMenubar.Portal, { children: /* @__PURE__ */ jsx53(
3656
3783
  RadixMenubar.Content,
3657
3784
  {
3658
3785
  ref,
@@ -3674,24 +3801,24 @@ var itemBase3 = cn(
3674
3801
  "data-[highlighted]:bg-panel-2",
3675
3802
  "data-[disabled]:opacity-40 data-[disabled]:cursor-not-allowed"
3676
3803
  );
3677
- var MenubarItem = forwardRef50(function MenubarItem2({ trailing, destructive, className, children, ...props }, ref) {
3678
- return /* @__PURE__ */ jsxs44(
3804
+ var MenubarItem = forwardRef51(function MenubarItem2({ trailing, destructive, className, children, ...props }, ref) {
3805
+ return /* @__PURE__ */ jsxs45(
3679
3806
  RadixMenubar.Item,
3680
3807
  {
3681
3808
  ref,
3682
3809
  className: cn(itemBase3, destructive ? "text-err" : "text-text", className),
3683
3810
  ...props,
3684
3811
  children: [
3685
- /* @__PURE__ */ jsx52("span", { className: "flex-1", children }),
3686
- trailing && /* @__PURE__ */ jsx52("span", { className: "text-text-dim font-mono text-[10px]", children: trailing })
3812
+ /* @__PURE__ */ jsx53("span", { className: "flex-1", children }),
3813
+ trailing && /* @__PURE__ */ jsx53("span", { className: "text-text-dim font-mono text-[10px]", children: trailing })
3687
3814
  ]
3688
3815
  }
3689
3816
  );
3690
3817
  });
3691
3818
  MenubarItem.displayName = "MenubarItem";
3692
- var MenubarSeparator = forwardRef50(
3819
+ var MenubarSeparator = forwardRef51(
3693
3820
  function MenubarSeparator2({ className, ...props }, ref) {
3694
- return /* @__PURE__ */ jsx52(
3821
+ return /* @__PURE__ */ jsx53(
3695
3822
  RadixMenubar.Separator,
3696
3823
  {
3697
3824
  ref,
@@ -3706,7 +3833,7 @@ MenubarSeparator.displayName = "MenubarSeparator";
3706
3833
  // src/patterns/NavBar/NavBar.tsx
3707
3834
  import * as RadixNav from "@radix-ui/react-navigation-menu";
3708
3835
  import {
3709
- forwardRef as forwardRef52,
3836
+ forwardRef as forwardRef53,
3710
3837
  useCallback as useCallback10,
3711
3838
  useEffect as useEffect9,
3712
3839
  useRef as useRef7,
@@ -3715,13 +3842,13 @@ import {
3715
3842
 
3716
3843
  // src/patterns/Sidebar/Sidebar.tsx
3717
3844
  import {
3718
- forwardRef as forwardRef51,
3845
+ forwardRef as forwardRef52,
3719
3846
  useCallback as useCallback9,
3720
3847
  useState as useState13
3721
3848
  } 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(
3849
+ import { Fragment as Fragment2, jsx as jsx54, jsxs as jsxs46 } from "react/jsx-runtime";
3850
+ var Sidebar = forwardRef52(function Sidebar2({ width = 240, className, style, ...props }, ref) {
3851
+ return /* @__PURE__ */ jsx54(
3725
3852
  "aside",
3726
3853
  {
3727
3854
  ref,
@@ -3735,12 +3862,12 @@ var Sidebar = forwardRef51(function Sidebar2({ width = 240, className, style, ..
3735
3862
  );
3736
3863
  });
3737
3864
  Sidebar.displayName = "Sidebar";
3738
- var NavItem = forwardRef51(
3865
+ var NavItem = forwardRef52(
3739
3866
  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(
3867
+ const inner = /* @__PURE__ */ jsxs46(Fragment2, { children: [
3868
+ icon && /* @__PURE__ */ jsx54("span", { "aria-hidden": true, className: "w-[14px] text-center opacity-80", children: icon }),
3869
+ /* @__PURE__ */ jsx54("span", { className: "flex-1 truncate", children: label }),
3870
+ badge != null && /* @__PURE__ */ jsx54(
3744
3871
  "span",
3745
3872
  {
3746
3873
  className: cn(
@@ -3761,7 +3888,7 @@ var NavItem = forwardRef51(
3761
3888
  );
3762
3889
  if (href) {
3763
3890
  const anchorProps = props;
3764
- return /* @__PURE__ */ jsx53(
3891
+ return /* @__PURE__ */ jsx54(
3765
3892
  "a",
3766
3893
  {
3767
3894
  ref,
@@ -3775,7 +3902,7 @@ var NavItem = forwardRef51(
3775
3902
  );
3776
3903
  }
3777
3904
  const buttonProps = props;
3778
- return /* @__PURE__ */ jsx53(
3905
+ return /* @__PURE__ */ jsx54(
3779
3906
  "button",
3780
3907
  {
3781
3908
  ref,
@@ -3790,7 +3917,7 @@ var NavItem = forwardRef51(
3790
3917
  }
3791
3918
  );
3792
3919
  NavItem.displayName = "NavItem";
3793
- var NavSection = forwardRef51(function NavSection2({
3920
+ var NavSection = forwardRef52(function NavSection2({
3794
3921
  label,
3795
3922
  icon,
3796
3923
  action,
@@ -3812,8 +3939,8 @@ var NavSection = forwardRef51(function NavSection2({
3812
3939
  onOpenChange?.(next);
3813
3940
  }, [isOpen, isControlled, onOpenChange]);
3814
3941
  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(
3942
+ return /* @__PURE__ */ jsxs46("div", { ref, className: cn("flex flex-col gap-1", className), ...props, children: [
3943
+ collapsible ? /* @__PURE__ */ jsxs46(
3817
3944
  "button",
3818
3945
  {
3819
3946
  type: "button",
@@ -3826,18 +3953,18 @@ var NavSection = forwardRef51(function NavSection2({
3826
3953
  "hover:text-text-muted"
3827
3954
  ),
3828
3955
  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 }),
3956
+ icon != null && /* @__PURE__ */ jsx54("span", { "aria-hidden": true, className: "opacity-80", children: icon }),
3957
+ /* @__PURE__ */ jsx54("span", { className: "flex-1 text-left", children: label }),
3831
3958
  action,
3832
- /* @__PURE__ */ jsx53("span", { "aria-hidden": true, className: "text-[10px] opacity-70", children: isOpen ? "\u25BE" : "\u25B8" })
3959
+ /* @__PURE__ */ jsx54("span", { "aria-hidden": true, className: "text-[10px] opacity-70", children: isOpen ? "\u25BE" : "\u25B8" })
3833
3960
  ]
3834
3961
  }
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 }),
3962
+ ) : /* @__PURE__ */ jsxs46("div", { className: eyebrowClass, children: [
3963
+ icon != null && /* @__PURE__ */ jsx54("span", { "aria-hidden": true, className: "opacity-80", children: icon }),
3964
+ /* @__PURE__ */ jsx54("span", { className: "flex-1", children: label }),
3838
3965
  action
3839
3966
  ] }),
3840
- isOpen && /* @__PURE__ */ jsx53(
3967
+ isOpen && /* @__PURE__ */ jsx54(
3841
3968
  "div",
3842
3969
  {
3843
3970
  className: cn("flex flex-col gap-[2px]", indent > 0 && "border-border ml-2 border-l"),
@@ -3850,12 +3977,12 @@ var NavSection = forwardRef51(function NavSection2({
3850
3977
  NavSection.displayName = "NavSection";
3851
3978
 
3852
3979
  // src/patterns/NavBar/NavBar.tsx
3853
- import { Fragment as Fragment3, jsx as jsx54, jsxs as jsxs46 } from "react/jsx-runtime";
3980
+ import { Fragment as Fragment3, jsx as jsx55, jsxs as jsxs47 } from "react/jsx-runtime";
3854
3981
  function isActiveTree(item, activeId) {
3855
3982
  if (item.id === activeId) return true;
3856
3983
  return item.children?.some((c) => isActiveTree(c, activeId)) ?? false;
3857
3984
  }
3858
- var NavBar = forwardRef52(function NavBar2({
3985
+ var NavBar = forwardRef53(function NavBar2({
3859
3986
  orientation = "horizontal",
3860
3987
  items,
3861
3988
  brand,
@@ -3891,7 +4018,7 @@ var NavBar = forwardRef52(function NavBar2({
3891
4018
  // drawer is open on a viewport that's resizing past `md`, both navs can
3892
4019
  // sit in the DOM together. Identical accessible names would trip axe's
3893
4020
  // `landmark-unique` rule.
3894
- /* @__PURE__ */ jsx54("nav", { "aria-label": "Mobile navigation", className: "flex flex-col gap-1", children: items.map((item) => /* @__PURE__ */ jsx54(
4021
+ /* @__PURE__ */ jsx55("nav", { "aria-label": "Mobile navigation", className: "flex flex-col gap-1", children: items.map((item) => /* @__PURE__ */ jsx55(
3895
4022
  VerticalItem,
3896
4023
  {
3897
4024
  item,
@@ -3901,14 +4028,14 @@ var NavBar = forwardRef52(function NavBar2({
3901
4028
  item.id
3902
4029
  )) })
3903
4030
  );
3904
- const mobileBar = responsive ? /* @__PURE__ */ jsxs46(
4031
+ const mobileBar = responsive ? /* @__PURE__ */ jsxs47(
3905
4032
  "div",
3906
4033
  {
3907
4034
  className: cn(
3908
4035
  "border-border bg-panel z-overlay sticky top-0 flex h-[52px] items-center gap-4 border-b px-5 md:hidden"
3909
4036
  ),
3910
4037
  children: [
3911
- /* @__PURE__ */ jsx54(
4038
+ /* @__PURE__ */ jsx55(
3912
4039
  "button",
3913
4040
  {
3914
4041
  type: "button",
@@ -3918,15 +4045,15 @@ var NavBar = forwardRef52(function NavBar2({
3918
4045
  children: "\u2630"
3919
4046
  }
3920
4047
  ),
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 })
4048
+ brand && /* @__PURE__ */ jsx55("div", { className: "flex flex-1 items-center text-[13px] font-medium whitespace-nowrap", children: brand }),
4049
+ actions && /* @__PURE__ */ jsx55("div", { className: "flex items-center gap-3", children: actions })
3923
4050
  ]
3924
4051
  }
3925
4052
  ) : null;
3926
4053
  if (orientation === "horizontal") {
3927
- return /* @__PURE__ */ jsxs46(Fragment3, { children: [
4054
+ return /* @__PURE__ */ jsxs47(Fragment3, { children: [
3928
4055
  mobileBar,
3929
- /* @__PURE__ */ jsxs46(
4056
+ /* @__PURE__ */ jsxs47(
3930
4057
  "header",
3931
4058
  {
3932
4059
  ref,
@@ -3937,10 +4064,10 @@ var NavBar = forwardRef52(function NavBar2({
3937
4064
  ),
3938
4065
  ...props,
3939
4066
  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(
4067
+ brand && /* @__PURE__ */ jsx55("div", { className: "shrink-0 text-[13px] font-medium whitespace-nowrap", children: brand }),
4068
+ /* @__PURE__ */ jsxs47(RadixNav.Root, { className: "relative flex-1", delayDuration: 120, children: [
4069
+ /* @__PURE__ */ jsx55(RadixNav.List, { className: "m-0! flex list-none! items-center gap-1 p-0! [&_li]:m-0!", children: items.map(
4070
+ (item) => item.children?.length ? /* @__PURE__ */ jsx55(
3944
4071
  HorizontalDropdown,
3945
4072
  {
3946
4073
  item,
@@ -3949,7 +4076,7 @@ var NavBar = forwardRef52(function NavBar2({
3949
4076
  onActivate: handleItemActivate
3950
4077
  },
3951
4078
  item.id
3952
- ) : /* @__PURE__ */ jsx54(RadixNav.Item, { children: /* @__PURE__ */ jsx54(
4079
+ ) : /* @__PURE__ */ jsx55(RadixNav.Item, { children: /* @__PURE__ */ jsx55(
3953
4080
  HorizontalLink,
3954
4081
  {
3955
4082
  item,
@@ -3958,13 +4085,13 @@ var NavBar = forwardRef52(function NavBar2({
3958
4085
  }
3959
4086
  ) }, item.id)
3960
4087
  ) }),
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)]" }) })
4088
+ /* @__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
4089
  ] }),
3963
- actions && /* @__PURE__ */ jsx54("div", { className: "flex items-center gap-3", children: actions })
4090
+ actions && /* @__PURE__ */ jsx55("div", { className: "flex items-center gap-3", children: actions })
3964
4091
  ]
3965
4092
  }
3966
4093
  ),
3967
- responsive && /* @__PURE__ */ jsx54(
4094
+ responsive && /* @__PURE__ */ jsx55(
3968
4095
  Drawer,
3969
4096
  {
3970
4097
  open: drawerOpen,
@@ -3977,9 +4104,9 @@ var NavBar = forwardRef52(function NavBar2({
3977
4104
  )
3978
4105
  ] });
3979
4106
  }
3980
- return /* @__PURE__ */ jsxs46(Fragment3, { children: [
4107
+ return /* @__PURE__ */ jsxs47(Fragment3, { children: [
3981
4108
  mobileBar,
3982
- /* @__PURE__ */ jsxs46(
4109
+ /* @__PURE__ */ jsxs47(
3983
4110
  "aside",
3984
4111
  {
3985
4112
  ref,
@@ -3992,8 +4119,8 @@ var NavBar = forwardRef52(function NavBar2({
3992
4119
  ),
3993
4120
  ...props,
3994
4121
  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(
4122
+ brand && /* @__PURE__ */ jsx55("div", { className: "px-2 py-1 text-[13px] font-medium", children: brand }),
4123
+ /* @__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
4124
  VerticalItem,
3998
4125
  {
3999
4126
  item,
@@ -4002,11 +4129,11 @@ var NavBar = forwardRef52(function NavBar2({
4002
4129
  },
4003
4130
  item.id
4004
4131
  )) }),
4005
- actions && /* @__PURE__ */ jsx54("div", { className: "border-border mt-auto flex flex-col gap-2 border-t pt-3", children: actions })
4132
+ actions && /* @__PURE__ */ jsx55("div", { className: "border-border mt-auto flex flex-col gap-2 border-t pt-3", children: actions })
4006
4133
  ]
4007
4134
  }
4008
4135
  ),
4009
- responsive && /* @__PURE__ */ jsx54(
4136
+ responsive && /* @__PURE__ */ jsx55(
4010
4137
  Drawer,
4011
4138
  {
4012
4139
  open: drawerOpen,
@@ -4035,13 +4162,13 @@ function HorizontalLink({ item, active, onActivate }) {
4035
4162
  }
4036
4163
  onActivate(item.id);
4037
4164
  };
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 })
4165
+ const inner = /* @__PURE__ */ jsxs47(Fragment3, { children: [
4166
+ item.icon != null && /* @__PURE__ */ jsx55("span", { "aria-hidden": true, className: "opacity-80", children: item.icon }),
4167
+ /* @__PURE__ */ jsx55("span", { children: item.label }),
4168
+ item.badge != null && /* @__PURE__ */ jsx55(ItemBadge, { active, children: item.badge })
4042
4169
  ] });
4043
4170
  if (item.href) {
4044
- return /* @__PURE__ */ jsx54(RadixNav.Link, { asChild: true, active, children: /* @__PURE__ */ jsx54(
4171
+ return /* @__PURE__ */ jsx55(RadixNav.Link, { asChild: true, active, children: /* @__PURE__ */ jsx55(
4045
4172
  "a",
4046
4173
  {
4047
4174
  href: item.href,
@@ -4053,7 +4180,7 @@ function HorizontalLink({ item, active, onActivate }) {
4053
4180
  }
4054
4181
  ) });
4055
4182
  }
4056
- return /* @__PURE__ */ jsx54(RadixNav.Link, { asChild: true, active, children: /* @__PURE__ */ jsx54(
4183
+ return /* @__PURE__ */ jsx55(RadixNav.Link, { asChild: true, active, children: /* @__PURE__ */ jsx55(
4057
4184
  "button",
4058
4185
  {
4059
4186
  type: "button",
@@ -4066,8 +4193,8 @@ function HorizontalLink({ item, active, onActivate }) {
4066
4193
  ) });
4067
4194
  }
4068
4195
  function HorizontalDropdown({ item, active, activeId, onActivate }) {
4069
- return /* @__PURE__ */ jsxs46(RadixNav.Item, { children: [
4070
- /* @__PURE__ */ jsxs46(
4196
+ return /* @__PURE__ */ jsxs47(RadixNav.Item, { children: [
4197
+ /* @__PURE__ */ jsxs47(
4071
4198
  RadixNav.Trigger,
4072
4199
  {
4073
4200
  className: cn(
@@ -4079,9 +4206,9 @@ function HorizontalDropdown({ item, active, activeId, onActivate }) {
4079
4206
  ),
4080
4207
  disabled: item.disabled,
4081
4208
  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(
4209
+ item.icon != null && /* @__PURE__ */ jsx55("span", { "aria-hidden": true, className: "opacity-80", children: item.icon }),
4210
+ /* @__PURE__ */ jsx55("span", { children: item.label }),
4211
+ /* @__PURE__ */ jsx55(
4085
4212
  "span",
4086
4213
  {
4087
4214
  "aria-hidden": true,
@@ -4092,7 +4219,7 @@ function HorizontalDropdown({ item, active, activeId, onActivate }) {
4092
4219
  ]
4093
4220
  }
4094
4221
  ),
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)) }) })
4222
+ /* @__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
4223
  ] });
4097
4224
  }
4098
4225
  function DropdownLink({ item, active, onActivate }) {
@@ -4109,13 +4236,13 @@ function DropdownLink({ item, active, onActivate }) {
4109
4236
  }
4110
4237
  onActivate(item.id);
4111
4238
  };
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 })
4239
+ const inner = /* @__PURE__ */ jsxs47(Fragment3, { children: [
4240
+ item.icon != null && /* @__PURE__ */ jsx55("span", { "aria-hidden": true, className: "opacity-80", children: item.icon }),
4241
+ /* @__PURE__ */ jsx55("span", { className: "flex-1", children: item.label }),
4242
+ item.badge != null && /* @__PURE__ */ jsx55(ItemBadge, { active, children: item.badge })
4116
4243
  ] });
4117
4244
  if (item.href) {
4118
- return /* @__PURE__ */ jsx54(RadixNav.Link, { asChild: true, active, children: /* @__PURE__ */ jsx54(
4245
+ return /* @__PURE__ */ jsx55(RadixNav.Link, { asChild: true, active, children: /* @__PURE__ */ jsx55(
4119
4246
  "a",
4120
4247
  {
4121
4248
  href: item.href,
@@ -4127,7 +4254,7 @@ function DropdownLink({ item, active, onActivate }) {
4127
4254
  }
4128
4255
  ) });
4129
4256
  }
4130
- return /* @__PURE__ */ jsx54(RadixNav.Link, { asChild: true, active, children: /* @__PURE__ */ jsx54(
4257
+ return /* @__PURE__ */ jsx55(RadixNav.Link, { asChild: true, active, children: /* @__PURE__ */ jsx55(
4131
4258
  "button",
4132
4259
  {
4133
4260
  type: "button",
@@ -4156,7 +4283,7 @@ function VerticalItem({ item, activeId, onActivate }) {
4156
4283
  }
4157
4284
  onActivate(item.id);
4158
4285
  };
4159
- return /* @__PURE__ */ jsx54(
4286
+ return /* @__PURE__ */ jsx55(
4160
4287
  NavItem,
4161
4288
  {
4162
4289
  icon: item.icon,
@@ -4169,8 +4296,8 @@ function VerticalItem({ item, activeId, onActivate }) {
4169
4296
  }
4170
4297
  );
4171
4298
  }
4172
- return /* @__PURE__ */ jsxs46("div", { className: "flex flex-col", children: [
4173
- /* @__PURE__ */ jsxs46(
4299
+ return /* @__PURE__ */ jsxs47("div", { className: "flex flex-col", children: [
4300
+ /* @__PURE__ */ jsxs47(
4174
4301
  "button",
4175
4302
  {
4176
4303
  type: "button",
@@ -4186,18 +4313,18 @@ function VerticalItem({ item, activeId, onActivate }) {
4186
4313
  item.disabled && "pointer-events-none opacity-50"
4187
4314
  ),
4188
4315
  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" })
4316
+ item.icon != null && /* @__PURE__ */ jsx55("span", { "aria-hidden": true, className: "w-[14px] text-center opacity-80", children: item.icon }),
4317
+ /* @__PURE__ */ jsx55("span", { className: "flex-1 truncate", children: item.label }),
4318
+ item.badge != null && /* @__PURE__ */ jsx55(ItemBadge, { active: treeActive, children: item.badge }),
4319
+ /* @__PURE__ */ jsx55("span", { "aria-hidden": true, className: "text-[10px] opacity-60", children: open ? "\u25BE" : "\u25B8" })
4193
4320
  ]
4194
4321
  }
4195
4322
  ),
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)) })
4323
+ 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
4324
  ] });
4198
4325
  }
4199
4326
  function ItemBadge({ active, children }) {
4200
- return /* @__PURE__ */ jsx54(
4327
+ return /* @__PURE__ */ jsx55(
4201
4328
  "span",
4202
4329
  {
4203
4330
  className: cn(
@@ -4210,8 +4337,8 @@ function ItemBadge({ active, children }) {
4210
4337
  }
4211
4338
 
4212
4339
  // 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";
4340
+ import { forwardRef as forwardRef54 } from "react";
4341
+ import { Fragment as Fragment4, jsx as jsx56, jsxs as jsxs48 } from "react/jsx-runtime";
4215
4342
  var statusDot = {
4216
4343
  pending: "off",
4217
4344
  "in-progress": "sync",
@@ -4222,11 +4349,11 @@ var labelStateClass = {
4222
4349
  "in-progress": "text-text",
4223
4350
  done: "text-text-dim line-through"
4224
4351
  };
4225
- var OnboardingChecklist = forwardRef53(
4352
+ var OnboardingChecklist = forwardRef54(
4226
4353
  function OnboardingChecklist2({ items, onItemClick, title = "Get started", progressLabel, hideProgress, className, ...props }, ref) {
4227
4354
  const total = items.length;
4228
4355
  const done = items.filter((i) => i.status === "done").length;
4229
- return /* @__PURE__ */ jsxs47(
4356
+ return /* @__PURE__ */ jsxs48(
4230
4357
  "section",
4231
4358
  {
4232
4359
  ref,
@@ -4237,11 +4364,11 @@ var OnboardingChecklist = forwardRef53(
4237
4364
  ),
4238
4365
  ...props,
4239
4366
  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` })
4367
+ /* @__PURE__ */ jsxs48("header", { className: "flex items-center gap-2", children: [
4368
+ /* @__PURE__ */ jsx56("span", { className: "text-[14px] font-medium", children: title }),
4369
+ /* @__PURE__ */ jsx56("span", { className: "text-text-dim ml-auto font-mono text-[11px] tabular-nums", children: progressLabel ?? `${done} of ${total} complete` })
4243
4370
  ] }),
4244
- !hideProgress && total > 0 && /* @__PURE__ */ jsx55(
4371
+ !hideProgress && total > 0 && /* @__PURE__ */ jsx56(
4245
4372
  "div",
4246
4373
  {
4247
4374
  role: "progressbar",
@@ -4250,7 +4377,7 @@ var OnboardingChecklist = forwardRef53(
4250
4377
  "aria-valuenow": done,
4251
4378
  "aria-label": typeof title === "string" ? `${title} progress` : "Setup progress",
4252
4379
  className: "bg-panel-2 h-[3px] w-full overflow-hidden rounded-full",
4253
- children: /* @__PURE__ */ jsx55(
4380
+ children: /* @__PURE__ */ jsx56(
4254
4381
  "span",
4255
4382
  {
4256
4383
  "aria-hidden": true,
@@ -4263,10 +4390,10 @@ var OnboardingChecklist = forwardRef53(
4263
4390
  )
4264
4391
  }
4265
4392
  ),
4266
- /* @__PURE__ */ jsx55("ul", { className: "m-0 flex list-none flex-col gap-1 p-0", children: items.map((item) => {
4393
+ /* @__PURE__ */ jsx56("ul", { className: "m-0 flex list-none flex-col gap-1 p-0", children: items.map((item) => {
4267
4394
  const interactive = typeof onItemClick === "function";
4268
- const labelBlock = /* @__PURE__ */ jsxs47(Fragment4, { children: [
4269
- /* @__PURE__ */ jsx55(
4395
+ const labelBlock = /* @__PURE__ */ jsxs48(Fragment4, { children: [
4396
+ /* @__PURE__ */ jsx56(
4270
4397
  StatusDot,
4271
4398
  {
4272
4399
  state: statusDot[item.status],
@@ -4275,17 +4402,17 @@ var OnboardingChecklist = forwardRef53(
4275
4402
  className: "mt-[3px]"
4276
4403
  }
4277
4404
  ),
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 })
4405
+ /* @__PURE__ */ jsxs48("div", { className: "flex min-w-0 flex-1 flex-col gap-[2px]", children: [
4406
+ /* @__PURE__ */ jsx56("span", { className: cn("text-[13px]", labelStateClass[item.status]), children: item.label }),
4407
+ item.description && /* @__PURE__ */ jsx56("span", { className: "text-text-muted text-[12px] leading-[1.45]", children: item.description })
4281
4408
  ] })
4282
4409
  ] });
4283
4410
  const labelRegionClass = cn(
4284
4411
  "flex flex-1 items-start gap-3 rounded-md px-2 py-2 text-left transition-colors duration-(--duration-micro)",
4285
4412
  interactive && "cursor-pointer outline-none hover:bg-panel-2 focus-visible:ring-[3px] focus-visible:ring-accent-dim"
4286
4413
  );
4287
- return /* @__PURE__ */ jsxs47("li", { className: "flex items-start gap-2", children: [
4288
- interactive ? /* @__PURE__ */ jsx55(
4414
+ return /* @__PURE__ */ jsxs48("li", { className: "flex items-start gap-2", children: [
4415
+ interactive ? /* @__PURE__ */ jsx56(
4289
4416
  "button",
4290
4417
  {
4291
4418
  type: "button",
@@ -4294,8 +4421,8 @@ var OnboardingChecklist = forwardRef53(
4294
4421
  className: labelRegionClass,
4295
4422
  children: labelBlock
4296
4423
  }
4297
- ) : /* @__PURE__ */ jsx55("div", { className: labelRegionClass, children: labelBlock }),
4298
- item.action && /* @__PURE__ */ jsx55("div", { className: "shrink-0 self-center", children: item.action })
4424
+ ) : /* @__PURE__ */ jsx56("div", { className: labelRegionClass, children: labelBlock }),
4425
+ item.action && /* @__PURE__ */ jsx56("div", { className: "shrink-0 self-center", children: item.action })
4299
4426
  ] }, item.id);
4300
4427
  }) })
4301
4428
  ]
@@ -4306,8 +4433,8 @@ var OnboardingChecklist = forwardRef53(
4306
4433
  OnboardingChecklist.displayName = "OnboardingChecklist";
4307
4434
 
4308
4435
  // src/patterns/Pagination/Pagination.tsx
4309
- import { forwardRef as forwardRef54 } from "react";
4310
- import { jsx as jsx56, jsxs as jsxs48 } from "react/jsx-runtime";
4436
+ import { forwardRef as forwardRef55 } from "react";
4437
+ import { jsx as jsx57, jsxs as jsxs49 } from "react/jsx-runtime";
4311
4438
  function buildRange(page, total, siblings) {
4312
4439
  if (total <= 0) return [];
4313
4440
  const items = [];
@@ -4320,9 +4447,9 @@ function buildRange(page, total, siblings) {
4320
4447
  if (total > 1) items.push(total);
4321
4448
  return items;
4322
4449
  }
4323
- var Pagination = forwardRef54(function Pagination2({ page, total, onPageChange, siblings = 1, className, ...props }, ref) {
4450
+ var Pagination = forwardRef55(function Pagination2({ page, total, onPageChange, siblings = 1, className, ...props }, ref) {
4324
4451
  const items = buildRange(page, total, siblings);
4325
- return /* @__PURE__ */ jsxs48(
4452
+ return /* @__PURE__ */ jsxs49(
4326
4453
  "nav",
4327
4454
  {
4328
4455
  ref,
@@ -4330,7 +4457,7 @@ var Pagination = forwardRef54(function Pagination2({ page, total, onPageChange,
4330
4457
  className: cn("inline-flex items-center gap-1", className),
4331
4458
  ...props,
4332
4459
  children: [
4333
- /* @__PURE__ */ jsx56(
4460
+ /* @__PURE__ */ jsx57(
4334
4461
  IconButton,
4335
4462
  {
4336
4463
  size: "sm",
@@ -4343,7 +4470,7 @@ var Pagination = forwardRef54(function Pagination2({ page, total, onPageChange,
4343
4470
  ),
4344
4471
  items.map((item, i) => {
4345
4472
  if (item === "start-ellipsis" || item === "end-ellipsis") {
4346
- return /* @__PURE__ */ jsx56(
4473
+ return /* @__PURE__ */ jsx57(
4347
4474
  "span",
4348
4475
  {
4349
4476
  "aria-hidden": true,
@@ -4354,7 +4481,7 @@ var Pagination = forwardRef54(function Pagination2({ page, total, onPageChange,
4354
4481
  );
4355
4482
  }
4356
4483
  const isActive = item === page;
4357
- return /* @__PURE__ */ jsx56(
4484
+ return /* @__PURE__ */ jsx57(
4358
4485
  "button",
4359
4486
  {
4360
4487
  type: "button",
@@ -4372,7 +4499,7 @@ var Pagination = forwardRef54(function Pagination2({ page, total, onPageChange,
4372
4499
  item
4373
4500
  );
4374
4501
  }),
4375
- /* @__PURE__ */ jsx56(
4502
+ /* @__PURE__ */ jsx57(
4376
4503
  IconButton,
4377
4504
  {
4378
4505
  size: "sm",
@@ -4391,8 +4518,8 @@ Pagination.displayName = "Pagination";
4391
4518
 
4392
4519
  // src/patterns/Progress/Progress.tsx
4393
4520
  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";
4521
+ import { forwardRef as forwardRef56 } from "react";
4522
+ import { jsx as jsx58, jsxs as jsxs50 } from "react/jsx-runtime";
4396
4523
  var trackStyles = cva11("w-full rounded-full bg-panel-2 overflow-hidden", {
4397
4524
  variants: {
4398
4525
  size: {
@@ -4414,7 +4541,7 @@ var fillStyles = cva11("h-full rounded-full transition-[width] duration-(--durat
4414
4541
  },
4415
4542
  defaultVariants: { tone: "accent" }
4416
4543
  });
4417
- var Progress = forwardRef55(function Progress2({
4544
+ var Progress = forwardRef56(function Progress2({
4418
4545
  value = 0,
4419
4546
  max = 100,
4420
4547
  indeterminate = false,
@@ -4428,15 +4555,15 @@ var Progress = forwardRef55(function Progress2({
4428
4555
  const clamped = Math.min(max, Math.max(0, value));
4429
4556
  const pct = max > 0 ? clamped / max * 100 : 0;
4430
4557
  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: [
4558
+ return /* @__PURE__ */ jsxs50("div", { ref, className: cn("flex w-full flex-col gap-2", className), ...props, children: [
4559
+ label != null && /* @__PURE__ */ jsxs50("div", { className: "flex text-[12px]", children: [
4560
+ /* @__PURE__ */ jsx58("span", { className: "text-text-muted", children: label }),
4561
+ showValue && !indeterminate && /* @__PURE__ */ jsxs50("span", { className: "text-text ml-auto font-mono tabular-nums", children: [
4435
4562
  display,
4436
4563
  "%"
4437
4564
  ] })
4438
4565
  ] }),
4439
- /* @__PURE__ */ jsx57(
4566
+ /* @__PURE__ */ jsx58(
4440
4567
  "div",
4441
4568
  {
4442
4569
  role: "progressbar",
@@ -4445,7 +4572,7 @@ var Progress = forwardRef55(function Progress2({
4445
4572
  "aria-valuenow": indeterminate ? void 0 : display,
4446
4573
  "aria-label": typeof label === "string" ? label : void 0,
4447
4574
  className: trackStyles({ size }),
4448
- children: indeterminate ? /* @__PURE__ */ jsx57(
4575
+ children: indeterminate ? /* @__PURE__ */ jsx58(
4449
4576
  "span",
4450
4577
  {
4451
4578
  "aria-hidden": true,
@@ -4455,16 +4582,61 @@ var Progress = forwardRef55(function Progress2({
4455
4582
  "animate-[ship-indeterminate_1.4s_linear_infinite]"
4456
4583
  )
4457
4584
  }
4458
- ) : /* @__PURE__ */ jsx57("span", { "aria-hidden": true, className: fillStyles({ tone }), style: { width: `${pct}%` } })
4585
+ ) : /* @__PURE__ */ jsx58("span", { "aria-hidden": true, className: fillStyles({ tone }), style: { width: `${pct}%` } })
4459
4586
  }
4460
4587
  )
4461
4588
  ] });
4462
4589
  });
4463
4590
  Progress.displayName = "Progress";
4464
4591
 
4592
+ // src/patterns/PullToRefresh/PullToRefresh.tsx
4593
+ import { forwardRef as forwardRef57 } from "react";
4594
+ import { jsx as jsx59, jsxs as jsxs51 } from "react/jsx-runtime";
4595
+ var labels = {
4596
+ idle: "Pull to refresh",
4597
+ pulling: "Pull to refresh",
4598
+ ready: "Release to refresh",
4599
+ loading: "Refreshing\u2026"
4600
+ };
4601
+ var PullToRefresh = forwardRef57(function PullToRefresh2({ state = "idle", label, className, ...props }, ref) {
4602
+ const isLoading = state === "loading";
4603
+ const transform = state === "ready" ? "rotate(180deg)" : state === "pulling" ? "rotate(90deg)" : "rotate(0deg)";
4604
+ return /* @__PURE__ */ jsxs51(
4605
+ "div",
4606
+ {
4607
+ ref,
4608
+ role: "status",
4609
+ "aria-live": "polite",
4610
+ "aria-busy": isLoading || void 0,
4611
+ className: cn("text-text-muted flex flex-col items-center gap-[6px] py-3", className),
4612
+ ...props,
4613
+ children: [
4614
+ /* @__PURE__ */ jsx59(
4615
+ "div",
4616
+ {
4617
+ "aria-hidden": true,
4618
+ className: cn(
4619
+ "border-border border-t-accent rounded-full border-2",
4620
+ isLoading && "animate-[ship-spin_700ms_linear_infinite]"
4621
+ ),
4622
+ style: {
4623
+ width: 22,
4624
+ height: 22,
4625
+ transform: isLoading ? void 0 : transform,
4626
+ transition: isLoading ? void 0 : "transform 200ms var(--easing-out)"
4627
+ }
4628
+ }
4629
+ ),
4630
+ /* @__PURE__ */ jsx59("span", { className: "text-m-eyebrow font-mono tracking-wide uppercase", children: label ?? labels[state] })
4631
+ ]
4632
+ }
4633
+ );
4634
+ });
4635
+ PullToRefresh.displayName = "PullToRefresh";
4636
+
4465
4637
  // 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";
4638
+ import { forwardRef as forwardRef58, useMemo as useMemo5 } from "react";
4639
+ import { jsx as jsx60, jsxs as jsxs52 } from "react/jsx-runtime";
4468
4640
  function buildPath(values, w, h) {
4469
4641
  if (values.length === 0) return { line: "", area: "" };
4470
4642
  const pad = 2;
@@ -4483,7 +4655,7 @@ function buildPath(values, w, h) {
4483
4655
  )} L${pad.toFixed(2)},${(h - pad).toFixed(2)} Z`;
4484
4656
  return { line, area };
4485
4657
  }
4486
- var Sparkline = forwardRef56(function Sparkline2({
4658
+ var Sparkline = forwardRef58(function Sparkline2({
4487
4659
  values,
4488
4660
  width = 160,
4489
4661
  height = 32,
@@ -4495,7 +4667,7 @@ var Sparkline = forwardRef56(function Sparkline2({
4495
4667
  ...props
4496
4668
  }, ref) {
4497
4669
  const { line, area } = useMemo5(() => buildPath(values, width, height), [values, width, height]);
4498
- return /* @__PURE__ */ jsxs50(
4670
+ return /* @__PURE__ */ jsxs52(
4499
4671
  "svg",
4500
4672
  {
4501
4673
  ref,
@@ -4507,8 +4679,8 @@ var Sparkline = forwardRef56(function Sparkline2({
4507
4679
  className: cn("inline-block", className),
4508
4680
  ...props,
4509
4681
  children: [
4510
- fill && /* @__PURE__ */ jsx58("path", { d: area, fill: stroke, fillOpacity: 0.16, stroke: "none" }),
4511
- /* @__PURE__ */ jsx58(
4682
+ fill && /* @__PURE__ */ jsx60("path", { d: area, fill: stroke, fillOpacity: 0.16, stroke: "none" }),
4683
+ /* @__PURE__ */ jsx60(
4512
4684
  "path",
4513
4685
  {
4514
4686
  d: line,
@@ -4526,16 +4698,16 @@ var Sparkline = forwardRef56(function Sparkline2({
4526
4698
  Sparkline.displayName = "Sparkline";
4527
4699
 
4528
4700
  // src/patterns/Spinner/Spinner.tsx
4529
- import { forwardRef as forwardRef57 } from "react";
4530
- import { jsx as jsx59 } from "react/jsx-runtime";
4701
+ import { forwardRef as forwardRef59 } from "react";
4702
+ import { jsx as jsx61 } from "react/jsx-runtime";
4531
4703
  var sizes = {
4532
4704
  sm: { box: "h-3 w-3", border: "border-[2px]" },
4533
4705
  md: { box: "h-4 w-4", border: "border-[2px]" },
4534
4706
  lg: { box: "h-5 w-5", border: "border-[2px]" }
4535
4707
  };
4536
- var Spinner2 = forwardRef57(function Spinner3({ size = "md", label = "Loading", className, ...props }, ref) {
4708
+ var Spinner2 = forwardRef59(function Spinner3({ size = "md", label = "Loading", className, ...props }, ref) {
4537
4709
  const s = sizes[size];
4538
- return /* @__PURE__ */ jsx59(
4710
+ return /* @__PURE__ */ jsx61(
4539
4711
  "span",
4540
4712
  {
4541
4713
  ref,
@@ -4543,7 +4715,7 @@ var Spinner2 = forwardRef57(function Spinner3({ size = "md", label = "Loading",
4543
4715
  "aria-label": label,
4544
4716
  className: cn("inline-block", className),
4545
4717
  ...props,
4546
- children: /* @__PURE__ */ jsx59(
4718
+ children: /* @__PURE__ */ jsx61(
4547
4719
  "span",
4548
4720
  {
4549
4721
  "aria-hidden": true,
@@ -4560,8 +4732,8 @@ var Spinner2 = forwardRef57(function Spinner3({ size = "md", label = "Loading",
4560
4732
  Spinner2.displayName = "Spinner";
4561
4733
 
4562
4734
  // 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";
4735
+ import { forwardRef as forwardRef60, Fragment as Fragment5 } from "react";
4736
+ import { jsx as jsx62, jsxs as jsxs53 } from "react/jsx-runtime";
4565
4737
  var dotBase = "h-6 w-6 rounded-full grid place-items-center text-[11px] font-mono font-semibold border";
4566
4738
  var dotStateClass = {
4567
4739
  done: "bg-accent text-on-accent border-accent",
@@ -4578,8 +4750,8 @@ function stateFor(index, current) {
4578
4750
  if (index === current) return "current";
4579
4751
  return "upcoming";
4580
4752
  }
4581
- var Stepper = forwardRef58(function Stepper2({ steps, current, className, ...props }, ref) {
4582
- return /* @__PURE__ */ jsx60(
4753
+ var Stepper = forwardRef60(function Stepper2({ steps, current, className, ...props }, ref) {
4754
+ return /* @__PURE__ */ jsx62(
4583
4755
  "ol",
4584
4756
  {
4585
4757
  ref,
@@ -4591,19 +4763,19 @@ var Stepper = forwardRef58(function Stepper2({ steps, current, className, ...pro
4591
4763
  const id = typeof step === "string" ? void 0 : step.id;
4592
4764
  const state = stateFor(i, current);
4593
4765
  const connectorActive = i < current;
4594
- return /* @__PURE__ */ jsxs51(Fragment5, { children: [
4595
- /* @__PURE__ */ jsxs51(
4766
+ return /* @__PURE__ */ jsxs53(Fragment5, { children: [
4767
+ /* @__PURE__ */ jsxs53(
4596
4768
  "li",
4597
4769
  {
4598
4770
  "aria-current": state === "current" ? "step" : void 0,
4599
4771
  className: "flex items-center gap-2",
4600
4772
  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 })
4773
+ /* @__PURE__ */ jsx62("span", { "aria-hidden": true, className: cn(dotBase, dotStateClass[state]), children: state === "done" ? "\u2713" : i + 1 }),
4774
+ /* @__PURE__ */ jsx62("span", { className: cn("text-[12px]", labelStateClass2[state]), children: label })
4603
4775
  ]
4604
4776
  }
4605
4777
  ),
4606
- i < steps.length - 1 && /* @__PURE__ */ jsx60(
4778
+ i < steps.length - 1 && /* @__PURE__ */ jsx62(
4607
4779
  "span",
4608
4780
  {
4609
4781
  "aria-hidden": true,
@@ -4617,11 +4789,113 @@ var Stepper = forwardRef58(function Stepper2({ steps, current, className, ...pro
4617
4789
  });
4618
4790
  Stepper.displayName = "Stepper";
4619
4791
 
4792
+ // src/patterns/TabBar/TabBar.tsx
4793
+ import {
4794
+ forwardRef as forwardRef61,
4795
+ useCallback as useCallback11,
4796
+ useState as useState15
4797
+ } from "react";
4798
+ import { jsx as jsx63, jsxs as jsxs54 } from "react/jsx-runtime";
4799
+ var TabBar = forwardRef61(function TabBar2({ items, value, defaultValue, onValueChange, className, ...props }, ref) {
4800
+ const isControlled = value !== void 0;
4801
+ const [internalValue, setInternalValue] = useState15(defaultValue);
4802
+ const activeId = isControlled ? value : internalValue;
4803
+ const handleSelect = useCallback11(
4804
+ (id, e) => {
4805
+ if (!isControlled) setInternalValue(id);
4806
+ onValueChange?.(id);
4807
+ e.stopPropagation();
4808
+ },
4809
+ [isControlled, onValueChange]
4810
+ );
4811
+ return /* @__PURE__ */ jsx63(
4812
+ "nav",
4813
+ {
4814
+ ref,
4815
+ "aria-label": "Primary",
4816
+ className: cn(
4817
+ "border-border bg-panel h-tabbar grid items-center border-t",
4818
+ "pb-[env(safe-area-inset-bottom)]",
4819
+ className
4820
+ ),
4821
+ style: { gridTemplateColumns: `repeat(${items.length}, minmax(0, 1fr))` },
4822
+ ...props,
4823
+ children: items.map((item) => {
4824
+ const isActive = item.id === activeId;
4825
+ if (item.elevated) {
4826
+ return /* @__PURE__ */ jsx63("div", { className: "grid place-items-center", children: /* @__PURE__ */ jsxs54(
4827
+ "button",
4828
+ {
4829
+ type: "button",
4830
+ "aria-current": isActive ? "page" : void 0,
4831
+ disabled: item.disabled,
4832
+ onClick: (e) => handleSelect(item.id, e),
4833
+ className: cn(
4834
+ "bg-accent text-on-accent grid place-items-center rounded-2xl shadow-lg",
4835
+ "-mt-[10px] h-[52px] w-[52px]",
4836
+ "transition-[filter,transform] duration-(--duration-micro)",
4837
+ "hover:brightness-110 active:scale-95",
4838
+ "focus-visible:ring-accent-dim outline-none focus-visible:ring-[3px]",
4839
+ "disabled:cursor-not-allowed disabled:opacity-40"
4840
+ ),
4841
+ children: [
4842
+ /* @__PURE__ */ jsx63("span", { "aria-hidden": true, children: item.icon }),
4843
+ /* @__PURE__ */ jsx63("span", { className: "sr-only", children: item.label })
4844
+ ]
4845
+ }
4846
+ ) }, item.id);
4847
+ }
4848
+ return /* @__PURE__ */ jsxs54(
4849
+ "button",
4850
+ {
4851
+ type: "button",
4852
+ "aria-current": isActive ? "page" : void 0,
4853
+ disabled: item.disabled,
4854
+ onClick: (e) => handleSelect(item.id, e),
4855
+ className: cn(
4856
+ "flex flex-col items-center justify-center gap-[3px] border-0 bg-transparent",
4857
+ "h-full cursor-pointer outline-none",
4858
+ "focus-visible:ring-accent-dim focus-visible:ring-[3px]",
4859
+ "disabled:cursor-not-allowed disabled:opacity-40",
4860
+ isActive ? "text-accent-text" : "text-text-muted hover:text-text"
4861
+ ),
4862
+ children: [
4863
+ /* @__PURE__ */ jsxs54("span", { className: "relative inline-flex", "aria-hidden": true, children: [
4864
+ item.icon,
4865
+ item.badge != null && /* @__PURE__ */ jsx63(
4866
+ "span",
4867
+ {
4868
+ className: cn(
4869
+ "absolute -top-1 -right-2 rounded-full font-mono leading-none",
4870
+ "bg-err text-on-accent min-w-[16px] px-[5px] py-[2px] text-center text-[9px]"
4871
+ ),
4872
+ children: item.badge
4873
+ }
4874
+ )
4875
+ ] }),
4876
+ /* @__PURE__ */ jsxs54("span", { className: "text-[10px] font-medium tracking-tight", children: [
4877
+ item.label,
4878
+ item.badge != null && /* @__PURE__ */ jsxs54("span", { className: "sr-only", children: [
4879
+ ", ",
4880
+ item.badge,
4881
+ " unread"
4882
+ ] })
4883
+ ] })
4884
+ ]
4885
+ },
4886
+ item.id
4887
+ );
4888
+ })
4889
+ }
4890
+ );
4891
+ });
4892
+ TabBar.displayName = "TabBar";
4893
+
4620
4894
  // src/patterns/Tabs/Tabs.tsx
4621
4895
  import * as RadixTabs from "@radix-ui/react-tabs";
4622
4896
  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";
4897
+ import { createContext as createContext2, forwardRef as forwardRef62, useContext as useContext2 } from "react";
4898
+ import { jsx as jsx64 } from "react/jsx-runtime";
4625
4899
  var TabsVariantContext = createContext2("underline");
4626
4900
  var tabsListStyles = cva12("", {
4627
4901
  variants: {
@@ -4652,8 +4926,8 @@ var tabsTriggerStyles = cva12(
4652
4926
  }
4653
4927
  }
4654
4928
  );
4655
- var Tabs = forwardRef59(function Tabs2({ variant = "underline", className, ...props }, ref) {
4656
- return /* @__PURE__ */ jsx61(TabsVariantContext.Provider, { value: variant, children: /* @__PURE__ */ jsx61(
4929
+ var Tabs = forwardRef62(function Tabs2({ variant = "underline", className, ...props }, ref) {
4930
+ return /* @__PURE__ */ jsx64(TabsVariantContext.Provider, { value: variant, children: /* @__PURE__ */ jsx64(
4657
4931
  RadixTabs.Root,
4658
4932
  {
4659
4933
  ref,
@@ -4663,14 +4937,14 @@ var Tabs = forwardRef59(function Tabs2({ variant = "underline", className, ...pr
4663
4937
  ) });
4664
4938
  });
4665
4939
  Tabs.displayName = "Tabs";
4666
- var TabsList = forwardRef59(function TabsList2({ className, ...props }, ref) {
4940
+ var TabsList = forwardRef62(function TabsList2({ className, ...props }, ref) {
4667
4941
  const variant = useContext2(TabsVariantContext);
4668
- return /* @__PURE__ */ jsx61(RadixTabs.List, { ref, className: cn(tabsListStyles({ variant }), className), ...props });
4942
+ return /* @__PURE__ */ jsx64(RadixTabs.List, { ref, className: cn(tabsListStyles({ variant }), className), ...props });
4669
4943
  });
4670
4944
  TabsList.displayName = "TabsList";
4671
- var Tab = forwardRef59(function Tab2({ className, ...props }, ref) {
4945
+ var Tab = forwardRef62(function Tab2({ className, ...props }, ref) {
4672
4946
  const variant = useContext2(TabsVariantContext);
4673
- return /* @__PURE__ */ jsx61(
4947
+ return /* @__PURE__ */ jsx64(
4674
4948
  RadixTabs.Trigger,
4675
4949
  {
4676
4950
  ref,
@@ -4680,9 +4954,9 @@ var Tab = forwardRef59(function Tab2({ className, ...props }, ref) {
4680
4954
  );
4681
4955
  });
4682
4956
  Tab.displayName = "Tab";
4683
- var TabsContent = forwardRef59(
4957
+ var TabsContent = forwardRef62(
4684
4958
  function TabsContent2({ className, ...props }, ref) {
4685
- return /* @__PURE__ */ jsx61(
4959
+ return /* @__PURE__ */ jsx64(
4686
4960
  RadixTabs.Content,
4687
4961
  {
4688
4962
  ref,
@@ -4698,8 +4972,8 @@ var TabsContent = forwardRef59(
4698
4972
  TabsContent.displayName = "TabsContent";
4699
4973
 
4700
4974
  // src/patterns/Timeline/Timeline.tsx
4701
- import { forwardRef as forwardRef60 } from "react";
4702
- import { jsx as jsx62, jsxs as jsxs52 } from "react/jsx-runtime";
4975
+ import { forwardRef as forwardRef63 } from "react";
4976
+ import { jsx as jsx65, jsxs as jsxs55 } from "react/jsx-runtime";
4703
4977
  var ringClass = {
4704
4978
  accent: "border-accent",
4705
4979
  ok: "border-ok",
@@ -4707,8 +4981,8 @@ var ringClass = {
4707
4981
  err: "border-err",
4708
4982
  muted: "border-text-dim"
4709
4983
  };
4710
- var Timeline = forwardRef60(function Timeline2({ events, className, children, ...props }, ref) {
4711
- return /* @__PURE__ */ jsx62(
4984
+ var Timeline = forwardRef63(function Timeline2({ events, className, children, ...props }, ref) {
4985
+ return /* @__PURE__ */ jsx65(
4712
4986
  "ol",
4713
4987
  {
4714
4988
  ref,
@@ -4718,14 +4992,14 @@ var Timeline = forwardRef60(function Timeline2({ events, className, children, ..
4718
4992
  className
4719
4993
  ),
4720
4994
  ...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
4995
+ children: events ? events.map((e, i) => /* @__PURE__ */ jsx65(TimelineItem, { tone: e.tone, time: e.time, description: e.description, children: e.title }, i)) : children
4722
4996
  }
4723
4997
  );
4724
4998
  });
4725
4999
  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(
5000
+ var TimelineItem = forwardRef63(function TimelineItem2({ tone = "accent", description, time, className, children, ...props }, ref) {
5001
+ return /* @__PURE__ */ jsxs55("li", { ref, className: cn("relative mb-[18px] last:mb-0", className), ...props, children: [
5002
+ /* @__PURE__ */ jsx65(
4729
5003
  "span",
4730
5004
  {
4731
5005
  "aria-hidden": true,
@@ -4735,15 +5009,15 @@ var TimelineItem = forwardRef60(function TimelineItem2({ tone = "accent", descri
4735
5009
  )
4736
5010
  }
4737
5011
  ),
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 })
5012
+ /* @__PURE__ */ jsx65("div", { className: "text-[13px] font-medium", children }),
5013
+ description && /* @__PURE__ */ jsx65("div", { className: "text-text-muted text-[12px]", children: description }),
5014
+ time && /* @__PURE__ */ jsx65("div", { className: "text-text-dim mt-[2px] font-mono text-[10px]", children: time })
4741
5015
  ] });
4742
5016
  });
4743
5017
  TimelineItem.displayName = "TimelineItem";
4744
5018
 
4745
5019
  // src/patterns/Timeline/ActivityTimeline.tsx
4746
- import { forwardRef as forwardRef61 } from "react";
5020
+ import { forwardRef as forwardRef64 } from "react";
4747
5021
 
4748
5022
  // src/patterns/Timeline/formatRelative.ts
4749
5023
  var SECOND = 1e3;
@@ -4778,7 +5052,7 @@ function formatRelative(input, now = /* @__PURE__ */ new Date()) {
4778
5052
  }
4779
5053
 
4780
5054
  // src/patterns/Timeline/ActivityTimeline.tsx
4781
- import { jsx as jsx63, jsxs as jsxs53 } from "react/jsx-runtime";
5055
+ import { jsx as jsx66, jsxs as jsxs56 } from "react/jsx-runtime";
4782
5056
  var ringClass2 = {
4783
5057
  accent: "border-accent",
4784
5058
  ok: "border-ok",
@@ -4786,10 +5060,10 @@ var ringClass2 = {
4786
5060
  err: "border-err",
4787
5061
  muted: "border-text-dim"
4788
5062
  };
4789
- var ActivityTimeline = forwardRef61(
5063
+ var ActivityTimeline = forwardRef64(
4790
5064
  function ActivityTimeline2({ events, relativeNow, className, ...props }, ref) {
4791
5065
  const now = relativeNow ?? /* @__PURE__ */ new Date();
4792
- return /* @__PURE__ */ jsx63(
5066
+ return /* @__PURE__ */ jsx66(
4793
5067
  "ol",
4794
5068
  {
4795
5069
  ref,
@@ -4802,8 +5076,8 @@ var ActivityTimeline = forwardRef61(
4802
5076
  children: events.map((event) => {
4803
5077
  const tone = event.tone ?? "accent";
4804
5078
  const time = formatRelative(event.at, now);
4805
- return /* @__PURE__ */ jsxs53("li", { className: "relative mb-4 last:mb-0", children: [
4806
- /* @__PURE__ */ jsx63(
5079
+ return /* @__PURE__ */ jsxs56("li", { className: "relative mb-4 last:mb-0", children: [
5080
+ /* @__PURE__ */ jsx66(
4807
5081
  "span",
4808
5082
  {
4809
5083
  "aria-hidden": true,
@@ -4813,16 +5087,16 @@ var ActivityTimeline = forwardRef61(
4813
5087
  )
4814
5088
  }
4815
5089
  ),
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 })
5090
+ /* @__PURE__ */ jsxs56("div", { className: "flex items-baseline gap-2", children: [
5091
+ event.icon && /* @__PURE__ */ jsx66("span", { "aria-hidden": true, className: "text-text-muted font-mono text-[12px]", children: event.icon }),
5092
+ /* @__PURE__ */ jsx66("div", { className: "text-[13px] font-medium", children: event.title }),
5093
+ time && /* @__PURE__ */ jsx66("time", { className: "text-text-dim ml-auto font-mono text-[10px]", children: time })
4820
5094
  ] }),
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 })
5095
+ event.actor && /* @__PURE__ */ jsxs56("div", { className: "text-text-muted mt-[2px] flex items-center gap-[6px] text-[12px]", children: [
5096
+ event.actor.avatar && /* @__PURE__ */ jsx66("span", { "aria-hidden": true, className: "inline-flex", children: event.actor.avatar }),
5097
+ /* @__PURE__ */ jsx66("span", { children: event.actor.name })
4824
5098
  ] }),
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 })
5099
+ 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
5100
  ] }, event.id);
4827
5101
  })
4828
5102
  }
@@ -4832,23 +5106,77 @@ var ActivityTimeline = forwardRef61(
4832
5106
  ActivityTimeline.displayName = "ActivityTimeline";
4833
5107
 
4834
5108
  // 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(
5109
+ import { forwardRef as forwardRef65 } from "react";
5110
+ import { jsx as jsx67, jsxs as jsxs57 } from "react/jsx-runtime";
5111
+ var Topbar = forwardRef65(function Topbar2({
5112
+ title,
5113
+ eyebrow,
5114
+ leading,
5115
+ back,
5116
+ onBack,
5117
+ actions,
5118
+ density = "comfortable",
5119
+ className,
5120
+ children,
5121
+ ...props
5122
+ }, ref) {
5123
+ const isTouch = density === "touch";
5124
+ const backHandler = typeof back === "function" ? back : back ? onBack : void 0;
5125
+ return /* @__PURE__ */ jsxs57(
4839
5126
  "header",
4840
5127
  {
4841
5128
  ref,
4842
5129
  className: cn(
4843
- "border-border bg-panel flex h-[52px] items-center gap-4 border-b px-5",
5130
+ "border-border bg-panel flex items-center border-b",
5131
+ isTouch ? "h-navbar gap-2 px-3" : "h-[52px] gap-4 px-5",
4844
5132
  className
4845
5133
  ),
4846
5134
  ...props,
4847
5135
  children: [
5136
+ isTouch && back && /* @__PURE__ */ jsx67(
5137
+ "button",
5138
+ {
5139
+ type: "button",
5140
+ onClick: backHandler,
5141
+ "aria-label": "Back",
5142
+ className: cn(
5143
+ "text-text inline-grid place-items-center rounded-md bg-transparent",
5144
+ // The back button is only rendered in touch density — use the
5145
+ // touch token (44pt) instead of `h-9 w-9` (36px) so it meets the
5146
+ // HIG minimum the rest of the touch surface enforces.
5147
+ "hover:bg-panel-2 h-touch w-touch",
5148
+ "focus-visible:ring-accent-dim outline-none focus-visible:ring-[3px]"
5149
+ ),
5150
+ children: /* @__PURE__ */ jsx67(
5151
+ "svg",
5152
+ {
5153
+ width: "20",
5154
+ height: "20",
5155
+ viewBox: "0 0 24 24",
5156
+ fill: "none",
5157
+ stroke: "currentColor",
5158
+ strokeWidth: "2",
5159
+ "aria-hidden": true,
5160
+ children: /* @__PURE__ */ jsx67("path", { d: "m15 18-6-6 6-6" })
5161
+ }
5162
+ )
5163
+ }
5164
+ ),
4848
5165
  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 }),
5166
+ (title || isTouch && eyebrow) && /* @__PURE__ */ jsxs57("div", { className: cn("min-w-0", isTouch && "flex-1"), children: [
5167
+ isTouch && eyebrow && /* @__PURE__ */ jsx67("div", { className: "text-m-eyebrow text-accent font-mono tracking-wide uppercase", children: eyebrow }),
5168
+ title && /* @__PURE__ */ jsx67(
5169
+ "div",
5170
+ {
5171
+ className: cn(
5172
+ isTouch ? "text-m-body-lg truncate font-semibold tracking-tight" : "text-[13px] font-medium"
5173
+ ),
5174
+ children: title
5175
+ }
5176
+ )
5177
+ ] }),
5178
+ !isTouch && /* @__PURE__ */ jsx67("div", { className: "flex flex-1 items-center" }),
5179
+ actions && /* @__PURE__ */ jsx67("div", { className: cn("flex items-center", isTouch ? "gap-1" : "gap-3"), children: actions }),
4852
5180
  children
4853
5181
  ]
4854
5182
  }
@@ -4858,14 +5186,14 @@ Topbar.displayName = "Topbar";
4858
5186
 
4859
5187
  // src/patterns/Tree/Tree.tsx
4860
5188
  import {
4861
- forwardRef as forwardRef63,
4862
- useCallback as useCallback11,
5189
+ forwardRef as forwardRef66,
5190
+ useCallback as useCallback12,
4863
5191
  useEffect as useEffect10,
4864
5192
  useMemo as useMemo6,
4865
5193
  useRef as useRef8,
4866
- useState as useState15
5194
+ useState as useState16
4867
5195
  } from "react";
4868
- import { jsx as jsx65, jsxs as jsxs55 } from "react/jsx-runtime";
5196
+ import { jsx as jsx68, jsxs as jsxs58 } from "react/jsx-runtime";
4869
5197
  var EMPTY_SET2 = /* @__PURE__ */ new Set();
4870
5198
  function flattenVisible(items, expanded, level, parentId, out) {
4871
5199
  for (const item of items) {
@@ -4876,7 +5204,7 @@ function flattenVisible(items, expanded, level, parentId, out) {
4876
5204
  }
4877
5205
  }
4878
5206
  }
4879
- var Tree = forwardRef63(function Tree2({
5207
+ var Tree = forwardRef66(function Tree2({
4880
5208
  items,
4881
5209
  expanded: expandedProp,
4882
5210
  defaultExpanded,
@@ -4904,7 +5232,7 @@ var Tree = forwardRef63(function Tree2({
4904
5232
  flattenVisible(items, expandedSet, 1, null, out);
4905
5233
  return out;
4906
5234
  }, [items, expandedSet]);
4907
- const [activeId, setActiveId] = useState15(null);
5235
+ const [activeId, setActiveId] = useState16(null);
4908
5236
  useEffect10(() => {
4909
5237
  if (activeId && !flatVisible.some((f) => f.id === activeId)) {
4910
5238
  setActiveId(null);
@@ -4916,7 +5244,7 @@ var Tree = forwardRef63(function Tree2({
4916
5244
  return flatVisible[0]?.id ?? null;
4917
5245
  }, [activeId, flatVisible, value]);
4918
5246
  const listRef = useRef8(null);
4919
- const setRefs = useCallback11(
5247
+ const setRefs = useCallback12(
4920
5248
  (node) => {
4921
5249
  listRef.current = node;
4922
5250
  if (typeof ref === "function") ref(node);
@@ -4924,20 +5252,20 @@ var Tree = forwardRef63(function Tree2({
4924
5252
  },
4925
5253
  [ref]
4926
5254
  );
4927
- const focusItem = useCallback11((id) => {
5255
+ const focusItem = useCallback12((id) => {
4928
5256
  const root = listRef.current;
4929
5257
  if (!root) return;
4930
5258
  const el = root.querySelector(`[data-treeitem-id="${CSS.escape(id)}"]`);
4931
5259
  el?.focus();
4932
5260
  }, []);
4933
- const moveActive = useCallback11(
5261
+ const moveActive = useCallback12(
4934
5262
  (id) => {
4935
5263
  setActiveId(id);
4936
5264
  queueMicrotask(() => focusItem(id));
4937
5265
  },
4938
5266
  [focusItem]
4939
5267
  );
4940
- const toggle = useCallback11(
5268
+ const toggle = useCallback12(
4941
5269
  (id) => {
4942
5270
  setExpanded((prev) => {
4943
5271
  const next = new Set(prev ?? EMPTY_SET2);
@@ -4948,7 +5276,7 @@ var Tree = forwardRef63(function Tree2({
4948
5276
  },
4949
5277
  [setExpanded]
4950
5278
  );
4951
- const expand = useCallback11(
5279
+ const expand = useCallback12(
4952
5280
  (id) => {
4953
5281
  setExpanded((prev) => {
4954
5282
  const base = prev ?? EMPTY_SET2;
@@ -4960,7 +5288,7 @@ var Tree = forwardRef63(function Tree2({
4960
5288
  },
4961
5289
  [setExpanded]
4962
5290
  );
4963
- const collapse = useCallback11(
5291
+ const collapse = useCallback12(
4964
5292
  (id) => {
4965
5293
  setExpanded((prev) => {
4966
5294
  const base = prev ?? EMPTY_SET2;
@@ -4972,13 +5300,13 @@ var Tree = forwardRef63(function Tree2({
4972
5300
  },
4973
5301
  [setExpanded]
4974
5302
  );
4975
- const selectItem = useCallback11(
5303
+ const selectItem = useCallback12(
4976
5304
  (id) => {
4977
5305
  setValue(id);
4978
5306
  },
4979
5307
  [setValue]
4980
5308
  );
4981
- const handleKeyDown = useCallback11(
5309
+ const handleKeyDown = useCallback12(
4982
5310
  (e) => {
4983
5311
  onKeyDown?.(e);
4984
5312
  if (e.defaultPrevented) return;
@@ -5058,7 +5386,7 @@ var Tree = forwardRef63(function Tree2({
5058
5386
  toggle
5059
5387
  ]
5060
5388
  );
5061
- return /* @__PURE__ */ jsx65(
5389
+ return /* @__PURE__ */ jsx68(
5062
5390
  "ul",
5063
5391
  {
5064
5392
  ref: setRefs,
@@ -5066,7 +5394,7 @@ var Tree = forwardRef63(function Tree2({
5066
5394
  className: cn("flex flex-col gap-px text-[12px]", className),
5067
5395
  onKeyDown: handleKeyDown,
5068
5396
  ...props,
5069
- children: items.map((item) => /* @__PURE__ */ jsx65(
5397
+ children: items.map((item) => /* @__PURE__ */ jsx68(
5070
5398
  TreeItemRow,
5071
5399
  {
5072
5400
  item,
@@ -5101,8 +5429,8 @@ function TreeItemRow({
5101
5429
  const isExpanded = hasChildren && expanded.has(item.id);
5102
5430
  const isSelected = selected === item.id;
5103
5431
  const isTabStop = tabStopId === item.id;
5104
- return /* @__PURE__ */ jsxs55("li", { role: "none", children: [
5105
- /* @__PURE__ */ jsxs55(
5432
+ return /* @__PURE__ */ jsxs58("li", { role: "none", children: [
5433
+ /* @__PURE__ */ jsxs58(
5106
5434
  "div",
5107
5435
  {
5108
5436
  role: "treeitem",
@@ -5125,14 +5453,14 @@ function TreeItemRow({
5125
5453
  isSelected ? "bg-accent-dim text-accent" : "text-text hover:bg-panel-2"
5126
5454
  ),
5127
5455
  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 }),
5456
+ /* @__PURE__ */ jsx68("span", { "aria-hidden": true, className: "text-text-dim grid w-3 place-items-center text-[10px]", children: hasChildren ? isExpanded ? "\u25BE" : "\u25B8" : "" }),
5457
+ item.icon && /* @__PURE__ */ jsx68("span", { "aria-hidden": true, className: "text-[12px] opacity-80", children: item.icon }),
5458
+ /* @__PURE__ */ jsx68("span", { className: "flex-1 truncate", children: item.label }),
5131
5459
  item.trailing
5132
5460
  ]
5133
5461
  }
5134
5462
  ),
5135
- hasChildren && isExpanded && /* @__PURE__ */ jsx65("ul", { role: "group", className: "flex flex-col gap-px", children: (item.children ?? []).map((child) => /* @__PURE__ */ jsx65(
5463
+ hasChildren && isExpanded && /* @__PURE__ */ jsx68("ul", { role: "group", className: "flex flex-col gap-px", children: (item.children ?? []).map((child) => /* @__PURE__ */ jsx68(
5136
5464
  TreeItemRow,
5137
5465
  {
5138
5466
  item: child,
@@ -5151,9 +5479,9 @@ function TreeItemRow({
5151
5479
 
5152
5480
  // src/patterns/WizardDialog/WizardDialog.tsx
5153
5481
  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({
5482
+ import { forwardRef as forwardRef67, useCallback as useCallback13, useMemo as useMemo7, useState as useState17 } from "react";
5483
+ import { jsx as jsx69, jsxs as jsxs59 } from "react/jsx-runtime";
5484
+ var WizardDialog = forwardRef67(function WizardDialog2({
5157
5485
  open,
5158
5486
  defaultOpen,
5159
5487
  onOpenChange,
@@ -5169,18 +5497,18 @@ var WizardDialog = forwardRef64(function WizardDialog2({
5169
5497
  cancelLabel,
5170
5498
  onCancel
5171
5499
  }, ref) {
5172
- const [current, setCurrent] = useState16(initialStep);
5500
+ const [current, setCurrent] = useState17(initialStep);
5173
5501
  const total = steps.length;
5174
5502
  const safeCurrent = Math.min(current, Math.max(0, total - 1));
5175
5503
  const step = steps[safeCurrent];
5176
- const goTo = useCallback12(
5504
+ const goTo = useCallback13(
5177
5505
  (index) => {
5178
5506
  setCurrent(Math.min(Math.max(0, index), Math.max(0, total - 1)));
5179
5507
  },
5180
5508
  [total]
5181
5509
  );
5182
- const goNext = useCallback12(() => setCurrent((c) => Math.min(c + 1, total - 1)), [total]);
5183
- const goBack = useCallback12(() => setCurrent((c) => Math.max(c - 1, 0)), []);
5510
+ const goNext = useCallback13(() => setCurrent((c) => Math.min(c + 1, total - 1)), [total]);
5511
+ const goBack = useCallback13(() => setCurrent((c) => Math.max(c - 1, 0)), []);
5184
5512
  const ctx = useMemo7(
5185
5513
  () => ({
5186
5514
  current: safeCurrent,
@@ -5204,23 +5532,23 @@ var WizardDialog = forwardRef64(function WizardDialog2({
5204
5532
  goNext();
5205
5533
  }
5206
5534
  };
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 })
5535
+ return /* @__PURE__ */ jsx69(DialogRoot, { open, defaultOpen, onOpenChange, children: /* @__PURE__ */ jsxs59(DialogContent, { ref, width, children: [
5536
+ title && /* @__PURE__ */ jsx69(WizardTitle, { children: title }),
5537
+ description && /* @__PURE__ */ jsx69(WizardDescription, { children: description }),
5538
+ /* @__PURE__ */ jsx69("div", { className: "mb-5", children: /* @__PURE__ */ jsx69(Stepper, { steps: stepperSteps, current: safeCurrent }) }),
5539
+ /* @__PURE__ */ jsx69("div", { className: "mb-5", children: body }),
5540
+ /* @__PURE__ */ jsxs59("div", { className: "flex justify-end gap-2", children: [
5541
+ cancelLabel && /* @__PURE__ */ jsx69(Button, { type: "button", variant: "ghost", onClick: onCancel, children: cancelLabel }),
5542
+ /* @__PURE__ */ jsx69(Button, { type: "button", variant: "secondary", onClick: goBack, disabled: ctx.isFirst, children: backLabel }),
5543
+ /* @__PURE__ */ jsx69(Button, { type: "button", variant: "primary", onClick: handlePrimary, disabled: !canAdvance, children: ctx.isLast ? completeLabel : nextLabel })
5216
5544
  ] })
5217
5545
  ] }) });
5218
5546
  });
5219
5547
  function WizardTitle({ children }) {
5220
- return /* @__PURE__ */ jsx66(RadixDialog5.Title, { className: "mb-2 text-[16px] font-medium", children });
5548
+ return /* @__PURE__ */ jsx69(RadixDialog5.Title, { className: "mb-2 text-[16px] font-medium", children });
5221
5549
  }
5222
5550
  function WizardDescription({ children }) {
5223
- return /* @__PURE__ */ jsx66(RadixDialog5.Description, { className: "text-text-muted mb-4 text-[13px] leading-[1.55]", children });
5551
+ return /* @__PURE__ */ jsx69(RadixDialog5.Description, { className: "text-text-muted mb-4 text-[13px] leading-[1.55]", children });
5224
5552
  }
5225
5553
  WizardDialog.displayName = "WizardDialog";
5226
5554
  export {
@@ -5287,6 +5615,7 @@ export {
5287
5615
  IconButton,
5288
5616
  Input,
5289
5617
  Kbd,
5618
+ LargeTitle,
5290
5619
  MenuCheckboxItem,
5291
5620
  MenuItem,
5292
5621
  MenuSeparator,
@@ -5311,6 +5640,7 @@ export {
5311
5640
  PopoverRoot,
5312
5641
  PopoverTrigger,
5313
5642
  Progress,
5643
+ PullToRefresh,
5314
5644
  RadialProgress,
5315
5645
  Radio,
5316
5646
  RadioGroup,
@@ -5337,6 +5667,7 @@ export {
5337
5667
  Stepper,
5338
5668
  Switch,
5339
5669
  Tab,
5670
+ TabBar,
5340
5671
  Tabs,
5341
5672
  TabsContent,
5342
5673
  TabsList,