@cueplusplus/ui 0.1.0 → 0.3.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 (246) hide show
  1. package/CHANGELOG.md +705 -0
  2. package/dist/brand/_chassis.d.ts +54 -0
  3. package/dist/brand/_chassis.js +81 -0
  4. package/dist/brand/_geometry.js +41 -0
  5. package/dist/brand/cue-logotype.d.ts +29 -0
  6. package/dist/brand/cue-logotype.js +60 -0
  7. package/dist/brand/cue-mark.d.ts +30 -0
  8. package/dist/brand/cue-mark.js +61 -0
  9. package/dist/brand/index.d.ts +5 -0
  10. package/dist/brand/plussie.d.ts +67 -0
  11. package/dist/brand/plussie.js +125 -0
  12. package/dist/chat/agent-pile.js +1 -1
  13. package/dist/chat/ask-box.js +2 -2
  14. package/dist/chat/delegation-card.js +1 -1
  15. package/dist/chat/message.js +2 -2
  16. package/dist/chrome/_edge-scroller.d.ts +45 -0
  17. package/dist/chrome/_edge-scroller.js +149 -0
  18. package/dist/chrome/_glyphs.js +19 -1
  19. package/dist/chrome/_tabs-scroll.d.ts +13 -8
  20. package/dist/chrome/_tabs-scroll.js +13 -8
  21. package/dist/chrome/app-bar.d.ts +103 -0
  22. package/dist/chrome/app-bar.js +175 -0
  23. package/dist/chrome/app-shell.d.ts +125 -0
  24. package/dist/chrome/app-shell.js +167 -0
  25. package/dist/chrome/footer.d.ts +75 -0
  26. package/dist/chrome/footer.js +68 -0
  27. package/dist/chrome/index.d.ts +5 -1
  28. package/dist/chrome/index.js +4 -1
  29. package/dist/chrome/navigation-menu.js +1 -1
  30. package/dist/chrome/page-shell.d.ts +1 -1
  31. package/dist/chrome/page-shell.js +15 -5
  32. package/dist/chrome/segmented-control.d.ts +19 -0
  33. package/dist/chrome/segmented-control.js +40 -21
  34. package/dist/chrome/tabs.js +21 -65
  35. package/dist/chrome/toolbar.d.ts +22 -0
  36. package/dist/chrome/toolbar.js +26 -5
  37. package/dist/configurator/_overrides.js +22 -8
  38. package/dist/configurator/configurator.js +1 -1
  39. package/dist/configurator/panel-sections.js +10 -4
  40. package/dist/dmx/channel-matrix.js +1 -1
  41. package/dist/forms/otp-field.js +1 -1
  42. package/dist/index.d.ts +18 -9
  43. package/dist/index.js +16 -10
  44. package/dist/instruments/data-table.js +1 -1
  45. package/dist/instruments/index.d.ts +2 -2
  46. package/dist/instruments/index.js +2 -2
  47. package/dist/instruments/table.d.ts +14 -1
  48. package/dist/instruments/table.js +20 -1
  49. package/dist/layout/carousel.js +1 -1
  50. package/dist/layout/container.d.ts +1 -1
  51. package/dist/layout/container.js +6 -3
  52. package/dist/layout/index.d.ts +3 -3
  53. package/dist/layout/index.js +3 -3
  54. package/dist/layout/pagination.js +1 -1
  55. package/dist/layout/sidebar.d.ts +23 -3
  56. package/dist/layout/sidebar.js +18 -7
  57. package/dist/midi/spectrum-visualizer.js +1 -1
  58. package/dist/midi/timeline-ruler.js +1 -1
  59. package/dist/overlays/command-palette.js +1 -1
  60. package/dist/overlays/dialog.js +1 -1
  61. package/dist/overlays/dropdown-menu.js +2 -2
  62. package/dist/overlays/hover-card.js +1 -1
  63. package/dist/overlays/index.js +1 -1
  64. package/dist/overlays/popover.js +1 -1
  65. package/dist/overlays/sheet.js +1 -1
  66. package/dist/overlays/toast.js +1 -1
  67. package/dist/primitives/chip.d.ts +1 -1
  68. package/dist/primitives/index.d.ts +1 -1
  69. package/dist/primitives/index.js +1 -1
  70. package/dist/primitives/status-dot.d.ts +7 -0
  71. package/dist/primitives/status-dot.js +8 -1
  72. package/dist/styles.css +58 -2
  73. package/dist/system/density.d.ts +4 -1
  74. package/dist/system/density.js +12 -4
  75. package/dist/system/index.d.ts +4 -4
  76. package/dist/system/portal.d.ts +5 -5
  77. package/dist/system/portal.js +30 -11
  78. package/dist/system/prepaint.d.ts +34 -9
  79. package/dist/system/prepaint.js +48 -25
  80. package/dist/system/theme-provider.d.ts +48 -11
  81. package/dist/system/theme-provider.js +109 -35
  82. package/dist/system/use-density.d.ts +3 -3
  83. package/dist/system/use-density.js +16 -6
  84. package/dist/system/use-theme.d.ts +4 -2
  85. package/dist/system/use-theme.js +4 -2
  86. package/dist/theming/_presets.js +133 -5
  87. package/dist/theming/create-theme.d.ts +2 -2
  88. package/dist/theming/create-theme.js +37 -19
  89. package/dist/theming/serialize.d.ts +1 -1
  90. package/dist/theming/serialize.js +25 -1
  91. package/manifest/components/accordion.json +154 -0
  92. package/manifest/components/agent-pile.json +116 -0
  93. package/manifest/components/alert-dialog.json +190 -0
  94. package/manifest/components/app-bar.json +244 -0
  95. package/manifest/components/app-shell.json +291 -0
  96. package/manifest/components/app-window-frame.json +102 -0
  97. package/manifest/components/ask-box.json +209 -0
  98. package/manifest/components/autocomplete.json +197 -0
  99. package/manifest/components/avatar-group.json +72 -0
  100. package/manifest/components/avatar.json +95 -0
  101. package/manifest/components/breadcrumb.json +74 -0
  102. package/manifest/components/button-group.json +74 -0
  103. package/manifest/components/button.json +125 -0
  104. package/manifest/components/calendar.json +65 -0
  105. package/manifest/components/card.json +140 -0
  106. package/manifest/components/carousel.json +200 -0
  107. package/manifest/components/channel-matrix.json +173 -0
  108. package/manifest/components/chart-container.json +111 -0
  109. package/manifest/components/chart-ramp.json +72 -0
  110. package/manifest/components/chart-swatch.json +65 -0
  111. package/manifest/components/chart-tooltip-content.json +114 -0
  112. package/manifest/components/checkbox-group.json +68 -0
  113. package/manifest/components/checkbox.json +93 -0
  114. package/manifest/components/chip.json +132 -0
  115. package/manifest/components/collapsible.json +120 -0
  116. package/manifest/components/color-area.json +59 -0
  117. package/manifest/components/color-field.json +79 -0
  118. package/manifest/components/color-picker.json +175 -0
  119. package/manifest/components/color-slider.json +75 -0
  120. package/manifest/components/color-swatch.json +68 -0
  121. package/manifest/components/colors-section.json +66 -0
  122. package/manifest/components/combobox.json +198 -0
  123. package/manifest/components/command-palette.json +177 -0
  124. package/manifest/components/composer.json +176 -0
  125. package/manifest/components/container.json +60 -0
  126. package/manifest/components/context-menu.json +121 -0
  127. package/manifest/components/copy-button.json +93 -0
  128. package/manifest/components/cue-logotype.json +96 -0
  129. package/manifest/components/cue-mark.json +97 -0
  130. package/manifest/components/cue-portal-frame.json +55 -0
  131. package/manifest/components/data-table-pagination.json +83 -0
  132. package/manifest/components/data-table-toolbar.json +104 -0
  133. package/manifest/components/date-field.json +80 -0
  134. package/manifest/components/date-picker.json +191 -0
  135. package/manifest/components/date-range-picker.json +191 -0
  136. package/manifest/components/delegation-card.json +144 -0
  137. package/manifest/components/density.json +58 -0
  138. package/manifest/components/description-list.json +84 -0
  139. package/manifest/components/dialog.json +198 -0
  140. package/manifest/components/disclosure.json +109 -0
  141. package/manifest/components/dmx-bar.json +94 -0
  142. package/manifest/components/dmx-strip.json +101 -0
  143. package/manifest/components/drawer.json +179 -0
  144. package/manifest/components/dropdown-menu.json +229 -0
  145. package/manifest/components/empty-state.json +90 -0
  146. package/manifest/components/env-var-input.json +150 -0
  147. package/manifest/components/export-dialog.json +84 -0
  148. package/manifest/components/eyebrow.json +56 -0
  149. package/manifest/components/field-description.json +63 -0
  150. package/manifest/components/field-error.json +77 -0
  151. package/manifest/components/field-label.json +63 -0
  152. package/manifest/components/field.json +79 -0
  153. package/manifest/components/file-upload.json +159 -0
  154. package/manifest/components/flow-background.json +50 -0
  155. package/manifest/components/flow-controls.json +50 -0
  156. package/manifest/components/footer.json +112 -0
  157. package/manifest/components/grid.json +81 -0
  158. package/manifest/components/group-bar.json +102 -0
  159. package/manifest/components/hover-card.json +151 -0
  160. package/manifest/components/icon-button.json +88 -0
  161. package/manifest/components/info-tip.json +98 -0
  162. package/manifest/components/input-group.json +91 -0
  163. package/manifest/components/input.json +89 -0
  164. package/manifest/components/item.json +129 -0
  165. package/manifest/components/kbd.json +52 -0
  166. package/manifest/components/link.json +81 -0
  167. package/manifest/components/log-viewer.json +139 -0
  168. package/manifest/components/menubar.json +157 -0
  169. package/manifest/components/message-list.json +100 -0
  170. package/manifest/components/message.json +116 -0
  171. package/manifest/components/meter.json +114 -0
  172. package/manifest/components/multi-select.json +190 -0
  173. package/manifest/components/musical-time-input.json +113 -0
  174. package/manifest/components/navigation-menu.json +226 -0
  175. package/manifest/components/node-card.json +109 -0
  176. package/manifest/components/node-handle.json +69 -0
  177. package/manifest/components/number-field.json +107 -0
  178. package/manifest/components/otp-field.json +128 -0
  179. package/manifest/components/page-shell.json +96 -0
  180. package/manifest/components/pagination.json +92 -0
  181. package/manifest/components/panel-header.json +77 -0
  182. package/manifest/components/panel.json +71 -0
  183. package/manifest/components/password-input.json +119 -0
  184. package/manifest/components/piano-keyboard.json +120 -0
  185. package/manifest/components/plussie.json +111 -0
  186. package/manifest/components/popover.json +193 -0
  187. package/manifest/components/preset-section.json +73 -0
  188. package/manifest/components/progress.json +95 -0
  189. package/manifest/components/radio-group.json +73 -0
  190. package/manifest/components/radio.json +80 -0
  191. package/manifest/components/rating.json +141 -0
  192. package/manifest/components/resizable.json +88 -0
  193. package/manifest/components/row.json +109 -0
  194. package/manifest/components/scroll-area.json +91 -0
  195. package/manifest/components/scrollable-tabs-list.json +83 -0
  196. package/manifest/components/scrub-input.json +200 -0
  197. package/manifest/components/seam-cell.json +75 -0
  198. package/manifest/components/seam-grid.json +75 -0
  199. package/manifest/components/seam-list.json +56 -0
  200. package/manifest/components/search-input.json +134 -0
  201. package/manifest/components/section-header.json +112 -0
  202. package/manifest/components/segmented-control.json +138 -0
  203. package/manifest/components/select.json +194 -0
  204. package/manifest/components/separator.json +53 -0
  205. package/manifest/components/shape-section.json +66 -0
  206. package/manifest/components/sheet.json +186 -0
  207. package/manifest/components/sidebar.json +198 -0
  208. package/manifest/components/signal-edge.json +56 -0
  209. package/manifest/components/skeleton.json +46 -0
  210. package/manifest/components/slider.json +89 -0
  211. package/manifest/components/sparkline.json +76 -0
  212. package/manifest/components/spectrum-visualizer.json +115 -0
  213. package/manifest/components/spinner.json +61 -0
  214. package/manifest/components/stack.json +96 -0
  215. package/manifest/components/stat.json +87 -0
  216. package/manifest/components/status-bar.json +58 -0
  217. package/manifest/components/status-dot.json +78 -0
  218. package/manifest/components/stepper.json +89 -0
  219. package/manifest/components/switch.json +87 -0
  220. package/manifest/components/table-scroll-region.json +69 -0
  221. package/manifest/components/table.json +155 -0
  222. package/manifest/components/tabs.json +145 -0
  223. package/manifest/components/tags-input.json +190 -0
  224. package/manifest/components/terminal-frame.json +119 -0
  225. package/manifest/components/textarea.json +76 -0
  226. package/manifest/components/theme-configurator.json +124 -0
  227. package/manifest/components/theme-provider.json +134 -0
  228. package/manifest/components/threshold-rail.json +160 -0
  229. package/manifest/components/time-field.json +80 -0
  230. package/manifest/components/timeline-ruler.json +139 -0
  231. package/manifest/components/timeline.json +115 -0
  232. package/manifest/components/title-bar.json +82 -0
  233. package/manifest/components/toast.json +130 -0
  234. package/manifest/components/toggle-group.json +106 -0
  235. package/manifest/components/toggle.json +109 -0
  236. package/manifest/components/token-editor.json +90 -0
  237. package/manifest/components/toolbar.json +163 -0
  238. package/manifest/components/tooltip.json +164 -0
  239. package/manifest/components/tree-visibility-toggle.json +84 -0
  240. package/manifest/components/tree.json +140 -0
  241. package/manifest/components/two-step-button.json +113 -0
  242. package/manifest/components/universe-grid.json +127 -0
  243. package/manifest/components/usage-chart.json +124 -0
  244. package/manifest/manifest.json +2142 -0
  245. package/manifest/tokens.json +138 -0
  246. package/package.json +13 -5
