@repobit/dex-system-design 0.25.12 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (336) hide show
  1. package/CHANGELOG.md +187 -0
  2. package/README.md +131 -8
  3. package/package.json +95 -13
  4. package/schemas/component-manifest.json +3294 -405
  5. package/schemas/manifest-omissions.json +173 -0
  6. package/src/blog/src/breakpoints.js +6 -6
  7. package/src/blog/src/content/blog-atoms-showcase.js +1 -1
  8. package/src/blog/src/content/blog-page-layout.js +2 -2
  9. package/src/blog/src/lib/article-toc.js +7 -7
  10. package/src/blog/src/shell/blog-shell.js +1 -1
  11. package/src/blog/src/tokens/blog.js +2 -2
  12. package/src/blog/src/tokens/core.js +34 -35
  13. package/src/blog/src/tokens/legacy.js +0 -9
  14. package/src/blog/tokens/blog.js +2 -2
  15. package/src/blog/tokens/core.js +34 -35
  16. package/src/blog/tokens/legacy.js +0 -9
  17. package/src/blog/tokens.css +36 -46
  18. package/src/components/accordion/accordion-bg.css.js +83 -59
  19. package/src/components/accordion/accordion-bg.js +29 -10
  20. package/src/components/accordion/accordion-bg.stories.js +67 -67
  21. package/src/components/accordion/accordion-keyboard.js +80 -0
  22. package/src/components/accordion/accordion.css.js +142 -80
  23. package/src/components/accordion/accordion.js +37 -10
  24. package/src/components/accordion/accordion.stories.js +7 -7
  25. package/src/components/agent-endpoints/agent-endpoints.css.js +36 -39
  26. package/src/components/agent-endpoints/agent-endpoints.js +30 -20
  27. package/src/components/agent-endpoints/agent-endpoints.stories.js +1 -1
  28. package/src/components/ai-guardian-demo.stories.js +91 -91
  29. package/src/components/alert/alert.css.js +198 -0
  30. package/src/components/alert/alert.js +103 -0
  31. package/src/components/alert/alert.stories.js +206 -0
  32. package/src/components/anchor/anchor-nav.css.js +213 -101
  33. package/src/components/anchor/anchor-nav.js +26 -40
  34. package/src/components/anchor/anchor.stories.js +22 -12
  35. package/src/components/annotation/annotation.css.js +58 -0
  36. package/src/components/annotation/annotation.js +67 -0
  37. package/src/components/annotation/annotation.stories.js +63 -0
  38. package/src/components/architecture.stories.js +285 -0
  39. package/src/components/atoms.stories.js +342 -0
  40. package/src/components/avatar/avatar.css.js +67 -0
  41. package/src/components/avatar/avatar.js +42 -0
  42. package/src/components/avatar/avatar.stories.js +95 -0
  43. package/src/components/awards/awards-flex.css.js +209 -23
  44. package/src/components/awards/awards-flex.js +66 -7
  45. package/src/components/awards/awards-flex.stories.js +1 -1
  46. package/src/components/awards/{awards-light.stories.js → awards-summary.stories.js} +54 -64
  47. package/src/components/awards/awards.css.js +116 -58
  48. package/src/components/awards/awards.js +102 -28
  49. package/src/components/awards/awards.stories.js +1 -1
  50. package/src/components/back/back.css.js +51 -22
  51. package/src/components/back/back.js +28 -7
  52. package/src/components/back/back.stories.js +9 -3
  53. package/src/components/badge/badge.css.js +158 -46
  54. package/src/components/badge/badge.js +62 -74
  55. package/src/components/badge/badge.stories.js +176 -248
  56. package/src/components/bento-grid/bento-grid.css.js +21 -16
  57. package/src/components/bento-grid/bento-grid.js +16 -4
  58. package/src/components/bento-grid/bento-grid.stories.js +19 -18
  59. package/src/components/bento-grid/bento-item.css.js +52 -28
  60. package/src/components/bento-grid/bento-item.js +2 -2
  61. package/src/components/blockquote/blockquote.css.js +47 -0
  62. package/src/components/blockquote/blockquote.js +29 -0
  63. package/src/components/blockquote/blockquote.stories.js +62 -0
  64. package/src/components/breadcrumb/breadcrumb.css.js +92 -22
  65. package/src/components/breadcrumb/breadcrumb.js +56 -11
  66. package/src/components/button/button.css.js +531 -161
  67. package/src/components/button/button.js +206 -214
  68. package/src/components/button/button.stories.js +322 -174
  69. package/src/components/caption/caption.css.js +21 -0
  70. package/src/components/caption/caption.js +31 -0
  71. package/src/components/caption/caption.stories.js +62 -0
  72. package/src/components/card-features/card-features.css.js +14 -22
  73. package/src/components/card-features/card-features.js +68 -9
  74. package/src/components/card-features/card-features.stories.js +11 -11
  75. package/src/components/cards/card.css.js +60 -81
  76. package/src/components/cards/card.js +56 -25
  77. package/src/components/cards/card.stories.js +39 -39
  78. package/src/components/carousel/carousel.css.js +93 -99
  79. package/src/components/carousel/carousel.js +32 -4
  80. package/src/components/checkbox/checkbox.css.js +111 -93
  81. package/src/components/checkbox/checkbox.js +64 -90
  82. package/src/components/checkbox/checkbox.stories.js +96 -29
  83. package/src/components/code/code.css.js +70 -0
  84. package/src/components/code/code.js +40 -0
  85. package/src/components/code/code.stories.js +73 -0
  86. package/src/components/compare/compare.css.js +179 -43
  87. package/src/components/compare/compare.js +52 -25
  88. package/src/components/compare/compare.stories.js +61 -4
  89. package/src/components/comparison-panel/comparison-panel.css.js +38 -51
  90. package/src/components/comparison-panel/comparison-panel.js +5 -4
  91. package/src/components/comparison-panel/comparison-panel.stories.js +1 -1
  92. package/src/components/compatibility-table/compatibility-table.css.js +180 -80
  93. package/src/components/compatibility-table/compatibility-table.js +37 -9
  94. package/src/components/control-alignment.stories.js +393 -0
  95. package/src/components/cta-banner/cta-banner.css.js +41 -13
  96. package/src/components/cta-banner/cta-banner.js +6 -5
  97. package/src/components/cta-banner/cta-banner.stories.js +43 -98
  98. package/src/components/display/display.css.js +25 -1
  99. package/src/components/display/display.js +46 -13
  100. package/src/components/display/display.stories.js +270 -40
  101. package/src/components/divider/divider-horizontal.js +21 -5
  102. package/src/components/divider/divider-vertical.js +15 -7
  103. package/src/components/divider/divider.css.js +2 -2
  104. package/src/components/divider/divider.stories.js +38 -34
  105. package/src/components/dropdown/dropdown.css.js +93 -126
  106. package/src/components/dropdown/dropdown.js +114 -34
  107. package/src/components/dropdown/dropdown.stories.js +56 -24
  108. package/src/components/features/features.css.js +24 -11
  109. package/src/components/features/features.js +7 -3
  110. package/src/components/features/features.stories.js +37 -37
  111. package/src/components/features-tab/features-tab.css.js +19 -8
  112. package/src/components/features-tab/features-tab.js +6 -5
  113. package/src/components/features-tab/features-tab.stories.js +23 -23
  114. package/src/components/fieldset/fieldset.css.js +30 -0
  115. package/src/components/fieldset/fieldset.js +28 -0
  116. package/src/components/fieldset/fieldset.stories.js +84 -0
  117. package/src/components/footer/footer-links-group.css.js +10 -14
  118. package/src/components/footer/footer-links-group.js +4 -3
  119. package/src/components/footer/footer-lp.css.js +59 -30
  120. package/src/components/footer/footer-lp.js +17 -12
  121. package/src/components/footer/footer-lp.stories.js +63 -75
  122. package/src/components/footer/footer-nav-menu.css.js +26 -4
  123. package/src/components/footer/footer-nav-menu.js +3 -2
  124. package/src/components/footer/footer.css.js +146 -264
  125. package/src/components/footer/footer.js +176 -106
  126. package/src/components/footer/footer.stories.js +9 -9
  127. package/src/components/footer/localeMap.js +1 -1
  128. package/src/components/grid/grid.css.js +1 -1
  129. package/src/components/grid/grid.js +49 -7
  130. package/src/components/grid/grid.stories.js +111 -0
  131. package/src/components/header/header-code.css.js +61 -51
  132. package/src/components/header/header-code.js +28 -14
  133. package/src/components/header/header-code.stories.js +5 -5
  134. package/src/components/header/header.css.js +655 -176
  135. package/src/components/header/header.js +269 -36
  136. package/src/components/header/header.stories.js +841 -18
  137. package/src/components/heading/heading.css.js +14 -17
  138. package/src/components/heading/heading.js +48 -33
  139. package/src/components/heading/heading.stories.js +27 -25
  140. package/src/components/help-text/help-text.css.js +21 -0
  141. package/src/components/help-text/help-text.js +25 -0
  142. package/src/components/help-text/help-text.stories.js +66 -0
  143. package/src/components/highlight/highlight.css.js +86 -64
  144. package/src/components/highlight/highlight.js +18 -27
  145. package/src/components/highlight/highlight.stories.js +14 -3
  146. package/src/components/icons/analysis-icon.js +6 -16
  147. package/src/components/icons/arrow-down-icon.js +6 -19
  148. package/src/components/icons/arrow-icon.js +44 -0
  149. package/src/components/icons/arrow-right-icon.js +30 -23
  150. package/src/components/icons/arrow-up-icon.js +19 -18
  151. package/src/components/icons/bd-ai-icon.js +1 -1
  152. package/src/components/icons/brand-marks.stories.js +279 -0
  153. package/src/components/icons/brand-signature-icon.js +42 -0
  154. package/src/components/icons/check-icon.js +27 -0
  155. package/src/components/icons/circle-info-icon.js +33 -0
  156. package/src/components/icons/close-icon.js +6 -18
  157. package/src/components/icons/family-icon.js +8 -20
  158. package/src/components/icons/globe-icon.js +6 -18
  159. package/src/components/icons/guide-icon.js +6 -18
  160. package/src/components/icons/icon-element.js +99 -0
  161. package/src/components/icons/icons.js +36 -0
  162. package/src/components/icons/icons.stories.js +184 -52
  163. package/src/components/icons/individual-icon.js +6 -18
  164. package/src/components/icons/laurel-icon.js +9 -19
  165. package/src/components/icons/machine-learning-icon.js +6 -17
  166. package/src/components/icons/marks.js +41 -0
  167. package/src/components/icons/minus-icon.js +7 -21
  168. package/src/components/icons/missing-icon.js +52 -0
  169. package/src/components/icons/plus-icon.js +7 -21
  170. package/src/components/icons/quote-icon.js +19 -19
  171. package/src/components/image/image.css.js +72 -25
  172. package/src/components/image/image.js +11 -6
  173. package/src/components/image/image.stories.js +2 -2
  174. package/src/components/input/custom-form.stories.js +214 -62
  175. package/src/components/input/input-clipboard.css.js +51 -144
  176. package/src/components/input/input-clipboard.js +31 -15
  177. package/src/components/input/input.css.js +8 -146
  178. package/src/components/input/input.js +93 -38
  179. package/src/components/install-options/install-options.css.js +84 -77
  180. package/src/components/install-options/install-options.js +33 -30
  181. package/src/components/install-options/install-options.stories.js +3 -3
  182. package/src/components/label/label.css.js +35 -0
  183. package/src/components/label/label.js +38 -0
  184. package/src/components/label/label.stories.js +82 -0
  185. package/src/components/light-carousel/light-carousel.css.js +111 -63
  186. package/src/components/light-carousel/light-carousel.js +85 -11
  187. package/src/components/light-carousel/light-carousel.stories.js +126 -82
  188. package/src/components/link/link.css.js +150 -99
  189. package/src/components/link/link.js +86 -11
  190. package/src/components/link/link.stories.js +124 -30
  191. package/src/components/list/list-item/list-item.css.js +74 -22
  192. package/src/components/list/list-item/list-item.js +32 -10
  193. package/src/components/list/list-item/list-item.stories.js +23 -23
  194. package/src/components/list/list.css.js +8 -2
  195. package/src/components/list/list.js +3 -2
  196. package/src/components/list/list.stories.js +222 -0
  197. package/src/components/modal/modal.css.js +114 -24
  198. package/src/components/modal/modal.js +83 -7
  199. package/src/components/modal/modal.stories.js +9 -9
  200. package/src/components/overview/overview.css.js +19 -14
  201. package/src/components/overview/overview.js +6 -5
  202. package/src/components/overview/overview.stories.js +10 -10
  203. package/src/components/page-switcher/page-switcher.css.js +97 -40
  204. package/src/components/page-switcher/page-switcher.js +28 -5
  205. package/src/components/page-switcher/page-switcher.stories.js +95 -0
  206. package/src/components/paragraph/paragraph.css.js +15 -10
  207. package/src/components/paragraph/paragraph.js +41 -44
  208. package/src/components/paragraph/paragraph.stories.js +56 -21
  209. package/src/components/picture/picture.css.js +103 -44
  210. package/src/components/picture/picture.js +100 -30
  211. package/src/components/picture/picture.stories.js +1 -1
  212. package/src/components/pricing-cards/new-pricing-card.js +3 -3
  213. package/src/components/pricing-cards/new-pricing.css.js +24 -15
  214. package/src/components/pricing-cards/pricing-card-actions.css.js +1 -1
  215. package/src/components/pricing-cards/pricing-card-actions.js +3 -4
  216. package/src/components/pricing-cards/pricing-card-container.css.js +3 -3
  217. package/src/components/pricing-cards/pricing-card-container.js +3 -2
  218. package/src/components/pricing-cards/pricing-card-header.css.js +10 -8
  219. package/src/components/pricing-cards/pricing-card-header.js +6 -7
  220. package/src/components/pricing-cards/pricing-card-pricing.css.js +16 -9
  221. package/src/components/pricing-cards/pricing-card-pricing.js +8 -6
  222. package/src/components/pricing-cards/pricing-card-show-more.css.js +11 -3
  223. package/src/components/pricing-cards/pricing-card-show-more.js +8 -3
  224. package/src/components/pricing-cards/pricing-card.css.js +244 -190
  225. package/src/components/pricing-cards/pricing-card.js +54 -70
  226. package/src/components/pricing-cards/pricing-feature-item.css.js +25 -8
  227. package/src/components/pricing-cards/pricing-feature-item.js +8 -3
  228. package/src/components/process-steps/process-steps.css.js +26 -14
  229. package/src/components/process-steps/process-steps.js +23 -6
  230. package/src/components/process-steps/process-steps.stories.js +1 -1
  231. package/src/components/progress/progress.css.js +80 -0
  232. package/src/components/progress/progress.js +42 -0
  233. package/src/components/progress/progress.stories.js +79 -0
  234. package/src/components/quick-answer/quick-answer.css.js +75 -13
  235. package/src/components/quick-answer/quick-answer.js +8 -3
  236. package/src/components/radio/radio.css.js +92 -128
  237. package/src/components/radio/radio.js +106 -127
  238. package/src/components/radio/radio.stories.js +54 -19
  239. package/src/components/review/review-grid.css.js +5 -6
  240. package/src/components/review/review-grid.js +14 -11
  241. package/src/components/review/review.css.js +11 -6
  242. package/src/components/review/review.js +3 -8
  243. package/src/components/shared/ensemble.css.js +93 -0
  244. package/src/components/shared/form-field.css.js +206 -0
  245. package/src/components/shared/prop-vocabulary.js +48 -0
  246. package/src/components/shared/token-scales.js +306 -0
  247. package/src/components/skeleton/skeleton.css.js +34 -0
  248. package/src/components/skeleton/skeleton.js +32 -0
  249. package/src/components/skeleton/skeleton.stories.js +70 -0
  250. package/src/components/spinner/spinner.css.js +62 -0
  251. package/src/components/spinner/spinner.js +38 -0
  252. package/src/components/spinner/spinner.stories.js +92 -0
  253. package/src/components/spotlight-section/spotlight-section.css.js +14 -13
  254. package/src/components/spotlight-section/spotlight-section.js +42 -39
  255. package/src/components/switch/switch.css.js +103 -0
  256. package/src/components/switch/switch.js +44 -0
  257. package/src/components/switch/switch.stories.js +86 -0
  258. package/src/components/tab-list/content-switcher.stories.js +189 -0
  259. package/src/components/tab-list/tab-list.css.js +250 -0
  260. package/src/components/tab-list/tab-list.js +184 -0
  261. package/src/components/tab-list/tab-list.stories.js +221 -0
  262. package/src/components/tabs/tabs.css.js +14 -123
  263. package/src/components/tabs/tabs.js +16 -19
  264. package/src/components/tabs/tabs.stories.js +95 -95
  265. package/src/components/tag/tag.css.js +54 -0
  266. package/src/components/tag/tag.js +32 -0
  267. package/src/components/tag/tag.stories.js +126 -0
  268. package/src/components/terminal/terminal-message.css.js +164 -60
  269. package/src/components/terminal/terminal-message.js +5 -5
  270. package/src/components/terminal/terminal-message.stories.js +70 -1
  271. package/src/components/termsOfUse/terms.css.js +25 -20
  272. package/src/components/termsOfUse/terms.js +13 -9
  273. package/src/components/termsOfUse/terms.stories.js +1 -1
  274. package/src/components/textarea/textarea.css.js +51 -0
  275. package/src/components/textarea/textarea.js +136 -0
  276. package/src/components/textarea/textarea.stories.js +191 -0
  277. package/src/components/tooltip/tooltip.css.js +75 -0
  278. package/src/components/tooltip/tooltip.js +156 -0
  279. package/src/components/tooltip/tooltip.stories.js +161 -0
  280. package/src/components/trust-panel/trust-panel.css.js +85 -33
  281. package/src/components/trust-panel/trust-panel.js +18 -10
  282. package/src/components/trust-panel/trust-panel.stories.js +1 -1
  283. package/src/components/ultimate-security-demo.stories.js +431 -0
  284. package/src/components/video/video.css.js +17 -0
  285. package/src/components/video/video.js +40 -0
  286. package/src/components/video/video.stories.js +106 -0
  287. package/src/components/video-player/video-player.css.js +67 -11
  288. package/src/components/video-player/video-player.js +35 -4
  289. package/src/components/video-player/video-player.stories.js +1 -1
  290. package/src/components/visual-alignment.stories.js +411 -0
  291. package/src/components/visually-hidden/visually-hidden.css.js +24 -0
  292. package/src/components/visually-hidden/visually-hidden.js +16 -0
  293. package/src/components/visually-hidden/visually-hidden.stories.js +56 -0
  294. package/src/stories/Button.stories.js +17 -17
  295. package/src/stories/Header.stories.js +10 -10
  296. package/src/stories/Page.js +1 -1
  297. package/src/stories/Page.stories.js +6 -6
  298. package/src/tokens/borders.stories.js +339 -0
  299. package/src/tokens/color-responsibilities.stories.js +227 -0
  300. package/src/tokens/dark-derivation.js +309 -0
  301. package/src/tokens/dark-findings.js +197 -0
  302. package/src/tokens/dark-mode.stories.js +207 -0
  303. package/src/tokens/dimension.stories.js +251 -0
  304. package/src/tokens/elevation.stories.js +143 -0
  305. package/src/tokens/focus.stories.js +276 -0
  306. package/src/tokens/fonts.css +20 -20
  307. package/src/tokens/fonts.stories.js +354 -374
  308. package/src/tokens/layout.css +25 -11
  309. package/src/tokens/motion.stories.js +231 -0
  310. package/src/tokens/shape.stories.js +272 -0
  311. package/src/tokens/spacing-rhythm.stories.js +359 -0
  312. package/src/tokens/spacing.stories.js +208 -703
  313. package/src/tokens/story-chrome.js +503 -0
  314. package/src/tokens/surfaces.stories.js +224 -0
  315. package/src/tokens/text-on-surface.stories.js +164 -0
  316. package/src/tokens/token-map.js +220 -0
  317. package/src/tokens/token-map.stories.js +257 -0
  318. package/src/tokens/token-purposes.js +266 -0
  319. package/src/tokens/tokens-grid.stories.js +388 -900
  320. package/src/tokens/tokens.css +1633 -1045
  321. package/src/tokens/tokens.js +1130 -492
  322. package/src/tokens/tokens.stories.js +137 -47
  323. package/src/tokens/type-ceiling-words.js +299 -0
  324. package/src/tokens/typography.stories.js +1003 -965
  325. package/src/tokens/vertical-rhythm.stories.js +224 -0
  326. package/src/components/awards/awards-icon.js +0 -56
  327. package/src/components/awards/awards-light.js +0 -240
  328. package/src/components/banner/banner.js +0 -60
  329. package/src/components/banner/banner.stories.js +0 -51
  330. package/src/components/button/icons.js +0 -24
  331. package/src/components/input/index.js +0 -0
  332. package/src/components/light-carousel/light-carousel-simple.css.js +0 -183
  333. package/src/components/light-carousel/light-carousel-simple.js +0 -74
  334. package/src/tokens/colors.js +0 -121
  335. package/src/tokens/typography.css.js +0 -207
  336. package/src/tokens/typography.js +0 -0
