@codecademy/gamut 68.7.1-alpha.510665.0 β†’ 68.7.1-alpha.70b485.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.
@@ -180,8 +180,6 @@ This file defines the visual design tokens for codecademy.com, implemented using
180
180
  **Figma file**: https://www.figma.com/design/ReGfRNillGABAj5SlITalN/πŸ“-Gamut
181
181
  **Storybook**: https://gamut.codecademy.com
182
182
 
183
- > **Other Gamut themes:** This document covers **Codecademy** (Core, Admin, Platform) only. For Percipio or LX Studio, install that product's `DESIGN.md` instead: `gamut plugin install cursor --theme percipio` or `--theme lxstudio` (see `DESIGN.Percipio.md` / `DESIGN.LXStudio.md` in agent-tools).
184
-
185
183
  ---
186
184
 
187
185
  ## Visual Theme & Atmosphere
@@ -193,7 +191,7 @@ Codecademy communicates **logic with personality** β€” structured and trustworth
193
191
  **Design philosophy**:
194
192
 
195
193
  - Components are color mode–aware by default β€” never hardcode hex values for adaptive UI
196
- - Every component works across Core, Admin, and Platform without modification
194
+ - Every component works across all themes without modification
197
195
  - Mobile-first responsive design built on a 12-column grid
198
196
  - Accessibility is guaranteed by design: semantic color tokens meet contrast requirements per mode automatically
199
197
 
@@ -201,17 +199,46 @@ Codecademy communicates **logic with personality** β€” structured and trustworth
201
199
 
202
200
  ## Themes
203
201
 
204
- Codecademy products use **Core**, **Admin**, or **Platform** β€” the same visual identity with theme-specific palette additions on Platform. Token aliases resolve per theme automatically; components require no modification.
202
+ Codecademy products use one of four Gamut themes, all sharing the same core visual identity. Token aliases resolve to the right values per theme automatically β€” components require no modification.
203
+
204
+ | Theme | Use case | Base font | Dark mode |
205
+ | ------------- | ------------------------------- | --------------------- | -------------- |
206
+ | **Core** | Codecademy (default) | Apercu | βœ“ light + dark |
207
+ | **Admin** | Codecademy admin tools | Apercu | βœ“ light + dark |
208
+ | **Platform** | Codecademy learning environment | Apercu | βœ“ light + dark |
209
+ | **LX Studio** | LX Studio application | Skillsoft Text / Sans | light only |
210
+
211
+ The active theme is set at the app root via `<GamutProvider>`. When designing, know which theme your screen targets β€” it affects primary colors, font families, and available color weights.
212
+
213
+ **Font licensing**: Apercu is licensed for codecademy.com only. LX Studio and Percipio use Skillsoft Text and Skillsoft Sans.
214
+
215
+ For Percipio projects, use `DESIGN.Percipio.md` from the same package instead. For LX Studio, use `DESIGN.LXStudio.md`.
216
+
217
+ ### LX Studio theme overrides
218
+
219
+ LX Studio extends Core with these differences:
205
220
 
206
- | Theme | Use case | Base font | Dark mode |
207
- | ------------ | ------------------------------- | --------- | -------------- |
208
- | **Core** | Codecademy (default) | Apercu | βœ“ light + dark |
209
- | **Admin** | Codecademy admin tools | Apercu | βœ“ light + dark |
210
- | **Platform** | Codecademy learning environment | Apercu | βœ“ light + dark |
221
+ **Font**: `base` β†’ Skillsoft Text; `accent` β†’ Skillsoft Sans (no Apercu, no Suisse). Title weight is **500**, not Core's 700.
211
222
 
212
- Set the active theme at the app root via `<GamutProvider theme={coreTheme | adminTheme | platformTheme}>`.
223
+ **Border radii** (all values shift up one step):
213
224
 
214
- **Font licensing:** Apercu is licensed for codecademy.com only.
225
+ | Token | Core | LX Studio |
226
+ | ----- | ---- | --------- |
227
+ | `sm` | 2px | 4px |
228
+ | `md` | 4px | 8px |
229
+ | `lg` | 8px | 12px |
230
+
231
+ **Semantic color overrides (light mode)**:
232
+
233
+ | Token | Core value | LX Studio value |
234
+ | -------------------- | ------------------- | ----------------------------- |
235
+ | `primary` | hyper-500 `#3A10E5` | sapphire `#1C50BB` |
236
+ | `primary-hover` | hyper-400 `#5533FF` | navy-800 `#10162F` |
237
+ | `feedback-success` | green-700 `#008A27` | `#06844F` (lxStudioSuccess) |
238
+ | `background-primary` | beige `#FFF0E5` | `#FAFBFC` (lxStudioBgPrimary) |
239
+ | `shadow-primary` | navy-800 | navy-200 |
240
+ | `border-primary` | navy-800 | navy-400 |
241
+ | `border-disabled` | navy-500 | navy-300 |
215
242
 
216
243
  ---
217
244
 
@@ -221,55 +248,55 @@ Use these token names when specifying colors in designs. They resolve to the cor
221
248
 
222
249
  ### Text
223
250
 
224
- | Token | Light | Dark | Use for |
225
- | ---------------- | --------------- | ------------ | --------------------------- |
226
- | `text` | `navy-800` | `white` | Default body and UI text |
227
- | `text-accent` | `navy-900` | `beige` | Stronger emphasis text |
228
- | `text-secondary` | navy-800 at 75% | white at 65% | Supporting / secondary copy |
229
- | `text-disabled` | navy-800 at 63% | white at 50% | Disabled state labels |
251
+ | Token | Light | Dark | Use for |
252
+ | ---------------- | -------------------------- | --------------- | --------------------------- |
253
+ | `text` | navy-800 `#10162F` at 100% | white `#ffffff` | Default body and UI text |
254
+ | `text-accent` | navy-900 `#0A0D1C` | beige `#FFF0E5` | Stronger emphasis text |
255
+ | `text-secondary` | navy-800 at 75% | white at 65% | Supporting / secondary copy |
256
+ | `text-disabled` | navy-800 at 63% | white at 50% | Disabled state labels |
230
257
 
231
258
  ### Background
232
259
 
233
- | Token | Light | Dark | Use for |
234
- | --------------------- | --------------- | ------------ | --------------------------------- |
235
- | `background` | `white` | `navy-800` | Default page/component background |
236
- | `background-primary` | `beige` | `navy-900` | Slightly elevated surfaces |
237
- | `background-contrast` | `white` | `black` | Maximum contrast surface |
238
- | `background-selected` | navy-800 at 4% | white at 4% | Selected row / item |
239
- | `background-hover` | navy-800 at 12% | white at 9% | Hover state overlay |
240
- | `background-disabled` | navy-800 at 12% | white at 9% | Disabled surface |
241
- | `background-success` | `green-0` | `green-900` | Success state container |
242
- | `background-warning` | `yellow-0` | `yellow-900` | Warning state container |
243
- | `background-error` | `red-0` | `red-900` | Error state container |
260
+ | Token | Light | Dark | Use for |
261
+ | --------------------- | ------------------ | -------------------- | --------------------------------- |
262
+ | `background` | white `#ffffff` | navy-800 `#10162F` | Default page/component background |
263
+ | `background-primary` | beige `#FFF0E5` | navy-900 `#0A0D1C` | Slightly elevated surfaces |
264
+ | `background-contrast` | white | black `#000000` | Maximum contrast surface |
265
+ | `background-selected` | navy-800 at 4% | white at 4% | Selected row / item |
266
+ | `background-hover` | navy-800 at 12% | white at 9% | Hover state overlay |
267
+ | `background-disabled` | navy-800 at 12% | white at 9% | Disabled surface |
268
+ | `background-success` | green-0 `#F5FFE3` | green-900 `#151C07` | Success state container |
269
+ | `background-warning` | yellow-0 `#FFFAE5` | yellow-900 `#211B00` | Warning state container |
270
+ | `background-error` | red-0 `#FBF1F0` | red-900 `#280503` | Error state container |
244
271
 
