bitboss-ui 3.0.0-beta.21 → 3.0.0-beta.22

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 (183) hide show
  1. package/README.md +55 -3
  2. package/bin/bitboss-ui-mcp.mjs +419 -9
  3. package/bin/bitboss-ui.mjs +293 -22
  4. package/dist/ai/BbAccordion.md +21 -23
  5. package/dist/ai/BbAlert.md +6 -12
  6. package/dist/ai/BbAvatar.md +60 -24
  7. package/dist/ai/BbBadge.md +12 -20
  8. package/dist/ai/BbBaseButton.md +14 -16
  9. package/dist/ai/BbBaseCheckboxIcon.md +6 -10
  10. package/dist/ai/BbBaseRadioIcon.md +6 -10
  11. package/dist/ai/BbBaseSwitchIcon.md +5 -9
  12. package/dist/ai/BbBreadcrumbs.md +23 -34
  13. package/dist/ai/BbButton.md +35 -47
  14. package/dist/ai/BbCheckbox.md +21 -37
  15. package/dist/ai/BbCheckboxGroup.md +13 -13
  16. package/dist/ai/BbCollapsible.md +14 -26
  17. package/dist/ai/BbColorInput.md +13 -23
  18. package/dist/ai/BbColorPalette.md +23 -35
  19. package/dist/ai/BbConfirm.md +17 -32
  20. package/dist/ai/BbDatePickerInput.md +15 -21
  21. package/dist/ai/BbDialog.md +159 -62
  22. package/dist/ai/BbDropdown.md +21 -25
  23. package/dist/ai/BbDropdownButton.md +13 -30
  24. package/dist/ai/BbDropzone.md +9 -11
  25. package/dist/ai/BbIcon.md +44 -33
  26. package/dist/ai/BbIndicator.md +2 -2
  27. package/dist/ai/BbNumberInput.md +18 -20
  28. package/dist/ai/BbOffCanvas.md +42 -42
  29. package/dist/ai/BbPagination.md +21 -23
  30. package/dist/ai/BbPopover.md +15 -17
  31. package/dist/ai/BbProgress.md +40 -51
  32. package/dist/ai/BbRadio.md +9 -9
  33. package/dist/ai/BbRadioGroup.md +7 -11
  34. package/dist/ai/BbRating.md +8 -12
  35. package/dist/ai/BbSelect.md +32 -36
  36. package/dist/ai/BbSelectPopover.md +19 -31
  37. package/dist/ai/BbSlider.md +15 -19
  38. package/dist/ai/BbSmoothHeight.md +16 -31
  39. package/dist/ai/BbSpinner.md +118 -74
  40. package/dist/ai/BbSwitch.md +25 -18
  41. package/dist/ai/BbSwitchGroup.md +9 -14
  42. package/dist/ai/BbTable.md +102 -55
  43. package/dist/ai/BbTabs.md +59 -82
  44. package/dist/ai/BbTag.md +12 -23
  45. package/dist/ai/BbTextInput.md +20 -26
  46. package/dist/ai/BbTextarea.md +28 -34
  47. package/dist/ai/BbToast.md +14 -34
  48. package/dist/ai/BbTooltip.md +22 -20
  49. package/dist/ai/BbTree.md +46 -72
  50. package/dist/ai/changelog.json +169 -62
  51. package/dist/ai/components.json +1467 -9
  52. package/dist/ai/composables/useConfirm.md +5 -2
  53. package/dist/ai/composables/useToast.md +4 -2
  54. package/dist/ai/guides/agent-contract.md +7 -4
  55. package/dist/ai/guides/ai-router.md +37 -22
  56. package/dist/ai/guides/component-picker.md +23 -18
  57. package/dist/ai/guides/design-language.md +141 -13
  58. package/dist/ai/guides/design-tokens.md +29 -4
  59. package/dist/ai/guides/icons-policy.md +46 -21
  60. package/dist/ai/guides/installation-and-plugin-setup.md +253 -17
  61. package/dist/ai/guides/migration/components/bb-rating.md +26 -1
  62. package/dist/ai/guides/migration/components/bb-tooltip.md +18 -0
  63. package/dist/ai/guides/migration/v2-to-v3.md +50 -23
  64. package/dist/ai/index.md +1 -1
  65. package/dist/ai/recipes/inertia/approvals-inbox.md +3 -3
  66. package/dist/ai/recipes/inertia/inline-edit-workspace.md +2 -2
  67. package/dist/ai/recipes/inertia/onboarding.md +2 -2
  68. package/dist/ai/recipes/inertia/ownership-atlas.md +6 -6
  69. package/dist/ai/recipes/inertia/record-form.md +5 -5
  70. package/dist/ai/recipes/inertia/records-workspace.md +4 -4
  71. package/dist/ai/recipes/inertia/upload-center.md +6 -6
  72. package/dist/ai/recipes/inertia/wizard-form.md +5 -5
  73. package/dist/ai/recipes/nuxt/approvals-inbox.md +3 -3
  74. package/dist/ai/recipes/nuxt/inline-edit-workspace.md +2 -2
  75. package/dist/ai/recipes/nuxt/onboarding.md +2 -2
  76. package/dist/ai/recipes/nuxt/record-form.md +5 -5
  77. package/dist/ai/recipes/nuxt/records-workspace.md +4 -4
  78. package/dist/ai/recipes/nuxt/upload-center.md +6 -6
  79. package/dist/ai/recipes/nuxt/wizard-form.md +5 -5
  80. package/dist/ai/recipes/vue/approvals-inbox.md +3 -3
  81. package/dist/ai/recipes/vue/inline-edit-workspace.md +2 -2
  82. package/dist/ai/recipes/vue/onboarding.md +2 -2
  83. package/dist/ai/recipes/vue/record-form.md +10 -10
  84. package/dist/ai/recipes/vue/records-workspace.md +4 -4
  85. package/dist/ai/recipes/vue/upload-center.md +6 -6
  86. package/dist/ai/recipes/vue/wizard-form.md +5 -5
  87. package/dist/ai/source/BbBadge.md +1 -1
  88. package/dist/ai/source/BbBaseCheckbox.md +1 -1
  89. package/dist/ai/source/BbBaseDatePicker.md +5 -5
  90. package/dist/ai/source/BbBaseDatePickerInput.md +2 -2
  91. package/dist/ai/source/BbBaseRadio.md +1 -1
  92. package/dist/ai/source/BbBaseRating.md +5 -5
  93. package/dist/ai/source/BbBaseSelect.md +1 -1
  94. package/dist/ai/source/BbBaseSlider.md +5 -5
  95. package/dist/ai/source/BbBaseSwitch.md +1 -1
  96. package/dist/ai/source/BbBaseTimePickerInput.md +1 -1
  97. package/dist/ai/source/BbBreadcrumbs.md +20 -1
  98. package/dist/ai/source/BbButton.md +2 -2
  99. package/dist/ai/source/BbDialog.md +39 -8
  100. package/dist/ai/source/BbDropdown.md +1 -1
  101. package/dist/ai/source/BbDropzone.md +5 -5
  102. package/dist/ai/source/BbIcon.md +23 -10
  103. package/dist/ai/source/BbOffCanvas.md +50 -28
  104. package/dist/ai/source/BbPagination.md +2 -2
  105. package/dist/ai/source/BbPopover.md +12 -1
  106. package/dist/ai/source/BbSelectPopover.md +45 -7
  107. package/dist/ai/source/BbSpinner.md +2 -2
  108. package/dist/ai/source/BbTable.md +11 -11
  109. package/dist/ai/source/BbTooltip.md +57 -10
  110. package/dist/ai/source/ChipsBox.md +1 -1
  111. package/dist/ai/source/CommaBox.md +1 -1
  112. package/dist/ai/source/GuidesComponent.md +14 -7
  113. package/dist/ai/source/OptionsContainer.md +1 -1
  114. package/dist/components/BbBadge/BadgeBodyContent.vue_vue_type_script_setup_true_lang.js +1 -1
  115. package/dist/components/BbBadge/BbBadge.vue_vue_type_script_setup_true_lang.js +1 -1
  116. package/dist/components/BbBaseCheckbox/BbBaseCheckbox.vue_vue_type_script_setup_true_lang.js +1 -1
  117. package/dist/components/BbBaseDatePicker/BbBaseDatePicker.vue_vue_type_script_setup_true_lang.js +4 -4
  118. package/dist/components/BbBaseDatePicker/BbBaseDatePickerInputDaySelector.vue_vue_type_script_setup_true_lang.js +1 -1
  119. package/dist/components/BbBaseDatePickerInput/BbBaseDatePickerInput.vue_vue_type_script_setup_true_lang.js +1 -1
  120. package/dist/components/BbBaseInputContainer/BbBaseInputContainer.vue.d.ts +1 -1
  121. package/dist/components/BbBaseRadio/BbBaseRadio.vue_vue_type_script_setup_true_lang.js +1 -1
  122. package/dist/components/BbBaseRating/BbBaseRating.vue_vue_type_script_setup_true_lang.js +3 -3
  123. package/dist/components/BbBaseSelect/BbBaseSelect.vue_vue_type_script_setup_true_lang.js +1 -1
  124. package/dist/components/BbBaseSlider/BbBaseSlider.vue_vue_type_script_setup_true_lang.js +3 -3
  125. package/dist/components/BbBaseSwitch/BbBaseSwitch.vue_vue_type_script_setup_true_lang.js +1 -1
  126. package/dist/components/BbBaseTimePickerInput/BbBaseTimePickerInput.vue_vue_type_script_setup_true_lang.js +1 -1
  127. package/dist/components/BbBreadcrumbs/BbBreadcrumbs.vue_vue_type_script_setup_true_lang.js +71 -71
  128. package/dist/components/BbButton/BbButton.vue_vue_type_script_setup_true_lang.js +2 -2
  129. package/dist/components/BbDialog/BbDialog.vue_vue_type_script_setup_true_lang.js +102 -97
  130. package/dist/components/BbDropdown/AdaptiveDropdown.vue_vue_type_script_setup_true_lang.js +1 -1
  131. package/dist/components/BbDropdown/BbDropdown.vue_vue_type_script_setup_true_lang.js +58 -58
  132. package/dist/components/BbDropzone/BbDropzone.vue_vue_type_script_setup_true_lang.js +2 -2
  133. package/dist/components/BbIcon/BbIcon.vue_vue_type_script_setup_true_lang.js +33 -35
  134. package/dist/components/BbIcon/iconCache.d.ts +30 -0
  135. package/dist/components/BbIcon/iconCache.js +21 -3
  136. package/dist/components/BbOffCanvas/BbOffCanvas.vue_vue_type_script_setup_true_lang.js +57 -56
  137. package/dist/components/BbPagination/BbPagination.vue_vue_type_script_setup_true_lang.js +2 -2
  138. package/dist/components/BbPopover/BbPopover.vue_vue_type_script_setup_true_lang.js +138 -138
  139. package/dist/components/BbSelectPopover/BbSelectPopover.vue_vue_type_script_setup_true_lang.js +43 -43
  140. package/dist/components/BbSpinner/BbSpinner.vue_vue_type_script_setup_true_lang.js +1 -1
  141. package/dist/components/BbSpinner/types.d.ts +1 -1
  142. package/dist/components/BbTable/BbTable.vue_vue_type_script_setup_true_lang.js +8 -8
  143. package/dist/components/BbTable/BbTableDataRow.js +2 -2
  144. package/dist/components/BbToast/BbToastRegion.vue_vue_type_script_setup_true_lang.js +62 -62
  145. package/dist/components/BbTooltip/BbTooltip.vue_vue_type_script_setup_true_lang.js +81 -78
  146. package/dist/components/BbTooltip/types.d.ts +8 -1
  147. package/dist/components/ChipsBox/ChipsBox.vue_vue_type_script_setup_true_lang.js +1 -1
  148. package/dist/components/CommaBox/CommaBox.vue_vue_type_script_setup_true_lang.js +1 -1
  149. package/dist/components/OptionsContainer/OptionsContainer.vue_vue_type_script_setup_true_lang.js +1 -1
  150. package/dist/composables/useConfirm.d.ts +22 -0
  151. package/dist/composables/useConfirm.js +43 -40
  152. package/dist/composables/useSafeAreaInternal.js +1 -1
  153. package/dist/composables/useToast.d.ts +16 -0
  154. package/dist/composables/useToast.js +20 -16
  155. package/dist/composables/useViewportWidth.d.ts +20 -6
  156. package/dist/composables/useViewportWidth.js +8 -7
  157. package/dist/icon-scan.d.ts +276 -0
  158. package/dist/icon-scan.js +485 -0
  159. package/dist/icons-whitelist.d.ts +5 -4
  160. package/dist/llms-full.txt +1979 -1527
  161. package/dist/llms-medium.txt +461 -74
  162. package/dist/llms.txt +1 -1
  163. package/dist/nuxt.js +10 -7
  164. package/dist/plugin.js +1 -0
  165. package/dist/runtime/nuxt-plugin.js +2 -1
  166. package/dist/styles.css +1 -1
  167. package/dist/types/Config.d.ts +18 -0
  168. package/dist/utils/cssLayers.d.ts +91 -0
  169. package/dist/utils/cssLayers.js +43 -0
  170. package/dist/utils/injectLibraryStyles.d.ts +3 -1
  171. package/dist/utils/injectLibraryStyles.js +24 -23
  172. package/dist/vite-plugin.d.ts +74 -11
  173. package/dist/vite.js +292 -253
  174. package/llms.txt +1 -1
  175. package/package.json +7 -5
  176. package/scripts/lib/ensure-manifest.mjs +28 -5
  177. package/scripts/lib/eslint-plugin.d.ts +35 -0
  178. package/scripts/lib/eslint-plugin.mjs +299 -3
  179. package/scripts/lib/hand-roll-hints.mjs +50 -6
  180. package/scripts/lib/html-attributes.mjs +42 -0
  181. package/scripts/lib/mcp-config.mjs +38 -34
  182. package/scripts/lib/public-type-exports.mjs +246 -0
  183. package/scripts/lib/validate-bb-markup.mjs +205 -12