@@ -8,12 +8,56 @@ export const accordionItem = css`
8
8
  border-radius: var(--radius-sm);
9
9
  }
10
10
 
11
+ /* The one focus ring, on the item.
12
+
13
+ Two owners are in play and they are deliberately different elements. The
14
+ TRIGGER owns focus: it is the button, it carries aria-expanded, a keyboard
15
+ lands on it and a screen reader announces it. The ITEM owns the focus
16
+ VISUAL: a disclosure is perceived as one object -- the question and, when
17
+ open, its answer -- and the ring goes round that object, growing with the
18
+ answer when it is revealed. Measured before this rule, on Components/
19
+ Accordion "Item open by default": host [99,131,1242,61], trigger
20
+ [99,131,1242,24], content [99,171,1242,21] -- the ring stopped at the
21
+ question and the answer sat outside it.
22
+
23
+ Exactly one painter. The trigger's :focus-visible rule below sets outline
24
+ none and nothing else; the ring lives here. P6C.2.1 found both painting the
25
+ same --focus-outline-primary and removed the host's; P6C.2.2 moves the one
26
+ ring back up to the item and takes the trigger's away, so the invariant
27
+ that phase established -- one token, one painter -- still holds.
28
+
29
+ No border-radius here. The ring is a box-shadow and follows the shape of
30
+ the item it sits on: --radius-sm on this host, --radius-lg on the tinted
31
+ FAQ item. Setting --focus-outline-radius here is what P6C.2.1 removed,
32
+ because it pulled a focused FAQ card's corners from 8px to 4px.
33
+
34
+ Why an attribute and not a pseudo-class. This rule needs to fire when the
35
+ trigger -- inside this shadow root -- matches :focus-visible, and no
36
+ selector says that from the host. Measured with a probe sheet injected at
37
+ runtime: :host(:has(button:focus-visible)) never matches, because :has()
38
+ inside :host() looks at light-DOM descendants and cannot see the shadow
39
+ tree (:host(:has(.bd-accordion-bg-question)) fails the same way);
40
+ :host(:focus-within) matches on a real Tab AND on a real mouse click, so it
41
+ cannot tell keyboard from pointer; :host(:focus-visible) never matches. The
42
+ JS in accordion.js sets data-bd-acc-focus after two animation frames when
43
+ -- and only when -- the trigger matches :focus-visible, and re-checks on
44
+ every keydown, because a keypress can make an already-focused button
45
+ :focus-visible without a focus change. Measured: after a mouse click the
46
+ attribute stays off; after Tab it is on.
47
+
48
+ The stacking is the other reason the attribute exists, and it is measured:
49
+ --bd-acc-item-margin-bottom is a public custom property, and with it zeroed
50
+ on AccordionBg "FAQ - Default" a 300x5 sample where the ring overlaps the
51
+ next item holds 600 blue-500 pixels with position/z-index and 0 without --
52
+ the next item's tint paints over the ring. On the untinted
53
+ bd-accordion-item it reads 600 either way.
54
+
55
+ bd-accordion-bg-item adopts this stylesheet too, so this is the one rule
56
+ that rings and stacks the whole accordion family. */
11
57
  :host([data-bd-acc-focus]) {
12
- outline: none;
13
- box-shadow: var(--focus-outline-primary);
14
58
  position: relative;
15
- z-index: 1;
16
- border-radius: var(--radius-sm);
59
+ z-index: var(--z-base);
60
+ box-shadow: var(--focus-outline-primary);
17
61
  }
18
62
 
19
63
  :host(:last-child) {
@@ -21,20 +65,26 @@ export const accordionItem = css`
21
65
  }
