@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
@@ -112,10 +112,22 @@
112
112
  "language": "tsx"
113
113
  }
114
114
  ],
115
- "status": "todo-docs",
115
+ "status": "stable",
116
116
  "url": "/docs/components/grid",
117
117
  "mdUrl": "/docs/components/grid.md",
118
118
  "jsonUrl": "/r/components/grid.json",
119
+ "whenToUse": [
120
+ "A card grid, a tile wall, any set of peers laid out in both directions.",
121
+ "Responsive column counts without media queries: give `minItemWidth` and let it fit as many as it can."
122
+ ],
123
+ "whenNotToUse": [
124
+ "A single row or column. Use `Stack`.",
125
+ "A table. Use the data-table instruments, which carry the semantics a grid of divs cannot."
126
+ ],
127
+ "commonMistakes": [
128
+ "Setting `cols` and `minItemWidth` together and expecting both to apply.",
129
+ "Hand-picking the gap. It is a rung of the density ladder for the same reason `Stack`'s is — a card grid should tighten with the rest of the console."
130
+ ],
119
131
  "specimens": [
120
132
  {
121
133
  "title": "Grid",
@@ -127,6 +139,5 @@
127
139
  "note": "Fixed columns, or auto-fit from a minimum item width.",
128
140
  "interaction": "none."
129
141
  }
130
- ],
131
- "todo": true
142
+ ]
132
143
  }
@@ -102,10 +102,21 @@
102
102
  "language": "tsx"
103
103
  }
104
104
  ],
105
- "status": "todo-docs",
105
+ "status": "stable",
106
106
  "url": "/docs/components/group-bar",
107
107
  "mdUrl": "/docs/components/group-bar.md",
108
108
  "jsonUrl": "/r/components/group-bar.json",
109
+ "whenToUse": [
110
+ "A breakdown where the proportions are the reading and exact numbers are not.",
111
+ "Anywhere a stacked bar should carry no axis — the shape is the answer."
112
+ ],
113
+ "whenNotToUse": [
114
+ "Values that must be compared precisely. Use a table or a labelled chart.",
115
+ "A single value against a maximum. Use `Progress`."
116
+ ],
117
+ "commonMistakes": [
118
+ "Rendering zero-valued groups. Empty groups get no cell: a minimum width is what makes a two-pixel sliver visible, and a minimum width on a zero draws a group that is not there."
119
+ ],
109
120
  "specimens": [
110
121
  {
111
122
  "title": "GroupBar",
@@ -117,6 +128,5 @@
117
128
  "note": "The distribution strip: one flex cell per item, coloured by tone, with a legend that names each share.",
118
129
  "interaction": "none. It is a picture of a breakdown, and the legend is the text version of it."
119
130
  }
120
- ],
121
- "todo": true
131
+ ]
122
132
  }
@@ -89,10 +89,21 @@
89
89
  "language": "tsx"
90
90
  }
91
91
  ],
92
- "status": "todo-docs",
92
+ "status": "stable",
93
93
  "url": "/docs/components/guardrail-notice",
94
94
  "mdUrl": "/docs/components/guardrail-notice.md",
95
95
  "jsonUrl": "/r/components/guardrail-notice.json",
96
+ "whenToUse": [
97
+ "A refusal that should say where the line actually sits and offer the nearest things it can do."
98
+ ],
99
+ "whenNotToUse": [
100
+ "A failure the system could simply try again.",
101
+ "A refusal with no rule behind it. `policy` is a required short label for the rule that applied."
102
+ ],
103
+ "commonMistakes": [
104
+ "Writing an apology into `title`. It is the refusal in one line, stated plainly rather than apologetically.",
105
+ "Omitting `alternatives` to hide the section. Pass an empty array; it is a required prop."
106
+ ],
96
107
  "specimens": [
97
108
  {
98
109
  "title": "GuardrailNotice",
@@ -104,6 +115,5 @@
104
115
  "note": "A refusal in its own shape: what it will not do, why, the rule that applied, and the nearest things it *can* do. The alternatives are the whole point — a refusal that ends at 'no' hands the work back with nothing attached, and this one hands back three next moves.",
105
116
  "interaction": "each alternative is a button reporting its own text to `onPick`. With an empty list the section disappears rather than leaving an empty rule."
106
117
  }
107
- ],
108
- "todo": true
118
+ ]
109
119
  }
