@codecademy/gamut 68.6.1-alpha.edab62.0 → 68.6.1-alpha.f6b2ce.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/agent-tools/.cursor-plugin/plugin.json +1 -1
- package/agent-tools/DESIGN.Codecademy.md +466 -413
- package/agent-tools/DESIGN.LXStudio.md +350 -282
- package/agent-tools/DESIGN.Percipio.md +357 -279
- package/agent-tools/commands/gamut-review.md +176 -87
- package/agent-tools/guidelines/components/animations.md +74 -0
- package/agent-tools/guidelines/components/buttons.md +74 -23
- package/agent-tools/guidelines/components/card.md +19 -0
- package/agent-tools/guidelines/components/coachmark.md +21 -0
- package/agent-tools/guidelines/components/data-table.md +79 -0
- package/agent-tools/guidelines/components/forms.md +106 -0
- package/agent-tools/guidelines/components/loading-states.md +17 -0
- package/agent-tools/guidelines/components/menu.md +58 -0
- package/agent-tools/guidelines/components/overview.md +97 -17
- package/agent-tools/guidelines/components/radial-progress.md +13 -0
- package/agent-tools/guidelines/components/select.md +23 -0
- package/agent-tools/guidelines/components/tooltips.md +22 -0
- package/agent-tools/guidelines/components/video.md +29 -0
- package/agent-tools/guidelines/foundations/color.md +140 -58
- package/agent-tools/guidelines/foundations/modes.md +41 -17
- package/agent-tools/guidelines/foundations/spacing.md +78 -37
- package/agent-tools/guidelines/foundations/typography.md +69 -37
- package/agent-tools/guidelines/overview-icons.md +19 -0
- package/agent-tools/guidelines/overview-illustrations.md +7 -0
- package/agent-tools/guidelines/overview-patterns.md +7 -0
- package/agent-tools/guidelines/overview.md +71 -22
- package/agent-tools/guidelines/setup.md +59 -18
- package/agent-tools/rules/accessibility.mdc +22 -13
- package/agent-tools/skills/gamut-accessibility/SKILL.md +97 -112
- package/agent-tools/skills/gamut-color-mode/SKILL.md +91 -41
- package/agent-tools/skills/gamut-components/SKILL.md +46 -0
- package/agent-tools/skills/gamut-forms/SKILL.md +101 -0
- package/agent-tools/skills/gamut-style-utilities/SKILL.md +111 -0
- package/agent-tools/skills/gamut-system-props/SKILL.md +81 -29
- package/agent-tools/skills/gamut-testing/SKILL.md +106 -62
- package/agent-tools/skills/gamut-theming/SKILL.md +36 -86
- package/agent-tools/skills/gamut-typography/SKILL.md +36 -80
- package/bin/commands/plugin/install.mjs +96 -56
- package/bin/commands/plugin/list.mjs +11 -43
- package/bin/commands/plugin/remove.mjs +30 -38
- package/bin/commands/plugin/update.mjs +15 -5
- package/bin/gamut.mjs +17 -13
- package/bin/lib/design.mjs +71 -0
- package/bin/lib/io.mjs +14 -0
- package/package.json +6 -6
- package/bin/lib/figma.mjs +0 -49
|
@@ -4,245 +4,301 @@ name: LX Studio Design System
|
|
|
4
4
|
description: Design tokens for the Skillsoft LX Studio authoring platform.
|
|
5
5
|
colors:
|
|
6
6
|
# LX Studio additions — custom brand tokens
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
lxStudioBgPrimary: "#FAFBFC"
|
|
7
|
+
sapphire: '#1C50BB'
|
|
8
|
+
lxStudioSuccess: '#06844F'
|
|
9
|
+
lxStudioBgPrimary: '#FAFBFC'
|
|
11
10
|
# core palette — referenced by semantic aliases below
|
|
12
|
-
hyper-500:
|
|
13
|
-
hyper-400:
|
|
14
|
-
navy-900:
|
|
15
|
-
navy-800:
|
|
16
|
-
navy-700:
|
|
17
|
-
navy-600:
|
|
18
|
-
navy-500:
|
|
19
|
-
navy-400:
|
|
20
|
-
navy-300:
|
|
21
|
-
navy-200:
|
|
22
|
-
navy-100:
|
|
23
|
-
yellow-500:
|
|
24
|
-
yellow-0:
|
|
25
|
-
green-700:
|
|
26
|
-
green-0:
|
|
27
|
-
red-600:
|
|
28
|
-
red-500:
|
|
29
|
-
red-0:
|
|
30
|
-
white:
|
|
11
|
+
hyper-500: '#3A10E5'
|
|
12
|
+
hyper-400: '#5533FF'
|
|
13
|
+
navy-900: '#0A0D1C'
|
|
14
|
+
navy-800: '#10162F'
|
|
15
|
+
navy-700: 'rgba(16, 22, 47, 0.86)'
|
|
16
|
+
navy-600: 'rgba(16, 22, 47, 0.75)'
|
|
17
|
+
navy-500: 'rgba(16, 22, 47, 0.63)'
|
|
18
|
+
navy-400: 'rgba(16, 22, 47, 0.47)'
|
|
19
|
+
navy-300: 'rgba(16, 22, 47, 0.28)'
|
|
20
|
+
navy-200: 'rgba(16, 22, 47, 0.12)'
|
|
21
|
+
navy-100: 'rgba(16, 22, 47, 0.04)'
|
|
22
|
+
yellow-500: '#FFD300'
|
|
23
|
+
yellow-0: '#FFFAE5'
|
|
24
|
+
green-700: '#008A27'
|
|
25
|
+
green-0: '#F5FFE3'
|
|
26
|
+
red-600: '#BE1809'
|
|
27
|
+
red-500: '#E91C11'
|
|
28
|
+
red-0: '#FBF1F0'
|
|
29
|
+
white: '#ffffff'
|
|
31
30
|
# semantic aliases — use these in code, not palette swatches or hex values
|
|
32
|
-
text:
|
|
33
|
-
text-accent:
|
|
34
|
-
text-secondary:
|
|
35
|
-
text-disabled:
|
|
36
|
-
background:
|
|
37
|
-
background-primary:
|
|
38
|
-
background-contrast:
|
|
39
|
-
background-selected:
|
|
40
|
-
background-hover:
|
|
41
|
-
background-disabled:
|
|
42
|
-
background-success:
|
|
43
|
-
background-warning:
|
|
44
|
-
background-error:
|
|
45
|
-
primary:
|
|
46
|
-
primary-hover:
|
|
47
|
-
primary-inverse:
|
|
48
|
-
secondary:
|
|
49
|
-
secondary-hover:
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
feedback-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
border-
|
|
58
|
-
border-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
shadow-primary: "{colors.navy-200}"
|
|
62
|
-
shadow-secondary: "{colors.navy-600}"
|
|
31
|
+
text: '{colors.navy-800}'
|
|
32
|
+
text-accent: '{colors.navy-900}'
|
|
33
|
+
text-secondary: '{colors.navy-600}'
|
|
34
|
+
text-disabled: '{colors.navy-500}'
|
|
35
|
+
background: '{colors.white}'
|
|
36
|
+
background-primary: '{colors.lxStudioBgPrimary}'
|
|
37
|
+
background-contrast: '{colors.white}'
|
|
38
|
+
background-selected: '{colors.navy-100}'
|
|
39
|
+
background-hover: '{colors.navy-200}'
|
|
40
|
+
background-disabled: '{colors.navy-200}'
|
|
41
|
+
background-success: '{colors.green-0}'
|
|
42
|
+
background-warning: '{colors.yellow-0}'
|
|
43
|
+
background-error: '{colors.red-0}'
|
|
44
|
+
primary: '{colors.sapphire}'
|
|
45
|
+
primary-hover: '{colors.navy-800}'
|
|
46
|
+
primary-inverse: '{colors.yellow-500}'
|
|
47
|
+
secondary: '{colors.navy-800}'
|
|
48
|
+
secondary-hover: '{colors.navy-700}'
|
|
49
|
+
danger: '{colors.red-500}'
|
|
50
|
+
danger-hover: '{colors.red-600}'
|
|
51
|
+
feedback-error: '{colors.red-600}'
|
|
52
|
+
feedback-success: '{colors.lxStudioSuccess}'
|
|
53
|
+
feedback-warning: '{colors.yellow-500}'
|
|
54
|
+
border-primary: '{colors.navy-400}'
|
|
55
|
+
border-secondary: '{colors.navy-600}'
|
|
56
|
+
border-tertiary: '{colors.navy-800}'
|
|
57
|
+
border-disabled: '{colors.navy-300}'
|
|
58
|
+
shadow-primary: '{colors.navy-200}'
|
|
59
|
+
shadow-secondary: '{colors.navy-600}'
|
|
63
60
|
typography:
|
|
64
61
|
base:
|
|
65
|
-
fontFamily: '"
|
|
66
|
-
fontSize:
|
|
67
|
-
fontWeight:
|
|
68
|
-
lineHeight:
|
|
62
|
+
fontFamily: '"Skillsoft Text", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif'
|
|
63
|
+
fontSize: '1rem'
|
|
64
|
+
fontWeight: '400'
|
|
65
|
+
lineHeight: '1.5'
|
|
69
66
|
accent:
|
|
70
|
-
fontFamily: '"
|
|
71
|
-
fontSize:
|
|
72
|
-
fontWeight:
|
|
73
|
-
lineHeight:
|
|
67
|
+
fontFamily: '"Skillsoft Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif'
|
|
68
|
+
fontSize: '0.875rem'
|
|
69
|
+
fontWeight: '400'
|
|
70
|
+
lineHeight: '1.5'
|
|
74
71
|
title:
|
|
75
|
-
fontFamily: '"
|
|
76
|
-
fontSize:
|
|
77
|
-
fontWeight:
|
|
78
|
-
lineHeight:
|
|
72
|
+
fontFamily: '"Skillsoft Text", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif'
|
|
73
|
+
fontSize: '2.125rem'
|
|
74
|
+
fontWeight: '500'
|
|
75
|
+
lineHeight: '1.2'
|
|
79
76
|
monospace:
|
|
80
77
|
fontFamily: 'Monaco, Menlo, "Ubuntu Mono", "Droid Sans Mono", Consolas, monospace'
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
78
|
+
system:
|
|
79
|
+
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif'
|
|
80
|
+
'14':
|
|
81
|
+
fontSize: '0.875rem'
|
|
82
|
+
'16':
|
|
83
|
+
fontSize: '1rem'
|
|
84
|
+
'18':
|
|
85
|
+
fontSize: '1.125rem'
|
|
86
|
+
'20':
|
|
87
|
+
fontSize: '1.25rem'
|
|
88
|
+
'22':
|
|
89
|
+
fontSize: '1.375rem'
|
|
90
|
+
'26':
|
|
91
|
+
fontSize: '1.625rem'
|
|
92
|
+
'34':
|
|
93
|
+
fontSize: '2.125rem'
|
|
94
|
+
'44':
|
|
95
|
+
fontSize: '2.75rem'
|
|
96
|
+
'64':
|
|
97
|
+
fontSize: '4rem'
|
|
98
|
+
borderRadii:
|
|
99
|
+
none: '0px'
|
|
100
|
+
sm: '4px'
|
|
101
|
+
md: '8px'
|
|
102
|
+
lg: '12px'
|
|
103
|
+
xl: '16px'
|
|
104
|
+
full: '999px'
|
|
105
|
+
spacing:
|
|
106
|
+
'0': '0'
|
|
107
|
+
'4': '0.25rem'
|
|
108
|
+
'8': '0.5rem'
|
|
109
|
+
'12': '0.75rem'
|
|
110
|
+
'16': '1rem'
|
|
111
|
+
'24': '1.5rem'
|
|
112
|
+
'32': '2rem'
|
|
113
|
+
'40': '2.5rem'
|
|
114
|
+
'48': '3rem'
|
|
115
|
+
'64': '4rem'
|
|
116
|
+
'96': '6rem'
|
|
88
117
|
components:
|
|
89
118
|
FillButton:
|
|
90
|
-
backgroundColor:
|
|
91
|
-
textColor:
|
|
92
|
-
|
|
119
|
+
backgroundColor: '{colors.primary}'
|
|
120
|
+
textColor: '{colors.white}'
|
|
121
|
+
borderRadii: '{borderRadii.md}'
|
|
93
122
|
FillButton-hover:
|
|
94
|
-
backgroundColor:
|
|
95
|
-
textColor:
|
|
123
|
+
backgroundColor: '{colors.primary-hover}'
|
|
124
|
+
textColor: '{colors.white}'
|
|
96
125
|
FillButton-danger:
|
|
97
|
-
backgroundColor:
|
|
98
|
-
textColor:
|
|
99
|
-
|
|
126
|
+
backgroundColor: '{colors.danger}'
|
|
127
|
+
textColor: '{colors.white}'
|
|
128
|
+
borderRadii: '{borderRadii.md}'
|
|
100
129
|
FillButton-danger-hover:
|
|
101
|
-
backgroundColor:
|
|
102
|
-
textColor:
|
|
130
|
+
backgroundColor: '{colors.danger-hover}'
|
|
131
|
+
textColor: '{colors.white}'
|
|
103
132
|
StrokeButton:
|
|
104
|
-
backgroundColor:
|
|
105
|
-
textColor:
|
|
106
|
-
|
|
133
|
+
backgroundColor: 'transparent'
|
|
134
|
+
textColor: '{colors.secondary}'
|
|
135
|
+
borderRadii: '{borderRadii.md}'
|
|
136
|
+
StrokeButton-hover:
|
|
137
|
+
textColor: '{colors.secondary-hover}'
|
|
138
|
+
TextButton:
|
|
139
|
+
backgroundColor: 'transparent'
|
|
140
|
+
textColor: '{colors.primary}'
|
|
141
|
+
TextButton-hover:
|
|
142
|
+
textColor: '{colors.primary-hover}'
|
|
143
|
+
IconButton:
|
|
144
|
+
backgroundColor: 'transparent'
|
|
145
|
+
textColor: '{colors.secondary}'
|
|
146
|
+
IconButton-hover:
|
|
147
|
+
textColor: '{colors.secondary-hover}'
|
|
107
148
|
Input:
|
|
108
|
-
backgroundColor:
|
|
109
|
-
textColor:
|
|
110
|
-
|
|
111
|
-
borderColor:
|
|
149
|
+
backgroundColor: '{colors.background}'
|
|
150
|
+
textColor: '{colors.text}'
|
|
151
|
+
borderRadii: '{borderRadii.md}'
|
|
152
|
+
borderColor: '{colors.border-primary}'
|
|
112
153
|
Checkbox:
|
|
113
|
-
backgroundColor:
|
|
114
|
-
|
|
154
|
+
backgroundColor: '{colors.primary}'
|
|
155
|
+
borderRadii: '{borderRadii.sm}'
|
|
115
156
|
Checkbox-hover:
|
|
116
|
-
backgroundColor:
|
|
157
|
+
backgroundColor: '{colors.primary-hover}'
|
|
158
|
+
Card:
|
|
159
|
+
backgroundColor: '{colors.background}'
|
|
160
|
+
borderRadii: '{borderRadii.none}'
|
|
161
|
+
Card-interactive:
|
|
162
|
+
borderRadii: '{borderRadii.md}'
|
|
163
|
+
Card-elevated:
|
|
164
|
+
backgroundColor: '{colors.background-primary}'
|
|
165
|
+
borderRadii: '{borderRadii.lg}'
|
|
166
|
+
Headline:
|
|
167
|
+
textColor: '{colors.text-accent}'
|
|
168
|
+
typography: '{typography.title}'
|
|
169
|
+
Tag-success:
|
|
170
|
+
backgroundColor: '{colors.feedback-success}'
|
|
171
|
+
textColor: '{colors.white}'
|
|
172
|
+
borderRadii: '{borderRadii.sm}'
|
|
173
|
+
Tag-warning:
|
|
174
|
+
backgroundColor: '{colors.feedback-warning}'
|
|
175
|
+
textColor: '{colors.text}'
|
|
176
|
+
borderRadii: '{borderRadii.sm}'
|
|
117
177
|
Alert-error:
|
|
118
|
-
backgroundColor:
|
|
119
|
-
textColor:
|
|
178
|
+
backgroundColor: '{colors.background-error}'
|
|
179
|
+
textColor: '{colors.feedback-error}'
|
|
120
180
|
Alert-success:
|
|
121
|
-
backgroundColor:
|
|
122
|
-
textColor:
|
|
181
|
+
backgroundColor: '{colors.background-success}'
|
|
182
|
+
textColor: '{colors.text}'
|
|
123
183
|
Alert-warning:
|
|
124
|
-
backgroundColor:
|
|
125
|
-
textColor:
|
|
184
|
+
backgroundColor: '{colors.background-warning}'
|
|
185
|
+
textColor: '{colors.text}'
|
|
126
186
|
---
|
|
127
187
|
|
|
128
188
|
# LX Studio
|
|
129
189
|
|
|
130
190
|
This file defines the visual design tokens for the Skillsoft LX Studio authoring platform, implemented using the Gamut design system (`@codecademy/gamut`, `@codecademy/gamut-styles`). LX Studio uses a dedicated Gamut theme that extends Core with its own brand colors, typography, and border radii — all Gamut components work without modification.
|
|
131
191
|
|
|
132
|
-
|
|
192
|
+
Storybook: https://gamut.codecademy.com
|
|
133
193
|
|
|
134
194
|
---
|
|
135
195
|
|
|
136
|
-
##
|
|
196
|
+
## Overview
|
|
137
197
|
|
|
138
|
-
LX Studio communicates
|
|
198
|
+
LX Studio communicates modern professional craft — clean, precise, and tool-like. As an authoring environment for learning content creators, the interface must feel capable and unobtrusive. The design voice prioritizes clarity and control over personality.
|
|
139
199
|
|
|
140
|
-
|
|
200
|
+
Density: Medium. Layouts are information-dense but well-spaced; generous border radii and soft shadows reduce visual weight.
|
|
201
|
+
|
|
202
|
+
Design philosophy:
|
|
141
203
|
|
|
142
|
-
**Design philosophy**:
|
|
143
|
-
- Light mode only — no dark mode support
|
|
144
204
|
- Larger border radii than Core give the UI a softer, more modern feel
|
|
145
|
-
-
|
|
205
|
+
- Sapphire (`#1C50BB`) drives primary CTAs and interactive controls in light mode
|
|
146
206
|
- Shadows are soft (navy-200) rather than hard (navy-800 in Core light mode)
|
|
147
|
-
-
|
|
148
|
-
|
|
149
|
-
---
|
|
207
|
+
- Skillsoft Text and Skillsoft Sans replace Apercu and Suisse across `base` and `accent`
|
|
208
|
+
- Use semantic `background-primary` (`#FAFBFC`) — not Core `beige`
|
|
150
209
|
|
|
151
|
-
|
|
210
|
+
### Themes
|
|
152
211
|
|
|
153
|
-
LX Studio uses a single Gamut theme
|
|
212
|
+
LX Studio uses a single Gamut theme that extends Core. Light mode applies LX-specific semantic overrides (sapphire primary, softer borders, larger radii). Dark mode inherits Core dark semantics — use `<ColorMode>` and semantic tokens the same way as Codecademy.
|
|
154
213
|
|
|
155
|
-
| Theme
|
|
156
|
-
|
|
157
|
-
|
|
|
214
|
+
| Theme | Use case | Base font | Dark mode |
|
|
215
|
+
| --------- | -------------------------------------- | --------------------- | -------------- |
|
|
216
|
+
| LX Studio | Skillsoft LX Studio authoring platform | Skillsoft Sans / Text | ✓ light + dark |
|
|
158
217
|
|
|
159
|
-
|
|
218
|
+
Set the active theme via `<GamutProvider theme={lxStudioTheme}>`. For new LX Studio apps, default to `lxStudioTheme` unless another theme is explicitly requested. Install in app repos: `gamut plugin install cursor --theme lxstudio` (copies to `./DESIGN.md`).
|
|
160
219
|
|
|
161
220
|
---
|
|
162
221
|
|
|
163
|
-
##
|
|
222
|
+
## Colors
|
|
164
223
|
|
|
165
|
-
Use
|
|
224
|
+
Use semantic token names in code and designs. They resolve per color mode automatically. Never hardcode hex values for adaptive UI. Never hardcode `beige` — LX maps `background-primary` to `lxStudioBgPrimary` (`#FAFBFC`).
|
|
225
|
+
|
|
226
|
+
For dark/light regions, use `<ColorMode>` or `<Background>` — never swap colors manually with custom CSS.
|
|
166
227
|
|
|
167
228
|
### Text
|
|
168
229
|
|
|
169
|
-
| Token |
|
|
170
|
-
|
|
171
|
-
| `text`
|
|
172
|
-
| `text-accent`
|
|
173
|
-
| `text-secondary` |
|
|
174
|
-
| `text-disabled`
|
|
230
|
+
| Token | Light | Dark | Use for |
|
|
231
|
+
| ---------------- | --------------------------------- | --------------- | --------------------------- |
|
|
232
|
+
| `text` | navy-800 `#10162F` | white `#ffffff` | Default body and UI text |
|
|
233
|
+
| `text-accent` | navy-900 `#0A0D1C` | beige `#FFF0E5` | Stronger emphasis text |
|
|
234
|
+
| `text-secondary` | navy-600 `rgba(16, 22, 47, 0.75)` | white at 65% | Supporting / secondary copy |
|
|
235
|
+
| `text-disabled` | navy-500 `rgba(16, 22, 47, 0.63)` | white at 50% | Disabled state labels |
|
|
175
236
|
|
|
176
237
|
### Background
|
|
177
238
|
|
|
178
|
-
| Token |
|
|
179
|
-
|
|
180
|
-
| `background`
|
|
181
|
-
| `background-primary`
|
|
182
|
-
| `background-contrast` | `#ffffff` | Maximum contrast surface
|
|
183
|
-
| `background-selected` |
|
|
184
|
-
| `background-hover`
|
|
185
|
-
| `background-disabled` |
|
|
186
|
-
| `background-success`
|
|
187
|
-
| `background-warning`
|
|
188
|
-
| `background-error`
|
|
239
|
+
| Token | Light | Dark | Use for |
|
|
240
|
+
| --------------------- | --------------------------------- | -------------------- | --------------------------------- |
|
|
241
|
+
| `background` | white `#ffffff` | navy-800 `#10162F` | Default page/component background |
|
|
242
|
+
| `background-primary` | `#FAFBFC` (lxStudioBgPrimary) | navy-900 `#0A0D1C` | Slightly elevated surfaces |
|
|
243
|
+
| `background-contrast` | white `#ffffff` | black `#000000` | Maximum contrast surface |
|
|
244
|
+
| `background-selected` | navy-100 `rgba(16, 22, 47, 0.04)` | white at 4% | Selected row / item |
|
|
245
|
+
| `background-hover` | navy-200 `rgba(16, 22, 47, 0.12)` | white at 9% | Hover state overlay |
|
|
246
|
+
| `background-disabled` | navy-200 `rgba(16, 22, 47, 0.12)` | white at 9% | Disabled surface |
|
|
247
|
+
| `background-success` | green-0 `#F5FFE3` | green-900 `#151C07` | Success state container |
|
|
248
|
+
| `background-warning` | yellow-0 `#FFFAE5` | yellow-900 `#211B00` | Warning state container |
|
|
249
|
+
| `background-error` | red-0 `#FBF1F0` | red-900 `#280503` | Error state container |
|
|
189
250
|
|
|
190
251
|
### Interactive
|
|
191
252
|
|
|
192
|
-
| Token |
|
|
193
|
-
|
|
194
|
-
| `primary` | `#
|
|
195
|
-
| `primary-hover` | `#
|
|
196
|
-
| `primary-inverse` | `#FFD300`
|
|
197
|
-
| `secondary`
|
|
198
|
-
| `secondary-hover` |
|
|
199
|
-
| `
|
|
200
|
-
| `
|
|
201
|
-
| `danger` | `#E91C11` (red-500) | Destructive actions, error states |
|
|
202
|
-
| `danger-hover` | `#BE1809` (red-600) | Hover on danger interactive |
|
|
203
|
-
|
|
204
|
-
**Key distinction**: `primary` (lxStudioPurple `#5628FE`) differs from `interface` (hyper-500 `#3A10E5`). Buttons and links use the lighter LX Studio purple; checkboxes, toggles, and sliders use the deeper hyper purple.
|
|
253
|
+
| Token | Light | Dark | Use for |
|
|
254
|
+
| ----------------- | --------------------------------- | -------------------- | ---------------------------------- |
|
|
255
|
+
| `primary` | sapphire `#1C50BB` | yellow-500 `#FFD300` | Primary CTA, links, focus rings |
|
|
256
|
+
| `primary-hover` | navy-800 `#10162F` | yellow-400 `#CCA900` | Hover state of primary interactive |
|
|
257
|
+
| `primary-inverse` | yellow-500 `#FFD300` | hyper-500 `#3A10E5` | Primary on a colored background |
|
|
258
|
+
| `secondary` | navy-800 `#10162F` | white `#ffffff` | Secondary CTA, ghost buttons |
|
|
259
|
+
| `secondary-hover` | navy-700 `rgba(16, 22, 47, 0.86)` | white at 80% | Hover state of secondary |
|
|
260
|
+
| `danger` | red-500 `#E91C11` | red-300 `#E85D7F` | Destructive actions, error states |
|
|
261
|
+
| `danger-hover` | red-600 `#BE1809` | red-400 `#DC5879` | Hover on danger interactive |
|
|
205
262
|
|
|
206
263
|
### Border
|
|
207
264
|
|
|
208
|
-
| Token |
|
|
209
|
-
|
|
210
|
-
| `border-primary`
|
|
211
|
-
| `border-secondary` |
|
|
212
|
-
| `border-tertiary`
|
|
213
|
-
| `border-disabled`
|
|
265
|
+
| Token | Light | Dark | Use for |
|
|
266
|
+
| ------------------ | --------------------------------- | --------------- | ------------------------------- |
|
|
267
|
+
| `border-primary` | navy-400 `rgba(16, 22, 47, 0.47)` | white `#ffffff` | Standard input and card borders |
|
|
268
|
+
| `border-secondary` | navy-600 `rgba(16, 22, 47, 0.75)` | white at 65% | Medium-weight borders |
|
|
269
|
+
| `border-tertiary` | navy-800 `#10162F` | white at 20% | Strong structural borders |
|
|
270
|
+
| `border-disabled` | navy-300 `rgba(16, 22, 47, 0.28)` | white at 50% | Disabled input borders |
|
|
214
271
|
|
|
215
272
|
LX Studio's `border-primary` is mid-gray (navy-400) rather than Core's near-black navy-800 — borders are softer and less prominent.
|
|
216
273
|
|
|
217
274
|
### Feedback
|
|
218
275
|
|
|
219
|
-
| Token |
|
|
220
|
-
|
|
221
|
-
| `feedback-error`
|
|
222
|
-
| `feedback-success` | `#06844F` (lxStudioSuccess) | Success messages, confirmations
|
|
223
|
-
| `feedback-warning` | `#FFD300`
|
|
276
|
+
| Token | Light | Dark | Use for |
|
|
277
|
+
| ------------------ | --------------------------- | ------------------- | -------------------------------- |
|
|
278
|
+
| `feedback-error` | red-600 `#BE1809` | red-300 `#E85D7F` | Error messages, validation |
|
|
279
|
+
| `feedback-success` | `#06844F` (lxStudioSuccess) | green-400 `#AEE938` | Success messages, confirmations |
|
|
280
|
+
| `feedback-warning` | yellow-500 `#FFD300` | yellow-0 `#FFFAE5` | Warning messages, caution states |
|
|
224
281
|
|
|
225
282
|
### Shadow
|
|
226
283
|
|
|
227
|
-
| Token |
|
|
228
|
-
|
|
229
|
-
| `shadow-primary`
|
|
230
|
-
| `shadow-secondary` |
|
|
284
|
+
| Token | Light | Dark |
|
|
285
|
+
| ------------------ | --------------------------------- | ------------ |
|
|
286
|
+
| `shadow-primary` | navy-200 `rgba(16, 22, 47, 0.12)` | white |
|
|
287
|
+
| `shadow-secondary` | navy-600 `rgba(16, 22, 47, 0.75)` | white at 65% |
|
|
231
288
|
|
|
232
289
|
LX Studio shadows are soft — use `shadow-primary` for standard elevated surfaces. This matches Percipio's shadow weight, not Core's hard navy-800 shadow.
|
|
233
290
|
|
|
234
291
|
---
|
|
235
292
|
|
|
236
|
-
|
|
293
|
+
### LX Studio color palette
|
|
237
294
|
|
|
238
|
-
LX Studio adds
|
|
295
|
+
LX Studio adds named colors to the core palette. Use semantic aliases in code, not these raw names.
|
|
239
296
|
|
|
240
|
-
| Named color
|
|
241
|
-
|
|
242
|
-
| `
|
|
243
|
-
| `
|
|
244
|
-
| `
|
|
245
|
-
| `lxStudioBgPrimary` | `#FAFBFC` | `background-primary` |
|
|
297
|
+
| Named color | Value | Mapped to |
|
|
298
|
+
| ------------------- | --------- | -------------------------------- |
|
|
299
|
+
| `sapphire` | `#1C50BB` | `primary` (shared with Percipio) |
|
|
300
|
+
| `lxStudioSuccess` | `#06844F` | `feedback-success` |
|
|
301
|
+
| `lxStudioBgPrimary` | `#FAFBFC` | `background-primary` |
|
|
246
302
|
|
|
247
303
|
The full core swatch palette (navy, hyper, blue, green, yellow, red, etc.) is also available. Raw swatches should only be used for fixed colors that must not adapt (illustrations, data viz, etc.).
|
|
248
304
|
|
|
@@ -252,57 +308,57 @@ The full core swatch palette (navy, hyper, blue, green, yellow, red, etc.) is al
|
|
|
252
308
|
|
|
253
309
|
### Typefaces
|
|
254
310
|
|
|
255
|
-
LX Studio uses
|
|
311
|
+
LX Studio uses Skillsoft Text for `base` and Skillsoft Sans for `accent`. There is no Apercu and no Suisse.
|
|
256
312
|
|
|
257
|
-
| Token
|
|
258
|
-
|
|
259
|
-
| `base`
|
|
260
|
-
| `accent`
|
|
261
|
-
| `monospace` | Monaco, Menlo, Ubuntu Mono, Droid Sans Mono, Consolas | Code editor contexts
|
|
262
|
-
| `system`
|
|
313
|
+
| Token | Font | Use for |
|
|
314
|
+
| ----------- | ----------------------------------------------------- | ----------------------------------------- |
|
|
315
|
+
| `base` | `"Skillsoft Text", …` | All default UI text, headlines, body copy |
|
|
316
|
+
| `accent` | `"Skillsoft Sans", …` | Labels, captions, technical context |
|
|
317
|
+
| `monospace` | Monaco, Menlo, Ubuntu Mono, Droid Sans Mono, Consolas | Code editor contexts |
|
|
318
|
+
| `system` | System UI fonts | Performance-critical surfaces |
|
|
263
319
|
|
|
264
|
-
|
|
320
|
+
Skillsoft fonts are loaded via `GamutProvider` asset configuration (see `@codecademy/gamut-styles` remote font assets).
|
|
265
321
|
|
|
266
322
|
### Rules
|
|
267
323
|
|
|
268
|
-
-
|
|
269
|
-
-
|
|
270
|
-
- Text is
|
|
324
|
+
- Skillsoft Medium (500) for headlines, sub-headlines, CTAs, and buttons — not Bold (700).
|
|
325
|
+
- Skillsoft Regular (400) for body text, UI labels, and menu items.
|
|
326
|
+
- Text is left-aligned by default. Center-align only for short marketing headlines. Never right-align.
|
|
271
327
|
- Do not adjust letter-spacing.
|
|
272
|
-
-
|
|
328
|
+
- `accent` uses Skillsoft Sans; `base` uses Skillsoft Text — they are intentionally different families.
|
|
273
329
|
|
|
274
330
|
### Font weight scale
|
|
275
331
|
|
|
276
|
-
| Token
|
|
277
|
-
|
|
278
|
-
| `base`
|
|
279
|
-
| `title` |
|
|
332
|
+
| Token | Value | Use |
|
|
333
|
+
| ------- | ----- | ------------------------------------------------------------- |
|
|
334
|
+
| `base` | 400 | Body text, UI labels |
|
|
335
|
+
| `title` | 500 | Headlines, CTAs, buttons _(matches Percipio, not Core's 700)_ |
|
|
280
336
|
|
|
281
337
|
### Font size scale
|
|
282
338
|
|
|
283
339
|
Shared with Core — all sizes are identical.
|
|
284
340
|
|
|
285
|
-
| Token key | Size | Common use
|
|
286
|
-
|
|
287
|
-
| `64`
|
|
288
|
-
| `44`
|
|
289
|
-
| `34`
|
|
290
|
-
| `26`
|
|
291
|
-
| `22`
|
|
292
|
-
| `20`
|
|
293
|
-
| `18`
|
|
294
|
-
| `16`
|
|
295
|
-
| `14`
|
|
341
|
+
| Token key | Size | Common use |
|
|
342
|
+
| --------- | ---- | ---------------------------- |
|
|
343
|
+
| `64` | 64px | Hero / display |
|
|
344
|
+
| `44` | 44px | Page titles |
|
|
345
|
+
| `34` | 34px | Section titles |
|
|
346
|
+
| `26` | 26px | Sub-section titles |
|
|
347
|
+
| `22` | 22px | Card titles, large UI labels |
|
|
348
|
+
| `20` | 20px | Secondary titles |
|
|
349
|
+
| `18` | 18px | Large body, intro text |
|
|
350
|
+
| `16` | 16px | Default body text |
|
|
351
|
+
| `14` | 14px | Small body, captions, labels |
|
|
296
352
|
|
|
297
353
|
### Line height scale
|
|
298
354
|
|
|
299
355
|
Shared with Core.
|
|
300
356
|
|
|
301
|
-
| Token
|
|
302
|
-
|
|
303
|
-
| `base`
|
|
304
|
-
| `spacedTitle` | 1.3
|
|
305
|
-
| `title`
|
|
357
|
+
| Token | Value | Use |
|
|
358
|
+
| ------------- | ----- | ------------------------------- |
|
|
359
|
+
| `base` | 1.5 | Body text |
|
|
360
|
+
| `spacedTitle` | 1.3 | Sub-headlines and medium titles |
|
|
361
|
+
| `title` | 1.2 | Large headlines |
|
|
306
362
|
|
|
307
363
|
### Line length
|
|
308
364
|
|
|
@@ -310,77 +366,81 @@ Target 45–85 characters per line; 66 characters is ideal. Max 50 for multi-col
|
|
|
310
366
|
|
|
311
367
|
---
|
|
312
368
|
|
|
313
|
-
##
|
|
369
|
+
## Layout
|
|
370
|
+
|
|
371
|
+
### Spacing scale
|
|
314
372
|
|
|
315
373
|
Identical to Core. All spacing is multiples of 4px on an 8px grid.
|
|
316
374
|
|
|
317
375
|
| Token | Value |
|
|
318
|
-
|
|
319
|
-
| `0`
|
|
320
|
-
| `4`
|
|
321
|
-
| `8`
|
|
322
|
-
| `12`
|
|
323
|
-
| `16`
|
|
324
|
-
| `24`
|
|
325
|
-
| `32`
|
|
326
|
-
| `40`
|
|
327
|
-
| `48`
|
|
328
|
-
| `64`
|
|
329
|
-
| `96`
|
|
376
|
+
| ----- | ----- |
|
|
377
|
+
| `0` | 0 |
|
|
378
|
+
| `4` | 4px |
|
|
379
|
+
| `8` | 8px |
|
|
380
|
+
| `12` | 12px |
|
|
381
|
+
| `16` | 16px |
|
|
382
|
+
| `24` | 24px |
|
|
383
|
+
| `32` | 32px |
|
|
384
|
+
| `40` | 40px |
|
|
385
|
+
| `48` | 48px |
|
|
386
|
+
| `64` | 64px |
|
|
387
|
+
| `96` | 96px |
|
|
330
388
|
|
|
331
|
-
|
|
389
|
+
### System props
|
|
332
390
|
|
|
333
|
-
|
|
391
|
+
Never use inline `style` attributes. Use system props shorthand (`m`, `mb`, `p`, etc.) and Gamut tokens for colors and borders.
|
|
334
392
|
|
|
335
|
-
|
|
393
|
+
### Responsive behavior
|
|
336
394
|
|
|
337
|
-
|
|
338
|
-
|---|---|---|---|
|
|
339
|
-
| `none` | 0px | 0px | Square / non-interactive elements |
|
|
340
|
-
| `sm` | **4px** | 2px | Subtle rounding, tags, checkboxes |
|
|
341
|
-
| `md` | **8px** | 4px | Default buttons, inputs, interactive cards |
|
|
342
|
-
| `lg` | **12px** | 8px | Cards, panels |
|
|
343
|
-
| `xl` | 16px | 16px | Large cards, modals |
|
|
344
|
-
| `full` | 999px | 999px | Pills, avatars, circular elements |
|
|
395
|
+
Identical to Core. Mobile-first; 12-column grid; 44×44px minimum touch targets on mobile.
|
|
345
396
|
|
|
346
397
|
---
|
|
347
398
|
|
|
348
|
-
##
|
|
399
|
+
## Elevation & Depth
|
|
349
400
|
|
|
350
|
-
|
|
401
|
+
LX Studio shadows are soft — use `shadow-primary` (navy-200) for elevated surfaces, not Core's hard navy-800 shadow in light mode.
|
|
351
402
|
|
|
352
|
-
|
|
353
|
-
|---|---|---|
|
|
354
|
-
| _(base)_ | 0 | 288px |
|
|
355
|
-
| `xs` | 480px | 448px |
|
|
356
|
-
| `sm` | 768px | 704px |
|
|
357
|
-
| `md` | 1024px | 896px |
|
|
358
|
-
| `lg` | 1200px | 1072px |
|
|
359
|
-
| `xl` | 1440px | 1248px |
|
|
403
|
+
---
|
|
360
404
|
|
|
361
|
-
|
|
405
|
+
## Shapes
|
|
362
406
|
|
|
363
|
-
|
|
364
|
-
|---|---|
|
|
365
|
-
| Horizontal margins | 64px (lg+), 48px (md), 32px (sm/xs), 16px (base) |
|
|
366
|
-
| Column gaps (gutters) | 32px (lg+), 24px (md), 16px (sm/xs), 8px (base) |
|
|
367
|
-
| Row gaps | 32px (lg+), 24px (md), 16px (sm/xs), 8px (base) |
|
|
407
|
+
LX Studio uses larger border radii than Core — defined in `lxStudioBorderRadii`. No custom radius values.
|
|
368
408
|
|
|
369
|
-
|
|
409
|
+
| Token | LX Studio | Core | Use |
|
|
410
|
+
| ------ | --------- | ----- | ------------------------------------------ |
|
|
411
|
+
| `none` | 0px | 0px | Square / non-interactive elements |
|
|
412
|
+
| `sm` | 4px | 2px | Subtle rounding, tags, checkboxes |
|
|
413
|
+
| `md` | 8px | 4px | Default buttons, inputs, interactive cards |
|
|
414
|
+
| `lg` | 12px | 8px | Cards, panels |
|
|
415
|
+
| `xl` | 16px | 16px | Large cards, modals |
|
|
416
|
+
| `full` | 999px | 999px | Pills, avatars, circular elements |
|
|
370
417
|
|
|
371
418
|
---
|
|
372
419
|
|
|
373
|
-
##
|
|
420
|
+
## Components
|
|
374
421
|
|
|
375
422
|
Same component library as Codecademy — all atoms, molecules, and organisms apply. Token values resolve differently per theme automatically.
|
|
376
423
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
- `FillButton`
|
|
380
|
-
- `
|
|
381
|
-
-
|
|
424
|
+
### LX Studio visual differences
|
|
425
|
+
|
|
426
|
+
- `FillButton` uses sapphire `#1C50BB` in light mode instead of hyper-500
|
|
427
|
+
- `FillButton` hover shifts to navy-800 `#10162F` in light mode
|
|
428
|
+
- Interactive elements use `borderRadius: md` (8px, not Core's 4px)
|
|
382
429
|
- `Card` shadows use navy-200 (soft) rather than navy-800 (hard)
|
|
383
|
-
-
|
|
430
|
+
- Prefer `background-primary` over beige for elevated surfaces
|
|
431
|
+
|
|
432
|
+
### Gamut implementation guardrails
|
|
433
|
+
|
|
434
|
+
Same rules as Codecademy (`DESIGN.Codecademy.md` Components section), with LX-specific notes:
|
|
435
|
+
|
|
436
|
+
- Buttons: no generic `Button`; `IconButton` requires `tip`; never set `mode` on buttons; use `borderRadii.md` (8px) on buttons/inputs.
|
|
437
|
+
- Forms: `GridForm` / `ConnectedForm` for submit flows.
|
|
438
|
+
- Cards: valid variants `default`, `white`, `yellow`, `beige`, `navy`, `hyper`; defaults `shadow="none"`, `isInteractive={false}`.
|
|
439
|
+
- DataTable / DataList: `sortable` requires `query`, `onQueryChange`, and client-sorted rows.
|
|
440
|
+
- Menu: always explicit `variant` (`fixed` + `as="nav"` or `popover`).
|
|
441
|
+
- Color mode: `<ColorMode>` / `<Background>` only.
|
|
442
|
+
- Accessibility: WCAG, `FocusTrap` in modals/drawers.
|
|
443
|
+
- Assets: `@codecademy/gamut-icons`, `gamut-illustrations`, `gamut-patterns`.
|
|
384
444
|
|
|
385
445
|
---
|
|
386
446
|
|
|
@@ -388,27 +448,35 @@ Key LX Studio-specific visual differences:
|
|
|
388
448
|
|
|
389
449
|
### Colors
|
|
390
450
|
|
|
391
|
-
-
|
|
392
|
-
-
|
|
393
|
-
-
|
|
394
|
-
- **Don't** use `primary` and `interface` interchangeably — they are intentionally different purples.
|
|
395
|
-
- **Don't** attempt dark mode — LX Studio is light only.
|
|
396
|
-
- **Don't** use the Percipio or Codecademy primary blue/hyper colors directly; go through semantic aliases.
|
|
451
|
+
- Do use semantic color aliases (`primary`, `text`, `background`, etc.) — never hardcode hex values.
|
|
452
|
+
- Do use `<ColorMode>` and `<Background>` for scoped light/dark — dark mode inherits from Core.
|
|
453
|
+
- Don't use the Percipio or Codecademy palette swatches directly; go through semantic aliases.
|
|
397
454
|
|
|
398
455
|
### Typography
|
|
399
456
|
|
|
400
|
-
-
|
|
401
|
-
-
|
|
402
|
-
-
|
|
403
|
-
-
|
|
404
|
-
-
|
|
457
|
+
- Do use title weight (500) for headlines, CTAs, and buttons — not 700.
|
|
458
|
+
- Do keep body text at 150–175% line height for readability.
|
|
459
|
+
- Don't use Apercu or Suisse — LX Studio uses Skillsoft Text and Skillsoft Sans.
|
|
460
|
+
- Don't right-align or center-align body paragraphs.
|
|
461
|
+
- Don't adjust letter-spacing.
|
|
405
462
|
|
|
406
463
|
### Layout & Spacing
|
|
407
464
|
|
|
408
|
-
-
|
|
409
|
-
-
|
|
410
|
-
-
|
|
411
|
-
-
|
|
465
|
+
- Do use multiples of 8px for block-element spacing (4px only for inline / typographic relationships).
|
|
466
|
+
- Do begin design work at 1440px (XL), then adapt down.
|
|
467
|
+
- Do align elements to the 12-column grid.
|
|
468
|
+
- Do apply the larger `md` border radius (8px) to buttons and inputs — it defines the LX Studio feel.
|
|
469
|
+
|
|
470
|
+
### Components
|
|
471
|
+
|
|
472
|
+
- Don't import a generic `Button` or use Apercu / Suisse.
|
|
473
|
+
- Don't use bare form atoms for functional forms.
|
|
474
|
+
|
|
475
|
+
### Pre-ship validation
|
|
476
|
+
|
|
477
|
+
Before considering UI output final, run `/gamut-review` from the app repository root (the directory that contains `DESIGN.md`). Install the plugin first if needed: Cursor — `gamut plugin install cursor --theme lxstudio`; Claude Code — `gamut plugin install claude --theme lxstudio`.
|
|
478
|
+
|
|
479
|
+
The command performs automated checks (dependencies, `GamutProvider`, imports, hex colors, tests, component guardrails) and prints a manual pre-ship checklist keyed to this product's theme. Fix all errors before shipping. Full procedure: [`commands/gamut-review.md`](commands/gamut-review.md) in `@codecademy/gamut` agent-tools (installed as a slash command with the Gamut plugin).
|
|
412
480
|
|
|
413
481
|
---
|
|
414
482
|
|
|
@@ -416,28 +484,28 @@ Key LX Studio-specific visual differences:
|
|
|
416
484
|
|
|
417
485
|
Quick color/token reference for generating or specifying LX Studio UI:
|
|
418
486
|
|
|
419
|
-
| Scenario
|
|
420
|
-
|
|
421
|
-
| Primary button
|
|
422
|
-
| Body text
|
|
423
|
-
| Headline
|
|
424
|
-
| Secondary text
|
|
425
|
-
| Disabled text
|
|
426
|
-
| Elevated surface
|
|
427
|
-
| Card default
|
|
428
|
-
| Checkbox / toggle | `
|
|
429
|
-
| Error state
|
|
430
|
-
| Success state
|
|
431
|
-
| Warning state
|
|
432
|
-
| Disabled state
|
|
487
|
+
| Scenario | Tokens |
|
|
488
|
+
| ----------------- | ------------------------------------------------------------------------------------------------------------------------- |
|
|
489
|
+
| Primary button | `bg: primary (#1C50BB)`, `color: white`, `hover: primary-hover (#10162F)`, `borderRadius: md (8px)` |
|
|
490
|
+
| Body text | `color: text (#10162F)`, `font: Skillsoft Text`, `size: 16px`, `weight: 400`, `lineHeight: base (1.5)` |
|
|
491
|
+
| Headline | `color: text-accent (#0A0D1C)`, `font: Skillsoft Text`, `size: 34–64px`, `weight: title (500)`, `lineHeight: title (1.2)` |
|
|
492
|
+
| Secondary text | `color: text-secondary (navy-600)` |
|
|
493
|
+
| Disabled text | `color: text-disabled (navy-500)` |
|
|
494
|
+
| Elevated surface | `bg: background-primary (#FAFBFC)` |
|
|
495
|
+
| Card default | `bg: background (#ffffff)`, `borderRadius: none` — add `isInteractive` for hover shadow + `borderRadius: md (8px)` |
|
|
496
|
+
| Checkbox / toggle | `primary` / `primary-hover` (theme-resolved via Gamut Checkbox) |
|
|
497
|
+
| Error state | `color: feedback-error (#BE1809)`, `bg: background-error (#FBF1F0)`, `border: danger` |
|
|
498
|
+
| Success state | `color: feedback-success (#06844F)`, `bg: background-success (#F5FFE3)` |
|
|
499
|
+
| Warning state | `color: feedback-warning (#FFD300)`, `bg: background-warning (#FFFAE5)` |
|
|
500
|
+
| Disabled state | `color: text-disabled (navy-500)`, `bg: background-disabled (navy-200)`, `border: border-disabled` |
|
|
433
501
|
|
|
434
502
|
### Component token cheatsheet
|
|
435
503
|
|
|
436
504
|
```
|
|
437
|
-
FillButton → bg: primary (#
|
|
505
|
+
FillButton → bg: primary (#1C50BB), color: white, hover: primary-hover (#10162F), radius: 8px
|
|
438
506
|
StrokeButton → bg: transparent, border: secondary (#10162F)
|
|
439
|
-
Checkbox/Toggle →
|
|
440
|
-
Card → bg: background, shadow: shadow-primary (
|
|
507
|
+
Checkbox/Toggle → primary (theme-resolved), hover: primary-hover, radius: 4px
|
|
508
|
+
Card → bg: background, shadow: shadow-primary (navy-200, soft), radius: none
|
|
441
509
|
Alert (error) → uses feedback-error + background-error
|
|
442
510
|
Alert (success) → uses feedback-success + background-success
|
|
443
511
|
Alert (warning) → uses feedback-warning + background-warning
|