@flytedan/flytebot-design-system 0.48.0 → 0.49.0

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
@@ -851,28 +851,28 @@ function Card({
851
851
  interactive ? "fd-card-interactive" : "",
852
852
  className
853
853
  ].filter(Boolean).join(" ");
854
- const head = title ? /* @__PURE__ */ jsxs4("div", { className: "fd-card-head", children: [
854
+ const titleOnlyHead = title ? /* @__PURE__ */ jsxs4("div", { className: "fd-card-head", children: [
855
855
  /* @__PURE__ */ jsx7("span", { className: "fd-card-head-title", title: truncationTitle(title), children: title }),
856
- action
856
+ !interactive && action
857
857
  ] }) : null;
858
858
  const body = padded ? /* @__PURE__ */ jsx7("div", { className: "fd-card-body", children }) : children;
859
859
  const foot = footer ? /* @__PURE__ */ jsx7("div", { className: "fd-card-foot", children: footer }) : null;
860
- if (href != null) {
861
- return /* @__PURE__ */ jsxs4("a", { href, onClick, className: cls, role, tabIndex, ...rest, children: [
862
- head,
863
- body,
864
- foot
860
+ if (interactive) {
861
+ const inner = href != null ? /* @__PURE__ */ jsxs4("a", { href, onClick, className: cls, role, tabIndex, ...rest, children: [
862
+ titleOnlyHead,
863
+ body
864
+ ] }) : /* @__PURE__ */ jsxs4("button", { type: "button", onClick, className: cls, role, tabIndex, ...rest, children: [
865
+ titleOnlyHead,
866
+ body
865
867
  ] });
866
- }
867
- if (onClick != null) {
868
- return /* @__PURE__ */ jsxs4("button", { type: "button", onClick, className: cls, role, tabIndex, ...rest, children: [
869
- head,
870
- body,
868
+ return /* @__PURE__ */ jsxs4("div", { className: "fd-card-shell", children: [
869
+ inner,
870
+ action ? /* @__PURE__ */ jsx7("div", { className: "fd-card-shell-action", children: action }) : null,
871
871
  foot
872
872
  ] });
873
873
  }
874
874
  return /* @__PURE__ */ jsxs4("div", { className: cls, role, tabIndex, ...rest, children: [
875
- head,
875
+ titleOnlyHead,
876
876
  body,
877
877
  foot
878
878
  ] });
@@ -1046,8 +1046,21 @@ function ScreenHead({ kicker, title, lede, actions }) {
1046
1046
  // src/components/layout/CardGrid.tsx
1047
1047
  import * as React8 from "react";
1048
1048
  import { jsx as jsx12 } from "react/jsx-runtime";
1049
+ function flattenFragments(children) {
1050
+ const out = [];
1051
+ React8.Children.forEach(children, (child) => {
1052
+ if (child === null || child === void 0 || typeof child === "boolean") return;
1053
+ if (React8.isValidElement(child) && child.type === React8.Fragment) {
1054
+ const fragmentChildren = child.props.children;
1055
+ out.push(...flattenFragments(fragmentChildren));
1056
+ return;
1057
+ }
1058
+ out.push(child);
1059
+ });
1060
+ return out;
1061
+ }
1049
1062
  function CardGrid({ children, minCardWidth = 280, gap = "lg", className = "", style }) {
1050
- const items = React8.Children.toArray(children);
1063
+ const items = flattenFragments(children);
1051
1064
  return /* @__PURE__ */ jsx12(
1052
1065
  "div",
1053
1066
  {
@@ -1055,10 +1068,12 @@ function CardGrid({ children, minCardWidth = 280, gap = "lg", className = "", st
1055
1068
  className: ["fd-card-grid", "fd-gap-" + gap, className].filter(Boolean).join(" "),
1056
1069
  style: { ["--card-grid-min"]: minCardWidth + "px", ...style },
1057
1070
  children: items.map((child, i) => {
1058
- if (!React8.isValidElement(child)) return child;
1059
- const existingProps = child.props;
1060
- if (existingProps.role) return child;
1061
- return React8.cloneElement(child, { role: "listitem", key: child.key ?? i });
1071
+ if (React8.isValidElement(child)) {
1072
+ const existingRole = child.props.role;
1073
+ if (existingRole) return child;
1074
+ return /* @__PURE__ */ jsx12("div", { role: "listitem", children: child }, child.key ?? i);
1075
+ }
1076
+ return /* @__PURE__ */ jsx12("div", { role: "listitem", children: child }, i);
1062
1077
  })
1063
1078
  }
1064
1079
  );
@@ -1330,7 +1345,7 @@ var SidebarNav = React11.forwardRef(function SidebarNav2({ brand, groups = [], c
1330
1345
 
1331
1346
  // src/components/navigation/Topbar.tsx
1332
1347
  import * as React12 from "react";
1333
- import { Fragment as Fragment3, jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
1348
+ import { Fragment as Fragment4, jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
1334
1349
  function useIsNarrow(breakpoint) {
1335
1350
  const [narrow, setNarrow] = React12.useState(
1336
1351
  () => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(`(max-width: ${breakpoint}px)`).matches
@@ -1379,7 +1394,7 @@ function Topbar({
1379
1394
  }
1380
1395
  )
1381
1396
  ] }, i)) }),
1382
- overflowActions != null ? narrow ? /* @__PURE__ */ jsxs14(Fragment3, { children: [
1397
+ overflowActions != null ? narrow ? /* @__PURE__ */ jsxs14(Fragment4, { children: [
1383
1398
  /* @__PURE__ */ jsx20(
1384
1399
  "button",
1385
1400
  {
@@ -1689,12 +1704,12 @@ function EmptyState({ icon = "tray", title, children, action, className = "", ..
1689
1704
  }
1690
1705
 
1691
1706
  // src/components/feedback/Flag.tsx
1692
- import { Fragment as Fragment4, jsx as jsx28, jsxs as jsxs22 } from "react/jsx-runtime";
1707
+ import { Fragment as Fragment5, jsx as jsx28, jsxs as jsxs22 } from "react/jsx-runtime";
1693
1708
  function Flag({ statement, cost, actions, tone = "warning", className = "", ...rest }) {
1694
1709
  return /* @__PURE__ */ jsxs22("div", { className: ["fd-flag", "fd-flag-" + tone, className].filter(Boolean).join(" "), role: "status", ...rest, children: [
1695
1710
  /* @__PURE__ */ jsxs22("span", { className: "fd-flag-text", children: [
1696
1711
  statement,
1697
- cost ? /* @__PURE__ */ jsxs22(Fragment4, { children: [
1712
+ cost ? /* @__PURE__ */ jsxs22(Fragment5, { children: [
1698
1713
  " ",
1699
1714
  /* @__PURE__ */ jsx28("span", { className: "fd-flag-cost", children: cost })
1700
1715
  ] }) : null
@@ -1921,7 +1936,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
1921
1936
 
1922
1937
  // src/components/data/AnimNum.tsx
1923
1938
  import * as React15 from "react";
1924
- import { Fragment as Fragment5, jsx as jsx33 } from "react/jsx-runtime";
1939
+ import { Fragment as Fragment6, jsx as jsx33 } from "react/jsx-runtime";
1925
1940
  function shouldSkipEasing() {
1926
1941
  if (typeof document !== "undefined" && document.hidden) return true;
1927
1942
  return window.matchMedia?.("(prefers-reduced-motion: reduce)").matches ?? false;
@@ -1953,7 +1968,7 @@ function AnimNum({ value, format, duration = 550 }) {
1953
1968
  setDisplay(to);
1954
1969
  };
1955
1970
  }, [value, duration]);
1956
- return /* @__PURE__ */ jsx33(Fragment5, { children: format ? format(display) : Math.round(display).toLocaleString() });
1971
+ return /* @__PURE__ */ jsx33(Fragment6, { children: format ? format(display) : Math.round(display).toLocaleString() });
1957
1972
  }
1958
1973
 
1959
1974
  // src/components/data/TrendChart.tsx
@@ -4436,7 +4451,7 @@ function StatTile({ label, value, sub, delta, invert = false, loading = false, c
4436
4451
 
4437
4452
  // src/components/data/CodeBlock.tsx
4438
4453
  import * as React27 from "react";
4439
- import { Fragment as Fragment6, jsx as jsx49, jsxs as jsxs41 } from "react/jsx-runtime";
4454
+ import { Fragment as Fragment7, jsx as jsx49, jsxs as jsxs41 } from "react/jsx-runtime";
4440
4455
  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)$/;
4441
4456
  var RULES = {
4442
4457
  js: [
@@ -4592,7 +4607,7 @@ function tokenize(src, lang) {
4592
4607
  }
4593
4608
  function Highlighted({ code, lang }) {
4594
4609
  const toks = React27.useMemo(() => tokenize(code, lang), [code, lang]);
4595
- return /* @__PURE__ */ jsx49(Fragment6, { children: toks.map((tk, i) => tk.c ? /* @__PURE__ */ jsx49("span", { className: "tok-" + tk.c, children: tk.t }, i) : tk.t) });
4610
+ return /* @__PURE__ */ jsx49(Fragment7, { children: toks.map((tk, i) => tk.c ? /* @__PURE__ */ jsx49("span", { className: "tok-" + tk.c, children: tk.t }, i) : tk.t) });
4596
4611
  }
4597
4612
  function useCopy() {
4598
4613
  const [done, setDone] = React27.useState(false);
@@ -4626,7 +4641,7 @@ function CodeBlock({
4626
4641
  code = "",
4627
4642
  language,
4628
4643
  filename,
4629
- lineNumbers = false,
4644
+ lineNumbers: lineNumbers2 = false,
4630
4645
  wrap: wrapDefault = false,
4631
4646
  collapseAfter = 26,
4632
4647
  copyable = true,
@@ -4653,7 +4668,7 @@ function CodeBlock({
4653
4668
  ] }) : null
4654
4669
  ] }),
4655
4670
  /* @__PURE__ */ jsxs41("div", { className: "fd-code-body", children: [
4656
- lineNumbers ? /* @__PURE__ */ jsx49("pre", { className: "fd-code-gutter", "aria-hidden": "true", children: shown.split("\n").map((_, i) => i + 1 + "\n").join("") }) : null,
4671
+ lineNumbers2 ? /* @__PURE__ */ jsx49("pre", { className: "fd-code-gutter", "aria-hidden": "true", children: shown.split("\n").map((_, i) => i + 1 + "\n").join("") }) : null,
4657
4672
  /* @__PURE__ */ jsx49("pre", { className: "fd-code-pre", tabIndex: 0, children: /* @__PURE__ */ jsx49("code", { children: /* @__PURE__ */ jsx49(Highlighted, { code: shown, lang: language }) }) })
4658
4673
  ] }),
4659
4674
  foldable ? /* @__PURE__ */ jsxs41("button", { type: "button", className: "fd-code-fold", onClick: () => setOpen((v) => !v), "aria-expanded": open2, children: [
@@ -4956,7 +4971,7 @@ function Meter({ segments = [], unallocated = 0, height = 8, label, legend = fal
4956
4971
  }
4957
4972
 
4958
4973
  // src/components/data/Pagination.tsx
4959
- import { Fragment as Fragment8, jsx as jsx52, jsxs as jsxs44 } from "react/jsx-runtime";
4974
+ import { Fragment as Fragment9, jsx as jsx52, jsxs as jsxs44 } from "react/jsx-runtime";
4960
4975
  var unitPluralRules = new Intl.PluralRules("en-US");
4961
4976
  function pluralizeUnit(n, singular, irregularPlural) {
4962
4977
  return unitPluralRules.select(n) === "one" ? singular : irregularPlural ?? `${singular}s`;
@@ -4988,10 +5003,10 @@ function Pagination({
4988
5003
  else if (nums[nums.length - 1] !== "\u2026") nums.push("\u2026");
4989
5004
  }
4990
5005
  return /* @__PURE__ */ jsxs44("div", { className: ["fd-pag", className].filter(Boolean).join(" "), ...rest, children: [
4991
- /* @__PURE__ */ jsx52("span", { className: "fd-pag-count", children: loading ? /* @__PURE__ */ jsx52("span", { className: "fd-skel fd-skel-text", style: { display: "inline-block", height: 12, width: 108 } }) : total === 0 ? /* @__PURE__ */ jsxs44(Fragment8, { children: [
5006
+ /* @__PURE__ */ jsx52("span", { className: "fd-pag-count", children: loading ? /* @__PURE__ */ jsx52("span", { className: "fd-skel fd-skel-text", style: { display: "inline-block", height: 12, width: 108 } }) : total === 0 ? /* @__PURE__ */ jsxs44(Fragment9, { children: [
4992
5007
  "No ",
4993
5008
  unitLabel
4994
- ] }) : /* @__PURE__ */ jsxs44(Fragment8, { children: [
5009
+ ] }) : /* @__PURE__ */ jsxs44(Fragment9, { children: [
4995
5010
  /* @__PURE__ */ jsxs44("strong", { children: [
4996
5011
  from.toLocaleString(),
4997
5012
  "\u2013",
@@ -7236,17 +7251,254 @@ var MarkdownEditor = React42.forwardRef(function MarkdownEditor2({
7236
7251
  ] });
7237
7252
  });
7238
7253
 
7254
+ // src/components/forms/CodeEditor.tsx
7255
+ import * as React43 from "react";
7256
+ import { EditorView, keymap, lineNumbers, placeholder as cmPlaceholder, drawSelection, Decoration } from "@codemirror/view";
7257
+ import { EditorState, StateEffect, StateField, Compartment } from "@codemirror/state";
7258
+ import { defaultKeymap, history, historyKeymap, indentMore, indentLess } from "@codemirror/commands";
7259
+ import { sql as sqlLang } from "@codemirror/lang-sql";
7260
+ import { syntaxHighlighting, HighlightStyle, indentOnInput, bracketMatching } from "@codemirror/language";
7261
+ import { tags } from "@lezer/highlight";
7262
+ import { jsx as jsx72, jsxs as jsxs63 } from "react/jsx-runtime";
7263
+ function clampOffset(state, line, column) {
7264
+ const total = state.doc.lines;
7265
+ const ln = state.doc.line(Math.min(Math.max(1, line), total));
7266
+ const col = Math.max(0, (column || 1) - 1);
7267
+ return Math.min(ln.from + col, ln.to);
7268
+ }
7269
+ function toCmDiagnostics(state, diags) {
7270
+ return diags.map((d) => {
7271
+ const from = clampOffset(state, d.line, d.column ?? 1);
7272
+ const endLine = d.endLine ?? d.line;
7273
+ const endColumn = d.endColumn ?? state.doc.line(Math.min(Math.max(1, endLine), state.doc.lines)).length + 1;
7274
+ let to = clampOffset(state, endLine, endColumn);
7275
+ if (to <= from) to = Math.min(from + 1, state.doc.length);
7276
+ return { from, to, severity: d.severity || "error", message: d.message, source: void 0 };
7277
+ });
7278
+ }
7279
+ var setDiagnosticsEffect = StateEffect.define();
7280
+ var diagnosticsField = StateField.define({
7281
+ create: () => [],
7282
+ update(value, tr) {
7283
+ for (const e of tr.effects) if (e.is(setDiagnosticsEffect)) return e.value;
7284
+ if (!tr.docChanged) return value;
7285
+ return value.map((d) => ({ ...d, from: tr.changes.mapPos(d.from), to: tr.changes.mapPos(d.to) }));
7286
+ }
7287
+ });
7288
+ var tokenHighlight = HighlightStyle.define([
7289
+ { tag: tags.keyword, class: "tok-kw" },
7290
+ { tag: tags.string, class: "tok-str" },
7291
+ { tag: [tags.number, tags.bool], class: "tok-num" },
7292
+ { tag: tags.comment, class: "tok-com" },
7293
+ { tag: [tags.function(tags.variableName), tags.function(tags.propertyName)], class: "tok-fn" },
7294
+ { tag: tags.typeName, class: "tok-type" },
7295
+ { tag: tags.propertyName, class: "tok-prop" },
7296
+ { tag: tags.null, class: "tok-lit" },
7297
+ { tag: [tags.punctuation, tags.paren, tags.bracket], class: "tok-pun" },
7298
+ { tag: tags.operator, class: "tok-op" }
7299
+ ]);
7300
+ var editorTheme = EditorView.theme({
7301
+ "&": {
7302
+ fontFamily: "var(--font-mono)",
7303
+ fontSize: "12.5px",
7304
+ color: "var(--text)",
7305
+ backgroundColor: "transparent",
7306
+ height: "100%"
7307
+ },
7308
+ ".cm-content": { padding: "10px 12px", caretColor: "var(--text)" },
7309
+ ".cm-scroller": { fontFamily: "var(--font-mono)", lineHeight: "1.62" },
7310
+ ".cm-gutters": {
7311
+ backgroundColor: "transparent",
7312
+ color: "var(--text-disabled)",
7313
+ border: "0",
7314
+ borderRight: "1px solid var(--chat-code-border)"
7315
+ },
7316
+ ".cm-lineNumbers .cm-gutterElement": { padding: "0 8px 0 12px" },
7317
+ ".cm-activeLine": { backgroundColor: "var(--surface-2)" },
7318
+ ".cm-activeLineGutter": { backgroundColor: "var(--surface-2)", color: "var(--text-2)" },
7319
+ "&.cm-focused": { outline: "none" },
7320
+ ".cm-cursor": { borderLeftColor: "var(--text)" },
7321
+ ".cm-selectionBackground, &.cm-focused .cm-selectionBackground": { backgroundColor: "var(--blue-100) !important" },
7322
+ ".cm-placeholder": { color: "var(--text-disabled)" },
7323
+ ".fd-cm-diag-error": { textDecoration: "underline wavy var(--danger-solid)", textUnderlineOffset: "3px" },
7324
+ ".fd-cm-diag-warning": { textDecoration: "underline wavy var(--warn-solid)", textUnderlineOffset: "3px" },
7325
+ ".fd-cm-diag-info": { textDecoration: "underline wavy var(--info-solid)", textUnderlineOffset: "3px" }
7326
+ }, { dark: false });
7327
+ function severityClass(sev) {
7328
+ return sev === "warning" ? "fd-cm-diag-warning" : sev === "info" ? "fd-cm-diag-info" : "fd-cm-diag-error";
7329
+ }
7330
+ function decorationsFromDiagnostics() {
7331
+ return EditorView.decorations.compute([diagnosticsField], (state) => {
7332
+ const diags = state.field(diagnosticsField);
7333
+ if (!diags.length) return Decoration.none;
7334
+ const marks = diags.filter((d) => d.from < d.to).sort((a, b) => a.from - b.from).map((d) => Decoration.mark({ class: severityClass(d.severity) }).range(d.from, d.to));
7335
+ return Decoration.set(marks, true);
7336
+ });
7337
+ }
7338
+ function CodeEditor({
7339
+ value,
7340
+ onChange,
7341
+ label,
7342
+ help,
7343
+ error,
7344
+ required = false,
7345
+ disabled = false,
7346
+ readOnly = false,
7347
+ placeholder: placeholderText = "",
7348
+ diagnostics = [],
7349
+ showEscapeHint = true,
7350
+ minHeight = 160,
7351
+ id,
7352
+ className = "",
7353
+ style,
7354
+ autoFocus = false
7355
+ }) {
7356
+ const fieldId = useFieldId(id);
7357
+ const descId = fieldId + "-desc";
7358
+ const liveId = fieldId + "-live";
7359
+ const hostRef = React43.useRef(null);
7360
+ const viewRef = React43.useRef(null);
7361
+ const valueRef = React43.useRef(value);
7362
+ const onChangeRef = React43.useRef(onChange);
7363
+ onChangeRef.current = onChange;
7364
+ const editableCompartment = React43.useRef(new Compartment()).current;
7365
+ const attributesCompartment = React43.useRef(new Compartment()).current;
7366
+ const errorRef = React43.useRef(error);
7367
+ errorRef.current = error;
7368
+ const diagnosticsCountRef = React43.useRef(diagnostics.length);
7369
+ diagnosticsCountRef.current = diagnostics.length;
7370
+ function contentAttributes() {
7371
+ return {
7372
+ id: fieldId,
7373
+ "aria-describedby": descId + " " + liveId,
7374
+ "aria-invalid": errorRef.current || diagnosticsCountRef.current ? "true" : "false",
7375
+ ...label ? { "aria-label": label } : {}
7376
+ };
7377
+ }
7378
+ React43.useEffect(() => {
7379
+ const host = hostRef.current;
7380
+ if (!host) return;
7381
+ const updateListener = EditorView.updateListener.of((update) => {
7382
+ if (!update.docChanged) return;
7383
+ const next = update.state.doc.toString();
7384
+ valueRef.current = next;
7385
+ onChangeRef.current && onChangeRef.current(next);
7386
+ });
7387
+ const state = EditorState.create({
7388
+ doc: value,
7389
+ extensions: [
7390
+ lineNumbers(),
7391
+ history(),
7392
+ drawSelection(),
7393
+ indentOnInput(),
7394
+ bracketMatching(),
7395
+ sqlLang(),
7396
+ syntaxHighlighting(tokenHighlight),
7397
+ diagnosticsField,
7398
+ decorationsFromDiagnostics(),
7399
+ editorTheme,
7400
+ cmPlaceholder(placeholderText),
7401
+ keymap.of([
7402
+ { key: "Tab", run: indentMore, shift: indentLess },
7403
+ ...defaultKeymap,
7404
+ ...historyKeymap
7405
+ ]),
7406
+ editableCompartment.of(EditorView.editable.of(!disabled)),
7407
+ EditorState.readOnly.of(readOnly),
7408
+ updateListener,
7409
+ attributesCompartment.of(EditorView.contentAttributes.of(contentAttributes()))
7410
+ ]
7411
+ });
7412
+ const view = new EditorView({ state, parent: host });
7413
+ viewRef.current = view;
7414
+ if (autoFocus) view.focus();
7415
+ return () => {
7416
+ view.destroy();
7417
+ viewRef.current = null;
7418
+ };
7419
+ }, []);
7420
+ React43.useEffect(() => {
7421
+ const view = viewRef.current;
7422
+ if (!view) return;
7423
+ const current2 = view.state.doc.toString();
7424
+ if (current2 !== value) {
7425
+ view.dispatch({ changes: { from: 0, to: current2.length, insert: value } });
7426
+ }
7427
+ valueRef.current = value;
7428
+ }, [value]);
7429
+ React43.useEffect(() => {
7430
+ const view = viewRef.current;
7431
+ if (!view) return;
7432
+ view.dispatch({ effects: editableCompartment.reconfigure(EditorView.editable.of(!disabled)) });
7433
+ }, [disabled, editableCompartment]);
7434
+ React43.useEffect(() => {
7435
+ const view = viewRef.current;
7436
+ if (!view) return;
7437
+ view.dispatch({
7438
+ effects: [
7439
+ setDiagnosticsEffect.of(toCmDiagnostics(view.state, diagnostics)),
7440
+ attributesCompartment.reconfigure(EditorView.contentAttributes.of(contentAttributes()))
7441
+ ]
7442
+ });
7443
+ }, [diagnostics, error]);
7444
+ const box = ["fd-input", "fd-code-editor", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" ");
7445
+ const announce = diagnostics.length ? diagnostics.length + (diagnostics.length === 1 ? " problem: " : " problems: ") + diagnostics.map((d) => "line " + d.line + (d.column ? ", column " + d.column : "") + ": " + d.message).join("; ") : "";
7446
+ return /* @__PURE__ */ jsxs63("div", { className: ["fd-field", className].filter(Boolean).join(" "), style, children: [
7447
+ label ? /* @__PURE__ */ jsx72(FieldLabel, { htmlFor: fieldId, required, children: label }) : null,
7448
+ /* @__PURE__ */ jsx72(
7449
+ "div",
7450
+ {
7451
+ className: box,
7452
+ style: { minHeight },
7453
+ children: /* @__PURE__ */ jsx72(
7454
+ "div",
7455
+ {
7456
+ ref: hostRef,
7457
+ className: "fd-code-editor-host",
7458
+ style: { minHeight }
7459
+ }
7460
+ )
7461
+ }
7462
+ ),
7463
+ /* @__PURE__ */ jsxs63("span", { id: descId, className: "fd-sr", children: [
7464
+ help ? help + ". " : "",
7465
+ showEscapeHint ? "Tab indents. Press Escape, then Tab, to move focus out of the editor." : ""
7466
+ ] }),
7467
+ /* @__PURE__ */ jsx72("div", { id: liveId, className: "fd-sr", role: "status", "aria-live": "polite", children: announce }),
7468
+ diagnostics.length ? /* @__PURE__ */ jsx72("ul", { className: "fd-code-editor-diagnostics", children: diagnostics.map((d, i) => /* @__PURE__ */ jsxs63("li", { className: "fd-code-editor-diag is-" + (d.severity || "error"), children: [
7469
+ /* @__PURE__ */ jsx72(
7470
+ "i",
7471
+ {
7472
+ className: "ph ph-" + (d.severity === "warning" ? "warning" : d.severity === "info" ? "info" : "warning-circle"),
7473
+ "aria-hidden": "true"
7474
+ }
7475
+ ),
7476
+ /* @__PURE__ */ jsxs63("span", { className: "fd-code-editor-diag-loc", children: [
7477
+ "Line ",
7478
+ d.line,
7479
+ d.column ? ":" + d.column : ""
7480
+ ] }),
7481
+ /* @__PURE__ */ jsx72("span", { children: d.message })
7482
+ ] }, i)) }) : null,
7483
+ error ? /* @__PURE__ */ jsxs63("span", { className: "fd-field-error", children: [
7484
+ /* @__PURE__ */ jsx72("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
7485
+ error
7486
+ ] }) : !diagnostics.length && help ? /* @__PURE__ */ jsx72("span", { className: "fd-field-help", children: help }) : null,
7487
+ showEscapeHint ? /* @__PURE__ */ jsx72("span", { className: "fd-field-help fd-code-editor-hint", children: "Tab indents. Escape, then Tab, moves focus out." }) : null
7488
+ ] });
7489
+ }
7490
+
7239
7491
  // src/components/platform/AccountMenu.tsx
7240
- import * as React44 from "react";
7492
+ import * as React45 from "react";
7241
7493
 
7242
7494
  // src/kits/sessionContext.tsx
7243
- import * as React43 from "react";
7244
- var SessionContext = React43.createContext(null);
7495
+ import * as React44 from "react";
7496
+ var SessionContext = React44.createContext(null);
7245
7497
  function SessionProvider({ value, children }) {
7246
- return React43.createElement(SessionContext.Provider, { value }, children);
7498
+ return React44.createElement(SessionContext.Provider, { value }, children);
7247
7499
  }
7248
7500
  function useSessionContext() {
7249
- const ctx = React43.useContext(SessionContext);
7501
+ const ctx = React44.useContext(SessionContext);
7250
7502
  if (!ctx) {
7251
7503
  throw new Error(
7252
7504
  "useSessionContext() was called outside a <SessionProvider>. Wrap your app root in <SessionProvider value={...}> with your real session, or \u2014 in the docs site or a demo \u2014 in <DemoSessionProvider>, before rendering AccountMenu, Gate, ProfilePage or AppSwitcher."
@@ -7256,11 +7508,11 @@ function useSessionContext() {
7256
7508
  }
7257
7509
 
7258
7510
  // src/components/platform/AccountMenu.tsx
7259
- import { Fragment as Fragment15, jsx as jsx72, jsxs as jsxs63 } from "react/jsx-runtime";
7511
+ import { Fragment as Fragment16, jsx as jsx73, jsxs as jsxs64 } from "react/jsx-runtime";
7260
7512
  var DEFAULT_LINKS = [];
7261
7513
  var DEFAULT_GROUPS = [];
7262
7514
  function Item({ item, onPick }) {
7263
- return /* @__PURE__ */ jsxs63(
7515
+ return /* @__PURE__ */ jsxs64(
7264
7516
  "button",
7265
7517
  {
7266
7518
  type: "button",
@@ -7268,9 +7520,9 @@ function Item({ item, onPick }) {
7268
7520
  className: "fd-acct-item",
7269
7521
  onClick: () => onPick(item),
7270
7522
  children: [
7271
- item.icon ? /* @__PURE__ */ jsx72("i", { className: "ph ph-" + item.icon, "aria-hidden": "true" }) : null,
7272
- /* @__PURE__ */ jsx72("span", { style: { flex: 1 }, children: item.label }),
7273
- item.badge ? /* @__PURE__ */ jsx72(Badge, { tone: "neutral", children: item.badge }) : null
7523
+ item.icon ? /* @__PURE__ */ jsx73("i", { className: "ph ph-" + item.icon, "aria-hidden": "true" }) : null,
7524
+ /* @__PURE__ */ jsx73("span", { style: { flex: 1 }, children: item.label }),
7525
+ item.badge ? /* @__PURE__ */ jsx73(Badge, { tone: "neutral", children: item.badge }) : null
7274
7526
  ]
7275
7527
  }
7276
7528
  );
@@ -7286,11 +7538,11 @@ function AccountMenu({
7286
7538
  ...rest
7287
7539
  }) {
7288
7540
  const { user, roles, can: can2, signOut: ctxSignOut, demo, pending } = useSessionContext();
7289
- const [open2, setOpen] = React44.useState(false);
7290
- const [switching, setSwitching] = React44.useState(false);
7291
- const [signingOut, setSigningOut] = React44.useState(false);
7292
- const [signOutError, setSignOutError] = React44.useState(null);
7293
- const ref = React44.useRef(null);
7541
+ const [open2, setOpen] = React45.useState(false);
7542
+ const [switching, setSwitching] = React45.useState(false);
7543
+ const [signingOut, setSigningOut] = React45.useState(false);
7544
+ const [signOutError, setSignOutError] = React45.useState(null);
7545
+ const ref = React45.useRef(null);
7294
7546
  const visibleLinks = links.filter((l) => !l.perm || !pending && can2(l.perm));
7295
7547
  const visibleGroups = groups.map((g) => ({ label: g.label, links: g.links.filter((l) => !l.perm || !pending && can2(l.perm)) })).filter((g) => g.links.length);
7296
7548
  const closeMenu = () => {
@@ -7318,8 +7570,8 @@ function AccountMenu({
7318
7570
  }
7319
7571
  };
7320
7572
  const showSwitcher = allowUserSwitch && !!demo;
7321
- return /* @__PURE__ */ jsxs63(Fragment15, { children: [
7322
- /* @__PURE__ */ jsxs63(
7573
+ return /* @__PURE__ */ jsxs64(Fragment16, { children: [
7574
+ /* @__PURE__ */ jsxs64(
7323
7575
  "button",
7324
7576
  {
7325
7577
  type: "button",
@@ -7331,12 +7583,12 @@ function AccountMenu({
7331
7583
  onClick: () => open2 ? closeMenu() : setOpen(true),
7332
7584
  ...rest,
7333
7585
  children: [
7334
- /* @__PURE__ */ jsx72(Avatar, { name: user.name, size: "sm" }),
7335
- /* @__PURE__ */ jsx72("i", { className: "ph ph-caret-down", "aria-hidden": "true", style: { fontSize: 11, color: "var(--text-muted)" } })
7586
+ /* @__PURE__ */ jsx73(Avatar, { name: user.name, size: "sm" }),
7587
+ /* @__PURE__ */ jsx73("i", { className: "ph ph-caret-down", "aria-hidden": "true", style: { fontSize: 11, color: "var(--text-muted)" } })
7336
7588
  ]
7337
7589
  }
7338
7590
  ),
7339
- /* @__PURE__ */ jsx72(
7591
+ /* @__PURE__ */ jsx73(
7340
7592
  Popover,
7341
7593
  {
7342
7594
  open: open2,
@@ -7344,27 +7596,27 @@ function AccountMenu({
7344
7596
  onClose: closeMenu,
7345
7597
  placement: "bottom-end",
7346
7598
  width: 272,
7347
- children: /* @__PURE__ */ jsxs63("div", { role: "menu", className: "fd-stack", style: { gap: 0 }, children: [
7348
- /* @__PURE__ */ jsxs63("div", { className: "fd-row", style: { gap: 10, padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
7349
- /* @__PURE__ */ jsx72(Avatar, { name: user.name }),
7350
- /* @__PURE__ */ jsxs63("span", { className: "fd-stack", style: { gap: 1, minWidth: 0, flex: 1 }, children: [
7351
- /* @__PURE__ */ jsx72("span", { className: "fd-body-sm", style: { fontWeight: 700 }, children: user.name }),
7352
- /* @__PURE__ */ jsx72("span", { className: "fd-body-sm fd-muted fd-table-trunc", title: truncationTitle(user.email), children: user.email })
7599
+ children: /* @__PURE__ */ jsxs64("div", { role: "menu", className: "fd-stack", style: { gap: 0 }, children: [
7600
+ /* @__PURE__ */ jsxs64("div", { className: "fd-row", style: { gap: 10, padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
7601
+ /* @__PURE__ */ jsx73(Avatar, { name: user.name }),
7602
+ /* @__PURE__ */ jsxs64("span", { className: "fd-stack", style: { gap: 1, minWidth: 0, flex: 1 }, children: [
7603
+ /* @__PURE__ */ jsx73("span", { className: "fd-body-sm", style: { fontWeight: 700 }, children: user.name }),
7604
+ /* @__PURE__ */ jsx73("span", { className: "fd-body-sm fd-muted fd-table-trunc", title: truncationTitle(user.email), children: user.email })
7353
7605
  ] })
7354
7606
  ] }),
7355
- showRoles && roles.length ? /* @__PURE__ */ jsx72("div", { className: "fd-row", style: { gap: 6, padding: "10px 14px", flexWrap: "wrap", borderBottom: "1px solid var(--border)" }, children: roles.map((r) => /* @__PURE__ */ jsx72(Badge, { tone: r.id === "owner" ? "success" : "neutral", children: r.name }, r.id)) }) : null,
7356
- visibleLinks.length ? /* @__PURE__ */ jsx72("div", { className: "fd-acct-group", children: visibleLinks.map((l) => /* @__PURE__ */ jsx72(Item, { item: l, onPick: pick }, l.id)) }) : null,
7357
- visibleGroups.map((g) => /* @__PURE__ */ jsxs63("div", { className: "fd-acct-group", style: { borderTop: "1px solid var(--border)" }, children: [
7358
- /* @__PURE__ */ jsx72("span", { className: "fd-overline fd-muted", style: { padding: "8px 14px 4px", display: "block" }, children: g.label }),
7359
- g.links.map((l) => /* @__PURE__ */ jsx72(Item, { item: l, onPick: pick }, l.id))
7607
+ showRoles && roles.length ? /* @__PURE__ */ jsx73("div", { className: "fd-row", style: { gap: 6, padding: "10px 14px", flexWrap: "wrap", borderBottom: "1px solid var(--border)" }, children: roles.map((r) => /* @__PURE__ */ jsx73(Badge, { tone: r.id === "owner" ? "success" : "neutral", children: r.name }, r.id)) }) : null,
7608
+ visibleLinks.length ? /* @__PURE__ */ jsx73("div", { className: "fd-acct-group", children: visibleLinks.map((l) => /* @__PURE__ */ jsx73(Item, { item: l, onPick: pick }, l.id)) }) : null,
7609
+ visibleGroups.map((g) => /* @__PURE__ */ jsxs64("div", { className: "fd-acct-group", style: { borderTop: "1px solid var(--border)" }, children: [
7610
+ /* @__PURE__ */ jsx73("span", { className: "fd-overline fd-muted", style: { padding: "8px 14px 4px", display: "block" }, children: g.label }),
7611
+ g.links.map((l) => /* @__PURE__ */ jsx73(Item, { item: l, onPick: pick }, l.id))
7360
7612
  ] }, g.label)),
7361
- showSwitcher && demo ? /* @__PURE__ */ jsxs63("div", { className: "fd-acct-group", style: { borderTop: "1px solid var(--border)" }, children: [
7362
- /* @__PURE__ */ jsxs63("button", { type: "button", role: "menuitem", className: "fd-acct-item", onClick: () => setSwitching((s) => !s), children: [
7363
- /* @__PURE__ */ jsx72("i", { className: "ph ph-user-switch", "aria-hidden": "true" }),
7364
- /* @__PURE__ */ jsx72("span", { style: { flex: 1 }, children: "View as another member" }),
7365
- /* @__PURE__ */ jsx72("i", { className: "ph ph-caret-" + (switching ? "up" : "down"), "aria-hidden": "true", style: { fontSize: 11 } })
7613
+ showSwitcher && demo ? /* @__PURE__ */ jsxs64("div", { className: "fd-acct-group", style: { borderTop: "1px solid var(--border)" }, children: [
7614
+ /* @__PURE__ */ jsxs64("button", { type: "button", role: "menuitem", className: "fd-acct-item", onClick: () => setSwitching((s) => !s), children: [
7615
+ /* @__PURE__ */ jsx73("i", { className: "ph ph-user-switch", "aria-hidden": "true" }),
7616
+ /* @__PURE__ */ jsx73("span", { style: { flex: 1 }, children: "View as another member" }),
7617
+ /* @__PURE__ */ jsx73("i", { className: "ph ph-caret-" + (switching ? "up" : "down"), "aria-hidden": "true", style: { fontSize: 11 } })
7366
7618
  ] }),
7367
- switching ? /* @__PURE__ */ jsx72("div", { className: "fd-stack", style: { gap: 0 }, children: demo.allUsers.map((u) => /* @__PURE__ */ jsxs63(
7619
+ switching ? /* @__PURE__ */ jsx73("div", { className: "fd-stack", style: { gap: 0 }, children: demo.allUsers.map((u) => /* @__PURE__ */ jsxs64(
7368
7620
  "button",
7369
7621
  {
7370
7622
  type: "button",
@@ -7376,19 +7628,19 @@ function AccountMenu({
7376
7628
  setSwitching(false);
7377
7629
  },
7378
7630
  children: [
7379
- /* @__PURE__ */ jsx72(Avatar, { name: u.name, size: "sm" }),
7380
- /* @__PURE__ */ jsxs63("span", { className: "fd-stack", style: { gap: 0, flex: 1, minWidth: 0, alignItems: "flex-start" }, children: [
7381
- /* @__PURE__ */ jsx72("span", { style: { fontWeight: u.id === user.id ? 700 : 500 }, children: u.name }),
7382
- u.roles ? /* @__PURE__ */ jsx72("span", { className: "fd-muted", style: { fontSize: 11.5 }, children: u.roles.join(", ") }) : null
7631
+ /* @__PURE__ */ jsx73(Avatar, { name: u.name, size: "sm" }),
7632
+ /* @__PURE__ */ jsxs64("span", { className: "fd-stack", style: { gap: 0, flex: 1, minWidth: 0, alignItems: "flex-start" }, children: [
7633
+ /* @__PURE__ */ jsx73("span", { style: { fontWeight: u.id === user.id ? 700 : 500 }, children: u.name }),
7634
+ u.roles ? /* @__PURE__ */ jsx73("span", { className: "fd-muted", style: { fontSize: 11.5 }, children: u.roles.join(", ") }) : null
7383
7635
  ] }),
7384
- u.id === user.id ? /* @__PURE__ */ jsx72("i", { className: "ph ph-check", "aria-hidden": "true", style: { color: "var(--ok-text)" } }) : null
7636
+ u.id === user.id ? /* @__PURE__ */ jsx73("i", { className: "ph ph-check", "aria-hidden": "true", style: { color: "var(--ok-text)" } }) : null
7385
7637
  ]
7386
7638
  },
7387
7639
  u.id
7388
7640
  )) }) : null
7389
7641
  ] }) : null,
7390
- /* @__PURE__ */ jsxs63("div", { className: "fd-acct-group", style: { borderTop: "1px solid var(--border)" }, children: [
7391
- /* @__PURE__ */ jsxs63(
7642
+ /* @__PURE__ */ jsxs64("div", { className: "fd-acct-group", style: { borderTop: "1px solid var(--border)" }, children: [
7643
+ /* @__PURE__ */ jsxs64(
7392
7644
  "button",
7393
7645
  {
7394
7646
  type: "button",
@@ -7398,14 +7650,14 @@ function AccountMenu({
7398
7650
  disabled: signingOut,
7399
7651
  onClick: signOut,
7400
7652
  children: [
7401
- signingOut ? /* @__PURE__ */ jsx72(Spinner, { size: "sm" }) : /* @__PURE__ */ jsx72("i", { className: "ph ph-sign-out", "aria-hidden": "true" }),
7402
- /* @__PURE__ */ jsx72("span", { style: { flex: 1 }, children: signingOut ? "Signing out\u2026" : "Sign out" })
7653
+ signingOut ? /* @__PURE__ */ jsx73(Spinner, { size: "sm" }) : /* @__PURE__ */ jsx73("i", { className: "ph ph-sign-out", "aria-hidden": "true" }),
7654
+ /* @__PURE__ */ jsx73("span", { style: { flex: 1 }, children: signingOut ? "Signing out\u2026" : "Sign out" })
7403
7655
  ]
7404
7656
  }
7405
7657
  ),
7406
- signOutError ? /* @__PURE__ */ jsxs63("div", { role: "alert", className: "fd-body-sm", style: { padding: "0 14px 12px" }, children: [
7407
- /* @__PURE__ */ jsx72("span", { style: { display: "block", color: "var(--danger-text)", marginBottom: 6 }, children: signOutError }),
7408
- /* @__PURE__ */ jsx72("button", { type: "button", className: "fd-soon-link", disabled: signingOut, onClick: signOut, children: "Retry" })
7658
+ signOutError ? /* @__PURE__ */ jsxs64("div", { role: "alert", className: "fd-body-sm", style: { padding: "0 14px 12px" }, children: [
7659
+ /* @__PURE__ */ jsx73("span", { style: { display: "block", color: "var(--danger-text)", marginBottom: 6 }, children: signOutError }),
7660
+ /* @__PURE__ */ jsx73("button", { type: "button", className: "fd-soon-link", disabled: signingOut, onClick: signOut, children: "Retry" })
7409
7661
  ] }) : null
7410
7662
  ] })
7411
7663
  ] })
@@ -7415,13 +7667,13 @@ function AccountMenu({
7415
7667
  }
7416
7668
 
7417
7669
  // src/components/platform/AppSwitcher.tsx
7418
- import * as React45 from "react";
7419
- import { jsx as jsx73, jsxs as jsxs64 } from "react/jsx-runtime";
7670
+ import * as React46 from "react";
7671
+ import { jsx as jsx74, jsxs as jsxs65 } from "react/jsx-runtime";
7420
7672
  function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
7421
7673
  const { apps: contextApps } = useSessionContext();
7422
7674
  const apps = appsProp ?? contextApps ?? [];
7423
- const [open2, setOpen] = React45.useState(false);
7424
- const anchorRef = React45.useRef(null);
7675
+ const [open2, setOpen] = React46.useState(false);
7676
+ const anchorRef = React46.useRef(null);
7425
7677
  if (!apps.length) return null;
7426
7678
  const items = apps.map((app) => ({
7427
7679
  id: app.key,
@@ -7435,8 +7687,8 @@ function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
7435
7687
  window.location.href = app.url;
7436
7688
  }
7437
7689
  }));
7438
- return /* @__PURE__ */ jsxs64(React45.Fragment, { children: [
7439
- /* @__PURE__ */ jsx73("span", { ref: anchorRef, className: ["fd-appswitch-anchor", className].filter(Boolean).join(" "), style: { display: "inline-flex" }, children: /* @__PURE__ */ jsx73(
7690
+ return /* @__PURE__ */ jsxs65(React46.Fragment, { children: [
7691
+ /* @__PURE__ */ jsx74("span", { ref: anchorRef, className: ["fd-appswitch-anchor", className].filter(Boolean).join(" "), style: { display: "inline-flex" }, children: /* @__PURE__ */ jsx74(
7440
7692
  IconButton,
7441
7693
  {
7442
7694
  icon: "squares-four",
@@ -7446,7 +7698,7 @@ function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
7446
7698
  onClick: () => setOpen((v) => !v)
7447
7699
  }
7448
7700
  ) }),
7449
- /* @__PURE__ */ jsx73(
7701
+ /* @__PURE__ */ jsx74(
7450
7702
  Popover,
7451
7703
  {
7452
7704
  open: open2,
@@ -7457,17 +7709,17 @@ function AppSwitcher({ apps: appsProp, onNavigate, className = "" }) {
7457
7709
  label: "All flytedesk apps",
7458
7710
  width: 240,
7459
7711
  maxHeight: 360,
7460
- children: /* @__PURE__ */ jsx73(Menu, { items, onClose: () => setOpen(false) })
7712
+ children: /* @__PURE__ */ jsx74(Menu, { items, onClose: () => setOpen(false) })
7461
7713
  }
7462
7714
  )
7463
7715
  ] });
7464
7716
  }
7465
7717
 
7466
7718
  // src/components/platform/AppearanceMenu.tsx
7467
- import * as React47 from "react";
7719
+ import * as React48 from "react";
7468
7720
 
7469
7721
  // src/kits/appearance.ts
7470
- import * as React46 from "react";
7722
+ import * as React47 from "react";
7471
7723
  var DEFAULT_STORAGE_KEY = "fd-appearance";
7472
7724
  var DEFAULT_PREFS = {
7473
7725
  theme: "system",
@@ -7562,11 +7814,11 @@ function applyPrefs(prefs, root = document.documentElement) {
7562
7814
  else root.removeAttribute("data-motion");
7563
7815
  }
7564
7816
  function useAppearancePrefs(store) {
7565
- const prefs = React46.useSyncExternalStore(store.subscribe, store.getSnapshot);
7566
- React46.useEffect(() => {
7817
+ const prefs = React47.useSyncExternalStore(store.subscribe, store.getSnapshot);
7818
+ React47.useEffect(() => {
7567
7819
  applyPrefs(prefs);
7568
7820
  }, [prefs]);
7569
- React46.useEffect(() => {
7821
+ React47.useEffect(() => {
7570
7822
  if (prefs.theme !== "system" || typeof window === "undefined" || typeof window.matchMedia !== "function") {
7571
7823
  return;
7572
7824
  }
@@ -7575,7 +7827,7 @@ function useAppearancePrefs(store) {
7575
7827
  mq.addEventListener("change", onChange);
7576
7828
  return () => mq.removeEventListener("change", onChange);
7577
7829
  }, [prefs]);
7578
- const update = React46.useCallback(
7830
+ const update = React47.useCallback(
7579
7831
  (patch) => {
7580
7832
  store.write({ ...store.getSnapshot(), ...patch });
7581
7833
  },
@@ -7585,7 +7837,7 @@ function useAppearancePrefs(store) {
7585
7837
  }
7586
7838
 
7587
7839
  // src/components/platform/AppearanceMenu.tsx
7588
- import { jsx as jsx74, jsxs as jsxs65 } from "react/jsx-runtime";
7840
+ import { jsx as jsx75, jsxs as jsxs66 } from "react/jsx-runtime";
7589
7841
  var THEME_OPTIONS = [
7590
7842
  { value: "light", label: "Light" },
7591
7843
  { value: "dark", label: "Dark" },
@@ -7598,16 +7850,16 @@ var TEXT_SCALE_OPTIONS = [
7598
7850
  { value: "xl", label: "XL" }
7599
7851
  ];
7600
7852
  function AppearanceMenu({ className = "", store: storeProp, storageKey, storage, defaults }) {
7601
- const store = React47.useMemo(
7853
+ const store = React48.useMemo(
7602
7854
  () => storeProp ?? createLocalStorageAppearanceStore({ storageKey, storage, defaults }),
7603
7855
  [storeProp, storageKey, storage, defaults]
7604
7856
  );
7605
7857
  const [prefs, update] = useAppearancePrefs(store);
7606
- const [open2, setOpen] = React47.useState(false);
7607
- const anchorRef = React47.useRef(null);
7858
+ const [open2, setOpen] = React48.useState(false);
7859
+ const anchorRef = React48.useRef(null);
7608
7860
  const patch = (p) => update(p);
7609
- return /* @__PURE__ */ jsxs65(React47.Fragment, { children: [
7610
- /* @__PURE__ */ jsx74("span", { ref: anchorRef, className: ["fd-appearance-anchor", className].filter(Boolean).join(" "), style: { display: "inline-flex" }, children: /* @__PURE__ */ jsx74(
7861
+ return /* @__PURE__ */ jsxs66(React48.Fragment, { children: [
7862
+ /* @__PURE__ */ jsx75("span", { ref: anchorRef, className: ["fd-appearance-anchor", className].filter(Boolean).join(" "), style: { display: "inline-flex" }, children: /* @__PURE__ */ jsx75(
7611
7863
  IconButton,
7612
7864
  {
7613
7865
  icon: "circle-half",
@@ -7615,7 +7867,7 @@ function AppearanceMenu({ className = "", store: storeProp, storageKey, storage,
7615
7867
  onClick: () => setOpen((v) => !v)
7616
7868
  }
7617
7869
  ) }),
7618
- /* @__PURE__ */ jsx74(
7870
+ /* @__PURE__ */ jsx75(
7619
7871
  Popover,
7620
7872
  {
7621
7873
  open: open2,
@@ -7625,10 +7877,10 @@ function AppearanceMenu({ className = "", store: storeProp, storageKey, storage,
7625
7877
  padded: true,
7626
7878
  width: 260,
7627
7879
  label: "Appearance settings",
7628
- children: /* @__PURE__ */ jsxs65("div", { className: "fd-stack", style: { display: "flex", flexDirection: "column", gap: 16 }, children: [
7629
- /* @__PURE__ */ jsxs65("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: [
7630
- /* @__PURE__ */ jsx74("span", { className: "fd-field-label", children: "Theme" }),
7631
- /* @__PURE__ */ jsx74(
7880
+ children: /* @__PURE__ */ jsxs66("div", { className: "fd-stack", style: { display: "flex", flexDirection: "column", gap: 16 }, children: [
7881
+ /* @__PURE__ */ jsxs66("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: [
7882
+ /* @__PURE__ */ jsx75("span", { className: "fd-field-label", children: "Theme" }),
7883
+ /* @__PURE__ */ jsx75(
7632
7884
  SegmentedControl,
7633
7885
  {
7634
7886
  options: THEME_OPTIONS,
@@ -7638,9 +7890,9 @@ function AppearanceMenu({ className = "", store: storeProp, storageKey, storage,
7638
7890
  }
7639
7891
  )
7640
7892
  ] }),
7641
- /* @__PURE__ */ jsxs65("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: [
7642
- /* @__PURE__ */ jsx74("span", { className: "fd-field-label", children: "Text size" }),
7643
- /* @__PURE__ */ jsx74(
7893
+ /* @__PURE__ */ jsxs66("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: [
7894
+ /* @__PURE__ */ jsx75("span", { className: "fd-field-label", children: "Text size" }),
7895
+ /* @__PURE__ */ jsx75(
7644
7896
  SegmentedControl,
7645
7897
  {
7646
7898
  options: TEXT_SCALE_OPTIONS,
@@ -7650,7 +7902,7 @@ function AppearanceMenu({ className = "", store: storeProp, storageKey, storage,
7650
7902
  }
7651
7903
  )
7652
7904
  ] }),
7653
- /* @__PURE__ */ jsx74(
7905
+ /* @__PURE__ */ jsx75(
7654
7906
  Switch,
7655
7907
  {
7656
7908
  label: "High contrast",
@@ -7659,7 +7911,7 @@ function AppearanceMenu({ className = "", store: storeProp, storageKey, storage,
7659
7911
  onChange: (e) => patch({ highContrast: e.target.checked })
7660
7912
  }
7661
7913
  ),
7662
- /* @__PURE__ */ jsx74(
7914
+ /* @__PURE__ */ jsx75(
7663
7915
  Switch,
7664
7916
  {
7665
7917
  label: "Reduce motion",
@@ -7675,14 +7927,14 @@ function AppearanceMenu({ className = "", store: storeProp, storageKey, storage,
7675
7927
  }
7676
7928
 
7677
7929
  // src/components/platform/ApiSpecBrowser.tsx
7678
- import * as React48 from "react";
7679
- import { jsx as jsx75, jsxs as jsxs66 } from "react/jsx-runtime";
7930
+ import * as React49 from "react";
7931
+ import { jsx as jsx76, jsxs as jsxs67 } from "react/jsx-runtime";
7680
7932
  var METHOD_TONE = { GET: "success", POST: "info", PATCH: "warning", PUT: "warning", DELETE: "danger" };
7681
7933
  function Json({ obj }) {
7682
- return /* @__PURE__ */ jsx75("pre", { className: "fd-json", children: JSON.stringify(obj, null, 2) });
7934
+ return /* @__PURE__ */ jsx76("pre", { className: "fd-json", children: JSON.stringify(obj, null, 2) });
7683
7935
  }
7684
7936
  function Endpoint({ s, onRequest }) {
7685
- const [tried, setTried] = React48.useState(null);
7937
+ const [tried, setTried] = React49.useState(null);
7686
7938
  const run = async () => {
7687
7939
  setTried("busy");
7688
7940
  const t0 = (window.performance || Date).now();
@@ -7693,50 +7945,50 @@ function Endpoint({ s, onRequest }) {
7693
7945
  setTried({ ms: Math.round((window.performance || Date).now() - t0), error: String(e && e.message || e) });
7694
7946
  }
7695
7947
  };
7696
- return /* @__PURE__ */ jsx75(Card, { elevation: "flat", padded: false, children: /* @__PURE__ */ jsxs66("div", { className: "fd-stack", style: { gap: 0 }, children: [
7697
- /* @__PURE__ */ jsxs66("div", { className: "fd-row", style: { gap: 10, padding: "14px 18px", flexWrap: "wrap" }, children: [
7698
- /* @__PURE__ */ jsx75(Badge, { tone: METHOD_TONE[s.method] || "neutral", children: s.method }),
7699
- /* @__PURE__ */ jsx75("code", { className: "fd-mono", style: { fontSize: 12.5, fontWeight: 600, color: "var(--text)", wordBreak: "break-all" }, children: s.path }),
7700
- s.isList ? /* @__PURE__ */ jsx75(Badge, { tone: "neutral", icon: "rows", children: "Paged list" }) : null,
7701
- /* @__PURE__ */ jsx75("span", { style: { flex: 1 } }),
7702
- /* @__PURE__ */ jsxs66("span", { className: "fd-body-sm fd-muted fd-mono", children: [
7948
+ return /* @__PURE__ */ jsx76(Card, { elevation: "flat", padded: false, children: /* @__PURE__ */ jsxs67("div", { className: "fd-stack", style: { gap: 0 }, children: [
7949
+ /* @__PURE__ */ jsxs67("div", { className: "fd-row", style: { gap: 10, padding: "14px 18px", flexWrap: "wrap" }, children: [
7950
+ /* @__PURE__ */ jsx76(Badge, { tone: METHOD_TONE[s.method] || "neutral", children: s.method }),
7951
+ /* @__PURE__ */ jsx76("code", { className: "fd-mono", style: { fontSize: 12.5, fontWeight: 600, color: "var(--text)", wordBreak: "break-all" }, children: s.path }),
7952
+ s.isList ? /* @__PURE__ */ jsx76(Badge, { tone: "neutral", icon: "rows", children: "Paged list" }) : null,
7953
+ /* @__PURE__ */ jsx76("span", { style: { flex: 1 } }),
7954
+ /* @__PURE__ */ jsxs67("span", { className: "fd-body-sm fd-muted fd-mono", children: [
7703
7955
  s.latency[0],
7704
7956
  "\u2013",
7705
7957
  s.latency[1],
7706
7958
  "ms"
7707
7959
  ] }),
7708
- /* @__PURE__ */ jsx75(Button, { size: "sm", variant: "secondary", icon: "play", loading: tried === "busy", onClick: run, children: "Try it" })
7960
+ /* @__PURE__ */ jsx76(Button, { size: "sm", variant: "secondary", icon: "play", loading: tried === "busy", onClick: run, children: "Try it" })
7709
7961
  ] }),
7710
- /* @__PURE__ */ jsxs66("div", { className: "fd-stack", style: { gap: 14, padding: "0 18px 16px" }, children: [
7711
- /* @__PURE__ */ jsxs66("div", { className: "fd-stack", style: { gap: 6 }, children: [
7712
- /* @__PURE__ */ jsx75("span", { className: "fd-body-sm", style: { fontWeight: 700 }, children: s.title }),
7713
- /* @__PURE__ */ jsx75("p", { className: "fd-body-sm fd-secondary", style: { margin: 0, textWrap: "pretty" }, children: s.purpose }),
7714
- s.usedBy && s.usedBy.length ? /* @__PURE__ */ jsx75("span", { className: "fd-row", style: { gap: 6, flexWrap: "wrap" }, children: s.usedBy.map((u) => /* @__PURE__ */ jsx75(Tag, { children: u }, u)) }) : null
7962
+ /* @__PURE__ */ jsxs67("div", { className: "fd-stack", style: { gap: 14, padding: "0 18px 16px" }, children: [
7963
+ /* @__PURE__ */ jsxs67("div", { className: "fd-stack", style: { gap: 6 }, children: [
7964
+ /* @__PURE__ */ jsx76("span", { className: "fd-body-sm", style: { fontWeight: 700 }, children: s.title }),
7965
+ /* @__PURE__ */ jsx76("p", { className: "fd-body-sm fd-secondary", style: { margin: 0, textWrap: "pretty" }, children: s.purpose }),
7966
+ s.usedBy && s.usedBy.length ? /* @__PURE__ */ jsx76("span", { className: "fd-row", style: { gap: 6, flexWrap: "wrap" }, children: s.usedBy.map((u) => /* @__PURE__ */ jsx76(Tag, { children: u }, u)) }) : null
7715
7967
  ] }),
7716
- /* @__PURE__ */ jsxs66("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(280px,1fr))", gap: 12, alignItems: "start" }, children: [
7717
- s.request ? /* @__PURE__ */ jsxs66("div", { className: "fd-stack", style: { gap: 6 }, children: [
7718
- /* @__PURE__ */ jsx75("span", { className: "fd-overline fd-muted", children: "Request body" }),
7719
- /* @__PURE__ */ jsx75(Json, { obj: s.request })
7968
+ /* @__PURE__ */ jsxs67("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(280px,1fr))", gap: 12, alignItems: "start" }, children: [
7969
+ s.request ? /* @__PURE__ */ jsxs67("div", { className: "fd-stack", style: { gap: 6 }, children: [
7970
+ /* @__PURE__ */ jsx76("span", { className: "fd-overline fd-muted", children: "Request body" }),
7971
+ /* @__PURE__ */ jsx76(Json, { obj: s.request })
7720
7972
  ] }) : null,
7721
- s.query ? /* @__PURE__ */ jsxs66("div", { className: "fd-stack", style: { gap: 6 }, children: [
7722
- /* @__PURE__ */ jsx75("span", { className: "fd-overline fd-muted", children: "Query" }),
7723
- /* @__PURE__ */ jsx75(Json, { obj: s.query })
7973
+ s.query ? /* @__PURE__ */ jsxs67("div", { className: "fd-stack", style: { gap: 6 }, children: [
7974
+ /* @__PURE__ */ jsx76("span", { className: "fd-overline fd-muted", children: "Query" }),
7975
+ /* @__PURE__ */ jsx76(Json, { obj: s.query })
7724
7976
  ] }) : null,
7725
- /* @__PURE__ */ jsxs66("div", { className: "fd-stack", style: { gap: 6 }, children: [
7726
- /* @__PURE__ */ jsx75("span", { className: "fd-overline fd-muted", children: "Response 200" }),
7727
- /* @__PURE__ */ jsx75(Json, { obj: s.response })
7977
+ /* @__PURE__ */ jsxs67("div", { className: "fd-stack", style: { gap: 6 }, children: [
7978
+ /* @__PURE__ */ jsx76("span", { className: "fd-overline fd-muted", children: "Response 200" }),
7979
+ /* @__PURE__ */ jsx76(Json, { obj: s.response })
7728
7980
  ] })
7729
7981
  ] }),
7730
- s.notes ? /* @__PURE__ */ jsx75(Flag, { tone: "info", statement: "Implementation note", cost: s.notes, actions: null }) : null,
7731
- tried && tried !== "busy" ? /* @__PURE__ */ jsxs66("div", { className: "fd-stack", style: { gap: 6 }, children: [
7732
- /* @__PURE__ */ jsxs66("span", { className: "fd-row", style: { gap: 8 }, children: [
7733
- /* @__PURE__ */ jsx75("span", { className: "fd-overline fd-muted", children: "Simulated response" }),
7734
- /* @__PURE__ */ jsxs66(Badge, { tone: tried.error ? "danger" : "success", icon: "timer", children: [
7982
+ s.notes ? /* @__PURE__ */ jsx76(Flag, { tone: "info", statement: "Implementation note", cost: s.notes, actions: null }) : null,
7983
+ tried && tried !== "busy" ? /* @__PURE__ */ jsxs67("div", { className: "fd-stack", style: { gap: 6 }, children: [
7984
+ /* @__PURE__ */ jsxs67("span", { className: "fd-row", style: { gap: 8 }, children: [
7985
+ /* @__PURE__ */ jsx76("span", { className: "fd-overline fd-muted", children: "Simulated response" }),
7986
+ /* @__PURE__ */ jsxs67(Badge, { tone: tried.error ? "danger" : "success", icon: "timer", children: [
7735
7987
  tried.ms,
7736
7988
  "ms"
7737
7989
  ] })
7738
7990
  ] }),
7739
- /* @__PURE__ */ jsx75(Json, { obj: tried.error ? { error: tried.error } : tried.data })
7991
+ /* @__PURE__ */ jsx76(Json, { obj: tried.error ? { error: tried.error } : tried.data })
7740
7992
  ] }) : null
7741
7993
  ] })
7742
7994
  ] }) });
@@ -7755,58 +8007,58 @@ function ApiSpecBrowser({
7755
8007
  className = "",
7756
8008
  ...rest
7757
8009
  }) {
7758
- const [q, setQ] = React48.useState("");
7759
- const [method, setMethod] = React48.useState(null);
7760
- const [mod, setMod] = React48.useState(null);
7761
- const [listOnly, setListOnly] = React48.useState(false);
8010
+ const [q, setQ] = React49.useState("");
8011
+ const [method, setMethod] = React49.useState(null);
8012
+ const [mod, setMod] = React49.useState(null);
8013
+ const [listOnly, setListOnly] = React49.useState(false);
7762
8014
  const activeModule = modules && modules.find((m) => m.id === mod);
7763
8015
  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())));
7764
8016
  const effGroups = groups && groups.length ? groups : [["All endpoints", spec.map((s) => s.id)]];
7765
8017
  const methods = [...new Set(spec.map((s) => s.method))];
7766
8018
  const listCount = spec.filter((s) => s.isList).length;
7767
- return /* @__PURE__ */ jsxs66("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 20, maxWidth: 1100 }, ...rest, children: [
7768
- /* @__PURE__ */ jsxs66("div", { className: "fd-stack", style: { gap: 10 }, children: [
7769
- kicker ? /* @__PURE__ */ jsx75("span", { className: "fd-overline fd-muted", children: kicker }) : null,
7770
- /* @__PURE__ */ jsx75("h1", { className: "fd-h1", style: { margin: 0 }, children: title }),
7771
- lede ? /* @__PURE__ */ jsx75("p", { className: "fd-body fd-secondary fd-prose", style: { margin: 0 }, children: lede }) : null
8019
+ return /* @__PURE__ */ jsxs67("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 20, maxWidth: 1100 }, ...rest, children: [
8020
+ /* @__PURE__ */ jsxs67("div", { className: "fd-stack", style: { gap: 10 }, children: [
8021
+ kicker ? /* @__PURE__ */ jsx76("span", { className: "fd-overline fd-muted", children: kicker }) : null,
8022
+ /* @__PURE__ */ jsx76("h1", { className: "fd-h1", style: { margin: 0 }, children: title }),
8023
+ lede ? /* @__PURE__ */ jsx76("p", { className: "fd-body fd-secondary fd-prose", style: { margin: 0 }, children: lede }) : null
7772
8024
  ] }),
7773
- modules && modules.length ? /* @__PURE__ */ jsxs66("div", { className: "fd-stack", style: { gap: 8 }, children: [
7774
- /* @__PURE__ */ jsx75("span", { className: "fd-overline fd-muted", children: "Filter by screen \u2014 every endpoint that screen depends on" }),
7775
- /* @__PURE__ */ jsxs66("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: [
7776
- /* @__PURE__ */ jsxs66(Tag, { icon: "stack", selected: !mod, onClick: () => setMod(null), children: [
8025
+ modules && modules.length ? /* @__PURE__ */ jsxs67("div", { className: "fd-stack", style: { gap: 8 }, children: [
8026
+ /* @__PURE__ */ jsx76("span", { className: "fd-overline fd-muted", children: "Filter by screen \u2014 every endpoint that screen depends on" }),
8027
+ /* @__PURE__ */ jsxs67("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: [
8028
+ /* @__PURE__ */ jsxs67(Tag, { icon: "stack", selected: !mod, onClick: () => setMod(null), children: [
7777
8029
  "All screens ",
7778
- /* @__PURE__ */ jsx75("span", { className: "fd-mono", children: spec.length })
8030
+ /* @__PURE__ */ jsx76("span", { className: "fd-mono", children: spec.length })
7779
8031
  ] }),
7780
- modules.map((m) => /* @__PURE__ */ jsxs66(Tag, { icon: m.icon, selected: mod === m.id, onClick: () => setMod(mod === m.id ? null : m.id), children: [
8032
+ modules.map((m) => /* @__PURE__ */ jsxs67(Tag, { icon: m.icon, selected: mod === m.id, onClick: () => setMod(mod === m.id ? null : m.id), children: [
7781
8033
  m.label,
7782
8034
  " ",
7783
- /* @__PURE__ */ jsx75("span", { className: "fd-mono", children: m.endpoints.length })
8035
+ /* @__PURE__ */ jsx76("span", { className: "fd-mono", children: m.endpoints.length })
7784
8036
  ] }, m.id))
7785
8037
  ] }),
7786
- activeModule ? /* @__PURE__ */ jsx75(
8038
+ activeModule ? /* @__PURE__ */ jsx76(
7787
8039
  Flag,
7788
8040
  {
7789
8041
  tone: "info",
7790
8042
  statement: activeModule.label + " calls " + activeModule.endpoints.length + " endpoints.",
7791
8043
  cost: "Integration checklist for this screen: " + activeModule.endpoints.join(", ") + ". Wire these and the screen is done.",
7792
- actions: /* @__PURE__ */ jsx75(Button, { size: "sm", variant: "ghost", icon: "x", onClick: () => setMod(null), children: "Show all screens" })
8044
+ actions: /* @__PURE__ */ jsx76(Button, { size: "sm", variant: "ghost", icon: "x", onClick: () => setMod(null), children: "Show all screens" })
7793
8045
  }
7794
8046
  ) : null
7795
8047
  ] }) : null,
7796
- sourceNote ? /* @__PURE__ */ jsx75(Flag, { tone: "info", statement: "Design-first: this page is the spec.", cost: sourceNote, actions: null }) : null,
7797
- /* @__PURE__ */ jsxs66("div", { className: "fd-row", style: { gap: 10, flexWrap: "wrap" }, children: [
7798
- /* @__PURE__ */ jsx75(Input, { icon: "magnifying-glass", placeholder: "Find an endpoint, screen, or behavior", value: q, onChange: (e) => setQ(e.target.value), style: { width: 300 } }),
7799
- methods.map((m) => /* @__PURE__ */ jsxs66(Tag, { selected: method === m, onClick: () => setMethod(method === m ? null : m), children: [
8048
+ sourceNote ? /* @__PURE__ */ jsx76(Flag, { tone: "info", statement: "Design-first: this page is the spec.", cost: sourceNote, actions: null }) : null,
8049
+ /* @__PURE__ */ jsxs67("div", { className: "fd-row", style: { gap: 10, flexWrap: "wrap" }, children: [
8050
+ /* @__PURE__ */ jsx76(Input, { icon: "magnifying-glass", placeholder: "Find an endpoint, screen, or behavior", value: q, onChange: (e) => setQ(e.target.value), style: { width: 300 } }),
8051
+ methods.map((m) => /* @__PURE__ */ jsxs67(Tag, { selected: method === m, onClick: () => setMethod(method === m ? null : m), children: [
7800
8052
  m,
7801
8053
  " ",
7802
- /* @__PURE__ */ jsx75("span", { className: "fd-mono", children: spec.filter((s) => s.method === m).length })
8054
+ /* @__PURE__ */ jsx76("span", { className: "fd-mono", children: spec.filter((s) => s.method === m).length })
7803
8055
  ] }, m)),
7804
- listCount ? /* @__PURE__ */ jsxs66(Tag, { icon: "rows", selected: listOnly, onClick: () => setListOnly(!listOnly), children: [
8056
+ listCount ? /* @__PURE__ */ jsxs67(Tag, { icon: "rows", selected: listOnly, onClick: () => setListOnly(!listOnly), children: [
7805
8057
  "Paged lists ",
7806
- /* @__PURE__ */ jsx75("span", { className: "fd-mono", children: listCount })
8058
+ /* @__PURE__ */ jsx76("span", { className: "fd-mono", children: listCount })
7807
8059
  ] }) : null,
7808
- /* @__PURE__ */ jsx75("span", { style: { flex: 1 } }),
7809
- /* @__PURE__ */ jsxs66("span", { className: "fd-body-sm fd-muted", children: [
8060
+ /* @__PURE__ */ jsx76("span", { style: { flex: 1 } }),
8061
+ /* @__PURE__ */ jsxs67("span", { className: "fd-body-sm fd-muted", children: [
7810
8062
  hits.length,
7811
8063
  " of ",
7812
8064
  spec.length,
@@ -7814,31 +8066,31 @@ function ApiSpecBrowser({
7814
8066
  listCount ? " \xB7 " + listCount + " paged" : ""
7815
8067
  ] })
7816
8068
  ] }),
7817
- hits.length === 0 ? /* @__PURE__ */ jsx75(Card, { elevation: "flat", children: /* @__PURE__ */ jsx75("p", { className: "fd-body-sm fd-muted", style: { margin: 0 }, children: "No endpoint matches those filters." }) }) : effGroups.map(([g, ids]) => {
8069
+ hits.length === 0 ? /* @__PURE__ */ jsx76(Card, { elevation: "flat", children: /* @__PURE__ */ jsx76("p", { className: "fd-body-sm fd-muted", style: { margin: 0 }, children: "No endpoint matches those filters." }) }) : effGroups.map(([g, ids]) => {
7818
8070
  const items = hits.filter((s) => ids.indexOf(s.id) >= 0);
7819
8071
  if (!items.length) return null;
7820
- return /* @__PURE__ */ jsxs66("div", { className: "fd-stack", style: { gap: 12 }, children: [
7821
- /* @__PURE__ */ jsx75("span", { className: "fd-label-lg", children: g }),
7822
- items.map((s) => /* @__PURE__ */ jsx75(Endpoint, { s, onRequest }, s.id))
8072
+ return /* @__PURE__ */ jsxs67("div", { className: "fd-stack", style: { gap: 12 }, children: [
8073
+ /* @__PURE__ */ jsx76("span", { className: "fd-label-lg", children: g }),
8074
+ items.map((s) => /* @__PURE__ */ jsx76(Endpoint, { s, onRequest }, s.id))
7823
8075
  ] }, g);
7824
8076
  }),
7825
- conventions && conventions.length ? /* @__PURE__ */ jsx75(Card, { title: "Cross-cutting conventions", elevation: "flat", children: /* @__PURE__ */ jsx75("div", { className: "fd-stack", style: { gap: 10 }, children: conventions.map(([k, v]) => /* @__PURE__ */ jsxs66("div", { className: "fd-row", style: { gap: 12, alignItems: "flex-start" }, children: [
7826
- /* @__PURE__ */ jsx75("span", { className: "fd-overline fd-muted", style: { width: 110, flex: "none", paddingTop: 2 }, children: k }),
7827
- /* @__PURE__ */ jsx75("span", { className: "fd-body-sm fd-secondary", style: { textWrap: "pretty" }, children: v })
8077
+ conventions && conventions.length ? /* @__PURE__ */ jsx76(Card, { title: "Cross-cutting conventions", elevation: "flat", children: /* @__PURE__ */ jsx76("div", { className: "fd-stack", style: { gap: 10 }, children: conventions.map(([k, v]) => /* @__PURE__ */ jsxs67("div", { className: "fd-row", style: { gap: 12, alignItems: "flex-start" }, children: [
8078
+ /* @__PURE__ */ jsx76("span", { className: "fd-overline fd-muted", style: { width: 110, flex: "none", paddingTop: 2 }, children: k }),
8079
+ /* @__PURE__ */ jsx76("span", { className: "fd-body-sm fd-secondary", style: { textWrap: "pretty" }, children: v })
7828
8080
  ] }, k)) }) }) : null,
7829
- openQuestions && openQuestions.length ? /* @__PURE__ */ jsx75(Collapsible, { icon: "list-checks", title: "Open questions before implementation", subtitle: openQuestions.length + " unresolved", children: /* @__PURE__ */ jsx75("div", { className: "fd-stack", style: { gap: 8 }, children: openQuestions.map(([id, question, why]) => /* @__PURE__ */ jsxs66("div", { className: "fd-row", style: { gap: 10, alignItems: "flex-start", padding: "8px 0", borderTop: "1px solid var(--border)" }, children: [
7830
- /* @__PURE__ */ jsx75(Badge, { tone: "danger", children: id }),
7831
- /* @__PURE__ */ jsxs66("span", { className: "fd-stack", style: { gap: 2, flex: 1 }, children: [
7832
- /* @__PURE__ */ jsx75("span", { className: "fd-body-sm", style: { fontWeight: 600 }, children: question }),
7833
- /* @__PURE__ */ jsx75("span", { className: "fd-body-sm fd-muted", children: why })
8081
+ openQuestions && openQuestions.length ? /* @__PURE__ */ jsx76(Collapsible, { icon: "list-checks", title: "Open questions before implementation", subtitle: openQuestions.length + " unresolved", children: /* @__PURE__ */ jsx76("div", { className: "fd-stack", style: { gap: 8 }, children: openQuestions.map(([id, question, why]) => /* @__PURE__ */ jsxs67("div", { className: "fd-row", style: { gap: 10, alignItems: "flex-start", padding: "8px 0", borderTop: "1px solid var(--border)" }, children: [
8082
+ /* @__PURE__ */ jsx76(Badge, { tone: "danger", children: id }),
8083
+ /* @__PURE__ */ jsxs67("span", { className: "fd-stack", style: { gap: 2, flex: 1 }, children: [
8084
+ /* @__PURE__ */ jsx76("span", { className: "fd-body-sm", style: { fontWeight: 600 }, children: question }),
8085
+ /* @__PURE__ */ jsx76("span", { className: "fd-body-sm fd-muted", children: why })
7834
8086
  ] })
7835
8087
  ] }, id)) }) }) : null
7836
8088
  ] });
7837
8089
  }
7838
8090
 
7839
8091
  // src/components/platform/ProfilePage.tsx
7840
- import * as React49 from "react";
7841
- import { jsx as jsx76, jsxs as jsxs67 } from "react/jsx-runtime";
8092
+ import * as React50 from "react";
8093
+ import { jsx as jsx77, jsxs as jsxs68 } from "react/jsx-runtime";
7842
8094
  function fieldInitialValue(field, user) {
7843
8095
  if (field.value) return field.value(user);
7844
8096
  const raw = user[field.key];
@@ -7873,21 +8125,21 @@ function ProfilePage({
7873
8125
  }) {
7874
8126
  const { user: sessionUser, roles, permissions, saveProfile: saveProfile2 } = useSessionContext();
7875
8127
  const user = userProp || sessionUser;
7876
- const initialFieldValues = React49.useMemo(() => {
8128
+ const initialFieldValues = React50.useMemo(() => {
7877
8129
  const values2 = {};
7878
8130
  for (const field of fields) values2[field.key] = fieldInitialValue(field, user);
7879
8131
  return values2;
7880
8132
  }, [user.id, fields]);
7881
- const initialNotify = React49.useMemo(() => {
8133
+ const initialNotify = React50.useMemo(() => {
7882
8134
  const values2 = {};
7883
8135
  for (const n of notifications) values2[n.key] = !!user.notify?.[n.key];
7884
8136
  return values2;
7885
8137
  }, [user.id, notifications]);
7886
- const [values, setValues] = React49.useState(initialFieldValues);
7887
- const [notify, setNotify] = React49.useState(initialNotify);
7888
- const [saving, setSaving] = React49.useState(false);
7889
- const [saved, setSaved] = React49.useState(false);
7890
- const [prevUserId, setPrevUserId] = React49.useState(user.id);
8138
+ const [values, setValues] = React50.useState(initialFieldValues);
8139
+ const [notify, setNotify] = React50.useState(initialNotify);
8140
+ const [saving, setSaving] = React50.useState(false);
8141
+ const [saved, setSaved] = React50.useState(false);
8142
+ const [prevUserId, setPrevUserId] = React50.useState(user.id);
7891
8143
  if (user.id !== prevUserId) {
7892
8144
  setPrevUserId(user.id);
7893
8145
  setValues(initialFieldValues);
@@ -7924,37 +8176,37 @@ function ProfilePage({
7924
8176
  };
7925
8177
  const displayName = fields.some((f) => f.key === "name") ? values.name || user.name : user.name;
7926
8178
  const fieldGroups = groupFields(fields);
7927
- return /* @__PURE__ */ jsxs67("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 20, maxWidth: 860 }, children: [
7928
- /* @__PURE__ */ jsxs67("div", { className: "fd-stack", style: { gap: 10 }, children: [
7929
- /* @__PURE__ */ jsx76("span", { className: "fd-overline fd-muted", children: "Account" }),
7930
- /* @__PURE__ */ jsx76("h1", { className: "fd-h1", style: { margin: 0 }, children: "Your profile" }),
7931
- /* @__PURE__ */ jsx76("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." })
8179
+ return /* @__PURE__ */ jsxs68("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 20, maxWidth: 860 }, children: [
8180
+ /* @__PURE__ */ jsxs68("div", { className: "fd-stack", style: { gap: 10 }, children: [
8181
+ /* @__PURE__ */ jsx77("span", { className: "fd-overline fd-muted", children: "Account" }),
8182
+ /* @__PURE__ */ jsx77("h1", { className: "fd-h1", style: { margin: 0 }, children: "Your profile" }),
8183
+ /* @__PURE__ */ jsx77("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." })
7932
8184
  ] }),
7933
- /* @__PURE__ */ jsx76(Card, { elevation: "flat", children: /* @__PURE__ */ jsxs67("div", { className: "fd-row", style: { gap: 16, flexWrap: "wrap", alignItems: "flex-start" }, children: [
7934
- /* @__PURE__ */ jsx76(Avatar, { name: displayName, size: "lg" }),
7935
- /* @__PURE__ */ jsxs67("div", { className: "fd-stack", style: { gap: 4, flex: 1, minWidth: 200 }, children: [
7936
- /* @__PURE__ */ jsx76("span", { className: "fd-h3", style: { margin: 0 }, children: displayName }),
7937
- /* @__PURE__ */ jsxs67("span", { className: "fd-row", style: { gap: 6, flexWrap: "wrap", paddingTop: 4 }, children: [
7938
- roles.map((r) => /* @__PURE__ */ jsx76(Badge, { tone: r.id === "owner" ? "success" : "neutral", children: r.name }, r.id)),
7939
- user.sso ? /* @__PURE__ */ jsx76(Badge, { tone: "info", icon: "shield-check", children: "SSO" }) : null
8185
+ /* @__PURE__ */ jsx77(Card, { elevation: "flat", children: /* @__PURE__ */ jsxs68("div", { className: "fd-row", style: { gap: 16, flexWrap: "wrap", alignItems: "flex-start" }, children: [
8186
+ /* @__PURE__ */ jsx77(Avatar, { name: displayName, size: "lg" }),
8187
+ /* @__PURE__ */ jsxs68("div", { className: "fd-stack", style: { gap: 4, flex: 1, minWidth: 200 }, children: [
8188
+ /* @__PURE__ */ jsx77("span", { className: "fd-h3", style: { margin: 0 }, children: displayName }),
8189
+ /* @__PURE__ */ jsxs68("span", { className: "fd-row", style: { gap: 6, flexWrap: "wrap", paddingTop: 4 }, children: [
8190
+ roles.map((r) => /* @__PURE__ */ jsx77(Badge, { tone: r.id === "owner" ? "success" : "neutral", children: r.name }, r.id)),
8191
+ user.sso ? /* @__PURE__ */ jsx77(Badge, { tone: "info", icon: "shield-check", children: "SSO" }) : null
7940
8192
  ] })
7941
8193
  ] }),
7942
- onChangePhoto ? /* @__PURE__ */ jsx76(Button, { variant: "secondary", size: "sm", icon: "image", onClick: onChangePhoto, children: "Change photo" }) : null
8194
+ onChangePhoto ? /* @__PURE__ */ jsx77(Button, { variant: "secondary", size: "sm", icon: "image", onClick: onChangePhoto, children: "Change photo" }) : null
7943
8195
  ] }) }),
7944
- fieldGroups.map(({ group, description, fields: groupFieldDefs }) => /* @__PURE__ */ jsx76(
8196
+ fieldGroups.map(({ group, description, fields: groupFieldDefs }) => /* @__PURE__ */ jsx77(
7945
8197
  Card,
7946
8198
  {
7947
- title: description ? /* @__PURE__ */ jsxs67("span", { className: "fd-stack", style: { gap: 2 }, children: [
7948
- /* @__PURE__ */ jsx76("span", { children: group }),
7949
- /* @__PURE__ */ jsx76("span", { className: "fd-body-sm fd-muted", style: { fontWeight: 400 }, children: description })
8199
+ title: description ? /* @__PURE__ */ jsxs68("span", { className: "fd-stack", style: { gap: 2 }, children: [
8200
+ /* @__PURE__ */ jsx77("span", { children: group }),
8201
+ /* @__PURE__ */ jsx77("span", { className: "fd-body-sm fd-muted", style: { fontWeight: 400 }, children: description })
7950
8202
  ] }) : group,
7951
8203
  elevation: "flat",
7952
- children: /* @__PURE__ */ jsxs67("div", { className: "fd-stack", style: { gap: 14 }, children: [
7953
- /* @__PURE__ */ jsx76("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(220px,1fr))", gap: 14 }, children: groupFieldDefs.filter((f) => f.type !== "textarea").map((field) => {
8204
+ children: /* @__PURE__ */ jsxs68("div", { className: "fd-stack", style: { gap: 14 }, children: [
8205
+ /* @__PURE__ */ jsx77("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(220px,1fr))", gap: 14 }, children: groupFieldDefs.filter((f) => f.type !== "textarea").map((field) => {
7954
8206
  const help = typeof field.help === "function" ? field.help(user) : field.help;
7955
8207
  const readOnly = field.readOnly || field.type === "readonly";
7956
8208
  if (field.type === "select") {
7957
- return /* @__PURE__ */ jsx76(
8209
+ return /* @__PURE__ */ jsx77(
7958
8210
  Select,
7959
8211
  {
7960
8212
  label: field.label,
@@ -7968,7 +8220,7 @@ function ProfilePage({
7968
8220
  field.key
7969
8221
  );
7970
8222
  }
7971
- return /* @__PURE__ */ jsx76(
8223
+ return /* @__PURE__ */ jsx77(
7972
8224
  Input,
7973
8225
  {
7974
8226
  label: field.label,
@@ -7984,7 +8236,7 @@ function ProfilePage({
7984
8236
  }) }),
7985
8237
  groupFieldDefs.filter((f) => f.type === "textarea").map((field) => {
7986
8238
  const help = typeof field.help === "function" ? field.help(user) : field.help;
7987
- return /* @__PURE__ */ jsx76(
8239
+ return /* @__PURE__ */ jsx77(
7988
8240
  Textarea,
7989
8241
  {
7990
8242
  label: field.label,
@@ -8004,16 +8256,16 @@ function ProfilePage({
8004
8256
  group
8005
8257
  )),
8006
8258
  extra,
8007
- notifications.length > 0 ? /* @__PURE__ */ jsx76(Card, { title: "Notifications", elevation: "flat", children: /* @__PURE__ */ jsx76("div", { className: "fd-stack", style: { gap: 14 }, children: notifications.map((n) => /* @__PURE__ */ jsx76(Switch, { checked: !!notify[n.key], onChange: () => toggleNotify(n.key), label: n.label, description: n.description }, n.key)) }) }) : null,
8008
- /* @__PURE__ */ jsxs67(
8259
+ notifications.length > 0 ? /* @__PURE__ */ jsx77(Card, { title: "Notifications", elevation: "flat", children: /* @__PURE__ */ jsx77("div", { className: "fd-stack", style: { gap: 14 }, children: notifications.map((n) => /* @__PURE__ */ jsx77(Switch, { checked: !!notify[n.key], onChange: () => toggleNotify(n.key), label: n.label, description: n.description }, n.key)) }) }) : null,
8260
+ /* @__PURE__ */ jsxs68(
8009
8261
  Card,
8010
8262
  {
8011
- title: /* @__PURE__ */ jsxs67("span", { className: "fd-stack", style: { gap: 2 }, children: [
8012
- /* @__PURE__ */ jsx76("span", { children: "Access" }),
8013
- /* @__PURE__ */ jsx76("span", { className: "fd-body-sm fd-muted", style: { fontWeight: 400 }, children: "What your roles grant you" })
8263
+ title: /* @__PURE__ */ jsxs68("span", { className: "fd-stack", style: { gap: 2 }, children: [
8264
+ /* @__PURE__ */ jsx77("span", { children: "Access" }),
8265
+ /* @__PURE__ */ jsx77("span", { className: "fd-body-sm fd-muted", style: { fontWeight: 400 }, children: "What your roles grant you" })
8014
8266
  ] }),
8015
8267
  elevation: "flat",
8016
- action: /* @__PURE__ */ jsx76(
8268
+ action: /* @__PURE__ */ jsx77(
8017
8269
  Button,
8018
8270
  {
8019
8271
  size: "sm",
@@ -8024,39 +8276,39 @@ function ProfilePage({
8024
8276
  }
8025
8277
  ),
8026
8278
  children: [
8027
- /* @__PURE__ */ jsxs67("div", { className: "fd-stack", style: { gap: 0 }, children: [
8028
- /* @__PURE__ */ jsx76(CardRow, { label: "Roles", children: roles.map((r) => r.name).join(", ") || "None" }),
8029
- /* @__PURE__ */ jsxs67(CardRow, { label: "Permissions", children: [
8279
+ /* @__PURE__ */ jsxs68("div", { className: "fd-stack", style: { gap: 0 }, children: [
8280
+ /* @__PURE__ */ jsx77(CardRow, { label: "Roles", children: roles.map((r) => r.name).join(", ") || "None" }),
8281
+ /* @__PURE__ */ jsxs68(CardRow, { label: "Permissions", children: [
8030
8282
  permissions.length,
8031
8283
  " granted"
8032
8284
  ] }),
8033
- /* @__PURE__ */ jsx76(CardRow, { label: "Member since", children: user.joined || "\u2014" })
8285
+ /* @__PURE__ */ jsx77(CardRow, { label: "Member since", children: user.joined || "\u2014" })
8034
8286
  ] }),
8035
- /* @__PURE__ */ jsx76("p", { className: "fd-body-sm fd-muted", style: { margin: "12px 0 0" }, children: "You cannot change your own roles \u2014 that is the point of them. An administrator manages roles from Admin \u2192 Users." })
8287
+ /* @__PURE__ */ jsx77("p", { className: "fd-body-sm fd-muted", style: { margin: "12px 0 0" }, children: "You cannot change your own roles \u2014 that is the point of them. An administrator manages roles from Admin \u2192 Users." })
8036
8288
  ]
8037
8289
  }
8038
8290
  ),
8039
- sessions ? /* @__PURE__ */ jsx76(
8291
+ sessions ? /* @__PURE__ */ jsx77(
8040
8292
  Card,
8041
8293
  {
8042
8294
  title: "Signed-in devices",
8043
8295
  elevation: "flat",
8044
- action: /* @__PURE__ */ jsx76(Button, { size: "sm", variant: "ghost", icon: "sign-out", onClick: onSignOutEverywhere, children: "Sign out everywhere" }),
8045
- children: /* @__PURE__ */ jsx76("div", { className: "fd-stack", style: { gap: 0 }, children: sessions.length === 0 ? /* @__PURE__ */ jsx76("p", { className: "fd-body-sm fd-muted", style: { margin: 0 }, children: "No other signed-in devices." }) : sessions.map((s) => /* @__PURE__ */ jsxs67("div", { className: "fd-row", style: { gap: 12, padding: "10px 0", borderTop: "1px solid var(--border)", flexWrap: "wrap" }, children: [
8046
- /* @__PURE__ */ jsx76("i", { className: "ph ph-device-mobile", style: { fontSize: 16, color: "var(--text-muted)" }, "aria-hidden": "true" }),
8047
- /* @__PURE__ */ jsxs67("span", { className: "fd-stack", style: { gap: 1, flex: 1, minWidth: 160 }, children: [
8048
- /* @__PURE__ */ jsx76("span", { className: "fd-body-sm", style: { fontWeight: 600 }, children: s.device }),
8049
- /* @__PURE__ */ jsxs67("span", { className: "fd-body-sm fd-muted", children: [
8296
+ action: /* @__PURE__ */ jsx77(Button, { size: "sm", variant: "ghost", icon: "sign-out", onClick: onSignOutEverywhere, children: "Sign out everywhere" }),
8297
+ children: /* @__PURE__ */ jsx77("div", { className: "fd-stack", style: { gap: 0 }, children: sessions.length === 0 ? /* @__PURE__ */ jsx77("p", { className: "fd-body-sm fd-muted", style: { margin: 0 }, children: "No other signed-in devices." }) : sessions.map((s) => /* @__PURE__ */ jsxs68("div", { className: "fd-row", style: { gap: 12, padding: "10px 0", borderTop: "1px solid var(--border)", flexWrap: "wrap" }, children: [
8298
+ /* @__PURE__ */ jsx77("i", { className: "ph ph-device-mobile", style: { fontSize: 16, color: "var(--text-muted)" }, "aria-hidden": "true" }),
8299
+ /* @__PURE__ */ jsxs68("span", { className: "fd-stack", style: { gap: 1, flex: 1, minWidth: 160 }, children: [
8300
+ /* @__PURE__ */ jsx77("span", { className: "fd-body-sm", style: { fontWeight: 600 }, children: s.device }),
8301
+ /* @__PURE__ */ jsxs68("span", { className: "fd-body-sm fd-muted", children: [
8050
8302
  s.where,
8051
8303
  " \xB7 ",
8052
8304
  s.when
8053
8305
  ] })
8054
8306
  ] }),
8055
- s.current ? /* @__PURE__ */ jsx76(Badge, { tone: "success", dot: true, children: "This device" }) : /* @__PURE__ */ jsx76(Button, { size: "sm", variant: "ghost", children: "Revoke" })
8307
+ s.current ? /* @__PURE__ */ jsx77(Badge, { tone: "success", dot: true, children: "This device" }) : /* @__PURE__ */ jsx77(Button, { size: "sm", variant: "ghost", children: "Revoke" })
8056
8308
  ] }, s.id)) })
8057
8309
  }
8058
8310
  ) : null,
8059
- /* @__PURE__ */ jsxs67("div", { className: "fd-row", style: {
8311
+ /* @__PURE__ */ jsxs68("div", { className: "fd-row", style: {
8060
8312
  gap: 10,
8061
8313
  flexWrap: "wrap",
8062
8314
  position: "sticky",
@@ -8067,19 +8319,19 @@ function ProfilePage({
8067
8319
  border: "1px solid var(--border)",
8068
8320
  boxShadow: "0 -4px 16px rgba(11,13,17,.06)"
8069
8321
  }, children: [
8070
- /* @__PURE__ */ jsx76("span", { className: "fd-body-sm", style: { fontWeight: 600, flex: 1 }, children: saved ? "Saved." : dirty ? "Unsaved changes" : "No pending changes" }),
8071
- /* @__PURE__ */ jsx76(Button, { size: "sm", variant: "ghost", disabled: !dirty || saving, onClick: discard, children: "Discard" }),
8072
- /* @__PURE__ */ jsx76(Button, { size: "sm", icon: "check", disabled: !dirty || !canSave, loading: saving, onClick: save, children: "Save changes" })
8322
+ /* @__PURE__ */ jsx77("span", { className: "fd-body-sm", style: { fontWeight: 600, flex: 1 }, children: saved ? "Saved." : dirty ? "Unsaved changes" : "No pending changes" }),
8323
+ /* @__PURE__ */ jsx77(Button, { size: "sm", variant: "ghost", disabled: !dirty || saving, onClick: discard, children: "Discard" }),
8324
+ /* @__PURE__ */ jsx77(Button, { size: "sm", icon: "check", disabled: !dirty || !canSave, loading: saving, onClick: save, children: "Save changes" })
8073
8325
  ] })
8074
8326
  ] });
8075
8327
  }
8076
8328
 
8077
8329
  // src/components/platform/SignInPage.tsx
8078
- import * as React50 from "react";
8079
- import { Fragment as Fragment18, jsx as jsx77, jsxs as jsxs68 } from "react/jsx-runtime";
8330
+ import * as React51 from "react";
8331
+ import { Fragment as Fragment19, jsx as jsx78, jsxs as jsxs69 } from "react/jsx-runtime";
8080
8332
  function SignInPage({ productName, onSignIn, continueAs, error }) {
8081
- const [signingIn, setSigningIn] = React50.useState(false);
8082
- const [resuming, setResuming] = React50.useState(false);
8333
+ const [signingIn, setSigningIn] = React51.useState(false);
8334
+ const [resuming, setResuming] = React51.useState(false);
8083
8335
  function handleSignIn() {
8084
8336
  setSigningIn(true);
8085
8337
  onSignIn();
@@ -8088,7 +8340,7 @@ function SignInPage({ productName, onSignIn, continueAs, error }) {
8088
8340
  setResuming(true);
8089
8341
  continueAs.onContinue().finally(() => setResuming(false));
8090
8342
  }
8091
- return /* @__PURE__ */ jsxs68(
8343
+ return /* @__PURE__ */ jsxs69(
8092
8344
  "div",
8093
8345
  {
8094
8346
  style: {
@@ -8102,7 +8354,7 @@ function SignInPage({ productName, onSignIn, continueAs, error }) {
8102
8354
  background: "radial-gradient(circle at 15% 15%, var(--blue-700) 0%, transparent 45%), radial-gradient(circle at 85% 85%, var(--blue-600) 0%, transparent 40%), linear-gradient(160deg, var(--navy) 0%, var(--blue-950) 55%, var(--blue-900) 100%)"
8103
8355
  },
8104
8356
  children: [
8105
- /* @__PURE__ */ jsx77(
8357
+ /* @__PURE__ */ jsx78(
8106
8358
  "div",
8107
8359
  {
8108
8360
  "aria-hidden": true,
@@ -8115,7 +8367,7 @@ function SignInPage({ productName, onSignIn, continueAs, error }) {
8115
8367
  }
8116
8368
  }
8117
8369
  ),
8118
- /* @__PURE__ */ jsxs68(
8370
+ /* @__PURE__ */ jsxs69(
8119
8371
  "div",
8120
8372
  {
8121
8373
  style: {
@@ -8127,8 +8379,8 @@ function SignInPage({ productName, onSignIn, continueAs, error }) {
8127
8379
  alignItems: "center"
8128
8380
  },
8129
8381
  children: [
8130
- /* @__PURE__ */ jsx77("div", { style: { marginBottom: "var(--s-32)" }, "data-theme": "dark", children: /* @__PURE__ */ jsx77(FlytedeskMark, { size: "lg" }) }),
8131
- /* @__PURE__ */ jsxs68(
8382
+ /* @__PURE__ */ jsx78("div", { style: { marginBottom: "var(--s-32)" }, "data-theme": "dark", children: /* @__PURE__ */ jsx78(FlytedeskMark, { size: "lg" }) }),
8383
+ /* @__PURE__ */ jsxs69(
8132
8384
  "div",
8133
8385
  {
8134
8386
  style: {
@@ -8138,7 +8390,7 @@ function SignInPage({ productName, onSignIn, continueAs, error }) {
8138
8390
  boxShadow: "0 24px 64px -12px rgba(2, 8, 20, 0.55), 0 2px 8px rgba(2, 8, 20, 0.3)"
8139
8391
  },
8140
8392
  children: [
8141
- /* @__PURE__ */ jsx77(
8393
+ /* @__PURE__ */ jsx78(
8142
8394
  "div",
8143
8395
  {
8144
8396
  style: {
@@ -8147,7 +8399,7 @@ function SignInPage({ productName, onSignIn, continueAs, error }) {
8147
8399
  }
8148
8400
  }
8149
8401
  ),
8150
- /* @__PURE__ */ jsx77(Card, { children: /* @__PURE__ */ jsxs68(
8402
+ /* @__PURE__ */ jsx78(Card, { children: /* @__PURE__ */ jsxs69(
8151
8403
  "div",
8152
8404
  {
8153
8405
  style: {
@@ -8159,13 +8411,13 @@ function SignInPage({ productName, onSignIn, continueAs, error }) {
8159
8411
  padding: "var(--s-8) 0"
8160
8412
  },
8161
8413
  children: [
8162
- /* @__PURE__ */ jsxs68("div", { children: [
8163
- /* @__PURE__ */ jsx77("h1", { className: "fd-h3", style: { color: "var(--navy)" }, children: productName }),
8164
- /* @__PURE__ */ jsx77("p", { className: "fd-body-sm fd-muted", style: { marginTop: "var(--s-4)" }, children: continueAs ? "Your session timed out, but you're likely still signed in" : "Sign in with your flytedesk workspace account" })
8414
+ /* @__PURE__ */ jsxs69("div", { children: [
8415
+ /* @__PURE__ */ jsx78("h1", { className: "fd-h3", style: { color: "var(--navy)" }, children: productName }),
8416
+ /* @__PURE__ */ jsx78("p", { className: "fd-body-sm fd-muted", style: { marginTop: "var(--s-4)" }, children: continueAs ? "Your session timed out, but you're likely still signed in" : "Sign in with your flytedesk workspace account" })
8165
8417
  ] }),
8166
- error ? /* @__PURE__ */ jsx77("div", { role: "alert", style: { width: "100%" }, children: /* @__PURE__ */ jsx77(Banner, { tone: "danger", title: error }) }) : null,
8167
- continueAs ? /* @__PURE__ */ jsxs68(Fragment18, { children: [
8168
- /* @__PURE__ */ jsx77(
8418
+ error ? /* @__PURE__ */ jsx78("div", { role: "alert", style: { width: "100%" }, children: /* @__PURE__ */ jsx78(Banner, { tone: "danger", title: error }) }) : null,
8419
+ continueAs ? /* @__PURE__ */ jsxs69(Fragment19, { children: [
8420
+ /* @__PURE__ */ jsx78(
8169
8421
  Button,
8170
8422
  {
8171
8423
  variant: "primary",
@@ -8176,7 +8428,7 @@ function SignInPage({ productName, onSignIn, continueAs, error }) {
8176
8428
  children: resuming ? "Resuming\u2026" : `Continue as ${continueAs.name}`
8177
8429
  }
8178
8430
  ),
8179
- /* @__PURE__ */ jsx77(
8431
+ /* @__PURE__ */ jsx78(
8180
8432
  "button",
8181
8433
  {
8182
8434
  type: "button",
@@ -8193,7 +8445,7 @@ function SignInPage({ productName, onSignIn, continueAs, error }) {
8193
8445
  children: "Not you? Sign in with flytedesk ID"
8194
8446
  }
8195
8447
  )
8196
- ] }) : /* @__PURE__ */ jsx77(
8448
+ ] }) : /* @__PURE__ */ jsx78(
8197
8449
  Button,
8198
8450
  {
8199
8451
  variant: "primary",
@@ -8201,7 +8453,7 @@ function SignInPage({ productName, onSignIn, continueAs, error }) {
8201
8453
  loading: signingIn,
8202
8454
  disabled: signingIn,
8203
8455
  onClick: handleSignIn,
8204
- children: /* @__PURE__ */ jsxs68(
8456
+ children: /* @__PURE__ */ jsxs69(
8205
8457
  "span",
8206
8458
  {
8207
8459
  style: {
@@ -8213,14 +8465,14 @@ function SignInPage({ productName, onSignIn, continueAs, error }) {
8213
8465
  flexWrap: "nowrap"
8214
8466
  },
8215
8467
  children: [
8216
- /* @__PURE__ */ jsx77(GoogleGlyph, {}),
8217
- /* @__PURE__ */ jsx77("span", { children: signingIn ? "Signing in\u2026" : "Sign in with flytedesk ID" })
8468
+ /* @__PURE__ */ jsx78(GoogleGlyph, {}),
8469
+ /* @__PURE__ */ jsx78("span", { children: signingIn ? "Signing in\u2026" : "Sign in with flytedesk ID" })
8218
8470
  ]
8219
8471
  }
8220
8472
  )
8221
8473
  }
8222
8474
  ),
8223
- /* @__PURE__ */ jsx77("p", { className: "fd-body-sm fd-muted", style: { fontSize: "12px" }, children: "One account, every flytedesk app." })
8475
+ /* @__PURE__ */ jsx78("p", { className: "fd-body-sm fd-muted", style: { fontSize: "12px" }, children: "One account, every flytedesk app." })
8224
8476
  ]
8225
8477
  }
8226
8478
  ) })
@@ -8235,29 +8487,29 @@ function SignInPage({ productName, onSignIn, continueAs, error }) {
8235
8487
  );
8236
8488
  }
8237
8489
  function GoogleGlyph() {
8238
- return /* @__PURE__ */ jsxs68("svg", { width: "18", height: "18", viewBox: "0 0 18 18", "aria-hidden": true, children: [
8239
- /* @__PURE__ */ jsx77(
8490
+ return /* @__PURE__ */ jsxs69("svg", { width: "18", height: "18", viewBox: "0 0 18 18", "aria-hidden": true, children: [
8491
+ /* @__PURE__ */ jsx78(
8240
8492
  "path",
8241
8493
  {
8242
8494
  fill: "#4285F4",
8243
8495
  d: "M17.64 9.2c0-.64-.06-1.25-.16-1.84H9v3.48h4.84a4.14 4.14 0 0 1-1.8 2.72v2.26h2.92c1.7-1.57 2.68-3.87 2.68-6.62Z"
8244
8496
  }
8245
8497
  ),
8246
- /* @__PURE__ */ jsx77(
8498
+ /* @__PURE__ */ jsx78(
8247
8499
  "path",
8248
8500
  {
8249
8501
  fill: "#34A853",
8250
8502
  d: "M9 18c2.43 0 4.47-.8 5.96-2.18l-2.92-2.26c-.81.54-1.84.87-3.04.87-2.34 0-4.32-1.58-5.03-3.7H.96v2.33A9 9 0 0 0 9 18Z"
8251
8503
  }
8252
8504
  ),
8253
- /* @__PURE__ */ jsx77(
8505
+ /* @__PURE__ */ jsx78(
8254
8506
  "path",
8255
8507
  {
8256
8508
  fill: "#FBBC05",
8257
8509
  d: "M3.97 10.73A5.4 5.4 0 0 1 3.68 9c0-.6.1-1.19.29-1.73V4.94H.96A9 9 0 0 0 0 9c0 1.45.35 2.83.96 4.06l3.01-2.33Z"
8258
8510
  }
8259
8511
  ),
8260
- /* @__PURE__ */ jsx77(
8512
+ /* @__PURE__ */ jsx78(
8261
8513
  "path",
8262
8514
  {
8263
8515
  fill: "#EA4335",
@@ -8268,10 +8520,10 @@ function GoogleGlyph() {
8268
8520
  }
8269
8521
 
8270
8522
  // src/components/platform/RoadmapTimeline.tsx
8271
- import * as React53 from "react";
8523
+ import * as React54 from "react";
8272
8524
 
8273
8525
  // src/kits/session.ts
8274
- import * as React51 from "react";
8526
+ import * as React52 from "react";
8275
8527
  var PERMISSION_CATALOG = [
8276
8528
  { group: "Plans", items: [
8277
8529
  { key: "plan.view", label: "View plans", detail: "Read any plan in the workspace." },
@@ -9838,8 +10090,8 @@ function roadmap(overrides) {
9838
10090
  };
9839
10091
  }
9840
10092
  function useSession() {
9841
- const [s, setS] = React51.useState(getSession);
9842
- React51.useEffect(() => subscribe(setS), []);
10093
+ const [s, setS] = React52.useState(getSession);
10094
+ React52.useEffect(() => subscribe(setS), []);
9843
10095
  return s;
9844
10096
  }
9845
10097
  var SessionKit = {
@@ -9872,7 +10124,7 @@ var SessionKit = {
9872
10124
  };
9873
10125
  function DemoSessionProvider({ children }) {
9874
10126
  const session = useSession();
9875
- const value = React51.useMemo(
10127
+ const value = React52.useMemo(
9876
10128
  () => ({
9877
10129
  user: session.user,
9878
10130
  roles: session.roles,
@@ -9888,11 +10140,11 @@ function DemoSessionProvider({ children }) {
9888
10140
  }),
9889
10141
  [session]
9890
10142
  );
9891
- return React51.createElement(SessionProvider, { value }, children);
10143
+ return React52.createElement(SessionProvider, { value }, children);
9892
10144
  }
9893
10145
 
9894
10146
  // src/kits/runtime.ts
9895
- import * as React52 from "react";
10147
+ import * as React53 from "react";
9896
10148
  var WIRED_ENDPOINTS = [
9897
10149
  // Nothing yet. Every id below would come from a real service:
9898
10150
  // "plan.get", "placements.list", …
@@ -10063,8 +10315,8 @@ var RuntimeKit = {
10063
10315
  };
10064
10316
  RuntimeKit.declare(FEATURE_NEEDS);
10065
10317
  function useRuntimeMode() {
10066
- const [m, setM] = React52.useState(RuntimeKit.getMode());
10067
- React52.useEffect(() => RuntimeKit.subscribe(setM), []);
10318
+ const [m, setM] = React53.useState(RuntimeKit.getMode());
10319
+ React53.useEffect(() => RuntimeKit.subscribe(setM), []);
10068
10320
  return m;
10069
10321
  }
10070
10322
  function useFeatureStatus(key) {
@@ -10083,7 +10335,7 @@ var UseRuntimeMode = useRuntimeMode;
10083
10335
  var UseFeatureStatus = useFeatureStatus;
10084
10336
 
10085
10337
  // src/components/platform/RoadmapTimeline.tsx
10086
- import { jsx as jsx78, jsxs as jsxs69 } from "react/jsx-runtime";
10338
+ import { jsx as jsx79, jsxs as jsxs70 } from "react/jsx-runtime";
10087
10339
  var STATUS = {
10088
10340
  shipped: { tone: "success", icon: "check-circle", label: "Wired" },
10089
10341
  next: { tone: "warning", icon: "traffic-cone", label: "Not wired" },
@@ -10098,45 +10350,45 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
10098
10350
  const s = STATUS[item.status] || STATUS.planned;
10099
10351
  const deps = (item.dependsOn || []).map((k) => byKey[k]).filter(Boolean);
10100
10352
  const blocking = deps.filter((d) => !d.implemented);
10101
- return /* @__PURE__ */ jsx78(Card, { elevation: "flat", children: /* @__PURE__ */ jsxs69("div", { className: "fd-stack", style: { gap: 10 }, children: [
10102
- /* @__PURE__ */ jsxs69("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: [
10103
- /* @__PURE__ */ jsx78("span", { className: "fd-body", style: { fontWeight: 700, flex: 1, minWidth: 140 }, children: item.label }),
10104
- /* @__PURE__ */ jsx78(Badge, { tone: "neutral", icon: PROJECT_ICON[item.project] || "squares-four", children: item.project }),
10105
- /* @__PURE__ */ jsx78(Badge, { tone: s.tone, icon: s.icon, children: s.label })
10353
+ return /* @__PURE__ */ jsx79(Card, { elevation: "flat", children: /* @__PURE__ */ jsxs70("div", { className: "fd-stack", style: { gap: 10 }, children: [
10354
+ /* @__PURE__ */ jsxs70("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: [
10355
+ /* @__PURE__ */ jsx79("span", { className: "fd-body", style: { fontWeight: 700, flex: 1, minWidth: 140 }, children: item.label }),
10356
+ /* @__PURE__ */ jsx79(Badge, { tone: "neutral", icon: PROJECT_ICON[item.project] || "squares-four", children: item.project }),
10357
+ /* @__PURE__ */ jsx79(Badge, { tone: s.tone, icon: s.icon, children: s.label })
10106
10358
  ] }),
10107
- /* @__PURE__ */ jsx78("p", { className: "fd-body-sm fd-secondary", style: { margin: 0, textWrap: "pretty" }, children: item.description }),
10108
- item.backend ? /* @__PURE__ */ jsxs69("div", { className: "fd-row", style: { gap: 10, alignItems: "flex-start" }, children: [
10109
- /* @__PURE__ */ jsx78("span", { className: "fd-overline fd-muted", style: { width: 62, flex: "none", paddingTop: 2 }, children: "Backend" }),
10110
- /* @__PURE__ */ jsx78("span", { className: "fd-body-sm", style: { flex: 1, textWrap: "pretty" }, children: item.backend })
10359
+ /* @__PURE__ */ jsx79("p", { className: "fd-body-sm fd-secondary", style: { margin: 0, textWrap: "pretty" }, children: item.description }),
10360
+ item.backend ? /* @__PURE__ */ jsxs70("div", { className: "fd-row", style: { gap: 10, alignItems: "flex-start" }, children: [
10361
+ /* @__PURE__ */ jsx79("span", { className: "fd-overline fd-muted", style: { width: 62, flex: "none", paddingTop: 2 }, children: "Backend" }),
10362
+ /* @__PURE__ */ jsx79("span", { className: "fd-body-sm", style: { flex: 1, textWrap: "pretty" }, children: item.backend })
10111
10363
  ] }) : null,
10112
- /* @__PURE__ */ jsxs69("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
10113
- item.effort ? /* @__PURE__ */ jsxs69("span", { className: "fd-body-sm fd-muted", children: [
10114
- /* @__PURE__ */ jsx78("i", { className: "ph ph-hourglass-medium" }),
10364
+ /* @__PURE__ */ jsxs70("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
10365
+ item.effort ? /* @__PURE__ */ jsxs70("span", { className: "fd-body-sm fd-muted", children: [
10366
+ /* @__PURE__ */ jsx79("i", { className: "ph ph-hourglass-medium" }),
10115
10367
  " ",
10116
10368
  item.effort
10117
10369
  ] }) : null,
10118
- /* @__PURE__ */ jsxs69("span", { className: "fd-body-sm fd-muted", children: [
10119
- /* @__PURE__ */ jsx78("i", { className: "ph ph-user" }),
10370
+ /* @__PURE__ */ jsxs70("span", { className: "fd-body-sm fd-muted", children: [
10371
+ /* @__PURE__ */ jsx79("i", { className: "ph ph-user" }),
10120
10372
  " ",
10121
10373
  item.owner
10122
10374
  ] }),
10123
- item.screen ? /* @__PURE__ */ jsx78(Badge, { tone: "neutral", icon: "browser", children: "screen" }) : null,
10124
- /* @__PURE__ */ jsx78("span", { style: { flex: 1 } }),
10125
- /* @__PURE__ */ jsx78(
10375
+ item.screen ? /* @__PURE__ */ jsx79(Badge, { tone: "neutral", icon: "browser", children: "screen" }) : null,
10376
+ /* @__PURE__ */ jsx79("span", { style: { flex: 1 } }),
10377
+ /* @__PURE__ */ jsx79(
10126
10378
  "button",
10127
10379
  {
10128
10380
  type: "button",
10129
10381
  onClick: () => onOpenFlag && onOpenFlag(item.key),
10130
10382
  style: { all: "unset", cursor: "pointer", display: "inline-flex", alignItems: "center", gap: 5 },
10131
- children: /* @__PURE__ */ jsx78("code", { className: "fd-mono", style: { fontSize: 11, color: "var(--brand)" }, children: item.key })
10383
+ children: /* @__PURE__ */ jsx79("code", { className: "fd-mono", style: { fontSize: 11, color: "var(--brand)" }, children: item.key })
10132
10384
  }
10133
10385
  )
10134
10386
  ] }),
10135
- deps.length ? /* @__PURE__ */ jsxs69("div", { className: "fd-row", style: { gap: 6, flexWrap: "wrap", paddingTop: 6, borderTop: "1px solid var(--border)" }, children: [
10136
- /* @__PURE__ */ jsx78("span", { className: "fd-overline fd-muted", style: { paddingTop: 3 }, children: "After" }),
10137
- deps.map((d) => /* @__PURE__ */ jsx78(Tag, { icon: d.implemented ? "check" : "clock", children: d.label }, d.key))
10387
+ deps.length ? /* @__PURE__ */ jsxs70("div", { className: "fd-row", style: { gap: 6, flexWrap: "wrap", paddingTop: 6, borderTop: "1px solid var(--border)" }, children: [
10388
+ /* @__PURE__ */ jsx79("span", { className: "fd-overline fd-muted", style: { paddingTop: 3 }, children: "After" }),
10389
+ deps.map((d) => /* @__PURE__ */ jsx79(Tag, { icon: d.implemented ? "check" : "clock", children: d.label }, d.key))
10138
10390
  ] }) : null,
10139
- blocking.length && !item.implemented ? /* @__PURE__ */ jsxs69("span", { className: "fd-body-sm", style: { color: "var(--warn-text)" }, children: [
10391
+ blocking.length && !item.implemented ? /* @__PURE__ */ jsxs70("span", { className: "fd-body-sm", style: { color: "var(--warn-text)" }, children: [
10140
10392
  "Blocked until ",
10141
10393
  blocking.map((d) => d.label).join(" and "),
10142
10394
  " ",
@@ -10147,12 +10399,12 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
10147
10399
  }
10148
10400
  function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
10149
10401
  const session = SessionKit.useSession();
10150
- const [project, setProject] = React53.useState("");
10151
- const [q, setQ] = React53.useState("");
10152
- const scrollRef = React53.useRef(null);
10153
- const nowRef = React53.useRef(null);
10154
- const rm = React53.useMemo(() => SessionKit.roadmap({ isComplete: RuntimeKit.isComplete }), [session]);
10155
- const byKey = React53.useMemo(() => {
10402
+ const [project, setProject] = React54.useState("");
10403
+ const [q, setQ] = React54.useState("");
10404
+ const scrollRef = React54.useRef(null);
10405
+ const nowRef = React54.useRef(null);
10406
+ const rm = React54.useMemo(() => SessionKit.roadmap({ isComplete: RuntimeKit.isComplete }), [session]);
10407
+ const byKey = React54.useMemo(() => {
10156
10408
  const m = {};
10157
10409
  rm.items.forEach((i) => {
10158
10410
  m[i.key] = i;
@@ -10161,7 +10413,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
10161
10413
  }, [rm]);
10162
10414
  const items = rm.items.filter((i) => (!project || i.project === project) && (!q || (i.label + " " + i.description + " " + (i.backend || "") + " " + i.key).toLowerCase().includes(q.toLowerCase())));
10163
10415
  const projects = [...new Set(rm.items.map((i) => i.project))];
10164
- React53.useEffect(() => {
10416
+ React54.useEffect(() => {
10165
10417
  let raf1 = 0, raf2 = 0;
10166
10418
  const place = () => {
10167
10419
  const box = scrollRef.current, mark = nowRef.current;
@@ -10189,23 +10441,23 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
10189
10441
  }, 0);
10190
10442
  const nextPhase = items.find((i) => !i.implemented);
10191
10443
  let lastPhase = null;
10192
- return /* @__PURE__ */ jsxs69("div", { className: "fd-stack", style: { gap: 16, maxWidth: 1e3 }, children: [
10193
- /* @__PURE__ */ jsxs69("div", { className: "fd-stack", style: { gap: 10 }, children: [
10194
- /* @__PURE__ */ jsx78("span", { className: "fd-overline fd-muted", children: "Architecture" }),
10195
- /* @__PURE__ */ jsx78("h1", { className: "fd-h1", style: { margin: 0 }, children: title }),
10196
- /* @__PURE__ */ jsx78("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." })
10444
+ return /* @__PURE__ */ jsxs70("div", { className: "fd-stack", style: { gap: 16, maxWidth: 1e3 }, children: [
10445
+ /* @__PURE__ */ jsxs70("div", { className: "fd-stack", style: { gap: 10 }, children: [
10446
+ /* @__PURE__ */ jsx79("span", { className: "fd-overline fd-muted", children: "Architecture" }),
10447
+ /* @__PURE__ */ jsx79("h1", { className: "fd-h1", style: { margin: 0 }, children: title }),
10448
+ /* @__PURE__ */ jsx79("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." })
10197
10449
  ] }),
10198
- /* @__PURE__ */ jsxs69("div", { className: "fd-grid-stats is-thin", children: [
10199
- /* @__PURE__ */ jsx78(StatTile, { compact: true, label: "Wired", value: String(rm.shipped), sub: "of " + rm.items.length + " features" }),
10200
- /* @__PURE__ */ jsx78(StatTile, { compact: true, label: "Remaining", value: String(rm.remaining), sub: "backend work" }),
10201
- /* @__PURE__ */ jsx78(StatTile, { compact: true, label: "Est. effort", value: days ? days + " days" : "\u2014", sub: "sum of estimates, not calendar" }),
10202
- /* @__PURE__ */ jsx78(StatTile, { compact: true, label: "Up next", value: nextPhase ? "Phase " + nextPhase.phase : "\u2014", sub: nextPhase ? nextPhase.phaseName : "all wired" })
10450
+ /* @__PURE__ */ jsxs70("div", { className: "fd-grid-stats is-thin", children: [
10451
+ /* @__PURE__ */ jsx79(StatTile, { compact: true, label: "Wired", value: String(rm.shipped), sub: "of " + rm.items.length + " features" }),
10452
+ /* @__PURE__ */ jsx79(StatTile, { compact: true, label: "Remaining", value: String(rm.remaining), sub: "backend work" }),
10453
+ /* @__PURE__ */ jsx79(StatTile, { compact: true, label: "Est. effort", value: days ? days + " days" : "\u2014", sub: "sum of estimates, not calendar" }),
10454
+ /* @__PURE__ */ jsx79(StatTile, { compact: true, label: "Up next", value: nextPhase ? "Phase " + nextPhase.phase : "\u2014", sub: nextPhase ? nextPhase.phaseName : "all wired" })
10203
10455
  ] }),
10204
- /* @__PURE__ */ jsxs69("div", { className: "fd-row", style: { gap: 10, flexWrap: "wrap" }, children: [
10205
- /* @__PURE__ */ jsx78(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 } }),
10206
- /* @__PURE__ */ jsx78(Select, { placeholder: "All projects", value: project, onChange: (e) => setProject(e.target.value), options: projects, style: { width: 190 } }),
10207
- /* @__PURE__ */ jsx78("span", { style: { flex: 1 } }),
10208
- /* @__PURE__ */ jsx78(
10456
+ /* @__PURE__ */ jsxs70("div", { className: "fd-row", style: { gap: 10, flexWrap: "wrap" }, children: [
10457
+ /* @__PURE__ */ jsx79(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 } }),
10458
+ /* @__PURE__ */ jsx79(Select, { placeholder: "All projects", value: project, onChange: (e) => setProject(e.target.value), options: projects, style: { width: 190 } }),
10459
+ /* @__PURE__ */ jsx79("span", { style: { flex: 1 } }),
10460
+ /* @__PURE__ */ jsx79(
10209
10461
  Button,
10210
10462
  {
10211
10463
  size: "sm",
@@ -10219,7 +10471,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
10219
10471
  }
10220
10472
  )
10221
10473
  ] }),
10222
- /* @__PURE__ */ jsx78(
10474
+ /* @__PURE__ */ jsx79(
10223
10475
  Flag,
10224
10476
  {
10225
10477
  tone: "info",
@@ -10228,60 +10480,60 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
10228
10480
  actions: null
10229
10481
  }
10230
10482
  ),
10231
- /* @__PURE__ */ jsx78("div", { className: "fd-rm", children: /* @__PURE__ */ jsx78("div", { className: "fd-rm-scroll", ref: scrollRef, children: /* @__PURE__ */ jsxs69("div", { className: "fd-rm-track", children: [
10232
- /* @__PURE__ */ jsx78("span", { className: "fd-rm-spine", children: /* @__PURE__ */ jsx78("span", { className: "fd-rm-spine-done", style: { height: items.length ? 100 * shippedShown / items.length + "%" : "0%" } }) }),
10483
+ /* @__PURE__ */ jsx79("div", { className: "fd-rm", children: /* @__PURE__ */ jsx79("div", { className: "fd-rm-scroll", ref: scrollRef, children: /* @__PURE__ */ jsxs70("div", { className: "fd-rm-track", children: [
10484
+ /* @__PURE__ */ jsx79("span", { className: "fd-rm-spine", children: /* @__PURE__ */ jsx79("span", { className: "fd-rm-spine-done", style: { height: items.length ? 100 * shippedShown / items.length + "%" : "0%" } }) }),
10233
10485
  items.map((item, n) => {
10234
10486
  const showPhase = item.phase !== lastPhase;
10235
10487
  lastPhase = item.phase;
10236
10488
  const inPhase = items.filter((i) => i.phase === item.phase).length;
10237
10489
  const isBoundary = n === firstPending;
10238
- return /* @__PURE__ */ jsxs69(React53.Fragment, { children: [
10239
- showPhase ? /* @__PURE__ */ jsxs69("div", { className: "fd-rm-era", children: [
10240
- /* @__PURE__ */ jsxs69("span", { className: "fd-row", style: { gap: 8, flexWrap: "wrap", alignItems: "baseline" }, children: [
10241
- /* @__PURE__ */ jsx78("span", { style: { fontWeight: 700 }, children: item.phase === 0 ? "Shipped" : "Phase " + item.phase + " \u2014 " + item.phaseName }),
10242
- item.phase === 0 ? null : /* @__PURE__ */ jsxs69("span", { className: "fd-mono", style: { opacity: 0.7, fontWeight: 400 }, children: [
10490
+ return /* @__PURE__ */ jsxs70(React54.Fragment, { children: [
10491
+ showPhase ? /* @__PURE__ */ jsxs70("div", { className: "fd-rm-era", children: [
10492
+ /* @__PURE__ */ jsxs70("span", { className: "fd-row", style: { gap: 8, flexWrap: "wrap", alignItems: "baseline" }, children: [
10493
+ /* @__PURE__ */ jsx79("span", { style: { fontWeight: 700 }, children: item.phase === 0 ? "Shipped" : "Phase " + item.phase + " \u2014 " + item.phaseName }),
10494
+ item.phase === 0 ? null : /* @__PURE__ */ jsxs70("span", { className: "fd-mono", style: { opacity: 0.7, fontWeight: 400 }, children: [
10243
10495
  fmtDate(item.phaseStart),
10244
10496
  " \u2013 ",
10245
10497
  fmtDate(item.date)
10246
10498
  ] }),
10247
- /* @__PURE__ */ jsxs69("span", { style: { opacity: 0.7, fontWeight: 400 }, children: [
10499
+ /* @__PURE__ */ jsxs70("span", { style: { opacity: 0.7, fontWeight: 400 }, children: [
10248
10500
  "\xB7 ",
10249
10501
  inPhase,
10250
10502
  " feature",
10251
10503
  inPhase === 1 ? "" : "s"
10252
10504
  ] })
10253
10505
  ] }),
10254
- item.phaseWhy ? /* @__PURE__ */ jsx78("p", { className: "fd-rm-era-why", children: item.phaseWhy }) : null
10506
+ item.phaseWhy ? /* @__PURE__ */ jsx79("p", { className: "fd-rm-era-why", children: item.phaseWhy }) : null
10255
10507
  ] }) : null,
10256
- isBoundary ? /* @__PURE__ */ jsx78("div", { className: "fd-rm-now", ref: nowRef, children: /* @__PURE__ */ jsxs69("span", { className: "fd-rm-now-pill", children: [
10257
- /* @__PURE__ */ jsx78("i", { className: "ph ph-map-pin" }),
10508
+ isBoundary ? /* @__PURE__ */ jsx79("div", { className: "fd-rm-now", ref: nowRef, children: /* @__PURE__ */ jsxs70("span", { className: "fd-rm-now-pill", children: [
10509
+ /* @__PURE__ */ jsx79("i", { className: "ph ph-map-pin" }),
10258
10510
  " You are here \u2014 everything above is wired"
10259
10511
  ] }) }) : null,
10260
- /* @__PURE__ */ jsxs69("div", { className: "fd-rm-row", children: [
10261
- /* @__PURE__ */ jsx78("span", { className: "fd-rm-dot " + (item.implemented ? "is-shipped" : item.status === "next" ? "is-next" : "") }),
10262
- /* @__PURE__ */ jsxs69("div", { className: "fd-rm-date", children: [
10512
+ /* @__PURE__ */ jsxs70("div", { className: "fd-rm-row", children: [
10513
+ /* @__PURE__ */ jsx79("span", { className: "fd-rm-dot " + (item.implemented ? "is-shipped" : item.status === "next" ? "is-next" : "") }),
10514
+ /* @__PURE__ */ jsxs70("div", { className: "fd-rm-date", children: [
10263
10515
  fmtDate(item.date),
10264
- /* @__PURE__ */ jsx78("br", {}),
10265
- /* @__PURE__ */ jsx78("span", { style: { opacity: 0.75 }, children: item.implemented ? "shipped" : "phase " + item.phase })
10516
+ /* @__PURE__ */ jsx79("br", {}),
10517
+ /* @__PURE__ */ jsx79("span", { style: { opacity: 0.75 }, children: item.implemented ? "shipped" : "phase " + item.phase })
10266
10518
  ] }),
10267
- /* @__PURE__ */ jsx78(RoadmapCard, { item, byKey, onOpenFlag })
10519
+ /* @__PURE__ */ jsx79(RoadmapCard, { item, byKey, onOpenFlag })
10268
10520
  ] })
10269
10521
  ] }, item.key);
10270
10522
  }),
10271
- !items.length ? /* @__PURE__ */ jsx78("p", { className: "fd-body-sm fd-muted", children: "Nothing matches that filter." }) : null
10523
+ !items.length ? /* @__PURE__ */ jsx79("p", { className: "fd-body-sm fd-muted", children: "Nothing matches that filter." }) : null
10272
10524
  ] }) }) }),
10273
- /* @__PURE__ */ jsxs69("p", { className: "fd-body-sm fd-muted", style: { margin: 0 }, children: [
10525
+ /* @__PURE__ */ jsxs70("p", { className: "fd-body-sm fd-muted", style: { margin: 0 }, children: [
10274
10526
  "Derived from the feature-flag registry \u2014 each entry's status is its flag's ",
10275
- /* @__PURE__ */ jsx78("code", { className: "fd-mono", children: "implemented" }),
10527
+ /* @__PURE__ */ jsx79("code", { className: "fd-mono", children: "implemented" }),
10276
10528
  " field, so this page cannot drift from what the apps actually do."
10277
10529
  ] })
10278
10530
  ] });
10279
10531
  }
10280
10532
 
10281
10533
  // src/components/platform/ComingSoon.tsx
10282
- import * as React54 from "react";
10534
+ import * as React55 from "react";
10283
10535
  import { createPortal as createPortal5 } from "react-dom";
10284
- import { Fragment as Fragment20, jsx as jsx79, jsxs as jsxs70 } from "react/jsx-runtime";
10536
+ import { Fragment as Fragment21, jsx as jsx80, jsxs as jsxs71 } from "react/jsx-runtime";
10285
10537
  var BYPASS_STORE = "fd.soon.bypass.v1";
10286
10538
  function readBypassed() {
10287
10539
  try {
@@ -10297,8 +10549,8 @@ function writeBypassed(list) {
10297
10549
  }
10298
10550
  }
10299
10551
  function useBypass(key) {
10300
- const [on, setOn] = React54.useState(() => !!key && readBypassed().indexOf(key) >= 0);
10301
- React54.useEffect(() => {
10552
+ const [on, setOn] = React55.useState(() => !!key && readBypassed().indexOf(key) >= 0);
10553
+ React55.useEffect(() => {
10302
10554
  setOn(!!key && readBypassed().indexOf(key) >= 0);
10303
10555
  }, [key]);
10304
10556
  const set = (next) => {
@@ -10311,43 +10563,43 @@ function useBypass(key) {
10311
10563
  return [on, set];
10312
10564
  }
10313
10565
  function SoonCard({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass }) {
10314
- return /* @__PURE__ */ jsxs70(Fragment20, { children: [
10315
- /* @__PURE__ */ jsxs70("span", { className: "fd-soon-badge", children: [
10316
- /* @__PURE__ */ jsx79("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" }),
10566
+ return /* @__PURE__ */ jsxs71(Fragment21, { children: [
10567
+ /* @__PURE__ */ jsxs71("span", { className: "fd-soon-badge", children: [
10568
+ /* @__PURE__ */ jsx80("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" }),
10317
10569
  label
10318
10570
  ] }),
10319
- detail ? /* @__PURE__ */ jsx79("span", { className: "fd-soon-detail", children: detail }) : null,
10320
- backend ? /* @__PURE__ */ jsxs70("span", { className: "fd-soon-backend", children: [
10321
- /* @__PURE__ */ jsx79("span", { className: "fd-overline", children: "Needs" }),
10571
+ detail ? /* @__PURE__ */ jsx80("span", { className: "fd-soon-detail", children: detail }) : null,
10572
+ backend ? /* @__PURE__ */ jsxs71("span", { className: "fd-soon-backend", children: [
10573
+ /* @__PURE__ */ jsx80("span", { className: "fd-overline", children: "Needs" }),
10322
10574
  " ",
10323
10575
  backend
10324
10576
  ] }) : null,
10325
- eta || effort || onRoadmap ? /* @__PURE__ */ jsxs70("span", { className: "fd-soon-meta", children: [
10326
- eta ? /* @__PURE__ */ jsxs70("span", { children: [
10327
- /* @__PURE__ */ jsx79("i", { className: "ph ph-calendar-blank", "aria-hidden": "true" }),
10577
+ eta || effort || onRoadmap ? /* @__PURE__ */ jsxs71("span", { className: "fd-soon-meta", children: [
10578
+ eta ? /* @__PURE__ */ jsxs71("span", { children: [
10579
+ /* @__PURE__ */ jsx80("i", { className: "ph ph-calendar-blank", "aria-hidden": "true" }),
10328
10580
  " ",
10329
10581
  eta
10330
10582
  ] }) : null,
10331
- effort ? /* @__PURE__ */ jsxs70("span", { children: [
10332
- /* @__PURE__ */ jsx79("i", { className: "ph ph-hourglass-medium", "aria-hidden": "true" }),
10583
+ effort ? /* @__PURE__ */ jsxs71("span", { children: [
10584
+ /* @__PURE__ */ jsx80("i", { className: "ph ph-hourglass-medium", "aria-hidden": "true" }),
10333
10585
  " ",
10334
10586
  effort
10335
10587
  ] }) : null,
10336
- onRoadmap ? /* @__PURE__ */ jsxs70("button", { type: "button", className: "fd-soon-link", onClick: onRoadmap, children: [
10588
+ onRoadmap ? /* @__PURE__ */ jsxs71("button", { type: "button", className: "fd-soon-link", onClick: onRoadmap, children: [
10337
10589
  "See the roadmap ",
10338
- /* @__PURE__ */ jsx79("i", { className: "ph ph-arrow-right", "aria-hidden": "true" })
10590
+ /* @__PURE__ */ jsx80("i", { className: "ph ph-arrow-right", "aria-hidden": "true" })
10339
10591
  ] }) : null
10340
10592
  ] }) : null,
10341
- allowed ? /* @__PURE__ */ jsxs70("button", { type: "button", className: "fd-soon-view", onClick: onBypass, children: [
10342
- /* @__PURE__ */ jsx79("i", { className: "ph ph-eye", "aria-hidden": "true" }),
10593
+ allowed ? /* @__PURE__ */ jsxs71("button", { type: "button", className: "fd-soon-view", onClick: onBypass, children: [
10594
+ /* @__PURE__ */ jsx80("i", { className: "ph ph-eye", "aria-hidden": "true" }),
10343
10595
  " View and use it anyway"
10344
10596
  ] }) : null
10345
10597
  ] });
10346
10598
  }
10347
10599
  function useHoverCard(open2) {
10348
- const anchor = React54.useRef(null);
10349
- const [pos, setPos] = React54.useState(null);
10350
- React54.useLayoutEffect(() => {
10600
+ const anchor = React55.useRef(null);
10601
+ const [pos, setPos] = React55.useState(null);
10602
+ React55.useLayoutEffect(() => {
10351
10603
  if (!open2 || !anchor.current) {
10352
10604
  setPos(null);
10353
10605
  return;
@@ -10399,9 +10651,9 @@ function ComingSoon({
10399
10651
  const tip = [label, detail, backend ? "Needs " + backend : null, eta ? "ETA " + eta : null, effort].filter(Boolean).join(" \xB7 ");
10400
10652
  if (inline) {
10401
10653
  if (allowed && bypassed) {
10402
- return /* @__PURE__ */ jsxs70("span", { className: ["fd-soon-inline-on", className].filter(Boolean).join(" "), ...rest, children: [
10654
+ return /* @__PURE__ */ jsxs71("span", { className: ["fd-soon-inline-on", className].filter(Boolean).join(" "), ...rest, children: [
10403
10655
  children,
10404
- /* @__PURE__ */ jsx79(
10656
+ /* @__PURE__ */ jsx80(
10405
10657
  "button",
10406
10658
  {
10407
10659
  type: "button",
@@ -10409,12 +10661,12 @@ function ComingSoon({
10409
10661
  title: "Unwired \u2014 writes go to the simulated backend. " + tip + " Click to re-blur.",
10410
10662
  onClick: () => setBypassed(false),
10411
10663
  "aria-label": "Re-blur this unwired feature",
10412
- children: /* @__PURE__ */ jsx79("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" })
10664
+ children: /* @__PURE__ */ jsx80("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" })
10413
10665
  }
10414
10666
  )
10415
10667
  ] });
10416
10668
  }
10417
- return /* @__PURE__ */ jsx79(
10669
+ return /* @__PURE__ */ jsx80(
10418
10670
  InlineSoon,
10419
10671
  {
10420
10672
  label,
@@ -10434,20 +10686,20 @@ function ComingSoon({
10434
10686
  );
10435
10687
  }
10436
10688
  if (allowed && bypassed) {
10437
- return /* @__PURE__ */ jsxs70("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 14 }, ...rest, children: [
10438
- /* @__PURE__ */ jsxs70("div", { className: "fd-soon-bar", role: "status", children: [
10439
- /* @__PURE__ */ jsxs70("span", { className: "fd-soon-badge", children: [
10440
- /* @__PURE__ */ jsx79("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" }),
10689
+ return /* @__PURE__ */ jsxs71("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 14 }, ...rest, children: [
10690
+ /* @__PURE__ */ jsxs71("div", { className: "fd-soon-bar", role: "status", children: [
10691
+ /* @__PURE__ */ jsxs71("span", { className: "fd-soon-badge", children: [
10692
+ /* @__PURE__ */ jsx80("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" }),
10441
10693
  "Unwired feature \u2014 you are using it anyway"
10442
10694
  ] }),
10443
- /* @__PURE__ */ jsx79("span", { className: "fd-soon-bar-detail", children: "Every action here writes to the simulated backend, so nothing you do persists beyond this session." }),
10444
- /* @__PURE__ */ jsxs70("span", { className: "fd-soon-bar-actions", children: [
10445
- onRoadmap ? /* @__PURE__ */ jsxs70("button", { type: "button", className: "fd-soon-link", onClick: onRoadmap, children: [
10695
+ /* @__PURE__ */ jsx80("span", { className: "fd-soon-bar-detail", children: "Every action here writes to the simulated backend, so nothing you do persists beyond this session." }),
10696
+ /* @__PURE__ */ jsxs71("span", { className: "fd-soon-bar-actions", children: [
10697
+ onRoadmap ? /* @__PURE__ */ jsxs71("button", { type: "button", className: "fd-soon-link", onClick: onRoadmap, children: [
10446
10698
  "Roadmap ",
10447
- /* @__PURE__ */ jsx79("i", { className: "ph ph-arrow-right", "aria-hidden": "true" })
10699
+ /* @__PURE__ */ jsx80("i", { className: "ph ph-arrow-right", "aria-hidden": "true" })
10448
10700
  ] }) : null,
10449
- /* @__PURE__ */ jsxs70("button", { type: "button", className: "fd-soon-link", onClick: () => setBypassed(false), children: [
10450
- /* @__PURE__ */ jsx79("i", { className: "ph ph-eye-slash", "aria-hidden": "true" }),
10701
+ /* @__PURE__ */ jsxs71("button", { type: "button", className: "fd-soon-link", onClick: () => setBypassed(false), children: [
10702
+ /* @__PURE__ */ jsx80("i", { className: "ph ph-eye-slash", "aria-hidden": "true" }),
10451
10703
  " Re-blur"
10452
10704
  ] })
10453
10705
  ] })
@@ -10455,10 +10707,10 @@ function ComingSoon({
10455
10707
  children
10456
10708
  ] });
10457
10709
  }
10458
- return /* @__PURE__ */ jsxs70("div", { className: ["fd-soon", className].filter(Boolean).join(" "), style: minHeight ? { minHeight } : void 0, ...rest, children: [
10459
- /* @__PURE__ */ jsx79("div", { className: "fd-soon-under", style: { filter: "blur(" + blur + "px) saturate(.62)" }, ...{ inert: "" }, "aria-hidden": "true", children }),
10460
- /* @__PURE__ */ jsx79("div", { className: "fd-soon-veil" }),
10461
- /* @__PURE__ */ jsx79("div", { className: "fd-soon-note", role: "note", children: /* @__PURE__ */ jsx79(
10710
+ return /* @__PURE__ */ jsxs71("div", { className: ["fd-soon", className].filter(Boolean).join(" "), style: minHeight ? { minHeight } : void 0, ...rest, children: [
10711
+ /* @__PURE__ */ jsx80("div", { className: "fd-soon-under", style: { filter: "blur(" + blur + "px) saturate(.62)" }, ...{ inert: "" }, "aria-hidden": "true", children }),
10712
+ /* @__PURE__ */ jsx80("div", { className: "fd-soon-veil" }),
10713
+ /* @__PURE__ */ jsx80("div", { className: "fd-soon-note", role: "note", children: /* @__PURE__ */ jsx80(
10462
10714
  SoonCard,
10463
10715
  {
10464
10716
  label,
@@ -10474,10 +10726,10 @@ function ComingSoon({
10474
10726
  ] });
10475
10727
  }
10476
10728
  function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass, blur, tip, className, rest, children }) {
10477
- const [open2, setOpen] = React54.useState(false);
10729
+ const [open2, setOpen] = React55.useState(false);
10478
10730
  const [anchor, pos] = useHoverCard(open2);
10479
10731
  const zIndex = useOverlayLayer(open2);
10480
- const close2 = React54.useRef(null);
10732
+ const close2 = React55.useRef(null);
10481
10733
  const show = () => {
10482
10734
  if (close2.current) {
10483
10735
  clearTimeout(close2.current);
@@ -10493,10 +10745,10 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
10493
10745
  setOpen(false);
10494
10746
  }, 140);
10495
10747
  };
10496
- React54.useEffect(() => () => {
10748
+ React55.useEffect(() => () => {
10497
10749
  if (close2.current) clearTimeout(close2.current);
10498
10750
  }, []);
10499
- return /* @__PURE__ */ jsxs70(
10751
+ return /* @__PURE__ */ jsxs71(
10500
10752
  "span",
10501
10753
  {
10502
10754
  ref: anchor,
@@ -10507,8 +10759,8 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
10507
10759
  onBlur: hide,
10508
10760
  ...rest,
10509
10761
  children: [
10510
- /* @__PURE__ */ jsx79("span", { className: "fd-soon-under", style: { filter: "blur(" + Math.min(blur, 1.1) + "px) saturate(.66)" }, ...{ inert: "" }, "aria-hidden": "true", children }),
10511
- /* @__PURE__ */ jsx79(
10762
+ /* @__PURE__ */ jsx80("span", { className: "fd-soon-under", style: { filter: "blur(" + Math.min(blur, 1.1) + "px) saturate(.66)" }, ...{ inert: "" }, "aria-hidden": "true", children }),
10763
+ /* @__PURE__ */ jsx80(
10512
10764
  "button",
10513
10765
  {
10514
10766
  type: "button",
@@ -10519,11 +10771,11 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
10519
10771
  onFocus: show,
10520
10772
  onBlur: hide,
10521
10773
  onClick: () => open2 ? setOpen(false) : show(),
10522
- children: /* @__PURE__ */ jsx79("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" })
10774
+ children: /* @__PURE__ */ jsx80("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" })
10523
10775
  }
10524
10776
  ),
10525
10777
  open2 && pos ? createPortal5(
10526
- /* @__PURE__ */ jsx79(LayerProvider, { zIndex, children: /* @__PURE__ */ jsx79(
10778
+ /* @__PURE__ */ jsx80(LayerProvider, { zIndex, children: /* @__PURE__ */ jsx80(
10527
10779
  "div",
10528
10780
  {
10529
10781
  className: "fd-soon-note fd-soon-hovercard",
@@ -10531,7 +10783,7 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
10531
10783
  style: { position: "fixed", left: pos.left, top: pos.top, bottom: pos.bottom, width: pos.width, zIndex },
10532
10784
  onMouseEnter: show,
10533
10785
  onMouseLeave: hide,
10534
- children: /* @__PURE__ */ jsx79(
10786
+ children: /* @__PURE__ */ jsx80(
10535
10787
  SoonCard,
10536
10788
  {
10537
10789
  label,
@@ -10561,10 +10813,10 @@ function formatEta(iso2) {
10561
10813
  var FormatEta = formatEta;
10562
10814
 
10563
10815
  // src/components/platform/Gate.tsx
10564
- import { jsx as jsx80, jsxs as jsxs71 } from "react/jsx-runtime";
10816
+ import { jsx as jsx81, jsxs as jsxs72 } from "react/jsx-runtime";
10565
10817
  function PermissionDenied({ permission, title, detail, compact: compact3 = false, className = "", ...rest }) {
10566
10818
  const need = Array.isArray(permission) ? permission : [permission].filter(Boolean);
10567
- return /* @__PURE__ */ jsxs71(
10819
+ return /* @__PURE__ */ jsxs72(
10568
10820
  "div",
10569
10821
  {
10570
10822
  className: ["fd-stack", className].filter(Boolean).join(" "),
@@ -10580,14 +10832,14 @@ function PermissionDenied({ permission, title, detail, compact: compact3 = false
10580
10832
  },
10581
10833
  ...rest,
10582
10834
  children: [
10583
- /* @__PURE__ */ jsxs71("span", { className: "fd-row", style: { gap: 8 }, children: [
10584
- /* @__PURE__ */ jsx80("i", { className: "ph ph-lock-simple", style: { fontSize: 16, color: "var(--text-muted)" }, "aria-hidden": "true" }),
10585
- /* @__PURE__ */ jsx80("span", { className: compact3 ? "fd-label-lg" : "fd-h3", children: title || "You do not have access to this" })
10835
+ /* @__PURE__ */ jsxs72("span", { className: "fd-row", style: { gap: 8 }, children: [
10836
+ /* @__PURE__ */ jsx81("i", { className: "ph ph-lock-simple", style: { fontSize: 16, color: "var(--text-muted)" }, "aria-hidden": "true" }),
10837
+ /* @__PURE__ */ jsx81("span", { className: compact3 ? "fd-label-lg" : "fd-h3", children: title || "You do not have access to this" })
10586
10838
  ] }),
10587
- /* @__PURE__ */ jsx80("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." }),
10588
- need.length ? /* @__PURE__ */ jsxs71("span", { className: "fd-row", style: { gap: 6, flexWrap: "wrap" }, children: [
10589
- /* @__PURE__ */ jsx80("span", { className: "fd-overline fd-muted", children: "Requires" }),
10590
- need.map((p) => /* @__PURE__ */ jsx80("code", { className: "fd-mono", style: {
10839
+ /* @__PURE__ */ jsx81("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." }),
10840
+ need.length ? /* @__PURE__ */ jsxs72("span", { className: "fd-row", style: { gap: 6, flexWrap: "wrap" }, children: [
10841
+ /* @__PURE__ */ jsx81("span", { className: "fd-overline fd-muted", children: "Requires" }),
10842
+ need.map((p) => /* @__PURE__ */ jsx81("code", { className: "fd-mono", style: {
10591
10843
  fontSize: 11.5,
10592
10844
  padding: "2px 7px",
10593
10845
  borderRadius: 5,
@@ -10600,7 +10852,7 @@ function PermissionDenied({ permission, title, detail, compact: compact3 = false
10600
10852
  );
10601
10853
  }
10602
10854
  function GatePending({ compact: compact3 = false, className = "" }) {
10603
- return /* @__PURE__ */ jsxs71(
10855
+ return /* @__PURE__ */ jsxs72(
10604
10856
  "div",
10605
10857
  {
10606
10858
  className: ["fd-stack", className].filter(Boolean).join(" "),
@@ -10616,11 +10868,11 @@ function GatePending({ compact: compact3 = false, className = "" }) {
10616
10868
  textAlign: "left"
10617
10869
  },
10618
10870
  children: [
10619
- /* @__PURE__ */ jsxs71("span", { className: "fd-row", style: { gap: 8 }, children: [
10620
- /* @__PURE__ */ jsx80("i", { className: "ph ph-arrows-clockwise", style: { fontSize: 16, color: "var(--text-muted)" }, "aria-hidden": "true" }),
10621
- /* @__PURE__ */ jsx80("span", { className: compact3 ? "fd-label-lg" : "fd-h3", children: "Reconnecting\u2026" })
10871
+ /* @__PURE__ */ jsxs72("span", { className: "fd-row", style: { gap: 8 }, children: [
10872
+ /* @__PURE__ */ jsx81("i", { className: "ph ph-arrows-clockwise", style: { fontSize: 16, color: "var(--text-muted)" }, "aria-hidden": "true" }),
10873
+ /* @__PURE__ */ jsx81("span", { className: compact3 ? "fd-label-lg" : "fd-h3", children: "Reconnecting\u2026" })
10622
10874
  ] }),
10623
- /* @__PURE__ */ jsx80("p", { className: "fd-body-sm fd-secondary", style: { margin: 0, textWrap: "pretty" }, children: "Your access can't be verified right now. This will resolve on its own once the connection is back." })
10875
+ /* @__PURE__ */ jsx81("p", { className: "fd-body-sm fd-secondary", style: { margin: 0, textWrap: "pretty" }, children: "Your access can't be verified right now. This will resolve on its own once the connection is back." })
10624
10876
  ]
10625
10877
  }
10626
10878
  );
@@ -10630,7 +10882,7 @@ function Gate({ perm, anyOf, role, silent = false, fallback, pendingFallback, co
10630
10882
  if (pending) {
10631
10883
  if (pendingFallback !== void 0) return pendingFallback;
10632
10884
  if (silent) return null;
10633
- return /* @__PURE__ */ jsx80(GatePending, { compact: compact3 });
10885
+ return /* @__PURE__ */ jsx81(GatePending, { compact: compact3 });
10634
10886
  }
10635
10887
  let ok = true;
10636
10888
  if (perm) ok = ok && can2(perm);
@@ -10639,7 +10891,7 @@ function Gate({ perm, anyOf, role, silent = false, fallback, pendingFallback, co
10639
10891
  if (ok) return children;
10640
10892
  if (fallback !== void 0) return fallback;
10641
10893
  if (silent) return null;
10642
- return /* @__PURE__ */ jsx80(PermissionDenied, { permission: perm || anyOf, compact: compact3 });
10894
+ return /* @__PURE__ */ jsx81(PermissionDenied, { permission: perm || anyOf, compact: compact3 });
10643
10895
  }
10644
10896
  function FeatureGate({
10645
10897
  flag,
@@ -10662,7 +10914,7 @@ function FeatureGate({
10662
10914
  const f = SessionKit.findFlag(flag) || {};
10663
10915
  const missing = rt.missing || [];
10664
10916
  const canBypass = pending ? false : bypassPerm === null ? false : !bypassPerm || can2(bypassPerm);
10665
- return /* @__PURE__ */ jsx80(
10917
+ return /* @__PURE__ */ jsx81(
10666
10918
  ComingSoon,
10667
10919
  {
10668
10920
  label: label || (variant === "inline" ? f.label || "Not wired yet" : "Designed \u2014 backend not wired yet"),
@@ -10683,22 +10935,22 @@ function FeatureGate({
10683
10935
  function PermissionHint({ perm, children }) {
10684
10936
  const { can: can2, pending } = useSessionContext();
10685
10937
  if (pending) {
10686
- return /* @__PURE__ */ jsx80("span", { title: "Access can't be verified right now", style: { display: "inline-flex", opacity: 0.45, cursor: "not-allowed" }, "aria-disabled": "true", children: /* @__PURE__ */ jsx80("span", { style: { pointerEvents: "none" }, children }) });
10938
+ return /* @__PURE__ */ jsx81("span", { title: "Access can't be verified right now", style: { display: "inline-flex", opacity: 0.45, cursor: "not-allowed" }, "aria-disabled": "true", children: /* @__PURE__ */ jsx81("span", { style: { pointerEvents: "none" }, children }) });
10687
10939
  }
10688
10940
  if (can2(perm)) return children;
10689
- return /* @__PURE__ */ jsx80(
10941
+ return /* @__PURE__ */ jsx81(
10690
10942
  "span",
10691
10943
  {
10692
10944
  title: "Requires " + (Array.isArray(perm) ? perm.join(", ") : perm),
10693
10945
  style: { display: "inline-flex", opacity: 0.45, cursor: "not-allowed" },
10694
10946
  "aria-disabled": "true",
10695
- children: /* @__PURE__ */ jsx80("span", { style: { pointerEvents: "none" }, children })
10947
+ children: /* @__PURE__ */ jsx81("span", { style: { pointerEvents: "none" }, children })
10696
10948
  }
10697
10949
  );
10698
10950
  }
10699
10951
 
10700
10952
  // src/components/platform/ModeSwitch.tsx
10701
- import { Fragment as Fragment21, jsx as jsx81, jsxs as jsxs72 } from "react/jsx-runtime";
10953
+ import { Fragment as Fragment22, jsx as jsx82, jsxs as jsxs73 } from "react/jsx-runtime";
10702
10954
  function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog, onOpenSpec, summary }) {
10703
10955
  const mode2 = useRuntimeMode();
10704
10956
  const panel = useInlinePanel();
@@ -10710,8 +10962,8 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
10710
10962
  RuntimeKit.setMode(next);
10711
10963
  setOpen(false);
10712
10964
  };
10713
- return /* @__PURE__ */ jsxs72("span", { style: { position: "relative", display: "inline-flex" }, ref, children: [
10714
- /* @__PURE__ */ jsxs72(
10965
+ return /* @__PURE__ */ jsxs73("span", { style: { position: "relative", display: "inline-flex" }, ref, children: [
10966
+ /* @__PURE__ */ jsxs73(
10715
10967
  "button",
10716
10968
  {
10717
10969
  type: "button",
@@ -10721,29 +10973,29 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
10721
10973
  title: test ? "Test mode \u2014 every response is simulated. Click to inspect requests or return to live mode." : "Live mode \u2014 incomplete features are shown under construction. Click for test mode.",
10722
10974
  className: "fd-mode-btn" + (test ? " is-test" : "") + (open2 ? " is-open" : ""),
10723
10975
  children: [
10724
- /* @__PURE__ */ jsx81("i", { className: "ph " + (test ? "ph-flask" : "ph-lightning"), style: { fontSize: 17 } }),
10725
- test && requestCount ? /* @__PURE__ */ jsx81("span", { className: "fd-mono fd-mode-count", children: requestCount > 99 ? "99+" : requestCount }, requestCount) : null
10976
+ /* @__PURE__ */ jsx82("i", { className: "ph " + (test ? "ph-flask" : "ph-lightning"), style: { fontSize: 17 } }),
10977
+ test && requestCount ? /* @__PURE__ */ jsx82("span", { className: "fd-mono fd-mode-count", children: requestCount > 99 ? "99+" : requestCount }, requestCount) : null
10726
10978
  ]
10727
10979
  }
10728
10980
  ),
10729
- open2 ? /* @__PURE__ */ jsx81(InlinePanelLayers, { panel, children: /* @__PURE__ */ jsxs72("span", { className: "fd-view-enter fd-mode-pop", style: { zIndex }, children: [
10730
- /* @__PURE__ */ jsxs72("span", { className: "fd-row", style: { gap: 10, padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
10731
- /* @__PURE__ */ jsxs72("span", { className: "fd-badge " + (test ? "fd-badge-warning" : "fd-badge-neutral"), children: [
10732
- /* @__PURE__ */ jsx81("i", { className: "ph " + (test ? "ph-flask" : "ph-lightning"), "aria-hidden": "true" }),
10981
+ open2 ? /* @__PURE__ */ jsx82(InlinePanelLayers, { panel, children: /* @__PURE__ */ jsxs73("span", { className: "fd-view-enter fd-mode-pop", style: { zIndex }, children: [
10982
+ /* @__PURE__ */ jsxs73("span", { className: "fd-row", style: { gap: 10, padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
10983
+ /* @__PURE__ */ jsxs73("span", { className: "fd-badge " + (test ? "fd-badge-warning" : "fd-badge-neutral"), children: [
10984
+ /* @__PURE__ */ jsx82("i", { className: "ph " + (test ? "ph-flask" : "ph-lightning"), "aria-hidden": "true" }),
10733
10985
  test ? "Test mode" : "Live mode"
10734
10986
  ] }),
10735
- test ? /* @__PURE__ */ jsxs72("span", { className: "fd-body-sm fd-muted fd-mono", children: [
10987
+ test ? /* @__PURE__ */ jsxs73("span", { className: "fd-body-sm fd-muted fd-mono", children: [
10736
10988
  requestCount,
10737
10989
  " simulated request",
10738
10990
  requestCount === 1 ? "" : "s"
10739
10991
  ] }) : null,
10740
- /* @__PURE__ */ jsx81("span", { style: { flex: 1 } }),
10741
- test && onClearLog ? /* @__PURE__ */ jsx81("button", { type: "button", className: "fd-soon-link", onClick: onClearLog, children: "Clear" }) : null
10992
+ /* @__PURE__ */ jsx82("span", { style: { flex: 1 } }),
10993
+ test && onClearLog ? /* @__PURE__ */ jsx82("button", { type: "button", className: "fd-soon-link", onClick: onClearLog, children: "Clear" }) : null
10742
10994
  ] }),
10743
- /* @__PURE__ */ jsxs72("span", { style: { display: "block", padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
10744
- /* @__PURE__ */ jsx81("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." }),
10745
- /* @__PURE__ */ jsxs72("span", { className: "fd-row", style: { gap: 8, marginTop: 10, flexWrap: "wrap" }, children: [
10746
- /* @__PURE__ */ jsxs72("span", { className: "fd-body-sm fd-muted fd-mono", children: [
10995
+ /* @__PURE__ */ jsxs73("span", { style: { display: "block", padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
10996
+ /* @__PURE__ */ jsx82("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." }),
10997
+ /* @__PURE__ */ jsxs73("span", { className: "fd-row", style: { gap: 8, marginTop: 10, flexWrap: "wrap" }, children: [
10998
+ /* @__PURE__ */ jsxs73("span", { className: "fd-body-sm fd-muted fd-mono", children: [
10747
10999
  s.endpointsWired,
10748
11000
  " endpoint",
10749
11001
  s.endpointsWired === 1 ? "" : "s",
@@ -10753,58 +11005,58 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
10753
11005
  s.total,
10754
11006
  " features complete"
10755
11007
  ] }),
10756
- onOpenSpec ? /* @__PURE__ */ jsxs72(Fragment21, { children: [
10757
- /* @__PURE__ */ jsx81("span", { style: { flex: 1 } }),
10758
- /* @__PURE__ */ jsxs72("button", { type: "button", className: "fd-soon-link", onClick: () => {
11008
+ onOpenSpec ? /* @__PURE__ */ jsxs73(Fragment22, { children: [
11009
+ /* @__PURE__ */ jsx82("span", { style: { flex: 1 } }),
11010
+ /* @__PURE__ */ jsxs73("button", { type: "button", className: "fd-soon-link", onClick: () => {
10759
11011
  setOpen(false);
10760
11012
  onOpenSpec();
10761
11013
  }, children: [
10762
11014
  "API spec ",
10763
- /* @__PURE__ */ jsx81("i", { className: "ph ph-arrow-right", "aria-hidden": "true" })
11015
+ /* @__PURE__ */ jsx82("i", { className: "ph ph-arrow-right", "aria-hidden": "true" })
10764
11016
  ] })
10765
11017
  ] }) : null
10766
11018
  ] })
10767
11019
  ] }),
10768
- /* @__PURE__ */ jsxs72("span", { className: "fd-mode-choice", children: [
10769
- /* @__PURE__ */ jsxs72("button", { type: "button", className: "fd-mode-opt" + (!test ? " is-on" : ""), onClick: () => go("live"), children: [
10770
- /* @__PURE__ */ jsx81("i", { className: "ph ph-lightning", "aria-hidden": "true" }),
10771
- /* @__PURE__ */ jsxs72("span", { className: "fd-mode-opt-text", children: [
10772
- /* @__PURE__ */ jsx81("span", { className: "fd-mode-opt-title", children: "Live mode" }),
10773
- /* @__PURE__ */ jsx81("span", { className: "fd-mode-opt-desc", children: "Incomplete features under construction" })
11020
+ /* @__PURE__ */ jsxs73("span", { className: "fd-mode-choice", children: [
11021
+ /* @__PURE__ */ jsxs73("button", { type: "button", className: "fd-mode-opt" + (!test ? " is-on" : ""), onClick: () => go("live"), children: [
11022
+ /* @__PURE__ */ jsx82("i", { className: "ph ph-lightning", "aria-hidden": "true" }),
11023
+ /* @__PURE__ */ jsxs73("span", { className: "fd-mode-opt-text", children: [
11024
+ /* @__PURE__ */ jsx82("span", { className: "fd-mode-opt-title", children: "Live mode" }),
11025
+ /* @__PURE__ */ jsx82("span", { className: "fd-mode-opt-desc", children: "Incomplete features under construction" })
10774
11026
  ] }),
10775
- !test ? /* @__PURE__ */ jsx81("i", { className: "ph ph-check", "aria-hidden": "true" }) : null
11027
+ !test ? /* @__PURE__ */ jsx82("i", { className: "ph ph-check", "aria-hidden": "true" }) : null
10776
11028
  ] }),
10777
- /* @__PURE__ */ jsxs72("button", { type: "button", className: "fd-mode-opt" + (test ? " is-on" : ""), onClick: () => go("test"), children: [
10778
- /* @__PURE__ */ jsx81("i", { className: "ph ph-flask", "aria-hidden": "true" }),
10779
- /* @__PURE__ */ jsxs72("span", { className: "fd-mode-opt-text", children: [
10780
- /* @__PURE__ */ jsx81("span", { className: "fd-mode-opt-title", children: "Test mode" }),
10781
- /* @__PURE__ */ jsx81("span", { className: "fd-mode-opt-desc", children: "Everything usable, all data simulated" })
11029
+ /* @__PURE__ */ jsxs73("button", { type: "button", className: "fd-mode-opt" + (test ? " is-on" : ""), onClick: () => go("test"), children: [
11030
+ /* @__PURE__ */ jsx82("i", { className: "ph ph-flask", "aria-hidden": "true" }),
11031
+ /* @__PURE__ */ jsxs73("span", { className: "fd-mode-opt-text", children: [
11032
+ /* @__PURE__ */ jsx82("span", { className: "fd-mode-opt-title", children: "Test mode" }),
11033
+ /* @__PURE__ */ jsx82("span", { className: "fd-mode-opt-desc", children: "Everything usable, all data simulated" })
10782
11034
  ] }),
10783
- test ? /* @__PURE__ */ jsx81("i", { className: "ph ph-check", "aria-hidden": "true" }) : null
11035
+ test ? /* @__PURE__ */ jsx82("i", { className: "ph ph-check", "aria-hidden": "true" }) : null
10784
11036
  ] })
10785
11037
  ] }),
10786
- test && renderLog ? /* @__PURE__ */ jsx81("span", { style: { display: "block", maxHeight: 340, overflowY: "auto", borderTop: "1px solid var(--border)" }, children: renderLog() }) : null
11038
+ test && renderLog ? /* @__PURE__ */ jsx82("span", { style: { display: "block", maxHeight: 340, overflowY: "auto", borderTop: "1px solid var(--border)" }, children: renderLog() }) : null
10787
11039
  ] }) }) : null
10788
11040
  ] });
10789
11041
  }
10790
11042
  function TestModeBar({ onExit }) {
10791
11043
  const mode2 = useRuntimeMode();
10792
11044
  if (mode2 !== "test") return null;
10793
- return /* @__PURE__ */ jsxs72("div", { className: "fd-testbar", role: "status", children: [
10794
- /* @__PURE__ */ jsxs72("span", { className: "fd-badge fd-badge-warning", children: [
10795
- /* @__PURE__ */ jsx81("i", { className: "ph ph-flask", "aria-hidden": "true" }),
11045
+ return /* @__PURE__ */ jsxs73("div", { className: "fd-testbar", role: "status", children: [
11046
+ /* @__PURE__ */ jsxs73("span", { className: "fd-badge fd-badge-warning", children: [
11047
+ /* @__PURE__ */ jsx82("i", { className: "ph ph-flask", "aria-hidden": "true" }),
10796
11048
  "Test mode"
10797
11049
  ] }),
10798
- /* @__PURE__ */ jsx81("span", { className: "fd-testbar-detail", children: "Every feature is unlocked and every response is simulated \u2014 nothing here persists." }),
10799
- /* @__PURE__ */ jsxs72("button", { type: "button", className: "fd-soon-link", onClick: () => onExit ? onExit() : RuntimeKit.setMode("live"), children: [
10800
- /* @__PURE__ */ jsx81("i", { className: "ph ph-lightning", "aria-hidden": "true" }),
11050
+ /* @__PURE__ */ jsx82("span", { className: "fd-testbar-detail", children: "Every feature is unlocked and every response is simulated \u2014 nothing here persists." }),
11051
+ /* @__PURE__ */ jsxs73("button", { type: "button", className: "fd-soon-link", onClick: () => onExit ? onExit() : RuntimeKit.setMode("live"), children: [
11052
+ /* @__PURE__ */ jsx82("i", { className: "ph ph-lightning", "aria-hidden": "true" }),
10801
11053
  " Back to live mode"
10802
11054
  ] })
10803
11055
  ] });
10804
11056
  }
10805
11057
 
10806
11058
  // src/components/planner/ChannelMeta.tsx
10807
- import { jsx as jsx82, jsxs as jsxs73 } from "react/jsx-runtime";
11059
+ import { jsx as jsx83, jsxs as jsxs74 } from "react/jsx-runtime";
10808
11060
  var CHANNEL_WEIGHTS = {
10809
11061
  "OOH": 50,
10810
11062
  "DOOH": 50,
@@ -10857,9 +11109,9 @@ function ChannelTag({ channel, size = "md", showLabel = true, dot = false, weigh
10857
11109
  const m = ChannelMeta(channel);
10858
11110
  const wt = channelWeightOf(channel || "");
10859
11111
  if (dot) {
10860
- return /* @__PURE__ */ jsx82("span", { className: ["fd-chan-dot", className].filter(Boolean).join(" "), title: m.name, style: { background: m.color }, ...rest });
11112
+ return /* @__PURE__ */ jsx83("span", { className: ["fd-chan-dot", className].filter(Boolean).join(" "), title: m.name, style: { background: m.color }, ...rest });
10861
11113
  }
10862
- return /* @__PURE__ */ jsxs73(
11114
+ return /* @__PURE__ */ jsxs74(
10863
11115
  "span",
10864
11116
  {
10865
11117
  className: ["fd-chan", size === "sm" ? "fd-chan-sm" : "", className].filter(Boolean).join(" "),
@@ -10867,16 +11119,16 @@ function ChannelTag({ channel, size = "md", showLabel = true, dot = false, weigh
10867
11119
  style: { "--chan": m.color },
10868
11120
  ...rest,
10869
11121
  children: [
10870
- /* @__PURE__ */ jsx82("i", { className: "ph ph-" + m.icon, "aria-hidden": "true" }),
10871
- showLabel ? /* @__PURE__ */ jsx82("span", { className: "fd-chan-label", children: m.label }) : null,
10872
- weight ? /* @__PURE__ */ jsx82("span", { className: "fd-chan-weight", children: wt || 0 }) : null
11122
+ /* @__PURE__ */ jsx83("i", { className: "ph ph-" + m.icon, "aria-hidden": "true" }),
11123
+ showLabel ? /* @__PURE__ */ jsx83("span", { className: "fd-chan-label", children: m.label }) : null,
11124
+ weight ? /* @__PURE__ */ jsx83("span", { className: "fd-chan-weight", children: wt || 0 }) : null
10873
11125
  ]
10874
11126
  }
10875
11127
  );
10876
11128
  }
10877
11129
 
10878
11130
  // src/components/planner/SaturationDistribution.tsx
10879
- import { jsx as jsx83, jsxs as jsxs74 } from "react/jsx-runtime";
11131
+ import { jsx as jsx84, jsxs as jsxs75 } from "react/jsx-runtime";
10880
11132
  var BANDS2 = [
10881
11133
  { key: "weak", label: "Weak", n: 1, range: "< 50" },
10882
11134
  { key: "adequate", label: "Adequate", n: 2, range: "50\u2013100" },
@@ -10887,24 +11139,24 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
10887
11139
  const grouped = BANDS2.map((b) => ({ ...b, items: campuses.filter((c) => c.band === b.key) }));
10888
11140
  const tallest = Math.max(1, ...grouped.map((g) => g.items.length));
10889
11141
  const floor = BANDS2.find((b) => b.key === floorBand) || BANDS2[0];
10890
- return /* @__PURE__ */ jsxs74("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 16 }, children: [
10891
- /* @__PURE__ */ jsx83("div", { style: { display: "grid", gridTemplateColumns: "repeat(4,minmax(0,1fr))", gap: 12, alignItems: "end" }, children: grouped.map((g) => {
11142
+ return /* @__PURE__ */ jsxs75("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 16 }, children: [
11143
+ /* @__PURE__ */ jsx84("div", { style: { display: "grid", gridTemplateColumns: "repeat(4,minmax(0,1fr))", gap: 12, alignItems: "end" }, children: grouped.map((g) => {
10892
11144
  const mark = "var(--csi-" + g.n + "-mark)";
10893
11145
  const active = selectedBand === g.key;
10894
- return /* @__PURE__ */ jsxs74(
11146
+ return /* @__PURE__ */ jsxs75(
10895
11147
  "button",
10896
11148
  {
10897
11149
  type: "button",
10898
11150
  onClick: onSelectBand ? () => onSelectBand(active ? null : g.key) : void 0,
10899
11151
  style: { display: "flex", flexDirection: "column", justifyContent: "flex-end", gap: 10, padding: 12, border: "1px solid " + (active ? "var(--border-strong)" : "var(--border)"), borderRadius: "var(--r-lg)", background: active ? "var(--surface-2)" : "var(--surface)", cursor: onSelectBand ? "pointer" : "default", textAlign: "left", minHeight: 190, minWidth: 0, transition: "background var(--dur-fast) var(--ease),border-color var(--dur-fast) var(--ease)" },
10900
11152
  children: [
10901
- /* @__PURE__ */ jsx83("span", { style: { display: "flex", flexDirection: "column-reverse", gap: 4, minHeight: tallest * 24, minWidth: 0 }, children: loading ? Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsx83("span", { className: "fd-skel", style: { height: 16, borderRadius: 4 } }, i)) : g.items.map((c) => (
11153
+ /* @__PURE__ */ jsx84("span", { style: { display: "flex", flexDirection: "column-reverse", gap: 4, minHeight: tallest * 24, minWidth: 0 }, children: loading ? Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsx84("span", { className: "fd-skel", style: { height: 16, borderRadius: 4 } }, i)) : g.items.map((c) => (
10902
11154
  // `overflow: hidden` + `white-space: nowrap` only clips once the span
10903
11155
  // actually HAS a bounded width to clip against (see the grid/flex
10904
11156
  // `minWidth: 0` chain above) — `textOverflow: ellipsis` then makes
10905
11157
  // that clip readable instead of a hard cut mid-letter; the full name
10906
11158
  // is still one hover away via `title`.
10907
- /* @__PURE__ */ jsx83(
11159
+ /* @__PURE__ */ jsx84(
10908
11160
  "span",
10909
11161
  {
10910
11162
  title: c.name + " \xB7 " + c.crp,
@@ -10914,13 +11166,13 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
10914
11166
  c.name
10915
11167
  )
10916
11168
  )) }),
10917
- /* @__PURE__ */ jsxs74("span", { className: "fd-row", style: { gap: 8, alignItems: "baseline" }, children: [
10918
- /* @__PURE__ */ jsx83("span", { className: "fd-num-hero", style: { fontSize: 30, color: g.items.length ? "var(--text)" : "var(--text-disabled)" }, children: loading ? "\u2013" : g.items.length }),
10919
- /* @__PURE__ */ jsx83("span", { className: "fd-meter", style: { gap: 2, color: mark }, "aria-hidden": "true", children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx83("span", { className: "fd-meter-seg" + (i <= g.n ? " is-on" : ""), style: { width: 4, height: 9 } }, i)) })
11169
+ /* @__PURE__ */ jsxs75("span", { className: "fd-row", style: { gap: 8, alignItems: "baseline" }, children: [
11170
+ /* @__PURE__ */ jsx84("span", { className: "fd-num-hero", style: { fontSize: 30, color: g.items.length ? "var(--text)" : "var(--text-disabled)" }, children: loading ? "\u2013" : g.items.length }),
11171
+ /* @__PURE__ */ jsx84("span", { className: "fd-meter", style: { gap: 2, color: mark }, "aria-hidden": "true", children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx84("span", { className: "fd-meter-seg" + (i <= g.n ? " is-on" : ""), style: { width: 4, height: 9 } }, i)) })
10920
11172
  ] }),
10921
- /* @__PURE__ */ jsxs74("span", { className: "fd-stack", style: { gap: 1 }, children: [
10922
- /* @__PURE__ */ jsx83("span", { className: "fd-label-lg", children: g.label }),
10923
- /* @__PURE__ */ jsxs74("span", { className: "fd-body-sm fd-muted", style: { fontSize: 11.5 }, children: [
11173
+ /* @__PURE__ */ jsxs75("span", { className: "fd-stack", style: { gap: 1 }, children: [
11174
+ /* @__PURE__ */ jsx84("span", { className: "fd-label-lg", children: g.label }),
11175
+ /* @__PURE__ */ jsxs75("span", { className: "fd-body-sm fd-muted", style: { fontSize: 11.5 }, children: [
10924
11176
  "CRP ",
10925
11177
  g.range
10926
11178
  ] })
@@ -10930,10 +11182,10 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
10930
11182
  g.key
10931
11183
  );
10932
11184
  }) }),
10933
- floorBand ? /* @__PURE__ */ jsxs74("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: [
10934
- /* @__PURE__ */ jsx83("span", { className: "fd-meter", style: { gap: 2, color: "var(--csi-" + floor.n + "-mark)" }, "aria-hidden": "true", children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx83("span", { className: "fd-meter-seg" + (i <= floor.n ? " is-on" : ""), style: { width: 5, height: 12 } }, i)) }),
10935
- /* @__PURE__ */ jsxs74("span", { className: "fd-body-sm fd-secondary", style: { flex: 1, minWidth: 240 }, children: [
10936
- /* @__PURE__ */ jsxs74("strong", { style: { color: "var(--text)" }, children: [
11185
+ floorBand ? /* @__PURE__ */ jsxs75("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: [
11186
+ /* @__PURE__ */ jsx84("span", { className: "fd-meter", style: { gap: 2, color: "var(--csi-" + floor.n + "-mark)" }, "aria-hidden": "true", children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx84("span", { className: "fd-meter-seg" + (i <= floor.n ? " is-on" : ""), style: { width: 5, height: 12 } }, i)) }),
11187
+ /* @__PURE__ */ jsxs75("span", { className: "fd-body-sm fd-secondary", style: { flex: 1, minWidth: 240 }, children: [
11188
+ /* @__PURE__ */ jsxs75("strong", { style: { color: "var(--text)" }, children: [
10937
11189
  "Plan floor ",
10938
11190
  floorScore
10939
11191
  ] }),
@@ -10944,8 +11196,8 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
10944
11196
  }
10945
11197
 
10946
11198
  // src/components/planner/MixGap.tsx
10947
- import * as React55 from "react";
10948
- import { Fragment as Fragment22, jsx as jsx84, jsxs as jsxs75 } from "react/jsx-runtime";
11199
+ import * as React56 from "react";
11200
+ import { Fragment as Fragment23, jsx as jsx85, jsxs as jsxs76 } from "react/jsx-runtime";
10949
11201
  var MIX_GAP_LAYOUT = {
10950
11202
  trackHeight: 30,
10951
11203
  barHeight: 20,
@@ -10959,19 +11211,19 @@ function mixGapOffset(value, max) {
10959
11211
  }
10960
11212
  function MixGap({ rows = [], loading = false, className = "" }) {
10961
11213
  const max = Math.max(1, ...rows.flatMap((r) => [r.target, r.realized]));
10962
- const [hover, setHover] = React55.useState(null);
11214
+ const [hover, setHover] = React56.useState(null);
10963
11215
  const toneOf = (gap) => gap >= -1 ? "ok" : gap >= -4 ? "warn" : "danger";
10964
11216
  const TONE = { ok: "var(--ok-solid)", warn: "var(--warn-solid)", danger: "var(--danger-solid)" };
10965
11217
  const { trackHeight, barHeight, targetWidth, labelGap } = MIX_GAP_LAYOUT;
10966
11218
  const barTop = (trackHeight - barHeight) / 2;
10967
- return /* @__PURE__ */ jsxs75("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 4 }, children: [
10968
- /* @__PURE__ */ jsxs75("div", { className: "fd-row", style: { gap: 16, justifyContent: "flex-end", paddingBottom: 6, flexWrap: "wrap" }, children: [
10969
- [["On target", TONE.ok], ["Close", TONE.warn], ["Short", TONE.danger]].map(([l, c]) => /* @__PURE__ */ jsxs75("span", { className: "fd-row fd-body-sm fd-muted", style: { gap: 6 }, children: [
10970
- /* @__PURE__ */ jsx84("span", { style: { width: 14, height: 9, borderRadius: 2, background: c } }),
11219
+ return /* @__PURE__ */ jsxs76("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 4 }, children: [
11220
+ /* @__PURE__ */ jsxs76("div", { className: "fd-row", style: { gap: 16, justifyContent: "flex-end", paddingBottom: 6, flexWrap: "wrap" }, children: [
11221
+ [["On target", TONE.ok], ["Close", TONE.warn], ["Short", TONE.danger]].map(([l, c]) => /* @__PURE__ */ jsxs76("span", { className: "fd-row fd-body-sm fd-muted", style: { gap: 6 }, children: [
11222
+ /* @__PURE__ */ jsx85("span", { style: { width: 14, height: 9, borderRadius: 2, background: c } }),
10971
11223
  l
10972
11224
  ] }, l)),
10973
- /* @__PURE__ */ jsxs75("span", { className: "fd-row fd-body-sm fd-muted", style: { gap: 6 }, children: [
10974
- /* @__PURE__ */ jsx84("span", { "data-mixgap-legend-target": "", style: { width: targetWidth, height: 16, borderRadius: 1, background: MIX_GAP_TARGET_STRIPE } }),
11225
+ /* @__PURE__ */ jsxs76("span", { className: "fd-row fd-body-sm fd-muted", style: { gap: 6 }, children: [
11226
+ /* @__PURE__ */ jsx85("span", { "data-mixgap-legend-target": "", style: { width: targetWidth, height: 16, borderRadius: 1, background: MIX_GAP_TARGET_STRIPE } }),
10975
11227
  "Target"
10976
11228
  ] })
10977
11229
  ] }),
@@ -10980,7 +11232,7 @@ function MixGap({ rows = [], loading = false, className = "" }) {
10980
11232
  const tone = toneOf(gap);
10981
11233
  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 : "");
10982
11234
  const labelLeft = r.realized > r.target ? `calc(${mixGapOffset(r.realized, max)} + ${labelGap}px)` : `calc(${mixGapOffset(r.target, max)} + ${targetWidth / 2 + labelGap}px)`;
10983
- return /* @__PURE__ */ jsxs75(
11235
+ return /* @__PURE__ */ jsxs76(
10984
11236
  "div",
10985
11237
  {
10986
11238
  className: "fd-row",
@@ -10988,15 +11240,15 @@ function MixGap({ rows = [], loading = false, className = "" }) {
10988
11240
  onMouseEnter: () => setHover(r.channel),
10989
11241
  onMouseLeave: () => setHover(null),
10990
11242
  children: [
10991
- /* @__PURE__ */ jsx84("span", { style: { width: 128, flex: "none" }, children: /* @__PURE__ */ jsx84(ChannelTag, { channel: r.channel, size: "sm" }) }),
10992
- /* @__PURE__ */ jsx84("span", { style: { position: "relative", flex: 1, height: trackHeight, minWidth: 120 }, children: loading ? /* @__PURE__ */ jsx84("span", { className: "fd-skel", style: { position: "absolute", left: 0, right: 0, top: barTop, height: barHeight, borderRadius: 3 } }) : /* @__PURE__ */ jsxs75(Fragment22, { children: [
10993
- /* @__PURE__ */ jsx84("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)" } }),
10994
- /* @__PURE__ */ jsx84("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 } }),
10995
- /* @__PURE__ */ jsxs75("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: [
11243
+ /* @__PURE__ */ jsx85("span", { style: { width: 128, flex: "none" }, children: /* @__PURE__ */ jsx85(ChannelTag, { channel: r.channel, size: "sm" }) }),
11244
+ /* @__PURE__ */ jsx85("span", { style: { position: "relative", flex: 1, height: trackHeight, minWidth: 120 }, children: loading ? /* @__PURE__ */ jsx85("span", { className: "fd-skel", style: { position: "absolute", left: 0, right: 0, top: barTop, height: barHeight, borderRadius: 3 } }) : /* @__PURE__ */ jsxs76(Fragment23, { children: [
11245
+ /* @__PURE__ */ jsx85("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)" } }),
11246
+ /* @__PURE__ */ jsx85("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 } }),
11247
+ /* @__PURE__ */ jsxs76("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: [
10996
11248
  r.realized,
10997
11249
  "%"
10998
11250
  ] }),
10999
- hover === r.channel ? /* @__PURE__ */ jsx84("span", { className: "fd-tooltip", role: "tooltip", style: { position: "absolute", left: 0, right: "auto", bottom: trackHeight + 4, maxWidth: "min(340px, 100%)", whiteSpace: "normal", textAlign: "left", width: "max-content" }, children: tip }) : null
11251
+ hover === r.channel ? /* @__PURE__ */ jsx85("span", { className: "fd-tooltip", role: "tooltip", style: { position: "absolute", left: 0, right: "auto", bottom: trackHeight + 4, maxWidth: "min(340px, 100%)", whiteSpace: "normal", textAlign: "left", width: "max-content" }, children: tip }) : null
11000
11252
  ] }) })
11001
11253
  ]
11002
11254
  },
@@ -11007,7 +11259,7 @@ function MixGap({ rows = [], loading = false, className = "" }) {
11007
11259
  }
11008
11260
 
11009
11261
  // src/components/planner/ChannelContribution.tsx
11010
- import { jsx as jsx85, jsxs as jsxs76 } from "react/jsx-runtime";
11262
+ import { jsx as jsx86, jsxs as jsxs77 } from "react/jsx-runtime";
11011
11263
  var money = (n) => "$" + Math.round(n).toLocaleString();
11012
11264
  function ChannelContribution({
11013
11265
  channels = [],
@@ -11023,9 +11275,9 @@ function ChannelContribution({
11023
11275
  const grand = total !== void 0 ? total : base + bonus;
11024
11276
  const pct = (v) => grand ? v / grand * 100 : 0;
11025
11277
  const spendTotal = channels.reduce((s, c) => s + Number(String(c.spend || 0).replace(/[^0-9.]/g, "")), 0);
11026
- return /* @__PURE__ */ jsxs76("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 16 }, children: [
11027
- loading ? /* @__PURE__ */ jsx85("span", { className: "fd-skel", style: { height: 34, borderRadius: "var(--r-sm)" } }) : /* @__PURE__ */ jsxs76("div", { className: "fd-row", style: { height: 34, borderRadius: "var(--r-sm)", overflow: "hidden", gap: 2, background: "var(--surface-3)" }, children: [
11028
- channels.map((c) => /* @__PURE__ */ jsx85(
11278
+ return /* @__PURE__ */ jsxs77("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 16 }, children: [
11279
+ loading ? /* @__PURE__ */ jsx86("span", { className: "fd-skel", style: { height: 34, borderRadius: "var(--r-sm)" } }) : /* @__PURE__ */ jsxs77("div", { className: "fd-row", style: { height: 34, borderRadius: "var(--r-sm)", overflow: "hidden", gap: 2, background: "var(--surface-3)" }, children: [
11280
+ channels.map((c) => /* @__PURE__ */ jsx86(
11029
11281
  "span",
11030
11282
  {
11031
11283
  title: c.name + " \xB7 " + c.crp.toFixed(1) + " CRP",
@@ -11034,7 +11286,7 @@ function ChannelContribution({
11034
11286
  },
11035
11287
  c.name
11036
11288
  )),
11037
- bonus > 0 ? /* @__PURE__ */ jsx85(
11289
+ bonus > 0 ? /* @__PURE__ */ jsx86(
11038
11290
  "span",
11039
11291
  {
11040
11292
  title: "Surround-sound bonus +" + bonusPct + "%",
@@ -11043,18 +11295,18 @@ function ChannelContribution({
11043
11295
  }
11044
11296
  ) : null
11045
11297
  ] }),
11046
- showTable ? /* @__PURE__ */ jsxs76("table", { className: "fd-table", style: { fontSize: "var(--body-sm-size)" }, children: [
11047
- /* @__PURE__ */ jsx85("thead", { children: /* @__PURE__ */ jsxs76("tr", { children: [
11048
- /* @__PURE__ */ jsx85("th", { style: { width: "34%" }, children: "Channel" }),
11049
- /* @__PURE__ */ jsx85("th", { style: { width: "16%" }, children: "Weight" }),
11050
- /* @__PURE__ */ jsx85("th", { className: "is-num", style: { width: "16%" }, children: "Spend" }),
11051
- /* @__PURE__ */ jsx85("th", { className: "is-num", style: { width: "17%" }, children: "CRP" }),
11052
- /* @__PURE__ */ jsx85("th", { className: "is-num", style: { width: "17%" }, children: "Share" })
11298
+ showTable ? /* @__PURE__ */ jsxs77("table", { className: "fd-table", style: { fontSize: "var(--body-sm-size)" }, children: [
11299
+ /* @__PURE__ */ jsx86("thead", { children: /* @__PURE__ */ jsxs77("tr", { children: [
11300
+ /* @__PURE__ */ jsx86("th", { style: { width: "34%" }, children: "Channel" }),
11301
+ /* @__PURE__ */ jsx86("th", { style: { width: "16%" }, children: "Weight" }),
11302
+ /* @__PURE__ */ jsx86("th", { className: "is-num", style: { width: "16%" }, children: "Spend" }),
11303
+ /* @__PURE__ */ jsx86("th", { className: "is-num", style: { width: "17%" }, children: "CRP" }),
11304
+ /* @__PURE__ */ jsx86("th", { className: "is-num", style: { width: "17%" }, children: "Share" })
11053
11305
  ] }) }),
11054
- /* @__PURE__ */ jsxs76("tbody", { children: [
11055
- channels.map((c) => /* @__PURE__ */ jsxs76("tr", { children: [
11056
- /* @__PURE__ */ jsx85("td", { children: /* @__PURE__ */ jsx85(ChannelTag, { channel: c.name, size: "sm" }) }),
11057
- /* @__PURE__ */ jsx85("td", { children: /* @__PURE__ */ jsx85(
11306
+ /* @__PURE__ */ jsxs77("tbody", { children: [
11307
+ channels.map((c) => /* @__PURE__ */ jsxs77("tr", { children: [
11308
+ /* @__PURE__ */ jsx86("td", { children: /* @__PURE__ */ jsx86(ChannelTag, { channel: c.name, size: "sm" }) }),
11309
+ /* @__PURE__ */ jsx86("td", { children: /* @__PURE__ */ jsx86(
11058
11310
  "span",
11059
11311
  {
11060
11312
  className: "fd-badge fd-badge-neutral",
@@ -11063,38 +11315,38 @@ function ChannelContribution({
11063
11315
  children: "weight " + (channelWeightOf(c.name) || 0)
11064
11316
  }
11065
11317
  ) }),
11066
- /* @__PURE__ */ jsx85("td", { className: "is-num", children: c.spend }),
11067
- /* @__PURE__ */ jsx85("td", { className: "is-num", children: c.crp.toFixed(1) }),
11068
- /* @__PURE__ */ jsxs76("td", { className: "is-num", children: [
11318
+ /* @__PURE__ */ jsx86("td", { className: "is-num", children: c.spend }),
11319
+ /* @__PURE__ */ jsx86("td", { className: "is-num", children: c.crp.toFixed(1) }),
11320
+ /* @__PURE__ */ jsxs77("td", { className: "is-num", children: [
11069
11321
  pct(c.crp).toFixed(0),
11070
11322
  "%"
11071
11323
  ] })
11072
11324
  ] }, c.name)),
11073
- bonus > 0 ? /* @__PURE__ */ jsxs76("tr", { children: [
11074
- /* @__PURE__ */ jsx85("td", { children: /* @__PURE__ */ jsxs76("span", { className: "fd-row", style: { gap: 9, fontWeight: 600 }, children: [
11075
- /* @__PURE__ */ jsx85("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" } }),
11325
+ bonus > 0 ? /* @__PURE__ */ jsxs77("tr", { children: [
11326
+ /* @__PURE__ */ jsx86("td", { children: /* @__PURE__ */ jsxs77("span", { className: "fd-row", style: { gap: 9, fontWeight: 600 }, children: [
11327
+ /* @__PURE__ */ jsx86("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" } }),
11076
11328
  "Surround-sound bonus"
11077
11329
  ] }) }),
11078
- /* @__PURE__ */ jsx85("td", { children: /* @__PURE__ */ jsxs76("span", { className: "fd-badge fd-badge-success", style: { height: 20, fontSize: 11 }, children: [
11330
+ /* @__PURE__ */ jsx86("td", { children: /* @__PURE__ */ jsxs77("span", { className: "fd-badge fd-badge-success", style: { height: 20, fontSize: 11 }, children: [
11079
11331
  "+",
11080
11332
  bonusPct,
11081
11333
  "% of +",
11082
11334
  bonusMax,
11083
11335
  "%"
11084
11336
  ] }) }),
11085
- /* @__PURE__ */ jsx85("td", { className: "is-num fd-muted", children: "\u2014" }),
11086
- /* @__PURE__ */ jsx85("td", { className: "is-num", children: bonus.toFixed(1) }),
11087
- /* @__PURE__ */ jsxs76("td", { className: "is-num", children: [
11337
+ /* @__PURE__ */ jsx86("td", { className: "is-num fd-muted", children: "\u2014" }),
11338
+ /* @__PURE__ */ jsx86("td", { className: "is-num", children: bonus.toFixed(1) }),
11339
+ /* @__PURE__ */ jsxs77("td", { className: "is-num", children: [
11088
11340
  pct(bonus).toFixed(0),
11089
11341
  "%"
11090
11342
  ] })
11091
11343
  ] }) : null,
11092
- /* @__PURE__ */ jsxs76("tr", { style: { background: "var(--surface-2)" }, children: [
11093
- /* @__PURE__ */ jsx85("td", { style: { fontWeight: 700 }, children: "Campus total" }),
11094
- /* @__PURE__ */ jsx85("td", {}),
11095
- /* @__PURE__ */ jsx85("td", { className: "is-num", style: { fontWeight: 700 }, children: money(spendTotal) }),
11096
- /* @__PURE__ */ jsx85("td", { className: "is-num", style: { fontWeight: 700 }, children: grand.toFixed(1) }),
11097
- /* @__PURE__ */ jsx85("td", { className: "is-num", style: { fontWeight: 700 }, children: "100%" })
11344
+ /* @__PURE__ */ jsxs77("tr", { style: { background: "var(--surface-2)" }, children: [
11345
+ /* @__PURE__ */ jsx86("td", { style: { fontWeight: 700 }, children: "Campus total" }),
11346
+ /* @__PURE__ */ jsx86("td", {}),
11347
+ /* @__PURE__ */ jsx86("td", { className: "is-num", style: { fontWeight: 700 }, children: money(spendTotal) }),
11348
+ /* @__PURE__ */ jsx86("td", { className: "is-num", style: { fontWeight: 700 }, children: grand.toFixed(1) }),
11349
+ /* @__PURE__ */ jsx86("td", { className: "is-num", style: { fontWeight: 700 }, children: "100%" })
11098
11350
  ] })
11099
11351
  ] })
11100
11352
  ] }) : null
@@ -11102,8 +11354,8 @@ function ChannelContribution({
11102
11354
  }
11103
11355
 
11104
11356
  // src/components/planner/BudgetReallocator.tsx
11105
- import * as React56 from "react";
11106
- import { Fragment as Fragment23, jsx as jsx86, jsxs as jsxs77 } from "react/jsx-runtime";
11357
+ import * as React57 from "react";
11358
+ import { Fragment as Fragment24, jsx as jsx87, jsxs as jsxs78 } from "react/jsx-runtime";
11107
11359
  var bandFor = (crp) => crp >= 200 ? "dominant" : crp >= 100 ? "strong" : crp >= 50 ? "adequate" : "weak";
11108
11360
  function BudgetReallocator({
11109
11361
  campus,
@@ -11118,8 +11370,8 @@ function BudgetReallocator({
11118
11370
  onCancel,
11119
11371
  className = ""
11120
11372
  }) {
11121
- const [draft, setDraft] = React56.useState(spend);
11122
- React56.useEffect(() => setDraft(spend), [spend]);
11373
+ const [draft, setDraft] = React57.useState(spend);
11374
+ React57.useEffect(() => setDraft(spend), [spend]);
11123
11375
  const dirty = draft !== spend;
11124
11376
  const nextCrp = scoreFor ? scoreFor(draft) : crp;
11125
11377
  const nextBand = bandFor(nextCrp);
@@ -11134,10 +11386,10 @@ function BudgetReallocator({
11134
11386
  setDraft(spend);
11135
11387
  if (onCancel) onCancel();
11136
11388
  };
11137
- const trackRef = React56.useRef(null);
11138
- const chipRef = React56.useRef(null);
11139
- const [chipLeft, setChipLeft] = React56.useState(null);
11140
- React56.useLayoutEffect(() => {
11389
+ const trackRef = React57.useRef(null);
11390
+ const chipRef = React57.useRef(null);
11391
+ const [chipLeft, setChipLeft] = React57.useState(null);
11392
+ React57.useLayoutEffect(() => {
11141
11393
  const track = trackRef.current;
11142
11394
  if (!dirty || !track) {
11143
11395
  setChipLeft(null);
@@ -11158,23 +11410,23 @@ function BudgetReallocator({
11158
11410
  ro.observe(track);
11159
11411
  return () => ro.disconnect();
11160
11412
  }, [dirty, pct]);
11161
- return /* @__PURE__ */ jsxs77(
11413
+ return /* @__PURE__ */ jsxs78(
11162
11414
  "div",
11163
11415
  {
11164
11416
  className: ["fd-stack", className].filter(Boolean).join(" "),
11165
11417
  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)" },
11166
11418
  children: [
11167
- /* @__PURE__ */ jsxs77("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
11168
- /* @__PURE__ */ jsx86("span", { className: "fd-h4", style: { flex: 1, minWidth: 140 }, children: campus }),
11169
- /* @__PURE__ */ jsx86(CsiBadge, { band: nowBand, crp, size: "medium" }),
11170
- dirty ? /* @__PURE__ */ jsxs77(Fragment23, { children: [
11171
- /* @__PURE__ */ jsx86("i", { className: "ph ph-arrow-right fd-muted", "aria-hidden": "true" }),
11172
- /* @__PURE__ */ jsx86(CsiBadge, { band: nextBand, crp: nextCrp, size: "medium", preview: true })
11419
+ /* @__PURE__ */ jsxs78("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
11420
+ /* @__PURE__ */ jsx87("span", { className: "fd-h4", style: { flex: 1, minWidth: 140 }, children: campus }),
11421
+ /* @__PURE__ */ jsx87(CsiBadge, { band: nowBand, crp, size: "medium" }),
11422
+ dirty ? /* @__PURE__ */ jsxs78(Fragment24, { children: [
11423
+ /* @__PURE__ */ jsx87("i", { className: "ph ph-arrow-right fd-muted", "aria-hidden": "true" }),
11424
+ /* @__PURE__ */ jsx87(CsiBadge, { band: nextBand, crp: nextCrp, size: "medium", preview: true })
11173
11425
  ] }) : null
11174
11426
  ] }),
11175
- /* @__PURE__ */ jsxs77("div", { className: "fd-slider", ref: trackRef, children: [
11176
- /* @__PURE__ */ jsx86("span", { className: "fd-slider-fill", style: { width: pct + "%" } }),
11177
- dirty ? /* @__PURE__ */ jsx86(
11427
+ /* @__PURE__ */ jsxs78("div", { className: "fd-slider", ref: trackRef, children: [
11428
+ /* @__PURE__ */ jsx87("span", { className: "fd-slider-fill", style: { width: pct + "%" } }),
11429
+ dirty ? /* @__PURE__ */ jsx87(
11178
11430
  "span",
11179
11431
  {
11180
11432
  ref: chipRef,
@@ -11186,7 +11438,7 @@ function BudgetReallocator({
11186
11438
  children: (delta < 0 ? "\u2212$" : "+$") + Math.abs(delta).toLocaleString()
11187
11439
  }
11188
11440
  ) : null,
11189
- /* @__PURE__ */ jsx86(
11441
+ /* @__PURE__ */ jsx87(
11190
11442
  "input",
11191
11443
  {
11192
11444
  type: "range",
@@ -11202,13 +11454,13 @@ function BudgetReallocator({
11202
11454
  }
11203
11455
  )
11204
11456
  ] }),
11205
- /* @__PURE__ */ jsxs77("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
11206
- /* @__PURE__ */ jsxs77("span", { className: "fd-stack", style: { gap: 2, flex: 1, minWidth: 150 }, children: [
11207
- /* @__PURE__ */ jsx86("span", { className: "fd-num", style: { fontSize: 19, fontWeight: 700 }, children: "$" + draft.toLocaleString() }),
11208
- /* @__PURE__ */ jsx86("span", { className: "fd-body-sm fd-muted", children: "Arrow keys step $100, shift+arrow $1,000. Escape reverts." })
11457
+ /* @__PURE__ */ jsxs78("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
11458
+ /* @__PURE__ */ jsxs78("span", { className: "fd-stack", style: { gap: 2, flex: 1, minWidth: 150 }, children: [
11459
+ /* @__PURE__ */ jsx87("span", { className: "fd-num", style: { fontSize: 19, fontWeight: 700 }, children: "$" + draft.toLocaleString() }),
11460
+ /* @__PURE__ */ jsx87("span", { className: "fd-body-sm fd-muted", children: "Arrow keys step $100, shift+arrow $1,000. Escape reverts." })
11209
11461
  ] }),
11210
- /* @__PURE__ */ jsx86("button", { type: "button", className: "fd-btn fd-btn-ghost", disabled: !dirty, onClick: revert, children: "Cancel" }),
11211
- /* @__PURE__ */ jsx86(
11462
+ /* @__PURE__ */ jsx87("button", { type: "button", className: "fd-btn fd-btn-ghost", disabled: !dirty, onClick: revert, children: "Cancel" }),
11463
+ /* @__PURE__ */ jsx87(
11212
11464
  "button",
11213
11465
  {
11214
11466
  type: "button",
@@ -11227,7 +11479,7 @@ function BudgetReallocator({
11227
11479
  }
11228
11480
 
11229
11481
  // src/components/planner/SurroundSound.tsx
11230
- import { jsx as jsx87, jsxs as jsxs78 } from "react/jsx-runtime";
11482
+ import { jsx as jsx88, jsxs as jsxs79 } from "react/jsx-runtime";
11231
11483
  var CATEGORIES = [
11232
11484
  { key: "ooh", label: "OOH", icon: "flag-banner", color: "var(--ch-ooh)" },
11233
11485
  { key: "transit", label: "Transit", icon: "bus", color: "var(--ch-transit)" },
@@ -11239,26 +11491,26 @@ var CATEGORIES = [
11239
11491
  function SurroundSound({ present = [], bonusPct = 0, bonusMax = 40, missedCost, className = "" }) {
11240
11492
  const earned = Math.max(0, Math.min(1, bonusPct / bonusMax));
11241
11493
  const single = present.length <= 2;
11242
- return /* @__PURE__ */ jsxs78("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 14 }, children: [
11243
- /* @__PURE__ */ jsx87("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: CATEGORIES.map((c) => {
11494
+ return /* @__PURE__ */ jsxs79("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 14 }, children: [
11495
+ /* @__PURE__ */ jsx88("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: CATEGORIES.map((c) => {
11244
11496
  const on = present.includes(c.key);
11245
- return /* @__PURE__ */ jsxs78(
11497
+ return /* @__PURE__ */ jsxs79(
11246
11498
  "span",
11247
11499
  {
11248
11500
  title: c.label + (on ? " \u2014 present" : " \u2014 not bought"),
11249
11501
  style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 5, width: 62, padding: "10px 0", borderRadius: "var(--r-md)", border: "1px solid " + (on ? "var(--csi-2-edge)" : "var(--border)"), background: on ? "var(--csi-2-fill)" : "var(--surface-2)", color: on ? "var(--csi-2-text)" : "var(--text-disabled)" },
11250
11502
  children: [
11251
- /* @__PURE__ */ jsx87("i", { className: "ph ph-" + c.icon, style: { fontSize: 19, color: on ? c.color : "var(--text-muted)" }, "aria-hidden": "true" }),
11252
- /* @__PURE__ */ jsx87("span", { style: { fontSize: 10.5, fontWeight: 700 }, children: c.label })
11503
+ /* @__PURE__ */ jsx88("i", { className: "ph ph-" + c.icon, style: { fontSize: 19, color: on ? c.color : "var(--text-muted)" }, "aria-hidden": "true" }),
11504
+ /* @__PURE__ */ jsx88("span", { style: { fontSize: 10.5, fontWeight: 700 }, children: c.label })
11253
11505
  ]
11254
11506
  },
11255
11507
  c.key
11256
11508
  );
11257
11509
  }) }),
11258
- /* @__PURE__ */ jsxs78("div", { className: "fd-stack", style: { gap: 8 }, children: [
11259
- /* @__PURE__ */ jsxs78("div", { className: "fd-row", style: { justifyContent: "space-between", gap: 12 }, children: [
11260
- /* @__PURE__ */ jsx87("span", { className: "fd-label-lg", children: "Surround-sound bonus earned" }),
11261
- /* @__PURE__ */ jsxs78("span", { className: "fd-num", style: { color: single ? "var(--warn-text)" : "var(--csi-3-mark)", fontWeight: 700 }, children: [
11510
+ /* @__PURE__ */ jsxs79("div", { className: "fd-stack", style: { gap: 8 }, children: [
11511
+ /* @__PURE__ */ jsxs79("div", { className: "fd-row", style: { justifyContent: "space-between", gap: 12 }, children: [
11512
+ /* @__PURE__ */ jsx88("span", { className: "fd-label-lg", children: "Surround-sound bonus earned" }),
11513
+ /* @__PURE__ */ jsxs79("span", { className: "fd-num", style: { color: single ? "var(--warn-text)" : "var(--csi-3-mark)", fontWeight: 700 }, children: [
11262
11514
  "+",
11263
11515
  bonusPct,
11264
11516
  "% of +",
@@ -11266,8 +11518,8 @@ function SurroundSound({ present = [], bonusPct = 0, bonusMax = 40, missedCost,
11266
11518
  "%"
11267
11519
  ] })
11268
11520
  ] }),
11269
- /* @__PURE__ */ jsx87("div", { style: { height: 8, borderRadius: "var(--r-xs)", background: "var(--surface-3)", overflow: "hidden" }, children: /* @__PURE__ */ jsx87("div", { style: { height: "100%", width: earned * 100 + "%", background: "var(--csi-3-mark)", borderRadius: "inherit", transition: "width var(--dur-slow) var(--ease)" } }) }),
11270
- /* @__PURE__ */ jsxs78("span", { className: "fd-body-sm fd-secondary", style: { textWrap: "pretty" }, children: [
11521
+ /* @__PURE__ */ jsx88("div", { style: { height: 8, borderRadius: "var(--r-xs)", background: "var(--surface-3)", overflow: "hidden" }, children: /* @__PURE__ */ jsx88("div", { style: { height: "100%", width: earned * 100 + "%", background: "var(--csi-3-mark)", borderRadius: "inherit", transition: "width var(--dur-slow) var(--ease)" } }) }),
11522
+ /* @__PURE__ */ jsxs79("span", { className: "fd-body-sm fd-secondary", style: { textWrap: "pretty" }, children: [
11271
11523
  present.length,
11272
11524
  " of 6 channel categories present.",
11273
11525
  " ",
@@ -11279,7 +11531,7 @@ function SurroundSound({ present = [], bonusPct = 0, bonusMax = 40, missedCost,
11279
11531
  }
11280
11532
 
11281
11533
  // src/components/planner/Importance.tsx
11282
- import { jsx as jsx88, jsxs as jsxs79 } from "react/jsx-runtime";
11534
+ import { jsx as jsx89, jsxs as jsxs80 } from "react/jsx-runtime";
11283
11535
  var IMPORTANCE_LEVELS = [
11284
11536
  { id: "nudge", rank: 1, label: "Nudge", icon: "feather", description: "Breaks a tie, nothing more." },
11285
11537
  { id: "lean", rank: 2, label: "Lean", icon: "arrow-bend-up-right", description: "A mild preference between otherwise equal options." },
@@ -11309,7 +11561,7 @@ function importanceTokens(id) {
11309
11561
  function ImportanceTag({ level, showLabel = true, size = "sm", className = "", disabled = false }) {
11310
11562
  const lvl = importanceLevel(level);
11311
11563
  const t = importanceTokens(level);
11312
- return /* @__PURE__ */ jsxs79(
11564
+ return /* @__PURE__ */ jsxs80(
11313
11565
  "span",
11314
11566
  {
11315
11567
  className: ["fd-imp-tag", size === "md" ? "is-md" : "", disabled ? "is-disabled" : "", className].filter(Boolean).join(" "),
@@ -11317,16 +11569,16 @@ function ImportanceTag({ level, showLabel = true, size = "sm", className = "", d
11317
11569
  title: lvl.label + " \u2014 " + lvl.description,
11318
11570
  "aria-disabled": disabled ? "true" : void 0,
11319
11571
  children: [
11320
- /* @__PURE__ */ jsx88("i", { className: "ph ph-" + lvl.icon, "aria-hidden": "true" }),
11321
- showLabel ? lvl.label : /* @__PURE__ */ jsx88("span", { className: "fd-sr", children: lvl.label })
11572
+ /* @__PURE__ */ jsx89("i", { className: "ph ph-" + lvl.icon, "aria-hidden": "true" }),
11573
+ showLabel ? lvl.label : /* @__PURE__ */ jsx89("span", { className: "fd-sr", children: lvl.label })
11322
11574
  ]
11323
11575
  }
11324
11576
  );
11325
11577
  }
11326
11578
 
11327
11579
  // src/components/planner/PreferenceMeter.tsx
11328
- import * as React57 from "react";
11329
- import { jsx as jsx89, jsxs as jsxs80 } from "react/jsx-runtime";
11580
+ import * as React58 from "react";
11581
+ import { jsx as jsx90, jsxs as jsxs81 } from "react/jsx-runtime";
11330
11582
  function preferenceScore(criteria) {
11331
11583
  const earned = criteria.reduce((n, c) => n + (Number(c.earned) || 0), 0);
11332
11584
  const weight = criteria.reduce((n, c) => n + (Number(c.weight) || 0), 0);
@@ -11355,8 +11607,8 @@ function PreferenceMeter({
11355
11607
  className = ""
11356
11608
  }) {
11357
11609
  const value = score == null ? preferenceScore(criteria) : score;
11358
- const segments = React57.useMemo(() => preferenceSegments(criteria), [criteria]);
11359
- return /* @__PURE__ */ jsx89(
11610
+ const segments = React58.useMemo(() => preferenceSegments(criteria), [criteria]);
11611
+ return /* @__PURE__ */ jsx90(
11360
11612
  ScoreMeter,
11361
11613
  {
11362
11614
  score: value,
@@ -11368,22 +11620,22 @@ function PreferenceMeter({
11368
11620
  placement,
11369
11621
  className,
11370
11622
  breakdownLabel: breakdownTitle,
11371
- breakdown: /* @__PURE__ */ jsxs80("div", { className: "fd-prefbreak", children: [
11372
- /* @__PURE__ */ jsxs80("div", { className: "fd-prefbreak-head", children: [
11373
- /* @__PURE__ */ jsx89("span", { className: "fd-label-lg", children: breakdownTitle }),
11374
- /* @__PURE__ */ jsx89("span", { className: "fd-prefbreak-score fd-tabular", children: Math.round(value) })
11623
+ breakdown: /* @__PURE__ */ jsxs81("div", { className: "fd-prefbreak", children: [
11624
+ /* @__PURE__ */ jsxs81("div", { className: "fd-prefbreak-head", children: [
11625
+ /* @__PURE__ */ jsx90("span", { className: "fd-label-lg", children: breakdownTitle }),
11626
+ /* @__PURE__ */ jsx90("span", { className: "fd-prefbreak-score fd-tabular", children: Math.round(value) })
11375
11627
  ] }),
11376
- /* @__PURE__ */ jsx89("ul", { className: "fd-prefbreak-list", children: criteria.map((c) => {
11628
+ /* @__PURE__ */ jsx90("ul", { className: "fd-prefbreak-list", children: criteria.map((c) => {
11377
11629
  const pct = c.weight > 0 ? Math.round((Number(c.earned) || 0) / c.weight * 100) : 0;
11378
- return /* @__PURE__ */ jsxs80("li", { className: pct === 0 ? "fd-prefbreak-item is-unmet" : "fd-prefbreak-item", children: [
11379
- /* @__PURE__ */ jsx89(ImportanceTag, { level: c.importance }),
11380
- /* @__PURE__ */ jsxs80("span", { className: "fd-prefbreak-text", children: [
11381
- /* @__PURE__ */ jsx89("span", { className: "fd-prefbreak-label", children: c.label }),
11382
- c.note ? /* @__PURE__ */ jsx89("span", { className: "fd-prefbreak-note", children: c.note }) : null
11630
+ return /* @__PURE__ */ jsxs81("li", { className: pct === 0 ? "fd-prefbreak-item is-unmet" : "fd-prefbreak-item", children: [
11631
+ /* @__PURE__ */ jsx90(ImportanceTag, { level: c.importance }),
11632
+ /* @__PURE__ */ jsxs81("span", { className: "fd-prefbreak-text", children: [
11633
+ /* @__PURE__ */ jsx90("span", { className: "fd-prefbreak-label", children: c.label }),
11634
+ c.note ? /* @__PURE__ */ jsx90("span", { className: "fd-prefbreak-note", children: c.note }) : null
11383
11635
  ] }),
11384
- /* @__PURE__ */ jsxs80("span", { className: "fd-prefbreak-val fd-tabular", children: [
11636
+ /* @__PURE__ */ jsxs81("span", { className: "fd-prefbreak-val fd-tabular", children: [
11385
11637
  Math.round(Number(c.earned) || 0),
11386
- /* @__PURE__ */ jsx89("span", { className: "fd-prefbreak-sep", children: "/" }),
11638
+ /* @__PURE__ */ jsx90("span", { className: "fd-prefbreak-sep", children: "/" }),
11387
11639
  Math.round(c.weight)
11388
11640
  ] })
11389
11641
  ] }, c.id);
@@ -11394,10 +11646,10 @@ function PreferenceMeter({
11394
11646
  }
11395
11647
 
11396
11648
  // src/components/chat/AgentChatPanel.tsx
11397
- import * as React63 from "react";
11649
+ import * as React64 from "react";
11398
11650
 
11399
11651
  // src/components/chat/chatEngine.ts
11400
- import * as React58 from "react";
11652
+ import * as React59 from "react";
11401
11653
  var CHAT_UNAVAILABLE = "chat_unavailable";
11402
11654
  var JOB_PENDING = ["queued", "running"];
11403
11655
  var JOB_SUCCESS = ["completed", "recovered"];
@@ -11451,22 +11703,22 @@ function useChatEngine(opts) {
11451
11703
  onClear,
11452
11704
  onFeedback
11453
11705
  } = opts || {};
11454
- const [status, setStatus] = React58.useState("idle");
11455
- const [threadId, setThreadId] = React58.useState(null);
11456
- const [messages, setMessages] = React58.useState([]);
11457
- const [queue, setQueue] = React58.useState([]);
11458
- const [fatal, setFatal] = React58.useState(null);
11459
- const [busy, setBusy] = React58.useState(false);
11460
- const [turnStartedAt, setTurnStartedAt] = React58.useState(null);
11461
- const listRef = React58.useRef([]);
11462
- const queueRef = React58.useRef([]);
11463
- const busyRef = React58.useRef(false);
11464
- const stoppedRef = React58.useRef(false);
11465
- const abortRef = React58.useRef(null);
11466
- const serverCount = React58.useRef(0);
11467
- const threadRef = React58.useRef(null);
11468
- const mounted = React58.useRef(true);
11469
- React58.useEffect(() => {
11706
+ const [status, setStatus] = React59.useState("idle");
11707
+ const [threadId, setThreadId] = React59.useState(null);
11708
+ const [messages, setMessages] = React59.useState([]);
11709
+ const [queue, setQueue] = React59.useState([]);
11710
+ const [fatal, setFatal] = React59.useState(null);
11711
+ const [busy, setBusy] = React59.useState(false);
11712
+ const [turnStartedAt, setTurnStartedAt] = React59.useState(null);
11713
+ const listRef = React59.useRef([]);
11714
+ const queueRef = React59.useRef([]);
11715
+ const busyRef = React59.useRef(false);
11716
+ const stoppedRef = React59.useRef(false);
11717
+ const abortRef = React59.useRef(null);
11718
+ const serverCount = React59.useRef(0);
11719
+ const threadRef = React59.useRef(null);
11720
+ const mounted = React59.useRef(true);
11721
+ React59.useEffect(() => {
11470
11722
  mounted.current = true;
11471
11723
  return () => {
11472
11724
  mounted.current = false;
@@ -11488,14 +11740,14 @@ function useChatEngine(opts) {
11488
11740
  }
11489
11741
  return false;
11490
11742
  };
11491
- const loadThread = React58.useCallback(async (id) => {
11743
+ const loadThread = React59.useCallback(async (id) => {
11492
11744
  const data = await apiAdapter.getThread(id);
11493
11745
  const list = [...data && data.messages || []];
11494
11746
  serverCount.current = list.length;
11495
11747
  commit(list);
11496
11748
  return list;
11497
11749
  }, [apiAdapter]);
11498
- React58.useEffect(() => {
11750
+ React59.useEffect(() => {
11499
11751
  if (!apiAdapter) {
11500
11752
  setStatus("idle");
11501
11753
  setFatal(null);
@@ -11708,7 +11960,7 @@ function useChatEngine(opts) {
11708
11960
  await dispatchTurn(turn);
11709
11961
  }
11710
11962
  }
11711
- const send = React58.useCallback((text, attachments) => {
11963
+ const send = React59.useCallback((text, attachments) => {
11712
11964
  const body = (text || "").trim();
11713
11965
  if (!body && !(attachments && attachments.length)) return;
11714
11966
  if (status === "disconnected") return;
@@ -11718,7 +11970,7 @@ function useChatEngine(opts) {
11718
11970
  stoppedRef.current = false;
11719
11971
  drain();
11720
11972
  }, [status]);
11721
- const stop = React58.useCallback(() => {
11973
+ const stop = React59.useCallback(() => {
11722
11974
  stoppedRef.current = true;
11723
11975
  const ac = abortRef.current;
11724
11976
  if (ac) {
@@ -11737,11 +11989,11 @@ function useChatEngine(opts) {
11737
11989
  store.del(STORAGE_PREFIX + threadRef.current);
11738
11990
  }
11739
11991
  }, [apiAdapter]);
11740
- const removeQueued = React58.useCallback((id) => {
11992
+ const removeQueued = React59.useCallback((id) => {
11741
11993
  queueRef.current = queueRef.current.filter((t) => t.id !== id);
11742
11994
  setQueue(queueRef.current.slice());
11743
11995
  }, []);
11744
- const retry = React58.useCallback(() => {
11996
+ const retry = React59.useCallback(() => {
11745
11997
  const list = listRef.current;
11746
11998
  let at = -1;
11747
11999
  for (let i = list.length - 1; i >= 0; i--) if (list[i].role === "user") {
@@ -11757,19 +12009,19 @@ function useChatEngine(opts) {
11757
12009
  setQueue(queueRef.current.slice());
11758
12010
  drain();
11759
12011
  }, []);
11760
- const clear = React58.useCallback(() => {
12012
+ const clear = React59.useCallback(() => {
11761
12013
  commit([]);
11762
12014
  serverCount.current = 0;
11763
12015
  queueRef.current = [];
11764
12016
  setQueue([]);
11765
12017
  onClear && onClear();
11766
12018
  }, [onClear]);
11767
- const setFeedback = React58.useCallback((id, value) => {
12019
+ const setFeedback = React59.useCallback((id, value) => {
11768
12020
  patch(id, (m) => ({ feedback: m.feedback === value ? null : value }));
11769
12021
  const msg = listRef.current.find((m) => m.id === id);
11770
12022
  onFeedback && onFeedback({ message: msg, feedback: msg ? msg.feedback : value });
11771
12023
  }, [onFeedback]);
11772
- const reload = React58.useCallback(async () => {
12024
+ const reload = React59.useCallback(async () => {
11773
12025
  if (!threadRef.current) return;
11774
12026
  setStatus("loading");
11775
12027
  try {
@@ -11807,11 +12059,11 @@ var ChatKit = {
11807
12059
  };
11808
12060
 
11809
12061
  // src/components/chat/ChatTranscript.tsx
11810
- import * as React60 from "react";
12062
+ import * as React61 from "react";
11811
12063
 
11812
12064
  // src/components/chat/ChatTurn.tsx
11813
- import * as React59 from "react";
11814
- import { jsx as jsx90, jsxs as jsxs81 } from "react/jsx-runtime";
12065
+ import * as React60 from "react";
12066
+ import { jsx as jsx91, jsxs as jsxs82 } from "react/jsx-runtime";
11815
12067
  function JsonView({ value }) {
11816
12068
  let text;
11817
12069
  try {
@@ -11819,67 +12071,67 @@ function JsonView({ value }) {
11819
12071
  } catch (e) {
11820
12072
  text = String(value);
11821
12073
  }
11822
- return /* @__PURE__ */ jsx90(CodeBlock, { code: text, language: "json", collapseAfter: 18 });
12074
+ return /* @__PURE__ */ jsx91(CodeBlock, { code: text, language: "json", collapseAfter: 18 });
11823
12075
  }
11824
12076
  function PacketCard({ packet, schema, render, onApply, applied }) {
11825
12077
  if (!packet) return null;
11826
12078
  const s = schema || {};
11827
12079
  const invalid = packet.valid === false;
11828
12080
  const title = s.heading || packet.type;
11829
- return /* @__PURE__ */ jsxs81("section", { className: "fdc-packet" + (invalid ? " is-invalid" : ""), "aria-label": title, children: [
11830
- /* @__PURE__ */ jsxs81("header", { className: "fdc-packet-head", children: [
11831
- /* @__PURE__ */ jsx90("i", { className: "ph ph-" + (s.icon || "package"), "aria-hidden": "true" }),
11832
- /* @__PURE__ */ jsx90("span", { className: "fdc-packet-title", title: truncationTitle(title), children: title }),
11833
- packet.repaired ? /* @__PURE__ */ jsx90("span", { className: "fdc-packet-badge", children: "Repaired" }) : null,
11834
- invalid ? /* @__PURE__ */ jsx90("span", { className: "fdc-packet-badge is-danger", children: "Invalid" }) : null
12081
+ return /* @__PURE__ */ jsxs82("section", { className: "fdc-packet" + (invalid ? " is-invalid" : ""), "aria-label": title, children: [
12082
+ /* @__PURE__ */ jsxs82("header", { className: "fdc-packet-head", children: [
12083
+ /* @__PURE__ */ jsx91("i", { className: "ph ph-" + (s.icon || "package"), "aria-hidden": "true" }),
12084
+ /* @__PURE__ */ jsx91("span", { className: "fdc-packet-title", title: truncationTitle(title), children: title }),
12085
+ packet.repaired ? /* @__PURE__ */ jsx91("span", { className: "fdc-packet-badge", children: "Repaired" }) : null,
12086
+ invalid ? /* @__PURE__ */ jsx91("span", { className: "fdc-packet-badge is-danger", children: "Invalid" }) : null
11835
12087
  ] }),
11836
- invalid ? /* @__PURE__ */ jsxs81("div", { className: "fdc-packet-alert", role: "alert", children: [
11837
- /* @__PURE__ */ jsx90("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
11838
- /* @__PURE__ */ jsx90("span", { children: packet.error || "This result failed validation and can\u2019t be applied." })
11839
- ] }) : /* @__PURE__ */ jsx90("div", { className: "fdc-packet-body", children: render ? render(packet) : /* @__PURE__ */ jsx90(JsonView, { value: packet.payload }) }),
11840
- !invalid && onApply ? /* @__PURE__ */ jsxs81("footer", { className: "fdc-packet-foot", children: [
11841
- packet.repaired ? /* @__PURE__ */ jsx90("span", { className: "fdc-packet-note", children: "Corrected by the backend after a first attempt." }) : /* @__PURE__ */ jsx90("span", {}),
11842
- /* @__PURE__ */ jsxs81("button", { type: "button", className: "fd-btn fd-btn-primary fd-btn-sm", disabled: applied, onClick: () => onApply(packet), children: [
11843
- /* @__PURE__ */ jsx90("i", { className: "ph ph-" + (applied ? "check" : "arrow-square-in"), "aria-hidden": "true" }),
12088
+ invalid ? /* @__PURE__ */ jsxs82("div", { className: "fdc-packet-alert", role: "alert", children: [
12089
+ /* @__PURE__ */ jsx91("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
12090
+ /* @__PURE__ */ jsx91("span", { children: packet.error || "This result failed validation and can\u2019t be applied." })
12091
+ ] }) : /* @__PURE__ */ jsx91("div", { className: "fdc-packet-body", children: render ? render(packet) : /* @__PURE__ */ jsx91(JsonView, { value: packet.payload }) }),
12092
+ !invalid && onApply ? /* @__PURE__ */ jsxs82("footer", { className: "fdc-packet-foot", children: [
12093
+ packet.repaired ? /* @__PURE__ */ jsx91("span", { className: "fdc-packet-note", children: "Corrected by the backend after a first attempt." }) : /* @__PURE__ */ jsx91("span", {}),
12094
+ /* @__PURE__ */ jsxs82("button", { type: "button", className: "fd-btn fd-btn-primary fd-btn-sm", disabled: applied, onClick: () => onApply(packet), children: [
12095
+ /* @__PURE__ */ jsx91("i", { className: "ph ph-" + (applied ? "check" : "arrow-square-in"), "aria-hidden": "true" }),
11844
12096
  applied ? "Applied" : s.applyLabel || "Apply"
11845
12097
  ] })
11846
12098
  ] }) : null
11847
12099
  ] });
11848
12100
  }
11849
12101
  function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
11850
- const [open2, setOpen] = React59.useState(defaultOpen);
12102
+ const [open2, setOpen] = React60.useState(defaultOpen);
11851
12103
  if (!text) return null;
11852
- return /* @__PURE__ */ jsxs81("div", { className: "fdc-think" + (open2 ? " is-open" : ""), children: [
11853
- /* @__PURE__ */ jsxs81("button", { type: "button", className: "fdc-think-head", onClick: () => setOpen((v) => !v), "aria-expanded": open2, children: [
11854
- /* @__PURE__ */ jsx90("i", { className: "ph ph-brain", "aria-hidden": "true" }),
11855
- /* @__PURE__ */ jsx90("span", { children: streaming ? "Thinking" : durationMs ? "Thought for " + formatDuration(durationMs) : "Thought process" }),
11856
- streaming ? /* @__PURE__ */ jsxs81("span", { className: "fdc-dots", "aria-hidden": "true", children: [
11857
- /* @__PURE__ */ jsx90("span", {}),
11858
- /* @__PURE__ */ jsx90("span", {}),
11859
- /* @__PURE__ */ jsx90("span", {})
12104
+ return /* @__PURE__ */ jsxs82("div", { className: "fdc-think" + (open2 ? " is-open" : ""), children: [
12105
+ /* @__PURE__ */ jsxs82("button", { type: "button", className: "fdc-think-head", onClick: () => setOpen((v) => !v), "aria-expanded": open2, children: [
12106
+ /* @__PURE__ */ jsx91("i", { className: "ph ph-brain", "aria-hidden": "true" }),
12107
+ /* @__PURE__ */ jsx91("span", { children: streaming ? "Thinking" : durationMs ? "Thought for " + formatDuration(durationMs) : "Thought process" }),
12108
+ streaming ? /* @__PURE__ */ jsxs82("span", { className: "fdc-dots", "aria-hidden": "true", children: [
12109
+ /* @__PURE__ */ jsx91("span", {}),
12110
+ /* @__PURE__ */ jsx91("span", {}),
12111
+ /* @__PURE__ */ jsx91("span", {})
11860
12112
  ] }) : null,
11861
- /* @__PURE__ */ jsx90("i", { className: "ph ph-caret-" + (open2 ? "up" : "down"), "aria-hidden": "true" })
12113
+ /* @__PURE__ */ jsx91("i", { className: "ph ph-caret-" + (open2 ? "up" : "down"), "aria-hidden": "true" })
11862
12114
  ] }),
11863
- open2 ? /* @__PURE__ */ jsx90("div", { className: "fdc-think-body", children: text }) : null
12115
+ open2 ? /* @__PURE__ */ jsx91("div", { className: "fdc-think-body", children: text }) : null
11864
12116
  ] });
11865
12117
  }
11866
12118
  function Citations({ items = [], onOpen }) {
11867
- const [open2, setOpen] = React59.useState(false);
12119
+ const [open2, setOpen] = React60.useState(false);
11868
12120
  if (!items.length) return null;
11869
- return /* @__PURE__ */ jsxs81("div", { className: "fdc-cites", children: [
11870
- /* @__PURE__ */ jsxs81("button", { type: "button", className: "fdc-cites-head", onClick: () => setOpen((v) => !v), "aria-expanded": open2, children: [
11871
- /* @__PURE__ */ jsx90("i", { className: "ph ph-quotes", "aria-hidden": "true" }),
11872
- /* @__PURE__ */ jsxs81("span", { children: [
12121
+ return /* @__PURE__ */ jsxs82("div", { className: "fdc-cites", children: [
12122
+ /* @__PURE__ */ jsxs82("button", { type: "button", className: "fdc-cites-head", onClick: () => setOpen((v) => !v), "aria-expanded": open2, children: [
12123
+ /* @__PURE__ */ jsx91("i", { className: "ph ph-quotes", "aria-hidden": "true" }),
12124
+ /* @__PURE__ */ jsxs82("span", { children: [
11873
12125
  items.length,
11874
12126
  " source",
11875
12127
  items.length === 1 ? "" : "s"
11876
12128
  ] }),
11877
- /* @__PURE__ */ jsx90("i", { className: "ph ph-caret-" + (open2 ? "up" : "down"), "aria-hidden": "true" })
12129
+ /* @__PURE__ */ jsx91("i", { className: "ph ph-caret-" + (open2 ? "up" : "down"), "aria-hidden": "true" })
11878
12130
  ] }),
11879
- open2 ? /* @__PURE__ */ jsx90("ol", { className: "fdc-cites-list", children: items.map((c, i) => /* @__PURE__ */ jsxs81("li", { children: [
11880
- /* @__PURE__ */ jsx90("span", { className: "fdc-cite-n fd-tabular", children: c.marker || i + 1 }),
11881
- c.url ? /* @__PURE__ */ jsx90("a", { href: c.url, target: "_blank", rel: "noopener noreferrer", onClick: onOpen ? (e) => onOpen(c, e) : void 0, children: c.title || c.url }) : /* @__PURE__ */ jsx90("span", { children: c.title || "Source" }),
11882
- c.detail ? /* @__PURE__ */ jsx90("span", { className: "fdc-cite-detail", children: c.detail }) : null
12131
+ open2 ? /* @__PURE__ */ jsx91("ol", { className: "fdc-cites-list", children: items.map((c, i) => /* @__PURE__ */ jsxs82("li", { children: [
12132
+ /* @__PURE__ */ jsx91("span", { className: "fdc-cite-n fd-tabular", children: c.marker || i + 1 }),
12133
+ c.url ? /* @__PURE__ */ jsx91("a", { href: c.url, target: "_blank", rel: "noopener noreferrer", onClick: onOpen ? (e) => onOpen(c, e) : void 0, children: c.title || c.url }) : /* @__PURE__ */ jsx91("span", { children: c.title || "Source" }),
12134
+ c.detail ? /* @__PURE__ */ jsx91("span", { className: "fdc-cite-detail", children: c.detail }) : null
11883
12135
  ] }, c.id || i)) }) : null
11884
12136
  ] });
11885
12137
  }
@@ -11890,29 +12142,29 @@ function clampText(text, max) {
11890
12142
  return (at > max * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
11891
12143
  }
11892
12144
  function MessageBody({ message: m, ctx }) {
11893
- const [expanded, setExpanded] = React59.useState(false);
12145
+ const [expanded, setExpanded] = React60.useState(false);
11894
12146
  const isUser = m.role === "user";
11895
12147
  const raw = m.text || "";
11896
12148
  const clamped = !expanded && !m.streaming ? clampText(raw, ctx.maxVisibleChars) : null;
11897
12149
  const body = clamped != null ? clamped : raw;
11898
12150
  const showMd = ctx.markdown && !isUser;
11899
- return /* @__PURE__ */ jsxs81("div", { className: "fdc-body", children: [
11900
- m.thinking && ctx.showThinking ? /* @__PURE__ */ jsx90(ThinkingBlock, { text: m.thinking, durationMs: m.thinkingMs, streaming: m.streaming && !m.text }) : null,
11901
- m.steps && m.steps.length && ctx.showSteps ? /* @__PURE__ */ jsx90(StepList, { steps: m.steps, defaultOpen: m.steps.some((s) => s.status === "running"), dense: true }) : null,
11902
- body ? /* @__PURE__ */ jsxs81("div", { className: "fdc-text" + (isUser ? " is-user" : ""), children: [
11903
- showMd ? /* @__PURE__ */ jsx90(Markdown, { source: body, headingOffset: 2, codeProps: { collapseAfter: 22 }, renderCitation: ctx.renderCitation }) : /* @__PURE__ */ jsx90("div", { className: "fdc-plain", children: body }),
11904
- m.streaming ? /* @__PURE__ */ jsx90("span", { className: "fdc-caret", "aria-hidden": "true" }) : null
12151
+ return /* @__PURE__ */ jsxs82("div", { className: "fdc-body", children: [
12152
+ m.thinking && ctx.showThinking ? /* @__PURE__ */ jsx91(ThinkingBlock, { text: m.thinking, durationMs: m.thinkingMs, streaming: m.streaming && !m.text }) : null,
12153
+ m.steps && m.steps.length && ctx.showSteps ? /* @__PURE__ */ jsx91(StepList, { steps: m.steps, defaultOpen: m.steps.some((s) => s.status === "running"), dense: true }) : null,
12154
+ body ? /* @__PURE__ */ jsxs82("div", { className: "fdc-text" + (isUser ? " is-user" : ""), children: [
12155
+ showMd ? /* @__PURE__ */ jsx91(Markdown, { source: body, headingOffset: 2, codeProps: { collapseAfter: 22 }, renderCitation: ctx.renderCitation }) : /* @__PURE__ */ jsx91("div", { className: "fdc-plain", children: body }),
12156
+ m.streaming ? /* @__PURE__ */ jsx91("span", { className: "fdc-caret", "aria-hidden": "true" }) : null
11905
12157
  ] }) : null,
11906
- clamped != null ? /* @__PURE__ */ jsxs81("button", { type: "button", className: "fdc-more", onClick: () => setExpanded(true), children: [
11907
- /* @__PURE__ */ jsx90("i", { className: "ph ph-caret-down", "aria-hidden": "true" }),
12158
+ clamped != null ? /* @__PURE__ */ jsxs82("button", { type: "button", className: "fdc-more", onClick: () => setExpanded(true), children: [
12159
+ /* @__PURE__ */ jsx91("i", { className: "ph ph-caret-down", "aria-hidden": "true" }),
11908
12160
  "Show more",
11909
- /* @__PURE__ */ jsx90("span", { className: "fdc-more-len fd-tabular", children: raw.length < 2e3 ? raw.length.toLocaleString() + " characters" : Math.round(raw.length / 100) / 10 + "k characters" })
11910
- ] }) : expanded && ctx.maxVisibleChars && raw.length > ctx.maxVisibleChars ? /* @__PURE__ */ jsxs81("button", { type: "button", className: "fdc-more", onClick: () => setExpanded(false), children: [
11911
- /* @__PURE__ */ jsx90("i", { className: "ph ph-caret-up", "aria-hidden": "true" }),
12161
+ /* @__PURE__ */ jsx91("span", { className: "fdc-more-len fd-tabular", children: raw.length < 2e3 ? raw.length.toLocaleString() + " characters" : Math.round(raw.length / 100) / 10 + "k characters" })
12162
+ ] }) : expanded && ctx.maxVisibleChars && raw.length > ctx.maxVisibleChars ? /* @__PURE__ */ jsxs82("button", { type: "button", className: "fdc-more", onClick: () => setExpanded(false), children: [
12163
+ /* @__PURE__ */ jsx91("i", { className: "ph ph-caret-up", "aria-hidden": "true" }),
11912
12164
  "Show less"
11913
12165
  ] }) : null,
11914
- m.attachments && m.attachments.length ? /* @__PURE__ */ jsx90(FileGrid, { files: m.attachments, onOpen: ctx.onOpenAttachment, tiles: true, maxHeight: ctx.attachmentHeight || 220, compact: ctx.narrow }) : null,
11915
- m.packet ? /* @__PURE__ */ jsx90(
12166
+ m.attachments && m.attachments.length ? /* @__PURE__ */ jsx91(FileGrid, { files: m.attachments, onOpen: ctx.onOpenAttachment, tiles: true, maxHeight: ctx.attachmentHeight || 220, compact: ctx.narrow }) : null,
12167
+ m.packet ? /* @__PURE__ */ jsx91(
11916
12168
  PacketCard,
11917
12169
  {
11918
12170
  packet: m.packet,
@@ -11922,44 +12174,44 @@ function MessageBody({ message: m, ctx }) {
11922
12174
  applied: ctx.appliedPackets && ctx.appliedPackets[m.id]
11923
12175
  }
11924
12176
  ) : null,
11925
- m.citations && m.citations.length ? /* @__PURE__ */ jsx90(Citations, { items: m.citations, onOpen: ctx.onOpenCitation }) : null,
11926
- m.working ? /* @__PURE__ */ jsxs81("div", { className: "fdc-working", role: "status", children: [
11927
- /* @__PURE__ */ jsxs81("span", { className: "fdc-dots", "aria-hidden": "true", children: [
11928
- /* @__PURE__ */ jsx90("span", {}),
11929
- /* @__PURE__ */ jsx90("span", {}),
11930
- /* @__PURE__ */ jsx90("span", {})
12177
+ m.citations && m.citations.length ? /* @__PURE__ */ jsx91(Citations, { items: m.citations, onOpen: ctx.onOpenCitation }) : null,
12178
+ m.working ? /* @__PURE__ */ jsxs82("div", { className: "fdc-working", role: "status", children: [
12179
+ /* @__PURE__ */ jsxs82("span", { className: "fdc-dots", "aria-hidden": "true", children: [
12180
+ /* @__PURE__ */ jsx91("span", {}),
12181
+ /* @__PURE__ */ jsx91("span", {}),
12182
+ /* @__PURE__ */ jsx91("span", {})
11931
12183
  ] }),
11932
- /* @__PURE__ */ jsxs81("span", { className: "fdc-working-label", children: [
12184
+ /* @__PURE__ */ jsxs82("span", { className: "fdc-working-label", children: [
11933
12185
  m.resumed ? "Resuming" : "Working",
11934
- m.job && m.job.status ? /* @__PURE__ */ jsxs81("span", { className: "fdc-working-job", children: [
12186
+ m.job && m.job.status ? /* @__PURE__ */ jsxs82("span", { className: "fdc-working-job", children: [
11935
12187
  " \xB7 ",
11936
12188
  m.job.status
11937
12189
  ] }) : null,
11938
- m.job && m.job.detail ? /* @__PURE__ */ jsxs81("span", { className: "fdc-working-job", children: [
12190
+ m.job && m.job.detail ? /* @__PURE__ */ jsxs82("span", { className: "fdc-working-job", children: [
11939
12191
  " \xB7 ",
11940
12192
  m.job.detail
11941
12193
  ] }) : null
11942
12194
  ] }),
11943
- m.jobId ? /* @__PURE__ */ jsx90("span", { className: "fdc-working-id fd-mono", children: String(m.jobId).slice(0, 12) }) : null
12195
+ m.jobId ? /* @__PURE__ */ jsx91("span", { className: "fdc-working-id fd-mono", children: String(m.jobId).slice(0, 12) }) : null
11944
12196
  ] }) : null,
11945
- m.stopped ? /* @__PURE__ */ jsxs81("div", { className: "fdc-stopped", children: [
11946
- /* @__PURE__ */ jsx90("i", { className: "ph ph-stop-circle", "aria-hidden": "true" }),
12197
+ m.stopped ? /* @__PURE__ */ jsxs82("div", { className: "fdc-stopped", children: [
12198
+ /* @__PURE__ */ jsx91("i", { className: "ph ph-stop-circle", "aria-hidden": "true" }),
11947
12199
  "Stopped"
11948
12200
  ] }) : null,
11949
- m.error ? /* @__PURE__ */ jsxs81("div", { className: "fdc-error", role: "alert", children: [
11950
- /* @__PURE__ */ jsx90("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
11951
- /* @__PURE__ */ jsx90("span", { className: "fdc-error-text", children: ctx.errorCopy ? ctx.errorCopy(m.error) : m.error }),
11952
- m.retryable && ctx.onRetry ? /* @__PURE__ */ jsxs81("button", { type: "button", className: "fdc-error-retry", onClick: ctx.onRetry, children: [
11953
- /* @__PURE__ */ jsx90("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }),
12201
+ m.error ? /* @__PURE__ */ jsxs82("div", { className: "fdc-error", role: "alert", children: [
12202
+ /* @__PURE__ */ jsx91("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
12203
+ /* @__PURE__ */ jsx91("span", { className: "fdc-error-text", children: ctx.errorCopy ? ctx.errorCopy(m.error) : m.error }),
12204
+ m.retryable && ctx.onRetry ? /* @__PURE__ */ jsxs82("button", { type: "button", className: "fdc-error-retry", onClick: ctx.onRetry, children: [
12205
+ /* @__PURE__ */ jsx91("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }),
11954
12206
  "Retry"
11955
12207
  ] }) : null
11956
12208
  ] }) : null
11957
12209
  ] });
11958
12210
  }
11959
12211
  function useCopyRun() {
11960
- const [done, setDone] = React59.useState(false);
11961
- const t = React59.useRef(null);
11962
- React59.useEffect(() => () => {
12212
+ const [done, setDone] = React60.useState(false);
12213
+ const t = React60.useRef(null);
12214
+ React60.useEffect(() => () => {
11963
12215
  if (t.current) clearTimeout(t.current);
11964
12216
  }, []);
11965
12217
  return [done, (text) => {
@@ -11979,16 +12231,16 @@ function RunActions({ group, ctx }) {
11979
12231
  const isAssistant = group.role === "assistant";
11980
12232
  const fb = last.feedback;
11981
12233
  if (!ctx.messageActions) return null;
11982
- return /* @__PURE__ */ jsxs81("div", { className: "fdc-actions", role: "group", "aria-label": "Message actions", children: [
11983
- /* @__PURE__ */ jsxs81("button", { type: "button", className: "fdc-act" + (copied ? " is-done" : ""), onClick: () => copy(markdownToText(text)), "aria-label": "Copy message", children: [
11984
- /* @__PURE__ */ jsx90("i", { className: "ph ph-" + (copied ? "check" : "copy"), "aria-hidden": "true" }),
11985
- /* @__PURE__ */ jsx90("span", { className: "fdc-act-label", children: copied ? "Copied" : "Copy" })
12234
+ return /* @__PURE__ */ jsxs82("div", { className: "fdc-actions", role: "group", "aria-label": "Message actions", children: [
12235
+ /* @__PURE__ */ jsxs82("button", { type: "button", className: "fdc-act" + (copied ? " is-done" : ""), onClick: () => copy(markdownToText(text)), "aria-label": "Copy message", children: [
12236
+ /* @__PURE__ */ jsx91("i", { className: "ph ph-" + (copied ? "check" : "copy"), "aria-hidden": "true" }),
12237
+ /* @__PURE__ */ jsx91("span", { className: "fdc-act-label", children: copied ? "Copied" : "Copy" })
11986
12238
  ] }),
11987
- isAssistant && ctx.onRetry ? /* @__PURE__ */ jsx90("button", { type: "button", className: "fdc-act", onClick: ctx.onRetry, "aria-label": "Retry this turn", children: /* @__PURE__ */ jsx90("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }) }) : null,
11988
- group.role === "user" && ctx.onEdit ? /* @__PURE__ */ jsx90("button", { type: "button", className: "fdc-act", onClick: () => ctx.onEdit(last), "aria-label": "Edit and resend", children: /* @__PURE__ */ jsx90("i", { className: "ph ph-pencil-simple", "aria-hidden": "true" }) }) : null,
11989
- isAssistant && ctx.onFeedback ? /* @__PURE__ */ jsxs81(React59.Fragment, { children: [
11990
- /* @__PURE__ */ jsx90("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__ */ jsx90("i", { className: "ph ph-thumbs-up", "aria-hidden": "true" }) }),
11991
- /* @__PURE__ */ jsx90("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__ */ jsx90("i", { className: "ph ph-thumbs-down", "aria-hidden": "true" }) })
12239
+ isAssistant && ctx.onRetry ? /* @__PURE__ */ jsx91("button", { type: "button", className: "fdc-act", onClick: ctx.onRetry, "aria-label": "Retry this turn", children: /* @__PURE__ */ jsx91("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }) }) : null,
12240
+ group.role === "user" && ctx.onEdit ? /* @__PURE__ */ jsx91("button", { type: "button", className: "fdc-act", onClick: () => ctx.onEdit(last), "aria-label": "Edit and resend", children: /* @__PURE__ */ jsx91("i", { className: "ph ph-pencil-simple", "aria-hidden": "true" }) }) : null,
12241
+ isAssistant && ctx.onFeedback ? /* @__PURE__ */ jsxs82(React60.Fragment, { children: [
12242
+ /* @__PURE__ */ jsx91("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__ */ jsx91("i", { className: "ph ph-thumbs-up", "aria-hidden": "true" }) }),
12243
+ /* @__PURE__ */ jsx91("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__ */ jsx91("i", { className: "ph ph-thumbs-down", "aria-hidden": "true" }) })
11992
12244
  ] }) : null,
11993
12245
  ctx.extraActions ? ctx.extraActions(group) : null
11994
12246
  ] });
@@ -11998,22 +12250,22 @@ function ChatTurn({ group, ctx }) {
11998
12250
  const name = isUser ? ctx.userName : group.author || ctx.assistantName;
11999
12251
  const avatar = isUser ? ctx.userAvatar : ctx.assistantAvatar;
12000
12252
  const stamp = group.messages[0].timestamp;
12001
- return /* @__PURE__ */ jsxs81("article", { className: "fdc-turn is-" + group.role, "aria-label": String(name) + (stamp ? " at " + formatClock(stamp) : ""), children: [
12002
- /* @__PURE__ */ jsxs81("div", { className: "fdc-turn-head", children: [
12003
- ctx.showAvatars ? /* @__PURE__ */ jsx90("span", { className: "fdc-avatar is-" + group.role, "aria-hidden": "true", children: avatar ? /* @__PURE__ */ jsx90("img", { src: avatar, alt: "" }) : isUser ? /* @__PURE__ */ jsx90("span", { className: "fdc-avatar-txt", children: (name || "You").slice(0, 1).toUpperCase() }) : /* @__PURE__ */ jsx90("i", { className: "ph ph-" + (ctx.assistantIcon || "sparkle") }) }) : null,
12004
- /* @__PURE__ */ jsx90("span", { className: "fdc-who", children: name }),
12005
- stamp ? /* @__PURE__ */ jsx90(RelativeTime, { className: "fdc-when", value: stamp }) : null,
12006
- group.messages.some((m) => m.model) ? /* @__PURE__ */ jsx90("span", { className: "fdc-turn-model", children: group.messages.find((m) => m.model).model }) : null
12253
+ return /* @__PURE__ */ jsxs82("article", { className: "fdc-turn is-" + group.role, "aria-label": String(name) + (stamp ? " at " + formatClock(stamp) : ""), children: [
12254
+ /* @__PURE__ */ jsxs82("div", { className: "fdc-turn-head", children: [
12255
+ ctx.showAvatars ? /* @__PURE__ */ jsx91("span", { className: "fdc-avatar is-" + group.role, "aria-hidden": "true", children: avatar ? /* @__PURE__ */ jsx91("img", { src: avatar, alt: "" }) : isUser ? /* @__PURE__ */ jsx91("span", { className: "fdc-avatar-txt", children: (name || "You").slice(0, 1).toUpperCase() }) : /* @__PURE__ */ jsx91("i", { className: "ph ph-" + (ctx.assistantIcon || "sparkle") }) }) : null,
12256
+ /* @__PURE__ */ jsx91("span", { className: "fdc-who", children: name }),
12257
+ stamp ? /* @__PURE__ */ jsx91(RelativeTime, { className: "fdc-when", value: stamp }) : null,
12258
+ group.messages.some((m) => m.model) ? /* @__PURE__ */ jsx91("span", { className: "fdc-turn-model", children: group.messages.find((m) => m.model).model }) : null
12007
12259
  ] }),
12008
- /* @__PURE__ */ jsxs81("div", { className: "fdc-turn-body", children: [
12009
- group.messages.map((m) => /* @__PURE__ */ jsx90("div", { className: "fdc-msg" + (m.pending ? " is-pending" : ""), children: /* @__PURE__ */ jsx90(MessageBody, { message: m, ctx }) }, m.id)),
12010
- /* @__PURE__ */ jsx90(RunActions, { group, ctx })
12260
+ /* @__PURE__ */ jsxs82("div", { className: "fdc-turn-body", children: [
12261
+ group.messages.map((m) => /* @__PURE__ */ jsx91("div", { className: "fdc-msg" + (m.pending ? " is-pending" : ""), children: /* @__PURE__ */ jsx91(MessageBody, { message: m, ctx }) }, m.id)),
12262
+ /* @__PURE__ */ jsx91(RunActions, { group, ctx })
12011
12263
  ] })
12012
12264
  ] });
12013
12265
  }
12014
12266
 
12015
12267
  // src/components/chat/ChatTranscript.tsx
12016
- import { jsx as jsx91, jsxs as jsxs82 } from "react/jsx-runtime";
12268
+ import { jsx as jsx92, jsxs as jsxs83 } from "react/jsx-runtime";
12017
12269
  var GROUP_WINDOW = 6e4;
12018
12270
  var STICK_PX = 100;
12019
12271
  function groupMessages(list) {
@@ -12046,25 +12298,25 @@ function dayLabel(key) {
12046
12298
  }
12047
12299
  function Suggestions({ items = [], onPick }) {
12048
12300
  if (!items.length) return null;
12049
- return /* @__PURE__ */ jsx91("div", { className: "fdc-suggest", children: items.map((s, i) => {
12301
+ return /* @__PURE__ */ jsx92("div", { className: "fdc-suggest", children: items.map((s, i) => {
12050
12302
  const it = typeof s === "string" ? { label: s, text: s } : s;
12051
- return /* @__PURE__ */ jsxs82("button", { type: "button", className: "fdc-suggest-item", onClick: () => onPick && onPick(it.text || it.label), children: [
12052
- it.icon ? /* @__PURE__ */ jsx91("i", { className: "ph ph-" + it.icon, "aria-hidden": "true" }) : null,
12053
- /* @__PURE__ */ jsxs82("span", { className: "fdc-suggest-text", children: [
12054
- /* @__PURE__ */ jsx91("span", { className: "fdc-suggest-label", children: it.label }),
12055
- it.description ? /* @__PURE__ */ jsx91("span", { className: "fdc-suggest-desc", children: it.description }) : null
12303
+ return /* @__PURE__ */ jsxs83("button", { type: "button", className: "fdc-suggest-item", onClick: () => onPick && onPick(it.text || it.label), children: [
12304
+ it.icon ? /* @__PURE__ */ jsx92("i", { className: "ph ph-" + it.icon, "aria-hidden": "true" }) : null,
12305
+ /* @__PURE__ */ jsxs83("span", { className: "fdc-suggest-text", children: [
12306
+ /* @__PURE__ */ jsx92("span", { className: "fdc-suggest-label", children: it.label }),
12307
+ it.description ? /* @__PURE__ */ jsx92("span", { className: "fdc-suggest-desc", children: it.description }) : null
12056
12308
  ] }),
12057
- /* @__PURE__ */ jsx91("i", { className: "ph ph-arrow-up-right fdc-suggest-go", "aria-hidden": "true" })
12309
+ /* @__PURE__ */ jsx92("i", { className: "ph ph-arrow-up-right fdc-suggest-go", "aria-hidden": "true" })
12058
12310
  ] }, it.id || i);
12059
12311
  }) });
12060
12312
  }
12061
12313
  function LoadingTurns() {
12062
- return /* @__PURE__ */ jsx91("div", { className: "fdc-skel", "aria-hidden": "true", children: [0, 1].map((i) => /* @__PURE__ */ jsxs82("div", { className: "fdc-skel-turn", children: [
12063
- /* @__PURE__ */ jsx91("div", { className: "fd-skel fd-skel-circle", style: { width: 22, height: 22 } }),
12064
- /* @__PURE__ */ jsxs82("div", { className: "fdc-skel-lines", children: [
12065
- /* @__PURE__ */ jsx91("div", { className: "fd-skel", style: { width: i ? "62%" : "44%", height: 11 } }),
12066
- /* @__PURE__ */ jsx91("div", { className: "fd-skel", style: { width: i ? "94%" : "78%", height: 11 } }),
12067
- /* @__PURE__ */ jsx91("div", { className: "fd-skel", style: { width: i ? "71%" : "56%", height: 11 } })
12314
+ return /* @__PURE__ */ jsx92("div", { className: "fdc-skel", "aria-hidden": "true", children: [0, 1].map((i) => /* @__PURE__ */ jsxs83("div", { className: "fdc-skel-turn", children: [
12315
+ /* @__PURE__ */ jsx92("div", { className: "fd-skel fd-skel-circle", style: { width: 22, height: 22 } }),
12316
+ /* @__PURE__ */ jsxs83("div", { className: "fdc-skel-lines", children: [
12317
+ /* @__PURE__ */ jsx92("div", { className: "fd-skel", style: { width: i ? "62%" : "44%", height: 11 } }),
12318
+ /* @__PURE__ */ jsx92("div", { className: "fd-skel", style: { width: i ? "94%" : "78%", height: 11 } }),
12319
+ /* @__PURE__ */ jsx92("div", { className: "fd-skel", style: { width: i ? "71%" : "56%", height: 11 } })
12068
12320
  ] })
12069
12321
  ] }, i)) });
12070
12322
  }
@@ -12081,10 +12333,10 @@ function ChatTranscript({
12081
12333
  renderEmpty,
12082
12334
  className = ""
12083
12335
  }) {
12084
- const scroller = React60.useRef(null);
12085
- const stick = React60.useRef(true);
12086
- const [pill, setPill] = React60.useState(0);
12087
- const seen = React60.useRef(0);
12336
+ const scroller = React61.useRef(null);
12337
+ const stick = React61.useRef(true);
12338
+ const [pill, setPill] = React61.useState(0);
12339
+ const seen = React61.useRef(0);
12088
12340
  const toBottom = (smooth) => {
12089
12341
  const el = scroller.current;
12090
12342
  if (!el) return;
@@ -12103,7 +12355,7 @@ function ChatTranscript({
12103
12355
  seen.current = messages.length;
12104
12356
  }
12105
12357
  };
12106
- React60.useLayoutEffect(() => {
12358
+ React61.useLayoutEffect(() => {
12107
12359
  const el = scroller.current;
12108
12360
  if (!el) return;
12109
12361
  if (stick.current) {
@@ -12111,7 +12363,7 @@ function ChatTranscript({
12111
12363
  seen.current = messages.length;
12112
12364
  } else setPill(Math.max(0, messages.length - seen.current));
12113
12365
  }, [messages]);
12114
- React60.useEffect(() => {
12366
+ React61.useEffect(() => {
12115
12367
  const el = scroller.current;
12116
12368
  const inner = el && el.firstChild;
12117
12369
  if (!el || !inner || typeof ResizeObserver === "undefined") return;
@@ -12121,38 +12373,38 @@ function ChatTranscript({
12121
12373
  ro.observe(inner);
12122
12374
  return () => ro.disconnect();
12123
12375
  }, []);
12124
- const groups = React60.useMemo(() => groupMessages(messages), [messages]);
12376
+ const groups = React61.useMemo(() => groupMessages(messages), [messages]);
12125
12377
  const empty = !messages.length && status === "ready";
12126
- return /* @__PURE__ */ jsxs82("div", { className: ["fdc-scroll", className].filter(Boolean).join(" "), ref: scroller, onScroll, children: [
12127
- /* @__PURE__ */ jsxs82("div", { className: "fdc-log", role: "log", "aria-label": "Conversation", children: [
12128
- status === "loading" || status === "resolving" ? /* @__PURE__ */ jsx91(LoadingTurns, {}) : null,
12129
- status === "disconnected" ? /* @__PURE__ */ jsxs82("div", { className: "fdc-dead", children: [
12130
- /* @__PURE__ */ jsx91("span", { className: "fdc-dead-icon", children: /* @__PURE__ */ jsx91("i", { className: "ph ph-plugs", "aria-hidden": "true" }) }),
12131
- /* @__PURE__ */ jsx91("h3", { className: "fdc-dead-title", children: ctx.deadTitle || "The assistant isn\u2019t reachable" }),
12132
- /* @__PURE__ */ jsx91("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." }),
12133
- ctx.onReconnect ? /* @__PURE__ */ jsxs82("button", { type: "button", className: "fd-btn fd-btn-secondary fd-btn-sm", onClick: ctx.onReconnect, children: [
12134
- /* @__PURE__ */ jsx91("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }),
12378
+ return /* @__PURE__ */ jsxs83("div", { className: ["fdc-scroll", className].filter(Boolean).join(" "), ref: scroller, onScroll, children: [
12379
+ /* @__PURE__ */ jsxs83("div", { className: "fdc-log", role: "log", "aria-label": "Conversation", children: [
12380
+ status === "loading" || status === "resolving" ? /* @__PURE__ */ jsx92(LoadingTurns, {}) : null,
12381
+ status === "disconnected" ? /* @__PURE__ */ jsxs83("div", { className: "fdc-dead", children: [
12382
+ /* @__PURE__ */ jsx92("span", { className: "fdc-dead-icon", children: /* @__PURE__ */ jsx92("i", { className: "ph ph-plugs", "aria-hidden": "true" }) }),
12383
+ /* @__PURE__ */ jsx92("h3", { className: "fdc-dead-title", children: ctx.deadTitle || "The assistant isn\u2019t reachable" }),
12384
+ /* @__PURE__ */ jsx92("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." }),
12385
+ ctx.onReconnect ? /* @__PURE__ */ jsxs83("button", { type: "button", className: "fd-btn fd-btn-secondary fd-btn-sm", onClick: ctx.onReconnect, children: [
12386
+ /* @__PURE__ */ jsx92("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }),
12135
12387
  "Try again"
12136
12388
  ] }) : null
12137
12389
  ] }) : null,
12138
- empty ? renderEmpty ? renderEmpty() : /* @__PURE__ */ jsxs82("div", { className: "fdc-empty", children: [
12139
- /* @__PURE__ */ jsx91("span", { className: "fdc-empty-icon", children: /* @__PURE__ */ jsx91("i", { className: "ph ph-" + emptyIcon, "aria-hidden": "true" }) }),
12140
- /* @__PURE__ */ jsx91("h3", { className: "fdc-empty-title", children: emptyTitle }),
12141
- emptyDescription ? /* @__PURE__ */ jsx91("p", { className: "fdc-empty-body", children: emptyDescription }) : null,
12142
- /* @__PURE__ */ jsx91(Suggestions, { items: suggestions, onPick })
12390
+ empty ? renderEmpty ? renderEmpty() : /* @__PURE__ */ jsxs83("div", { className: "fdc-empty", children: [
12391
+ /* @__PURE__ */ jsx92("span", { className: "fdc-empty-icon", children: /* @__PURE__ */ jsx92("i", { className: "ph ph-" + emptyIcon, "aria-hidden": "true" }) }),
12392
+ /* @__PURE__ */ jsx92("h3", { className: "fdc-empty-title", children: emptyTitle }),
12393
+ emptyDescription ? /* @__PURE__ */ jsx92("p", { className: "fdc-empty-body", children: emptyDescription }) : null,
12394
+ /* @__PURE__ */ jsx92(Suggestions, { items: suggestions, onPick })
12143
12395
  ] }) : null,
12144
12396
  groups.map((g, i) => {
12145
12397
  const prev = groups[i - 1];
12146
12398
  const k = dayKey(g.messages[0].timestamp);
12147
12399
  const showDay = !!k && (!prev || dayKey(prev.messages[0].timestamp) !== k);
12148
- return /* @__PURE__ */ jsxs82(React60.Fragment, { children: [
12149
- showDay ? /* @__PURE__ */ jsx91("div", { className: "fdc-day", children: /* @__PURE__ */ jsx91("span", { children: dayLabel(k) }) }) : null,
12150
- /* @__PURE__ */ jsx91(ChatTurn, { group: g, ctx })
12400
+ return /* @__PURE__ */ jsxs83(React61.Fragment, { children: [
12401
+ showDay ? /* @__PURE__ */ jsx92("div", { className: "fdc-day", children: /* @__PURE__ */ jsx92("span", { children: dayLabel(k) }) }) : null,
12402
+ /* @__PURE__ */ jsx92(ChatTurn, { group: g, ctx })
12151
12403
  ] }, g.key || i);
12152
12404
  })
12153
12405
  ] }),
12154
- pill ? /* @__PURE__ */ jsxs82("button", { type: "button", className: "fdc-pill", onClick: () => toBottom(true), children: [
12155
- /* @__PURE__ */ jsx91("i", { className: "ph ph-arrow-down", "aria-hidden": "true" }),
12406
+ pill ? /* @__PURE__ */ jsxs83("button", { type: "button", className: "fdc-pill", onClick: () => toBottom(true), children: [
12407
+ /* @__PURE__ */ jsx92("i", { className: "ph ph-arrow-down", "aria-hidden": "true" }),
12156
12408
  pill,
12157
12409
  " new message",
12158
12410
  pill === 1 ? "" : "s"
@@ -12162,8 +12414,8 @@ function ChatTranscript({
12162
12414
  var TranscriptKit = { groupMessages };
12163
12415
 
12164
12416
  // src/components/chat/ChatComposer.tsx
12165
- import * as React61 from "react";
12166
- import { jsx as jsx92, jsxs as jsxs83 } from "react/jsx-runtime";
12417
+ import * as React62 from "react";
12418
+ import { jsx as jsx93, jsxs as jsxs84 } from "react/jsx-runtime";
12167
12419
  function ChatComposer({
12168
12420
  onSubmit,
12169
12421
  onStop,
@@ -12190,17 +12442,17 @@ function ChatComposer({
12190
12442
  onReject,
12191
12443
  onOpenAttachment
12192
12444
  }) {
12193
- const [text, setText] = React61.useState(draft || "");
12194
- const [trigger, setTrigger] = React61.useState(null);
12195
- const [mentionItems, setMentionItems] = React61.useState([]);
12196
- const [listening, setListening] = React61.useState(false);
12197
- const [notice, setNotice] = React61.useState(null);
12198
- const editor = React61.useRef(null);
12199
- const wrap = React61.useRef(null);
12200
- const stopVoice = React61.useRef(null);
12445
+ const [text, setText] = React62.useState(draft || "");
12446
+ const [trigger, setTrigger] = React62.useState(null);
12447
+ const [mentionItems, setMentionItems] = React62.useState([]);
12448
+ const [listening, setListening] = React62.useState(false);
12449
+ const [notice, setNotice] = React62.useState(null);
12450
+ const editor = React62.useRef(null);
12451
+ const wrap = React62.useRef(null);
12452
+ const stopVoice = React62.useRef(null);
12201
12453
  const staged = useStagedFiles(fileUploadHandler, { onError: () => {
12202
12454
  } });
12203
- React61.useEffect(() => {
12455
+ React62.useEffect(() => {
12204
12456
  if (draft != null && draft !== text) setText(draft);
12205
12457
  }, [draft]);
12206
12458
  const change = (v) => {
@@ -12236,7 +12488,7 @@ function ChatComposer({
12236
12488
  e.preventDefault();
12237
12489
  staged.add(found.files);
12238
12490
  };
12239
- React61.useEffect(() => {
12491
+ React62.useEffect(() => {
12240
12492
  if (!trigger || trigger.type !== "mention" || !mentionSources) {
12241
12493
  setMentionItems([]);
12242
12494
  return;
@@ -12254,7 +12506,7 @@ function ChatComposer({
12254
12506
  const q = (trigger.query || "").toLowerCase();
12255
12507
  setMentionItems(mentionSources.filter((m) => !q || (m.label + " " + (m.description || "")).toLowerCase().includes(q)));
12256
12508
  }, [trigger, mentionSources]);
12257
- const slashItems = React61.useMemo(() => {
12509
+ const slashItems = React62.useMemo(() => {
12258
12510
  if (!trigger || trigger.type !== "slash" || !slashCommands) return [];
12259
12511
  const q = (trigger.query || "").toLowerCase();
12260
12512
  return slashCommands.filter((c) => !q || (c.id + " " + c.label + " " + (c.description || "")).toLowerCase().includes(q));
@@ -12268,7 +12520,7 @@ function ChatComposer({
12268
12520
  description: it.description,
12269
12521
  icon: it.icon,
12270
12522
  meta: mention.meta,
12271
- shortcut: slash.shortcut ? /* @__PURE__ */ jsx92(KeyHint, { keys: slash.shortcut, size: "sm" }) : void 0,
12523
+ shortcut: slash.shortcut ? /* @__PURE__ */ jsx93(KeyHint, { keys: slash.shortcut, size: "sm" }) : void 0,
12272
12524
  onSelect: () => {
12273
12525
  const insert = trigger.type === "slash" ? slash.immediate ? "/" + slash.id : "/" + slash.id + " " : "@" + (mention.value || mention.label) + " ";
12274
12526
  editor.current && editor.current.replaceRange(trigger.from, trigger.to, insert);
@@ -12327,14 +12579,14 @@ function ChatComposer({
12327
12579
  stopVoice.current = typeof res === "function" ? res : () => {
12328
12580
  };
12329
12581
  };
12330
- return /* @__PURE__ */ jsxs83("div", { className: "fdc-composer" + (disabled ? " is-disabled" : "") + (narrow ? " is-narrow" : ""), children: [
12331
- queue.length ? /* @__PURE__ */ jsx92("div", { className: "fdc-queue", "aria-label": "Queued messages", children: queue.map((q) => /* @__PURE__ */ jsxs83("div", { className: "fdc-queue-row", children: [
12332
- /* @__PURE__ */ jsx92("i", { className: "ph ph-clock-countdown", "aria-hidden": "true" }),
12333
- /* @__PURE__ */ jsx92("span", { className: "fdc-queue-text", title: truncationTitle(q.text || (q.attachments ? q.attachments.length + " file(s)" : "")), children: q.text || (q.attachments ? q.attachments.length + " file(s)" : "") }),
12334
- onRemoveQueued ? /* @__PURE__ */ jsx92("button", { type: "button", className: "fdc-queue-x", onClick: () => onRemoveQueued(q.id), "aria-label": "Remove queued message", children: /* @__PURE__ */ jsx92("i", { className: "ph ph-x", "aria-hidden": "true" }) }) : null
12582
+ return /* @__PURE__ */ jsxs84("div", { className: "fdc-composer" + (disabled ? " is-disabled" : "") + (narrow ? " is-narrow" : ""), children: [
12583
+ queue.length ? /* @__PURE__ */ jsx93("div", { className: "fdc-queue", "aria-label": "Queued messages", children: queue.map((q) => /* @__PURE__ */ jsxs84("div", { className: "fdc-queue-row", children: [
12584
+ /* @__PURE__ */ jsx93("i", { className: "ph ph-clock-countdown", "aria-hidden": "true" }),
12585
+ /* @__PURE__ */ jsx93("span", { className: "fdc-queue-text", title: truncationTitle(q.text || (q.attachments ? q.attachments.length + " file(s)" : "")), children: q.text || (q.attachments ? q.attachments.length + " file(s)" : "") }),
12586
+ onRemoveQueued ? /* @__PURE__ */ jsx93("button", { type: "button", className: "fdc-queue-x", onClick: () => onRemoveQueued(q.id), "aria-label": "Remove queued message", children: /* @__PURE__ */ jsx93("i", { className: "ph ph-x", "aria-hidden": "true" }) }) : null
12335
12587
  ] }, q.id)) }) : null,
12336
12588
  sessionBar,
12337
- /* @__PURE__ */ jsx92(
12589
+ /* @__PURE__ */ jsx93(
12338
12590
  Dropzone,
12339
12591
  {
12340
12592
  className: "fdc-field",
@@ -12348,9 +12600,9 @@ function ChatComposer({
12348
12600
  disabled: !fileUploadHandler || disabled,
12349
12601
  label: "Drop to attach",
12350
12602
  hint: acceptFiles ? acceptFiles.replace(/,/g, " \xB7 ") : void 0,
12351
- children: /* @__PURE__ */ jsxs83("div", { ref: wrap, className: "fdc-field-inner", children: [
12352
- staged.items.length ? /* @__PURE__ */ jsx92("div", { className: "fdc-staged", children: /* @__PURE__ */ jsx92(FileStrip, { files: staged.items, size: narrow ? 60 : 68, onRemove: staged.remove, onRetry: staged.retry, onOpen: onOpenAttachment }) }) : null,
12353
- /* @__PURE__ */ jsx92(
12603
+ children: /* @__PURE__ */ jsxs84("div", { ref: wrap, className: "fdc-field-inner", children: [
12604
+ staged.items.length ? /* @__PURE__ */ jsx93("div", { className: "fdc-staged", children: /* @__PURE__ */ jsx93(FileStrip, { files: staged.items, size: narrow ? 60 : 68, onRemove: staged.remove, onRetry: staged.retry, onOpen: onOpenAttachment }) }) : null,
12605
+ /* @__PURE__ */ jsx93(
12354
12606
  MarkdownEditor,
12355
12607
  {
12356
12608
  ref: editor,
@@ -12369,33 +12621,33 @@ function ChatComposer({
12369
12621
  ariaLabel: "Message"
12370
12622
  }
12371
12623
  ),
12372
- /* @__PURE__ */ jsxs83("div", { className: "fdc-tools", children: [
12373
- fileUploadHandler ? /* @__PURE__ */ jsx92(FilePickButton, { onFiles: staged.add, onReject: (r) => flash(r[0].message), accept: acceptFiles, maxFileSize, label: "Attach files", icon: "plus" }) : null,
12374
- voiceHandler ? /* @__PURE__ */ jsx92("button", { type: "button", className: "fd-attachbtn" + (listening ? " is-live" : ""), onClick: voice, "aria-pressed": listening, "aria-label": listening ? "Stop dictation" : "Dictate", children: /* @__PURE__ */ jsx92("i", { className: "ph ph-" + (listening ? "waveform" : "microphone"), "aria-hidden": "true" }) }) : null,
12624
+ /* @__PURE__ */ jsxs84("div", { className: "fdc-tools", children: [
12625
+ fileUploadHandler ? /* @__PURE__ */ jsx93(FilePickButton, { onFiles: staged.add, onReject: (r) => flash(r[0].message), accept: acceptFiles, maxFileSize, label: "Attach files", icon: "plus" }) : null,
12626
+ voiceHandler ? /* @__PURE__ */ jsx93("button", { type: "button", className: "fd-attachbtn" + (listening ? " is-live" : ""), onClick: voice, "aria-pressed": listening, "aria-label": listening ? "Stop dictation" : "Dictate", children: /* @__PURE__ */ jsx93("i", { className: "ph ph-" + (listening ? "waveform" : "microphone"), "aria-hidden": "true" }) }) : null,
12375
12627
  toolbarExtras,
12376
- /* @__PURE__ */ jsx92("span", { className: "fdc-tools-gap" }),
12377
- maxLength && text.length > maxLength * 0.6 ? /* @__PURE__ */ jsxs83("span", { className: "fdc-count fd-tabular" + (text.length > maxLength * 0.95 ? " is-hot" : ""), children: [
12628
+ /* @__PURE__ */ jsx93("span", { className: "fdc-tools-gap" }),
12629
+ maxLength && text.length > maxLength * 0.6 ? /* @__PURE__ */ jsxs84("span", { className: "fdc-count fd-tabular" + (text.length > maxLength * 0.95 ? " is-hot" : ""), children: [
12378
12630
  text.length,
12379
12631
  "/",
12380
12632
  maxLength
12381
12633
  ] }) : null,
12382
- busy ? /* @__PURE__ */ jsxs83("button", { type: "button", className: "fdc-stop", onClick: onStop, "aria-label": "Stop generating", children: [
12383
- /* @__PURE__ */ jsx92("i", { className: "ph ph-stop-circle", "aria-hidden": "true" }),
12384
- /* @__PURE__ */ jsx92("span", { children: "Stop" })
12385
- ] }) : /* @__PURE__ */ jsxs83("button", { type: "button", className: "fdc-send", onClick: submit, disabled: !canSend, "aria-label": "Send message", children: [
12386
- /* @__PURE__ */ jsx92("i", { className: "ph ph-paper-plane-right", "aria-hidden": "true" }),
12387
- /* @__PURE__ */ jsx92("span", { className: "fdc-send-label", children: "Send" })
12634
+ busy ? /* @__PURE__ */ jsxs84("button", { type: "button", className: "fdc-stop", onClick: onStop, "aria-label": "Stop generating", children: [
12635
+ /* @__PURE__ */ jsx93("i", { className: "ph ph-stop-circle", "aria-hidden": "true" }),
12636
+ /* @__PURE__ */ jsx93("span", { children: "Stop" })
12637
+ ] }) : /* @__PURE__ */ jsxs84("button", { type: "button", className: "fdc-send", onClick: submit, disabled: !canSend, "aria-label": "Send message", children: [
12638
+ /* @__PURE__ */ jsx93("i", { className: "ph ph-paper-plane-right", "aria-hidden": "true" }),
12639
+ /* @__PURE__ */ jsx93("span", { className: "fdc-send-label", children: "Send" })
12388
12640
  ] })
12389
12641
  ] })
12390
12642
  ] })
12391
12643
  }
12392
12644
  ),
12393
- notice ? /* @__PURE__ */ jsxs83("div", { className: "fdc-notice", role: "status", children: [
12394
- /* @__PURE__ */ jsx92("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
12645
+ notice ? /* @__PURE__ */ jsxs84("div", { className: "fdc-notice", role: "status", children: [
12646
+ /* @__PURE__ */ jsx93("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
12395
12647
  notice
12396
12648
  ] }) : null,
12397
- hint && !notice ? /* @__PURE__ */ jsx92("div", { className: "fdc-hint", children: hint }) : null,
12398
- /* @__PURE__ */ jsx92(
12649
+ hint && !notice ? /* @__PURE__ */ jsx93("div", { className: "fdc-hint", children: hint }) : null,
12650
+ /* @__PURE__ */ jsx93(
12399
12651
  Popover,
12400
12652
  {
12401
12653
  open: menuOpen,
@@ -12409,12 +12661,12 @@ function ChatComposer({
12409
12661
  returnFocus: false,
12410
12662
  closeOnOutside: true,
12411
12663
  label: trigger && trigger.type === "slash" ? "Commands" : "Mentions",
12412
- children: /* @__PURE__ */ jsx92(
12664
+ children: /* @__PURE__ */ jsx93(
12413
12665
  Menu,
12414
12666
  {
12415
12667
  items: menuItems,
12416
12668
  autoFocus: false,
12417
- header: /* @__PURE__ */ jsx92("div", { className: "fd-pop-group", children: trigger && trigger.type === "slash" ? "Commands" : "Attach context" }),
12669
+ header: /* @__PURE__ */ jsx93("div", { className: "fd-pop-group", children: trigger && trigger.type === "slash" ? "Commands" : "Attach context" }),
12418
12670
  onClose: () => setTrigger(null)
12419
12671
  }
12420
12672
  )
@@ -12424,12 +12676,12 @@ function ChatComposer({
12424
12676
  }
12425
12677
 
12426
12678
  // src/components/chat/ChatSessionBar.tsx
12427
- import * as React62 from "react";
12428
- import { jsx as jsx93, jsxs as jsxs84 } from "react/jsx-runtime";
12679
+ import * as React63 from "react";
12680
+ import { jsx as jsx94, jsxs as jsxs85 } from "react/jsx-runtime";
12429
12681
  var compact2 = meterFormats.compact;
12430
12682
  function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extras }) {
12431
- const [open2, setOpen] = React62.useState(false);
12432
- const anchor = React62.useRef(null);
12683
+ const [open2, setOpen] = React63.useState(false);
12684
+ const anchor = React63.useRef(null);
12433
12685
  const stats = sessionStats || null;
12434
12686
  const cu = contextUsage || null;
12435
12687
  const limits = usageLimits || null;
@@ -12444,9 +12696,9 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
12444
12696
  if (stats && stats.runningTasks) bits.push(stats.runningTasks + " running task" + (stats.runningTasks === 1 ? "" : "s"));
12445
12697
  if (cu) bits.push(pct + "% context");
12446
12698
  const expandable = !!(cu || limits);
12447
- return /* @__PURE__ */ jsxs84(React62.Fragment, { children: [
12448
- /* @__PURE__ */ jsxs84("div", { className: "fdc-bar", children: [
12449
- /* @__PURE__ */ jsxs84(
12699
+ return /* @__PURE__ */ jsxs85(React63.Fragment, { children: [
12700
+ /* @__PURE__ */ jsxs85("div", { className: "fdc-bar", children: [
12701
+ /* @__PURE__ */ jsxs85(
12450
12702
  "button",
12451
12703
  {
12452
12704
  type: "button",
@@ -12457,15 +12709,15 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
12457
12709
  "aria-expanded": expandable ? open2 : void 0,
12458
12710
  "aria-label": expandable ? "Usage details" : void 0,
12459
12711
  children: [
12460
- cu ? /* @__PURE__ */ jsx93("span", { className: "fdc-bar-mini", "aria-hidden": "true", children: /* @__PURE__ */ jsx93(SegmentedMeter, { total, segments: cu.segments, height: 4, showTotal: false }) }) : null,
12461
- /* @__PURE__ */ jsx93("span", { className: "fdc-bar-text", title: truncationTitle(bits.join(" \xB7 ")), children: bits.join(" \xB7 ") }),
12462
- expandable ? /* @__PURE__ */ jsx93("i", { className: "ph ph-caret-right fdc-bar-caret", "aria-hidden": "true" }) : null
12712
+ cu ? /* @__PURE__ */ jsx94("span", { className: "fdc-bar-mini", "aria-hidden": "true", children: /* @__PURE__ */ jsx94(SegmentedMeter, { total, segments: cu.segments, height: 4, showTotal: false }) }) : null,
12713
+ /* @__PURE__ */ jsx94("span", { className: "fdc-bar-text", title: truncationTitle(bits.join(" \xB7 ")), children: bits.join(" \xB7 ") }),
12714
+ expandable ? /* @__PURE__ */ jsx94("i", { className: "ph ph-caret-right fdc-bar-caret", "aria-hidden": "true" }) : null
12463
12715
  ]
12464
12716
  }
12465
12717
  ),
12466
12718
  extras
12467
12719
  ] }),
12468
- /* @__PURE__ */ jsx93(
12720
+ /* @__PURE__ */ jsx94(
12469
12721
  Popover,
12470
12722
  {
12471
12723
  open: open2,
@@ -12476,15 +12728,15 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
12476
12728
  maxHeight: 460,
12477
12729
  padded: true,
12478
12730
  label: "Usage",
12479
- footer: onClear ? /* @__PURE__ */ jsxs84("button", { type: "button", className: "fdc-usage-clear", onClick: () => {
12731
+ footer: onClear ? /* @__PURE__ */ jsxs85("button", { type: "button", className: "fdc-usage-clear", onClick: () => {
12480
12732
  setOpen(false);
12481
12733
  onClear();
12482
12734
  }, children: [
12483
- /* @__PURE__ */ jsx93("i", { className: "ph ph-trash", "aria-hidden": "true" }),
12735
+ /* @__PURE__ */ jsx94("i", { className: "ph ph-trash", "aria-hidden": "true" }),
12484
12736
  "Clear conversation"
12485
12737
  ] }) : void 0,
12486
- children: /* @__PURE__ */ jsxs84("div", { className: "fdc-usage", children: [
12487
- cu ? /* @__PURE__ */ jsx93("section", { className: "fdc-usage-sec", children: /* @__PURE__ */ jsx93(
12738
+ children: /* @__PURE__ */ jsxs85("div", { className: "fdc-usage", children: [
12739
+ cu ? /* @__PURE__ */ jsx94("section", { className: "fdc-usage-sec", children: /* @__PURE__ */ jsx94(
12488
12740
  SegmentedMeter,
12489
12741
  {
12490
12742
  total,
@@ -12496,9 +12748,9 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
12496
12748
  remainderLabel: "Free"
12497
12749
  }
12498
12750
  ) }) : null,
12499
- limits && limits.length ? /* @__PURE__ */ jsxs84("section", { className: "fdc-usage-sec", children: [
12500
- /* @__PURE__ */ jsx93("h4", { className: "fdc-usage-h", children: "Usage limits" }),
12501
- /* @__PURE__ */ jsx93("div", { className: "fdc-usage-rows", children: limits.map((l) => /* @__PURE__ */ jsx93(
12751
+ limits && limits.length ? /* @__PURE__ */ jsxs85("section", { className: "fdc-usage-sec", children: [
12752
+ /* @__PURE__ */ jsx94("h4", { className: "fdc-usage-h", children: "Usage limits" }),
12753
+ /* @__PURE__ */ jsx94("div", { className: "fdc-usage-rows", children: limits.map((l) => /* @__PURE__ */ jsx94(
12502
12754
  QuotaRow,
12503
12755
  {
12504
12756
  label: l.label,
@@ -12508,25 +12760,25 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
12508
12760
  l.id
12509
12761
  )) })
12510
12762
  ] }) : null,
12511
- stats ? /* @__PURE__ */ jsxs84("section", { className: "fdc-usage-sec fdc-usage-stats", children: [
12512
- stats.elapsedMs ? /* @__PURE__ */ jsxs84("div", { children: [
12513
- /* @__PURE__ */ jsx93("span", { children: "Session" }),
12514
- /* @__PURE__ */ jsx93("b", { className: "fd-tabular", children: formatDuration(stats.elapsedMs) })
12763
+ stats ? /* @__PURE__ */ jsxs85("section", { className: "fdc-usage-sec fdc-usage-stats", children: [
12764
+ stats.elapsedMs ? /* @__PURE__ */ jsxs85("div", { children: [
12765
+ /* @__PURE__ */ jsx94("span", { children: "Session" }),
12766
+ /* @__PURE__ */ jsx94("b", { className: "fd-tabular", children: formatDuration(stats.elapsedMs) })
12515
12767
  ] }) : null,
12516
- stats.tokens ? /* @__PURE__ */ jsxs84("div", { children: [
12517
- /* @__PURE__ */ jsx93("span", { children: "Tokens" }),
12518
- /* @__PURE__ */ jsx93("b", { className: "fd-tabular", children: stats.tokens.toLocaleString() })
12768
+ stats.tokens ? /* @__PURE__ */ jsxs85("div", { children: [
12769
+ /* @__PURE__ */ jsx94("span", { children: "Tokens" }),
12770
+ /* @__PURE__ */ jsx94("b", { className: "fd-tabular", children: stats.tokens.toLocaleString() })
12519
12771
  ] }) : null,
12520
- stats.costUsd != null ? /* @__PURE__ */ jsxs84("div", { children: [
12521
- /* @__PURE__ */ jsx93("span", { children: "Cost" }),
12522
- /* @__PURE__ */ jsxs84("b", { className: "fd-tabular", children: [
12772
+ stats.costUsd != null ? /* @__PURE__ */ jsxs85("div", { children: [
12773
+ /* @__PURE__ */ jsx94("span", { children: "Cost" }),
12774
+ /* @__PURE__ */ jsxs85("b", { className: "fd-tabular", children: [
12523
12775
  "$",
12524
12776
  Number(stats.costUsd).toFixed(3)
12525
12777
  ] })
12526
12778
  ] }) : null,
12527
- stats.turns ? /* @__PURE__ */ jsxs84("div", { children: [
12528
- /* @__PURE__ */ jsx93("span", { children: "Turns" }),
12529
- /* @__PURE__ */ jsx93("b", { className: "fd-tabular", children: stats.turns })
12779
+ stats.turns ? /* @__PURE__ */ jsxs85("div", { children: [
12780
+ /* @__PURE__ */ jsx94("span", { children: "Turns" }),
12781
+ /* @__PURE__ */ jsx94("b", { className: "fd-tabular", children: stats.turns })
12530
12782
  ] }) : null
12531
12783
  ] }) : null
12532
12784
  ] })
@@ -12565,7 +12817,7 @@ function ModelControls({
12565
12817
  disabled: m.disabled,
12566
12818
  checked: m.id === (current2 && current2.id),
12567
12819
  meta: m.meta,
12568
- shortcut: m.shortcut ? /* @__PURE__ */ jsx93(KeyHint, { keys: m.shortcut, size: "sm" }) : void 0,
12820
+ shortcut: m.shortcut ? /* @__PURE__ */ jsx94(KeyHint, { keys: m.shortcut, size: "sm" }) : void 0,
12569
12821
  onSelect: () => onModelChange && onModelChange(m.id)
12570
12822
  });
12571
12823
  const items = [{ kind: "section", label: "Models" }].concat(flat.map(item));
@@ -12578,15 +12830,15 @@ function ModelControls({
12578
12830
  items.push({ kind: "section", label: "Fast mode" });
12579
12831
  items.push({
12580
12832
  kind: "custom",
12581
- render: () => /* @__PURE__ */ jsxs84("label", { className: "fdc-switchrow", children: [
12582
- /* @__PURE__ */ jsx93("span", { children: fastModeLabel }),
12583
- /* @__PURE__ */ jsx93("input", { type: "checkbox", className: "fd-sr", checked: !!fastMode, onChange: (e) => onFastModeChange(e.target.checked) }),
12584
- /* @__PURE__ */ jsx93("span", { className: "fd-switch-track" + (fastMode ? " is-on" : ""), "aria-hidden": "true", children: /* @__PURE__ */ jsx93("span", { className: "fd-switch-thumb" }) })
12833
+ render: () => /* @__PURE__ */ jsxs85("label", { className: "fdc-switchrow", children: [
12834
+ /* @__PURE__ */ jsx94("span", { children: fastModeLabel }),
12835
+ /* @__PURE__ */ jsx94("input", { type: "checkbox", className: "fd-sr", checked: !!fastMode, onChange: (e) => onFastModeChange(e.target.checked) }),
12836
+ /* @__PURE__ */ jsx94("span", { className: "fd-switch-track" + (fastMode ? " is-on" : ""), "aria-hidden": "true", children: /* @__PURE__ */ jsx94("span", { className: "fd-switch-thumb" }) })
12585
12837
  ] })
12586
12838
  });
12587
12839
  }
12588
- return /* @__PURE__ */ jsxs84(React62.Fragment, { children: [
12589
- /* @__PURE__ */ jsx93(
12840
+ return /* @__PURE__ */ jsxs85(React63.Fragment, { children: [
12841
+ /* @__PURE__ */ jsx94(
12590
12842
  MenuButton,
12591
12843
  {
12592
12844
  items,
@@ -12597,7 +12849,7 @@ function ModelControls({
12597
12849
  title: "Choose a model"
12598
12850
  }
12599
12851
  ),
12600
- effortLevels && effortLevels.length ? /* @__PURE__ */ jsx93(
12852
+ effortLevels && effortLevels.length ? /* @__PURE__ */ jsx94(
12601
12853
  MenuButton,
12602
12854
  {
12603
12855
  placement: "top-end",
@@ -12618,7 +12870,7 @@ function ModelControls({
12618
12870
  }
12619
12871
 
12620
12872
  // src/components/chat/AgentChatPanel.tsx
12621
- import { jsx as jsx94, jsxs as jsxs85 } from "react/jsx-runtime";
12873
+ import { jsx as jsx95, jsxs as jsxs86 } from "react/jsx-runtime";
12622
12874
  var SURFACES = { sidebar: "is-sidebar", inline: "is-inline", page: "is-page", modal: "is-modal", sheet: "is-sheet" };
12623
12875
  function AgentChatPanel({
12624
12876
  /* required */
@@ -12702,11 +12954,11 @@ function AgentChatPanel({
12702
12954
  onFeedback,
12703
12955
  onEditMessage
12704
12956
  }) {
12705
- const [panelWidth, setPanelWidth] = React63.useState(width);
12706
- const [applied, setApplied] = React63.useState({});
12707
- const [draft, setDraft] = React63.useState("");
12708
- const dragging = React63.useRef(null);
12709
- React63.useEffect(() => setPanelWidth(width), [width]);
12957
+ const [panelWidth, setPanelWidth] = React64.useState(width);
12958
+ const [applied, setApplied] = React64.useState({});
12959
+ const [draft, setDraft] = React64.useState("");
12960
+ const dragging = React64.useRef(null);
12961
+ React64.useEffect(() => setPanelWidth(width), [width]);
12710
12962
  const engine = useChatEngine({
12711
12963
  contextType,
12712
12964
  contextId,
@@ -12772,7 +13024,7 @@ function AgentChatPanel({
12772
13024
  onReconnect: engine.reload,
12773
13025
  deadTitle: "The assistant isn\u2019t reachable"
12774
13026
  };
12775
- const sessionBar = /* @__PURE__ */ jsx94(
13027
+ const sessionBar = /* @__PURE__ */ jsx95(
12776
13028
  ChatSessionBar,
12777
13029
  {
12778
13030
  sessionStats,
@@ -12781,7 +13033,7 @@ function AgentChatPanel({
12781
13033
  onClear: engine.visible.length ? engine.clear : void 0
12782
13034
  }
12783
13035
  );
12784
- const modelControls = /* @__PURE__ */ jsx94(
13036
+ const modelControls = /* @__PURE__ */ jsx95(
12785
13037
  ModelControls,
12786
13038
  {
12787
13039
  models,
@@ -12796,7 +13048,7 @@ function AgentChatPanel({
12796
13048
  narrow
12797
13049
  }
12798
13050
  );
12799
- const threadMenu = threads && threads.length ? /* @__PURE__ */ jsx94(
13051
+ const threadMenu = threads && threads.length ? /* @__PURE__ */ jsx95(
12800
13052
  MenuButton,
12801
13053
  {
12802
13054
  variant: "ghost",
@@ -12823,7 +13075,7 @@ function AgentChatPanel({
12823
13075
  })))
12824
13076
  }
12825
13077
  ) : null;
12826
- return /* @__PURE__ */ jsxs85(
13078
+ return /* @__PURE__ */ jsxs86(
12827
13079
  "aside",
12828
13080
  {
12829
13081
  className: ["fdc-panel", SURFACES[surface] || SURFACES.sidebar, narrow ? "is-narrow" : "", className].filter(Boolean).join(" "),
@@ -12834,7 +13086,7 @@ function AgentChatPanel({
12834
13086
  },
12835
13087
  "aria-label": title,
12836
13088
  children: [
12837
- surface === "sidebar" && resizable ? /* @__PURE__ */ jsx94(
13089
+ surface === "sidebar" && resizable ? /* @__PURE__ */ jsx95(
12838
13090
  "div",
12839
13091
  {
12840
13092
  className: "fdc-grip",
@@ -12849,20 +13101,20 @@ function AgentChatPanel({
12849
13101
  }
12850
13102
  }
12851
13103
  ) : null,
12852
- showHeader ? /* @__PURE__ */ jsxs85("header", { className: "fdc-head", children: [
12853
- /* @__PURE__ */ jsx94("span", { className: "fdc-head-mark", "aria-hidden": "true", children: /* @__PURE__ */ jsx94("i", { className: "ph ph-" + assistantIcon }) }),
12854
- /* @__PURE__ */ jsxs85("span", { className: "fdc-head-titles", children: [
12855
- /* @__PURE__ */ jsx94("span", { className: "fdc-head-title", title: truncationTitle(title), children: title }),
12856
- subtitle ? /* @__PURE__ */ jsx94("span", { className: "fdc-head-sub", title: truncationTitle(subtitle), children: subtitle }) : null
13104
+ showHeader ? /* @__PURE__ */ jsxs86("header", { className: "fdc-head", children: [
13105
+ /* @__PURE__ */ jsx95("span", { className: "fdc-head-mark", "aria-hidden": "true", children: /* @__PURE__ */ jsx95("i", { className: "ph ph-" + assistantIcon }) }),
13106
+ /* @__PURE__ */ jsxs86("span", { className: "fdc-head-titles", children: [
13107
+ /* @__PURE__ */ jsx95("span", { className: "fdc-head-title", title: truncationTitle(title), children: title }),
13108
+ subtitle ? /* @__PURE__ */ jsx95("span", { className: "fdc-head-sub", title: truncationTitle(subtitle), children: subtitle }) : null
12857
13109
  ] }),
12858
- /* @__PURE__ */ jsxs85("span", { className: "fdc-head-acts", children: [
13110
+ /* @__PURE__ */ jsxs86("span", { className: "fdc-head-acts", children: [
12859
13111
  headerActions,
12860
13112
  threadMenu,
12861
- onNewThread ? /* @__PURE__ */ jsx94("button", { type: "button", className: "fdc-iconbtn", onClick: onNewThread, "aria-label": "New conversation", title: "New conversation", children: /* @__PURE__ */ jsx94("i", { className: "ph ph-plus", "aria-hidden": "true" }) }) : null,
12862
- onClose ? /* @__PURE__ */ jsx94("button", { type: "button", className: "fdc-iconbtn", onClick: onClose, "aria-label": "Close panel", title: "Close", children: /* @__PURE__ */ jsx94("i", { className: "ph ph-x", "aria-hidden": "true" }) }) : null
13113
+ onNewThread ? /* @__PURE__ */ jsx95("button", { type: "button", className: "fdc-iconbtn", onClick: onNewThread, "aria-label": "New conversation", title: "New conversation", children: /* @__PURE__ */ jsx95("i", { className: "ph ph-plus", "aria-hidden": "true" }) }) : null,
13114
+ onClose ? /* @__PURE__ */ jsx95("button", { type: "button", className: "fdc-iconbtn", onClick: onClose, "aria-label": "Close panel", title: "Close", children: /* @__PURE__ */ jsx95("i", { className: "ph ph-x", "aria-hidden": "true" }) }) : null
12863
13115
  ] })
12864
13116
  ] }) : null,
12865
- /* @__PURE__ */ jsx94(
13117
+ /* @__PURE__ */ jsx95(
12866
13118
  ChatTranscript,
12867
13119
  {
12868
13120
  messages: engine.visible,
@@ -12877,7 +13129,7 @@ function AgentChatPanel({
12877
13129
  renderEmpty
12878
13130
  }
12879
13131
  ),
12880
- /* @__PURE__ */ jsx94(
13132
+ /* @__PURE__ */ jsx95(
12881
13133
  ChatComposer,
12882
13134
  {
12883
13135
  onSubmit: (text, atts) => engine.send(text, atts),
@@ -12910,8 +13162,8 @@ function AgentChatPanel({
12910
13162
  }
12911
13163
 
12912
13164
  // src/components/files/FileViewer.tsx
12913
- import * as React64 from "react";
12914
- import { jsx as jsx95, jsxs as jsxs86 } from "react/jsx-runtime";
13165
+ import * as React65 from "react";
13166
+ import { jsx as jsx96, jsxs as jsxs87 } from "react/jsx-runtime";
12915
13167
  function previewKindOf(file) {
12916
13168
  const mime = (file.mime || "").toLowerCase();
12917
13169
  const ext = extensionOf(file.name || "");
@@ -12967,13 +13219,13 @@ function parseDelimited(text, delimiter) {
12967
13219
  return rows;
12968
13220
  }
12969
13221
  function usePreview(file, kind, resolveUrl) {
12970
- const [state, setState] = React64.useState({ status: "loading" });
12971
- const [attempt, setAttempt] = React64.useState(0);
12972
- const resolveRef = React64.useRef(resolveUrl);
12973
- React64.useEffect(() => {
13222
+ const [state, setState] = React65.useState({ status: "loading" });
13223
+ const [attempt, setAttempt] = React65.useState(0);
13224
+ const resolveRef = React65.useRef(resolveUrl);
13225
+ React65.useEffect(() => {
12974
13226
  resolveRef.current = resolveUrl;
12975
13227
  }, [resolveUrl]);
12976
- React64.useEffect(() => {
13228
+ React65.useEffect(() => {
12977
13229
  if (kind === "none") {
12978
13230
  setState({ status: "ready" });
12979
13231
  return;
@@ -13003,19 +13255,19 @@ function usePreview(file, kind, resolveUrl) {
13003
13255
  if (ac) ac.abort();
13004
13256
  };
13005
13257
  }, [file.id, kind, attempt]);
13006
- return { ...state, retry: React64.useCallback(() => setAttempt((a) => a + 1), []) };
13258
+ return { ...state, retry: React65.useCallback(() => setAttempt((a) => a + 1), []) };
13007
13259
  }
13008
13260
  function PreviewBody({ file, kind, state }) {
13009
- if (kind === "image") return /* @__PURE__ */ jsx95("img", { className: "fd-fv-image", src: state.url, alt: file.name || "Preview" });
13010
- if (kind === "pdf") return /* @__PURE__ */ jsx95("iframe", { className: "fd-fv-pdf", src: state.url, title: file.name || "PDF preview" });
13011
- if (kind === "markdown") return /* @__PURE__ */ jsx95(Markdown, { className: "fd-fv-markdown", source: state.text || "" });
13261
+ if (kind === "image") return /* @__PURE__ */ jsx96("img", { className: "fd-fv-image", src: state.url, alt: file.name || "Preview" });
13262
+ if (kind === "pdf") return /* @__PURE__ */ jsx96("iframe", { className: "fd-fv-pdf", src: state.url, title: file.name || "PDF preview" });
13263
+ if (kind === "markdown") return /* @__PURE__ */ jsx96(Markdown, { className: "fd-fv-markdown", source: state.text || "" });
13012
13264
  if (kind === "json") {
13013
13265
  let pretty = state.text || "";
13014
13266
  try {
13015
13267
  pretty = JSON.stringify(JSON.parse(pretty), null, 2);
13016
13268
  } catch {
13017
13269
  }
13018
- return /* @__PURE__ */ jsx95(CodeBlock, { code: pretty, language: "json" });
13270
+ return /* @__PURE__ */ jsx96(CodeBlock, { code: pretty, language: "json" });
13019
13271
  }
13020
13272
  if (kind === "csv") {
13021
13273
  const tsv = extensionOf(file.name || "") === "tsv" || (file.mime || "").toLowerCase().includes("tab-separated");
@@ -13023,12 +13275,12 @@ function PreviewBody({ file, kind, state }) {
13023
13275
  const head = rows[0] || [];
13024
13276
  const dataRows = rows.slice(1);
13025
13277
  const shown = dataRows.slice(0, FILE_VIEWER_CSV_ROW_LIMIT);
13026
- return /* @__PURE__ */ jsxs86("div", { className: "fd-fv-csv", children: [
13027
- /* @__PURE__ */ jsxs86("table", { className: "fd-fv-csv-table", children: [
13028
- /* @__PURE__ */ jsx95("thead", { children: /* @__PURE__ */ jsx95("tr", { children: head.map((c, i) => /* @__PURE__ */ jsx95("th", { children: c }, i)) }) }),
13029
- /* @__PURE__ */ jsx95("tbody", { children: shown.map((r, ri) => /* @__PURE__ */ jsx95("tr", { children: head.map((_, ci) => /* @__PURE__ */ jsx95("td", { children: r[ci] ?? "" }, ci)) }, ri)) })
13278
+ return /* @__PURE__ */ jsxs87("div", { className: "fd-fv-csv", children: [
13279
+ /* @__PURE__ */ jsxs87("table", { className: "fd-fv-csv-table", children: [
13280
+ /* @__PURE__ */ jsx96("thead", { children: /* @__PURE__ */ jsx96("tr", { children: head.map((c, i) => /* @__PURE__ */ jsx96("th", { children: c }, i)) }) }),
13281
+ /* @__PURE__ */ jsx96("tbody", { children: shown.map((r, ri) => /* @__PURE__ */ jsx96("tr", { children: head.map((_, ci) => /* @__PURE__ */ jsx96("td", { children: r[ci] ?? "" }, ci)) }, ri)) })
13030
13282
  ] }),
13031
- dataRows.length > FILE_VIEWER_CSV_ROW_LIMIT ? /* @__PURE__ */ jsxs86("p", { className: "fd-fv-csv-note fd-body-sm fd-muted", children: [
13283
+ dataRows.length > FILE_VIEWER_CSV_ROW_LIMIT ? /* @__PURE__ */ jsxs87("p", { className: "fd-fv-csv-note fd-body-sm fd-muted", children: [
13032
13284
  "Showing the first ",
13033
13285
  FILE_VIEWER_CSV_ROW_LIMIT.toLocaleString(),
13034
13286
  " of ",
@@ -13037,24 +13289,24 @@ function PreviewBody({ file, kind, state }) {
13037
13289
  ] }) : null
13038
13290
  ] });
13039
13291
  }
13040
- if (kind === "text") return /* @__PURE__ */ jsx95(CodeBlock, { code: state.text || "", language: extensionOf(file.name || "") || void 0 });
13041
- return /* @__PURE__ */ jsxs86("div", { className: "fd-fv-fallback", children: [
13042
- /* @__PURE__ */ jsx95("span", { className: "fd-fv-fallback-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx95("i", { className: "ph ph-" + iconForMime(file.mime, file.name) }) }),
13043
- /* @__PURE__ */ jsx95("span", { className: "fd-fv-fallback-title", children: "No preview available" }),
13044
- /* @__PURE__ */ jsxs86("span", { className: "fd-fv-fallback-meta", children: [
13292
+ if (kind === "text") return /* @__PURE__ */ jsx96(CodeBlock, { code: state.text || "", language: extensionOf(file.name || "") || void 0 });
13293
+ return /* @__PURE__ */ jsxs87("div", { className: "fd-fv-fallback", children: [
13294
+ /* @__PURE__ */ jsx96("span", { className: "fd-fv-fallback-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx96("i", { className: "ph ph-" + iconForMime(file.mime, file.name) }) }),
13295
+ /* @__PURE__ */ jsx96("span", { className: "fd-fv-fallback-title", children: "No preview available" }),
13296
+ /* @__PURE__ */ jsxs87("span", { className: "fd-fv-fallback-meta", children: [
13045
13297
  file.mime || "Unknown type",
13046
13298
  file.size ? " \xB7 " + formatBytes(file.size) : ""
13047
13299
  ] })
13048
13300
  ] });
13049
13301
  }
13050
13302
  function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", onClose, actions, className = "" }) {
13051
- const kind = React64.useMemo(() => previewKindOf(file), [file]);
13303
+ const kind = React65.useMemo(() => previewKindOf(file), [file]);
13052
13304
  const preview = usePreview(file, kind, resolveUrl);
13053
- const [tab, setTab] = React64.useState("preview");
13054
- const [downloading, setDownloading] = React64.useState(false);
13055
- const [downloadError, setDownloadError] = React64.useState(null);
13305
+ const [tab, setTab] = React65.useState("preview");
13306
+ const [downloading, setDownloading] = React65.useState(false);
13307
+ const [downloadError, setDownloadError] = React65.useState(null);
13056
13308
  const hasSide = sidePanel != null;
13057
- React64.useEffect(() => {
13309
+ React65.useEffect(() => {
13058
13310
  setTab("preview");
13059
13311
  }, [file.id]);
13060
13312
  const download = () => {
@@ -13070,29 +13322,29 @@ function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", o
13070
13322
  a.remove();
13071
13323
  }).catch((err) => setDownloadError(err && err.message || "Download failed.")).finally(() => setDownloading(false));
13072
13324
  };
13073
- return /* @__PURE__ */ jsxs86(
13325
+ return /* @__PURE__ */ jsxs87(
13074
13326
  "section",
13075
13327
  {
13076
13328
  className: ["fd-fv", hasSide && tab === "side" ? "is-tab-side" : "is-tab-preview", className].filter(Boolean).join(" "),
13077
13329
  "aria-label": file.name || "File",
13078
13330
  children: [
13079
- /* @__PURE__ */ jsxs86("header", { className: "fd-fv-head", children: [
13080
- /* @__PURE__ */ jsx95("span", { className: "fd-fv-head-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx95("i", { className: "ph ph-" + iconForMime(file.mime, file.name) }) }),
13081
- /* @__PURE__ */ jsxs86("span", { className: "fd-fv-head-titles", children: [
13082
- /* @__PURE__ */ jsx95("span", { className: "fd-fv-head-title", title: file.name, children: file.name }),
13083
- /* @__PURE__ */ jsxs86("span", { className: "fd-fv-head-meta", children: [
13331
+ /* @__PURE__ */ jsxs87("header", { className: "fd-fv-head", children: [
13332
+ /* @__PURE__ */ jsx96("span", { className: "fd-fv-head-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx96("i", { className: "ph ph-" + iconForMime(file.mime, file.name) }) }),
13333
+ /* @__PURE__ */ jsxs87("span", { className: "fd-fv-head-titles", children: [
13334
+ /* @__PURE__ */ jsx96("span", { className: "fd-fv-head-title", title: file.name, children: file.name }),
13335
+ /* @__PURE__ */ jsxs87("span", { className: "fd-fv-head-meta", children: [
13084
13336
  file.mime || "Unknown type",
13085
13337
  file.size ? " \xB7 " + formatBytes(file.size) : ""
13086
13338
  ] })
13087
13339
  ] }),
13088
- /* @__PURE__ */ jsxs86("span", { className: "fd-fv-head-actions", children: [
13340
+ /* @__PURE__ */ jsxs87("span", { className: "fd-fv-head-actions", children: [
13089
13341
  actions,
13090
- /* @__PURE__ */ jsx95(Button, { variant: "secondary", size: "sm", icon: "download-simple", loading: downloading, onClick: download, children: "Download" }),
13091
- onClose ? /* @__PURE__ */ jsx95(IconButton, { icon: "x", label: "Close", onClick: onClose }) : null
13342
+ /* @__PURE__ */ jsx96(Button, { variant: "secondary", size: "sm", icon: "download-simple", loading: downloading, onClick: download, children: "Download" }),
13343
+ onClose ? /* @__PURE__ */ jsx96(IconButton, { icon: "x", label: "Close", onClick: onClose }) : null
13092
13344
  ] })
13093
13345
  ] }),
13094
- downloadError ? /* @__PURE__ */ jsx95("div", { className: "fd-fv-download-error", role: "alert", children: downloadError }) : null,
13095
- hasSide ? /* @__PURE__ */ jsx95(
13346
+ downloadError ? /* @__PURE__ */ jsx96("div", { className: "fd-fv-download-error", role: "alert", children: downloadError }) : null,
13347
+ hasSide ? /* @__PURE__ */ jsx96(
13096
13348
  Tabs,
13097
13349
  {
13098
13350
  className: "fd-fv-tabs",
@@ -13101,19 +13353,19 @@ function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", o
13101
13353
  onChange: (v) => setTab(v)
13102
13354
  }
13103
13355
  ) : null,
13104
- /* @__PURE__ */ jsxs86("div", { className: "fd-fv-body", children: [
13105
- /* @__PURE__ */ jsx95("div", { className: "fd-fv-preview", role: "region", "aria-label": "Preview of " + (file.name || "file"), children: /* @__PURE__ */ jsx95(
13356
+ /* @__PURE__ */ jsxs87("div", { className: "fd-fv-body", children: [
13357
+ /* @__PURE__ */ jsx96("div", { className: "fd-fv-preview", role: "region", "aria-label": "Preview of " + (file.name || "file"), children: /* @__PURE__ */ jsx96(
13106
13358
  LoadingRegion,
13107
13359
  {
13108
13360
  state: preview.status === "loading" ? "loading" : preview.status === "error" ? "error" : "ready",
13109
13361
  error: preview.error,
13110
13362
  label: "Loading preview of " + (file.name || "file"),
13111
13363
  onRetry: preview.status === "error" ? preview.retry : void 0,
13112
- skeleton: /* @__PURE__ */ jsx95(Skeleton, { shape: "card", h: 220 }),
13113
- children: /* @__PURE__ */ jsx95(PreviewBody, { file, kind, state: preview })
13364
+ skeleton: /* @__PURE__ */ jsx96(Skeleton, { shape: "card", h: 220 }),
13365
+ children: /* @__PURE__ */ jsx96(PreviewBody, { file, kind, state: preview })
13114
13366
  }
13115
13367
  ) }),
13116
- hasSide ? /* @__PURE__ */ jsx95("div", { className: "fd-fv-side", role: "region", "aria-label": sidePanelLabel, children: sidePanel }) : null
13368
+ hasSide ? /* @__PURE__ */ jsx96("div", { className: "fd-fv-side", role: "region", "aria-label": sidePanelLabel, children: sidePanel }) : null
13117
13369
  ] })
13118
13370
  ]
13119
13371
  }
@@ -13121,8 +13373,8 @@ function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", o
13121
13373
  }
13122
13374
 
13123
13375
  // src/components/files/FileBrowser.tsx
13124
- import * as React65 from "react";
13125
- import { Fragment as Fragment27, jsx as jsx96, jsxs as jsxs87 } from "react/jsx-runtime";
13376
+ import * as React66 from "react";
13377
+ import { Fragment as Fragment28, jsx as jsx97, jsxs as jsxs88 } from "react/jsx-runtime";
13126
13378
  function childrenOf(folders, parentId) {
13127
13379
  return folders.filter((f) => f.parentId === parentId).sort((a, b) => a.name.localeCompare(b.name));
13128
13380
  }
@@ -13194,8 +13446,8 @@ function FolderPickerMenu({
13194
13446
  }) {
13195
13447
  const panel = useInlinePanel();
13196
13448
  const { open: open2, setOpen, ref, zIndex } = panel;
13197
- return /* @__PURE__ */ jsxs87("span", { className: "fd-fb-menu-anchor", ref, children: [
13198
- /* @__PURE__ */ jsx96(
13449
+ return /* @__PURE__ */ jsxs88("span", { className: "fd-fb-menu-anchor", ref, children: [
13450
+ /* @__PURE__ */ jsx97(
13199
13451
  IconButton,
13200
13452
  {
13201
13453
  icon: "arrows-out-cardinal",
@@ -13207,9 +13459,9 @@ function FolderPickerMenu({
13207
13459
  onClick: () => setOpen((v) => !v)
13208
13460
  }
13209
13461
  ),
13210
- open2 ? /* @__PURE__ */ jsx96(InlinePanelLayers, { panel, children: /* @__PURE__ */ jsxs87("div", { className: "fd-fb-menu", role: "menu", "aria-label": label, style: { zIndex }, children: [
13211
- /* @__PURE__ */ jsx96("span", { className: "fd-overline fd-muted fd-fb-menu-title", children: "Move to\u2026" }),
13212
- destinations.map((d) => /* @__PURE__ */ jsxs87(
13462
+ open2 ? /* @__PURE__ */ jsx97(InlinePanelLayers, { panel, children: /* @__PURE__ */ jsxs88("div", { className: "fd-fb-menu", role: "menu", "aria-label": label, style: { zIndex }, children: [
13463
+ /* @__PURE__ */ jsx97("span", { className: "fd-overline fd-muted fd-fb-menu-title", children: "Move to\u2026" }),
13464
+ destinations.map((d) => /* @__PURE__ */ jsxs88(
13213
13465
  "button",
13214
13466
  {
13215
13467
  type: "button",
@@ -13221,7 +13473,7 @@ function FolderPickerMenu({
13221
13473
  setOpen(false);
13222
13474
  },
13223
13475
  children: [
13224
- /* @__PURE__ */ jsx96("i", { className: "ph ph-" + (d.id == null ? "house-simple" : "folder-simple"), "aria-hidden": "true" }),
13476
+ /* @__PURE__ */ jsx97("i", { className: "ph ph-" + (d.id == null ? "house-simple" : "folder-simple"), "aria-hidden": "true" }),
13225
13477
  d.name
13226
13478
  ]
13227
13479
  },
@@ -13231,8 +13483,8 @@ function FolderPickerMenu({
13231
13483
  ] });
13232
13484
  }
13233
13485
  function RowShell({ icon, name, meta, onOpen, draggableId, isDropTarget, onDropPayload, actions, className = "" }) {
13234
- const [over, setOver] = React65.useState(false);
13235
- const dragCounter = React65.useRef(0);
13486
+ const [over, setOver] = React66.useState(false);
13487
+ const dragCounter = React66.useRef(0);
13236
13488
  const dropHandlers = isDropTarget ? {
13237
13489
  onDragEnter: (e) => {
13238
13490
  if (!hasInternalPayload(e)) return;
@@ -13257,8 +13509,8 @@ function RowShell({ icon, name, meta, onOpen, draggableId, isDropTarget, onDropP
13257
13509
  if (payload && onDropPayload) onDropPayload(payload);
13258
13510
  }
13259
13511
  } : {};
13260
- return /* @__PURE__ */ jsxs87("div", { className: ["fd-fb-row", over ? "is-drop-target" : "", className].filter(Boolean).join(" "), ...dropHandlers, children: [
13261
- /* @__PURE__ */ jsxs87(
13512
+ return /* @__PURE__ */ jsxs88("div", { className: ["fd-fb-row", over ? "is-drop-target" : "", className].filter(Boolean).join(" "), ...dropHandlers, children: [
13513
+ /* @__PURE__ */ jsxs88(
13262
13514
  "button",
13263
13515
  {
13264
13516
  type: "button",
@@ -13267,26 +13519,26 @@ function RowShell({ icon, name, meta, onOpen, draggableId, isDropTarget, onDropP
13267
13519
  draggable: !!draggableId,
13268
13520
  onDragStart: draggableId ? (e) => writeDragPayload(e, draggableId) : void 0,
13269
13521
  children: [
13270
- /* @__PURE__ */ jsx96("span", { className: "fd-fb-row-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx96("i", { className: "ph ph-" + icon }) }),
13271
- /* @__PURE__ */ jsxs87("span", { className: "fd-fb-row-text", children: [
13272
- /* @__PURE__ */ jsx96("span", { className: "fd-fb-row-name", title: name, children: name }),
13273
- meta ? /* @__PURE__ */ jsx96("span", { className: "fd-fb-row-meta", children: meta }) : null
13522
+ /* @__PURE__ */ jsx97("span", { className: "fd-fb-row-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx97("i", { className: "ph ph-" + icon }) }),
13523
+ /* @__PURE__ */ jsxs88("span", { className: "fd-fb-row-text", children: [
13524
+ /* @__PURE__ */ jsx97("span", { className: "fd-fb-row-name", title: name, children: name }),
13525
+ meta ? /* @__PURE__ */ jsx97("span", { className: "fd-fb-row-meta", children: meta }) : null
13274
13526
  ] })
13275
13527
  ]
13276
13528
  }
13277
13529
  ),
13278
- actions ? /* @__PURE__ */ jsx96("span", { className: "fd-fb-row-actions", children: actions }) : null
13530
+ actions ? /* @__PURE__ */ jsx97("span", { className: "fd-fb-row-actions", children: actions }) : null
13279
13531
  ] });
13280
13532
  }
13281
13533
  function TreeNode({ folder, depth, folders, currentFolderId, onNavigate, onMoveInto, canMove }) {
13282
13534
  const kids = childrenOf(folders, folder.id);
13283
- const [expanded, setExpanded] = React65.useState(() => currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId));
13284
- React65.useEffect(() => {
13535
+ const [expanded, setExpanded] = React66.useState(() => currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId));
13536
+ React66.useEffect(() => {
13285
13537
  if (currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId)) setExpanded(true);
13286
13538
  }, [currentFolderId, folder.id, folders]);
13287
13539
  const isCurrent = folder.id === currentFolderId;
13288
- return /* @__PURE__ */ jsxs87("div", { className: "fd-fb-tree-node", children: [
13289
- /* @__PURE__ */ jsx96(
13540
+ return /* @__PURE__ */ jsxs88("div", { className: "fd-fb-tree-node", children: [
13541
+ /* @__PURE__ */ jsx97(
13290
13542
  RowShell,
13291
13543
  {
13292
13544
  icon: folder.id === currentFolderId ? "folder-open" : "folder-simple",
@@ -13296,7 +13548,7 @@ function TreeNode({ folder, depth, folders, currentFolderId, onNavigate, onMoveI
13296
13548
  isDropTarget: canMove,
13297
13549
  onDropPayload: (payload) => onMoveInto(payload, folder.id),
13298
13550
  className: ["fd-fb-tree-row", isCurrent ? "is-current" : ""].filter(Boolean).join(" "),
13299
- actions: kids.length ? /* @__PURE__ */ jsx96(
13551
+ actions: kids.length ? /* @__PURE__ */ jsx97(
13300
13552
  IconButton,
13301
13553
  {
13302
13554
  icon: expanded ? "caret-down" : "caret-right",
@@ -13308,7 +13560,7 @@ function TreeNode({ folder, depth, folders, currentFolderId, onNavigate, onMoveI
13308
13560
  ) : void 0
13309
13561
  }
13310
13562
  ),
13311
- expanded && kids.length ? /* @__PURE__ */ jsx96("div", { className: "fd-fb-tree-children", style: { paddingLeft: 14 }, children: kids.map((k) => /* @__PURE__ */ jsx96(
13563
+ expanded && kids.length ? /* @__PURE__ */ jsx97("div", { className: "fd-fb-tree-children", style: { paddingLeft: 14 }, children: kids.map((k) => /* @__PURE__ */ jsx97(
13312
13564
  TreeNode,
13313
13565
  {
13314
13566
  folder: k,
@@ -13347,15 +13599,15 @@ function FileBrowser({
13347
13599
  const canUpload = perm.canUpload !== false && !!onUpload;
13348
13600
  const canRemoveFile = perm.canRemoveFile !== false && !!onRemoveFile;
13349
13601
  const canDeleteFolder = perm.canDeleteFolder !== false && !!onDeleteFolder;
13350
- const [createOpen, setCreateOpen] = React65.useState(false);
13351
- const [createName, setCreateName] = React65.useState("");
13352
- const [renameTarget, setRenameTarget] = React65.useState(null);
13353
- const [renameValue, setRenameValue] = React65.useState("");
13354
- const [deleteTarget, setDeleteTarget] = React65.useState(null);
13355
- const uploadInputRef = React65.useRef(null);
13356
- const crumbFolders = React65.useMemo(() => ancestorsOf(folders, currentFolderId), [folders, currentFolderId]);
13357
- const subfolders = React65.useMemo(() => childrenOf(folders, currentFolderId), [folders, currentFolderId]);
13358
- const currentFiles = React65.useMemo(
13602
+ const [createOpen, setCreateOpen] = React66.useState(false);
13603
+ const [createName, setCreateName] = React66.useState("");
13604
+ const [renameTarget, setRenameTarget] = React66.useState(null);
13605
+ const [renameValue, setRenameValue] = React66.useState("");
13606
+ const [deleteTarget, setDeleteTarget] = React66.useState(null);
13607
+ const uploadInputRef = React66.useRef(null);
13608
+ const crumbFolders = React66.useMemo(() => ancestorsOf(folders, currentFolderId), [folders, currentFolderId]);
13609
+ const subfolders = React66.useMemo(() => childrenOf(folders, currentFolderId), [folders, currentFolderId]);
13610
+ const currentFiles = React66.useMemo(
13359
13611
  () => files.filter((f) => f.folderId === currentFolderId).sort((a, b) => a.name.localeCompare(b.name)),
13360
13612
  [files, currentFolderId]
13361
13613
  );
@@ -13394,10 +13646,10 @@ function FileBrowser({
13394
13646
  if (deleteTarget && onDeleteFolder) onDeleteFolder(deleteTarget);
13395
13647
  setDeleteTarget(null);
13396
13648
  };
13397
- const content = /* @__PURE__ */ jsxs87("div", { className: ["fd-fb", className].filter(Boolean).join(" "), children: [
13398
- /* @__PURE__ */ jsxs87("div", { className: "fd-fb-head", children: [
13399
- /* @__PURE__ */ jsxs87("nav", { className: "fd-fb-crumbs", "aria-label": "Folder path", children: [
13400
- /* @__PURE__ */ jsx96(
13649
+ const content = /* @__PURE__ */ jsxs88("div", { className: ["fd-fb", className].filter(Boolean).join(" "), children: [
13650
+ /* @__PURE__ */ jsxs88("div", { className: "fd-fb-head", children: [
13651
+ /* @__PURE__ */ jsxs88("nav", { className: "fd-fb-crumbs", "aria-label": "Folder path", children: [
13652
+ /* @__PURE__ */ jsx97(
13401
13653
  BreadcrumbCrumb,
13402
13654
  {
13403
13655
  label: "Home",
@@ -13407,7 +13659,7 @@ function FileBrowser({
13407
13659
  onDropPayload: (p) => moveIntoFolder(p, null)
13408
13660
  }
13409
13661
  ),
13410
- crumbFolders.map((f, i) => /* @__PURE__ */ jsx96(
13662
+ crumbFolders.map((f, i) => /* @__PURE__ */ jsx97(
13411
13663
  BreadcrumbCrumb,
13412
13664
  {
13413
13665
  label: f.name,
@@ -13419,11 +13671,11 @@ function FileBrowser({
13419
13671
  f.id
13420
13672
  ))
13421
13673
  ] }),
13422
- /* @__PURE__ */ jsxs87("span", { className: "fd-fb-actions", children: [
13423
- canCreateFolder ? /* @__PURE__ */ jsx96(Button, { variant: "secondary", size: "sm", icon: "folder-simple-plus", onClick: openCreate, children: "New folder" }) : null,
13424
- canUpload ? /* @__PURE__ */ jsxs87(Fragment27, { children: [
13425
- /* @__PURE__ */ jsx96(Button, { variant: "secondary", size: "sm", icon: "upload-simple", onClick: () => uploadInputRef.current && uploadInputRef.current.click(), children: "Upload" }),
13426
- /* @__PURE__ */ jsx96(
13674
+ /* @__PURE__ */ jsxs88("span", { className: "fd-fb-actions", children: [
13675
+ canCreateFolder ? /* @__PURE__ */ jsx97(Button, { variant: "secondary", size: "sm", icon: "folder-simple-plus", onClick: openCreate, children: "New folder" }) : null,
13676
+ canUpload ? /* @__PURE__ */ jsxs88(Fragment28, { children: [
13677
+ /* @__PURE__ */ jsx97(Button, { variant: "secondary", size: "sm", icon: "upload-simple", onClick: () => uploadInputRef.current && uploadInputRef.current.click(), children: "Upload" }),
13678
+ /* @__PURE__ */ jsx97(
13427
13679
  "input",
13428
13680
  {
13429
13681
  ref: uploadInputRef,
@@ -13441,9 +13693,9 @@ function FileBrowser({
13441
13693
  ] }) : null
13442
13694
  ] })
13443
13695
  ] }),
13444
- /* @__PURE__ */ jsxs87("div", { className: "fd-fb-body", children: [
13445
- /* @__PURE__ */ jsxs87("div", { className: "fd-fb-tree", role: "region", "aria-label": "Folder tree", children: [
13446
- /* @__PURE__ */ jsx96(
13696
+ /* @__PURE__ */ jsxs88("div", { className: "fd-fb-body", children: [
13697
+ /* @__PURE__ */ jsxs88("div", { className: "fd-fb-tree", role: "region", "aria-label": "Folder tree", children: [
13698
+ /* @__PURE__ */ jsx97(
13447
13699
  RowShell,
13448
13700
  {
13449
13701
  icon: "house-simple",
@@ -13454,7 +13706,7 @@ function FileBrowser({
13454
13706
  className: ["fd-fb-tree-row", currentFolderId == null ? "is-current" : ""].filter(Boolean).join(" ")
13455
13707
  }
13456
13708
  ),
13457
- childrenOf(folders, null).map((f) => /* @__PURE__ */ jsx96(
13709
+ childrenOf(folders, null).map((f) => /* @__PURE__ */ jsx97(
13458
13710
  TreeNode,
13459
13711
  {
13460
13712
  folder: f,
@@ -13468,18 +13720,18 @@ function FileBrowser({
13468
13720
  f.id
13469
13721
  ))
13470
13722
  ] }),
13471
- /* @__PURE__ */ jsx96("div", { className: "fd-fb-main", role: "region", "aria-label": "Folder contents", children: /* @__PURE__ */ jsx96(
13723
+ /* @__PURE__ */ jsx97("div", { className: "fd-fb-main", role: "region", "aria-label": "Folder contents", children: /* @__PURE__ */ jsx97(
13472
13724
  LoadingRegion,
13473
13725
  {
13474
13726
  state: loading ? "loading" : "ready",
13475
13727
  label: "Loading folder contents",
13476
- skeleton: /* @__PURE__ */ jsxs87("div", { className: "fd-stack", style: { gap: 8, padding: 12 }, children: [
13477
- /* @__PURE__ */ jsx96(Skeleton, { h: 44, radius: "10px" }),
13478
- /* @__PURE__ */ jsx96(Skeleton, { h: 44, radius: "10px" }),
13479
- /* @__PURE__ */ jsx96(Skeleton, { h: 44, radius: "10px" })
13728
+ skeleton: /* @__PURE__ */ jsxs88("div", { className: "fd-stack", style: { gap: 8, padding: 12 }, children: [
13729
+ /* @__PURE__ */ jsx97(Skeleton, { h: 44, radius: "10px" }),
13730
+ /* @__PURE__ */ jsx97(Skeleton, { h: 44, radius: "10px" }),
13731
+ /* @__PURE__ */ jsx97(Skeleton, { h: 44, radius: "10px" })
13480
13732
  ] }),
13481
- children: isEmpty ? /* @__PURE__ */ jsx96(EmptyState, { icon: "folder-open", title: "This folder is empty", children: canUpload ? "Drop files here, or use Upload above." : "Nothing has been filed here yet." }) : /* @__PURE__ */ jsxs87("div", { className: "fd-fb-list", children: [
13482
- subfolders.map((f) => /* @__PURE__ */ jsx96(
13733
+ children: isEmpty ? /* @__PURE__ */ jsx97(EmptyState, { icon: "folder-open", title: "This folder is empty", children: canUpload ? "Drop files here, or use Upload above." : "Nothing has been filed here yet." }) : /* @__PURE__ */ jsxs88("div", { className: "fd-fb-list", children: [
13734
+ subfolders.map((f) => /* @__PURE__ */ jsx97(
13483
13735
  RowShell,
13484
13736
  {
13485
13737
  icon: "folder-simple",
@@ -13488,9 +13740,9 @@ function FileBrowser({
13488
13740
  draggableId: canMove ? { kind: "folder", id: f.id } : void 0,
13489
13741
  isDropTarget: canMove,
13490
13742
  onDropPayload: (p) => moveIntoFolder(p, f.id),
13491
- actions: /* @__PURE__ */ jsxs87(Fragment27, { children: [
13492
- canRenameFolder ? /* @__PURE__ */ jsx96(IconButton, { icon: "pencil-simple", label: "Rename " + f.name, size: "sm", variant: "ghost", onClick: () => openRename(f) }) : null,
13493
- canMove ? /* @__PURE__ */ jsx96(
13743
+ actions: /* @__PURE__ */ jsxs88(Fragment28, { children: [
13744
+ canRenameFolder ? /* @__PURE__ */ jsx97(IconButton, { icon: "pencil-simple", label: "Rename " + f.name, size: "sm", variant: "ghost", onClick: () => openRename(f) }) : null,
13745
+ canMove ? /* @__PURE__ */ jsx97(
13494
13746
  FolderPickerMenu,
13495
13747
  {
13496
13748
  label: "Move " + f.name,
@@ -13498,12 +13750,12 @@ function FileBrowser({
13498
13750
  onPick: (target) => moveIntoFolder({ kind: "folder", id: f.id }, target)
13499
13751
  }
13500
13752
  ) : null,
13501
- canDeleteFolder ? /* @__PURE__ */ jsx96(IconButton, { icon: "trash-simple", label: "Delete " + f.name, size: "sm", variant: "ghost", onClick: () => openDelete(f) }) : null
13753
+ canDeleteFolder ? /* @__PURE__ */ jsx97(IconButton, { icon: "trash-simple", label: "Delete " + f.name, size: "sm", variant: "ghost", onClick: () => openDelete(f) }) : null
13502
13754
  ] })
13503
13755
  },
13504
13756
  f.id
13505
13757
  )),
13506
- currentFiles.map((file) => /* @__PURE__ */ jsx96(
13758
+ currentFiles.map((file) => /* @__PURE__ */ jsx97(
13507
13759
  RowShell,
13508
13760
  {
13509
13761
  icon: iconForMime(file.mime, file.name),
@@ -13511,8 +13763,8 @@ function FileBrowser({
13511
13763
  meta: file.size ? formatBytes(file.size) : void 0,
13512
13764
  onOpen: onOpenFile ? () => onOpenFile(file) : void 0,
13513
13765
  draggableId: canMove ? { kind: "file", id: file.id } : void 0,
13514
- actions: /* @__PURE__ */ jsxs87(Fragment27, { children: [
13515
- canMove ? /* @__PURE__ */ jsx96(
13766
+ actions: /* @__PURE__ */ jsxs88(Fragment28, { children: [
13767
+ canMove ? /* @__PURE__ */ jsx97(
13516
13768
  FolderPickerMenu,
13517
13769
  {
13518
13770
  label: "Move " + file.name,
@@ -13520,7 +13772,7 @@ function FileBrowser({
13520
13772
  onPick: (target) => onMoveFile && onMoveFile(file.id, target)
13521
13773
  }
13522
13774
  ) : null,
13523
- canRemoveFile ? /* @__PURE__ */ jsx96(IconButton, { icon: "trash-simple", label: "Remove " + file.name, size: "sm", variant: "ghost", onClick: () => onRemoveFile && onRemoveFile(file) }) : null
13775
+ canRemoveFile ? /* @__PURE__ */ jsx97(IconButton, { icon: "trash-simple", label: "Remove " + file.name, size: "sm", variant: "ghost", onClick: () => onRemoveFile && onRemoveFile(file) }) : null
13524
13776
  ] })
13525
13777
  },
13526
13778
  file.id
@@ -13529,10 +13781,10 @@ function FileBrowser({
13529
13781
  }
13530
13782
  ) })
13531
13783
  ] }),
13532
- /* @__PURE__ */ jsx96(Modal, { open: createOpen, title: "New folder", onClose: () => setCreateOpen(false), footer: /* @__PURE__ */ jsxs87(Fragment27, { children: [
13533
- /* @__PURE__ */ jsx96(Button, { variant: "secondary", onClick: () => setCreateOpen(false), children: "Cancel" }),
13534
- /* @__PURE__ */ jsx96(Button, { onClick: submitCreate, disabled: !createName.trim(), children: "Create" })
13535
- ] }), children: /* @__PURE__ */ jsx96(
13784
+ /* @__PURE__ */ jsx97(Modal, { open: createOpen, title: "New folder", onClose: () => setCreateOpen(false), footer: /* @__PURE__ */ jsxs88(Fragment28, { children: [
13785
+ /* @__PURE__ */ jsx97(Button, { variant: "secondary", onClick: () => setCreateOpen(false), children: "Cancel" }),
13786
+ /* @__PURE__ */ jsx97(Button, { onClick: submitCreate, disabled: !createName.trim(), children: "Create" })
13787
+ ] }), children: /* @__PURE__ */ jsx97(
13536
13788
  "input",
13537
13789
  {
13538
13790
  className: "fd-fb-input",
@@ -13546,10 +13798,10 @@ function FileBrowser({
13546
13798
  autoFocus: true
13547
13799
  }
13548
13800
  ) }),
13549
- /* @__PURE__ */ jsx96(Modal, { open: renameTarget != null, title: "Rename folder", onClose: () => setRenameTarget(null), footer: /* @__PURE__ */ jsxs87(Fragment27, { children: [
13550
- /* @__PURE__ */ jsx96(Button, { variant: "secondary", onClick: () => setRenameTarget(null), children: "Cancel" }),
13551
- /* @__PURE__ */ jsx96(Button, { onClick: submitRename, disabled: !renameValue.trim(), children: "Save" })
13552
- ] }), children: /* @__PURE__ */ jsx96(
13801
+ /* @__PURE__ */ jsx97(Modal, { open: renameTarget != null, title: "Rename folder", onClose: () => setRenameTarget(null), footer: /* @__PURE__ */ jsxs88(Fragment28, { children: [
13802
+ /* @__PURE__ */ jsx97(Button, { variant: "secondary", onClick: () => setRenameTarget(null), children: "Cancel" }),
13803
+ /* @__PURE__ */ jsx97(Button, { onClick: submitRename, disabled: !renameValue.trim(), children: "Save" })
13804
+ ] }), children: /* @__PURE__ */ jsx97(
13553
13805
  "input",
13554
13806
  {
13555
13807
  className: "fd-fb-input",
@@ -13563,22 +13815,22 @@ function FileBrowser({
13563
13815
  autoFocus: true
13564
13816
  }
13565
13817
  ) }),
13566
- /* @__PURE__ */ jsx96(
13818
+ /* @__PURE__ */ jsx97(
13567
13819
  Modal,
13568
13820
  {
13569
13821
  open: deleteTarget != null,
13570
13822
  title: deleteTarget ? "Delete \u201C" + deleteTarget.name + "\u201D?" : "Delete folder?",
13571
13823
  description: "This can't be undone. The folder must be empty.",
13572
13824
  onClose: () => setDeleteTarget(null),
13573
- footer: /* @__PURE__ */ jsxs87(Fragment27, { children: [
13574
- /* @__PURE__ */ jsx96(Button, { variant: "secondary", onClick: () => setDeleteTarget(null), children: "Cancel" }),
13575
- /* @__PURE__ */ jsx96(Button, { variant: "danger", onClick: confirmDelete, children: "Delete" })
13825
+ footer: /* @__PURE__ */ jsxs88(Fragment28, { children: [
13826
+ /* @__PURE__ */ jsx97(Button, { variant: "secondary", onClick: () => setDeleteTarget(null), children: "Cancel" }),
13827
+ /* @__PURE__ */ jsx97(Button, { variant: "danger", onClick: confirmDelete, children: "Delete" })
13576
13828
  ] })
13577
13829
  }
13578
13830
  )
13579
13831
  ] });
13580
13832
  if (!canUpload) return content;
13581
- return /* @__PURE__ */ jsx96(Dropzone, { className: "fd-fb-dropzone", onFiles: (picked) => onUpload && onUpload(picked, currentFolderId), label: "Drop files to upload", children: content });
13833
+ return /* @__PURE__ */ jsx97(Dropzone, { className: "fd-fb-dropzone", onFiles: (picked) => onUpload && onUpload(picked, currentFolderId), label: "Drop files to upload", children: content });
13582
13834
  }
13583
13835
  function BreadcrumbCrumb({
13584
13836
  label,
@@ -13587,8 +13839,8 @@ function BreadcrumbCrumb({
13587
13839
  isDropTarget,
13588
13840
  onDropPayload
13589
13841
  }) {
13590
- const [over, setOver] = React65.useState(false);
13591
- const dragCounter = React65.useRef(0);
13842
+ const [over, setOver] = React66.useState(false);
13843
+ const dragCounter = React66.useRef(0);
13592
13844
  const dropHandlers = isDropTarget ? {
13593
13845
  onDragEnter: (e) => {
13594
13846
  if (!hasInternalPayload(e)) return;
@@ -13613,11 +13865,11 @@ function BreadcrumbCrumb({
13613
13865
  if (payload && onDropPayload) onDropPayload(payload);
13614
13866
  }
13615
13867
  } : {};
13616
- return /* @__PURE__ */ jsx96("span", { className: ["fd-fb-crumb", over ? "is-drop-target" : ""].filter(Boolean).join(" "), ...dropHandlers, children: isCurrent ? /* @__PURE__ */ jsx96("span", { className: "fd-fb-crumb-current", "aria-current": "page", children: label }) : /* @__PURE__ */ jsx96("button", { type: "button", className: "fd-fb-crumb-link", onClick, children: label }) });
13868
+ return /* @__PURE__ */ jsx97("span", { className: ["fd-fb-crumb", over ? "is-drop-target" : ""].filter(Boolean).join(" "), ...dropHandlers, children: isCurrent ? /* @__PURE__ */ jsx97("span", { className: "fd-fb-crumb-current", "aria-current": "page", children: label }) : /* @__PURE__ */ jsx97("button", { type: "button", className: "fd-fb-crumb-link", onClick, children: label }) });
13617
13869
  }
13618
13870
 
13619
13871
  // src/kits/query.ts
13620
- import * as React66 from "react";
13872
+ import * as React67 from "react";
13621
13873
  var isMultiSelectShaped = (v) => !!v && typeof v === "object" && Array.isArray(v.values);
13622
13874
  var isRangeShaped = (v) => !!v && typeof v === "object" && ("min" in v || "max" in v);
13623
13875
  var isDateShaped = (v) => !!v && typeof v === "object" && "kind" in v;
@@ -13672,22 +13924,22 @@ function compare(a, b, dir) {
13672
13924
  var API = null;
13673
13925
  var PREFS = null;
13674
13926
  function useServerTable({ endpoint, params, defaults, deps, prefsKey }) {
13675
- const [query, setQuery] = React66.useState(() => {
13927
+ const [query, setQuery] = React67.useState(() => {
13676
13928
  const store = PREFS || window.PlannerPrefs;
13677
13929
  const saved = prefsKey && store ? store.getTable(prefsKey) : {};
13678
13930
  return { ...DEFAULTS, ...defaults || {}, ...saved.pageSize ? { pageSize: saved.pageSize } : {}, ...saved.sort ? { sort: saved.sort, dir: saved.dir || "desc" } : {} };
13679
13931
  });
13680
- const savePref = React66.useCallback((patch2) => {
13932
+ const savePref = React67.useCallback((patch2) => {
13681
13933
  const store = PREFS || window.PlannerPrefs;
13682
13934
  if (prefsKey && store) store.setTable(prefsKey, patch2);
13683
13935
  }, [prefsKey]);
13684
- const [res, setRes] = React66.useState(null);
13685
- const [loading, setLoading] = React66.useState(true);
13686
- const seq2 = React66.useRef(0);
13936
+ const [res, setRes] = React67.useState(null);
13937
+ const [loading, setLoading] = React67.useState(true);
13938
+ const seq2 = React67.useRef(0);
13687
13939
  const depKey = (deps || []).join("|");
13688
13940
  const paramKey = JSON.stringify(params || {});
13689
13941
  const queryKey = JSON.stringify(query);
13690
- React66.useEffect(() => {
13942
+ React67.useEffect(() => {
13691
13943
  const id = ++seq2.current;
13692
13944
  setLoading(true);
13693
13945
  const t = setTimeout(() => {
@@ -14006,12 +14258,12 @@ function createVersionStore(initialState, options) {
14006
14258
  }
14007
14259
 
14008
14260
  // src/kits/documentTitle.ts
14009
- import * as React67 from "react";
14261
+ import * as React68 from "react";
14010
14262
  function formatDocumentTitle(routeTitle, appName) {
14011
14263
  return [routeTitle, appName, "Flytedesk"].filter((part) => !!part && part.length > 0).join(" \xB7 ");
14012
14264
  }
14013
14265
  function useDocumentTitle(routeTitle, appName) {
14014
- React67.useEffect(() => {
14266
+ React68.useEffect(() => {
14015
14267
  if (typeof document === "undefined") return;
14016
14268
  document.title = formatDocumentTitle(routeTitle, appName);
14017
14269
  }, [routeTitle, appName]);
@@ -14053,6 +14305,7 @@ export {
14053
14305
  Clamp,
14054
14306
  ClockFace,
14055
14307
  CodeBlock,
14308
+ CodeEditor,
14056
14309
  Collapsible,
14057
14310
  ComingSoon,
14058
14311
  CsiBadge,