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

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 (178) hide show
  1. package/bin/bitboss-ui-mcp.mjs +52 -6
  2. package/bin/bitboss-ui.mjs +6 -0
  3. package/dist/ai/BbAccordion.md +1 -1
  4. package/dist/ai/BbAlert.md +24 -4
  5. package/dist/ai/BbAvatar.md +19 -5
  6. package/dist/ai/BbBadge.md +28 -5
  7. package/dist/ai/BbBadgeButton.md +23 -0
  8. package/dist/ai/BbBaseCheckboxIcon.md +17 -2
  9. package/dist/ai/BbBaseColorInput.md +1 -0
  10. package/dist/ai/BbBaseDatePicker.md +14 -0
  11. package/dist/ai/BbBaseDatePickerInput.md +11 -0
  12. package/dist/ai/BbBaseNumberInput.md +1 -0
  13. package/dist/ai/BbBaseRadioIcon.md +16 -2
  14. package/dist/ai/BbBaseRating.md +11 -0
  15. package/dist/ai/BbBaseSelect.md +9 -0
  16. package/dist/ai/BbBaseSlider.md +28 -0
  17. package/dist/ai/BbBaseSwitchIcon.md +20 -3
  18. package/dist/ai/BbBaseTag.md +11 -0
  19. package/dist/ai/BbBaseTextInput.md +2 -1
  20. package/dist/ai/BbBaseTextarea.md +11 -0
  21. package/dist/ai/BbBaseTimePickerInput.md +1 -0
  22. package/dist/ai/BbButton.md +100 -12
  23. package/dist/ai/BbColorInput.md +14 -0
  24. package/dist/ai/BbDatePickerInput.md +14 -0
  25. package/dist/ai/BbDialog.md +13 -0
  26. package/dist/ai/BbDropdown.md +9 -1
  27. package/dist/ai/BbDropdownGroup.md +8 -0
  28. package/dist/ai/BbIcon.md +9 -0
  29. package/dist/ai/BbIndicator.md +23 -3
  30. package/dist/ai/BbNumberInput.md +14 -0
  31. package/dist/ai/BbOffCanvas.md +20 -1
  32. package/dist/ai/BbPagination.md +18 -0
  33. package/dist/ai/BbProgress.md +9 -0
  34. package/dist/ai/BbSelect.md +15 -1
  35. package/dist/ai/BbSelectPopover.md +7 -7
  36. package/dist/ai/BbSwitch.md +1 -1
  37. package/dist/ai/BbTable.md +56 -2
  38. package/dist/ai/BbTabs.md +25 -1
  39. package/dist/ai/BbTabsList.md +24 -0
  40. package/dist/ai/BbTabsPanes.md +24 -0
  41. package/dist/ai/BbTabsRoot.md +24 -0
  42. package/dist/ai/BbTag.md +16 -2
  43. package/dist/ai/BbTextInput.md +43 -1
  44. package/dist/ai/BbTextarea.md +14 -0
  45. package/dist/ai/BbTimePickerInput.md +14 -0
  46. package/dist/ai/BbToast.md +46 -1
  47. package/dist/ai/BbToastPortal.md +27 -0
  48. package/dist/ai/BbTooltip.md +14 -0
  49. package/dist/ai/BbTree.md +9 -0
  50. package/dist/ai/CommonInputWrapper.md +18 -0
  51. package/dist/ai/ErrorIcon.md +8 -0
  52. package/dist/ai/WarningIcon.md +8 -0
  53. package/dist/ai/changelog.json +117 -3
  54. package/dist/ai/components.json +2318 -34
  55. package/dist/ai/guides/agent-contract.md +1 -1
  56. package/dist/ai/guides/component-picker.md +1 -1
  57. package/dist/ai/guides/design-language.md +88 -78
  58. package/dist/ai/guides/design-tokens.md +318 -81
  59. package/dist/ai/guides/inline-edit-playbook.md +1 -1
  60. package/dist/ai/guides/installation-and-plugin-setup.md +40 -0
  61. package/dist/ai/guides/migration/components/bb-alert.md +2 -2
  62. package/dist/ai/guides/migration/components/bb-avatar.md +13 -14
  63. package/dist/ai/guides/migration/components/bb-button.md +80 -20
  64. package/dist/ai/guides/migration/v2-to-v3.md +68 -29
  65. package/dist/ai/index.md +2 -2
  66. package/dist/ai/recipes/inertia/inline-edit-workspace.md +8 -8
  67. package/dist/ai/recipes/inertia/upload-center.md +2 -2
  68. package/dist/ai/recipes/nuxt/inline-edit-workspace.md +8 -8
  69. package/dist/ai/recipes/nuxt/upload-center.md +2 -2
  70. package/dist/ai/recipes/vue/inline-edit-workspace.md +8 -8
  71. package/dist/ai/recipes/vue/upload-center.md +2 -2
  72. package/dist/ai/source/BbAlert.md +76 -61
  73. package/dist/ai/source/BbAvatar.md +8 -10
  74. package/dist/ai/source/BbBadge.md +45 -28
  75. package/dist/ai/source/BbBadgeButton.md +45 -28
  76. package/dist/ai/source/BbBaseButton.md +10 -3
  77. package/dist/ai/source/BbBaseCheckboxIcon.md +33 -14
  78. package/dist/ai/source/BbBaseColorInput.md +20 -3
  79. package/dist/ai/source/BbBaseColorPalette.md +3 -3
  80. package/dist/ai/source/BbBaseDatePickerInput.md +7 -0
  81. package/dist/ai/source/BbBaseInputContainer.md +11 -3
  82. package/dist/ai/source/BbBaseNumberInput.md +7 -0
  83. package/dist/ai/source/BbBaseRadioIcon.md +30 -12
  84. package/dist/ai/source/BbBaseRating.md +13 -8
  85. package/dist/ai/source/BbBaseSelect.md +9 -0
  86. package/dist/ai/source/BbBaseSlider.md +49 -12
  87. package/dist/ai/source/BbBaseSwitchIcon.md +34 -20
  88. package/dist/ai/source/BbBaseTag.md +15 -0
  89. package/dist/ai/source/BbBaseTextInput.md +7 -0
  90. package/dist/ai/source/BbBaseTextarea.md +12 -1
  91. package/dist/ai/source/BbBaseTimePickerInput.md +7 -0
  92. package/dist/ai/source/BbButton.md +206 -111
  93. package/dist/ai/source/BbColorInput.md +14 -0
  94. package/dist/ai/source/BbDatePickerInput.md +14 -0
  95. package/dist/ai/source/BbDialog.md +21 -5
  96. package/dist/ai/source/BbDropdown.md +7 -5
  97. package/dist/ai/source/BbDropdownGroup.md +7 -5
  98. package/dist/ai/source/BbDropzone.md +8 -0
  99. package/dist/ai/source/BbIndicator.md +29 -37
  100. package/dist/ai/source/BbNumberInput.md +14 -0
  101. package/dist/ai/source/BbOffCanvas.md +15 -5
  102. package/dist/ai/source/BbPagination.md +35 -9
  103. package/dist/ai/source/BbPopover.md +3 -2
  104. package/dist/ai/source/BbProgress.md +5 -1
  105. package/dist/ai/source/BbSelect.md +14 -0
  106. package/dist/ai/source/BbSelectPopover.md +3 -3
  107. package/dist/ai/source/BbSlider.md +8 -2
  108. package/dist/ai/source/BbTable.md +8 -0
  109. package/dist/ai/source/BbTag.md +14 -0
  110. package/dist/ai/source/BbTextInput.md +14 -0
  111. package/dist/ai/source/BbTextarea.md +14 -0
  112. package/dist/ai/source/BbTimePickerInput.md +14 -0
  113. package/dist/ai/source/BbToast.md +64 -30
  114. package/dist/ai/source/BbToastPortal.md +39 -25
  115. package/dist/ai/source/BbTooltip.md +22 -9
  116. package/dist/ai/source/CommonInputWrapper.md +184 -34
  117. package/dist/ai/source/CommonPopover.md +37 -9
  118. package/dist/ai/source/ErrorIcon.md +2 -2
  119. package/dist/ai/source/WarningIcon.md +2 -2
  120. package/dist/components/BbBadge/types.d.ts +1 -1
  121. package/dist/components/BbBaseColorInput/BbBaseColorInput.vue_vue_type_script_setup_true_lang.js +4 -1
  122. package/dist/components/BbBaseColorInput/types.d.ts +5 -0
  123. package/dist/components/BbBaseDatePickerInput/BbBaseDatePickerInput.vue_vue_type_script_setup_true_lang.js +4 -1
  124. package/dist/components/BbBaseDatePickerInput/types.d.ts +5 -0
  125. package/dist/components/BbBaseNumberInput/BbBaseNumberInput.vue_vue_type_script_setup_true_lang.js +4 -1
  126. package/dist/components/BbBaseNumberInput/types.d.ts +5 -0
  127. package/dist/components/BbBaseSelect/BbBaseSelect.vue_vue_type_script_setup_true_lang.js +3 -0
  128. package/dist/components/BbBaseSelect/types.d.ts +5 -0
  129. package/dist/components/BbBaseTag/BbBaseTag.vue_vue_type_script_setup_true_lang.js +4 -1
  130. package/dist/components/BbBaseTag/types.d.ts +5 -0
  131. package/dist/components/BbBaseTextInput/BbBaseTextInput.vue_vue_type_script_setup_true_lang.js +4 -1
  132. package/dist/components/BbBaseTextInput/types.d.ts +5 -0
  133. package/dist/components/BbBaseTextarea/BbBaseTextarea.vue_vue_type_script_setup_true_lang.js +4 -1
  134. package/dist/components/BbBaseTextarea/types.d.ts +5 -0
  135. package/dist/components/BbBaseTimePickerInput/BbBaseTimePickerInput.vue_vue_type_script_setup_true_lang.js +4 -1
  136. package/dist/components/BbBaseTimePickerInput/types.d.ts +5 -0
  137. package/dist/components/BbColorInput/BbColorInput.vue_vue_type_script_setup_true_lang.js +5 -2
  138. package/dist/components/BbColorInput/types.d.ts +12 -0
  139. package/dist/components/BbDatePickerInput/BbDatePickerInput.vue_vue_type_script_setup_true_lang.js +4 -2
  140. package/dist/components/BbDatePickerInput/types.d.ts +12 -0
  141. package/dist/components/BbNumberInput/BbNumberInput.vue_vue_type_script_setup_true_lang.js +5 -2
  142. package/dist/components/BbNumberInput/types.d.ts +12 -0
  143. package/dist/components/BbSelect/BbSelect.vue_vue_type_script_setup_true_lang.js +4 -2
  144. package/dist/components/BbSelect/types.d.ts +12 -0
  145. package/dist/components/BbTag/BbTag.vue_vue_type_script_setup_true_lang.js +5 -2
  146. package/dist/components/BbTag/types.d.ts +12 -0
  147. package/dist/components/BbTextInput/BbTextInput.vue_vue_type_script_setup_true_lang.js +5 -2
  148. package/dist/components/BbTextInput/types.d.ts +12 -0
  149. package/dist/components/BbTextarea/BbTextarea.vue_vue_type_script_setup_true_lang.js +5 -2
  150. package/dist/components/BbTextarea/types.d.ts +12 -0
  151. package/dist/components/BbTimePickerInput/BbTimePickerInput.vue_vue_type_script_setup_true_lang.js +4 -2
  152. package/dist/components/BbTimePickerInput/types.d.ts +12 -0
  153. package/dist/components/BbToast/BbToast.vue_vue_type_script_setup_true_lang.js +14 -11
  154. package/dist/components/BbToast/BbToastRegion.vue_vue_type_script_setup_true_lang.js +17 -12
  155. package/dist/components/CommonInputWrapper/CommonInputWrapper.vue.d.ts +1 -0
  156. package/dist/components/CommonInputWrapper/CommonInputWrapper.vue_vue_type_script_setup_true_lang.js +4 -2
  157. package/dist/components/CommonInputWrapper/types.d.ts +10 -0
  158. package/dist/index.d.ts +2 -0
  159. package/dist/input-variants.d.ts +18 -0
  160. package/dist/llms-full.txt +1534 -313
  161. package/dist/llms-medium.txt +130 -80
  162. package/dist/llms.txt +2 -2
  163. package/dist/nuxt-module.d.ts +1 -0
  164. package/dist/styles.css +1 -1
  165. package/dist/types/InputVariant.d.ts +22 -0
  166. package/dist/validated/BbColorInput.vue_vue_type_script_setup_true_lang.js +1 -0
  167. package/dist/validated/BbDatePickerInput.vue_vue_type_script_setup_true_lang.js +1 -0
  168. package/dist/validated/BbNumberInput.vue_vue_type_script_setup_true_lang.js +1 -0
  169. package/dist/validated/BbSelect.vue_vue_type_script_setup_true_lang.js +1 -0
  170. package/dist/validated/BbTag.vue_vue_type_script_setup_true_lang.js +1 -0
  171. package/dist/validated/BbTextInput.vue_vue_type_script_setup_true_lang.js +1 -0
  172. package/dist/validated/BbTextarea.vue_vue_type_script_setup_true_lang.js +1 -0
  173. package/dist/validated/BbTimePickerInput.vue_vue_type_script_setup_true_lang.js +1 -0
  174. package/dist/validated/index.d.ts +1 -0
  175. package/dist/vite-plugin.d.ts +15 -1
  176. package/dist/vite.js +93 -82
  177. package/llms.txt +2 -2
  178. package/package.json +1 -1
