@cueplusplus/ui 0.20.1 → 0.22.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 (236) hide show
  1. package/CHANGELOG.md +133 -0
  2. package/dist/chat/agent-pile.js +2 -2
  3. package/dist/chrome/_status-bar.js +1 -1
  4. package/dist/chrome/app-shell.js +1 -1
  5. package/dist/chrome/navigation-menu.js +3 -3
  6. package/dist/chrome/row.js +1 -1
  7. package/dist/chrome/scroll-area.js +1 -1
  8. package/dist/chrome/section-header.js +1 -1
  9. package/dist/chrome/segmented-control.js +1 -1
  10. package/dist/chrome/tabs.js +1 -1
  11. package/dist/chrome/toolbar.js +1 -1
  12. package/dist/chrome/tree.js +3 -3
  13. package/dist/date/calendar.js +3 -3
  14. package/dist/dmx/channel-matrix.js +1 -1
  15. package/dist/dmx/universe-grid.js +1 -1
  16. package/dist/elements/agent-handoff.js +3 -3
  17. package/dist/elements/agent-plan.js +1 -1
  18. package/dist/elements/agent-status.js +1 -1
  19. package/dist/elements/agent-surface.d.ts +9 -6
  20. package/dist/elements/agent-surface.js +3 -2
  21. package/dist/elements/approval-card.d.ts +29 -3
  22. package/dist/elements/approval-card.js +18 -8
  23. package/dist/elements/artifact-card.js +2 -2
  24. package/dist/elements/canvas-split.js +3 -3
  25. package/dist/elements/chart.js +1 -1
  26. package/dist/elements/chat-panel.js +2 -2
  27. package/dist/elements/checkpoint-history.js +1 -1
  28. package/dist/elements/code-diff.js +1 -1
  29. package/dist/elements/code-runner.js +1 -1
  30. package/dist/elements/composer.d.ts +8 -2
  31. package/dist/elements/composer.js +20 -12
  32. package/dist/elements/computer-use.js +2 -2
  33. package/dist/elements/confidence-marker.js +1 -1
  34. package/dist/elements/connection-state.js +2 -2
  35. package/dist/elements/context-breakdown.js +1 -1
  36. package/dist/elements/context-usage.js +1 -1
  37. package/dist/elements/conversation-search.js +2 -2
  38. package/dist/elements/cost-meter.js +1 -1
  39. package/dist/elements/data-table.js +1 -1
  40. package/dist/elements/diagram.js +1 -1
  41. package/dist/elements/draft-restore.js +2 -2
  42. package/dist/elements/edit-message.js +1 -1
  43. package/dist/elements/elements.css +134 -0
  44. package/dist/elements/elicitation-form.d.ts +8 -1
  45. package/dist/elements/elicitation-form.js +24 -16
  46. package/dist/elements/empty-state.js +3 -3
  47. package/dist/elements/error-state.js +2 -2
  48. package/dist/elements/event-feed.d.ts +88 -0
  49. package/dist/elements/event-feed.js +190 -0
  50. package/dist/elements/feedback-dialog.js +2 -2
  51. package/dist/elements/file-tree.js +1 -1
  52. package/dist/elements/flow-graph.js +2 -2
  53. package/dist/elements/generative.css +13 -0
  54. package/dist/elements/generative.d.ts +8 -6
  55. package/dist/elements/generative.js +4 -3
  56. package/dist/elements/image-generation.js +2 -2
  57. package/dist/elements/index.d.ts +7 -3
  58. package/dist/elements/index.js +5 -2
  59. package/dist/elements/inline-citation.js +1 -1
  60. package/dist/elements/job-progress.js +1 -1
  61. package/dist/elements/launcher-bubble.js +3 -3
  62. package/dist/elements/loading-state.js +1 -1
  63. package/dist/elements/map-answer.js +1 -1
  64. package/dist/elements/math-block.js +1 -1
  65. package/dist/elements/mcp-server-panel.js +3 -3
  66. package/dist/elements/memory-chips.js +1 -1
  67. package/dist/elements/message-attachment.js +3 -3
  68. package/dist/elements/message-branches.js +1 -1
  69. package/dist/elements/message-pair.js +2 -2
  70. package/dist/elements/message-queue.js +1 -1
  71. package/dist/elements/message-timing.js +1 -1
  72. package/dist/elements/mobile-composer.js +1 -1
  73. package/dist/elements/model-picker.js +1 -1
  74. package/dist/elements/number-ticker.js +1 -1
  75. package/dist/elements/onboarding.js +3 -3
  76. package/dist/elements/permission-grant.js +3 -3
  77. package/dist/elements/prompt-library.js +1 -1
  78. package/dist/elements/question-card.d.ts +50 -0
  79. package/dist/elements/question-card.js +117 -0
  80. package/dist/elements/queue-dock.js +1 -1
  81. package/dist/elements/quota-banner.js +1 -1
  82. package/dist/elements/quote-reply.js +3 -3
  83. package/dist/elements/read-aloud.js +2 -2
  84. package/dist/elements/reasoning-effort.js +2 -2
  85. package/dist/elements/reasoning-panel.js +3 -3
  86. package/dist/elements/recommendation-card.js +2 -2
  87. package/dist/elements/regenerate-menu.js +1 -1
  88. package/dist/elements/request-delivery.js +31 -0
  89. package/dist/elements/research-report.js +1 -1
  90. package/dist/elements/retrieval-chunks.js +3 -3
  91. package/dist/elements/revert-dock.js +1 -1
  92. package/dist/elements/reviewable-diff.js +4 -4
  93. package/dist/elements/schedule-card.js +2 -2
  94. package/dist/elements/score-breakdown.js +2 -2
  95. package/dist/elements/scroll-anchor.js +2 -2
  96. package/dist/elements/settings-panel.js +3 -3
  97. package/dist/elements/sources.js +1 -1
  98. package/dist/elements/spec-sheet.js +1 -1
  99. package/dist/elements/stopped-run.js +2 -2
  100. package/dist/elements/streaming-text.js +2 -2
  101. package/dist/elements/subagent-list.js +4 -4
  102. package/dist/elements/suggestions.js +1 -1
  103. package/dist/elements/surfaces.d.ts +6 -6
  104. package/dist/elements/surfaces.js +7 -7
  105. package/dist/elements/tail-status.js +1 -1
  106. package/dist/elements/terminal-block.js +1 -1
  107. package/dist/elements/thinking-indicator.js +1 -1
  108. package/dist/elements/timeline.js +1 -1
  109. package/dist/elements/todo-list.js +1 -1
  110. package/dist/elements/tool-call.d.ts +18 -2
  111. package/dist/elements/tool-call.js +20 -11
  112. package/dist/elements/tool-error.js +2 -2
  113. package/dist/elements/tool-group.d.ts +11 -3
  114. package/dist/elements/tool-group.js +62 -38
  115. package/dist/elements/tool-state.d.ts +13 -0
  116. package/dist/elements/tool-state.js +44 -0
  117. package/dist/elements/tool-timeline.js +2 -2
  118. package/dist/elements/trace-waterfall.js +2 -2
  119. package/dist/elements/unsupported-request-card.d.ts +31 -0
  120. package/dist/elements/unsupported-request-card.js +80 -0
  121. package/dist/elements/vocabulary.d.ts +50 -1
  122. package/dist/elements/vocabulary.js +50 -1
  123. package/dist/elements/voice-conversation.js +5 -5
  124. package/dist/elements/web-preview.js +1 -1
  125. package/dist/elements/web-search.js +2 -2
  126. package/dist/elements/work-collapse.js +1 -1
  127. package/dist/forms/_chassis.d.ts +6 -1
  128. package/dist/forms/_chassis.js +8 -3
  129. package/dist/forms/file-upload.js +1 -1
  130. package/dist/forms/rating.js +1 -1
  131. package/dist/forms/select.js +1 -1
  132. package/dist/forms/switch.js +2 -2
  133. package/dist/forms/toggle.js +1 -1
  134. package/dist/index.d.ts +3 -1
  135. package/dist/index.js +3 -1
  136. package/dist/instruments/_ledger-disclosure.js +1 -1
  137. package/dist/instruments/data-tree.js +1 -1
  138. package/dist/instruments/meter.js +1 -1
  139. package/dist/instruments/seam-grid.js +1 -1
  140. package/dist/layout/_collapse.js +3 -3
  141. package/dist/layout/bento.js +1 -1
  142. package/dist/layout/breadcrumb.js +1 -1
  143. package/dist/layout/carousel.js +1 -1
  144. package/dist/layout/collapsible.js +1 -1
  145. package/dist/layout/index.d.ts +3 -1
  146. package/dist/layout/index.js +3 -1
  147. package/dist/layout/item.js +1 -1
  148. package/dist/layout/link.js +1 -1
  149. package/dist/layout/pagination.js +1 -1
  150. package/dist/layout/pane-seam.d.ts +75 -0
  151. package/dist/layout/pane-seam.js +127 -0
  152. package/dist/layout/resizable.d.ts +2 -1
  153. package/dist/layout/resizable.js +3 -2
  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 +5 -5
  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 +52 -0
  168. package/dist/system/_paint-stroke-sunken.js +22 -2
  169. package/dist/system/_paint-stroke-surface-1.js +5 -1
  170. package/dist/system/_paint-stroke-surface-2.js +5 -1
  171. package/dist/system/_style-disabled.js +1 -7
  172. package/dist/system/agent-skin.d.ts +11 -5
  173. package/manifest/components/agent-surface.json +5 -4
  174. package/manifest/components/alert-dialog.json +1 -0
  175. package/manifest/components/approval-card.json +45 -7
  176. package/manifest/components/autocomplete.json +2 -0
  177. package/manifest/components/button.json +0 -3
  178. package/manifest/components/card.json +1 -0
  179. package/manifest/components/channel-matrix.json +1 -0
  180. package/manifest/components/chart-tooltip-content.json +1 -0
  181. package/manifest/components/checkbox-group.json +0 -3
  182. package/manifest/components/checkbox.json +0 -3
  183. package/manifest/components/color-field.json +1 -0
  184. package/manifest/components/color-picker.json +1 -0
  185. package/manifest/components/combobox.json +2 -0
  186. package/manifest/components/command-palette.json +1 -0
  187. package/manifest/components/composer-input.json +16 -2
  188. package/manifest/components/composer.json +1 -0
  189. package/manifest/components/context-menu.json +1 -0
  190. package/manifest/components/date-field.json +1 -0
  191. package/manifest/components/date-picker.json +1 -0
  192. package/manifest/components/date-range-picker.json +1 -0
  193. package/manifest/components/dialog.json +1 -0
  194. package/manifest/components/dmx-bar.json +1 -0
  195. package/manifest/components/dmx-strip.json +1 -0
  196. package/manifest/components/drawer.json +1 -0
  197. package/manifest/components/dropdown-menu.json +1 -0
  198. package/manifest/components/elicitation-form.json +16 -1
  199. package/manifest/components/env-var-input.json +1 -0
  200. package/manifest/components/event-feed.json +171 -0
  201. package/manifest/components/event-row.json +116 -0
  202. package/manifest/components/generative-ui.json +4 -3
  203. package/manifest/components/hover-card.json +1 -0
  204. package/manifest/components/input-group.json +1 -0
  205. package/manifest/components/input.json +1 -0
  206. package/manifest/components/menubar.json +1 -0
  207. package/manifest/components/multi-select.json +2 -0
  208. package/manifest/components/musical-time-input.json +1 -0
  209. package/manifest/components/navigation-menu.json +1 -0
  210. package/manifest/components/number-field.json +1 -0
  211. package/manifest/components/otp-field.json +1 -0
  212. package/manifest/components/pane-seam.json +171 -0
  213. package/manifest/components/password-input.json +1 -0
  214. package/manifest/components/popover.json +1 -0
  215. package/manifest/components/question-card.json +157 -0
  216. package/manifest/components/resizable.json +1 -1
  217. package/manifest/components/scrub-input.json +1 -0
  218. package/manifest/components/search-input.json +1 -0
  219. package/manifest/components/select.json +2 -0
  220. package/manifest/components/sheet.json +1 -0
  221. package/manifest/components/split-pane.json +224 -0
  222. package/manifest/components/switch.json +0 -3
  223. package/manifest/components/tags-input.json +2 -0
  224. package/manifest/components/textarea.json +1 -0
  225. package/manifest/components/theme-configurator.json +1 -0
  226. package/manifest/components/time-field.json +1 -0
  227. package/manifest/components/toast.json +1 -0
  228. package/manifest/components/toggle.json +0 -3
  229. package/manifest/components/tool-call.json +46 -2
  230. package/manifest/components/tool-group.json +15 -3
  231. package/manifest/components/tooltip.json +1 -0
  232. package/manifest/components/unsupported-request-card.json +117 -0
  233. package/manifest/fixtures.json +16 -0
  234. package/manifest/manifest.json +134 -56
  235. package/manifest/tokens.json +12 -2
  236. package/package.json +3 -3