22
66
 
23
67
  :host-context(bd-accordion-section:not([variant="small"])) {
24
- --bd-acc-title-font-size: var(--typography-fontSize-base);
25
- --bd-acc-title-font-weight: var(--typography-fontWeight-semibold);
26
- --bd-acc-title-line-height: var(--typography-lineHeight-normal);
27
- --bd-acc-title-color-expanded: var(--color-neutral-900);
28
- --bd-acc-title-color-collapsed: var(--color-neutral-900);
29
- --bd-acc-panel-font-size: var(--typography-fontSize-sm);
30
- --bd-acc-panel-font-weight: var(--typography-fontWeight-normal);
31
- --bd-acc-panel-line-height: var(--typography-lineHeight-normal);
32
- --bd-acc-panel-color: var(--color-neutral-800);
68
+ --bd-acc-title-font-size: var(--typography-label-large-fontSize);
69
+ --bd-acc-title-font-weight: var(--typography-label-large-fontWeight);
70
+ --bd-acc-title-line-height: var(--typography-label-large-lineHeight);
71
+ /* Section titles. The role, not neutral-900: same value, but a primitive
72
+ records what the colour IS and a role records what it is FOR, and only
73
+ the second survives a theme or a palette revision. */
74
+ --bd-acc-title-color-expanded: var(--color-text-primary);
75
+ --bd-acc-title-color-collapsed: var(--color-text-primary);
76
+ --bd-acc-panel-font-size: var(--typography-body-small-fontSize);
77
+ --bd-acc-panel-font-weight: var(--typography-body-small-fontWeight);
78
+ --bd-acc-panel-line-height: var(--typography-body-small-lineHeight);
79
+ /* Panel body copy. */
80
+ --bd-acc-panel-color: var(--color-text-primary);
33
81
  }
