@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
package/CHANGELOG.md CHANGED
@@ -1,5 +1,345 @@
1
1
  # @cueplusplus/ui
2
2
 
3
+ ## 0.15.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 5493c5a: A style set can now say what colour the line between two bands is.
8
+
9
+ `band-rule` was only ever its WIDTH. The colour was the literal string
10
+ `border-border`, spelled twice — once in `SEPARATION_PAINT` and once in
11
+ `Footer`'s own class list — so a set could say how thick the rule is and had no
12
+ way to say what it was made of.
13
+
14
+ `--cue-band-rule-color` joins the style-set contract, which becomes six required
15
+ names. It takes `var(--cue-border)`, `var(--cue-border-subtle)`,
16
+ `var(--cue-border-strong)` or `transparent` — structural inks only, because a
17
+ brand colour on a structural line belongs to a different axis. The `:root`
18
+ default and all three shipped sets declare `var(--cue-border)`, which is
19
+ byte-for-byte what both call sites drew before, so this is a no-op until a set
20
+ spends it.
21
+
22
+ Measured across thirteen reference sites on 2026-09-22: every one that separates
23
+ bands by a line picks a line lighter than its box edge. `--cue-border` is a box
24
+ edge, and repeating a box edge between sections is what `--cue-border-subtle`'s
25
+ own docblock argues against one layer down. Until now no axis could express the
26
+ difference.
27
+
28
+ - c6e26c0: `Density`, `Preview` and portals carry the paint axis
29
+
30
+ `<Density paint>` and `<Preview paint>` stamp `data-paint` on their subtree, and
31
+ a portal opened inside either follows it — the same three-publisher arrangement
32
+ the style axis already has, for the same reason: a portal mounts on `<body>` and
33
+ inherits nothing from the DOM it was written in, so it has to be told.
34
+
35
+ ```tsx
36
+ <Density density="compact" paint="none">
37
+ <Toolbar />
38
+ </Density>
39
+
40
+ <Preview paint="none">
41
+ <Card>…</Card>
42
+ </Preview>
43
+ ```
44
+
45
+ **Absent means inherit, and `none` is a value rather than an absence.** An island
46
+ that names no pack stamps no attribute and passes the ambient pack straight
47
+ through; `none` restates the `:root` defaults, which is what a subtree stamps to
48
+ opt _out_ of a pack its parent set. Collapsing the two would make every unpainted
49
+ subtree override its parent instead of inheriting from it.
50
+
51
+ New: `PaintContext`, and a `paint` prop on `DensityProps` and `PreviewProps`.
52
+ `CuePortalStamp` gains a `paint` field.
53
+
54
+ The provider half — a `paint` prop on `<ThemeProvider>`, persistence, and the
55
+ blocking prepaint script — is not here. This is the island path, which works on
56
+ its own: a subtree can re-scope the axis without a provider, exactly as
57
+ `<Density styleSet>` does.
58
+
59
+ - e7a2405: `ThemeProvider` carries the paint axis, and persists it
60
+
61
+ `<ThemeProvider paint>` stamps `data-paint`, `useTheme()` reports it and
62
+ `setPaint()` switches it, and the blocking pre-paint script puts it on `<html>`
63
+ before the first frame — so a page restored from storage does not flash an
64
+ unpainted frame before React commits.
65
+
66
+ ```tsx
67
+ <ThemeProvider theme="cue" paint="none">
68
+ …
69
+ </ThemeProvider>;
70
+
71
+ const { paint, setPaint } = useTheme();
72
+ ```
73
+
74
+ **An app that never touches the axis writes the object it always wrote, byte for
75
+ byte.** The pack is persisted only when there is one — the rule `styleSet`
76
+ already follows — because a `"paint": null` in storage would be a value the
77
+ pre-paint script has to hold an opinion about for ever, for a preference nobody
78
+ expressed.
79
+
80
+ **The root never promotes an ambient pack.** `useTheme().paint` reports the pack
81
+ in force, but the `data-paint` stamp stays on the provider's own state, so a
82
+ `<Density paint>` island cannot become a document-wide attribute and from there
83
+ reach storage and the next load.
84
+
85
+ New: `paint` on `ThemeProviderProps` and `PrepaintDefaults`, `paint` and
86
+ `setPaint` on the `useTheme()` value, `isPaint()` beside `isStyleSet()`, and
87
+ `paint` on `PersistedPreferences`.
88
+
89
+ The skills learn the axis too: `ui-theming` documents five axes rather than four,
90
+ and the generated token reference carries the eighteen paint names — so an agent
91
+ asked to compose a page can find `--cue-paint-glow-blur` instead of spelling a
92
+ shadow literal by hand.
93
+
94
+ - d5c4183: Letter spacing becomes a token a style set can retune.
95
+
96
+ The system had already decided this and never finished it. `leading-ui` is spent
97
+ 63 times through a token against 2 literals. The only tracking name that existed,
98
+ `tracking-label`, was spent **zero** times — while 34 hard-coded `tracking-[…]`
99
+ literals sat across 27 chassis files at six distinct values.
100
+
101
+ Three names join the style-set contract, at the values those literals already
102
+ held: `tracking-caps` (0.15em, 23 call sites), `tracking-caps-tight` (0.1em, 5)
103
+ and `tracking-caps-loose` (0.2em, 1 — `Eyebrow`, the one place the system spends
104
+ the accent on pure typography, so a set that wants a different kicker has
105
+ nowhere else to say so). Two optional names join beside `style-display`:
106
+ `style-tracking-display` and `style-leading-display`, the latter a second name
107
+ rather than a widened `leading-prose` because a display register routinely sits
108
+ under 1 and a paragraph must not.
109
+
110
+ 32 literals become token spends. Two survive deliberately: `tracking-[inherit]`
111
+ on `Stepper`, which is a pass-through rather than a value, and `tracking-[0.06em]`
112
+ on `Chip`'s tag, one call site at a value no other rung shares.
113
+
114
+ `tracking-label` stays in the frozen base and does **not** move. Its three call
115
+ sites now spend `--cue-tracking-label` instead of a literal, which finally makes
116
+ a declared-and-never-spent token do its job.
117
+
118
+ Measured across thirteen reference sites on 2026-09-22: a display tracking is
119
+ missing in twelve of them — more than any single paint device. Apple's curve is
120
+ non-monotone (-0.022em at 17px, +0.012em at 19px, 0 at 40px, -0.015em at 80px);
121
+ vercel wants -0.02/-0.04/-0.06em; stripe -0.025em. None of it was expressible.
122
+
123
+ Every value is unchanged. The defaults restate the literals they replace.
124
+
125
+ ### Patch Changes
126
+
127
+ - 9c7041a: The dot screen and the app bar's glass spend paint tokens
128
+
129
+ `Preview` and `Frames`' dots ground reads `--cue-paint-screen` and
130
+ `--cue-paint-screen-size` instead of spelling the gradient out.
131
+
132
+ **Nothing renders differently, and that is proved in a browser rather than
133
+ argued.** Each token's `:root` default is the value its literal held, so a page
134
+ that never stamps `data-paint` computes exactly what it computed before.
135
+ `tests/browser/paint-noop.spec.ts` measures it on the built site: the adopted
136
+ utility and the literal it replaced compute the same `background-image` and
137
+ `background-size`, and every value is required to be non-`none` first — because two absences would satisfy an equality, and "the dots
138
+ stopped painting" is the regression that guards against.
139
+
140
+ A pack can now retune the finish without touching a component.
141
+
142
+ **One duplicate collapsed.** `apps/docs`' ground picker carried a hand-copied
143
+ second spelling of the same gradient, with a comment saying it was "the same
144
+ gradient `Preview`'s own `dots` ground paints" — and nothing tied the two
145
+ together. Both spend the token now, so they are the same value rather than the
146
+ same text.
147
+
148
+ **`AppBar` keeps `backdrop-blur`.** Adopting `--cue-paint-glass-filter` there was
149
+ tried and reverted: Tailwind composes every backdrop utility into one
150
+ declaration, so a raw `[backdrop-filter:var(…)]` would stop a consumer's
151
+ `backdrop-brightness-50` from combining with the bar's blur. The glass slice
152
+ owns that decision.
153
+
154
+ - Updated dependencies [a20e98e]
155
+ - Updated dependencies [5493c5a]
156
+ - Updated dependencies [96f6f6b]
157
+ - Updated dependencies [d5c4183]
158
+ - @cueplusplus/tokens@0.15.0
159
+
160
+ ## 0.14.1
161
+
162
+ ### Patch Changes
163
+
164
+ - 9857b93: Every chrome component now ships hand-written guidance in the manifest.
165
+
166
+ Fifteen of the twenty-three had extracted facts and nothing that said when to
167
+ reach for one. `chrome` joins `layout`, `forms` and `primitives` as a complete
168
+ group.
169
+
170
+ The guidance names the rules these components enforce and a hand-rolled
171
+ replacement always loses: `SegmentedControl` cannot be emptied and `ToggleGroup`
172
+ can, which is the whole difference between a view picker and a filter bar;
173
+ `NavigationMenu` must not take `role="menu"`, because that tells a screen reader
174
+ to expect commands and swallows the browser's own link affordances; `Toolbar` is
175
+ one tab stop with arrow keys inside, which is what a flex row of buttons throws
176
+ away; and `Tree` earns its hand-built implementation on three details together —
177
+ roving tabindex, a flat DOM carrying `aria-level`/`aria-posinset`/`aria-setsize`,
178
+ and the keyboard contract.
179
+
180
+ No API changed.
181
+
182
+ - d11bcb7: The six domain groups ship hand-written guidance: date, color, flow, midi, dmx
183
+ and charts.
184
+
185
+ Twenty-eight components gained `whenToUse`, `whenNotToUse` and `commonMistakes`,
186
+ completing every one of the six. Coverage is 164 of 326, and only `elements` and
187
+ `icons` remain.
188
+
189
+ These are the components most often reached for wrongly, because the right
190
+ choice depends on the domain rather than the shape: a `DateField` beats a
191
+ `DatePicker` whenever the user already knows the date, and `TimeField` takes
192
+ `hourCycle={24}` because a control room does not read AM/PM. `MusicalTimeInput`
193
+ exists because a number field asks for 4.25 and means "bar 2, beat 1, one
194
+ sixteenth in". `UniverseGrid` is deliberately not a table: position _is_ the
195
+ address, which is what makes an overlap visible rather than inferred. And three
196
+ of them refuse a prop on purpose — `FlowBackground`'s `color` writes a property
197
+ that outranks the theme map, so passing one opts out of theming rather than
198
+ into it.
199
+
200
+ No API changed.
201
+
202
+ - 2a5b3aa: Every component in the library now ships hand-written guidance.
203
+
204
+ The last 162 — all 152 of `elements` and all 10 of `icons` — gained `whenToUse`,
205
+ `whenNotToUse` and `commonMistakes`. Coverage is **326 of 326**: an agent reading
206
+ `manifest.json` now gets the judgement as well as the API for every component,
207
+ not for the thirty-eight that happened to have prose.
208
+
209
+ The guidance is derived from each component's own record, never invented, and
210
+ where a record had only a one-line summary the file is short rather than padded.
211
+ What that surfaces is the reasoning the source already carried:
212
+
213
+ - `GenerativeUI` takes `spec` as `unknown` on purpose, because a cast is a claim
214
+ about the bytes nobody is in a position to make — and it never throws, so an
215
+ error boundary around it is waiting for something that will not happen.
216
+ - `RevertDock` will not render without `This action cannot be undone.` on screen,
217
+ and picking a scope only arms it, because the old layout put the destructive
218
+ control _inside_ the scope control's box at 448px.
219
+ - `AnimatedNumber` is `tabular-nums` because a proportional `1` is narrower than
220
+ a `0`, so a stepping counter nudges everything to its right on every update.
221
+ - `Message` renders React nodes verbatim and will never parse markdown, which is
222
+ what keeps a consumer from being one prompt away from an injection.
223
+ - The ten icons each say what misreading their shape prevents: an audience drawn
224
+ as a tag files people with the folders, an empty beta ring reads as "nothing
225
+ here yet", and a bare chevron for a CLI tool promises a disclosure that
226
+ navigates instead.
227
+
228
+ No API changed.
229
+
230
+ - 0b5ed2d: Every forms control now ships hand-written guidance in the manifest.
231
+
232
+ Twenty-three of the twenty-nine carried extracted facts — props, variants, types
233
+ — but nothing that said when to reach for one. They now carry `whenToUse`,
234
+ `whenNotToUse` and `commonMistakes` alongside the rest, so `forms` joins
235
+ `primitives` as a complete group.
236
+
237
+ The guidance is mostly about pairs that look alike and are not:
238
+ `Autocomplete` accepts what you typed and `Combobox` does not, which decides what
239
+ downstream code may assume about the value. `ToggleGroup` can be empty and
240
+ `SegmentedControl` cannot, which is the difference between a filter bar and a
241
+ view switcher. `Toggle` announces `aria-pressed` and `Switch` announces
242
+ `aria-checked`, which is why one belongs in a toolbar and the other in a settings
243
+ list. `MultiSelect` takes a known set and `TagsInput` takes anything.
244
+
245
+ No API changed.
246
+
247
+ - 3e928f8: Every instrument now ships hand-written guidance in the manifest.
248
+
249
+ Fourteen of the twenty-one had extracted facts and nothing that said when to
250
+ reach for one. `instruments` joins `chrome`, `layout`, `forms` and `primitives`
251
+ as a complete group.
252
+
253
+ Several of these components exist because a hand-rolled version gets one rule
254
+ wrong, and the guidance names which: `Sparkline` and `UsageChart` fix their axis
255
+ at 0–100, because a trace scaled to its own range makes a flat 3% look identical
256
+ to a flat 95%; `Progress` transitions linearly, because a bar that eases is lying
257
+ about its rate; `GroupBar` gives no cell to an empty group, because a minimum
258
+ width on a zero draws a group that is not there; `LogViewer` fixes its row height
259
+ so the virtualiser never measures; and `TwoStepButton` is the right shape for a
260
+ _routine_ destructive action, where a modal would only teach people to dismiss
261
+ dialogs.
262
+
263
+ No API changed.
264
+
265
+ - f2e5203: Every layout component now ships hand-written guidance in the manifest.
266
+
267
+ Seventeen of the twenty had extracted facts and nothing that said when to reach
268
+ for one. `layout` joins `forms` and `primitives` as a complete group.
269
+
270
+ The guidance is mostly about three disclosure components that look alike and are
271
+ not: `Accordion` coordinates several peer sections, `Collapsible` is one of them
272
+ alone, and `Disclosure` is neither — it is an annotation on the form it sits in,
273
+ which is why giving those fields a summary row makes a form read as twice as long
274
+ as it is. Also why `Stack` exists at all: `flex gap-2` written by hand pins
275
+ spacing to a pixel value and quietly opts out of the density ladder.
276
+
277
+ No API changed.
278
+
279
+ - ba6d72e: `ThemeProvider`'s `nonce` now reaches Base UI's style element too, not just the
280
+ density layer.
281
+
282
+ `@base-ui/react` renders one `<style>` of its own — a hoisted
283
+ `<style precedence>` carrying `.base-ui-disable-scrollbar` — and `ScrollAreaRoot`
284
+ and `SelectPopup` give it a nonce they read from Base UI's `CSPContext`. Nothing
285
+ fills that context unless a `CSPProvider` is rendered above them, so under
286
+ `style-src-elem 'self' 'nonce-<per-request>'` that element shipped bare and the
287
+ browser refused it by content hash, on every page rendering a Select, a Popover
288
+ or a ScrollArea.
289
+
290
+ It was reported to us as a density-layer problem and it never was: the
291
+ application that hit it passes no `overrides`, so the density `<style>` did not
292
+ exist in its tree at all. The nonce prop added for that report was correct and
293
+ addressed a different element. This is the half that was actually biting.
294
+
295
+ Given a nonce, `ThemeProvider` now renders `CSPProvider` around its tree. Given
296
+ none, it renders none — deliberately, so an application that wraps itself in its
297
+ own `CSPProvider` keeps it. An unconditional inner provider would overwrite that
298
+ outer context with `undefined` and un-nonce every Base UI style element in the
299
+ tree, which is the bug this fixes, caused by its fix.
300
+
301
+ No API changed. A tree with no nonce renders exactly what it rendered before.
302
+
303
+ - b12c65d: Four more groups ship hand-written guidance: overlays, system, chat and the
304
+ configurator.
305
+
306
+ Twenty-one components gained `whenToUse`, `whenNotToUse` and `commonMistakes`,
307
+ completing all four groups. Coverage is 136 of 326.
308
+
309
+ Two of these matter beyond the component they describe. `Message` renders React
310
+ nodes verbatim and will never parse markdown or HTML, because model output is
311
+ untrusted text and a component that quietly parsed it would make every consumer
312
+ of this library one prompt away from an injection — a caller that wants rich text
313
+ passes its own renderer and owns that decision. And `AskBox` holds only the
314
+ _draft_ answer: the fact of having answered comes back from the host, because
315
+ local state as the source of truth for a decision a run depends on survives
316
+ exactly until the pane unmounts.
317
+
318
+ The overlay family's distinctions are the rest: `AlertDialog` refuses
319
+ outside-press dismissal and `Dialog` does not; `Sheet` is a side channel and
320
+ `Drawer` is its swipe-dismissable cousin; `HoverCard` is reachable by the pointer
321
+ and a `Tooltip` is not; `ContextMenu` and `Menubar` re-export `DropdownMenu`'s
322
+ own rows, so a user can never tell from a row how they got to it.
323
+
324
+ No API changed.
325
+
326
+ - f1fa7b6: Every primitive now ships hand-written guidance in the manifest.
327
+
328
+ `Avatar`, `AvatarGroup`, `IconButton`, `Kbd`, `Separator`, `Skeleton`, `Spinner`
329
+ and `StatusDot` carried extracted facts — props, variants, types — but nothing
330
+ that said when to reach for one. They now carry `whenToUse`, `whenNotToUse` and
331
+ `commonMistakes` alongside the rest, so the ten components in `primitives` are
332
+ complete. An agent reading `manifest.json` gets the judgement as well as the API:
333
+ that `StatusDot`'s wrapper is the containing block its `sr-only` label needs,
334
+ that `Skeleton` has no intrinsic size and collapses without one, that
335
+ `IconButton`'s `aria-label` is the only name the control has.
336
+
337
+ No API changed. These are fields the manifest schema already had and thirty-eight
338
+ other components already filled.
339
+
340
+ - Updated dependencies [abd9a57]
341
+ - @cueplusplus/tokens@0.14.1
342
+
3
343
  ## 0.14.0
