@repobit/dex-system-design 0.25.12 → 1.0.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 +204 -0
  2. package/README.md +131 -8
  3. package/package.json +96 -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
@@ -1,14 +1,11 @@
1
- import { css } from "lit";
1
+ import { css, unsafeCSS } from "lit";
2
+ import { below } from "../shared/token-scales.js";
2
3
 
3
4
  export const anchorNavStyles = css`
4
5
  :host {
5
6
  display: block;
6
7
  width: 100%;
7
- background: var(--color-neutral-0);
8
- --bd-accesibility-focus: var(--color-blue-500);
9
- --anchor-nav-max-width: 1290px;
10
- border-top: var(--border-width-1) solid var(--color-neutral-100);
11
- border-bottom: var(--border-width-1) solid var(--color-neutral-100);
8
+ background: var(--color-surface-default);
12
9
  }
13
10
 
14
11
  :host(.is-sticky) {
@@ -17,11 +14,7 @@ export const anchorNavStyles = css`
17
14
  left: var(--sticky-left, 0);
18
15
  width: var(--sticky-width, 100%);
19
16
  box-shadow: var(--shadow-sm);
20
- z-index: 1000;
21
- }
22
-
23
- :host(.is-sticky) nav {
24
- background: var(--color-neutral-0);
17
+ z-index: var(--z-sticky);
25
18
  }
26
19
 
27
20
  nav {
@@ -30,6 +23,13 @@ export const anchorNavStyles = css`
30
23
  padding: var(--spacing-0);
31
24
  width: 100%;
32
25
  box-sizing: border-box;
26
+ border-top: var(--border-width-1) solid var(--color-border-container);
27
+ border-bottom: var(--border-width-1) solid var(--color-border-container);
28
+ }
29
+
30
+ /* Când e sticky, păstrăm aceleași border-uri */
31
+ :host(.is-sticky) nav {
32
+ background: var(--color-surface-default);
33
33
  }
34
34
 
35
35
  .bd-anchor-nav__inner {
@@ -39,20 +39,30 @@ export const anchorNavStyles = css`
39
39
  align-items: center;
40
40
  gap: var(--spacing-32);
41
41
  width: 100%;
42
- max-width: var(--anchor-nav-max-width);
43
42
  padding-block: var(--spacing-10);
44
- padding-inline: var(--layout-ensemble-inline-padding, var(--spacing-24));
45
- margin-inline: auto;
46
43
  box-sizing: border-box;
47
44
  }
48
45
 
49
- .anchor-link:focus-visible,
50
- .bd-anchor-nav__cta:focus-visible,
46
+ /* No .anchor-link:focus-visible. .anchor-link is the class this component
47
+ puts on a bd-link HOST, and the focusable anchor lives inside bd-link's own
48
+ shadow root -- a host without delegatesFocus matches :focus and
49
+ :focus-within when focus is inside it, and never :focus-visible. Measured
50
+ with a real keyboard Tab at 1440: 4 .anchor-link hosts, 1 matching :focus,
51
+ 0 matching :focus-visible, box-shadow none on all four. bd-link carries the
52
+ one ring and the links get it; the two selectors left here are a real
53
+ button and a real anchor in this shadow root. */
51
54
  .bd-anchor-nav__dropdown-toggle:focus-visible,
52
55
  .bd-anchor-nav__dropdown-option:focus-visible {
53
- outline: var(--spacing-2) solid var(--bd-accesibility-focus);
54
- outline-offset: var(--spacing-2);
55
- border-radius: var(--space-2xs);
56
+ /* the one focus ring — see Foundations/Focus */
57
+ outline: none;
58
+ box-shadow: var(--focus-outline-primary);
59
+ /* No border-radius here, for the reason back.css.js records: the ring is a
60
+ box-shadow and already follows the shape of what it sits on, and both of
61
+ these have a radius of their own -- --radius-lg on the toggle,
62
+ --radius-md on the option. Setting --focus-outline-radius as well pulled
63
+ the toggle's corners from 8px to 4px, and the option's from 6px to 4px,
64
+ for as long as either was focused. That token is the default for an
65
+ element with NO radius, which is what Foundations/Focus says. */
56
66
  }
