@repobit/dex-system-design 0.25.12 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (336) hide show
  1. package/CHANGELOG.md +204 -0
  2. package/README.md +131 -8
  3. package/package.json +96 -13
  4. package/schemas/component-manifest.json +3294 -405
  5. package/schemas/manifest-omissions.json +173 -0
  6. package/src/blog/src/breakpoints.js +6 -6
  7. package/src/blog/src/content/blog-atoms-showcase.js +1 -1
  8. package/src/blog/src/content/blog-page-layout.js +2 -2
  9. package/src/blog/src/lib/article-toc.js +7 -7
  10. package/src/blog/src/shell/blog-shell.js +1 -1
  11. package/src/blog/src/tokens/blog.js +2 -2
  12. package/src/blog/src/tokens/core.js +34 -35
  13. package/src/blog/src/tokens/legacy.js +0 -9
  14. package/src/blog/tokens/blog.js +2 -2
  15. package/src/blog/tokens/core.js +34 -35
  16. package/src/blog/tokens/legacy.js +0 -9
  17. package/src/blog/tokens.css +36 -46
  18. package/src/components/accordion/accordion-bg.css.js +83 -59
  19. package/src/components/accordion/accordion-bg.js +29 -10
  20. package/src/components/accordion/accordion-bg.stories.js +67 -67
  21. package/src/components/accordion/accordion-keyboard.js +80 -0
  22. package/src/components/accordion/accordion.css.js +142 -80
  23. package/src/components/accordion/accordion.js +37 -10
  24. package/src/components/accordion/accordion.stories.js +7 -7
  25. package/src/components/agent-endpoints/agent-endpoints.css.js +36 -39
  26. package/src/components/agent-endpoints/agent-endpoints.js +30 -20
  27. package/src/components/agent-endpoints/agent-endpoints.stories.js +1 -1
  28. package/src/components/ai-guardian-demo.stories.js +91 -91
  29. package/src/components/alert/alert.css.js +198 -0
  30. package/src/components/alert/alert.js +103 -0
  31. package/src/components/alert/alert.stories.js +206 -0
  32. package/src/components/anchor/anchor-nav.css.js +213 -101
  33. package/src/components/anchor/anchor-nav.js +26 -40
  34. package/src/components/anchor/anchor.stories.js +22 -12
  35. package/src/components/annotation/annotation.css.js +58 -0
  36. package/src/components/annotation/annotation.js +67 -0
  37. package/src/components/annotation/annotation.stories.js +63 -0
  38. package/src/components/architecture.stories.js +285 -0
  39. package/src/components/atoms.stories.js +342 -0
  40. package/src/components/avatar/avatar.css.js +67 -0
  41. package/src/components/avatar/avatar.js +42 -0
  42. package/src/components/avatar/avatar.stories.js +95 -0
  43. package/src/components/awards/awards-flex.css.js +209 -23
  44. package/src/components/awards/awards-flex.js +66 -7
  45. package/src/components/awards/awards-flex.stories.js +1 -1
  46. package/src/components/awards/{awards-light.stories.js → awards-summary.stories.js} +54 -64
  47. package/src/components/awards/awards.css.js +116 -58
  48. package/src/components/awards/awards.js +102 -28
  49. package/src/components/awards/awards.stories.js +1 -1
  50. package/src/components/back/back.css.js +51 -22
  51. package/src/components/back/back.js +28 -7
  52. package/src/components/back/back.stories.js +9 -3
  53. package/src/components/badge/badge.css.js +158 -46
  54. package/src/components/badge/badge.js +62 -74
  55. package/src/components/badge/badge.stories.js +176 -248
  56. package/src/components/bento-grid/bento-grid.css.js +21 -16
  57. package/src/components/bento-grid/bento-grid.js +16 -4
  58. package/src/components/bento-grid/bento-grid.stories.js +19 -18
  59. package/src/components/bento-grid/bento-item.css.js +52 -28
  60. package/src/components/bento-grid/bento-item.js +2 -2
  61. package/src/components/blockquote/blockquote.css.js +47 -0
  62. package/src/components/blockquote/blockquote.js +29 -0
  63. package/src/components/blockquote/blockquote.stories.js +62 -0
  64. package/src/components/breadcrumb/breadcrumb.css.js +92 -22
  65. package/src/components/breadcrumb/breadcrumb.js +56 -11
  66. package/src/components/button/button.css.js +531 -161
  67. package/src/components/button/button.js +206 -214
  68. package/src/components/button/button.stories.js +322 -174
  69. package/src/components/caption/caption.css.js +21 -0
  70. package/src/components/caption/caption.js +31 -0
  71. package/src/components/caption/caption.stories.js +62 -0
  72. package/src/components/card-features/card-features.css.js +14 -22
  73. package/src/components/card-features/card-features.js +68 -9
  74. package/src/components/card-features/card-features.stories.js +11 -11
  75. package/src/components/cards/card.css.js +60 -81
  76. package/src/components/cards/card.js +56 -25
  77. package/src/components/cards/card.stories.js +39 -39
  78. package/src/components/carousel/carousel.css.js +93 -99
  79. package/src/components/carousel/carousel.js +32 -4
  80. package/src/components/checkbox/checkbox.css.js +111 -93
  81. package/src/components/checkbox/checkbox.js +64 -90
  82. package/src/components/checkbox/checkbox.stories.js +96 -29
  83. package/src/components/code/code.css.js +70 -0
  84. package/src/components/code/code.js +40 -0
  85. package/src/components/code/code.stories.js +73 -0
  86. package/src/components/compare/compare.css.js +179 -43
  87. package/src/components/compare/compare.js +52 -25
  88. package/src/components/compare/compare.stories.js +61 -4
  89. package/src/components/comparison-panel/comparison-panel.css.js +38 -51
  90. package/src/components/comparison-panel/comparison-panel.js +5 -4
  91. package/src/components/comparison-panel/comparison-panel.stories.js +1 -1
  92. package/src/components/compatibility-table/compatibility-table.css.js +180 -80
  93. package/src/components/compatibility-table/compatibility-table.js +37 -9
  94. package/src/components/control-alignment.stories.js +393 -0
  95. package/src/components/cta-banner/cta-banner.css.js +41 -13
  96. package/src/components/cta-banner/cta-banner.js +6 -5
  97. package/src/components/cta-banner/cta-banner.stories.js +43 -98
  98. package/src/components/display/display.css.js +25 -1
  99. package/src/components/display/display.js +46 -13
  100. package/src/components/display/display.stories.js +270 -40
  101. package/src/components/divider/divider-horizontal.js +21 -5
  102. package/src/components/divider/divider-vertical.js +15 -7
  103. package/src/components/divider/divider.css.js +2 -2
  104. package/src/components/divider/divider.stories.js +38 -34
  105. package/src/components/dropdown/dropdown.css.js +93 -126
  106. package/src/components/dropdown/dropdown.js +114 -34
  107. package/src/components/dropdown/dropdown.stories.js +56 -24
  108. package/src/components/features/features.css.js +24 -11
  109. package/src/components/features/features.js +7 -3
  110. package/src/components/features/features.stories.js +37 -37
  111. package/src/components/features-tab/features-tab.css.js +19 -8
  112. package/src/components/features-tab/features-tab.js +6 -5
  113. package/src/components/features-tab/features-tab.stories.js +23 -23
  114. package/src/components/fieldset/fieldset.css.js +30 -0
  115. package/src/components/fieldset/fieldset.js +28 -0
  116. package/src/components/fieldset/fieldset.stories.js +84 -0
  117. package/src/components/footer/footer-links-group.css.js +10 -14
  118. package/src/components/footer/footer-links-group.js +4 -3
  119. package/src/components/footer/footer-lp.css.js +59 -30
  120. package/src/components/footer/footer-lp.js +17 -12
  121. package/src/components/footer/footer-lp.stories.js +63 -75
  122. package/src/components/footer/footer-nav-menu.css.js +26 -4
  123. package/src/components/footer/footer-nav-menu.js +3 -2
  124. package/src/components/footer/footer.css.js +146 -264
  125. package/src/components/footer/footer.js +176 -106
  126. package/src/components/footer/footer.stories.js +9 -9
  127. package/src/components/footer/localeMap.js +1 -1
  128. package/src/components/grid/grid.css.js +1 -1
  129. package/src/components/grid/grid.js +49 -7
  130. package/src/components/grid/grid.stories.js +111 -0
  131. package/src/components/header/header-code.css.js +61 -51
  132. package/src/components/header/header-code.js +28 -14
  133. package/src/components/header/header-code.stories.js +5 -5
  134. package/src/components/header/header.css.js +655 -176
  135. package/src/components/header/header.js +269 -36
  136. package/src/components/header/header.stories.js +841 -18
  137. package/src/components/heading/heading.css.js +14 -17
  138. package/src/components/heading/heading.js +48 -33
  139. package/src/components/heading/heading.stories.js +27 -25
  140. package/src/components/help-text/help-text.css.js +21 -0
  141. package/src/components/help-text/help-text.js +25 -0
  142. package/src/components/help-text/help-text.stories.js +66 -0
  143. package/src/components/highlight/highlight.css.js +86 -64
  144. package/src/components/highlight/highlight.js +18 -27
  145. package/src/components/highlight/highlight.stories.js +14 -3
  146. package/src/components/icons/analysis-icon.js +6 -16
  147. package/src/components/icons/arrow-down-icon.js +6 -19
  148. package/src/components/icons/arrow-icon.js +44 -0
  149. package/src/components/icons/arrow-right-icon.js +30 -23
  150. package/src/components/icons/arrow-up-icon.js +19 -18
  151. package/src/components/icons/bd-ai-icon.js +1 -1
  152. package/src/components/icons/brand-marks.stories.js +279 -0
  153. package/src/components/icons/brand-signature-icon.js +42 -0
  154. package/src/components/icons/check-icon.js +27 -0
  155. package/src/components/icons/circle-info-icon.js +33 -0
  156. package/src/components/icons/close-icon.js +6 -18
  157. package/src/components/icons/family-icon.js +8 -20
  158. package/src/components/icons/globe-icon.js +6 -18
  159. package/src/components/icons/guide-icon.js +6 -18
  160. package/src/components/icons/icon-element.js +99 -0
  161. package/src/components/icons/icons.js +36 -0
  162. package/src/components/icons/icons.stories.js +184 -52
  163. package/src/components/icons/individual-icon.js +6 -18
  164. package/src/components/icons/laurel-icon.js +9 -19
  165. package/src/components/icons/machine-learning-icon.js +6 -17
  166. package/src/components/icons/marks.js +41 -0
  167. package/src/components/icons/minus-icon.js +7 -21
  168. package/src/components/icons/missing-icon.js +52 -0
  169. package/src/components/icons/plus-icon.js +7 -21
  170. package/src/components/icons/quote-icon.js +19 -19
  171. package/src/components/image/image.css.js +72 -25
  172. package/src/components/image/image.js +11 -6
  173. package/src/components/image/image.stories.js +2 -2
  174. package/src/components/input/custom-form.stories.js +214 -62
  175. package/src/components/input/input-clipboard.css.js +51 -144
  176. package/src/components/input/input-clipboard.js +31 -15
  177. package/src/components/input/input.css.js +8 -146
  178. package/src/components/input/input.js +93 -38
  179. package/src/components/install-options/install-options.css.js +84 -77
  180. package/src/components/install-options/install-options.js +33 -30
  181. package/src/components/install-options/install-options.stories.js +3 -3
  182. package/src/components/label/label.css.js +35 -0
  183. package/src/components/label/label.js +38 -0
  184. package/src/components/label/label.stories.js +82 -0
  185. package/src/components/light-carousel/light-carousel.css.js +111 -63
  186. package/src/components/light-carousel/light-carousel.js +85 -11
  187. package/src/components/light-carousel/light-carousel.stories.js +126 -82
  188. package/src/components/link/link.css.js +150 -99
  189. package/src/components/link/link.js +86 -11
  190. package/src/components/link/link.stories.js +124 -30
  191. package/src/components/list/list-item/list-item.css.js +74 -22
  192. package/src/components/list/list-item/list-item.js +32 -10
  193. package/src/components/list/list-item/list-item.stories.js +23 -23
  194. package/src/components/list/list.css.js +8 -2
  195. package/src/components/list/list.js +3 -2
  196. package/src/components/list/list.stories.js +222 -0
  197. package/src/components/modal/modal.css.js +114 -24
  198. package/src/components/modal/modal.js +83 -7
  199. package/src/components/modal/modal.stories.js +9 -9
  200. package/src/components/overview/overview.css.js +19 -14
  201. package/src/components/overview/overview.js +6 -5
  202. package/src/components/overview/overview.stories.js +10 -10
  203. package/src/components/page-switcher/page-switcher.css.js +97 -40
  204. package/src/components/page-switcher/page-switcher.js +28 -5
  205. package/src/components/page-switcher/page-switcher.stories.js +95 -0
  206. package/src/components/paragraph/paragraph.css.js +15 -10
  207. package/src/components/paragraph/paragraph.js +41 -44
  208. package/src/components/paragraph/paragraph.stories.js +56 -21
  209. package/src/components/picture/picture.css.js +103 -44
  210. package/src/components/picture/picture.js +100 -30
  211. package/src/components/picture/picture.stories.js +1 -1
  212. package/src/components/pricing-cards/new-pricing-card.js +3 -3
  213. package/src/components/pricing-cards/new-pricing.css.js +24 -15
  214. package/src/components/pricing-cards/pricing-card-actions.css.js +1 -1
  215. package/src/components/pricing-cards/pricing-card-actions.js +3 -4
  216. package/src/components/pricing-cards/pricing-card-container.css.js +3 -3
  217. package/src/components/pricing-cards/pricing-card-container.js +3 -2
  218. package/src/components/pricing-cards/pricing-card-header.css.js +10 -8
  219. package/src/components/pricing-cards/pricing-card-header.js +6 -7
  220. package/src/components/pricing-cards/pricing-card-pricing.css.js +16 -9
  221. package/src/components/pricing-cards/pricing-card-pricing.js +8 -6
  222. package/src/components/pricing-cards/pricing-card-show-more.css.js +11 -3
  223. package/src/components/pricing-cards/pricing-card-show-more.js +8 -3
  224. package/src/components/pricing-cards/pricing-card.css.js +244 -190
  225. package/src/components/pricing-cards/pricing-card.js +54 -70
  226. package/src/components/pricing-cards/pricing-feature-item.css.js +25 -8
  227. package/src/components/pricing-cards/pricing-feature-item.js +8 -3
  228. package/src/components/process-steps/process-steps.css.js +26 -14
  229. package/src/components/process-steps/process-steps.js +23 -6
  230. package/src/components/process-steps/process-steps.stories.js +1 -1
  231. package/src/components/progress/progress.css.js +80 -0
  232. package/src/components/progress/progress.js +42 -0
  233. package/src/components/progress/progress.stories.js +79 -0
  234. package/src/components/quick-answer/quick-answer.css.js +75 -13
  235. package/src/components/quick-answer/quick-answer.js +8 -3
  236. package/src/components/radio/radio.css.js +92 -128
  237. package/src/components/radio/radio.js +106 -127
  238. package/src/components/radio/radio.stories.js +54 -19
  239. package/src/components/review/review-grid.css.js +5 -6
  240. package/src/components/review/review-grid.js +14 -11
  241. package/src/components/review/review.css.js +11 -6
  242. package/src/components/review/review.js +3 -8
  243. package/src/components/shared/ensemble.css.js +93 -0
  244. package/src/components/shared/form-field.css.js +206 -0
  245. package/src/components/shared/prop-vocabulary.js +48 -0
  246. package/src/components/shared/token-scales.js +306 -0
  247. package/src/components/skeleton/skeleton.css.js +34 -0
  248. package/src/components/skeleton/skeleton.js +32 -0
  249. package/src/components/skeleton/skeleton.stories.js +70 -0
  250. package/src/components/spinner/spinner.css.js +62 -0
  251. package/src/components/spinner/spinner.js +38 -0
  252. package/src/components/spinner/spinner.stories.js +92 -0
  253. package/src/components/spotlight-section/spotlight-section.css.js +14 -13
  254. package/src/components/spotlight-section/spotlight-section.js +42 -39
  255. package/src/components/switch/switch.css.js +103 -0
  256. package/src/components/switch/switch.js +44 -0
  257. package/src/components/switch/switch.stories.js +86 -0
  258. package/src/components/tab-list/content-switcher.stories.js +189 -0
  259. package/src/components/tab-list/tab-list.css.js +250 -0
  260. package/src/components/tab-list/tab-list.js +184 -0
  261. package/src/components/tab-list/tab-list.stories.js +221 -0
  262. package/src/components/tabs/tabs.css.js +14 -123
  263. package/src/components/tabs/tabs.js +16 -19
  264. package/src/components/tabs/tabs.stories.js +95 -95
  265. package/src/components/tag/tag.css.js +54 -0
  266. package/src/components/tag/tag.js +32 -0
  267. package/src/components/tag/tag.stories.js +126 -0
  268. package/src/components/terminal/terminal-message.css.js +164 -60
  269. package/src/components/terminal/terminal-message.js +5 -5
  270. package/src/components/terminal/terminal-message.stories.js +70 -1
  271. package/src/components/termsOfUse/terms.css.js +25 -20
  272. package/src/components/termsOfUse/terms.js +13 -9
  273. package/src/components/termsOfUse/terms.stories.js +1 -1
  274. package/src/components/textarea/textarea.css.js +51 -0
  275. package/src/components/textarea/textarea.js +136 -0
  276. package/src/components/textarea/textarea.stories.js +191 -0
  277. package/src/components/tooltip/tooltip.css.js +75 -0
  278. package/src/components/tooltip/tooltip.js +156 -0
  279. package/src/components/tooltip/tooltip.stories.js +161 -0
  280. package/src/components/trust-panel/trust-panel.css.js +85 -33
  281. package/src/components/trust-panel/trust-panel.js +18 -10
  282. package/src/components/trust-panel/trust-panel.stories.js +1 -1
  283. package/src/components/ultimate-security-demo.stories.js +431 -0
  284. package/src/components/video/video.css.js +17 -0
  285. package/src/components/video/video.js +40 -0
  286. package/src/components/video/video.stories.js +106 -0
  287. package/src/components/video-player/video-player.css.js +67 -11
  288. package/src/components/video-player/video-player.js +35 -4
  289. package/src/components/video-player/video-player.stories.js +1 -1
  290. package/src/components/visual-alignment.stories.js +411 -0
  291. package/src/components/visually-hidden/visually-hidden.css.js +24 -0
  292. package/src/components/visually-hidden/visually-hidden.js +16 -0
  293. package/src/components/visually-hidden/visually-hidden.stories.js +56 -0
  294. package/src/stories/Button.stories.js +17 -17
  295. package/src/stories/Header.stories.js +10 -10
  296. package/src/stories/Page.js +1 -1
  297. package/src/stories/Page.stories.js +6 -6
  298. package/src/tokens/borders.stories.js +339 -0
  299. package/src/tokens/color-responsibilities.stories.js +227 -0
  300. package/src/tokens/dark-derivation.js +309 -0
  301. package/src/tokens/dark-findings.js +197 -0
  302. package/src/tokens/dark-mode.stories.js +207 -0
  303. package/src/tokens/dimension.stories.js +251 -0
  304. package/src/tokens/elevation.stories.js +143 -0
  305. package/src/tokens/focus.stories.js +276 -0
  306. package/src/tokens/fonts.css +20 -20
  307. package/src/tokens/fonts.stories.js +354 -374
  308. package/src/tokens/layout.css +25 -11
  309. package/src/tokens/motion.stories.js +231 -0
  310. package/src/tokens/shape.stories.js +272 -0
  311. package/src/tokens/spacing-rhythm.stories.js +359 -0
  312. package/src/tokens/spacing.stories.js +208 -703
  313. package/src/tokens/story-chrome.js +503 -0
  314. package/src/tokens/surfaces.stories.js +224 -0
  315. package/src/tokens/text-on-surface.stories.js +164 -0
  316. package/src/tokens/token-map.js +220 -0
  317. package/src/tokens/token-map.stories.js +257 -0
  318. package/src/tokens/token-purposes.js +266 -0
  319. package/src/tokens/tokens-grid.stories.js +388 -900
  320. package/src/tokens/tokens.css +1633 -1045
  321. package/src/tokens/tokens.js +1130 -492
  322. package/src/tokens/tokens.stories.js +137 -47
  323. package/src/tokens/type-ceiling-words.js +299 -0
  324. package/src/tokens/typography.stories.js +1003 -965
  325. package/src/tokens/vertical-rhythm.stories.js +224 -0
  326. package/src/components/awards/awards-icon.js +0 -56
  327. package/src/components/awards/awards-light.js +0 -240
  328. package/src/components/banner/banner.js +0 -60
  329. package/src/components/banner/banner.stories.js +0 -51
  330. package/src/components/button/icons.js +0 -24
  331. package/src/components/input/index.js +0 -0
  332. package/src/components/light-carousel/light-carousel-simple.css.js +0 -183
  333. package/src/components/light-carousel/light-carousel-simple.js +0 -74
  334. package/src/tokens/colors.js +0 -121
  335. package/src/tokens/typography.css.js +0 -207
  336. package/src/tokens/typography.js +0 -0