package/dist/ai/BbTabs.md CHANGED
@@ -45,12 +45,10 @@ in one component.
45
45
 
46
46
  ```vue
47
47
  <template>
48
- <div
49
- class="max-w-md rounded-[var(--bb-radius)] border border-[color:var(--bb-border)] p-3"
50
- >
48
+ <div class="max-w-md rounded-(--bb-radius) border border-(--bb-border) p-3">
51
49
  <div class="mb-3 flex flex-col gap-0.5">
52
50
  <p class="text-sm font-medium">Acme Checkout</p>
53
- <p class="text-xs text-[color:var(--bb-text-muted)]">
51
+ <p class="text-xs text-(--bb-text-muted)">
54
52
  Project · last deploy 14m ago
55
53
  </p>
56
54
  </div>
@@ -58,34 +56,34 @@ in one component.
58
56
  <template #overview>
59
57
  <div class="grid gap-1.5 pt-3 text-sm">
60
58
  <p class="font-medium">Health: stable</p>
61
- <p class="text-xs text-[color:var(--bb-text-muted)]">
59
+ <p class="text-xs text-(--bb-text-muted)">
62
60
  Error rate 0.12% · p95 180ms · 3 open incidents
63
61
  </p>
64
62
  </div>
65
63
  </template>
66
64
  <template #activity>
67
- <ul class="divide-y divide-[color:var(--bb-border)] pt-3">
65
+ <ul class="divide-y divide-(--bb-border) pt-3">
68
66
  <li
69
67
  v-for="event in activity"
70
68
  :key="event.id"
71
69
  class="flex flex-col gap-0.5 py-2"
72
70
  >
73
71
  <p class="text-sm">{{ event.text }}</p>
74
- <p class="text-xs text-[color:var(--bb-text-muted)]">
72
+ <p class="text-xs text-(--bb-text-muted)">
75
73
  {{ event.when }}
76
74
  </p>
77
75
  </li>
78
76
  </ul>
79
77
  </template>
80
78
  <template #members>
81
- <ul class="divide-y divide-[color:var(--bb-border)] pt-3">
79
+ <ul class="divide-y divide-(--bb-border) pt-3">
82
80
  <li
83
81
  v-for="member in members"
84
82
  :key="member.email"
85
83
  class="flex items-center justify-between gap-2 py-2 text-sm"
86
84
  >
87
85
  <span class="truncate">{{ member.name }}</span>
88
- <span class="shrink-0 text-xs text-[color:var(--bb-text-muted)]">{{
86
+ <span class="shrink-0 text-xs text-(--bb-text-muted)">{{
89
87
  member.role
90
88
  }}</span>
91
89
  </li>
@@ -136,9 +134,7 @@ dynamic-name slot instead of writing one block per key:
136
134
  **Dynamic pane slots from generated items**
137
135
 
138
136
  ```vue
