@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
@@ -0,0 +1,342 @@
1
+ import { html } from 'lit';
2
+ import { docsPage, readAllCssText, refSection, resolve } from '../tokens/story-chrome.js';
3
+
4
+ // every atom rendered below
5
+ import './heading/heading.js';
6
+ import './paragraph/paragraph.js';
7
+ import './display/display.js';
8
+ import './link/link.js';
9
+ import './highlight/highlight.js';
10
+ import './list/list-item/list-item.js';
11
+ import './button/button.js';
12
+ import './back/back.js';
13
+ import './input/input.js';
14
+ import './dropdown/dropdown.js';
15
+ import './checkbox/checkbox.js';
16
+ import './radio/radio.js';
17
+ import './image/image.js';
18
+ import './badge/badge.js';
19
+ import './divider/divider-horizontal.js';
20
+ import './divider/divider-vertical.js';
21
+ import './icons/plus-icon.js';
22
+ import './icons/globe-icon.js';
23
+ import './icons/close-icon.js';
24
+ import './label/label.js';
25
+ import './help-text/help-text.js';
26
+ import './caption/caption.js';
27
+ import './code/code.js';
28
+ import './annotation/annotation.js';
29
+ import './blockquote/blockquote.js';
30
+ import './textarea/textarea.js';
31
+ import './switch/switch.js';
32
+ import './fieldset/fieldset.js';
33
+ import './tag/tag.js';
34
+ import './avatar/avatar.js';
35
+ import './spinner/spinner.js';
36
+ import './progress/progress.js';
37
+ import './tooltip/tooltip.js';
38
+ import './alert/alert.js';
39
+ import './skeleton/skeleton.js';
40
+ import './video/video.js';
41
+ import './visually-hidden/visually-hidden.js';
42
+ import './picture/picture.js';
43
+
44
+ export default {
45
+ title: 'Atoms/Overview',
46
+ tags : ['autodocs']
47
+ };
48
+
49
+ const styles = html`
50
+ <style>
51
+ .atom-grid {
52
+ display: grid;
53
+ grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
54
+ gap: var(--spacing-16);
55
+ }
56
+
57
+ .atom {
58
+ border: var(--border-width-1) solid var(--color-neutral-100);
59
+ border-radius: var(--radius-md);
60
+ overflow: hidden;
61
+ }
62
+
63
+ .atom-head {
64
+ display: flex;
65
+ align-items: baseline;
66
+ justify-content: space-between;
67
+ gap: var(--spacing-8);
68
+ padding: var(--spacing-8) var(--spacing-12);
69
+ background: var(--color-neutral-50);
70
+ border-bottom: var(--border-width-1) solid var(--color-neutral-100);
71
+ }
72
+
73
+ .atom-name {
74
+ font-weight: var(--typography-fontWeight-semibold);
75
+ font-size: var(--typography-fontSize-sm);
76
+ }
77
+
78
+ .atom-tags {
79
+ font-family: var(--typography-fontFamily-mono);
80
+ font-size: var(--typography-fontSize-xxs);
81
+ color: var(--color-neutral-500);
82
+ text-align: right;
83
+ overflow-wrap: anywhere;
84
+ }
85
+
86
+ /* specimens vary wildly in size, so give each one a settled floor */
87
+ .atom-body {
88
+ padding: var(--spacing-16) var(--spacing-12);
89
+ min-height: var(--spacing-64);
90
+ display: flex;
91
+ align-items: center;
92
+ gap: var(--spacing-8);
93
+ flex-wrap: wrap;
94
+ }
95
+
96
+ .gap-table td:first-child,
97
+ .gap-table th:first-child {
98
+ white-space: nowrap;
99
+ }
100
+
101
+ .where {
102
+ font-family: var(--typography-fontFamily-mono);
103
+ font-size: var(--typography-fontSize-xxs);
104
+ }
105
+
106
+ .where[data-state='blog'] { color: var(--color-blue-700); }
107
+ .where[data-state='tokens'] { color: var(--color-green-800); }
108
+ .where[data-state='none'] { color: var(--color-neutral-500); }
109
+
110
+ .count {
111
+ font-weight: var(--typography-fontWeight-semibold);
112
+ }
113
+ </style>
114
+ `;
115
+
116
+ /* ============================================================
117
+ What we have
118
+ ============================================================ */
119
+
120
+ const ATOMS = [
121
+ ['Heading', 'typography', ['bd-h'],
122
+ html`<bd-h as="h4">Heading</bd-h>`],
123
+ ['Paragraph', 'typography', ['bd-p'],
124
+ html`<bd-p variant="regular">Body copy in a paragraph.</bd-p>`],
125
+ ['Display', 'typography', ['bd-display'],
126
+ html`<bd-display variant="sm">Display</bd-display>`],
127
+ ['Link', 'typography', ['bd-link'],
128
+ html`<bd-link href="#">A text link</bd-link>`],
129
+ ['Highlight', 'typography', ['bd-highlight'],
130
+ html`<bd-highlight>Highlighted</bd-highlight>`],
131
+ ['List item', 'typography', ['bd-li'],
132
+ html`<bd-li>A single list item</bd-li>`],
133
+ ['Button', 'action', ['bd-button', 'bd-button-link', 'bd-contact-button'],
134
+ html`<bd-button size="sm" variant="primary">Button</bd-button>`],
135
+ ['Back', 'action', ['bd-back'],
136
+ html`<bd-back label="Back"></bd-back>`],
137
+ ['Input', 'form', ['bd-custom-input', 'bd-custom-input-clipboard'],
138
+ html`<bd-custom-input label="Email" placeholder="you@example.com"></bd-custom-input>`],
139
+ ['Dropdown', 'form', ['bd-custom-dropdown'],
140
+ html`<bd-custom-dropdown label="Plan"></bd-custom-dropdown>`],
141
+ ['Checkbox', 'form', ['bd-checkbox'],
142
+ html`<bd-checkbox label="Remember me"></bd-checkbox>`],
143
+ ['Radio', 'form', ['bd-radio', 'bd-toggle-radio'],
144
+ html`<bd-radio name="p" value="a" label="Option"></bd-radio>`],
145
+ ['Image', 'media', ['bd-img'],
146
+ html`<bd-img src="/images/bd-header-img.jpg" alt="" width="120" height="70"></bd-img>`],
147
+ ['Picture', 'media', ['bd-picture'],
148
+ html`<span class="atom-tags">responsive &lt;picture&gt; with sources</span>`],
149
+ ['Icon', 'media', ['12 × bd-*-icon'],
150
+ html`<bd-plus-icon size="md"></bd-plus-icon>
151
+ <bd-globe-icon size="md"></bd-globe-icon>
152
+ <bd-close-icon size="md"></bd-close-icon>`],
153
+ ['Brand mark', 'media', ['8 × wordmark / award'],
154
+ html`<span class="atom-tags">fixed colour and aspect — off the icon scale</span>`],
155
+ ['Badge', 'feedback', ['bd-badge'],
156
+ html`<bd-badge tone="primary" variant="fill">New</bd-badge>
157
+ <bd-badge tone="success">Save 44%</bd-badge>
158
+ <bd-badge mode="count" tone="error" variant="fill">3</bd-badge>
159
+ <bd-badge mode="dot" tone="warning" variant="fill"></bd-badge>`],
160
+ ['Divider', 'separation', ['bd-divider-horizontal', 'bd-divider-vertical'],
161
+ html`<span style="display:block;width:100%"><bd-divider-horizontal></bd-divider-horizontal></span>`],
162
+ ['Label', 'form', ['bd-label'],
163
+ html`<bd-label required>Email address</bd-label>`],
164
+ ['Help text', 'form', ['bd-help-text'],
165
+ html`<bd-help-text tone="error">Enter a valid email address.</bd-help-text>`],
166
+ ['Textarea', 'form', ['bd-textarea'],
167
+ html`<bd-textarea rows="2" placeholder="Tell us more"></bd-textarea>`],
168
+ ['Switch', 'form', ['bd-switch'],
169
+ html`<bd-switch checked label="Real-time protection"></bd-switch>`],
170
+ ['Fieldset', 'form', ['bd-fieldset'],
171
+ html`<bd-fieldset legend="Alerts"><bd-switch label="Email"></bd-switch></bd-fieldset>`],
172
+ ['Caption', 'typography', ['bd-caption'],
173
+ html`<bd-caption>Source: Bitdefender Labs</bd-caption>`],
174
+ ['Code', 'typography', ['bd-code'],
175
+ html`<bd-code>var(--radius-md)</bd-code>`],
176
+ ['Blockquote', 'typography', ['bd-blockquote'],
177
+ html`<bd-blockquote attribution="Bitdefender Labs">Threats move fast.</bd-blockquote>`],
178
+ ['Annotation', 'typography', ['bd-footnote', 'bd-citation', 'bd-sup', 'bd-sub'],
179
+ html`<span style="font-family: var(--typography-fontFamily-sans)">99.8%<bd-footnote href="#n">1</bd-footnote>
180
+ · <bd-citation href="#">Report</bd-citation> · mc<bd-sup>2</bd-sup></span>`],
181
+ ['Tag', 'feedback', ['bd-tag'],
182
+ html`<bd-tag tone="brand">Brand</bd-tag> <bd-tag tone="success">Success</bd-tag>`],
183
+ ['Alert', 'feedback', ['bd-alert'],
184
+ html`<bd-alert tone="warning" heading="Check this.">Two devices are out of date.</bd-alert>`],
185
+ ['Spinner', 'feedback', ['bd-spinner'],
186
+ html`<bd-spinner></bd-spinner>`],
187
+ ['Progress', 'feedback', ['bd-progress'],
188
+ html`<span style="display:block;width:100%"><bd-progress value="64" label="Scan"></bd-progress></span>`],
189
+ ['Tooltip', 'feedback', ['bd-tooltip'],
190
+ html`<bd-tooltip text="Blocks trackers"><bd-badge>Hover</bd-badge></bd-tooltip>`],
191
+ ['Skeleton', 'feedback', ['bd-skeleton'],
192
+ html`<span style="display:block;width:100%"><bd-skeleton lines="2"></bd-skeleton></span>`],
193
+ ['Avatar', 'media', ['bd-avatar'],
194
+ html`<bd-avatar name="Ada Lovelace"></bd-avatar>`],
195
+ ['Video', 'media', ['bd-video'],
196
+ html`<span class="atom-tags">&lt;video&gt; with poster and controls</span>`],
197
+ ['Visually hidden', 'utility', ['bd-visually-hidden'],
198
+ html`<span class="atom-tags">in the a11y tree, out of view</span>`]
199
+ ];
200
+
201
+ /* The headline count is ATOMS.length, so a name listed twice inflates it and
202
+ renders a duplicate card. That is exactly what happened: bd-picture was
203
+ added a second time and the section claimed 37 atoms where 36 exist.
204
+ Nothing checked, because a duplicate is a perfectly valid array. */
205
+ const duplicateAtoms = ATOMS.map(([name]) => name)
206
+ .filter((name, i, all) => all.indexOf(name) !== i);
207
+ if (duplicateAtoms.length) {
208
+ console.warn(`Atoms/Overview lists ${duplicateAtoms.length} atom(s) twice: ${duplicateAtoms.join(', ')}`
209
+ + ' — the card grid and the headline count are both wrong until this is fixed.');
210
+ }
211
+
212
+
213
+ /* ============================================================
214
+ What is missing
215
+ ============================================================ */
216
+
217
+ const GAPS = [
218
+ // atom, category, state, why
219
+ ['Keyboard key', 'utility', 'none', 'deliberately skipped — no product surface documents shortcuts yet']
220
+ ];
221
+
222
+ const STATE_LABEL = { tokens: 'tokens only', blog: 'blog only', none: 'not built' };
223
+
224
+ /** Tokens belonging to an atom that was never built, counted from the loaded CSS. */
225
+ function orphanTokenCount() {
226
+ const css = readAllCssText();
227
+ const groups = [
228
+ 'typography-caption', 'typography-code', 'form-help-text', 'footnote', 'citation', 'math'
229
+ ];
230
+ return groups.reduce(
231
+ (total, g) => total + (css.match(new RegExp(`--${g}-[A-Za-z0-9-]+\\s*:`, 'g')) || []).length,
232
+ 0
233
+ );
234
+ }
235
+
236
+ export const Overview = () => {
237
+ return html`
238
+ ${styles}
239
+ ${docsPage({
240
+ title: 'Atoms',
241
+ lede : html`The smallest useful pieces of the system. An atom here renders one UI primitive,
242
+ is not built out of other <code>bd-*</code> components, and would mean nothing broken down
243
+ further. Anything composed of atoms stays under <b>Components</b>.`,
244
+ note: html`<b>${ATOMS.length}</b> atoms, every one styled only from design tokens —
245
+ <code>npm run lint:tokens</code> fails on a literal. <b>${orphanTokenCount()}</b> tokens
246
+ that previously had no component to use them now do: caption, code, help text, footnote,
247
+ citation and maths notation were fully specified in the token layer and never built.`,
248
+ children: html`
249
+ ${refSection({
250
+ name : 'What we have',
251
+ meta : `${ATOMS.length} atoms`,
252
+ children: html`
253
+ <div class="atom-grid">
254
+ ${ATOMS.map(
255
+ ([name, cat, tags, specimen]) => html`
256
+ <div class="atom">
257
+ <div class="atom-head">
258
+ <span class="atom-name">${name}</span>
259
+ <span class="atom-tags">${cat}</span>
260
+ </div>
261
+ <div class="atom-body">${specimen}</div>
262
+ <div class="atom-head" style="border-bottom: 0; border-top: var(--border-width-1) solid var(--color-neutral-100)">
263
+ <span class="atom-tags" style="text-align: left">${tags.join(' · ')}</span>
264
+ </div>
265
+ </div>
266
+ `
267
+ )}
268
+ </div>
269
+ `
270
+ })}
271
+
272
+ ${refSection({
273
+ name : 'Still missing',
274
+ meta : `${GAPS.length} against common practice`,
275
+ children: html`
276
+ <div class="table-scroll">
277
+ <table class="gap-table">
278
+ <caption>Atoms absent from the main system</caption>
279
+ <thead>
280
+ <tr>
281
+ <th scope="col">Atom</th>
282
+ <th scope="col">Category</th>
283
+ <th scope="col">State</th>
284
+ <th scope="col">Where it already half-exists</th>
285
+ </tr>
286
+ </thead>
287
+ <tbody>
288
+ ${GAPS.map(
289
+ ([name, cat, state, where]) => html`
290
+ <tr>
291
+ <td>${name}</td>
292
+ <td class="muted">${cat}</td>
293
+ <td><span class="where" data-state=${state}>${STATE_LABEL[state]}</span></td>
294
+ <td class="where" data-state=${state}>${where || '—'}</td>
295
+ </tr>
296
+ `
297
+ )}
298
+ </tbody>
299
+ </table>
300
+ </div>
301
+ `
302
+ })}
303
+
304
+ ${refSection({
305
+ name : 'Tokens that finally have a component',
306
+ children: html`
307
+ <div class="docs-note">
308
+ <p style="margin: 0 0 var(--spacing-8)">
309
+ Six groups — caption, code, help text, footnote, citation and maths notation —
310
+ carried <b>${orphanTokenCount()}</b> tokens between them with <b>zero</b> component
311
+ references. They were designed and never built. Each now has an atom that consumes
312
+ nothing but those tokens: <code>bd-caption</code> takes its size from
313
+ <code>--typography-caption-default-fontSize</code>
314
+ (<code>${resolve('--typography-caption-default-fontSize')}</code>),
315
+ <code>bd-help-text</code> its tones from
316
+ <code>--form-help-text-error-color</code> and
317
+ <code>--form-help-text-success-color</code>, and so on.
318
+ </p>
319
+ <p style="margin: 0">
320
+ Auditing the token layer for orphaned groups turned out to be a reliable way to
321
+ find missing components — the design decisions were already made and written down.
322
+ </p>
323
+ </div>
324
+ `
325
+ })}
326
+
327
+ ${refSection({
328
+ name : 'What stayed under Components',
329
+ children: html`
330
+ <div class="docs-note">
331
+ Everything composed of atoms: breadcrumb, card, accordion, tabs and the tab list it is
332
+ built from, carousel, features,
333
+ header, footer, modal, pricing cards, compare, awards, terms and the video player.
334
+ Introducing <b>Molecules</b> and <b>Organisms</b> tiers would split those further;
335
+ this section deliberately only draws the first line.
336
+ </div>
337
+ `
338
+ })}
339
+ `
340
+ })}
341
+ `;
342
+ };
@@ -0,0 +1,67 @@
1
+ import { css } from 'lit';
2
+
3
+ /** Styled entirely from design tokens — see npm run lint:tokens. */
4
+ export const avatarCSS = css`
5
+ :host { display: inline-flex; }
6
+
7
+ .avatar {
8
+ display: inline-flex;
9
+ align-items: center;
10
+ justify-content: center;
11
+ width: var(--dimension-40);
12
+ height: var(--dimension-40);
13
+ border-radius: var(--radius-full);
14
+ overflow: hidden;
15
+ /* The brand tint, chosen for what it means -- the disc carries brand
16
+ identity -- not for its value. It read blue-100 from the palette, which
17
+ no theme could reach: in dark its text-brand initials measured 2.68:1.
18
+ The only role holding blue-100 is info's surface-strong, and an avatar
19
+ is not info. On the brand tint the initials read 5.72:1 in light and
20
+ 5.10 in dark. The disc is fainter on the page than it was (1.08:1 from
21
+ 1.25); the initials identify the avatar, not its edge. Dark mode
22
+ decision 14. */
23
+ background: var(--status-brand-surface);
24
+ /* The brand ink. DECIDED, and it trades contrast for consistency rather than
25
+ gaining any: blue-700 measured 6.86:1 on the blue-100 disc and the role is
26
+ blue-600 at 4.95:1 -- still comfortably over the 3:1 bar for a mark, and over
27
+ 4.5:1 if these initials are read as text. blue-700 was never required here
28
+ (blue-500 already cleared the disc at 3.64:1), so it was a local choice; the
29
+ role is what every other mark in the package asks for. Those ratios were
30
+ on the old blue-100 disc; on the brand tint it is 5.72:1. */
31
+ color: var(--color-text-brand);
32
+ font-family: var(--typography-fontFamily-sans);
33
+ /* no role: this renders the user's initials as a glyph -- sized and
34
+ weighted for legibility inside a fixed-diameter circle, not running text
35
+ that a role describes. The leading below is already sanctioned under
36
+ typography rule 7; these two axes are the same glyph-box decision, and
37
+ no role in the vocabulary means "two letters centred in a 40px disc". */
38
+ font-size: var(--typography-fontSize-sm);
39
+ /* no role: the weight is part of the glyph-box decision the comment above
40
+ describes. */
41
+ font-weight: var(--typography-fontWeight-semibold);
42
+ line-height: var(--typography-lineHeight-none);
43
+ flex: none;
44
+ }
45
+
46
+ :host([size='sm']) .avatar {
47
+ width: var(--dimension-24);
48
+ height: var(--dimension-24);
49
+ /* no role: the same glyph-box decision the base rule above argues, at a
50
+ 24px diameter instead of 40. The size ladder is the disc's ladder --
51
+ each rung is picked so two letters still fit and stay legible inside
52
+ that circle -- so it is not a type-role ladder that a role family could
53
+ answer. */
54
+ font-size: var(--typography-fontSize-xxs);
55
+ }
56
+
57
+ :host([size='lg']) .avatar {
58
+ width: var(--dimension-64);
59
+ height: var(--dimension-64);
60
+ /* no role: as the sm rung above -- the same glyph box at a 64px diameter. */
61
+ font-size: var(--typography-fontSize-lg);
62
+ }
63
+
64
+ img { width: 100%; height: 100%; object-fit: cover; display: block; }
65
+ `;
66
+
67
+ export default avatarCSS;
@@ -0,0 +1,42 @@
1
+ import { LitElement, html } from 'lit';
2
+ // Installs the design tokens into document scope; see src/tokens/tokens.js
3
+ import '../../tokens/tokens.js';
4
+ import { avatarCSS } from './avatar.css.js';
5
+ import { resolveSize } from '../shared/prop-vocabulary.js';
6
+
7
+ export class BdAvatar extends LitElement {
8
+ static styles = [avatarCSS];
9
+
10
+ static properties = {
11
+ src : { type: String },
12
+ name: { type: String },
13
+ size: { type: String, reflect: true }
14
+ };
15
+
16
+ constructor() {
17
+ super();
18
+ this.src = '';
19
+ this.name = '';
20
+ this.size = 'md';
21
+ }
22
+
23
+ willUpdate(changed) {
24
+ // small / default / large still resolve; see shared/prop-vocabulary.js
25
+ if (changed.has('size')) this.size = resolveSize(this.size, 'md');
26
+ }
27
+
28
+ render() {
29
+ return html`
30
+ <span class="avatar" role="img" aria-label=${this.name || 'Avatar'}>
31
+ ${this.src
32
+ ? html`<img src=${this.src} alt="" />`
33
+ : html`${this.name.split(' ').map(w => w[0] || '')
34
+ .join('')
35
+ .slice(0, 2)
36
+ .toUpperCase()}`}
37
+ </span>
38
+ `;
39
+ }
40
+ }
41
+
42
+ customElements.define('bd-avatar', BdAvatar);
@@ -0,0 +1,95 @@
1
+ import { html } from 'lit';
2
+ import './avatar.js';
3
+
4
+ export default {
5
+ title : 'Atoms/Avatar',
6
+ tags : ['autodocs'],
7
+ parameters: {
8
+ docs: {
9
+ description: {
10
+ component: `
11
+ **BdAvatar** shows a person as an image, falling back to their initials when
12
+ there is no image.
13
+
14
+ ### Usage
15
+ \`\`\`html
16
+ <bd-avatar src="/images/ada.jpg" name="Ada Lovelace"></bd-avatar>
17
+ <bd-avatar name="Ada Lovelace"></bd-avatar>
18
+ <bd-avatar name="Ada Lovelace" size="lg"></bd-avatar>
19
+ \`\`\`
20
+
21
+ ### Props
22
+ | Prop | Values | Default |
23
+ |---|---|---|
24
+ | \`src\` | image URL — omit to fall back to initials | \`''\` |
25
+ | \`name\` | the person's name | \`''\` |
26
+ | \`size\` | \`small\`, \`default\`, \`large\` | \`default\` |
27
+
28
+ ### Always pass a name
29
+ \`name\` does two jobs. It is the source of the initials when there is no \`src\`,
30
+ and it is the accessible name in both cases — the wrapper carries
31
+ \`role="img"\` with \`aria-label\` from \`name\`, and the inner image is given an
32
+ empty \`alt\` so it is not announced twice.
33
+
34
+ Without a \`name\` the accessible name falls back to the literal string
35
+ "Avatar", which tells a screen reader user nothing. Pass one even when you have
36
+ an image.
37
+
38
+ ### How the initials are derived
39
+ The first letter of each whitespace-separated word, capped at two characters
40
+ and upper-cased. So "Ada Lovelace" gives AL, "Ada" gives A, and "Ada Byron
41
+ Lovelace" gives **AB** rather than AL — it takes the first two words, not the
42
+ first and last.
43
+ `
44
+ }
45
+ }
46
+ },
47
+ argTypes: {
48
+ src: {
49
+ control : 'text',
50
+ description: 'Image URL. Omit and the initials from `name` are shown instead.',
51
+ table : { type: { summary: 'string' }, defaultValue: { summary: "" }, category: 'Content' }
52
+ },
53
+ name: {
54
+ control : 'text',
55
+ description: 'The person. Source of the initials and of the accessible name — always pass it.',
56
+ table : { type: { summary: 'string' }, defaultValue: { summary: "" }, category: 'Content' }
57
+ },
58
+ size: {
59
+ control : { type: 'select' },
60
+ options : ['small', 'default', 'large'],
61
+ description: 'Diameter of the avatar.',
62
+ table : { type: { summary: 'string' }, defaultValue: { summary: "default" }, category: 'Appearance' }
63
+ }
64
+ }
65
+ };
66
+
67
+ export const Initials = () => html`
68
+ <bd-avatar name="Ada Lovelace"></bd-avatar>
69
+ `;
70
+
71
+ export const Sizes = () => html`
72
+ <bd-avatar size="sm" name="Ada Lovelace"></bd-avatar>
73
+ <bd-avatar name="Ada Lovelace"></bd-avatar>
74
+ <bd-avatar size="lg" name="Ada Lovelace"></bd-avatar>
75
+ `;
76
+
77
+ /**
78
+ * The image path, which until P6B nothing rendered: both stories used the
79
+ * initials fallback, so the img the component draws when `src` is set was never
80
+ * in the DOM and its rule never matched. The docs block showed an /images/ada.jpg
81
+ * that has never existed in src/assets.
82
+ */
83
+ export const WithImage = () => html`
84
+ <bd-avatar src="/images/tabs-img1.png" name="Ada Lovelace"></bd-avatar>
85
+ <bd-avatar size="lg" src="/images/tabs-img2.png" name="Grace Hopper"></bd-avatar>
86
+ `;
87
+
88
+ /**
89
+ * A src that cannot load. The alt is empty by design -- the accessible name is on
90
+ * the wrapper's aria-label -- so a broken image should leave the avatar silent
91
+ * rather than announcing a filename.
92
+ */
93
+ export const BrokenImage = () => html`
94
+ <bd-avatar src="/nonexistent-image.png" name="Ada Lovelace"></bd-avatar>
95
+ `;