@shapesos/clay 0.18.0 → 0.19.1

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.
Files changed (60) hide show
  1. package/dist/artifacts.cjs +207 -139
  2. package/dist/artifacts.cjs.map +1 -1
  3. package/dist/artifacts.js +5 -2
  4. package/dist/badge.cjs +70 -0
  5. package/dist/badge.cjs.map +1 -0
  6. package/dist/badge.d.cts +28 -0
  7. package/dist/badge.d.ts +28 -0
  8. package/dist/badge.js +9 -0
  9. package/dist/badge.js.map +1 -0
  10. package/dist/blocks.cjs +452 -185
  11. package/dist/blocks.cjs.map +1 -1
  12. package/dist/blocks.css +1 -1
  13. package/dist/blocks.d.cts +14 -3
  14. package/dist/blocks.d.ts +14 -3
  15. package/dist/blocks.js +17 -5
  16. package/dist/chat.cjs +457 -240
  17. package/dist/chat.cjs.map +1 -1
  18. package/dist/chat.d.cts +1 -1
  19. package/dist/chat.d.ts +1 -1
  20. package/dist/chat.js +10 -5
  21. package/dist/{chunk-JGMN6W72.js → chunk-2X4KUXYP.js} +1 -1
  22. package/dist/{chunk-QR4VBGK4.js → chunk-63AGNGKG.js} +81 -200
  23. package/dist/chunk-63AGNGKG.js.map +1 -0
  24. package/dist/chunk-CSTCTO3B.js +161 -0
  25. package/dist/chunk-CSTCTO3B.js.map +1 -0
  26. package/dist/chunk-EIAWZXE4.js +69 -0
  27. package/dist/chunk-EIAWZXE4.js.map +1 -0
  28. package/dist/chunk-EXRNGIQ2.js +41 -0
  29. package/dist/chunk-EXRNGIQ2.js.map +1 -0
  30. package/dist/{chunk-4MZZH3WX.js → chunk-HU5W7CGE.js} +37 -2
  31. package/dist/chunk-HU5W7CGE.js.map +1 -0
  32. package/dist/chunk-PISZYS2H.js +406 -0
  33. package/dist/chunk-PISZYS2H.js.map +1 -0
  34. package/dist/{chunk-CATIRDZP.js → chunk-PWSEEUVL.js} +10 -44
  35. package/dist/chunk-PWSEEUVL.js.map +1 -0
  36. package/dist/copy-button.cjs +439 -0
  37. package/dist/copy-button.cjs.map +1 -0
  38. package/dist/copy-button.d.cts +20 -0
  39. package/dist/copy-button.d.ts +20 -0
  40. package/dist/copy-button.js +12 -0
  41. package/dist/copy-button.js.map +1 -0
  42. package/dist/index.cjs +533 -298
  43. package/dist/index.cjs.map +1 -1
  44. package/dist/index.d.cts +4 -2
  45. package/dist/index.d.ts +4 -2
  46. package/dist/index.js +26 -9
  47. package/dist/table.cjs +40 -0
  48. package/dist/table.cjs.map +1 -1
  49. package/dist/table.d.cts +37 -2
  50. package/dist/table.d.ts +37 -2
  51. package/dist/table.js +11 -1
  52. package/dist/{types-BDYPVP2N.d.cts → types-Bhg0_ES8.d.cts} +74 -2
  53. package/dist/{types-BMwa4bPW.d.ts → types-orOQcI2z.d.ts} +74 -2
  54. package/package.json +11 -1
  55. package/dist/chunk-4MZZH3WX.js.map +0 -1
  56. package/dist/chunk-7MY4X4YL.js +0 -250
  57. package/dist/chunk-7MY4X4YL.js.map +0 -1
  58. package/dist/chunk-CATIRDZP.js.map +0 -1
  59. package/dist/chunk-QR4VBGK4.js.map +0 -1
  60. /package/dist/{chunk-JGMN6W72.js.map → chunk-2X4KUXYP.js.map} +0 -0
package/dist/blocks.cjs CHANGED
@@ -273,8 +273,12 @@ __export(blocks_exports, {
273
273
  Block: () => Block,
274
274
  BlockContext: () => BlockContext,
275
275
  BlockServices: () => BlockServices,
276
+ NotificationDraftBlock: () => NotificationDraftBlock,
277
+ NotificationDraftBlockService: () => NotificationDraftBlockService,
276
278
  TextBlockService: () => TextBlockService,
277
279
  blockTypes: () => blockTypes,
280
+ notificationChannels: () => notificationChannels,
281
+ notificationEmailTypes: () => notificationEmailTypes,
278
282
  useBlockContext: () => useBlockContext
279
283
  });
280
284
  module.exports = __toCommonJS(blocks_exports);
@@ -282,7 +286,8 @@ module.exports = __toCommonJS(blocks_exports);
282
286
  // src/components/blocks/types.ts
283
287
  var blockTypes = {
284
288
  TEXT: "TEXT",
285
- ARTIFACT_REF: "ARTIFACT_REF"
289
+ ARTIFACT_REF: "ARTIFACT_REF",
290
+ NOTIFICATION_DRAFT: "NOTIFICATION_DRAFT"
286
291
  };
287
292
 
288
293
  // src/components/artifacts/artifact-base.ts
