bitboss-ui 3.0.0-beta.42 → 3.0.0-beta.43

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 (245) hide show
  1. package/README.md +4 -2
  2. package/bin/bitboss-ui-mcp.mjs +71 -57
  3. package/bin/bitboss-ui.mjs +1 -1
  4. package/dist/ai/BbAccordion.md +1 -1
  5. package/dist/ai/BbAlert.md +1 -1
  6. package/dist/ai/BbAvatar.md +1 -1
  7. package/dist/ai/BbBadge.md +1 -1
  8. package/dist/ai/BbBadgeButton.md +1 -1
  9. package/dist/ai/BbBaseButton.md +1 -1
  10. package/dist/ai/BbBreadcrumbs.md +1 -1
  11. package/dist/ai/BbButton.md +31 -3
  12. package/dist/ai/BbCalendar.md +1 -1
  13. package/dist/ai/BbCheckbox.md +3 -2
  14. package/dist/ai/BbCheckboxGroup.md +3 -2
  15. package/dist/ai/BbColorInput.md +3 -2
  16. package/dist/ai/BbColorPalette.md +1 -1
  17. package/dist/ai/BbConfirm.md +1 -1
  18. package/dist/ai/BbDatePicker.md +1 -1
  19. package/dist/ai/BbDatePickerInput.md +3 -2
  20. package/dist/ai/BbDialog.md +1 -1
  21. package/dist/ai/BbDropdown.md +1 -1
  22. package/dist/ai/BbDropdownButton.md +1 -1
  23. package/dist/ai/BbDropzone.md +1 -1
  24. package/dist/ai/BbForm.md +65 -2
  25. package/dist/ai/BbNumberInput.md +3 -2
  26. package/dist/ai/BbOffCanvas.md +1 -1
  27. package/dist/ai/BbPagination.md +1 -1
  28. package/dist/ai/BbPopover.md +1 -1
  29. package/dist/ai/BbRadio.md +3 -2
  30. package/dist/ai/BbRadioGroup.md +3 -2
  31. package/dist/ai/BbRating.md +8 -2
  32. package/dist/ai/BbSelect.md +3 -2
  33. package/dist/ai/BbSelectPopover.md +1 -1
  34. package/dist/ai/BbSlider.md +8 -2
  35. package/dist/ai/BbSpinner.md +1 -1
  36. package/dist/ai/BbSwitch.md +3 -2
  37. package/dist/ai/BbSwitchGroup.md +3 -2
  38. package/dist/ai/BbTable.md +1 -1
  39. package/dist/ai/BbTabs.md +1 -1
  40. package/dist/ai/BbTabsList.md +1 -1
  41. package/dist/ai/BbTag.md +3 -2
  42. package/dist/ai/BbTextInput.md +11 -2
  43. package/dist/ai/BbTextarea.md +10 -7
  44. package/dist/ai/BbTimePicker.md +1 -1
  45. package/dist/ai/BbTimePickerInput.md +3 -2
  46. package/dist/ai/BbToast.md +1 -1
  47. package/dist/ai/BbTooltip.md +1 -1
  48. package/dist/ai/BbTree.md +1 -1
  49. package/dist/ai/ChipsBox.md +1 -1
  50. package/dist/ai/ClearableButton.md +1 -1
  51. package/dist/ai/CommonField.md +9 -1
  52. package/dist/ai/CommonFieldInput.md +1 -1
  53. package/dist/ai/CommonTimeSelector.md +1 -1
  54. package/dist/ai/ErrorIcon.md +1 -1
  55. package/dist/ai/FlatListBox.md +1 -1
  56. package/dist/ai/GroupedListBox.md +1 -1
  57. package/dist/ai/ListBox.md +1 -1
  58. package/dist/ai/WarningIcon.md +1 -1
  59. package/dist/ai/changelog.json +53 -3
  60. package/dist/ai/components.json +294 -58336
  61. package/dist/ai/composables/useBbFormContext.md +19 -19
  62. package/dist/ai/design-tokens.json +26 -6
  63. package/dist/ai/guides/agent-contract.md +5 -4
  64. package/dist/ai/guides/ai-router.md +6 -4
  65. package/dist/ai/guides/design-tokens.md +93 -16
  66. package/dist/ai/guides/migration/v2-to-v3.md +16 -0
  67. package/dist/ai/guides/migration/v3-beta-tooling.md +44 -0
  68. package/dist/ai/guides/passthrough.md +2 -2
  69. package/dist/ai/guides/validation-providers.md +36 -23
  70. package/dist/ai/index.md +5 -5
  71. package/dist/ai/manifest/components/BbAccordion.json +41 -0
  72. package/dist/ai/manifest/components/BbAccordion.tree.json +25 -0
  73. package/dist/ai/manifest/components/BbAlert.json +56 -0
  74. package/dist/ai/manifest/components/BbAlert.tree.json +80 -0
  75. package/dist/ai/manifest/components/BbAsterisk.json +26 -0
  76. package/dist/ai/manifest/components/BbAsterisk.tree.json +13 -0
  77. package/dist/ai/manifest/components/BbAvatar.json +38 -0
  78. package/dist/ai/manifest/components/BbAvatar.tree.json +39 -0
  79. package/dist/ai/manifest/components/BbBadge.json +50 -0
  80. package/dist/ai/manifest/components/BbBadge.tree.json +86 -0
  81. package/dist/ai/manifest/components/BbBadgeButton.json +67 -0
  82. package/dist/ai/manifest/components/BbBadgeButton.tree.json +32 -0
  83. package/dist/ai/manifest/components/BbBaseButton.json +69 -0
  84. package/dist/ai/manifest/components/BbBaseButton.tree.json +25 -0
  85. package/dist/ai/manifest/components/BbBaseCheckboxIcon.json +46 -0
  86. package/dist/ai/manifest/components/BbBaseCheckboxIcon.tree.json +41 -0
  87. package/dist/ai/manifest/components/BbBaseRadioIcon.json +44 -0
  88. package/dist/ai/manifest/components/BbBaseRadioIcon.tree.json +36 -0
  89. package/dist/ai/manifest/components/BbBaseSwitchIcon.json +46 -0
  90. package/dist/ai/manifest/components/BbBaseSwitchIcon.tree.json +44 -0
  91. package/dist/ai/manifest/components/BbBreadcrumbs.json +52 -0
  92. package/dist/ai/manifest/components/BbBreadcrumbs.tree.json +45 -0
  93. package/dist/ai/manifest/components/BbButton.json +101 -0
  94. package/dist/ai/manifest/components/BbButton.tree.json +206 -0
  95. package/dist/ai/manifest/components/BbCalendar.json +84 -0
  96. package/dist/ai/manifest/components/BbCalendar.tree.json +99 -0
  97. package/dist/ai/manifest/components/BbCheckbox.json +97 -0
  98. package/dist/ai/manifest/components/BbCheckbox.tree.json +22 -0
  99. package/dist/ai/manifest/components/BbCheckboxGroup.json +127 -0
  100. package/dist/ai/manifest/components/BbCheckboxGroup.tree.json +52 -0
  101. package/dist/ai/manifest/components/BbCollapsible.json +32 -0
  102. package/dist/ai/manifest/components/BbCollapsible.tree.json +17 -0
  103. package/dist/ai/manifest/components/BbColorInput.json +131 -0
  104. package/dist/ai/manifest/components/BbColorInput.tree.json +37 -0
  105. package/dist/ai/manifest/components/BbColorPalette.json +73 -0
  106. package/dist/ai/manifest/components/BbColorPalette.tree.json +55 -0
  107. package/dist/ai/manifest/components/BbConfirm.json +34 -0
  108. package/dist/ai/manifest/components/BbConfirm.tree.json +30 -0
  109. package/dist/ai/manifest/components/BbConfirmPortal.json +18 -0
  110. package/dist/ai/manifest/components/BbDatePicker.json +106 -0
  111. package/dist/ai/manifest/components/BbDatePicker.tree.json +54 -0
  112. package/dist/ai/manifest/components/BbDatePickerInput.json +163 -0
  113. package/dist/ai/manifest/components/BbDatePickerInput.tree.json +50 -0
  114. package/dist/ai/manifest/components/BbDialog.json +76 -0
  115. package/dist/ai/manifest/components/BbDialog.tree.json +74 -0
  116. package/dist/ai/manifest/components/BbDropdown.json +98 -0
  117. package/dist/ai/manifest/components/BbDropdown.tree.json +120 -0
  118. package/dist/ai/manifest/components/BbDropdownButton.json +104 -0
  119. package/dist/ai/manifest/components/BbDropdownButton.tree.json +28 -0
  120. package/dist/ai/manifest/components/BbDropdownGroup.json +25 -0
  121. package/dist/ai/manifest/components/BbDropzone.json +66 -0
  122. package/dist/ai/manifest/components/BbDropzone.tree.json +35 -0
  123. package/dist/ai/manifest/components/BbForm.json +41 -0
  124. package/dist/ai/manifest/components/BbIcon.json +33 -0
  125. package/dist/ai/manifest/components/BbIcon.tree.json +19 -0
  126. package/dist/ai/manifest/components/BbIndicator.json +39 -0
  127. package/dist/ai/manifest/components/BbIndicator.tree.json +67 -0
  128. package/dist/ai/manifest/components/BbNumberInput.json +121 -0
  129. package/dist/ai/manifest/components/BbNumberInput.tree.json +27 -0
  130. package/dist/ai/manifest/components/BbOffCanvas.json +72 -0
  131. package/dist/ai/manifest/components/BbOffCanvas.tree.json +115 -0
  132. package/dist/ai/manifest/components/BbPagination.json +61 -0
  133. package/dist/ai/manifest/components/BbPagination.tree.json +69 -0
  134. package/dist/ai/manifest/components/BbPopover.json +81 -0
  135. package/dist/ai/manifest/components/BbPopover.tree.json +36 -0
  136. package/dist/ai/manifest/components/BbProgress.json +31 -0
  137. package/dist/ai/manifest/components/BbProgress.tree.json +25 -0
  138. package/dist/ai/manifest/components/BbPtScope.json +21 -0
  139. package/dist/ai/manifest/components/BbRadio.json +86 -0
  140. package/dist/ai/manifest/components/BbRadio.tree.json +22 -0
  141. package/dist/ai/manifest/components/BbRadioGroup.json +126 -0
  142. package/dist/ai/manifest/components/BbRadioGroup.tree.json +52 -0
  143. package/dist/ai/manifest/components/BbRating.json +98 -0
  144. package/dist/ai/manifest/components/BbRating.tree.json +55 -0
  145. package/dist/ai/manifest/components/BbSelect.json +170 -0
  146. package/dist/ai/manifest/components/BbSelect.tree.json +53 -0
  147. package/dist/ai/manifest/components/BbSelectPopover.json +122 -0
  148. package/dist/ai/manifest/components/BbSelectPopover.tree.json +108 -0
  149. package/dist/ai/manifest/components/BbSlider.json +107 -0
  150. package/dist/ai/manifest/components/BbSlider.tree.json +89 -0
  151. package/dist/ai/manifest/components/BbSmoothHeight.json +31 -0
  152. package/dist/ai/manifest/components/BbSmoothHeight.tree.json +16 -0
  153. package/dist/ai/manifest/components/BbSpinner.json +31 -0
  154. package/dist/ai/manifest/components/BbSpinner.tree.json +31 -0
  155. package/dist/ai/manifest/components/BbSwitch.json +97 -0
  156. package/dist/ai/manifest/components/BbSwitch.tree.json +22 -0
  157. package/dist/ai/manifest/components/BbSwitchGroup.json +127 -0
  158. package/dist/ai/manifest/components/BbSwitchGroup.tree.json +52 -0
  159. package/dist/ai/manifest/components/BbTable.json +150 -0
  160. package/dist/ai/manifest/components/BbTable.tree.json +199 -0
  161. package/dist/ai/manifest/components/BbTabs.json +83 -0
  162. package/dist/ai/manifest/components/BbTabs.tree.json +88 -0
  163. package/dist/ai/manifest/components/BbTabsList.json +47 -0
  164. package/dist/ai/manifest/components/BbTabsList.tree.json +94 -0
  165. package/dist/ai/manifest/components/BbTabsPanels.json +32 -0
  166. package/dist/ai/manifest/components/BbTabsPanels.tree.json +69 -0
  167. package/dist/ai/manifest/components/BbTabsRoot.json +61 -0
  168. package/dist/ai/manifest/components/BbTag.json +128 -0
  169. package/dist/ai/manifest/components/BbTag.tree.json +40 -0
  170. package/dist/ai/manifest/components/BbTextInput.json +122 -0
  171. package/dist/ai/manifest/components/BbTextInput.tree.json +27 -0
  172. package/dist/ai/manifest/components/BbTextarea.json +117 -0
  173. package/dist/ai/manifest/components/BbTextarea.tree.json +37 -0
  174. package/dist/ai/manifest/components/BbTimePicker.json +76 -0
  175. package/dist/ai/manifest/components/BbTimePicker.tree.json +37 -0
  176. package/dist/ai/manifest/components/BbTimePickerInput.json +131 -0
  177. package/dist/ai/manifest/components/BbTimePickerInput.tree.json +44 -0
  178. package/dist/ai/manifest/components/BbToast.json +43 -0
  179. package/dist/ai/manifest/components/BbToast.tree.json +91 -0
  180. package/dist/ai/manifest/components/BbToastPortal.json +18 -0
  181. package/dist/ai/manifest/components/BbTooltip.json +60 -0
  182. package/dist/ai/manifest/components/BbTooltip.tree.json +41 -0
  183. package/dist/ai/manifest/components/BbTree.json +51 -0
  184. package/dist/ai/manifest/components/BbTree.tree.json +31 -0
  185. package/dist/ai/manifest/components/ChipsBox.json +32 -0
  186. package/dist/ai/manifest/components/ChipsBox.tree.json +11 -0
  187. package/dist/ai/manifest/components/ClearableButton.json +19 -0
  188. package/dist/ai/manifest/components/ClearableButton.tree.json +19 -0
  189. package/dist/ai/manifest/components/CommaBox.json +30 -0
  190. package/dist/ai/manifest/components/CommonField.json +53 -0
  191. package/dist/ai/manifest/components/CommonField.tree.json +92 -0
  192. package/dist/ai/manifest/components/CommonFieldInput.json +47 -0
  193. package/dist/ai/manifest/components/CommonFieldInput.tree.json +95 -0
  194. package/dist/ai/manifest/components/CommonPopover.json +44 -0
  195. package/dist/ai/manifest/components/CommonPopover.tree.json +26 -0
  196. package/dist/ai/manifest/components/CommonTimeSelector.json +31 -0
  197. package/dist/ai/manifest/components/CommonTimeSelector.tree.json +43 -0
  198. package/dist/ai/manifest/components/ErrorIcon.json +17 -0
  199. package/dist/ai/manifest/components/ErrorIcon.tree.json +22 -0
  200. package/dist/ai/manifest/components/FlatListBox.json +42 -0
  201. package/dist/ai/manifest/components/FlatListBox.tree.json +15 -0
  202. package/dist/ai/manifest/components/GroupedListBox.json +44 -0
  203. package/dist/ai/manifest/components/GroupedListBox.tree.json +15 -0
  204. package/dist/ai/manifest/components/GuidesComponent.json +17 -0
  205. package/dist/ai/manifest/components/ListBox.json +42 -0
  206. package/dist/ai/manifest/components/ListBox.tree.json +9 -0
  207. package/dist/ai/manifest/components/OptionsContainer.json +41 -0
  208. package/dist/ai/manifest/components/WarningIcon.json +17 -0
  209. package/dist/ai/manifest/components/WarningIcon.tree.json +22 -0
  210. package/dist/ai/manifest/index.json +118 -0
  211. package/dist/ai/manifest/meta.json +430 -0
  212. package/dist/ai/manifest/types.advanced.json +55 -0
  213. package/dist/ai/manifest/types.api.json +43 -0
  214. package/dist/ai/manifest/types.wrapper.json +115 -0
  215. package/dist/ai/recipes/inertia/record-form.md +1 -1
  216. package/dist/ai/recipes/inertia/settings-workspace.md +94 -70
  217. package/dist/ai/recipes/nuxt/record-form.md +1 -1
  218. package/dist/ai/recipes/nuxt/settings-workspace.md +93 -67
  219. package/dist/ai/recipes/vue/record-form.md +1 -1
  220. package/dist/ai/recipes/vue/settings-workspace.md +93 -67
  221. package/dist/ai/source/BbButton.md +55 -10
  222. package/dist/ai/source/BbForm.md +105 -4
  223. package/dist/ai/source/BbRating.md +10 -0
  224. package/dist/ai/source/BbTextarea.md +13 -5
  225. package/dist/ai/source/CommonField.md +74 -0
  226. package/dist/components/BbForm/BbForm.vue.d.ts +16 -0
  227. package/dist/components/BbForm/BbForm.vue_vue_type_script_setup_true_lang.js +130 -96
  228. package/dist/components/BbForm/BbFormCustomField.js +33 -27
  229. package/dist/components/BbForm/bindFormField.js +1 -0
  230. package/dist/components/BbForm/formFields.d.ts +9 -1
  231. package/dist/components/BbRating/BbRating.vue_vue_type_script_setup_true_lang.js +4 -2
  232. package/dist/components/BbTextarea/BbTextarea.vue_vue_type_script_setup_true_lang.js +2 -2
  233. package/dist/composables/useBbFormContext.d.ts +15 -4
  234. package/dist/composables/useBbFormContext.js +18 -5
  235. package/dist/llms-full.txt +719 -355
  236. package/dist/llms-medium.txt +12 -9
  237. package/dist/llms.txt +2 -2
  238. package/dist/styles.css +2 -2
  239. package/dist/utils/versionCheck.js +1 -1
  240. package/llms.txt +2 -2
  241. package/package.json +1 -1
  242. package/scripts/lib/agent-manifest.mjs +509 -0
  243. package/scripts/lib/css-color-resolve.mjs +128 -4
  244. package/scripts/lib/design-token-manifest.mjs +11 -4
  245. package/scripts/lib/manifest-pointers.mjs +71 -0