@@ -159,9 +159,10 @@
159
159
  "--cue-surface-2",
160
160
  "--cue-text-emphasis",
161
161
  "--cue-text-label",
162
- "--cue-text-ui"
162
+ "--cue-text-ui",
163
+ "--cue-tracking-caps"
163
164
  ],
164
- "summary": "A richer preview than a tooltip, revealed by hovering a link or a name: the fixture behind a profile string, the operator behind an initial.",
165
+ "summary": "A richer preview than a tooltip, revealed by hovering a link or a name.",
165
166
  "examples": [
166
167
  {
167
168
  "title": "Usage",
@@ -169,10 +170,21 @@
169
170
  "language": "tsx"
170
171
  }
171
172
  ],
172
- "status": "todo-docs",
173
+ "status": "stable",
173
174
  "url": "/docs/components/hover-card",
174
175
  "mdUrl": "/docs/components/hover-card.md",
175
176
  "jsonUrl": "/r/components/hover-card.json",
177
+ "whenToUse": [
178
+ "A preview the pointer can travel into — the fixture behind a profile string, the operator behind an initial.",
179
+ "Content with its own links or controls."
180
+ ],
181
+ "whenNotToUse": [
182
+ "A short description of a control. Use `Tooltip`, which is announced as the trigger's description.",
183
+ "Anything that must be reachable by keyboard alone. Hover is the trigger."
184
+ ],
185
+ "commonMistakes": [
186
+ "Using it as a big tooltip. It is deliberately not one: the card is reachable and its content is not announced as the trigger's description."
187
+ ],
176
188
  "specimens": [
177
189
  {
178
190
  "title": "HoverCard",
@@ -184,6 +196,5 @@
184
196
  "note": "A preview card: richer than a tooltip, and never the only way to reach the information.",
185
197
  "interaction": "opens on hover after a delay and on focus; the card itself is hoverable, so a link inside it is reachable."
186
198
  }
187
- ],
188
- "todo": true
199
+ ]
189
200
  }
@@ -86,10 +86,23 @@
86
86
  "language": "tsx"
87
87
  }
88
88
  ],
89
- "status": "todo-docs",
89
+ "status": "stable",
90
90
  "url": "/docs/components/icon-button",
91
91
  "mdUrl": "/docs/components/icon-button.md",
92
92
  "jsonUrl": "/r/components/icon-button.json",
93
+ "whenToUse": [
94
+ "A control whose meaning is carried by a familiar glyph in a place with no room for a label: a close, a copy, a kebab menu.",
95
+ "A dense toolbar where visible rims would be noise. The default `ghost` variant stays invisible until hovered."
96
+ ],
97
+ "whenNotToUse": [
98
+ "An action whose icon is not unambiguous on its own. Use `Button` with `icon` and real text.",
99
+ "A destructive action that deserves confirmation in place. Use `TwoStepButton`."
100
+ ],
101
+ "commonMistakes": [
102
+ "Treating `aria-label` as optional because the icon 'obviously' means close. It is required, and it is the only name the control has.",
103
+ "Putting a title or tooltip on the icon instead of labelling the button. The tooltip is a hint; the label is the accessible name.",
104
+ "Wrapping the icon in extra sizing markup. Pass the component to `icon` and it is rendered `aria-hidden` at the right rung."
105
+ ],
93
106
  "specimens": [
94
107
  {
95
108
  "title": "IconButton",
@@ -101,6 +114,5 @@
101
114
  "note": "A square button with a required accessible name. There is no unlabelled variant.",
102
115
  "interaction": "same ring as Button; the hit target stays at the control height even when the glyph shrinks."
103
116
  }
104
- ],
105
- "todo": true
117
+ ]
106
118
  }