57
67
 
58
68
  .anchor-links {
@@ -60,7 +70,11 @@ export const anchorNavStyles = css`
60
70
  display: flex;
61
71
  flex-wrap: wrap;
62
72
  align-items: center;
63
- gap: var(--spacing-16) var(--spacing-32);
73
+ /* Column gap and row gap say different things here, so they are spelled
74
+ apart. The shorthand carried a --spacing-16 row gap that the next
75
+ declaration overrode on the following line: measured row-gap 8px, so the
76
+ 16 was never a value anyone could read off the screen. */
77
+ column-gap: var(--spacing-32);
64
78
  row-gap: var(--spacing-8);
65
79
  flex: 1 1 auto;
66
80
  min-width: 0;
@@ -71,61 +85,92 @@ export const anchorNavStyles = css`
71
85
  .anchor-link {
72
86
  position: relative;
73
87
  text-decoration: none;
74
- color: var(--color-neutral-900);
75
- font-weight: var(--typography-fontWeight-normal);
76
- padding: var(--spacing-10) var(--spacing-0);
88
+ color: var(--color-text-primary);
89
+ /* No font-weight: body-regular, whose size this rule already asks for, is
90
+ normal -- and the inherited weight here is 400 too, measured, so the
91
+ declaration said nothing. .anchor-link.active still sets its own. */
77
92
  display: inline-block;
78
93
  font-size: var(--typography-body-regular-fontSize);
79
94
  font-family: var(--typography-body-regular-fontFamily);
80
95
  transition: color var(--transition-duration-fast) var(--transition-easing-smooth);
81
96
  }
82
97
 
98
+ /* The padding belongs to the PART, not to the host.
99
+
100
+ A host's padding does not extend the anchor inside it, so this rule used
101
+ to build a 44px-tall row around a 24px-tall target: measured 63x44 on the
102
+ host with a 63x24 <a> inside it, and elementsFromPoint 4px below the top
103
+ edge came back bd-anchor-nav > bd-root > div with no <a> in the stack at
104
+ all. The top and bottom 10px of every item were dead, 45% of the height a
105
+ reader aims at.
106
+
107
+ It is also why the focus ring wrapped the glyphs rather than the item: the
108
+ ring is drawn on whatever element is focusable, and that was the 24px
109
+ anchor. One boundary, two symptoms.
110
+
111
+ bd-breadcrumb already fixed exactly this by moving its padding onto
112
+ ::part(link) -- its comment records a 343x40 row whose focusable anchor
113
+ was 43x24 -- and this is the same move. Layout is unchanged: the host has
114
+ no padding now but wraps an anchor that does, so it still measures 44px
115
+ and the indicator's offset still lands on the bar's bottom edge. */
116
+ .anchor-link::part(link) {
117
+ padding: var(--spacing-10) var(--spacing-0);
118
+ }
119
+
83
120
  .anchor-link.active {
121
+ /* no role: the active item in the anchor nav -- a state or modifier weight, not a text-content
122
+ type. See button.css.js's .button--bold for the argument. */
84
123
  font-weight: var(--typography-fontWeight-semibold);
85
- color: var(--color-neutral-900);
124
+ color: var(--color-text-primary);
86
125
  }
87
126
 
88
- .anchor-link,
89
- .anchor-link.bd-link,
90
- .anchor-link.bd-link--primary,
91
- .anchor-link.bd-link--secondary {
127
+ /* The .bd-link--primary / --secondary selectors that used to accompany these
128
+ matched nothing: bd-link is a custom element and those classes live inside
129
+ its shadow root, unreachable from here. Measured zero matches for
130
+ .bd-link--primary, .bd-link--secondary and .anchor-link.bd-link, against
131
+ four live .anchor-link elements. Only the reachable selectors remain. */
132
+ .anchor-link {
92
133
  text-decoration: none !important;
93
134
  }
94
135
 
95
- .anchor-link:hover,
96
- .anchor-link.bd-link:hover,
97
- .anchor-link.bd-link--primary:hover,
98
- .anchor-link.bd-link--secondary:hover {
136
+ .anchor-link:hover {
99
137
  text-decoration: none !important;
100
138
  }
101
139
 
102
- .anchor-link.bd-link--primary:hover {
103
- color: var(--color-blue-500) !important;
140
+ .anchor-link.active:hover {
141
+ color: var(--color-text-primary) !important;
142
+ text-decoration: none !important;
104
143
  }
105
144
 
106
- .anchor-link.bd-link--secondary:hover {
107
- color: var(--color-neutral-900) !important;
108
- }
145
+ /* The offset has to equal the inner's padding-bottom, and it did not.
109
146
 
110
- .anchor-link.active:hover,
111
- .anchor-link.active.bd-link--primary:hover,
112
- .anchor-link.active.bd-link--secondary:hover {
113
- color: var(--color-neutral-900) !important;
114
- text-decoration: none !important;
115
- }
147
+ The indicator is absolute inside the link box, and what it is aiming for
148
+ is the bar's bottom edge -- so the distance it has to travel is exactly
149
+ the padding the inner adds below the link. This rule said 14, which is
150
+ bd-page-switcher's number and not this component's: the inner here pads
151
+ 10, so the indicator overshot by 4 and rendered BELOW the nav's bottom
152
+ border, detached from the bar it belongs to.
153
+
154
+ Measured before, at 1440 with the nav 66px tall including its borders:
155
+ link box bottom at 55, indicator occupying 66-69, nav bottom edge at 66.
156
+ After: 62-65, sitting directly on the border.
116
157
 
117
- .anchor-indicator {
158
+ The indicator is now one element that slides between items rather than
159
+ an ::after per link, so the offset lives in _updateIndicator(), which
160
+ reads the inner's padding-bottom instead of a number -- the two move
161
+ together. */
162
+ .anchor-indicator {
118
163
  position: absolute;
119
- left: 0;
120
- top: 0;
164
+ left: var(--spacing-0);
165
+ top: var(--spacing-0);
121
166
  width: 0;
122
- height: var(--border-width-3);
123
- background-color: var(--color-blue-500);
167
+ height: var(--indicator-underline-height);
168
+ background-color: var(--indicator-color);
124
169
  transform: translateX(0);
125
170
  transition:
126
- transform var(--transition-duration-slow) var(--transition-easing-ease-out),
127
- top var(--transition-duration-slow) var(--transition-easing-ease-out),
128
- width var(--transition-duration-slow) var(--transition-easing-ease-out);
171
+ transform var(--indicator-underline-duration) var(--indicator-underline-easing),
172
+ top var(--indicator-underline-duration) var(--indicator-underline-easing),
173
+ width var(--indicator-underline-duration) var(--indicator-underline-easing);
129
174
  pointer-events: none;
130
175
  }
131
176
 
@@ -143,16 +188,34 @@ export const anchorNavStyles = css`
143
188
  justify-content: space-between;
144
189
  gap: var(--spacing-12);
145
190
  width: 100%;
146
- min-height: var(--dimension-48px);
191
+ min-height: var(--dimension-48);
147
192
  padding-block: var(--spacing-10);
148
193
  padding-inline: var(--spacing-16);
149
194
  box-sizing: border-box;
150
195
  font-family: var(--typography-fontFamily-sans);
151
196
  font-size: var(--typography-body-regular-fontSize);
197
+ /* The leading that belongs to the size above. It was absent, so the label
198
+ and the ellipsised text inside it were laid out on IBM Plex Sans's own
199
+ "normal" metric -- a leading nobody chose, and one that stops being 1.25
200
+ the moment the font falls back. */
201
+ line-height: var(--typography-body-regular-lineHeight);
202
+ /* no role: the weight of a control, not a text-content type -- see
203
+ button.css.js's .button--bold. Nothing in the vocabulary carries semibold
204
+ at a body size anyway: all ten heavy-weight roles are headings or display
205
+ steps at 2xl and up. */
152
206
  font-weight: var(--typography-fontWeight-semibold);
153
- color: var(--color-neutral-900);
207
+ color: var(--color-text-primary);
208
+ /* no role: --color-surface-container is neutral-25 exactly, and it is the
209
+ wrong role -- it means "the ground of a self-contained object, a card, a
210
+ tile, a panel", and this is a control somebody operates. The control
211
+ families cannot say it either: --form-input-default-backgroundColor is
212
+ white, and this toggle deliberately sits one step off it. A ground for a
213
+ bordered control at rest has no role, and this is its one consumer. */
154
214
  background: var(--color-neutral-25);
155
- border: var(--border-width-1) solid var(--color-neutral-200);
215
+ /* A control edge, so it takes the role the form-field atom uses for one.
216
+ neutral-200 is border-subtle's value, which is documented as the wrong
217
+ role for the edge of something a person operates. */
218
+ border: var(--border-width-1) solid var(--color-border-default);
156
219
  border-radius: var(--radius-lg);
157
220
  cursor: pointer;
158
221
  text-align: left;
@@ -163,12 +226,34 @@ export const anchorNavStyles = css`
163
226
  }
164
227
 
165
228
  .bd-anchor-nav__dropdown-toggle:hover {
166
- background: var(--color-neutral-50);
167
- border-color: var(--color-neutral-300);
229
+ background: var(--color-surface-subtle);
230
+ /* The edge of a bordered control under the pointer, and this package
231
+ already had an answer for it: radio.css.js and checkbox.css.js both take
232
+ --color-action-primary-hover for exactly this job, four declarations
233
+ across two atoms. This rule was the only one on a primitive.
234
+ .
235
+ Measured against this toggle's own hover ground (--color-surface-subtle):
236
+ neutral-500 was 4.17:1 and blue-600 is 5.51:1, so the adoption improves
237
+ the edge rather than trading contrast for consistency. The visible change
238
+ is that the hover edge goes from grey to blue, which is what radio and
239
+ checkbox already do.
240
+ .
241
+ Note the token is an ACTION role rather than a --color-border-* one. That
242
+ is deliberate and is how the two atoms use it too: an interaction state
243
+ is the job, and the border roles describe permanence -- default, subtle,
244
+ strong -- not what a control does under a pointer. */
245
+ border-color: var(--color-action-primary-hover);
168
246
  }
169
247
 
170
248
  .bd-anchor-nav__dropdown-toggle[aria-expanded="true"] {
171
- background: var(--color-neutral-50);
249
+ background: var(--color-surface-subtle);
250
+ /* no role: the edge while the panel is open. No border role sits at
251
+ blue-200 -- only --status-brand-border and --status-info-border, and an
252
+ open disclosure is neither a brand nor an information STATUS. The nearest
253
+ control token is --form-input-focus-borderColor, which is blue-500 and
254
+ means focused rather than expanded; the two states are independent here,
255
+ since the toggle can be focused and closed. Expanded has no vocabulary
256
+ in either control family. */
172
257
  border-color: var(--color-blue-200);
173
258
  }
174
259
 
@@ -181,16 +266,26 @@ export const anchorNavStyles = css`
181
266
  transform-origin: left center;
182
267
  }
183
268
 
269
+ /* The mark inside is bd-arrow-down-icon, the same atom bd-custom-dropdown's
270
+ caret and the accordion's toggle use. It was an inline stroked svg written
271
+ into the template -- stroke-width 2 with round caps, so a visibly different
272
+ chevron from the filled one the rest of the package draws, and invisible to
273
+ check:icons. This span keeps the colour and the rotation; the icon reads
274
+ currentColor from it, which is what every icon site here does. */
184
275
  .bd-anchor-nav__dropdown-chevron {
185
276
  flex: 0 0 auto;
186
277
  display: flex;
187
- color: var(--color-neutral-600);
278
+ color: var(--color-text-muted);
188
279
  transition: transform var(--transition-duration-normal) var(--transition-easing-smooth);
189
280
  }
190
281
 
191
282
  .bd-anchor-nav__dropdown-toggle[aria-expanded="true"] .bd-anchor-nav__dropdown-chevron {
192
283
  transform: rotate(180deg);
193
- color: var(--color-blue-500);
284
+ /* The brand ink, matching the resting state three rules up, which already reads
285
+ --color-text-muted. A chevron is a currentColor glyph, so it takes the ink role
286
+ of its context -- the answer ten other icon sites in this package already give.
287
+ Visible: 4.05:1 -> 5.51:1 on the toggle's grey tint. */
288
+ color: var(--color-text-brand);
194
289
  }
195
290
 
196
291
  .bd-anchor-nav__dropdown-panel {
@@ -198,13 +293,13 @@ export const anchorNavStyles = css`
198
293
  left: var(--spacing-0);
199
294
  right: var(--spacing-0);
200
295
  top: 100%;
201
- z-index: 1001;
296
+ z-index: var(--z-overlay);
202
297
  max-height: min(50vh, 20rem);
203
298
  overflow-y: auto;
204
- background: var(--color-neutral-0);
299
+ background: var(--color-surface-default);
205
300
  border: var(--border-width-1) solid var(--color-blue-200);
206
301
  border-top: none;
207
- border-radius: var(--spacing-0) var(--spacing-0) var(--radius-lg) var(--radius-lg);
302
+ border-radius: var(--radius-none) var(--radius-none) var(--radius-lg) var(--radius-lg);
208
303
  box-shadow: var(--shadow-md);
209
304
  }
210
305
 
@@ -221,14 +316,26 @@ export const anchorNavStyles = css`
221
316
  display: flex;
222
317
  align-items: center;
223
318
  width: 100%;
224
- min-height: var(--dimension-48px);
319
+ text-decoration: none;
320
+ min-height: var(--dimension-48);
225
321
  padding-block: var(--spacing-12);
226
322
  padding-inline: var(--spacing-16);
227
323
  box-sizing: border-box;
228
324
  font-family: var(--typography-fontFamily-sans);
229
325
  font-size: var(--typography-body-regular-fontSize);
230
- font-weight: var(--typography-fontWeight-normal);
231
- color: var(--color-neutral-900);
326
+ /* As the toggle above: the size named its role and the leading did not
327
+ follow it. This one can wrap -- a long section title in a narrow
328
+ dropdown -- and CLAUDE.md asks for at least 1.25 on anything that can. */
329
+ line-height: var(--typography-body-regular-lineHeight);
330
+ /* No font-weight: as .anchor-link above -- body-regular is normal and so is
331
+ the inherited value. The --active variant sets its own. */
332
+ /* text/brand, the same resting ink the desktop items take. This is the
333
+ same component below md showing the same items, so it expresses the same
334
+ meaning: colour is AVAILABLE and neutral is current. It read
335
+ text/primary here, which made the current option the only blue one --
336
+ the inverse of the family, and the arrangement the desktop bar was just
337
+ moved off. */
338
+ color: var(--color-text-brand);
232
339
  background: transparent;
233
340
  border: none;
234
341
  border-radius: var(--radius-md);
@@ -239,19 +346,40 @@ export const anchorNavStyles = css`
239
346
  background var(--transition-duration-fast) var(--transition-easing-smooth);
240
347
  }
241
348
 
349
+ /* Hover on a dropdown option is the action responsibility, and it is now the
350
+ same step the desktop items hover to -- action/primary-active rather than
351
+ -hover, so brand darkens the same way in both presentations. blue-700 on
352
+ the --color-neutral-25 this hover sets measures 8.19:1; the blue-500 that
353
+ stood here before either role measured 4.34 and failed. The background is
354
+ the dropdown's own affordance and is not part of the ink contract. */
242
355
  .bd-anchor-nav__dropdown-option:hover:not(.bd-anchor-nav__dropdown-option--active) {
243
- color: var(--color-blue-500);
356
+ color: var(--color-action-primary-active);
244
357
  background: var(--color-neutral-25);
245
358
  }
246
359
 
360
+ /* The current option, in the family's terms: neutral ink at the weight the
361
+ other two use for the same job, and the blue-50 fill is this presentation's
362
+ indicator -- a dropdown row has no bottom edge to underline, so the fill
363
+ carries what the 3px line carries on the bars.
364
+
365
+ It used to be action/primary-active, which was defensible on its own
366
+ terms -- an option with aria-current, a click handler and a tinted fill is
367
+ an interactive element in an engaged state -- but it made the current item
368
+ the bluest thing in the list while every other item was neutral. Under one
369
+ contract for the whole family that reading is inverted: colour marks what
370
+ you can go to, neutral marks where you are. */
247
371
  .bd-anchor-nav__dropdown-option--active {
248
- font-weight: var(--typography-fontWeight-semibold);
372
+ /* no role: the weight that marks the current option -- a state or modifier
373
+ weight, not a text-content type. 700, the same as bd-link's
374
+ .bd-link--active and bd-tab-list's selected tab. */
375
+ font-weight: var(--typography-fontWeight-bold);
249
376
  background: var(--color-blue-50);
250
- color: var(--color-blue-700);
377
+ color: var(--color-text-primary);
251
378
  }
252
379
 
380
+ /* The current option does not move under the pointer, as on the bars. */
253
381
  .bd-anchor-nav__dropdown-option--active:hover {
254
- color: var(--color-blue-700);
382
+ color: var(--color-text-primary);
255
383
  background: var(--color-blue-50);
256
384
  }
257
385
 
@@ -259,33 +387,13 @@ export const anchorNavStyles = css`
259
387
  flex-shrink: 0;
260
388
  }
261
389
 
262
- .bd-anchor-nav__cta {
263
- font-family: var(--typography-fontFamily-sans);
264
- font-size: var(--typography-fontSize-lg);
265
- font-weight: var(--typography-fontWeight-semibold);
266
- line-height: var(--typography-lineHeight-normal);
267
- padding: var(--spacing-10) var(--spacing-20);
268
- border: none;
269
- border-radius: var(--radius-md);
270
- cursor: pointer;
271
- background: var(--color-red-500);
272
- color: var(--color-neutral-0);
273
- text-decoration: none !important;
274
- transition: background var(--transition-duration-fast) var(--transition-easing-smooth);
275
- }
276
-
277
- .bd-anchor-nav__cta:hover {
278
- background: var(--color-red-600);
279
- color: var(--color-neutral-0);
280
- text-decoration: none !important;
281
- }
282
-
283
- .bd-anchor-nav__cta:active {
284
- background: var(--color-red-700);
285
- color: var(--color-neutral-0);
286
- }
287
-
288
- .bd-anchor-nav__cta::after {
390
+ /* The .bd-anchor-nav__cta rules stood here: a base rule, hover, active,
391
+ focus-visible, an ::after reset and a full-width rule below md. The class
392
+ appears nowhere but this stylesheet -- not in anchor-nav.js, not in a story
393
+ -- because the CTA became a slot, and ::slotted([slot="cta"]) one rule up
394
+ is what styles it now. Measured across 556 stories: 0 matches in 14 shadow
395
+ roots. */
396
+ .bd-anchor-nav__dropdown-option::after {
289
397
  display: none;
290
398
  }
291
399
 
@@ -302,9 +410,17 @@ export const anchorNavStyles = css`
302
410
  transition: none !important;
303
411
  animation: none !important;
304
412
  }
