@cueplusplus/ui 0.20.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/CHANGELOG.md +134 -0
  2. package/dist/brand/particle-logo.js +11 -3
  3. package/dist/chat/agent-pile.js +2 -2
  4. package/dist/chrome/_status-bar.js +1 -1
  5. package/dist/chrome/app-shell.js +1 -1
  6. package/dist/chrome/navigation-menu.js +3 -3
  7. package/dist/chrome/row.js +1 -1
  8. package/dist/chrome/scroll-area.js +1 -1
  9. package/dist/chrome/section-header.js +1 -1
  10. package/dist/chrome/segmented-control.js +1 -1
  11. package/dist/chrome/tabs.js +1 -1
  12. package/dist/chrome/toolbar.js +1 -1
  13. package/dist/chrome/tree.js +3 -3
  14. package/dist/date/calendar.js +3 -3
  15. package/dist/dmx/channel-matrix.js +1 -1
  16. package/dist/dmx/universe-grid.js +1 -1
  17. package/dist/elements/agent-handoff.js +3 -3
  18. package/dist/elements/agent-plan.js +1 -1
  19. package/dist/elements/agent-status.js +1 -1
  20. package/dist/elements/agent-surface.d.ts +9 -6
  21. package/dist/elements/agent-surface.js +3 -2
  22. package/dist/elements/approval-card.d.ts +29 -3
  23. package/dist/elements/approval-card.js +18 -8
  24. package/dist/elements/artifact-card.js +2 -2
  25. package/dist/elements/canvas-split.js +3 -3
  26. package/dist/elements/chart.js +1 -1
  27. package/dist/elements/chat-panel.js +2 -2
  28. package/dist/elements/checkpoint-history.js +1 -1
  29. package/dist/elements/code-diff.js +1 -1
  30. package/dist/elements/code-runner.js +1 -1
  31. package/dist/elements/composer.d.ts +8 -2
  32. package/dist/elements/composer.js +20 -12
  33. package/dist/elements/computer-use.js +2 -2
  34. package/dist/elements/confidence-marker.js +1 -1
  35. package/dist/elements/connection-state.js +2 -2
  36. package/dist/elements/context-breakdown.js +1 -1
  37. package/dist/elements/context-usage.js +1 -1
  38. package/dist/elements/conversation-search.js +2 -2
  39. package/dist/elements/cost-meter.js +1 -1
  40. package/dist/elements/data-table.js +1 -1
  41. package/dist/elements/diagram.js +1 -1
  42. package/dist/elements/draft-restore.js +2 -2
  43. package/dist/elements/edit-message.js +1 -1
  44. package/dist/elements/elements.css +134 -0
  45. package/dist/elements/elicitation-form.d.ts +8 -1
  46. package/dist/elements/elicitation-form.js +24 -16
  47. package/dist/elements/empty-state.js +3 -3
  48. package/dist/elements/error-state.js +2 -2
  49. package/dist/elements/event-feed.d.ts +88 -0
  50. package/dist/elements/event-feed.js +190 -0
  51. package/dist/elements/feedback-dialog.js +2 -2
  52. package/dist/elements/file-tree.js +1 -1
  53. package/dist/elements/flow-graph.js +2 -2
  54. package/dist/elements/generative.css +13 -0
  55. package/dist/elements/generative.d.ts +8 -6
  56. package/dist/elements/generative.js +4 -3
  57. package/dist/elements/image-generation.js +2 -2
  58. package/dist/elements/index.d.ts +7 -3
  59. package/dist/elements/index.js +5 -2
  60. package/dist/elements/inline-citation.js +1 -1
  61. package/dist/elements/job-progress.js +1 -1
  62. package/dist/elements/launcher-bubble.js +3 -3
  63. package/dist/elements/loading-state.js +1 -1
  64. package/dist/elements/map-answer.js +1 -1
  65. package/dist/elements/math-block.js +1 -1
  66. package/dist/elements/mcp-server-panel.js +3 -3
  67. package/dist/elements/memory-chips.js +1 -1
  68. package/dist/elements/message-attachment.js +3 -3
  69. package/dist/elements/message-branches.js +1 -1
  70. package/dist/elements/message-pair.js +2 -2
  71. package/dist/elements/message-queue.js +1 -1
  72. package/dist/elements/message-timing.js +1 -1
  73. package/dist/elements/mobile-composer.js +1 -1
  74. package/dist/elements/model-picker.js +1 -1
  75. package/dist/elements/number-ticker.js +1 -1
  76. package/dist/elements/onboarding.js +3 -3
  77. package/dist/elements/permission-grant.js +3 -3
  78. package/dist/elements/prompt-library.js +1 -1
  79. package/dist/elements/question-card.d.ts +50 -0
  80. package/dist/elements/question-card.js +117 -0
  81. package/dist/elements/queue-dock.js +1 -1
  82. package/dist/elements/quota-banner.js +1 -1
  83. package/dist/elements/quote-reply.js +3 -3
  84. package/dist/elements/read-aloud.js +2 -2
  85. package/dist/elements/reasoning-effort.js +2 -2
  86. package/dist/elements/reasoning-panel.js +3 -3
  87. package/dist/elements/recommendation-card.js +2 -2
  88. package/dist/elements/regenerate-menu.js +1 -1
  89. package/dist/elements/request-delivery.js +31 -0
  90. package/dist/elements/research-report.js +1 -1
  91. package/dist/elements/retrieval-chunks.js +3 -3
  92. package/dist/elements/revert-dock.js +1 -1
  93. package/dist/elements/reviewable-diff.js +4 -4
  94. package/dist/elements/schedule-card.js +2 -2
  95. package/dist/elements/score-breakdown.js +2 -2
  96. package/dist/elements/scroll-anchor.js +2 -2
  97. package/dist/elements/settings-panel.js +3 -3
  98. package/dist/elements/sources.js +1 -1
  99. package/dist/elements/spec-sheet.js +1 -1
  100. package/dist/elements/stopped-run.js +2 -2
  101. package/dist/elements/streaming-text.js +2 -2
  102. package/dist/elements/subagent-list.js +4 -4
  103. package/dist/elements/suggestions.js +1 -1
  104. package/dist/elements/surfaces.d.ts +6 -6
  105. package/dist/elements/surfaces.js +7 -7
  106. package/dist/elements/tail-status.js +1 -1
  107. package/dist/elements/terminal-block.js +1 -1
  108. package/dist/elements/thinking-indicator.js +1 -1
  109. package/dist/elements/timeline.js +1 -1
  110. package/dist/elements/todo-list.js +1 -1
  111. package/dist/elements/tool-call.d.ts +18 -2
  112. package/dist/elements/tool-call.js +20 -11
  113. package/dist/elements/tool-error.js +2 -2
  114. package/dist/elements/tool-group.d.ts +11 -3
  115. package/dist/elements/tool-group.js +62 -38
  116. package/dist/elements/tool-state.d.ts +13 -0
  117. package/dist/elements/tool-state.js +44 -0
  118. package/dist/elements/tool-timeline.js +2 -2
  119. package/dist/elements/trace-waterfall.js +2 -2
  120. package/dist/elements/unsupported-request-card.d.ts +31 -0
  121. package/dist/elements/unsupported-request-card.js +80 -0
  122. package/dist/elements/vocabulary.d.ts +50 -1
  123. package/dist/elements/vocabulary.js +50 -1
  124. package/dist/elements/voice-conversation.js +5 -5
  125. package/dist/elements/web-preview.js +1 -1
  126. package/dist/elements/web-search.js +2 -2
  127. package/dist/elements/work-collapse.js +1 -1
  128. package/dist/forms/file-upload.js +1 -1
  129. package/dist/forms/rating.js +1 -1
  130. package/dist/forms/select.js +1 -1
  131. package/dist/forms/switch.js +2 -2
  132. package/dist/forms/toggle.js +1 -1
  133. package/dist/index.d.ts +3 -1
  134. package/dist/index.js +3 -1
  135. package/dist/instruments/_ledger-disclosure.js +1 -1
  136. package/dist/instruments/data-tree.js +1 -1
  137. package/dist/instruments/meter.js +1 -1
  138. package/dist/instruments/seam-grid.js +1 -1
  139. package/dist/layout/_collapse.js +3 -3
  140. package/dist/layout/bento.js +1 -1
  141. package/dist/layout/breadcrumb.js +1 -1
  142. package/dist/layout/carousel.js +1 -1
  143. package/dist/layout/collapsible.js +1 -1
  144. package/dist/layout/index.d.ts +3 -1
  145. package/dist/layout/index.js +3 -1
  146. package/dist/layout/item.js +1 -1
  147. package/dist/layout/link.js +1 -1
  148. package/dist/layout/pagination.js +1 -1
  149. package/dist/layout/pane-seam.d.ts +75 -0
  150. package/dist/layout/pane-seam.js +127 -0
  151. package/dist/layout/resizable.d.ts +2 -1
  152. package/dist/layout/resizable.js +3 -2
  153. package/dist/layout/reveal.js +10 -4
  154. package/dist/layout/sidebar.js +3 -3
  155. package/dist/layout/split-pane.d.ts +74 -0
  156. package/dist/layout/split-pane.js +135 -0
  157. package/dist/layout/stepper.js +1 -1
  158. package/dist/lib/auto-grow.js +42 -0
  159. package/dist/overlays/_surface.d.ts +4 -4
  160. package/dist/overlays/_surface.js +4 -4
  161. package/dist/overlays/drawer.js +1 -1
  162. package/dist/overlays/menubar.js +1 -1
  163. package/dist/overlays/sheet.js +1 -1
  164. package/dist/overlays/toast.js +1 -1
  165. package/dist/primitives/button.js +1 -1
  166. package/dist/primitives/chip.d.ts +1 -1
  167. package/dist/styles.css +12 -0
  168. package/dist/system/agent-skin.d.ts +11 -5
  169. package/dist/system/frame-clock.js +1 -0
  170. package/dist/system/theme-registry.d.ts +1 -1
  171. package/dist/system/theme-registry.js +1 -1
  172. package/manifest/components/agent-surface.json +5 -4
  173. package/manifest/components/approval-card.json +45 -7
  174. package/manifest/components/composer-input.json +16 -2
  175. package/manifest/components/elicitation-form.json +16 -1
  176. package/manifest/components/event-feed.json +171 -0
  177. package/manifest/components/event-row.json +116 -0
  178. package/manifest/components/generative-ui.json +4 -3
  179. package/manifest/components/pane-seam.json +171 -0
  180. package/manifest/components/question-card.json +157 -0
  181. package/manifest/components/resizable.json +1 -1
  182. package/manifest/components/reveal.json +3 -1
  183. package/manifest/components/split-pane.json +224 -0
  184. package/manifest/components/tool-call.json +46 -2
  185. package/manifest/components/tool-group.json +15 -3
  186. package/manifest/components/unsupported-request-card.json +117 -0
  187. package/manifest/fixtures.json +16 -0
  188. package/manifest/manifest.json +91 -13
  189. package/manifest/tokens.json +9 -2
  190. package/package.json +8 -6
