@cueplusplus/ui 0.14.0 → 0.15.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 (352) hide show
  1. package/CHANGELOG.md +340 -0
  2. package/dist/agent-runtime/tool-call-card.js +1 -1
  3. package/dist/chat/message.js +1 -1
  4. package/dist/chrome/band.js +10 -4
  5. package/dist/chrome/eyebrow.js +1 -1
  6. package/dist/chrome/footer.js +1 -1
  7. package/dist/chrome/section-header.js +1 -1
  8. package/dist/configurator/configurator.js +1 -1
  9. package/dist/configurator/export-dialog.js +1 -1
  10. package/dist/configurator/panel-sections.js +1 -1
  11. package/dist/configurator/token-editor.js +1 -1
  12. package/dist/date/calendar.js +2 -2
  13. package/dist/elements/context-usage.js +3 -3
  14. package/dist/elements/transcript-rules.js +1 -1
  15. package/dist/forms/field.js +1 -1
  16. package/dist/forms/slider.js +1 -1
  17. package/dist/instruments/code-block.js +1 -1
  18. package/dist/instruments/ledger.js +1 -1
  19. package/dist/instruments/progress.js +1 -1
  20. package/dist/instruments/stat.js +1 -1
  21. package/dist/instruments/table.js +2 -2
  22. package/dist/instruments/terminal-frame.js +1 -1
  23. package/dist/layout/_ground.js +1 -1
  24. package/dist/layout/collapsible.js +1 -1
  25. package/dist/layout/description-list.js +1 -1
  26. package/dist/layout/preview.d.ts +13 -1
  27. package/dist/layout/preview.js +16 -9
  28. package/dist/layout/sidebar.js +1 -1
  29. package/dist/layout/stepper.js +1 -1
  30. package/dist/overlays/_surface.d.ts +1 -1
  31. package/dist/overlays/_surface.js +1 -1
  32. package/dist/overlays/command-palette.js +1 -1
  33. package/dist/overlays/toast.js +1 -1
  34. package/dist/primitives/chip.d.ts +1 -1
  35. package/dist/primitives/chip.js +2 -2
  36. package/dist/system/density.d.ts +11 -2
  37. package/dist/system/density.js +29 -9
  38. package/dist/system/portal.js +8 -2
  39. package/dist/system/prepaint.d.ts +18 -1
  40. package/dist/system/prepaint.js +8 -2
  41. package/dist/system/theme-provider.d.ts +42 -5
  42. package/dist/system/theme-provider.js +84 -19
  43. package/dist/system/vocabulary.d.ts +1 -1
  44. package/dist/system/vocabulary.js +14 -2
  45. package/manifest/components/accordion.json +16 -4
  46. package/manifest/components/activity-graph.json +15 -3
  47. package/manifest/components/agent-card.json +15 -3
  48. package/manifest/components/agent-handoff.json +14 -3
  49. package/manifest/components/agent-mode-badge.json +12 -3
  50. package/manifest/components/agent-pile.json +13 -3
  51. package/manifest/components/agent-plan.json +13 -3
  52. package/manifest/components/agent-status.json +14 -3
  53. package/manifest/components/agent-surface.json +12 -3
  54. package/manifest/components/alert-dialog.json +16 -4
  55. package/manifest/components/animated-number.json +12 -3
  56. package/manifest/components/app-window-frame.json +13 -3
  57. package/manifest/components/approval-card.json +14 -3
  58. package/manifest/components/artifact-card.json +14 -3
  59. package/manifest/components/ask-box.json +13 -3
  60. package/manifest/components/audience-icon.json +11 -3
  61. package/manifest/components/autocomplete.json +17 -4
  62. package/manifest/components/avatar-group.json +15 -4
  63. package/manifest/components/avatar.json +16 -4
  64. package/manifest/components/background-inbox.json +14 -3
  65. package/manifest/components/band.json +15 -5
  66. package/manifest/components/breadcrumb.json +14 -3
  67. package/manifest/components/button-group.json +13 -3
  68. package/manifest/components/calendar.json +18 -5
  69. package/manifest/components/canvas-split-body.json +13 -3
  70. package/manifest/components/canvas-split-document.json +11 -3
  71. package/manifest/components/canvas-split-header.json +13 -3
  72. package/manifest/components/canvas-split-line.json +13 -3
  73. package/manifest/components/canvas-split-message.json +13 -3
  74. package/manifest/components/canvas-split-thread.json +11 -3
  75. package/manifest/components/canvas-split.json +13 -3
  76. package/manifest/components/card.json +14 -3
  77. package/manifest/components/carousel.json +12 -3
  78. package/manifest/components/catalogue-icon.json +11 -3
  79. package/manifest/components/channel-beta-icon.json +11 -3
  80. package/manifest/components/channel-matrix.json +13 -4
  81. package/manifest/components/channel-released-icon.json +11 -3
  82. package/manifest/components/chart-container.json +11 -3
  83. package/manifest/components/chart-ramp.json +12 -3
  84. package/manifest/components/chart-swatch.json +11 -3
  85. package/manifest/components/chart-tooltip-content.json +14 -5
  86. package/manifest/components/chart.json +14 -3
  87. package/manifest/components/chat-empty-state.json +13 -3
  88. package/manifest/components/chat-panel-assistant-message.json +11 -3
  89. package/manifest/components/chat-panel-composer.json +11 -3
  90. package/manifest/components/chat-panel-messages.json +11 -3
  91. package/manifest/components/chat-panel-typing.json +11 -3
  92. package/manifest/components/chat-panel-user-message.json +11 -3
  93. package/manifest/components/chat-panel.json +13 -3
  94. package/manifest/components/checkbox-group.json +15 -4
  95. package/manifest/components/checkpoint-history.json +13 -3
  96. package/manifest/components/chip.json +1 -0
  97. package/manifest/components/clamp.json +12 -3
  98. package/manifest/components/cli-tool-icon.json +11 -3
  99. package/manifest/components/code-block.json +2 -1
  100. package/manifest/components/code-diff.json +14 -3
  101. package/manifest/components/code-runner.json +13 -3
  102. package/manifest/components/collapsible.json +15 -4
  103. package/manifest/components/color-area.json +12 -4
  104. package/manifest/components/color-field.json +12 -3
  105. package/manifest/components/color-picker.json +14 -4
  106. package/manifest/components/color-slider.json +12 -3
  107. package/manifest/components/color-swatch.json +13 -3
  108. package/manifest/components/colors-section.json +13 -4
  109. package/manifest/components/combobox.json +17 -5
  110. package/manifest/components/command-palette.json +2 -1
  111. package/manifest/components/compaction-row.json +12 -3
  112. package/manifest/components/comparison-card.json +12 -3
  113. package/manifest/components/composer-actions.json +11 -3
  114. package/manifest/components/composer-attach-button.json +11 -3
  115. package/manifest/components/composer-attachment-chip.json +13 -3
  116. package/manifest/components/composer-attachments.json +11 -3
  117. package/manifest/components/composer-bar.json +12 -3
  118. package/manifest/components/composer-command-item.json +13 -3
  119. package/manifest/components/composer-context.json +13 -3
  120. package/manifest/components/composer-input.json +11 -3
  121. package/manifest/components/composer-menu-item.json +12 -3
  122. package/manifest/components/composer-menu.json +13 -3
  123. package/manifest/components/composer-model-item.json +13 -3
  124. package/manifest/components/composer-model-trigger.json +13 -3
  125. package/manifest/components/composer-person-item.json +13 -3
  126. package/manifest/components/composer-send.json +13 -3
  127. package/manifest/components/composer-toolbar.json +11 -3
  128. package/manifest/components/composer-voice-button.json +11 -3
  129. package/manifest/components/composer-voice.json +13 -3
  130. package/manifest/components/composer.json +14 -4
  131. package/manifest/components/computer-use.json +13 -3
  132. package/manifest/components/confidence-marker.json +11 -3
  133. package/manifest/components/connection-state.json +12 -3
  134. package/manifest/components/container.json +12 -3
  135. package/manifest/components/context-breakdown.json +12 -4
  136. package/manifest/components/context-menu.json +16 -5
  137. package/manifest/components/context-usage.json +15 -4
  138. package/manifest/components/conversation-search.json +13 -3
  139. package/manifest/components/copy-button.json +14 -3
  140. package/manifest/components/cost-meter.json +12 -3
  141. package/manifest/components/cue-portal-frame.json +12 -3
  142. package/manifest/components/data-table-pagination.json +13 -3
  143. package/manifest/components/data-table-toolbar.json +12 -3
  144. package/manifest/components/date-field.json +12 -3
  145. package/manifest/components/date-picker.json +13 -3
  146. package/manifest/components/date-range-picker.json +11 -3
  147. package/manifest/components/day-separator.json +12 -3
  148. package/manifest/components/delegation-card.json +14 -4
  149. package/manifest/components/density.json +25 -2
  150. package/manifest/components/description-list.json +17 -5
  151. package/manifest/components/diagram.json +13 -3
  152. package/manifest/components/dialog.json +2 -1
  153. package/manifest/components/disclosure.json +17 -5
  154. package/manifest/components/dmx-bar.json +14 -4
  155. package/manifest/components/dmx-strip.json +13 -4
  156. package/manifest/components/document-reference.json +13 -3
  157. package/manifest/components/draft-restore.json +13 -3
  158. package/manifest/components/drawer.json +15 -5
  159. package/manifest/components/dropdown-menu.json +2 -1
  160. package/manifest/components/edit-message.json +13 -3
  161. package/manifest/components/elements-command-palette.json +13 -3
  162. package/manifest/components/elements-composer.json +13 -3
  163. package/manifest/components/elements-data-table.json +11 -3
  164. package/manifest/components/elements-timeline.json +13 -3
  165. package/manifest/components/elicitation-form.json +13 -3
  166. package/manifest/components/empty-state-composer.json +11 -3
  167. package/manifest/components/empty-state-greeting.json +11 -3
  168. package/manifest/components/empty-state-suggestion.json +11 -3
  169. package/manifest/components/empty-state-suggestions.json +11 -3
  170. package/manifest/components/empty-state.json +15 -4
  171. package/manifest/components/end-of-turn-summary.json +14 -3
  172. package/manifest/components/env-var-input.json +15 -4
  173. package/manifest/components/error-state.json +13 -3
  174. package/manifest/components/export-dialog.json +12 -3
  175. package/manifest/components/eyebrow.json +16 -5
  176. package/manifest/components/feedback-dialog.json +13 -3
  177. package/manifest/components/field-description.json +17 -5
  178. package/manifest/components/field-error.json +17 -5
  179. package/manifest/components/field-label.json +17 -5
  180. package/manifest/components/field.json +2 -1
  181. package/manifest/components/file-tree.json +13 -3
  182. package/manifest/components/file-upload.json +14 -4
  183. package/manifest/components/flow-background.json +11 -3
  184. package/manifest/components/flow-controls.json +11 -3
  185. package/manifest/components/flow-graph.json +13 -3
  186. package/manifest/components/folder-icon.json +12 -3
  187. package/manifest/components/footer.json +1 -0
  188. package/manifest/components/frac.json +11 -3
  189. package/manifest/components/frames.json +2 -1
  190. package/manifest/components/generation-loader.json +13 -3
  191. package/manifest/components/generative-ui.json +16 -4
  192. package/manifest/components/grid.json +14 -3
  193. package/manifest/components/group-bar.json +13 -3
  194. package/manifest/components/guardrail-notice.json +13 -3
  195. package/manifest/components/hover-card.json +16 -5
  196. package/manifest/components/icon-button.json +15 -3
  197. package/manifest/components/image-generation.json +13 -3
  198. package/manifest/components/info-tip.json +15 -4
  199. package/manifest/components/inline-citation.json +13 -3
  200. package/manifest/components/input-group.json +15 -4
  201. package/manifest/components/item.json +15 -4
  202. package/manifest/components/job-progress.json +14 -3
  203. package/manifest/components/kbd.json +14 -3
  204. package/manifest/components/launcher-bubble.json +14 -3
  205. package/manifest/components/ledger.json +2 -1
  206. package/manifest/components/link.json +13 -3
  207. package/manifest/components/live-region-announcer.json +16 -4
  208. package/manifest/components/log-viewer.json +15 -3
  209. package/manifest/components/map-answer.json +13 -3
  210. package/manifest/components/markdown-text.json +16 -4
  211. package/manifest/components/math-block.json +13 -3
  212. package/manifest/components/mcp-server-icon.json +12 -3
  213. package/manifest/components/mcp-server-panel.json +13 -3
  214. package/manifest/components/memory-chips.json +12 -3
  215. package/manifest/components/menubar.json +15 -4
  216. package/manifest/components/message-actions.json +14 -4
  217. package/manifest/components/message-attachments.json +12 -3
  218. package/manifest/components/message-branches.json +12 -3
  219. package/manifest/components/message-list.json +12 -3
  220. package/manifest/components/message-pair.json +12 -3
  221. package/manifest/components/message-queue.json +13 -3
  222. package/manifest/components/message-timing.json +13 -3
  223. package/manifest/components/message.json +14 -4
  224. package/manifest/components/mobile-composer.json +14 -3
  225. package/manifest/components/model-picker.json +12 -3
  226. package/manifest/components/multi-select.json +18 -5
  227. package/manifest/components/musical-time-input.json +11 -3
  228. package/manifest/components/navigation-menu.json +15 -4
  229. package/manifest/components/node-card.json +11 -3
  230. package/manifest/components/node-handle.json +11 -3
  231. package/manifest/components/number-field.json +15 -3
  232. package/manifest/components/number-ticker.json +12 -3
  233. package/manifest/components/onboarding.json +12 -3
  234. package/manifest/components/otp-field.json +14 -3
  235. package/manifest/components/page-shell.json +14 -4
  236. package/manifest/components/pagination.json +14 -3
  237. package/manifest/components/panel-header.json +14 -4
  238. package/manifest/components/password-input.json +15 -4
  239. package/manifest/components/permission-grant.json +13 -3
  240. package/manifest/components/permission-scopes.json +14 -3
  241. package/manifest/components/piano-keyboard.json +11 -3
  242. package/manifest/components/popover.json +2 -1
  243. package/manifest/components/preset-section.json +13 -4
  244. package/manifest/components/preview.json +15 -1
  245. package/manifest/components/progress.json +16 -4
  246. package/manifest/components/prompt-library.json +12 -3
  247. package/manifest/components/queue-dock.json +14 -3
  248. package/manifest/components/quota-banner.json +12 -3
  249. package/manifest/components/quote-reply.json +12 -3
  250. package/manifest/components/radio-group.json +15 -4
  251. package/manifest/components/radio.json +15 -4
  252. package/manifest/components/rating.json +15 -4
  253. package/manifest/components/read-aloud.json +13 -3
  254. package/manifest/components/reasoning-effort.json +12 -3
  255. package/manifest/components/reasoning-panel.json +13 -3
  256. package/manifest/components/recommendation-card.json +12 -3
  257. package/manifest/components/regenerate-menu.json +12 -3
  258. package/manifest/components/replay-player.json +14 -3
  259. package/manifest/components/research-report.json +12 -3
  260. package/manifest/components/resizable.json +13 -3
  261. package/manifest/components/retrieval-chunks.json +13 -3
  262. package/manifest/components/revert-dock.json +14 -3
  263. package/manifest/components/reviewable-diff.json +12 -3
  264. package/manifest/components/risk-badge.json +14 -3
  265. package/manifest/components/schedule-card.json +12 -3
  266. package/manifest/components/score-breakdown.json +13 -3
  267. package/manifest/components/scroll-anchor.json +12 -3
  268. package/manifest/components/scroll-area.json +13 -3
  269. package/manifest/components/scrollable-tabs-list.json +14 -4
  270. package/manifest/components/seam-cell.json +13 -4
  271. package/manifest/components/seam-grid.json +14 -3
  272. package/manifest/components/seam-list.json +13 -3
  273. package/manifest/components/search-input.json +15 -4
  274. package/manifest/components/section-header.json +16 -4
  275. package/manifest/components/segmented-control.json +15 -3
  276. package/manifest/components/separator.json +14 -3
  277. package/manifest/components/settings-panel.json +13 -3
  278. package/manifest/components/shape-section.json +13 -4
  279. package/manifest/components/shared-conversation.json +12 -3
  280. package/manifest/components/sheet.json +16 -5
  281. package/manifest/components/shimmer-label.json +12 -3
  282. package/manifest/components/sidebar.json +17 -5
  283. package/manifest/components/signal-edge.json +13 -4
  284. package/manifest/components/skeleton.json +16 -4
  285. package/manifest/components/skill-icon.json +12 -3
  286. package/manifest/components/slider.json +16 -4
  287. package/manifest/components/sources.json +12 -3
  288. package/manifest/components/sparkline.json +14 -4
  289. package/manifest/components/speaker-identity.json +11 -3
  290. package/manifest/components/spec-sheet.json +13 -4
  291. package/manifest/components/spectrum-visualizer.json +11 -3
  292. package/manifest/components/spinner.json +16 -4
  293. package/manifest/components/stack-icon.json +12 -3
  294. package/manifest/components/stack.json +14 -3
  295. package/manifest/components/stacks-matrix-icon.json +11 -3
  296. package/manifest/components/stat.json +15 -3
  297. package/manifest/components/status-dot.json +16 -4
  298. package/manifest/components/stepper.json +17 -5
  299. package/manifest/components/stopped-run.json +13 -4
  300. package/manifest/components/streaming-text.json +12 -3
  301. package/manifest/components/sub.json +11 -3
  302. package/manifest/components/subagent-list.json +13 -3
  303. package/manifest/components/suggestions.json +12 -3
  304. package/manifest/components/sup.json +11 -3
  305. package/manifest/components/swap-label.json +12 -3
  306. package/manifest/components/table-scroll-region.json +2 -1
  307. package/manifest/components/table.json +2 -1
  308. package/manifest/components/tags-input.json +17 -5
  309. package/manifest/components/tail-status.json +14 -3
  310. package/manifest/components/terminal-block.json +13 -3
  311. package/manifest/components/terminal-frame.json +15 -3
  312. package/manifest/components/textarea.json +15 -4
  313. package/manifest/components/theme-configurator.json +14 -4
  314. package/manifest/components/theme-provider.json +14 -1
  315. package/manifest/components/thinking-indicator.json +12 -3
  316. package/manifest/components/thread-list.json +12 -3
  317. package/manifest/components/thread-search.json +12 -3
  318. package/manifest/components/threshold-rail.json +13 -3
  319. package/manifest/components/time-boundary.json +15 -4
  320. package/manifest/components/time-field.json +15 -4
  321. package/manifest/components/timeline-ruler.json +13 -3
  322. package/manifest/components/timeline.json +13 -3
  323. package/manifest/components/title-bar.json +13 -3
  324. package/manifest/components/toast.json +2 -0
  325. package/manifest/components/todo-list.json +12 -3
  326. package/manifest/components/toggle-group.json +15 -4
  327. package/manifest/components/toggle.json +15 -4
  328. package/manifest/components/token-editor.json +14 -4
  329. package/manifest/components/tool-call-card.json +2 -1
  330. package/manifest/components/tool-call.json +13 -3
  331. package/manifest/components/tool-error.json +14 -4
  332. package/manifest/components/tool-group.json +12 -3
  333. package/manifest/components/tool-timeline.json +14 -4
  334. package/manifest/components/toolbar.json +14 -4
  335. package/manifest/components/tooltip.json +2 -1
  336. package/manifest/components/trace-waterfall.json +12 -3
  337. package/manifest/components/tree-visibility-toggle.json +13 -3
  338. package/manifest/components/tree.json +14 -3
  339. package/manifest/components/turn-footer.json +14 -3
  340. package/manifest/components/two-step-button.json +14 -3
  341. package/manifest/components/typing-indicator.json +12 -3
  342. package/manifest/components/universe-grid.json +14 -4
  343. package/manifest/components/unread-divider.json +16 -5
  344. package/manifest/components/usage-chart.json +14 -3
  345. package/manifest/components/verdict-row.json +14 -3
  346. package/manifest/components/voice-conversation.json +13 -3
  347. package/manifest/components/web-preview.json +13 -3
  348. package/manifest/components/web-search.json +13 -3
  349. package/manifest/components/work-collapse.json +15 -4
  350. package/manifest/manifest.json +667 -667
  351. package/manifest/tokens.json +29 -2
  352. package/package.json +2 -2