245
272
  ### Interactive
246
273
 
247
- | Token | Light | Dark | Use for |
248
- | ----------------- | --------------- | ------------ | ------------------------------------ |
249
- | `primary` | `hyper-500` | `yellow-500` | Primary CTA, links, focus rings |
250
- | `primary-hover` | `hyper-400` | `yellow-400` | Hover state of primary interactive |
251
- | `primary-inverse` | `yellow-500` | `hyper-500` | Primary on a colored background |
252
- | `secondary` | `navy-800` | `white` | Secondary CTA, ghost buttons |
253
- | `secondary-hover` | navy-800 at 86% | white at 80% | Hover state of secondary interactive |
254
- | `danger` | `red-500` | `red-300` | Destructive actions, error states |
255
- | `danger-hover` | `red-600` | `red-400` | Hover on danger interactive |
274
+ | Token | Light | Dark | Use for |
275
+ | ----------------- | -------------------- | -------------------- | ------------------------------------ |
276
+ | `primary` | hyper-500 `#3A10E5` | yellow-500 `#FFD300` | Primary CTA, links, focus rings |
277
+ | `primary-hover` | hyper-400 `#5533FF` | yellow-400 `#CCA900` | Hover state of primary interactive |
278
+ | `primary-inverse` | yellow-500 `#FFD300` | hyper-500 `#3A10E5` | Primary on a colored background |
279
+ | `secondary` | navy-800 `#10162F` | white `#ffffff` | Secondary CTA, ghost buttons |
280
+ | `secondary-hover` | navy-800 at 86% | white at 80% | Hover state of secondary interactive |
281
+ | `danger` | red-500 `#E91C11` | red-300 `#E85D7F` | Destructive actions, error states |
282
+ | `danger-hover` | red-600 `#BE1809` | red-400 `#DC5879` | Hover on danger interactive |
256
283
 
257
284
  ### Border
258
285
 
259
- | Token | Light | Dark | Use for |
260
- | ------------------ | --------------- | ------------ | -------------------------- |
261
- | `border-primary` | `navy-800` | `white` | Strong borders, dividers |
262
- | `border-secondary` | navy-800 at 75% | white at 65% | Medium-weight borders |
263
- | `border-tertiary` | navy-800 at 28% | white at 20% | Subtle borders, separators |
264
- | `border-disabled` | navy-800 at 63% | white at 50% | Disabled input borders |
286
+ | Token | Light | Dark | Use for |
287
+ | ------------------ | ------------------ | --------------- | -------------------------- |
288
+ | `border-primary` | navy-800 `#10162F` | white `#ffffff` | Strong borders, dividers |
289
+ | `border-secondary` | navy-800 at 75% | white at 65% | Medium-weight borders |
290
+ | `border-tertiary` | navy-800 at 28% | white at 20% | Subtle borders, separators |
291
+ | `border-disabled` | navy-800 at 63% | white at 50% | Disabled input borders |
265
292
 
266
293
  ### Feedback
267
294
 
268
- | Token | Light | Dark | Use for |
269
- | ------------------ | ----------- | ----------- | -------------------------------- |
270
- | `feedback-error` | `red-600` | `red-300` | Error messages, validation |
271
- | `feedback-success` | `green-700` | `green-400` | Success messages, confirmations |
272
- | `feedback-warning` | `yellow` | `yellow-0` | Warning messages, caution states |
295
+ | Token | Light | Dark | Use for |
296
+ | ------------------ | ------------------- | ------------------- | -------------------------------- |
297
+ | `feedback-error` | red-600 `#BE1809` | red-300 `#E85D7F` | Error messages, validation |
298
+ | `feedback-success` | green-700 `#008A27` | green-400 `#AEE938` | Success messages, confirmations |
299
+ | `feedback-warning` | yellow `#FFD300` | yellow-0 `#FFFAE5` | Warning messages, caution states |
273
300
 
274
301
  ### Shadow
275
302
 
@@ -286,28 +313,32 @@ All colors available as static tokens regardless of color mode. Use these only w
286
313
 
287
314
  ### Core Palette
288
315
 
289
- | Name | Weights available | Notes |
290
- | --------------- | ---------------------------- | -------------------------------------------------------------------------- |
291
- | `navy` | 100–900 | 100–700 are rgba transparencies of `navy-800`; 800 and 900 are solid |
292
- | `white` | 100–700 | rgba transparencies of `white` (no solid white weight β€” use `white` token) |
293
- | `blue` | 0, 100, 300, 400, 500, 800 | named alias `blue` maps to `blue-500` |
294
- | `hyper` | 400, 500 | named alias `hyper` maps to `hyper-500` |
295
- | `green` | 0, 100, 400, 700, 900 | named alias `green` maps to `green-700` |
296
- | `yellow` | 0, 400, 500, 900 | named alias `yellow` maps to `yellow-500` |
297
- | `red` | 0, 300, 400, 500, 600, 900 | named alias `red` maps to `red-500` |
298
- | `gray` | 100, 200, 300, 600, 800, 900 | |
299
- | `pink` | 0, 400 | named alias `pink` maps to `pink-400` |
300
- | `orange` | 100, 500 | named alias `orange` maps to `orange-500` |
301
- | `beige` | 100 (alias: `beige`) | solid `beige` token |
302
- | `black` | β€” | `black` token |
303
- | `white` (solid) | β€” | `white` token |
316
+ | Name | Weights available | Notes |
317
+ | --------------- | ---------------------------- | --------------------------------------------------------------------------------- |
318
+ | `navy` | 100–900 | 100–700 are rgba transparencies of `#10162F`; 800 = `#10162F`; 900 = `#0A0D1C` |
319
+ | `white` | 100–700 | rgba transparencies of `#ffffff` (no solid white weight β€” use `white` for `#fff`) |
320
+ | `blue` | 0, 100, 300, 400, 500, 800 | 500 = `#1557FF` |
321
+ | `hyper` | 400, 500 | 500 = `#3A10E5` (purple-blue), 400 = `#5533FF` |
322
+ | `green` | 0, 100, 400, 700, 900 | 700 = `#008A27` |
323
+ | `yellow` | 0, 400, 500, 900 | 500 = `#FFD300` |
324
+ | `red` | 0, 300, 400, 500, 600, 900 | 500 = `#E91C11` |
325
+ | `gray` | 100, 200, 300, 600, 800, 900 | |
326
+ | `pink` | 0, 400 | 400 = `#F966FF` |
327
+ | `orange` | 100, 500 | 500 = `#FF8C00` |
328
+ | `beige` | 100 (alias: `beige`) | `#FFF0E5` |
329
+ | `black` | β€” | `#000000` |
330
+ | `white` (solid) | β€” | `#ffffff` |
304
331
 
305
332
  **Named aliases** (shorthand for common weights):
306
333
  `beige`, `blue`, `green`, `hyper`, `lightBlue`, `lightGreen`, `navy`, `orange`, `paleBlue`, `paleGreen`, `palePink`, `paleRed`, `paleYellow`, `pink`, `red`, `yellow`, `black`, `white`
307
334
 
308
335
  ### Platform-only additions
309
336
 
310
- `lightBeige`, `gold`, `teal`, `purple` (Platform theme palette)
337
+ `lightBeige` (`#FFFBF8`), `gold` (`#8A7300`), `teal` (`#006D82`), `purple` (`#B3CCFF`)
338
+
339
+ ### LX Studio additions
340
+
341
+ `sapphire` (`#1C50BB`), `lxStudioSuccess` (`#06844F`), `lxStudioBgPrimary` (`#FAFBFC`)
311
342
 
312
343
  ---
313
344
 
@@ -315,14 +346,14 @@ All colors available as static tokens regardless of color mode. Use these only w
315
346
 
316
347
  ### Typefaces
317
348
 
