@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
@@ -32,16 +32,22 @@ export default css`
32
32
 
33
33
  .bd-list[type="ordered"].vertical ::slotted(li)::before {
34
34
  content: counter(bd-ordered-counter) ". ";
35
+ /* no role: the ordered-list number -- a glyph/marker/placeholder box, not running
36
+ prose. See list-item.css.js's .bd-list-item-marker::before for the
37
+ argument. */
35
38
  font-weight: var(--typography-fontWeight-semibold);
36
- color: var(--color-neutral-600);
39
+ color: var(--color-text-muted);
37
40
  margin-right: var(--spacing-8);
38
41
  }
39
42
 
40
43
  /* Unordered list markers for vertical */
41
44
  .bd-list[type="unordered"].vertical ::slotted(li)::before {
42
45
  content: "•";
46
+ /* no role: the unordered-list bullet -- a glyph/marker/placeholder box, not running
47
+ prose. See list-item.css.js's .bd-list-item-marker::before for the
48
+ argument. */
43
49
  font-weight: var(--typography-fontWeight-semibold);
44
- color: var(--color-neutral-600);
50
+ color: var(--color-text-muted);
45
51
  margin-right: var(--spacing-8);
46
52
  }
47
53
 
@@ -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 listCSS from "./list.css.js";
4
5
 
5
6
  export class BdList extends LitElement {
@@ -38,7 +39,7 @@ export class BdList extends LitElement {
38
39
  `;
39
40
  }
40
41
 
41
- static styles = [tokens, listCSS];
42
+ static styles = [listCSS];
42
43
  }
43
44
 
44
45
  customElements.define("bd-list", BdList);