@@ -60,7 +60,7 @@ function McpServerPanel({ servers, expandedId, onToggle, onAuthorize, className,
60
60
  onClick: () => onToggle?.(server.id),
61
61
  className: "hover:bg-surface-1 flex items-center gap-2.5 rounded-surface px-1.5 py-2 text-start transition-colors",
62
62
  children: [
63
- /* @__PURE__ */ jsx(ChevronRightIcon, { className: cn("text-fg-subtle size-3 shrink-0 transition-transform duration-200 motion-reduce:transition-none", expanded && "rotate-90") }),
63
+ /* @__PURE__ */ jsx(ChevronRightIcon, { className: cn("text-fg-subtle size-3 shrink-0 transition-transform duration-brisk motion-reduce:transition-none", expanded && "rotate-90") }),
64
64
  /* @__PURE__ */ jsx(PlugIcon, { className: "text-fg-subtle size-3.5 shrink-0" }),
65
65
  /* @__PURE__ */ jsx("span", {
66
66
  className: "min-w-0 flex-1 truncate text-(length:--cue-text-body)",
@@ -80,7 +80,7 @@ function McpServerPanel({ servers, expandedId, onToggle, onAuthorize, className,
80
80
  })
81
81
  ]
82
82
  }), expanded && /* @__PURE__ */ jsxs("div", {
83
- className: "cue-elements-fade-in cue-elements-slide-in-from-top-1 cue-elements-animate-in flex flex-col gap-1.5 px-1.5 ps-8 pb-2 duration-200",
83
+ className: "cue-elements-fade-in cue-elements-slide-in-from-top-1 cue-elements-animate-in flex flex-col gap-1.5 px-1.5 ps-8 pb-2 duration-brisk",
84
84
  children: [/* @__PURE__ */ jsxs("div", {
85
85
  className: "flex items-center gap-2",
86
86
  children: [
@@ -95,7 +95,7 @@ function McpServerPanel({ servers, expandedId, onToggle, onAuthorize, className,
95
95
  server.status === "needs-auth" && onAuthorize && /* @__PURE__ */ jsx("button", {
96
96
  type: "button",
97
97
  onClick: () => onAuthorize?.(server.id),
98
- className: "ms-auto rounded-full bg-warn/15 px-2 py-0.5 text-(length:--cue-text-label) font-medium text-warn transition-[background-color,scale] duration-150 hover:bg-warn/25 active:scale-[0.96]",
98
+ className: "ms-auto rounded-full bg-warn/15 px-2 py-0.5 text-(length:--cue-text-label) font-medium text-warn transition-[background-color,scale] duration-fast hover:bg-warn/25 active:scale-[0.96]",
99
99
  children: "Authorize"
100
100
  })
101
101
  ]
@@ -27,7 +27,7 @@ function MemoryChips({ chips, onForget, className, ...props }) {
27
27
  }), /* @__PURE__ */ jsx("div", {
28
28
  className: "flex flex-wrap gap-1.5",
29
29
  children: chips.map((chip) => /* @__PURE__ */ jsxs("span", {
30
- className: cn("cue-elements-fade-in cue-elements-zoom-in-95 cue-elements-animate-in cue-elements-fill-mode-both group flex items-center gap-1 rounded-full py-1 pr-1 pl-2.5 text-(length:--cue-text-ui) duration-300", chip.change === "existing" ? cn(field, "text-fg-muted") : "bg-stream/15 text-stream"),
30
+ className: cn("cue-elements-fade-in cue-elements-zoom-in-95 cue-elements-animate-in cue-elements-fill-mode-both group flex items-center gap-1 rounded-full py-1 pr-1 pl-2.5 text-(length:--cue-text-ui) duration-base", chip.change === "existing" ? cn(field, "text-fg-muted") : "bg-stream/15 text-stream"),
31
31
  children: [chip.text, /* @__PURE__ */ jsx("button", {
32
32
  type: "button",
33
33
  "aria-label": `Forget "${chip.text}"`,
@@ -17,11 +17,11 @@ function MessageAttachments({ attachments, onOpen, className, ...props }) {
17
17
  children: attachments.map((item) => item.kind === "image" ? /* @__PURE__ */ jsxs("button", {
18
18
  type: "button",
19
19
  onClick: () => onOpen?.(item.id),
20
- className: cn(paper, "cue-elements-fade-in cue-elements-animate-in cue-elements-fill-mode-both group flex w-full items-center gap-3 overflow-hidden rounded-overlay p-2 text-start duration-300"),
20
+ className: cn(paper, "cue-elements-fade-in cue-elements-animate-in cue-elements-fill-mode-both group flex w-full items-center gap-3 overflow-hidden rounded-overlay p-2 text-start duration-base"),
21
21
  children: [
22
22
  /* @__PURE__ */ jsx("span", {
23
23
  "aria-hidden": true,
24
- className: "size-12 shrink-0 rounded-surface bg-cover bg-center transition-transform duration-300 group-hover:scale-[1.04] motion-reduce:transition-none",
24
+ className: "size-12 shrink-0 rounded-surface bg-cover bg-center transition-transform duration-base group-hover:scale-[1.04] motion-reduce:transition-none",
25
25
  style: {
26
26
  backgroundImage: item.swatch,
27
27
  backgroundColor: "var(--cue-fg)"
@@ -42,7 +42,7 @@ function MessageAttachments({ attachments, onOpen, className, ...props }) {
42
42
  }, item.id) : /* @__PURE__ */ jsxs("button", {
43
43
  type: "button",
44
44
  onClick: () => onOpen?.(item.id),
45
- className: cn(field, "cue-elements-fade-in cue-elements-animate-in cue-elements-fill-mode-both hover:bg-surface-2 flex w-full items-center gap-2.5 rounded-overlay px-3 py-2.5 text-start transition-colors duration-300"),
45
+ className: cn(field, "cue-elements-fade-in cue-elements-animate-in cue-elements-fill-mode-both hover:bg-surface-2 flex w-full items-center gap-2.5 rounded-overlay px-3 py-2.5 text-start transition-colors duration-base"),
46
46
  children: [/* @__PURE__ */ jsx("span", {
47
47
  className: "bg-bg text-fg-muted flex size-8 shrink-0 items-center justify-center rounded-surface",
48
48
  children: item.kind === "document" ? /* @__PURE__ */ jsx(FileTextIcon, { className: "size-3.5" }) : /* @__PURE__ */ jsx(PaperclipIcon, { className: "size-3.5" })
@@ -32,7 +32,7 @@ function MessageBranches({ variants, index, onIndexChange, className, ...props }
32
32
  className: cn("flex max-w-sm flex-col gap-2", className),
33
33
  ...props,
34
34
  children: [/* @__PURE__ */ jsx("p", {
35
- className: "cue-elements-fade-in cue-elements-slide-in-from-bottom-1 cue-elements-animate-in text-fg min-h-[4.25rem] text-(length:--cue-text-body) leading-(--cue-leading-ui) duration-300 motion-reduce:animate-none",
35
+ className: "cue-elements-fade-in cue-elements-slide-in-from-bottom-1 cue-elements-animate-in text-fg min-h-[4.25rem] text-(length:--cue-text-body) leading-(--cue-leading-ui) duration-base motion-reduce:animate-none",
36
36
  children: message
37
37
  }, index), /* @__PURE__ */ jsxs("div", {
38
38
  className: "flex items-center gap-1",
@@ -34,9 +34,9 @@ function MessagePair({ userMessage, words, visibleWords, streaming, variant = "b
34
34
  children: [shown.map((word, index) => {
35
35
  const fresh = streaming && shown.length - 1 - index < 2;
36
36
  return /* @__PURE__ */ jsxs("span", {
37
- className: "cue-elements-fade-in cue-elements-animate-in cue-elements-fill-mode-both duration-500 motion-reduce:animate-none",
37
+ className: "cue-elements-fade-in cue-elements-animate-in cue-elements-fill-mode-both duration-slow motion-reduce:animate-none",
38
38
  children: [/* @__PURE__ */ jsx("span", {
39
- className: cn("transition-colors duration-700 motion-reduce:transition-none", fresh && "text-stream"),
39
+ className: cn("transition-colors duration-slower motion-reduce:transition-none", fresh && "text-stream"),
40
40
  children: word
41
41
  }), " "]
42
42
  }, `${word}-${index}`);
@@ -52,7 +52,7 @@ function MessageQueue({ running, queued, onCancel, className, ...props }) {
52
52
  /* @__PURE__ */ jsx("ul", {
53
53
  className: "flex flex-col gap-1.5",
54
54
  children: queued.map((message, index) => /* @__PURE__ */ jsxs("li", {
55
- className: cn(field, "cue-elements-fade-in cue-elements-slide-in-from-bottom-1 cue-elements-animate-in cue-elements-fill-mode-both flex items-center gap-2.5 rounded-overlay py-2 pr-2 pl-3 duration-300"),
55
+ className: cn(field, "cue-elements-fade-in cue-elements-slide-in-from-bottom-1 cue-elements-animate-in cue-elements-fill-mode-both flex items-center gap-2.5 rounded-overlay py-2 pr-2 pl-3 duration-base"),
56
56
  children: [
57
57
  /* @__PURE__ */ jsx("span", {
58
58
  className: cn(mono, "text-fg-subtle w-3 shrink-0 tabular-nums"),
@@ -19,7 +19,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
19
19
  function MessageTiming({ stats, streaming, className, ...props }) {
20
20
  return /* @__PURE__ */ jsx("div", {
21
21
  "data-slot": "message-timing",
22
- className: cn("cue-elements-fade-in cue-elements-animate-in flex w-full max-w-sm flex-wrap items-center gap-x-3 gap-y-1 duration-500", className),
22
+ className: cn("cue-elements-fade-in cue-elements-animate-in flex w-full max-w-sm flex-wrap items-center gap-x-3 gap-y-1 duration-slow", className),
23
23
  ...props,
24
24
  children: stats.map((stat) => /* @__PURE__ */ jsxs("span", {
25
25
  className: "flex items-baseline gap-1",
@@ -27,7 +27,7 @@ function MobileComposer({ value, keyboardOpen, running, actions, onAction, onAtt
27
27
  ...props,
28
28
  children: [
29
29
  !keyboardOpen && /* @__PURE__ */ jsx("div", {
30
- className: "cue-elements-fade-in cue-elements-animate-in -mx-3 flex gap-1.5 overflow-x-auto px-3 pb-0.5 duration-200",
30
+ className: "cue-elements-fade-in cue-elements-animate-in -mx-3 flex gap-1.5 overflow-x-auto px-3 pb-0.5 duration-brisk",
31
31
  children: actions.map((action) => /* @__PURE__ */ jsx("button", {
32
32
  type: "button",
33
33
  onClick: () => onAction?.(action),
@@ -34,7 +34,7 @@ function ModelPicker({ models, selectedId, onSelect, className, ...props }) {
34
34
  children: [
35
35
  /* @__PURE__ */ jsx("span", {
36
36
  className: "flex size-3.5 shrink-0 items-center justify-center",
37
- children: selected && /* @__PURE__ */ jsx(CheckIcon, { className: "cue-elements-fade-in cue-elements-zoom-in-90 cue-elements-animate-in text-fg-muted size-3.5 duration-200" })
37
+ children: selected && /* @__PURE__ */ jsx(CheckIcon, { className: "cue-elements-fade-in cue-elements-zoom-in-90 cue-elements-animate-in text-fg-muted size-3.5 duration-brisk" })
38
38
  }),
39
39
  /* @__PURE__ */ jsxs("span", {
40
40
  className: "flex min-w-0 flex-1 flex-col gap-1",
@@ -7,7 +7,7 @@ function RollingDigit({ digit }) {
7
7
  return /* @__PURE__ */ jsx("span", {
8
8
  className: "inline-flex h-[1.15em] overflow-hidden",
9
9
  children: /* @__PURE__ */ jsx("span", {
10
- className: "flex flex-col transition-transform duration-500 ease-[cubic-bezier(0.32,0.72,0,1)] motion-reduce:transition-none",
10
+ className: "flex flex-col transition-transform duration-slow ease-[cubic-bezier(0.32,0.72,0,1)] motion-reduce:transition-none",
11
11
  style: { transform: `translateY(-${digit * 1.15}em)` },
12
12
  children: Array.from({ length: 10 }, (_, i) => /* @__PURE__ */ jsx("span", {
13
13
  className: "h-[1.15em] leading-[1.15]",
@@ -22,7 +22,7 @@ function Onboarding({ steps, index, onNext, onSkip, className, ...props }) {
22
22
  className: cn(paper, "flex w-full max-w-sm flex-col gap-4 rounded-overlay p-5", className),
23
23
  ...props,
24
24
  children: [/* @__PURE__ */ jsxs("div", {
25
- className: "cue-elements-fade-in cue-elements-animate-in flex flex-col gap-2 duration-300",
25
+ className: "cue-elements-fade-in cue-elements-animate-in flex flex-col gap-2 duration-base",
26
26
  children: [
27
27
  /* @__PURE__ */ jsxs("span", {
28
28
  className: cn(mono, "text-fg-subtle tabular-nums"),
@@ -52,13 +52,13 @@ function Onboarding({ steps, index, onNext, onSkip, className, ...props }) {
52
52
  className: "flex gap-1.5",
53
53
  children: steps.map((_, i) => /* @__PURE__ */ jsx("span", {
54
54
  "aria-hidden": true,
55
- className: cn("h-1 rounded-full transition-all duration-300 motion-reduce:transition-none", i === current ? "bg-accent w-4" : "bg-surface-3 w-1")
55
+ className: cn("h-1 rounded-full transition-all duration-base motion-reduce:transition-none", i === current ? "bg-accent w-4" : "bg-surface-3 w-1")
56
56
  }, i))
57
57
  }),
58
58
  /* @__PURE__ */ jsx("button", {
59
59
  type: "button",
60
60
  onClick: onSkip,
61
- className: "text-fg-muted hover:bg-surface-2 hover:text-fg ms-auto h-8 rounded-full px-3 text-(length:--cue-text-ui) font-medium transition-[background-color,color,scale] duration-150 active:scale-[0.96]",
61
+ className: "text-fg-muted hover:bg-surface-2 hover:text-fg ms-auto h-8 rounded-full px-3 text-(length:--cue-text-ui) font-medium transition-[background-color,color,scale] duration-fast active:scale-[0.96]",
62
62
  children: "Skip"
63
63
  }),
64
64
  /* @__PURE__ */ jsx("button", {
@@ -59,13 +59,13 @@ function PermissionGrant({ capability, requester, reach, scope, onGrant, classNa
59
59
  /* @__PURE__ */ jsx("button", {
60
60
  type: "button",
61
61
  onClick: () => onGrant?.("denied"),
62
- className: "text-fg-muted hover:bg-surface-2 hover:text-fg h-8 rounded-full px-3 text-(length:--cue-text-ui) font-medium transition-[background-color,color,scale] duration-150 active:scale-[0.96]",
62
+ className: "text-fg-muted hover:bg-surface-2 hover:text-fg h-8 rounded-full px-3 text-(length:--cue-text-ui) font-medium transition-[background-color,color,scale] duration-fast active:scale-[0.96]",
63
63
  children: "Deny"
64
64
  }),
65
65
  /* @__PURE__ */ jsx("button", {
66
66
  type: "button",
67
67
  onClick: () => onGrant?.("session"),
68
- className: "text-fg-muted hover:bg-surface-2 hover:text-fg h-8 rounded-full px-3 text-(length:--cue-text-ui) font-medium transition-[background-color,color,scale] duration-150 active:scale-[0.96]",
68
+ className: "text-fg-muted hover:bg-surface-2 hover:text-fg h-8 rounded-full px-3 text-(length:--cue-text-ui) font-medium transition-[background-color,color,scale] duration-fast active:scale-[0.96]",
69
69
  children: "This session"
70
70
  }),
71
71
  /* @__PURE__ */ jsx("button", {
@@ -75,7 +75,7 @@ function PermissionGrant({ capability, requester, reach, scope, onGrant, classNa
75
75
  children: "Always"
76
76
  })
77
77
  ] }) : /* @__PURE__ */ jsx("span", {
78
- className: cn(field, mono, "cue-elements-fade-in cue-elements-animate-in text-fg-muted rounded-full px-2.5 py-1.5 duration-300"),
78
+ className: cn(field, mono, "cue-elements-fade-in cue-elements-animate-in text-fg-muted rounded-full px-2.5 py-1.5 duration-base"),
79
79
  children: scope === "denied" ? "denied" : `granted · ${scope}`
80
80
  }, scope)
81
81
  })
@@ -99,7 +99,7 @@ function PromptLibrary({ prompts, query, selectedId, onQueryChange, onSelect, on
99
99
  ]
100
100
  }),
101
101
  selected && /* @__PURE__ */ jsxs("div", {
102
- className: cn("bg-fg/[0.06]", "cue-elements-fade-in cue-elements-animate-in flex flex-col gap-2 rounded-surface p-2.5 duration-200"),
102
+ className: cn("bg-fg/[0.06]", "cue-elements-fade-in cue-elements-animate-in flex flex-col gap-2 rounded-surface p-2.5 duration-brisk"),
103
103
  children: [/* @__PURE__ */ jsx("p", {
104
104
  className: "text-fg-muted text-(length:--cue-text-ui) leading-(--cue-leading-ui) break-words",
105
105
  children: selected.body
@@ -0,0 +1,50 @@
1
+ import { QuestionLabels, RequestDelivery } from "./vocabulary.js";
2
+ import * as React from "react";
3
+ //#region src/elements/question-card.d.ts
4
+ interface QuestionCardProps extends Omit<React.ComponentPropsWithoutRef<"div">, "children" | "onSubmit"> {
5
+ /** What the agent asked, in its own words. It also names the answer field. */
6
+ question: string;
7
+ /** A supporting line under the question: who is asking, or why. */
8
+ context?: string;
9
+ /** The field's resting text. Defaults to `QUESTION_LABELS.placeholder`. */
10
+ placeholder?: string;
11
+ /**
12
+ * The answer as the caller holds it. Drawn as sent while `delivery` is
13
+ * `sending` or `sent`, and put back in the field when it is `failed`, so a
14
+ * retry is one press.
15
+ */
16
+ answer?: string;
17
+ /**
18
+ * Where the answer has got to: `sending`, `sent` or `failed`. Unset while
19
+ * the question is still waiting on the person.
20
+ */
21
+ delivery?: RequestDelivery;
22
+ /** Called with the typed answer, trimmed, when the person sends it. */
23
+ onAnswer?: (answer: string) => void;
24
+ /** Called when the person skips the question. Skip is drawn only when this is set. */
25
+ onDismiss?: () => void;
26
+ /** Replace any of the card's own copy. */
27
+ labels?: Partial<QuestionLabels>;
28
+ }
29
+ /**
30
+ * An agent's free-text question, answered in place.
31
+ *
32
+ * The answer is the caller's to deliver. The card reports it through
33
+ * `onAnswer` and says where it has got to from `delivery`: on its way, arrived,
34
+ * or not arrived. It never claims more than that.
35
+ *
36
+ * @example
37
+ * import { QuestionCard } from "@cueplusplus/ui/elements";
38
+ *
39
+ * <QuestionCard
40
+ * question="Which branch should I deploy?"
41
+ * context="Asked by the release agent"
42
+ * onAnswer={(text) => reply(request.id, text)}
43
+ * />
44
+ * @example
45
+ * // While the answer travels, the card shows it and takes no other.
46
+ * <QuestionCard question="Which branch?" answer="main" delivery="sending" />
47
+ */
48
+ declare const QuestionCard: React.ForwardRefExoticComponent<QuestionCardProps & React.RefAttributes<HTMLDivElement>>;
49
+ //#endregion
50
+ export { QuestionCard, QuestionCardProps };
@@ -0,0 +1,117 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.js";
3
+ import { FOCUS_RING } from "../system/_focus-ring.js";
4
+ import { field, inkButton, paper } from "./surfaces.js";
5
+ import { QUESTION_LABELS } from "./vocabulary.js";
6
+ import { DeliveryNote } from "./request-delivery.js";
7
+ import { useAutoGrow } from "../lib/auto-grow.js";
8
+ import * as React from "react";
9
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
+ import { MessageCircleQuestionIcon } from "lucide-react";
11
+ //#region src/elements/question-card.tsx
12
+ /**
13
+ * An agent's free-text question, answered in place.
14
+ *
15
+ * The answer is the caller's to deliver. The card reports it through
16
+ * `onAnswer` and says where it has got to from `delivery`: on its way, arrived,
17
+ * or not arrived. It never claims more than that.
18
+ *
19
+ * @example
20
+ * import { QuestionCard } from "@cueplusplus/ui/elements";
21
+ *
22
+ * <QuestionCard
23
+ * question="Which branch should I deploy?"
24
+ * context="Asked by the release agent"
25
+ * onAnswer={(text) => reply(request.id, text)}
26
+ * />
27
+ * @example
28
+ * // While the answer travels, the card shows it and takes no other.
29
+ * <QuestionCard question="Which branch?" answer="main" delivery="sending" />
30
+ */
31
+ const QuestionCard = React.forwardRef(function QuestionCard({ question, context, placeholder, answer, delivery, onAnswer, onDismiss, labels, className, ...elementProps }, ref) {
32
+ const copy = {
33
+ ...QUESTION_LABELS,
34
+ ...labels
35
+ };
36
+ const questionId = React.useId();
37
+ const [draft, setDraft] = React.useState(answer ?? "");
38
+ const { ref: grow } = useAutoGrow(draft);
39
+ React.useEffect(() => {
40
+ if (answer !== void 0) setDraft(answer);
41
+ }, [answer]);
42
+ const locked = delivery === "sending" || delivery === "sent";
43
+ const text = draft.trim();
44
+ const send = () => {
45
+ if (text !== "") onAnswer?.(text);
46
+ };
47
+ return /* @__PURE__ */ jsxs("div", {
48
+ ref,
49
+ "data-slot": "question-card",
50
+ "data-delivery": delivery,
51
+ className: cn(paper, "flex w-full max-w-sm flex-col gap-3.5 rounded-overlay p-4", className),
52
+ ...elementProps,
53
+ children: [
54
+ /* @__PURE__ */ jsxs("div", {
55
+ className: "flex items-center gap-3",
56
+ children: [/* @__PURE__ */ jsx("span", {
57
+ className: "bg-surface-1 text-fg-muted flex size-9 shrink-0 items-center justify-center rounded-surface",
58
+ children: /* @__PURE__ */ jsx(MessageCircleQuestionIcon, {
59
+ "aria-hidden": true,
60
+ className: "size-4"
61
+ })
62
+ }), /* @__PURE__ */ jsxs("div", {
63
+ className: "flex flex-col",
64
+ children: [/* @__PURE__ */ jsx("p", {
65
+ id: questionId,
66
+ className: "text-(length:--cue-text-body) font-medium",
67
+ children: question
68
+ }), context === void 0 ? null : /* @__PURE__ */ jsx("p", {
69
+ className: "text-fg-muted text-(length:--cue-text-ui)",
70
+ children: context
71
+ })]
72
+ })]
73
+ }),
74
+ locked ? /* @__PURE__ */ jsx("p", {
75
+ className: cn(field, "text-fg-muted rounded-surface px-3.5 py-2.5 text-(length:--cue-text-body) whitespace-pre-wrap"),
76
+ children: answer ?? draft
77
+ }) : /* @__PURE__ */ jsx("textarea", {
78
+ ref: grow,
79
+ rows: 2,
80
+ "aria-labelledby": questionId,
81
+ value: draft,
82
+ placeholder: placeholder ?? copy.placeholder,
83
+ onChange: (event) => setDraft(event.target.value),
84
+ onKeyDown: (event) => {
85
+ if (event.key !== "Enter" || event.shiftKey || event.nativeEvent.isComposing) return;
86
+ event.preventDefault();
87
+ send();
88
+ },
89
+ className: cn(field, `placeholder:text-fg-subtle max-h-48 w-full resize-none rounded-surface px-3.5 py-2.5 text-(length:--cue-text-body) outline-none field-sizing-content ${FOCUS_RING}`)
90
+ }),
91
+ /* @__PURE__ */ jsx("div", {
92
+ className: "flex min-h-8 flex-wrap items-center justify-end gap-2",
93
+ children: delivery === "sending" || delivery === "sent" ? /* @__PURE__ */ jsx(DeliveryNote, { delivery }) : /* @__PURE__ */ jsxs(Fragment, { children: [
94
+ delivery === "failed" ? /* @__PURE__ */ jsx(DeliveryNote, {
95
+ delivery: "failed",
96
+ className: "me-auto"
97
+ }) : null,
98
+ onDismiss === void 0 ? null : /* @__PURE__ */ jsx("button", {
99
+ type: "button",
100
+ onClick: onDismiss,
101
+ 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]",
102
+ children: copy.skip
103
+ }),
104
+ /* @__PURE__ */ jsx("button", {
105
+ type: "button",
106
+ disabled: text === "",
107
+ onClick: send,
108
+ className: cn(inkButton, "flex h-8 items-center rounded-full px-3.5 text-(length:--cue-text-ui) font-medium disabled:opacity-50"),
109
+ children: copy.send
110
+ })
111
+ ] })
112
+ })
113
+ ]
114
+ });
115
+ });
116
+ //#endregion
117
+ export { QuestionCard };
@@ -84,7 +84,7 @@ const QueueDock = React.forwardRef(function QueueDock({ messages, open, onOpenCh
84
84
  className: `hover:bg-surface-2 flex items-center gap-2.5 rounded-overlay px-3 py-2 text-start transition-colors ${FOCUS_RING_INSET_2} motion-reduce:transition-none`,
85
85
  children: [/* @__PURE__ */ jsx(ChevronRightIcon, {
86
86
  "aria-hidden": true,
87
- className: cn("text-fg-subtle size-3 shrink-0 transition-transform duration-200 motion-reduce:transition-none", open && "rotate-90")
87
+ className: cn("text-fg-subtle size-3 shrink-0 transition-transform duration-brisk motion-reduce:transition-none", open && "rotate-90")
88
88
  }), /* @__PURE__ */ jsx("span", {
89
89
  className: "text-fg-muted min-w-0 flex-1 truncate text-(length:--cue-text-ui)",
90
90
  children: said
@@ -38,7 +38,7 @@ function QuotaBanner({ used, limit, unit, resetsIn, upgradeLabel, onUpgrade, cla
38
38
  /* @__PURE__ */ jsx("span", {
39
39
  className: "bg-surface-2 h-1 w-full overflow-hidden rounded-full",
40
40
  children: /* @__PURE__ */ jsx("span", {
41
- className: cn("block h-full rounded-full transition-[width] duration-500 motion-reduce:transition-none", tight ? "bg-warn" : "bg-surface-3"),
41
+ className: cn("block h-full rounded-full transition-[width] duration-slow motion-reduce:transition-none", tight ? "bg-warn" : "bg-surface-3"),
42
42
  style: { width: `${pct(used, limit)}%` }
43
43
  })
44
44
  }),
@@ -50,20 +50,20 @@ function QuoteReply({ before, selection, after, actions, toolbarVisible, quoted,
50
50
  /* @__PURE__ */ jsx("div", {
51
51
  className: "flex h-9 items-start",
52
52
  children: toolbarVisible && /* @__PURE__ */ jsx("div", {
53
- className: cn("bg-surface-2 border border-border-overlay", "cue-elements-fade-in cue-elements-zoom-in-95 cue-elements-slide-in-from-top-1 cue-elements-animate-in flex items-center gap-0.5 rounded-full p-1 duration-200"),
53
+ className: cn("bg-surface-2 border border-border-overlay", "cue-elements-fade-in cue-elements-zoom-in-95 cue-elements-slide-in-from-top-1 cue-elements-animate-in flex items-center gap-0.5 rounded-full p-1 duration-brisk"),
54
54
  children: actions.map((action) => {
55
55
  const Icon = ICON[action.icon];
56
56
  return /* @__PURE__ */ jsxs("button", {
57
57
  type: "button",
58
58
  onClick: () => onAction?.(action.key),
59
- className: "text-fg-muted hover:bg-surface-2 hover:text-fg flex h-7 items-center gap-1.5 rounded-full px-2.5 text-(length:--cue-text-ui) font-medium transition-[background-color,color,scale] duration-150 active:scale-[0.96]",
59
+ className: "text-fg-muted hover:bg-surface-2 hover:text-fg flex h-7 items-center gap-1.5 rounded-full px-2.5 text-(length:--cue-text-ui) font-medium transition-[background-color,color,scale] duration-fast active:scale-[0.96]",
60
60
  children: [/* @__PURE__ */ jsx(Icon, { className: "size-3.5" }), action.label]
61
61
  }, action.key);
62
62
  })
63
63
  })
64
64
  }),
65
65
  quoted && /* @__PURE__ */ jsxs("div", {
66
- className: "cue-elements-fade-in cue-elements-slide-in-from-bottom-1 cue-elements-animate-in flex flex-col gap-1 duration-300",
66
+ className: "cue-elements-fade-in cue-elements-slide-in-from-bottom-1 cue-elements-animate-in flex flex-col gap-1 duration-base",
67
67
  children: [/* @__PURE__ */ jsx("span", {
68
68
  className: cn("font-mono text-(length:--cue-text-label) tracking-tight", "text-fg-subtle"),
69
69
  children: "replying to"
@@ -31,7 +31,7 @@ function ReadAloud({ words, spokenIndex, playing, rate, elapsed, duration, onTog
31
31
  children: [/* @__PURE__ */ jsx("p", {
32
32
  className: "text-(length:--cue-text-body) leading-(--cue-leading-ui)",
33
33
  children: words.map((word, i) => /* @__PURE__ */ jsxs("span", {
34
- className: cn("transition-colors duration-200 motion-reduce:transition-none", i < spokenIndex ? "text-fg-subtle" : i === spokenIndex ? "text-fg rounded-control bg-stream/15" : "text-fg-muted"),
34
+ className: cn("transition-colors duration-brisk motion-reduce:transition-none", i < spokenIndex ? "text-fg-subtle" : i === spokenIndex ? "text-fg rounded-control bg-stream/15" : "text-fg-muted"),
35
35
  children: [word, " "]
36
36
  }, `${i}-${word}`))
37
37
  }), /* @__PURE__ */ jsxs("div", {
@@ -47,7 +47,7 @@ function ReadAloud({ words, spokenIndex, playing, rate, elapsed, duration, onTog
47
47
  /* @__PURE__ */ jsx("span", {
48
48
  className: "bg-surface-2 h-[3px] min-w-0 flex-1 overflow-hidden rounded-full",
49
49
  children: /* @__PURE__ */ jsx("span", {
50
- className: "block h-full rounded-full bg-stream transition-[width] duration-200 ease-linear motion-reduce:transition-none",
50
+ className: "block h-full rounded-full bg-stream transition-[width] duration-brisk ease-linear motion-reduce:transition-none",
51
51
  style: { width: `${progress}%` }
52
52
  })
53
53
  }),
@@ -48,7 +48,7 @@ function ReasoningEffort({ levels, selectedKey, spent, onSelect, className, ...p
48
48
  type: "button",
49
49
  "aria-pressed": active,
50
50
  onClick: () => onSelect?.(level.key),
51
- className: cn("flex-1 rounded-full py-1 text-(length:--cue-text-ui) font-medium transition-[background-color,color,scale] duration-150 active:scale-[0.97]", active ? "bg-bg text-fg" : "text-fg-muted hover:text-fg-muted"),
51
+ className: cn("flex-1 rounded-full py-1 text-(length:--cue-text-ui) font-medium transition-[background-color,color,scale] duration-fast active:scale-[0.97]", active ? "bg-bg text-fg" : "text-fg-muted hover:text-fg-muted"),
52
52
  children: level.label
53
53
  }, level.key);
54
54
  })
@@ -56,7 +56,7 @@ function ReasoningEffort({ levels, selectedKey, spent, onSelect, className, ...p
56
56
  /* @__PURE__ */ jsx("span", {
57
57
  className: "bg-surface-2 h-[3px] w-full overflow-hidden rounded-full",
58
58
  children: /* @__PURE__ */ jsx("span", {
59
- className: "block h-full rounded-full bg-stream transition-[width] duration-500 motion-reduce:transition-none",
59
+ className: "block h-full rounded-full bg-stream transition-[width] duration-slow motion-reduce:transition-none",
60
60
  style: { width: `${used}%` }
61
61
  })
62
62
  })
@@ -44,7 +44,7 @@ function ReasoningPanel({ steps, visibleSteps, streaming, open, onOpenChange, re
44
44
  className: cn("font-mono text-(length:--cue-text-label) tracking-tight", "text-fg-subtle tabular-nums"),
45
45
  children: elapsed
46
46
  })] }), /* @__PURE__ */ jsx(Fragment, { children: restingLabel })]
47
- }), /* @__PURE__ */ jsx(ChevronDownIcon, { 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-180 motion-reduce:transition-none" })]
47
+ }), /* @__PURE__ */ jsx(ChevronDownIcon, { 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-180 motion-reduce:transition-none" })]
48
48
  }), /* @__PURE__ */ jsx(Collapsible.Panel, {
49
49
  className: cn(collapsePanel, "outline-none"),
50
50
  children: /* @__PURE__ */ jsx("ol", {
@@ -52,10 +52,10 @@ function ReasoningPanel({ steps, visibleSteps, streaming, open, onOpenChange, re
52
52
  children: shown.map((step, i) => {
53
53
  const active = streaming && i === shown.length - 1;
54
54
  return /* @__PURE__ */ jsxs("li", {
55
- className: "cue-elements-fade-in cue-elements-slide-in-from-bottom-1 cue-elements-animate-in cue-elements-fill-mode-both flex gap-3 duration-300",
55
+ className: "cue-elements-fade-in cue-elements-slide-in-from-bottom-1 cue-elements-animate-in cue-elements-fill-mode-both flex gap-3 duration-base",
56
56
  children: [/* @__PURE__ */ jsx("span", {
57
57
  "aria-hidden": true,
58
- className: cn("mt-[7px] size-[5px] shrink-0 rounded-full transition-colors duration-300", active ? "animate-pulse bg-stream" : "bg-surface-3")
58
+ className: cn("mt-[7px] size-[5px] shrink-0 rounded-full transition-colors duration-base", active ? "animate-pulse bg-stream" : "bg-surface-3")
59
59
  }), /* @__PURE__ */ jsxs("span", {
60
60
  className: "flex min-w-0 flex-1 flex-col",
61
61
  children: [/* @__PURE__ */ jsx("p", {
@@ -63,7 +63,7 @@ function RecommendationCard({ state, question, children, confidenceLabel, accept
63
63
  children: [/* @__PURE__ */ jsx("button", {
64
64
  type: "button",
65
65
  onClick: onAlternatives,
66
- 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-150 active:scale-[0.96]",
66
+ 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]",
67
67
  children: "Alternatives"
68
68
  }), /* @__PURE__ */ jsx("button", {
69
69
  type: "button",
@@ -72,7 +72,7 @@ function RecommendationCard({ state, question, children, confidenceLabel, accept
72
72
  children: "Accept"
73
73
  })]
74
74
  })] }) : /* @__PURE__ */ jsxs("div", {
75
- className: "cue-elements-fade-in cue-elements-animate-in text-fg-muted flex items-center gap-2 text-(length:--cue-text-ui) duration-300",
75
+ className: "cue-elements-fade-in cue-elements-animate-in text-fg-muted flex items-center gap-2 text-(length:--cue-text-ui) duration-base",
76
76
  children: [/* @__PURE__ */ jsx(CheckIcon, { className: "size-3.5 text-ok" }), acceptedLabel]
77
77
  }, "accepted")
78
78
  })
@@ -31,7 +31,7 @@ function RegenerateMenu({ options, open, currentId, onOpenChange, onPick, classN
31
31
  className: cn(ghostButton, "size-7 self-start", open && "bg-surface-2 text-fg"),
32
32
  children: /* @__PURE__ */ jsx(RefreshCwIcon, { className: "size-3.5" })
33
33
  }), open && /* @__PURE__ */ jsx("div", {
34
- className: cn("bg-surface-2 border border-border-overlay", "cue-elements-fade-in cue-elements-zoom-in-95 cue-elements-slide-in-from-top-1 cue-elements-animate-in flex flex-col gap-0.5 rounded-overlay p-1.5 duration-200"),
34
+ className: cn("bg-surface-2 border border-border-overlay", "cue-elements-fade-in cue-elements-zoom-in-95 cue-elements-slide-in-from-top-1 cue-elements-animate-in flex flex-col gap-0.5 rounded-overlay p-1.5 duration-brisk"),
35
35
  children: options.map((option) => /* @__PURE__ */ jsxs("button", {
36
36
  type: "button",
37
37
  onClick: () => onPick?.(option.id),
@@ -0,0 +1,31 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.js";
3
+ import { DELIVERY_LABELS } from "./vocabulary.js";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ import { CheckIcon, Loader2Icon, TriangleAlertIcon } from "lucide-react";
6
+ //#region src/elements/request-delivery.tsx
7
+ /**
8
+ * Where a request card's answer has got to, as one status line.
9
+ *
10
+ * @internal Drawn by the request cards; not exported from the barrel.
11
+ */
12
+ function DeliveryNote({ delivery, className }) {
13
+ return /* @__PURE__ */ jsxs("span", {
14
+ role: "status",
15
+ "data-slot": "delivery-note",
16
+ "data-delivery": delivery,
17
+ className: cn("flex items-center gap-2 text-(length:--cue-text-ui)", delivery === "failed" ? "text-danger" : "text-fg-muted", className),
18
+ children: [delivery === "sending" ? /* @__PURE__ */ jsx(Loader2Icon, {
19
+ "aria-hidden": true,
20
+ className: "size-3.5 animate-spin motion-reduce:animate-none"
21
+ }) : delivery === "sent" ? /* @__PURE__ */ jsx(CheckIcon, {
22
+ "aria-hidden": true,
23
+ className: "size-3.5"
24
+ }) : /* @__PURE__ */ jsx(TriangleAlertIcon, {
25
+ "aria-hidden": true,
26
+ className: "size-3.5"
27
+ }), DELIVERY_LABELS[delivery]]
28
+ });
29
+ }
30
+ //#endregion
31
+ export { DeliveryNote };
@@ -58,7 +58,7 @@ function ResearchReport({ title, sections, sourcesRead, className, ...props }) {
58
58
  })
59
59
  ]
60
60
  }), section.preview && /* @__PURE__ */ jsx("p", {
61
- className: "text-fg-muted cue-elements-fade-in cue-elements-animate-in ps-5.5 text-(length:--cue-text-ui) leading-(--cue-leading-ui) duration-300",
61
+ className: "text-fg-muted cue-elements-fade-in cue-elements-animate-in ps-5.5 text-(length:--cue-text-ui) leading-(--cue-leading-ui) duration-base",
62
62
  children: section.preview
63
63
  })]
64
64
  }, section.id))
@@ -34,14 +34,14 @@ function RetrievalChunks({ query, chunks, visibleCount, searching, className, ..
34
34
  className: "relative inline-block leading-none",
35
35
  children: "Retrieving"
36
36
  }) : /* @__PURE__ */ jsxs("span", {
37
- className: "cue-elements-fade-in cue-elements-animate-in duration-300",
37
+ className: "cue-elements-fade-in cue-elements-animate-in duration-base",
38
38
  children: [chunks.length, " passages above threshold"]
39
39
  })
40
40
  }),
41
41
  /* @__PURE__ */ jsx("div", {
42
42
  className: "flex min-h-[7rem] flex-col gap-1.5",
43
43
  children: take(chunks, visibleCount).map((chunk) => /* @__PURE__ */ jsxs("div", {
44
- className: cn(paper, "cue-elements-fade-in cue-elements-slide-in-from-bottom-1 cue-elements-animate-in cue-elements-fill-mode-both flex flex-col gap-1.5 rounded-overlay px-3.5 py-2.5 duration-300"),
44
+ className: cn(paper, "cue-elements-fade-in cue-elements-slide-in-from-bottom-1 cue-elements-animate-in cue-elements-fill-mode-both flex flex-col gap-1.5 rounded-overlay px-3.5 py-2.5 duration-base"),
45
45
  children: [
46
46
  /* @__PURE__ */ jsxs("div", {
47
47
  className: "flex items-baseline gap-2",
@@ -67,7 +67,7 @@ function RetrievalChunks({ query, chunks, visibleCount, searching, className, ..
67
67
  /* @__PURE__ */ jsx("span", {
68
68
  className: "bg-surface-2 h-[2px] w-full overflow-hidden rounded-full",
69
69
  children: /* @__PURE__ */ jsx("span", {
70
- className: "block h-full rounded-full bg-stream/70 transition-[width] duration-500",
70
+ className: "block h-full rounded-full bg-stream/70 transition-[width] duration-slow",
71
71
  style: { width: `${pct(chunk.score, 1)}%` }
72
72
  })
73
73
  })
@@ -312,7 +312,7 @@ const RevertDock = React.forwardRef(function RevertDock({ label = "Revert to thi
312
312
  onConfirmingChange?.(null);
313
313
  onRestore?.(confirming);
314
314
  },
315
- className: `bg-danger text-danger-fg flex items-center gap-1.5 rounded-control px-3 py-1.5 text-(length:--cue-text-ui) font-medium outline-none transition-[opacity,scale] duration-150 enabled:hover:opacity-90 enabled:active:scale-[0.96] disabled:opacity-60 ${FOCUS_RING} motion-reduce:transition-none`,
315
+ className: `bg-danger text-danger-fg flex items-center gap-1.5 rounded-control px-3 py-1.5 text-(length:--cue-text-ui) font-medium outline-none transition-[opacity,scale] duration-fast enabled:hover:opacity-90 enabled:active:scale-[0.96] disabled:opacity-60 ${FOCUS_RING} motion-reduce:transition-none`,
316
316
  children: [/* @__PURE__ */ jsx(RotateCcwIcon, {
317
317
  "aria-hidden": true,
318
318
  className: "size-3.5"
@@ -50,7 +50,7 @@ function ReviewableDiff({ filename, hunks, onKeep, onDiscard, onApply, className
50
50
  /* @__PURE__ */ jsx("div", {
51
51
  className: "flex flex-col",
52
52
  children: hunks.map((hunk) => /* @__PURE__ */ jsxs("div", {
53
- className: cn("border-border border-t transition-opacity duration-300", hunk.decision === "discarded" && "opacity-40"),
53
+ className: cn("border-border border-t transition-opacity duration-base", hunk.decision === "discarded" && "opacity-40"),
54
54
  children: [/* @__PURE__ */ jsxs("div", {
55
55
  className: "flex items-center gap-2 px-4 py-1.5",
56
56
  children: [/* @__PURE__ */ jsx("span", {
@@ -62,16 +62,16 @@ function ReviewableDiff({ filename, hunks, onKeep, onDiscard, onApply, className
62
62
  type: "button",
63
63
  "aria-label": `Discard hunk ${hunk.range}`,
64
64
  onClick: () => onDiscard?.(hunk.id),
65
- className: "text-fg-muted hover:bg-surface-2 hover:text-fg flex h-6 items-center gap-1 rounded-full px-2 text-(length:--cue-text-label) font-medium transition-[background-color,color,scale] duration-150 active:scale-[0.96]",
65
+ className: "text-fg-muted hover:bg-surface-2 hover:text-fg flex h-6 items-center gap-1 rounded-full px-2 text-(length:--cue-text-label) font-medium transition-[background-color,color,scale] duration-fast active:scale-[0.96]",
66
66
  children: [/* @__PURE__ */ jsx(XIcon, { className: "size-3" }), "Discard"]
67
67
  }), /* @__PURE__ */ jsxs("button", {
68
68
  type: "button",
69
69
  "aria-label": `Keep hunk ${hunk.range}`,
70
70
  onClick: () => onKeep?.(hunk.id),
71
- className: "flex h-6 items-center gap-1 rounded-full bg-ok/12 px-2 text-(length:--cue-text-label) font-medium text-ok transition-[background-color,scale] duration-150 hover:bg-ok/20 active:scale-[0.96]",
71
+ className: "flex h-6 items-center gap-1 rounded-full bg-ok/12 px-2 text-(length:--cue-text-label) font-medium text-ok transition-[background-color,scale] duration-fast hover:bg-ok/20 active:scale-[0.96]",
72
72
  children: [/* @__PURE__ */ jsx(CheckIcon, { className: "size-3" }), "Keep"]
73
73
  })] }) : /* @__PURE__ */ jsx("span", {
74
- className: cn(mono, "cue-elements-fade-in cue-elements-animate-in duration-300", hunk.decision === "kept" ? "text-ok" : "text-fg-subtle"),
74
+ className: cn(mono, "cue-elements-fade-in cue-elements-animate-in duration-base", hunk.decision === "kept" ? "text-ok" : "text-fg-subtle"),
75
75
  children: hunk.decision
76
76
  })
77
77
  })]