@flytedan/flytebot-design-system 0.12.5 → 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,19 +1437,19 @@ function DataTable({
1427
1437
  }
1428
1438
 
1429
1439
  // src/components/data/FilterBar.tsx
1430
- import * as React8 from "react";
1431
- import { jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
1440
+ import * as React9 from "react";
1441
+ import { jsx as jsx28, jsxs as jsxs24 } from "react/jsx-runtime";
1432
1442
  var FILTER_BAR_BASE = 120;
1433
1443
  var isSet = (v) => !(v == null || v === "" || v === false);
1434
1444
  function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align = "left", className = "", ...rest }) {
1435
- const [panel, setPanel] = React8.useState(null);
1445
+ const [panel, setPanel] = React9.useState(null);
1436
1446
  const zIndex = useOverlayLayer(FILTER_BAR_BASE);
1437
- const rootRef = React8.useRef(null);
1438
- const textInputRef = React8.useRef(null);
1439
- const optionsRef = React8.useRef(null);
1447
+ const rootRef = React9.useRef(null);
1448
+ const textInputRef = React9.useRef(null);
1449
+ const optionsRef = React9.useRef(null);
1440
1450
  const editingField = panel && panel.kind === "edit" ? fields.find((f) => f.key === panel.key) : void 0;
1441
1451
  const dismissible = !!panel && (panel.kind === "add" || panel.kind === "edit" && editingField?.type === "select");
1442
- React8.useEffect(() => {
1452
+ React9.useEffect(() => {
1443
1453
  if (!dismissible) return;
1444
1454
  const away = (e) => {
1445
1455
  if (rootRef.current && !rootRef.current.contains(e.target)) setPanel(null);
@@ -1454,7 +1464,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
1454
1464
  document.removeEventListener("keydown", esc);
1455
1465
  };
1456
1466
  }, [dismissible]);
1457
- React8.useEffect(() => {
1467
+ React9.useEffect(() => {
1458
1468
  if (!panel || panel.kind !== "edit") return;
1459
1469
  if (editingField?.type === "text") {
1460
1470
  textInputRef.current?.focus();
@@ -1465,12 +1475,12 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
1465
1475
  }, [panel]);
1466
1476
  const addableFields = fields.filter((f) => !isSet(filters[f.key]));
1467
1477
  const startEditing = (key) => setPanel({ kind: "edit", key });
1468
- return /* @__PURE__ */ jsxs23("span", { className, style: { position: "relative", display: "inline-flex", flexWrap: "wrap", alignItems: "center", gap: 8 }, ref: rootRef, ...rest, children: [
1478
+ return /* @__PURE__ */ jsxs24("span", { className, style: { position: "relative", display: "inline-flex", flexWrap: "wrap", alignItems: "center", gap: 8 }, ref: rootRef, ...rest, children: [
1469
1479
  fields.map((field) => {
1470
1480
  const value = filters[field.key];
1471
1481
  const editing = panel?.kind === "edit" && panel.key === field.key;
1472
1482
  if (editing && field.type === "text") {
1473
- return /* @__PURE__ */ jsxs23(
1483
+ return /* @__PURE__ */ jsxs24(
1474
1484
  "span",
1475
1485
  {
1476
1486
  className: "fd-tag",
@@ -1516,8 +1526,8 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
1516
1526
  }
1517
1527
  if (editing && field.type === "select") {
1518
1528
  const chosen = field.options.find((o) => o.value === value);
1519
- return /* @__PURE__ */ jsxs23("span", { style: { position: "relative", display: "inline-flex" }, children: [
1520
- /* @__PURE__ */ jsxs23(Tag, { selected: true, onClick: () => setPanel(null), onRemove: () => {
1529
+ return /* @__PURE__ */ jsxs24("span", { style: { position: "relative", display: "inline-flex" }, children: [
1530
+ /* @__PURE__ */ jsxs24(Tag, { selected: true, onClick: () => setPanel(null), onRemove: () => {
1521
1531
  if (isSet(value)) onFilterRemove(field.key);
1522
1532
  setPanel(null);
1523
1533
  }, children: [
@@ -1555,7 +1565,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
1555
1565
  if (isSet(value)) {
1556
1566
  const chosen = field.type === "select" ? field.options.find((o) => o.value === value) : void 0;
1557
1567
  const display = chosen ? chosen.label : String(value);
1558
- return /* @__PURE__ */ jsxs23(Tag, { selected: true, onClick: () => startEditing(field.key), onRemove: () => onFilterRemove(field.key), children: [
1568
+ return /* @__PURE__ */ jsxs24(Tag, { selected: true, onClick: () => startEditing(field.key), onRemove: () => onFilterRemove(field.key), children: [
1559
1569
  field.label,
1560
1570
  ": ",
1561
1571
  display
@@ -1563,7 +1573,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
1563
1573
  }
1564
1574
  return null;
1565
1575
  }),
1566
- addableFields.length > 0 ? /* @__PURE__ */ jsxs23("span", { style: { position: "relative", display: "inline-flex" }, children: [
1576
+ addableFields.length > 0 ? /* @__PURE__ */ jsxs24("span", { style: { position: "relative", display: "inline-flex" }, children: [
1567
1577
  /* @__PURE__ */ jsx28(
1568
1578
  Button,
1569
1579
  {
@@ -1581,7 +1591,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
1581
1591
  {
1582
1592
  className: "fd-view-enter",
1583
1593
  style: { position: "absolute", top: "calc(100% + 6px)", [align]: 0, zIndex, width: 220, maxWidth: "calc(100vw - 32px)", display: "block", background: "var(--surface)", border: "1px solid var(--border)", borderRadius: 10, boxShadow: "0 16px 44px rgba(11,13,17,.18)", padding: 8 },
1584
- children: /* @__PURE__ */ jsxs23("span", { className: "fd-stack", role: "menu", "aria-label": "Add filter", style: { gap: 2 }, children: [
1594
+ children: /* @__PURE__ */ jsxs24("span", { className: "fd-stack", role: "menu", "aria-label": "Add filter", style: { gap: 2 }, children: [
1585
1595
  /* @__PURE__ */ jsx28("span", { className: "fd-overline fd-muted", style: { padding: "4px 8px 6px" }, children: "Add filter" }),
1586
1596
  addableFields.map((f) => /* @__PURE__ */ jsx28(
1587
1597
  "button",
@@ -1603,12 +1613,12 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
1603
1613
  }
1604
1614
 
1605
1615
  // src/components/data/StatTile.tsx
1606
- import { jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
1616
+ import { jsx as jsx29, jsxs as jsxs25 } from "react/jsx-runtime";
1607
1617
  function StatTile({ label, value, sub, delta, loading = false, compact: compact3 = false, className = "", ...rest }) {
1608
- return /* @__PURE__ */ jsxs24("div", { className: ["fd-stat", compact3 ? "fd-stat-compact" : "", className].filter(Boolean).join(" "), ...rest, children: [
1609
- loading ? /* @__PURE__ */ jsx29("span", { className: "fd-skel fd-skel-text", style: { display: "block", height: compact3 ? 20 : 28, width: "62%" } }) : /* @__PURE__ */ jsxs24("span", { className: "fd-stat-top", children: [
1618
+ return /* @__PURE__ */ jsxs25("div", { className: ["fd-stat", compact3 ? "fd-stat-compact" : "", className].filter(Boolean).join(" "), ...rest, children: [
1619
+ loading ? /* @__PURE__ */ jsx29("span", { className: "fd-skel fd-skel-text", style: { display: "block", height: compact3 ? 20 : 28, width: "62%" } }) : /* @__PURE__ */ jsxs25("span", { className: "fd-stat-top", children: [
1610
1620
  /* @__PURE__ */ jsx29("span", { className: "fd-stat-figure", children: value }),
1611
- delta ? /* @__PURE__ */ jsxs24("span", { className: delta.startsWith("-") ? "fd-stat-delta-down" : "fd-stat-delta-up", style: { fontWeight: 600, fontSize: "var(--body-sm-size)", flex: "none" }, children: [
1621
+ delta ? /* @__PURE__ */ jsxs25("span", { className: delta.startsWith("-") ? "fd-stat-delta-down" : "fd-stat-delta-up", style: { fontWeight: 600, fontSize: "var(--body-sm-size)", flex: "none" }, children: [
1612
1622
  /* @__PURE__ */ jsx29("i", { className: "ph ph-arrow-" + (delta.startsWith("-") ? "down" : "up") + "-right", "aria-hidden": "true" }),
1613
1623
  " ",
1614
1624
  delta
@@ -1620,8 +1630,8 @@ function StatTile({ label, value, sub, delta, loading = false, compact: compact3
1620
1630
  }
1621
1631
 
1622
1632
  // src/components/data/CodeBlock.tsx
1623
- import * as React9 from "react";
1624
- import { Fragment as Fragment5, jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
1633
+ import * as React10 from "react";
1634
+ import { Fragment as Fragment5, jsx as jsx30, jsxs as jsxs26 } from "react/jsx-runtime";
1625
1635
  var JS_KW = /^(?:const|let|var|function|return|if|else|for|while|do|new|class|extends|import|from|export|default|await|async|try|catch|finally|throw|typeof|instanceof|of|in|switch|case|break|continue|delete|void|yield|static|get|set|this|super|interface|type|enum|implements|public|private|protected|readonly|abstract|as|satisfies|declare|namespace)$/;
1626
1636
  var RULES = {
1627
1637
  js: [
@@ -1776,13 +1786,13 @@ function tokenize(src, lang) {
1776
1786
  return out;
1777
1787
  }
1778
1788
  function Highlighted({ code, lang }) {
1779
- const toks = React9.useMemo(() => tokenize(code, lang), [code, lang]);
1789
+ const toks = React10.useMemo(() => tokenize(code, lang), [code, lang]);
1780
1790
  return /* @__PURE__ */ jsx30(Fragment5, { children: toks.map((tk, i) => tk.c ? /* @__PURE__ */ jsx30("span", { className: "tok-" + tk.c, children: tk.t }, i) : tk.t) });
1781
1791
  }
1782
1792
  function useCopy() {
1783
- const [done, setDone] = React9.useState(false);
1784
- const timer = React9.useRef(null);
1785
- React9.useEffect(() => () => {
1793
+ const [done, setDone] = React10.useState(false);
1794
+ const timer = React10.useRef(null);
1795
+ React10.useEffect(() => () => {
1786
1796
  if (timer.current) clearTimeout(timer.current);
1787
1797
  }, []);
1788
1798
  const copy = (text) => {
@@ -1818,37 +1828,37 @@ function CodeBlock({
1818
1828
  actions,
1819
1829
  className = ""
1820
1830
  }) {
1821
- const [wrap, setWrap] = React9.useState(!!wrapDefault);
1822
- const [open, setOpen] = React9.useState(false);
1831
+ const [wrap, setWrap] = React10.useState(!!wrapDefault);
1832
+ const [open, setOpen] = React10.useState(false);
1823
1833
  const [copied, copy] = useCopy();
1824
1834
  const body = String(code).replace(/\n$/, "");
1825
1835
  const lines = body.split("\n");
1826
1836
  const foldable = collapseAfter > 0 && lines.length > collapseAfter + 6;
1827
1837
  const shown = foldable && !open ? lines.slice(0, collapseAfter).join("\n") : body;
1828
- return /* @__PURE__ */ jsxs25("div", { className: ["fd-code", wrap ? "is-wrap" : "", className].filter(Boolean).join(" "), children: [
1829
- /* @__PURE__ */ jsxs25("div", { className: "fd-code-head", children: [
1838
+ return /* @__PURE__ */ jsxs26("div", { className: ["fd-code", wrap ? "is-wrap" : "", className].filter(Boolean).join(" "), children: [
1839
+ /* @__PURE__ */ jsxs26("div", { className: "fd-code-head", children: [
1830
1840
  filename ? /* @__PURE__ */ jsx30("span", { className: "fd-code-file", children: filename }) : null,
1831
1841
  /* @__PURE__ */ jsx30("span", { className: "fd-code-lang", children: languageLabel(language) }),
1832
1842
  /* @__PURE__ */ jsx30("span", { className: "fd-code-spacer" }),
1833
1843
  actions,
1834
1844
  /* @__PURE__ */ jsx30("button", { type: "button", className: "fd-code-act", onClick: () => setWrap((v) => !v), "aria-pressed": wrap, title: wrap ? "No wrap" : "Soft wrap", children: /* @__PURE__ */ jsx30("i", { className: "ph ph-text-" + (wrap ? "columns" : "align-left"), "aria-hidden": "true" }) }),
1835
- copyable ? /* @__PURE__ */ jsxs25("button", { type: "button", className: "fd-code-act" + (copied ? " is-done" : ""), onClick: () => copy(body), children: [
1845
+ copyable ? /* @__PURE__ */ jsxs26("button", { type: "button", className: "fd-code-act" + (copied ? " is-done" : ""), onClick: () => copy(body), children: [
1836
1846
  /* @__PURE__ */ jsx30("i", { className: "ph ph-" + (copied ? "check" : "copy"), "aria-hidden": "true" }),
1837
1847
  /* @__PURE__ */ jsx30("span", { children: copied ? "Copied" : "Copy" })
1838
1848
  ] }) : null
1839
1849
  ] }),
1840
- /* @__PURE__ */ jsxs25("div", { className: "fd-code-body", children: [
1850
+ /* @__PURE__ */ jsxs26("div", { className: "fd-code-body", children: [
1841
1851
  lineNumbers ? /* @__PURE__ */ jsx30("pre", { className: "fd-code-gutter", "aria-hidden": "true", children: shown.split("\n").map((_, i) => i + 1 + "\n").join("") }) : null,
1842
1852
  /* @__PURE__ */ jsx30("pre", { className: "fd-code-pre", tabIndex: 0, children: /* @__PURE__ */ jsx30("code", { children: /* @__PURE__ */ jsx30(Highlighted, { code: shown, lang: language }) }) })
1843
1853
  ] }),
1844
- foldable ? /* @__PURE__ */ jsxs25("button", { type: "button", className: "fd-code-fold", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
1854
+ foldable ? /* @__PURE__ */ jsxs26("button", { type: "button", className: "fd-code-fold", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
1845
1855
  /* @__PURE__ */ jsx30("i", { className: "ph ph-caret-" + (open ? "up" : "down"), "aria-hidden": "true" }),
1846
1856
  open ? "Collapse" : "Show all " + lines.length + " lines"
1847
1857
  ] }) : null
1848
1858
  ] });
1849
1859
  }
1850
1860
  function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" }) {
1851
- const [open, setOpen] = React9.useState(false);
1861
+ const [open, setOpen] = React10.useState(false);
1852
1862
  const [copied, copy] = useCopy();
1853
1863
  const raw = String(diff).replace(/\n$/, "");
1854
1864
  const all = raw.split("\n").map((line) => {
@@ -1862,31 +1872,31 @@ function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" })
1862
1872
  const dels = all.filter((l) => l.k === "del").length;
1863
1873
  const foldable = collapseAfter > 0 && all.length > collapseAfter + 6;
1864
1874
  const rows = foldable && !open ? all.slice(0, collapseAfter) : all;
1865
- return /* @__PURE__ */ jsxs25("div", { className: ["fd-code", "fd-diff", className].filter(Boolean).join(" "), children: [
1866
- /* @__PURE__ */ jsxs25("div", { className: "fd-code-head", children: [
1875
+ return /* @__PURE__ */ jsxs26("div", { className: ["fd-code", "fd-diff", className].filter(Boolean).join(" "), children: [
1876
+ /* @__PURE__ */ jsxs26("div", { className: "fd-code-head", children: [
1867
1877
  /* @__PURE__ */ jsx30("i", { className: "ph ph-git-diff fd-code-icon", "aria-hidden": "true" }),
1868
1878
  filename ? /* @__PURE__ */ jsx30("span", { className: "fd-code-file", children: filename }) : /* @__PURE__ */ jsx30("span", { className: "fd-code-lang", children: "Diff" }),
1869
- /* @__PURE__ */ jsxs25("span", { className: "fd-diff-stat fd-tabular", children: [
1870
- /* @__PURE__ */ jsxs25("span", { className: "is-add", children: [
1879
+ /* @__PURE__ */ jsxs26("span", { className: "fd-diff-stat fd-tabular", children: [
1880
+ /* @__PURE__ */ jsxs26("span", { className: "is-add", children: [
1871
1881
  "+",
1872
1882
  adds
1873
1883
  ] }),
1874
- /* @__PURE__ */ jsxs25("span", { className: "is-del", children: [
1884
+ /* @__PURE__ */ jsxs26("span", { className: "is-del", children: [
1875
1885
  "\u2212",
1876
1886
  dels
1877
1887
  ] })
1878
1888
  ] }),
1879
1889
  /* @__PURE__ */ jsx30("span", { className: "fd-code-spacer" }),
1880
- /* @__PURE__ */ jsxs25("button", { type: "button", className: "fd-code-act" + (copied ? " is-done" : ""), onClick: () => copy(raw), children: [
1890
+ /* @__PURE__ */ jsxs26("button", { type: "button", className: "fd-code-act" + (copied ? " is-done" : ""), onClick: () => copy(raw), children: [
1881
1891
  /* @__PURE__ */ jsx30("i", { className: "ph ph-" + (copied ? "check" : "copy"), "aria-hidden": "true" }),
1882
1892
  /* @__PURE__ */ jsx30("span", { children: copied ? "Copied" : "Copy" })
1883
1893
  ] })
1884
1894
  ] }),
1885
- /* @__PURE__ */ jsx30("div", { className: "fd-diff-body", children: rows.map((r, i) => /* @__PURE__ */ jsxs25("div", { className: "fd-diff-line is-" + r.k, children: [
1895
+ /* @__PURE__ */ jsx30("div", { className: "fd-diff-body", children: rows.map((r, i) => /* @__PURE__ */ jsxs26("div", { className: "fd-diff-line is-" + r.k, children: [
1886
1896
  /* @__PURE__ */ jsx30("span", { className: "fd-diff-mark", "aria-hidden": "true", children: r.k === "add" ? "+" : r.k === "del" ? "\u2212" : "" }),
1887
1897
  /* @__PURE__ */ jsx30("code", { children: r.k === "add" || r.k === "del" ? r.line.slice(1) : r.line })
1888
1898
  ] }, i)) }),
1889
- foldable ? /* @__PURE__ */ jsxs25("button", { type: "button", className: "fd-code-fold", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
1899
+ foldable ? /* @__PURE__ */ jsxs26("button", { type: "button", className: "fd-code-fold", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
1890
1900
  /* @__PURE__ */ jsx30("i", { className: "ph ph-caret-" + (open ? "up" : "down"), "aria-hidden": "true" }),
1891
1901
  open ? "Collapse" : "Show all " + all.length + " lines"
1892
1902
  ] }) : null
@@ -1894,8 +1904,8 @@ function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" })
1894
1904
  }
1895
1905
 
1896
1906
  // src/components/data/Markdown.tsx
1897
- import * as React10 from "react";
1898
- import { jsx as jsx31, jsxs as jsxs26 } from "react/jsx-runtime";
1907
+ import * as React11 from "react";
1908
+ import { jsx as jsx31, jsxs as jsxs27 } from "react/jsx-runtime";
1899
1909
  var SAFE = /^(?:https?:|mailto:|tel:|#|\/|\.{1,2}\/)/i;
1900
1910
  var safeHref = (h) => SAFE.test(String(h || "").trim()) ? String(h).trim() : null;
1901
1911
  var INLINE = [
@@ -1933,7 +1943,7 @@ function inlineNodes(src, ctx, keyBase) {
1933
1943
  const href = safeHref(g(2));
1934
1944
  out.push(href ? /* @__PURE__ */ jsx31("a", { href, title: g(3) || void 0, target: /^https?:/i.test(href) ? "_blank" : void 0, rel: "noopener noreferrer", onClick: ctx.onLinkClick, children: inlineNodes(g(1), ctx, key()) }, key()) : /* @__PURE__ */ jsx31("span", { children: g(1) }, key()));
1935
1945
  } else if (kind === "cite") {
1936
- out.push(ctx.renderCitation ? /* @__PURE__ */ jsx31(React10.Fragment, { children: ctx.renderCitation(g(1)) }, key()) : /* @__PURE__ */ jsx31("sup", { className: "fd-md-cite", children: g(1) }, key()));
1946
+ out.push(ctx.renderCitation ? /* @__PURE__ */ jsx31(React11.Fragment, { children: ctx.renderCitation(g(1)) }, key()) : /* @__PURE__ */ jsx31("sup", { className: "fd-md-cite", children: g(1) }, key()));
1937
1947
  } else if (kind === "strongem") out.push(/* @__PURE__ */ jsx31("strong", { children: /* @__PURE__ */ jsx31("em", { children: inlineNodes(g(1), ctx, key()) }) }, key()));
1938
1948
  else if (kind === "strong") out.push(/* @__PURE__ */ jsx31("strong", { children: inlineNodes(g(1) || g(2), ctx, key()) }, key()));
1939
1949
  else if (kind === "em") out.push(/* @__PURE__ */ jsx31("em", { children: inlineNodes(g(1) || g(2), ctx, key()) }, key()));
@@ -2073,13 +2083,13 @@ function renderBlocks(blocks, ctx, path) {
2073
2083
  case "list": {
2074
2084
  const Tag2 = b.ordered ? "ol" : "ul";
2075
2085
  const isTask = b.items.some((it) => it.checked != null);
2076
- return /* @__PURE__ */ jsx31(Tag2, { className: "fd-md-list" + (isTask ? " is-task" : ""), start: b.ordered && b.start !== 1 ? b.start : void 0, children: b.items.map((it, j) => /* @__PURE__ */ jsxs26("li", { className: it.checked != null ? it.checked ? "is-done" : "is-todo" : void 0, children: [
2086
+ return /* @__PURE__ */ jsx31(Tag2, { className: "fd-md-list" + (isTask ? " is-task" : ""), start: b.ordered && b.start !== 1 ? b.start : void 0, children: b.items.map((it, j) => /* @__PURE__ */ jsxs27("li", { className: it.checked != null ? it.checked ? "is-done" : "is-todo" : void 0, children: [
2077
2087
  it.checked != null ? /* @__PURE__ */ jsx31("span", { className: "fd-md-task", "aria-hidden": "true", children: /* @__PURE__ */ jsx31("i", { className: "ph ph-" + (it.checked ? "check-square" : "square") }) }) : null,
2078
2088
  /* @__PURE__ */ jsx31("span", { className: "fd-md-li", children: renderBlocks(it.children, ctx, k + "-" + j) })
2079
2089
  ] }, k + "-" + j)) }, k);
2080
2090
  }
2081
2091
  case "table":
2082
- return /* @__PURE__ */ jsx31("div", { className: "fd-md-tablewrap", children: /* @__PURE__ */ jsxs26("table", { className: "fd-md-table", children: [
2092
+ return /* @__PURE__ */ jsx31("div", { className: "fd-md-tablewrap", children: /* @__PURE__ */ jsxs27("table", { className: "fd-md-table", children: [
2083
2093
  /* @__PURE__ */ jsx31("thead", { children: /* @__PURE__ */ jsx31("tr", { children: b.head.map((c, j) => /* @__PURE__ */ jsx31("th", { style: { textAlign: b.align[j] || "left" }, children: inlineNodes(c, ctx, k + "h" + j) }, j)) }) }),
2084
2094
  /* @__PURE__ */ jsx31("tbody", { children: b.rows.map((r, ri) => /* @__PURE__ */ jsx31("tr", { children: b.head.map((_, ci) => /* @__PURE__ */ jsx31("td", { style: { textAlign: b.align[ci] || "left" }, children: inlineNodes(r[ci] || "", ctx, k + ri + "c" + ci) }, ci)) }, ri)) })
2085
2095
  ] }) }, k);
@@ -2098,7 +2108,7 @@ function Markdown({
2098
2108
  onLinkClick
2099
2109
  }) {
2100
2110
  const ctx = { allowImages, headingOffset, renderCitation, onLinkClick, codeProps };
2101
- const blocks = React10.useMemo(() => parseBlocks(source), [source]);
2111
+ const blocks = React11.useMemo(() => parseBlocks(source), [source]);
2102
2112
  return /* @__PURE__ */ jsx31("div", { className: ["fd-md", className].filter(Boolean).join(" "), children: renderBlocks(blocks, ctx, "b") });
2103
2113
  }
2104
2114
  function MarkdownInline({ source = "", className = "", onLinkClick }) {
@@ -2109,13 +2119,13 @@ function markdownToText(src) {
2109
2119
  }
2110
2120
 
2111
2121
  // src/components/data/Meter.tsx
2112
- import { jsx as jsx32, jsxs as jsxs27 } from "react/jsx-runtime";
2122
+ import { jsx as jsx32, jsxs as jsxs28 } from "react/jsx-runtime";
2113
2123
  function Meter({ segments = [], unallocated = 0, height = 8, label, legend = false, className = "" }) {
2114
2124
  const total = segments.reduce((s, x) => s + x.value, 0) + unallocated;
2115
2125
  const pct = (v) => total ? v / total * 100 : 0;
2116
- return /* @__PURE__ */ jsxs27("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 8 }, children: [
2126
+ return /* @__PURE__ */ jsxs28("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 8 }, children: [
2117
2127
  label ? /* @__PURE__ */ jsx32("span", { className: "fd-label-lg fd-secondary", children: label }) : null,
2118
- /* @__PURE__ */ jsxs27("div", { className: "fd-meterbar", style: { height }, children: [
2128
+ /* @__PURE__ */ jsxs28("div", { className: "fd-meterbar", style: { height }, children: [
2119
2129
  segments.map((s, i) => /* @__PURE__ */ jsx32(
2120
2130
  "span",
2121
2131
  {
@@ -2127,12 +2137,12 @@ function Meter({ segments = [], unallocated = 0, height = 8, label, legend = fal
2127
2137
  )),
2128
2138
  unallocated > 0 ? /* @__PURE__ */ jsx32("span", { className: "fd-meterbar-seg fd-meterbar-unallocated", title: "Unallocated", style: { width: pct(unallocated) + "%" } }) : null
2129
2139
  ] }),
2130
- legend ? /* @__PURE__ */ jsxs27("div", { className: "fd-row", style: { gap: 16, flexWrap: "wrap" }, children: [
2131
- segments.map((s, i) => /* @__PURE__ */ jsxs27("span", { className: "fd-row fd-body-sm fd-secondary", style: { gap: 7 }, children: [
2140
+ legend ? /* @__PURE__ */ jsxs28("div", { className: "fd-row", style: { gap: 16, flexWrap: "wrap" }, children: [
2141
+ segments.map((s, i) => /* @__PURE__ */ jsxs28("span", { className: "fd-row fd-body-sm fd-secondary", style: { gap: 7 }, children: [
2132
2142
  /* @__PURE__ */ jsx32("span", { style: { width: 9, height: 9, borderRadius: 2, background: s.color || "var(--chart-" + (i % 8 + 1) + ")" } }),
2133
2143
  s.label
2134
2144
  ] }, i)),
2135
- unallocated > 0 ? /* @__PURE__ */ jsxs27("span", { className: "fd-row fd-body-sm fd-secondary", style: { gap: 7 }, children: [
2145
+ unallocated > 0 ? /* @__PURE__ */ jsxs28("span", { className: "fd-row fd-body-sm fd-secondary", style: { gap: 7 }, children: [
2136
2146
  /* @__PURE__ */ jsx32("span", { className: "fd-meterbar-unallocated", style: { width: 9, height: 9, borderRadius: 2 } }),
2137
2147
  "Unallocated"
2138
2148
  ] }) : null
@@ -2141,7 +2151,7 @@ function Meter({ segments = [], unallocated = 0, height = 8, label, legend = fal
2141
2151
  }
2142
2152
 
2143
2153
  // src/components/data/Pagination.tsx
2144
- import { Fragment as Fragment7, jsx as jsx33, jsxs as jsxs28 } from "react/jsx-runtime";
2154
+ import { Fragment as Fragment7, jsx as jsx33, jsxs as jsxs29 } from "react/jsx-runtime";
2145
2155
  function Pagination({
2146
2156
  page = 1,
2147
2157
  pageSize = 25,
@@ -2166,12 +2176,12 @@ function Pagination({
2166
2176
  if (i === 1 || i === totalPages || Math.abs(i - page) <= span) nums.push(i);
2167
2177
  else if (nums[nums.length - 1] !== "\u2026") nums.push("\u2026");
2168
2178
  }
2169
- return /* @__PURE__ */ jsxs28("div", { className: ["fd-pag", className].filter(Boolean).join(" "), ...rest, children: [
2170
- /* @__PURE__ */ jsx33("span", { className: "fd-pag-count", children: loading ? /* @__PURE__ */ jsx33("span", { className: "fd-skel fd-skel-text", style: { display: "inline-block", height: 12, width: 108 } }) : total === 0 ? /* @__PURE__ */ jsxs28(Fragment7, { children: [
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: [
2171
2181
  "No ",
2172
2182
  unit
2173
- ] }) : /* @__PURE__ */ jsxs28(Fragment7, { children: [
2174
- /* @__PURE__ */ jsxs28("strong", { children: [
2183
+ ] }) : /* @__PURE__ */ jsxs29(Fragment7, { children: [
2184
+ /* @__PURE__ */ jsxs29("strong", { children: [
2175
2185
  from.toLocaleString(),
2176
2186
  "\u2013",
2177
2187
  to.toLocaleString()
@@ -2181,11 +2191,11 @@ function Pagination({
2181
2191
  " ",
2182
2192
  unit
2183
2193
  ] }) }),
2184
- onPageSizeChange ? /* @__PURE__ */ jsxs28("label", { className: "fd-pag-size", children: [
2194
+ onPageSizeChange ? /* @__PURE__ */ jsxs29("label", { className: "fd-pag-size", children: [
2185
2195
  /* @__PURE__ */ jsx33("span", { children: "Rows" }),
2186
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)) })
2187
2197
  ] }) : null,
2188
- /* @__PURE__ */ jsxs28("span", { className: "fd-pag-nav", children: [
2198
+ /* @__PURE__ */ jsxs29("span", { className: "fd-pag-nav", children: [
2189
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" }) }),
2190
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" }) }),
2191
2201
  nums.map((n, i) => n === "\u2026" ? /* @__PURE__ */ jsx33("span", { className: "fd-pag-gap", "aria-hidden": "true", children: "\u2026" }, "e" + i) : /* @__PURE__ */ jsx33(
@@ -2206,8 +2216,8 @@ function Pagination({
2206
2216
  }
2207
2217
 
2208
2218
  // src/components/data/RelativeTime.tsx
2209
- import * as React11 from "react";
2210
- import { jsxs as jsxs29 } from "react/jsx-runtime";
2219
+ import * as React12 from "react";
2220
+ import { jsxs as jsxs30 } from "react/jsx-runtime";
2211
2221
  var MIN = 6e4;
2212
2222
  var HOUR = 36e5;
2213
2223
  var DAY = 864e5;
@@ -2258,9 +2268,9 @@ function formatDuration(ms) {
2258
2268
  return h + "h" + (m % 60 ? " " + m % 60 + "m" : "");
2259
2269
  }
2260
2270
  function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true, ...rest }) {
2261
- const [, force] = React11.useState(0);
2271
+ const [, force] = React12.useState(0);
2262
2272
  const t = value instanceof Date ? value.getTime() : Date.parse(value);
2263
- React11.useEffect(() => {
2273
+ React12.useEffect(() => {
2264
2274
  if (!refresh2 || !t || isNaN(t)) return;
2265
2275
  const abs = Math.abs(t - Date.now());
2266
2276
  if (abs > DAY) return;
@@ -2269,17 +2279,17 @@ function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true,
2269
2279
  return () => clearInterval(id);
2270
2280
  }, [t, refresh2]);
2271
2281
  if (!t || isNaN(t)) return null;
2272
- 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: [
2273
2283
  prefix ? prefix + " " : "",
2274
2284
  formatRelative(new Date(t))
2275
2285
  ] });
2276
2286
  }
2277
2287
 
2278
2288
  // src/components/data/ScoreMeter.tsx
2279
- import * as React13 from "react";
2289
+ import * as React14 from "react";
2280
2290
 
2281
2291
  // src/components/data/SegmentedMeter.tsx
2282
- import * as React12 from "react";
2292
+ import * as React13 from "react";
2283
2293
 
2284
2294
  // src/kits/files.ts
2285
2295
  function formatBytes(n) {
@@ -2439,7 +2449,7 @@ var FileKit = {
2439
2449
  };
2440
2450
 
2441
2451
  // src/components/data/SegmentedMeter.tsx
2442
- import { jsx as jsx34, jsxs as jsxs30 } from "react/jsx-runtime";
2452
+ import { jsx as jsx34, jsxs as jsxs31 } from "react/jsx-runtime";
2443
2453
  var VARIANT_FILL = {
2444
2454
  brand: "var(--brand)",
2445
2455
  neutral: "var(--n-400)",
@@ -2484,16 +2494,16 @@ function SegmentedMeter({
2484
2494
  const pct = safeTotal ? Math.min(100, Math.round(used / safeTotal * 100)) : 0;
2485
2495
  const w = (v) => safeTotal ? Math.max(0, Math.min(100, Number(v) / safeTotal * 100)) : 0;
2486
2496
  const fill = (s, i) => s.color || (s.variant ? VARIANT_FILL[s.variant] : void 0) || CHART[i % CHART.length];
2487
- const generatedId = React12.useId();
2497
+ const generatedId = React13.useId();
2488
2498
  const uid2 = id || generatedId;
2489
- return /* @__PURE__ */ jsxs30("div", { className: ["fd-segmeter", className].filter(Boolean).join(" "), onClick, children: [
2490
- label || showTotal ? /* @__PURE__ */ jsxs30("div", { className: "fd-segmeter-head", children: [
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: [
2491
2501
  label ? /* @__PURE__ */ jsx34("span", { className: "fd-segmeter-label", id: uid2 + "-l", children: label }) : /* @__PURE__ */ jsx34("span", {}),
2492
- showTotal ? /* @__PURE__ */ jsxs30("span", { className: "fd-segmeter-total fd-tabular", children: [
2502
+ showTotal ? /* @__PURE__ */ jsxs31("span", { className: "fd-segmeter-total fd-tabular", children: [
2493
2503
  format(used),
2494
2504
  /* @__PURE__ */ jsx34("span", { className: "fd-segmeter-sep", children: " / " }),
2495
2505
  safeTotal ? format(safeTotal) : "\u2014",
2496
- showPercent ? /* @__PURE__ */ jsxs30("span", { className: "fd-segmeter-pct", children: [
2506
+ showPercent ? /* @__PURE__ */ jsxs31("span", { className: "fd-segmeter-pct", children: [
2497
2507
  " (",
2498
2508
  pct,
2499
2509
  "%)"
@@ -2523,13 +2533,13 @@ function SegmentedMeter({
2523
2533
  ))
2524
2534
  }
2525
2535
  ),
2526
- legend ? /* @__PURE__ */ jsxs30("ul", { className: "fd-segmeter-legend", children: [
2527
- 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: [
2528
2538
  /* @__PURE__ */ jsx34("span", { className: "fd-segmeter-dot", style: { background: fill(s, i) }, "aria-hidden": "true" }),
2529
2539
  /* @__PURE__ */ jsx34("span", { className: "fd-segmeter-key", children: s.label }),
2530
2540
  /* @__PURE__ */ jsx34("span", { className: "fd-segmeter-val fd-tabular", children: format(s.value) })
2531
2541
  ] }, s.id || s.label || i)),
2532
- safeTotal && used < safeTotal ? /* @__PURE__ */ jsxs30("li", { className: "is-remainder", children: [
2542
+ safeTotal && used < safeTotal ? /* @__PURE__ */ jsxs31("li", { className: "is-remainder", children: [
2533
2543
  /* @__PURE__ */ jsx34("span", { className: "fd-segmeter-dot is-empty", "aria-hidden": "true" }),
2534
2544
  /* @__PURE__ */ jsx34("span", { className: "fd-segmeter-key", children: remainderLabel }),
2535
2545
  /* @__PURE__ */ jsx34("span", { className: "fd-segmeter-val fd-tabular", children: format(safeTotal - used) })
@@ -2540,11 +2550,11 @@ function SegmentedMeter({
2540
2550
  function QuotaRow({ label, percent = 0, note, tone, className = "" }) {
2541
2551
  const p = Math.max(0, Math.min(100, Math.round(Number(percent) || 0)));
2542
2552
  const auto = p >= 90 ? "danger" : p >= 70 ? "warn" : "brand";
2543
- return /* @__PURE__ */ jsxs30("div", { className: ["fd-quota", className].filter(Boolean).join(" "), children: [
2544
- /* @__PURE__ */ jsxs30("div", { className: "fd-quota-head", children: [
2553
+ return /* @__PURE__ */ jsxs31("div", { className: ["fd-quota", className].filter(Boolean).join(" "), children: [
2554
+ /* @__PURE__ */ jsxs31("div", { className: "fd-quota-head", children: [
2545
2555
  /* @__PURE__ */ jsx34("span", { className: "fd-quota-label", children: label }),
2546
2556
  note ? /* @__PURE__ */ jsx34("span", { className: "fd-quota-note", children: note }) : null,
2547
- /* @__PURE__ */ jsxs30("span", { className: "fd-quota-pct fd-tabular", children: [
2557
+ /* @__PURE__ */ jsxs31("span", { className: "fd-quota-pct fd-tabular", children: [
2548
2558
  p,
2549
2559
  "%"
2550
2560
  ] })
@@ -2554,7 +2564,7 @@ function QuotaRow({ label, percent = 0, note, tone, className = "" }) {
2554
2564
  }
2555
2565
 
2556
2566
  // src/components/data/ScoreMeter.tsx
2557
- import { jsx as jsx35, jsxs as jsxs31 } from "react/jsx-runtime";
2567
+ import { jsx as jsx35, jsxs as jsxs32 } from "react/jsx-runtime";
2558
2568
  function ScoreMeter({
2559
2569
  score,
2560
2570
  segments,
@@ -2568,10 +2578,10 @@ function ScoreMeter({
2568
2578
  breakdownWidth = 280,
2569
2579
  className = ""
2570
2580
  }) {
2571
- const [open, setOpen] = React13.useState(false);
2572
- const ref = React13.useRef(null);
2581
+ const [open, setOpen] = React14.useState(false);
2582
+ const ref = React14.useRef(null);
2573
2583
  const value = Math.max(0, Math.min(100, Math.round(Number(score) || 0)));
2574
- const body = /* @__PURE__ */ jsxs31(React13.Fragment, { children: [
2584
+ const body = /* @__PURE__ */ jsxs32(React14.Fragment, { children: [
2575
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 }) }),
2576
2586
  showScore ? /* @__PURE__ */ jsx35("span", { className: "fd-scoremeter-value fd-tabular", "aria-hidden": "true", children: value }) : null
2577
2587
  ] });
@@ -2590,7 +2600,7 @@ function ScoreMeter({
2590
2600
  }
2591
2601
  );
2592
2602
  }
2593
- return /* @__PURE__ */ jsxs31(React13.Fragment, { children: [
2603
+ return /* @__PURE__ */ jsxs32(React14.Fragment, { children: [
2594
2604
  /* @__PURE__ */ jsx35(
2595
2605
  "button",
2596
2606
  {
@@ -2621,14 +2631,14 @@ function ScoreMeter({
2621
2631
  }
2622
2632
 
2623
2633
  // src/components/data/SortMenu.tsx
2624
- import * as React14 from "react";
2625
- 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";
2626
2636
  var SORT_MENU_BASE = 120;
2627
2637
  function SortMenu({ fields = [], sort, onSort, align = "right", size = "md", className = "", ...rest }) {
2628
- const [open, setOpen] = React14.useState(false);
2638
+ const [open, setOpen] = React15.useState(false);
2629
2639
  const zIndex = useOverlayLayer(SORT_MENU_BASE);
2630
- const ref = React14.useRef(null);
2631
- React14.useEffect(() => {
2640
+ const ref = React15.useRef(null);
2641
+ React15.useEffect(() => {
2632
2642
  if (!open) return;
2633
2643
  const away = (e) => {
2634
2644
  if (ref.current && !ref.current.contains(e.target)) setOpen(false);
@@ -2670,16 +2680,16 @@ function SortMenu({ fields = [], sort, onSort, align = "right", size = "md", cla
2670
2680
  }
2671
2681
  );
2672
2682
  };
2673
- return /* @__PURE__ */ jsxs32("span", { className, style: { position: "relative", display: "inline-flex" }, ref, ...rest, children: [
2674
- /* @__PURE__ */ jsxs32(Button, { size, variant: "secondary", icon: dir === "asc" ? "sort-ascending" : "sort-descending", onClick: () => setOpen(!open), children: [
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: [
2675
2685
  cur ? cur.label : "Unsorted",
2676
2686
  /* @__PURE__ */ jsx36("i", { className: "ph ph-" + (dir === "asc" ? "arrow-up" : "arrow-down"), style: { fontSize: 12, marginLeft: 6, opacity: 0.75 } })
2677
2687
  ] }),
2678
- open ? /* @__PURE__ */ jsx36(LayerProvider, { zIndex, children: /* @__PURE__ */ jsx36("span", { className: "fd-view-enter", style: { position: "absolute", top: "calc(100% + 6px)", [align]: 0, zIndex, width: 280, maxWidth: "calc(100vw - 32px)", display: "block", background: "var(--surface)", border: "1px solid var(--border)", borderRadius: 10, boxShadow: "0 16px 44px rgba(11,13,17,.18)", padding: 8 }, children: /* @__PURE__ */ jsxs32("span", { className: "fd-stack", style: { gap: 2 }, children: [
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: [
2679
2689
  /* @__PURE__ */ jsx36("span", { className: "fd-overline fd-muted", style: { padding: "4px 8px 6px" }, children: "Sort by" }),
2680
2690
  fields.map((f) => {
2681
2691
  const active = cur && cur.key === f.key;
2682
- return /* @__PURE__ */ jsxs32("span", { className: "fd-row", style: { gap: 8, padding: "4px 8px", borderRadius: 7, background: active ? "var(--surface-brand)" : "transparent" }, children: [
2692
+ return /* @__PURE__ */ jsxs33("span", { className: "fd-row", style: { gap: 8, padding: "4px 8px", borderRadius: 7, background: active ? "var(--surface-brand)" : "transparent" }, children: [
2683
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 }),
2684
2694
  arrow(f, "asc"),
2685
2695
  arrow(f, "desc")
@@ -2690,8 +2700,8 @@ function SortMenu({ fields = [], sort, onSort, align = "right", size = "md", cla
2690
2700
  }
2691
2701
 
2692
2702
  // src/components/data/StepList.tsx
2693
- import * as React15 from "react";
2694
- 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";
2695
2705
  var KIND_ICON = { tool: "wrench", search: "magnifying-glass", read: "file-text", write: "pencil-simple", reasoning: "brain", run: "terminal", fetch: "cloud-arrow-down" };
2696
2706
  function StepList({
2697
2707
  steps = [],
@@ -2703,9 +2713,9 @@ function StepList({
2703
2713
  dense = false,
2704
2714
  className = ""
2705
2715
  }) {
2706
- const [openState, setOpenState] = React15.useState(defaultOpen);
2716
+ const [openState, setOpenState] = React16.useState(defaultOpen);
2707
2717
  const open = openProp == null ? openState : openProp;
2708
- const [expanded, setExpanded] = React15.useState({});
2718
+ const [expanded, setExpanded] = React16.useState({});
2709
2719
  if (!steps.length) return null;
2710
2720
  const running = steps.some((s) => s.status === "running");
2711
2721
  const failed = steps.filter((s) => s.status === "error").length;
@@ -2717,15 +2727,15 @@ function StepList({
2717
2727
  if (openProp == null) setOpenState(next);
2718
2728
  onToggle && onToggle(next);
2719
2729
  };
2720
- return /* @__PURE__ */ jsxs33("div", { className: ["fd-steps", dense ? "is-dense" : "", open ? "is-open" : "", className].filter(Boolean).join(" "), children: [
2721
- /* @__PURE__ */ jsxs33("button", { type: "button", className: "fd-steps-head", onClick: toggle, "aria-expanded": open, children: [
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: [
2722
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" }),
2723
2733
  /* @__PURE__ */ jsx37("span", { className: "fd-steps-title", children: summary }),
2724
- /* @__PURE__ */ jsxs33("span", { className: "fd-steps-count fd-tabular", children: [
2734
+ /* @__PURE__ */ jsxs34("span", { className: "fd-steps-count fd-tabular", children: [
2725
2735
  steps.length,
2726
2736
  " step",
2727
2737
  steps.length === 1 ? "" : "s",
2728
- failed ? /* @__PURE__ */ jsxs33("span", { className: "fd-steps-failed", children: [
2738
+ failed ? /* @__PURE__ */ jsxs34("span", { className: "fd-steps-failed", children: [
2729
2739
  " \xB7 ",
2730
2740
  failed,
2731
2741
  " failed"
@@ -2737,10 +2747,10 @@ function StepList({
2737
2747
  const id = s.id || i;
2738
2748
  const isOpen = !!expanded[id];
2739
2749
  const icon = KIND_ICON[s.kind || ""] || "dot-outline";
2740
- return /* @__PURE__ */ jsxs33("li", { className: "fd-step is-" + (s.status || "ok"), children: [
2741
- /* @__PURE__ */ jsxs33("div", { className: "fd-step-row", children: [
2750
+ return /* @__PURE__ */ jsxs34("li", { className: "fd-step is-" + (s.status || "ok"), children: [
2751
+ /* @__PURE__ */ jsxs34("div", { className: "fd-step-row", children: [
2742
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 }) }),
2743
- s.detail ? /* @__PURE__ */ jsxs33(
2753
+ s.detail ? /* @__PURE__ */ jsxs34(
2744
2754
  "button",
2745
2755
  {
2746
2756
  type: "button",
@@ -2763,8 +2773,8 @@ function StepList({
2763
2773
  }
2764
2774
 
2765
2775
  // src/components/data/VirtualList.tsx
2766
- import * as React16 from "react";
2767
- 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";
2768
2778
  var VIRTUAL_LIST_BUFFER_ROWS = 20;
2769
2779
  var VIRTUAL_LIST_ROW_GAP = 6;
2770
2780
  function computeVirtualWindow(opts) {
@@ -2815,35 +2825,35 @@ function VirtualList({
2815
2825
  className = "",
2816
2826
  style
2817
2827
  }) {
2818
- const [scrollTop, setScrollTop] = React16.useState(0);
2819
- const loaded = React16.useMemo(
2828
+ const [scrollTop, setScrollTop] = React17.useState(0);
2829
+ const loaded = React17.useMemo(
2820
2830
  () => ({ firstItemIndex, count: items.length }),
2821
2831
  [firstItemIndex, items.length]
2822
2832
  );
2823
2833
  const total = Math.max(totalCount == null ? 0 : totalCount, firstItemIndex + items.length);
2824
2834
  const bandKey = firstItemIndex + ":" + items.length;
2825
- const win = React16.useMemo(
2835
+ const win = React17.useMemo(
2826
2836
  () => computeVirtualWindow({ scrollTop, viewportHeight: height, itemHeight, itemCount: total, loaded }),
2827
2837
  [scrollTop, height, itemHeight, total, loaded]
2828
2838
  );
2829
- const need = React16.useMemo(() => computeNeedMore(win, loaded), [win, loaded]);
2839
+ const need = React17.useMemo(() => computeNeedMore(win, loaded), [win, loaded]);
2830
2840
  const wantStart = need.start && hasMore?.start !== false;
2831
2841
  const wantEnd = need.end && hasMore?.end !== false;
2832
2842
  const bucket2 = Math.floor(win.visibleStart / VIRTUAL_LIST_BUFFER_ROWS);
2833
2843
  const askKey = bandKey + "@" + bucket2;
2834
- const asked = React16.useRef({ start: null, end: null });
2835
- React16.useEffect(() => {
2844
+ const asked = React17.useRef({ start: null, end: null });
2845
+ React17.useEffect(() => {
2836
2846
  if (loading || !wantStart || asked.current.start === askKey) return;
2837
2847
  asked.current.start = askKey;
2838
2848
  onNeedMore("start", win);
2839
2849
  }, [wantStart, loading, askKey, onNeedMore, win]);
2840
- React16.useEffect(() => {
2850
+ React17.useEffect(() => {
2841
2851
  if (loading || !wantEnd || asked.current.end === askKey) return;
2842
2852
  asked.current.end = askKey;
2843
2853
  onNeedMore("end", win);
2844
2854
  }, [wantEnd, loading, askKey, onNeedMore, win]);
2845
- const lastKeysRef = React16.useRef(null);
2846
- const newKeys = React16.useMemo(() => {
2855
+ const lastKeysRef = React17.useRef(null);
2856
+ const newKeys = React17.useMemo(() => {
2847
2857
  const prev = lastKeysRef.current;
2848
2858
  if (!prev) return /* @__PURE__ */ new Set();
2849
2859
  const fresh = /* @__PURE__ */ new Set();
@@ -2853,7 +2863,7 @@ function VirtualList({
2853
2863
  }
2854
2864
  return fresh;
2855
2865
  }, [items]);
2856
- React16.useEffect(() => {
2866
+ React17.useEffect(() => {
2857
2867
  lastKeysRef.current = new Set(items.map(keyOf));
2858
2868
  }, [items]);
2859
2869
  const gapStyle = { "--fd-vlist-gap": rowGap + "px" };
@@ -2877,8 +2887,8 @@ function VirtualList({
2877
2887
  )
2878
2888
  );
2879
2889
  }
2880
- return /* @__PURE__ */ jsxs34("div", { className: ["fd-vlist-wrap", className].filter(Boolean).join(" "), style: { height, position: "relative", ...gapStyle, ...style }, children: [
2881
- /* @__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(
2882
2892
  "div",
2883
2893
  {
2884
2894
  className: "fd-vlist fd-scrollbar",
@@ -2890,7 +2900,7 @@ function VirtualList({
2890
2900
  ]
2891
2901
  }
2892
2902
  ),
2893
- 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: [
2894
2904
  /* @__PURE__ */ jsx38("span", { className: "fd-spinner", "aria-hidden": "true" }),
2895
2905
  /* @__PURE__ */ jsx38("span", { className: "fd-body-sm", children: refreshingLabel })
2896
2906
  ] }) }) : null
@@ -2898,8 +2908,8 @@ function VirtualList({
2898
2908
  }
2899
2909
 
2900
2910
  // src/components/data/EntityRow.tsx
2901
- import * as React17 from "react";
2902
- 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";
2903
2913
  var ENTITY_ROW_METRIC_WIDTH = 74;
2904
2914
  var METRIC_TONE_COLOR = {
2905
2915
  default: "var(--text-2)",
@@ -2911,7 +2921,7 @@ function EntityRowMetrics({ metrics, className = "", style }) {
2911
2921
  const key = m.id || m.label || i;
2912
2922
  const className2 = ["fd-erow-metric", m.tone && m.tone !== "default" ? "is-" + m.tone : "", m.tooltip != null ? "is-described" : ""].filter(Boolean).join(" ");
2913
2923
  const tone = { color: METRIC_TONE_COLOR[m.tone || "default"] };
2914
- const content = /* @__PURE__ */ jsxs35(React17.Fragment, { children: [
2924
+ const content = /* @__PURE__ */ jsxs36(React18.Fragment, { children: [
2915
2925
  m.icon ? /* @__PURE__ */ jsx39("i", { className: "ph ph-" + m.icon, "aria-hidden": "true" }) : null,
2916
2926
  /* @__PURE__ */ jsx39("span", { className: "fd-erow-metric-value fd-tabular", children: m.value }),
2917
2927
  /* @__PURE__ */ jsx39("span", { className: "fd-sr", children: " " + m.label })
@@ -2932,7 +2942,7 @@ function EntityRow({
2932
2942
  className = ""
2933
2943
  }) {
2934
2944
  const hasStrip = metrics && metrics.length > 0 || accessory != null;
2935
- return /* @__PURE__ */ jsxs35(
2945
+ return /* @__PURE__ */ jsxs36(
2936
2946
  "div",
2937
2947
  {
2938
2948
  onPointerDown,
@@ -2951,12 +2961,12 @@ function EntityRow({
2951
2961
  },
2952
2962
  children: [
2953
2963
  draggable ? /* @__PURE__ */ jsx39("i", { className: "ph ph-dots-six-vertical", "aria-hidden": "true", style: { fontSize: 14, flex: "none", color: "var(--text-muted)" } }) : null,
2954
- /* @__PURE__ */ jsxs35("span", { className: "fd-erow-body", children: [
2955
- /* @__PURE__ */ jsxs35("span", { className: "fd-erow-titleline", children: [
2964
+ /* @__PURE__ */ jsxs36("span", { className: "fd-erow-body", children: [
2965
+ /* @__PURE__ */ jsxs36("span", { className: "fd-erow-titleline", children: [
2956
2966
  /* @__PURE__ */ jsx39("span", { className: "fd-erow-title fd-body-sm", children: title }),
2957
2967
  meta ? /* @__PURE__ */ jsx39("span", { className: "fd-erow-meta", children: meta }) : null
2958
2968
  ] }),
2959
- hasStrip ? /* @__PURE__ */ jsxs35("span", { className: "fd-erow-strip", children: [
2969
+ hasStrip ? /* @__PURE__ */ jsxs36("span", { className: "fd-erow-strip", children: [
2960
2970
  metrics && metrics.length ? /* @__PURE__ */ jsx39(EntityRowMetrics, { metrics }) : null,
2961
2971
  accessory ? /* @__PURE__ */ jsx39("span", { className: "fd-erow-accessory", children: accessory }) : null
2962
2972
  ] }) : null
@@ -2979,18 +2989,18 @@ function EntityRow({
2979
2989
  }
2980
2990
 
2981
2991
  // src/components/data/TransferList.tsx
2982
- import * as React19 from "react";
2992
+ import * as React20 from "react";
2983
2993
  import { createPortal as createPortal4 } from "react-dom";
2984
2994
 
2985
2995
  // src/components/forms/field.tsx
2986
- import * as React18 from "react";
2987
- 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";
2988
2998
  function useFieldId(id) {
2989
- const generated = React18.useId();
2999
+ const generated = React19.useId();
2990
3000
  return id || generated;
2991
3001
  }
2992
3002
  function FieldLabel({ htmlFor, id, required = false, onClick, children }) {
2993
- 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: [
2994
3004
  children,
2995
3005
  required ? /* @__PURE__ */ jsx40("span", { className: "fd-field-req", "aria-hidden": "true", children: "*" }) : null
2996
3006
  ] });
@@ -3002,7 +3012,7 @@ function useTriggerLabelling(label, id) {
3002
3012
  }
3003
3013
 
3004
3014
  // src/components/forms/Input.tsx
3005
- import { jsx as jsx41, jsxs as jsxs37 } from "react/jsx-runtime";
3015
+ import { jsx as jsx41, jsxs as jsxs38 } from "react/jsx-runtime";
3006
3016
  function Input({
3007
3017
  label,
3008
3018
  help,
@@ -3029,16 +3039,16 @@ function Input({
3029
3039
  disabled ? "fd-input-disabled" : "",
3030
3040
  size === "lg" ? "fd-input-lg" : ""
3031
3041
  ].filter(Boolean).join(" ");
3032
- 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: [
3033
3043
  label ? /* @__PURE__ */ jsx41(FieldLabel, { htmlFor: fieldId, required, children: label }) : null,
3034
- /* @__PURE__ */ jsxs37("div", { className: box, children: [
3044
+ /* @__PURE__ */ jsxs38("div", { className: box, children: [
3035
3045
  icon ? /* @__PURE__ */ jsx41("span", { className: "fd-input-icon", children: /* @__PURE__ */ jsx41("i", { className: "ph ph-" + icon, "aria-hidden": "true" }) }) : null,
3036
3046
  prefix ? /* @__PURE__ */ jsx41("span", { className: "fd-input-affix", children: prefix }) : null,
3037
3047
  /* @__PURE__ */ jsx41("input", { id: fieldId, disabled, style: inputStyle, "aria-invalid": error ? "true" : void 0, ...rest }),
3038
3048
  loading ? /* @__PURE__ */ jsx41("span", { className: "fd-spinner", style: { color: "var(--text-muted)" }, "aria-label": "Loading" }) : null,
3039
3049
  suffix && !loading ? /* @__PURE__ */ jsx41("span", { className: "fd-input-affix", children: suffix }) : null
3040
3050
  ] }),
3041
- error ? /* @__PURE__ */ jsxs37("span", { className: "fd-field-error", children: [
3051
+ error ? /* @__PURE__ */ jsxs38("span", { className: "fd-field-error", children: [
3042
3052
  /* @__PURE__ */ jsx41("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
3043
3053
  error
3044
3054
  ] }) : help ? /* @__PURE__ */ jsx41("span", { className: "fd-field-help", children: help }) : null
@@ -3090,7 +3100,7 @@ function SearchField({
3090
3100
  }
3091
3101
 
3092
3102
  // src/components/data/TransferList.tsx
3093
- import { jsx as jsx43, jsxs as jsxs38 } from "react/jsx-runtime";
3103
+ import { jsx as jsx43, jsxs as jsxs39 } from "react/jsx-runtime";
3094
3104
  var emptyHasMore = {};
3095
3105
  var DRAG_THRESHOLD_PX = 5;
3096
3106
  function TransferList({
@@ -3104,12 +3114,12 @@ function TransferList({
3104
3114
  listHeight = 440,
3105
3115
  className = ""
3106
3116
  }) {
3107
- const [drag, setDrag] = React19.useState(null);
3108
- const [dragOverSide, setDragOverSide] = React19.useState(null);
3109
- const dragRef = React19.useRef(null);
3110
- const armedRef = React19.useRef(null);
3111
- const sideRefs = React19.useRef({ left: null, right: null });
3112
- const hitTestSide = React19.useCallback((x, y) => {
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) => {
3113
3123
  for (const side of ["left", "right"]) {
3114
3124
  const el = sideRefs.current[side];
3115
3125
  if (!el) continue;
@@ -3118,7 +3128,7 @@ function TransferList({
3118
3128
  }
3119
3129
  return null;
3120
3130
  }, []);
3121
- const findItem = React19.useCallback(
3131
+ const findItem = React20.useCallback(
3122
3132
  (side, key) => (side === "left" ? left.items : right.items).find((it) => keyOf(it) === key),
3123
3133
  [left.items, right.items, keyOf]
3124
3134
  );
@@ -3140,7 +3150,7 @@ function TransferList({
3140
3150
  height: rect.height
3141
3151
  };
3142
3152
  };
3143
- React19.useEffect(() => {
3153
+ React20.useEffect(() => {
3144
3154
  const onMovePointer = (e) => {
3145
3155
  const armed = armedRef.current;
3146
3156
  if (!armed || e.pointerId !== armed.pointerId) return;
@@ -3193,7 +3203,7 @@ function TransferList({
3193
3203
  window.removeEventListener("pointercancel", endDrag);
3194
3204
  };
3195
3205
  }, [hitTestSide, findItem, onMove]);
3196
- React19.useEffect(() => {
3206
+ React20.useEffect(() => {
3197
3207
  if (!drag || typeof document === "undefined") return;
3198
3208
  const prev = document.body.style.userSelect;
3199
3209
  document.body.style.userSelect = "none";
@@ -3203,7 +3213,7 @@ function TransferList({
3203
3213
  }, [drag]);
3204
3214
  const renderSide = (side, cfg, opposite) => {
3205
3215
  const showOverlay = drag != null && dragOverSide === side;
3206
- return /* @__PURE__ */ jsxs38(
3216
+ return /* @__PURE__ */ jsxs39(
3207
3217
  "div",
3208
3218
  {
3209
3219
  ref: (el) => {
@@ -3211,12 +3221,12 @@ function TransferList({
3211
3221
  },
3212
3222
  className: ["fd-tlist-side", dragOverSide === side ? "is-drop-target" : ""].filter(Boolean).join(" "),
3213
3223
  children: [
3214
- cfg.label ? /* @__PURE__ */ jsxs38("span", { className: "fd-overline fd-muted", children: [
3224
+ cfg.label ? /* @__PURE__ */ jsxs39("span", { className: "fd-overline fd-muted", children: [
3215
3225
  cfg.label,
3216
3226
  cfg.total != null ? " (" + cfg.total.toLocaleString() + ")" : ""
3217
3227
  ] }) : null,
3218
3228
  cfg.header ? /* @__PURE__ */ jsx43("div", { className: "fd-tlist-header", children: cfg.header }) : null,
3219
- /* @__PURE__ */ jsxs38("span", { className: "fd-row", style: { gap: 8 }, children: [
3229
+ /* @__PURE__ */ jsxs39("span", { className: "fd-row", style: { gap: 8 }, children: [
3220
3230
  /* @__PURE__ */ jsx43(SearchField, { value: cfg.search, onChange: cfg.onSearchChange, placeholder: "Search", "aria-label": (cfg.label || side) + " search", style: { flex: 1 } }),
3221
3231
  /* @__PURE__ */ jsx43(SortMenu, { fields: cfg.sortFields, sort: cfg.sort, onSort: cfg.onSort, align: side === "left" ? "left" : "right" })
3222
3232
  ] }),
@@ -3263,7 +3273,7 @@ function TransferList({
3263
3273
  }
3264
3274
  ),
3265
3275
  cfg.footer ? /* @__PURE__ */ jsx43("div", { className: "fd-tlist-footer", children: cfg.footer }) : null,
3266
- showOverlay ? /* @__PURE__ */ jsx43("div", { className: "fd-tlist-drop-overlay", "aria-hidden": "true", children: /* @__PURE__ */ jsxs38("span", { className: "fd-tlist-drop-card", children: [
3276
+ showOverlay ? /* @__PURE__ */ jsx43("div", { className: "fd-tlist-drop-overlay", "aria-hidden": "true", children: /* @__PURE__ */ jsxs39("span", { className: "fd-tlist-drop-card", children: [
3267
3277
  /* @__PURE__ */ jsx43("i", { className: "ph ph-tray-arrow-down", style: { fontSize: 18 }, "aria-hidden": "true" }),
3268
3278
  /* @__PURE__ */ jsx43("span", { className: "fd-body-sm", style: { fontWeight: 600 }, children: cfg.dropLabel || "Drop here" + (cfg.label ? " \u2014 " + cfg.label : "") })
3269
3279
  ] }) }) : null
@@ -3271,8 +3281,8 @@ function TransferList({
3271
3281
  }
3272
3282
  );
3273
3283
  };
3274
- return /* @__PURE__ */ jsxs38("div", { className: ["fd-tlist", className].filter(Boolean).join(" "), children: [
3275
- /* @__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: [
3276
3286
  renderSide("left", left, "right"),
3277
3287
  renderSide("right", right, "left")
3278
3288
  ] }),
@@ -3301,19 +3311,19 @@ function TransferList({
3301
3311
  }
3302
3312
 
3303
3313
  // src/components/forms/Checkbox.tsx
3304
- import * as React20 from "react";
3305
- 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";
3306
3316
  function Checkbox({ label, description, card = false, indeterminate = false, className = "", ...rest }) {
3307
- const ref = React20.useRef(null);
3308
- React20.useEffect(() => {
3317
+ const ref = React21.useRef(null);
3318
+ React21.useEffect(() => {
3309
3319
  if (ref.current) ref.current.indeterminate = indeterminate;
3310
3320
  }, [indeterminate]);
3311
- return /* @__PURE__ */ jsxs39("label", { className: ["fd-choice", card ? "fd-choice-card" : "", className].filter(Boolean).join(" "), children: [
3312
- /* @__PURE__ */ jsxs39("span", { className: "fd-choice-input", children: [
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: [
3313
3323
  /* @__PURE__ */ jsx44("input", { ref, type: "checkbox", ...rest }),
3314
3324
  /* @__PURE__ */ jsx44("span", { className: "fd-choice-box", "aria-hidden": "true", children: /* @__PURE__ */ jsx44("i", { className: indeterminate ? "ph ph-minus" : "ph ph-check" }) })
3315
3325
  ] }),
3316
- /* @__PURE__ */ jsxs39("span", { className: "fd-choice-text", children: [
3326
+ /* @__PURE__ */ jsxs40("span", { className: "fd-choice-text", children: [
3317
3327
  /* @__PURE__ */ jsx44("span", { className: "fd-choice-title", children: label }),
3318
3328
  description ? /* @__PURE__ */ jsx44("span", { className: "fd-choice-desc", children: description }) : null
3319
3329
  ] })
@@ -3321,14 +3331,14 @@ function Checkbox({ label, description, card = false, indeterminate = false, cla
3321
3331
  }
3322
3332
 
3323
3333
  // src/components/forms/Radio.tsx
3324
- import { jsx as jsx45, jsxs as jsxs40 } from "react/jsx-runtime";
3334
+ import { jsx as jsx45, jsxs as jsxs41 } from "react/jsx-runtime";
3325
3335
  function Radio({ label, description, card = false, className = "", ...rest }) {
3326
- return /* @__PURE__ */ jsxs40("label", { className: ["fd-choice", card ? "fd-choice-card" : "", className].filter(Boolean).join(" "), children: [
3327
- /* @__PURE__ */ jsxs40("span", { className: "fd-choice-input", children: [
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: [
3328
3338
  /* @__PURE__ */ jsx45("input", { type: "radio", ...rest }),
3329
3339
  /* @__PURE__ */ jsx45("span", { className: "fd-choice-box fd-choice-box-round", "aria-hidden": "true", children: /* @__PURE__ */ jsx45("span", { className: "fd-choice-dot" }) })
3330
3340
  ] }),
3331
- /* @__PURE__ */ jsxs40("span", { className: "fd-choice-text", children: [
3341
+ /* @__PURE__ */ jsxs41("span", { className: "fd-choice-text", children: [
3332
3342
  /* @__PURE__ */ jsx45("span", { className: "fd-choice-title", children: label }),
3333
3343
  description ? /* @__PURE__ */ jsx45("span", { className: "fd-choice-desc", children: description }) : null
3334
3344
  ] })
@@ -3336,12 +3346,12 @@ function Radio({ label, description, card = false, className = "", ...rest }) {
3336
3346
  }
3337
3347
 
3338
3348
  // src/components/forms/Switch.tsx
3339
- import { jsx as jsx46, jsxs as jsxs41 } from "react/jsx-runtime";
3349
+ import { jsx as jsx46, jsxs as jsxs42 } from "react/jsx-runtime";
3340
3350
  function Switch({ label, description, className = "", ...rest }) {
3341
- 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: [
3342
3352
  /* @__PURE__ */ jsx46("input", { type: "checkbox", role: "switch", ...rest }),
3343
3353
  /* @__PURE__ */ jsx46("span", { className: "fd-switch-track", children: /* @__PURE__ */ jsx46("span", { className: "fd-switch-thumb" }) }),
3344
- label ? /* @__PURE__ */ jsxs41("span", { className: "fd-choice-text", children: [
3354
+ label ? /* @__PURE__ */ jsxs42("span", { className: "fd-choice-text", children: [
3345
3355
  /* @__PURE__ */ jsx46("span", { className: "fd-switch-label", children: label }),
3346
3356
  description ? /* @__PURE__ */ jsx46("span", { className: "fd-choice-desc", children: description }) : null
3347
3357
  ] }) : null
@@ -3349,14 +3359,14 @@ function Switch({ label, description, className = "", ...rest }) {
3349
3359
  }
3350
3360
 
3351
3361
  // src/components/forms/Textarea.tsx
3352
- import { jsx as jsx47, jsxs as jsxs42 } from "react/jsx-runtime";
3362
+ import { jsx as jsx47, jsxs as jsxs43 } from "react/jsx-runtime";
3353
3363
  function Textarea({ label, help, error, required = false, rows = 4, disabled = false, id, className = "", style, ...rest }) {
3354
3364
  const fieldId = useFieldId(id);
3355
3365
  const box = ["fd-input", "fd-input-textarea", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" ");
3356
- return /* @__PURE__ */ jsxs42("div", { className: ["fd-field", className].filter(Boolean).join(" "), style, children: [
3366
+ return /* @__PURE__ */ jsxs43("div", { className: ["fd-field", className].filter(Boolean).join(" "), style, children: [
3357
3367
  label ? /* @__PURE__ */ jsx47(FieldLabel, { htmlFor: fieldId, required, children: label }) : null,
3358
3368
  /* @__PURE__ */ jsx47("div", { className: box, children: /* @__PURE__ */ jsx47("textarea", { id: fieldId, rows, disabled, "aria-invalid": error ? "true" : void 0, ...rest }) }),
3359
- error ? /* @__PURE__ */ jsxs42("span", { className: "fd-field-error", children: [
3369
+ error ? /* @__PURE__ */ jsxs43("span", { className: "fd-field-error", children: [
3360
3370
  /* @__PURE__ */ jsx47("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
3361
3371
  error
3362
3372
  ] }) : help ? /* @__PURE__ */ jsx47("span", { className: "fd-field-help", children: help }) : null
@@ -3364,8 +3374,8 @@ function Textarea({ label, help, error, required = false, rows = 4, disabled = f
3364
3374
  }
3365
3375
 
3366
3376
  // src/components/forms/NumberInput.tsx
3367
- import * as React21 from "react";
3368
- 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";
3369
3379
  function NumberInput({
3370
3380
  label,
3371
3381
  help,
@@ -3392,10 +3402,10 @@ function NumberInput({
3392
3402
  const n = Number(String(v == null ? "" : v).replace(/[^0-9.-]/g, ""));
3393
3403
  return isNaN(n) ? null : n;
3394
3404
  };
3395
- const [text, setText] = React21.useState(value == null || value === "" ? "" : String(value));
3396
- const [editing, setEditing] = React21.useState(false);
3397
- const timer = React21.useRef(null);
3398
- React21.useEffect(() => {
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(() => {
3399
3409
  if (!editing) setText(value == null || value === "" ? "" : String(value));
3400
3410
  }, [value, editing]);
3401
3411
  const clamp = (n) => Math.min(max, Math.max(min, n));
@@ -3419,7 +3429,7 @@ function NumberInput({
3419
3429
  const release = () => {
3420
3430
  if (timer.current) clearTimeout(timer.current);
3421
3431
  };
3422
- React21.useEffect(() => () => {
3432
+ React22.useEffect(() => () => {
3423
3433
  if (timer.current) clearTimeout(timer.current);
3424
3434
  }, []);
3425
3435
  const shown = editing ? text : (() => {
@@ -3429,9 +3439,9 @@ function NumberInput({
3429
3439
  const box = ["fd-input", "fd-input-num", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" ");
3430
3440
  const fieldName = label || ariaLabel;
3431
3441
  const stepperName = (verb) => fieldName ? verb + " " + fieldName : verb;
3432
- 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: [
3433
3443
  label ? /* @__PURE__ */ jsx48(FieldLabel, { htmlFor: fieldId, required, children: label }) : null,
3434
- /* @__PURE__ */ jsxs43("div", { className: box, style: { gap: 8 }, children: [
3444
+ /* @__PURE__ */ jsxs44("div", { className: box, style: { gap: 8 }, children: [
3435
3445
  prefix ? /* @__PURE__ */ jsx48("span", { className: "fd-input-affix", children: prefix }) : null,
3436
3446
  /* @__PURE__ */ jsx48(
3437
3447
  "input",
@@ -3469,7 +3479,7 @@ function NumberInput({
3469
3479
  }
3470
3480
  ),
3471
3481
  suffix ? /* @__PURE__ */ jsx48("span", { className: "fd-input-affix", children: suffix }) : null,
3472
- /* @__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: [
3473
3483
  /* @__PURE__ */ jsx48(
3474
3484
  "button",
3475
3485
  {
@@ -3498,7 +3508,7 @@ function NumberInput({
3498
3508
  )
3499
3509
  ] })
3500
3510
  ] }),
3501
- error ? /* @__PURE__ */ jsxs43("span", { className: "fd-field-error", children: [
3511
+ error ? /* @__PURE__ */ jsxs44("span", { className: "fd-field-error", children: [
3502
3512
  /* @__PURE__ */ jsx48("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
3503
3513
  error
3504
3514
  ] }) : help ? /* @__PURE__ */ jsx48("span", { className: "fd-field-help", children: help }) : null
@@ -3506,8 +3516,8 @@ function NumberInput({
3506
3516
  }
3507
3517
 
3508
3518
  // src/components/forms/Select.tsx
3509
- import * as React22 from "react";
3510
- 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";
3511
3521
  var norm = (o) => typeof o === "string" ? { value: o, label: o } : o;
3512
3522
  function Select({
3513
3523
  label,
@@ -3533,13 +3543,13 @@ function Select({
3533
3543
  const isOn = (v) => multiple ? vals.includes(v) : v === value;
3534
3544
  const hasSearch = searchable === void 0 ? opts.length > 8 : searchable;
3535
3545
  const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
3536
- const [open, setOpen] = React22.useState(false);
3537
- const [q, setQ] = React22.useState("");
3538
- const [active, setActive] = React22.useState(-1);
3539
- const rootRef = React22.useRef(null);
3540
- const boxRef = React22.useRef(null);
3541
- const listRef = React22.useRef(null);
3542
- const typeBuf = React22.useRef({ s: "", t: 0 });
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 });
3543
3553
  const selected = multiple ? null : opts.find((o) => o.value === value);
3544
3554
  const chosen = multiple ? opts.filter((o) => vals.includes(o.value)) : [];
3545
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;
@@ -3564,7 +3574,7 @@ function Select({
3564
3574
  }
3565
3575
  setOpen(!open);
3566
3576
  };
3567
- React22.useEffect(() => {
3577
+ React23.useEffect(() => {
3568
3578
  if (!open || active < 0 || !listRef.current) return;
3569
3579
  const el = listRef.current.querySelector('[data-i="' + active + '"]');
3570
3580
  if (el) {
@@ -3617,10 +3627,10 @@ function Select({
3617
3627
  else last.items.push({ o, i });
3618
3628
  });
3619
3629
  const box = ["fd-input", "fd-select", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" ");
3620
- return /* @__PURE__ */ jsxs44("div", { className: ["fd-field", "fd-popfield", open ? "is-open" : "", className].filter(Boolean).join(" "), style, ref: rootRef, children: [
3630
+ return /* @__PURE__ */ jsxs45("div", { className: ["fd-field", "fd-popfield", open ? "is-open" : "", className].filter(Boolean).join(" "), style, ref: rootRef, children: [
3621
3631
  label ? /* @__PURE__ */ jsx49(FieldLabel, { id: labelId, required, onClick: toggle, children: label }) : null,
3622
- /* @__PURE__ */ jsxs44("div", { className: box, style: { cursor: disabled ? "not-allowed" : "pointer" }, ref: boxRef, children: [
3623
- /* @__PURE__ */ jsxs44(
3632
+ /* @__PURE__ */ jsxs45("div", { className: box, style: { cursor: disabled ? "not-allowed" : "pointer" }, ref: boxRef, children: [
3633
+ /* @__PURE__ */ jsxs45(
3624
3634
  "button",
3625
3635
  {
3626
3636
  type: "button",
@@ -3668,7 +3678,7 @@ function Select({
3668
3678
  minWidth: 260,
3669
3679
  role: "presentation",
3670
3680
  style: { maxWidth: 380 },
3671
- header: hasSearch ? /* @__PURE__ */ jsxs44("div", { className: "fd-pop-search", children: [
3681
+ header: hasSearch ? /* @__PURE__ */ jsxs45("div", { className: "fd-pop-search", children: [
3672
3682
  /* @__PURE__ */ jsx49("i", { className: "ph ph-magnifying-glass", style: { color: "var(--text-muted)", fontSize: 14 } }),
3673
3683
  /* @__PURE__ */ jsx49(
3674
3684
  "input",
@@ -3685,7 +3695,7 @@ function Select({
3685
3695
  ),
3686
3696
  q ? /* @__PURE__ */ jsx49("span", { className: "fd-body-sm fd-muted", children: visible.length }) : null
3687
3697
  ] }) : void 0,
3688
- footer: multiple ? /* @__PURE__ */ jsxs44(React22.Fragment, { children: [
3698
+ footer: multiple ? /* @__PURE__ */ jsxs45(React23.Fragment, { children: [
3689
3699
  /* @__PURE__ */ jsx49(
3690
3700
  "button",
3691
3701
  {
@@ -3696,7 +3706,7 @@ function Select({
3696
3706
  }
3697
3707
  ),
3698
3708
  /* @__PURE__ */ jsx49("span", { style: { flex: 1 } }),
3699
- /* @__PURE__ */ jsxs44("span", { className: "fd-body-sm fd-muted", children: [
3709
+ /* @__PURE__ */ jsxs45("span", { className: "fd-body-sm fd-muted", children: [
3700
3710
  vals.length,
3701
3711
  " of ",
3702
3712
  opts.length
@@ -3712,13 +3722,13 @@ function Select({
3712
3722
  }
3713
3723
  )
3714
3724
  ] }) : void 0,
3715
- children: /* @__PURE__ */ jsx49("div", { className: "fd-pop-list", role: "listbox", "aria-multiselectable": multiple || void 0, ref: listRef, children: visible.length === 0 ? /* @__PURE__ */ jsxs44("div", { className: "fd-pop-empty", children: [
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: [
3716
3726
  'Nothing matches "',
3717
3727
  q,
3718
3728
  '".'
3719
- ] }) : groups.map((grp) => /* @__PURE__ */ jsxs44(React22.Fragment, { children: [
3729
+ ] }) : groups.map((grp) => /* @__PURE__ */ jsxs45(React23.Fragment, { children: [
3720
3730
  grp.g ? /* @__PURE__ */ jsx49("div", { className: "fd-pop-group", children: grp.g }) : null,
3721
- grp.items.map(({ o, i }) => /* @__PURE__ */ jsxs44(
3731
+ grp.items.map(({ o, i }) => /* @__PURE__ */ jsxs45(
3722
3732
  "button",
3723
3733
  {
3724
3734
  type: "button",
@@ -3732,7 +3742,7 @@ function Select({
3732
3742
  children: [
3733
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,
3734
3744
  o.icon ? /* @__PURE__ */ jsx49("span", { className: "fd-opt-icon", children: /* @__PURE__ */ jsx49("i", { className: "ph ph-" + o.icon }) }) : null,
3735
- /* @__PURE__ */ jsxs44("span", { style: { flex: 1, minWidth: 0 }, children: [
3745
+ /* @__PURE__ */ jsxs45("span", { style: { flex: 1, minWidth: 0 }, children: [
3736
3746
  /* @__PURE__ */ jsx49("span", { className: "fd-opt-label", children: o.label }),
3737
3747
  o.description ? /* @__PURE__ */ jsx49("span", { className: "fd-opt-desc", children: o.description }) : null
3738
3748
  ] }),
@@ -3745,7 +3755,7 @@ function Select({
3745
3755
  ] }, grp.g || "_")) })
3746
3756
  }
3747
3757
  ),
3748
- error ? /* @__PURE__ */ jsxs44("span", { className: "fd-field-error", children: [
3758
+ error ? /* @__PURE__ */ jsxs45("span", { className: "fd-field-error", children: [
3749
3759
  /* @__PURE__ */ jsx49("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
3750
3760
  error
3751
3761
  ] }) : help ? /* @__PURE__ */ jsx49("span", { className: "fd-field-help", children: help }) : null
@@ -3753,8 +3763,8 @@ function Select({
3753
3763
  }
3754
3764
 
3755
3765
  // src/components/forms/DatePicker.tsx
3756
- import * as React23 from "react";
3757
- 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";
3758
3768
  var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
3759
3769
  var DOW = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
3760
3770
  var iso = (d) => d.getFullYear() + "-" + String(d.getMonth() + 1).padStart(2, "0") + "-" + String(d.getDate()).padStart(2, "0");
@@ -3771,10 +3781,10 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3771
3781
  const today = /* @__PURE__ */ new Date();
3772
3782
  const sel = range ? value || {} : { start: value, end: value };
3773
3783
  const anchor = parse(sel.start) || parse(initialMonth) || today;
3774
- const [vy, setVy] = React23.useState(anchor.getFullYear());
3775
- const [vm, setVm] = React23.useState(anchor.getMonth());
3776
- const [mode2, setMode] = React23.useState("days");
3777
- const [hover, setHover] = React23.useState(null);
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);
3778
3788
  const s = parse(sel.start), e = parse(sel.end);
3779
3789
  const hoverEnd = range && s && !e && hover ? parse(hover) : null;
3780
3790
  const inRange = (d) => {
@@ -3811,7 +3821,7 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3811
3821
  const startPad = new Date(y, m, 1).getDay();
3812
3822
  const cells = [];
3813
3823
  for (let i = 0; i < 42; i++) cells.push(new Date(y, m, i - startPad + 1));
3814
- return /* @__PURE__ */ jsxs45("div", { className: "fd-cal-grid", style: { width: months > 1 ? 252 : "auto", flex: "none" }, onMouseLeave: () => setHover(null), children: [
3824
+ return /* @__PURE__ */ jsxs46("div", { className: "fd-cal-grid", style: { width: months > 1 ? 252 : "auto", flex: "none" }, onMouseLeave: () => setHover(null), children: [
3815
3825
  DOW.map((d) => /* @__PURE__ */ jsx50("span", { className: "fd-cal-dow", children: d }, d)),
3816
3826
  cells.map((d, i) => /* @__PURE__ */ jsx50(
3817
3827
  "button",
@@ -3827,17 +3837,17 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3827
3837
  ] });
3828
3838
  };
3829
3839
  const nextY = vm === 11 ? vy + 1 : vy, nextM = (vm + 1) % 12;
3830
- return /* @__PURE__ */ jsxs45("div", { className: "fd-cal", style: { width: months > 1 && mode2 === "days" ? "auto" : void 0 }, children: [
3831
- /* @__PURE__ */ jsxs45("div", { className: "fd-cal-head", children: [
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: [
3832
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" }) }),
3833
- /* @__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: [
3834
3844
  mode2 === "days" ? MONTHS[vm] + " " + vy : mode2 === "months" ? vy : vy - 5 + " \u2013 " + (vy + 6),
3835
3845
  /* @__PURE__ */ jsx50("i", { className: "ph ph-caret-down", style: { fontSize: 10, marginLeft: 6, color: "var(--text-muted)" } })
3836
3846
  ] }),
3837
3847
  months > 1 && mode2 === "days" ? /* @__PURE__ */ jsx50("span", { className: "fd-cal-title", style: { cursor: "default", background: "none" }, children: MONTHS[nextM] + " " + nextY }) : null,
3838
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" }) })
3839
3849
  ] }),
3840
- mode2 === "days" ? /* @__PURE__ */ jsxs45("div", { style: { display: "flex", gap: 18 }, children: [
3850
+ mode2 === "days" ? /* @__PURE__ */ jsxs46("div", { style: { display: "flex", gap: 18 }, children: [
3841
3851
  monthGrid(vy, vm),
3842
3852
  months > 1 ? monthGrid(nextY, nextM) : null
3843
3853
  ] }) : mode2 === "months" ? /* @__PURE__ */ jsx50("div", { className: "fd-cal-grid-months", children: MONTHS.map((m, i) => /* @__PURE__ */ jsx50(
@@ -3865,7 +3875,7 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3865
3875
  },
3866
3876
  y
3867
3877
  )) }),
3868
- /* @__PURE__ */ jsxs45("div", { className: "fd-cal-foot", children: [
3878
+ /* @__PURE__ */ jsxs46("div", { className: "fd-cal-foot", children: [
3869
3879
  /* @__PURE__ */ jsx50(
3870
3880
  "button",
3871
3881
  {
@@ -3881,7 +3891,7 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3881
3891
  }
3882
3892
  ),
3883
3893
  /* @__PURE__ */ jsx50("span", { style: { flex: 1 } }),
3884
- 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: [
3885
3895
  fmt(sel.start),
3886
3896
  sel.end ? " \u2192 " + fmt(sel.end) : " \u2192 pick an end"
3887
3897
  ] }) : null
@@ -3890,16 +3900,16 @@ function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
3890
3900
  }
3891
3901
  function DatePicker({ label, help, error, required = false, disabled = false, range = false, value, onChange, placeholder, id, className = "", style, ...rest }) {
3892
3902
  const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
3893
- const [open, setOpen] = React23.useState(false);
3894
- const rootRef = React23.useRef(null);
3895
- const boxRef = React23.useRef(null);
3903
+ const [open, setOpen] = React24.useState(false);
3904
+ const rootRef = React24.useRef(null);
3905
+ const boxRef = React24.useRef(null);
3896
3906
  const display = range ? value && value.start ? fmt(value.start) + (value.end ? " \u2192 " + fmt(value.end) : " \u2192 \u2026") : "" : fmt(value);
3897
3907
  const toggle = () => {
3898
3908
  if (!disabled) setOpen(!open);
3899
3909
  };
3900
- 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: [
3901
3911
  label ? /* @__PURE__ */ jsx50(FieldLabel, { id: labelId, required, onClick: toggle, children: label }) : null,
3902
- /* @__PURE__ */ jsxs45("div", { className: ["fd-input", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" "), style: { cursor: disabled ? "not-allowed" : "pointer" }, onClick: toggle, ref: boxRef, children: [
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: [
3903
3913
  /* @__PURE__ */ jsx50("span", { className: "fd-input-icon", children: /* @__PURE__ */ jsx50("i", { className: "ph ph-calendar-blank", "aria-hidden": "true" }) }),
3904
3914
  /* @__PURE__ */ jsx50(
3905
3915
  "button",
@@ -3946,7 +3956,7 @@ function DatePicker({ label, help, error, required = false, disabled = false, ra
3946
3956
  )
3947
3957
  }
3948
3958
  ),
3949
- error ? /* @__PURE__ */ jsxs45("span", { className: "fd-field-error", children: [
3959
+ error ? /* @__PURE__ */ jsxs46("span", { className: "fd-field-error", children: [
3950
3960
  /* @__PURE__ */ jsx50("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
3951
3961
  error
3952
3962
  ] }) : help ? /* @__PURE__ */ jsx50("span", { className: "fd-field-help", children: help }) : null
@@ -3954,8 +3964,8 @@ function DatePicker({ label, help, error, required = false, disabled = false, ra
3954
3964
  }
3955
3965
 
3956
3966
  // src/components/forms/TimePicker.tsx
3957
- import * as React24 from "react";
3958
- 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";
3959
3969
  var pad = (n) => String(n).padStart(2, "0");
3960
3970
  function ClockFace({ value = "09:00", onChange }) {
3961
3971
  let [h24, m] = value.split(":").map(Number);
@@ -3963,9 +3973,9 @@ function ClockFace({ value = "09:00", onChange }) {
3963
3973
  if (isNaN(m)) m = 0;
3964
3974
  const pm = h24 >= 12;
3965
3975
  const h12 = h24 % 12 === 0 ? 12 : h24 % 12;
3966
- const [mode2, setMode] = React24.useState("h");
3967
- const faceRef = React24.useRef(null);
3968
- const dragging = React24.useRef(false);
3976
+ const [mode2, setMode] = React25.useState("h");
3977
+ const faceRef = React25.useRef(null);
3978
+ const dragging = React25.useRef(false);
3969
3979
  const set = (h, mm, isPm) => onChange((isPm ? h % 12 + 12 : h % 12) + ":" + pad(mm));
3970
3980
  const R = 108, NR = 80;
3971
3981
  const nums = mode2 === "h" ? Array.from({ length: 12 }, (_, i) => i + 1) : Array.from({ length: 12 }, (_, i) => i * 5);
@@ -4000,8 +4010,8 @@ function ClockFace({ value = "09:00", onChange }) {
4000
4010
  };
4001
4011
  const handAngle = mode2 === "h" ? h12 % 12 * 30 : m * 6;
4002
4012
  const minuteOff = mode2 === "m" && m % 5 !== 0;
4003
- return /* @__PURE__ */ jsxs46("div", { style: { padding: "4px 14px 14px" }, children: [
4004
- /* @__PURE__ */ jsxs46("div", { className: "fd-clock-digits", children: [
4013
+ return /* @__PURE__ */ jsxs47("div", { style: { padding: "4px 14px 14px" }, children: [
4014
+ /* @__PURE__ */ jsxs47("div", { className: "fd-clock-digits", children: [
4005
4015
  /* @__PURE__ */ jsx51("button", { type: "button", className: "fd-clock-digit" + (mode2 === "h" ? " is-active" : ""), onClick: () => setMode("h"), children: pad(h12) }),
4006
4016
  /* @__PURE__ */ jsx51("span", { style: { fontSize: 24, fontWeight: 700, color: "var(--text-muted)" }, children: ":" }),
4007
4017
  /* @__PURE__ */ jsx51("button", { type: "button", className: "fd-clock-digit" + (mode2 === "m" ? " is-active" : ""), onClick: () => setMode("m"), children: pad(m) }),
@@ -4016,7 +4026,7 @@ function ClockFace({ value = "09:00", onChange }) {
4016
4026
  ap
4017
4027
  )) })
4018
4028
  ] }),
4019
- /* @__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: [
4020
4030
  /* @__PURE__ */ jsx51("span", { className: "fd-clock-hand", style: { height: NR - (minuteOff ? 14 : 16), transform: "translateX(-50%) rotate(" + handAngle + "deg)", bottom: "50%" } }),
4021
4031
  /* @__PURE__ */ jsx51("span", { className: "fd-clock-pivot" }),
4022
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,
@@ -4038,9 +4048,9 @@ function ClockFace({ value = "09:00", onChange }) {
4038
4048
  }
4039
4049
  function TimePicker({ label, help, error, required = false, disabled = false, value = "", onChange, placeholder = "Pick a time", id, className = "", style }) {
4040
4050
  const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
4041
- const [open, setOpen] = React24.useState(false);
4042
- const rootRef = React24.useRef(null);
4043
- const boxRef = React24.useRef(null);
4051
+ const [open, setOpen] = React25.useState(false);
4052
+ const rootRef = React25.useRef(null);
4053
+ const boxRef = React25.useRef(null);
4044
4054
  const disp = () => {
4045
4055
  if (!value) return "";
4046
4056
  const [h, m] = value.split(":").map(Number);
@@ -4049,9 +4059,9 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
4049
4059
  const toggle = () => {
4050
4060
  if (!disabled) setOpen(!open);
4051
4061
  };
4052
- 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: [
4053
4063
  label ? /* @__PURE__ */ jsx51(FieldLabel, { id: labelId, required, onClick: toggle, children: label }) : null,
4054
- /* @__PURE__ */ jsxs46("div", { className: ["fd-input", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" "), style: { cursor: disabled ? "not-allowed" : "pointer" }, onClick: toggle, ref: boxRef, children: [
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: [
4055
4065
  /* @__PURE__ */ jsx51("span", { className: "fd-input-icon", children: /* @__PURE__ */ jsx51("i", { className: "ph ph-clock", "aria-hidden": "true" }) }),
4056
4066
  /* @__PURE__ */ jsx51(
4057
4067
  "button",
@@ -4083,7 +4093,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
4083
4093
  offset: 6,
4084
4094
  width: 262,
4085
4095
  role: "presentation",
4086
- footer: /* @__PURE__ */ jsxs46(React24.Fragment, { children: [
4096
+ footer: /* @__PURE__ */ jsxs47(React25.Fragment, { children: [
4087
4097
  /* @__PURE__ */ jsx51(
4088
4098
  "button",
4089
4099
  {
@@ -4103,7 +4113,7 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
4103
4113
  children: /* @__PURE__ */ jsx51(ClockFace, { value: value || "09:00", onChange: (v) => onChange && onChange({ target: { value: v } }) })
4104
4114
  }
4105
4115
  ),
4106
- error ? /* @__PURE__ */ jsxs46("span", { className: "fd-field-error", children: [
4116
+ error ? /* @__PURE__ */ jsxs47("span", { className: "fd-field-error", children: [
4107
4117
  /* @__PURE__ */ jsx51("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
4108
4118
  error
4109
4119
  ] }) : help ? /* @__PURE__ */ jsx51("span", { className: "fd-field-help", children: help }) : null
@@ -4111,8 +4121,8 @@ function TimePicker({ label, help, error, required = false, disabled = false, va
4111
4121
  }
4112
4122
 
4113
4123
  // src/components/forms/Slider.tsx
4114
- import * as React25 from "react";
4115
- 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";
4116
4126
  function Slider({
4117
4127
  label,
4118
4128
  min = 0,
@@ -4129,15 +4139,15 @@ function Slider({
4129
4139
  ...rest
4130
4140
  }) {
4131
4141
  const fieldId = useFieldId(id);
4132
- const [dragging, setDragging] = React25.useState(false);
4142
+ const [dragging, setDragging] = React26.useState(false);
4133
4143
  const v = value === void 0 ? min : Number(value);
4134
4144
  const pct = max === min ? 0 : (v - min) / (max - min) * 100;
4135
- return /* @__PURE__ */ jsxs47("div", { className: ["fd-field", className].filter(Boolean).join(" "), children: [
4136
- label ? /* @__PURE__ */ jsxs47("div", { className: "fd-row", style: { justifyContent: "space-between", gap: 12 }, children: [
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: [
4137
4147
  /* @__PURE__ */ jsx52(FieldLabel, { htmlFor: fieldId, children: label }),
4138
4148
  /* @__PURE__ */ jsx52("span", { className: "fd-num", style: { color: "var(--text-2)" }, children: format(v) })
4139
4149
  ] }) : null,
4140
- /* @__PURE__ */ jsxs47("div", { className: "fd-slider", children: [
4150
+ /* @__PURE__ */ jsxs48("div", { className: "fd-slider", children: [
4141
4151
  /* @__PURE__ */ jsx52("span", { className: "fd-slider-fill", style: { width: pct + "%" } }),
4142
4152
  showChip && dragging ? /* @__PURE__ */ jsx52("span", { className: "fd-slider-chip", style: { left: pct + "%" }, children: format(v) }) : null,
4143
4153
  /* @__PURE__ */ jsx52(
@@ -4163,8 +4173,8 @@ function Slider({
4163
4173
  }
4164
4174
 
4165
4175
  // src/components/forms/RangeSlider.tsx
4166
- import * as React26 from "react";
4167
- 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";
4168
4178
  function RangeSlider({
4169
4179
  label,
4170
4180
  min = 0,
@@ -4183,9 +4193,9 @@ function RangeSlider({
4183
4193
  }) {
4184
4194
  const fmt2 = format || ((v) => String(v));
4185
4195
  const [a, b] = value || [min, max];
4186
- const [drag, setDrag] = React26.useState(null);
4187
- const [focus, setFocus] = React26.useState(null);
4188
- const railRef = React26.useRef(null);
4196
+ const [drag, setDrag] = React27.useState(null);
4197
+ const [focus, setFocus] = React27.useState(null);
4198
+ const railRef = React27.useRef(null);
4189
4199
  const pct = (v) => max === min ? 0 : (v - min) / (max - min) * 100;
4190
4200
  const clampPair = (i, v) => {
4191
4201
  v = Math.min(max, Math.max(min, Math.round(v / step) * step));
@@ -4200,7 +4210,7 @@ function RangeSlider({
4200
4210
  const r = railRef.current.getBoundingClientRect();
4201
4211
  return min + Math.min(1, Math.max(0, (e.clientX - r.left) / r.width)) * (max - min);
4202
4212
  };
4203
- React26.useEffect(() => {
4213
+ React27.useEffect(() => {
4204
4214
  if (drag === null) return;
4205
4215
  const mv = (e) => onChange && onChange(clampPair(drag, fromEvent(e)));
4206
4216
  const upH = () => setDrag(null);
@@ -4269,19 +4279,19 @@ function RangeSlider({
4269
4279
  };
4270
4280
  const showChip = (i) => drag === i || focus === i;
4271
4281
  const hasLabels = marks.some((m) => m.label);
4272
- return /* @__PURE__ */ jsxs48("div", { className: ["fd-field", className].filter(Boolean).join(" "), ...rest, children: [
4273
- label ? /* @__PURE__ */ jsxs48("div", { className: "fd-row", style: { justifyContent: "space-between", gap: 12 }, children: [
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: [
4274
4284
  /* @__PURE__ */ jsx53("span", { className: "fd-field-label", children: label }),
4275
- /* @__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: [
4276
4286
  fmt2(a),
4277
4287
  " \u2013 ",
4278
4288
  fmt2(b)
4279
4289
  ] })
4280
4290
  ] }) : null,
4281
- /* @__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: [
4282
4292
  /* @__PURE__ */ jsx53("span", { className: "fd-range-rail", ref: railRef }),
4283
4293
  /* @__PURE__ */ jsx53("span", { className: "fd-range-fill", style: { left: pct(a) + "%", width: pct(b) - pct(a) + "%" } }),
4284
- marks.map((m) => /* @__PURE__ */ jsxs48(React26.Fragment, { children: [
4294
+ marks.map((m) => /* @__PURE__ */ jsxs49(React27.Fragment, { children: [
4285
4295
  /* @__PURE__ */ jsx53("span", { className: "fd-range-mark" + (m.value >= a && m.value <= b ? " is-in" : ""), style: { left: pct(m.value) + "%" } }),
4286
4296
  m.label ? /* @__PURE__ */ jsx53("span", { className: "fd-range-mark-label", style: { left: pct(m.value) + "%" }, children: m.label }) : null
4287
4297
  ] }, m.value)),
@@ -4310,8 +4320,8 @@ function RangeSlider({
4310
4320
  }
4311
4321
 
4312
4322
  // src/components/forms/Dropzone.tsx
4313
- import * as React27 from "react";
4314
- 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";
4315
4325
  function Dropzone({
4316
4326
  onFiles,
4317
4327
  onReject,
@@ -4325,8 +4335,8 @@ function Dropzone({
4325
4335
  className = "",
4326
4336
  style
4327
4337
  }) {
4328
- const [over, setOver] = React27.useState(false);
4329
- const depth = React27.useRef(0);
4338
+ const [over, setOver] = React28.useState(false);
4339
+ const depth = React28.useRef(0);
4330
4340
  const has = (e) => {
4331
4341
  const dt = e.dataTransfer;
4332
4342
  if (!dt) return false;
@@ -4356,7 +4366,7 @@ function Dropzone({
4356
4366
  if (rejected.length && onReject) onReject(rejected);
4357
4367
  if (accepted.length && onFiles) onFiles(accepted);
4358
4368
  };
4359
- return /* @__PURE__ */ jsxs49(
4369
+ return /* @__PURE__ */ jsxs50(
4360
4370
  "div",
4361
4371
  {
4362
4372
  className: ["fd-dropzone", over ? "is-over" : "", className].filter(Boolean).join(" "),
@@ -4367,7 +4377,7 @@ function Dropzone({
4367
4377
  onDrop: drop,
4368
4378
  children: [
4369
4379
  children,
4370
- 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: [
4371
4381
  /* @__PURE__ */ jsx54("i", { className: "ph ph-tray-arrow-down" }),
4372
4382
  /* @__PURE__ */ jsx54("span", { className: "fd-dropzone-label", children: label }),
4373
4383
  hint ? /* @__PURE__ */ jsx54("span", { className: "fd-dropzone-hint", children: hint }) : null
@@ -4388,8 +4398,8 @@ function FilePickButton({
4388
4398
  className = "",
4389
4399
  children
4390
4400
  }) {
4391
- const ref = React27.useRef(null);
4392
- return /* @__PURE__ */ jsxs49(React27.Fragment, { children: [
4401
+ const ref = React28.useRef(null);
4402
+ return /* @__PURE__ */ jsxs50(React28.Fragment, { children: [
4393
4403
  /* @__PURE__ */ jsx54(
4394
4404
  "button",
4395
4405
  {
@@ -4422,10 +4432,10 @@ function FilePickButton({
4422
4432
  }
4423
4433
  function useStagedFiles(upload, opts) {
4424
4434
  const o = opts || {};
4425
- const [items, setItems] = React27.useState([]);
4426
- const controllers = React27.useRef({});
4435
+ const [items, setItems] = React28.useState([]);
4436
+ const controllers = React28.useRef({});
4427
4437
  const patch = (id, next) => setItems((list) => list.map((f) => f.id === id ? Object.assign({}, f, next) : f));
4428
- const run = React27.useCallback((att) => {
4438
+ const run = React28.useCallback((att) => {
4429
4439
  if (!upload) return;
4430
4440
  const ac = typeof AbortController !== "undefined" ? new AbortController() : null;
4431
4441
  controllers.current[att.id] = ac;
@@ -4442,14 +4452,14 @@ function useStagedFiles(upload, opts) {
4442
4452
  delete controllers.current[att.id];
4443
4453
  });
4444
4454
  }, [upload]);
4445
- const add = React27.useCallback((files) => {
4455
+ const add = React28.useCallback((files) => {
4446
4456
  if (!upload) return [];
4447
4457
  const atts = Array.from(files).map((f) => toAttachment(f));
4448
4458
  setItems((list) => list.concat(atts));
4449
4459
  atts.forEach(run);
4450
4460
  return atts;
4451
4461
  }, [upload, run]);
4452
- const remove = React27.useCallback((att) => {
4462
+ const remove = React28.useCallback((att) => {
4453
4463
  const ac = controllers.current[att.id];
4454
4464
  if (ac) {
4455
4465
  try {
@@ -4460,10 +4470,10 @@ function useStagedFiles(upload, opts) {
4460
4470
  }
4461
4471
  setItems((list) => list.filter((f) => f.id !== att.id));
4462
4472
  }, []);
4463
- const retry = React27.useCallback((att) => {
4473
+ const retry = React28.useCallback((att) => {
4464
4474
  run(att);
4465
4475
  }, [run]);
4466
- const clear = React27.useCallback(() => {
4476
+ const clear = React28.useCallback(() => {
4467
4477
  Object.values(controllers.current).forEach((ac) => {
4468
4478
  try {
4469
4479
  ac && ac.abort();
@@ -4479,7 +4489,7 @@ function useStagedFiles(upload, opts) {
4479
4489
  var DropzoneKit = { useStagedFiles };
4480
4490
 
4481
4491
  // src/components/forms/FileGrid.tsx
4482
- import { jsx as jsx55, jsxs as jsxs50 } from "react/jsx-runtime";
4492
+ import { jsx as jsx55, jsxs as jsxs51 } from "react/jsx-runtime";
4483
4493
  var truncateMiddle = (name, max = 34) => {
4484
4494
  if (!name || name.length <= max) return name;
4485
4495
  const ext = /\.[A-Za-z0-9]+$/.exec(name);
@@ -4497,8 +4507,8 @@ function FileChip({ file, onOpen, onRemove, onRetry, compact: compact3 = false,
4497
4507
  const thumb = file.thumb && file.thumb.url || (image ? file.blobUrl || file.url : null);
4498
4508
  const meta = file.meta || (file.size ? formatBytes(file.size) : "");
4499
4509
  const clickable = !!onOpen && !uploading;
4500
- return /* @__PURE__ */ jsxs50("div", { className: ["fd-file", compact3 ? "is-compact" : "", file.error ? "is-error" : "", uploading ? "is-uploading" : "", className].filter(Boolean).join(" "), children: [
4501
- /* @__PURE__ */ jsxs50(
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(
4502
4512
  "button",
4503
4513
  {
4504
4514
  type: "button",
@@ -4507,16 +4517,16 @@ function FileChip({ file, onOpen, onRemove, onRetry, compact: compact3 = false,
4507
4517
  onClick: clickable ? () => onOpen(file) : void 0,
4508
4518
  title: file.name + (meta ? " \xB7 " + meta : ""),
4509
4519
  children: [
4510
- /* @__PURE__ */ jsxs50("span", { className: "fd-file-icon", children: [
4520
+ /* @__PURE__ */ jsxs51("span", { className: "fd-file-icon", children: [
4511
4521
  thumb ? /* @__PURE__ */ jsx55("img", { src: thumb, alt: "" }) : /* @__PURE__ */ jsx55("i", { className: "ph ph-" + iconForMime(file.mime, file.name), "aria-hidden": "true" }),
4512
4522
  (file.mime || "").startsWith("video/") ? /* @__PURE__ */ jsx55("i", { className: "ph ph-play fd-file-play", "aria-hidden": "true" }) : null
4513
4523
  ] }),
4514
- /* @__PURE__ */ jsxs50("span", { className: "fd-file-text", children: [
4524
+ /* @__PURE__ */ jsxs51("span", { className: "fd-file-text", children: [
4515
4525
  /* @__PURE__ */ jsx55("span", { className: "fd-file-name", children: truncateMiddle(file.name, compact3 ? 26 : 40) }),
4516
- /* @__PURE__ */ jsx55("span", { className: "fd-file-meta", children: file.error ? /* @__PURE__ */ jsxs50("span", { className: "fd-file-err", children: [
4526
+ /* @__PURE__ */ jsx55("span", { className: "fd-file-meta", children: file.error ? /* @__PURE__ */ jsxs51("span", { className: "fd-file-err", children: [
4517
4527
  /* @__PURE__ */ jsx55("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
4518
4528
  file.error
4519
- ] }) : uploading ? /* @__PURE__ */ jsxs50("span", { className: "fd-tabular", children: [
4529
+ ] }) : uploading ? /* @__PURE__ */ jsxs51("span", { className: "fd-tabular", children: [
4520
4530
  Math.round(file.progress),
4521
4531
  "% uploaded"
4522
4532
  ] }) : meta })
@@ -4533,10 +4543,10 @@ function FileTile({ file, onOpen, onRemove, maxHeight = 200, className = "" }) {
4533
4543
  if (!file) return null;
4534
4544
  const src = file.thumb && file.thumb.url || file.blobUrl || file.url;
4535
4545
  const uploading = file.progress != null && file.progress < 100 && !file.error;
4536
- return /* @__PURE__ */ jsxs50("figure", { className: ["fd-tile", uploading ? "is-uploading" : "", file.error ? "is-error" : "", className].filter(Boolean).join(" "), children: [
4546
+ return /* @__PURE__ */ jsxs51("figure", { className: ["fd-tile", uploading ? "is-uploading" : "", file.error ? "is-error" : "", className].filter(Boolean).join(" "), children: [
4537
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" }) }) }),
4538
4548
  uploading ? /* @__PURE__ */ jsx55(Progress, { value: file.progress }) : null,
4539
- file.error ? /* @__PURE__ */ jsxs50("figcaption", { className: "fd-tile-err", children: [
4549
+ file.error ? /* @__PURE__ */ jsxs51("figcaption", { className: "fd-tile-err", children: [
4540
4550
  /* @__PURE__ */ jsx55("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
4541
4551
  file.error
4542
4552
  ] }) : null,
@@ -4560,9 +4570,9 @@ function FileCell({ file, onOpen, onRemove, onRetry }) {
4560
4570
  const image = isImage(file.mime, file.name);
4561
4571
  const thumb = file.thumb && file.thumb.url || (image ? file.blobUrl || file.url : null);
4562
4572
  const label = file.name + (file.size ? " \xB7 " + formatBytes(file.size) : "");
4563
- return /* @__PURE__ */ jsxs50("div", { className: ["fd-cell", file.error ? "is-error" : "", uploading ? "is-uploading" : ""].filter(Boolean).join(" "), title: file.error ? file.name + " \u2014 " + file.error : label, children: [
4564
- /* @__PURE__ */ jsxs50("button", { type: "button", className: "fd-cell-main", onClick: onOpen ? () => onOpen(file) : void 0, disabled: !onOpen || uploading, "aria-label": "Open " + file.name, children: [
4565
- thumb ? /* @__PURE__ */ jsx55("img", { src: thumb, alt: "" }) : /* @__PURE__ */ jsxs50("span", { className: "fd-cell-doc", children: [
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: [
4566
4576
  /* @__PURE__ */ jsx55("i", { className: "ph ph-" + iconForMime(file.mime, file.name), "aria-hidden": "true" }),
4567
4577
  /* @__PURE__ */ jsx55("span", { className: "fd-cell-name", children: shortName(file.name) }),
4568
4578
  /* @__PURE__ */ jsx55("span", { className: "fd-cell-size", children: file.meta || formatBytes(file.size) })
@@ -4580,15 +4590,15 @@ function FileGrid({ files = [], onOpen, onRemove, onRetry, tiles = true, maxHeig
4580
4590
  if (!list.length) return null;
4581
4591
  const pics = tiles ? list.filter((f) => isImage(f.mime, f.name)) : [];
4582
4592
  const rest = list.filter((f) => pics.indexOf(f) === -1);
4583
- 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: [
4584
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,
4585
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
4586
4596
  ] });
4587
4597
  }
4588
4598
 
4589
4599
  // src/components/forms/MarkdownEditor.tsx
4590
- import * as React28 from "react";
4591
- 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";
4592
4602
  var isMac = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent || "");
4593
4603
  var INLINE_RE = /(\*\*\*[^*\n]+\*\*\*|\*\*[^*\n]+\*\*|__[^_\n]+__|~~[^~\n]+~~|`[^`\n]+`|\*[^*\s][^*\n]*\*|(?<![A-Za-z0-9_])_[^_\s][^_\n]*_|\[[^\]\n]*\]\([^)\s\n]*\)|https?:\/\/\S+)/g;
4594
4604
  function inlineParts(text) {
@@ -4801,7 +4811,7 @@ function syncDom(root, value) {
4801
4811
  while (root.children.length > lines.length) root.removeChild(root.lastChild);
4802
4812
  }
4803
4813
  var LIST_CONT = RE_LI;
4804
- var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
4814
+ var MarkdownEditor = React29.forwardRef(function MarkdownEditor2({
4805
4815
  value = "",
4806
4816
  onChange,
4807
4817
  onSubmit,
@@ -4820,10 +4830,10 @@ var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
4820
4830
  className = "",
4821
4831
  id
4822
4832
  }, ref) {
4823
- const boxRef = React28.useRef(null);
4824
- const composing = React28.useRef(false);
4825
- const pendingCaret = React28.useRef(null);
4826
- React28.useLayoutEffect(() => {
4833
+ const boxRef = React29.useRef(null);
4834
+ const composing = React29.useRef(false);
4835
+ const pendingCaret = React29.useRef(null);
4836
+ React29.useLayoutEffect(() => {
4827
4837
  const root = boxRef.current;
4828
4838
  if (!root || composing.current) return;
4829
4839
  const active = document.activeElement === root || root.contains(document.activeElement);
@@ -4832,7 +4842,7 @@ var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
4832
4842
  pendingCaret.current = null;
4833
4843
  if (active && caret != null) placeCaret(root, caret);
4834
4844
  }, [value]);
4835
- React28.useEffect(() => {
4845
+ React29.useEffect(() => {
4836
4846
  if (autoFocus && boxRef.current) boxRef.current.focus();
4837
4847
  }, [autoFocus]);
4838
4848
  const caretNow = () => {
@@ -4899,7 +4909,7 @@ var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
4899
4909
  api.replaceRange(from, to, next, from + next.length);
4900
4910
  }
4901
4911
  };
4902
- React28.useImperativeHandle(ref, () => api);
4912
+ React29.useImperativeHandle(ref, () => api);
4903
4913
  function detect(text, caret) {
4904
4914
  if (!onTrigger) return;
4905
4915
  const upto = text.slice(0, caret);
@@ -5012,7 +5022,7 @@ var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
5012
5022
  api.replaceRange(s.start, s.end, text.replace(/\r\n?/g, "\n"));
5013
5023
  };
5014
5024
  const lh = 1.55;
5015
- 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: [
5016
5026
  /* @__PURE__ */ jsx56(
5017
5027
  "div",
5018
5028
  {
@@ -5051,10 +5061,10 @@ var MarkdownEditor = React28.forwardRef(function MarkdownEditor2({
5051
5061
  });
5052
5062
 
5053
5063
  // src/components/platform/AccountMenu.tsx
5054
- import * as React30 from "react";
5064
+ import * as React31 from "react";
5055
5065
 
5056
5066
  // src/kits/session.ts
5057
- import * as React29 from "react";
5067
+ import * as React30 from "react";
5058
5068
  var PERMISSION_CATALOG = [
5059
5069
  { group: "Plans", items: [
5060
5070
  { key: "plan.view", label: "View plans", detail: "Read any plan in the workspace." },
@@ -6621,8 +6631,8 @@ function roadmap(overrides) {
6621
6631
  };
6622
6632
  }
6623
6633
  function useSession() {
6624
- const [s, setS] = React29.useState(getSession);
6625
- React29.useEffect(() => subscribe(setS), []);
6634
+ const [s, setS] = React30.useState(getSession);
6635
+ React30.useEffect(() => subscribe(setS), []);
6626
6636
  return s;
6627
6637
  }
6628
6638
  var SessionKit = {
@@ -6655,7 +6665,7 @@ var SessionKit = {
6655
6665
  };
6656
6666
 
6657
6667
  // src/components/platform/AccountMenu.tsx
6658
- 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";
6659
6669
  var DEFAULT_LINKS = [
6660
6670
  { id: "profile", label: "Your profile", icon: "user-circle", href: "../admin/index.html#profile" },
6661
6671
  { id: "preferences", label: "Preferences", icon: "sliders-horizontal", href: "../admin/index.html#preferences" }
@@ -6666,7 +6676,7 @@ var DEFAULT_ADMIN_LINKS = [
6666
6676
  { id: "flags", label: "Feature flags", icon: "toggle-right", href: "../admin/index.html#flags", perm: "flags.manage" }
6667
6677
  ];
6668
6678
  function Item({ item, onPick }) {
6669
- return /* @__PURE__ */ jsxs52(
6679
+ return /* @__PURE__ */ jsxs53(
6670
6680
  "button",
6671
6681
  {
6672
6682
  type: "button",
@@ -6692,9 +6702,9 @@ function AccountMenu({
6692
6702
  ...rest
6693
6703
  }) {
6694
6704
  const session = SessionKit.useSession();
6695
- const [open, setOpen] = React30.useState(false);
6696
- const [switching, setSwitching] = React30.useState(false);
6697
- 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);
6698
6708
  const user = session.user;
6699
6709
  const visibleAdmin = adminLinks.filter((l) => !l.perm || SessionKit.can(l.perm));
6700
6710
  const pick = (item) => {
@@ -6708,8 +6718,8 @@ function AccountMenu({
6708
6718
  if (onSignOut) return onSignOut();
6709
6719
  window.alert("Signed out. (Simulated \u2014 no auth provider is wired up.)");
6710
6720
  };
6711
- return /* @__PURE__ */ jsxs52(Fragment14, { children: [
6712
- /* @__PURE__ */ jsxs52(
6721
+ return /* @__PURE__ */ jsxs53(Fragment14, { children: [
6722
+ /* @__PURE__ */ jsxs53(
6713
6723
  "button",
6714
6724
  {
6715
6725
  type: "button",
@@ -6726,27 +6736,27 @@ function AccountMenu({
6726
6736
  ]
6727
6737
  }
6728
6738
  ),
6729
- /* @__PURE__ */ jsx57(Popover, { open, anchorRef: ref, onClose: () => setOpen(false), placement: "bottom-end", width: 272, children: /* @__PURE__ */ jsxs52("div", { role: "menu", className: "fd-stack", style: { gap: 0 }, children: [
6730
- /* @__PURE__ */ jsxs52("div", { className: "fd-row", style: { gap: 10, padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
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: [
6731
6741
  /* @__PURE__ */ jsx57(Avatar, { name: user.name }),
6732
- /* @__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: [
6733
6743
  /* @__PURE__ */ jsx57("span", { className: "fd-body-sm", style: { fontWeight: 700 }, children: user.name }),
6734
6744
  /* @__PURE__ */ jsx57("span", { className: "fd-body-sm fd-muted fd-table-trunc", children: user.email })
6735
6745
  ] })
6736
6746
  ] }),
6737
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,
6738
6748
  /* @__PURE__ */ jsx57("div", { className: "fd-acct-group", children: links.map((l) => /* @__PURE__ */ jsx57(Item, { item: l, onPick: pick }, l.id)) }),
6739
- visibleAdmin.length ? /* @__PURE__ */ jsxs52("div", { className: "fd-acct-group", style: { borderTop: "1px solid var(--border)" }, children: [
6749
+ visibleAdmin.length ? /* @__PURE__ */ jsxs53("div", { className: "fd-acct-group", style: { borderTop: "1px solid var(--border)" }, children: [
6740
6750
  /* @__PURE__ */ jsx57("span", { className: "fd-overline fd-muted", style: { padding: "8px 14px 4px", display: "block" }, children: "Administration" }),
6741
6751
  visibleAdmin.map((l) => /* @__PURE__ */ jsx57(Item, { item: l, onPick: pick }, l.id))
6742
6752
  ] }) : null,
6743
- allowUserSwitch ? /* @__PURE__ */ jsxs52("div", { className: "fd-acct-group", style: { borderTop: "1px solid var(--border)" }, children: [
6744
- /* @__PURE__ */ jsxs52("button", { type: "button", role: "menuitem", className: "fd-acct-item", onClick: () => setSwitching((s) => !s), children: [
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: [
6745
6755
  /* @__PURE__ */ jsx57("i", { className: "ph ph-user-switch", "aria-hidden": "true" }),
6746
6756
  /* @__PURE__ */ jsx57("span", { style: { flex: 1 }, children: "View as another member" }),
6747
6757
  /* @__PURE__ */ jsx57("i", { className: "ph ph-caret-" + (switching ? "up" : "down"), "aria-hidden": "true", style: { fontSize: 11 } })
6748
6758
  ] }),
6749
- 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(
6750
6760
  "button",
6751
6761
  {
6752
6762
  type: "button",
@@ -6759,7 +6769,7 @@ function AccountMenu({
6759
6769
  },
6760
6770
  children: [
6761
6771
  /* @__PURE__ */ jsx57(Avatar, { name: u.name, size: "sm" }),
6762
- /* @__PURE__ */ jsxs52("span", { className: "fd-stack", style: { gap: 0, flex: 1, minWidth: 0, alignItems: "flex-start" }, children: [
6772
+ /* @__PURE__ */ jsxs53("span", { className: "fd-stack", style: { gap: 0, flex: 1, minWidth: 0, alignItems: "flex-start" }, children: [
6763
6773
  /* @__PURE__ */ jsx57("span", { style: { fontWeight: u.id === user.id ? 700 : 500 }, children: u.name }),
6764
6774
  /* @__PURE__ */ jsx57("span", { className: "fd-muted", style: { fontSize: 11.5 }, children: u.roles.join(", ") })
6765
6775
  ] }),
@@ -6769,7 +6779,7 @@ function AccountMenu({
6769
6779
  u.id
6770
6780
  )) }) : null
6771
6781
  ] }) : null,
6772
- /* @__PURE__ */ jsx57("div", { className: "fd-acct-group", style: { borderTop: "1px solid var(--border)" }, children: /* @__PURE__ */ jsxs52("button", { type: "button", role: "menuitem", className: "fd-acct-item", "data-danger": "true", onClick: signOut, children: [
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: [
6773
6783
  /* @__PURE__ */ jsx57("i", { className: "ph ph-sign-out", "aria-hidden": "true" }),
6774
6784
  /* @__PURE__ */ jsx57("span", { style: { flex: 1 }, children: "Sign out" })
6775
6785
  ] }) })
@@ -6778,14 +6788,14 @@ function AccountMenu({
6778
6788
  }
6779
6789
 
6780
6790
  // src/components/platform/ApiSpecBrowser.tsx
6781
- import * as React31 from "react";
6782
- 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";
6783
6793
  var METHOD_TONE = { GET: "success", POST: "info", PATCH: "warning", PUT: "warning", DELETE: "danger" };
6784
6794
  function Json({ obj }) {
6785
6795
  return /* @__PURE__ */ jsx58("pre", { className: "fd-json", children: JSON.stringify(obj, null, 2) });
6786
6796
  }
6787
6797
  function Endpoint({ s, onRequest }) {
6788
- const [tried, setTried] = React31.useState(null);
6798
+ const [tried, setTried] = React32.useState(null);
6789
6799
  const run = async () => {
6790
6800
  setTried("busy");
6791
6801
  const t0 = (window.performance || Date).now();
@@ -6796,13 +6806,13 @@ function Endpoint({ s, onRequest }) {
6796
6806
  setTried({ ms: Math.round((window.performance || Date).now() - t0), error: String(e && e.message || e) });
6797
6807
  }
6798
6808
  };
6799
- return /* @__PURE__ */ jsx58(Card, { elevation: "flat", padded: false, children: /* @__PURE__ */ jsxs53("div", { className: "fd-stack", style: { gap: 0 }, children: [
6800
- /* @__PURE__ */ jsxs53("div", { className: "fd-row", style: { gap: 10, padding: "14px 18px", flexWrap: "wrap" }, children: [
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: [
6801
6811
  /* @__PURE__ */ jsx58(Badge, { tone: METHOD_TONE[s.method] || "neutral", children: s.method }),
6802
6812
  /* @__PURE__ */ jsx58("code", { className: "fd-mono", style: { fontSize: 12.5, fontWeight: 600, color: "var(--text)", wordBreak: "break-all" }, children: s.path }),
6803
6813
  s.isList ? /* @__PURE__ */ jsx58(Badge, { tone: "neutral", icon: "rows", children: "Paged list" }) : null,
6804
6814
  /* @__PURE__ */ jsx58("span", { style: { flex: 1 } }),
6805
- /* @__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: [
6806
6816
  s.latency[0],
6807
6817
  "\u2013",
6808
6818
  s.latency[1],
@@ -6810,31 +6820,31 @@ function Endpoint({ s, onRequest }) {
6810
6820
  ] }),
6811
6821
  /* @__PURE__ */ jsx58(Button, { size: "sm", variant: "secondary", icon: "play", loading: tried === "busy", onClick: run, children: "Try it" })
6812
6822
  ] }),
6813
- /* @__PURE__ */ jsxs53("div", { className: "fd-stack", style: { gap: 14, padding: "0 18px 16px" }, children: [
6814
- /* @__PURE__ */ jsxs53("div", { className: "fd-stack", style: { gap: 6 }, children: [
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: [
6815
6825
  /* @__PURE__ */ jsx58("span", { className: "fd-body-sm", style: { fontWeight: 700 }, children: s.title }),
6816
6826
  /* @__PURE__ */ jsx58("p", { className: "fd-body-sm fd-secondary", style: { margin: 0, textWrap: "pretty" }, children: s.purpose }),
6817
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
6818
6828
  ] }),
6819
- /* @__PURE__ */ jsxs53("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(280px,1fr))", gap: 12, alignItems: "start" }, children: [
6820
- s.request ? /* @__PURE__ */ jsxs53("div", { className: "fd-stack", style: { gap: 6 }, children: [
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: [
6821
6831
  /* @__PURE__ */ jsx58("span", { className: "fd-overline fd-muted", children: "Request body" }),
6822
6832
  /* @__PURE__ */ jsx58(Json, { obj: s.request })
6823
6833
  ] }) : null,
6824
- 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: [
6825
6835
  /* @__PURE__ */ jsx58("span", { className: "fd-overline fd-muted", children: "Query" }),
6826
6836
  /* @__PURE__ */ jsx58(Json, { obj: s.query })
6827
6837
  ] }) : null,
6828
- /* @__PURE__ */ jsxs53("div", { className: "fd-stack", style: { gap: 6 }, children: [
6838
+ /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 6 }, children: [
6829
6839
  /* @__PURE__ */ jsx58("span", { className: "fd-overline fd-muted", children: "Response 200" }),
6830
6840
  /* @__PURE__ */ jsx58(Json, { obj: s.response })
6831
6841
  ] })
6832
6842
  ] }),
6833
6843
  s.notes ? /* @__PURE__ */ jsx58(Flag, { tone: "info", statement: "Implementation note", cost: s.notes, actions: null }) : null,
6834
- tried && tried !== "busy" ? /* @__PURE__ */ jsxs53("div", { className: "fd-stack", style: { gap: 6 }, children: [
6835
- /* @__PURE__ */ jsxs53("span", { className: "fd-row", style: { gap: 8 }, children: [
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: [
6836
6846
  /* @__PURE__ */ jsx58("span", { className: "fd-overline fd-muted", children: "Simulated response" }),
6837
- /* @__PURE__ */ jsxs53(Badge, { tone: tried.error ? "danger" : "success", icon: "timer", children: [
6847
+ /* @__PURE__ */ jsxs54(Badge, { tone: tried.error ? "danger" : "success", icon: "timer", children: [
6838
6848
  tried.ms,
6839
6849
  "ms"
6840
6850
  ] })
@@ -6858,29 +6868,29 @@ function ApiSpecBrowser({
6858
6868
  className = "",
6859
6869
  ...rest
6860
6870
  }) {
6861
- const [q, setQ] = React31.useState("");
6862
- const [method, setMethod] = React31.useState(null);
6863
- const [mod, setMod] = React31.useState(null);
6864
- const [listOnly, setListOnly] = React31.useState(false);
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);
6865
6875
  const activeModule = modules && modules.find((m) => m.id === mod);
6866
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())));
6867
6877
  const effGroups = groups && groups.length ? groups : [["All endpoints", spec.map((s) => s.id)]];
6868
6878
  const methods = [...new Set(spec.map((s) => s.method))];
6869
6879
  const listCount = spec.filter((s) => s.isList).length;
6870
- return /* @__PURE__ */ jsxs53("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 20, maxWidth: 1100 }, ...rest, children: [
6871
- /* @__PURE__ */ jsxs53("div", { className: "fd-stack", style: { gap: 10 }, children: [
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: [
6872
6882
  kicker ? /* @__PURE__ */ jsx58("span", { className: "fd-overline fd-muted", children: kicker }) : null,
6873
6883
  /* @__PURE__ */ jsx58("h1", { className: "fd-h1", style: { margin: 0 }, children: title }),
6874
6884
  lede ? /* @__PURE__ */ jsx58("p", { className: "fd-body fd-secondary fd-prose", style: { margin: 0 }, children: lede }) : null
6875
6885
  ] }),
6876
- 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: [
6877
6887
  /* @__PURE__ */ jsx58("span", { className: "fd-overline fd-muted", children: "Filter by screen \u2014 every endpoint that screen depends on" }),
6878
- /* @__PURE__ */ jsxs53("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: [
6879
- /* @__PURE__ */ jsxs53(Tag, { icon: "stack", selected: !mod, onClick: () => setMod(null), children: [
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: [
6880
6890
  "All screens ",
6881
6891
  /* @__PURE__ */ jsx58("span", { className: "fd-mono", children: spec.length })
6882
6892
  ] }),
6883
- 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: [
6884
6894
  m.label,
6885
6895
  " ",
6886
6896
  /* @__PURE__ */ jsx58("span", { className: "fd-mono", children: m.endpoints.length })
@@ -6897,19 +6907,19 @@ function ApiSpecBrowser({
6897
6907
  ) : null
6898
6908
  ] }) : null,
6899
6909
  sourceNote ? /* @__PURE__ */ jsx58(Flag, { tone: "info", statement: "Design-first: this page is the spec.", cost: sourceNote, actions: null }) : null,
6900
- /* @__PURE__ */ jsxs53("div", { className: "fd-row", style: { gap: 10, flexWrap: "wrap" }, children: [
6910
+ /* @__PURE__ */ jsxs54("div", { className: "fd-row", style: { gap: 10, flexWrap: "wrap" }, children: [
6901
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 } }),
6902
- 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: [
6903
6913
  m,
6904
6914
  " ",
6905
6915
  /* @__PURE__ */ jsx58("span", { className: "fd-mono", children: spec.filter((s) => s.method === m).length })
6906
6916
  ] }, m)),
6907
- 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: [
6908
6918
  "Paged lists ",
6909
6919
  /* @__PURE__ */ jsx58("span", { className: "fd-mono", children: listCount })
6910
6920
  ] }) : null,
6911
6921
  /* @__PURE__ */ jsx58("span", { style: { flex: 1 } }),
6912
- /* @__PURE__ */ jsxs53("span", { className: "fd-body-sm fd-muted", children: [
6922
+ /* @__PURE__ */ jsxs54("span", { className: "fd-body-sm fd-muted", children: [
6913
6923
  hits.length,
6914
6924
  " of ",
6915
6925
  spec.length,
@@ -6920,18 +6930,18 @@ function ApiSpecBrowser({
6920
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]) => {
6921
6931
  const items = hits.filter((s) => ids.indexOf(s.id) >= 0);
6922
6932
  if (!items.length) return null;
6923
- return /* @__PURE__ */ jsxs53("div", { className: "fd-stack", style: { gap: 12 }, children: [
6933
+ return /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 12 }, children: [
6924
6934
  /* @__PURE__ */ jsx58("span", { className: "fd-label-lg", children: g }),
6925
6935
  items.map((s) => /* @__PURE__ */ jsx58(Endpoint, { s, onRequest }, s.id))
6926
6936
  ] }, g);
6927
6937
  }),
6928
- conventions && conventions.length ? /* @__PURE__ */ jsx58(Card, { title: "Cross-cutting conventions", elevation: "flat", children: /* @__PURE__ */ jsx58("div", { className: "fd-stack", style: { gap: 10 }, children: conventions.map(([k, v]) => /* @__PURE__ */ jsxs53("div", { className: "fd-row", style: { gap: 12, alignItems: "flex-start" }, children: [
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: [
6929
6939
  /* @__PURE__ */ jsx58("span", { className: "fd-overline fd-muted", style: { width: 110, flex: "none", paddingTop: 2 }, children: k }),
6930
6940
  /* @__PURE__ */ jsx58("span", { className: "fd-body-sm fd-secondary", style: { textWrap: "pretty" }, children: v })
6931
6941
  ] }, k)) }) }) : null,
6932
- openQuestions && openQuestions.length ? /* @__PURE__ */ jsx58(Collapsible, { icon: "list-checks", title: "Open questions before implementation", subtitle: openQuestions.length + " unresolved", children: /* @__PURE__ */ jsx58("div", { className: "fd-stack", style: { gap: 8 }, children: openQuestions.map(([id, question, why]) => /* @__PURE__ */ jsxs53("div", { className: "fd-row", style: { gap: 10, alignItems: "flex-start", padding: "8px 0", borderTop: "1px solid var(--border)" }, children: [
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: [
6933
6943
  /* @__PURE__ */ jsx58(Badge, { tone: "danger", children: id }),
6934
- /* @__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: [
6935
6945
  /* @__PURE__ */ jsx58("span", { className: "fd-body-sm", style: { fontWeight: 600 }, children: question }),
6936
6946
  /* @__PURE__ */ jsx58("span", { className: "fd-body-sm fd-muted", children: why })
6937
6947
  ] })
@@ -6940,8 +6950,8 @@ function ApiSpecBrowser({
6940
6950
  }
6941
6951
 
6942
6952
  // src/components/platform/ProfilePage.tsx
6943
- import * as React32 from "react";
6944
- 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";
6945
6955
  var TIMEZONES = ["America/New_York", "America/Chicago", "America/Denver", "America/Los_Angeles", "America/Anchorage", "Pacific/Honolulu", "Europe/London", "Europe/Berlin"];
6946
6956
  var NOTIFY = [
6947
6957
  { key: "planShared", label: "A plan is shared with me", detail: "Someone sends you a plan or a client link." },
@@ -6953,7 +6963,7 @@ var NOTIFY = [
6953
6963
  function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSessions = true, className = "", ...rest }) {
6954
6964
  const session = SessionKit.useSession();
6955
6965
  const user = userProp || session.user;
6956
- const [draft, setDraft] = React32.useState(() => ({
6966
+ const [draft, setDraft] = React33.useState(() => ({
6957
6967
  name: user.name || "",
6958
6968
  title: user.title || "",
6959
6969
  email: user.email || "",
@@ -6962,8 +6972,8 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
6962
6972
  bio: user.bio || "",
6963
6973
  notify: user.notify || { planShared: true, planChanged: true, goalMissed: true, flagChanged: false, weekly: true }
6964
6974
  }));
6965
- const [saving, setSaving] = React32.useState(false);
6966
- const [saved, setSaved] = React32.useState(false);
6975
+ const [saving, setSaving] = React33.useState(false);
6976
+ const [saved, setSaved] = React33.useState(false);
6967
6977
  const set = (k, v) => {
6968
6978
  setDraft((d) => Object.assign({}, d, { [k]: v }));
6969
6979
  setSaved(false);
@@ -6985,22 +6995,22 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
6985
6995
  { id: "s2", device: "iPhone 15 \xB7 Safari", where: "Denver, CO", when: "2 hours ago" },
6986
6996
  { id: "s3", device: "Windows \xB7 Edge", where: "Chicago, IL", when: "Aug 12" }
6987
6997
  ];
6988
- return /* @__PURE__ */ jsxs54("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 20, maxWidth: 860 }, ...rest, children: [
6989
- /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 10 }, children: [
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: [
6990
7000
  /* @__PURE__ */ jsx59("span", { className: "fd-overline fd-muted", children: "Account" }),
6991
7001
  /* @__PURE__ */ jsx59("h1", { className: "fd-h1", style: { margin: 0 }, children: "Your profile" }),
6992
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." })
6993
7003
  ] }),
6994
- /* @__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: [
6995
7005
  /* @__PURE__ */ jsx59(Avatar, { name: draft.name || user.name, size: "lg" }),
6996
- /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 4, flex: 1, minWidth: 200 }, children: [
7006
+ /* @__PURE__ */ jsxs55("div", { className: "fd-stack", style: { gap: 4, flex: 1, minWidth: 200 }, children: [
6997
7007
  /* @__PURE__ */ jsx59("span", { className: "fd-h3", style: { margin: 0 }, children: draft.name || user.name }),
6998
- /* @__PURE__ */ jsxs54("span", { className: "fd-body-sm fd-muted", children: [
7008
+ /* @__PURE__ */ jsxs55("span", { className: "fd-body-sm fd-muted", children: [
6999
7009
  draft.title || "No title set",
7000
7010
  " \xB7 ",
7001
7011
  user.team || "No team"
7002
7012
  ] }),
7003
- /* @__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: [
7004
7014
  session.roles.map((r) => /* @__PURE__ */ jsx59(Badge, { tone: r.id === "owner" ? "success" : "neutral", children: r.name }, r.id)),
7005
7015
  user.sso ? /* @__PURE__ */ jsx59(Badge, { tone: "info", icon: "shield-check", children: "SSO" }) : null
7006
7016
  ] })
@@ -7010,17 +7020,17 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
7010
7020
  /* @__PURE__ */ jsx59(
7011
7021
  Card,
7012
7022
  {
7013
- title: /* @__PURE__ */ jsxs54("span", { className: "fd-stack", style: { gap: 2 }, children: [
7023
+ title: /* @__PURE__ */ jsxs55("span", { className: "fd-stack", style: { gap: 2 }, children: [
7014
7024
  /* @__PURE__ */ jsx59("span", { children: "Identity" }),
7015
7025
  /* @__PURE__ */ jsx59("span", { className: "fd-body-sm fd-muted", style: { fontWeight: 400 }, children: "Name and title appear on plans you share" })
7016
7026
  ] }),
7017
7027
  elevation: "flat",
7018
- children: /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 14 }, children: [
7019
- /* @__PURE__ */ jsxs54("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(220px,1fr))", gap: 14 }, children: [
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: [
7020
7030
  /* @__PURE__ */ jsx59(Input, { label: "Full name", value: draft.name, onChange: (e) => set("name", e.target.value) }),
7021
7031
  /* @__PURE__ */ jsx59(Input, { label: "Job title", value: draft.title, onChange: (e) => set("title", e.target.value), placeholder: "e.g. Senior media planner" })
7022
7032
  ] }),
7023
- /* @__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: [
7024
7034
  /* @__PURE__ */ jsx59(
7025
7035
  Input,
7026
7036
  {
@@ -7047,7 +7057,7 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
7047
7057
  ] })
7048
7058
  }
7049
7059
  ),
7050
- /* @__PURE__ */ jsx59(Card, { title: "Working preferences", elevation: "flat", children: /* @__PURE__ */ jsxs54("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(220px,1fr))", gap: 14 }, children: [
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: [
7051
7061
  /* @__PURE__ */ jsx59(
7052
7062
  Select,
7053
7063
  {
@@ -7063,7 +7073,7 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
7063
7073
  /* @__PURE__ */ jsx59(
7064
7074
  Card,
7065
7075
  {
7066
- title: /* @__PURE__ */ jsxs54("span", { className: "fd-stack", style: { gap: 2 }, children: [
7076
+ title: /* @__PURE__ */ jsxs55("span", { className: "fd-stack", style: { gap: 2 }, children: [
7067
7077
  /* @__PURE__ */ jsx59("span", { children: "Notifications" }),
7068
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" })
7069
7079
  ] }),
@@ -7071,10 +7081,10 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
7071
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)) })
7072
7082
  }
7073
7083
  ),
7074
- /* @__PURE__ */ jsxs54(
7084
+ /* @__PURE__ */ jsxs55(
7075
7085
  Card,
7076
7086
  {
7077
- title: /* @__PURE__ */ jsxs54("span", { className: "fd-stack", style: { gap: 2 }, children: [
7087
+ title: /* @__PURE__ */ jsxs55("span", { className: "fd-stack", style: { gap: 2 }, children: [
7078
7088
  /* @__PURE__ */ jsx59("span", { children: "Access" }),
7079
7089
  /* @__PURE__ */ jsx59("span", { className: "fd-body-sm fd-muted", style: { fontWeight: 400 }, children: "What your roles grant you" })
7080
7090
  ] }),
@@ -7090,9 +7100,9 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
7090
7100
  }
7091
7101
  ),
7092
7102
  children: [
7093
- /* @__PURE__ */ jsxs54("div", { className: "fd-stack", style: { gap: 0 }, children: [
7103
+ /* @__PURE__ */ jsxs55("div", { className: "fd-stack", style: { gap: 0 }, children: [
7094
7104
  /* @__PURE__ */ jsx59(CardRow, { label: "Roles", children: session.roles.map((r) => r.name).join(", ") || "None" }),
7095
- /* @__PURE__ */ jsxs54(CardRow, { label: "Permissions", children: [
7105
+ /* @__PURE__ */ jsxs55(CardRow, { label: "Permissions", children: [
7096
7106
  session.permissions.length,
7097
7107
  " granted"
7098
7108
  ] }),
@@ -7108,11 +7118,11 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
7108
7118
  title: "Signed-in devices",
7109
7119
  elevation: "flat",
7110
7120
  action: /* @__PURE__ */ jsx59(Button, { size: "sm", variant: "ghost", icon: "sign-out", children: "Sign out everywhere" }),
7111
- children: /* @__PURE__ */ jsx59("div", { className: "fd-stack", style: { gap: 0 }, children: liveSessions.map((s) => /* @__PURE__ */ jsxs54("div", { className: "fd-row", style: { gap: 12, padding: "10px 0", borderTop: "1px solid var(--border)", flexWrap: "wrap" }, children: [
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: [
7112
7122
  /* @__PURE__ */ jsx59("i", { className: "ph ph-device-mobile", style: { fontSize: 16, color: "var(--text-muted)" }, "aria-hidden": "true" }),
7113
- /* @__PURE__ */ jsxs54("span", { className: "fd-stack", style: { gap: 1, flex: 1, minWidth: 160 }, children: [
7123
+ /* @__PURE__ */ jsxs55("span", { className: "fd-stack", style: { gap: 1, flex: 1, minWidth: 160 }, children: [
7114
7124
  /* @__PURE__ */ jsx59("span", { className: "fd-body-sm", style: { fontWeight: 600 }, children: s.device }),
7115
- /* @__PURE__ */ jsxs54("span", { className: "fd-body-sm fd-muted", children: [
7125
+ /* @__PURE__ */ jsxs55("span", { className: "fd-body-sm fd-muted", children: [
7116
7126
  s.where,
7117
7127
  " \xB7 ",
7118
7128
  s.when
@@ -7122,7 +7132,7 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
7122
7132
  ] }, s.id)) })
7123
7133
  }
7124
7134
  ) : null,
7125
- /* @__PURE__ */ jsxs54("div", { className: "fd-row", style: {
7135
+ /* @__PURE__ */ jsxs55("div", { className: "fd-row", style: {
7126
7136
  gap: 10,
7127
7137
  flexWrap: "wrap",
7128
7138
  position: "sticky",
@@ -7153,10 +7163,10 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
7153
7163
  }
7154
7164
 
7155
7165
  // src/components/platform/RoadmapTimeline.tsx
7156
- import * as React34 from "react";
7166
+ import * as React35 from "react";
7157
7167
 
7158
7168
  // src/kits/runtime.ts
7159
- import * as React33 from "react";
7169
+ import * as React34 from "react";
7160
7170
  var WIRED_ENDPOINTS = [
7161
7171
  // Nothing yet. Every id below would come from a real service:
7162
7172
  // "plan.get", "placements.list", …
@@ -7327,8 +7337,8 @@ var RuntimeKit = {
7327
7337
  };
7328
7338
  RuntimeKit.declare(FEATURE_NEEDS);
7329
7339
  function useRuntimeMode() {
7330
- const [m, setM] = React33.useState(RuntimeKit.getMode());
7331
- React33.useEffect(() => RuntimeKit.subscribe(setM), []);
7340
+ const [m, setM] = React34.useState(RuntimeKit.getMode());
7341
+ React34.useEffect(() => RuntimeKit.subscribe(setM), []);
7332
7342
  return m;
7333
7343
  }
7334
7344
  function useFeatureStatus(key) {
@@ -7347,7 +7357,7 @@ var UseRuntimeMode = useRuntimeMode;
7347
7357
  var UseFeatureStatus = useFeatureStatus;
7348
7358
 
7349
7359
  // src/components/platform/RoadmapTimeline.tsx
7350
- import { jsx as jsx60, jsxs as jsxs55 } from "react/jsx-runtime";
7360
+ import { jsx as jsx60, jsxs as jsxs56 } from "react/jsx-runtime";
7351
7361
  var STATUS = {
7352
7362
  shipped: { tone: "success", icon: "check-circle", label: "Wired" },
7353
7363
  next: { tone: "warning", icon: "traffic-cone", label: "Not wired" },
@@ -7362,24 +7372,24 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
7362
7372
  const s = STATUS[item.status] || STATUS.planned;
7363
7373
  const deps = (item.dependsOn || []).map((k) => byKey[k]).filter(Boolean);
7364
7374
  const blocking = deps.filter((d) => !d.implemented);
7365
- return /* @__PURE__ */ jsx60(Card, { elevation: "flat", children: /* @__PURE__ */ jsxs55("div", { className: "fd-stack", style: { gap: 10 }, children: [
7366
- /* @__PURE__ */ jsxs55("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: [
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: [
7367
7377
  /* @__PURE__ */ jsx60("span", { className: "fd-body", style: { fontWeight: 700, flex: 1, minWidth: 140 }, children: item.label }),
7368
7378
  /* @__PURE__ */ jsx60(Badge, { tone: "neutral", icon: PROJECT_ICON[item.project] || "squares-four", children: item.project }),
7369
7379
  /* @__PURE__ */ jsx60(Badge, { tone: s.tone, icon: s.icon, children: s.label })
7370
7380
  ] }),
7371
7381
  /* @__PURE__ */ jsx60("p", { className: "fd-body-sm fd-secondary", style: { margin: 0, textWrap: "pretty" }, children: item.description }),
7372
- item.backend ? /* @__PURE__ */ jsxs55("div", { className: "fd-row", style: { gap: 10, alignItems: "flex-start" }, children: [
7382
+ item.backend ? /* @__PURE__ */ jsxs56("div", { className: "fd-row", style: { gap: 10, alignItems: "flex-start" }, children: [
7373
7383
  /* @__PURE__ */ jsx60("span", { className: "fd-overline fd-muted", style: { width: 62, flex: "none", paddingTop: 2 }, children: "Backend" }),
7374
7384
  /* @__PURE__ */ jsx60("span", { className: "fd-body-sm", style: { flex: 1, textWrap: "pretty" }, children: item.backend })
7375
7385
  ] }) : null,
7376
- /* @__PURE__ */ jsxs55("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
7377
- item.effort ? /* @__PURE__ */ jsxs55("span", { className: "fd-body-sm fd-muted", children: [
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: [
7378
7388
  /* @__PURE__ */ jsx60("i", { className: "ph ph-hourglass-medium" }),
7379
7389
  " ",
7380
7390
  item.effort
7381
7391
  ] }) : null,
7382
- /* @__PURE__ */ jsxs55("span", { className: "fd-body-sm fd-muted", children: [
7392
+ /* @__PURE__ */ jsxs56("span", { className: "fd-body-sm fd-muted", children: [
7383
7393
  /* @__PURE__ */ jsx60("i", { className: "ph ph-user" }),
7384
7394
  " ",
7385
7395
  item.owner
@@ -7396,11 +7406,11 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
7396
7406
  }
7397
7407
  )
7398
7408
  ] }),
7399
- 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: [
7400
7410
  /* @__PURE__ */ jsx60("span", { className: "fd-overline fd-muted", style: { paddingTop: 3 }, children: "After" }),
7401
7411
  deps.map((d) => /* @__PURE__ */ jsx60(Tag, { icon: d.implemented ? "check" : "clock", children: d.label }, d.key))
7402
7412
  ] }) : null,
7403
- 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: [
7404
7414
  "Blocked until ",
7405
7415
  blocking.map((d) => d.label).join(" and "),
7406
7416
  " ",
@@ -7411,12 +7421,12 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
7411
7421
  }
7412
7422
  function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
7413
7423
  const session = SessionKit.useSession();
7414
- const [project, setProject] = React34.useState("");
7415
- const [q, setQ] = React34.useState("");
7416
- const scrollRef = React34.useRef(null);
7417
- const nowRef = React34.useRef(null);
7418
- const rm = React34.useMemo(() => SessionKit.roadmap({ isComplete: RuntimeKit.isComplete }), [session]);
7419
- const byKey = React34.useMemo(() => {
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(() => {
7420
7430
  const m = {};
7421
7431
  rm.items.forEach((i) => {
7422
7432
  m[i.key] = i;
@@ -7425,7 +7435,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
7425
7435
  }, [rm]);
7426
7436
  const items = rm.items.filter((i) => (!project || i.project === project) && (!q || (i.label + " " + i.description + " " + (i.backend || "") + " " + i.key).toLowerCase().includes(q.toLowerCase())));
7427
7437
  const projects = [...new Set(rm.items.map((i) => i.project))];
7428
- React34.useEffect(() => {
7438
+ React35.useEffect(() => {
7429
7439
  let raf1 = 0, raf2 = 0;
7430
7440
  const place = () => {
7431
7441
  const box = scrollRef.current, mark = nowRef.current;
@@ -7453,19 +7463,19 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
7453
7463
  }, 0);
7454
7464
  const nextPhase = items.find((i) => !i.implemented);
7455
7465
  let lastPhase = null;
7456
- return /* @__PURE__ */ jsxs55("div", { className: "fd-stack", style: { gap: 16, maxWidth: 1e3 }, children: [
7457
- /* @__PURE__ */ jsxs55("div", { className: "fd-stack", style: { gap: 10 }, children: [
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: [
7458
7468
  /* @__PURE__ */ jsx60("span", { className: "fd-overline fd-muted", children: "Architecture" }),
7459
7469
  /* @__PURE__ */ jsx60("h1", { className: "fd-h1", style: { margin: 0 }, children: title }),
7460
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." })
7461
7471
  ] }),
7462
- /* @__PURE__ */ jsxs55("div", { className: "fd-grid-stats is-thin", children: [
7472
+ /* @__PURE__ */ jsxs56("div", { className: "fd-grid-stats is-thin", children: [
7463
7473
  /* @__PURE__ */ jsx60(StatTile, { compact: true, label: "Wired", value: String(rm.shipped), sub: "of " + rm.items.length + " features" }),
7464
7474
  /* @__PURE__ */ jsx60(StatTile, { compact: true, label: "Remaining", value: String(rm.remaining), sub: "backend work" }),
7465
7475
  /* @__PURE__ */ jsx60(StatTile, { compact: true, label: "Est. effort", value: days ? days + " days" : "\u2014", sub: "sum of estimates, not calendar" }),
7466
7476
  /* @__PURE__ */ jsx60(StatTile, { compact: true, label: "Up next", value: nextPhase ? "Phase " + nextPhase.phase : "\u2014", sub: nextPhase ? nextPhase.phaseName : "all wired" })
7467
7477
  ] }),
7468
- /* @__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: [
7469
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 } }),
7470
7480
  /* @__PURE__ */ jsx60(Select, { placeholder: "All projects", value: project, onChange: (e) => setProject(e.target.value), options: projects, style: { width: 190 } }),
7471
7481
  /* @__PURE__ */ jsx60("span", { style: { flex: 1 } }),
@@ -7492,23 +7502,23 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
7492
7502
  actions: null
7493
7503
  }
7494
7504
  ),
7495
- /* @__PURE__ */ jsx60("div", { className: "fd-rm", children: /* @__PURE__ */ jsx60("div", { className: "fd-rm-scroll", ref: scrollRef, children: /* @__PURE__ */ jsxs55("div", { className: "fd-rm-track", children: [
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: [
7496
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%" } }) }),
7497
7507
  items.map((item, n) => {
7498
7508
  const showPhase = item.phase !== lastPhase;
7499
7509
  lastPhase = item.phase;
7500
7510
  const inPhase = items.filter((i) => i.phase === item.phase).length;
7501
7511
  const isBoundary = n === firstPending;
7502
- return /* @__PURE__ */ jsxs55(React34.Fragment, { children: [
7503
- showPhase ? /* @__PURE__ */ jsxs55("div", { className: "fd-rm-era", children: [
7504
- /* @__PURE__ */ jsxs55("span", { className: "fd-row", style: { gap: 8, flexWrap: "wrap", alignItems: "baseline" }, children: [
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: [
7505
7515
  /* @__PURE__ */ jsx60("span", { style: { fontWeight: 700 }, children: item.phase === 0 ? "Shipped" : "Phase " + item.phase + " \u2014 " + item.phaseName }),
7506
- item.phase === 0 ? null : /* @__PURE__ */ jsxs55("span", { className: "fd-mono", style: { opacity: 0.7, fontWeight: 400 }, children: [
7516
+ item.phase === 0 ? null : /* @__PURE__ */ jsxs56("span", { className: "fd-mono", style: { opacity: 0.7, fontWeight: 400 }, children: [
7507
7517
  fmtDate(item.phaseStart),
7508
7518
  " \u2013 ",
7509
7519
  fmtDate(item.date)
7510
7520
  ] }),
7511
- /* @__PURE__ */ jsxs55("span", { style: { opacity: 0.7, fontWeight: 400 }, children: [
7521
+ /* @__PURE__ */ jsxs56("span", { style: { opacity: 0.7, fontWeight: 400 }, children: [
7512
7522
  "\xB7 ",
7513
7523
  inPhase,
7514
7524
  " feature",
@@ -7517,13 +7527,13 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
7517
7527
  ] }),
7518
7528
  item.phaseWhy ? /* @__PURE__ */ jsx60("p", { className: "fd-rm-era-why", children: item.phaseWhy }) : null
7519
7529
  ] }) : null,
7520
- 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: [
7521
7531
  /* @__PURE__ */ jsx60("i", { className: "ph ph-map-pin" }),
7522
7532
  " You are here \u2014 everything above is wired"
7523
7533
  ] }) }) : null,
7524
- /* @__PURE__ */ jsxs55("div", { className: "fd-rm-row", children: [
7534
+ /* @__PURE__ */ jsxs56("div", { className: "fd-rm-row", children: [
7525
7535
  /* @__PURE__ */ jsx60("span", { className: "fd-rm-dot " + (item.implemented ? "is-shipped" : item.status === "next" ? "is-next" : "") }),
7526
- /* @__PURE__ */ jsxs55("div", { className: "fd-rm-date", children: [
7536
+ /* @__PURE__ */ jsxs56("div", { className: "fd-rm-date", children: [
7527
7537
  fmtDate(item.date),
7528
7538
  /* @__PURE__ */ jsx60("br", {}),
7529
7539
  /* @__PURE__ */ jsx60("span", { style: { opacity: 0.75 }, children: item.implemented ? "shipped" : "phase " + item.phase })
@@ -7534,7 +7544,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
7534
7544
  }),
7535
7545
  !items.length ? /* @__PURE__ */ jsx60("p", { className: "fd-body-sm fd-muted", children: "Nothing matches that filter." }) : null
7536
7546
  ] }) }) }),
7537
- /* @__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: [
7538
7548
  "Derived from the feature-flag registry \u2014 each entry's status is its flag's ",
7539
7549
  /* @__PURE__ */ jsx60("code", { className: "fd-mono", children: "implemented" }),
7540
7550
  " field, so this page cannot drift from what the apps actually do."
@@ -7543,9 +7553,9 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
7543
7553
  }
7544
7554
 
7545
7555
  // src/components/platform/ComingSoon.tsx
7546
- import * as React35 from "react";
7556
+ import * as React36 from "react";
7547
7557
  import { createPortal as createPortal5 } from "react-dom";
7548
- 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";
7549
7559
  var SOON_HOVERCARD_BASE = 220;
7550
7560
  var BYPASS_STORE = "fd.soon.bypass.v1";
7551
7561
  function readBypassed() {
@@ -7562,8 +7572,8 @@ function writeBypassed(list) {
7562
7572
  }
7563
7573
  }
7564
7574
  function useBypass(key) {
7565
- const [on, setOn] = React35.useState(() => !!key && readBypassed().indexOf(key) >= 0);
7566
- React35.useEffect(() => {
7575
+ const [on, setOn] = React36.useState(() => !!key && readBypassed().indexOf(key) >= 0);
7576
+ React36.useEffect(() => {
7567
7577
  setOn(!!key && readBypassed().indexOf(key) >= 0);
7568
7578
  }, [key]);
7569
7579
  const set = (next) => {
@@ -7576,43 +7586,43 @@ function useBypass(key) {
7576
7586
  return [on, set];
7577
7587
  }
7578
7588
  function SoonCard({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass }) {
7579
- return /* @__PURE__ */ jsxs56(Fragment16, { children: [
7580
- /* @__PURE__ */ jsxs56("span", { className: "fd-soon-badge", children: [
7589
+ return /* @__PURE__ */ jsxs57(Fragment16, { children: [
7590
+ /* @__PURE__ */ jsxs57("span", { className: "fd-soon-badge", children: [
7581
7591
  /* @__PURE__ */ jsx61("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" }),
7582
7592
  label
7583
7593
  ] }),
7584
7594
  detail ? /* @__PURE__ */ jsx61("span", { className: "fd-soon-detail", children: detail }) : null,
7585
- backend ? /* @__PURE__ */ jsxs56("span", { className: "fd-soon-backend", children: [
7595
+ backend ? /* @__PURE__ */ jsxs57("span", { className: "fd-soon-backend", children: [
7586
7596
  /* @__PURE__ */ jsx61("span", { className: "fd-overline", children: "Needs" }),
7587
7597
  " ",
7588
7598
  backend
7589
7599
  ] }) : null,
7590
- eta || effort || onRoadmap ? /* @__PURE__ */ jsxs56("span", { className: "fd-soon-meta", children: [
7591
- eta ? /* @__PURE__ */ jsxs56("span", { children: [
7600
+ eta || effort || onRoadmap ? /* @__PURE__ */ jsxs57("span", { className: "fd-soon-meta", children: [
7601
+ eta ? /* @__PURE__ */ jsxs57("span", { children: [
7592
7602
  /* @__PURE__ */ jsx61("i", { className: "ph ph-calendar-blank", "aria-hidden": "true" }),
7593
7603
  " ",
7594
7604
  eta
7595
7605
  ] }) : null,
7596
- effort ? /* @__PURE__ */ jsxs56("span", { children: [
7606
+ effort ? /* @__PURE__ */ jsxs57("span", { children: [
7597
7607
  /* @__PURE__ */ jsx61("i", { className: "ph ph-hourglass-medium", "aria-hidden": "true" }),
7598
7608
  " ",
7599
7609
  effort
7600
7610
  ] }) : null,
7601
- 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: [
7602
7612
  "See the roadmap ",
7603
7613
  /* @__PURE__ */ jsx61("i", { className: "ph ph-arrow-right", "aria-hidden": "true" })
7604
7614
  ] }) : null
7605
7615
  ] }) : null,
7606
- 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: [
7607
7617
  /* @__PURE__ */ jsx61("i", { className: "ph ph-eye", "aria-hidden": "true" }),
7608
7618
  " View and use it anyway"
7609
7619
  ] }) : null
7610
7620
  ] });
7611
7621
  }
7612
7622
  function useHoverCard(open) {
7613
- const anchor = React35.useRef(null);
7614
- const [pos, setPos] = React35.useState(null);
7615
- React35.useLayoutEffect(() => {
7623
+ const anchor = React36.useRef(null);
7624
+ const [pos, setPos] = React36.useState(null);
7625
+ React36.useLayoutEffect(() => {
7616
7626
  if (!open || !anchor.current) {
7617
7627
  setPos(null);
7618
7628
  return;
@@ -7664,7 +7674,7 @@ function ComingSoon({
7664
7674
  const tip = [label, detail, backend ? "Needs " + backend : null, eta ? "ETA " + eta : null, effort].filter(Boolean).join(" \xB7 ");
7665
7675
  if (inline) {
7666
7676
  if (allowed && bypassed) {
7667
- 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: [
7668
7678
  children,
7669
7679
  /* @__PURE__ */ jsx61(
7670
7680
  "button",
@@ -7699,19 +7709,19 @@ function ComingSoon({
7699
7709
  );
7700
7710
  }
7701
7711
  if (allowed && bypassed) {
7702
- return /* @__PURE__ */ jsxs56("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 14 }, ...rest, children: [
7703
- /* @__PURE__ */ jsxs56("div", { className: "fd-soon-bar", role: "status", children: [
7704
- /* @__PURE__ */ jsxs56("span", { className: "fd-soon-badge", children: [
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: [
7705
7715
  /* @__PURE__ */ jsx61("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" }),
7706
7716
  "Unwired feature \u2014 you are using it anyway"
7707
7717
  ] }),
7708
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." }),
7709
- /* @__PURE__ */ jsxs56("span", { className: "fd-soon-bar-actions", children: [
7710
- 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: [
7711
7721
  "Roadmap ",
7712
7722
  /* @__PURE__ */ jsx61("i", { className: "ph ph-arrow-right", "aria-hidden": "true" })
7713
7723
  ] }) : null,
7714
- /* @__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: [
7715
7725
  /* @__PURE__ */ jsx61("i", { className: "ph ph-eye-slash", "aria-hidden": "true" }),
7716
7726
  " Re-blur"
7717
7727
  ] })
@@ -7720,7 +7730,7 @@ function ComingSoon({
7720
7730
  children
7721
7731
  ] });
7722
7732
  }
7723
- 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: [
7724
7734
  /* @__PURE__ */ jsx61("div", { className: "fd-soon-under", style: { filter: "blur(" + blur + "px) saturate(.62)" }, ...{ inert: "" }, "aria-hidden": "true", children }),
7725
7735
  /* @__PURE__ */ jsx61("div", { className: "fd-soon-veil" }),
7726
7736
  /* @__PURE__ */ jsx61("div", { className: "fd-soon-note", role: "note", children: /* @__PURE__ */ jsx61(
@@ -7739,10 +7749,10 @@ function ComingSoon({
7739
7749
  ] });
7740
7750
  }
7741
7751
  function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass, blur, tip, className, rest, children }) {
7742
- const [open, setOpen] = React35.useState(false);
7752
+ const [open, setOpen] = React36.useState(false);
7743
7753
  const [anchor, pos] = useHoverCard(open);
7744
7754
  const zIndex = useOverlayLayer(SOON_HOVERCARD_BASE);
7745
- const close = React35.useRef(null);
7755
+ const close = React36.useRef(null);
7746
7756
  const show = () => {
7747
7757
  if (close.current) {
7748
7758
  clearTimeout(close.current);
@@ -7758,10 +7768,10 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
7758
7768
  setOpen(false);
7759
7769
  }, 140);
7760
7770
  };
7761
- React35.useEffect(() => () => {
7771
+ React36.useEffect(() => () => {
7762
7772
  if (close.current) clearTimeout(close.current);
7763
7773
  }, []);
7764
- return /* @__PURE__ */ jsxs56(
7774
+ return /* @__PURE__ */ jsxs57(
7765
7775
  "span",
7766
7776
  {
7767
7777
  ref: anchor,
@@ -7826,10 +7836,10 @@ function formatEta(iso2) {
7826
7836
  var FormatEta = formatEta;
7827
7837
 
7828
7838
  // src/components/platform/Gate.tsx
7829
- import { jsx as jsx62, jsxs as jsxs57 } from "react/jsx-runtime";
7839
+ import { jsx as jsx62, jsxs as jsxs58 } from "react/jsx-runtime";
7830
7840
  function PermissionDenied({ permission, title, detail, compact: compact3 = false, className = "", ...rest }) {
7831
7841
  const need = Array.isArray(permission) ? permission : [permission].filter(Boolean);
7832
- return /* @__PURE__ */ jsxs57(
7842
+ return /* @__PURE__ */ jsxs58(
7833
7843
  "div",
7834
7844
  {
7835
7845
  className: ["fd-stack", className].filter(Boolean).join(" "),
@@ -7845,12 +7855,12 @@ function PermissionDenied({ permission, title, detail, compact: compact3 = false
7845
7855
  },
7846
7856
  ...rest,
7847
7857
  children: [
7848
- /* @__PURE__ */ jsxs57("span", { className: "fd-row", style: { gap: 8 }, children: [
7858
+ /* @__PURE__ */ jsxs58("span", { className: "fd-row", style: { gap: 8 }, children: [
7849
7859
  /* @__PURE__ */ jsx62("i", { className: "ph ph-lock-simple", style: { fontSize: 16, color: "var(--text-muted)" }, "aria-hidden": "true" }),
7850
7860
  /* @__PURE__ */ jsx62("span", { className: compact3 ? "fd-label-lg" : "fd-h3", children: title || "You do not have access to this" })
7851
7861
  ] }),
7852
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." }),
7853
- 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: [
7854
7864
  /* @__PURE__ */ jsx62("span", { className: "fd-overline fd-muted", children: "Requires" }),
7855
7865
  need.map((p) => /* @__PURE__ */ jsx62("code", { className: "fd-mono", style: {
7856
7866
  fontSize: 11.5,
@@ -7927,15 +7937,15 @@ function PermissionHint({ perm, children }) {
7927
7937
  }
7928
7938
 
7929
7939
  // src/components/platform/ModeSwitch.tsx
7930
- import * as React36 from "react";
7931
- import { Fragment as Fragment17, jsx as jsx63, jsxs as jsxs58 } from "react/jsx-runtime";
7940
+ import * as React37 from "react";
7941
+ import { Fragment as Fragment17, jsx as jsx63, jsxs as jsxs59 } from "react/jsx-runtime";
7932
7942
  var MODE_SWITCH_BASE = 140;
7933
7943
  function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog, onOpenSpec, summary }) {
7934
7944
  const mode2 = useRuntimeMode();
7935
- const [open, setOpen] = React36.useState(false);
7945
+ const [open, setOpen] = React37.useState(false);
7936
7946
  const zIndex = useOverlayLayer(MODE_SWITCH_BASE);
7937
- const ref = React36.useRef(null);
7938
- React36.useEffect(() => {
7947
+ const ref = React37.useRef(null);
7948
+ React37.useEffect(() => {
7939
7949
  if (!open) return;
7940
7950
  const away = (e) => {
7941
7951
  if (ref.current && !ref.current.contains(e.target)) setOpen(false);
@@ -7957,8 +7967,8 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
7957
7967
  RuntimeKit.setMode(next);
7958
7968
  setOpen(false);
7959
7969
  };
7960
- return /* @__PURE__ */ jsxs58("span", { style: { position: "relative", display: "inline-flex" }, ref, children: [
7961
- /* @__PURE__ */ jsxs58(
7970
+ return /* @__PURE__ */ jsxs59("span", { style: { position: "relative", display: "inline-flex" }, ref, children: [
7971
+ /* @__PURE__ */ jsxs59(
7962
7972
  "button",
7963
7973
  {
7964
7974
  type: "button",
@@ -7973,13 +7983,13 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
7973
7983
  ]
7974
7984
  }
7975
7985
  ),
7976
- open ? /* @__PURE__ */ jsx63(LayerProvider, { zIndex, children: /* @__PURE__ */ jsxs58("span", { className: "fd-view-enter fd-mode-pop", style: { zIndex }, children: [
7977
- /* @__PURE__ */ jsxs58("span", { className: "fd-row", style: { gap: 10, padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
7978
- /* @__PURE__ */ jsxs58("span", { className: "fd-badge " + (test ? "fd-badge-warning" : "fd-badge-neutral"), children: [
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: [
7979
7989
  /* @__PURE__ */ jsx63("i", { className: "ph " + (test ? "ph-flask" : "ph-lightning"), "aria-hidden": "true" }),
7980
7990
  test ? "Test mode" : "Live mode"
7981
7991
  ] }),
7982
- 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: [
7983
7993
  requestCount,
7984
7994
  " simulated request",
7985
7995
  requestCount === 1 ? "" : "s"
@@ -7987,10 +7997,10 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
7987
7997
  /* @__PURE__ */ jsx63("span", { style: { flex: 1 } }),
7988
7998
  test && onClearLog ? /* @__PURE__ */ jsx63("button", { type: "button", className: "fd-soon-link", onClick: onClearLog, children: "Clear" }) : null
7989
7999
  ] }),
7990
- /* @__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: [
7991
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." }),
7992
- /* @__PURE__ */ jsxs58("span", { className: "fd-row", style: { gap: 8, marginTop: 10, flexWrap: "wrap" }, children: [
7993
- /* @__PURE__ */ jsxs58("span", { className: "fd-body-sm fd-muted fd-mono", children: [
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: [
7994
8004
  s.endpointsWired,
7995
8005
  " endpoint",
7996
8006
  s.endpointsWired === 1 ? "" : "s",
@@ -8000,9 +8010,9 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
8000
8010
  s.total,
8001
8011
  " features complete"
8002
8012
  ] }),
8003
- onOpenSpec ? /* @__PURE__ */ jsxs58(Fragment17, { children: [
8013
+ onOpenSpec ? /* @__PURE__ */ jsxs59(Fragment17, { children: [
8004
8014
  /* @__PURE__ */ jsx63("span", { style: { flex: 1 } }),
8005
- /* @__PURE__ */ jsxs58("button", { type: "button", className: "fd-soon-link", onClick: () => {
8015
+ /* @__PURE__ */ jsxs59("button", { type: "button", className: "fd-soon-link", onClick: () => {
8006
8016
  setOpen(false);
8007
8017
  onOpenSpec();
8008
8018
  }, children: [
@@ -8012,18 +8022,18 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
8012
8022
  ] }) : null
8013
8023
  ] })
8014
8024
  ] }),
8015
- /* @__PURE__ */ jsxs58("span", { className: "fd-mode-choice", children: [
8016
- /* @__PURE__ */ jsxs58("button", { type: "button", className: "fd-mode-opt" + (!test ? " is-on" : ""), onClick: () => go("live"), children: [
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: [
8017
8027
  /* @__PURE__ */ jsx63("i", { className: "ph ph-lightning", "aria-hidden": "true" }),
8018
- /* @__PURE__ */ jsxs58("span", { className: "fd-mode-opt-text", children: [
8028
+ /* @__PURE__ */ jsxs59("span", { className: "fd-mode-opt-text", children: [
8019
8029
  /* @__PURE__ */ jsx63("span", { className: "fd-mode-opt-title", children: "Live mode" }),
8020
8030
  /* @__PURE__ */ jsx63("span", { className: "fd-mode-opt-desc", children: "Incomplete features under construction" })
8021
8031
  ] }),
8022
8032
  !test ? /* @__PURE__ */ jsx63("i", { className: "ph ph-check", "aria-hidden": "true" }) : null
8023
8033
  ] }),
8024
- /* @__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: [
8025
8035
  /* @__PURE__ */ jsx63("i", { className: "ph ph-flask", "aria-hidden": "true" }),
8026
- /* @__PURE__ */ jsxs58("span", { className: "fd-mode-opt-text", children: [
8036
+ /* @__PURE__ */ jsxs59("span", { className: "fd-mode-opt-text", children: [
8027
8037
  /* @__PURE__ */ jsx63("span", { className: "fd-mode-opt-title", children: "Test mode" }),
8028
8038
  /* @__PURE__ */ jsx63("span", { className: "fd-mode-opt-desc", children: "Everything usable, all data simulated" })
8029
8039
  ] }),
@@ -8037,13 +8047,13 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
8037
8047
  function TestModeBar({ onExit }) {
8038
8048
  const mode2 = useRuntimeMode();
8039
8049
  if (mode2 !== "test") return null;
8040
- return /* @__PURE__ */ jsxs58("div", { className: "fd-testbar", role: "status", children: [
8041
- /* @__PURE__ */ jsxs58("span", { className: "fd-badge fd-badge-warning", children: [
8050
+ return /* @__PURE__ */ jsxs59("div", { className: "fd-testbar", role: "status", children: [
8051
+ /* @__PURE__ */ jsxs59("span", { className: "fd-badge fd-badge-warning", children: [
8042
8052
  /* @__PURE__ */ jsx63("i", { className: "ph ph-flask", "aria-hidden": "true" }),
8043
8053
  "Test mode"
8044
8054
  ] }),
8045
8055
  /* @__PURE__ */ jsx63("span", { className: "fd-testbar-detail", children: "Every feature is unlocked and every response is simulated \u2014 nothing here persists." }),
8046
- /* @__PURE__ */ jsxs58("button", { type: "button", className: "fd-soon-link", onClick: () => onExit ? onExit() : RuntimeKit.setMode("live"), children: [
8056
+ /* @__PURE__ */ jsxs59("button", { type: "button", className: "fd-soon-link", onClick: () => onExit ? onExit() : RuntimeKit.setMode("live"), children: [
8047
8057
  /* @__PURE__ */ jsx63("i", { className: "ph ph-lightning", "aria-hidden": "true" }),
8048
8058
  " Back to live mode"
8049
8059
  ] })
@@ -8051,7 +8061,7 @@ function TestModeBar({ onExit }) {
8051
8061
  }
8052
8062
 
8053
8063
  // src/components/planner/ChannelMeta.tsx
8054
- import { jsx as jsx64, jsxs as jsxs59 } from "react/jsx-runtime";
8064
+ import { jsx as jsx64, jsxs as jsxs60 } from "react/jsx-runtime";
8055
8065
  var CHANNEL_WEIGHTS = {
8056
8066
  "OOH": 50,
8057
8067
  "DOOH": 50,
@@ -8106,7 +8116,7 @@ function ChannelTag({ channel, size = "md", showLabel = true, dot = false, weigh
8106
8116
  if (dot) {
8107
8117
  return /* @__PURE__ */ jsx64("span", { className: ["fd-chan-dot", className].filter(Boolean).join(" "), title: m.name, style: { background: m.color }, ...rest });
8108
8118
  }
8109
- return /* @__PURE__ */ jsxs59(
8119
+ return /* @__PURE__ */ jsxs60(
8110
8120
  "span",
8111
8121
  {
8112
8122
  className: ["fd-chan", size === "sm" ? "fd-chan-sm" : "", className].filter(Boolean).join(" "),
@@ -8123,7 +8133,7 @@ function ChannelTag({ channel, size = "md", showLabel = true, dot = false, weigh
8123
8133
  }
8124
8134
 
8125
8135
  // src/components/planner/SaturationDistribution.tsx
8126
- import { jsx as jsx65, jsxs as jsxs60 } from "react/jsx-runtime";
8136
+ import { jsx as jsx65, jsxs as jsxs61 } from "react/jsx-runtime";
8127
8137
  var BANDS2 = [
8128
8138
  { key: "weak", label: "Weak", n: 1, range: "< 50" },
8129
8139
  { key: "adequate", label: "Adequate", n: 2, range: "50\u2013100" },
@@ -8134,11 +8144,11 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
8134
8144
  const grouped = BANDS2.map((b) => ({ ...b, items: campuses.filter((c) => c.band === b.key) }));
8135
8145
  const tallest = Math.max(1, ...grouped.map((g) => g.items.length));
8136
8146
  const floor = BANDS2.find((b) => b.key === floorBand) || BANDS2[0];
8137
- return /* @__PURE__ */ jsxs60("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 16 }, children: [
8147
+ return /* @__PURE__ */ jsxs61("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 16 }, children: [
8138
8148
  /* @__PURE__ */ jsx65("div", { style: { display: "grid", gridTemplateColumns: "repeat(4,1fr)", gap: 12, alignItems: "end" }, children: grouped.map((g) => {
8139
8149
  const mark = "var(--csi-" + g.n + "-mark)";
8140
8150
  const active = selectedBand === g.key;
8141
- return /* @__PURE__ */ jsxs60(
8151
+ return /* @__PURE__ */ jsxs61(
8142
8152
  "button",
8143
8153
  {
8144
8154
  type: "button",
@@ -8154,13 +8164,13 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
8154
8164
  },
8155
8165
  c.name
8156
8166
  )) }),
8157
- /* @__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: [
8158
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 }),
8159
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)) })
8160
8170
  ] }),
8161
- /* @__PURE__ */ jsxs60("span", { className: "fd-stack", style: { gap: 1 }, children: [
8171
+ /* @__PURE__ */ jsxs61("span", { className: "fd-stack", style: { gap: 1 }, children: [
8162
8172
  /* @__PURE__ */ jsx65("span", { className: "fd-label-lg", children: g.label }),
8163
- /* @__PURE__ */ jsxs60("span", { className: "fd-body-sm fd-muted", style: { fontSize: 11.5 }, children: [
8173
+ /* @__PURE__ */ jsxs61("span", { className: "fd-body-sm fd-muted", style: { fontSize: 11.5 }, children: [
8164
8174
  "CRP ",
8165
8175
  g.range
8166
8176
  ] })
@@ -8170,10 +8180,10 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
8170
8180
  g.key
8171
8181
  );
8172
8182
  }) }),
8173
- floorBand ? /* @__PURE__ */ jsxs60("div", { className: "fd-row", style: { gap: 10, padding: "12px 14px", borderRadius: "var(--r-md)", background: "var(--surface-2)", border: "1px solid var(--border)", flexWrap: "wrap" }, children: [
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: [
8174
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)) }),
8175
- /* @__PURE__ */ jsxs60("span", { className: "fd-body-sm fd-secondary", style: { flex: 1, minWidth: 240 }, children: [
8176
- /* @__PURE__ */ jsxs60("strong", { style: { color: "var(--text)" }, children: [
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: [
8177
8187
  "Plan floor ",
8178
8188
  floorScore
8179
8189
  ] }),
@@ -8184,8 +8194,8 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
8184
8194
  }
8185
8195
 
8186
8196
  // src/components/planner/MixGap.tsx
8187
- import * as React37 from "react";
8188
- import { Fragment as Fragment18, jsx as jsx66, jsxs as jsxs61 } from "react/jsx-runtime";
8197
+ import * as React38 from "react";
8198
+ import { Fragment as Fragment18, jsx as jsx66, jsxs as jsxs62 } from "react/jsx-runtime";
8189
8199
  var MIX_GAP_LAYOUT = {
8190
8200
  trackHeight: 30,
8191
8201
  barHeight: 20,
@@ -8199,18 +8209,18 @@ function mixGapOffset(value, max) {
8199
8209
  }
8200
8210
  function MixGap({ rows = [], loading = false, className = "" }) {
8201
8211
  const max = Math.max(1, ...rows.flatMap((r) => [r.target, r.realized]));
8202
- const [hover, setHover] = React37.useState(null);
8212
+ const [hover, setHover] = React38.useState(null);
8203
8213
  const toneOf = (gap) => gap >= -1 ? "ok" : gap >= -4 ? "warn" : "danger";
8204
8214
  const TONE = { ok: "var(--ok-solid)", warn: "var(--warn-solid)", danger: "var(--danger-solid)" };
8205
8215
  const { trackHeight, barHeight, targetWidth, labelGap } = MIX_GAP_LAYOUT;
8206
8216
  const barTop = (trackHeight - barHeight) / 2;
8207
- return /* @__PURE__ */ jsxs61("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 4 }, children: [
8208
- /* @__PURE__ */ jsxs61("div", { className: "fd-row", style: { gap: 16, justifyContent: "flex-end", paddingBottom: 6, flexWrap: "wrap" }, children: [
8209
- [["On target", TONE.ok], ["Close", TONE.warn], ["Short", TONE.danger]].map(([l, c]) => /* @__PURE__ */ jsxs61("span", { className: "fd-row fd-body-sm fd-muted", style: { gap: 6 }, children: [
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: [
8210
8220
  /* @__PURE__ */ jsx66("span", { style: { width: 14, height: 9, borderRadius: 2, background: c } }),
8211
8221
  l
8212
8222
  ] }, l)),
8213
- /* @__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: [
8214
8224
  /* @__PURE__ */ jsx66("span", { "data-mixgap-legend-target": "", style: { width: targetWidth, height: 16, borderRadius: 1, background: MIX_GAP_TARGET_STRIPE } }),
8215
8225
  "Target"
8216
8226
  ] })
@@ -8220,7 +8230,7 @@ function MixGap({ rows = [], loading = false, className = "" }) {
8220
8230
  const tone = toneOf(gap);
8221
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 : "");
8222
8232
  const labelLeft = r.realized > r.target ? `calc(${mixGapOffset(r.realized, max)} + ${labelGap}px)` : `calc(${mixGapOffset(r.target, max)} + ${targetWidth / 2 + labelGap}px)`;
8223
- return /* @__PURE__ */ jsxs61(
8233
+ return /* @__PURE__ */ jsxs62(
8224
8234
  "div",
8225
8235
  {
8226
8236
  className: "fd-row",
@@ -8229,10 +8239,10 @@ function MixGap({ rows = [], loading = false, className = "" }) {
8229
8239
  onMouseLeave: () => setHover(null),
8230
8240
  children: [
8231
8241
  /* @__PURE__ */ jsx66("span", { style: { width: 128, flex: "none" }, children: /* @__PURE__ */ jsx66(ChannelTag, { channel: r.channel, size: "sm" }) }),
8232
- /* @__PURE__ */ jsx66("span", { style: { position: "relative", flex: 1, height: trackHeight, minWidth: 120 }, children: loading ? /* @__PURE__ */ jsx66("span", { className: "fd-skel", style: { position: "absolute", left: 0, right: 0, top: barTop, height: barHeight, borderRadius: 3 } }) : /* @__PURE__ */ jsxs61(Fragment18, { children: [
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: [
8233
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)" } }),
8234
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 } }),
8235
- /* @__PURE__ */ jsxs61("span", { "data-mixgap-label": "", className: "fd-num", style: { position: "absolute", left: labelLeft, top: "50%", transform: "translateY(-50%)", fontSize: 12, color: "var(--text-muted)", whiteSpace: "nowrap" }, children: [
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: [
8236
8246
  r.realized,
8237
8247
  "%"
8238
8248
  ] }),
@@ -8247,7 +8257,7 @@ function MixGap({ rows = [], loading = false, className = "" }) {
8247
8257
  }
8248
8258
 
8249
8259
  // src/components/planner/ChannelContribution.tsx
8250
- import { jsx as jsx67, jsxs as jsxs62 } from "react/jsx-runtime";
8260
+ import { jsx as jsx67, jsxs as jsxs63 } from "react/jsx-runtime";
8251
8261
  var money = (n) => "$" + Math.round(n).toLocaleString();
8252
8262
  function ChannelContribution({
8253
8263
  channels = [],
@@ -8263,8 +8273,8 @@ function ChannelContribution({
8263
8273
  const grand = total !== void 0 ? total : base + bonus;
8264
8274
  const pct = (v) => grand ? v / grand * 100 : 0;
8265
8275
  const spendTotal = channels.reduce((s, c) => s + Number(String(c.spend || 0).replace(/[^0-9.]/g, "")), 0);
8266
- return /* @__PURE__ */ jsxs62("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 16 }, children: [
8267
- loading ? /* @__PURE__ */ jsx67("span", { className: "fd-skel", style: { height: 34, borderRadius: "var(--r-sm)" } }) : /* @__PURE__ */ jsxs62("div", { className: "fd-row", style: { height: 34, borderRadius: "var(--r-sm)", overflow: "hidden", gap: 2, background: "var(--surface-3)" }, children: [
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: [
8268
8278
  channels.map((c) => /* @__PURE__ */ jsx67(
8269
8279
  "span",
8270
8280
  {
@@ -8283,16 +8293,16 @@ function ChannelContribution({
8283
8293
  }
8284
8294
  ) : null
8285
8295
  ] }),
8286
- showTable ? /* @__PURE__ */ jsxs62("table", { className: "fd-table", style: { fontSize: "var(--body-sm-size)" }, children: [
8287
- /* @__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: [
8288
8298
  /* @__PURE__ */ jsx67("th", { style: { width: "34%" }, children: "Channel" }),
8289
8299
  /* @__PURE__ */ jsx67("th", { style: { width: "16%" }, children: "Weight" }),
8290
8300
  /* @__PURE__ */ jsx67("th", { className: "is-num", style: { width: "16%" }, children: "Spend" }),
8291
8301
  /* @__PURE__ */ jsx67("th", { className: "is-num", style: { width: "17%" }, children: "CRP" }),
8292
8302
  /* @__PURE__ */ jsx67("th", { className: "is-num", style: { width: "17%" }, children: "Share" })
8293
8303
  ] }) }),
8294
- /* @__PURE__ */ jsxs62("tbody", { children: [
8295
- channels.map((c) => /* @__PURE__ */ jsxs62("tr", { children: [
8304
+ /* @__PURE__ */ jsxs63("tbody", { children: [
8305
+ channels.map((c) => /* @__PURE__ */ jsxs63("tr", { children: [
8296
8306
  /* @__PURE__ */ jsx67("td", { children: /* @__PURE__ */ jsx67(ChannelTag, { channel: c.name, size: "sm" }) }),
8297
8307
  /* @__PURE__ */ jsx67("td", { children: /* @__PURE__ */ jsx67(
8298
8308
  "span",
@@ -8305,17 +8315,17 @@ function ChannelContribution({
8305
8315
  ) }),
8306
8316
  /* @__PURE__ */ jsx67("td", { className: "is-num", children: c.spend }),
8307
8317
  /* @__PURE__ */ jsx67("td", { className: "is-num", children: c.crp.toFixed(1) }),
8308
- /* @__PURE__ */ jsxs62("td", { className: "is-num", children: [
8318
+ /* @__PURE__ */ jsxs63("td", { className: "is-num", children: [
8309
8319
  pct(c.crp).toFixed(0),
8310
8320
  "%"
8311
8321
  ] })
8312
8322
  ] }, c.name)),
8313
- bonus > 0 ? /* @__PURE__ */ jsxs62("tr", { children: [
8314
- /* @__PURE__ */ jsx67("td", { children: /* @__PURE__ */ jsxs62("span", { className: "fd-row", style: { gap: 9, fontWeight: 600 }, children: [
8323
+ bonus > 0 ? /* @__PURE__ */ jsxs63("tr", { children: [
8324
+ /* @__PURE__ */ jsx67("td", { children: /* @__PURE__ */ jsxs63("span", { className: "fd-row", style: { gap: 9, fontWeight: 600 }, children: [
8315
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" } }),
8316
8326
  "Surround-sound bonus"
8317
8327
  ] }) }),
8318
- /* @__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: [
8319
8329
  "+",
8320
8330
  bonusPct,
8321
8331
  "% of +",
@@ -8324,12 +8334,12 @@ function ChannelContribution({
8324
8334
  ] }) }),
8325
8335
  /* @__PURE__ */ jsx67("td", { className: "is-num fd-muted", children: "\u2014" }),
8326
8336
  /* @__PURE__ */ jsx67("td", { className: "is-num", children: bonus.toFixed(1) }),
8327
- /* @__PURE__ */ jsxs62("td", { className: "is-num", children: [
8337
+ /* @__PURE__ */ jsxs63("td", { className: "is-num", children: [
8328
8338
  pct(bonus).toFixed(0),
8329
8339
  "%"
8330
8340
  ] })
8331
8341
  ] }) : null,
8332
- /* @__PURE__ */ jsxs62("tr", { style: { background: "var(--surface-2)" }, children: [
8342
+ /* @__PURE__ */ jsxs63("tr", { style: { background: "var(--surface-2)" }, children: [
8333
8343
  /* @__PURE__ */ jsx67("td", { style: { fontWeight: 700 }, children: "Campus total" }),
8334
8344
  /* @__PURE__ */ jsx67("td", {}),
8335
8345
  /* @__PURE__ */ jsx67("td", { className: "is-num", style: { fontWeight: 700 }, children: money(spendTotal) }),
@@ -8342,8 +8352,8 @@ function ChannelContribution({
8342
8352
  }
8343
8353
 
8344
8354
  // src/components/planner/BudgetReallocator.tsx
8345
- import * as React38 from "react";
8346
- import { Fragment as Fragment19, jsx as jsx68, jsxs as jsxs63 } from "react/jsx-runtime";
8355
+ import * as React39 from "react";
8356
+ import { Fragment as Fragment19, jsx as jsx68, jsxs as jsxs64 } from "react/jsx-runtime";
8347
8357
  var bandFor = (crp) => crp >= 200 ? "dominant" : crp >= 100 ? "strong" : crp >= 50 ? "adequate" : "weak";
8348
8358
  function BudgetReallocator({
8349
8359
  campus,
@@ -8358,8 +8368,8 @@ function BudgetReallocator({
8358
8368
  onCancel,
8359
8369
  className = ""
8360
8370
  }) {
8361
- const [draft, setDraft] = React38.useState(spend);
8362
- React38.useEffect(() => setDraft(spend), [spend]);
8371
+ const [draft, setDraft] = React39.useState(spend);
8372
+ React39.useEffect(() => setDraft(spend), [spend]);
8363
8373
  const dirty = draft !== spend;
8364
8374
  const nextCrp = scoreFor ? scoreFor(draft) : crp;
8365
8375
  const nextBand = bandFor(nextCrp);
@@ -8374,21 +8384,21 @@ function BudgetReallocator({
8374
8384
  setDraft(spend);
8375
8385
  if (onCancel) onCancel();
8376
8386
  };
8377
- return /* @__PURE__ */ jsxs63(
8387
+ return /* @__PURE__ */ jsxs64(
8378
8388
  "div",
8379
8389
  {
8380
8390
  className: ["fd-stack", className].filter(Boolean).join(" "),
8381
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)" },
8382
8392
  children: [
8383
- /* @__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: [
8384
8394
  /* @__PURE__ */ jsx68("span", { className: "fd-h4", style: { flex: 1, minWidth: 140 }, children: campus }),
8385
8395
  /* @__PURE__ */ jsx68(CsiBadge, { band: nowBand, crp, size: "medium" }),
8386
- dirty ? /* @__PURE__ */ jsxs63(Fragment19, { children: [
8396
+ dirty ? /* @__PURE__ */ jsxs64(Fragment19, { children: [
8387
8397
  /* @__PURE__ */ jsx68("i", { className: "ph ph-arrow-right fd-muted", "aria-hidden": "true" }),
8388
8398
  /* @__PURE__ */ jsx68(CsiBadge, { band: nextBand, crp: nextCrp, size: "medium", preview: true })
8389
8399
  ] }) : null
8390
8400
  ] }),
8391
- /* @__PURE__ */ jsxs63("div", { className: "fd-slider", children: [
8401
+ /* @__PURE__ */ jsxs64("div", { className: "fd-slider", children: [
8392
8402
  /* @__PURE__ */ jsx68("span", { className: "fd-slider-fill", style: { width: pct + "%" } }),
8393
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,
8394
8404
  /* @__PURE__ */ jsx68(
@@ -8407,8 +8417,8 @@ function BudgetReallocator({
8407
8417
  }
8408
8418
  )
8409
8419
  ] }),
8410
- /* @__PURE__ */ jsxs63("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
8411
- /* @__PURE__ */ jsxs63("span", { className: "fd-stack", style: { gap: 2, flex: 1, minWidth: 150 }, children: [
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: [
8412
8422
  /* @__PURE__ */ jsx68("span", { className: "fd-num", style: { fontSize: 19, fontWeight: 700 }, children: "$" + draft.toLocaleString() }),
8413
8423
  /* @__PURE__ */ jsx68("span", { className: "fd-body-sm fd-muted", children: "Arrow keys step $100, shift+arrow $1,000. Escape reverts." })
8414
8424
  ] }),
@@ -8432,7 +8442,7 @@ function BudgetReallocator({
8432
8442
  }
8433
8443
 
8434
8444
  // src/components/planner/SurroundSound.tsx
8435
- import { jsx as jsx69, jsxs as jsxs64 } from "react/jsx-runtime";
8445
+ import { jsx as jsx69, jsxs as jsxs65 } from "react/jsx-runtime";
8436
8446
  var CATEGORIES = [
8437
8447
  { key: "ooh", label: "OOH", icon: "flag-banner", color: "var(--ch-ooh)" },
8438
8448
  { key: "transit", label: "Transit", icon: "bus", color: "var(--ch-transit)" },
@@ -8444,10 +8454,10 @@ var CATEGORIES = [
8444
8454
  function SurroundSound({ present = [], bonusPct = 0, bonusMax = 40, missedCost, className = "" }) {
8445
8455
  const earned = Math.max(0, Math.min(1, bonusPct / bonusMax));
8446
8456
  const single = present.length <= 2;
8447
- 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: [
8448
8458
  /* @__PURE__ */ jsx69("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: CATEGORIES.map((c) => {
8449
8459
  const on = present.includes(c.key);
8450
- return /* @__PURE__ */ jsxs64(
8460
+ return /* @__PURE__ */ jsxs65(
8451
8461
  "span",
8452
8462
  {
8453
8463
  title: c.label + (on ? " \u2014 present" : " \u2014 not bought"),
@@ -8460,10 +8470,10 @@ function SurroundSound({ present = [], bonusPct = 0, bonusMax = 40, missedCost,
8460
8470
  c.key
8461
8471
  );
8462
8472
  }) }),
8463
- /* @__PURE__ */ jsxs64("div", { className: "fd-stack", style: { gap: 8 }, children: [
8464
- /* @__PURE__ */ jsxs64("div", { className: "fd-row", style: { justifyContent: "space-between", gap: 12 }, children: [
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: [
8465
8475
  /* @__PURE__ */ jsx69("span", { className: "fd-label-lg", children: "Surround-sound bonus earned" }),
8466
- /* @__PURE__ */ jsxs64("span", { className: "fd-num", style: { color: single ? "var(--warn-text)" : "var(--csi-3-mark)", fontWeight: 700 }, children: [
8476
+ /* @__PURE__ */ jsxs65("span", { className: "fd-num", style: { color: single ? "var(--warn-text)" : "var(--csi-3-mark)", fontWeight: 700 }, children: [
8467
8477
  "+",
8468
8478
  bonusPct,
8469
8479
  "% of +",
@@ -8472,7 +8482,7 @@ function SurroundSound({ present = [], bonusPct = 0, bonusMax = 40, missedCost,
8472
8482
  ] })
8473
8483
  ] }),
8474
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)" } }) }),
8475
- /* @__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: [
8476
8486
  present.length,
8477
8487
  " of 6 channel categories present.",
8478
8488
  " ",
@@ -8484,7 +8494,7 @@ function SurroundSound({ present = [], bonusPct = 0, bonusMax = 40, missedCost,
8484
8494
  }
8485
8495
 
8486
8496
  // src/components/planner/Importance.tsx
8487
- import { jsx as jsx70, jsxs as jsxs65 } from "react/jsx-runtime";
8497
+ import { jsx as jsx70, jsxs as jsxs66 } from "react/jsx-runtime";
8488
8498
  var IMPORTANCE_LEVELS = [
8489
8499
  { id: "nudge", rank: 1, label: "Nudge", icon: "feather", description: "Breaks a tie, nothing more." },
8490
8500
  { id: "lean", rank: 2, label: "Lean", icon: "arrow-bend-up-right", description: "A mild preference between otherwise equal options." },
@@ -8514,7 +8524,7 @@ function importanceTokens(id) {
8514
8524
  function ImportanceTag({ level, showLabel = true, size = "sm", className = "" }) {
8515
8525
  const lvl = importanceLevel(level);
8516
8526
  const t = importanceTokens(level);
8517
- return /* @__PURE__ */ jsxs65(
8527
+ return /* @__PURE__ */ jsxs66(
8518
8528
  "span",
8519
8529
  {
8520
8530
  className: ["fd-imp-tag", size === "md" ? "is-md" : "", className].filter(Boolean).join(" "),
@@ -8529,8 +8539,8 @@ function ImportanceTag({ level, showLabel = true, size = "sm", className = "" })
8529
8539
  }
8530
8540
 
8531
8541
  // src/components/planner/PreferenceMeter.tsx
8532
- import * as React39 from "react";
8533
- 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";
8534
8544
  function preferenceScore(criteria) {
8535
8545
  const earned = criteria.reduce((n, c) => n + (Number(c.earned) || 0), 0);
8536
8546
  const weight = criteria.reduce((n, c) => n + (Number(c.weight) || 0), 0);
@@ -8559,7 +8569,7 @@ function PreferenceMeter({
8559
8569
  className = ""
8560
8570
  }) {
8561
8571
  const value = score == null ? preferenceScore(criteria) : score;
8562
- const segments = React39.useMemo(() => preferenceSegments(criteria), [criteria]);
8572
+ const segments = React40.useMemo(() => preferenceSegments(criteria), [criteria]);
8563
8573
  return /* @__PURE__ */ jsx71(
8564
8574
  ScoreMeter,
8565
8575
  {
@@ -8572,20 +8582,20 @@ function PreferenceMeter({
8572
8582
  placement,
8573
8583
  className,
8574
8584
  breakdownLabel: breakdownTitle,
8575
- breakdown: /* @__PURE__ */ jsxs66("div", { className: "fd-prefbreak", children: [
8576
- /* @__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: [
8577
8587
  /* @__PURE__ */ jsx71("span", { className: "fd-label-lg", children: breakdownTitle }),
8578
8588
  /* @__PURE__ */ jsx71("span", { className: "fd-prefbreak-score fd-tabular", children: Math.round(value) })
8579
8589
  ] }),
8580
8590
  /* @__PURE__ */ jsx71("ul", { className: "fd-prefbreak-list", children: criteria.map((c) => {
8581
8591
  const pct = c.weight > 0 ? Math.round((Number(c.earned) || 0) / c.weight * 100) : 0;
8582
- return /* @__PURE__ */ jsxs66("li", { className: pct === 0 ? "fd-prefbreak-item is-unmet" : "fd-prefbreak-item", children: [
8592
+ return /* @__PURE__ */ jsxs67("li", { className: pct === 0 ? "fd-prefbreak-item is-unmet" : "fd-prefbreak-item", children: [
8583
8593
  /* @__PURE__ */ jsx71(ImportanceTag, { level: c.importance }),
8584
- /* @__PURE__ */ jsxs66("span", { className: "fd-prefbreak-text", children: [
8594
+ /* @__PURE__ */ jsxs67("span", { className: "fd-prefbreak-text", children: [
8585
8595
  /* @__PURE__ */ jsx71("span", { className: "fd-prefbreak-label", children: c.label }),
8586
8596
  c.note ? /* @__PURE__ */ jsx71("span", { className: "fd-prefbreak-note", children: c.note }) : null
8587
8597
  ] }),
8588
- /* @__PURE__ */ jsxs66("span", { className: "fd-prefbreak-val fd-tabular", children: [
8598
+ /* @__PURE__ */ jsxs67("span", { className: "fd-prefbreak-val fd-tabular", children: [
8589
8599
  Math.round(Number(c.earned) || 0),
8590
8600
  /* @__PURE__ */ jsx71("span", { className: "fd-prefbreak-sep", children: "/" }),
8591
8601
  Math.round(c.weight)
@@ -8598,10 +8608,10 @@ function PreferenceMeter({
8598
8608
  }
8599
8609
 
8600
8610
  // src/components/chat/AgentChatPanel.tsx
8601
- import * as React45 from "react";
8611
+ import * as React46 from "react";
8602
8612
 
8603
8613
  // src/components/chat/chatEngine.ts
8604
- import * as React40 from "react";
8614
+ import * as React41 from "react";
8605
8615
  var CHAT_UNAVAILABLE = "chat_unavailable";
8606
8616
  var JOB_PENDING = ["queued", "running"];
8607
8617
  var JOB_SUCCESS = ["completed", "recovered"];
@@ -8655,22 +8665,22 @@ function useChatEngine(opts) {
8655
8665
  onClear,
8656
8666
  onFeedback
8657
8667
  } = opts || {};
8658
- const [status, setStatus] = React40.useState("idle");
8659
- const [threadId, setThreadId] = React40.useState(null);
8660
- const [messages, setMessages] = React40.useState([]);
8661
- const [queue, setQueue] = React40.useState([]);
8662
- const [fatal, setFatal] = React40.useState(null);
8663
- const [busy, setBusy] = React40.useState(false);
8664
- const [turnStartedAt, setTurnStartedAt] = React40.useState(null);
8665
- const listRef = React40.useRef([]);
8666
- const queueRef = React40.useRef([]);
8667
- const busyRef = React40.useRef(false);
8668
- const stoppedRef = React40.useRef(false);
8669
- const abortRef = React40.useRef(null);
8670
- const serverCount = React40.useRef(0);
8671
- const threadRef = React40.useRef(null);
8672
- const mounted = React40.useRef(true);
8673
- React40.useEffect(() => {
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(() => {
8674
8684
  mounted.current = true;
8675
8685
  return () => {
8676
8686
  mounted.current = false;
@@ -8692,14 +8702,14 @@ function useChatEngine(opts) {
8692
8702
  }
8693
8703
  return false;
8694
8704
  };
8695
- const loadThread = React40.useCallback(async (id) => {
8705
+ const loadThread = React41.useCallback(async (id) => {
8696
8706
  const data = await apiAdapter.getThread(id);
8697
8707
  const list = [...data && data.messages || []];
8698
8708
  serverCount.current = list.length;
8699
8709
  commit(list);
8700
8710
  return list;
8701
8711
  }, [apiAdapter]);
8702
- React40.useEffect(() => {
8712
+ React41.useEffect(() => {
8703
8713
  if (!apiAdapter) {
8704
8714
  setStatus("idle");
8705
8715
  setFatal(null);
@@ -8912,7 +8922,7 @@ function useChatEngine(opts) {
8912
8922
  await dispatchTurn(turn);
8913
8923
  }
8914
8924
  }
8915
- const send = React40.useCallback((text, attachments) => {
8925
+ const send = React41.useCallback((text, attachments) => {
8916
8926
  const body = (text || "").trim();
8917
8927
  if (!body && !(attachments && attachments.length)) return;
8918
8928
  if (status === "disconnected") return;
@@ -8922,7 +8932,7 @@ function useChatEngine(opts) {
8922
8932
  stoppedRef.current = false;
8923
8933
  drain();
8924
8934
  }, [status]);
8925
- const stop = React40.useCallback(() => {
8935
+ const stop = React41.useCallback(() => {
8926
8936
  stoppedRef.current = true;
8927
8937
  const ac = abortRef.current;
8928
8938
  if (ac) {
@@ -8941,11 +8951,11 @@ function useChatEngine(opts) {
8941
8951
  store.del(STORAGE_PREFIX + threadRef.current);
8942
8952
  }
8943
8953
  }, [apiAdapter]);
8944
- const removeQueued = React40.useCallback((id) => {
8954
+ const removeQueued = React41.useCallback((id) => {
8945
8955
  queueRef.current = queueRef.current.filter((t) => t.id !== id);
8946
8956
  setQueue(queueRef.current.slice());
8947
8957
  }, []);
8948
- const retry = React40.useCallback(() => {
8958
+ const retry = React41.useCallback(() => {
8949
8959
  const list = listRef.current;
8950
8960
  let at = -1;
8951
8961
  for (let i = list.length - 1; i >= 0; i--) if (list[i].role === "user") {
@@ -8961,19 +8971,19 @@ function useChatEngine(opts) {
8961
8971
  setQueue(queueRef.current.slice());
8962
8972
  drain();
8963
8973
  }, []);
8964
- const clear = React40.useCallback(() => {
8974
+ const clear = React41.useCallback(() => {
8965
8975
  commit([]);
8966
8976
  serverCount.current = 0;
8967
8977
  queueRef.current = [];
8968
8978
  setQueue([]);
8969
8979
  onClear && onClear();
8970
8980
  }, [onClear]);
8971
- const setFeedback = React40.useCallback((id, value) => {
8981
+ const setFeedback = React41.useCallback((id, value) => {
8972
8982
  patch(id, (m) => ({ feedback: m.feedback === value ? null : value }));
8973
8983
  const msg = listRef.current.find((m) => m.id === id);
8974
8984
  onFeedback && onFeedback({ message: msg, feedback: msg ? msg.feedback : value });
8975
8985
  }, [onFeedback]);
8976
- const reload = React40.useCallback(async () => {
8986
+ const reload = React41.useCallback(async () => {
8977
8987
  if (!threadRef.current) return;
8978
8988
  setStatus("loading");
8979
8989
  try {
@@ -9011,11 +9021,11 @@ var ChatKit = {
9011
9021
  };
9012
9022
 
9013
9023
  // src/components/chat/ChatTranscript.tsx
9014
- import * as React42 from "react";
9024
+ import * as React43 from "react";
9015
9025
 
9016
9026
  // src/components/chat/ChatTurn.tsx
9017
- import * as React41 from "react";
9018
- 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";
9019
9029
  function JsonView({ value }) {
9020
9030
  let text;
9021
9031
  try {
@@ -9030,20 +9040,20 @@ function PacketCard({ packet, schema, render, onApply, applied }) {
9030
9040
  const s = schema || {};
9031
9041
  const invalid = packet.valid === false;
9032
9042
  const title = s.heading || packet.type;
9033
- return /* @__PURE__ */ jsxs67("section", { className: "fdc-packet" + (invalid ? " is-invalid" : ""), "aria-label": title, children: [
9034
- /* @__PURE__ */ jsxs67("header", { className: "fdc-packet-head", children: [
9043
+ return /* @__PURE__ */ jsxs68("section", { className: "fdc-packet" + (invalid ? " is-invalid" : ""), "aria-label": title, children: [
9044
+ /* @__PURE__ */ jsxs68("header", { className: "fdc-packet-head", children: [
9035
9045
  /* @__PURE__ */ jsx72("i", { className: "ph ph-" + (s.icon || "package"), "aria-hidden": "true" }),
9036
9046
  /* @__PURE__ */ jsx72("span", { className: "fdc-packet-title", children: title }),
9037
9047
  packet.repaired ? /* @__PURE__ */ jsx72("span", { className: "fdc-packet-badge", children: "Repaired" }) : null,
9038
9048
  invalid ? /* @__PURE__ */ jsx72("span", { className: "fdc-packet-badge is-danger", children: "Invalid" }) : null
9039
9049
  ] }),
9040
- invalid ? /* @__PURE__ */ jsxs67("div", { className: "fdc-packet-alert", role: "alert", children: [
9050
+ invalid ? /* @__PURE__ */ jsxs68("div", { className: "fdc-packet-alert", role: "alert", children: [
9041
9051
  /* @__PURE__ */ jsx72("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
9042
9052
  /* @__PURE__ */ jsx72("span", { children: packet.error || "This result failed validation and can\u2019t be applied." })
9043
9053
  ] }) : /* @__PURE__ */ jsx72("div", { className: "fdc-packet-body", children: render ? render(packet) : /* @__PURE__ */ jsx72(JsonView, { value: packet.payload }) }),
9044
- !invalid && onApply ? /* @__PURE__ */ jsxs67("footer", { className: "fdc-packet-foot", children: [
9054
+ !invalid && onApply ? /* @__PURE__ */ jsxs68("footer", { className: "fdc-packet-foot", children: [
9045
9055
  packet.repaired ? /* @__PURE__ */ jsx72("span", { className: "fdc-packet-note", children: "Corrected by the backend after a first attempt." }) : /* @__PURE__ */ jsx72("span", {}),
9046
- /* @__PURE__ */ jsxs67("button", { type: "button", className: "fd-btn fd-btn-primary fd-btn-sm", disabled: applied, onClick: () => onApply(packet), children: [
9056
+ /* @__PURE__ */ jsxs68("button", { type: "button", className: "fd-btn fd-btn-primary fd-btn-sm", disabled: applied, onClick: () => onApply(packet), children: [
9047
9057
  /* @__PURE__ */ jsx72("i", { className: "ph ph-" + (applied ? "check" : "arrow-square-in"), "aria-hidden": "true" }),
9048
9058
  applied ? "Applied" : s.applyLabel || "Apply"
9049
9059
  ] })
@@ -9051,13 +9061,13 @@ function PacketCard({ packet, schema, render, onApply, applied }) {
9051
9061
  ] });
9052
9062
  }
9053
9063
  function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
9054
- const [open, setOpen] = React41.useState(defaultOpen);
9064
+ const [open, setOpen] = React42.useState(defaultOpen);
9055
9065
  if (!text) return null;
9056
- return /* @__PURE__ */ jsxs67("div", { className: "fdc-think" + (open ? " is-open" : ""), children: [
9057
- /* @__PURE__ */ jsxs67("button", { type: "button", className: "fdc-think-head", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
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: [
9058
9068
  /* @__PURE__ */ jsx72("i", { className: "ph ph-brain", "aria-hidden": "true" }),
9059
9069
  /* @__PURE__ */ jsx72("span", { children: streaming ? "Thinking" : durationMs ? "Thought for " + formatDuration(durationMs) : "Thought process" }),
9060
- streaming ? /* @__PURE__ */ jsxs67("span", { className: "fdc-dots", "aria-hidden": "true", children: [
9070
+ streaming ? /* @__PURE__ */ jsxs68("span", { className: "fdc-dots", "aria-hidden": "true", children: [
9061
9071
  /* @__PURE__ */ jsx72("span", {}),
9062
9072
  /* @__PURE__ */ jsx72("span", {}),
9063
9073
  /* @__PURE__ */ jsx72("span", {})
@@ -9068,19 +9078,19 @@ function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
9068
9078
  ] });
9069
9079
  }
9070
9080
  function Citations({ items = [], onOpen }) {
9071
- const [open, setOpen] = React41.useState(false);
9081
+ const [open, setOpen] = React42.useState(false);
9072
9082
  if (!items.length) return null;
9073
- return /* @__PURE__ */ jsxs67("div", { className: "fdc-cites", children: [
9074
- /* @__PURE__ */ jsxs67("button", { type: "button", className: "fdc-cites-head", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
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: [
9075
9085
  /* @__PURE__ */ jsx72("i", { className: "ph ph-quotes", "aria-hidden": "true" }),
9076
- /* @__PURE__ */ jsxs67("span", { children: [
9086
+ /* @__PURE__ */ jsxs68("span", { children: [
9077
9087
  items.length,
9078
9088
  " source",
9079
9089
  items.length === 1 ? "" : "s"
9080
9090
  ] }),
9081
9091
  /* @__PURE__ */ jsx72("i", { className: "ph ph-caret-" + (open ? "up" : "down"), "aria-hidden": "true" })
9082
9092
  ] }),
9083
- 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: [
9084
9094
  /* @__PURE__ */ jsx72("span", { className: "fdc-cite-n fd-tabular", children: c.marker || i + 1 }),
9085
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" }),
9086
9096
  c.detail ? /* @__PURE__ */ jsx72("span", { className: "fdc-cite-detail", children: c.detail }) : null
@@ -9094,24 +9104,24 @@ function clampText(text, max) {
9094
9104
  return (at > max * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
9095
9105
  }
9096
9106
  function MessageBody({ message: m, ctx }) {
9097
- const [expanded, setExpanded] = React41.useState(false);
9107
+ const [expanded, setExpanded] = React42.useState(false);
9098
9108
  const isUser = m.role === "user";
9099
9109
  const raw = m.text || "";
9100
9110
  const clamped = !expanded && !m.streaming ? clampText(raw, ctx.maxVisibleChars) : null;
9101
9111
  const body = clamped != null ? clamped : raw;
9102
9112
  const showMd = ctx.markdown && !isUser;
9103
- return /* @__PURE__ */ jsxs67("div", { className: "fdc-body", children: [
9113
+ return /* @__PURE__ */ jsxs68("div", { className: "fdc-body", children: [
9104
9114
  m.thinking && ctx.showThinking ? /* @__PURE__ */ jsx72(ThinkingBlock, { text: m.thinking, durationMs: m.thinkingMs, streaming: m.streaming && !m.text }) : null,
9105
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,
9106
- body ? /* @__PURE__ */ jsxs67("div", { className: "fdc-text" + (isUser ? " is-user" : ""), children: [
9116
+ body ? /* @__PURE__ */ jsxs68("div", { className: "fdc-text" + (isUser ? " is-user" : ""), children: [
9107
9117
  showMd ? /* @__PURE__ */ jsx72(Markdown, { source: body, headingOffset: 2, codeProps: { collapseAfter: 22 }, renderCitation: ctx.renderCitation }) : /* @__PURE__ */ jsx72("div", { className: "fdc-plain", children: body }),
9108
9118
  m.streaming ? /* @__PURE__ */ jsx72("span", { className: "fdc-caret", "aria-hidden": "true" }) : null
9109
9119
  ] }) : null,
9110
- 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: [
9111
9121
  /* @__PURE__ */ jsx72("i", { className: "ph ph-caret-down", "aria-hidden": "true" }),
9112
9122
  "Show more",
9113
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" })
9114
- ] }) : 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: [
9115
9125
  /* @__PURE__ */ jsx72("i", { className: "ph ph-caret-up", "aria-hidden": "true" }),
9116
9126
  "Show less"
9117
9127
  ] }) : null,
@@ -9127,33 +9137,33 @@ function MessageBody({ message: m, ctx }) {
9127
9137
  }
9128
9138
  ) : null,
9129
9139
  m.citations && m.citations.length ? /* @__PURE__ */ jsx72(Citations, { items: m.citations, onOpen: ctx.onOpenCitation }) : null,
9130
- m.working ? /* @__PURE__ */ jsxs67("div", { className: "fdc-working", role: "status", children: [
9131
- /* @__PURE__ */ jsxs67("span", { className: "fdc-dots", "aria-hidden": "true", children: [
9140
+ m.working ? /* @__PURE__ */ jsxs68("div", { className: "fdc-working", role: "status", children: [
9141
+ /* @__PURE__ */ jsxs68("span", { className: "fdc-dots", "aria-hidden": "true", children: [
9132
9142
  /* @__PURE__ */ jsx72("span", {}),
9133
9143
  /* @__PURE__ */ jsx72("span", {}),
9134
9144
  /* @__PURE__ */ jsx72("span", {})
9135
9145
  ] }),
9136
- /* @__PURE__ */ jsxs67("span", { className: "fdc-working-label", children: [
9146
+ /* @__PURE__ */ jsxs68("span", { className: "fdc-working-label", children: [
9137
9147
  m.resumed ? "Resuming" : "Working",
9138
- 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: [
9139
9149
  " \xB7 ",
9140
9150
  m.job.status
9141
9151
  ] }) : null,
9142
- 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: [
9143
9153
  " \xB7 ",
9144
9154
  m.job.detail
9145
9155
  ] }) : null
9146
9156
  ] }),
9147
9157
  m.jobId ? /* @__PURE__ */ jsx72("span", { className: "fdc-working-id fd-mono", children: String(m.jobId).slice(0, 12) }) : null
9148
9158
  ] }) : null,
9149
- m.stopped ? /* @__PURE__ */ jsxs67("div", { className: "fdc-stopped", children: [
9159
+ m.stopped ? /* @__PURE__ */ jsxs68("div", { className: "fdc-stopped", children: [
9150
9160
  /* @__PURE__ */ jsx72("i", { className: "ph ph-stop-circle", "aria-hidden": "true" }),
9151
9161
  "Stopped"
9152
9162
  ] }) : null,
9153
- m.error ? /* @__PURE__ */ jsxs67("div", { className: "fdc-error", role: "alert", children: [
9163
+ m.error ? /* @__PURE__ */ jsxs68("div", { className: "fdc-error", role: "alert", children: [
9154
9164
  /* @__PURE__ */ jsx72("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
9155
9165
  /* @__PURE__ */ jsx72("span", { className: "fdc-error-text", children: ctx.errorCopy ? ctx.errorCopy(m.error) : m.error }),
9156
- m.retryable && ctx.onRetry ? /* @__PURE__ */ jsxs67("button", { type: "button", className: "fdc-error-retry", onClick: ctx.onRetry, children: [
9166
+ m.retryable && ctx.onRetry ? /* @__PURE__ */ jsxs68("button", { type: "button", className: "fdc-error-retry", onClick: ctx.onRetry, children: [
9157
9167
  /* @__PURE__ */ jsx72("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }),
9158
9168
  "Retry"
9159
9169
  ] }) : null
@@ -9161,9 +9171,9 @@ function MessageBody({ message: m, ctx }) {
9161
9171
  ] });
9162
9172
  }
9163
9173
  function useCopyRun() {
9164
- const [done, setDone] = React41.useState(false);
9165
- const t = React41.useRef(null);
9166
- React41.useEffect(() => () => {
9174
+ const [done, setDone] = React42.useState(false);
9175
+ const t = React42.useRef(null);
9176
+ React42.useEffect(() => () => {
9167
9177
  if (t.current) clearTimeout(t.current);
9168
9178
  }, []);
9169
9179
  return [done, (text) => {
@@ -9183,14 +9193,14 @@ function RunActions({ group, ctx }) {
9183
9193
  const isAssistant = group.role === "assistant";
9184
9194
  const fb = last.feedback;
9185
9195
  if (!ctx.messageActions) return null;
9186
- return /* @__PURE__ */ jsxs67("div", { className: "fdc-actions", role: "group", "aria-label": "Message actions", children: [
9187
- /* @__PURE__ */ jsxs67("button", { type: "button", className: "fdc-act" + (copied ? " is-done" : ""), onClick: () => copy(markdownToText(text)), "aria-label": "Copy message", children: [
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: [
9188
9198
  /* @__PURE__ */ jsx72("i", { className: "ph ph-" + (copied ? "check" : "copy"), "aria-hidden": "true" }),
9189
9199
  /* @__PURE__ */ jsx72("span", { className: "fdc-act-label", children: copied ? "Copied" : "Copy" })
9190
9200
  ] }),
9191
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,
9192
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,
9193
- isAssistant && ctx.onFeedback ? /* @__PURE__ */ jsxs67(React41.Fragment, { children: [
9203
+ isAssistant && ctx.onFeedback ? /* @__PURE__ */ jsxs68(React42.Fragment, { children: [
9194
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" }) }),
9195
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" }) })
9196
9206
  ] }) : null,
@@ -9202,14 +9212,14 @@ function ChatTurn({ group, ctx }) {
9202
9212
  const name = isUser ? ctx.userName : group.author || ctx.assistantName;
9203
9213
  const avatar = isUser ? ctx.userAvatar : ctx.assistantAvatar;
9204
9214
  const stamp = group.messages[0].timestamp;
9205
- return /* @__PURE__ */ jsxs67("article", { className: "fdc-turn is-" + group.role, "aria-label": String(name) + (stamp ? " at " + formatClock(stamp) : ""), children: [
9206
- /* @__PURE__ */ jsxs67("div", { className: "fdc-turn-head", children: [
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: [
9207
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,
9208
9218
  /* @__PURE__ */ jsx72("span", { className: "fdc-who", children: name }),
9209
9219
  stamp ? /* @__PURE__ */ jsx72(RelativeTime, { className: "fdc-when", value: stamp }) : null,
9210
9220
  group.messages.some((m) => m.model) ? /* @__PURE__ */ jsx72("span", { className: "fdc-turn-model", children: group.messages.find((m) => m.model).model }) : null
9211
9221
  ] }),
9212
- /* @__PURE__ */ jsxs67("div", { className: "fdc-turn-body", children: [
9222
+ /* @__PURE__ */ jsxs68("div", { className: "fdc-turn-body", children: [
9213
9223
  group.messages.map((m) => /* @__PURE__ */ jsx72("div", { className: "fdc-msg" + (m.pending ? " is-pending" : ""), children: /* @__PURE__ */ jsx72(MessageBody, { message: m, ctx }) }, m.id)),
9214
9224
  /* @__PURE__ */ jsx72(RunActions, { group, ctx })
9215
9225
  ] })
@@ -9217,7 +9227,7 @@ function ChatTurn({ group, ctx }) {
9217
9227
  }
9218
9228
 
9219
9229
  // src/components/chat/ChatTranscript.tsx
9220
- import { jsx as jsx73, jsxs as jsxs68 } from "react/jsx-runtime";
9230
+ import { jsx as jsx73, jsxs as jsxs69 } from "react/jsx-runtime";
9221
9231
  var GROUP_WINDOW = 6e4;
9222
9232
  var STICK_PX = 100;
9223
9233
  function groupMessages(list) {
@@ -9252,9 +9262,9 @@ function Suggestions({ items = [], onPick }) {
9252
9262
  if (!items.length) return null;
9253
9263
  return /* @__PURE__ */ jsx73("div", { className: "fdc-suggest", children: items.map((s, i) => {
9254
9264
  const it = typeof s === "string" ? { label: s, text: s } : s;
9255
- return /* @__PURE__ */ jsxs68("button", { type: "button", className: "fdc-suggest-item", onClick: () => onPick && onPick(it.text || it.label), children: [
9265
+ return /* @__PURE__ */ jsxs69("button", { type: "button", className: "fdc-suggest-item", onClick: () => onPick && onPick(it.text || it.label), children: [
9256
9266
  it.icon ? /* @__PURE__ */ jsx73("i", { className: "ph ph-" + it.icon, "aria-hidden": "true" }) : null,
9257
- /* @__PURE__ */ jsxs68("span", { className: "fdc-suggest-text", children: [
9267
+ /* @__PURE__ */ jsxs69("span", { className: "fdc-suggest-text", children: [
9258
9268
  /* @__PURE__ */ jsx73("span", { className: "fdc-suggest-label", children: it.label }),
9259
9269
  it.description ? /* @__PURE__ */ jsx73("span", { className: "fdc-suggest-desc", children: it.description }) : null
9260
9270
  ] }),
@@ -9263,9 +9273,9 @@ function Suggestions({ items = [], onPick }) {
9263
9273
  }) });
9264
9274
  }
9265
9275
  function LoadingTurns() {
9266
- return /* @__PURE__ */ jsx73("div", { className: "fdc-skel", "aria-hidden": "true", children: [0, 1].map((i) => /* @__PURE__ */ jsxs68("div", { className: "fdc-skel-turn", children: [
9276
+ return /* @__PURE__ */ jsx73("div", { className: "fdc-skel", "aria-hidden": "true", children: [0, 1].map((i) => /* @__PURE__ */ jsxs69("div", { className: "fdc-skel-turn", children: [
9267
9277
  /* @__PURE__ */ jsx73("div", { className: "fd-skel fd-skel-circle", style: { width: 22, height: 22 } }),
9268
- /* @__PURE__ */ jsxs68("div", { className: "fdc-skel-lines", children: [
9278
+ /* @__PURE__ */ jsxs69("div", { className: "fdc-skel-lines", children: [
9269
9279
  /* @__PURE__ */ jsx73("div", { className: "fd-skel", style: { width: i ? "62%" : "44%", height: 11 } }),
9270
9280
  /* @__PURE__ */ jsx73("div", { className: "fd-skel", style: { width: i ? "94%" : "78%", height: 11 } }),
9271
9281
  /* @__PURE__ */ jsx73("div", { className: "fd-skel", style: { width: i ? "71%" : "56%", height: 11 } })
@@ -9285,10 +9295,10 @@ function ChatTranscript({
9285
9295
  renderEmpty,
9286
9296
  className = ""
9287
9297
  }) {
9288
- const scroller = React42.useRef(null);
9289
- const stick = React42.useRef(true);
9290
- const [pill, setPill] = React42.useState(0);
9291
- const seen = React42.useRef(0);
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);
9292
9302
  const toBottom = (smooth) => {
9293
9303
  const el = scroller.current;
9294
9304
  if (!el) return;
@@ -9307,7 +9317,7 @@ function ChatTranscript({
9307
9317
  seen.current = messages.length;
9308
9318
  }
9309
9319
  };
9310
- React42.useLayoutEffect(() => {
9320
+ React43.useLayoutEffect(() => {
9311
9321
  const el = scroller.current;
9312
9322
  if (!el) return;
9313
9323
  if (stick.current) {
@@ -9315,7 +9325,7 @@ function ChatTranscript({
9315
9325
  seen.current = messages.length;
9316
9326
  } else setPill(Math.max(0, messages.length - seen.current));
9317
9327
  }, [messages]);
9318
- React42.useEffect(() => {
9328
+ React43.useEffect(() => {
9319
9329
  const el = scroller.current;
9320
9330
  const inner = el && el.firstChild;
9321
9331
  if (!el || !inner || typeof ResizeObserver === "undefined") return;
@@ -9325,21 +9335,21 @@ function ChatTranscript({
9325
9335
  ro.observe(inner);
9326
9336
  return () => ro.disconnect();
9327
9337
  }, []);
9328
- const groups = React42.useMemo(() => groupMessages(messages), [messages]);
9338
+ const groups = React43.useMemo(() => groupMessages(messages), [messages]);
9329
9339
  const empty = !messages.length && status === "ready";
9330
- return /* @__PURE__ */ jsxs68("div", { className: ["fdc-scroll", className].filter(Boolean).join(" "), ref: scroller, onScroll, children: [
9331
- /* @__PURE__ */ jsxs68("div", { className: "fdc-log", role: "log", "aria-label": "Conversation", children: [
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: [
9332
9342
  status === "loading" || status === "resolving" ? /* @__PURE__ */ jsx73(LoadingTurns, {}) : null,
9333
- status === "disconnected" ? /* @__PURE__ */ jsxs68("div", { className: "fdc-dead", children: [
9343
+ status === "disconnected" ? /* @__PURE__ */ jsxs69("div", { className: "fdc-dead", children: [
9334
9344
  /* @__PURE__ */ jsx73("span", { className: "fdc-dead-icon", children: /* @__PURE__ */ jsx73("i", { className: "ph ph-plugs", "aria-hidden": "true" }) }),
9335
9345
  /* @__PURE__ */ jsx73("h3", { className: "fdc-dead-title", children: ctx.deadTitle || "The assistant isn\u2019t reachable" }),
9336
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." }),
9337
- 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: [
9338
9348
  /* @__PURE__ */ jsx73("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }),
9339
9349
  "Try again"
9340
9350
  ] }) : null
9341
9351
  ] }) : null,
9342
- empty ? renderEmpty ? renderEmpty() : /* @__PURE__ */ jsxs68("div", { className: "fdc-empty", children: [
9352
+ empty ? renderEmpty ? renderEmpty() : /* @__PURE__ */ jsxs69("div", { className: "fdc-empty", children: [
9343
9353
  /* @__PURE__ */ jsx73("span", { className: "fdc-empty-icon", children: /* @__PURE__ */ jsx73("i", { className: "ph ph-" + emptyIcon, "aria-hidden": "true" }) }),
9344
9354
  /* @__PURE__ */ jsx73("h3", { className: "fdc-empty-title", children: emptyTitle }),
9345
9355
  emptyDescription ? /* @__PURE__ */ jsx73("p", { className: "fdc-empty-body", children: emptyDescription }) : null,
@@ -9349,13 +9359,13 @@ function ChatTranscript({
9349
9359
  const prev = groups[i - 1];
9350
9360
  const k = dayKey(g.messages[0].timestamp);
9351
9361
  const showDay = !!k && (!prev || dayKey(prev.messages[0].timestamp) !== k);
9352
- return /* @__PURE__ */ jsxs68(React42.Fragment, { children: [
9362
+ return /* @__PURE__ */ jsxs69(React43.Fragment, { children: [
9353
9363
  showDay ? /* @__PURE__ */ jsx73("div", { className: "fdc-day", children: /* @__PURE__ */ jsx73("span", { children: dayLabel(k) }) }) : null,
9354
9364
  /* @__PURE__ */ jsx73(ChatTurn, { group: g, ctx })
9355
9365
  ] }, g.key || i);
9356
9366
  })
9357
9367
  ] }),
9358
- 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: [
9359
9369
  /* @__PURE__ */ jsx73("i", { className: "ph ph-arrow-down", "aria-hidden": "true" }),
9360
9370
  pill,
9361
9371
  " new message",
@@ -9366,8 +9376,8 @@ function ChatTranscript({
9366
9376
  var TranscriptKit = { groupMessages };
9367
9377
 
9368
9378
  // src/components/chat/ChatComposer.tsx
9369
- import * as React43 from "react";
9370
- 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";
9371
9381
  function ChatComposer({
9372
9382
  onSubmit,
9373
9383
  onStop,
@@ -9394,17 +9404,17 @@ function ChatComposer({
9394
9404
  onReject,
9395
9405
  onOpenAttachment
9396
9406
  }) {
9397
- const [text, setText] = React43.useState(draft || "");
9398
- const [trigger, setTrigger] = React43.useState(null);
9399
- const [mentionItems, setMentionItems] = React43.useState([]);
9400
- const [listening, setListening] = React43.useState(false);
9401
- const [notice, setNotice] = React43.useState(null);
9402
- const editor = React43.useRef(null);
9403
- const wrap = React43.useRef(null);
9404
- const stopVoice = React43.useRef(null);
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);
9405
9415
  const staged = useStagedFiles(fileUploadHandler, { onError: () => {
9406
9416
  } });
9407
- React43.useEffect(() => {
9417
+ React44.useEffect(() => {
9408
9418
  if (draft != null && draft !== text) setText(draft);
9409
9419
  }, [draft]);
9410
9420
  const change = (v) => {
@@ -9438,7 +9448,7 @@ function ChatComposer({
9438
9448
  e.preventDefault();
9439
9449
  staged.add(found.files);
9440
9450
  };
9441
- React43.useEffect(() => {
9451
+ React44.useEffect(() => {
9442
9452
  if (!trigger || trigger.type !== "mention" || !mentionSources) {
9443
9453
  setMentionItems([]);
9444
9454
  return;
@@ -9456,7 +9466,7 @@ function ChatComposer({
9456
9466
  const q = (trigger.query || "").toLowerCase();
9457
9467
  setMentionItems(mentionSources.filter((m) => !q || (m.label + " " + (m.description || "")).toLowerCase().includes(q)));
9458
9468
  }, [trigger, mentionSources]);
9459
- const slashItems = React43.useMemo(() => {
9469
+ const slashItems = React44.useMemo(() => {
9460
9470
  if (!trigger || trigger.type !== "slash" || !slashCommands) return [];
9461
9471
  const q = (trigger.query || "").toLowerCase();
9462
9472
  return slashCommands.filter((c) => !q || (c.id + " " + c.label + " " + (c.description || "")).toLowerCase().includes(q));
@@ -9533,8 +9543,8 @@ function ChatComposer({
9533
9543
  stopVoice.current = typeof res === "function" ? res : () => {
9534
9544
  };
9535
9545
  };
9536
- return /* @__PURE__ */ jsxs69("div", { className: "fdc-composer" + (disabled ? " is-disabled" : "") + (narrow ? " is-narrow" : ""), children: [
9537
- queue.length ? /* @__PURE__ */ jsx74("div", { className: "fdc-queue", "aria-label": "Queued messages", children: queue.map((q) => /* @__PURE__ */ jsxs69("div", { className: "fdc-queue-row", children: [
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: [
9538
9548
  /* @__PURE__ */ jsx74("i", { className: "ph ph-clock-countdown", "aria-hidden": "true" }),
9539
9549
  /* @__PURE__ */ jsx74("span", { className: "fdc-queue-text", children: q.text || (q.attachments ? q.attachments.length + " file(s)" : "") }),
9540
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
@@ -9554,7 +9564,7 @@ function ChatComposer({
9554
9564
  disabled: !fileUploadHandler || disabled,
9555
9565
  label: "Drop to attach",
9556
9566
  hint: acceptFiles ? acceptFiles.replace(/,/g, " \xB7 ") : void 0,
9557
- children: /* @__PURE__ */ jsxs69("div", { ref: wrap, className: "fdc-field-inner", children: [
9567
+ children: /* @__PURE__ */ jsxs70("div", { ref: wrap, className: "fdc-field-inner", children: [
9558
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,
9559
9569
  /* @__PURE__ */ jsx74(
9560
9570
  MarkdownEditor,
@@ -9575,20 +9585,20 @@ function ChatComposer({
9575
9585
  ariaLabel: "Message"
9576
9586
  }
9577
9587
  ),
9578
- /* @__PURE__ */ jsxs69("div", { className: "fdc-tools", children: [
9588
+ /* @__PURE__ */ jsxs70("div", { className: "fdc-tools", children: [
9579
9589
  fileUploadHandler ? /* @__PURE__ */ jsx74(FilePickButton, { onFiles: staged.add, onReject: (r) => flash(r[0].message), accept: acceptFiles, maxFileSize, label: "Attach files", icon: "plus" }) : null,
9580
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,
9581
9591
  toolbarExtras,
9582
9592
  /* @__PURE__ */ jsx74("span", { className: "fdc-tools-gap" }),
9583
- maxLength && text.length > maxLength * 0.6 ? /* @__PURE__ */ jsxs69("span", { className: "fdc-count fd-tabular" + (text.length > maxLength * 0.95 ? " is-hot" : ""), children: [
9593
+ maxLength && text.length > maxLength * 0.6 ? /* @__PURE__ */ jsxs70("span", { className: "fdc-count fd-tabular" + (text.length > maxLength * 0.95 ? " is-hot" : ""), children: [
9584
9594
  text.length,
9585
9595
  "/",
9586
9596
  maxLength
9587
9597
  ] }) : null,
9588
- 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: [
9589
9599
  /* @__PURE__ */ jsx74("i", { className: "ph ph-stop-circle", "aria-hidden": "true" }),
9590
9600
  /* @__PURE__ */ jsx74("span", { children: "Stop" })
9591
- ] }) : /* @__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: [
9592
9602
  /* @__PURE__ */ jsx74("i", { className: "ph ph-paper-plane-right", "aria-hidden": "true" }),
9593
9603
  /* @__PURE__ */ jsx74("span", { className: "fdc-send-label", children: "Send" })
9594
9604
  ] })
@@ -9596,7 +9606,7 @@ function ChatComposer({
9596
9606
  ] })
9597
9607
  }
9598
9608
  ),
9599
- notice ? /* @__PURE__ */ jsxs69("div", { className: "fdc-notice", role: "status", children: [
9609
+ notice ? /* @__PURE__ */ jsxs70("div", { className: "fdc-notice", role: "status", children: [
9600
9610
  /* @__PURE__ */ jsx74("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
9601
9611
  notice
9602
9612
  ] }) : null,
@@ -9630,12 +9640,12 @@ function ChatComposer({
9630
9640
  }
9631
9641
 
9632
9642
  // src/components/chat/ChatSessionBar.tsx
9633
- import * as React44 from "react";
9634
- 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";
9635
9645
  var compact2 = meterFormats.compact;
9636
9646
  function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extras }) {
9637
- const [open, setOpen] = React44.useState(false);
9638
- const anchor = React44.useRef(null);
9647
+ const [open, setOpen] = React45.useState(false);
9648
+ const anchor = React45.useRef(null);
9639
9649
  const stats = sessionStats || null;
9640
9650
  const cu = contextUsage || null;
9641
9651
  const limits = usageLimits || null;
@@ -9650,9 +9660,9 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
9650
9660
  if (stats && stats.runningTasks) bits.push(stats.runningTasks + " running task" + (stats.runningTasks === 1 ? "" : "s"));
9651
9661
  if (cu) bits.push(pct + "% context");
9652
9662
  const expandable = !!(cu || limits);
9653
- return /* @__PURE__ */ jsxs70(React44.Fragment, { children: [
9654
- /* @__PURE__ */ jsxs70("div", { className: "fdc-bar", children: [
9655
- /* @__PURE__ */ jsxs70(
9663
+ return /* @__PURE__ */ jsxs71(React45.Fragment, { children: [
9664
+ /* @__PURE__ */ jsxs71("div", { className: "fdc-bar", children: [
9665
+ /* @__PURE__ */ jsxs71(
9656
9666
  "button",
9657
9667
  {
9658
9668
  type: "button",
@@ -9682,14 +9692,14 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
9682
9692
  maxHeight: 460,
9683
9693
  padded: true,
9684
9694
  label: "Usage",
9685
- 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: () => {
9686
9696
  setOpen(false);
9687
9697
  onClear();
9688
9698
  }, children: [
9689
9699
  /* @__PURE__ */ jsx75("i", { className: "ph ph-trash", "aria-hidden": "true" }),
9690
9700
  "Clear conversation"
9691
9701
  ] }) : void 0,
9692
- children: /* @__PURE__ */ jsxs70("div", { className: "fdc-usage", children: [
9702
+ children: /* @__PURE__ */ jsxs71("div", { className: "fdc-usage", children: [
9693
9703
  cu ? /* @__PURE__ */ jsx75("section", { className: "fdc-usage-sec", children: /* @__PURE__ */ jsx75(
9694
9704
  SegmentedMeter,
9695
9705
  {
@@ -9702,7 +9712,7 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
9702
9712
  remainderLabel: "Free"
9703
9713
  }
9704
9714
  ) }) : null,
9705
- limits && limits.length ? /* @__PURE__ */ jsxs70("section", { className: "fdc-usage-sec", children: [
9715
+ limits && limits.length ? /* @__PURE__ */ jsxs71("section", { className: "fdc-usage-sec", children: [
9706
9716
  /* @__PURE__ */ jsx75("h4", { className: "fdc-usage-h", children: "Usage limits" }),
9707
9717
  /* @__PURE__ */ jsx75("div", { className: "fdc-usage-rows", children: limits.map((l) => /* @__PURE__ */ jsx75(
9708
9718
  QuotaRow,
@@ -9714,23 +9724,23 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
9714
9724
  l.id
9715
9725
  )) })
9716
9726
  ] }) : null,
9717
- stats ? /* @__PURE__ */ jsxs70("section", { className: "fdc-usage-sec fdc-usage-stats", children: [
9718
- 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: [
9719
9729
  /* @__PURE__ */ jsx75("span", { children: "Session" }),
9720
9730
  /* @__PURE__ */ jsx75("b", { className: "fd-tabular", children: formatDuration(stats.elapsedMs) })
9721
9731
  ] }) : null,
9722
- stats.tokens ? /* @__PURE__ */ jsxs70("div", { children: [
9732
+ stats.tokens ? /* @__PURE__ */ jsxs71("div", { children: [
9723
9733
  /* @__PURE__ */ jsx75("span", { children: "Tokens" }),
9724
9734
  /* @__PURE__ */ jsx75("b", { className: "fd-tabular", children: stats.tokens.toLocaleString() })
9725
9735
  ] }) : null,
9726
- stats.costUsd != null ? /* @__PURE__ */ jsxs70("div", { children: [
9736
+ stats.costUsd != null ? /* @__PURE__ */ jsxs71("div", { children: [
9727
9737
  /* @__PURE__ */ jsx75("span", { children: "Cost" }),
9728
- /* @__PURE__ */ jsxs70("b", { className: "fd-tabular", children: [
9738
+ /* @__PURE__ */ jsxs71("b", { className: "fd-tabular", children: [
9729
9739
  "$",
9730
9740
  Number(stats.costUsd).toFixed(3)
9731
9741
  ] })
9732
9742
  ] }) : null,
9733
- stats.turns ? /* @__PURE__ */ jsxs70("div", { children: [
9743
+ stats.turns ? /* @__PURE__ */ jsxs71("div", { children: [
9734
9744
  /* @__PURE__ */ jsx75("span", { children: "Turns" }),
9735
9745
  /* @__PURE__ */ jsx75("b", { className: "fd-tabular", children: stats.turns })
9736
9746
  ] }) : null
@@ -9784,14 +9794,14 @@ function ModelControls({
9784
9794
  items.push({ kind: "section", label: "Fast mode" });
9785
9795
  items.push({
9786
9796
  kind: "custom",
9787
- render: () => /* @__PURE__ */ jsxs70("label", { className: "fdc-switchrow", children: [
9797
+ render: () => /* @__PURE__ */ jsxs71("label", { className: "fdc-switchrow", children: [
9788
9798
  /* @__PURE__ */ jsx75("span", { children: fastModeLabel }),
9789
9799
  /* @__PURE__ */ jsx75("input", { type: "checkbox", className: "fd-sr", checked: !!fastMode, onChange: (e) => onFastModeChange(e.target.checked) }),
9790
9800
  /* @__PURE__ */ jsx75("span", { className: "fd-switch-track" + (fastMode ? " is-on" : ""), "aria-hidden": "true", children: /* @__PURE__ */ jsx75("span", { className: "fd-switch-thumb" }) })
9791
9801
  ] })
9792
9802
  });
9793
9803
  }
9794
- return /* @__PURE__ */ jsxs70(React44.Fragment, { children: [
9804
+ return /* @__PURE__ */ jsxs71(React45.Fragment, { children: [
9795
9805
  /* @__PURE__ */ jsx75(
9796
9806
  MenuButton,
9797
9807
  {
@@ -9824,7 +9834,7 @@ function ModelControls({
9824
9834
  }
9825
9835
 
9826
9836
  // src/components/chat/AgentChatPanel.tsx
9827
- import { jsx as jsx76, jsxs as jsxs71 } from "react/jsx-runtime";
9837
+ import { jsx as jsx76, jsxs as jsxs72 } from "react/jsx-runtime";
9828
9838
  var SURFACES = { sidebar: "is-sidebar", inline: "is-inline", page: "is-page", modal: "is-modal", sheet: "is-sheet" };
9829
9839
  function AgentChatPanel({
9830
9840
  /* required */
@@ -9908,11 +9918,11 @@ function AgentChatPanel({
9908
9918
  onFeedback,
9909
9919
  onEditMessage
9910
9920
  }) {
9911
- const [panelWidth, setPanelWidth] = React45.useState(width);
9912
- const [applied, setApplied] = React45.useState({});
9913
- const [draft, setDraft] = React45.useState("");
9914
- const dragging = React45.useRef(null);
9915
- React45.useEffect(() => setPanelWidth(width), [width]);
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]);
9916
9926
  const engine = useChatEngine({
9917
9927
  contextType,
9918
9928
  contextId,
@@ -10029,7 +10039,7 @@ function AgentChatPanel({
10029
10039
  })))
10030
10040
  }
10031
10041
  ) : null;
10032
- return /* @__PURE__ */ jsxs71(
10042
+ return /* @__PURE__ */ jsxs72(
10033
10043
  "aside",
10034
10044
  {
10035
10045
  className: ["fdc-panel", SURFACES[surface] || SURFACES.sidebar, narrow ? "is-narrow" : "", className].filter(Boolean).join(" "),
@@ -10055,13 +10065,13 @@ function AgentChatPanel({
10055
10065
  }
10056
10066
  }
10057
10067
  ) : null,
10058
- showHeader ? /* @__PURE__ */ jsxs71("header", { className: "fdc-head", children: [
10068
+ showHeader ? /* @__PURE__ */ jsxs72("header", { className: "fdc-head", children: [
10059
10069
  /* @__PURE__ */ jsx76("span", { className: "fdc-head-mark", "aria-hidden": "true", children: /* @__PURE__ */ jsx76("i", { className: "ph ph-" + assistantIcon }) }),
10060
- /* @__PURE__ */ jsxs71("span", { className: "fdc-head-titles", children: [
10070
+ /* @__PURE__ */ jsxs72("span", { className: "fdc-head-titles", children: [
10061
10071
  /* @__PURE__ */ jsx76("span", { className: "fdc-head-title", children: title }),
10062
10072
  subtitle ? /* @__PURE__ */ jsx76("span", { className: "fdc-head-sub", children: subtitle }) : null
10063
10073
  ] }),
10064
- /* @__PURE__ */ jsxs71("span", { className: "fdc-head-acts", children: [
10074
+ /* @__PURE__ */ jsxs72("span", { className: "fdc-head-acts", children: [
10065
10075
  headerActions,
10066
10076
  threadMenu,
10067
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,
@@ -10116,7 +10126,7 @@ function AgentChatPanel({
10116
10126
  }
10117
10127
 
10118
10128
  // src/kits/query.ts
10119
- import * as React46 from "react";
10129
+ import * as React47 from "react";
10120
10130
  function eqFilter(get2) {
10121
10131
  return (row, value) => Array.isArray(value) ? value.includes(get2(row)) : get2(row) === value;
10122
10132
  }
@@ -10148,22 +10158,22 @@ function compare(a, b, dir) {
10148
10158
  var API = null;
10149
10159
  var PREFS = null;
10150
10160
  function useServerTable({ endpoint, params, defaults, deps, prefsKey }) {
10151
- const [query, setQuery] = React46.useState(() => {
10161
+ const [query, setQuery] = React47.useState(() => {
10152
10162
  const store = PREFS || window.PlannerPrefs;
10153
10163
  const saved = prefsKey && store ? store.getTable(prefsKey) : {};
10154
10164
  return { ...DEFAULTS, ...defaults || {}, ...saved.pageSize ? { pageSize: saved.pageSize } : {}, ...saved.sort ? { sort: saved.sort, dir: saved.dir || "desc" } : {} };
10155
10165
  });
10156
- const savePref = React46.useCallback((patch2) => {
10166
+ const savePref = React47.useCallback((patch2) => {
10157
10167
  const store = PREFS || window.PlannerPrefs;
10158
10168
  if (prefsKey && store) store.setTable(prefsKey, patch2);
10159
10169
  }, [prefsKey]);
10160
- const [res, setRes] = React46.useState(null);
10161
- const [loading, setLoading] = React46.useState(true);
10162
- 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);
10163
10173
  const depKey = (deps || []).join("|");
10164
10174
  const paramKey = JSON.stringify(params || {});
10165
10175
  const queryKey = JSON.stringify(query);
10166
- React46.useEffect(() => {
10176
+ React47.useEffect(() => {
10167
10177
  const id = ++seq2.current;
10168
10178
  setLoading(true);
10169
10179
  const t = setTimeout(() => {