@@ -53,10 +53,21 @@
53
53
  "language": "tsx"
54
54
  }
55
55
  ],
56
- "status": "todo-docs",
56
+ "status": "stable",
57
57
  "url": "/docs/components/image-generation",
58
58
  "mdUrl": "/docs/components/image-generation.md",
59
59
  "jsonUrl": "/r/components/image-generation.json",
60
+ "whenToUse": [
61
+ "An image being generated, where the frame should hold its size before there is anything in it.",
62
+ "A result that should stay tied to its prompt, which is printed under the frame."
63
+ ],
64
+ "whenNotToUse": [
65
+ "An image that already exists and has no generating phase."
66
+ ],
67
+ "commonMistakes": [
68
+ "Leaving `generating` true after the image lands, which keeps a pulsing dot grid over a finished picture.",
69
+ "Dropping the prompt. It is shown under the frame, and it is what ties the result back to what was asked."
70
+ ],
60
71
  "specimens": [
61
72
  {
62
73
  "title": "ImageGeneration",
@@ -68,6 +79,5 @@
68
79
  "note": "A dot grid holds the square while the image resolves out of a blur — the frame is the right size from the first frame, so nothing below it moves when the picture lands. While generating, the prompt is replaced by a shimmering label; when it settles, the prompt is what is left under the image.",
69
80
  "interaction": "regenerate is a labelled icon button. The grid and the image are both `aria-hidden`: the prompt underneath is the description, and a decorative placeholder should not be announced as a picture."
70
81
  }
71
- ],
72
- "todo": true
82
+ ]
73
83
  }
@@ -104,7 +104,7 @@
104
104
  "--cue-font-mono",
105
105
  "--cue-text-micro"
106
106
  ],
107
- "summary": "The 13px circular \"i\" badge: a footnote marker for a field, a column or a number whose definition is not obvious.",
107
+ "summary": "The 13px circular 'i' badge: a footnote marker for a field, a column or a number.",
108
108
  "examples": [
109
109
  {
110
110
  "title": "Usage",
@@ -112,10 +112,22 @@
112
112
  "language": "tsx"
113
113
  }
114
114
  ],
115
- "status": "todo-docs",
115
+ "status": "stable",
116
116
  "url": "/docs/components/info-tip",
117
117
  "mdUrl": "/docs/components/info-tip.md",
118
118
  "jsonUrl": "/r/components/info-tip.json",
119
+ "whenToUse": [
120
+ "A definition that is not obvious and does not deserve permanent space.",
121
+ "Anywhere the explanation must be reachable from the keyboard — it is a real `<button>`."
122
+ ],
123
+ "whenNotToUse": [
124
+ "Text the reader needs. Use `FieldDescription`; a footnote most people never open is the wrong home for a requirement.",
125
+ "A control's name. Use a label."
126
+ ],
127
+ "commonMistakes": [
128
+ "Rebuilding it as a `<span>` with a hover handler, which puts the explanation out of keyboard reach.",
129
+ "Filling it with a paragraph. It is a footnote marker, not a panel."
130
+ ],
119
131
  "specimens": [
120
132
  {
121
133
  "title": "Tooltip / InfoTip",
@@ -128,6 +140,5 @@
128
140
  "note": "A tooltip names a control; an InfoTip is the 13px `i` badge that explains one.",
129
141
  "interaction": "tooltips open on hover and on keyboard focus, and never on touch; the InfoTip badge is a real button."
130
142
  }
131
- ],
132
- "todo": true
143
+ ]
133
144
  }
@@ -70,10 +70,21 @@
70
70
  "language": "tsx"