@@ -1,8 +1,9 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.js";
3
- import { mono, paper } from "./surfaces.js";
3
+ import { mono } from "./surfaces.js";
4
+ import { ToolStateMark } from "./tool-state.js";
4
5
  import { jsx, jsxs } from "react/jsx-runtime";
5
- import { CheckIcon, ChevronRightIcon, Loader2Icon, XIcon } from "lucide-react";
6
+ import { ChevronRightIcon, Loader2Icon } from "lucide-react";
6
7
  //#region src/elements/tool-group.tsx
7
8
  /**
8
9
  * Calls that went out together, collapsed to one row until you want the detail.
@@ -17,54 +18,77 @@ import { CheckIcon, ChevronRightIcon, Loader2Icon, XIcon } from "lucide-react";
17
18
  * onOpenChange={setOpen}
18
19
  * />
19
20
  */
20
- function ToolGroup({ label, tools, open, onOpenChange, className, ...props }) {
21
+ function ToolGroup({ label, tools, open, onOpenChange, variant = "card", className, ...props }) {
21
22
  const running = tools.filter((tool) => tool.state === "running").length;
22
23
  const failed = tools.filter((tool) => tool.state === "failed").length;
24
+ const refused = tools.filter((tool) => tool.state === "refused").length;
25
+ const live = open ? void 0 : tools.find((tool) => tool.state === "running");
23
26
  return /* @__PURE__ */ jsxs("div", {
24
27
  "data-slot": "tool-group",
25
- className: cn(paper, "flex w-full max-w-sm flex-col overflow-hidden rounded-overlay", className),
28
+ "data-variant": variant,
29
+ className: cn(variant === "card" && "bg-surface-1 border border-border", "flex w-full flex-col overflow-hidden", variant === "card" && "max-w-sm rounded-overlay", className),
26
30
  ...props,
27
- children: [/* @__PURE__ */ jsxs("button", {
28
- type: "button",
29
- "aria-expanded": open,
30
- onClick: () => onOpenChange?.(!open),
31
- className: "hover:bg-surface-1 flex items-center gap-2.5 px-3.5 py-2.5 text-start transition-colors",
32
- children: [
33
- /* @__PURE__ */ jsx(ChevronRightIcon, { className: cn("text-fg-subtle size-3 shrink-0 transition-transform duration-200 motion-reduce:transition-none", open && "rotate-90") }),
34
- /* @__PURE__ */ jsx("span", {
35
- className: "min-w-0 flex-1 truncate text-(length:--cue-text-body)",
36
- children: label
37
- }),
38
- /* @__PURE__ */ jsx("span", {
39
- className: cn(mono, "text-fg-subtle shrink-0 tabular-nums"),
40
- children: running > 0 ? `${tools.length - running}/${tools.length}` : failed > 0 ? `${failed} failed` : `${tools.length} done`
41
- }),
42
- running > 0 ? /* @__PURE__ */ jsx(Loader2Icon, { className: "text-fg-subtle size-3.5 shrink-0 animate-spin motion-reduce:animate-none" }) : failed > 0 ? /* @__PURE__ */ jsx(XIcon, { className: "size-3.5 shrink-0 text-danger" }) : /* @__PURE__ */ jsx(CheckIcon, { className: "size-3.5 shrink-0 text-ok" })
43
- ]
44
- }), open && /* @__PURE__ */ jsx("div", {
45
- className: "border-border cue-elements-fade-in cue-elements-slide-in-from-top-1 cue-elements-animate-in flex flex-col border-t duration-200",
46
- children: tools.map((tool) => /* @__PURE__ */ jsxs("div", {
47
- className: "flex items-center gap-2.5 px-3.5 py-2",
31
+ children: [
32
+ /* @__PURE__ */ jsxs("button", {
33
+ type: "button",
34
+ "aria-expanded": open,
35
+ onClick: () => onOpenChange?.(!open),
36
+ className: "hover:bg-surface-1 flex items-center gap-2.5 px-3.5 py-2.5 text-start transition-colors",
48
37
  children: [
38
+ /* @__PURE__ */ jsx(ChevronRightIcon, { className: cn("text-fg-subtle size-3 shrink-0 transition-transform duration-brisk motion-reduce:transition-none", open && "rotate-90") }),
49
39
  /* @__PURE__ */ jsx("span", {
50
- className: "flex size-3.5 shrink-0 items-center justify-center",
51
- children: tool.state === "running" ? /* @__PURE__ */ jsx(Loader2Icon, { className: "text-fg-subtle size-3 animate-spin motion-reduce:animate-none" }) : tool.state === "failed" ? /* @__PURE__ */ jsx(XIcon, { className: "size-3 text-danger" }) : /* @__PURE__ */ jsx(CheckIcon, { className: "size-3 text-ok" })
40
+ className: "min-w-0 flex-1 truncate text-(length:--cue-text-body)",
41
+ children: label
52
42
  }),
53
43
  /* @__PURE__ */ jsx("span", {
54
- className: cn("font-mono text-(length:--cue-text-label) tracking-tight", "text-fg-muted shrink-0"),
55
- children: tool.name
44
+ className: cn(mono, "text-fg-subtle shrink-0 tabular-nums"),
45
+ children: running > 0 ? `${tools.length - running}/${tools.length}` : failed > 0 ? `${failed} failed` : refused > 0 ? `${refused} refused` : `${tools.length} done`
56
46
  }),
57
- /* @__PURE__ */ jsx("span", {
58
- className: "text-fg-muted min-w-0 flex-1 truncate text-(length:--cue-text-body)",
59
- children: tool.target
60
- }),
61
- tool.durationMs !== void 0 && /* @__PURE__ */ jsxs("span", {
62
- className: cn("font-mono text-(length:--cue-text-label) tracking-tight", "text-fg-subtle shrink-0 tabular-nums"),
63
- children: [tool.durationMs, "ms"]
47
+ running > 0 ? /* @__PURE__ */ jsx(Loader2Icon, { className: "text-fg-subtle size-3.5 shrink-0 animate-spin motion-reduce:animate-none" }) : /* @__PURE__ */ jsx(ToolStateMark, {
48
+ state: failed > 0 ? "failed" : refused > 0 ? "refused" : "done",
49
+ animated: false,
50
+ className: "size-3.5 shrink-0"
64
51
  })
65
52
  ]
66
- }, tool.id))
67
- })]
53
+ }),
54
+ live !== void 0 && /* @__PURE__ */ jsxs("p", {
55
+ "data-slot": "tool-group-live",
56
+ className: cn("font-mono text-(length:--cue-text-label) tracking-tight", "text-fg-subtle -mt-1.5 truncate px-3.5 pb-2 ps-9"),
57
+ children: [
58
+ live.name,
59
+ " ",
60
+ live.target
61
+ ]
62
+ }),
63
+ open && /* @__PURE__ */ jsx("div", {
64
+ className: "border-border cue-elements-fade-in cue-elements-slide-in-from-top-1 cue-elements-animate-in flex flex-col border-t duration-brisk",
65
+ children: tools.map((tool) => /* @__PURE__ */ jsxs("div", {
66
+ className: "flex items-center gap-2.5 px-3.5 py-2",
67
+ children: [
68
+ /* @__PURE__ */ jsx("span", {
69
+ className: "flex size-3.5 shrink-0 items-center justify-center",
70
+ children: tool.state === "running" ? /* @__PURE__ */ jsx(Loader2Icon, { className: "text-fg-subtle size-3 animate-spin motion-reduce:animate-none" }) : /* @__PURE__ */ jsx(ToolStateMark, {
71
+ state: tool.state,
72
+ animated: false,
73
+ className: "size-3"
74
+ })
75
+ }),
76
+ /* @__PURE__ */ jsx("span", {
77
+ className: cn("font-mono text-(length:--cue-text-label) tracking-tight", "text-fg-muted shrink-0"),
78
+ children: tool.name
79
+ }),
80
+ /* @__PURE__ */ jsx("span", {
81
+ className: "text-fg-muted min-w-0 flex-1 truncate text-(length:--cue-text-body)",
82
+ children: tool.target
83
+ }),
84
+ tool.durationMs !== void 0 && /* @__PURE__ */ jsxs("span", {
85
+ className: cn("font-mono text-(length:--cue-text-label) tracking-tight", "text-fg-subtle shrink-0 tabular-nums"),
86
+ children: [tool.durationMs, "ms"]
87
+ })
88
+ ]
89
+ }, tool.id))
90
+ })
91
+ ]
68
92
  });
69
93
  }
70
94
  //#endregion
@@ -0,0 +1,13 @@
1
+ //#region src/elements/tool-state.d.ts
2
+ /**
3
+ * Where a tool call got to: still running, finished, failed, or refused before
4
+ * it ran (cue-ui-51). The four a transcript has to tell apart at a glance.
5
+ */
6
+ type ToolState = "running" | "done" | "failed" | "refused";
7
+ /**
8
+ * What kind of nothing an empty result is (cue-ui-52): the call ran and
9
+ * returned nothing, it was refused, or it was never answered.
10
+ */
11
+ type ToolAbsence = "none" | "refused" | "unanswered";
12
+ //#endregion
13
+ export { ToolAbsence, ToolState };
@@ -0,0 +1,44 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.js";
3
+ import { jsx } from "react/jsx-runtime";
4
+ import { BanIcon, CheckIcon, XIcon } from "lucide-react";
5
+ //#region src/elements/tool-state.tsx
6
+ /**
7
+ * A tool call's vocabulary: where it got to, what kind of nothing an empty
8
+ * result is, and the mark a settled call ends its row with (cue-ui-51, 52).
9
+ *
10
+ * cue's own, shared by the vendored `ToolCall` and `ToolGroup` through
11
+ * `scripts/elements-sync` rules. It is a module of its own, not part of
12
+ * `surfaces.tsx`, because the mark draws lucide icons and `surfaces.tsx` is
13
+ * imported by subpaths, `./elements/markdown` among them, that must not pull
14
+ * `lucide-react` in.
15
+ */
16
+ /** The sentence an empty result shows for each absence. */
17
+ const ABSENCE_TEXT = {
18
+ none: "No result",
19
+ refused: "Refused",
20
+ unanswered: "Not answered"
21
+ };
22
+ /**
23
+ * One state out of `state` and the deprecated `running` flag: `state` wins,
24
+ * and without it `running` decides between running and done.
25
+ */
26
+ function resolveToolState(state, running) {
27
+ return state ?? (running ? "running" : "done");
28
+ }
29
+ /**
30
+ * The mark a settled call ends its row with: a check when done, a cross in the
31
+ * danger ink when it failed, and a muted ban when it was refused. A running
32
+ * call draws none, because its label already shimmers.
33
+ */
34
+ function ToolStateMark({ state, animated = true, className }) {
35
+ if (state === "running") return null;
36
+ return /* @__PURE__ */ jsx("span", {
37
+ "data-slot": "tool-state-mark",
38
+ "data-state": state,
39
+ className: "contents",
40
+ children: state === "done" ? /* @__PURE__ */ jsx(CheckIcon, { className: cn(animated && "cue-elements-fade-in cue-elements-zoom-in-90 cue-elements-animate-in duration-brisk", "text-ok", className) }) : state === "failed" ? /* @__PURE__ */ jsx(XIcon, { className: cn("text-danger", className) }) : /* @__PURE__ */ jsx(BanIcon, { className: cn("text-fg-muted", className) })
41
+ });
42
+ }
43
+ //#endregion
44
+ export { ABSENCE_TEXT, ToolStateMark, resolveToolState };
@@ -33,7 +33,7 @@ function ToolTimeline({ steps, visibleSteps, streaming, open, onOpenChange, rest
33
33
  className: cn("w-full max-w-sm", className),
34
34
  children: [/* @__PURE__ */ jsxs(Collapsible.Trigger, {
35
35
  className: `group/trigger text-fg-muted hover:text-fg flex items-center gap-1.5 rounded-control py-1 text-(length:--cue-text-body) transition-colors outline-none ${FOCUS_RING}`,
36
- children: [/* @__PURE__ */ jsx(ChevronRightIcon, { className: "size-3.5 shrink-0 opacity-60 transition-transform duration-200 ease-[cubic-bezier(0.32,0.72,0,1)] group-data-[panel-open]/trigger:rotate-90 motion-reduce:transition-none" }), /* @__PURE__ */ jsxs(SwapLabel, {
36
+ children: [/* @__PURE__ */ jsx(ChevronRightIcon, { className: "size-3.5 shrink-0 opacity-60 transition-transform duration-brisk ease-[cubic-bezier(0.32,0.72,0,1)] group-data-[panel-open]/trigger:rotate-90 motion-reduce:transition-none" }), /* @__PURE__ */ jsxs(SwapLabel, {
37
37
  active: streaming ? 0 : 1,
38
38
  className: "text-start tabular-nums",
39
39
  children: [/* @__PURE__ */ jsx(ShimmerLabel, {
@@ -50,7 +50,7 @@ function ToolTimeline({ steps, visibleSteps, streaming, open, onOpenChange, rest
50
50
  const Icon = step.icon;
51
51
  const active = streaming && index === shown.length - 1;
52
52
  return /* @__PURE__ */ jsxs("div", {
53
- className: "cue-elements-fade-in cue-elements-slide-in-from-bottom-1 cue-elements-animate-in cue-elements-fill-mode-both text-fg-muted flex items-center gap-2 text-(length:--cue-text-body) duration-300",
53
+ className: "cue-elements-fade-in cue-elements-slide-in-from-bottom-1 cue-elements-animate-in cue-elements-fill-mode-both text-fg-muted flex items-center gap-2 text-(length:--cue-text-body) duration-base",
54
54
  children: [
55
55
  /* @__PURE__ */ jsx(Icon, { className: "text-fg-subtle size-3.5 shrink-0" }),
56
56
  /* @__PURE__ */ jsx(ShimmerLabel, {
@@ -38,7 +38,7 @@ function TraceWaterfall({ spans, totalMs, visibleCount, className, ...props }) {
38
38
  const left = pct(item.startMs, span);
39
39
  const width = Math.max(1.5, pct(item.durationMs, span));
40
40
  return /* @__PURE__ */ jsxs("div", {
41
- className: "cue-elements-fade-in cue-elements-slide-in-from-left-1 cue-elements-animate-in cue-elements-fill-mode-both grid grid-cols-[7.5rem_1fr_2.5rem] items-center gap-2 duration-300",
41
+ className: "cue-elements-fade-in cue-elements-slide-in-from-left-1 cue-elements-animate-in cue-elements-fill-mode-both grid grid-cols-[7.5rem_1fr_2.5rem] items-center gap-2 duration-base",
42
42
  children: [
43
43
  /* @__PURE__ */ jsx("span", {
44
44
  className: "text-fg-muted min-w-0 truncate text-(length:--cue-text-ui)",
@@ -48,7 +48,7 @@ function TraceWaterfall({ spans, totalMs, visibleCount, className, ...props }) {
48
48
  /* @__PURE__ */ jsx("span", {
49
49
  className: "relative flex h-4 min-w-0 items-center",
50
50
  children: /* @__PURE__ */ jsx("span", {
51
- className: cn("absolute h-[7px] rounded-full transition-[width] duration-500 ease-out motion-reduce:transition-none", TONE[item.status], item.status === "running" && "animate-pulse"),
51
+ className: cn("absolute h-[7px] rounded-full transition-[width] duration-slow ease-out motion-reduce:transition-none", TONE[item.status], item.status === "running" && "animate-pulse"),
52
52
  style: {
53
53
  insetInlineStart: `${left}%`,
54
54
  width: `${width}%`
@@ -0,0 +1,31 @@
1
+ import { UnsupportedRequestLabels } from "./vocabulary.js";
2
+ import * as React from "react";
3
+ //#region src/elements/unsupported-request-card.d.ts
4
+ interface UnsupportedRequestCardProps extends Omit<React.ComponentPropsWithoutRef<"div">, "children"> {
5
+ /** What the agent asked for, in its words: `Pick a file`, `Open a browser`. */
6
+ title: string;
7
+ /** The request's kind as the protocol names it, printed in mono so it can be reported. */
8
+ kind?: string;
9
+ /** A supporting line: which agent asked, or what it was doing. */
10
+ detail?: string;
11
+ /** Called when the person clears the card. Dismiss is drawn only when this is set. */
12
+ onDismiss?: () => void;
13
+ /** Replace any of the card's own copy. */
14
+ labels?: Partial<UnsupportedRequestLabels>;
15
+ }
16
+ /**
17
+ * A request this client cannot answer, said plainly, with no answer offered.
18
+ *
19
+ * @example
20
+ * import { UnsupportedRequestCard } from "@cueplusplus/ui/elements";
21
+ *
22
+ * <UnsupportedRequestCard
23
+ * title="Pick a file"
24
+ * kind="file-picker"
25
+ * detail="Asked by the coding agent"
26
+ * onDismiss={() => dismiss(request.id)}
27
+ * />
28
+ */
29
+ declare const UnsupportedRequestCard: React.ForwardRefExoticComponent<UnsupportedRequestCardProps & React.RefAttributes<HTMLDivElement>>;
30
+ //#endregion
31
+ export { UnsupportedRequestCard, UnsupportedRequestCardProps };
@@ -0,0 +1,80 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.js";
3
+ import { mono, paper } from "./surfaces.js";
4
+ import { UNSUPPORTED_REQUEST_LABELS } from "./vocabulary.js";
5
+ import * as React from "react";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { CircleSlashIcon } from "lucide-react";
8
+ //#region src/elements/unsupported-request-card.tsx
9
+ /**
10
+ * A request this client cannot answer, said plainly, with no answer offered.
11
+ *
12
+ * @example
13
+ * import { UnsupportedRequestCard } from "@cueplusplus/ui/elements";
14
+ *
15
+ * <UnsupportedRequestCard
16
+ * title="Pick a file"
17
+ * kind="file-picker"
18
+ * detail="Asked by the coding agent"
19
+ * onDismiss={() => dismiss(request.id)}
20
+ * />
21
+ */
22
+ const UnsupportedRequestCard = React.forwardRef(function UnsupportedRequestCard({ title, kind, detail, onDismiss, labels, className, ...elementProps }, ref) {
23
+ const copy = {
24
+ ...UNSUPPORTED_REQUEST_LABELS,
25
+ ...labels
26
+ };
27
+ return /* @__PURE__ */ jsxs("div", {
28
+ ref,
29
+ "data-slot": "unsupported-request-card",
30
+ className: cn(paper, "flex w-full max-w-sm flex-col gap-3.5 rounded-overlay p-4", className),
31
+ ...elementProps,
32
+ children: [
33
+ /* @__PURE__ */ jsxs("div", {
34
+ className: "flex items-center gap-3",
35
+ children: [
36
+ /* @__PURE__ */ jsx("span", {
37
+ className: "bg-surface-1 text-fg-muted flex size-9 shrink-0 items-center justify-center rounded-surface",
38
+ children: /* @__PURE__ */ jsx(CircleSlashIcon, {
39
+ "aria-hidden": true,
40
+ className: "size-4"
41
+ })
42
+ }),
43
+ /* @__PURE__ */ jsxs("div", {
44
+ className: "flex min-w-0 flex-col",
45
+ children: [/* @__PURE__ */ jsx("p", {
46
+ className: "text-(length:--cue-text-body) font-medium",
47
+ children: title
48
+ }), detail === void 0 ? null : /* @__PURE__ */ jsx("p", {
49
+ className: "text-fg-muted text-(length:--cue-text-ui)",
50
+ children: detail
51
+ })]
52
+ }),
53
+ kind === void 0 ? null : /* @__PURE__ */ jsx("span", {
54
+ className: cn(mono, "text-fg-subtle ms-auto shrink-0 truncate"),
55
+ children: kind
56
+ })
57
+ ]
58
+ }),
59
+ /* @__PURE__ */ jsxs("p", {
60
+ className: "text-fg-muted text-(length:--cue-text-ui)",
61
+ children: [
62
+ copy.cannot,
63
+ " ",
64
+ copy.where
65
+ ]
66
+ }),
67
+ onDismiss === void 0 ? null : /* @__PURE__ */ jsx("div", {
68
+ className: "flex h-8 items-center justify-end",
69
+ children: /* @__PURE__ */ jsx("button", {
70
+ type: "button",
71
+ onClick: onDismiss,
72
+ className: "text-fg-muted hover:bg-surface-2 hover:text-fg h-8 rounded-full px-3.5 text-(length:--cue-text-ui) font-medium transition-[background-color,color,scale] duration-fast active:scale-[0.96]",
73
+ children: copy.dismiss
74
+ })
75
+ })
76
+ ]
77
+ });
78
+ });
79
+ //#endregion
80
+ export { UnsupportedRequestCard };
@@ -498,6 +498,55 @@ declare const PERMISSION_LABELS: {
498
498
  };
499
499
  /** The six pieces of copy a {@link PermissionScopes} draws for itself. */
500
500
  type PermissionLabels = Record<keyof typeof PERMISSION_LABELS, string>;
501
+ /** The copy an {@link EventFeed} draws for itself. */
502
+ declare const EVENT_FEED_LABELS: {
503
+ /** The chip that keeps every kind. */
504
+ readonly all: "All";
505
+ /** The accessible name of the row of chips. */
506
+ readonly filter: "Filter events";
507
+ /** What the feed says when the filter keeps nothing. */
508
+ readonly empty: "No events";
509
+ };
510
+ /** The three pieces of copy an {@link EventFeed} draws for itself. */
511
+ type EventFeedLabels = Record<keyof typeof EVENT_FEED_LABELS, string>;
512
+ /**
513
+ * Where a person's answer to an agent's request has got to (cue-ui-57).
514
+ *
515
+ * Delivery, not outcome. `sent` says the answer arrived, and it does not say
516
+ * the tool then ran: a card that drew "done" when the answer was merely
517
+ * delivered would be making a claim on the agent's behalf. The outcome is the
518
+ * card's own `state`, and once there is one it wins.
519
+ */
520
+ declare const REQUEST_DELIVERIES: readonly ["sending", "sent", "failed"];
521
+ /** One of {@link REQUEST_DELIVERIES}. */
522
+ type RequestDelivery = (typeof REQUEST_DELIVERIES)[number];
523
+ /**
524
+ * What a request card says about its answer's delivery. `failed` asks for the
525
+ * retry, because the card draws its decisions again beside it.
526
+ */
527
+ declare const DELIVERY_LABELS: Record<RequestDelivery, string>;
528
+ /** The copy a {@link QuestionCard} draws for itself. */
529
+ declare const QUESTION_LABELS: {
530
+ /** The button that sends the answer. */
531
+ readonly send: "Send";
532
+ /** The button that declines to answer, drawn only when the question can be skipped. */
533
+ readonly skip: "Skip";
534
+ /** The field's placeholder when the caller names none. */
535
+ readonly placeholder: "Type your answer";
536
+ };
537
+ /** The three pieces of copy a {@link QuestionCard} draws for itself. */
538
+ type QuestionLabels = Record<keyof typeof QUESTION_LABELS, string>;
539
+ /** The copy an {@link UnsupportedRequestCard} draws for itself. */
540
+ declare const UNSUPPORTED_REQUEST_LABELS: {
541
+ /** What the card says about itself. */
542
+ readonly cannot: "This app can't answer this request.";
543
+ /** Where the person can answer it instead. */
544
+ readonly where: "Answer it where the agent is running.";
545
+ /** The button that clears the card, drawn only when the caller can. */
546
+ readonly dismiss: "Dismiss";
547
+ };
548
+ /** The three pieces of copy an {@link UnsupportedRequestCard} draws for itself. */
549
+ type UnsupportedRequestLabels = Record<keyof typeof UNSUPPORTED_REQUEST_LABELS, string>;
501
550
  /**
502
551
  * How dangerous the runtime says this call is — OpenHands' `SecurityRisk`, in
503
552
  * its own four values.
@@ -609,4 +658,4 @@ declare const ANNOUNCEMENTS: {
609
658
  /** The nine templates a {@link LiveRegionAnnouncer} is usually fed. */
610
659
  type Announcements = Record<keyof typeof ANNOUNCEMENTS, string>;
611
660
  //#endregion
612
- export { AGENT_MODES, AGENT_MODE_DESCRIPTIONS, AGENT_MODE_LABELS, ANNOUNCEMENTS, AgentMode, Announcements, CLAMP_LABELS, COMPACTION_LABELS, COMPACTION_STATES, CONTEXT_CATEGORY_LABELS, CONTEXT_LABELS, CONTEXT_STAT_LABELS, ClampLabels, CompactionState, ContextLabels, PERMISSION_LABELS, PERMISSION_SCOPE_LABELS, PermissionLabels, QUEUE_LABELS, QueueLabels, REVERT_LABELS, REVERT_SCOPES, REVERT_SCOPE_DESCRIPTIONS, REVERT_SCOPE_LABELS, RISK_LABELS, RevertLabels, RevertScope, SECURITY_RISKS, SecurityRisk, TAIL_ACTIONS, TURN_ACTION_LABELS, TailAction, TurnActionLabels, VERB_TRIADS, VERDICT_LABELS, VerbKind, VerbTense, VerbTriad, VerdictLabels, verbFor };
661
+ export { AGENT_MODES, AGENT_MODE_DESCRIPTIONS, AGENT_MODE_LABELS, ANNOUNCEMENTS, AgentMode, Announcements, CLAMP_LABELS, COMPACTION_LABELS, COMPACTION_STATES, CONTEXT_CATEGORY_LABELS, CONTEXT_LABELS, CONTEXT_STAT_LABELS, ClampLabels, CompactionState, ContextLabels, DELIVERY_LABELS, EVENT_FEED_LABELS, EventFeedLabels, PERMISSION_LABELS, PERMISSION_SCOPE_LABELS, PermissionLabels, QUESTION_LABELS, QUEUE_LABELS, QuestionLabels, QueueLabels, REQUEST_DELIVERIES, REVERT_LABELS, REVERT_SCOPES, REVERT_SCOPE_DESCRIPTIONS, REVERT_SCOPE_LABELS, RISK_LABELS, RequestDelivery, RevertLabels, RevertScope, SECURITY_RISKS, SecurityRisk, TAIL_ACTIONS, TURN_ACTION_LABELS, TailAction, TurnActionLabels, UNSUPPORTED_REQUEST_LABELS, UnsupportedRequestLabels, VERB_TRIADS, VERDICT_LABELS, VerbKind, VerbTense, VerbTriad, VerdictLabels, verbFor };
@@ -495,6 +495,55 @@ const PERMISSION_LABELS = {
495
495
  /** What the always-allow answer says when there is no rule to name. */
496
496
  fallback: "Yes, and don't ask again"
497
497
  };
498
+ /** The copy an {@link EventFeed} draws for itself. */
499
+ const EVENT_FEED_LABELS = {
500
+ /** The chip that keeps every kind. */
501
+ all: "All",
502
+ /** The accessible name of the row of chips. */
503
+ filter: "Filter events",
504
+ /** What the feed says when the filter keeps nothing. */
505
+ empty: "No events"
506
+ };
507
+ /**
508
+ * Where a person's answer to an agent's request has got to (cue-ui-57).
509
+ *
510
+ * Delivery, not outcome. `sent` says the answer arrived, and it does not say
511
+ * the tool then ran: a card that drew "done" when the answer was merely
512
+ * delivered would be making a claim on the agent's behalf. The outcome is the
513
+ * card's own `state`, and once there is one it wins.
514
+ */
515
+ const REQUEST_DELIVERIES = [
516
+ "sending",
517
+ "sent",
518
+ "failed"
519
+ ];
520
+ /**
521
+ * What a request card says about its answer's delivery. `failed` asks for the
522
+ * retry, because the card draws its decisions again beside it.
523
+ */
524
+ const DELIVERY_LABELS = {
525
+ sending: "Sending",
526
+ sent: "Sent",
527
+ failed: "Not sent. Try again."
528
+ };
529
+ /** The copy a {@link QuestionCard} draws for itself. */
530
+ const QUESTION_LABELS = {
531
+ /** The button that sends the answer. */
532
+ send: "Send",
533
+ /** The button that declines to answer, drawn only when the question can be skipped. */
534
+ skip: "Skip",
535
+ /** The field's placeholder when the caller names none. */
536
+ placeholder: "Type your answer"
537
+ };
538
+ /** The copy an {@link UnsupportedRequestCard} draws for itself. */
539
+ const UNSUPPORTED_REQUEST_LABELS = {
540
+ /** What the card says about itself. */
541
+ cannot: "This app can't answer this request.",
542
+ /** Where the person can answer it instead. */
543
+ where: "Answer it where the agent is running.",
544
+ /** The button that clears the card, drawn only when the caller can. */
545
+ dismiss: "Dismiss"
546
+ };
498
547
  /**
499
548
  * How dangerous the runtime says this call is — OpenHands' `SecurityRisk`, in
500
549
  * its own four values.
@@ -608,4 +657,4 @@ const ANNOUNCEMENTS = {
608
657
  answer: "The agent answered: {text}"
609
658
  };
610
659
  //#endregion
611
- export { AGENT_MODES, AGENT_MODE_DESCRIPTIONS, AGENT_MODE_LABELS, ANNOUNCEMENTS, CLAMP_LABELS, COMPACTION_LABELS, COMPACTION_STATES, CONTEXT_CATEGORY_LABELS, CONTEXT_LABELS, CONTEXT_STAT_LABELS, PERMISSION_LABELS, PERMISSION_SCOPE_LABELS, QUEUE_LABELS, REVERT_LABELS, REVERT_SCOPES, REVERT_SCOPE_DESCRIPTIONS, REVERT_SCOPE_LABELS, RISK_LABELS, SECURITY_RISKS, TAIL_ACTIONS, TURN_ACTION_LABELS, VERB_TRIADS, VERDICT_LABELS, verbFor };
660
+ export { AGENT_MODES, AGENT_MODE_DESCRIPTIONS, AGENT_MODE_LABELS, ANNOUNCEMENTS, CLAMP_LABELS, COMPACTION_LABELS, COMPACTION_STATES, CONTEXT_CATEGORY_LABELS, CONTEXT_LABELS, CONTEXT_STAT_LABELS, DELIVERY_LABELS, EVENT_FEED_LABELS, PERMISSION_LABELS, PERMISSION_SCOPE_LABELS, QUESTION_LABELS, QUEUE_LABELS, REQUEST_DELIVERIES, REVERT_LABELS, REVERT_SCOPES, REVERT_SCOPE_DESCRIPTIONS, REVERT_SCOPE_LABELS, RISK_LABELS, SECURITY_RISKS, TAIL_ACTIONS, TURN_ACTION_LABELS, UNSUPPORTED_REQUEST_LABELS, VERB_TRIADS, VERDICT_LABELS, verbFor };
@@ -51,7 +51,7 @@ function VoiceConversation({ mode, amplitude, transcript, muted, onToggleMute, o
51
51
  children: [
52
52
  /* @__PURE__ */ jsx("span", {
53
53
  "aria-hidden": true,
54
- className: cn("absolute rounded-full transition-[transform,opacity] duration-200 ease-out motion-reduce:transition-none", mode === "speaking" ? "bg-stream/15" : "bg-surface-1"),
54
+ className: cn("absolute rounded-full transition-[transform,opacity] duration-brisk ease-out motion-reduce:transition-none", mode === "speaking" ? "bg-stream/15" : "bg-surface-1"),
55
55
  style: {
56
56
  width: "6rem",
57
57
  height: "6rem",
@@ -61,7 +61,7 @@ function VoiceConversation({ mode, amplitude, transcript, muted, onToggleMute, o
61
61
  }),
62
62
  /* @__PURE__ */ jsx("span", {
63
63
  "aria-hidden": true,
64
- className: cn("absolute rounded-full transition-[transform,opacity] duration-150 ease-out motion-reduce:transition-none", mode === "speaking" ? "bg-stream/25" : "bg-surface-2"),
64
+ className: cn("absolute rounded-full transition-[transform,opacity] duration-fast ease-out motion-reduce:transition-none", mode === "speaking" ? "bg-stream/25" : "bg-surface-2"),
65
65
  style: {
66
66
  width: "4.25rem",
67
67
  height: "4.25rem",
@@ -70,7 +70,7 @@ function VoiceConversation({ mode, amplitude, transcript, muted, onToggleMute, o
70
70
  }),
71
71
  /* @__PURE__ */ jsx("span", {
72
72
  "aria-hidden": true,
73
- className: cn("relative size-10 rounded-full transition-[transform,background-color] duration-150 ease-out motion-reduce:transition-none", mode === "connecting" && "bg-surface-3 animate-pulse", mode === "listening" && "bg-accent", mode === "thinking" && "bg-surface-3 animate-pulse", mode === "speaking" && "bg-stream"),
73
+ className: cn("relative size-10 rounded-full transition-[transform,background-color] duration-fast ease-out motion-reduce:transition-none", mode === "connecting" && "bg-surface-3 animate-pulse", mode === "listening" && "bg-accent", mode === "thinking" && "bg-surface-3 animate-pulse", mode === "speaking" && "bg-stream"),
74
74
  style: { transform: `scale(${active ? .9 + level * .2 : .85})` }
75
75
  })
76
76
  ]
@@ -88,7 +88,7 @@ function VoiceConversation({ mode, amplitude, transcript, muted, onToggleMute, o
88
88
  /* @__PURE__ */ jsx("div", {
89
89
  className: "flex min-h-[4.5rem] w-full flex-col gap-1.5",
90
90
  children: transcript.map((turn) => /* @__PURE__ */ jsxs("div", {
91
- className: "cue-elements-fade-in cue-elements-slide-in-from-bottom-1 cue-elements-animate-in cue-elements-fill-mode-both flex gap-2 text-(length:--cue-text-ui) leading-(--cue-leading-ui) duration-300",
91
+ className: "cue-elements-fade-in cue-elements-slide-in-from-bottom-1 cue-elements-animate-in cue-elements-fill-mode-both flex gap-2 text-(length:--cue-text-ui) leading-(--cue-leading-ui) duration-base",
92
92
  children: [/* @__PURE__ */ jsx("span", {
93
93
  className: cn(mono, "w-8 shrink-0", turn.role === "user" ? "text-fg-subtle" : "text-stream/70"),
94
94
  children: turn.role === "user" ? "you" : "ai"
@@ -113,7 +113,7 @@ function VoiceConversation({ mode, amplitude, transcript, muted, onToggleMute, o
113
113
  "aria-label": "End the call",
114
114
  onClick: onEnd,
115
115
  disabled: !onEnd,
116
- className: "flex size-10 items-center justify-center rounded-full bg-danger text-danger-fg transition-[opacity,scale] duration-150 hover:opacity-90 active:scale-[0.96] disabled:pointer-events-none disabled:opacity-30 motion-reduce:transition-none",
116
+ className: "flex size-10 items-center justify-center rounded-full bg-danger text-danger-fg transition-[opacity,scale] duration-fast hover:opacity-90 active:scale-[0.96] disabled:pointer-events-none disabled:opacity-30 motion-reduce:transition-none",
117
117
  children: /* @__PURE__ */ jsx(PhoneOffIcon, { className: "size-4" })
118
118
  })]
119
119
  })
@@ -50,7 +50,7 @@ function WebPreview({ origin, loading, children, onReload, onOpenExternal, class
50
50
  className: "border-border relative min-h-[9rem] border-t",
51
51
  children: [/* @__PURE__ */ jsx("div", {
52
52
  "aria-hidden": loading,
53
- className: cn("transition-opacity duration-300 motion-reduce:transition-none", loading && "invisible opacity-0"),
53
+ className: cn("transition-opacity duration-base motion-reduce:transition-none", loading && "invisible opacity-0"),
54
54
  children
55
55
  }), loading && /* @__PURE__ */ jsx("div", {
56
56
  className: "absolute inset-0 flex items-center justify-center",
@@ -35,14 +35,14 @@ function WebSearch({ query, results, visibleResults, searching, cycle, className
35
35
  className: "relative inline-block leading-none",
36
36
  children: "Searching"
37
37
  }) : /* @__PURE__ */ jsx("span", {
38
- className: "cue-elements-fade-in cue-elements-animate-in duration-300",
38
+ className: "cue-elements-fade-in cue-elements-animate-in duration-base",
39
39
  children: "Read 3 sources"
40
40
  })
41
41
  }),
42
42
  /* @__PURE__ */ jsx("div", {
43
43
  className: "flex min-h-[5.75rem] flex-col",
44
44
  children: take(results, visibleResults).map((result) => /* @__PURE__ */ jsxs("div", {
45
- className: "cue-elements-fade-in cue-elements-slide-in-from-bottom-1 cue-elements-animate-in cue-elements-fill-mode-both hover:bg-surface-1 -mx-2.5 flex items-center gap-2.5 rounded-surface px-2.5 py-1.5 transition-colors duration-300",
45
+ className: "cue-elements-fade-in cue-elements-slide-in-from-bottom-1 cue-elements-animate-in cue-elements-fill-mode-both hover:bg-surface-1 -mx-2.5 flex items-center gap-2.5 rounded-surface px-2.5 py-1.5 transition-colors duration-base",
46
46
  children: [
47
47
  /* @__PURE__ */ jsx("span", {
48
48
  className: "bg-surface-2 text-fg-muted flex size-4 shrink-0 items-center justify-center rounded-control text-(length:--cue-text-micro) font-medium",
@@ -115,7 +115,7 @@ const WorkCollapse = React.forwardRef(function WorkCollapse({ durationMs, toolCa
115
115
  className: `hover:bg-surface-1 -mx-2 flex items-center gap-2.5 rounded-control px-2 py-1 text-start transition-colors ${FOCUS_RING} motion-reduce:transition-none`,
116
116
  children: [/* @__PURE__ */ jsx(ChevronRightIcon, {
117
117
  "aria-hidden": true,
118
- className: cn("text-fg-subtle size-3 shrink-0 transition-transform duration-200 motion-reduce:transition-none", open && "rotate-90")
118
+ className: cn("text-fg-subtle size-3 shrink-0 transition-transform duration-brisk motion-reduce:transition-none", open && "rotate-90")
119
119
  }), /* @__PURE__ */ jsx(ShimmerLabel, {
120
120
  active: running,
121
121
  className: "text-fg-muted min-w-0 flex-1 truncate text-(length:--cue-text-ui)",
@@ -145,7 +145,7 @@ const FileUpload = React.forwardRef(function FileUpload({ className, zoneClassNa
145
145
  setDragging(false);
146
146
  intake(event.dataTransfer?.files ?? null);
147
147
  },
148
- className: cn(`flex w-full cursor-pointer flex-col items-center justify-center gap-(--cue-space-1) ${FIELD_RADIUS} border border-dashed border-border bg-sunken px-(--cue-space-4) py-(--cue-space-5) font-mono text-(length:--cue-text-ui) text-fg-muted outline-none transition-colors duration-150 hover:border-border-strong hover:text-fg ${FOCUS_RING} disabled:pointer-events-none disabled:opacity-40 data-[dragging=true]:border-accent data-[dragging=true]:bg-accent-soft data-[dragging=true]:text-fg motion-reduce:transition-none`, zoneClassName),
148
+ className: cn(`flex w-full cursor-pointer flex-col items-center justify-center gap-(--cue-space-1) ${FIELD_RADIUS} border border-dashed border-border bg-sunken px-(--cue-space-4) py-(--cue-space-5) font-mono text-(length:--cue-text-ui) text-fg-muted outline-none transition-colors duration-fast hover:border-border-strong hover:text-fg ${FOCUS_RING} disabled:pointer-events-none disabled:opacity-40 data-[dragging=true]:border-accent data-[dragging=true]:bg-accent-soft data-[dragging=true]:text-fg motion-reduce:transition-none`, zoneClassName),
149
149
  children: [/* @__PURE__ */ jsx("span", { children: label }), hint === void 0 ? null : /* @__PURE__ */ jsx("span", {
150
150
  className: "text-(length:--cue-text-label) text-fg-subtle",
151
151
  children: hint
@@ -11,7 +11,7 @@ const MARK_SIZES = {
11
11
  md: "size-icon-md",
12
12
  lg: "size-[calc(var(--cue-icon-md)*1.35)]"
13
13
  };
14
- const MARK_CLASSES = `flex cursor-pointer items-center justify-center border-0 bg-transparent p-0 text-fg-subtle transition-colors duration-150 outline-none hover:text-accent ${FOCUS_RING_OFFSET_2} disabled:pointer-events-none disabled:opacity-40 aria-checked:text-accent`;
14
+ const MARK_CLASSES = `flex cursor-pointer items-center justify-center border-0 bg-transparent p-0 text-fg-subtle transition-colors duration-fast outline-none hover:text-accent ${FOCUS_RING_OFFSET_2} disabled:pointer-events-none disabled:opacity-40 aria-checked:text-accent`;
15
15
  /**
16
16
  * A 0–N rating, drawn as marks.
17
17
  *
@@ -72,7 +72,7 @@ const Select$1 = React.forwardRef(function Select$2({ items, value, defaultValue
72
72
  alignItemWithTrigger: false,
73
73
  children: /* @__PURE__ */ jsx(Select.Popup, {
74
74
  "data-slot": "select-popup",
75
- className: cn(`min-w-(--anchor-width) origin-(--transform-origin) overflow-hidden rounded-overlay ${STROKE_SURFACE_2} ${LISTBOX_PAD} ${ELEVATION_2} outline-none`, "transition-[opacity,scale] duration-100 ease-out motion-reduce:transition-none", "data-[starting-style]:scale-[0.98] data-[starting-style]:opacity-0", "data-[ending-style]:scale-[0.98] data-[ending-style]:opacity-0", popupClassName),
75
+ className: cn(`min-w-(--anchor-width) origin-(--transform-origin) overflow-hidden rounded-overlay ${STROKE_SURFACE_2} ${LISTBOX_PAD} ${ELEVATION_2} outline-none`, "transition-[opacity,scale] duration-instant ease-out motion-reduce:transition-none", "data-[starting-style]:scale-[0.98] data-[starting-style]:opacity-0", "data-[ending-style]:scale-[0.98] data-[ending-style]:opacity-0", popupClassName),
76
76
  children: /* @__PURE__ */ jsx(Select.List, {
77
77
  className: "max-h-(--available-height) overflow-y-auto",
78
78
  children: items.map((item) => /* @__PURE__ */ jsxs(Select.Item, {
@@ -56,11 +56,11 @@ const Switch$1 = React.forwardRef(function Switch$2({ className, label, size = "
56
56
  ref,
57
57
  "data-slot": "switch",
58
58
  "aria-labelledby": hasLabel ? labelId : void 0,
59
- className: cn(`relative inline-flex shrink-0 items-center rounded-full border ${SWITCH_EDGE} bg-surface-3 p-0 outline-none transition-colors duration-150 motion-reduce:transition-none`, geometry.track, "data-[checked]:border-accent data-[checked]:bg-accent", `${FOCUS_RING}`, `data-[disabled]:pointer-events-none ${DATA_DISABLED_OPACITY} ${SWITCH_DISABLED_TRACK}`, "data-[invalid]:border-danger", className),
59
+ className: cn(`relative inline-flex shrink-0 items-center rounded-full border ${SWITCH_EDGE} bg-surface-3 p-0 outline-none transition-colors duration-fast motion-reduce:transition-none`, geometry.track, "data-[checked]:border-accent data-[checked]:bg-accent", `${FOCUS_RING}`, `data-[disabled]:pointer-events-none ${DATA_DISABLED_OPACITY} ${SWITCH_DISABLED_TRACK}`, "data-[invalid]:border-danger", className),
60
60
  ...elementProps,
61
61
  children: /* @__PURE__ */ jsx(Switch.Thumb, {
62
62
  "data-slot": "switch-thumb",
63
- className: cn(`absolute top-1/2 left-px -translate-y-1/2 rounded-full ${SWITCH_THUMB} transition-transform duration-150 motion-reduce:transition-none`, geometry.thumb, SWITCH_THUMB_CHECKED, SWITCH_THUMB_DISABLED)
63
+ className: cn(`absolute top-1/2 left-px -translate-y-1/2 rounded-full ${SWITCH_THUMB} transition-transform duration-fast motion-reduce:transition-none`, geometry.thumb, SWITCH_THUMB_CHECKED, SWITCH_THUMB_DISABLED)
64
64
  })
65
65
  });
66
66
  if (!hasLabel) return control;
@@ -16,7 +16,7 @@ import { Toggle } from "@base-ui/react/toggle";
16
16
  * the highlighted menu row. A solid accent block on a 22px control reads as a
17
17
  * second, louder button and drowns the labels beside it.
18
18
  */
19
- const toggleVariants = cva(`inline-flex shrink-0 cursor-pointer select-none items-center justify-center gap-[0.4em] whitespace-nowrap rounded-control border ${TOGGLE_EDGE} bg-transparent ${CONTROL_FACE} font-medium ${TOGGLE_INK} transition-colors duration-150 outline-none ${TOGGLE_HOVER_GROUND} ${TOGGLE_HOVER_INK} ${TOGGLE_HOVER_EDGE} ${FOCUS_RING} ${TOGGLE_PRESSED_GROUND} ${TOGGLE_PRESSED_EDGE} ${TOGGLE_PRESSED_INK} data-[disabled]:pointer-events-none ${DATA_DISABLED_OPACITY} ${TOGGLE_DISABLED}`, {
19
+ const toggleVariants = cva(`inline-flex shrink-0 cursor-pointer select-none items-center justify-center gap-[0.4em] whitespace-nowrap rounded-control border ${TOGGLE_EDGE} bg-transparent ${CONTROL_FACE} font-medium ${TOGGLE_INK} transition-colors duration-fast outline-none ${TOGGLE_HOVER_GROUND} ${TOGGLE_HOVER_INK} ${TOGGLE_HOVER_EDGE} ${FOCUS_RING} ${TOGGLE_PRESSED_GROUND} ${TOGGLE_PRESSED_EDGE} ${TOGGLE_PRESSED_INK} data-[disabled]:pointer-events-none ${DATA_DISABLED_OPACITY} ${TOGGLE_DISABLED}`, {
20
20
  variants: {
21
21
  size: {
22
22
  sm: "text-(length:--cue-text-label)",