139
- <div
140
- class="max-w-md rounded-[var(--bb-radius)] border border-[color:var(--bb-border)] p-3"
141
- >
137
+ <div class="max-w-md rounded-(--bb-radius) border border-(--bb-border) p-3">
142
138
  <BbTabs
143
139
  compact
144
140
  :items="[
@@ -152,7 +148,7 @@ dynamic-name slot instead of writing one block per key:
152
148
  :key="stage"
153
149
  #[stage]
154
150
  >
155
- <p class="pt-3 text-sm capitalize text-[color:var(--bb-text-muted)]">{{ stage }} documents.</p>
151
+ <p class="pt-3 text-sm capitalize text-(--bb-text-muted)">{{ stage }} documents.</p>
156
152
  </template>
157
153
  </BbTabs>
158
154
  </div>
@@ -172,9 +168,7 @@ button or link inside a label — the trigger is already the control).
172
168
 
173
169
  ```vue
174
170
  <template>
175
- <div
176
- class="max-w-md rounded-[var(--bb-radius)] border border-[color:var(--bb-border)] p-3"
177
- >
171
+ <div class="max-w-md rounded-(--bb-radius) border border-(--bb-border) p-3">
178
172
  <BbTabs v-model="active" compact :items="tabs">
179
173
  <template #label:inbox="{ text }">
180
174
  <span class="inline-flex items-center gap-1.5">
@@ -183,26 +177,26 @@ button or link inside a label — the trigger is already the control).
183
177
  </span>
184
178
  </template>
185
179
  <template #inbox>
186
- <ul class="divide-y divide-[color:var(--bb-border)] pt-3">
180
+ <ul class="divide-y divide-(--bb-border) pt-3">
187
181
  <li
188
182
  v-for="thread in inbox"
189
183
  :key="thread.id"
190
184
  class="flex flex-col gap-0.5 py-2"
191
185
  >
192
186
  <p class="text-sm font-medium">{{ thread.subject }}</p>
193
- <p class="text-xs text-[color:var(--bb-text-muted)]">
187
+ <p class="text-xs text-(--bb-text-muted)">
194
188
  {{ thread.from }} · {{ thread.when }}
195
189
  </p>
196
190
  </li>
197
191
  </ul>
198
192
  </template>
199
193
  <template #sent>
200
- <p class="pt-3 text-sm text-[color:var(--bb-text-muted)]">
194
+ <p class="pt-3 text-sm text-(--bb-text-muted)">
201
195
  12 messages sent this week.
202
196
  </p>
203
197
  </template>
204
198
  <template #spam>
205
- <p class="pt-3 text-sm text-[color:var(--bb-text-muted)]">
199
+ <p class="pt-3 text-sm text-(--bb-text-muted)">
206
200
  3 filtered messages · last scan 2h ago.
207
201
  </p>
208
202
  </template>
@@ -290,12 +284,10 @@ the Audience and Schedule tabs:
290
284
 
291
285
  ```vue