@@ -446,33 +451,41 @@ var IconArrowsMinimize = createReactComponent("outline", "arrows-minimize", "Arr
446
451
  var __iconNode4 = [["path", { "d": "M5 12l5 5l10 -10", "key": "svg-0" }]];
447
452
  var IconCheck = createReactComponent("outline", "check", "Check", __iconNode4);
448
453
 
454
+ // node_modules/@tabler/icons-react/dist/esm/icons/IconChevronDown.mjs
455
+ var __iconNode5 = [["path", { "d": "M6 9l6 6l6 -6", "key": "svg-0" }]];
456
+ var IconChevronDown = createReactComponent("outline", "chevron-down", "ChevronDown", __iconNode5);
457
+
449
458
  // node_modules/@tabler/icons-react/dist/esm/icons/IconChevronLeft.mjs
450
- var __iconNode5 = [["path", { "d": "M15 6l-6 6l6 6", "key": "svg-0" }]];
451
- var IconChevronLeft = createReactComponent("outline", "chevron-left", "ChevronLeft", __iconNode5);
459
+ var __iconNode6 = [["path", { "d": "M15 6l-6 6l6 6", "key": "svg-0" }]];
460
+ var IconChevronLeft = createReactComponent("outline", "chevron-left", "ChevronLeft", __iconNode6);
452
461
 
453
462
  // node_modules/@tabler/icons-react/dist/esm/icons/IconChevronRight.mjs
454
- var __iconNode6 = [["path", { "d": "M9 6l6 6l-6 6", "key": "svg-0" }]];
455
- var IconChevronRight = createReactComponent("outline", "chevron-right", "ChevronRight", __iconNode6);
463
+ var __iconNode7 = [["path", { "d": "M9 6l6 6l-6 6", "key": "svg-0" }]];
464
+ var IconChevronRight = createReactComponent("outline", "chevron-right", "ChevronRight", __iconNode7);
456
465
 
457
466
  // node_modules/@tabler/icons-react/dist/esm/icons/IconCopy.mjs
458
- var __iconNode7 = [["path", { "d": "M7 9.667a2.667 2.667 0 0 1 2.667 -2.667h8.666a2.667 2.667 0 0 1 2.667 2.667v8.666a2.667 2.667 0 0 1 -2.667 2.667h-8.666a2.667 2.667 0 0 1 -2.667 -2.667l0 -8.666", "key": "svg-0" }], ["path", { "d": "M4.012 16.737a2.005 2.005 0 0 1 -1.012 -1.737v-10c0 -1.1 .9 -2 2 -2h10c.75 0 1.158 .385 1.5 1", "key": "svg-1" }]];
459
- var IconCopy = createReactComponent("outline", "copy", "Copy", __iconNode7);
467
+ var __iconNode8 = [["path", { "d": "M7 9.667a2.667 2.667 0 0 1 2.667 -2.667h8.666a2.667 2.667 0 0 1 2.667 2.667v8.666a2.667 2.667 0 0 1 -2.667 2.667h-8.666a2.667 2.667 0 0 1 -2.667 -2.667l0 -8.666", "key": "svg-0" }], ["path", { "d": "M4.012 16.737a2.005 2.005 0 0 1 -1.012 -1.737v-10c0 -1.1 .9 -2 2 -2h10c.75 0 1.158 .385 1.5 1", "key": "svg-1" }]];
468
+ var IconCopy = createReactComponent("outline", "copy", "Copy", __iconNode8);
460
469
 
461
470
  // node_modules/@tabler/icons-react/dist/esm/icons/IconDownload.mjs
462
- var __iconNode8 = [["path", { "d": "M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2 -2v-2", "key": "svg-0" }], ["path", { "d": "M7 11l5 5l5 -5", "key": "svg-1" }], ["path", { "d": "M12 4l0 12", "key": "svg-2" }]];
463
- var IconDownload = createReactComponent("outline", "download", "Download", __iconNode8);
471
+ var __iconNode9 = [["path", { "d": "M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2 -2v-2", "key": "svg-0" }], ["path", { "d": "M7 11l5 5l5 -5", "key": "svg-1" }], ["path", { "d": "M12 4l0 12", "key": "svg-2" }]];
472
+ var IconDownload = createReactComponent("outline", "download", "Download", __iconNode9);
464
473
 
465
474
  // node_modules/@tabler/icons-react/dist/esm/icons/IconFileSpreadsheet.mjs
466
- var __iconNode9 = [["path", { "d": "M14 3v4a1 1 0 0 0 1 1h4", "key": "svg-0" }], ["path", { "d": "M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2", "key": "svg-1" }], ["path", { "d": "M8 11h8v7h-8l0 -7", "key": "svg-2" }], ["path", { "d": "M8 15h8", "key": "svg-3" }], ["path", { "d": "M11 11v7", "key": "svg-4" }]];
467
- var IconFileSpreadsheet = createReactComponent("outline", "file-spreadsheet", "FileSpreadsheet", __iconNode9);
475
+ var __iconNode10 = [["path", { "d": "M14 3v4a1 1 0 0 0 1 1h4", "key": "svg-0" }], ["path", { "d": "M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2", "key": "svg-1" }], ["path", { "d": "M8 11h8v7h-8l0 -7", "key": "svg-2" }], ["path", { "d": "M8 15h8", "key": "svg-3" }], ["path", { "d": "M11 11v7", "key": "svg-4" }]];
476
+ var IconFileSpreadsheet = createReactComponent("outline", "file-spreadsheet", "FileSpreadsheet", __iconNode10);
468
477
 
469
478
  // node_modules/@tabler/icons-react/dist/esm/icons/IconLoader2.mjs
470
- var __iconNode10 = [["path", { "d": "M12 3a9 9 0 1 0 9 9", "key": "svg-0" }]];
471
- var IconLoader2 = createReactComponent("outline", "loader-2", "Loader2", __iconNode10);
479
+ var __iconNode11 = [["path", { "d": "M12 3a9 9 0 1 0 9 9", "key": "svg-0" }]];
480
+ var IconLoader2 = createReactComponent("outline", "loader-2", "Loader2", __iconNode11);
472
481
 
473
482
  // node_modules/@tabler/icons-react/dist/esm/icons/IconPhoto.mjs
474
- var __iconNode11 = [["path", { "d": "M15 8h.01", "key": "svg-0" }], ["path", { "d": "M3 6a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v12a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3v-12", "key": "svg-1" }], ["path", { "d": "M3 16l5 -5c.928 -.893 2.072 -.893 3 0l5 5", "key": "svg-2" }], ["path", { "d": "M14 14l1 -1c.928 -.893 2.072 -.893 3 0l3 3", "key": "svg-3" }]];
475
- var IconPhoto = createReactComponent("outline", "photo", "Photo", __iconNode11);
483
+ var __iconNode12 = [["path", { "d": "M15 8h.01", "key": "svg-0" }], ["path", { "d": "M3 6a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v12a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3v-12", "key": "svg-1" }], ["path", { "d": "M3 16l5 -5c.928 -.893 2.072 -.893 3 0l5 5", "key": "svg-2" }], ["path", { "d": "M14 14l1 -1c.928 -.893 2.072 -.893 3 0l3 3", "key": "svg-3" }]];
484
+ var IconPhoto = createReactComponent("outline", "photo", "Photo", __iconNode12);
485
+
486
+ // node_modules/@tabler/icons-react/dist/esm/icons/IconFlask2Filled.mjs
487
+ var __iconNode13 = [["path", { "d": "M15 2a1 1 0 0 1 0 2v5.674l.062 .03a7 7 0 0 1 3.85 5.174l.037 .262a7 7 0 0 1 -3.078 6.693a1 1 0 0 1 -.553 .167h-6.635a1 1 0 0 1 -.552 -.166a7 7 0 0 1 .807 -12.134l.062 -.028v-5.672a1 1 0 1 1 0 -2h6zm-2 2h-2v6.34a1 1 0 0 1 -.551 .894l-.116 .049a5 5 0 0 0 -2.92 2.717h9.172a5 5 0 0 0 -2.918 -2.715a1 1 0 0 1 -.667 -.943v-6.342z", "key": "svg-0" }]];
488
+ var IconFlask2Filled = createReactComponent("filled", "flask-2-filled", "Flask2Filled", __iconNode13);
476
489
 
477
490
  // src/components/artifacts/artifact-copy-as-image-button/artifact-copy-as-image-button.tsx
478
491
  var import_react6 = require("react");
@@ -2048,6 +2061,41 @@ var ChartArtifactService = {
2048
2061
  // src/components/artifacts/deck-artifact/deck-artifact.tsx
2049
2062
  var import_react17 = require("react");
2050
2063
  var import_react_dom = require("react-dom");
2064
+
2065
+ // src/components/badge/badge.tsx
2066
+ var import_jsx_runtime20 = require("react/jsx-runtime");
2067
+ var BASE = "inline-flex items-center whitespace-nowrap rounded-full";
2068
+ var SIZES = {
2069
+ // `sm` is a uniform scale-down of `md` (text 10/12 of caption): padding and line-height keep
2070
+ // md's proportions (caption is 12px text on a 16px line = 1.333 ratio) so the pill shape matches.
2071
+ md: "px-2.5 py-0.5 text-geist-label-caption-medium",
2072
+ sm: "px-2 py-0.5 text-[11px]/[1.333] font-medium"
2073
+ };
2074
+ var SUBTLE = {
2075
+ neutral: "bg-brown-20 text-brown-70",
2076
+ warning: "bg-orange-50 text-orange-600",
2077
+ violet: "bg-violet-50 text-violet-600"
2078
+ };
2079
+ var OUTLINE = {
2080
+ neutral: "border border-brown-30 bg-white text-brown-100",
2081
+ warning: "border border-orange-200 bg-white text-orange-600",
2082
+ violet: "border border-violet-400 bg-white text-violet-600"
2083
+ };
2084
+ var VARIANTS = {
2085
+ subtle: SUBTLE,
2086
+ outline: OUTLINE
2087
+ };
2088
+ function Badge({
2089
+ variant = "subtle",
2090
+ tone = "neutral",
2091
+ size = "md",
2092
+ className,
2093
+ children
2094
+ }) {
2095
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: cn(BASE, SIZES[size], VARIANTS[variant][tone], className), children });
2096
+ }
2097
+
2098
+ // src/components/artifacts/deck-artifact/deck-artifact.tsx
2051
2099
  init_capture_exclude_attribute();
2052
2100
 
2053
2101
  // src/components/artifacts/deck-artifact/deck-artifact-content.tsx
@@ -2055,23 +2103,23 @@ var import_react16 = require("react");
2055
2103
 
2056
2104
  // src/components/ui/table.tsx
2057
2105
  var React3 = __toESM(require("react"), 1);
2058
- var import_jsx_runtime20 = require("react/jsx-runtime");
2059
- var Table = React3.forwardRef(({ className, containerClassName, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: cn("relative w-full overflow-auto", containerClassName), children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("table", { ref, className: cn("w-full caption-bottom text-sm", className), ...props }) }));
2106
+ var import_jsx_runtime21 = require("react/jsx-runtime");
2107
+ var Table = React3.forwardRef(({ className, containerClassName, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: cn("relative w-full overflow-auto", containerClassName), children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("table", { ref, className: cn("w-full caption-bottom text-sm", className), ...props }) }));
2060
2108
  Table.displayName = "Table";
2061
2109
  var TableHeader = React3.forwardRef(
2062
- ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("thead", { ref, className: cn("[&_tr]:border-b", className), ...props })
2110
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("thead", { ref, className: cn("[&_tr]:border-b", className), ...props })
2063
2111
  );
2064
2112
  TableHeader.displayName = "TableHeader";
2065
2113
  var TableBody = React3.forwardRef(
2066
- ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("tbody", { ref, className: cn("[&_tr:last-child]:border-0", className), ...props })
2114
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("tbody", { ref, className: cn("[&_tr:last-child]:border-0", className), ...props })
2067
2115
  );
2068
2116
  TableBody.displayName = "TableBody";
2069
2117
  var TableFooter = React3.forwardRef(
2070
- ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("tfoot", { ref, className: cn("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0", className), ...props })
2118
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("tfoot", { ref, className: cn("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0", className), ...props })
2071
2119
  );
2072
2120
  TableFooter.displayName = "TableFooter";
2073
2121
  var TableRow = React3.forwardRef(
2074
- ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2122
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2075
2123
  "tr",
2076
2124
  {
2077
2125
  ref,
@@ -2082,7 +2130,7 @@ var TableRow = React3.forwardRef(
2082
2130
  );
2083
2131
  TableRow.displayName = "TableRow";
2084
2132
  var TableHead = React3.forwardRef(
2085
- ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2133
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2086
2134
  "th",
2087
2135
  {
2088
2136
  ref,
@@ -2096,11 +2144,11 @@ var TableHead = React3.forwardRef(
2096
2144
  );
2097
2145
  TableHead.displayName = "TableHead";
2098
2146
  var TableCell = React3.forwardRef(
2099
- ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("td", { ref, className: cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className), ...props })
2147
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("td", { ref, className: cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className), ...props })
2100
2148
  );
2101
2149
  TableCell.displayName = "TableCell";
2102
2150
  var TableCaption = React3.forwardRef(
2103
- ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("caption", { ref, className: cn("mt-4 text-sm text-muted-foreground", className), ...props })
2151
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("caption", { ref, className: cn("mt-4 text-sm text-muted-foreground", className), ...props })
2104
2152
  );
2105
2153
  TableCaption.displayName = "TableCaption";
2106
2154
 
@@ -2130,6 +2178,36 @@ function useScrollShadow() {
2130
2178
  return { targetRef, isScrolled };
2131
2179
  }
2132
2180
 
2181
+ // src/components/table/data-table.tsx
2182
+ var import_jsx_runtime22 = require("react/jsx-runtime");
2183
+ var DATA_TABLE_HEAD_CLASS = "h-auto py-2 px-4 text-xs font-medium text-foreground whitespace-nowrap text-left";
2184
+ var DATA_TABLE_CELL_CLASS = "p-4 text-sm font-normal text-foreground align-top min-w-[150px] text-left";
2185
+ var DATA_TABLE_ROW_CLASS = "border-b-brown-30 bg-background/70 hover:bg-secondary";
2186
+ var DATA_TABLE_SCROLL_SHADOW = "0 1px 2px rgb(0 0 0 / 0.01), 0 6px 12px -2px rgb(0 0 0 / 0.03)";
2187
+ function DataTable({ header, children, maxBodyHeight, className }) {
2188
+ const { targetRef, isScrolled } = useScrollShadow();
2189
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2190
+ "div",
2191
+ {
2192
+ ref: targetRef,
2193
+ className: cn("overscroll-none", className),
2194
+ style: maxBodyHeight !== void 0 ? { maxHeight: maxBodyHeight, overflowY: "auto" } : void 0,
2195
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Table, { containerClassName: "overflow-visible", children: [
2196
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2197
+ TableHeader,
2198
+ {
2199
+ "data-scrolled": isScrolled ? "true" : void 0,
2200
+ className: "sticky top-0 z-10 bg-background/70 backdrop-blur-lg transition-shadow",
2201
+ style: isScrolled ? { boxShadow: DATA_TABLE_SCROLL_SHADOW } : void 0,
2202
+ children: header
2203
+ }
2204
+ ),
2205
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TableBody, { children })
2206
+ ] })
2207
+ }
2208
+ );
2209
+ }
2210
+
2133
2211
  // src/components/artifacts/table-artifact/table-artifact-content.constants.ts