package/CHANGELOG.md ADDED
@@ -0,0 +1,705 @@
1
+ # @cueplusplus/ui
2
+
3
+ ## 0.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 31e3607: Ship the linked RequestPort preset release across tokens, UI, and brand tokens.
8
+
9
+ The release adds the typed RequestPort preset and its generated dark, light, and
10
+ system selectors; system SSR, prepaint, provider, and portal behavior; the
11
+ `persistPreferences={false}` and authoritative prepaint options contracts; the
12
+ typed `fontFamilies` provider/portal override; the deterministic package
13
+ manifest and companion checksums; and the accessible `TableScrollRegion`.
14
+
15
+ All three linked tarballs receive the same minor version and changelog entry.
16
+ The Version Packages path regenerates the package manifest after applying those
17
+ versions and rejects stale or nondeterministic output before publication.
18
+
19
+ ### Patch Changes
20
+
21
+ - Updated dependencies [31e3607]
22
+ - @cueplusplus/tokens@0.3.0
23
+
24
+ ## 0.2.0
25
+
26
+ ### Minor Changes
27
+
28
+ - 33a95c4: Typeface is a third axis, beside theme and density.
29
+
30
+ `data-font` selects one of eight font pairings — a sans and a monospace — the
31
+ same way `data-theme` selects a palette and `data-density` selects a geometry.
32
+ `<ThemeProvider font>`, `useTheme().font` / `setFont`, persistence beside the
33
+ other two, the pre-paint script, and every portal root carry it.
34
+
35
+ ```tsx
36
+ <ThemeProvider theme="cue" density="normal" font="plex">
37
+ <App />
38
+ </ThemeProvider>
39
+ ```
40
+
41
+ | id | sans | mono | what your app has to do |
42
+ | -------- | ---------------------- | ------------------- | ---------------------------------- |
43
+ | `system` | the platform's UI sans | **the theme's own** | nothing — this is the default |
44
+ | `geist` | Geist | JetBrains Mono | deliver two faces |
45
+ | `inter` | Inter | IBM Plex Mono | deliver two faces |
46
+ | `plex` | IBM Plex Sans | IBM Plex Mono | deliver two faces |
47
+ | `roboto` | Roboto | Roboto Mono | deliver two faces |
48
+ | `source` | Source Sans 3 | Source Code Pro | deliver two faces |
49
+ | `apple` | SF Pro Text | SF Mono | nothing — and nothing you _may_ do |
50
+ | `office` | Calibri (Carlito) | Cascadia Mono | nothing — and nothing you _may_ do |
51
+
52
+ New exports from `@cueplusplus/tokens`: `FONTS`, `FontName`, `DEFAULT_FONT`,
53
+ `FONT_PAIRINGS`, `FONT_FACES`, `FontDelivery`, `FontPairing`, `faceProperty`.
54
+ `prepaintScript()` takes a fourth argument, the default pairing.
55
+
56
+ ## You have to load the fonts. We will not.
57
+
58
+ **This package ships no font file and no `@font-face`, and that is deliberate.**
59
+ A library that injected one would be choosing your network requests, your
60
+ content-security policy and your font licensing, in a stylesheet you imported
61
+ for its colours. What a pairing emits instead is a hook with the family name as
62
+ its fallback:
63
+
64
+ ```css
65
+ [data-font="inter"] {
66
+ --cue-font-sans: var(--cue-face-inter, Inter), ui-sans-serif, system-ui, …;
67
+ --cue-font-mono:
68
+ var(--cue-face-ibm-plex-mono, "IBM Plex Mono"), ui-monospace, …;
69
+ }
70
+ ```
71
+
72
+ Assign nothing and the stack still resolves — a local install first, then the
73
+ platform — so no pairing ever renders as nothing. Assign the property and
74
+ everything painted from the token follows. With `next/font`, the property name
75
+ _is_ the option:
76
+
77
+ ```tsx
78
+ const inter = Inter({ subsets: ["latin"], display: "swap", preload: false, variable: "--cue-face-inter" });
79
+ <html className={inter.variable}>
80
+ ```
81
+
82
+ `preload: false` matters: with preloading on, a site offering five webfont
83
+ pairings makes every visitor download all of them to render in one.
84
+ `FONT_PAIRINGS[name].faces` is the list of properties one pairing needs;
85
+ `FONT_FACES` is every face at once, as `property → family`.
86
+
87
+ **`apple` and `office` are stacks and must stay stacks.** SF Pro and SF Mono are
88
+ Apple-licensed and may not be served as webfonts; Calibri is Microsoft's and
89
+ ships with Windows and Office rather than with anybody's site (Carlito is its
90
+ metric-compatible libre twin, and is in the stack). They light up where
91
+ installed and fall through cleanly where they are not. Do not bundle them.
92
+
93
+ ## A theme's monospace still applies — until somebody picks a pairing
94
+
95
+ Seven presets name a monospace of their own, and seven pairings name one, so
96
+ one token was claimed twice.
97
+ Neither axis writes it now: a theme publishes `--cue-font-theme-mono`, a pairing
98
+ publishes `--cue-font-pairing-mono`, and `--cue-font-mono` resolves the two,
99
+ pairing first. **A chosen pairing wins**, at whatever element each was stamped
100
+ on — a pairing is what a person picked out of a menu and a preset's mono is what
101
+ its author chose in the absence of a person. The default pairing, `system`,
102
+ declines the question, so an app that never touches the axis keeps exactly the
103
+ monospace it has today.
104
+
105
+ ## Two things that change without you asking
106
+
107
+ **The base sans no longer names `Geist`.** It named a font this package has
108
+ never delivered, so for almost every visitor it resolved to the next entry
109
+ anyway. `--cue-font-sans` and `--cue-font-display` are now the platform stack;
110
+ Geist is the head of the `geist` pairing, which your app can actually deliver.
111
+ If you want it back, deliver it: `font="geist"` plus the two `--cue-face-*`
112
+ assignments.
113
+
114
+ **A generated theme's mono moves with it.** `createTheme({ fonts: { mono } })`
115
+ now writes `--cue-font-theme-mono`. Nothing to change unless you read the
116
+ generated `tokens` map by key.
117
+
118
+ ## Migrating
119
+
120
+ Nothing is required. Two things are worth doing:
121
+
122
+ 1. **Pass the pairing to the pre-paint script**, as its fourth argument, if your
123
+ app's default is not `system`:
124
+ `prepaintScript(DEFAULT_STORAGE_KEY, "cue", "normal", "geist")`. A theme that
125
+ arrives one frame late is a flash of the wrong colour; a _family_ that
126
+ arrives one frame late reflows every line under the reader.
127
+ 2. **If your own CSS overrides `--cue-font-mono`** under a `[data-theme]` block
128
+ of your own, move it to `--cue-font-theme-mono` — otherwise your override
129
+ beats the typeface picker and yours is the one theme it cannot move.
130
+
131
+ `font` is a root-level prop: there is no font island, and a nested provider
132
+ forwards the axis (and `setFont`) to the root. A specimen that genuinely wants
133
+ one face beside another needs nothing from this library but `data-font` on a
134
+ `<div>`.
135
+
136
+ - 038837d: `AppShell`: the console frame, and the mobile navigation that goes with it.
137
+
138
+ Every console screen is the same five parts in the same arrangement — title bar,
139
+ navigation column, toolbar, one scrolling work area, status bar — and until now
140
+ each one arranged them by hand. `AppShell` is that arrangement, with the
141
+ arithmetic that actually holds it up: `h-dvh` rather than `min-h-dvh`, an
142
+ unbroken `min-h-0` chain from the frame down to the scroller, `min-w-0` on the
143
+ content column, and a scroller that is not the document, so the chrome stays put
144
+ with no `sticky` anywhere.
145
+
146
+ ```tsx
147
+ import {
148
+ AppShell,
149
+ Sidebar,
150
+ StatusBar,
151
+ TitleBar,
152
+ Toolbar,
153
+ } from "@cueplusplus/ui";
154
+
155
+ <AppShell.Root>
156
+ <TitleBar center="main-stage.cue">
157
+ <AppShell.NavTrigger />
158
+ </TitleBar>
159
+ <AppShell.Body>
160
+ <AppShell.Sidebar aria-label="Console" drawerTitle="Console">
161
+ <Sidebar.Section label="Show">
162
+ <Sidebar.Item icon={List} active>
163
+ Cues
164
+ </Sidebar.Item>
165
+ </Sidebar.Section>
166
+ </AppShell.Sidebar>
167
+ <AppShell.Content>
168
+ <Toolbar.Root aria-label="Playback">…</Toolbar.Root>
169
+ <AppShell.Scroller>…</AppShell.Scroller>
170
+ </AppShell.Content>
171
+ <AppShell.Aside aria-label="Inspector">…</AppShell.Aside>
172
+ </AppShell.Body>
173
+ <StatusBar>…</StatusBar>
174
+ </AppShell.Root>;
175
+ ```
176
+
177
+ Seven parts: `Root` (the frame), `Body` (the middle row), `Sidebar` (the
178
+ navigation), `NavTrigger` (the control that opens it on a phone), `Content` (the
179
+ `<main>` column — pass `main={false}` when the shell is embedded in a page that
180
+ already has one), `Scroller` (the only element that may scroll) and `Aside` (a
181
+ trailing column with a scroller of its own). `TitleBar` and `StatusBar` go in as
182
+ ordinary children: both are already `shrink-0`, so a wrapper would only repeat
183
+ that.
184
+
185
+ **`AppShell` is the one component in this library with a viewport breakpoint.**
186
+ `AppShell.Sidebar` renders the same children twice — as the 14rem column at
187
+ Tailwind's stock `md` (48rem) and up, and as a `Drawer` below it, opened by
188
+ `AppShell.NavTrigger` from the bar. It is a CSS-only dual render, both shapes in
189
+ the markup with one hidden per viewport: no `useMediaQuery`, nothing to measure,
190
+ and a first server-rendered frame that is already correct. The switch decides
191
+ navigation shape and nothing else; everything else in the library stays
192
+ intrinsically responsive, and a later component that wants a breakpoint is a new
193
+ decision rather than a precedent this one set.
194
+
195
+ `PageShell` and `Container` now offer the same four measures.
196
+
197
+ `narrow` (42rem) and `wide` (54rem) are unchanged. `broad` (84rem) is new on
198
+ both: the application measure, wide enough for a two-column documentation page
199
+ or a device frame. `full` is new on `PageShell`, which had no uncapped rung at
200
+ all while `Container` did. Nothing existing moves — `narrow` is still the
201
+ default on both.
202
+
203
+ ```tsx
204
+ <PageShell width="broad" title="Components">…</PageShell>
205
+ <PageShell width="full" title="Gallery">…</PageShell>
206
+ ```
207
+
208
+ - 7eeb1c4: New component group, `brand`: the CUE++ marks, as components rather than files.
209
+
210
+ `CueMark` is the circular mark, `CueLogotype` is the wordmark and mark locked up
211
+ at 778:367, and `Plussie` is the character — the same circle and the same two
212
+ `+` glyphs the mark draws, out of the same geometry module, with the eyes in
213
+ their own groups so a pose can move them. All three come from the root barrel
214
+ (`@cueplusplus/ui`), pull no optional peer, and are static markup, so a
215
+ server-rendered header costs no client bundle.
216
+
217
+ ```tsx
218
+ import { CueLogotype, CueMark, Plussie } from "@cueplusplus/ui";
219
+
220
+ <CueMark size="sm" />
221
+ <CueLogotype size="lg" title="CUE++" />
222
+ <Plussie size={96} expression="wink" />
223
+ ```
224
+
225
+ Props on all three: `size` (`"sm" | "md" | "lg"`, or a height in px), which sets
226
+ the height and lets the artwork's ratio decide the width; `tone`
227
+ (`"inherit" | "fg" | "accent"`, default `"inherit"` = `currentColor`); and an
228
+ optional `title`, which turns a decorative `aria-hidden` mark into a labelled
229
+ `role="img"`. `Plussie` adds `expression` (`default`, `blink`, `wink`,
230
+ `look-left`, `look-right`, `look-up`, `look-down` — each one a still from the
231
+ character's own animations) and `idle`, a CSS-only blink that is off by default
232
+ and switched off again under `prefers-reduced-motion`.
233
+
234
+ There is no light/dark pair to choose between. `@cueplusplus/brand-tokens` still
235
+ ships the four source SVGs as files for the places that need a URL — a favicon,
236
+ an `<img>`, an email — and those hard-code `white`, `black` and `#1E1E1E`.
237
+ These components take their ink from the token layer instead, so one element is
238
+ correct in all eight presets and both modes. The path data is the same artwork,
239
+ copied verbatim.
240
+
241
+ - b86f482: The density ladder is five rungs, and the two names in the middle have moved.
242
+
243
+ `ultra-compact` · `normal` · `large` was never a ladder anyone could reason
244
+ about: the rung called `normal` is what every other design system calls
245
+ _compact_, the rung called `large` is what everyone else calls _normal_, and
246
+ above that there was nothing at all — no level for a touch panel, a stage
247
+ monitor, or a reader who needs the whole screen a size up. This renames the two
248
+ misnamed rungs to what they always were and adds the two that were missing.
249
+
250
+ **Minor rather than major because the package is pre-1.0** — 0.x's breaking rung
251
+ is the minor one, and this is breaking.
252
+
253
+ **Read the migration before you upgrade.** One of its four steps is a prop
254
+ rename a compiler catches. The other three are not: CSS of your own keyed on
255
+ `[data-density]`, a label map with one entry per level, and a persisted
256
+ preference all keep working after this release and quietly mean something else.
257
+
258
+ ## The mapping
259
+
260
+ | you wrote | you now write | geometry |
261
+ | --------------- | ----------------- | ---------------------------------------------------- |
262
+ | `ultra-compact` | `ultra-compact` | unchanged |
263
+ | `normal` | **`compact`** | **unchanged** — the name moved, not a pixel |
264
+ | `large` | **`normal`** | **unchanged** — the name moved, not a pixel |
265
+ | — | **`large`** | new: a rung above what the ladder used to top out at |
266
+ | — | **`ultra-large`** | new: the top, and the mirror of `ultra-compact` |
267
+
268
+ Nothing that existed changed size. `<ThemeProvider density="normal">` used to
269
+ render 24px controls and now renders 32px ones — not because the geometry moved
270
+ but because `normal` now names the rung above the one it used to name.
271
+
272
+ ## Migrating
273
+
274
+ Four things move. Only the first and the last are visible to a compiler; the two
275
+ in the middle are the ones that ship a wrong-looking screen with a green build.
276
+
277
+ ### 1. Rename every level you name, one step down the ladder
278
+
279
+ Everywhere you write a density — the provider, a `<Density>` island, a prop you pass
280
+ through, a test:
281
+
282
+ ```diff
283
+ -<ThemeProvider theme="cue" density="normal">
284
+ +<ThemeProvider theme="cue" density="compact">
285
+ ```
286
+
287
+ ```diff
288
+ -<Density density="large">
289
+ +<Density density="normal">
290
+ ```
291
+
292
+ `ultra-compact` is unchanged and needs no edit. Do the two renames in that
293
+ order, or in one pass — `normal` → `compact` and `large` → `normal` — and your
294
+ screens render exactly as they did before.
295
+
296
+ **If you never passed a `density`, this step is a no-op.** The default moved
297
+ from `normal` to `compact`, which is the same geometry it always was: an app
298
+ that never chose a level renders identically before and after.
299
+
300
+ ### 2. Rename your own `[data-density]` CSS — and add blocks for the two new rungs
301
+
302
+ **This is the half that fails silently.** If your app keys any of its own CSS on
303
+ `data-density` — a per-rung scalar you multiply your lengths by, a per-rung
304
+ override, anything — those selectors still match a valid attribute value after
305
+ this release. They just match a _different rung_. Nothing throws, nothing logs,
306
+ no build fails: your rows simply stop matching the controls inside them.
307
+
308
+ ```diff
309
+ :root { --app-type: 1; --app-space: 1; }
310
+ -[data-density="normal"] { --app-type: 1; --app-space: 1; }
311
+ -[data-density="large"] { --app-type: 1.111; --app-space: 1.333; }
312
+ +[data-density="compact"] { --app-type: 1; --app-space: 1; }
313
+ +[data-density="normal"] { --app-type: 1.111; --app-space: 1.333; }
314
+ +/* and two blocks that did not exist before — continue your own step, or read
315
+ + the ratio off the library's ladder: --cue-density is 0.85 / 1 / 1.3 / 1.6 / 1.9
316
+ + and the spacing sequence shifts one place per rung. */
317
+ +[data-density="large"] { --app-type: …; --app-space: …; }
318
+ +[data-density="ultra-large"] { --app-type: …; --app-space: …; }
319
+ ```
320
+
321
+ What each rung does if you rename the props and stop there:
322
+
323
+ | rung | if you only renamed the props | what the reader sees |
324
+ | --------------- | ----------------------------------------------- | ------------------------------------------------------------------------------- |
325
+ | `ultra-compact` | your `ultra-compact` block still matches | correct |
326
+ | `compact` | **no block matches** — falls through to `:root` | your scalars sit at their base values while the library's geometry is a rung up |
327
+ | `normal` | your old `normal` block matches | your scalars are a rung behind the library's |
328
+ | `large` | your old `large` block matches | your scalars are two rungs behind |
329
+ | `ultra-large` | **no block matches** — falls through to `:root` | base scalars against the largest geometry the ladder has |
330
+
331
+ A rung with no block of yours does not fall back to the nearest one. It falls
332
+ through to whatever `:root` declares, which is almost always the smallest value
333
+ you own. Grep your stylesheets for `data-density` before you upgrade:
334
+
335
+ ```sh
336
+ rg 'data-density' --glob '!node_modules'
337
+ ```
338
+
339
+ ### 3. Fix anything that enumerates the ladder
340
+
341
+ A label map, a switcher, a segmented control, a settings screen, a persisted
342
+ preference — anything with one entry per density level is now missing two and
343
+ mis-naming two. A map keyed by the old three names does not error; it returns
344
+ `undefined`, and most switchers render the raw slug:
345
+
346
+ ```diff
347
+ const DENSITY_LABELS = {
348
+ "ultra-compact": "Ultra compact",
349
+ - normal: "Normal",
350
+ - large: "Large",
351
+ + compact: "Compact",
352
+ + normal: "Normal",
353
+ + large: "Large",
354
+ + "ultra-large": "Ultra large",
355
+ };
356
+ ```
357
+
358
+ `DENSITIES` from `@cueplusplus/tokens` is the list to derive from rather than
359
+ restate — it is five entries now and it will be right next time too. If your map
360
+ is typed `Record<Density, string>` TypeScript will fail the build for you; if it
361
+ is a plain object literal, nothing will.
362
+
363
+ **A persisted preference that says `"normal"` is now a bigger screen.** The
364
+ provider stores the level under `localStorage` and validates it against the
365
+ ladder, so `"normal"` is still a valid value — it just means a different rung.
366
+ Migrate the stored value the same way you migrate the code, or accept that
367
+ returning users move up one rung once.
368
+
369
+ ### 4. `density-ultra:` is now `density-ultra-compact:`
370
+
371
+ The stylesheet registers one Tailwind variant per rung, each named after the
372
+ rung it matches: `density-ultra-compact:`, `density-compact:`,
373
+ `density-normal:`, `density-large:`, `density-ultra-large:`. `density-ultra:` is
374
+ gone, because with an `ultra-large` rung on the ladder "ultra" names neither end
375
+ of it — and an unknown variant is a build error, so this one tells you.
376
+ `density-large:` keeps its name and changes meaning with its rung, which does
377
+ not.
378
+
379
+ ## The two new rungs
380
+
381
+ Every axis continues the step the three existing rungs already walk, rather than
382
+ scaling anything by a factor:
383
+
384
+ | | ultra-compact | compact | normal | **large** | **ultra-large** |
385
+ | ---------------- | ------------- | ------- | -------- | ------------ | --------------- |
386
+ | `control-md` | 20px | 24px | 32px | **40px** | **48px** |
387
+ | `chip-h` | 16px | 18px | 22px | **26px** | **30px** |
388
+ | `icon-md` | 10px | 12px | 16px | **20px** | **24px** |
389
+ | `text-body` | 10px | 11px | 13px | **15px** | **17px** |
390
+ | `pad-row` | 2 × 6px | 4 × 8px | 6 × 12px | **8 × 16px** | **10 × 20px** |
391
+ | `chrome-toolbar` | 32px | 36px | 44px | **52px** | **60px** |
392
+ | `--cue-density` | 0.85 | 1 | 1.3 | **1.6** | **1.9** |
393
+
394
+ `large` is a touch and presentation rung: 40px controls clear the WCAG 2.2
395
+ SC 2.5.8 target floor with room to spare. `ultra-large` is for a wall display, a
396
+ kiosk, a stage monitor read from two metres, and for a low-vision reader who
397
+ wants the whole interface a size up rather than the browser's zoom.
398
+
399
+ The `@media (pointer: coarse)` re-raise still applies to `ultra-compact` alone,
400
+ and still raises it to exactly the same heights it always did — `compact`'s.
401
+ `compact` is the rung the raise lands on, so raising it too would mean promoting
402
+ it to `normal` and moving today's default geometry on every touch device.
403
+
404
+ ## The type ladder got a top
405
+
406
+ `text-title` and `text-emphasis` are bigger at every rung. `text-micro`,
407
+ `text-label`, `text-ui` and `text-body` are untouched — consoles are built out
408
+ of those four and none of them moves.
409
+
410
+ | | ultra-compact | compact | normal | large | ultra-large |
411
+ | --------------- | ------------- | ------------- | ------------- | -------- | ----------- |
412
+ | `text-emphasis` | 11 → **13px** | 12 → **14px** | 14 → **17px** | **20px** | **23px** |
413
+ | `text-title` | 12 → **16px** | 13 → **18px** | 16 → **22px** | **26px** | **30px** |
414
+
415
+ A page heading was 1.18× a paragraph, which is not a hierarchy — it is six sizes
416
+ within four points of each other, and every screen built on it came out flat. It
417
+ is now 1.6–1.76×, and the whole ladder spans 2× to 2.7× from `micro` to `title`
418
+ depending on the rung. If you set a page title in `text-title` it will look like
419
+ one now; if you were compensating with a hand-written size, delete the
420
+ compensation.
421
+
422
+ ## Also
423
+
424
+ `prepaintScript()` takes a third argument, `defaultDensity`, alongside
425
+ `defaultTheme`. An app whose provider names a level other than `compact` should
426
+ pass the same level here, or the first frame paints at one rung and every frame
427
+ after it at another:
428
+
429
+ ```tsx
430
+ prepaintScript(DEFAULT_STORAGE_KEY, "cue", "normal");
431
+ ```
432
+
433
+ - a382b68: A ninth theme preset, `quotamate`, with a light pair.
434
+
435
+ `THEMES` gains `"quotamate"` and `ThemeName` widens with it, so a consumer can write
436
+ `theme="quotamate"` without a cast. `dist/themes/quotamate.css` is built alongside the other
437
+ eight, and `THEME_PRESETS.quotamate` is available to `createTheme()` and the configurator.
438
+
439
+ ```tsx
440
+ <ThemeProvider theme="quotamate" density="ultra-compact" mode="dark">
441
+ ```
442
+
443
+ A blue-black ramp at hue 240 under a cyan accent (`#00e5e5`). Not a new design — quotamate is
444
+ a shipping product whose palette was already fixed in a private stylesheet, so the values are
445
+ the same colours in hex that it authored in HSL. Adopting the preset is a no-op for the
446
+ running product rather than a restyle, which is the only reason it can be adopted at all.
447
+
448
+ **Its status hues are deliberately not the accent**, which is where this preset differs from
449
+ `cue`. quotamate's whole job is to say whether an account is usable right now, so `ok`, `warn`
450
+ and `danger` have to stay separable at a glance from the colour that means "interactive" — a
451
+ dashboard where "healthy" and "clickable" are the same green cannot be read quickly.
452
+
453
+ Light drops the accent to a deepened teal (`#0d7d7d`) rather than the near-black the product
454
+ itself used. `#00e5e5` on `#fcfcfc` fails contrast for text and for a hairline rim alike, so
455
+ the product's instinct was right; an accent that is merely dark, though, loses the brand.
456
+ Same hue, enough chroma to read as the product's colour, dark enough to carry white text on a
457
+ filled control.
458
+
459
+ Two tests encoded "eight presets" and were corrected rather than bumped:
460
+
461
+ - `build.test.mjs` listed the theme names, which is the point of that assertion.
462
+ - `disjoint.test.mjs` asserted `sources === 16` as a stand-in for "each preset has a dark and
463
+ a light source". A count is a poor proxy — eight darks and eight lights is 16, and so is
464
+ nine darks and seven lights — and it failed a geometry test for a reason unrelated to
465
+ geometry. It now asserts the pairing directly and will not go stale on the tenth preset.
466
+
467
+ - 236d09b: The bars: `AppBar`, `Footer`, and one overflow behaviour for every strip that can
468
+ outgrow its box.
469
+
470
+ ### One overflow behaviour, not three bespoke fixes
471
+
472
+ `Toolbar` had neither wrap nor scroll and its buttons are `shrink-0
473
+ whitespace-nowrap`, so a bar wider than its container ran off the edge with no
474
+ way to reach it. `SegmentedControl` did the same with five segments in a page
475
+ header. Both now scroll, from one module, with the affordance
476
+ `ScrollableTabsList` has shipped since the tab strip was written: a fade mask at
477
+ whichever edge still hides something, and a chevron there — because what sits at
478
+ an overflowing edge is usually the gap _between_ two controls, and fading empty
479
+ space produces nothing anyone can see.
480
+
481
+ ```tsx
482
+ <Toolbar.Root aria-label="Playback" /> // scrolls by default
483
+ <Toolbar.Root aria-label="Playback" overflow="clip" /> // the old behaviour
484
+ <SegmentedControl aria-label="View" items={items} overflow="clip" />
485
+ ```
486
+
487
+ Not wrapping: every bar here is one rung of the chrome ladder tall and sits in a
488
+ layout that has already subtracted that height, so a bar that quietly becomes
489
+ two rows steals it from the work area. Not a "more" menu: `Toolbar` takes
490
+ arbitrary children and there is no honest conversion from one into a menu item,
491
+ so it would need a parallel data model, a measuring pass on every resize, and it
492
+ would lift the surplus controls out of Base UI's roving-focus group. A bar whose
493
+ controls fit renders exactly as it did before — no mask, no chevrons, no
494
+ compositing layer.
495
+
496
+ `AppBar.Nav` and `ScrollableTabsList` use the same module, so the library has one
497
+ implementation of this and four consumers.
498
+
499
+ ### `AppBar` — the horizontal bar
500
+
501
+ ```tsx
502
+ <AppBar.Root>
503
+ <AppBar.Brand render={<NextLink href="/" />}>
504
+ <Eyebrow>@cueplusplus/ui</Eyebrow>
505
+ <Chip tone="accent" variant="outline">
506
+ 0.1.0
507
+ </Chip>
508
+ </AppBar.Brand>
509
+
510
+ <AppBar.Nav aria-label="Sections">
511
+ <AppBar.Link render={<NextLink href="/docs" />}>
512
+ Getting started
513
+ </AppBar.Link>
514
+ <AppBar.Separator />
515
+ <AppBar.Link render={<NextLink href="/gallery" />} register="strong">
516
+ Gallery
517
+ </AppBar.Link>
518
+ <AppBar.Link
519
+ external
520
+ render={<a href="https://skills.cueplusplus.com" />}
521
+ >
522
+ Skills
523
+ </AppBar.Link>
524
+ </AppBar.Nav>
525
+
526
+ <AppBar.Actions>
527
+ <ThemePicker />
528
+ </AppBar.Actions>
529
+ </AppBar.Root>
530
+ ```
531
+
532
+ Sticky, `--cue-chrome-toolbar` tall, brand and actions `shrink-0` with the
533
+ navigation between them giving up the width. `AppBar.Link` is set in one of two
534
+ registers — `muted` is furniture, `strong` is a destination — and `active` is a
535
+ third thing rather than a louder register: accent ink _and_ `aria-current="page"`.
536
+
537
+ This is a **bar**, not a menu: `NavigationMenu` goes inside `AppBar.Nav` when a
538
+ section has children. It is also not `TitleBar`, which is window furniture.
539
+
540
+ **It adds no viewport breakpoint.** `AppShell` still holds the library's only
541
+ one, for navigation shape. A horizontal bar never faces that question: at 390px
542
+ it is the same bar with a shorter window onto the same links.
543
+
544
+ `app-bar.tsx` carries no `"use client"` directive, so the bar renders from a
545
+ server component — which a site header has to, because that is where a framework
546
+ reads its data. The client boundary is around the navigation's scroller alone.
547
+
548
+ ### `Footer` — the landmark, the hairline, the measure
549
+
550
+ ```tsx
551
+ <Footer
552
+ meta={
553
+ <>
554
+ <span>© 2026 CUE++</span>
555
+ <Link href="/legal">Legal</Link>
556
+ </>
557
+ }
558
+ >
559
+ <Grid minItemWidth="12rem" gap={5}>
560
+ <Stack gap={2}>
561
+ <Eyebrow>Docs</Eyebrow>
562
+ <Link href="/docs">Getting started</Link>
563
+ </Stack>
564
+ </Grid>
565
+ </Footer>
566
+ ```
567
+
568
+ The `contentinfo` landmark, a full-bleed hairline, a centred column on the same
569
+ four measures `Container` and `PageShell` offer (`broad` by default), and a
570
+ `meta` slot whose fine print hangs under a rule of its own.
571
+
572
+ Deliberately **not** a link-list component. A complex footer is `Grid` + `Stack`
573
+ - `Link` inside this one — components that already exist, already read the
574
+ density ladder, and already handle a column that is a paragraph rather than a
575
+ list. `Grid`'s `minItemWidth` collapses the columns on a phone with no breakpoint
576
+ and no prop for how many to draw. Static markup, no `"use client"`.
577
+
578
+ - 2c6aca1: `AppShell` and `Sidebar`: the four defects the shell's first independent consumer found, and the landmark it was announcing twice.
579
+
580
+ `AppShell` was drawn from the console specimens. The documentation site is the
581
+ first thing outside them to wear it, and putting a real 30-row navigation and a
582
+ few hundred visually-hidden labels through it turned up four things the
583
+ specimens never could. All four are fixed in the library rather than at the call
584
+ site, which is the whole point of a shell.
585
+
586
+ **Minor rather than major because the package is pre-1.0** — 0.x's breaking rung
587
+ is the minor one, and two of these changes are breaking. The migration is at the
588
+ bottom.
589
+
590
+ **`AppShell.Root` keeps its own `documentScrolls: false` promise.** The frame is
591
+ now `relative overflow-clip`. The flex arithmetic it already had only governs
592
+ boxes in the flow; an absolutely positioned descendant is laid out against its
593
+ containing block, and a frame that is neither positioned nor clipping is not
594
+ one — so the _initial_ containing block was, and the descendant's scrollable
595
+ overflow landed on `<html>`. `.sr-only` is `position: absolute`, so this was an
596
+ everyday case rather than an exotic one: a page carrying 308 hidden labels
597
+ measured a 7,068px document inside a 900px frame with every visible box on
598
+ screen, and a browser scrollbar that scrolled nothing. `clip` rather than
599
+ `hidden`, so the frame is not a scroll container something can shove sideways
600
+ with no scrollbar to put it back. The emitters are fixed too — `StatusDot`,
601
+ `OTPField`, `Message`, `AskBox` and `Sidebar.Item` now position the box their
602
+ hidden label is laid out against, so the leak stops at source as well as at the
603
+ frame.
604
+
605
+ **One navigation, one landmark.** `Sidebar.Root` rendered `<aside>` while
606
+ `AppShell.Sidebar`'s drawer half rendered `<nav>`, so the same navigation
607
+ announced as two different landmarks depending on the viewport — and a call site
608
+ whose column is the site's primary navigation had to hand-patch
609
+ `role="navigation"` over the part. Both halves now take one `landmark` prop:
610
+
611
+ ```tsx
612
+ <AppShell.Sidebar aria-label="Console">…</AppShell.Sidebar> {/* <nav>, both shapes */}
613
+ <Sidebar.Root aria-label="Filters" landmark="complementary">…</Sidebar.Root> {/* <aside> */}
614
+ ```
615
+
616
+ `"navigation"` is the default, because a column of `Sidebar.Item`s with one of
617
+ them marked `aria-current="page"` is primary navigation and not complementary.
618
+
619
+ **The column scrolls, and the rail does not scroll with it.** `Sidebar.Root` had
620
+ no scroller at all, so a navigation taller than the frame simply lost its last
621
+ rows; the fix is an inner scroller rather than `overflow-y-auto` on the root,
622
+ because `Sidebar.Rail` is `absolute inset-y-0` and would otherwise slide away
623
+ with the third screenful. Its containing block is the root and the scroller is
624
+ the element inside it, so the rail spans the whole column and holds its edge
625
+ however far the sections are scrolled. Measured: a 828px column of navigation in
626
+ a 318px frame, scrolled 400px, rail unmoved and unclipped.
627
+
628
+ **`AppShell.NavTrigger` is a target a finger can hit.** It defaulted to
629
+ `size="sm"` — 20px at normal density — on a control that renders _only_ below
630
+ the `md` breakpoint, which is to say only on a touch screen, under the 24×24
631
+ floor WCAG 2.2 SC 2.5.8 sets. The default is `size="md"` now: 24px at normal and
632
+ large, and 24px at ultra-compact too, where the token layer's
633
+ `@media (pointer: coarse)` rule already lifts the control ladder. It is also
634
+ `shrink-0`, because every other slot in `AppBar` is and this was the one that
635
+ gave — measured at 14px wide in a crowded 390px bar.
636
+
637
+ `Footer` gained no code, but its guidance was wrong in a way that cost a site its
638
+ footer: it listed "inside `AppShell`" under _when not to use_. Inside a shell a
639
+ footer belongs to the content scroller, at the end of the work area — bounded by
640
+ the content column, scrolling with the page. What does not belong is a footer as
641
+ a sibling of the navigation column. `Footer` and `StatusBar` are different
642
+ objects and a shell can carry both.
643
+
644
+ ### Migrating
645
+ - **`Sidebar.Root` renders `<nav>`.** A stylesheet or a test selecting
646
+ `aside[data-slot="sidebar"]` needs `[data-slot="sidebar"]`, and a column that
647
+ really is complementary needs `landmark="complementary"`. A call site passing
648
+ `role="navigation"` to work around the old element can drop it.
649
+ - **`Sidebar.Root` has one more element inside it.** Its children are wrapped in
650
+ `[data-slot="sidebar-scroller"]`, which now carries the column's padding and
651
+ gap. A `> *` selector aimed at the sections needs re-aiming; `overflow-y-auto`
652
+ passed in at the call site can go.
653
+ - **`AppShell.NavTrigger` is 4px bigger.** Pass `size="sm"` back if a bar really
654
+ needs the old height, and read WCAG 2.5.8 first.
655
+
656
+ ### Patch Changes
657
+
658
+ - 6ce0c7d: The release notes now ship inside the package.
659
+
660
+ `files` was `dist` alone, so the `CHANGELOG.md` this repository writes on every
661
+ release stayed in a private git repository and reached nobody: `npm pack` left it
662
+ out, and the tarball a consumer installs from GitHub Packages carried the code
663
+ with no record of what had changed in it. Anyone asking "what moved between the
664
+ version I have and the version I am upgrading to" had to have access to the
665
+ source repository to find out.
666
+
667
+ `CHANGELOG.md` is now on the `files` allowlist of all three published packages,
668
+ so it lands in `node_modules/@cueplusplus/<package>/CHANGELOG.md` beside the code
669
+ it describes. `packages/release` has the test that keeps it there.
670
+
671
+ No code changes and no API changes — the same `dist`, plus one file.
672
+
673
+ The same notes are published, alongside the CUE++ agent skills' own, at
674
+ <https://skills.cueplusplus.com/releases>.
675
+
676
+ - Updated dependencies [33a95c4]
677
+ - Updated dependencies [b86f482]
678
+ - Updated dependencies [a382b68]
679
+ - Updated dependencies [6ce0c7d]
680
+ - @cueplusplus/tokens@0.2.0
681
+
682
+ ## 0.1.0
683
+
684
+ ### Minor Changes
685
+
686
+ - First release of the CUE++ design system.
687
+
688
+ `@cueplusplus/tokens` ships eight theme presets (`cue`, `terminal`, `signal`, `venu`, `hivehub`,
689
+ `dusk`, `luma`, `snuffle`) in dark and light, three density levels (`ultra-compact`, `normal`,
690
+ `large`), and the Tailwind v4 `@theme inline` mapping — colour scoped to `[data-theme]`, geometry to
691
+ `[data-density]`, never mixed.
692
+
693
+ `@cueplusplus/ui` ships 146 components on Base UI: the core entry plus the `/layout`, `/forms`,
694
+ `/overlays`, `/chrome`, `/instruments`, `/chat`, `/theming`, `/configurator`, `/color`, `/date`
695
+ subpaths and the four opt-in ones (`/charts`, `/dmx`, `/midi`, `/flow`) whose heavy dependencies stay
696
+ optional peers. `ThemeProvider`, the density islands, `createTheme()` with its contrast report and the
697
+ floating `ThemeConfigurator` come with it.
698
+
699
+ `@cueplusplus/brand-tokens` ships the CUE++ brand layer — the white-alpha ramp, the mono stack, the
700
+ eyebrow and motion treatments, and the wordmark and Plussie marks.
701
+
702
+ ### Patch Changes
703
+
704
+ - Updated dependencies
705
+ - @cueplusplus/tokens@0.1.0