@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
@@ -1,10 +1,13 @@
1
- @import './tokens.css';
1
+ /* Layout helpers for non-component markup.
2
+ Tokens are not imported here: every entry point that loads this file loads
3
+ tokens.css first, and the @import was pulling in a second ~39KB copy. */
4
+
2
5
  .bd-button-container {
3
6
  display: flex;
4
7
  flex-direction: column;
5
8
  align-items: center;
6
- gap: 1rem;
7
- padding: 1rem;
9
+ gap: var(--spacing-16);
10
+ padding: var(--spacing-16);
8
11
  }
9
12
 
10
13
  @media (min-width: 768px) {
@@ -18,18 +21,29 @@
18
21
  .bd-button-container > bd-button,
19
22
  .bd-button-container > bd-contact-button {
20
23
  width: 100%;
24
+ /* no token: the cap a stacked call-to-action column is allowed to grow to.
25
+ It is a layout decision with no home on the spacing or dimension scales,
26
+ which stop well below it, and no --layout-* token names it. */
21
27
  max-width: 300px;
22
28
  }
23
29
 
24
30
 
31
+ /* The page column for light-DOM markup: the twin of .bd-ensemble in
32
+ src/components/shared/ensemble.css.js, which is the source of truth. A page
33
+ that lays out its own sections gets the same edges the modules draw. The
34
+ breakpoints are the scale's own values (576 / 768 / 992 / 1200 / 1400). */
25
35
  .bd-container {
26
- max-width: 1200px;
27
- margin: 0 auto;
28
- padding: var(--spacing-16);
29
- display: flex;
30
- flex-direction: column;
31
- gap: var(--spacing-8);
36
+ box-sizing: border-box;
37
+ width: 100%;
38
+ max-width: var(--grid-container-max-xs);
39
+ margin-inline: auto;
40
+ padding-inline: var(--grid-padding-xs);
32
41
  }
42
+ @media (min-width: 576px) { .bd-container { max-width: var(--grid-container-max-sm); padding-inline: var(--grid-padding-sm); } }
43
+ @media (min-width: 768px) { .bd-container { max-width: var(--grid-container-max-md); padding-inline: var(--grid-padding-md); } }
44
+ @media (min-width: 992px) { .bd-container { max-width: var(--grid-container-max-lg); padding-inline: var(--grid-padding-lg); } }
45
+ @media (min-width: 1200px) { .bd-container { max-width: var(--grid-container-max-xl); } }
46
+ @media (min-width: 1400px) { .bd-container { max-width: var(--grid-container-max-xxl); } }
33
47
 
34
48
  .bd-container-fluid {
35
49
  width: 100%;
@@ -38,9 +52,9 @@
38
52
 
39
53
  .pricing-container {
40
54
  display: flex;
41
- gap: 16px;
55
+ gap: var(--spacing-16);
42
56
  justify-content: center;
43
57
  align-items: stretch;
44
- padding: 20px;
58
+ padding: var(--spacing-20);
45
59
  }
46
60
 
@@ -0,0 +1,231 @@
1
+ import { html } from 'lit';
2
+ import {
3
+ discoverConsumers,
4
+ docsPage,
5
+ primitiveTable,
6
+ readAllCssText,
7
+ refSection,
8
+ referenceNote,
9
+ resolve,
10
+ tokensFor
11
+ } from './story-chrome.js';
12
+
13
+ export default {
14
+ title: 'Foundations/Motion',
15
+ tags : ['autodocs']
16
+ };
17
+
18
+ const motionStyles = html`
19
+ <style>
20
+ .track {
21
+ position: relative;
22
+ height: var(--spacing-24);
23
+ background: var(--color-neutral-50);
24
+ border-radius: var(--radius-full);
25
+ min-width: 220px;
26
+ }
27
+
28
+ .runner {
29
+ position: absolute;
30
+ top: var(--spacing-4);
31
+ left: var(--spacing-4);
32
+ width: var(--spacing-16);
33
+ height: var(--spacing-16);
34
+ background: var(--color-blue-500);
35
+ border-radius: var(--radius-full);
36
+ transition-property: transform;
37
+ }
38
+
39
+ /* .is-running is toggled on the page, so every runner moves together and
40
+ the durations and curves can be compared in one pass. */
41
+ .is-running .runner {
42
+ transform: translateX(calc(100% + 180px));
43
+ }
44
+
45
+ .replay {
46
+ font: inherit;
47
+ font-size: var(--typography-fontSize-xs);
48
+ font-weight: var(--typography-fontWeight-medium);
49
+ color: var(--color-neutral-0);
50
+ background: var(--color-blue-500);
51
+ border: 0;
52
+ border-radius: var(--radius-md);
53
+ padding: var(--spacing-8) var(--spacing-16);
54
+ cursor: pointer;
55
+ margin-bottom: var(--spacing-16);
56
+ }
57
+
58
+ .replay:hover {
59
+ background: var(--color-blue-600);
60
+ }
61
+
62
+ .replay:focus-visible {
63
+ outline: var(--focus-outline-traditional);
64
+ outline-offset: var(--focus-outline-offset);
65
+ }
66
+
67
+ .hover-chip {
68
+ display: inline-block;
69
+ background: var(--color-neutral-100);
70
+ color: var(--color-neutral-900);
71
+ font-family: var(--typography-fontFamily-mono);
72
+ font-size: var(--typography-fontSize-xxs);
73
+ padding: var(--spacing-8) var(--spacing-12);
74
+ border-radius: var(--radius-md);
75
+ transition-property: background-color, transform;
76
+ transition-timing-function: var(--transition-easing-smooth);
77
+ }
78
+
79
+ .hover-chip:hover {
80
+ background: var(--color-blue-500);
81
+ color: var(--color-neutral-0);
82
+ transform: translateY(-2px);
83
+ }
84
+
85
+ /* Honour the user's motion preference — a motion page especially must. */
86
+ @media (prefers-reduced-motion: reduce) {
87
+ .runner,
88
+ .hover-chip {
89
+ transition: none !important;
90
+ }
91
+
92
+ .is-running .runner {
93
+ transform: none;
94
+ }
95
+ }
96
+
97
+ .reduced-note {
98
+ display: none;
99
+ font-size: var(--typography-fontSize-xs);
100
+ color: var(--color-neutral-700);
101
+ background: var(--color-yellow-50);
102
+ border-radius: var(--radius-md);
103
+ padding: var(--spacing-12) var(--spacing-16);
104
+ margin-bottom: var(--spacing-16);
105
+ }
106
+
107
+ @media (prefers-reduced-motion: reduce) {
108
+ .reduced-note {
109
+ display: block;
110
+ }
111
+ }
112
+ </style>
113
+ `;
114
+
115
+ const replay = event => {
116
+ const root = event.currentTarget.closest('.section');
117
+ const demo = root && root.querySelector('.demo-body');
118
+ if (!demo) return;
119
+ demo.classList.remove('is-running');
120
+ // force a reflow so the transition restarts from the beginning
121
+ void demo.offsetWidth;
122
+ demo.classList.add('is-running');
123
+ };
124
+
125
+ export const Motion = () => {
126
+ const cssText = readAllCssText();
127
+ const consumers = discoverConsumers(cssText);
128
+
129
+ const durations = tokensFor(cssText, 'transition-duration-');
130
+ const easings = tokensFor(cssText, 'transition-easing-');
131
+
132
+ return html`
133
+ ${motionStyles}
134
+ ${docsPage({
135
+ title: 'Motion',
136
+ lede : html`Durations and easing curves. Components combine them as
137
+ <code>transition: background-color var(--transition-duration-normal)
138
+ var(--transition-easing-smooth)</code>. There is no composed
139
+ <code>--transition-*</code> shorthand token — the two halves are always applied separately.`,
140
+ note: html`Every animated example here is disabled under
141
+ <code>prefers-reduced-motion: reduce</code>. Components should do the same;
142
+ <code>button.css.js</code> is the pattern to copy. ${referenceNote}`,
143
+ children: html`
144
+ <div class="reduced-note">
145
+ Your system requests reduced motion, so the demos below are static. The tokens and their
146
+ values are still listed.
147
+ </div>
148
+
149
+ ${refSection({
150
+ name : 'Duration',
151
+ meta : `${durations.length} steps · --transition-duration-*`,
152
+ children: html`
153
+ ${primitiveTable({
154
+ caption: 'Duration tokens',
155
+ tokens : durations,
156
+ consumers
157
+ })}
158
+ <button class="replay" @click=${replay}>Replay durations</button>
159
+ <div class="specimen demo-body is-running">
160
+ ${durations.map(
161
+ token => html`
162
+ <p style="margin: 0 0 var(--spacing-6); font-family: var(--typography-fontFamily-mono); font-size: var(--typography-fontSize-xxs); color: var(--color-neutral-600)">
163
+ ${token} — ${resolve(token)}
164
+ </p>
165
+ <div class="track" style="margin-bottom: var(--spacing-16)">
166
+ <div
167
+ class="runner"
168
+ style="transition-duration: var(${token}); transition-timing-function: linear"
169
+ ></div>
170
+ </div>
171
+ `
172
+ )}
173
+ </div>
174
+ `
175
+ })}
176
+
177
+ ${refSection({
178
+ name : 'Easing',
179
+ meta : `${easings.length} curves · --transition-easing-*`,
180
+ children: html`
181
+ ${primitiveTable({
182
+ caption: 'Easing tokens',
183
+ tokens : easings,
184
+ consumers
185
+ })}
186
+ <button class="replay" @click=${replay}>Replay easings</button>
187
+ <div class="specimen demo-body is-running">
188
+ ${easings.map(
189
+ token => html`
190
+ <p style="margin: 0 0 var(--spacing-6); font-family: var(--typography-fontFamily-mono); font-size: var(--typography-fontSize-xxs); color: var(--color-neutral-600)">
191
+ ${token} — ${resolve(token)}
192
+ </p>
193
+ <div class="track" style="margin-bottom: var(--spacing-16)">
194
+ <div
195
+ class="runner"
196
+ style="transition-duration: var(--transition-duration-slower); transition-timing-function: var(${token})"
197
+ ></div>
198
+ </div>
199
+ `
200
+ )}
201
+ </div>
202
+ <p class="docs-lede" style="margin-top: var(--spacing-16)">
203
+ <code>--transition-easing-bounce</code> is
204
+ <code>${resolve('--transition-easing-bounce')}</code> — the negative and
205
+ greater-than-one control points make it overshoot at both ends. Use it for a
206
+ deliberate spring, not for hover states.
207
+ </p>
208
+ `
209
+ })}
210
+
211
+ ${refSection({
212
+ name : 'In context',
213
+ meta : 'hover a chip',
214
+ children: html`
215
+ <div class="specimen">
216
+ ${durations.map(
217
+ token => html`
218
+ <span
219
+ class="hover-chip"
220
+ style="transition-duration: var(${token}); margin: 0 var(--spacing-8) var(--spacing-8) 0"
221
+ >${token.replace('--transition-duration-', '')} · ${resolve(token)}</span
222
+ >
223
+ `
224
+ )}
225
+ </div>
226
+ `
227
+ })}
228
+ `
229
+ })}
230
+ `;
231
+ };
@@ -0,0 +1,272 @@
1
+ import { html } from 'lit';
2
+ import {
3
+ discoverConsumers,
4
+ docsPage,
5
+ primitiveTable,
6
+ readAllCssText,
7
+ refSection,
8
+ referenceNote,
9
+ resolve,
10
+ tokensFor
11
+ } from './story-chrome.js';
12
+
13
+ export default {
14
+ title: 'Foundations/Shape',
15
+ tags : ['autodocs']
16
+ };
17
+
18
+ const shapeStyles = html`
19
+ <style>
20
+ .radius-chip {
21
+ width: var(--spacing-56);
22
+ height: var(--spacing-36);
23
+ background: var(--color-blue-100);
24
+ border: var(--border-width-1) solid var(--color-blue-500);
25
+ }
26
+
27
+ .border-chip {
28
+ width: var(--spacing-56);
29
+ height: var(--spacing-36);
30
+ background: var(--color-neutral-0);
31
+ border-style: solid;
32
+ border-color: var(--color-neutral-700);
33
+ border-radius: var(--radius-sm);
34
+ }
35
+
36
+ /* radius reads differently depending on the size of the box it is on */
37
+ .scale-demo {
38
+ display: flex;
39
+ align-items: flex-end;
40
+ gap: var(--spacing-16);
41
+ flex-wrap: wrap;
42
+ }
43
+
44
+ .scale-demo figure {
45
+ margin: 0;
46
+ text-align: center;
47
+ }
48
+
49
+ .scale-demo .box {
50
+ background: var(--color-blue-100);
51
+ border: var(--border-width-1) solid var(--color-blue-500);
52
+ margin-bottom: var(--spacing-4);
53
+ }
54
+
55
+ .scale-demo figcaption {
56
+ font-family: var(--typography-fontFamily-mono);
57
+ font-size: var(--typography-fontSize-xxs);
58
+ color: var(--color-neutral-600);
59
+ }
60
+
61
+ .warn {
62
+ color: var(--color-red-800);
63
+ background: var(--color-red-50);
64
+ border-radius: var(--radius-md);
65
+ padding: var(--spacing-12) var(--spacing-16);
66
+ font-size: var(--typography-fontSize-xs);
67
+ line-height: var(--typography-lineHeight-normal);
68
+ margin-bottom: var(--spacing-16);
69
+ }
70
+
71
+ .warn code {
72
+ font-family: var(--typography-fontFamily-mono);
73
+ }
74
+ </style>
75
+ `;
76
+
77
+ export const Radius = () => {
78
+ const cssText = readAllCssText();
79
+ const consumers = discoverConsumers(cssText);
80
+ const radii = tokensFor(cssText, 'radius-');
81
+
82
+ return html`
83
+ ${shapeStyles}
84
+ ${docsPage({
85
+ title: 'Border radius',
86
+ lede : html`Eight steps, and which one to reach for is a question of role rather than
87
+ taste.
88
+ <br><br>
89
+ <b>Controls</b> — button, input, select, textarea — read a size-matched alias rather
90
+ than a step: <code>--button-<b>small</b>-borderRadius</code> beside
91
+ <code>--form-input-<b>small</b>-borderRadius</code>, and so on for medium and large.
92
+ A button and a field of the same size sit in the same row, and matching the size in
93
+ the name is what keeps their corners in step. They were a step apart at
94
+ <code>sm</code> and <code>md</code> until this was written down.
95
+ <br><br>
96
+ <b>Containers</b> that hold content take <code>--radius-md</code> — alert, fieldset.
97
+ <b>Media</b> takes <code>--radius-lg</code> — video, and the default for image and
98
+ picture. <b>Pills and circles</b> take <code>--radius-full</code> — badge, tag,
99
+ avatar, switch, progress, spinner. Small inline surfaces take
100
+ <code>--radius-sm</code> — inline code, the checkbox box, skeleton.
101
+ <br><br>
102
+ <code>--radius-xl</code>, <code>--radius-2xl</code> and <code>--radius-3xl</code> have
103
+ no role in the atom layer. They are reachable through the radius prop on bd-img and
104
+ bd-picture, and one block in bd-code uses <code>3xl</code>; nothing else should reach
105
+ for them without a reason.`,
106
+ note : referenceNote,
107
+ children: html`
108
+ ${refSection({
109
+ name : 'Scale',
110
+ meta : `${radii.length} steps · --radius-*`,
111
+ children: primitiveTable({
112
+ caption: 'Border radius scale',
113
+ tokens : radii,
114
+ consumers,
115
+ visual : token => html`<div class="radius-chip" style="border-radius: var(${token})"></div>`
116
+ })
117
+ })}
118
+ ${refSection({
119
+ name : 'The same radius on different box sizes',
120
+ meta : '--radius-lg on 32px, 64px and 128px',
121
+ children: html`
122
+ <div class="specimen">
123
+ <div class="scale-demo">
124
+ ${[32, 64, 128].map(
125
+ size => html`
126
+ <figure>
127
+ <div
128
+ class="box"
129
+ style="width: ${size}px; height: ${size}px; border-radius: var(--radius-lg)"
130
+ ></div>
131
+ <figcaption>${size}px</figcaption>
132
+ </figure>
133
+ `
134
+ )}
135
+ </div>
136
+ </div>
137
+ `
138
+ })}
139
+ ${refSection({
140
+ name : 'Rules',
141
+ children: html`
142
+ <div class="warn">
143
+ <p style="margin: 0 0 var(--spacing-8)">
144
+ <b>Always a token, never a literal.</b> Components used to hardcode
145
+ <code>2px</code>, <code>5px</code>, <code>20px</code>, <code>22px</code> and
146
+ <code>28px</code> as radii — none of which are steps on this scale. They are all
147
+ on the scale now, and <code>npm run lint:tokens</code> fails on a new one.
148
+ </p>
149
+ <p style="margin: 0 0 var(--spacing-8)">
150
+ <b>Never a fallback.</b> <code>var(--radius-lg, 16px)</code> appeared five times,
151
+ and the fallback was wrong — <code>--radius-lg</code> is
152
+ <b>${resolve('--radius-lg')}</b> (8px), so it claimed double. Tokens are always
153
+ present in document scope, so a fallback can only ever lie.
154
+ </p>
155
+ <p style="margin: 0">
156
+ <b>Use <code>--radius-full</code>, never <code>50%</code>.</b> They are not the
157
+ same shape: on a box that is not square, <code>50%</code> is an ellipse and
158
+ <code>--radius-full</code> is a stadium. The atom layer had six of them, and
159
+ <code>radius-percent</code> in <code>npm run lint:tokens</code> fails on a new
160
+ one.
161
+ </p>
162
+ </div>
163
+ `
164
+ })}
165
+ ${refSection({
166
+ name : 'Which step, and why',
167
+ meta : 'responsibility, not proximity',
168
+ children: html`
169
+ <p>
170
+ A radius is a claim about what kind of thing this is. Controls run a
171
+ <b>size-derived ladder</b>: <code>--form-input-*-borderRadius</code> and
172
+ <code>--button-*-borderRadius</code> both resolve small to <code>--radius-sm</code>,
173
+ medium to <code>--radius-md</code> and large to <code>--radius-lg</code>, so a
174
+ control's corner follows its own size rather than a designer's mood.
175
+ </p>
176
+ <p>
177
+ <b>The card family is 16px, and it is now unanimous.</b> All eleven
178
+ card-shaped objects use <code>--radius-2xl</code> on a
179
+ <code>--spacing-32</code> inset with no resting elevation: the Card box,
180
+ CardFeatures, LightCarousel, Bento, the Awards feature card, the TrustPanel
181
+ card, the CompareSection card, the Carousel item, the Comparison Panel column
182
+ and both Pricing cards.
183
+ </p>
184
+ <p>
185
+ <b>So the shape is a role now, not an observation.</b>
186
+ <code>--card-radius</code> and <code>--card-padding</code> are declared in
187
+ <code>tokens.js</code>, and every one of the eleven asks for them by name. This
188
+ page used to say the family agreed; it can now say the family is checked —
189
+ <code>scripts/card-shapes.json</code> lists them and <code>lint:tokens</code>
190
+ reads it both ways, so a card that stops using the role, a rule that uses the
191
+ role without being a card, and a registry entry that matches nothing are all
192
+ findings.
193
+ </p>
194
+ <p>
195
+ <b>The inset has a second step, and finding that out corrected this page.</b>
196
+ <code>--card-padding-compact</code> is 24px, and it exists because five of the
197
+ eleven were already reducing their inset on small viewports — Bento, the
198
+ Comparison Panel, the Trust Panel, the Carousel item and LightCarousel — while
199
+ this page said the family held 32 everywhere. Three of them had independently
200
+ picked exactly 24, which is what makes it a role rather than five local
201
+ decisions. They now take it at the same breakpoint, below md.
202
+ </p>
203
+ <p>
204
+ One card is outside it and recorded: the Carousel item drops to
205
+ <code>--spacing-0 --spacing-20</code> below 480, which is not a smaller inset
206
+ but a different shape — the only card that stops insetting an axis at all.
207
+ That is in the registry with its reason and a review trigger, not quietly
208
+ tolerated. A new content card joins the family; it does not pick a corner.
209
+ </p>
210
+ <p>
211
+ <b>24px is not a card corner.</b> It is valid only where a responsibility or a
212
+ recorded decision supports it, and exactly one live case does:
213
+ <code>bd-img</code> and <code>bd-picture</code> expose <code>radius-3xl</code>
214
+ as a public variant, so the corner is the consuming page's choice. Those two
215
+ variants are the only <code>--radius-3xl</code> left in the package.
216
+ </p>
217
+ <p>
218
+ <b>Two cards used to sit outside and no longer do, and the reasons differed.</b>
219
+ The CompareSection card was never an exception: same surface, same inset, no
220
+ elevation, no interaction, no recorded reason. The Carousel item had a real
221
+ argument — it is draggable and its plus button opens a modal — and it was still
222
+ dropped, because nothing about a carousel item asks for a softer corner than the
223
+ same card sitting in a grid. Behaviour earns a state, a cue or a control; it does
224
+ not earn a different corner. Both are 16px now, and the Carousel item lost its
225
+ 2px border to the ground-and-edge rule at the same time.
226
+ </p>
227
+ <h3 style="font-size: var(--typography-fontSize-base); margin: var(--spacing-32) 0 var(--spacing-8)">
228
+ Nested corners
229
+ </h3>
230
+ <p>
231
+ An inner corner should be smaller than the corner containing it, ideally the
232
+ parent's radius minus the padding between them. A child rounded more than its
233
+ parent either bulges past the parent's curve or, if the parent clips, is cut flat.
234
+ </p>
235
+ <p>
236
+ Do not reach for <code>overflow: hidden</code> to make a mismatch look right. It
237
+ also clips everything else that has to leave the box: a focus ring, a hover shadow,
238
+ a legend sitting on the border line. Terminal deliberately lets a label overlap its
239
+ own panel edge, and it can only do that because the panel does not clip.
240
+ </p>`
241
+ })}
242
+ `
243
+ })}
244
+ `;
245
+ };
246
+
247
+ export const BorderWidth = () => {
248
+ const cssText = readAllCssText();
249
+ const consumers = discoverConsumers(cssText);
250
+ const widths = tokensFor(cssText, 'border-width-');
251
+
252
+ return html`
253
+ ${shapeStyles}
254
+ ${docsPage({
255
+ title: 'Border width',
256
+ lede : html`Named after the pixel value. <code>--border-width-1</code> is the default hairline
257
+ for inputs, cards and dividers; <code>--border-width-2</code> is used for outline buttons
258
+ and focus rings.`,
259
+ note : referenceNote,
260
+ children: refSection({
261
+ name : 'Scale',
262
+ meta : `${widths.length} steps · --border-width-*`,
263
+ children: primitiveTable({
264
+ caption: 'Border width scale',
265
+ tokens : widths,
266
+ consumers,
267
+ visual : token => html`<div class="border-chip" style="border-width: var(${token})"></div>`
268
+ })
269
+ })
270
+ })}
271
+ `;
272
+ };