292
286
  <template>
293
- <div
294
- class="max-w-md rounded-[var(--bb-radius)] border border-[color:var(--bb-border)] p-3"
295
- >
287
+ <div class="max-w-md rounded-(--bb-radius) border border-(--bb-border) p-3">
296
288
  <div class="mb-3 flex flex-col gap-0.5">
297
289
  <p class="text-sm font-medium">Product announcement</p>
298
- <p class="text-xs text-[color:var(--bb-text-muted)]">
290
+ <p class="text-xs text-(--bb-text-muted)">
299
291
  Draft · scheduled for Tue 09:00 local
300
292
  </p>
301
293
  </div>
@@ -320,7 +312,7 @@ the Audience and Schedule tabs:
320
312
  </div>
321
313
  </template>
322
314
  <template #audience>
323
- <p class="pt-3 text-sm text-[color:var(--bb-text-muted)]">
315
+ <p class="pt-3 text-sm text-(--bb-text-muted)">
324
316
  Sending to
325
317
  <span class="font-medium tabular-nums">{{
326
318
  recipients.toLocaleString()
@@ -329,7 +321,7 @@ the Audience and Schedule tabs:
329
321
  </p>
330
322
  </template>
331
323
  <template #schedule>
332
- <p class="pt-3 text-sm text-[color:var(--bb-text-muted)]">
324
+ <p class="pt-3 text-sm text-(--bb-text-muted)">
333
325
  Queued for Tuesday 09:00 in each recipient's local timezone.
334
326
  </p>
335
327
  </template>
@@ -379,12 +371,10 @@ nothing when you flip back:
379
371
 
380
372
  ```vue
381
373
  <template>
382
- <div
383
- class="max-w-md rounded-[var(--bb-radius)] border border-[color:var(--bb-border)] p-3"
384
- >
374
+ <div class="max-w-md rounded-(--bb-radius) border border-(--bb-border) p-3">
385
375
  <div class="mb-3 flex flex-col gap-0.5">
386
376
  <p class="text-sm font-medium">Release notes</p>
387
- <p class="text-xs text-[color:var(--bb-text-muted)]">
377
+ <p class="text-xs text-(--bb-text-muted)">
388
378
  Markdown draft · preview before publishing.
389
379
  </p>
390
380
  </div>
@@ -405,14 +395,12 @@ nothing when you flip back:
405
395
  </div>
406
396
  </template>
407
397
  <template #preview>
408
- <div class="grid gap-1.5 whitespace-pre-line pt-3 text-sm">
398
+ <div class="grid gap-1.5 pt-3 text-sm whitespace-pre-line">
409
399
  <template v-if="draft.trim()">
410
400
  <p class="font-medium">{{ previewTitle }}</p>
411
- <p class="text-[color:var(--bb-text-muted)]">{{ previewBody }}</p>
401
+ <p class="text-(--bb-text-muted)">{{ previewBody }}</p>
412
402
  </template>
413
- <p v-else class="text-[color:var(--bb-text-muted)]">
414
- Nothing to preview.
415
- </p>
403
+ <p v-else class="text-(--bb-text-muted)">Nothing to preview.</p>
416
404
  </div>
417
405
  </template>
418
406
  </BbTabs>
@@ -470,12 +458,10 @@ active section stays in the URL without flooding Back history:
470
458
 
471
459
  ```vue
472
460
  <template>
473
- <div
474
- class="max-w-md rounded-[var(--bb-radius)] border border-[color:var(--bb-border)] p-3"
475
- >
461
+ <div class="max-w-md rounded-(--bb-radius) border border-(--bb-border) p-3">
476
462
  <div class="mb-3 flex flex-col gap-0.5">
477
463
  <p class="text-sm font-medium">Workspace settings</p>
478
- <p class="text-xs text-[color:var(--bb-text-muted)]">
464
+ <p class="text-xs text-(--bb-text-muted)">
479
465
  Northwind Billing · changes save per section.
480
466
  </p>
481
467
  </div>
@@ -511,7 +497,7 @@ active section stays in the URL without flooding Back history:
511
497
  </div>
512
498
  </template>
513
499
  <template #members>
514
- <ul class="divide-y divide-[color:var(--bb-border)] pt-3">
500
+ <ul class="divide-y divide-(--bb-border) pt-3">
515
501
  <li
516
502
  v-for="member in members"
517
503
  :key="member.email"
@@ -519,11 +505,11 @@ active section stays in the URL without flooding Back history:
519
505
  >
520
506
  <span class="min-w-0 truncate">
521
507
  <span class="font-medium">{{ member.name }}</span>
522
- <span class="text-xs text-[color:var(--bb-text-muted)]">
508
+ <span class="text-xs text-(--bb-text-muted)">
523
509
  · {{ member.email }}</span
524
510
  >
525
511
  </span>
526
- <span class="shrink-0 text-xs text-[color:var(--bb-text-muted)]">{{
512
+ <span class="shrink-0 text-xs text-(--bb-text-muted)">{{
527
513
  member.role
528
514
  }}</span>
529
515
  </li>
@@ -532,7 +518,7 @@ active section stays in the URL without flooding Back history:
532
518
  <template #billing>
533
519
  <div class="grid gap-1.5 pt-3">
534
520
  <p class="text-sm font-medium">Pro · €49 / month</p>
535
- <p class="text-xs text-[color:var(--bb-text-muted)]">
521
+ <p class="text-xs text-(--bb-text-muted)">
536
522
  Next invoice Jul 28, 2026 · Visa ···· 4242
537
523
  </p>
538
524
  <div class="pt-1">
@@ -577,9 +563,7 @@ const onSaveGeneral = async () => {
577
563
  **Full-width strip with a disabled tab**
578
564
 
579
565
  ```vue
580
- <div
581
- class="max-w-md rounded-[var(--bb-radius)] border border-[color:var(--bb-border)] p-3"
582
- >
566
+ <div class="max-w-md rounded-(--bb-radius) border border-(--bb-border) p-3">
583
567
  <BbTabs
584
568
  block
585
569
  compact
@@ -589,9 +573,9 @@ const onSaveGeneral = async () => {
589
573
  { key: 'billing', label: 'Billing', disabled: true },
590
574
  ]"
591
575
  >
592
- <template #summary><p class="pt-3 text-sm text-[color:var(--bb-text-muted)]">Environment status at a glance.</p></template>
593
- <template #integrations><p class="pt-3 text-sm text-[color:var(--bb-text-muted)]">Connected services.</p></template>
594
- <template #billing><p class="pt-3 text-sm text-[color:var(--bb-text-muted)]">Locked on this plan.</p></template>
576
+ <template #summary><p class="pt-3 text-sm text-(--bb-text-muted)">Environment status at a glance.</p></template>
577
+ <template #integrations><p class="pt-3 text-sm text-(--bb-text-muted)">Connected services.</p></template>
578
+ <template #billing><p class="pt-3 text-sm text-(--bb-text-muted)">Locked on this plan.</p></template>
595
579
  </BbTabs>
596
580
  </div>
597
581
  ```
@@ -599,9 +583,7 @@ const onSaveGeneral = async () => {
599
583
  **Vertical, compact strip**
600
584
 
601
585
  ```vue
602
- <div
603
- class="max-w-md rounded-[var(--bb-radius)] border border-[color:var(--bb-border)] p-3"
604
- >
586
+ <div class="max-w-md rounded-(--bb-radius) border border-(--bb-border) p-3">
605
587
  <BbTabs
606
588
  compact
607
589
  direction="vertical"
@@ -611,9 +593,9 @@ const onSaveGeneral = async () => {
611
593
  { key: 'api', label: 'API keys' },
612
594
  ]"
613
595
  >
614
- <template #general><p class="px-3 text-sm text-[color:var(--bb-text-muted)]">Workspace basics.</p></template>
615
- <template #security><p class="px-3 text-sm text-[color:var(--bb-text-muted)]">Sessions and 2FA.</p></template>
616
- <template #api><p class="px-3 text-sm text-[color:var(--bb-text-muted)]">Personal access tokens.</p></template>
596
+ <template #general><p class="px-3 text-sm text-(--bb-text-muted)">Workspace basics.</p></template>
597
+ <template #security><p class="px-3 text-sm text-(--bb-text-muted)">Sessions and 2FA.</p></template>
598
+ <template #api><p class="px-3 text-sm text-(--bb-text-muted)">Personal access tokens.</p></template>
617
599
  </BbTabs>
618
600
  </div>
619
601
  ```
@@ -640,12 +622,10 @@ ends.
640
622
 
641
623
  ```vue
642
624
  <template>
643
- <div
644
- class="max-w-md rounded-[var(--bb-radius)] border border-[color:var(--bb-border)] p-3"
645
- >
625
+ <div class="max-w-md rounded-(--bb-radius) border border-(--bb-border) p-3">
646
626
  <div class="mb-3 flex flex-col gap-0.5">
647
627
  <p class="text-sm font-medium">Release timeline</p>
648
- <p class="text-xs text-[color:var(--bb-text-muted)]">
628
+ <p class="text-xs text-(--bb-text-muted)">
649
629
  Monthly notes · scroll arrows when the strip overflows.
650
630
  </p>
651
631
  </div>
@@ -674,17 +654,17 @@ ends.
674
654
  </template>
675
655
  <!--
676
656
  `slotKey(...)`, never the raw key. A pane's slot name is the
677
- NORMALIZED key, so `#[release.key]` only happens to work while the
678
- keys are already slug-safe (`v1`…`v9`). Give a release a realistic
679
- tag — `v3-1`, `2026-03` — and the raw key stops matching the slot
680
- name, and every pane silently renders empty.
657
+ NORMALIZED key: `v3.0` becomes `v3_0`, so `#[release.key]` would
658
+ name a slot that never matches and every pane would silently render
659
+ empty. The keys here carry a dot on purpose — with slug-safe keys
660
+ (`v1`…`v9`) the mistake is invisible.
681
661
  -->
682
662
  <template
683
663
  v-for="release in releases"
684
664
  :key="release.key"
685
665
  #[slotKey(release.key)]
686
666
  >
687
- <p class="pt-3 text-sm text-[color:var(--bb-text-muted)]">
667
+ <p class="pt-3 text-sm text-(--bb-text-muted)">
688
668
  {{ release.label }} shipped the design-token overhaul and the tabs
689
669
  keyboard-navigation pass.
690
670
  </p>
@@ -711,12 +691,14 @@ const months = [
711
691
  'August',
712
692
  'September',
713
693
  ];
694
+ // Realistic release tags: `v3.0` … `v3.8`. The dot is what makes the
695
+ // `slotKey` call in the template load-bearing (see the note there).
714
696
  const releases: BbTabsItem[] = months.map((label, index) => ({
715
- key: `v${index + 1}`,
716
- label: `${label} 2026`,
697
+ key: `v3.${index}`,
698
+ label: `${label} · v3.${index}`,
717
699
  }));
718
700
 
719
- const active = ref('v1');
701
+ const active = ref('v3.0');
720
702
  </script>
721
703
  ```
722
704
 
@@ -743,12 +725,10 @@ context; use nesting freely.
743
725
 
744
726
  ```vue
745
727
  <template>
746
- <div
747
- class="max-w-md rounded-[var(--bb-radius)] border border-[color:var(--bb-border)] p-3"
748
- >
728
+ <div class="max-w-md rounded-(--bb-radius) border border-(--bb-border) p-3">
749
729
  <div class="mb-3 flex flex-col gap-0.5">
750
730
  <p class="text-sm font-medium">Acme Checkout</p>
751
- <p class="text-xs text-[color:var(--bb-text-muted)]">
731
+ <p class="text-xs text-(--bb-text-muted)">
752
732
  Workspace · Prev/Next via root slot
753
733
  </p>
754
734
  </div>
@@ -775,21 +755,21 @@ context; use nesting freely.
775
755
  </BbButton>
776
756
  </div>
777
757
  </div>
778
- <hr class="my-3 border-[color:var(--bb-border)]" />
758
+ <hr class="my-3 border-(--bb-border)" />
779
759
  <BbTabsPanes>
780
760
  <template #overview>
781
- <p class="text-sm text-[color:var(--bb-text-muted)]">
761
+ <p class="text-sm text-(--bb-text-muted)">
782
762
  Health stable · owners Alex + Sam · objective: cut checkout
783
763
  latency 20%.
784
764
  </p>
785
765
  </template>
786
766
  <template #activity>
787
- <p class="text-sm text-[color:var(--bb-text-muted)]">
767
+ <p class="text-sm text-(--bb-text-muted)">
788
768
  Shipped billing retries; fixed avatar upload timeout.
789
769
  </p>
790
770
  </template>
791
771
  <template #members>
792
- <p class="text-sm text-[color:var(--bb-text-muted)]">
772
+ <p class="text-sm text-(--bb-text-muted)">
793
773
  14 editors, 23 viewers, 3 billing admins.
794
774
  </p>
795
775
  </template>
@@ -852,7 +832,7 @@ the tabs jumps straight to the Security section:
852
832
  ```vue
853
833
  <template>
854
834
  <div
855
- class="max-w-md space-y-3 rounded-[var(--bb-radius)] border border-[color:var(--bb-border)] p-3"
835
+ class="max-w-md space-y-3 rounded-(--bb-radius) border border-(--bb-border) p-3"
856
836
  >
857
837
  <div class="grid gap-2">
858
838
  <BbAlert
@@ -899,7 +879,7 @@ the tabs jumps straight to the Security section:
899
879
  <template #security>
900
880
  <div class="grid gap-1.5 pt-3 text-sm">
901
881
  <p class="font-medium">Two-factor authentication</p>
902
- <p class="text-xs text-[color:var(--bb-text-muted)]">
882
+ <p class="text-xs text-(--bb-text-muted)">
903
883
  Off · last password change Mar 12, 2026 · 2 active sessions
904
884
  </p>
905
885
  <div class="pt-1">
@@ -910,15 +890,12 @@ the tabs jumps straight to the Security section:
910
890
  </div>
911
891
  </template>
912
892
  <template #notifications>
913
- <p class="pt-3 text-sm text-[color:var(--bb-text-muted)]">
893
+ <p class="pt-3 text-sm text-(--bb-text-muted)">
914
894
  Email digests and mention alerts for alex@northwind.io.
915
895
  </p>
916
896
  </template>
917
897
  </BbTabs>
918
- <p
919
- class="text-xs text-[color:var(--bb-text-muted)]"
920
- data-test="active-section"
921
- >
898
+ <p class="text-xs text-(--bb-text-muted)" data-test="active-section">
922
899
  Active section: {{ current }}
923
900
  </p>
924
901
  </div>
package/dist/ai/BbTag.md CHANGED
@@ -55,12 +55,10 @@ for the next.
55
55
 
56
56
  ```vue
57
57
  <template>
58
- <div
59
- class="flex max-w-md flex-col gap-2 rounded-[var(--bb-radius)] border p-3"
60
- >
58
+ <div class="flex max-w-md flex-col gap-2 rounded-(--bb-radius) border p-3">
61
59
  <div class="flex flex-col gap-0.5">
62
60
  <span class="text-sm font-medium">Profile · Skills</span>
63
- <span class="text-xs text-[color:var(--bb-text-muted)]">
61
+ <span class="text-xs text-(--bb-text-muted)">
64
62
  Shown on your public profile and in search
65
63
  </span>
66
64
  </div>
@@ -74,7 +72,7 @@ for the next.
74
72
  persistent-hint
75
73
  placeholder="Add a skill…"
76
74
  />
77
- <p class="text-xs text-[color:var(--bb-text-muted)]" data-testid="count">
75
+ <p class="text-xs text-(--bb-text-muted)" data-testid="count">
78
76
  {{ skills.length }} skill{{ skills.length === 1 ? '' : 's' }} shown on
79
77
  your profile
80
78
  </p>
@@ -105,12 +103,10 @@ up to the first delimiter.
105
103
 
106
104
  ```vue
107
105
  <template>
108
- <div
109
- class="flex max-w-sm flex-col gap-2 rounded-[var(--bb-radius)] border p-3"
110
- >
106
+ <div class="flex max-w-sm flex-col gap-2 rounded-(--bb-radius) border p-3">
111
107
  <div class="flex flex-col gap-0.5">
112
108
  <span class="text-sm font-medium">Issue #4821</span>
113
- <span class="text-xs text-[color:var(--bb-text-muted)]"
109
+ <span class="text-xs text-(--bb-text-muted)"
114
110
  >bitboss-ui · triage labels</span
115
111
  >
116
112
  </div>
@@ -124,7 +120,7 @@ up to the first delimiter.
124
120
  persistent-hint
125
121
  placeholder="bug, regression, breaking-change…"
126
122
  />
127
- <p class="text-xs text-[color:var(--bb-text-muted)]" data-testid="labels">
123
+ <p class="text-xs text-(--bb-text-muted)" data-testid="labels">
128
124
  {{ labels.join(' · ') || 'No labels yet' }}
129
125
  </p>
130
126
  </div>
@@ -168,12 +164,10 @@ when a remaining allowance hits the floor), not “unlimited”.
168
164
 
169
165
  ```vue
170
166
  <template>
171
- <div
172
- class="flex max-w-md flex-col gap-2 rounded-[var(--bb-radius)] border p-3"
173
- >
167
+ <div class="flex max-w-md flex-col gap-2 rounded-(--bb-radius) border p-3">
174
168
  <div class="flex flex-col gap-0.5">
175
169
  <span class="text-sm font-medium">Invite to Acme Studio</span>
176
- <span class="text-xs text-[color:var(--bb-text-muted)]">
170
+ <span class="text-xs text-(--bb-text-muted)">
177
171
  Up to 5 people · they get editor access
178
172
  </span>
179
173
  </div>
@@ -190,10 +184,7 @@ when a remaining allowance hits the floor), not “unlimited”.
190
184
  @max="onMax"
191
185
  @update:model-value="warning = ''"
192
186
  />
193
- <p
194
- class="text-xs text-[color:var(--bb-text-muted)]"
195
- data-testid="invite-status"
196
- >
187
+ <p class="text-xs text-(--bb-text-muted)" data-testid="invite-status">
197
188
  {{ recipients.length }} / 5 invited<span v-if="warning">
198
189
  — {{ warning }}</span
199
190
  >
@@ -245,12 +236,10 @@ rarely. `clearable` still empties the whole field.
245
236
 
246
237
  ```vue
247
238
  <template>
248
- <div
249
- class="flex max-w-sm flex-col gap-2 rounded-[var(--bb-radius)] border p-3"
250
- >
239
+ <div class="flex max-w-sm flex-col gap-2 rounded-(--bb-radius) border p-3">
251
240
  <div class="flex flex-col gap-0.5">
252
241
  <span class="text-sm font-medium">Weekly digest</span>
253
- <span class="text-xs text-[color:var(--bb-text-muted)]">
242
+ <span class="text-xs text-(--bb-text-muted)">
254
243
  Topics land as a compact comma list
255
244
  </span>
256
245
  </div>
@@ -263,7 +252,7 @@ rarely. `clearable` still empties the whole field.
263
252
  name="topics"
264
253
  placeholder="Add a topic…"
265
254
  />
266
- <p class="text-xs text-[color:var(--bb-text-muted)]">
255
+ <p class="text-xs text-(--bb-text-muted)">
267
256
  Your weekly digest covers {{ topics.length }} topics.
268
257
  </p>
269
258
  </div>
@@ -55,10 +55,10 @@ label already plays that role and the two would overlap.
55
55
 
56
56
  ```vue
57
57
  <template>
58
- <div class="grid max-w-sm gap-3 rounded-[var(--bb-radius)] border p-4">
58
+ <div class="grid max-w-sm gap-3 rounded-(--bb-radius) border p-4">
59
59
  <div>
60
60
  <p class="text-sm font-medium">Profile basics</p>
61
- <p class="text-xs text-[color:var(--bb-text-muted)]">
61
+ <p class="text-xs text-(--bb-text-muted)">
62
62
  Same field, three label placements — pick one per product.
63
63
  </p>
64
64
  </div>
@@ -85,10 +85,10 @@ const inside = ref<string | null>('Bitboss');
85
85
 
86
86
  ```vue
87
87
  <template>
88
- <div class="grid max-w-sm gap-3 rounded-[var(--bb-radius)] border p-4">
88
+ <div class="grid max-w-sm gap-3 rounded-(--bb-radius) border p-4">
89
89
  <div>
90
90
  <p class="text-sm font-medium">Workspace settings</p>
91
- <p class="text-xs text-[color:var(--bb-text-muted)]">
91
+ <p class="text-xs text-(--bb-text-muted)">
92
92
  Required fields mark the label — keep the accessible name intact.
93
93
  </p>
94
94
  </div>
@@ -102,11 +102,7 @@ const inside = ref<string | null>('Bitboss');
102
102
  <template #label="{ text, hasErrors }">
103
103
  {{ text }}
104
104
  <span
105
- :class="
106
- hasErrors
107
- ? 'text-[color:var(--bb-danger)]'
108
- : 'text-[color:var(--bb-text-muted)]'
109
- "
105
+ :class="hasErrors ? 'text-(--bb-danger)' : 'text-(--bb-text-muted)'"
110
106
  >
111
107
  *
112
108
  </span>
@@ -171,10 +167,8 @@ validation layer should still drive `errors`.
171
167
  ```vue
172
168
  <template>
173
169
  <div class="grid max-w-sm gap-3">
174
- <div class="grid gap-2 rounded-[var(--bb-radius)] border p-3">
175
- <p class="text-xs font-medium text-[color:var(--bb-text-muted)]">
176
- Invite teammate
177
- </p>
170
+ <div class="grid gap-2 rounded-(--bb-radius) border p-3">
171
+ <p class="text-xs font-medium text-(--bb-text-muted)">Invite teammate</p>
178
172
  <BbTextInput
179
173
  v-model="email"
180
174
  compact
@@ -186,8 +180,8 @@ validation layer should still drive `errors`.
186
180
  type="email"
187
181
  />
188
182
  </div>
189
- <div class="grid gap-2 rounded-[var(--bb-radius)] border p-3">
190
- <p class="text-xs font-medium text-[color:var(--bb-text-muted)]">
183
+ <div class="grid gap-2 rounded-(--bb-radius) border p-3">
184
+ <p class="text-xs font-medium text-(--bb-text-muted)">
191
185
  Non-blocking hint
192
186
  </p>
193
187
  <BbTextInput
@@ -199,7 +193,7 @@ validation layer should still drive `errors`.
199
193
  :warnings="['This name is very short — is it what you meant?']"
200
194
  />
201
195
  </div>
202
- <div class="rounded-[var(--bb-radius)] border px-2 py-1.5">
196
+ <div class="rounded-(--bb-radius) border px-2 py-1.5">
203
197
  <BbTextInput
204
198
  v-model="search"
205
199
  class="w-full"
@@ -258,10 +252,10 @@ The full slot ring, inside → out:
258
252
 
259
253
  ```vue
260
254
  <template>
261
- <div class="grid max-w-sm gap-3 rounded-[var(--bb-radius)] border p-4">
255
+ <div class="grid max-w-sm gap-3 rounded-(--bb-radius) border p-4">
262
256
  <div>
263
257
  <p class="text-sm font-medium">Workspace & billing</p>
264
- <p class="text-xs text-[color:var(--bb-text-muted)]">
258
+ <p class="text-xs text-(--bb-text-muted)">
265
259
  Icons and short affixes live inside the chrome; actions sit outside.
266
260
  </p>
267
261
  </div>
@@ -328,10 +322,10 @@ the status.
328
322
 
329
323
  ```vue
330
324
  <template>
331
- <div class="grid max-w-sm gap-3 rounded-[var(--bb-radius)] border p-4">
325
+ <div class="grid max-w-sm gap-3 rounded-(--bb-radius) border p-4">
332
326
  <div>
333
327
  <p class="text-sm font-medium">Claim your handle</p>
334
- <p class="text-xs text-[color:var(--bb-text-muted)]">
328
+ <p class="text-xs text-(--bb-text-muted)">
335
329
  Debounced check — spinner while pending, hint or error on result.
336
330
  </p>
337
331
  </div>
@@ -550,10 +544,10 @@ five carry `labelMode` and all five fall back to
550
544
 
551
545
  ```vue
552
546
  <template>
553
- <div class="grid max-w-md gap-3 rounded-[var(--bb-radius)] border p-4">
547
+ <div class="grid max-w-md gap-3 rounded-(--bb-radius) border p-4">
554
548
  <div>
555
549
  <p class="text-sm font-medium">Billing contact</p>
556
- <p class="text-xs text-[color:var(--bb-text-muted)]">
550
+ <p class="text-xs text-(--bb-text-muted)">
557
551
  Outside labels only — horizontal rows keep dense forms scannable.
558
552
  </p>
559
553
  </div>
@@ -591,10 +585,10 @@ const company = ref<string | null>('Bitboss');
591
585
 
592
586
  ```vue
593
587
  <template>
594
- <div class="grid max-w-sm gap-2 rounded-[var(--bb-radius)] border p-3">
588
+ <div class="grid max-w-sm gap-2 rounded-(--bb-radius) border p-3">
595
589
  <div>
596
590
  <p class="text-sm font-medium">Merino Tee — Black / M</p>
597
- <p class="text-xs text-[color:var(--bb-text-muted)]">
591
+ <p class="text-xs text-(--bb-text-muted)">
598
592
  Product identifiers · compact density
599
593
  </p>
600
594
  </div>
@@ -655,7 +649,7 @@ submit, format checks on blur, errors cleared as the user fixes them.
655
649
  ```vue
656
650
  <template>
657
651
  <form
658
- class="grid max-w-md gap-3 rounded-[var(--bb-radius)] border p-4"
652
+ class="grid max-w-md gap-3 rounded-(--bb-radius) border p-4"
659
653
  novalidate
660
654
  @submit.prevent="submit"
661
655
  >
@@ -663,7 +657,7 @@ submit, format checks on blur, errors cleared as the user fixes them.
663
657
  <p class="text-sm font-medium">
664
658
  Invoice for {{ customer || 'a new client' }}
665
659
  </p>
666
- <p class="text-xs text-[color:var(--bb-text-muted)]">
660
+ <p class="text-xs text-(--bb-text-muted)">
667
661
  Draft INV-2048 · validate on blur / submit, clear as they type
668
662
  </p>
669
663
  </div>