@codecademy/gamut 68.6.1-alpha.e6c390.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 +239 -191
- package/agent-tools/DESIGN.LXStudio.md +236 -184
- package/agent-tools/DESIGN.Percipio.md +232 -182
- package/agent-tools/DESIGN.md +1 -1
- 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 +39 -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 +69 -23
- 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 +79 -29
- 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 +70 -26
- package/agent-tools/skills/gamut-testing/SKILL.md +106 -62
- package/agent-tools/skills/gamut-theming/SKILL.md +34 -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
|
@@ -3,10 +3,8 @@ version: alpha
|
|
|
3
3
|
name: LX Studio Design System
|
|
4
4
|
description: Design tokens for the Skillsoft LX Studio authoring platform.
|
|
5
5
|
colors:
|
|
6
|
-
# palette — reference hex for docs/tools; in product UI use semantic colors via Gamut theme (Emotion) / system props or Figma tokens—never paste these literals into code
|
|
7
6
|
# LX Studio additions — custom brand tokens
|
|
8
|
-
|
|
9
|
-
lxStudioPurpleHover: '#7955FC'
|
|
7
|
+
sapphire: '#1C50BB'
|
|
10
8
|
lxStudioSuccess: '#06844F'
|
|
11
9
|
lxStudioBgPrimary: '#FAFBFC'
|
|
12
10
|
# core palette — referenced by semantic aliases below
|
|
@@ -14,13 +12,13 @@ colors:
|
|
|
14
12
|
hyper-400: '#5533FF'
|
|
15
13
|
navy-900: '#0A0D1C'
|
|
16
14
|
navy-800: '#10162F'
|
|
17
|
-
navy-700: '
|
|
18
|
-
navy-600: '
|
|
19
|
-
navy-500: '
|
|
20
|
-
navy-400: '
|
|
21
|
-
navy-300: '
|
|
22
|
-
navy-200: '
|
|
23
|
-
navy-100: '
|
|
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)'
|
|
24
22
|
yellow-500: '#FFD300'
|
|
25
23
|
yellow-0: '#FFFAE5'
|
|
26
24
|
green-700: '#008A27'
|
|
@@ -43,13 +41,11 @@ colors:
|
|
|
43
41
|
background-success: '{colors.green-0}'
|
|
44
42
|
background-warning: '{colors.yellow-0}'
|
|
45
43
|
background-error: '{colors.red-0}'
|
|
46
|
-
primary: '{colors.
|
|
47
|
-
primary-hover: '{colors.
|
|
44
|
+
primary: '{colors.sapphire}'
|
|
45
|
+
primary-hover: '{colors.navy-800}'
|
|
48
46
|
primary-inverse: '{colors.yellow-500}'
|
|
49
47
|
secondary: '{colors.navy-800}'
|
|
50
48
|
secondary-hover: '{colors.navy-700}'
|
|
51
|
-
interface: '{colors.hyper-500}'
|
|
52
|
-
interface-hover: '{colors.hyper-400}'
|
|
53
49
|
danger: '{colors.red-500}'
|
|
54
50
|
danger-hover: '{colors.red-600}'
|
|
55
51
|
feedback-error: '{colors.red-600}'
|
|
@@ -63,22 +59,42 @@ colors:
|
|
|
63
59
|
shadow-secondary: '{colors.navy-600}'
|
|
64
60
|
typography:
|
|
65
61
|
base:
|
|
66
|
-
fontFamily: '"
|
|
62
|
+
fontFamily: '"Skillsoft Text", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif'
|
|
67
63
|
fontSize: '1rem'
|
|
68
64
|
fontWeight: '400'
|
|
69
65
|
lineHeight: '1.5'
|
|
70
66
|
accent:
|
|
71
|
-
fontFamily: '"
|
|
67
|
+
fontFamily: '"Skillsoft Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif'
|
|
72
68
|
fontSize: '0.875rem'
|
|
73
69
|
fontWeight: '400'
|
|
74
70
|
lineHeight: '1.5'
|
|
75
71
|
title:
|
|
76
|
-
fontFamily: '"
|
|
72
|
+
fontFamily: '"Skillsoft Text", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif'
|
|
77
73
|
fontSize: '2.125rem'
|
|
78
|
-
fontWeight: '
|
|
74
|
+
fontWeight: '500'
|
|
79
75
|
lineHeight: '1.2'
|
|
80
76
|
monospace:
|
|
81
77
|
fontFamily: 'Monaco, Menlo, "Ubuntu Mono", "Droid Sans Mono", Consolas, monospace'
|
|
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'
|
|
82
98
|
borderRadii:
|
|
83
99
|
none: '0px'
|
|
84
100
|
sm: '4px'
|
|
@@ -102,31 +118,62 @@ components:
|
|
|
102
118
|
FillButton:
|
|
103
119
|
backgroundColor: '{colors.primary}'
|
|
104
120
|
textColor: '{colors.white}'
|
|
105
|
-
|
|
121
|
+
borderRadii: '{borderRadii.md}'
|
|
106
122
|
FillButton-hover:
|
|
107
123
|
backgroundColor: '{colors.primary-hover}'
|
|
108
124
|
textColor: '{colors.white}'
|
|
109
125
|
FillButton-danger:
|
|
110
126
|
backgroundColor: '{colors.danger}'
|
|
111
127
|
textColor: '{colors.white}'
|
|
112
|
-
|
|
128
|
+
borderRadii: '{borderRadii.md}'
|
|
113
129
|
FillButton-danger-hover:
|
|
114
130
|
backgroundColor: '{colors.danger-hover}'
|
|
115
131
|
textColor: '{colors.white}'
|
|
116
132
|
StrokeButton:
|
|
117
133
|
backgroundColor: 'transparent'
|
|
118
134
|
textColor: '{colors.secondary}'
|
|
119
|
-
|
|
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}'
|
|
120
148
|
Input:
|
|
121
149
|
backgroundColor: '{colors.background}'
|
|
122
150
|
textColor: '{colors.text}'
|
|
123
|
-
|
|
151
|
+
borderRadii: '{borderRadii.md}'
|
|
124
152
|
borderColor: '{colors.border-primary}'
|
|
125
153
|
Checkbox:
|
|
126
|
-
backgroundColor: '{colors.
|
|
127
|
-
|
|
154
|
+
backgroundColor: '{colors.primary}'
|
|
155
|
+
borderRadii: '{borderRadii.sm}'
|
|
128
156
|
Checkbox-hover:
|
|
129
|
-
backgroundColor: '{colors.
|
|
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}'
|
|
130
177
|
Alert-error:
|
|
131
178
|
backgroundColor: '{colors.background-error}'
|
|
132
179
|
textColor: '{colors.feedback-error}'
|
|
@@ -140,123 +187,118 @@ components:
|
|
|
140
187
|
|
|
141
188
|
# LX Studio
|
|
142
189
|
|
|
143
|
-
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.
|
|
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.
|
|
144
191
|
|
|
145
|
-
|
|
192
|
+
Storybook: https://gamut.codecademy.com
|
|
146
193
|
|
|
147
194
|
---
|
|
148
195
|
|
|
149
|
-
##
|
|
196
|
+
## Overview
|
|
150
197
|
|
|
151
|
-
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.
|
|
152
199
|
|
|
153
|
-
|
|
200
|
+
Density: Medium. Layouts are information-dense but well-spaced; generous border radii and soft shadows reduce visual weight.
|
|
154
201
|
|
|
155
|
-
|
|
202
|
+
Design philosophy:
|
|
156
203
|
|
|
157
|
-
- Extends **Core** — light and dark color modes are available; `lxStudioTheme` defines explicit **light** overrides and inherits **Core dark** where not overridden
|
|
158
204
|
- Larger border radii than Core give the UI a softer, more modern feel
|
|
159
|
-
-
|
|
205
|
+
- Sapphire (`#1C50BB`) drives primary CTAs and interactive controls in light mode
|
|
160
206
|
- Shadows are soft (navy-200) rather than hard (navy-800 in Core light mode)
|
|
161
|
-
-
|
|
207
|
+
- Skillsoft Text and Skillsoft Sans replace Apercu and Suisse across `base` and `accent`
|
|
208
|
+
- Use semantic `background-primary` (`#FAFBFC`) — not Core `beige`
|
|
162
209
|
|
|
163
|
-
|
|
210
|
+
### Themes
|
|
164
211
|
|
|
165
|
-
|
|
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.
|
|
166
213
|
|
|
167
|
-
|
|
214
|
+
| Theme | Use case | Base font | Dark mode |
|
|
215
|
+
| --------- | -------------------------------------- | --------------------- | -------------- |
|
|
216
|
+
| LX Studio | Skillsoft LX Studio authoring platform | Skillsoft Sans / Text | ✓ light + dark |
|
|
168
217
|
|
|
169
|
-
|
|
170
|
-
| ------------- | -------------------------------------- | -------------- | ------------------------------------------------------- |
|
|
171
|
-
| **LX Studio** | Skillsoft LX Studio authoring platform | Hanken Grotesk | yes (inherits Core dark; light overrides in theme file) |
|
|
172
|
-
|
|
173
|
-
The active theme is set at the app root via `<GamutProvider theme={lxStudioTheme}>`.
|
|
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`).
|
|
174
219
|
|
|
175
220
|
---
|
|
176
221
|
|
|
177
|
-
##
|
|
222
|
+
## Colors
|
|
223
|
+
|
|
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`).
|
|
178
225
|
|
|
179
|
-
|
|
226
|
+
For dark/light regions, use `<ColorMode>` or `<Background>` — never swap colors manually with custom CSS.
|
|
180
227
|
|
|
181
228
|
### Text
|
|
182
229
|
|
|
183
|
-
| Token |
|
|
184
|
-
| ---------------- |
|
|
185
|
-
| `text` | `#10162F`
|
|
186
|
-
| `text-accent` | `#0A0D1C`
|
|
187
|
-
| `text-secondary` |
|
|
188
|
-
| `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 |
|
|
189
236
|
|
|
190
237
|
### Background
|
|
191
238
|
|
|
192
|
-
| Token |
|
|
193
|
-
| --------------------- |
|
|
194
|
-
| `background` | `#ffffff`
|
|
195
|
-
| `background-primary` | `#FAFBFC` (lxStudioBgPrimary) | Slightly elevated surfaces |
|
|
196
|
-
| `background-contrast` | `#ffffff`
|
|
197
|
-
| `background-selected` |
|
|
198
|
-
| `background-hover` |
|
|
199
|
-
| `background-disabled` |
|
|
200
|
-
| `background-success` | `#F5FFE3`
|
|
201
|
-
| `background-warning` | `#FFFAE5`
|
|
202
|
-
| `background-error` | `#FBF1F0`
|
|
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 |
|
|
203
250
|
|
|
204
251
|
### Interactive
|
|
205
252
|
|
|
206
|
-
| Token |
|
|
207
|
-
| ----------------- |
|
|
208
|
-
| `primary` | `#
|
|
209
|
-
| `primary-hover` | `#
|
|
210
|
-
| `primary-inverse` | `#FFD300`
|
|
211
|
-
| `secondary` | `#10162F`
|
|
212
|
-
| `secondary-hover` |
|
|
213
|
-
| `
|
|
214
|
-
| `
|
|
215
|
-
| `danger` | `#E91C11` (red-500) | Destructive actions, error states |
|
|
216
|
-
| `danger-hover` | `#BE1809` (red-600) | Hover on danger interactive |
|
|
217
|
-
|
|
218
|
-
**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 |
|
|
219
262
|
|
|
220
263
|
### Border
|
|
221
264
|
|
|
222
|
-
| Token |
|
|
223
|
-
| ------------------ |
|
|
224
|
-
| `border-primary` |
|
|
225
|
-
| `border-secondary` |
|
|
226
|
-
| `border-tertiary` | `#10162F`
|
|
227
|
-
| `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 |
|
|
228
271
|
|
|
229
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.
|
|
230
273
|
|
|
231
274
|
### Feedback
|
|
232
275
|
|
|
233
|
-
| Token |
|
|
234
|
-
| ------------------ | --------------------------- | -------------------------------- |
|
|
235
|
-
| `feedback-error` | `#BE1809`
|
|
236
|
-
| `feedback-success` | `#06844F` (lxStudioSuccess) | Success messages, confirmations |
|
|
237
|
-
| `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 |
|
|
238
281
|
|
|
239
282
|
### Shadow
|
|
240
283
|
|
|
241
|
-
| Token |
|
|
242
|
-
| ------------------ |
|
|
243
|
-
| `shadow-primary` |
|
|
244
|
-
| `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% |
|
|
245
288
|
|
|
246
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.
|
|
247
290
|
|
|
248
291
|
---
|
|
249
292
|
|
|
250
|
-
|
|
293
|
+
### LX Studio color palette
|
|
251
294
|
|
|
252
|
-
LX Studio adds
|
|
295
|
+
LX Studio adds named colors to the core palette. Use semantic aliases in code, not these raw names.
|
|
253
296
|
|
|
254
|
-
| Named color
|
|
255
|
-
|
|
|
256
|
-
| `
|
|
257
|
-
| `
|
|
258
|
-
| `
|
|
259
|
-
| `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` |
|
|
260
302
|
|
|
261
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.).
|
|
262
304
|
|
|
@@ -266,31 +308,31 @@ The full core swatch palette (navy, hyper, blue, green, yellow, red, etc.) is al
|
|
|
266
308
|
|
|
267
309
|
### Typefaces
|
|
268
310
|
|
|
269
|
-
LX Studio uses
|
|
311
|
+
LX Studio uses Skillsoft Text for `base` and Skillsoft Sans for `accent`. There is no Apercu and no Suisse.
|
|
270
312
|
|
|
271
|
-
| Token | Font | Use for
|
|
272
|
-
| ----------- | ----------------------------------------------------- |
|
|
273
|
-
| `base` | `"
|
|
274
|
-
| `accent` | `"
|
|
275
|
-
| `monospace` | Monaco, Menlo, Ubuntu Mono, Droid Sans Mono, Consolas | Code editor contexts
|
|
276
|
-
| `system` | System UI fonts | Performance-critical surfaces
|
|
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 |
|
|
277
319
|
|
|
278
|
-
|
|
320
|
+
Skillsoft fonts are loaded via `GamutProvider` asset configuration (see `@codecademy/gamut-styles` remote font assets).
|
|
279
321
|
|
|
280
322
|
### Rules
|
|
281
323
|
|
|
282
|
-
-
|
|
283
|
-
-
|
|
284
|
-
- 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.
|
|
285
327
|
- Do not adjust letter-spacing.
|
|
286
|
-
-
|
|
328
|
+
- `accent` uses Skillsoft Sans; `base` uses Skillsoft Text — they are intentionally different families.
|
|
287
329
|
|
|
288
330
|
### Font weight scale
|
|
289
331
|
|
|
290
|
-
| Token | Value | Use
|
|
291
|
-
| ------- | ----- |
|
|
292
|
-
| `base` | 400 | Body text, UI labels
|
|
293
|
-
| `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)_ |
|
|
294
336
|
|
|
295
337
|
### Font size scale
|
|
296
338
|
|
|
@@ -324,7 +366,9 @@ Target 45–85 characters per line; 66 characters is ideal. Max 50 for multi-col
|
|
|
324
366
|
|
|
325
367
|
---
|
|
326
368
|
|
|
327
|
-
##
|
|
369
|
+
## Layout
|
|
370
|
+
|
|
371
|
+
### Spacing scale
|
|
328
372
|
|
|
329
373
|
Identical to Core. All spacing is multiples of 4px on an 8px grid.
|
|
330
374
|
|
|
@@ -342,60 +386,61 @@ Identical to Core. All spacing is multiples of 4px on an 8px grid.
|
|
|
342
386
|
| `64` | 64px |
|
|
343
387
|
| `96` | 96px |
|
|
344
388
|
|
|
345
|
-
|
|
389
|
+
### System props
|
|
346
390
|
|
|
347
|
-
|
|
391
|
+
Never use inline `style` attributes. Use system props shorthand (`m`, `mb`, `p`, etc.) and Gamut tokens for colors and borders.
|
|
348
392
|
|
|
349
|
-
|
|
393
|
+
### Responsive behavior
|
|
350
394
|
|
|
351
|
-
|
|
352
|
-
| ------ | --------- | ----- | ------------------------------------------ |
|
|
353
|
-
| `none` | 0px | 0px | Square / non-interactive elements |
|
|
354
|
-
| `sm` | **4px** | 2px | Subtle rounding, tags, checkboxes |
|
|
355
|
-
| `md` | **8px** | 4px | Default buttons, inputs, interactive cards |
|
|
356
|
-
| `lg` | **12px** | 8px | Cards, panels |
|
|
357
|
-
| `xl` | 16px | 16px | Large cards, modals |
|
|
358
|
-
| `full` | 999px | 999px | Pills, avatars, circular elements |
|
|
395
|
+
Identical to Core. Mobile-first; 12-column grid; 44×44px minimum touch targets on mobile.
|
|
359
396
|
|
|
360
397
|
---
|
|
361
398
|
|
|
362
|
-
##
|
|
399
|
+
## Elevation & Depth
|
|
363
400
|
|
|
364
|
-
|
|
401
|
+
LX Studio shadows are soft — use `shadow-primary` (navy-200) for elevated surfaces, not Core's hard navy-800 shadow in light mode.
|
|
365
402
|
|
|
366
|
-
|
|
367
|
-
| -------- | --------- | ----------- |
|
|
368
|
-
| _(base)_ | 0 | 288px |
|
|
369
|
-
| `xs` | 480px | 448px |
|
|
370
|
-
| `sm` | 768px | 704px |
|
|
371
|
-
| `md` | 1024px | 896px |
|
|
372
|
-
| `lg` | 1200px | 1072px |
|
|
373
|
-
| `xl` | 1440px | 1248px |
|
|
403
|
+
---
|
|
374
404
|
|
|
375
|
-
|
|
405
|
+
## Shapes
|
|
376
406
|
|
|
377
|
-
|
|
378
|
-
| --------------------- | ------------------------------------------------ |
|
|
379
|
-
| Horizontal margins | 64px (lg+), 48px (md), 32px (sm/xs), 16px (base) |
|
|
380
|
-
| Column gaps (gutters) | 32px (lg+), 24px (md), 16px (sm/xs), 8px (base) |
|
|
381
|
-
| 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.
|
|
382
408
|
|
|
383
|
-
|
|
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 |
|
|
384
417
|
|
|
385
418
|
---
|
|
386
419
|
|
|
387
|
-
##
|
|
420
|
+
## Components
|
|
388
421
|
|
|
389
422
|
Same component library as Codecademy — all atoms, molecules, and organisms apply. Token values resolve differently per theme automatically.
|
|
390
423
|
|
|
391
|
-
|
|
424
|
+
### LX Studio visual differences
|
|
392
425
|
|
|
393
|
-
- `FillButton` uses `#
|
|
394
|
-
- `FillButton` hover shifts to `#
|
|
395
|
-
-
|
|
396
|
-
- All interactive elements have `borderRadius: md` (8px) instead of Core's 4px
|
|
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)
|
|
397
429
|
- `Card` shadows use navy-200 (soft) rather than navy-800 (hard)
|
|
398
|
-
-
|
|
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`.
|
|
399
444
|
|
|
400
445
|
---
|
|
401
446
|
|
|
@@ -403,57 +448,64 @@ Key LX Studio-specific visual differences:
|
|
|
403
448
|
|
|
404
449
|
### Colors
|
|
405
450
|
|
|
406
|
-
-
|
|
407
|
-
-
|
|
408
|
-
-
|
|
409
|
-
- **Don't** use `primary` and `interface` interchangeably — they are intentionally different purples.
|
|
410
|
-
- **Don't** treat the semantic tables as exhaustive for dark mode — they show resolved **light** values; use tokens and `colorMode` in code.
|
|
411
|
-
- **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.
|
|
412
454
|
|
|
413
455
|
### Typography
|
|
414
456
|
|
|
415
|
-
-
|
|
416
|
-
-
|
|
417
|
-
-
|
|
418
|
-
-
|
|
419
|
-
-
|
|
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.
|
|
420
462
|
|
|
421
463
|
### Layout & Spacing
|
|
422
464
|
|
|
423
|
-
-
|
|
424
|
-
-
|
|
425
|
-
-
|
|
426
|
-
-
|
|
427
|
-
|
|
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).
|
|
428
480
|
|
|
429
481
|
---
|
|
430
482
|
|
|
431
483
|
## Agent Prompt Guide
|
|
432
484
|
|
|
433
|
-
Quick color/token reference for generating or specifying LX Studio UI
|
|
434
|
-
|
|
435
|
-
| Scenario | Tokens
|
|
436
|
-
| ----------------- |
|
|
437
|
-
| Primary button | `bg: primary (#
|
|
438
|
-
| Body text | `color: text (#10162F)`, `font:
|
|
439
|
-
| Headline | `color: text-accent (#0A0D1C)`, `font:
|
|
440
|
-
| Secondary text | `color: text-secondary (
|
|
441
|
-
| Disabled text | `color: text-disabled (
|
|
442
|
-
| Elevated surface | `bg: background-primary (#FAFBFC)`
|
|
443
|
-
| Card default | `bg: background (#ffffff)`, `borderRadius: none` — add `isInteractive` for hover shadow + `borderRadius: md (8px)`
|
|
444
|
-
| Checkbox / toggle | `
|
|
445
|
-
| Error state | `color: feedback-error (#BE1809)`, `bg: background-error (#FBF1F0)`, `border: danger`
|
|
446
|
-
| Success state | `color: feedback-success (#06844F)`, `bg: background-success (#F5FFE3)`
|
|
447
|
-
| Warning state | `color: feedback-warning (#FFD300)`, `bg: background-warning (#FFFAE5)`
|
|
448
|
-
| Disabled state | `color: text-disabled (
|
|
485
|
+
Quick color/token reference for generating or specifying LX Studio UI:
|
|
486
|
+
|
|
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` |
|
|
449
501
|
|
|
450
502
|
### Component token cheatsheet
|
|
451
503
|
|
|
452
504
|
```
|
|
453
|
-
FillButton → bg: primary (#
|
|
505
|
+
FillButton → bg: primary (#1C50BB), color: white, hover: primary-hover (#10162F), radius: 8px
|
|
454
506
|
StrokeButton → bg: transparent, border: secondary (#10162F)
|
|
455
|
-
Checkbox/Toggle →
|
|
456
|
-
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
|
|
457
509
|
Alert (error) → uses feedback-error + background-error
|
|
458
510
|
Alert (success) → uses feedback-success + background-success
|
|
459
511
|
Alert (warning) → uses feedback-warning + background-warning
|