2134
2212
  var TABLE_STATUS = {
2135
2213
  LOADING: "loading",
@@ -2142,14 +2220,10 @@ var TABLE_STATUS = {
2142
2220
  function formatCell(row, column) {
2143
2221
  return row[column.key] ?? "";
2144
2222
  }
2145
- var HEAD_CLASS = "h-auto py-2 px-4 text-xs font-medium text-foreground whitespace-nowrap text-left";
2146
- var CELL_CLASS = "p-4 text-sm font-normal text-foreground align-top min-w-[150px] text-left";
2147
- var ROW_CLASSES = "border-b-brown-30 bg-background/70 hover:bg-secondary";
2148
- var DATA_ROW_CLASSES = `${ROW_CLASSES} animate-in fade-in duration-300`;
2149
- var SCROLL_SHADOW = "0 1px 2px rgb(0 0 0 / 0.01), 0 6px 12px -2px rgb(0 0 0 / 0.03)";
2223
+ var DATA_ROW_CLASSES = `${DATA_TABLE_ROW_CLASS} animate-in fade-in duration-300`;
2150
2224
 
2151
2225
  // src/components/artifacts/table-artifact/table-artifact-content.tsx
2152
- var import_jsx_runtime21 = require("react/jsx-runtime");
2226
+ var import_jsx_runtime23 = require("react/jsx-runtime");
2153
2227
  function TableArtifactContent({
2154
2228
  columns,
2155
2229
  data,
@@ -2159,50 +2233,45 @@ function TableArtifactContent({
2159
2233
  labels
2160
2234
  }) {
2161
2235
  if (data.status === TABLE_STATUS.ERROR) {
2162
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(StatusMessage, { $tone: "error", children: labels.loadError });
2236
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(StatusMessage, { $tone: "error", children: labels.loadError });
2163
2237
  }
2164
2238
  if (data.status === TABLE_STATUS.UNAVAILABLE) {
2165
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(StatusMessage, { $tone: "info", children: labels.unavailable });
2239
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(StatusMessage, { $tone: "info", children: labels.unavailable });
2166
2240
  }
2167
2241
  if (data.status === TABLE_STATUS.LOADING) {
2168
2242
  if (typeof knownRowCount === "number" && knownRowCount > 0) {
2169
2243
  const shimmerCount = Math.min(knownRowCount, maxShimmerRows);
2170
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ArtifactTable, { columns, maxBodyHeight, children: renderShimmerRows(columns, shimmerCount) });
2244
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ArtifactTable, { columns, maxBodyHeight, children: renderShimmerRows(columns, shimmerCount) });
2171
2245
  }
2172
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(StatusMessage, { $tone: "info", children: labels.loading });
2246
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(StatusMessage, { $tone: "info", children: labels.loading });
2173
2247
  }
2174
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ArtifactTable, { columns, maxBodyHeight, children: data.rows.length === 0 ? renderEmptyRow(columns.length, labels.empty) : renderDataRows(columns, data.rows) });
2248
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ArtifactTable, { columns, maxBodyHeight, children: data.rows.length === 0 ? renderEmptyRow(columns.length, labels.empty) : renderDataRows(columns, data.rows) });
2175
2249
  }
2176
2250
  function ArtifactTable({ columns, maxBodyHeight, children }) {
2177
- const { targetRef, isScrolled } = useScrollShadow();
2178
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { ref: targetRef, className: "overscroll-none", style: { maxHeight: maxBodyHeight, overflowY: "auto" }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Table, { containerClassName: "overflow-visible", children: [
2179
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2180
- TableHeader,
2181
- {
2182
- "data-scrolled": isScrolled ? "true" : void 0,
2183
- className: "sticky top-0 z-10 bg-background/70 backdrop-blur-lg transition-shadow",
2184
- style: isScrolled ? { boxShadow: SCROLL_SHADOW } : void 0,
2185
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TableRow, { className: "hover:bg-transparent", children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TableHead, { scope: "col", className: HEAD_CLASS, children: column.label }, column.key)) })
2186
- }
2187
- ),
2188
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TableBody, { children })
2189
- ] }) });
2251
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2252
+ DataTable,
2253
+ {
2254
+ maxBodyHeight,
2255
+ header: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TableRow, { className: "hover:bg-transparent", children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TableHead, { scope: "col", className: DATA_TABLE_HEAD_CLASS, children: column.label }, column.key)) }),
2256
+ children
2257
+ }
2258
+ );
2190
2259
  }
2191
2260
  function renderShimmerRows(columns, count) {
2192
- return Array.from({ length: count }).map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TableRow, { className: ROW_CLASSES, "aria-hidden": "true", children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TableCell, { className: CELL_CLASS, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "block h-3 w-3/4 animate-pulse rounded bg-muted-foreground/20" }) }, column.key)) }, `shimmer-${index}`));
2261
+ return Array.from({ length: count }).map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TableRow, { className: DATA_TABLE_ROW_CLASS, "aria-hidden": "true", children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TableCell, { className: DATA_TABLE_CELL_CLASS, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "block h-3 w-3/4 animate-pulse rounded bg-muted-foreground/20" }) }, column.key)) }, `shimmer-${index}`));
2193
2262
  }
2194
2263
  function renderDataRows(columns, rows) {
2195
- return rows.map((row, index) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TableRow, { className: DATA_ROW_CLASSES, children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TableCell, { className: CELL_CLASS, children: formatCell(row, column) }, column.key)) }, index));
2264
+ return rows.map((row, index) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TableRow, { className: DATA_ROW_CLASSES, children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TableCell, { className: DATA_TABLE_CELL_CLASS, children: formatCell(row, column) }, column.key)) }, index));
2196
2265
  }
2197
2266
  function renderEmptyRow(colSpan, emptyMessage) {
2198
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TableRow, { className: "hover:bg-transparent", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TableCell, { colSpan, className: "py-6 text-center text-sm text-muted-foreground", children: emptyMessage }) });
2267
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TableRow, { className: "hover:bg-transparent", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TableCell, { colSpan, className: "py-6 text-center text-sm text-muted-foreground", children: emptyMessage }) });
2199
2268
  }
2200
2269
 
2201
2270
  // src/components/artifacts/deck-artifact/deck-markdown.tsx
2202
2271
  var import_react_markdown = __toESM(require("react-markdown"), 1);
2203
2272
  var import_remark_breaks = __toESM(require("remark-breaks"), 1);
2204
2273
  var import_remark_gfm = __toESM(require("remark-gfm"), 1);
