@nadicodeai/ui 9.2.1 → 10.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (293) hide show
  1. package/AGENTS.md +1 -0
  2. package/README.md +4 -29
  3. package/dist/agent-orb.d.ts +3 -0
  4. package/dist/agent-orb.d.ts.map +1 -0
  5. package/dist/agent-orb.js +2 -0
  6. package/dist/assets/brand/aionlabs.svg +2 -0
  7. package/dist/assets/brand/airtable.svg +2 -0
  8. package/dist/assets/brand/apple.svg +2 -0
  9. package/dist/assets/brand/arcee.svg +2 -0
  10. package/dist/assets/brand/asana.svg +2 -0
  11. package/dist/assets/brand/atlassian.svg +2 -0
  12. package/dist/assets/brand/baidu.svg +2 -0
  13. package/dist/assets/brand/bytedance.svg +2 -0
  14. package/dist/assets/brand/claude.svg +2 -0
  15. package/dist/assets/brand/cohere.svg +2 -0
  16. package/dist/assets/brand/datadog.svg +2 -0
  17. package/dist/assets/brand/deepseek.svg +2 -0
  18. package/dist/assets/brand/discord.svg +2 -0
  19. package/dist/assets/brand/dolphin.svg +2 -0
  20. package/dist/assets/brand/dotsstudio.svg +2 -0
  21. package/dist/assets/brand/figma.svg +2 -0
  22. package/dist/assets/brand/gemini.svg +2 -0
  23. package/dist/assets/brand/github.svg +2 -0
  24. package/dist/assets/brand/gitlab.svg +2 -0
  25. package/dist/assets/brand/gmail.svg +2 -0
  26. package/dist/assets/brand/google-calendar.svg +2 -0
  27. package/dist/assets/brand/google-drive.svg +2 -0
  28. package/dist/assets/brand/grok.svg +2 -0
  29. package/dist/assets/brand/huggingface.svg +2 -0
  30. package/dist/assets/brand/ibm.svg +2 -0
  31. package/dist/assets/brand/inception.svg +2 -0
  32. package/dist/assets/brand/inclusionai.svg +2 -0
  33. package/dist/assets/brand/index.json +778 -0
  34. package/dist/assets/brand/inference.svg +2 -0
  35. package/dist/assets/brand/intercom.svg +2 -0
  36. package/dist/assets/brand/jira.svg +2 -0
  37. package/dist/assets/brand/kwaipilot.svg +2 -0
  38. package/dist/assets/brand/linear.svg +2 -0
  39. package/dist/assets/brand/linux.svg +2 -0
  40. package/dist/assets/brand/liquid.svg +2 -0
  41. package/dist/assets/brand/longcat.svg +2 -0
  42. package/dist/assets/brand/mattermost.svg +2 -0
  43. package/dist/assets/brand/meta.svg +2 -0
  44. package/dist/assets/brand/microsoft.svg +2 -0
  45. package/dist/assets/brand/minimax.svg +2 -0
  46. package/dist/assets/brand/mistral.svg +2 -0
  47. package/dist/assets/brand/moonshot.svg +2 -0
  48. package/dist/assets/brand/morph.svg +2 -0
  49. package/dist/assets/brand/n8n.svg +2 -0
  50. package/dist/assets/brand/netlify.svg +2 -0
  51. package/dist/assets/brand/nexagi.svg +2 -0
  52. package/dist/assets/brand/notion.svg +2 -0
  53. package/dist/assets/brand/nousresearch.svg +2 -0
  54. package/dist/assets/brand/nova.svg +2 -0
  55. package/dist/assets/brand/nvidia.svg +2 -0
  56. package/dist/assets/brand/openai.svg +2 -0
  57. package/dist/assets/brand/openrouter.svg +2 -0
  58. package/dist/assets/brand/paypal.svg +2 -0
  59. package/dist/assets/brand/perceptron.svg +2 -0
  60. package/dist/assets/brand/perplexity.svg +2 -0
  61. package/dist/assets/brand/poolside.svg +2 -0
  62. package/dist/assets/brand/postgresql.svg +2 -0
  63. package/dist/assets/brand/qwen.svg +2 -0
  64. package/dist/assets/brand/reka.svg +2 -0
  65. package/dist/assets/brand/relace.svg +2 -0
  66. package/dist/assets/brand/sakana.svg +2 -0
  67. package/dist/assets/brand/sentry.svg +2 -0
  68. package/dist/assets/brand/signal.svg +2 -0
  69. package/dist/assets/brand/slack.svg +2 -0
  70. package/dist/assets/brand/spotify.svg +2 -0
  71. package/dist/assets/brand/square.svg +2 -0
  72. package/dist/assets/brand/stepfun.svg +2 -0
  73. package/dist/assets/brand/stripe.svg +2 -0
  74. package/dist/assets/brand/supabase.svg +2 -0
  75. package/dist/assets/brand/telegram.svg +2 -0
  76. package/dist/assets/brand/tencent.svg +2 -0
  77. package/dist/assets/brand/the-drummer.svg +2 -0
  78. package/dist/assets/brand/thinkingmachines.svg +2 -0
  79. package/dist/assets/brand/todoist.svg +2 -0
  80. package/dist/assets/brand/unbiased.svg +2 -0
  81. package/dist/assets/brand/unreal-engine.svg +2 -0
  82. package/dist/assets/brand/upstage.svg +2 -0
  83. package/dist/assets/brand/vercel.svg +2 -0
  84. package/dist/assets/brand/webflow.svg +2 -0
  85. package/dist/assets/brand/whatsapp.svg +2 -0
  86. package/dist/assets/brand/windows.svg +2 -0
  87. package/dist/assets/brand/writer.svg +2 -0
  88. package/dist/assets/brand/xiaomimimo.svg +2 -0
  89. package/dist/assets/brand/youtube.svg +2 -0
  90. package/dist/assets/brand/yuanbao.svg +2 -0
  91. package/dist/assets/brand/zai.svg +2 -0
  92. package/dist/assets/brand/zapier.svg +2 -0
  93. package/dist/components/action-status.d.ts +5 -0
  94. package/dist/components/action-status.d.ts.map +1 -1
  95. package/dist/components/action-status.js +6 -2
  96. package/dist/components/agent-orb-appearance.d.ts +16 -2
  97. package/dist/components/agent-orb-appearance.d.ts.map +1 -1
  98. package/dist/components/agent-orb-appearance.js +28 -5
  99. package/dist/components/agent-orb.d.ts +6 -3
  100. package/dist/components/agent-orb.d.ts.map +1 -1
  101. package/dist/components/agent-orb.js +20 -7
  102. package/dist/components/app-mark-aliases.d.ts +16 -0
  103. package/dist/components/app-mark-aliases.d.ts.map +1 -0
  104. package/dist/components/app-mark-aliases.js +84 -0
  105. package/dist/components/app-mark.d.ts +4 -0
  106. package/dist/components/app-mark.d.ts.map +1 -1
  107. package/dist/components/app-mark.js +14 -31
  108. package/dist/components/automation-section.d.ts.map +1 -1
  109. package/dist/components/automation-section.js +2 -2
  110. package/dist/components/badge.js +1 -1
  111. package/dist/components/brand.d.ts +3 -2
  112. package/dist/components/brand.d.ts.map +1 -1
  113. package/dist/components/brand.js +18 -28
  114. package/dist/components/button.js +1 -1
  115. package/dist/components/collection-filters.js +2 -2
  116. package/dist/components/confirm-dialog.d.ts +3 -1
  117. package/dist/components/confirm-dialog.d.ts.map +1 -1
  118. package/dist/components/confirm-dialog.js +3 -3
  119. package/dist/components/drawer.js +5 -5
  120. package/dist/components/feedback-state.d.ts.map +1 -1
  121. package/dist/components/feedback-state.js +6 -9
  122. package/dist/components/footer.js +2 -2
  123. package/dist/components/house-icons.d.ts.map +1 -1
  124. package/dist/components/house-icons.js +9 -1
  125. package/dist/components/input-otp.js +1 -1
  126. package/dist/components/installer-shell.d.ts.map +1 -1
  127. package/dist/components/installer-shell.js +5 -6
  128. package/dist/components/navigation-menu.js +2 -2
  129. package/dist/components/pending-label.d.ts +15 -0
  130. package/dist/components/pending-label.d.ts.map +1 -0
  131. package/dist/components/pending-label.js +14 -0
  132. package/dist/components/sheet.js +1 -1
  133. package/dist/components/skeleton.d.ts +4 -0
  134. package/dist/components/skeleton.d.ts.map +1 -1
  135. package/dist/components/skeleton.js +5 -1
  136. package/dist/components/sonner.d.ts.map +1 -1
  137. package/dist/components/sonner.js +5 -2
  138. package/dist/components/table.js +1 -1
  139. package/dist/components/tabs.js +1 -1
  140. package/dist/components/toggle.js +1 -1
  141. package/dist/components/waiting-line.d.ts +30 -0
  142. package/dist/components/waiting-line.d.ts.map +1 -0
  143. package/dist/components/waiting-line.js +33 -0
  144. package/dist/eslint/rules/no-invalid-token-utility.js +1 -1
  145. package/dist/index.d.ts +3 -38
  146. package/dist/index.d.ts.map +1 -1
  147. package/dist/index.js +3 -38
  148. package/dist/internal/agent-orb-motion.d.ts +9 -1
  149. package/dist/internal/agent-orb-motion.d.ts.map +1 -1
  150. package/dist/internal/agent-orb-motion.js +23 -11
  151. package/dist/internal/agent-orb.d.ts +14 -1
  152. package/dist/internal/agent-orb.d.ts.map +1 -1
  153. package/dist/internal/agent-orb.js +78 -22
  154. package/dist/internal/assistant-ui/attachment.d.ts.map +1 -1
  155. package/dist/internal/assistant-ui/attachment.js +3 -2
  156. package/dist/internal/assistant-ui/reasoning.d.ts.map +1 -1
  157. package/dist/internal/assistant-ui/reasoning.js +4 -4
  158. package/dist/internal/assistant-ui/tool-fallback.d.ts.map +1 -1
  159. package/dist/internal/assistant-ui/tool-fallback.js +5 -4
  160. package/dist/internal/assistant-ui/tool-group.d.ts.map +1 -1
  161. package/dist/internal/assistant-ui/tool-group.js +4 -3
  162. package/dist/lib/motion.d.ts +18 -4
  163. package/dist/lib/motion.d.ts.map +1 -1
  164. package/dist/lib/motion.js +18 -4
  165. package/dist/styles/globals.css +0 -1
  166. package/docs/activity.md +99 -119
  167. package/docs/agent-orb.md +71 -20
  168. package/docs/component-classification.md +4 -4
  169. package/docs/consuming-cross-repo.md +8 -10
  170. package/docs/contract.md +10 -9
  171. package/docs/icon-assets.md +106 -0
  172. package/docs/migration/10.0.0.md +144 -0
  173. package/package.json +8 -7
  174. package/dist/activity.d.ts +0 -2
  175. package/dist/activity.d.ts.map +0 -1
  176. package/dist/activity.js +0 -2
  177. package/dist/components/action-band.d.ts +0 -12
  178. package/dist/components/action-band.d.ts.map +0 -1
  179. package/dist/components/action-band.js +0 -48
  180. package/dist/components/activity-orb.d.ts +0 -21
  181. package/dist/components/activity-orb.d.ts.map +0 -1
  182. package/dist/components/activity-orb.js +0 -26
  183. package/dist/components/benefits-bento.d.ts +0 -15
  184. package/dist/components/benefits-bento.d.ts.map +0 -1
  185. package/dist/components/benefits-bento.js +0 -6
  186. package/dist/components/bento.d.ts +0 -39
  187. package/dist/components/bento.d.ts.map +0 -1
  188. package/dist/components/bento.js +0 -70
  189. package/dist/components/card-marketing.d.ts +0 -30
  190. package/dist/components/card-marketing.d.ts.map +0 -1
  191. package/dist/components/card-marketing.js +0 -48
  192. package/dist/components/code-editor-mockup.d.ts +0 -25
  193. package/dist/components/code-editor-mockup.d.ts.map +0 -1
  194. package/dist/components/code-editor-mockup.js +0 -47
  195. package/dist/components/contact.d.ts +0 -32
  196. package/dist/components/contact.d.ts.map +0 -1
  197. package/dist/components/contact.js +0 -46
  198. package/dist/components/faq-item.d.ts +0 -25
  199. package/dist/components/faq-item.d.ts.map +0 -1
  200. package/dist/components/faq-item.js +0 -25
  201. package/dist/components/faq.d.ts +0 -20
  202. package/dist/components/faq.d.ts.map +0 -1
  203. package/dist/components/faq.js +0 -23
  204. package/dist/components/feature-grid.d.ts +0 -23
  205. package/dist/components/feature-grid.d.ts.map +0 -1
  206. package/dist/components/feature-grid.js +0 -33
  207. package/dist/components/feature-rows.d.ts +0 -23
  208. package/dist/components/feature-rows.d.ts.map +0 -1
  209. package/dist/components/feature-rows.js +0 -27
  210. package/dist/components/glyph-spinner.d.ts +0 -10
  211. package/dist/components/glyph-spinner.d.ts.map +0 -1
  212. package/dist/components/glyph-spinner.js +0 -101
  213. package/dist/components/hero-split.d.ts +0 -23
  214. package/dist/components/hero-split.d.ts.map +0 -1
  215. package/dist/components/hero-split.js +0 -35
  216. package/dist/components/hero.d.ts +0 -28
  217. package/dist/components/hero.d.ts.map +0 -1
  218. package/dist/components/hero.js +0 -45
  219. package/dist/components/integration-flow.d.ts +0 -36
  220. package/dist/components/integration-flow.d.ts.map +0 -1
  221. package/dist/components/integration-flow.js +0 -36
  222. package/dist/components/live-demo.d.ts +0 -31
  223. package/dist/components/live-demo.d.ts.map +0 -1
  224. package/dist/components/live-demo.js +0 -30
  225. package/dist/components/logo-band.d.ts +0 -33
  226. package/dist/components/logo-band.d.ts.map +0 -1
  227. package/dist/components/logo-band.js +0 -49
  228. package/dist/components/logo-tile.d.ts +0 -21
  229. package/dist/components/logo-tile.d.ts.map +0 -1
  230. package/dist/components/logo-tile.js +0 -28
  231. package/dist/components/media-mount.d.ts +0 -13
  232. package/dist/components/media-mount.d.ts.map +0 -1
  233. package/dist/components/media-mount.js +0 -15
  234. package/dist/components/nav-bar.d.ts +0 -24
  235. package/dist/components/nav-bar.d.ts.map +0 -1
  236. package/dist/components/nav-bar.js +0 -35
  237. package/dist/components/newsletter.d.ts +0 -24
  238. package/dist/components/newsletter.d.ts.map +0 -1
  239. package/dist/components/newsletter.js +0 -31
  240. package/dist/components/page-frame.d.ts +0 -30
  241. package/dist/components/page-frame.d.ts.map +0 -1
  242. package/dist/components/page-frame.js +0 -30
  243. package/dist/components/pricing-card.d.ts +0 -30
  244. package/dist/components/pricing-card.d.ts.map +0 -1
  245. package/dist/components/pricing-card.js +0 -44
  246. package/dist/components/pricing.d.ts +0 -25
  247. package/dist/components/pricing.d.ts.map +0 -1
  248. package/dist/components/pricing.js +0 -11
  249. package/dist/components/proof-slot.d.ts +0 -8
  250. package/dist/components/proof-slot.d.ts.map +0 -1
  251. package/dist/components/proof-slot.js +0 -8
  252. package/dist/components/quote-card.d.ts +0 -31
  253. package/dist/components/quote-card.d.ts.map +0 -1
  254. package/dist/components/quote-card.js +0 -48
  255. package/dist/components/seam-grid.d.ts +0 -30
  256. package/dist/components/seam-grid.d.ts.map +0 -1
  257. package/dist/components/seam-grid.js +0 -30
  258. package/dist/components/section-intro.d.ts +0 -18
  259. package/dist/components/section-intro.d.ts.map +0 -1
  260. package/dist/components/section-intro.js +0 -22
  261. package/dist/components/security-grid.d.ts +0 -25
  262. package/dist/components/security-grid.d.ts.map +0 -1
  263. package/dist/components/security-grid.js +0 -28
  264. package/dist/components/shift-band.d.ts +0 -14
  265. package/dist/components/shift-band.d.ts.map +0 -1
  266. package/dist/components/shift-band.js +0 -11
  267. package/dist/components/spinner.d.ts +0 -3
  268. package/dist/components/spinner.d.ts.map +0 -1
  269. package/dist/components/spinner.js +0 -7
  270. package/dist/components/statement.d.ts +0 -32
  271. package/dist/components/statement.d.ts.map +0 -1
  272. package/dist/components/statement.js +0 -40
  273. package/dist/components/steps.d.ts +0 -34
  274. package/dist/components/steps.d.ts.map +0 -1
  275. package/dist/components/steps.js +0 -40
  276. package/dist/components/team-grid.d.ts +0 -27
  277. package/dist/components/team-grid.d.ts.map +0 -1
  278. package/dist/components/team-grid.js +0 -30
  279. package/dist/components/testimonials.d.ts +0 -48
  280. package/dist/components/testimonials.d.ts.map +0 -1
  281. package/dist/components/testimonials.js +0 -58
  282. package/dist/components/texture-strip.d.ts +0 -22
  283. package/dist/components/texture-strip.d.ts.map +0 -1
  284. package/dist/components/texture-strip.js +0 -32
  285. package/dist/components/use-case-bento.d.ts +0 -13
  286. package/dist/components/use-case-bento.d.ts.map +0 -1
  287. package/dist/components/use-case-bento.js +0 -8
  288. package/dist/internal/activity-orb.d.ts +0 -27
  289. package/dist/internal/activity-orb.d.ts.map +0 -1
  290. package/dist/internal/activity-orb.js +0 -150
  291. package/dist/lib/seam.d.ts +0 -29
  292. package/dist/lib/seam.d.ts.map +0 -1
  293. package/dist/lib/seam.js +0 -30