@@ -1,14 +1,15 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.js";
3
3
  import { useIsomorphicInsertionEffect, useIsomorphicLayoutEffect } from "./use-isomorphic-layout-effect.js";
4
- import { AmbientThemeContext, DensityContext, StyleSetContext } from "./density.js";
5
- import { buildRegistry, isStyleSet, vocabulary, warnOnce } from "./vocabulary.js";
4
+ import { AmbientThemeContext, DensityContext, PaintContext, StyleSetContext } from "./density.js";
5
+ import { buildRegistry, isPaint, isStyleSet, vocabulary, warnOnce } from "./vocabulary.js";
6
6
  import { OverridesContext, inlineOverrides, overridesCss, reportOverrides } from "./overrides.js";
7
7
  import { DEFAULT_STORAGE_KEY } from "./prepaint.js";
8
8
  import { ThemeRegistryContext } from "./theme-registry.js";
9
9
  import * as React from "react";
10
10
  import { jsx, jsxs } from "react/jsx-runtime";
11
11
  import { MODES, THEME_NAME_PATTERN, validateManifest } from "@cueplusplus/theme-base";
12
+ import { CSPProvider } from "@base-ui/react/csp-provider";
12
13
  //#region src/system/theme-provider.tsx
13
14
  /**
14
15
  * The empty registry, at module scope so the default is referentially stable.
@@ -116,16 +117,21 @@ function acceptedPreferences(vocab, stored, fallback) {
116
117
  density: vocab.acceptsDensity(theme, stored.density) ? stored.density : vocab.acceptsDensity(theme, fallback.density) ? fallback.density : vocab.preferredDensity(theme),
117
118
  font: vocab.acceptsFont(theme, stored.font) ? stored.font : vocab.acceptsFont(theme, fallback.font) ? fallback.font : vocab.preferredFont(theme),
118
119
  mode: isOneOf(MODES, stored.mode) ? stored.mode : fallback.mode,
119
- styleSet: isStyleSet(stored.style) ? stored.style : fallback.styleSet
120
+ styleSet: isStyleSet(stored.style) ? stored.style : fallback.styleSet,
121
+ paint: isPaint(stored.paint) ? stored.paint : fallback.paint
120
122
  };
121
123
  }
122
124
  function writePreferences(storageKey, preferences) {
123
125
  if (typeof localStorage === "undefined") return;
124
- const { styleSet, ...axes } = preferences;
125
- const payload = styleSet === null ? axes : {
126
+ const { styleSet, paint, ...axes } = preferences;
127
+ const withStyle = styleSet === null ? axes : {
126
128
  ...axes,
127
129
  style: styleSet
128
130
  };
131
+ const payload = paint === null ? withStyle : {
132
+ ...withStyle,
133
+ paint
134
+ };
129
135
  try {
130
136
  localStorage.setItem(storageKey, JSON.stringify(payload));
131
137
  } catch {}
@@ -170,10 +176,11 @@ function writePreferences(storageKey, preferences) {
170
176
  * <App />
171
177
  * </ThemeProvider>
172
178
  */