2205
- var import_jsx_runtime22 = require("react/jsx-runtime");
2274
+ var import_jsx_runtime24 = require("react/jsx-runtime");
2206
2275
  function sanitize(text) {
2207
2276
  return text.split("\n").filter((line) => {
2208
2277
  const t = line.trim();
@@ -2210,45 +2279,45 @@ function sanitize(text) {
2210
2279
  }).join("\n");
2211
2280
  }
2212
2281
  var MARKDOWN_COMPONENTS = {
2213
- h1: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h1", { className: "text-[30px] font-semibold leading-tight text-foreground mb-3", ...props }),
2214
- h2: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h2", { className: "text-[26px] font-semibold leading-tight text-foreground mb-2", ...props }),
2215
- h3: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { className: "text-[24px] font-semibold leading-tight text-foreground mb-2", ...props }),
2216
- h4: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h4", { className: "text-[24px] font-semibold leading-tight text-foreground mb-2", ...props }),
2217
- h5: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h5", { className: "text-[24px] font-semibold leading-tight text-foreground mb-2", ...props }),
2218
- h6: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h6", { className: "text-[24px] font-semibold leading-tight text-foreground mb-2", ...props }),
2219
- p: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-[22px] leading-relaxed text-foreground my-2", ...props }),
2220
- ul: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("ul", { className: "list-disc pl-7 text-[22px] leading-relaxed text-foreground my-2", ...props }),
2221
- ol: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("ol", { className: "list-decimal pl-7 text-[22px] leading-relaxed text-foreground my-2", ...props }),
2282
+ h1: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h1", { className: "text-[30px] font-semibold leading-tight text-foreground mb-3", ...props }),
2283
+ h2: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h2", { className: "text-[26px] font-semibold leading-tight text-foreground mb-2", ...props }),
2284
+ h3: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h3", { className: "text-[24px] font-semibold leading-tight text-foreground mb-2", ...props }),
2285
+ h4: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h4", { className: "text-[24px] font-semibold leading-tight text-foreground mb-2", ...props }),
2286
+ h5: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h5", { className: "text-[24px] font-semibold leading-tight text-foreground mb-2", ...props }),
2287
+ h6: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h6", { className: "text-[24px] font-semibold leading-tight text-foreground mb-2", ...props }),
2288
+ p: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-[22px] leading-relaxed text-foreground my-2", ...props }),
2289
+ ul: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("ul", { className: "list-disc pl-7 text-[22px] leading-relaxed text-foreground my-2", ...props }),
2290
+ ol: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("ol", { className: "list-decimal pl-7 text-[22px] leading-relaxed text-foreground my-2", ...props }),
2222
2291
  // react-markdown injects list metadata (`ordered` / `index` / `checked`) that must not leak to the DOM.
2223
- li: ({ node: _node, ordered: _ordered, index: _index, checked: _checked, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("li", { className: "my-1", ...props }),
2224
- strong: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("strong", { className: "font-semibold", ...props }),
2225
- em: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("em", { className: "italic", ...props }),
2292
+ li: ({ node: _node, ordered: _ordered, index: _index, checked: _checked, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("li", { className: "my-1", ...props }),
2293
+ strong: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("strong", { className: "font-semibold", ...props }),
2294
+ em: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("em", { className: "italic", ...props }),
2226
2295
  // Gate `<img src>` against an http(s) allowlist. react-markdown v8 percent-encodes the URL but
2227
2296
  // does NOT protocol-filter image src (unlike link href), so an LLM-authored
2228
2297
  // `![](javascript:…)` / `![](data:…)` or a tracking-pixel `![](http://…)` would otherwise render
2229
2298
  // with the raw URL. Unsafe src → render nothing.
2230
- img: ({ node: _node, src, ...props }) => typeof src === "string" && isSafeDownloadUrl(src) ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("img", { src, className: "max-w-full", ...props }) : null,
2299
+ img: ({ node: _node, src, ...props }) => typeof src === "string" && isSafeDownloadUrl(src) ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("img", { src, className: "max-w-full", ...props }) : null,
2231
2300
  a: ({ node: _node, ...props }) => (
2232
2301
  // `rel` is forced AFTER `{...props}` so it can't be overridden — if a consumer ever adds
2233
2302
  // `linkTarget="_blank"`, LLM-authored links still can't reach `window.opener`.
2234
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("a", { className: "underline underline-offset-2", ...props, rel: "noopener noreferrer" })
2303
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("a", { className: "underline underline-offset-2", ...props, rel: "noopener noreferrer" })
2235
2304
  ),
2236
2305
  // react-markdown passes `inline` to distinguish inline code from fenced blocks — strip it from the DOM.
2237
- code: ({ node: _node, inline: _inline, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("code", { className: "rounded bg-muted px-1.5 py-0.5 font-mono text-[18px]", ...props }),
2238
- blockquote: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("blockquote", { className: "border-l-2 border-brown-alpha-12 pl-4 text-[22px] text-muted-foreground", ...props }),
2239
- hr: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("hr", { className: "my-4 border-brown-alpha-12", ...props }),
2240
- table: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("table", { className: "w-full border-collapse text-[20px]", ...props }) }),
2306
+ code: ({ node: _node, inline: _inline, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("code", { className: "rounded bg-muted px-1.5 py-0.5 font-mono text-[18px]", ...props }),
2307
+ blockquote: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("blockquote", { className: "border-l-2 border-brown-alpha-12 pl-4 text-[22px] text-muted-foreground", ...props }),
2308
+ hr: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("hr", { className: "my-4 border-brown-alpha-12", ...props }),
2309
+ table: ({ node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("table", { className: "w-full border-collapse text-[20px]", ...props }) }),
2241
2310
  // react-markdown passes `isHeader` to cell renderers — strip it so it never reaches the DOM.
2242
- th: ({ node: _node, isHeader: _isHeader, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("th", { className: "border-b border-brown-alpha-12 px-3 py-1.5 text-left font-medium", ...props }),
2243
- td: ({ node: _node, isHeader: _isHeader, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("td", { className: "border-b border-brown-alpha-12 px-3 py-1.5", ...props })
2311
+ th: ({ node: _node, isHeader: _isHeader, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("th", { className: "border-b border-brown-alpha-12 px-3 py-1.5 text-left font-medium", ...props }),
2312
+ td: ({ node: _node, isHeader: _isHeader, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("td", { className: "border-b border-brown-alpha-12 px-3 py-1.5", ...props })
2244
2313
  };
2245
2314
  function DeckMarkdown({ markdown }) {
2246
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_markdown.default, { remarkPlugins: [import_remark_gfm.default, import_remark_breaks.default], components: MARKDOWN_COMPONENTS, children: sanitize(markdown) });
2315
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react_markdown.default, { remarkPlugins: [import_remark_gfm.default, import_remark_breaks.default], components: MARKDOWN_COMPONENTS, children: sanitize(markdown) });
2247
2316
  }
2248
2317
 
2249
2318
  // src/components/artifacts/deck-artifact/slide-renderers.tsx
2250
2319
  var import_react15 = require("react");
2251
- var import_jsx_runtime23 = require("react/jsx-runtime");
2320
+ var import_jsx_runtime25 = require("react/jsx-runtime");
2252
2321
  function safeLogoUrl(meta) {
2253
2322
  return meta?.logoUrl && isSafeDownloadUrl(meta.logoUrl) ? meta.logoUrl : null;
2254
2323
  }
@@ -2275,7 +2344,7 @@ function SlideFrame({ meta, children, accent = false, bare = false }) {
2275
2344
  const eyebrowColor = accent ? "text-white/70" : "text-brown-60";
2276
2345
  const borderColor = accent ? "border-white/20" : "border-brown-alpha-12";
2277
2346
  const logoSrc = safeLogoUrl(meta);
2278
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { ref: frameRef, className: `relative aspect-[16/9] w-full overflow-hidden rounded-lg ${bg}`, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
2347
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { ref: frameRef, className: `relative aspect-[16/9] w-full overflow-hidden rounded-lg ${bg}`, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
2279
2348
  "div",
2280
2349
  {
2281
2350
  className: "absolute left-0 top-0 origin-top-left",
@@ -2286,26 +2355,26 @@ function SlideFrame({ meta, children, accent = false, bare = false }) {
2286
2355
  visibility: scale === null ? "hidden" : "visible"
2287
2356
  },
2288
2357
  children: [
2289
- !bare ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
2358
+ !bare ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
2290
2359
  "div",
2291
2360
  {
2292
2361
  className: `absolute inset-x-0 top-0 flex items-center justify-between border-b px-16 ${borderColor}`,
2293
2362
  style: { height: EYEBROW_H },
2294
2363
  children: [
2295
- meta?.eyebrow ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: eyebrowColor, style: { ...ACCENT_FONT, fontSize: 22 }, children: meta.eyebrow }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", {}),
2296
- logoSrc ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: logoSrc, alt: "", className: "object-contain", style: { maxHeight: CANVAS_LOGO_MAX_H } }) : null
2364
+ meta?.eyebrow ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: eyebrowColor, style: { ...ACCENT_FONT, fontSize: 22 }, children: meta.eyebrow }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", {}),
2365
+ logoSrc ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("img", { src: logoSrc, alt: "", className: "object-contain", style: { maxHeight: CANVAS_LOGO_MAX_H } }) : null
2297
2366
  ]
2298
2367
  }
2299
2368
  ) : null,
2300
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "absolute inset-x-0 bottom-0 overflow-hidden", style: { top: bare ? 0 : EYEBROW_H }, children })
2369
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "absolute inset-x-0 bottom-0 overflow-hidden", style: { top: bare ? 0 : EYEBROW_H }, children })
2301
2370
  ]
2302
2371
  }
2303
2372
  ) });
2304
2373
  }
2305
2374
  function TitleSlide({ slide, meta }) {
2306
2375
  const logoSrc = safeLogoUrl(meta);
2307
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SlideFrame, { meta, bare: true, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex h-full flex-col justify-center px-24 py-16", children: [
2308
- logoSrc ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2376
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(SlideFrame, { meta, bare: true, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex h-full flex-col justify-center px-24 py-16", children: [
2377
+ logoSrc ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2309
2378
  "img",
2310
2379
  {
2311
2380
  src: logoSrc,
@@ -2314,7 +2383,7 @@ function TitleSlide({ slide, meta }) {
2314
2383
  style: { maxHeight: 56, maxWidth: 380 }
2315
2384
  }
2316
2385
  ) : null,
2317
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2386
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2318
2387
  "h1",
2319
2388
  {
2320
2389
  className: "font-bold tracking-tight text-brown-100",
@@ -2322,36 +2391,36 @@ function TitleSlide({ slide, meta }) {
2322
2391
  children: slide.title
2323
2392
  }
2324
2393
  ),
2325
- slide.subtitle ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "mt-7 text-brown-70", style: { ...ACCENT_FONT, fontSize: 34 }, children: slide.subtitle }) : null,
2326
- slide.description ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "mt-4 leading-relaxed text-brown-70", style: { fontSize: 24, maxWidth: 880 }, children: slide.description }) : null,
2327
- meta?.date ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "mt-10 text-brown-70", style: { ...ACCENT_FONT, fontSize: 30 }, children: meta.date }) : null
2394
+ slide.subtitle ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "mt-7 text-brown-70", style: { ...ACCENT_FONT, fontSize: 34 }, children: slide.subtitle }) : null,
2395
+ slide.description ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "mt-4 leading-relaxed text-brown-70", style: { fontSize: 24, maxWidth: 880 }, children: slide.description }) : null,
2396
+ meta?.date ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "mt-10 text-brown-70", style: { ...ACCENT_FONT, fontSize: 30 }, children: meta.date }) : null
2328
2397
  ] }) });
2329
2398
  }
2330
2399
  function AgendaSlide({ slide, meta, labels }) {
2331
2400
  const items = slide.items ?? [];
2332
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SlideFrame, { meta, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "h-full px-24 py-14", children: [
2333
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h2", { className: "mb-10 font-bold text-brown-90", style: { fontSize: 40 }, children: slide.title || labels.agenda }),
2334
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex flex-col", children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-baseline gap-6 border-b border-brown-alpha-12 py-5", children: [
2335
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "shrink-0 text-indigo-600", style: { ...ACCENT_FONT, fontSize: 28, width: 64 }, children: String(i + 1).padStart(2, "0") }),
2336
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-brown-90", style: { fontSize: 28 }, children: item })
2401
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(SlideFrame, { meta, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "h-full px-24 py-14", children: [
2402
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h2", { className: "mb-10 font-bold text-brown-90", style: { fontSize: 40 }, children: slide.title || labels.agenda }),
2403
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex flex-col", children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-baseline gap-6 border-b border-brown-alpha-12 py-5", children: [
2404
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "shrink-0 text-indigo-600", style: { ...ACCENT_FONT, fontSize: 28, width: 64 }, children: String(i + 1).padStart(2, "0") }),
2405
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-brown-90", style: { fontSize: 28 }, children: item })
2337
2406
  ] }, i)) })