413
+
414
+ /* The underline grows via a transition, not an animation, so the rule
415
+ above never reached it. Same for the chevron and the option hover. */
416
+ .anchor-link,
417
+ .bd-anchor-nav__dropdown-chevron,
418
+ .bd-anchor-nav__dropdown-option {
419
+ transition: none !important;
420
+ }
305
421
  }
306
422
 
307
- @media (max-width: 768px) {
423
+ @media ${unsafeCSS(below('md'))} {
308
424
  .bd-anchor-nav__inner {
309
425
  flex-direction: column;
310
426
  align-items: stretch;
@@ -344,9 +460,5 @@ export const anchorNavStyles = css`
344
460
  margin-top: var(--spacing-0);
345
461
  }
346
462
 
347
- .bd-anchor-nav__cta {
348
- width: 100%;
349
- box-sizing: border-box;
350
- }
351
463
  }
352
464
  `;
@@ -1,8 +1,12 @@
1
- import { LitElement, html, nothing } from "lit";
2
- import { tokens } from "../../tokens/tokens.js";
1
+ import { LitElement, html, nothing } from "lit";
2
+ // Installs the design tokens into document scope; see src/tokens/tokens.js
3
+ import "../../tokens/tokens.js";
4
+ import "../icons/arrow-down-icon.js";
3
5
  import "../button/button.js";
4
6
  import "../link/link.js";
5
7
  import { anchorNavStyles } from "./anchor-nav.css.js";
8
+ import { ensembleCSS } from "../shared/ensemble.css.js";
9
+ import { matchesBelow } from "../shared/token-scales.js";
6
10
 
7
11
  function parseLengthToPx(value) {
8
12
  const s = (value || "").trim();
@@ -37,7 +41,7 @@ class BdAnchorNav extends LitElement {
37
41
  stickyTop : { type: String, attribute: "sticky-top" }
38
42
  };
39
43
 
40
- static styles = [tokens, anchorNavStyles];
44
+ static styles = [ensembleCSS, anchorNavStyles];
41
45
 
42
46
  constructor() {
43
47
  super();
@@ -122,11 +126,6 @@ class BdAnchorNav extends LitElement {
122
126
  const links = this.renderRoot?.querySelector(".anchor-links--desktop");
123
127
  if (links && "ResizeObserver" in window) {
124
128
  this._indicatorResizeObserver = new ResizeObserver(() => {
125
- console.log("[anchor-nav] ResizeObserver fired", {
126
- isSticky : this.classList.contains("is-sticky"),
127
- navRect : this.getBoundingClientRect(),
128
- linksRect: links.getBoundingClientRect()
129
- });
130
129
  this._updateIndicator("ResizeObserver");
131
130
  });
132
131
  this._indicatorResizeObserver.observe(links);
@@ -143,7 +142,10 @@ class BdAnchorNav extends LitElement {
143
142
 
144
143
  const left = activeLink.offsetLeft;
145
144
  const width = activeLink.offsetWidth;
146
- const top = activeLink.offsetTop + activeLink.offsetHeight + 14;
145
+ // The bar's bottom edge is the inner's padding-bottom below the link.
146
+ const inner = this.renderRoot.querySelector(".bd-anchor-nav__inner");
147
+ const gap = inner ? parseFloat(getComputedStyle(inner).paddingBottom) || 0 : 0;
148
+ const top = activeLink.offsetTop + activeLink.offsetHeight + gap;
147
149
 
148
150
  if (!this._indicatorReady) {
149
151
  indicator.style.transition = "none";
@@ -167,7 +169,7 @@ class BdAnchorNav extends LitElement {
167
169
  }
168
170
 
169
171
  _handleMobileFullWidth() {
170
- const isMobile = window.matchMedia("(max-width: 768px)").matches;
172
+ const isMobile = matchesBelow('md');
171
173
  const ctaSlot = this.shadowRoot?.querySelector('slot[name="cta"]');
172
174
 
173
175
  if (!ctaSlot) return;
@@ -242,17 +244,6 @@ class BdAnchorNav extends LitElement {
242
244
  this._onStickyScroll();
243
245
  };
244
246
 
245
- this._onStickyResize = () => {
246
- this._stickyOriginalTop = null;
247
- if (this.classList.contains("is-sticky")) {
248
- const parent = this.parentElement;
249
- const parentRect = parent.getBoundingClientRect();
250
- this.style.setProperty("--sticky-left", `${parentRect.left}px`);
251
- this.style.setProperty("--sticky-width", `${parentRect.width}px`);
252
- }
253
- this._onStickyScroll();
254
- };
255
-
256
247
  window.addEventListener("scroll", this._onStickyScroll, { passive: true });
257
248
  window.addEventListener("resize", this._onStickyResize, { passive: true });
258
249
  requestAnimationFrame(() => this._onStickyScroll());
@@ -318,6 +309,8 @@ class BdAnchorNav extends LitElement {
318
309
  if (e.key === "Escape" && this._dropdownOpen) {
319
310
  this._dropdownOpen = false;
320
311
  this.requestUpdate();
312
+ this.updateComplete.then(() =>
313
+ this.renderRoot?.querySelector(".bd-anchor-nav__dropdown-toggle")?.focus());
321
314
  }
322
315
  }
323
316
 
@@ -372,7 +365,7 @@ class BdAnchorNav extends LitElement {
372
365
  }
373
366
  }
374
367
 
375
- const isMobile = window.matchMedia("(max-width: 768px)").matches;
368
+ const isMobile = matchesBelow('md');
376
369
  const firstHref = resolved[0]?.href.replace(/^#/, "") || "anchor-1-section";
377
370
  const first = document.getElementById(firstHref);
378
371
  let nextCta;
@@ -390,7 +383,7 @@ class BdAnchorNav extends LitElement {
390
383
  _playMobileDropdownLabelSwap() {
391
384
  if (typeof window === "undefined") return;
392
385
  if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
393
- if (!window.matchMedia("(max-width: 768px)").matches) return;
386
+ if (!matchesBelow('md')) return;
394
387
  const el = this.renderRoot?.querySelector(".bd-anchor-nav__dropdown-label");
395
388
  if (!el) return;
396
389
  el.classList.remove("bd-anchor-nav__dropdown-label--swap");
@@ -475,12 +468,11 @@ class BdAnchorNav extends LitElement {
475
468
  return html`
476
469
  <bd-link
477
470
  href="${href}"
478
- kind="${isActive ? "primary" : "secondary"}"
471
+ variant="primary"
479
472
  no-underline
480
473
  class="anchor-link ${isActive ? "active" : ""}"
481
- color="var(--color-neutral-900)"
482
474
  ?active=${isActive}
483
- aria-current=${isActive ? "true" : nothing}
475
+ aria-current=${isActive ? "location" : nothing}
484
476
  @click=${(e) => this.handleClick(e, id, href)}
485
477
  >${title}</bd-link>
486
478
  `;
@@ -494,7 +486,7 @@ class BdAnchorNav extends LitElement {
494
486
  return html`
495
487
  <nav aria-label=${this.navLabel}>
496
488
  <div
497
- class="bd-anchor-nav__inner"
489
+ class="bd-ensemble bd-anchor-nav__inner"
498
490
  part="inner"
499
491
  style="${innerStyle}"
500
492
  ?data-mobile-cta-visible=${this._mobileCtaRevealed}
@@ -507,35 +499,29 @@ class BdAnchorNav extends LitElement {
507
499
  class="bd-anchor-nav__dropdown-toggle"
508
500
  aria-expanded=${this._dropdownOpen ? "true" : "false"}
509
501
  aria-controls=${this._panelId}
510
- aria-haspopup="listbox"
511
502
  @click=${this._toggleDropdown}
512
503
  >
513
504
  <span class="bd-anchor-nav__dropdown-label">${dropdownLabel}</span>
514
505
  <span class="bd-anchor-nav__dropdown-chevron" aria-hidden="true">
515
- <svg width="20" height="20" viewBox="0 0 20 20" fill="none">
516
- <path d="M5 8l5 5 5-5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
517
- </svg>
506
+ <bd-arrow-down-icon size="md"></bd-arrow-down-icon>
518
507
  </span>
519
508
  </button>
520
509
  <div
521
510
  class="bd-anchor-nav__dropdown-panel"
522
511
  id=${this._panelId}
523
- role="listbox"
524
- aria-label=${this.navLabel}
525
512
  ?hidden=${!this._dropdownOpen}
526
513
  >
527
- <ul class="bd-anchor-nav__dropdown-list" role="presentation">
514
+ <ul class="bd-anchor-nav__dropdown-list">
528
515
  ${resolved.map(({ id, title, href }) => {
529
516
  const isActive = this.activeId === id;
530
517
  return html`
531
- <li role="presentation">
532
- <button
533
- type="button"
534
- role="option"
518
+ <li>
519
+ <a
520
+ href="${href}"
535
521
  class="bd-anchor-nav__dropdown-option ${isActive ? "bd-anchor-nav__dropdown-option--active" : ""}"
536
- aria-selected=${isActive ? "true" : "false"}
522
+ aria-current=${isActive ? "location" : nothing}
537
523
  @click=${(e) => this._selectFromDropdown(e, id, href)}
538
- >${title}</button>
524
+ >${title}</a>
539
525
  </li>
540
526
  `;
541
527
  })}