173
- function ThemeProvider({ themes: themesProp, theme: themeProp, density: densityProp, mode: modeProp = DEFAULT_MODE, font: fontProp, styleSet: styleSetProp, fontScale = 1, fontFamilies, overrides, storageKey = DEFAULT_STORAGE_KEY, persistPreferences = true, nonce, asChild = false, className, style: styleProp, children }) {
179
+ function ThemeProvider({ themes: themesProp, theme: themeProp, density: densityProp, mode: modeProp = DEFAULT_MODE, font: fontProp, styleSet: styleSetProp, paint: paintProp, fontScale = 1, fontFamilies, overrides, storageKey = DEFAULT_STORAGE_KEY, persistPreferences = true, nonce, asChild = false, className, style: styleProp, children }) {
174
180
  const ambient = React.useContext(ThemeContext);
175
181
  const isRoot = ambient === null;
176
182
  const outerStyleSet = React.useContext(StyleSetContext);
183
+ const outerPaint = React.useContext(PaintContext);
177
184
  const ambientRegistry = React.useContext(ThemeRegistryContext);
178
185
  const themes = themesProp ?? ambientRegistry?.themes ?? EMPTY;
179
186
  const vocab = React.useMemo(() => vocabulary(themes), [themes]);
@@ -199,10 +206,12 @@ function ThemeProvider({ themes: themesProp, theme: themeProp, density: densityP
199
206
  const initialDensity = densityProp ?? vocab.preferredDensity(initialTheme);
200
207
  const initialFont = fontProp ?? vocab.preferredFont(initialTheme);
201
208
  const initialStyleSet = styleSetProp ?? (isRoot ? null : outerStyleSet);
209
+ const initialPaint = paintProp ?? (isRoot ? null : outerPaint);
202
210
  const [theme, setThemeState] = React.useState(initialTheme);
203
211
  const [densityState, setDensityState] = React.useState(initialDensity);
204
212
  const [mode, setModeState] = React.useState(modeProp);
205
213
  const [styleSet, setStyleSetState] = React.useState(initialStyleSet);
214
+ const [paint, setPaintState] = React.useState(initialPaint);
206
215
  const [storedSeed] = React.useState(() => {
207
216
  if (!isRoot || !persistPreferences) return {
208
217
  theme: initialTheme,
@@ -244,14 +253,16 @@ function ThemeProvider({ themes: themesProp, theme: themeProp, density: densityP
244
253
  density,
245
254
  font,
246
255
  mode,
247
- styleSet
256
+ styleSet,
257
+ paint
248
258
  });
249
259
  setThemeState(next.theme);
250
260
  setDensityState(next.density);
251
261
  setRootFontState(next.font);
252
262
  setModeState(next.mode);
253
263
  setStyleSetState(next.styleSet);
254
- if (stored.theme !== void 0 && stored.theme !== next.theme || stored.density !== void 0 && stored.density !== next.density || stored.font !== void 0 && stored.font !== next.font || stored.mode !== void 0 && stored.mode !== next.mode || stored.style !== void 0 && !isStyleSet(stored.style)) writePreferences(storageKey, next);
264
+ setPaintState(next.paint);
265
+ if (stored.theme !== void 0 && stored.theme !== next.theme || stored.density !== void 0 && stored.density !== next.density || stored.font !== void 0 && stored.font !== next.font || stored.mode !== void 0 && stored.mode !== next.mode || stored.style !== void 0 && !isStyleSet(stored.style) || stored.paint !== void 0 && !isPaint(stored.paint)) writePreferences(storageKey, next);
255
266
  }, [
256
267
  isRoot,
257
268
  persistPreferences,
@@ -262,7 +273,8 @@ function ThemeProvider({ themes: themesProp, theme: themeProp, density: densityP
262
273
  density: densityProp,
263
274
  mode: modeProp,
264
275
  font: fontProp,
265
- styleSet: styleSetProp
276
+ styleSet: styleSetProp,
277
+ paint: paintProp
266
278
  });
267
279
  React.useEffect(() => {
268
280
  const previous = lastProps.current;
@@ -271,19 +283,22 @@ function ThemeProvider({ themes: themesProp, theme: themeProp, density: densityP
271
283
  density: densityProp,
272
284
  mode: modeProp,
273
285
  font: fontProp,
274
- styleSet: styleSetProp
286
+ styleSet: styleSetProp,
287
+ paint: paintProp
275
288
  };
276
289
  if (previous.theme !== themeProp && themeProp !== void 0) setThemeState(themeProp);
277
290
  if (previous.density !== densityProp && densityProp !== void 0) setDensityState(densityProp);
278
291
  if (previous.mode !== modeProp) setModeState(modeProp);
279
292
  if (previous.font !== fontProp && fontProp !== void 0) setRootFontState(fontProp);
280
293
  if (previous.styleSet !== styleSetProp && styleSetProp !== void 0) setStyleSetState(styleSetProp);
294
+ if (previous.paint !== paintProp && paintProp !== void 0) setPaintState(paintProp);
281
295
  }, [
282
296
  themeProp,
283
297
  densityProp,
284
298
  modeProp,
285
299
  fontProp,
286
- styleSetProp
300
+ styleSetProp,
301
+ paintProp
287
302
  ]);
288
303
  useIsomorphicLayoutEffect(() => {
289
304
  if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
@@ -298,7 +313,8 @@ function ThemeProvider({ themes: themesProp, theme: themeProp, density: densityP
298
313
  density: densityState,
299
314
  mode,
300
315
  font: rawFont,
301
- styleSet
316
+ styleSet,
317
+ paint
302
318
  });
303
319
  useIsomorphicLayoutEffect(() => {
304
320
  stateRef.current = {
@@ -306,7 +322,8 @@ function ThemeProvider({ themes: themesProp, theme: themeProp, density: densityP
306
322
  density: densityState,
307
323
  mode,
308
324
  font: rawFont,
309
- styleSet
325
+ styleSet,
326
+ paint
310
327
  };
311
328
  });
312
329
  const persist = React.useCallback((patch) => {
@@ -344,6 +361,10 @@ function ThemeProvider({ themes: themesProp, theme: themeProp, density: densityP
344
361
  setStyleSetState(next);
345
362
  persist({ styleSet: next });
346
363
  }, [persist]);
364
+ const setPaint = React.useCallback((next) => {
365
+ setPaintState(next);
366
+ persist({ paint: next });
367
+ }, [persist]);
347
368
  const originalStamp = React.useRef(null);
348
369
  useIsomorphicInsertionEffect(() => {
349
370
  if (!isRoot || typeof document === "undefined") return;
@@ -353,7 +374,8 @@ function ThemeProvider({ themes: themesProp, theme: themeProp, density: densityP
353
374
  density,
354
375
  font,
355
376
  mode,
356
- styleSet
377
+ styleSet,
378
+ paint
357
379
  };
358
380
  const next = restored || !persistPreferences ? current : acceptedPreferences(vocab, readPreferences(storageKey), current);
359
381
  originalStamp.current ??= {
@@ -362,6 +384,7 @@ function ThemeProvider({ themes: themesProp, theme: themeProp, density: densityP
362
384
  font: root.getAttribute("data-font"),
363
385
  mode: root.getAttribute("data-mode"),
364
386
  style: root.getAttribute("data-style"),
387
+ paint: root.getAttribute("data-paint"),
365
388
  colorScheme: root.style.colorScheme
366
389
  };
367
390
  const write = (name, value) => {
@@ -374,6 +397,9 @@ function ThemeProvider({ themes: themesProp, theme: themeProp, density: densityP
374
397
  if (next.styleSet === null) {
375
398
  if (root.hasAttribute("data-style")) root.removeAttribute("data-style");
376
399
  } else write("data-style", next.styleSet);
400
+ if (next.paint === null) {
401
+ if (root.hasAttribute("data-paint")) root.removeAttribute("data-paint");
402
+ } else write("data-paint", next.paint);
377
403
  const scheme = (themes.find((m) => m.name === next.theme) ?? null)?.supportsLight === false ? "dark" : next.mode === "system" ? "light dark" : next.mode;
378
404
  if (root.style.colorScheme !== scheme) root.style.colorScheme = scheme;
379
405
  }, [
@@ -403,9 +429,19 @@ function ThemeProvider({ themes: themesProp, theme: themeProp, density: densityP
403
429
  restore("data-font", original.font);
404
430
  restore("data-mode", original.mode);
405
431
  restore("data-style", original.style);
432
+ restore("data-paint", original.paint);
406
433
  root.style.colorScheme = original.colorScheme;
407
434
  }, []);
408
435
  const effectiveStyleSet = styleSet ?? outerStyleSet;
436
+ /**
437
+ * The pack in force, for the same reason and with the same caveat: it is what
438
+ * `useTheme().paint` reports, and it does NOT feed the `data-paint` stamp.
439
+ * That stays on this provider's own `paint` state, so a root that named none
440
+ * stamps nothing on itself and nothing on `<html>` however much is stamped
441
+ * around it — which keeps a `<Density paint>` island out of the document-wide
442
+ * attribute and out of the storage the pre-paint script reads back.
443
+ */
444
+ const effectivePaint = paint ?? outerPaint;
409
445
  const contextValue = React.useMemo(() => ({
410
446
  theme,
411
447
  manifest,
@@ -413,12 +449,14 @@ function ThemeProvider({ themes: themesProp, theme: themeProp, density: densityP
413
449
  mode,
414
450
  font,
415
451
  styleSet: effectiveStyleSet,
452
+ paint: effectivePaint,
416
453
  resolvedMode,
417
454
  setTheme,
418
455
  setDensity,
419
456
  setMode,
420
457
  setFont,
421
- setStyleSet
458
+ setStyleSet,
459
+ setPaint
422
460
  }), [
423
461
  theme,
424
462
  manifest,
@@ -426,12 +464,14 @@ function ThemeProvider({ themes: themesProp, theme: themeProp, density: densityP
426
464
  mode,
427
465
  font,
428
466
  effectiveStyleSet,
467
+ effectivePaint,
429
468
  resolvedMode,
430
469
  setTheme,
431
470
  setDensity,
432
471
  setMode,
433
472
  setFont,
434
- setStyleSet
473
+ setStyleSet,
474
+ setPaint
435
475
  ]);
436
476
  /** The axes on offer under the theme that is actually active. */
437
477
  const registry = React.useMemo(() => buildRegistry(themes, theme), [themes, theme]);
@@ -490,7 +530,8 @@ function ThemeProvider({ themes: themesProp, theme: themeProp, density: densityP
490
530
  "data-theme": theme,
491
531
  "data-density": density,
492
532
  "data-mode": mode,
493
- ...styleSet === null ? null : { "data-style": styleSet }
533
+ ...styleSet === null ? null : { "data-style": styleSet },
534
+ ...paint === null ? null : { "data-paint": paint }
494
535
  };
495
536
  let root;
496
537
  if (asChild) {
@@ -514,7 +555,31 @@ function ThemeProvider({ themes: themesProp, theme: themeProp, density: densityP
514
555
  "data-cue-overrides": "",
515
556
  children: overridesStyle
516
557
  });
517
- return /* @__PURE__ */ jsx(ThemeRegistryContext.Provider, {
558
+ /**
559
+ * Base UI's own style elements, which this provider's nonce also has to reach.
560
+ *
561
+ * `@base-ui/react` renders one style element — a hoisted
562
+ * `<style precedence>` carrying `.base-ui-disable-scrollbar` — from
563
+ * `utils/styles.mjs`. `ScrollAreaRoot` and `SelectPopup` pass it a nonce they
564
+ * read from Base UI's own `CSPContext`, and nothing fills that context unless
565
+ * a `CSPProvider` is rendered above them. Without one it ships bare and a
566
+ * `style-src-elem` policy refuses it by content hash, on every page that
567
+ * renders a Select, a Popover or a ScrollArea — which is most authenticated
568
+ * pages of a real application, and no page of its sign-in screen. A consumer
569
+ * cannot reasonably guess that the fix lives in a peer dependency's provider,
570
+ * and this library already takes the nonce and already sits at the root.
571
+ *
572
+ * Rendered **only when a nonce was given**, and that is not tidiness. A
573
+ * consumer that wraps its own application in `CSPProvider` is the case this
574
+ * must not break: an unconditional inner provider would overwrite that outer
575
+ * context with `undefined` and un-nonce every Base UI style element in the
576
+ * tree — turning this into the bug it exists to fix.
577
+ */
578
+ const withCspContext = (tree) => nonce === void 0 ? tree : /* @__PURE__ */ jsx(CSPProvider, {
579
+ nonce,
580
+ children: tree
581
+ });
582
+ return withCspContext(/* @__PURE__ */ jsx(ThemeRegistryContext.Provider, {
518
583
  value: registry,
519
584
  children: /* @__PURE__ */ jsx(ThemeContext.Provider, {
520
585
  value: contextValue,
@@ -538,7 +603,7 @@ function ThemeProvider({ themes: themesProp, theme: themeProp, density: densityP
538
603
  })
539
604
  })
540
605
  })
541
- });
606
+ }));
542
607
  }
543
608
  //#endregion
544
609
  export { FontFamiliesContext, FontScaleContext, ThemeContext, ThemeProvider };
@@ -1,4 +1,4 @@
1
- import { StyleSet } from "@cueplusplus/tokens";
1
+ import { Paint, StyleSet } from "@cueplusplus/tokens";
2
2
  import { Density as Density$1, DensityEntry, FontEntry, FontName, ThemeManifest } from "@cueplusplus/theme-base";
3
3
  //#region src/system/vocabulary.d.ts
4
4
  /** What the three registry hooks read: the manifests, and the axes the ACTIVE theme offers. */
@@ -1,4 +1,4 @@
1
- import { DEFAULT_DENSITY, DEFAULT_FONT, STYLE_SETS } from "@cueplusplus/tokens";
1
+ import { DEFAULT_DENSITY, DEFAULT_FONT, PAINTS, STYLE_SETS } from "@cueplusplus/tokens";
2
2
  import { DENSITIES, FONTS, THEME_NAME_PATTERN, resolveDensities, resolveFonts } from "@cueplusplus/theme-base";
3
3
  //#region src/system/vocabulary.ts
4
4
  /**
@@ -82,6 +82,18 @@ function vocabulary(themes) {
82
82
  function isStyleSet(value) {
83
83
  return typeof value === "string" && STYLE_SETS.includes(value);
84
84
  }
85
+ /**
86
+ * Whether a value is one of the look packs.
87
+ *
88
+ * Standalone for exactly the reason {@link isStyleSet} is, and the reason reads
89
+ * the same one axis over: no theme can add a pack. The vocabulary is emitted by
90
+ * `@cueplusplus/tokens`, no manifest field describes it, so there is nothing
91
+ * per-theme to ask and a per-theme signature would be parameters pretending to
92
+ * be a rule.
93
+ */
94
+ function isPaint(value) {
95
+ return typeof value === "string" && PAINTS.includes(value);
96
+ }
85
97
  /** Derive the context value. Pure; the provider memoises it on `themes` and the active name. */
86
98
  function buildRegistry(themes, active) {
87
99
  return {
@@ -122,4 +134,4 @@ function noteOnce(message) {
122
134
  console.info(`[cue] ${message}`);
123
135
  }
124
136
  //#endregion
125
- export { buildRegistry, isStyleSet, noteOnce, vocabulary, warnOnce };
137
+ export { buildRegistry, isPaint, isStyleSet, noteOnce, vocabulary, warnOnce };
@@ -145,7 +145,7 @@
145
145
  "--cue-space-4",
146
146
  "--cue-text-ui"
147
147
  ],
148
- "summary": "A stack of sections, one (or several) open at a time.",
148
+ "summary": "A stack of sections, one or several open at a time.",
149
149
  "examples": [
150
150
  {
151
151
  "title": "Usage",
@@ -153,10 +153,23 @@
153
153
  "language": "tsx"
154
154
  }
155
155
  ],
156
- "status": "todo-docs",
156
+ "status": "stable",
157
157
  "url": "/docs/components/accordion",
158
158
  "mdUrl": "/docs/components/accordion.md",
159
159
  "jsonUrl": "/r/components/accordion.json",
160
+ "whenToUse": [
161
+ "Several peer sections where the reader only needs one at a time: a settings page, a long form split by topic.",
162
+ "Anywhere the closed titles are themselves a useful table of contents."
163
+ ],
164
+ "whenNotToUse": [
165
+ "Exactly one section. Use `Collapsible` — it wears the same skin, so a lone section and a stack of them look alike by design.",
166
+ "Optional detail inside a form. Use `Disclosure`; a summary row that looks like a section header makes a form read as twice as long as it is.",
167
+ "Content the reader must compare side by side. Hiding one to see the other defeats the task."
168
+ ],
169
+ "commonMistakes": [
170
+ "Opening every section by default, which is a page with extra clicks in it.",
171
+ "Reimplementing the open-state bookkeeping. The disclosure ARIA and keyboard handling are Base UI's; this layer only adds the console skin."
172
+ ],
160
173
  "specimens": [
161
174
  {
162
175
  "title": "Accordion",
@@ -168,6 +181,5 @@
168
181
  "note": "Hairline-separated items with mono summary rows. Several can be open at once.",
169
182
  "interaction": "the whole header row is the trigger; the panel animates its height and stills under prefers-reduced-motion."
170
183
  }
171
- ],
172
- "todo": true
184
+ ]
173
185
  }
@@ -84,10 +84,23 @@
84
84
  "language": "tsx"
85
85
  }
86
86
  ],
87
- "status": "todo-docs",
87
+ "status": "stable",
88
88
  "url": "/docs/components/activity-graph",
89
89
  "mdUrl": "/docs/components/activity-graph.md",
90
90
  "jsonUrl": "/r/components/activity-graph.json",
91
+ "whenToUse": [
92
+ "Run volume over a date window, where the question is which days were busy rather than the exact number on any one of them.",
93
+ "A header that needs what is being counted on one side and a pre-formatted total opposite it."
94
+ ],
95
+ "whenNotToUse": [
96
+ "A window you need to fit a fixed width. Cells are fixed-size, so a long range scrolls horizontally rather than shrinking.",
97
+ "Anything that is not a date-and-count series: `data` is date and count pairs, and every gap in the window is filled as an empty cell."
98
+ ],
99
+ "commonMistakes": [
100
+ "Leaving `start` and `end` unset. heat-graph then draws a full year ending today, which will not match your data.",
101
+ "Bucketing the counts into levels yourself. Levels are classified for you from `data`.",
102
+ "Passing a raw number to `total`. It is printed as given, so format it first."
103
+ ],
91
104
  "specimens": [
92
105
  {
93
106
  "title": "ActivityGraph",
@@ -99,6 +112,5 @@
99
112
  "note": "Half a year of runs as a calendar of cells, dense where the work was. It is the one element in the family with a runtime dependency of its own — `heat-graph`, an optional peer — which does the calendar arithmetic and the levelling; everything you can see here is cue's, from the five-step ramp in the streaming hue down to the legend. Cells are a fixed size, so a long window scrolls sideways rather than shrinking into a smudge.",
100
113
  "interaction": "none. The five legend swatches are `aria-hidden` and sit between the words less and more, which is what carries the scale."
101
114
  }
102
- ],
103
- "todo": true
115
+ ]
104
116
  }
@@ -130,10 +130,23 @@
130
130
  "language": "tsx"
131
131
  }
132
132
  ],
133
- "status": "todo-docs",
133
+ "status": "stable",
134
134
  "url": "/docs/components/agent-card",
135
135
  "mdUrl": "/docs/components/agent-card.md",
136
136
  "jsonUrl": "/r/components/agent-card.json",
137
+ "whenToUse": [
138
+ "A directory or picker where someone chooses an agent before the conversation starts.",
139
+ "Advertising named capabilities alongside the provider, version, model and endpoint behind them."
140
+ ],
141
+ "whenNotToUse": [
142
+ "Reporting what an agent is doing right now. The card is a standing description of the agent, not a live state.",
143
+ "An endpoint that has to be read in full. `endpoint` truncates rather than wraps."
144
+ ],
145
+ "commonMistakes": [
146
+ "Rendering your own Connected label beside the action. `connected` already swaps the action for a settled Connected state and disables it.",
147
+ "Writing a paragraph into `description`. It is sized for one or two sentences.",
148
+ "Leaving `onConnect` off while `connected` is false, which shows an action with nowhere to go."
149
+ ],
137
150
  "specimens": [
138
151
  {
139
152
  "title": "AgentCard",
@@ -145,6 +158,5 @@
145
158
  "note": "Who you are about to talk to, before you talk to it: the name and who publishes it, one paragraph on what it is for, the skills it advertises, and — in mono along the bottom — the model and the endpoint actually behind it. Those last two are the line that separates a card from a marketing tile.",
146
159
  "interaction": "the action is the only control. Connected disables it and swaps the ink button for a settled field row with a tick, rather than greying out a button that still looks pressable."
147
160
  }
148
- ],
149
- "todo": true
161
+ ]
150
162
  }
@@ -84,10 +84,22 @@
84
84
  "language": "tsx"
85
85
  }
86
86
  ],
87
- "status": "todo-docs",
87
+ "status": "stable",
88
88
  "url": "/docs/components/agent-handoff",
89
89
  "mdUrl": "/docs/components/agent-handoff.md",
90
90
  "jsonUrl": "/r/components/agent-handoff.json",
91
+ "whenToUse": [
92
+ "The moment one agent gives the baton to another in a transcript that would otherwise jump.",
93
+ "Showing which pieces of context travelled across with it."
94
+ ],
95
+ "whenNotToUse": [
96
+ "A handoff you cannot explain. `reason` is required because without it a handoff reads as an unexplained jump.",
97
+ "A step inside a single agent's own work — this element is about the boundary between two of them."
98
+ ],
99
+ "commonMistakes": [
100
+ "Omitting `carried` to hide the context section. Pass an empty array instead; it is a required prop.",
101
+ "Leaving `settled` false once the receiving agent is underway, so the arrow and the receiving badge keep signalling a transition that already finished."
102
+ ],
91
103
  "specimens": [
92
104
  {
93
105
  "title": "AgentHandoff",
@@ -99,6 +111,5 @@
99
111
  "note": "The baton moving, with the reason attached. Two badges and an arrow: while the handoff is live the receiving agent and the arrow take the streaming hue, and `settled` cools both once the new agent is actually underway. What travelled across is listed under it against a rule — a handoff with no carried context is a handoff you cannot audit.",
100
112
  "interaction": "none. It is a record of something that happened, not a control; the only thing that moves is the colour, over half a second."
101
113
  }
102
- ],
103
- "todo": true
114
+ ]
104
115
  }
@@ -82,10 +82,20 @@
82
82
  "language": "tsx"
83
83
  }
84
84
  ],
85
- "status": "todo-docs",
85
+ "status": "stable",
86
86
  "url": "/docs/components/agent-mode-badge",
87
87
  "mdUrl": "/docs/components/agent-mode-badge.md",
88
88
  "jsonUrl": "/r/components/agent-mode-badge.json",
89
+ "whenToUse": [
90
+ "Anywhere a person needs the run's authority from the corner of their eye — the fact every catalogue leaves to prose.",
91
+ "As the source for mode-aware styling elsewhere: put the same `data-agent-mode` on a composer and its focus ring, send button and rail tint from one place."
92
+ ],
93
+ "whenNotToUse": [
94
+ "A status. Use `AgentStatus` — authority and activity are different questions."
95
+ ],
96
+ "commonMistakes": [
97
+ "Threading a mode prop through components instead of reusing the attribute. `elements.css` declares four custom properties under `data-agent-mode`, so a console adds a mode-aware surface by reading a property rather than by branching."
98
+ ],
89
99
  "specimens": [
90
100
  {
91
101
  "title": "AgentModeBadge",
@@ -97,6 +107,5 @@
97
107
  "note": "How much authority the run is holding, which is the fact a person most needs from the corner of their eye and the one every catalogue leaves to prose. The ladder is four rungs — will it ask me, is it writing, is it only planning, are the guardrails off — because that is how many accents every product in the study paints, whatever it calls its six or seven or nine modes. The chip is the readout; `data-agent-mode` is the part that travels.",
98
108
  "interaction": "press the chip to cycle the rung. The second specimen is the whole point: one attribute on the box, and the rail, the border and the send button all re-derive from `var(--cue-elements-mode-icon)` with no prop threading and no branch in any component. Colour is never alone — each rung has its own glyph and its own word, so the ladder survives a monochrome screenshot."
99
109
  }
100
- ],
101
- "todo": true
110
+ ]
102
111
  }
@@ -127,10 +127,21 @@
127
127
  "language": "tsx"
128
128
  }
129
129
  ],
130
- "status": "todo-docs",
130
+ "status": "stable",
131
131
  "url": "/docs/components/agent-pile",
132
132
  "mdUrl": "/docs/components/agent-pile.md",
133
133
  "jsonUrl": "/r/components/agent-pile.json",
134
+ "whenToUse": [
135
+ "A multi-agent run where who is involved matters more than what each is doing right now.",
136
+ "Anywhere the states must be legible without colour — crown, spinning arc and `?` badge each also go into the accessible name."
137
+ ],
138
+ "whenNotToUse": [
139
+ "One agent. An `Avatar` says it with less.",
140
+ "A list the reader must act on. A pile is a summary."
141
+ ],
142
+ "commonMistakes": [
143
+ "Adding a colour-only state of your own, which breaks the rule the three built-in states follow."
144
+ ],
134
145
  "specimens": [
135
146
  {
136
147
  "title": "AgentPile",
@@ -142,6 +153,5 @@
142
153
  "note": "Faces at −12px overlap, fanning to +4px on hover. The crown marks the orchestrator, an arc marks work in flight and a `?` marks an agent waiting on an answer.",
143
154
  "interaction": "every face is a button with the agent's name; the pile is one tab stop and arrow keys move inside it."
144
155
  }
145
- ],
146
- "todo": true
156
+ ]
147
157
  }
@@ -54,10 +54,21 @@
54
54
  "language": "tsx"
55
55
  }
56
56
  ],
57
- "status": "todo-docs",
57
+ "status": "stable",
58
58
  "url": "/docs/components/agent-plan",
59
59
  "mdUrl": "/docs/components/agent-plan.md",
60
60
  "jsonUrl": "/r/components/agent-plan.json",
61
+ "whenToUse": [
62
+ "An ordered set of steps the agent walks front to back, with one of them currently running."
63
+ ],
64
+ "whenNotToUse": [
65
+ "Work that fans out and rejoins. `steps` is a flat array worked through in order.",
66
+ "A checklist a person ticks. Progress is driven entirely by `activeIndex`, not by input."
67
+ ],
68
+ "commonMistakes": [
69
+ "Clamping `activeIndex` before passing it. Values past the end already mark every step done, and values before the start mark none.",
70
+ "Passing rich nodes as steps. `steps` is `readonly string[]`."
71
+ ],
61
72
  "specimens": [
62
73
  {
63
74
  "title": "AgentPlan",
@@ -69,6 +80,5 @@
69
80
  "note": "The checklist the agent published before it started, with one index driving the whole thing: steps before it are done, the step at it is running, steps after it are waiting. An index past the end marks every step done.",
70
81
  "interaction": "none. A plan is a readout; the agent moves it, not the reader."
71
82
  }
72
- ],
73
- "todo": true
83
+ ]
74
84
  }