@@ -1,932 +1,420 @@
1
1
  import { html } from 'lit';
2
+ import {
3
+ copyToken,
4
+ discoverConsumers,
5
+ discoverTokens,
6
+ docsPage,
7
+ readAllCssText,
8
+ refSection,
9
+ resolve,
10
+ usageCell
11
+ } from './story-chrome.js';
2
12
 
3
13
  export default {
4
- title : 'Design Tokens/Grid System',
5
- tags : ['autodocs'],
6
- parameters: {
7
- layout: 'fullscreen',
8
- docs : {
9
- description: {
10
- component: `
11
- # Grid System
12
-
13
- A responsive, mobile-first grid system based on CSS Grid with semantic classes and design tokens.
14
-
15
- ## Overview
16
-
17
- The grid system provides a flexible layout foundation using CSS Grid Layout. It supports responsive design, fixed and fluid columns, and consistent spacing through design tokens.
18
-
19
- ## Core Concepts
20
-
21
- ### 1. Container
22
- The outermost wrapper that centers content and sets maximum width.
23
-
24
- ### 2. Row
25
- Horizontal containers that hold columns. Uses CSS Grid for layout.
26
-
27
- ### 3. Column
28
- Content containers that span across the grid. Can be fixed or fluid.
29
-
30
- ## Usage
31
-
32
- ### Basic Grid Structure
33
- \`\`\`html
34
- <div class="grid-container">
35
- <div class="grid-row">
36
- <div class="grid-col">
37
- <!-- Column content -->
38
- </div>
39
- <div class="grid-col">
40
- <!-- Column content -->
41
- </div>
42
- </div>
43
- </div>
44
- \`\`\`
45
-
46
- ### Fixed Width Columns
47
- \`\`\`html
48
- <div class="grid-container">
49
- <div class="grid-row">
50
- <div class="col-6">
51
- <!-- 50% width column -->
52
- </div>
53
- <div class="col-6">
54
- <!-- 50% width column -->
55
- </div>
56
- </div>
57
- </div>
58
- \`\`\`
59
-
60
- ### Responsive Grid
61
- \`\`\`html
62
- <div class="grid-container">
63
- <div class="grid-row">
64
- <div class="col-12 col-md-8 col-lg-6">
65
- <!-- Responsive column -->
66
- </div>
67
- </div>
68
- </div>
69
- \`\`\`
70
-
71
- ## Grid Classes Reference
72
-
73
- ### Container Classes
74
- | Class | Description | CSS Equivalent |
75
- |-------|-------------|----------------|
76
- | \`.grid-container\` | Centers content with max-width | \`max-width: var(--container-max-width)\` |
77
- | \`.container-fluid\` | Full-width container | \`width: 100%\` |
78
-
79
- ### Row Classes
80
- | Class | Description | CSS Equivalent |
81
- |-------|-------------|----------------|
82
- | \`.grid-row\` | Grid container row | \`display: grid; grid-template-columns: repeat(auto-fit, minmax(min-content, 1fr))\` |
83
- | \`.row-gap-sm\` | Small row gap | \`row-gap: var(--space-sm)\` |
84
- | \`.row-gap-md\` | Medium row gap | \`row-gap: var(--space-md)\` |
85
- | \`.row-gap-lg\` | Large row gap | \`row-gap: var(--space-lg)\` |
86
-
87
- ### Column Classes
88
- #### Fluid Columns
89
- | Class | Description | Behavior |
90
- |-------|-------------|----------|
91
- | \`.grid-col\` | Auto-sizing column | Fills available space equally |
92
- | \`.col-auto\` | Content-based width | Width based on content size |
93
-
94
- #### Fixed Columns (12-column grid)
95
- | Class | Width | Columns |
96
- |-------|-------|---------|
97
- | \`.col-1\` | 8.33% | 1 of 12 |
98
- | \`.col-2\` | 16.66% | 2 of 12 |
99
- | \`.col-3\` | 25% | 3 of 12 |
100
- | \`.col-4\` | 33.33% | 4 of 12 |
101
- | \`.col-5\` | 41.66% | 5 of 12 |
102
- | \`.col-6\` | 50% | 6 of 12 |
103
- | \`.col-7\` | 58.33% | 7 of 12 |
104
- | \`.col-8\` | 66.66% | 8 of 12 |
105
- | \`.col-9\` | 75% | 9 of 12 |
106
- | \`.col-10\` | 83.33% | 10 of 12 |
107
- | \`.col-11\` | 91.66% | 11 of 12 |
108
- | \`.col-12\` | 100% | 12 of 12 |
109
-
110
- #### Responsive Columns
111
- | Class | Breakpoint | Description |
112
- |-------|------------|-------------|
113
- | \`.col-sm-*\` | ≥576px | Small devices |
114
- | \`.col-md-*\` | ≥768px | Medium devices |
115
- | \`.col-lg-*\` | ≥992px | Large devices |
116
- | \`.col-xl-*\` | ≥1200px | Extra large devices |
117
-
118
- ## Design Tokens
119
-
120
- The grid system uses CSS custom properties for consistent spacing and sizing:
121
-
122
- \`\`\`css
123
- :root {
124
- /* Container */
125
- --container-max-width: 1200px;
126
- --container-padding: var(--space-lg);
127
-
128
- /* Grid */
129
- --grid-columns: 12;
130
- --grid-gap: var(--space-md);
131
-
132
- /* Breakpoints */
133
- --breakpoint-sm: 576px;
134
- --breakpoint-md: 768px;
135
- --breakpoint-lg: 992px;
136
- --breakpoint-xl: 1200px;
137
- }
138
- \`\`\`
139
-
140
- ## Examples
141
-
142
- ### Equal Width Columns
143
- \`\`\`html
144
- <div class="grid-container">
145
- <div class="grid-row">
146
- <div class="grid-col">Column 1</div>
147
- <div class="grid-col">Column 2</div>
148
- <div class="grid-col">Column 3</div>
149
- </div>
150
- </div>
151
- \`\`\`
152
-
153
- ### Mixed Fixed and Fluid
154
- \`\`\`html
155
- <div class="grid-container">
156
- <div class="grid-row">
157
- <div class="col-4">Fixed 33%</div>
158
- <div class="grid-col">Fluid remaining</div>
159
- </div>
160
- </div>
161
- \`\`\`
162
-
163
- ### Nested Grids
164
- \`\`\`html
165
- <div class="grid-container">
166
- <div class="grid-row">
167
- <div class="col-8">
168
- <div class="grid-row">
169
- <div class="col-6">Nested 50%</div>
170
- <div class="col-6">Nested 50%</div>
171
- </div>
172
- </div>
173
- <div class="col-4">Sidebar</div>
174
- </div>
175
- </div>
176
- \`\`\`
177
-
178
- ### Responsive Layout
179
- \`\`\`html
180
- <div class="grid-container">
181
- <div class="grid-row">
182
- <div class="col-12 col-md-8 col-lg-6">
183
- Content adjusts based on screen size
184
- </div>
185
- <div class="col-12 col-md-4 col-lg-6">
186
- Sidebar adjusts accordingly
187
- </div>
188
- </div>
189
- </div>
190
- \`\`\`
191
-
192
- ## Best Practices
193
-
194
- ### 1. Always Use Container
195
- Wrap your grid in a container for proper centering and padding:
196
- \`\`\`html
197
- <!-- Good ✅ -->
198
- <div class="grid-container">
199
- <div class="grid-row">...</div>
200
- </div>
201
-
202
- <!-- Bad ❌ -->
203
- <div class="grid-row">...</div>
204
- \`\`\`
205
-
206
- ### 2. Column Sum Should Equal 12 (for fixed grids)
207
- \`\`\`html
208
- <!-- Good ✅ -->
209
- <div class="col-8">...</div>
210
- <div class="col-4">...</div>
211
- <!-- Total: 12 -->
212
-
213
- <!-- Bad ❌ -->
214
- <div class="col-7">...</div>
215
- <div class="col-6">...</div>
216
- <!-- Total: 13, will wrap -->
217
- \`\`\`
218
-
219
- ### 3. Use Semantic Class Names
220
- \`\`\`html
221
- <!-- Good ✅ -->
222
- <div class="grid-col">Main Content</div>
223
- <div class="col-4">Sidebar</div>
224
-
225
- <!-- Avoid ❌ -->
226
- <div style="grid-column: span 8;">Main Content</div>
227
- \`\`\`
228
-
229
- ### 4. Responsive Considerations
230
- - Test on multiple screen sizes
231
- - Use responsive column classes
232
- - Consider mobile-first approach
233
- - Ensure touch targets are adequate
234
-
235
- ## Browser Support
236
-
237
- CSS Grid is supported in:
238
- - Chrome 57+
239
- - Firefox 52+
240
- - Safari 10.1+
241
- - Edge 16+
242
-
243
- For older browsers, consider using feature detection with \`@supports\`:
244
- \`\`\`css
245
- @supports (display: grid) {
246
- .grid-row {
247
- display: grid;
248
- }
249
- }
250
-
251
- @supports not (display: grid) {
252
- .grid-row {
253
- display: flex;
254
- flex-wrap: wrap;
255
- }
256
- }
257
- \`\`\`
258
-
259
- ## Performance
260
-
261
- - CSS Grid has excellent performance in modern browsers
262
- - Avoid deeply nested grids when possible
263
- - Use \`grid-auto-flow: dense\` for complex layouts
264
- - Consider \`will-change: transform\` for animated grids
265
-
266
- ## Accessibility
267
-
268
- - Maintain logical source order
269
- - Ensure proper heading hierarchy within grids
270
- - Test keyboard navigation
271
- - Verify screen reader announcements
272
- - Maintain sufficient color contrast
273
- `
274
- }
275
- }
276
- },
277
-
278
- argTypes: {
279
- backgroundColor: {
280
- control : 'color',
281
- description: 'Background color for container',
282
- table : {
283
- type : { summary: 'string' },
284
- defaultValue: { summary: '#f4f4f4' }
285
- }
286
- },
287
- padding: {
288
- control : 'text',
289
- description: 'Padding for container and columns',
290
- table : {
291
- type : { summary: 'string' },
292
- defaultValue: { summary: 'var(--space-md)' }
293
- }
294
- },
295
- gutter: {
296
- control : 'text',
297
- description: 'Gap between columns',
298
- table : {
299
- type : { summary: 'string' },
300
- defaultValue: { summary: 'var(--grid-gap, var(--space-md))' }
301
- }
302
- },
303
- colBg1: {
304
- control : 'color',
305
- description: 'Background color for first column',
306
- table : {
307
- type : { summary: 'string' },
308
- defaultValue: { summary: '#bbb' }
309
- }
310
- },
311
- colBg2: {
312
- control : 'color',
313
- description: 'Background color for second column',
314
- table : {
315
- type : { summary: 'string' },
316
- defaultValue: { summary: '#999' }
317
- }
318
- },
319
- maxWidth: {
320
- control : 'text',
321
- description: 'Maximum width of container',
322
- table : {
323
- type : { summary: 'string' },
324
- defaultValue: { summary: 'var(--container-max-width, 1200px)' }
325
- }
326
- }
327
- }
14
+ title: 'Foundations/Grid System',
15
+ tags : ['autodocs']
328
16
  };