@@ -0,0 +1,222 @@
1
+ import { html } from "lit";
2
+ import "./list.js";
3
+ import "./list-item/list-item.js";
4
+
5
+ export default {
6
+ title : "Atoms/List",
7
+ component : "bd-list",
8
+ tags : ["autodocs"],
9
+ parameters: {
10
+ docs: {
11
+ description: {
12
+ component: `
13
+ **\`bd-list\`** renders the real \`<ul>\` or \`<ol>\` and lays its items out. What
14
+ it does **not** currently do is draw markers or apply its own outer spacing —
15
+ three of its five properties are largely inert, and this story exists partly to
16
+ make that visible. Every claim below was measured in the browser, not read off
17
+ the stylesheet.
18
+
19
+ ### The \`type\` axis only chooses the tag
20
+
21
+ \`type\` is reflected on the host, but every rule that depends on it targets the
22
+ **inner** element — \`.bd-list[type="ordered"]\`. The inner \`<ol>\` carries
23
+ \`class\` and \`start\` and no \`type\` attribute at all, so
24
+ \`inner.matches('.bd-list[type="ordered"]')\` is **false** and none of those
25
+ rules apply. Measured on the Ordered story: \`::before\` content is \`none\`,
26
+ \`counter-increment\` is \`none\`, and all three items sit at the same left offset.
27
+ Combined with \`list-style: none\` on the base rule, **no marker is drawn for
28
+ either type.**
29
+
30
+ The bullet and counter rules also reach through \`::slotted(li)::before\`, and a
31
+ pseudo-element of slotted content is not stylable in browsers today — so they
32
+ would still not paint even with the attribute fixed.
33
+
34
+ ### \`spacing\` and \`variant\` do not move the outer margin
35
+
36
+ \`.bd-list.md\` sets \`margin: 16px 0\`, but two rules later in the same sheet —
37
+ \`.bd-list:first-child { margin-top: 0 }\` and \`.bd-list:last-child
38
+ { margin-bottom: 0 }\` — carry the same specificity and win on order. The inner
39
+ list is the **only** child of the shadow root, so it is always both, and the
40
+ margin is always zero. Measured: \`0px\` top and bottom at every \`spacing\` and
41
+ \`variant\` value.
42
+
43
+ What is still live, measured: **\`variant\`** sets the gap between items in both
44
+ orientations — the \`::slotted(li)\` bottom margin vertically (default 8, compact
45
+ 4, spacious 12) and \`gap\` horizontally. **\`spacing\`** is live *only* when
46
+ horizontal, where it sets \`gap\` to 8/16/24; vertically it does nothing at all,
47
+ because no rule ties it to the item margin and its own outer margin is
48
+ cancelled.
49
+
50
+ ### So what is it good for
51
+
52
+ The semantics and the layout, which are real: a genuine \`<ul>\`/\`<ol>\` for
53
+ assistive technology, \`start\` on the \`<ol>\`, vertical or horizontal flow, and
54
+ the gap between items. For a visible marker, fill it with \`<bd-li>\`, which
55
+ draws its own — a bullet, a number, or the green tick — and is what
56
+ \`bd-terms-section\` and \`bd-accordion-bg\` actually do.
57
+
58
+ **Do not "fix" the bullets without checking the consumers first.** Every live
59
+ consumer fills this element with \`<bd-li>\`, so making \`bd-list\` draw its own
60
+ markers would give those pages two markers per row.
61
+ `
62
+ }
63
+ }
64
+ },
65
+ argTypes: {
66
+ type: {
67
+ control : { type: "inline-radio" },
68
+ options : ["unordered", "ordered"],
69
+ description: "Chooses the tag. Does NOT change the marker -- none is drawn."
70
+ },
71
+ spacing: {
72
+ control : { type: "inline-radio" },
73
+ options : ["sm", "md", "lg"],
74
+ description: "Intended as the outer margin (8/16/24) but cancelled by the "
75
+ + "first-child/last-child reset. Its only live effect is gap when horizontal; "
76
+ + "vertically it does nothing."
77
+ },
78
+ variant: {
79
+ control : { type: "inline-radio" },
80
+ options : ["default", "compact", "spacious"],
81
+ description: "Its outer margin is cancelled too; the per-item gap it sets is live."
82
+ },
83
+ orientation: {
84
+ control : { type: "inline-radio" },
85
+ options : ["vertical", "horizontal"],
86
+ description: "horizontal lays items in a row AND removes the markers."
87
+ },
88
+ start: {
89
+ control : { type: "number" },
90
+ description: "First number of an ordered list."
91
+ }
92
+ },
93
+ args: { type: "unordered", spacing: "md", variant: "default", orientation: "vertical", start: 1 }
94
+ };
95
+
96
+ const ITEMS = [
97
+ "Real-time protection for every device on the plan",
98
+ "A VPN with no traffic limit",
99
+ "Password manager across desktop and mobile"
100
+ ];
101
+
102
+ export const Default = {
103
+ render: ({ type, spacing, variant, orientation, start }) => html`
104
+ <bd-list
105
+ type=${type}
106
+ spacing=${spacing}
107
+ variant=${variant}
108
+ orientation=${orientation}
109
+ start=${start}
110
+ >
111
+ ${ITEMS.map(t => html`<li>${t}</li>`)}
112
+ </bd-list>
113
+ `,
114
+ parameters: {
115
+ docs: {
116
+ description: {
117
+ story: "Plain `<li>` children. Note there is no bullet: the rule that would "
118
+ + "draw one is gated on an attribute the inner element does not carry, and "
119
+ + "`list-style` is none — see the component notes above. Every axis is on the "
120
+ + "controls, so you can confirm that changing `spacing` or `variant` moves "
121
+ + "nothing on the outside of the list."
122
+ }
123
+ }
124
+ }
125
+ };
126
+
127
+ export const Ordered = {
128
+ args : { type: "ordered" },
129
+ render: ({ type, spacing, variant, orientation, start }) => html`
130
+ <bd-list
131
+ type=${type}
132
+ spacing=${spacing}
133
+ variant=${variant}
134
+ orientation=${orientation}
135
+ start=${start}
136
+ >
137
+ ${ITEMS.map(t => html`<li>${t}</li>`)}
138
+ </bd-list>
139
+ `,
140
+ parameters: {
141
+ docs: {
142
+ description: {
143
+ story: "A real `<ol>` — the tag and `start` are correct and reach assistive "
144
+ + "technology. The numbers are NOT drawn, for the reason in the component "
145
+ + "notes: the counter rules never match. Measured here, `counter-increment` "
146
+ + "is none on every item."
147
+ }
148
+ }
149
+ }
150
+ };
151
+
152
+ export const WithListItemAtoms = {
153
+ name : "Filled with bd-li",
154
+ render: () => html`
155
+ <bd-list type="unordered" spacing="md">
156
+ <bd-li variant="check" size="md">Included in this plan</bd-li>
157
+ <bd-li variant="check" size="md">Also included</bd-li>
158
+ <bd-li variant="none" size="md">Not part of this tier</bd-li>
159
+ </bd-list>
160
+ `,
161
+ parameters: {
162
+ docs: {
163
+ description: {
164
+ story: "The `<bd-li>` form, and the only one that shows a marker at all. "
165
+ + "Each item draws its own, so you get the `variant` markers including the "
166
+ + "green tick. This is what `bd-terms-section` and `bd-accordion-bg` use."
167
+ }
168
+ }
169
+ }
170
+ };
171
+
172
+ export const Horizontal = {
173
+ args : { orientation: "horizontal" },
174
+ render: ({ spacing, variant }) => html`
175
+ <bd-list type="unordered" orientation="horizontal" spacing=${spacing} variant=${variant}>
176
+ <li>Windows</li>
177
+ <li>macOS</li>
178
+ <li>Android</li>
179
+ <li>iOS</li>
180
+ </bd-list>
181
+ `,
182
+ parameters: {
183
+ docs: {
184
+ description: {
185
+ story: "A row, with the markers removed on purpose — bullets in a horizontal "
186
+ + "run read as separators rather than markers. `spacing` becomes the gap here "
187
+ + "instead of a margin."
188
+ }
189
+ }
190
+ }
191
+ };
192
+
193
+ export const SpacingAndVariant = {
194
+ name : "spacing vs variant",
195
+ render: () => html`
196
+ <div style="display:grid;gap:var(--spacing-32);font-family:var(--typography-fontFamily-sans)">
197
+ ${[
198
+ ["spacing=sm", { spacing: "sm", variant: "default" }],
199
+ ["spacing=lg", { spacing: "lg", variant: "default" }],
200
+ ["variant=compact", { spacing: "md", variant: "compact" }],
201
+ ["variant=spacious", { spacing: "md", variant: "spacious" }]
202
+ ].map(([label, a]) => html`
203
+ <div>
204
+ <div style="font-size:var(--typography-fontSize-sm);color:var(--color-text-muted)">${label}</div>
205
+ <bd-list type="unordered" spacing=${a.spacing} variant=${a.variant}>
206
+ ${ITEMS.slice(0, 2).map(t => html`<li>${t}</li>`)}
207
+ </bd-list>
208
+ </div>
209
+ `)}
210
+ </div>
211
+ `,
212
+ parameters: {
213
+ docs: {
214
+ description: {
215
+ story: "The two spacing axes side by side — and the point of the story is "
216
+ + "that the four look almost identical. The outer margins they set are "
217
+ + "cancelled by the first-child/last-child reset; what little separates them "
218
+ + "is the per-item bottom margin that `variant` still controls."
219
+ }
220
+ }
221
+ }
222
+ };
@@ -1,26 +1,37 @@
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
- :host {
5
- --bd-blue-color: var(--color-blue-500);
6
- --bd-accesibility-focus: var(--color-blue-800);
7
- }
8
-
9
5
  .bd-modal {
10
6
  position: fixed;
11
7
  top: var(--spacing-0);
12
8
  left: var(--spacing-0);
13
9
  width: 100%;
14
10
  height: 100%;
15
- background: rgba(0, 0, 0, 0.5);
11
+ /* The scrim. Expressed as a mix over the palette rather than a raw rgba,
12
+ which is the house pattern -- --color-border-container-inverse and
13
+ spinner's two private aliases are written the same way. A raw
14
+ rgba(0,0,0,0.5) is a black no theme can reach; this one follows
15
+ --color-neutral-1000. Verified pixel-identical to the rgba it replaces.
16
+ .
17
+ no role: a page scrim has no role, and with one consumer it should not
18
+ have one yet. If a second component ever needs to darken the page behind
19
+ itself, that is the point to name it. */
20
+ background: color-mix(in srgb, var(--color-neutral-1000) 50%, transparent);
16
21
  display: flex;
17
22
  justify-content: center;
18
23
  align-items: center;
19
- z-index: 9999;
24
+ z-index: var(--z-modal);
20
25
  backdrop-filter: blur(var(--spacing-12));
21
26
  opacity: 0;
22
27
  transform: scale(0.9);
23
- transition: opacity 0.3s ease, transform 0.3s ease;
28
+ transition: opacity var(--transition-duration-slow) var(--transition-easing-ease), transform var(--transition-duration-slow) var(--transition-easing-ease);
29
+ /* The counterpart of the pointer-events: auto in the [open] rule below,
30
+ which was written without it. A closed modal is still a full-viewport
31
+ fixed layer at this z-index, so without this it sits invisibly over the
32
+ whole page and swallows every click: elementsFromPoint at the centre of
33
+ the viewport returned [BD-MODAL, HTML] with the modal closed. */
34
+ pointer-events: none;
24
35
  }