34
82
 
35
83
  :host-context(bd-accordion-section[variant="default-blue"]) {
36
- --bd-acc-title-color-expanded: var(--color-blue-600);
37
- --bd-acc-title-color-collapsed: var(--color-blue-600);
84
+ /* -text-brand IS blue-600; naming the role also inherits the reason it is
85
+ blue-600 and not blue-500, which tokens.js records. */
86
+ --bd-acc-title-color-expanded: var(--color-text-brand);
87
+ --bd-acc-title-color-collapsed: var(--color-text-brand);
38
88
  }
39
89
 
40
90
  :host-context(bd-accordion-section[variant="small"]) {
@@ -42,13 +92,14 @@ export const accordionItem = css`
42
92
  --bd-acc-header-margin-bottom: var(--spacing-0);
43
93
  --bd-acc-icon-gap: var(--spacing-12);
44
94
  --bd-acc-toggle-size: var(--icon-sm-size);
45
- --bd-acc-title-font-size: var(--typography-fontSize-xs);
46
- --bd-acc-title-font-weight: var(--typography-fontWeight-semibold);
47
- --bd-acc-title-line-height: 1.3;
48
- --bd-acc-panel-font-size: var(--typography-fontSize-xs);
49
- --bd-acc-panel-font-weight: var(--typography-fontWeight-normal);
50
- --bd-acc-panel-line-height: 1.3;
51
- --bd-acc-panel-color: var(--color-neutral-800);
95
+ --bd-acc-title-font-size: var(--typography-label-default-fontSize);
96
+ --bd-acc-title-font-weight: var(--typography-label-default-fontWeight);
97
+ --bd-acc-title-line-height: var(--typography-label-default-lineHeight);
98
+ --bd-acc-panel-font-size: var(--typography-caption-default-fontSize);
99
+ --bd-acc-panel-font-weight: var(--typography-caption-default-fontWeight);
100
+ --bd-acc-panel-line-height: var(--typography-caption-default-lineHeight);
101
+ /* Panel body copy, small variant. */
102
+ --bd-acc-panel-color: var(--color-text-primary);
52
103
  --bd-acc-panel-padding: var(--spacing-0) var(--spacing-8) var(--spacing-8)
53
104
  var(--spacing-36);
54
105
  --bd-acc-panel-paragraph-gap: var(--spacing-0);
@@ -87,8 +138,8 @@ export const accordionItem = css`
87
138
  font-family: var(--typography-fontFamily-sans);
88
139
  font-style: normal;
89
140
  font-size: var(--bd-acc-title-font-size, var(--typography-label-large-fontSize));
90
- font-weight: var(--bd-acc-title-font-weight, var(--typography-fontWeight-semibold));
91
- line-height: var(--bd-acc-title-line-height, var(--typography-lineHeight-normal));
141
+ font-weight: var(--bd-acc-title-font-weight, var(--typography-label-large-fontWeight));
142
+ line-height: var(--bd-acc-title-line-height, var(--typography-label-large-lineHeight));
92
143
  margin-bottom: var(--bd-acc-header-margin-bottom, var(--spacing-16));
93
144
  }