71
71
  }
72
72
  ],
73
- "status": "todo-docs",
73
+ "status": "stable",
74
74
  "url": "/docs/components/inline-citation",
75
75
  "mdUrl": "/docs/components/inline-citation.md",
76
76
  "jsonUrl": "/r/components/inline-citation.json",
77
+ "whenToUse": [
78
+ "Numbered markers set in a sentence, each previewing the source behind it.",
79
+ "A preview that carries the source's domain, title and snippet without leaving the sentence."
80
+ ],
81
+ "whenNotToUse": [
82
+ "A standalone source card outside a sentence. These markers live inline."
83
+ ],
84
+ "commonMistakes": [
85
+ "Using `-1` for closed. `openIndex` is `number | null`, and `null` is the closed value.",
86
+ "Leaving `onOpenIndexChange` off. It is required, because which preview is open is state you hold rather than state the element keeps."
87
+ ],
77
88
  "specimens": [
78
89
  {
79
90
  "title": "InlineCitation",
@@ -85,6 +96,5 @@
85
96
  "note": "The marker inside the sentence, rather than the list under it: a numbered chip the paragraph flows around, and behind each one the page it stands on. `Sources` is the bibliography; this is the footnote, and the two are meant to be read together — the chip says a claim is attributable without spending a clause saying so.",
86
97
  "interaction": "each marker is a button, so the preview is reachable from a keyboard as well as a pointer; the open one inverts to the accent fill. The card is the family's one portal, and it carries the island stamp — opened inside an `AgentSurface`, it paints in that island's values rather than the document's."
87
98
  }
88
- ],
89
- "todo": true
99
+ ]
90
100
  }
@@ -84,7 +84,7 @@
84
84
  "--cue-text-label",
85
85
  "--cue-text-ui"
86
86
  ],
87
- "summary": "A control and its adornments, drawn as a single field.",
87
+ "summary": "A control and its adornments, drawn as a single field — one rim, one fill, however many affordances.",
88
88
  "examples": [
89
89
  {
90
90
  "title": "Usage",
@@ -92,10 +92,22 @@
92
92
  "language": "tsx"
93
93
  }
94
94
  ],
95
- "status": "todo-docs",
95
+ "status": "stable",
96
96
  "url": "/docs/components/input-group",
97
97
  "mdUrl": "/docs/components/input-group.md",
98
98
  "jsonUrl": "/r/components/input-group.json",
99
+ "whenToUse": [
100
+ "A prefix or suffix that belongs to the field: a unit, a currency, a copy button, a scheme.",
101
+ "Anywhere two controls must read as one: the group owns the chassis and publishes that through context."
102
+ ],
103
+ "whenNotToUse": [
104
+ "Two independent fields. Give them their own rims; a shared one says they are one value.",
105
+ "A label. Use `FieldLabel`; `leading` is part of the control, not its name."
106
+ ],
107
+ "commonMistakes": [
108
+ "Styling the `Input` inside. It strips its own border, background, height and padding by design and inherits the group's font size — restyling it puts the rim back and breaks the single-field illusion.",
109
+ "Assuming focus styling comes free. A `<div>` matches neither `:focus` nor `:focus-visible`, which is why the group handles it; do not reimplement it with `:focus-within`."
110
+ ],
99
111
  "specimens": [
100
112
  {
101
113
  "title": "InputGroup",
@@ -107,6 +119,5 @@
107
119
  "note": "One rim around a control and its adornments, so the group focuses as a unit.",
108
120
  "interaction": "any focus inside strengthens the whole rim; the ring waits for a keyboard-visible descendant, so a click on an adornment does not light the cluster up. The inner control never rings — the group owns the rim."
109
121
  }
110
- ],
111
- "todo": true
122
+ ]
112
123
  }
@@ -135,7 +135,7 @@
135
135
  "--cue-text-label",