2338
2407
  ] }) });
2339
2408
  }
2340
2409
  function SectionSlide({ slide, meta }) {
2341
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SlideFrame, { meta, accent: true, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex h-full flex-col justify-center gap-6 px-24", children: [
2342
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h2", { className: "font-bold text-white", style: { fontSize: 72, lineHeight: 1.05, maxWidth: 940 }, children: slide.title }),
2343
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "mt-2 bg-white/50", style: { width: 96, height: 5 } })
2410
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(SlideFrame, { meta, accent: true, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex h-full flex-col justify-center gap-6 px-24", children: [
2411
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h2", { className: "font-bold text-white", style: { fontSize: 72, lineHeight: 1.05, maxWidth: 940 }, children: slide.title }),
2412
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "mt-2 bg-white/50", style: { width: 96, height: 5 } })
2344
2413
  ] }) });
2345
2414
  }
2346
2415
  function ClosingSlide({ meta, labels }) {
2347
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SlideFrame, { meta, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex h-full flex-col items-center justify-center gap-6 px-24 text-center", children: [
2348
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h1", { className: "font-bold text-brown-100", style: { fontSize: 72 }, children: labels.thankYou }),
2349
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-indigo-600", style: { ...ACCENT_FONT, fontSize: 36 }, children: labels.questions })
2416
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(SlideFrame, { meta, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex h-full flex-col items-center justify-center gap-6 px-24 text-center", children: [
2417
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h1", { className: "font-bold text-brown-100", style: { fontSize: 72 }, children: labels.thankYou }),
2418
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-indigo-600", style: { ...ACCENT_FONT, fontSize: 36 }, children: labels.questions })
2350
2419
  ] }) });
2351
2420
  }
2352
2421
 
2353
2422
  // src/components/artifacts/deck-artifact/deck-artifact-content.tsx
2354
- var import_jsx_runtime24 = require("react/jsx-runtime");
2423
+ var import_jsx_runtime26 = require("react/jsx-runtime");
2355
2424
  var TABLE_BLOCK_MAX_SHIMMER_ROWS = 10;
2356
2425
  var TABLE_CHROME_RESERVE = 56;
2357
2426
  var VISUAL_FALLBACK_HEIGHT = 360;
@@ -2381,14 +2450,14 @@ function DeckArtifactContent({
2381
2450
  [slides.length, onNavigate, isControlled, onSlideChange]
2382
2451
  );
2383
2452
  const position = labels.position.replace("{current}", String(current + 1)).replace("{total}", String(slides.length));
2384
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col gap-3 p-4", children: [
2385
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SlideDispatch, { slide, labels, meta }),
2386
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
2453
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-col gap-3 p-4", children: [
2454
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SlideDispatch, { slide, labels, meta }),
2455
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
2387
2456
  "div",
2388
2457
  {
2389
2458
  className: `flex items-center justify-between border-t pt-2 ${onDark ? "border-white/20" : "border-brown-alpha-12"}`,
2390
2459
  children: [
2391
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2460
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2392
2461
  IconButton,
2393
2462
  {
2394
2463
  icon: IconChevronLeft,
@@ -2399,8 +2468,8 @@ function DeckArtifactContent({
2399
2468
  onClick: () => goTo(current - 1)
2400
2469
  }
2401
2470
  ),
2402
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: `text-xs font-medium ${onDark ? "text-white/70" : "text-brown-70"}`, children: position }),
2403
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2471
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: `text-xs font-medium ${onDark ? "text-white/70" : "text-brown-70"}`, children: position }),
2472
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2404
2473
  IconButton,
2405
2474
  {
2406
2475
  icon: IconChevronRight,
@@ -2420,16 +2489,16 @@ function SlideDispatch({ slide, labels, meta }) {
2420
2489
  const kind = slide.kind ?? deckSlideKinds.CONTENT;
2421
2490
  switch (kind) {
2422
2491
  case deckSlideKinds.TITLE:
2423
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(TitleSlide, { slide, meta });
2492
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(TitleSlide, { slide, meta });
2424
2493
  case deckSlideKinds.AGENDA:
2425
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(AgendaSlide, { slide, meta, labels });
2494
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(AgendaSlide, { slide, meta, labels });
2426
2495
  case deckSlideKinds.SECTION:
2427
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SectionSlide, { slide, meta });
2496
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SectionSlide, { slide, meta });
2428
2497
  case deckSlideKinds.CLOSING:
2429
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ClosingSlide, { meta, labels });
2498
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ClosingSlide, { meta, labels });
2430
2499
  case deckSlideKinds.CONTENT:
2431
2500
  default:
2432
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ContentSlide, { slide, meta, labels });
2501
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ContentSlide, { slide, meta, labels });
2433
2502
  }
2434
2503
  }
2435
2504
  function isVisualBlock(block) {
@@ -2442,25 +2511,25 @@ function ContentSlide({ slide, meta, labels }) {
2442
2511
  (b) => b.type === deckBlockTypes.TEXT
2443
2512
  );
2444
2513
  if (visuals.length === 1 && texts.length > 0) {
2445
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SlideFrame, { meta, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex h-full items-stretch gap-12 px-16 py-12", children: [
2446
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex w-[42%] shrink-0 flex-col overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(AutoFit, { children: [
2447
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h3", { className: "mb-5 font-bold leading-tight text-foreground", style: { fontSize: 34 }, children: slide.title }),
2448
- texts.map((block, i) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(DeckMarkdown, { markdown: block.markdown }, i))
2514
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SlideFrame, { meta, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex h-full items-stretch gap-12 px-16 py-12", children: [
2515
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex w-[42%] shrink-0 flex-col overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(AutoFit, { children: [
2516
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("h3", { className: "mb-5 font-bold leading-tight text-foreground", style: { fontSize: 34 }, children: slide.title }),
2517
+ texts.map((block, i) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DeckMarkdown, { markdown: block.markdown }, i))
2449
2518
  ] }) }),
2450
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "min-h-0 min-w-0 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(FillVisual, { block: visuals[0], labels }) })
2519
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "min-h-0 min-w-0 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(FillVisual, { block: visuals[0], labels }) })
2451
2520
  ] }) });
2452
2521
  }
2453
2522
  if (visuals.length > 0) {
2454
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SlideFrame, { meta, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex h-full flex-col gap-5 px-16 py-10", children: [
2455
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h3", { className: "shrink-0 font-bold leading-tight text-foreground", style: { fontSize: 32 }, children: slide.title }),
2523
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SlideFrame, { meta, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex h-full flex-col gap-5 px-16 py-10", children: [
2524
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("h3", { className: "shrink-0 font-bold leading-tight text-foreground", style: { fontSize: 32 }, children: slide.title }),
2456
2525
  content.map(
2457
- (block, i) => isVisualBlock(block) ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "min-h-0 min-w-0 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(FillVisual, { block, labels }) }, i) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "shrink-0 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(DeckMarkdown, { markdown: block.markdown }) }, i)
2526
+ (block, i) => isVisualBlock(block) ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "min-h-0 min-w-0 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(FillVisual, { block, labels }) }, i) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "shrink-0 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DeckMarkdown, { markdown: block.markdown }) }, i)
2458
2527
  )
2459
2528
  ] }) });
2460
2529
  }
2461
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SlideFrame, { meta, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "h-full px-24 py-12", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(AutoFit, { children: [
2462
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h3", { className: "mb-6 font-bold leading-tight text-foreground", style: { fontSize: 38 }, children: slide.title }),
2463
- texts.map((block, i) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(DeckMarkdown, { markdown: block.markdown }, i))
2530
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SlideFrame, { meta, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "h-full px-24 py-12", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(AutoFit, { children: [
2531
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("h3", { className: "mb-6 font-bold leading-tight text-foreground", style: { fontSize: 38 }, children: slide.title }),
2532
+ texts.map((block, i) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DeckMarkdown, { markdown: block.markdown }, i))
2464
2533
  ] }) }) });
2465
2534
  }
2466
2535
  function AutoFit({ children }) {
@@ -2484,7 +2553,7 @@ function AutoFit({ children }) {
2484
2553
  return () => ro.disconnect();
2485
2554
  }, []);
2486
2555
  const scaled = fit.scale < 1;