94
145
 
@@ -96,25 +147,29 @@ export const accordionItem = css`
96
147
  margin-bottom: var(--spacing-8);
97
148
  }
98
149
 
150
+ /* No ring on the trigger. outline: none is not a removal: the visible focus
151
+ indicator is the item's ring, drawn by :host([data-bd-acc-focus]) above on
152
+ exactly the frames this pseudo-class matches. Painting it here as well is
153
+ the double ring P6C.2.1 measured and removed. */
99
154
  .header:focus-visible {
100
155
  outline: none;
101
- box-shadow: none;
102
156
  }
103
157
 
104
158
  .header[aria-expanded="true"] .title {
105
- color: var(--color-blue-500);
159
+ /* blue-500 is 4.2:1 on the blue-50 tint these titles sit on; blue-600 is 5.72 */
160
+ color: var(--color-text-brand);
106
161
  }
107
162
 
108
163
  .header[aria-expanded="false"] .title {
109
- color: var(--color-blue-500);
164
+ color: var(--color-text-brand);
110
165
  }
111
166
 
112
167
  :host-context(bd-accordion-section[variant="small"]) .header[aria-expanded="false"] .title {
113
- color: var(--color-neutral-900);
168
+ color: var(--color-text-primary);
114
169
  }
115
170
 
116
171
  :host-context(bd-accordion-section[variant="small"]) .header[aria-expanded="false"]:hover .title {
117
- color: var(--color-blue-500);
172
+ color: var(--color-text-brand);
118
173
  }
119
174
 
120
175
  :host-context(bd-accordion-section[variant="small"]) .header[aria-expanded="true"] .title {
@@ -122,7 +177,7 @@ export const accordionItem = css`
122
177
  }
123
178
 
124
179
  :host-context(bd-accordion-section[variant="small"]) .header[aria-expanded="true"]:hover .title {
125
- color: var(--color-blue-500);
180
+ color: var(--color-text-brand);
126
181
  }
127
182
 