@@ -67,10 +67,22 @@
67
67
  "language": "tsx"
68
68
  }
69
69
  ],
70
- "status": "todo-docs",
70
+ "status": "stable",
71
71
  "url": "/docs/components/agent-status",
72
72
  "mdUrl": "/docs/components/agent-status.md",
73
73
  "jsonUrl": "/r/components/agent-status.json",
74
+ "whenToUse": [
75
+ "A standing status pill beside a run: working, waiting, or done with a check.",
76
+ "Showing how long it has been going, which renders in mono when `elapsed` is provided."
77
+ ],
78
+ "whenNotToUse": [
79
+ "A failure. The three states are working, waiting and done — there is no error mode.",
80
+ "A multi-line explanation. `label` is a short status line."
81
+ ],
82
+ "commonMistakes": [
83
+ "Formatting the clock into `label`. `elapsed` is its own prop and gets the mono treatment.",
84
+ "Leaving `state=\"working\"` on a finished run, which keeps the pill signalling activity after there is nothing left to do."
85
+ ],
74
86
  "specimens": [
75
87
  {
76
88
  "title": "AgentStatus",
@@ -82,6 +94,5 @@
82
94
  "note": "One pill that always answers the two questions a run raises: what is it doing, and for how long. Working shimmers, waiting is still and marked, done carries a check and the elapsed total.",
83
95
  "interaction": "the trailing control is a labelled icon button that pauses a run and offers to run it again once it is done."
84
96
  }
85
- ],
86
- "todo": true
97
+ ]
87
98
  }