2487
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { ref: boxRef, className: "flex h-full min-h-0 w-full flex-col justify-center overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: scaled ? { height: fit.height } : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2556
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { ref: boxRef, className: "flex h-full min-h-0 w-full flex-col justify-center overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { style: scaled ? { height: fit.height } : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2488
2557
  "div",
2489
2558
  {
2490
2559
  ref: contentRef,
@@ -2509,12 +2578,12 @@ function FillVisual({ block, labels }) {
2509
2578
  return () => ro.disconnect();
2510
2579
  }, []);
2511
2580
  const chartLabels = labels.chart ?? DEFAULT_CHART_ARTIFACT_LABELS;
2512
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { ref, className: "h-full min-h-0 w-full overflow-hidden", children: block.type === deckBlockTypes.CHART ? (
2581
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { ref, className: "h-full min-h-0 w-full overflow-hidden", children: block.type === deckBlockTypes.CHART ? (
2513
2582
  // ChartArtifactContent assumes a non-empty rowset (the standalone ChartArtifact guards
2514
2583
  // `rows.length > 0` upstream); mirror that guard here so an empty inline chart shows the
2515
2584
  // localized empty status instead of a blank chart area.
2516
- block.rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(StatusMessage, { $tone: "info", children: chartLabels.empty }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { height }, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ChartArtifactContent, { config: block.config, rows: block.rows, labels: chartLabels }) })
2517
- ) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2585
+ block.rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(StatusMessage, { $tone: "info", children: chartLabels.empty }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { style: { height }, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ChartArtifactContent, { config: block.config, rows: block.rows, labels: chartLabels }) })
2586
+ ) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2518
2587
  TableArtifactContent,
2519
2588
  {
2520
2589
  columns: block.config.columns,
@@ -2580,7 +2649,7 @@ function isValidDeckBlock(block) {
2580
2649
  }
2581
2650
 
2582
2651
  // src/components/artifacts/deck-artifact/deck-artifact.tsx
2583
- var import_jsx_runtime25 = require("react/jsx-runtime");
2652
+ var import_jsx_runtime27 = require("react/jsx-runtime");
2584
2653
  var TITLE_CLASSES2 = "text-sm font-semibold text-foreground";
2585
2654
  function DeckArtifact({ artifact, labels, callbacks }) {
2586
2655
  const validConfig = isValidDeckConfig(artifact.config);
@@ -2621,9 +2690,9 @@ function DeckArtifact({ artifact, labels, callbacks }) {
2621
2690
  const meta = artifact.config?.meta;
2622
2691
  const handleOpenFullscreen = () => setIsFullscreen(true);
2623
2692
  const handleCloseFullscreen = () => setIsFullscreen(false);
2624
- const actions = /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(ArtifactActions, { ...{ [CAPTURE_EXCLUDE_ATTRIBUTE]: "" }, children: [
2625
- showDownload ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ArtifactDownloadButton, { href: presignedUrl ?? "", label: resolvedLabels.download, onClick: handleDownload }) : null,
2626
- validConfig ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2693
+ const actions = /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(ArtifactActions, { ...{ [CAPTURE_EXCLUDE_ATTRIBUTE]: "" }, children: [
2694
+ showDownload ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ArtifactDownloadButton, { href: presignedUrl ?? "", label: resolvedLabels.download, onClick: handleDownload }) : null,
2695
+ validConfig ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
2627
2696
  IconButton,
2628
2697
  {
2629
2698
  icon: IconArrowsMaximize,
@@ -2633,22 +2702,29 @@ function DeckArtifact({ artifact, labels, callbacks }) {
2633
2702
  }
2634
2703
  ) : null
2635
2704
  ] });
2705
+ const heading = /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center gap-2", children: [
2706
+ artifact.title ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ArtifactTitle, { className: TITLE_CLASSES2, children: artifact.title }) : null,
2707
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(Badge, { tone: "violet", variant: "subtle", size: "sm", className: "gap-1 py-1", children: [
2708
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Icon, { icon: IconFlask2Filled, size: 12 }),
2709
+ "Labs"
2710
+ ] })
2711
+ ] });
2636
2712
  if (!validConfig) {
2637
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
2638
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(ArtifactHeader, { className: "bg-background/70", children: [
2639
- artifact.title ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ArtifactTitle, { className: TITLE_CLASSES2, children: artifact.title }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", {}),
2713
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
2714
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(ArtifactHeader, { className: "bg-background/70", children: [
2715
+ heading,
2640
2716
  actions
2641
2717
  ] }),
2642
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ArtifactContent, { className: "p-0", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(StatusMessage, { $tone: "info", children: resolvedLabels.unavailable }) })
2718
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ArtifactContent, { className: "p-0", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(StatusMessage, { $tone: "info", children: resolvedLabels.unavailable }) })
2643
2719
  ] });
2644
2720
  }
