@flytedan/flytebot-design-system 0.12.4 → 0.12.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -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,17 +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";
1442
+ var FILTER_BAR_BASE = 120;
1432
1443
  var isSet = (v) => !(v == null || v === "" || v === false);
1433
1444
  function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align = "left", className = "", ...rest }) {
1434
- const [panel, setPanel] = React8.useState(null);
1435
- const rootRef = React8.useRef(null);
1436
- const textInputRef = React8.useRef(null);
1437
- const optionsRef = React8.useRef(null);
1445
+ const [panel, setPanel] = React9.useState(null);
1446
+ const zIndex = useOverlayLayer(FILTER_BAR_BASE);
1447
+ const rootRef = React9.useRef(null);
1448
+ const textInputRef = React9.useRef(null);
1449
+ const optionsRef = React9.useRef(null);
1438
1450
  const editingField = panel && panel.kind === "edit" ? fields.find((f) => f.key === panel.key) : void 0;
1439
1451
  const dismissible = !!panel && (panel.kind === "add" || panel.kind === "edit" && editingField?.type === "select");
1440
- React8.useEffect(() => {
1452
+ React9.useEffect(() => {
1441
1453
  if (!dismissible) return;
1442
1454
  const away = (e) => {
1443
1455
  if (rootRef.current && !rootRef.current.contains(e.target)) setPanel(null);
@@ -1452,7 +1464,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
1452
1464
  document.removeEventListener("keydown", esc);
1453
1465
  };
1454
1466
  }, [dismissible]);
1455
- React8.useEffect(() => {
1467
+ React9.useEffect(() => {
1456
1468
  if (!panel || panel.kind !== "edit") return;
1457
1469
  if (editingField?.type === "text") {
1458
1470
  textInputRef.current?.focus();
@@ -1463,12 +1475,12 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
1463
1475
  }, [panel]);
1464
1476
  const addableFields = fields.filter((f) => !isSet(filters[f.key]));
1465
1477
  const startEditing = (key) => setPanel({ kind: "edit", key });
1466
- 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: [
1467
1479
  fields.map((field) => {
1468
1480
  const value = filters[field.key];
1469
1481
  const editing = panel?.kind === "edit" && panel.key === field.key;
1470
1482
  if (editing && field.type === "text") {
1471
- return /* @__PURE__ */ jsxs23(
1483
+ return /* @__PURE__ */ jsxs24(
1472
1484
  "span",
1473
1485
  {
1474
1486
  className: "fd-tag",
@@ -1514,19 +1526,19 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
1514
1526
  }
1515
1527
  if (editing && field.type === "select") {
1516
1528
  const chosen = field.options.find((o) => o.value === value);
1517
- return /* @__PURE__ */ jsxs23("span", { style: { position: "relative", display: "inline-flex" }, children: [
1518
- /* @__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: () => {
1519
1531
  if (isSet(value)) onFilterRemove(field.key);
1520
1532
  setPanel(null);
1521
1533
  }, children: [
1522
1534
  field.label,
1523
1535
  chosen ? ": " + chosen.label : ""
1524
1536
  ] }),
1525
- /* @__PURE__ */ jsx28(
1537
+ /* @__PURE__ */ jsx28(LayerProvider, { zIndex, children: /* @__PURE__ */ jsx28(
1526
1538
  "span",
1527
1539
  {
1528
1540
  className: "fd-view-enter",
1529
- style: { position: "absolute", top: "calc(100% + 6px)", left: 0, zIndex: 120, minWidth: 200, 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 },
1541
+ style: { position: "absolute", top: "calc(100% + 6px)", left: 0, zIndex, minWidth: 200, 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 },
1530
1542
  children: /* @__PURE__ */ jsx28("span", { className: "fd-stack", role: "listbox", "aria-label": field.label, ref: optionsRef, style: { gap: 2 }, children: field.options.map((o) => {
1531
1543
  const on = o.value === value;
1532
1544
  return /* @__PURE__ */ jsx28(
@@ -1547,13 +1559,13 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
1547
1559
  );
1548
1560
  }) })
1549
1561
  }
1550
- )
1562
+ ) })
1551
1563
  ] }, field.key);
1552
1564
  }
1553
1565
  if (isSet(value)) {
1554
1566
  const chosen = field.type === "select" ? field.options.find((o) => o.value === value) : void 0;
1555
1567
  const display = chosen ? chosen.label : String(value);
1556
- 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: [
1557
1569
  field.label,
1558
1570
  ": ",
1559
1571
  display
@@ -1561,7 +1573,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
1561
1573
  }
1562
1574
  return null;
1563
1575
  }),
1564
- 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: [
1565
1577
  /* @__PURE__ */ jsx28(
1566
1578
  Button,
1567
1579
  {
@@ -1574,12 +1586,12 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
1574
1586
  children: "Filter"
1575
1587
  }
1576
1588
  ),
1577
- panel?.kind === "add" ? /* @__PURE__ */ jsx28(
1589
+ panel?.kind === "add" ? /* @__PURE__ */ jsx28(LayerProvider, { zIndex, children: /* @__PURE__ */ jsx28(
1578
1590
  "span",
1579
1591
  {
1580
1592
  className: "fd-view-enter",
1581
- style: { position: "absolute", top: "calc(100% + 6px)", [align]: 0, zIndex: 120, 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 },
1582
- children: /* @__PURE__ */ jsxs23("span", { className: "fd-stack", role: "menu", "aria-label": "Add filter", style: { gap: 2 }, children: [
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 },
1594
+ children: /* @__PURE__ */ jsxs24("span", { className: "fd-stack", role: "menu", "aria-label": "Add filter", style: { gap: 2 }, children: [
1583
1595
  /* @__PURE__ */ jsx28("span", { className: "fd-overline fd-muted", style: { padding: "4px 8px 6px" }, children: "Add filter" }),
1584
1596
  addableFields.map((f) => /* @__PURE__ */ jsx28(
1585
1597
  "button",
@@ -1595,18 +1607,18 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
1595
1607
  ))
1596
1608
  ] })
1597
1609
  }
1598
- ) : null
1610
+ ) }) : null
1599
1611
  ] }) : null
1600
1612
  ] });
1601
1613
  }
1602
1614
 
1603
1615
  // src/components/data/StatTile.tsx
1604
- import { jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
1616
+ import { jsx as jsx29, jsxs as jsxs25 } from "react/jsx-runtime";
1605
1617
  function StatTile({ label, value, sub, delta, loading = false, compact: compact3 = false, className = "", ...rest }) {
1606
- return /* @__PURE__ */ jsxs24("div", { className: ["fd-stat", compact3 ? "fd-stat-compact" : "", className].filter(Boolean).join(" "), ...rest, children: [
1607
- 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: [
1608
1620
  /* @__PURE__ */ jsx29("span", { className: "fd-stat-figure", children: value }),
1609
- 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: [
1610
1622
  /* @__PURE__ */ jsx29("i", { className: "ph ph-arrow-" + (delta.startsWith("-") ? "down" : "up") + "-right", "aria-hidden": "true" }),
1611
1623
  " ",
1612
1624
  delta
@@ -1618,8 +1630,8 @@ function StatTile({ label, value, sub, delta, loading = false, compact: compact3
1618
1630
  }
1619
1631
 
1620
1632
  // src/components/data/CodeBlock.tsx
1621
- import * as React9 from "react";
1622
- 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";
1623
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)$/;
1624
1636
  var RULES = {
1625
1637
  js: [
@@ -1774,13 +1786,13 @@ function tokenize(src, lang) {
1774
1786
  return out;
1775
1787
  }
1776
1788
  function Highlighted({ code, lang }) {
1777
- const toks = React9.useMemo(() => tokenize(code, lang), [code, lang]);
1789
+ const toks = React10.useMemo(() => tokenize(code, lang), [code, lang]);
1778
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) });
1779
1791
  }
1780
1792
  function useCopy() {
1781
- const [done, setDone] = React9.useState(false);
1782
- const timer = React9.useRef(null);
1783
- React9.useEffect(() => () => {
1793
+ const [done, setDone] = React10.useState(false);
1794
+ const timer = React10.useRef(null);
1795
+ React10.useEffect(() => () => {
1784
1796
  if (timer.current) clearTimeout(timer.current);
1785
1797
  }, []);
1786
1798
  const copy = (text) => {
@@ -1816,37 +1828,37 @@ function CodeBlock({
1816
1828
  actions,
1817
1829
  className = ""
1818
1830
  }) {
1819
- const [wrap, setWrap] = React9.useState(!!wrapDefault);
1820
- const [open, setOpen] = React9.useState(false);
1831
+ const [wrap, setWrap] = React10.useState(!!wrapDefault);
1832
+ const [open, setOpen] = React10.useState(false);
1821
1833
  const [copied, copy] = useCopy();
1822
1834
  const body = String(code).replace(/\n$/, "");
1823
1835
  const lines = body.split("\n");
1824
1836
  const foldable = collapseAfter > 0 && lines.length > collapseAfter + 6;
1825
1837
  const shown = foldable && !open ? lines.slice(0, collapseAfter).join("\n") : body;
1826
- return /* @__PURE__ */ jsxs25("div", { className: ["fd-code", wrap ? "is-wrap" : "", className].filter(Boolean).join(" "), children: [
1827
- /* @__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: [
1828
1840
  filename ? /* @__PURE__ */ jsx30("span", { className: "fd-code-file", children: filename }) : null,
1829
1841
  /* @__PURE__ */ jsx30("span", { className: "fd-code-lang", children: languageLabel(language) }),
1830
1842
  /* @__PURE__ */ jsx30("span", { className: "fd-code-spacer" }),
1831
1843
  actions,
1832
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" }) }),
1833
- 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: [
1834
1846
  /* @__PURE__ */ jsx30("i", { className: "ph ph-" + (copied ? "check" : "copy"), "aria-hidden": "true" }),
1835
1847
  /* @__PURE__ */ jsx30("span", { children: copied ? "Copied" : "Copy" })
1836
1848
  ] }) : null
1837
1849
  ] }),
1838
- /* @__PURE__ */ jsxs25("div", { className: "fd-code-body", children: [
1850
+ /* @__PURE__ */ jsxs26("div", { className: "fd-code-body", children: [
1839
1851
  lineNumbers ? /* @__PURE__ */ jsx30("pre", { className: "fd-code-gutter", "aria-hidden": "true", children: shown.split("\n").map((_, i) => i + 1 + "\n").join("") }) : null,
1840
1852
  /* @__PURE__ */ jsx30("pre", { className: "fd-code-pre", tabIndex: 0, children: /* @__PURE__ */ jsx30("code", { children: /* @__PURE__ */ jsx30(Highlighted, { code: shown, lang: language }) }) })
1841
1853
  ] }),
1842
- 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: [
1843
1855
  /* @__PURE__ */ jsx30("i", { className: "ph ph-caret-" + (open ? "up" : "down"), "aria-hidden": "true" }),
1844
1856
  open ? "Collapse" : "Show all " + lines.length + " lines"
1845
1857
  ] }) : null
1846
1858
  ] });
1847
1859
  }
1848
1860
  function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" }) {
1849
- const [open, setOpen] = React9.useState(false);
1861
+ const [open, setOpen] = React10.useState(false);
1850
1862
  const [copied, copy] = useCopy();
1851
1863
  const raw = String(diff).replace(/\n$/, "");
1852
1864
  const all = raw.split("\n").map((line) => {
@@ -1860,31 +1872,31 @@ function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" })
1860
1872
  const dels = all.filter((l) => l.k === "del").length;
1861
1873
  const foldable = collapseAfter > 0 && all.length > collapseAfter + 6;
1862
1874
  const rows = foldable && !open ? all.slice(0, collapseAfter) : all;
1863
- return /* @__PURE__ */ jsxs25("div", { className: ["fd-code", "fd-diff", className].filter(Boolean).join(" "), children: [
1864
- /* @__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: [
1865
1877
  /* @__PURE__ */ jsx30("i", { className: "ph ph-git-diff fd-code-icon", "aria-hidden": "true" }),
1866
1878
  filename ? /* @__PURE__ */ jsx30("span", { className: "fd-code-file", children: filename }) : /* @__PURE__ */ jsx30("span", { className: "fd-code-lang", children: "Diff" }),
1867
- /* @__PURE__ */ jsxs25("span", { className: "fd-diff-stat fd-tabular", children: [
1868
- /* @__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: [
1869
1881
  "+",
1870
1882
  adds
1871
1883
  ] }),
1872
- /* @__PURE__ */ jsxs25("span", { className: "is-del", children: [
1884
+ /* @__PURE__ */ jsxs26("span", { className: "is-del", children: [
1873
1885
  "\u2212",
1874
1886
  dels
1875
1887
  ] })
1876
1888
  ] }),
1877
1889
  /* @__PURE__ */ jsx30("span", { className: "fd-code-spacer" }),
1878
- /* @__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: [
1879
1891
  /* @__PURE__ */ jsx30("i", { className: "ph ph-" + (copied ? "check" : "copy"), "aria-hidden": "true" }),
1880
1892
  /* @__PURE__ */ jsx30("span", { children: copied ? "Copied" : "Copy" })
1881
1893
  ] })
1882
1894
  ] }),
1883
- /* @__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: [
1884
1896
  /* @__PURE__ */ jsx30("span", { className: "fd-diff-mark", "aria-hidden": "true", children: r.k === "add" ? "+" : r.k === "del" ? "\u2212" : "" }),
1885
1897
  /* @__PURE__ */ jsx30("code", { children: r.k === "add" || r.k === "del" ? r.line.slice(1) : r.line })
1886
1898
  ] }, i)) }),
1887
- 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: [
1888
1900
  /* @__PURE__ */ jsx30("i", { className: "ph ph-caret-" + (open ? "up" : "down"), "aria-hidden": "true" }),
1889
1901
  open ? "Collapse" : "Show all " + all.length + " lines"
1890
1902
  ] }) : null
@@ -1892,8 +1904,8 @@ function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" })
1892
1904
  }
1893
1905
 
1894
1906
  // src/components/data/Markdown.tsx
1895
- import * as React10 from "react";
1896
- 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";
1897
1909
  var SAFE = /^(?:https?:|mailto:|tel:|#|\/|\.{1,2}\/)/i;
1898
1910
  var safeHref = (h) => SAFE.test(String(h || "").trim()) ? String(h).trim() : null;
1899
1911
  var INLINE = [
@@ -1931,7 +1943,7 @@ function inlineNodes(src, ctx, keyBase) {
1931
1943
  const href = safeHref(g(2));
1932
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()));
1933
1945
  } else if (kind === "cite") {
1934
- 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()));
1935
1947
  } else if (kind === "strongem") out.push(/* @__PURE__ */ jsx31("strong", { children: /* @__PURE__ */ jsx31("em", { children: inlineNodes(g(1), ctx, key()) }) }, key()));
1936
1948
  else if (kind === "strong") out.push(/* @__PURE__ */ jsx31("strong", { children: inlineNodes(g(1) || g(2), ctx, key()) }, key()));
1937
1949
  else if (kind === "em") out.push(/* @__PURE__ */ jsx31("em", { children: inlineNodes(g(1) || g(2), ctx, key()) }, key()));
@@ -2071,13 +2083,13 @@ function renderBlocks(blocks, ctx, path) {
2071
2083
  case "list": {
2072
2084
  const Tag2 = b.ordered ? "ol" : "ul";
2073
2085
  const isTask = b.items.some((it) => it.checked != null);
2074
- 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: [
2075
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,
2076
2088
  /* @__PURE__ */ jsx31("span", { className: "fd-md-li", children: renderBlocks(it.children, ctx, k + "-" + j) })
2077
2089
  ] }, k + "-" + j)) }, k);
2078
2090
  }
2079
2091
  case "table":
2080
- 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: [
2081
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)) }) }),
2082
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)) })
2083
2095
  ] }) }, k);
@@ -2096,7 +2108,7 @@ function Markdown({
2096
2108
  onLinkClick
2097
2109
  }) {
2098
2110
  const ctx = { allowImages, headingOffset, renderCitation, onLinkClick, codeProps };
2099
- const blocks = React10.useMemo(() => parseBlocks(source), [source]);
2111
+ const blocks = React11.useMemo(() => parseBlocks(source), [source]);
2100
2112
  return /* @__PURE__ */ jsx31("div", { className: ["fd-md", className].filter(Boolean).join(" "), children: renderBlocks(blocks, ctx, "b") });
2101
2113
  }