318
- | Token | Font stack | Use for |
319
- | ----------- | -------------------------------------------------------- | ------------------------------------------------ |
320
- | `base` | Apercu Pro (CSS: `Apercu`) | All default UI text, headlines, body copy |
321
- | `accent` | Suisse Intl Mono (CSS: `Suisse`); falls back to `Apercu` | Code, captions, labels, lists, technical context |
322
- | `monospace` | Monaco, Menlo, Ubuntu Mono, Droid Sans Mono, Consolas | Code editor contexts |
323
- | `system` | System UI fonts | Performance-critical surfaces |
349
+ | Token | Core / Admin / Platform | LX Studio | Use for |
350
+ | ----------- | -------------------------------------------------------- | ----------------------------------------------------- | ------------------------------------------------ |
351
+ | `base` | Apercu Pro (CSS: `Apercu`) | Skillsoft Text | All default UI text, headlines, body copy |
352
+ | `accent` | Suisse Intl Mono (CSS: `Suisse`); falls back to `Apercu` | Skillsoft Sans | Code, captions, labels, lists, technical context |
353
+ | `monospace` | Monaco, Menlo, Ubuntu Mono, Droid Sans Mono, Consolas | Monaco, Menlo, Ubuntu Mono, Droid Sans Mono, Consolas | Code editor contexts |
354
+ | `system` | System UI fonts | System UI fonts | Performance-critical surfaces |
324
355
 
325
- **Apercu is licensed for codecademy.com only.**
356
+ **Apercu is licensed for codecademy.com only.** LX Studio uses Skillsoft Text (`base`) and Skillsoft Sans (`accent`) with title weight 500.
326
357
 
327
358
  ### Rules
328
359
 
@@ -422,16 +453,14 @@ Interactive cards (`isInteractive` prop) gain a shadow on hover and `borderRadiu
422
453
 
423
454
  ## Border Radius Scale
424
455
 
425
- | Token | Value | Use |
426
- | ------ | ----- | ------------------------ |
427
- | `none` | 0px | Non-interactive elements |
428
- | `sm` | 2px | Interactive elements |
429
- | `md` | 4px | Overlays |
430
- | `lg` | 8px | Non-interactive elements |
431
- | `xl` | 16px | Non-interactive elements |
432
- | `full` | 999px | Toggles, badges |
433
-
434
- ---
456
+ | Token | Value | Use |
457
+ | ------ | ----- | ------------------------------------------ |
458
+ | `none` | 0px | Square / non-interactive elements |
459
+ | `sm` | 2px | Subtle rounding, tags |
460
+ | `md` | 4px | Default buttons, inputs, interactive cards |
461
+ | `lg` | 8px | Cards, panels |
462
+ | `xl` | 16px | Large cards, modals |
463
+ | `full` | 999px | Pills, avatars, circular elements |
435
464
 
436
465
  ---
437
466
 
@@ -573,8 +602,8 @@ Quick color/token reference for generating or specifying UI:
573
602
 
574
603
  | Scenario | Tokens |
575
604
  | ---------------------- | ----------------------------------------------------------------------------------------------------- |
576
- | Primary button (light) | `bg: primary`, `color: white`, `hover: primary-hover` |
577
- | Primary button (dark) | `bg: primary`, `color: text`, `hover: primary-hover` |
605
+ | Primary button (light) | `bg: primary (#3A10E5)`, `color: white`, `hover: primary-hover (#5533FF)` |
606
+ | Primary button (dark) | `bg: primary (#FFD300)`, `color: navy-800`, `hover: primary-hover (#CCA900)` |
578
607
  | Body text | `color: text`, `font: base (Apercu Pro)`, `size: 16px`, `weight: 400`, `lineHeight: base (1.5)` |
579
608
  | Headline | `color: text-accent`, `font: base`, `size: 34–64px`, `weight: title (700)`, `lineHeight: title (1.2)` |
580
609
  | Caption / label | `color: text-secondary`, `font: accent (Suisse Int'l Mono)`, `size: 14px` |
@@ -124,12 +124,10 @@ components:
124
124
 
125
125
  # LX Studio
126
126
 
127
- 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 with its own brand colors, typography, and border radii β€” all Gamut components work without modification.
127
+ 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.
128
128
 
129
129
  **Storybook**: https://gamut.codecademy.com
130
130
 
131
- > **Other Gamut themes:** This document covers **LX Studio** only. For Codecademy (Core/Admin/Platform) or Percipio, install that product's `DESIGN.md` instead: `gamut plugin install cursor --theme core` or `--theme percipio`.
132
-
133
131
  ---
134
132
 
135
133
  ## Visual Theme & Atmosphere
@@ -140,10 +138,11 @@ LX Studio communicates **modern professional craft** β€” clean, precise, and too
140
138
 
141
139
  **Design philosophy**:
142
140
 
143
- - Larger border radii (`sm`–`lg`) for a softer, more modern feel
141
+ - Light mode only β€” no dark mode support
142
+ - Larger border radii than Core give the UI a softer, more modern feel
144
143
  - Brand blue (`sapphire` / `primary`) drives CTAs, buttons, and links
145
- - Soft shadows (`shadow-primary` β†’ `navy-200`)
146
- - Skillsoft Text (`base`) and Skillsoft Sans (`accent`) for all UI typography
144
+ - Shadows are soft (navy-200) rather than hard (navy-800 in Core light mode)
145
+ - Skillsoft Text and Skillsoft Sans replace Apercu and Suisse across all font roles
147
146
 
148
147
  ---
149
148
 
@@ -165,66 +164,66 @@ Use these token names when specifying colors. LX Studio is light mode only β€” t
165
164
 
166
165
  ### Text
167
166
 
168
- | Token | Resolves to | Use for |
169
- | ---------------- | ----------- | --------------------------- |
170
- | `text` | `navy-800` | Default body and UI text |
171
- | `text-accent` | `navy-900` | Stronger emphasis text |
172
- | `text-secondary` | `navy-600` | Supporting / secondary copy |
173
- | `text-disabled` | `navy-500` | Disabled state labels |
167
+ | Token | Value | Use for |
168
+ | ---------------- | --------------------------------- | --------------------------- |
169
+ | `text` | `#10162F` (navy-800) | Default body and UI text |
170
+ | `text-accent` | `#0A0D1C` (navy-900) | Stronger emphasis text |
171
+ | `text-secondary` | navy-600 `rgba(16, 22, 47, 0.75)` | Supporting / secondary copy |
172
+ | `text-disabled` | navy-500 `rgba(16, 22, 47, 0.63)` | Disabled state labels |
174
173
 
175
174
  ### Background
176
175
 
177
- | Token | Resolves to | Use for |
178
- | --------------------- | ------------------- | --------------------------------- |
179
- | `background` | `white` | Default page/component background |
180
- | `background-primary` | `lxStudioBgPrimary` | Slightly elevated surfaces |
181
- | `background-contrast` | `white` | Maximum contrast surface |
182
- | `background-selected` | `navy-100` | Selected row / item |
183
- | `background-hover` | `navy-200` | Hover state overlay |
184
- | `background-disabled` | `navy-200` | Disabled surface |
185
- | `background-success` | `green-0` | Success state container |
186
- | `background-warning` | `yellow-0` | Warning state container |
187
- | `background-error` | `red-0` | Error state container |
176
+ | Token | Value | Use for |
177
+ | --------------------- | --------------------------------- | --------------------------------- |
178
+ | `background` | `#ffffff` | Default page/component background |
179
+ | `background-primary` | `#FAFBFC` (lxStudioBgPrimary) | Slightly elevated surfaces |
180
+ | `background-contrast` | `#ffffff` | Maximum contrast surface |
181
+ | `background-selected` | navy-100 `rgba(16, 22, 47, 0.04)` | Selected row / item |
182
+ | `background-hover` | navy-200 `rgba(16, 22, 47, 0.12)` | Hover state overlay |
183
+ | `background-disabled` | navy-200 `rgba(16, 22, 47, 0.12)` | Disabled surface |
184
+ | `background-success` | `#F5FFE3` (green-0) | Success state container |
185
+ | `background-warning` | `#FFFAE5` (yellow-0) | Warning state container |
186
+ | `background-error` | `#FBF1F0` (red-0) | Error state container |
188
187
 
189
188
  ### Interactive
190
189
 
191
- | Token | Resolves to | Use for |
192
- | ----------------- | ------------ | ------------------------------------ |
193
- | `primary` | `sapphire` | Primary CTA, links, focus rings |
194
- | `primary-hover` | `navy-800` | Hover state of primary interactive |
195
- | `primary-inverse` | `yellow-500` | Primary on a colored background |
196
- | `secondary` | `navy-800` | Secondary CTA, ghost buttons |
197
- | `secondary-hover` | `navy-700` | Hover state of secondary interactive |
198
- | `danger` | `red-500` | Destructive actions, error states |
199
- | `danger-hover` | `red-600` | Hover on danger interactive |
190
+ | Token | Value | Use for |
191
+ | ----------------- | --------------------------------- | ------------------------------------ |
192
+ | `primary` | `#1C50BB` (sapphire) | Primary CTA, links, focus rings |
193
+ | `primary-hover` | `#10162F` (navy-800) | Hover state of primary interactive |
194
+ | `primary-inverse` | `#FFD300` (yellow-500) | Primary on a colored background |
195
+ | `secondary` | `#10162F` (navy-800) | Secondary CTA, ghost buttons |
196
+ | `secondary-hover` | navy-700 `rgba(16, 22, 47, 0.86)` | Hover state of secondary interactive |
197
+ | `danger` | `#E91C11` (red-500) | Destructive actions, error states |
198
+ | `danger-hover` | `#BE1809` (red-600) | Hover on danger interactive |
200
199
 
201
200
  ### Border
202
201
 
203
- | Token | Resolves to | Use for |
204
- | ------------------ | ----------- | ------------------------------- |
205
- | `border-primary` | `navy-400` | Standard input and card borders |
206
- | `border-secondary` | `navy-600` | Medium-weight borders |
207
- | `border-tertiary` | `navy-800` | Strong structural borders |
208
- | `border-disabled` | `navy-300` | Disabled input borders |
202
+ | Token | Value | Use for |
203
+ | ------------------ | --------------------------------- | ------------------------------- |
204
+ | `border-primary` | navy-400 `rgba(16, 22, 47, 0.47)` | Standard input and card borders |
205
+ | `border-secondary` | navy-600 `rgba(16, 22, 47, 0.75)` | Medium-weight borders |
206
+ | `border-tertiary` | `#10162F` (navy-800) | Strong structural borders |
207
+ | `border-disabled` | navy-300 `rgba(16, 22, 47, 0.28)` | Disabled input borders |
209
208
 
210
- `border-primary` resolves to `navy-400` β€” mid-weight borders for inputs and cards.
209
+ LX Studio's `border-primary` is mid-gray (navy-400) rather than Core's near-black navy-800 β€” borders are softer and less prominent.
211
210
 
212
211
  ### Feedback
213
212
 
214
- | Token | Resolves to | Use for |
215
- | ------------------ | ----------------- | -------------------------------- |
216
- | `feedback-error` | `red-600` | Error messages, validation |
217
- | `feedback-success` | `lxStudioSuccess` | Success messages, confirmations |
218
- | `feedback-warning` | `yellow-500` | Warning messages, caution states |
213
+ | Token | Value | Use for |
214
+ | ------------------ | --------------------------- | -------------------------------- |
215
+ | `feedback-error` | `#BE1809` (red-600) | Error messages, validation |
216
+ | `feedback-success` | `#06844F` (lxStudioSuccess) | Success messages, confirmations |
217
+ | `feedback-warning` | `#FFD300` (yellow-500) | Warning messages, caution states |
219
218
 
220
219
  ### Shadow
221
220
 
222
- | Token | Resolves to |
223
- | ------------------ | ----------- |
224
- | `shadow-primary` | `navy-200` |
225
- | `shadow-secondary` | `navy-600` |
221
+ | Token | Value |
222
+ | ------------------ | --------------------------------- |
223
+ | `shadow-primary` | navy-200 `rgba(16, 22, 47, 0.12)` |
224
+ | `shadow-secondary` | navy-600 `rgba(16, 22, 47, 0.75)` |
226
225
 
227
- Use `shadow-primary` for standard elevated surfaces.
226
+ 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.
228
227
 
229
228
  ---
230
229
 
@@ -232,11 +231,11 @@ Use `shadow-primary` for standard elevated surfaces.
232
231
 
233
232
  LX Studio adds named colors to the core palette. Use semantic aliases in code, not these raw names.
234
233
 
235
- | Palette token | Semantic alias(es) |
236
- | ------------------- | -------------------- |
237
- | `sapphire` | `primary` |
238
- | `lxStudioSuccess` | `feedback-success` |
239
- | `lxStudioBgPrimary` | `background-primary` |
234
+ | Named color | Value | Mapped to |
235
+ | ------------------- | --------- | -------------------- |
236
+ | `sapphire` | `#1C50BB` | `primary` |
237
+ | `lxStudioSuccess` | `#06844F` | `feedback-success` |
238
+ | `lxStudioBgPrimary` | `#FAFBFC` | `background-primary` |
240
239
 
241
240
  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.).