2645
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
2646
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
2647
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(ArtifactHeader, { className: "bg-background/70", children: [
2648
- artifact.title ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ArtifactTitle, { className: TITLE_CLASSES2, children: artifact.title }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", {}),
2721
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
2722
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
2723
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(ArtifactHeader, { className: "bg-background/70", children: [
2724
+ heading,
2649
2725
  actions
2650
2726
  ] }),
2651
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ArtifactContent, { className: "p-0", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2727
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ArtifactContent, { className: "p-0", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
2652
2728
  DeckArtifactContent,
2653
2729
  {
2654
2730
  slides: artifact.config.slides,
@@ -2661,7 +2737,7 @@ function DeckArtifact({ artifact, labels, callbacks }) {
2661
2737
  ) })
2662
2738
  ] }),
2663
2739
  isFullscreen && (0, import_react_dom.createPortal)(
2664
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2740
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
2665
2741
  FullscreenOverlay,
2666
2742
  {
2667
2743
  artifact,
@@ -2685,15 +2761,15 @@ function FullscreenOverlay({
2685
2761
  onClose
2686
2762
  }) {
2687
2763
  const meta = artifact.config?.meta;
2688
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2764
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
2689
2765
  "div",
2690
2766
  {
2691
2767
  className: "fixed inset-0 z-[2147483647] flex items-center justify-center bg-black/80",
2692
2768
  role: "dialog",
2693
2769
  "aria-modal": "true",
2694
2770
  "aria-label": resolvedLabels.exitFullscreen,
2695
- children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "relative", style: { width: "min(94vw, calc(82vh * 16 / 9))" }, children: [
2696
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2771
+ children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "relative", style: { width: "min(94vw, calc(82vh * 16 / 9))" }, children: [
2772
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
2697
2773
  DeckArtifactContent,
2698
2774
  {
2699
2775
  slides: artifact.config.slides,
@@ -2705,15 +2781,15 @@ function FullscreenOverlay({
2705
2781
  onDark: true
2706
2782
  }
2707
2783
  ),
2708
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
2784
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
2709
2785
  "button",
2710
2786
  {
2711
2787
  className: "absolute -top-10 right-6 flex items-center gap-1.5 text-sm text-white/80 hover:text-white",
2712
2788
  "aria-label": resolvedLabels.exitFullscreen,
2713
2789
  onClick: onClose,
2714
2790
  children: [
2715
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(IconArrowsMinimize, { size: 16 }),
2716
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: resolvedLabels.exitFullscreen })
2791
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(IconArrowsMinimize, { size: 16 }),
2792
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { children: resolvedLabels.exitFullscreen })
2717
2793
  ]
2718
2794
  }
2719
2795
  )
@@ -2790,7 +2866,7 @@ function useTableArtifactData(presignedUrl, columns) {
2790
2866
  }
2791
2867
 
2792
2868
  // src/components/artifacts/table-artifact/table-artifact.tsx
2793
- var import_jsx_runtime26 = require("react/jsx-runtime");
2869
+ var import_jsx_runtime28 = require("react/jsx-runtime");
2794
2870
  var TITLE_CLASSES3 = "text-sm font-semibold text-foreground";
2795
2871
  var TABLE_MAX_BODY_HEIGHT = 480;
2796
2872
  var MAX_SHIMMER_ROWS = 10;
@@ -2813,10 +2889,10 @@ function TableArtifact({ artifact, labels, callbacks }) {
2813
2889
  const onDownload = callbacks?.onDownload;
2814
2890
  const handleDownloadClick = onDownload ? () => onDownload(artifact) : void 0;
2815
2891
  if (!validConfig || !validColumns) {
2816
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
2817
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(ArtifactHeader, { className: "bg-background/70", children: [
2818
- artifact.title ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ArtifactTitle, { className: TITLE_CLASSES3, children: artifact.title }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", {}),
2819
- presignedUrl ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ArtifactActions, { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2892
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
2893
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(ArtifactHeader, { className: "bg-background/70", children: [
2894
+ artifact.title ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ArtifactTitle, { className: TITLE_CLASSES3, children: artifact.title }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", {}),
2895
+ presignedUrl ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ArtifactActions, { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2820
2896
  ArtifactDownloadButton,
2821
2897
  {
2822
2898
  href: presignedUrl,
@@ -2825,17 +2901,17 @@ function TableArtifact({ artifact, labels, callbacks }) {
2825
2901
  }
2826
2902
  ) }) : null
2827
2903
  ] }),
2828
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ArtifactContent, { className: "p-0 overflow-auto", style: { maxHeight: TABLE_MAX_BODY_HEIGHT }, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(StatusMessage, { $tone: "info", children: resolvedLabels.unavailable }) })
2904
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ArtifactContent, { className: "p-0 overflow-auto", style: { maxHeight: TABLE_MAX_BODY_HEIGHT }, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(StatusMessage, { $tone: "info", children: resolvedLabels.unavailable }) })
2829
2905
  ] });
2830
2906
  }
2831
2907
  return (
2832
2908
  // The table body owns its own scroll container (`ArtifactTable` inside `TableArtifactContent`).
2833
2909
  // Disable the outer overflow container so only one scroll context exists — this prevents
2834
2910
  // double-scroll nesting and lets `useScrollShadow` find the correct scroll ancestor.
2835
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
2836
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(ArtifactHeader, { className: "bg-background/70", children: [
2837
- artifact.title ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ArtifactTitle, { className: TITLE_CLASSES3, children: artifact.title }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", {}),
2838
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ArtifactActions, { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2911
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(Artifact, { className: "shadow-none w-full rounded-2xl bg-background/70", children: [
2912
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(ArtifactHeader, { className: "bg-background/70", children: [
2913
+ artifact.title ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ArtifactTitle, { className: TITLE_CLASSES3, children: artifact.title }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", {}),
2914
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ArtifactActions, { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2839
2915
  ArtifactDownloadButton,
2840
2916
  {
2841
2917
  href: presignedUrl ?? "",
@@ -2844,7 +2920,7 @@ function TableArtifact({ artifact, labels, callbacks }) {
2844
2920
  }
2845
2921
  ) })
2846
2922
  ] }),
2847
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ArtifactContent, { className: "p-0 overflow-visible", style: { maxHeight: "none" }, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2923
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ArtifactContent, { className: "p-0 overflow-visible", style: { maxHeight: "none" }, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2848
2924
  TableArtifactContent,
2849
2925
  {
2850
2926
  columns: validColumns,
@@ -2887,13 +2963,13 @@ function artifactToClipboardText(artifact) {
2887
2963
  }
2888
2964
 
2889
2965
  // src/components/blocks/artifact-ref-block/artifact-ref-block.tsx
2890
- var import_jsx_runtime27 = require("react/jsx-runtime");
2966
+ var import_jsx_runtime29 = require("react/jsx-runtime");
2891
2967
  function ArtifactRefBlock({ block }) {
2892
2968
  const { artifact, labels, callbacks } = block.payload;
2893
2969
  const entry = ArtifactServices[artifact.type];
2894
2970
  if (!entry) return null;
2895
2971
  const Component = entry.Component;
2896
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Component, { artifact, labels, callbacks });
2972
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Component, { artifact, labels, callbacks });
2897
2973
  }
2898
2974
 
2899
2975
  // src/components/blocks/block-services/artifact-ref-block-service.ts
@@ -2908,26 +2984,66 @@ var ArtifactRefBlockService = {
2908
2984
  toClipboardText: (block) => artifactToClipboardText(block.payload.artifact)
2909
2985
  };
2910
2986
 
2911
- // src/utils/markdown-to-plain-text.ts
2912
- var PLACEHOLDER_PREFIX = "\u200B\u200BIC";
2913
- var PLACEHOLDER_SUFFIX = "\u200B\u200B";
2914
- var PLACEHOLDER_REGEX = new RegExp(`${PLACEHOLDER_PREFIX}(\\d+)${PLACEHOLDER_SUFFIX}`, "g");
2915
- function stripInlineMarks(text) {
2916
- return text.replace(/\*{3}(.+?)\*{3}/g, "$1").replace(/\*{2}(.+?)\*{2}/g, "$1").replace(/_{2}(.+?)_{2}/g, "$1").replace(/\*(.+?)\*/g, "$1").replace(/_(.+?)_/g, "$1").replace(/~~(.+?)~~/g, "$1");
2987
+ // src/components/blocks/notification-draft-block/notification-draft-block.tsx
2988
+ var import_react20 = require("react");
2989
+
2990
+ // src/components/chat/hooks/use-copy-to-clipboard.ts
2991
+ var import_react19 = require("react");
2992
+
2993
+ // src/utils/clipboard.ts
2994
+ function copyToClipboard(text, options) {
2995
+ navigator.clipboard.writeText(text).then(
2996
+ () => options?.onSuccess?.(),
2997
+ (error) => options?.onFailure?.(error)
2998
+ );
2917
2999
  }
2918
- function markdownToPlainText(markdown) {
2919
- if (!markdown) return "";
2920
- const inlineCodeSnippets = [];
2921
- let result = markdown.replace(/^<!--[\s\S]*?--!?>\n?/gm, "").replace(/```[\s\S]*?```/g, "").replace(/`([^`]+)`/g, (_match, code) => {
2922
- inlineCodeSnippets.push(code);
2923
- return `${PLACEHOLDER_PREFIX}${inlineCodeSnippets.length - 1}${PLACEHOLDER_SUFFIX}`;
2924
- }).replace(/^#{1,6}\s+/gm, "").replace(/^(?:---|\*\*\*|___)\s*$/gm, "");
2925
- result = stripInlineMarks(result).replace(/!\[([^\]]*)\]\([^)]+\)/g, "$1").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/^>\s?/gm, "").replace(/^\|[-:\s|]+\|\s*$/gm, "").replace(/^\|\s?/gm, "").replace(/\s?\|$/gm, "").replace(/\n{3,}/g, "\n\n").trim();
2926
- result = result.replace(PLACEHOLDER_REGEX, (_match, index) => inlineCodeSnippets[Number(index)]);
2927
- return result;
3000
+
3001
+ // src/components/chat/hooks/use-copy-to-clipboard.ts
3002
+ var RESET_DELAY_MS = 2e3;
3003
+ function useCopyToClipboard() {
3004
+ const [isCopied, setIsCopied] = (0, import_react19.useState)(false);
3005
+ const timeoutRef = (0, import_react19.useRef)(null);
3006
+ (0, import_react19.useEffect)(() => {
3007
+ return () => {
3008
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
3009
+ };
3010
+ }, []);
3011
+ const copy = (0, import_react19.useCallback)((text) => {
3012
+ copyToClipboard(text, {
3013
+ onSuccess: () => {
3014
+ setIsCopied(true);
3015
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
3016
+ timeoutRef.current = setTimeout(() => {
3017
+ setIsCopied(false);
3018
+ timeoutRef.current = null;
3019
+ }, RESET_DELAY_MS);
3020
+ }
3021
+ });
3022
+ }, []);
3023
+ return { isCopied, copy };
2928
3024
  }
2929
3025
 
2930
- // src/components/blocks/text-block/text-block.tsx
3026
+ // src/components/copy-button/copy-button.tsx
3027
+ var import_jsx_runtime30 = require("react/jsx-runtime");
3028
+ function CopyButton({
3029
+ text,
3030
+ copyLabel = "Copy",
3031
+ copiedLabel = "Copied",
3032
+ className
3033
+ }) {
3034
+ const { isCopied, copy } = useCopyToClipboard();
3035
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
3036
+ IconButton,
3037
+ {
3038
+ icon: isCopied ? IconCheck : IconCopy,
3039
+ onClick: () => copy(text),
3040
+ "aria-label": isCopied ? copiedLabel : copyLabel,
3041
+ className
3042
+ }
3043
+ );
3044
+ }
3045
+
3046
+ // src/components/blocks/markdown/markdown.tsx
2931
3047
  var import_react_markdown2 = __toESM(require("react-markdown"), 1);
2932
3048
  var import_remark_breaks2 = __toESM(require("remark-breaks"), 1);
2933
3049
  var import_remark_gfm2 = __toESM(require("remark-gfm"), 1);
@@ -2945,9 +3061,9 @@ var TableScroll = import_styled_components3.default.div`
2945
3061
  `;
2946
3062
 
2947
3063
  // src/components/blocks/scrollable-table/scrollable-table.tsx
2948
- var import_jsx_runtime28 = require("react/jsx-runtime");
3064
+ var import_jsx_runtime31 = require("react/jsx-runtime");
2949
3065
  function ScrollableTable({ node: _node, ...props }) {
2950
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(TableContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(TableScroll, { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("table", { ...props }) }) });
3066
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(TableContainer, { children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(TableScroll, { children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("table", { ...props }) }) });
2951
3067
  }
2952
3068
 
2953
3069
  // src/components/blocks/text-block/sanitize.ts
@@ -3090,13 +3206,157 @@ var TextBlockWrapper = import_styled_components4.default.div`
3090
3206
  }
3091
3207
  `;
3092
3208
 
3093
- // src/components/blocks/text-block/text-block.tsx
3094
- var import_jsx_runtime29 = require("react/jsx-runtime");
3209
+ // src/components/blocks/markdown/markdown.tsx
3210
+ var import_jsx_runtime32 = require("react/jsx-runtime");
3095
3211
  var markdownComponents = {
3096
- table: ((tableProps) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ScrollableTable, { ...tableProps }))
3212
+ table: ((tableProps) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ScrollableTable, { ...tableProps }))
3213
+ };
3214
+ function Markdown({ children }) {
3215
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(TextBlockWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_react_markdown2.default, { remarkPlugins: [import_remark_gfm2.default, import_remark_breaks2.default], components: markdownComponents, children: sanitize2(children) }) });
3216
+ }
3217
+
3218
+ // src/utils/markdown-to-plain-text.ts
3219
+ var PLACEHOLDER_PREFIX = "\u200B\u200BIC";
3220
+ var PLACEHOLDER_SUFFIX = "\u200B\u200B";
3221
+ var PLACEHOLDER_REGEX = new RegExp(`${PLACEHOLDER_PREFIX}(\\d+)${PLACEHOLDER_SUFFIX}`, "g");
3222
+ function stripInlineMarks(text) {
3223
+ return text.replace(/\*{3}(.+?)\*{3}/g, "$1").replace(/\*{2}(.+?)\*{2}/g, "$1").replace(/_{2}(.+?)_{2}/g, "$1").replace(/\*(.+?)\*/g, "$1").replace(/_(.+?)_/g, "$1").replace(/~~(.+?)~~/g, "$1");
3224
+ }
3225
+ function markdownToPlainText(markdown) {
3226
+ if (!markdown) return "";
3227
+ const inlineCodeSnippets = [];
3228
+ let result = markdown.replace(/^<!--[\s\S]*?--!?>\n?/gm, "").replace(/```[\s\S]*?```/g, "").replace(/`([^`]+)`/g, (_match, code) => {
3229
+ inlineCodeSnippets.push(code);
3230
+ return `${PLACEHOLDER_PREFIX}${inlineCodeSnippets.length - 1}${PLACEHOLDER_SUFFIX}`;
3231
+ }).replace(/^#{1,6}\s+/gm, "").replace(/^(?:---|\*\*\*|___)\s*$/gm, "");
3232
+ result = stripInlineMarks(result).replace(/!\[([^\]]*)\]\([^)]+\)/g, "$1").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/^>\s?/gm, "").replace(/^\|[-:\s|]+\|\s*$/gm, "").replace(/^\|\s?/gm, "").replace(/\s?\|$/gm, "").replace(/\n{3,}/g, "\n\n").trim();
3233
+ result = result.replace(PLACEHOLDER_REGEX, (_match, index) => inlineCodeSnippets[Number(index)]);
3234
+ return result;
3235
+ }
3236
+
3237
+ // src/components/blocks/notification-draft-block/types.ts
3238
+ var notificationChannels = {
3239
+ /** Branded email — renders a From/subject header. */
3240
+ EMAIL: "email",
3241
+ /** Slack DM — renders as a chat bubble, no subject. */
3242
+ SLACK: "slack",
3243
+ /** Microsoft Teams DM — renders as a chat bubble, no subject. */
3244
+ TEAMS: "teams"
3245
+ };
3246
+ var notificationEmailTypes = {
3247
+ /** Recipient's work email. */
3248
+ WORK: "work",
3249
+ /** Recipient's personal email. */
3250
+ PERSONAL: "personal"
3251
+ };
3252
+
3253
+ // src/components/blocks/notification-draft-block/to-text.ts
3254
+ function notificationDraftToText(payload) {
3255
+ const { channel, subject, body } = payload;
3256
+ const text = markdownToPlainText(body);
3257
+ return channel === notificationChannels.EMAIL && subject ? `${subject}
3258
+
3259
+ ${text}` : text;
3260
+ }
3261
+
3262
+ // src/components/blocks/notification-draft-block/notification-draft-block.tsx
3263
+ var import_jsx_runtime33 = require("react/jsx-runtime");
3264
+ var CHIP_LIMIT = 3;
3265
+ var RECIPIENTS_MAX_HEIGHT = 320;
3266
+ function chipLabel(recipient) {
3267
+ return recipient.name ?? recipient.email ?? recipient.employeeId;
3268
+ }
3269
+ function channelCellText(recipient) {
3270
+ return recipient.fallback ? `${recipient.channelLabel} (fallback)` : recipient.channelLabel;
3271
+ }
3272
+ function FieldLabel({ children }) {
3273
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-geist-label-caption-medium tracking-wide text-brown-60", children });
3274
+ }
3275
+ function RecipientChips({ recipients }) {
3276
+ const shown = recipients.slice(0, CHIP_LIMIT);
3277
+ const overflow = recipients.length - shown.length;
3278
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex flex-wrap items-center gap-1.5", children: [
3279
+ shown.map((recipient) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Badge, { variant: "outline", children: chipLabel(recipient) }, recipient.employeeId)),
3280
+ overflow > 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Badge, { variant: "subtle", children: `+${overflow}` })
3281
+ ] });
3282
+ }
3283
+ function RecipientsTable({ recipients }) {
3284
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
3285
+ DataTable,
3286
+ {
3287
+ maxBodyHeight: RECIPIENTS_MAX_HEIGHT,
3288
+ header: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(TableRow, { className: "hover:bg-transparent", children: [
3289
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TableHead, { scope: "col", className: DATA_TABLE_HEAD_CLASS, children: "Name" }),
3290
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TableHead, { scope: "col", className: DATA_TABLE_HEAD_CLASS, children: "Email" }),
3291
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TableHead, { scope: "col", className: DATA_TABLE_HEAD_CLASS, children: "Channel" })
3292
+ ] }),
3293
+ children: recipients.map((recipient) => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(TableRow, { className: DATA_TABLE_ROW_CLASS, children: [
3294
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TableCell, { className: DATA_TABLE_CELL_CLASS, children: recipient.name ?? "\u2014" }),
3295
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TableCell, { className: DATA_TABLE_CELL_CLASS, children: recipient.email ?? "\u2014" }),
3296
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TableCell, { className: DATA_TABLE_CELL_CLASS, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Badge, { tone: recipient.fallback ? "warning" : "neutral", variant: "subtle", children: channelCellText(recipient) }) })
3297
+ ] }, recipient.employeeId))
3298
+ }
3299
+ );
3300
+ }
3301
+ function NotificationDraftBlock({ block }) {
3302
+ const { channel, subject, body, recipients } = block.payload;
3303
+ const [detailsOpen, setDetailsOpen] = (0, import_react20.useState)(false);
3304
+ const showSubject = channel === notificationChannels.EMAIL && subject;
3305
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "overflow-hidden rounded-2xl border border-brown-30 bg-white", children: [
3306
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex flex-col gap-3 border-b border-brown-30 px-4 py-3", children: [
3307
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
3308
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex items-center gap-2", children: [
3309
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-geist-body-s-semi-bold text-brown-100", children: "Notification draft" }),
3310
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(Badge, { tone: "violet", variant: "subtle", size: "sm", className: "gap-1 py-1", children: [
3311
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Icon, { icon: IconFlask2Filled, size: 12 }),
3312
+ "Labs"
3313
+ ] })
3314
+ ] }),
3315
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(CopyButton, { text: notificationDraftToText(block.payload), copyLabel: "Copy draft", copiedLabel: "Copied" })
3316
+ ] }),
3317
+ showSubject && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex flex-col gap-0.5", children: [
3318
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(FieldLabel, { children: "Title" }),
3319
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("p", { className: "text-geist-body-s-medium text-brown-100", children: subject })
3320
+ ] }),
3321
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex flex-col gap-1", children: [
3322
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
3323
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(FieldLabel, { children: `Recipients (${recipients.length})` }),
3324
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
3325
+ "button",
3326
+ {
3327
+ type: "button",
3328
+ "aria-expanded": detailsOpen,
3329
+ onClick: () => setDetailsOpen((open) => !open),
3330
+ className: "inline-flex items-center gap-1 text-geist-label-caption-medium text-brown-70 transition-colors hover:text-brown-100",
3331
+ children: [
3332
+ "Details",
3333
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Icon, { icon: IconChevronDown, size: 14, className: detailsOpen ? "rotate-180" : void 0 })
3334
+ ]
3335
+ }
3336
+ )
3337
+ ] }),
3338
+ detailsOpen ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(RecipientsTable, { recipients }) : /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(RecipientChips, { recipients })
3339
+ ] })
3340
+ ] }),
3341
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Markdown, { children: body }) })
3342
+ ] });
3343
+ }
3344
+
3345
+ // src/components/blocks/block-services/notification-draft-block-service.ts
3346
+ var NotificationDraftBlockService = {
3347
+ type: blockTypes.NOTIFICATION_DRAFT,
3348
+ Component: NotificationDraftBlock,
3349
+ /**
3350
+ * Plain-text clipboard form of the drafted notification — shared with the in-block copy button
3351
+ * via {@link notificationDraftToText} so both copy the same text.
3352
+ */
3353
+ toClipboardText: (block) => notificationDraftToText(block.payload)
3097
3354
  };