25
36
 
26
37
  :host([open]) .bd-modal {
@@ -29,38 +40,117 @@ export default css`
29
40
  pointer-events: auto;
30
41
  }
31
42
 
43
+ /* max-height and overflow, because without them the bottom of a tall dialog
44
+ is simply gone. Measured on Components/Modal "Long Modal Text": the panel
45
+ is 506px tall at every viewport height, so at 500px and at 360px its
46
+ bottom edge -- and the Close button on it -- sat past the viewport with
47
+ nothing scrollable anywhere. The panel could not scroll (overflow
48
+ visible, no max-height) and neither could the page (the scrim is
49
+ position: fixed at 100% height, so the document never grows), which left
50
+ the only control in the dialog unreachable by any means.
51
+
52
+ --spacing-128 rather than --spacing-64, and the arithmetic is the reason.
53
+ This box is content-box, so the cap applies to the content and the 2em
54
+ padding is added outside it: subtracting 64 produced a panel of exactly
55
+ the viewport height at every constrained height -- 436 + 64 = 500 at a
56
+ 500px viewport, 296 + 64 = 360 at 360 -- with no scrim band at all.
57
+ 128 is that 64 of padding plus the 64 of scrim the band wants, which
58
+ lands the panel 32px from the top and bottom edges.
59
+
60
+ box-sizing: border-box would express the same thing more directly and is
61
+ deliberately not used here: it also makes max-width mean the border box,
62
+ which took the panel from 564px wide to 500 and rewrapped its text a line
63
+ taller. That is a visible change to an axis this fix has no business
64
+ touching, so the arithmetic goes in the calc instead. */
32
65
  .bd-modal-content {
33
- background: #fff;
66
+ /* --color-surface-default, the role, not --color-neutral-0, the primitive
67
+ it resolves to. Same value; the category is the point, and CLAUDE.md's
68
+ "same primitive value is not same semantic meaning" section exists for
69
+ exactly this. Found by check:color-coverage once the background shorthand came into
70
+ its scope -- it had been invisible because the check counted
71
+ background-color: and this package almost never writes that. */
72
+ background: var(--color-surface-default);
34
73
  padding: 2em;
35
- border-radius: var(--spacing-12);
74
+ border-radius: var(--radius-xl);
36
75
  max-width: 500px;
76
+ max-height: calc(100vh - var(--spacing-128));
77
+ overflow-y: auto;
37
78
  text-align: start;
38
- box-shadow: var(--spacing-0) var(--spacing-2) var(--spacing-8) rgba(0, 0, 0, 0.2);
39
- font-family: var(--typography-fontFamily-sans);
40
- }
79
+ /* --shadow-md, the role this package already uses for a floating overlay
80
+ surface: bd-tooltip's bubble and bd-anchor-nav's dropdown panel both name
81
+ it, and this panel is the third of the same kind.
82
+
83
+ The shadow was built out of --spacing-0/2/8, which is a spacing scale
84
+ doing a depth role's job -- and spacing is rem, so it grew with the
85
+ reader. Measured at a 24px root: this panel's shadow went from
86
+ 0 2px 8px to 0 3px 12px while the tooltip's --shadow-md held exactly
87
+ still. A drop shadow is a fixed optical depth, not a distance that
88
+ should scale with text.
41
89
 
42
- .bd-modal-content h2 {
43
- margin: var(--spacing-0) var(--spacing-0) 1em var(--spacing-0);
90
+ Visible, and intended: the shadow becomes the two-layer --shadow-md
91
+ rather than a single 8px blur at 0.2 alpha. The panel's separation from
92
+ the page is carried by the scrim above it -- 0.5 alpha and a 12px
93
+ backdrop blur -- so the shadow is doing detail work here, not the
94
+ heavy lifting. */
95
+ box-shadow: var(--shadow-md);
44
96
  font-family: var(--typography-fontFamily-sans);
45
97
  }
46
98
 
99
+ /* The title's spacing is set through bd-h's own paddingBottom prop, in
100
+ modal.js. A ".bd-modal-content h2" rule stood here and could never match:
101
+ the h2 is inside bd-h's shadow root, so a descendant selector from this
102
+ stylesheet does not reach it. The declared 1em resolved to 0 in all 80
103
+ measured story x viewport combinations, which is why the title sat flush
104
+ on its description. */
105
+ /* This is a <button> the component renders itself rather than a slotted
106
+ bd-button, and that is not going to change here: the element owns the
107
+ close behaviour and there is nothing for a page to pass in. What it can
108
+ stop doing is disagreeing with the atom about the shape of a button.
109
+
110
+ Measured against Atoms/Button, variant=primary size=md: the fill is the
111
+ same step, and every other axis was different. The padding was em
112
+ literals -- 0.5em/1em -- which is the spacing scale spelled in a unit that
113
+ is not on it, and the radius was --radius-lg against the atom's
114
+ --radius-sm, so the same fill came out with 8px corners here and 4px two
115
+ components over. The margin-top was a third em literal.
116
+
117
+ The values now match the atom's md size (8/16 at --radius-sm) and are
118
+ spelled with the tokens it uses. Visible: corners tighten from 8px to
119
+ 4px. */
47
120
  .bd-modal-content button {
48
- margin-top: 1em;
49
- padding: 0.5em 1em;
50
- background: var(--bd-blue-color);
51
- color: #fff;
121
+ margin-top: var(--spacing-16);
122
+ padding: var(--spacing-8) var(--spacing-16);
123
+ background: var(--color-surface-brand);
124
+ color: var(--color-text-inverse);
52
125
  border: none;
53
- border-radius: var(--spacing-8);
126
+ border-radius: var(--radius-sm);
54
127
  cursor: pointer;
55
128
  font-family: var(--typography-fontFamily-sans);
56
129
  }
57
130
 
58
131
  .bd-modal-content button:focus-visible {
59
- outline: var(--spacing-2) solid var(--bd-accesibility-focus);
60
- outline-offset: var(--spacing-2);
132
+ /* the one focus ring — see Foundations/Focus */
133
+ outline: none;
134
+ box-shadow: var(--focus-outline-primary);
135
+ }
136
+
137
+ /* The scrim scales and fades in. Measured before this: with
138
+ prefers-reduced-motion: reduce the transition still reported
139
+ 0.3s on opacity and transform, so a reader who asked for less motion got
140
+ the panel zooming in anyway. Every other animated component in this
141
+ package honours the query -- see the tooltip two files over. */
142
+ @media (prefers-reduced-motion: reduce) {
143
+ .bd-modal {
144
+ transition: none;
145
+ transform: none;
146
+ }
147
+
148
+ :host([open]) .bd-modal {
149
+ transform: none;
150
+ }
61
151
  }
62
152
 
63
- @media (max-width: 768px) {
153
+ @media ${unsafeCSS(below('md'))} {
64
154
  .bd-modal-content {
65
155
  max-width: 90%;
66
156
  padding: 1.5em;
@@ -1,9 +1,35 @@
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
- import modalCSS from "../modal/modal.css";
5
+ import modalCSS from "../modal/modal.css.js";
5
6
  import "../paragraph/paragraph.js";
6
7
 
8
+ /**
9
+ * A dialog surface: a scrim, a centred panel, a title, a description and a
10
+ * close control. The consuming page owns `open` and reacts to close-modal.
11
+ *
12
+ * `role="dialog"` is on the panel, and it is what makes the two labels this
13
+ * element has always declared mean anything. Measured before it: the full
14
+ * accessibility tree for an open modal was RootWebArea, image, heading,
15
+ * paragraph, button -- no dialog node at any level, so `aria-labelledby` and
16
+ * `aria-describedby` pointed at real targets from an element with no role to
17
+ * name. With the role, the dialog is exposed and named "VPN Protection" from
18
+ * the bd-h it already pointed at; the name resolves across bd-h's shadow
19
+ * boundary because the title is slotted light-DOM text.
20
+ *
21
+ * `aria-modal="true"` is deliberately NOT set. It is a claim that the rest of
22
+ * the page is unavailable, and it is not: measured with a real keyboard, one
23
+ * Tab reaches the close button and the next leaves the dialog entirely, with
24
+ * seven focusable elements still reachable outside it. Setting the attribute
25
+ * without focus containment would tell a screen reader something untrue.
26
+ * Making it true is a dialog rework -- containment, an opener to restore focus
27
+ * to, and a scroll lock -- and that is a decision with more than one valid
28
+ * shape, so P6C.4 reports it rather than picking one.
29
+ *
30
+ * The icon is `alt=""`. It was `alt="icon"`, which a screen reader announced
31
+ * as the word "icon" beside a title that already says what the dialog is.
32
+ */
7
33
  export class BdModal extends LitElement {
8
34
  static properties = {
9
35
  open : { type: Boolean, reflect: true },
@@ -16,20 +42,70 @@ export class BdModal extends LitElement {
16
42
  this.dispatchEvent(new CustomEvent("close-modal", { bubbles: true, composed: true }));
17
43
  }
18
44
 
45
+ /**
46
+ * Escape closes through the same channel as the backdrop click: this element
47
+ * does not own `open`, the consuming page does, so both gestures dispatch
48
+ * close-modal and let the page decide. The channel already existed and
49
+ * Escape was the one way in that was missing -- measured, Escape on an open
50
+ * modal left open true and did nothing at all.
51
+ *
52
+ * On the document, guarded on `open`, because focus is normally NOT inside
53
+ * this dialog: nothing moves it there when the dialog opens, so a listener
54
+ * on the host would only fire after the user had already Tabbed in. Measured
55
+ * with the host-scoped version first -- Escape with focus on body left open
56
+ * true, which is every real case. The guard means a closed modal listens for
57
+ * nothing, and propagation is left alone so a page that wants to react to
58
+ * the same Escape still can.
59
+ */
60
+ connectedCallback() {
61
+ super.connectedCallback();
62
+ this._onKeydown = e => {
63
+ if (e.key !== "Escape" || !this.open) return;
64
+ this._onClose();
65
+ };
66
+ document.addEventListener("keydown", this._onKeydown);
67
+ }
68
+
69
+ disconnectedCallback() {
70
+ document.removeEventListener("keydown", this._onKeydown);
71
+ super.disconnectedCallback();
72
+ }
73
+
74
+ /**
75
+ * Closing makes the dialog inert, which stops anything inside being reached
76
+ * — but focus that was ALREADY inside stays there, on a subtree the user can
77
+ * no longer see or operate. Measured: after close, document.activeElement was
78
+ * still BD-MODAL with the close button active inside it.
79
+ *
80
+ * This releases that focus. It is deliberately not focus *restoration*:
81
+ * returning focus to whatever opened the dialog needs the opener recorded,
82
+ * which is part of the dialog rework this fix is scoped out of.
83
+ */
84
+ updated(changed) {
85
+ if (!changed.has("open") || this.open) return;
86
+ if (this.renderRoot?.activeElement) this.renderRoot.activeElement.blur();
87
+ }
88
+
19
89
  render() {
20
90
  return html`
21
- <div class="bd-modal" @click="${this._onClose}" aria-hidden="${!this.open}">
91
+ <div
92
+ class="bd-modal"
93
+ @click="${this._onClose}"
94
+ aria-hidden="${!this.open}"
95
+ ?inert="${!this.open}"
96
+ >
22
97
  <div
23
98
  class="bd-modal-content"
24
99
  @click="${(e) => e.stopPropagation()}"
100
+ role="dialog"
25
101
  aria-labelledby="modal-title"
26
102
  aria-describedby="modal-description"
27
103
  >
28
104
  ${this.icon
29
- ? html`<img src="${this.icon}" alt="icon" class="bd-carousel-modal-icon" />`
105
+ ? html`<img src="${this.icon}" alt="" class="bd-carousel-modal-icon" />`
30
106
  : ""}
31
- <bd-h as="h2" id="modal-title">${this.title}</bd-h>
32
- <bd-p kind="regular" id="modal-description">${this.modalText}</bd-p>
107
+ <bd-h as="h2" id="modal-title" paddingBottom="16">${this.title}</bd-h>
108
+ <bd-p variant="regular" id="modal-description">${this.modalText}</bd-p>
33
109
  <button @click="${this._onClose}" aria-label="Close modal">Close</button>
34
110
  </div>
35
111
  </div>
@@ -37,6 +113,6 @@ export class BdModal extends LitElement {
37
113
  }
38
114
  }
