@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.
- package/CHANGELOG.md +187 -0
- package/README.md +131 -8
- package/package.json +95 -13
- package/schemas/component-manifest.json +3294 -405
- package/schemas/manifest-omissions.json +173 -0
- package/src/blog/src/breakpoints.js +6 -6
- package/src/blog/src/content/blog-atoms-showcase.js +1 -1
- package/src/blog/src/content/blog-page-layout.js +2 -2
- package/src/blog/src/lib/article-toc.js +7 -7
- package/src/blog/src/shell/blog-shell.js +1 -1
- package/src/blog/src/tokens/blog.js +2 -2
- package/src/blog/src/tokens/core.js +34 -35
- package/src/blog/src/tokens/legacy.js +0 -9
- package/src/blog/tokens/blog.js +2 -2
- package/src/blog/tokens/core.js +34 -35
- package/src/blog/tokens/legacy.js +0 -9
- package/src/blog/tokens.css +36 -46
- package/src/components/accordion/accordion-bg.css.js +83 -59
- package/src/components/accordion/accordion-bg.js +29 -10
- package/src/components/accordion/accordion-bg.stories.js +67 -67
- package/src/components/accordion/accordion-keyboard.js +80 -0
- package/src/components/accordion/accordion.css.js +142 -80
- package/src/components/accordion/accordion.js +37 -10
- package/src/components/accordion/accordion.stories.js +7 -7
- package/src/components/agent-endpoints/agent-endpoints.css.js +36 -39
- package/src/components/agent-endpoints/agent-endpoints.js +30 -20
- package/src/components/agent-endpoints/agent-endpoints.stories.js +1 -1
- package/src/components/ai-guardian-demo.stories.js +91 -91
- package/src/components/alert/alert.css.js +198 -0
- package/src/components/alert/alert.js +103 -0
- package/src/components/alert/alert.stories.js +206 -0
- package/src/components/anchor/anchor-nav.css.js +213 -101
- package/src/components/anchor/anchor-nav.js +26 -40
- package/src/components/anchor/anchor.stories.js +22 -12
- package/src/components/annotation/annotation.css.js +58 -0
- package/src/components/annotation/annotation.js +67 -0
- package/src/components/annotation/annotation.stories.js +63 -0
- package/src/components/architecture.stories.js +285 -0
- package/src/components/atoms.stories.js +342 -0
- package/src/components/avatar/avatar.css.js +67 -0
- package/src/components/avatar/avatar.js +42 -0
- package/src/components/avatar/avatar.stories.js +95 -0
- package/src/components/awards/awards-flex.css.js +209 -23
- package/src/components/awards/awards-flex.js +66 -7
- package/src/components/awards/awards-flex.stories.js +1 -1
- package/src/components/awards/{awards-light.stories.js → awards-summary.stories.js} +54 -64
- package/src/components/awards/awards.css.js +116 -58
- package/src/components/awards/awards.js +102 -28
- package/src/components/awards/awards.stories.js +1 -1
- package/src/components/back/back.css.js +51 -22
- package/src/components/back/back.js +28 -7
- package/src/components/back/back.stories.js +9 -3
- package/src/components/badge/badge.css.js +158 -46
- package/src/components/badge/badge.js +62 -74
- package/src/components/badge/badge.stories.js +176 -248
- package/src/components/bento-grid/bento-grid.css.js +21 -16
- package/src/components/bento-grid/bento-grid.js +16 -4
- package/src/components/bento-grid/bento-grid.stories.js +19 -18
- package/src/components/bento-grid/bento-item.css.js +52 -28
- package/src/components/bento-grid/bento-item.js +2 -2
- package/src/components/blockquote/blockquote.css.js +47 -0
- package/src/components/blockquote/blockquote.js +29 -0
- package/src/components/blockquote/blockquote.stories.js +62 -0
- package/src/components/breadcrumb/breadcrumb.css.js +92 -22
- package/src/components/breadcrumb/breadcrumb.js +56 -11
- package/src/components/button/button.css.js +531 -161
- package/src/components/button/button.js +206 -214
- package/src/components/button/button.stories.js +322 -174
- package/src/components/caption/caption.css.js +21 -0
- package/src/components/caption/caption.js +31 -0
- package/src/components/caption/caption.stories.js +62 -0
- package/src/components/card-features/card-features.css.js +14 -22
- package/src/components/card-features/card-features.js +68 -9
- package/src/components/card-features/card-features.stories.js +11 -11
- package/src/components/cards/card.css.js +60 -81
- package/src/components/cards/card.js +56 -25
- package/src/components/cards/card.stories.js +39 -39
- package/src/components/carousel/carousel.css.js +93 -99
- package/src/components/carousel/carousel.js +32 -4
- package/src/components/checkbox/checkbox.css.js +111 -93
- package/src/components/checkbox/checkbox.js +64 -90
- package/src/components/checkbox/checkbox.stories.js +96 -29
- package/src/components/code/code.css.js +70 -0
- package/src/components/code/code.js +40 -0
- package/src/components/code/code.stories.js +73 -0
- package/src/components/compare/compare.css.js +179 -43
- package/src/components/compare/compare.js +52 -25
- package/src/components/compare/compare.stories.js +61 -4
- package/src/components/comparison-panel/comparison-panel.css.js +38 -51
- package/src/components/comparison-panel/comparison-panel.js +5 -4
- package/src/components/comparison-panel/comparison-panel.stories.js +1 -1
- package/src/components/compatibility-table/compatibility-table.css.js +180 -80
- package/src/components/compatibility-table/compatibility-table.js +37 -9
- package/src/components/control-alignment.stories.js +393 -0
- package/src/components/cta-banner/cta-banner.css.js +41 -13
- package/src/components/cta-banner/cta-banner.js +6 -5
- package/src/components/cta-banner/cta-banner.stories.js +43 -98
- package/src/components/display/display.css.js +25 -1
- package/src/components/display/display.js +46 -13
- package/src/components/display/display.stories.js +270 -40
- package/src/components/divider/divider-horizontal.js +21 -5
- package/src/components/divider/divider-vertical.js +15 -7
- package/src/components/divider/divider.css.js +2 -2
- package/src/components/divider/divider.stories.js +38 -34
- package/src/components/dropdown/dropdown.css.js +93 -126
- package/src/components/dropdown/dropdown.js +114 -34
- package/src/components/dropdown/dropdown.stories.js +56 -24
- package/src/components/features/features.css.js +24 -11
- package/src/components/features/features.js +7 -3
- package/src/components/features/features.stories.js +37 -37
- package/src/components/features-tab/features-tab.css.js +19 -8
- package/src/components/features-tab/features-tab.js +6 -5
- package/src/components/features-tab/features-tab.stories.js +23 -23
- package/src/components/fieldset/fieldset.css.js +30 -0
- package/src/components/fieldset/fieldset.js +28 -0
- package/src/components/fieldset/fieldset.stories.js +84 -0
- package/src/components/footer/footer-links-group.css.js +10 -14
- package/src/components/footer/footer-links-group.js +4 -3
- package/src/components/footer/footer-lp.css.js +59 -30
- package/src/components/footer/footer-lp.js +17 -12
- package/src/components/footer/footer-lp.stories.js +63 -75
- package/src/components/footer/footer-nav-menu.css.js +26 -4
- package/src/components/footer/footer-nav-menu.js +3 -2
- package/src/components/footer/footer.css.js +146 -264
- package/src/components/footer/footer.js +176 -106
- package/src/components/footer/footer.stories.js +9 -9
- package/src/components/footer/localeMap.js +1 -1
- package/src/components/grid/grid.css.js +1 -1
- package/src/components/grid/grid.js +49 -7
- package/src/components/grid/grid.stories.js +111 -0
- package/src/components/header/header-code.css.js +61 -51
- package/src/components/header/header-code.js +28 -14
- package/src/components/header/header-code.stories.js +5 -5
- package/src/components/header/header.css.js +655 -176
- package/src/components/header/header.js +269 -36
- package/src/components/header/header.stories.js +841 -18
- package/src/components/heading/heading.css.js +14 -17
- package/src/components/heading/heading.js +48 -33
- package/src/components/heading/heading.stories.js +27 -25
- package/src/components/help-text/help-text.css.js +21 -0
- package/src/components/help-text/help-text.js +25 -0
- package/src/components/help-text/help-text.stories.js +66 -0
- package/src/components/highlight/highlight.css.js +86 -64
- package/src/components/highlight/highlight.js +18 -27
- package/src/components/highlight/highlight.stories.js +14 -3
- package/src/components/icons/analysis-icon.js +6 -16
- package/src/components/icons/arrow-down-icon.js +6 -19
- package/src/components/icons/arrow-icon.js +44 -0
- package/src/components/icons/arrow-right-icon.js +30 -23
- package/src/components/icons/arrow-up-icon.js +19 -18
- package/src/components/icons/bd-ai-icon.js +1 -1
- package/src/components/icons/brand-marks.stories.js +279 -0
- package/src/components/icons/brand-signature-icon.js +42 -0
- package/src/components/icons/check-icon.js +27 -0
- package/src/components/icons/circle-info-icon.js +33 -0
- package/src/components/icons/close-icon.js +6 -18
- package/src/components/icons/family-icon.js +8 -20
- package/src/components/icons/globe-icon.js +6 -18
- package/src/components/icons/guide-icon.js +6 -18
- package/src/components/icons/icon-element.js +99 -0
- package/src/components/icons/icons.js +36 -0
- package/src/components/icons/icons.stories.js +184 -52
- package/src/components/icons/individual-icon.js +6 -18
- package/src/components/icons/laurel-icon.js +9 -19
- package/src/components/icons/machine-learning-icon.js +6 -17
- package/src/components/icons/marks.js +41 -0
- package/src/components/icons/minus-icon.js +7 -21
- package/src/components/icons/missing-icon.js +52 -0
- package/src/components/icons/plus-icon.js +7 -21
- package/src/components/icons/quote-icon.js +19 -19
- package/src/components/image/image.css.js +72 -25
- package/src/components/image/image.js +11 -6
- package/src/components/image/image.stories.js +2 -2
- package/src/components/input/custom-form.stories.js +214 -62
- package/src/components/input/input-clipboard.css.js +51 -144
- package/src/components/input/input-clipboard.js +31 -15
- package/src/components/input/input.css.js +8 -146
- package/src/components/input/input.js +93 -38
- package/src/components/install-options/install-options.css.js +84 -77
- package/src/components/install-options/install-options.js +33 -30
- package/src/components/install-options/install-options.stories.js +3 -3
- package/src/components/label/label.css.js +35 -0
- package/src/components/label/label.js +38 -0
- package/src/components/label/label.stories.js +82 -0
- package/src/components/light-carousel/light-carousel.css.js +111 -63
- package/src/components/light-carousel/light-carousel.js +85 -11
- package/src/components/light-carousel/light-carousel.stories.js +126 -82
- package/src/components/link/link.css.js +150 -99
- package/src/components/link/link.js +86 -11
- package/src/components/link/link.stories.js +124 -30
- package/src/components/list/list-item/list-item.css.js +74 -22
- package/src/components/list/list-item/list-item.js +32 -10
- package/src/components/list/list-item/list-item.stories.js +23 -23
- package/src/components/list/list.css.js +8 -2
- package/src/components/list/list.js +3 -2
- package/src/components/list/list.stories.js +222 -0
- package/src/components/modal/modal.css.js +114 -24
- package/src/components/modal/modal.js +83 -7
- package/src/components/modal/modal.stories.js +9 -9
- package/src/components/overview/overview.css.js +19 -14
- package/src/components/overview/overview.js +6 -5
- package/src/components/overview/overview.stories.js +10 -10
- package/src/components/page-switcher/page-switcher.css.js +97 -40
- package/src/components/page-switcher/page-switcher.js +28 -5
- package/src/components/page-switcher/page-switcher.stories.js +95 -0
- package/src/components/paragraph/paragraph.css.js +15 -10
- package/src/components/paragraph/paragraph.js +41 -44
- package/src/components/paragraph/paragraph.stories.js +56 -21
- package/src/components/picture/picture.css.js +103 -44
- package/src/components/picture/picture.js +100 -30
- package/src/components/picture/picture.stories.js +1 -1
- package/src/components/pricing-cards/new-pricing-card.js +3 -3
- package/src/components/pricing-cards/new-pricing.css.js +24 -15
- package/src/components/pricing-cards/pricing-card-actions.css.js +1 -1
- package/src/components/pricing-cards/pricing-card-actions.js +3 -4
- package/src/components/pricing-cards/pricing-card-container.css.js +3 -3
- package/src/components/pricing-cards/pricing-card-container.js +3 -2
- package/src/components/pricing-cards/pricing-card-header.css.js +10 -8
- package/src/components/pricing-cards/pricing-card-header.js +6 -7
- package/src/components/pricing-cards/pricing-card-pricing.css.js +16 -9
- package/src/components/pricing-cards/pricing-card-pricing.js +8 -6
- package/src/components/pricing-cards/pricing-card-show-more.css.js +11 -3
- package/src/components/pricing-cards/pricing-card-show-more.js +8 -3
- package/src/components/pricing-cards/pricing-card.css.js +244 -190
- package/src/components/pricing-cards/pricing-card.js +54 -70
- package/src/components/pricing-cards/pricing-feature-item.css.js +25 -8
- package/src/components/pricing-cards/pricing-feature-item.js +8 -3
- package/src/components/process-steps/process-steps.css.js +26 -14
- package/src/components/process-steps/process-steps.js +23 -6
- package/src/components/process-steps/process-steps.stories.js +1 -1
- package/src/components/progress/progress.css.js +80 -0
- package/src/components/progress/progress.js +42 -0
- package/src/components/progress/progress.stories.js +79 -0
- package/src/components/quick-answer/quick-answer.css.js +75 -13
- package/src/components/quick-answer/quick-answer.js +8 -3
- package/src/components/radio/radio.css.js +92 -128
- package/src/components/radio/radio.js +106 -127
- package/src/components/radio/radio.stories.js +54 -19
- package/src/components/review/review-grid.css.js +5 -6
- package/src/components/review/review-grid.js +14 -11
- package/src/components/review/review.css.js +11 -6
- package/src/components/review/review.js +3 -8
- package/src/components/shared/ensemble.css.js +93 -0
- package/src/components/shared/form-field.css.js +206 -0
- package/src/components/shared/prop-vocabulary.js +48 -0
- package/src/components/shared/token-scales.js +306 -0
- package/src/components/skeleton/skeleton.css.js +34 -0
- package/src/components/skeleton/skeleton.js +32 -0
- package/src/components/skeleton/skeleton.stories.js +70 -0
- package/src/components/spinner/spinner.css.js +62 -0
- package/src/components/spinner/spinner.js +38 -0
- package/src/components/spinner/spinner.stories.js +92 -0
- package/src/components/spotlight-section/spotlight-section.css.js +14 -13
- package/src/components/spotlight-section/spotlight-section.js +42 -39
- package/src/components/switch/switch.css.js +103 -0
- package/src/components/switch/switch.js +44 -0
- package/src/components/switch/switch.stories.js +86 -0
- package/src/components/tab-list/content-switcher.stories.js +189 -0
- package/src/components/tab-list/tab-list.css.js +250 -0
- package/src/components/tab-list/tab-list.js +184 -0
- package/src/components/tab-list/tab-list.stories.js +221 -0
- package/src/components/tabs/tabs.css.js +14 -123
- package/src/components/tabs/tabs.js +16 -19
- package/src/components/tabs/tabs.stories.js +95 -95
- package/src/components/tag/tag.css.js +54 -0
- package/src/components/tag/tag.js +32 -0
- package/src/components/tag/tag.stories.js +126 -0
- package/src/components/terminal/terminal-message.css.js +164 -60
- package/src/components/terminal/terminal-message.js +5 -5
- package/src/components/terminal/terminal-message.stories.js +70 -1
- package/src/components/termsOfUse/terms.css.js +25 -20
- package/src/components/termsOfUse/terms.js +13 -9
- package/src/components/termsOfUse/terms.stories.js +1 -1
- package/src/components/textarea/textarea.css.js +51 -0
- package/src/components/textarea/textarea.js +136 -0
- package/src/components/textarea/textarea.stories.js +191 -0
- package/src/components/tooltip/tooltip.css.js +75 -0
- package/src/components/tooltip/tooltip.js +156 -0
- package/src/components/tooltip/tooltip.stories.js +161 -0
- package/src/components/trust-panel/trust-panel.css.js +85 -33
- package/src/components/trust-panel/trust-panel.js +18 -10
- package/src/components/trust-panel/trust-panel.stories.js +1 -1
- package/src/components/ultimate-security-demo.stories.js +431 -0
- package/src/components/video/video.css.js +17 -0
- package/src/components/video/video.js +40 -0
- package/src/components/video/video.stories.js +106 -0
- package/src/components/video-player/video-player.css.js +67 -11
- package/src/components/video-player/video-player.js +35 -4
- package/src/components/video-player/video-player.stories.js +1 -1
- package/src/components/visual-alignment.stories.js +411 -0
- package/src/components/visually-hidden/visually-hidden.css.js +24 -0
- package/src/components/visually-hidden/visually-hidden.js +16 -0
- package/src/components/visually-hidden/visually-hidden.stories.js +56 -0
- package/src/stories/Button.stories.js +17 -17
- package/src/stories/Header.stories.js +10 -10
- package/src/stories/Page.js +1 -1
- package/src/stories/Page.stories.js +6 -6
- package/src/tokens/borders.stories.js +339 -0
- package/src/tokens/color-responsibilities.stories.js +227 -0
- package/src/tokens/dark-derivation.js +309 -0
- package/src/tokens/dark-findings.js +197 -0
- package/src/tokens/dark-mode.stories.js +207 -0
- package/src/tokens/dimension.stories.js +251 -0
- package/src/tokens/elevation.stories.js +143 -0
- package/src/tokens/focus.stories.js +276 -0
- package/src/tokens/fonts.css +20 -20
- package/src/tokens/fonts.stories.js +354 -374
- package/src/tokens/layout.css +25 -11
- package/src/tokens/motion.stories.js +231 -0
- package/src/tokens/shape.stories.js +272 -0
- package/src/tokens/spacing-rhythm.stories.js +359 -0
- package/src/tokens/spacing.stories.js +208 -703
- package/src/tokens/story-chrome.js +503 -0
- package/src/tokens/surfaces.stories.js +224 -0
- package/src/tokens/text-on-surface.stories.js +164 -0
- package/src/tokens/token-map.js +220 -0
- package/src/tokens/token-map.stories.js +257 -0
- package/src/tokens/token-purposes.js +266 -0
- package/src/tokens/tokens-grid.stories.js +388 -900
- package/src/tokens/tokens.css +1633 -1045
- package/src/tokens/tokens.js +1130 -492
- package/src/tokens/tokens.stories.js +137 -47
- package/src/tokens/type-ceiling-words.js +299 -0
- package/src/tokens/typography.stories.js +1003 -965
- package/src/tokens/vertical-rhythm.stories.js +224 -0
- package/src/components/awards/awards-icon.js +0 -56
- package/src/components/awards/awards-light.js +0 -240
- package/src/components/banner/banner.js +0 -60
- package/src/components/banner/banner.stories.js +0 -51
- package/src/components/button/icons.js +0 -24
- package/src/components/input/index.js +0 -0
- package/src/components/light-carousel/light-carousel-simple.css.js +0 -183
- package/src/components/light-carousel/light-carousel-simple.js +0 -74
- package/src/tokens/colors.js +0 -121
- package/src/tokens/typography.css.js +0 -207
- package/src/tokens/typography.js +0 -0
package/src/tokens/tokens.css
CHANGED
|
@@ -1,1048 +1,1636 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
--
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
1
|
+
/* =====================================================================
|
|
2
|
+
Design tokens — document scope, inside the `bd-tokens` cascade layer.
|
|
3
|
+
|
|
4
|
+
The layer is what lets an application override a token: anything in a
|
|
5
|
+
cascade layer loses to unlayered CSS, so a consumer's own
|
|
6
|
+
`:root { --color-blue-500: ... }` wins over these defaults.
|
|
7
|
+
|
|
8
|
+
AUTO-GENERATED from src/tokens/tokens.js — run `npm run build:tokens`.
|
|
9
|
+
===================================================================== */
|
|
10
|
+
|
|
11
|
+
@layer bd-tokens {
|
|
12
|
+
:root {
|
|
13
|
+
--typography-fontFamily-sans: "IBM Plex Sans", system-ui, -apple-system,
|
|
14
|
+
BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
15
|
+
--typography-fontFamily-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular,
|
|
16
|
+
Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
17
|
+
|
|
18
|
+
--typography-fontSize-xxs: 0.6875rem; /* 11px */
|
|
19
|
+
--typography-fontSize-xs: 0.75rem; /* 12px */
|
|
20
|
+
--typography-fontSize-sm: 0.875rem; /* 14px */
|
|
21
|
+
--typography-fontSize-base: 1rem; /* 16px */
|
|
22
|
+
--typography-fontSize-lg: 1.125rem; /* 18px */
|
|
23
|
+
--typography-fontSize-xl: 1.25rem; /* 20px */
|
|
24
|
+
--typography-fontSize-2xl: 1.5rem; /* 24px */
|
|
25
|
+
--typography-fontSize-3xl: 2rem; /* 32px */
|
|
26
|
+
--typography-fontSize-4xl: 2.25rem; /* 36px */
|
|
27
|
+
--typography-fontSize-5xl: 3rem; /* 48px */
|
|
28
|
+
--typography-fontSize-6xl: 3.75rem; /* 60px */
|
|
29
|
+
--typography-fontSize-7xl: 4.5rem; /* 72px */
|
|
30
|
+
--typography-fontSize-8xl: 6rem; /* 96px */
|
|
31
|
+
--typography-fontSize-9xl: 8rem; /* 128px */
|
|
32
|
+
|
|
33
|
+
--typography-fontWeight-light: 300;
|
|
34
|
+
--typography-fontWeight-normal: 400;
|
|
35
|
+
--typography-fontWeight-medium: 500;
|
|
36
|
+
--typography-fontWeight-semibold: 600;
|
|
37
|
+
--typography-fontWeight-bold: 700;
|
|
38
|
+
|
|
39
|
+
--typography-lineHeight-none: 1;
|
|
40
|
+
--typography-lineHeight-tight: 1.25;
|
|
41
|
+
/* There is no snug (1.375). It was Tailwind's step, it carried the
|
|
42
|
+
heading roles until the leading was measured against IBM Plex Sans,
|
|
43
|
+
and once those moved to tight and 130 its only readers were four
|
|
44
|
+
documentation-chrome files setting 11px text. 11px is what
|
|
45
|
+
label-extra-small already answers, at normal, so they were repointed
|
|
46
|
+
there and the step was retired rather than kept alive by its own
|
|
47
|
+
documentation. */
|
|
48
|
+
--typography-lineHeight-normal: 1.5;
|
|
49
|
+
--typography-lineHeight-relaxed: 1.625;
|
|
50
|
+
--typography-lineHeight-loose: 2;
|
|
51
|
+
|
|
52
|
+
/* The three steps above named for a density -- none .. loose -- are
|
|
53
|
+
Tailwind's default scale, values and names both, and nothing in them
|
|
54
|
+
was derived from IBM Plex Sans. These three were, and they are named
|
|
55
|
+
numerically because that is what the rest of this system does for a
|
|
56
|
+
scale step: --spacing-14, --dimension-44, --border-width-2.
|
|
57
|
+
|
|
58
|
+
130 the font's own declared line box. hhea, OS/2 sTypo and OS/2
|
|
59
|
+
usWin in IBMPlexSans-*.woff2 all state 1.30, which is both
|
|
60
|
+
unusual and deliberate -- it is why the same text does not
|
|
61
|
+
change height between macOS and Windows.
|
|
62
|
+
140 IBM's own published value for Plex at 20px (@carbon/type,
|
|
63
|
+
productive-heading-03 and expressive-heading-03).
|
|
64
|
+
145 between IBM's 1.5 at 16px and 1.4 at 20px.
|
|
65
|
+
|
|
66
|
+
The floor under all of them is ink, not taste. The deepest glyphs in
|
|
67
|
+
this family are the Romanian comma-below letters -- s-comma and
|
|
68
|
+
t-comma, -0.275em in Bold, a third deeper than g -- and the tallest
|
|
69
|
+
are grave and acute capitals at +0.977em. Measured per weight, ink
|
|
70
|
+
spans 1.174 Light, 1.194 Regular, 1.219 Medium, 1.235 SemiBold,
|
|
71
|
+
1.252 Bold. Nothing may be set below the floor for its weight, which
|
|
72
|
+
is why the display roles stay at tight and are not tightened further.
|
|
73
|
+
Foundations/Typography/Vertical Rhythm reaches 1.231 for 48px Bold
|
|
74
|
+
from canvas metrics; this is the same number from outline bounds. */
|
|
75
|
+
--typography-lineHeight-130: 1.3;
|
|
76
|
+
--typography-lineHeight-140: 1.4;
|
|
77
|
+
--typography-lineHeight-145: 1.45;
|
|
78
|
+
|
|
79
|
+
--typography-letterSpacing-tighter: -0.05em;
|
|
80
|
+
--typography-letterSpacing-tight: -0.025em;
|
|
81
|
+
--typography-letterSpacing-normal: 0em;
|
|
82
|
+
--typography-letterSpacing-wide: 0.025em;
|
|
83
|
+
--typography-letterSpacing-wider: 0.05em;
|
|
84
|
+
--typography-letterSpacing-widest: 0.1em;
|
|
85
|
+
|
|
86
|
+
/* =====================
|
|
87
|
+
COLORS
|
|
88
|
+
====================== */
|
|
89
|
+
--color-blue-50: #f0f7ff;
|
|
90
|
+
--color-blue-100: #d6e8ff;
|
|
91
|
+
--color-blue-200: #9ec8ff;
|
|
92
|
+
--color-blue-300: #6babff;
|
|
93
|
+
--color-blue-400: #338bff;
|
|
94
|
+
--color-blue-500: #006dff;
|
|
95
|
+
--color-blue-600: #0059d6;
|
|
96
|
+
--color-blue-700: #0045ad;
|
|
97
|
+
--color-blue-800: #003385;
|
|
98
|
+
--color-blue-900: #00225c;
|
|
99
|
+
--color-blue-950: #001947;
|
|
100
|
+
|
|
101
|
+
--color-red-50: #fff0f0;
|
|
102
|
+
--color-red-100: #ffd6d6;
|
|
103
|
+
--color-red-200: #ff9e9e;
|
|
104
|
+
--color-red-300: #ff6b6b;
|
|
105
|
+
--color-red-400: #ff3333;
|
|
106
|
+
--color-red-500: #ff0000;
|
|
107
|
+
--color-red-600: #d60000;
|
|
108
|
+
--color-red-700: #ad0000;
|
|
109
|
+
--color-red-800: #850000;
|
|
110
|
+
--color-red-900: #5c0000;
|
|
111
|
+
--color-red-950: #470000;
|
|
112
|
+
|
|
113
|
+
--color-green-50: #edfdf1;
|
|
114
|
+
--color-green-100: #d1fadc;
|
|
115
|
+
--color-green-200: #9af4b4;
|
|
116
|
+
--color-green-300: #63ee8d;
|
|
117
|
+
--color-green-400: #2ce767;
|
|
118
|
+
--color-green-500: #15c14f;
|
|
119
|
+
--color-green-600: #12a641;
|
|
120
|
+
--color-green-700: #0e8532;
|
|
121
|
+
--color-green-800: #0b6a26;
|
|
122
|
+
--color-green-900: #084a1a;
|
|
123
|
+
--color-green-950: #063c14;
|
|
124
|
+
--color-green-975: #011705;
|
|
125
|
+
|
|
126
|
+
--color-yellow-50: #fffbf0;
|
|
127
|
+
--color-yellow-100: #fff5d6;
|
|
128
|
+
--color-yellow-200: #ffe89e;
|
|
129
|
+
--color-yellow-300: #ffdc6b;
|
|
130
|
+
--color-yellow-400: #ffcf33;
|
|
131
|
+
--color-yellow-500: #ffc400;
|
|
132
|
+
--color-yellow-600: #d6a000;
|
|
133
|
+
--color-yellow-700: #ad7f00;
|
|
134
|
+
--color-yellow-800: #855f00;
|
|
135
|
+
--color-yellow-900: #5c4000;
|
|
136
|
+
--color-yellow-950: #473100;
|
|
137
|
+
--color-yellow-975: #1a0f00;
|
|
138
|
+
|
|
139
|
+
--color-neutral-0: #ffffff;
|
|
140
|
+
--color-neutral-25: #fafafa;
|
|
141
|
+
--color-neutral-50: #f1f2f3;
|
|
142
|
+
--color-neutral-100: #e1e3e5;
|
|
143
|
+
--color-neutral-200: #c5c9ce;
|
|
144
|
+
--color-neutral-300: #a6adb4;
|
|
145
|
+
--color-neutral-400: #88909b;
|
|
146
|
+
/* The five in-between steps -- 450, 850, 925 here, and the two 975s
|
|
147
|
+
above -- exist for a dark theme, and nothing in light reads them.
|
|
148
|
+
The dark mode study (Foundations/Theming/Dark mode) found the ramps
|
|
149
|
+
too coarse at the dark end: container and subtle had to share
|
|
150
|
+
neutral-900 (finding 2), no step kept text-subtle both quieter than
|
|
151
|
+
muted and over 4.5:1 (finding 3), and green-950 and yellow-950 sat
|
|
152
|
+
1.5:1 off the dark page where every other tint sits near 1.1
|
|
153
|
+
(finding 5). Each is interpolated in OKLCH between its two
|
|
154
|
+
neighbours to the ratio the derivation asks for: 450 is 4.75:1 on
|
|
155
|
+
a dark card (4.93 on the dark page), midway between 500 and 400 at
|
|
156
|
+
1.22:1 from each -- subtle text sits on a page or a card, so it is
|
|
157
|
+
measured on the card (decision 17); 925 and 850 are 1.04 and 1.12
|
|
158
|
+
off it, the light container and subtle steps; the 975s are 1.04
|
|
159
|
+
and 1.03, the light tints. Measured against neutral-950, the dark
|
|
160
|
+
page, in src/tokens/dark-derivation.js. */
|
|
161
|
+
--color-neutral-450: #78818c;
|
|
162
|
+
/* #6a737e, moved one step from #6c7580. neutral-500 is
|
|
163
|
+
--color-text-subtle, and at #6c7580 subtle text on a card
|
|
164
|
+
(--color-surface-container, neutral-25) measured 4.48:1 -- under
|
|
165
|
+
4.5 on the ground most subtle text sits on. #6a737e gives 4.61 on a
|
|
166
|
+
card and 4.81 on the page, and stays a clear step above
|
|
167
|
+
neutral-600 (1.37:1 apart, the gap was 1.39). It does not clear
|
|
168
|
+
subtle on surface-subtle or the status tints (4.29 to 4.46):
|
|
169
|
+
that needs a step this ramp does not have, and is its own
|
|
170
|
+
decision. */
|
|
171
|
+
--color-neutral-500: #6a737e;
|
|
172
|
+
--color-neutral-600: #565e66;
|
|
173
|
+
--color-neutral-700: #41474d;
|
|
174
|
+
--color-neutral-800: #2c3035;
|
|
175
|
+
--color-neutral-850: #181b1d;
|
|
176
|
+
--color-neutral-900: #151719;
|
|
177
|
+
--color-neutral-925: #111214;
|
|
178
|
+
--color-neutral-950: #0c0d0e;
|
|
179
|
+
--color-neutral-1000: #000000;
|
|
180
|
+
|
|
181
|
+
/* ================================
|
|
182
|
+
CORE BORDER TOKENS
|
|
183
|
+
================================ */
|
|
184
|
+
--border-width-0: 0;
|
|
185
|
+
--border-width-1: 1px;
|
|
186
|
+
--border-width-2: 2px;
|
|
187
|
+
--border-width-3: 3px;
|
|
188
|
+
--border-width-4: 4px;
|
|
189
|
+
--border-width-8: 8px;
|
|
190
|
+
|
|
191
|
+
--radius-none: 0;
|
|
192
|
+
--radius-sm: 0.25rem; /* 4px */
|
|
193
|
+
--radius-md: 0.375rem; /* 6px */
|
|
194
|
+
--radius-lg: 0.5rem; /* 8px */
|
|
195
|
+
--radius-xl: 0.75rem; /* 12px */
|
|
196
|
+
--radius-2xl: 1rem; /* 16px */
|
|
197
|
+
--radius-3xl: 1.5rem; /* 24px */
|
|
198
|
+
--radius-full: 9999px;
|
|
199
|
+
|
|
200
|
+
/* ================================
|
|
201
|
+
CORE DIMENSION TOKENS
|
|
202
|
+
================================ */
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
--dimension-4: 4px;
|
|
206
|
+
--dimension-8: 8px;
|
|
207
|
+
--dimension-12: 12px;
|
|
208
|
+
--dimension-16: 16px;
|
|
209
|
+
--dimension-20: 20px;
|
|
210
|
+
--dimension-24: 24px;
|
|
211
|
+
--dimension-32: 32px;
|
|
212
|
+
--dimension-36: 36px;
|
|
213
|
+
--dimension-40: 40px;
|
|
214
|
+
--dimension-44: 44px;
|
|
215
|
+
--dimension-48: 48px;
|
|
216
|
+
--dimension-56: 56px;
|
|
217
|
+
--dimension-64: 64px;
|
|
218
|
+
|
|
219
|
+
/* ================================
|
|
220
|
+
CORE TRANSITION TOKENS
|
|
221
|
+
================================ */
|
|
222
|
+
|
|
223
|
+
--transition-duration-fast: 150ms;
|
|
224
|
+
--transition-duration-normal: 200ms;
|
|
225
|
+
--transition-duration-slow: 300ms;
|
|
226
|
+
--transition-duration-slower: 500ms;
|
|
227
|
+
|
|
228
|
+
--transition-easing-linear: linear;
|
|
229
|
+
--transition-easing-smooth: ease-in-out;
|
|
230
|
+
/* The CSS default curve. It was missing, and its absence was the single
|
|
231
|
+
reason eleven component transitions could not be expressed in tokens:
|
|
232
|
+
ease is not ease-in-out — it front-loads, and swapping one for the
|
|
233
|
+
other is a visible change. Named after the keyword, as linear,
|
|
234
|
+
ease-in and ease-out beside it are; smooth is the outlier that
|
|
235
|
+
aliases a keyword rather than naming it. */
|
|
236
|
+
--transition-easing-ease: ease;
|
|
237
|
+
--transition-easing-ease-in: ease-in;
|
|
238
|
+
--transition-easing-ease-out: ease-out;
|
|
239
|
+
--transition-easing-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55);
|
|
240
|
+
|
|
241
|
+
/* ================================
|
|
242
|
+
CORE SHADOW TOKENS
|
|
243
|
+
================================ */
|
|
244
|
+
|
|
245
|
+
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
|
246
|
+
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
|
247
|
+
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1),
|
|
248
|
+
0 4px 6px -4px rgb(0 0 0 / 0.1);
|
|
249
|
+
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1),
|
|
250
|
+
0 8px 10px -6px rgb(0 0 0 / 0.1);
|
|
251
|
+
--shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / 0.25);
|
|
252
|
+
--shadow-inner: inset 0 2px 4px 0 rgb(0 0 0 / 0.05);
|
|
253
|
+
|
|
254
|
+
/* Focus Shadows - Box Shadow Version */
|
|
255
|
+
--shadow-focus-outline-blue: 0 0 0 3px rgba(6, 109, 255, 0.15);
|
|
256
|
+
--shadow-focus-outline-red: 0 0 0 3px rgba(239, 68, 68, 0.15);
|
|
257
|
+
--shadow-focus-outline-green: 0 0 0 3px rgba(34, 197, 94, 0.15);
|
|
258
|
+
|
|
259
|
+
/* Focus Outlines - Two-Color System for Universal Visibility */
|
|
260
|
+
--focus-outline-primary: 0 0 0 2px var(--color-neutral-0),
|
|
261
|
+
0 0 0 4px var(--color-blue-500);
|
|
262
|
+
--focus-outline-secondary: 0 0 0 2px var(--color-neutral-0),
|
|
263
|
+
0 0 0 4px var(--color-neutral-600);
|
|
264
|
+
--focus-outline-error: 0 0 0 2px var(--color-neutral-0),
|
|
265
|
+
0 0 0 4px var(--color-red-500);
|
|
266
|
+
--focus-outline-success: 0 0 0 2px var(--color-neutral-0),
|
|
267
|
+
0 0 0 4px var(--color-green-500);
|
|
268
|
+
|
|
269
|
+
/* The four above put the WHITE band against the control, which is what
|
|
270
|
+
keeps them visible on a coloured hero. That fails on a control which
|
|
271
|
+
is itself white: bd-button-link variant="white" measured 1.00:1 for
|
|
272
|
+
the inner band against its own fill and 2.38:1 for the blue band
|
|
273
|
+
against a blue hero, so neither band reached the 3:1 WCAG 2.4.11
|
|
274
|
+
asks of a focus indicator. This one inverts the pair -- dark band
|
|
275
|
+
against the control, white band against the ground -- so the inner
|
|
276
|
+
band carries the contrast whatever the control is sitting on. */
|
|
277
|
+
--focus-outline-inverse: 0 0 0 2px var(--color-neutral-900),
|
|
278
|
+
0 0 0 4px var(--color-neutral-0);
|
|
279
|
+
|
|
280
|
+
/* Traditional Outline Values for Fallback */
|
|
281
|
+
--focus-outline-traditional: 2px solid var(--color-blue-500);
|
|
282
|
+
--focus-outline-offset: 2px;
|
|
283
|
+
|
|
284
|
+
/* The ring is a box-shadow, so it already follows the radius of the
|
|
285
|
+
element it is on. This is the default for elements that have no
|
|
286
|
+
radius of their own — a link, a tab, an accordion header — so the
|
|
287
|
+
ring is not a hard rectangle. An element with its own radius should
|
|
288
|
+
set nothing and let the ring follow its shape. */
|
|
289
|
+
--focus-outline-radius: var(--radius-sm);
|
|
290
|
+
|
|
291
|
+
/* ================================
|
|
292
|
+
SEMANTIC ROLE - SELECTED INDICATOR
|
|
293
|
+
================================
|
|
294
|
+
What marks the current item in a set. Two components already drew it
|
|
295
|
+
— Components/Tab List and the anchor nav — and they drifted apart on
|
|
296
|
+
easing while both used valid tokens. The role is named here so there
|
|
297
|
+
is one answer, not two spellings.
|
|
298
|
+
|
|
299
|
+
THE COLOUR IS NOT NAMED FOR A SHAPE, and that is the whole point of
|
|
300
|
+
the split below. It was --indicator-underline-color, which described
|
|
301
|
+
the underline three components happen to draw rather than the job the
|
|
302
|
+
value does. awards-flex marks its current slide with a DOT: same job,
|
|
303
|
+
same blue-500, and it could not adopt the token because a dot is not
|
|
304
|
+
an underline, so it reached for the primitive instead. Vocabulary
|
|
305
|
+
question E1 found that — see plans/reports/phase-2-vocab-e-has-role-pass.md.
|
|
306
|
+
|
|
307
|
+
Renamed with no back-compat alias, following the same convention as
|
|
308
|
+
--typography-label-xsmall becoming --typography-body-xsmall: rename
|
|
309
|
+
cleanly and say why here.
|
|
310
|
+
|
|
311
|
+
The geometry stays underline-specific, because it genuinely is — a
|
|
312
|
+
3px height and a width transition describe a rule sliding under a
|
|
313
|
+
tab, and a dot scales instead. A fourth consumer needing dot
|
|
314
|
+
geometry should name it for the dot, not borrow these. */
|
|
315
|
+
--indicator-color: var(--color-blue-500);
|
|
316
|
+
--indicator-underline-height: var(--border-width-3);
|
|
317
|
+
--indicator-underline-duration: var(--transition-duration-slow);
|
|
318
|
+
--indicator-underline-easing: var(--transition-easing-smooth);
|
|
319
|
+
|
|
320
|
+
/* ================================
|
|
321
|
+
SEMANTIC ROLE - CARD SHAPE
|
|
322
|
+
================================
|
|
323
|
+
The corner and the inset that make a card a card here. Eleven
|
|
324
|
+
card-shaped objects agree on both -- the Card box, CardFeatures,
|
|
325
|
+
LightCarousel, Bento, the Awards feature card, the TrustPanel card,
|
|
326
|
+
the CompareSection card, the Carousel item, the Comparison Panel
|
|
327
|
+
column and both Pricing cards -- and they only agree because the two
|
|
328
|
+
that did not were brought in one at a time.
|
|
329
|
+
|
|
330
|
+
This role is named now and was deliberately not named before, and
|
|
331
|
+
the difference is evidence rather than appetite. CLAUDE.md said
|
|
332
|
+
there was no semantic radius scale because "the components do not
|
|
333
|
+
agree closely enough for a shared role to be honest", which was true
|
|
334
|
+
when it was written: the compare card sat at --radius-3xl and the
|
|
335
|
+
carousel item at --radius-3xl with a 2em inset. Both have since been
|
|
336
|
+
measured, argued and moved. A role declared then would have imposed
|
|
337
|
+
a consensus; declared now it records one.
|
|
338
|
+
|
|
339
|
+
It is a role, not a scale. There is still no --card-* family and no
|
|
340
|
+
semantic step between radii -- naming the job is the whole point,
|
|
341
|
+
and the same reasoning is why --panel-radius is NOT here: the eight
|
|
342
|
+
--radius-xl consumers are a code block, a bar track, a table
|
|
343
|
+
container, a discount pill, two public image variants, a modal and a
|
|
344
|
+
terminal. That is not a family, and calling it one would be the
|
|
345
|
+
mistake this comment is describing.
|
|
346
|
+
|
|
347
|
+
scripts/card-shapes.json lists the eleven and lint:tokens checks it
|
|
348
|
+
both ways, so a card that stops using the role and a registry entry
|
|
349
|
+
that stops matching are both findings. */
|
|
350
|
+
--card-radius: var(--radius-2xl);
|
|
351
|
+
--card-padding: var(--spacing-32);
|
|
352
|
+
|
|
353
|
+
/* The inset a card takes when the viewport is too narrow to afford the
|
|
354
|
+
full one. Four cards reached for this independently before it had a
|
|
355
|
+
name -- Bento below sm, the Comparison Panel and Trust Panel below
|
|
356
|
+
md, and LightCarousel with an em literal -- and three of the four
|
|
357
|
+
picked exactly 24. That is the agreement that makes it a role rather
|
|
358
|
+
than four local decisions.
|
|
359
|
+
|
|
360
|
+
Two steps, not a scale. A card is either affording its inset or it
|
|
361
|
+
is not; there is no third size, and a component that wants one is
|
|
362
|
+
asking a design question rather than a token question. */
|
|
363
|
+
--card-padding-compact: var(--spacing-24);
|
|
364
|
+
|
|
365
|
+
/* ================================
|
|
366
|
+
SEMANTIC ROLES - COLOUR
|
|
367
|
+
================================
|
|
368
|
+
The tier the architecture always described and the components never
|
|
369
|
+
had. Measured before this landed: 71.8% of the colour references in
|
|
370
|
+
the atom layer pointed straight at a palette step — 38 distinct
|
|
371
|
+
primitives across 233 references, where the roles underneath them
|
|
372
|
+
number about thirty. That gap is why four text atoms ended up with
|
|
373
|
+
four different inks, and why two components disagreed about which
|
|
374
|
+
green means "success".
|
|
375
|
+
|
|
376
|
+
None of these are new decisions. Every value is the step something
|
|
377
|
+
already uses, and the text roles are the ones COLOR_ROLES in
|
|
378
|
+
src/components/shared/token-scales.js had already chosen as clearing
|
|
379
|
+
4.5:1 on white — that map should now resolve through these rather
|
|
380
|
+
than reaching past them into the palette.
|
|
381
|
+
|
|
382
|
+
Reach for the role, not the step. The palette stays available for
|
|
383
|
+
what no role covers yet; when that happens, add the role.
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
NAME COLLISION WITH src/blog. The blog sub-system already declares
|
|
388
|
+
seven of these names with different values:
|
|
389
|
+
|
|
390
|
+
--color-text-secondary here neutral-700 blog neutral-600
|
|
391
|
+
--color-text-muted here neutral-600 blog neutral-500
|
|
392
|
+
--color-surface-brand here blue-500 blog blue-50 (!)
|
|
393
|
+
--color-surface-inverse here neutral-900 blog neutral-950
|
|
394
|
+
--color-border-default here neutral-400 blog neutral-300
|
|
395
|
+
--color-border-subtle here neutral-200 blog neutral-100
|
|
396
|
+
--color-border-strong here neutral-900 blog neutral-600
|
|
397
|
+
|
|
398
|
+
This is safe today and must not be assumed safe. The blog applies
|
|
399
|
+
its tokens on :host inside each blog component, so inside a blog
|
|
400
|
+
shadow tree the blog value wins, and outside it never applies.
|
|
401
|
+
Nothing in this system renders inside that tree.
|
|
402
|
+
|
|
403
|
+
It stops being safe if a page ever loads src/blog/tokens.css
|
|
404
|
+
globally alongside this file. That file is an unlayered :root block,
|
|
405
|
+
and unlayered CSS beats a cascade layer, so it would win — silently
|
|
406
|
+
turning --color-surface-brand from a saturated fill into a pale
|
|
407
|
+
tint under any component that had adopted it.
|
|
408
|
+
|
|
409
|
+
The two files share 616 names and disagree on 82 of them; all 58
|
|
410
|
+
shared palette primitives are identical, so the fork is entirely at
|
|
411
|
+
this tier and above. Reconciling it is its own piece of work. Until
|
|
412
|
+
it happens, do not load both globally. */
|
|
413
|
+
|
|
414
|
+
/* Text. -primary is the default ink for anything that reads as body
|
|
415
|
+
or heading copy. -brand is blue-600 rather than blue-500 on purpose:
|
|
416
|
+
blue-500 is 4.53:1 on pure white and fails on any tint. */
|
|
417
|
+
--color-text-primary: var(--color-neutral-900);
|
|
418
|
+
--color-text-secondary: var(--color-neutral-700);
|
|
419
|
+
--color-text-muted: var(--color-neutral-600);
|
|
420
|
+
/* Subtle sits on the page or a card, and nowhere else: on a band
|
|
421
|
+
(surface-subtle, surface-muted) or a status tint, step up to
|
|
422
|
+
-muted. No value can be both quieter than muted and 4.5:1 on every
|
|
423
|
+
ground -- on surface-muted it would have to be muted -- so the rule
|
|
424
|
+
is where it goes, not how dark it is. Dark mode decision 17. */
|
|
425
|
+
--color-text-subtle: var(--color-neutral-500);
|
|
426
|
+
--color-text-disabled: var(--color-neutral-400);
|
|
427
|
+
--color-text-inverse: var(--color-neutral-0);
|
|
428
|
+
/* Subordinate text on an inverse surface. --color-text-inverse is the
|
|
429
|
+
high-emphasis step there; this is the one below it, and until now the
|
|
430
|
+
system had no such step at all -- the light-side -secondary, -muted and
|
|
431
|
+
-subtle roles invert to 1.91, 2.73 and 3.85 against
|
|
432
|
+
--color-surface-inverse and cannot be used.
|
|
433
|
+
|
|
434
|
+
Two components had already invented it independently and spelled it
|
|
435
|
+
differently: bd-terminal-message with rgba(255,255,255,0.5) and
|
|
436
|
+
bd-process-steps with --color-neutral-300 twice. neutral-300 is the
|
|
437
|
+
value here because it is the portable one. Measured on the three
|
|
438
|
+
inverse grounds in use -- neutral-900, neutral-800 and the #0b1626 the
|
|
439
|
+
process-steps gradient ends on -- it reads 7.92, 5.85 and 8.00, while
|
|
440
|
+
the white-at-half-alpha spelling reads 5.27, 3.89 and 5.32 and only
|
|
441
|
+
clears 4.5 because the terminal's ground happens to be the darkest of
|
|
442
|
+
the three.
|
|
443
|
+
|
|
444
|
+
There is deliberately no -secondary-inverse: bd-cta-banner has a third
|
|
445
|
+
tier at white 0.85 and it is one consumer, which is not a
|
|
446
|
+
responsibility. An earlier draft of this note also called it a
|
|
447
|
+
contrast failure, from a worst-case calculation against the lightest
|
|
448
|
+
stop in its gradient. Sampling the pixels actually behind the text
|
|
449
|
+
disproved that -- the radial highlight sits at 78% -10% and is mostly
|
|
450
|
+
outside the banner, so the three tiers measure 4.60, 4.57 and 4.46 at
|
|
451
|
+
their worst pixel rather than the 3.35, 2.84 and 2.13 the arithmetic
|
|
452
|
+
predicted. The tier is fine; it is still not a role. */
|
|
453
|
+
--color-text-muted-inverse: var(--color-neutral-300);
|
|
454
|
+
/* Ink on --color-surface-media, fixed with it: a part that does not
|
|
455
|
+
switch needs ink that does not switch either (the white button
|
|
456
|
+
preset, dark mode finding 8). text-inverse and text-muted-inverse
|
|
457
|
+
flip in a dark theme and would put dark ink on the dark frame --
|
|
458
|
+
a video play icon at 3.13:1, a terminal's quieter lines at 1.91. */
|
|
459
|
+
--color-text-on-media: var(--color-neutral-0);
|
|
460
|
+
--color-text-on-media-muted: var(--color-neutral-300);
|
|
461
|
+
--color-text-brand: var(--color-blue-600);
|
|
462
|
+
/* Brand text, hovered: a link or a citation reference under the
|
|
463
|
+
pointer. Before this role existed, the hover read
|
|
464
|
+
--color-action-primary-active -- a pressed button fill used as ink.
|
|
465
|
+
The value is the same blue-700, so nothing moves in this theme; the
|
|
466
|
+
difference is that a fill and a text colour answer different
|
|
467
|
+
questions, and a dark theme has to answer them differently. Measured
|
|
468
|
+
in the Figma Dark mode study: the fill stays put on a dark page and
|
|
469
|
+
the link it borrowed falls to 2.27:1. */
|
|
470
|
+
--color-text-brand-hover: var(--color-blue-700);
|
|
471
|
+
--color-text-success: var(--color-green-800);
|
|
472
|
+
--color-text-warning: var(--color-yellow-800);
|
|
473
|
+
--color-text-error: var(--color-red-700);
|
|
474
|
+
|
|
475
|
+
/* Surfaces. The feedback four are the tints a message sits on, each
|
|
476
|
+
measured against the matching --color-text-* step above: success
|
|
477
|
+
6.42, warning 5.59, error 6.83, info 5.72.
|
|
478
|
+
|
|
479
|
+
-brand is the one to watch. --color-text-inverse on it measures
|
|
480
|
+
4.53:1 — it passes, with no headroom at all, and it is the same
|
|
481
|
+
blue-500 the contrast note warns about elsewhere. White on brand is
|
|
482
|
+
fine for a button label; do not build a tinted variant on top of it
|
|
483
|
+
without re-measuring. */
|
|
484
|
+
--color-surface-default: var(--color-neutral-0);
|
|
485
|
+
/* The ground a self-contained content object sits on: one step off the
|
|
486
|
+
page, so a card, tile or panel reads as its own object without
|
|
487
|
+
needing a border or a shadow to say so. Twelve components were
|
|
488
|
+
reaching past the surface family for this, eight of them declaring
|
|
489
|
+
the same local alias, because the role did not exist.
|
|
490
|
+
|
|
491
|
+
Container is not subtle. Subtle groups things that already belong
|
|
492
|
+
together and is meant to recede; container is the default ground of
|
|
493
|
+
an object that stands on its own. They also differ visibly -- the
|
|
494
|
+
step between them is the difference between an object on the page
|
|
495
|
+
and a wash behind a group -- so they are not interchangeable.
|
|
496
|
+
|
|
497
|
+
The name means a visual container for content. It has nothing to do
|
|
498
|
+
with CSS container queries. */
|
|
499
|
+
--color-surface-container: var(--color-neutral-25);
|
|
500
|
+
--color-surface-subtle: var(--color-neutral-50);
|
|
501
|
+
--color-surface-muted: var(--color-neutral-100);
|
|
502
|
+
--color-surface-inverse: var(--color-neutral-900);
|
|
503
|
+
/* The frame around media: a video letterbox, a terminal panel. Dark in
|
|
504
|
+
every theme, because what it frames is dark -- which is why it is
|
|
505
|
+
not --color-surface-inverse, the polarity flip, that both used to
|
|
506
|
+
read. Inverse turns light in a dark theme; a letterbox must not,
|
|
507
|
+
and the terminal's own palette (blue-400, the traffic-light green)
|
|
508
|
+
is only legible on a dark ground. Dark mode decision 15. */
|
|
509
|
+
--color-surface-media: var(--color-neutral-900);
|
|
510
|
+
--color-surface-brand: var(--color-blue-500);
|
|
511
|
+
--color-surface-disabled: var(--color-neutral-100);
|
|
512
|
+
/* The ground of a control while it is held down, one step below
|
|
513
|
+
-muted (its hover). bd-back read neutral-200 for this and said in a
|
|
514
|
+
no-token comment that the surface roles stopped at -muted; reading
|
|
515
|
+
the primitive meant it could not follow a theme, and on a dark page
|
|
516
|
+
it measured 1.48:1 under a label that did (dark mode finding 14). */
|
|
517
|
+
--color-surface-pressed: var(--color-neutral-200);
|
|
518
|
+
--color-surface-success: var(--color-green-50);
|
|
519
|
+
--color-surface-warning: var(--color-yellow-50);
|
|
520
|
+
--color-surface-error: var(--color-red-50);
|
|
521
|
+
--color-surface-info: var(--color-blue-50);
|
|
522
|
+
|
|
523
|
+
/* Borders, measured on --color-surface-default. Only the two that
|
|
524
|
+
bound a live control clear the 3:1 WCAG 1.4.11 asks of a UI
|
|
525
|
+
component: -default at 3.23 and -brand at 4.53.
|
|
526
|
+
|
|
527
|
+
-subtle (1.66) and -disabled (2.27) sit below it on purpose.
|
|
528
|
+
-subtle is a decorative hairline between things that already belong
|
|
529
|
+
together, not the edge of anything actionable, and disabled controls
|
|
530
|
+
are exempt under 1.4.3. Do not reach for -subtle to outline a
|
|
531
|
+
control. */
|
|
532
|
+
--color-border-subtle: var(--color-neutral-200);
|
|
533
|
+
--color-border-default: var(--color-neutral-400);
|
|
534
|
+
--color-border-strong: var(--color-neutral-900);
|
|
535
|
+
--color-border-brand: var(--color-blue-500);
|
|
536
|
+
--color-border-disabled: var(--color-neutral-300);
|
|
537
|
+
|
|
538
|
+
/* The boundary of a self-contained object -- a card, a panel, a
|
|
539
|
+
navigation band -- drawn only so the object is perceptible, never so
|
|
540
|
+
it looks operable. It is the border counterpart of
|
|
541
|
+
--color-surface-container, and the two answer the same question from
|
|
542
|
+
opposite sides: is this its own thing.
|
|
543
|
+
|
|
544
|
+
It exists because eight components needed it and none could ask for
|
|
545
|
+
it. Seven reached past the roles to --color-neutral-100 directly and
|
|
546
|
+
one more declared a private --border-card-grey alias in seven files
|
|
547
|
+
to say --color-neutral-50. Measured on --color-surface-default it is
|
|
548
|
+
1.29:1, and on --color-surface-container 1.23:1 -- deliberately below
|
|
549
|
+
-subtle's 1.66, because -subtle is already spoken for as the hairline
|
|
550
|
+
between things that belong together, and a long way below the 3:1
|
|
551
|
+
WCAG 1.4.11 asks of anything actionable. That is the point: an object
|
|
552
|
+
boundary is not a control edge, and must not read as one.
|
|
553
|
+
|
|
554
|
+
-inverse is the same responsibility on an inverse surface, the way
|
|
555
|
+
--color-text-inverse and --color-surface-inverse are, and not a
|
|
556
|
+
second role. It is spelled as a proportion of --color-neutral-0
|
|
557
|
+
rather than a raw rgba for the same reason
|
|
558
|
+
--button-outline-white-border-default is: the value stays traceable
|
|
559
|
+
to a token when the palette moves. Over --color-surface-inverse it
|
|
560
|
+
measures 1.42:1, which puts it in the same perceptual band as the
|
|
561
|
+
light value rather than at the 10.8:1 --color-border-subtle would
|
|
562
|
+
give there.
|
|
563
|
+
|
|
564
|
+
This role says what a low-emphasis boundary looks like. It does not
|
|
565
|
+
say whether a component should have one -- that stays a component
|
|
566
|
+
decision, and the evidence says the components genuinely disagree. */
|
|
567
|
+
--color-border-container: var(--color-neutral-100);
|
|
568
|
+
--color-border-container-inverse: color-mix(in srgb, var(--color-neutral-0) 12%, transparent);
|
|
569
|
+
|
|
570
|
+
/* Action. The interactive ramp, one step down the palette per state.
|
|
571
|
+
accent is this system's conversion colour — Buy now and the like —
|
|
572
|
+
and is not a danger signal; see the bd-button story notes. */
|
|
573
|
+
--color-action-primary: var(--color-blue-500);
|
|
574
|
+
--color-action-primary-hover: var(--color-blue-600);
|
|
575
|
+
--color-action-primary-active: var(--color-blue-700);
|
|
576
|
+
--color-action-accent: var(--color-red-600);
|
|
577
|
+
--color-action-accent-hover: var(--color-red-700);
|
|
578
|
+
--color-action-accent-active: var(--color-red-800);
|
|
579
|
+
/* The neutral action fill: the secondary button, and the ghost
|
|
580
|
+
button's pressed state. Both read neutral-950 / 800 / 1000 straight
|
|
581
|
+
from the palette, which no theme can reach -- and the dark page is
|
|
582
|
+
neutral-950 too, so in a dark theme the fill would vanish into it
|
|
583
|
+
(dark mode finding 8). A role gives the fill a value of its own in
|
|
584
|
+
each theme. */
|
|
585
|
+
--color-action-secondary: var(--color-neutral-950);
|
|
586
|
+
--color-action-secondary-hover: var(--color-neutral-800);
|
|
587
|
+
--color-action-secondary-active: var(--color-neutral-1000);
|
|
588
|
+
/* Ink on an action fill: a button label, a checkmark, a radio dot, a
|
|
589
|
+
switch thumb. Before this role existed the buttons read
|
|
590
|
+
--color-text-inverse ("text on an inverse surface") and the controls
|
|
591
|
+
read --color-surface-default ("the page"). Both resolve to white in
|
|
592
|
+
this theme, which is why the borrowing never showed -- and both must
|
|
593
|
+
flip to near-black in a dark one, which would turn every label and
|
|
594
|
+
mark dark on its blue or red fill. White clears every action fill:
|
|
595
|
+
4.53 to 10.51:1. Measured in the Figma Dark mode study. */
|
|
596
|
+
--color-action-on-fill: var(--color-neutral-0);
|
|
597
|
+
|
|
598
|
+
/* ================================
|
|
599
|
+
SEMANTIC ROLES - STACKING
|
|
600
|
+
================================
|
|
601
|
+
Thirty z-index declarations across eight values that were never
|
|
602
|
+
chosen relative to one another: -1, 1, 2, 10, 200, 1000, 1001 and
|
|
603
|
+
9999. Both bd-modal and the carousel sit on 9999, so there is no
|
|
604
|
+
answer to which of the two wins — that is what an unscaled ladder
|
|
605
|
+
costs.
|
|
606
|
+
|
|
607
|
+
The rungs are far apart on purpose, so a component can take a rung
|
|
608
|
+
and still stack its own internals inside it with a calc. A tooltip
|
|
609
|
+
opened from inside a dialog has to clear the dialog, which is why
|
|
610
|
+
it is the top rung rather than the first. */
|
|
611
|
+
--z-below: -1;
|
|
612
|
+
--z-base: 1;
|
|
613
|
+
--z-raised: 2;
|
|
614
|
+
--z-sticky: 200;
|
|
615
|
+
--z-overlay: 1000;
|
|
616
|
+
--z-modal: 1100;
|
|
617
|
+
--z-tooltip: 1200;
|
|
618
|
+
|
|
619
|
+
/* ================================
|
|
620
|
+
SEMANTIC ROLES - OPACITY
|
|
621
|
+
================================
|
|
622
|
+
One role, because one role is what the evidence supports. The dim
|
|
623
|
+
end of a reduced-motion pulse is spelled three times in the atom
|
|
624
|
+
layer — bd-button and bd-spinner at 0.4, bd-skeleton at 0.45 — and
|
|
625
|
+
is the same intent each time: a mark that cannot spin should still
|
|
626
|
+
read as busy.
|
|
627
|
+
|
|
628
|
+
Disabled is deliberately absent. This system expresses disabled with
|
|
629
|
+
the neutral ramp rather than by dimming, and the one token that said
|
|
630
|
+
otherwise (--button-shared-disabled-opacity: 0.6) is unused. */
|
|
631
|
+
--opacity-pulse: 0.4;
|
|
632
|
+
|
|
633
|
+
/* ================================
|
|
634
|
+
SEMANTIC ROLE - STATUS TONES
|
|
635
|
+
================================
|
|
636
|
+
bd-badge, bd-tag and bd-alert all say the same six things and each
|
|
637
|
+
spelled them out for itself. The text colours already matched across
|
|
638
|
+
badge and tag — the tag story says so — but by coincidence rather
|
|
639
|
+
than construction, and the one place they had drifted proves the
|
|
640
|
+
point: alert drew its success rule in green-600 where badge's
|
|
641
|
+
success dot used green-700.
|
|
642
|
+
|
|
643
|
+
Seven roles, because the three components need different weights of
|
|
644
|
+
the same tone:
|
|
645
|
+
|
|
646
|
+
-text ink on a tinted chip badge shade, tag
|
|
647
|
+
-surface the light tint tag, alert
|
|
648
|
+
-surface-strong the heavier tint badge shade
|
|
649
|
+
-border the hairline tag
|
|
650
|
+
-accent the saturated step badge dot, alert rule
|
|
651
|
+
-fill / -on-fill a saturated chip and its ink badge fill
|
|
652
|
+
|
|
653
|
+
What is deliberately *not* unified: a tag carries a border and sits
|
|
654
|
+
on -surface, a badge has no border and sits on -surface-strong. That
|
|
655
|
+
difference is documented in the tag story — the lighter fill is what
|
|
656
|
+
lets the tag's border read — so it is expressed as two roles rather
|
|
657
|
+
than flattened into one.
|
|
658
|
+
|
|
659
|
+
Brand has no -surface-strong. It would be blue-100, which is
|
|
660
|
+
info's, so a brand badge on it could not be told from an info badge.
|
|
661
|
+
Brand's badge sits on -surface like its tag, and that one collision
|
|
662
|
+
is the whole exception. */
|
|
663
|
+
|
|
664
|
+
--status-neutral-text: var(--color-neutral-700);
|
|
665
|
+
--status-neutral-surface: var(--color-neutral-50);
|
|
666
|
+
--status-neutral-surface-strong: var(--color-neutral-100);
|
|
667
|
+
--status-neutral-border: var(--color-neutral-200);
|
|
668
|
+
--status-neutral-accent: var(--color-neutral-700);
|
|
669
|
+
--status-neutral-fill: var(--color-neutral-900);
|
|
670
|
+
--status-neutral-on-fill: var(--color-neutral-0);
|
|
671
|
+
|
|
672
|
+
--status-brand-text: var(--color-blue-600);
|
|
673
|
+
--status-brand-surface: var(--color-blue-50);
|
|
674
|
+
--status-brand-border: var(--color-blue-200);
|
|
675
|
+
--status-brand-accent: var(--color-blue-600);
|
|
676
|
+
--status-brand-fill: var(--color-blue-500);
|
|
677
|
+
--status-brand-on-fill: var(--color-neutral-0);
|
|
678
|
+
|
|
679
|
+
--status-info-text: var(--color-blue-600);
|
|
680
|
+
--status-info-surface: var(--color-blue-50);
|
|
681
|
+
--status-info-surface-strong: var(--color-blue-100);
|
|
682
|
+
--status-info-border: var(--color-blue-200);
|
|
683
|
+
--status-info-accent: var(--color-blue-500);
|
|
684
|
+
--status-info-fill: var(--color-blue-500);
|
|
685
|
+
--status-info-on-fill: var(--color-neutral-0);
|
|
686
|
+
|
|
687
|
+
--status-success-text: var(--color-green-800);
|
|
688
|
+
--status-success-surface: var(--color-green-50);
|
|
689
|
+
--status-success-surface-strong: var(--color-green-100);
|
|
690
|
+
--status-success-border: var(--color-green-200);
|
|
691
|
+
--status-success-accent: var(--color-green-700);
|
|
692
|
+
--status-success-fill: var(--color-green-700);
|
|
693
|
+
--status-success-on-fill: var(--color-neutral-0);
|
|
694
|
+
|
|
695
|
+
--status-warning-text: var(--color-yellow-800);
|
|
696
|
+
--status-warning-surface: var(--color-yellow-50);
|
|
697
|
+
--status-warning-surface-strong: var(--color-yellow-100);
|
|
698
|
+
--status-warning-border: var(--color-yellow-200);
|
|
699
|
+
--status-warning-accent: var(--color-yellow-700);
|
|
700
|
+
--status-warning-fill: var(--color-yellow-500);
|
|
701
|
+
--status-warning-on-fill: var(--color-neutral-900);
|
|
702
|
+
|
|
703
|
+
--status-error-text: var(--color-red-700);
|
|
704
|
+
--status-error-surface: var(--color-red-50);
|
|
705
|
+
--status-error-surface-strong: var(--color-red-100);
|
|
706
|
+
--status-error-border: var(--color-red-200);
|
|
707
|
+
--status-error-accent: var(--color-red-600);
|
|
708
|
+
--status-error-fill: var(--color-red-600);
|
|
709
|
+
--status-error-on-fill: var(--color-neutral-0);
|
|
710
|
+
|
|
711
|
+
/* ================================
|
|
712
|
+
COMPONENT TOKENS - TYPOGRAPHY
|
|
713
|
+
================================ */
|
|
714
|
+
|
|
715
|
+
|
|
716
|
+
/* ===============================================================
|
|
717
|
+
FLUID TYPE - the roles that cannot hold their size on a phone.
|
|
718
|
+
|
|
719
|
+
WHY. Measured in the Figma file (page "Type on mobile"), the
|
|
720
|
+
binding constraint on large type is not how many lines a sentence
|
|
721
|
+
takes, it is whether the longest UNBREAKABLE WORD fits the column.
|
|
722
|
+
The column is the viewport minus twice --grid-padding-*, so a 320px
|
|
723
|
+
phone gives type 288px -- 10% of the screen is gutter. Against that
|
|
724
|
+
column the ceiling for the worst realistic compound (Finnish
|
|
725
|
+
"Henkilollisyyssuoja", 9.07px of width per px of size) is 31px.
|
|
726
|
+
heading-h1 is 48. It overflowed at 375 as well as at 320, in German
|
|
727
|
+
and Finnish both.
|
|
728
|
+
|
|
729
|
+
WHY NOT A BREAKPOINT STEP. Tried first and abandoned, measured:
|
|
730
|
+
stepping h1 to 36 below sm still overflows at 320 (needs 327 of
|
|
731
|
+
288) and changes nothing at 576-767 where the ceiling is already 54.
|
|
732
|
+
The constraint moves continuously with the column, because the
|
|
733
|
+
column is a function of viewport width -- a step function
|
|
734
|
+
approximates a line with a staircase. clamp() states the line.
|
|
735
|
+
|
|
736
|
+
THE WINDOW IS 320 -> 992. The minimum is reached at 320 and the
|
|
737
|
+
maximum at 992, which is the lg breakpoint. Above lg NOTHING
|
|
738
|
+
changes from the sizes this system shipped with, so every desktop
|
|
739
|
+
layout that has been reviewed stays exactly as reviewed, and the
|
|
740
|
+
whole change is confined to the widths where the failures were
|
|
741
|
+
measured.
|
|
742
|
+
|
|
743
|
+
THE MIDDLE TERM CARRIES A rem, AND THAT IS NOT OPTIONAL.
|
|
744
|
+
clamp(2rem, 4vw, 3rem) is the spelling everyone reaches for and it
|
|
745
|
+
breaks text resize: a size depending only on viewport width ignores
|
|
746
|
+
the reader's own font-size setting, which is WCAG 1.4.4. With a rem
|
|
747
|
+
in the middle term the type still grows when the reader enlarges
|
|
748
|
+
it. This package already refuses the equivalent mistake twice --
|
|
749
|
+
line-height is always unitless, and --spacing-* is rem precisely so
|
|
750
|
+
boxes grow with the text.
|
|
751
|
+
|
|
752
|
+
THE TWO LITERALS PER ROLE ARE DERIVED, NOT CHOSEN. For a role
|
|
753
|
+
running from min m to max M across the window V1..V2:
|
|
754
|
+
|
|
755
|
+
slope = (M - m) / (V2 - V1) px of size per px of width
|
|
756
|
+
vw term = slope x 100
|
|
757
|
+
rem term = (m - slope x V1) / 16
|
|
758
|
+
|
|
759
|
+
With V1=320 and V2=992 that is (M-m)/6.72 vw and
|
|
760
|
+
(m - (M-m)/2.1) / 16 rem. Every pair below is that arithmetic and
|
|
761
|
+
nothing else; each line states its own m and M so it can be checked
|
|
762
|
+
without re-deriving. Changing the mobile ladder means changing the
|
|
763
|
+
-fontSizeMin token and re-running the two formulas.
|
|
764
|
+
|
|
765
|
+
THE MOBILE LADDER IS THE DESIGN DECISION HERE, and it is these six
|
|
766
|
+
numbers: 30 27 24 21 18 16 for h1 through h6. Its ratios are 1.11,
|
|
767
|
+
1.13, 1.14, 1.17, 1.13 -- near-even, against the desktop ladder's
|
|
768
|
+
irregular 1.33, 1.13, 1.33, 1.20, 1.11. A phone has less range to
|
|
769
|
+
spend (16 to the 31px ceiling, a factor of 1.94, where desktop has
|
|
770
|
+
18 to 48, a factor of 2.67), so the ladder has to compress, and
|
|
771
|
+
compressing it evenly is what keeps six levels distinguishable.
|
|
772
|
+
Measured: h1 at 30 needs 272px of a 288px column, so there is 16px
|
|
773
|
+
of margin for a word longer than any tested.
|
|
774
|
+
|
|
775
|
+
WHAT IS DELIBERATELY NOT FLUID.
|
|
776
|
+
- Every role at 24px and below except body-lead. Nothing that small
|
|
777
|
+
overflows, and the small end's own failure is measure, not
|
|
778
|
+
overflow -- see below.
|
|
779
|
+
- display-lg, display-xl, display-2xl, display-3xl (60 to 128px).
|
|
780
|
+
Above display-md the family has NO mobile identity
|
|
781
|
+
to give it: five roles would all have to squeeze between 30 and
|
|
782
|
+
the 31px ceiling. They are desktop-only, and a component that
|
|
783
|
+
needs one of them on a phone should reach for a heading role
|
|
784
|
+
instead. Recorded rather than papered over.
|
|
785
|
+
- body-regular at 16px. It runs 40 characters per line on a 288px
|
|
786
|
+
column, which the study first called "below the comfortable
|
|
787
|
+
45-75 band" -- and that band is a print and desktop yardstick.
|
|
788
|
+
Reaching 45 CPL on a 288px column needs 14.2px body text, and 50
|
|
789
|
+
CPL needs 12.8px; applying it to a phone trades the 16px
|
|
790
|
+
accessibility floor for a soft readability target. 40 characters
|
|
791
|
+
is what every phone does. body-lead is the one prose role that
|
|
792
|
+
does move, 20 -> 18, because at 20 it ran 32 characters -- five
|
|
793
|
+
or six words a line -- and an intro paragraph has no claim on
|
|
794
|
+
being the largest thing on a small screen.
|
|
795
|
+
=============================================================== */
|
|
796
|
+
|
|
797
|
+
/* Heading Tokens */
|
|
798
|
+
/* fluid: 30px at 320 -> 48px at 992. (48-30)/6.72=2.6786vw, (30-(48-30)/2.1)/16=1.33929rem */
|
|
799
|
+
--typography-heading-h1-fontSizeMin: 1.875rem; /* 30px */
|
|
800
|
+
--typography-heading-h1-fontSize: clamp(
|
|
801
|
+
var(--typography-heading-h1-fontSizeMin),
|
|
802
|
+
calc(1.33929rem + 2.6786vw),
|
|
803
|
+
var(--typography-fontSize-5xl)
|
|
804
|
+
);
|
|
805
|
+
--typography-heading-h1-fontWeight: var(--typography-fontWeight-bold);
|
|
806
|
+
--typography-heading-h1-lineHeight: var(--typography-lineHeight-tight);
|
|
807
|
+
--typography-heading-h1-letterSpacing: var(--typography-letterSpacing-normal);
|
|
808
|
+
--typography-heading-h1-fontFamily: var(--typography-fontFamily-sans);
|
|
809
|
+
|
|
810
|
+
/* fluid: 27px at 320 -> 36px at 992. (36-27)/6.72=1.3393vw, (27-(36-27)/2.1)/16=1.41964rem */
|
|
811
|
+
--typography-heading-h2-fontSizeMin: 1.6875rem; /* 27px */
|
|
812
|
+
--typography-heading-h2-fontSize: clamp(
|
|
813
|
+
var(--typography-heading-h2-fontSizeMin),
|
|
814
|
+
calc(1.41964rem + 1.3393vw),
|
|
815
|
+
var(--typography-fontSize-4xl)
|
|
816
|
+
);
|
|
817
|
+
--typography-heading-h2-fontWeight: var(--typography-fontWeight-bold);
|
|
818
|
+
--typography-heading-h2-lineHeight: var(--typography-lineHeight-tight);
|
|
819
|
+
--typography-heading-h2-letterSpacing: var(--typography-letterSpacing-normal);
|
|
820
|
+
--typography-heading-h2-fontFamily: var(--typography-fontFamily-sans);
|
|
821
|
+
|
|
822
|
+
/* fluid: 24px at 320 -> 32px at 992. (32-24)/6.72=1.1905vw, (24-(32-24)/2.1)/16=1.26190rem */
|
|
823
|
+
--typography-heading-h3-fontSizeMin: 1.5rem; /* 24px */
|
|
824
|
+
--typography-heading-h3-fontSize: clamp(
|
|
825
|
+
var(--typography-heading-h3-fontSizeMin),
|
|
826
|
+
calc(1.26190rem + 1.1905vw),
|
|
827
|
+
var(--typography-fontSize-3xl)
|
|
828
|
+
);
|
|
829
|
+
--typography-heading-h3-fontWeight: var(--typography-fontWeight-semibold);
|
|
830
|
+
--typography-heading-h3-lineHeight: var(--typography-lineHeight-130);
|
|
831
|
+
--typography-heading-h3-letterSpacing: var(--typography-letterSpacing-normal);
|
|
832
|
+
--typography-heading-h3-fontFamily: var(--typography-fontFamily-sans);
|
|
833
|
+
|
|
834
|
+
/* fluid: 21px at 320 -> 24px at 992. (24-21)/6.72=0.4464vw, (21-(24-21)/2.1)/16=1.22321rem */
|
|
835
|
+
--typography-heading-h4-fontSizeMin: 1.3125rem; /* 21px */
|
|
836
|
+
--typography-heading-h4-fontSize: clamp(
|
|
837
|
+
var(--typography-heading-h4-fontSizeMin),
|
|
838
|
+
calc(1.22321rem + 0.4464vw),
|
|
839
|
+
var(--typography-fontSize-2xl)
|
|
840
|
+
);
|
|
841
|
+
--typography-heading-h4-fontWeight: var(--typography-fontWeight-semibold);
|
|
842
|
+
--typography-heading-h4-lineHeight: var(--typography-lineHeight-130);
|
|
843
|
+
--typography-heading-h4-letterSpacing: var(--typography-letterSpacing-normal);
|
|
844
|
+
--typography-heading-h4-fontFamily: var(--typography-fontFamily-sans);
|
|
845
|
+
|
|
846
|
+
/* fluid: 18px at 320 -> 20px at 992. (20-18)/6.72=0.2976vw, (18-(20-18)/2.1)/16=1.06548rem */
|
|
847
|
+
--typography-heading-h5-fontSizeMin: 1.125rem; /* 18px */
|
|
848
|
+
--typography-heading-h5-fontSize: clamp(
|
|
849
|
+
var(--typography-heading-h5-fontSizeMin),
|
|
850
|
+
calc(1.06548rem + 0.2976vw),
|
|
851
|
+
var(--typography-fontSize-xl)
|
|
852
|
+
);
|
|
853
|
+
--typography-heading-h5-fontWeight: var(--typography-fontWeight-medium);
|
|
854
|
+
--typography-heading-h5-lineHeight: var(--typography-lineHeight-140);
|
|
855
|
+
--typography-heading-h5-letterSpacing: var(--typography-letterSpacing-normal);
|
|
856
|
+
--typography-heading-h5-fontFamily: var(--typography-fontFamily-sans);
|
|
857
|
+
|
|
858
|
+
/* fluid: 16px at 320 -> 18px at 992. (18-16)/6.72=0.2976vw, (16-(18-16)/2.1)/16=0.94048rem */
|
|
859
|
+
--typography-heading-h6-fontSizeMin: 1rem; /* 16px */
|
|
860
|
+
--typography-heading-h6-fontSize: clamp(
|
|
861
|
+
var(--typography-heading-h6-fontSizeMin),
|
|
862
|
+
calc(0.94048rem + 0.2976vw),
|
|
863
|
+
var(--typography-fontSize-lg)
|
|
864
|
+
);
|
|
865
|
+
--typography-heading-h6-fontWeight: var(--typography-fontWeight-medium);
|
|
866
|
+
--typography-heading-h6-lineHeight: var(--typography-lineHeight-145);
|
|
867
|
+
--typography-heading-h6-letterSpacing: var(--typography-letterSpacing-normal);
|
|
868
|
+
--typography-heading-h6-fontFamily: var(--typography-fontFamily-sans);
|
|
869
|
+
|
|
870
|
+
/* Body Text Tokens */
|
|
871
|
+
--typography-body-large-fontSize: var(--typography-fontSize-lg);
|
|
872
|
+
--typography-body-large-fontWeight: var(--typography-fontWeight-normal);
|
|
873
|
+
--typography-body-large-lineHeight: var(--typography-lineHeight-145);
|
|
874
|
+
--typography-body-large-letterSpacing: var(--typography-letterSpacing-normal);
|
|
875
|
+
--typography-body-large-fontFamily: var(--typography-fontFamily-sans);
|
|
876
|
+
|
|
877
|
+
--typography-body-regular-fontSize: var(--typography-fontSize-base);
|
|
878
|
+
--typography-body-regular-fontWeight: var(--typography-fontWeight-normal);
|
|
879
|
+
--typography-body-regular-lineHeight: var(--typography-lineHeight-normal);
|
|
880
|
+
--typography-body-regular-letterSpacing: var(
|
|
881
|
+
--typography-letterSpacing-normal
|
|
882
|
+
);
|
|
883
|
+
--typography-body-regular-fontFamily: var(--typography-fontFamily-sans);
|
|
884
|
+
|
|
885
|
+
--typography-body-small-fontSize: var(--typography-fontSize-sm);
|
|
886
|
+
--typography-body-small-fontWeight: var(--typography-fontWeight-normal);
|
|
887
|
+
--typography-body-small-lineHeight: var(--typography-lineHeight-145);
|
|
888
|
+
--typography-body-small-letterSpacing: var(--typography-letterSpacing-normal);
|
|
889
|
+
--typography-body-small-fontFamily: var(--typography-fontFamily-sans);
|
|
890
|
+
|
|
891
|
+
/* fluid: 18px at 320 -> 20px at 992. (20-18)/6.72=0.2976vw, (18-(20-18)/2.1)/16=1.06548rem */
|
|
892
|
+
--typography-body-lead-fontSizeMin: 1.125rem; /* 18px */
|
|
893
|
+
--typography-body-lead-fontSize: clamp(
|
|
894
|
+
var(--typography-body-lead-fontSizeMin),
|
|
895
|
+
calc(1.06548rem + 0.2976vw),
|
|
896
|
+
var(--typography-fontSize-xl)
|
|
897
|
+
);
|
|
898
|
+
--typography-body-lead-fontWeight: var(--typography-fontWeight-normal);
|
|
899
|
+
--typography-body-lead-lineHeight: var(--typography-lineHeight-140);
|
|
900
|
+
--typography-body-lead-letterSpacing: var(--typography-letterSpacing-normal);
|
|
901
|
+
--typography-body-lead-fontFamily: var(--typography-fontFamily-sans);
|
|
902
|
+
|
|
903
|
+
/* Label Tokens */
|
|
904
|
+
--typography-label-default-fontSize: var(--typography-fontSize-sm);
|
|
905
|
+
--typography-label-default-fontWeight: var(--typography-fontWeight-medium);
|
|
906
|
+
--typography-label-default-lineHeight: var(--typography-lineHeight-normal);
|
|
907
|
+
--typography-label-default-letterSpacing: var(
|
|
908
|
+
--typography-letterSpacing-normal
|
|
909
|
+
);
|
|
910
|
+
--typography-label-default-fontFamily: var(--typography-fontFamily-sans);
|
|
911
|
+
|
|
912
|
+
--typography-label-small-fontSize: var(--typography-fontSize-xs);
|
|
913
|
+
--typography-label-small-fontWeight: var(--typography-fontWeight-medium);
|
|
914
|
+
--typography-label-small-lineHeight: var(--typography-lineHeight-normal);
|
|
915
|
+
--typography-label-small-letterSpacing: var(--typography-letterSpacing-wide);
|
|
916
|
+
--typography-label-small-fontFamily: var(--typography-fontFamily-sans);
|
|
917
|
+
|
|
918
|
+
/* The only role for the 11px step, and it carried a size and nothing
|
|
919
|
+
else -- so anything using it inherited its leading from whatever it
|
|
920
|
+
happened to sit inside, which is not a typography contract. The four
|
|
921
|
+
missing axes match label-small, one step up. It has no consumers
|
|
922
|
+
today; the five components that render 11px reach past it for the
|
|
923
|
+
primitive, and moving them is a visual change this phase does not
|
|
924
|
+
make. */
|
|
288
925
|
--typography-label-extra-small-fontSize: var(--typography-fontSize-xxs);
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
--typography-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
--typography-letterSpacing-normal
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
*/
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
926
|
+
--typography-label-extra-small-fontWeight: var(--typography-fontWeight-medium);
|
|
927
|
+
--typography-label-extra-small-lineHeight: var(--typography-lineHeight-normal);
|
|
928
|
+
--typography-label-extra-small-letterSpacing: var(--typography-letterSpacing-wide);
|
|
929
|
+
--typography-label-extra-small-fontFamily: var(--typography-fontFamily-sans);
|
|
930
|
+
|
|
931
|
+
/* Deliberately size-only: bd-p variant=xsmall composes it with
|
|
932
|
+
body-small's weight, leading and tracking, so giving it axes of its
|
|
933
|
+
own would create a second answer to those questions.
|
|
934
|
+
|
|
935
|
+
It lives in the body family, not the label one. It was
|
|
936
|
+
--typography-label-xsmall-fontSize, one character away from
|
|
937
|
+
label-extra-small, which is a complete 11px role with a weight, a
|
|
938
|
+
leading and a family. Two names that close, describing things that
|
|
939
|
+
different, is a trap: one is a role you can ask for and the other is
|
|
940
|
+
a bare size that matches any one-axis 12px declaration on size
|
|
941
|
+
alone. Naming it for the component that owns it says which is
|
|
942
|
+
which. */
|
|
943
|
+
--typography-body-xsmall-fontSize: var(--typography-fontSize-xs);
|
|
944
|
+
|
|
945
|
+
--typography-label-large-fontSize: var(--typography-fontSize-base);
|
|
946
|
+
--typography-label-large-fontWeight: var(--typography-fontWeight-medium);
|
|
947
|
+
--typography-label-large-lineHeight: var(--typography-lineHeight-normal);
|
|
948
|
+
--typography-label-large-letterSpacing: var(
|
|
949
|
+
--typography-letterSpacing-normal
|
|
950
|
+
);
|
|
951
|
+
--typography-label-large-fontFamily: var(--typography-fontFamily-sans);
|
|
952
|
+
|
|
953
|
+
/* Control Label Tokens
|
|
954
|
+
|
|
955
|
+
label-* at control leading. Every label-* rung is lineHeight-normal
|
|
956
|
+
(1.5); a control -- a badge, a button -- needs 1.25 so its box can be
|
|
957
|
+
padding-driven without the line box forcing it taller.
|
|
958
|
+
scripts/typography-pairings.json already records 16px at 1.25 as
|
|
959
|
+
physically valid "because control text needs it", and rule 8 says
|
|
960
|
+
that file is a technical boundary rather than authorization, so the
|
|
961
|
+
authorization is here: this is the role that means "a label on a
|
|
962
|
+
control".
|
|
963
|
+
|
|
964
|
+
Motivated by badge.css.js and button.css.js's .bd-contact-btn, which
|
|
965
|
+
each arrived independently at medium + tight and had no role to ask
|
|
966
|
+
for. The three rungs mirror label-small / label-default /
|
|
967
|
+
label-large step for step. The one place they do not mirror is
|
|
968
|
+
tracking on the small rung: label-small is letterSpacing-wide, but
|
|
969
|
+
badge -- the atom this rung exists for -- renders normal, so the rung
|
|
970
|
+
describes its consumer rather than its twin. Everywhere else the only
|
|
971
|
+
axis that differs from the label-* rung of the same name is the
|
|
972
|
+
leading. */
|
|
973
|
+
--typography-control-label-small-fontSize: var(--typography-fontSize-xs);
|
|
974
|
+
--typography-control-label-small-fontWeight: var(--typography-fontWeight-medium);
|
|
975
|
+
--typography-control-label-small-lineHeight: var(--typography-lineHeight-tight);
|
|
976
|
+
--typography-control-label-small-letterSpacing: var(--typography-letterSpacing-normal);
|
|
977
|
+
--typography-control-label-small-fontFamily: var(--typography-fontFamily-sans);
|
|
978
|
+
|
|
979
|
+
--typography-control-label-default-fontSize: var(--typography-fontSize-sm);
|
|
980
|
+
--typography-control-label-default-fontWeight: var(--typography-fontWeight-medium);
|
|
981
|
+
--typography-control-label-default-lineHeight: var(--typography-lineHeight-tight);
|
|
982
|
+
--typography-control-label-default-letterSpacing: var(--typography-letterSpacing-normal);
|
|
983
|
+
--typography-control-label-default-fontFamily: var(--typography-fontFamily-sans);
|
|
984
|
+
|
|
985
|
+
--typography-control-label-large-fontSize: var(--typography-fontSize-base);
|
|
986
|
+
--typography-control-label-large-fontWeight: var(--typography-fontWeight-medium);
|
|
987
|
+
--typography-control-label-large-lineHeight: var(--typography-lineHeight-tight);
|
|
988
|
+
--typography-control-label-large-letterSpacing: var(--typography-letterSpacing-normal);
|
|
989
|
+
--typography-control-label-large-fontFamily: var(--typography-fontFamily-sans);
|
|
990
|
+
|
|
991
|
+
/* The rung label-xl used to occupy. label-xl was lg/medium/normal and
|
|
992
|
+
documented in vertical-rhythm.stories.js as "the name of a large
|
|
993
|
+
control" -- the same job this family names, but at label leading
|
|
994
|
+
rather than control leading, and with no consumer in the package.
|
|
995
|
+
Retired in favour of this. Note it was byte-identical to heading-h6,
|
|
996
|
+
which stays: that pair was two questions with coincidentally equal
|
|
997
|
+
answers, and heading-h6 is the one bd-h actually renders. */
|
|
998
|
+
--typography-control-label-xl-fontSize: var(--typography-fontSize-lg);
|
|
999
|
+
--typography-control-label-xl-fontWeight: var(--typography-fontWeight-medium);
|
|
1000
|
+
--typography-control-label-xl-lineHeight: var(--typography-lineHeight-tight);
|
|
1001
|
+
--typography-control-label-xl-letterSpacing: var(--typography-letterSpacing-normal);
|
|
1002
|
+
--typography-control-label-xl-fontFamily: var(--typography-fontFamily-sans);
|
|
1003
|
+
|
|
1004
|
+
/* Caption Tokens */
|
|
1005
|
+
--typography-caption-default-fontSize: var(--typography-fontSize-xs);
|
|
1006
|
+
--typography-caption-default-fontWeight: var(--typography-fontWeight-normal);
|
|
1007
|
+
--typography-caption-default-lineHeight: var(--typography-lineHeight-normal);
|
|
1008
|
+
--typography-caption-default-letterSpacing: var(
|
|
1009
|
+
--typography-letterSpacing-normal
|
|
1010
|
+
);
|
|
1011
|
+
--typography-caption-default-fontFamily: var(--typography-fontFamily-sans);
|
|
1012
|
+
--typography-caption-default-color: var(--color-text-muted);
|
|
1013
|
+
|
|
1014
|
+
--typography-caption-small-fontSize: var(--typography-fontSize-xs);
|
|
1015
|
+
--typography-caption-small-fontWeight: var(--typography-fontWeight-normal);
|
|
1016
|
+
--typography-caption-small-lineHeight: var(--typography-lineHeight-normal);
|
|
1017
|
+
--typography-caption-small-letterSpacing: var(
|
|
1018
|
+
--typography-letterSpacing-wide
|
|
1019
|
+
);
|
|
1020
|
+
--typography-caption-small-fontFamily: var(--typography-fontFamily-sans);
|
|
1021
|
+
|
|
1022
|
+
/* Link Tokens */
|
|
1023
|
+
--typography-link-default-fontSize: inherit;
|
|
1024
|
+
--typography-link-default-fontWeight: var(--typography-fontWeight-normal);
|
|
1025
|
+
--typography-link-default-lineHeight: inherit;
|
|
1026
|
+
--typography-link-default-letterSpacing: inherit;
|
|
1027
|
+
--typography-link-default-fontFamily: inherit;
|
|
1028
|
+
--typography-link-default-textDecoration-default: underline;
|
|
1029
|
+
--typography-link-default-textDecoration-hover: none;
|
|
1030
|
+
/* The gap between the text and its underline. It was spelled as a 2px
|
|
1031
|
+
literal in seven places in bd-link, on a property the length rule
|
|
1032
|
+
does not check, so nothing could see it and nothing could change it
|
|
1033
|
+
in one move. */
|
|
1034
|
+
--typography-link-underlineOffset: var(--spacing-2);
|
|
1035
|
+
--typography-link-underlineThickness: var(--border-width-2);
|
|
1036
|
+
|
|
1037
|
+
--typography-link-standalone-fontSize: var(--typography-fontSize-base);
|
|
1038
|
+
--typography-link-standalone-fontWeight: var(--typography-fontWeight-medium);
|
|
1039
|
+
--typography-link-standalone-lineHeight: var(--typography-lineHeight-normal);
|
|
1040
|
+
--typography-link-standalone-letterSpacing: var(
|
|
1041
|
+
--typography-letterSpacing-normal
|
|
1042
|
+
);
|
|
1043
|
+
--typography-link-standalone-fontFamily: var(--typography-fontFamily-sans);
|
|
1044
|
+
--typography-link-standalone-textDecoration-default: underline;
|
|
1045
|
+
--typography-link-standalone-textDecoration-hover: none;
|
|
1046
|
+
|
|
1047
|
+
/* Code Tokens */
|
|
1048
|
+
--typography-code-inline-fontSize: 0.875em;
|
|
1049
|
+
--typography-code-inline-fontWeight: var(--typography-fontWeight-normal);
|
|
1050
|
+
--typography-code-inline-lineHeight: inherit;
|
|
1051
|
+
--typography-code-inline-letterSpacing: var(
|
|
1052
|
+
--typography-letterSpacing-normal
|
|
1053
|
+
);
|
|
1054
|
+
--typography-code-inline-fontFamily: var(--typography-fontFamily-mono);
|
|
1055
|
+
|
|
1056
|
+
--typography-code-block-fontSize: var(--typography-fontSize-sm);
|
|
1057
|
+
--typography-code-block-fontWeight: var(--typography-fontWeight-normal);
|
|
1058
|
+
--typography-code-block-lineHeight: var(--typography-lineHeight-relaxed);
|
|
1059
|
+
--typography-code-block-letterSpacing: var(--typography-letterSpacing-normal);
|
|
1060
|
+
--typography-code-block-fontFamily: var(--typography-fontFamily-mono);
|
|
1061
|
+
|
|
1062
|
+
/* Display Typography Tokens */
|
|
1063
|
+
--typography-display-3xl-fontSize: var(--typography-fontSize-9xl);
|
|
1064
|
+
--typography-display-3xl-fontWeight: var(--typography-fontWeight-bold);
|
|
1065
|
+
--typography-display-3xl-lineHeight: var(--typography-lineHeight-tight);
|
|
1066
|
+
--typography-display-3xl-letterSpacing: var(--typography-letterSpacing-tight);
|
|
1067
|
+
--typography-display-3xl-fontFamily: var(--typography-fontFamily-sans);
|
|
1068
|
+
|
|
1069
|
+
--typography-display-2xl-fontSize: var(--typography-fontSize-8xl);
|
|
1070
|
+
--typography-display-2xl-fontWeight: var(--typography-fontWeight-bold);
|
|
1071
|
+
--typography-display-2xl-lineHeight: var(--typography-lineHeight-tight);
|
|
1072
|
+
--typography-display-2xl-letterSpacing: var(--typography-letterSpacing-tight);
|
|
1073
|
+
--typography-display-2xl-fontFamily: var(--typography-fontFamily-sans);
|
|
1074
|
+
|
|
1075
|
+
--typography-display-xl-fontSize: var(--typography-fontSize-7xl);
|
|
1076
|
+
--typography-display-xl-fontWeight: var(--typography-fontWeight-bold);
|
|
1077
|
+
--typography-display-xl-lineHeight: var(--typography-lineHeight-tight);
|
|
1078
|
+
--typography-display-xl-letterSpacing: var(--typography-letterSpacing-tight);
|
|
1079
|
+
--typography-display-xl-fontFamily: var(--typography-fontFamily-sans);
|
|
1080
|
+
|
|
1081
|
+
--typography-display-lg-fontSize: var(--typography-fontSize-6xl);
|
|
1082
|
+
--typography-display-lg-fontWeight: var(--typography-fontWeight-bold);
|
|
1083
|
+
--typography-display-lg-lineHeight: var(--typography-lineHeight-tight);
|
|
1084
|
+
--typography-display-lg-letterSpacing: var(--typography-letterSpacing-tight);
|
|
1085
|
+
--typography-display-lg-fontFamily: var(--typography-fontFamily-sans);
|
|
1086
|
+
|
|
1087
|
+
/* fluid: 30px at 320 -> 48px at 992. (48-30)/6.72=2.6786vw, (30-(48-30)/2.1)/16=1.33929rem */
|
|
1088
|
+
--typography-display-md-fontSizeMin: 1.875rem; /* 30px */
|
|
1089
|
+
--typography-display-md-fontSize: clamp(
|
|
1090
|
+
var(--typography-display-md-fontSizeMin),
|
|
1091
|
+
calc(1.33929rem + 2.6786vw),
|
|
1092
|
+
var(--typography-fontSize-5xl)
|
|
1093
|
+
);
|
|
1094
|
+
--typography-display-md-fontWeight: var(--typography-fontWeight-bold);
|
|
1095
|
+
--typography-display-md-lineHeight: var(--typography-lineHeight-tight);
|
|
1096
|
+
--typography-display-md-letterSpacing: var(--typography-letterSpacing-tight);
|
|
1097
|
+
--typography-display-md-fontFamily: var(--typography-fontFamily-sans);
|
|
1098
|
+
|
|
1099
|
+
/* fluid: 30px at 320 -> 36px at 992. (36-30)/6.72=0.8929vw, (30-(36-30)/2.1)/16=1.69643rem */
|
|
1100
|
+
--typography-display-sm-fontSizeMin: 1.875rem; /* 30px */
|
|
1101
|
+
--typography-display-sm-fontSize: clamp(
|
|
1102
|
+
var(--typography-display-sm-fontSizeMin),
|
|
1103
|
+
calc(1.69643rem + 0.8929vw),
|
|
1104
|
+
var(--typography-fontSize-4xl)
|
|
1105
|
+
);
|
|
1106
|
+
--typography-display-sm-fontWeight: var(--typography-fontWeight-bold);
|
|
1107
|
+
--typography-display-sm-lineHeight: var(--typography-lineHeight-tight);
|
|
1108
|
+
--typography-display-sm-letterSpacing: var(--typography-letterSpacing-tight);
|
|
1109
|
+
--typography-display-sm-fontFamily: var(--typography-fontFamily-sans);
|
|
1110
|
+
|
|
1111
|
+
/* ================================
|
|
1112
|
+
COMPONENT TOKENS - FORM
|
|
1113
|
+
================================ */
|
|
1114
|
+
|
|
1115
|
+
/* Form Label Tokens */
|
|
1116
|
+
--form-label-default-fontSize: var(--typography-fontSize-sm);
|
|
1117
|
+
--form-label-default-fontWeight: var(--typography-fontWeight-medium);
|
|
1118
|
+
--form-label-default-lineHeight: var(--typography-lineHeight-normal);
|
|
1119
|
+
--form-label-default-letterSpacing: var(--typography-letterSpacing-normal);
|
|
1120
|
+
--form-label-default-fontFamily: var(--typography-fontFamily-sans);
|
|
1121
|
+
--form-label-default-color: var(--color-text-primary);
|
|
1122
|
+
--form-label-default-marginBottom: var(--spacing-4);
|
|
1123
|
+
|
|
1124
|
+
--form-label-large-fontSize: var(--typography-fontSize-lg);
|
|
1125
|
+
--form-label-large-fontWeight: var(--typography-fontWeight-medium);
|
|
1126
|
+
--form-label-large-lineHeight: var(--typography-lineHeight-normal);
|
|
1127
|
+
--form-label-large-letterSpacing: var(--typography-letterSpacing-normal);
|
|
1128
|
+
--form-label-large-fontFamily: var(--typography-fontFamily-sans);
|
|
1129
|
+
--form-label-large-color: var(--color-text-primary);
|
|
1130
|
+
--form-label-large-marginBottom: var(--spacing-8);
|
|
1131
|
+
|
|
1132
|
+
--form-label-small-fontSize: var(--typography-fontSize-xs);
|
|
1133
|
+
--form-label-small-fontWeight: var(--typography-fontWeight-medium);
|
|
1134
|
+
--form-label-small-lineHeight: var(--typography-lineHeight-normal);
|
|
1135
|
+
--form-label-small-letterSpacing: var(--typography-letterSpacing-wide);
|
|
1136
|
+
--form-label-small-fontFamily: var(--typography-fontFamily-sans);
|
|
1137
|
+
--form-label-small-color: var(--color-text-primary);
|
|
1138
|
+
--form-label-small-marginBottom: var(--spacing-4);
|
|
1139
|
+
|
|
1140
|
+
--form-label-required-color: var(--status-error-accent);
|
|
1141
|
+
--form-label-required-marginLeft: var(--spacing-4);
|
|
1142
|
+
|
|
1143
|
+
/* Form Input Tokens */
|
|
1144
|
+
|
|
1145
|
+
/* The height of a control is derived, not chosen: padding, type step and
|
|
1146
|
+
line-height, the same three bd-button derives its own height from.
|
|
1147
|
+
That derivation is what keeps a field and a button of the same size
|
|
1148
|
+
the same height on one row of a form.
|
|
1149
|
+
|
|
1150
|
+
These three said --dimension-36/44/56 and stated a height the system
|
|
1151
|
+
does not draw. A small field renders 33.5px and a large one 54.5px;
|
|
1152
|
+
only medium agreed, and it agreed by coincidence. Nothing read them,
|
|
1153
|
+
so nothing surfaced the disagreement -- which is the argument for
|
|
1154
|
+
spelling the derivation here rather than a rounder number, and for
|
|
1155
|
+
shared/form-field.css.js reading these instead of repeating the calc
|
|
1156
|
+
three times. Changing them changes no pixel; it changes what the
|
|
1157
|
+
package tells a consumer the height is.
|
|
1158
|
+
|
|
1159
|
+
The line box these leave is 2px taller than the content box, because
|
|
1160
|
+
the derivation counts padding but not the 1px border on each edge.
|
|
1161
|
+
Measured at every size: no glyph clips, because an input centres its
|
|
1162
|
+
line and paints into the padding. Correcting it would move a field
|
|
1163
|
+
off its button, so it stays a recorded fact rather than a fix. */
|
|
1164
|
+
--form-input-small-height: calc(
|
|
1165
|
+
var(--spacing-8) * 2 + var(--typography-fontSize-sm) * var(--typography-lineHeight-tight)
|
|
1166
|
+
);
|
|
1167
|
+
--form-input-small-fontSize: var(--typography-fontSize-sm);
|
|
1168
|
+
--form-input-small-padding: var(--spacing-8) var(--spacing-12);
|
|
1169
|
+
--form-input-small-borderRadius: var(--radius-sm);
|
|
1170
|
+
|
|
1171
|
+
--form-input-medium-height: calc(
|
|
1172
|
+
var(--spacing-12) * 2 + var(--typography-fontSize-base) * var(--typography-lineHeight-tight)
|
|
1173
|
+
);
|
|
1174
|
+
--form-input-medium-fontSize: var(--typography-fontSize-base);
|
|
1175
|
+
--form-input-medium-padding: var(--spacing-12) var(--spacing-16);
|
|
1176
|
+
--form-input-medium-borderRadius: var(--radius-md);
|
|
1177
|
+
|
|
1178
|
+
--form-input-large-height: calc(
|
|
1179
|
+
var(--spacing-16) * 2 + var(--typography-fontSize-lg) * var(--typography-lineHeight-tight)
|
|
1180
|
+
);
|
|
1181
|
+
--form-input-large-fontSize: var(--typography-fontSize-lg);
|
|
1182
|
+
--form-input-large-padding: var(--spacing-16) var(--spacing-20);
|
|
1183
|
+
--form-input-large-borderRadius: var(--radius-lg);
|
|
1184
|
+
|
|
1185
|
+
--form-input-default-backgroundColor: var(--color-surface-default);
|
|
1186
|
+
--form-input-default-borderColor: var(--color-border-default);
|
|
1187
|
+
--form-input-default-borderWidth: var(--border-width-1);
|
|
1188
|
+
--form-input-default-color: var(--color-text-primary);
|
|
1189
|
+
--form-input-default-fontFamily: var(--typography-fontFamily-sans);
|
|
1190
|
+
/* There is deliberately no --form-input-default-lineHeight. There was
|
|
1191
|
+
one, it said normal (1.5), it had no consumer, and it described the
|
|
1192
|
+
opposite of what the control does: form-field.css.js sets tight and
|
|
1193
|
+
records why -- at normal the line box stood taller than the content
|
|
1194
|
+
box the derived height leaves, and the select clipped the descenders
|
|
1195
|
+
of its own option text.
|
|
1196
|
+
|
|
1197
|
+
It is not restored as tight either. The control's height is
|
|
1198
|
+
DERIVED from padding, type step and this leading, so exposing the
|
|
1199
|
+
leading as a component token would let a consuming page change the
|
|
1200
|
+
height by setting something that reads like a type preference. The
|
|
1201
|
+
primitive is used at the one site that needs it, with its reason on
|
|
1202
|
+
the line, which is what keeps the box and the text unable to
|
|
1203
|
+
disagree. */
|
|
1204
|
+
|
|
1205
|
+
--form-input-focus-borderColor: var(--color-border-brand);
|
|
1206
|
+
--form-input-focus-boxShadow: var(--shadow-focus-outline-blue);
|
|
1207
|
+
|
|
1208
|
+
--form-input-error-backgroundColor: var(--status-error-surface);
|
|
1209
|
+
--form-input-error-borderColor: var(--status-error-accent);
|
|
1210
|
+
--form-input-error-placeholderColor: var(--color-red-600);
|
|
1211
|
+
|
|
1212
|
+
--form-input-success-backgroundColor: var(--status-success-surface);
|
|
1213
|
+
--form-input-success-borderColor: var(--color-green-600);
|
|
1214
|
+
--form-input-success-placeholderColor: var(--color-green-700);
|
|
1215
|
+
|
|
1216
|
+
--form-input-disabled-backgroundColor: var(--color-surface-disabled);
|
|
1217
|
+
--form-input-disabled-borderColor: var(--color-border-disabled);
|
|
1218
|
+
--form-input-disabled-color: var(--color-text-subtle);
|
|
1219
|
+
--form-input-disabled-placeholderColor: var(--color-neutral-400);
|
|
1220
|
+
|
|
1221
|
+
/* Form Help Text Tokens */
|
|
1222
|
+
--form-help-text-default-fontSize: var(--typography-fontSize-xs);
|
|
1223
|
+
--form-help-text-default-fontWeight: var(--typography-fontWeight-normal);
|
|
1224
|
+
--form-help-text-default-lineHeight: var(--typography-lineHeight-normal);
|
|
1225
|
+
--form-help-text-default-letterSpacing: var(
|
|
1226
|
+
--typography-letterSpacing-normal
|
|
1227
|
+
);
|
|
1228
|
+
--form-help-text-default-fontFamily: var(--typography-fontFamily-sans);
|
|
1229
|
+
--form-help-text-default-color: var(--color-text-muted);
|
|
1230
|
+
--form-help-text-default-marginTop: var(--spacing-4);
|
|
1231
|
+
|
|
1232
|
+
/* Measured against the tint the field itself takes in each state, not
|
|
1233
|
+
against white — that is the background this text actually sits
|
|
1234
|
+
beside. red-600 on red-50 is 4.92 and needs nothing.
|
|
1235
|
+
|
|
1236
|
+
success was green-700, which is 4.75 on white but only 4.51 on
|
|
1237
|
+
green-50: passing by a hundredth, and the kind of margin that stops
|
|
1238
|
+
passing the moment a tint moves. green-800 is 6.42 there, and is
|
|
1239
|
+
already the step --color-text-success names for this role. */
|
|
1240
|
+
--form-help-text-error-color: var(--status-error-accent);
|
|
1241
|
+
--form-help-text-success-color: var(--color-text-success);
|
|
1242
|
+
|
|
1243
|
+
/* Form Layout Tokens
|
|
1244
|
+
|
|
1245
|
+
These were written against a step-indexed spacing scale, where the
|
|
1246
|
+
number is the position on the scale, and never converted when the
|
|
1247
|
+
scale became pixel-named, where the number is the value. So
|
|
1248
|
+
--spacing-6 stopped meaning "the sixth step, 24px" and started
|
|
1249
|
+
meaning 6px, silently — every token still resolved, and the lint has
|
|
1250
|
+
no way to see it.
|
|
1251
|
+
|
|
1252
|
+
bd-fieldset consumes fieldSpacing, so a form built from it has been
|
|
1253
|
+
stacking its fields 6px apart. Decoded as indices these read 24 and
|
|
1254
|
+
32, which is what a form actually wants and what the value is set to
|
|
1255
|
+
here. */
|
|
1256
|
+
--form-fieldSpacing: var(--spacing-24);
|
|
1257
|
+
--form-sectionSpacing: var(--spacing-32);
|
|
1258
|
+
--form-labelSpacing: var(--spacing-4);
|
|
1259
|
+
--form-helpTextSpacing: var(--spacing-4);
|
|
1260
|
+
|
|
1261
|
+
/* ================================
|
|
1262
|
+
COMPONENT TOKENS - BUTTON
|
|
1263
|
+
================================ */
|
|
1264
|
+
|
|
1265
|
+
/* Button Size Tokens */
|
|
1266
|
+
/* One size family. There were two — this one and --button-size-*, with
|
|
1267
|
+
different padding in each and neither matching what the component
|
|
1268
|
+
rendered. bd-button reads these.
|
|
1269
|
+
|
|
1270
|
+
No -height. The component derives its height from padding, type step
|
|
1271
|
+
and line-height rather than pinning it, which is what keeps it equal
|
|
1272
|
+
to a field of the same size; a height token here would be a second
|
|
1273
|
+
answer that could disagree. */
|
|
1274
|
+
--button-small-fontSize: var(--typography-fontSize-sm);
|
|
1275
|
+
--button-small-padding: var(--spacing-8) var(--spacing-16);
|
|
1276
|
+
--button-small-gap: var(--spacing-4);
|
|
1277
|
+
--button-small-borderRadius: var(--radius-sm);
|
|
1278
|
+
|
|
1279
|
+
--button-medium-fontSize: var(--typography-fontSize-base);
|
|
1280
|
+
--button-medium-padding: var(--spacing-12) var(--spacing-24);
|
|
1281
|
+
--button-medium-gap: var(--spacing-8);
|
|
1282
|
+
--button-medium-borderRadius: var(--radius-md);
|
|
1283
|
+
|
|
1284
|
+
--button-large-fontSize: var(--typography-fontSize-lg);
|
|
1285
|
+
--button-large-padding: var(--spacing-16) var(--spacing-32);
|
|
1286
|
+
--button-large-gap: var(--spacing-8);
|
|
1287
|
+
--button-large-borderRadius: var(--radius-lg);
|
|
1288
|
+
|
|
1289
|
+
/* Button Default State */
|
|
1290
|
+
--button-default-backgroundColor: var(--color-neutral-0);
|
|
1291
|
+
--button-default-borderColor: var(--color-neutral-400);
|
|
1292
|
+
--button-default-borderWidth: var(--border-width-1);
|
|
1293
|
+
--button-default-color: var(--color-neutral-900);
|
|
1294
|
+
--button-default-fontFamily: var(--typography-fontFamily-sans);
|
|
1295
|
+
--button-default-fontWeight: var(--typography-fontWeight-medium);
|
|
1296
|
+
--button-default-lineHeight: var(--typography-lineHeight-normal);
|
|
1297
|
+
|
|
1298
|
+
/* Button Shared Tokens */
|
|
1299
|
+
--button-shared-fontFamily: var(--typography-fontFamily-sans);
|
|
1300
|
+
--button-shared-fontWeight: var(--typography-fontWeight-medium);
|
|
1301
|
+
--button-shared-lineHeight: var(--typography-lineHeight-tight);
|
|
1302
|
+
--button-shared-letterSpacing: var(--typography-letterSpacing-normal);
|
|
1303
|
+
--button-shared-borderWidth: var(--border-width-1);
|
|
1304
|
+
--button-shared-transition-properties: background-color, border-color, color,
|
|
1305
|
+
box-shadow;
|
|
1306
|
+
--button-shared-transition-duration: var(--transition-duration-normal);
|
|
1307
|
+
--button-shared-transition-easing: var(--transition-easing-smooth);
|
|
1308
|
+
--button-shared-focus-outline: var(--focus-outline-traditional);
|
|
1309
|
+
--button-shared-focus-outlineOffset: var(--focus-outline-offset);
|
|
1310
|
+
--button-shared-focus-boxShadow: var(--focus-outline-primary);
|
|
1311
|
+
--button-shared-disabled-opacity: 0.6;
|
|
1312
|
+
--button-shared-disabled-cursor: not-allowed;
|
|
1313
|
+
|
|
1314
|
+
/* ---- variant colours -------------------------------------------
|
|
1315
|
+
Named for the kind attribute they serve, because that is the public
|
|
1316
|
+
vocabulary: primary, secondary, tertiary, ghost, accent, white and
|
|
1317
|
+
outline-white. They used to be named tertiaryPrimary,
|
|
1318
|
+
tertiarySecondary and cta, which no consumer could map onto the
|
|
1319
|
+
component without reading its source.
|
|
1320
|
+
|
|
1321
|
+
bd-button aliases each of these onto a --button-*-bg property on its
|
|
1322
|
+
own :host, so there are two override points and they do different
|
|
1323
|
+
jobs: set the token on :root to move every button in the document,
|
|
1324
|
+
or the alias on the bd-button element to move one. The alias is also what
|
|
1325
|
+
surface="dark" switches, which is why the component keeps it.
|
|
1326
|
+
|
|
1327
|
+
Every value here is what the component already renders. The old
|
|
1328
|
+
values had drifted apart from it in four places — secondary's hover
|
|
1329
|
+
and active, tertiary's hover border and ghost's active fill — so
|
|
1330
|
+
wiring them up unchanged would have moved pixels.
|
|
1331
|
+
|
|
1332
|
+
The per-variant -focus and -disabled sets are gone. The component
|
|
1333
|
+
draws one focus ring for every variant, from --focus-outline-primary,
|
|
1334
|
+
and one shared disabled treatment; thirty tokens described per-variant
|
|
1335
|
+
versions of both that nothing rendered. --button-empty-* went with
|
|
1336
|
+
them: there is no empty kind. */
|
|
1337
|
+
|
|
1338
|
+
/* primary: blue fill */
|
|
1339
|
+
--button-primary-background-default: var(--color-action-primary);
|
|
1340
|
+
--button-primary-background-hover: var(--color-action-primary-hover);
|
|
1341
|
+
--button-primary-background-active: var(--color-action-primary-active);
|
|
1342
|
+
--button-primary-text-default: var(--color-action-on-fill);
|
|
1343
|
+
|
|
1344
|
+
/* secondary: near-black fill */
|
|
1345
|
+
--button-secondary-background-default: var(--color-action-secondary);
|
|
1346
|
+
--button-secondary-background-hover: var(--color-action-secondary-hover);
|
|
1347
|
+
--button-secondary-background-active: var(--color-action-secondary-active);
|
|
1348
|
+
--button-secondary-text-default: var(--color-action-on-fill);
|
|
1349
|
+
|
|
1350
|
+
/* tertiary: blue outline. text-hover is blue-600, not blue-500: on the
|
|
1351
|
+
blue-50 hover fill the lighter step measures 4.20:1 and fails 1.4.3,
|
|
1352
|
+
where blue-600 gives 5.72.
|
|
1353
|
+
.
|
|
1354
|
+
text-default is blue-600 for the same reason, applied to the state a
|
|
1355
|
+
reader actually sits in. The line above fixed hover, where blue-500
|
|
1356
|
+
failed outright, and left the resting state on blue-500 at 4.53:1 --
|
|
1357
|
+
passing 4.5 by 0.03 on pure white and failing on any tint, which is
|
|
1358
|
+
the margin CLAUDE.md says is not real. Both states now name the same
|
|
1359
|
+
ink role, and the role is the category-correct one: --color-action-primary
|
|
1360
|
+
is an interaction role for fills, not ink, and it was being read by a
|
|
1361
|
+
color: property. Measured 4.53:1 -> 6.18:1 on all six consumers.
|
|
1362
|
+
The ring is deliberately NOT changed here and stays blue-500: it is
|
|
1363
|
+
non-text UI at a 3:1 bar, it passes, and moving it would mean naming a
|
|
1364
|
+
blue-600 border role that does not exist. See the plan's backlog. */
|
|
1365
|
+
--button-tertiary-text-default: var(--color-text-brand);
|
|
1366
|
+
--button-tertiary-border-default: var(--color-border-brand);
|
|
1367
|
+
--button-tertiary-background-hover: var(--color-surface-info);
|
|
1368
|
+
--button-tertiary-text-hover: var(--color-text-brand);
|
|
1369
|
+
--button-tertiary-border-hover: var(--color-action-primary-hover);
|
|
1370
|
+
--button-tertiary-background-active: var(--color-action-primary);
|
|
1371
|
+
--button-tertiary-text-active: var(--color-action-on-fill);
|
|
1372
|
+
|
|
1373
|
+
/* ghost: dark outline */
|
|
1374
|
+
--button-ghost-text-default: var(--color-text-primary);
|
|
1375
|
+
--button-ghost-border-default: var(--color-border-strong);
|
|
1376
|
+
--button-ghost-background-hover: var(--color-surface-muted);
|
|
1377
|
+
--button-ghost-text-hover: var(--color-text-primary);
|
|
1378
|
+
--button-ghost-background-active: var(--color-action-secondary);
|
|
1379
|
+
--button-ghost-text-active: var(--color-action-on-fill);
|
|
1380
|
+
|
|
1381
|
+
/* accent: red fill. This system's conversion colour — Buy now and the
|
|
1382
|
+
like — not a danger signal; there is deliberately no danger variant.
|
|
1383
|
+
red-600, not red-500: white on red-500 measures 4.00:1 and fails. */
|
|
1384
|
+
--button-accent-background-default: var(--color-action-accent);
|
|
1385
|
+
--button-accent-background-hover: var(--color-action-accent-hover);
|
|
1386
|
+
--button-accent-background-active: var(--color-action-accent-active);
|
|
1387
|
+
--button-accent-text-default: var(--color-action-on-fill);
|
|
1388
|
+
--button-accent-ring-default: transparent;
|
|
1389
|
+
|
|
1390
|
+
/* white and outline-white: fixed presets for a solid-colour banner,
|
|
1391
|
+
where even a surface="dark" primary would sit too close in tone.
|
|
1392
|
+
They ignore surface on purpose.
|
|
1393
|
+
|
|
1394
|
+
text-default is blue-600 rather than blue-500: white is the fill
|
|
1395
|
+
here, and blue-500 on white is 4.53:1 — the marginal step the
|
|
1396
|
+
contrast note warns against for text.
|
|
1397
|
+
|
|
1398
|
+
The translucent whites were rgba(255,255,255,…) and #ffffff8c
|
|
1399
|
+
literals, which no theme could reach. color-mix keeps the alpha and
|
|
1400
|
+
puts the colour back on the palette. */
|
|
1401
|
+
--button-white-background-default: var(--color-neutral-0);
|
|
1402
|
+
--button-white-background-hover: var(--color-blue-50);
|
|
1403
|
+
--button-white-background-active: var(--color-blue-100);
|
|
1404
|
+
/* blue-600 by name, not --color-text-brand. The preset is fixed --
|
|
1405
|
+
a white fill on a brand band, in any theme -- so its ink must be
|
|
1406
|
+
fixed too. Reading the role mixed a fill that never switches with a
|
|
1407
|
+
label that does: text-brand goes light in a dark theme and measured
|
|
1408
|
+
2.36:1 on the white fill (dark mode finding 8). */
|
|
1409
|
+
--button-white-text-default: var(--color-blue-600);
|
|
1410
|
+
|
|
1411
|
+
--button-outline-white-text-default: var(--color-action-on-fill);
|
|
1412
|
+
/* 71% rather than 55%. This edge is the only thing bounding an
|
|
1413
|
+
outline-white button, so it carries the 3:1 of WCAG 1.4.11 on its
|
|
1414
|
+
own. Measured over the grounds the preset is actually used on, 55%
|
|
1415
|
+
gave 2.34 on blue-500 and 2.90 on blue-600 and only cleared on
|
|
1416
|
+
blue-700 at 3.65. 71% is the lowest value that clears all three
|
|
1417
|
+
with one number, so the token stops depending on which blue is
|
|
1418
|
+
behind it. */
|
|
1419
|
+
--button-outline-white-border-default: color-mix(in srgb, var(--color-neutral-0) 71%, transparent);
|
|
1420
|
+
/* Hover and press DARKEN the band, they do not wash it white. A white
|
|
1421
|
+
wash lightened the blue under a white label: 3.91:1 on hover and
|
|
1422
|
+
3.38 pressed over blue-500, and 4.22 pressed over blue-600 -- under
|
|
1423
|
+
the 4.5 the label needs. 10% and 20% black take blue-500 to 5.40
|
|
1424
|
+
and 6.49 and give the 71% edge more ground (3.46 and 4.03); every
|
|
1425
|
+
ground the preset sits on now clears, the CTA gradient included.
|
|
1426
|
+
Darker on hover is also what every filled button already does.
|
|
1427
|
+
.
|
|
1428
|
+
The trade-off, chosen knowingly: on the navy end of the CTA
|
|
1429
|
+
gradient (#061a5c) darkening barely shows, a 1.05 step where the
|
|
1430
|
+
white wash gave 1.31. The label is what must pass; the hover there
|
|
1431
|
+
is carried by the cursor. A white wash cannot work on blue-500 at
|
|
1432
|
+
all, where the label clears 4.5 at rest by 0.03. */
|
|
1433
|
+
--button-outline-white-background-hover: color-mix(in srgb, var(--color-neutral-1000) 10%, transparent);
|
|
1434
|
+
--button-outline-white-background-active: color-mix(in srgb, var(--color-neutral-1000) 20%, transparent);
|
|
1435
|
+
|
|
1436
|
+
/* Shared across every variant. Filled kinds go grey; outlined ones keep
|
|
1437
|
+
a transparent fill and take the subtle border. Contrast is exempt
|
|
1438
|
+
here under WCAG 1.4.3.
|
|
1439
|
+
|
|
1440
|
+
borderColor is --color-border-disabled: the role named for the state
|
|
1441
|
+
it expresses, and the one disabled-edge value the whole control
|
|
1442
|
+
family now shares. It read neutral-300 once, then moved to
|
|
1443
|
+
neutral-200 to match what the component drew; bd-checkbox and
|
|
1444
|
+
bd-radio have since moved to neutral-300, so token and component
|
|
1445
|
+
agree again -- a step darker, 2.27:1 against the page where
|
|
1446
|
+
neutral-200 gave 1.66, and still lighter than any enabled edge. */
|
|
1447
|
+
--button-disabled-backgroundColor: var(--color-surface-disabled);
|
|
1448
|
+
--button-disabled-borderColor: var(--color-border-disabled);
|
|
1449
|
+
--button-disabled-color: var(--color-text-subtle);
|
|
1450
|
+
|
|
1451
|
+
/* ================================
|
|
1452
|
+
COMPONENT TOKENS - ANNOTATION
|
|
1453
|
+
================================ */
|
|
1454
|
+
|
|
1455
|
+
/* Footnote Tokens */
|
|
1456
|
+
--footnote-reference-fontSize: 0.75em;
|
|
1457
|
+
--footnote-reference-fontWeight: var(--typography-fontWeight-normal);
|
|
1458
|
+
--footnote-reference-lineHeight: 1;
|
|
1459
|
+
--footnote-reference-verticalAlign: super;
|
|
1460
|
+
--footnote-reference-color: inherit;
|
|
1461
|
+
--footnote-reference-marginLeft: 0.1em;
|
|
1462
|
+
--footnote-reference-marginRight: 0.2em;
|
|
1463
|
+
|
|
1464
|
+
/* Citation Tokens */
|
|
1465
|
+
--citation-reference-fontSize: inherit;
|
|
1466
|
+
--citation-reference-fontWeight: var(--typography-fontWeight-normal);
|
|
1467
|
+
--citation-reference-lineHeight: inherit;
|
|
1468
|
+
--citation-reference-color: var(--color-text-brand);
|
|
1469
|
+
--citation-reference-textDecoration: underline;
|
|
1470
|
+
--citation-reference-hover-color: var(--color-text-brand-hover);
|
|
1471
|
+
--citation-reference-hover-textDecoration: none;
|
|
1472
|
+
|
|
1473
|
+
/* Mathematical Notation Tokens */
|
|
1474
|
+
--math-superscript-fontSize: 0.75em;
|
|
1475
|
+
--math-superscript-fontWeight: var(--typography-fontWeight-normal);
|
|
1476
|
+
--math-superscript-lineHeight: 1;
|
|
1477
|
+
--math-superscript-verticalAlign: super;
|
|
1478
|
+
--math-superscript-marginLeft: 0.05em;
|
|
1479
|
+
|
|
1480
|
+
--math-subscript-fontSize: 0.75em;
|
|
1481
|
+
--math-subscript-fontWeight: var(--typography-fontWeight-normal);
|
|
1482
|
+
--math-subscript-lineHeight: 1;
|
|
1483
|
+
--math-subscript-verticalAlign: sub;
|
|
1484
|
+
--math-subscript-marginLeft: 0.05em;
|
|
1485
|
+
|
|
1486
|
+
/* ================================
|
|
1487
|
+
COMPONENT TOKENS - ICON
|
|
1488
|
+
================================ */
|
|
1489
|
+
|
|
1490
|
+
/* Icon Size Tokens */
|
|
1491
|
+
--icon-xs-size: var(--dimension-12);
|
|
1492
|
+
--icon-sm-size: var(--dimension-16);
|
|
1493
|
+
--icon-md-size: var(--dimension-20);
|
|
1494
|
+
--icon-lg-size: var(--dimension-24);
|
|
1495
|
+
--icon-xl-size: var(--dimension-32);
|
|
1496
|
+
--icon-2xl-size: var(--dimension-48);
|
|
1497
|
+
--icon-3xl-size: var(--dimension-64);
|
|
1498
|
+
|
|
1499
|
+
/* The context aliases (--icon-button-*, --icon-form-*) and the ten
|
|
1500
|
+
--icon-*-color tokens were removed when the icon elements moved onto
|
|
1501
|
+
the size scale and currentColor. The aliases said the same thing as a
|
|
1502
|
+
step — --icon-button-small-size and --icon-sm-size were both 16px —
|
|
1503
|
+
and the colours described states an icon no longer has: it takes the
|
|
1504
|
+
colour of the text it sits in, so there is nothing per-state to keep
|
|
1505
|
+
in step. */
|
|
1506
|
+
|
|
1507
|
+
/* ================================
|
|
1508
|
+
CORE SPACING TOKENS
|
|
1509
|
+
================================ */
|
|
1510
|
+
|
|
1511
|
+
--spacing-0: 0;
|
|
1512
|
+
--spacing-1: 0.0625rem; /* 1px */
|
|
1513
|
+
--spacing-2: 0.125rem; /* 2px */
|
|
1514
|
+
--spacing-4: 0.25rem; /* 4px */
|
|
1515
|
+
--spacing-6: 0.375rem; /* 6px */
|
|
1516
|
+
--spacing-8: 0.5rem; /* 8px */
|
|
1517
|
+
--spacing-10: 0.625rem; /* 10px */
|
|
1518
|
+
--spacing-12: 0.75rem; /* 12px */
|
|
1519
|
+
--spacing-14: 0.875rem; /* 14px */
|
|
1520
|
+
--spacing-16: 1rem; /* 16px */
|
|
1521
|
+
--spacing-18: 1.125rem; /* 18px */
|
|
1522
|
+
--spacing-20: 1.25rem; /* 20px */
|
|
1523
|
+
--spacing-22: 1.375rem; /* 22px */
|
|
1524
|
+
--spacing-24: 1.5rem; /* 24px */
|
|
1525
|
+
--spacing-28: 1.75rem; /* 28px */
|
|
1526
|
+
--spacing-32: 2rem; /* 32px */
|
|
1527
|
+
--spacing-36: 2.25rem; /* 36px */
|
|
1528
|
+
--spacing-40: 2.5rem; /* 40px */
|
|
1529
|
+
--spacing-44: 2.75rem; /* 44px */
|
|
1530
|
+
--spacing-48: 3rem; /* 48px */
|
|
1531
|
+
--spacing-52: 3.25rem; /* 52px */
|
|
1532
|
+
--spacing-56: 3.5rem; /* 56px */
|
|
1533
|
+
--spacing-64: 4rem; /* 64px */
|
|
1534
|
+
--spacing-80: 5rem; /* 80px */
|
|
1535
|
+
--spacing-96: 6rem; /* 96px */
|
|
1536
|
+
--spacing-112: 7rem; /* 112px */
|
|
1537
|
+
--spacing-128: 8rem; /* 128px */
|
|
1538
|
+
|
|
1539
|
+
/* The OLD VALUES block stood here: --display-*, --heading-*, --body-* and
|
|
1540
|
+
--caption-* as pixel font sizes, and a second spacing vocabulary in
|
|
1541
|
+
--space-*, --padding-*, --container-*, --inset-*, --stack-* and
|
|
1542
|
+
--inline-*. Forty-nine tokens, every one a duplicate of something on
|
|
1543
|
+
a live scale under a different name, and not one of them referenced
|
|
1544
|
+
by any component. They are gone. Type comes from
|
|
1545
|
+
--typography-fontSize-* and the component type tokens above it;
|
|
1546
|
+
spacing comes from --spacing-*. */
|
|
1547
|
+
|
|
1548
|
+
/* Accessibility Spacing Tokens
|
|
1549
|
+
-----------------------------------------------*/
|
|
1550
|
+
/* Touch Target Sizes - WCAG 2.1 Success Criterion 2.5.5 (AAA) and 2.5.8 (AA) */
|
|
1551
|
+
--touch-target-size: 44px; /* Minimum touch target size (44px × 44px) */
|
|
1552
|
+
--touch-target-spacing: 8px; /* Minimum space between touch targets */
|
|
1553
|
+
|
|
1554
|
+
/* Readable Line Lengths - For optimal readability */
|
|
1555
|
+
--content-width-readable: 70ch; /* Approximately 70 characters per line */
|
|
1556
|
+
--content-width-max: 1200px; /* Maximum overall content width */
|
|
1557
|
+
|
|
1558
|
+
/** GRID AND BREAKPOINT TOKENS
|
|
1559
|
+
|
|
1560
|
+
These have no consumer in this package and are kept deliberately.
|
|
1561
|
+
A media condition cannot read a custom property — @media
|
|
1562
|
+
(max-width: var(--breakpoint-sm)) is not valid CSS — so a breakpoint
|
|
1563
|
+
token can never be referenced the way a colour is. It exists so the
|
|
1564
|
+
six values have one place to be read from, by the lint that checks
|
|
1565
|
+
media queries against them and by anything generating CSS. The grid
|
|
1566
|
+
tokens are the same case: a layout that wants them reads them, and
|
|
1567
|
+
nothing in the atom layer does.
|
|
1568
|
+
|
|
1569
|
+
They are the exception. Everything else here that nothing references
|
|
1570
|
+
is dead weight, and the OLD VALUES and FONT TOKENS blocks that used
|
|
1571
|
+
to sit below were removed for exactly that reason.
|
|
1572
|
+
*/
|
|
1573
|
+
/* Grid container max widths */
|
|
1574
|
+
--grid-container-max-xs: 100%; /* mobile full width */
|
|
1575
|
+
--grid-container-max-sm: 540px;
|
|
1576
|
+
--grid-container-max-md: 720px;
|
|
1577
|
+
--grid-container-max-lg: 960px;
|
|
1578
|
+
--grid-container-max-xl: 1140px;
|
|
1579
|
+
--grid-container-max-xxl: 1320px;
|
|
1580
|
+
|
|
1581
|
+
/* Column count (usually 12) */
|
|
1582
|
+
--grid-columns: 12;
|
|
1583
|
+
|
|
1584
|
+
/* Gutter spacing between columns */
|
|
1585
|
+
--grid-gutter-xs: 16px;
|
|
1586
|
+
--grid-gutter-sm: 24px;
|
|
1587
|
+
--grid-gutter-md: 32px;
|
|
1588
|
+
--grid-gutter-lg: 40px;
|
|
1589
|
+
|
|
1590
|
+
/* Container padding (horizontal spacing) */
|
|
1591
|
+
--grid-padding-xs: 16px;
|
|
1592
|
+
--grid-padding-sm: 24px;
|
|
1593
|
+
--grid-padding-md: 32px;
|
|
1594
|
+
--grid-padding-lg: 40px;
|
|
1595
|
+
|
|
1596
|
+
/* Breakpoints */
|
|
1597
|
+
--breakpoint-xs: 0px;
|
|
1598
|
+
--breakpoint-sm: 576px;
|
|
1599
|
+
--breakpoint-md: 768px;
|
|
1600
|
+
--breakpoint-lg: 992px;
|
|
1601
|
+
--breakpoint-xl: 1200px;
|
|
1602
|
+
--breakpoint-xxl: 1400px;
|
|
1603
|
+
/* =====================
|
|
1604
|
+
FONT-FACE DEFINITIONS
|
|
1605
|
+
Intentionally NOT here. @font-face nested inside a :host rule is
|
|
1606
|
+
discarded at parse time, and even at the top level of a shadow-root
|
|
1607
|
+
stylesheet it never reaches document.fonts. Font faces must be
|
|
1608
|
+
loaded in document scope: see src/tokens/fonts.css.
|
|
1609
|
+
====================== */
|
|
1610
|
+
|
|
1611
|
+
/* The FONT TOKENS block stood here: --font-weight-mono-*,
|
|
1612
|
+
--font-weight-sans-*, --font-style-mono-* and --font-style-sans-*.
|
|
1613
|
+
Thirteen tokens duplicating --typography-fontWeight-* under a second
|
|
1614
|
+
name, with regular where the live scale says normal, and nothing
|
|
1615
|
+
consuming any of them. --font-family-mono went earlier, with bd-li.
|
|
1616
|
+
A weight is a weight whichever face it is set in. */
|
|
1617
|
+
|
|
1618
|
+
/* Awards section — Orbit Frame 14 (node 1882:9342) */
|
|
1619
|
+
--layout-awards-section-background: var(--color-blue-50);
|
|
1620
|
+
--layout-awards-banner-max-width: 37.5rem; /* legacy narrow cap; prefer cluster */
|
|
1621
|
+
--layout-awards-cluster-max-width: 49.5625rem; /* 793px — trust banner column */
|
|
1622
|
+
--layout-awards-intro-max-width: 39.4375rem; /* 631px — headline stack */
|
|
1623
|
+
/* Legacy: narrow lower block from Orbit; prefer --layout-ensemble-content-max for compare-aligned grids */
|
|
1624
|
+
--layout-awards-content-max-width: 53.0625rem; /* 849px */
|
|
1625
|
+
/* There is no page-width token. The page column is an implementation --
|
|
1626
|
+
src/components/shared/ensemble.css.js -- on the grid container scale
|
|
1627
|
+
above (--grid-container-max-* with --grid-padding-*), which is what
|
|
1628
|
+
Foundations/Grid System documented and nothing had built. A width token
|
|
1629
|
+
here is how six ensembles came to hold one literal each and seven other
|
|
1630
|
+
modules a different one. This padding step stays only because the blog
|
|
1631
|
+
still reads it. */
|
|
1632
|
+
--layout-ensemble-inline-padding: var(--spacing-24);
|
|
1633
|
+
|
|
1634
|
+
|
|
991
1635
|
}
|
|
992
|
-
|
|
993
|
-
@font-face {
|
|
994
|
-
font-family: "IBMPlexSans";
|
|
995
|
-
font-style: italic;
|
|
996
|
-
font-weight: 500;
|
|
997
|
-
src: url("/assets/fonts/IBMPlexSans-Medium.woff2") format("woff2");
|
|
998
|
-
}
|
|
999
|
-
@font-face {
|
|
1000
|
-
font-family: "IBMPlexSans";
|
|
1001
|
-
font-style: italic;
|
|
1002
|
-
font-weight: 500;
|
|
1003
|
-
src: url("/assets/fonts/IBMPlexSans-MediumItalic.woff2") format("woff2");
|
|
1004
|
-
}
|
|
1005
|
-
@font-face {
|
|
1006
|
-
font-family: "IBMPlexSans";
|
|
1007
|
-
font-style: italic;
|
|
1008
|
-
font-weight: 400;
|
|
1009
|
-
src: url("/assets/fonts/IBMPlexSans-Regular.woff2") format("woff2");
|
|
1010
|
-
}
|
|
1011
|
-
@font-face {
|
|
1012
|
-
font-family: "IBMPlexSans";
|
|
1013
|
-
font-style: italic;
|
|
1014
|
-
font-weight: 600;
|
|
1015
|
-
src: url("/assets/fonts/IBMPlexSans-SemiBold.woff2") format("woff2");
|
|
1016
|
-
}
|
|
1017
|
-
@font-face {
|
|
1018
|
-
font-family: "IBMPlexSans";
|
|
1019
|
-
font-style: italic;
|
|
1020
|
-
font-weight: 600;
|
|
1021
|
-
src: url("/assets/fonts/IBMPlexSans-SemiBoldItalic.woff2") format("woff2");
|
|
1022
|
-
}
|
|
1023
|
-
|
|
1024
|
-
/* =====================
|
|
1025
|
-
FONT TOKENS
|
|
1026
|
-
====================== */
|
|
1027
|
-
/* IBM Plex Mono */
|
|
1028
|
-
--font-family-mono: "IBM Plex Mono", monospace;
|
|
1029
|
-
--font-weight-mono-light: 300;
|
|
1030
|
-
--font-weight-mono-regular: 400;
|
|
1031
|
-
--font-weight-mono-medium: 500;
|
|
1032
|
-
--font-weight-mono-semibold: 600;
|
|
1033
|
-
--font-weight-mono-bold: 700;
|
|
1034
|
-
|
|
1035
|
-
--font-style-mono-normal: normal;
|
|
1036
|
-
--font-style-mono-italic: italic;
|
|
1037
|
-
|
|
1038
|
-
/* IBMPlexSans */
|
|
1039
|
-
--typography-fontFamily-sans: "IBM Plex Sans", sans-serif;
|
|
1040
|
-
--font-weight-sans-light: 300;
|
|
1041
|
-
--typography-body-large-fontWeight: 400;
|
|
1042
|
-
--font-weight-sans-medium: 500;
|
|
1043
|
-
--typography-fontWeight-semibold: 600;
|
|
1044
|
-
--typography-fontWeight-bold: 700;
|
|
1045
|
-
|
|
1046
|
-
--font-style-sans-normal: normal;
|
|
1047
|
-
--font-style-sans-italic: italic;
|
|
1048
1636
|
}
|