composeai 0.1.3 → 0.1.4

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
@@ -795,11 +795,11 @@ function EditorShell({
795
795
  }) {
796
796
  const { classNames, sx, dir } = useComposerContext();
797
797
  const isMarkdown = mode === "markdown";
798
- const editorClass = multiline ? "composer-editor min-h-[44px] max-h-56 scrollbar-thin overflow-y-auto px-5 py-3.5" : "composer-editor composer-editor--inline h-9 overflow-x-auto overflow-y-hidden whitespace-nowrap px-2 leading-9";
798
+ const editorClass = multiline ? "composer-editor composer-editor--multiline" : "composer-editor composer-editor--inline";
799
799
  const editor = slotProps("editor", editorClass, classNames, sx);
800
800
  const editorResolved = resolveSx(sx?.editor);
801
801
  const placeholderBase = mirrorEditorPadding(editorResolved);
802
- const placeholderClass = multiline ? "composer-placeholder pointer-events-none absolute inset-x-0 top-0 select-none px-5 py-3.5 text-[15px] leading-relaxed text-muted-foreground" : "composer-placeholder pointer-events-none absolute inset-y-0 inset-x-0 select-none px-2 text-[15px] leading-9 text-muted-foreground truncate";
802
+ const placeholderClass = multiline ? "composer-placeholder composer-placeholder--multiline" : "composer-placeholder composer-placeholder--inline";
803
803
  const placeholderProps = slotProps(
804
804
  "placeholder",
805
805
  placeholderClass,
@@ -813,9 +813,9 @@ function EditorShell({
813
813
  "div",
814
814
  {
815
815
  className: cn(
816
- "composer-editor-block relative min-w-0",
816
+ "composer-editor-block",
817
817
  // Inline: the editor block is the flex child that fills the row.
818
- !multiline && "flex-1"
818
+ !multiline && "composer-editor-block--inline"
819
819
  ),
820
820
  children: isMarkdown ? /* @__PURE__ */ jsx(
821
821
  RichTextPlugin,
@@ -837,10 +837,10 @@ function EditorShell({
837
837
  if (!multiline) {
838
838
  return /* @__PURE__ */ jsxs(Fragment, { children: [
839
839
  header,
840
- /* @__PURE__ */ jsxs("div", { className: "composer-inline-row flex items-center gap-1 px-2 py-1.5", children: [
841
- toolbar && /* @__PURE__ */ jsx("div", { className: "composer-inline-toolbar flex shrink-0 items-center", children: toolbar }),
840
+ /* @__PURE__ */ jsxs("div", { className: "composer-inline-row", children: [
841
+ toolbar && /* @__PURE__ */ jsx("div", { className: "composer-inline-toolbar", children: toolbar }),
842
842
  editorBlock,
843
- sendButton && /* @__PURE__ */ jsx("div", { className: "composer-inline-send flex shrink-0 items-center", children: sendButton })
843
+ sendButton && /* @__PURE__ */ jsx("div", { className: "composer-inline-send", children: sendButton })
844
844
  ] }),
845
845
  /* @__PURE__ */ jsx(HistoryPlugin, {})
846
846
  ] });
@@ -848,7 +848,7 @@ function EditorShell({
848
848
  return /* @__PURE__ */ jsxs(Fragment, { children: [
849
849
  header,
850
850
  editorBlock,
851
- (toolbar || sendButton) && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-3 pb-2.5", children: [
851
+ (toolbar || sendButton) && /* @__PURE__ */ jsxs("div", { className: "composer-toolbar-row", children: [
852
852
  toolbar ?? /* @__PURE__ */ jsx("span", {}),
853
853
  sendButton
854
854
  ] }),
@@ -2342,14 +2342,15 @@ function ImageLightbox({ src, alt, onClose }) {
2342
2342
  {
2343
2343
  role: "dialog",
2344
2344
  "aria-modal": "true",
2345
- className: "fixed inset-0 z-50 flex items-center justify-center p-6",
2345
+ "data-composer-scope": "",
2346
+ className: "composer-lightbox",
2346
2347
  style: tokenStyle,
2347
2348
  children: [
2348
2349
  /* @__PURE__ */ jsx(
2349
2350
  "div",
2350
2351
  {
2351
2352
  "aria-hidden": true,
2352
- className: "absolute inset-0 bg-foreground/70 backdrop-blur-sm",
2353
+ className: "composer-lightbox-backdrop",
2353
2354
  onClick: onClose
2354
2355
  }
2355
2356
  ),
@@ -2359,18 +2360,11 @@ function ImageLightbox({ src, alt, onClose }) {
2359
2360
  type: "button",
2360
2361
  onClick: onClose,
2361
2362
  "aria-label": "Close",
2362
- className: "absolute end-5 top-5 flex h-9 w-9 items-center justify-center rounded-full bg-card text-foreground shadow-soft transition-colors hover:bg-accent",
2363
- children: /* @__PURE__ */ jsx(CloseIcon, { className: "h-4 w-4" })
2363
+ className: "composer-lightbox-close",
2364
+ children: /* @__PURE__ */ jsx(CloseIcon, {})
2364
2365
  }
2365
2366
  ),
2366
- /* @__PURE__ */ jsx(
2367
- "img",
2368
- {
2369
- src,
2370
- alt,
2371
- className: "relative max-h-[85vh] max-w-[85vw] rounded-lg object-contain shadow-xl"
2372
- }
2373
- )
2367
+ /* @__PURE__ */ jsx("img", { src, alt, className: "composer-lightbox-img" })
2374
2368
  ]
2375
2369
  }
2376
2370
  ) });
@@ -2498,16 +2492,16 @@ function MermaidPlugin() {
2498
2492
  if (diagrams.length === 0) return null;
2499
2493
  const preview = slotProps(
2500
2494
  "mermaidPreview",
2501
- "border-t border-border/60 bg-muted/30 px-4 py-3",
2495
+ "composer-mermaid",
2502
2496
  classNames,
2503
2497
  sx
2504
2498
  );
2505
2499
  return /* @__PURE__ */ jsxs("div", { ...preview, children: [
2506
- /* @__PURE__ */ jsxs("div", { className: "mb-1.5 flex items-center gap-1.5 text-[10px] font-medium uppercase tracking-wide text-muted-foreground", children: [
2507
- /* @__PURE__ */ jsx(SparkleIcon, { className: "h-3 w-3" }),
2500
+ /* @__PURE__ */ jsxs("div", { className: "composer-mermaid-head", children: [
2501
+ /* @__PURE__ */ jsx(SparkleIcon, {}),
2508
2502
  "Diagram preview"
2509
2503
  ] }),
2510
- /* @__PURE__ */ jsx("div", { className: "flex gap-2 overflow-x-auto scrollbar-thin", children: diagrams.map((d) => /* @__PURE__ */ jsx(
2504
+ /* @__PURE__ */ jsx("div", { className: "composer-mermaid-row", children: diagrams.map((d) => /* @__PURE__ */ jsx(
2511
2505
  DiagramTile,
2512
2506
  {
2513
2507
  diagram: d,
@@ -2532,9 +2526,9 @@ function ConsumerTile({
2532
2526
  content = renderDiagram({ code: diagram.code, language: "mermaid" });
2533
2527
  } catch (err) {
2534
2528
  console.error("[composeai] renderDiagram threw", err);
2535
- content = /* @__PURE__ */ jsx("div", { className: "flex h-24 w-40 items-center justify-center px-2 text-center text-[10px] text-destructive", children: err instanceof Error ? err.message.slice(0, 80) : "Render failed" });
2529
+ content = /* @__PURE__ */ jsx("div", { className: "composer-mermaid-msg composer-mermaid-msg--error", children: err instanceof Error ? err.message.slice(0, 80) : "Render failed" });
2536
2530
  }
2537
- return /* @__PURE__ */ jsx("div", { className: "shrink-0 overflow-hidden rounded-lg border border-border bg-card", children: content });
2531
+ return /* @__PURE__ */ jsx("div", { className: "composer-mermaid-tile", children: content });
2538
2532
  }
2539
2533
  function MermaidTile({ diagram }) {
2540
2534
  const { icons } = useComposerContext();
@@ -2581,24 +2575,22 @@ function MermaidTile({ diagram }) {
2581
2575
  type: "button",
2582
2576
  onClick: () => svg && setZoom(true),
2583
2577
  "aria-label": "Zoom diagram",
2584
- className: "group/dia relative shrink-0 overflow-hidden rounded-lg border border-border bg-card transition-colors hover:border-primary/40",
2578
+ className: "composer-mermaid-tile",
2585
2579
  children: svg ? /* @__PURE__ */ jsxs(Fragment, { children: [
2586
2580
  /* @__PURE__ */ jsx(
2587
2581
  "div",
2588
2582
  {
2589
- className: "h-24 w-40 [&_svg]:h-full [&_svg]:w-full",
2583
+ className: "composer-mermaid-svg",
2590
2584
  dangerouslySetInnerHTML: { __html: svg }
2591
2585
  }
2592
2586
  ),
2593
- /* @__PURE__ */ jsx("span", { className: "absolute end-1 top-1 flex h-5 w-5 items-center justify-center rounded-full bg-foreground/70 text-background opacity-0 transition-opacity group-hover/dia:opacity-100", children: /* @__PURE__ */ jsx(ZoomIcon, { className: "h-3 w-3" }) })
2594
- ] }) : mermaidMissing ? /* @__PURE__ */ jsx("div", { className: "grid h-24 w-40 place-items-center px-3 text-center text-[11px] leading-snug text-muted-foreground", children: /* @__PURE__ */ jsxs("span", { children: [
2587
+ /* @__PURE__ */ jsx("span", { className: "composer-mermaid-zoom", children: /* @__PURE__ */ jsx(ZoomIcon, {}) })
2588
+ ] }) : mermaidMissing ? /* @__PURE__ */ jsx("div", { className: "composer-mermaid-msg", children: /* @__PURE__ */ jsxs("span", { children: [
2595
2589
  "Install ",
2596
- /* @__PURE__ */ jsx("code", { className: "rounded bg-muted px-1 font-mono", children: "mermaid" }),
2597
- " ",
2598
- "or pass",
2599
- " ",
2600
- /* @__PURE__ */ jsx("code", { className: "rounded bg-muted px-1 font-mono", children: "renderDiagram" })
2601
- ] }) }) : error ? /* @__PURE__ */ jsx("div", { className: "grid h-24 w-40 place-items-center px-2 text-center text-[10px] leading-snug text-destructive", children: /* @__PURE__ */ jsx("span", { children: error.slice(0, 80) }) }) : /* @__PURE__ */ jsx("div", { className: "grid h-24 w-40 place-items-center text-[10px] text-muted-foreground", children: /* @__PURE__ */ jsx("span", { children: "Rendering\u2026" }) })
2590
+ /* @__PURE__ */ jsx("code", { className: "composer-mermaid-code", children: "mermaid" }),
2591
+ " or pass ",
2592
+ /* @__PURE__ */ jsx("code", { className: "composer-mermaid-code", children: "renderDiagram" })
2593
+ ] }) }) : error ? /* @__PURE__ */ jsx("div", { className: "composer-mermaid-msg composer-mermaid-msg--error", children: /* @__PURE__ */ jsx("span", { children: error.slice(0, 80) }) }) : /* @__PURE__ */ jsx("div", { className: "composer-mermaid-msg", children: /* @__PURE__ */ jsx("span", { children: "Rendering\u2026" }) })
2602
2594
  }
2603
2595
  ),
2604
2596
  zoom && svg && /* @__PURE__ */ jsx(
@@ -2637,7 +2629,7 @@ function SlashMenu({
2637
2629
  );
2638
2630
  const menu = slotProps(
2639
2631
  "slashMenu",
2640
- "z-50 w-72 origin-top animate-slide-up overflow-hidden rounded-xl border border-border bg-popover text-popover-foreground shadow-soft",
2632
+ "composer-menu composer-menu--slash",
2641
2633
  classNames,
2642
2634
  sx
2643
2635
  );
@@ -2651,10 +2643,10 @@ function SlashMenu({
2651
2643
  "aria-label": "Slash commands",
2652
2644
  "aria-busy": isLoading || void 0,
2653
2645
  ...menu,
2654
- children: /* @__PURE__ */ jsxs("ul", { ref: listRef, className: "max-h-72 overflow-y-auto scrollbar-thin py-1", children: [
2646
+ children: /* @__PURE__ */ jsxs("ul", { ref: listRef, className: "composer-menu-list", children: [
2655
2647
  showSkeleton && /* @__PURE__ */ jsx(SlashSkeleton, { rows: 4 }),
2656
2648
  Object.entries(grouped).map(([group, entries]) => /* @__PURE__ */ jsxs("li", { children: [
2657
- /* @__PURE__ */ jsx("div", { className: "px-3 pb-1 pt-2 text-[10px] font-medium uppercase tracking-wide text-muted-foreground", children: group }),
2649
+ /* @__PURE__ */ jsx("div", { className: "composer-menu-group", children: group }),
2658
2650
  /* @__PURE__ */ jsx("ul", { children: entries.map(({ item, index }) => /* @__PURE__ */ jsxs(
2659
2651
  "li",
2660
2652
  {
@@ -2666,19 +2658,15 @@ function SlashMenu({
2666
2658
  onSelect(index);
2667
2659
  },
2668
2660
  onMouseEnter: () => onHover(index),
2669
- className: cn(
2670
- "flex cursor-pointer items-center gap-2.5 px-2.5 py-1.5 text-sm",
2671
- selectedIndex === index ? "bg-accent text-accent-foreground" : "text-foreground",
2672
- classNames?.slashItem
2673
- ),
2661
+ className: cn("composer-menu-item", classNames?.slashItem),
2674
2662
  style: itemStyle,
2675
2663
  children: [
2676
- item.icon && /* @__PURE__ */ jsx("span", { className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-md bg-muted text-muted-foreground", children: item.icon }),
2677
- /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-col leading-tight", children: [
2678
- /* @__PURE__ */ jsx("span", { className: "truncate font-medium", children: item.label }),
2679
- item.description && /* @__PURE__ */ jsx("span", { className: "truncate text-[11px] text-muted-foreground", children: item.description })
2664
+ item.icon && /* @__PURE__ */ jsx("span", { className: "composer-menu-icon", children: item.icon }),
2665
+ /* @__PURE__ */ jsxs("span", { className: "composer-menu-text", children: [
2666
+ /* @__PURE__ */ jsx("span", { className: "composer-menu-label", children: item.label }),
2667
+ item.description && /* @__PURE__ */ jsx("span", { className: "composer-menu-desc", children: item.description })
2680
2668
  ] }),
2681
- item.shortcut && /* @__PURE__ */ jsx("span", { className: "ms-auto rounded border border-border bg-muted px-1.5 py-0.5 font-mono text-[10px] text-muted-foreground", children: item.shortcut })
2669
+ item.shortcut && /* @__PURE__ */ jsx("span", { className: "composer-menu-shortcut", children: item.shortcut })
2682
2670
  ]
2683
2671
  },
2684
2672
  item.id
@@ -2689,35 +2677,28 @@ function SlashMenu({
2689
2677
  );
2690
2678
  }
2691
2679
  function SlashSkeleton({ rows = 4 }) {
2692
- return /* @__PURE__ */ jsxs("li", { "aria-hidden": "true", className: "px-2.5 py-1.5", children: [
2693
- /* @__PURE__ */ jsx("div", { className: "px-0.5 pb-1.5 pt-0.5", children: /* @__PURE__ */ jsx("span", { className: "block h-2 w-16 animate-pulse rounded bg-muted/70" }) }),
2694
- /* @__PURE__ */ jsx("ul", { className: "flex flex-col gap-1", children: Array.from({ length: rows }).map((_, i) => /* @__PURE__ */ jsxs(
2695
- "li",
2696
- {
2697
- className: "flex items-center gap-2.5 rounded-md px-0 py-1.5",
2698
- children: [
2699
- /* @__PURE__ */ jsx("span", { className: "h-7 w-7 shrink-0 animate-pulse rounded-md bg-muted" }),
2700
- /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-1 flex-col gap-1.5", children: [
2701
- /* @__PURE__ */ jsx(
2702
- "span",
2703
- {
2704
- className: "h-2.5 animate-pulse rounded bg-muted",
2705
- style: { width: `${50 + i * 19 % 35}%` }
2706
- }
2707
- ),
2708
- /* @__PURE__ */ jsx(
2709
- "span",
2710
- {
2711
- className: "h-2 animate-pulse rounded bg-muted/70",
2712
- style: { width: `${30 + i * 13 % 30}%` }
2713
- }
2714
- )
2715
- ] })
2716
- ]
2717
- },
2718
- i
2719
- )) }),
2720
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading commands\u2026" })
2680
+ return /* @__PURE__ */ jsxs("li", { "aria-hidden": "true", className: "composer-skel-row", children: [
2681
+ /* @__PURE__ */ jsx("span", { className: "composer-skel-grouplabel composer-pulse" }),
2682
+ /* @__PURE__ */ jsx("ul", { className: "composer-skel-group", children: Array.from({ length: rows }).map((_, i) => /* @__PURE__ */ jsxs("li", { className: "composer-skel-line", children: [
2683
+ /* @__PURE__ */ jsx("span", { className: "composer-skel-avatar composer-skel-avatar--square composer-pulse" }),
2684
+ /* @__PURE__ */ jsxs("span", { className: "composer-skel-text", children: [
2685
+ /* @__PURE__ */ jsx(
2686
+ "span",
2687
+ {
2688
+ className: "composer-skel-bar composer-pulse",
2689
+ style: { width: `${50 + i * 19 % 35}%` }
2690
+ }
2691
+ ),
2692
+ /* @__PURE__ */ jsx(
2693
+ "span",
2694
+ {
2695
+ className: "composer-skel-bar--sm composer-pulse",
2696
+ style: { width: `${30 + i * 13 % 30}%` }
2697
+ }
2698
+ )
2699
+ ] })
2700
+ ] }, i)) }),
2701
+ /* @__PURE__ */ jsx("span", { className: "composer-sr-only", children: "Loading commands\u2026" })
2721
2702
  ] });
2722
2703
  }
2723
2704
  var MARGIN = 8;
@@ -2884,6 +2865,7 @@ function SmartPopover({ children, gap = 6 }) {
2884
2865
  "div",
2885
2866
  {
2886
2867
  ref,
2868
+ "data-composer-scope": "",
2887
2869
  "data-composer-popover-placement": placement?.bottom !== void 0 ? "above-composer" : "below",
2888
2870
  dir: placement?.rtl ? "rtl" : "ltr",
2889
2871
  style: mergedStyle,
@@ -3033,14 +3015,14 @@ function Avatar({ src, alt, size = 28, className }) {
3033
3015
  return /* @__PURE__ */ jsx(
3034
3016
  "span",
3035
3017
  {
3036
- className: "inline-flex shrink-0 select-none items-center justify-center overflow-hidden rounded-full bg-primary/10 text-xs font-semibold text-primary" + (className ? ` ${className}` : ""),
3018
+ className: "composer-avatar" + (className ? ` ${className}` : ""),
3037
3019
  style: { width: size, height: size },
3038
3020
  children: showImage ? /* @__PURE__ */ jsx(
3039
3021
  "img",
3040
3022
  {
3041
3023
  src,
3042
3024
  alt,
3043
- className: "h-full w-full object-cover",
3025
+ className: "composer-avatar-img",
3044
3026
  onError: () => setErrored(true)
3045
3027
  }
3046
3028
  ) : initial
@@ -3062,12 +3044,7 @@ function MentionMenu({
3062
3044
  );
3063
3045
  if (el) el.scrollIntoView({ block: "nearest" });
3064
3046
  }, [selectedIndex]);
3065
- const menu = slotProps(
3066
- "mentionMenu",
3067
- "z-50 w-64 origin-top animate-slide-up overflow-hidden rounded-xl border border-border bg-popover text-popover-foreground shadow-soft",
3068
- classNames,
3069
- sx
3070
- );
3047
+ const menu = slotProps("mentionMenu", "composer-menu", classNames, sx);
3071
3048
  const itemStyle = useMemo(() => resolveSx(sx?.mentionItem), [sx]);
3072
3049
  const showSkeleton = isLoading && options.length === 0;
3073
3050
  return /* @__PURE__ */ jsx(
@@ -3078,7 +3055,7 @@ function MentionMenu({
3078
3055
  "aria-label": "Mentions",
3079
3056
  "aria-busy": isLoading || void 0,
3080
3057
  ...menu,
3081
- children: /* @__PURE__ */ jsxs("ul", { ref: listRef, className: "max-h-72 overflow-y-auto scrollbar-thin py-1", children: [
3058
+ children: /* @__PURE__ */ jsxs("ul", { ref: listRef, className: "composer-menu-list", children: [
3082
3059
  showSkeleton ? /* @__PURE__ */ jsx(MentionSkeleton, { rows: 3 }) : null,
3083
3060
  options.map((item, index) => /* @__PURE__ */ jsxs(
3084
3061
  "li",
@@ -3091,17 +3068,13 @@ function MentionMenu({
3091
3068
  onSelect(index);
3092
3069
  },
3093
3070
  onMouseEnter: () => onHover(index),
3094
- className: cn(
3095
- "flex cursor-pointer items-center gap-2.5 px-2.5 py-1.5 text-sm",
3096
- selectedIndex === index ? "bg-accent text-accent-foreground" : "text-foreground",
3097
- classNames?.mentionItem
3098
- ),
3071
+ className: cn("composer-menu-item", classNames?.mentionItem),
3099
3072
  style: itemStyle,
3100
3073
  children: [
3101
- item.avatarUrl ? /* @__PURE__ */ jsx(Avatar, { src: item.avatarUrl, alt: item.label }) : item.icon ? /* @__PURE__ */ jsx("span", { className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-primary/10 text-primary", children: item.icon }) : /* @__PURE__ */ jsx("span", { className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-primary/10 text-xs font-semibold text-primary", children: item.label.slice(0, 1).toUpperCase() }),
3102
- /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-col leading-tight", children: [
3103
- /* @__PURE__ */ jsx("span", { className: "truncate font-medium", children: item.label }),
3104
- item.description && /* @__PURE__ */ jsx("span", { className: "truncate text-[11px] text-muted-foreground", children: item.description })
3074
+ item.avatarUrl ? /* @__PURE__ */ jsx(Avatar, { src: item.avatarUrl, alt: item.label }) : item.icon ? /* @__PURE__ */ jsx("span", { className: "composer-menu-avatar", children: item.icon }) : /* @__PURE__ */ jsx("span", { className: "composer-menu-avatar", children: item.label.slice(0, 1).toUpperCase() }),
3075
+ /* @__PURE__ */ jsxs("span", { className: "composer-menu-text", children: [
3076
+ /* @__PURE__ */ jsx("span", { className: "composer-menu-label", children: item.label }),
3077
+ item.description && /* @__PURE__ */ jsx("span", { className: "composer-menu-desc", children: item.description })
3105
3078
  ] })
3106
3079
  ]
3107
3080
  },
@@ -3112,34 +3085,27 @@ function MentionMenu({
3112
3085
  );
3113
3086
  }
3114
3087
  function MentionSkeleton({ rows = 3 }) {
3115
- return /* @__PURE__ */ jsxs("li", { "aria-hidden": "true", className: "px-2.5 py-1.5", children: [
3116
- /* @__PURE__ */ jsx("ul", { className: "flex flex-col gap-1", children: Array.from({ length: rows }).map((_, i) => /* @__PURE__ */ jsxs(
3117
- "li",
3118
- {
3119
- className: "flex items-center gap-2.5 rounded-md px-0 py-1.5",
3120
- children: [
3121
- /* @__PURE__ */ jsx("span", { className: "h-7 w-7 shrink-0 animate-pulse rounded-full bg-muted" }),
3122
- /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-1 flex-col gap-1.5", children: [
3123
- /* @__PURE__ */ jsx(
3124
- "span",
3125
- {
3126
- className: "h-2.5 animate-pulse rounded bg-muted",
3127
- style: { width: `${60 + i * 17 % 30}%` }
3128
- }
3129
- ),
3130
- /* @__PURE__ */ jsx(
3131
- "span",
3132
- {
3133
- className: "h-2 animate-pulse rounded bg-muted/70",
3134
- style: { width: `${35 + i * 23 % 25}%` }
3135
- }
3136
- )
3137
- ] })
3138
- ]
3139
- },
3140
- i
3141
- )) }),
3142
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Loading suggestions\u2026" })
3088
+ return /* @__PURE__ */ jsxs("li", { "aria-hidden": "true", className: "composer-skel-row", children: [
3089
+ /* @__PURE__ */ jsx("ul", { className: "composer-skel-group", children: Array.from({ length: rows }).map((_, i) => /* @__PURE__ */ jsxs("li", { className: "composer-skel-line", children: [
3090
+ /* @__PURE__ */ jsx("span", { className: "composer-skel-avatar composer-pulse" }),
3091
+ /* @__PURE__ */ jsxs("span", { className: "composer-skel-text", children: [
3092
+ /* @__PURE__ */ jsx(
3093
+ "span",
3094
+ {
3095
+ className: "composer-skel-bar composer-pulse",
3096
+ style: { width: `${60 + i * 17 % 30}%` }
3097
+ }
3098
+ ),
3099
+ /* @__PURE__ */ jsx(
3100
+ "span",
3101
+ {
3102
+ className: "composer-skel-bar--sm composer-pulse",
3103
+ style: { width: `${35 + i * 23 % 25}%` }
3104
+ }
3105
+ )
3106
+ ] })
3107
+ ] }, i)) }),
3108
+ /* @__PURE__ */ jsx("span", { className: "composer-sr-only", children: "Loading suggestions\u2026" })
3143
3109
  ] });
3144
3110
  }
3145
3111
  var MentionOption = class extends MenuOption {
@@ -3366,14 +3332,14 @@ function GhostOverlay({ typed, remainder, multiline }) {
3366
3332
  setContainer(block);
3367
3333
  }, [editor]);
3368
3334
  if (!container) return null;
3369
- const paddingClass = multiline ? "composer-ghost-overlay--multiline px-5 py-3.5" : "composer-ghost-overlay--inline px-2 leading-9";
3335
+ const paddingClass = multiline ? "composer-ghost-overlay--multiline" : "composer-ghost-overlay--inline";
3370
3336
  return createPortal(
3371
3337
  /* @__PURE__ */ jsxs(
3372
3338
  "div",
3373
3339
  {
3374
3340
  "aria-hidden": true,
3375
3341
  "data-composer-ghost": "",
3376
- className: `composer-ghost-overlay pointer-events-none absolute inset-0 select-none ${paddingClass}`,
3342
+ className: `composer-ghost-overlay ${paddingClass}`,
3377
3343
  children: [
3378
3344
  /* @__PURE__ */ jsx("span", { className: "composer-ghost-overlay-typed", "aria-hidden": true, children: typed }),
3379
3345
  /* @__PURE__ */ jsx("span", { className: "composer-ghost-suggestion", children: remainder })
@@ -3405,7 +3371,7 @@ function AttachmentChip({ attachment, onRemove, onZoom }) {
3405
3371
  if (isImage) {
3406
3372
  const chip2 = slotProps(
3407
3373
  "attachmentChip",
3408
- "group/chip relative h-16 w-16 overflow-hidden rounded-xl border border-border bg-muted",
3374
+ "composer-chip composer-chip--image",
3409
3375
  classNames,
3410
3376
  sx
3411
3377
  );
@@ -3415,23 +3381,23 @@ function AttachmentChip({ attachment, onRemove, onZoom }) {
3415
3381
  {
3416
3382
  src: attachment.previewUrl,
3417
3383
  alt: attachment.name,
3418
- className: "h-full w-full object-cover"
3384
+ className: "composer-chip-img"
3419
3385
  }
3420
3386
  ),
3421
3387
  isUploading && /* @__PURE__ */ jsx(
3422
3388
  "div",
3423
3389
  {
3424
3390
  "aria-label": "Uploading",
3425
- className: "absolute inset-0 grid place-items-center bg-foreground/50",
3426
- children: /* @__PURE__ */ jsx(SpinnerIcon, { className: "h-5 w-5 animate-spin text-background" })
3391
+ className: "composer-chip-overlay composer-chip-overlay--uploading",
3392
+ children: /* @__PURE__ */ jsx(SpinnerIcon, { className: "composer-spin" })
3427
3393
  }
3428
3394
  ),
3429
3395
  isFailed && /* @__PURE__ */ jsx(
3430
3396
  "div",
3431
3397
  {
3432
3398
  "aria-label": "Upload failed",
3433
- className: "absolute inset-0 grid place-items-center bg-destructive/55",
3434
- children: /* @__PURE__ */ jsx(WarningIcon, { className: "h-5 w-5 text-destructive-foreground" })
3399
+ className: "composer-chip-overlay composer-chip-overlay--failed",
3400
+ children: /* @__PURE__ */ jsx(WarningIcon, {})
3435
3401
  }
3436
3402
  ),
3437
3403
  !isUploading && !isFailed && /* @__PURE__ */ jsx(
@@ -3440,8 +3406,8 @@ function AttachmentChip({ attachment, onRemove, onZoom }) {
3440
3406
  type: "button",
3441
3407
  onClick: onZoom,
3442
3408
  "aria-label": `Zoom ${attachment.name}`,
3443
- className: "absolute inset-0 flex items-center justify-center bg-foreground/40 opacity-0 transition-opacity group-hover/chip:opacity-100",
3444
- children: /* @__PURE__ */ jsx(ZoomIcon, { className: "h-4 w-4 text-background" })
3409
+ className: "composer-chip-zoom",
3410
+ children: /* @__PURE__ */ jsx(ZoomIcon, {})
3445
3411
  }
3446
3412
  ),
3447
3413
  /* @__PURE__ */ jsx(
@@ -3450,8 +3416,9 @@ function AttachmentChip({ attachment, onRemove, onZoom }) {
3450
3416
  type: "button",
3451
3417
  onClick: onRemove,
3452
3418
  "aria-label": `Remove ${attachment.name}`,
3453
- className: "absolute end-1 top-1 z-10 flex h-5 w-5 items-center justify-center rounded-full bg-foreground text-background transition-opacity " + (isUploading || isFailed ? "opacity-100" : "opacity-0 group-hover/chip:opacity-100"),
3454
- children: /* @__PURE__ */ jsx(CloseIcon, { className: "h-3 w-3", strokeWidth: 2.5 })
3419
+ className: "composer-chip-remove",
3420
+ "data-visible": isUploading || isFailed ? "" : void 0,
3421
+ children: /* @__PURE__ */ jsx(CloseIcon, { strokeWidth: 2.5 })
3455
3422
  }
3456
3423
  )
3457
3424
  ] });
@@ -3459,27 +3426,15 @@ function AttachmentChip({ attachment, onRemove, onZoom }) {
3459
3426
  const KindIcon = attachment.kind === "audio" ? AudioIcon : FileIcon;
3460
3427
  const chip = slotProps(
3461
3428
  "attachmentChip",
3462
- "group/chip flex items-center gap-2 rounded-xl border bg-card ps-2 pe-1 py-1.5 " + (isFailed ? "border-destructive/60" : "border-border"),
3429
+ "composer-chip composer-chip--file",
3463
3430
  classNames,
3464
3431
  sx
3465
3432
  );
3466
- return /* @__PURE__ */ jsxs("div", { ...chip, title: titleText, children: [
3467
- /* @__PURE__ */ jsx(
3468
- "span",
3469
- {
3470
- className: "flex h-8 w-8 items-center justify-center rounded-md " + (isFailed ? "bg-destructive/15 text-destructive" : "bg-muted text-muted-foreground"),
3471
- children: isUploading ? /* @__PURE__ */ jsx(SpinnerIcon, { className: "h-4 w-4 animate-spin" }) : isFailed ? /* @__PURE__ */ jsx(WarningIcon, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(KindIcon, { className: "h-4 w-4" })
3472
- }
3473
- ),
3474
- /* @__PURE__ */ jsxs("span", { className: "flex flex-col", children: [
3475
- /* @__PURE__ */ jsx("span", { className: "max-w-[160px] truncate text-xs font-medium leading-tight", children: attachment.name }),
3476
- /* @__PURE__ */ jsx(
3477
- "span",
3478
- {
3479
- className: "text-[10px] " + (isFailed ? "text-destructive" : "text-muted-foreground"),
3480
- children: isUploading ? "Uploading\u2026" : isFailed ? attachment.error || "Upload failed" : formatBytes(attachment.size)
3481
- }
3482
- )
3433
+ return /* @__PURE__ */ jsxs("div", { ...chip, "data-failed": isFailed ? "" : void 0, title: titleText, children: [
3434
+ /* @__PURE__ */ jsx("span", { className: "composer-chip-icon", "data-failed": isFailed ? "" : void 0, children: isUploading ? /* @__PURE__ */ jsx(SpinnerIcon, { className: "composer-spin" }) : isFailed ? /* @__PURE__ */ jsx(WarningIcon, {}) : /* @__PURE__ */ jsx(KindIcon, {}) }),
3435
+ /* @__PURE__ */ jsxs("span", { className: "composer-chip-text", children: [
3436
+ /* @__PURE__ */ jsx("span", { className: "composer-chip-name", children: attachment.name }),
3437
+ /* @__PURE__ */ jsx("span", { className: "composer-chip-meta", "data-failed": isFailed ? "" : void 0, children: isUploading ? "Uploading\u2026" : isFailed ? attachment.error || "Upload failed" : formatBytes(attachment.size) })
3483
3438
  ] }),
3484
3439
  /* @__PURE__ */ jsx(
3485
3440
  "button",
@@ -3487,8 +3442,8 @@ function AttachmentChip({ attachment, onRemove, onZoom }) {
3487
3442
  type: "button",
3488
3443
  onClick: onRemove,
3489
3444
  "aria-label": `Remove ${attachment.name}`,
3490
- className: "flex h-6 w-6 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
3491
- children: /* @__PURE__ */ jsx(CloseIcon, { className: "h-3.5 w-3.5" })
3445
+ className: "composer-chip-remove-inline",
3446
+ children: /* @__PURE__ */ jsx(CloseIcon, {})
3492
3447
  }
3493
3448
  )
3494
3449
  ] });
@@ -3499,7 +3454,7 @@ function AttachmentTray() {
3499
3454
  if (attachments.length === 0) return null;
3500
3455
  const tray = slotProps(
3501
3456
  "attachmentTray",
3502
- "flex flex-wrap gap-2 px-4 pt-3",
3457
+ "composer-attachment-tray",
3503
3458
  classNames,
3504
3459
  sx
3505
3460
  );
@@ -3524,10 +3479,10 @@ function AttachmentTray() {
3524
3479
  ] });
3525
3480
  }
3526
3481
  var sideClasses = {
3527
- top: "bottom-full left-1/2 mb-2 -translate-x-1/2",
3528
- bottom: "top-full left-1/2 mt-2 -translate-x-1/2",
3529
- left: "end-full top-1/2 me-2 -translate-y-1/2",
3530
- right: "start-full top-1/2 ms-2 -translate-y-1/2"
3482
+ top: "composer-tooltip--top",
3483
+ bottom: "composer-tooltip--bottom",
3484
+ left: "composer-tooltip--left",
3485
+ right: "composer-tooltip--right"
3531
3486
  };
3532
3487
  function Tooltip({
3533
3488
  children,
@@ -3565,18 +3520,14 @@ function Tooltip({
3565
3520
  children
3566
3521
  }
3567
3522
  );
3568
- return /* @__PURE__ */ jsxs("span", { className: "relative inline-flex", children: [
3523
+ return /* @__PURE__ */ jsxs("span", { className: "composer-tooltip-wrap", children: [
3569
3524
  trigger,
3570
3525
  open && /* @__PURE__ */ jsx(
3571
3526
  "span",
3572
3527
  {
3573
3528
  id,
3574
3529
  role: "tooltip",
3575
- className: cn(
3576
- "absolute z-50 whitespace-nowrap rounded-md bg-foreground px-2 py-1 text-xs text-background shadow-md",
3577
- sideClasses[side],
3578
- className
3579
- ),
3530
+ className: cn("composer-tooltip", sideClasses[side], className),
3580
3531
  children: content
3581
3532
  }
3582
3533
  )
@@ -3726,7 +3677,7 @@ function VoiceButton() {
3726
3677
  }
3727
3678
  };
3728
3679
  const isRecording = state === "recording" || state === "starting";
3729
- return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
3680
+ return /* @__PURE__ */ jsxs("div", { className: "composer-voice", children: [
3730
3681
  /* @__PURE__ */ jsx(
3731
3682
  Tooltip,
3732
3683
  {
@@ -3740,17 +3691,16 @@ function VoiceButton() {
3740
3691
  "aria-pressed": isRecording,
3741
3692
  onClick: () => isRecording ? stop() : void start(),
3742
3693
  className: cn(
3743
- "flex h-8 w-8 items-center justify-center rounded-full transition-colors",
3744
- isRecording ? "bg-destructive/10 text-destructive ring-1 ring-destructive/40" : "text-muted-foreground hover:bg-accent hover:text-foreground",
3694
+ "composer-toolbar-btn composer-voice-btn",
3745
3695
  classNames?.toolbarButton
3746
3696
  ),
3747
- children: state === "transcribing" ? /* @__PURE__ */ jsx(VoiceRecordingIcon, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(VoiceIcon, { className: cn("h-4 w-4", isRecording && "animate-pulse") })
3697
+ children: state === "transcribing" ? /* @__PURE__ */ jsx(VoiceRecordingIcon, { className: "composer-spin" }) : /* @__PURE__ */ jsx(VoiceIcon, { className: cn(isRecording && "composer-pulse") })
3748
3698
  }
3749
3699
  )
3750
3700
  }
3751
3701
  ),
3752
- isRecording && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 rounded-full bg-destructive/10 px-2 py-0.5 text-[11px] font-mono font-medium tabular-nums text-destructive", children: [
3753
- /* @__PURE__ */ jsx("span", { className: "h-1.5 w-1.5 animate-pulse rounded-full bg-destructive" }),
3702
+ isRecording && /* @__PURE__ */ jsxs("span", { className: "composer-voice-timer", children: [
3703
+ /* @__PURE__ */ jsx("span", { className: "composer-voice-dot composer-pulse" }),
3754
3704
  formatSeconds(elapsed)
3755
3705
  ] })
3756
3706
  ] });
@@ -3848,7 +3798,7 @@ function AttachmentTypePicker({
3848
3798
  useEffect(() => {
3849
3799
  if (open) setActiveIndex(0);
3850
3800
  }, [open]);
3851
- return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
3801
+ return /* @__PURE__ */ jsxs("div", { className: "composer-attach-picker", children: [
3852
3802
  /* @__PURE__ */ jsx(
3853
3803
  "input",
3854
3804
  {
@@ -3875,7 +3825,7 @@ function AttachmentTypePicker({
3875
3825
  onClick: () => setOpen((o) => !o),
3876
3826
  className: triggerClassName,
3877
3827
  style: triggerStyle,
3878
- children: /* @__PURE__ */ jsx(TriggerIcon, { className: "h-4 w-4" })
3828
+ children: /* @__PURE__ */ jsx(TriggerIcon, {})
3879
3829
  }
3880
3830
  ),
3881
3831
  open && /* @__PURE__ */ jsx(
@@ -3886,11 +3836,7 @@ function AttachmentTypePicker({
3886
3836
  role: "menu",
3887
3837
  "aria-label": "Attachment types",
3888
3838
  "data-composer-popover": "open",
3889
- className: cn(
3890
- "composer-popover-in absolute bottom-full start-0 z-30 mb-2 min-w-[200px] overflow-hidden",
3891
- "rounded-xl border border-border bg-popover p-1 text-popover-foreground",
3892
- "shadow-soft"
3893
- ),
3839
+ className: "composer-popover-in composer-attach-menu",
3894
3840
  children: types.map((type, index) => {
3895
3841
  const active = index === activeIndex;
3896
3842
  return /* @__PURE__ */ jsxs(
@@ -3902,16 +3848,14 @@ function AttachmentTypePicker({
3902
3848
  role: "menuitem",
3903
3849
  type: "button",
3904
3850
  tabIndex: active ? 0 : -1,
3851
+ "data-active": active ? "" : void 0,
3905
3852
  onMouseEnter: () => setActiveIndex(index),
3906
3853
  onClick: () => pick(index),
3907
- className: cn(
3908
- "flex w-full items-center gap-2.5 rounded-lg px-2.5 py-1.5 text-start text-sm transition-colors",
3909
- active ? "bg-accent text-accent-foreground" : "text-foreground hover:bg-accent/60"
3910
- ),
3854
+ className: "composer-attach-item",
3911
3855
  children: [
3912
- type.icon ? /* @__PURE__ */ jsx("span", { className: "flex h-5 w-5 shrink-0 items-center justify-center text-muted-foreground", children: type.icon }) : null,
3913
- /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate font-medium", children: type.label }),
3914
- type.description ? /* @__PURE__ */ jsx("span", { className: "shrink-0 font-mono text-[11px] text-muted-foreground", children: type.description }) : null
3856
+ type.icon ? /* @__PURE__ */ jsx("span", { className: "composer-attach-item-icon", children: type.icon }) : null,
3857
+ /* @__PURE__ */ jsx("span", { className: "composer-attach-item-label", children: type.label }),
3858
+ type.description ? /* @__PURE__ */ jsx("span", { className: "composer-attach-item-desc", children: type.description }) : null
3915
3859
  ]
3916
3860
  },
3917
3861
  type.id
@@ -3921,7 +3865,7 @@ function AttachmentTypePicker({
3921
3865
  )
3922
3866
  ] });
3923
3867
  }
3924
- var TOOLBAR_BTN_BASE = "flex h-8 w-8 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-accent hover:text-foreground";
3868
+ var TOOLBAR_BTN_BASE = "composer-toolbar-btn";
3925
3869
  function Toolbar({ extras }) {
3926
3870
  const {
3927
3871
  features,
@@ -3940,7 +3884,7 @@ function Toolbar({ extras }) {
3940
3884
  const showFileBtn = attachmentsEnabled && attachmentsConfig.file !== false;
3941
3885
  const showImageBtn = attachmentsEnabled && attachmentsConfig.image !== false;
3942
3886
  const hasTypePicker = showFileBtn && Array.isArray(attachmentsConfig.types) && attachmentsConfig.types.length > 0;
3943
- const toolbar = slotProps("toolbar", "flex items-center gap-1", classNames, sx);
3887
+ const toolbar = slotProps("toolbar", "composer-toolbar", classNames, sx);
3944
3888
  const toolbarBtn = slotProps("toolbarButton", TOOLBAR_BTN_BASE, classNames, sx);
3945
3889
  return /* @__PURE__ */ jsxs("div", { ...toolbar, children: [
3946
3890
  showFileBtn && !hasTypePicker && /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -3966,7 +3910,7 @@ function Toolbar({ extras }) {
3966
3910
  "aria-label": "Attach file",
3967
3911
  onClick: () => fileInputRef.current?.click(),
3968
3912
  ...toolbarBtn,
3969
- children: /* @__PURE__ */ jsx(AttachIcon, { className: "h-4 w-4" })
3913
+ children: /* @__PURE__ */ jsx(AttachIcon, {})
3970
3914
  }
3971
3915
  ) })
3972
3916
  ] }),
@@ -4003,7 +3947,7 @@ function Toolbar({ extras }) {
4003
3947
  "aria-label": "Add image",
4004
3948
  onClick: () => imageInputRef.current?.click(),
4005
3949
  ...toolbarBtn,
4006
- children: /* @__PURE__ */ jsx(ImageIcon, { className: "h-4 w-4" })
3950
+ children: /* @__PURE__ */ jsx(ImageIcon, {})
4007
3951
  }
4008
3952
  ) })
4009
3953
  ] }),
@@ -4014,13 +3958,9 @@ function Toolbar({ extras }) {
4014
3958
  type: "button",
4015
3959
  onClick: toggleWeb,
4016
3960
  "aria-pressed": webEnabled,
4017
- className: cn(
4018
- "ms-0.5 inline-flex h-8 items-center gap-1.5 rounded-full px-2.5 text-xs font-medium transition-colors",
4019
- webEnabled ? "bg-primary/10 text-primary" : "text-muted-foreground hover:bg-accent hover:text-foreground",
4020
- classNames?.toolbarButton
4021
- ),
3961
+ className: cn("composer-web-btn", classNames?.toolbarButton),
4022
3962
  children: [
4023
- /* @__PURE__ */ jsx(WebIcon, { className: "h-3.5 w-3.5" }),
3963
+ /* @__PURE__ */ jsx(WebIcon, {}),
4024
3964
  "Web"
4025
3965
  ]
4026
3966
  }
@@ -4034,7 +3974,7 @@ function SendButton({ canSend, isStreaming, onSend, onStop }) {
4034
3974
  if (isStreaming) {
4035
3975
  const stop = slotProps(
4036
3976
  "stopButton",
4037
- "inline-flex h-9 w-9 items-center justify-center rounded-full bg-foreground text-background transition-transform hover:scale-105",
3977
+ "composer-send-btn composer-send-btn--stop",
4038
3978
  classNames,
4039
3979
  sx
4040
3980
  );
@@ -4049,17 +3989,9 @@ function SendButton({ canSend, isStreaming, onSend, onStop }) {
4049
3989
  }
4050
3990
  );
4051
3991
  }
4052
- return /* @__PURE__ */ jsx("button", { type: "button", onClick: onStop, "aria-label": "Stop generating", ...stop, children: /* @__PURE__ */ jsx(StopIcon, { className: "h-3.5 w-3.5 fill-current" }) });
3992
+ return /* @__PURE__ */ jsx("button", { type: "button", onClick: onStop, "aria-label": "Stop generating", ...stop, children: /* @__PURE__ */ jsx(StopIcon, {}) });
4053
3993
  }
4054
- const send = slotProps(
4055
- "sendButton",
4056
- [
4057
- "inline-flex h-9 w-9 items-center justify-center rounded-full transition-all",
4058
- canSend ? "bg-foreground text-background shadow-sm hover:scale-105" : "bg-muted text-muted-foreground/60"
4059
- ],
4060
- classNames,
4061
- sx
4062
- );
3994
+ const send = slotProps("sendButton", "composer-send-btn", classNames, sx);
4063
3995
  if (slots.sendButton) {
4064
3996
  const Slot = slots.sendButton;
4065
3997
  return /* @__PURE__ */ jsx(
@@ -4080,14 +4012,14 @@ function SendButton({ canSend, isStreaming, onSend, onStop }) {
4080
4012
  disabled: !canSend,
4081
4013
  "aria-label": "Send message",
4082
4014
  ...send,
4083
- children: /* @__PURE__ */ jsx(SendIcon, { className: "h-4 w-4", strokeWidth: 2.5 })
4015
+ children: /* @__PURE__ */ jsx(SendIcon, { strokeWidth: 2.5 })
4084
4016
  }
4085
4017
  );
4086
4018
  }
4087
4019
  function noop() {
4088
4020
  }
4089
4021
  function Key({ children }) {
4090
- return /* @__PURE__ */ jsx("kbd", { className: "rounded border border-border bg-card px-1 py-0.5 font-mono text-[10px]", children });
4022
+ return /* @__PURE__ */ jsx("kbd", { className: "composer-kbd", children });
4091
4023
  }
4092
4024
  function formatShortcut(spec) {
4093
4025
  const parts = spec.split("+").map((s) => s.trim().toLowerCase()).filter(Boolean);
@@ -4178,19 +4110,14 @@ function HintBar({ hint }) {
4178
4110
  ] });
4179
4111
  }, [focusShortcut]);
4180
4112
  if (!hint) return null;
4181
- const hintProps = slotProps(
4182
- "hint",
4183
- "text-center text-[11px] text-muted-foreground",
4184
- classNames,
4185
- sx
4186
- );
4113
+ const hintProps = slotProps("hint", "composer-hint", classNames, sx);
4187
4114
  return /* @__PURE__ */ jsx("p", { ...hintProps, children: hint === true ? /* @__PURE__ */ jsxs(Fragment, { children: [
4188
4115
  "AI can make mistakes \u2014 verify important info.",
4189
- defaultShortcuts ? /* @__PURE__ */ jsxs("span", { className: "hidden sm:inline", children: [
4116
+ defaultShortcuts ? /* @__PURE__ */ jsxs("span", { className: "composer-hint-sm", children: [
4190
4117
  " ",
4191
4118
  defaultShortcuts
4192
4119
  ] }) : null,
4193
- focusHint ? /* @__PURE__ */ jsx("span", { className: "hidden md:inline", children: focusHint }) : null
4120
+ focusHint ? /* @__PURE__ */ jsx("span", { className: "composer-hint-md", children: focusHint }) : null
4194
4121
  ] }) : hint });
4195
4122
  }
4196
4123
  var DEFAULT_MAX = 3;
@@ -4221,35 +4148,20 @@ function QuickPrompts({ prompts }) {
4221
4148
  prompts.onSelect?.(prompt);
4222
4149
  runPrompt(prompt, behavior);
4223
4150
  };
4224
- return /* @__PURE__ */ jsx(
4225
- "div",
4151
+ return /* @__PURE__ */ jsx("div", { role: "group", "aria-label": "Quick prompts", className: "composer-prompts", children: display.map((p) => /* @__PURE__ */ jsxs(
4152
+ "button",
4226
4153
  {
4227
- role: "group",
4228
- "aria-label": "Quick prompts",
4229
- className: "flex flex-wrap items-center gap-2 px-1 pb-1",
4230
- children: display.map((p) => /* @__PURE__ */ jsxs(
4231
- "button",
4232
- {
4233
- type: "button",
4234
- onClick: () => handleClick(p),
4235
- title: p,
4236
- className: cn(
4237
- "group inline-flex max-w-full items-center gap-1.5 rounded-full",
4238
- "border border-border bg-card/60 px-3 py-1.5 text-xs",
4239
- "text-muted-foreground backdrop-blur transition-all",
4240
- "hover:-translate-y-px hover:border-primary/40 hover:bg-card",
4241
- "hover:text-foreground hover:shadow-sm",
4242
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40"
4243
- ),
4244
- children: [
4245
- /* @__PURE__ */ jsx(SparkleIcon, { className: "h-3 w-3 shrink-0 text-primary opacity-70 group-hover:opacity-100" }),
4246
- /* @__PURE__ */ jsx("span", { className: "truncate", style: { maxWidth: "32ch" }, children: p })
4247
- ]
4248
- },
4249
- p
4250
- ))
4251
- }
4252
- );
4154
+ type: "button",
4155
+ onClick: () => handleClick(p),
4156
+ title: p,
4157
+ className: "composer-prompt",
4158
+ children: [
4159
+ /* @__PURE__ */ jsx(SparkleIcon, {}),
4160
+ /* @__PURE__ */ jsx("span", { className: "composer-prompt-text", style: { maxWidth: "32ch" }, children: p })
4161
+ ]
4162
+ },
4163
+ p
4164
+ )) });
4253
4165
  }
4254
4166
  function useComposerHandle(ref, onSubmit) {
4255
4167
  const [editor] = useLexicalComposerContext();
@@ -4399,7 +4311,7 @@ var Composer = forwardRef(function Composer2(props, ref) {
4399
4311
  if (!derived && !tokens) return void 0;
4400
4312
  return tokensToStyle({ ...derived, ...tokens });
4401
4313
  }, [color, tokens]);
4402
- const root = slotProps("root", "space-y-2", classNames, sx);
4314
+ const root = slotProps("root", "composer-root", classNames, sx);
4403
4315
  const rootStyle = useMemo(
4404
4316
  () => ({ ...tokenStyle, ...root.style, ...style }),
4405
4317
  [tokenStyle, root.style, style]
@@ -4427,6 +4339,7 @@ var Composer = forwardRef(function Composer2(props, ref) {
4427
4339
  "div",
4428
4340
  {
4429
4341
  dir,
4342
+ "data-composer-scope": "",
4430
4343
  className: cn(root.className, className),
4431
4344
  style: Object.keys(rootStyle).length ? rootStyle : void 0,
4432
4345
  children: [
@@ -4483,16 +4396,7 @@ function ComposerCard({
4483
4396
  multiline
4484
4397
  }) {
4485
4398
  const { webEnabled, isDraggingFiles, classNames, sx } = useComposerContext();
4486
- const card = slotProps(
4487
- "card",
4488
- [
4489
- "group relative border border-border bg-card shadow-soft transition-all focus-within:border-primary/40 focus-within:shadow-glow",
4490
- webEnabled && "ring-1 ring-primary/20",
4491
- isDraggingFiles && "ring-2 ring-primary/60"
4492
- ],
4493
- classNames,
4494
- sx
4495
- );
4399
+ const card = slotProps("card", "composer-card", classNames, sx);
4496
4400
  const initialConfig = useMemo(
4497
4401
  () => ({
4498
4402
  namespace: "composeai",
@@ -4510,6 +4414,8 @@ function ComposerCard({
4510
4414
  {
4511
4415
  "data-composer-root": "",
4512
4416
  "data-composer-inline": multiline ? void 0 : "",
4417
+ "data-composer-web": webEnabled ? "" : void 0,
4418
+ "data-composer-dragging": isDraggingFiles ? "" : void 0,
4513
4419
  ...card,
4514
4420
  children: [
4515
4421
  /* @__PURE__ */ jsx(
@@ -4517,7 +4423,7 @@ function ComposerCard({
4517
4423
  {
4518
4424
  "aria-hidden": true,
4519
4425
  "data-composer-overlay": "",
4520
- className: "pointer-events-none absolute inset-0 opacity-0 transition-opacity group-focus-within:opacity-100",
4426
+ className: "composer-overlay-glow",
4521
4427
  style: {
4522
4428
  background: "linear-gradient(135deg, hsl(var(--primary)/0.08) 0%, transparent 40%, hsl(var(--primary)/0.06) 100%)"
4523
4429
  }
@@ -4528,7 +4434,7 @@ function ComposerCard({
4528
4434
  {
4529
4435
  "aria-hidden": true,
4530
4436
  "data-composer-overlay": "",
4531
- className: "pointer-events-none absolute inset-0 z-10 flex items-center justify-center bg-primary/5 text-sm font-medium text-primary backdrop-blur-[1px]",
4437
+ className: "composer-overlay-drop",
4532
4438
  children: "Drop to attach"
4533
4439
  }
4534
4440
  ),
@@ -4727,14 +4633,14 @@ function MermaidSlot() {
4727
4633
  function SuggestionRow({ items, onSelect, className }) {
4728
4634
  const { icons } = useComposerContext();
4729
4635
  const { sparkle: SparkleIcon } = icons;
4730
- return /* @__PURE__ */ jsx("div", { className: cn("flex flex-wrap justify-center gap-2", className), children: items.map((s) => /* @__PURE__ */ jsxs(
4636
+ return /* @__PURE__ */ jsx("div", { className: cn("composer-suggestions", className), children: items.map((s) => /* @__PURE__ */ jsxs(
4731
4637
  "button",
4732
4638
  {
4733
4639
  type: "button",
4734
4640
  onClick: () => onSelect(s),
4735
- className: "group inline-flex items-center gap-1.5 rounded-full border border-border bg-card/60 px-3.5 py-1.5 text-xs text-muted-foreground backdrop-blur transition-all hover:-translate-y-px hover:border-primary/40 hover:bg-card hover:text-foreground hover:shadow-sm",
4641
+ className: "composer-suggestion",
4736
4642
  children: [
4737
- /* @__PURE__ */ jsx(SparkleIcon, { className: "h-3 w-3 text-primary opacity-70 group-hover:opacity-100" }),
4643
+ /* @__PURE__ */ jsx(SparkleIcon, {}),
4738
4644
  s
4739
4645
  ]
4740
4646
  },