@flytedan/flytebot-design-system 0.19.0 → 0.20.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
@@ -6376,11 +6376,203 @@ function ProfilePage({
6376
6376
  ] });
6377
6377
  }
6378
6378
 
6379
+ // src/components/platform/SignInPage.tsx
6380
+ import * as React42 from "react";
6381
+ import { Fragment as Fragment18, jsx as jsx67, jsxs as jsxs61 } from "react/jsx-runtime";
6382
+ function SignInPage({ productName, onSignIn, continueAs }) {
6383
+ const [signingIn, setSigningIn] = React42.useState(false);
6384
+ const [resuming, setResuming] = React42.useState(false);
6385
+ function handleSignIn() {
6386
+ setSigningIn(true);
6387
+ onSignIn();
6388
+ }
6389
+ function handleContinue() {
6390
+ setResuming(true);
6391
+ continueAs.onContinue().finally(() => setResuming(false));
6392
+ }
6393
+ return /* @__PURE__ */ jsxs61(
6394
+ "div",
6395
+ {
6396
+ style: {
6397
+ position: "relative",
6398
+ display: "grid",
6399
+ placeItems: "center",
6400
+ minHeight: "100vh",
6401
+ padding: "24px 16px",
6402
+ boxSizing: "border-box",
6403
+ overflow: "hidden",
6404
+ 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%)"
6405
+ },
6406
+ children: [
6407
+ /* @__PURE__ */ jsx67(
6408
+ "div",
6409
+ {
6410
+ "aria-hidden": true,
6411
+ style: {
6412
+ position: "absolute",
6413
+ inset: 0,
6414
+ backgroundImage: "linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px)",
6415
+ backgroundSize: "48px 48px",
6416
+ maskImage: "radial-gradient(circle at 50% 40%, black, transparent 70%)"
6417
+ }
6418
+ }
6419
+ ),
6420
+ /* @__PURE__ */ jsxs61(
6421
+ "div",
6422
+ {
6423
+ style: {
6424
+ position: "relative",
6425
+ width: "100%",
6426
+ maxWidth: 408,
6427
+ display: "flex",
6428
+ flexDirection: "column",
6429
+ alignItems: "center"
6430
+ },
6431
+ children: [
6432
+ /* @__PURE__ */ jsx67("div", { style: { marginBottom: "var(--s-32)" }, "data-theme": "dark", children: /* @__PURE__ */ jsx67(FlytedeskMark, { size: "lg" }) }),
6433
+ /* @__PURE__ */ jsxs61(
6434
+ "div",
6435
+ {
6436
+ style: {
6437
+ width: "100%",
6438
+ borderRadius: "var(--r-2xl)",
6439
+ overflow: "hidden",
6440
+ boxShadow: "0 24px 64px -12px rgba(2, 8, 20, 0.55), 0 2px 8px rgba(2, 8, 20, 0.3)"
6441
+ },
6442
+ children: [
6443
+ /* @__PURE__ */ jsx67(
6444
+ "div",
6445
+ {
6446
+ style: {
6447
+ height: 4,
6448
+ background: "linear-gradient(90deg, var(--blue-400), var(--blue-600), var(--navy))"
6449
+ }
6450
+ }
6451
+ ),
6452
+ /* @__PURE__ */ jsx67(Card, { children: /* @__PURE__ */ jsxs61(
6453
+ "div",
6454
+ {
6455
+ style: {
6456
+ display: "flex",
6457
+ flexDirection: "column",
6458
+ gap: "var(--s-20)",
6459
+ alignItems: "center",
6460
+ textAlign: "center",
6461
+ padding: "var(--s-8) 0"
6462
+ },
6463
+ children: [
6464
+ /* @__PURE__ */ jsxs61("div", { children: [
6465
+ /* @__PURE__ */ jsx67("h1", { className: "fd-h3", style: { color: "var(--navy)" }, children: productName }),
6466
+ /* @__PURE__ */ jsx67("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" })
6467
+ ] }),
6468
+ continueAs ? /* @__PURE__ */ jsxs61(Fragment18, { children: [
6469
+ /* @__PURE__ */ jsx67(
6470
+ Button,
6471
+ {
6472
+ variant: "primary",
6473
+ style: { width: "100%" },
6474
+ loading: resuming,
6475
+ disabled: resuming,
6476
+ onClick: handleContinue,
6477
+ children: resuming ? "Resuming\u2026" : `Continue as ${continueAs.name}`
6478
+ }
6479
+ ),
6480
+ /* @__PURE__ */ jsx67(
6481
+ "button",
6482
+ {
6483
+ type: "button",
6484
+ className: "fd-body-sm fd-muted",
6485
+ style: {
6486
+ background: "none",
6487
+ border: "none",
6488
+ cursor: "pointer",
6489
+ textDecoration: "underline",
6490
+ padding: 0
6491
+ },
6492
+ disabled: resuming,
6493
+ onClick: continueAs.onDecline,
6494
+ children: "Not you? Sign in with flytedesk ID"
6495
+ }
6496
+ )
6497
+ ] }) : /* @__PURE__ */ jsx67(
6498
+ Button,
6499
+ {
6500
+ variant: "primary",
6501
+ style: { width: "100%" },
6502
+ loading: signingIn,
6503
+ disabled: signingIn,
6504
+ onClick: handleSignIn,
6505
+ children: /* @__PURE__ */ jsxs61(
6506
+ "span",
6507
+ {
6508
+ style: {
6509
+ display: "flex",
6510
+ flexDirection: "row",
6511
+ alignItems: "center",
6512
+ justifyContent: "center",
6513
+ gap: "var(--s-8)",
6514
+ flexWrap: "nowrap"
6515
+ },
6516
+ children: [
6517
+ /* @__PURE__ */ jsx67(GoogleGlyph, {}),
6518
+ /* @__PURE__ */ jsx67("span", { children: signingIn ? "Signing in\u2026" : "Sign in with flytedesk ID" })
6519
+ ]
6520
+ }
6521
+ )
6522
+ }
6523
+ ),
6524
+ /* @__PURE__ */ jsx67("p", { className: "fd-body-sm fd-muted", style: { fontSize: "12px" }, children: "One account, every flytedesk app." })
6525
+ ]
6526
+ }
6527
+ ) })
6528
+ ]
6529
+ }
6530
+ )
6531
+ ]
6532
+ }
6533
+ )
6534
+ ]
6535
+ }
6536
+ );
6537
+ }
6538
+ function GoogleGlyph() {
6539
+ return /* @__PURE__ */ jsxs61("svg", { width: "18", height: "18", viewBox: "0 0 18 18", "aria-hidden": true, children: [
6540
+ /* @__PURE__ */ jsx67(
6541
+ "path",
6542
+ {
6543
+ fill: "#4285F4",
6544
+ 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"
6545
+ }
6546
+ ),
6547
+ /* @__PURE__ */ jsx67(
6548
+ "path",
6549
+ {
6550
+ fill: "#34A853",
6551
+ 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"
6552
+ }
6553
+ ),
6554
+ /* @__PURE__ */ jsx67(
6555
+ "path",
6556
+ {
6557
+ fill: "#FBBC05",
6558
+ 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"
6559
+ }
6560
+ ),
6561
+ /* @__PURE__ */ jsx67(
6562
+ "path",
6563
+ {
6564
+ fill: "#EA4335",
6565
+ d: "M9 3.58c1.32 0 2.51.45 3.44 1.35l2.59-2.59C13.46.89 11.43 0 9 0A9 9 0 0 0 .96 4.94l3.01 2.33C4.68 5.16 6.66 3.58 9 3.58Z"
6566
+ }
6567
+ )
6568
+ ] });
6569
+ }
6570
+
6379
6571
  // src/components/platform/RoadmapTimeline.tsx
6380
- import * as React44 from "react";
6572
+ import * as React45 from "react";
6381
6573
 
6382
6574
  // src/kits/session.ts