@@ -490,16 +490,53 @@ const STYLES_CSS = join(PACKAGE_ROOT, 'dist', 'styles.css');
490
490
  * every comma-part is built solely from these — `:root`, `.light`, `:root.dark`
491
491
  * and `html.dark` are theme roots; `.bb-tooltip .bb-common-popover__bubble` is
492
492
  * not, however many `--bb-*` it redeclares.
493
+ *
494
+ * `.bb-theme` is a theme root too: it is the island boundary the derived block
495
+ * re-specifies its formulas on (design-tokens.md § the CSS mechanic).
496
+ */
497
+ const THEME_ROOT_PART = /^(?::root|html|body|\.light|\.dark|\.bb-theme)+$/;
498
+
499
+ /**
500
+ * Unwrap the `:where(…)` / `:is(…)` a selector list may be wrapped in. The
501
+ * derived-token block ships as `:where(:root,.light,.dark,.bb-theme)`, and
502
+ * splitting THAT on commas yields `:where(:root` and `.bb-theme)` — neither of
503
+ * which is a theme root, so without this every derived token is misreported as
504
+ * a component rebind with no value. That is not a cosmetic slip: `localRebinds`
505
+ * is documented to agents as "not something to copy".
493
506
  */
494
- const THEME_ROOT_PART = /^(?::root|html|body|\.light|\.dark)+$/;
507
+ function unwrapSelectorList(selector) {
508
+ const trimmed = selector.trim();
509
+ const match = /^:(?:where|is)\((.*)\)$/s.exec(trimmed);
510
+ return match ? match[1] : trimmed;
511
+ }
512
+
495
513
  function isThemeSelector(selector) {
496
- return selector
514
+ return unwrapSelectorList(selector)
497
515
  .split(',')
498
516
  .every((part) =>
499
517
  THEME_ROOT_PART.test(part.replace(/[\s>+~]+/g, '').trim())
500
518
  );
501
519
  }
