@boostdev/design-system-components 0.1.18 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/AGENTS.md +65 -27
  2. package/README.md +64 -29
  3. package/dist/client.cjs +412 -241
  4. package/dist/client.css +1378 -1186
  5. package/dist/client.d.cts +43 -16
  6. package/dist/client.d.ts +43 -16
  7. package/dist/client.js +414 -245
  8. package/dist/index.cjs +412 -241
  9. package/dist/index.css +1378 -1186
  10. package/dist/index.d.cts +43 -16
  11. package/dist/index.d.ts +43 -16
  12. package/dist/index.js +414 -245
  13. package/package.json +9 -4
  14. package/src/components/interaction/Button/Button.mdx +2 -5
  15. package/src/components/interaction/Button/Button.module.css +74 -44
  16. package/src/components/interaction/Button/Button.stories.tsx +4 -4
  17. package/src/components/interaction/Button/Button.tsx +5 -5
  18. package/src/components/interaction/Button/index.ts +1 -0
  19. package/src/components/interaction/Command/Command.module.css +53 -38
  20. package/src/components/interaction/Command/Command.spec.tsx +24 -0
  21. package/src/components/interaction/Command/Command.tsx +5 -0
  22. package/src/components/interaction/Dialog/Dialog.mdx +2 -2
  23. package/src/components/interaction/Dialog/Dialog.module.css +20 -10
  24. package/src/components/interaction/Dialog/Dialog.spec.tsx +19 -0
  25. package/src/components/interaction/Dialog/Dialog.tsx +22 -0
  26. package/src/components/interaction/Drawer/Drawer.module.css +11 -11
  27. package/src/components/interaction/Drawer/Drawer.spec.tsx +30 -0
  28. package/src/components/interaction/Drawer/Drawer.tsx +7 -3
  29. package/src/components/interaction/DropdownMenu/DropdownMenu.module.css +24 -19
  30. package/src/components/interaction/DropdownMenu/DropdownMenu.stories.tsx +4 -4
  31. package/src/components/interaction/Popover/Popover.module.css +17 -12
  32. package/src/components/interaction/Popover/Popover.spec.tsx +25 -4
  33. package/src/components/interaction/Popover/Popover.stories.tsx +1 -1
  34. package/src/components/interaction/Popover/Popover.tsx +5 -2
  35. package/src/components/interaction/Rating/Rating.module.css +3 -3
  36. package/src/components/interaction/Toast/Toast.module.css +19 -19
  37. package/src/components/interaction/Toast/Toast.tsx +1 -1
  38. package/src/components/interaction/form/Checkbox/Checkbox.mdx +2 -2
  39. package/src/components/interaction/form/Checkbox/Checkbox.module.css +22 -18
  40. package/src/components/interaction/form/Checkbox/Checkbox.tsx +2 -2
  41. package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.module.css +29 -0
  42. package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.spec.tsx +87 -0
  43. package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.stories.tsx +62 -0
  44. package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.tsx +46 -0
  45. package/src/components/interaction/form/CheckboxGroup/index.ts +2 -0
  46. package/src/components/interaction/form/Combobox/Combobox.module.css +44 -34
  47. package/src/components/interaction/form/Combobox/Combobox.tsx +0 -1
  48. package/src/components/interaction/form/FileInput/FileInput.module.css +24 -16
  49. package/src/components/interaction/form/FileInput/FileInput.tsx +5 -2
  50. package/src/components/interaction/form/FormInput/FormInput.module.css +21 -16
  51. package/src/components/interaction/form/FormInput/FormInput.tsx +3 -0
  52. package/src/components/interaction/form/NumberInput/NumberInput.module.css +25 -19
  53. package/src/components/interaction/form/NumberInput/NumberInput.tsx +5 -2
  54. package/src/components/interaction/form/Radio/Radio.mdx +3 -3
  55. package/src/components/interaction/form/Radio/Radio.module.css +28 -24
  56. package/src/components/interaction/form/Radio/Radio.stories.tsx +1 -1
  57. package/src/components/interaction/form/Radio/Radio.tsx +2 -2
  58. package/src/components/interaction/form/RadioGroup/RadioGroup.module.css +29 -0
  59. package/src/components/interaction/form/RadioGroup/RadioGroup.spec.tsx +75 -0
  60. package/src/components/interaction/form/RadioGroup/RadioGroup.stories.tsx +64 -0
  61. package/src/components/interaction/form/RadioGroup/RadioGroup.tsx +46 -0
  62. package/src/components/interaction/form/RadioGroup/index.ts +2 -0
  63. package/src/components/interaction/form/SegmentedControl/SegmentedControl.mdx +5 -5
  64. package/src/components/interaction/form/SegmentedControl/SegmentedControl.module.css +26 -26
  65. package/src/components/interaction/form/SegmentedControl/SegmentedControl.tsx +4 -0
  66. package/src/components/interaction/form/Select/Select.module.css +24 -19
  67. package/src/components/interaction/form/Select/Select.tsx +3 -0
  68. package/src/components/interaction/form/Slider/Slider.mdx +1 -1
  69. package/src/components/interaction/form/Slider/Slider.module.css +24 -24
  70. package/src/components/interaction/form/Slider/Slider.tsx +1 -0
  71. package/src/components/interaction/form/Switch/Switch.mdx +4 -4
  72. package/src/components/interaction/form/Switch/Switch.module.css +22 -16
  73. package/src/components/interaction/form/Switch/Switch.tsx +1 -1
  74. package/src/components/interaction/form/Textarea/Textarea.module.css +23 -18
  75. package/src/components/interaction/form/Textarea/Textarea.tsx +3 -0
  76. package/src/components/interaction/form/atoms/InputContainer.module.css +2 -2
  77. package/src/components/interaction/form/atoms/Label.module.css +2 -2
  78. package/src/components/interaction/form/atoms/Message.module.css +2 -2
  79. package/src/components/layout/ButtonGroup/ButtonGroup.module.css +2 -2
  80. package/src/components/layout/ButtonGroup/ButtonGroup.stories.tsx +2 -2
  81. package/src/components/layout/ButtonGroup/ButtonGroup.tsx +8 -3
  82. package/src/components/layout/ButtonGroup/index.ts +1 -0
  83. package/src/components/layout/Card/Card.module.css +30 -16
  84. package/src/components/layout/Card/Card.tsx +1 -1
  85. package/src/components/layout/IconWrapper/IconWrapper.mdx +2 -2
  86. package/src/components/layout/IconWrapper/IconWrapper.module.css +5 -5
  87. package/src/components/layout/IconWrapper/IconWrapper.tsx +4 -3
  88. package/src/components/layout/IconWrapper/index.ts +1 -0
  89. package/src/components/layout/SectionHeader/SectionHeader.module.css +23 -23
  90. package/src/components/layout/SectionHeader/SectionHeader.spec.tsx +2 -2
  91. package/src/components/layout/SectionHeader/SectionHeader.tsx +2 -2
  92. package/src/components/ui/Accordion/Accordion.module.css +23 -18
  93. package/src/components/ui/Alert/Alert.module.css +31 -27
  94. package/src/components/ui/Avatar/Avatar.module.css +6 -6
  95. package/src/components/ui/Avatar/Avatar.tsx +1 -1
  96. package/src/components/ui/Badge/Badge.mdx +2 -2
  97. package/src/components/ui/Badge/Badge.module.css +15 -15
  98. package/src/components/ui/Breadcrumb/Breadcrumb.module.css +11 -11
  99. package/src/components/ui/Calendar/Calendar.module.css +39 -29
  100. package/src/components/ui/Calendar/Calendar.tsx +6 -2
  101. package/src/components/ui/Carousel/Carousel.module.css +15 -10
  102. package/src/components/ui/Carousel/Carousel.stories.tsx +1 -1
  103. package/src/components/ui/Collapsible/Collapsible.mdx +6 -6
  104. package/src/components/ui/Collapsible/Collapsible.module.css +18 -18
  105. package/src/components/ui/DescriptionList/DescriptionList.module.css +8 -8
  106. package/src/components/ui/Link/Link.module.css +14 -14
  107. package/src/components/ui/Loading/Loading.module.css +8 -2
  108. package/src/components/ui/NotificationBanner/NotificationBanner.module.css +27 -23
  109. package/src/components/ui/Pagination/Pagination.module.css +22 -17
  110. package/src/components/ui/Progress/Progress.mdx +1 -1
  111. package/src/components/ui/Progress/Progress.module.css +10 -10
  112. package/src/components/ui/ProgressCircle/ProgressCircle.module.css +8 -8
  113. package/src/components/ui/Separator/Separator.module.css +1 -1
  114. package/src/components/ui/Separator/Separator.tsx +1 -1
  115. package/src/components/ui/Skeleton/Skeleton.module.css +5 -5
  116. package/src/components/ui/SkipLink/SkipLink.module.css +17 -12
  117. package/src/components/ui/Table/Table.module.css +35 -30
  118. package/src/components/ui/Table/Table.tsx +2 -1
  119. package/src/components/ui/Tabs/Tabs.module.css +17 -17
  120. package/src/components/ui/Tabs/Tabs.tsx +0 -1
  121. package/src/components/ui/Tooltip/Tooltip.module.css +12 -12
  122. package/src/components/ui/Tooltip/Tooltip.spec.tsx +3 -3
  123. package/src/components/ui/Tooltip/Tooltip.tsx +10 -2
  124. package/src/components/ui/Typography/Typography.module.css +18 -18
  125. package/src/css/bdc.css +61 -0
  126. package/src/css/index.css +5 -0
  127. package/src/index.ts +7 -0
  128. package/src/stories/DesignSystem/Borders.mdx +158 -0
  129. package/src/stories/DesignSystem/Colors.mdx +196 -0
  130. package/src/stories/DesignSystem/Elevation.mdx +127 -0
  131. package/src/stories/DesignSystem/Grid.mdx +140 -0
  132. package/src/stories/DesignSystem/Motion.mdx +96 -0
  133. package/src/stories/DesignSystem/Overview.mdx +99 -0
  134. package/src/stories/DesignSystem/Spacing.mdx +74 -0
  135. package/src/stories/DesignSystem/Typography.mdx +110 -0
  136. package/src/stories/Introduction.css +2 -2
  137. package/src/stories/Introduction.mdx +7 -7