4
344
 
5
345
  ### Minor Changes
@@ -25,7 +25,7 @@ const DANGER_TONES = {
25
25
  */
26
26
  const HEADER = "flex min-w-0 items-center gap-(--cue-space-2) border-0 bg-transparent p-0 text-start font-mono text-(length:--cue-text-ui) text-fg-muted outline-none focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-offset-2 focus-visible:outline-accent";
27
27
  /** The label over a block in the body, in the same eyebrow as a message header. */
28
- const EYEBROW = "font-mono text-(length:--cue-text-micro) tracking-[0.15em] uppercase text-fg-subtle";
28
+ const EYEBROW = "font-mono text-(length:--cue-text-micro) tracking-(--cue-tracking-caps) uppercase text-fg-subtle";
29
29
  /**
30
30
  * An LLM's own tool call, shown while it runs and after.
31
31
  *
@@ -72,7 +72,7 @@ const Message = React.forwardRef(function Message({ className, role = "agent", a
72
72
  children: [
73
73
  hasHeader ? /* @__PURE__ */ jsxs("div", {
74
74
  "data-slot": "message-header",
75
- className: "flex min-w-0 items-baseline justify-between gap-(--cue-space-3) font-mono text-(length:--cue-text-micro) tracking-[0.15em] uppercase",
75
+ className: "flex min-w-0 items-baseline justify-between gap-(--cue-space-3) font-mono text-(length:--cue-text-micro) tracking-(--cue-tracking-caps) uppercase",
76
76
  children: [name === void 0 ? null : /* @__PURE__ */ jsx("span", {
77
77
  "data-slot": "message-author",
78
78
  className: cn("min-w-0 truncate", role === "user" ? "text-accent-fg opacity-70" : "text-(--agent-color)"),
@@ -16,12 +16,18 @@ import { jsx } from "react/jsx-runtime";
16
16
  * the argument.
17
17
  *
18
18
  * `rule`'s entry is the colour and not the width: the width is
19
- * `--cue-band-rule` and belongs to the chassis, and both elements name
20
- * `border-border` in their own class list rather than inheriting it from the
21
- * other.
19
+ * `--cue-band-rule` and belongs to the chassis, and both elements name the ink
20
+ * in their own class list rather than inheriting it from the other.
21
+ *
22
+ * That ink is now a token. It was the literal `border-border`, spelled here and
23
+ * again in `Footer`, which meant a style set could say how THICK the line
24
+ * between two bands is and had no way to say what colour it was — and every
25
+ * site measured in the 2026-09-22 corpus that separates bands by a line picks
26
+ * one lighter than its box edge. `--cue-band-rule-color` defaults to
27
+ * `var(--cue-border)` on `:root`, which is byte-for-byte what this drew before.
22
28
  */
23
29
  const SEPARATION_PAINT = {
24
- rule: "border-border",
30
+ rule: "border-(--cue-band-rule-color)",
25
31
  ground: "bg-(--cue-band-ground)",
26
32
  bleed: null,
27
33
  none: null
@@ -22,7 +22,7 @@ const Eyebrow = React.forwardRef(function Eyebrow({ className, slashes = true, c
22
22
  return /* @__PURE__ */ jsxs("span", {
23
23
  ref,
24
24
  "data-slot": "eyebrow",
25
- className: cn("inline-flex items-center gap-(--cue-space-2) font-mono text-(length:--cue-text-label) tracking-[0.2em] text-accent uppercase", className),
25
+ className: cn("inline-flex items-center gap-(--cue-space-2) font-mono text-(length:--cue-text-label) tracking-(--cue-tracking-caps-loose) text-accent uppercase", className),
26
26
  ...elementProps,
27
27
  children: [slashes ? /* @__PURE__ */ jsx("span", {
28
28
  "data-slot": "eyebrow-glyph",
@@ -66,7 +66,7 @@ const Footer = React.forwardRef(function Footer({ className, columnClassName, wi
66
66
  ref,
67
67
  "data-slot": "footer",
68
68
  "data-separation": "rule",
69
- className: cn(bandClasses("rule"), "border-border", className),
69
+ className: cn(bandClasses("rule"), "border-(--cue-band-rule-color)", className),
70
70
  ...elementProps,
71
71
  children: /* @__PURE__ */ jsxs(Container, {
72
72
  width,
@@ -35,7 +35,7 @@ const SectionHeader = React.forwardRef(function SectionHeader({ className, label
35
35
  }) : null,
36
36
  /* @__PURE__ */ jsx("span", {
37
37
  "data-slot": "section-header-label",
38
- className: "shrink-0 font-mono text-(length:--cue-text-label) tracking-[0.15em] text-fg-muted uppercase",
38
+ className: "shrink-0 font-mono text-(length:--cue-text-label) tracking-(--cue-tracking-caps) text-fg-muted uppercase",
39
39
  children: label
40
40
  }),
41
41
  count === void 0 ? null : /* @__PURE__ */ jsx("span", {
@@ -221,7 +221,7 @@ function ThemeConfigurator({ position: positionProp, defaultPosition = "floating
221
221
  }),
222
222
  /* @__PURE__ */ jsx("span", {
223
223
  id: titleId,
224
- className: "flex-1 truncate font-mono text-(length:--cue-text-label) tracking-[0.15em] text-fg-muted uppercase",
224
+ className: "flex-1 truncate font-mono text-(length:--cue-text-label) tracking-(--cue-tracking-caps) text-fg-muted uppercase",
225
225
  children: title
226
226
  }),
227
227
  moved === 0 ? null : /* @__PURE__ */ jsx(Chip, {
@@ -70,7 +70,7 @@ function ExportDialog({ open, onOpenChange, overrides, scope, defaultFormat = "c
70
70
  /* @__PURE__ */ jsxs(Field, {
71
71
  className: "gap-(--cue-space-1)",
72
72
  children: [/* @__PURE__ */ jsx(FieldLabel, {
73
- className: "font-mono text-(length:--cue-text-micro) tracking-[0.15em] uppercase",
73
+ className: "font-mono text-(length:--cue-text-micro) tracking-(--cue-tracking-caps) uppercase",
74
74
  children: "Theme name"
75
75
  }), /* @__PURE__ */ jsx(Input, {
76
76
  size: "sm",
@@ -133,7 +133,7 @@ function TextTokenField({ label, token, edits, placeholder }) {
133
133
  return /* @__PURE__ */ jsxs(Field, {
134
134
  className: "gap-(--cue-space-1)",
135
135
  children: [/* @__PURE__ */ jsx(FieldLabel, {
136
- className: "font-mono text-(length:--cue-text-micro) tracking-[0.15em] uppercase",
136
+ className: "font-mono text-(length:--cue-text-micro) tracking-(--cue-tracking-caps) uppercase",
137
137
  children: label
138
138
  }), /* @__PURE__ */ jsx(Input, {
139
139
  size: "sm",
@@ -133,7 +133,7 @@ function TokenEditor({ values, overridden, onTokenChange, onTokenReset, groups =
133
133
  "data-slot": "configurator-token-group",
134
134
  className: "flex flex-col gap-(--cue-space-2)",
135
135
  children: [/* @__PURE__ */ jsx("span", {
136
- className: "font-mono text-(length:--cue-text-micro) tracking-[0.15em] text-fg-subtle uppercase",
136
+ className: "font-mono text-(length:--cue-text-micro) tracking-(--cue-tracking-caps) text-fg-subtle uppercase",
137
137
  children: group.label
138
138
  }), group.tokens.map((token) => {
139
139
  const property = tokenProperty(token);
@@ -23,14 +23,14 @@ const CALENDAR_CLASSES = {
23
23
  months: "relative flex flex-wrap items-start gap-(--cue-space-5)",
24
24
  month: "flex flex-col gap-(--cue-space-2)",
25
25
  month_caption: "flex h-control-sm items-center justify-center",
26
- caption_label: "font-mono text-(length:--cue-text-label) tracking-[0.15em] text-fg-subtle uppercase",
26
+ caption_label: "font-mono text-(length:--cue-text-label) tracking-(--cue-tracking-caps) text-fg-subtle uppercase",
27
27
  nav: "absolute inset-x-0 top-0 flex h-control-sm items-center justify-between",
28
28
  button_previous: "flex size-control-sm cursor-pointer items-center justify-center rounded-(--radius-control) border-0 bg-transparent p-0 text-fg-subtle outline-none transition-colors duration-150 hover:text-fg focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-offset-1 focus-visible:outline-accent disabled:pointer-events-none disabled:opacity-30 motion-reduce:transition-none",
29
29
  button_next: "flex size-control-sm cursor-pointer items-center justify-center rounded-(--radius-control) border-0 bg-transparent p-0 text-fg-subtle outline-none transition-colors duration-150 hover:text-fg focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-offset-1 focus-visible:outline-accent disabled:pointer-events-none disabled:opacity-30 motion-reduce:transition-none",
30
30
  chevron: "size-icon-sm fill-current",
31
31
  month_grid: "border-collapse border-spacing-0",
32
32
  weekdays: "",
33
- weekday: "size-control-sm p-0 text-center align-middle font-mono text-(length:--cue-text-micro) font-normal tracking-[0.1em] text-fg-subtle uppercase",
33
+ weekday: "size-control-sm p-0 text-center align-middle font-mono text-(length:--cue-text-micro) font-normal tracking-(--cue-tracking-caps-tight) text-fg-subtle uppercase",
34
34
  week: "",
35
35
  day: "p-0 text-center align-middle",
36
36
  day_button: "size-control-sm cursor-pointer rounded-(--radius-control) border-0 bg-transparent p-0 font-mono text-(length:--cue-text-ui) tabular-nums text-fg-muted outline-none transition-colors duration-150 hover:bg-surface-3 hover:text-fg focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-offset-1 focus-visible:outline-accent disabled:pointer-events-none disabled:opacity-30 motion-reduce:transition-none",
@@ -136,17 +136,17 @@ const ContextUsage = React.forwardRef(function ContextUsage({ categories, limit,
136
136
  children: [
137
137
  /* @__PURE__ */ jsx("th", {
138
138
  scope: "col",
139
- className: "pb-1 text-start font-normal tracking-[0.12em]",
139
+ className: "pb-1 text-start font-normal tracking-(--cue-tracking-label)",
140
140
  children: copy.category
141
141
  }),
142
142
  /* @__PURE__ */ jsx("th", {
143
143
  scope: "col",
144
- className: "pb-1 text-end font-normal tracking-[0.12em]",
144
+ className: "pb-1 text-end font-normal tracking-(--cue-tracking-label)",
145
145
  children: copy.tokens
146
146
  }),
147
147
  /* @__PURE__ */ jsx("th", {
148
148
  scope: "col",
149
- className: "pb-1 text-end font-normal tracking-[0.12em]",
149
+ className: "pb-1 text-end font-normal tracking-(--cue-tracking-label)",
150
150
  children: copy.usage
151
151
  })
152
152
  ]
@@ -86,7 +86,7 @@ const UnreadDivider = React.forwardRef(function UnreadDivider({ label = "New", c
86
86
  className: "bg-accent/40 h-px flex-1"
87
87
  }), /* @__PURE__ */ jsx("span", {
88
88
  "aria-hidden": true,
89
- className: cn(mono, "text-accent shrink-0 tracking-[0.15em] uppercase"),
89
+ className: cn(mono, "text-accent shrink-0 tracking-(--cue-tracking-caps) uppercase"),
90
90
  children: label
91
91
  })]
92
92
  });
@@ -43,7 +43,7 @@ const FieldLabel = React.forwardRef(function FieldLabel({ className, ...elementP
43
43
  return /* @__PURE__ */ jsx(Field.Label, {
44
44
  ref,
45
45
  "data-slot": "field-label",
46
- className: cn("font-mono text-(length:--cue-text-label) leading-none tracking-[0.1em] text-fg-muted uppercase select-none data-[disabled]:opacity-40", className),
46
+ className: cn("font-mono text-(length:--cue-text-label) leading-none tracking-(--cue-tracking-caps-tight) text-fg-muted uppercase select-none data-[disabled]:opacity-40", className),
47
47
  ...elementProps
48
48
  });
49
49
  });
@@ -40,7 +40,7 @@ const Slider$1 = React.forwardRef(function Slider$2({ className, onCommit, label
40
40
  className: cn("flex w-full flex-col gap-(--cue-space-2)", className),
41
41
  ...elementProps,
42
42
  children: [label === void 0 && !showValue ? null : /* @__PURE__ */ jsxs("div", {
43
- className: "flex items-baseline justify-between gap-(--cue-space-3) font-mono text-(length:--cue-text-label) tracking-[0.1em] text-fg-muted uppercase",
43
+ className: "flex items-baseline justify-between gap-(--cue-space-3) font-mono text-(length:--cue-text-label) tracking-(--cue-tracking-caps-tight) text-fg-muted uppercase",
44
44
  children: [label === void 0 ? /* @__PURE__ */ jsx("span", {}) : /* @__PURE__ */ jsx(Slider.Label, { children: label }), showValue ? /* @__PURE__ */ jsx(Slider.Value, { className: "tabular-nums text-fg normal-case tracking-normal" }) : null]
45
45
  }), /* @__PURE__ */ jsx(Slider.Control, {
46
46
  "data-slot": "slider-control",
@@ -159,7 +159,7 @@ const CodeBlock = React.forwardRef(function CodeBlock({ code, label, language =
159
159
  className: "flex items-center justify-between gap-(--cue-space-4) border-b border-border px-(--cue-pad-row-x) py-(--cue-pad-row-y)",
160
160
  children: [/* @__PURE__ */ jsx("span", {
161
161
  "data-slot": "code-block-label",
162
- className: "font-mono text-(length:--cue-text-micro) tracking-[0.15em] text-fg-subtle uppercase",
162
+ className: "font-mono text-(length:--cue-text-micro) tracking-(--cue-tracking-caps) text-fg-subtle uppercase",
163
163
  children: label ?? language
164
164
  }), /* @__PURE__ */ jsx(CopyButton, { value: code })]
165
165
  }), /* @__PURE__ */ jsx("pre", {
@@ -13,7 +13,7 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
13
13
  * be said out loud, because `<h2>` and `<h3>` come bold by default and a bold
14
14
  * micro-label in a dense list reads as a second kind of emphasis.
15
15
  */
16
- const LEDGER_LABEL = "font-mono text-(length:--cue-text-label) font-normal tracking-[0.15em] text-fg-subtle uppercase";
16
+ const LEDGER_LABEL = "font-mono text-(length:--cue-text-label) font-normal tracking-(--cue-tracking-caps) text-fg-subtle uppercase";
17
17
  /**
18
18
  * The disclosure button a collapsible heading holds.
19
19
  *
@@ -58,7 +58,7 @@ const Progress$1 = React.forwardRef(function Progress$2({ className, trackClassN
58
58
  children: [label === void 0 ? null : /* @__PURE__ */ jsx(Progress.Label, {
59
59
  id: namedByCaption ? captionId : void 0,
60
60
  "data-slot": "progress-label",
61
- className: "truncate tracking-[0.15em] text-fg-subtle uppercase",
61
+ className: "truncate tracking-(--cue-tracking-caps) text-fg-subtle uppercase",
62
62
  children: label
63
63
  }), showValue ? /* @__PURE__ */ jsx(Progress.Value, {
64
64
  "data-slot": "progress-value",
@@ -39,7 +39,7 @@ const Stat = React.forwardRef(function Stat({ className, label, value, detail, t
39
39
  children: [
40
40
  /* @__PURE__ */ jsx("span", {
41
41
  "data-slot": "stat-label",
42
- className: "truncate font-mono text-(length:--cue-text-micro) tracking-[0.15em] text-fg-subtle uppercase",
42
+ className: "truncate font-mono text-(length:--cue-text-micro) tracking-(--cue-tracking-caps) text-fg-subtle uppercase",
43
43
  children: label
44
44
  }),
45
45
  /* @__PURE__ */ jsx("span", {
@@ -122,7 +122,7 @@ const TableHead = React.forwardRef(function TableHead({ className, numeric = fal
122
122
  scope,
123
123
  "data-slot": "table-head",
124
124
  "data-numeric": numeric ? "" : void 0,
125
- className: cn("border-b border-border bg-surface-1 px-(--cue-pad-row-x) py-(--cue-pad-row-y) text-left font-mono text-(length:--cue-text-label) font-normal tracking-[0.15em] whitespace-nowrap text-fg-subtle uppercase", sticky ? "sticky top-0 z-3 border-b-0 shadow-[inset_0_-1px_0_var(--cue-hair-strong)]" : null, className),
125
+ className: cn("border-b border-border bg-surface-1 px-(--cue-pad-row-x) py-(--cue-pad-row-y) text-left font-mono text-(length:--cue-text-label) font-normal tracking-(--cue-tracking-caps) whitespace-nowrap text-fg-subtle uppercase", sticky ? "sticky top-0 z-3 border-b-0 shadow-[inset_0_-1px_0_var(--cue-hair-strong)]" : null, className),
126
126
  ...elementProps
127
127
  });
128
128
  });
@@ -201,7 +201,7 @@ const Table = {
201
201
  colSpan: span,
202
202
  scope: "rowgroup",
203
203
  "data-slot": "table-group-cell",
204
- className: cn("bg-bg px-(--cue-pad-row-x) py-(--cue-pad-row-y) text-left font-mono text-(length:--cue-text-label) font-normal tracking-[0.15em] whitespace-nowrap text-fg-subtle uppercase", sticky ? "sticky z-2 [top:var(--cue-table-group-top,0px)]" : null, className),
204
+ className: cn("bg-bg px-(--cue-pad-row-x) py-(--cue-pad-row-y) text-left font-mono text-(length:--cue-text-label) font-normal tracking-(--cue-tracking-caps) whitespace-nowrap text-fg-subtle uppercase", sticky ? "sticky z-2 [top:var(--cue-table-group-top,0px)]" : null, className),
205
205
  children: [/* @__PURE__ */ jsx(Label, {
206
206
  "data-slot": "table-group-label",
207
207
  className: TABLE_GROUP_LABEL,
@@ -191,7 +191,7 @@ const TerminalFrame = React.forwardRef(function TerminalFrame({ className, title
191
191
  className: "flex h-control-md shrink-0 items-center justify-between gap-(--cue-space-3) border-b border-border px-(--cue-pad-row-x)",
192
192
  children: [/* @__PURE__ */ jsx("span", {
193
193
  "data-slot": "terminal-frame-title",
194
- className: "min-w-0 truncate text-(length:--cue-text-label) tracking-[0.15em] text-fg-subtle uppercase",
194
+ className: "min-w-0 truncate text-(length:--cue-text-label) tracking-(--cue-tracking-caps) text-fg-subtle uppercase",
195
195
  children: title
196
196
  }), copy ? /* @__PURE__ */ jsx("span", {
197
197
  "data-slot": "terminal-frame-copy",
@@ -2,7 +2,7 @@
2
2
  /** What each ground paints. `"none"` paints nothing, so whatever is behind shows through. */
3
3
  const GROUND_CLASSES = {
4
4
  plain: "bg-surface-1",
5
- dots: "bg-surface-1 bg-[radial-gradient(circle,var(--cue-hair-strong)_1px,transparent_1.3px)] bg-[length:14px_14px]",
5
+ dots: "bg-surface-1 bg-(image:--cue-paint-screen) bg-(length:--cue-paint-screen-size)",
6
6
  none: ""
7
7
  };
8
8
  //#endregion
@@ -94,7 +94,7 @@ const Disclosure = React.forwardRef(function Disclosure({ className, label = "ad
94
94
  children: [/* @__PURE__ */ jsxs(Collapsible.Trigger, {
95
95
  ref,
96
96
  "data-slot": "disclosure-trigger",
97
- className: cn("group/disclosure inline-flex cursor-pointer items-center gap-(--cue-space-2) self-start border-0 bg-transparent p-0 py-(--cue-space-2) font-mono text-(length:--cue-text-label) tracking-[0.15em] text-fg-subtle uppercase transition-colors duration-150 outline-none select-none hover:text-fg-muted focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-offset-2 focus-visible:outline-accent", className),
97
+ className: cn("group/disclosure inline-flex cursor-pointer items-center gap-(--cue-space-2) self-start border-0 bg-transparent p-0 py-(--cue-space-2) font-mono text-(length:--cue-text-label) tracking-(--cue-tracking-caps) text-fg-subtle uppercase transition-colors duration-150 outline-none select-none hover:text-fg-muted focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-offset-2 focus-visible:outline-accent", className),
98
98
  ...elementProps,
99
99
  children: [
100
100
  /* @__PURE__ */ jsx("span", {
@@ -20,7 +20,7 @@ const DescriptionList = {
20
20
  return /* @__PURE__ */ jsx("dt", {
21
21
  ref,
22
22
  "data-slot": "description-list-term",
23
- className: cn("font-mono text-(length:--cue-text-label) tracking-[0.15em] text-fg-subtle uppercase", className),
23
+ className: cn("font-mono text-(length:--cue-text-label) tracking-(--cue-tracking-caps) text-fg-subtle uppercase", className),
24
24
  ...elementProps
25
25
  });
26
26
  }),