136
136
  "--cue-text-ui"
137
137
  ],
138
- "summary": "One thing in a list, with room for a glyph, a name, a line of detail and a control — the shape a settings entry, a search hit and a device row all want.",
138
+ "summary": "One thing in a list, with room for a glyph, a name, a line of detail and a control.",
139
139
  "examples": [
140
140
  {
141
141
  "title": "Usage",
@@ -143,10 +143,22 @@
143
143
  "language": "tsx"
144
144
  }
145
145
  ],
146
- "status": "todo-docs",
146
+ "status": "stable",
147
147
  "url": "/docs/components/item",
148
148
  "mdUrl": "/docs/components/item.md",
149
149
  "jsonUrl": "/r/components/item.json",
150
+ "whenToUse": [
151
+ "A settings entry, a search hit, a device row — a self-contained object that can stand alone, sit in a `Stack` or fill a `Grid` cell.",
152
+ "Anything clickable: it renders a real `<button>` when interactive, so keyboard users get it for free."
153
+ ],
154
+ "whenNotToUse": [
155
+ "A line of a hairline table. Use `Row` — that is a row of a grid, this is an object.",
156
+ "A whole summary surface. Use `Card`."
157
+ ],
158
+ "commonMistakes": [
159
+ "Wrapping a non-interactive `Item` in a `<div onClick>`. Pass `interactive` and let it be a button.",
160
+ "Putting the control inside `children` instead of `actions`, which loses the reserved slot and the alignment with every other row."
161
+ ],
150
162
  "specimens": [
151
163
  {
152
164
  "title": "Item",
@@ -158,6 +170,5 @@
158
170
  "note": "A media, title, description and actions row. Three variants, plus interactive and disabled.",
159
171
  "interaction": "the interactive variant takes a hover ground and a focus ring; it is a button, so Enter and Space activate it."
160
172
  }
161
- ],
162
- "todo": true
173
+ ]
163
174
  }
@@ -96,10 +96,22 @@
96
96
  "language": "tsx"
97
97
  }
98
98
  ],
99
- "status": "todo-docs",
99
+ "status": "stable",
100
100
  "url": "/docs/components/job-progress",
101
101
  "mdUrl": "/docs/components/job-progress.md",
102
102
  "jsonUrl": "/r/components/job-progress.json",
103
+ "whenToUse": [
104
+ "Long work with named stages, where a long install should not read the same as a fast clone.",
105
+ "Anything a person may need to abandon — `onCancel` is the way out, and it hides once the job finishes."
106
+ ],
107
+ "whenNotToUse": [
108
+ "A wait short enough that stages and an estimate are noise."
109
+ ],
110
+ "commonMistakes": [
111
+ "Giving every stage the same weight, which is exactly what the relative weights exist to avoid.",
112
+ "Special-casing the finished state. Passing `stages.length` as `stageIndex` marks the job finished, and the bar never runs past its track.",
113
+ "Passing a duration object to `eta`. It is a pre-formatted estimate, replaced by done once finished."
114
+ ],
103
115
  "specimens": [
104
116
  {
105
117
  "title": "JobProgress",
@@ -111,6 +123,5 @@
111
123
  "note": "Work measured in minutes rather than steps. The stages are weighted, so a six-minute render does not read the same length as a one-second export, and the bar is filled from those weights plus the fraction of the current stage — which is why it never jumps backwards when a short stage ends.",
112
124
  "interaction": "cancel is a labelled icon button and disappears once the job finishes: there is nothing left to stop, and a dead X beside a green tick reads as an error."
113
125
  }
114
- ],
115
- "todo": true
126
+ ]
116
127
  }
@@ -32,10 +32,22 @@
32
32
  "language": "tsx"
33
33
  }
34
34
  ],
35
- "status": "todo-docs",
35
+ "status": "stable",
36
36
  "url": "/docs/components/kbd",
