@flytedan/flytebot-design-system 0.12.5 → 0.12.7

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
@@ -50,8 +50,13 @@ function Button({
50
50
  );
51
51
  }
52
52
 
53
+ // src/components/actions/overflowRowContext.ts
54
+ import * as React from "react";
55
+ var OverflowRowContext = React.createContext(false);
56
+ var useOverflowRow = () => React.useContext(OverflowRowContext);
57
+
53
58
  // src/components/actions/IconButton.tsx
54
- import { jsx as jsx2 } from "react/jsx-runtime";
59
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
55
60
  function IconButton({
56
61
  icon,
57
62
  label,
@@ -63,21 +68,26 @@ function IconButton({
63
68
  className = "",
64
69
  ...rest
65
70
  }) {
71
+ const overflowRow = useOverflowRow();
66
72
  const cls = [
67
73
  "fd-btn-icon",
68
74
  variant === "outline" ? "fd-btn-icon-outline" : variant === "solid" ? "fd-btn-icon-solid" : "",
69
75
  tone !== "neutral" ? "is-" + tone : "",
70
76
  size === "sm" ? "fd-btn-icon-sm" : size === "lg" ? "fd-btn-icon-lg" : "",
71
77
  round ? "fd-btn-icon-round" : "",
78
+ overflowRow ? "fd-btn-icon-row" : "",
72
79
  className
73
80
  ].filter(Boolean).join(" ");
74
- return /* @__PURE__ */ jsx2("button", { type: "button", className: cls, "aria-label": label, title: label, disabled, ...rest, children: /* @__PURE__ */ jsx2("i", { className: "ph ph-" + icon, "aria-hidden": "true" }) });
81
+ return /* @__PURE__ */ jsxs2("button", { type: "button", className: cls, "aria-label": label, title: label, disabled, ...rest, children: [
82
+ /* @__PURE__ */ jsx2("i", { className: "ph ph-" + icon, "aria-hidden": "true" }),
83
+ overflowRow ? /* @__PURE__ */ jsx2("span", { className: "fd-btn-icon-row-label", children: label }) : null
84
+ ] });
75
85
  }
76
86
 
77
87
  // src/components/actions/Popover.tsx
78
- import * as React from "react";
88
+ import * as React2 from "react";
79
89
  import { createPortal } from "react-dom";
80
- import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
90
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
81
91
  var MARGIN = 8;
82
92
  var parsePlacement = (p) => {
83
93
  const [side, align = "start"] = String(p || "bottom-start").split("-");
@@ -107,12 +117,12 @@ function measureLayer(el) {
107
117
  function usePopoverPosition(open, anchorRef, opts) {
108
118
  const o = opts || {};
109
119
  const { side: wantSide, align } = parsePlacement(o.placement);
110
- const [pos, setPos] = React.useState(null);
111
- const posRef = React.useRef(null);
112
- const detachRef = React.useRef(o.onDetach);
120
+ const [pos, setPos] = React2.useState(null);
121
+ const posRef = React2.useRef(null);
122
+ const detachRef = React2.useRef(o.onDetach);
113
123
  detachRef.current = o.onDetach;
114
124
  const layerRef = o.layerRef;
115
- React.useLayoutEffect(() => {
125
+ React2.useLayoutEffect(() => {
116
126
  if (!open || !anchorRef || !anchorRef.current) {
117
127
  posRef.current = null;
118
128
  setPos(null);
@@ -187,8 +197,8 @@ var portal = (node) => {
187
197
  };
188
198
  var ROOT_LAYER = 0;
189
199
  var LAYER_STEP = 10;
190
- var LayerContext = React.createContext(ROOT_LAYER);
191
- var useLayer = () => React.useContext(LayerContext);
200
+ var LayerContext = React2.createContext(ROOT_LAYER);
201
+ var useLayer = () => React2.useContext(LayerContext);
192
202
  var useOverlayLayer = (base) => {
193
203
  const parent = useLayer();
194
204
  return parent === ROOT_LAYER ? base : parent + LAYER_STEP;
@@ -218,7 +228,7 @@ function Popover({
218
228
  footer,
219
229
  children
220
230
  }) {
221
- const ref = React.useRef(null);
231
+ const ref = React2.useRef(null);
222
232
  const pos = usePopoverPosition(!!open, anchorRef, {
223
233
  placement,
224
234
  offset,
@@ -230,9 +240,9 @@ function Popover({
230
240
  onDetach: onClose,
231
241
  layerRef: ref
232
242
  });
233
- const restore = React.useRef(null);
243
+ const restore = React2.useRef(null);
234
244
  const zIndex = useOverlayLayer(POPOVER_BASE);
235
- React.useEffect(() => {
245
+ React2.useEffect(() => {
236
246
  if (!open) return;
237
247
  restore.current = typeof document !== "undefined" ? document.activeElement : null;
238
248
  return () => {
@@ -244,7 +254,7 @@ function Popover({
244
254
  }
245
255
  };
246
256
  }, [open, returnFocus]);
247
- React.useEffect(() => {
257
+ React2.useEffect(() => {
248
258
  if (!open) return;
249
259
  const away = (e) => {
250
260
  if (!closeOnOutside) return;
@@ -270,7 +280,7 @@ function Popover({
270
280
  }, [open, closeOnOutside, closeOnEscape, onClose, anchorRef, triggerRef]);
271
281
  if (!open || !pos) return null;
272
282
  return portal(
273
- /* @__PURE__ */ jsx3(LayerProvider, { zIndex, children: /* @__PURE__ */ jsxs2(
283
+ /* @__PURE__ */ jsx3(LayerProvider, { zIndex, children: /* @__PURE__ */ jsxs3(
274
284
  "div",
275
285
  {
276
286
  ref,
@@ -318,12 +328,12 @@ function Popover({
318
328
  }
319
329
  var isItem = (it) => !!it && it.kind !== "separator" && it.kind !== "section" && it.kind !== "custom" && !it.disabled;
320
330
  function Menu({ items = [], onSelect, onClose, autoFocus = true, className = "", footer, header }) {
321
- const listRef = React.useRef(null);
322
- const [active, setActive] = React.useState(() => items.findIndex(isItem));
323
- const [openSub, setOpenSub] = React.useState(null);
324
- const subAnchor = React.useRef(null);
325
- const typed = React.useRef({ s: "", t: 0 });
326
- React.useEffect(() => {
331
+ const listRef = React2.useRef(null);
332
+ const [active, setActive] = React2.useState(() => items.findIndex(isItem));
333
+ const [openSub, setOpenSub] = React2.useState(null);
334
+ const subAnchor = React2.useRef(null);
335
+ const typed = React2.useRef({ s: "", t: 0 });
336
+ React2.useEffect(() => {
327
337
  if (autoFocus && listRef.current) listRef.current.focus({ preventScroll: true });
328
338
  }, [autoFocus]);
329
339
  const move = (dir) => {
@@ -385,8 +395,8 @@ function Menu({ items = [], onSelect, onClose, autoFocus = true, className = "",
385
395
  }
386
396
  };
387
397
  const sub = openSub != null ? items[openSub] : null;
388
- return /* @__PURE__ */ jsxs2(React.Fragment, { children: [
389
- /* @__PURE__ */ jsxs2("div", { className: "fd-menu-frame", children: [
398
+ return /* @__PURE__ */ jsxs3(React2.Fragment, { children: [
399
+ /* @__PURE__ */ jsxs3("div", { className: "fd-menu-frame", children: [
390
400
  header != null ? /* @__PURE__ */ jsx3("div", { className: "fd-menu-header", children: header }) : null,
391
401
  /* @__PURE__ */ jsx3(
392
402
  "div",
@@ -402,7 +412,7 @@ function Menu({ items = [], onSelect, onClose, autoFocus = true, className = "",
402
412
  if (it.kind === "section") return /* @__PURE__ */ jsx3("div", { className: "fd-pop-group", role: "presentation", children: it.label }, "h" + i);
403
413
  if (it.kind === "custom") return /* @__PURE__ */ jsx3("div", { className: "fd-menu-custom", children: it.render ? it.render() : null }, "c" + i);
404
414
  const on = !!it.checked;
405
- const row = /* @__PURE__ */ jsxs2(
415
+ const row = /* @__PURE__ */ jsxs3(
406
416
  "button",
407
417
  {
408
418
  type: "button",
@@ -420,7 +430,7 @@ function Menu({ items = [], onSelect, onClose, autoFocus = true, className = "",
420
430
  onClick: () => choose(it, i),
421
431
  children: [
422
432
  it.icon ? /* @__PURE__ */ jsx3("span", { className: "fd-menu-icon", children: /* @__PURE__ */ jsx3("i", { className: "ph ph-" + it.icon, "aria-hidden": "true" }) }) : null,
423
- /* @__PURE__ */ jsxs2("span", { className: "fd-menu-text", children: [
433
+ /* @__PURE__ */ jsxs3("span", { className: "fd-menu-text", children: [
424
434
  /* @__PURE__ */ jsx3("span", { className: "fd-opt-label", children: it.label }),
425
435
  it.description ? /* @__PURE__ */ jsx3("span", { className: "fd-opt-desc", children: it.description }) : null
426
436
  ] }),
@@ -434,7 +444,7 @@ function Menu({ items = [], onSelect, onClose, autoFocus = true, className = "",
434
444
  );
435
445
  const ta = it.trailingAction;
436
446
  if (!ta) return row;
437
- return /* @__PURE__ */ jsxs2("div", { className: "fd-menu-row", onMouseEnter: () => setActive(i), children: [
447
+ return /* @__PURE__ */ jsxs3("div", { className: "fd-menu-row", onMouseEnter: () => setActive(i), children: [
438
448
  row,
439
449
  /* @__PURE__ */ jsx3(
440
450
  "button",
@@ -499,10 +509,10 @@ function MenuButton({
499
509
  header,
500
510
  footer
501
511
  }) {
502
- const [open, setOpen] = React.useState(false);
503
- const ref = React.useRef(null);
504
- return /* @__PURE__ */ jsxs2(React.Fragment, { children: [
505
- /* @__PURE__ */ jsxs2(
512
+ const [open, setOpen] = React2.useState(false);
513
+ const ref = React2.useRef(null);
514
+ return /* @__PURE__ */ jsxs3(React2.Fragment, { children: [
515
+ /* @__PURE__ */ jsxs3(
506
516
  "button",
507
517
  {
508
518
  type: "button",
@@ -559,7 +569,7 @@ function SegmentedControl({ options = [], value, onChange, className = "", ...re
559
569
  }
560
570
 
561
571
  // src/components/surfaces/Card.tsx
562
- import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
572
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
563
573
  function Card({
564
574
  title,
565
575
  action,
@@ -577,8 +587,8 @@ function Card({
577
587
  hoverable ? "fd-card-hoverable" : "",
578
588
  className
579
589
  ].filter(Boolean).join(" ");
580
- return /* @__PURE__ */ jsxs3("div", { className: cls, ...rest, children: [
581
- title ? /* @__PURE__ */ jsxs3("div", { className: "fd-card-head", children: [
590
+ return /* @__PURE__ */ jsxs4("div", { className: cls, ...rest, children: [
591
+ title ? /* @__PURE__ */ jsxs4("div", { className: "fd-card-head", children: [
582
592
  /* @__PURE__ */ jsx5("span", { className: "fd-card-head-title", children: title }),
583
593
  action
584
594
  ] }) : null,
@@ -587,15 +597,15 @@ function Card({
587
597
  ] });
588
598
  }
589
599
  function CardRow({ label, children, className = "" }) {
590
- return /* @__PURE__ */ jsxs3("div", { className: ["fd-card-row", className].filter(Boolean).join(" "), children: [
600
+ return /* @__PURE__ */ jsxs4("div", { className: ["fd-card-row", className].filter(Boolean).join(" "), children: [
591
601
  /* @__PURE__ */ jsx5("span", { className: "fd-card-row-label", children: label }),
592
602
  /* @__PURE__ */ jsx5("span", { className: "fd-card-row-value", children })
593
603
  ] });
594
604
  }
595
605
 
596
606
  // src/components/surfaces/Collapsible.tsx
597
- import * as React2 from "react";
598
- import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
607
+ import * as React3 from "react";
608
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
599
609
  function Collapsible({
600
610
  title,
601
611
  subtitle,
@@ -608,16 +618,16 @@ function Collapsible({
608
618
  className = "",
609
619
  ...rest
610
620
  }) {
611
- const [internal, setInternal] = React2.useState(defaultOpen);
621
+ const [internal, setInternal] = React3.useState(defaultOpen);
612
622
  const isOpen = open === void 0 ? internal : open;
613
623
  const toggle = () => {
614
624
  if (open === void 0) setInternal(!isOpen);
615
625
  if (onToggle) onToggle(!isOpen);
616
626
  };
617
- return /* @__PURE__ */ jsxs4("div", { className: ["fd-coll", className].filter(Boolean).join(" "), "data-open": isOpen ? "true" : "false", ...rest, children: [
618
- /* @__PURE__ */ jsxs4("button", { type: "button", className: "fd-coll-trigger", "aria-expanded": isOpen, onClick: toggle, children: [
627
+ return /* @__PURE__ */ jsxs5("div", { className: ["fd-coll", className].filter(Boolean).join(" "), "data-open": isOpen ? "true" : "false", ...rest, children: [
628
+ /* @__PURE__ */ jsxs5("button", { type: "button", className: "fd-coll-trigger", "aria-expanded": isOpen, onClick: toggle, children: [
619
629
  icon ? /* @__PURE__ */ jsx6("span", { className: "fd-coll-caret", style: { background: "var(--brand-soft)", color: "var(--brand)", transform: "none" }, children: /* @__PURE__ */ jsx6("i", { className: "ph ph-" + icon, "aria-hidden": "true" }) }) : null,
620
- /* @__PURE__ */ jsxs4("span", { style: { flex: 1, minWidth: 0 }, children: [
630
+ /* @__PURE__ */ jsxs5("span", { style: { flex: 1, minWidth: 0 }, children: [
621
631
  /* @__PURE__ */ jsx6("span", { className: "fd-coll-title", style: { display: "block" }, children: title }),
622
632
  subtitle ? /* @__PURE__ */ jsx6("span", { className: "fd-coll-sub", style: { display: "block" }, children: subtitle }) : null
623
633
  ] }),
@@ -629,19 +639,19 @@ function Collapsible({
629
639
  }
630
640
 
631
641
  // src/components/surfaces/Drawer.tsx
632
- import * as React3 from "react";
642
+ import * as React4 from "react";
633
643
  import { createPortal as createPortal2 } from "react-dom";
634
- import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
644
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
635
645
  var DRAWER_BASE = 90;
636
646
  function Drawer({ open = true, title, onClose, footer, children, className = "", ...rest }) {
637
647
  const zIndex = useOverlayLayer(DRAWER_BASE);
638
- const [closing, setClosing] = React3.useState(false);
639
- const close = React3.useCallback(() => {
648
+ const [closing, setClosing] = React4.useState(false);
649
+ const close = React4.useCallback(() => {
640
650
  if (!onClose) return;
641
651
  setClosing(true);
642
652
  setTimeout(onClose, 210);
643
653
  }, [onClose]);
644
- React3.useEffect(() => {
654
+ React4.useEffect(() => {
645
655
  if (!open || !onClose) return;
646
656
  const h = (e) => {
647
657
  if (e.key === "Escape") close();
@@ -651,10 +661,10 @@ function Drawer({ open = true, title, onClose, footer, children, className = "",
651
661
  }, [open, onClose, close]);
652
662
  if (!open) return null;
653
663
  return createPortal2(
654
- /* @__PURE__ */ jsxs5(LayerProvider, { zIndex, children: [
664
+ /* @__PURE__ */ jsxs6(LayerProvider, { zIndex, children: [
655
665
  /* @__PURE__ */ jsx7("div", { className: "fd-scrim" + (closing ? " is-closing" : ""), style: { display: "block", zIndex: zIndex - LAYER_STEP }, onClick: close }),
656
- /* @__PURE__ */ jsxs5("aside", { className: ["fd-drawer", closing ? "is-closing" : "", className].filter(Boolean).join(" "), role: "dialog", "aria-modal": "true", ...rest, style: { zIndex }, children: [
657
- /* @__PURE__ */ jsxs5("div", { className: "fd-card-head", style: { flex: "none" }, children: [
666
+ /* @__PURE__ */ jsxs6("aside", { className: ["fd-drawer", closing ? "is-closing" : "", className].filter(Boolean).join(" "), role: "dialog", "aria-modal": "true", ...rest, style: { zIndex }, children: [
667
+ /* @__PURE__ */ jsxs6("div", { className: "fd-card-head", style: { flex: "none" }, children: [
658
668
  /* @__PURE__ */ jsx7("span", { className: "fd-card-head-title", children: title }),
659
669
  onClose ? /* @__PURE__ */ jsx7("button", { type: "button", className: "fd-btn-icon", "aria-label": "Close", onClick: close, children: /* @__PURE__ */ jsx7("i", { className: "ph ph-x" }) }) : null
660
670
  ] }),
@@ -667,17 +677,17 @@ function Drawer({ open = true, title, onClose, footer, children, className = "",
667
677
  }
668
678
 
669
679
  // src/components/surfaces/Modal.tsx
670
- import * as React4 from "react";
680
+ import * as React5 from "react";
671
681
  import { createPortal as createPortal3 } from "react-dom";
672
- import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
682
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
673
683
  function Modal({ open = true, title, description, onClose, footer, wide = false, children, className = "", ...rest }) {
674
- const [closing, setClosing] = React4.useState(false);
675
- const close = React4.useCallback(() => {
684
+ const [closing, setClosing] = React5.useState(false);
685
+ const close = React5.useCallback(() => {
676
686
  if (!onClose) return;
677
687
  setClosing(true);
678
688
  setTimeout(onClose, 190);
679
689
  }, [onClose]);
680
- React4.useEffect(() => {
690
+ React5.useEffect(() => {
681
691
  if (!open || !onClose) return;
682
692
  const h = (e) => {
683
693
  if (e.key === "Escape") close();
@@ -694,7 +704,7 @@ function Modal({ open = true, title, description, onClose, footer, wide = false,
694
704
  onClick: onClose ? (e) => {
695
705
  if (e.target === e.currentTarget) close();
696
706
  } : void 0,
697
- children: /* @__PURE__ */ jsxs6(
707
+ children: /* @__PURE__ */ jsxs7(
698
708
  "div",
699
709
  {
700
710
  className: ["fd-modal", closing ? "is-closing" : "", wide ? "fd-modal-wide" : "", className].filter(Boolean).join(" "),
@@ -703,8 +713,8 @@ function Modal({ open = true, title, description, onClose, footer, wide = false,
703
713
  "aria-label": typeof title === "string" ? title : void 0,
704
714
  ...rest,
705
715
  children: [
706
- title ? /* @__PURE__ */ jsxs6("div", { className: "fd-modal-head", children: [
707
- /* @__PURE__ */ jsxs6("span", { style: { flex: 1, minWidth: 0 }, children: [
716
+ title ? /* @__PURE__ */ jsxs7("div", { className: "fd-modal-head", children: [
717
+ /* @__PURE__ */ jsxs7("span", { style: { flex: 1, minWidth: 0 }, children: [
708
718
  /* @__PURE__ */ jsx8("span", { className: "fd-modal-title", style: { display: "block" }, children: title }),
709
719
  description ? /* @__PURE__ */ jsx8("span", { className: "fd-body-sm fd-secondary", style: { display: "block", marginTop: 6 }, children: description }) : null
710
720
  ] }),
@@ -722,7 +732,7 @@ function Modal({ open = true, title, description, onClose, footer, wide = false,
722
732
  }
723
733
 
724
734
  // src/components/loading/LoadingRegion.tsx
725
- import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
735
+ import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
726
736
  function LoadingRegion({
727
737
  state = "ready",
728
738
  skeleton,
@@ -734,7 +744,7 @@ function LoadingRegion({
734
744
  ...rest
735
745
  }) {
736
746
  if (state === "empty" || state === "error") {
737
- return /* @__PURE__ */ jsxs7("div", { className: ["fd-empty", className].filter(Boolean).join(" "), ...rest, children: [
747
+ return /* @__PURE__ */ jsxs8("div", { className: ["fd-empty", className].filter(Boolean).join(" "), ...rest, children: [
738
748
  /* @__PURE__ */ jsx9("span", { className: "fd-empty-icon", children: /* @__PURE__ */ jsx9("i", { className: state === "error" ? "ph ph-warning" : "ph ph-tray", "aria-hidden": "true" }) }),
739
749
  /* @__PURE__ */ jsx9("span", { className: "fd-empty-title", children: state === "error" ? "That didn't load" : "Nothing here yet" }),
740
750
  /* @__PURE__ */ jsx9("span", { className: "fd-empty-body", children: error || "Data will appear here once it exists." }),
@@ -742,7 +752,7 @@ function LoadingRegion({
742
752
  ] });
743
753
  }
744
754
  if (state === "loading") {
745
- return /* @__PURE__ */ jsxs7("div", { className, role: "status", "aria-busy": "true", "aria-label": label, ...rest, children: [
755
+ return /* @__PURE__ */ jsxs8("div", { className, role: "status", "aria-busy": "true", "aria-label": label, ...rest, children: [
746
756
  /* @__PURE__ */ jsx9("span", { className: "fd-sr", children: label }),
747
757
  skeleton
748
758
  ] });
@@ -760,14 +770,14 @@ function LoadingRegion({
760
770
  }
761
771
 
762
772
  // src/components/loading/ProgressBar.tsx
763
- import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
773
+ import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
764
774
  function ProgressBar({ value, label, showValue = false, className = "", ...rest }) {
765
775
  const indeterminate = value === void 0 || value === null;
766
776
  const pct = indeterminate ? 0 : Math.max(0, Math.min(100, value));
767
- return /* @__PURE__ */ jsxs8("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 8 }, children: [
768
- label || showValue ? /* @__PURE__ */ jsxs8("div", { className: "fd-row", style: { justifyContent: "space-between", gap: 12 }, children: [
777
+ return /* @__PURE__ */ jsxs9("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 8 }, children: [
778
+ label || showValue ? /* @__PURE__ */ jsxs9("div", { className: "fd-row", style: { justifyContent: "space-between", gap: 12 }, children: [
769
779
  label ? /* @__PURE__ */ jsx10("span", { className: "fd-label-lg", children: label }) : /* @__PURE__ */ jsx10("span", {}),
770
- showValue && !indeterminate ? /* @__PURE__ */ jsxs8("span", { className: "fd-num fd-secondary", children: [
780
+ showValue && !indeterminate ? /* @__PURE__ */ jsxs9("span", { className: "fd-num fd-secondary", children: [
771
781
  pct,
772
782
  "%"
773
783
  ] }) : null
@@ -833,16 +843,16 @@ function Spinner({ size = "md", label = "Loading", className = "", style, ...res
833
843
  }
834
844
 
835
845
  // src/components/navigation/SidebarNav.tsx
836
- import { jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
846
+ import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
837
847
  function Tip({ label, children }) {
838
848
  return /* @__PURE__ */ jsx13("span", { title: label, style: { display: "inline-flex", flex: "none" }, children });
839
849
  }
840
850
  function SidebarNav({ brand, groups = [], current: current2, onNavigate, footer, open = false, className = "", ...rest }) {
841
- return /* @__PURE__ */ jsxs9("nav", { className: ["fd-side", className].filter(Boolean).join(" "), "data-open": open ? "true" : "false", ...rest, children: [
851
+ return /* @__PURE__ */ jsxs10("nav", { className: ["fd-side", className].filter(Boolean).join(" "), "data-open": open ? "true" : "false", ...rest, children: [
842
852
  brand ? /* @__PURE__ */ jsx13("div", { style: { height: "var(--topbar-h)", display: "flex", alignItems: "center", padding: "0 18px", borderBottom: "1px solid var(--border)", flex: "none", overflow: "hidden" }, children: brand }) : null,
843
- /* @__PURE__ */ jsx13("div", { style: { flex: 1, overflow: "auto", padding: "4px 10px 18px" }, children: groups.map((g, gi) => /* @__PURE__ */ jsxs9("div", { children: [
853
+ /* @__PURE__ */ jsx13("div", { style: { flex: 1, overflow: "auto", padding: "4px 10px 18px" }, children: groups.map((g, gi) => /* @__PURE__ */ jsxs10("div", { children: [
844
854
  g.label ? /* @__PURE__ */ jsx13("div", { className: "fd-side-group", children: g.label }) : null,
845
- /* @__PURE__ */ jsx13("div", { className: "fd-stack", style: { gap: 2 }, children: g.items.map((it) => /* @__PURE__ */ jsxs9(
855
+ /* @__PURE__ */ jsx13("div", { className: "fd-stack", style: { gap: 2 }, children: g.items.map((it) => /* @__PURE__ */ jsxs10(
846
856
  "button",
847
857
  {
848
858
  type: "button",
@@ -866,26 +876,26 @@ function SidebarNav({ brand, groups = [], current: current2, onNavigate, footer,
866
876
  }
867
877
 
868
878
  // src/components/navigation/FlytedeskBrand.tsx
869
- import { jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
879
+ import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
870
880
  var LOGO_SRC = "https://cdn.prod.website-files.com/69a96def413819b7db64de8c/69ac8ec2ed84b986a5fb76dc_Logo%20(dark)%202.svg";
871
881
  function FlytedeskMark({ size = "md", className = "", ...rest }) {
872
882
  return /* @__PURE__ */ jsx14("span", { className: ["fd-brand-mark", size !== "md" ? "fd-brand-mark-" + size : "", className].filter(Boolean).join(" "), ...rest, children: /* @__PURE__ */ jsx14("img", { src: LOGO_SRC, alt: "flytedesk" }) });
873
883
  }
874
884
  function FlytedeskBrand({ appName, size = "md", className = "", ...rest }) {
875
- return /* @__PURE__ */ jsxs10("span", { className: ["fd-brand", size !== "md" ? "fd-brand-" + size : "", className].filter(Boolean).join(" "), ...rest, children: [
885
+ return /* @__PURE__ */ jsxs11("span", { className: ["fd-brand", size !== "md" ? "fd-brand-" + size : "", className].filter(Boolean).join(" "), ...rest, children: [
876
886
  /* @__PURE__ */ jsx14(FlytedeskMark, { size }),
877
887
  /* @__PURE__ */ jsx14("span", { className: "fd-overline fd-muted", children: appName })
878
888
  ] });
879
889
  }
880
890
 
881
891
  // src/components/navigation/Tabs.tsx
882
- import { jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
892
+ import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
883
893
  function Tabs({ tabs = [], value, onChange, className = "", ...rest }) {
884
894
  return /* @__PURE__ */ jsx15("div", { className: ["fd-tabs", className].filter(Boolean).join(" "), role: "tablist", ...rest, children: tabs.map((t) => {
885
895
  const v = typeof t === "string" ? t : t.value;
886
896
  const label = typeof t === "string" ? t : t.label;
887
897
  const count = typeof t === "string" ? void 0 : t.count;
888
- return /* @__PURE__ */ jsxs11(
898
+ return /* @__PURE__ */ jsxs12(
889
899
  "button",
890
900
  {
891
901
  type: "button",
@@ -904,13 +914,13 @@ function Tabs({ tabs = [], value, onChange, className = "", ...rest }) {
904
914
  }
905
915
 
906
916
  // src/components/navigation/Topbar.tsx
907
- import * as React5 from "react";
908
- import { Fragment as Fragment3, jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
917
+ import * as React6 from "react";
918
+ import { Fragment as Fragment3, jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
909
919
  function useIsNarrow(breakpoint) {
910
- const [narrow, setNarrow] = React5.useState(
920
+ const [narrow, setNarrow] = React6.useState(
911
921
  () => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(`(max-width: ${breakpoint}px)`).matches
912
922
  );
913
- React5.useEffect(() => {
923
+ React6.useEffect(() => {
914
924
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
915
925
  const mq = window.matchMedia(`(max-width: ${breakpoint}px)`);
916
926
  const apply = () => setNarrow(mq.matches);
@@ -931,11 +941,11 @@ function Topbar({
931
941
  ...rest
932
942
  }) {
933
943
  const narrow = useIsNarrow(overflowBreakpoint);
934
- const [moreOpen, setMoreOpen] = React5.useState(false);
935
- const moreRef = React5.useRef(null);
936
- return /* @__PURE__ */ jsxs12("header", { className: ["fd-topbar", narrow ? "is-narrow" : "", className].filter(Boolean).join(" "), ...rest, children: [
944
+ const [moreOpen, setMoreOpen] = React6.useState(false);
945
+ const moreRef = React6.useRef(null);
946
+ return /* @__PURE__ */ jsxs13("header", { className: ["fd-topbar", narrow ? "is-narrow" : "", className].filter(Boolean).join(" "), ...rest, children: [
937
947
  onMenu ? /* @__PURE__ */ jsx16("button", { type: "button", className: "fd-btn-icon", "aria-label": "Menu", onClick: onMenu, children: /* @__PURE__ */ jsx16("i", { className: "ph ph-list" }) }) : null,
938
- /* @__PURE__ */ jsx16("nav", { className: "fd-crumb", "aria-label": "Breadcrumb", children: crumbs.map((c, i) => /* @__PURE__ */ jsxs12(React5.Fragment, { children: [
948
+ /* @__PURE__ */ jsx16("nav", { className: "fd-crumb", "aria-label": "Breadcrumb", children: crumbs.map((c, i) => /* @__PURE__ */ jsxs13(React6.Fragment, { children: [
939
949
  i > 0 ? /* @__PURE__ */ jsx16("i", { className: "ph ph-caret-right", style: { fontSize: 11, opacity: 0.6 }, "aria-hidden": "true" }) : null,
940
950
  i === crumbs.length - 1 ? /* @__PURE__ */ jsx16("span", { className: "fd-crumb-current", children: c.label }) : /* @__PURE__ */ jsx16(
941
951
  "a",
@@ -950,7 +960,7 @@ function Topbar({
950
960
  )
951
961
  ] }, i)) }),
952
962
  /* @__PURE__ */ jsx16("span", { style: { flex: 1 } }),
953
- overflowActions != null ? narrow ? /* @__PURE__ */ jsxs12(Fragment3, { children: [
963
+ overflowActions != null ? narrow ? /* @__PURE__ */ jsxs13(Fragment3, { children: [
954
964
  /* @__PURE__ */ jsx16(
955
965
  "button",
956
966
  {
@@ -974,7 +984,7 @@ function Topbar({
974
984
  padded: true,
975
985
  label: "More actions",
976
986
  className: "fd-topbar-overflow",
977
- children: /* @__PURE__ */ jsx16("div", { className: "fd-stack fd-topbar-overflow-list", children: overflowActions })
987
+ children: /* @__PURE__ */ jsx16("div", { className: "fd-stack fd-topbar-overflow-list", children: /* @__PURE__ */ jsx16(OverflowRowContext.Provider, { value: true, children: overflowActions }) })
978
988
  }
979
989
  )
980
990
  ] }) : overflowActions : null,
@@ -984,7 +994,7 @@ function Topbar({
984
994
  }
985
995
 
986
996
  // src/components/feedback/Avatar.tsx
987
- import { jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
997
+ import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
988
998
  function Avatar({ name = "", src, size = "md", className = "", ...rest }) {
989
999
  const initials = name.split(/\s+/).filter(Boolean).slice(0, 2).map((w) => w[0]).join("").toUpperCase();
990
1000
  return /* @__PURE__ */ jsx17(
@@ -1000,17 +1010,17 @@ function Avatar({ name = "", src, size = "md", className = "", ...rest }) {
1000
1010
  function AvatarStack({ people = [], size = "sm", max = 4, className = "" }) {
1001
1011
  const shown = people.slice(0, max);
1002
1012
  const rest = people.length - shown.length;
1003
- return /* @__PURE__ */ jsxs13("span", { className: ["fd-avatar-stack", className].filter(Boolean).join(" "), children: [
1013
+ return /* @__PURE__ */ jsxs14("span", { className: ["fd-avatar-stack", className].filter(Boolean).join(" "), children: [
1004
1014
  shown.map((p, i) => /* @__PURE__ */ jsx17(Avatar, { name: typeof p === "string" ? p : p.name, src: typeof p === "string" ? void 0 : p.src, size }, i)),
1005
1015
  rest > 0 ? /* @__PURE__ */ jsx17(Avatar, { name: "+" + rest, size }) : null
1006
1016
  ] });
1007
1017
  }
1008
1018
 
1009
1019
  // src/components/feedback/Badge.tsx
1010
- import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
1020
+ import { jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
1011
1021
  var TONES = { neutral: "fd-badge-neutral", info: "fd-badge-info", success: "fd-badge-success", warning: "fd-badge-warning", danger: "fd-badge-danger", live: "fd-badge-live", approved: "fd-badge-approved", count: "fd-badge-count" };
1012
1022
  function Badge({ children, tone = "neutral", dot = false, icon, className = "", ...rest }) {
1013
- return /* @__PURE__ */ jsxs14("span", { className: ["fd-badge", TONES[tone] || TONES.neutral, className].filter(Boolean).join(" "), ...rest, children: [
1023
+ return /* @__PURE__ */ jsxs15("span", { className: ["fd-badge", TONES[tone] || TONES.neutral, className].filter(Boolean).join(" "), ...rest, children: [
1014
1024
  dot ? /* @__PURE__ */ jsx18("span", { className: "fd-badge-dot", "aria-hidden": "true" }) : null,
1015
1025
  icon ? /* @__PURE__ */ jsx18("i", { className: "ph ph-" + icon, "aria-hidden": "true" }) : null,
1016
1026
  children
@@ -1018,9 +1028,9 @@ function Badge({ children, tone = "neutral", dot = false, icon, className = "",
1018
1028
  }
1019
1029
 
1020
1030
  // src/components/feedback/EmptyState.tsx
1021
- import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
1031
+ import { jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
1022
1032
  function EmptyState({ icon = "tray", title, children, action, className = "", ...rest }) {
1023
- return /* @__PURE__ */ jsxs15("div", { className: ["fd-empty", className].filter(Boolean).join(" "), ...rest, children: [
1033
+ return /* @__PURE__ */ jsxs16("div", { className: ["fd-empty", className].filter(Boolean).join(" "), ...rest, children: [
1024
1034
  /* @__PURE__ */ jsx19("span", { className: "fd-empty-icon", children: /* @__PURE__ */ jsx19("i", { className: "ph ph-" + icon, "aria-hidden": "true" }) }),
1025
1035
  /* @__PURE__ */ jsx19("span", { className: "fd-empty-title", children: title }),
1026
1036
  children ? /* @__PURE__ */ jsx19("span", { className: "fd-empty-body", children }) : null,
@@ -1029,12 +1039,12 @@ function EmptyState({ icon = "tray", title, children, action, className = "", ..
1029
1039
  }
1030
1040
 
1031
1041
  // src/components/feedback/Flag.tsx
1032
- import { Fragment as Fragment4, jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
1042
+ import { Fragment as Fragment4, jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
1033
1043
  function Flag({ statement, cost, actions, tone = "warning", className = "", ...rest }) {
1034
- return /* @__PURE__ */ jsxs16("div", { className: ["fd-flag", "fd-flag-" + tone, className].filter(Boolean).join(" "), role: "status", ...rest, children: [
1035
- /* @__PURE__ */ jsxs16("span", { className: "fd-flag-text", children: [
1044
+ return /* @__PURE__ */ jsxs17("div", { className: ["fd-flag", "fd-flag-" + tone, className].filter(Boolean).join(" "), role: "status", ...rest, children: [
1045
+ /* @__PURE__ */ jsxs17("span", { className: "fd-flag-text", children: [
1036
1046
  statement,
1037
- cost ? /* @__PURE__ */ jsxs16(Fragment4, { children: [
1047
+ cost ? /* @__PURE__ */ jsxs17(Fragment4, { children: [
1038
1048
  " ",
1039
1049
  /* @__PURE__ */ jsx20("span", { className: "fd-flag-cost", children: cost })
1040
1050
  ] }) : null
@@ -1086,10 +1096,10 @@ function hasModifier(e) {
1086
1096
  }
1087
1097
 
1088
1098
  // src/components/feedback/Tag.tsx
1089
- import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
1099
+ import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
1090
1100
  var TONES2 = { info: "fd-tag-info", success: "fd-tag-success", warning: "fd-tag-warning", danger: "fd-tag-danger" };
1091
1101
  function Tag({ children, icon, selected = false, tone = "neutral", onRemove, onClick, className = "", ...rest }) {
1092
- return /* @__PURE__ */ jsxs17(
1102
+ return /* @__PURE__ */ jsxs18(
1093
1103
  "button",
1094
1104
  {
1095
1105
  type: "button",
@@ -1119,7 +1129,7 @@ function Tag({ children, icon, selected = false, tone = "neutral", onRemove, onC
1119
1129
  }
1120
1130
 
1121
1131
  // src/components/feedback/Toast.tsx
1122
- import { jsx as jsx23, jsxs as jsxs18 } from "react/jsx-runtime";
1132
+ import { jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
1123
1133
  var ICON = {
1124
1134
  success: { i: "check", bg: "var(--ok-solid)" },
1125
1135
  error: { i: "x", bg: "var(--danger-solid)" },
@@ -1128,9 +1138,9 @@ var ICON = {
1128
1138
  };
1129
1139
  function Toast({ title, children, tone = "success", onUndo, onDismiss, className = "", ...rest }) {
1130
1140
  const ic = ICON[tone] || ICON.info;
1131
- return /* @__PURE__ */ jsxs18("div", { className: ["fd-toast", className].filter(Boolean).join(" "), role: "status", ...rest, children: [
1141
+ return /* @__PURE__ */ jsxs19("div", { className: ["fd-toast", className].filter(Boolean).join(" "), role: "status", ...rest, children: [
1132
1142
  /* @__PURE__ */ jsx23("span", { className: "fd-toast-icon", style: { background: ic.bg }, "aria-hidden": "true", children: tone === "loading" ? /* @__PURE__ */ jsx23("span", { className: "fd-spinner", style: { width: 12, height: 12, borderWidth: 2, color: "#fff" } }) : /* @__PURE__ */ jsx23("i", { className: "ph ph-" + ic.i }) }),
1133
- /* @__PURE__ */ jsxs18("span", { className: "fd-toast-body", children: [
1143
+ /* @__PURE__ */ jsxs19("span", { className: "fd-toast-body", children: [
1134
1144
  /* @__PURE__ */ jsx23("span", { className: "fd-toast-title", style: { display: "block" }, children: title }),
1135
1145
  children ? /* @__PURE__ */ jsx23("span", { className: "fd-secondary", style: { display: "block", marginTop: 2 }, children }) : null,
1136
1146
  onUndo ? /* @__PURE__ */ jsx23("button", { type: "button", className: "fd-btn fd-btn-link", style: { marginTop: 8 }, onClick: onUndo, children: "Undo" }) : null
@@ -1140,19 +1150,19 @@ function Toast({ title, children, tone = "success", onUndo, onDismiss, className
1140
1150
  }
1141
1151
 
1142
1152
  // src/components/feedback/Tooltip.tsx
1143
- import * as React6 from "react";
1144
- import { jsx as jsx24, jsxs as jsxs19 } from "react/jsx-runtime";
1153
+ import * as React7 from "react";
1154
+ import { jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
1145
1155
  var TOOLTIP_BASE = 150;
1146
1156
  var CLOSE_DELAY_MS = 120;
1147
1157
  function Tooltip({ label, placement = "top", children, className = "" }) {
1148
- const anchorRef = React6.useRef(null);
1149
- const bubbleRef = React6.useRef(null);
1150
- const [reason, setReason] = React6.useState(null);
1151
- const closeTimer = React6.useRef(null);
1152
- const id = React6.useId();
1158
+ const anchorRef = React7.useRef(null);
1159
+ const bubbleRef = React7.useRef(null);
1160
+ const [reason, setReason] = React7.useState(null);
1161
+ const closeTimer = React7.useRef(null);
1162
+ const id = React7.useId();
1153
1163
  const descId = id + "-desc";
1154
1164
  const open = reason != null;
1155
- const cancelClose = React6.useCallback(() => {
1165
+ const cancelClose = React7.useCallback(() => {
1156
1166
  if (closeTimer.current) {
1157
1167
  clearTimeout(closeTimer.current);
1158
1168
  closeTimer.current = null;
@@ -1162,7 +1172,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
1162
1172
  cancelClose();
1163
1173
  setReason(why);
1164
1174
  };
1165
- const hide = React6.useCallback(() => {
1175
+ const hide = React7.useCallback(() => {
1166
1176
  cancelClose();
1167
1177
  setReason(null);
1168
1178
  }, [cancelClose]);
@@ -1177,7 +1187,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
1177
1187
  setReason((r) => r === "hover" ? null : r);
1178
1188
  }, CLOSE_DELAY_MS);
1179
1189
  };
1180
- React6.useEffect(() => cancelClose, [cancelClose]);
1190
+ React7.useEffect(() => cancelClose, [cancelClose]);
1181
1191
  const pos = usePopoverPosition(open, anchorRef, {
1182
1192
  placement: placement === "bottom" ? "bottom-center" : "top-center",
1183
1193
  offset: 8,
@@ -1187,7 +1197,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
1187
1197
  onDetach: hide
1188
1198
  });
1189
1199
  const zIndex = useOverlayLayer(TOOLTIP_BASE);
1190
- React6.useEffect(() => {
1200
+ React7.useEffect(() => {
1191
1201
  if (!open) return;
1192
1202
  const key = (e) => {
1193
1203
  if (e.key === "Escape") hide();
@@ -1215,15 +1225,15 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
1215
1225
  }
1216
1226
  if (keyboard) show("focus");
1217
1227
  };
1218
- const described = React6.isValidElement(children) ? React6.cloneElement(children, {
1228
+ const described = React7.isValidElement(children) ? React7.cloneElement(children, {
1219
1229
  "aria-describedby": [children.props["aria-describedby"], descId].filter(Boolean).join(" ")
1220
1230
  }) : children;
1221
- return /* @__PURE__ */ jsxs19(
1231
+ return /* @__PURE__ */ jsxs20(
1222
1232
  "span",
1223
1233
  {
1224
1234
  ref: anchorRef,
1225
1235
  className: "fd-tooltip-anchor",
1226
- "aria-describedby": React6.isValidElement(children) ? void 0 : descId,
1236
+ "aria-describedby": React7.isValidElement(children) ? void 0 : descId,
1227
1237
  onPointerEnter: (e) => {
1228
1238
  if (isMouse(e)) hover();
1229
1239
  },
@@ -1267,8 +1277,8 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
1267
1277
  }
1268
1278
 
1269
1279
  // src/components/data/Clamp.tsx
1270
- import * as React7 from "react";
1271
- import { jsx as jsx25, jsxs as jsxs20 } from "react/jsx-runtime";
1280
+ import * as React8 from "react";
1281
+ import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
1272
1282
  function Clamp({
1273
1283
  children,
1274
1284
  text,
@@ -1279,16 +1289,16 @@ function Clamp({
1279
1289
  onToggle,
1280
1290
  className = ""
1281
1291
  }) {
1282
- const [open, setOpen] = React7.useState(false);
1283
- const [overflows, setOverflows] = React7.useState(false);
1284
- const bodyRef = React7.useRef(null);
1285
- const charClamped = React7.useMemo(() => {
1292
+ const [open, setOpen] = React8.useState(false);
1293
+ const [overflows, setOverflows] = React8.useState(false);
1294
+ const bodyRef = React8.useRef(null);
1295
+ const charClamped = React8.useMemo(() => {
1286
1296
  if (open || !maxChars || typeof text !== "string" || text.length <= maxChars) return null;
1287
1297
  const cut = text.slice(0, maxChars);
1288
1298
  const at = cut.lastIndexOf(" ");
1289
1299
  return (at > maxChars * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
1290
1300
  }, [text, maxChars, open]);
1291
- React7.useLayoutEffect(() => {
1301
+ React8.useLayoutEffect(() => {
1292
1302
  const node = bodyRef.current;
1293
1303
  if (maxChars || !node || !maxHeight) return;
1294
1304
  const measure = () => {
@@ -1309,9 +1319,9 @@ function Clamp({
1309
1319
  return !v;
1310
1320
  });
1311
1321
  };
1312
- return /* @__PURE__ */ jsxs20("div", { className: ["fd-clamp", clamped ? "is-clamped" : "", className].filter(Boolean).join(" "), children: [
1322
+ return /* @__PURE__ */ jsxs21("div", { className: ["fd-clamp", clamped ? "is-clamped" : "", className].filter(Boolean).join(" "), children: [
1313
1323
  /* @__PURE__ */ jsx25("div", { className: "fd-clamp-body", ref: bodyRef, style: !maxChars && clamped ? { maxHeight } : void 0, children: maxChars ? charClamped != null ? charClamped : text != null ? text : children : children }),
1314
- (maxChars ? charClamped != null || open : overflows) ? /* @__PURE__ */ jsxs20("button", { type: "button", className: "fd-clamp-more", onClick: toggle, "aria-expanded": open, children: [
1324
+ (maxChars ? charClamped != null || open : overflows) ? /* @__PURE__ */ jsxs21("button", { type: "button", className: "fd-clamp-more", onClick: toggle, "aria-expanded": open, children: [
1315
1325
  /* @__PURE__ */ jsx25("i", { className: "ph ph-caret-" + (open ? "up" : "down"), "aria-hidden": "true" }),
1316
1326
  open ? lessLabel : moreLabel
1317
1327
  ] }) : null
@@ -1319,7 +1329,7 @@ function Clamp({
1319
1329
  }
1320
1330
 
1321
1331
  // src/components/data/CsiBadge.tsx
1322
- import { jsx as jsx26, jsxs as jsxs21 } from "react/jsx-runtime";
1332
+ import { jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
1323
1333
  var BANDS = {
1324
1334
  weak: { n: 1, label: "Weak" },
1325
1335
  adequate: { n: 2, label: "Adequate" },
@@ -1342,7 +1352,7 @@ function CsiMeter({ band = "weak", size = 4, width = 5, gap = 2 }) {
1342
1352
  }
1343
1353
  function CsiBadge({ band = "weak", crp, size = "compact", preview = false, alert = false, className = "", ...rest }) {
1344
1354
  const b = BANDS[band] || BANDS.weak;
1345
- return /* @__PURE__ */ jsxs21(
1355
+ return /* @__PURE__ */ jsxs22(
1346
1356
  "span",
1347
1357
  {
1348
1358
  className: ["fd-csi", "fd-csi-" + b.n, size === "medium" ? "fd-csi-medium" : "fd-csi-compact", preview ? "fd-csi-preview" : "", className].filter(Boolean).join(" "),
@@ -1359,7 +1369,7 @@ function CsiBadge({ band = "weak", crp, size = "compact", preview = false, alert
1359
1369
  function CsiHero({ band = "weak", crp, label, className = "" }) {
1360
1370
  const b = BANDS[band] || BANDS.weak;
1361
1371
  const mark = "var(--csi-" + b.n + "-mark)";
1362
- return /* @__PURE__ */ jsxs21("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 10 }, children: [
1372
+ return /* @__PURE__ */ jsxs22("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 10 }, children: [
1363
1373
  /* @__PURE__ */ jsx26("span", { className: "fd-csi-hero-num", style: { color: mark }, children: crp !== void 0 && crp !== null ? formatCrp(crp) : "" }),
1364
1374
  /* @__PURE__ */ jsx26("span", { className: "fd-label-lg", style: { color: "var(--text-2)" }, children: label || b.label }),
1365
1375
  /* @__PURE__ */ jsx26("span", { className: "fd-meter", style: { gap: 3, color: mark, width: 120 }, children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx26("span", { className: "fd-meter-seg" + (i <= b.n ? " is-on" : ""), style: { height: 6, flex: 1 } }, i)) })
@@ -1367,7 +1377,7 @@ function CsiHero({ band = "weak", crp, label, className = "" }) {
1367
1377
  }
1368
1378
 
1369
1379
  // src/components/data/DataTable.tsx
1370
- import { jsx as jsx27, jsxs as jsxs22 } from "react/jsx-runtime";
1380
+ import { jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
1371
1381
  function DataTable({
1372
1382
  columns = [],
1373
1383
  rows = [],
@@ -1384,14 +1394,14 @@ function DataTable({
1384
1394
  ...rest
1385
1395
  }) {
1386
1396
  const stale = refreshing && !loading;
1387
- return /* @__PURE__ */ jsxs22("div", { className: "fd-table-host", children: [
1397
+ return /* @__PURE__ */ jsxs23("div", { className: "fd-table-host", children: [
1388
1398
  /* @__PURE__ */ jsx27(
1389
1399
  "div",
1390
1400
  {
1391
1401
  className: ["fd-table-wrap", className].filter(Boolean).join(" "),
1392
1402
  "aria-busy": loading || refreshing ? "true" : void 0,
1393
1403
  ...rest,
1394
- children: /* @__PURE__ */ jsxs22("table", { className: ["fd-table", compact3 ? "fd-table-compact" : ""].filter(Boolean).join(" "), children: [
1404
+ children: /* @__PURE__ */ jsxs23("table", { className: ["fd-table", compact3 ? "fd-table-compact" : ""].filter(Boolean).join(" "), children: [
1395
1405
  /* @__PURE__ */ jsx27("thead", { children: /* @__PURE__ */ jsx27("tr", { children: columns.map((c) => /* @__PURE__ */ jsx27(
1396
1406
  "th",
1397
1407
  {
@@ -1399,7 +1409,7 @@ function DataTable({
1399
1409
  style: { width: c.width },
1400
1410
  className: [c.numeric ? "is-num" : "", sort && sort.key === c.key ? "is-sorted" : ""].filter(Boolean).join(" "),
1401
1411
  "aria-sort": sort && sort.key === c.key ? sort.dir === "asc" ? "ascending" : "descending" : void 0,
1402
- children: c.sortable && onSort ? /* @__PURE__ */ jsxs22("button", { type: "button", onClick: () => onSort(c.key), children: [
1412
+ children: c.sortable && onSort ? /* @__PURE__ */ jsxs23("button", { type: "button", onClick: () => onSort(c.key), children: [
1403
1413
  c.label,
1404
1414
  sort && sort.key === c.key ? /* @__PURE__ */ jsx27("i", { className: "ph fd-caret ph-caret-" + (sort.dir === "asc" ? "up" : "down") }) : null
1405
1415
  ] }) : c.label
@@ -1419,7 +1429,7 @@ function DataTable({
1419
1429
  ] })
1420
1430
  }
1421
1431
  ),
1422
- stale ? /* @__PURE__ */ jsx27("div", { className: "fd-table-stale", children: /* @__PURE__ */ jsxs22("span", { className: "fd-table-stale-pill", role: "status", children: [
1432
+ stale ? /* @__PURE__ */ jsx27("div", { className: "fd-table-stale", children: /* @__PURE__ */ jsxs23("span", { className: "fd-table-stale-pill", role: "status", children: [
1423
1433
  /* @__PURE__ */ jsx27("span", { className: "fd-spinner", "aria-hidden": "true" }),
1424
1434
  " Updating\u2026"
1425
1435
  ] }) }) : null
@@ -1427,19 +1437,19 @@ function DataTable({
1427
1437
  }
1428
1438
 
1429
1439
  // src/components/data/FilterBar.tsx
1430
- import * as React8 from "react";
1431
- import { jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
1440
+ import * as React9 from "react";
1441
+ import { jsx as jsx28, jsxs as jsxs24 } from "react/jsx-runtime";
1432
1442
  var FILTER_BAR_BASE = 120;
1433
1443
  var isSet = (v) => !(v == null || v === "" || v === false);
1434
1444
  function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align = "left", className = "", ...rest }) {
1435
- const [panel, setPanel] = React8.useState(null);
1445
+ const [panel, setPanel] = React9.useState(null);
1436
1446
  const zIndex = useOverlayLayer(FILTER_BAR_BASE);
1437
- const rootRef = React8.useRef(null);
1438
- const textInputRef = React8.useRef(null);
1439
- const optionsRef = React8.useRef(null);
1447
+ const rootRef = React9.useRef(null);
1448
+ const textInputRef = React9.useRef(null);
1449
+ const optionsRef = React9.useRef(null);
1440
1450
  const editingField = panel && panel.kind === "edit" ? fields.find((f) => f.key === panel.key) : void 0;
1441
1451
  const dismissible = !!panel && (panel.kind === "add" || panel.kind === "edit" && editingField?.type === "select");
1442
- React8.useEffect(() => {
1452
+ React9.useEffect(() => {
1443
1453
  if (!dismissible) return;
1444
1454
  const away = (e) => {
1445
1455
  if (rootRef.current && !rootRef.current.contains(e.target)) setPanel(null);
@@ -1454,7 +1464,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
1454
1464
  document.removeEventListener("keydown", esc);
1455
1465
  };
1456
1466
  }, [dismissible]);
1457
- React8.useEffect(() => {
1467
+ React9.useEffect(() => {
1458
1468
  if (!panel || panel.kind !== "edit") return;
1459
1469
  if (editingField?.type === "text") {
1460
1470
  textInputRef.current?.focus();
@@ -1465,12 +1475,12 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
1465
1475
  }, [panel]);
1466
1476
  const addableFields = fields.filter((f) => !isSet(filters[f.key]));
1467
1477
  const startEditing = (key) => setPanel({ kind: "edit", key });
1468
- return /* @__PURE__ */ jsxs23("span", { className, style: { position: "relative", display: "inline-flex", flexWrap: "wrap", alignItems: "center", gap: 8 }, ref: rootRef, ...rest, children: [
1478
+ return /* @__PURE__ */ jsxs24("span", { className, style: { position: "relative", display: "inline-flex", flexWrap: "wrap", alignItems: "center", gap: 8 }, ref: rootRef, ...rest, children: [
1469
1479
  fields.map((field) => {
1470
1480
  const value = filters[field.key];
1471
1481
  const editing = panel?.kind === "edit" && panel.key === field.key;
1472
1482
  if (editing && field.type === "text") {
1473
- return /* @__PURE__ */ jsxs23(
1483
+ return /* @__PURE__ */ jsxs24(
1474
1484
  "span",
1475
1485
  {
1476
1486
  className: "fd-tag",
@@ -1516,8 +1526,8 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
1516
1526
  }
1517
1527
  if (editing && field.type === "select") {
1518
1528
  const chosen = field.options.find((o) => o.value === value);
1519
- return /* @__PURE__ */ jsxs23("span", { style: { position: "relative", display: "inline-flex" }, children: [
1520
- /* @__PURE__ */ jsxs23(Tag, { selected: true, onClick: () => setPanel(null), onRemove: () => {
1529
+ return /* @__PURE__ */ jsxs24("span", { style: { position: "relative", display: "inline-flex" }, children: [
1530
+ /* @__PURE__ */ jsxs24(Tag, { selected: true, onClick: () => setPanel(null), onRemove: () => {
1521
1531
  if (isSet(value)) onFilterRemove(field.key);
1522
1532
  setPanel(null);
1523
1533
  }, children: [
@@ -1555,7 +1565,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
1555
1565
  if (isSet(value)) {
1556
1566
  const chosen = field.type === "select" ? field.options.find((o) => o.value === value) : void 0;
1557
1567
  const display = chosen ? chosen.label : String(value);
1558
- return /* @__PURE__ */ jsxs23(Tag, { selected: true, onClick: () => startEditing(field.key), onRemove: () => onFilterRemove(field.key), children: [
1568
+ return /* @__PURE__ */ jsxs24(Tag, { selected: true, onClick: () => startEditing(field.key), onRemove: () => onFilterRemove(field.key), children: [
1559
1569
  field.label,
1560
1570
  ": ",
1561
1571
  display
@@ -1563,7 +1573,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
1563
1573
  }
1564
1574
  return null;
1565
1575
  }),
1566
- addableFields.length > 0 ? /* @__PURE__ */ jsxs23("span", { style: { position: "relative", display: "inline-flex" }, children: [
1576
+ addableFields.length > 0 ? /* @__PURE__ */ jsxs24("span", { style: { position: "relative", display: "inline-flex" }, children: [
1567
1577
  /* @__PURE__ */ jsx28(
1568
1578
  Button,
1569
1579
  {
@@ -1581,7 +1591,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
1581
1591
  {
1582
1592
  className: "fd-view-enter",
1583
1593
  style: { position: "absolute", top: "calc(100% + 6px)", [align]: 0, zIndex, width: 220, maxWidth: "calc(100vw - 32px)", display: "block", background: "var(--surface)", border: "1px solid var(--border)", borderRadius: 10, boxShadow: "0 16px 44px rgba(11,13,17,.18)", padding: 8 },
1584
- children: /* @__PURE__ */ jsxs23("span", { className: "fd-stack", role: "menu", "aria-label": "Add filter", style: { gap: 2 }, children: [
1594
+ children: /* @__PURE__ */ jsxs24("span", { className: "fd-stack", role: "menu", "aria-label": "Add filter", style: { gap: 2 }, children: [
1585
1595
  /* @__PURE__ */ jsx28("span", { className: "fd-overline fd-muted", style: { padding: "4px 8px 6px" }, children: "Add filter" }),
1586
1596
  addableFields.map((f) => /* @__PURE__ */ jsx28(
1587
1597
  "button",
@@ -1603,12 +1613,12 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
1603
1613
  }
1604
1614
 
1605
1615
  // src/components/data/StatTile.tsx
1606
- import { jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
1616
+ import { jsx as jsx29, jsxs as jsxs25 } from "react/jsx-runtime";
1607
1617
  function StatTile({ label, value, sub, delta, loading = false, compact: compact3 = false, className = "", ...rest }) {
1608
- return /* @__PURE__ */ jsxs24("div", { className: ["fd-stat", compact3 ? "fd-stat-compact" : "", className].filter(Boolean).join(" "), ...rest, children: [
1609
- loading ? /* @__PURE__ */ jsx29("span", { className: "fd-skel fd-skel-text", style: { display: "block", height: compact3 ? 20 : 28, width: "62%" } }) : /* @__PURE__ */ jsxs24("span", { className: "fd-stat-top", children: [
1618
+ return /* @__PURE__ */ jsxs25("div", { className: ["fd-stat", compact3 ? "fd-stat-compact" : "", className].filter(Boolean).join(" "), ...rest, children: [
1619
+ loading ? /* @__PURE__ */ jsx29("span", { className: "fd-skel fd-skel-text", style: { display: "block", height: compact3 ? 20 : 28, width: "62%" } }) : /* @__PURE__ */ jsxs25("span", { className: "fd-stat-top", children: [
1610
1620
  /* @__PURE__ */ jsx29("span", { className: "fd-stat-figure", children: value }),
1611
- delta ? /* @__PURE__ */ jsxs24("span", { className: delta.startsWith("-") ? "fd-stat-delta-down" : "fd-stat-delta-up", style: { fontWeight: 600, fontSize: "var(--body-sm-size)", flex: "none" }, children: [
1621
+ delta ? /* @__PURE__ */ jsxs25("span", { className: delta.startsWith("-") ? "fd-stat-delta-down" : "fd-stat-delta-up", style: { fontWeight: 600, fontSize: "var(--body-sm-size)", flex: "none" }, children: [
1612
1622
  /* @__PURE__ */ jsx29("i", { className: "ph ph-arrow-" + (delta.startsWith("-") ? "down" : "up") + "-right", "aria-hidden": "true" }),
1613
1623
  " ",
1614
1624
  delta
@@ -1620,8 +1630,8 @@ function StatTile({ label, value, sub, delta, loading = false, compact: compact3
1620
1630
  }
1621
1631
 
1622
1632
  // src/components/data/CodeBlock.tsx
1623
- import * as React9 from "react";
1624
- import { Fragment as Fragment5, jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
1633
+ import * as React10 from "react";
1634
+ import { Fragment as Fragment5, jsx as jsx30, jsxs as jsxs26 } from "react/jsx-runtime";
1625
1635
  var JS_KW = /^(?:const|let|var|function|return|if|else|for|while|do|new|class|extends|import|from|export|default|await|async|try|catch|finally|throw|typeof|instanceof|of|in|switch|case|break|continue|delete|void|yield|static|get|set|this|super|interface|type|enum|implements|public|private|protected|readonly|abstract|as|satisfies|declare|namespace)$/;
1626
1636
  var RULES = {
1627
1637
  js: [
@@ -1776,13 +1786,13 @@ function tokenize(src, lang) {
1776
1786
  return out;
1777
1787
  }
1778
1788
  function Highlighted({ code, lang }) {
1779
- const toks = React9.useMemo(() => tokenize(code, lang), [code, lang]);
1789
+ const toks = React10.useMemo(() => tokenize(code, lang), [code, lang]);
1780
1790
  return /* @__PURE__ */ jsx30(Fragment5, { children: toks.map((tk, i) => tk.c ? /* @__PURE__ */ jsx30("span", { className: "tok-" + tk.c, children: tk.t }, i) : tk.t) });
1781
1791
  }
1782
1792
  function useCopy() {
1783
- const [done, setDone] = React9.useState(false);
1784
- const timer = React9.useRef(null);
1785
- React9.useEffect(() => () => {
1793
+ const [done, setDone] = React10.useState(false);
1794
+ const timer = React10.useRef(null);
1795
+ React10.useEffect(() => () => {
1786
1796
  if (timer.current) clearTimeout(timer.current);
1787
1797
  }, []);
1788
1798
  const copy = (text) => {
@@ -1818,37 +1828,37 @@ function CodeBlock({
1818
1828
  actions,
1819
1829
  className = ""
1820
1830
  }) {
1821
- const [wrap, setWrap] = React9.useState(!!wrapDefault);
1822
- const [open, setOpen] = React9.useState(false);
1831
+ const [wrap, setWrap] = React10.useState(!!wrapDefault);
1832
+ const [open, setOpen] = React10.useState(false);
1823
1833
  const [copied, copy] = useCopy();
1824
1834
  const body = String(code).replace(/\n$/, "");
1825
1835
  const lines = body.split("\n");
1826
1836
  const foldable = collapseAfter > 0 && lines.length > collapseAfter + 6;
1827
1837
  const shown = foldable && !open ? lines.slice(0, collapseAfter).join("\n") : body;
1828
- return /* @__PURE__ */ jsxs25("div", { className: ["fd-code", wrap ? "is-wrap" : "", className].filter(Boolean).join(" "), children: [
1829
- /* @__PURE__ */ jsxs25("div", { className: "fd-code-head", children: [
1838
+ return /* @__PURE__ */ jsxs26("div", { className: ["fd-code", wrap ? "is-wrap" : "", className].filter(Boolean).join(" "), children: [
1839
+ /* @__PURE__ */ jsxs26("div", { className: "fd-code-head", children: [
1830
1840
  filename ? /* @__PURE__ */ jsx30("span", { className: "fd-code-file", children: filename }) : null,
1831
1841
  /* @__PURE__ */ jsx30("span", { className: "fd-code-lang", children: languageLabel(language) }),
1832
1842
  /* @__PURE__ */ jsx30("span", { className: "fd-code-spacer" }),
1833
1843
  actions,
1834
1844
  /* @__PURE__ */ jsx30("button", { type: "button", className: "fd-code-act", onClick: () => setWrap((v) => !v), "aria-pressed": wrap, title: wrap ? "No wrap" : "Soft wrap", children: /* @__PURE__ */ jsx30("i", { className: "ph ph-text-" + (wrap ? "columns" : "align-left"), "aria-hidden": "true" }) }),
1835
- copyable ? /* @__PURE__ */ jsxs25("button", { type: "button", className: "fd-code-act" + (copied ? " is-done" : ""), onClick: () => copy(body), children: [
1845
+ copyable ? /* @__PURE__ */ jsxs26("button", { type: "button", className: "fd-code-act" + (copied ? " is-done" : ""), onClick: () => copy(body), children: [
1836
1846
  /* @__PURE__ */ jsx30("i", { className: "ph ph-" + (copied ? "check" : "copy"), "aria-hidden": "true" }),
1837
1847
  /* @__PURE__ */ jsx30("span", { children: copied ? "Copied" : "Copy" })
1838
1848
  ] }) : null
1839
1849
  ] }),
1840
- /* @__PURE__ */ jsxs25("div", { className: "fd-code-body", children: [
1850
+ /* @__PURE__ */ jsxs26("div", { className: "fd-code-body", children: [
1841
1851
  lineNumbers ? /* @__PURE__ */ jsx30("pre", { className: "fd-code-gutter", "aria-hidden": "true", children: shown.split("\n").map((_, i) => i + 1 + "\n").join("") }) : null,
1842
1852
  /* @__PURE__ */ jsx30("pre", { className: "fd-code-pre", tabIndex: 0, children: /* @__PURE__ */ jsx30("code", { children: /* @__PURE__ */ jsx30(Highlighted, { code: shown, lang: language }) }) })
1843
1853
  ] }),
1844
- foldable ? /* @__PURE__ */ jsxs25("button", { type: "button", className: "fd-code-fold", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
1854
+ foldable ? /* @__PURE__ */ jsxs26("button", { type: "button", className: "fd-code-fold", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
1845
1855
  /* @__PURE__ */ jsx30("i", { className: "ph ph-caret-" + (open ? "up" : "down"), "aria-hidden": "true" }),
1846
1856
  open ? "Collapse" : "Show all " + lines.length + " lines"
1847
1857
  ] }) : null
1848
1858
  ] });
1849
1859
  }
1850
1860
  function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" }) {
1851
- const [open, setOpen] = React9.useState(false);
1861
+ const [open, setOpen] = React10.useState(false);
1852
1862
  const [copied, copy] = useCopy();
1853
1863
  const raw = String(diff).replace(/\n$/, "");
1854
1864
  const all = raw.split("\n").map((line) => {
@@ -1862,31 +1872,31 @@ function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" })
1862
1872
  const dels = all.filter((l) => l.k === "del").length;
1863
1873
  const foldable = collapseAfter > 0 && all.length > collapseAfter + 6;
1864
1874
  const rows = foldable && !open ? all.slice(0, collapseAfter) : all;
1865
- return /* @__PURE__ */ jsxs25("div", { className: ["fd-code", "fd-diff", className].filter(Boolean).join(" "), children: [
1866
- /* @__PURE__ */ jsxs25("div", { className: "fd-code-head", children: [
1875
+ return /* @__PURE__ */ jsxs26("div", { className: ["fd-code", "fd-diff", className].filter(Boolean).join(" "), children: [
1876
+ /* @__PURE__ */ jsxs26("div", { className: "fd-code-head", children: [
1867
1877
  /* @__PURE__ */ jsx30("i", { className: "ph ph-git-diff fd-code-icon", "aria-hidden": "true" }),
1868
1878
  filename ? /* @__PURE__ */ jsx30("span", { className: "fd-code-file", children: filename }) : /* @__PURE__ */ jsx30("span", { className: "fd-code-lang", children: "Diff" }),
1869
- /* @__PURE__ */ jsxs25("span", { className: "fd-diff-stat fd-tabular", children: [
1870
- /* @__PURE__ */ jsxs25("span", { className: "is-add", children: [
1879
+ /* @__PURE__ */ jsxs26("span", { className: "fd-diff-stat fd-tabular", children: [
1880
+ /* @__PURE__ */ jsxs26("span", { className: "is-add", children: [
1871
1881
  "+",
1872
1882
  adds
1873
1883
  ] }),
1874
- /* @__PURE__ */ jsxs25("span", { className: "is-del", children: [
1884
+ /* @__PURE__ */ jsxs26("span", { className: "is-del", children: [
1875
1885
  "\u2212",
1876
1886
  dels
1877
1887
  ] })
1878
1888
  ] }),
1879
1889
  /* @__PURE__ */ jsx30("span", { className: "fd-code-spacer" }),
1880
- /* @__PURE__ */ jsxs25("button", { type: "button", className: "fd-code-act" + (copied ? " is-done" : ""), onClick: () => copy(raw), children: [
1890
+ /* @__PURE__ */ jsxs26("button", { type: "button", className: "fd-code-act" + (copied ? " is-done" : ""), onClick: () => copy(raw), children: [
1881
1891
  /* @__PURE__ */ jsx30("i", { className: "ph ph-" + (copied ? "check" : "copy"), "aria-hidden": "true" }),
1882
1892
  /* @__PURE__ */ jsx30("span", { children: copied ? "Copied" : "Copy" })
1883
1893
  ] })
1884
1894
  ] }),
1885
- /* @__PURE__ */ jsx30("div", { className: "fd-diff-body", children: rows.map((r, i) => /* @__PURE__ */ jsxs25("div", { className: "fd-diff-line is-" + r.k, children: [
1895
+ /* @__PURE__ */ jsx30("div", { className: "fd-diff-body", children: rows.map((r, i) => /* @__PURE__ */ jsxs26("div", { className: "fd-diff-line is-" + r.k, children: [
1886
1896
  /* @__PURE__ */ jsx30("span", { className: "fd-diff-mark", "aria-hidden": "true", children: r.k === "add" ? "+" : r.k === "del" ? "\u2212" : "" }),
1887
1897
  /* @__PURE__ */ jsx30("code", { children: r.k === "add" || r.k === "del" ? r.line.slice(1) : r.line })
1888
1898
  ] }, i)) }),
1889
- foldable ? /* @__PURE__ */ jsxs25("button", { type: "button", className: "fd-code-fold", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
1899
+ foldable ? /* @__PURE__ */ jsxs26("button", { type: "button", className: "fd-code-fold", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
1890
1900
  /* @__PURE__ */ jsx30("i", { className: "ph ph-caret-" + (open ? "up" : "down"), "aria-hidden": "true" }),
1891
1901
  open ? "Collapse" : "Show all " + all.length + " lines"
1892
1902
  ] }) : null
@@ -1894,8 +1904,8 @@ function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" })
1894
1904
  }
1895
1905
 
1896
1906
  // src/components/data/Markdown.tsx
1897
- import * as React10 from "react";
1898
- import { jsx as jsx31, jsxs as jsxs26 } from "react/jsx-runtime";
1907
+ import * as React11 from "react";
1908
+ import { jsx as jsx31, jsxs as jsxs27 } from "react/jsx-runtime";
1899
1909
  var SAFE = /^(?:https?:|mailto:|tel:|#|\/|\.{1,2}\/)/i;
1900
1910
  var safeHref = (h) => SAFE.test(String(h || "").trim()) ? String(h).trim() : null;
1901
1911
  var INLINE = [
@@ -1933,7 +1943,7 @@ function inlineNodes(src, ctx, keyBase) {
1933
1943
  const href = safeHref(g(2));
1934
1944
  out.push(href ? /* @__PURE__ */ jsx31("a", { href, title: g(3) || void 0, target: /^https?:/i.test(href) ? "_blank" : void 0, rel: "noopener noreferrer", onClick: ctx.onLinkClick, children: inlineNodes(g(1), ctx, key()) }, key()) : /* @__PURE__ */ jsx31("span", { children: g(1) }, key()));
1935
1945
  } else if (kind === "cite") {
1936
- out.push(ctx.renderCitation ? /* @__PURE__ */ jsx31(React10.Fragment, { children: ctx.renderCitation(g(1)) }, key()) : /* @__PURE__ */ jsx31("sup", { className: "fd-md-cite", children: g(1) }, key()));
1946
+ out.push(ctx.renderCitation ? /* @__PURE__ */ jsx31(React11.Fragment, { children: ctx.renderCitation(g(1)) }, key()) : /* @__PURE__ */ jsx31("sup", { className: "fd-md-cite", children: g(1) }, key()));
1937
1947
  } else if (kind === "strongem") out.push(/* @__PURE__ */ jsx31("strong", { children: /* @__PURE__ */ jsx31("em", { children: inlineNodes(g(1), ctx, key()) }) }, key()));
1938
1948
  else if (kind === "strong") out.push(/* @__PURE__ */ jsx31("strong", { children: inlineNodes(g(1) || g(2), ctx, key()) }, key()));
1939
1949
  else if (kind === "em") out.push(/* @__PURE__ */ jsx31("em", { children: inlineNodes(g(1) || g(2), ctx, key()) }, key()));
@@ -2073,13 +2083,13 @@ function renderBlocks(blocks, ctx, path) {
2073
2083
  case "list": {
2074
2084
  const Tag2 = b.ordered ? "ol" : "ul";
2075
2085
  const isTask = b.items.some((it) => it.checked != null);
2076
- return /* @__PURE__ */ jsx31(Tag2, { className: "fd-md-list" + (isTask ? " is-task" : ""), start: b.ordered && b.start !== 1 ? b.start : void 0, children: b.items.map((it, j) => /* @__PURE__ */ jsxs26("li", { className: it.checked != null ? it.checked ? "is-done" : "is-todo" : void 0, children: [
2086
+ return /* @__PURE__ */ jsx31(Tag2, { className: "fd-md-list" + (isTask ? " is-task" : ""), start: b.ordered && b.start !== 1 ? b.start : void 0, children: b.items.map((it, j) => /* @__PURE__ */ jsxs27("li", { className: it.checked != null ? it.checked ? "is-done" : "is-todo" : void 0, children: [
2077
2087
  it.checked != null ? /* @__PURE__ */ jsx31("span", { className: "fd-md-task", "aria-hidden": "true", children: /* @__PURE__ */ jsx31("i", { className: "ph ph-" + (it.checked ? "check-square" : "square") }) }) : null,
2078
2088
  /* @__PURE__ */ jsx31("span", { className: "fd-md-li", children: renderBlocks(it.children, ctx, k + "-" + j) })
2079
2089
  ] }, k + "-" + j)) }, k);
2080
2090
  }
2081
2091
  case "table":
2082
- return /* @__PURE__ */ jsx31("div", { className: "fd-md-tablewrap", children: /* @__PURE__ */ jsxs26("table", { className: "fd-md-table", children: [
2092
+ return /* @__PURE__ */ jsx31("div", { className: "fd-md-tablewrap", children: /* @__PURE__ */ jsxs27("table", { className: "fd-md-table", children: [
2083
2093
  /* @__PURE__ */ jsx31("thead", { children: /* @__PURE__ */ jsx31("tr", { children: b.head.map((c, j) => /* @__PURE__ */ jsx31("th", { style: { textAlign: b.align[j] || "left" }, children: inlineNodes(c, ctx, k + "h" + j) }, j)) }) }),
2084
2094
  /* @__PURE__ */ jsx31("tbody", { children: b.rows.map((r, ri) => /* @__PURE__ */ jsx31("tr", { children: b.head.map((_, ci) => /* @__PURE__ */ jsx31("td", { style: { textAlign: b.align[ci] || "left" }, children: inlineNodes(r[ci] || "", ctx, k + ri + "c" + ci) }, ci)) }, ri)) })
2085
2095
  ] }) }, k);
@@ -2098,7 +2108,7 @@ function Markdown({
2098
2108
  onLinkClick
2099
2109
  }) {
2100
2110
  const ctx = { allowImages, headingOffset, renderCitation, onLinkClick, codeProps };
2101
- const blocks = React10.useMemo(() => parseBlocks(source), [source]);
2111
+ const blocks = React11.useMemo(() => parseBlocks(source), [source]);
2102
2112
  return /* @__PURE__ */ jsx31("div", { className: ["fd-md", className].filter(Boolean).join(" "), children: renderBlocks(blocks, ctx, "b") });
2103
2113
  }
2104
2114
  function MarkdownInline({ source = "", className = "", onLinkClick }) {
@@ -2109,13 +2119,13 @@ function markdownToText(src) {
2109
2119
  }
2110
2120
 
2111
2121
  // src/components/data/Meter.tsx
2112
- import { jsx as jsx32, jsxs as jsxs27 } from "react/jsx-runtime";
2122
+ import { jsx as jsx32, jsxs as jsxs28 } from "react/jsx-runtime";
2113
2123
  function Meter({ segments = [], unallocated = 0, height = 8, label, legend = false, className = "" }) {
2114
2124
  const total = segments.reduce((s, x) => s + x.value, 0) + unallocated;
2115
2125
  const pct = (v) => total ? v / total * 100 : 0;
2116
- return /* @__PURE__ */ jsxs27("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 8 }, children: [
2126
+ return /* @__PURE__ */ jsxs28("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 8 }, children: [
2117
2127
  label ? /* @__PURE__ */ jsx32("span", { className: "fd-label-lg fd-secondary", children: label }) : null,
2118
- /* @__PURE__ */ jsxs27("div", { className: "fd-meterbar", style: { height }, children: [
2128
+ /* @__PURE__ */ jsxs28("div", { className: "fd-meterbar", style: { height }, children: [
2119
2129
  segments.map((s, i) => /* @__PURE__ */ jsx32(
2120
2130
  "span",
2121
2131
  {
@@ -2127,12 +2137,12 @@ function Meter({ segments = [], unallocated = 0, height = 8, label, legend = fal
2127
2137
  )),
2128
2138
  unallocated > 0 ? /* @__PURE__ */ jsx32("span", { className: "fd-meterbar-seg fd-meterbar-unallocated", title: "Unallocated", style: { width: pct(unallocated) + "%" } }) : null
2129
2139
  ] }),
2130
- legend ? /* @__PURE__ */ jsxs27("div", { className: "fd-row", style: { gap: 16, flexWrap: "wrap" }, children: [
2131
- segments.map((s, i) => /* @__PURE__ */ jsxs27("span", { className: "fd-row fd-body-sm fd-secondary", style: { gap: 7 }, children: [
2140
+ legend ? /* @__PURE__ */ jsxs28("div", { className: "fd-row", style: { gap: 16, flexWrap: "wrap" }, children: [
2141
+ segments.map((s, i) => /* @__PURE__ */ jsxs28("span", { className: "fd-row fd-body-sm fd-secondary", style: { gap: 7 }, children: [
2132
2142
  /* @__PURE__ */ jsx32("span", { style: { width: 9, height: 9, borderRadius: 2, background: s.color || "var(--chart-" + (i % 8 + 1) + ")" } }),
2133
2143
  s.label
2134
2144
  ] }, i)),
2135
- unallocated > 0 ? /* @__PURE__ */ jsxs27("span", { className: "fd-row fd-body-sm fd-secondary", style: { gap: 7 }, children: [
2145
+ unallocated > 0 ? /* @__PURE__ */ jsxs28("span", { className: "fd-row fd-body-sm fd-secondary", style: { gap: 7 }, children: [
2136
2146
  /* @__PURE__ */ jsx32("span", { className: "fd-meterbar-unallocated", style: { width: 9, height: 9, borderRadius: 2 } }),
2137
2147
  "Unallocated"
2138
2148
  ] }) : null
@@ -2141,7 +2151,11 @@ function Meter({ segments = [], unallocated = 0, height = 8, label, legend = fal
2141
2151
  }
2142
2152
 
2143
2153
  // src/components/data/Pagination.tsx
2144
- import { Fragment as Fragment7, jsx as jsx33, jsxs as jsxs28 } from "react/jsx-runtime";
2154
+ import { Fragment as Fragment7, jsx as jsx33, jsxs as jsxs29 } from "react/jsx-runtime";
2155
+ var unitPluralRules = new Intl.PluralRules("en-US");
2156
+ function pluralizeUnit(n, singular, irregularPlural) {
2157
+ return unitPluralRules.select(n) === "one" ? singular : irregularPlural ?? `${singular}s`;
2158
+ }
2145
2159
  function Pagination({
2146
2160
  page = 1,
2147
2161
  pageSize = 25,
@@ -2150,7 +2164,8 @@ function Pagination({
2150
2164
  onPageChange,
2151
2165
  onPageSizeChange,
2152
2166
  loading = false,
2153
- unit = "rows",
2167
+ unit = "row",
2168
+ unitPlural,
2154
2169
  className = "",
2155
2170
  ...rest
2156
2171
  }) {
@@ -2160,18 +2175,19 @@ function Pagination({
2160
2175
  const go = (p) => {
2161
2176
  if (onPageChange && p >= 1 && p <= totalPages && p !== page) onPageChange(p);
2162
2177
  };
2178
+ const unitLabel = pluralizeUnit(total, unit, unitPlural);
2163
2179
  const nums = [];
2164
2180
  const span = 1;
2165
2181
  for (let i = 1; i <= totalPages; i++) {
2166
2182
  if (i === 1 || i === totalPages || Math.abs(i - page) <= span) nums.push(i);
2167
2183
  else if (nums[nums.length - 1] !== "\u2026") nums.push("\u2026");
2168
2184
  }
2169
- return /* @__PURE__ */ jsxs28("div", { className: ["fd-pag", className].filter(Boolean).join(" "), ...rest, children: [
2170
- /* @__PURE__ */ jsx33("span", { className: "fd-pag-count", children: loading ? /* @__PURE__ */ jsx33("span", { className: "fd-skel fd-skel-text", style: { display: "inline-block", height: 12, width: 108 } }) : total === 0 ? /* @__PURE__ */ jsxs28(Fragment7, { children: [
2185
+ return /* @__PURE__ */ jsxs29("div", { className: ["fd-pag", className].filter(Boolean).join(" "), ...rest, children: [
2186
+ /* @__PURE__ */ jsx33("span", { className: "fd-pag-count", children: loading ? /* @__PURE__ */ jsx33("span", { className: "fd-skel fd-skel-text", style: { display: "inline-block", height: 12, width: 108 } }) : total === 0 ? /* @__PURE__ */ jsxs29(Fragment7, { children: [
2171
2187
  "No ",
2172
- unit
2173
- ] }) : /* @__PURE__ */ jsxs28(Fragment7, { children: [
2174
- /* @__PURE__ */ jsxs28("strong", { children: [
2188
+ unitLabel
2189
+ ] }) : /* @__PURE__ */ jsxs29(Fragment7, { children: [
2190
+ /* @__PURE__ */ jsxs29("strong", { children: [
2175
2191
  from.toLocaleString(),
2176
2192
  "\u2013",
2177
2193
  to.toLocaleString()
@@ -2179,13 +2195,13 @@ function Pagination({
2179
2195
  " of ",
2180
2196
  total.toLocaleString(),
2181
2197
  " ",
2182
- unit
2198
+ unitLabel
2183
2199
  ] }) }),
2184
- onPageSizeChange ? /* @__PURE__ */ jsxs28("label", { className: "fd-pag-size", children: [
2200
+ onPageSizeChange ? /* @__PURE__ */ jsxs29("label", { className: "fd-pag-size", children: [
2185
2201
  /* @__PURE__ */ jsx33("span", { children: "Rows" }),
2186
2202
  /* @__PURE__ */ jsx33("select", { value: pageSize, onChange: (e) => onPageSizeChange(Number(e.target.value)), "aria-label": "Rows per page", children: pageSizes.map((n) => /* @__PURE__ */ jsx33("option", { value: n, children: n }, n)) })
2187
2203
  ] }) : null,
2188
- /* @__PURE__ */ jsxs28("span", { className: "fd-pag-nav", children: [
2204
+ /* @__PURE__ */ jsxs29("span", { className: "fd-pag-nav", children: [
2189
2205
  /* @__PURE__ */ jsx33("button", { type: "button", onClick: () => go(1), disabled: page <= 1, "aria-label": "First page", children: /* @__PURE__ */ jsx33("i", { className: "ph ph-caret-double-left" }) }),
2190
2206
  /* @__PURE__ */ jsx33("button", { type: "button", onClick: () => go(page - 1), disabled: page <= 1, "aria-label": "Previous page", children: /* @__PURE__ */ jsx33("i", { className: "ph ph-caret-left" }) }),
2191
2207
  nums.map((n, i) => n === "\u2026" ? /* @__PURE__ */ jsx33("span", { className: "fd-pag-gap", "aria-hidden": "true", children: "\u2026" }, "e" + i) : /* @__PURE__ */ jsx33(
@@ -2206,8 +2222,8 @@ function Pagination({
2206
2222
  }
2207
2223
 
2208
2224
  // src/components/data/RelativeTime.tsx
2209
- import * as React11 from "react";
2210
- import { jsxs as jsxs29 } from "react/jsx-runtime";
2225
+ import * as React12 from "react";
2226
+ import { jsxs as jsxs30 } from "react/jsx-runtime";
2211
2227
  var MIN = 6e4;
2212
2228
  var HOUR = 36e5;
2213
2229
  var DAY = 864e5;
@@ -2258,9 +2274,9 @@ function formatDuration(ms) {
2258
2274
  return h + "h" + (m % 60 ? " " + m % 60 + "m" : "");
2259
2275
  }
2260
2276
  function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true, ...rest }) {
2261
- const [, force] = React11.useState(0);
2277
+ const [, force] = React12.useState(0);
2262
2278
  const t = value instanceof Date ? value.getTime() : Date.parse(value);
2263
- React11.useEffect(() => {
2279
+ React12.useEffect(() => {
2264
2280
  if (!refresh2 || !t || isNaN(t)) return;
2265
2281
  const abs = Math.abs(t - Date.now());
2266
2282
  if (abs > DAY) return;
@@ -2269,17 +2285,17 @@ function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true,
2269
2285
  return () => clearInterval(id);
2270
2286
  }, [t, refresh2]);
2271
2287
  if (!t || isNaN(t)) return null;
2272
- return /* @__PURE__ */ jsxs29("time", { className, dateTime: new Date(t).toISOString(), title: formatAbsolute(new Date(t)), ...rest, children: [
2288
+ return /* @__PURE__ */ jsxs30("time", { className, dateTime: new Date(t).toISOString(), title: formatAbsolute(new Date(t)), ...rest, children: [
2273
2289
  prefix ? prefix + " " : "",
2274
2290
  formatRelative(new Date(t))
2275
2291
  ] });
2276
2292
  }
2277
2293
 
2278
2294
  // src/components/data/ScoreMeter.tsx
2279
- import * as React13 from "react";
2295
+ import * as React14 from "react";
2280
2296
 
2281
2297
  // src/components/data/SegmentedMeter.tsx
2282
- import * as React12 from "react";
2298
+ import * as React13 from "react";
2283
2299
 
2284
2300
  // src/kits/files.ts
2285
2301
  function formatBytes(n) {
@@ -2439,7 +2455,7 @@ var FileKit = {
2439
2455
  };
2440
2456
 
2441
2457
  // src/components/data/SegmentedMeter.tsx
2442
- import { jsx as jsx34, jsxs as jsxs30 } from "react/jsx-runtime";
2458
+ import { jsx as jsx34, jsxs as jsxs31 } from "react/jsx-runtime";
2443
2459
  var VARIANT_FILL = {
2444
2460
  brand: "var(--brand)",
2445
2461
  neutral: "var(--n-400)",
@@ -2484,16 +2500,16 @@ function SegmentedMeter({
2484
2500
  const pct = safeTotal ? Math.min(100, Math.round(used / safeTotal * 100)) : 0;
2485
2501
  const w = (v) => safeTotal ? Math.max(0, Math.min(100, Number(v) / safeTotal * 100)) : 0;
2486
2502
  const fill = (s, i) => s.color || (s.variant ? VARIANT_FILL[s.variant] : void 0) || CHART[i % CHART.length];
2487
- const generatedId = React12.useId();
2503
+ const generatedId = React13.useId();
2488
2504
  const uid2 = id || generatedId;
2489
- return /* @__PURE__ */ jsxs30("div", { className: ["fd-segmeter", className].filter(Boolean).join(" "), onClick, children: [
2490
- label || showTotal ? /* @__PURE__ */ jsxs30("div", { className: "fd-segmeter-head", children: [
2505
+ return /* @__PURE__ */ jsxs31("div", { className: ["fd-segmeter", className].filter(Boolean).join(" "), onClick, children: [
2506
+ label || showTotal ? /* @__PURE__ */ jsxs31("div", { className: "fd-segmeter-head", children: [
2491
2507
  label ? /* @__PURE__ */ jsx34("span", { className: "fd-segmeter-label", id: uid2 + "-l", children: label }) : /* @__PURE__ */ jsx34("span", {}),
2492
- showTotal ? /* @__PURE__ */ jsxs30("span", { className: "fd-segmeter-total fd-tabular", children: [
2508
+ showTotal ? /* @__PURE__ */ jsxs31("span", { className: "fd-segmeter-total fd-tabular", children: [
2493
2509
  format(used),
2494
2510
  /* @__PURE__ */ jsx34("span", { className: "fd-segmeter-sep", children: " / " }),
2495
2511
  safeTotal ? format(safeTotal) : "\u2014",
2496
- showPercent ? /* @__PURE__ */ jsxs30("span", { className: "fd-segmeter-pct", children: [
2512
+ showPercent ? /* @__PURE__ */ jsxs31("span", { className: "fd-segmeter-pct", children: [
2497
2513
  " (",
2498
2514
  pct,
2499
2515
  "%)"
@@ -2523,13 +2539,13 @@ function SegmentedMeter({
2523
2539
  ))
2524
2540
  }
2525
2541
  ),
2526
- legend ? /* @__PURE__ */ jsxs30("ul", { className: "fd-segmeter-legend", children: [
2527
- items.map((s, i) => /* @__PURE__ */ jsxs30("li", { children: [
2542
+ legend ? /* @__PURE__ */ jsxs31("ul", { className: "fd-segmeter-legend", children: [
2543
+ items.map((s, i) => /* @__PURE__ */ jsxs31("li", { children: [
2528
2544
  /* @__PURE__ */ jsx34("span", { className: "fd-segmeter-dot", style: { background: fill(s, i) }, "aria-hidden": "true" }),
2529
2545
  /* @__PURE__ */ jsx34("span", { className: "fd-segmeter-key", children: s.label }),
2530
2546
  /* @__PURE__ */ jsx34("span", { className: "fd-segmeter-val fd-tabular", children: format(s.value) })
2531
2547
  ] }, s.id || s.label || i)),
2532
- safeTotal && used < safeTotal ? /* @__PURE__ */ jsxs30("li", { className: "is-remainder", children: [
2548
+ safeTotal && used < safeTotal ? /* @__PURE__ */ jsxs31("li", { className: "is-remainder", children: [
2533
2549
  /* @__PURE__ */ jsx34("span", { className: "fd-segmeter-dot is-empty", "aria-hidden": "true" }),
2534
2550
  /* @__PURE__ */ jsx34("span", { className: "fd-segmeter-key", children: remainderLabel }),
2535
2551
  /* @__PURE__ */ jsx34("span", { className: "fd-segmeter-val fd-tabular", children: format(safeTotal - used) })
@@ -2540,11 +2556,11 @@ function SegmentedMeter({
2540
2556
  function QuotaRow({ label, percent = 0, note, tone, className = "" }) {
2541
2557
  const p = Math.max(0, Math.min(100, Math.round(Number(percent) || 0)));
2542
2558
  const auto = p >= 90 ? "danger" : p >= 70 ? "warn" : "brand";
2543
- return /* @__PURE__ */ jsxs30("div", { className: ["fd-quota", className].filter(Boolean).join(" "), children: [
2544
- /* @__PURE__ */ jsxs30("div", { className: "fd-quota-head", children: [
2559
+ return /* @__PURE__ */ jsxs31("div", { className: ["fd-quota", className].filter(Boolean).join(" "), children: [
2560
+ /* @__PURE__ */ jsxs31("div", { className: "fd-quota-head", children: [
2545
2561
  /* @__PURE__ */ jsx34("span", { className: "fd-quota-label", children: label }),
2546
2562
  note ? /* @__PURE__ */ jsx34("span", { className: "fd-quota-note", children: note }) : null,
2547
- /* @__PURE__ */ jsxs30("span", { className: "fd-quota-pct fd-tabular", children: [
2563
+ /* @__PURE__ */ jsxs31("span", { className: "fd-quota-pct fd-tabular", children: [
2548
2564
  p,
2549
2565
  "%"
2550
2566
  ] })
@@ -2554,7 +2570,7 @@ function QuotaRow({ label, percent = 0, note, tone, className = "" }) {
2554
2570
  }
2555
2571
 
2556
2572
  // src/components/data/ScoreMeter.tsx
2557
- import { jsx as jsx35, jsxs as jsxs31 } from "react/jsx-runtime";
2573
+ import { jsx as jsx35, jsxs as jsxs32 } from "react/jsx-runtime";
2558
2574
  function ScoreMeter({
2559
2575
  score,
2560
2576
  segments,
@@ -2568,10 +2584,10 @@ function ScoreMeter({
2568
2584
  breakdownWidth = 280,
2569
2585
  className = ""
2570
2586
  }) {
2571
- const [open, setOpen] = React13.useState(false);
2572
- const ref = React13.useRef(null);
2587
+ const [open, setOpen] = React14.useState(false);
2588
+ const ref = React14.useRef(null);
2573
2589
  const value = Math.max(0, Math.min(100, Math.round(Number(score) || 0)));
2574
- const body = /* @__PURE__ */ jsxs31(React13.Fragment, { children: [
2590
+ const body = /* @__PURE__ */ jsxs32(React14.Fragment, { children: [
2575
2591
  /* @__PURE__ */ jsx35("span", { className: "fd-scoremeter-rail", style: { width }, "aria-hidden": "true", children: /* @__PURE__ */ jsx35(SegmentedMeter, { total: 100, segments, height, showTotal: false, showPercent: false, legend: false }) }),
2576
2592
  showScore ? /* @__PURE__ */ jsx35("span", { className: "fd-scoremeter-value fd-tabular", "aria-hidden": "true", children: value }) : null
2577
2593
  ] });
@@ -2590,7 +2606,7 @@ function ScoreMeter({
2590
2606
  }
2591
2607
  );
2592
2608
  }
2593
- return /* @__PURE__ */ jsxs31(React13.Fragment, { children: [
2609
+ return /* @__PURE__ */ jsxs32(React14.Fragment, { children: [
2594
2610
  /* @__PURE__ */ jsx35(
2595
2611
  "button",
2596
2612
  {
@@ -2621,14 +2637,14 @@ function ScoreMeter({
2621
2637
  }
2622
2638
 
2623
2639
  // src/components/data/SortMenu.tsx
2624
- import * as React14 from "react";
2625
- import { jsx as jsx36, jsxs as jsxs32 } from "react/jsx-runtime";
2640
+ import * as React15 from "react";
2641
+ import { jsx as jsx36, jsxs as jsxs33 } from "react/jsx-runtime";
2626
2642
  var SORT_MENU_BASE = 120;
2627
2643
  function SortMenu({ fields = [], sort, onSort, align = "right", size = "md", className = "", ...rest }) {
2628
- const [open, setOpen] = React14.useState(false);
2644
+ const [open, setOpen] = React15.useState(false);
2629
2645
  const zIndex = useOverlayLayer(SORT_MENU_BASE);
2630
- const ref = React14.useRef(null);
2631
- React14.useEffect(() => {
2646
+ const ref = React15.useRef(null);
2647
+ React15.useEffect(() => {
2632
2648
  if (!open) return;
2633
2649
  const away = (e) => {
2634
2650
  if (ref.current && !ref.current.contains(e.target)) setOpen(false);
@@ -2670,16 +2686,16 @@ function SortMenu({ fields = [], sort, onSort, align = "right", size = "md", cla
2670
2686
  }
2671
2687
  );
2672
2688
  };
2673
- return /* @__PURE__ */ jsxs32("span", { className, style: { position: "relative", display: "inline-flex" }, ref, ...rest, children: [
2674
- /* @__PURE__ */ jsxs32(Button, { size, variant: "secondary", icon: dir === "asc" ? "sort-ascending" : "sort-descending", onClick: () => setOpen(!open), children: [
2689
+ return /* @__PURE__ */ jsxs33("span", { className, style: { position: "relative", display: "inline-flex" }, ref, ...rest, children: [
2690
+ /* @__PURE__ */ jsxs33(Button, { size, variant: "secondary", icon: dir === "asc" ? "sort-ascending" : "sort-descending", onClick: () => setOpen(!open), children: [
2675
2691
  cur ? cur.label : "Unsorted",
2676
2692
  /* @__PURE__ */ jsx36("i", { className: "ph ph-" + (dir === "asc" ? "arrow-up" : "arrow-down"), style: { fontSize: 12, marginLeft: 6, opacity: 0.75 } })
2677
2693
  ] }),
2678
- open ? /* @__PURE__ */ jsx36(LayerProvider, { zIndex, children: /* @__PURE__ */ jsx36("span", { className: "fd-view-enter", style: { position: "absolute", top: "calc(100% + 6px)", [align]: 0, zIndex, width: 280, maxWidth: "calc(100vw - 32px)", display: "block", background: "var(--surface)", border: "1px solid var(--border)", borderRadius: 10, boxShadow: "0 16px 44px rgba(11,13,17,.18)", padding: 8 }, children: /* @__PURE__ */ jsxs32("span", { className: "fd-stack", style: { gap: 2 }, children: [
2694
+ open ? /* @__PURE__ */ jsx36(LayerProvider, { zIndex, children: /* @__PURE__ */ jsx36("span", { className: "fd-view-enter", style: { position: "absolute", top: "calc(100% + 6px)", [align]: 0, zIndex, width: 280, maxWidth: "calc(100vw - 32px)", display: "block", background: "var(--surface)", border: "1px solid var(--border)", borderRadius: 10, boxShadow: "0 16px 44px rgba(11,13,17,.18)", padding: 8 }, children: /* @__PURE__ */ jsxs33("span", { className: "fd-stack", style: { gap: 2 }, children: [
2679
2695
  /* @__PURE__ */ jsx36("span", { className: "fd-overline fd-muted", style: { padding: "4px 8px 6px" }, children: "Sort by" }),
2680
2696
  fields.map((f) => {
2681
2697
  const active = cur && cur.key === f.key;
2682
- return /* @__PURE__ */ jsxs32("span", { className: "fd-row", style: { gap: 8, padding: "4px 8px", borderRadius: 7, background: active ? "var(--surface-brand)" : "transparent" }, children: [
2698
+ return /* @__PURE__ */ jsxs33("span", { className: "fd-row", style: { gap: 8, padding: "4px 8px", borderRadius: 7, background: active ? "var(--surface-brand)" : "transparent" }, children: [
2683
2699
  /* @__PURE__ */ jsx36("span", { className: "fd-body-sm", style: { flex: 1, fontWeight: active ? 700 : 500, color: active ? "var(--text-on-surface-brand)" : "var(--text)" }, children: f.label }),
2684
2700
  arrow(f, "asc"),
2685
2701
  arrow(f, "desc")
@@ -2690,8 +2706,8 @@ function SortMenu({ fields = [], sort, onSort, align = "right", size = "md", cla
2690
2706
  }
2691
2707
 
2692
2708
  // src/components/data/StepList.tsx
2693
- import * as React15 from "react";
2694
- import { jsx as jsx37, jsxs as jsxs33 } from "react/jsx-runtime";
2709
+ import * as React16 from "react";
2710
+ import { jsx as jsx37, jsxs as jsxs34 } from "react/jsx-runtime";
2695
2711
  var KIND_ICON = { tool: "wrench", search: "magnifying-glass", read: "file-text", write: "pencil-simple", reasoning: "brain", run: "terminal", fetch: "cloud-arrow-down" };
2696
2712
  function StepList({
2697
2713
  steps = [],
@@ -2703,9 +2719,9 @@ function StepList({
2703
2719
  dense = false,
2704
2720
  className = ""
2705
2721
  }) {
2706
- const [openState, setOpenState] = React15.useState(defaultOpen);
2722
+ const [openState, setOpenState] = React16.useState(defaultOpen);
2707
2723
  const open = openProp == null ? openState : openProp;
2708
- const [expanded, setExpanded] = React15.useState({});
2724
+ const [expanded, setExpanded] = React16.useState({});
2709
2725
  if (!steps.length) return null;
2710
2726
  const running = steps.some((s) => s.status === "running");
2711
2727
  const failed = steps.filter((s) => s.status === "error").length;
@@ -2717,15 +2733,15 @@ function StepList({
2717
2733
  if (openProp == null) setOpenState(next);
2718
2734
  onToggle && onToggle(next);
2719
2735
  };
2720
- return /* @__PURE__ */ jsxs33("div", { className: ["fd-steps", dense ? "is-dense" : "", open ? "is-open" : "", className].filter(Boolean).join(" "), children: [
2721
- /* @__PURE__ */ jsxs33("button", { type: "button", className: "fd-steps-head", onClick: toggle, "aria-expanded": open, children: [
2736
+ return /* @__PURE__ */ jsxs34("div", { className: ["fd-steps", dense ? "is-dense" : "", open ? "is-open" : "", className].filter(Boolean).join(" "), children: [
2737
+ /* @__PURE__ */ jsxs34("button", { type: "button", className: "fd-steps-head", onClick: toggle, "aria-expanded": open, children: [
2722
2738
  running ? /* @__PURE__ */ jsx37("span", { className: "fd-steps-spin", "aria-hidden": "true" }) : /* @__PURE__ */ jsx37("i", { className: "ph ph-" + (failed ? "warning-circle" : "check-circle"), "aria-hidden": "true" }),
2723
2739
  /* @__PURE__ */ jsx37("span", { className: "fd-steps-title", children: summary }),
2724
- /* @__PURE__ */ jsxs33("span", { className: "fd-steps-count fd-tabular", children: [
2740
+ /* @__PURE__ */ jsxs34("span", { className: "fd-steps-count fd-tabular", children: [
2725
2741
  steps.length,
2726
2742
  " step",
2727
2743
  steps.length === 1 ? "" : "s",
2728
- failed ? /* @__PURE__ */ jsxs33("span", { className: "fd-steps-failed", children: [
2744
+ failed ? /* @__PURE__ */ jsxs34("span", { className: "fd-steps-failed", children: [
2729
2745
  " \xB7 ",
2730
2746
  failed,
2731
2747
  " failed"
@@ -2737,10 +2753,10 @@ function StepList({
2737
2753
  const id = s.id || i;
2738
2754
  const isOpen = !!expanded[id];
2739
2755
  const icon = KIND_ICON[s.kind || ""] || "dot-outline";
2740
- return /* @__PURE__ */ jsxs33("li", { className: "fd-step is-" + (s.status || "ok"), children: [
2741
- /* @__PURE__ */ jsxs33("div", { className: "fd-step-row", children: [
2756
+ return /* @__PURE__ */ jsxs34("li", { className: "fd-step is-" + (s.status || "ok"), children: [
2757
+ /* @__PURE__ */ jsxs34("div", { className: "fd-step-row", children: [
2742
2758
  /* @__PURE__ */ jsx37("span", { className: "fd-step-icon", "aria-hidden": "true", children: s.status === "running" ? /* @__PURE__ */ jsx37("span", { className: "fd-steps-spin" }) : /* @__PURE__ */ jsx37("i", { className: "ph ph-" + icon }) }),
2743
- s.detail ? /* @__PURE__ */ jsxs33(
2759
+ s.detail ? /* @__PURE__ */ jsxs34(
2744
2760
  "button",
2745
2761
  {
2746
2762
  type: "button",
@@ -2763,8 +2779,8 @@ function StepList({
2763
2779
  }
2764
2780
 
2765
2781
  // src/components/data/VirtualList.tsx
2766
- import * as React16 from "react";
2767
- import { jsx as jsx38, jsxs as jsxs34 } from "react/jsx-runtime";
2782
+ import * as React17 from "react";
2783
+ import { jsx as jsx38, jsxs as jsxs35 } from "react/jsx-runtime";
2768
2784
  var VIRTUAL_LIST_BUFFER_ROWS = 20;
2769
2785
  var VIRTUAL_LIST_ROW_GAP = 6;
2770
2786
  function computeVirtualWindow(opts) {
@@ -2815,35 +2831,35 @@ function VirtualList({
2815
2831
  className = "",
2816
2832
  style
2817
2833
  }) {
2818
- const [scrollTop, setScrollTop] = React16.useState(0);
2819
- const loaded = React16.useMemo(
2834
+ const [scrollTop, setScrollTop] = React17.useState(0);
2835
+ const loaded = React17.useMemo(
2820
2836
  () => ({ firstItemIndex, count: items.length }),
2821
2837
  [firstItemIndex, items.length]
2822
2838
  );
2823
2839
  const total = Math.max(totalCount == null ? 0 : totalCount, firstItemIndex + items.length);
2824
2840
  const bandKey = firstItemIndex + ":" + items.length;
2825
- const win = React16.useMemo(
2841
+ const win = React17.useMemo(
2826
2842
  () => computeVirtualWindow({ scrollTop, viewportHeight: height, itemHeight, itemCount: total, loaded }),
2827
2843
  [scrollTop, height, itemHeight, total, loaded]
2828
2844
  );
2829
- const need = React16.useMemo(() => computeNeedMore(win, loaded), [win, loaded]);
2845
+ const need = React17.useMemo(() => computeNeedMore(win, loaded), [win, loaded]);
2830
2846
  const wantStart = need.start && hasMore?.start !== false;
2831
2847
  const wantEnd = need.end && hasMore?.end !== false;
2832
2848
  const bucket2 = Math.floor(win.visibleStart / VIRTUAL_LIST_BUFFER_ROWS);
2833
2849
  const askKey = bandKey + "@" + bucket2;
2834
- const asked = React16.useRef({ start: null, end: null });
2835
- React16.useEffect(() => {
2850
+ const asked = React17.useRef({ start: null, end: null });
2851
+ React17.useEffect(() => {
2836
2852
  if (loading || !wantStart || asked.current.start === askKey) return;
2837
2853
  asked.current.start = askKey;
2838
2854
  onNeedMore("start", win);
2839
2855
  }, [wantStart, loading, askKey, onNeedMore, win]);
2840
- React16.useEffect(() => {
2856
+ React17.useEffect(() => {
2841
2857
  if (loading || !wantEnd || asked.current.end === askKey) return;
2842
2858
  asked.current.end = askKey;
2843
2859
  onNeedMore("end", win);
2844
2860
  }, [wantEnd, loading, askKey, onNeedMore, win]);
2845
- const lastKeysRef = React16.useRef(null);
2846
- const newKeys = React16.useMemo(() => {
2861
+ const lastKeysRef = React17.useRef(null);
2862
+ const newKeys = React17.useMemo(() => {
2847
2863
  const prev = lastKeysRef.current;
2848
2864
  if (!prev) return /* @__PURE__ */ new Set();
2849
2865
  const fresh = /* @__PURE__ */ new Set();
@@ -2853,7 +2869,7 @@ function VirtualList({
2853
2869
  }
2854
2870
  return fresh;
2855
2871
  }, [items]);
2856
- React16.useEffect(() => {
2872
+ React17.useEffect(() => {
2857
2873
  lastKeysRef.current = new Set(items.map(keyOf));
2858
2874
  }, [items]);
2859
2875
  const gapStyle = { "--fd-vlist-gap": rowGap + "px" };
@@ -2877,8 +2893,8 @@ function VirtualList({
2877
2893
  )
2878
2894
  );
2879
2895
  }
2880
- return /* @__PURE__ */ jsxs34("div", { className: ["fd-vlist-wrap", className].filter(Boolean).join(" "), style: { height, position: "relative", ...gapStyle, ...style }, children: [
2881
- /* @__PURE__ */ jsxs34(
2896
+ return /* @__PURE__ */ jsxs35("div", { className: ["fd-vlist-wrap", className].filter(Boolean).join(" "), style: { height, position: "relative", ...gapStyle, ...style }, children: [
2897
+ /* @__PURE__ */ jsxs35(
2882
2898
  "div",
2883
2899
  {
2884
2900
  className: "fd-vlist fd-scrollbar",
@@ -2890,7 +2906,7 @@ function VirtualList({
2890
2906
  ]
2891
2907
  }
2892
2908
  ),
2893
- refreshing ? /* @__PURE__ */ jsx38("div", { className: "fd-vlist-refresh-scrim", children: /* @__PURE__ */ jsxs34("div", { className: "fd-vlist-refresh-card", children: [
2909
+ refreshing ? /* @__PURE__ */ jsx38("div", { className: "fd-vlist-refresh-scrim", children: /* @__PURE__ */ jsxs35("div", { className: "fd-vlist-refresh-card", children: [
2894
2910
  /* @__PURE__ */ jsx38("span", { className: "fd-spinner", "aria-hidden": "true" }),
2895
2911
  /* @__PURE__ */ jsx38("span", { className: "fd-body-sm", children: refreshingLabel })
2896
2912
  ] }) }) : null
@@ -2898,8 +2914,8 @@ function VirtualList({
2898
2914
  }
2899
2915
 
2900
2916
  // src/components/data/EntityRow.tsx
2901
- import * as React17 from "react";
2902
- import { jsx as jsx39, jsxs as jsxs35 } from "react/jsx-runtime";
2917
+ import * as React18 from "react";
2918
+ import { jsx as jsx39, jsxs as jsxs36 } from "react/jsx-runtime";
2903
2919
  var ENTITY_ROW_METRIC_WIDTH = 74;
2904
2920
  var METRIC_TONE_COLOR = {
2905
2921
  default: "var(--text-2)",
@@ -2911,7 +2927,7 @@ function EntityRowMetrics({ metrics, className = "", style }) {
2911
2927
  const key = m.id || m.label || i;
2912
2928
  const className2 = ["fd-erow-metric", m.tone && m.tone !== "default" ? "is-" + m.tone : "", m.tooltip != null ? "is-described" : ""].filter(Boolean).join(" ");
2913
2929
  const tone = { color: METRIC_TONE_COLOR[m.tone || "default"] };
2914
- const content = /* @__PURE__ */ jsxs35(React17.Fragment, { children: [
2930
+ const content = /* @__PURE__ */ jsxs36(React18.Fragment, { children: [
2915
2931
  m.icon ? /* @__PURE__ */ jsx39("i", { className: "ph ph-" + m.icon, "aria-hidden": "true" }) : null,
2916
2932
  /* @__PURE__ */ jsx39("span", { className: "fd-erow-metric-value fd-tabular", children: m.value }),
2917
2933
  /* @__PURE__ */ jsx39("span", { className: "fd-sr", children: " " + m.label })
@@ -2932,7 +2948,7 @@ function EntityRow({
2932
2948
  className = ""
2933
2949
  }) {
2934
2950
  const hasStrip = metrics && metrics.length > 0 || accessory != null;
2935
- return /* @__PURE__ */ jsxs35(
2951
+ return /* @__PURE__ */ jsxs36(
2936
2952
  "div",
2937
2953
  {
2938
2954
  onPointerDown,
@@ -2951,12 +2967,12 @@ function EntityRow({
2951
2967
  },
2952
2968
  children: [
2953
2969
  draggable ? /* @__PURE__ */ jsx39("i", { className: "ph ph-dots-six-vertical", "aria-hidden": "true", style: { fontSize: 14, flex: "none", color: "var(--text-muted)" } }) : null,
2954
- /* @__PURE__ */ jsxs35("span", { className: "fd-erow-body", children: [
2955
- /* @__PURE__ */ jsxs35("span", { className: "fd-erow-titleline", children: [
2970
+ /* @__PURE__ */ jsxs36("span", { className: "fd-erow-body", children: [
2971
+ /* @__PURE__ */ jsxs36("span", { className: "fd-erow-titleline", children: [
2956
2972
  /* @__PURE__ */ jsx39("span", { className: "fd-erow-title fd-body-sm", children: title }),
2957
2973
  meta ? /* @__PURE__ */ jsx39("span", { className: "fd-erow-meta", children: meta }) : null
2958
2974
  ] }),
2959
- hasStrip ? /* @__PURE__ */ jsxs35("span", { className: "fd-erow-strip", children: [
2975
+ hasStrip ? /* @__PURE__ */ jsxs36("span", { className: "fd-erow-strip", children: [
2960
2976
  metrics && metrics.length ? /* @__PURE__ */ jsx39(EntityRowMetrics, { metrics }) : null,
2961
2977
  accessory ? /* @__PURE__ */ jsx39("span", { className: "fd-erow-accessory", children: accessory }) : null
2962
2978
  ] }) : null
@@ -2979,18 +2995,18 @@ function EntityRow({
2979
2995
  }
2980
2996
 
2981
2997
  // src/components/data/TransferList.tsx
2982
- import * as React19 from "react";
2998
+ import * as React20 from "react";
2983
2999
  import { createPortal as createPortal4 } from "react-dom";
2984
3000
 
2985
3001
  // src/components/forms/field.tsx
2986
- import * as React18 from "react";
2987
- import { jsx as jsx40, jsxs as jsxs36 } from "react/jsx-runtime";
3002
+ import * as React19 from "react";
3003
+ import { jsx as jsx40, jsxs as jsxs37 } from "react/jsx-runtime";
2988
3004
  function useFieldId(id) {
2989
- const generated = React18.useId();
3005
+ const generated = React19.useId();
2990
3006
  return id || generated;
2991
3007
  }
2992
3008
  function FieldLabel({ htmlFor, id, required = false, onClick, children }) {
2993
- return /* @__PURE__ */ jsxs36("label", { className: "fd-field-label", htmlFor, id, onClick, children: [
3009
+ return /* @__PURE__ */ jsxs37("label", { className: "fd-field-label", htmlFor, id, onClick, children: [
2994
3010
  children,
2995
3011
  required ? /* @__PURE__ */ jsx40("span", { className: "fd-field-req", "aria-hidden": "true", children: "*" }) : null
2996
3012
  ] });
@@ -3002,7 +3018,7 @@ function useTriggerLabelling(label, id) {
3002
3018
  }
3003
3019
 
3004
3020
  // src/components/forms/Input.tsx
3005
- import { jsx as jsx41, jsxs as jsxs37 } from "react/jsx-runtime";
3021
+ import { jsx as jsx41, jsxs as jsxs38 } from "react/jsx-runtime";
3006
3022
  function Input({
3007
3023
  label,
3008
3024
  help,
@@ -3029,16 +3045,16 @@ function Input({
3029
3045
  disabled ? "fd-input-disabled" : "",
3030
3046
  size === "lg" ? "fd-input-lg" : ""
3031
3047
  ].filter(Boolean).join(" ");
3032
- return /* @__PURE__ */ jsxs37("div", { className: ["fd-field", className].filter(Boolean).join(" "), style, children: [
3048
+ return /* @__PURE__ */ jsxs38("div", { className: ["fd-field", className].filter(Boolean).join(" "), style, children: [
3033
3049
  label ? /* @__PURE__ */ jsx41(FieldLabel, { htmlFor: fieldId, required, children: label }) : null,
3034
- /* @__PURE__ */ jsxs37("div", { className: box, children: [
3050
+ /* @__PURE__ */ jsxs38("div", { className: box, children: [
3035
3051
  icon ? /* @__PURE__ */ jsx41("span", { className: "fd-input-icon", children: /* @__PURE__ */ jsx41("i", { className: "ph ph-" + icon, "aria-hidden": "true" }) }) : null,
3036
3052
  prefix ? /* @__PURE__ */ jsx41("span", { className: "fd-input-affix", children: prefix }) : null,
3037
3053
  /* @__PURE__ */ jsx41("input", { id: fieldId, disabled, style: inputStyle, "aria-invalid": error ? "true" : void 0, ...rest }),
3038
3054
  loading ? /* @__PURE__ */ jsx41("span", { className: "fd-spinner", style: { color: "var(--text-muted)" }, "aria-label": "Loading" }) : null,
3039
3055
  suffix && !loading ? /* @__PURE__ */ jsx41("span", { className: "fd-input-affix", children: suffix }) : null
3040
3056
  ] }),
3041
- error ? /* @__PURE__ */ jsxs37("span", { className: "fd-field-error", children: [
3057
+ error ? /* @__PURE__ */ jsxs38("span", { className: "fd-field-error", children: [
3042
3058
  /* @__PURE__ */ jsx41("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
3043
3059
  error
3044
3060
  ] }) : help ? /* @__PURE__ */ jsx41("span", { className: "fd-field-help", children: help }) : null
@@ -3090,7 +3106,7 @@ function SearchField({
3090
3106
  }
3091
3107
 
3092
3108
  // src/components/data/TransferList.tsx
3093
- import { jsx as jsx43, jsxs as jsxs38 } from "react/jsx-runtime";
3109
+ import { jsx as jsx43, jsxs as jsxs39 } from "react/jsx-runtime";
3094
3110
  var emptyHasMore = {};
3095
3111
  var DRAG_THRESHOLD_PX = 5;
3096
3112
  function TransferList({
@@ -3104,12 +3120,12 @@ function TransferList({
3104
3120
  listHeight = 440,
3105
3121
  className = ""
3106
3122
  }) {
3107
- const [drag, setDrag] = React19.useState(null);
3108
- const [dragOverSide, setDragOverSide] = React19.useState(null);
3109
- const dragRef = React19.useRef(null);
3110
- const armedRef = React19.useRef(null);
3111
- const sideRefs = React19.useRef({ left: null, right: null });
3112
- const hitTestSide = React19.useCallback((x, y) => {
3123
+ const [drag, setDrag] = React20.useState(null);
3124
+ const [dragOverSide, setDragOverSide] = React20.useState(null);
3125
+ const dragRef = React20.useRef(null);
3126
+ const armedRef = React20.useRef(null);
3127
+ const sideRefs = React20.useRef({ left: null, right: null });
3128
+ const hitTestSide = React20.useCallback((x, y) => {
3113
3129
  for (const side of ["left", "right"]) {
3114
3130
  const el = sideRefs.current[side];
3115
3131
  if (!el) continue;
@@ -3118,7 +3134,7 @@ function TransferList({
3118
3134
  }
3119
3135
  return null;
3120
3136
  }, []);
3121
- const findItem = React19.useCallback(
3137
+ const findItem = React20.useCallback(
3122
3138
  (side, key) => (side === "left" ? left.items : right.items).find((it) => keyOf(it) === key),
3123
3139
  [left.items, right.items, keyOf]
3124
3140
  );
@@ -3140,7 +3156,7 @@ function TransferList({
3140
3156
  height: rect.height
3141
3157
  };
3142
3158
  };
3143
- React19.useEffect(() => {
3159
+ React20.useEffect(() => {
3144
3160
  const onMovePointer = (e) => {
3145
3161
  const armed = armedRef.current;
3146
3162
  if (!armed || e.pointerId !== armed.pointerId) return;
@@ -3193,7 +3209,7 @@ function TransferList({
3193
3209
  window.removeEventListener("pointercancel", endDrag);
3194
3210
  };
3195
3211
  }, [hitTestSide, findItem, onMove]);
3196
- React19.useEffect(() => {
3212
+ React20.useEffect(() => {
3197
3213
  if (!drag || typeof document === "undefined") return;
3198
3214
  const prev = document.body.style.userSelect;
3199
3215
  document.body.style.userSelect = "none";
@@ -3203,7 +3219,7 @@ function TransferList({
3203
3219
  }, [drag]);
3204
3220
  const renderSide = (side, cfg, opposite) => {
3205
3221
  const showOverlay = drag != null && dragOverSide === side;
3206
- return /* @__PURE__ */ jsxs38(
3222
+ return /* @__PURE__ */ jsxs39(
3207
3223
  "div",
3208
3224
  {
3209
3225
  ref: (el) => {
@@ -3211,12 +3227,12 @@ function TransferList({
3211
3227
  },
3212
3228
  className: ["fd-tlist-side", dragOverSide === side ? "is-drop-target" : ""].filter(Boolean).join(" "),
3213
3229
  children: [
3214
- cfg.label ? /* @__PURE__ */ jsxs38("span", { className: "fd-overline fd-muted", children: [
3230
+ cfg.label ? /* @__PURE__ */ jsxs39("span", { className: "fd-overline fd-muted", children: [
3215
3231
  cfg.label,
3216
3232
  cfg.total != null ? " (" + cfg.total.toLocaleString() + ")" : ""
3217
3233
  ] }) : null,
3218
3234
  cfg.header ? /* @__PURE__ */ jsx43("div", { className: "fd-tlist-header", children: cfg.header }) : null,
3219
- /* @__PURE__ */ jsxs38("span", { className: "fd-row", style: { gap: 8 }, children: [
3235
+ /* @__PURE__ */ jsxs39("span", { className: "fd-row", style: { gap: 8 }, children: [
3220
3236
  /* @__PURE__ */ jsx43(SearchField, { value: cfg.search, onChange: cfg.onSearchChange, placeholder: "Search", "aria-label": (cfg.label || side) + " search", style: { flex: 1 } }),
3221
3237
  /* @__PURE__ */ jsx43(SortMenu, { fields: cfg.sortFields, sort: cfg.sort, onSort: cfg.onSort, align: side === "left" ? "left" : "right" })
3222
3238
  ] }),
@@ -3263,7 +3279,7 @@ function TransferList({
3263
3279
  }
3264
3280
  ),
3265
3281
  cfg.footer ? /* @__PURE__ */ jsx43("div", { className: "fd-tlist-footer", children: cfg.footer }) : null,
3266
- showOverlay ? /* @__PURE__ */ jsx43("div", { className: "fd-tlist-drop-overlay", "aria-hidden": "true", children: /* @__PURE__ */ jsxs38("span", { className: "fd-tlist-drop-card", children: [
3282
+ showOverlay ? /* @__PURE__ */ jsx43("div", { className: "fd-tlist-drop-overlay", "aria-hidden": "true", children: /* @__PURE__ */ jsxs39("span", { className: "fd-tlist-drop-card", children: [
3267
3283
  /* @__PURE__ */ jsx43("i", { className: "ph ph-tray-arrow-down", style: { fontSize: 18 }, "aria-hidden": "true" }),
3268
3284
  /* @__PURE__ */ jsx43("span", { className: "fd-body-sm", style: { fontWeight: 600 }, children: cfg.dropLabel || "Drop here" + (cfg.label ? " \u2014 " + cfg.label : "") })
3269
3285
  ] }) }) : null
@@ -3271,8 +3287,8 @@ function TransferList({
3271
3287
  }
3272
3288
  );
3273
3289
  };
3274
- return /* @__PURE__ */ jsxs38("div", { className: ["fd-tlist", className].filter(Boolean).join(" "), children: [
3275
- /* @__PURE__ */ jsxs38("div", { className: "fd-tlist-panes", children: [
3290
+ return /* @__PURE__ */ jsxs39("div", { className: ["fd-tlist", className].filter(Boolean).join(" "), children: [
3291
+ /* @__PURE__ */ jsxs39("div", { className: "fd-tlist-panes", children: [
3276
3292
  renderSide("left", left, "right"),
3277
3293
  renderSide("right", right, "left")
3278
3294
  ] }),
@@ -3301,19 +3317,19 @@ function TransferList({
3301
3317
  }
3302
3318
 
3303
3319
  // src/components/forms/Checkbox.tsx
3304
- import * as React20 from "react";
3305
- import { jsx as jsx44, jsxs as jsxs39 } from "react/jsx-runtime";
3320
+ import * as React21 from "react";
3321
+ import { jsx as jsx44, jsxs as jsxs40 } from "react/jsx-runtime";
3306
3322
  function Checkbox({ label, description, card = false, indeterminate = false, className = "", ...rest }) {
3307
- const ref = React20.useRef(null);
3308
- React20.useEffect(() => {
3323
+ const ref = React21.useRef(null);
3324
+ React21.useEffect(() => {
3309
3325
  if (ref.current) ref.current.indeterminate = indeterminate;
3310
3326
  }, [indeterminate]);
3311
- return /* @__PURE__ */ jsxs39("label", { className: ["fd-choice", card ? "fd-choice-card" : "", className].filter(Boolean).join(" "), children: [
3312
- /* @__PURE__ */ jsxs39("span", { className: "fd-choice-input", children: [
3327
+ return /* @__PURE__ */ jsxs40("label", { className: ["fd-choice", card ? "fd-choice-card" : "", className].filter(Boolean).join(" "), children: [
3328
+ /* @__PURE__ */ jsxs40("span", { className: "fd-choice-input", children: [
3313
3329
  /* @__PURE__ */ jsx44("input", { ref, type: "checkbox", ...rest }),
3314
3330
  /* @__PURE__ */ jsx44("span", { className: "fd-choice-box", "aria-hidden": "true", children: /* @__PURE__ */ jsx44("i", { className: indeterminate ? "ph ph-minus" : "ph ph-check" }) })
3315
3331
  ] }),
3316
- /* @__PURE__ */ jsxs39("span", { className: "fd-choice-text", children: [
3332
+ /* @__PURE__ */ jsxs40("span", { className: "fd-choice-text", children: [
3317
3333
  /* @__PURE__ */ jsx44("span", { className: "fd-choice-title", children: label }),
3318
3334
  description ? /* @__PURE__ */ jsx44("span", { className: "fd-choice-desc", children: description }) : null
3319
3335
  ] })
@@ -3321,14 +3337,14 @@ function Checkbox({ label, description, card = false, indeterminate = false, cla
3321
3337
  }
3322
3338
 
3323
3339
  // src/components/forms/Radio.tsx
3324
- import { jsx as jsx45, jsxs as jsxs40 } from "react/jsx-runtime";
3340
+ import { jsx as jsx45, jsxs as jsxs41 } from "react/jsx-runtime";
3325
3341
  function Radio({ label, description, card = false, className = "", ...rest }) {
3326
- return /* @__PURE__ */ jsxs40("label", { className: ["fd-choice", card ? "fd-choice-card" : "", className].filter(Boolean).join(" "), children: [
3327
- /* @__PURE__ */ jsxs40("span", { className: "fd-choice-input", children: [
3342
+ return /* @__PURE__ */ jsxs41("label", { className: ["fd-choice", card ? "fd-choice-card" : "", className].filter(Boolean).join(" "), children: [
3343
+ /* @__PURE__ */ jsxs41("span", { className: "fd-choice-input", children: [
3328
3344
  /* @__PURE__ */ jsx45("input", { type: "radio", ...rest }),
3329
3345
  /* @__PURE__ */ jsx45("span", { className: "fd-choice-box fd-choice-box-round", "aria-hidden": "true", children: /* @__PURE__ */ jsx45("span", { className: "fd-choice-dot" }) })
3330
3346
  ] }),
3331
- /* @__PURE__ */ jsxs40("span", { className: "fd-choice-text", children: [
3347
+ /* @__PURE__ */ jsxs41("span", { className: "fd-choice-text", children: [
3332
3348
  /* @__PURE__ */ jsx45("span", { className: "fd-choice-title", children: label }),
3333
3349
  description ? /* @__PURE__ */ jsx45("span", { className: "fd-choice-desc", children: description }) : null
3334
3350
  ] })
@@ -3336,12 +3352,12 @@ function Radio({ label, description, card = false, className = "", ...rest }) {
3336
3352
  }
3337
3353
 
3338
3354
  // src/components/forms/Switch.tsx
3339
- import { jsx as jsx46, jsxs as jsxs41 } from "react/jsx-runtime";
3355
+ import { jsx as jsx46, jsxs as jsxs42 } from "react/jsx-runtime";
3340
3356
  function Switch({ label, description, className = "", ...rest }) {
3341
- return /* @__PURE__ */ jsxs41("label", { className: ["fd-switch", className].filter(Boolean).join(" "), children: [
3357
+ return /* @__PURE__ */ jsxs42("label", { className: ["fd-switch", className].filter(Boolean).join(" "), children: [
3342
3358
  /* @__PURE__ */ jsx46("input", { type: "checkbox", role: "switch", ...rest }),
3343
3359
  /* @__PURE__ */ jsx46("span", { className: "fd-switch-track", children: /* @__PURE__ */ jsx46("span", { className: "fd-switch-thumb" }) }),
3344
- label ? /* @__PURE__ */ jsxs41("span", { className: "fd-choice-text", children: [
3360
+ label ? /* @__PURE__ */ jsxs42("span", { className: "fd-choice-text", children: [
3345
3361
  /* @__PURE__ */ jsx46("span", { className: "fd-switch-label", children: label }),
3346
3362
  description ? /* @__PURE__ */ jsx46("span", { className: "fd-choice-desc", children: description }) : null
3347
3363
  ] }) : null
@@ -3349,14 +3365,14 @@ function Switch({ label, description, className = "", ...rest }) {
3349
3365
  }
3350
3366
 
3351
3367
  // src/components/forms/Textarea.tsx
3352
- import { jsx as jsx47, jsxs as jsxs42 } from "react/jsx-runtime";
3368
+ import { jsx as jsx47, jsxs as jsxs43 } from "react/jsx-runtime";
3353
3369
  function Textarea({ label, help, error, required = false, rows = 4, disabled = false, id, className = "", style, ...rest }) {
3354
3370
  const fieldId = useFieldId(id);
3355
3371
  const box = ["fd-input", "fd-input-textarea", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" ");
3356
- return /* @__PURE__ */ jsxs42("div", { className: ["fd-field", className].filter(Boolean).join(" "), style, children: [
3372
+ return /* @__PURE__ */ jsxs43("div", { className: ["fd-field", className].filter(Boolean).join(" "), style, children: [
3357
3373
  label ? /* @__PURE__ */ jsx47(FieldLabel, { htmlFor: fieldId, required, children: label }) : null,
3358
3374
  /* @__PURE__ */ jsx47("div", { className: box, children: /* @__PURE__ */ jsx47("textarea", { id: fieldId, rows, disabled, "aria-invalid": error ? "true" : void 0, ...rest }) }),
3359
- error ? /* @__PURE__ */ jsxs42("span", { className: "fd-field-error", children: [
3375
+ error ? /* @__PURE__ */ jsxs43("span", { className: "fd-field-error", children: [
3360
3376
  /* @__PURE__ */ jsx47("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
3361
3377
  error
3362
3378
  ] }) : help ? /* @__PURE__ */ jsx47("span", { className: "fd-field-help", children: help }) : null
@@ -3364,8 +3380,8 @@ function Textarea({ label, help, error, required = false, rows = 4, disabled = f
3364
3380
  }
3365
3381
 
3366
3382
  // src/components/forms/NumberInput.tsx
3367
- import * as React21 from "react";
3368
- import { jsx as jsx48, jsxs as jsxs43 } from "react/jsx-runtime";
3383
+ import * as React22 from "react";
3384
+ import { jsx as jsx48, jsxs as jsxs44 } from "react/jsx-runtime";
3369
3385
  function NumberInput({
3370
3386
  label,
3371
3387
  help,
@@ -3392,10 +3408,10 @@ function NumberInput({
3392
3408
  const n = Number(String(v == null ? "" : v).replace(/[^0-9.-]/g, ""));
3393
3409
  return isNaN(n) ? null : n;
3394
3410
  };
3395
- const [text, setText] = React21.useState(value == null || value === "" ? "" : String(value));
3396
- const [editing, setEditing] = React21.useState(false);
3397
- const timer = React21.useRef(null);
3398
- React21.useEffect(() => {
3411
+ const [text, setText] = React22.useState(value == null || value === "" ? "" : String(value));
3412
+ const [editing, setEditing] = React22.useState(false);
3413
+ const timer = React22.useRef(null);
3414
+ React22.useEffect(() => {
3399
3415
  if (!editing) setText(value == null || value === "" ? "" : String(value));
3400
3416
  }, [value, editing]);
3401
3417
  const clamp = (n) => Math.min(max, Math.max(min, n));
@@ -3419,7 +3435,7 @@ function NumberInput({
3419
3435
  const release = () => {
3420
3436
  if (timer.current) clearTimeout(timer.current);
3421
3437
  };
3422
- React21.useEffect(() => () => {
3438
+ React22.useEffect(() => () => {
3423
3439
  if (timer.current) clearTimeout(timer.current);
3424
3440
  }, []);
3425
3441
  const shown = editing ? text : (() => {
@@ -3429,9 +3445,9 @@ function NumberInput({
3429
3445
  const box = ["fd-input", "fd-input-num", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" ");
3430
3446
  const fieldName = label || ariaLabel;
3431
3447
  const stepperName = (verb) => fieldName ? verb + " " + fieldName : verb;
3432
- return /* @__PURE__ */ jsxs43("div", { className: ["fd-field", className].filter(Boolean).join(" "), style, children: [
3448
+ return /* @__PURE__ */ jsxs44("div", { className: ["fd-field", className].filter(Boolean).join(" "), style, children: [
3433
3449
  label ? /* @__PURE__ */ jsx48(FieldLabel, { htmlFor: fieldId, required, children: label }) : null,
3434
- /* @__PURE__ */ jsxs43("div", { className: box, style: { gap: 8 }, children: [
3450
+ /* @__PURE__ */ jsxs44("div", { className: box, style: { gap: 8 }, children: [
3435
3451
  prefix ? /* @__PURE__ */ jsx48("span", { className: "fd-input-affix", children: prefix }) : null,
3436
3452
  /* @__PURE__ */ jsx48(
3437
3453
  "input",
@@ -3469,7 +3485,7 @@ function NumberInput({
3469
3485
  }
3470
3486
  ),
3471
3487
  suffix ? /* @__PURE__ */ jsx48("span", { className: "fd-input-affix", children: suffix }) : null,
3472
- /* @__PURE__ */ jsxs43("span", { className: "fd-row", style: { gap: 4, flex: "none" }, children: [
3488
+ /* @__PURE__ */ jsxs44("span", { className: "fd-row", style: { gap: 4, flex: "none" }, children: [
3473
3489
  /* @__PURE__ */ jsx48(
3474
3490
  "button",
3475
3491
  {
@@ -3498,7 +3514,7 @@ function NumberInput({
3498
3514
  )
3499
3515
  ] })
3500
3516
  ] }),
3501
- error ? /* @__PURE__ */ jsxs43("span", { className: "fd-field-error", children: [
3517
+ error ? /* @__PURE__ */ jsxs44("span", { className: "fd-field-error", children: [
3502
3518
  /* @__PURE__ */ jsx48("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
3503
3519
  error
3504
3520
  ] }) : help ? /* @__PURE__ */ jsx48("span", { className: "fd-field-help", children: help }) : null
@@ -3506,8 +3522,8 @@ function NumberInput({
3506
3522
  }
3507
3523
 
3508
3524
  // src/components/forms/Select.tsx
3509
- import * as React22 from "react";
3510
- import { jsx as jsx49, jsxs as jsxs44 } from "react/jsx-runtime";
3525
+ import * as React23 from "react";
3526
+ import { jsx as jsx49, jsxs as jsxs45 } from "react/jsx-runtime";
3511
3527
  var norm = (o) => typeof o === "string" ? { value: o, label: o } : o;
3512
3528
  function Select({
3513
3529
  label,
@@ -3533,13 +3549,13 @@ function Select({
3533
3549
  const isOn = (v) => multiple ? vals.includes(v) : v === value;
3534
3550
  const hasSearch = searchable === void 0 ? opts.length > 8 : searchable;
3535
3551
  const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
3536
- const [open, setOpen] = React22.useState(false);
3537
- const [q, setQ] = React22.useState("");
3538
- const [active, setActive] = React22.useState(-1);
3539
- const rootRef = React22.useRef(null);
3540
- const boxRef = React22.useRef(null);
3541
- const listRef = React22.useRef(null);
3542
- const typeBuf = React22.useRef({ s: "", t: 0 });
3552
+ const [open, setOpen] = React23.useState(false);
3553
+ const [q, setQ] = React23.useState("");
3554
+ const [active, setActive] = React23.useState(-1);
3555
+ const rootRef = React23.useRef(null);
3556
+ const boxRef = React23.useRef(null);
3557
+ const listRef = React23.useRef(null);
3558
+ const typeBuf = React23.useRef({ s: "", t: 0 });
3543
3559
  const selected = multiple ? null : opts.find((o) => o.value === value);
3544
3560
  const chosen = multiple ? opts.filter((o) => vals.includes(o.value)) : [];
3545
3561
  const boxText = multiple ? chosen.length === 0 ? placeholder : chosen.length === 1 ? chosen[0].label : summary ? summary(chosen.map((o) => o.value)) : chosen.length + " selected" : selected ? selected.label : placeholder;
@@ -3564,7 +3580,7 @@ function Select({
3564
3580
  }
3565
3581
  setOpen(!open);
3566
3582
  };
3567
- React22.useEffect(() => {
3583
+ React23.useEffect(() => {
3568
3584
  if (!open || active < 0 || !listRef.current) return;
3569
3585
  const el = listRef.current.querySelector('[data-i="' + active + '"]');
3570
3586
  if (el) {
@@ -3617,10 +3633,10 @@ function Select({
3617
3633
  else last.items.push({ o, i });
3618
3634
  });
3619
3635
  const box = ["fd-input", "fd-select", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" ");
3620
- return /* @__PURE__ */ jsxs44("div", { className: ["fd-field", "fd-popfield", open ? "is-open" : "", className].filter(Boolean).join(" "), style, ref: rootRef, children: [
3636
+ return /* @__PURE__ */ jsxs45("div", { className: ["fd-field", "fd-popfield", open ? "is-open" : "", className].filter(Boolean).join(" "), style, ref: rootRef, children: [
3621
3637
  label ? /* @__PURE__ */ jsx49(FieldLabel, { id: labelId, required, onClick: toggle, children: label }) : null,
3622
- /* @__PURE__ */ jsxs44("div", { className: box, style: { cursor: disabled ? "not-allowed" : "pointer" }, ref: boxRef, children: [
3623
- /* @__PURE__ */ jsxs44(
3638
+ /* @__PURE__ */ jsxs45("div", { className: box, style: { cursor: disabled ? "not-allowed" : "pointer" }, ref: boxRef, children: [
3639
+ /* @__PURE__ */ jsxs45(
3624
3640
  "button",
3625
3641
  {
3626
3642
  type: "button",
@@ -3668,7 +3684,7 @@ function Select({
3668
3684
  minWidth: 260,
3669
3685
  role: "presentation",
3670
3686
  style: { maxWidth: 380 },
3671
- header: hasSearch ? /* @__PURE__ */ jsxs44("div", { className: "fd-pop-search", children: [
3687
+ header: hasSearch ? /* @__PURE__ */ jsxs45("div", { className: "fd-pop-search", children: [
3672
3688
  /* @__PURE__ */ jsx49("i", { className: "ph ph-magnifying-glass", style: { color: "var(--text-muted)", fontSize: 14 } }),
3673
3689
  /* @__PURE__ */ jsx49(
3674
3690
  "input",
@@ -3685,7 +3701,7 @@ function Select({
3685
3701
  ),
3686
3702
  q ? /* @__PURE__ */ jsx49("span", { className: "fd-body-sm fd-muted", children: visible.length }) : null
3687
3703
  ] }) : void 0,
3688
- footer: multiple ? /* @__PURE__ */ jsxs44(React22.Fragment, { children: [
3704
+ footer: multiple ? /* @__PURE__ */ jsxs45(React23.Fragment, { children: [
3689
3705
  /* @__PURE__ */ jsx49(
3690
3706
  "button",
3691
3707
  {
@@ -3696,7 +3712,7 @@ function Select({
3696
3712
  }
3697
3713
  ),
3698
3714
  /* @__PURE__ */ jsx49("span", { style: { flex: 1 } }),
3699
- /* @__PURE__ */ jsxs44("span", { className: "fd-body-sm fd-muted", children: [
3715
+ /* @__PURE__ */ jsxs45("span", { className: "fd-body-sm fd-muted", children: [
3700
3716
  vals.length,
3701
3717
  " of ",
3702
3718
  opts.length
@@ -3712,13 +3728,13 @@ function Select({
3712
3728
  }
3713
3729
  )
3714
3730
  ] }) : void 0,
3715
- children: /* @__PURE__ */ jsx49("div", { className: "fd-pop-list", role: "listbox", "aria-multiselectable": multiple || void 0, ref: listRef, children: visible.length === 0 ? /* @__PURE__ */ jsxs44("div", { className: "fd-pop-empty", children: [
3731
+ children: /* @__PURE__ */ jsx49("div", { className: "fd-pop-list", role: "listbox", "aria-multiselectable": multiple || void 0, ref: listRef, children: visible.length === 0 ? /* @__PURE__ */ jsxs45("div", { className: "fd-pop-empty", children: [
3716
3732
  'Nothing matches "',
3717
3733
  q,
3718
3734
  '".'
3719
- ] }) : groups.map((grp) => /* @__PURE__ */ jsxs44(React22.Fragment, { children: [
3735
+ ] }) : groups.map((grp) => /* @__PURE__ */ jsxs45(React23.Fragment, { children: [
3720
3736
  grp.g ? /* @__PURE__ */ jsx49("div", { className: "fd-pop-group", children: grp.g }) : null,
3721
- grp.items.map(({ o, i }) => /* @__PURE__ */ jsxs44(
3737
+ grp.items.map(({ o, i }) => /* @__PURE__ */ jsxs45(
3722
3738
  "button",
3723
3739
  {
3724
3740
  type: "button",
@@ -3732,7 +3748,7 @@ function Select({
3732
3748
  children: [
3733
3749
  multiple ? /* @__PURE__ */ jsx49("span", { "aria-hidden": "true", style: { flex: "none", display: "grid", placeItems: "center", width: 16, height: 16, borderRadius: 4, border: "1.5px solid " + (isOn(o.value) ? "var(--brand)" : "var(--border-strong, var(--border))"), background: isOn(o.value) ? "var(--brand)" : "var(--surface)", color: "#fff" }, children: isOn(o.value) ? /* @__PURE__ */ jsx49("i", { className: "ph ph-check", style: { fontSize: 11 } }) : null }) : null,
3734
3750
  o.icon ? /* @__PURE__ */ jsx49("span", { className: "fd-opt-icon", children: /* @__PURE__ */ jsx49("i", { className: "ph ph-" + o.icon }) }) : null,
3735
- /* @__PURE__ */ jsxs44("span", { style: { flex: 1, minWidth: 0 }, children: [
3751
+ /* @__PURE__ */ jsxs45("span", { style: { flex: 1, minWidth: 0 }, children: [
3736
3752
  /* @__PURE__ */ jsx49("span", { className: "fd-opt-label", children: o.label }),
3737
3753
  o.description ? /* @__PURE__ */ jsx49("span", { className: "fd-opt-desc", children: o.description }) : null
3738
3754
  ] }),
@@ -3745,7 +3761,7 @@ function Select({
3745
3761
  ] }, grp.g || "_")) })
3746
3762
  }
3747
3763
  ),
3748
- error ? /* @__PURE__ */ jsxs44("span", { className: "fd-field-error", children: [
3764
+ error ? /* @__PURE__ */ jsxs45("span", { className: "fd-field-error", children: [
3749
3765
  /* @__PURE__ */ jsx49("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
3750
3766
  error
3751
3767
  ] }) : help ? /* @__PURE__ */ jsx49("span", { className: "fd-field-help", children: help }) : null
@@ -3753,8 +3769,8 @@ function Select({
3753
3769
  }
3754
3770
 
3755
3771
  // src/components/forms/DatePicker.tsx
3756
- import * as React23 from "react";
3757
- import { jsx as jsx50, jsxs as jsxs45 } from "react/jsx-runtime";
3772
+ import * as React24 from "react";
3773
+ import { jsx as jsx50, jsxs as jsxs46 } from "react/jsx-runtime";
3758
3774
  var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
3759
3775
  var DOW = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
3760
3776
  var iso = (d) => d.getFullYear() + "-" + String(d.getMonth() + 1).padStart(2, "0") + "-" + String(d.getDate()).padStart(2, "0");
@@ -3771,10 +3787,10 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3771
3787
  const today = /* @__PURE__ */ new Date();
3772
3788
  const sel = range ? value || {} : { start: value, end: value };
3773
3789
  const anchor = parse(sel.start) || parse(initialMonth) || today;
3774
- const [vy, setVy] = React23.useState(anchor.getFullYear());
3775
- const [vm, setVm] = React23.useState(anchor.getMonth());
3776
- const [mode2, setMode] = React23.useState("days");
3777
- const [hover, setHover] = React23.useState(null);
3790
+ const [vy, setVy] = React24.useState(anchor.getFullYear());
3791
+ const [vm, setVm] = React24.useState(anchor.getMonth());
3792
+ const [mode2, setMode] = React24.useState("days");
3793
+ const [hover, setHover] = React24.useState(null);
3778
3794
  const s = parse(sel.start), e = parse(sel.end);
3779
3795
  const hoverEnd = range && s && !e && hover ? parse(hover) : null;
3780
3796
  const inRange = (d) => {
@@ -3811,7 +3827,7 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3811
3827
  const startPad = new Date(y, m, 1).getDay();
3812
3828
  const cells = [];
3813
3829
  for (let i = 0; i < 42; i++) cells.push(new Date(y, m, i - startPad + 1));
3814
- return /* @__PURE__ */ jsxs45("div", { className: "fd-cal-grid", style: { width: months > 1 ? 252 : "auto", flex: "none" }, onMouseLeave: () => setHover(null), children: [
3830
+ return /* @__PURE__ */ jsxs46("div", { className: "fd-cal-grid", style: { width: months > 1 ? 252 : "auto", flex: "none" }, onMouseLeave: () => setHover(null), children: [
3815
3831
  DOW.map((d) => /* @__PURE__ */ jsx50("span", { className: "fd-cal-dow", children: d }, d)),
3816
3832
  cells.map((d, i) => /* @__PURE__ */ jsx50(
3817
3833
  "button",
@@ -3827,17 +3843,17 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3827
3843
  ] });
3828
3844
  };
3829
3845
  const nextY = vm === 11 ? vy + 1 : vy, nextM = (vm + 1) % 12;
3830
- return /* @__PURE__ */ jsxs45("div", { className: "fd-cal", style: { width: months > 1 && mode2 === "days" ? "auto" : void 0 }, children: [
3831
- /* @__PURE__ */ jsxs45("div", { className: "fd-cal-head", children: [
3846
+ return /* @__PURE__ */ jsxs46("div", { className: "fd-cal", style: { width: months > 1 && mode2 === "days" ? "auto" : void 0 }, children: [
3847
+ /* @__PURE__ */ jsxs46("div", { className: "fd-cal-head", children: [
3832
3848
  /* @__PURE__ */ jsx50("button", { type: "button", className: "fd-btn-icon", "aria-label": "Previous", onClick: () => mode2 === "years" ? setVy(vy - 12) : mode2 === "months" ? setVy(vy - 1) : nav(-1), children: /* @__PURE__ */ jsx50("i", { className: "ph ph-caret-left" }) }),
3833
- /* @__PURE__ */ jsxs45("button", { type: "button", className: "fd-cal-title", onClick: () => setMode(mode2 === "days" ? "months" : mode2 === "months" ? "years" : "days"), children: [
3849
+ /* @__PURE__ */ jsxs46("button", { type: "button", className: "fd-cal-title", onClick: () => setMode(mode2 === "days" ? "months" : mode2 === "months" ? "years" : "days"), children: [
3834
3850
  mode2 === "days" ? MONTHS[vm] + " " + vy : mode2 === "months" ? vy : vy - 5 + " \u2013 " + (vy + 6),
3835
3851
  /* @__PURE__ */ jsx50("i", { className: "ph ph-caret-down", style: { fontSize: 10, marginLeft: 6, color: "var(--text-muted)" } })
3836
3852
  ] }),
3837
3853
  months > 1 && mode2 === "days" ? /* @__PURE__ */ jsx50("span", { className: "fd-cal-title", style: { cursor: "default", background: "none" }, children: MONTHS[nextM] + " " + nextY }) : null,
3838
3854
  /* @__PURE__ */ jsx50("button", { type: "button", className: "fd-btn-icon", "aria-label": "Next", onClick: () => mode2 === "years" ? setVy(vy + 12) : mode2 === "months" ? setVy(vy + 1) : nav(1), children: /* @__PURE__ */ jsx50("i", { className: "ph ph-caret-right" }) })
3839
3855
  ] }),
3840
- mode2 === "days" ? /* @__PURE__ */ jsxs45("div", { style: { display: "flex", gap: 18 }, children: [
3856
+ mode2 === "days" ? /* @__PURE__ */ jsxs46("div", { style: { display: "flex", gap: 18 }, children: [
3841
3857
  monthGrid(vy, vm),
3842
3858
  months > 1 ? monthGrid(nextY, nextM) : null
3843
3859
  ] }) : mode2 === "months" ? /* @__PURE__ */ jsx50("div", { className: "fd-cal-grid-months", children: MONTHS.map((m, i) => /* @__PURE__ */ jsx50(
@@ -3865,7 +3881,7 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3865
3881
  },
3866
3882
  y
3867
3883
  )) }),
3868
- /* @__PURE__ */ jsxs45("div", { className: "fd-cal-foot", children: [
3884
+ /* @__PURE__ */ jsxs46("div", { className: "fd-cal-foot", children: [
3869
3885
  /* @__PURE__ */ jsx50(
3870
3886
  "button",
3871
3887
  {
@@ -3881,7 +3897,7 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3881
3897
  }
3882
3898
  ),
3883
3899
  /* @__PURE__ */ jsx50("span", { style: { flex: 1 } }),
3884
- range && sel.start ? /* @__PURE__ */ jsxs45("span", { className: "fd-body-sm fd-muted", children: [
3900
+ range && sel.start ? /* @__PURE__ */ jsxs46("span", { className: "fd-body-sm fd-muted", children: [
3885
3901
  fmt(sel.start),
3886
3902
  sel.end ? " \u2192 " + fmt(sel.end) : " \u2192 pick an end"
3887
3903
  ] }) : null
@@ -3890,16 +3906,16 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3890
3906
  }
3891
3907
  function DatePicker({ label, help, error, required = false, disabled = false, range = false, value, onChange, placeholder, id, className = "", style, ...rest }) {
3892
3908
  const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
3893
- const [open, setOpen] = React23.useState(false);
3894
- const rootRef = React23.useRef(null);
3895
- const boxRef = React23.useRef(null);
3909
+ const [open, setOpen] = React24.useState(false);
3910
+ const rootRef = React24.useRef(null);
3911
+ const boxRef = React24.useRef(null);
3896
3912
  const display = range ? value && value.start ? fmt(value.start) + (value.end ? " \u2192 " + fmt(value.end) : " \u2192 \u2026") : "" : fmt(value);
3897
3913
  const toggle = () => {
3898
3914
  if (!disabled) setOpen(!open);
3899
3915
  };
3900
- return /* @__PURE__ */ jsxs45("div", { className: ["fd-field", "fd-popfield", open ? "is-open" : "", className].filter(Boolean).join(" "), style, ref: rootRef, children: [
3916
+ return /* @__PURE__ */ jsxs46("div", { className: ["fd-field", "fd-popfield", open ? "is-open" : "", className].filter(Boolean).join(" "), style, ref: rootRef, children: [
3901
3917
  label ? /* @__PURE__ */ jsx50(FieldLabel, { id: labelId, required, onClick: toggle, children: label }) : null,
3902
- /* @__PURE__ */ jsxs45("div", { className: ["fd-input", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" "), style: { cursor: disabled ? "not-allowed" : "pointer" }, onClick: toggle, ref: boxRef, children: [
3918
+ /* @__PURE__ */ jsxs46("div", { className: ["fd-input", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" "), style: { cursor: disabled ? "not-allowed" : "pointer" }, onClick: toggle, ref: boxRef, children: [
3903
3919
  /* @__PURE__ */ jsx50("span", { className: "fd-input-icon", children: /* @__PURE__ */ jsx50("i", { className: "ph ph-calendar-blank", "aria-hidden": "true" }) }),
3904
3920
  /* @__PURE__ */ jsx50(
3905
3921
  "button",
@@ -3946,7 +3962,7 @@ function DatePicker({ label, help, error, required = false, disabled = false, ra
3946
3962
  )
3947
3963
  }
3948
3964
  ),
3949
- error ? /* @__PURE__ */ jsxs45("span", { className: "fd-field-error", children: [
3965
+ error ? /* @__PURE__ */ jsxs46("span", { className: "fd-field-error", children: [
3950
3966
  /* @__PURE__ */ jsx50("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
3951
3967
  error
3952
3968
  ] }) : help ? /* @__PURE__ */ jsx50("span", { className: "fd-field-help", children: help }) : null
@@ -3954,8 +3970,8 @@ function DatePicker({ label, help, error, required = false, disabled = false, ra
3954
3970
  }
3955
3971
 
3956
3972
  // src/components/forms/TimePicker.tsx
3957
- import * as React24 from "react";
3958
- import { jsx as jsx51, jsxs as jsxs46 } from "react/jsx-runtime";
3973
+ import * as React25 from "react";
3974
+ import { jsx as jsx51, jsxs as jsxs47 } from "react/jsx-runtime";
3959
3975
  var pad = (n) => String(n).padStart(2, "0");
3960
3976
  function ClockFace({ value = "09:00", onChange }) {
3961
3977
  let [h24, m] = value.split(":").map(Number);
@@ -3963,9 +3979,9 @@ function ClockFace({ value = "09:00", onChange }) {
3963
3979
  if (isNaN(m)) m = 0;
3964
3980
  const pm = h24 >= 12;
3965
3981
  const h12 = h24 % 12 === 0 ? 12 : h24 % 12;
3966
- const [mode2, setMode] = React24.useState("h");
3967
- const faceRef = React24.useRef(null);
3968
- const dragging = React24.useRef(false);
3982
+ const [mode2, setMode] = React25.useState("h");
3983
+ const faceRef = React25.useRef(null);
3984
+ const dragging = React25.useRef(false);
3969
3985
  const set = (h, mm, isPm) => onChange((isPm ? h % 12 + 12 : h % 12) + ":" + pad(mm));
3970
3986
  const R = 108, NR = 80;
3971
3987
  const nums = mode2 === "h" ? Array.from({ length: 12 }, (_, i) => i + 1) : Array.from({ length: 12 }, (_, i) => i * 5);
@@ -4000,8 +4016,8 @@ function ClockFace({ value = "09:00", onChange }) {
4000
4016
  };
4001
4017
  const handAngle = mode2 === "h" ? h12 % 12 * 30 : m * 6;
4002
4018
  const minuteOff = mode2 === "m" && m % 5 !== 0;
4003
- return /* @__PURE__ */ jsxs46("div", { style: { padding: "4px 14px 14px" }, children: [
4004
- /* @__PURE__ */ jsxs46("div", { className: "fd-clock-digits", children: [
4019
+ return /* @__PURE__ */ jsxs47("div", { style: { padding: "4px 14px 14px" }, children: [
4020
+ /* @__PURE__ */ jsxs47("div", { className: "fd-clock-digits", children: [
4005
4021
  /* @__PURE__ */ jsx51("button", { type: "button", className: "fd-clock-digit" + (mode2 === "h" ? " is-active" : ""), onClick: () => setMode("h"), children: pad(h12) }),
4006
4022
  /* @__PURE__ */ jsx51("span", { style: { fontSize: 24, fontWeight: 700, color: "var(--text-muted)" }, children: ":" }),
4007
4023
  /* @__PURE__ */ jsx51("button", { type: "button", className: "fd-clock-digit" + (mode2 === "m" ? " is-active" : ""), onClick: () => setMode("m"), children: pad(m) }),
@@ -4016,7 +4032,7 @@ function ClockFace({ value = "09:00", onChange }) {
4016
4032
  ap
4017
4033
  )) })
4018
4034
  ] }),
4019
- /* @__PURE__ */ jsxs46("div", { className: "fd-clock", ref: faceRef, onPointerDown: down, onPointerMove: move, onPointerUp: upH, children: [
4035
+ /* @__PURE__ */ jsxs47("div", { className: "fd-clock", ref: faceRef, onPointerDown: down, onPointerMove: move, onPointerUp: upH, children: [
4020
4036
  /* @__PURE__ */ jsx51("span", { className: "fd-clock-hand", style: { height: NR - (minuteOff ? 14 : 16), transform: "translateX(-50%) rotate(" + handAngle + "deg)", bottom: "50%" } }),
4021
4037
  /* @__PURE__ */ jsx51("span", { className: "fd-clock-pivot" }),
4022
4038
  minuteOff ? /* @__PURE__ */ jsx51("span", { style: { position: "absolute", left: "50%", top: "50%", width: 10, height: 10, margin: -5, borderRadius: "50%", border: "2px solid var(--brand)", background: "var(--surface)", transform: "rotate(" + handAngle + "deg) translateY(-" + (NR - 6) + "px)", transformOrigin: "center", pointerEvents: "none" } }) : null,
@@ -4038,9 +4054,9 @@ function ClockFace({ value = "09:00", onChange }) {
4038
4054
  }
4039
4055
  function TimePicker({ label, help, error, required = false, disabled = false, value = "", onChange, placeholder = "Pick a time", id, className = "", style }) {
4040
4056
  const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
4041
- const [open, setOpen] = React24.useState(false);
4042
- const rootRef = React24.useRef(null);
4043
- const boxRef = React24.useRef(null);
4057
+ const [open, setOpen] = React25.useState(false);
4058
+ const rootRef = React25.useRef(null);
4059
+ const boxRef = React25.useRef(null);
4044
4060
  const disp = () => {
4045
4061
  if (!value) return "";
4046
4062
  const [h, m] = value.split(":").map(Number);
@@ -4049,9 +4065,9 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
4049
4065
  const toggle = () => {
4050
4066
  if (!disabled) setOpen(!open);
4051
4067
  };
4052
- return /* @__PURE__ */ jsxs46("div", { className: ["fd-field", "fd-popfield", open ? "is-open" : "", className].filter(Boolean).join(" "), style, ref: rootRef, children: [
4068
+ return /* @__PURE__ */ jsxs47("div", { className: ["fd-field", "fd-popfield", open ? "is-open" : "", className].filter(Boolean).join(" "), style, ref: rootRef, children: [
4053
4069
  label ? /* @__PURE__ */ jsx51(FieldLabel, { id: labelId, required, onClick: toggle, children: label }) : null,
4054
- /* @__PURE__ */ jsxs46("div", { className: ["fd-input", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" "), style: { cursor: disabled ? "not-allowed" : "pointer" }, onClick: toggle, ref: boxRef, children: [
4070
+ /* @__PURE__ */ jsxs47("div", { className: ["fd-input", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" "), style: { cursor: disabled ? "not-allowed" : "pointer" }, onClick: toggle, ref: boxRef, children: [
4055
4071
  /* @__PURE__ */ jsx51("span", { className: "fd-input-icon", children: /* @__PURE__ */ jsx51("i", { className: "ph ph-clock", "aria-hidden": "true" }) }),
4056
4072
  /* @__PURE__ */ jsx51(
4057
4073
  "button",
@@ -4083,7 +4099,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
4083
4099
  offset: 6,
4084
4100
  width: 262,
4085
4101
  role: "presentation",
4086
- footer: /* @__PURE__ */ jsxs46(React24.Fragment, { children: [
4102
+ footer: /* @__PURE__ */ jsxs47(React25.Fragment, { children: [
4087
4103
  /* @__PURE__ */ jsx51(
4088
4104
  "button",
4089
4105
  {
@@ -4103,7 +4119,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
4103
4119
  children: /* @__PURE__ */ jsx51(ClockFace, { value: value || "09:00", onChange: (v) => onChange && onChange({ target: { value: v } }) })
4104
4120
  }
4105
4121
  ),
4106
- error ? /* @__PURE__ */ jsxs46("span", { className: "fd-field-error", children: [
4122
+ error ? /* @__PURE__ */ jsxs47("span", { className: "fd-field-error", children: [
4107
4123
  /* @__PURE__ */ jsx51("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
4108
4124
  error
4109
4125
  ] }) : help ? /* @__PURE__ */ jsx51("span", { className: "fd-field-help", children: help }) : null
@@ -4111,8 +4127,8 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
4111
4127
  }
4112
4128
 
4113
4129
  // src/components/forms/Slider.tsx
4114
- import * as React25 from "react";
4115
- import { jsx as jsx52, jsxs as jsxs47 } from "react/jsx-runtime";
4130
+ import * as React26 from "react";
4131
+ import { jsx as jsx52, jsxs as jsxs48 } from "react/jsx-runtime";
4116
4132
  function Slider({
4117
4133
  label,
4118
4134
  min = 0,
@@ -4129,15 +4145,15 @@ function Slider({
4129
4145
  ...rest
4130
4146
  }) {
4131
4147
  const fieldId = useFieldId(id);
4132
- const [dragging, setDragging] = React25.useState(false);
4148
+ const [dragging, setDragging] = React26.useState(false);
4133
4149
  const v = value === void 0 ? min : Number(value);
4134
4150
  const pct = max === min ? 0 : (v - min) / (max - min) * 100;
4135
- return /* @__PURE__ */ jsxs47("div", { className: ["fd-field", className].filter(Boolean).join(" "), children: [
4136
- label ? /* @__PURE__ */ jsxs47("div", { className: "fd-row", style: { justifyContent: "space-between", gap: 12 }, children: [
4151
+ return /* @__PURE__ */ jsxs48("div", { className: ["fd-field", className].filter(Boolean).join(" "), children: [
4152
+ label ? /* @__PURE__ */ jsxs48("div", { className: "fd-row", style: { justifyContent: "space-between", gap: 12 }, children: [
4137
4153
  /* @__PURE__ */ jsx52(FieldLabel, { htmlFor: fieldId, children: label }),
4138
4154
  /* @__PURE__ */ jsx52("span", { className: "fd-num", style: { color: "var(--text-2)" }, children: format(v) })
4139
4155
  ] }) : null,
4140
- /* @__PURE__ */ jsxs47("div", { className: "fd-slider", children: [
4156
+ /* @__PURE__ */ jsxs48("div", { className: "fd-slider", children: [
4141
4157
  /* @__PURE__ */ jsx52("span", { className: "fd-slider-fill", style: { width: pct + "%" } }),
4142
4158
  showChip && dragging ? /* @__PURE__ */ jsx52("span", { className: "fd-slider-chip", style: { left: pct + "%" }, children: format(v) }) : null,
4143
4159
  /* @__PURE__ */ jsx52(
@@ -4163,8 +4179,8 @@ function Slider({
4163
4179
  }
4164
4180
 
4165
4181
  // src/components/forms/RangeSlider.tsx
4166
- import * as React26 from "react";
4167
- import { jsx as jsx53, jsxs as jsxs48 } from "react/jsx-runtime";
4182
+ import * as React27 from "react";
4183
+ import { jsx as jsx53, jsxs as jsxs49 } from "react/jsx-runtime";
4168
4184
  function RangeSlider({
4169
4185
  label,
4170
4186
  min = 0,
@@ -4183,9 +4199,9 @@ function RangeSlider({
4183
4199
  }) {
4184
4200
  const fmt2 = format || ((v) => String(v));
4185
4201
  const [a, b] = value || [min, max];
4186
- const [drag, setDrag] = React26.useState(null);
4187
- const [focus, setFocus] = React26.useState(null);
4188
- const railRef = React26.useRef(null);
4202
+ const [drag, setDrag] = React27.useState(null);
4203
+ const [focus, setFocus] = React27.useState(null);
4204
+ const railRef = React27.useRef(null);
4189
4205
  const pct = (v) => max === min ? 0 : (v - min) / (max - min) * 100;
4190
4206
  const clampPair = (i, v) => {
4191
4207
  v = Math.min(max, Math.max(min, Math.round(v / step) * step));
@@ -4200,7 +4216,7 @@ function RangeSlider({
4200
4216
  const r = railRef.current.getBoundingClientRect();
4201
4217
  return min + Math.min(1, Math.max(0, (e.clientX - r.left) / r.width)) * (max - min);
4202
4218
  };
4203
- React26.useEffect(() => {
4219
+ React27.useEffect(() => {
4204
4220
  if (drag === null) return;
4205
4221
  const mv = (e) => onChange && onChange(clampPair(drag, fromEvent(e)));
4206
4222
  const upH = () => setDrag(null);
@@ -4269,19 +4285,19 @@ function RangeSlider({
4269
4285
  };
4270
4286
  const showChip = (i) => drag === i || focus === i;
4271
4287
  const hasLabels = marks.some((m) => m.label);
4272
- return /* @__PURE__ */ jsxs48("div", { className: ["fd-field", className].filter(Boolean).join(" "), ...rest, children: [
4273
- label ? /* @__PURE__ */ jsxs48("div", { className: "fd-row", style: { justifyContent: "space-between", gap: 12 }, children: [
4288
+ return /* @__PURE__ */ jsxs49("div", { className: ["fd-field", className].filter(Boolean).join(" "), ...rest, children: [
4289
+ label ? /* @__PURE__ */ jsxs49("div", { className: "fd-row", style: { justifyContent: "space-between", gap: 12 }, children: [
4274
4290
  /* @__PURE__ */ jsx53("span", { className: "fd-field-label", children: label }),
4275
- /* @__PURE__ */ jsxs48("span", { className: "fd-num", style: { color: "var(--text-2)" }, children: [
4291
+ /* @__PURE__ */ jsxs49("span", { className: "fd-num", style: { color: "var(--text-2)" }, children: [
4276
4292
  fmt2(a),
4277
4293
  " \u2013 ",
4278
4294
  fmt2(b)
4279
4295
  ] })
4280
4296
  ] }) : null,
4281
- /* @__PURE__ */ jsxs48("div", { className: "fd-range" + (hasLabels ? " has-labels" : ""), onPointerDown: onRailDown, children: [
4297
+ /* @__PURE__ */ jsxs49("div", { className: "fd-range" + (hasLabels ? " has-labels" : ""), onPointerDown: onRailDown, children: [
4282
4298
  /* @__PURE__ */ jsx53("span", { className: "fd-range-rail", ref: railRef }),
4283
4299
  /* @__PURE__ */ jsx53("span", { className: "fd-range-fill", style: { left: pct(a) + "%", width: pct(b) - pct(a) + "%" } }),
4284
- marks.map((m) => /* @__PURE__ */ jsxs48(React26.Fragment, { children: [
4300
+ marks.map((m) => /* @__PURE__ */ jsxs49(React27.Fragment, { children: [
4285
4301
  /* @__PURE__ */ jsx53("span", { className: "fd-range-mark" + (m.value >= a && m.value <= b ? " is-in" : ""), style: { left: pct(m.value) + "%" } }),
4286
4302
  m.label ? /* @__PURE__ */ jsx53("span", { className: "fd-range-mark-label", style: { left: pct(m.value) + "%" }, children: m.label }) : null
4287
4303
  ] }, m.value)),
@@ -4310,8 +4326,8 @@ function RangeSlider({
4310
4326
  }
4311
4327
 
4312
4328
  // src/components/forms/Dropzone.tsx
4313
- import * as React27 from "react";
4314
- import { jsx as jsx54, jsxs as jsxs49 } from "react/jsx-runtime";
4329
+ import * as React28 from "react";
4330
+ import { jsx as jsx54, jsxs as jsxs50 } from "react/jsx-runtime";
4315
4331
  function Dropzone({
4316
4332
  onFiles,
4317
4333
  onReject,
@@ -4325,8 +4341,8 @@ function Dropzone({
4325
4341
  className = "",
4326
4342
  style
4327
4343
  }) {
4328
- const [over, setOver] = React27.useState(false);
4329
- const depth = React27.useRef(0);
4344
+ const [over, setOver] = React28.useState(false);
4345
+ const depth = React28.useRef(0);
4330
4346
  const has = (e) => {
4331
4347
  const dt = e.dataTransfer;
4332
4348
  if (!dt) return false;
@@ -4356,7 +4372,7 @@ function Dropzone({
4356
4372
  if (rejected.length && onReject) onReject(rejected);
4357
4373
  if (accepted.length && onFiles) onFiles(accepted);
4358
4374
  };
4359
- return /* @__PURE__ */ jsxs49(
4375
+ return /* @__PURE__ */ jsxs50(
4360
4376
  "div",
4361
4377
  {
4362
4378
  className: ["fd-dropzone", over ? "is-over" : "", className].filter(Boolean).join(" "),
@@ -4367,7 +4383,7 @@ function Dropzone({
4367
4383
  onDrop: drop,
4368
4384
  children: [
4369
4385
  children,
4370
- over ? /* @__PURE__ */ jsx54("div", { className: "fd-dropzone-veil", "aria-hidden": "true", children: /* @__PURE__ */ jsxs49("div", { className: "fd-dropzone-card", children: [
4386
+ over ? /* @__PURE__ */ jsx54("div", { className: "fd-dropzone-veil", "aria-hidden": "true", children: /* @__PURE__ */ jsxs50("div", { className: "fd-dropzone-card", children: [
4371
4387
  /* @__PURE__ */ jsx54("i", { className: "ph ph-tray-arrow-down" }),
4372
4388
  /* @__PURE__ */ jsx54("span", { className: "fd-dropzone-label", children: label }),
4373
4389
  hint ? /* @__PURE__ */ jsx54("span", { className: "fd-dropzone-hint", children: hint }) : null
@@ -4388,8 +4404,8 @@ function FilePickButton({
4388
4404
  className = "",
4389
4405
  children
4390
4406
  }) {
4391
- const ref = React27.useRef(null);
4392
- return /* @__PURE__ */ jsxs49(React27.Fragment, { children: [
4407
+ const ref = React28.useRef(null);
4408
+ return /* @__PURE__ */ jsxs50(React28.Fragment, { children: [
4393
4409
  /* @__PURE__ */ jsx54(
4394
4410
  "button",
4395
4411
  {
@@ -4422,10 +4438,10 @@ function FilePickButton({
4422
4438
  }
4423
4439
  function useStagedFiles(upload, opts) {
4424
4440
  const o = opts || {};
4425
- const [items, setItems] = React27.useState([]);
4426
- const controllers = React27.useRef({});
4441
+ const [items, setItems] = React28.useState([]);
4442
+ const controllers = React28.useRef({});
4427
4443
  const patch = (id, next) => setItems((list) => list.map((f) => f.id === id ? Object.assign({}, f, next) : f));
4428
- const run = React27.useCallback((att) => {
4444
+ const run = React28.useCallback((att) => {
4429
4445
  if (!upload) return;
4430
4446
  const ac = typeof AbortController !== "undefined" ? new AbortController() : null;
4431
4447
  controllers.current[att.id] = ac;
@@ -4442,14 +4458,14 @@ function useStagedFiles(upload, opts) {
4442
4458
  delete controllers.current[att.id];
4443
4459
  });
4444
4460
  }, [upload]);
4445
- const add = React27.useCallback((files) => {
4461
+ const add = React28.useCallback((files) => {
4446
4462
  if (!upload) return [];
4447
4463
  const atts = Array.from(files).map((f) => toAttachment(f));
4448
4464
  setItems((list) => list.concat(atts));
4449
4465
  atts.forEach(run);
4450
4466
  return atts;
4451
4467
  }, [upload, run]);
4452
- const remove = React27.useCallback((att) => {
4468
+ const remove = React28.useCallback((att) => {
4453
4469
  const ac = controllers.current[att.id];
4454
4470
  if (ac) {
4455
4471
  try {
@@ -4460,10 +4476,10 @@ function useStagedFiles(upload, opts) {
4460
4476
  }
4461
4477
  setItems((list) => list.filter((f) => f.id !== att.id));
4462
4478
  }, []);
4463
- const retry = React27.useCallback((att) => {
4479
+ const retry = React28.useCallback((att) => {
4464
4480
  run(att);
4465
4481
  }, [run]);
4466
- const clear = React27.useCallback(() => {
4482
+ const clear = React28.useCallback(() => {
4467
4483
  Object.values(controllers.current).forEach((ac) => {
4468
4484
  try {
4469
4485
  ac && ac.abort();
@@ -4479,7 +4495,7 @@ function useStagedFiles(upload, opts) {
4479
4495
  var DropzoneKit = { useStagedFiles };
4480
4496
 
4481
4497
  // src/components/forms/FileGrid.tsx
4482
- import { jsx as jsx55, jsxs as jsxs50 } from "react/jsx-runtime";
4498
+ import { jsx as jsx55, jsxs as jsxs51 } from "react/jsx-runtime";
4483
4499
  var truncateMiddle = (name, max = 34) => {
4484
4500
  if (!name || name.length <= max) return name;
4485
4501
  const ext = /\.[A-Za-z0-9]+$/.exec(name);
@@ -4497,8 +4513,8 @@ function FileChip({ file, onOpen, onRemove, onRetry, compact: compact3 = false,
4497
4513
  const thumb = file.thumb && file.thumb.url || (image ? file.blobUrl || file.url : null);
4498
4514
  const meta = file.meta || (file.size ? formatBytes(file.size) : "");
4499
4515
  const clickable = !!onOpen && !uploading;
4500
- return /* @__PURE__ */ jsxs50("div", { className: ["fd-file", compact3 ? "is-compact" : "", file.error ? "is-error" : "", uploading ? "is-uploading" : "", className].filter(Boolean).join(" "), children: [
4501
- /* @__PURE__ */ jsxs50(
4516
+ return /* @__PURE__ */ jsxs51("div", { className: ["fd-file", compact3 ? "is-compact" : "", file.error ? "is-error" : "", uploading ? "is-uploading" : "", className].filter(Boolean).join(" "), children: [
4517
+ /* @__PURE__ */ jsxs51(
4502
4518
  "button",
4503
4519
  {
4504
4520
  type: "button",
@@ -4507,16 +4523,16 @@ function FileChip({ file, onOpen, onRemove, onRetry, compact: compact3 = false,
4507
4523
  onClick: clickable ? () => onOpen(file) : void 0,
4508
4524
  title: file.name + (meta ? " \xB7 " + meta : ""),
4509
4525
  children: [
4510
- /* @__PURE__ */ jsxs50("span", { className: "fd-file-icon", children: [
4526
+ /* @__PURE__ */ jsxs51("span", { className: "fd-file-icon", children: [
4511
4527
  thumb ? /* @__PURE__ */ jsx55("img", { src: thumb, alt: "" }) : /* @__PURE__ */ jsx55("i", { className: "ph ph-" + iconForMime(file.mime, file.name), "aria-hidden": "true" }),
4512
4528
  (file.mime || "").startsWith("video/") ? /* @__PURE__ */ jsx55("i", { className: "ph ph-play fd-file-play", "aria-hidden": "true" }) : null
4513
4529
  ] }),
4514
- /* @__PURE__ */ jsxs50("span", { className: "fd-file-text", children: [
4530
+ /* @__PURE__ */ jsxs51("span", { className: "fd-file-text", children: [
4515
4531
  /* @__PURE__ */ jsx55("span", { className: "fd-file-name", children: truncateMiddle(file.name, compact3 ? 26 : 40) }),
4516
- /* @__PURE__ */ jsx55("span", { className: "fd-file-meta", children: file.error ? /* @__PURE__ */ jsxs50("span", { className: "fd-file-err", children: [
4532
+ /* @__PURE__ */ jsx55("span", { className: "fd-file-meta", children: file.error ? /* @__PURE__ */ jsxs51("span", { className: "fd-file-err", children: [
4517
4533
  /* @__PURE__ */ jsx55("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
4518
4534
  file.error
4519
- ] }) : uploading ? /* @__PURE__ */ jsxs50("span", { className: "fd-tabular", children: [
4535
+ ] }) : uploading ? /* @__PURE__ */ jsxs51("span", { className: "fd-tabular", children: [
4520
4536
  Math.round(file.progress),
4521
4537
  "% uploaded"
4522
4538
  ] }) : meta })
@@ -4533,10 +4549,10 @@ function FileTile({ file, onOpen, onRemove, maxHeight = 200, className = "" }) {
4533
4549
  if (!file) return null;
4534
4550
  const src = file.thumb && file.thumb.url || file.blobUrl || file.url;
4535
4551
  const uploading = file.progress != null && file.progress < 100 && !file.error;
4536
- return /* @__PURE__ */ jsxs50("figure", { className: ["fd-tile", uploading ? "is-uploading" : "", file.error ? "is-error" : "", className].filter(Boolean).join(" "), children: [
4552
+ return /* @__PURE__ */ jsxs51("figure", { className: ["fd-tile", uploading ? "is-uploading" : "", file.error ? "is-error" : "", className].filter(Boolean).join(" "), children: [
4537
4553
  /* @__PURE__ */ jsx55("button", { type: "button", className: "fd-tile-btn", onClick: onOpen ? () => onOpen(file) : void 0, disabled: !onOpen, children: src ? /* @__PURE__ */ jsx55("img", { src, alt: file.name || "", style: { maxHeight }, loading: "lazy" }) : /* @__PURE__ */ jsx55("span", { className: "fd-tile-fallback", children: /* @__PURE__ */ jsx55("i", { className: "ph ph-" + iconForMime(file.mime, file.name), "aria-hidden": "true" }) }) }),
4538
4554
  uploading ? /* @__PURE__ */ jsx55(Progress, { value: file.progress }) : null,
4539
- file.error ? /* @__PURE__ */ jsxs50("figcaption", { className: "fd-tile-err", children: [
4555
+ file.error ? /* @__PURE__ */ jsxs51("figcaption", { className: "fd-tile-err", children: [
4540
4556
  /* @__PURE__ */ jsx55("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
4541
4557
  file.error
4542
4558
  ] }) : null,
@@ -4560,9 +4576,9 @@ function FileCell({ file, onOpen, onRemove, onRetry }) {
4560
4576
  const image = isImage(file.mime, file.name);
4561
4577
  const thumb = file.thumb && file.thumb.url || (image ? file.blobUrl || file.url : null);
4562
4578
  const label = file.name + (file.size ? " \xB7 " + formatBytes(file.size) : "");
4563
- return /* @__PURE__ */ jsxs50("div", { className: ["fd-cell", file.error ? "is-error" : "", uploading ? "is-uploading" : ""].filter(Boolean).join(" "), title: file.error ? file.name + " \u2014 " + file.error : label, children: [
4564
- /* @__PURE__ */ jsxs50("button", { type: "button", className: "fd-cell-main", onClick: onOpen ? () => onOpen(file) : void 0, disabled: !onOpen || uploading, "aria-label": "Open " + file.name, children: [
4565
- thumb ? /* @__PURE__ */ jsx55("img", { src: thumb, alt: "" }) : /* @__PURE__ */ jsxs50("span", { className: "fd-cell-doc", children: [
4579
+ return /* @__PURE__ */ jsxs51("div", { className: ["fd-cell", file.error ? "is-error" : "", uploading ? "is-uploading" : ""].filter(Boolean).join(" "), title: file.error ? file.name + " \u2014 " + file.error : label, children: [
4580
+ /* @__PURE__ */ jsxs51("button", { type: "button", className: "fd-cell-main", onClick: onOpen ? () => onOpen(file) : void 0, disabled: !onOpen || uploading, "aria-label": "Open " + file.name, children: [
4581
+ thumb ? /* @__PURE__ */ jsx55("img", { src: thumb, alt: "" }) : /* @__PURE__ */ jsxs51("span", { className: "fd-cell-doc", children: [
4566
4582
  /* @__PURE__ */ jsx55("i", { className: "ph ph-" + iconForMime(file.mime, file.name), "aria-hidden": "true" }),
4567
4583
  /* @__PURE__ */ jsx55("span", { className: "fd-cell-name", children: shortName(file.name) }),
4568
4584
  /* @__PURE__ */ jsx55("span", { className: "fd-cell-size", children: file.meta || formatBytes(file.size) })
@@ -4580,15 +4596,15 @@ function FileGrid({ files = [], onOpen, onRemove, onRetry, tiles = true, maxHeig
4580
4596
  if (!list.length) return null;
4581
4597
  const pics = tiles ? list.filter((f) => isImage(f.mime, f.name)) : [];
4582
4598
  const rest = list.filter((f) => pics.indexOf(f) === -1);
4583
- return /* @__PURE__ */ jsxs50("div", { className: ["fd-filegrid", className].filter(Boolean).join(" "), children: [
4599
+ return /* @__PURE__ */ jsxs51("div", { className: ["fd-filegrid", className].filter(Boolean).join(" "), children: [
4584
4600
  pics.length ? /* @__PURE__ */ jsx55("div", { className: "fd-filegrid-tiles", children: pics.map((f) => /* @__PURE__ */ jsx55(FileTile, { file: f, onOpen, onRemove, maxHeight }, f.id || f.name)) }) : null,
4585
4601
  rest.length ? /* @__PURE__ */ jsx55("div", { className: "fd-filegrid-chips", children: rest.map((f) => /* @__PURE__ */ jsx55(FileChip, { file: f, onOpen, onRemove, onRetry, compact: compact3 }, f.id || f.name)) }) : null
4586
4602
  ] });
4587
4603
  }
4588
4604
 
4589
4605
  // src/components/forms/MarkdownEditor.tsx
4590
- import * as React28 from "react";
4591
- import { jsx as jsx56, jsxs as jsxs51 } from "react/jsx-runtime";
4606
+ import * as React29 from "react";
4607
+ import { jsx as jsx56, jsxs as jsxs52 } from "react/jsx-runtime";
4592
4608
  var isMac = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent || "");
4593
4609
  var INLINE_RE = /(\*\*\*[^*\n]+\*\*\*|\*\*[^*\n]+\*\*|__[^_\n]+__|~~[^~\n]+~~|`[^`\n]+`|\*[^*\s][^*\n]*\*|(?<![A-Za-z0-9_])_[^_\s][^_\n]*_|\[[^\]\n]*\]\([^)\s\n]*\)|https?:\/\/\S+)/g;
4594
4610
  function inlineParts(text) {
@@ -4801,7 +4817,7 @@ function syncDom(root, value) {
4801
4817
  while (root.children.length > lines.length) root.removeChild(root.lastChild);
4802
4818
  }
4803
4819
  var LIST_CONT = RE_LI;
4804
- var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
4820
+ var MarkdownEditor = React29.forwardRef(function MarkdownEditor2({
4805
4821
  value = "",
4806
4822
  onChange,
4807
4823
  onSubmit,
@@ -4820,10 +4836,10 @@ var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
4820
4836
  className = "",
4821
4837
  id
4822
4838
  }, ref) {
4823
- const boxRef = React28.useRef(null);
4824
- const composing = React28.useRef(false);
4825
- const pendingCaret = React28.useRef(null);
4826
- React28.useLayoutEffect(() => {
4839
+ const boxRef = React29.useRef(null);
4840
+ const composing = React29.useRef(false);
4841
+ const pendingCaret = React29.useRef(null);
4842
+ React29.useLayoutEffect(() => {
4827
4843
  const root = boxRef.current;
4828
4844
  if (!root || composing.current) return;
4829
4845
  const active = document.activeElement === root || root.contains(document.activeElement);
@@ -4832,7 +4848,7 @@ var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
4832
4848
  pendingCaret.current = null;
4833
4849
  if (active && caret != null) placeCaret(root, caret);
4834
4850
  }, [value]);
4835
- React28.useEffect(() => {
4851
+ React29.useEffect(() => {
4836
4852
  if (autoFocus && boxRef.current) boxRef.current.focus();
4837
4853
  }, [autoFocus]);
4838
4854
  const caretNow = () => {
@@ -4899,7 +4915,7 @@ var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
4899
4915
  api.replaceRange(from, to, next, from + next.length);
4900
4916
  }
4901
4917
  };
4902
- React28.useImperativeHandle(ref, () => api);
4918
+ React29.useImperativeHandle(ref, () => api);
4903
4919
  function detect(text, caret) {
4904
4920
  if (!onTrigger) return;
4905
4921
  const upto = text.slice(0, caret);
@@ -5012,7 +5028,7 @@ var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
5012
5028
  api.replaceRange(s.start, s.end, text.replace(/\r\n?/g, "\n"));
5013
5029
  };
5014
5030
  const lh = 1.55;
5015
- return /* @__PURE__ */ jsxs51("div", { className: ["fd-rme-wrap", disabled ? "is-disabled" : "", className].filter(Boolean).join(" "), children: [
5031
+ return /* @__PURE__ */ jsxs52("div", { className: ["fd-rme-wrap", disabled ? "is-disabled" : "", className].filter(Boolean).join(" "), children: [
5016
5032
  /* @__PURE__ */ jsx56(
5017
5033
  "div",
5018
5034
  {
@@ -5051,10 +5067,10 @@ var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
5051
5067
  });
5052
5068
 
5053
5069
  // src/components/platform/AccountMenu.tsx
5054
- import * as React30 from "react";
5070
+ import * as React31 from "react";
5055
5071
 
5056
5072
  // src/kits/session.ts
5057
- import * as React29 from "react";
5073
+ import * as React30 from "react";
5058
5074
  var PERMISSION_CATALOG = [
5059
5075
  { group: "Plans", items: [
5060
5076
  { key: "plan.view", label: "View plans", detail: "Read any plan in the workspace." },
@@ -6621,8 +6637,8 @@ function roadmap(overrides) {
6621
6637
  };
6622
6638
  }
6623
6639
  function useSession() {
6624
- const [s, setS] = React29.useState(getSession);
6625
- React29.useEffect(() => subscribe(setS), []);
6640
+ const [s, setS] = React30.useState(getSession);
6641
+ React30.useEffect(() => subscribe(setS), []);
6626
6642
  return s;
6627
6643
  }
6628
6644
  var SessionKit = {
@@ -6655,7 +6671,7 @@ var SessionKit = {
6655
6671
  };
6656
6672
 
6657
6673
  // src/components/platform/AccountMenu.tsx
6658
- import { Fragment as Fragment14, jsx as jsx57, jsxs as jsxs52 } from "react/jsx-runtime";
6674
+ import { Fragment as Fragment14, jsx as jsx57, jsxs as jsxs53 } from "react/jsx-runtime";
6659
6675
  var DEFAULT_LINKS = [
6660
6676
  { id: "profile", label: "Your profile", icon: "user-circle", href: "../admin/index.html#profile" },
6661
6677
  { id: "preferences", label: "Preferences", icon: "sliders-horizontal", href: "../admin/index.html#preferences" }
@@ -6666,7 +6682,7 @@ var DEFAULT_ADMIN_LINKS = [
6666
6682
  { id: "flags", label: "Feature flags", icon: "toggle-right", href: "../admin/index.html#flags", perm: "flags.manage" }
6667
6683
  ];
6668
6684
  function Item({ item, onPick }) {
6669
- return /* @__PURE__ */ jsxs52(
6685
+ return /* @__PURE__ */ jsxs53(
6670
6686
  "button",
6671
6687
  {
6672
6688
  type: "button",
@@ -6692,9 +6708,9 @@ function AccountMenu({
6692
6708
  ...rest
6693
6709
  }) {
6694
6710
  const session = SessionKit.useSession();
6695
- const [open, setOpen] = React30.useState(false);
6696
- const [switching, setSwitching] = React30.useState(false);
6697
- const ref = React30.useRef(null);
6711
+ const [open, setOpen] = React31.useState(false);
6712
+ const [switching, setSwitching] = React31.useState(false);
6713
+ const ref = React31.useRef(null);
6698
6714
  const user = session.user;
6699
6715
  const visibleAdmin = adminLinks.filter((l) => !l.perm || SessionKit.can(l.perm));
6700
6716
  const pick = (item) => {
@@ -6708,8 +6724,8 @@ function AccountMenu({
6708
6724
  if (onSignOut) return onSignOut();
6709
6725
  window.alert("Signed out. (Simulated \u2014 no auth provider is wired up.)");
6710
6726
  };
6711
- return /* @__PURE__ */ jsxs52(Fragment14, { children: [
6712
- /* @__PURE__ */ jsxs52(
6727
+ return /* @__PURE__ */ jsxs53(Fragment14, { children: [
6728
+ /* @__PURE__ */ jsxs53(
6713
6729
  "button",
6714
6730
  {
6715
6731
  type: "button",
@@ -6726,27 +6742,27 @@ function AccountMenu({
6726
6742
  ]
6727
6743
  }
6728
6744
  ),
6729
- /* @__PURE__ */ jsx57(Popover, { open, anchorRef: ref, onClose: () => setOpen(false), placement: "bottom-end", width: 272, children: /* @__PURE__ */ jsxs52("div", { role: "menu", className: "fd-stack", style: { gap: 0 }, children: [
6730
- /* @__PURE__ */ jsxs52("div", { className: "fd-row", style: { gap: 10, padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
6745
+ /* @__PURE__ */ jsx57(Popover, { open, anchorRef: ref, onClose: () => setOpen(false), placement: "bottom-end", width: 272, children: /* @__PURE__ */ jsxs53("div", { role: "menu", className: "fd-stack", style: { gap: 0 }, children: [
6746
+ /* @__PURE__ */ jsxs53("div", { className: "fd-row", style: { gap: 10, padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
6731
6747
  /* @__PURE__ */ jsx57(Avatar, { name: user.name }),
6732
- /* @__PURE__ */ jsxs52("span", { className: "fd-stack", style: { gap: 1, minWidth: 0, flex: 1 }, children: [
6748
+ /* @__PURE__ */ jsxs53("span", { className: "fd-stack", style: { gap: 1, minWidth: 0, flex: 1 }, children: [
6733
6749
  /* @__PURE__ */ jsx57("span", { className: "fd-body-sm", style: { fontWeight: 700 }, children: user.name }),
6734
6750
  /* @__PURE__ */ jsx57("span", { className: "fd-body-sm fd-muted fd-table-trunc", children: user.email })
6735
6751
  ] })
6736
6752
  ] }),
6737
6753
  showRoles && session.roles.length ? /* @__PURE__ */ jsx57("div", { className: "fd-row", style: { gap: 6, padding: "10px 14px", flexWrap: "wrap", borderBottom: "1px solid var(--border)" }, children: session.roles.map((r) => /* @__PURE__ */ jsx57(Badge, { tone: r.id === "owner" ? "success" : "neutral", children: r.name }, r.id)) }) : null,
6738
6754
  /* @__PURE__ */ jsx57("div", { className: "fd-acct-group", children: links.map((l) => /* @__PURE__ */ jsx57(Item, { item: l, onPick: pick }, l.id)) }),
6739
- visibleAdmin.length ? /* @__PURE__ */ jsxs52("div", { className: "fd-acct-group", style: { borderTop: "1px solid var(--border)" }, children: [
6755
+ visibleAdmin.length ? /* @__PURE__ */ jsxs53("div", { className: "fd-acct-group", style: { borderTop: "1px solid var(--border)" }, children: [
6740
6756
  /* @__PURE__ */ jsx57("span", { className: "fd-overline fd-muted", style: { padding: "8px 14px 4px", display: "block" }, children: "Administration" }),
6741
6757
  visibleAdmin.map((l) => /* @__PURE__ */ jsx57(Item, { item: l, onPick: pick }, l.id))
6742
6758
  ] }) : null,
6743
- allowUserSwitch ? /* @__PURE__ */ jsxs52("div", { className: "fd-acct-group", style: { borderTop: "1px solid var(--border)" }, children: [
6744
- /* @__PURE__ */ jsxs52("button", { type: "button", role: "menuitem", className: "fd-acct-item", onClick: () => setSwitching((s) => !s), children: [
6759
+ allowUserSwitch ? /* @__PURE__ */ jsxs53("div", { className: "fd-acct-group", style: { borderTop: "1px solid var(--border)" }, children: [
6760
+ /* @__PURE__ */ jsxs53("button", { type: "button", role: "menuitem", className: "fd-acct-item", onClick: () => setSwitching((s) => !s), children: [
6745
6761
  /* @__PURE__ */ jsx57("i", { className: "ph ph-user-switch", "aria-hidden": "true" }),
6746
6762
  /* @__PURE__ */ jsx57("span", { style: { flex: 1 }, children: "View as another member" }),
6747
6763
  /* @__PURE__ */ jsx57("i", { className: "ph ph-caret-" + (switching ? "up" : "down"), "aria-hidden": "true", style: { fontSize: 11 } })
6748
6764
  ] }),
6749
- switching ? /* @__PURE__ */ jsx57("div", { className: "fd-stack", style: { gap: 0 }, children: session.allUsers.filter((u) => u.status === "active").map((u) => /* @__PURE__ */ jsxs52(
6765
+ switching ? /* @__PURE__ */ jsx57("div", { className: "fd-stack", style: { gap: 0 }, children: session.allUsers.filter((u) => u.status === "active").map((u) => /* @__PURE__ */ jsxs53(
6750
6766
  "button",
6751
6767
  {
6752
6768
  type: "button",
@@ -6759,7 +6775,7 @@ function AccountMenu({
6759
6775
  },
6760
6776
  children: [
6761
6777
  /* @__PURE__ */ jsx57(Avatar, { name: u.name, size: "sm" }),
6762
- /* @__PURE__ */ jsxs52("span", { className: "fd-stack", style: { gap: 0, flex: 1, minWidth: 0, alignItems: "flex-start" }, children: [
6778
+ /* @__PURE__ */ jsxs53("span", { className: "fd-stack", style: { gap: 0, flex: 1, minWidth: 0, alignItems: "flex-start" }, children: [
6763
6779
  /* @__PURE__ */ jsx57("span", { style: { fontWeight: u.id === user.id ? 700 : 500 }, children: u.name }),
6764
6780
  /* @__PURE__ */ jsx57("span", { className: "fd-muted", style: { fontSize: 11.5 }, children: u.roles.join(", ") })
6765
6781
  ] }),
@@ -6769,7 +6785,7 @@ function AccountMenu({
6769
6785
  u.id
6770
6786
  )) }) : null
6771
6787
  ] }) : null,
6772
- /* @__PURE__ */ jsx57("div", { className: "fd-acct-group", style: { borderTop: "1px solid var(--border)" }, children: /* @__PURE__ */ jsxs52("button", { type: "button", role: "menuitem", className: "fd-acct-item", "data-danger": "true", onClick: signOut, children: [
6788
+ /* @__PURE__ */ jsx57("div", { className: "fd-acct-group", style: { borderTop: "1px solid var(--border)" }, children: /* @__PURE__ */ jsxs53("button", { type: "button", role: "menuitem", className: "fd-acct-item", "data-danger": "true", onClick: signOut, children: [
6773
6789
  /* @__PURE__ */ jsx57("i", { className: "ph ph-sign-out", "aria-hidden": "true" }),
6774
6790
  /* @__PURE__ */ jsx57("span", { style: { flex: 1 }, children: "Sign out" })
6775
6791
  ] }) })
@@ -6778,14 +6794,14 @@ function AccountMenu({
6778
6794
  }
6779
6795
 
6780
6796
  // src/components/platform/ApiSpecBrowser.tsx
6781
- import * as React31 from "react";
6782
- import { jsx as jsx58, jsxs as jsxs53 } from "react/jsx-runtime";
6797
+ import * as React32 from "react";
6798
+ import { jsx as jsx58, jsxs as jsxs54 } from "react/jsx-runtime";
6783
6799
  var METHOD_TONE = { GET: "success", POST: "info", PATCH: "warning", PUT: "warning", DELETE: "danger" };
6784
6800
  function Json({ obj }) {
6785
6801
  return /* @__PURE__ */ jsx58("pre", { className: "fd-json", children: JSON.stringify(obj, null, 2) });
6786
6802
  }
6787
6803
  function Endpoint({ s, onRequest }) {
6788
- const [tried, setTried] = React31.useState(null);
6804
+ const [tried, setTried] = React32.useState(null);
6789
6805
  const run = async () => {
6790
6806
  setTried("busy");
6791
6807
  const t0 = (window.performance || Date).now();
@@ -6796,13 +6812,13 @@ function Endpoint({ s, onRequest }) {
6796
6812
  setTried({ ms: Math.round((window.performance || Date).now() - t0), error: String(e && e.message || e) });
6797
6813
  }
6798
6814
  };
6799
- return /* @__PURE__ */ jsx58(Card, { elevation: "flat", padded: false, children: /* @__PURE__ */ jsxs53("div", { className: "fd-stack", style: { gap: 0 }, children: [
6800
- /* @__PURE__ */ jsxs53("div", { className: "fd-row", style: { gap: 10, padding: "14px 18px", flexWrap: "wrap" }, children: [
6815
+ return /* @__PURE__ */ jsx58(Card, { elevation: "flat", padded: false, children: /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 0 }, children: [
6816
+ /* @__PURE__ */ jsxs54("div", { className: "fd-row", style: { gap: 10, padding: "14px 18px", flexWrap: "wrap" }, children: [
6801
6817
  /* @__PURE__ */ jsx58(Badge, { tone: METHOD_TONE[s.method] || "neutral", children: s.method }),
6802
6818
  /* @__PURE__ */ jsx58("code", { className: "fd-mono", style: { fontSize: 12.5, fontWeight: 600, color: "var(--text)", wordBreak: "break-all" }, children: s.path }),
6803
6819
  s.isList ? /* @__PURE__ */ jsx58(Badge, { tone: "neutral", icon: "rows", children: "Paged list" }) : null,
6804
6820
  /* @__PURE__ */ jsx58("span", { style: { flex: 1 } }),
6805
- /* @__PURE__ */ jsxs53("span", { className: "fd-body-sm fd-muted fd-mono", children: [
6821
+ /* @__PURE__ */ jsxs54("span", { className: "fd-body-sm fd-muted fd-mono", children: [
6806
6822
  s.latency[0],
6807
6823
  "\u2013",
6808
6824
  s.latency[1],
@@ -6810,31 +6826,31 @@ function Endpoint({ s, onRequest }) {
6810
6826
  ] }),
6811
6827
  /* @__PURE__ */ jsx58(Button, { size: "sm", variant: "secondary", icon: "play", loading: tried === "busy", onClick: run, children: "Try it" })
6812
6828
  ] }),
6813
- /* @__PURE__ */ jsxs53("div", { className: "fd-stack", style: { gap: 14, padding: "0 18px 16px" }, children: [
6814
- /* @__PURE__ */ jsxs53("div", { className: "fd-stack", style: { gap: 6 }, children: [
6829
+ /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 14, padding: "0 18px 16px" }, children: [
6830
+ /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 6 }, children: [
6815
6831
  /* @__PURE__ */ jsx58("span", { className: "fd-body-sm", style: { fontWeight: 700 }, children: s.title }),
6816
6832
  /* @__PURE__ */ jsx58("p", { className: "fd-body-sm fd-secondary", style: { margin: 0, textWrap: "pretty" }, children: s.purpose }),
6817
6833
  s.usedBy && s.usedBy.length ? /* @__PURE__ */ jsx58("span", { className: "fd-row", style: { gap: 6, flexWrap: "wrap" }, children: s.usedBy.map((u) => /* @__PURE__ */ jsx58(Tag, { children: u }, u)) }) : null
6818
6834
  ] }),
6819
- /* @__PURE__ */ jsxs53("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(280px,1fr))", gap: 12, alignItems: "start" }, children: [
6820
- s.request ? /* @__PURE__ */ jsxs53("div", { className: "fd-stack", style: { gap: 6 }, children: [
6835
+ /* @__PURE__ */ jsxs54("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(280px,1fr))", gap: 12, alignItems: "start" }, children: [
6836
+ s.request ? /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 6 }, children: [
6821
6837
  /* @__PURE__ */ jsx58("span", { className: "fd-overline fd-muted", children: "Request body" }),
6822
6838
  /* @__PURE__ */ jsx58(Json, { obj: s.request })
6823
6839
  ] }) : null,
6824
- s.query ? /* @__PURE__ */ jsxs53("div", { className: "fd-stack", style: { gap: 6 }, children: [
6840
+ s.query ? /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 6 }, children: [
6825
6841
  /* @__PURE__ */ jsx58("span", { className: "fd-overline fd-muted", children: "Query" }),
6826
6842
  /* @__PURE__ */ jsx58(Json, { obj: s.query })
6827
6843
  ] }) : null,
6828
- /* @__PURE__ */ jsxs53("div", { className: "fd-stack", style: { gap: 6 }, children: [
6844
+ /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 6 }, children: [
6829
6845
  /* @__PURE__ */ jsx58("span", { className: "fd-overline fd-muted", children: "Response 200" }),
6830
6846
  /* @__PURE__ */ jsx58(Json, { obj: s.response })
6831
6847
  ] })
6832
6848
  ] }),
6833
6849
  s.notes ? /* @__PURE__ */ jsx58(Flag, { tone: "info", statement: "Implementation note", cost: s.notes, actions: null }) : null,
6834
- tried && tried !== "busy" ? /* @__PURE__ */ jsxs53("div", { className: "fd-stack", style: { gap: 6 }, children: [
6835
- /* @__PURE__ */ jsxs53("span", { className: "fd-row", style: { gap: 8 }, children: [
6850
+ tried && tried !== "busy" ? /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 6 }, children: [
6851
+ /* @__PURE__ */ jsxs54("span", { className: "fd-row", style: { gap: 8 }, children: [
6836
6852
  /* @__PURE__ */ jsx58("span", { className: "fd-overline fd-muted", children: "Simulated response" }),
6837
- /* @__PURE__ */ jsxs53(Badge, { tone: tried.error ? "danger" : "success", icon: "timer", children: [
6853
+ /* @__PURE__ */ jsxs54(Badge, { tone: tried.error ? "danger" : "success", icon: "timer", children: [
6838
6854
  tried.ms,
6839
6855
  "ms"
6840
6856
  ] })
@@ -6858,29 +6874,29 @@ function ApiSpecBrowser({
6858
6874
  className = "",
6859
6875
  ...rest
6860
6876
  }) {
6861
- const [q, setQ] = React31.useState("");
6862
- const [method, setMethod] = React31.useState(null);
6863
- const [mod, setMod] = React31.useState(null);
6864
- const [listOnly, setListOnly] = React31.useState(false);
6877
+ const [q, setQ] = React32.useState("");
6878
+ const [method, setMethod] = React32.useState(null);
6879
+ const [mod, setMod] = React32.useState(null);
6880
+ const [listOnly, setListOnly] = React32.useState(false);
6865
6881
  const activeModule = modules && modules.find((m) => m.id === mod);
6866
6882
  const hits = spec.filter((s) => (!method || s.method === method) && (!listOnly || s.isList) && (!activeModule || activeModule.endpoints.indexOf(s.id) >= 0) && (!q || (s.path + " " + s.title + " " + s.purpose + " " + (s.usedBy || []).join(" ")).toLowerCase().includes(q.toLowerCase())));
6867
6883
  const effGroups = groups && groups.length ? groups : [["All endpoints", spec.map((s) => s.id)]];
6868
6884
  const methods = [...new Set(spec.map((s) => s.method))];
6869
6885
  const listCount = spec.filter((s) => s.isList).length;
6870
- return /* @__PURE__ */ jsxs53("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 20, maxWidth: 1100 }, ...rest, children: [
6871
- /* @__PURE__ */ jsxs53("div", { className: "fd-stack", style: { gap: 10 }, children: [
6886
+ return /* @__PURE__ */ jsxs54("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 20, maxWidth: 1100 }, ...rest, children: [
6887
+ /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 10 }, children: [
6872
6888
  kicker ? /* @__PURE__ */ jsx58("span", { className: "fd-overline fd-muted", children: kicker }) : null,
6873
6889
  /* @__PURE__ */ jsx58("h1", { className: "fd-h1", style: { margin: 0 }, children: title }),
6874
6890
  lede ? /* @__PURE__ */ jsx58("p", { className: "fd-body fd-secondary fd-prose", style: { margin: 0 }, children: lede }) : null
6875
6891
  ] }),
6876
- modules && modules.length ? /* @__PURE__ */ jsxs53("div", { className: "fd-stack", style: { gap: 8 }, children: [
6892
+ modules && modules.length ? /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 8 }, children: [
6877
6893
  /* @__PURE__ */ jsx58("span", { className: "fd-overline fd-muted", children: "Filter by screen \u2014 every endpoint that screen depends on" }),
6878
- /* @__PURE__ */ jsxs53("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: [
6879
- /* @__PURE__ */ jsxs53(Tag, { icon: "stack", selected: !mod, onClick: () => setMod(null), children: [
6894
+ /* @__PURE__ */ jsxs54("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: [
6895
+ /* @__PURE__ */ jsxs54(Tag, { icon: "stack", selected: !mod, onClick: () => setMod(null), children: [
6880
6896
  "All screens ",
6881
6897
  /* @__PURE__ */ jsx58("span", { className: "fd-mono", children: spec.length })
6882
6898
  ] }),
6883
- modules.map((m) => /* @__PURE__ */ jsxs53(Tag, { icon: m.icon, selected: mod === m.id, onClick: () => setMod(mod === m.id ? null : m.id), children: [
6899
+ modules.map((m) => /* @__PURE__ */ jsxs54(Tag, { icon: m.icon, selected: mod === m.id, onClick: () => setMod(mod === m.id ? null : m.id), children: [
6884
6900
  m.label,
6885
6901
  " ",
6886
6902
  /* @__PURE__ */ jsx58("span", { className: "fd-mono", children: m.endpoints.length })
@@ -6897,19 +6913,19 @@ function ApiSpecBrowser({
6897
6913
  ) : null
6898
6914
  ] }) : null,
6899
6915
  sourceNote ? /* @__PURE__ */ jsx58(Flag, { tone: "info", statement: "Design-first: this page is the spec.", cost: sourceNote, actions: null }) : null,
6900
- /* @__PURE__ */ jsxs53("div", { className: "fd-row", style: { gap: 10, flexWrap: "wrap" }, children: [
6916
+ /* @__PURE__ */ jsxs54("div", { className: "fd-row", style: { gap: 10, flexWrap: "wrap" }, children: [
6901
6917
  /* @__PURE__ */ jsx58(Input, { icon: "magnifying-glass", placeholder: "Find an endpoint, screen, or behavior", value: q, onChange: (e) => setQ(e.target.value), style: { width: 300 } }),
6902
- methods.map((m) => /* @__PURE__ */ jsxs53(Tag, { selected: method === m, onClick: () => setMethod(method === m ? null : m), children: [
6918
+ methods.map((m) => /* @__PURE__ */ jsxs54(Tag, { selected: method === m, onClick: () => setMethod(method === m ? null : m), children: [
6903
6919
  m,
6904
6920
  " ",
6905
6921
  /* @__PURE__ */ jsx58("span", { className: "fd-mono", children: spec.filter((s) => s.method === m).length })
6906
6922
  ] }, m)),
6907
- listCount ? /* @__PURE__ */ jsxs53(Tag, { icon: "rows", selected: listOnly, onClick: () => setListOnly(!listOnly), children: [
6923
+ listCount ? /* @__PURE__ */ jsxs54(Tag, { icon: "rows", selected: listOnly, onClick: () => setListOnly(!listOnly), children: [
6908
6924
  "Paged lists ",
6909
6925
  /* @__PURE__ */ jsx58("span", { className: "fd-mono", children: listCount })
6910
6926
  ] }) : null,
6911
6927
  /* @__PURE__ */ jsx58("span", { style: { flex: 1 } }),
6912
- /* @__PURE__ */ jsxs53("span", { className: "fd-body-sm fd-muted", children: [
6928
+ /* @__PURE__ */ jsxs54("span", { className: "fd-body-sm fd-muted", children: [
6913
6929
  hits.length,
6914
6930
  " of ",
6915
6931
  spec.length,
@@ -6920,18 +6936,18 @@ function ApiSpecBrowser({
6920
6936
  hits.length === 0 ? /* @__PURE__ */ jsx58(Card, { elevation: "flat", children: /* @__PURE__ */ jsx58("p", { className: "fd-body-sm fd-muted", style: { margin: 0 }, children: "No endpoint matches those filters." }) }) : effGroups.map(([g, ids]) => {
6921
6937
  const items = hits.filter((s) => ids.indexOf(s.id) >= 0);
6922
6938
  if (!items.length) return null;
6923
- return /* @__PURE__ */ jsxs53("div", { className: "fd-stack", style: { gap: 12 }, children: [
6939
+ return /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 12 }, children: [
6924
6940
  /* @__PURE__ */ jsx58("span", { className: "fd-label-lg", children: g }),
6925
6941
  items.map((s) => /* @__PURE__ */ jsx58(Endpoint, { s, onRequest }, s.id))
6926
6942
  ] }, g);
6927
6943
  }),
6928
- conventions && conventions.length ? /* @__PURE__ */ jsx58(Card, { title: "Cross-cutting conventions", elevation: "flat", children: /* @__PURE__ */ jsx58("div", { className: "fd-stack", style: { gap: 10 }, children: conventions.map(([k, v]) => /* @__PURE__ */ jsxs53("div", { className: "fd-row", style: { gap: 12, alignItems: "flex-start" }, children: [
6944
+ conventions && conventions.length ? /* @__PURE__ */ jsx58(Card, { title: "Cross-cutting conventions", elevation: "flat", children: /* @__PURE__ */ jsx58("div", { className: "fd-stack", style: { gap: 10 }, children: conventions.map(([k, v]) => /* @__PURE__ */ jsxs54("div", { className: "fd-row", style: { gap: 12, alignItems: "flex-start" }, children: [
6929
6945
  /* @__PURE__ */ jsx58("span", { className: "fd-overline fd-muted", style: { width: 110, flex: "none", paddingTop: 2 }, children: k }),
6930
6946
  /* @__PURE__ */ jsx58("span", { className: "fd-body-sm fd-secondary", style: { textWrap: "pretty" }, children: v })
6931
6947
  ] }, k)) }) }) : null,
6932
- openQuestions && openQuestions.length ? /* @__PURE__ */ jsx58(Collapsible, { icon: "list-checks", title: "Open questions before implementation", subtitle: openQuestions.length + " unresolved", children: /* @__PURE__ */ jsx58("div", { className: "fd-stack", style: { gap: 8 }, children: openQuestions.map(([id, question, why]) => /* @__PURE__ */ jsxs53("div", { className: "fd-row", style: { gap: 10, alignItems: "flex-start", padding: "8px 0", borderTop: "1px solid var(--border)" }, children: [
6948
+ openQuestions && openQuestions.length ? /* @__PURE__ */ jsx58(Collapsible, { icon: "list-checks", title: "Open questions before implementation", subtitle: openQuestions.length + " unresolved", children: /* @__PURE__ */ jsx58("div", { className: "fd-stack", style: { gap: 8 }, children: openQuestions.map(([id, question, why]) => /* @__PURE__ */ jsxs54("div", { className: "fd-row", style: { gap: 10, alignItems: "flex-start", padding: "8px 0", borderTop: "1px solid var(--border)" }, children: [
6933
6949
  /* @__PURE__ */ jsx58(Badge, { tone: "danger", children: id }),
6934
- /* @__PURE__ */ jsxs53("span", { className: "fd-stack", style: { gap: 2, flex: 1 }, children: [
6950
+ /* @__PURE__ */ jsxs54("span", { className: "fd-stack", style: { gap: 2, flex: 1 }, children: [
6935
6951
  /* @__PURE__ */ jsx58("span", { className: "fd-body-sm", style: { fontWeight: 600 }, children: question }),
6936
6952
  /* @__PURE__ */ jsx58("span", { className: "fd-body-sm fd-muted", children: why })
6937
6953
  ] })
@@ -6940,8 +6956,8 @@ function ApiSpecBrowser({
6940
6956
  }
6941
6957
 
6942
6958
  // src/components/platform/ProfilePage.tsx
6943
- import * as React32 from "react";
6944
- import { jsx as jsx59, jsxs as jsxs54 } from "react/jsx-runtime";
6959
+ import * as React33 from "react";
6960
+ import { jsx as jsx59, jsxs as jsxs55 } from "react/jsx-runtime";
6945
6961
  var TIMEZONES = ["America/New_York", "America/Chicago", "America/Denver", "America/Los_Angeles", "America/Anchorage", "Pacific/Honolulu", "Europe/London", "Europe/Berlin"];
6946
6962
  var NOTIFY = [
6947
6963
  { key: "planShared", label: "A plan is shared with me", detail: "Someone sends you a plan or a client link." },
@@ -6953,7 +6969,7 @@ var NOTIFY = [
6953
6969
  function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSessions = true, className = "", ...rest }) {
6954
6970
  const session = SessionKit.useSession();
6955
6971
  const user = userProp || session.user;
6956
- const [draft, setDraft] = React32.useState(() => ({
6972
+ const [draft, setDraft] = React33.useState(() => ({
6957
6973
  name: user.name || "",
6958
6974
  title: user.title || "",
6959
6975
  email: user.email || "",
@@ -6962,8 +6978,8 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
6962
6978
  bio: user.bio || "",
6963
6979
  notify: user.notify || { planShared: true, planChanged: true, goalMissed: true, flagChanged: false, weekly: true }
6964
6980
  }));
6965
- const [saving, setSaving] = React32.useState(false);
6966
- const [saved, setSaved] = React32.useState(false);
6981
+ const [saving, setSaving] = React33.useState(false);
6982
+ const [saved, setSaved] = React33.useState(false);
6967
6983
  const set = (k, v) => {
6968
6984
  setDraft((d) => Object.assign({}, d, { [k]: v }));
6969
6985
  setSaved(false);
@@ -6985,22 +7001,22 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
6985
7001
  { id: "s2", device: "iPhone 15 \xB7 Safari", where: "Denver, CO", when: "2 hours ago" },
6986
7002
  { id: "s3", device: "Windows \xB7 Edge", where: "Chicago, IL", when: "Aug 12" }
6987
7003
  ];
6988
- return /* @__PURE__ */ jsxs54("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 20, maxWidth: 860 }, ...rest, children: [
6989
- /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 10 }, children: [
7004
+ return /* @__PURE__ */ jsxs55("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 20, maxWidth: 860 }, ...rest, children: [
7005
+ /* @__PURE__ */ jsxs55("div", { className: "fd-stack", style: { gap: 10 }, children: [
6990
7006
  /* @__PURE__ */ jsx59("span", { className: "fd-overline fd-muted", children: "Account" }),
6991
7007
  /* @__PURE__ */ jsx59("h1", { className: "fd-h1", style: { margin: 0 }, children: "Your profile" }),
6992
7008
  /* @__PURE__ */ jsx59("p", { className: "fd-body fd-secondary fd-prose", style: { margin: 0 }, children: "How you appear to colleagues and clients across every flytedesk app, and what we send you." })
6993
7009
  ] }),
6994
- /* @__PURE__ */ jsx59(Card, { elevation: "flat", children: /* @__PURE__ */ jsxs54("div", { className: "fd-row", style: { gap: 16, flexWrap: "wrap", alignItems: "flex-start" }, children: [
7010
+ /* @__PURE__ */ jsx59(Card, { elevation: "flat", children: /* @__PURE__ */ jsxs55("div", { className: "fd-row", style: { gap: 16, flexWrap: "wrap", alignItems: "flex-start" }, children: [
6995
7011
  /* @__PURE__ */ jsx59(Avatar, { name: draft.name || user.name, size: "lg" }),
6996
- /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 4, flex: 1, minWidth: 200 }, children: [
7012
+ /* @__PURE__ */ jsxs55("div", { className: "fd-stack", style: { gap: 4, flex: 1, minWidth: 200 }, children: [
6997
7013
  /* @__PURE__ */ jsx59("span", { className: "fd-h3", style: { margin: 0 }, children: draft.name || user.name }),
6998
- /* @__PURE__ */ jsxs54("span", { className: "fd-body-sm fd-muted", children: [
7014
+ /* @__PURE__ */ jsxs55("span", { className: "fd-body-sm fd-muted", children: [
6999
7015
  draft.title || "No title set",
7000
7016
  " \xB7 ",
7001
7017
  user.team || "No team"
7002
7018
  ] }),
7003
- /* @__PURE__ */ jsxs54("span", { className: "fd-row", style: { gap: 6, flexWrap: "wrap", paddingTop: 4 }, children: [
7019
+ /* @__PURE__ */ jsxs55("span", { className: "fd-row", style: { gap: 6, flexWrap: "wrap", paddingTop: 4 }, children: [
7004
7020
  session.roles.map((r) => /* @__PURE__ */ jsx59(Badge, { tone: r.id === "owner" ? "success" : "neutral", children: r.name }, r.id)),
7005
7021
  user.sso ? /* @__PURE__ */ jsx59(Badge, { tone: "info", icon: "shield-check", children: "SSO" }) : null
7006
7022
  ] })
@@ -7010,17 +7026,17 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
7010
7026
  /* @__PURE__ */ jsx59(
7011
7027
  Card,
7012
7028
  {
7013
- title: /* @__PURE__ */ jsxs54("span", { className: "fd-stack", style: { gap: 2 }, children: [
7029
+ title: /* @__PURE__ */ jsxs55("span", { className: "fd-stack", style: { gap: 2 }, children: [
7014
7030
  /* @__PURE__ */ jsx59("span", { children: "Identity" }),
7015
7031
  /* @__PURE__ */ jsx59("span", { className: "fd-body-sm fd-muted", style: { fontWeight: 400 }, children: "Name and title appear on plans you share" })
7016
7032
  ] }),
7017
7033
  elevation: "flat",
7018
- children: /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 14 }, children: [
7019
- /* @__PURE__ */ jsxs54("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(220px,1fr))", gap: 14 }, children: [
7034
+ children: /* @__PURE__ */ jsxs55("div", { className: "fd-stack", style: { gap: 14 }, children: [
7035
+ /* @__PURE__ */ jsxs55("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(220px,1fr))", gap: 14 }, children: [
7020
7036
  /* @__PURE__ */ jsx59(Input, { label: "Full name", value: draft.name, onChange: (e) => set("name", e.target.value) }),
7021
7037
  /* @__PURE__ */ jsx59(Input, { label: "Job title", value: draft.title, onChange: (e) => set("title", e.target.value), placeholder: "e.g. Senior media planner" })
7022
7038
  ] }),
7023
- /* @__PURE__ */ jsxs54("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(220px,1fr))", gap: 14 }, children: [
7039
+ /* @__PURE__ */ jsxs55("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(220px,1fr))", gap: 14 }, children: [
7024
7040
  /* @__PURE__ */ jsx59(
7025
7041
  Input,
7026
7042
  {
@@ -7047,7 +7063,7 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
7047
7063
  ] })
7048
7064
  }
7049
7065
  ),
7050
- /* @__PURE__ */ jsx59(Card, { title: "Working preferences", elevation: "flat", children: /* @__PURE__ */ jsxs54("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(220px,1fr))", gap: 14 }, children: [
7066
+ /* @__PURE__ */ jsx59(Card, { title: "Working preferences", elevation: "flat", children: /* @__PURE__ */ jsxs55("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(220px,1fr))", gap: 14 }, children: [
7051
7067
  /* @__PURE__ */ jsx59(
7052
7068
  Select,
7053
7069
  {
@@ -7063,7 +7079,7 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
7063
7079
  /* @__PURE__ */ jsx59(
7064
7080
  Card,
7065
7081
  {
7066
- title: /* @__PURE__ */ jsxs54("span", { className: "fd-stack", style: { gap: 2 }, children: [
7082
+ title: /* @__PURE__ */ jsxs55("span", { className: "fd-stack", style: { gap: 2 }, children: [
7067
7083
  /* @__PURE__ */ jsx59("span", { children: "Notifications" }),
7068
7084
  /* @__PURE__ */ jsx59("span", { className: "fd-body-sm fd-muted", style: { fontWeight: 400 }, children: "Email only for now \u2014 in-app notifications are on the roadmap" })
7069
7085
  ] }),
@@ -7071,10 +7087,10 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
7071
7087
  children: /* @__PURE__ */ jsx59("div", { className: "fd-stack", style: { gap: 14 }, children: NOTIFY.map((n) => /* @__PURE__ */ jsx59(Switch, { checked: !!draft.notify[n.key], onChange: () => setNotify(n.key), label: n.label, description: n.detail }, n.key)) })
7072
7088
  }
7073
7089
  ),
7074
- /* @__PURE__ */ jsxs54(
7090
+ /* @__PURE__ */ jsxs55(
7075
7091
  Card,
7076
7092
  {
7077
- title: /* @__PURE__ */ jsxs54("span", { className: "fd-stack", style: { gap: 2 }, children: [
7093
+ title: /* @__PURE__ */ jsxs55("span", { className: "fd-stack", style: { gap: 2 }, children: [
7078
7094
  /* @__PURE__ */ jsx59("span", { children: "Access" }),
7079
7095
  /* @__PURE__ */ jsx59("span", { className: "fd-body-sm fd-muted", style: { fontWeight: 400 }, children: "What your roles grant you" })
7080
7096
  ] }),
@@ -7090,9 +7106,9 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
7090
7106
  }
7091
7107
  ),
7092
7108
  children: [
7093
- /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 0 }, children: [
7109
+ /* @__PURE__ */ jsxs55("div", { className: "fd-stack", style: { gap: 0 }, children: [
7094
7110
  /* @__PURE__ */ jsx59(CardRow, { label: "Roles", children: session.roles.map((r) => r.name).join(", ") || "None" }),
7095
- /* @__PURE__ */ jsxs54(CardRow, { label: "Permissions", children: [
7111
+ /* @__PURE__ */ jsxs55(CardRow, { label: "Permissions", children: [
7096
7112
  session.permissions.length,
7097
7113
  " granted"
7098
7114
  ] }),
@@ -7108,11 +7124,11 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
7108
7124
  title: "Signed-in devices",
7109
7125
  elevation: "flat",
7110
7126
  action: /* @__PURE__ */ jsx59(Button, { size: "sm", variant: "ghost", icon: "sign-out", children: "Sign out everywhere" }),
7111
- children: /* @__PURE__ */ jsx59("div", { className: "fd-stack", style: { gap: 0 }, children: liveSessions.map((s) => /* @__PURE__ */ jsxs54("div", { className: "fd-row", style: { gap: 12, padding: "10px 0", borderTop: "1px solid var(--border)", flexWrap: "wrap" }, children: [
7127
+ children: /* @__PURE__ */ jsx59("div", { className: "fd-stack", style: { gap: 0 }, children: liveSessions.map((s) => /* @__PURE__ */ jsxs55("div", { className: "fd-row", style: { gap: 12, padding: "10px 0", borderTop: "1px solid var(--border)", flexWrap: "wrap" }, children: [
7112
7128
  /* @__PURE__ */ jsx59("i", { className: "ph ph-device-mobile", style: { fontSize: 16, color: "var(--text-muted)" }, "aria-hidden": "true" }),
7113
- /* @__PURE__ */ jsxs54("span", { className: "fd-stack", style: { gap: 1, flex: 1, minWidth: 160 }, children: [
7129
+ /* @__PURE__ */ jsxs55("span", { className: "fd-stack", style: { gap: 1, flex: 1, minWidth: 160 }, children: [
7114
7130
  /* @__PURE__ */ jsx59("span", { className: "fd-body-sm", style: { fontWeight: 600 }, children: s.device }),
7115
- /* @__PURE__ */ jsxs54("span", { className: "fd-body-sm fd-muted", children: [
7131
+ /* @__PURE__ */ jsxs55("span", { className: "fd-body-sm fd-muted", children: [
7116
7132
  s.where,
7117
7133
  " \xB7 ",
7118
7134
  s.when
@@ -7122,7 +7138,7 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
7122
7138
  ] }, s.id)) })
7123
7139
  }
7124
7140
  ) : null,
7125
- /* @__PURE__ */ jsxs54("div", { className: "fd-row", style: {
7141
+ /* @__PURE__ */ jsxs55("div", { className: "fd-row", style: {
7126
7142
  gap: 10,
7127
7143
  flexWrap: "wrap",
7128
7144
  position: "sticky",
@@ -7153,10 +7169,10 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
7153
7169
  }
7154
7170
 
7155
7171
  // src/components/platform/RoadmapTimeline.tsx
7156
- import * as React34 from "react";
7172
+ import * as React35 from "react";
7157
7173
 
7158
7174
  // src/kits/runtime.ts
7159
- import * as React33 from "react";
7175
+ import * as React34 from "react";
7160
7176
  var WIRED_ENDPOINTS = [
7161
7177
  // Nothing yet. Every id below would come from a real service:
7162
7178
  // "plan.get", "placements.list", …
@@ -7327,8 +7343,8 @@ var RuntimeKit = {
7327
7343
  };
7328
7344
  RuntimeKit.declare(FEATURE_NEEDS);
7329
7345
  function useRuntimeMode() {
7330
- const [m, setM] = React33.useState(RuntimeKit.getMode());
7331
- React33.useEffect(() => RuntimeKit.subscribe(setM), []);
7346
+ const [m, setM] = React34.useState(RuntimeKit.getMode());
7347
+ React34.useEffect(() => RuntimeKit.subscribe(setM), []);
7332
7348
  return m;
7333
7349
  }
7334
7350
  function useFeatureStatus(key) {
@@ -7347,7 +7363,7 @@ var UseRuntimeMode = useRuntimeMode;
7347
7363
  var UseFeatureStatus = useFeatureStatus;
7348
7364
 
7349
7365
  // src/components/platform/RoadmapTimeline.tsx
7350
- import { jsx as jsx60, jsxs as jsxs55 } from "react/jsx-runtime";
7366
+ import { jsx as jsx60, jsxs as jsxs56 } from "react/jsx-runtime";
7351
7367
  var STATUS = {
7352
7368
  shipped: { tone: "success", icon: "check-circle", label: "Wired" },
7353
7369
  next: { tone: "warning", icon: "traffic-cone", label: "Not wired" },
@@ -7362,24 +7378,24 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
7362
7378
  const s = STATUS[item.status] || STATUS.planned;
7363
7379
  const deps = (item.dependsOn || []).map((k) => byKey[k]).filter(Boolean);
7364
7380
  const blocking = deps.filter((d) => !d.implemented);
7365
- return /* @__PURE__ */ jsx60(Card, { elevation: "flat", children: /* @__PURE__ */ jsxs55("div", { className: "fd-stack", style: { gap: 10 }, children: [
7366
- /* @__PURE__ */ jsxs55("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: [
7381
+ return /* @__PURE__ */ jsx60(Card, { elevation: "flat", children: /* @__PURE__ */ jsxs56("div", { className: "fd-stack", style: { gap: 10 }, children: [
7382
+ /* @__PURE__ */ jsxs56("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: [
7367
7383
  /* @__PURE__ */ jsx60("span", { className: "fd-body", style: { fontWeight: 700, flex: 1, minWidth: 140 }, children: item.label }),
7368
7384
  /* @__PURE__ */ jsx60(Badge, { tone: "neutral", icon: PROJECT_ICON[item.project] || "squares-four", children: item.project }),
7369
7385
  /* @__PURE__ */ jsx60(Badge, { tone: s.tone, icon: s.icon, children: s.label })
7370
7386
  ] }),
7371
7387
  /* @__PURE__ */ jsx60("p", { className: "fd-body-sm fd-secondary", style: { margin: 0, textWrap: "pretty" }, children: item.description }),
7372
- item.backend ? /* @__PURE__ */ jsxs55("div", { className: "fd-row", style: { gap: 10, alignItems: "flex-start" }, children: [
7388
+ item.backend ? /* @__PURE__ */ jsxs56("div", { className: "fd-row", style: { gap: 10, alignItems: "flex-start" }, children: [
7373
7389
  /* @__PURE__ */ jsx60("span", { className: "fd-overline fd-muted", style: { width: 62, flex: "none", paddingTop: 2 }, children: "Backend" }),
7374
7390
  /* @__PURE__ */ jsx60("span", { className: "fd-body-sm", style: { flex: 1, textWrap: "pretty" }, children: item.backend })
7375
7391
  ] }) : null,
7376
- /* @__PURE__ */ jsxs55("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
7377
- item.effort ? /* @__PURE__ */ jsxs55("span", { className: "fd-body-sm fd-muted", children: [
7392
+ /* @__PURE__ */ jsxs56("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
7393
+ item.effort ? /* @__PURE__ */ jsxs56("span", { className: "fd-body-sm fd-muted", children: [
7378
7394
  /* @__PURE__ */ jsx60("i", { className: "ph ph-hourglass-medium" }),
7379
7395
  " ",
7380
7396
  item.effort
7381
7397
  ] }) : null,
7382
- /* @__PURE__ */ jsxs55("span", { className: "fd-body-sm fd-muted", children: [
7398
+ /* @__PURE__ */ jsxs56("span", { className: "fd-body-sm fd-muted", children: [
7383
7399
  /* @__PURE__ */ jsx60("i", { className: "ph ph-user" }),
7384
7400
  " ",
7385
7401
  item.owner
@@ -7396,11 +7412,11 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
7396
7412
  }
7397
7413
  )
7398
7414
  ] }),
7399
- deps.length ? /* @__PURE__ */ jsxs55("div", { className: "fd-row", style: { gap: 6, flexWrap: "wrap", paddingTop: 6, borderTop: "1px solid var(--border)" }, children: [
7415
+ deps.length ? /* @__PURE__ */ jsxs56("div", { className: "fd-row", style: { gap: 6, flexWrap: "wrap", paddingTop: 6, borderTop: "1px solid var(--border)" }, children: [
7400
7416
  /* @__PURE__ */ jsx60("span", { className: "fd-overline fd-muted", style: { paddingTop: 3 }, children: "After" }),
7401
7417
  deps.map((d) => /* @__PURE__ */ jsx60(Tag, { icon: d.implemented ? "check" : "clock", children: d.label }, d.key))
7402
7418
  ] }) : null,
7403
- blocking.length && !item.implemented ? /* @__PURE__ */ jsxs55("span", { className: "fd-body-sm", style: { color: "var(--warn-text)" }, children: [
7419
+ blocking.length && !item.implemented ? /* @__PURE__ */ jsxs56("span", { className: "fd-body-sm", style: { color: "var(--warn-text)" }, children: [
7404
7420
  "Blocked until ",
7405
7421
  blocking.map((d) => d.label).join(" and "),
7406
7422
  " ",
@@ -7411,12 +7427,12 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
7411
7427
  }
7412
7428
  function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
7413
7429
  const session = SessionKit.useSession();
7414
- const [project, setProject] = React34.useState("");
7415
- const [q, setQ] = React34.useState("");
7416
- const scrollRef = React34.useRef(null);
7417
- const nowRef = React34.useRef(null);
7418
- const rm = React34.useMemo(() => SessionKit.roadmap({ isComplete: RuntimeKit.isComplete }), [session]);
7419
- const byKey = React34.useMemo(() => {
7430
+ const [project, setProject] = React35.useState("");
7431
+ const [q, setQ] = React35.useState("");
7432
+ const scrollRef = React35.useRef(null);
7433
+ const nowRef = React35.useRef(null);
7434
+ const rm = React35.useMemo(() => SessionKit.roadmap({ isComplete: RuntimeKit.isComplete }), [session]);
7435
+ const byKey = React35.useMemo(() => {
7420
7436
  const m = {};
7421
7437
  rm.items.forEach((i) => {
7422
7438
  m[i.key] = i;
@@ -7425,7 +7441,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
7425
7441
  }, [rm]);
7426
7442
  const items = rm.items.filter((i) => (!project || i.project === project) && (!q || (i.label + " " + i.description + " " + (i.backend || "") + " " + i.key).toLowerCase().includes(q.toLowerCase())));
7427
7443
  const projects = [...new Set(rm.items.map((i) => i.project))];
7428
- React34.useEffect(() => {
7444
+ React35.useEffect(() => {
7429
7445
  let raf1 = 0, raf2 = 0;
7430
7446
  const place = () => {
7431
7447
  const box = scrollRef.current, mark = nowRef.current;
@@ -7453,19 +7469,19 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
7453
7469
  }, 0);
7454
7470
  const nextPhase = items.find((i) => !i.implemented);
7455
7471
  let lastPhase = null;
7456
- return /* @__PURE__ */ jsxs55("div", { className: "fd-stack", style: { gap: 16, maxWidth: 1e3 }, children: [
7457
- /* @__PURE__ */ jsxs55("div", { className: "fd-stack", style: { gap: 10 }, children: [
7472
+ return /* @__PURE__ */ jsxs56("div", { className: "fd-stack", style: { gap: 16, maxWidth: 1e3 }, children: [
7473
+ /* @__PURE__ */ jsxs56("div", { className: "fd-stack", style: { gap: 10 }, children: [
7458
7474
  /* @__PURE__ */ jsx60("span", { className: "fd-overline fd-muted", children: "Architecture" }),
7459
7475
  /* @__PURE__ */ jsx60("h1", { className: "fd-h1", style: { margin: 0 }, children: title }),
7460
7476
  /* @__PURE__ */ jsx60("p", { className: "fd-body fd-secondary fd-prose", style: { margin: 0 }, children: lede || "Every screen and feature in these tools is already designed and working against a simulated backend. This is the plan for connecting them to the real one \u2014 so the only work described here is server work." })
7461
7477
  ] }),
7462
- /* @__PURE__ */ jsxs55("div", { className: "fd-grid-stats is-thin", children: [
7478
+ /* @__PURE__ */ jsxs56("div", { className: "fd-grid-stats is-thin", children: [
7463
7479
  /* @__PURE__ */ jsx60(StatTile, { compact: true, label: "Wired", value: String(rm.shipped), sub: "of " + rm.items.length + " features" }),
7464
7480
  /* @__PURE__ */ jsx60(StatTile, { compact: true, label: "Remaining", value: String(rm.remaining), sub: "backend work" }),
7465
7481
  /* @__PURE__ */ jsx60(StatTile, { compact: true, label: "Est. effort", value: days ? days + " days" : "\u2014", sub: "sum of estimates, not calendar" }),
7466
7482
  /* @__PURE__ */ jsx60(StatTile, { compact: true, label: "Up next", value: nextPhase ? "Phase " + nextPhase.phase : "\u2014", sub: nextPhase ? nextPhase.phaseName : "all wired" })
7467
7483
  ] }),
7468
- /* @__PURE__ */ jsxs55("div", { className: "fd-row", style: { gap: 10, flexWrap: "wrap" }, children: [
7484
+ /* @__PURE__ */ jsxs56("div", { className: "fd-row", style: { gap: 10, flexWrap: "wrap" }, children: [
7469
7485
  /* @__PURE__ */ jsx60(Input, { icon: "magnifying-glass", placeholder: "Find a feature or a piece of backend work", value: q, onChange: (e) => setQ(e.target.value), style: { width: 300 } }),
7470
7486
  /* @__PURE__ */ jsx60(Select, { placeholder: "All projects", value: project, onChange: (e) => setProject(e.target.value), options: projects, style: { width: 190 } }),
7471
7487
  /* @__PURE__ */ jsx60("span", { style: { flex: 1 } }),
@@ -7492,23 +7508,23 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
7492
7508
  actions: null
7493
7509
  }
7494
7510
  ),
7495
- /* @__PURE__ */ jsx60("div", { className: "fd-rm", children: /* @__PURE__ */ jsx60("div", { className: "fd-rm-scroll", ref: scrollRef, children: /* @__PURE__ */ jsxs55("div", { className: "fd-rm-track", children: [
7511
+ /* @__PURE__ */ jsx60("div", { className: "fd-rm", children: /* @__PURE__ */ jsx60("div", { className: "fd-rm-scroll", ref: scrollRef, children: /* @__PURE__ */ jsxs56("div", { className: "fd-rm-track", children: [
7496
7512
  /* @__PURE__ */ jsx60("span", { className: "fd-rm-spine", children: /* @__PURE__ */ jsx60("span", { className: "fd-rm-spine-done", style: { height: items.length ? 100 * shippedShown / items.length + "%" : "0%" } }) }),
7497
7513
  items.map((item, n) => {
7498
7514
  const showPhase = item.phase !== lastPhase;
7499
7515
  lastPhase = item.phase;
7500
7516
  const inPhase = items.filter((i) => i.phase === item.phase).length;
7501
7517
  const isBoundary = n === firstPending;
7502
- return /* @__PURE__ */ jsxs55(React34.Fragment, { children: [
7503
- showPhase ? /* @__PURE__ */ jsxs55("div", { className: "fd-rm-era", children: [
7504
- /* @__PURE__ */ jsxs55("span", { className: "fd-row", style: { gap: 8, flexWrap: "wrap", alignItems: "baseline" }, children: [
7518
+ return /* @__PURE__ */ jsxs56(React35.Fragment, { children: [
7519
+ showPhase ? /* @__PURE__ */ jsxs56("div", { className: "fd-rm-era", children: [
7520
+ /* @__PURE__ */ jsxs56("span", { className: "fd-row", style: { gap: 8, flexWrap: "wrap", alignItems: "baseline" }, children: [
7505
7521
  /* @__PURE__ */ jsx60("span", { style: { fontWeight: 700 }, children: item.phase === 0 ? "Shipped" : "Phase " + item.phase + " \u2014 " + item.phaseName }),
7506
- item.phase === 0 ? null : /* @__PURE__ */ jsxs55("span", { className: "fd-mono", style: { opacity: 0.7, fontWeight: 400 }, children: [
7522
+ item.phase === 0 ? null : /* @__PURE__ */ jsxs56("span", { className: "fd-mono", style: { opacity: 0.7, fontWeight: 400 }, children: [
7507
7523
  fmtDate(item.phaseStart),
7508
7524
  " \u2013 ",
7509
7525
  fmtDate(item.date)
7510
7526
  ] }),
7511
- /* @__PURE__ */ jsxs55("span", { style: { opacity: 0.7, fontWeight: 400 }, children: [
7527
+ /* @__PURE__ */ jsxs56("span", { style: { opacity: 0.7, fontWeight: 400 }, children: [
7512
7528
  "\xB7 ",
7513
7529
  inPhase,
7514
7530
  " feature",
@@ -7517,13 +7533,13 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
7517
7533
  ] }),
7518
7534
  item.phaseWhy ? /* @__PURE__ */ jsx60("p", { className: "fd-rm-era-why", children: item.phaseWhy }) : null
7519
7535
  ] }) : null,
7520
- isBoundary ? /* @__PURE__ */ jsx60("div", { className: "fd-rm-now", ref: nowRef, children: /* @__PURE__ */ jsxs55("span", { className: "fd-rm-now-pill", children: [
7536
+ isBoundary ? /* @__PURE__ */ jsx60("div", { className: "fd-rm-now", ref: nowRef, children: /* @__PURE__ */ jsxs56("span", { className: "fd-rm-now-pill", children: [
7521
7537
  /* @__PURE__ */ jsx60("i", { className: "ph ph-map-pin" }),
7522
7538
  " You are here \u2014 everything above is wired"
7523
7539
  ] }) }) : null,
7524
- /* @__PURE__ */ jsxs55("div", { className: "fd-rm-row", children: [
7540
+ /* @__PURE__ */ jsxs56("div", { className: "fd-rm-row", children: [
7525
7541
  /* @__PURE__ */ jsx60("span", { className: "fd-rm-dot " + (item.implemented ? "is-shipped" : item.status === "next" ? "is-next" : "") }),
7526
- /* @__PURE__ */ jsxs55("div", { className: "fd-rm-date", children: [
7542
+ /* @__PURE__ */ jsxs56("div", { className: "fd-rm-date", children: [
7527
7543
  fmtDate(item.date),
7528
7544
  /* @__PURE__ */ jsx60("br", {}),
7529
7545
  /* @__PURE__ */ jsx60("span", { style: { opacity: 0.75 }, children: item.implemented ? "shipped" : "phase " + item.phase })
@@ -7534,7 +7550,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
7534
7550
  }),
7535
7551
  !items.length ? /* @__PURE__ */ jsx60("p", { className: "fd-body-sm fd-muted", children: "Nothing matches that filter." }) : null
7536
7552
  ] }) }) }),
7537
- /* @__PURE__ */ jsxs55("p", { className: "fd-body-sm fd-muted", style: { margin: 0 }, children: [
7553
+ /* @__PURE__ */ jsxs56("p", { className: "fd-body-sm fd-muted", style: { margin: 0 }, children: [
7538
7554
  "Derived from the feature-flag registry \u2014 each entry's status is its flag's ",
7539
7555
  /* @__PURE__ */ jsx60("code", { className: "fd-mono", children: "implemented" }),
7540
7556
  " field, so this page cannot drift from what the apps actually do."
@@ -7543,9 +7559,9 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
7543
7559
  }
7544
7560
 
7545
7561
  // src/components/platform/ComingSoon.tsx
7546
- import * as React35 from "react";
7562
+ import * as React36 from "react";
7547
7563
  import { createPortal as createPortal5 } from "react-dom";
7548
- import { Fragment as Fragment16, jsx as jsx61, jsxs as jsxs56 } from "react/jsx-runtime";
7564
+ import { Fragment as Fragment16, jsx as jsx61, jsxs as jsxs57 } from "react/jsx-runtime";
7549
7565
  var SOON_HOVERCARD_BASE = 220;
7550
7566
  var BYPASS_STORE = "fd.soon.bypass.v1";
7551
7567
  function readBypassed() {
@@ -7562,8 +7578,8 @@ function writeBypassed(list) {
7562
7578
  }
7563
7579
  }
7564
7580
  function useBypass(key) {
7565
- const [on, setOn] = React35.useState(() => !!key && readBypassed().indexOf(key) >= 0);
7566
- React35.useEffect(() => {
7581
+ const [on, setOn] = React36.useState(() => !!key && readBypassed().indexOf(key) >= 0);
7582
+ React36.useEffect(() => {
7567
7583
  setOn(!!key && readBypassed().indexOf(key) >= 0);
7568
7584
  }, [key]);
7569
7585
  const set = (next) => {
@@ -7576,43 +7592,43 @@ function useBypass(key) {
7576
7592
  return [on, set];
7577
7593
  }
7578
7594
  function SoonCard({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass }) {
7579
- return /* @__PURE__ */ jsxs56(Fragment16, { children: [
7580
- /* @__PURE__ */ jsxs56("span", { className: "fd-soon-badge", children: [
7595
+ return /* @__PURE__ */ jsxs57(Fragment16, { children: [
7596
+ /* @__PURE__ */ jsxs57("span", { className: "fd-soon-badge", children: [
7581
7597
  /* @__PURE__ */ jsx61("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" }),
7582
7598
  label
7583
7599
  ] }),
7584
7600
  detail ? /* @__PURE__ */ jsx61("span", { className: "fd-soon-detail", children: detail }) : null,
7585
- backend ? /* @__PURE__ */ jsxs56("span", { className: "fd-soon-backend", children: [
7601
+ backend ? /* @__PURE__ */ jsxs57("span", { className: "fd-soon-backend", children: [
7586
7602
  /* @__PURE__ */ jsx61("span", { className: "fd-overline", children: "Needs" }),
7587
7603
  " ",
7588
7604
  backend
7589
7605
  ] }) : null,
7590
- eta || effort || onRoadmap ? /* @__PURE__ */ jsxs56("span", { className: "fd-soon-meta", children: [
7591
- eta ? /* @__PURE__ */ jsxs56("span", { children: [
7606
+ eta || effort || onRoadmap ? /* @__PURE__ */ jsxs57("span", { className: "fd-soon-meta", children: [
7607
+ eta ? /* @__PURE__ */ jsxs57("span", { children: [
7592
7608
  /* @__PURE__ */ jsx61("i", { className: "ph ph-calendar-blank", "aria-hidden": "true" }),
7593
7609
  " ",
7594
7610
  eta
7595
7611
  ] }) : null,
7596
- effort ? /* @__PURE__ */ jsxs56("span", { children: [
7612
+ effort ? /* @__PURE__ */ jsxs57("span", { children: [
7597
7613
  /* @__PURE__ */ jsx61("i", { className: "ph ph-hourglass-medium", "aria-hidden": "true" }),
7598
7614
  " ",
7599
7615
  effort
7600
7616
  ] }) : null,
7601
- onRoadmap ? /* @__PURE__ */ jsxs56("button", { type: "button", className: "fd-soon-link", onClick: onRoadmap, children: [
7617
+ onRoadmap ? /* @__PURE__ */ jsxs57("button", { type: "button", className: "fd-soon-link", onClick: onRoadmap, children: [
7602
7618
  "See the roadmap ",
7603
7619
  /* @__PURE__ */ jsx61("i", { className: "ph ph-arrow-right", "aria-hidden": "true" })
7604
7620
  ] }) : null
7605
7621
  ] }) : null,
7606
- allowed ? /* @__PURE__ */ jsxs56("button", { type: "button", className: "fd-soon-view", onClick: onBypass, children: [
7622
+ allowed ? /* @__PURE__ */ jsxs57("button", { type: "button", className: "fd-soon-view", onClick: onBypass, children: [
7607
7623
  /* @__PURE__ */ jsx61("i", { className: "ph ph-eye", "aria-hidden": "true" }),
7608
7624
  " View and use it anyway"
7609
7625
  ] }) : null
7610
7626
  ] });
7611
7627
  }
7612
7628
  function useHoverCard(open) {
7613
- const anchor = React35.useRef(null);
7614
- const [pos, setPos] = React35.useState(null);
7615
- React35.useLayoutEffect(() => {
7629
+ const anchor = React36.useRef(null);
7630
+ const [pos, setPos] = React36.useState(null);
7631
+ React36.useLayoutEffect(() => {
7616
7632
  if (!open || !anchor.current) {
7617
7633
  setPos(null);
7618
7634
  return;
@@ -7664,7 +7680,7 @@ function ComingSoon({
7664
7680
  const tip = [label, detail, backend ? "Needs " + backend : null, eta ? "ETA " + eta : null, effort].filter(Boolean).join(" \xB7 ");
7665
7681
  if (inline) {
7666
7682
  if (allowed && bypassed) {
7667
- return /* @__PURE__ */ jsxs56("span", { className: ["fd-soon-inline-on", className].filter(Boolean).join(" "), ...rest, children: [
7683
+ return /* @__PURE__ */ jsxs57("span", { className: ["fd-soon-inline-on", className].filter(Boolean).join(" "), ...rest, children: [
7668
7684
  children,
7669
7685
  /* @__PURE__ */ jsx61(
7670
7686
  "button",
@@ -7699,19 +7715,19 @@ function ComingSoon({
7699
7715
  );
7700
7716
  }
7701
7717
  if (allowed && bypassed) {
7702
- return /* @__PURE__ */ jsxs56("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 14 }, ...rest, children: [
7703
- /* @__PURE__ */ jsxs56("div", { className: "fd-soon-bar", role: "status", children: [
7704
- /* @__PURE__ */ jsxs56("span", { className: "fd-soon-badge", children: [
7718
+ return /* @__PURE__ */ jsxs57("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 14 }, ...rest, children: [
7719
+ /* @__PURE__ */ jsxs57("div", { className: "fd-soon-bar", role: "status", children: [
7720
+ /* @__PURE__ */ jsxs57("span", { className: "fd-soon-badge", children: [
7705
7721
  /* @__PURE__ */ jsx61("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" }),
7706
7722
  "Unwired feature \u2014 you are using it anyway"
7707
7723
  ] }),
7708
7724
  /* @__PURE__ */ jsx61("span", { className: "fd-soon-bar-detail", children: "Every action here writes to the simulated backend, so nothing you do persists beyond this session." }),
7709
- /* @__PURE__ */ jsxs56("span", { className: "fd-soon-bar-actions", children: [
7710
- onRoadmap ? /* @__PURE__ */ jsxs56("button", { type: "button", className: "fd-soon-link", onClick: onRoadmap, children: [
7725
+ /* @__PURE__ */ jsxs57("span", { className: "fd-soon-bar-actions", children: [
7726
+ onRoadmap ? /* @__PURE__ */ jsxs57("button", { type: "button", className: "fd-soon-link", onClick: onRoadmap, children: [
7711
7727
  "Roadmap ",
7712
7728
  /* @__PURE__ */ jsx61("i", { className: "ph ph-arrow-right", "aria-hidden": "true" })
7713
7729
  ] }) : null,
7714
- /* @__PURE__ */ jsxs56("button", { type: "button", className: "fd-soon-link", onClick: () => setBypassed(false), children: [
7730
+ /* @__PURE__ */ jsxs57("button", { type: "button", className: "fd-soon-link", onClick: () => setBypassed(false), children: [
7715
7731
  /* @__PURE__ */ jsx61("i", { className: "ph ph-eye-slash", "aria-hidden": "true" }),
7716
7732
  " Re-blur"
7717
7733
  ] })
@@ -7720,7 +7736,7 @@ function ComingSoon({
7720
7736
  children
7721
7737
  ] });
7722
7738
  }
7723
- return /* @__PURE__ */ jsxs56("div", { className: ["fd-soon", className].filter(Boolean).join(" "), style: minHeight ? { minHeight } : void 0, ...rest, children: [
7739
+ return /* @__PURE__ */ jsxs57("div", { className: ["fd-soon", className].filter(Boolean).join(" "), style: minHeight ? { minHeight } : void 0, ...rest, children: [
7724
7740
  /* @__PURE__ */ jsx61("div", { className: "fd-soon-under", style: { filter: "blur(" + blur + "px) saturate(.62)" }, ...{ inert: "" }, "aria-hidden": "true", children }),
7725
7741
  /* @__PURE__ */ jsx61("div", { className: "fd-soon-veil" }),
7726
7742
  /* @__PURE__ */ jsx61("div", { className: "fd-soon-note", role: "note", children: /* @__PURE__ */ jsx61(
@@ -7739,10 +7755,10 @@ function ComingSoon({
7739
7755
  ] });
7740
7756
  }
7741
7757
  function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass, blur, tip, className, rest, children }) {
7742
- const [open, setOpen] = React35.useState(false);
7758
+ const [open, setOpen] = React36.useState(false);
7743
7759
  const [anchor, pos] = useHoverCard(open);
7744
7760
  const zIndex = useOverlayLayer(SOON_HOVERCARD_BASE);
7745
- const close = React35.useRef(null);
7761
+ const close = React36.useRef(null);
7746
7762
  const show = () => {
7747
7763
  if (close.current) {
7748
7764
  clearTimeout(close.current);
@@ -7758,10 +7774,10 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
7758
7774
  setOpen(false);
7759
7775
  }, 140);
7760
7776
  };
7761
- React35.useEffect(() => () => {
7777
+ React36.useEffect(() => () => {
7762
7778
  if (close.current) clearTimeout(close.current);
7763
7779
  }, []);
7764
- return /* @__PURE__ */ jsxs56(
7780
+ return /* @__PURE__ */ jsxs57(
7765
7781
  "span",
7766
7782
  {
7767
7783
  ref: anchor,
@@ -7826,10 +7842,10 @@ function formatEta(iso2) {
7826
7842
  var FormatEta = formatEta;
7827
7843
 
7828
7844
  // src/components/platform/Gate.tsx
7829
- import { jsx as jsx62, jsxs as jsxs57 } from "react/jsx-runtime";
7845
+ import { jsx as jsx62, jsxs as jsxs58 } from "react/jsx-runtime";
7830
7846
  function PermissionDenied({ permission, title, detail, compact: compact3 = false, className = "", ...rest }) {
7831
7847
  const need = Array.isArray(permission) ? permission : [permission].filter(Boolean);
7832
- return /* @__PURE__ */ jsxs57(
7848
+ return /* @__PURE__ */ jsxs58(
7833
7849
  "div",
7834
7850
  {
7835
7851
  className: ["fd-stack", className].filter(Boolean).join(" "),
@@ -7845,12 +7861,12 @@ function PermissionDenied({ permission, title, detail, compact: compact3 = false
7845
7861
  },
7846
7862
  ...rest,
7847
7863
  children: [
7848
- /* @__PURE__ */ jsxs57("span", { className: "fd-row", style: { gap: 8 }, children: [
7864
+ /* @__PURE__ */ jsxs58("span", { className: "fd-row", style: { gap: 8 }, children: [
7849
7865
  /* @__PURE__ */ jsx62("i", { className: "ph ph-lock-simple", style: { fontSize: 16, color: "var(--text-muted)" }, "aria-hidden": "true" }),
7850
7866
  /* @__PURE__ */ jsx62("span", { className: compact3 ? "fd-label-lg" : "fd-h3", children: title || "You do not have access to this" })
7851
7867
  ] }),
7852
7868
  /* @__PURE__ */ jsx62("p", { className: "fd-body-sm fd-secondary", style: { margin: 0, textWrap: "pretty" }, children: detail || "Your roles do not grant this. An administrator can change that from Admin \u2192 Users." }),
7853
- need.length ? /* @__PURE__ */ jsxs57("span", { className: "fd-row", style: { gap: 6, flexWrap: "wrap" }, children: [
7869
+ need.length ? /* @__PURE__ */ jsxs58("span", { className: "fd-row", style: { gap: 6, flexWrap: "wrap" }, children: [
7854
7870
  /* @__PURE__ */ jsx62("span", { className: "fd-overline fd-muted", children: "Requires" }),
7855
7871
  need.map((p) => /* @__PURE__ */ jsx62("code", { className: "fd-mono", style: {
7856
7872
  fontSize: 11.5,
@@ -7927,15 +7943,15 @@ function PermissionHint({ perm, children }) {
7927
7943
  }
7928
7944
 
7929
7945
  // src/components/platform/ModeSwitch.tsx
7930
- import * as React36 from "react";
7931
- import { Fragment as Fragment17, jsx as jsx63, jsxs as jsxs58 } from "react/jsx-runtime";
7946
+ import * as React37 from "react";
7947
+ import { Fragment as Fragment17, jsx as jsx63, jsxs as jsxs59 } from "react/jsx-runtime";
7932
7948
  var MODE_SWITCH_BASE = 140;
7933
7949
  function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog, onOpenSpec, summary }) {
7934
7950
  const mode2 = useRuntimeMode();
7935
- const [open, setOpen] = React36.useState(false);
7951
+ const [open, setOpen] = React37.useState(false);
7936
7952
  const zIndex = useOverlayLayer(MODE_SWITCH_BASE);
7937
- const ref = React36.useRef(null);
7938
- React36.useEffect(() => {
7953
+ const ref = React37.useRef(null);
7954
+ React37.useEffect(() => {
7939
7955
  if (!open) return;
7940
7956
  const away = (e) => {
7941
7957
  if (ref.current && !ref.current.contains(e.target)) setOpen(false);
@@ -7957,8 +7973,8 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
7957
7973
  RuntimeKit.setMode(next);
7958
7974
  setOpen(false);
7959
7975
  };
7960
- return /* @__PURE__ */ jsxs58("span", { style: { position: "relative", display: "inline-flex" }, ref, children: [
7961
- /* @__PURE__ */ jsxs58(
7976
+ return /* @__PURE__ */ jsxs59("span", { style: { position: "relative", display: "inline-flex" }, ref, children: [
7977
+ /* @__PURE__ */ jsxs59(
7962
7978
  "button",
7963
7979
  {
7964
7980
  type: "button",
@@ -7973,13 +7989,13 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
7973
7989
  ]
7974
7990
  }
7975
7991
  ),
7976
- open ? /* @__PURE__ */ jsx63(LayerProvider, { zIndex, children: /* @__PURE__ */ jsxs58("span", { className: "fd-view-enter fd-mode-pop", style: { zIndex }, children: [
7977
- /* @__PURE__ */ jsxs58("span", { className: "fd-row", style: { gap: 10, padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
7978
- /* @__PURE__ */ jsxs58("span", { className: "fd-badge " + (test ? "fd-badge-warning" : "fd-badge-neutral"), children: [
7992
+ open ? /* @__PURE__ */ jsx63(LayerProvider, { zIndex, children: /* @__PURE__ */ jsxs59("span", { className: "fd-view-enter fd-mode-pop", style: { zIndex }, children: [
7993
+ /* @__PURE__ */ jsxs59("span", { className: "fd-row", style: { gap: 10, padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
7994
+ /* @__PURE__ */ jsxs59("span", { className: "fd-badge " + (test ? "fd-badge-warning" : "fd-badge-neutral"), children: [
7979
7995
  /* @__PURE__ */ jsx63("i", { className: "ph " + (test ? "ph-flask" : "ph-lightning"), "aria-hidden": "true" }),
7980
7996
  test ? "Test mode" : "Live mode"
7981
7997
  ] }),
7982
- test ? /* @__PURE__ */ jsxs58("span", { className: "fd-body-sm fd-muted fd-mono", children: [
7998
+ test ? /* @__PURE__ */ jsxs59("span", { className: "fd-body-sm fd-muted fd-mono", children: [
7983
7999
  requestCount,
7984
8000
  " simulated request",
7985
8001
  requestCount === 1 ? "" : "s"
@@ -7987,10 +8003,10 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
7987
8003
  /* @__PURE__ */ jsx63("span", { style: { flex: 1 } }),
7988
8004
  test && onClearLog ? /* @__PURE__ */ jsx63("button", { type: "button", className: "fd-soon-link", onClick: onClearLog, children: "Clear" }) : null
7989
8005
  ] }),
7990
- /* @__PURE__ */ jsxs58("span", { style: { display: "block", padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
8006
+ /* @__PURE__ */ jsxs59("span", { style: { display: "block", padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
7991
8007
  /* @__PURE__ */ jsx63("span", { className: "fd-body-sm fd-secondary", style: { display: "block", textWrap: "pretty" }, children: test ? "Every feature is usable and nothing is obstructed, but no response comes from a real service \u2014 nothing you do here persists. Use this to review and demo the design." : "This is what a user would see today. " + s.incomplete + " of " + s.total + " features depend on backend work that is not wired yet, so they render under construction." }),
7992
- /* @__PURE__ */ jsxs58("span", { className: "fd-row", style: { gap: 8, marginTop: 10, flexWrap: "wrap" }, children: [
7993
- /* @__PURE__ */ jsxs58("span", { className: "fd-body-sm fd-muted fd-mono", children: [
8008
+ /* @__PURE__ */ jsxs59("span", { className: "fd-row", style: { gap: 8, marginTop: 10, flexWrap: "wrap" }, children: [
8009
+ /* @__PURE__ */ jsxs59("span", { className: "fd-body-sm fd-muted fd-mono", children: [
7994
8010
  s.endpointsWired,
7995
8011
  " endpoint",
7996
8012
  s.endpointsWired === 1 ? "" : "s",
@@ -8000,9 +8016,9 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
8000
8016
  s.total,
8001
8017
  " features complete"
8002
8018
  ] }),
8003
- onOpenSpec ? /* @__PURE__ */ jsxs58(Fragment17, { children: [
8019
+ onOpenSpec ? /* @__PURE__ */ jsxs59(Fragment17, { children: [
8004
8020
  /* @__PURE__ */ jsx63("span", { style: { flex: 1 } }),
8005
- /* @__PURE__ */ jsxs58("button", { type: "button", className: "fd-soon-link", onClick: () => {
8021
+ /* @__PURE__ */ jsxs59("button", { type: "button", className: "fd-soon-link", onClick: () => {
8006
8022
  setOpen(false);
8007
8023
  onOpenSpec();
8008
8024
  }, children: [
@@ -8012,18 +8028,18 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
8012
8028
  ] }) : null
8013
8029
  ] })
8014
8030
  ] }),
8015
- /* @__PURE__ */ jsxs58("span", { className: "fd-mode-choice", children: [
8016
- /* @__PURE__ */ jsxs58("button", { type: "button", className: "fd-mode-opt" + (!test ? " is-on" : ""), onClick: () => go("live"), children: [
8031
+ /* @__PURE__ */ jsxs59("span", { className: "fd-mode-choice", children: [
8032
+ /* @__PURE__ */ jsxs59("button", { type: "button", className: "fd-mode-opt" + (!test ? " is-on" : ""), onClick: () => go("live"), children: [
8017
8033
  /* @__PURE__ */ jsx63("i", { className: "ph ph-lightning", "aria-hidden": "true" }),
8018
- /* @__PURE__ */ jsxs58("span", { className: "fd-mode-opt-text", children: [
8034
+ /* @__PURE__ */ jsxs59("span", { className: "fd-mode-opt-text", children: [
8019
8035
  /* @__PURE__ */ jsx63("span", { className: "fd-mode-opt-title", children: "Live mode" }),
8020
8036
  /* @__PURE__ */ jsx63("span", { className: "fd-mode-opt-desc", children: "Incomplete features under construction" })
8021
8037
  ] }),
8022
8038
  !test ? /* @__PURE__ */ jsx63("i", { className: "ph ph-check", "aria-hidden": "true" }) : null
8023
8039
  ] }),
8024
- /* @__PURE__ */ jsxs58("button", { type: "button", className: "fd-mode-opt" + (test ? " is-on" : ""), onClick: () => go("test"), children: [
8040
+ /* @__PURE__ */ jsxs59("button", { type: "button", className: "fd-mode-opt" + (test ? " is-on" : ""), onClick: () => go("test"), children: [
8025
8041
  /* @__PURE__ */ jsx63("i", { className: "ph ph-flask", "aria-hidden": "true" }),
8026
- /* @__PURE__ */ jsxs58("span", { className: "fd-mode-opt-text", children: [
8042
+ /* @__PURE__ */ jsxs59("span", { className: "fd-mode-opt-text", children: [
8027
8043
  /* @__PURE__ */ jsx63("span", { className: "fd-mode-opt-title", children: "Test mode" }),
8028
8044
  /* @__PURE__ */ jsx63("span", { className: "fd-mode-opt-desc", children: "Everything usable, all data simulated" })
8029
8045
  ] }),
@@ -8037,13 +8053,13 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
8037
8053
  function TestModeBar({ onExit }) {
8038
8054
  const mode2 = useRuntimeMode();
8039
8055
  if (mode2 !== "test") return null;
8040
- return /* @__PURE__ */ jsxs58("div", { className: "fd-testbar", role: "status", children: [
8041
- /* @__PURE__ */ jsxs58("span", { className: "fd-badge fd-badge-warning", children: [
8056
+ return /* @__PURE__ */ jsxs59("div", { className: "fd-testbar", role: "status", children: [
8057
+ /* @__PURE__ */ jsxs59("span", { className: "fd-badge fd-badge-warning", children: [
8042
8058
  /* @__PURE__ */ jsx63("i", { className: "ph ph-flask", "aria-hidden": "true" }),
8043
8059
  "Test mode"
8044
8060
  ] }),
8045
8061
  /* @__PURE__ */ jsx63("span", { className: "fd-testbar-detail", children: "Every feature is unlocked and every response is simulated \u2014 nothing here persists." }),
8046
- /* @__PURE__ */ jsxs58("button", { type: "button", className: "fd-soon-link", onClick: () => onExit ? onExit() : RuntimeKit.setMode("live"), children: [
8062
+ /* @__PURE__ */ jsxs59("button", { type: "button", className: "fd-soon-link", onClick: () => onExit ? onExit() : RuntimeKit.setMode("live"), children: [
8047
8063
  /* @__PURE__ */ jsx63("i", { className: "ph ph-lightning", "aria-hidden": "true" }),
8048
8064
  " Back to live mode"
8049
8065
  ] })
@@ -8051,7 +8067,7 @@ function TestModeBar({ onExit }) {
8051
8067
  }
8052
8068
 
8053
8069
  // src/components/planner/ChannelMeta.tsx
8054
- import { jsx as jsx64, jsxs as jsxs59 } from "react/jsx-runtime";
8070
+ import { jsx as jsx64, jsxs as jsxs60 } from "react/jsx-runtime";
8055
8071
  var CHANNEL_WEIGHTS = {
8056
8072
  "OOH": 50,
8057
8073
  "DOOH": 50,
@@ -8106,7 +8122,7 @@ function ChannelTag({ channel, size = "md", showLabel = true, dot = false, weigh
8106
8122
  if (dot) {
8107
8123
  return /* @__PURE__ */ jsx64("span", { className: ["fd-chan-dot", className].filter(Boolean).join(" "), title: m.name, style: { background: m.color }, ...rest });
8108
8124
  }
8109
- return /* @__PURE__ */ jsxs59(
8125
+ return /* @__PURE__ */ jsxs60(
8110
8126
  "span",
8111
8127
  {
8112
8128
  className: ["fd-chan", size === "sm" ? "fd-chan-sm" : "", className].filter(Boolean).join(" "),
@@ -8123,7 +8139,7 @@ function ChannelTag({ channel, size = "md", showLabel = true, dot = false, weigh
8123
8139
  }
8124
8140
 
8125
8141
  // src/components/planner/SaturationDistribution.tsx
8126
- import { jsx as jsx65, jsxs as jsxs60 } from "react/jsx-runtime";
8142
+ import { jsx as jsx65, jsxs as jsxs61 } from "react/jsx-runtime";
8127
8143
  var BANDS2 = [
8128
8144
  { key: "weak", label: "Weak", n: 1, range: "< 50" },
8129
8145
  { key: "adequate", label: "Adequate", n: 2, range: "50\u2013100" },
@@ -8134,11 +8150,11 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
8134
8150
  const grouped = BANDS2.map((b) => ({ ...b, items: campuses.filter((c) => c.band === b.key) }));
8135
8151
  const tallest = Math.max(1, ...grouped.map((g) => g.items.length));
8136
8152
  const floor = BANDS2.find((b) => b.key === floorBand) || BANDS2[0];
8137
- return /* @__PURE__ */ jsxs60("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 16 }, children: [
8153
+ return /* @__PURE__ */ jsxs61("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 16 }, children: [
8138
8154
  /* @__PURE__ */ jsx65("div", { style: { display: "grid", gridTemplateColumns: "repeat(4,1fr)", gap: 12, alignItems: "end" }, children: grouped.map((g) => {
8139
8155
  const mark = "var(--csi-" + g.n + "-mark)";
8140
8156
  const active = selectedBand === g.key;
8141
- return /* @__PURE__ */ jsxs60(
8157
+ return /* @__PURE__ */ jsxs61(
8142
8158
  "button",
8143
8159
  {
8144
8160
  type: "button",
@@ -8154,13 +8170,13 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
8154
8170
  },
8155
8171
  c.name
8156
8172
  )) }),
8157
- /* @__PURE__ */ jsxs60("span", { className: "fd-row", style: { gap: 8, alignItems: "baseline" }, children: [
8173
+ /* @__PURE__ */ jsxs61("span", { className: "fd-row", style: { gap: 8, alignItems: "baseline" }, children: [
8158
8174
  /* @__PURE__ */ jsx65("span", { className: "fd-num-hero", style: { fontSize: 30, color: g.items.length ? "var(--text)" : "var(--text-disabled)" }, children: loading ? "\u2013" : g.items.length }),
8159
8175
  /* @__PURE__ */ jsx65("span", { className: "fd-meter", style: { gap: 2, color: mark }, "aria-hidden": "true", children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx65("span", { className: "fd-meter-seg" + (i <= g.n ? " is-on" : ""), style: { width: 4, height: 9 } }, i)) })
8160
8176
  ] }),
8161
- /* @__PURE__ */ jsxs60("span", { className: "fd-stack", style: { gap: 1 }, children: [
8177
+ /* @__PURE__ */ jsxs61("span", { className: "fd-stack", style: { gap: 1 }, children: [
8162
8178
  /* @__PURE__ */ jsx65("span", { className: "fd-label-lg", children: g.label }),
8163
- /* @__PURE__ */ jsxs60("span", { className: "fd-body-sm fd-muted", style: { fontSize: 11.5 }, children: [
8179
+ /* @__PURE__ */ jsxs61("span", { className: "fd-body-sm fd-muted", style: { fontSize: 11.5 }, children: [
8164
8180
  "CRP ",
8165
8181
  g.range
8166
8182
  ] })
@@ -8170,10 +8186,10 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
8170
8186
  g.key
8171
8187
  );
8172
8188
  }) }),
8173
- floorBand ? /* @__PURE__ */ jsxs60("div", { className: "fd-row", style: { gap: 10, padding: "12px 14px", borderRadius: "var(--r-md)", background: "var(--surface-2)", border: "1px solid var(--border)", flexWrap: "wrap" }, children: [
8189
+ floorBand ? /* @__PURE__ */ jsxs61("div", { className: "fd-row", style: { gap: 10, padding: "12px 14px", borderRadius: "var(--r-md)", background: "var(--surface-2)", border: "1px solid var(--border)", flexWrap: "wrap" }, children: [
8174
8190
  /* @__PURE__ */ jsx65("span", { className: "fd-meter", style: { gap: 2, color: "var(--csi-" + floor.n + "-mark)" }, "aria-hidden": "true", children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx65("span", { className: "fd-meter-seg" + (i <= floor.n ? " is-on" : ""), style: { width: 5, height: 12 } }, i)) }),
8175
- /* @__PURE__ */ jsxs60("span", { className: "fd-body-sm fd-secondary", style: { flex: 1, minWidth: 240 }, children: [
8176
- /* @__PURE__ */ jsxs60("strong", { style: { color: "var(--text)" }, children: [
8191
+ /* @__PURE__ */ jsxs61("span", { className: "fd-body-sm fd-secondary", style: { flex: 1, minWidth: 240 }, children: [
8192
+ /* @__PURE__ */ jsxs61("strong", { style: { color: "var(--text)" }, children: [
8177
8193
  "Plan floor ",
8178
8194
  floorScore
8179
8195
  ] }),
@@ -8184,8 +8200,8 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
8184
8200
  }
8185
8201
 
8186
8202
  // src/components/planner/MixGap.tsx
8187
- import * as React37 from "react";
8188
- import { Fragment as Fragment18, jsx as jsx66, jsxs as jsxs61 } from "react/jsx-runtime";
8203
+ import * as React38 from "react";
8204
+ import { Fragment as Fragment18, jsx as jsx66, jsxs as jsxs62 } from "react/jsx-runtime";
8189
8205
  var MIX_GAP_LAYOUT = {
8190
8206
  trackHeight: 30,
8191
8207
  barHeight: 20,
@@ -8199,18 +8215,18 @@ function mixGapOffset(value, max) {
8199
8215
  }
8200
8216
  function MixGap({ rows = [], loading = false, className = "" }) {
8201
8217
  const max = Math.max(1, ...rows.flatMap((r) => [r.target, r.realized]));
8202
- const [hover, setHover] = React37.useState(null);
8218
+ const [hover, setHover] = React38.useState(null);
8203
8219
  const toneOf = (gap) => gap >= -1 ? "ok" : gap >= -4 ? "warn" : "danger";
8204
8220
  const TONE = { ok: "var(--ok-solid)", warn: "var(--warn-solid)", danger: "var(--danger-solid)" };
8205
8221
  const { trackHeight, barHeight, targetWidth, labelGap } = MIX_GAP_LAYOUT;
8206
8222
  const barTop = (trackHeight - barHeight) / 2;
8207
- return /* @__PURE__ */ jsxs61("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 4 }, children: [
8208
- /* @__PURE__ */ jsxs61("div", { className: "fd-row", style: { gap: 16, justifyContent: "flex-end", paddingBottom: 6, flexWrap: "wrap" }, children: [
8209
- [["On target", TONE.ok], ["Close", TONE.warn], ["Short", TONE.danger]].map(([l, c]) => /* @__PURE__ */ jsxs61("span", { className: "fd-row fd-body-sm fd-muted", style: { gap: 6 }, children: [
8223
+ return /* @__PURE__ */ jsxs62("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 4 }, children: [
8224
+ /* @__PURE__ */ jsxs62("div", { className: "fd-row", style: { gap: 16, justifyContent: "flex-end", paddingBottom: 6, flexWrap: "wrap" }, children: [
8225
+ [["On target", TONE.ok], ["Close", TONE.warn], ["Short", TONE.danger]].map(([l, c]) => /* @__PURE__ */ jsxs62("span", { className: "fd-row fd-body-sm fd-muted", style: { gap: 6 }, children: [
8210
8226
  /* @__PURE__ */ jsx66("span", { style: { width: 14, height: 9, borderRadius: 2, background: c } }),
8211
8227
  l
8212
8228
  ] }, l)),
8213
- /* @__PURE__ */ jsxs61("span", { className: "fd-row fd-body-sm fd-muted", style: { gap: 6 }, children: [
8229
+ /* @__PURE__ */ jsxs62("span", { className: "fd-row fd-body-sm fd-muted", style: { gap: 6 }, children: [
8214
8230
  /* @__PURE__ */ jsx66("span", { "data-mixgap-legend-target": "", style: { width: targetWidth, height: 16, borderRadius: 1, background: MIX_GAP_TARGET_STRIPE } }),
8215
8231
  "Target"
8216
8232
  ] })
@@ -8220,7 +8236,7 @@ function MixGap({ rows = [], loading = false, className = "" }) {
8220
8236
  const tone = toneOf(gap);
8221
8237
  const tip = "Realized " + r.realized + "% vs " + r.target + "% target" + (gap < -1 ? " \xB7 " + Math.abs(gap).toFixed(0) + " pts short" : gap > 1 ? " \xB7 " + gap.toFixed(0) + " pts over" : " \xB7 on target") + (r.note ? " \u2014 " + r.note : "");
8222
8238
  const labelLeft = r.realized > r.target ? `calc(${mixGapOffset(r.realized, max)} + ${labelGap}px)` : `calc(${mixGapOffset(r.target, max)} + ${targetWidth / 2 + labelGap}px)`;
8223
- return /* @__PURE__ */ jsxs61(
8239
+ return /* @__PURE__ */ jsxs62(
8224
8240
  "div",
8225
8241
  {
8226
8242
  className: "fd-row",
@@ -8229,10 +8245,10 @@ function MixGap({ rows = [], loading = false, className = "" }) {
8229
8245
  onMouseLeave: () => setHover(null),
8230
8246
  children: [
8231
8247
  /* @__PURE__ */ jsx66("span", { style: { width: 128, flex: "none" }, children: /* @__PURE__ */ jsx66(ChannelTag, { channel: r.channel, size: "sm" }) }),
8232
- /* @__PURE__ */ jsx66("span", { style: { position: "relative", flex: 1, height: trackHeight, minWidth: 120 }, children: loading ? /* @__PURE__ */ jsx66("span", { className: "fd-skel", style: { position: "absolute", left: 0, right: 0, top: barTop, height: barHeight, borderRadius: 3 } }) : /* @__PURE__ */ jsxs61(Fragment18, { children: [
8248
+ /* @__PURE__ */ jsx66("span", { style: { position: "relative", flex: 1, height: trackHeight, minWidth: 120 }, children: loading ? /* @__PURE__ */ jsx66("span", { className: "fd-skel", style: { position: "absolute", left: 0, right: 0, top: barTop, height: barHeight, borderRadius: 3 } }) : /* @__PURE__ */ jsxs62(Fragment18, { children: [
8233
8249
  /* @__PURE__ */ jsx66("span", { "data-mixgap-bar": "", style: { position: "absolute", left: 0, top: barTop, height: barHeight, width: mixGapOffset(r.realized, max), background: TONE[tone], borderRadius: "2px 3px 3px 2px", transition: "width var(--dur-slow) var(--ease), background var(--dur-base) var(--ease)" } }),
8234
8250
  /* @__PURE__ */ jsx66("span", { "data-mixgap-target": "", style: { position: "absolute", left: `calc(${mixGapOffset(r.target, max)} - ${targetWidth / 2}px)`, top: 0, width: targetWidth, height: trackHeight, background: MIX_GAP_TARGET_STRIPE, borderRadius: 1 } }),
8235
- /* @__PURE__ */ jsxs61("span", { "data-mixgap-label": "", className: "fd-num", style: { position: "absolute", left: labelLeft, top: "50%", transform: "translateY(-50%)", fontSize: 12, color: "var(--text-muted)", whiteSpace: "nowrap" }, children: [
8251
+ /* @__PURE__ */ jsxs62("span", { "data-mixgap-label": "", className: "fd-num", style: { position: "absolute", left: labelLeft, top: "50%", transform: "translateY(-50%)", fontSize: 12, color: "var(--text-muted)", whiteSpace: "nowrap" }, children: [
8236
8252
  r.realized,
8237
8253
  "%"
8238
8254
  ] }),
@@ -8247,7 +8263,7 @@ function MixGap({ rows = [], loading = false, className = "" }) {
8247
8263
  }
8248
8264
 
8249
8265
  // src/components/planner/ChannelContribution.tsx
8250
- import { jsx as jsx67, jsxs as jsxs62 } from "react/jsx-runtime";
8266
+ import { jsx as jsx67, jsxs as jsxs63 } from "react/jsx-runtime";
8251
8267
  var money = (n) => "$" + Math.round(n).toLocaleString();
8252
8268
  function ChannelContribution({
8253
8269
  channels = [],
@@ -8263,8 +8279,8 @@ function ChannelContribution({
8263
8279
  const grand = total !== void 0 ? total : base + bonus;
8264
8280
  const pct = (v) => grand ? v / grand * 100 : 0;
8265
8281
  const spendTotal = channels.reduce((s, c) => s + Number(String(c.spend || 0).replace(/[^0-9.]/g, "")), 0);
8266
- return /* @__PURE__ */ jsxs62("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 16 }, children: [
8267
- loading ? /* @__PURE__ */ jsx67("span", { className: "fd-skel", style: { height: 34, borderRadius: "var(--r-sm)" } }) : /* @__PURE__ */ jsxs62("div", { className: "fd-row", style: { height: 34, borderRadius: "var(--r-sm)", overflow: "hidden", gap: 2, background: "var(--surface-3)" }, children: [
8282
+ return /* @__PURE__ */ jsxs63("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 16 }, children: [
8283
+ loading ? /* @__PURE__ */ jsx67("span", { className: "fd-skel", style: { height: 34, borderRadius: "var(--r-sm)" } }) : /* @__PURE__ */ jsxs63("div", { className: "fd-row", style: { height: 34, borderRadius: "var(--r-sm)", overflow: "hidden", gap: 2, background: "var(--surface-3)" }, children: [
8268
8284
  channels.map((c) => /* @__PURE__ */ jsx67(
8269
8285
  "span",
8270
8286
  {
@@ -8283,16 +8299,16 @@ function ChannelContribution({
8283
8299
  }
8284
8300
  ) : null
8285
8301
  ] }),
8286
- showTable ? /* @__PURE__ */ jsxs62("table", { className: "fd-table", style: { fontSize: "var(--body-sm-size)" }, children: [
8287
- /* @__PURE__ */ jsx67("thead", { children: /* @__PURE__ */ jsxs62("tr", { children: [
8302
+ showTable ? /* @__PURE__ */ jsxs63("table", { className: "fd-table", style: { fontSize: "var(--body-sm-size)" }, children: [
8303
+ /* @__PURE__ */ jsx67("thead", { children: /* @__PURE__ */ jsxs63("tr", { children: [
8288
8304
  /* @__PURE__ */ jsx67("th", { style: { width: "34%" }, children: "Channel" }),
8289
8305
  /* @__PURE__ */ jsx67("th", { style: { width: "16%" }, children: "Weight" }),
8290
8306
  /* @__PURE__ */ jsx67("th", { className: "is-num", style: { width: "16%" }, children: "Spend" }),
8291
8307
  /* @__PURE__ */ jsx67("th", { className: "is-num", style: { width: "17%" }, children: "CRP" }),
8292
8308
  /* @__PURE__ */ jsx67("th", { className: "is-num", style: { width: "17%" }, children: "Share" })
8293
8309
  ] }) }),
8294
- /* @__PURE__ */ jsxs62("tbody", { children: [
8295
- channels.map((c) => /* @__PURE__ */ jsxs62("tr", { children: [
8310
+ /* @__PURE__ */ jsxs63("tbody", { children: [
8311
+ channels.map((c) => /* @__PURE__ */ jsxs63("tr", { children: [
8296
8312
  /* @__PURE__ */ jsx67("td", { children: /* @__PURE__ */ jsx67(ChannelTag, { channel: c.name, size: "sm" }) }),
8297
8313
  /* @__PURE__ */ jsx67("td", { children: /* @__PURE__ */ jsx67(
8298
8314
  "span",
@@ -8305,17 +8321,17 @@ function ChannelContribution({
8305
8321
  ) }),
8306
8322
  /* @__PURE__ */ jsx67("td", { className: "is-num", children: c.spend }),
8307
8323
  /* @__PURE__ */ jsx67("td", { className: "is-num", children: c.crp.toFixed(1) }),
8308
- /* @__PURE__ */ jsxs62("td", { className: "is-num", children: [
8324
+ /* @__PURE__ */ jsxs63("td", { className: "is-num", children: [
8309
8325
  pct(c.crp).toFixed(0),
8310
8326
  "%"
8311
8327
  ] })
8312
8328
  ] }, c.name)),
8313
- bonus > 0 ? /* @__PURE__ */ jsxs62("tr", { children: [
8314
- /* @__PURE__ */ jsx67("td", { children: /* @__PURE__ */ jsxs62("span", { className: "fd-row", style: { gap: 9, fontWeight: 600 }, children: [
8329
+ bonus > 0 ? /* @__PURE__ */ jsxs63("tr", { children: [
8330
+ /* @__PURE__ */ jsx67("td", { children: /* @__PURE__ */ jsxs63("span", { className: "fd-row", style: { gap: 9, fontWeight: 600 }, children: [
8315
8331
  /* @__PURE__ */ jsx67("span", { style: { width: 9, height: 9, borderRadius: 2, background: "repeating-linear-gradient(135deg,var(--csi-3-mark) 0 3px,var(--csi-2-mark) 3px 6px)", flex: "none" } }),
8316
8332
  "Surround-sound bonus"
8317
8333
  ] }) }),
8318
- /* @__PURE__ */ jsx67("td", { children: /* @__PURE__ */ jsxs62("span", { className: "fd-badge fd-badge-success", style: { height: 20, fontSize: 11 }, children: [
8334
+ /* @__PURE__ */ jsx67("td", { children: /* @__PURE__ */ jsxs63("span", { className: "fd-badge fd-badge-success", style: { height: 20, fontSize: 11 }, children: [
8319
8335
  "+",
8320
8336
  bonusPct,
8321
8337
  "% of +",
@@ -8324,12 +8340,12 @@ function ChannelContribution({
8324
8340
  ] }) }),
8325
8341
  /* @__PURE__ */ jsx67("td", { className: "is-num fd-muted", children: "\u2014" }),
8326
8342
  /* @__PURE__ */ jsx67("td", { className: "is-num", children: bonus.toFixed(1) }),
8327
- /* @__PURE__ */ jsxs62("td", { className: "is-num", children: [
8343
+ /* @__PURE__ */ jsxs63("td", { className: "is-num", children: [
8328
8344
  pct(bonus).toFixed(0),
8329
8345
  "%"
8330
8346
  ] })
8331
8347
  ] }) : null,
8332
- /* @__PURE__ */ jsxs62("tr", { style: { background: "var(--surface-2)" }, children: [
8348
+ /* @__PURE__ */ jsxs63("tr", { style: { background: "var(--surface-2)" }, children: [
8333
8349
  /* @__PURE__ */ jsx67("td", { style: { fontWeight: 700 }, children: "Campus total" }),
8334
8350
  /* @__PURE__ */ jsx67("td", {}),
8335
8351
  /* @__PURE__ */ jsx67("td", { className: "is-num", style: { fontWeight: 700 }, children: money(spendTotal) }),
@@ -8342,8 +8358,8 @@ function ChannelContribution({
8342
8358
  }
8343
8359
 
8344
8360
  // src/components/planner/BudgetReallocator.tsx
8345
- import * as React38 from "react";
8346
- import { Fragment as Fragment19, jsx as jsx68, jsxs as jsxs63 } from "react/jsx-runtime";
8361
+ import * as React39 from "react";
8362
+ import { Fragment as Fragment19, jsx as jsx68, jsxs as jsxs64 } from "react/jsx-runtime";
8347
8363
  var bandFor = (crp) => crp >= 200 ? "dominant" : crp >= 100 ? "strong" : crp >= 50 ? "adequate" : "weak";
8348
8364
  function BudgetReallocator({
8349
8365
  campus,
@@ -8358,8 +8374,8 @@ function BudgetReallocator({
8358
8374
  onCancel,
8359
8375
  className = ""
8360
8376
  }) {
8361
- const [draft, setDraft] = React38.useState(spend);
8362
- React38.useEffect(() => setDraft(spend), [spend]);
8377
+ const [draft, setDraft] = React39.useState(spend);
8378
+ React39.useEffect(() => setDraft(spend), [spend]);
8363
8379
  const dirty = draft !== spend;
8364
8380
  const nextCrp = scoreFor ? scoreFor(draft) : crp;
8365
8381
  const nextBand = bandFor(nextCrp);
@@ -8374,21 +8390,21 @@ function BudgetReallocator({
8374
8390
  setDraft(spend);
8375
8391
  if (onCancel) onCancel();
8376
8392
  };
8377
- return /* @__PURE__ */ jsxs63(
8393
+ return /* @__PURE__ */ jsxs64(
8378
8394
  "div",
8379
8395
  {
8380
8396
  className: ["fd-stack", className].filter(Boolean).join(" "),
8381
8397
  style: { gap: 14, padding: 18, border: "1px solid " + (dirty ? "var(--border-brand)" : "var(--border)"), borderRadius: "var(--r-lg)", background: dirty ? "var(--surface-brand)" : "var(--surface)", color: "var(--text)", transition: "background var(--dur-base) var(--ease),border-color var(--dur-base) var(--ease)" },
8382
8398
  children: [
8383
- /* @__PURE__ */ jsxs63("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
8399
+ /* @__PURE__ */ jsxs64("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
8384
8400
  /* @__PURE__ */ jsx68("span", { className: "fd-h4", style: { flex: 1, minWidth: 140 }, children: campus }),
8385
8401
  /* @__PURE__ */ jsx68(CsiBadge, { band: nowBand, crp, size: "medium" }),
8386
- dirty ? /* @__PURE__ */ jsxs63(Fragment19, { children: [
8402
+ dirty ? /* @__PURE__ */ jsxs64(Fragment19, { children: [
8387
8403
  /* @__PURE__ */ jsx68("i", { className: "ph ph-arrow-right fd-muted", "aria-hidden": "true" }),
8388
8404
  /* @__PURE__ */ jsx68(CsiBadge, { band: nextBand, crp: nextCrp, size: "medium", preview: true })
8389
8405
  ] }) : null
8390
8406
  ] }),
8391
- /* @__PURE__ */ jsxs63("div", { className: "fd-slider", children: [
8407
+ /* @__PURE__ */ jsxs64("div", { className: "fd-slider", children: [
8392
8408
  /* @__PURE__ */ jsx68("span", { className: "fd-slider-fill", style: { width: pct + "%" } }),
8393
8409
  dirty ? /* @__PURE__ */ jsx68("span", { className: "fd-slider-chip", style: { left: pct + "%", background: delta < 0 ? "var(--danger-solid)" : "var(--ok-solid)" }, children: (delta < 0 ? "\u2212$" : "+$") + Math.abs(delta).toLocaleString() }) : null,
8394
8410
  /* @__PURE__ */ jsx68(
@@ -8407,8 +8423,8 @@ function BudgetReallocator({
8407
8423
  }
8408
8424
  )
8409
8425
  ] }),
8410
- /* @__PURE__ */ jsxs63("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
8411
- /* @__PURE__ */ jsxs63("span", { className: "fd-stack", style: { gap: 2, flex: 1, minWidth: 150 }, children: [
8426
+ /* @__PURE__ */ jsxs64("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
8427
+ /* @__PURE__ */ jsxs64("span", { className: "fd-stack", style: { gap: 2, flex: 1, minWidth: 150 }, children: [
8412
8428
  /* @__PURE__ */ jsx68("span", { className: "fd-num", style: { fontSize: 19, fontWeight: 700 }, children: "$" + draft.toLocaleString() }),
8413
8429
  /* @__PURE__ */ jsx68("span", { className: "fd-body-sm fd-muted", children: "Arrow keys step $100, shift+arrow $1,000. Escape reverts." })
8414
8430
  ] }),
@@ -8432,7 +8448,7 @@ function BudgetReallocator({
8432
8448
  }
8433
8449
 
8434
8450
  // src/components/planner/SurroundSound.tsx
8435
- import { jsx as jsx69, jsxs as jsxs64 } from "react/jsx-runtime";
8451
+ import { jsx as jsx69, jsxs as jsxs65 } from "react/jsx-runtime";
8436
8452
  var CATEGORIES = [
8437
8453
  { key: "ooh", label: "OOH", icon: "flag-banner", color: "var(--ch-ooh)" },
8438
8454
  { key: "transit", label: "Transit", icon: "bus", color: "var(--ch-transit)" },
@@ -8444,10 +8460,10 @@ var CATEGORIES = [
8444
8460
  function SurroundSound({ present = [], bonusPct = 0, bonusMax = 40, missedCost, className = "" }) {
8445
8461
  const earned = Math.max(0, Math.min(1, bonusPct / bonusMax));
8446
8462
  const single = present.length <= 2;
8447
- return /* @__PURE__ */ jsxs64("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 14 }, children: [
8463
+ return /* @__PURE__ */ jsxs65("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 14 }, children: [
8448
8464
  /* @__PURE__ */ jsx69("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: CATEGORIES.map((c) => {
8449
8465
  const on = present.includes(c.key);
8450
- return /* @__PURE__ */ jsxs64(
8466
+ return /* @__PURE__ */ jsxs65(
8451
8467
  "span",
8452
8468
  {
8453
8469
  title: c.label + (on ? " \u2014 present" : " \u2014 not bought"),
@@ -8460,10 +8476,10 @@ function SurroundSound({ present = [], bonusPct = 0, bonusMax = 40, missedCost,
8460
8476
  c.key
8461
8477
  );
8462
8478
  }) }),
8463
- /* @__PURE__ */ jsxs64("div", { className: "fd-stack", style: { gap: 8 }, children: [
8464
- /* @__PURE__ */ jsxs64("div", { className: "fd-row", style: { justifyContent: "space-between", gap: 12 }, children: [
8479
+ /* @__PURE__ */ jsxs65("div", { className: "fd-stack", style: { gap: 8 }, children: [
8480
+ /* @__PURE__ */ jsxs65("div", { className: "fd-row", style: { justifyContent: "space-between", gap: 12 }, children: [
8465
8481
  /* @__PURE__ */ jsx69("span", { className: "fd-label-lg", children: "Surround-sound bonus earned" }),
8466
- /* @__PURE__ */ jsxs64("span", { className: "fd-num", style: { color: single ? "var(--warn-text)" : "var(--csi-3-mark)", fontWeight: 700 }, children: [
8482
+ /* @__PURE__ */ jsxs65("span", { className: "fd-num", style: { color: single ? "var(--warn-text)" : "var(--csi-3-mark)", fontWeight: 700 }, children: [
8467
8483
  "+",
8468
8484
  bonusPct,
8469
8485
  "% of +",
@@ -8472,7 +8488,7 @@ function SurroundSound({ present = [], bonusPct = 0, bonusMax = 40, missedCost,
8472
8488
  ] })
8473
8489
  ] }),
8474
8490
  /* @__PURE__ */ jsx69("div", { style: { height: 8, borderRadius: "var(--r-xs)", background: "var(--surface-3)", overflow: "hidden" }, children: /* @__PURE__ */ jsx69("div", { style: { height: "100%", width: earned * 100 + "%", background: "var(--csi-3-mark)", borderRadius: "inherit", transition: "width var(--dur-slow) var(--ease)" } }) }),
8475
- /* @__PURE__ */ jsxs64("span", { className: "fd-body-sm fd-secondary", style: { textWrap: "pretty" }, children: [
8491
+ /* @__PURE__ */ jsxs65("span", { className: "fd-body-sm fd-secondary", style: { textWrap: "pretty" }, children: [
8476
8492
  present.length,
8477
8493
  " of 6 channel categories present.",
8478
8494
  " ",
@@ -8484,7 +8500,7 @@ function SurroundSound({ present = [], bonusPct = 0, bonusMax = 40, missedCost,
8484
8500
  }
8485
8501
 
8486
8502
  // src/components/planner/Importance.tsx
8487
- import { jsx as jsx70, jsxs as jsxs65 } from "react/jsx-runtime";
8503
+ import { jsx as jsx70, jsxs as jsxs66 } from "react/jsx-runtime";
8488
8504
  var IMPORTANCE_LEVELS = [
8489
8505
  { id: "nudge", rank: 1, label: "Nudge", icon: "feather", description: "Breaks a tie, nothing more." },
8490
8506
  { id: "lean", rank: 2, label: "Lean", icon: "arrow-bend-up-right", description: "A mild preference between otherwise equal options." },
@@ -8514,7 +8530,7 @@ function importanceTokens(id) {
8514
8530
  function ImportanceTag({ level, showLabel = true, size = "sm", className = "" }) {
8515
8531
  const lvl = importanceLevel(level);
8516
8532
  const t = importanceTokens(level);
8517
- return /* @__PURE__ */ jsxs65(
8533
+ return /* @__PURE__ */ jsxs66(
8518
8534
  "span",
8519
8535
  {
8520
8536
  className: ["fd-imp-tag", size === "md" ? "is-md" : "", className].filter(Boolean).join(" "),
@@ -8529,8 +8545,8 @@ function ImportanceTag({ level, showLabel = true, size = "sm", className = "" })
8529
8545
  }
8530
8546
 
8531
8547
  // src/components/planner/PreferenceMeter.tsx
8532
- import * as React39 from "react";
8533
- import { jsx as jsx71, jsxs as jsxs66 } from "react/jsx-runtime";
8548
+ import * as React40 from "react";
8549
+ import { jsx as jsx71, jsxs as jsxs67 } from "react/jsx-runtime";
8534
8550
  function preferenceScore(criteria) {
8535
8551
  const earned = criteria.reduce((n, c) => n + (Number(c.earned) || 0), 0);
8536
8552
  const weight = criteria.reduce((n, c) => n + (Number(c.weight) || 0), 0);
@@ -8559,7 +8575,7 @@ function PreferenceMeter({
8559
8575
  className = ""
8560
8576
  }) {
8561
8577
  const value = score == null ? preferenceScore(criteria) : score;
8562
- const segments = React39.useMemo(() => preferenceSegments(criteria), [criteria]);
8578
+ const segments = React40.useMemo(() => preferenceSegments(criteria), [criteria]);
8563
8579
  return /* @__PURE__ */ jsx71(
8564
8580
  ScoreMeter,
8565
8581
  {
@@ -8572,20 +8588,20 @@ function PreferenceMeter({
8572
8588
  placement,
8573
8589
  className,
8574
8590
  breakdownLabel: breakdownTitle,
8575
- breakdown: /* @__PURE__ */ jsxs66("div", { className: "fd-prefbreak", children: [
8576
- /* @__PURE__ */ jsxs66("div", { className: "fd-prefbreak-head", children: [
8591
+ breakdown: /* @__PURE__ */ jsxs67("div", { className: "fd-prefbreak", children: [
8592
+ /* @__PURE__ */ jsxs67("div", { className: "fd-prefbreak-head", children: [
8577
8593
  /* @__PURE__ */ jsx71("span", { className: "fd-label-lg", children: breakdownTitle }),
8578
8594
  /* @__PURE__ */ jsx71("span", { className: "fd-prefbreak-score fd-tabular", children: Math.round(value) })
8579
8595
  ] }),
8580
8596
  /* @__PURE__ */ jsx71("ul", { className: "fd-prefbreak-list", children: criteria.map((c) => {
8581
8597
  const pct = c.weight > 0 ? Math.round((Number(c.earned) || 0) / c.weight * 100) : 0;
8582
- return /* @__PURE__ */ jsxs66("li", { className: pct === 0 ? "fd-prefbreak-item is-unmet" : "fd-prefbreak-item", children: [
8598
+ return /* @__PURE__ */ jsxs67("li", { className: pct === 0 ? "fd-prefbreak-item is-unmet" : "fd-prefbreak-item", children: [
8583
8599
  /* @__PURE__ */ jsx71(ImportanceTag, { level: c.importance }),
8584
- /* @__PURE__ */ jsxs66("span", { className: "fd-prefbreak-text", children: [
8600
+ /* @__PURE__ */ jsxs67("span", { className: "fd-prefbreak-text", children: [
8585
8601
  /* @__PURE__ */ jsx71("span", { className: "fd-prefbreak-label", children: c.label }),
8586
8602
  c.note ? /* @__PURE__ */ jsx71("span", { className: "fd-prefbreak-note", children: c.note }) : null
8587
8603
  ] }),
8588
- /* @__PURE__ */ jsxs66("span", { className: "fd-prefbreak-val fd-tabular", children: [
8604
+ /* @__PURE__ */ jsxs67("span", { className: "fd-prefbreak-val fd-tabular", children: [
8589
8605
  Math.round(Number(c.earned) || 0),
8590
8606
  /* @__PURE__ */ jsx71("span", { className: "fd-prefbreak-sep", children: "/" }),
8591
8607
  Math.round(c.weight)
@@ -8598,10 +8614,10 @@ function PreferenceMeter({
8598
8614
  }
8599
8615
 
8600
8616
  // src/components/chat/AgentChatPanel.tsx
8601
- import * as React45 from "react";
8617
+ import * as React46 from "react";
8602
8618
 
8603
8619
  // src/components/chat/chatEngine.ts
8604
- import * as React40 from "react";
8620
+ import * as React41 from "react";
8605
8621
  var CHAT_UNAVAILABLE = "chat_unavailable";
8606
8622
  var JOB_PENDING = ["queued", "running"];
8607
8623
  var JOB_SUCCESS = ["completed", "recovered"];
@@ -8655,22 +8671,22 @@ function useChatEngine(opts) {
8655
8671
  onClear,
8656
8672
  onFeedback
8657
8673
  } = opts || {};
8658
- const [status, setStatus] = React40.useState("idle");
8659
- const [threadId, setThreadId] = React40.useState(null);
8660
- const [messages, setMessages] = React40.useState([]);
8661
- const [queue, setQueue] = React40.useState([]);
8662
- const [fatal, setFatal] = React40.useState(null);
8663
- const [busy, setBusy] = React40.useState(false);
8664
- const [turnStartedAt, setTurnStartedAt] = React40.useState(null);
8665
- const listRef = React40.useRef([]);
8666
- const queueRef = React40.useRef([]);
8667
- const busyRef = React40.useRef(false);
8668
- const stoppedRef = React40.useRef(false);
8669
- const abortRef = React40.useRef(null);
8670
- const serverCount = React40.useRef(0);
8671
- const threadRef = React40.useRef(null);
8672
- const mounted = React40.useRef(true);
8673
- React40.useEffect(() => {
8674
+ const [status, setStatus] = React41.useState("idle");
8675
+ const [threadId, setThreadId] = React41.useState(null);
8676
+ const [messages, setMessages] = React41.useState([]);
8677
+ const [queue, setQueue] = React41.useState([]);
8678
+ const [fatal, setFatal] = React41.useState(null);
8679
+ const [busy, setBusy] = React41.useState(false);
8680
+ const [turnStartedAt, setTurnStartedAt] = React41.useState(null);
8681
+ const listRef = React41.useRef([]);
8682
+ const queueRef = React41.useRef([]);
8683
+ const busyRef = React41.useRef(false);
8684
+ const stoppedRef = React41.useRef(false);
8685
+ const abortRef = React41.useRef(null);
8686
+ const serverCount = React41.useRef(0);
8687
+ const threadRef = React41.useRef(null);
8688
+ const mounted = React41.useRef(true);
8689
+ React41.useEffect(() => {
8674
8690
  mounted.current = true;
8675
8691
  return () => {
8676
8692
  mounted.current = false;
@@ -8692,14 +8708,14 @@ function useChatEngine(opts) {
8692
8708
  }
8693
8709
  return false;
8694
8710
  };
8695
- const loadThread = React40.useCallback(async (id) => {
8711
+ const loadThread = React41.useCallback(async (id) => {
8696
8712
  const data = await apiAdapter.getThread(id);
8697
8713
  const list = [...data && data.messages || []];
8698
8714
  serverCount.current = list.length;
8699
8715
  commit(list);
8700
8716
  return list;
8701
8717
  }, [apiAdapter]);
8702
- React40.useEffect(() => {
8718
+ React41.useEffect(() => {
8703
8719
  if (!apiAdapter) {
8704
8720
  setStatus("idle");
8705
8721
  setFatal(null);
@@ -8912,7 +8928,7 @@ function useChatEngine(opts) {
8912
8928
  await dispatchTurn(turn);
8913
8929
  }
8914
8930
  }
8915
- const send = React40.useCallback((text, attachments) => {
8931
+ const send = React41.useCallback((text, attachments) => {
8916
8932
  const body = (text || "").trim();
8917
8933
  if (!body && !(attachments && attachments.length)) return;
8918
8934
  if (status === "disconnected") return;
@@ -8922,7 +8938,7 @@ function useChatEngine(opts) {
8922
8938
  stoppedRef.current = false;
8923
8939
  drain();
8924
8940
  }, [status]);
8925
- const stop = React40.useCallback(() => {
8941
+ const stop = React41.useCallback(() => {
8926
8942
  stoppedRef.current = true;
8927
8943
  const ac = abortRef.current;
8928
8944
  if (ac) {
@@ -8941,11 +8957,11 @@ function useChatEngine(opts) {
8941
8957
  store.del(STORAGE_PREFIX + threadRef.current);
8942
8958
  }
8943
8959
  }, [apiAdapter]);
8944
- const removeQueued = React40.useCallback((id) => {
8960
+ const removeQueued = React41.useCallback((id) => {
8945
8961
  queueRef.current = queueRef.current.filter((t) => t.id !== id);
8946
8962
  setQueue(queueRef.current.slice());
8947
8963
  }, []);
8948
- const retry = React40.useCallback(() => {
8964
+ const retry = React41.useCallback(() => {
8949
8965
  const list = listRef.current;
8950
8966
  let at = -1;
8951
8967
  for (let i = list.length - 1; i >= 0; i--) if (list[i].role === "user") {
@@ -8961,19 +8977,19 @@ function useChatEngine(opts) {
8961
8977
  setQueue(queueRef.current.slice());
8962
8978
  drain();
8963
8979
  }, []);
8964
- const clear = React40.useCallback(() => {
8980
+ const clear = React41.useCallback(() => {
8965
8981
  commit([]);
8966
8982
  serverCount.current = 0;
8967
8983
  queueRef.current = [];
8968
8984
  setQueue([]);
8969
8985
  onClear && onClear();
8970
8986
  }, [onClear]);
8971
- const setFeedback = React40.useCallback((id, value) => {
8987
+ const setFeedback = React41.useCallback((id, value) => {
8972
8988
  patch(id, (m) => ({ feedback: m.feedback === value ? null : value }));
8973
8989
  const msg = listRef.current.find((m) => m.id === id);
8974
8990
  onFeedback && onFeedback({ message: msg, feedback: msg ? msg.feedback : value });
8975
8991
  }, [onFeedback]);
8976
- const reload = React40.useCallback(async () => {
8992
+ const reload = React41.useCallback(async () => {
8977
8993
  if (!threadRef.current) return;
8978
8994
  setStatus("loading");
8979
8995
  try {
@@ -9011,11 +9027,11 @@ var ChatKit = {
9011
9027
  };
9012
9028
 
9013
9029
  // src/components/chat/ChatTranscript.tsx
9014
- import * as React42 from "react";
9030
+ import * as React43 from "react";
9015
9031
 
9016
9032
  // src/components/chat/ChatTurn.tsx
9017
- import * as React41 from "react";
9018
- import { jsx as jsx72, jsxs as jsxs67 } from "react/jsx-runtime";
9033
+ import * as React42 from "react";
9034
+ import { jsx as jsx72, jsxs as jsxs68 } from "react/jsx-runtime";
9019
9035
  function JsonView({ value }) {
9020
9036
  let text;
9021
9037
  try {
@@ -9030,20 +9046,20 @@ function PacketCard({ packet, schema, render, onApply, applied }) {
9030
9046
  const s = schema || {};
9031
9047
  const invalid = packet.valid === false;
9032
9048
  const title = s.heading || packet.type;
9033
- return /* @__PURE__ */ jsxs67("section", { className: "fdc-packet" + (invalid ? " is-invalid" : ""), "aria-label": title, children: [
9034
- /* @__PURE__ */ jsxs67("header", { className: "fdc-packet-head", children: [
9049
+ return /* @__PURE__ */ jsxs68("section", { className: "fdc-packet" + (invalid ? " is-invalid" : ""), "aria-label": title, children: [
9050
+ /* @__PURE__ */ jsxs68("header", { className: "fdc-packet-head", children: [
9035
9051
  /* @__PURE__ */ jsx72("i", { className: "ph ph-" + (s.icon || "package"), "aria-hidden": "true" }),
9036
9052
  /* @__PURE__ */ jsx72("span", { className: "fdc-packet-title", children: title }),
9037
9053
  packet.repaired ? /* @__PURE__ */ jsx72("span", { className: "fdc-packet-badge", children: "Repaired" }) : null,
9038
9054
  invalid ? /* @__PURE__ */ jsx72("span", { className: "fdc-packet-badge is-danger", children: "Invalid" }) : null
9039
9055
  ] }),
9040
- invalid ? /* @__PURE__ */ jsxs67("div", { className: "fdc-packet-alert", role: "alert", children: [
9056
+ invalid ? /* @__PURE__ */ jsxs68("div", { className: "fdc-packet-alert", role: "alert", children: [
9041
9057
  /* @__PURE__ */ jsx72("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
9042
9058
  /* @__PURE__ */ jsx72("span", { children: packet.error || "This result failed validation and can\u2019t be applied." })
9043
9059
  ] }) : /* @__PURE__ */ jsx72("div", { className: "fdc-packet-body", children: render ? render(packet) : /* @__PURE__ */ jsx72(JsonView, { value: packet.payload }) }),
9044
- !invalid && onApply ? /* @__PURE__ */ jsxs67("footer", { className: "fdc-packet-foot", children: [
9060
+ !invalid && onApply ? /* @__PURE__ */ jsxs68("footer", { className: "fdc-packet-foot", children: [
9045
9061
  packet.repaired ? /* @__PURE__ */ jsx72("span", { className: "fdc-packet-note", children: "Corrected by the backend after a first attempt." }) : /* @__PURE__ */ jsx72("span", {}),
9046
- /* @__PURE__ */ jsxs67("button", { type: "button", className: "fd-btn fd-btn-primary fd-btn-sm", disabled: applied, onClick: () => onApply(packet), children: [
9062
+ /* @__PURE__ */ jsxs68("button", { type: "button", className: "fd-btn fd-btn-primary fd-btn-sm", disabled: applied, onClick: () => onApply(packet), children: [
9047
9063
  /* @__PURE__ */ jsx72("i", { className: "ph ph-" + (applied ? "check" : "arrow-square-in"), "aria-hidden": "true" }),
9048
9064
  applied ? "Applied" : s.applyLabel || "Apply"
9049
9065
  ] })
@@ -9051,13 +9067,13 @@ function PacketCard({ packet, schema, render, onApply, applied }) {
9051
9067
  ] });
9052
9068
  }
9053
9069
  function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
9054
- const [open, setOpen] = React41.useState(defaultOpen);
9070
+ const [open, setOpen] = React42.useState(defaultOpen);
9055
9071
  if (!text) return null;
9056
- return /* @__PURE__ */ jsxs67("div", { className: "fdc-think" + (open ? " is-open" : ""), children: [
9057
- /* @__PURE__ */ jsxs67("button", { type: "button", className: "fdc-think-head", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
9072
+ return /* @__PURE__ */ jsxs68("div", { className: "fdc-think" + (open ? " is-open" : ""), children: [
9073
+ /* @__PURE__ */ jsxs68("button", { type: "button", className: "fdc-think-head", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
9058
9074
  /* @__PURE__ */ jsx72("i", { className: "ph ph-brain", "aria-hidden": "true" }),
9059
9075
  /* @__PURE__ */ jsx72("span", { children: streaming ? "Thinking" : durationMs ? "Thought for " + formatDuration(durationMs) : "Thought process" }),
9060
- streaming ? /* @__PURE__ */ jsxs67("span", { className: "fdc-dots", "aria-hidden": "true", children: [
9076
+ streaming ? /* @__PURE__ */ jsxs68("span", { className: "fdc-dots", "aria-hidden": "true", children: [
9061
9077
  /* @__PURE__ */ jsx72("span", {}),
9062
9078
  /* @__PURE__ */ jsx72("span", {}),
9063
9079
  /* @__PURE__ */ jsx72("span", {})
@@ -9068,19 +9084,19 @@ function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
9068
9084
  ] });
9069
9085
  }
9070
9086
  function Citations({ items = [], onOpen }) {
9071
- const [open, setOpen] = React41.useState(false);
9087
+ const [open, setOpen] = React42.useState(false);
9072
9088
  if (!items.length) return null;
9073
- return /* @__PURE__ */ jsxs67("div", { className: "fdc-cites", children: [
9074
- /* @__PURE__ */ jsxs67("button", { type: "button", className: "fdc-cites-head", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
9089
+ return /* @__PURE__ */ jsxs68("div", { className: "fdc-cites", children: [
9090
+ /* @__PURE__ */ jsxs68("button", { type: "button", className: "fdc-cites-head", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
9075
9091
  /* @__PURE__ */ jsx72("i", { className: "ph ph-quotes", "aria-hidden": "true" }),
9076
- /* @__PURE__ */ jsxs67("span", { children: [
9092
+ /* @__PURE__ */ jsxs68("span", { children: [
9077
9093
  items.length,
9078
9094
  " source",
9079
9095
  items.length === 1 ? "" : "s"
9080
9096
  ] }),
9081
9097
  /* @__PURE__ */ jsx72("i", { className: "ph ph-caret-" + (open ? "up" : "down"), "aria-hidden": "true" })
9082
9098
  ] }),
9083
- open ? /* @__PURE__ */ jsx72("ol", { className: "fdc-cites-list", children: items.map((c, i) => /* @__PURE__ */ jsxs67("li", { children: [
9099
+ open ? /* @__PURE__ */ jsx72("ol", { className: "fdc-cites-list", children: items.map((c, i) => /* @__PURE__ */ jsxs68("li", { children: [
9084
9100
  /* @__PURE__ */ jsx72("span", { className: "fdc-cite-n fd-tabular", children: c.marker || i + 1 }),
9085
9101
  c.url ? /* @__PURE__ */ jsx72("a", { href: c.url, target: "_blank", rel: "noopener noreferrer", onClick: onOpen ? (e) => onOpen(c, e) : void 0, children: c.title || c.url }) : /* @__PURE__ */ jsx72("span", { children: c.title || "Source" }),
9086
9102
  c.detail ? /* @__PURE__ */ jsx72("span", { className: "fdc-cite-detail", children: c.detail }) : null
@@ -9094,24 +9110,24 @@ function clampText(text, max) {
9094
9110
  return (at > max * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
9095
9111
  }
9096
9112
  function MessageBody({ message: m, ctx }) {
9097
- const [expanded, setExpanded] = React41.useState(false);
9113
+ const [expanded, setExpanded] = React42.useState(false);
9098
9114
  const isUser = m.role === "user";
9099
9115
  const raw = m.text || "";
9100
9116
  const clamped = !expanded && !m.streaming ? clampText(raw, ctx.maxVisibleChars) : null;
9101
9117
  const body = clamped != null ? clamped : raw;
9102
9118
  const showMd = ctx.markdown && !isUser;
9103
- return /* @__PURE__ */ jsxs67("div", { className: "fdc-body", children: [
9119
+ return /* @__PURE__ */ jsxs68("div", { className: "fdc-body", children: [
9104
9120
  m.thinking && ctx.showThinking ? /* @__PURE__ */ jsx72(ThinkingBlock, { text: m.thinking, durationMs: m.thinkingMs, streaming: m.streaming && !m.text }) : null,
9105
9121
  m.steps && m.steps.length && ctx.showSteps ? /* @__PURE__ */ jsx72(StepList, { steps: m.steps, defaultOpen: m.steps.some((s) => s.status === "running"), dense: true }) : null,
9106
- body ? /* @__PURE__ */ jsxs67("div", { className: "fdc-text" + (isUser ? " is-user" : ""), children: [
9122
+ body ? /* @__PURE__ */ jsxs68("div", { className: "fdc-text" + (isUser ? " is-user" : ""), children: [
9107
9123
  showMd ? /* @__PURE__ */ jsx72(Markdown, { source: body, headingOffset: 2, codeProps: { collapseAfter: 22 }, renderCitation: ctx.renderCitation }) : /* @__PURE__ */ jsx72("div", { className: "fdc-plain", children: body }),
9108
9124
  m.streaming ? /* @__PURE__ */ jsx72("span", { className: "fdc-caret", "aria-hidden": "true" }) : null
9109
9125
  ] }) : null,
9110
- clamped != null ? /* @__PURE__ */ jsxs67("button", { type: "button", className: "fdc-more", onClick: () => setExpanded(true), children: [
9126
+ clamped != null ? /* @__PURE__ */ jsxs68("button", { type: "button", className: "fdc-more", onClick: () => setExpanded(true), children: [
9111
9127
  /* @__PURE__ */ jsx72("i", { className: "ph ph-caret-down", "aria-hidden": "true" }),
9112
9128
  "Show more",
9113
9129
  /* @__PURE__ */ jsx72("span", { className: "fdc-more-len fd-tabular", children: raw.length < 2e3 ? raw.length.toLocaleString() + " characters" : Math.round(raw.length / 100) / 10 + "k characters" })
9114
- ] }) : expanded && ctx.maxVisibleChars && raw.length > ctx.maxVisibleChars ? /* @__PURE__ */ jsxs67("button", { type: "button", className: "fdc-more", onClick: () => setExpanded(false), children: [
9130
+ ] }) : expanded && ctx.maxVisibleChars && raw.length > ctx.maxVisibleChars ? /* @__PURE__ */ jsxs68("button", { type: "button", className: "fdc-more", onClick: () => setExpanded(false), children: [
9115
9131
  /* @__PURE__ */ jsx72("i", { className: "ph ph-caret-up", "aria-hidden": "true" }),
9116
9132
  "Show less"
9117
9133
  ] }) : null,
@@ -9127,33 +9143,33 @@ function MessageBody({ message: m, ctx }) {
9127
9143
  }
9128
9144
  ) : null,
9129
9145
  m.citations && m.citations.length ? /* @__PURE__ */ jsx72(Citations, { items: m.citations, onOpen: ctx.onOpenCitation }) : null,
9130
- m.working ? /* @__PURE__ */ jsxs67("div", { className: "fdc-working", role: "status", children: [
9131
- /* @__PURE__ */ jsxs67("span", { className: "fdc-dots", "aria-hidden": "true", children: [
9146
+ m.working ? /* @__PURE__ */ jsxs68("div", { className: "fdc-working", role: "status", children: [
9147
+ /* @__PURE__ */ jsxs68("span", { className: "fdc-dots", "aria-hidden": "true", children: [
9132
9148
  /* @__PURE__ */ jsx72("span", {}),
9133
9149
  /* @__PURE__ */ jsx72("span", {}),
9134
9150
  /* @__PURE__ */ jsx72("span", {})
9135
9151
  ] }),
9136
- /* @__PURE__ */ jsxs67("span", { className: "fdc-working-label", children: [
9152
+ /* @__PURE__ */ jsxs68("span", { className: "fdc-working-label", children: [
9137
9153
  m.resumed ? "Resuming" : "Working",
9138
- m.job && m.job.status ? /* @__PURE__ */ jsxs67("span", { className: "fdc-working-job", children: [
9154
+ m.job && m.job.status ? /* @__PURE__ */ jsxs68("span", { className: "fdc-working-job", children: [
9139
9155
  " \xB7 ",
9140
9156
  m.job.status
9141
9157
  ] }) : null,
9142
- m.job && m.job.detail ? /* @__PURE__ */ jsxs67("span", { className: "fdc-working-job", children: [
9158
+ m.job && m.job.detail ? /* @__PURE__ */ jsxs68("span", { className: "fdc-working-job", children: [
9143
9159
  " \xB7 ",
9144
9160
  m.job.detail
9145
9161
  ] }) : null
9146
9162
  ] }),
9147
9163
  m.jobId ? /* @__PURE__ */ jsx72("span", { className: "fdc-working-id fd-mono", children: String(m.jobId).slice(0, 12) }) : null
9148
9164
  ] }) : null,
9149
- m.stopped ? /* @__PURE__ */ jsxs67("div", { className: "fdc-stopped", children: [
9165
+ m.stopped ? /* @__PURE__ */ jsxs68("div", { className: "fdc-stopped", children: [
9150
9166
  /* @__PURE__ */ jsx72("i", { className: "ph ph-stop-circle", "aria-hidden": "true" }),
9151
9167
  "Stopped"
9152
9168
  ] }) : null,
9153
- m.error ? /* @__PURE__ */ jsxs67("div", { className: "fdc-error", role: "alert", children: [
9169
+ m.error ? /* @__PURE__ */ jsxs68("div", { className: "fdc-error", role: "alert", children: [
9154
9170
  /* @__PURE__ */ jsx72("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
9155
9171
  /* @__PURE__ */ jsx72("span", { className: "fdc-error-text", children: ctx.errorCopy ? ctx.errorCopy(m.error) : m.error }),
9156
- m.retryable && ctx.onRetry ? /* @__PURE__ */ jsxs67("button", { type: "button", className: "fdc-error-retry", onClick: ctx.onRetry, children: [
9172
+ m.retryable && ctx.onRetry ? /* @__PURE__ */ jsxs68("button", { type: "button", className: "fdc-error-retry", onClick: ctx.onRetry, children: [
9157
9173
  /* @__PURE__ */ jsx72("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }),
9158
9174
  "Retry"
9159
9175
  ] }) : null
@@ -9161,9 +9177,9 @@ function MessageBody({ message: m, ctx }) {
9161
9177
  ] });
9162
9178
  }
9163
9179
  function useCopyRun() {
9164
- const [done, setDone] = React41.useState(false);
9165
- const t = React41.useRef(null);
9166
- React41.useEffect(() => () => {
9180
+ const [done, setDone] = React42.useState(false);
9181
+ const t = React42.useRef(null);
9182
+ React42.useEffect(() => () => {
9167
9183
  if (t.current) clearTimeout(t.current);
9168
9184
  }, []);
9169
9185
  return [done, (text) => {
@@ -9183,14 +9199,14 @@ function RunActions({ group, ctx }) {
9183
9199
  const isAssistant = group.role === "assistant";
9184
9200
  const fb = last.feedback;
9185
9201
  if (!ctx.messageActions) return null;
9186
- return /* @__PURE__ */ jsxs67("div", { className: "fdc-actions", role: "group", "aria-label": "Message actions", children: [
9187
- /* @__PURE__ */ jsxs67("button", { type: "button", className: "fdc-act" + (copied ? " is-done" : ""), onClick: () => copy(markdownToText(text)), "aria-label": "Copy message", children: [
9202
+ return /* @__PURE__ */ jsxs68("div", { className: "fdc-actions", role: "group", "aria-label": "Message actions", children: [
9203
+ /* @__PURE__ */ jsxs68("button", { type: "button", className: "fdc-act" + (copied ? " is-done" : ""), onClick: () => copy(markdownToText(text)), "aria-label": "Copy message", children: [
9188
9204
  /* @__PURE__ */ jsx72("i", { className: "ph ph-" + (copied ? "check" : "copy"), "aria-hidden": "true" }),
9189
9205
  /* @__PURE__ */ jsx72("span", { className: "fdc-act-label", children: copied ? "Copied" : "Copy" })
9190
9206
  ] }),
9191
9207
  isAssistant && ctx.onRetry ? /* @__PURE__ */ jsx72("button", { type: "button", className: "fdc-act", onClick: ctx.onRetry, "aria-label": "Retry this turn", children: /* @__PURE__ */ jsx72("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }) }) : null,
9192
9208
  group.role === "user" && ctx.onEdit ? /* @__PURE__ */ jsx72("button", { type: "button", className: "fdc-act", onClick: () => ctx.onEdit(last), "aria-label": "Edit and resend", children: /* @__PURE__ */ jsx72("i", { className: "ph ph-pencil-simple", "aria-hidden": "true" }) }) : null,
9193
- isAssistant && ctx.onFeedback ? /* @__PURE__ */ jsxs67(React41.Fragment, { children: [
9209
+ isAssistant && ctx.onFeedback ? /* @__PURE__ */ jsxs68(React42.Fragment, { children: [
9194
9210
  /* @__PURE__ */ jsx72("button", { type: "button", className: "fdc-act" + (fb === "up" ? " is-on" : ""), onClick: () => ctx.onFeedback(last.id, "up"), "aria-pressed": fb === "up", "aria-label": "Good response", children: /* @__PURE__ */ jsx72("i", { className: "ph ph-thumbs-up", "aria-hidden": "true" }) }),
9195
9211
  /* @__PURE__ */ jsx72("button", { type: "button", className: "fdc-act" + (fb === "down" ? " is-on" : ""), onClick: () => ctx.onFeedback(last.id, "down"), "aria-pressed": fb === "down", "aria-label": "Bad response", children: /* @__PURE__ */ jsx72("i", { className: "ph ph-thumbs-down", "aria-hidden": "true" }) })
9196
9212
  ] }) : null,
@@ -9202,14 +9218,14 @@ function ChatTurn({ group, ctx }) {
9202
9218
  const name = isUser ? ctx.userName : group.author || ctx.assistantName;
9203
9219
  const avatar = isUser ? ctx.userAvatar : ctx.assistantAvatar;
9204
9220
  const stamp = group.messages[0].timestamp;
9205
- return /* @__PURE__ */ jsxs67("article", { className: "fdc-turn is-" + group.role, "aria-label": String(name) + (stamp ? " at " + formatClock(stamp) : ""), children: [
9206
- /* @__PURE__ */ jsxs67("div", { className: "fdc-turn-head", children: [
9221
+ return /* @__PURE__ */ jsxs68("article", { className: "fdc-turn is-" + group.role, "aria-label": String(name) + (stamp ? " at " + formatClock(stamp) : ""), children: [
9222
+ /* @__PURE__ */ jsxs68("div", { className: "fdc-turn-head", children: [
9207
9223
  ctx.showAvatars ? /* @__PURE__ */ jsx72("span", { className: "fdc-avatar is-" + group.role, "aria-hidden": "true", children: avatar ? /* @__PURE__ */ jsx72("img", { src: avatar, alt: "" }) : isUser ? /* @__PURE__ */ jsx72("span", { className: "fdc-avatar-txt", children: (name || "You").slice(0, 1).toUpperCase() }) : /* @__PURE__ */ jsx72("i", { className: "ph ph-" + (ctx.assistantIcon || "sparkle") }) }) : null,
9208
9224
  /* @__PURE__ */ jsx72("span", { className: "fdc-who", children: name }),
9209
9225
  stamp ? /* @__PURE__ */ jsx72(RelativeTime, { className: "fdc-when", value: stamp }) : null,
9210
9226
  group.messages.some((m) => m.model) ? /* @__PURE__ */ jsx72("span", { className: "fdc-turn-model", children: group.messages.find((m) => m.model).model }) : null
9211
9227
  ] }),
9212
- /* @__PURE__ */ jsxs67("div", { className: "fdc-turn-body", children: [
9228
+ /* @__PURE__ */ jsxs68("div", { className: "fdc-turn-body", children: [
9213
9229
  group.messages.map((m) => /* @__PURE__ */ jsx72("div", { className: "fdc-msg" + (m.pending ? " is-pending" : ""), children: /* @__PURE__ */ jsx72(MessageBody, { message: m, ctx }) }, m.id)),
9214
9230
  /* @__PURE__ */ jsx72(RunActions, { group, ctx })
9215
9231
  ] })
@@ -9217,7 +9233,7 @@ function ChatTurn({ group, ctx }) {
9217
9233
  }
9218
9234
 
9219
9235
  // src/components/chat/ChatTranscript.tsx
9220
- import { jsx as jsx73, jsxs as jsxs68 } from "react/jsx-runtime";
9236
+ import { jsx as jsx73, jsxs as jsxs69 } from "react/jsx-runtime";
9221
9237
  var GROUP_WINDOW = 6e4;
9222
9238
  var STICK_PX = 100;
9223
9239
  function groupMessages(list) {
@@ -9252,9 +9268,9 @@ function Suggestions({ items = [], onPick }) {
9252
9268
  if (!items.length) return null;
9253
9269
  return /* @__PURE__ */ jsx73("div", { className: "fdc-suggest", children: items.map((s, i) => {
9254
9270
  const it = typeof s === "string" ? { label: s, text: s } : s;
9255
- return /* @__PURE__ */ jsxs68("button", { type: "button", className: "fdc-suggest-item", onClick: () => onPick && onPick(it.text || it.label), children: [
9271
+ return /* @__PURE__ */ jsxs69("button", { type: "button", className: "fdc-suggest-item", onClick: () => onPick && onPick(it.text || it.label), children: [
9256
9272
  it.icon ? /* @__PURE__ */ jsx73("i", { className: "ph ph-" + it.icon, "aria-hidden": "true" }) : null,
9257
- /* @__PURE__ */ jsxs68("span", { className: "fdc-suggest-text", children: [
9273
+ /* @__PURE__ */ jsxs69("span", { className: "fdc-suggest-text", children: [
9258
9274
  /* @__PURE__ */ jsx73("span", { className: "fdc-suggest-label", children: it.label }),
9259
9275
  it.description ? /* @__PURE__ */ jsx73("span", { className: "fdc-suggest-desc", children: it.description }) : null
9260
9276
  ] }),
@@ -9263,9 +9279,9 @@ function Suggestions({ items = [], onPick }) {
9263
9279
  }) });
9264
9280
  }
9265
9281
  function LoadingTurns() {
9266
- return /* @__PURE__ */ jsx73("div", { className: "fdc-skel", "aria-hidden": "true", children: [0, 1].map((i) => /* @__PURE__ */ jsxs68("div", { className: "fdc-skel-turn", children: [
9282
+ return /* @__PURE__ */ jsx73("div", { className: "fdc-skel", "aria-hidden": "true", children: [0, 1].map((i) => /* @__PURE__ */ jsxs69("div", { className: "fdc-skel-turn", children: [
9267
9283
  /* @__PURE__ */ jsx73("div", { className: "fd-skel fd-skel-circle", style: { width: 22, height: 22 } }),
9268
- /* @__PURE__ */ jsxs68("div", { className: "fdc-skel-lines", children: [
9284
+ /* @__PURE__ */ jsxs69("div", { className: "fdc-skel-lines", children: [
9269
9285
  /* @__PURE__ */ jsx73("div", { className: "fd-skel", style: { width: i ? "62%" : "44%", height: 11 } }),
9270
9286
  /* @__PURE__ */ jsx73("div", { className: "fd-skel", style: { width: i ? "94%" : "78%", height: 11 } }),
9271
9287
  /* @__PURE__ */ jsx73("div", { className: "fd-skel", style: { width: i ? "71%" : "56%", height: 11 } })
@@ -9285,10 +9301,10 @@ function ChatTranscript({
9285
9301
  renderEmpty,
9286
9302
  className = ""
9287
9303
  }) {
9288
- const scroller = React42.useRef(null);
9289
- const stick = React42.useRef(true);
9290
- const [pill, setPill] = React42.useState(0);
9291
- const seen = React42.useRef(0);
9304
+ const scroller = React43.useRef(null);
9305
+ const stick = React43.useRef(true);
9306
+ const [pill, setPill] = React43.useState(0);
9307
+ const seen = React43.useRef(0);
9292
9308
  const toBottom = (smooth) => {
9293
9309
  const el = scroller.current;
9294
9310
  if (!el) return;
@@ -9307,7 +9323,7 @@ function ChatTranscript({
9307
9323
  seen.current = messages.length;
9308
9324
  }
9309
9325
  };
9310
- React42.useLayoutEffect(() => {
9326
+ React43.useLayoutEffect(() => {
9311
9327
  const el = scroller.current;
9312
9328
  if (!el) return;
9313
9329
  if (stick.current) {
@@ -9315,7 +9331,7 @@ function ChatTranscript({
9315
9331
  seen.current = messages.length;
9316
9332
  } else setPill(Math.max(0, messages.length - seen.current));
9317
9333
  }, [messages]);
9318
- React42.useEffect(() => {
9334
+ React43.useEffect(() => {
9319
9335
  const el = scroller.current;
9320
9336
  const inner = el && el.firstChild;
9321
9337
  if (!el || !inner || typeof ResizeObserver === "undefined") return;
@@ -9325,21 +9341,21 @@ function ChatTranscript({
9325
9341
  ro.observe(inner);
9326
9342
  return () => ro.disconnect();
9327
9343
  }, []);
9328
- const groups = React42.useMemo(() => groupMessages(messages), [messages]);
9344
+ const groups = React43.useMemo(() => groupMessages(messages), [messages]);
9329
9345
  const empty = !messages.length && status === "ready";
9330
- return /* @__PURE__ */ jsxs68("div", { className: ["fdc-scroll", className].filter(Boolean).join(" "), ref: scroller, onScroll, children: [
9331
- /* @__PURE__ */ jsxs68("div", { className: "fdc-log", role: "log", "aria-label": "Conversation", children: [
9346
+ return /* @__PURE__ */ jsxs69("div", { className: ["fdc-scroll", className].filter(Boolean).join(" "), ref: scroller, onScroll, children: [
9347
+ /* @__PURE__ */ jsxs69("div", { className: "fdc-log", role: "log", "aria-label": "Conversation", children: [
9332
9348
  status === "loading" || status === "resolving" ? /* @__PURE__ */ jsx73(LoadingTurns, {}) : null,
9333
- status === "disconnected" ? /* @__PURE__ */ jsxs68("div", { className: "fdc-dead", children: [
9349
+ status === "disconnected" ? /* @__PURE__ */ jsxs69("div", { className: "fdc-dead", children: [
9334
9350
  /* @__PURE__ */ jsx73("span", { className: "fdc-dead-icon", children: /* @__PURE__ */ jsx73("i", { className: "ph ph-plugs", "aria-hidden": "true" }) }),
9335
9351
  /* @__PURE__ */ jsx73("h3", { className: "fdc-dead-title", children: ctx.deadTitle || "The assistant isn\u2019t reachable" }),
9336
9352
  /* @__PURE__ */ jsx73("p", { className: "fdc-dead-body", children: fatal === "chat_unavailable" ? "The service reported chat_unavailable. Nothing you type will be lost \u2014 reopen the panel once it\u2019s back." : "The thread couldn\u2019t be resolved" + (fatal ? " (" + fatal + ")" : "") + ". The composer stays disabled until it resolves." }),
9337
- ctx.onReconnect ? /* @__PURE__ */ jsxs68("button", { type: "button", className: "fd-btn fd-btn-secondary fd-btn-sm", onClick: ctx.onReconnect, children: [
9353
+ ctx.onReconnect ? /* @__PURE__ */ jsxs69("button", { type: "button", className: "fd-btn fd-btn-secondary fd-btn-sm", onClick: ctx.onReconnect, children: [
9338
9354
  /* @__PURE__ */ jsx73("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }),
9339
9355
  "Try again"
9340
9356
  ] }) : null
9341
9357
  ] }) : null,
9342
- empty ? renderEmpty ? renderEmpty() : /* @__PURE__ */ jsxs68("div", { className: "fdc-empty", children: [
9358
+ empty ? renderEmpty ? renderEmpty() : /* @__PURE__ */ jsxs69("div", { className: "fdc-empty", children: [
9343
9359
  /* @__PURE__ */ jsx73("span", { className: "fdc-empty-icon", children: /* @__PURE__ */ jsx73("i", { className: "ph ph-" + emptyIcon, "aria-hidden": "true" }) }),
9344
9360
  /* @__PURE__ */ jsx73("h3", { className: "fdc-empty-title", children: emptyTitle }),
9345
9361
  emptyDescription ? /* @__PURE__ */ jsx73("p", { className: "fdc-empty-body", children: emptyDescription }) : null,
@@ -9349,13 +9365,13 @@ function ChatTranscript({
9349
9365
  const prev = groups[i - 1];
9350
9366
  const k = dayKey(g.messages[0].timestamp);
9351
9367
  const showDay = !!k && (!prev || dayKey(prev.messages[0].timestamp) !== k);
9352
- return /* @__PURE__ */ jsxs68(React42.Fragment, { children: [
9368
+ return /* @__PURE__ */ jsxs69(React43.Fragment, { children: [
9353
9369
  showDay ? /* @__PURE__ */ jsx73("div", { className: "fdc-day", children: /* @__PURE__ */ jsx73("span", { children: dayLabel(k) }) }) : null,
9354
9370
  /* @__PURE__ */ jsx73(ChatTurn, { group: g, ctx })
9355
9371
  ] }, g.key || i);
9356
9372
  })
9357
9373
  ] }),
9358
- pill ? /* @__PURE__ */ jsxs68("button", { type: "button", className: "fdc-pill", onClick: () => toBottom(true), children: [
9374
+ pill ? /* @__PURE__ */ jsxs69("button", { type: "button", className: "fdc-pill", onClick: () => toBottom(true), children: [
9359
9375
  /* @__PURE__ */ jsx73("i", { className: "ph ph-arrow-down", "aria-hidden": "true" }),
9360
9376
  pill,
9361
9377
  " new message",
@@ -9366,8 +9382,8 @@ function ChatTranscript({
9366
9382
  var TranscriptKit = { groupMessages };
9367
9383
 
9368
9384
  // src/components/chat/ChatComposer.tsx
9369
- import * as React43 from "react";
9370
- import { jsx as jsx74, jsxs as jsxs69 } from "react/jsx-runtime";
9385
+ import * as React44 from "react";
9386
+ import { jsx as jsx74, jsxs as jsxs70 } from "react/jsx-runtime";
9371
9387
  function ChatComposer({
9372
9388
  onSubmit,
9373
9389
  onStop,
@@ -9394,17 +9410,17 @@ function ChatComposer({
9394
9410
  onReject,
9395
9411
  onOpenAttachment
9396
9412
  }) {
9397
- const [text, setText] = React43.useState(draft || "");
9398
- const [trigger, setTrigger] = React43.useState(null);
9399
- const [mentionItems, setMentionItems] = React43.useState([]);
9400
- const [listening, setListening] = React43.useState(false);
9401
- const [notice, setNotice] = React43.useState(null);
9402
- const editor = React43.useRef(null);
9403
- const wrap = React43.useRef(null);
9404
- const stopVoice = React43.useRef(null);
9413
+ const [text, setText] = React44.useState(draft || "");
9414
+ const [trigger, setTrigger] = React44.useState(null);
9415
+ const [mentionItems, setMentionItems] = React44.useState([]);
9416
+ const [listening, setListening] = React44.useState(false);
9417
+ const [notice, setNotice] = React44.useState(null);
9418
+ const editor = React44.useRef(null);
9419
+ const wrap = React44.useRef(null);
9420
+ const stopVoice = React44.useRef(null);
9405
9421
  const staged = useStagedFiles(fileUploadHandler, { onError: () => {
9406
9422
  } });
9407
- React43.useEffect(() => {
9423
+ React44.useEffect(() => {
9408
9424
  if (draft != null && draft !== text) setText(draft);
9409
9425
  }, [draft]);
9410
9426
  const change = (v) => {
@@ -9438,7 +9454,7 @@ function ChatComposer({
9438
9454
  e.preventDefault();
9439
9455
  staged.add(found.files);
9440
9456
  };
9441
- React43.useEffect(() => {
9457
+ React44.useEffect(() => {
9442
9458
  if (!trigger || trigger.type !== "mention" || !mentionSources) {
9443
9459
  setMentionItems([]);
9444
9460
  return;
@@ -9456,7 +9472,7 @@ function ChatComposer({
9456
9472
  const q = (trigger.query || "").toLowerCase();
9457
9473
  setMentionItems(mentionSources.filter((m) => !q || (m.label + " " + (m.description || "")).toLowerCase().includes(q)));
9458
9474
  }, [trigger, mentionSources]);
9459
- const slashItems = React43.useMemo(() => {
9475
+ const slashItems = React44.useMemo(() => {
9460
9476
  if (!trigger || trigger.type !== "slash" || !slashCommands) return [];
9461
9477
  const q = (trigger.query || "").toLowerCase();
9462
9478
  return slashCommands.filter((c) => !q || (c.id + " " + c.label + " " + (c.description || "")).toLowerCase().includes(q));
@@ -9533,8 +9549,8 @@ function ChatComposer({
9533
9549
  stopVoice.current = typeof res === "function" ? res : () => {
9534
9550
  };
9535
9551
  };
9536
- return /* @__PURE__ */ jsxs69("div", { className: "fdc-composer" + (disabled ? " is-disabled" : "") + (narrow ? " is-narrow" : ""), children: [
9537
- queue.length ? /* @__PURE__ */ jsx74("div", { className: "fdc-queue", "aria-label": "Queued messages", children: queue.map((q) => /* @__PURE__ */ jsxs69("div", { className: "fdc-queue-row", children: [
9552
+ return /* @__PURE__ */ jsxs70("div", { className: "fdc-composer" + (disabled ? " is-disabled" : "") + (narrow ? " is-narrow" : ""), children: [
9553
+ queue.length ? /* @__PURE__ */ jsx74("div", { className: "fdc-queue", "aria-label": "Queued messages", children: queue.map((q) => /* @__PURE__ */ jsxs70("div", { className: "fdc-queue-row", children: [
9538
9554
  /* @__PURE__ */ jsx74("i", { className: "ph ph-clock-countdown", "aria-hidden": "true" }),
9539
9555
  /* @__PURE__ */ jsx74("span", { className: "fdc-queue-text", children: q.text || (q.attachments ? q.attachments.length + " file(s)" : "") }),
9540
9556
  onRemoveQueued ? /* @__PURE__ */ jsx74("button", { type: "button", className: "fdc-queue-x", onClick: () => onRemoveQueued(q.id), "aria-label": "Remove queued message", children: /* @__PURE__ */ jsx74("i", { className: "ph ph-x", "aria-hidden": "true" }) }) : null
@@ -9554,7 +9570,7 @@ function ChatComposer({
9554
9570
  disabled: !fileUploadHandler || disabled,
9555
9571
  label: "Drop to attach",
9556
9572
  hint: acceptFiles ? acceptFiles.replace(/,/g, " \xB7 ") : void 0,
9557
- children: /* @__PURE__ */ jsxs69("div", { ref: wrap, className: "fdc-field-inner", children: [
9573
+ children: /* @__PURE__ */ jsxs70("div", { ref: wrap, className: "fdc-field-inner", children: [
9558
9574
  staged.items.length ? /* @__PURE__ */ jsx74("div", { className: "fdc-staged", children: /* @__PURE__ */ jsx74(FileStrip, { files: staged.items, size: narrow ? 60 : 68, onRemove: staged.remove, onRetry: staged.retry, onOpen: onOpenAttachment }) }) : null,
9559
9575
  /* @__PURE__ */ jsx74(
9560
9576
  MarkdownEditor,
@@ -9575,20 +9591,20 @@ function ChatComposer({
9575
9591
  ariaLabel: "Message"
9576
9592
  }
9577
9593
  ),
9578
- /* @__PURE__ */ jsxs69("div", { className: "fdc-tools", children: [
9594
+ /* @__PURE__ */ jsxs70("div", { className: "fdc-tools", children: [
9579
9595
  fileUploadHandler ? /* @__PURE__ */ jsx74(FilePickButton, { onFiles: staged.add, onReject: (r) => flash(r[0].message), accept: acceptFiles, maxFileSize, label: "Attach files", icon: "plus" }) : null,
9580
9596
  voiceHandler ? /* @__PURE__ */ jsx74("button", { type: "button", className: "fd-attachbtn" + (listening ? " is-live" : ""), onClick: voice, "aria-pressed": listening, "aria-label": listening ? "Stop dictation" : "Dictate", children: /* @__PURE__ */ jsx74("i", { className: "ph ph-" + (listening ? "waveform" : "microphone"), "aria-hidden": "true" }) }) : null,
9581
9597
  toolbarExtras,
9582
9598
  /* @__PURE__ */ jsx74("span", { className: "fdc-tools-gap" }),
9583
- maxLength && text.length > maxLength * 0.6 ? /* @__PURE__ */ jsxs69("span", { className: "fdc-count fd-tabular" + (text.length > maxLength * 0.95 ? " is-hot" : ""), children: [
9599
+ maxLength && text.length > maxLength * 0.6 ? /* @__PURE__ */ jsxs70("span", { className: "fdc-count fd-tabular" + (text.length > maxLength * 0.95 ? " is-hot" : ""), children: [
9584
9600
  text.length,
9585
9601
  "/",
9586
9602
  maxLength
9587
9603
  ] }) : null,
9588
- busy ? /* @__PURE__ */ jsxs69("button", { type: "button", className: "fdc-stop", onClick: onStop, "aria-label": "Stop generating", children: [
9604
+ busy ? /* @__PURE__ */ jsxs70("button", { type: "button", className: "fdc-stop", onClick: onStop, "aria-label": "Stop generating", children: [
9589
9605
  /* @__PURE__ */ jsx74("i", { className: "ph ph-stop-circle", "aria-hidden": "true" }),
9590
9606
  /* @__PURE__ */ jsx74("span", { children: "Stop" })
9591
- ] }) : /* @__PURE__ */ jsxs69("button", { type: "button", className: "fdc-send", onClick: submit, disabled: !canSend, "aria-label": "Send message", children: [
9607
+ ] }) : /* @__PURE__ */ jsxs70("button", { type: "button", className: "fdc-send", onClick: submit, disabled: !canSend, "aria-label": "Send message", children: [
9592
9608
  /* @__PURE__ */ jsx74("i", { className: "ph ph-paper-plane-right", "aria-hidden": "true" }),
9593
9609
  /* @__PURE__ */ jsx74("span", { className: "fdc-send-label", children: "Send" })
9594
9610
  ] })
@@ -9596,7 +9612,7 @@ function ChatComposer({
9596
9612
  ] })
9597
9613
  }
9598
9614
  ),
9599
- notice ? /* @__PURE__ */ jsxs69("div", { className: "fdc-notice", role: "status", children: [
9615
+ notice ? /* @__PURE__ */ jsxs70("div", { className: "fdc-notice", role: "status", children: [
9600
9616
  /* @__PURE__ */ jsx74("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
9601
9617
  notice
9602
9618
  ] }) : null,
@@ -9630,12 +9646,12 @@ function ChatComposer({
9630
9646
  }
9631
9647
 
9632
9648
  // src/components/chat/ChatSessionBar.tsx
9633
- import * as React44 from "react";
9634
- import { jsx as jsx75, jsxs as jsxs70 } from "react/jsx-runtime";
9649
+ import * as React45 from "react";
9650
+ import { jsx as jsx75, jsxs as jsxs71 } from "react/jsx-runtime";
9635
9651
  var compact2 = meterFormats.compact;
9636
9652
  function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extras }) {
9637
- const [open, setOpen] = React44.useState(false);
9638
- const anchor = React44.useRef(null);
9653
+ const [open, setOpen] = React45.useState(false);
9654
+ const anchor = React45.useRef(null);
9639
9655
  const stats = sessionStats || null;
9640
9656
  const cu = contextUsage || null;
9641
9657
  const limits = usageLimits || null;
@@ -9650,9 +9666,9 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
9650
9666
  if (stats && stats.runningTasks) bits.push(stats.runningTasks + " running task" + (stats.runningTasks === 1 ? "" : "s"));
9651
9667
  if (cu) bits.push(pct + "% context");
9652
9668
  const expandable = !!(cu || limits);
9653
- return /* @__PURE__ */ jsxs70(React44.Fragment, { children: [
9654
- /* @__PURE__ */ jsxs70("div", { className: "fdc-bar", children: [
9655
- /* @__PURE__ */ jsxs70(
9669
+ return /* @__PURE__ */ jsxs71(React45.Fragment, { children: [
9670
+ /* @__PURE__ */ jsxs71("div", { className: "fdc-bar", children: [
9671
+ /* @__PURE__ */ jsxs71(
9656
9672
  "button",
9657
9673
  {
9658
9674
  type: "button",
@@ -9682,14 +9698,14 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
9682
9698
  maxHeight: 460,
9683
9699
  padded: true,
9684
9700
  label: "Usage",
9685
- footer: onClear ? /* @__PURE__ */ jsxs70("button", { type: "button", className: "fdc-usage-clear", onClick: () => {
9701
+ footer: onClear ? /* @__PURE__ */ jsxs71("button", { type: "button", className: "fdc-usage-clear", onClick: () => {
9686
9702
  setOpen(false);
9687
9703
  onClear();
9688
9704
  }, children: [
9689
9705
  /* @__PURE__ */ jsx75("i", { className: "ph ph-trash", "aria-hidden": "true" }),
9690
9706
  "Clear conversation"
9691
9707
  ] }) : void 0,
9692
- children: /* @__PURE__ */ jsxs70("div", { className: "fdc-usage", children: [
9708
+ children: /* @__PURE__ */ jsxs71("div", { className: "fdc-usage", children: [
9693
9709
  cu ? /* @__PURE__ */ jsx75("section", { className: "fdc-usage-sec", children: /* @__PURE__ */ jsx75(
9694
9710
  SegmentedMeter,
9695
9711
  {
@@ -9702,7 +9718,7 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
9702
9718
  remainderLabel: "Free"
9703
9719
  }
9704
9720
  ) }) : null,
9705
- limits && limits.length ? /* @__PURE__ */ jsxs70("section", { className: "fdc-usage-sec", children: [
9721
+ limits && limits.length ? /* @__PURE__ */ jsxs71("section", { className: "fdc-usage-sec", children: [
9706
9722
  /* @__PURE__ */ jsx75("h4", { className: "fdc-usage-h", children: "Usage limits" }),
9707
9723
  /* @__PURE__ */ jsx75("div", { className: "fdc-usage-rows", children: limits.map((l) => /* @__PURE__ */ jsx75(
9708
9724
  QuotaRow,
@@ -9714,23 +9730,23 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
9714
9730
  l.id
9715
9731
  )) })
9716
9732
  ] }) : null,
9717
- stats ? /* @__PURE__ */ jsxs70("section", { className: "fdc-usage-sec fdc-usage-stats", children: [
9718
- stats.elapsedMs ? /* @__PURE__ */ jsxs70("div", { children: [
9733
+ stats ? /* @__PURE__ */ jsxs71("section", { className: "fdc-usage-sec fdc-usage-stats", children: [
9734
+ stats.elapsedMs ? /* @__PURE__ */ jsxs71("div", { children: [
9719
9735
  /* @__PURE__ */ jsx75("span", { children: "Session" }),
9720
9736
  /* @__PURE__ */ jsx75("b", { className: "fd-tabular", children: formatDuration(stats.elapsedMs) })
9721
9737
  ] }) : null,
9722
- stats.tokens ? /* @__PURE__ */ jsxs70("div", { children: [
9738
+ stats.tokens ? /* @__PURE__ */ jsxs71("div", { children: [
9723
9739
  /* @__PURE__ */ jsx75("span", { children: "Tokens" }),
9724
9740
  /* @__PURE__ */ jsx75("b", { className: "fd-tabular", children: stats.tokens.toLocaleString() })
9725
9741
  ] }) : null,
9726
- stats.costUsd != null ? /* @__PURE__ */ jsxs70("div", { children: [
9742
+ stats.costUsd != null ? /* @__PURE__ */ jsxs71("div", { children: [
9727
9743
  /* @__PURE__ */ jsx75("span", { children: "Cost" }),
9728
- /* @__PURE__ */ jsxs70("b", { className: "fd-tabular", children: [
9744
+ /* @__PURE__ */ jsxs71("b", { className: "fd-tabular", children: [
9729
9745
  "$",
9730
9746
  Number(stats.costUsd).toFixed(3)
9731
9747
  ] })
9732
9748
  ] }) : null,
9733
- stats.turns ? /* @__PURE__ */ jsxs70("div", { children: [
9749
+ stats.turns ? /* @__PURE__ */ jsxs71("div", { children: [
9734
9750
  /* @__PURE__ */ jsx75("span", { children: "Turns" }),
9735
9751
  /* @__PURE__ */ jsx75("b", { className: "fd-tabular", children: stats.turns })
9736
9752
  ] }) : null
@@ -9784,14 +9800,14 @@ function ModelControls({
9784
9800
  items.push({ kind: "section", label: "Fast mode" });
9785
9801
  items.push({
9786
9802
  kind: "custom",
9787
- render: () => /* @__PURE__ */ jsxs70("label", { className: "fdc-switchrow", children: [
9803
+ render: () => /* @__PURE__ */ jsxs71("label", { className: "fdc-switchrow", children: [
9788
9804
  /* @__PURE__ */ jsx75("span", { children: fastModeLabel }),
9789
9805
  /* @__PURE__ */ jsx75("input", { type: "checkbox", className: "fd-sr", checked: !!fastMode, onChange: (e) => onFastModeChange(e.target.checked) }),
9790
9806
  /* @__PURE__ */ jsx75("span", { className: "fd-switch-track" + (fastMode ? " is-on" : ""), "aria-hidden": "true", children: /* @__PURE__ */ jsx75("span", { className: "fd-switch-thumb" }) })
9791
9807
  ] })
9792
9808
  });
9793
9809
  }
9794
- return /* @__PURE__ */ jsxs70(React44.Fragment, { children: [
9810
+ return /* @__PURE__ */ jsxs71(React45.Fragment, { children: [
9795
9811
  /* @__PURE__ */ jsx75(
9796
9812
  MenuButton,
9797
9813
  {
@@ -9824,7 +9840,7 @@ function ModelControls({
9824
9840
  }
9825
9841
 
9826
9842
  // src/components/chat/AgentChatPanel.tsx
9827
- import { jsx as jsx76, jsxs as jsxs71 } from "react/jsx-runtime";
9843
+ import { jsx as jsx76, jsxs as jsxs72 } from "react/jsx-runtime";
9828
9844
  var SURFACES = { sidebar: "is-sidebar", inline: "is-inline", page: "is-page", modal: "is-modal", sheet: "is-sheet" };
9829
9845
  function AgentChatPanel({
9830
9846
  /* required */
@@ -9908,11 +9924,11 @@ function AgentChatPanel({
9908
9924
  onFeedback,
9909
9925
  onEditMessage
9910
9926
  }) {
9911
- const [panelWidth, setPanelWidth] = React45.useState(width);
9912
- const [applied, setApplied] = React45.useState({});
9913
- const [draft, setDraft] = React45.useState("");
9914
- const dragging = React45.useRef(null);
9915
- React45.useEffect(() => setPanelWidth(width), [width]);
9927
+ const [panelWidth, setPanelWidth] = React46.useState(width);
9928
+ const [applied, setApplied] = React46.useState({});
9929
+ const [draft, setDraft] = React46.useState("");
9930
+ const dragging = React46.useRef(null);
9931
+ React46.useEffect(() => setPanelWidth(width), [width]);
9916
9932
  const engine = useChatEngine({
9917
9933
  contextType,
9918
9934
  contextId,
@@ -10029,7 +10045,7 @@ function AgentChatPanel({
10029
10045
  })))
10030
10046
  }
10031
10047
  ) : null;
10032
- return /* @__PURE__ */ jsxs71(
10048
+ return /* @__PURE__ */ jsxs72(
10033
10049
  "aside",
10034
10050
  {
10035
10051
  className: ["fdc-panel", SURFACES[surface] || SURFACES.sidebar, narrow ? "is-narrow" : "", className].filter(Boolean).join(" "),
@@ -10055,13 +10071,13 @@ function AgentChatPanel({
10055
10071
  }
10056
10072
  }
10057
10073
  ) : null,
10058
- showHeader ? /* @__PURE__ */ jsxs71("header", { className: "fdc-head", children: [
10074
+ showHeader ? /* @__PURE__ */ jsxs72("header", { className: "fdc-head", children: [
10059
10075
  /* @__PURE__ */ jsx76("span", { className: "fdc-head-mark", "aria-hidden": "true", children: /* @__PURE__ */ jsx76("i", { className: "ph ph-" + assistantIcon }) }),
10060
- /* @__PURE__ */ jsxs71("span", { className: "fdc-head-titles", children: [
10076
+ /* @__PURE__ */ jsxs72("span", { className: "fdc-head-titles", children: [
10061
10077
  /* @__PURE__ */ jsx76("span", { className: "fdc-head-title", children: title }),
10062
10078
  subtitle ? /* @__PURE__ */ jsx76("span", { className: "fdc-head-sub", children: subtitle }) : null
10063
10079
  ] }),
10064
- /* @__PURE__ */ jsxs71("span", { className: "fdc-head-acts", children: [
10080
+ /* @__PURE__ */ jsxs72("span", { className: "fdc-head-acts", children: [
10065
10081
  headerActions,
10066
10082
  threadMenu,
10067
10083
  onNewThread ? /* @__PURE__ */ jsx76("button", { type: "button", className: "fdc-iconbtn", onClick: onNewThread, "aria-label": "New conversation", title: "New conversation", children: /* @__PURE__ */ jsx76("i", { className: "ph ph-plus", "aria-hidden": "true" }) }) : null,
@@ -10116,7 +10132,7 @@ function AgentChatPanel({
10116
10132
  }
10117
10133
 
10118
10134
  // src/kits/query.ts
10119
- import * as React46 from "react";
10135
+ import * as React47 from "react";
10120
10136
  function eqFilter(get2) {
10121
10137
  return (row, value) => Array.isArray(value) ? value.includes(get2(row)) : get2(row) === value;
10122
10138
  }
@@ -10148,22 +10164,22 @@ function compare(a, b, dir) {
10148
10164
  var API = null;
10149
10165
  var PREFS = null;
10150
10166
  function useServerTable({ endpoint, params, defaults, deps, prefsKey }) {
10151
- const [query, setQuery] = React46.useState(() => {
10167
+ const [query, setQuery] = React47.useState(() => {
10152
10168
  const store = PREFS || window.PlannerPrefs;
10153
10169
  const saved = prefsKey && store ? store.getTable(prefsKey) : {};
10154
10170
  return { ...DEFAULTS, ...defaults || {}, ...saved.pageSize ? { pageSize: saved.pageSize } : {}, ...saved.sort ? { sort: saved.sort, dir: saved.dir || "desc" } : {} };
10155
10171
  });
10156
- const savePref = React46.useCallback((patch2) => {
10172
+ const savePref = React47.useCallback((patch2) => {
10157
10173
  const store = PREFS || window.PlannerPrefs;
10158
10174
  if (prefsKey && store) store.setTable(prefsKey, patch2);
10159
10175
  }, [prefsKey]);
10160
- const [res, setRes] = React46.useState(null);
10161
- const [loading, setLoading] = React46.useState(true);
10162
- const seq2 = React46.useRef(0);
10176
+ const [res, setRes] = React47.useState(null);
10177
+ const [loading, setLoading] = React47.useState(true);
10178
+ const seq2 = React47.useRef(0);
10163
10179
  const depKey = (deps || []).join("|");
10164
10180
  const paramKey = JSON.stringify(params || {});
10165
10181
  const queryKey = JSON.stringify(query);
10166
- React46.useEffect(() => {
10182
+ React47.useEffect(() => {
10167
10183
  const id = ++seq2.current;
10168
10184
  setLoading(true);
10169
10185
  const t = setTimeout(() => {
@@ -10616,6 +10632,7 @@ export {
10616
10632
  meterFormats,
10617
10633
  modifierLabel,
10618
10634
  pastedTextName,
10635
+ pluralizeUnit,
10619
10636
  preferenceScore,
10620
10637
  preferenceSegments,
10621
10638
  rangeFilter,