6383
- import * as React42 from "react";
6575
+ import * as React43 from "react";
6384
6576
  var PERMISSION_CATALOG = [
6385
6577
  { group: "Plans", items: [
6386
6578
  { key: "plan.view", label: "View plans", detail: "Read any plan in the workspace." },
@@ -7947,8 +8139,8 @@ function roadmap(overrides) {
7947
8139
  };
7948
8140
  }
7949
8141
  function useSession() {
7950
- const [s, setS] = React42.useState(getSession);
7951
- React42.useEffect(() => subscribe(setS), []);
8142
+ const [s, setS] = React43.useState(getSession);
8143
+ React43.useEffect(() => subscribe(setS), []);
7952
8144
  return s;
7953
8145
  }
7954
8146
  var SessionKit = {
@@ -7981,7 +8173,7 @@ var SessionKit = {
7981
8173
  };
7982
8174
  function DemoSessionProvider({ children }) {
7983
8175
  const session = useSession();
7984
- const value = React42.useMemo(
8176
+ const value = React43.useMemo(
7985
8177
  () => ({
7986
8178
  user: session.user,
7987
8179
  roles: session.roles,
@@ -7997,11 +8189,11 @@ function DemoSessionProvider({ children }) {
7997
8189
  }),
7998
8190
  [session]
7999
8191
  );
8000
- return React42.createElement(SessionProvider, { value }, children);
8192
+ return React43.createElement(SessionProvider, { value }, children);
8001
8193
  }
8002
8194
 
8003
8195
  // src/kits/runtime.ts
8004
- import * as React43 from "react";
8196
+ import * as React44 from "react";
8005
8197
  var WIRED_ENDPOINTS = [
8006
8198
  // Nothing yet. Every id below would come from a real service:
8007
8199
  // "plan.get", "placements.list", …
@@ -8172,8 +8364,8 @@ var RuntimeKit = {
8172
8364
  };
8173
8365
  RuntimeKit.declare(FEATURE_NEEDS);
8174
8366
  function useRuntimeMode() {
8175
- const [m, setM] = React43.useState(RuntimeKit.getMode());
8176
- React43.useEffect(() => RuntimeKit.subscribe(setM), []);
8367
+ const [m, setM] = React44.useState(RuntimeKit.getMode());
8368
+ React44.useEffect(() => RuntimeKit.subscribe(setM), []);
8177
8369
  return m;
8178
8370
  }
8179
8371
  function useFeatureStatus(key) {
@@ -8192,7 +8384,7 @@ var UseRuntimeMode = useRuntimeMode;
8192
8384
  var UseFeatureStatus = useFeatureStatus;
8193
8385
 
8194
8386
  // src/components/platform/RoadmapTimeline.tsx
8195
- import { jsx as jsx67, jsxs as jsxs61 } from "react/jsx-runtime";
8387
+ import { jsx as jsx68, jsxs as jsxs62 } from "react/jsx-runtime";
8196
8388
  var STATUS = {
8197
8389
  shipped: { tone: "success", icon: "check-circle", label: "Wired" },
8198
8390
  next: { tone: "warning", icon: "traffic-cone", label: "Not wired" },
@@ -8207,45 +8399,45 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
8207
8399
  const s = STATUS[item.status] || STATUS.planned;
8208
8400
  const deps = (item.dependsOn || []).map((k) => byKey[k]).filter(Boolean);
8209
8401
  const blocking = deps.filter((d) => !d.implemented);
8210
- return /* @__PURE__ */ jsx67(Card, { elevation: "flat", children: /* @__PURE__ */ jsxs61("div", { className: "fd-stack", style: { gap: 10 }, children: [
8211
- /* @__PURE__ */ jsxs61("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: [
8212
- /* @__PURE__ */ jsx67("span", { className: "fd-body", style: { fontWeight: 700, flex: 1, minWidth: 140 }, children: item.label }),
8213
- /* @__PURE__ */ jsx67(Badge, { tone: "neutral", icon: PROJECT_ICON[item.project] || "squares-four", children: item.project }),
8214
- /* @__PURE__ */ jsx67(Badge, { tone: s.tone, icon: s.icon, children: s.label })
8402
+ return /* @__PURE__ */ jsx68(Card, { elevation: "flat", children: /* @__PURE__ */ jsxs62("div", { className: "fd-stack", style: { gap: 10 }, children: [
8403
+ /* @__PURE__ */ jsxs62("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: [
8404
+ /* @__PURE__ */ jsx68("span", { className: "fd-body", style: { fontWeight: 700, flex: 1, minWidth: 140 }, children: item.label }),
8405
+ /* @__PURE__ */ jsx68(Badge, { tone: "neutral", icon: PROJECT_ICON[item.project] || "squares-four", children: item.project }),
8406
+ /* @__PURE__ */ jsx68(Badge, { tone: s.tone, icon: s.icon, children: s.label })
8215
8407
  ] }),
8216
- /* @__PURE__ */ jsx67("p", { className: "fd-body-sm fd-secondary", style: { margin: 0, textWrap: "pretty" }, children: item.description }),
8217
- item.backend ? /* @__PURE__ */ jsxs61("div", { className: "fd-row", style: { gap: 10, alignItems: "flex-start" }, children: [
8218
- /* @__PURE__ */ jsx67("span", { className: "fd-overline fd-muted", style: { width: 62, flex: "none", paddingTop: 2 }, children: "Backend" }),
8219
- /* @__PURE__ */ jsx67("span", { className: "fd-body-sm", style: { flex: 1, textWrap: "pretty" }, children: item.backend })
8408
+ /* @__PURE__ */ jsx68("p", { className: "fd-body-sm fd-secondary", style: { margin: 0, textWrap: "pretty" }, children: item.description }),
8409
+ item.backend ? /* @__PURE__ */ jsxs62("div", { className: "fd-row", style: { gap: 10, alignItems: "flex-start" }, children: [
8410
+ /* @__PURE__ */ jsx68("span", { className: "fd-overline fd-muted", style: { width: 62, flex: "none", paddingTop: 2 }, children: "Backend" }),
8411
+ /* @__PURE__ */ jsx68("span", { className: "fd-body-sm", style: { flex: 1, textWrap: "pretty" }, children: item.backend })
8220
8412
  ] }) : null,
8221
- /* @__PURE__ */ jsxs61("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
8222
- item.effort ? /* @__PURE__ */ jsxs61("span", { className: "fd-body-sm fd-muted", children: [
8223
- /* @__PURE__ */ jsx67("i", { className: "ph ph-hourglass-medium" }),
8413
+ /* @__PURE__ */ jsxs62("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
8414
+ item.effort ? /* @__PURE__ */ jsxs62("span", { className: "fd-body-sm fd-muted", children: [
8415
+ /* @__PURE__ */ jsx68("i", { className: "ph ph-hourglass-medium" }),
8224
8416
  " ",
8225
8417
  item.effort
8226
8418
  ] }) : null,
8227
- /* @__PURE__ */ jsxs61("span", { className: "fd-body-sm fd-muted", children: [
8228
- /* @__PURE__ */ jsx67("i", { className: "ph ph-user" }),
8419
+ /* @__PURE__ */ jsxs62("span", { className: "fd-body-sm fd-muted", children: [
8420
+ /* @__PURE__ */ jsx68("i", { className: "ph ph-user" }),
8229
8421
  " ",
8230
8422
  item.owner
8231
8423
  ] }),
8232
- item.screen ? /* @__PURE__ */ jsx67(Badge, { tone: "neutral", icon: "browser", children: "screen" }) : null,
8233
- /* @__PURE__ */ jsx67("span", { style: { flex: 1 } }),
8234
- /* @__PURE__ */ jsx67(
8424
+ item.screen ? /* @__PURE__ */ jsx68(Badge, { tone: "neutral", icon: "browser", children: "screen" }) : null,
8425
+ /* @__PURE__ */ jsx68("span", { style: { flex: 1 } }),
8426
+ /* @__PURE__ */ jsx68(
8235
8427
  "button",
8236
8428
  {
8237
8429
  type: "button",
8238
8430
  onClick: () => onOpenFlag && onOpenFlag(item.key),
8239
8431
  style: { all: "unset", cursor: "pointer", display: "inline-flex", alignItems: "center", gap: 5 },
8240
- children: /* @__PURE__ */ jsx67("code", { className: "fd-mono", style: { fontSize: 11, color: "var(--brand)" }, children: item.key })
8432
+ children: /* @__PURE__ */ jsx68("code", { className: "fd-mono", style: { fontSize: 11, color: "var(--brand)" }, children: item.key })
8241
8433
  }
8242
8434
  )
8243
8435
  ] }),
8244
- deps.length ? /* @__PURE__ */ jsxs61("div", { className: "fd-row", style: { gap: 6, flexWrap: "wrap", paddingTop: 6, borderTop: "1px solid var(--border)" }, children: [
8245
- /* @__PURE__ */ jsx67("span", { className: "fd-overline fd-muted", style: { paddingTop: 3 }, children: "After" }),
8246
- deps.map((d) => /* @__PURE__ */ jsx67(Tag, { icon: d.implemented ? "check" : "clock", children: d.label }, d.key))
8436
+ deps.length ? /* @__PURE__ */ jsxs62("div", { className: "fd-row", style: { gap: 6, flexWrap: "wrap", paddingTop: 6, borderTop: "1px solid var(--border)" }, children: [
8437
+ /* @__PURE__ */ jsx68("span", { className: "fd-overline fd-muted", style: { paddingTop: 3 }, children: "After" }),
8438
+ deps.map((d) => /* @__PURE__ */ jsx68(Tag, { icon: d.implemented ? "check" : "clock", children: d.label }, d.key))
8247
8439
  ] }) : null,
8248
- blocking.length && !item.implemented ? /* @__PURE__ */ jsxs61("span", { className: "fd-body-sm", style: { color: "var(--warn-text)" }, children: [
8440
+ blocking.length && !item.implemented ? /* @__PURE__ */ jsxs62("span", { className: "fd-body-sm", style: { color: "var(--warn-text)" }, children: [
8249
8441
  "Blocked until ",
8250
8442
  blocking.map((d) => d.label).join(" and "),
8251
8443
  " ",
@@ -8256,12 +8448,12 @@ function RoadmapCard({ item, byKey, onOpenFlag }) {
8256
8448
  }
8257
8449
  function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
8258
8450
  const session = SessionKit.useSession();
8259
- const [project, setProject] = React44.useState("");
8260
- const [q, setQ] = React44.useState("");
8261
- const scrollRef = React44.useRef(null);
8262
- const nowRef = React44.useRef(null);
8263
- const rm = React44.useMemo(() => SessionKit.roadmap({ isComplete: RuntimeKit.isComplete }), [session]);
8264
- const byKey = React44.useMemo(() => {
8451
+ const [project, setProject] = React45.useState("");
8452
+ const [q, setQ] = React45.useState("");
8453
+ const scrollRef = React45.useRef(null);
8454
+ const nowRef = React45.useRef(null);
8455
+ const rm = React45.useMemo(() => SessionKit.roadmap({ isComplete: RuntimeKit.isComplete }), [session]);
8456
+ const byKey = React45.useMemo(() => {
8265
8457
  const m = {};
8266
8458
  rm.items.forEach((i) => {
8267
8459
  m[i.key] = i;
@@ -8270,7 +8462,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
8270
8462
  }, [rm]);
8271
8463
  const items = rm.items.filter((i) => (!project || i.project === project) && (!q || (i.label + " " + i.description + " " + (i.backend || "") + " " + i.key).toLowerCase().includes(q.toLowerCase())));
8272
8464
  const projects = [...new Set(rm.items.map((i) => i.project))];
8273
- React44.useEffect(() => {
8465
+ React45.useEffect(() => {
8274
8466
  let raf1 = 0, raf2 = 0;
8275
8467
  const place = () => {
8276
8468
  const box = scrollRef.current, mark = nowRef.current;
@@ -8298,23 +8490,23 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
8298
8490
  }, 0);
8299
8491
  const nextPhase = items.find((i) => !i.implemented);
8300
8492
  let lastPhase = null;
8301
- return /* @__PURE__ */ jsxs61("div", { className: "fd-stack", style: { gap: 16, maxWidth: 1e3 }, children: [
8302
- /* @__PURE__ */ jsxs61("div", { className: "fd-stack", style: { gap: 10 }, children: [
8303
- /* @__PURE__ */ jsx67("span", { className: "fd-overline fd-muted", children: "Architecture" }),
8304
- /* @__PURE__ */ jsx67("h1", { className: "fd-h1", style: { margin: 0 }, children: title }),
8305
- /* @__PURE__ */ jsx67("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." })
8493
+ return /* @__PURE__ */ jsxs62("div", { className: "fd-stack", style: { gap: 16, maxWidth: 1e3 }, children: [
8494
+ /* @__PURE__ */ jsxs62("div", { className: "fd-stack", style: { gap: 10 }, children: [
8495
+ /* @__PURE__ */ jsx68("span", { className: "fd-overline fd-muted", children: "Architecture" }),
8496
+ /* @__PURE__ */ jsx68("h1", { className: "fd-h1", style: { margin: 0 }, children: title }),
8497
+ /* @__PURE__ */ jsx68("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." })
8306
8498
  ] }),
8307
- /* @__PURE__ */ jsxs61("div", { className: "fd-grid-stats is-thin", children: [
8308
- /* @__PURE__ */ jsx67(StatTile, { compact: true, label: "Wired", value: String(rm.shipped), sub: "of " + rm.items.length + " features" }),
8309
- /* @__PURE__ */ jsx67(StatTile, { compact: true, label: "Remaining", value: String(rm.remaining), sub: "backend work" }),
8310
- /* @__PURE__ */ jsx67(StatTile, { compact: true, label: "Est. effort", value: days ? days + " days" : "\u2014", sub: "sum of estimates, not calendar" }),
8311
- /* @__PURE__ */ jsx67(StatTile, { compact: true, label: "Up next", value: nextPhase ? "Phase " + nextPhase.phase : "\u2014", sub: nextPhase ? nextPhase.phaseName : "all wired" })
8499
+ /* @__PURE__ */ jsxs62("div", { className: "fd-grid-stats is-thin", children: [
8500
+ /* @__PURE__ */ jsx68(StatTile, { compact: true, label: "Wired", value: String(rm.shipped), sub: "of " + rm.items.length + " features" }),
8501
+ /* @__PURE__ */ jsx68(StatTile, { compact: true, label: "Remaining", value: String(rm.remaining), sub: "backend work" }),
8502
+ /* @__PURE__ */ jsx68(StatTile, { compact: true, label: "Est. effort", value: days ? days + " days" : "\u2014", sub: "sum of estimates, not calendar" }),
8503
+ /* @__PURE__ */ jsx68(StatTile, { compact: true, label: "Up next", value: nextPhase ? "Phase " + nextPhase.phase : "\u2014", sub: nextPhase ? nextPhase.phaseName : "all wired" })
8312
8504
  ] }),
8313
- /* @__PURE__ */ jsxs61("div", { className: "fd-row", style: { gap: 10, flexWrap: "wrap" }, children: [
8314
- /* @__PURE__ */ jsx67(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 } }),
8315
- /* @__PURE__ */ jsx67(Select, { placeholder: "All projects", value: project, onChange: (e) => setProject(e.target.value), options: projects, style: { width: 190 } }),
8316
- /* @__PURE__ */ jsx67("span", { style: { flex: 1 } }),
8317
- /* @__PURE__ */ jsx67(
8505
+ /* @__PURE__ */ jsxs62("div", { className: "fd-row", style: { gap: 10, flexWrap: "wrap" }, children: [
8506
+ /* @__PURE__ */ jsx68(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 } }),
8507
+ /* @__PURE__ */ jsx68(Select, { placeholder: "All projects", value: project, onChange: (e) => setProject(e.target.value), options: projects, style: { width: 190 } }),
8508
+ /* @__PURE__ */ jsx68("span", { style: { flex: 1 } }),
8509
+ /* @__PURE__ */ jsx68(
8318
8510
  Button,
8319
8511
  {
8320
8512
  size: "sm",
@@ -8328,7 +8520,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
8328
8520
  }
8329
8521
  )
8330
8522
  ] }),
8331
- /* @__PURE__ */ jsx67(
8523
+ /* @__PURE__ */ jsx68(
8332
8524
  Flag,
8333
8525
  {
8334
8526
  tone: "info",
@@ -8337,60 +8529,60 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
8337
8529
  actions: null
8338
8530
  }
8339
8531
  ),
8340
- /* @__PURE__ */ jsx67("div", { className: "fd-rm", children: /* @__PURE__ */ jsx67("div", { className: "fd-rm-scroll", ref: scrollRef, children: /* @__PURE__ */ jsxs61("div", { className: "fd-rm-track", children: [
8341
- /* @__PURE__ */ jsx67("span", { className: "fd-rm-spine", children: /* @__PURE__ */ jsx67("span", { className: "fd-rm-spine-done", style: { height: items.length ? 100 * shippedShown / items.length + "%" : "0%" } }) }),
8532
+ /* @__PURE__ */ jsx68("div", { className: "fd-rm", children: /* @__PURE__ */ jsx68("div", { className: "fd-rm-scroll", ref: scrollRef, children: /* @__PURE__ */ jsxs62("div", { className: "fd-rm-track", children: [
8533
+ /* @__PURE__ */ jsx68("span", { className: "fd-rm-spine", children: /* @__PURE__ */ jsx68("span", { className: "fd-rm-spine-done", style: { height: items.length ? 100 * shippedShown / items.length + "%" : "0%" } }) }),
8342
8534
  items.map((item, n) => {
8343
8535
  const showPhase = item.phase !== lastPhase;
8344
8536
  lastPhase = item.phase;
8345
8537
  const inPhase = items.filter((i) => i.phase === item.phase).length;
8346
8538
  const isBoundary = n === firstPending;
8347
- return /* @__PURE__ */ jsxs61(React44.Fragment, { children: [
8348
- showPhase ? /* @__PURE__ */ jsxs61("div", { className: "fd-rm-era", children: [
8349
- /* @__PURE__ */ jsxs61("span", { className: "fd-row", style: { gap: 8, flexWrap: "wrap", alignItems: "baseline" }, children: [
8350
- /* @__PURE__ */ jsx67("span", { style: { fontWeight: 700 }, children: item.phase === 0 ? "Shipped" : "Phase " + item.phase + " \u2014 " + item.phaseName }),
8351
- item.phase === 0 ? null : /* @__PURE__ */ jsxs61("span", { className: "fd-mono", style: { opacity: 0.7, fontWeight: 400 }, children: [
8539
+ return /* @__PURE__ */ jsxs62(React45.Fragment, { children: [
8540
+ showPhase ? /* @__PURE__ */ jsxs62("div", { className: "fd-rm-era", children: [
8541
+ /* @__PURE__ */ jsxs62("span", { className: "fd-row", style: { gap: 8, flexWrap: "wrap", alignItems: "baseline" }, children: [
8542
+ /* @__PURE__ */ jsx68("span", { style: { fontWeight: 700 }, children: item.phase === 0 ? "Shipped" : "Phase " + item.phase + " \u2014 " + item.phaseName }),
8543
+ item.phase === 0 ? null : /* @__PURE__ */ jsxs62("span", { className: "fd-mono", style: { opacity: 0.7, fontWeight: 400 }, children: [
8352
8544
  fmtDate(item.phaseStart),
8353
8545
  " \u2013 ",
8354
8546
  fmtDate(item.date)
8355
8547
  ] }),
8356
- /* @__PURE__ */ jsxs61("span", { style: { opacity: 0.7, fontWeight: 400 }, children: [
8548
+ /* @__PURE__ */ jsxs62("span", { style: { opacity: 0.7, fontWeight: 400 }, children: [
8357
8549
  "\xB7 ",
8358
8550
  inPhase,
8359
8551
  " feature",
8360
8552
  inPhase === 1 ? "" : "s"
8361
8553
  ] })
8362
8554
  ] }),
8363
- item.phaseWhy ? /* @__PURE__ */ jsx67("p", { className: "fd-rm-era-why", children: item.phaseWhy }) : null
8555
+ item.phaseWhy ? /* @__PURE__ */ jsx68("p", { className: "fd-rm-era-why", children: item.phaseWhy }) : null
8364
8556
  ] }) : null,
8365
- isBoundary ? /* @__PURE__ */ jsx67("div", { className: "fd-rm-now", ref: nowRef, children: /* @__PURE__ */ jsxs61("span", { className: "fd-rm-now-pill", children: [
8366
- /* @__PURE__ */ jsx67("i", { className: "ph ph-map-pin" }),
8557
+ isBoundary ? /* @__PURE__ */ jsx68("div", { className: "fd-rm-now", ref: nowRef, children: /* @__PURE__ */ jsxs62("span", { className: "fd-rm-now-pill", children: [
8558
+ /* @__PURE__ */ jsx68("i", { className: "ph ph-map-pin" }),
8367
8559
  " You are here \u2014 everything above is wired"
8368
8560
  ] }) }) : null,
8369
- /* @__PURE__ */ jsxs61("div", { className: "fd-rm-row", children: [
8370
- /* @__PURE__ */ jsx67("span", { className: "fd-rm-dot " + (item.implemented ? "is-shipped" : item.status === "next" ? "is-next" : "") }),
8371
- /* @__PURE__ */ jsxs61("div", { className: "fd-rm-date", children: [
8561
+ /* @__PURE__ */ jsxs62("div", { className: "fd-rm-row", children: [
8562
+ /* @__PURE__ */ jsx68("span", { className: "fd-rm-dot " + (item.implemented ? "is-shipped" : item.status === "next" ? "is-next" : "") }),
8563
+ /* @__PURE__ */ jsxs62("div", { className: "fd-rm-date", children: [
8372
8564
  fmtDate(item.date),
8373
- /* @__PURE__ */ jsx67("br", {}),
8374
- /* @__PURE__ */ jsx67("span", { style: { opacity: 0.75 }, children: item.implemented ? "shipped" : "phase " + item.phase })
8565
+ /* @__PURE__ */ jsx68("br", {}),
8566
+ /* @__PURE__ */ jsx68("span", { style: { opacity: 0.75 }, children: item.implemented ? "shipped" : "phase " + item.phase })
8375
8567
  ] }),
8376
- /* @__PURE__ */ jsx67(RoadmapCard, { item, byKey, onOpenFlag })
8568
+ /* @__PURE__ */ jsx68(RoadmapCard, { item, byKey, onOpenFlag })
8377
8569
  ] })
8378
8570
  ] }, item.key);
8379
8571
  }),
8380
- !items.length ? /* @__PURE__ */ jsx67("p", { className: "fd-body-sm fd-muted", children: "Nothing matches that filter." }) : null
8572
+ !items.length ? /* @__PURE__ */ jsx68("p", { className: "fd-body-sm fd-muted", children: "Nothing matches that filter." }) : null
8381
8573
  ] }) }) }),
8382
- /* @__PURE__ */ jsxs61("p", { className: "fd-body-sm fd-muted", style: { margin: 0 }, children: [
8574
+ /* @__PURE__ */ jsxs62("p", { className: "fd-body-sm fd-muted", style: { margin: 0 }, children: [
8383
8575
  "Derived from the feature-flag registry \u2014 each entry's status is its flag's ",
8384
- /* @__PURE__ */ jsx67("code", { className: "fd-mono", children: "implemented" }),
8576
+ /* @__PURE__ */ jsx68("code", { className: "fd-mono", children: "implemented" }),
8385
8577
  " field, so this page cannot drift from what the apps actually do."
8386
8578
  ] })
8387
8579
  ] });
8388
8580
  }
8389
8581
 
8390
8582
  // src/components/platform/ComingSoon.tsx
8391
- import * as React45 from "react";
8583
+ import * as React46 from "react";
8392
8584
  import { createPortal as createPortal5 } from "react-dom";
8393
- import { Fragment as Fragment19, jsx as jsx68, jsxs as jsxs62 } from "react/jsx-runtime";
8585
+ import { Fragment as Fragment20, jsx as jsx69, jsxs as jsxs63 } from "react/jsx-runtime";
8394
8586
  var BYPASS_STORE = "fd.soon.bypass.v1";
8395
8587
  function readBypassed() {
8396
8588
  try {
@@ -8406,8 +8598,8 @@ function writeBypassed(list) {
8406
8598
  }
8407
8599
  }
8408
8600
  function useBypass(key) {
8409
- const [on, setOn] = React45.useState(() => !!key && readBypassed().indexOf(key) >= 0);
8410
- React45.useEffect(() => {
8601
+ const [on, setOn] = React46.useState(() => !!key && readBypassed().indexOf(key) >= 0);
8602
+ React46.useEffect(() => {
8411
8603
  setOn(!!key && readBypassed().indexOf(key) >= 0);
8412
8604
  }, [key]);
8413
8605
  const set = (next) => {
@@ -8420,43 +8612,43 @@ function useBypass(key) {
8420
8612
  return [on, set];
8421
8613
  }
8422
8614
  function SoonCard({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass }) {
8423
- return /* @__PURE__ */ jsxs62(Fragment19, { children: [
8424
- /* @__PURE__ */ jsxs62("span", { className: "fd-soon-badge", children: [
8425
- /* @__PURE__ */ jsx68("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" }),
8615
+ return /* @__PURE__ */ jsxs63(Fragment20, { children: [
8616
+ /* @__PURE__ */ jsxs63("span", { className: "fd-soon-badge", children: [
8617
+ /* @__PURE__ */ jsx69("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" }),
8426
8618
  label
8427
8619
  ] }),
8428
- detail ? /* @__PURE__ */ jsx68("span", { className: "fd-soon-detail", children: detail }) : null,
8429
- backend ? /* @__PURE__ */ jsxs62("span", { className: "fd-soon-backend", children: [
8430
- /* @__PURE__ */ jsx68("span", { className: "fd-overline", children: "Needs" }),
8620
+ detail ? /* @__PURE__ */ jsx69("span", { className: "fd-soon-detail", children: detail }) : null,
8621
+ backend ? /* @__PURE__ */ jsxs63("span", { className: "fd-soon-backend", children: [
8622
+ /* @__PURE__ */ jsx69("span", { className: "fd-overline", children: "Needs" }),
8431
8623
  " ",
8432
8624
  backend
8433
8625
  ] }) : null,
8434
- eta || effort || onRoadmap ? /* @__PURE__ */ jsxs62("span", { className: "fd-soon-meta", children: [
8435
- eta ? /* @__PURE__ */ jsxs62("span", { children: [
8436
- /* @__PURE__ */ jsx68("i", { className: "ph ph-calendar-blank", "aria-hidden": "true" }),
8626
+ eta || effort || onRoadmap ? /* @__PURE__ */ jsxs63("span", { className: "fd-soon-meta", children: [
8627
+ eta ? /* @__PURE__ */ jsxs63("span", { children: [
8628
+ /* @__PURE__ */ jsx69("i", { className: "ph ph-calendar-blank", "aria-hidden": "true" }),
8437
8629
  " ",
8438
8630
  eta
8439
8631
  ] }) : null,
8440
- effort ? /* @__PURE__ */ jsxs62("span", { children: [
8441
- /* @__PURE__ */ jsx68("i", { className: "ph ph-hourglass-medium", "aria-hidden": "true" }),
8632
+ effort ? /* @__PURE__ */ jsxs63("span", { children: [
8633
+ /* @__PURE__ */ jsx69("i", { className: "ph ph-hourglass-medium", "aria-hidden": "true" }),
8442
8634
  " ",
8443
8635
  effort
8444
8636
  ] }) : null,
8445
- onRoadmap ? /* @__PURE__ */ jsxs62("button", { type: "button", className: "fd-soon-link", onClick: onRoadmap, children: [
8637
+ onRoadmap ? /* @__PURE__ */ jsxs63("button", { type: "button", className: "fd-soon-link", onClick: onRoadmap, children: [
8446
8638
  "See the roadmap ",
8447
- /* @__PURE__ */ jsx68("i", { className: "ph ph-arrow-right", "aria-hidden": "true" })
8639
+ /* @__PURE__ */ jsx69("i", { className: "ph ph-arrow-right", "aria-hidden": "true" })
8448
8640
  ] }) : null
8449
8641
  ] }) : null,
8450
- allowed ? /* @__PURE__ */ jsxs62("button", { type: "button", className: "fd-soon-view", onClick: onBypass, children: [
8451
- /* @__PURE__ */ jsx68("i", { className: "ph ph-eye", "aria-hidden": "true" }),
8642
+ allowed ? /* @__PURE__ */ jsxs63("button", { type: "button", className: "fd-soon-view", onClick: onBypass, children: [
8643
+ /* @__PURE__ */ jsx69("i", { className: "ph ph-eye", "aria-hidden": "true" }),
8452
8644
  " View and use it anyway"
8453
8645
  ] }) : null
8454
8646
  ] });
8455
8647
  }
8456
8648
  function useHoverCard(open) {
8457
- const anchor = React45.useRef(null);
8458
- const [pos, setPos] = React45.useState(null);
8459
- React45.useLayoutEffect(() => {
8649
+ const anchor = React46.useRef(null);
8650
+ const [pos, setPos] = React46.useState(null);
8651
+ React46.useLayoutEffect(() => {
8460
8652
  if (!open || !anchor.current) {
8461
8653
  setPos(null);
8462
8654
  return;
@@ -8508,9 +8700,9 @@ function ComingSoon({
8508
8700
  const tip = [label, detail, backend ? "Needs " + backend : null, eta ? "ETA " + eta : null, effort].filter(Boolean).join(" \xB7 ");
8509
8701
  if (inline) {
8510
8702
  if (allowed && bypassed) {
8511
- return /* @__PURE__ */ jsxs62("span", { className: ["fd-soon-inline-on", className].filter(Boolean).join(" "), ...rest, children: [
8703
+ return /* @__PURE__ */ jsxs63("span", { className: ["fd-soon-inline-on", className].filter(Boolean).join(" "), ...rest, children: [
8512
8704
  children,
8513
- /* @__PURE__ */ jsx68(
8705
+ /* @__PURE__ */ jsx69(
8514
8706
  "button",
8515
8707
  {
8516
8708
  type: "button",
@@ -8518,12 +8710,12 @@ function ComingSoon({
8518
8710
  title: "Unwired \u2014 writes go to the simulated backend. " + tip + " Click to re-blur.",
8519
8711
  onClick: () => setBypassed(false),
8520
8712
  "aria-label": "Re-blur this unwired feature",
8521
- children: /* @__PURE__ */ jsx68("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" })
8713
+ children: /* @__PURE__ */ jsx69("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" })
8522
8714
  }
8523
8715
  )
8524
8716
  ] });
8525
8717
  }
8526
- return /* @__PURE__ */ jsx68(
8718
+ return /* @__PURE__ */ jsx69(
8527
8719
  InlineSoon,
8528
8720
  {
8529
8721
  label,
@@ -8543,20 +8735,20 @@ function ComingSoon({
8543
8735
  );
8544
8736
  }
8545
8737
  if (allowed && bypassed) {
8546
- return /* @__PURE__ */ jsxs62("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 14 }, ...rest, children: [
8547
- /* @__PURE__ */ jsxs62("div", { className: "fd-soon-bar", role: "status", children: [
8548
- /* @__PURE__ */ jsxs62("span", { className: "fd-soon-badge", children: [
8549
- /* @__PURE__ */ jsx68("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" }),
8738
+ return /* @__PURE__ */ jsxs63("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 14 }, ...rest, children: [
8739
+ /* @__PURE__ */ jsxs63("div", { className: "fd-soon-bar", role: "status", children: [
8740
+ /* @__PURE__ */ jsxs63("span", { className: "fd-soon-badge", children: [
8741
+ /* @__PURE__ */ jsx69("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" }),
8550
8742
  "Unwired feature \u2014 you are using it anyway"
8551
8743
  ] }),
8552
- /* @__PURE__ */ jsx68("span", { className: "fd-soon-bar-detail", children: "Every action here writes to the simulated backend, so nothing you do persists beyond this session." }),
8553
- /* @__PURE__ */ jsxs62("span", { className: "fd-soon-bar-actions", children: [
8554
- onRoadmap ? /* @__PURE__ */ jsxs62("button", { type: "button", className: "fd-soon-link", onClick: onRoadmap, children: [
8744
+ /* @__PURE__ */ jsx69("span", { className: "fd-soon-bar-detail", children: "Every action here writes to the simulated backend, so nothing you do persists beyond this session." }),
8745
+ /* @__PURE__ */ jsxs63("span", { className: "fd-soon-bar-actions", children: [
8746
+ onRoadmap ? /* @__PURE__ */ jsxs63("button", { type: "button", className: "fd-soon-link", onClick: onRoadmap, children: [
8555
8747
  "Roadmap ",
8556
- /* @__PURE__ */ jsx68("i", { className: "ph ph-arrow-right", "aria-hidden": "true" })
8748
+ /* @__PURE__ */ jsx69("i", { className: "ph ph-arrow-right", "aria-hidden": "true" })
8557
8749
  ] }) : null,
8558
- /* @__PURE__ */ jsxs62("button", { type: "button", className: "fd-soon-link", onClick: () => setBypassed(false), children: [
8559
- /* @__PURE__ */ jsx68("i", { className: "ph ph-eye-slash", "aria-hidden": "true" }),
8750
+ /* @__PURE__ */ jsxs63("button", { type: "button", className: "fd-soon-link", onClick: () => setBypassed(false), children: [
8751
+ /* @__PURE__ */ jsx69("i", { className: "ph ph-eye-slash", "aria-hidden": "true" }),
8560
8752
  " Re-blur"
8561
8753
  ] })
8562
8754
  ] })
@@ -8564,10 +8756,10 @@ function ComingSoon({
8564
8756
  children
8565
8757
  ] });
8566
8758
  }
8567
- return /* @__PURE__ */ jsxs62("div", { className: ["fd-soon", className].filter(Boolean).join(" "), style: minHeight ? { minHeight } : void 0, ...rest, children: [
8568
- /* @__PURE__ */ jsx68("div", { className: "fd-soon-under", style: { filter: "blur(" + blur + "px) saturate(.62)" }, ...{ inert: "" }, "aria-hidden": "true", children }),
8569
- /* @__PURE__ */ jsx68("div", { className: "fd-soon-veil" }),
8570
- /* @__PURE__ */ jsx68("div", { className: "fd-soon-note", role: "note", children: /* @__PURE__ */ jsx68(
8759
+ return /* @__PURE__ */ jsxs63("div", { className: ["fd-soon", className].filter(Boolean).join(" "), style: minHeight ? { minHeight } : void 0, ...rest, children: [
8760
+ /* @__PURE__ */ jsx69("div", { className: "fd-soon-under", style: { filter: "blur(" + blur + "px) saturate(.62)" }, ...{ inert: "" }, "aria-hidden": "true", children }),
8761
+ /* @__PURE__ */ jsx69("div", { className: "fd-soon-veil" }),
8762
+ /* @__PURE__ */ jsx69("div", { className: "fd-soon-note", role: "note", children: /* @__PURE__ */ jsx69(
8571
8763
  SoonCard,
8572
8764
  {
8573
8765
  label,
@@ -8583,10 +8775,10 @@ function ComingSoon({
8583
8775
  ] });
8584
8776
  }
8585
8777
  function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass, blur, tip, className, rest, children }) {
8586
- const [open, setOpen] = React45.useState(false);
8778
+ const [open, setOpen] = React46.useState(false);
8587
8779
  const [anchor, pos] = useHoverCard(open);
8588
8780
  const zIndex = useOverlayLayer(open);
8589
- const close = React45.useRef(null);
8781
+ const close = React46.useRef(null);
8590
8782
  const show = () => {
8591
8783
  if (close.current) {
8592
8784
  clearTimeout(close.current);
@@ -8602,10 +8794,10 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
8602
8794
  setOpen(false);
8603
8795
  }, 140);
8604
8796
  };
8605
- React45.useEffect(() => () => {
8797
+ React46.useEffect(() => () => {
8606
8798
  if (close.current) clearTimeout(close.current);
8607
8799
  }, []);
8608
- return /* @__PURE__ */ jsxs62(
8800
+ return /* @__PURE__ */ jsxs63(
8609
8801
  "span",
8610
8802
  {
8611
8803
  ref: anchor,
@@ -8616,8 +8808,8 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
8616
8808
  onBlur: hide,
8617
8809
  ...rest,
8618
8810
  children: [
8619
- /* @__PURE__ */ jsx68("span", { className: "fd-soon-under", style: { filter: "blur(" + Math.min(blur, 1.1) + "px) saturate(.66)" }, ...{ inert: "" }, "aria-hidden": "true", children }),
8620
- /* @__PURE__ */ jsx68(
8811
+ /* @__PURE__ */ jsx69("span", { className: "fd-soon-under", style: { filter: "blur(" + Math.min(blur, 1.1) + "px) saturate(.66)" }, ...{ inert: "" }, "aria-hidden": "true", children }),
8812
+ /* @__PURE__ */ jsx69(
8621
8813
  "button",
8622
8814
  {
8623
8815
  type: "button",
@@ -8628,11 +8820,11 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
8628
8820
  onFocus: show,
8629
8821
  onBlur: hide,
8630
8822
  onClick: () => open ? setOpen(false) : show(),
8631
- children: /* @__PURE__ */ jsx68("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" })
8823
+ children: /* @__PURE__ */ jsx69("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" })
8632
8824
  }
8633
8825
  ),
8634
8826
  open && pos ? createPortal5(
8635
- /* @__PURE__ */ jsx68(LayerProvider, { zIndex, children: /* @__PURE__ */ jsx68(
8827
+ /* @__PURE__ */ jsx69(LayerProvider, { zIndex, children: /* @__PURE__ */ jsx69(
8636
8828
  "div",
8637
8829
  {
8638
8830
  className: "fd-soon-note fd-soon-hovercard",
@@ -8640,7 +8832,7 @@ function InlineSoon({ label, detail, backend, eta, effort, onRoadmap, allowed, o
8640
8832
  style: { position: "fixed", left: pos.left, top: pos.top, bottom: pos.bottom, width: pos.width, zIndex },
8641
8833
  onMouseEnter: show,
8642
8834
  onMouseLeave: hide,
8643
- children: /* @__PURE__ */ jsx68(
8835
+ children: /* @__PURE__ */ jsx69(
8644
8836
  SoonCard,
8645
8837
  {
8646
8838
  label,
@@ -8670,10 +8862,10 @@ function formatEta(iso2) {
8670
8862
  var FormatEta = formatEta;
8671
8863
 
8672
8864
  // src/components/platform/Gate.tsx
8673
- import { jsx as jsx69, jsxs as jsxs63 } from "react/jsx-runtime";
8865
+ import { jsx as jsx70, jsxs as jsxs64 } from "react/jsx-runtime";
8674
8866
  function PermissionDenied({ permission, title, detail, compact: compact3 = false, className = "", ...rest }) {
8675
8867
  const need = Array.isArray(permission) ? permission : [permission].filter(Boolean);
8676
- return /* @__PURE__ */ jsxs63(
8868
+ return /* @__PURE__ */ jsxs64(
8677
8869
  "div",
8678
8870
  {
8679
8871
  className: ["fd-stack", className].filter(Boolean).join(" "),
@@ -8689,14 +8881,14 @@ function PermissionDenied({ permission, title, detail, compact: compact3 = false
8689
8881
  },
8690
8882
  ...rest,
8691
8883
  children: [
8692
- /* @__PURE__ */ jsxs63("span", { className: "fd-row", style: { gap: 8 }, children: [
8693
- /* @__PURE__ */ jsx69("i", { className: "ph ph-lock-simple", style: { fontSize: 16, color: "var(--text-muted)" }, "aria-hidden": "true" }),
8694
- /* @__PURE__ */ jsx69("span", { className: compact3 ? "fd-label-lg" : "fd-h3", children: title || "You do not have access to this" })
8884
+ /* @__PURE__ */ jsxs64("span", { className: "fd-row", style: { gap: 8 }, children: [
8885
+ /* @__PURE__ */ jsx70("i", { className: "ph ph-lock-simple", style: { fontSize: 16, color: "var(--text-muted)" }, "aria-hidden": "true" }),
8886
+ /* @__PURE__ */ jsx70("span", { className: compact3 ? "fd-label-lg" : "fd-h3", children: title || "You do not have access to this" })
8695
8887
  ] }),
8696
- /* @__PURE__ */ jsx69("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." }),
8697
- need.length ? /* @__PURE__ */ jsxs63("span", { className: "fd-row", style: { gap: 6, flexWrap: "wrap" }, children: [
8698
- /* @__PURE__ */ jsx69("span", { className: "fd-overline fd-muted", children: "Requires" }),
8699
- need.map((p) => /* @__PURE__ */ jsx69("code", { className: "fd-mono", style: {
8888
+ /* @__PURE__ */ jsx70("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." }),
8889
+ need.length ? /* @__PURE__ */ jsxs64("span", { className: "fd-row", style: { gap: 6, flexWrap: "wrap" }, children: [
8890
+ /* @__PURE__ */ jsx70("span", { className: "fd-overline fd-muted", children: "Requires" }),
8891
+ need.map((p) => /* @__PURE__ */ jsx70("code", { className: "fd-mono", style: {
8700
8892
  fontSize: 11.5,
8701
8893
  padding: "2px 7px",
8702
8894
  borderRadius: 5,
@@ -8717,7 +8909,7 @@ function Gate({ perm, anyOf, role, silent = false, fallback, compact: compact3 =
8717
8909
  if (ok) return children;
8718
8910
  if (fallback !== void 0) return fallback;
8719
8911
  if (silent) return null;
8720
- return /* @__PURE__ */ jsx69(PermissionDenied, { permission: perm || anyOf, compact: compact3 });
8912
+ return /* @__PURE__ */ jsx70(PermissionDenied, { permission: perm || anyOf, compact: compact3 });
8721
8913
  }
8722
8914
  function FeatureGate({
8723
8915
  flag,
@@ -8740,7 +8932,7 @@ function FeatureGate({
8740
8932
  const f = SessionKit.findFlag(flag) || {};
8741
8933
  const missing = rt.missing || [];
8742
8934
  const canBypass = bypassPerm === null ? false : !bypassPerm || can2(bypassPerm);
8743
- return /* @__PURE__ */ jsx69(
8935
+ return /* @__PURE__ */ jsx70(
8744
8936
  ComingSoon,
8745
8937
  {
8746
8938
  label: label || (variant === "inline" ? f.label || "Not wired yet" : "Designed \u2014 backend not wired yet"),
@@ -8761,26 +8953,26 @@ function FeatureGate({
8761
8953
  function PermissionHint({ perm, children }) {
8762
8954
  const { can: can2 } = useSessionContext();
8763
8955
  if (can2(perm)) return children;
8764
- return /* @__PURE__ */ jsx69(
8956
+ return /* @__PURE__ */ jsx70(
8765
8957
  "span",
8766
8958
  {
8767
8959
  title: "Requires " + (Array.isArray(perm) ? perm.join(", ") : perm),
8768
8960
  style: { display: "inline-flex", opacity: 0.45, cursor: "not-allowed" },
8769
8961
  "aria-disabled": "true",
8770
- children: /* @__PURE__ */ jsx69("span", { style: { pointerEvents: "none" }, children })
8962
+ children: /* @__PURE__ */ jsx70("span", { style: { pointerEvents: "none" }, children })
8771
8963
  }
8772
8964
  );
8773
8965
  }
8774
8966
 
8775
8967
  // src/components/platform/ModeSwitch.tsx
8776
- import * as React46 from "react";
8777
- import { Fragment as Fragment20, jsx as jsx70, jsxs as jsxs64 } from "react/jsx-runtime";
8968
+ import * as React47 from "react";
8969
+ import { Fragment as Fragment21, jsx as jsx71, jsxs as jsxs65 } from "react/jsx-runtime";
8778
8970
  function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog, onOpenSpec, summary }) {
8779
8971
  const mode2 = useRuntimeMode();
8780
- const [open, setOpen] = React46.useState(false);
8972
+ const [open, setOpen] = React47.useState(false);
8781
8973
  const zIndex = useOverlayLayer(open);
8782
- const ref = React46.useRef(null);
8783
- React46.useEffect(() => {
8974
+ const ref = React47.useRef(null);
8975
+ React47.useEffect(() => {
8784
8976
  if (!open) return;
8785
8977
  const away = (e) => {
8786
8978
  if (ref.current && !ref.current.contains(e.target)) setOpen(false);
@@ -8802,8 +8994,8 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
8802
8994
  RuntimeKit.setMode(next);
8803
8995
  setOpen(false);
8804
8996
  };
8805
- return /* @__PURE__ */ jsxs64("span", { style: { position: "relative", display: "inline-flex" }, ref, children: [
8806
- /* @__PURE__ */ jsxs64(
8997
+ return /* @__PURE__ */ jsxs65("span", { style: { position: "relative", display: "inline-flex" }, ref, children: [
8998
+ /* @__PURE__ */ jsxs65(
8807
8999
  "button",
8808
9000
  {
8809
9001
  type: "button",
@@ -8813,29 +9005,29 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
8813
9005
  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.",
8814
9006
  className: "fd-mode-btn" + (test ? " is-test" : "") + (open ? " is-open" : ""),
8815
9007
  children: [
8816
- /* @__PURE__ */ jsx70("i", { className: "ph " + (test ? "ph-flask" : "ph-lightning"), style: { fontSize: 17 } }),
8817
- test && requestCount ? /* @__PURE__ */ jsx70("span", { className: "fd-mono fd-mode-count", children: requestCount > 99 ? "99+" : requestCount }, requestCount) : null
9008
+ /* @__PURE__ */ jsx71("i", { className: "ph " + (test ? "ph-flask" : "ph-lightning"), style: { fontSize: 17 } }),
9009
+ test && requestCount ? /* @__PURE__ */ jsx71("span", { className: "fd-mono fd-mode-count", children: requestCount > 99 ? "99+" : requestCount }, requestCount) : null
8818
9010
  ]
8819
9011
  }
8820
9012
  ),
8821
- open ? /* @__PURE__ */ jsx70(LayerProvider, { zIndex, children: /* @__PURE__ */ jsxs64("span", { className: "fd-view-enter fd-mode-pop", style: { zIndex }, children: [
8822
- /* @__PURE__ */ jsxs64("span", { className: "fd-row", style: { gap: 10, padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
8823
- /* @__PURE__ */ jsxs64("span", { className: "fd-badge " + (test ? "fd-badge-warning" : "fd-badge-neutral"), children: [
8824
- /* @__PURE__ */ jsx70("i", { className: "ph " + (test ? "ph-flask" : "ph-lightning"), "aria-hidden": "true" }),
9013
+ open ? /* @__PURE__ */ jsx71(LayerProvider, { zIndex, children: /* @__PURE__ */ jsxs65("span", { className: "fd-view-enter fd-mode-pop", style: { zIndex }, children: [
9014
+ /* @__PURE__ */ jsxs65("span", { className: "fd-row", style: { gap: 10, padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
9015
+ /* @__PURE__ */ jsxs65("span", { className: "fd-badge " + (test ? "fd-badge-warning" : "fd-badge-neutral"), children: [
9016
+ /* @__PURE__ */ jsx71("i", { className: "ph " + (test ? "ph-flask" : "ph-lightning"), "aria-hidden": "true" }),
8825
9017
  test ? "Test mode" : "Live mode"
8826
9018
  ] }),
8827
- test ? /* @__PURE__ */ jsxs64("span", { className: "fd-body-sm fd-muted fd-mono", children: [
9019
+ test ? /* @__PURE__ */ jsxs65("span", { className: "fd-body-sm fd-muted fd-mono", children: [
8828
9020
  requestCount,
8829
9021
  " simulated request",
8830
9022
  requestCount === 1 ? "" : "s"
8831
9023
  ] }) : null,
8832
- /* @__PURE__ */ jsx70("span", { style: { flex: 1 } }),
8833
- test && onClearLog ? /* @__PURE__ */ jsx70("button", { type: "button", className: "fd-soon-link", onClick: onClearLog, children: "Clear" }) : null
9024
+ /* @__PURE__ */ jsx71("span", { style: { flex: 1 } }),
9025
+ test && onClearLog ? /* @__PURE__ */ jsx71("button", { type: "button", className: "fd-soon-link", onClick: onClearLog, children: "Clear" }) : null
8834
9026
  ] }),
8835
- /* @__PURE__ */ jsxs64("span", { style: { display: "block", padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
8836
- /* @__PURE__ */ jsx70("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." }),
8837
- /* @__PURE__ */ jsxs64("span", { className: "fd-row", style: { gap: 8, marginTop: 10, flexWrap: "wrap" }, children: [
8838
- /* @__PURE__ */ jsxs64("span", { className: "fd-body-sm fd-muted fd-mono", children: [
9027
+ /* @__PURE__ */ jsxs65("span", { style: { display: "block", padding: "12px 14px", borderBottom: "1px solid var(--border)" }, children: [
9028
+ /* @__PURE__ */ jsx71("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." }),
9029
+ /* @__PURE__ */ jsxs65("span", { className: "fd-row", style: { gap: 8, marginTop: 10, flexWrap: "wrap" }, children: [
9030
+ /* @__PURE__ */ jsxs65("span", { className: "fd-body-sm fd-muted fd-mono", children: [
8839
9031
  s.endpointsWired,
8840
9032
  " endpoint",
8841
9033
  s.endpointsWired === 1 ? "" : "s",
@@ -8845,58 +9037,58 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
8845
9037
  s.total,
8846
9038
  " features complete"
8847
9039
  ] }),
8848
- onOpenSpec ? /* @__PURE__ */ jsxs64(Fragment20, { children: [
8849
- /* @__PURE__ */ jsx70("span", { style: { flex: 1 } }),
8850
- /* @__PURE__ */ jsxs64("button", { type: "button", className: "fd-soon-link", onClick: () => {
9040
+ onOpenSpec ? /* @__PURE__ */ jsxs65(Fragment21, { children: [
9041
+ /* @__PURE__ */ jsx71("span", { style: { flex: 1 } }),
9042
+ /* @__PURE__ */ jsxs65("button", { type: "button", className: "fd-soon-link", onClick: () => {
8851
9043
  setOpen(false);
8852
9044
  onOpenSpec();
8853
9045
  }, children: [
8854
9046
  "API spec ",
8855
- /* @__PURE__ */ jsx70("i", { className: "ph ph-arrow-right", "aria-hidden": "true" })
9047
+ /* @__PURE__ */ jsx71("i", { className: "ph ph-arrow-right", "aria-hidden": "true" })
8856
9048
  ] })
8857
9049
  ] }) : null
8858
9050
  ] })
8859
9051
  ] }),
8860
- /* @__PURE__ */ jsxs64("span", { className: "fd-mode-choice", children: [
8861
- /* @__PURE__ */ jsxs64("button", { type: "button", className: "fd-mode-opt" + (!test ? " is-on" : ""), onClick: () => go("live"), children: [
8862
- /* @__PURE__ */ jsx70("i", { className: "ph ph-lightning", "aria-hidden": "true" }),
8863
- /* @__PURE__ */ jsxs64("span", { className: "fd-mode-opt-text", children: [
8864
- /* @__PURE__ */ jsx70("span", { className: "fd-mode-opt-title", children: "Live mode" }),
8865
- /* @__PURE__ */ jsx70("span", { className: "fd-mode-opt-desc", children: "Incomplete features under construction" })
9052
+ /* @__PURE__ */ jsxs65("span", { className: "fd-mode-choice", children: [
9053
+ /* @__PURE__ */ jsxs65("button", { type: "button", className: "fd-mode-opt" + (!test ? " is-on" : ""), onClick: () => go("live"), children: [
9054
+ /* @__PURE__ */ jsx71("i", { className: "ph ph-lightning", "aria-hidden": "true" }),
9055
+ /* @__PURE__ */ jsxs65("span", { className: "fd-mode-opt-text", children: [
9056
+ /* @__PURE__ */ jsx71("span", { className: "fd-mode-opt-title", children: "Live mode" }),
9057
+ /* @__PURE__ */ jsx71("span", { className: "fd-mode-opt-desc", children: "Incomplete features under construction" })
8866
9058
  ] }),
8867
- !test ? /* @__PURE__ */ jsx70("i", { className: "ph ph-check", "aria-hidden": "true" }) : null
9059
+ !test ? /* @__PURE__ */ jsx71("i", { className: "ph ph-check", "aria-hidden": "true" }) : null
8868
9060
  ] }),
8869
- /* @__PURE__ */ jsxs64("button", { type: "button", className: "fd-mode-opt" + (test ? " is-on" : ""), onClick: () => go("test"), children: [
8870
- /* @__PURE__ */ jsx70("i", { className: "ph ph-flask", "aria-hidden": "true" }),
8871
- /* @__PURE__ */ jsxs64("span", { className: "fd-mode-opt-text", children: [
8872
- /* @__PURE__ */ jsx70("span", { className: "fd-mode-opt-title", children: "Test mode" }),
8873
- /* @__PURE__ */ jsx70("span", { className: "fd-mode-opt-desc", children: "Everything usable, all data simulated" })
9061
+ /* @__PURE__ */ jsxs65("button", { type: "button", className: "fd-mode-opt" + (test ? " is-on" : ""), onClick: () => go("test"), children: [
9062
+ /* @__PURE__ */ jsx71("i", { className: "ph ph-flask", "aria-hidden": "true" }),
9063
+ /* @__PURE__ */ jsxs65("span", { className: "fd-mode-opt-text", children: [
9064
+ /* @__PURE__ */ jsx71("span", { className: "fd-mode-opt-title", children: "Test mode" }),
9065
+ /* @__PURE__ */ jsx71("span", { className: "fd-mode-opt-desc", children: "Everything usable, all data simulated" })
8874
9066
  ] }),
8875
- test ? /* @__PURE__ */ jsx70("i", { className: "ph ph-check", "aria-hidden": "true" }) : null
9067
+ test ? /* @__PURE__ */ jsx71("i", { className: "ph ph-check", "aria-hidden": "true" }) : null
8876
9068
  ] })
8877
9069
  ] }),
8878
- test && renderLog ? /* @__PURE__ */ jsx70("span", { style: { display: "block", maxHeight: 340, overflowY: "auto", borderTop: "1px solid var(--border)" }, children: renderLog() }) : null
9070
+ test && renderLog ? /* @__PURE__ */ jsx71("span", { style: { display: "block", maxHeight: 340, overflowY: "auto", borderTop: "1px solid var(--border)" }, children: renderLog() }) : null
8879
9071
  ] }) }) : null
8880
9072
  ] });
8881
9073
  }
8882
9074
  function TestModeBar({ onExit }) {
8883
9075
  const mode2 = useRuntimeMode();
8884
9076
  if (mode2 !== "test") return null;
8885
- return /* @__PURE__ */ jsxs64("div", { className: "fd-testbar", role: "status", children: [
8886
- /* @__PURE__ */ jsxs64("span", { className: "fd-badge fd-badge-warning", children: [
8887
- /* @__PURE__ */ jsx70("i", { className: "ph ph-flask", "aria-hidden": "true" }),
9077
+ return /* @__PURE__ */ jsxs65("div", { className: "fd-testbar", role: "status", children: [
9078
+ /* @__PURE__ */ jsxs65("span", { className: "fd-badge fd-badge-warning", children: [
9079
+ /* @__PURE__ */ jsx71("i", { className: "ph ph-flask", "aria-hidden": "true" }),
8888
9080
  "Test mode"
8889
9081
  ] }),
8890
- /* @__PURE__ */ jsx70("span", { className: "fd-testbar-detail", children: "Every feature is unlocked and every response is simulated \u2014 nothing here persists." }),
8891
- /* @__PURE__ */ jsxs64("button", { type: "button", className: "fd-soon-link", onClick: () => onExit ? onExit() : RuntimeKit.setMode("live"), children: [
8892
- /* @__PURE__ */ jsx70("i", { className: "ph ph-lightning", "aria-hidden": "true" }),
9082
+ /* @__PURE__ */ jsx71("span", { className: "fd-testbar-detail", children: "Every feature is unlocked and every response is simulated \u2014 nothing here persists." }),
9083
+ /* @__PURE__ */ jsxs65("button", { type: "button", className: "fd-soon-link", onClick: () => onExit ? onExit() : RuntimeKit.setMode("live"), children: [
9084
+ /* @__PURE__ */ jsx71("i", { className: "ph ph-lightning", "aria-hidden": "true" }),
8893
9085
  " Back to live mode"
8894
9086
  ] })
8895
9087
  ] });
8896
9088
  }
8897
9089
 
8898
9090
  // src/components/planner/ChannelMeta.tsx
8899
- import { jsx as jsx71, jsxs as jsxs65 } from "react/jsx-runtime";
9091
+ import { jsx as jsx72, jsxs as jsxs66 } from "react/jsx-runtime";
8900
9092
  var CHANNEL_WEIGHTS = {
8901
9093
  "OOH": 50,
8902
9094
  "DOOH": 50,
@@ -8949,9 +9141,9 @@ function ChannelTag({ channel, size = "md", showLabel = true, dot = false, weigh
8949
9141
  const m = ChannelMeta(channel);
8950
9142
  const wt = channelWeightOf(channel || "");
8951
9143
  if (dot) {
8952
- return /* @__PURE__ */ jsx71("span", { className: ["fd-chan-dot", className].filter(Boolean).join(" "), title: m.name, style: { background: m.color }, ...rest });
9144
+ return /* @__PURE__ */ jsx72("span", { className: ["fd-chan-dot", className].filter(Boolean).join(" "), title: m.name, style: { background: m.color }, ...rest });
8953
9145
  }
8954
- return /* @__PURE__ */ jsxs65(
9146
+ return /* @__PURE__ */ jsxs66(
8955
9147
  "span",
8956
9148
  {
8957
9149
  className: ["fd-chan", size === "sm" ? "fd-chan-sm" : "", className].filter(Boolean).join(" "),
@@ -8959,16 +9151,16 @@ function ChannelTag({ channel, size = "md", showLabel = true, dot = false, weigh
8959
9151
  style: { "--chan": m.color },
8960
9152
  ...rest,
8961
9153
  children: [
8962
- /* @__PURE__ */ jsx71("i", { className: "ph ph-" + m.icon, "aria-hidden": "true" }),
8963
- showLabel ? /* @__PURE__ */ jsx71("span", { className: "fd-chan-label", children: m.label }) : null,
8964
- weight ? /* @__PURE__ */ jsx71("span", { className: "fd-chan-weight", children: wt || 0 }) : null
9154
+ /* @__PURE__ */ jsx72("i", { className: "ph ph-" + m.icon, "aria-hidden": "true" }),
9155
+ showLabel ? /* @__PURE__ */ jsx72("span", { className: "fd-chan-label", children: m.label }) : null,
9156
+ weight ? /* @__PURE__ */ jsx72("span", { className: "fd-chan-weight", children: wt || 0 }) : null
8965
9157
  ]
8966
9158
  }
8967
9159
  );
8968
9160
  }
8969
9161
 
8970
9162
  // src/components/planner/SaturationDistribution.tsx
8971
- import { jsx as jsx72, jsxs as jsxs66 } from "react/jsx-runtime";
9163
+ import { jsx as jsx73, jsxs as jsxs67 } from "react/jsx-runtime";
8972
9164
  var BANDS2 = [
8973
9165
  { key: "weak", label: "Weak", n: 1, range: "< 50" },
8974
9166
  { key: "adequate", label: "Adequate", n: 2, range: "50\u2013100" },
@@ -8979,24 +9171,24 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
8979
9171
  const grouped = BANDS2.map((b) => ({ ...b, items: campuses.filter((c) => c.band === b.key) }));
8980
9172
  const tallest = Math.max(1, ...grouped.map((g) => g.items.length));
8981
9173
  const floor = BANDS2.find((b) => b.key === floorBand) || BANDS2[0];
8982
- return /* @__PURE__ */ jsxs66("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 16 }, children: [
8983
- /* @__PURE__ */ jsx72("div", { style: { display: "grid", gridTemplateColumns: "repeat(4,minmax(0,1fr))", gap: 12, alignItems: "end" }, children: grouped.map((g) => {
9174
+ return /* @__PURE__ */ jsxs67("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 16 }, children: [
9175
+ /* @__PURE__ */ jsx73("div", { style: { display: "grid", gridTemplateColumns: "repeat(4,minmax(0,1fr))", gap: 12, alignItems: "end" }, children: grouped.map((g) => {
8984
9176
  const mark = "var(--csi-" + g.n + "-mark)";
8985
9177
  const active = selectedBand === g.key;
8986
- return /* @__PURE__ */ jsxs66(
9178
+ return /* @__PURE__ */ jsxs67(
8987
9179
  "button",
8988
9180
  {
8989
9181
  type: "button",
8990
9182
  onClick: onSelectBand ? () => onSelectBand(active ? null : g.key) : void 0,
8991
9183
  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)" },
8992
9184
  children: [
8993
- /* @__PURE__ */ jsx72("span", { style: { display: "flex", flexDirection: "column-reverse", gap: 4, minHeight: tallest * 24, minWidth: 0 }, children: loading ? Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsx72("span", { className: "fd-skel", style: { height: 16, borderRadius: 4 } }, i)) : g.items.map((c) => (
9185
+ /* @__PURE__ */ jsx73("span", { style: { display: "flex", flexDirection: "column-reverse", gap: 4, minHeight: tallest * 24, minWidth: 0 }, children: loading ? Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsx73("span", { className: "fd-skel", style: { height: 16, borderRadius: 4 } }, i)) : g.items.map((c) => (
8994
9186
  // `overflow: hidden` + `white-space: nowrap` only clips once the span
8995
9187
  // actually HAS a bounded width to clip against (see the grid/flex
8996
9188
  // `minWidth: 0` chain above) — `textOverflow: ellipsis` then makes
8997
9189
  // that clip readable instead of a hard cut mid-letter; the full name
8998
9190
  // is still one hover away via `title`.
8999
- /* @__PURE__ */ jsx72(
9191
+ /* @__PURE__ */ jsx73(
9000
9192
  "span",
9001
9193
  {
9002
9194
  title: c.name + " \xB7 " + c.crp,
@@ -9006,13 +9198,13 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
9006
9198
  c.name
9007
9199
  )
9008
9200
  )) }),
9009
- /* @__PURE__ */ jsxs66("span", { className: "fd-row", style: { gap: 8, alignItems: "baseline" }, children: [
9010
- /* @__PURE__ */ jsx72("span", { className: "fd-num-hero", style: { fontSize: 30, color: g.items.length ? "var(--text)" : "var(--text-disabled)" }, children: loading ? "\u2013" : g.items.length }),
9011
- /* @__PURE__ */ jsx72("span", { className: "fd-meter", style: { gap: 2, color: mark }, "aria-hidden": "true", children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx72("span", { className: "fd-meter-seg" + (i <= g.n ? " is-on" : ""), style: { width: 4, height: 9 } }, i)) })
9201
+ /* @__PURE__ */ jsxs67("span", { className: "fd-row", style: { gap: 8, alignItems: "baseline" }, children: [
9202
+ /* @__PURE__ */ jsx73("span", { className: "fd-num-hero", style: { fontSize: 30, color: g.items.length ? "var(--text)" : "var(--text-disabled)" }, children: loading ? "\u2013" : g.items.length }),
9203
+ /* @__PURE__ */ jsx73("span", { className: "fd-meter", style: { gap: 2, color: mark }, "aria-hidden": "true", children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx73("span", { className: "fd-meter-seg" + (i <= g.n ? " is-on" : ""), style: { width: 4, height: 9 } }, i)) })
9012
9204
  ] }),
9013
- /* @__PURE__ */ jsxs66("span", { className: "fd-stack", style: { gap: 1 }, children: [
9014
- /* @__PURE__ */ jsx72("span", { className: "fd-label-lg", children: g.label }),
9015
- /* @__PURE__ */ jsxs66("span", { className: "fd-body-sm fd-muted", style: { fontSize: 11.5 }, children: [
9205
+ /* @__PURE__ */ jsxs67("span", { className: "fd-stack", style: { gap: 1 }, children: [
9206
+ /* @__PURE__ */ jsx73("span", { className: "fd-label-lg", children: g.label }),
9207
+ /* @__PURE__ */ jsxs67("span", { className: "fd-body-sm fd-muted", style: { fontSize: 11.5 }, children: [
9016
9208
  "CRP ",
9017
9209
  g.range
9018
9210
  ] })
@@ -9022,10 +9214,10 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
9022
9214
  g.key
9023
9215
  );
9024
9216
  }) }),
9025
- floorBand ? /* @__PURE__ */ jsxs66("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: [
9026
- /* @__PURE__ */ jsx72("span", { className: "fd-meter", style: { gap: 2, color: "var(--csi-" + floor.n + "-mark)" }, "aria-hidden": "true", children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx72("span", { className: "fd-meter-seg" + (i <= floor.n ? " is-on" : ""), style: { width: 5, height: 12 } }, i)) }),
9027
- /* @__PURE__ */ jsxs66("span", { className: "fd-body-sm fd-secondary", style: { flex: 1, minWidth: 240 }, children: [
9028
- /* @__PURE__ */ jsxs66("strong", { style: { color: "var(--text)" }, children: [
9217
+ floorBand ? /* @__PURE__ */ jsxs67("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: [
9218
+ /* @__PURE__ */ jsx73("span", { className: "fd-meter", style: { gap: 2, color: "var(--csi-" + floor.n + "-mark)" }, "aria-hidden": "true", children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx73("span", { className: "fd-meter-seg" + (i <= floor.n ? " is-on" : ""), style: { width: 5, height: 12 } }, i)) }),
9219
+ /* @__PURE__ */ jsxs67("span", { className: "fd-body-sm fd-secondary", style: { flex: 1, minWidth: 240 }, children: [
9220
+ /* @__PURE__ */ jsxs67("strong", { style: { color: "var(--text)" }, children: [
9029
9221
  "Plan floor ",
9030
9222
  floorScore
9031
9223
  ] }),
@@ -9036,8 +9228,8 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
9036
9228
  }
9037
9229
 
9038
9230
  // src/components/planner/MixGap.tsx
9039
- import * as React47 from "react";
9040
- import { Fragment as Fragment21, jsx as jsx73, jsxs as jsxs67 } from "react/jsx-runtime";
9231
+ import * as React48 from "react";
9232
+ import { Fragment as Fragment22, jsx as jsx74, jsxs as jsxs68 } from "react/jsx-runtime";
9041
9233
  var MIX_GAP_LAYOUT = {
9042
9234
  trackHeight: 30,
9043
9235
  barHeight: 20,
@@ -9051,19 +9243,19 @@ function mixGapOffset(value, max) {
9051
9243
  }
9052
9244
  function MixGap({ rows = [], loading = false, className = "" }) {
9053
9245
  const max = Math.max(1, ...rows.flatMap((r) => [r.target, r.realized]));
9054
- const [hover, setHover] = React47.useState(null);
9246
+ const [hover, setHover] = React48.useState(null);
9055
9247
  const toneOf = (gap) => gap >= -1 ? "ok" : gap >= -4 ? "warn" : "danger";
9056
9248
  const TONE = { ok: "var(--ok-solid)", warn: "var(--warn-solid)", danger: "var(--danger-solid)" };
9057
9249
  const { trackHeight, barHeight, targetWidth, labelGap } = MIX_GAP_LAYOUT;
9058
9250
  const barTop = (trackHeight - barHeight) / 2;
9059
- return /* @__PURE__ */ jsxs67("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 4 }, children: [
9060
- /* @__PURE__ */ jsxs67("div", { className: "fd-row", style: { gap: 16, justifyContent: "flex-end", paddingBottom: 6, flexWrap: "wrap" }, children: [
9061
- [["On target", TONE.ok], ["Close", TONE.warn], ["Short", TONE.danger]].map(([l, c]) => /* @__PURE__ */ jsxs67("span", { className: "fd-row fd-body-sm fd-muted", style: { gap: 6 }, children: [
9062
- /* @__PURE__ */ jsx73("span", { style: { width: 14, height: 9, borderRadius: 2, background: c } }),
9251
+ return /* @__PURE__ */ jsxs68("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 4 }, children: [
9252
+ /* @__PURE__ */ jsxs68("div", { className: "fd-row", style: { gap: 16, justifyContent: "flex-end", paddingBottom: 6, flexWrap: "wrap" }, children: [
9253
+ [["On target", TONE.ok], ["Close", TONE.warn], ["Short", TONE.danger]].map(([l, c]) => /* @__PURE__ */ jsxs68("span", { className: "fd-row fd-body-sm fd-muted", style: { gap: 6 }, children: [
9254
+ /* @__PURE__ */ jsx74("span", { style: { width: 14, height: 9, borderRadius: 2, background: c } }),
9063
9255
  l
9064
9256
  ] }, l)),
9065
- /* @__PURE__ */ jsxs67("span", { className: "fd-row fd-body-sm fd-muted", style: { gap: 6 }, children: [
9066
- /* @__PURE__ */ jsx73("span", { "data-mixgap-legend-target": "", style: { width: targetWidth, height: 16, borderRadius: 1, background: MIX_GAP_TARGET_STRIPE } }),
9257
+ /* @__PURE__ */ jsxs68("span", { className: "fd-row fd-body-sm fd-muted", style: { gap: 6 }, children: [
9258
+ /* @__PURE__ */ jsx74("span", { "data-mixgap-legend-target": "", style: { width: targetWidth, height: 16, borderRadius: 1, background: MIX_GAP_TARGET_STRIPE } }),
9067
9259
  "Target"
9068
9260
  ] })
9069
9261
  ] }),
@@ -9072,7 +9264,7 @@ function MixGap({ rows = [], loading = false, className = "" }) {
9072
9264
  const tone = toneOf(gap);
9073
9265
  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 : "");
9074
9266
  const labelLeft = r.realized > r.target ? `calc(${mixGapOffset(r.realized, max)} + ${labelGap}px)` : `calc(${mixGapOffset(r.target, max)} + ${targetWidth / 2 + labelGap}px)`;
9075
- return /* @__PURE__ */ jsxs67(
9267
+ return /* @__PURE__ */ jsxs68(
9076
9268
  "div",
9077
9269
  {
9078
9270
  className: "fd-row",
@@ -9080,15 +9272,15 @@ function MixGap({ rows = [], loading = false, className = "" }) {
9080
9272
  onMouseEnter: () => setHover(r.channel),
9081
9273
  onMouseLeave: () => setHover(null),
9082
9274
  children: [
9083
- /* @__PURE__ */ jsx73("span", { style: { width: 128, flex: "none" }, children: /* @__PURE__ */ jsx73(ChannelTag, { channel: r.channel, size: "sm" }) }),
9084
- /* @__PURE__ */ jsx73("span", { style: { position: "relative", flex: 1, height: trackHeight, minWidth: 120 }, children: loading ? /* @__PURE__ */ jsx73("span", { className: "fd-skel", style: { position: "absolute", left: 0, right: 0, top: barTop, height: barHeight, borderRadius: 3 } }) : /* @__PURE__ */ jsxs67(Fragment21, { children: [
9085
- /* @__PURE__ */ jsx73("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)" } }),
9086
- /* @__PURE__ */ jsx73("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 } }),
9087
- /* @__PURE__ */ jsxs67("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: [
9275
+ /* @__PURE__ */ jsx74("span", { style: { width: 128, flex: "none" }, children: /* @__PURE__ */ jsx74(ChannelTag, { channel: r.channel, size: "sm" }) }),
9276
+ /* @__PURE__ */ jsx74("span", { style: { position: "relative", flex: 1, height: trackHeight, minWidth: 120 }, children: loading ? /* @__PURE__ */ jsx74("span", { className: "fd-skel", style: { position: "absolute", left: 0, right: 0, top: barTop, height: barHeight, borderRadius: 3 } }) : /* @__PURE__ */ jsxs68(Fragment22, { children: [
9277
+ /* @__PURE__ */ jsx74("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)" } }),
9278
+ /* @__PURE__ */ jsx74("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 } }),
9279
+ /* @__PURE__ */ jsxs68("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: [
9088
9280
  r.realized,
9089
9281
  "%"
9090
9282
  ] }),
9091
- hover === r.channel ? /* @__PURE__ */ jsx73("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
9283
+ hover === r.channel ? /* @__PURE__ */ jsx74("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
9092
9284
  ] }) })
9093
9285
  ]
9094
9286
  },
@@ -9099,7 +9291,7 @@ function MixGap({ rows = [], loading = false, className = "" }) {
9099
9291
  }
9100
9292
 
9101
9293
  // src/components/planner/ChannelContribution.tsx
9102
- import { jsx as jsx74, jsxs as jsxs68 } from "react/jsx-runtime";
9294
+ import { jsx as jsx75, jsxs as jsxs69 } from "react/jsx-runtime";
9103
9295
  var money = (n) => "$" + Math.round(n).toLocaleString();
9104
9296
  function ChannelContribution({
9105
9297
  channels = [],
@@ -9115,9 +9307,9 @@ function ChannelContribution({
9115
9307
  const grand = total !== void 0 ? total : base + bonus;
9116
9308
  const pct = (v) => grand ? v / grand * 100 : 0;
9117
9309
  const spendTotal = channels.reduce((s, c) => s + Number(String(c.spend || 0).replace(/[^0-9.]/g, "")), 0);
9118
- return /* @__PURE__ */ jsxs68("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 16 }, children: [
9119
- loading ? /* @__PURE__ */ jsx74("span", { className: "fd-skel", style: { height: 34, borderRadius: "var(--r-sm)" } }) : /* @__PURE__ */ jsxs68("div", { className: "fd-row", style: { height: 34, borderRadius: "var(--r-sm)", overflow: "hidden", gap: 2, background: "var(--surface-3)" }, children: [
9120
- channels.map((c) => /* @__PURE__ */ jsx74(
9310
+ return /* @__PURE__ */ jsxs69("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 16 }, children: [
9311
+ loading ? /* @__PURE__ */ jsx75("span", { className: "fd-skel", style: { height: 34, borderRadius: "var(--r-sm)" } }) : /* @__PURE__ */ jsxs69("div", { className: "fd-row", style: { height: 34, borderRadius: "var(--r-sm)", overflow: "hidden", gap: 2, background: "var(--surface-3)" }, children: [
9312
+ channels.map((c) => /* @__PURE__ */ jsx75(
9121
9313
  "span",
9122
9314
  {
9123
9315
  title: c.name + " \xB7 " + c.crp.toFixed(1) + " CRP",
@@ -9126,7 +9318,7 @@ function ChannelContribution({
9126
9318
  },
9127
9319
  c.name
9128
9320
  )),
9129
- bonus > 0 ? /* @__PURE__ */ jsx74(
9321
+ bonus > 0 ? /* @__PURE__ */ jsx75(
9130
9322
  "span",
9131
9323
  {
9132
9324
  title: "Surround-sound bonus +" + bonusPct + "%",
@@ -9135,18 +9327,18 @@ function ChannelContribution({
9135
9327
  }
9136
9328
  ) : null
9137
9329
  ] }),
9138
- showTable ? /* @__PURE__ */ jsxs68("table", { className: "fd-table", style: { fontSize: "var(--body-sm-size)" }, children: [
9139
- /* @__PURE__ */ jsx74("thead", { children: /* @__PURE__ */ jsxs68("tr", { children: [
9140
- /* @__PURE__ */ jsx74("th", { style: { width: "34%" }, children: "Channel" }),
9141
- /* @__PURE__ */ jsx74("th", { style: { width: "16%" }, children: "Weight" }),
9142
- /* @__PURE__ */ jsx74("th", { className: "is-num", style: { width: "16%" }, children: "Spend" }),
9143
- /* @__PURE__ */ jsx74("th", { className: "is-num", style: { width: "17%" }, children: "CRP" }),
9144
- /* @__PURE__ */ jsx74("th", { className: "is-num", style: { width: "17%" }, children: "Share" })
9330
+ showTable ? /* @__PURE__ */ jsxs69("table", { className: "fd-table", style: { fontSize: "var(--body-sm-size)" }, children: [
9331
+ /* @__PURE__ */ jsx75("thead", { children: /* @__PURE__ */ jsxs69("tr", { children: [
9332
+ /* @__PURE__ */ jsx75("th", { style: { width: "34%" }, children: "Channel" }),
9333
+ /* @__PURE__ */ jsx75("th", { style: { width: "16%" }, children: "Weight" }),
9334
+ /* @__PURE__ */ jsx75("th", { className: "is-num", style: { width: "16%" }, children: "Spend" }),
9335
+ /* @__PURE__ */ jsx75("th", { className: "is-num", style: { width: "17%" }, children: "CRP" }),
9336
+ /* @__PURE__ */ jsx75("th", { className: "is-num", style: { width: "17%" }, children: "Share" })
9145
9337
  ] }) }),
9146
- /* @__PURE__ */ jsxs68("tbody", { children: [
9147
- channels.map((c) => /* @__PURE__ */ jsxs68("tr", { children: [
9148
- /* @__PURE__ */ jsx74("td", { children: /* @__PURE__ */ jsx74(ChannelTag, { channel: c.name, size: "sm" }) }),
9149
- /* @__PURE__ */ jsx74("td", { children: /* @__PURE__ */ jsx74(
9338
+ /* @__PURE__ */ jsxs69("tbody", { children: [
9339
+ channels.map((c) => /* @__PURE__ */ jsxs69("tr", { children: [
9340
+ /* @__PURE__ */ jsx75("td", { children: /* @__PURE__ */ jsx75(ChannelTag, { channel: c.name, size: "sm" }) }),
9341
+ /* @__PURE__ */ jsx75("td", { children: /* @__PURE__ */ jsx75(
9150
9342
  "span",
9151
9343
  {
9152
9344
  className: "fd-badge fd-badge-neutral",
@@ -9155,38 +9347,38 @@ function ChannelContribution({
9155
9347
  children: "weight " + (channelWeightOf(c.name) || 0)
9156
9348
  }
9157
9349
  ) }),
9158
- /* @__PURE__ */ jsx74("td", { className: "is-num", children: c.spend }),
9159
- /* @__PURE__ */ jsx74("td", { className: "is-num", children: c.crp.toFixed(1) }),
9160
- /* @__PURE__ */ jsxs68("td", { className: "is-num", children: [
9350
+ /* @__PURE__ */ jsx75("td", { className: "is-num", children: c.spend }),
9351
+ /* @__PURE__ */ jsx75("td", { className: "is-num", children: c.crp.toFixed(1) }),
9352
+ /* @__PURE__ */ jsxs69("td", { className: "is-num", children: [
9161
9353
  pct(c.crp).toFixed(0),
9162
9354
  "%"
9163
9355
  ] })
9164
9356
  ] }, c.name)),
9165
- bonus > 0 ? /* @__PURE__ */ jsxs68("tr", { children: [
9166
- /* @__PURE__ */ jsx74("td", { children: /* @__PURE__ */ jsxs68("span", { className: "fd-row", style: { gap: 9, fontWeight: 600 }, children: [
9167
- /* @__PURE__ */ jsx74("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" } }),
9357
+ bonus > 0 ? /* @__PURE__ */ jsxs69("tr", { children: [
9358
+ /* @__PURE__ */ jsx75("td", { children: /* @__PURE__ */ jsxs69("span", { className: "fd-row", style: { gap: 9, fontWeight: 600 }, children: [
9359
+ /* @__PURE__ */ jsx75("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" } }),
9168
9360
  "Surround-sound bonus"
9169
9361
  ] }) }),
9170
- /* @__PURE__ */ jsx74("td", { children: /* @__PURE__ */ jsxs68("span", { className: "fd-badge fd-badge-success", style: { height: 20, fontSize: 11 }, children: [
9362
+ /* @__PURE__ */ jsx75("td", { children: /* @__PURE__ */ jsxs69("span", { className: "fd-badge fd-badge-success", style: { height: 20, fontSize: 11 }, children: [
9171
9363
  "+",
9172
9364
  bonusPct,
9173
9365
  "% of +",
9174
9366
  bonusMax,
9175
9367
  "%"
9176
9368
  ] }) }),
9177
- /* @__PURE__ */ jsx74("td", { className: "is-num fd-muted", children: "\u2014" }),
9178
- /* @__PURE__ */ jsx74("td", { className: "is-num", children: bonus.toFixed(1) }),
9179
- /* @__PURE__ */ jsxs68("td", { className: "is-num", children: [
9369
+ /* @__PURE__ */ jsx75("td", { className: "is-num fd-muted", children: "\u2014" }),
9370
+ /* @__PURE__ */ jsx75("td", { className: "is-num", children: bonus.toFixed(1) }),
9371
+ /* @__PURE__ */ jsxs69("td", { className: "is-num", children: [
9180
9372
  pct(bonus).toFixed(0),
9181
9373
  "%"
9182
9374
  ] })
9183
9375
  ] }) : null,
9184
- /* @__PURE__ */ jsxs68("tr", { style: { background: "var(--surface-2)" }, children: [
9185
- /* @__PURE__ */ jsx74("td", { style: { fontWeight: 700 }, children: "Campus total" }),
9186
- /* @__PURE__ */ jsx74("td", {}),
9187
- /* @__PURE__ */ jsx74("td", { className: "is-num", style: { fontWeight: 700 }, children: money(spendTotal) }),
9188
- /* @__PURE__ */ jsx74("td", { className: "is-num", style: { fontWeight: 700 }, children: grand.toFixed(1) }),
9189
- /* @__PURE__ */ jsx74("td", { className: "is-num", style: { fontWeight: 700 }, children: "100%" })
9376
+ /* @__PURE__ */ jsxs69("tr", { style: { background: "var(--surface-2)" }, children: [
9377
+ /* @__PURE__ */ jsx75("td", { style: { fontWeight: 700 }, children: "Campus total" }),
9378
+ /* @__PURE__ */ jsx75("td", {}),
9379
+ /* @__PURE__ */ jsx75("td", { className: "is-num", style: { fontWeight: 700 }, children: money(spendTotal) }),
9380
+ /* @__PURE__ */ jsx75("td", { className: "is-num", style: { fontWeight: 700 }, children: grand.toFixed(1) }),
9381
+ /* @__PURE__ */ jsx75("td", { className: "is-num", style: { fontWeight: 700 }, children: "100%" })
9190
9382
  ] })
9191
9383
  ] })
9192
9384
  ] }) : null
@@ -9194,8 +9386,8 @@ function ChannelContribution({
9194
9386
  }
9195
9387
 
9196
9388
  // src/components/planner/BudgetReallocator.tsx
9197
- import * as React48 from "react";
9198
- import { Fragment as Fragment22, jsx as jsx75, jsxs as jsxs69 } from "react/jsx-runtime";
9389
+ import * as React49 from "react";
9390
+ import { Fragment as Fragment23, jsx as jsx76, jsxs as jsxs70 } from "react/jsx-runtime";
9199
9391
  var bandFor = (crp) => crp >= 200 ? "dominant" : crp >= 100 ? "strong" : crp >= 50 ? "adequate" : "weak";
9200
9392
  function BudgetReallocator({
9201
9393
  campus,
@@ -9210,8 +9402,8 @@ function BudgetReallocator({
9210
9402
  onCancel,
9211
9403
  className = ""
9212
9404
  }) {
9213
- const [draft, setDraft] = React48.useState(spend);
9214
- React48.useEffect(() => setDraft(spend), [spend]);
9405
+ const [draft, setDraft] = React49.useState(spend);
9406
+ React49.useEffect(() => setDraft(spend), [spend]);
9215
9407
  const dirty = draft !== spend;
9216
9408
  const nextCrp = scoreFor ? scoreFor(draft) : crp;
9217
9409
  const nextBand = bandFor(nextCrp);
@@ -9226,10 +9418,10 @@ function BudgetReallocator({
9226
9418
  setDraft(spend);
9227
9419
  if (onCancel) onCancel();
9228
9420
  };
9229
- const trackRef = React48.useRef(null);
9230
- const chipRef = React48.useRef(null);
9231
- const [chipLeft, setChipLeft] = React48.useState(null);
9232
- React48.useLayoutEffect(() => {
9421
+ const trackRef = React49.useRef(null);
9422
+ const chipRef = React49.useRef(null);
9423
+ const [chipLeft, setChipLeft] = React49.useState(null);
9424
+ React49.useLayoutEffect(() => {
9233
9425
  const track = trackRef.current;
9234
9426
  if (!dirty || !track) {
9235
9427
  setChipLeft(null);
@@ -9250,23 +9442,23 @@ function BudgetReallocator({
9250
9442
  ro.observe(track);
9251
9443
  return () => ro.disconnect();
9252
9444
  }, [dirty, pct]);
9253
- return /* @__PURE__ */ jsxs69(
9445
+ return /* @__PURE__ */ jsxs70(
9254
9446
  "div",
9255
9447
  {
9256
9448
  className: ["fd-stack", className].filter(Boolean).join(" "),
9257
9449
  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)" },
9258
9450
  children: [
9259
- /* @__PURE__ */ jsxs69("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
9260
- /* @__PURE__ */ jsx75("span", { className: "fd-h4", style: { flex: 1, minWidth: 140 }, children: campus }),
9261
- /* @__PURE__ */ jsx75(CsiBadge, { band: nowBand, crp, size: "medium" }),
9262
- dirty ? /* @__PURE__ */ jsxs69(Fragment22, { children: [
9263
- /* @__PURE__ */ jsx75("i", { className: "ph ph-arrow-right fd-muted", "aria-hidden": "true" }),
9264
- /* @__PURE__ */ jsx75(CsiBadge, { band: nextBand, crp: nextCrp, size: "medium", preview: true })
9451
+ /* @__PURE__ */ jsxs70("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
9452
+ /* @__PURE__ */ jsx76("span", { className: "fd-h4", style: { flex: 1, minWidth: 140 }, children: campus }),
9453
+ /* @__PURE__ */ jsx76(CsiBadge, { band: nowBand, crp, size: "medium" }),
9454
+ dirty ? /* @__PURE__ */ jsxs70(Fragment23, { children: [
9455
+ /* @__PURE__ */ jsx76("i", { className: "ph ph-arrow-right fd-muted", "aria-hidden": "true" }),
9456
+ /* @__PURE__ */ jsx76(CsiBadge, { band: nextBand, crp: nextCrp, size: "medium", preview: true })
9265
9457
  ] }) : null
9266
9458
  ] }),
9267
- /* @__PURE__ */ jsxs69("div", { className: "fd-slider", ref: trackRef, children: [
9268
- /* @__PURE__ */ jsx75("span", { className: "fd-slider-fill", style: { width: pct + "%" } }),
9269
- dirty ? /* @__PURE__ */ jsx75(
9459
+ /* @__PURE__ */ jsxs70("div", { className: "fd-slider", ref: trackRef, children: [
9460
+ /* @__PURE__ */ jsx76("span", { className: "fd-slider-fill", style: { width: pct + "%" } }),
9461
+ dirty ? /* @__PURE__ */ jsx76(
9270
9462
  "span",
9271
9463
  {
9272
9464
  ref: chipRef,
@@ -9278,7 +9470,7 @@ function BudgetReallocator({
9278
9470
  children: (delta < 0 ? "\u2212$" : "+$") + Math.abs(delta).toLocaleString()
9279
9471
  }
9280
9472
  ) : null,
9281
- /* @__PURE__ */ jsx75(
9473
+ /* @__PURE__ */ jsx76(
9282
9474
  "input",
9283
9475
  {
9284
9476
  type: "range",
@@ -9294,13 +9486,13 @@ function BudgetReallocator({
9294
9486
  }
9295
9487
  )
9296
9488
  ] }),
9297
- /* @__PURE__ */ jsxs69("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
9298
- /* @__PURE__ */ jsxs69("span", { className: "fd-stack", style: { gap: 2, flex: 1, minWidth: 150 }, children: [
9299
- /* @__PURE__ */ jsx75("span", { className: "fd-num", style: { fontSize: 19, fontWeight: 700 }, children: "$" + draft.toLocaleString() }),
9300
- /* @__PURE__ */ jsx75("span", { className: "fd-body-sm fd-muted", children: "Arrow keys step $100, shift+arrow $1,000. Escape reverts." })
9489
+ /* @__PURE__ */ jsxs70("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
9490
+ /* @__PURE__ */ jsxs70("span", { className: "fd-stack", style: { gap: 2, flex: 1, minWidth: 150 }, children: [
9491
+ /* @__PURE__ */ jsx76("span", { className: "fd-num", style: { fontSize: 19, fontWeight: 700 }, children: "$" + draft.toLocaleString() }),
9492
+ /* @__PURE__ */ jsx76("span", { className: "fd-body-sm fd-muted", children: "Arrow keys step $100, shift+arrow $1,000. Escape reverts." })
9301
9493
  ] }),
9302
- /* @__PURE__ */ jsx75("button", { type: "button", className: "fd-btn fd-btn-ghost", disabled: !dirty, onClick: revert, children: "Cancel" }),
9303
- /* @__PURE__ */ jsx75(
9494
+ /* @__PURE__ */ jsx76("button", { type: "button", className: "fd-btn fd-btn-ghost", disabled: !dirty, onClick: revert, children: "Cancel" }),
9495
+ /* @__PURE__ */ jsx76(
9304
9496
  "button",
9305
9497
  {
9306
9498
  type: "button",
@@ -9319,7 +9511,7 @@ function BudgetReallocator({
9319
9511
  }
9320
9512
 
9321
9513
  // src/components/planner/SurroundSound.tsx
9322
- import { jsx as jsx76, jsxs as jsxs70 } from "react/jsx-runtime";
9514
+ import { jsx as jsx77, jsxs as jsxs71 } from "react/jsx-runtime";
9323
9515
  var CATEGORIES = [
9324
9516
  { key: "ooh", label: "OOH", icon: "flag-banner", color: "var(--ch-ooh)" },
9325
9517
  { key: "transit", label: "Transit", icon: "bus", color: "var(--ch-transit)" },
@@ -9331,26 +9523,26 @@ var CATEGORIES = [
9331
9523
  function SurroundSound({ present = [], bonusPct = 0, bonusMax = 40, missedCost, className = "" }) {
9332
9524
  const earned = Math.max(0, Math.min(1, bonusPct / bonusMax));
9333
9525
  const single = present.length <= 2;
9334
- return /* @__PURE__ */ jsxs70("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 14 }, children: [
9335
- /* @__PURE__ */ jsx76("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: CATEGORIES.map((c) => {
9526
+ return /* @__PURE__ */ jsxs71("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 14 }, children: [
9527
+ /* @__PURE__ */ jsx77("div", { className: "fd-row", style: { gap: 8, flexWrap: "wrap" }, children: CATEGORIES.map((c) => {
9336
9528
  const on = present.includes(c.key);
9337
- return /* @__PURE__ */ jsxs70(
9529
+ return /* @__PURE__ */ jsxs71(
9338
9530
  "span",
9339
9531
  {
9340
9532
  title: c.label + (on ? " \u2014 present" : " \u2014 not bought"),
9341
9533
  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)" },
9342
9534
  children: [
9343
- /* @__PURE__ */ jsx76("i", { className: "ph ph-" + c.icon, style: { fontSize: 19, color: on ? c.color : "var(--text-muted)" }, "aria-hidden": "true" }),
9344
- /* @__PURE__ */ jsx76("span", { style: { fontSize: 10.5, fontWeight: 700 }, children: c.label })
9535
+ /* @__PURE__ */ jsx77("i", { className: "ph ph-" + c.icon, style: { fontSize: 19, color: on ? c.color : "var(--text-muted)" }, "aria-hidden": "true" }),
9536
+ /* @__PURE__ */ jsx77("span", { style: { fontSize: 10.5, fontWeight: 700 }, children: c.label })
9345
9537
  ]
9346
9538
  },
9347
9539
  c.key
9348
9540
  );
9349
9541
  }) }),
9350
- /* @__PURE__ */ jsxs70("div", { className: "fd-stack", style: { gap: 8 }, children: [
9351
- /* @__PURE__ */ jsxs70("div", { className: "fd-row", style: { justifyContent: "space-between", gap: 12 }, children: [
9352
- /* @__PURE__ */ jsx76("span", { className: "fd-label-lg", children: "Surround-sound bonus earned" }),
9353
- /* @__PURE__ */ jsxs70("span", { className: "fd-num", style: { color: single ? "var(--warn-text)" : "var(--csi-3-mark)", fontWeight: 700 }, children: [
9542
+ /* @__PURE__ */ jsxs71("div", { className: "fd-stack", style: { gap: 8 }, children: [
9543
+ /* @__PURE__ */ jsxs71("div", { className: "fd-row", style: { justifyContent: "space-between", gap: 12 }, children: [
9544
+ /* @__PURE__ */ jsx77("span", { className: "fd-label-lg", children: "Surround-sound bonus earned" }),
9545
+ /* @__PURE__ */ jsxs71("span", { className: "fd-num", style: { color: single ? "var(--warn-text)" : "var(--csi-3-mark)", fontWeight: 700 }, children: [
9354
9546
  "+",
9355
9547
  bonusPct,
9356
9548
  "% of +",
@@ -9358,8 +9550,8 @@ function SurroundSound({ present = [], bonusPct = 0, bonusMax = 40, missedCost,
9358
9550
  "%"
9359
9551
  ] })
9360
9552
  ] }),
9361
- /* @__PURE__ */ jsx76("div", { style: { height: 8, borderRadius: "var(--r-xs)", background: "var(--surface-3)", overflow: "hidden" }, children: /* @__PURE__ */ jsx76("div", { style: { height: "100%", width: earned * 100 + "%", background: "var(--csi-3-mark)", borderRadius: "inherit", transition: "width var(--dur-slow) var(--ease)" } }) }),
9362
- /* @__PURE__ */ jsxs70("span", { className: "fd-body-sm fd-secondary", style: { textWrap: "pretty" }, children: [
9553
+ /* @__PURE__ */ jsx77("div", { style: { height: 8, borderRadius: "var(--r-xs)", background: "var(--surface-3)", overflow: "hidden" }, children: /* @__PURE__ */ jsx77("div", { style: { height: "100%", width: earned * 100 + "%", background: "var(--csi-3-mark)", borderRadius: "inherit", transition: "width var(--dur-slow) var(--ease)" } }) }),
9554
+ /* @__PURE__ */ jsxs71("span", { className: "fd-body-sm fd-secondary", style: { textWrap: "pretty" }, children: [
9363
9555
  present.length,
9364
9556
  " of 6 channel categories present.",
9365
9557
  " ",
@@ -9371,7 +9563,7 @@ function SurroundSound({ present = [], bonusPct = 0, bonusMax = 40, missedCost,
9371
9563
  }
9372
9564
 
9373
9565
  // src/components/planner/Importance.tsx
9374
- import { jsx as jsx77, jsxs as jsxs71 } from "react/jsx-runtime";
9566
+ import { jsx as jsx78, jsxs as jsxs72 } from "react/jsx-runtime";
9375
9567
  var IMPORTANCE_LEVELS = [
9376
9568
  { id: "nudge", rank: 1, label: "Nudge", icon: "feather", description: "Breaks a tie, nothing more." },
9377
9569
  { id: "lean", rank: 2, label: "Lean", icon: "arrow-bend-up-right", description: "A mild preference between otherwise equal options." },
@@ -9401,23 +9593,23 @@ function importanceTokens(id) {
9401
9593
  function ImportanceTag({ level, showLabel = true, size = "sm", className = "" }) {
9402
9594
  const lvl = importanceLevel(level);
9403
9595
  const t = importanceTokens(level);
9404
- return /* @__PURE__ */ jsxs71(
9596
+ return /* @__PURE__ */ jsxs72(
9405
9597
  "span",
9406
9598
  {
9407
9599
  className: ["fd-imp-tag", size === "md" ? "is-md" : "", className].filter(Boolean).join(" "),
9408
9600
  style: { background: t.fill, borderColor: t.edge, color: t.text },
9409
9601
  title: lvl.label + " \u2014 " + lvl.description,
9410
9602
  children: [
9411
- /* @__PURE__ */ jsx77("i", { className: "ph ph-" + lvl.icon, "aria-hidden": "true" }),
9412
- showLabel ? lvl.label : /* @__PURE__ */ jsx77("span", { className: "fd-sr", children: lvl.label })
9603
+ /* @__PURE__ */ jsx78("i", { className: "ph ph-" + lvl.icon, "aria-hidden": "true" }),
9604
+ showLabel ? lvl.label : /* @__PURE__ */ jsx78("span", { className: "fd-sr", children: lvl.label })
9413
9605
  ]
9414
9606
  }
9415
9607
  );
9416
9608
  }
9417
9609
 
9418
9610
  // src/components/planner/PreferenceMeter.tsx
9419
- import * as React49 from "react";
9420
- import { jsx as jsx78, jsxs as jsxs72 } from "react/jsx-runtime";
9611
+ import * as React50 from "react";
9612
+ import { jsx as jsx79, jsxs as jsxs73 } from "react/jsx-runtime";
9421
9613
  function preferenceScore(criteria) {
9422
9614
  const earned = criteria.reduce((n, c) => n + (Number(c.earned) || 0), 0);
9423
9615
  const weight = criteria.reduce((n, c) => n + (Number(c.weight) || 0), 0);
@@ -9446,8 +9638,8 @@ function PreferenceMeter({
9446
9638
  className = ""
9447
9639
  }) {
9448
9640
  const value = score == null ? preferenceScore(criteria) : score;
9449
- const segments = React49.useMemo(() => preferenceSegments(criteria), [criteria]);
9450
- return /* @__PURE__ */ jsx78(
9641
+ const segments = React50.useMemo(() => preferenceSegments(criteria), [criteria]);
9642
+ return /* @__PURE__ */ jsx79(
9451
9643
  ScoreMeter,
9452
9644
  {
9453
9645
  score: value,
@@ -9459,22 +9651,22 @@ function PreferenceMeter({
9459
9651
  placement,
9460
9652
  className,
9461
9653
  breakdownLabel: breakdownTitle,
9462
- breakdown: /* @__PURE__ */ jsxs72("div", { className: "fd-prefbreak", children: [
9463
- /* @__PURE__ */ jsxs72("div", { className: "fd-prefbreak-head", children: [
9464
- /* @__PURE__ */ jsx78("span", { className: "fd-label-lg", children: breakdownTitle }),
9465
- /* @__PURE__ */ jsx78("span", { className: "fd-prefbreak-score fd-tabular", children: Math.round(value) })
9654
+ breakdown: /* @__PURE__ */ jsxs73("div", { className: "fd-prefbreak", children: [
9655
+ /* @__PURE__ */ jsxs73("div", { className: "fd-prefbreak-head", children: [
9656
+ /* @__PURE__ */ jsx79("span", { className: "fd-label-lg", children: breakdownTitle }),
9657
+ /* @__PURE__ */ jsx79("span", { className: "fd-prefbreak-score fd-tabular", children: Math.round(value) })
9466
9658
  ] }),
9467
- /* @__PURE__ */ jsx78("ul", { className: "fd-prefbreak-list", children: criteria.map((c) => {
9659
+ /* @__PURE__ */ jsx79("ul", { className: "fd-prefbreak-list", children: criteria.map((c) => {
9468
9660
  const pct = c.weight > 0 ? Math.round((Number(c.earned) || 0) / c.weight * 100) : 0;
9469
- return /* @__PURE__ */ jsxs72("li", { className: pct === 0 ? "fd-prefbreak-item is-unmet" : "fd-prefbreak-item", children: [
9470
- /* @__PURE__ */ jsx78(ImportanceTag, { level: c.importance }),
9471
- /* @__PURE__ */ jsxs72("span", { className: "fd-prefbreak-text", children: [
9472
- /* @__PURE__ */ jsx78("span", { className: "fd-prefbreak-label", children: c.label }),
9473
- c.note ? /* @__PURE__ */ jsx78("span", { className: "fd-prefbreak-note", children: c.note }) : null
9661
+ return /* @__PURE__ */ jsxs73("li", { className: pct === 0 ? "fd-prefbreak-item is-unmet" : "fd-prefbreak-item", children: [
9662
+ /* @__PURE__ */ jsx79(ImportanceTag, { level: c.importance }),
9663
+ /* @__PURE__ */ jsxs73("span", { className: "fd-prefbreak-text", children: [
9664
+ /* @__PURE__ */ jsx79("span", { className: "fd-prefbreak-label", children: c.label }),
9665
+ c.note ? /* @__PURE__ */ jsx79("span", { className: "fd-prefbreak-note", children: c.note }) : null
9474
9666
  ] }),
9475
- /* @__PURE__ */ jsxs72("span", { className: "fd-prefbreak-val fd-tabular", children: [
9667
+ /* @__PURE__ */ jsxs73("span", { className: "fd-prefbreak-val fd-tabular", children: [
9476
9668
  Math.round(Number(c.earned) || 0),
9477
- /* @__PURE__ */ jsx78("span", { className: "fd-prefbreak-sep", children: "/" }),
9669
+ /* @__PURE__ */ jsx79("span", { className: "fd-prefbreak-sep", children: "/" }),
9478
9670
  Math.round(c.weight)
9479
9671
  ] })
9480
9672
  ] }, c.id);
@@ -9485,10 +9677,10 @@ function PreferenceMeter({
9485
9677
  }
9486
9678
 
9487
9679
  // src/components/chat/AgentChatPanel.tsx
9488
- import * as React55 from "react";
9680
+ import * as React56 from "react";
9489
9681
 
9490
9682
  // src/components/chat/chatEngine.ts
9491
- import * as React50 from "react";
9683
+ import * as React51 from "react";
9492
9684
  var CHAT_UNAVAILABLE = "chat_unavailable";
9493
9685
  var JOB_PENDING = ["queued", "running"];
9494
9686
  var JOB_SUCCESS = ["completed", "recovered"];
@@ -9542,22 +9734,22 @@ function useChatEngine(opts) {
9542
9734
  onClear,
9543
9735
  onFeedback
9544
9736
  } = opts || {};
9545
- const [status, setStatus] = React50.useState("idle");
9546
- const [threadId, setThreadId] = React50.useState(null);
9547
- const [messages, setMessages] = React50.useState([]);
9548
- const [queue, setQueue] = React50.useState([]);
9549
- const [fatal, setFatal] = React50.useState(null);
9550
- const [busy, setBusy] = React50.useState(false);
9551
- const [turnStartedAt, setTurnStartedAt] = React50.useState(null);
9552
- const listRef = React50.useRef([]);
9553
- const queueRef = React50.useRef([]);
9554
- const busyRef = React50.useRef(false);
9555
- const stoppedRef = React50.useRef(false);
9556
- const abortRef = React50.useRef(null);
9557
- const serverCount = React50.useRef(0);
9558
- const threadRef = React50.useRef(null);
9559
- const mounted = React50.useRef(true);
9560
- React50.useEffect(() => {
9737
+ const [status, setStatus] = React51.useState("idle");
9738
+ const [threadId, setThreadId] = React51.useState(null);
9739
+ const [messages, setMessages] = React51.useState([]);
9740
+ const [queue, setQueue] = React51.useState([]);
9741
+ const [fatal, setFatal] = React51.useState(null);
9742
+ const [busy, setBusy] = React51.useState(false);
9743
+ const [turnStartedAt, setTurnStartedAt] = React51.useState(null);
9744
+ const listRef = React51.useRef([]);
9745
+ const queueRef = React51.useRef([]);
9746
+ const busyRef = React51.useRef(false);
9747
+ const stoppedRef = React51.useRef(false);
9748
+ const abortRef = React51.useRef(null);
9749
+ const serverCount = React51.useRef(0);
9750
+ const threadRef = React51.useRef(null);
9751
+ const mounted = React51.useRef(true);
9752
+ React51.useEffect(() => {
9561
9753
  mounted.current = true;
9562
9754
  return () => {
9563
9755
  mounted.current = false;
@@ -9579,14 +9771,14 @@ function useChatEngine(opts) {
9579
9771
  }
9580
9772
  return false;
9581
9773
  };
9582
- const loadThread = React50.useCallback(async (id) => {
9774
+ const loadThread = React51.useCallback(async (id) => {
9583
9775
  const data = await apiAdapter.getThread(id);
9584
9776
  const list = [...data && data.messages || []];
9585
9777
  serverCount.current = list.length;
9586
9778
  commit(list);
9587
9779
  return list;
9588
9780
  }, [apiAdapter]);
9589
- React50.useEffect(() => {
9781
+ React51.useEffect(() => {
9590
9782
  if (!apiAdapter) {
9591
9783
  setStatus("idle");
9592
9784
  setFatal(null);
@@ -9799,7 +9991,7 @@ function useChatEngine(opts) {
9799
9991
  await dispatchTurn(turn);
9800
9992
  }
9801
9993
  }
9802
- const send = React50.useCallback((text, attachments) => {
9994
+ const send = React51.useCallback((text, attachments) => {
9803
9995
  const body = (text || "").trim();
9804
9996
  if (!body && !(attachments && attachments.length)) return;
9805
9997
  if (status === "disconnected") return;
@@ -9809,7 +10001,7 @@ function useChatEngine(opts) {
9809
10001
  stoppedRef.current = false;
9810
10002
  drain();
9811
10003
  }, [status]);
9812
- const stop = React50.useCallback(() => {
10004
+ const stop = React51.useCallback(() => {
9813
10005
  stoppedRef.current = true;
9814
10006
  const ac = abortRef.current;
9815
10007
  if (ac) {
@@ -9828,11 +10020,11 @@ function useChatEngine(opts) {
9828
10020
  store.del(STORAGE_PREFIX + threadRef.current);
9829
10021
  }
9830
10022
  }, [apiAdapter]);
9831
- const removeQueued = React50.useCallback((id) => {
10023
+ const removeQueued = React51.useCallback((id) => {
9832
10024
  queueRef.current = queueRef.current.filter((t) => t.id !== id);
9833
10025
  setQueue(queueRef.current.slice());
9834
10026
  }, []);
9835
- const retry = React50.useCallback(() => {
10027
+ const retry = React51.useCallback(() => {
9836
10028
  const list = listRef.current;
9837
10029
  let at = -1;
9838
10030
  for (let i = list.length - 1; i >= 0; i--) if (list[i].role === "user") {
@@ -9848,19 +10040,19 @@ function useChatEngine(opts) {
9848
10040
  setQueue(queueRef.current.slice());
9849
10041
  drain();
9850
10042
  }, []);
9851
- const clear = React50.useCallback(() => {
10043
+ const clear = React51.useCallback(() => {
9852
10044
  commit([]);
9853
10045
  serverCount.current = 0;
9854
10046
  queueRef.current = [];
9855
10047
  setQueue([]);
9856
10048
  onClear && onClear();
9857
10049
  }, [onClear]);
9858
- const setFeedback = React50.useCallback((id, value) => {
10050
+ const setFeedback = React51.useCallback((id, value) => {
9859
10051
  patch(id, (m) => ({ feedback: m.feedback === value ? null : value }));
9860
10052
  const msg = listRef.current.find((m) => m.id === id);
9861
10053
  onFeedback && onFeedback({ message: msg, feedback: msg ? msg.feedback : value });
9862
10054
  }, [onFeedback]);
9863
- const reload = React50.useCallback(async () => {
10055
+ const reload = React51.useCallback(async () => {
9864
10056
  if (!threadRef.current) return;
9865
10057
  setStatus("loading");
9866
10058
  try {
@@ -9898,11 +10090,11 @@ var ChatKit = {
9898
10090
  };
9899
10091
 
9900
10092
  // src/components/chat/ChatTranscript.tsx
9901
- import * as React52 from "react";
10093
+ import * as React53 from "react";
9902
10094
 
9903
10095
  // src/components/chat/ChatTurn.tsx
9904
- import * as React51 from "react";
9905
- import { jsx as jsx79, jsxs as jsxs73 } from "react/jsx-runtime";
10096
+ import * as React52 from "react";
10097
+ import { jsx as jsx80, jsxs as jsxs74 } from "react/jsx-runtime";
9906
10098
  function JsonView({ value }) {
9907
10099
  let text;
9908
10100
  try {
@@ -9910,67 +10102,67 @@ function JsonView({ value }) {
9910
10102
  } catch (e) {
9911
10103
  text = String(value);
9912
10104
  }
9913
- return /* @__PURE__ */ jsx79(CodeBlock, { code: text, language: "json", collapseAfter: 18 });
10105
+ return /* @__PURE__ */ jsx80(CodeBlock, { code: text, language: "json", collapseAfter: 18 });
9914
10106
  }
9915
10107
  function PacketCard({ packet, schema, render, onApply, applied }) {
9916
10108
  if (!packet) return null;
9917
10109
  const s = schema || {};
9918
10110
  const invalid = packet.valid === false;
9919
10111
  const title = s.heading || packet.type;
9920
- return /* @__PURE__ */ jsxs73("section", { className: "fdc-packet" + (invalid ? " is-invalid" : ""), "aria-label": title, children: [
9921
- /* @__PURE__ */ jsxs73("header", { className: "fdc-packet-head", children: [
9922
- /* @__PURE__ */ jsx79("i", { className: "ph ph-" + (s.icon || "package"), "aria-hidden": "true" }),
9923
- /* @__PURE__ */ jsx79("span", { className: "fdc-packet-title", title: truncationTitle(title), children: title }),
9924
- packet.repaired ? /* @__PURE__ */ jsx79("span", { className: "fdc-packet-badge", children: "Repaired" }) : null,
9925
- invalid ? /* @__PURE__ */ jsx79("span", { className: "fdc-packet-badge is-danger", children: "Invalid" }) : null
10112
+ return /* @__PURE__ */ jsxs74("section", { className: "fdc-packet" + (invalid ? " is-invalid" : ""), "aria-label": title, children: [
10113
+ /* @__PURE__ */ jsxs74("header", { className: "fdc-packet-head", children: [
10114
+ /* @__PURE__ */ jsx80("i", { className: "ph ph-" + (s.icon || "package"), "aria-hidden": "true" }),
10115
+ /* @__PURE__ */ jsx80("span", { className: "fdc-packet-title", title: truncationTitle(title), children: title }),
10116
+ packet.repaired ? /* @__PURE__ */ jsx80("span", { className: "fdc-packet-badge", children: "Repaired" }) : null,
10117
+ invalid ? /* @__PURE__ */ jsx80("span", { className: "fdc-packet-badge is-danger", children: "Invalid" }) : null
9926
10118
  ] }),
9927
- invalid ? /* @__PURE__ */ jsxs73("div", { className: "fdc-packet-alert", role: "alert", children: [
9928
- /* @__PURE__ */ jsx79("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
9929
- /* @__PURE__ */ jsx79("span", { children: packet.error || "This result failed validation and can\u2019t be applied." })
9930
- ] }) : /* @__PURE__ */ jsx79("div", { className: "fdc-packet-body", children: render ? render(packet) : /* @__PURE__ */ jsx79(JsonView, { value: packet.payload }) }),
9931
- !invalid && onApply ? /* @__PURE__ */ jsxs73("footer", { className: "fdc-packet-foot", children: [
9932
- packet.repaired ? /* @__PURE__ */ jsx79("span", { className: "fdc-packet-note", children: "Corrected by the backend after a first attempt." }) : /* @__PURE__ */ jsx79("span", {}),
9933
- /* @__PURE__ */ jsxs73("button", { type: "button", className: "fd-btn fd-btn-primary fd-btn-sm", disabled: applied, onClick: () => onApply(packet), children: [
9934
- /* @__PURE__ */ jsx79("i", { className: "ph ph-" + (applied ? "check" : "arrow-square-in"), "aria-hidden": "true" }),
10119
+ invalid ? /* @__PURE__ */ jsxs74("div", { className: "fdc-packet-alert", role: "alert", children: [
10120
+ /* @__PURE__ */ jsx80("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
10121
+ /* @__PURE__ */ jsx80("span", { children: packet.error || "This result failed validation and can\u2019t be applied." })
10122
+ ] }) : /* @__PURE__ */ jsx80("div", { className: "fdc-packet-body", children: render ? render(packet) : /* @__PURE__ */ jsx80(JsonView, { value: packet.payload }) }),
10123
+ !invalid && onApply ? /* @__PURE__ */ jsxs74("footer", { className: "fdc-packet-foot", children: [
10124
+ packet.repaired ? /* @__PURE__ */ jsx80("span", { className: "fdc-packet-note", children: "Corrected by the backend after a first attempt." }) : /* @__PURE__ */ jsx80("span", {}),
10125
+ /* @__PURE__ */ jsxs74("button", { type: "button", className: "fd-btn fd-btn-primary fd-btn-sm", disabled: applied, onClick: () => onApply(packet), children: [
10126
+ /* @__PURE__ */ jsx80("i", { className: "ph ph-" + (applied ? "check" : "arrow-square-in"), "aria-hidden": "true" }),
9935
10127
  applied ? "Applied" : s.applyLabel || "Apply"
9936
10128
  ] })
9937
10129
  ] }) : null
9938
10130
  ] });
9939
10131
  }
9940
10132
  function ThinkingBlock({ text, durationMs, streaming, defaultOpen = false }) {
9941
- const [open, setOpen] = React51.useState(defaultOpen);
10133
+ const [open, setOpen] = React52.useState(defaultOpen);
9942
10134
  if (!text) return null;
9943
- return /* @__PURE__ */ jsxs73("div", { className: "fdc-think" + (open ? " is-open" : ""), children: [
9944
- /* @__PURE__ */ jsxs73("button", { type: "button", className: "fdc-think-head", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
9945
- /* @__PURE__ */ jsx79("i", { className: "ph ph-brain", "aria-hidden": "true" }),
9946
- /* @__PURE__ */ jsx79("span", { children: streaming ? "Thinking" : durationMs ? "Thought for " + formatDuration(durationMs) : "Thought process" }),
9947
- streaming ? /* @__PURE__ */ jsxs73("span", { className: "fdc-dots", "aria-hidden": "true", children: [
9948
- /* @__PURE__ */ jsx79("span", {}),
9949
- /* @__PURE__ */ jsx79("span", {}),
9950
- /* @__PURE__ */ jsx79("span", {})
10135
+ return /* @__PURE__ */ jsxs74("div", { className: "fdc-think" + (open ? " is-open" : ""), children: [
10136
+ /* @__PURE__ */ jsxs74("button", { type: "button", className: "fdc-think-head", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
10137
+ /* @__PURE__ */ jsx80("i", { className: "ph ph-brain", "aria-hidden": "true" }),
10138
+ /* @__PURE__ */ jsx80("span", { children: streaming ? "Thinking" : durationMs ? "Thought for " + formatDuration(durationMs) : "Thought process" }),
10139
+ streaming ? /* @__PURE__ */ jsxs74("span", { className: "fdc-dots", "aria-hidden": "true", children: [
10140
+ /* @__PURE__ */ jsx80("span", {}),
10141
+ /* @__PURE__ */ jsx80("span", {}),
10142
+ /* @__PURE__ */ jsx80("span", {})
9951
10143
  ] }) : null,
9952
- /* @__PURE__ */ jsx79("i", { className: "ph ph-caret-" + (open ? "up" : "down"), "aria-hidden": "true" })
10144
+ /* @__PURE__ */ jsx80("i", { className: "ph ph-caret-" + (open ? "up" : "down"), "aria-hidden": "true" })
9953
10145
  ] }),
9954
- open ? /* @__PURE__ */ jsx79("div", { className: "fdc-think-body", children: text }) : null
10146
+ open ? /* @__PURE__ */ jsx80("div", { className: "fdc-think-body", children: text }) : null
9955
10147
  ] });
9956
10148
  }
9957
10149
  function Citations({ items = [], onOpen }) {
9958
- const [open, setOpen] = React51.useState(false);
10150
+ const [open, setOpen] = React52.useState(false);
9959
10151
  if (!items.length) return null;
9960
- return /* @__PURE__ */ jsxs73("div", { className: "fdc-cites", children: [
9961
- /* @__PURE__ */ jsxs73("button", { type: "button", className: "fdc-cites-head", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
9962
- /* @__PURE__ */ jsx79("i", { className: "ph ph-quotes", "aria-hidden": "true" }),
9963
- /* @__PURE__ */ jsxs73("span", { children: [
10152
+ return /* @__PURE__ */ jsxs74("div", { className: "fdc-cites", children: [
10153
+ /* @__PURE__ */ jsxs74("button", { type: "button", className: "fdc-cites-head", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
10154
+ /* @__PURE__ */ jsx80("i", { className: "ph ph-quotes", "aria-hidden": "true" }),
10155
+ /* @__PURE__ */ jsxs74("span", { children: [
9964
10156
  items.length,
9965
10157
  " source",
9966
10158
  items.length === 1 ? "" : "s"
9967
10159
  ] }),
9968
- /* @__PURE__ */ jsx79("i", { className: "ph ph-caret-" + (open ? "up" : "down"), "aria-hidden": "true" })
10160
+ /* @__PURE__ */ jsx80("i", { className: "ph ph-caret-" + (open ? "up" : "down"), "aria-hidden": "true" })
9969
10161
  ] }),
9970
- open ? /* @__PURE__ */ jsx79("ol", { className: "fdc-cites-list", children: items.map((c, i) => /* @__PURE__ */ jsxs73("li", { children: [
9971
- /* @__PURE__ */ jsx79("span", { className: "fdc-cite-n fd-tabular", children: c.marker || i + 1 }),
9972
- c.url ? /* @__PURE__ */ jsx79("a", { href: c.url, target: "_blank", rel: "noopener noreferrer", onClick: onOpen ? (e) => onOpen(c, e) : void 0, children: c.title || c.url }) : /* @__PURE__ */ jsx79("span", { children: c.title || "Source" }),
9973
- c.detail ? /* @__PURE__ */ jsx79("span", { className: "fdc-cite-detail", children: c.detail }) : null
10162
+ open ? /* @__PURE__ */ jsx80("ol", { className: "fdc-cites-list", children: items.map((c, i) => /* @__PURE__ */ jsxs74("li", { children: [
10163
+ /* @__PURE__ */ jsx80("span", { className: "fdc-cite-n fd-tabular", children: c.marker || i + 1 }),
10164
+ c.url ? /* @__PURE__ */ jsx80("a", { href: c.url, target: "_blank", rel: "noopener noreferrer", onClick: onOpen ? (e) => onOpen(c, e) : void 0, children: c.title || c.url }) : /* @__PURE__ */ jsx80("span", { children: c.title || "Source" }),
10165
+ c.detail ? /* @__PURE__ */ jsx80("span", { className: "fdc-cite-detail", children: c.detail }) : null
9974
10166
  ] }, c.id || i)) }) : null
9975
10167
  ] });
9976
10168
  }
@@ -9981,29 +10173,29 @@ function clampText(text, max) {
9981
10173
  return (at > max * 0.6 ? cut.slice(0, at) : cut).trimEnd() + "\u2026";
9982
10174
  }
9983
10175
  function MessageBody({ message: m, ctx }) {
9984
- const [expanded, setExpanded] = React51.useState(false);
10176
+ const [expanded, setExpanded] = React52.useState(false);
9985
10177
  const isUser = m.role === "user";
9986
10178
  const raw = m.text || "";
9987
10179
  const clamped = !expanded && !m.streaming ? clampText(raw, ctx.maxVisibleChars) : null;
9988
10180
  const body = clamped != null ? clamped : raw;
9989
10181
  const showMd = ctx.markdown && !isUser;
9990
- return /* @__PURE__ */ jsxs73("div", { className: "fdc-body", children: [
9991
- m.thinking && ctx.showThinking ? /* @__PURE__ */ jsx79(ThinkingBlock, { text: m.thinking, durationMs: m.thinkingMs, streaming: m.streaming && !m.text }) : null,
9992
- m.steps && m.steps.length && ctx.showSteps ? /* @__PURE__ */ jsx79(StepList, { steps: m.steps, defaultOpen: m.steps.some((s) => s.status === "running"), dense: true }) : null,
9993
- body ? /* @__PURE__ */ jsxs73("div", { className: "fdc-text" + (isUser ? " is-user" : ""), children: [
9994
- showMd ? /* @__PURE__ */ jsx79(Markdown, { source: body, headingOffset: 2, codeProps: { collapseAfter: 22 }, renderCitation: ctx.renderCitation }) : /* @__PURE__ */ jsx79("div", { className: "fdc-plain", children: body }),
9995
- m.streaming ? /* @__PURE__ */ jsx79("span", { className: "fdc-caret", "aria-hidden": "true" }) : null
10182
+ return /* @__PURE__ */ jsxs74("div", { className: "fdc-body", children: [
10183
+ m.thinking && ctx.showThinking ? /* @__PURE__ */ jsx80(ThinkingBlock, { text: m.thinking, durationMs: m.thinkingMs, streaming: m.streaming && !m.text }) : null,
10184
+ m.steps && m.steps.length && ctx.showSteps ? /* @__PURE__ */ jsx80(StepList, { steps: m.steps, defaultOpen: m.steps.some((s) => s.status === "running"), dense: true }) : null,
10185
+ body ? /* @__PURE__ */ jsxs74("div", { className: "fdc-text" + (isUser ? " is-user" : ""), children: [
10186
+ showMd ? /* @__PURE__ */ jsx80(Markdown, { source: body, headingOffset: 2, codeProps: { collapseAfter: 22 }, renderCitation: ctx.renderCitation }) : /* @__PURE__ */ jsx80("div", { className: "fdc-plain", children: body }),
10187
+ m.streaming ? /* @__PURE__ */ jsx80("span", { className: "fdc-caret", "aria-hidden": "true" }) : null
9996
10188
  ] }) : null,
9997
- clamped != null ? /* @__PURE__ */ jsxs73("button", { type: "button", className: "fdc-more", onClick: () => setExpanded(true), children: [
9998
- /* @__PURE__ */ jsx79("i", { className: "ph ph-caret-down", "aria-hidden": "true" }),
10189
+ clamped != null ? /* @__PURE__ */ jsxs74("button", { type: "button", className: "fdc-more", onClick: () => setExpanded(true), children: [
10190
+ /* @__PURE__ */ jsx80("i", { className: "ph ph-caret-down", "aria-hidden": "true" }),
9999
10191
  "Show more",
10000
- /* @__PURE__ */ jsx79("span", { className: "fdc-more-len fd-tabular", children: raw.length < 2e3 ? raw.length.toLocaleString() + " characters" : Math.round(raw.length / 100) / 10 + "k characters" })
10001
- ] }) : expanded && ctx.maxVisibleChars && raw.length > ctx.maxVisibleChars ? /* @__PURE__ */ jsxs73("button", { type: "button", className: "fdc-more", onClick: () => setExpanded(false), children: [
10002
- /* @__PURE__ */ jsx79("i", { className: "ph ph-caret-up", "aria-hidden": "true" }),
10192
+ /* @__PURE__ */ jsx80("span", { className: "fdc-more-len fd-tabular", children: raw.length < 2e3 ? raw.length.toLocaleString() + " characters" : Math.round(raw.length / 100) / 10 + "k characters" })
10193
+ ] }) : expanded && ctx.maxVisibleChars && raw.length > ctx.maxVisibleChars ? /* @__PURE__ */ jsxs74("button", { type: "button", className: "fdc-more", onClick: () => setExpanded(false), children: [
10194
+ /* @__PURE__ */ jsx80("i", { className: "ph ph-caret-up", "aria-hidden": "true" }),
10003
10195
  "Show less"
10004
10196
  ] }) : null,
10005
- m.attachments && m.attachments.length ? /* @__PURE__ */ jsx79(FileGrid, { files: m.attachments, onOpen: ctx.onOpenAttachment, tiles: true, maxHeight: ctx.attachmentHeight || 220, compact: ctx.narrow }) : null,
10006
- m.packet ? /* @__PURE__ */ jsx79(
10197
+ m.attachments && m.attachments.length ? /* @__PURE__ */ jsx80(FileGrid, { files: m.attachments, onOpen: ctx.onOpenAttachment, tiles: true, maxHeight: ctx.attachmentHeight || 220, compact: ctx.narrow }) : null,
10198
+ m.packet ? /* @__PURE__ */ jsx80(
10007
10199
  PacketCard,
10008
10200
  {
10009
10201
  packet: m.packet,
@@ -10013,44 +10205,44 @@ function MessageBody({ message: m, ctx }) {
10013
10205
  applied: ctx.appliedPackets && ctx.appliedPackets[m.id]
10014
10206
  }
10015
10207
  ) : null,
10016
- m.citations && m.citations.length ? /* @__PURE__ */ jsx79(Citations, { items: m.citations, onOpen: ctx.onOpenCitation }) : null,
10017
- m.working ? /* @__PURE__ */ jsxs73("div", { className: "fdc-working", role: "status", children: [
10018
- /* @__PURE__ */ jsxs73("span", { className: "fdc-dots", "aria-hidden": "true", children: [
10019
- /* @__PURE__ */ jsx79("span", {}),
10020
- /* @__PURE__ */ jsx79("span", {}),
10021
- /* @__PURE__ */ jsx79("span", {})
10208
+ m.citations && m.citations.length ? /* @__PURE__ */ jsx80(Citations, { items: m.citations, onOpen: ctx.onOpenCitation }) : null,
10209
+ m.working ? /* @__PURE__ */ jsxs74("div", { className: "fdc-working", role: "status", children: [
10210
+ /* @__PURE__ */ jsxs74("span", { className: "fdc-dots", "aria-hidden": "true", children: [
10211
+ /* @__PURE__ */ jsx80("span", {}),
10212
+ /* @__PURE__ */ jsx80("span", {}),
10213
+ /* @__PURE__ */ jsx80("span", {})
10022
10214
  ] }),
10023
- /* @__PURE__ */ jsxs73("span", { className: "fdc-working-label", children: [
10215
+ /* @__PURE__ */ jsxs74("span", { className: "fdc-working-label", children: [
10024
10216
  m.resumed ? "Resuming" : "Working",
10025
- m.job && m.job.status ? /* @__PURE__ */ jsxs73("span", { className: "fdc-working-job", children: [
10217
+ m.job && m.job.status ? /* @__PURE__ */ jsxs74("span", { className: "fdc-working-job", children: [
10026
10218
  " \xB7 ",
10027
10219
  m.job.status
10028
10220
  ] }) : null,
10029
- m.job && m.job.detail ? /* @__PURE__ */ jsxs73("span", { className: "fdc-working-job", children: [
10221
+ m.job && m.job.detail ? /* @__PURE__ */ jsxs74("span", { className: "fdc-working-job", children: [
10030
10222
  " \xB7 ",
10031
10223
  m.job.detail
10032
10224
  ] }) : null
10033
10225
  ] }),
10034
- m.jobId ? /* @__PURE__ */ jsx79("span", { className: "fdc-working-id fd-mono", children: String(m.jobId).slice(0, 12) }) : null
10226
+ m.jobId ? /* @__PURE__ */ jsx80("span", { className: "fdc-working-id fd-mono", children: String(m.jobId).slice(0, 12) }) : null
10035
10227
  ] }) : null,
10036
- m.stopped ? /* @__PURE__ */ jsxs73("div", { className: "fdc-stopped", children: [
10037
- /* @__PURE__ */ jsx79("i", { className: "ph ph-stop-circle", "aria-hidden": "true" }),
10228
+ m.stopped ? /* @__PURE__ */ jsxs74("div", { className: "fdc-stopped", children: [
10229
+ /* @__PURE__ */ jsx80("i", { className: "ph ph-stop-circle", "aria-hidden": "true" }),
10038
10230
  "Stopped"
10039
10231
  ] }) : null,
10040
- m.error ? /* @__PURE__ */ jsxs73("div", { className: "fdc-error", role: "alert", children: [
10041
- /* @__PURE__ */ jsx79("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
10042
- /* @__PURE__ */ jsx79("span", { className: "fdc-error-text", children: ctx.errorCopy ? ctx.errorCopy(m.error) : m.error }),
10043
- m.retryable && ctx.onRetry ? /* @__PURE__ */ jsxs73("button", { type: "button", className: "fdc-error-retry", onClick: ctx.onRetry, children: [
10044
- /* @__PURE__ */ jsx79("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }),
10232
+ m.error ? /* @__PURE__ */ jsxs74("div", { className: "fdc-error", role: "alert", children: [
10233
+ /* @__PURE__ */ jsx80("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
10234
+ /* @__PURE__ */ jsx80("span", { className: "fdc-error-text", children: ctx.errorCopy ? ctx.errorCopy(m.error) : m.error }),
10235
+ m.retryable && ctx.onRetry ? /* @__PURE__ */ jsxs74("button", { type: "button", className: "fdc-error-retry", onClick: ctx.onRetry, children: [
10236
+ /* @__PURE__ */ jsx80("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }),
10045
10237
  "Retry"
10046
10238
  ] }) : null
10047
10239
  ] }) : null
10048
10240
  ] });
10049
10241
  }
10050
10242
  function useCopyRun() {
10051
- const [done, setDone] = React51.useState(false);
10052
- const t = React51.useRef(null);
10053
- React51.useEffect(() => () => {
10243
+ const [done, setDone] = React52.useState(false);
10244
+ const t = React52.useRef(null);
10245
+ React52.useEffect(() => () => {
10054
10246
  if (t.current) clearTimeout(t.current);
10055
10247
  }, []);
10056
10248
  return [done, (text) => {
@@ -10070,16 +10262,16 @@ function RunActions({ group, ctx }) {
10070
10262
  const isAssistant = group.role === "assistant";
10071
10263
  const fb = last.feedback;
10072
10264
  if (!ctx.messageActions) return null;
10073
- return /* @__PURE__ */ jsxs73("div", { className: "fdc-actions", role: "group", "aria-label": "Message actions", children: [
10074
- /* @__PURE__ */ jsxs73("button", { type: "button", className: "fdc-act" + (copied ? " is-done" : ""), onClick: () => copy(markdownToText(text)), "aria-label": "Copy message", children: [
10075
- /* @__PURE__ */ jsx79("i", { className: "ph ph-" + (copied ? "check" : "copy"), "aria-hidden": "true" }),
10076
- /* @__PURE__ */ jsx79("span", { className: "fdc-act-label", children: copied ? "Copied" : "Copy" })
10265
+ return /* @__PURE__ */ jsxs74("div", { className: "fdc-actions", role: "group", "aria-label": "Message actions", children: [
10266
+ /* @__PURE__ */ jsxs74("button", { type: "button", className: "fdc-act" + (copied ? " is-done" : ""), onClick: () => copy(markdownToText(text)), "aria-label": "Copy message", children: [
10267
+ /* @__PURE__ */ jsx80("i", { className: "ph ph-" + (copied ? "check" : "copy"), "aria-hidden": "true" }),
10268
+ /* @__PURE__ */ jsx80("span", { className: "fdc-act-label", children: copied ? "Copied" : "Copy" })
10077
10269
  ] }),
10078
- isAssistant && ctx.onRetry ? /* @__PURE__ */ jsx79("button", { type: "button", className: "fdc-act", onClick: ctx.onRetry, "aria-label": "Retry this turn", children: /* @__PURE__ */ jsx79("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }) }) : null,
10079
- group.role === "user" && ctx.onEdit ? /* @__PURE__ */ jsx79("button", { type: "button", className: "fdc-act", onClick: () => ctx.onEdit(last), "aria-label": "Edit and resend", children: /* @__PURE__ */ jsx79("i", { className: "ph ph-pencil-simple", "aria-hidden": "true" }) }) : null,
10080
- isAssistant && ctx.onFeedback ? /* @__PURE__ */ jsxs73(React51.Fragment, { children: [
10081
- /* @__PURE__ */ jsx79("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__ */ jsx79("i", { className: "ph ph-thumbs-up", "aria-hidden": "true" }) }),
10082
- /* @__PURE__ */ jsx79("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__ */ jsx79("i", { className: "ph ph-thumbs-down", "aria-hidden": "true" }) })
10270
+ isAssistant && ctx.onRetry ? /* @__PURE__ */ jsx80("button", { type: "button", className: "fdc-act", onClick: ctx.onRetry, "aria-label": "Retry this turn", children: /* @__PURE__ */ jsx80("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }) }) : null,
10271
+ group.role === "user" && ctx.onEdit ? /* @__PURE__ */ jsx80("button", { type: "button", className: "fdc-act", onClick: () => ctx.onEdit(last), "aria-label": "Edit and resend", children: /* @__PURE__ */ jsx80("i", { className: "ph ph-pencil-simple", "aria-hidden": "true" }) }) : null,
10272
+ isAssistant && ctx.onFeedback ? /* @__PURE__ */ jsxs74(React52.Fragment, { children: [
10273
+ /* @__PURE__ */ jsx80("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__ */ jsx80("i", { className: "ph ph-thumbs-up", "aria-hidden": "true" }) }),
10274
+ /* @__PURE__ */ jsx80("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__ */ jsx80("i", { className: "ph ph-thumbs-down", "aria-hidden": "true" }) })
10083
10275
  ] }) : null,
10084
10276
  ctx.extraActions ? ctx.extraActions(group) : null
10085
10277
  ] });
@@ -10089,22 +10281,22 @@ function ChatTurn({ group, ctx }) {
10089
10281
  const name = isUser ? ctx.userName : group.author || ctx.assistantName;
10090
10282
  const avatar = isUser ? ctx.userAvatar : ctx.assistantAvatar;
10091
10283
  const stamp = group.messages[0].timestamp;
10092
- return /* @__PURE__ */ jsxs73("article", { className: "fdc-turn is-" + group.role, "aria-label": String(name) + (stamp ? " at " + formatClock(stamp) : ""), children: [
10093
- /* @__PURE__ */ jsxs73("div", { className: "fdc-turn-head", children: [
10094
- ctx.showAvatars ? /* @__PURE__ */ jsx79("span", { className: "fdc-avatar is-" + group.role, "aria-hidden": "true", children: avatar ? /* @__PURE__ */ jsx79("img", { src: avatar, alt: "" }) : isUser ? /* @__PURE__ */ jsx79("span", { className: "fdc-avatar-txt", children: (name || "You").slice(0, 1).toUpperCase() }) : /* @__PURE__ */ jsx79("i", { className: "ph ph-" + (ctx.assistantIcon || "sparkle") }) }) : null,
10095
- /* @__PURE__ */ jsx79("span", { className: "fdc-who", children: name }),
10096
- stamp ? /* @__PURE__ */ jsx79(RelativeTime, { className: "fdc-when", value: stamp }) : null,
10097
- group.messages.some((m) => m.model) ? /* @__PURE__ */ jsx79("span", { className: "fdc-turn-model", children: group.messages.find((m) => m.model).model }) : null
10284
+ return /* @__PURE__ */ jsxs74("article", { className: "fdc-turn is-" + group.role, "aria-label": String(name) + (stamp ? " at " + formatClock(stamp) : ""), children: [
10285
+ /* @__PURE__ */ jsxs74("div", { className: "fdc-turn-head", children: [
10286
+ ctx.showAvatars ? /* @__PURE__ */ jsx80("span", { className: "fdc-avatar is-" + group.role, "aria-hidden": "true", children: avatar ? /* @__PURE__ */ jsx80("img", { src: avatar, alt: "" }) : isUser ? /* @__PURE__ */ jsx80("span", { className: "fdc-avatar-txt", children: (name || "You").slice(0, 1).toUpperCase() }) : /* @__PURE__ */ jsx80("i", { className: "ph ph-" + (ctx.assistantIcon || "sparkle") }) }) : null,
10287
+ /* @__PURE__ */ jsx80("span", { className: "fdc-who", children: name }),
10288
+ stamp ? /* @__PURE__ */ jsx80(RelativeTime, { className: "fdc-when", value: stamp }) : null,
10289
+ group.messages.some((m) => m.model) ? /* @__PURE__ */ jsx80("span", { className: "fdc-turn-model", children: group.messages.find((m) => m.model).model }) : null
10098
10290
  ] }),
10099
- /* @__PURE__ */ jsxs73("div", { className: "fdc-turn-body", children: [
10100
- group.messages.map((m) => /* @__PURE__ */ jsx79("div", { className: "fdc-msg" + (m.pending ? " is-pending" : ""), children: /* @__PURE__ */ jsx79(MessageBody, { message: m, ctx }) }, m.id)),
10101
- /* @__PURE__ */ jsx79(RunActions, { group, ctx })
10291
+ /* @__PURE__ */ jsxs74("div", { className: "fdc-turn-body", children: [
10292
+ group.messages.map((m) => /* @__PURE__ */ jsx80("div", { className: "fdc-msg" + (m.pending ? " is-pending" : ""), children: /* @__PURE__ */ jsx80(MessageBody, { message: m, ctx }) }, m.id)),
10293
+ /* @__PURE__ */ jsx80(RunActions, { group, ctx })
10102
10294
  ] })
10103
10295
  ] });
10104
10296
  }
10105
10297
 
10106
10298
  // src/components/chat/ChatTranscript.tsx
10107
- import { jsx as jsx80, jsxs as jsxs74 } from "react/jsx-runtime";
10299
+ import { jsx as jsx81, jsxs as jsxs75 } from "react/jsx-runtime";
10108
10300
  var GROUP_WINDOW = 6e4;
10109
10301
  var STICK_PX = 100;
10110
10302
  function groupMessages(list) {
@@ -10137,25 +10329,25 @@ function dayLabel(key) {
10137
10329
  }
10138
10330
  function Suggestions({ items = [], onPick }) {
10139
10331
  if (!items.length) return null;
10140
- return /* @__PURE__ */ jsx80("div", { className: "fdc-suggest", children: items.map((s, i) => {
10332
+ return /* @__PURE__ */ jsx81("div", { className: "fdc-suggest", children: items.map((s, i) => {
10141
10333
  const it = typeof s === "string" ? { label: s, text: s } : s;
10142
- return /* @__PURE__ */ jsxs74("button", { type: "button", className: "fdc-suggest-item", onClick: () => onPick && onPick(it.text || it.label), children: [
10143
- it.icon ? /* @__PURE__ */ jsx80("i", { className: "ph ph-" + it.icon, "aria-hidden": "true" }) : null,
10144
- /* @__PURE__ */ jsxs74("span", { className: "fdc-suggest-text", children: [
10145
- /* @__PURE__ */ jsx80("span", { className: "fdc-suggest-label", children: it.label }),
10146
- it.description ? /* @__PURE__ */ jsx80("span", { className: "fdc-suggest-desc", children: it.description }) : null
10334
+ return /* @__PURE__ */ jsxs75("button", { type: "button", className: "fdc-suggest-item", onClick: () => onPick && onPick(it.text || it.label), children: [
10335
+ it.icon ? /* @__PURE__ */ jsx81("i", { className: "ph ph-" + it.icon, "aria-hidden": "true" }) : null,
10336
+ /* @__PURE__ */ jsxs75("span", { className: "fdc-suggest-text", children: [
10337
+ /* @__PURE__ */ jsx81("span", { className: "fdc-suggest-label", children: it.label }),
10338
+ it.description ? /* @__PURE__ */ jsx81("span", { className: "fdc-suggest-desc", children: it.description }) : null
10147
10339
  ] }),
10148
- /* @__PURE__ */ jsx80("i", { className: "ph ph-arrow-up-right fdc-suggest-go", "aria-hidden": "true" })
10340
+ /* @__PURE__ */ jsx81("i", { className: "ph ph-arrow-up-right fdc-suggest-go", "aria-hidden": "true" })
10149
10341
  ] }, it.id || i);
10150
10342
  }) });
10151
10343
  }
10152
10344
  function LoadingTurns() {
10153
- return /* @__PURE__ */ jsx80("div", { className: "fdc-skel", "aria-hidden": "true", children: [0, 1].map((i) => /* @__PURE__ */ jsxs74("div", { className: "fdc-skel-turn", children: [
10154
- /* @__PURE__ */ jsx80("div", { className: "fd-skel fd-skel-circle", style: { width: 22, height: 22 } }),
10155
- /* @__PURE__ */ jsxs74("div", { className: "fdc-skel-lines", children: [
10156
- /* @__PURE__ */ jsx80("div", { className: "fd-skel", style: { width: i ? "62%" : "44%", height: 11 } }),
10157
- /* @__PURE__ */ jsx80("div", { className: "fd-skel", style: { width: i ? "94%" : "78%", height: 11 } }),
10158
- /* @__PURE__ */ jsx80("div", { className: "fd-skel", style: { width: i ? "71%" : "56%", height: 11 } })
10345
+ return /* @__PURE__ */ jsx81("div", { className: "fdc-skel", "aria-hidden": "true", children: [0, 1].map((i) => /* @__PURE__ */ jsxs75("div", { className: "fdc-skel-turn", children: [
10346
+ /* @__PURE__ */ jsx81("div", { className: "fd-skel fd-skel-circle", style: { width: 22, height: 22 } }),
10347
+ /* @__PURE__ */ jsxs75("div", { className: "fdc-skel-lines", children: [
10348
+ /* @__PURE__ */ jsx81("div", { className: "fd-skel", style: { width: i ? "62%" : "44%", height: 11 } }),
10349
+ /* @__PURE__ */ jsx81("div", { className: "fd-skel", style: { width: i ? "94%" : "78%", height: 11 } }),
10350
+ /* @__PURE__ */ jsx81("div", { className: "fd-skel", style: { width: i ? "71%" : "56%", height: 11 } })
10159
10351
  ] })
10160
10352
  ] }, i)) });
10161
10353
  }
@@ -10172,10 +10364,10 @@ function ChatTranscript({
10172
10364
  renderEmpty,
10173
10365
  className = ""
10174
10366
  }) {
10175
- const scroller = React52.useRef(null);
10176
- const stick = React52.useRef(true);
10177
- const [pill, setPill] = React52.useState(0);
10178
- const seen = React52.useRef(0);
10367
+ const scroller = React53.useRef(null);
10368
+ const stick = React53.useRef(true);
10369
+ const [pill, setPill] = React53.useState(0);
10370
+ const seen = React53.useRef(0);
10179
10371
  const toBottom = (smooth) => {
10180
10372
  const el = scroller.current;
10181
10373
  if (!el) return;
@@ -10194,7 +10386,7 @@ function ChatTranscript({
10194
10386
  seen.current = messages.length;
10195
10387
  }
10196
10388
  };
10197
- React52.useLayoutEffect(() => {
10389
+ React53.useLayoutEffect(() => {
10198
10390
  const el = scroller.current;
10199
10391
  if (!el) return;
10200
10392
  if (stick.current) {
@@ -10202,7 +10394,7 @@ function ChatTranscript({
10202
10394
  seen.current = messages.length;
10203
10395
  } else setPill(Math.max(0, messages.length - seen.current));
10204
10396
  }, [messages]);
10205
- React52.useEffect(() => {
10397
+ React53.useEffect(() => {
10206
10398
  const el = scroller.current;
10207
10399
  const inner = el && el.firstChild;
10208
10400
  if (!el || !inner || typeof ResizeObserver === "undefined") return;
@@ -10212,38 +10404,38 @@ function ChatTranscript({
10212
10404
  ro.observe(inner);
10213
10405
  return () => ro.disconnect();
10214
10406
  }, []);
10215
- const groups = React52.useMemo(() => groupMessages(messages), [messages]);
10407
+ const groups = React53.useMemo(() => groupMessages(messages), [messages]);
10216
10408
  const empty = !messages.length && status === "ready";
10217
- return /* @__PURE__ */ jsxs74("div", { className: ["fdc-scroll", className].filter(Boolean).join(" "), ref: scroller, onScroll, children: [
10218
- /* @__PURE__ */ jsxs74("div", { className: "fdc-log", role: "log", "aria-label": "Conversation", children: [
10219
- status === "loading" || status === "resolving" ? /* @__PURE__ */ jsx80(LoadingTurns, {}) : null,
10220
- status === "disconnected" ? /* @__PURE__ */ jsxs74("div", { className: "fdc-dead", children: [
10221
- /* @__PURE__ */ jsx80("span", { className: "fdc-dead-icon", children: /* @__PURE__ */ jsx80("i", { className: "ph ph-plugs", "aria-hidden": "true" }) }),
10222
- /* @__PURE__ */ jsx80("h3", { className: "fdc-dead-title", children: ctx.deadTitle || "The assistant isn\u2019t reachable" }),
10223
- /* @__PURE__ */ jsx80("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." }),
10224
- ctx.onReconnect ? /* @__PURE__ */ jsxs74("button", { type: "button", className: "fd-btn fd-btn-secondary fd-btn-sm", onClick: ctx.onReconnect, children: [
10225
- /* @__PURE__ */ jsx80("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }),
10409
+ return /* @__PURE__ */ jsxs75("div", { className: ["fdc-scroll", className].filter(Boolean).join(" "), ref: scroller, onScroll, children: [
10410
+ /* @__PURE__ */ jsxs75("div", { className: "fdc-log", role: "log", "aria-label": "Conversation", children: [
10411
+ status === "loading" || status === "resolving" ? /* @__PURE__ */ jsx81(LoadingTurns, {}) : null,
10412
+ status === "disconnected" ? /* @__PURE__ */ jsxs75("div", { className: "fdc-dead", children: [
10413
+ /* @__PURE__ */ jsx81("span", { className: "fdc-dead-icon", children: /* @__PURE__ */ jsx81("i", { className: "ph ph-plugs", "aria-hidden": "true" }) }),
10414
+ /* @__PURE__ */ jsx81("h3", { className: "fdc-dead-title", children: ctx.deadTitle || "The assistant isn\u2019t reachable" }),
10415
+ /* @__PURE__ */ jsx81("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." }),
10416
+ ctx.onReconnect ? /* @__PURE__ */ jsxs75("button", { type: "button", className: "fd-btn fd-btn-secondary fd-btn-sm", onClick: ctx.onReconnect, children: [
10417
+ /* @__PURE__ */ jsx81("i", { className: "ph ph-arrow-clockwise", "aria-hidden": "true" }),
10226
10418
  "Try again"
10227
10419
  ] }) : null
10228
10420
  ] }) : null,
10229
- empty ? renderEmpty ? renderEmpty() : /* @__PURE__ */ jsxs74("div", { className: "fdc-empty", children: [
10230
- /* @__PURE__ */ jsx80("span", { className: "fdc-empty-icon", children: /* @__PURE__ */ jsx80("i", { className: "ph ph-" + emptyIcon, "aria-hidden": "true" }) }),
10231
- /* @__PURE__ */ jsx80("h3", { className: "fdc-empty-title", children: emptyTitle }),
10232
- emptyDescription ? /* @__PURE__ */ jsx80("p", { className: "fdc-empty-body", children: emptyDescription }) : null,
10233
- /* @__PURE__ */ jsx80(Suggestions, { items: suggestions, onPick })
10421
+ empty ? renderEmpty ? renderEmpty() : /* @__PURE__ */ jsxs75("div", { className: "fdc-empty", children: [
10422
+ /* @__PURE__ */ jsx81("span", { className: "fdc-empty-icon", children: /* @__PURE__ */ jsx81("i", { className: "ph ph-" + emptyIcon, "aria-hidden": "true" }) }),
10423
+ /* @__PURE__ */ jsx81("h3", { className: "fdc-empty-title", children: emptyTitle }),
10424
+ emptyDescription ? /* @__PURE__ */ jsx81("p", { className: "fdc-empty-body", children: emptyDescription }) : null,
10425
+ /* @__PURE__ */ jsx81(Suggestions, { items: suggestions, onPick })
10234
10426
  ] }) : null,
10235
10427
  groups.map((g, i) => {
10236
10428
  const prev = groups[i - 1];
10237
10429
  const k = dayKey(g.messages[0].timestamp);
10238
10430
  const showDay = !!k && (!prev || dayKey(prev.messages[0].timestamp) !== k);
10239
- return /* @__PURE__ */ jsxs74(React52.Fragment, { children: [
10240
- showDay ? /* @__PURE__ */ jsx80("div", { className: "fdc-day", children: /* @__PURE__ */ jsx80("span", { children: dayLabel(k) }) }) : null,
10241
- /* @__PURE__ */ jsx80(ChatTurn, { group: g, ctx })
10431
+ return /* @__PURE__ */ jsxs75(React53.Fragment, { children: [
10432
+ showDay ? /* @__PURE__ */ jsx81("div", { className: "fdc-day", children: /* @__PURE__ */ jsx81("span", { children: dayLabel(k) }) }) : null,
10433
+ /* @__PURE__ */ jsx81(ChatTurn, { group: g, ctx })
10242
10434
  ] }, g.key || i);
10243
10435
  })
10244
10436
  ] }),
10245
- pill ? /* @__PURE__ */ jsxs74("button", { type: "button", className: "fdc-pill", onClick: () => toBottom(true), children: [
10246
- /* @__PURE__ */ jsx80("i", { className: "ph ph-arrow-down", "aria-hidden": "true" }),
10437
+ pill ? /* @__PURE__ */ jsxs75("button", { type: "button", className: "fdc-pill", onClick: () => toBottom(true), children: [
10438
+ /* @__PURE__ */ jsx81("i", { className: "ph ph-arrow-down", "aria-hidden": "true" }),
10247
10439
  pill,
10248
10440
  " new message",
10249
10441
  pill === 1 ? "" : "s"
@@ -10253,8 +10445,8 @@ function ChatTranscript({
10253
10445
  var TranscriptKit = { groupMessages };
10254
10446
 
10255
10447
  // src/components/chat/ChatComposer.tsx
10256
- import * as React53 from "react";
10257
- import { jsx as jsx81, jsxs as jsxs75 } from "react/jsx-runtime";
10448
+ import * as React54 from "react";
10449
+ import { jsx as jsx82, jsxs as jsxs76 } from "react/jsx-runtime";
10258
10450
  function ChatComposer({
10259
10451
  onSubmit,
10260
10452
  onStop,
@@ -10281,17 +10473,17 @@ function ChatComposer({
10281
10473
  onReject,
10282
10474
  onOpenAttachment
10283
10475
  }) {
10284
- const [text, setText] = React53.useState(draft || "");
10285
- const [trigger, setTrigger] = React53.useState(null);
10286
- const [mentionItems, setMentionItems] = React53.useState([]);
10287
- const [listening, setListening] = React53.useState(false);
10288
- const [notice, setNotice] = React53.useState(null);
10289
- const editor = React53.useRef(null);
10290
- const wrap = React53.useRef(null);
10291
- const stopVoice = React53.useRef(null);
10476
+ const [text, setText] = React54.useState(draft || "");
10477
+ const [trigger, setTrigger] = React54.useState(null);
10478
+ const [mentionItems, setMentionItems] = React54.useState([]);
10479
+ const [listening, setListening] = React54.useState(false);
10480
+ const [notice, setNotice] = React54.useState(null);
10481
+ const editor = React54.useRef(null);
10482
+ const wrap = React54.useRef(null);
10483
+ const stopVoice = React54.useRef(null);
10292
10484
  const staged = useStagedFiles(fileUploadHandler, { onError: () => {
10293
10485
  } });
10294
- React53.useEffect(() => {
10486
+ React54.useEffect(() => {
10295
10487
  if (draft != null && draft !== text) setText(draft);
10296
10488
  }, [draft]);
10297
10489
  const change = (v) => {
@@ -10327,7 +10519,7 @@ function ChatComposer({
10327
10519
  e.preventDefault();
10328
10520
  staged.add(found.files);
10329
10521
  };
10330
- React53.useEffect(() => {
10522
+ React54.useEffect(() => {
10331
10523
  if (!trigger || trigger.type !== "mention" || !mentionSources) {
10332
10524
  setMentionItems([]);
10333
10525
  return;
@@ -10345,7 +10537,7 @@ function ChatComposer({
10345
10537
  const q = (trigger.query || "").toLowerCase();
10346
10538
  setMentionItems(mentionSources.filter((m) => !q || (m.label + " " + (m.description || "")).toLowerCase().includes(q)));
10347
10539
  }, [trigger, mentionSources]);
10348
- const slashItems = React53.useMemo(() => {
10540
+ const slashItems = React54.useMemo(() => {
10349
10541
  if (!trigger || trigger.type !== "slash" || !slashCommands) return [];
10350
10542
  const q = (trigger.query || "").toLowerCase();
10351
10543
  return slashCommands.filter((c) => !q || (c.id + " " + c.label + " " + (c.description || "")).toLowerCase().includes(q));
@@ -10359,7 +10551,7 @@ function ChatComposer({
10359
10551
  description: it.description,
10360
10552
  icon: it.icon,
10361
10553
  meta: mention.meta,
10362
- shortcut: slash.shortcut ? /* @__PURE__ */ jsx81(KeyHint, { keys: slash.shortcut, size: "sm" }) : void 0,
10554
+ shortcut: slash.shortcut ? /* @__PURE__ */ jsx82(KeyHint, { keys: slash.shortcut, size: "sm" }) : void 0,
10363
10555
  onSelect: () => {
10364
10556
  const insert = trigger.type === "slash" ? slash.immediate ? "/" + slash.id : "/" + slash.id + " " : "@" + (mention.value || mention.label) + " ";
10365
10557
  editor.current && editor.current.replaceRange(trigger.from, trigger.to, insert);
@@ -10422,14 +10614,14 @@ function ChatComposer({
10422
10614
  stopVoice.current = typeof res === "function" ? res : () => {
10423
10615
  };
10424
10616
  };
10425
- return /* @__PURE__ */ jsxs75("div", { className: "fdc-composer" + (disabled ? " is-disabled" : "") + (narrow ? " is-narrow" : ""), children: [
10426
- queue.length ? /* @__PURE__ */ jsx81("div", { className: "fdc-queue", "aria-label": "Queued messages", children: queue.map((q) => /* @__PURE__ */ jsxs75("div", { className: "fdc-queue-row", children: [
10427
- /* @__PURE__ */ jsx81("i", { className: "ph ph-clock-countdown", "aria-hidden": "true" }),
10428
- /* @__PURE__ */ jsx81("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)" : "") }),
10429
- onRemoveQueued ? /* @__PURE__ */ jsx81("button", { type: "button", className: "fdc-queue-x", onClick: () => onRemoveQueued(q.id), "aria-label": "Remove queued message", children: /* @__PURE__ */ jsx81("i", { className: "ph ph-x", "aria-hidden": "true" }) }) : null
10617
+ return /* @__PURE__ */ jsxs76("div", { className: "fdc-composer" + (disabled ? " is-disabled" : "") + (narrow ? " is-narrow" : ""), children: [
10618
+ queue.length ? /* @__PURE__ */ jsx82("div", { className: "fdc-queue", "aria-label": "Queued messages", children: queue.map((q) => /* @__PURE__ */ jsxs76("div", { className: "fdc-queue-row", children: [
10619
+ /* @__PURE__ */ jsx82("i", { className: "ph ph-clock-countdown", "aria-hidden": "true" }),
10620
+ /* @__PURE__ */ jsx82("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)" : "") }),
10621
+ onRemoveQueued ? /* @__PURE__ */ jsx82("button", { type: "button", className: "fdc-queue-x", onClick: () => onRemoveQueued(q.id), "aria-label": "Remove queued message", children: /* @__PURE__ */ jsx82("i", { className: "ph ph-x", "aria-hidden": "true" }) }) : null
10430
10622
  ] }, q.id)) }) : null,
10431
10623
  sessionBar,
10432
- /* @__PURE__ */ jsx81(
10624
+ /* @__PURE__ */ jsx82(
10433
10625
  Dropzone,
10434
10626
  {
10435
10627
  className: "fdc-field",
@@ -10443,9 +10635,9 @@ function ChatComposer({
10443
10635
  disabled: !fileUploadHandler || disabled,
10444
10636
  label: "Drop to attach",
10445
10637
  hint: acceptFiles ? acceptFiles.replace(/,/g, " \xB7 ") : void 0,
10446
- children: /* @__PURE__ */ jsxs75("div", { ref: wrap, className: "fdc-field-inner", children: [
10447
- staged.items.length ? /* @__PURE__ */ jsx81("div", { className: "fdc-staged", children: /* @__PURE__ */ jsx81(FileStrip, { files: staged.items, size: narrow ? 60 : 68, onRemove: staged.remove, onRetry: staged.retry, onOpen: onOpenAttachment }) }) : null,
10448
- /* @__PURE__ */ jsx81(
10638
+ children: /* @__PURE__ */ jsxs76("div", { ref: wrap, className: "fdc-field-inner", children: [
10639
+ staged.items.length ? /* @__PURE__ */ jsx82("div", { className: "fdc-staged", children: /* @__PURE__ */ jsx82(FileStrip, { files: staged.items, size: narrow ? 60 : 68, onRemove: staged.remove, onRetry: staged.retry, onOpen: onOpenAttachment }) }) : null,
10640
+ /* @__PURE__ */ jsx82(
10449
10641
  MarkdownEditor,
10450
10642
  {
10451
10643
  ref: editor,
@@ -10464,33 +10656,33 @@ function ChatComposer({
10464
10656
  ariaLabel: "Message"
10465
10657
  }
10466
10658
  ),
10467
- /* @__PURE__ */ jsxs75("div", { className: "fdc-tools", children: [
10468
- fileUploadHandler ? /* @__PURE__ */ jsx81(FilePickButton, { onFiles: staged.add, onReject: (r) => flash(r[0].message), accept: acceptFiles, maxFileSize, label: "Attach files", icon: "plus" }) : null,
10469
- voiceHandler ? /* @__PURE__ */ jsx81("button", { type: "button", className: "fd-attachbtn" + (listening ? " is-live" : ""), onClick: voice, "aria-pressed": listening, "aria-label": listening ? "Stop dictation" : "Dictate", children: /* @__PURE__ */ jsx81("i", { className: "ph ph-" + (listening ? "waveform" : "microphone"), "aria-hidden": "true" }) }) : null,
10659
+ /* @__PURE__ */ jsxs76("div", { className: "fdc-tools", children: [
10660
+ fileUploadHandler ? /* @__PURE__ */ jsx82(FilePickButton, { onFiles: staged.add, onReject: (r) => flash(r[0].message), accept: acceptFiles, maxFileSize, label: "Attach files", icon: "plus" }) : null,
10661
+ voiceHandler ? /* @__PURE__ */ jsx82("button", { type: "button", className: "fd-attachbtn" + (listening ? " is-live" : ""), onClick: voice, "aria-pressed": listening, "aria-label": listening ? "Stop dictation" : "Dictate", children: /* @__PURE__ */ jsx82("i", { className: "ph ph-" + (listening ? "waveform" : "microphone"), "aria-hidden": "true" }) }) : null,
10470
10662
  toolbarExtras,
10471
- /* @__PURE__ */ jsx81("span", { className: "fdc-tools-gap" }),
10472
- maxLength && text.length > maxLength * 0.6 ? /* @__PURE__ */ jsxs75("span", { className: "fdc-count fd-tabular" + (text.length > maxLength * 0.95 ? " is-hot" : ""), children: [
10663
+ /* @__PURE__ */ jsx82("span", { className: "fdc-tools-gap" }),
10664
+ maxLength && text.length > maxLength * 0.6 ? /* @__PURE__ */ jsxs76("span", { className: "fdc-count fd-tabular" + (text.length > maxLength * 0.95 ? " is-hot" : ""), children: [
10473
10665
  text.length,
10474
10666
  "/",
10475
10667
  maxLength
10476
10668
  ] }) : null,
10477
- busy ? /* @__PURE__ */ jsxs75("button", { type: "button", className: "fdc-stop", onClick: onStop, "aria-label": "Stop generating", children: [
10478
- /* @__PURE__ */ jsx81("i", { className: "ph ph-stop-circle", "aria-hidden": "true" }),
10479
- /* @__PURE__ */ jsx81("span", { children: "Stop" })
10480
- ] }) : /* @__PURE__ */ jsxs75("button", { type: "button", className: "fdc-send", onClick: submit, disabled: !canSend, "aria-label": "Send message", children: [
10481
- /* @__PURE__ */ jsx81("i", { className: "ph ph-paper-plane-right", "aria-hidden": "true" }),
10482
- /* @__PURE__ */ jsx81("span", { className: "fdc-send-label", children: "Send" })
10669
+ busy ? /* @__PURE__ */ jsxs76("button", { type: "button", className: "fdc-stop", onClick: onStop, "aria-label": "Stop generating", children: [
10670
+ /* @__PURE__ */ jsx82("i", { className: "ph ph-stop-circle", "aria-hidden": "true" }),
10671
+ /* @__PURE__ */ jsx82("span", { children: "Stop" })
10672
+ ] }) : /* @__PURE__ */ jsxs76("button", { type: "button", className: "fdc-send", onClick: submit, disabled: !canSend, "aria-label": "Send message", children: [
10673
+ /* @__PURE__ */ jsx82("i", { className: "ph ph-paper-plane-right", "aria-hidden": "true" }),
10674
+ /* @__PURE__ */ jsx82("span", { className: "fdc-send-label", children: "Send" })
10483
10675
  ] })
10484
10676
  ] })
10485
10677
  ] })
10486
10678
  }
10487
10679
  ),
10488
- notice ? /* @__PURE__ */ jsxs75("div", { className: "fdc-notice", role: "status", children: [
10489
- /* @__PURE__ */ jsx81("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
10680
+ notice ? /* @__PURE__ */ jsxs76("div", { className: "fdc-notice", role: "status", children: [
10681
+ /* @__PURE__ */ jsx82("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
10490
10682
  notice
10491
10683
  ] }) : null,
10492
- hint && !notice ? /* @__PURE__ */ jsx81("div", { className: "fdc-hint", children: hint }) : null,
10493
- /* @__PURE__ */ jsx81(
10684
+ hint && !notice ? /* @__PURE__ */ jsx82("div", { className: "fdc-hint", children: hint }) : null,
10685
+ /* @__PURE__ */ jsx82(
10494
10686
  Popover,
10495
10687
  {
10496
10688
  open: menuOpen,
@@ -10504,12 +10696,12 @@ function ChatComposer({
10504
10696
  returnFocus: false,
10505
10697
  closeOnOutside: true,
10506
10698
  label: trigger && trigger.type === "slash" ? "Commands" : "Mentions",
10507
- children: /* @__PURE__ */ jsx81(
10699
+ children: /* @__PURE__ */ jsx82(
10508
10700
  Menu,
10509
10701
  {
10510
10702
  items: menuItems,
10511
10703
  autoFocus: false,
10512
- header: /* @__PURE__ */ jsx81("div", { className: "fd-pop-group", children: trigger && trigger.type === "slash" ? "Commands" : "Attach context" }),
10704
+ header: /* @__PURE__ */ jsx82("div", { className: "fd-pop-group", children: trigger && trigger.type === "slash" ? "Commands" : "Attach context" }),
10513
10705
  onClose: () => setTrigger(null)
10514
10706
  }
10515
10707
  )
@@ -10519,12 +10711,12 @@ function ChatComposer({
10519
10711
  }
10520
10712
 
10521
10713
  // src/components/chat/ChatSessionBar.tsx
10522
- import * as React54 from "react";
10523
- import { jsx as jsx82, jsxs as jsxs76 } from "react/jsx-runtime";
10714
+ import * as React55 from "react";
10715
+ import { jsx as jsx83, jsxs as jsxs77 } from "react/jsx-runtime";
10524
10716
  var compact2 = meterFormats.compact;
10525
10717
  function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extras }) {
10526
- const [open, setOpen] = React54.useState(false);
10527
- const anchor = React54.useRef(null);
10718
+ const [open, setOpen] = React55.useState(false);
10719
+ const anchor = React55.useRef(null);
10528
10720
  const stats = sessionStats || null;
10529
10721
  const cu = contextUsage || null;
10530
10722
  const limits = usageLimits || null;
@@ -10539,9 +10731,9 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
10539
10731
  if (stats && stats.runningTasks) bits.push(stats.runningTasks + " running task" + (stats.runningTasks === 1 ? "" : "s"));
10540
10732
  if (cu) bits.push(pct + "% context");
10541
10733
  const expandable = !!(cu || limits);
10542
- return /* @__PURE__ */ jsxs76(React54.Fragment, { children: [
10543
- /* @__PURE__ */ jsxs76("div", { className: "fdc-bar", children: [
10544
- /* @__PURE__ */ jsxs76(
10734
+ return /* @__PURE__ */ jsxs77(React55.Fragment, { children: [
10735
+ /* @__PURE__ */ jsxs77("div", { className: "fdc-bar", children: [
10736
+ /* @__PURE__ */ jsxs77(
10545
10737
  "button",
10546
10738
  {
10547
10739
  type: "button",
@@ -10552,15 +10744,15 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
10552
10744
  "aria-expanded": expandable ? open : void 0,
10553
10745
  "aria-label": expandable ? "Usage details" : void 0,
10554
10746
  children: [
10555
- cu ? /* @__PURE__ */ jsx82("span", { className: "fdc-bar-mini", "aria-hidden": "true", children: /* @__PURE__ */ jsx82(SegmentedMeter, { total, segments: cu.segments, height: 4, showTotal: false }) }) : null,
10556
- /* @__PURE__ */ jsx82("span", { className: "fdc-bar-text", title: truncationTitle(bits.join(" \xB7 ")), children: bits.join(" \xB7 ") }),
10557
- expandable ? /* @__PURE__ */ jsx82("i", { className: "ph ph-caret-right fdc-bar-caret", "aria-hidden": "true" }) : null
10747
+ cu ? /* @__PURE__ */ jsx83("span", { className: "fdc-bar-mini", "aria-hidden": "true", children: /* @__PURE__ */ jsx83(SegmentedMeter, { total, segments: cu.segments, height: 4, showTotal: false }) }) : null,
10748
+ /* @__PURE__ */ jsx83("span", { className: "fdc-bar-text", title: truncationTitle(bits.join(" \xB7 ")), children: bits.join(" \xB7 ") }),
10749
+ expandable ? /* @__PURE__ */ jsx83("i", { className: "ph ph-caret-right fdc-bar-caret", "aria-hidden": "true" }) : null
10558
10750
  ]
10559
10751
  }
10560
10752
  ),
10561
10753
  extras
10562
10754
  ] }),
10563
- /* @__PURE__ */ jsx82(
10755
+ /* @__PURE__ */ jsx83(
10564
10756
  Popover,
10565
10757
  {
10566
10758
  open,
@@ -10571,15 +10763,15 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
10571
10763
  maxHeight: 460,
10572
10764
  padded: true,
10573
10765
  label: "Usage",
10574
- footer: onClear ? /* @__PURE__ */ jsxs76("button", { type: "button", className: "fdc-usage-clear", onClick: () => {
10766
+ footer: onClear ? /* @__PURE__ */ jsxs77("button", { type: "button", className: "fdc-usage-clear", onClick: () => {
10575
10767
  setOpen(false);
10576
10768
  onClear();
10577
10769
  }, children: [
10578
- /* @__PURE__ */ jsx82("i", { className: "ph ph-trash", "aria-hidden": "true" }),
10770
+ /* @__PURE__ */ jsx83("i", { className: "ph ph-trash", "aria-hidden": "true" }),
10579
10771
  "Clear conversation"
10580
10772
  ] }) : void 0,
10581
- children: /* @__PURE__ */ jsxs76("div", { className: "fdc-usage", children: [
10582
- cu ? /* @__PURE__ */ jsx82("section", { className: "fdc-usage-sec", children: /* @__PURE__ */ jsx82(
10773
+ children: /* @__PURE__ */ jsxs77("div", { className: "fdc-usage", children: [
10774
+ cu ? /* @__PURE__ */ jsx83("section", { className: "fdc-usage-sec", children: /* @__PURE__ */ jsx83(
10583
10775
  SegmentedMeter,
10584
10776
  {
10585
10777
  total,
@@ -10591,9 +10783,9 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
10591
10783
  remainderLabel: "Free"
10592
10784
  }
10593
10785
  ) }) : null,
10594
- limits && limits.length ? /* @__PURE__ */ jsxs76("section", { className: "fdc-usage-sec", children: [
10595
- /* @__PURE__ */ jsx82("h4", { className: "fdc-usage-h", children: "Usage limits" }),
10596
- /* @__PURE__ */ jsx82("div", { className: "fdc-usage-rows", children: limits.map((l) => /* @__PURE__ */ jsx82(
10786
+ limits && limits.length ? /* @__PURE__ */ jsxs77("section", { className: "fdc-usage-sec", children: [
10787
+ /* @__PURE__ */ jsx83("h4", { className: "fdc-usage-h", children: "Usage limits" }),
10788
+ /* @__PURE__ */ jsx83("div", { className: "fdc-usage-rows", children: limits.map((l) => /* @__PURE__ */ jsx83(
10597
10789
  QuotaRow,
10598
10790
  {
10599
10791
  label: l.label,
@@ -10603,25 +10795,25 @@ function ChatSessionBar({ sessionStats, contextUsage, usageLimits, onClear, extr
10603
10795
  l.id
10604
10796
  )) })
10605
10797
  ] }) : null,
10606
- stats ? /* @__PURE__ */ jsxs76("section", { className: "fdc-usage-sec fdc-usage-stats", children: [
10607
- stats.elapsedMs ? /* @__PURE__ */ jsxs76("div", { children: [
10608
- /* @__PURE__ */ jsx82("span", { children: "Session" }),
10609
- /* @__PURE__ */ jsx82("b", { className: "fd-tabular", children: formatDuration(stats.elapsedMs) })
10798
+ stats ? /* @__PURE__ */ jsxs77("section", { className: "fdc-usage-sec fdc-usage-stats", children: [
10799
+ stats.elapsedMs ? /* @__PURE__ */ jsxs77("div", { children: [
10800
+ /* @__PURE__ */ jsx83("span", { children: "Session" }),
10801
+ /* @__PURE__ */ jsx83("b", { className: "fd-tabular", children: formatDuration(stats.elapsedMs) })
10610
10802
  ] }) : null,
10611
- stats.tokens ? /* @__PURE__ */ jsxs76("div", { children: [
10612
- /* @__PURE__ */ jsx82("span", { children: "Tokens" }),
10613
- /* @__PURE__ */ jsx82("b", { className: "fd-tabular", children: stats.tokens.toLocaleString() })
10803
+ stats.tokens ? /* @__PURE__ */ jsxs77("div", { children: [
10804
+ /* @__PURE__ */ jsx83("span", { children: "Tokens" }),
10805
+ /* @__PURE__ */ jsx83("b", { className: "fd-tabular", children: stats.tokens.toLocaleString() })
10614
10806
  ] }) : null,
10615
- stats.costUsd != null ? /* @__PURE__ */ jsxs76("div", { children: [
10616
- /* @__PURE__ */ jsx82("span", { children: "Cost" }),
10617
- /* @__PURE__ */ jsxs76("b", { className: "fd-tabular", children: [
10807
+ stats.costUsd != null ? /* @__PURE__ */ jsxs77("div", { children: [
10808
+ /* @__PURE__ */ jsx83("span", { children: "Cost" }),
10809
+ /* @__PURE__ */ jsxs77("b", { className: "fd-tabular", children: [
10618
10810
  "$",
10619
10811
  Number(stats.costUsd).toFixed(3)
10620
10812
  ] })
10621
10813
  ] }) : null,
10622
- stats.turns ? /* @__PURE__ */ jsxs76("div", { children: [
10623
- /* @__PURE__ */ jsx82("span", { children: "Turns" }),
10624
- /* @__PURE__ */ jsx82("b", { className: "fd-tabular", children: stats.turns })
10814
+ stats.turns ? /* @__PURE__ */ jsxs77("div", { children: [
10815
+ /* @__PURE__ */ jsx83("span", { children: "Turns" }),
10816
+ /* @__PURE__ */ jsx83("b", { className: "fd-tabular", children: stats.turns })
10625
10817
  ] }) : null
10626
10818
  ] }) : null
10627
10819
  ] })
@@ -10660,7 +10852,7 @@ function ModelControls({
10660
10852
  disabled: m.disabled,
10661
10853
  checked: m.id === (current2 && current2.id),
10662
10854
  meta: m.meta,
10663
- shortcut: m.shortcut ? /* @__PURE__ */ jsx82(KeyHint, { keys: m.shortcut, size: "sm" }) : void 0,
10855
+ shortcut: m.shortcut ? /* @__PURE__ */ jsx83(KeyHint, { keys: m.shortcut, size: "sm" }) : void 0,
10664
10856
  onSelect: () => onModelChange && onModelChange(m.id)
10665
10857
  });
10666
10858
  const items = [{ kind: "section", label: "Models" }].concat(flat.map(item));
@@ -10673,15 +10865,15 @@ function ModelControls({
10673
10865
  items.push({ kind: "section", label: "Fast mode" });
10674
10866
  items.push({
10675
10867
  kind: "custom",
10676
- render: () => /* @__PURE__ */ jsxs76("label", { className: "fdc-switchrow", children: [
10677
- /* @__PURE__ */ jsx82("span", { children: fastModeLabel }),
10678
- /* @__PURE__ */ jsx82("input", { type: "checkbox", className: "fd-sr", checked: !!fastMode, onChange: (e) => onFastModeChange(e.target.checked) }),
10679
- /* @__PURE__ */ jsx82("span", { className: "fd-switch-track" + (fastMode ? " is-on" : ""), "aria-hidden": "true", children: /* @__PURE__ */ jsx82("span", { className: "fd-switch-thumb" }) })
10868
+ render: () => /* @__PURE__ */ jsxs77("label", { className: "fdc-switchrow", children: [
10869
+ /* @__PURE__ */ jsx83("span", { children: fastModeLabel }),
10870
+ /* @__PURE__ */ jsx83("input", { type: "checkbox", className: "fd-sr", checked: !!fastMode, onChange: (e) => onFastModeChange(e.target.checked) }),
10871
+ /* @__PURE__ */ jsx83("span", { className: "fd-switch-track" + (fastMode ? " is-on" : ""), "aria-hidden": "true", children: /* @__PURE__ */ jsx83("span", { className: "fd-switch-thumb" }) })
10680
10872
  ] })
10681
10873
  });
10682
10874
  }
10683
- return /* @__PURE__ */ jsxs76(React54.Fragment, { children: [
10684
- /* @__PURE__ */ jsx82(
10875
+ return /* @__PURE__ */ jsxs77(React55.Fragment, { children: [
10876
+ /* @__PURE__ */ jsx83(
10685
10877
  MenuButton,
10686
10878
  {
10687
10879
  items,
@@ -10692,7 +10884,7 @@ function ModelControls({
10692
10884
  title: "Choose a model"
10693
10885
  }
10694
10886
  ),
10695
- effortLevels && effortLevels.length ? /* @__PURE__ */ jsx82(
10887
+ effortLevels && effortLevels.length ? /* @__PURE__ */ jsx83(
10696
10888
  MenuButton,
10697
10889
  {
10698
10890
  placement: "top-end",
@@ -10713,7 +10905,7 @@ function ModelControls({
10713
10905
  }
10714
10906
 
10715
10907
  // src/components/chat/AgentChatPanel.tsx
10716
- import { jsx as jsx83, jsxs as jsxs77 } from "react/jsx-runtime";
10908
+ import { jsx as jsx84, jsxs as jsxs78 } from "react/jsx-runtime";
10717
10909
  var SURFACES = { sidebar: "is-sidebar", inline: "is-inline", page: "is-page", modal: "is-modal", sheet: "is-sheet" };
10718
10910
  function AgentChatPanel({
10719
10911
  /* required */
@@ -10797,11 +10989,11 @@ function AgentChatPanel({
10797
10989
  onFeedback,
10798
10990
  onEditMessage
10799
10991
  }) {
10800
- const [panelWidth, setPanelWidth] = React55.useState(width);
10801
- const [applied, setApplied] = React55.useState({});
10802
- const [draft, setDraft] = React55.useState("");
10803
- const dragging = React55.useRef(null);
10804
- React55.useEffect(() => setPanelWidth(width), [width]);
10992
+ const [panelWidth, setPanelWidth] = React56.useState(width);
10993
+ const [applied, setApplied] = React56.useState({});
10994
+ const [draft, setDraft] = React56.useState("");
10995
+ const dragging = React56.useRef(null);
10996
+ React56.useEffect(() => setPanelWidth(width), [width]);
10805
10997
  const engine = useChatEngine({
10806
10998
  contextType,
10807
10999
  contextId,
@@ -10867,7 +11059,7 @@ function AgentChatPanel({
10867
11059
  onReconnect: engine.reload,
10868
11060
  deadTitle: "The assistant isn\u2019t reachable"
10869
11061
  };
10870
- const sessionBar = /* @__PURE__ */ jsx83(
11062
+ const sessionBar = /* @__PURE__ */ jsx84(
10871
11063
  ChatSessionBar,
10872
11064
  {
10873
11065
  sessionStats,
@@ -10876,7 +11068,7 @@ function AgentChatPanel({
10876
11068
  onClear: engine.visible.length ? engine.clear : void 0
10877
11069
  }
10878
11070
  );
10879
- const modelControls = /* @__PURE__ */ jsx83(
11071
+ const modelControls = /* @__PURE__ */ jsx84(
10880
11072
  ModelControls,
10881
11073
  {
10882
11074
  models,
@@ -10891,7 +11083,7 @@ function AgentChatPanel({
10891
11083
  narrow
10892
11084
  }
10893
11085
  );
10894
- const threadMenu = threads && threads.length ? /* @__PURE__ */ jsx83(
11086
+ const threadMenu = threads && threads.length ? /* @__PURE__ */ jsx84(
10895
11087
  MenuButton,
10896
11088
  {
10897
11089
  variant: "ghost",
@@ -10918,7 +11110,7 @@ function AgentChatPanel({
10918
11110
  })))
10919
11111
  }
10920
11112
  ) : null;
10921
- return /* @__PURE__ */ jsxs77(
11113
+ return /* @__PURE__ */ jsxs78(
10922
11114
  "aside",
10923
11115
  {
10924
11116
  className: ["fdc-panel", SURFACES[surface] || SURFACES.sidebar, narrow ? "is-narrow" : "", className].filter(Boolean).join(" "),
@@ -10929,7 +11121,7 @@ function AgentChatPanel({
10929
11121
  },
10930
11122
  "aria-label": title,
10931
11123
  children: [
10932
- surface === "sidebar" && resizable ? /* @__PURE__ */ jsx83(
11124
+ surface === "sidebar" && resizable ? /* @__PURE__ */ jsx84(
10933
11125
  "div",
10934
11126
  {
10935
11127
  className: "fdc-grip",
@@ -10944,20 +11136,20 @@ function AgentChatPanel({
10944
11136
  }
10945
11137
  }
10946
11138
  ) : null,
10947
- showHeader ? /* @__PURE__ */ jsxs77("header", { className: "fdc-head", children: [
10948
- /* @__PURE__ */ jsx83("span", { className: "fdc-head-mark", "aria-hidden": "true", children: /* @__PURE__ */ jsx83("i", { className: "ph ph-" + assistantIcon }) }),
10949
- /* @__PURE__ */ jsxs77("span", { className: "fdc-head-titles", children: [
10950
- /* @__PURE__ */ jsx83("span", { className: "fdc-head-title", title: truncationTitle(title), children: title }),
10951
- subtitle ? /* @__PURE__ */ jsx83("span", { className: "fdc-head-sub", title: truncationTitle(subtitle), children: subtitle }) : null
11139
+ showHeader ? /* @__PURE__ */ jsxs78("header", { className: "fdc-head", children: [
11140
+ /* @__PURE__ */ jsx84("span", { className: "fdc-head-mark", "aria-hidden": "true", children: /* @__PURE__ */ jsx84("i", { className: "ph ph-" + assistantIcon }) }),
11141
+ /* @__PURE__ */ jsxs78("span", { className: "fdc-head-titles", children: [
11142
+ /* @__PURE__ */ jsx84("span", { className: "fdc-head-title", title: truncationTitle(title), children: title }),
11143
+ subtitle ? /* @__PURE__ */ jsx84("span", { className: "fdc-head-sub", title: truncationTitle(subtitle), children: subtitle }) : null
10952
11144
  ] }),
10953
- /* @__PURE__ */ jsxs77("span", { className: "fdc-head-acts", children: [
11145
+ /* @__PURE__ */ jsxs78("span", { className: "fdc-head-acts", children: [
10954
11146
  headerActions,
10955
11147
  threadMenu,
10956
- onNewThread ? /* @__PURE__ */ jsx83("button", { type: "button", className: "fdc-iconbtn", onClick: onNewThread, "aria-label": "New conversation", title: "New conversation", children: /* @__PURE__ */ jsx83("i", { className: "ph ph-plus", "aria-hidden": "true" }) }) : null,
10957
- onClose ? /* @__PURE__ */ jsx83("button", { type: "button", className: "fdc-iconbtn", onClick: onClose, "aria-label": "Close panel", title: "Close", children: /* @__PURE__ */ jsx83("i", { className: "ph ph-x", "aria-hidden": "true" }) }) : null
11148
+ onNewThread ? /* @__PURE__ */ jsx84("button", { type: "button", className: "fdc-iconbtn", onClick: onNewThread, "aria-label": "New conversation", title: "New conversation", children: /* @__PURE__ */ jsx84("i", { className: "ph ph-plus", "aria-hidden": "true" }) }) : null,
11149
+ onClose ? /* @__PURE__ */ jsx84("button", { type: "button", className: "fdc-iconbtn", onClick: onClose, "aria-label": "Close panel", title: "Close", children: /* @__PURE__ */ jsx84("i", { className: "ph ph-x", "aria-hidden": "true" }) }) : null
10958
11150
  ] })
10959
11151
  ] }) : null,
10960
- /* @__PURE__ */ jsx83(
11152
+ /* @__PURE__ */ jsx84(
10961
11153
  ChatTranscript,
10962
11154
  {
10963
11155
  messages: engine.visible,
@@ -10972,7 +11164,7 @@ function AgentChatPanel({
10972
11164
  renderEmpty
10973
11165
  }
10974
11166
  ),
10975
- /* @__PURE__ */ jsx83(
11167
+ /* @__PURE__ */ jsx84(
10976
11168
  ChatComposer,
10977
11169
  {
10978
11170
  onSubmit: (text, atts) => engine.send(text, atts),
@@ -11005,8 +11197,8 @@ function AgentChatPanel({
11005
11197
  }
11006
11198
 
11007
11199
  // src/components/files/FileViewer.tsx
11008
- import * as React56 from "react";
11009
- import { jsx as jsx84, jsxs as jsxs78 } from "react/jsx-runtime";
11200
+ import * as React57 from "react";
11201
+ import { jsx as jsx85, jsxs as jsxs79 } from "react/jsx-runtime";
11010
11202
  function previewKindOf(file) {
11011
11203
  const mime = (file.mime || "").toLowerCase();
11012
11204
  const ext = extensionOf(file.name || "");
@@ -11062,13 +11254,13 @@ function parseDelimited(text, delimiter) {
11062
11254
  return rows;
11063
11255
  }
11064
11256
  function usePreview(file, kind, resolveUrl) {
11065
- const [state, setState] = React56.useState({ status: "loading" });
11066
- const [attempt, setAttempt] = React56.useState(0);
11067
- const resolveRef = React56.useRef(resolveUrl);
11068
- React56.useEffect(() => {
11257
+ const [state, setState] = React57.useState({ status: "loading" });
11258
+ const [attempt, setAttempt] = React57.useState(0);
11259
+ const resolveRef = React57.useRef(resolveUrl);
11260
+ React57.useEffect(() => {
11069
11261
  resolveRef.current = resolveUrl;
11070
11262
  }, [resolveUrl]);
11071
- React56.useEffect(() => {
11263
+ React57.useEffect(() => {
11072
11264
  if (kind === "none") {
11073
11265
  setState({ status: "ready" });
11074
11266
  return;
@@ -11098,19 +11290,19 @@ function usePreview(file, kind, resolveUrl) {
11098
11290
  if (ac) ac.abort();
11099
11291
  };
11100
11292
  }, [file.id, kind, attempt]);
11101
- return { ...state, retry: React56.useCallback(() => setAttempt((a) => a + 1), []) };
11293
+ return { ...state, retry: React57.useCallback(() => setAttempt((a) => a + 1), []) };
11102
11294
  }
11103
11295
  function PreviewBody({ file, kind, state }) {
11104
- if (kind === "image") return /* @__PURE__ */ jsx84("img", { className: "fd-fv-image", src: state.url, alt: file.name || "Preview" });
11105
- if (kind === "pdf") return /* @__PURE__ */ jsx84("iframe", { className: "fd-fv-pdf", src: state.url, title: file.name || "PDF preview" });
11106
- if (kind === "markdown") return /* @__PURE__ */ jsx84(Markdown, { className: "fd-fv-markdown", source: state.text || "" });
11296
+ if (kind === "image") return /* @__PURE__ */ jsx85("img", { className: "fd-fv-image", src: state.url, alt: file.name || "Preview" });
11297
+ if (kind === "pdf") return /* @__PURE__ */ jsx85("iframe", { className: "fd-fv-pdf", src: state.url, title: file.name || "PDF preview" });
11298
+ if (kind === "markdown") return /* @__PURE__ */ jsx85(Markdown, { className: "fd-fv-markdown", source: state.text || "" });
11107
11299
  if (kind === "json") {
11108
11300
  let pretty = state.text || "";
11109
11301
  try {
11110
11302
  pretty = JSON.stringify(JSON.parse(pretty), null, 2);
11111
11303
  } catch {
11112
11304
  }
11113
- return /* @__PURE__ */ jsx84(CodeBlock, { code: pretty, language: "json" });
11305
+ return /* @__PURE__ */ jsx85(CodeBlock, { code: pretty, language: "json" });
11114
11306
  }
11115
11307
  if (kind === "csv") {
11116
11308
  const tsv = extensionOf(file.name || "") === "tsv" || (file.mime || "").toLowerCase().includes("tab-separated");
@@ -11118,12 +11310,12 @@ function PreviewBody({ file, kind, state }) {
11118
11310
  const head = rows[0] || [];
11119
11311
  const dataRows = rows.slice(1);
11120
11312
  const shown = dataRows.slice(0, FILE_VIEWER_CSV_ROW_LIMIT);
11121
- return /* @__PURE__ */ jsxs78("div", { className: "fd-fv-csv", children: [
11122
- /* @__PURE__ */ jsxs78("table", { className: "fd-fv-csv-table", children: [
11123
- /* @__PURE__ */ jsx84("thead", { children: /* @__PURE__ */ jsx84("tr", { children: head.map((c, i) => /* @__PURE__ */ jsx84("th", { children: c }, i)) }) }),
11124
- /* @__PURE__ */ jsx84("tbody", { children: shown.map((r, ri) => /* @__PURE__ */ jsx84("tr", { children: head.map((_, ci) => /* @__PURE__ */ jsx84("td", { children: r[ci] ?? "" }, ci)) }, ri)) })
11313
+ return /* @__PURE__ */ jsxs79("div", { className: "fd-fv-csv", children: [
11314
+ /* @__PURE__ */ jsxs79("table", { className: "fd-fv-csv-table", children: [
11315
+ /* @__PURE__ */ jsx85("thead", { children: /* @__PURE__ */ jsx85("tr", { children: head.map((c, i) => /* @__PURE__ */ jsx85("th", { children: c }, i)) }) }),
11316
+ /* @__PURE__ */ jsx85("tbody", { children: shown.map((r, ri) => /* @__PURE__ */ jsx85("tr", { children: head.map((_, ci) => /* @__PURE__ */ jsx85("td", { children: r[ci] ?? "" }, ci)) }, ri)) })
11125
11317
  ] }),
11126
- dataRows.length > FILE_VIEWER_CSV_ROW_LIMIT ? /* @__PURE__ */ jsxs78("p", { className: "fd-fv-csv-note fd-body-sm fd-muted", children: [
11318
+ dataRows.length > FILE_VIEWER_CSV_ROW_LIMIT ? /* @__PURE__ */ jsxs79("p", { className: "fd-fv-csv-note fd-body-sm fd-muted", children: [
11127
11319
  "Showing the first ",
11128
11320
  FILE_VIEWER_CSV_ROW_LIMIT.toLocaleString(),
11129
11321
  " of ",
@@ -11132,24 +11324,24 @@ function PreviewBody({ file, kind, state }) {
11132
11324
  ] }) : null
11133
11325
  ] });
11134
11326
  }
11135
- if (kind === "text") return /* @__PURE__ */ jsx84(CodeBlock, { code: state.text || "", language: extensionOf(file.name || "") || void 0 });
11136
- return /* @__PURE__ */ jsxs78("div", { className: "fd-fv-fallback", children: [
11137
- /* @__PURE__ */ jsx84("span", { className: "fd-fv-fallback-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx84("i", { className: "ph ph-" + iconForMime(file.mime, file.name) }) }),
11138
- /* @__PURE__ */ jsx84("span", { className: "fd-fv-fallback-title", children: "No preview available" }),
11139
- /* @__PURE__ */ jsxs78("span", { className: "fd-fv-fallback-meta", children: [
11327
+ if (kind === "text") return /* @__PURE__ */ jsx85(CodeBlock, { code: state.text || "", language: extensionOf(file.name || "") || void 0 });
11328
+ return /* @__PURE__ */ jsxs79("div", { className: "fd-fv-fallback", children: [
11329
+ /* @__PURE__ */ jsx85("span", { className: "fd-fv-fallback-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx85("i", { className: "ph ph-" + iconForMime(file.mime, file.name) }) }),
11330
+ /* @__PURE__ */ jsx85("span", { className: "fd-fv-fallback-title", children: "No preview available" }),
11331
+ /* @__PURE__ */ jsxs79("span", { className: "fd-fv-fallback-meta", children: [
11140
11332
  file.mime || "Unknown type",
11141
11333
  file.size ? " \xB7 " + formatBytes(file.size) : ""
11142
11334
  ] })
11143
11335
  ] });
11144
11336
  }
11145
11337
  function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", onClose, actions, className = "" }) {
11146
- const kind = React56.useMemo(() => previewKindOf(file), [file]);
11338
+ const kind = React57.useMemo(() => previewKindOf(file), [file]);
11147
11339
  const preview = usePreview(file, kind, resolveUrl);
11148
- const [tab, setTab] = React56.useState("preview");
11149
- const [downloading, setDownloading] = React56.useState(false);
11150
- const [downloadError, setDownloadError] = React56.useState(null);
11340
+ const [tab, setTab] = React57.useState("preview");
11341
+ const [downloading, setDownloading] = React57.useState(false);
11342
+ const [downloadError, setDownloadError] = React57.useState(null);
11151
11343
  const hasSide = sidePanel != null;
11152
- React56.useEffect(() => {
11344
+ React57.useEffect(() => {
11153
11345
  setTab("preview");
11154
11346
  }, [file.id]);
11155
11347
  const download = () => {
@@ -11165,29 +11357,29 @@ function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", o
11165
11357
  a.remove();
11166
11358
  }).catch((err) => setDownloadError(err && err.message || "Download failed.")).finally(() => setDownloading(false));
11167
11359
  };
11168
- return /* @__PURE__ */ jsxs78(
11360
+ return /* @__PURE__ */ jsxs79(
11169
11361
  "section",
11170
11362
  {
11171
11363
  className: ["fd-fv", hasSide && tab === "side" ? "is-tab-side" : "is-tab-preview", className].filter(Boolean).join(" "),
11172
11364
  "aria-label": file.name || "File",
11173
11365
  children: [
11174
- /* @__PURE__ */ jsxs78("header", { className: "fd-fv-head", children: [
11175
- /* @__PURE__ */ jsx84("span", { className: "fd-fv-head-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx84("i", { className: "ph ph-" + iconForMime(file.mime, file.name) }) }),
11176
- /* @__PURE__ */ jsxs78("span", { className: "fd-fv-head-titles", children: [
11177
- /* @__PURE__ */ jsx84("span", { className: "fd-fv-head-title", title: file.name, children: file.name }),
11178
- /* @__PURE__ */ jsxs78("span", { className: "fd-fv-head-meta", children: [
11366
+ /* @__PURE__ */ jsxs79("header", { className: "fd-fv-head", children: [
11367
+ /* @__PURE__ */ jsx85("span", { className: "fd-fv-head-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx85("i", { className: "ph ph-" + iconForMime(file.mime, file.name) }) }),
11368
+ /* @__PURE__ */ jsxs79("span", { className: "fd-fv-head-titles", children: [
11369
+ /* @__PURE__ */ jsx85("span", { className: "fd-fv-head-title", title: file.name, children: file.name }),
11370
+ /* @__PURE__ */ jsxs79("span", { className: "fd-fv-head-meta", children: [
11179
11371
  file.mime || "Unknown type",
11180
11372
  file.size ? " \xB7 " + formatBytes(file.size) : ""
11181
11373
  ] })
11182
11374
  ] }),
11183
- /* @__PURE__ */ jsxs78("span", { className: "fd-fv-head-actions", children: [
11375
+ /* @__PURE__ */ jsxs79("span", { className: "fd-fv-head-actions", children: [
11184
11376
  actions,
11185
- /* @__PURE__ */ jsx84(Button, { variant: "secondary", size: "sm", icon: "download-simple", loading: downloading, onClick: download, children: "Download" }),
11186
- onClose ? /* @__PURE__ */ jsx84(IconButton, { icon: "x", label: "Close", onClick: onClose }) : null
11377
+ /* @__PURE__ */ jsx85(Button, { variant: "secondary", size: "sm", icon: "download-simple", loading: downloading, onClick: download, children: "Download" }),
11378
+ onClose ? /* @__PURE__ */ jsx85(IconButton, { icon: "x", label: "Close", onClick: onClose }) : null
11187
11379
  ] })
11188
11380
  ] }),
11189
- downloadError ? /* @__PURE__ */ jsx84("div", { className: "fd-fv-download-error", role: "alert", children: downloadError }) : null,
11190
- hasSide ? /* @__PURE__ */ jsx84(
11381
+ downloadError ? /* @__PURE__ */ jsx85("div", { className: "fd-fv-download-error", role: "alert", children: downloadError }) : null,
11382
+ hasSide ? /* @__PURE__ */ jsx85(
11191
11383
  Tabs,
11192
11384
  {
11193
11385
  className: "fd-fv-tabs",
@@ -11196,19 +11388,19 @@ function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", o
11196
11388
  onChange: (v) => setTab(v)
11197
11389
  }
11198
11390
  ) : null,
11199
- /* @__PURE__ */ jsxs78("div", { className: "fd-fv-body", children: [
11200
- /* @__PURE__ */ jsx84("div", { className: "fd-fv-preview", role: "region", "aria-label": "Preview of " + (file.name || "file"), children: /* @__PURE__ */ jsx84(
11391
+ /* @__PURE__ */ jsxs79("div", { className: "fd-fv-body", children: [
11392
+ /* @__PURE__ */ jsx85("div", { className: "fd-fv-preview", role: "region", "aria-label": "Preview of " + (file.name || "file"), children: /* @__PURE__ */ jsx85(
11201
11393
  LoadingRegion,
11202
11394
  {
11203
11395
  state: preview.status === "loading" ? "loading" : preview.status === "error" ? "error" : "ready",
11204
11396
  error: preview.error,
11205
11397
  label: "Loading preview of " + (file.name || "file"),
11206
11398
  onRetry: preview.status === "error" ? preview.retry : void 0,
11207
- skeleton: /* @__PURE__ */ jsx84(Skeleton, { shape: "card", h: 220 }),
11208
- children: /* @__PURE__ */ jsx84(PreviewBody, { file, kind, state: preview })
11399
+ skeleton: /* @__PURE__ */ jsx85(Skeleton, { shape: "card", h: 220 }),
11400
+ children: /* @__PURE__ */ jsx85(PreviewBody, { file, kind, state: preview })
11209
11401
  }
11210
11402
  ) }),
11211
- hasSide ? /* @__PURE__ */ jsx84("div", { className: "fd-fv-side", role: "region", "aria-label": sidePanelLabel, children: sidePanel }) : null
11403
+ hasSide ? /* @__PURE__ */ jsx85("div", { className: "fd-fv-side", role: "region", "aria-label": sidePanelLabel, children: sidePanel }) : null
11212
11404
  ] })
11213
11405
  ]
11214
11406
  }
@@ -11216,8 +11408,8 @@ function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", o
11216
11408
  }
11217
11409
 
11218
11410
  // src/components/files/FileBrowser.tsx
11219
- import * as React57 from "react";
11220
- import { Fragment as Fragment26, jsx as jsx85, jsxs as jsxs79 } from "react/jsx-runtime";
11411
+ import * as React58 from "react";
11412
+ import { Fragment as Fragment27, jsx as jsx86, jsxs as jsxs80 } from "react/jsx-runtime";
11221
11413
  function childrenOf(folders, parentId) {
11222
11414
  return folders.filter((f) => f.parentId === parentId).sort((a, b) => a.name.localeCompare(b.name));
11223
11415
  }
@@ -11287,10 +11479,10 @@ function FolderPickerMenu({
11287
11479
  destinations,
11288
11480
  onPick
11289
11481
  }) {
11290
- const [open, setOpen] = React57.useState(false);
11482
+ const [open, setOpen] = React58.useState(false);
11291
11483
  const zIndex = useOverlayLayer(open);
11292
- const ref = React57.useRef(null);
11293
- React57.useEffect(() => {
11484
+ const ref = React58.useRef(null);
11485
+ React58.useEffect(() => {
11294
11486
  if (!open) return;
11295
11487
  const away = (e) => {
11296
11488
  if (ref.current && !ref.current.contains(e.target)) setOpen(false);
@@ -11305,8 +11497,8 @@ function FolderPickerMenu({
11305
11497
  document.removeEventListener("keydown", esc);
11306
11498
  };
11307
11499
  }, [open]);
11308
- return /* @__PURE__ */ jsxs79("span", { className: "fd-fb-menu-anchor", ref, children: [
11309
- /* @__PURE__ */ jsx85(
11500
+ return /* @__PURE__ */ jsxs80("span", { className: "fd-fb-menu-anchor", ref, children: [
11501
+ /* @__PURE__ */ jsx86(
11310
11502
  IconButton,
11311
11503
  {
11312
11504
  icon: "arrows-out-cardinal",
@@ -11318,9 +11510,9 @@ function FolderPickerMenu({
11318
11510
  onClick: () => setOpen((v) => !v)
11319
11511
  }
11320
11512
  ),
11321
- open ? /* @__PURE__ */ jsx85(LayerProvider, { zIndex, children: /* @__PURE__ */ jsxs79("div", { className: "fd-fb-menu", role: "menu", "aria-label": label, style: { zIndex }, children: [
11322
- /* @__PURE__ */ jsx85("span", { className: "fd-overline fd-muted fd-fb-menu-title", children: "Move to\u2026" }),
11323
- destinations.map((d) => /* @__PURE__ */ jsxs79(
11513
+ open ? /* @__PURE__ */ jsx86(LayerProvider, { zIndex, children: /* @__PURE__ */ jsxs80("div", { className: "fd-fb-menu", role: "menu", "aria-label": label, style: { zIndex }, children: [
11514
+ /* @__PURE__ */ jsx86("span", { className: "fd-overline fd-muted fd-fb-menu-title", children: "Move to\u2026" }),
11515
+ destinations.map((d) => /* @__PURE__ */ jsxs80(
11324
11516
  "button",
11325
11517
  {
11326
11518
  type: "button",
@@ -11332,7 +11524,7 @@ function FolderPickerMenu({
11332
11524
  setOpen(false);
11333
11525
  },
11334
11526
  children: [
11335
- /* @__PURE__ */ jsx85("i", { className: "ph ph-" + (d.id == null ? "house-simple" : "folder-simple"), "aria-hidden": "true" }),
11527
+ /* @__PURE__ */ jsx86("i", { className: "ph ph-" + (d.id == null ? "house-simple" : "folder-simple"), "aria-hidden": "true" }),
11336
11528
  d.name
11337
11529
  ]
11338
11530
  },
@@ -11342,8 +11534,8 @@ function FolderPickerMenu({
11342
11534
  ] });
11343
11535
  }
11344
11536
  function RowShell({ icon, name, meta, onOpen, draggableId, isDropTarget, onDropPayload, actions, className = "" }) {
11345
- const [over, setOver] = React57.useState(false);
11346
- const dragCounter = React57.useRef(0);
11537
+ const [over, setOver] = React58.useState(false);
11538
+ const dragCounter = React58.useRef(0);
11347
11539
  const dropHandlers = isDropTarget ? {
11348
11540
  onDragEnter: (e) => {
11349
11541
  if (!hasInternalPayload(e)) return;
@@ -11368,8 +11560,8 @@ function RowShell({ icon, name, meta, onOpen, draggableId, isDropTarget, onDropP
11368
11560
  if (payload && onDropPayload) onDropPayload(payload);
11369
11561
  }
11370
11562
  } : {};
11371
- return /* @__PURE__ */ jsxs79("div", { className: ["fd-fb-row", over ? "is-drop-target" : "", className].filter(Boolean).join(" "), ...dropHandlers, children: [
11372
- /* @__PURE__ */ jsxs79(
11563
+ return /* @__PURE__ */ jsxs80("div", { className: ["fd-fb-row", over ? "is-drop-target" : "", className].filter(Boolean).join(" "), ...dropHandlers, children: [
11564
+ /* @__PURE__ */ jsxs80(
11373
11565
  "button",
11374
11566
  {
11375
11567
  type: "button",
@@ -11378,26 +11570,26 @@ function RowShell({ icon, name, meta, onOpen, draggableId, isDropTarget, onDropP
11378
11570
  draggable: !!draggableId,
11379
11571
  onDragStart: draggableId ? (e) => writeDragPayload(e, draggableId) : void 0,
11380
11572
  children: [
11381
- /* @__PURE__ */ jsx85("span", { className: "fd-fb-row-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx85("i", { className: "ph ph-" + icon }) }),
11382
- /* @__PURE__ */ jsxs79("span", { className: "fd-fb-row-text", children: [
11383
- /* @__PURE__ */ jsx85("span", { className: "fd-fb-row-name", title: name, children: name }),
11384
- meta ? /* @__PURE__ */ jsx85("span", { className: "fd-fb-row-meta", children: meta }) : null
11573
+ /* @__PURE__ */ jsx86("span", { className: "fd-fb-row-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx86("i", { className: "ph ph-" + icon }) }),
11574
+ /* @__PURE__ */ jsxs80("span", { className: "fd-fb-row-text", children: [
11575
+ /* @__PURE__ */ jsx86("span", { className: "fd-fb-row-name", title: name, children: name }),
11576
+ meta ? /* @__PURE__ */ jsx86("span", { className: "fd-fb-row-meta", children: meta }) : null
11385
11577
  ] })
11386
11578
  ]
11387
11579
  }
11388
11580
  ),
11389
- actions ? /* @__PURE__ */ jsx85("span", { className: "fd-fb-row-actions", children: actions }) : null
11581
+ actions ? /* @__PURE__ */ jsx86("span", { className: "fd-fb-row-actions", children: actions }) : null
11390
11582
  ] });
11391
11583
  }
11392
11584
  function TreeNode({ folder, depth, folders, currentFolderId, onNavigate, onMoveInto, canMove }) {
11393
11585
  const kids = childrenOf(folders, folder.id);
11394
- const [expanded, setExpanded] = React57.useState(() => currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId));
11395
- React57.useEffect(() => {
11586
+ const [expanded, setExpanded] = React58.useState(() => currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId));
11587
+ React58.useEffect(() => {
11396
11588
  if (currentFolderId != null && isSelfOrDescendant(folders, folder.id, currentFolderId)) setExpanded(true);
11397
11589
  }, [currentFolderId, folder.id, folders]);
11398
11590
  const isCurrent = folder.id === currentFolderId;
11399
- return /* @__PURE__ */ jsxs79("div", { className: "fd-fb-tree-node", children: [
11400
- /* @__PURE__ */ jsx85(
11591
+ return /* @__PURE__ */ jsxs80("div", { className: "fd-fb-tree-node", children: [
11592
+ /* @__PURE__ */ jsx86(
11401
11593
  RowShell,
11402
11594
  {
11403
11595
  icon: folder.id === currentFolderId ? "folder-open" : "folder-simple",
@@ -11407,7 +11599,7 @@ function TreeNode({ folder, depth, folders, currentFolderId, onNavigate, onMoveI
11407
11599
  isDropTarget: canMove,
11408
11600
  onDropPayload: (payload) => onMoveInto(payload, folder.id),
11409
11601
  className: ["fd-fb-tree-row", isCurrent ? "is-current" : ""].filter(Boolean).join(" "),
11410
- actions: kids.length ? /* @__PURE__ */ jsx85(
11602
+ actions: kids.length ? /* @__PURE__ */ jsx86(
11411
11603
  IconButton,
11412
11604
  {
11413
11605
  icon: expanded ? "caret-down" : "caret-right",
@@ -11419,7 +11611,7 @@ function TreeNode({ folder, depth, folders, currentFolderId, onNavigate, onMoveI
11419
11611
  ) : void 0
11420
11612
  }
11421
11613
  ),
11422
- expanded && kids.length ? /* @__PURE__ */ jsx85("div", { className: "fd-fb-tree-children", style: { paddingLeft: 14 }, children: kids.map((k) => /* @__PURE__ */ jsx85(
11614
+ expanded && kids.length ? /* @__PURE__ */ jsx86("div", { className: "fd-fb-tree-children", style: { paddingLeft: 14 }, children: kids.map((k) => /* @__PURE__ */ jsx86(
11423
11615
  TreeNode,
11424
11616
  {
11425
11617
  folder: k,
@@ -11458,15 +11650,15 @@ function FileBrowser({
11458
11650
  const canUpload = perm.canUpload !== false && !!onUpload;
11459
11651
  const canRemoveFile = perm.canRemoveFile !== false && !!onRemoveFile;
11460
11652
  const canDeleteFolder = perm.canDeleteFolder !== false && !!onDeleteFolder;
11461
- const [createOpen, setCreateOpen] = React57.useState(false);
11462
- const [createName, setCreateName] = React57.useState("");
11463
- const [renameTarget, setRenameTarget] = React57.useState(null);
11464
- const [renameValue, setRenameValue] = React57.useState("");
11465
- const [deleteTarget, setDeleteTarget] = React57.useState(null);
11466
- const uploadInputRef = React57.useRef(null);
11467
- const crumbFolders = React57.useMemo(() => ancestorsOf(folders, currentFolderId), [folders, currentFolderId]);
11468
- const subfolders = React57.useMemo(() => childrenOf(folders, currentFolderId), [folders, currentFolderId]);
11469
- const currentFiles = React57.useMemo(
11653
+ const [createOpen, setCreateOpen] = React58.useState(false);
11654
+ const [createName, setCreateName] = React58.useState("");
11655
+ const [renameTarget, setRenameTarget] = React58.useState(null);
11656
+ const [renameValue, setRenameValue] = React58.useState("");
11657
+ const [deleteTarget, setDeleteTarget] = React58.useState(null);
11658
+ const uploadInputRef = React58.useRef(null);
11659
+ const crumbFolders = React58.useMemo(() => ancestorsOf(folders, currentFolderId), [folders, currentFolderId]);
11660
+ const subfolders = React58.useMemo(() => childrenOf(folders, currentFolderId), [folders, currentFolderId]);
11661
+ const currentFiles = React58.useMemo(
11470
11662
  () => files.filter((f) => f.folderId === currentFolderId).sort((a, b) => a.name.localeCompare(b.name)),
11471
11663
  [files, currentFolderId]
11472
11664
  );
@@ -11505,10 +11697,10 @@ function FileBrowser({
11505
11697
  if (deleteTarget && onDeleteFolder) onDeleteFolder(deleteTarget);
11506
11698
  setDeleteTarget(null);
11507
11699
  };
11508
- const content = /* @__PURE__ */ jsxs79("div", { className: ["fd-fb", className].filter(Boolean).join(" "), children: [
11509
- /* @__PURE__ */ jsxs79("div", { className: "fd-fb-head", children: [
11510
- /* @__PURE__ */ jsxs79("nav", { className: "fd-fb-crumbs", "aria-label": "Folder path", children: [
11511
- /* @__PURE__ */ jsx85(
11700
+ const content = /* @__PURE__ */ jsxs80("div", { className: ["fd-fb", className].filter(Boolean).join(" "), children: [
11701
+ /* @__PURE__ */ jsxs80("div", { className: "fd-fb-head", children: [
11702
+ /* @__PURE__ */ jsxs80("nav", { className: "fd-fb-crumbs", "aria-label": "Folder path", children: [
11703
+ /* @__PURE__ */ jsx86(
11512
11704
  BreadcrumbCrumb,
11513
11705
  {
11514
11706
  label: "Home",
@@ -11518,7 +11710,7 @@ function FileBrowser({
11518
11710
  onDropPayload: (p) => moveIntoFolder(p, null)
11519
11711
  }
11520
11712
  ),
11521
- crumbFolders.map((f, i) => /* @__PURE__ */ jsx85(
11713
+ crumbFolders.map((f, i) => /* @__PURE__ */ jsx86(
11522
11714
  BreadcrumbCrumb,
11523
11715
  {
11524
11716
  label: f.name,
@@ -11530,11 +11722,11 @@ function FileBrowser({
11530
11722
  f.id
11531
11723
  ))
11532
11724
  ] }),
11533
- /* @__PURE__ */ jsxs79("span", { className: "fd-fb-actions", children: [
11534
- canCreateFolder ? /* @__PURE__ */ jsx85(Button, { variant: "secondary", size: "sm", icon: "folder-simple-plus", onClick: openCreate, children: "New folder" }) : null,
11535
- canUpload ? /* @__PURE__ */ jsxs79(Fragment26, { children: [
11536
- /* @__PURE__ */ jsx85(Button, { variant: "secondary", size: "sm", icon: "upload-simple", onClick: () => uploadInputRef.current && uploadInputRef.current.click(), children: "Upload" }),
11537
- /* @__PURE__ */ jsx85(
11725
+ /* @__PURE__ */ jsxs80("span", { className: "fd-fb-actions", children: [
11726
+ canCreateFolder ? /* @__PURE__ */ jsx86(Button, { variant: "secondary", size: "sm", icon: "folder-simple-plus", onClick: openCreate, children: "New folder" }) : null,
11727
+ canUpload ? /* @__PURE__ */ jsxs80(Fragment27, { children: [
11728
+ /* @__PURE__ */ jsx86(Button, { variant: "secondary", size: "sm", icon: "upload-simple", onClick: () => uploadInputRef.current && uploadInputRef.current.click(), children: "Upload" }),
11729
+ /* @__PURE__ */ jsx86(
11538
11730
  "input",
11539
11731
  {
11540
11732
  ref: uploadInputRef,
@@ -11552,9 +11744,9 @@ function FileBrowser({
11552
11744
  ] }) : null
11553
11745
  ] })
11554
11746
  ] }),
11555
- /* @__PURE__ */ jsxs79("div", { className: "fd-fb-body", children: [
11556
- /* @__PURE__ */ jsxs79("div", { className: "fd-fb-tree", role: "region", "aria-label": "Folder tree", children: [
11557
- /* @__PURE__ */ jsx85(
11747
+ /* @__PURE__ */ jsxs80("div", { className: "fd-fb-body", children: [
11748
+ /* @__PURE__ */ jsxs80("div", { className: "fd-fb-tree", role: "region", "aria-label": "Folder tree", children: [
11749
+ /* @__PURE__ */ jsx86(
11558
11750
  RowShell,
11559
11751
  {
11560
11752
  icon: "house-simple",
@@ -11565,7 +11757,7 @@ function FileBrowser({
11565
11757
  className: ["fd-fb-tree-row", currentFolderId == null ? "is-current" : ""].filter(Boolean).join(" ")
11566
11758
  }
11567
11759
  ),
11568
- childrenOf(folders, null).map((f) => /* @__PURE__ */ jsx85(
11760
+ childrenOf(folders, null).map((f) => /* @__PURE__ */ jsx86(
11569
11761
  TreeNode,
11570
11762
  {
11571
11763
  folder: f,
@@ -11579,18 +11771,18 @@ function FileBrowser({
11579
11771
  f.id
11580
11772
  ))
11581
11773
  ] }),
11582
- /* @__PURE__ */ jsx85("div", { className: "fd-fb-main", role: "region", "aria-label": "Folder contents", children: /* @__PURE__ */ jsx85(
11774
+ /* @__PURE__ */ jsx86("div", { className: "fd-fb-main", role: "region", "aria-label": "Folder contents", children: /* @__PURE__ */ jsx86(
11583
11775
  LoadingRegion,
11584
11776
  {
11585
11777
  state: loading ? "loading" : "ready",
11586
11778
  label: "Loading folder contents",
11587
- skeleton: /* @__PURE__ */ jsxs79("div", { className: "fd-stack", style: { gap: 8, padding: 12 }, children: [
11588
- /* @__PURE__ */ jsx85(Skeleton, { h: 44, radius: "10px" }),
11589
- /* @__PURE__ */ jsx85(Skeleton, { h: 44, radius: "10px" }),
11590
- /* @__PURE__ */ jsx85(Skeleton, { h: 44, radius: "10px" })
11779
+ skeleton: /* @__PURE__ */ jsxs80("div", { className: "fd-stack", style: { gap: 8, padding: 12 }, children: [
11780
+ /* @__PURE__ */ jsx86(Skeleton, { h: 44, radius: "10px" }),
11781
+ /* @__PURE__ */ jsx86(Skeleton, { h: 44, radius: "10px" }),
11782
+ /* @__PURE__ */ jsx86(Skeleton, { h: 44, radius: "10px" })
11591
11783
  ] }),
11592
- children: isEmpty ? /* @__PURE__ */ jsx85(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__ */ jsxs79("div", { className: "fd-fb-list", children: [
11593
- subfolders.map((f) => /* @__PURE__ */ jsx85(
11784
+ children: isEmpty ? /* @__PURE__ */ jsx86(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__ */ jsxs80("div", { className: "fd-fb-list", children: [
11785
+ subfolders.map((f) => /* @__PURE__ */ jsx86(
11594
11786
  RowShell,
11595
11787
  {
11596
11788
  icon: "folder-simple",
@@ -11599,9 +11791,9 @@ function FileBrowser({
11599
11791
  draggableId: canMove ? { kind: "folder", id: f.id } : void 0,
11600
11792
  isDropTarget: canMove,
11601
11793
  onDropPayload: (p) => moveIntoFolder(p, f.id),
11602
- actions: /* @__PURE__ */ jsxs79(Fragment26, { children: [
11603
- canRenameFolder ? /* @__PURE__ */ jsx85(IconButton, { icon: "pencil-simple", label: "Rename " + f.name, size: "sm", variant: "ghost", onClick: () => openRename(f) }) : null,
11604
- canMove ? /* @__PURE__ */ jsx85(
11794
+ actions: /* @__PURE__ */ jsxs80(Fragment27, { children: [
11795
+ canRenameFolder ? /* @__PURE__ */ jsx86(IconButton, { icon: "pencil-simple", label: "Rename " + f.name, size: "sm", variant: "ghost", onClick: () => openRename(f) }) : null,
11796
+ canMove ? /* @__PURE__ */ jsx86(
11605
11797
  FolderPickerMenu,
11606
11798
  {
11607
11799
  label: "Move " + f.name,
@@ -11609,12 +11801,12 @@ function FileBrowser({
11609
11801
  onPick: (target) => moveIntoFolder({ kind: "folder", id: f.id }, target)
11610
11802
  }
11611
11803
  ) : null,
11612
- canDeleteFolder ? /* @__PURE__ */ jsx85(IconButton, { icon: "trash-simple", label: "Delete " + f.name, size: "sm", variant: "ghost", onClick: () => openDelete(f) }) : null
11804
+ canDeleteFolder ? /* @__PURE__ */ jsx86(IconButton, { icon: "trash-simple", label: "Delete " + f.name, size: "sm", variant: "ghost", onClick: () => openDelete(f) }) : null
11613
11805
  ] })
11614
11806
  },
11615
11807
  f.id
11616
11808
  )),
11617
- currentFiles.map((file) => /* @__PURE__ */ jsx85(
11809
+ currentFiles.map((file) => /* @__PURE__ */ jsx86(
11618
11810
  RowShell,
11619
11811
  {
11620
11812
  icon: iconForMime(file.mime, file.name),
@@ -11622,8 +11814,8 @@ function FileBrowser({
11622
11814
  meta: file.size ? formatBytes(file.size) : void 0,
11623
11815
  onOpen: onOpenFile ? () => onOpenFile(file) : void 0,
11624
11816
  draggableId: canMove ? { kind: "file", id: file.id } : void 0,
11625
- actions: /* @__PURE__ */ jsxs79(Fragment26, { children: [
11626
- canMove ? /* @__PURE__ */ jsx85(
11817
+ actions: /* @__PURE__ */ jsxs80(Fragment27, { children: [
11818
+ canMove ? /* @__PURE__ */ jsx86(
11627
11819
  FolderPickerMenu,
11628
11820
  {
11629
11821
  label: "Move " + file.name,
@@ -11631,7 +11823,7 @@ function FileBrowser({
11631
11823
  onPick: (target) => onMoveFile && onMoveFile(file.id, target)
11632
11824
  }
11633
11825
  ) : null,
11634
- canRemoveFile ? /* @__PURE__ */ jsx85(IconButton, { icon: "trash-simple", label: "Remove " + file.name, size: "sm", variant: "ghost", onClick: () => onRemoveFile && onRemoveFile(file) }) : null
11826
+ canRemoveFile ? /* @__PURE__ */ jsx86(IconButton, { icon: "trash-simple", label: "Remove " + file.name, size: "sm", variant: "ghost", onClick: () => onRemoveFile && onRemoveFile(file) }) : null
11635
11827
  ] })
11636
11828
  },
11637
11829
  file.id
@@ -11640,10 +11832,10 @@ function FileBrowser({
11640
11832
  }
11641
11833
  ) })
11642
11834
  ] }),
11643
- /* @__PURE__ */ jsx85(Modal, { open: createOpen, title: "New folder", onClose: () => setCreateOpen(false), footer: /* @__PURE__ */ jsxs79(Fragment26, { children: [
11644
- /* @__PURE__ */ jsx85(Button, { variant: "secondary", onClick: () => setCreateOpen(false), children: "Cancel" }),
11645
- /* @__PURE__ */ jsx85(Button, { onClick: submitCreate, disabled: !createName.trim(), children: "Create" })
11646
- ] }), children: /* @__PURE__ */ jsx85(
11835
+ /* @__PURE__ */ jsx86(Modal, { open: createOpen, title: "New folder", onClose: () => setCreateOpen(false), footer: /* @__PURE__ */ jsxs80(Fragment27, { children: [
11836
+ /* @__PURE__ */ jsx86(Button, { variant: "secondary", onClick: () => setCreateOpen(false), children: "Cancel" }),
11837
+ /* @__PURE__ */ jsx86(Button, { onClick: submitCreate, disabled: !createName.trim(), children: "Create" })
11838
+ ] }), children: /* @__PURE__ */ jsx86(
11647
11839
  "input",
11648
11840
  {
11649
11841
  className: "fd-fb-input",
@@ -11657,10 +11849,10 @@ function FileBrowser({
11657
11849
  autoFocus: true
11658
11850
  }
11659
11851
  ) }),
11660
- /* @__PURE__ */ jsx85(Modal, { open: renameTarget != null, title: "Rename folder", onClose: () => setRenameTarget(null), footer: /* @__PURE__ */ jsxs79(Fragment26, { children: [
11661
- /* @__PURE__ */ jsx85(Button, { variant: "secondary", onClick: () => setRenameTarget(null), children: "Cancel" }),
11662
- /* @__PURE__ */ jsx85(Button, { onClick: submitRename, disabled: !renameValue.trim(), children: "Save" })
11663
- ] }), children: /* @__PURE__ */ jsx85(
11852
+ /* @__PURE__ */ jsx86(Modal, { open: renameTarget != null, title: "Rename folder", onClose: () => setRenameTarget(null), footer: /* @__PURE__ */ jsxs80(Fragment27, { children: [
11853
+ /* @__PURE__ */ jsx86(Button, { variant: "secondary", onClick: () => setRenameTarget(null), children: "Cancel" }),
11854
+ /* @__PURE__ */ jsx86(Button, { onClick: submitRename, disabled: !renameValue.trim(), children: "Save" })
11855
+ ] }), children: /* @__PURE__ */ jsx86(
11664
11856
  "input",
11665
11857
  {
11666
11858
  className: "fd-fb-input",
@@ -11674,22 +11866,22 @@ function FileBrowser({
11674
11866
  autoFocus: true
11675
11867
  }
11676
11868
  ) }),
11677
- /* @__PURE__ */ jsx85(
11869
+ /* @__PURE__ */ jsx86(
11678
11870
  Modal,
11679
11871
  {
11680
11872
  open: deleteTarget != null,
11681
11873
  title: deleteTarget ? "Delete \u201C" + deleteTarget.name + "\u201D?" : "Delete folder?",
11682
11874
  description: "This can't be undone. The folder must be empty.",
11683
11875
  onClose: () => setDeleteTarget(null),
11684
- footer: /* @__PURE__ */ jsxs79(Fragment26, { children: [
11685
- /* @__PURE__ */ jsx85(Button, { variant: "secondary", onClick: () => setDeleteTarget(null), children: "Cancel" }),
11686
- /* @__PURE__ */ jsx85(Button, { variant: "danger", onClick: confirmDelete, children: "Delete" })
11876
+ footer: /* @__PURE__ */ jsxs80(Fragment27, { children: [
11877
+ /* @__PURE__ */ jsx86(Button, { variant: "secondary", onClick: () => setDeleteTarget(null), children: "Cancel" }),
11878
+ /* @__PURE__ */ jsx86(Button, { variant: "danger", onClick: confirmDelete, children: "Delete" })
11687
11879
  ] })
11688
11880
  }
11689
11881
  )
11690
11882
  ] });
11691
11883
  if (!canUpload) return content;
11692
- return /* @__PURE__ */ jsx85(Dropzone, { className: "fd-fb-dropzone", onFiles: (picked) => onUpload && onUpload(picked, currentFolderId), label: "Drop files to upload", children: content });
11884
+ return /* @__PURE__ */ jsx86(Dropzone, { className: "fd-fb-dropzone", onFiles: (picked) => onUpload && onUpload(picked, currentFolderId), label: "Drop files to upload", children: content });
11693
11885
  }
11694
11886
  function BreadcrumbCrumb({
11695
11887
  label,
@@ -11698,8 +11890,8 @@ function BreadcrumbCrumb({
11698
11890
  isDropTarget,
11699
11891
  onDropPayload
11700
11892
  }) {
11701
- const [over, setOver] = React57.useState(false);
11702
- const dragCounter = React57.useRef(0);
11893
+ const [over, setOver] = React58.useState(false);
11894
+ const dragCounter = React58.useRef(0);
11703
11895
  const dropHandlers = isDropTarget ? {
11704
11896
  onDragEnter: (e) => {
11705
11897
  if (!hasInternalPayload(e)) return;
@@ -11724,11 +11916,11 @@ function BreadcrumbCrumb({
11724
11916
  if (payload && onDropPayload) onDropPayload(payload);
11725
11917
  }
11726
11918
  } : {};
11727
- return /* @__PURE__ */ jsx85("span", { className: ["fd-fb-crumb", over ? "is-drop-target" : ""].filter(Boolean).join(" "), ...dropHandlers, children: isCurrent ? /* @__PURE__ */ jsx85("span", { className: "fd-fb-crumb-current", "aria-current": "page", children: label }) : /* @__PURE__ */ jsx85("button", { type: "button", className: "fd-fb-crumb-link", onClick, children: label }) });
11919
+ return /* @__PURE__ */ jsx86("span", { className: ["fd-fb-crumb", over ? "is-drop-target" : ""].filter(Boolean).join(" "), ...dropHandlers, children: isCurrent ? /* @__PURE__ */ jsx86("span", { className: "fd-fb-crumb-current", "aria-current": "page", children: label }) : /* @__PURE__ */ jsx86("button", { type: "button", className: "fd-fb-crumb-link", onClick, children: label }) });
11728
11920
  }
11729
11921
 
11730
11922
  // src/kits/query.ts
11731
- import * as React58 from "react";
11923
+ import * as React59 from "react";
11732
11924
  function eqFilter(get2) {
11733
11925
  return (row, value) => Array.isArray(value) ? value.includes(get2(row)) : get2(row) === value;
11734
11926
  }
@@ -11760,22 +11952,22 @@ function compare(a, b, dir) {
11760
11952
  var API = null;
11761
11953
  var PREFS = null;
11762
11954
  function useServerTable({ endpoint, params, defaults, deps, prefsKey }) {
11763
- const [query, setQuery] = React58.useState(() => {
11955
+ const [query, setQuery] = React59.useState(() => {
11764
11956
  const store = PREFS || window.PlannerPrefs;
11765
11957
  const saved = prefsKey && store ? store.getTable(prefsKey) : {};
11766
11958
  return { ...DEFAULTS, ...defaults || {}, ...saved.pageSize ? { pageSize: saved.pageSize } : {}, ...saved.sort ? { sort: saved.sort, dir: saved.dir || "desc" } : {} };
11767
11959
  });
11768
- const savePref = React58.useCallback((patch2) => {
11960
+ const savePref = React59.useCallback((patch2) => {
11769
11961
  const store = PREFS || window.PlannerPrefs;
11770
11962
  if (prefsKey && store) store.setTable(prefsKey, patch2);
11771
11963
  }, [prefsKey]);
11772
- const [res, setRes] = React58.useState(null);
11773
- const [loading, setLoading] = React58.useState(true);
11774
- const seq2 = React58.useRef(0);
11964
+ const [res, setRes] = React59.useState(null);
11965
+ const [loading, setLoading] = React59.useState(true);
11966
+ const seq2 = React59.useRef(0);
11775
11967
  const depKey = (deps || []).join("|");
11776
11968
  const paramKey = JSON.stringify(params || {});
11777
11969
  const queryKey = JSON.stringify(query);
11778
- React58.useEffect(() => {
11970
+ React59.useEffect(() => {
11779
11971
  const id = ++seq2.current;
11780
11972
  setLoading(true);
11781
11973
  const t = setTimeout(() => {
@@ -12074,12 +12266,12 @@ function createVersionStore(initialState, options) {
12074
12266
  }
12075
12267
 
12076
12268
  // src/kits/documentTitle.ts
12077
- import * as React59 from "react";
12269
+ import * as React60 from "react";
12078
12270
  function formatDocumentTitle(routeTitle, appName) {
12079
12271
  return [routeTitle, appName, "Flytedesk"].filter((part) => !!part && part.length > 0).join(" \xB7 ");
12080
12272
  }
12081
12273
  function useDocumentTitle(routeTitle, appName) {
12082
- React59.useEffect(() => {
12274
+ React60.useEffect(() => {
12083
12275
  if (typeof document === "undefined") return;
12084
12276
  document.title = formatDocumentTitle(routeTitle, appName);
12085
12277
  }, [routeTitle, appName]);
@@ -12201,6 +12393,7 @@ export {
12201
12393
  SessionKit,
12202
12394
  SessionProvider,
12203
12395
  SidebarNav,
12396
+ SignInPage,
12204
12397
  Skeleton,
12205
12398
  SkeletonText,
12206
12399
  Slider,