37
37
  "mdUrl": "/docs/components/kbd.md",
38
38
  "jsonUrl": "/r/components/kbd.json",
39
+ "whenToUse": [
40
+ "Naming a shortcut in prose, a menu row or an empty state — reference material the reader's eye can skip.",
41
+ "Anywhere a `Chip` sits on the same row. It is sized off the chip height so the two line up."
42
+ ],
43
+ "whenNotToUse": [
44
+ "A button. This is static markup that renders on the server and has no press behaviour.",
45
+ "A code fragment or a token name. Use inline code; a key cap says 'press this'."
46
+ ],
47
+ "commonMistakes": [
48
+ "Building a chord out of one `Kbd` containing `⌘ + K`. Emit one per key and put the separator between them, so each cap reads as a key.",
49
+ "Reaching for it as a small badge. It is set in the micro type step on purpose; `Chip` is the badge."
50
+ ],
39
51
  "specimens": [
40
52
  {
41
53
  "title": "Kbd",
@@ -47,6 +59,5 @@
47
59
  "note": "A key cap, in the mono face. Static markup, so it renders on the server.",
48
60
  "interaction": "none."
49
61
  }
50
- ],
51
- "todo": true
62
+ ]
52
63
  }
@@ -110,10 +110,22 @@
110
110
  "language": "tsx"
111
111
  }
112
112
  ],
113
- "status": "todo-docs",
113
+ "status": "stable",
114
114
  "url": "/docs/components/launcher-bubble",
115
115
  "mdUrl": "/docs/components/launcher-bubble.md",
116
116
  "jsonUrl": "/r/components/launcher-bubble.json",
117
+ "whenToUse": [
118
+ "An assistant that lives in the corner of a product rather than owning the page: a bubble that opens into a greeting and a few ways in.",
119
+ "A first run with nothing typed yet — `prompts` exists so the first message does not have to be invented."
120
+ ],
121
+ "whenNotToUse": [
122
+ "A launcher with no starters to offer. `prompts` is required, and an empty panel is the case the component is shaped against.",
123
+ "A panel whose open state lives inside it. `open` is required and the bubble only reports the press through `onToggle`."
124
+ ],
125
+ "commonMistakes": [
126
+ "Driving `unread` to zero and expecting a `0` badge. It is hidden at zero, and hidden again the whole time the panel is open.",
127
+ "Wiring the panel's Start a conversation action to `onPick`. That callback fires only for a starter prompt; the empty thread is `onStart`."
128
+ ],
117
129
  "specimens": [
118
130
  {
119
131
  "title": "LauncherBubble",
@@ -125,6 +137,5 @@
125
137
  "note": "The floating entry point and the panel it opens into — the shape an assistant takes on somebody else's site. The badge counts unread and disappears the moment the panel is open, because a count of things you are currently looking at is noise. The starter prompts exist so the first message does not have to be invented by a visitor who has no idea what this thing knows.",
126
138
  "interaction": "the bubble carries `aria-expanded` and its label changes with it (`Open the assistant` / `Close the assistant`); the two icons cross-fade in one grid cell so nothing reflows."
127
139
  }
128
- ],
129
- "todo": true
140
+ ]
130
141
  }
@@ -259,7 +259,8 @@
259
259
  "--cue-space-2",
260
260
  "--cue-space-3",
261
261
  "--cue-text-label",
262
- "--cue-text-ui"
262
+ "--cue-text-ui",
263
+ "--cue-tracking-caps"
263
264
  ],
264
265
  "summary": "Grouped dense rows under sticky tier headings and gutter slugs, with an opt-in disclosure that folds a heading without leaving the outline.",
265
266
  "examples": [
@@ -74,10 +74,21 @@
74
74
  "language": "tsx"
75
75
  }
76
76
  ],
77
- "status": "todo-docs",
77
+ "status": "stable",
78
78
  "url": "/docs/components/link",