39
115
 
40
- BdModal.styles = [tokens, modalCSS];
116
+ BdModal.styles = [modalCSS];
41
117
 
42
118
  customElements.define("bd-modal", BdModal);
@@ -15,7 +15,7 @@ export default {
15
15
  <bd-modal
16
16
  .open="${true}"
17
17
  title="VPN Protection"
18
- icon="/assets/vpn.svg"
18
+ icon="/icons/privacy_protection.png"
19
19
  modalText="Our VPN encrypts your connection."
20
20
  @close-modal="${() => {}}"
21
21
  ></bd-modal>
@@ -50,7 +50,7 @@ export default {
50
50
  },
51
51
  modalText: {
52
52
  control : 'text',
53
- description: 'Modal body text rendered as `<bd-p kind="regular">`',
53
+ description: 'Modal body text rendered as `<bd-p variant="regular">`',
54
54
  table : { type: { summary: 'string' }, defaultValue: { summary: '' }, category: 'Content' }
55
55
  },
56
56
  icon: {
@@ -65,7 +65,7 @@ const defaultArgs = {
65
65
  open : true,
66
66
  title : 'VPN Protection',
67
67
  modalText: 'Our VPN encrypts your internet traffic and hides your IP address, keeping you safe on public networks.',
68
- icon : '/assets/vpn.svg'
68
+ icon : '/icons/privacy_protection.png'
69
69
  };
70
70
 
71
71
  const render = (args) => html`
@@ -86,7 +86,7 @@ export const Default = {
86
86
  .open="${true}"
87
87
  title="VPN Protection"
88
88
  modalText="Our VPN encrypts your internet traffic and hides your IP address, keeping you safe on public Wi-Fi networks and preventing tracking."
89
- icon="/assets/vpn.svg"
89
+ icon="/icons/privacy_protection.png"
90
90
  ></bd-modal>
91
91
  `,
92
92
  parameters: { docs: { description: { story: 'Modal rendered in the open state with icon, title, and body text.' } } }
@@ -100,7 +100,7 @@ export const Closed = {
100
100
  .open="${false}"
101
101
  title="VPN Protection"
102
102
  modalText="This modal is closed."
103
- icon="/assets/vpn.svg"
103
+ icon="/icons/privacy_protection.png"
104
104
  ></bd-modal>
105
105
  `,
106
106
  parameters: { docs: { description: { story: 'Modal with `open=false` — renders in the DOM with `aria-hidden="true"`. Visibility depends on CSS handling of the open state.' } } }
@@ -124,7 +124,7 @@ export const LongText = {
124
124
  <bd-modal
125
125
  .open="${true}"
126
126
  title="Behavioral Analysis"
127
- icon="/assets/analysis.svg"
127
+ icon="/icons/device_protection.png"
128
128
  modalText="Bitdefender's behavioral detection technology monitors active applications in real time for suspicious activity. Unlike traditional signature-based detection, behavioral analysis can identify zero-day threats and novel malware variants by observing what a program does, not just what it looks like. When suspicious behavior is detected — such as a process attempting to encrypt files, modify system registries, or communicate with known malicious servers — Bitdefender immediately quarantines the threat before damage can occur."
129
129
  ></bd-modal>
130
130
  `,
@@ -135,9 +135,9 @@ export const DifferentTitles = {
135
135
  name : 'Various Content Types',
136
136
  render: () => html`
137
137
  <div style="display:flex; flex-direction:column; gap:32px;">
138
- <bd-modal .open="${true}" title="VPN Protection" icon="/assets/vpn.svg" modalText="Unlimited encrypted VPN traffic across 200+ servers."></bd-modal>
138
+ <bd-modal .open="${true}" title="VPN Protection" icon="/icons/privacy_protection.png" modalText="Unlimited encrypted VPN traffic across 200+ servers."></bd-modal>
139
139
  <bd-modal .open="${true}" title="Password Manager" modalText="Store and autofill passwords securely across all your devices."></bd-modal>
140
- <bd-modal .open="${true}" title="Parental Controls" icon="/assets/parental.svg" modalText="Monitor your children's online activity and set screen time limits."></bd-modal>
140
+ <bd-modal .open="${true}" title="Parental Controls" icon="/icons/bd-icon-family.png" modalText="Monitor your children's online activity and set screen time limits."></bd-modal>
141
141
  </div>
142
142
  `,
143
143
  parameters: { docs: { description: { story: 'Three modals stacked for visual comparison of different content configurations.' } } }
@@ -169,7 +169,7 @@ export const MobileView = {
169
169
  .open="${true}"
170
170
  title="VPN Protection"
171
171
  modalText="Unlimited encrypted VPN traffic and IP masking."
172
- icon="/assets/vpn.svg"
172
+ icon="/icons/privacy_protection.png"
173
173
  ></bd-modal>
174
174
  `,
175
175
  parameters: {