329
17
 
330
- const Template = (args) => html`
18
+ const gridStyles = html`
331
19
  <style>
332
- :root {
333
- --container-max-width: 1200px;
334
- --grid-gap: var(--space-md);
335
- --space-md: 1.5rem;
336
- --space-lg: 2rem;
337
- }
338
-
339
- .story-container {
340
- padding: 2rem;
341
- background: #f8f9fa;
342
- min-height: 100vh;
343
- }
344
-
345
- .grid-container {
346
- max-width: ${args.maxWidth};
347
- margin: 0 auto;
348
- padding: ${args.padding};
349
- background: ${args.backgroundColor};
350
- border-radius: 8px;
351
- border: 2px solid #dee2e6;
352
- }
353
-
354
- .grid-row {
355
- display: grid;
356
- grid-template-columns: repeat(auto-fit, minmax(min-content, 1fr));
357
- gap: ${args.gutter};
358
- }
359
-
360
- .grid-col {
361
- min-height: 100px;
362
- display: flex;
363
- align-items: center;
364
- justify-content: center;
365
- border-radius: 4px;
366
- }
367
-
368
- .col-6 {
369
- grid-column: span 6;
370
- min-height: 100px;
371
- display: flex;
372
- align-items: center;
373
- justify-content: center;
374
- border-radius: 4px;
375
- }
376
-
377
- .col-4 {
378
- grid-column: span 4;
379
- }
380
-
381
- .col-8 {
382
- grid-column: span 8;
383
- }
384
-
385
- .col-12 {
386
- grid-column: span 12;
387
- }
388
-
389
- .info-panel {
390
- background: white;
391
- padding: 1.5rem;
392
- border-radius: 8px;
393
- margin-bottom: 2rem;
394
- box-shadow: 0 2px 8px rgba(0,0,0,0.1);
395
- }
396
-
397
- .info-title {
398
- font-family: var(--font-family-sans, sans-serif);
399
- font-size: 1.25rem;
400
- font-weight: 600;
401
- margin: 0 0 1rem 0;
402
- color: #212529;
403
- }
404
-
405
- .info-grid {
406
- display: grid;
407
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
408
- gap: 1rem;
409
- margin-top: 1rem;
410
- }
411
-
412
- .info-item {
413
- padding: 1rem;
414
- background: #f8f9fa;
415
- border-radius: 4px;
416
- border-left: 4px solid #007bff;
417
- }
418
-
419
- .info-label {
420
- font-family: var(--font-family-sans, sans-serif);
421
- font-weight: 600;
422
- color: #495057;
423
- margin: 0 0 0.25rem 0;
424
- font-size: 0.9rem;
425
- }
426
-
427
- .info-value {
428
- font-family: var(--font-family-mono, monospace);
429
- color: #6c757d;
430
- margin: 0;
431
- font-size: 0.85rem;
432
- }
433
-
434
- .code-block {
435
- background: #1a1a1a;
436
- color: #f8f8f2;
437
- padding: 1.5rem;
438
- border-radius: 4px;
439
- font-family: var(--font-family-mono, monospace);
440
- font-size: 0.85rem;
441
- line-height: 1.5;
20
+ .demo-frame {
21
+ background: var(--color-neutral-25);
22
+ border: var(--border-width-1) solid var(--color-neutral-100);
23
+ border-radius: var(--radius-md);
24
+ padding: var(--spacing-16);
25
+ /* the demos are width-sensitive; keep them off the page scrollbar */
442
26
  overflow-x: auto;
443
- margin-top: 1rem;
444
- }
445
-
446
- .code-comment { color: #6272a4; }
447
- .code-class { color: #50fa7b; }
448
- .code-property { color: #f1fa8c; }
449
- .code-value { color: #ff79c6; }
450
- </style>
451
-
452
- <div class="story-container">
453
- <div class="info-panel">
454
- <h3 class="info-title">Grid System Configuration</h3>
455
- <div class="info-grid">
456
- <div class="info-item">
457
- <p class="info-label">Container Max Width</p>
458
- <p class="info-value">${args.maxWidth}</p>
459
- </div>
460
- <div class="info-item">
461
- <p class="info-label">Container Padding</p>
462
- <p class="info-value">${args.padding}</p>
463
- </div>
464
- <div class="info-item">
465
- <p class="info-label">Grid Gutter</p>
466
- <p class="info-value">${args.gutter}</p>
467
- </div>
468
- </div>
469
- </div>
470
-
471
- <div class="grid-container">
472
- <div class="grid-row" style="gap: ${args.gutter};">
473
- <div class="grid-col" style="background: ${args.colBg1}; padding: ${args.padding};">
474
- .grid-col (auto width)
475
- </div>
476
- <div class="grid-col" style="background: ${args.colBg2}; padding: ${args.padding};">
477
- .grid-col (auto width)
478
- </div>
479
- </div>
480
- </div>
481
-
482
- <div class="code-block">
483
- <span class="code-comment">HTML Structure:</span><br>
484
- &lt;<span class="code-class">div</span> <span class="code-property">class</span>=<span class="code-value">"grid-container"</span>&gt;<br>
485
- &nbsp;&nbsp;&lt;<span class="code-class">div</span> <span class="code-property">class</span>=<span class="code-value">"grid-row"</span>&gt;<br>
486
- &nbsp;&nbsp;&nbsp;&nbsp;&lt;<span class="code-class">div</span> <span class="code-property">class</span>=<span class="code-value">"grid-col"</span>&gt;Column 1&lt;/<span class="code-class">div</span>&gt;<br>
487
- &nbsp;&nbsp;&nbsp;&nbsp;&lt;<span class="code-class">div</span> <span class="code-property">class</span>=<span class="code-value">"grid-col"</span>&gt;Column 2&lt;/<span class="code-class">div</span>&gt;<br>
488
- &nbsp;&nbsp;&lt;/<span class="code-class">div</span>&gt;<br>
489
- &lt;/<span class="code-class">div</span>&gt;
490
- </div>
491
- </div>
492
- `;
493
-
494
- export const GridContainer = Template.bind({});
495
- GridContainer.args = {
496
- backgroundColor: '#f4f4f4',
497
- padding : 'var(--space-lg)',
498
- gutter : 'var(--space-md)',
499
- colBg1 : '#bbb',
500
- colBg2 : '#999',
501
- maxWidth : 'var(--container-max-width, 1200px)'
502
- };
503
- GridContainer.storyName = 'Basic Grid';
504
- GridContainer.parameters = {
505
- docs: {
506
- description: {
507
- story: 'Basic grid container with auto-sizing columns. Demonstrates the foundational grid structure with container, row, and columns.'
508
27
  }
509
- }
510
- };
511
28
 
512
- export const FixedColumns = (args) => html`
513
- <style>
514
29
  .demo-container {
515
- padding: 2rem;
516
- background: #f8f9fa;
517
- min-height: 100vh;
518
- }
519
-
520
- .grid-container {
521
- max-width: ${args.maxWidth};
522
30
  margin: 0 auto;
523
- padding: ${args.padding};
524
- background: white;
525
- border-radius: 8px;
526
- box-shadow: 0 2px 8px rgba(0,0,0,0.1);
527
- }
528
-
529
- .grid-row {
530
- display: grid;
531
- grid-template-columns: repeat(12, 1fr);
532
- gap: ${args.gutter};
533
- margin-bottom: 2rem;
534
- }
535
-
536
- .col {
537
- min-height: 80px;
538
- display: flex;
539
- align-items: center;
540
- justify-content: center;
541
- border-radius: 4px;
542
- font-family: var(--font-family-sans, sans-serif);
543
- font-weight: 600;
544
- color: white;
545
- }
546
-
547
- .col-1 { grid-column: span 1; background: #007bff; }
548
- .col-2 { grid-column: span 2; background: #6f42c1; }
549
- .col-3 { grid-column: span 3; background: #e83e8c; }
550
- .col-4 { grid-column: span 4; background: #fd7e14; }
551
- .col-5 { grid-column: span 5; background: #20c997; }
552
- .col-6 { grid-column: span 6; background: #17a2b8; }
553
- .col-7 { grid-column: span 7; background: #ffc107; color: #212529; }
554
- .col-8 { grid-column: span 8; background: #dc3545; }
555
- .col-9 { grid-column: span 9; background: #343a40; }
556
- .col-10 { grid-column: span 10; background: #28a745; }
557
- .col-11 { grid-column: span 11; background: #6c757d; }
558
- .col-12 { grid-column: span 12; background: #6610f2; }
559
-
560
- .grid-example {
561
- margin-bottom: 3rem;
562
- }
563
-
564
- .example-title {
565
- font-family: var(--font-family-sans, sans-serif);
566
- font-size: 1.1rem;
567
- font-weight: 600;
568
- margin: 0 0 1rem 0;
569
- color: #212529;
570
- }
571
-
572
- .example-description {
573
- font-family: var(--font-family-sans, sans-serif);
574
- color: #6c757d;
575
- margin: 0 0 1.5rem 0;
576
- font-size: 0.9rem;
31
+ background: var(--color-blue-50);
32
+ border: var(--border-width-1) dashed var(--color-blue-300);
33
+ border-radius: var(--radius-sm);
577
34
  }
578
- </style>
579
35
 
580
- <div class="demo-container">
581
- <div class="grid-container">
582
- <div class="grid-example">
583
- <h3 class="example-title">12-Column Grid System</h3>
584
- <p class="example-description">All available fixed-width column classes:</p>
585
- <div class="grid-row">
586
- ${[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].map(num => html`
587
- <div class="col col-1">.col-1</div>
588
- `)}
589
- </div>
590
-
591
- <div class="grid-row">
592
- <div class="col col-6">.col-6 (50%)</div>
593
- <div class="col col-6">.col-6 (50%)</div>
594
- </div>
595
-
596
- <div class="grid-row">
597
- <div class="col col-4">.col-4 (33%)</div>
598
- <div class="col col-4">.col-4 (33%)</div>
599
- <div class="col col-4">.col-4 (33%)</div>
600
- </div>
601
-
602
- <div class="grid-row">
603
- <div class="col col-8">.col-8 (66%)</div>
604
- <div class="col col-4">.col-4 (33%)</div>
605
- </div>
606
-
607
- <div class="grid-row">
608
- <div class="col col-3">.col-3 (25%)</div>
609
- <div class="col col-6">.col-6 (50%)</div>
610
- <div class="col col-3">.col-3 (25%)</div>
611
- </div>
612
- </div>
613
- </div>
614
- </div>
615
- `;
616
- FixedColumns.args = {
617
- padding : 'var(--space-lg)',
618
- gutter : 'var(--space-sm)',
619
- maxWidth: 'var(--container-max-width, 1200px)'
620
- };
621
- FixedColumns.storyName = 'Fixed Columns';
622
- FixedColumns.parameters = {
623
- docs: {
624
- description: {
625
- story: 'Fixed-width column system based on a 12-column grid. Demonstrates all available column classes from .col-1 to .col-12.'
626
- }
627
- }
628
- };
629
-
630
- export const ResponsiveGrid = () => html`
631
- <style>
632
- .responsive-demo {
633
- padding: 2rem;
634
- background: #f8f9fa;
635
- min-height: 100vh;
636
- }
637
-
638
- .grid-container {
639
- max-width: 1200px;
640
- margin: 0 auto;
641
- padding: 2rem;
642
- background: white;
643
- border-radius: 8px;
644
- box-shadow: 0 2px 8px rgba(0,0,0,0.1);
645
- }
646
-
647
- .grid-row {
36
+ .demo-grid {
648
37
  display: grid;
649
- gap: 1rem;
650
- margin-bottom: 2rem;
38
+ grid-template-columns: repeat(var(--demo-cols, 12), 1fr);
651
39
  }
652
-
653
- .col {
654
- padding: 1.5rem;
655
- border-radius: 6px;
656
- font-family: var(--font-family-sans, sans-serif);
657
- font-weight: 600;
658
- display: flex;
659
- align-items: center;
660
- justify-content: center;
40
+
41
+ .demo-cell {
42
+ background: var(--color-blue-500);
43
+ color: var(--color-neutral-0);
44
+ border-radius: var(--radius-sm);
45
+ padding: var(--spacing-8) 0;
661
46
  text-align: center;
662
- min-height: 120px;
663
- }
664
-
665
- .col-1 { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; }
666
- .col-2 { background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); color: white; }
667
- .col-3 { background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); color: white; }
668
-
669
- .breakpoint-info {
670
- display: grid;
671
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
672
- gap: 1rem;
673
- margin-bottom: 2rem;
674
- }
675
-
676
- .breakpoint-card {
677
- padding: 1rem;
678
- background: #f8f9fa;
679
- border-radius: 6px;
680
- border-left: 4px solid #007bff;
681
- }
682
-
683
- .breakpoint-title {
684
- font-family: var(--font-family-sans, sans-serif);
685
- font-weight: 600;
686
- margin: 0 0 0.5rem 0;
687
- color: #212529;
47
+ font-family: var(--typography-fontFamily-mono);
48
+ font-size: var(--typography-fontSize-xxs);
49
+ font-weight: var(--typography-fontWeight-semibold);
688
50
  }
689
-
690
- .breakpoint-desc {
691
- font-family: var(--font-family-sans, sans-serif);
692
- color: #6c757d;
693
- margin: 0;
694
- font-size: 0.9rem;
51
+
52
+ .demo-cell--alt {
53
+ background: var(--color-neutral-400);
695
54
  }
696
-
697
- .device-preview {
698
- position: relative;
699
- border: 2px solid #dee2e6;
700
- border-radius: 12px;
701
- padding: 1rem;
702
- margin: 1rem 0;
703
- background: #f8f9fa;
55
+
56
+ .demo-label {
57
+ font-family: var(--typography-fontFamily-mono);
58
+ font-size: var(--typography-fontSize-xxs);
59
+ color: var(--color-neutral-600);
60
+ margin: 0 0 var(--spacing-8);
704
61
  }
705
-
706
- .device-label {
707
- position: absolute;
708
- top: -12px;
709
- left: 1rem;
710
- background: #007bff;
711
- color: white;
712
- padding: 2px 8px;
713
- border-radius: 4px;
714
- font-family: var(--font-family-sans, sans-serif);
715
- font-size: 0.8rem;
716
- font-weight: 600;
62
+
63
+ .demo-label + .demo-frame {
64
+ margin-bottom: var(--spacing-24);
717
65
  }
718
-
719
- .responsive-code {
720
- background: #1a1a1a;
721
- color: #f8f8f2;
722
- padding: 1.5rem;
723
- border-radius: 6px;
724
- font-family: var(--font-family-mono, monospace);
725
- font-size: 0.85rem;
726
- line-height: 1.5;
727
- margin-top: 2rem;
66
+
67
+ .ruler {
68
+ height: var(--spacing-8);
69
+ background: var(--color-blue-500);
70
+ border-radius: var(--radius-sm);
71
+ min-width: 1px;
728
72
  }
729
73
  </style>
74
+ `;
730
75
 
731
- <div class="responsive-demo">
732
- <div class="grid-container">
733
- <h3 style="font-family: var(--font-family-sans, sans-serif); margin: 0 0 2rem 0;">Responsive Grid System</h3>
734
-
735
- <div class="breakpoint-info">
736
- <div class="breakpoint-card">
737
- <h4 class="breakpoint-title">Mobile First</h4>
738
- <p class="breakpoint-desc">Columns stack vertically by default on small screens</p>
739
- </div>
740
- <div class="breakpoint-card">
741
- <h4 class="breakpoint-title">Tablet (≥768px)</h4>
742
- <p class="breakpoint-desc">Use .col-md-* classes for tablet layouts</p>
743
- </div>
744
- <div class="breakpoint-card">
745
- <h4 class="breakpoint-title">Desktop (≥992px)</h4>
746
- <p class="breakpoint-desc">Use .col-lg-* classes for desktop layouts</p>
747
- </div>
748
- </div>
749
-
750
- <div class="device-preview">
751
- <div class="device-label">Mobile (Stacked)</div>
752
- <div class="grid-row">
753
- <div class="col col-12" style="background: #007bff; color: white;">.col-12 (100%)</div>
754
- <div class="col col-12" style="background: #28a745; color: white;">.col-12 (100%)</div>
755
- </div>
756
- </div>
757
-
758
- <div class="device-preview">
759
- <div class="device-label">Tablet (2 Columns)</div>
760
- <div class="grid-row" style="grid-template-columns: repeat(2, 1fr);">
761
- <div class="col col-1">.col-md-6</div>
762
- <div class="col col-2">.col-md-6</div>
763
- </div>
764
- </div>
765
-
766
- <div class="device-preview">
767
- <div class="device-label">Desktop (3 Columns)</div>
768
- <div class="grid-row" style="grid-template-columns: repeat(3, 1fr);">
769
- <div class="col col-1">.col-lg-4</div>
770
- <div class="col col-2">.col-lg-4</div>
771
- <div class="col col-3">.col-lg-4</div>
772
- </div>
773
- </div>
774
-
775
- <div class="responsive-code">
776
- <span style="color: #6272a4;">/* Responsive column example */</span><br>
777
- &lt;div class="col-12 col-md-6 col-lg-4"&gt;<br>
778
- &nbsp;&nbsp;<span style="color: #6272a4;">&lt;!-- Stacked on mobile, 2 columns on tablet, 3 columns on desktop --&gt;</span><br>
779
- &lt;/div&gt;
780
- </div>
76
+ function tokensFor(cssText, prefix) {
77
+ const pattern = new RegExp(`(--${prefix}[A-Za-z0-9-]*)\\s*:`, 'g');
78
+ return discoverTokens(cssText, pattern).map(match => match[1]);
79
+ }
80
+
81
+ function tokenTable({ caption, tokens, consumers, ruler = false }) {
82
+ const rows = tokens.map(token => ({ token, value: resolve(token) })).filter(r => r.value);
83
+ const max = ruler ? Math.max(...rows.map(r => parseFloat(r.value) || 0), 1) : 0;
84
+
85
+ return html`
86
+ <div class="table-scroll">
87
+ <table>
88
+ <caption>${caption}</caption>
89
+ <thead>
90
+ <tr>
91
+ <th scope="col">Token</th>
92
+ <th scope="col">Value</th>
93
+ ${ruler ? html`<th scope="col">Scale</th>` : ''}
94
+ <th scope="col">Used by</th>
95
+ </tr>
96
+ </thead>
97
+ <tbody>
98
+ ${rows.map(
99
+ ({ token, value }) => html`
100
+ <tr>
101
+ <td>${copyToken(token)}</td>
102
+ <td class="num">${value}</td>
103
+ ${ruler
104
+ ? html`<td style="width: 40%">
105
+ <div
106
+ class="ruler"
107
+ style="width: ${((parseFloat(value) || 0) / max) * 100}%"
108
+ ></div>
109
+ </td>`
110
+ : ''}
111
+ <td>${usageCell(consumers.get(token))}</td>
112
+ </tr>
113
+ `
114
+ )}
115
+ </tbody>
116
+ </table>
781
117
  </div>
782
- </div>
118
+ `;
119
+ }
120
+
121
+ /* ---------------------------------------------------------------------------
122
+ The one table everything else in this system rests on, and it was missing.
123
+
124
+ Type, images and controls never get the viewport -- they get what is left
125
+ after the gutters. Until this was written down, the number had to be
126
+ re-derived by whoever needed it, and at least once it was got wrong by
127
+ MEASURING a Storybook story instead: the harness adds 16px of body padding
128
+ either side, so a 288px column was recorded as 256 and moved a typography
129
+ conclusion by a whole step of the scale. Derive it from the tokens. */
130
+ const COLUMN_TABLE = [
131
+ ['320', 'xs', '100%', 16],
132
+ ['375', 'xs', '100%', 16],
133
+ ['576', 'sm', '540px', 24],
134
+ ['768', 'md', '720px', 32],
135
+ ['992', 'lg', '960px', 40],
136
+ ['1200', 'xl', '1140px', 40],
137
+ ['1400', 'xxl', '1320px', 40]
138
+ ];
139
+ const columnOf = (vw, cmax, padding) => {
140
+ const box = cmax === '100%' ? Number(vw) : parseInt(cmax, 10);
141
+ return Math.min(box, Number(vw)) - padding * 2;
142
+ };
143
+
144
+ export const TheColumn = () => html`
145
+ ${gridStyles}
146
+ ${docsPage({
147
+ title: 'The column',
148
+ lede : html`What content actually gets at each viewport:
149
+ <code>--grid-container-max-*</code> capped by the viewport, minus
150
+ <b>twice</b> <code>--grid-padding-*</code>. Every sizing decision in the
151
+ system — type, media, controls — is really a decision against this
152
+ number, not against the viewport.`,
153
+ note: html`<b>Derive it, do not measure it.</b> A Storybook story sits inside 16px of
154
+ harness body padding either side, so measuring one understates the column at the
155
+ <code>xs</code> tier. That mistake recorded a 288px column as 256 and moved a typography
156
+ conclusion by a whole step of the type scale.`,
157
+ children: html`
158
+ ${refSection({
159
+ name : 'Viewport to column',
160
+ meta : '7 widths · container − 2 × gutter',
161
+ children: html`
162
+ <div style="overflow-x: auto">
163
+ <table class="tokens-table">
164
+ <caption>The column at each breakpoint, and what the gutters cost</caption>
165
+ <thead>
166
+ <tr>
167
+ <th>viewport</th><th>tier</th><th>container max</th>
168
+ <th>gutter × 2</th><th>column</th><th>lost to gutters</th>
169
+ </tr>
170
+ </thead>
171
+ <tbody>
172
+ ${COLUMN_TABLE.map(([vw, tier, cmax, padding]) => {
173
+ const col = columnOf(vw, cmax, padding);
174
+ return html`
175
+ <tr>
176
+ <td>${vw}px</td>
177
+ <td><code>${tier}</code></td>
178
+ <td>${cmax === '100%' ? html`<code>100%</code> → ${vw}px` : cmax}</td>
179
+ <td>${padding} × 2 = ${padding * 2}px</td>
180
+ <td><b>${col}px</b></td>
181
+ <td>${Math.round((padding * 2 / Number(vw)) * 100)}%</td>
182
+ </tr>
183
+ `;
184
+ })}
185
+ </tbody>
186
+ </table>
187
+ </div>
188
+ <p>
189
+ <b><code>xl</code> and <code>xxl</code> inherit <code>--grid-padding-lg</code>.</b>
190
+ <code>ensemble.css.js</code> raises <code>max-width</code> above <code>lg</code> but
191
+ never the padding, so <b>40px is the widest gutter this system has</b> — and the
192
+ column therefore grows more slowly than the screen does. At 320 the gutters are 10%
193
+ of the screen; at 1400 they are 6%.
194
+ </p>
195
+ <p>
196
+ <b>Why it matters most at the narrow end.</b> A 320px phone gives type 288px. Against
197
+ that column the largest size at which the longest realistic compound word still fits
198
+ is <b>31px</b> — which is why nine type roles are fluid. See
199
+ <i>Foundations/Typography → Fluid type</i>.
200
+ </p>
201
+ `
202
+ })}
203
+ `
204
+ })}
783
205
  `;
784
- ResponsiveGrid.storyName = 'Responsive Grid';
785
- ResponsiveGrid.parameters = {
786
- docs: {
787
- description: {
788
- story: 'Responsive grid system with mobile-first approach. Shows how columns adapt to different screen sizes using responsive classes.'
789
- }
790
- }
206
+
207
+ export const GridTokens = () => {
208
+ const cssText = readAllCssText();
209
+ const consumers = discoverConsumers(cssText);
210
+
211
+ const groups = [
212
+ { name: 'Breakpoints', prefix: 'breakpoint-', ruler: true, caption: 'Breakpoint tokens' },
213
+ { name: 'Container max widths', prefix: 'grid-container-max-', ruler: true, caption: 'Container max widths' },
214
+ { name: 'Gutters', prefix: 'grid-gutter-', ruler: true, caption: 'Gutter tokens' },
215
+ { name: 'Container padding', prefix: 'grid-padding-', ruler: true, caption: 'Grid padding tokens' },
216
+ { name: 'Columns', prefix: 'grid-columns', ruler: false, caption: 'Column count' },
217
+ { name: 'Content widths', prefix: 'content-width-', ruler: false, caption: 'Content width tokens' }
218
+ ];
219
+
220
+ return html`
221
+ ${gridStyles}
222
+ ${docsPage({
223
+ title: 'Grid system',
224
+ lede : html`The layout tokens, read from the loaded token CSS at render time so this page
225
+ always matches <code>src/tokens/tokens.css</code>. Click a token name to copy its
226
+ <code>var()</code> reference.`,
227
+ note: html`<b>Breakpoint tokens cannot be used in a media query.</b>
228
+ <code>@media (min-width: var(--breakpoint-md))</code> does not work — custom properties are
229
+ not allowed in media conditions. Write the value literally, or import the breakpoint map
230
+ from JavaScript (<code>src/blog/src/breakpoints.js</code> does this for Lit
231
+ <code>css</code> templates). Note also that components currently hardcode several widths
232
+ that are not on this scale, so check the <b>Used by</b> column before assuming a
233
+ breakpoint is authoritative.`,
234
+ children: groups.map(({ name, prefix, ruler, caption }) => {
235
+ const tokens = tokensFor(cssText, prefix);
236
+ if (!tokens.length) return html``;
237
+ return refSection({
238
+ name,
239
+ meta : `${tokens.length} token${tokens.length === 1 ? '' : 's'} · --${prefix}*`,
240
+ children: tokenTable({ caption, tokens, consumers, ruler })
241
+ });
242
+ })
243
+ })}
244
+ `;
791
245
  };
792
246
 
793
- export const GutterExample = (args) => html`
794
- <style>
795
- .gutter-demo {
796
- padding: 2rem;
797
- background: #f8f9fa;
798
- min-height: 100vh;
799
- }
800
-
801
- .grid-container {
802
- max-width: 1200px;
803
- margin: 0 auto;
804
- padding: 2rem;
805
- background: white;
806
- border-radius: 8px;
807
- box-shadow: 0 2px 8px rgba(0,0,0,0.1);
808
- }
809
-
810
- .gutter-visualization {
811
- display: grid;
812
- grid-template-columns: repeat(2, 1fr);
813
- gap: 2rem;
814
- margin-bottom: 3rem;
815
- }
816
-
817
- .gutter-example {
818
- padding: 1.5rem;
819
- border-radius: 6px;
820
- border: 2px solid #dee2e6;
821
- }
822
-
823
- .example-title {
824
- font-family: var(--font-family-sans, sans-serif);
825
- font-weight: 600;
826
- margin: 0 0 1rem 0;
827
- color: #212529;
828
- }
829
-
830
- .grid-row-demo {
831
- display: grid;
832
- grid-template-columns: repeat(2, 1fr);
833
- margin: 1rem 0;
834
- }
835
-
836
- .grid-col-demo {
837
- background: #007bff;
838
- color: white;
839
- padding: 1rem;
840
- border-radius: 4px;
841
- font-family: var(--font-family-sans, sans-serif);
842
- text-align: center;
843
- }
844
-
845
- .no-gap { gap: 0; }
846
- .gap-sm { gap: var(--space-sm); }
847
- .gap-md { gap: var(--space-md); }
848
- .gap-lg { gap: var(--space-lg); }
849
-
850
- .gutter-preview {
851
- height: 60px;
852
- background: repeating-linear-gradient(
853
- 90deg,
854
- #dee2e6,
855
- #dee2e6 1px,
856
- transparent 1px,
857
- transparent calc(${args.gutter} - 1px)
858
- );
859
- margin: 1rem 0;
860
- border-radius: 4px;
861
- }
862
-
863
- .gutter-value {
864
- font-family: var(--font-family-mono, monospace);
865
- background: #f8f9fa;
866
- padding: 0.5rem;
867
- border-radius: 4px;
868
- margin: 0.5rem 0;
869
- }
870
- </style>
247
+ export const GridContainer = () => {
248
+ const sizes = ['xs', 'sm', 'md', 'lg', 'xl', 'xxl'];
249
+
250
+ return html`
251
+ ${gridStyles}
252
+ ${docsPage({
253
+ title: 'Containers',
254
+ lede : html`Each container caps content at its breakpoint's max width and applies the
255
+ matching horizontal padding. Widths are the real token values, so the bars below are to
256
+ scale with each other.`,
257
+ children: html`${refSection({
258
+ name : 'Container max widths',
259
+ meta : '--grid-container-max-* with --grid-padding-*',
260
+ children: html`
261
+ ${sizes.map(size => {
262
+ const maxToken = `--grid-container-max-${size}`;
263
+ const padToken = `--grid-padding-${['xs', 'sm', 'md', 'lg'].includes(size) ? size : 'lg'}`;
264
+ return html`
265
+ <p class="demo-label">${maxToken} = ${resolve(maxToken)} · ${padToken} = ${resolve(padToken)}</p>
266
+ <div class="demo-frame">
267
+ <div
268
+ class="demo-container"
269
+ style="max-width: var(${maxToken}); padding: var(--spacing-12) var(${padToken})"
270
+ >
271
+ <div class="demo-cell">${size}</div>
272
+ </div>
273
+ </div>
274
+ `;
275
+ })}
276
+ `
277
+ })}${refSection({
278
+ name : 'The page column',
279
+ meta : '.bd-ensemble · src/components/shared/ensemble.css.js',
280
+ children: html`
281
+ <p class="demo-label">
282
+ This container is implemented once, as <code>ensembleCSS</code>. Every page-level
283
+ module composes it and puts <code>bd-ensemble</code> on the element that holds its
284
+ content, so a page assembled from independent sections has its content on one pair
285
+ of edges. A column nested inside another collapses on its own. See
286
+ <code>check:ensemble</code>, and the page column section of CLAUDE.md.
287
+ </p>
288
+ `
289
+ })}`
290
+ })}
291
+ `;
292
+ };
871
293
 
872
- <div class="gutter-demo">
873
- <div class="grid-container">
874
- <h3 style="font-family: var(--font-family-sans, sans-serif); margin: 0 0 2rem 0;">Grid Gutter System</h3>
875
-
876
- <div class="gutter-visualization">
877
- <div class="gutter-example">
878
- <h4 class="example-title">No Gutter</h4>
879
- <div class="grid-row-demo no-gap">
880
- <div class="grid-col-demo">Column 1</div>
881
- <div class="grid-col-demo">Column 2</div>
882
- </div>
883
- <div class="gutter-value">gap: 0</div>
884
- </div>
885
-
886
- <div class="gutter-example">
887
- <h4 class="example-title">Small Gutter</h4>
888
- <div class="grid-row-demo gap-sm">
889
- <div class="grid-col-demo">Column 1</div>
890
- <div class="grid-col-demo">Column 2</div>
891
- </div>
892
- <div class="gutter-value">gap: var(--space-sm)</div>
893
- </div>
894
-
895
- <div class="gutter-example">
896
- <h4 class="example-title">Medium Gutter (Default)</h4>
897
- <div class="grid-row-demo gap-md">
898
- <div class="grid-col-demo">Column 1</div>
899
- <div class="grid-col-demo">Column 2</div>
900
- </div>
901
- <div class="gutter-value">gap: var(--space-md)</div>
902
- </div>
903
-
904
- <div class="gutter-example">
905
- <h4 class="example-title">Large Gutter</h4>
906
- <div class="grid-row-demo gap-lg">
907
- <div class="grid-col-demo">Column 1</div>
908
- <div class="grid-col-demo">Column 2</div>
294
+ export const FixedColumns = () => {
295
+ const columnCount = Number(resolve('--grid-columns')) || 12;
296
+ const spans = [
297
+ [12],
298
+ [6, 6],
299
+ [4, 4, 4],
300
+ [3, 3, 3, 3],
301
+ [8, 4],
302
+ [2, 8, 2]
303
+ ];
304
+
305
+ return html`
306
+ ${gridStyles}
307
+ ${docsPage({
308
+ title: 'Columns',
309
+ lede : html`The grid is <b>${columnCount}</b> columns
310
+ (<code>--grid-columns</code>), with <code>--grid-gutter-md</code> between them.`,
311
+ children: refSection({
312
+ name : 'Common splits',
313
+ meta : `${columnCount} columns · --grid-gutter-md`,
314
+ children: html`
315
+ ${spans.map(
316
+ row => html`
317
+ <p class="demo-label">${row.join(' + ')}</p>
318
+ <div class="demo-frame">
319
+ <div
320
+ class="demo-grid"
321
+ style="--demo-cols: ${columnCount}; gap: var(--grid-gutter-md)"
322
+ >
323
+ ${row.map(
324
+ (span, index) => html`
325
+ <div
326
+ class="demo-cell ${index % 2 ? 'demo-cell--alt' : ''}"
327
+ style="grid-column: span ${span}"
328
+ >
329
+ ${span}
330
+ </div>
331
+ `
332
+ )}
333
+ </div>
334
+ </div>
335
+ `
336
+ )}
337
+ `
338
+ })
339
+ })}
340
+ `;
341
+ };
342
+
343
+ export const ResponsiveGrid = () => html`
344
+ ${gridStyles}
345
+ ${docsPage({
346
+ title: 'Responsive columns',
347
+ lede : html`Resize the canvas to see the column count change. The media queries below use the
348
+ literal breakpoint values, because <code>var(--breakpoint-*)</code> is not valid inside a
349
+ media condition — this is the gap the token scale cannot close on its own.`,
350
+ children: refSection({
351
+ name : 'One / two / three / four up',
352
+ meta : '576px · 768px · 992px — mirrors --breakpoint-sm/md/lg',
353
+ children: html`
354
+ <style>
355
+ .responsive-demo {
356
+ display: grid;
357
+ gap: var(--grid-gutter-md);
358
+ grid-template-columns: 1fr;
359
+ }
360
+ /* literal values, matching --breakpoint-sm/md/lg */
361
+ @media (min-width: 576px) {
362
+ .responsive-demo { grid-template-columns: repeat(2, 1fr); }
363
+ }
364
+ @media (min-width: 768px) {
365
+ .responsive-demo { grid-template-columns: repeat(3, 1fr); }
366
+ }
367
+ @media (min-width: 992px) {
368
+ .responsive-demo { grid-template-columns: repeat(4, 1fr); }
369
+ }
370
+ </style>
371
+ <div class="demo-frame">
372
+ <div class="responsive-demo">
373
+ ${Array.from(
374
+ { length: 8 },
375
+ (_unused, index) => html`
376
+ <div class="demo-cell ${index % 2 ? 'demo-cell--alt' : ''}">${index + 1}</div>
377
+ `
378
+ )}
909
379
  </div>
910
- <div class="gutter-value">gap: var(--space-lg)</div>
911
380
  </div>
912
- </div>
913
-
914
- <div style="background: #f8f9fa; padding: 1.5rem; border-radius: 6px; margin-top: 2rem;">
915
- <h4 style="font-family: var(--font-family-sans, sans-serif); margin: 0 0 1rem 0;">Current Gutter Preview</h4>
916
- <div class="gutter-preview"></div>
917
- <div class="gutter-value">Current gutter value: ${args.gutter}</div>
918
- </div>
919
- </div>
920
- </div>
381
+ `
382
+ })
383
+ })}
921
384
  `;
922
- GutterExample.args = {
923
- gutter: 'var(--space-md)'
385
+
386
+ export const GutterExample = () => {
387
+ const gutters = ['xs', 'sm', 'md', 'lg'];
388
+
389
+ return html`
390
+ ${gridStyles}
391
+ ${docsPage({
392
+ title : 'Gutters',
393
+ lede : 'The four gutter steps applied to the same four-column grid, so the difference is judged against identical content.',
394
+ children: refSection({
395
+ name : 'Gutter scale',
396
+ meta : '--grid-gutter-*',
397
+ children: html`
398
+ ${gutters.map(size => {
399
+ const token = `--grid-gutter-${size}`;
400
+ return html`
401
+ <p class="demo-label">${token} = ${resolve(token)}</p>
402
+ <div class="demo-frame">
403
+ <div class="demo-grid" style="--demo-cols: 4; gap: var(${token})">
404
+ ${Array.from(
405
+ { length: 4 },
406
+ (_unused, index) => html`
407
+ <div class="demo-cell ${index % 2 ? 'demo-cell--alt' : ''}">
408
+ ${index + 1}
409
+ </div>
410
+ `
411
+ )}
412
+ </div>
413
+ </div>
414
+ `;
415
+ })}
416
+ `
417
+ })
418
+ })}
419
+ `;
924
420
  };
925
- GutterExample.storyName = 'Grid Gutter';
926
- GutterExample.parameters = {
927
- docs: {
928
- description: {
929
- story: 'Grid gutter (gap) system demonstrating different spacing options between columns. Shows visual comparison of no gutter, small, medium, and large gutters.'
930
- }
931
- }
932
- };