3355
+
3356
+ // src/components/blocks/text-block/text-block.tsx
3357
+ var import_jsx_runtime34 = require("react/jsx-runtime");
3098
3358
  function TextBlock({ block }) {
3099
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TextBlockWrapper, { children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_markdown2.default, { remarkPlugins: [import_remark_gfm2.default, import_remark_breaks2.default], components: markdownComponents, children: sanitize2(block.payload.text) }) });
3359
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Markdown, { children: block.payload.text });
3100
3360
  }
3101
3361
 
3102
3362
  // src/components/blocks/block-services/text-block-service.ts
@@ -3114,23 +3374,24 @@ var TextBlockService = {
3114
3374
  // src/components/blocks/block-services/index.ts
3115
3375
  var BlockServices = {
3116
3376
  [blockTypes.TEXT]: TextBlockService,
3117
- [blockTypes.ARTIFACT_REF]: ArtifactRefBlockService
3377
+ [blockTypes.ARTIFACT_REF]: ArtifactRefBlockService,
3378
+ [blockTypes.NOTIFICATION_DRAFT]: NotificationDraftBlockService
3118
3379
  };
3119
3380
 
3120
3381
  // src/components/blocks/block/block.tsx
3121
- var import_jsx_runtime30 = require("react/jsx-runtime");
3382
+ var import_jsx_runtime35 = require("react/jsx-runtime");
3122
3383
  function Block({ block }) {
3123
3384
  const service = BlockServices[block.type];
3124
3385
  if (!service) return null;
3125
3386
  const { Component } = service;
3126
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Component, { block });
3387
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(Component, { block });
3127
3388
  }
3128
3389
 
3129
3390
  // src/components/blocks/block-context/block-context.tsx
3130
- var import_react19 = require("react");
3131
- var BlockContext = (0, import_react19.createContext)(null);
3391
+ var import_react21 = require("react");
3392
+ var BlockContext = (0, import_react21.createContext)(null);
3132
3393
  function useBlockContext() {
3133
- return (0, import_react19.useContext)(BlockContext) ?? {};
3394
+ return (0, import_react21.useContext)(BlockContext) ?? {};
3134
3395
  }
3135
3396
  // Annotate the CommonJS export names for ESM import in node:
3136
3397
  0 && (module.exports = {
@@ -3139,8 +3400,12 @@ function useBlockContext() {
3139
3400
  Block,
3140
3401
  BlockContext,
3141
3402
  BlockServices,
3403
+ NotificationDraftBlock,
3404
+ NotificationDraftBlockService,
3142
3405
  TextBlockService,
3143
3406
  blockTypes,
3407
+ notificationChannels,
3408
+ notificationEmailTypes,
3144
3409
  useBlockContext
3145
3410
  });
3146
3411
  /*! Bundled license information:
@@ -3151,6 +3416,7 @@ function useBlockContext() {
3151
3416
  @tabler/icons-react/dist/esm/icons/IconArrowsMaximize.mjs:
3152
3417
  @tabler/icons-react/dist/esm/icons/IconArrowsMinimize.mjs:
3153
3418
  @tabler/icons-react/dist/esm/icons/IconCheck.mjs:
3419
+ @tabler/icons-react/dist/esm/icons/IconChevronDown.mjs:
3154
3420
  @tabler/icons-react/dist/esm/icons/IconChevronLeft.mjs:
3155
3421
  @tabler/icons-react/dist/esm/icons/IconChevronRight.mjs:
3156
3422
  @tabler/icons-react/dist/esm/icons/IconCopy.mjs:
@@ -3158,6 +3424,7 @@ function useBlockContext() {
3158
3424
  @tabler/icons-react/dist/esm/icons/IconFileSpreadsheet.mjs:
3159
3425
  @tabler/icons-react/dist/esm/icons/IconLoader2.mjs:
3160
3426
  @tabler/icons-react/dist/esm/icons/IconPhoto.mjs:
3427
+ @tabler/icons-react/dist/esm/icons/IconFlask2Filled.mjs:
3161
3428
  @tabler/icons-react/dist/esm/tabler-icons-react.mjs:
3162
3429
  (**
3163
3430
  * @license @tabler/icons-react v3.37.1 - MIT