242
241
 
@@ -246,7 +245,7 @@ The full core swatch palette (navy, hyper, blue, green, yellow, red, etc.) is al
246
245
 
247
246
  ### Typefaces
248
247
 
249
- LX Studio uses **Skillsoft Text** for body and headlines and **Skillsoft Sans** for accent UI.
248
+ LX Studio uses **Skillsoft Text** for body and headlines and **Skillsoft Sans** for accent UI. There is no Apercu and no Suisse.
250
249
 
251
250
  | Token | Font | Use for |
252
251
  | ----------- | ----------------------------------------------------- | ----------------------------------------- |
@@ -255,7 +254,7 @@ LX Studio uses **Skillsoft Text** for body and headlines and **Skillsoft Sans**
255
254
  | `monospace` | Monaco, Menlo, Ubuntu Mono, Droid Sans Mono, Consolas | Code editor contexts |
256
255
  | `system` | System UI fonts | Performance-critical surfaces |
257
256
 
258
- Skillsoft fonts are loaded via Gamut's asset provider.
257
+ Skillsoft fonts are loaded via Gamut's asset provider (same stack as Percipio).
259
258
 
260
259
  ### Rules
261
260
 
@@ -267,14 +266,14 @@ Skillsoft fonts are loaded via Gamut's asset provider.
267
266
 
268
267
  ### Font weight scale
269
268
 
