@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.
- package/AGENTS.md +65 -27
- package/README.md +64 -29
- package/dist/client.cjs +412 -241
- package/dist/client.css +1378 -1186
- package/dist/client.d.cts +43 -16
- package/dist/client.d.ts +43 -16
- package/dist/client.js +414 -245
- package/dist/index.cjs +412 -241
- package/dist/index.css +1378 -1186
- package/dist/index.d.cts +43 -16
- package/dist/index.d.ts +43 -16
- package/dist/index.js +414 -245
- package/package.json +9 -4
- package/src/components/interaction/Button/Button.mdx +2 -5
- package/src/components/interaction/Button/Button.module.css +74 -44
- package/src/components/interaction/Button/Button.stories.tsx +4 -4
- package/src/components/interaction/Button/Button.tsx +5 -5
- package/src/components/interaction/Button/index.ts +1 -0
- package/src/components/interaction/Command/Command.module.css +53 -38
- package/src/components/interaction/Command/Command.spec.tsx +24 -0
- package/src/components/interaction/Command/Command.tsx +5 -0
- package/src/components/interaction/Dialog/Dialog.mdx +2 -2
- package/src/components/interaction/Dialog/Dialog.module.css +20 -10
- package/src/components/interaction/Dialog/Dialog.spec.tsx +19 -0
- package/src/components/interaction/Dialog/Dialog.tsx +22 -0
- package/src/components/interaction/Drawer/Drawer.module.css +11 -11
- package/src/components/interaction/Drawer/Drawer.spec.tsx +30 -0
- package/src/components/interaction/Drawer/Drawer.tsx +7 -3
- package/src/components/interaction/DropdownMenu/DropdownMenu.module.css +24 -19
- package/src/components/interaction/DropdownMenu/DropdownMenu.stories.tsx +4 -4
- package/src/components/interaction/Popover/Popover.module.css +17 -12
- package/src/components/interaction/Popover/Popover.spec.tsx +25 -4
- package/src/components/interaction/Popover/Popover.stories.tsx +1 -1
- package/src/components/interaction/Popover/Popover.tsx +5 -2
- package/src/components/interaction/Rating/Rating.module.css +3 -3
- package/src/components/interaction/Toast/Toast.module.css +19 -19
- package/src/components/interaction/Toast/Toast.tsx +1 -1
- package/src/components/interaction/form/Checkbox/Checkbox.mdx +2 -2
- package/src/components/interaction/form/Checkbox/Checkbox.module.css +22 -18
- package/src/components/interaction/form/Checkbox/Checkbox.tsx +2 -2
- package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.module.css +29 -0
- package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.spec.tsx +87 -0
- package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.stories.tsx +62 -0
- package/src/components/interaction/form/CheckboxGroup/CheckboxGroup.tsx +46 -0
- package/src/components/interaction/form/CheckboxGroup/index.ts +2 -0
- package/src/components/interaction/form/Combobox/Combobox.module.css +44 -34
- package/src/components/interaction/form/Combobox/Combobox.tsx +0 -1
- package/src/components/interaction/form/FileInput/FileInput.module.css +24 -16
- package/src/components/interaction/form/FileInput/FileInput.tsx +5 -2
- package/src/components/interaction/form/FormInput/FormInput.module.css +21 -16
- package/src/components/interaction/form/FormInput/FormInput.tsx +3 -0
- package/src/components/interaction/form/NumberInput/NumberInput.module.css +25 -19
- package/src/components/interaction/form/NumberInput/NumberInput.tsx +5 -2
- package/src/components/interaction/form/Radio/Radio.mdx +3 -3
- package/src/components/interaction/form/Radio/Radio.module.css +28 -24
- package/src/components/interaction/form/Radio/Radio.stories.tsx +1 -1
- package/src/components/interaction/form/Radio/Radio.tsx +2 -2
- package/src/components/interaction/form/RadioGroup/RadioGroup.module.css +29 -0
- package/src/components/interaction/form/RadioGroup/RadioGroup.spec.tsx +75 -0
- package/src/components/interaction/form/RadioGroup/RadioGroup.stories.tsx +64 -0
- package/src/components/interaction/form/RadioGroup/RadioGroup.tsx +46 -0
- package/src/components/interaction/form/RadioGroup/index.ts +2 -0
- package/src/components/interaction/form/SegmentedControl/SegmentedControl.mdx +5 -5
- package/src/components/interaction/form/SegmentedControl/SegmentedControl.module.css +26 -26
- package/src/components/interaction/form/SegmentedControl/SegmentedControl.tsx +4 -0
- package/src/components/interaction/form/Select/Select.module.css +24 -19
- package/src/components/interaction/form/Select/Select.tsx +3 -0
- package/src/components/interaction/form/Slider/Slider.mdx +1 -1
- package/src/components/interaction/form/Slider/Slider.module.css +24 -24
- package/src/components/interaction/form/Slider/Slider.tsx +1 -0
- package/src/components/interaction/form/Switch/Switch.mdx +4 -4
- package/src/components/interaction/form/Switch/Switch.module.css +22 -16
- package/src/components/interaction/form/Switch/Switch.tsx +1 -1
- package/src/components/interaction/form/Textarea/Textarea.module.css +23 -18
- package/src/components/interaction/form/Textarea/Textarea.tsx +3 -0
- package/src/components/interaction/form/atoms/InputContainer.module.css +2 -2
- package/src/components/interaction/form/atoms/Label.module.css +2 -2
- package/src/components/interaction/form/atoms/Message.module.css +2 -2
- package/src/components/layout/ButtonGroup/ButtonGroup.module.css +2 -2
- package/src/components/layout/ButtonGroup/ButtonGroup.stories.tsx +2 -2
- package/src/components/layout/ButtonGroup/ButtonGroup.tsx +8 -3
- package/src/components/layout/ButtonGroup/index.ts +1 -0
- package/src/components/layout/Card/Card.module.css +30 -16
- package/src/components/layout/Card/Card.tsx +1 -1
- package/src/components/layout/IconWrapper/IconWrapper.mdx +2 -2
- package/src/components/layout/IconWrapper/IconWrapper.module.css +5 -5
- package/src/components/layout/IconWrapper/IconWrapper.tsx +4 -3
- package/src/components/layout/IconWrapper/index.ts +1 -0
- package/src/components/layout/SectionHeader/SectionHeader.module.css +23 -23
- package/src/components/layout/SectionHeader/SectionHeader.spec.tsx +2 -2
- package/src/components/layout/SectionHeader/SectionHeader.tsx +2 -2
- package/src/components/ui/Accordion/Accordion.module.css +23 -18
- package/src/components/ui/Alert/Alert.module.css +31 -27
- package/src/components/ui/Avatar/Avatar.module.css +6 -6
- package/src/components/ui/Avatar/Avatar.tsx +1 -1
- package/src/components/ui/Badge/Badge.mdx +2 -2
- package/src/components/ui/Badge/Badge.module.css +15 -15
- package/src/components/ui/Breadcrumb/Breadcrumb.module.css +11 -11
- package/src/components/ui/Calendar/Calendar.module.css +39 -29
- package/src/components/ui/Calendar/Calendar.tsx +6 -2
- package/src/components/ui/Carousel/Carousel.module.css +15 -10
- package/src/components/ui/Carousel/Carousel.stories.tsx +1 -1
- package/src/components/ui/Collapsible/Collapsible.mdx +6 -6
- package/src/components/ui/Collapsible/Collapsible.module.css +18 -18
- package/src/components/ui/DescriptionList/DescriptionList.module.css +8 -8
- package/src/components/ui/Link/Link.module.css +14 -14
- package/src/components/ui/Loading/Loading.module.css +8 -2
- package/src/components/ui/NotificationBanner/NotificationBanner.module.css +27 -23
- package/src/components/ui/Pagination/Pagination.module.css +22 -17
- package/src/components/ui/Progress/Progress.mdx +1 -1
- package/src/components/ui/Progress/Progress.module.css +10 -10
- package/src/components/ui/ProgressCircle/ProgressCircle.module.css +8 -8
- package/src/components/ui/Separator/Separator.module.css +1 -1
- package/src/components/ui/Separator/Separator.tsx +1 -1
- package/src/components/ui/Skeleton/Skeleton.module.css +5 -5
- package/src/components/ui/SkipLink/SkipLink.module.css +17 -12
- package/src/components/ui/Table/Table.module.css +35 -30
- package/src/components/ui/Table/Table.tsx +2 -1
- package/src/components/ui/Tabs/Tabs.module.css +17 -17
- package/src/components/ui/Tabs/Tabs.tsx +0 -1
- package/src/components/ui/Tooltip/Tooltip.module.css +12 -12
- package/src/components/ui/Tooltip/Tooltip.spec.tsx +3 -3
- package/src/components/ui/Tooltip/Tooltip.tsx +10 -2
- package/src/components/ui/Typography/Typography.module.css +18 -18
- package/src/css/bdc.css +61 -0
- package/src/css/index.css +5 -0
- package/src/index.ts +7 -0
- package/src/stories/DesignSystem/Borders.mdx +158 -0
- package/src/stories/DesignSystem/Colors.mdx +196 -0
- package/src/stories/DesignSystem/Elevation.mdx +127 -0
- package/src/stories/DesignSystem/Grid.mdx +140 -0
- package/src/stories/DesignSystem/Motion.mdx +96 -0
- package/src/stories/DesignSystem/Overview.mdx +99 -0
- package/src/stories/DesignSystem/Spacing.mdx +74 -0
- package/src/stories/DesignSystem/Typography.mdx +110 -0
- package/src/stories/Introduction.css +2 -2
- 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`)
|