128
183
  .toggle {
@@ -133,25 +188,40 @@ export const accordionItem = css`
133
188
  display: flex;
134
189
  align-items: center;
135
190
  justify-content: center;
136
- line-height: 0;
191
+ /* the box holds an icon, not text; none collapses the leading to the
192
+ glyph rather than reserving a text line around it */
193
+ line-height: var(--typography-lineHeight-none);
137
194
  user-select: none;
138
195
  margin-top: calc(
139
- (var(--bd-acc-title-line-height, var(--typography-lineHeight-normal)) * 1em -
196
+ (var(--bd-acc-title-line-height, var(--typography-label-large-lineHeight)) * 1em -
140
197
  var(--bd-acc-toggle-size, var(--icon-sm-size))) / 2
141
198
  );
142
199
  }
143
200
 
144
- .toggle img {
145
- display: block;
146
- width: 100%;
147
- height: 100%;
148
- object-fit: contain;
149
- }
201
+ /* A ".toggle img" rule stood here and could never match. The toggle renders
202
+ <bd-plus-icon>, <bd-minus-icon> or the chevron atoms, each taking its own
203
+ size and color props -- there has been no <img> here since that migration,
204
+ and the atom's props already carry what this rule was sizing.
205
+ .
206
+ Those props pass --color-text-brand, the same role .header carries and the
207
+ one bd-link's whole family resolves to. They passed --color-blue-500 until
208
+ the Figma audit put icon and label side by side: the label was already the
209
+ role, so the toggle disagreed with its own text by one step. This file had
210
+ already made the same move twice -- on .header[aria-expanded="true"] .title
211
+ and on .user-guide-link a -- and the icon was the hold-out, passing on the
212
+ 3:1 non-text bar where the text beside it needed 4.5:1. */
150
213
 
151
214
  .title {
152
- font-weight: var(--bd-acc-title-font-weight, var(--typography-fontWeight-semibold));
215
+ font-weight: var(--bd-acc-title-font-weight, var(--typography-label-large-fontWeight));
153
216
  }
154
217
 
218
+ /* Wrapping is the whole mechanism: whether a title and its badge fit on one
219
+ line depends on how long the title is and how much room this accordion
220
+ has, not on how wide the window is. A 430px viewport rule used to force
221
+ the column stack, which was both too eager and too narrow -- measured, a
222
+ 320px-wide accordion on a 1280px viewport never triggered it and laid out
223
+ correctly anyway, while a short title on a 320px viewport was stacked when
224
+ it would have fitted. flex-wrap answers the question actually being asked. */
155
225
  .title-badge-wrapper {
156
226
  display: flex;
157
227
  align-items: center;
@@ -163,10 +233,14 @@ export const accordionItem = css`
163
233
  .content {
164
234
  padding: var(--bd-acc-panel-padding, 0 0 0 calc(var(--icon-sm-size) + var(--spacing-12)));
165
235
  font-family: var(--typography-fontFamily-sans);
166
- font-size: var(--bd-acc-panel-font-size, var(--typography-fontSize-sm));
167
- font-weight: var(--bd-acc-panel-font-weight, var(--typography-fontWeight-normal));
168
- line-height: var(--bd-acc-panel-line-height, var(--typography-lineHeight-normal));
169
- color: var(--bd-acc-panel-color, var(--color-neutral-700));
236
+ font-size: var(--bd-acc-panel-font-size, var(--typography-body-small-fontSize));
237
+ font-weight: var(--bd-acc-panel-font-weight, var(--typography-body-small-fontWeight));
238
+ line-height: var(--bd-acc-panel-line-height, var(--typography-body-small-lineHeight));
239
+ /* The fallback is -primary because both :host-context blocks above set
240
+ -primary, so it was only ever reachable by a standalone bd-accordion-item
241
+ outside any section -- one rendering that disagreed with every real
242
+ usage, and with the Figma item, which draws this at text/primary. */
243
+ color: var(--bd-acc-panel-color, var(--color-text-primary));
170
244
  }
171
245
 
172
246
  .content[hidden] {
@@ -187,15 +261,6 @@ export const accordionItem = css`
187
261
  margin-bottom: 0;
188
262
  }
189
263
 
190
- @media (max-width: 430px) {
191
- .title-badge-wrapper {
192
- flex-direction: column;
193
- align-items: flex-start;
194
- gap: var(--spacing-0);
195
- width: 100%;
196
- }
197
- }
198
-
199
264
  /* === CHEVRON VARIANT (text + arrow icon only, no visible border/pill/background) === */
200
265
  .header--chevron {
201
266
  display: inline-flex;
@@ -205,11 +270,11 @@ export const accordionItem = css`
205
270
  gap: var(--spacing-8);
206
271
  padding: 0;
207
272
  border: none;
208
- border-radius: 0;
273
+ border-radius: var(--radius-none);
209
274
  background: none;
210
275
  margin-bottom: var(--spacing-24);
211
- font-size: var(--typography-fontSize-sm);
212
- font-weight: var(--typography-fontWeight-semibold);
276
+ font-size: var(--typography-label-default-fontSize);
277
+ font-weight: var(--typography-label-default-fontWeight);
213
278
  }
214
279
 
215
280
  .header--chevron .title-badge-wrapper {
@@ -217,7 +282,7 @@ export const accordionItem = css`
217
282
  }
218
283
 
219
284
  .header--chevron .title {
220
- color: var(--color-blue-600);
285
+ color: var(--color-text-brand);
221
286
  white-space: nowrap;
222
287
  }
223
288
 
@@ -239,8 +304,8 @@ export const accordionItem = css`
239
304
 
240
305
  export const accordionSection = css`
241
306
  .bd-accordion-section-container {
242
- background-color: var(--bd-acc-section-bg, var(--color-neutral-25));
243
- border-radius: 0;
307
+ background-color: var(--bd-acc-section-bg, var(--color-surface-container));
308
+ border-radius: var(--radius-none);
244
309
  box-sizing: border-box;
245
310
 
246
311
  /* Bleed — bg full width */
@@ -255,65 +320,62 @@ export const accordionSection = css`
255
320
  }
256
321
 
257
322
  .bd-accordion-section-inner {
258
- max-width: 1290px;
259
- margin-inline: auto;
260
- padding-inline: var(--layout-ensemble-inline-padding, var(--spacing-24));
261
323
  box-sizing: border-box;
262
324
  }
263
325
 
264
326
  :host([variant="small"]) {
265
- --bd-acc-section-bg: var(--color-neutral-0);
327
+ /* White here means "the untinted page ground", which is -surface-default's
328
+ job; the default variant two rules up already asks for a surface role. */
329
+ --bd-acc-section-bg: var(--color-surface-default);
266
330
  --bd-acc-section-padding-v: var(--spacing-24);
267
331
  }
268
332
 
269
333
  :host([variant="default-blue"]) {
270
- --bd-acc-section-bg: var(--color-blue-50);
271
- }
272
-
273
- :host(:not([variant="small"])) .user-guide-link {
274
- color: var(--color-blue-700);
334
+ /* The brand tint as a surface, which is what the Figma section already
335
+ binds this to (status/brand/surface) and what bd-accordion-bg's item
336
+ ground uses for the same tint. */
337
+ --bd-acc-section-bg: var(--status-brand-surface);
275
338
  }
276
339
 
277
340
  .section-title {
278
341
  margin-bottom: var(--spacing-24);
279
342
  margin-top: var(--spacing-0);
280
- font-family: var(--typography-fontFamily-sans);
281
- font-weight: var(--typography-fontWeight-bold);
282
- font-size: var(--typography-body-regular-fontSize);
283
- line-height: var(--typography-lineHeight-normal);
284
- color: var(--color-neutral-1000);
285
343
  }
286
344
 
287
345
  :host([variant="small"]) .section-title {
288
- font-size: var(--typography-fontSize-lg);
289
346
  margin-bottom: var(--spacing-16);
290
347
  }
291
348
 
292
349
  .user-guide-link {
293
350
  margin-top: var(--spacing-32);
294
- color: var(--color-blue-600);
351
+ color: var(--color-text-brand);
295
352
  }
296
353
 
297
354
  .user-guide-link a {
298
355
  display: inline-flex;
299
356
  align-items: center;
300
357
  text-decoration: none;
301
- color: var(--color-blue-500);
358
+ /* --color-text-brand, which is what .user-guide-link one rule up already
359
+ says. This anchor overrode its own parent with the raw primitive, and
360
+ blue-500 measures 4.34:1 on the --color-surface-container these links sit
361
+ on -- the exact trap the token comment two hundred lines up describes and
362
+ that this file already avoids twice elsewhere. blue-600 is 5.92. */
363
+ color: var(--color-text-brand);
302
364
  gap: var(--spacing-12);
303
- font-family: Arial, Helvetica, sans-serif;
304
- font-size: var(--typography-fontSize-xs);
365
+ font-family: var(--typography-fontFamily-sans);
366
+ font-size: var(--typography-body-xsmall-fontSize);
305
367
  }
306
368
 
307
369
  .user-guide-link a:focus-visible {
308
370
  outline: none;
309
371
  box-shadow: var(--focus-outline-primary);
310
- border-radius: var(--radius-sm);
372
+ border-radius: var(--focus-outline-radius);
311
373
  }
312
374
 
313
375
  .user-guide-link .icon img {
314
376
  display: block;
315
- width: var(--dimension-16px);
316
- height: var(--dimension-16px);
377
+ width: var(--dimension-16);
378
+ height: var(--dimension-16);
317
379
  object-fit: contain;
318
380
  }
319
381
  `;
@@ -1,5 +1,6 @@
1
1
  import { LitElement, html } from "lit";
2
- import { tokens } from "../../tokens/tokens.js";
2
+ // Installs the design tokens into document scope; see src/tokens/tokens.js
3
+ import "../../tokens/tokens.js";
3
4
  import "../heading/heading.js";
4
5
  import "../icons/arrow-down-icon.js";
5
6
  import "../icons/arrow-up-icon.js";
@@ -7,9 +8,11 @@ import "../icons/minus-icon.js";
7
8
  import "../icons/plus-icon.js";
8
9
  import "../paragraph/paragraph.js";
9
10
  import { accordionItem, accordionSection } from "./accordion.css.js";
11
+ import { ensembleCSS } from "../shared/ensemble.css.js";
12
+ import { onTriggerKeydown } from "./accordion-keyboard.js";
10
13
 
11
14
  export class BdAccordionItem extends LitElement {
12
- static styles = [tokens, accordionItem];
15
+ static styles = [accordionItem];
13
16
 
14
17
  static properties = {
15
18
  open : { type: Boolean, reflect: true },
@@ -31,6 +34,18 @@ export class BdAccordionItem extends LitElement {
31
34
  this.open = !this.open;
32
35
  }
33
36
 
37
+ /**
38
+ * The trigger is the focus target; the item draws the ring. This puts
39
+ * data-bd-acc-focus on the host when -- and only when -- the trigger matches
40
+ * :focus-visible, which is the one thing no selector can say from the host
41
+ * (see the note on :host([data-bd-acc-focus]) in accordion.css.js). Two
42
+ * frames, because :focus-visible is decided after the focus event.
43
+ *
44
+ * Called on focusin and on every keydown. The keydown matters: after a mouse
45
+ * click the button is focused without :focus-visible and the attribute is
46
+ * rightly off, but a keypress then makes it :focus-visible with no focus
47
+ * change, and without this the item would show no ring for a keyboard user.
48
+ */
34
49
  _onTriggerFocusIn() {
35
50
  const btn = this.renderRoot?.querySelector(".header");
36
51
  if (!btn) return;
@@ -47,6 +62,16 @@ export class BdAccordionItem extends LitElement {
47
62
  this.removeAttribute("data-bd-acc-focus");
48
63
  }
49
64
 
65
+ _onTriggerKeydown(e) {
66
+ onTriggerKeydown(this, e);
67
+ this._onTriggerFocusIn();
68
+ }
69
+
70
+ /** Move keyboard focus to this item's disclosure trigger. */
71
+ focusTrigger() {
72
+ this.renderRoot?.querySelector(".header")?.focus();
73
+ }
74
+
50
75
  render() {
51
76
  const badgeEl = this.querySelector("[slot='badge']");
52
77
 
@@ -60,6 +85,7 @@ export class BdAccordionItem extends LitElement {
60
85
  @click=${this.toggle}
61
86
  @focusin=${this._onTriggerFocusIn}
62
87
  @focusout=${this._onTriggerFocusOut}
88
+ @keydown=${this._onTriggerKeydown}
63
89
  >
64
90
  <span class="title-badge-wrapper">
65
91
  <span class="title">${this.title}</span>
@@ -67,8 +93,8 @@ export class BdAccordionItem extends LitElement {
67
93
  </span>
68
94
  <span class="toggle toggle--chevron" aria-hidden="true">
69
95
  ${this.open
70
- ? html`<bd-arrow-up-icon size="16" color="#006DFF"></bd-arrow-up-icon>`
71
- : html`<bd-arrow-down-icon size="16" color="#006DFF"></bd-arrow-down-icon>`}
96
+ ? html`<bd-arrow-up-icon size="16" color="var(--color-text-brand)"></bd-arrow-up-icon>`
97
+ : html`<bd-arrow-down-icon size="16" color="var(--color-text-brand)"></bd-arrow-down-icon>`}
72
98
  </span>
73
99
  </button>
74
100
  <div id="${this._panelId}" class="content content--chevron" ?hidden=${!this.open}>
@@ -86,11 +112,12 @@ export class BdAccordionItem extends LitElement {
86
112
  @click=${this.toggle}
87
113
  @focusin=${this._onTriggerFocusIn}
88
114
  @focusout=${this._onTriggerFocusOut}
115
+ @keydown=${this._onTriggerKeydown}
89
116
  >
90
117
  <span class="toggle" aria-hidden="true">
91
118
  ${this.open
92
- ? html`<bd-minus-icon size="16" color="#006DFF"></bd-minus-icon>`
93
- : html`<bd-plus-icon size="16" color="#006DFF"></bd-plus-icon>`}
119
+ ? html`<bd-minus-icon size="16" color="var(--color-text-brand)"></bd-minus-icon>`
120
+ : html`<bd-plus-icon size="16" color="var(--color-text-brand)"></bd-plus-icon>`}
94
121
  </span>
95
122
  <span class="title-badge-wrapper">
96
123
  <span class="title">${this.title}</span>
@@ -105,7 +132,7 @@ export class BdAccordionItem extends LitElement {
105
132
  }
106
133
 
107
134
  export class BdAccordionSection extends LitElement {
108
- static styles = [tokens, accordionSection];
135
+ static styles = [ensembleCSS, accordionSection];
109
136
 
110
137
  static properties = {
111
138
  title : { type: String },
@@ -129,12 +156,12 @@ export class BdAccordionSection extends LitElement {
129
156
  render() {
130
157
  const content = html`
131
158
  ${this.title
132
- ? html`<bd-h as="h6" fontWeight="700" paddingBottom="var(--spacing-32)" class="section-title">${this.title}</bd-h>`
159
+ ? html`<bd-h as="h6" fontWeight="bold" class="section-title">${this.title}</bd-h>`
133
160
  : ""}
134
161
  <slot></slot>
135
162
  ${this.guideLabel
136
163
  ? html`
137
- <bd-p kind="small" class="user-guide-link">
164
+ <bd-p variant="small" class="user-guide-link">
138
165
  <a href=${this.guideHref}>
139
166
  ${this.guideIcon
140
167
  ? html`<span class="icon"><img src=${this.guideIcon} alt="" /></span>`
@@ -151,7 +178,7 @@ export class BdAccordionSection extends LitElement {
151
178
 
152
179
  return html`
153
180
  <div class="bd-accordion-section-container">
154
- <div class="bd-accordion-section-inner">
181
+ <div class="bd-ensemble bd-accordion-section-inner">
155
182
  ${content}
156
183
  </div>
157
184
  </div>
@@ -257,8 +257,8 @@ export const RiskMappingAccordion = {
257
257
  name : "Chevron variant — Risk mapping table",
258
258
  render: () => html`
259
259
  <div style="max-width: 900px;">
260
- <bd-h as="h2" font-weight="700" style="margin: 0 0 8px;">Coverage against agentic AI risk categories</bd-h>
261
- <bd-p kind="regular" style="color: var(--color-neutral-700); margin: 0 0 24px;">
260
+ <bd-h as="h2" fontWeight="bold" style="margin: 0 0 8px;">Coverage against agentic AI risk categories</bd-h>
261
+ <bd-p variant="regular" style="color: var(--color-neutral-700); margin: 0 0 24px;">
262
262
  How AI Guardian maps to the risk categories the industry is standardising on for agentic applications.
263
263
  </bd-p>
264
264
 
@@ -276,7 +276,7 @@ export const RiskMappingAccordion = {
276
276
  ></bd-compatibility-table>
277
277
  </bd-accordion-item>
278
278
 
279
- <bd-p kind="small" style="color: var(--color-neutral-500); margin-top: 16px;">
279
+ <bd-p variant="small" style="color: var(--color-neutral-500); margin-top: 16px;">
280
280
  Category naming follows OWASP Top 10 for Agentic Applications (2026).
281
281
  </bd-p>
282
282
  </div>
@@ -323,14 +323,14 @@ export const DefaultVsChevron = {
323
323
  render: () => html`
324
324
  <div style="display: flex; flex-direction: column; gap: 32px;">
325
325
  <div>
326
- <bd-p kind="small" style="color: var(--color-neutral-500); margin-bottom: 8px;">Default (plus/minus, left icon)</bd-p>
326
+ <bd-p variant="small" style="color: var(--color-neutral-500); margin-bottom: 8px;">Default (plus/minus, left icon)</bd-p>
327
327
  <bd-accordion-item title="Default accordion item">
328
328
  <p>Regular accordion content, unaffected by the new chevron variant.</p>
329
329
  </bd-accordion-item>
330
330
  </div>
331
331
 
332
332
  <div>
333
- <bd-p kind="small" style="color: var(--color-neutral-500); margin-bottom: 8px;">Chevron (plain text, right arrow icon, no border)</bd-p>
333
+ <bd-p variant="small" style="color: var(--color-neutral-500); margin-bottom: 8px;">Chevron (plain text, right arrow icon, no border)</bd-p>
334
334
  <bd-accordion-item chevron title="Chevron accordion item">
335
335
  <p>Same underlying component, opt-in chevron styling via the chevron attribute.</p>
336
336
  </bd-accordion-item>
@@ -351,8 +351,8 @@ export const OperationalDetailsAccordion = {
351
351
  name : "Chevron variant — Operational details (light table)",
352
352
  render: () => html`
353
353
  <div style="max-width: 900px;">
354
- <bd-h as="h2" font-weight="700" style="margin: 0 0 8px;">How it runs</bd-h>
355
- <bd-p kind="regular" style="color: var(--color-neutral-700); margin: 0 0 24px;">
354
+ <bd-h as="h2" fontWeight="bold" style="margin: 0 0 8px;">How it runs</bd-h>
355
+ <bd-p variant="regular" style="color: var(--color-neutral-700); margin: 0 0 24px;">
356
356
  AI Guardian installs from a signed macOS installer and runs as a background service; the rows below list how it installs, where analysis happens, and what the BETA costs.
357
357
  </bd-p>
358
358
 
@@ -1,4 +1,5 @@
1
- import { css } from "lit";
1
+ import { css, unsafeCSS } from "lit";
2
+ import { below } from "../shared/token-scales.js";
2
3
 
3
4
  export default css`
4
5
  :host {
@@ -7,30 +8,32 @@ export default css`
7
8
  }
8
9
 
9
10
  .bd-agentendpoints-wrapper {
10
- max-width: var(--layout-ensemble-max-width, 1200px);
11
- margin: 0 auto;
12
- padding: var(--spacing-48) var(--layout-ensemble-inline-padding, var(--spacing-24));
11
+ padding-block: var(--spacing-48);
13
12
  box-sizing: border-box;
14
13
  }
15
14
 
16
15
  .bd-agentendpoints-eyebrow {
17
16
  display: block;
18
17
  margin: 0 0 var(--spacing-8);
19
- color: var(--color-blue-500);
18
+ /* The brand text role, not the brand primitive. This darkens the ink: the
19
+ role is blue-600, so contrast on white goes 4.53:1 -> 6.18:1. It is not a
20
+ like-for-like swap, and it cannot be -- no text role exists at blue-500's
21
+ value. The roles sitting there are surface, border, action, two status
22
+ fills, an accent and the tab indicator, and blue-500 is the step
23
+ CLAUDE.md says is not for text. */
24
+ color: var(--color-text-brand);
20
25
  }
21
26
 
22
27
  .bd-agentendpoints-title {
23
28
  display: block;
24
29
  margin: 0 0 var(--spacing-16);
25
- color: var(--color-neutral-1000);
26
- line-height: var(--typography-lineHeight-tight, 1.1);
27
30
  }
28
31
 
29
32
  .bd-agentendpoints-description {
30
33
  display: block;
31
34
  margin: 0 0 var(--spacing-24);
32
- color: var(--color-neutral-600);
33
- max-width: 70ch;
35
+ color: var(--color-text-muted);
36
+ max-width: var(--content-width-readable);
34
37
  }
35
38
 
36
39
  .bd-agentendpoints-row {
@@ -44,39 +47,33 @@ export default css`
44
47
  margin-bottom: 0;
45
48
  }
46
49
 
47
- /* === button--outline-white ===
48
- White pill button with a thin gray border, rounded corners — used both
49
- for the /endpoint links (with a leading arrow, monospace label) and the
50
- "Ask <assistant>" links (with a leading brand icon). Reusable class,
51
- not scoped to this component only. */
52
- .button--outline-white {
53
- display: inline-flex;
54
- align-items: center;
55
- gap: var(--spacing-8);
56
- padding: var(--spacing-10, 10px) var(--spacing-16);
57
- background: var(--color-neutral-0, #fff);
58
- border: 1px solid var(--color-neutral-200, #e5e7eb);
59
- border-radius: var(--radius-full, 999px);
60
- color: var(--color-neutral-800);
61
- font-size: var(--typography-fontSize-sm);
62
- font-weight: var(--typography-fontWeight-medium, 500);
63
- text-decoration: none;
64
- white-space: nowrap;
65
- transition: border-color 0.2s ease, background 0.2s ease;
66
- }
50
+ /* === pill ===
51
+ A white pill with a thin grey border, used for the /endpoint links (leading
52
+ arrow, monospace label) and the Ask <assistant> links (leading brand icon).
67
53
 
68
- .button--outline-white:hover {
69
- border-color: var(--color-blue-300, #93c5fd);
70
- background: var(--color-blue-50, #eef4ff);
71
- }
54
+ This was called button--outline-white, which is the name the button atom
55
+ uses for something else entirely: there, outline-white is a fixed preset
56
+ for a coloured banner and its label is white. Here the pill sits on a light
57
+ surface and its label is dark. The two never met, because a shadow root
58
+ scopes a class to its own component and nothing here was ever reusable, but
59
+ the shared name invited the wrong one to be reasoned about. */
60
+ /* No rule for .bd-agentendpoints-pill any more. It was a hand-rolled control
61
+ -- surface, border, radius, colour, type, hover and a focus ring, all
62
+ reimplemented -- and the class now sits on a <bd-button-link variant=
63
+ "tertiary" size="sm">, which supplies every one of them from the button
64
+ atom. Left in place it also doubled the padding, since the host and the
65
+ anchor inside it were both padding the same content: the host measured
66
+ 55.5px against the anchor's 33.5px.
72
67
 
73
- .bd-agentendpoints-arrow {
74
- color: var(--color-neutral-400, #9ca3af);
75
- }
68
+ The class is kept as a hook only, for the two spans below. */
76
69
 
70
+ /* No colour on either span: the button owns the ink. These were
71
+ neutral-400 and text-secondary, chosen when the pill was a white box with
72
+ dark text; on a tertiary button they overrode its blue and left the file
73
+ path grey inside a blue control. The mono face stays, because a path
74
+ rendered in the text face is the thing this span exists to prevent. */
77
75
  .bd-agentendpoints-mono {
78
- font-family: var(--typography-fontFamily-mono, monospace);
79
- color: var(--color-neutral-700);
76
+ font-family: var(--typography-fontFamily-mono);
80
77
  }
81
78
 
82
79
  .bd-agentendpoints-icon {
@@ -84,7 +81,7 @@ export default css`
84
81
  flex-shrink: 0;
85
82
  }
86
83
 
87
- @media (max-width: 599px) {
84
+ @media ${unsafeCSS(below('sm'))} {
88
85
  .bd-agentendpoints-wrapper {
89
86
  padding: var(--spacing-32) var(--spacing-24);
90
87
  }