270
- | Token | Value | Use |
271
- | ------- | ------- | ------------------------ |
272
- | `base` | 400 | Body text, UI labels |
273
- | `title` | **500** | Headlines, CTAs, buttons |
269
+ | Token | Value | Use |
270
+ | ------- | ------- | ---------------------------------------------------- |
271
+ | `base` | 400 | Body text, UI labels |
272
+ | `title` | **500** | Headlines, CTAs, buttons _(differs from Core's 700)_ |
274
273
 
275
274
  ### Font size scale
276
275
 
277
- Standard Gamut font size scale:
276
+ Shared with Core β€” all sizes are identical.
278
277
 
279
278
  | Token key | Size | Common use |
280
279
  | --------- | ---- | ---------------------------- |
@@ -290,7 +289,7 @@ Standard Gamut font size scale:
290
289
 
291
290
  ### Line height scale
292
291
 
293
- Standard Gamut line height scale:
292
+ Shared with Core.
294
293
 
295
294
  | Token | Value | Use |
296
295
  | ------------- | ----- | ------------------------------- |
@@ -306,7 +305,7 @@ Target 45–85 characters per line; 66 characters is ideal. Max 50 for multi-col
306
305
 
307
306
  ## Spacing Scale
308
307
 
309
- All spacing is multiples of 4px on an 8px grid.
308
+ Identical to Core. All spacing is multiples of 4px on an 8px grid.
310
309
 
311
310
  | Token | Value |
312
311
  | ----- | ----- |
@@ -326,20 +325,22 @@ All spacing is multiples of 4px on an 8px grid.
326
325
 
327
326
  ## Border Radius Scale
328
327
 
329
- | Token | Value | Use |
330
- | ------ | ----- | ------------------------ |
331
- | `none` | 0px | Non-interactive elements |
332
- | `sm` | 4px | Interactive elements |
333
- | `md` | 8px | Overlays |
334
- | `lg` | 12px | Non-interactive elements |
335
- | `xl` | 16px | Non-interactive elements |
336
- | `full` | 999px | Toggles, badges |
328
+ LX Studio uses larger border radii than Core β€” everything is one step softer.
329
+
330
+ | Token | LX Studio | Core | Use |
331
+ | ------ | --------- | ----- | ------------------------------------------ |
332
+ | `none` | 0px | 0px | Square / non-interactive elements |
333
+ | `sm` | **4px** | 2px | Subtle rounding, tags, checkboxes |
334
+ | `md` | **8px** | 4px | Default buttons, inputs, interactive cards |
335
+ | `lg` | **12px** | 8px | Cards, panels |
336
+ | `xl` | 16px | 16px | Large cards, modals |
337
+ | `full` | 999px | 999px | Pills, avatars, circular elements |
337
338
 
338
339
  ---
339
340
 
340
341
  ## Responsive Behavior
341
342
 
342
- Mobile-first; apply styles from the named breakpoint up.
343
+ Identical to Core. Mobile-first, apply styles from the named breakpoint up.
343
344
 
344
345
  | Token | Min-width | Max content |
345
346
  | -------- | --------- | ----------- |
@@ -364,14 +365,16 @@ Minimum interactive touch target: **44Γ—44px** on mobile breakpoints.
364
365
 
365
366
  ## Component Library
366
367
 
367
- Gamut atoms, molecules, and organisms all apply. Use semantic tokens below for LX Studio styling.
368
+ Same component library as Codecademy β€” all atoms, molecules, and organisms apply. Token values resolve differently per theme automatically.
368
369
 
369
- Key patterns:
370
+ Key LX Studio-specific visual differences:
370
371
 
371
- - `FillButton` β€” `bg: primary` (`sapphire`), `hover: primary-hover` (`navy-800`)
372
- - `Checkbox` / `Toggle` β€” `primary`, `hover: primary-hover` (same as `FillButton`)
373
- - Buttons and inputs β€” `borderRadius: md` (8px)
374
- - `Card` β€” `shadow-primary` (`navy-200`); elevated surfaces use `background-primary` (`lxStudioBgPrimary`), not beige
372
+ - `FillButton` uses sapphire `#1C50BB` instead of hyper-500
373
+ - `FillButton` hover shifts to navy-800 `#10162F` β€” darker on hover
374
+ - `Checkbox` / `Toggle` use hyper-500 `#3A10E5`
375
+ - All interactive elements have `borderRadius: md` (8px) instead of Core's 4px
376
+ - `Card` shadows use navy-200 (soft) rather than navy-800 (hard)
377
+ - No `Card-beige` variant β€” LX Studio `background-primary` is off-white, not beige
375
378
 
376
379
  ---
377
380
 
@@ -380,15 +383,15 @@ Key patterns:
380
383
  ### Colors
381
384
 
382
385
  - **Do** use semantic color aliases (`primary`, `text`, `background`, etc.) β€” never hardcode hex values.
383
- - **Do** use `primary` (resolves to palette `sapphire`) for buttons and links.
386
+ - **Do** use `primary` / `sapphire` (`#1C50BB`) for buttons and links.
384
387
  - **Don't** attempt dark mode β€” LX Studio is light only.
385
- - **Don't** use raw palette swatches for adaptive UI β€” use semantic aliases.
388
+ - **Don't** use the Percipio or Codecademy primary blue/hyper colors directly; go through semantic aliases.
386
389
 
387
390
  ### Typography
388
391
 
389
392
  - **Do** use `fontWeight="title"` (500) for headlines, CTAs, and buttons.
390
393
  - **Do** keep body text at 150–175% line height for readability.
391
- - **Don't** use fonts outside the LX Studio theme stack (Skillsoft Text, Skillsoft Sans).
394
+ - **Don't** use Apercu, Suisse, or Hanken Grotesk β€” LX Studio uses Skillsoft Text and Skillsoft Sans.
392
395
  - **Don't** right-align or center-align body paragraphs.
393
396
  - **Don't** adjust letter-spacing.
394
397
 
@@ -405,26 +408,26 @@ Key patterns:
405
408
 
406
409
  Quick color/token reference for generating or specifying LX Studio UI:
407
410
 
408
- | Scenario | Tokens |
409
- | ---------------- | -------------------------------------------------------------------------------------------------- |
410
- | Primary button | `bg: primary`, `color: white`, `hover: primary-hover`, `borderRadius: md` |
411
- | Body text | `color: text`, `font: base`, `size: 16`, `weight: 400`, `lineHeight: base` |
412
- | Headline | `color: text-accent`, `font: base`, `size: 34–64`, `weight: title`, `lineHeight: title` |
413
- | Secondary text | `color: text-secondary` |
414
- | Disabled text | `color: text-disabled` |
415
- | Elevated surface | `bg: background-primary` |
416
- | Card default | `bg: background`, `borderRadius: none` β€” add `isInteractive` for hover shadow + `borderRadius: md` |
417
- | Error state | `color: feedback-error`, `bg: background-error`, `borderColor: danger` |
418
- | Success state | `color: feedback-success`, `bg: background-success` |
419
- | Warning state | `color: feedback-warning`, `bg: background-warning` |
420
- | Disabled state | `color: text-disabled`, `bg: background-disabled`, `borderColor: border-disabled` |
411
+ | Scenario | Tokens |
412
+ | ---------------- | ------------------------------------------------------------------------------------------------------------------------- |
413
+ | Primary button | `bg: primary (#1C50BB)`, `color: white`, `hover: primary-hover (#10162F)`, `borderRadius: md (8px)` |
414
+ | Body text | `color: text (#10162F)`, `font: Skillsoft Text`, `size: 16px`, `weight: 400`, `lineHeight: base (1.5)` |
415
+ | Headline | `color: text-accent (#0A0D1C)`, `font: Skillsoft Text`, `size: 34–64px`, `weight: title (500)`, `lineHeight: title (1.2)` |
416
+ | Secondary text | `color: text-secondary (navy-600)` |
417
+ | Disabled text | `color: text-disabled (navy-500)` |
418
+ | Elevated surface | `bg: background-primary (#FAFBFC)` |
419
+ | Card default | `bg: background (#ffffff)`, `borderRadius: none` β€” add `isInteractive` for hover shadow + `borderRadius: md (8px)` |
420
+ | Error state | `color: feedback-error (#BE1809)`, `bg: background-error (#FBF1F0)`, `border: danger` |
421
+ | Success state | `color: feedback-success (#06844F)`, `bg: background-success (#F5FFE3)` |
422
+ | Warning state | `color: feedback-warning (#FFD300)`, `bg: background-warning (#FFFAE5)` |
423
+ | Disabled state | `color: text-disabled (navy-500)`, `bg: background-disabled (navy-200)`, `border: border-disabled` |
421
424
 
422
425
  ### Component token cheatsheet
423
426
 
424
427
  ```
425
- FillButton β†’ bg: primary, color: white, hover: primary-hover, borderRadius: md
426
- StrokeButton β†’ bg: transparent, borderColor: secondary
427
- Checkbox/Toggle β†’ bg: primary, hover: primary-hover, borderRadius: sm
428
+ FillButton β†’ bg: primary (#1C50BB), color: white, hover: primary-hover (#10162F), radius: 8px
429
+ StrokeButton β†’ bg: transparent, border: secondary (#10162F)
430
+ Checkbox/Toggle β†’ hyper-500 (#3A10E5), hover: hyper-400 (#5533FF), radius: 4px
428
431
  Card β†’ bg: background, shadow: shadow-primary (navy-200, soft), radius: none
429
432
  Alert (error) β†’ uses feedback-error + background-error
430
433
  Alert (success) β†’ uses feedback-success + background-success
@@ -118,23 +118,21 @@ This file defines the visual design tokens for the Skillsoft Percipio platform,
118
118
 
119
119
  **Storybook**: https://gamut.codecademy.com
120
120
 
121
- > **Other Gamut themes:** This document covers **Percipio** only. For Codecademy (Core/Admin/Platform) or LX Studio, install that product's `DESIGN.md` instead: `gamut plugin install cursor --theme core` or `--theme lxstudio`.
122
-
123
121
  ---
124
122
 
125
123
  ## Visual Theme & Atmosphere
126
124
 
127
- Percipio communicates **professional clarity** β€” clean, trustworthy, and enterprise-ready. The design voice is neutral and corporate: functional, with clear hierarchy. Brand blue drives interactive affordances; neutral grays define text and structure.
125
+ Percipio communicates **professional clarity** β€” clean, trustworthy, and enterprise-ready. The design voice is more neutral and corporate than Codecademy: less playful, more functional. Primary blue drives interactive affordances; neutral grays define text and structure.
128
126
 
129
- **Density**: Medium. Information-dense layouts with softer shadows and a muted neutral palette.
127
+ **Density**: Medium. Consistent with Codecademy layouts but with softer shadows and a lighter overall feel due to the muted neutral palette.
130
128
 
131
129
  **Design philosophy**:
132
130
 
133
131
  - Light mode only β€” no dark mode support
134
- - Brand blue (`sapphire` / `primary`) for buttons, links, and focus rings
135
- - Text uses dedicated Percipio palette tokens (`percipioTextPrimary`, etc.)
136
- - Shadows are soft and minimal (`shadow-primary` β†’ `navy-200`)
137
- - Title font weight is **500** via `fontWeight="title"` β€” use semantic weight, not literal `700`
132
+ - Brand blue (`sapphire` / `primary`) replaces Codecademy's `hyper-500` for buttons, links, and focus rings
133
+ - Text is near-black dark gray rather than navy
134
+ - Shadows are soft and minimal (navy at low opacity) rather than hard borders
135
+ - Title font weight is 500 (medium) rather than 700 (bold) β€” Percipio headlines are less heavy
138
136
 
139
137
  ---
140
138
 
@@ -156,65 +154,65 @@ Use these token names when specifying colors. Percipio is light mode only β€” th
156
154
 
157
155
  ### Text
158
156
 
159
- | Token | Resolves to | Use for |
160
- | ---------------- | ----------------------- | ------------------------------------------------ |
161
- | `text` | `percipioTextPrimary` | Default body and UI text |
162
- | `text-accent` | `percipioTextPrimary` | Emphasis text (same value as `text` in Percipio) |
163
- | `text-secondary` | `percipioTextSecondary` | Supporting / secondary copy |
164
- | `text-disabled` | `percipioTextDisabled` | Disabled state labels |
157
+ | Token | Value | Use for |
158
+ | ---------------- | ------------------------ | ------------------------------------------------ |
159
+ | `text` | `#222325` | Default body and UI text |
160
+ | `text-accent` | `#222325` | Emphasis text (same value as `text` in Percipio) |
161
+ | `text-secondary` | `rgba(34, 35, 37, 0.75)` | Supporting / secondary copy |
162
+ | `text-disabled` | `#AFB6C2` | Disabled state labels |
165
163
 
166
164
  ### Background
167
165
 
168
- | Token | Resolves to | Use for |
169
- | --------------------- | ------------------- | --------------------------------- |
170
- | `background` | `white` | Default page/component background |
171
- | `background-primary` | `percipioBgPrimary` | Slightly elevated surfaces |
172
- | `background-selected` | `navy-100` | Selected row / item |
173
- | `background-hover` | `navy-200` | Hover state overlay |
174
- | `background-disabled` | `navy-200` | Disabled surface |
175
- | `background-success` | `percipioBgSuccess` | Success state container |
176
- | `background-warning` | `percipioBgWarning` | Warning state container |
177
- | `background-error` | `percipioBgError` | Error state container |
166
+ | Token | Value | Use for |
167
+ | --------------------- | --------------------------------- | --------------------------------- |
168
+ | `background` | `#ffffff` | Default page/component background |
169
+ | `background-primary` | `#FAFBFC` | Slightly elevated surfaces |
170
+ | `background-selected` | navy-100 `rgba(16, 22, 47, 0.04)` | Selected row / item |
171
+ | `background-hover` | navy-200 `rgba(16, 22, 47, 0.12)` | Hover state overlay |
172
+ | `background-disabled` | navy-200 `rgba(16, 22, 47, 0.12)` | Disabled surface |
173
+ | `background-success` | `#EEF7F3` | Success state container |
174
+ | `background-warning` | `#FFF7E0` | Warning state container |
175
+ | `background-error` | `#FFF1F5` | Error state container |
178
176
 
179
177
  ### Interactive
180
178
 
181
- | Token | Resolves to | Use for |
182
- | ----------------- | ------------------------------ | ------------------------------------ |
183
- | `primary` | `sapphire` | Primary CTA, links, focus rings |
184
- | `primary-hover` | `percipioActionPrimaryHover` | Hover state of primary interactive |
185
- | `primary-inverse` | `white` | Primary on a colored background |
186
- | `secondary` | `percipioActionSecondary` | Secondary CTA, ghost buttons |
187
- | `secondary-hover` | `percipioActionSecondaryHover` | Hover state of secondary interactive |
188
- | `danger` | `percipioDanger` | Destructive actions, error states |
189
- | `danger-hover` | `percipioActionDangerHover` | Hover on danger interactive |
179
+ | Token | Value | Use for |
180
+ | ----------------- | --------------------------- | ------------------------------------ |
181
+ | `primary` | `#1C50BB` (sapphire) | Primary CTA, links, focus rings |
182
+ | `primary-hover` | `#141C36` | Hover state of primary interactive |
183
+ | `primary-inverse` | `#ffffff` | Primary on a colored background |
184
+ | `secondary` | `#6A6E75` | Secondary CTA, ghost buttons |
185
+ | `secondary-hover` | `rgba(106, 110, 117, 0.86)` | Hover state of secondary interactive |
186
+ | `danger` | `#B83C3C` | Destructive actions, error states |
187
+ | `danger-hover` | `#A52020` | Hover on danger interactive |
190
188
 
191
189
  ### Border
192
190
 
193
191
  Percipio's border weights use a non-standard order: `primary` is mid-weight, `secondary` is very light, `tertiary` is the strongest (solid navy). Use them for their semantic intent, not their numeric rank.
194
192
 
195
- | Token | Resolves to | Use for |
196
- | ------------------ | ----------- | ----------------------------------- |
197
- | `border-primary` | `navy-400` | Standard input and card borders |
198
- | `border-secondary` | `navy-200` | Subtle dividers, section separators |
199
- | `border-tertiary` | `navy-800` | Strong structural borders |
200
- | `border-disabled` | `navy-300` | Disabled input borders |
193
+ | Token | Value | Use for |
194
+ | ------------------ | --------------------------------- | ----------------------------------- |
195
+ | `border-primary` | navy-400 `rgba(16, 22, 47, 0.47)` | Standard input and card borders |
196
+ | `border-secondary` | navy-200 `rgba(16, 22, 47, 0.12)` | Subtle dividers, section separators |
197
+ | `border-tertiary` | `#10162F` (navy-800) | Strong structural borders |
198
+ | `border-disabled` | navy-300 `rgba(16, 22, 47, 0.28)` | Disabled input borders |
201
199
 
202
200
  ### Feedback
203
201
 
204
- | Token | Resolves to | Use for |
205
- | ------------------ | ------------------------- | -------------------------------- |
206
- | `feedback-error` | `percipioDanger` | Error messages, validation |
207
- | `feedback-success` | `percipioFeedbackSuccess` | Success messages, confirmations |
208
- | `feedback-warning` | `percipioFeedbackWarning` | Warning messages, caution states |
202
+ | Token | Value | Use for |
203
+ | ------------------ | --------- | -------------------------------- |
204
+ | `feedback-error` | `#B83C3C` | Error messages, validation |
205
+ | `feedback-success` | `#1B8057` | Success messages, confirmations |
206
+ | `feedback-warning` | `#EF5B0D` | Warning messages, caution states |
209
207
 
210
208
  ### Shadow
211
209
 
212
- | Token | Resolves to |
213
- | ------------------ | ----------- |
214
- | `shadow-primary` | `navy-200` |
215
- | `shadow-secondary` | `navy-400` |
210
+ | Token | Value |
211
+ | ------------------ | --------------------------------- |
212
+ | `shadow-primary` | navy-200 `rgba(16, 22, 47, 0.12)` |
213
+ | `shadow-secondary` | navy-400 `rgba(16, 22, 47, 0.47)` |
216
214
 
217
- Use `shadow-primary` for standard elevated surfaces.
215
+ Percipio shadows are softer than Codecademy's β€” use `shadow-primary` for standard elevated surfaces.
218
216
 
219
217
  ---
220
218
 
@@ -222,23 +220,23 @@ Use `shadow-primary` for standard elevated surfaces.
222
220
 
223
221
  Percipio introduces its own named semantic colors. These are the source values behind the aliases above. Use the semantic aliases in designs, not the raw named colors.
224
222
 
225
- | Palette token | Semantic alias(es) |
226
- | ------------------------------ | -------------------------- |
227
- | `percipioTextPrimary` | `text`, `text-accent` |
228
- | `percipioTextSecondary` | `text-secondary` |
229
- | `percipioTextDisabled` | `text-disabled` |
230
- | `sapphire` | `primary` |
231
- | `percipioActionPrimaryHover` | `primary-hover` |
232
- | `percipioActionSecondary` | `secondary` |
233
- | `percipioActionSecondaryHover` | `secondary-hover` |
234
- | `percipioActionDangerHover` | `danger-hover` |
235
- | `percipioDanger` | `danger`, `feedback-error` |
236
- | `percipioFeedbackSuccess` | `feedback-success` |
237
- | `percipioFeedbackWarning` | `feedback-warning` |
238
- | `percipioBgPrimary` | `background-primary` |
239
- | `percipioBgSuccess` | `background-success` |
240
- | `percipioBgWarning` | `background-warning` |
241
- | `percipioBgError` | `background-error` |
223
+ | Named color | Value | Mapped to |
224
+ | ------------------------------ | --------------------------- | -------------------------- |
225
+ | `percipioTextPrimary` | `#222325` | `text`, `text-accent` |
226
+ | `percipioTextSecondary` | `rgba(34, 35, 37, 0.75)` | `text-secondary` |
227
+ | `percipioTextDisabled` | `#AFB6C2` | `text-disabled` |
228
+ | `sapphire` | `#1C50BB` | `primary` |
229
+ | `percipioActionPrimaryHover` | `#141C36` | `primary-hover` |
230
+ | `percipioActionSecondary` | `#6A6E75` | `secondary` |
231
+ | `percipioActionSecondaryHover` | `rgba(106, 110, 117, 0.86)` | `secondary-hover` |
232
+ | `percipioActionDangerHover` | `#A52020` | `danger-hover` |
233
+ | `percipioDanger` | `#B83C3C` | `danger`, `feedback-error` |
234
+ | `percipioFeedbackSuccess` | `#1B8057` | `feedback-success` |
235
+ | `percipioFeedbackWarning` | `#EF5B0D` | `feedback-warning` |
236
+ | `percipioBgPrimary` | `#FAFBFC` | `background-primary` |
237
+ | `percipioBgSuccess` | `#EEF7F3` | `background-success` |
238
+ | `percipioBgWarning` | `#FFF7E0` | `background-warning` |
239
+ | `percipioBgError` | `#FFF1F5` | `background-error` |
242
240
 
243
241
  The full core swatch palette (navy, blue, green, yellow, red, etc.) is also available, but the semantic aliases above are how Percipio maps them. Raw swatches should only be used for fixed colors that must not adapt (illustrations, data viz, etc.).
244
242
 
@@ -266,14 +264,16 @@ Percipio uses **Skillsoft Text** for body and headlines and **Skillsoft Sans** f
266
264
 
267
265
  ### Font weight scale
268
266
 
269
- | Token | Value | Use |
270
- | ------- | ------- | ------------------------ |
271
- | `base` | 400 | Body text, UI labels |
272
- | `title` | **500** | Headlines, CTAs, buttons |
267
+ Percipio overrides the title weight from Core's 700 to 500 (medium). This gives Percipio a lighter, less heavy headline style.
268
+
269
+ | Token | Value | Use |
270
+ | ------- | ------- | ---------------------------------------------------------- |
271
+ | `base` | 400 | Body text, UI labels |
272
+ | `title` | **500** | Headlines, CTAs, buttons _(differs from Codecademy's 700)_ |
273
273
 
274
274
  ### Font size scale
275
275
 
276
- Standard Gamut font size scale:
276
+ Shared with Core β€” all sizes are identical.
277
277
 
278
278
  | Token key | Size | Common use |
279
279
  | --------- | ---- | ---------------------------- |
@@ -289,7 +289,7 @@ Standard Gamut font size scale:
289
289
 
290
290
  ### Line height scale
291
291
 
292
- Standard Gamut line height scale:
292
+ Shared with Core.
293
293
 
294
294
  | Token | Value | Use |
295
295
  | ------------- | ----- | ------------------------------- |
@@ -305,7 +305,7 @@ Target 45–85 characters per line; 66 characters is ideal. Max 50 for multi-col
305
305
 
306
306
  ## Spacing Scale
307
307
 
308
- All spacing is multiples of 4px on an 8px grid.
308
+ Identical to Core. All spacing is multiples of 4px on an 8px grid.
309
309
 
310
310
  | Token | Value |
311
311
  | ----- | ----- |
@@ -325,20 +325,22 @@ All spacing is multiples of 4px on an 8px grid.
325
325
 
326
326
  ## Border Radius Scale
327
327
 
328
- | Token | Value | Use |
329
- | ------ | ----- | ------------------------ |
330
- | `none` | 0px | Non-interactive elements |
331
- | `sm` | 2px | Interactive elements |
332
- | `md` | 4px | Overlays |
333
- | `lg` | 8px | Non-interactive elements |
334
- | `xl` | 16px | Non-interactive elements |
335
- | `full` | 999px | Toggles, badges |
328
+ Identical to Core.
329
+
330
+ | Token | Value | Use |
331
+ | ------ | ----- | ------------------------------------------ |
332
+ | `none` | 0px | Square / non-interactive elements |
333
+ | `sm` | 2px | Subtle rounding, tags |
334
+ | `md` | 4px | Default buttons, inputs, interactive cards |
335
+ | `lg` | 8px | Cards, panels |
336
+ | `xl` | 16px | Large cards, modals |
337
+ | `full` | 999px | Pills, avatars, circular elements |
336
338
 
337
339
  ---
338
340
 
339
341
  ## Responsive Behavior
340
342
 
341
- Mobile-first; apply styles from the named breakpoint up.
343
+ Identical to Core. Mobile-first, apply styles from the named breakpoint up.
342
344
 
343
345
  | Token | Min-width | Max content |
344
346
  | -------- | --------- | ----------- |
@@ -363,13 +365,15 @@ Minimum interactive touch target: **44Γ—44px** on mobile breakpoints.
363
365
 
364
366
  ## Component Library
365
367
 
366
- Gamut atoms, molecules, and organisms all apply. Use semantic tokens below for Percipio-specific styling.
368
+ Same component library as Codecademy β€” all atoms, molecules, and organisms apply. Token values resolve differently per theme automatically.
367
369
 
368
- Key patterns:
370
+ Key Percipio-specific visual differences:
369
371
 
370
- - `FillButton` β€” `bg: primary`, `hover: primary-hover`
371
- - `Checkbox` / `Toggle` β€” `primary`, `hover: primary-hover`
372
- - `Card` β€” `shadow-primary` (`navy-200`); `patternLeft` / `patternRight` are available but rarely used
372
+ - `FillButton` uses sapphire `#1C50BB` instead of hyper-purple
373
+ - `FillButton` hover shifts to near-black `#141C36` rather than a lighter blue
374
+ - `Checkbox` / `Toggle` use sapphire `#1C50BB` via `primary`
375
+ - `Card` has softer shadows (navy-200 vs navy-800 in Codecademy light mode)
376
+ - Card shadow patterns (`patternLeft`, `patternRight`) are available but rarely used in Percipio UIs
373
377
 
374
378
  ---
375
379
 
@@ -378,14 +382,15 @@ Key patterns:
378
382
  ### Colors
379
383
 
380
384
  - **Do** use semantic color aliases (`primary`, `text`, `background`, etc.) β€” never hardcode hex values.
381
- - **Do** use `primary` (resolves to palette `sapphire`) as the brand interactive color.
385
+ - **Do** use `primary` / `sapphire` (`#1C50BB`) as the brand interactive color.
386
+ - **Don't** use Codecademy's hyper-purple or yellow in Percipio contexts.
382
387
  - **Don't** attempt dark mode β€” Percipio is light only.
383
388
 
384
389
  ### Typography
385
390
 
386
391
  - **Do** use title weight (500) for headlines, CTAs, and buttons β€” not 700.
387
392
  - **Do** keep body text at 150–175% line height for readability.
388
- - **Don't** use fonts outside the Percipio theme stack (Skillsoft Text, Skillsoft Sans, Roboto Mono for code).
393
+ - **Don't** use Apercu or Suisse β€” Percipio uses Skillsoft Text and Skillsoft Sans.
389
394
  - **Don't** right-align or center-align body paragraphs.
390
395
  - **Don't** adjust letter-spacing.
391
396
 
@@ -401,26 +406,26 @@ Key patterns:
401
406
 
402
407
  Quick color/token reference for generating or specifying Percipio UI:
403
408
 
404
- | Scenario | Tokens |
405
- | ---------------- | -------------------------------------------------------------------------------------------------- |
406
- | Primary button | `bg: primary`, `color: primary-inverse`, `hover: primary-hover` |
407
- | Body text | `color: text`, `font: base`, `size: 16`, `weight: 400`, `lineHeight: base` |
408
- | Headline | `color: text`, `font: base`, `size: 34–64`, `weight: title`, `lineHeight: title` |
409
- | Secondary text | `color: text-secondary` |
410
- | Disabled text | `color: text-disabled` |
411
- | Elevated surface | `bg: background-primary` |
412
- | Card default | `bg: background`, `borderRadius: none` β€” add `isInteractive` for hover shadow + `borderRadius: md` |
413
- | Error state | `color: feedback-error`, `bg: background-error`, `borderColor: danger` |
414
- | Success state | `color: feedback-success`, `bg: background-success` |
415
- | Warning state | `color: feedback-warning`, `bg: background-warning` |
416
- | Disabled state | `color: text-disabled`, `bg: background-disabled`, `borderColor: border-disabled` |
409
+ | Scenario | Tokens |
410
+ | ---------------- | ------------------------------------------------------------------------------------------------------------------ |
411
+ | Primary button | `bg: primary (#1C50BB)`, `color: white`, `hover: primary-hover (#141C36)` |
412
+ | Body text | `color: text (#222325)`, `font: Skillsoft Text`, `size: 16px`, `weight: 400`, `lineHeight: base (1.5)` |
413
+ | Headline | `color: text (#222325)`, `font: Skillsoft Text`, `size: 34–64px`, `weight: title (500)`, `lineHeight: title (1.2)` |
414
+ | Secondary text | `color: text-secondary (rgba(34, 35, 37, 0.75))` |
415
+ | Disabled text | `color: text-disabled (#AFB6C2)` |
416
+ | Elevated surface | `bg: background-primary (#FAFBFC)` |
417
+ | Card default | `bg: background (#ffffff)`, `borderRadius: none` β€” add `isInteractive` for hover shadow + `borderRadius: md` |
418
+ | Error state | `color: feedback-error (#B83C3C)`, `bg: background-error (#FFF1F5)`, `border: danger` |
419
+ | Success state | `color: feedback-success (#1B8057)`, `bg: background-success (#EEF7F3)` |
420
+ | Warning state | `color: feedback-warning (#EF5B0D)`, `bg: background-warning (#FFF7E0)` |
421
+ | Disabled state | `color: text-disabled (#AFB6C2)`, `bg: background-disabled (navy-200)`, `border: border-disabled` |
417
422
 
418
423
  ### Component token cheatsheet
419
424
 
420
425
  ```
421
- FillButton β†’ bg: primary, color: primary-inverse, hover: primary-hover
422
- StrokeButton β†’ bg: transparent, borderColor: secondary, hover: secondary-hover
423
- Checkbox/Toggle β†’ bg: primary, hover: primary-hover
426
+ FillButton β†’ bg: primary (#1C50BB), color: white, hover: primary-hover (#141C36)
427
+ StrokeButton β†’ bg: transparent, border: secondary (#6A6E75)
428
+ Checkbox/Toggle β†’ primary (#1C50BB), hover: primary-hover (#141C36)
424
429
  Card β†’ bg: background, shadow: shadow-primary (navy-200, soft)
425
430
  Alert (error) β†’ uses feedback-error + background-error
426
431
  Alert (success) β†’ uses feedback-success + background-success
@@ -1,12 +1,7 @@
1
- Product-specific design context lives in this directory. **Use one `DESIGN.md` per app β€” matched to the Gamut theme that app uses.**
1
+ Product-specific design context lives in this directory:
2
2
 
3
- | Source file | Install with `--theme` |
4
- | ---------------------- | --------------------------------------------------------- |
5
- | `DESIGN.Codecademy.md` | `core`, `admin`, `platform` (aliases: `codecademy`, `cc`) |
6
- | `DESIGN.Percipio.md` | `percipio` |
7
- | `DESIGN.LXStudio.md` | `lxstudio` (alias: `lx-studio`) |
3
+ - `DESIGN.Codecademy.md` β€” Core, Admin, and Platform themes
4
+ - `DESIGN.Percipio.md` β€” Percipio theme
5
+ - `DESIGN.LXStudio.md` β€” LX Studio theme
8
6
 
9
- ```sh
10
- gamut plugin install cursor --theme <name>
11
- # refresh: gamut plugin update cursor --theme <name> --force
12
- ```
7
+ Install into your app repo with `gamut plugin install cursor --theme <core|percipio|lxstudio|admin|platform>` (or `claude`) to copy the matching file to the repo root as `DESIGN.md`.
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@codecademy/gamut",
3
3
  "description": "Styleguide & Component library for Codecademy",
4
- "version": "68.7.1-alpha.510665.0",
4
+ "version": "68.7.1-alpha.70b485.0",
5
5
  "author": "Codecademy Engineering <dev@codecademy.com>",
6
6
  "bin": "./bin/gamut.mjs",
7
7
  "dependencies": {
8
- "@codecademy/gamut-icons": "9.57.6-alpha.510665.0",
9
- "@codecademy/gamut-illustrations": "0.58.12-alpha.510665.0",
10
- "@codecademy/gamut-patterns": "0.10.31-alpha.510665.0",
11
- "@codecademy/gamut-styles": "18.0.1-alpha.510665.0",
12
- "@codecademy/variance": "0.26.2-alpha.510665.0",
8
+ "@codecademy/gamut-icons": "9.57.6-alpha.70b485.0",
9
+ "@codecademy/gamut-illustrations": "0.58.12-alpha.70b485.0",
10
+ "@codecademy/gamut-patterns": "0.10.31-alpha.70b485.0",
11
+ "@codecademy/gamut-styles": "18.0.1-alpha.70b485.0",
12
+ "@codecademy/variance": "0.26.2-alpha.70b485.0",
13
13
  "@formatjs/intl-locale": "5.3.1",
14
14
  "@react-aria/interactions": "3.25.0",
15
15
  "@types/marked": "^4.0.8",