package/README.md CHANGED
@@ -127,7 +127,7 @@ magnitude, not a contract.
127
127
 
128
128
  - [Core knowledge base](https://llms-bitboss-ui.bitboss.it/dist/llms-medium.txt) (about 200 KB) — **start here if you can only fetch one file.** Hard rules, setup, component picker, design language, and the full component catalogue.
129
129
  - [Index](https://llms-bitboss-ui.bitboss.it/llms.txt) (about 20 KB) — link index into every document.
130
- - [components.json](https://llms-bitboss-ui.bitboss.it/dist/ai/components.json) — machine-readable API surface, for programmatic validation.
130
+ - [Component API files](https://llms-bitboss-ui.bitboss.it/dist/ai/manifest/index.json) — machine-readable API, one file per component (`manifest/components/<Name>.json`), each one read. The same data in one file for tools: [components.json](https://llms-bitboss-ui.bitboss.it/dist/ai/components.json) (about 1.2 MB).
131
131
  - [Complete knowledge base](https://llms-bitboss-ui.bitboss.it/dist/llms-full.txt) (about 5 MB) — everything concatenated. Bulk ingestion only; too large to prompt with.
132
132
 
133
133
  Already installed? Prefer the local copy under `node_modules/bitboss-ui/dist/ai/`,
@@ -617,7 +617,8 @@ A standard `llms.txt` discovery file is also published at:
617
617
  | ------------------------------------- | ------------------------------------------------------------------------------------ |
618
618
  | `dist/ai/guides/ai-router.md` | **Start here** — which file to open next |
619
619
  | `dist/ai/index.md` | Full catalogue + agent rules |
620
- | `dist/ai/components.json` | Machine-readable API (props/events/slots) |
620
+ | `dist/ai/manifest/index.json` | Machine-readable API for agents: the component list → `components/<Name>.json` |
621
+ | `dist/ai/components.json` | The same API in one file, for tools (`check`, ESLint, MCP) |
621
622
  | `dist/ai/<ComponentName>.md` | Guide-first contract per component |
622
623
  | `dist/ai/composables/<name>.md` | Composable docs |
623
624
  | `dist/ai/guides/agent-contract.md` | Mandatory agent rules |
@@ -636,6 +637,7 @@ files directly:
636
637
  | ----------------------------------- | ------------------------------ |
637
638
  | `bitboss-ui/ai` | `dist/ai/index.md` (catalogue) |
638
639
  | `bitboss-ui/ai/components.json` | `dist/ai/components.json` |
640
+ | `bitboss-ui/ai/manifest/index.json` | `dist/ai/manifest/index.json` |
639
641
  | `bitboss-ui/ai/guides/ai-router.md` | `dist/ai/guides/ai-router.md` |
640
642
 
641
643
  Agents can also read paths under `node_modules/bitboss-ui/dist/ai/` directly.
@@ -31,7 +31,7 @@
31
31
 
32
32
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
33
33
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
34
- import { existsSync, readFileSync, readdirSync } from 'node:fs';
34
+ import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
35
35
  import { dirname, join, sep } from 'node:path';
36
36
  import { fileURLToPath } from 'node:url';
37
37
  import { z } from 'zod';
@@ -48,6 +48,10 @@ import {
48
48
  possessive,
49
49
  validateVueSnippet,
50
50
  } from '../scripts/lib/validate-bb-markup.mjs';
51
+ import {
52
+ agentComponent,
53
+ firstSentence,
54
+ } from '../scripts/lib/agent-manifest.mjs';
51
55
 
52
56
  const PACKAGE_ROOT = join(dirname(fileURLToPath(import.meta.url)), '..');
53
57
  const AI_ROOT = join(PACKAGE_ROOT, 'dist', 'ai');
@@ -65,19 +69,38 @@ function packageVersion() {
65
69
  }
66
70
  }
67
71
 
72
+ /*
73
+ * Parsed once per build of components.json (Q56.46): the 1.2 MB file was
74
+ * re-read and re-parsed on every tool call. Both caches below (the raw
75
+ * manifest for the lookup tools, the validator's map for `validate`) are
76
+ * keyed on the file's mtime, so a rebuild under a running server (library
77
+ * repo, `npm run build`) is picked up by every tool.
78
+ */
79
+ let cachedManifest = null;
68
80
  function loadComponentsManifest() {
69
81
  if (!existsSync(MANIFEST_PATH)) {
70
82
  throw new Error(
71
83
  `components.json not found at ${MANIFEST_PATH} — reinstall bitboss-ui (or run \`npm run build\` when working in the library repo).`
72
84
  );
73
85
  }
74
- return JSON.parse(readFileSync(MANIFEST_PATH, 'utf-8'));
86
+ const mtime = statSync(MANIFEST_PATH).mtimeMs;
87
+ if (cachedManifest?.mtime !== mtime)
88
+ cachedManifest = {
89
+ mtime,
90
+ value: JSON.parse(readFileSync(MANIFEST_PATH, 'utf-8')),
91
+ };
92
+ return cachedManifest.value;
75
93
  }
76
94
 
77
95
  let cachedManifestMap = null;
78
96
  function getManifestMap() {
79
- cachedManifestMap ??= loadManifest(MANIFEST_PATH);
80
- return cachedManifestMap;
97
+ // Missing file: loadManifest throws the install hint.
98
+ const mtime = existsSync(MANIFEST_PATH)
99
+ ? statSync(MANIFEST_PATH).mtimeMs
100
+ : null;
101
+ if (cachedManifestMap?.mtime !== mtime || mtime === null)
102
+ cachedManifestMap = { mtime, value: loadManifest(MANIFEST_PATH) };
103
+ return cachedManifestMap.value;
81
104
  }
82
105
 
83
106
  /** `search_components({ query })` — token match over name/description. */
@@ -745,43 +768,9 @@ const SUMMARY_SECTIONS = [/^gotchas/i];
745
768
  * keeps EVERY name (a partial prop list is what makes agents invent API) as one
746
769
  * line — name, type, default, the description's first sentence — and marks a
747
770
  * cut sentence with " …": `members: ['name']` returns the full row.
771
+ * `firstSentence` lives in scripts/lib/agent-manifest.mjs: the manifest
772
+ * index (Q56.46) cuts descriptions the same way.
748
773
  */
749
- function firstSentence(text, cap = 160) {
750
- const flat = String(text ?? '')
751
- .replace(/\s+/g, ' ')
752
- .trim();
753
- if (!flat) return '';
754
- // A sentence ends at ". " before a capital, a backtick or a bracket — not
755
- // inside "1.234,56", "v3.0.0" or after "e.g." / "i.e." / "etc.".
756
- const ends = [...flat.matchAll(/[.!?](?=\s+[A-Z`([]|$)/g)]
757
- .map((m) => m.index)
758
- .filter((i) => !/\b(e\.g|i\.e|etc|vs|approx)$/i.test(flat.slice(0, i)));
759
- let stop = ends[0] ?? flat.length - 1;
760
- // A second sentence that limits the first ("Only …", "Ignored with …",
761
- // "Not called in …") changes what the first one means: keep it.
762
- const next = flat.slice(stop + 1).trim();
763
- if (
764
- ends[1] != null &&
765
- /^(Only|Not|Never|Ignored|Mutually|Takes precedence|Requires|Must|Has no effect|Without|Unless|Deprecated|Wins over|Overrides)\b/.test(
766
- next
767
- )
768
- )
769
- stop = ends[1];
770
- // A short, generic first sentence ("The id.") says little: add the next.
771
- if (stop + 1 < 60 && ends[ends.indexOf(stop) + 1] != null)
772
- stop = ends[ends.indexOf(stop) + 1];
773
- let out = flat.slice(0, stop + 1);
774
- if (out.length > cap) {
775
- let cut = out.lastIndexOf(' ', cap);
776
- if (cut < 40) cut = cap;
777
- let head = out.slice(0, cut);
778
- // Never end inside a code span: an unpaired backtick reads as code.
779
- if ((head.match(/`/g) ?? []).length % 2)
780
- head = head.slice(0, head.lastIndexOf('`')).trimEnd();
781
- out = `${head} …`;
782
- } else if (out.length < flat.length) out += ' …';
783
- return out;
784
- }
785
774
 
786
775
  /** A type as the summary prints it: no ` | undefined` tail, long ones cut. */
787
776
  function shortType(type, cap = 180) {
@@ -1293,30 +1282,42 @@ function getComponent({
1293
1282
  };
1294
1283
  }
1295
1284
 
1285
+ /*
1286
+ * The whole entry is the shipped agent file, dist/ai/manifest/components/
1287
+ * <Name>.json (Q56.46: one builder), with the MCP's own compaction on top:
1288
+ * the types go in the answer's `types` (with import lines), the cssProps
1289
+ * as names, the register as one history line per old name.
1290
+ */
1291
+ const { types: _agentTypes, ...agent } = agentComponent(entry, manifest);
1296
1292
  const component = {
1297
- ...entry,
1298
- props: (wanted.has('ptProps')
1299
- ? entry.props
1300
- : entry.props.filter((p) => !ptRows.includes(p))
1301
- ).map(({ required, ...prop }) => (required ? { ...prop, required } : prop)),
1302
- ...(entry.cssProps && !wanted.has('cssProps')
1303
- ? { cssProps: entry.cssProps.map((c) => c.name ?? c) }
1293
+ ...agent,
1294
+ ...(wanted.has('ptProps')
1295
+ ? {
1296
+ props: entry.props.map(({ required, ...prop }) =>
1297
+ required ? { ...prop, required } : prop
1298
+ ),
1299
+ }
1300
+ : {}),
1301
+ ...(entry.cssProps
1302
+ ? {
1303
+ cssProps: wanted.has('cssProps')
1304
+ ? entry.cssProps
1305
+ : entry.cssProps.map((c) => c.name ?? c),
1306
+ }
1304
1307
  : {}),
1308
+ ...(wanted.has('tree') && entry.tree ? { tree: entry.tree } : {}),
1309
+ // The rendered `.bb-*` classes (Q46.5) are for tools (`check`,
1310
+ // `validate`); an agent restyles through pt and the locals.
1311
+ ...(wanted.has('css') && entry.css ? { css: entry.css } : {}),
1305
1312
  };
1306
- if (!wanted.has('tree')) delete component.tree;
1307
- // The rendered `.bb-*` classes (Q46.5) are for tools (`check`, `validate`);
1308
- // an agent restyles through pt and the locals. include: ['css'] lists them.
1309
- if (!wanted.has('css')) delete component.css;
1310
1313
  // `removed` and `renamed` repeat each other with migration metadata; one
1311
1314
  // line per old name answers "what happened to X" (include 'history' for
1312
1315
  // the records the fixers use).
1313
- if (
1314
- !wanted.has('history') &&
1315
- (entry.removed?.length || entry.renamed?.length)
1316
- ) {
1316
+ if (wanted.has('history')) {
1317
+ if (entry.renamed) component.renamed = entry.renamed;
1318
+ } else if (entry.removed?.length || entry.renamed?.length) {
1317
1319
  component.history = historyLines(entry);
1318
1320
  delete component.removed;
1319
- delete component.renamed;
1320
1321
  }
1321
1322
 
1322
1323
  const always = guide.filter(
@@ -1451,8 +1452,16 @@ function* eachTokenDeclaration(css) {
1451
1452
  const stack = [];
1452
1453
  let buffer = '';
1453
1454
  let quote = null;
1455
+ // Parenthesis depth: CSS `if()` separates its branches with `;`, and a
1456
+ // branch may read `style(--bb-x: …)`. Only a top-level `;` ends a
1457
+ // declaration, and only a name at its START is the property it sets
1458
+ // (Q56.48: `--fg-hover: if(style(--bb-primary-fg: …)…)` was served as a
1459
+ // local rebind of --bb-primary-fg).
1460
+ let depth = 0;
1454
1461
  const declaration = () => {
1455
- const m = buffer.match(/(--bb-[a-z0-9-]+)\s*:\s*([\s\S]+)/);
1462
+ const m = buffer
1463
+ .replace(/\/\*[\s\S]*?\*\//g, '')
1464
+ .match(/^\s*(--bb-[a-z0-9-]+)\s*:\s*([\s\S]+)/);
1456
1465
  buffer = '';
1457
1466
  return m ? { name: m[1], value: m[2].trim() } : null;
1458
1467
  };
@@ -1465,6 +1474,11 @@ function* eachTokenDeclaration(css) {
1465
1474
  if (char === '"' || char === "'") {
1466
1475
  quote = char;
1467
1476
  buffer += char;
1477
+ } else if (char === '(' || char === ')') {
1478
+ depth = Math.max(0, depth + (char === '(' ? 1 : -1));
1479
+ buffer += char;
1480
+ } else if (depth > 0) {
1481
+ buffer += char;
1468
1482
  } else if (char === '{') {
1469
1483
  // A comment before a rule would otherwise prefix its selector or
1470
1484
  // hide the `@supports` it opens.
@@ -131,7 +131,7 @@ function coreRules(version) {
131
131
  1. **Start at the AI Router**: \`${ROUTER}\` — which file to open next (do not dump the full catalogue into context).
132
132
  2. **Obey the agent contract**: \`${CONTRACT}\`.
133
133
  3. **Prefer \`Bb*\` consumer components**; never use entries marked "Reference Only - Internal" unless the user explicitly asks for internals. (\`BbBaseButton\` and the \`BbBase*Icon\` glyphs are consumer API; the \`Common*\` building blocks are not.)
134
- 4. **Never invent prop/event/slot names** — open \`${KNOWLEDGE_BASE}/<ComponentName>.md\` (Usage & Guidelines first) or validate against \`${KNOWLEDGE_BASE}/components.json\`.
134
+ 4. **Never invent prop/event/slot names** — open \`${KNOWLEDGE_BASE}/<ComponentName>.md\` (Usage & Guidelines first) or its API file \`${KNOWLEDGE_BASE}/manifest/components/<ComponentName>.json\` (one member per line; the list is \`${KNOWLEDGE_BASE}/manifest/index.json\`). Never read \`components.json\` whole: it is the 1.2 MB file the tools use.
135
135
  5. **Icons**: discover names first; never invent them (\`${KNOWLEDGE_BASE}/guides/icons-policy.md\`).
136
136
  6. **Item-driven components**: declarative \`items\` / \`item-text\` / \`item-value\`, \`dependencies\`, \`enforce-coherence\` — no manual watchers for coherence.
137
137
  7. **Whole pages**: one recipe under \`${KNOWLEDGE_BASE}/recipes/{vue|nuxt|inertia}/\` (see the router table).
@@ -659,7 +659,7 @@ States are listed in precedence order: when two are on at once and their entries
659
659
  - **_internal_** nodes are building blocks with no API of their own: you reach them only through `BbAccordion`. A pt part listed as landing there is set on `BbAccordion` (`pt:<part>`).
660
660
  - **_public_** nodes are components with their own contract. `BbAccordion` reaches one only through a pt part of its own that lands on it (shown on the parent node as `part → Component`, e.g. `spinner → BbSpinner`) or through a pt map it hands it (shown as "hands … the pt map", in `BbAccordion`'s words → the child's). The child's other props and parts are not exposed; its contract explains what it renders.
661
661
  - **CSS custom properties** listed on a node are declared on THAT node's root and read by elements inside it. Set one on that node's root or on the element inside it that reads it — the pt part that lands there is how you reach it (`pt:box="[--border-color:…]"` on a text input) — never on `BbAccordion`'s root, where the node's own declaration masks it (design-tokens guide, _Overriding one from a consumer app_, rule 0).
662
- - Listed nodes are the ones `BbAccordion`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is the `tree` field of this component in `components.json`.
662
+ - Listed nodes are the ones `BbAccordion`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is `manifest/components/BbAccordion.tree.json`.
663
663
 
664
664
  - `BbAccordion` _(this component)_ — its own template binds: `header` → `BbBaseButton`, `panel` → `div.bb-accordion__panel`
665
665
  - `BbBaseButton` _(public — [contract](./BbBaseButton.md))_ — its own pt parts (`BbBaseButton`): `root` → `RouterComponent`, `root` → `a`, `root` → `component`; also mounts `RouterComponent`
@@ -519,7 +519,7 @@ Set these on the element, or on a class you put on it, to retune this component
519
519
  - **_internal_** nodes are building blocks with no API of their own: you reach them only through `BbAlert`. A pt part listed as landing there is set on `BbAlert` (`pt:<part>`).
520
520
  - **_public_** nodes are components with their own contract. `BbAlert` reaches one only through a pt part of its own that lands on it (shown on the parent node as `part → Component`, e.g. `spinner → BbSpinner`) or through a pt map it hands it (shown as "hands … the pt map", in `BbAlert`'s words → the child's). The child's other props and parts are not exposed; its contract explains what it renders.
521
521
  - **CSS custom properties** listed on a node are declared on THAT node's root and read by elements inside it. Set one on that node's root or on the element inside it that reads it — the pt part that lands there is how you reach it (`pt:box="[--border-color:…]"` on a text input) — never on `BbAlert`'s root, where the node's own declaration masks it (design-tokens guide, _Overriding one from a consumer app_, rule 0).
522
- - Listed nodes are the ones `BbAlert`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is the `tree` field of this component in `components.json`.
522
+ - Listed nodes are the ones `BbAlert`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is `manifest/components/BbAlert.tree.json`.
523
523
 
524
524
  - `BbAlert` _(this component)_ — its own template binds: `icon` → `BbIcon`, `close` → `ClearableButton`, `title` → `div.bb-alert__title`, `text` → `div.bb-alert__text`
525
525
  - Also mounts `BbIcon`, `ClearableButton`
@@ -646,7 +646,7 @@ Set these on the element, or on a class you put on it, to retune this component
646
646
  - **_internal_** nodes are building blocks with no API of their own: you reach them only through `BbAvatar`. A pt part listed as landing there is set on `BbAvatar` (`pt:<part>`).
647
647
  - **_public_** nodes are components with their own contract. `BbAvatar` reaches one only through a pt part of its own that lands on it (shown on the parent node as `part → Component`, e.g. `spinner → BbSpinner`) or through a pt map it hands it (shown as "hands … the pt map", in `BbAvatar`'s words → the child's). The child's other props and parts are not exposed; its contract explains what it renders.
648
648
  - **CSS custom properties** listed on a node are declared on THAT node's root and read by elements inside it. Set one on that node's root or on the element inside it that reads it — the pt part that lands there is how you reach it (`pt:box="[--border-color:…]"` on a text input) — never on `BbAvatar`'s root, where the node's own declaration masks it (design-tokens guide, _Overriding one from a consumer app_, rule 0).
649
- - Listed nodes are the ones `BbAvatar`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is the `tree` field of this component in `components.json`.
649
+ - Listed nodes are the ones `BbAvatar`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is `manifest/components/BbAvatar.tree.json`.
650
650
 
651
651
  - `BbAvatar` _(this component)_ — its own template binds: `icon` → `BbIcon`
652
652
  - Also mounts `BbIcon`
@@ -923,7 +923,7 @@ Set these on the element, or on a class you put on it, to retune this component
923
923
  - **_internal_** nodes are building blocks with no API of their own: you reach them only through `BbBadge`. A pt part listed as landing there is set on `BbBadge` (`pt:<part>`).
924
924
  - **_public_** nodes are components with their own contract. `BbBadge` reaches one only through a pt part of its own that lands on it (shown on the parent node as `part → Component`, e.g. `spinner → BbSpinner`) or through a pt map it hands it (shown as "hands … the pt map", in `BbBadge`'s words → the child's). The child's other props and parts are not exposed; its contract explains what it renders.
925
925
  - **CSS custom properties** listed on a node are declared on THAT node's root and read by elements inside it. Set one on that node's root or on the element inside it that reads it — the pt part that lands there is how you reach it (`pt:box="[--border-color:…]"` on a text input) — never on `BbBadge`'s root, where the node's own declaration masks it (design-tokens guide, _Overriding one from a consumer app_, rule 0).
926
- - Listed nodes are the ones `BbBadge`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is the `tree` field of this component in `components.json`.
926
+ - Listed nodes are the ones `BbBadge`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is `manifest/components/BbBadge.tree.json`.
927
927
 
928
928
  - `BbBadge` _(this component)_ — its own template binds: `spinner` → `BbSpinner`, `icon` → `BbIcon`, `clear` → `button.bb-badge__clear`
929
929
  - Also mounts `BbIcon`, `BbSpinner`, `BadgeBodyContent`
@@ -111,7 +111,7 @@ Set these on the element, or on a class you put on it, to retune this component
111
111
  - **_internal_** nodes are building blocks with no API of their own: you reach them only through `BbBadgeButton`. A pt part listed as landing there is set on `BbBadgeButton` (`pt:<part>`).
112
112
  - **_public_** nodes are components with their own contract. `BbBadgeButton` reaches one only through a pt part of its own that lands on it (shown on the parent node as `part → Component`, e.g. `spinner → BbSpinner`) or through a pt map it hands it (shown as "hands … the pt map", in `BbBadgeButton`'s words → the child's). The child's other props and parts are not exposed; its contract explains what it renders.
113
113
  - **CSS custom properties** listed on a node are declared on THAT node's root and read by elements inside it. Set one on that node's root or on the element inside it that reads it — the pt part that lands there is how you reach it (`pt:box="[--border-color:…]"` on a text input) — never on `BbBadgeButton`'s root, where the node's own declaration masks it (design-tokens guide, _Overriding one from a consumer app_, rule 0).
114
- - Listed nodes are the ones `BbBadgeButton`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is the `tree` field of this component in `components.json`.
114
+ - Listed nodes are the ones `BbBadgeButton`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is `manifest/components/BbBadgeButton.tree.json`.
115
115
 
116
116
  - `BbBadgeButton` _(this component)_
117
117
  - `BbBaseButton` _(public — [contract](./BbBaseButton.md))_ — its own pt parts (`BbBaseButton`): `root` → `RouterComponent`, `root` → `a`, `root` → `component`; also mounts `RouterComponent`
@@ -582,7 +582,7 @@ States are listed in precedence order: when two are on at once and their entries
582
582
  - **_internal_** nodes are building blocks with no API of their own: you reach them only through `BbBaseButton`. A pt part listed as landing there is set on `BbBaseButton` (`pt:<part>`).
583
583
  - **_public_** nodes are components with their own contract. `BbBaseButton` reaches one only through a pt part of its own that lands on it (shown on the parent node as `part → Component`, e.g. `spinner → BbSpinner`) or through a pt map it hands it (shown as "hands … the pt map", in `BbBaseButton`'s words → the child's). The child's other props and parts are not exposed; its contract explains what it renders.
584
584
  - **CSS custom properties** listed on a node are declared on THAT node's root and read by elements inside it. Set one on that node's root or on the element inside it that reads it — the pt part that lands there is how you reach it (`pt:box="[--border-color:…]"` on a text input) — never on `BbBaseButton`'s root, where the node's own declaration masks it (design-tokens guide, _Overriding one from a consumer app_, rule 0).
585
- - Listed nodes are the ones `BbBaseButton`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is the `tree` field of this component in `components.json`.
585
+ - Listed nodes are the ones `BbBaseButton`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is `manifest/components/BbBaseButton.tree.json`.
586
586
 
587
587
  - `BbBaseButton` _(this component)_ — its own template binds: `root` → `RouterComponent`, `root` → `a`, `root` → `component`
588
588
  - Also mounts `RouterComponent`
@@ -742,7 +742,7 @@ States are listed in precedence order: when two are on at once and their entries
742
742
  - **_internal_** nodes are building blocks with no API of their own: you reach them only through `BbBreadcrumbs`. A pt part listed as landing there is set on `BbBreadcrumbs` (`pt:<part>`).
743
743
  - **_public_** nodes are components with their own contract. `BbBreadcrumbs` reaches one only through a pt part of its own that lands on it (shown on the parent node as `part → Component`, e.g. `spinner → BbSpinner`) or through a pt map it hands it (shown as "hands … the pt map", in `BbBreadcrumbs`'s words → the child's). The child's other props and parts are not exposed; its contract explains what it renders.
744
744
  - **CSS custom properties** listed on a node are declared on THAT node's root and read by elements inside it. Set one on that node's root or on the element inside it that reads it — the pt part that lands there is how you reach it (`pt:box="[--border-color:…]"` on a text input) — never on `BbBreadcrumbs`'s root, where the node's own declaration masks it (design-tokens guide, _Overriding one from a consumer app_, rule 0).
745
- - Listed nodes are the ones `BbBreadcrumbs`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is the `tree` field of this component in `components.json`.
745
+ - Listed nodes are the ones `BbBreadcrumbs`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is `manifest/components/BbBreadcrumbs.tree.json`.
746
746
 
747
747
  - `BbBreadcrumbs` _(this component)_ — its own template binds: `item` → `li.bb-breadcrumbs__item`, `icon` → `BbIcon`, `text` → `span.bb-breadcrumbs__text`
748
748
  - `BbBaseButton` _(public — [contract](./BbBaseButton.md))_ — its own pt parts (`BbBaseButton`): `root` → `RouterComponent`, `root` → `a`, `root` → `component`; also mounts `RouterComponent`
@@ -109,13 +109,41 @@ restate a state:
109
109
  ```css
110
110
  .bb-button--upgrade {
111
111
  --bg: var(--bb-primary);
112
- --bg-hover: color-mix(in oklab, var(--bb-primary) 90%, black);
113
- --bg-pressed: color-mix(in oklab, var(--bb-primary) 80%, var(--bb-text));
112
+ --bg-hover: var(--bb-primary-hover);
113
+ --bg-pressed: var(--bb-primary-pressed);
114
114
  --fg: var(--bb-primary-fg);
115
115
  --ring-color: var(--bb-ring);
116
116
  }
117
117
  ```
118
118
 
119
+ The primary's hover is one 1.25:1 luminance step away from the panel
120
+ (darker in light, lighter in dark), turning toward the panel only when the
121
+ primary has no room left, as the default black in light and white in dark
122
+ do: hover is always visible and never sinks into the surface. Pressed takes
123
+ the same move with a larger 1.6:1 step, so it is always the strongest state
124
+ and never equals rest, and a pressed toggle keeps its pressed fill under
125
+ keyboard focus, with the focus ring still showing. The built-in primary
126
+ moves its frame with the hover and pressed fills and,
127
+ where `contrast-color()` exists, picks each state's label for its own fill
128
+ (a white label on a mid blue can turn dark on the lighter dark-scheme
129
+ hover). That is only the default: a pinned `--bb-primary-fg` paints the
130
+ hover and pressed labels too. One limit: a pin that equals the automatic
131
+ pick (white on a blue that already picks white) reads as automatic, so on a
132
+ lighter dark-scheme hover or pressed fill the label still turns dark. To
133
+ keep your pin on every state, point the state labels at it:
134
+
135
+ ```css
136
+ .bb-button--primary {
137
+ --fg-hover: var(--bb-primary-fg);
138
+ --fg-pressed: var(--bb-primary-fg);
139
+ }
140
+ ```
141
+
142
+ The same two lines apply where the browser has `contrast-color()` but not
143
+ CSS `if()`, where pins never reach the hover and pressed labels
144
+ (design-tokens.md § `--bb-primary-fg` auto-contrasts). The measurements are
145
+ in design-tokens.md § The state recipe.
146
+
119
147
  Every state has the full trio. Hover and pressed also take `--fg-hover` /
120
148
  `--border-hover` and `--fg-pressed` / `--border-pressed` (both default to the
121
149
  resting `--fg` / `--border-color`, so only the fill moves unless you say
@@ -1217,7 +1245,7 @@ Set these on the element, or on a class you put on it, to retune this component
1217
1245
  - **_internal_** nodes are building blocks with no API of their own: you reach them only through `BbButton`. A pt part listed as landing there is set on `BbButton` (`pt:<part>`).
1218
1246
  - **_public_** nodes are components with their own contract. `BbButton` reaches one only through a pt part of its own that lands on it (shown on the parent node as `part → Component`, e.g. `spinner → BbSpinner`) or through a pt map it hands it (shown as "hands … the pt map", in `BbButton`'s words → the child's). The child's other props and parts are not exposed; its contract explains what it renders.
1219
1247
  - **CSS custom properties** listed on a node are declared on THAT node's root and read by elements inside it. Set one on that node's root or on the element inside it that reads it — the pt part that lands there is how you reach it (`pt:box="[--border-color:…]"` on a text input) — never on `BbButton`'s root, where the node's own declaration masks it (design-tokens guide, _Overriding one from a consumer app_, rule 0).
1220
- - Listed nodes are the ones `BbButton`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is the `tree` field of this component in `components.json`.
1248
+ - Listed nodes are the ones `BbButton`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is `manifest/components/BbButton.tree.json`.
1221
1249
 
1222
1250
  - `BbButton` _(this component)_ — its own template binds: `root` → `BbBaseButton`, `spinner` → `BbSpinner`, `icon` → `BbIcon`, `text` → `span.bb-button__text`
1223
1251
  - `BbBaseButton` _(public — [contract](./BbBaseButton.md))_ — its own pt parts (`BbBaseButton`): `root` → `RouterComponent`, `root` → `a`, `root` → `component`; also mounts `RouterComponent`
@@ -662,7 +662,7 @@ Set these on the element, or on a class you put on it, to retune this component
662
662
  - **_internal_** nodes are building blocks with no API of their own: you reach them only through `BbCalendar`. A pt part listed as landing there is set on `BbCalendar` (`pt:<part>`).
663
663
  - **_public_** nodes are components with their own contract. `BbCalendar` reaches one only through a pt part of its own that lands on it (shown on the parent node as `part → Component`, e.g. `spinner → BbSpinner`) or through a pt map it hands it (shown as "hands … the pt map", in `BbCalendar`'s words → the child's). The child's other props and parts are not exposed; its contract explains what it renders.
664
664
  - **CSS custom properties** listed on a node are declared on THAT node's root and read by elements inside it. Set one on that node's root or on the element inside it that reads it — the pt part that lands there is how you reach it (`pt:box="[--border-color:…]"` on a text input) — never on `BbCalendar`'s root, where the node's own declaration masks it (design-tokens guide, _Overriding one from a consumer app_, rule 0).
665
- - Listed nodes are the ones `BbCalendar`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is the `tree` field of this component in `components.json`.
665
+ - Listed nodes are the ones `BbCalendar`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is `manifest/components/BbCalendar.tree.json`.
666
666
 
667
667
  - `BbCalendar` _(this component)_ — its own template binds: `header` → `div.bb-calendar__header`, `arrow` → `BbBaseButton`, `month` → `BbBaseButton`, `year` → `BbBaseButton`, `day` → `div.bb-calendar__day`, `dayButton` → `button.bb-calendar__day-button`
668
668
  - `BbBaseButton` _(public — [contract](./BbBaseButton.md))_ — its own pt parts (`BbBaseButton`): `root` → `RouterComponent`, `root` → `a`, `root` → `component`; also mounts `RouterComponent`
@@ -29,6 +29,7 @@
29
29
  | `--ring-color` | `pt:icon` | `BbBaseCheckboxIcon` | The focus ring's colour, re-pointed by errors and warnings. Both ring declarations read it, so a focused glyph grows its ring in its own colour instead of tweening from a different one. |
30
30
  | `--elev` | `pt:icon` | `BbBaseCheckboxIcon` | Resting lift; a no-op until a theme pins `--bb-elev`. |
31
31
  | `--bg` | `pt:icon` | `BbBaseCheckboxIcon` | 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's fill, which happens to match at the shipped default and would diverge the moment anyone writes `.my-table { --bg: … }`. Identical to the raw tokens it replaces at every theme. |
32
+ | `--ctrl-line` | `pt:label` | `CommonField` | * First-line alignment of side-by-side fields (Q56.44) * ----------------------------------------------------------------- * In a side-by-side layout the label's FIRST line sits on the control's * first line: the text line of a box, the glyph of a toggle, the first * option of a group. Both sides are anchored to the top of the row, so a * taller label column (a description, a wrapped label) never pulls the * control down to its middle; then whichever side's first line is higher * is pushed down by the difference. * * `--ctrl-line` is where the control's first line is centred, from the * top of the control column: half the box height here, and each control * whose first line sits elsewhere (a textarea, a toggle, a group, the * stars) declares its own on the field root. The label's is half its * line box, `--bb-label-lh`. All of it is tokens, so compact and a * custom scale follow. |
32
33
 
33
34
  ## Usage & Guidelines
34
35
 
@@ -768,10 +769,10 @@ States are listed in precedence order: when two are on at once and their entries
768
769
  - **_internal_** nodes are building blocks with no API of their own: you reach them only through `BbCheckbox`. A pt part listed as landing there is set on `BbCheckbox` (`pt:<part>`).
769
770
  - **_public_** nodes are components with their own contract. `BbCheckbox` reaches one only through a pt part of its own that lands on it (shown on the parent node as `part → Component`, e.g. `spinner → BbSpinner`) or through a pt map it hands it (shown as "hands … the pt map", in `BbCheckbox`'s words → the child's). The child's other props and parts are not exposed; its contract explains what it renders.
770
771
  - **CSS custom properties** listed on a node are declared on THAT node's root and read by elements inside it. Set one on that node's root or on the element inside it that reads it — the pt part that lands there is how you reach it (`pt:box="[--border-color:…]"` on a text input) — never on `BbCheckbox`'s root, where the node's own declaration masks it (design-tokens guide, _Overriding one from a consumer app_, rule 0).
771
- - Listed nodes are the ones `BbCheckbox`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is the `tree` field of this component in `components.json`.
772
+ - Listed nodes are the ones `BbCheckbox`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is `manifest/components/BbCheckbox.tree.json`.
772
773
 
773
774
  - `BbCheckbox` _(this component)_ — its own template binds: `icon` → `BbBaseCheckboxIcon`
774
- - `CommonField` _(internal — not importable, reach it through `BbCheckbox`)_ — `BbCheckbox`'s pt parts land here: `root` → `div.bb-field`, `label` → `component`, `description` → `span.bb-field__description`, `hint` → `span.bb-field__hint`, `message` → `div.bb-field__message`; also mounts `BbAsterisk`
775
+ - `CommonField` _(internal — not importable, reach it through `BbCheckbox`)_ — `BbCheckbox`'s pt parts land here: `root` → `div.bb-field`, `label` → `component`, `description` → `span.bb-field__description`, `hint` → `span.bb-field__hint`, `message` → `div.bb-field__message`; documented CSS variables: `--ctrl-line`; also mounts `BbAsterisk`
775
776
  - Also mounts `BbBaseCheckboxIcon`
776
777
 
777
778
  ## See Also
@@ -33,6 +33,7 @@
33
33
  | `--ring-color` | `pt:icon` | `BbBaseCheckboxIcon` | The focus ring's colour, re-pointed by errors and warnings. Both ring declarations read it, so a focused glyph grows its ring in its own colour instead of tweening from a different one. |
34
34
  | `--elev` | `pt:icon` | `BbBaseCheckboxIcon` | Resting lift; a no-op until a theme pins `--bb-elev`. |
35
35
  | `--bg` | `pt:icon` | `BbBaseCheckboxIcon` | 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's fill, which happens to match at the shipped default and would diverge the moment anyone writes `.my-table { --bg: … }`. Identical to the raw tokens it replaces at every theme. |
36
+ | `--ctrl-line` | `pt:label` | `CommonField` | * First-line alignment of side-by-side fields (Q56.44) * ----------------------------------------------------------------- * In a side-by-side layout the label's FIRST line sits on the control's * first line: the text line of a box, the glyph of a toggle, the first * option of a group. Both sides are anchored to the top of the row, so a * taller label column (a description, a wrapped label) never pulls the * control down to its middle; then whichever side's first line is higher * is pushed down by the difference. * * `--ctrl-line` is where the control's first line is centred, from the * top of the control column: half the box height here, and each control * whose first line sits elsewhere (a textarea, a toggle, a group, the * stars) declares its own on the field root. The label's is half its * line box, `--bb-label-lh`. All of it is tokens, so compact and a * custom scale follow. |
36
37
 
37
38
  ## Usage & Guidelines
38
39
 
@@ -1088,10 +1089,10 @@ Set these on the element, or on a class you put on it, to retune this component
1088
1089
  - **_internal_** nodes are building blocks with no API of their own: you reach them only through `BbCheckboxGroup`. A pt part listed as landing there is set on `BbCheckboxGroup` (`pt:<part>`).
1089
1090
  - **_public_** nodes are components with their own contract. `BbCheckboxGroup` reaches one only through a pt part of its own that lands on it (shown on the parent node as `part → Component`, e.g. `spinner → BbSpinner`) or through a pt map it hands it (shown as "hands … the pt map", in `BbCheckboxGroup`'s words → the child's). The child's other props and parts are not exposed; its contract explains what it renders.
1090
1091
  - **CSS custom properties** listed on a node are declared on THAT node's root and read by elements inside it. Set one on that node's root or on the element inside it that reads it — the pt part that lands there is how you reach it (`pt:box="[--border-color:…]"` on a text input) — never on `BbCheckboxGroup`'s root, where the node's own declaration masks it (design-tokens guide, _Overriding one from a consumer app_, rule 0).
1091
- - Listed nodes are the ones `BbCheckboxGroup`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is the `tree` field of this component in `components.json`.
1092
+ - Listed nodes are the ones `BbCheckboxGroup`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is `manifest/components/BbCheckboxGroup.tree.json`.
1092
1093
 
1093
1094
  - `BbCheckboxGroup` _(this component)_ — its own template binds: `icon` → `BbBaseCheckboxIcon`
1094
- - `CommonField` _(internal — not importable, reach it through `BbCheckboxGroup`)_ — `BbCheckboxGroup`'s pt parts land here: `root` → `div.bb-field`, `label` → `component`, `description` → `span.bb-field__description`, `hint` → `span.bb-field__hint`, `message` → `div.bb-field__message`; also mounts `BbAsterisk`
1095
+ - `CommonField` _(internal — not importable, reach it through `BbCheckboxGroup`)_ — `BbCheckboxGroup`'s pt parts land here: `root` → `div.bb-field`, `label` → `component`, `description` → `span.bb-field__description`, `hint` → `span.bb-field__hint`, `message` → `div.bb-field__message`; documented CSS variables: `--ctrl-line`; also mounts `BbAsterisk`
1095
1096
  - `OptionsContainer` _(internal — not importable, reach it through `BbCheckboxGroup`)_ — `BbCheckboxGroup`'s pt parts land here: `list` → `span`, `item` → `label`, `label` → `span`, `itemDescription` → `span`
1096
1097
  - Also mounts `BbBaseCheckboxIcon`
1097
1098
 
@@ -32,6 +32,7 @@
32
32
 
33
33
  | Variable | Set through | Declared by | What it is |
34
34
  | --- | --- | --- | --- |
35
+ | `--ctrl-line` | `pt:label` | `CommonField` | * First-line alignment of side-by-side fields (Q56.44) * ----------------------------------------------------------------- * In a side-by-side layout the label's FIRST line sits on the control's * first line: the text line of a box, the glyph of a toggle, the first * option of a group. Both sides are anchored to the top of the row, so a * taller label column (a description, a wrapped label) never pulls the * control down to its middle; then whichever side's first line is higher * is pushed down by the difference. * * `--ctrl-line` is where the control's first line is centred, from the * top of the control column: half the box height here, and each control * whose first line sits elsewhere (a textarea, a toggle, a group, the * stars) declares its own on the field root. The label's is half its * line box, `--bb-label-lh`. All of it is tokens, so compact and a * custom scale follow. |
35
36
  | `--bg` | `pt:box` | `CommonFieldInput` | the shell's fill |
36
37
  | `--bg-hover` | `pt:box` | `CommonFieldInput` | fill under the pointer |
37
38
  | `--bg-focus` | `pt:box` | `CommonFieldInput` | fill while focus is inside, and under --active |
@@ -796,10 +797,10 @@ Set these on the element, or on a class you put on it, to retune this component
796
797
  - **_internal_** nodes are building blocks with no API of their own: you reach them only through `BbColorInput`. A pt part listed as landing there is set on `BbColorInput` (`pt:<part>`).
797
798
  - **_public_** nodes are components with their own contract. `BbColorInput` reaches one only through a pt part of its own that lands on it (shown on the parent node as `part → Component`, e.g. `spinner → BbSpinner`) or through a pt map it hands it (shown as "hands … the pt map", in `BbColorInput`'s words → the child's). The child's other props and parts are not exposed; its contract explains what it renders.
798
799
  - **CSS custom properties** listed on a node are declared on THAT node's root and read by elements inside it. Set one on that node's root or on the element inside it that reads it — the pt part that lands there is how you reach it (`pt:box="[--border-color:…]"` on a text input) — never on `BbColorInput`'s root, where the node's own declaration masks it (design-tokens guide, _Overriding one from a consumer app_, rule 0).
799
- - Listed nodes are the ones `BbColorInput`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is the `tree` field of this component in `components.json`.
800
+ - Listed nodes are the ones `BbColorInput`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is `manifest/components/BbColorInput.tree.json`.
800
801
 
801
802
  - `BbColorInput` _(this component)_ — its own template binds: `controlAttrs` → `input.bb-color-input__input`, `input` → `input.bb-color-input__input`, `indicator` → `button.bb-color-input__indicator`, `suffix` → `span.bb-field-input__suffix`; hands `BbColorPalette` the pt map `{ panel: 'panel', sheet: 'sheet', swatch: 'swatch' }` (ours → theirs)
802
- - `CommonField` _(internal — not importable, reach it through `BbColorInput`)_ — `BbColorInput`'s pt parts land here: `root` → `div.bb-field`, `label` → `component`, `description` → `span.bb-field__description`, `hint` → `span.bb-field__hint`, `message` → `div.bb-field__message`; also mounts `BbAsterisk`
803
+ - `CommonField` _(internal — not importable, reach it through `BbColorInput`)_ — `BbColorInput`'s pt parts land here: `root` → `div.bb-field`, `label` → `component`, `description` → `span.bb-field__description`, `hint` → `span.bb-field__hint`, `message` → `div.bb-field__message`; documented CSS variables: `--ctrl-line`; also mounts `BbAsterisk`
803
804
  - `CommonFieldInput` _(internal — not importable, reach it through `BbColorInput`)_ — `BbColorInput`'s pt parts land here: `box` → `span.bb-field-input__box`, `prefix` → `span.bb-field-input__prefix`, `icon` → `BbIcon`, `clear` → `ClearableButton`, `spinner` → `BbSpinner`, `suffix` → `span.bb-field-input__suffix`; documented CSS variables: `--bg`, `--bg-hover`, `--bg-focus`, `--bg-disabled`, `--fg-disabled`, `--border-color`, `--border-focus`, `--ring-size`, `--ring-color`, `--elev`, `--frost`, `--inside-label-clearance`; also mounts `ErrorIcon`, `WarningIcon`, `ClearableButton`, `BbIcon`, `BbSpinner`
804
805
  - `BbColorPalette` _(public — [contract](./BbColorPalette.md))_ — its own pt parts (`BbColorPalette`): `swatch` → `button.bb-color-palette__swatch`, `panel` → `div`, `panel` → `CommonPopover`; hands `BbOffCanvas` the pt map `{ panel: 'root', sheet: 'root' }` (ours → theirs); documented CSS variables: `--edge`; also mounts `CommonPopover`
805
806
  - `BbOffCanvas` _(public — [contract](./BbOffCanvas.md))_ — its own pt parts (`BbOffCanvas`): `header` → `div.bb-offcanvas__header`, `title` → `span.bb-offcanvas__title`, `description` → `p.bb-offcanvas__description`, `close` → `CloseButton`, `content` → `div.bb-offcanvas__content`, `footer` → `div.bb-offcanvas__footer`; documented CSS variables: `--stack-x`, `--stack-fill`, `--stack-transition-duration`, `--px`, `--handle-w`, `--handle-h`, `--handle-bg`, `--safe-top`, `--close-size`
@@ -817,7 +817,7 @@ Set these on the element, or on a class you put on it, to retune this component
817
817
  - **_internal_** nodes are building blocks with no API of their own: you reach them only through `BbColorPalette`. A pt part listed as landing there is set on `BbColorPalette` (`pt:<part>`).
818
818
  - **_public_** nodes are components with their own contract. `BbColorPalette` reaches one only through a pt part of its own that lands on it (shown on the parent node as `part → Component`, e.g. `spinner → BbSpinner`) or through a pt map it hands it (shown as "hands … the pt map", in `BbColorPalette`'s words → the child's). The child's other props and parts are not exposed; its contract explains what it renders.
819
819
  - **CSS custom properties** listed on a node are declared on THAT node's root and read by elements inside it. Set one on that node's root or on the element inside it that reads it — the pt part that lands there is how you reach it (`pt:box="[--border-color:…]"` on a text input) — never on `BbColorPalette`'s root, where the node's own declaration masks it (design-tokens guide, _Overriding one from a consumer app_, rule 0).
820
- - Listed nodes are the ones `BbColorPalette`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is the `tree` field of this component in `components.json`.
820
+ - Listed nodes are the ones `BbColorPalette`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is `manifest/components/BbColorPalette.tree.json`.
821
821
 
822
822
  - `BbColorPalette` _(this component)_ — its own template binds: `swatch` → `button.bb-color-palette__swatch`, `panel` → `div`, `panel` → `CommonPopover`; hands `BbOffCanvas` the pt map `{ panel: 'root', sheet: 'root' }` (ours → theirs)
823
823
  - `BbOffCanvas` _(public — [contract](./BbOffCanvas.md))_ — its own pt parts (`BbOffCanvas`): `header` → `div.bb-offcanvas__header`, `title` → `span.bb-offcanvas__title`, `description` → `p.bb-offcanvas__description`, `close` → `CloseButton`, `content` → `div.bb-offcanvas__content`, `footer` → `div.bb-offcanvas__footer`; documented CSS variables: `--stack-x`, `--stack-fill`, `--stack-transition-duration`, `--px`, `--handle-w`, `--handle-h`, `--handle-bg`, `--safe-top`, `--close-size`
@@ -836,7 +836,7 @@ States are listed in precedence order: when two are on at once and their entries
836
836
  - **_internal_** nodes are building blocks with no API of their own: you reach them only through `BbConfirm`. A pt part listed as landing there is set on `BbConfirm` (`pt:<part>`).
837
837
  - **_public_** nodes are components with their own contract. `BbConfirm` reaches one only through a pt part of its own that lands on it (shown on the parent node as `part → Component`, e.g. `spinner → BbSpinner`) or through a pt map it hands it (shown as "hands … the pt map", in `BbConfirm`'s words → the child's). The child's other props and parts are not exposed; its contract explains what it renders.
838
838
  - **CSS custom properties** listed on a node are declared on THAT node's root and read by elements inside it. Set one on that node's root or on the element inside it that reads it — the pt part that lands there is how you reach it (`pt:box="[--border-color:…]"` on a text input) — never on `BbConfirm`'s root, where the node's own declaration masks it (design-tokens guide, _Overriding one from a consumer app_, rule 0).
839
- - Listed nodes are the ones `BbConfirm`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is the `tree` field of this component in `components.json`.
839
+ - Listed nodes are the ones `BbConfirm`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is `manifest/components/BbConfirm.tree.json`.
840
840
 
841
841
  - `BbConfirm` _(this component)_ — its own template binds: `text` → `div.bb-confirm__text`, `action` → `BbButton`; hands `BbDialog` the pt map `passthrough.forward(DIALOG_PARTS, BB_DIALOG_PT.states)` (ours → theirs)
842
842
  - `BbDialog` _(public — [contract](./BbDialog.md))_ — its own pt parts (`BbDialog`): `header` → `div.bb-dialog__header`, `title` → `span.bb-dialog__title`, `description` → `p.bb-dialog__description`, `close` → `CloseButton`, `content` → `div.bb-dialog__content`, `footer` → `div.bb-dialog__footer`; hands `BbOffCanvas` the pt map `{ root: 'root', header: 'header', title: 'title', description: 'description', content: 'content', footer: 'footer', close: 'close', sheet: 'root', }` (ours → theirs); documented CSS variables: `--px`, `--close-size`
@@ -527,7 +527,7 @@ Set these on the element, or on a class you put on it, to retune this component
527
527
  - **_internal_** nodes are building blocks with no API of their own: you reach them only through `BbDatePicker`. A pt part listed as landing there is set on `BbDatePicker` (`pt:<part>`).
528
528
  - **_public_** nodes are components with their own contract. `BbDatePicker` reaches one only through a pt part of its own that lands on it (shown on the parent node as `part → Component`, e.g. `spinner → BbSpinner`) or through a pt map it hands it (shown as "hands … the pt map", in `BbDatePicker`'s words → the child's). The child's other props and parts are not exposed; its contract explains what it renders.
529
529
  - **CSS custom properties** listed on a node are declared on THAT node's root and read by elements inside it. Set one on that node's root or on the element inside it that reads it — the pt part that lands there is how you reach it (`pt:box="[--border-color:…]"` on a text input) — never on `BbDatePicker`'s root, where the node's own declaration masks it (design-tokens guide, _Overriding one from a consumer app_, rule 0).
530
- - Listed nodes are the ones `BbDatePicker`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is the `tree` field of this component in `components.json`.
530
+ - Listed nodes are the ones `BbDatePicker`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is `manifest/components/BbDatePicker.tree.json`.
531
531
 
532
532
  - `BbDatePicker` _(this component)_ — its own template binds: `panel` → `div`, `panel` → `CommonPopover`; hands `BbCalendar` the pt map ` passthrough.forward(DATE_PICKER_CALENDAR_PARTS, BB_CALENDAR_PT.states) ` (ours → theirs); hands `BbOffCanvas` the pt map `{ panel: 'root', sheet: 'root' }` (ours → theirs)
533
533
  - `BbCalendar` _(public — [contract](./BbCalendar.md))_ — its own pt parts (`BbCalendar`): `header` → `div.bb-calendar__header`, `arrow` → `BbBaseButton`, `month` → `BbBaseButton`, `year` → `BbBaseButton`, `day` → `div.bb-calendar__day`, `dayButton` → `button.bb-calendar__day-button`; documented CSS variables: `--cell`, `--unit-row`; also mounts `ScaleFade`, `Slide`, `CalendarMonthPanel`, `CalendarYearPanel`
@@ -29,6 +29,7 @@
29
29
 
30
30
  | Variable | Set through | Declared by | What it is |
31
31
  | --- | --- | --- | --- |
32
+ | `--ctrl-line` | `pt:label` | `CommonField` | * First-line alignment of side-by-side fields (Q56.44) * ----------------------------------------------------------------- * In a side-by-side layout the label's FIRST line sits on the control's * first line: the text line of a box, the glyph of a toggle, the first * option of a group. Both sides are anchored to the top of the row, so a * taller label column (a description, a wrapped label) never pulls the * control down to its middle; then whichever side's first line is higher * is pushed down by the difference. * * `--ctrl-line` is where the control's first line is centred, from the * top of the control column: half the box height here, and each control * whose first line sits elsewhere (a textarea, a toggle, a group, the * stars) declares its own on the field root. The label's is half its * line box, `--bb-label-lh`. All of it is tokens, so compact and a * custom scale follow. |
32
33
  | `--bg` | `pt:box` | `CommonFieldInput` | the shell's fill |
33
34
  | `--bg-hover` | `pt:box` | `CommonFieldInput` | fill under the pointer |
34
35
  | `--bg-focus` | `pt:box` | `CommonFieldInput` | fill while focus is inside, and under --active |
@@ -1000,7 +1001,7 @@ Set these on the element, or on a class you put on it, to retune this component
1000
1001
  - **_internal_** nodes are building blocks with no API of their own: you reach them only through `BbDatePickerInput`. A pt part listed as landing there is set on `BbDatePickerInput` (`pt:<part>`).
1001
1002
  - **_public_** nodes are components with their own contract. `BbDatePickerInput` reaches one only through a pt part of its own that lands on it (shown on the parent node as `part → Component`, e.g. `spinner → BbSpinner`) or through a pt map it hands it (shown as "hands … the pt map", in `BbDatePickerInput`'s words → the child's). The child's other props and parts are not exposed; its contract explains what it renders.
1002
1003
  - **CSS custom properties** listed on a node are declared on THAT node's root and read by elements inside it. Set one on that node's root or on the element inside it that reads it — the pt part that lands there is how you reach it (`pt:box="[--border-color:…]"` on a text input) — never on `BbDatePickerInput`'s root, where the node's own declaration masks it (design-tokens guide, _Overriding one from a consumer app_, rule 0).
1003
- - Listed nodes are the ones `BbDatePickerInput`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is the `tree` field of this component in `components.json`.
1004
+ - Listed nodes are the ones `BbDatePickerInput`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is `manifest/components/BbDatePickerInput.tree.json`.
1004
1005
 
1005
1006
  - `BbDatePickerInput` _(this component)_ — its own template binds: `controlAttrs` → `input.bb-segmented-field__input`, `input` → `input.bb-segmented-field__input`, `activator` → `button.bb-segmented-field__activator`, `suffix` → `span.bb-field-input__suffix`; hands `BbDatePicker` the pt map `passthrough.forward(PICKER_PARTS, BB_DATE_PICKER_PT.states)` (ours → theirs)
1006
1007
  - `BbDatePicker` _(public — [contract](./BbDatePicker.md))_ — its own pt parts (`BbDatePicker`): `panel` → `div`, `panel` → `CommonPopover`; hands `BbCalendar` the pt map ` passthrough.forward(DATE_PICKER_CALENDAR_PARTS, BB_CALENDAR_PT.states) ` (ours → theirs); hands `BbOffCanvas` the pt map `{ panel: 'root', sheet: 'root' }` (ours → theirs); documented CSS variables: `--cell`, `--unit-row`; also mounts `CommonPopover`
@@ -1009,7 +1010,7 @@ Set these on the element, or on a class you put on it, to retune this component
1009
1010
  - `CommonTimeSelector` _(internal — not importable, reach it through `BbCalendar`)_ — its own pt parts (`BbCalendar`): `header` → `div.bb-time-selector__header`, `cellColumnHeader` → `div.bb-time-selector__cell-column-header`, `item` → `BbBaseButton`; documented CSS variables: `--time-mark`; also mounts `BbBaseButton`
1010
1011
  - `BbOffCanvas` _(public — [contract](./BbOffCanvas.md))_ — its own pt parts (`BbOffCanvas`): `header` → `div.bb-offcanvas__header`, `title` → `span.bb-offcanvas__title`, `description` → `p.bb-offcanvas__description`, `close` → `CloseButton`, `content` → `div.bb-offcanvas__content`, `footer` → `div.bb-offcanvas__footer`; documented CSS variables: `--stack-x`, `--stack-fill`, `--stack-transition-duration`, `--px`, `--handle-w`, `--handle-h`, `--handle-bg`, `--safe-top`, `--close-size`
1011
1012
  - `CloseButton` _(internal — not importable, reach it through `BbOffCanvas`)_ — documented CSS variables: `--size`, `--p`
1012
- - `CommonField` _(internal — not importable, reach it through `BbDatePickerInput`)_ — `BbDatePickerInput`'s pt parts land here: `root` → `div.bb-field`, `label` → `component`, `description` → `span.bb-field__description`, `hint` → `span.bb-field__hint`, `message` → `div.bb-field__message`; also mounts `BbAsterisk`
1013
+ - `CommonField` _(internal — not importable, reach it through `BbDatePickerInput`)_ — `BbDatePickerInput`'s pt parts land here: `root` → `div.bb-field`, `label` → `component`, `description` → `span.bb-field__description`, `hint` → `span.bb-field__hint`, `message` → `div.bb-field__message`; documented CSS variables: `--ctrl-line`; also mounts `BbAsterisk`
1013
1014
  - `CommonFieldInput` _(internal — not importable, reach it through `BbDatePickerInput`)_ — `BbDatePickerInput`'s pt parts land here: `box` → `span.bb-field-input__box`, `prefix` → `span.bb-field-input__prefix`, `icon` → `BbIcon`, `clear` → `ClearableButton`, `spinner` → `BbSpinner`, `suffix` → `span.bb-field-input__suffix`; documented CSS variables: `--bg`, `--bg-hover`, `--bg-focus`, `--bg-disabled`, `--fg-disabled`, `--border-color`, `--border-focus`, `--ring-size`, `--ring-color`, `--elev`, `--frost`, `--inside-label-clearance`; also mounts `ErrorIcon`, `WarningIcon`, `ClearableButton`, `BbIcon`, `BbSpinner`
1014
1015
  - Also mounts `BbIcon`
1015
1016
 
@@ -1200,7 +1200,7 @@ Set these on the element, or on a class you put on it, to retune this component
1200
1200
  - **_internal_** nodes are building blocks with no API of their own: you reach them only through `BbDialog`. A pt part listed as landing there is set on `BbDialog` (`pt:<part>`).
1201
1201
  - **_public_** nodes are components with their own contract. `BbDialog` reaches one only through a pt part of its own that lands on it (shown on the parent node as `part → Component`, e.g. `spinner → BbSpinner`) or through a pt map it hands it (shown as "hands … the pt map", in `BbDialog`'s words → the child's). The child's other props and parts are not exposed; its contract explains what it renders.
1202
1202
  - **CSS custom properties** listed on a node are declared on THAT node's root and read by elements inside it. Set one on that node's root or on the element inside it that reads it — the pt part that lands there is how you reach it (`pt:box="[--border-color:…]"` on a text input) — never on `BbDialog`'s root, where the node's own declaration masks it (design-tokens guide, _Overriding one from a consumer app_, rule 0).
1203
- - Listed nodes are the ones `BbDialog`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is the `tree` field of this component in `components.json`.
1203
+ - Listed nodes are the ones `BbDialog`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is `manifest/components/BbDialog.tree.json`.
1204
1204
 
1205
1205
  - `BbDialog` _(this component)_ — its own template binds: `header` → `div.bb-dialog__header`, `title` → `span.bb-dialog__title`, `description` → `p.bb-dialog__description`, `close` → `CloseButton`, `content` → `div.bb-dialog__content`, `footer` → `div.bb-dialog__footer`; hands `BbOffCanvas` the pt map `{ root: 'root', header: 'header', title: 'title', description: 'description', content: 'content', footer: 'footer', close: 'close', sheet: 'root', }` (ours → theirs)
1206
1206
  - `CloseButton` _(internal — not importable, reach it through `BbDialog`)_ — documented CSS variables: `--size`, `--p`
@@ -2209,7 +2209,7 @@ Set these on the element, or on a class you put on it, to retune this component
2209
2209
  - **_internal_** nodes are building blocks with no API of their own: you reach them only through `BbDropdown`. A pt part listed as landing there is set on `BbDropdown` (`pt:<part>`).
2210
2210
  - **_public_** nodes are components with their own contract. `BbDropdown` reaches one only through a pt part of its own that lands on it (shown on the parent node as `part → Component`, e.g. `spinner → BbSpinner`) or through a pt map it hands it (shown as "hands … the pt map", in `BbDropdown`'s words → the child's). The child's other props and parts are not exposed; its contract explains what it renders.
2211
2211
  - **CSS custom properties** listed on a node are declared on THAT node's root and read by elements inside it. Set one on that node's root or on the element inside it that reads it — the pt part that lands there is how you reach it (`pt:box="[--border-color:…]"` on a text input) — never on `BbDropdown`'s root, where the node's own declaration masks it (design-tokens guide, _Overriding one from a consumer app_, rule 0).
2212
- - Listed nodes are the ones `BbDropdown`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is the `tree` field of this component in `components.json`.
2212
+ - Listed nodes are the ones `BbDropdown`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is `manifest/components/BbDropdown.tree.json`.
2213
2213
 
2214
2214
  - `BbDropdown` _(this component)_ — its own template binds: `panel` → `CommonPopover`, `root` → `CommonPopover`, `header` → `div.bb-dropdown__header`, `list` → `span.bb-dropdown__list`, `footer` → `div.bb-dropdown__footer`
2215
2215
  - `BbDropdownList` _(internal — not importable, reach it through `BbDropdown`)_ — also mounts `BbIcon`, `CommonPopover`, `BbDropdownList`
@@ -714,7 +714,7 @@ States are listed in precedence order: when two are on at once and their entries
714
714
  - **_internal_** nodes are building blocks with no API of their own: you reach them only through `BbDropdownButton`. A pt part listed as landing there is set on `BbDropdownButton` (`pt:<part>`).
715
715
  - **_public_** nodes are components with their own contract. `BbDropdownButton` reaches one only through a pt part of its own that lands on it (shown on the parent node as `part → Component`, e.g. `spinner → BbSpinner`) or through a pt map it hands it (shown as "hands … the pt map", in `BbDropdownButton`'s words → the child's). The child's other props and parts are not exposed; its contract explains what it renders.
716
716
  - **CSS custom properties** listed on a node are declared on THAT node's root and read by elements inside it. Set one on that node's root or on the element inside it that reads it — the pt part that lands there is how you reach it (`pt:box="[--border-color:…]"` on a text input) — never on `BbDropdownButton`'s root, where the node's own declaration masks it (design-tokens guide, _Overriding one from a consumer app_, rule 0).
717
- - Listed nodes are the ones `BbDropdownButton`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is the `tree` field of this component in `components.json`.
717
+ - Listed nodes are the ones `BbDropdownButton`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is `manifest/components/BbDropdownButton.tree.json`.
718
718
 
719
719
  - `BbDropdownButton` _(this component)_ — hands `BbButton` the pt map `{ main: 'root', icon: 'icon', spinner: 'spinner', text: 'text' }` (ours → theirs); hands `BbDropdown` the pt map `{ panel: 'panel', sheet: 'sheet', header: 'header', footer: 'footer', input: 'input', item: 'item', itemText: 'itemText', itemIcon: 'itemIcon', itemDescription: 'itemDescription' }` (ours → theirs); hands `BbButton` the pt map `{ toggle: 'root' }` (ours → theirs)
720
720
  - `BbButton` _(public — [contract](./BbButton.md))_ — its own pt parts (`BbButton`): `root` → `BbBaseButton`, `spinner` → `BbSpinner`, `icon` → `BbIcon`, `text` → `span.bb-button__text`; documented CSS variables: `--h-xs`, `--h`, `--icon-size`, `--px`, `--fs`, `--r`, `--gap`, `--bg`, `--bg-hover`, `--bg-pressed`, `--fg`, `--border-color`, `--ring-color`, `--ring-size`, `--bw`, `--fg-hover`, `--border-hover`, `--fg-pressed`, `--border-pressed`, `--bg-disabled`, `--fg-disabled`, `--border-disabled`, `--opacity-disabled`, `--elev-tier`, `--elev`; also mounts `BbIcon`, `BbSpinner`
@@ -1471,7 +1471,7 @@ States are listed in precedence order: when two are on at once and their entries
1471
1471
  - **_internal_** nodes are building blocks with no API of their own: you reach them only through `BbDropzone`. A pt part listed as landing there is set on `BbDropzone` (`pt:<part>`).
1472
1472
  - **_public_** nodes are components with their own contract. `BbDropzone` reaches one only through a pt part of its own that lands on it (shown on the parent node as `part → Component`, e.g. `spinner → BbSpinner`) or through a pt map it hands it (shown as "hands … the pt map", in `BbDropzone`'s words → the child's). The child's other props and parts are not exposed; its contract explains what it renders.
1473
1473
  - **CSS custom properties** listed on a node are declared on THAT node's root and read by elements inside it. Set one on that node's root or on the element inside it that reads it — the pt part that lands there is how you reach it (`pt:box="[--border-color:…]"` on a text input) — never on `BbDropzone`'s root, where the node's own declaration masks it (design-tokens guide, _Overriding one from a consumer app_, rule 0).
1474
- - Listed nodes are the ones `BbDropzone`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is the `tree` field of this component in `components.json`.
1474
+ - Listed nodes are the ones `BbDropzone`'s API reaches or that declare a documented CSS variable; the rest fold into "also mounts". The complete tree, repeats and undocumented locals included, is `manifest/components/BbDropzone.tree.json`.
1475
1475
 
1476
1476
  - `BbDropzone` _(this component)_ — its own template binds: `content` → `label.bb-dropzone__content`, `message` → `span.bb-dropzone__message`
1477
1477
  - Also mounts `BbSmoothHeight`