@@ -73,10 +73,20 @@
73
73
  "language": "tsx"
74
74
  }
75
75
  ],
76
- "status": "todo-docs",
76
+ "status": "stable",
77
77
  "url": "/docs/components/agent-surface",
78
78
  "mdUrl": "/docs/components/agent-surface.md",
79
79
  "jsonUrl": "/r/components/agent-surface.json",
80
+ "whenToUse": [
81
+ "A region of the elements family that must repaint wholesale — a different skin or fidelity — with no prop threading and no branch in any component."
82
+ ],
83
+ "whenNotToUse": [
84
+ "One component's appearance. Use that component's own props.",
85
+ "Density. Use `Density`."
86
+ ],
87
+ "commonMistakes": [
88
+ "Reading the React context to style something. The attributes do the work — `elements.css` re-declares the `--cue-*` tokens under them and custom properties inherit. The context exists for the one place that cannot see the DOM: an overlay portalled to `<body>` from inside the island."
89
+ ],
80
90
  "specimens": [
81
91
  {
82
92
  "title": "AgentSurface",
@@ -88,6 +98,5 @@
88
98
  "note": "One DOM, three paint jobs. The same three tool calls sit in all three specimens; the only difference is the pair of attributes on the box around them. skin='aui' re-points the colour set to assistant-ui's own inks and grounds, and fidelity='upstream' re-points the metrics too, which is what stops cue's density ladder at the island edge. Without @cueplusplus/ui/elements.css imported, all three would look alike.",
89
99
  "interaction": "none of its own. The island is a values-set, not a control: everything inside keeps the behaviour it has outside."
90
100
  }
91
- ],
92
- "todo": true
101
+ ]
93
102
  }