@@ -1,5 +1,5 @@
1
1
  import { finalizeFrame, MODE_FRAMES, makeProj, radiusScale, resolvePreset, } from "thinking-orbs/engine";
2
- import { motionPose, paintOrbCue, stateSpeed } from "./agent-orb-motion.js";
2
+ import { motionPose, paintOrbCue, reducedBreath, stateSpeed, } from "./agent-orb-motion.js";
3
3
  const agentOrbForms = {
4
4
  orbit: "working",
5
5
  globe: "searching",
@@ -9,6 +9,17 @@ const agentOrbForms = {
9
9
  ribbon: "composing",
10
10
  morph: "shaping",
11
11
  };
12
+ /**
13
+ * Presence belongs to the orb, not to the module: two orbs on one page can
14
+ * want different weights. `plain` is the interface's own ink. `over-picture`
15
+ * is the orb drawn on a photograph, where the plain weights sink into the
16
+ * image, so its ink and its dot and line radius are multiplied. Nadia on open
17
+ * sky keeps `plain`.
18
+ */
19
+ const presenceWeights = {
20
+ plain: { alpha: 1, radius: 1 },
21
+ "over-picture": { alpha: 2.3, radius: 1.9 },
22
+ };
12
23
  /**
13
24
  * Nadia's four stripes across the ribbon's width, azzurro to rosso. The third
14
25
  * is the orb's own pigment, the inherited text colour, so the white of the
@@ -79,7 +90,9 @@ export function stripedRibbonFrame(size, t, opts) {
79
90
  }
80
91
  return finalizeFrame(dots, [], opts.rMin);
81
92
  }
82
- function paintAgentOrb(context, form, size, seconds, color, state = "idle", age = 0, reduced = false, celebrationColors = [color], stripeColors = [color]) {
93
+ function paintAgentOrb(context, input) {
94
+ const { form, size, seconds, color, state, age, reduced, breath, celebrationColors, stripeColors, } = input;
95
+ const presence = presenceWeights[input.presence];
83
96
  const preset = resolvePreset(agentOrbForms[form === "nadia" ? "ribbon" : form], size <= 32 ? 20 : 64);
84
97
  const frame = form === "nadia"
85
98
  ? stripedRibbonFrame(size, seconds, preset.opts)
@@ -98,12 +111,13 @@ function paintAgentOrb(context, form, size, seconds, color, state = "idle", age
98
111
  size / 2 + dx * Math.sin(pose.rotation) + dy * Math.cos(pose.rotation) + pose.y * size,
99
112
  ];
100
113
  };
101
- paintOrbCue(context, state, size, gestureSeconds, reduced, celebrationColors, "back");
114
+ const ink = pose.opacity * breath;
115
+ paintOrbCue(context, state, size, gestureSeconds, reduced, celebrationColors, "back", breath);
102
116
  context.fillStyle = color;
103
117
  context.strokeStyle = color;
104
118
  for (const line of frame.lines) {
105
- context.globalAlpha = Math.min(1, Math.max(0, (1 - line.white) * (line.a ?? 1) * pose.opacity));
106
- context.lineWidth = line.w;
119
+ context.globalAlpha = Math.min(1, Math.max(0, (1 - line.white) * (line.a ?? 1) * ink * presence.alpha));
120
+ context.lineWidth = line.w * presence.radius;
107
121
  context.beginPath();
108
122
  context.moveTo(...project(line.x1, line.y1));
109
123
  context.lineTo(...project(line.x2, line.y2));
@@ -111,44 +125,71 @@ function paintAgentOrb(context, form, size, seconds, color, state = "idle", age
111
125
  }
112
126
  for (const dot of frame.dots) {
113
127
  context.fillStyle = dot.stripe === undefined ? color : (stripeColors[dot.stripe] ?? color);
114
- context.globalAlpha = Math.min(1, Math.max(0, (1 - dot.white) * (dot.a ?? 1) * pose.opacity));
128
+ context.globalAlpha = Math.min(1, Math.max(0, (1 - dot.white) * (dot.a ?? 1) * ink * presence.alpha));
115
129
  context.beginPath();
116
- context.arc(...project(dot.x, dot.y), dot.r, 0, Math.PI * 2);
130
+ context.arc(...project(dot.x, dot.y), dot.r * presence.radius, 0, Math.PI * 2);
117
131
  context.fill();
118
132
  }
119
133
  context.globalAlpha = 1;
120
- paintOrbCue(context, state, size, gestureSeconds, reduced, celebrationColors, "front");
134
+ paintOrbCue(context, state, size, gestureSeconds, reduced, celebrationColors, "front", breath);
121
135
  }
122
- export function mountAgentOrb(canvas, form, size, initiallyPaused, initialState = "idle") {
136
+ export function mountAgentOrb(canvas, options) {
137
+ const { form, presence = "plain" } = options;
123
138
  const context = canvas.getContext("2d");
124
139
  if (!context)
125
140
  return { destroy() { }, setPaused(_value) { }, setState(_value) { } };
126
141
  const motion = window.matchMedia("(prefers-reduced-motion: reduce)");
127
- let paused = initiallyPaused;
142
+ let paused = options.paused ?? false;
128
143
  let visible = true;
129
144
  let disposed = false;
130
145
  let request = 0;
131
146
  let seconds = 0.6;
132
147
  let age = 0;
133
- let state = initialState;
148
+ let breath = 0;
149
+ let state = options.state ?? "idle";
134
150
  let previous = null;
135
151
  let lastPaint = 0;
136
152
  let ratio = 1;
153
+ let painted = options.size;
137
154
  let color = getComputedStyle(canvas).color;
138
155
  let celebrationColors = [color];
139
156
  let stripeColors = [color];
157
+ /**
158
+ * The box the orb is displayed at, in CSS pixels. A canvas stretched by
159
+ * layout reads as pixels unless the engine paints at that size, so the box
160
+ * decides both the backing store and the engine's density profile; the
161
+ * declared size only stands in before layout has measured anything.
162
+ */
163
+ function measure() {
164
+ const box = canvas.getBoundingClientRect();
165
+ const side = Math.min(box.width, box.height);
166
+ return side > 0 ? side : options.size;
167
+ }
140
168
  function paint() {
141
169
  if (!context)
142
170
  return;
143
171
  context.setTransform(ratio, 0, 0, ratio, 0, 0);
144
- paintAgentOrb(context, form, size, seconds, color, state, age, motion.matches, celebrationColors, stripeColors);
172
+ paintAgentOrb(context, {
173
+ form,
174
+ size: painted,
175
+ seconds,
176
+ color,
177
+ state,
178
+ age,
179
+ reduced: motion.matches,
180
+ breath: motion.matches ? reducedBreath(state, breath) : 1,
181
+ presence,
182
+ celebrationColors,
183
+ stripeColors,
184
+ });
145
185
  }
146
186
  function running() {
147
- return (!disposed &&
148
- visible &&
149
- !document.hidden &&
150
- !motion.matches &&
151
- !paused &&
187
+ if (disposed || !visible || document.hidden || paused)
188
+ return false;
189
+ // Reduced motion holds every pose; only a busy orb keeps breathing.
190
+ if (motion.matches)
191
+ return state === "thinking" || state === "working";
192
+ return (state !== "idle" &&
152
193
  state !== "waiting" &&
153
194
  !(state === "blocked" && age >= 0.3) &&
154
195
  !(state === "done" && age >= 1.8));
@@ -159,8 +200,12 @@ export function mountAgentOrb(canvas, form, size, initiallyPaused, initialState
159
200
  return;
160
201
  if (previous !== null) {
161
202
  const elapsed = Math.min((now - previous) / 1000, 0.1);
162
- seconds += elapsed * stateSpeed(state, form);
163
- age += elapsed * (state === "done" ? 0.575 : 0.2875);
203
+ if (motion.matches)
204
+ breath += elapsed;
205
+ else {
206
+ seconds += elapsed * stateSpeed(state, form);
207
+ age += elapsed * (state === "done" ? 0.575 : 0.2875);
208
+ }
164
209
  }
165
210
  previous = now;
166
211
  if (now - lastPaint >= 1000 / 30) {
@@ -178,9 +223,11 @@ export function mountAgentOrb(canvas, form, size, initiallyPaused, initialState
178
223
  request = requestAnimationFrame(tick);
179
224
  }
180
225
  function refresh() {
181
- ratio = Math.min(window.devicePixelRatio || 1, 2);
182
- canvas.width = Math.round(size * ratio);
183
- canvas.height = Math.round(size * ratio);
226
+ painted = measure();
227
+ const backing = Math.max(1, Math.round(painted * Math.min(window.devicePixelRatio || 1, 2)));
228
+ canvas.width = backing;
229
+ canvas.height = backing;
230
+ ratio = backing / painted;
184
231
  const appearance = getComputedStyle(canvas);
185
232
  color = appearance.color;
186
233
  celebrationColors = ["--nc-chart-5", "--nc-chart-6", "--nc-warning", "--nc-chart-4"].map((token) => `color-mix(in oklch, ${appearance.getPropertyValue(token).trim() || color} 75%, white)`);
@@ -199,6 +246,13 @@ export function mountAgentOrb(canvas, form, size, initiallyPaused, initialState
199
246
  attributeFilter: ["class", "style", "data-theme"],
200
247
  });
201
248
  }
249
+ // Layout, not the declared size, decides the pixels, so the box is observed
250
+ // rather than remounted on: an orb sized by its container stays sharp.
251
+ const box = new ResizeObserver(() => {
252
+ if (Math.abs(measure() - painted) >= 0.5)
253
+ refresh();
254
+ });
255
+ box.observe(canvas);
202
256
  motion.addEventListener("change", play);
203
257
  document.addEventListener("visibilitychange", play);
204
258
  window.addEventListener("resize", refresh);
@@ -207,6 +261,7 @@ export function mountAgentOrb(canvas, form, size, initiallyPaused, initialState
207
261
  setState(value) {
208
262
  state = value;
209
263
  age = 0;
264
+ breath = 0;
210
265
  play();
211
266
  },
212
267
  setPaused(value) {
@@ -218,6 +273,7 @@ export function mountAgentOrb(canvas, form, size, initiallyPaused, initialState
218
273
  cancelAnimationFrame(request);
219
274
  visibility.disconnect();
220
275
  appearance.disconnect();
276
+ box.disconnect();
221
277
  motion.removeEventListener("change", play);
222
278
  document.removeEventListener("visibilitychange", play);
223
279
  window.removeEventListener("resize", refresh);
@@ -1 +1 @@
1
- {"version":3,"file":"attachment.d.ts","sourceRoot":"","sources":["../../../src/internal/assistant-ui/attachment.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA+C,KAAK,EAAE,EAAkB,MAAM,OAAO,CAAC;AAkN7F,eAAO,MAAM,sBAAsB,EAAE,EAMpC,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,EAMjC,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,EAiBnC,CAAC"}
1
+ {"version":3,"file":"attachment.d.ts","sourceRoot":"","sources":["../../../src/internal/assistant-ui/attachment.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA+C,KAAK,EAAE,EAAkB,MAAM,OAAO,CAAC;AAmN7F,eAAO,MAAM,sBAAsB,EAAE,EAMpC,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,EAMjC,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,EAiBnC,CAAC"}
@@ -1,12 +1,13 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useEffect, useState, isValidElement } from "react";
4
- import { XIcon, PlusIcon, FileText, Loader2Icon, AlertCircleIcon } from "lucide-react";
4
+ import { XIcon, PlusIcon, FileText, AlertCircleIcon } from "lucide-react";
5
5
  import { AttachmentPrimitive, ComposerPrimitive, MessagePrimitive, useAuiState, useAui, } from "@assistant-ui/react";
6
6
  import { useShallow } from "zustand/shallow";
7
7
  import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../../components/tooltip.js";
8
8
  import { Dialog, DialogTitle, DialogContent, DialogTrigger } from "../../components/dialog.js";
9
9
  import { Avatar, AvatarImage, AvatarFallback } from "../../components/avatar.js";
10
+ import { WaitingLine } from "../../components/waiting-line.js";
10
11
  import { TooltipIconButton } from "./tooltip-icon-button.js";
11
12
  import { cn } from "../../lib/utils.js";
12
13
  const useFileSrc = (file) => {
@@ -77,7 +78,7 @@ const AttachmentUI = () => {
77
78
  const errorMessage = useAuiState((s) => s.attachment.status.type === "incomplete" && s.attachment.status.reason === "error"
78
79
  ? (s.attachment.status.message ?? "Upload failed")
79
80
  : undefined);
80
- return (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsxs(AttachmentPrimitive.Root, { className: cn("aui-attachment-root relative", isComposer && "nc-transition-opacity", isImage && !isComposer && "aui-attachment-root-message only:*:first:size-24"), children: [_jsx(AttachmentPreviewDialog, { children: _jsxs(TooltipTrigger, { render: _jsx("div", { className: cn("aui-attachment-tile nc-transition-transform relative size-14 cursor-pointer overflow-hidden rounded-[calc(var(--composer-radius)-var(--composer-padding))] bg-muted after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:ring-1 after:ring-border after:ring-inset hover:after:bg-foreground/10", isError && "after:ring-destructive/60"), role: "button", tabIndex: 0, "aria-label": `${typeLabel} attachment${isError ? ", upload failed" : isUploading ? ", uploading" : ""}` }), children: [_jsx(AttachmentThumb, {}), isUploading && (_jsx("div", { "aria-hidden": "true", className: "aui-attachment-tile-uploading nc-transition-opacity absolute inset-0 flex items-center justify-center bg-background/60 backdrop-blur-[2px]", children: _jsx(Loader2Icon, { className: "size-4 text-muted-foreground motion-safe:animate-spin motion-reduce:animate-pulse" }) })), isError && (_jsx("div", { "aria-hidden": "true", className: "aui-attachment-tile-error nc-transition-opacity absolute inset-0 flex items-center justify-center bg-background/70 backdrop-blur-[2px]", children: _jsx(AlertCircleIcon, { className: "text-destructive size-4" }) }))] }) }), isComposer && _jsx(AttachmentRemove, {})] }), _jsxs(TooltipContent, { side: "top", children: [_jsx(AttachmentPrimitive.Name, {}), errorMessage && _jsx("p", { className: "aui-attachment-error-message", children: errorMessage })] })] }) }));
81
+ return (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsxs(AttachmentPrimitive.Root, { className: cn("aui-attachment-root relative", isComposer && "nc-transition-opacity", isImage && !isComposer && "aui-attachment-root-message only:*:first:size-24"), children: [_jsx(AttachmentPreviewDialog, { children: _jsxs(TooltipTrigger, { render: _jsx("div", { className: cn("aui-attachment-tile nc-transition-transform relative size-14 cursor-pointer overflow-hidden rounded-[calc(var(--composer-radius)-var(--composer-padding))] bg-muted after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:ring-1 after:ring-border after:ring-inset hover:after:bg-foreground/10", isError && "after:ring-destructive/60"), role: "button", tabIndex: 0, "aria-label": `${typeLabel} attachment${isError ? ", upload failed" : isUploading ? ", uploading" : ""}` }), children: [_jsx(AttachmentThumb, {}), isUploading && (_jsx("div", { "aria-hidden": "true", className: "aui-attachment-tile-uploading nc-transition-opacity absolute inset-0 flex items-center justify-center bg-background/60 backdrop-blur-[2px]", children: _jsx(WaitingLine, { className: "w-8 text-muted-foreground", decorative: true }) })), isError && (_jsx("div", { "aria-hidden": "true", className: "aui-attachment-tile-error nc-transition-opacity absolute inset-0 flex items-center justify-center bg-background/70 backdrop-blur-[2px]", children: _jsx(AlertCircleIcon, { className: "text-destructive size-4" }) }))] }) }), isComposer && _jsx(AttachmentRemove, {})] }), _jsxs(TooltipContent, { side: "top", children: [_jsx(AttachmentPrimitive.Name, {}), errorMessage && _jsx("p", { className: "aui-attachment-error-message", children: errorMessage })] })] }) }));
81
82
  };