@@ -0,0 +1,196 @@
1
+ import { Meta } from '@storybook/blocks';
2
+
3
+ <Meta title="Design System/Colors" />
4
+
5
+ export const Swatch = ({ label, bg, text, token }) => (
6
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem', minWidth: '9rem' }}>
7
+ <div style={{
8
+ background: bg,
9
+ color: text,
10
+ height: '4rem',
11
+ borderRadius: '0.5rem',
12
+ border: '1px solid rgba(0,0,0,0.08)',
13
+ display: 'flex',
14
+ alignItems: 'flex-end',
15
+ padding: '0.375rem 0.5rem',
16
+ fontSize: '0.7rem',
17
+ fontFamily: 'monospace',
18
+ gap: '0.25rem',
19
+ }}>
20
+ {text && <span style={{ opacity: 0.8 }}>Aa</span>}
21
+ </div>
22
+ <div style={{ fontSize: '0.75rem', lineHeight: 1.3 }}>
23
+ <div style={{ fontWeight: 600 }}>{label}</div>
24
+ <div style={{ fontFamily: 'monospace', opacity: 0.65, fontSize: '0.7rem' }}>{token}</div>
25
+ </div>
26
+ </div>
27
+ );
28
+
29
+ export const SwatchRow = ({ children }) => (
30
+ <div style={{ display: 'flex', flexWrap: 'wrap', gap: '1rem', marginBottom: '2rem' }}>
31
+ {children}
32
+ </div>
33
+ );
34
+
35
+ export const TokenRow = ({ token, description }) => (
36
+ <tr>
37
+ <td><code>{token}</code></td>
38
+ <td>
39
+ <div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
40
+ <div style={{ width: '1.5rem', height: '1.5rem', background: `var(${token})`, borderRadius: '0.25rem', border: '1px solid rgba(0,0,0,0.1)', flexShrink: 0 }} />
41
+ {description}
42
+ </div>
43
+ </td>
44
+ </tr>
45
+ );
46
+
47
+ # Colours
48
+
49
+ Colours are the most visible part of the design system.
50
+ Every colour token comes in surface–content pairs: for every `--bds-*` there is a `--bds-on-*` that guarantees WCAG AA contrast.
51
+
52
+ ```css
53
+ .badge {
54
+ background-color: var(--bds-success--subtle);
55
+ color: var(--bds-on-success--subtle); /* always legible */
56
+ }
57
+ ```
58
+
59
+ ## Semantic colours
60
+
61
+ These are the tokens you should use in component CSS. They adapt automatically to light and dark mode.
62
+
63
+ ### Brand & intent
64
+
65
+ <SwatchRow>
66
+ <Swatch label="CTA / Active" token="--bds-cta" bg="var(--bds-cta)" text="var(--bds-on-cta)" />
67
+ <Swatch label="Interactive" token="--bds-interactive" bg="var(--bds-interactive)" text="var(--bds-on-interactive)" />
68
+ <Swatch label="Brand" token="--bds-brand" bg="var(--bds-brand)" text="var(--bds-on-brand)" />
69
+ </SwatchRow>
70
+
71
+ ### Status
72
+
73
+ <SwatchRow>
74
+ <Swatch label="Success" token="--bds-success" bg="var(--bds-success)" text="var(--bds-on-success)" />
75
+ <Swatch label="Warning" token="--bds-warning" bg="var(--bds-warning)" text="var(--bds-on-warning)" />
76
+ <Swatch label="Error" token="--bds-error" bg="var(--bds-error)" text="var(--bds-on-error)" />
77
+ <Swatch label="Important" token="--bds-important" bg="var(--bds-important)" text="var(--bds-on-important)" />
78
+ </SwatchRow>
79
+
80
+ ### Surface
81
+
82
+ <SwatchRow>
83
+ <Swatch label="Background" token="--bds-bg" bg="var(--bds-bg)" text="var(--bds-on-bg)" />
84
+ <Swatch label="Subtle background" token="--bds-bg--subtle" bg="var(--bds-bg--subtle)" text="var(--bds-on-bg--subtle)" />
85
+ </SwatchRow>
86
+
87
+ ### Neutral grey scale
88
+
89
+ <SwatchRow>
90
+ <Swatch label="Grey subtle" token="--bds-grey--subtle" bg="var(--bds-grey--subtle)" text="var(--bds-on-grey--subtle)" />
91
+ <Swatch label="Grey" token="--bds-grey" bg="var(--bds-grey)" text="var(--bds-on-grey)" />
92
+ <Swatch label="Grey strong" token="--bds-grey--strong" bg="var(--bds-grey--strong)" text="var(--bds-on-grey--strong)" />
93
+ </SwatchRow>
94
+
95
+ ### Green scale
96
+
97
+ <SwatchRow>
98
+ <Swatch label="Green subtle" token="--bds-green--subtle" bg="var(--bds-green--subtle)" text="var(--bds-on-green--subtle)" />
99
+ <Swatch label="Green" token="--bds-green" bg="var(--bds-green)" text="var(--bds-on-green)" />
100
+ <Swatch label="Green strong" token="--bds-green--strong" bg="var(--bds-green--strong)" text="var(--bds-on-green--strong)" />
101
+ </SwatchRow>
102
+
103
+ ### Blue scale
104
+
105
+ <SwatchRow>
106
+ <Swatch label="Blue subtle" token="--bds-blue--subtle" bg="var(--bds-blue--subtle)" text="var(--bds-on-blue--subtle)" />
107
+ <Swatch label="Blue" token="--bds-blue" bg="var(--bds-blue)" text="var(--bds-on-blue)" />
108
+ <Swatch label="Blue strong" token="--bds-blue--strong" bg="var(--bds-blue--strong)" text="var(--bds-on-blue--strong)" />
109
+ </SwatchRow>
110
+
111
+ ### Orange scale
112
+
113
+ <SwatchRow>
114
+ <Swatch label="Orange subtle" token="--bds-orange--subtle" bg="var(--bds-orange--subtle)" text="var(--bds-on-orange--subtle)" />
115
+ <Swatch label="Orange" token="--bds-orange" bg="var(--bds-orange)" text="var(--bds-on-orange)" />
116
+ <Swatch label="Orange strong" token="--bds-orange--strong" bg="var(--bds-orange--strong)" text="var(--bds-on-orange--strong)" />
117
+ </SwatchRow>
118
+
119
+ ---
120
+
121
+ ## Base palette
122
+
123
+ These `--bds-BASE__color--*` tokens are the primitive values. **Do not use them directly** in component CSS — always use semantic tokens so themes work correctly.
124
+
125
+ ### Grey
126
+
127
+ <SwatchRow>
128
+ <Swatch label="grey-100" token="--bds-BASE__color--grey--100" bg="var(--bds-BASE__color--grey--100)" />
129
+ <Swatch label="grey-200" token="--bds-BASE__color--grey--200" bg="var(--bds-BASE__color--grey--200)" />
130
+ <Swatch label="grey-300" token="--bds-BASE__color--grey--300" bg="var(--bds-BASE__color--grey--300)" />
131
+ <Swatch label="grey-400" token="--bds-BASE__color--grey--400" bg="var(--bds-BASE__color--grey--400)" />
132
+ <Swatch label="grey-500" token="--bds-BASE__color--grey" bg="var(--bds-BASE__color--grey)" text="white" />
133
+ <Swatch label="grey-600" token="--bds-BASE__color--grey--600" bg="var(--bds-BASE__color--grey--600)" text="white" />
134
+ <Swatch label="grey-700" token="--bds-BASE__color--grey--700" bg="var(--bds-BASE__color--grey--700)" text="white" />
135
+ <Swatch label="grey-800" token="--bds-BASE__color--grey--800" bg="var(--bds-BASE__color--grey--800)" text="white" />
136
+ <Swatch label="grey-900" token="--bds-BASE__color--grey--900" bg="var(--bds-BASE__color--grey--900)" text="white" />
137
+ </SwatchRow>
138
+
139
+ ### Green
140
+
141
+ <SwatchRow>
142
+ <Swatch label="green-100" token="--bds-BASE__color--green--100" bg="var(--bds-BASE__color--green--100)" />
143
+ <Swatch label="green-200" token="--bds-BASE__color--green--200" bg="var(--bds-BASE__color--green--200)" />
144
+ <Swatch label="green-300" token="--bds-BASE__color--green--300" bg="var(--bds-BASE__color--green--300)" />
145
+ <Swatch label="green-400" token="--bds-BASE__color--green--400" bg="var(--bds-BASE__color--green--400)" />
146
+ <Swatch label="green-500" token="--bds-BASE__color--green" bg="var(--bds-BASE__color--green)" />
147
+ <Swatch label="green-600" token="--bds-BASE__color--green--600" bg="var(--bds-BASE__color--green--600)" />
148
+ <Swatch label="green-700" token="--bds-BASE__color--green--700" bg="var(--bds-BASE__color--green--700)" text="white" />
149
+ <Swatch label="green-800" token="--bds-BASE__color--green--800" bg="var(--bds-BASE__color--green--800)" text="white" />
150
+ <Swatch label="green-900" token="--bds-BASE__color--green--900" bg="var(--bds-BASE__color--green--900)" text="white" />
151
+ </SwatchRow>
152
+
153
+ ### Blue
154
+
155
+ <SwatchRow>
156
+ <Swatch label="blue-100" token="--bds-BASE__color--blue--100" bg="var(--bds-BASE__color--blue--100)" />
157
+ <Swatch label="blue-200" token="--bds-BASE__color--blue--200" bg="var(--bds-BASE__color--blue--200)" />
158
+ <Swatch label="blue-300" token="--bds-BASE__color--blue--300" bg="var(--bds-BASE__color--blue--300)" />
159
+ <Swatch label="blue-400" token="--bds-BASE__color--blue--400" bg="var(--bds-BASE__color--blue--400)" />
160
+ <Swatch label="blue-500" token="--bds-BASE__color--blue" bg="var(--bds-BASE__color--blue)" text="white" />
161
+ <Swatch label="blue-600" token="--bds-BASE__color--blue--600" bg="var(--bds-BASE__color--blue--600)" text="white" />
162
+ <Swatch label="blue-700" token="--bds-BASE__color--blue--700" bg="var(--bds-BASE__color--blue--700)" text="white" />
163
+ <Swatch label="blue-800" token="--bds-BASE__color--blue--800" bg="var(--bds-BASE__color--blue--800)" text="white" />
164
+ <Swatch label="blue-900" token="--bds-BASE__color--blue--900" bg="var(--bds-BASE__color--blue--900)" text="white" />
165
+ </SwatchRow>
166
+
167
+ ### Orange
168
+
169
+ <SwatchRow>
170
+ <Swatch label="orange-100" token="--bds-BASE__color--orange--100" bg="var(--bds-BASE__color--orange--100)" />
171
+ <Swatch label="orange-200" token="--bds-BASE__color--orange--200" bg="var(--bds-BASE__color--orange--200)" />
172
+ <Swatch label="orange-300" token="--bds-BASE__color--orange--300" bg="var(--bds-BASE__color--orange--300)" />
173
+ <Swatch label="orange-400" token="--bds-BASE__color--orange--400" bg="var(--bds-BASE__color--orange--400)" />
174
+ <Swatch label="orange-500" token="--bds-BASE__color--orange" bg="var(--bds-BASE__color--orange)" />
175
+ <Swatch label="orange-600" token="--bds-BASE__color--orange--600" bg="var(--bds-BASE__color--orange--600)" text="white" />
176
+ <Swatch label="orange-700" token="--bds-BASE__color--orange--700" bg="var(--bds-BASE__color--orange--700)" text="white" />
177
+ <Swatch label="orange-800" token="--bds-BASE__color--orange--800" bg="var(--bds-BASE__color--orange--800)" text="white" />
178
+ <Swatch label="orange-900" token="--bds-BASE__color--orange--900" bg="var(--bds-BASE__color--orange--900)" text="white" />
179
+ </SwatchRow>
180
+
181
+ ---
182
+
183
+ ## Theming
184
+
185
+ Override `--bds-cta` (and its `on-` pair) to change the primary action colour globally:
186
+
187
+ ```css
188
+ @layer tokens.override {
189
+ :root {
190
+ --bds-cta: var(--bds-BASE__color--blue);
191
+ --bds-on-cta: var(--bds-BASE__color--white);
192
+ --bds-interactive: var(--bds-BASE__color--blue);
193
+ --bds-on-interactive: var(--bds-BASE__color--white);
194
+ }
195
+ }
196
+ ```
@@ -0,0 +1,127 @@
1
+ import { Meta } from '@storybook/blocks';
2
+
3
+ <Meta title="Design System/Elevation" />
4
+
5
+ export const ShadowCard = ({ token, label }) => (
6
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '0.75rem', alignItems: 'center' }}>
7
+ <div style={{
8
+ width: '8rem',
9
+ height: '5rem',
10
+ background: 'var(--bds-bg)',
11
+ borderRadius: '0.75rem',
12
+ boxShadow: `var(${token})`,
13
+ }} />
14
+ <div style={{ textAlign: 'center' }}>
15
+ <div style={{ fontSize: '0.8rem', fontWeight: 600 }}>{label}</div>
16
+ <div style={{ fontSize: '0.7rem', fontFamily: 'monospace', opacity: 0.6, marginTop: '0.1rem' }}>{token}</div>
17
+ </div>
18
+ </div>
19
+ );
20
+
21
+ export const RadiusBox = ({ token, label, value }) => (
22
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '0.75rem', alignItems: 'center' }}>
23
+ <div style={{
24
+ width: '4rem',
25
+ height: '4rem',
26
+ background: 'var(--bds-interactive)',
27
+ borderRadius: `var(${token})`,
28
+ opacity: 0.8,
29
+ }} />
30
+ <div style={{ textAlign: 'center' }}>
31
+ <div style={{ fontSize: '0.8rem', fontWeight: 600 }}>{label}</div>
32
+ <div style={{ fontSize: '0.7rem', fontFamily: 'monospace', opacity: 0.6 }}>{token}</div>
33
+ <div style={{ fontSize: '0.7rem', opacity: 0.5 }}>{value}</div>
34
+ </div>
35
+ </div>
36
+ );
37
+
38
+ export const ZRow = ({ token, value, description }) => (
39
+ <tr>
40
+ <td><code>{token}</code></td>
41
+ <td style={{ fontFamily: 'monospace' }}>{value}</td>
42
+ <td>{description}</td>
43
+ </tr>
44
+ );
45
+
46
+ # Elevation
47
+
48
+ ## Shadows
49
+
50
+ Five shadow levels from subtle to dramatic. All values adapt to dark mode (higher opacity for visibility against dark surfaces).
51
+
52
+ <div style={{ display: 'flex', gap: '2.5rem', flexWrap: 'wrap', padding: '2rem', background: 'var(--bds-bg--subtle)', borderRadius: '0.75rem', marginBottom: '2rem' }}>
53
+ <ShadowCard token="--bds-shadow_s" label="Small" />
54
+ <ShadowCard token="--bds-shadow_m" label="Medium" />
55
+ <ShadowCard token="--bds-shadow_l" label="Large" />
56
+ <ShadowCard token="--bds-shadow_xl" label="X-Large" />
57
+ <ShadowCard token="--bds-shadow_2xl" label="2X-Large" />
58
+ </div>
59
+
60
+ | Token | Light mode | Dark mode |
61
+ |-------|-----------|-----------|
62
+ | `--bds-shadow_s` | `0 1px 3px rgba(0,0,0,0.05)` | `0 2px 12px rgba(0,0,0,0.40)` |
63
+ | `--bds-shadow_m` | `0 2px 8px rgba(0,0,0,0.10)` | `0 4px 20px rgba(0,0,0,0.50)` |
64
+ | `--bds-shadow_l` | `0 4px 16px rgba(0,0,0,0.12)` | `0 8px 36px rgba(0,0,0,0.60)` |
65
+ | `--bds-shadow_xl` | `0 8px 24px rgba(0,0,0,0.15)` | `0 8px 28px rgba(0,0,0,0.50)` |
66
+ | `--bds-shadow_2xl` | `0 8px 32px rgba(0,0,0,0.16)` | `0 8px 32px rgba(0,0,0,0.65)` |
67
+
68
+ ---
69
+
70
+ ## Border radius
71
+
72
+ <div style={{ display: 'flex', gap: '2rem', flexWrap: 'wrap', padding: '2rem', background: 'var(--bds-bg--subtle)', borderRadius: '0.75rem', marginBottom: '2rem' }}>
73
+ <RadiusBox token="--bds-border_radius--xs" label="X-Small" value="0.25rem / 4px" />
74
+ <RadiusBox token="--bds-border_radius--s" label="Small" value="0.75rem / 12px" />
75
+ <RadiusBox token="--bds-border_radius--m" label="Medium" value="1rem / 16px" />
76
+ </div>
77
+
78
+ ---
79
+
80
+ ## Outline
81
+
82
+ Used for focus rings on interactive elements.
83
+
84
+ | Token | Value |
85
+ |-------|-------|
86
+ | `--bds-outline_default` | `2px dotted var(--bds-outline_color)` |
87
+ | `--bds-outline_color` | grey-600 (light) / grey-400 (dark) |
88
+ | `--bds-outline_offset` | `2px` |
89
+
90
+ ```css
91
+ .my-button:focus-visible {
92
+ outline: var(--bds-outline_default);
93
+ outline-offset: var(--bds-outline_offset);
94
+ }
95
+ ```
96
+
97
+ ---
98
+
99
+ ## Z-index
100
+
101
+ <table>
102
+ <thead>
103
+ <tr>
104
+ <th>Token</th>
105
+ <th>Value</th>
106
+ <th>Purpose</th>
107
+ </tr>
108
+ </thead>
109
+ <tbody>
110
+ <ZRow token="--bds-z-index_below" value="-1" description="Visually behind the page" />
111
+ <ZRow token="--bds-z-index_base" value="0" description="Default stacking context" />
112
+ <ZRow token="--bds-z-index_above" value="1" description="One step above base" />
113
+ <ZRow token="--bds-z-index_s" value="20" description="Sticky headers, minor overlays" />
114
+ <ZRow token="--bds-z-index_m" value="50" description="Dropdowns, popovers" />
115
+ <ZRow token="--bds-z-index_l" value="100" description="Navigation, drawers" />
116
+ <ZRow token="--bds-z-index_xl" value="200" description="Toasts, critical overlays" />
117
+ <ZRow token="--bds-z-index_dropdown" value="50" description="Role alias → m" />
118
+ <ZRow token="--bds-z-index_popover" value="50" description="Role alias → m" />
119
+ <ZRow token="--bds-z-index_nav" value="100" description="Role alias → l" />
120
+ <ZRow token="--bds-z-index_toast" value="200" description="Role alias → xl" />
121
+ </tbody>
122
+ </table>
123
+
124
+ ```css
125
+ .dropdown { z-index: var(--bds-z-index_dropdown); }
126
+ .toast { z-index: var(--bds-z-index_toast); }
127
+ ```
@@ -0,0 +1,140 @@
1
+ import { Meta } from '@storybook/blocks';
2
+
3
+ <Meta title="Design System/Grid" />
4
+
5
+ export const GridCell = ({ span, label, color = 'var(--bds-interactive)' }) => (
6
+ <div style={{
7
+ gridColumn: span,
8
+ background: color,
9
+ color: 'var(--bds-on-interactive)',
10
+ borderRadius: '0.25rem',
11
+ padding: '0.5rem 0.75rem',
12
+ fontSize: '0.75rem',
13
+ fontFamily: 'monospace',
14
+ opacity: 0.85,
15
+ }}>
16
+ {label}
17
+ </div>
18
+ );
19
+
20
+ export const GridDemo = ({ children }) => (
21
+ <div style={{
22
+ display: 'grid',
23
+ gridTemplateColumns: 'repeat(12, 1fr)',
24
+ gap: '0.5rem',
25
+ padding: '1rem',
26
+ background: 'var(--bds-bg--subtle)',
27
+ borderRadius: '0.5rem',
28
+ marginBottom: '1.5rem',
29
+ }}>
30
+ {children}
31
+ </div>
32
+ );
33
+
34
+ # Grid
35
+
36
+ The grid system is responsive and built entirely on CSS custom properties. It adapts from 4 columns on mobile to 12 columns on large screens.
37
+
38
+ ## Breakpoints
39
+
40
+ | Breakpoint | Columns | Gap |
41
+ |------------|---------|-----|
42
+ | `< 48rem` (mobile) | 4 | 1rem |
43
+ | `48rem+` (tablet) | 8 | 1.5rem |
44
+ | `64rem+` (desktop) | 12 | 2rem |
45
+
46
+ ## Tokens
47
+
48
+ | Token | Description |
49
+ |-------|-------------|
50
+ | `--bds-grid_columns` | Current column count (4 / 8 / 12) |
51
+ | `--bds-grid_gap` | Current gap (1rem / 1.5rem / 2rem) |
52
+ | `--bds-grid_template-columns` | `repeat(var(--bds-grid_columns), minmax(1rem, 1fr))` |
53
+ | `--bds-grid_span-100` | `1 / -1` — full width |
54
+ | `--bds-grid_span-75` | Approx. 75% — 3 of 4, 6 of 8, 9 of 12 columns |
55
+ | `--bds-grid_span-66` | Approx. 66% — 2 of 4 / 5 of 8 / 8 of 12 |
56
+ | `--bds-grid_span-50` | Approx. 50% — 2 / 4 / 6 columns |
57
+ | `--bds-grid_span-33` | Approx. 33% — 1 / 3 / 4 columns |
58
+ | `--bds-grid_span-25` | Approx. 25% — 1 / 2 / 3 columns |
59
+
60
+ ## Visual examples (shown at 12-column scale)
61
+
62
+ ### Full width — `--bds-grid_span-100`
63
+
64
+ <GridDemo>
65
+ <GridCell span="1 / -1" label="span 100%" />
66
+ </GridDemo>
67
+
68
+ ### 75% — `--bds-grid_span-75`
69
+
70
+ <GridDemo>
71
+ <GridCell span="span 9" label="span 75%" />
72
+ <GridCell span="span 3" label="25%" color="var(--bds-grey)" />
73
+ </GridDemo>
74
+
75
+ ### Two thirds — `--bds-grid_span-66`
76
+
77
+ <GridDemo>
78
+ <GridCell span="span 8" label="span 66%" />
79
+ <GridCell span="span 4" label="33%" color="var(--bds-grey)" />
80
+ </GridDemo>
81
+
82
+ ### Half and half — `--bds-grid_span-50`
83
+
84
+ <GridDemo>
85
+ <GridCell span="span 6" label="span 50%" />
86
+ <GridCell span="span 6" label="span 50%" />
87
+ </GridDemo>
88
+
89
+ ### Thirds — `--bds-grid_span-33`
90
+
91
+ <GridDemo>
92
+ <GridCell span="span 4" label="33%" />
93
+ <GridCell span="span 4" label="33%" />
94
+ <GridCell span="span 4" label="33%" />
95
+ </GridDemo>
96
+
97
+ ### Quarters — `--bds-grid_span-25`
98
+
99
+ <GridDemo>
100
+ <GridCell span="span 3" label="25%" />
101
+ <GridCell span="span 3" label="25%" />
102
+ <GridCell span="span 3" label="25%" />
103
+ <GridCell span="span 3" label="25%" />
104
+ </GridDemo>
105
+
106
+ ---
107
+
108
+ ## Utility classes
109
+
110
+ Apply the built-in layout utilities to use the grid system without writing CSS:
111
+
112
+ ```html
113
+ <div class="utl-page-grid"> <!-- full-width stacked outer layout -->
114
+ <main class="utl-main-grid"> <!-- responsive CSS grid with padding + max-width -->
115
+ <div class="utl-column" style="--size: var(--bds-grid_span-66)">
116
+ Two thirds content
117
+ </div>
118
+ <aside class="utl-column" style="--size: var(--bds-grid_span-33)">
119
+ One third sidebar
120
+ </aside>
121
+ </main>
122
+ </div>
123
+ ```
124
+
125
+ ## Custom grid usage
126
+
127
+ ```css
128
+ .my-layout {
129
+ display: grid;
130
+ grid-template-columns: var(--bds-grid_template-columns);
131
+ gap: var(--bds-grid_gap);
132
+ }
133
+
134
+ .sidebar { grid-column: var(--bds-grid_span-25); }
135
+ .main { grid-column: var(--bds-grid_span-75); }
136
+ ```
137
+
138
+ ## Sticky position
139
+
140
+ `--bds-sticky_inset-start: 5rem` — the default top offset for sticky elements (accounts for a fixed nav bar).
@@ -0,0 +1,96 @@
1
+ import { Meta } from '@storybook/blocks';
2
+
3
+ <Meta title="Design System/Motion" />
4
+
5
+ export const AnimDemo = ({ label, token, animationStyle }) => (
6
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '0.75rem', alignItems: 'center' }}>
7
+ <div style={{
8
+ width: '3rem',
9
+ height: '3rem',
10
+ background: 'var(--bds-interactive)',
11
+ borderRadius: '0.5rem',
12
+ animation: animationStyle,
13
+ opacity: 0.9,
14
+ }} />
15
+ <div style={{ textAlign: 'center' }}>
16
+ <div style={{ fontSize: '0.8rem', fontWeight: 600 }}>{label}</div>
17
+ {token && <div style={{ fontSize: '0.7rem', fontFamily: 'monospace', opacity: 0.6 }}>{token}</div>}
18
+ </div>
19
+ </div>
20
+ );
21
+
22
+ # Motion
23
+
24
+ ## Timing tokens
25
+
26
+ | Token | Value | Use |
27
+ |-------|-------|-----|
28
+ | `--bds-animation_easing` | `ease-out` | Default easing for transitions |
29
+ | `--bds-animation_duration--fast` | `150ms` | Micro-interactions, hover states |
30
+ | `--bds-animation_duration--normal` | `350ms` | Panel opens, page transitions |
31
+ | `--bds-animation_transition-duration` | `150ms` | Shorthand duration alias |
32
+ | `--bds-animation_transition` | `all 150ms ease-out` | Single-line transition shorthand |
33
+
34
+ ```css
35
+ .button {
36
+ transition: var(--bds-animation_transition);
37
+ }
38
+
39
+ .panel {
40
+ transition: transform var(--bds-animation_duration--normal) var(--bds-animation_easing);
41
+ }
42
+ ```
43
+
44
+ ---
45
+
46
+ ## Keyframe animations
47
+
48
+ The foundation ships six named keyframes.
49
+
50
+ <div style={{ display: 'flex', gap: '3rem', flexWrap: 'wrap', padding: '2rem', background: 'var(--bds-bg--subtle)', borderRadius: '0.75rem', marginBottom: '2rem' }}>
51
+ <AnimDemo label="bounce" animationStyle="bounce 1s ease-out infinite" />
52
+ <AnimDemo label="rotate" animationStyle="rotate 2s linear infinite" />
53
+ <AnimDemo label="fade-zoom" animationStyle="fade-zoom 2s ease-in-out infinite" />
54
+ <AnimDemo label="slide-to-start" animationStyle="slide-to-start 1.5s ease-in-out infinite alternate" />
55
+ <AnimDemo label="slide-to-end" animationStyle="slide-to-end 1.5s ease-in-out infinite alternate" />
56
+ </div>
57
+
58
+ | Keyframe | Description |
59
+ |----------|-------------|
60
+ | `bounce` | Scale 1 → 0.75 → 1 — attention pulse |
61
+ | `rotate` | 0 → 360deg — continuous spin |
62
+ | `fade-zoom` | Opacity + scale pulse (1,1) → (0.4,1.25) → (1,1) |
63
+ | `slide-to-start` | translateX 0 → -20% |
64
+ | `slide-to-end` | translateX 0 → 20% |
65
+
66
+ ---
67
+
68
+ ## Reduced motion
69
+
70
+ All animations in the library respect `prefers-reduced-motion`. When building custom animations, always add this override:
71
+
72
+ ```css
73
+ @media (prefers-reduced-motion: reduce) {
74
+ .my-animated-element {
75
+ animation: none;
76
+ transition: none;
77
+ }
78
+ }
79
+ ```
80
+
81
+ ---
82
+
83
+ ## Chevron rotation
84
+
85
+ `--bds-animation_chevron-rotate--end: x 180deg`
86
+
87
+ Convenience token for animating a chevron/caret icon into its open/closed state:
88
+
89
+ ```css
90
+ .chevron {
91
+ transition: rotate var(--bds-animation_transition);
92
+ }
93
+ .chevron[data-open="true"] {
94
+ rotate: var(--bds-animation_chevron-rotate--end);
95
+ }
96
+ ```
@@ -0,0 +1,99 @@
1
+ import { Meta } from '@storybook/blocks';
2
+
3
+ <Meta title="Design System/Overview" />
4
+
5
+ # Design System Foundation
6
+
7
+ `@boostdev/design-system-foundation` is the token layer that every component in this library is built on.
8
+ It provides a complete set of CSS custom properties for colour, spacing, typography, grid, elevation, and motion —
9
+ all responsive and theme-aware out of the box.
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ pnpm add @boostdev/design-system-foundation
15
+ ```
16
+
17
+ ## Setup
18
+
19
+ Import the CSS once at your app root. Components rely on these custom properties being present in the document.
20
+
21
+ ```css
22
+ /* app.css */
23
+ @import "@boostdev/design-system-foundation/css";
24
+ ```
25
+
26
+ Or via a JS bundler (Vite, Next.js, etc.):
27
+
28
+ ```ts
29
+ // main.ts / layout.tsx
30
+ import '@boostdev/design-system-foundation/css';
31
+ ```
32
+
33
+ ## What's included
34
+
35
+ | Import | Contents |
36
+ |--------|----------|
37
+ | `/css` | Everything below, bundled |
38
+ | `/css/tokens/color` | Colour palette + semantic colour tokens |
39
+ | `/css/tokens/space` | Spacing scale + container tokens |
40
+ | `/css/tokens/font` | Typography — family, size, weight, line-height, tracking |
41
+ | `/css/tokens/grid` | Responsive grid columns + span helpers |
42
+ | `/css/tokens/border` | Border radius + outline tokens |
43
+ | `/css/tokens/shadow` | Elevation scale (s → 2xl) |
44
+ | `/css/tokens/animations` | Easing, duration, transition shorthand, keyframes |
45
+ | `/css/tokens/z-index` | Z-index scale + named role aliases |
46
+ | `/css/reset` | Minimal CSS reset |
47
+ | `/css/base` | Base element styles (headings, links, body) |
48
+ | `/css/utilities` | Utility classes (grid layout, visually-hidden, etc.) |
49
+
50
+ ## Layer architecture
51
+
52
+ All tokens live inside `@layer` declarations. The cascade order, from lowest to highest, is:
53
+
54
+ ```
55
+ tokens.base → tokens.semantic → tokens.override → reset → base → utilities → component
56
+ ```
57
+
58
+ `@layer component` — used by every component in this library — sits above the token layers,
59
+ so you can override any component from `@layer my-overrides` without specificity fights.
60
+
61
+ ## Theming
62
+
63
+ Tokens adapt automatically to light and dark mode via `data-theme` attribute or `prefers-color-scheme`:
64
+
65
+ ```html
66
+ <!-- explicit themes -->
67
+ <html data-theme="light">
68
+ <html data-theme="dark">
69
+ ```
70
+
71
+ ```css
72
+ /* or CSS-only, no attribute needed */
73
+ @media (prefers-color-scheme: dark) { … }
74
+ ```
75
+
76
+ Override any token in your own layer to retheme:
77
+
78
+ ```css
79
+ @import "@boostdev/design-system-foundation/css";
80
+
81
+ @layer tokens.override {
82
+ :root {
83
+ --bds-cta: var(--bds-BASE__color--blue);
84
+ --bds-on-cta: var(--bds-BASE__color--white);
85
+ }
86
+ }
87
+ ```
88
+
89
+ ## Naming convention
90
+
91
+ ```
92
+ --bds-{group}_{name}--{variant}
93
+ ```
94
+
95
+ - `bds-` prefix = all foundation tokens
96
+ - `_` separates group from name
97
+ - `--` separates name from scale variant
98
+ - `BASE__` prefix = primitive palette (never use directly in component CSS)
99
+ - All semantic tokens are prefixed with `bds-` (e.g. `--bds-bg`, `--bds-interactive`)