2102
2114
  function MarkdownInline({ source = "", className = "", onLinkClick }) {
@@ -2107,13 +2119,13 @@ function markdownToText(src) {
2107
2119
  }
2108
2120
 
2109
2121
  // src/components/data/Meter.tsx
2110
- import { jsx as jsx32, jsxs as jsxs27 } from "react/jsx-runtime";
2122
+ import { jsx as jsx32, jsxs as jsxs28 } from "react/jsx-runtime";
2111
2123
  function Meter({ segments = [], unallocated = 0, height = 8, label, legend = false, className = "" }) {
2112
2124
  const total = segments.reduce((s, x) => s + x.value, 0) + unallocated;
2113
2125
  const pct = (v) => total ? v / total * 100 : 0;
2114
- 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: [
2115
2127
  label ? /* @__PURE__ */ jsx32("span", { className: "fd-label-lg fd-secondary", children: label }) : null,
2116
- /* @__PURE__ */ jsxs27("div", { className: "fd-meterbar", style: { height }, children: [
2128
+ /* @__PURE__ */ jsxs28("div", { className: "fd-meterbar", style: { height }, children: [
2117
2129
  segments.map((s, i) => /* @__PURE__ */ jsx32(
2118
2130
  "span",
2119
2131
  {
@@ -2125,12 +2137,12 @@ function Meter({ segments = [], unallocated = 0, height = 8, label, legend = fal
2125
2137
  )),
2126
2138
  unallocated > 0 ? /* @__PURE__ */ jsx32("span", { className: "fd-meterbar-seg fd-meterbar-unallocated", title: "Unallocated", style: { width: pct(unallocated) + "%" } }) : null
2127
2139
  ] }),
2128
- legend ? /* @__PURE__ */ jsxs27("div", { className: "fd-row", style: { gap: 16, flexWrap: "wrap" }, children: [
2129
- 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: [
2130
2142
  /* @__PURE__ */ jsx32("span", { style: { width: 9, height: 9, borderRadius: 2, background: s.color || "var(--chart-" + (i % 8 + 1) + ")" } }),
2131
2143
  s.label
2132
2144
  ] }, i)),
2133
- 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: [
2134
2146
  /* @__PURE__ */ jsx32("span", { className: "fd-meterbar-unallocated", style: { width: 9, height: 9, borderRadius: 2 } }),
2135
2147
  "Unallocated"
2136
2148
  ] }) : null
@@ -2139,7 +2151,7 @@ function Meter({ segments = [], unallocated = 0, height = 8, label, legend = fal
2139
2151
  }
2140
2152
 
2141
2153
  // src/components/data/Pagination.tsx
2142
- 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";
2143
2155
  function Pagination({
2144
2156
  page = 1,
2145
2157
  pageSize = 25,
@@ -2164,12 +2176,12 @@ function Pagination({
2164
2176
  if (i === 1 || i === totalPages || Math.abs(i - page) <= span) nums.push(i);
2165
2177
  else if (nums[nums.length - 1] !== "\u2026") nums.push("\u2026");
2166
2178
  }
2167
- return /* @__PURE__ */ jsxs28("div", { className: ["fd-pag", className].filter(Boolean).join(" "), ...rest, children: [
2168
- /* @__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: [
2179
+ return /* @__PURE__ */ jsxs29("div", { className: ["fd-pag", className].filter(Boolean).join(" "), ...rest, children: [
2180
+ /* @__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: [
2169
2181
  "No ",
2170
2182
  unit
2171
- ] }) : /* @__PURE__ */ jsxs28(Fragment7, { children: [
2172
- /* @__PURE__ */ jsxs28("strong", { children: [
2183
+ ] }) : /* @__PURE__ */ jsxs29(Fragment7, { children: [
2184
+ /* @__PURE__ */ jsxs29("strong", { children: [
2173
2185
  from.toLocaleString(),
2174
2186
  "\u2013",
2175
2187
  to.toLocaleString()
@@ -2179,11 +2191,11 @@ function Pagination({
2179
2191
  " ",
2180
2192
  unit
2181
2193
  ] }) }),
2182
- onPageSizeChange ? /* @__PURE__ */ jsxs28("label", { className: "fd-pag-size", children: [
2194
+ onPageSizeChange ? /* @__PURE__ */ jsxs29("label", { className: "fd-pag-size", children: [
2183
2195
  /* @__PURE__ */ jsx33("span", { children: "Rows" }),
2184
2196
  /* @__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)) })
2185
2197
  ] }) : null,
2186
- /* @__PURE__ */ jsxs28("span", { className: "fd-pag-nav", children: [
2198
+ /* @__PURE__ */ jsxs29("span", { className: "fd-pag-nav", children: [
2187
2199
  /* @__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" }) }),
2188
2200
  /* @__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" }) }),
2189
2201
  nums.map((n, i) => n === "\u2026" ? /* @__PURE__ */ jsx33("span", { className: "fd-pag-gap", "aria-hidden": "true", children: "\u2026" }, "e" + i) : /* @__PURE__ */ jsx33(
@@ -2204,8 +2216,8 @@ function Pagination({
2204
2216
  }
2205
2217
 
2206
2218
  // src/components/data/RelativeTime.tsx
2207
- import * as React11 from "react";
2208
- import { jsxs as jsxs29 } from "react/jsx-runtime";
2219
+ import * as React12 from "react";
2220
+ import { jsxs as jsxs30 } from "react/jsx-runtime";
2209
2221
  var MIN = 6e4;
2210
2222
  var HOUR = 36e5;
2211
2223
  var DAY = 864e5;
@@ -2256,9 +2268,9 @@ function formatDuration(ms) {
2256
2268
  return h + "h" + (m % 60 ? " " + m % 60 + "m" : "");
2257
2269
  }
2258
2270
  function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true, ...rest }) {
2259
- const [, force] = React11.useState(0);
2271
+ const [, force] = React12.useState(0);
2260
2272
  const t = value instanceof Date ? value.getTime() : Date.parse(value);
2261
- React11.useEffect(() => {
2273
+ React12.useEffect(() => {
2262
2274
  if (!refresh2 || !t || isNaN(t)) return;
2263
2275
  const abs = Math.abs(t - Date.now());
2264
2276
  if (abs > DAY) return;
@@ -2267,17 +2279,17 @@ function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true,
2267
2279
  return () => clearInterval(id);
2268
2280
  }, [t, refresh2]);
2269
2281
  if (!t || isNaN(t)) return null;
2270
- return /* @__PURE__ */ jsxs29("time", { className, dateTime: new Date(t).toISOString(), title: formatAbsolute(new Date(t)), ...rest, children: [
2282
+ return /* @__PURE__ */ jsxs30("time", { className, dateTime: new Date(t).toISOString(), title: formatAbsolute(new Date(t)), ...rest, children: [
2271
2283
  prefix ? prefix + " " : "",
2272
2284
  formatRelative(new Date(t))
2273
2285
  ] });
2274
2286
  }
2275
2287
 
2276
2288
  // src/components/data/ScoreMeter.tsx
2277
- import * as React13 from "react";
2289
+ import * as React14 from "react";
2278
2290
 
2279
2291
  // src/components/data/SegmentedMeter.tsx
2280
- import * as React12 from "react";
2292
+ import * as React13 from "react";
2281
2293
 
2282
2294
  // src/kits/files.ts
2283
2295
  function formatBytes(n) {
@@ -2437,7 +2449,7 @@ var FileKit = {
2437
2449
  };
2438
2450
 
2439
2451
  // src/components/data/SegmentedMeter.tsx
2440
- import { jsx as jsx34, jsxs as jsxs30 } from "react/jsx-runtime";
2452
+ import { jsx as jsx34, jsxs as jsxs31 } from "react/jsx-runtime";
2441
2453
  var VARIANT_FILL = {
2442
2454
  brand: "var(--brand)",
2443
2455
  neutral: "var(--n-400)",
@@ -2482,16 +2494,16 @@ function SegmentedMeter({
2482
2494
  const pct = safeTotal ? Math.min(100, Math.round(used / safeTotal * 100)) : 0;
2483
2495
  const w = (v) => safeTotal ? Math.max(0, Math.min(100, Number(v) / safeTotal * 100)) : 0;
2484
2496
  const fill = (s, i) => s.color || (s.variant ? VARIANT_FILL[s.variant] : void 0) || CHART[i % CHART.length];
2485
- const generatedId = React12.useId();
2497
+ const generatedId = React13.useId();
2486
2498
  const uid2 = id || generatedId;
2487
- return /* @__PURE__ */ jsxs30("div", { className: ["fd-segmeter", className].filter(Boolean).join(" "), onClick, children: [
2488
- label || showTotal ? /* @__PURE__ */ jsxs30("div", { className: "fd-segmeter-head", children: [
2499
+ return /* @__PURE__ */ jsxs31("div", { className: ["fd-segmeter", className].filter(Boolean).join(" "), onClick, children: [
2500
+ label || showTotal ? /* @__PURE__ */ jsxs31("div", { className: "fd-segmeter-head", children: [
2489
2501
  label ? /* @__PURE__ */ jsx34("span", { className: "fd-segmeter-label", id: uid2 + "-l", children: label }) : /* @__PURE__ */ jsx34("span", {}),
2490
- showTotal ? /* @__PURE__ */ jsxs30("span", { className: "fd-segmeter-total fd-tabular", children: [
2502
+ showTotal ? /* @__PURE__ */ jsxs31("span", { className: "fd-segmeter-total fd-tabular", children: [
2491
2503
  format(used),
2492
2504
  /* @__PURE__ */ jsx34("span", { className: "fd-segmeter-sep", children: " / " }),
2493
2505
  safeTotal ? format(safeTotal) : "\u2014",
2494
- showPercent ? /* @__PURE__ */ jsxs30("span", { className: "fd-segmeter-pct", children: [
2506
+ showPercent ? /* @__PURE__ */ jsxs31("span", { className: "fd-segmeter-pct", children: [
2495
2507
  " (",
2496
2508
  pct,
2497
2509
  "%)"
@@ -2521,13 +2533,13 @@ function SegmentedMeter({
2521
2533
  ))
2522
2534
  }
2523
2535
  ),
2524
- legend ? /* @__PURE__ */ jsxs30("ul", { className: "fd-segmeter-legend", children: [
2525
- items.map((s, i) => /* @__PURE__ */ jsxs30("li", { children: [
2536
+ legend ? /* @__PURE__ */ jsxs31("ul", { className: "fd-segmeter-legend", children: [
2537
+ items.map((s, i) => /* @__PURE__ */ jsxs31("li", { children: [
2526
2538
  /* @__PURE__ */ jsx34("span", { className: "fd-segmeter-dot", style: { background: fill(s, i) }, "aria-hidden": "true" }),
2527
2539
  /* @__PURE__ */ jsx34("span", { className: "fd-segmeter-key", children: s.label }),
2528
2540
  /* @__PURE__ */ jsx34("span", { className: "fd-segmeter-val fd-tabular", children: format(s.value) })
2529
2541
  ] }, s.id || s.label || i)),
2530
- safeTotal && used < safeTotal ? /* @__PURE__ */ jsxs30("li", { className: "is-remainder", children: [
2542
+ safeTotal && used < safeTotal ? /* @__PURE__ */ jsxs31("li", { className: "is-remainder", children: [
2531
2543
  /* @__PURE__ */ jsx34("span", { className: "fd-segmeter-dot is-empty", "aria-hidden": "true" }),
2532
2544
  /* @__PURE__ */ jsx34("span", { className: "fd-segmeter-key", children: remainderLabel }),
2533
2545
  /* @__PURE__ */ jsx34("span", { className: "fd-segmeter-val fd-tabular", children: format(safeTotal - used) })
@@ -2538,11 +2550,11 @@ function SegmentedMeter({
2538
2550
  function QuotaRow({ label, percent = 0, note, tone, className = "" }) {
2539
2551
  const p = Math.max(0, Math.min(100, Math.round(Number(percent) || 0)));
2540
2552
  const auto = p >= 90 ? "danger" : p >= 70 ? "warn" : "brand";
2541
- return /* @__PURE__ */ jsxs30("div", { className: ["fd-quota", className].filter(Boolean).join(" "), children: [
2542
- /* @__PURE__ */ jsxs30("div", { className: "fd-quota-head", children: [
2553
+ return /* @__PURE__ */ jsxs31("div", { className: ["fd-quota", className].filter(Boolean).join(" "), children: [
2554
+ /* @__PURE__ */ jsxs31("div", { className: "fd-quota-head", children: [
2543
2555
  /* @__PURE__ */ jsx34("span", { className: "fd-quota-label", children: label }),
2544
2556
  note ? /* @__PURE__ */ jsx34("span", { className: "fd-quota-note", children: note }) : null,
2545
- /* @__PURE__ */ jsxs30("span", { className: "fd-quota-pct fd-tabular", children: [
2557
+ /* @__PURE__ */ jsxs31("span", { className: "fd-quota-pct fd-tabular", children: [
2546
2558
  p,
2547
2559
  "%"
2548
2560
  ] })
@@ -2552,7 +2564,7 @@ function QuotaRow({ label, percent = 0, note, tone, className = "" }) {
2552
2564
  }
2553
2565
 
2554
2566
  // src/components/data/ScoreMeter.tsx
2555
- import { jsx as jsx35, jsxs as jsxs31 } from "react/jsx-runtime";
2567
+ import { jsx as jsx35, jsxs as jsxs32 } from "react/jsx-runtime";
2556
2568
  function ScoreMeter({
2557
2569
  score,
2558
2570
  segments,
@@ -2566,10 +2578,10 @@ function ScoreMeter({
2566
2578
  breakdownWidth = 280,
2567
2579
  className = ""
2568
2580
  }) {
2569
- const [open, setOpen] = React13.useState(false);
2570
- const ref = React13.useRef(null);
2581
+ const [open, setOpen] = React14.useState(false);
2582
+ const ref = React14.useRef(null);
2571
2583
  const value = Math.max(0, Math.min(100, Math.round(Number(score) || 0)));
2572
- const body = /* @__PURE__ */ jsxs31(React13.Fragment, { children: [
2584
+ const body = /* @__PURE__ */ jsxs32(React14.Fragment, { children: [
2573
2585
  /* @__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 }) }),
2574
2586
  showScore ? /* @__PURE__ */ jsx35("span", { className: "fd-scoremeter-value fd-tabular", "aria-hidden": "true", children: value }) : null
2575
2587
  ] });
@@ -2588,7 +2600,7 @@ function ScoreMeter({
2588
2600
  }
2589
2601
  );
2590
2602
  }
2591
- return /* @__PURE__ */ jsxs31(React13.Fragment, { children: [
2603
+ return /* @__PURE__ */ jsxs32(React14.Fragment, { children: [
2592
2604
  /* @__PURE__ */ jsx35(
2593
2605
  "button",
2594
2606
  {
@@ -2619,12 +2631,14 @@ function ScoreMeter({
2619
2631
  }
2620
2632
 
2621
2633
  // src/components/data/SortMenu.tsx
2622
- import * as React14 from "react";
2623
- import { jsx as jsx36, jsxs as jsxs32 } from "react/jsx-runtime";
2634
+ import * as React15 from "react";
2635
+ import { jsx as jsx36, jsxs as jsxs33 } from "react/jsx-runtime";
2636
+ var SORT_MENU_BASE = 120;
2624
2637
  function SortMenu({ fields = [], sort, onSort, align = "right", size = "md", className = "", ...rest }) {
2625
- const [open, setOpen] = React14.useState(false);
2626
- const ref = React14.useRef(null);
2627
- React14.useEffect(() => {
2638
+ const [open, setOpen] = React15.useState(false);
2639
+ const zIndex = useOverlayLayer(SORT_MENU_BASE);
2640
+ const ref = React15.useRef(null);
2641
+ React15.useEffect(() => {
2628
2642
  if (!open) return;
2629
2643
  const away = (e) => {
2630
2644
  if (ref.current && !ref.current.contains(e.target)) setOpen(false);
@@ -2666,28 +2680,28 @@ function SortMenu({ fields = [], sort, onSort, align = "right", size = "md", cla
2666
2680
  }
2667
2681
  );
2668
2682
  };
2669
- return /* @__PURE__ */ jsxs32("span", { className, style: { position: "relative", display: "inline-flex" }, ref, ...rest, children: [
2670
- /* @__PURE__ */ jsxs32(Button, { size, variant: "secondary", icon: dir === "asc" ? "sort-ascending" : "sort-descending", onClick: () => setOpen(!open), children: [
2683
+ return /* @__PURE__ */ jsxs33("span", { className, style: { position: "relative", display: "inline-flex" }, ref, ...rest, children: [
2684
+ /* @__PURE__ */ jsxs33(Button, { size, variant: "secondary", icon: dir === "asc" ? "sort-ascending" : "sort-descending", onClick: () => setOpen(!open), children: [
2671
2685
  cur ? cur.label : "Unsorted",
2672
2686
  /* @__PURE__ */ jsx36("i", { className: "ph ph-" + (dir === "asc" ? "arrow-up" : "arrow-down"), style: { fontSize: 12, marginLeft: 6, opacity: 0.75 } })
2673
2687
  ] }),
2674
- open ? /* @__PURE__ */ jsx36("span", { className: "fd-view-enter", style: { position: "absolute", top: "calc(100% + 6px)", [align]: 0, zIndex: 120, 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: [
2688
+ 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: [
2675
2689
  /* @__PURE__ */ jsx36("span", { className: "fd-overline fd-muted", style: { padding: "4px 8px 6px" }, children: "Sort by" }),
2676
2690
  fields.map((f) => {
2677
2691
  const active = cur && cur.key === f.key;
2678
- return /* @__PURE__ */ jsxs32("span", { className: "fd-row", style: { gap: 8, padding: "4px 8px", borderRadius: 7, background: active ? "var(--surface-brand)" : "transparent" }, children: [
2692
+ return /* @__PURE__ */ jsxs33("span", { className: "fd-row", style: { gap: 8, padding: "4px 8px", borderRadius: 7, background: active ? "var(--surface-brand)" : "transparent" }, children: [
2679
2693
  /* @__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 }),
2680
2694
  arrow(f, "asc"),
2681
2695
  arrow(f, "desc")
2682
2696
  ] }, f.key);
2683
2697
  })
2684
- ] }) }) : null
2698
+ ] }) }) }) : null
2685
2699
  ] });
2686
2700
  }
2687
2701
 
2688
2702
  // src/components/data/StepList.tsx
2689
- import * as React15 from "react";
2690
- import { jsx as jsx37, jsxs as jsxs33 } from "react/jsx-runtime";
2703
+ import * as React16 from "react";
2704
+ import { jsx as jsx37, jsxs as jsxs34 } from "react/jsx-runtime";
2691
2705
  var KIND_ICON = { tool: "wrench", search: "magnifying-glass", read: "file-text", write: "pencil-simple", reasoning: "brain", run: "terminal", fetch: "cloud-arrow-down" };
2692
2706
  function StepList({
2693
2707
  steps = [],
@@ -2699,9 +2713,9 @@ function StepList({
2699
2713
  dense = false,
2700
2714
  className = ""
2701
2715
  }) {
2702
- const [openState, setOpenState] = React15.useState(defaultOpen);
2716
+ const [openState, setOpenState] = React16.useState(defaultOpen);
2703
2717
  const open = openProp == null ? openState : openProp;
2704
- const [expanded, setExpanded] = React15.useState({});
2718
+ const [expanded, setExpanded] = React16.useState({});
2705
2719
  if (!steps.length) return null;
2706
2720
  const running = steps.some((s) => s.status === "running");
2707
2721
  const failed = steps.filter((s) => s.status === "error").length;
@@ -2713,15 +2727,15 @@ function StepList({
2713
2727
  if (openProp == null) setOpenState(next);
2714
2728
  onToggle && onToggle(next);
2715
2729
  };
2716
- return /* @__PURE__ */ jsxs33("div", { className: ["fd-steps", dense ? "is-dense" : "", open ? "is-open" : "", className].filter(Boolean).join(" "), children: [
2717
- /* @__PURE__ */ jsxs33("button", { type: "button", className: "fd-steps-head", onClick: toggle, "aria-expanded": open, children: [
2730
+ return /* @__PURE__ */ jsxs34("div", { className: ["fd-steps", dense ? "is-dense" : "", open ? "is-open" : "", className].filter(Boolean).join(" "), children: [
2731
+ /* @__PURE__ */ jsxs34("button", { type: "button", className: "fd-steps-head", onClick: toggle, "aria-expanded": open, children: [
2718
2732
  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" }),
2719
2733
  /* @__PURE__ */ jsx37("span", { className: "fd-steps-title", children: summary }),
2720
- /* @__PURE__ */ jsxs33("span", { className: "fd-steps-count fd-tabular", children: [
2734
+ /* @__PURE__ */ jsxs34("span", { className: "fd-steps-count fd-tabular", children: [
2721
2735
  steps.length,
2722
2736
  " step",
2723
2737
  steps.length === 1 ? "" : "s",
2724
- failed ? /* @__PURE__ */ jsxs33("span", { className: "fd-steps-failed", children: [
2738
+ failed ? /* @__PURE__ */ jsxs34("span", { className: "fd-steps-failed", children: [
2725
2739
  " \xB7 ",
2726
2740
  failed,
2727
2741
  " failed"
@@ -2733,10 +2747,10 @@ function StepList({
2733
2747
  const id = s.id || i;
2734
2748
  const isOpen = !!expanded[id];
2735
2749
  const icon = KIND_ICON[s.kind || ""] || "dot-outline";
2736
- return /* @__PURE__ */ jsxs33("li", { className: "fd-step is-" + (s.status || "ok"), children: [
2737
- /* @__PURE__ */ jsxs33("div", { className: "fd-step-row", children: [
2750
+ return /* @__PURE__ */ jsxs34("li", { className: "fd-step is-" + (s.status || "ok"), children: [
2751
+ /* @__PURE__ */ jsxs34("div", { className: "fd-step-row", children: [
2738
2752
  /* @__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 }) }),
2739
- s.detail ? /* @__PURE__ */ jsxs33(
2753
+ s.detail ? /* @__PURE__ */ jsxs34(
2740
2754
  "button",
2741
2755
  {
2742
2756
  type: "button",
@@ -2759,8 +2773,8 @@ function StepList({
2759
2773
  }
2760
2774
 
2761
2775
  // src/components/data/VirtualList.tsx
2762
- import * as React16 from "react";
2763
- import { jsx as jsx38, jsxs as jsxs34 } from "react/jsx-runtime";
2776
+ import * as React17 from "react";
2777
+ import { jsx as jsx38, jsxs as jsxs35 } from "react/jsx-runtime";
2764
2778
  var VIRTUAL_LIST_BUFFER_ROWS = 20;
2765
2779
  var VIRTUAL_LIST_ROW_GAP = 6;
2766
2780
  function computeVirtualWindow(opts) {
@@ -2811,35 +2825,35 @@ function VirtualList({
2811
2825
  className = "",
2812
2826
  style
2813
2827
  }) {
2814
- const [scrollTop, setScrollTop] = React16.useState(0);
2815
- const loaded = React16.useMemo(
2828
+ const [scrollTop, setScrollTop] = React17.useState(0);
2829
+ const loaded = React17.useMemo(
2816
2830
  () => ({ firstItemIndex, count: items.length }),
2817
2831
  [firstItemIndex, items.length]
2818
2832
  );
2819
2833
  const total = Math.max(totalCount == null ? 0 : totalCount, firstItemIndex + items.length);
2820
2834
  const bandKey = firstItemIndex + ":" + items.length;
2821
- const win = React16.useMemo(
2835
+ const win = React17.useMemo(
2822
2836
  () => computeVirtualWindow({ scrollTop, viewportHeight: height, itemHeight, itemCount: total, loaded }),
2823
2837
  [scrollTop, height, itemHeight, total, loaded]
2824
2838
  );
2825
- const need = React16.useMemo(() => computeNeedMore(win, loaded), [win, loaded]);
2839
+ const need = React17.useMemo(() => computeNeedMore(win, loaded), [win, loaded]);
2826
2840
  const wantStart = need.start && hasMore?.start !== false;
2827
2841
  const wantEnd = need.end && hasMore?.end !== false;
2828
2842
  const bucket2 = Math.floor(win.visibleStart / VIRTUAL_LIST_BUFFER_ROWS);
2829
2843
  const askKey = bandKey + "@" + bucket2;
2830
- const asked = React16.useRef({ start: null, end: null });
2831
- React16.useEffect(() => {
2844
+ const asked = React17.useRef({ start: null, end: null });
2845
+ React17.useEffect(() => {
2832
2846
  if (loading || !wantStart || asked.current.start === askKey) return;
2833
2847
  asked.current.start = askKey;
2834
2848
  onNeedMore("start", win);
2835
2849
  }, [wantStart, loading, askKey, onNeedMore, win]);
2836
- React16.useEffect(() => {
2850
+ React17.useEffect(() => {
2837
2851
  if (loading || !wantEnd || asked.current.end === askKey) return;
2838
2852
  asked.current.end = askKey;
2839
2853
  onNeedMore("end", win);
2840
2854
  }, [wantEnd, loading, askKey, onNeedMore, win]);
2841
- const lastKeysRef = React16.useRef(null);
2842
- const newKeys = React16.useMemo(() => {
2855
+ const lastKeysRef = React17.useRef(null);
2856
+ const newKeys = React17.useMemo(() => {
2843
2857
  const prev = lastKeysRef.current;
2844
2858
  if (!prev) return /* @__PURE__ */ new Set();
2845
2859
  const fresh = /* @__PURE__ */ new Set();
@@ -2849,7 +2863,7 @@ function VirtualList({
2849
2863
  }
2850
2864
  return fresh;
2851
2865
  }, [items]);
2852
- React16.useEffect(() => {
2866
+ React17.useEffect(() => {
2853
2867
  lastKeysRef.current = new Set(items.map(keyOf));
2854
2868
  }, [items]);
2855
2869
  const gapStyle = { "--fd-vlist-gap": rowGap + "px" };
@@ -2873,8 +2887,8 @@ function VirtualList({
2873
2887
  )
2874
2888
  );
2875
2889
  }
2876
- return /* @__PURE__ */ jsxs34("div", { className: ["fd-vlist-wrap", className].filter(Boolean).join(" "), style: { height, position: "relative", ...gapStyle, ...style }, children: [
2877
- /* @__PURE__ */ jsxs34(
2890
+ return /* @__PURE__ */ jsxs35("div", { className: ["fd-vlist-wrap", className].filter(Boolean).join(" "), style: { height, position: "relative", ...gapStyle, ...style }, children: [
2891
+ /* @__PURE__ */ jsxs35(
2878
2892
  "div",
2879
2893
  {
2880
2894
  className: "fd-vlist fd-scrollbar",
@@ -2886,7 +2900,7 @@ function VirtualList({
2886
2900
  ]
2887
2901
  }
2888
2902
  ),
2889
- refreshing ? /* @__PURE__ */ jsx38("div", { className: "fd-vlist-refresh-scrim", children: /* @__PURE__ */ jsxs34("div", { className: "fd-vlist-refresh-card", children: [
2903
+ refreshing ? /* @__PURE__ */ jsx38("div", { className: "fd-vlist-refresh-scrim", children: /* @__PURE__ */ jsxs35("div", { className: "fd-vlist-refresh-card", children: [
2890
2904
  /* @__PURE__ */ jsx38("span", { className: "fd-spinner", "aria-hidden": "true" }),
2891
2905
  /* @__PURE__ */ jsx38("span", { className: "fd-body-sm", children: refreshingLabel })
2892
2906
  ] }) }) : null
@@ -2894,8 +2908,8 @@ function VirtualList({
2894
2908
  }
2895
2909
 
2896
2910
  // src/components/data/EntityRow.tsx
2897
- import * as React17 from "react";
2898
- import { jsx as jsx39, jsxs as jsxs35 } from "react/jsx-runtime";
2911
+ import * as React18 from "react";
2912
+ import { jsx as jsx39, jsxs as jsxs36 } from "react/jsx-runtime";
2899
2913
  var ENTITY_ROW_METRIC_WIDTH = 74;
2900
2914
  var METRIC_TONE_COLOR = {
2901
2915
  default: "var(--text-2)",
@@ -2907,7 +2921,7 @@ function EntityRowMetrics({ metrics, className = "", style }) {
2907
2921
  const key = m.id || m.label || i;
2908
2922
  const className2 = ["fd-erow-metric", m.tone && m.tone !== "default" ? "is-" + m.tone : "", m.tooltip != null ? "is-described" : ""].filter(Boolean).join(" ");
2909
2923
  const tone = { color: METRIC_TONE_COLOR[m.tone || "default"] };
2910
- const content = /* @__PURE__ */ jsxs35(React17.Fragment, { children: [
2924
+ const content = /* @__PURE__ */ jsxs36(React18.Fragment, { children: [
2911
2925
  m.icon ? /* @__PURE__ */ jsx39("i", { className: "ph ph-" + m.icon, "aria-hidden": "true" }) : null,
2912
2926
  /* @__PURE__ */ jsx39("span", { className: "fd-erow-metric-value fd-tabular", children: m.value }),
2913
2927
  /* @__PURE__ */ jsx39("span", { className: "fd-sr", children: " " + m.label })
@@ -2928,7 +2942,7 @@ function EntityRow({
2928
2942
  className = ""
2929
2943
  }) {
2930
2944
  const hasStrip = metrics && metrics.length > 0 || accessory != null;
2931
- return /* @__PURE__ */ jsxs35(
2945
+ return /* @__PURE__ */ jsxs36(
2932
2946
  "div",
2933
2947
  {
2934
2948
  onPointerDown,
@@ -2947,12 +2961,12 @@ function EntityRow({
2947
2961
  },
2948
2962
  children: [
2949
2963
  draggable ? /* @__PURE__ */ jsx39("i", { className: "ph ph-dots-six-vertical", "aria-hidden": "true", style: { fontSize: 14, flex: "none", color: "var(--text-muted)" } }) : null,
2950
- /* @__PURE__ */ jsxs35("span", { className: "fd-erow-body", children: [
2951
- /* @__PURE__ */ jsxs35("span", { className: "fd-erow-titleline", children: [
2964
+ /* @__PURE__ */ jsxs36("span", { className: "fd-erow-body", children: [
2965
+ /* @__PURE__ */ jsxs36("span", { className: "fd-erow-titleline", children: [
2952
2966
  /* @__PURE__ */ jsx39("span", { className: "fd-erow-title fd-body-sm", children: title }),
2953
2967
  meta ? /* @__PURE__ */ jsx39("span", { className: "fd-erow-meta", children: meta }) : null
2954
2968
  ] }),
2955
- hasStrip ? /* @__PURE__ */ jsxs35("span", { className: "fd-erow-strip", children: [
2969
+ hasStrip ? /* @__PURE__ */ jsxs36("span", { className: "fd-erow-strip", children: [
2956
2970
  metrics && metrics.length ? /* @__PURE__ */ jsx39(EntityRowMetrics, { metrics }) : null,
2957
2971
  accessory ? /* @__PURE__ */ jsx39("span", { className: "fd-erow-accessory", children: accessory }) : null
2958
2972
  ] }) : null
@@ -2975,18 +2989,18 @@ function EntityRow({
2975
2989
  }
2976
2990
 
2977
2991
  // src/components/data/TransferList.tsx
2978
- import * as React19 from "react";
2992
+ import * as React20 from "react";
2979
2993
  import { createPortal as createPortal4 } from "react-dom";
2980
2994
 
2981
2995
  // src/components/forms/field.tsx
2982
- import * as React18 from "react";
2983
- import { jsx as jsx40, jsxs as jsxs36 } from "react/jsx-runtime";
2996
+ import * as React19 from "react";
2997
+ import { jsx as jsx40, jsxs as jsxs37 } from "react/jsx-runtime";
2984
2998
  function useFieldId(id) {
2985
- const generated = React18.useId();
2999
+ const generated = React19.useId();
2986
3000
  return id || generated;
2987
3001
  }
2988
3002
  function FieldLabel({ htmlFor, id, required = false, onClick, children }) {
2989
- return /* @__PURE__ */ jsxs36("label", { className: "fd-field-label", htmlFor, id, onClick, children: [
3003
+ return /* @__PURE__ */ jsxs37("label", { className: "fd-field-label", htmlFor, id, onClick, children: [
2990
3004
  children,
2991
3005
  required ? /* @__PURE__ */ jsx40("span", { className: "fd-field-req", "aria-hidden": "true", children: "*" }) : null
2992
3006
  ] });
@@ -2998,7 +3012,7 @@ function useTriggerLabelling(label, id) {
2998
3012
  }
2999
3013
 
3000
3014
  // src/components/forms/Input.tsx
3001
- import { jsx as jsx41, jsxs as jsxs37 } from "react/jsx-runtime";
3015
+ import { jsx as jsx41, jsxs as jsxs38 } from "react/jsx-runtime";
3002
3016
  function Input({
3003
3017
  label,
3004
3018
  help,
@@ -3025,16 +3039,16 @@ function Input({
3025
3039
  disabled ? "fd-input-disabled" : "",
3026
3040
  size === "lg" ? "fd-input-lg" : ""
3027
3041
  ].filter(Boolean).join(" ");
3028
- return /* @__PURE__ */ jsxs37("div", { className: ["fd-field", className].filter(Boolean).join(" "), style, children: [
3042
+ return /* @__PURE__ */ jsxs38("div", { className: ["fd-field", className].filter(Boolean).join(" "), style, children: [
3029
3043
  label ? /* @__PURE__ */ jsx41(FieldLabel, { htmlFor: fieldId, required, children: label }) : null,
3030
- /* @__PURE__ */ jsxs37("div", { className: box, children: [
3044
+ /* @__PURE__ */ jsxs38("div", { className: box, children: [
3031
3045
  icon ? /* @__PURE__ */ jsx41("span", { className: "fd-input-icon", children: /* @__PURE__ */ jsx41("i", { className: "ph ph-" + icon, "aria-hidden": "true" }) }) : null,
3032
3046
  prefix ? /* @__PURE__ */ jsx41("span", { className: "fd-input-affix", children: prefix }) : null,
3033
3047
  /* @__PURE__ */ jsx41("input", { id: fieldId, disabled, style: inputStyle, "aria-invalid": error ? "true" : void 0, ...rest }),
3034
3048
  loading ? /* @__PURE__ */ jsx41("span", { className: "fd-spinner", style: { color: "var(--text-muted)" }, "aria-label": "Loading" }) : null,
3035
3049
  suffix && !loading ? /* @__PURE__ */ jsx41("span", { className: "fd-input-affix", children: suffix }) : null
3036
3050
  ] }),
3037
- error ? /* @__PURE__ */ jsxs37("span", { className: "fd-field-error", children: [
3051
+ error ? /* @__PURE__ */ jsxs38("span", { className: "fd-field-error", children: [
3038
3052
  /* @__PURE__ */ jsx41("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
3039
3053
  error
3040
3054
  ] }) : help ? /* @__PURE__ */ jsx41("span", { className: "fd-field-help", children: help }) : null
@@ -3086,7 +3100,7 @@ function SearchField({
3086
3100
  }
3087
3101
 
3088
3102
  // src/components/data/TransferList.tsx
3089
- import { jsx as jsx43, jsxs as jsxs38 } from "react/jsx-runtime";
3103
+ import { jsx as jsx43, jsxs as jsxs39 } from "react/jsx-runtime";
3090
3104
  var emptyHasMore = {};
3091
3105
  var DRAG_THRESHOLD_PX = 5;
3092
3106
  function TransferList({
@@ -3100,12 +3114,12 @@ function TransferList({
3100
3114
  listHeight = 440,
3101
3115
  className = ""
3102
3116
  }) {
3103
- const [drag, setDrag] = React19.useState(null);
3104
- const [dragOverSide, setDragOverSide] = React19.useState(null);
3105
- const dragRef = React19.useRef(null);
3106
- const armedRef = React19.useRef(null);
3107
- const sideRefs = React19.useRef({ left: null, right: null });
3108
- const hitTestSide = React19.useCallback((x, y) => {
3117
+ const [drag, setDrag] = React20.useState(null);
3118
+ const [dragOverSide, setDragOverSide] = React20.useState(null);
3119
+ const dragRef = React20.useRef(null);
3120
+ const armedRef = React20.useRef(null);
3121
+ const sideRefs = React20.useRef({ left: null, right: null });
3122
+ const hitTestSide = React20.useCallback((x, y) => {
3109
3123
  for (const side of ["left", "right"]) {
3110
3124
  const el = sideRefs.current[side];
3111
3125
  if (!el) continue;
@@ -3114,7 +3128,7 @@ function TransferList({
3114
3128
  }
3115
3129
  return null;
3116
3130
  }, []);
3117
- const findItem = React19.useCallback(
3131
+ const findItem = React20.useCallback(
3118
3132
  (side, key) => (side === "left" ? left.items : right.items).find((it) => keyOf(it) === key),
3119
3133
  [left.items, right.items, keyOf]
3120
3134
  );
@@ -3136,7 +3150,7 @@ function TransferList({
3136
3150
  height: rect.height
3137
3151
  };
3138
3152
  };
3139
- React19.useEffect(() => {
3153
+ React20.useEffect(() => {
3140
3154
  const onMovePointer = (e) => {
3141
3155
  const armed = armedRef.current;
3142
3156
  if (!armed || e.pointerId !== armed.pointerId) return;
@@ -3189,7 +3203,7 @@ function TransferList({
3189
3203
  window.removeEventListener("pointercancel", endDrag);
3190
3204
  };
3191
3205
  }, [hitTestSide, findItem, onMove]);
3192
- React19.useEffect(() => {
3206
+ React20.useEffect(() => {
3193
3207
  if (!drag || typeof document === "undefined") return;
3194
3208
  const prev = document.body.style.userSelect;
3195
3209
  document.body.style.userSelect = "none";
@@ -3199,7 +3213,7 @@ function TransferList({
3199
3213
  }, [drag]);
3200
3214
  const renderSide = (side, cfg, opposite) => {
3201
3215
  const showOverlay = drag != null && dragOverSide === side;
3202
- return /* @__PURE__ */ jsxs38(
3216
+ return /* @__PURE__ */ jsxs39(
3203
3217
  "div",
3204
3218
  {
3205
3219
  ref: (el) => {
@@ -3207,12 +3221,12 @@ function TransferList({
3207
3221
  },
3208
3222
  className: ["fd-tlist-side", dragOverSide === side ? "is-drop-target" : ""].filter(Boolean).join(" "),
3209
3223
  children: [
3210
- cfg.label ? /* @__PURE__ */ jsxs38("span", { className: "fd-overline fd-muted", children: [
3224
+ cfg.label ? /* @__PURE__ */ jsxs39("span", { className: "fd-overline fd-muted", children: [
3211
3225
  cfg.label,
3212
3226
  cfg.total != null ? " (" + cfg.total.toLocaleString() + ")" : ""
3213
3227
  ] }) : null,
3214
3228
  cfg.header ? /* @__PURE__ */ jsx43("div", { className: "fd-tlist-header", children: cfg.header }) : null,
3215
- /* @__PURE__ */ jsxs38("span", { className: "fd-row", style: { gap: 8 }, children: [
3229
+ /* @__PURE__ */ jsxs39("span", { className: "fd-row", style: { gap: 8 }, children: [
3216
3230
  /* @__PURE__ */ jsx43(SearchField, { value: cfg.search, onChange: cfg.onSearchChange, placeholder: "Search", "aria-label": (cfg.label || side) + " search", style: { flex: 1 } }),
3217
3231
  /* @__PURE__ */ jsx43(SortMenu, { fields: cfg.sortFields, sort: cfg.sort, onSort: cfg.onSort, align: side === "left" ? "left" : "right" })
3218
3232
  ] }),
@@ -3259,7 +3273,7 @@ function TransferList({
3259
3273
  }
3260
3274
  ),
3261
3275
  cfg.footer ? /* @__PURE__ */ jsx43("div", { className: "fd-tlist-footer", children: cfg.footer }) : null,
3262
- showOverlay ? /* @__PURE__ */ jsx43("div", { className: "fd-tlist-drop-overlay", "aria-hidden": "true", children: /* @__PURE__ */ jsxs38("span", { className: "fd-tlist-drop-card", children: [
3276
+ showOverlay ? /* @__PURE__ */ jsx43("div", { className: "fd-tlist-drop-overlay", "aria-hidden": "true", children: /* @__PURE__ */ jsxs39("span", { className: "fd-tlist-drop-card", children: [
3263
3277
  /* @__PURE__ */ jsx43("i", { className: "ph ph-tray-arrow-down", style: { fontSize: 18 }, "aria-hidden": "true" }),
3264
3278
  /* @__PURE__ */ jsx43("span", { className: "fd-body-sm", style: { fontWeight: 600 }, children: cfg.dropLabel || "Drop here" + (cfg.label ? " \u2014 " + cfg.label : "") })
3265
3279
  ] }) }) : null
@@ -3267,8 +3281,8 @@ function TransferList({
3267
3281
  }
3268
3282
  );
3269
3283
  };
3270
- return /* @__PURE__ */ jsxs38("div", { className: ["fd-tlist", className].filter(Boolean).join(" "), children: [
3271
- /* @__PURE__ */ jsxs38("div", { className: "fd-tlist-panes", children: [
3284
+ return /* @__PURE__ */ jsxs39("div", { className: ["fd-tlist", className].filter(Boolean).join(" "), children: [
3285
+ /* @__PURE__ */ jsxs39("div", { className: "fd-tlist-panes", children: [
3272
3286
  renderSide("left", left, "right"),
3273
3287
  renderSide("right", right, "left")
3274
3288
  ] }),
@@ -3297,19 +3311,19 @@ function TransferList({
3297
3311
  }
3298
3312
 
3299
3313
  // src/components/forms/Checkbox.tsx
3300
- import * as React20 from "react";
3301
- import { jsx as jsx44, jsxs as jsxs39 } from "react/jsx-runtime";
3314
+ import * as React21 from "react";
3315
+ import { jsx as jsx44, jsxs as jsxs40 } from "react/jsx-runtime";
3302
3316
  function Checkbox({ label, description, card = false, indeterminate = false, className = "", ...rest }) {
3303
- const ref = React20.useRef(null);
3304
- React20.useEffect(() => {
3317
+ const ref = React21.useRef(null);
3318
+ React21.useEffect(() => {
3305
3319
  if (ref.current) ref.current.indeterminate = indeterminate;
3306
3320
  }, [indeterminate]);
3307
- return /* @__PURE__ */ jsxs39("label", { className: ["fd-choice", card ? "fd-choice-card" : "", className].filter(Boolean).join(" "), children: [
3308
- /* @__PURE__ */ jsxs39("span", { className: "fd-choice-input", children: [
3321
+ return /* @__PURE__ */ jsxs40("label", { className: ["fd-choice", card ? "fd-choice-card" : "", className].filter(Boolean).join(" "), children: [
3322
+ /* @__PURE__ */ jsxs40("span", { className: "fd-choice-input", children: [
3309
3323
  /* @__PURE__ */ jsx44("input", { ref, type: "checkbox", ...rest }),
3310
3324
  /* @__PURE__ */ jsx44("span", { className: "fd-choice-box", "aria-hidden": "true", children: /* @__PURE__ */ jsx44("i", { className: indeterminate ? "ph ph-minus" : "ph ph-check" }) })
3311
3325
  ] }),
3312
- /* @__PURE__ */ jsxs39("span", { className: "fd-choice-text", children: [
3326
+ /* @__PURE__ */ jsxs40("span", { className: "fd-choice-text", children: [
3313
3327
  /* @__PURE__ */ jsx44("span", { className: "fd-choice-title", children: label }),
3314
3328
  description ? /* @__PURE__ */ jsx44("span", { className: "fd-choice-desc", children: description }) : null
3315
3329
  ] })
@@ -3317,14 +3331,14 @@ function Checkbox({ label, description, card = false, indeterminate = false, cla
3317
3331
  }
3318
3332
 
3319
3333
  // src/components/forms/Radio.tsx
3320
- import { jsx as jsx45, jsxs as jsxs40 } from "react/jsx-runtime";
3334
+ import { jsx as jsx45, jsxs as jsxs41 } from "react/jsx-runtime";
3321
3335
  function Radio({ label, description, card = false, className = "", ...rest }) {
3322
- return /* @__PURE__ */ jsxs40("label", { className: ["fd-choice", card ? "fd-choice-card" : "", className].filter(Boolean).join(" "), children: [
3323
- /* @__PURE__ */ jsxs40("span", { className: "fd-choice-input", children: [
3336
+ return /* @__PURE__ */ jsxs41("label", { className: ["fd-choice", card ? "fd-choice-card" : "", className].filter(Boolean).join(" "), children: [
3337
+ /* @__PURE__ */ jsxs41("span", { className: "fd-choice-input", children: [
3324
3338
  /* @__PURE__ */ jsx45("input", { type: "radio", ...rest }),
3325
3339
  /* @__PURE__ */ jsx45("span", { className: "fd-choice-box fd-choice-box-round", "aria-hidden": "true", children: /* @__PURE__ */ jsx45("span", { className: "fd-choice-dot" }) })
3326
3340
  ] }),
3327
- /* @__PURE__ */ jsxs40("span", { className: "fd-choice-text", children: [
3341
+ /* @__PURE__ */ jsxs41("span", { className: "fd-choice-text", children: [
3328
3342
  /* @__PURE__ */ jsx45("span", { className: "fd-choice-title", children: label }),
3329
3343
  description ? /* @__PURE__ */ jsx45("span", { className: "fd-choice-desc", children: description }) : null
3330
3344
  ] })
@@ -3332,12 +3346,12 @@ function Radio({ label, description, card = false, className = "", ...rest }) {
3332
3346
  }
3333
3347
 
3334
3348
  // src/components/forms/Switch.tsx
3335
- import { jsx as jsx46, jsxs as jsxs41 } from "react/jsx-runtime";
3349
+ import { jsx as jsx46, jsxs as jsxs42 } from "react/jsx-runtime";
3336
3350
  function Switch({ label, description, className = "", ...rest }) {
3337
- return /* @__PURE__ */ jsxs41("label", { className: ["fd-switch", className].filter(Boolean).join(" "), children: [
3351
+ return /* @__PURE__ */ jsxs42("label", { className: ["fd-switch", className].filter(Boolean).join(" "), children: [
3338
3352
  /* @__PURE__ */ jsx46("input", { type: "checkbox", role: "switch", ...rest }),
3339
3353
  /* @__PURE__ */ jsx46("span", { className: "fd-switch-track", children: /* @__PURE__ */ jsx46("span", { className: "fd-switch-thumb" }) }),
3340
- label ? /* @__PURE__ */ jsxs41("span", { className: "fd-choice-text", children: [
3354
+ label ? /* @__PURE__ */ jsxs42("span", { className: "fd-choice-text", children: [
3341
3355
  /* @__PURE__ */ jsx46("span", { className: "fd-switch-label", children: label }),
3342
3356
  description ? /* @__PURE__ */ jsx46("span", { className: "fd-choice-desc", children: description }) : null
3343
3357
  ] }) : null
@@ -3345,14 +3359,14 @@ function Switch({ label, description, className = "", ...rest }) {
3345
3359
  }
3346
3360
 
3347
3361
  // src/components/forms/Textarea.tsx
3348
- import { jsx as jsx47, jsxs as jsxs42 } from "react/jsx-runtime";
3362
+ import { jsx as jsx47, jsxs as jsxs43 } from "react/jsx-runtime";
3349
3363
  function Textarea({ label, help, error, required = false, rows = 4, disabled = false, id, className = "", style, ...rest }) {
3350
3364
  const fieldId = useFieldId(id);
3351
3365
  const box = ["fd-input", "fd-input-textarea", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" ");
3352
- return /* @__PURE__ */ jsxs42("div", { className: ["fd-field", className].filter(Boolean).join(" "), style, children: [
3366
+ return /* @__PURE__ */ jsxs43("div", { className: ["fd-field", className].filter(Boolean).join(" "), style, children: [
3353
3367
  label ? /* @__PURE__ */ jsx47(FieldLabel, { htmlFor: fieldId, required, children: label }) : null,
3354
3368
  /* @__PURE__ */ jsx47("div", { className: box, children: /* @__PURE__ */ jsx47("textarea", { id: fieldId, rows, disabled, "aria-invalid": error ? "true" : void 0, ...rest }) }),
3355
- error ? /* @__PURE__ */ jsxs42("span", { className: "fd-field-error", children: [
3369
+ error ? /* @__PURE__ */ jsxs43("span", { className: "fd-field-error", children: [
3356
3370
  /* @__PURE__ */ jsx47("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
3357
3371
  error
3358
3372
  ] }) : help ? /* @__PURE__ */ jsx47("span", { className: "fd-field-help", children: help }) : null
@@ -3360,8 +3374,8 @@ function Textarea({ label, help, error, required = false, rows = 4, disabled = f
3360
3374
  }
3361
3375
 
3362
3376
  // src/components/forms/NumberInput.tsx
3363
- import * as React21 from "react";
3364
- import { jsx as jsx48, jsxs as jsxs43 } from "react/jsx-runtime";
3377
+ import * as React22 from "react";
3378
+ import { jsx as jsx48, jsxs as jsxs44 } from "react/jsx-runtime";
3365
3379
  function NumberInput({
3366
3380
  label,
3367
3381
  help,
@@ -3388,10 +3402,10 @@ function NumberInput({
3388
3402
  const n = Number(String(v == null ? "" : v).replace(/[^0-9.-]/g, ""));
3389
3403
  return isNaN(n) ? null : n;
3390
3404
  };
3391
- const [text, setText] = React21.useState(value == null || value === "" ? "" : String(value));
3392
- const [editing, setEditing] = React21.useState(false);
3393
- const timer = React21.useRef(null);
3394
- React21.useEffect(() => {
3405
+ const [text, setText] = React22.useState(value == null || value === "" ? "" : String(value));
3406
+ const [editing, setEditing] = React22.useState(false);
3407
+ const timer = React22.useRef(null);
3408
+ React22.useEffect(() => {
3395
3409
  if (!editing) setText(value == null || value === "" ? "" : String(value));
3396
3410
  }, [value, editing]);
3397
3411
  const clamp = (n) => Math.min(max, Math.max(min, n));
@@ -3415,7 +3429,7 @@ function NumberInput({
3415
3429
  const release = () => {
3416
3430
  if (timer.current) clearTimeout(timer.current);
3417
3431
  };
3418
- React21.useEffect(() => () => {
3432
+ React22.useEffect(() => () => {
3419
3433
  if (timer.current) clearTimeout(timer.current);
3420
3434
  }, []);
3421
3435
  const shown = editing ? text : (() => {
@@ -3425,9 +3439,9 @@ function NumberInput({
3425
3439
  const box = ["fd-input", "fd-input-num", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" ");
3426
3440
  const fieldName = label || ariaLabel;
3427
3441
  const stepperName = (verb) => fieldName ? verb + " " + fieldName : verb;
3428
- return /* @__PURE__ */ jsxs43("div", { className: ["fd-field", className].filter(Boolean).join(" "), style, children: [
3442
+ return /* @__PURE__ */ jsxs44("div", { className: ["fd-field", className].filter(Boolean).join(" "), style, children: [
3429
3443
  label ? /* @__PURE__ */ jsx48(FieldLabel, { htmlFor: fieldId, required, children: label }) : null,
3430
- /* @__PURE__ */ jsxs43("div", { className: box, style: { gap: 8 }, children: [
3444
+ /* @__PURE__ */ jsxs44("div", { className: box, style: { gap: 8 }, children: [
3431
3445
  prefix ? /* @__PURE__ */ jsx48("span", { className: "fd-input-affix", children: prefix }) : null,
3432
3446
  /* @__PURE__ */ jsx48(
3433
3447
  "input",
@@ -3465,7 +3479,7 @@ function NumberInput({
3465
3479
  }
3466
3480
  ),
3467
3481
  suffix ? /* @__PURE__ */ jsx48("span", { className: "fd-input-affix", children: suffix }) : null,
3468
- /* @__PURE__ */ jsxs43("span", { className: "fd-row", style: { gap: 4, flex: "none" }, children: [
3482
+ /* @__PURE__ */ jsxs44("span", { className: "fd-row", style: { gap: 4, flex: "none" }, children: [
3469
3483
  /* @__PURE__ */ jsx48(
3470
3484
  "button",
3471
3485
  {
@@ -3494,7 +3508,7 @@ function NumberInput({
3494
3508
  )
3495
3509
  ] })
3496
3510
  ] }),
3497
- error ? /* @__PURE__ */ jsxs43("span", { className: "fd-field-error", children: [
3511
+ error ? /* @__PURE__ */ jsxs44("span", { className: "fd-field-error", children: [
3498
3512
  /* @__PURE__ */ jsx48("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
3499
3513
  error
3500
3514
  ] }) : help ? /* @__PURE__ */ jsx48("span", { className: "fd-field-help", children: help }) : null
@@ -3502,8 +3516,8 @@ function NumberInput({
3502
3516
  }
3503
3517
 
3504
3518
  // src/components/forms/Select.tsx
3505
- import * as React22 from "react";
3506
- import { jsx as jsx49, jsxs as jsxs44 } from "react/jsx-runtime";
3519
+ import * as React23 from "react";
3520
+ import { jsx as jsx49, jsxs as jsxs45 } from "react/jsx-runtime";
3507
3521
  var norm = (o) => typeof o === "string" ? { value: o, label: o } : o;
3508
3522
  function Select({
3509
3523
  label,
@@ -3529,13 +3543,13 @@ function Select({
3529
3543
  const isOn = (v) => multiple ? vals.includes(v) : v === value;
3530
3544
  const hasSearch = searchable === void 0 ? opts.length > 8 : searchable;
3531
3545
  const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
3532
- const [open, setOpen] = React22.useState(false);
3533
- const [q, setQ] = React22.useState("");
3534
- const [active, setActive] = React22.useState(-1);
3535
- const rootRef = React22.useRef(null);
3536
- const boxRef = React22.useRef(null);
3537
- const listRef = React22.useRef(null);
3538
- const typeBuf = React22.useRef({ s: "", t: 0 });
3546
+ const [open, setOpen] = React23.useState(false);
3547
+ const [q, setQ] = React23.useState("");
3548
+ const [active, setActive] = React23.useState(-1);
3549
+ const rootRef = React23.useRef(null);
3550
+ const boxRef = React23.useRef(null);
3551
+ const listRef = React23.useRef(null);
3552
+ const typeBuf = React23.useRef({ s: "", t: 0 });
3539
3553
  const selected = multiple ? null : opts.find((o) => o.value === value);
3540
3554
  const chosen = multiple ? opts.filter((o) => vals.includes(o.value)) : [];
3541
3555
  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;
@@ -3560,7 +3574,7 @@ function Select({
3560
3574
  }
3561
3575
  setOpen(!open);
3562
3576
  };
3563
- React22.useEffect(() => {
3577
+ React23.useEffect(() => {
3564
3578
  if (!open || active < 0 || !listRef.current) return;
3565
3579
  const el = listRef.current.querySelector('[data-i="' + active + '"]');
3566
3580
  if (el) {
@@ -3613,10 +3627,10 @@ function Select({
3613
3627
  else last.items.push({ o, i });
3614
3628
  });
3615
3629
  const box = ["fd-input", "fd-select", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" ");
3616
- return /* @__PURE__ */ jsxs44("div", { className: ["fd-field", "fd-popfield", open ? "is-open" : "", className].filter(Boolean).join(" "), style, ref: rootRef, children: [
3630
+ return /* @__PURE__ */ jsxs45("div", { className: ["fd-field", "fd-popfield", open ? "is-open" : "", className].filter(Boolean).join(" "), style, ref: rootRef, children: [
3617
3631
  label ? /* @__PURE__ */ jsx49(FieldLabel, { id: labelId, required, onClick: toggle, children: label }) : null,
3618
- /* @__PURE__ */ jsxs44("div", { className: box, style: { cursor: disabled ? "not-allowed" : "pointer" }, ref: boxRef, children: [
3619
- /* @__PURE__ */ jsxs44(
3632
+ /* @__PURE__ */ jsxs45("div", { className: box, style: { cursor: disabled ? "not-allowed" : "pointer" }, ref: boxRef, children: [
3633
+ /* @__PURE__ */ jsxs45(
3620
3634
  "button",
3621
3635
  {
3622
3636
  type: "button",
@@ -3664,7 +3678,7 @@ function Select({
3664
3678
  minWidth: 260,
3665
3679
  role: "presentation",
3666
3680
  style: { maxWidth: 380 },
3667
- header: hasSearch ? /* @__PURE__ */ jsxs44("div", { className: "fd-pop-search", children: [
3681
+ header: hasSearch ? /* @__PURE__ */ jsxs45("div", { className: "fd-pop-search", children: [
3668
3682
  /* @__PURE__ */ jsx49("i", { className: "ph ph-magnifying-glass", style: { color: "var(--text-muted)", fontSize: 14 } }),
3669
3683
  /* @__PURE__ */ jsx49(
3670
3684
  "input",
@@ -3681,7 +3695,7 @@ function Select({
3681
3695
  ),
3682
3696
  q ? /* @__PURE__ */ jsx49("span", { className: "fd-body-sm fd-muted", children: visible.length }) : null
3683
3697
  ] }) : void 0,
3684
- footer: multiple ? /* @__PURE__ */ jsxs44(React22.Fragment, { children: [
3698
+ footer: multiple ? /* @__PURE__ */ jsxs45(React23.Fragment, { children: [
3685
3699
  /* @__PURE__ */ jsx49(
3686
3700
  "button",
3687
3701
  {
@@ -3692,7 +3706,7 @@ function Select({
3692
3706
  }
3693
3707
  ),
3694
3708
  /* @__PURE__ */ jsx49("span", { style: { flex: 1 } }),
3695
- /* @__PURE__ */ jsxs44("span", { className: "fd-body-sm fd-muted", children: [
3709
+ /* @__PURE__ */ jsxs45("span", { className: "fd-body-sm fd-muted", children: [
3696
3710
  vals.length,
3697
3711
  " of ",
3698
3712
  opts.length
@@ -3708,13 +3722,13 @@ function Select({
3708
3722
  }
3709
3723
  )
3710
3724
  ] }) : void 0,
3711
- 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: [
3725
+ 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: [
3712
3726
  'Nothing matches "',
3713
3727
  q,
3714
3728
  '".'
3715
- ] }) : groups.map((grp) => /* @__PURE__ */ jsxs44(React22.Fragment, { children: [
3729
+ ] }) : groups.map((grp) => /* @__PURE__ */ jsxs45(React23.Fragment, { children: [
3716
3730
  grp.g ? /* @__PURE__ */ jsx49("div", { className: "fd-pop-group", children: grp.g }) : null,
3717
- grp.items.map(({ o, i }) => /* @__PURE__ */ jsxs44(
3731
+ grp.items.map(({ o, i }) => /* @__PURE__ */ jsxs45(
3718
3732
  "button",
3719
3733
  {
3720
3734
  type: "button",
@@ -3728,7 +3742,7 @@ function Select({
3728
3742
  children: [
3729
3743
  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,
3730
3744
  o.icon ? /* @__PURE__ */ jsx49("span", { className: "fd-opt-icon", children: /* @__PURE__ */ jsx49("i", { className: "ph ph-" + o.icon }) }) : null,
3731
- /* @__PURE__ */ jsxs44("span", { style: { flex: 1, minWidth: 0 }, children: [
3745
+ /* @__PURE__ */ jsxs45("span", { style: { flex: 1, minWidth: 0 }, children: [
3732
3746
  /* @__PURE__ */ jsx49("span", { className: "fd-opt-label", children: o.label }),
3733
3747
  o.description ? /* @__PURE__ */ jsx49("span", { className: "fd-opt-desc", children: o.description }) : null
3734
3748
  ] }),
@@ -3741,7 +3755,7 @@ function Select({
3741
3755
  ] }, grp.g || "_")) })
3742
3756
  }
3743
3757
  ),
3744
- error ? /* @__PURE__ */ jsxs44("span", { className: "fd-field-error", children: [
3758
+ error ? /* @__PURE__ */ jsxs45("span", { className: "fd-field-error", children: [
3745
3759
  /* @__PURE__ */ jsx49("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
3746
3760
  error
3747
3761
  ] }) : help ? /* @__PURE__ */ jsx49("span", { className: "fd-field-help", children: help }) : null
@@ -3749,8 +3763,8 @@ function Select({
3749
3763
  }
3750
3764
 
3751
3765
  // src/components/forms/DatePicker.tsx
3752
- import * as React23 from "react";
3753
- import { jsx as jsx50, jsxs as jsxs45 } from "react/jsx-runtime";
3766
+ import * as React24 from "react";
3767
+ import { jsx as jsx50, jsxs as jsxs46 } from "react/jsx-runtime";
3754
3768
  var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
3755
3769
  var DOW = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
3756
3770
  var iso = (d) => d.getFullYear() + "-" + String(d.getMonth() + 1).padStart(2, "0") + "-" + String(d.getDate()).padStart(2, "0");
@@ -3767,10 +3781,10 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3767
3781
  const today = /* @__PURE__ */ new Date();
3768
3782
  const sel = range ? value || {} : { start: value, end: value };
3769
3783
  const anchor = parse(sel.start) || parse(initialMonth) || today;
3770
- const [vy, setVy] = React23.useState(anchor.getFullYear());
3771
- const [vm, setVm] = React23.useState(anchor.getMonth());
3772
- const [mode2, setMode] = React23.useState("days");
3773
- const [hover, setHover] = React23.useState(null);
3784
+ const [vy, setVy] = React24.useState(anchor.getFullYear());
3785
+ const [vm, setVm] = React24.useState(anchor.getMonth());
3786
+ const [mode2, setMode] = React24.useState("days");
3787
+ const [hover, setHover] = React24.useState(null);
3774
3788
  const s = parse(sel.start), e = parse(sel.end);
3775
3789
  const hoverEnd = range && s && !e && hover ? parse(hover) : null;
3776
3790
  const inRange = (d) => {
@@ -3807,7 +3821,7 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3807
3821
  const startPad = new Date(y, m, 1).getDay();
3808
3822
  const cells = [];
3809
3823
  for (let i = 0; i < 42; i++) cells.push(new Date(y, m, i - startPad + 1));
3810
- return /* @__PURE__ */ jsxs45("div", { className: "fd-cal-grid", style: { width: months > 1 ? 252 : "auto", flex: "none" }, onMouseLeave: () => setHover(null), children: [
3824
+ return /* @__PURE__ */ jsxs46("div", { className: "fd-cal-grid", style: { width: months > 1 ? 252 : "auto", flex: "none" }, onMouseLeave: () => setHover(null), children: [
3811
3825
  DOW.map((d) => /* @__PURE__ */ jsx50("span", { className: "fd-cal-dow", children: d }, d)),
3812
3826
  cells.map((d, i) => /* @__PURE__ */ jsx50(
3813
3827
  "button",
@@ -3823,17 +3837,17 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3823
3837
  ] });
3824
3838
  };
3825
3839
  const nextY = vm === 11 ? vy + 1 : vy, nextM = (vm + 1) % 12;
3826
- return /* @__PURE__ */ jsxs45("div", { className: "fd-cal", style: { width: months > 1 && mode2 === "days" ? "auto" : void 0 }, children: [
3827
- /* @__PURE__ */ jsxs45("div", { className: "fd-cal-head", children: [
3840
+ return /* @__PURE__ */ jsxs46("div", { className: "fd-cal", style: { width: months > 1 && mode2 === "days" ? "auto" : void 0 }, children: [
3841
+ /* @__PURE__ */ jsxs46("div", { className: "fd-cal-head", children: [
3828
3842
  /* @__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" }) }),
3829
- /* @__PURE__ */ jsxs45("button", { type: "button", className: "fd-cal-title", onClick: () => setMode(mode2 === "days" ? "months" : mode2 === "months" ? "years" : "days"), children: [
3843
+ /* @__PURE__ */ jsxs46("button", { type: "button", className: "fd-cal-title", onClick: () => setMode(mode2 === "days" ? "months" : mode2 === "months" ? "years" : "days"), children: [
3830
3844
  mode2 === "days" ? MONTHS[vm] + " " + vy : mode2 === "months" ? vy : vy - 5 + " \u2013 " + (vy + 6),
3831
3845
  /* @__PURE__ */ jsx50("i", { className: "ph ph-caret-down", style: { fontSize: 10, marginLeft: 6, color: "var(--text-muted)" } })
3832
3846
  ] }),
3833
3847
  months > 1 && mode2 === "days" ? /* @__PURE__ */ jsx50("span", { className: "fd-cal-title", style: { cursor: "default", background: "none" }, children: MONTHS[nextM] + " " + nextY }) : null,
3834
3848
  /* @__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" }) })
3835
3849
  ] }),
3836
- mode2 === "days" ? /* @__PURE__ */ jsxs45("div", { style: { display: "flex", gap: 18 }, children: [
3850
+ mode2 === "days" ? /* @__PURE__ */ jsxs46("div", { style: { display: "flex", gap: 18 }, children: [
3837
3851
  monthGrid(vy, vm),
3838
3852
  months > 1 ? monthGrid(nextY, nextM) : null
3839
3853
  ] }) : mode2 === "months" ? /* @__PURE__ */ jsx50("div", { className: "fd-cal-grid-months", children: MONTHS.map((m, i) => /* @__PURE__ */ jsx50(
@@ -3861,7 +3875,7 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3861
3875
  },
3862
3876
  y
3863
3877
  )) }),
3864
- /* @__PURE__ */ jsxs45("div", { className: "fd-cal-foot", children: [
3878
+ /* @__PURE__ */ jsxs46("div", { className: "fd-cal-foot", children: [
3865
3879
  /* @__PURE__ */ jsx50(
3866
3880
  "button",
3867
3881
  {
@@ -3877,7 +3891,7 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3877
3891
  }
3878
3892
  ),
3879
3893
  /* @__PURE__ */ jsx50("span", { style: { flex: 1 } }),
3880
- range && sel.start ? /* @__PURE__ */ jsxs45("span", { className: "fd-body-sm fd-muted", children: [
3894
+ range && sel.start ? /* @__PURE__ */ jsxs46("span", { className: "fd-body-sm fd-muted", children: [
3881
3895
  fmt(sel.start),
3882
3896
  sel.end ? " \u2192 " + fmt(sel.end) : " \u2192 pick an end"
3883
3897
  ] }) : null
@@ -3886,16 +3900,16 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3886
3900
  }
3887
3901
  function DatePicker({ label, help, error, required = false, disabled = false, range = false, value, onChange, placeholder, id, className = "", style, ...rest }) {
3888
3902
  const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
3889
- const [open, setOpen] = React23.useState(false);
3890
- const rootRef = React23.useRef(null);
3891
- const boxRef = React23.useRef(null);
3903
+ const [open, setOpen] = React24.useState(false);
3904
+ const rootRef = React24.useRef(null);
3905
+ const boxRef = React24.useRef(null);
3892
3906
  const display = range ? value && value.start ? fmt(value.start) + (value.end ? " \u2192 " + fmt(value.end) : " \u2192 \u2026") : "" : fmt(value);
3893
3907
  const toggle = () => {
3894
3908
  if (!disabled) setOpen(!open);
3895
3909
  };
3896
- return /* @__PURE__ */ jsxs45("div", { className: ["fd-field", "fd-popfield", open ? "is-open" : "", className].filter(Boolean).join(" "), style, ref: rootRef, children: [
3910
+ return /* @__PURE__ */ jsxs46("div", { className: ["fd-field", "fd-popfield", open ? "is-open" : "", className].filter(Boolean).join(" "), style, ref: rootRef, children: [
3897
3911
  label ? /* @__PURE__ */ jsx50(FieldLabel, { id: labelId, required, onClick: toggle, children: label }) : null,
3898
- /* @__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: [
3912
+ /* @__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: [
3899
3913
  /* @__PURE__ */ jsx50("span", { className: "fd-input-icon", children: /* @__PURE__ */ jsx50("i", { className: "ph ph-calendar-blank", "aria-hidden": "true" }) }),
3900
3914
  /* @__PURE__ */ jsx50(
3901
3915
  "button",
@@ -3942,7 +3956,7 @@ function DatePicker({ label, help, error, required = false, disabled = false, ra
3942
3956
  )
3943
3957
  }
3944
3958
  ),
3945
- error ? /* @__PURE__ */ jsxs45("span", { className: "fd-field-error", children: [
3959
+ error ? /* @__PURE__ */ jsxs46("span", { className: "fd-field-error", children: [
3946
3960
  /* @__PURE__ */ jsx50("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
3947
3961
  error
3948
3962
  ] }) : help ? /* @__PURE__ */ jsx50("span", { className: "fd-field-help", children: help }) : null
@@ -3950,8 +3964,8 @@ function DatePicker({ label, help, error, required = false, disabled = false, ra
3950
3964
  }
3951
3965
 
3952
3966
  // src/components/forms/TimePicker.tsx
3953
- import * as React24 from "react";
3954
- import { jsx as jsx51, jsxs as jsxs46 } from "react/jsx-runtime";
3967
+ import * as React25 from "react";
3968
+ import { jsx as jsx51, jsxs as jsxs47 } from "react/jsx-runtime";
3955
3969
  var pad = (n) => String(n).padStart(2, "0");
3956
3970
  function ClockFace({ value = "09:00", onChange }) {
3957
3971
  let [h24, m] = value.split(":").map(Number);
@@ -3959,9 +3973,9 @@ function ClockFace({ value = "09:00", onChange }) {
3959
3973
  if (isNaN(m)) m = 0;
3960
3974
  const pm = h24 >= 12;
3961
3975
  const h12 = h24 % 12 === 0 ? 12 : h24 % 12;
3962
- const [mode2, setMode] = React24.useState("h");
3963
- const faceRef = React24.useRef(null);
3964
- const dragging = React24.useRef(false);
3976
+ const [mode2, setMode] = React25.useState("h");
3977
+ const faceRef = React25.useRef(null);
3978
+ const dragging = React25.useRef(false);
3965
3979
  const set = (h, mm, isPm) => onChange((isPm ? h % 12 + 12 : h % 12) + ":" + pad(mm));
3966
3980
  const R = 108, NR = 80;
3967
3981
  const nums = mode2 === "h" ? Array.from({ length: 12 }, (_, i) => i + 1) : Array.from({ length: 12 }, (_, i) => i * 5);
@@ -3996,8 +4010,8 @@ function ClockFace({ value = "09:00", onChange }) {
3996
4010
  };
3997
4011
  const handAngle = mode2 === "h" ? h12 % 12 * 30 : m * 6;
3998
4012
  const minuteOff = mode2 === "m" && m % 5 !== 0;
3999
- return /* @__PURE__ */ jsxs46("div", { style: { padding: "4px 14px 14px" }, children: [
4000
- /* @__PURE__ */ jsxs46("div", { className: "fd-clock-digits", children: [
4013
+ return /* @__PURE__ */ jsxs47("div", { style: { padding: "4px 14px 14px" }, children: [
4014
+ /* @__PURE__ */ jsxs47("div", { className: "fd-clock-digits", children: [
4001
4015
  /* @__PURE__ */ jsx51("button", { type: "button", className: "fd-clock-digit" + (mode2 === "h" ? " is-active" : ""), onClick: () => setMode("h"), children: pad(h12) }),
4002
4016
  /* @__PURE__ */ jsx51("span", { style: { fontSize: 24, fontWeight: 700, color: "var(--text-muted)" }, children: ":" }),
4003
4017
  /* @__PURE__ */ jsx51("button", { type: "button", className: "fd-clock-digit" + (mode2 === "m" ? " is-active" : ""), onClick: () => setMode("m"), children: pad(m) }),
@@ -4012,7 +4026,7 @@ function ClockFace({ value = "09:00", onChange }) {
4012
4026
  ap
4013
4027
  )) })
4014
4028
  ] }),
4015
- /* @__PURE__ */ jsxs46("div", { className: "fd-clock", ref: faceRef, onPointerDown: down, onPointerMove: move, onPointerUp: upH, children: [
4029
+ /* @__PURE__ */ jsxs47("div", { className: "fd-clock", ref: faceRef, onPointerDown: down, onPointerMove: move, onPointerUp: upH, children: [
4016
4030
  /* @__PURE__ */ jsx51("span", { className: "fd-clock-hand", style: { height: NR - (minuteOff ? 14 : 16), transform: "translateX(-50%) rotate(" + handAngle + "deg)", bottom: "50%" } }),
4017
4031
  /* @__PURE__ */ jsx51("span", { className: "fd-clock-pivot" }),
4018
4032
  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,
@@ -4034,9 +4048,9 @@ function ClockFace({ value = "09:00", onChange }) {
4034
4048
  }
4035
4049
  function TimePicker({ label, help, error, required = false, disabled = false, value = "", onChange, placeholder = "Pick a time", id, className = "", style }) {
4036
4050
  const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
4037
- const [open, setOpen] = React24.useState(false);
4038
- const rootRef = React24.useRef(null);
4039
- const boxRef = React24.useRef(null);
4051
+ const [open, setOpen] = React25.useState(false);
4052
+ const rootRef = React25.useRef(null);
4053
+ const boxRef = React25.useRef(null);
4040
4054
  const disp = () => {
4041
4055
  if (!value) return "";
4042
4056
  const [h, m] = value.split(":").map(Number);
@@ -4045,9 +4059,9 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
4045
4059
  const toggle = () => {
4046
4060
  if (!disabled) setOpen(!open);
4047
4061
  };
4048
- return /* @__PURE__ */ jsxs46("div", { className: ["fd-field", "fd-popfield", open ? "is-open" : "", className].filter(Boolean).join(" "), style, ref: rootRef, children: [
4062
+ return /* @__PURE__ */ jsxs47("div", { className: ["fd-field", "fd-popfield", open ? "is-open" : "", className].filter(Boolean).join(" "), style, ref: rootRef, children: [
4049
4063
  label ? /* @__PURE__ */ jsx51(FieldLabel, { id: labelId, required, onClick: toggle, children: label }) : null,
4050
- /* @__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: [
4064
+ /* @__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: [
4051
4065
  /* @__PURE__ */ jsx51("span", { className: "fd-input-icon", children: /* @__PURE__ */ jsx51("i", { className: "ph ph-clock", "aria-hidden": "true" }) }),
4052
4066
  /* @__PURE__ */ jsx51(
4053
4067
  "button",
@@ -4079,7 +4093,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
4079
4093
  offset: 6,
4080
4094
  width: 262,
4081
4095
  role: "presentation",
4082
- footer: /* @__PURE__ */ jsxs46(React24.Fragment, { children: [
4096
+ footer: /* @__PURE__ */ jsxs47(React25.Fragment, { children: [
4083
4097
  /* @__PURE__ */ jsx51(
4084
4098
  "button",
4085
4099
  {
@@ -4099,7 +4113,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
4099
4113
  children: /* @__PURE__ */ jsx51(ClockFace, { value: value || "09:00", onChange: (v) => onChange && onChange({ target: { value: v } }) })
4100
4114
  }
4101
4115
  ),
4102
- error ? /* @__PURE__ */ jsxs46("span", { className: "fd-field-error", children: [
4116
+ error ? /* @__PURE__ */ jsxs47("span", { className: "fd-field-error", children: [
4103
4117
  /* @__PURE__ */ jsx51("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
4104
4118
  error
4105
4119
  ] }) : help ? /* @__PURE__ */ jsx51("span", { className: "fd-field-help", children: help }) : null
@@ -4107,8 +4121,8 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
4107
4121
  }
4108
4122
 
4109
4123
  // src/components/forms/Slider.tsx
4110
- import * as React25 from "react";
4111
- import { jsx as jsx52, jsxs as jsxs47 } from "react/jsx-runtime";
4124
+ import * as React26 from "react";
4125
+ import { jsx as jsx52, jsxs as jsxs48 } from "react/jsx-runtime";
4112
4126
  function Slider({
4113
4127
  label,
4114
4128
  min = 0,
@@ -4125,15 +4139,15 @@ function Slider({
4125
4139
  ...rest
4126
4140
  }) {
4127
4141
  const fieldId = useFieldId(id);
4128
- const [dragging, setDragging] = React25.useState(false);
4142
+ const [dragging, setDragging] = React26.useState(false);
4129
4143
  const v = value === void 0 ? min : Number(value);
4130
4144
  const pct = max === min ? 0 : (v - min) / (max - min) * 100;
4131
- return /* @__PURE__ */ jsxs47("div", { className: ["fd-field", className].filter(Boolean).join(" "), children: [
4132
- label ? /* @__PURE__ */ jsxs47("div", { className: "fd-row", style: { justifyContent: "space-between", gap: 12 }, children: [
4145
+ return /* @__PURE__ */ jsxs48("div", { className: ["fd-field", className].filter(Boolean).join(" "), children: [
4146
+ label ? /* @__PURE__ */ jsxs48("div", { className: "fd-row", style: { justifyContent: "space-between", gap: 12 }, children: [
4133
4147
  /* @__PURE__ */ jsx52(FieldLabel, { htmlFor: fieldId, children: label }),
4134
4148
  /* @__PURE__ */ jsx52("span", { className: "fd-num", style: { color: "var(--text-2)" }, children: format(v) })
4135
4149
  ] }) : null,
4136
- /* @__PURE__ */ jsxs47("div", { className: "fd-slider", children: [
4150
+ /* @__PURE__ */ jsxs48("div", { className: "fd-slider", children: [
4137
4151
  /* @__PURE__ */ jsx52("span", { className: "fd-slider-fill", style: { width: pct + "%" } }),
4138
4152
  showChip && dragging ? /* @__PURE__ */ jsx52("span", { className: "fd-slider-chip", style: { left: pct + "%" }, children: format(v) }) : null,
4139
4153
  /* @__PURE__ */ jsx52(
@@ -4159,8 +4173,8 @@ function Slider({
4159
4173
  }
4160
4174
 
4161
4175
  // src/components/forms/RangeSlider.tsx
4162
- import * as React26 from "react";
4163
- import { jsx as jsx53, jsxs as jsxs48 } from "react/jsx-runtime";
4176
+ import * as React27 from "react";
4177
+ import { jsx as jsx53, jsxs as jsxs49 } from "react/jsx-runtime";
4164
4178
  function RangeSlider({
4165
4179
  label,
4166
4180
  min = 0,
@@ -4179,9 +4193,9 @@ function RangeSlider({
4179
4193
  }) {
4180
4194
  const fmt2 = format || ((v) => String(v));
4181
4195
  const [a, b] = value || [min, max];
4182
- const [drag, setDrag] = React26.useState(null);
4183
- const [focus, setFocus] = React26.useState(null);
4184
- const railRef = React26.useRef(null);
4196
+ const [drag, setDrag] = React27.useState(null);
4197
+ const [focus, setFocus] = React27.useState(null);
4198
+ const railRef = React27.useRef(null);
4185
4199
  const pct = (v) => max === min ? 0 : (v - min) / (max - min) * 100;
4186
4200
  const clampPair = (i, v) => {
4187
4201
  v = Math.min(max, Math.max(min, Math.round(v / step) * step));
@@ -4196,7 +4210,7 @@ function RangeSlider({
4196
4210
  const r = railRef.current.getBoundingClientRect();
4197
4211
  return min + Math.min(1, Math.max(0, (e.clientX - r.left) / r.width)) * (max - min);
4198
4212
  };
4199
- React26.useEffect(() => {
4213
+ React27.useEffect(() => {
4200
4214
  if (drag === null) return;
4201
4215
  const mv = (e) => onChange && onChange(clampPair(drag, fromEvent(e)));
4202
4216
  const upH = () => setDrag(null);
@@ -4265,19 +4279,19 @@ function RangeSlider({
4265
4279
  };
4266
4280
  const showChip = (i) => drag === i || focus === i;
4267
4281
  const hasLabels = marks.some((m) => m.label);
4268
- return /* @__PURE__ */ jsxs48("div", { className: ["fd-field", className].filter(Boolean).join(" "), ...rest, children: [
4269
- label ? /* @__PURE__ */ jsxs48("div", { className: "fd-row", style: { justifyContent: "space-between", gap: 12 }, children: [
4282
+ return /* @__PURE__ */ jsxs49("div", { className: ["fd-field", className].filter(Boolean).join(" "), ...rest, children: [
4283
+ label ? /* @__PURE__ */ jsxs49("div", { className: "fd-row", style: { justifyContent: "space-between", gap: 12 }, children: [
4270
4284
  /* @__PURE__ */ jsx53("span", { className: "fd-field-label", children: label }),
4271
- /* @__PURE__ */ jsxs48("span", { className: "fd-num", style: { color: "var(--text-2)" }, children: [
4285
+ /* @__PURE__ */ jsxs49("span", { className: "fd-num", style: { color: "var(--text-2)" }, children: [
4272
4286
  fmt2(a),
4273
4287
  " \u2013 ",
4274
4288
  fmt2(b)
4275
4289
  ] })
4276
4290
  ] }) : null,
4277
- /* @__PURE__ */ jsxs48("div", { className: "fd-range" + (hasLabels ? " has-labels" : ""), onPointerDown: onRailDown, children: [
4291
+ /* @__PURE__ */ jsxs49("div", { className: "fd-range" + (hasLabels ? " has-labels" : ""), onPointerDown: onRailDown, children: [
4278
4292
  /* @__PURE__ */ jsx53("span", { className: "fd-range-rail", ref: railRef }),
4279
4293
  /* @__PURE__ */ jsx53("span", { className: "fd-range-fill", style: { left: pct(a) + "%", width: pct(b) - pct(a) + "%" } }),
4280
- marks.map((m) => /* @__PURE__ */ jsxs48(React26.Fragment, { children: [
4294
+ marks.map((m) => /* @__PURE__ */ jsxs49(React27.Fragment, { children: [
4281
4295
  /* @__PURE__ */ jsx53("span", { className: "fd-range-mark" + (m.value >= a && m.value <= b ? " is-in" : ""), style: { left: pct(m.value) + "%" } }),
4282
4296
  m.label ? /* @__PURE__ */ jsx53("span", { className: "fd-range-mark-label", style: { left: pct(m.value) + "%" }, children: m.label }) : null
4283
4297
  ] }, m.value)),
@@ -4306,8 +4320,8 @@ function RangeSlider({
4306
4320
  }
4307
4321
 
4308
4322
  // src/components/forms/Dropzone.tsx
4309
- import * as React27 from "react";
4310
- import { jsx as jsx54, jsxs as jsxs49 } from "react/jsx-runtime";
4323
+ import * as React28 from "react";
4324
+ import { jsx as jsx54, jsxs as jsxs50 } from "react/jsx-runtime";
4311
4325
  function Dropzone({
4312
4326
  onFiles,
4313
4327
  onReject,
@@ -4321,8 +4335,8 @@ function Dropzone({
4321
4335
  className = "",
4322
4336
  style
4323
4337
  }) {
4324
- const [over, setOver] = React27.useState(false);
4325
- const depth = React27.useRef(0);
4338
+ const [over, setOver] = React28.useState(false);
4339
+ const depth = React28.useRef(0);
4326
4340
  const has = (e) => {
4327
4341
  const dt = e.dataTransfer;
4328
4342
  if (!dt) return false;
@@ -4352,7 +4366,7 @@ function Dropzone({
4352
4366
  if (rejected.length && onReject) onReject(rejected);
4353
4367
  if (accepted.length && onFiles) onFiles(accepted);
4354
4368
  };
4355
- return /* @__PURE__ */ jsxs49(
4369
+ return /* @__PURE__ */ jsxs50(
4356
4370
  "div",
4357
4371
  {
4358
4372
  className: ["fd-dropzone", over ? "is-over" : "", className].filter(Boolean).join(" "),
@@ -4363,7 +4377,7 @@ function Dropzone({
4363
4377
  onDrop: drop,
4364
4378
  children: [
4365
4379
  children,
4366
- over ? /* @__PURE__ */ jsx54("div", { className: "fd-dropzone-veil", "aria-hidden": "true", children: /* @__PURE__ */ jsxs49("div", { className: "fd-dropzone-card", children: [
4380
+ over ? /* @__PURE__ */ jsx54("div", { className: "fd-dropzone-veil", "aria-hidden": "true", children: /* @__PURE__ */ jsxs50("div", { className: "fd-dropzone-card", children: [
4367
4381
  /* @__PURE__ */ jsx54("i", { className: "ph ph-tray-arrow-down" }),
4368
4382
  /* @__PURE__ */ jsx54("span", { className: "fd-dropzone-label", children: label }),
4369
4383
  hint ? /* @__PURE__ */ jsx54("span", { className: "fd-dropzone-hint", children: hint }) : null
@@ -4384,8 +4398,8 @@ function FilePickButton({
4384
4398
  className = "",
4385
4399
  children
4386
4400
  }) {
4387
- const ref = React27.useRef(null);
4388
- return /* @__PURE__ */ jsxs49(React27.Fragment, { children: [
4401
+ const ref = React28.useRef(null);
4402
+ return /* @__PURE__ */ jsxs50(React28.Fragment, { children: [
4389
4403
  /* @__PURE__ */ jsx54(
4390
4404
  "button",
4391
4405
  {
@@ -4418,10 +4432,10 @@ function FilePickButton({
4418
4432
  }
4419
4433
  function useStagedFiles(upload, opts) {
4420
4434
  const o = opts || {};
4421
- const [items, setItems] = React27.useState([]);
4422
- const controllers = React27.useRef({});
4435
+ const [items, setItems] = React28.useState([]);
4436
+ const controllers = React28.useRef({});
4423
4437
  const patch = (id, next) => setItems((list) => list.map((f) => f.id === id ? Object.assign({}, f, next) : f));
4424
- const run = React27.useCallback((att) => {
4438
+ const run = React28.useCallback((att) => {
4425
4439
  if (!upload) return;
4426
4440
  const ac = typeof AbortController !== "undefined" ? new AbortController() : null;
4427
4441
  controllers.current[att.id] = ac;
@@ -4438,14 +4452,14 @@ function useStagedFiles(upload, opts) {
4438
4452
  delete controllers.current[att.id];
4439
4453
  });
4440
4454
  }, [upload]);
4441
- const add = React27.useCallback((files) => {
4455
+ const add = React28.useCallback((files) => {
4442
4456
  if (!upload) return [];
4443
4457
  const atts = Array.from(files).map((f) => toAttachment(f));
4444
4458
  setItems((list) => list.concat(atts));
4445
4459
  atts.forEach(run);
4446
4460
  return atts;
4447
4461
  }, [upload, run]);
4448
- const remove = React27.useCallback((att) => {
4462
+ const remove = React28.useCallback((att) => {
4449
4463
  const ac = controllers.current[att.id];
4450
4464
  if (ac) {
4451
4465
  try {
@@ -4456,10 +4470,10 @@ function useStagedFiles(upload, opts) {
4456
4470
  }
4457
4471
  setItems((list) => list.filter((f) => f.id !== att.id));
4458
4472
  }, []);
4459
- const retry = React27.useCallback((att) => {
4473
+ const retry = React28.useCallback((att) => {
4460
4474
  run(att);
4461
4475
  }, [run]);
4462
- const clear = React27.useCallback(() => {
4476
+ const clear = React28.useCallback(() => {
4463
4477
  Object.values(controllers.current).forEach((ac) => {
4464
4478
  try {
4465
4479
  ac && ac.abort();
@@ -4475,7 +4489,7 @@ function useStagedFiles(upload, opts) {
4475
4489
  var DropzoneKit = { useStagedFiles };
4476
4490
 
4477
4491
  // src/components/forms/FileGrid.tsx
4478
- import { jsx as jsx55, jsxs as jsxs50 } from "react/jsx-runtime";
4492
+ import { jsx as jsx55, jsxs as jsxs51 } from "react/jsx-runtime";
4479
4493
  var truncateMiddle = (name, max = 34) => {
4480
4494
  if (!name || name.length <= max) return name;
4481
4495
  const ext = /\.[A-Za-z0-9]+$/.exec(name);
@@ -4493,8 +4507,8 @@ function FileChip({ file, onOpen, onRemove, onRetry, compact: compact3 = false,
4493
4507
  const thumb = file.thumb && file.thumb.url || (image ? file.blobUrl || file.url : null);
4494
4508
  const meta = file.meta || (file.size ? formatBytes(file.size) : "");
4495
4509
  const clickable = !!onOpen && !uploading;
4496
- return /* @__PURE__ */ jsxs50("div", { className: ["fd-file", compact3 ? "is-compact" : "", file.error ? "is-error" : "", uploading ? "is-uploading" : "", className].filter(Boolean).join(" "), children: [
4497
- /* @__PURE__ */ jsxs50(
4510
+ return /* @__PURE__ */ jsxs51("div", { className: ["fd-file", compact3 ? "is-compact" : "", file.error ? "is-error" : "", uploading ? "is-uploading" : "", className].filter(Boolean).join(" "), children: [
4511
+ /* @__PURE__ */ jsxs51(
4498
4512
  "button",
4499
4513
  {
4500
4514
  type: "button",
@@ -4503,16 +4517,16 @@ function FileChip({ file, onOpen, onRemove, onRetry, compact: compact3 = false,
4503
4517
  onClick: clickable ? () => onOpen(file) : void 0,
4504
4518
  title: file.name + (meta ? " \xB7 " + meta : ""),
4505
4519
  children: [
4506
- /* @__PURE__ */ jsxs50("span", { className: "fd-file-icon", children: [
4520
+ /* @__PURE__ */ jsxs51("span", { className: "fd-file-icon", children: [
4507
4521
  thumb ? /* @__PURE__ */ jsx55("img", { src: thumb, alt: "" }) : /* @__PURE__ */ jsx55("i", { className: "ph ph-" + iconForMime(file.mime, file.name), "aria-hidden": "true" }),
4508
4522
  (file.mime || "").startsWith("video/") ? /* @__PURE__ */ jsx55("i", { className: "ph ph-play fd-file-play", "aria-hidden": "true" }) : null
4509
4523
  ] }),
4510
- /* @__PURE__ */ jsxs50("span", { className: "fd-file-text", children: [
4524
+ /* @__PURE__ */ jsxs51("span", { className: "fd-file-text", children: [
4511
4525
  /* @__PURE__ */ jsx55("span", { className: "fd-file-name", children: truncateMiddle(file.name, compact3 ? 26 : 40) }),
4512
- /* @__PURE__ */ jsx55("span", { className: "fd-file-meta", children: file.error ? /* @__PURE__ */ jsxs50("span", { className: "fd-file-err", children: [
4526
+ /* @__PURE__ */ jsx55("span", { className: "fd-file-meta", children: file.error ? /* @__PURE__ */ jsxs51("span", { className: "fd-file-err", children: [
4513
4527
  /* @__PURE__ */ jsx55("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
4514
4528
  file.error
4515
- ] }) : uploading ? /* @__PURE__ */ jsxs50("span", { className: "fd-tabular", children: [
4529
+ ] }) : uploading ? /* @__PURE__ */ jsxs51("span", { className: "fd-tabular", children: [
4516
4530
  Math.round(file.progress),
4517
4531
  "% uploaded"
4518
4532
  ] }) : meta })
@@ -4529,10 +4543,10 @@ function FileTile({ file, onOpen, onRemove, maxHeight = 200, className = "" }) {
4529
4543
  if (!file) return null;
4530
4544
  const src = file.thumb && file.thumb.url || file.blobUrl || file.url;
4531
4545
  const uploading = file.progress != null && file.progress < 100 && !file.error;
4532
- return /* @__PURE__ */ jsxs50("figure", { className: ["fd-tile", uploading ? "is-uploading" : "", file.error ? "is-error" : "", className].filter(Boolean).join(" "), children: [
4546
+ return /* @__PURE__ */ jsxs51("figure", { className: ["fd-tile", uploading ? "is-uploading" : "", file.error ? "is-error" : "", className].filter(Boolean).join(" "), children: [
4533
4547
  /* @__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" }) }) }),
4534
4548
  uploading ? /* @__PURE__ */ jsx55(Progress, { value: file.progress }) : null,
4535
- file.error ? /* @__PURE__ */ jsxs50("figcaption", { className: "fd-tile-err", children: [
4549
+ file.error ? /* @__PURE__ */ jsxs51("figcaption", { className: "fd-tile-err", children: [
4536
4550
  /* @__PURE__ */ jsx55("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
4537
4551
  file.error
4538
4552
  ] }) : null,
@@ -4556,9 +4570,9 @@ function FileCell({ file, onOpen, onRemove, onRetry }) {
4556
4570
  const image = isImage(file.mime, file.name);
4557
4571
  const thumb = file.thumb && file.thumb.url || (image ? file.blobUrl || file.url : null);
4558
4572
  const label = file.name + (file.size ? " \xB7 " + formatBytes(file.size) : "");
4559
- 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: [
4560
- /* @__PURE__ */ jsxs50("button", { type: "button", className: "fd-cell-main", onClick: onOpen ? () => onOpen(file) : void 0, disabled: !onOpen || uploading, "aria-label": "Open " + file.name, children: [
4561
- thumb ? /* @__PURE__ */ jsx55("img", { src: thumb, alt: "" }) : /* @__PURE__ */ jsxs50("span", { className: "fd-cell-doc", children: [
4573
+ 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: [
4574
+ /* @__PURE__ */ jsxs51("button", { type: "button", className: "fd-cell-main", onClick: onOpen ? () => onOpen(file) : void 0, disabled: !onOpen || uploading, "aria-label": "Open " + file.name, children: [
4575
+ thumb ? /* @__PURE__ */ jsx55("img", { src: thumb, alt: "" }) : /* @__PURE__ */ jsxs51("span", { className: "fd-cell-doc", children: [
4562
4576
  /* @__PURE__ */ jsx55("i", { className: "ph ph-" + iconForMime(file.mime, file.name), "aria-hidden": "true" }),
4563
4577
  /* @__PURE__ */ jsx55("span", { className: "fd-cell-name", children: shortName(file.name) }),
4564
4578
  /* @__PURE__ */ jsx55("span", { className: "fd-cell-size", children: file.meta || formatBytes(file.size) })
@@ -4576,15 +4590,15 @@ function FileGrid({ files = [], onOpen, onRemove, onRetry, tiles = true, maxHeig
4576
4590
  if (!list.length) return null;
4577
4591
  const pics = tiles ? list.filter((f) => isImage(f.mime, f.name)) : [];
4578
4592
  const rest = list.filter((f) => pics.indexOf(f) === -1);
4579
- return /* @__PURE__ */ jsxs50("div", { className: ["fd-filegrid", className].filter(Boolean).join(" "), children: [
4593
+ return /* @__PURE__ */ jsxs51("div", { className: ["fd-filegrid", className].filter(Boolean).join(" "), children: [
4580
4594
  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,
4581
4595
  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
4582
4596
  ] });
4583
4597
  }
4584
4598
 
4585
4599
  // src/components/forms/MarkdownEditor.tsx
4586
- import * as React28 from "react";
4587
- import { jsx as jsx56, jsxs as jsxs51 } from "react/jsx-runtime";
4600
+ import * as React29 from "react";
4601
+ import { jsx as jsx56, jsxs as jsxs52 } from "react/jsx-runtime";
4588
4602
  var isMac = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent || "");
4589
4603
  var INLINE_RE = /(\*\*\*[^*\n]+\*\*\*|\*\*[^*\n]+\*\*|__[^_\n]+__|~~[^~\n]+~~|`[^`\n]+`|\*[^*\s][^*\n]*\*|(?<![A-Za-z0-9_])_[^_\s][^_\n]*_|\[[^\]\n]*\]\([^)\s\n]*\)|https?:\/\/\S+)/g;
4590
4604
  function inlineParts(text) {
@@ -4797,7 +4811,7 @@ function syncDom(root, value) {
4797
4811
  while (root.children.length > lines.length) root.removeChild(root.lastChild);
4798
4812
  }
4799
4813
  var LIST_CONT = RE_LI;
4800
- var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
4814
+ var MarkdownEditor = React29.forwardRef(function MarkdownEditor2({
4801
4815
  value = "",
4802
4816
  onChange,
4803
4817
  onSubmit,
@@ -4816,10 +4830,10 @@ var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
4816
4830
  className = "",
4817
4831
  id
4818
4832
  }, ref) {
4819
- const boxRef = React28.useRef(null);
4820
- const composing = React28.useRef(false);
4821
- const pendingCaret = React28.useRef(null);
4822
- React28.useLayoutEffect(() => {
4833
+ const boxRef = React29.useRef(null);
4834
+ const composing = React29.useRef(false);
4835
+ const pendingCaret = React29.useRef(null);
4836
+ React29.useLayoutEffect(() => {
4823
4837
  const root = boxRef.current;
4824
4838
  if (!root || composing.current) return;
4825
4839
  const active = document.activeElement === root || root.contains(document.activeElement);
@@ -4828,7 +4842,7 @@ var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
4828
4842
  pendingCaret.current = null;
4829
4843
  if (active && caret != null) placeCaret(root, caret);
4830
4844
  }, [value]);
4831
- React28.useEffect(() => {
4845
+ React29.useEffect(() => {
4832
4846
  if (autoFocus && boxRef.current) boxRef.current.focus();
4833
4847
  }, [autoFocus]);
4834
4848
  const caretNow = () => {
@@ -4895,7 +4909,7 @@ var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
4895
4909
  api.replaceRange(from, to, next, from + next.length);
4896
4910
  }
4897
4911
  };
4898
- React28.useImperativeHandle(ref, () => api);
4912
+ React29.useImperativeHandle(ref, () => api);
4899
4913
  function detect(text, caret) {
4900
4914
  if (!onTrigger) return;
4901
4915
  const upto = text.slice(0, caret);
@@ -5008,7 +5022,7 @@ var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
5008
5022
  api.replaceRange(s.start, s.end, text.replace(/\r\n?/g, "\n"));
5009
5023
  };
5010
5024
  const lh = 1.55;
5011
- return /* @__PURE__ */ jsxs51("div", { className: ["fd-rme-wrap", disabled ? "is-disabled" : "", className].filter(Boolean).join(" "), children: [
5025
+ return /* @__PURE__ */ jsxs52("div", { className: ["fd-rme-wrap", disabled ? "is-disabled" : "", className].filter(Boolean).join(" "), children: [
5012
5026
  /* @__PURE__ */ jsx56(
5013
5027
  "div",
5014
5028
  {
@@ -5047,10 +5061,10 @@ var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
5047
5061
  });
5048
5062
 
5049
5063
  // src/components/platform/AccountMenu.tsx
5050
- import * as React30 from "react";
5064
+ import * as React31 from "react";
5051
5065
 
5052
5066
  // src/kits/session.ts
5053
- import * as React29 from "react";
5067
+ import * as React30 from "react";
5054
5068
  var PERMISSION_CATALOG = [
5055
5069
  { group: "Plans", items: [
5056
5070
  { key: "plan.view", label: "View plans", detail: "Read any plan in the workspace." },
@@ -6617,8 +6631,8 @@ function roadmap(overrides) {
6617
6631
  };
6618
6632
  }
6619
6633
  function useSession() {
6620
- const [s, setS] = React29.useState(getSession);
6621
- React29.useEffect(() => subscribe(setS), []);
6634
+ const [s, setS] = React30.useState(getSession);
6635
+ React30.useEffect(() => subscribe(setS), []);
6622
6636
  return s;
6623
6637
  }
6624
6638
  var SessionKit = {
@@ -6651,7 +6665,7 @@ var SessionKit = {
6651
6665
  };
6652
6666
 
6653
6667
  // src/components/platform/AccountMenu.tsx
6654
- import { Fragment as Fragment14, jsx as jsx57, jsxs as jsxs52 } from "react/jsx-runtime";
6668
+ import { Fragment as Fragment14, jsx as jsx57, jsxs as jsxs53 } from "react/jsx-runtime";
6655
6669
  var DEFAULT_LINKS = [
6656
6670
  { id: "profile", label: "Your profile", icon: "user-circle", href: "../admin/index.html#profile" },
6657
6671
  { id: "preferences", label: "Preferences", icon: "sliders-horizontal", href: "../admin/index.html#preferences" }
@@ -6662,7 +6676,7 @@ var DEFAULT_ADMIN_LINKS = [
6662
6676
  { id: "flags", label: "Feature flags", icon: "toggle-right", href: "../admin/index.html#flags", perm: "flags.manage" }
6663
6677
  ];
6664
6678
  function Item({ item, onPick }) {
6665
- return /* @__PURE__ */ jsxs52(
6679
+ return /* @__PURE__ */ jsxs53(
6666
6680
  "button",
6667
6681
  {
6668
6682
  type: "button",
@@ -6688,9 +6702,9 @@ function AccountMenu({
6688
6702
  ...rest
6689
6703
  }) {
6690
6704
  const session = SessionKit.useSession();
6691
- const [open, setOpen] = React30.useState(false);
6692
- const [switching, setSwitching] = React30.useState(false);
6693
- const ref = React30.useRef(null);
6705
+ const [open, setOpen] = React31.useState(false);
6706
+ const [switching, setSwitching] = React31.useState(false);
6707
+ const ref = React31.useRef(null);
6694
6708
  const user = session.user;
6695
6709
  const visibleAdmin = adminLinks.filter((l) => !l.perm || SessionKit.can(l.perm));
6696
6710
  const pick = (item) => {
@@ -6704,8 +6718,8 @@ function AccountMenu({
6704
6718
  if (onSignOut) return onSignOut();
6705
6719
  window.alert("Signed out. (Simulated \u2014 no auth provider is wired up.)");
6706
6720
  };
6707
- return /* @__PURE__ */ jsxs52(Fragment14, { children: [
6708
- /* @__PURE__ */ jsxs52(
6721
+ return /* @__PURE__ */ jsxs53(Fragment14, { children: [
6722
+ /* @__PURE__ */ jsxs53(
6709
6723
  "button",
6710
6724
  {
6711
6725
  type: "button",
@@ -6722,27 +6736,27 @@ function AccountMenu({
6722
6736
  ]
6723
6737
  }
6724
6738
  ),
6725
- /* @__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: [
6726
- /* @__PURE__ */ jsxs52("div", { className: "fd-row", style: { gap: 10, padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
6739
+ /* @__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: [
6740
+ /* @__PURE__ */ jsxs53("div", { className: "fd-row", style: { gap: 10, padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
6727
6741
  /* @__PURE__ */ jsx57(Avatar, { name: user.name }),
6728
- /* @__PURE__ */ jsxs52("span", { className: "fd-stack", style: { gap: 1, minWidth: 0, flex: 1 }, children: [
6742
+ /* @__PURE__ */ jsxs53("span", { className: "fd-stack", style: { gap: 1, minWidth: 0, flex: 1 }, children: [
6729
6743
  /* @__PURE__ */ jsx57("span", { className: "fd-body-sm", style: { fontWeight: 700 }, children: user.name }),
6730
6744
  /* @__PURE__ */ jsx57("span", { className: "fd-body-sm fd-muted fd-table-trunc", children: user.email })
6731
6745
  ] })
6732
6746
  ] }),
6733
6747
  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,
6734
6748
  /* @__PURE__ */ jsx57("div", { className: "fd-acct-group", children: links.map((l) => /* @__PURE__ */ jsx57(Item, { item: l, onPick: pick }, l.id)) }),
6735
- visibleAdmin.length ? /* @__PURE__ */ jsxs52("div", { className: "fd-acct-group", style: { borderTop: "1px solid var(--border)" }, children: [
6749
+ visibleAdmin.length ? /* @__PURE__ */ jsxs53("div", { className: "fd-acct-group", style: { borderTop: "1px solid var(--border)" }, children: [
6736
6750
  /* @__PURE__ */ jsx57("span", { className: "fd-overline fd-muted", style: { padding: "8px 14px 4px", display: "block" }, children: "Administration" }),
6737
6751
  visibleAdmin.map((l) => /* @__PURE__ */ jsx57(Item, { item: l, onPick: pick }, l.id))
6738
6752
  ] }) : null,
6739
- allowUserSwitch ? /* @__PURE__ */ jsxs52("div", { className: "fd-acct-group", style: { borderTop: "1px solid var(--border)" }, children: [
6740
- /* @__PURE__ */ jsxs52("button", { type: "button", role: "menuitem", className: "fd-acct-item", onClick: () => setSwitching((s) => !s), children: [
6753
+ allowUserSwitch ? /* @__PURE__ */ jsxs53("div", { className: "fd-acct-group", style: { borderTop: "1px solid var(--border)" }, children: [
6754
+ /* @__PURE__ */ jsxs53("button", { type: "button", role: "menuitem", className: "fd-acct-item", onClick: () => setSwitching((s) => !s), children: [
6741
6755
  /* @__PURE__ */ jsx57("i", { className: "ph ph-user-switch", "aria-hidden": "true" }),
6742
6756
  /* @__PURE__ */ jsx57("span", { style: { flex: 1 }, children: "View as another member" }),
6743
6757
  /* @__PURE__ */ jsx57("i", { className: "ph ph-caret-" + (switching ? "up" : "down"), "aria-hidden": "true", style: { fontSize: 11 } })
6744
6758
  ] }),
6745
- switching ? /* @__PURE__ */ jsx57("div", { className: "fd-stack", style: { gap: 0 }, children: session.allUsers.filter((u) => u.status === "active").map((u) => /* @__PURE__ */ jsxs52(
6759
+ switching ? /* @__PURE__ */ jsx57("div", { className: "fd-stack", style: { gap: 0 }, children: session.allUsers.filter((u) => u.status === "active").map((u) => /* @__PURE__ */ jsxs53(
6746
6760
  "button",
6747
6761
  {
6748
6762
  type: "button",
@@ -6755,7 +6769,7 @@ function AccountMenu({
6755
6769
  },
6756
6770
  children: [
6757
6771
  /* @__PURE__ */ jsx57(Avatar, { name: u.name, size: "sm" }),
6758
- /* @__PURE__ */ jsxs52("span", { className: "fd-stack", style: { gap: 0, flex: 1, minWidth: 0, alignItems: "flex-start" }, children: [
6772
+ /* @__PURE__ */ jsxs53("span", { className: "fd-stack", style: { gap: 0, flex: 1, minWidth: 0, alignItems: "flex-start" }, children: [
6759
6773
  /* @__PURE__ */ jsx57("span", { style: { fontWeight: u.id === user.id ? 700 : 500 }, children: u.name }),
6760
6774
  /* @__PURE__ */ jsx57("span", { className: "fd-muted", style: { fontSize: 11.5 }, children: u.roles.join(", ") })
6761
6775
  ] }),
@@ -6765,7 +6779,7 @@ function AccountMenu({
6765
6779
  u.id
6766
6780
  )) }) : null
6767
6781
  ] }) : null,
6768
- /* @__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: [
6782
+ /* @__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: [
6769
6783
  /* @__PURE__ */ jsx57("i", { className: "ph ph-sign-out", "aria-hidden": "true" }),
6770
6784
  /* @__PURE__ */ jsx57("span", { style: { flex: 1 }, children: "Sign out" })
6771
6785
  ] }) })
@@ -6774,14 +6788,14 @@ function AccountMenu({
6774
6788
  }
6775
6789
 
6776
6790
  // src/components/platform/ApiSpecBrowser.tsx
6777
- import * as React31 from "react";
6778
- import { jsx as jsx58, jsxs as jsxs53 } from "react/jsx-runtime";
6791
+ import * as React32 from "react";
6792
+ import { jsx as jsx58, jsxs as jsxs54 } from "react/jsx-runtime";
6779
6793
  var METHOD_TONE = { GET: "success", POST: "info", PATCH: "warning", PUT: "warning", DELETE: "danger" };
6780
6794
  function Json({ obj }) {
6781
6795
  return /* @__PURE__ */ jsx58("pre", { className: "fd-json", children: JSON.stringify(obj, null, 2) });
6782
6796
  }
6783
6797
  function Endpoint({ s, onRequest }) {
6784
- const [tried, setTried] = React31.useState(null);
6798
+ const [tried, setTried] = React32.useState(null);
6785
6799
  const run = async () => {
6786
6800
  setTried("busy");
6787
6801
  const t0 = (window.performance || Date).now();
@@ -6792,13 +6806,13 @@ function Endpoint({ s, onRequest }) {
6792
6806
  setTried({ ms: Math.round((window.performance || Date).now() - t0), error: String(e && e.message || e) });
6793
6807
  }
6794
6808
  };
6795
- return /* @__PURE__ */ jsx58(Card, { elevation: "flat", padded: false, children: /* @__PURE__ */ jsxs53("div", { className: "fd-stack", style: { gap: 0 }, children: [
6796
- /* @__PURE__ */ jsxs53("div", { className: "fd-row", style: { gap: 10, padding: "14px 18px", flexWrap: "wrap" }, children: [
6809
+ return /* @__PURE__ */ jsx58(Card, { elevation: "flat", padded: false, children: /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 0 }, children: [
6810
+ /* @__PURE__ */ jsxs54("div", { className: "fd-row", style: { gap: 10, padding: "14px 18px", flexWrap: "wrap" }, children: [
6797
6811
  /* @__PURE__ */ jsx58(Badge, { tone: METHOD_TONE[s.method] || "neutral", children: s.method }),
6798
6812
  /* @__PURE__ */ jsx58("code", { className: "fd-mono", style: { fontSize: 12.5, fontWeight: 600, color: "var(--text)", wordBreak: "break-all" }, children: s.path }),
6799
6813
  s.isList ? /* @__PURE__ */ jsx58(Badge, { tone: "neutral", icon: "rows", children: "Paged list" }) : null,
6800
6814
  /* @__PURE__ */ jsx58("span", { style: { flex: 1 } }),
6801
- /* @__PURE__ */ jsxs53("span", { className: "fd-body-sm fd-muted fd-mono", children: [
6815
+ /* @__PURE__ */ jsxs54("span", { className: "fd-body-sm fd-muted fd-mono", children: [
6802
6816
  s.latency[0],
6803
6817
  "\u2013",
6804
6818
  s.latency[1],
@@ -6806,31 +6820,31 @@ function Endpoint({ s, onRequest }) {
6806
6820
  ] }),
6807
6821
  /* @__PURE__ */ jsx58(Button, { size: "sm", variant: "secondary", icon: "play", loading: tried === "busy", onClick: run, children: "Try it" })
6808
6822
  ] }),
6809
- /* @__PURE__ */ jsxs53("div", { className: "fd-stack", style: { gap: 14, padding: "0 18px 16px" }, children: [
6810
- /* @__PURE__ */ jsxs53("div", { className: "fd-stack", style: { gap: 6 }, children: [
6823
+ /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 14, padding: "0 18px 16px" }, children: [
6824
+ /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 6 }, children: [
6811
6825
  /* @__PURE__ */ jsx58("span", { className: "fd-body-sm", style: { fontWeight: 700 }, children: s.title }),
6812
6826
  /* @__PURE__ */ jsx58("p", { className: "fd-body-sm fd-secondary", style: { margin: 0, textWrap: "pretty" }, children: s.purpose }),
6813
6827
  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
6814
6828
  ] }),
6815
- /* @__PURE__ */ jsxs53("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(280px,1fr))", gap: 12, alignItems: "start" }, children: [
6816
- s.request ? /* @__PURE__ */ jsxs53("div", { className: "fd-stack", style: { gap: 6 }, children: [
6829
+ /* @__PURE__ */ jsxs54("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(280px,1fr))", gap: 12, alignItems: "start" }, children: [
6830
+ s.request ? /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 6 }, children: [
6817
6831
  /* @__PURE__ */ jsx58("span", { className: "fd-overline fd-muted", children: "Request body" }),
6818
6832
  /* @__PURE__ */ jsx58(Json, { obj: s.request })
6819
6833
  ] }) : null,
6820
- s.query ? /* @__PURE__ */ jsxs53("div", { className: "fd-stack", style: { gap: 6 }, children: [
6834
+ s.query ? /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 6 }, children: [
6821
6835
  /* @__PURE__ */ jsx58("span", { className: "fd-overline fd-muted", children: "Query" }),
6822
6836
  /* @__PURE__ */ jsx58(Json, { obj: s.query })
6823
6837
  ] }) : null,
6824
- /* @__PURE__ */ jsxs53("div", { className: "fd-stack", style: { gap: 6 }, children: [
6838
+ /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 6 }, children: [
6825
6839
  /* @__PURE__ */ jsx58("span", { className: "fd-overline fd-muted", children: "Response 200" }),
6826
6840
  /* @__PURE__ */ jsx58(Json, { obj: s.response })
6827
6841
  ] })
6828
6842
  ] }),
6829
6843
  s.notes ? /* @__PURE__ */ jsx58(Flag, { tone: "info", statement: "Implementation note", cost: s.notes, actions: null }) : null,
6830
- tried && tried !== "busy" ? /* @__PURE__ */ jsxs53("div", { className: "fd-stack", style: { gap: 6 }, children: [
6831
- /* @__PURE__ */ jsxs53("span", { className: "fd-row", style: { gap: 8 }, children: [
6844
+ tried && tried !== "busy" ? /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 6 }, children: [
6845
+ /* @__PURE__ */ jsxs54("span", { className: "fd-row", style: { gap: 8 }, children: [
6832
6846
  /* @__PURE__ */ jsx58("span", { className: "fd-overline fd-muted", children: "Simulated response" }),
6833
- /* @__PURE__ */ jsxs53(Badge, { tone: tried.error ? "danger" : "success", icon: "timer", children: [
6847
+ /* @__PURE__ */ jsxs54(Badge, { tone: tried.error ? "danger" : "success", icon: "timer", children: [
6834
6848
  tried.ms,
6835
6849
  "ms"
6836
6850
  ] })
@@ -6854,29 +6868,29 @@ function ApiSpecBrowser({
6854
6868
  className = "",
6855
6869
  ...rest
6856
6870
  }) {
6857
- const [q, setQ] = React31.useState("");
6858
- const [method, setMethod] = React31.useState(null);
6859
- const [mod, setMod] = React31.useState(null);
6860
- const [listOnly, setListOnly] = React31.useState(false);
6871
+ const [q, setQ] = React32.useState("");
6872
+ const [method, setMethod] = React32.useState(null);
6873
+ const [mod, setMod] = React32.useState(null);
6874
+ const [listOnly, setListOnly] = React32.useState(false);
6861
6875
  const activeModule = modules && modules.find((m) => m.id === mod);
6862
6876
  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())));
6863
6877
  const effGroups = groups && groups.length ? groups : [["All endpoints", spec.map((s) => s.id)]];
6864
6878
  const methods = [...new Set(spec.map((s) => s.method))];
6865
6879
  const listCount = spec.filter((s) => s.isList).length;
6866
- return /* @__PURE__ */ jsxs53("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 20, maxWidth: 1100 }, ...rest, children: [
6867
- /* @__PURE__ */ jsxs53("div", { className: "fd-stack", style: { gap: 10 }, children: [
6880
+ return /* @__PURE__ */ jsxs54("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 20, maxWidth: 1100 }, ...rest, children: [
6881
+ /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 10 }, children: [
6868
6882
  kicker ? /* @__PURE__ */ jsx58("span", { className: "fd-overline fd-muted", children: kicker }) : null,
6869
6883
  /* @__PURE__ */ jsx58("h1", { className: "fd-h1", style: { margin: 0 }, children: title }),
6870
6884
  lede ? /* @__PURE__ */ jsx58("p", { className: "fd-body fd-secondary fd-prose", style: { margin: 0 }, children: lede }) : null
6871
6885
  ] }),
6872
- modules && modules.length ? /* @__PURE__ */ jsxs53("div", { className: "fd-stack", style: { gap: 8 }, children: [
6886
+ modules && modules.length ? /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 8 }, children: [
6873
6887
  /* @__PURE__ */ jsx58("span", { className: "fd-overline fd-muted", children: "Filter by screen \u2014 every endpoint that screen depends on" }),
6874
- /* @__PURE__ */ jsxs53("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: [
6875
- /* @__PURE__ */ jsxs53(Tag, { icon: "stack", selected: !mod, onClick: () => setMod(null), children: [
6888
+ /* @__PURE__ */ jsxs54("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: [
6889
+ /* @__PURE__ */ jsxs54(Tag, { icon: "stack", selected: !mod, onClick: () => setMod(null), children: [
6876
6890
  "All screens ",
6877
6891
  /* @__PURE__ */ jsx58("span", { className: "fd-mono", children: spec.length })
6878
6892
  ] }),
6879
- modules.map((m) => /* @__PURE__ */ jsxs53(Tag, { icon: m.icon, selected: mod === m.id, onClick: () => setMod(mod === m.id ? null : m.id), children: [
6893
+ modules.map((m) => /* @__PURE__ */ jsxs54(Tag, { icon: m.icon, selected: mod === m.id, onClick: () => setMod(mod === m.id ? null : m.id), children: [
6880
6894
  m.label,
6881
6895
  " ",
6882
6896
  /* @__PURE__ */ jsx58("span", { className: "fd-mono", children: m.endpoints.length })
@@ -6893,19 +6907,19 @@ function ApiSpecBrowser({
6893
6907
  ) : null
6894
6908
  ] }) : null,
6895
6909
  sourceNote ? /* @__PURE__ */ jsx58(Flag, { tone: "info", statement: "Design-first: this page is the spec.", cost: sourceNote, actions: null }) : null,
6896
- /* @__PURE__ */ jsxs53("div", { className: "fd-row", style: { gap: 10, flexWrap: "wrap" }, children: [
6910
+ /* @__PURE__ */ jsxs54("div", { className: "fd-row", style: { gap: 10, flexWrap: "wrap" }, children: [
6897
6911
  /* @__PURE__ */ jsx58(Input, { icon: "magnifying-glass", placeholder: "Find an endpoint, screen, or behavior", value: q, onChange: (e) => setQ(e.target.value), style: { width: 300 } }),
6898
- methods.map((m) => /* @__PURE__ */ jsxs53(Tag, { selected: method === m, onClick: () => setMethod(method === m ? null : m), children: [
6912
+ methods.map((m) => /* @__PURE__ */ jsxs54(Tag, { selected: method === m, onClick: () => setMethod(method === m ? null : m), children: [
6899
6913
  m,
6900
6914
  " ",
6901
6915
  /* @__PURE__ */ jsx58("span", { className: "fd-mono", children: spec.filter((s) => s.method === m).length })
6902
6916
  ] }, m)),
6903
- listCount ? /* @__PURE__ */ jsxs53(Tag, { icon: "rows", selected: listOnly, onClick: () => setListOnly(!listOnly), children: [
6917
+ listCount ? /* @__PURE__ */ jsxs54(Tag, { icon: "rows", selected: listOnly, onClick: () => setListOnly(!listOnly), children: [
6904
6918
  "Paged lists ",
6905
6919
  /* @__PURE__ */ jsx58("span", { className: "fd-mono", children: listCount })
6906
6920
  ] }) : null,
6907
6921
  /* @__PURE__ */ jsx58("span", { style: { flex: 1 } }),
6908
- /* @__PURE__ */ jsxs53("span", { className: "fd-body-sm fd-muted", children: [
6922
+ /* @__PURE__ */ jsxs54("span", { className: "fd-body-sm fd-muted", children: [
6909
6923
  hits.length,
6910
6924
  " of ",
6911
6925
  spec.length,
@@ -6916,18 +6930,18 @@ function ApiSpecBrowser({
6916
6930
  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]) => {
6917
6931
  const items = hits.filter((s) => ids.indexOf(s.id) >= 0);
6918
6932
  if (!items.length) return null;
6919
- return /* @__PURE__ */ jsxs53("div", { className: "fd-stack", style: { gap: 12 }, children: [
6933
+ return /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 12 }, children: [
6920
6934
  /* @__PURE__ */ jsx58("span", { className: "fd-label-lg", children: g }),
6921
6935
  items.map((s) => /* @__PURE__ */ jsx58(Endpoint, { s, onRequest }, s.id))
6922
6936
  ] }, g);
6923
6937
  }),
6924
- 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: [
6938
+ 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: [
6925
6939
  /* @__PURE__ */ jsx58("span", { className: "fd-overline fd-muted", style: { width: 110, flex: "none", paddingTop: 2 }, children: k }),
6926
6940
  /* @__PURE__ */ jsx58("span", { className: "fd-body-sm fd-secondary", style: { textWrap: "pretty" }, children: v })
6927
6941
  ] }, k)) }) }) : null,
6928
- 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: [
6942
+ 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: [
6929
6943
  /* @__PURE__ */ jsx58(Badge, { tone: "danger", children: id }),
6930
- /* @__PURE__ */ jsxs53("span", { className: "fd-stack", style: { gap: 2, flex: 1 }, children: [
6944
+ /* @__PURE__ */ jsxs54("span", { className: "fd-stack", style: { gap: 2, flex: 1 }, children: [
6931
6945
  /* @__PURE__ */ jsx58("span", { className: "fd-body-sm", style: { fontWeight: 600 }, children: question }),
6932
6946
  /* @__PURE__ */ jsx58("span", { className: "fd-body-sm fd-muted", children: why })
6933
6947
  ] })
@@ -6936,8 +6950,8 @@ function ApiSpecBrowser({
6936
6950
  }
6937
6951
 
6938
6952
  // src/components/platform/ProfilePage.tsx
6939
- import * as React32 from "react";
6940
- import { jsx as jsx59, jsxs as jsxs54 } from "react/jsx-runtime";
6953
+ import * as React33 from "react";
6954
+ import { jsx as jsx59, jsxs as jsxs55 } from "react/jsx-runtime";
6941
6955
  var TIMEZONES = ["America/New_York", "America/Chicago", "America/Denver", "America/Los_Angeles", "America/Anchorage", "Pacific/Honolulu", "Europe/London", "Europe/Berlin"];
6942
6956
  var NOTIFY = [
6943
6957
  { key: "planShared", label: "A plan is shared with me", detail: "Someone sends you a plan or a client link." },
@@ -6949,7 +6963,7 @@ var NOTIFY = [
6949
6963
  function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSessions = true, className = "", ...rest }) {
6950
6964
  const session = SessionKit.useSession();
6951
6965
  const user = userProp || session.user;
6952
- const [draft, setDraft] = React32.useState(() => ({
6966
+ const [draft, setDraft] = React33.useState(() => ({
6953
6967
  name: user.name || "",
6954
6968
  title: user.title || "",
6955
6969
  email: user.email || "",
@@ -6958,8 +6972,8 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
6958
6972
  bio: user.bio || "",
6959
6973
  notify: user.notify || { planShared: true, planChanged: true, goalMissed: true, flagChanged: false, weekly: true }
6960
6974
  }));
6961
- const [saving, setSaving] = React32.useState(false);
6962
- const [saved, setSaved] = React32.useState(false);
6975
+ const [saving, setSaving] = React33.useState(false);
6976
+ const [saved, setSaved] = React33.useState(false);
6963
6977
  const set = (k, v) => {
6964
6978
  setDraft((d) => Object.assign({}, d, { [k]: v }));
6965
6979
  setSaved(false);
@@ -6981,22 +6995,22 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
6981
6995
  { id: "s2", device: "iPhone 15 \xB7 Safari", where: "Denver, CO", when: "2 hours ago" },
6982
6996
  { id: "s3", device: "Windows \xB7 Edge", where: "Chicago, IL", when: "Aug 12" }
6983
6997
  ];
6984
- return /* @__PURE__ */ jsxs54("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 20, maxWidth: 860 }, ...rest, children: [
6985
- /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 10 }, children: [
6998
+ return /* @__PURE__ */ jsxs55("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 20, maxWidth: 860 }, ...rest, children: [
6999
+ /* @__PURE__ */ jsxs55("div", { className: "fd-stack", style: { gap: 10 }, children: [
6986
7000
  /* @__PURE__ */ jsx59("span", { className: "fd-overline fd-muted", children: "Account" }),
6987
7001
  /* @__PURE__ */ jsx59("h1", { className: "fd-h1", style: { margin: 0 }, children: "Your profile" }),
6988
7002
  /* @__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." })
6989
7003
  ] }),
6990
- /* @__PURE__ */ jsx59(Card, { elevation: "flat", children: /* @__PURE__ */ jsxs54("div", { className: "fd-row", style: { gap: 16, flexWrap: "wrap", alignItems: "flex-start" }, children: [
7004
+ /* @__PURE__ */ jsx59(Card, { elevation: "flat", children: /* @__PURE__ */ jsxs55("div", { className: "fd-row", style: { gap: 16, flexWrap: "wrap", alignItems: "flex-start" }, children: [
6991
7005
  /* @__PURE__ */ jsx59(Avatar, { name: draft.name || user.name, size: "lg" }),
6992
- /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 4, flex: 1, minWidth: 200 }, children: [
7006
+ /* @__PURE__ */ jsxs55("div", { className: "fd-stack", style: { gap: 4, flex: 1, minWidth: 200 }, children: [
6993
7007
  /* @__PURE__ */ jsx59("span", { className: "fd-h3", style: { margin: 0 }, children: draft.name || user.name }),
6994
- /* @__PURE__ */ jsxs54("span", { className: "fd-body-sm fd-muted", children: [
7008
+ /* @__PURE__ */ jsxs55("span", { className: "fd-body-sm fd-muted", children: [
6995
7009
  draft.title || "No title set",
6996
7010
  " \xB7 ",
6997
7011
  user.team || "No team"
6998
7012
  ] }),
6999
- /* @__PURE__ */ jsxs54("span", { className: "fd-row", style: { gap: 6, flexWrap: "wrap", paddingTop: 4 }, children: [
7013
+ /* @__PURE__ */ jsxs55("span", { className: "fd-row", style: { gap: 6, flexWrap: "wrap", paddingTop: 4 }, children: [
7000
7014
  session.roles.map((r) => /* @__PURE__ */ jsx59(Badge, { tone: r.id === "owner" ? "success" : "neutral", children: r.name }, r.id)),
7001
7015
  user.sso ? /* @__PURE__ */ jsx59(Badge, { tone: "info", icon: "shield-check", children: "SSO" }) : null
7002
7016
  ] })
@@ -7006,17 +7020,17 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
7006
7020
  /* @__PURE__ */ jsx59(
7007
7021
  Card,
7008
7022
  {
7009
- title: /* @__PURE__ */ jsxs54("span", { className: "fd-stack", style: { gap: 2 }, children: [
7023
+ title: /* @__PURE__ */ jsxs55("span", { className: "fd-stack", style: { gap: 2 }, children: [
7010
7024
  /* @__PURE__ */ jsx59("span", { children: "Identity" }),
7011
7025
  /* @__PURE__ */ jsx59("span", { className: "fd-body-sm fd-muted", style: { fontWeight: 400 }, children: "Name and title appear on plans you share" })
7012
7026
  ] }),
7013
7027
  elevation: "flat",
7014
- children: /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 14 }, children: [
7015
- /* @__PURE__ */ jsxs54("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(220px,1fr))", gap: 14 }, children: [
7028
+ children: /* @__PURE__ */ jsxs55("div", { className: "fd-stack", style: { gap: 14 }, children: [
7029
+ /* @__PURE__ */ jsxs55("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(220px,1fr))", gap: 14 }, children: [
7016
7030
  /* @__PURE__ */ jsx59(Input, { label: "Full name", value: draft.name, onChange: (e) => set("name", e.target.value) }),
7017
7031
  /* @__PURE__ */ jsx59(Input, { label: "Job title", value: draft.title, onChange: (e) => set("title", e.target.value), placeholder: "e.g. Senior media planner" })
7018
7032
  ] }),
7019
- /* @__PURE__ */ jsxs54("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(220px,1fr))", gap: 14 }, children: [
7033
+ /* @__PURE__ */ jsxs55("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(220px,1fr))", gap: 14 }, children: [
7020
7034
  /* @__PURE__ */ jsx59(
7021
7035
  Input,
7022
7036
  {
@@ -7043,7 +7057,7 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
7043
7057
  ] })
7044
7058
  }
7045
7059
  ),
7046
- /* @__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: [
7060
+ /* @__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: [
7047
7061
  /* @__PURE__ */ jsx59(
7048
7062
  Select,
7049
7063
  {
@@ -7059,7 +7073,7 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
7059
7073
  /* @__PURE__ */ jsx59(
7060
7074
  Card,
7061
7075
  {
7062
- title: /* @__PURE__ */ jsxs54("span", { className: "fd-stack", style: { gap: 2 }, children: [
7076
+ title: /* @__PURE__ */ jsxs55("span", { className: "fd-stack", style: { gap: 2 }, children: [
7063
7077
  /* @__PURE__ */ jsx59("span", { children: "Notifications" }),
7064
7078
  /* @__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" })
7065
7079
  ] }),
@@ -7067,10 +7081,10 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
7067
7081
  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)) })
7068
7082
  }
7069
7083
  ),
7070
- /* @__PURE__ */ jsxs54(
7084
+ /* @__PURE__ */ jsxs55(
7071
7085
  Card,
7072
7086
  {
7073
- title: /* @__PURE__ */ jsxs54("span", { className: "fd-stack", style: { gap: 2 }, children: [
7087
+ title: /* @__PURE__ */ jsxs55("span", { className: "fd-stack", style: { gap: 2 }, children: [
7074
7088
  /* @__PURE__ */ jsx59("span", { children: "Access" }),
7075
7089
  /* @__PURE__ */ jsx59("span", { className: "fd-body-sm fd-muted", style: { fontWeight: 400 }, children: "What your roles grant you" })
7076
7090
  ] }),
@@ -7086,9 +7100,9 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
7086
7100
  }
7087
7101
  ),
7088
7102
  children: [
7089
- /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 0 }, children: [
7103
+ /* @__PURE__ */ jsxs55("div", { className: "fd-stack", style: { gap: 0 }, children: [
7090
7104
  /* @__PURE__ */ jsx59(CardRow, { label: "Roles", children: session.roles.map((r) => r.name).join(", ") || "None" }),
7091
- /* @__PURE__ */ jsxs54(CardRow, { label: "Permissions", children: [
7105
+ /* @__PURE__ */ jsxs55(CardRow, { label: "Permissions", children: [
7092
7106
  session.permissions.length,
7093
7107
  " granted"
7094
7108
  ] }),
@@ -7104,11 +7118,11 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
7104
7118
  title: "Signed-in devices",
7105
7119
  elevation: "flat",
7106
7120
  action: /* @__PURE__ */ jsx59(Button, { size: "sm", variant: "ghost", icon: "sign-out", children: "Sign out everywhere" }),
7107
- 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: [
7121
+ 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: [
7108
7122
  /* @__PURE__ */ jsx59("i", { className: "ph ph-device-mobile", style: { fontSize: 16, color: "var(--text-muted)" }, "aria-hidden": "true" }),
7109
- /* @__PURE__ */ jsxs54("span", { className: "fd-stack", style: { gap: 1, flex: 1, minWidth: 160 }, children: [
7123
+ /* @__PURE__ */ jsxs55("span", { className: "fd-stack", style: { gap: 1, flex: 1, minWidth: 160 }, children: [
7110
7124
  /* @__PURE__ */ jsx59("span", { className: "fd-body-sm", style: { fontWeight: 600 }, children: s.device }),
7111
- /* @__PURE__ */ jsxs54("span", { className: "fd-body-sm fd-muted", children: [
7125
+ /* @__PURE__ */ jsxs55("span", { className: "fd-body-sm fd-muted", children: [
7112
7126
  s.where,
7113
7127
  " \xB7 ",
7114
7128
  s.when
@@ -7118,7 +7132,7 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
7118
7132
  ] }, s.id)) })
7119
7133
  }
7120
7134
  ) : null,
7121
- /* @__PURE__ */ jsxs54("div", { className: "fd-row", style: {
7135
+ /* @__PURE__ */ jsxs55("div", { className: "fd-row", style: {
7122
7136
  gap: 10,
7123
7137
  flexWrap: "wrap",
7124
7138
  position: "sticky",
@@ -7149,10 +7163,10 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
7149
7163
  }
7150
7164
 
7151
7165
  // src/components/platform/RoadmapTimeline.tsx
7152
- import * as React34 from "react";
7166
+ import * as React35 from "react";
7153
7167
 
7154
7168
  // src/kits/runtime.ts
7155
- import * as React33 from "react";
7169
+ import * as React34 from "react";
7156
7170
  var WIRED_ENDPOINTS = [
7157
7171
  // Nothing yet. Every id below would come from a real service:
7158
7172
  // "plan.get", "placements.list", …
@@ -7323,8 +7337,8 @@ var RuntimeKit = {
7323
7337
  };
7324
7338
  RuntimeKit.declare(FEATURE_NEEDS);
7325
7339
  function useRuntimeMode() {
7326
- const [m, setM] = React33.useState(RuntimeKit.getMode());
7327
- React33.useEffect(() => RuntimeKit.subscribe(setM), []);
7340
+ const [m, setM] = React34.useState(RuntimeKit.getMode());
7341
+ React34.useEffect(() => RuntimeKit.subscribe(setM), []);
7328
7342
  return m;
7329
7343
  }
7330
7344
  function useFeatureStatus(key) {
@@ -7343,7 +7357,7 @@ var UseRuntimeMode = useRuntimeMode;
7343
7357
  var UseFeatureStatus = useFeatureStatus;
7344
7358
 
7345
7359
  // src/components/platform/RoadmapTimeline.tsx
7346
- import { jsx as jsx60, jsxs as jsxs55 } from "react/jsx-runtime";
7360
+ import { jsx as jsx60, jsxs as jsxs56 } from "react/jsx-runtime";
7347
7361
  var STATUS = {
7348
7362
  shipped: { tone: "success", icon: "check-circle", label: "Wired" },
7349
7363
  next: { tone: "warning", icon: "traffic-cone", label: "Not wired" },
@@ -7358,24 +7372,24 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
7358
7372
  const s = STATUS[item.status] || STATUS.planned;
7359
7373
  const deps = (item.dependsOn || []).map((k) => byKey[k]).filter(Boolean);
7360
7374
  const blocking = deps.filter((d) => !d.implemented);
7361
- return /* @__PURE__ */ jsx60(Card, { elevation: "flat", children: /* @__PURE__ */ jsxs55("div", { className: "fd-stack", style: { gap: 10 }, children: [
7362
- /* @__PURE__ */ jsxs55("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: [
7375
+ return /* @__PURE__ */ jsx60(Card, { elevation: "flat", children: /* @__PURE__ */ jsxs56("div", { className: "fd-stack", style: { gap: 10 }, children: [
7376
+ /* @__PURE__ */ jsxs56("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: [
7363
7377
  /* @__PURE__ */ jsx60("span", { className: "fd-body", style: { fontWeight: 700, flex: 1, minWidth: 140 }, children: item.label }),
7364
7378
  /* @__PURE__ */ jsx60(Badge, { tone: "neutral", icon: PROJECT_ICON[item.project] || "squares-four", children: item.project }),
7365
7379
  /* @__PURE__ */ jsx60(Badge, { tone: s.tone, icon: s.icon, children: s.label })
7366
7380
  ] }),
7367
7381
  /* @__PURE__ */ jsx60("p", { className: "fd-body-sm fd-secondary", style: { margin: 0, textWrap: "pretty" }, children: item.description }),
7368
- item.backend ? /* @__PURE__ */ jsxs55("div", { className: "fd-row", style: { gap: 10, alignItems: "flex-start" }, children: [
7382
+ item.backend ? /* @__PURE__ */ jsxs56("div", { className: "fd-row", style: { gap: 10, alignItems: "flex-start" }, children: [
7369
7383
  /* @__PURE__ */ jsx60("span", { className: "fd-overline fd-muted", style: { width: 62, flex: "none", paddingTop: 2 }, children: "Backend" }),
7370
7384
  /* @__PURE__ */ jsx60("span", { className: "fd-body-sm", style: { flex: 1, textWrap: "pretty" }, children: item.backend })
7371
7385
  ] }) : null,
7372
- /* @__PURE__ */ jsxs55("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
7373
- item.effort ? /* @__PURE__ */ jsxs55("span", { className: "fd-body-sm fd-muted", children: [
7386
+ /* @__PURE__ */ jsxs56("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
7387
+ item.effort ? /* @__PURE__ */ jsxs56("span", { className: "fd-body-sm fd-muted", children: [
7374
7388
  /* @__PURE__ */ jsx60("i", { className: "ph ph-hourglass-medium" }),
7375
7389
  " ",
7376
7390
  item.effort
7377
7391
  ] }) : null,
7378
- /* @__PURE__ */ jsxs55("span", { className: "fd-body-sm fd-muted", children: [
7392
+ /* @__PURE__ */ jsxs56("span", { className: "fd-body-sm fd-muted", children: [
7379
7393
  /* @__PURE__ */ jsx60("i", { className: "ph ph-user" }),
7380
7394
  " ",
7381
7395
  item.owner
@@ -7392,11 +7406,11 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
7392
7406
  }
7393
7407
  )
7394
7408
  ] }),
7395
- deps.length ? /* @__PURE__ */ jsxs55("div", { className: "fd-row", style: { gap: 6, flexWrap: "wrap", paddingTop: 6, borderTop: "1px solid var(--border)" }, children: [
7409
+ deps.length ? /* @__PURE__ */ jsxs56("div", { className: "fd-row", style: { gap: 6, flexWrap: "wrap", paddingTop: 6, borderTop: "1px solid var(--border)" }, children: [
7396
7410
  /* @__PURE__ */ jsx60("span", { className: "fd-overline fd-muted", style: { paddingTop: 3 }, children: "After" }),
7397
7411
  deps.map((d) => /* @__PURE__ */ jsx60(Tag, { icon: d.implemented ? "check" : "clock", children: d.label }, d.key))
7398
7412
  ] }) : null,
7399
- blocking.length && !item.implemented ? /* @__PURE__ */ jsxs55("span", { className: "fd-body-sm", style: { color: "var(--warn-text)" }, children: [
7413
+ blocking.length && !item.implemented ? /* @__PURE__ */ jsxs56("span", { className: "fd-body-sm", style: { color: "var(--warn-text)" }, children: [
7400
7414
  "Blocked until ",
7401
7415
  blocking.map((d) => d.label).join(" and "),
7402
7416
  " ",
@@ -7407,12 +7421,12 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
7407
7421
  }
7408
7422
  function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
7409
7423
  const session = SessionKit.useSession();
7410
- const [project, setProject] = React34.useState("");
7411
- const [q, setQ] = React34.useState("");
7412
- const scrollRef = React34.useRef(null);
7413
- const nowRef = React34.useRef(null);
7414
- const rm = React34.useMemo(() => SessionKit.roadmap({ isComplete: RuntimeKit.isComplete }), [session]);
7415
- const byKey = React34.useMemo(() => {
7424
+ const [project, setProject] = React35.useState("");
7425
+ const [q, setQ] = React35.useState("");
7426
+ const scrollRef = React35.useRef(null);
7427
+ const nowRef = React35.useRef(null);
7428
+ const rm = React35.useMemo(() => SessionKit.roadmap({ isComplete: RuntimeKit.isComplete }), [session]);
7429
+ const byKey = React35.useMemo(() => {
7416
7430
  const m = {};
7417
7431
  rm.items.forEach((i) => {
7418
7432
  m[i.key] = i;
@@ -7421,7 +7435,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
7421
7435
  }, [rm]);
7422
7436
  const items = rm.items.filter((i) => (!project || i.project === project) && (!q || (i.label + " " + i.description + " " + (i.backend || "") + " " + i.key).toLowerCase().includes(q.toLowerCase())));
7423
7437
  const projects = [...new Set(rm.items.map((i) => i.project))];
7424
- React34.useEffect(() => {
7438
+ React35.useEffect(() => {
7425
7439
  let raf1 = 0, raf2 = 0;
7426
7440
  const place = () => {
7427
7441
  const box = scrollRef.current, mark = nowRef.current;
@@ -7449,19 +7463,19 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
7449
7463
  }, 0);
7450
7464
  const nextPhase = items.find((i) => !i.implemented);
7451
7465
  let lastPhase = null;
7452
- return /* @__PURE__ */ jsxs55("div", { className: "fd-stack", style: { gap: 16, maxWidth: 1e3 }, children: [
7453
- /* @__PURE__ */ jsxs55("div", { className: "fd-stack", style: { gap: 10 }, children: [
7466
+ return /* @__PURE__ */ jsxs56("div", { className: "fd-stack", style: { gap: 16, maxWidth: 1e3 }, children: [
7467
+ /* @__PURE__ */ jsxs56("div", { className: "fd-stack", style: { gap: 10 }, children: [
7454
7468
  /* @__PURE__ */ jsx60("span", { className: "fd-overline fd-muted", children: "Architecture" }),
7455
7469
  /* @__PURE__ */ jsx60("h1", { className: "fd-h1", style: { margin: 0 }, children: title }),
7456
7470
  /* @__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." })
7457
7471
  ] }),
7458
- /* @__PURE__ */ jsxs55("div", { className: "fd-grid-stats is-thin", children: [
7472
+ /* @__PURE__ */ jsxs56("div", { className: "fd-grid-stats is-thin", children: [
7459
7473
  /* @__PURE__ */ jsx60(StatTile, { compact: true, label: "Wired", value: String(rm.shipped), sub: "of " + rm.items.length + " features" }),
7460
7474
  /* @__PURE__ */ jsx60(StatTile, { compact: true, label: "Remaining", value: String(rm.remaining), sub: "backend work" }),
7461
7475
  /* @__PURE__ */ jsx60(StatTile, { compact: true, label: "Est. effort", value: days ? days + " days" : "\u2014", sub: "sum of estimates, not calendar" }),
7462
7476
  /* @__PURE__ */ jsx60(StatTile, { compact: true, label: "Up next", value: nextPhase ? "Phase " + nextPhase.phase : "\u2014", sub: nextPhase ? nextPhase.phaseName : "all wired" })
7463
7477
  ] }),
7464
- /* @__PURE__ */ jsxs55("div", { className: "fd-row", style: { gap: 10, flexWrap: "wrap" }, children: [
7478
+ /* @__PURE__ */ jsxs56("div", { className: "fd-row", style: { gap: 10, flexWrap: "wrap" }, children: [
7465
7479
  /* @__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 } }),
7466
7480
  /* @__PURE__ */ jsx60(Select, { placeholder: "All projects", value: project, onChange: (e) => setProject(e.target.value), options: projects, style: { width: 190 } }),
7467
7481
  /* @__PURE__ */ jsx60("span", { style: { flex: 1 } }),
@@ -7488,23 +7502,23 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
7488
7502
  actions: null
7489
7503
  }
7490
7504
  ),
7491
- /* @__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: [
7505
+ /* @__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: [
7492
7506
  /* @__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%" } }) }),
7493
7507
  items.map((item, n) => {
7494
7508
  const showPhase = item.phase !== lastPhase;
7495
7509
  lastPhase = item.phase;
7496
7510
  const inPhase = items.filter((i) => i.phase === item.phase).length;
7497
7511
  const isBoundary = n === firstPending;
7498
- return /* @__PURE__ */ jsxs55(React34.Fragment, { children: [
7499
- showPhase ? /* @__PURE__ */ jsxs55("div", { className: "fd-rm-era", children: [
7500
- /* @__PURE__ */ jsxs55("span", { className: "fd-row", style: { gap: 8, flexWrap: "wrap", alignItems: "baseline" }, children: [
7512
+ return /* @__PURE__ */ jsxs56(React35.Fragment, { children: [
7513
+ showPhase ? /* @__PURE__ */ jsxs56("div", { className: "fd-rm-era", children: [
7514
+ /* @__PURE__ */ jsxs56("span", { className: "fd-row", style: { gap: 8, flexWrap: "wrap", alignItems: "baseline" }, children: [
7501
7515
  /* @__PURE__ */ jsx60("span", { style: { fontWeight: 700 }, children: item.phase === 0 ? "Shipped" : "Phase " + item.phase + " \u2014 " + item.phaseName }),
7502
- item.phase === 0 ? null : /* @__PURE__ */ jsxs55("span", { className: "fd-mono", style: { opacity: 0.7, fontWeight: 400 }, children: [
7516
+ item.phase === 0 ? null : /* @__PURE__ */ jsxs56("span", { className: "fd-mono", style: { opacity: 0.7, fontWeight: 400 }, children: [
7503
7517
  fmtDate(item.phaseStart),
7504
7518
  " \u2013 ",
7505
7519
  fmtDate(item.date)
7506
7520
  ] }),
7507
- /* @__PURE__ */ jsxs55("span", { style: { opacity: 0.7, fontWeight: 400 }, children: [
7521
+ /* @__PURE__ */ jsxs56("span", { style: { opacity: 0.7, fontWeight: 400 }, children: [
7508
7522
  "\xB7 ",
7509
7523
  inPhase,
7510
7524
  " feature",
@@ -7513,13 +7527,13 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
7513
7527
  ] }),
7514
7528
  item.phaseWhy ? /* @__PURE__ */ jsx60("p", { className: "fd-rm-era-why", children: item.phaseWhy }) : null
7515
7529
  ] }) : null,
7516
- isBoundary ? /* @__PURE__ */ jsx60("div", { className: "fd-rm-now", ref: nowRef, children: /* @__PURE__ */ jsxs55("span", { className: "fd-rm-now-pill", children: [
7530
+ isBoundary ? /* @__PURE__ */ jsx60("div", { className: "fd-rm-now", ref: nowRef, children: /* @__PURE__ */ jsxs56("span", { className: "fd-rm-now-pill", children: [
7517
7531
  /* @__PURE__ */ jsx60("i", { className: "ph ph-map-pin" }),
7518
7532
  " You are here \u2014 everything above is wired"
7519
7533
  ] }) }) : null,
7520
- /* @__PURE__ */ jsxs55("div", { className: "fd-rm-row", children: [
7534
+ /* @__PURE__ */ jsxs56("div", { className: "fd-rm-row", children: [
7521
7535
  /* @__PURE__ */ jsx60("span", { className: "fd-rm-dot " + (item.implemented ? "is-shipped" : item.status === "next" ? "is-next" : "") }),
7522
- /* @__PURE__ */ jsxs55("div", { className: "fd-rm-date", children: [
7536
+ /* @__PURE__ */ jsxs56("div", { className: "fd-rm-date", children: [
7523
7537
  fmtDate(item.date),
7524
7538
  /* @__PURE__ */ jsx60("br", {}),
7525
7539
  /* @__PURE__ */ jsx60("span", { style: { opacity: 0.75 }, children: item.implemented ? "shipped" : "phase " + item.phase })
@@ -7530,7 +7544,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
7530
7544
  }),
7531
7545
  !items.length ? /* @__PURE__ */ jsx60("p", { className: "fd-body-sm fd-muted", children: "Nothing matches that filter." }) : null
7532
7546
  ] }) }) }),
7533
- /* @__PURE__ */ jsxs55("p", { className: "fd-body-sm fd-muted", style: { margin: 0 }, children: [
7547
+ /* @__PURE__ */ jsxs56("p", { className: "fd-body-sm fd-muted", style: { margin: 0 }, children: [
7534
7548
  "Derived from the feature-flag registry \u2014 each entry's status is its flag's ",
7535
7549
  /* @__PURE__ */ jsx60("code", { className: "fd-mono", children: "implemented" }),
7536
7550
  " field, so this page cannot drift from what the apps actually do."
@@ -7539,9 +7553,10 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
7539
7553
  }
7540
7554
 
7541
7555
  // src/components/platform/ComingSoon.tsx
7542
- import * as React35 from "react";
7556
+ import * as React36 from "react";
7543
7557
  import { createPortal as createPortal5 } from "react-dom";
7544
- import { Fragment as Fragment16, jsx as jsx61, jsxs as jsxs56 } from "react/jsx-runtime";
7558
+ import { Fragment as Fragment16, jsx as jsx61, jsxs as jsxs57 } from "react/jsx-runtime";
7559
+ var SOON_HOVERCARD_BASE = 220;
7545
7560
  var BYPASS_STORE = "fd.soon.bypass.v1";
7546
7561
  function readBypassed() {
7547
7562
  try {
@@ -7557,8 +7572,8 @@ function writeBypassed(list) {
7557
7572
  }
7558
7573
  }
7559
7574
  function useBypass(key) {
7560
- const [on, setOn] = React35.useState(() => !!key && readBypassed().indexOf(key) >= 0);
7561
- React35.useEffect(() => {
7575
+ const [on, setOn] = React36.useState(() => !!key && readBypassed().indexOf(key) >= 0);
7576
+ React36.useEffect(() => {
7562
7577
  setOn(!!key && readBypassed().indexOf(key) >= 0);
7563
7578
  }, [key]);
7564
7579
  const set = (next) => {
@@ -7571,43 +7586,43 @@ function useBypass(key) {
7571
7586
  return [on, set];
7572
7587
  }
7573
7588
  function SoonCard({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass }) {
7574
- return /* @__PURE__ */ jsxs56(Fragment16, { children: [
7575
- /* @__PURE__ */ jsxs56("span", { className: "fd-soon-badge", children: [
7589
+ return /* @__PURE__ */ jsxs57(Fragment16, { children: [
7590
+ /* @__PURE__ */ jsxs57("span", { className: "fd-soon-badge", children: [
7576
7591
  /* @__PURE__ */ jsx61("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" }),
7577
7592
  label
7578
7593
  ] }),
7579
7594
  detail ? /* @__PURE__ */ jsx61("span", { className: "fd-soon-detail", children: detail }) : null,
7580
- backend ? /* @__PURE__ */ jsxs56("span", { className: "fd-soon-backend", children: [
7595
+ backend ? /* @__PURE__ */ jsxs57("span", { className: "fd-soon-backend", children: [
7581
7596
  /* @__PURE__ */ jsx61("span", { className: "fd-overline", children: "Needs" }),
7582
7597
  " ",
7583
7598
  backend
7584
7599
  ] }) : null,
7585
- eta || effort || onRoadmap ? /* @__PURE__ */ jsxs56("span", { className: "fd-soon-meta", children: [
7586
- eta ? /* @__PURE__ */ jsxs56("span", { children: [
7600
+ eta || effort || onRoadmap ? /* @__PURE__ */ jsxs57("span", { className: "fd-soon-meta", children: [
7601
+ eta ? /* @__PURE__ */ jsxs57("span", { children: [
7587
7602
  /* @__PURE__ */ jsx61("i", { className: "ph ph-calendar-blank", "aria-hidden": "true" }),
7588
7603
  " ",
7589
7604
  eta
7590
7605
  ] }) : null,
7591
- effort ? /* @__PURE__ */ jsxs56("span", { children: [
7606
+ effort ? /* @__PURE__ */ jsxs57("span", { children: [
7592
7607
  /* @__PURE__ */ jsx61("i", { className: "ph ph-hourglass-medium", "aria-hidden": "true" }),
7593
7608
  " ",
7594
7609
  effort
7595
7610
  ] }) : null,
7596
- onRoadmap ? /* @__PURE__ */ jsxs56("button", { type: "button", className: "fd-soon-link", onClick: onRoadmap, children: [
7611
+ onRoadmap ? /* @__PURE__ */ jsxs57("button", { type: "button", className: "fd-soon-link", onClick: onRoadmap, children: [
7597
7612
  "See the roadmap ",
7598
7613
  /* @__PURE__ */ jsx61("i", { className: "ph ph-arrow-right", "aria-hidden": "true" })
7599
7614
  ] }) : null
7600
7615
  ] }) : null,
7601
- allowed ? /* @__PURE__ */ jsxs56("button", { type: "button", className: "fd-soon-view", onClick: onBypass, children: [
7616
+ allowed ? /* @__PURE__ */ jsxs57("button", { type: "button", className: "fd-soon-view", onClick: onBypass, children: [
7602
7617
  /* @__PURE__ */ jsx61("i", { className: "ph ph-eye", "aria-hidden": "true" }),
7603
7618
  " View and use it anyway"
7604
7619
  ] }) : null
7605
7620
  ] });
7606
7621
  }
7607
7622
  function useHoverCard(open) {
7608
- const anchor = React35.useRef(null);
7609
- const [pos, setPos] = React35.useState(null);
7610
- React35.useLayoutEffect(() => {
7623
+ const anchor = React36.useRef(null);
7624
+ const [pos, setPos] = React36.useState(null);
7625
+ React36.useLayoutEffect(() => {
7611
7626
  if (!open || !anchor.current) {
7612
7627
  setPos(null);
7613
7628
  return;
@@ -7659,7 +7674,7 @@ function ComingSoon({
7659
7674
  const tip = [label, detail, backend ? "Needs " + backend : null, eta ? "ETA " + eta : null, effort].filter(Boolean).join(" \xB7 ");
7660
7675
  if (inline) {
7661
7676
  if (allowed && bypassed) {
7662
- return /* @__PURE__ */ jsxs56("span", { className: ["fd-soon-inline-on", className].filter(Boolean).join(" "), ...rest, children: [
7677
+ return /* @__PURE__ */ jsxs57("span", { className: ["fd-soon-inline-on", className].filter(Boolean).join(" "), ...rest, children: [
7663
7678
  children,
7664
7679
  /* @__PURE__ */ jsx61(
7665
7680
  "button",
@@ -7694,19 +7709,19 @@ function ComingSoon({
7694
7709
  );
7695
7710
  }
7696
7711
  if (allowed && bypassed) {
7697
- return /* @__PURE__ */ jsxs56("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 14 }, ...rest, children: [
7698
- /* @__PURE__ */ jsxs56("div", { className: "fd-soon-bar", role: "status", children: [
7699
- /* @__PURE__ */ jsxs56("span", { className: "fd-soon-badge", children: [
7712
+ return /* @__PURE__ */ jsxs57("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 14 }, ...rest, children: [
7713
+ /* @__PURE__ */ jsxs57("div", { className: "fd-soon-bar", role: "status", children: [
7714
+ /* @__PURE__ */ jsxs57("span", { className: "fd-soon-badge", children: [
7700
7715
  /* @__PURE__ */ jsx61("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" }),
7701
7716
  "Unwired feature \u2014 you are using it anyway"
7702
7717
  ] }),
7703
7718
  /* @__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." }),
7704
- /* @__PURE__ */ jsxs56("span", { className: "fd-soon-bar-actions", children: [
7705
- onRoadmap ? /* @__PURE__ */ jsxs56("button", { type: "button", className: "fd-soon-link", onClick: onRoadmap, children: [
7719
+ /* @__PURE__ */ jsxs57("span", { className: "fd-soon-bar-actions", children: [
7720
+ onRoadmap ? /* @__PURE__ */ jsxs57("button", { type: "button", className: "fd-soon-link", onClick: onRoadmap, children: [
7706
7721
  "Roadmap ",
7707
7722
  /* @__PURE__ */ jsx61("i", { className: "ph ph-arrow-right", "aria-hidden": "true" })
7708
7723
  ] }) : null,
7709
- /* @__PURE__ */ jsxs56("button", { type: "button", className: "fd-soon-link", onClick: () => setBypassed(false), children: [
7724
+ /* @__PURE__ */ jsxs57("button", { type: "button", className: "fd-soon-link", onClick: () => setBypassed(false), children: [
7710
7725
  /* @__PURE__ */ jsx61("i", { className: "ph ph-eye-slash", "aria-hidden": "true" }),
7711
7726
  " Re-blur"
7712
7727
  ] })
@@ -7715,7 +7730,7 @@ function ComingSoon({
7715
7730
  children
7716
7731
  ] });
7717
7732
  }
7718
- return /* @__PURE__ */ jsxs56("div", { className: ["fd-soon", className].filter(Boolean).join(" "), style: minHeight ? { minHeight } : void 0, ...rest, children: [
7733
+ return /* @__PURE__ */ jsxs57("div", { className: ["fd-soon", className].filter(Boolean).join(" "), style: minHeight ? { minHeight } : void 0, ...rest, children: [
7719
7734
  /* @__PURE__ */ jsx61("div", { className: "fd-soon-under", style: { filter: "blur(" + blur + "px) saturate(.62)" }, ...{ inert: "" }, "aria-hidden": "true", children }),
7720
7735
  /* @__PURE__ */ jsx61("div", { className: "fd-soon-veil" }),
7721
7736
  /* @__PURE__ */ jsx61("div", { className: "fd-soon-note", role: "note", children: /* @__PURE__ */ jsx61(
@@ -7734,9 +7749,10 @@ function ComingSoon({
7734
7749
  ] });
7735
7750
  }
7736
7751
  function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass, blur, tip, className, rest, children }) {
7737
- const [open, setOpen] = React35.useState(false);
7752
+ const [open, setOpen] = React36.useState(false);
7738
7753
  const [anchor, pos] = useHoverCard(open);
7739
- const close = React35.useRef(null);
7754
+ const zIndex = useOverlayLayer(SOON_HOVERCARD_BASE);
7755
+ const close = React36.useRef(null);
7740
7756
  const show = () => {
7741
7757
  if (close.current) {
7742
7758
  clearTimeout(close.current);
@@ -7752,10 +7768,10 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
7752
7768
  setOpen(false);
7753
7769
  }, 140);
7754
7770
  };
7755
- React35.useEffect(() => () => {
7771
+ React36.useEffect(() => () => {
7756
7772
  if (close.current) clearTimeout(close.current);
7757
7773
  }, []);
7758
- return /* @__PURE__ */ jsxs56(
7774
+ return /* @__PURE__ */ jsxs57(
7759
7775
  "span",
7760
7776
  {
7761
7777
  ref: anchor,
@@ -7782,12 +7798,12 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
7782
7798
  }
7783
7799
  ),
7784
7800
  open && pos ? createPortal5(
7785
- /* @__PURE__ */ jsx61(
7801
+ /* @__PURE__ */ jsx61(LayerProvider, { zIndex, children: /* @__PURE__ */ jsx61(
7786
7802
  "div",
7787
7803
  {
7788
7804
  className: "fd-soon-note fd-soon-hovercard",
7789
7805
  role: "tooltip",
7790
- style: { position: "fixed", left: pos.left, top: pos.top, bottom: pos.bottom, width: pos.width },
7806
+ style: { position: "fixed", left: pos.left, top: pos.top, bottom: pos.bottom, width: pos.width, zIndex },
7791
7807
  onMouseEnter: show,
7792
7808
  onMouseLeave: hide,
7793
7809
  children: /* @__PURE__ */ jsx61(
@@ -7804,7 +7820,7 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
7804
7820
  }
7805
7821
  )
7806
7822
  }
7807
- ),
7823
+ ) }),
7808
7824
  document.body
7809
7825
  ) : null
7810
7826
  ]
@@ -7820,10 +7836,10 @@ function formatEta(iso2) {
7820
7836
  var FormatEta = formatEta;
7821
7837
 
7822
7838
  // src/components/platform/Gate.tsx
7823
- import { jsx as jsx62, jsxs as jsxs57 } from "react/jsx-runtime";
7839
+ import { jsx as jsx62, jsxs as jsxs58 } from "react/jsx-runtime";
7824
7840
  function PermissionDenied({ permission, title, detail, compact: compact3 = false, className = "", ...rest }) {
7825
7841
  const need = Array.isArray(permission) ? permission : [permission].filter(Boolean);
7826
- return /* @__PURE__ */ jsxs57(
7842
+ return /* @__PURE__ */ jsxs58(
7827
7843
  "div",
7828
7844
  {
7829
7845
  className: ["fd-stack", className].filter(Boolean).join(" "),
@@ -7839,12 +7855,12 @@ function PermissionDenied({ permission, title, detail, compact: compact3 = false
7839
7855
  },
7840
7856
  ...rest,
7841
7857
  children: [
7842
- /* @__PURE__ */ jsxs57("span", { className: "fd-row", style: { gap: 8 }, children: [
7858
+ /* @__PURE__ */ jsxs58("span", { className: "fd-row", style: { gap: 8 }, children: [
7843
7859
  /* @__PURE__ */ jsx62("i", { className: "ph ph-lock-simple", style: { fontSize: 16, color: "var(--text-muted)" }, "aria-hidden": "true" }),
7844
7860
  /* @__PURE__ */ jsx62("span", { className: compact3 ? "fd-label-lg" : "fd-h3", children: title || "You do not have access to this" })
7845
7861
  ] }),
7846
7862
  /* @__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." }),
7847
- need.length ? /* @__PURE__ */ jsxs57("span", { className: "fd-row", style: { gap: 6, flexWrap: "wrap" }, children: [
7863
+ need.length ? /* @__PURE__ */ jsxs58("span", { className: "fd-row", style: { gap: 6, flexWrap: "wrap" }, children: [
7848
7864
  /* @__PURE__ */ jsx62("span", { className: "fd-overline fd-muted", children: "Requires" }),
7849
7865
  need.map((p) => /* @__PURE__ */ jsx62("code", { className: "fd-mono", style: {
7850
7866
  fontSize: 11.5,
@@ -7921,13 +7937,15 @@ function PermissionHint({ perm, children }) {
7921
7937
  }
7922
7938
 
7923
7939
  // src/components/platform/ModeSwitch.tsx
7924
- import * as React36 from "react";
7925
- import { Fragment as Fragment17, jsx as jsx63, jsxs as jsxs58 } from "react/jsx-runtime";
7940
+ import * as React37 from "react";
7941
+ import { Fragment as Fragment17, jsx as jsx63, jsxs as jsxs59 } from "react/jsx-runtime";
7942
+ var MODE_SWITCH_BASE = 140;
7926
7943
  function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog, onOpenSpec, summary }) {
7927
7944
  const mode2 = useRuntimeMode();
7928
- const [open, setOpen] = React36.useState(false);
7929
- const ref = React36.useRef(null);
7930
- React36.useEffect(() => {
7945
+ const [open, setOpen] = React37.useState(false);
7946
+ const zIndex = useOverlayLayer(MODE_SWITCH_BASE);
7947
+ const ref = React37.useRef(null);
7948
+ React37.useEffect(() => {
7931
7949
  if (!open) return;
7932
7950
  const away = (e) => {
7933
7951
  if (ref.current && !ref.current.contains(e.target)) setOpen(false);
@@ -7949,8 +7967,8 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
7949
7967
  RuntimeKit.setMode(next);
7950
7968
  setOpen(false);
7951
7969
  };
7952
- return /* @__PURE__ */ jsxs58("span", { style: { position: "relative", display: "inline-flex" }, ref, children: [
7953
- /* @__PURE__ */ jsxs58(
7970
+ return /* @__PURE__ */ jsxs59("span", { style: { position: "relative", display: "inline-flex" }, ref, children: [
7971
+ /* @__PURE__ */ jsxs59(
7954
7972
  "button",
7955
7973
  {
7956
7974
  type: "button",
@@ -7965,13 +7983,13 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
7965
7983
  ]
7966
7984
  }
7967
7985
  ),
7968
- open ? /* @__PURE__ */ jsxs58("span", { className: "fd-view-enter fd-mode-pop", children: [
7969
- /* @__PURE__ */ jsxs58("span", { className: "fd-row", style: { gap: 10, padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
7970
- /* @__PURE__ */ jsxs58("span", { className: "fd-badge " + (test ? "fd-badge-warning" : "fd-badge-neutral"), children: [
7986
+ open ? /* @__PURE__ */ jsx63(LayerProvider, { zIndex, children: /* @__PURE__ */ jsxs59("span", { className: "fd-view-enter fd-mode-pop", style: { zIndex }, children: [
7987
+ /* @__PURE__ */ jsxs59("span", { className: "fd-row", style: { gap: 10, padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
7988
+ /* @__PURE__ */ jsxs59("span", { className: "fd-badge " + (test ? "fd-badge-warning" : "fd-badge-neutral"), children: [
7971
7989
  /* @__PURE__ */ jsx63("i", { className: "ph " + (test ? "ph-flask" : "ph-lightning"), "aria-hidden": "true" }),
7972
7990
  test ? "Test mode" : "Live mode"
7973
7991
  ] }),
7974
- test ? /* @__PURE__ */ jsxs58("span", { className: "fd-body-sm fd-muted fd-mono", children: [
7992
+ test ? /* @__PURE__ */ jsxs59("span", { className: "fd-body-sm fd-muted fd-mono", children: [
7975
7993
  requestCount,
7976
7994
  " simulated request",
7977
7995
  requestCount === 1 ? "" : "s"
@@ -7979,10 +7997,10 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
7979
7997
  /* @__PURE__ */ jsx63("span", { style: { flex: 1 } }),
7980
7998
  test && onClearLog ? /* @__PURE__ */ jsx63("button", { type: "button", className: "fd-soon-link", onClick: onClearLog, children: "Clear" }) : null
7981
7999
  ] }),
7982
- /* @__PURE__ */ jsxs58("span", { style: { display: "block", padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
8000
+ /* @__PURE__ */ jsxs59("span", { style: { display: "block", padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
7983
8001
  /* @__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." }),
7984
- /* @__PURE__ */ jsxs58("span", { className: "fd-row", style: { gap: 8, marginTop: 10, flexWrap: "wrap" }, children: [
7985
- /* @__PURE__ */ jsxs58("span", { className: "fd-body-sm fd-muted fd-mono", children: [
8002
+ /* @__PURE__ */ jsxs59("span", { className: "fd-row", style: { gap: 8, marginTop: 10, flexWrap: "wrap" }, children: [
8003
+ /* @__PURE__ */ jsxs59("span", { className: "fd-body-sm fd-muted fd-mono", children: [
7986
8004
  s.endpointsWired,
7987
8005
  " endpoint",
7988
8006
  s.endpointsWired === 1 ? "" : "s",
@@ -7992,9 +8010,9 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
7992
8010
  s.total,
7993
8011
  " features complete"
7994
8012
  ] }),
7995
- onOpenSpec ? /* @__PURE__ */ jsxs58(Fragment17, { children: [
8013
+ onOpenSpec ? /* @__PURE__ */ jsxs59(Fragment17, { children: [
7996
8014
  /* @__PURE__ */ jsx63("span", { style: { flex: 1 } }),
7997
- /* @__PURE__ */ jsxs58("button", { type: "button", className: "fd-soon-link", onClick: () => {
8015
+ /* @__PURE__ */ jsxs59("button", { type: "button", className: "fd-soon-link", onClick: () => {
7998
8016
  setOpen(false);
7999
8017
  onOpenSpec();
8000
8018
  }, children: [
@@ -8004,18 +8022,18 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
8004
8022
  ] }) : null
8005
8023
  ] })
8006
8024
  ] }),
8007
- /* @__PURE__ */ jsxs58("span", { className: "fd-mode-choice", children: [
8008
- /* @__PURE__ */ jsxs58("button", { type: "button", className: "fd-mode-opt" + (!test ? " is-on" : ""), onClick: () => go("live"), children: [
8025
+ /* @__PURE__ */ jsxs59("span", { className: "fd-mode-choice", children: [
8026
+ /* @__PURE__ */ jsxs59("button", { type: "button", className: "fd-mode-opt" + (!test ? " is-on" : ""), onClick: () => go("live"), children: [
8009
8027
  /* @__PURE__ */ jsx63("i", { className: "ph ph-lightning", "aria-hidden": "true" }),
8010
- /* @__PURE__ */ jsxs58("span", { className: "fd-mode-opt-text", children: [
8028
+ /* @__PURE__ */ jsxs59("span", { className: "fd-mode-opt-text", children: [
8011
8029
  /* @__PURE__ */ jsx63("span", { className: "fd-mode-opt-title", children: "Live mode" }),
8012
8030
  /* @__PURE__ */ jsx63("span", { className: "fd-mode-opt-desc", children: "Incomplete features under construction" })
8013
8031
  ] }),
8014
8032
  !test ? /* @__PURE__ */ jsx63("i", { className: "ph ph-check", "aria-hidden": "true" }) : null
8015
8033
  ] }),
8016
- /* @__PURE__ */ jsxs58("button", { type: "button", className: "fd-mode-opt" + (test ? " is-on" : ""), onClick: () => go("test"), children: [
8034
+ /* @__PURE__ */ jsxs59("button", { type: "button", className: "fd-mode-opt" + (test ? " is-on" : ""), onClick: () => go("test"), children: [
8017
8035
  /* @__PURE__ */ jsx63("i", { className: "ph ph-flask", "aria-hidden": "true" }),
8018
- /* @__PURE__ */ jsxs58("span", { className: "fd-mode-opt-text", children: [
8036
+ /* @__PURE__ */ jsxs59("span", { className: "fd-mode-opt-text", children: [
8019
8037
  /* @__PURE__ */ jsx63("span", { className: "fd-mode-opt-title", children: "Test mode" }),
8020
8038
  /* @__PURE__ */ jsx63("span", { className: "fd-mode-opt-desc", children: "Everything usable, all data simulated" })
8021
8039
  ] }),
@@ -8023,19 +8041,19 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
8023
8041
  ] })
8024
8042
  ] }),
8025
8043
  test && renderLog ? /* @__PURE__ */ jsx63("span", { style: { display: "block", maxHeight: 340, overflowY: "auto", borderTop: "1px solid var(--border)" }, children: renderLog() }) : null
8026
- ] }) : null
8044
+ ] }) }) : null
8027
8045
  ] });
8028
8046
  }
8029
8047
  function TestModeBar({ onExit }) {
8030
8048
  const mode2 = useRuntimeMode();
8031
8049
  if (mode2 !== "test") return null;
8032
- return /* @__PURE__ */ jsxs58("div", { className: "fd-testbar", role: "status", children: [
8033
- /* @__PURE__ */ jsxs58("span", { className: "fd-badge fd-badge-warning", children: [
8050
+ return /* @__PURE__ */ jsxs59("div", { className: "fd-testbar", role: "status", children: [
8051
+ /* @__PURE__ */ jsxs59("span", { className: "fd-badge fd-badge-warning", children: [
8034
8052
  /* @__PURE__ */ jsx63("i", { className: "ph ph-flask", "aria-hidden": "true" }),
8035
8053
  "Test mode"
8036
8054
  ] }),
8037
8055
  /* @__PURE__ */ jsx63("span", { className: "fd-testbar-detail", children: "Every feature is unlocked and every response is simulated \u2014 nothing here persists." }),
8038
- /* @__PURE__ */ jsxs58("button", { type: "button", className: "fd-soon-link", onClick: () => onExit ? onExit() : RuntimeKit.setMode("live"), children: [
8056
+ /* @__PURE__ */ jsxs59("button", { type: "button", className: "fd-soon-link", onClick: () => onExit ? onExit() : RuntimeKit.setMode("live"), children: [
8039
8057
  /* @__PURE__ */ jsx63("i", { className: "ph ph-lightning", "aria-hidden": "true" }),
8040
8058
  " Back to live mode"
8041
8059
  ] })
@@ -8043,7 +8061,7 @@ function TestModeBar({ onExit }) {
8043
8061
  }
8044
8062
 
8045
8063
  // src/components/planner/ChannelMeta.tsx
8046
- import { jsx as jsx64, jsxs as jsxs59 } from "react/jsx-runtime";
8064
+ import { jsx as jsx64, jsxs as jsxs60 } from "react/jsx-runtime";
8047
8065
  var CHANNEL_WEIGHTS = {
8048
8066
  "OOH": 50,
8049
8067
  "DOOH": 50,
@@ -8098,7 +8116,7 @@ function ChannelTag({ channel, size = "md", showLabel = true, dot = false, weigh
8098
8116
  if (dot) {
8099
8117
  return /* @__PURE__ */ jsx64("span", { className: ["fd-chan-dot", className].filter(Boolean).join(" "), title: m.name, style: { background: m.color }, ...rest });
8100
8118
  }
8101
- return /* @__PURE__ */ jsxs59(
8119
+ return /* @__PURE__ */ jsxs60(
8102
8120
  "span",
8103
8121
  {
8104
8122
  className: ["fd-chan", size === "sm" ? "fd-chan-sm" : "", className].filter(Boolean).join(" "),
@@ -8115,7 +8133,7 @@ function ChannelTag({ channel, size = "md", showLabel = true, dot = false, weigh
8115
8133
  }
8116
8134
 
8117
8135
  // src/components/planner/SaturationDistribution.tsx
8118
- import { jsx as jsx65, jsxs as jsxs60 } from "react/jsx-runtime";
8136
+ import { jsx as jsx65, jsxs as jsxs61 } from "react/jsx-runtime";
8119
8137
  var BANDS2 = [
8120
8138
  { key: "weak", label: "Weak", n: 1, range: "< 50" },
8121
8139
  { key: "adequate", label: "Adequate", n: 2, range: "50\u2013100" },
@@ -8126,11 +8144,11 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
8126
8144
  const grouped = BANDS2.map((b) => ({ ...b, items: campuses.filter((c) => c.band === b.key) }));
8127
8145
  const tallest = Math.max(1, ...grouped.map((g) => g.items.length));
8128
8146
  const floor = BANDS2.find((b) => b.key === floorBand) || BANDS2[0];
8129
- return /* @__PURE__ */ jsxs60("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 16 }, children: [
8147
+ return /* @__PURE__ */ jsxs61("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 16 }, children: [
8130
8148
  /* @__PURE__ */ jsx65("div", { style: { display: "grid", gridTemplateColumns: "repeat(4,1fr)", gap: 12, alignItems: "end" }, children: grouped.map((g) => {
8131
8149
  const mark = "var(--csi-" + g.n + "-mark)";
8132
8150
  const active = selectedBand === g.key;
8133
- return /* @__PURE__ */ jsxs60(
8151
+ return /* @__PURE__ */ jsxs61(
8134
8152
  "button",
8135
8153
  {
8136
8154
  type: "button",
@@ -8146,13 +8164,13 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
8146
8164
  },
8147
8165
  c.name
8148
8166
  )) }),
8149
- /* @__PURE__ */ jsxs60("span", { className: "fd-row", style: { gap: 8, alignItems: "baseline" }, children: [
8167
+ /* @__PURE__ */ jsxs61("span", { className: "fd-row", style: { gap: 8, alignItems: "baseline" }, children: [
8150
8168
  /* @__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 }),
8151
8169
  /* @__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)) })
8152
8170
  ] }),
8153
- /* @__PURE__ */ jsxs60("span", { className: "fd-stack", style: { gap: 1 }, children: [
8171
+ /* @__PURE__ */ jsxs61("span", { className: "fd-stack", style: { gap: 1 }, children: [
8154
8172
  /* @__PURE__ */ jsx65("span", { className: "fd-label-lg", children: g.label }),
8155
- /* @__PURE__ */ jsxs60("span", { className: "fd-body-sm fd-muted", style: { fontSize: 11.5 }, children: [
8173
+ /* @__PURE__ */ jsxs61("span", { className: "fd-body-sm fd-muted", style: { fontSize: 11.5 }, children: [
8156
8174
  "CRP ",
8157
8175
  g.range
8158
8176
  ] })
@@ -8162,10 +8180,10 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
8162
8180
  g.key
8163
8181
  );
8164
8182
  }) }),
8165
- 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: [
8183
+ 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: [
8166
8184
  /* @__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)) }),
8167
- /* @__PURE__ */ jsxs60("span", { className: "fd-body-sm fd-secondary", style: { flex: 1, minWidth: 240 }, children: [
8168
- /* @__PURE__ */ jsxs60("strong", { style: { color: "var(--text)" }, children: [
8185
+ /* @__PURE__ */ jsxs61("span", { className: "fd-body-sm fd-secondary", style: { flex: 1, minWidth: 240 }, children: [
8186
+ /* @__PURE__ */ jsxs61("strong", { style: { color: "var(--text)" }, children: [
8169
8187
  "Plan floor ",
8170
8188
  floorScore
8171
8189
  ] }),
@@ -8176,8 +8194,8 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
8176
8194
  }
8177
8195
 
8178
8196
  // src/components/planner/MixGap.tsx
8179
- import * as React37 from "react";
8180
- import { Fragment as Fragment18, jsx as jsx66, jsxs as jsxs61 } from "react/jsx-runtime";
8197
+ import * as React38 from "react";
8198
+ import { Fragment as Fragment18, jsx as jsx66, jsxs as jsxs62 } from "react/jsx-runtime";
8181
8199
  var MIX_GAP_LAYOUT = {
8182
8200
  trackHeight: 30,
8183
8201
  barHeight: 20,
@@ -8191,18 +8209,18 @@ function mixGapOffset(value, max) {
8191
8209
  }
8192
8210
  function MixGap({ rows = [], loading = false, className = "" }) {
8193
8211
  const max = Math.max(1, ...rows.flatMap((r) => [r.target, r.realized]));
8194
- const [hover, setHover] = React37.useState(null);
8212
+ const [hover, setHover] = React38.useState(null);
8195
8213
  const toneOf = (gap) => gap >= -1 ? "ok" : gap >= -4 ? "warn" : "danger";
8196
8214
  const TONE = { ok: "var(--ok-solid)", warn: "var(--warn-solid)", danger: "var(--danger-solid)" };
8197
8215
  const { trackHeight, barHeight, targetWidth, labelGap } = MIX_GAP_LAYOUT;
8198
8216
  const barTop = (trackHeight - barHeight) / 2;
8199
- return /* @__PURE__ */ jsxs61("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 4 }, children: [
8200
- /* @__PURE__ */ jsxs61("div", { className: "fd-row", style: { gap: 16, justifyContent: "flex-end", paddingBottom: 6, flexWrap: "wrap" }, children: [
8201
- [["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: [
8217
+ return /* @__PURE__ */ jsxs62("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 4 }, children: [
8218
+ /* @__PURE__ */ jsxs62("div", { className: "fd-row", style: { gap: 16, justifyContent: "flex-end", paddingBottom: 6, flexWrap: "wrap" }, children: [
8219
+ [["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: [
8202
8220
  /* @__PURE__ */ jsx66("span", { style: { width: 14, height: 9, borderRadius: 2, background: c } }),
8203
8221
  l
8204
8222
  ] }, l)),
8205
- /* @__PURE__ */ jsxs61("span", { className: "fd-row fd-body-sm fd-muted", style: { gap: 6 }, children: [
8223
+ /* @__PURE__ */ jsxs62("span", { className: "fd-row fd-body-sm fd-muted", style: { gap: 6 }, children: [
8206
8224
  /* @__PURE__ */ jsx66("span", { "data-mixgap-legend-target": "", style: { width: targetWidth, height: 16, borderRadius: 1, background: MIX_GAP_TARGET_STRIPE } }),
8207
8225
  "Target"
8208
8226
  ] })
@@ -8212,7 +8230,7 @@ function MixGap({ rows = [], loading = false, className = "" }) {
8212
8230
  const tone = toneOf(gap);
8213
8231
  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 : "");
8214
8232
  const labelLeft = r.realized > r.target ? `calc(${mixGapOffset(r.realized, max)} + ${labelGap}px)` : `calc(${mixGapOffset(r.target, max)} + ${targetWidth / 2 + labelGap}px)`;
8215
- return /* @__PURE__ */ jsxs61(
8233
+ return /* @__PURE__ */ jsxs62(
8216
8234
  "div",
8217
8235
  {
8218
8236
  className: "fd-row",
@@ -8221,10 +8239,10 @@ function MixGap({ rows = [], loading = false, className = "" }) {
8221
8239
  onMouseLeave: () => setHover(null),
8222
8240
  children: [
8223
8241
  /* @__PURE__ */ jsx66("span", { style: { width: 128, flex: "none" }, children: /* @__PURE__ */ jsx66(ChannelTag, { channel: r.channel, size: "sm" }) }),
8224
- /* @__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: [
8242
+ /* @__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: [
8225
8243
  /* @__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)" } }),
8226
8244
  /* @__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 } }),
8227
- /* @__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: [
8245
+ /* @__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: [
8228
8246
  r.realized,
8229
8247
  "%"
8230
8248
  ] }),
@@ -8239,7 +8257,7 @@ function MixGap({ rows = [], loading = false, className = "" }) {
8239
8257
  }
8240
8258
 
8241
8259
  // src/components/planner/ChannelContribution.tsx
8242
- import { jsx as jsx67, jsxs as jsxs62 } from "react/jsx-runtime";
8260
+ import { jsx as jsx67, jsxs as jsxs63 } from "react/jsx-runtime";
8243
8261
  var money = (n) => "$" + Math.round(n).toLocaleString();
8244
8262
  function ChannelContribution({
8245
8263
  channels = [],
@@ -8255,8 +8273,8 @@ function ChannelContribution({
8255
8273
  const grand = total !== void 0 ? total : base + bonus;
8256
8274
  const pct = (v) => grand ? v / grand * 100 : 0;
8257
8275
  const spendTotal = channels.reduce((s, c) => s + Number(String(c.spend || 0).replace(/[^0-9.]/g, "")), 0);
8258
- return /* @__PURE__ */ jsxs62("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 16 }, children: [
8259
- 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: [
8276
+ return /* @__PURE__ */ jsxs63("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 16 }, children: [
8277
+ 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: [
8260
8278
  channels.map((c) => /* @__PURE__ */ jsx67(
8261
8279
  "span",
8262
8280
  {
@@ -8275,16 +8293,16 @@ function ChannelContribution({
8275
8293
  }
8276
8294
  ) : null
8277
8295
  ] }),
8278
- showTable ? /* @__PURE__ */ jsxs62("table", { className: "fd-table", style: { fontSize: "var(--body-sm-size)" }, children: [
8279
- /* @__PURE__ */ jsx67("thead", { children: /* @__PURE__ */ jsxs62("tr", { children: [
8296
+ showTable ? /* @__PURE__ */ jsxs63("table", { className: "fd-table", style: { fontSize: "var(--body-sm-size)" }, children: [
8297
+ /* @__PURE__ */ jsx67("thead", { children: /* @__PURE__ */ jsxs63("tr", { children: [
8280
8298
  /* @__PURE__ */ jsx67("th", { style: { width: "34%" }, children: "Channel" }),
8281
8299
  /* @__PURE__ */ jsx67("th", { style: { width: "16%" }, children: "Weight" }),
8282
8300
  /* @__PURE__ */ jsx67("th", { className: "is-num", style: { width: "16%" }, children: "Spend" }),
8283
8301
  /* @__PURE__ */ jsx67("th", { className: "is-num", style: { width: "17%" }, children: "CRP" }),
8284
8302
  /* @__PURE__ */ jsx67("th", { className: "is-num", style: { width: "17%" }, children: "Share" })
8285
8303
  ] }) }),
8286
- /* @__PURE__ */ jsxs62("tbody", { children: [
8287
- channels.map((c) => /* @__PURE__ */ jsxs62("tr", { children: [
8304
+ /* @__PURE__ */ jsxs63("tbody", { children: [
8305
+ channels.map((c) => /* @__PURE__ */ jsxs63("tr", { children: [
8288
8306
  /* @__PURE__ */ jsx67("td", { children: /* @__PURE__ */ jsx67(ChannelTag, { channel: c.name, size: "sm" }) }),
8289
8307
  /* @__PURE__ */ jsx67("td", { children: /* @__PURE__ */ jsx67(
8290
8308
  "span",
@@ -8297,17 +8315,17 @@ function ChannelContribution({
8297
8315
  ) }),
8298
8316
  /* @__PURE__ */ jsx67("td", { className: "is-num", children: c.spend }),
8299
8317
  /* @__PURE__ */ jsx67("td", { className: "is-num", children: c.crp.toFixed(1) }),
8300
- /* @__PURE__ */ jsxs62("td", { className: "is-num", children: [
8318
+ /* @__PURE__ */ jsxs63("td", { className: "is-num", children: [
8301
8319
  pct(c.crp).toFixed(0),
8302
8320
  "%"
8303
8321
  ] })
8304
8322
  ] }, c.name)),
8305
- bonus > 0 ? /* @__PURE__ */ jsxs62("tr", { children: [
8306
- /* @__PURE__ */ jsx67("td", { children: /* @__PURE__ */ jsxs62("span", { className: "fd-row", style: { gap: 9, fontWeight: 600 }, children: [
8323
+ bonus > 0 ? /* @__PURE__ */ jsxs63("tr", { children: [
8324
+ /* @__PURE__ */ jsx67("td", { children: /* @__PURE__ */ jsxs63("span", { className: "fd-row", style: { gap: 9, fontWeight: 600 }, children: [
8307
8325
  /* @__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" } }),
8308
8326
  "Surround-sound bonus"
8309
8327
  ] }) }),
8310
- /* @__PURE__ */ jsx67("td", { children: /* @__PURE__ */ jsxs62("span", { className: "fd-badge fd-badge-success", style: { height: 20, fontSize: 11 }, children: [
8328
+ /* @__PURE__ */ jsx67("td", { children: /* @__PURE__ */ jsxs63("span", { className: "fd-badge fd-badge-success", style: { height: 20, fontSize: 11 }, children: [
8311
8329
  "+",
8312
8330
  bonusPct,
8313
8331
  "% of +",
@@ -8316,12 +8334,12 @@ function ChannelContribution({
8316
8334
  ] }) }),
8317
8335
  /* @__PURE__ */ jsx67("td", { className: "is-num fd-muted", children: "\u2014" }),
8318
8336
  /* @__PURE__ */ jsx67("td", { className: "is-num", children: bonus.toFixed(1) }),
8319
- /* @__PURE__ */ jsxs62("td", { className: "is-num", children: [
8337
+ /* @__PURE__ */ jsxs63("td", { className: "is-num", children: [
8320
8338
  pct(bonus).toFixed(0),
8321
8339
  "%"
8322
8340
  ] })
8323
8341
  ] }) : null,
8324
- /* @__PURE__ */ jsxs62("tr", { style: { background: "var(--surface-2)" }, children: [
8342
+ /* @__PURE__ */ jsxs63("tr", { style: { background: "var(--surface-2)" }, children: [
8325
8343
  /* @__PURE__ */ jsx67("td", { style: { fontWeight: 700 }, children: "Campus total" }),
8326
8344
  /* @__PURE__ */ jsx67("td", {}),
8327
8345
  /* @__PURE__ */ jsx67("td", { className: "is-num", style: { fontWeight: 700 }, children: money(spendTotal) }),
@@ -8334,8 +8352,8 @@ function ChannelContribution({
8334
8352
  }
8335
8353
 
8336
8354
  // src/components/planner/BudgetReallocator.tsx
8337
- import * as React38 from "react";
8338
- import { Fragment as Fragment19, jsx as jsx68, jsxs as jsxs63 } from "react/jsx-runtime";
8355
+ import * as React39 from "react";
8356
+ import { Fragment as Fragment19, jsx as jsx68, jsxs as jsxs64 } from "react/jsx-runtime";
8339
8357
  var bandFor = (crp) => crp >= 200 ? "dominant" : crp >= 100 ? "strong" : crp >= 50 ? "adequate" : "weak";
8340
8358
  function BudgetReallocator({
8341
8359
  campus,
@@ -8350,8 +8368,8 @@ function BudgetReallocator({
8350
8368
  onCancel,
8351
8369
  className = ""
8352
8370
  }) {
8353
- const [draft, setDraft] = React38.useState(spend);
8354
- React38.useEffect(() => setDraft(spend), [spend]);
8371
+ const [draft, setDraft] = React39.useState(spend);
8372
+ React39.useEffect(() => setDraft(spend), [spend]);
8355
8373
  const dirty = draft !== spend;
8356
8374
  const nextCrp = scoreFor ? scoreFor(draft) : crp;
8357
8375
  const nextBand = bandFor(nextCrp);
@@ -8366,21 +8384,21 @@ function BudgetReallocator({
8366
8384
  setDraft(spend);
8367
8385
  if (onCancel) onCancel();
8368
8386
  };
8369
- return /* @__PURE__ */ jsxs63(
8387
+ return /* @__PURE__ */ jsxs64(
8370
8388
  "div",
8371
8389
  {
8372
8390
  className: ["fd-stack", className].filter(Boolean).join(" "),
8373
8391
  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)" },
8374
8392
  children: [
8375
- /* @__PURE__ */ jsxs63("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
8393
+ /* @__PURE__ */ jsxs64("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
8376
8394
  /* @__PURE__ */ jsx68("span", { className: "fd-h4", style: { flex: 1, minWidth: 140 }, children: campus }),
8377
8395
  /* @__PURE__ */ jsx68(CsiBadge, { band: nowBand, crp, size: "medium" }),
8378
- dirty ? /* @__PURE__ */ jsxs63(Fragment19, { children: [
8396
+ dirty ? /* @__PURE__ */ jsxs64(Fragment19, { children: [
8379
8397
  /* @__PURE__ */ jsx68("i", { className: "ph ph-arrow-right fd-muted", "aria-hidden": "true" }),
8380
8398
  /* @__PURE__ */ jsx68(CsiBadge, { band: nextBand, crp: nextCrp, size: "medium", preview: true })
8381
8399
  ] }) : null
8382
8400
  ] }),
8383
- /* @__PURE__ */ jsxs63("div", { className: "fd-slider", children: [
8401
+ /* @__PURE__ */ jsxs64("div", { className: "fd-slider", children: [
8384
8402
  /* @__PURE__ */ jsx68("span", { className: "fd-slider-fill", style: { width: pct + "%" } }),
8385
8403
  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,
8386
8404
  /* @__PURE__ */ jsx68(
@@ -8399,8 +8417,8 @@ function BudgetReallocator({
8399
8417
  }
8400
8418
  )
8401
8419
  ] }),
8402
- /* @__PURE__ */ jsxs63("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
8403
- /* @__PURE__ */ jsxs63("span", { className: "fd-stack", style: { gap: 2, flex: 1, minWidth: 150 }, children: [
8420
+ /* @__PURE__ */ jsxs64("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
8421
+ /* @__PURE__ */ jsxs64("span", { className: "fd-stack", style: { gap: 2, flex: 1, minWidth: 150 }, children: [
8404
8422
  /* @__PURE__ */ jsx68("span", { className: "fd-num", style: { fontSize: 19, fontWeight: 700 }, children: "$" + draft.toLocaleString() }),
8405
8423
  /* @__PURE__ */ jsx68("span", { className: "fd-body-sm fd-muted", children: "Arrow keys step $100, shift+arrow $1,000. Escape reverts." })
8406
8424
  ] }),
@@ -8424,7 +8442,7 @@ function BudgetReallocator({
8424
8442
  }
8425
8443
 
8426
8444
  // src/components/planner/SurroundSound.tsx
8427
- import { jsx as jsx69, jsxs as jsxs64 } from "react/jsx-runtime";
8445
+ import { jsx as jsx69, jsxs as jsxs65 } from "react/jsx-runtime";
8428
8446
  var CATEGORIES = [
8429
8447
  { key: "ooh", label: "OOH", icon: "flag-banner", color: "var(--ch-ooh)" },
8430
8448
  { key: "transit", label: "Transit", icon: "bus", color: "var(--ch-transit)" },
@@ -8436,10 +8454,10 @@ var CATEGORIES = [
8436
8454
  function SurroundSound({ present = [], bonusPct = 0, bonusMax = 40, missedCost, className = "" }) {
8437
8455
  const earned = Math.max(0, Math.min(1, bonusPct / bonusMax));
8438
8456
  const single = present.length <= 2;
8439
- return /* @__PURE__ */ jsxs64("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 14 }, children: [
8457
+ return /* @__PURE__ */ jsxs65("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 14 }, children: [
8440
8458
  /* @__PURE__ */ jsx69("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: CATEGORIES.map((c) => {
8441
8459
  const on = present.includes(c.key);
8442
- return /* @__PURE__ */ jsxs64(
8460
+ return /* @__PURE__ */ jsxs65(
8443
8461
  "span",
8444
8462
  {
8445
8463
  title: c.label + (on ? " \u2014 present" : " \u2014 not bought"),
@@ -8452,10 +8470,10 @@ function SurroundSound({ present = [], bonusPct = 0, bonusMax = 40, missedCost,
8452
8470
  c.key
8453
8471
  );
8454
8472
  }) }),
8455
- /* @__PURE__ */ jsxs64("div", { className: "fd-stack", style: { gap: 8 }, children: [
8456
- /* @__PURE__ */ jsxs64("div", { className: "fd-row", style: { justifyContent: "space-between", gap: 12 }, children: [
8473
+ /* @__PURE__ */ jsxs65("div", { className: "fd-stack", style: { gap: 8 }, children: [
8474
+ /* @__PURE__ */ jsxs65("div", { className: "fd-row", style: { justifyContent: "space-between", gap: 12 }, children: [
8457
8475
  /* @__PURE__ */ jsx69("span", { className: "fd-label-lg", children: "Surround-sound bonus earned" }),
8458
- /* @__PURE__ */ jsxs64("span", { className: "fd-num", style: { color: single ? "var(--warn-text)" : "var(--csi-3-mark)", fontWeight: 700 }, children: [
8476
+ /* @__PURE__ */ jsxs65("span", { className: "fd-num", style: { color: single ? "var(--warn-text)" : "var(--csi-3-mark)", fontWeight: 700 }, children: [
8459
8477
  "+",
8460
8478
  bonusPct,
8461
8479
  "% of +",
@@ -8464,7 +8482,7 @@ function SurroundSound({ present = [], bonusPct = 0, bonusMax = 40, missedCost,
8464
8482
  ] })
8465
8483
  ] }),
8466
8484
  /* @__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)" } }) }),
8467
- /* @__PURE__ */ jsxs64("span", { className: "fd-body-sm fd-secondary", style: { textWrap: "pretty" }, children: [
8485
+ /* @__PURE__ */ jsxs65("span", { className: "fd-body-sm fd-secondary", style: { textWrap: "pretty" }, children: [
8468
8486
  present.length,
8469
8487
  " of 6 channel categories present.",
8470
8488
  " ",
@@ -8476,7 +8494,7 @@ function SurroundSound({ present = [], bonusPct = 0, bonusMax = 40, missedCost,
8476
8494
  }
8477
8495
 
8478
8496
  // src/components/planner/Importance.tsx
8479
- import { jsx as jsx70, jsxs as jsxs65 } from "react/jsx-runtime";
8497
+ import { jsx as jsx70, jsxs as jsxs66 } from "react/jsx-runtime";
8480
8498
  var IMPORTANCE_LEVELS = [
8481
8499
  { id: "nudge", rank: 1, label: "Nudge", icon: "feather", description: "Breaks a tie, nothing more." },
8482
8500
  { id: "lean", rank: 2, label: "Lean", icon: "arrow-bend-up-right", description: "A mild preference between otherwise equal options." },
@@ -8506,7 +8524,7 @@ function importanceTokens(id) {
8506
8524
  function ImportanceTag({ level, showLabel = true, size = "sm", className = "" }) {
8507
8525
  const lvl = importanceLevel(level);
8508
8526
  const t = importanceTokens(level);
8509
- return /* @__PURE__ */ jsxs65(
8527
+ return /* @__PURE__ */ jsxs66(
8510
8528
  "span",
8511
8529
  {
8512
8530
  className: ["fd-imp-tag", size === "md" ? "is-md" : "", className].filter(Boolean).join(" "),
@@ -8521,8 +8539,8 @@ function ImportanceTag({ level, showLabel = true, size = "sm", className = "" })
8521
8539
  }
8522
8540
 
8523
8541
  // src/components/planner/PreferenceMeter.tsx
8524
- import * as React39 from "react";
8525
- import { jsx as jsx71, jsxs as jsxs66 } from "react/jsx-runtime";
8542
+ import * as React40 from "react";
8543
+ import { jsx as jsx71, jsxs as jsxs67 } from "react/jsx-runtime";
8526
8544
  function preferenceScore(criteria) {
8527
8545
  const earned = criteria.reduce((n, c) => n + (Number(c.earned) || 0), 0);
8528
8546
  const weight = criteria.reduce((n, c) => n + (Number(c.weight) || 0), 0);
@@ -8551,7 +8569,7 @@ function PreferenceMeter({
8551
8569
  className = ""
8552
8570
  }) {
8553
8571
  const value = score == null ? preferenceScore(criteria) : score;
8554
- const segments = React39.useMemo(() => preferenceSegments(criteria), [criteria]);
8572
+ const segments = React40.useMemo(() => preferenceSegments(criteria), [criteria]);
8555
8573
  return /* @__PURE__ */ jsx71(
8556
8574
  ScoreMeter,
8557
8575
  {
@@ -8564,20 +8582,20 @@ function PreferenceMeter({
8564
8582
  placement,
8565
8583
  className,
8566
8584
  breakdownLabel: breakdownTitle,
8567
- breakdown: /* @__PURE__ */ jsxs66("div", { className: "fd-prefbreak", children: [
8568
- /* @__PURE__ */ jsxs66("div", { className: "fd-prefbreak-head", children: [
8585
+ breakdown: /* @__PURE__ */ jsxs67("div", { className: "fd-prefbreak", children: [
8586
+ /* @__PURE__ */ jsxs67("div", { className: "fd-prefbreak-head", children: [
8569
8587
  /* @__PURE__ */ jsx71("span", { className: "fd-label-lg", children: breakdownTitle }),
8570
8588
  /* @__PURE__ */ jsx71("span", { className: "fd-prefbreak-score fd-tabular", children: Math.round(value) })
8571
8589
  ] }),
8572
8590
  /* @__PURE__ */ jsx71("ul", { className: "fd-prefbreak-list", children: criteria.map((c) => {
8573
8591
  const pct = c.weight > 0 ? Math.round((Number(c.earned) || 0) / c.weight * 100) : 0;
8574
- return /* @__PURE__ */ jsxs66("li", { className: pct === 0 ? "fd-prefbreak-item is-unmet" : "fd-prefbreak-item", children: [
8592
+ return /* @__PURE__ */ jsxs67("li", { className: pct === 0 ? "fd-prefbreak-item is-unmet" : "fd-prefbreak-item", children: [
8575
8593
  /* @__PURE__ */ jsx71(ImportanceTag, { level: c.importance }),
8576
- /* @__PURE__ */ jsxs66("span", { className: "fd-prefbreak-text", children: [
8594
+ /* @__PURE__ */ jsxs67("span", { className: "fd-prefbreak-text", children: [
8577
8595
  /* @__PURE__ */ jsx71("span", { className: "fd-prefbreak-label", children: c.label }),
8578
8596
  c.note ? /* @__PURE__ */ jsx71("span", { className: "fd-prefbreak-note", children: c.note }) : null
8579
8597
  ] }),
8580
- /* @__PURE__ */ jsxs66("span", { className: "fd-prefbreak-val fd-tabular", children: [
8598
+ /* @__PURE__ */ jsxs67("span", { className: "fd-prefbreak-val fd-tabular", children: [
8581
8599
  Math.round(Number(c.earned) || 0),
8582
8600
  /* @__PURE__ */ jsx71("span", { className: "fd-prefbreak-sep", children: "/" }),
8583
8601
  Math.round(c.weight)
@@ -8590,10 +8608,10 @@ function PreferenceMeter({
8590
8608
  }
8591
8609
 
8592
8610
  // src/components/chat/AgentChatPanel.tsx
8593
- import * as React45 from "react";
8611
+ import * as React46 from "react";
8594
8612
 
8595
8613
  // src/components/chat/chatEngine.ts
8596
- import * as React40 from "react";
8614
+ import * as React41 from "react";
8597
8615
  var CHAT_UNAVAILABLE = "chat_unavailable";
8598
8616
  var JOB_PENDING = ["queued", "running"];
8599
8617
  var JOB_SUCCESS = ["completed", "recovered"];
@@ -8647,22 +8665,22 @@ function useChatEngine(opts) {
8647
8665
  onClear,
8648
8666
  onFeedback
8649
8667
  } = opts || {};
8650
- const [status, setStatus] = React40.useState("idle");
8651
- const [threadId, setThreadId] = React40.useState(null);
8652
- const [messages, setMessages] = React40.useState([]);
8653
- const [queue, setQueue] = React40.useState([]);
8654
- const [fatal, setFatal] = React40.useState(null);
8655
- const [busy, setBusy] = React40.useState(false);
8656
- const [turnStartedAt, setTurnStartedAt] = React40.useState(null);
8657
- const listRef = React40.useRef([]);
8658
- const queueRef = React40.useRef([]);
8659
- const busyRef = React40.useRef(false);
8660
- const stoppedRef = React40.useRef(false);
8661
- const abortRef = React40.useRef(null);
8662
- const serverCount = React40.useRef(0);
8663
- const threadRef = React40.useRef(null);
8664
- const mounted = React40.useRef(true);
8665
- React40.useEffect(() => {
8668
+ const [status, setStatus] = React41.useState("idle");
8669
+ const [threadId, setThreadId] = React41.useState(null);
8670
+ const [messages, setMessages] = React41.useState([]);
8671
+ const [queue, setQueue] = React41.useState([]);
8672
+ const [fatal, setFatal] = React41.useState(null);
8673
+ const [busy, setBusy] = React41.useState(false);
8674
+ const [turnStartedAt, setTurnStartedAt] = React41.useState(null);
8675
+ const listRef = React41.useRef([]);
8676
+ const queueRef = React41.useRef([]);
8677
+ const busyRef = React41.useRef(false);
8678
+ const stoppedRef = React41.useRef(false);
8679
+ const abortRef = React41.useRef(null);
8680
+ const serverCount = React41.useRef(0);
8681
+ const threadRef = React41.useRef(null);
8682
+ const mounted = React41.useRef(true);
8683
+ React41.useEffect(() => {
8666
8684
  mounted.current = true;
8667
8685
  return () => {
8668
8686
  mounted.current = false;
@@ -8684,14 +8702,14 @@ function useChatEngine(opts) {
8684
8702
  }
8685
8703
  return false;
8686
8704
  };
8687
- const loadThread = React40.useCallback(async (id) => {
8705
+ const loadThread = React41.useCallback(async (id) => {
8688
8706
  const data = await apiAdapter.getThread(id);
8689
8707
  const list = [...data && data.messages || []];
8690
8708
  serverCount.current = list.length;
8691
8709
  commit(list);
8692
8710
  return list;
8693
8711
  }, [apiAdapter]);
8694
- React40.useEffect(() => {
8712
+ React41.useEffect(() => {
8695
8713
  if (!apiAdapter) {
8696
8714
  setStatus("idle");
8697
8715
  setFatal(null);
@@ -8904,7 +8922,7 @@ function useChatEngine(opts) {
8904
8922
  await dispatchTurn(turn);
8905
8923
  }
8906
8924
  }
8907
- const send = React40.useCallback((text, attachments) => {
8925
+ const send = React41.useCallback((text, attachments) => {
8908
8926
  const body = (text || "").trim();
8909
8927
  if (!body && !(attachments && attachments.length)) return;
8910
8928
  if (status === "disconnected") return;
@@ -8914,7 +8932,7 @@ function useChatEngine(opts) {
8914
8932
  stoppedRef.current = false;
8915
8933
  drain();
8916
8934
  }, [status]);
8917
- const stop = React40.useCallback(() => {
8935
+ const stop = React41.useCallback(() => {
8918
8936
  stoppedRef.current = true;
8919
8937
  const ac = abortRef.current;
8920
8938
  if (ac) {
@@ -8933,11 +8951,11 @@ function useChatEngine(opts) {
8933
8951
  store.del(STORAGE_PREFIX + threadRef.current);
8934
8952
  }
8935
8953
  }, [apiAdapter]);
8936
- const removeQueued = React40.useCallback((id) => {
8954
+ const removeQueued = React41.useCallback((id) => {
8937
8955
  queueRef.current = queueRef.current.filter((t) => t.id !== id);
8938
8956
  setQueue(queueRef.current.slice());
8939
8957
  }, []);
8940
- const retry = React40.useCallback(() => {
8958
+ const retry = React41.useCallback(() => {
8941
8959
  const list = listRef.current;
8942
8960
  let at = -1;
8943
8961
  for (let i = list.length - 1; i >= 0; i--) if (list[i].role === "user") {
@@ -8953,19 +8971,19 @@ function useChatEngine(opts) {
8953
8971
  setQueue(queueRef.current.slice());
8954
8972
  drain();
8955
8973
  }, []);
8956
- const clear = React40.useCallback(() => {
8974
+ const clear = React41.useCallback(() => {
8957
8975
  commit([]);
8958
8976
  serverCount.current = 0;
8959
8977
  queueRef.current = [];
8960
8978
  setQueue([]);
8961
8979
  onClear && onClear();
8962
8980
  }, [onClear]);
8963
- const setFeedback = React40.useCallback((id, value) => {
8981
+ const setFeedback = React41.useCallback((id, value) => {
8964
8982
  patch(id, (m) => ({ feedback: m.feedback === value ? null : value }));
8965
8983
  const msg = listRef.current.find((m) => m.id === id);
8966
8984
  onFeedback && onFeedback({ message: msg, feedback: msg ? msg.feedback : value });
8967
8985
  }, [onFeedback]);
8968
- const reload = React40.useCallback(async () => {
8986
+ const reload = React41.useCallback(async () => {
8969
8987
  if (!threadRef.current) return;
8970
8988
  setStatus("loading");
8971
8989
  try {
@@ -9003,11 +9021,11 @@ var ChatKit = {
9003
9021
  };
9004
9022
 
9005
9023
  // src/components/chat/ChatTranscript.tsx
9006
- import * as React42 from "react";
9024
+ import * as React43 from "react";
9007
9025
 
9008
9026
  // src/components/chat/ChatTurn.tsx
9009
- import * as React41 from "react";
9010
- import { jsx as jsx72, jsxs as jsxs67 } from "react/jsx-runtime";
9027
+ import * as React42 from "react";
9028
+ import { jsx as jsx72, jsxs as jsxs68 } from "react/jsx-runtime";
9011
9029
  function JsonView({ value }) {
9012
9030
  let text;
9013
9031
  try {
@@ -9022,20 +9040,20 @@ function PacketCard({ packet, schema, render, onApply, applied }) {
9022
9040
  const s = schema || {};
9023
9041
  const invalid = packet.valid === false;
9024
9042
  const title = s.heading || packet.type;
9025
- return /* @__PURE__ */ jsxs67("section", { className: "fdc-packet" + (invalid ? " is-invalid" : ""), "aria-label": title, children: [
9026
- /* @__PURE__ */ jsxs67("header", { className: "fdc-packet-head", children: [
9043
+ return /* @__PURE__ */ jsxs68("section", { className: "fdc-packet" + (invalid ? " is-invalid" : ""), "aria-label": title, children: [
9044
+ /* @__PURE__ */ jsxs68("header", { className: "fdc-packet-head", children: [
9027
9045
  /* @__PURE__ */ jsx72("i", { className: "ph ph-" + (s.icon || "package"), "aria-hidden": "true" }),
9028
9046
  /* @__PURE__ */ jsx72("span", { className: "fdc-packet-title", children: title }),
9029
9047
  packet.repaired ? /* @__PURE__ */ jsx72("span", { className: "fdc-packet-badge", children: "Repaired" }) : null,
9030
9048
  invalid ? /* @__PURE__ */ jsx72("span", { className: "fdc-packet-badge is-danger", children: "Invalid" }) : null
9031
9049
  ] }),
9032
- invalid ? /* @__PURE__ */ jsxs67("div", { className: "fdc-packet-alert", role: "alert", children: [
9050
+ invalid ? /* @__PURE__ */ jsxs68("div", { className: "fdc-packet-alert", role: "alert", children: [
9033
9051
  /* @__PURE__ */ jsx72("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
9034
9052
  /* @__PURE__ */ jsx72("span", { children: packet.error || "This result failed validation and can\u2019t be applied." })
9035
9053
  ] }) : /* @__PURE__ */ jsx72("div", { className: "fdc-packet-body", children: render ? render(packet) : /* @__PURE__ */ jsx72(JsonView, { value: packet.payload }) }),
9036
- !invalid && onApply ? /* @__PURE__ */ jsxs67("footer", { className: "fdc-packet-foot", children: [
9054
+ !invalid && onApply ? /* @__PURE__ */ jsxs68("footer", { className: "fdc-packet-foot", children: [
9037
9055
  packet.repaired ? /* @__PURE__ */ jsx72("span", { className: "fdc-packet-note", children: "Corrected by the backend after a first attempt." }) : /* @__PURE__ */ jsx72("span", {}),
9038
- /* @__PURE__ */ jsxs67("button", { type: "button", className: "fd-btn fd-btn-primary fd-btn-sm", disabled: applied, onClick: () => onApply(packet), children: [
9056
+ /* @__PURE__ */ jsxs68("button", { type: "button", className: "fd-btn fd-btn-primary fd-btn-sm", disabled: applied, onClick: () => onApply(packet), children: [
9039
9057
  /* @__PURE__ */ jsx72("i", { className: "ph ph-" + (applied ? "check" : "arrow-square-in"), "aria-hidden": "true" }),
9040
9058
  applied ? "Applied" : s.applyLabel || "Apply"
9041
9059
  ] })
@@ -9043,13 +9061,13 @@ function PacketCard({ packet, schema, render, onApply, applied }) {
9043
9061
  ] });
9044
9062
  }
9045
9063
  function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
9046
- const [open, setOpen] = React41.useState(defaultOpen);
9064
+ const [open, setOpen] = React42.useState(defaultOpen);
9047
9065
  if (!text) return null;
9048
- return /* @__PURE__ */ jsxs67("div", { className: "fdc-think" + (open ? " is-open" : ""), children: [
9049
- /* @__PURE__ */ jsxs67("button", { type: "button", className: "fdc-think-head", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
9066
+ return /* @__PURE__ */ jsxs68("div", { className: "fdc-think" + (open ? " is-open" : ""), children: [
9067
+ /* @__PURE__ */ jsxs68("button", { type: "button", className: "fdc-think-head", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
9050
9068
  /* @__PURE__ */ jsx72("i", { className: "ph ph-brain", "aria-hidden": "true" }),
9051
9069
  /* @__PURE__ */ jsx72("span", { children: streaming ? "Thinking" : durationMs ? "Thought for " + formatDuration(durationMs) : "Thought process" }),
9052
- streaming ? /* @__PURE__ */ jsxs67("span", { className: "fdc-dots", "aria-hidden": "true", children: [
9070
+ streaming ? /* @__PURE__ */ jsxs68("span", { className: "fdc-dots", "aria-hidden": "true", children: [
9053
9071
  /* @__PURE__ */ jsx72("span", {}),
9054
9072
  /* @__PURE__ */ jsx72("span", {}),
9055
9073
  /* @__PURE__ */ jsx72("span", {})
@@ -9060,19 +9078,19 @@ function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
9060
9078
  ] });
9061
9079
  }
9062
9080
  function Citations({ items = [], onOpen }) {
9063
- const [open, setOpen] = React41.useState(false);
9081
+ const [open, setOpen] = React42.useState(false);
9064
9082
  if (!items.length) return null;
9065
- return /* @__PURE__ */ jsxs67("div", { className: "fdc-cites", children: [
9066
- /* @__PURE__ */ jsxs67("button", { type: "button", className: "fdc-cites-head", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
9083
+ return /* @__PURE__ */ jsxs68("div", { className: "fdc-cites", children: [
9084
+ /* @__PURE__ */ jsxs68("button", { type: "button", className: "fdc-cites-head", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
9067
9085
  /* @__PURE__ */ jsx72("i", { className: "ph ph-quotes", "aria-hidden": "true" }),
9068
- /* @__PURE__ */ jsxs67("span", { children: [
9086
+ /* @__PURE__ */ jsxs68("span", { children: [
9069
9087
  items.length,
9070
9088
  " source",
9071
9089
  items.length === 1 ? "" : "s"
9072
9090
  ] }),
9073
9091
  /* @__PURE__ */ jsx72("i", { className: "ph ph-caret-" + (open ? "up" : "down"), "aria-hidden": "true" })
9074
9092
  ] }),
9075
- open ? /* @__PURE__ */ jsx72("ol", { className: "fdc-cites-list", children: items.map((c, i) => /* @__PURE__ */ jsxs67("li", { children: [
9093
+ open ? /* @__PURE__ */ jsx72("ol", { className: "fdc-cites-list", children: items.map((c, i) => /* @__PURE__ */ jsxs68("li", { children: [
9076
9094
  /* @__PURE__ */ jsx72("span", { className: "fdc-cite-n fd-tabular", children: c.marker || i + 1 }),
9077
9095
  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" }),
9078
9096
  c.detail ? /* @__PURE__ */ jsx72("span", { className: "fdc-cite-detail", children: c.detail }) : null
@@ -9086,24 +9104,24 @@ function clampText(text, max) {
9086
9104
  return (at > max * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
9087
9105
  }
9088
9106
  function MessageBody({ message: m, ctx }) {
9089
- const [expanded, setExpanded] = React41.useState(false);
9107
+ const [expanded, setExpanded] = React42.useState(false);
9090
9108
  const isUser = m.role === "user";
9091
9109
  const raw = m.text || "";
9092
9110
  const clamped = !expanded && !m.streaming ? clampText(raw, ctx.maxVisibleChars) : null;
9093
9111
  const body = clamped != null ? clamped : raw;
9094
9112
  const showMd = ctx.markdown && !isUser;
9095
- return /* @__PURE__ */ jsxs67("div", { className: "fdc-body", children: [
9113
+ return /* @__PURE__ */ jsxs68("div", { className: "fdc-body", children: [
9096
9114
  m.thinking && ctx.showThinking ? /* @__PURE__ */ jsx72(ThinkingBlock, { text: m.thinking, durationMs: m.thinkingMs, streaming: m.streaming && !m.text }) : null,
9097
9115
  m.steps && m.steps.length && ctx.showSteps ? /* @__PURE__ */ jsx72(StepList, { steps: m.steps, defaultOpen: m.steps.some((s) => s.status === "running"), dense: true }) : null,
9098
- body ? /* @__PURE__ */ jsxs67("div", { className: "fdc-text" + (isUser ? " is-user" : ""), children: [
9116
+ body ? /* @__PURE__ */ jsxs68("div", { className: "fdc-text" + (isUser ? " is-user" : ""), children: [
9099
9117
  showMd ? /* @__PURE__ */ jsx72(Markdown, { source: body, headingOffset: 2, codeProps: { collapseAfter: 22 }, renderCitation: ctx.renderCitation }) : /* @__PURE__ */ jsx72("div", { className: "fdc-plain", children: body }),
9100
9118
  m.streaming ? /* @__PURE__ */ jsx72("span", { className: "fdc-caret", "aria-hidden": "true" }) : null
9101
9119
  ] }) : null,
9102
- clamped != null ? /* @__PURE__ */ jsxs67("button", { type: "button", className: "fdc-more", onClick: () => setExpanded(true), children: [
9120
+ clamped != null ? /* @__PURE__ */ jsxs68("button", { type: "button", className: "fdc-more", onClick: () => setExpanded(true), children: [
9103
9121
  /* @__PURE__ */ jsx72("i", { className: "ph ph-caret-down", "aria-hidden": "true" }),
9104
9122
  "Show more",
9105
9123
  /* @__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" })
9106
- ] }) : expanded && ctx.maxVisibleChars && raw.length > ctx.maxVisibleChars ? /* @__PURE__ */ jsxs67("button", { type: "button", className: "fdc-more", onClick: () => setExpanded(false), children: [
9124
+ ] }) : expanded && ctx.maxVisibleChars && raw.length > ctx.maxVisibleChars ? /* @__PURE__ */ jsxs68("button", { type: "button", className: "fdc-more", onClick: () => setExpanded(false), children: [
9107
9125
  /* @__PURE__ */ jsx72("i", { className: "ph ph-caret-up", "aria-hidden": "true" }),
9108
9126
  "Show less"
9109
9127
  ] }) : null,
@@ -9119,33 +9137,33 @@ function MessageBody({ message: m, ctx }) {
9119
9137
  }
9120
9138
  ) : null,
9121
9139
  m.citations && m.citations.length ? /* @__PURE__ */ jsx72(Citations, { items: m.citations, onOpen: ctx.onOpenCitation }) : null,
9122
- m.working ? /* @__PURE__ */ jsxs67("div", { className: "fdc-working", role: "status", children: [
9123
- /* @__PURE__ */ jsxs67("span", { className: "fdc-dots", "aria-hidden": "true", children: [
9140
+ m.working ? /* @__PURE__ */ jsxs68("div", { className: "fdc-working", role: "status", children: [
9141
+ /* @__PURE__ */ jsxs68("span", { className: "fdc-dots", "aria-hidden": "true", children: [
9124
9142
  /* @__PURE__ */ jsx72("span", {}),
9125
9143
  /* @__PURE__ */ jsx72("span", {}),
9126
9144
  /* @__PURE__ */ jsx72("span", {})
9127
9145
  ] }),
9128
- /* @__PURE__ */ jsxs67("span", { className: "fdc-working-label", children: [
9146
+ /* @__PURE__ */ jsxs68("span", { className: "fdc-working-label", children: [
9129
9147
  m.resumed ? "Resuming" : "Working",
9130
- m.job && m.job.status ? /* @__PURE__ */ jsxs67("span", { className: "fdc-working-job", children: [
9148
+ m.job && m.job.status ? /* @__PURE__ */ jsxs68("span", { className: "fdc-working-job", children: [
9131
9149
  " \xB7 ",
9132
9150
  m.job.status
9133
9151
  ] }) : null,
9134
- m.job && m.job.detail ? /* @__PURE__ */ jsxs67("span", { className: "fdc-working-job", children: [
9152
+ m.job && m.job.detail ? /* @__PURE__ */ jsxs68("span", { className: "fdc-working-job", children: [
9135
9153
  " \xB7 ",
9136
9154
  m.job.detail
9137
9155
  ] }) : null
9138
9156
  ] }),
9139
9157
  m.jobId ? /* @__PURE__ */ jsx72("span", { className: "fdc-working-id fd-mono", children: String(m.jobId).slice(0, 12) }) : null
9140
9158
  ] }) : null,
9141
- m.stopped ? /* @__PURE__ */ jsxs67("div", { className: "fdc-stopped", children: [
9159
+ m.stopped ? /* @__PURE__ */ jsxs68("div", { className: "fdc-stopped", children: [
9142
9160
  /* @__PURE__ */ jsx72("i", { className: "ph ph-stop-circle", "aria-hidden": "true" }),
9143
9161
  "Stopped"
9144
9162
  ] }) : null,
9145
- m.error ? /* @__PURE__ */ jsxs67("div", { className: "fdc-error", role: "alert", children: [
9163
+ m.error ? /* @__PURE__ */ jsxs68("div", { className: "fdc-error", role: "alert", children: [
9146
9164
  /* @__PURE__ */ jsx72("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
9147
9165
  /* @__PURE__ */ jsx72("span", { className: "fdc-error-text", children: ctx.errorCopy ? ctx.errorCopy(m.error) : m.error }),
9148
- m.retryable && ctx.onRetry ? /* @__PURE__ */ jsxs67("button", { type: "button", className: "fdc-error-retry", onClick: ctx.onRetry, children: [
9166
+ m.retryable && ctx.onRetry ? /* @__PURE__ */ jsxs68("button", { type: "button", className: "fdc-error-retry", onClick: ctx.onRetry, children: [
9149
9167
  /* @__PURE__ */ jsx72("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }),
9150
9168
  "Retry"
9151
9169
  ] }) : null
@@ -9153,9 +9171,9 @@ function MessageBody({ message: m, ctx }) {
9153
9171
  ] });
9154
9172
  }
9155
9173
  function useCopyRun() {
9156
- const [done, setDone] = React41.useState(false);
9157
- const t = React41.useRef(null);
9158
- React41.useEffect(() => () => {
9174
+ const [done, setDone] = React42.useState(false);
9175
+ const t = React42.useRef(null);
9176
+ React42.useEffect(() => () => {
9159
9177
  if (t.current) clearTimeout(t.current);
9160
9178
  }, []);
9161
9179
  return [done, (text) => {
@@ -9175,14 +9193,14 @@ function RunActions({ group, ctx }) {
9175
9193
  const isAssistant = group.role === "assistant";
9176
9194
  const fb = last.feedback;
9177
9195
  if (!ctx.messageActions) return null;
9178
- return /* @__PURE__ */ jsxs67("div", { className: "fdc-actions", role: "group", "aria-label": "Message actions", children: [
9179
- /* @__PURE__ */ jsxs67("button", { type: "button", className: "fdc-act" + (copied ? " is-done" : ""), onClick: () => copy(markdownToText(text)), "aria-label": "Copy message", children: [
9196
+ return /* @__PURE__ */ jsxs68("div", { className: "fdc-actions", role: "group", "aria-label": "Message actions", children: [
9197
+ /* @__PURE__ */ jsxs68("button", { type: "button", className: "fdc-act" + (copied ? " is-done" : ""), onClick: () => copy(markdownToText(text)), "aria-label": "Copy message", children: [
9180
9198
  /* @__PURE__ */ jsx72("i", { className: "ph ph-" + (copied ? "check" : "copy"), "aria-hidden": "true" }),
9181
9199
  /* @__PURE__ */ jsx72("span", { className: "fdc-act-label", children: copied ? "Copied" : "Copy" })
9182
9200
  ] }),
9183
9201
  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,
9184
9202
  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,
9185
- isAssistant && ctx.onFeedback ? /* @__PURE__ */ jsxs67(React41.Fragment, { children: [
9203
+ isAssistant && ctx.onFeedback ? /* @__PURE__ */ jsxs68(React42.Fragment, { children: [
9186
9204
  /* @__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" }) }),
9187
9205
  /* @__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" }) })
9188
9206
  ] }) : null,
@@ -9194,14 +9212,14 @@ function ChatTurn({ group, ctx }) {
9194
9212
  const name = isUser ? ctx.userName : group.author || ctx.assistantName;
9195
9213
  const avatar = isUser ? ctx.userAvatar : ctx.assistantAvatar;
9196
9214
  const stamp = group.messages[0].timestamp;
9197
- return /* @__PURE__ */ jsxs67("article", { className: "fdc-turn is-" + group.role, "aria-label": String(name) + (stamp ? " at " + formatClock(stamp) : ""), children: [
9198
- /* @__PURE__ */ jsxs67("div", { className: "fdc-turn-head", children: [
9215
+ return /* @__PURE__ */ jsxs68("article", { className: "fdc-turn is-" + group.role, "aria-label": String(name) + (stamp ? " at " + formatClock(stamp) : ""), children: [
9216
+ /* @__PURE__ */ jsxs68("div", { className: "fdc-turn-head", children: [
9199
9217
  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,
9200
9218
  /* @__PURE__ */ jsx72("span", { className: "fdc-who", children: name }),
9201
9219
  stamp ? /* @__PURE__ */ jsx72(RelativeTime, { className: "fdc-when", value: stamp }) : null,
9202
9220
  group.messages.some((m) => m.model) ? /* @__PURE__ */ jsx72("span", { className: "fdc-turn-model", children: group.messages.find((m) => m.model).model }) : null
9203
9221
  ] }),
9204
- /* @__PURE__ */ jsxs67("div", { className: "fdc-turn-body", children: [
9222
+ /* @__PURE__ */ jsxs68("div", { className: "fdc-turn-body", children: [
9205
9223
  group.messages.map((m) => /* @__PURE__ */ jsx72("div", { className: "fdc-msg" + (m.pending ? " is-pending" : ""), children: /* @__PURE__ */ jsx72(MessageBody, { message: m, ctx }) }, m.id)),
9206
9224
  /* @__PURE__ */ jsx72(RunActions, { group, ctx })
9207
9225
  ] })
@@ -9209,7 +9227,7 @@ function ChatTurn({ group, ctx }) {
9209
9227
  }
9210
9228
 
9211
9229
  // src/components/chat/ChatTranscript.tsx
9212
- import { jsx as jsx73, jsxs as jsxs68 } from "react/jsx-runtime";
9230
+ import { jsx as jsx73, jsxs as jsxs69 } from "react/jsx-runtime";
9213
9231
  var GROUP_WINDOW = 6e4;
9214
9232
  var STICK_PX = 100;
9215
9233
  function groupMessages(list) {
@@ -9244,9 +9262,9 @@ function Suggestions({ items = [], onPick }) {
9244
9262
  if (!items.length) return null;
9245
9263
  return /* @__PURE__ */ jsx73("div", { className: "fdc-suggest", children: items.map((s, i) => {
9246
9264
  const it = typeof s === "string" ? { label: s, text: s } : s;
9247
- return /* @__PURE__ */ jsxs68("button", { type: "button", className: "fdc-suggest-item", onClick: () => onPick && onPick(it.text || it.label), children: [
9265
+ return /* @__PURE__ */ jsxs69("button", { type: "button", className: "fdc-suggest-item", onClick: () => onPick && onPick(it.text || it.label), children: [
9248
9266
  it.icon ? /* @__PURE__ */ jsx73("i", { className: "ph ph-" + it.icon, "aria-hidden": "true" }) : null,
9249
- /* @__PURE__ */ jsxs68("span", { className: "fdc-suggest-text", children: [
9267
+ /* @__PURE__ */ jsxs69("span", { className: "fdc-suggest-text", children: [
9250
9268
  /* @__PURE__ */ jsx73("span", { className: "fdc-suggest-label", children: it.label }),
9251
9269
  it.description ? /* @__PURE__ */ jsx73("span", { className: "fdc-suggest-desc", children: it.description }) : null
9252
9270
  ] }),
@@ -9255,9 +9273,9 @@ function Suggestions({ items = [], onPick }) {
9255
9273
  }) });
9256
9274
  }
9257
9275
  function LoadingTurns() {
9258
- return /* @__PURE__ */ jsx73("div", { className: "fdc-skel", "aria-hidden": "true", children: [0, 1].map((i) => /* @__PURE__ */ jsxs68("div", { className: "fdc-skel-turn", children: [
9276
+ return /* @__PURE__ */ jsx73("div", { className: "fdc-skel", "aria-hidden": "true", children: [0, 1].map((i) => /* @__PURE__ */ jsxs69("div", { className: "fdc-skel-turn", children: [
9259
9277
  /* @__PURE__ */ jsx73("div", { className: "fd-skel fd-skel-circle", style: { width: 22, height: 22 } }),
9260
- /* @__PURE__ */ jsxs68("div", { className: "fdc-skel-lines", children: [
9278
+ /* @__PURE__ */ jsxs69("div", { className: "fdc-skel-lines", children: [
9261
9279
  /* @__PURE__ */ jsx73("div", { className: "fd-skel", style: { width: i ? "62%" : "44%", height: 11 } }),
9262
9280
  /* @__PURE__ */ jsx73("div", { className: "fd-skel", style: { width: i ? "94%" : "78%", height: 11 } }),
9263
9281
  /* @__PURE__ */ jsx73("div", { className: "fd-skel", style: { width: i ? "71%" : "56%", height: 11 } })
@@ -9277,10 +9295,10 @@ function ChatTranscript({
9277
9295
  renderEmpty,
9278
9296
  className = ""
9279
9297
  }) {
9280
- const scroller = React42.useRef(null);
9281
- const stick = React42.useRef(true);
9282
- const [pill, setPill] = React42.useState(0);
9283
- const seen = React42.useRef(0);
9298
+ const scroller = React43.useRef(null);
9299
+ const stick = React43.useRef(true);
9300
+ const [pill, setPill] = React43.useState(0);
9301
+ const seen = React43.useRef(0);
9284
9302
  const toBottom = (smooth) => {
9285
9303
  const el = scroller.current;
9286
9304
  if (!el) return;
@@ -9299,7 +9317,7 @@ function ChatTranscript({
9299
9317
  seen.current = messages.length;
9300
9318
  }
9301
9319
  };
9302
- React42.useLayoutEffect(() => {
9320
+ React43.useLayoutEffect(() => {
9303
9321
  const el = scroller.current;
9304
9322
  if (!el) return;
9305
9323
  if (stick.current) {
@@ -9307,7 +9325,7 @@ function ChatTranscript({
9307
9325
  seen.current = messages.length;
9308
9326
  } else setPill(Math.max(0, messages.length - seen.current));
9309
9327
  }, [messages]);
9310
- React42.useEffect(() => {
9328
+ React43.useEffect(() => {
9311
9329
  const el = scroller.current;
9312
9330
  const inner = el && el.firstChild;
9313
9331
  if (!el || !inner || typeof ResizeObserver === "undefined") return;
@@ -9317,21 +9335,21 @@ function ChatTranscript({
9317
9335
  ro.observe(inner);
9318
9336
  return () => ro.disconnect();
9319
9337
  }, []);
9320
- const groups = React42.useMemo(() => groupMessages(messages), [messages]);
9338
+ const groups = React43.useMemo(() => groupMessages(messages), [messages]);
9321
9339
  const empty = !messages.length && status === "ready";
9322
- return /* @__PURE__ */ jsxs68("div", { className: ["fdc-scroll", className].filter(Boolean).join(" "), ref: scroller, onScroll, children: [
9323
- /* @__PURE__ */ jsxs68("div", { className: "fdc-log", role: "log", "aria-label": "Conversation", children: [
9340
+ return /* @__PURE__ */ jsxs69("div", { className: ["fdc-scroll", className].filter(Boolean).join(" "), ref: scroller, onScroll, children: [
9341
+ /* @__PURE__ */ jsxs69("div", { className: "fdc-log", role: "log", "aria-label": "Conversation", children: [
9324
9342
  status === "loading" || status === "resolving" ? /* @__PURE__ */ jsx73(LoadingTurns, {}) : null,
9325
- status === "disconnected" ? /* @__PURE__ */ jsxs68("div", { className: "fdc-dead", children: [
9343
+ status === "disconnected" ? /* @__PURE__ */ jsxs69("div", { className: "fdc-dead", children: [
9326
9344
  /* @__PURE__ */ jsx73("span", { className: "fdc-dead-icon", children: /* @__PURE__ */ jsx73("i", { className: "ph ph-plugs", "aria-hidden": "true" }) }),
9327
9345
  /* @__PURE__ */ jsx73("h3", { className: "fdc-dead-title", children: ctx.deadTitle || "The assistant isn\u2019t reachable" }),
9328
9346
  /* @__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." }),
9329
- ctx.onReconnect ? /* @__PURE__ */ jsxs68("button", { type: "button", className: "fd-btn fd-btn-secondary fd-btn-sm", onClick: ctx.onReconnect, children: [
9347
+ ctx.onReconnect ? /* @__PURE__ */ jsxs69("button", { type: "button", className: "fd-btn fd-btn-secondary fd-btn-sm", onClick: ctx.onReconnect, children: [
9330
9348
  /* @__PURE__ */ jsx73("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }),
9331
9349
  "Try again"
9332
9350
  ] }) : null
9333
9351
  ] }) : null,
9334
- empty ? renderEmpty ? renderEmpty() : /* @__PURE__ */ jsxs68("div", { className: "fdc-empty", children: [
9352
+ empty ? renderEmpty ? renderEmpty() : /* @__PURE__ */ jsxs69("div", { className: "fdc-empty", children: [
9335
9353
  /* @__PURE__ */ jsx73("span", { className: "fdc-empty-icon", children: /* @__PURE__ */ jsx73("i", { className: "ph ph-" + emptyIcon, "aria-hidden": "true" }) }),
9336
9354
  /* @__PURE__ */ jsx73("h3", { className: "fdc-empty-title", children: emptyTitle }),
9337
9355
  emptyDescription ? /* @__PURE__ */ jsx73("p", { className: "fdc-empty-body", children: emptyDescription }) : null,
@@ -9341,13 +9359,13 @@ function ChatTranscript({
9341
9359
  const prev = groups[i - 1];
9342
9360
  const k = dayKey(g.messages[0].timestamp);
9343
9361
  const showDay = !!k && (!prev || dayKey(prev.messages[0].timestamp) !== k);
9344
- return /* @__PURE__ */ jsxs68(React42.Fragment, { children: [
9362
+ return /* @__PURE__ */ jsxs69(React43.Fragment, { children: [
9345
9363
  showDay ? /* @__PURE__ */ jsx73("div", { className: "fdc-day", children: /* @__PURE__ */ jsx73("span", { children: dayLabel(k) }) }) : null,
9346
9364
  /* @__PURE__ */ jsx73(ChatTurn, { group: g, ctx })
9347
9365
  ] }, g.key || i);
9348
9366
  })
9349
9367
  ] }),
9350
- pill ? /* @__PURE__ */ jsxs68("button", { type: "button", className: "fdc-pill", onClick: () => toBottom(true), children: [
9368
+ pill ? /* @__PURE__ */ jsxs69("button", { type: "button", className: "fdc-pill", onClick: () => toBottom(true), children: [
9351
9369
  /* @__PURE__ */ jsx73("i", { className: "ph ph-arrow-down", "aria-hidden": "true" }),
9352
9370
  pill,
9353
9371
  " new message",
@@ -9358,8 +9376,8 @@ function ChatTranscript({
9358
9376
  var TranscriptKit = { groupMessages };
9359
9377
 
9360
9378
  // src/components/chat/ChatComposer.tsx
9361
- import * as React43 from "react";
9362
- import { jsx as jsx74, jsxs as jsxs69 } from "react/jsx-runtime";
9379
+ import * as React44 from "react";
9380
+ import { jsx as jsx74, jsxs as jsxs70 } from "react/jsx-runtime";
9363
9381
  function ChatComposer({
9364
9382
  onSubmit,
9365
9383
  onStop,
@@ -9386,17 +9404,17 @@ function ChatComposer({
9386
9404
  onReject,
9387
9405
  onOpenAttachment
9388
9406
  }) {
9389
- const [text, setText] = React43.useState(draft || "");
9390
- const [trigger, setTrigger] = React43.useState(null);
9391
- const [mentionItems, setMentionItems] = React43.useState([]);
9392
- const [listening, setListening] = React43.useState(false);
9393
- const [notice, setNotice] = React43.useState(null);
9394
- const editor = React43.useRef(null);
9395
- const wrap = React43.useRef(null);
9396
- const stopVoice = React43.useRef(null);
9407
+ const [text, setText] = React44.useState(draft || "");
9408
+ const [trigger, setTrigger] = React44.useState(null);
9409
+ const [mentionItems, setMentionItems] = React44.useState([]);
9410
+ const [listening, setListening] = React44.useState(false);
9411
+ const [notice, setNotice] = React44.useState(null);
9412
+ const editor = React44.useRef(null);
9413
+ const wrap = React44.useRef(null);
9414
+ const stopVoice = React44.useRef(null);
9397
9415
  const staged = useStagedFiles(fileUploadHandler, { onError: () => {
9398
9416
  } });
9399
- React43.useEffect(() => {
9417
+ React44.useEffect(() => {
9400
9418
  if (draft != null && draft !== text) setText(draft);
9401
9419
  }, [draft]);
9402
9420
  const change = (v) => {
@@ -9430,7 +9448,7 @@ function ChatComposer({
9430
9448
  e.preventDefault();
9431
9449
  staged.add(found.files);
9432
9450
  };
9433
- React43.useEffect(() => {
9451
+ React44.useEffect(() => {
9434
9452
  if (!trigger || trigger.type !== "mention" || !mentionSources) {
9435
9453
  setMentionItems([]);
9436
9454
  return;
@@ -9448,7 +9466,7 @@ function ChatComposer({
9448
9466
  const q = (trigger.query || "").toLowerCase();
9449
9467
  setMentionItems(mentionSources.filter((m) => !q || (m.label + " " + (m.description || "")).toLowerCase().includes(q)));
9450
9468
  }, [trigger, mentionSources]);
9451
- const slashItems = React43.useMemo(() => {
9469
+ const slashItems = React44.useMemo(() => {
9452
9470
  if (!trigger || trigger.type !== "slash" || !slashCommands) return [];
9453
9471
  const q = (trigger.query || "").toLowerCase();
9454
9472
  return slashCommands.filter((c) => !q || (c.id + " " + c.label + " " + (c.description || "")).toLowerCase().includes(q));
@@ -9525,8 +9543,8 @@ function ChatComposer({
9525
9543
  stopVoice.current = typeof res === "function" ? res : () => {
9526
9544
  };
9527
9545
  };
9528
- return /* @__PURE__ */ jsxs69("div", { className: "fdc-composer" + (disabled ? " is-disabled" : "") + (narrow ? " is-narrow" : ""), children: [
9529
- queue.length ? /* @__PURE__ */ jsx74("div", { className: "fdc-queue", "aria-label": "Queued messages", children: queue.map((q) => /* @__PURE__ */ jsxs69("div", { className: "fdc-queue-row", children: [
9546
+ return /* @__PURE__ */ jsxs70("div", { className: "fdc-composer" + (disabled ? " is-disabled" : "") + (narrow ? " is-narrow" : ""), children: [
9547
+ queue.length ? /* @__PURE__ */ jsx74("div", { className: "fdc-queue", "aria-label": "Queued messages", children: queue.map((q) => /* @__PURE__ */ jsxs70("div", { className: "fdc-queue-row", children: [
9530
9548
  /* @__PURE__ */ jsx74("i", { className: "ph ph-clock-countdown", "aria-hidden": "true" }),
9531
9549
  /* @__PURE__ */ jsx74("span", { className: "fdc-queue-text", children: q.text || (q.attachments ? q.attachments.length + " file(s)" : "") }),
9532
9550
  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
@@ -9546,7 +9564,7 @@ function ChatComposer({
9546
9564
  disabled: !fileUploadHandler || disabled,
9547
9565
  label: "Drop to attach",
9548
9566
  hint: acceptFiles ? acceptFiles.replace(/,/g, " \xB7 ") : void 0,
9549
- children: /* @__PURE__ */ jsxs69("div", { ref: wrap, className: "fdc-field-inner", children: [
9567
+ children: /* @__PURE__ */ jsxs70("div", { ref: wrap, className: "fdc-field-inner", children: [
9550
9568
  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,
9551
9569
  /* @__PURE__ */ jsx74(
9552
9570
  MarkdownEditor,
@@ -9567,20 +9585,20 @@ function ChatComposer({
9567
9585
  ariaLabel: "Message"
9568
9586
  }
9569
9587
  ),
9570
- /* @__PURE__ */ jsxs69("div", { className: "fdc-tools", children: [
9588
+ /* @__PURE__ */ jsxs70("div", { className: "fdc-tools", children: [
9571
9589
  fileUploadHandler ? /* @__PURE__ */ jsx74(FilePickButton, { onFiles: staged.add, onReject: (r) => flash(r[0].message), accept: acceptFiles, maxFileSize, label: "Attach files", icon: "plus" }) : null,
9572
9590
  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,
9573
9591
  toolbarExtras,
9574
9592
  /* @__PURE__ */ jsx74("span", { className: "fdc-tools-gap" }),
9575
- maxLength && text.length > maxLength * 0.6 ? /* @__PURE__ */ jsxs69("span", { className: "fdc-count fd-tabular" + (text.length > maxLength * 0.95 ? " is-hot" : ""), children: [
9593
+ maxLength && text.length > maxLength * 0.6 ? /* @__PURE__ */ jsxs70("span", { className: "fdc-count fd-tabular" + (text.length > maxLength * 0.95 ? " is-hot" : ""), children: [
9576
9594
  text.length,
9577
9595
  "/",
9578
9596
  maxLength
9579
9597
  ] }) : null,
9580
- busy ? /* @__PURE__ */ jsxs69("button", { type: "button", className: "fdc-stop", onClick: onStop, "aria-label": "Stop generating", children: [
9598
+ busy ? /* @__PURE__ */ jsxs70("button", { type: "button", className: "fdc-stop", onClick: onStop, "aria-label": "Stop generating", children: [
9581
9599
  /* @__PURE__ */ jsx74("i", { className: "ph ph-stop-circle", "aria-hidden": "true" }),
9582
9600
  /* @__PURE__ */ jsx74("span", { children: "Stop" })
9583
- ] }) : /* @__PURE__ */ jsxs69("button", { type: "button", className: "fdc-send", onClick: submit, disabled: !canSend, "aria-label": "Send message", children: [
9601
+ ] }) : /* @__PURE__ */ jsxs70("button", { type: "button", className: "fdc-send", onClick: submit, disabled: !canSend, "aria-label": "Send message", children: [
9584
9602
  /* @__PURE__ */ jsx74("i", { className: "ph ph-paper-plane-right", "aria-hidden": "true" }),
9585
9603
  /* @__PURE__ */ jsx74("span", { className: "fdc-send-label", children: "Send" })
9586
9604
  ] })
@@ -9588,7 +9606,7 @@ function ChatComposer({
9588
9606
  ] })
9589
9607
  }
9590
9608
  ),
9591
- notice ? /* @__PURE__ */ jsxs69("div", { className: "fdc-notice", role: "status", children: [
9609
+ notice ? /* @__PURE__ */ jsxs70("div", { className: "fdc-notice", role: "status", children: [
9592
9610
  /* @__PURE__ */ jsx74("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
9593
9611
  notice
9594
9612
  ] }) : null,
@@ -9622,12 +9640,12 @@ function ChatComposer({
9622
9640
  }
9623
9641
 
9624
9642
  // src/components/chat/ChatSessionBar.tsx
9625
- import * as React44 from "react";
9626
- import { jsx as jsx75, jsxs as jsxs70 } from "react/jsx-runtime";
9643
+ import * as React45 from "react";
9644
+ import { jsx as jsx75, jsxs as jsxs71 } from "react/jsx-runtime";
9627
9645
  var compact2 = meterFormats.compact;
9628
9646
  function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extras }) {
9629
- const [open, setOpen] = React44.useState(false);
9630
- const anchor = React44.useRef(null);
9647
+ const [open, setOpen] = React45.useState(false);
9648
+ const anchor = React45.useRef(null);
9631
9649
  const stats = sessionStats || null;
9632
9650
  const cu = contextUsage || null;
9633
9651
  const limits = usageLimits || null;
@@ -9642,9 +9660,9 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
9642
9660
  if (stats && stats.runningTasks) bits.push(stats.runningTasks + " running task" + (stats.runningTasks === 1 ? "" : "s"));
9643
9661
  if (cu) bits.push(pct + "% context");
9644
9662
  const expandable = !!(cu || limits);
9645
- return /* @__PURE__ */ jsxs70(React44.Fragment, { children: [
9646
- /* @__PURE__ */ jsxs70("div", { className: "fdc-bar", children: [
9647
- /* @__PURE__ */ jsxs70(
9663
+ return /* @__PURE__ */ jsxs71(React45.Fragment, { children: [
9664
+ /* @__PURE__ */ jsxs71("div", { className: "fdc-bar", children: [
9665
+ /* @__PURE__ */ jsxs71(
9648
9666
  "button",
9649
9667
  {
9650
9668
  type: "button",
@@ -9674,14 +9692,14 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
9674
9692
  maxHeight: 460,
9675
9693
  padded: true,
9676
9694
  label: "Usage",
9677
- footer: onClear ? /* @__PURE__ */ jsxs70("button", { type: "button", className: "fdc-usage-clear", onClick: () => {
9695
+ footer: onClear ? /* @__PURE__ */ jsxs71("button", { type: "button", className: "fdc-usage-clear", onClick: () => {
9678
9696
  setOpen(false);
9679
9697
  onClear();
9680
9698
  }, children: [
9681
9699
  /* @__PURE__ */ jsx75("i", { className: "ph ph-trash", "aria-hidden": "true" }),
9682
9700
  "Clear conversation"
9683
9701
  ] }) : void 0,
9684
- children: /* @__PURE__ */ jsxs70("div", { className: "fdc-usage", children: [
9702
+ children: /* @__PURE__ */ jsxs71("div", { className: "fdc-usage", children: [
9685
9703
  cu ? /* @__PURE__ */ jsx75("section", { className: "fdc-usage-sec", children: /* @__PURE__ */ jsx75(
9686
9704
  SegmentedMeter,
9687
9705
  {
@@ -9694,7 +9712,7 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
9694
9712
  remainderLabel: "Free"
9695
9713
  }
9696
9714
  ) }) : null,
9697
- limits && limits.length ? /* @__PURE__ */ jsxs70("section", { className: "fdc-usage-sec", children: [
9715
+ limits && limits.length ? /* @__PURE__ */ jsxs71("section", { className: "fdc-usage-sec", children: [
9698
9716
  /* @__PURE__ */ jsx75("h4", { className: "fdc-usage-h", children: "Usage limits" }),
9699
9717
  /* @__PURE__ */ jsx75("div", { className: "fdc-usage-rows", children: limits.map((l) => /* @__PURE__ */ jsx75(
9700
9718
  QuotaRow,
@@ -9706,23 +9724,23 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
9706
9724
  l.id
9707
9725
  )) })
9708
9726
  ] }) : null,
9709
- stats ? /* @__PURE__ */ jsxs70("section", { className: "fdc-usage-sec fdc-usage-stats", children: [
9710
- stats.elapsedMs ? /* @__PURE__ */ jsxs70("div", { children: [
9727
+ stats ? /* @__PURE__ */ jsxs71("section", { className: "fdc-usage-sec fdc-usage-stats", children: [
9728
+ stats.elapsedMs ? /* @__PURE__ */ jsxs71("div", { children: [
9711
9729
  /* @__PURE__ */ jsx75("span", { children: "Session" }),
9712
9730
  /* @__PURE__ */ jsx75("b", { className: "fd-tabular", children: formatDuration(stats.elapsedMs) })
9713
9731
  ] }) : null,
9714
- stats.tokens ? /* @__PURE__ */ jsxs70("div", { children: [
9732
+ stats.tokens ? /* @__PURE__ */ jsxs71("div", { children: [
9715
9733
  /* @__PURE__ */ jsx75("span", { children: "Tokens" }),
9716
9734
  /* @__PURE__ */ jsx75("b", { className: "fd-tabular", children: stats.tokens.toLocaleString() })
9717
9735
  ] }) : null,
9718
- stats.costUsd != null ? /* @__PURE__ */ jsxs70("div", { children: [
9736
+ stats.costUsd != null ? /* @__PURE__ */ jsxs71("div", { children: [
9719
9737
  /* @__PURE__ */ jsx75("span", { children: "Cost" }),
9720
- /* @__PURE__ */ jsxs70("b", { className: "fd-tabular", children: [
9738
+ /* @__PURE__ */ jsxs71("b", { className: "fd-tabular", children: [
9721
9739
  "$",
9722
9740
  Number(stats.costUsd).toFixed(3)
9723
9741
  ] })
9724
9742
  ] }) : null,
9725
- stats.turns ? /* @__PURE__ */ jsxs70("div", { children: [
9743
+ stats.turns ? /* @__PURE__ */ jsxs71("div", { children: [
9726
9744
  /* @__PURE__ */ jsx75("span", { children: "Turns" }),
9727
9745
  /* @__PURE__ */ jsx75("b", { className: "fd-tabular", children: stats.turns })
9728
9746
  ] }) : null
@@ -9776,14 +9794,14 @@ function ModelControls({
9776
9794
  items.push({ kind: "section", label: "Fast mode" });
9777
9795
  items.push({
9778
9796
  kind: "custom",
9779
- render: () => /* @__PURE__ */ jsxs70("label", { className: "fdc-switchrow", children: [
9797
+ render: () => /* @__PURE__ */ jsxs71("label", { className: "fdc-switchrow", children: [
9780
9798
  /* @__PURE__ */ jsx75("span", { children: fastModeLabel }),
9781
9799
  /* @__PURE__ */ jsx75("input", { type: "checkbox", className: "fd-sr", checked: !!fastMode, onChange: (e) => onFastModeChange(e.target.checked) }),
9782
9800
  /* @__PURE__ */ jsx75("span", { className: "fd-switch-track" + (fastMode ? " is-on" : ""), "aria-hidden": "true", children: /* @__PURE__ */ jsx75("span", { className: "fd-switch-thumb" }) })
9783
9801
  ] })
9784
9802
  });
9785
9803
  }
9786
- return /* @__PURE__ */ jsxs70(React44.Fragment, { children: [
9804
+ return /* @__PURE__ */ jsxs71(React45.Fragment, { children: [
9787
9805
  /* @__PURE__ */ jsx75(
9788
9806
  MenuButton,
9789
9807
  {
@@ -9816,7 +9834,7 @@ function ModelControls({
9816
9834
  }
9817
9835
 
9818
9836
  // src/components/chat/AgentChatPanel.tsx
9819
- import { jsx as jsx76, jsxs as jsxs71 } from "react/jsx-runtime";
9837
+ import { jsx as jsx76, jsxs as jsxs72 } from "react/jsx-runtime";
9820
9838
  var SURFACES = { sidebar: "is-sidebar", inline: "is-inline", page: "is-page", modal: "is-modal", sheet: "is-sheet" };
9821
9839
  function AgentChatPanel({
9822
9840
  /* required */
@@ -9900,11 +9918,11 @@ function AgentChatPanel({
9900
9918
  onFeedback,
9901
9919
  onEditMessage
9902
9920
  }) {
9903
- const [panelWidth, setPanelWidth] = React45.useState(width);
9904
- const [applied, setApplied] = React45.useState({});
9905
- const [draft, setDraft] = React45.useState("");
9906
- const dragging = React45.useRef(null);
9907
- React45.useEffect(() => setPanelWidth(width), [width]);
9921
+ const [panelWidth, setPanelWidth] = React46.useState(width);
9922
+ const [applied, setApplied] = React46.useState({});
9923
+ const [draft, setDraft] = React46.useState("");
9924
+ const dragging = React46.useRef(null);
9925
+ React46.useEffect(() => setPanelWidth(width), [width]);
9908
9926
  const engine = useChatEngine({
9909
9927
  contextType,
9910
9928
  contextId,
@@ -10021,7 +10039,7 @@ function AgentChatPanel({
10021
10039
  })))
10022
10040
  }
10023
10041
  ) : null;
10024
- return /* @__PURE__ */ jsxs71(
10042
+ return /* @__PURE__ */ jsxs72(
10025
10043
  "aside",
10026
10044
  {
10027
10045
  className: ["fdc-panel", SURFACES[surface] || SURFACES.sidebar, narrow ? "is-narrow" : "", className].filter(Boolean).join(" "),
@@ -10047,13 +10065,13 @@ function AgentChatPanel({
10047
10065
  }
10048
10066
  }
10049
10067
  ) : null,
10050
- showHeader ? /* @__PURE__ */ jsxs71("header", { className: "fdc-head", children: [
10068
+ showHeader ? /* @__PURE__ */ jsxs72("header", { className: "fdc-head", children: [
10051
10069
  /* @__PURE__ */ jsx76("span", { className: "fdc-head-mark", "aria-hidden": "true", children: /* @__PURE__ */ jsx76("i", { className: "ph ph-" + assistantIcon }) }),
10052
- /* @__PURE__ */ jsxs71("span", { className: "fdc-head-titles", children: [
10070
+ /* @__PURE__ */ jsxs72("span", { className: "fdc-head-titles", children: [
10053
10071
  /* @__PURE__ */ jsx76("span", { className: "fdc-head-title", children: title }),
10054
10072
  subtitle ? /* @__PURE__ */ jsx76("span", { className: "fdc-head-sub", children: subtitle }) : null
10055
10073
  ] }),
10056
- /* @__PURE__ */ jsxs71("span", { className: "fdc-head-acts", children: [
10074
+ /* @__PURE__ */ jsxs72("span", { className: "fdc-head-acts", children: [
10057
10075
  headerActions,
10058
10076
  threadMenu,
10059
10077
  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,
@@ -10108,7 +10126,7 @@ function AgentChatPanel({
10108
10126
  }
10109
10127
 
10110
10128
  // src/kits/query.ts
10111
- import * as React46 from "react";
10129
+ import * as React47 from "react";
10112
10130
  function eqFilter(get2) {
10113
10131
  return (row, value) => Array.isArray(value) ? value.includes(get2(row)) : get2(row) === value;
10114
10132
  }
@@ -10140,22 +10158,22 @@ function compare(a, b, dir) {
10140
10158
  var API = null;
10141
10159
  var PREFS = null;
10142
10160
  function useServerTable({ endpoint, params, defaults, deps, prefsKey }) {
10143
- const [query, setQuery] = React46.useState(() => {
10161
+ const [query, setQuery] = React47.useState(() => {
10144
10162
  const store = PREFS || window.PlannerPrefs;
10145
10163
  const saved = prefsKey && store ? store.getTable(prefsKey) : {};
10146
10164
  return { ...DEFAULTS, ...defaults || {}, ...saved.pageSize ? { pageSize: saved.pageSize } : {}, ...saved.sort ? { sort: saved.sort, dir: saved.dir || "desc" } : {} };
10147
10165
  });
10148
- const savePref = React46.useCallback((patch2) => {
10166
+ const savePref = React47.useCallback((patch2) => {
10149
10167
  const store = PREFS || window.PlannerPrefs;
10150
10168
  if (prefsKey && store) store.setTable(prefsKey, patch2);
10151
10169
  }, [prefsKey]);
10152
- const [res, setRes] = React46.useState(null);
10153
- const [loading, setLoading] = React46.useState(true);
10154
- const seq2 = React46.useRef(0);
10170
+ const [res, setRes] = React47.useState(null);
10171
+ const [loading, setLoading] = React47.useState(true);
10172
+ const seq2 = React47.useRef(0);
10155
10173
  const depKey = (deps || []).join("|");
10156
10174
  const paramKey = JSON.stringify(params || {});
10157
10175
  const queryKey = JSON.stringify(query);
10158
- React46.useEffect(() => {
10176
+ React47.useEffect(() => {
10159
10177
  const id = ++seq2.current;
10160
10178
  setLoading(true);
10161
10179
  const t = setTimeout(() => {