79
79
  "mdUrl": "/docs/components/link.md",
80
80
  "jsonUrl": "/r/components/link.json",
81
+ "whenToUse": [
82
+ "Navigation — somewhere the user can middle-click, copy the address of, or open in a new tab.",
83
+ "An outbound destination: `external` marks it as leaving."
84
+ ],
85
+ "whenNotToUse": [
86
+ "An action that happens on this page. Use `Button`, or `Button` with `render={<NextLink/>}` when it must look like one but navigate."
87
+ ],
88
+ "commonMistakes": [
89
+ "Using a `Button` with an `onClick` that navigates, which takes away middle-click and copy-address.",
90
+ "Marking an in-app route `external`, which promises a new context the click does not deliver."
91
+ ],
81
92
  "specimens": [
82
93
  {
83
94
  "title": "Link",
@@ -89,6 +100,5 @@
89
100
  "note": "Two variants. Links do not underline by default; the underline variant offsets by 4px so descenders survive.",
90
101
  "interaction": "hover moves the ink to the accent."
91
102
  }
92
- ],
93
- "todo": true
103
+ ]
94
104
  }
@@ -67,7 +67,7 @@
67
67
  "variants": {},
68
68
  "defaultVariants": {},
69
69
  "tokensUsed": [],
70
- "summary": "One polite region, and a queue that makes it audible.",
70
+ "summary": "One polite region with a queue behind it, so a run's state changes are actually spoken.",
71
71
  "examples": [
72
72
  {
73
73
  "title": "Usage",
@@ -75,10 +75,23 @@
75
75
  "language": "tsx"
76
76
  }
77
77
  ],
78
- "status": "todo-docs",
78
+ "status": "stable",
79
79
  "url": "/docs/components/live-region-announcer",
80
80
  "mdUrl": "/docs/components/live-region-announcer.md",
81
81
  "jsonUrl": "/r/components/live-region-announcer.json",
82
+ "whenToUse": [
83
+ "Any agent console that has to be usable without a screen: it spaces announcements so each is spoken instead of overwritten.",
84
+ "One per surface, mounted for the life of the transcript — the region is mounted empty and stays mounted, which is the only way a live region is reliably announced."
85
+ ],
86
+ "whenNotToUse": [
87
+ "Alongside a second speaker. Mounting this takes the speech away from `TailStatus` automatically; two live regions read every state out twice, out of step.",
88
+ "Deciding what to say. The words are the caller's — `ANNOUNCEMENTS` carries the nine transitions the study found announced, and this only queues and speaks them."
89
+ ],
90
+ "commonMistakes": [
91
+ "Trimming `messages` at the head. It is append-only and the announcer remembers how far it has read, so trimmed entries are lost — keep the log growing, or remount with a new `key` for a new run.",
92
+ "Dropping `spacing` towards zero to keep up. A polite announcement that arrives while another is being spoken replaces it; the `400` default is roughly how long a short phrase takes to speak.",
93
+ "Expecting a restored session to be read out. `announceOnMount` is `false` by default, and the pause rules hold over it — a backlog handed to a hidden tab waits rather than spending its first line."
94
+ ],
82
95
  "specimens": [
83
96
  {
84
97
  "title": "LiveRegionAnnouncer",
@@ -90,6 +103,5 @@
90
103
  "note": "The element with no visual design at all, and the one that decides whether the rest of this family can be used without a screen. An agent transcript is a stream of state changes, and a live region wired straight to it announces almost none of them: polite announcements replace each other, so a region updated four times a second speaks once and swallows the rest. So it is a queue — 400ms of spacing, five deep with the oldest dropped, held while the page is hidden or a modal has the reader, and an identical sentence re-announced by appending a space, which changes the string without changing a word of it.",
91
104
  "interaction": "press the button and nothing visible happens, which is the point — the list below is a mirror of what the region said, drawn only so the bench has something to look at. Press it twice quickly and the second announcement waits its 400ms rather than replacing the first; press it faster than five times and the oldest waiting one is dropped, because five deep behind a busy run the newest is the true one. The second specimen is the composition with TailStatus: that row is a role=status too, so mounting this takes the speaking off it — inspect the row and it carries data-announces=false and no role, which is how a console gets one voice instead of two."
92
105
  }
93
- ],
94
- "todo": true
106
+ ]
95
107
  }