502
520
 
521
+ /**
522
+ * A theme token is a KNOB (the consumer sets it) or DERIVED (a formula the
523
+ * library recomputes at every theme boundary). Setting a derived value is the
524
+ * documented trap — it stops tracking the knob it was computed from.
525
+ *
526
+ * The split is structural in the shipped sheet, so it needs no curated list to
527
+ * drift: knobs are declared on the plain scheme roots, formulas inside the
528
+ * `:where(…)` boundary block. A name in BOTH is a knob that TRACKS another one
529
+ * until pinned — and because the boundary block re-specifies it, a pin has to
530
+ * be repeated at every boundary it is used on, `.dark` included.
531
+ */
532
+ const isDerivedBlock = (selector) => /^:(?:where|is)\(/.test(selector.trim());
533
+ const tokenKind = (inKnobBlock, inDerivedBlock) =>
534
+ inKnobBlock && inDerivedBlock
535
+ ? 'knob-tracking'
536
+ : inDerivedBlock
537
+ ? 'derived'
538
+ : 'knob';
539
+
503
540
  /**
504
541
  * Walk a stylesheet and yield every `--bb-*` declaration WITH the selector that
505
542
  * owns it. A flat regex cannot do this: it sees a declaration but not its
@@ -552,7 +589,8 @@ function* eachTokenDeclaration(css) {
552
589
  * different components and is only meaningful inside that component's scope.
553
590
  * Serving them as one flat list would invite exactly the wrong move — an agent
554
591
  * writing `:root { --gap: … }` and wondering why nothing changed. They are
555
- * documented per component, which `get_component` already serves.
592
+ * documented per component: `get_component` carries them as `cssProps`, each
593
+ * with the root class to set it on, its default, and what it is.
556
594
  *
557
595
  * WHY `dist/styles.css` AND NOT `src/assets/css/variables.css`: `src/` is not
558
596
  * in the published package, so the source file does not exist for the consumer
@@ -573,8 +611,15 @@ function listTokens({ filter } = {}) {
573
611
  const css = readFileSync(STYLES_CSS, 'utf-8');
574
612
  const byName = new Map();
575
613
  for (const { name, value, selector } of eachTokenDeclaration(css)) {
576
- const entry = byName.get(name) ?? { theme: [], local: [] };
614
+ const entry = byName.get(name) ?? {
615
+ theme: [],
616
+ local: [],
617
+ knobBlock: false,
618
+ derivedBlock: false,
619
+ };
577
620
  if (isThemeSelector(selector)) {
621
+ if (isDerivedBlock(selector)) entry.derivedBlock = true;
622
+ else entry.knobBlock = true;
578
623
  // Light first, dark after: report both rather than let one win.
579
624
  if (!entry.theme.includes(value)) entry.theme.push(value);
580
625
  } else if (!entry.local.some((r) => r.selector === selector)) {
@@ -591,8 +636,9 @@ function listTokens({ filter } = {}) {
591
636
  const tokens = [...byName.entries()]
592
637
  .filter(([name]) => !needle || name.toLowerCase().includes(needle))
593
638
  .sort(([a], [b]) => a.localeCompare(b))
594
- .map(([name, { theme, local }]) => ({
639
+ .map(([name, { theme, local, knobBlock, derivedBlock }]) => ({
595
640
  name,
641
+ kind: tokenKind(knobBlock, derivedBlock),
596
642
  value: theme[0],
597
643
  ...(theme.length > 1 ? { themeOverrides: theme.slice(1) } : {}),
598
644
  ...(local.length > 0 ? { localRebinds: local } : {}),
@@ -604,7 +650,7 @@ function listTokens({ filter } = {}) {
604
650
  hint:
605
651
  needle && tokens.length === 0
606
652
  ? `No token name contains '${needle}'. Call list_tokens with no filter for all ${byName.size} — the names are semantic (primary/danger/panel/text/border/radius/…), not literal colours.`
607
- : 'Theme tokens are set by the consumer app (e.g. on :root / .dark); `themeOverrides` is the dark-theme value. `localRebinds` is a component rebinding the token inside its own subtree — not something to copy. Component-level unprefixed tokens are documented per component; see the design-tokens guide via get_guide.',
653
+ : 'Theme tokens are set by the consumer app (e.g. on :root / .dark); `themeOverrides` is the dark-theme value. `localRebinds` is a component rebinding the token inside its own subtree — not something to copy. `kind` says what you may set: "knob" is yours; "derived" is a formula recomputed at every theme boundary, so setting it stops it tracking the knob it came from — set that knob instead; "knob-tracking" is a knob that follows another until you pin it, and the pin must be repeated at every boundary you use, .dark included. Component-level unprefixed tokens are documented per component; see the design-tokens guide via get_guide.',
608
654
  };
609
655
  }
610
656
 
@@ -108,11 +108,17 @@ function coreRules(version) {
108
108
  After upgrading bitboss-ui, re-run: \`npx bitboss-ui ai-init\``;
109
109
  }
110
110
 
111
+ // A blank line after the start marker and before the end marker: an HTML
112
+ // comment butting against a heading or a paragraph is not Prettier-stable
113
+ // markdown, and a consumer running `prettier --check` on their AGENTS.md
114
+ // (as our own fixture does in CI) would fail on text we wrote.
111
115
  function agentsFragment(version) {
112
116
  return `${START_MARKER}
117
+
113
118
  ## bitboss-ui (v${version})
114
119
 
115
120
  ${coreRules(version)}
121
+
116
122
  ${END_MARKER}`;
117
123
  }
118
124
 
@@ -238,7 +238,7 @@ const endpoints = ref<Endpoint[]>([
238
238
  .bb-badge.bb-badge--soft-green,
239
239
  .bb-badge.bb-badge--soft-red {
240
240
  --bg: color-mix(in oklab, var(--accent) 15%, var(--bb-panel));
241
- --color: color-mix(in oklab, var(--accent) 80%, var(--bb-text));
241
+ --fg: color-mix(in oklab, var(--accent) 80%, var(--bb-text));
242
242
  --border-width: 1px;
243
243
  --border-color: color-mix(in oklab, var(--accent) 25%, var(--bb-panel));
244
244
  --ring: color-mix(in oklab, var(--accent) 45%, transparent);
@@ -101,13 +101,13 @@ bitbossUi({
101
101
 
102
102
  ```css
103
103
  .bb-alert--success {
104
- --main-color: #15803d; /* title + icon */
105
- --muted-color: color-mix(
104
+ --fg: #15803d; /* title + icon */
105
+ --fg-muted: color-mix(
106
106
  in oklab,
107
- var(--main-color) 75%,
107
+ var(--fg) 75%,
108
108
  transparent
109
109
  ); /* body + close */
110
- background-color: transparent;
110
+ --bg: transparent;
111
111
  border-color: var(--bb-border);
112
112
  }
113
113
  ```
@@ -410,6 +410,26 @@ const publish = () => {
410
410
  - `text` — scope: `BbAlertTextSlotProps` — Replaces the default alert body text. Wins over children and `text`.
411
411
  - `title` — scope: `BbAlertTitleSlotProps` — Replaces the default alert title text.
412
412
 
413
+ ## CSS custom properties
414
+
415
+ Set these on the element, or on a class you put on it, to retune this component alone — the sanctioned alternative to reaching past the API with `:deep()`. They are this component's own locals; the global `--bb-*` theme tokens are a separate tier (see the [design-tokens guide](./guides/design-tokens.md), or the MCP `list_tokens` tool).
416
+
417
+ | Property | Default | What it is |
418
+ | --- | --- | --- |
419
+ | `--px` | `10px` | side padding of the plate |
420
+ | `--py` | `6px` | top/bottom padding of the plate, and the close button's inset from those edges |
421
+ | `--gap` | `4px` | icon column → content gap, reused between title parts and in the close button's reserved width |
422
+ | `--title-size` | `14px` | icon column → content gap, reused between title parts and in the close button's reserved width |
423
+ | `--title-lh` | `18px` | title line box — the close button is centred on it |
424
+ | `--text-size` | `14px` | title line box — the close button is centred on it |
425
+ | `--text-lh` | `18px` | |
426
+ | `--close-size` | `16px` | close glyph; also the width reserved at the end of the title |
427
+ | `--bg` | `transparent` | plate fill |
428
+ | `--fg` | `var(--bb-text)` | title and icon |
429
+ | `--fg-muted` | `color-mix(in oklab, var(--fg) 75%, transparent)` | Body text and the close glyph (the destructive variant points it back at --fg) |
430
+ | `--border-color` | `color-mix(in oklab, var(--bb-text) 15%, transparent)` | Plate border |
431
+ | `--elev` | `var(--bb-elev)` | Resting lift. A local, so a page that already sits on a card can flatten one alert (`<BbAlert style="--elev: none">`) without unsetting the theme's lift everywhere. |
432
+
413
433
  ## See Also
414
434
 
415
435
  - [BbToast](./BbToast.md) — Shows transient notification messages (includes the co-located BbToastPortal export).
@@ -89,14 +89,18 @@ The fallback surface is **always painted with the primary design token** —
89
89
  pairing as a primary button — so initials stay legible in light and dark and
90
90
  every avatar matches your theme automatically.
91
91
 
92
- There is no tinting **prop**, but there are three component locals on
92
+ There is no tinting **prop**, but there are two component locals on
93
93
  `.bb-avatar` for the cases the theme cannot cover — a per-tenant or
94
- per-user colour: `--bg-color` (fallback surface, defaults to `--bb-primary`),
95
- `--text-color` (initials, `--bb-primary-fg`) and `--default-icon-color` (the
96
- placeholder glyph). Set them on the avatar or on a class you put on it:
94
+ per-user colour: `--bg` (fallback surface, defaults to `--bb-primary`) and
95
+ `--fg` (initials and slotted fallback, `--bb-primary-fg`). The built-in person
96
+ glyph mixes `--fg` over `--bg`, so there is no third local. Set both on the
97
+ avatar or on a class you put on it:
97
98
 
98
99
  ```vue
99
- <BbAvatar text="Acme Studio" :style="{ '--bg-color': tenant.color }" />
100
+ <BbAvatar
101
+ text="Acme Studio"
102
+ :style="{ '--bg': tenant.color, '--fg': tenant.fg }"
103
+ />
100
104
  ```
101
105
 
102
106
  **The size scale**
@@ -555,6 +559,16 @@ available in visible text or an adjacent label.
555
559
 
556
560
  - `default` — scope: `Record<string, never>` — Fallback content shown when no image source is provided or when the image fails to load. Typically used to render initials or a placeholder icon.
557
561
 
562
+ ## CSS custom properties
563
+
564
+ Set these on the element, or on a class you put on it, to retune this component alone — the sanctioned alternative to reaching past the API with `:deep()`. They are this component's own locals; the global `--bb-*` theme tokens are a separate tier (see the [design-tokens guide](./guides/design-tokens.md), or the MCP `list_tokens` tool).
565
+
566
+ | Property | Default | What it is |
567
+ | --- | --- | --- |
568
+ | `--bg` | `var(--bb-primary)` | fallback surface (an image covers it) |
569
+ | `--fg` | `var(--bb-primary-fg)` | Initials; the built-in icon is an 80/20 mix of this toward --bg |
570
+ | `--default-icon-size` | `clamp(14px, calc(var(--size) * 0.7), 48px)` | Built-in fallback icon: 70% of the avatar, floored at 14px and capped at 48px. `--size` is the avatar's own box, set inline from the `size` prop. |
571
+
558
572
  ## See Also
559
573
 
560
574
  - [BbBadge](./BbBadge.md) — Displays a compact inline status counter or label. It sits in the flow — for a bubble or dot anchored OVER another element, use BbIndicator (includes the co-located BbBadgeButton export).
@@ -43,7 +43,7 @@ Drive the look with the `variant` ladder; put the copy in the default slot.
43
43
  The built-ins are `primary`, `secondary`, `destructive`, and `outline` — a floor,
44
44
  not the whole vocabulary. Projects register extra tones via the plugin's
45
45
  `badgeVariants` option; registration extends the TypeScript union and yields a
46
- `bb-badge--<name>` class hook — you own the CSS (`--bg` and `--color` are the
46
+ `bb-badge--<name>` class hook — you own the CSS (`--bg` and `--fg` are the
47
47
  tokens to set). **If your page needs a tone that isn't in the list, register it
48
48
  and style it** — that is the sanctioned path, not a reason to force the design
49
49
  into `secondary`/`outline`. For a genuinely one-off accent, override `--bg`
@@ -162,7 +162,7 @@ const invoices: InvoiceRow[] = [
162
162
  .bb-badge.bb-badge--soft-amber,
163
163
  .bb-badge.bb-badge--soft-red {
164
164
  --bg: color-mix(in oklab, var(--accent) 15%, var(--bb-panel));
165
- --color: color-mix(in oklab, var(--accent) 80%, var(--bb-text));
165
+ --fg: color-mix(in oklab, var(--accent) 80%, var(--bb-text));
166
166
  --border-width: 1px;
167
167
  --border-color: color-mix(in oklab, var(--accent) 25%, var(--bb-panel));
168
168
  --ring: color-mix(in oklab, var(--accent) 45%, transparent);
@@ -604,7 +604,7 @@ in dev and falls back to `md`). Keep one size per cluster.
604
604
 
605
605
  There is no `color` prop. To paint a single badge outside the variant system,
606
606
  override the CSS custom properties the variants drive — `--bg` for the
607
- background, `--color` for the text — inline:
607
+ background, `--fg` for the text — inline:
608
608
 
609
609
  **A one-off accent via the --bg token**
610
610
 
@@ -616,7 +616,7 @@ background, `--color` for the text — inline:
616
616
  ```
617
617
 
618
618
  Pair a dark custom `--bg` with a light-text variant (`primary`), or set
619
- `--color` too, and check contrast yourself. For anything recurring, register a
619
+ `--fg` too, and check contrast yourself. For anything recurring, register a
620
620
  variant instead so the styling stays in the design system.
621
621
 
622
622
  ### Anatomy and CSS hooks
@@ -712,7 +712,7 @@ selectors like `.bb-badge > .bb-badge__content`, which no longer match.
712
712
  | `loading` | `boolean \| undefined` | `false` | | Shows a spinner in place of the leftmost icon, mirroring `BbButton`: it replaces the `icon` glyph or the `prepend:icon` when one is set; when the `append:icon` is the sole icon it replaces that instead (e.g. a select-activator chevron while… |
713
713
  | `prepend:icon` | `string \| undefined` | | | Icon rendered before the label. |
714
714
  | `size` | `keyof Sizes \| undefined` | `"md"` | | Preset size of the badge. |
715
- | `variant` | `keyof BadgeVariantRegistry \| undefined` | `"primary"` | | Visual variant: `primary`, `secondary`, `destructive`, or `outline`. Register more via the vite plugin `badgeVariants` option and style `.bb-badge--<variant>` (set `--bg` / `--color`). |
715
+ | `variant` | `keyof BadgeVariantRegistry \| undefined` | `"primary"` | | Visual variant: `primary`, `secondary`, `destructive`, or `outline`. Register more via the vite plugin `badgeVariants` option and style `.bb-badge--<variant>` (set `--bg` / `--fg`). |
716
716
 
717
717
  ## Events
718
718
 
@@ -722,6 +722,29 @@ selectors like `.bb-badge > .bb-badge__content`, which no longer match.
722
722
 
723
723
  - `default` — scope: `object` — The badge's label content. When `icon` is set this becomes the visually hidden accessible label. Render a `BbBadgeButton` here to make the badge body interactive (the wrapper stays a passive `<span>`).
724
724
 
725
+ ## CSS custom properties
726
+
727
+ Set these on the element, or on a class you put on it, to retune this component alone — the sanctioned alternative to reaching past the API with `:deep()`. They are this component's own locals; the global `--bb-*` theme tokens are a separate tier (see the [design-tokens guide](./guides/design-tokens.md), or the MCP `list_tokens` tool).
728
+
729
+ | Property | Default | What it is |
730
+ | --- | --- | --- |
731
+ | `--bg` | `var(--bb-primary)` | pill fill |
732
+ | `--fg` | `var(--bb-primary-fg)` | label, icons and the clear glyph |
733
+ | `--border-width` | `0px` | Pill border. The `border` shorthand is always present, so the width is what turns it on — the filled variants leave it at 0 and the bordered ones (secondary/destructive/outline) step up to `--bb-border-w-sm`. Nothing compensates for it: the… |
734
+ | `--border-color` | `transparent` | |
735
+ | `--ring` | `var(--bb-primary-ring)` | focus ring, per variant |
736
+ | `--min-size-md` | `16px` | The md value. Only the default --min-size below reads it; the size modifiers set --min-size directly. |
737
+ | `--min-size` | `var(--min-size-md)` | pill min height and min width |
738
+ | `--elev` | `var(--bb-elev-sm)` | Resting lift. Invisible while `--bb-elev` is its default transparent layer. A chip is small enough that a theme wanting a different lift here than on a button sets `--elev` on this class. |
739
+ | `--radius` | `calc(var(--bb-radius) * 0.5)` | Pill corners; the body and trailing wrappers round their outer edges to match |
740
+ | `--font-size` | `10px` | label |
741
+ | `--icon-size` | `12px` | leading/append icons (passed to BbIcon as --size) |
742
+ | `--gap` | `3px` | space between label, icons and the trailing side |
743
+ | `--padding-inline` | `6px` | base side padding; the modifiers below scale it per side |
744
+ | `--clear-size` | `12px` | clear button's glyph box (the circle painted on hover is 2px smaller) |
745
+ | `--pad-left` | `var(--padding-inline)` | Side-owned padding: the body and trailing wrappers carry the pill's inline padding (and its radius) so their hit areas run flush to the border. The modifiers below retune these vars instead of the pill's own padding. |
746
+ | `--pad-right` | `var(--padding-inline)` | |
747
+
725
748
  ## See Also
726
749
 
727
750
  - [BbIndicator](./BbIndicator.md) — Anchors a notification bubble (count/short text) or a dot over a wrapped element.
@@ -61,6 +61,29 @@
61
61
 
62
62
  - `default` — scope: `object` — The action's label — what the badge displays as its body.
63
63
 
64
+ ## CSS custom properties
65
+
66
+ Set these on the element, or on a class you put on it, to retune this component alone — the sanctioned alternative to reaching past the API with `:deep()`. They are this component's own locals; the global `--bb-*` theme tokens are a separate tier (see the [design-tokens guide](./guides/design-tokens.md), or the MCP `list_tokens` tool).
67
+
68
+ | Property | Default | What it is |
69
+ | --- | --- | --- |
70
+ | `--bg` | `var(--bb-primary)` | pill fill |
71
+ | `--fg` | `var(--bb-primary-fg)` | label, icons and the clear glyph |
72
+ | `--border-width` | `0px` | Pill border. The `border` shorthand is always present, so the width is what turns it on — the filled variants leave it at 0 and the bordered ones (secondary/destructive/outline) step up to `--bb-border-w-sm`. Nothing compensates for it: the… |
73
+ | `--border-color` | `transparent` | |
74
+ | `--ring` | `var(--bb-primary-ring)` | focus ring, per variant |
75
+ | `--min-size-md` | `16px` | The md value. Only the default --min-size below reads it; the size modifiers set --min-size directly. |
76
+ | `--min-size` | `var(--min-size-md)` | pill min height and min width |
77
+ | `--elev` | `var(--bb-elev-sm)` | Resting lift. Invisible while `--bb-elev` is its default transparent layer. A chip is small enough that a theme wanting a different lift here than on a button sets `--elev` on this class. |
78
+ | `--radius` | `calc(var(--bb-radius) * 0.5)` | Pill corners; the body and trailing wrappers round their outer edges to match |
79
+ | `--font-size` | `10px` | label |
80
+ | `--icon-size` | `12px` | leading/append icons (passed to BbIcon as --size) |
81
+ | `--gap` | `3px` | space between label, icons and the trailing side |
82
+ | `--padding-inline` | `6px` | base side padding; the modifiers below scale it per side |
83
+ | `--clear-size` | `12px` | clear button's glyph box (the circle painted on hover is 2px smaller) |
84
+ | `--pad-left` | `var(--padding-inline)` | Side-owned padding: the body and trailing wrappers carry the pill's inline padding (and its radius) so their hit areas run flush to the border. The modifiers below retune these vars instead of the pill's own padding. |
85
+ | `--pad-right` | `var(--padding-inline)` | |
86
+
64
87
  ## See Also
65
88
 
66
89
  - [BbBadge](./BbBadge.md) — Displays a compact inline status counter or label. It sits in the flow — for a bubble or dot anchored OVER another element, use BbIndicator (includes the co-located BbBadgeButton export).
@@ -111,7 +111,7 @@ properties on it:
111
111
 
112
112
  - `--size` — box edge length (default `16px`)
113
113
  - `--r` — corner radius (default `4px`)
114
- - `--color` — fill + border when checked/indeterminate (default `--bb-primary`)
114
+ - `--accent` — fill + border when checked/indeterminate (default `--bb-primary`)
115
115
  - `--check-color` — checkmark stroke (default `--bb-primary-fg`)
116
116
  - `--ring-color` — focus ring color
117
117
 
@@ -137,7 +137,7 @@ from an ancestor — so `--size` set on a wrapper `div` is simply ignored
137
137
  ```vue
138
138
  <BbBaseCheckboxIcon
139
139
  :checked="true"
140
- style="--size: 28px; --r: 999px; --color: #16a34a"
140
+ style="--size: 28px; --r: 999px; --accent: #16a34a"
141
141
  />
142
142
  ```
143
143
 
@@ -181,6 +181,21 @@ from an ancestor — so `--size` set on a wrapper `div` is simply ignored
181
181
 
182
182
  - None.
183
183
 
184
+ ## CSS custom properties
185
+
186
+ Set these on the element, or on a class you put on it, to retune this component alone — the sanctioned alternative to reaching past the API with `:deep()`. They are this component's own locals; the global `--bb-*` theme tokens are a separate tier (see the [design-tokens guide](./guides/design-tokens.md), or the MCP `list_tokens` tool).
187
+
188
+ | Property | Default | What it is |
189
+ | --- | --- | --- |
190
+ | `--accent` | `var(--bb-primary)` | |
191
+ | `--check-color` | `var(--bb-primary-fg)` | |
192
+ | `--size` | `16px` | |
193
+ | `--r` | `min(4px, var(--bb-radius))` | The checkbox corner, capped by the master radius so a zero- or small-radius theme reaches it. Not `--bb-radius-sm`: that tier is 4.8px at the shipped radius and this glyph ships at 4px. |
194
+ | `--ring-color` | `var(--bb-ring)` | |
195
+ | `--elev` | `var(--bb-elev-sm)` | Resting lift; a no-op until a theme pins `--bb-elev`. |
196
+ | `--bg` | `var(--bb-panel)` | The glyph plate. DECLARED here, not consumed bare, because this glyph renders inside surfaces that declare `--bg` themselves — a table row or header cell, a dialog, an off-canvas sheet. Without the declaration it would inherit that surface'… |
197
+ | `--border-color` | `var(--bb-border)` | |
198
+
184
199
  ## See Also
185
200
 
186
201
  - [BbCheckbox](./BbCheckbox.md) — Toggles a single boolean option.
@@ -38,6 +38,7 @@
38
38
  | `required` | `boolean \| undefined` | `false` | | Mark the input as required. |
39
39
  | `swatches` | `boolean \| string[][] \| undefined` | | | Controls swatches display in the picker: - `true` — show the built-in Material-palette swatches - `string[][]` — show custom swatches (each inner array = a column of shades) - `false` / omitted — no swatches section |
40
40
  | `transitionDuration` | `number \| undefined` | `250` | | Transition duration (ms) of the palette popover. Forwarded to `BbColorPalette`, which supplies the default. |
41
+ | `variant` | `InputVariantType \| undefined` | | | Visual variant of the field box, forwarded to `CommonInputWrapper`. |
41
42
 
42
43
  ## Events
43
44
 
@@ -41,3 +41,17 @@
41
41
  ## Exposed (template ref)
42
42
 
43
43
  - `resetStatus`: `() => void`
44
+
45
+ ## CSS custom properties
46
+
47
+ Set these on the element, or on a class you put on it, to retune this component alone — the sanctioned alternative to reaching past the API with `:deep()`. They are this component's own locals; the global `--bb-*` theme tokens are a separate tier (see the [design-tokens guide](./guides/design-tokens.md), or the MCP `list_tokens` tool).
48
+
49
+ | Property | Default | What it is |
50
+ | --- | --- | --- |
51
+ | `--cell` | `28px` | Cell size drives all grid math: 224px ÷ 7 = 32px exactly |
52
+ | `--pad-x` | `6px` | |
53
+ | `--pad-y` | `8px` | |
54
+ | `--nav-button-h` | `24px` | |
55
+ | `--weeks` | `6` | |
56
+ | `--day-slot-allowance` | `0px` | Allowance for the day slot append area - needed for the slot to be visible |
57
+ | `--unit-row` | `calc(var(--cell) * 1.25)` | Row pitch for the coarse grids (month/year), where a "row" is one of four month rows rather than a week. Roomier than --cell because twelve months in a 4×3 grid have space the 6×7 day grid does not. |
@@ -51,6 +51,7 @@
51
51
  | `transitionDuration` | `number \| undefined` | | | Transition duration, in milliseconds, for the popover appearance. |
52
52
  | `type` | `DatePickerType \| undefined` | `"date"` | | What the field edits, and therefore its segments and emitted shape. - `date` (default) — `DD/MM/YYYY`. - `datetime` — adds the time segments and the calendar's time rail. - `month` — `MM/YYYY`, emitting `YYYY-MM`. - `year` — `YYYY`, emittin… |
53
53
  | `utc` | `boolean \| undefined` | `false` | | Emits values as UTC ISO strings (`...Z`) instead of ISO strings carrying the local offset (`...+01:00`). Emission-only: incoming values are parsed identically either way, so the prop can be added or removed without touching stored values. F… |
54
+ | `variant` | `InputVariantType \| undefined` | | | Visual variant of the field box, forwarded to `CommonInputWrapper`. |
54
55
 
55
56
  ## Events
56
57
 
@@ -71,3 +72,13 @@
71
72
  - `prepend` — scope: `object` — Content rendered before the date fields, at the start of the inner container.
72
73
  - `prepend-outer` — scope: `object` — Content rendered before the entire input control, outside the input chrome.
73
74
  - `suffix` — scope: `object` — Inline content rendered at the end of the input field area, after the date fields.
75
+
76
+ ## CSS custom properties
77
+
78
+ Set these on the element, or on a class you put on it, to retune this component alone — the sanctioned alternative to reaching past the API with `:deep()`. They are this component's own locals; the global `--bb-*` theme tokens are a separate tier (see the [design-tokens guide](./guides/design-tokens.md), or the MCP `list_tokens` tool).
79
+
80
+ | Property | Default | What it is |
81
+ | --- | --- | --- |
82
+ | `--time-row-h` | `28px` | |
83
+ | `--time-col-w` | `44px` | |
84
+ | `--time-mark` | `24px` | Visible mark = the day-cell mark (--cell - 4). Hit area stays the full row; only the painted knob matches the calendar's. |
@@ -37,6 +37,7 @@
37
37
  | `readonly` | `boolean \| undefined` | `false` | | Make the input read-only while keeping its value visible. |
38
38
  | `required` | `boolean \| undefined` | `false` | | Mark the input as required for form validation. |
39
39
  | `step` | `number \| undefined` | `1` | | Increment used by the `increase`/`decrease` helpers. Manual typing is never forced to this step. |
40
+ | `variant` | `InputVariantType \| undefined` | | | Visual variant of the field box, forwarded to `CommonInputWrapper`. |
40
41
 
41
42
  ## Events
42
43
 
@@ -130,7 +130,7 @@ Restyle by overriding the glyph's CSS custom properties on it:
130
130
 
131
131
  - `--size` — ring diameter (default `16px`)
132
132
  - `--space` — gap between ring and dot when checked (default `2px`)
133
- - `--color` — dot color (default `--bb-primary`)
133
+ - `--accent` — dot color (default `--bb-primary`)
134
134
  - `--ring-color` — focus ring color
135
135
 
136
136
  **On the element itself, not an ancestor.** Each of these is declared on the
@@ -153,7 +153,7 @@ from an ancestor — so `--size` set on a wrapper `div` is simply ignored
153
153
  **Bigger and recolored**
154
154
 
155
155
  ```vue
156
- <BbBaseRadioIcon :checked="true" style="--size: 24px; --color: #16a34a" />
156
+ <BbBaseRadioIcon :checked="true" style="--size: 24px; --accent: #16a34a" />
157
157
  ```
158
158
 
159
159
  ### Gotchas & anti-patterns
@@ -195,6 +195,20 @@ from an ancestor — so `--size` set on a wrapper `div` is simply ignored
195
195
 
196
196
  - None.
197
197
 
198
+ ## CSS custom properties
199
+
200
+ Set these on the element, or on a class you put on it, to retune this component alone — the sanctioned alternative to reaching past the API with `:deep()`. They are this component's own locals; the global `--bb-*` theme tokens are a separate tier (see the [design-tokens guide](./guides/design-tokens.md), or the MCP `list_tokens` tool).
201
+
202
+ | Property | Default | What it is |
203
+ | --- | --- | --- |
204
+ | `--accent` | `var(--bb-primary)` | |
205
+ | `--size` | `16px` | |
206
+ | `--space` | `2px` | |
207
+ | `--ring-color` | `var(--bb-ring)` | |
208
+ | `--elev` | `var(--bb-elev-sm)` | Same resting lift as the checkbox glyph — see BbBaseCheckboxIcon. |
209
+ | `--bg` | `var(--bb-panel)` | The glyph plate. DECLARED here, not consumed bare, because this glyph renders inside surfaces that declare `--bg` themselves — a table row or header cell, a dialog, an off-canvas sheet. Without the declaration it would inherit that surface'… |
210
+ | `--border-color` | `var(--bb-border)` | |
211
+
198
212
  ## See Also
199
213
 
200
214
  - [BbRadio](./BbRadio.md) — Represents a single choice in exclusive options.
@@ -50,3 +50,14 @@
50
50
  - `append` — scope: `object` — Content rendered after the row of rating stars.
51
51
  - `icon` — scope: `BaseRatingIconSlotProps` — Replaces the default star SVG for each rating option.
52
52
  - `prepend` — scope: `object` — Content rendered before the row of rating stars.
53
+
54
+ ## CSS custom properties
55
+
56
+ Set these on the element, or on a class you put on it, to retune this component alone — the sanctioned alternative to reaching past the API with `:deep()`. They are this component's own locals; the global `--bb-*` theme tokens are a separate tier (see the [design-tokens guide](./guides/design-tokens.md), or the MCP `list_tokens` tool).
57
+
58
+ | Property | Default | What it is |
59
+ | --- | --- | --- |
60
+ | `--accent` | `var(--bb-primary)` | Fill of a filled (or hover-previewed) star. An unfilled one is --bb-panel with a --bb-border stroke. |
61
+ | `--ring-color` | `var(--bb-ring)` | focus ring around the focused star |
62
+ | `--size` | `24px` | one star's box; overridden inline from the `size` prop |
63
+ | `--space` | `0px` | Gap between stars. Named `--space`, not `--spacing`: Tailwind v4 builds its whole spacing scale on a variable of that name, and a local of the same name zeroed every spacing utility used inside the slots. |
@@ -59,6 +59,7 @@
59
59
  | `selectedLabelsFn` | `((count: number) => string) \| undefined` | | | Function to generate a summary label when selected items exceed `maxSelectedLabels` or overflow the control width. |
60
60
  | `stash` | `boolean \| undefined` | `false` | | Accumulate selected items across searches. |
61
61
  | `transitionDuration` | `number \| undefined` | `250` | | Transition duration (ms) for dropdown animations. Forwarded to `BbSelectPopover`, which supplies the default. |
62
+ | `variant` | `InputVariantType \| undefined` | | | Visual variant of the field box, forwarded to `CommonInputWrapper`. |
62
63
 
63
64
  ## Events
64
65
 
@@ -87,3 +88,11 @@
87
88
  - `prepend` — scope: `BaseSelectActivatorSlotProps`
88
89
  - `prepend-outer` — scope: `BaseSelectOuterSlotProps`
89
90
  - `suffix` — scope: `object`
91
+
92
+ ## CSS custom properties
93
+
94
+ Set these on the element, or on a class you put on it, to retune this component alone — the sanctioned alternative to reaching past the API with `:deep()`. They are this component's own locals; the global `--bb-*` theme tokens are a separate tier (see the [design-tokens guide](./guides/design-tokens.md), or the MCP `list_tokens` tool).
95
+
96
+ | Property | Default | What it is |
97
+ | --- | --- | --- |
98
+ | `--compensation-multiplier` | `0.3` | Fraction of the shell's inner padding the chips row is pulled back by when no prepend icon precedes it (see the negative margin below). |
@@ -54,3 +54,31 @@
54
54
  - `thumb:higher` — scope: `BaseSliderThumbSlotProps` — Replaces the default higher-value thumb in range mode (`range: true`).
55
55
  - `thumb:lower` — scope: `BaseSliderThumbSlotProps` — Replaces the default lower-value thumb in range mode (`range: true`).
56
56
  - `tick` — scope: `BaseSliderTickSlotProps` — Replaces the default tick mark rendered at each step when ticks are enabled.
57
+
58
+ ## CSS custom properties
59
+
60
+ Set these on the element, or on a class you put on it, to retune this component alone — the sanctioned alternative to reaching past the API with `:deep()`. They are this component's own locals; the global `--bb-*` theme tokens are a separate tier (see the [design-tokens guide](./guides/design-tokens.md), or the MCP `list_tokens` tool).
61
+
62
+ | Property | Default | What it is |
63
+ | --- | --- | --- |
64
+ | `--thumb` | `12px` | thumb diameter (square, then `border-radius: 50%`) |
65
+ | `--track` | `4px` | rail thickness |
66
+ | `--track-color` | `var(--bb-track)` | The recessed rail surface — the same token the switch track reads, which is what design-tokens.md has always documented it as ("switch/slider rails"). It was `--bb-muted` (6% of text), a chrome wash so faint the unfilled rail barely read, a… |
67
+ | `--padding` | `calc((var(--thumb) - var(--track)) / 2)` | Room above and below the rail for the thumb's overhang. |
68
+ | `--control-h` | `var(--bb-input-h)` | Row height; --compact swaps in the compact input height. |
69
+ | `--px` | `var(--bb-input-px)` | Horizontal inset for the shell below. Declared here and read by BbSlider (nothing in this file consumes it). |
70
+ | `--shell-px` | `0px` | inner left/right padding of the box |
71
+ | `--track-inset` | `0px` | How far the rail and the tick row are held off both ends. |
72
+ | `--inside-label-clearance` | `0px` | height added for the label line |
73
+ | `--inside-label-track-offset` | `0px` | How far rail and thumbs drop from centre to clear that line. |
74
+ | `--shell-bg` | `transparent` | |
75
+ | `--shell-border-width` | `0px` | |
76
+ | `--shell-border-color` | `var(--bb-border)` | |
77
+ | `--shell-radius` | `0px` | |
78
+ | `--shell-focus-border` | `var(--bb-border)` | Border while a thumb is focused or held; the errors and warnings blocks below paint the resting border with it too. |
79
+ | `--shell-focus-ring` | `0px 0px 0px 0px transparent` | The box-shadow that replaces --shell-shadow in that state. |
80
+ | `--shell-shadow` | `0px 0px 0px 0px var(--bb-ring)` | resting box-shadow |
81
+ | `--shell-disabled-bg` | `transparent` | resting box-shadow |
82
+ | `--accent` | `var(--bb-primary)` | The selected span of the rail (`__track-background`, sized from JS), and the base of --ring-color below. |
83
+ | `--ring-color` | `color-mix( in oklab, var(--accent) var(--bb-ring-opacity), transparent )` | Halo around the thumb on hover and focus; errors and warnings re-point it. |
84
+ | `--radius` | `var(--bb-radius)` | Rail rounding: all four corners of the rail, the leading pair on the selected span. |
@@ -120,8 +120,8 @@ Restyle by overriding the glyph's CSS custom properties on it:
120
120
 
121
121
  - `--w` / `--h` — track width / height (default `32px` / `18px`)
122
122
  - `--thumb` — thumb diameter (default `16px`)
123
- - `--color` — track fill when checked (default `--bb-primary`)
124
- - `--bg-color` — track fill when off (default `--bb-track`)
123
+ - `--accent` — track fill when checked (default `--bb-primary`)
124
+ - `--bg` — track fill when off (default `--bb-track`)
125
125
  - `--radius` — track/thumb rounding (default `999px`)
126
126
 
127
127
  **On the element itself, not an ancestor.** Each of these is declared on the
@@ -148,7 +148,7 @@ from an ancestor — so `--w` set on a wrapper `div` is simply ignored
148
148
  ```vue
149
149
  <BbBaseSwitchIcon
150
150
  :checked="true"
151
- style="--w: 48px; --h: 26px; --thumb: 22px; --color: #16a34a"
151
+ style="--w: 48px; --h: 26px; --thumb: 22px; --accent: #16a34a"
152
152
  />
153
153
  ```
154
154
 
@@ -192,6 +192,23 @@ from an ancestor — so `--w` set on a wrapper `div` is simply ignored
192
192
 
193
193
  - None.
194
194
 
195
+ ## CSS custom properties
196
+
197
+ Set these on the element, or on a class you put on it, to retune this component alone — the sanctioned alternative to reaching past the API with `:deep()`. They are this component's own locals; the global `--bb-*` theme tokens are a separate tier (see the [design-tokens guide](./guides/design-tokens.md), or the MCP `list_tokens` tool).
198
+
199
+ | Property | Default | What it is |
200
+ | --- | --- | --- |
201
+ | `--accent` | `var(--bb-primary)` | Track fill and border once checked or indeterminate; --errors, --warnings and --disabled re-point it. |
202
+ | `--bg` | `var(--bb-track)` | track fill while off |
203
+ | `--ring-color` | `color-mix( in oklab, var(--accent) var(--bb-ring-opacity), transparent )` | focus ring; follows --accent, so the status modifiers tint it too |
204
+ | `--radius` | `999px` | track corners; the thumb rounds to 80% of it |
205
+ | `--bw` | `var(--bb-border-w-sm)` | Geometry — change --h / --w / --thumb freely: everything else is derived, so the thumb stays vertically centred and travels flush-to-flush at any size. --bw is the track border; the box is border-box, so the border eats into the inner track… |
206
+ | `--h` | `18px` | track height, border included (border-box) |
207
+ | `--w` | `32px` | track width, border included |
208
+ | `--thumb` | `min(16px, calc(var(--h) - 2 * var(--bw)))` | Capped by the track's inner height, so a thick-hairline theme shrinks the thumb instead of overflowing it. Unclamped, a 6px plate hairline leaves a 12px inner track carrying a 16px thumb; `--inset` then goes negative and the thumb paints ov… |
209
+ | `--inset` | `calc((var(--h) - 2 * var(--bw) - var(--thumb)) / 2)` | Equal gap around the thumb — centres it vertically by construction, and is reused as the resting left/right inset. |
210
+ | `--travel` | `calc(var(--w) - 2 * var(--bw) - var(--thumb) - 2 * var(--inset))` | How far the thumb slides between off and on (inset ↔ inset). |
211
+
195
212
  ## See Also
196
213
 
197
214
  - [BbSwitch](./BbSwitch.md) — Toggles two-state values with switch semantics.
@@ -37,6 +37,7 @@
37
37
  | `prepend:icon` | `string \| undefined` | | | Name of the icon to render at the left hand side of the input. |
38
38
  | `readonly` | `boolean \| undefined` | `false` | | Make the input read-only while keeping tags visible. |
39
39
  | `required` | `boolean \| undefined` | `false` | | Mark the input as required for form validation. |
40
+ | `variant` | `InputVariantType \| undefined` | | | Visual variant of the field box, forwarded to `CommonInputWrapper`. |
40
41
 
41
42
  ## Events
42
43
 
@@ -66,3 +67,13 @@
66
67
  - `prepend` — scope: `Record<string, never>` — Content rendered before the tag input, at the start of the inner container.
67
68
  - `prepend-outer` — scope: `Record<string, never>` — Content rendered before the entire tag input control, outside the input chrome.
68
69
  - `suffix` — scope: `Record<string, never>` — Inline content rendered at the end of the input field area, after the typed text.
70
+
71
+ ## CSS custom properties
72
+
73
+ Set these on the element, or on a class you put on it, to retune this component alone — the sanctioned alternative to reaching past the API with `:deep()`. They are this component's own locals; the global `--bb-*` theme tokens are a separate tier (see the [design-tokens guide](./guides/design-tokens.md), or the MCP `list_tokens` tool).
74
+
75
+ | Property | Default | What it is |
76
+ | --- | --- | --- |
77
+ | `--compensation-multiplier` | `0.3` | Fraction of the shell's inner padding the chip row is pulled back by when no prepend icon precedes it (see the negative margin below). |
78
+ | `--inner-h` | `max( calc(var(--bb-leading) + var(--bb-input-py) * 2), calc(var(--bb-input-h) - …` | The first chip row's height: the tallest of one line plus its vertical padding, the input height less its borders, and the icon box. Feeds `--floating-py` and nothing else. |
79
+ | `--floating-py` | `calc((var(--inner-h) - var(--bb-input-icon)) / 2)` | Top offset for centring icons and affixes on that first row — the same value BbBaseTextarea uses for that. Nothing in the library reads it, so this and the compact override below are currently inert. |
@@ -27,7 +27,7 @@
27
27
  | `hasErrors` | `boolean \| undefined` | `false` | | Apply error styling to the input and set `aria-invalid`. |
28
28
  | `hasWarning` | `boolean \| undefined` | `false` | | Apply warning styling (same chrome as errors, `--bb-warn` color). Suppressed when `hasErrors` is also set. |
29
29
  | `id` | `string \| undefined` | | | Explicit id for the input element. |
30
- | `inputMode` | `"text" \| "search" \| "email" \| "url" \| "tel" \| "none" \| "numeric" \| "decimal" \| undefined` | | | Input mode hint for mobile keyboards. |
30
+ | `inputMode` | `"text" \| "none" \| "search" \| "email" \| "url" \| "tel" \| "numeric" \| "decimal" \| undefined` | | | Input mode hint for mobile keyboards. |
31
31
  | `labelMode` | `"floating" \| "outside" \| "inside" \| undefined` | | | Label rendering mode, forwarded by wrapper components. |
32
32
  | `loading` | `boolean \| undefined` | `false` | | Display the loading state styles. |
33
33
  | `mask` | `MaskInputOptions \| undefined` | | | Input mask configuration. When provided, enables formatted input with validation. |
@@ -42,6 +42,7 @@
42
42
  | `required` | `boolean \| undefined` | `false` | | Mark the input as required for form validation. |
43
43
  | `step` | `string \| undefined` | | | Stepping interval for numeric and date inputs. |
44
44
  | `type` | `"text" \| "search" \| "email" \| "url" \| "tel" \| "password" \| undefined` | `"text"` | | HTML input type attribute. Restricted to the textual input types this component supports — use `BbNumberInput` for numbers and `BbDatePickerInput` for dates. |
45
+ | `variant` | `InputVariantType \| undefined` | | | Visual variant of the field box, forwarded to `CommonInputWrapper`. |
45
46
 
46
47
  ## Events
47
48