@@ -185,7 +185,8 @@
185
185
  "--cue-surface-2",
186
186
  "--cue-text-emphasis",
187
187
  "--cue-text-label",
188
- "--cue-text-ui"
188
+ "--cue-text-ui",
189
+ "--cue-tracking-caps"
189
190
  ],
190
191
  "summary": "A modal that asks one question with two answers, for anything irreversible.",
191
192
  "examples": [
@@ -195,10 +196,22 @@
195
196
  "language": "tsx"
196
197
  }
197
198
  ],
198
- "status": "todo-docs",
199
+ "status": "stable",
199
200
  "url": "/docs/components/alert-dialog",
200
201
  "mdUrl": "/docs/components/alert-dialog.md",
201
202
  "jsonUrl": "/r/components/alert-dialog.json",
203
+ "whenToUse": [
204
+ "A rare, expensive, irreversible action — dropping a database, discarding unsaved work.",
205
+ "Anywhere an accidental outside click must not dismiss the question."
206
+ ],
207
+ "whenNotToUse": [
208
+ "A routine destructive action. Use `TwoStepButton`: a dialog in front of something people do twenty times an hour only teaches them to dismiss dialogs.",
209
+ "Anything with more than two answers. Use `Dialog`."
210
+ ],
211
+ "commonMistakes": [
212
+ "Reaching for `Dialog` instead. The difference is not cosmetic — this takes `role=\"alertdialog\"` and refuses outside-press dismissal, which is the whole point.",
213
+ "Labelling the buttons 'OK' and 'Cancel'. Name the action: 'Delete patch' says what OK does."
214
+ ],
202
215
  "specimens": [
203
216
  {
204
217
  "title": "AlertDialog",
@@ -210,6 +223,5 @@
210
223
  "note": "The destructive twin: no scrim dismissal, no close button, and an explicit pair of Cancel and Action.",
211
224
  "interaction": "Escape is deliberately not enough on its own; the action has to be chosen."
212
225
  }
213
- ],
214
- "todo": true
226
+ ]
215
227
  }