@@ -152,10 +152,23 @@
152
152
  "language": "tsx"
153
153
  }
154
154
  ],
155
- "status": "todo-docs",
155
+ "status": "stable",
156
156
  "url": "/docs/components/log-viewer",
157
157
  "mdUrl": "/docs/components/log-viewer.md",
158
158
  "jsonUrl": "/r/components/log-viewer.json",
159
+ "whenToUse": [
160
+ "Streaming output of any length — build logs, run output, a device trace.",
161
+ "Anywhere the reader needs to follow the tail and still be able to scroll back without being yanked forward."
162
+ ],
163
+ "whenNotToUse": [
164
+ "A handful of static lines. A `<pre>` is simpler and costs nothing.",
165
+ "Structured records the reader filters and sorts. Use a data table."
166
+ ],
167
+ "commonMistakes": [
168
+ "Rendering the lines yourself. Five thousand DOM rows is a frozen tab, which is why this is virtualised.",
169
+ "Overriding `rowHeight` to something variable. Rows are fixed at the short control rung so the virtualiser never has to measure, which is also what keeps the scrollbar honest while lines stream in.",
170
+ "Omitting `height`. It is required because a virtualiser cannot work without a viewport."
171
+ ],
159
172
  "specimens": [
160
173
  {
161
174
  "title": "LogViewer",
@@ -167,6 +180,5 @@
167
180
  "note": "Virtualised rows at the small control height, ANSI decoded to text nodes (never innerHTML), level filter chips, and a stick-to-bottom scroller that offers a `N new lines` pill once you scroll away.",
168
181
  "interaction": "the filter chips are toggles; the new-lines pill is a button that returns you to the tail."
169
182
  }
170
- ],
171
- "todo": true
183
+ ]
172
184
  }
@@ -77,10 +77,21 @@
77
77
  "language": "tsx"
78
78
  }
79
79
  ],
80
- "status": "todo-docs",
80
+ "status": "stable",
81
81
  "url": "/docs/components/map-answer",
82
82
  "mdUrl": "/docs/components/map-answer.md",
83
83
  "jsonUrl": "/r/components/map-answer.json",
84
+ "whenToUse": [
85
+ "A model answer that is a set of places, where the plot and the list beside it must stay in step.",
86
+ "An ordered itinerary — `route` draws a dashed path through the pins in the order they were given."
87
+ ],
88
+ "whenNotToUse": [
89
+ "A real map. Pins are positioned as percentages precisely so the element needs no tiles, and it knows nothing about geography."
90
+ ],
91
+ "commonMistakes": [
92
+ "Keeping two selections, one for the plot and one for the list. Both surfaces report the same id through `onSelect`, and `activeId` selects in both.",
93
+ "Expecting `route` to work out an order. It follows the order of `pins`, which is the caller's."
94
+ ],
84
95
  "specimens": [
85
96
  {
86
97
  "title": "MapAnswer",
@@ -92,6 +103,5 @@
92
103
  "note": "A location answer as a plan and a list at once: pins on a ruled ground, the same pins as rows underneath, and one selection driving both. The grid is drawn, not tiled — there is no map provider here, and `x`/`y` are percentages the caller decides.",
93
104
  "interaction": "pin and row are both buttons for the same id, and both carry `aria-current`; the pin's own label is what a screen reader gets, since the plan itself is aria-hidden."
94
105
  }
95
- ],
96
- "todo": true
106
+ ]
97
107
  }