82
83
  const AttachmentRemove = () => {
83
84
  return (_jsx(AttachmentPrimitive.Remove, { render: _jsx(TooltipIconButton, { tooltip: "Remove file", className: "aui-attachment-tile-remove absolute end-1 top-1 size-5 rounded-full bg-foreground/70! text-background! backdrop-blur-sm after:absolute after:-inset-1.5 hover:bg-foreground/85!", side: "top" }), children: _jsx(XIcon, { className: "aui-attachment-remove-icon size-3 stroke-[2.5]" }) }));
@@ -1 +1 @@
1
- {"version":3,"file":"reasoning.d.ts","sourceRoot":"","sources":["../../../src/internal/assistant-ui/reasoning.tsx"],"names":[],"mappings":"AAYA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAElE,OAAO,EAAiB,KAAK,6BAA6B,EAAE,MAAM,qBAAqB,CAAC;AAExF,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAO/F,QAAA,MAAM,iBAAiB;;8EAWrB,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,IAAI,CACnC,KAAK,CAAC,cAAc,CAAC,OAAO,WAAW,CAAC,EACxC,MAAM,GAAG,cAAc,CACxB,GACC,YAAY,CAAC,OAAO,iBAAiB,CAAC,GAAG;IACvC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEJ,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,OAAO,EACP,IAAI,EAAE,cAAc,EACpB,YAAY,EAAE,sBAAsB,EACpC,WAAmB,EACnB,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,kBAAkB,+BAsDpB;AAkCD,iBAAS,gBAAgB,CAAC,EACxB,MAAM,EACN,QAAQ,EACR,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,kBAAkB,CAAC,GAAG;IACnD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,+BA2CA;AAED,iBAAS,gBAAgB,CAAC,EACxB,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,kBAAkB,CAAC,+BAmBjD;AAED,iBAAS,aAAa,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,+BA6DpF;AAID,QAAA,MAAM,SAAS,EAAqC,6BAA6B,CAAC;AAIlF,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"reasoning.d.ts","sourceRoot":"","sources":["../../../src/internal/assistant-ui/reasoning.tsx"],"names":[],"mappings":"AAYA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAElE,OAAO,EAAiB,KAAK,6BAA6B,EAAE,MAAM,qBAAqB,CAAC;AAExF,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAM/F,QAAA,MAAM,iBAAiB;;8EAWrB,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,IAAI,CACnC,KAAK,CAAC,cAAc,CAAC,OAAO,WAAW,CAAC,EACxC,MAAM,GAAG,cAAc,CACxB,GACC,YAAY,CAAC,OAAO,iBAAiB,CAAC,GAAG;IACvC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEJ,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,OAAO,EACP,IAAI,EAAE,cAAc,EACpB,YAAY,EAAE,sBAAsB,EACpC,WAAmB,EACnB,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,kBAAkB,+BAsDpB;AAkCD,iBAAS,gBAAgB,CAAC,EACxB,MAAM,EACN,QAAQ,EACR,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,kBAAkB,CAAC,GAAG;IACnD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,+BAmCA;AAED,iBAAS,gBAAgB,CAAC,EACxB,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,kBAAkB,CAAC,+BAmBjD;AAED,iBAAS,aAAa,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,+BA6DpF;AAID,QAAA,MAAM,SAAS,EAAqC,6BAA6B,CAAC;AAIlF,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,aAAa,EAAE,CAAC"}
@@ -7,7 +7,7 @@ import { useScrollLock } from "@assistant-ui/react";
7
7
  import { MarkdownText } from "./markdown-text.js";
8
8
  import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../../components/collapsible.js";
9
9
  import { cn } from "../../lib/utils.js";
10
- const ANIMATION_DURATION = 200;
10
+ import { disclosureDuration, disclosureDurationMs } from "../../lib/motion.js";
11
11
  const ReasoningPreviewContext = createContext(false);
12
12
  const reasoningVariants = cva("aui-reasoning-root mb-4 w-full", {
13
13
  variants: {
@@ -25,7 +25,7 @@ function ReasoningRoot({ className, variant, open: controlledOpen, onOpenChange:
25
25
  const collapsibleRef = useRef(null);
26
26
  const initialOpenRef = useRef(defaultOpen);
27
27
  const [userOpen, setUserOpen] = useState(null);
28
- const lockScroll = useScrollLock(collapsibleRef, ANIMATION_DURATION);
28
+ const lockScroll = useScrollLock(collapsibleRef, disclosureDurationMs);
29
29
  const isControlled = controlledOpen !== undefined;
30
30
  const isOpen = isControlled
31
31
  ? controlledOpen
@@ -50,7 +50,7 @@ function ReasoningRoot({ className, variant, open: controlledOpen, onOpenChange:
50
50
  controlledOnOpenChange?.(open);
51
51
  }, [lockScroll, isControlled, controlledOnOpenChange]);
52
52
  return (_jsx(Collapsible, { ref: collapsibleRef, "data-slot": "reasoning-root", "data-variant": variant, open: isOpen, onOpenChange: handleOpenChange, className: cn("group/reasoning-root", reasoningVariants({ variant, className })), style: {
53
- "--animation-duration": `${ANIMATION_DURATION}ms`,
53
+ "--animation-duration": disclosureDuration,
54
54
  }, ...props, children: _jsx(ReasoningPreviewContext.Provider, { value: isPreview, children: children }) }));
55
55
  }
56
56
  function ReasoningFade({ side = "bottom", className, ...props }) {
@@ -61,7 +61,7 @@ function ReasoningFade({ side = "bottom", className, ...props }) {
61
61
  }
62
62
  function ReasoningTrigger({ active, duration, className, ...props }) {
63
63
  const durationText = duration ? ` (${duration}s)` : "";
64
- return (_jsxs(CollapsibleTrigger, { "data-slot": "reasoning-trigger", className: cn("aui-reasoning-trigger nc-transition-paint group/trigger flex max-w-[75%] origin-left items-center gap-2 py-1.5 text-sm text-muted-foreground hover:text-foreground", className), ...props, children: [_jsx(BrainIcon, { "data-slot": "reasoning-trigger-icon", className: "aui-reasoning-trigger-icon size-4 shrink-0" }), _jsxs("span", { "data-slot": "reasoning-trigger-label", className: "aui-reasoning-trigger-label-wrapper relative inline-block leading-none tabular-nums", children: [_jsxs("span", { children: ["Reasoning", durationText] }), active ? (_jsxs("span", { "aria-hidden": true, "data-slot": "reasoning-trigger-shimmer", className: "aui-reasoning-trigger-shimmer shimmer pointer-events-none absolute inset-0 motion-reduce:animate-none", children: ["Reasoning", durationText] })) : null] }), _jsx(ChevronDownIcon, { "data-slot": "reasoning-trigger-chevron", className: cn("aui-reasoning-trigger-chevron mt-0.5 size-4 shrink-0", "transition-transform duration-(--animation-duration) ease-[var(--nc-ease-out-strong)] motion-reduce:transition-none", "-rotate-90", "group-data-open/trigger:rotate-0", "group-data-panel-open/trigger:rotate-0") })] }));
64
+ return (_jsxs(CollapsibleTrigger, { "aria-busy": active || undefined, "data-slot": "reasoning-trigger", className: cn("aui-reasoning-trigger nc-transition-paint group/trigger flex max-w-[75%] origin-left items-center gap-2 py-1.5 text-sm text-muted-foreground hover:text-foreground", className), ...props, children: [_jsx(BrainIcon, { "data-slot": "reasoning-trigger-icon", className: "aui-reasoning-trigger-icon size-4 shrink-0" }), _jsx("span", { "data-slot": "reasoning-trigger-label", className: "aui-reasoning-trigger-label-wrapper relative inline-block leading-none tabular-nums", children: _jsxs("span", { children: ["Reasoning", durationText] }) }), _jsx(ChevronDownIcon, { "data-slot": "reasoning-trigger-chevron", className: cn("aui-reasoning-trigger-chevron mt-0.5 size-4 shrink-0", "transition-transform duration-(--animation-duration) ease-[var(--nc-ease-out-strong)] motion-reduce:transition-none", "-rotate-90", "group-data-open/trigger:rotate-0", "group-data-panel-open/trigger:rotate-0") })] }));
65
65
  }
66
66
  function ReasoningContent({ className, children, ...props }) {
67
67
  const isPreview = useContext(ReasoningPreviewContext);
@@ -1 +1 @@
1
- {"version":3,"file":"tool-fallback.d.ts","sourceRoot":"","sources":["../../../src/internal/assistant-ui/tool-fallback.tsx"],"names":[],"mappings":"AAIA,OAAO,EAOL,KAAK,4BAA4B,EAClC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,WAAW,EAA0C,MAAM,0BAA0B,CAAC;AAQ/F,MAAM,MAAM,qBAAqB,GAAG,IAAI,CACtC,KAAK,CAAC,cAAc,CAAC,OAAO,WAAW,CAAC,EACxC,MAAM,GAAG,cAAc,CACxB,GAAG;IACF,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAieF,QAAA,MAAM,YAAY,EAAwC,4BAA4B,CAAC;AAIvF,OAAO,EAAE,YAAY,EAAE,CAAC"}
1
+ {"version":3,"file":"tool-fallback.d.ts","sourceRoot":"","sources":["../../../src/internal/assistant-ui/tool-fallback.tsx"],"names":[],"mappings":"AAUA,OAAO,EAOL,KAAK,4BAA4B,EAClC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,WAAW,EAA0C,MAAM,0BAA0B,CAAC;AAQ/F,MAAM,MAAM,qBAAqB,GAAG,IAAI,CACtC,KAAK,CAAC,cAAc,CAAC,OAAO,WAAW,CAAC,EACxC,MAAM,GAAG,cAAc,CACxB,GAAG;IACF,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAydF,QAAA,MAAM,YAAY,EAAwC,4BAA4B,CAAC;AAIvF,OAAO,EAAE,YAAY,EAAE,CAAC"}
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { memo, useCallback, useRef, useState } from "react";
4
- import { AlertCircleIcon, CheckIcon, ChevronDownIcon, LoaderIcon, XCircleIcon } from "lucide-react";
4
+ import { AlertCircleIcon, CheckIcon, ChevronDownIcon, CircleDotIcon, XCircleIcon, } from "lucide-react";
5
5
  import { useScrollLock, useToolCallElapsed, } from "@assistant-ui/react";
6
6
  import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../../components/collapsible.js";
7
7
  import { cn } from "../../lib/utils.js";
@@ -26,7 +26,7 @@ function ToolFallbackRoot({ className, open: controlledOpen, onOpenChange: contr
26
26
  }, ...props, children: children }));
27
27
  }
28
28
  const statusIconMap = {
29
- running: LoaderIcon,
29
+ running: CircleDotIcon,
30
30
  complete: CheckIcon,
31
31
  incomplete: XCircleIcon,
32
32
  "requires-action": AlertCircleIcon,
@@ -52,8 +52,9 @@ function ToolFallbackTrigger({ toolName, status, className, ...props }) {
52
52
  const isRunning = statusType === "running";
53
53
  const isCancelled = status?.type === "incomplete" && status.reason === "cancelled";
54
54
  const Icon = statusIconMap[statusType];
55
- const label = isCancelled ? "Cancelled tool" : "Used tool";
56
- return (_jsxs(CollapsibleTrigger, { "data-slot": "tool-fallback-trigger", className: cn("aui-tool-fallback-trigger nc-transition-paint group/trigger flex w-fit origin-left items-center gap-2 py-1.5 text-sm text-muted-foreground hover:text-foreground", className), ...props, children: [_jsx(Icon, { "data-slot": "tool-fallback-trigger-icon", className: cn("aui-tool-fallback-trigger-icon size-4 shrink-0", isCancelled && "text-muted-foreground", isRunning && "animate-spin [animation-duration:var(--nc-duration-spin)]") }), _jsxs("span", { "data-slot": "tool-fallback-trigger-label", className: cn("aui-tool-fallback-trigger-label-wrapper relative inline-block text-start leading-none", isCancelled && "text-muted-foreground line-through"), children: [_jsxs("span", { children: [label, ": ", _jsx("b", { children: toolName })] }), isRunning && (_jsxs("span", { "aria-hidden": true, "data-slot": "tool-fallback-trigger-shimmer", className: "aui-tool-fallback-trigger-shimmer shimmer pointer-events-none absolute inset-0 motion-reduce:animate-none", children: [label, ": ", _jsx("b", { children: toolName })] }))] }), _jsx(ToolFallbackDuration, {}), _jsx(ChevronDownIcon, { "data-slot": "tool-fallback-trigger-chevron", className: cn("aui-tool-fallback-trigger-chevron size-4 shrink-0", "transition-transform duration-(--animation-duration) ease-[var(--nc-ease-out-strong)] motion-reduce:transition-none", "-rotate-90", "group-data-open/trigger:rotate-0", "group-data-panel-open/trigger:rotate-0") })] }));
55
+ // A call still running says so in its own words; the icon holds still.
56
+ const label = isCancelled ? "Cancelled tool" : isRunning ? "Running tool" : "Used tool";
57
+ return (_jsxs(CollapsibleTrigger, { "aria-busy": isRunning || undefined, "data-slot": "tool-fallback-trigger", className: cn("aui-tool-fallback-trigger nc-transition-paint group/trigger flex w-fit origin-left items-center gap-2 py-1.5 text-sm text-muted-foreground hover:text-foreground", className), ...props, children: [_jsx(Icon, { "data-slot": "tool-fallback-trigger-icon", className: cn("aui-tool-fallback-trigger-icon size-4 shrink-0", isCancelled && "text-muted-foreground") }), _jsx("span", { "data-slot": "tool-fallback-trigger-label", className: cn("aui-tool-fallback-trigger-label-wrapper relative inline-block text-start leading-none", isCancelled && "text-muted-foreground line-through"), children: _jsxs("span", { children: [label, ": ", _jsx("b", { children: toolName })] }) }), _jsx(ToolFallbackDuration, {}), _jsx(ChevronDownIcon, { "data-slot": "tool-fallback-trigger-chevron", className: cn("aui-tool-fallback-trigger-chevron size-4 shrink-0", "transition-transform duration-(--animation-duration) ease-[var(--nc-ease-out-strong)] motion-reduce:transition-none", "-rotate-90", "group-data-open/trigger:rotate-0", "group-data-panel-open/trigger:rotate-0") })] }));
57
58
  }
58
59
  function ToolFallbackContent({ className, children, ...props }) {
59
60
  return (_jsx(CollapsibleContent, { "data-slot": "tool-fallback-content", className: cn("aui-tool-fallback-content relative overflow-hidden text-sm outline-none", "group/collapsible-content", "data-closed:pointer-events-none", className), ...props, children: _jsx("div", { className: cn("nc-transition-opacity flex flex-col gap-2 ps-6 pt-1 pb-2"), children: children }) }));
@@ -1 +1 @@
1
- {"version":3,"file":"tool-group.d.ts","sourceRoot":"","sources":["../../../src/internal/assistant-ui/tool-group.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAElE,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAK/F,QAAA,MAAM,iBAAiB;;8EASrB,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,IAAI,CACnC,KAAK,CAAC,cAAc,CAAC,OAAO,WAAW,CAAC,EACxC,MAAM,GAAG,cAAc,CACxB,GACC,YAAY,CAAC,OAAO,iBAAiB,CAAC,GAAG;IACvC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEJ,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,OAAO,EACP,IAAI,EAAE,cAAc,EACpB,YAAY,EAAE,sBAAsB,EACpC,WAAmB,EACnB,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,kBAAkB,+BAqCpB;AAED,iBAAS,gBAAgB,CAAC,EACxB,KAAK,EACL,MAAc,EACd,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,kBAAkB,CAAC,GAAG;IACnD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,+BAqDA;AAED,iBAAS,gBAAgB,CAAC,EACxB,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,kBAAkB,CAAC,+BAyBjD;AAED,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAC"}
1
+ {"version":3,"file":"tool-group.d.ts","sourceRoot":"","sources":["../../../src/internal/assistant-ui/tool-group.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAElE,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAK/F,QAAA,MAAM,iBAAiB;;8EASrB,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,IAAI,CACnC,KAAK,CAAC,cAAc,CAAC,OAAO,WAAW,CAAC,EACxC,MAAM,GAAG,cAAc,CACxB,GACC,YAAY,CAAC,OAAO,iBAAiB,CAAC,GAAG;IACvC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEJ,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,OAAO,EACP,IAAI,EAAE,cAAc,EACpB,YAAY,EAAE,sBAAsB,EACpC,WAAmB,EACnB,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,kBAAkB,+BAqCpB;AAED,iBAAS,gBAAgB,CAAC,EACxB,KAAK,EACL,MAAc,EACd,SAAS,EACT,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,kBAAkB,CAAC,GAAG;IACnD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,+BAwCA;AAED,iBAAS,gBAAgB,CAAC,EACxB,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,kBAAkB,CAAC,+BAyBjD;AAED,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAC"}
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useCallback, useRef, useState } from "react";
4
- import { ChevronDownIcon, LoaderIcon } from "lucide-react";
4
+ import { ChevronDownIcon } from "lucide-react";
5
5
  import { cva } from "class-variance-authority";
6
6
  import { useScrollLock } from "@assistant-ui/react";
7
7
  import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../../components/collapsible.js";
@@ -35,8 +35,9 @@ function ToolGroupRoot({ className, variant, open: controlledOpen, onOpenChange:
35
35
  }, ...props, children: children }));
36
36
  }
37
37
  function ToolGroupTrigger({ count, active = false, className, ...props }) {
38
- const label = `${count} tool ${count === 1 ? "call" : "calls"}`;
39
- return (_jsxs(CollapsibleTrigger, { "data-slot": "tool-group-trigger", className: cn("aui-tool-group-trigger nc-transition-paint group/trigger flex origin-left items-center gap-2 text-sm", "group-data-[variant=ghost]/tool-group-root:text-muted-foreground group-data-[variant=ghost]/tool-group-root:hover:text-foreground group-data-[variant=ghost]/tool-group-root:py-1.5", "group-data-[variant=outline]/tool-group-root:w-full group-data-[variant=outline]/tool-group-root:px-4", "group-data-[variant=muted]/tool-group-root:w-full group-data-[variant=muted]/tool-group-root:px-4", className), ...props, children: [active && (_jsx(LoaderIcon, { "data-slot": "tool-group-trigger-loader", className: "aui-tool-group-trigger-loader size-3 shrink-0 animate-spin [animation-duration:var(--nc-duration-spin)]" })), _jsxs("span", { "data-slot": "tool-group-trigger-label", className: cn("aui-tool-group-trigger-label-wrapper relative inline-block text-start leading-none font-medium", "group-data-[variant=ghost]/tool-group-root:font-normal", "group-data-[variant=outline]/tool-group-root:grow", "group-data-[variant=muted]/tool-group-root:grow"), children: [_jsx("span", { className: "text-xs", children: label }), active && (_jsx("span", { "aria-hidden": true, "data-slot": "tool-group-trigger-shimmer", className: "aui-tool-group-trigger-shimmer shimmer pointer-events-none absolute inset-0 text-xs motion-reduce:animate-none", children: label }))] }), _jsx(ChevronDownIcon, { "data-slot": "tool-group-trigger-chevron", className: cn("aui-tool-group-trigger-chevron size-3 shrink-0", "transition-transform duration-(--animation-duration) ease-[var(--nc-ease-out-strong)] motion-reduce:transition-none", "-rotate-90", "group-data-open/trigger:rotate-0", "group-data-panel-open/trigger:rotate-0") })] }));
38
+ // A group still running says so in its own label; nothing spins or shimmers.
39
+ const label = `${count} tool ${count === 1 ? "call" : "calls"}${active ? ", running" : ""}`;
40
+ return (_jsxs(CollapsibleTrigger, { "aria-busy": active || undefined, "data-slot": "tool-group-trigger", className: cn("aui-tool-group-trigger nc-transition-paint group/trigger flex origin-left items-center gap-2 text-sm", "group-data-[variant=ghost]/tool-group-root:text-muted-foreground group-data-[variant=ghost]/tool-group-root:hover:text-foreground group-data-[variant=ghost]/tool-group-root:py-1.5", "group-data-[variant=outline]/tool-group-root:w-full group-data-[variant=outline]/tool-group-root:px-4", "group-data-[variant=muted]/tool-group-root:w-full group-data-[variant=muted]/tool-group-root:px-4", className), ...props, children: [_jsx("span", { "data-slot": "tool-group-trigger-label", className: cn("aui-tool-group-trigger-label-wrapper relative inline-block text-start leading-none font-medium", "group-data-[variant=ghost]/tool-group-root:font-normal", "group-data-[variant=outline]/tool-group-root:grow", "group-data-[variant=muted]/tool-group-root:grow"), children: _jsx("span", { className: "text-xs", children: label }) }), _jsx(ChevronDownIcon, { "data-slot": "tool-group-trigger-chevron", className: cn("aui-tool-group-trigger-chevron size-3 shrink-0", "transition-transform duration-(--animation-duration) ease-[var(--nc-ease-out-strong)] motion-reduce:transition-none", "-rotate-90", "group-data-open/trigger:rotate-0", "group-data-panel-open/trigger:rotate-0") })] }));
40
41
  }
41
42
  function ToolGroupContent({ className, children, ...props }) {
42
43
  return (_jsx(CollapsibleContent, { "data-slot": "tool-group-content", className: cn("aui-tool-group-content relative overflow-hidden text-sm outline-none", "group/collapsible-content", "data-closed:pointer-events-none", className), ...props, children: _jsx("div", { className: cn("mt-2 flex flex-col gap-2", "group-data-[variant=ghost]/tool-group-root:mt-1 group-data-[variant=ghost]/tool-group-root:gap-1", "group-data-[variant=outline]/tool-group-root:mt-3 group-data-[variant=outline]/tool-group-root:border-t group-data-[variant=outline]/tool-group-root:px-4 group-data-[variant=outline]/tool-group-root:pt-3", "group-data-[variant=muted]/tool-group-root:mt-3 group-data-[variant=muted]/tool-group-root:border-t group-data-[variant=muted]/tool-group-root:px-4 group-data-[variant=muted]/tool-group-root:pt-3", "[&>*]:nc-transition-opacity"), children: children }) }));
@@ -4,11 +4,25 @@
4
4
  * Keeping these states behind one internal seam makes token timing and reduced
5
5
  * motion part of every public primitive that consumes them. Base UI supplies
6
6
  * the lifecycle attributes and transform origin; the classes only style them.
7
+ *
8
+ * One reduced-motion policy, the same one `motion.css` states for the CSS
9
+ * layer: movement stops and paint continues. An overlay that scales drops the
10
+ * scale and keeps its fade, because the fade is how the overlay says it arrived
11
+ * or left. A backdrop that only fades is already within the policy and carries
12
+ * no reduced-motion override at all.
7
13
  */
8
- declare const overlayBackdropMotion = "transition-opacity duration-[var(--nc-duration-close)] ease-[var(--nc-ease-out-strong)] data-open:duration-[var(--nc-duration-open)] data-ending-style:opacity-0 data-starting-style:opacity-0 motion-reduce:transition-none motion-reduce:data-ending-style:opacity-100 motion-reduce:data-starting-style:opacity-100";
9
- declare const anchoredOverlayMotion = "origin-(--transform-origin) transition-[opacity,scale] duration-[var(--nc-duration-close)] ease-[var(--nc-ease-out-strong)] data-open:duration-[var(--nc-duration-open)] data-instant:transition-none data-ending-style:opacity-0 data-ending-style:scale-[0.98] data-starting-style:opacity-0 data-starting-style:scale-[0.98] motion-reduce:transition-none motion-reduce:data-ending-style:opacity-100 motion-reduce:data-ending-style:scale-100 motion-reduce:data-starting-style:opacity-100 motion-reduce:data-starting-style:scale-100";
10
- declare const modalOverlayMotion = "transition-[opacity,scale] duration-[var(--nc-duration-close)] ease-[var(--nc-ease-out-strong)] data-open:duration-[var(--nc-duration-open)] data-ending-style:opacity-0 data-ending-style:scale-[0.98] data-starting-style:opacity-0 data-starting-style:scale-[0.98] motion-reduce:transition-none motion-reduce:data-ending-style:opacity-100 motion-reduce:data-ending-style:scale-100 motion-reduce:data-starting-style:opacity-100 motion-reduce:data-starting-style:scale-100";
14
+ declare const overlayBackdropMotion = "transition-opacity duration-[var(--nc-duration-close)] ease-[var(--nc-ease-out-strong)] data-open:duration-[var(--nc-duration-open)] data-ending-style:opacity-0 data-starting-style:opacity-0";
15
+ declare const anchoredOverlayMotion = "origin-(--transform-origin) transition-[opacity,scale] duration-[var(--nc-duration-close)] ease-[var(--nc-ease-out-strong)] data-open:duration-[var(--nc-duration-open)] data-instant:transition-none data-ending-style:opacity-0 data-ending-style:scale-[0.98] data-starting-style:opacity-0 data-starting-style:scale-[0.98] motion-reduce:transition-opacity motion-reduce:data-ending-style:scale-100 motion-reduce:data-starting-style:scale-100";
16
+ declare const modalOverlayMotion = "transition-[opacity,scale] duration-[var(--nc-duration-close)] ease-[var(--nc-ease-out-strong)] data-open:duration-[var(--nc-duration-open)] data-ending-style:opacity-0 data-ending-style:scale-[0.98] data-starting-style:opacity-0 data-starting-style:scale-[0.98] motion-reduce:transition-opacity motion-reduce:data-ending-style:scale-100 motion-reduce:data-starting-style:scale-100";
11
17
  declare const instantOverlayBackdropMotion = "transition-none data-ending-style:opacity-100 data-starting-style:opacity-100";
12
18
  declare const instantModalOverlayMotion = "transition-none data-ending-style:opacity-100 data-ending-style:scale-100 data-starting-style:opacity-100 data-starting-style:scale-100";
13
- export { anchoredOverlayMotion, instantModalOverlayMotion, instantOverlayBackdropMotion, modalOverlayMotion, overlayBackdropMotion, };
19
+ /**
20
+ * The disclosure cadence for the assistant-ui collapsibles: `open`, 220 ms.
21
+ * The stylesheet takes the token; the scroll lock that runs alongside the
22
+ * animation needs a number, so the two spellings sit together here and
23
+ * `motion.test.ts` holds them equal to the shipped contract.
24
+ */
25
+ declare const disclosureDuration = "var(--nc-duration-open)";
26
+ declare const disclosureDurationMs = 220;
27
+ export { anchoredOverlayMotion, disclosureDuration, disclosureDurationMs, instantModalOverlayMotion, instantOverlayBackdropMotion, modalOverlayMotion, overlayBackdropMotion, };
14
28
  //# sourceMappingURL=motion.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"motion.d.ts","sourceRoot":"","sources":["../../src/lib/motion.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,QAAA,MAAM,qBAAqB,2TAC+R,CAAC;AAE3T,QAAA,MAAM,qBAAqB,khBACsf,CAAC;AAElhB,QAAA,MAAM,kBAAkB,ydACgc,CAAC;AAEzd,QAAA,MAAM,4BAA4B,kFAC+C,CAAC;AAElF,QAAA,MAAM,yBAAyB,4IAC4G,CAAC;AAE5I,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,4BAA4B,EAC5B,kBAAkB,EAClB,qBAAqB,GACtB,CAAC"}
1
+ {"version":3,"file":"motion.d.ts","sourceRoot":"","sources":["../../src/lib/motion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,QAAA,MAAM,qBAAqB,mMACuK,CAAC;AAEnM,QAAA,MAAM,qBAAqB,2bAC+Z,CAAC;AAE3b,QAAA,MAAM,kBAAkB,kYACyW,CAAC;AAElY,QAAA,MAAM,4BAA4B,kFAC+C,CAAC;AAElF,QAAA,MAAM,yBAAyB,4IAC4G,CAAC;AAE5I;;;;;GAKG;AACH,QAAA,MAAM,kBAAkB,4BAA4B,CAAC;AACrD,QAAA,MAAM,oBAAoB,MAAM,CAAC;AAEjC,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,oBAAoB,EACpB,yBAAyB,EACzB,4BAA4B,EAC5B,kBAAkB,EAClB,qBAAqB,GACtB,CAAC"}
@@ -4,10 +4,24 @@
4
4
  * Keeping these states behind one internal seam makes token timing and reduced
5
5
  * motion part of every public primitive that consumes them. Base UI supplies
6
6
  * the lifecycle attributes and transform origin; the classes only style them.
7
+ *
8
+ * One reduced-motion policy, the same one `motion.css` states for the CSS
9
+ * layer: movement stops and paint continues. An overlay that scales drops the
10
+ * scale and keeps its fade, because the fade is how the overlay says it arrived
11
+ * or left. A backdrop that only fades is already within the policy and carries
12
+ * no reduced-motion override at all.
7
13
  */
8
- const overlayBackdropMotion = "transition-opacity duration-[var(--nc-duration-close)] ease-[var(--nc-ease-out-strong)] data-open:duration-[var(--nc-duration-open)] data-ending-style:opacity-0 data-starting-style:opacity-0 motion-reduce:transition-none motion-reduce:data-ending-style:opacity-100 motion-reduce:data-starting-style:opacity-100";
9
- const anchoredOverlayMotion = "origin-(--transform-origin) transition-[opacity,scale] duration-[var(--nc-duration-close)] ease-[var(--nc-ease-out-strong)] data-open:duration-[var(--nc-duration-open)] data-instant:transition-none data-ending-style:opacity-0 data-ending-style:scale-[0.98] data-starting-style:opacity-0 data-starting-style:scale-[0.98] motion-reduce:transition-none motion-reduce:data-ending-style:opacity-100 motion-reduce:data-ending-style:scale-100 motion-reduce:data-starting-style:opacity-100 motion-reduce:data-starting-style:scale-100";
10
- const modalOverlayMotion = "transition-[opacity,scale] duration-[var(--nc-duration-close)] ease-[var(--nc-ease-out-strong)] data-open:duration-[var(--nc-duration-open)] data-ending-style:opacity-0 data-ending-style:scale-[0.98] data-starting-style:opacity-0 data-starting-style:scale-[0.98] motion-reduce:transition-none motion-reduce:data-ending-style:opacity-100 motion-reduce:data-ending-style:scale-100 motion-reduce:data-starting-style:opacity-100 motion-reduce:data-starting-style:scale-100";
14
+ const overlayBackdropMotion = "transition-opacity duration-[var(--nc-duration-close)] ease-[var(--nc-ease-out-strong)] data-open:duration-[var(--nc-duration-open)] data-ending-style:opacity-0 data-starting-style:opacity-0";
15
+ const anchoredOverlayMotion = "origin-(--transform-origin) transition-[opacity,scale] duration-[var(--nc-duration-close)] ease-[var(--nc-ease-out-strong)] data-open:duration-[var(--nc-duration-open)] data-instant:transition-none data-ending-style:opacity-0 data-ending-style:scale-[0.98] data-starting-style:opacity-0 data-starting-style:scale-[0.98] motion-reduce:transition-opacity motion-reduce:data-ending-style:scale-100 motion-reduce:data-starting-style:scale-100";
16
+ const modalOverlayMotion = "transition-[opacity,scale] duration-[var(--nc-duration-close)] ease-[var(--nc-ease-out-strong)] data-open:duration-[var(--nc-duration-open)] data-ending-style:opacity-0 data-ending-style:scale-[0.98] data-starting-style:opacity-0 data-starting-style:scale-[0.98] motion-reduce:transition-opacity motion-reduce:data-ending-style:scale-100 motion-reduce:data-starting-style:scale-100";
11
17
  const instantOverlayBackdropMotion = "transition-none data-ending-style:opacity-100 data-starting-style:opacity-100";
12
18
  const instantModalOverlayMotion = "transition-none data-ending-style:opacity-100 data-ending-style:scale-100 data-starting-style:opacity-100 data-starting-style:scale-100";
13
- export { anchoredOverlayMotion, instantModalOverlayMotion, instantOverlayBackdropMotion, modalOverlayMotion, overlayBackdropMotion, };
19
+ /**
20
+ * The disclosure cadence for the assistant-ui collapsibles: `open`, 220 ms.
21
+ * The stylesheet takes the token; the scroll lock that runs alongside the
22
+ * animation needs a number, so the two spellings sit together here and
23
+ * `motion.test.ts` holds them equal to the shipped contract.
24
+ */
25
+ const disclosureDuration = "var(--nc-duration-open)";
26
+ const disclosureDurationMs = 220;
27
+ export { anchoredOverlayMotion, disclosureDuration, disclosureDurationMs, instantModalOverlayMotion, instantOverlayBackdropMotion, modalOverlayMotion, overlayBackdropMotion, };
@@ -16,7 +16,6 @@
16
16
 
17
17
  @import "tailwindcss";
18
18
  @import "tw-animate-css";
19
- @import "tw-shimmer";
20
19
  @import "@assistant-ui/react-markdown/styles/dot.css";
21
20
  @import "./shadcn.tailwind.css";
22
21
  @import "@nadicodeai/design-system/css";