@codecademy/gamut 68.7.1-alpha.1ea5a8.0 → 68.7.1-alpha.29afd9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/agent-tools/DESIGN.Codecademy.md +120 -90
  2. package/agent-tools/DESIGN.LXStudio.md +132 -127
  3. package/agent-tools/DESIGN.Percipio.md +134 -129
  4. package/agent-tools/DESIGN.md +1 -12
  5. package/bin/lib/claude.mjs +14 -5
  6. package/bin/lib/cursor.mjs +4 -1
  7. package/dist/AccordionButtonDeprecated/ButtonDeprecated/index.d.ts +2 -2
  8. package/dist/AccordionButtonDeprecated/ButtonDeprecated/index.js +1 -1
  9. package/dist/Alert/elements.d.ts +2 -2
  10. package/dist/Anchor/index.d.ts +19 -9
  11. package/dist/Anchor/index.js +9 -6
  12. package/dist/BarChart/BarRow/elements.d.ts +47 -45
  13. package/dist/BarChart/utils/hooks.d.ts +2 -2
  14. package/dist/BarChart/utils/hooks.js +3 -1
  15. package/dist/Box/GridBox.d.ts +1 -0
  16. package/dist/Box/GridBox.js +1 -1
  17. package/dist/Box/props.d.ts +1 -1
  18. package/dist/Breadcrumbs/index.d.ts +5 -5
  19. package/dist/Breadcrumbs/index.js +2 -2
  20. package/dist/Button/CTAButton.d.ts +2 -2
  21. package/dist/Button/FillButton.d.ts +4 -4
  22. package/dist/Button/IconButton.d.ts +4 -4
  23. package/dist/Button/StrokeButton.d.ts +4 -4
  24. package/dist/Button/TextButton.d.ts +4 -4
  25. package/dist/Button/shared/InlineIconButton.d.ts +2 -2
  26. package/dist/Button/shared/styles.d.ts +3 -3
  27. package/dist/Button/shared/types.d.ts +1 -1
  28. package/dist/ButtonBase/ButtonBase.d.ts +9 -4
  29. package/dist/ButtonBase/ButtonBase.js +11 -4
  30. package/dist/Card/elements.d.ts +109 -103
  31. package/dist/Card/styles.d.ts +8 -8
  32. package/dist/Coachmark/index.d.ts +1 -1
  33. package/dist/ConnectedForm/ConnectedForm.d.ts +1 -1
  34. package/dist/ConnectedForm/ConnectedFormGroup.js +4 -3
  35. package/dist/ConnectedForm/utils.d.ts +1 -1
  36. package/dist/ConnectedForm/utils.js +1 -1
  37. package/dist/DatePicker/DatePickerInput/index.d.ts +1 -1
  38. package/dist/Disclosure/elements.d.ts +18 -12
  39. package/dist/FeatureShimmer/index.js +1 -1
  40. package/dist/Form/SelectDropdown/SelectDropdown.js +1 -1
  41. package/dist/Form/SelectDropdown/elements/containers.js +1 -1
  42. package/dist/Form/SelectDropdown/elements/controls.js +2 -2
  43. package/dist/Form/SelectDropdown/elements/multi-value.js +2 -2
  44. package/dist/Form/SelectDropdown/types/internal.d.ts +2 -2
  45. package/dist/Form/SelectDropdown/utils.js +2 -1
  46. package/dist/Form/elements/Form.d.ts +15 -15
  47. package/dist/Form/elements/FormGroup.d.ts +1 -1
  48. package/dist/Form/styles/Checkbox-styles.d.ts +1 -1
  49. package/dist/GridForm/GridFormButtons/index.d.ts +4 -4
  50. package/dist/List/ListProvider.d.ts +1 -1
  51. package/dist/List/elements.d.ts +44 -42
  52. package/dist/Menu/MenuItem.js +10 -6
  53. package/dist/Menu/elements.d.ts +2 -2
  54. package/dist/Modals/Dialog.js +6 -2
  55. package/dist/Modals/Modal.js +5 -2
  56. package/dist/Modals/elements.d.ts +1 -1
  57. package/dist/Pagination/AnimatedPaginationButtons.d.ts +31 -29
  58. package/dist/Pagination/EllipsisButton.d.ts +2 -2
  59. package/dist/Pagination/PaginationButton.d.ts +6 -6
  60. package/dist/Pagination/utils.d.ts +31 -29
  61. package/dist/Pagination/utils.js +14 -11
  62. package/dist/Popover/Popover.js +6 -6
  63. package/dist/Popover/types.d.ts +4 -3
  64. package/dist/PopoverContainer/PopoverContainer.js +9 -9
  65. package/dist/PopoverContainer/hooks.d.ts +16 -4
  66. package/dist/PopoverContainer/hooks.js +50 -27
  67. package/dist/PopoverContainer/types.d.ts +2 -1
  68. package/dist/Tabs/TabButton.d.ts +2 -2
  69. package/dist/Tabs/TabNavLink.d.ts +2 -2
  70. package/dist/Tag/elements.d.ts +14 -8
  71. package/dist/Tag/index.js +1 -1
  72. package/dist/Tip/InfoTip/InfoTipButton.d.ts +4 -4
  73. package/dist/Tip/PreviewTip/elements.d.ts +12 -6
  74. package/dist/Tip/__tests__/helpers.d.ts +1 -1
  75. package/dist/Tip/shared/FloatingTip.js +2 -2
  76. package/dist/Tip/shared/types.d.ts +2 -2
  77. package/dist/Tip/shared/utils.js +1 -1
  78. package/dist/utils/nullish.d.ts +10 -0
  79. package/dist/utils/nullish.js +11 -0
  80. package/dist/utils/react.js +4 -2
  81. package/package.json +10 -10
@@ -5,12 +5,12 @@ description: Design tokens for the Skillsoft Percipio platform.
5
5
  colors:
6
6
  # palette — raw swatches; set once on :root and then always reference by token name, never use hex values directly in code
7
7
  percipioTextPrimary: '#222325'
8
- percipioTextSecondary: 'rgba(34, 35, 37, 0.75)'
8
+ percipioTextSecondary: '#595A5C'
9
9
  percipioTextDisabled: '#AFB6C2'
10
- sapphire: '#1C50BB'
10
+ percipioActionPrimary: '#0073C4'
11
11
  percipioActionPrimaryHover: '#141C36'
12
12
  percipioActionSecondary: '#6A6E75'
13
- percipioActionSecondaryHover: 'rgba(106, 110, 117, 0.86)'
13
+ percipioActionSecondaryHover: '#7F8288'
14
14
  percipioActionDangerHover: '#A52020'
15
15
  percipioDanger: '#B83C3C'
16
16
  percipioFeedbackSuccess: '#1B8057'
@@ -20,10 +20,10 @@ colors:
20
20
  percipioBgWarning: '#FFF7E0'
21
21
  percipioBgError: '#FFF1F5'
22
22
  navy-800: '#10162F'
23
- navy-400: 'rgba(16, 22, 47, 0.47)'
24
- navy-300: 'rgba(16, 22, 47, 0.28)'
25
- navy-200: 'rgba(16, 22, 47, 0.12)'
26
- navy-100: 'rgba(16, 22, 47, 0.04)'
23
+ navy-400: '#8F919D'
24
+ navy-300: '#BCBEC5'
25
+ navy-200: '#E2E3E6'
26
+ navy-100: '#F5F6F7'
27
27
  white: '#ffffff'
28
28
  # semantic aliases — use these in code, not palette swatches or hex values
29
29
  text: '{colors.percipioTextPrimary}'
@@ -38,7 +38,7 @@ colors:
38
38
  background-success: '{colors.percipioBgSuccess}'
39
39
  background-warning: '{colors.percipioBgWarning}'
40
40
  background-error: '{colors.percipioBgError}'
41
- primary: '{colors.sapphire}'
41
+ primary: '{colors.percipioActionPrimary}'
42
42
  primary-hover: '{colors.percipioActionPrimaryHover}'
43
43
  primary-inverse: '{colors.white}'
44
44
  secondary: '{colors.percipioActionSecondary}'
@@ -56,17 +56,17 @@ colors:
56
56
  shadow-secondary: '{colors.navy-400}'
57
57
  typography:
58
58
  base:
59
- fontFamily: '"Skillsoft Text", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif'
59
+ fontFamily: '"Roboto", sans-serif'
60
60
  fontSize: '1rem'
61
61
  fontWeight: '400'
62
62
  lineHeight: '1.5'
63
63
  accent:
64
- fontFamily: '"Skillsoft Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif'
64
+ fontFamily: '"Roboto", sans-serif'
65
65
  fontSize: '0.875rem'
66
66
  fontWeight: '400'
67
67
  lineHeight: '1.5'
68
68
  title:
69
- fontFamily: '"Skillsoft Text", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif'
69
+ fontFamily: '"Roboto", sans-serif'
70
70
  fontSize: '2.125rem'
71
71
  fontWeight: '500'
72
72
  lineHeight: '1.2'
@@ -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
+ - Primary blue (`percipioActionPrimary`) replaces Codecademy's `hyper-500` for all interactive elements
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
 
@@ -142,9 +140,9 @@ Percipio communicates **professional clarity** — clean, trustworthy, and enter
142
140
 
143
141
  Percipio uses a single Gamut theme — light mode only.
144
142
 
145
- | Theme | Use case | Base font | Dark mode |
146
- | ------------ | --------------------------- | --------------------- | ---------- |
147
- | **Percipio** | Skillsoft Percipio platform | Skillsoft Text / Sans | light only |
143
+ | Theme | Use case | Base font | Dark mode |
144
+ | ------------ | --------------------------- | --------- | ---------- |
145
+ | **Percipio** | Skillsoft Percipio platform | Roboto | light only |
148
146
 
149
147
  The active theme is set at the app root via `<GamutProvider theme={percipioTheme}>`.
150
148
 
@@ -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` | `#595A5C` | 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` | `#F5F6F7` (navy-100) | Selected row / item |
171
+ | `background-hover` | `#E2E3E6` (navy-200) | Hover state overlay |
172
+ | `background-disabled` | `#E2E3E6` (navy-200) | 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` | `#0073C4` | 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` | `#7F8288` | 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` | `#8F919D` (navy-400) | Standard input and card borders |
196
+ | `border-secondary` | `#E2E3E6` (navy-200) | Subtle dividers, section separators |
197
+ | `border-tertiary` | `#10162F` (navy-800) | Strong structural borders |
198
+ | `border-disabled` | `#BCBEC5` (navy-300) | 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` | `#E2E3E6` (navy-200) |
213
+ | `shadow-secondary` | `#8F919D` (navy-400) |
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` | `#595A5C` | `text-secondary` |
227
+ | `percipioTextDisabled` | `#AFB6C2` | `text-disabled` |
228
+ | `percipioActionPrimary` | `#0073C4` | `primary` |
229
+ | `percipioActionPrimaryHover` | `#141C36` | `primary-hover` |
230
+ | `percipioActionSecondary` | `#6A6E75` | `secondary` |
231
+ | `percipioActionSecondaryHover` | `#7F8288` | `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
 
@@ -248,32 +246,34 @@ The full core swatch palette (navy, blue, green, yellow, red, etc.) is also avai
248
246
 
249
247
  ### Typefaces
250
248
 
251
- Percipio uses **Skillsoft Text** for body and headlines and **Skillsoft Sans** for accent UI. Roboto Mono is used for code; the `system` slot still uses Roboto.
249
+ All font families in Percipio use **Roboto**. There is no separate accent or display typeface.
252
250
 
253
- | Token | Font | Use for |
254
- | ----------- | ------------------------------ | ----------------------------------------- |
255
- | `base` | `"Skillsoft Text", sans-serif` | All default UI text, headlines, body copy |
256
- | `accent` | `"Skillsoft Sans", sans-serif` | Labels, captions, accent UI |
257
- | `monospace` | `"Roboto Mono", monospace` | Code editor contexts |
258
- | `system` | `"Roboto", sans-serif` | Performance-critical surfaces |
251
+ | Token | Font | Use for |
252
+ | ----------- | -------------------------- | ------------------------------------------- |
253
+ | `base` | `"Roboto", sans-serif` | All default UI text, headlines, body copy |
254
+ | `accent` | `"Roboto", sans-serif` | Labels, captions (same as base in Percipio) |
255
+ | `monospace` | `"Roboto Mono", monospace` | Code editor contexts |
256
+ | `system` | `"Roboto", sans-serif` | Performance-critical surfaces |
259
257
 
260
258
  ### Rules
261
259
 
262
- - **Skillsoft Text Medium (500)** for headlines, sub-headlines, CTAs, and buttons — use `fontWeight="title"`, not literal `700`.
263
- - **Skillsoft Text Regular (400)** for body text, UI labels, and menu items.
260
+ - **Roboto Medium (500)** for headlines, sub-headlines, CTAs, and buttons — not Bold (700).
261
+ - **Roboto Regular (400)** for body text, UI labels, and menu items.
264
262
  - Text is **left-aligned** by default. Center-align only for short marketing headlines. Never right-align.
265
263
  - Do not adjust letter-spacing.
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 | Overlays |
332
- | `md` | 4px | Interactive elements |
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 `#0073C4` (blue) instead of hyper-purple
373
+ - `FillButton` hover shifts to near-black `#141C36` rather than a lighter purple
374
+ - `Checkbox` / `Toggle` use the same blue `#0073C4`
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 `#0073C4` blue as the only primary 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 a separate accent typeface Roboto is used uniformly for base and accent.
389
394
  - **Don't** right-align or center-align body paragraphs.
390
395
  - **Don't** adjust letter-spacing.
391
396
 
@@ -401,27 +406,27 @@ 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 (#0073C4)`, `color: white`, `hover: primary-hover (#141C36)` |
412
+ | Body text | `color: text (#222325)`, `font: Roboto`, `size: 16px`, `weight: 400`, `lineHeight: base (1.5)` |
413
+ | Headline | `color: text (#222325)`, `font: Roboto`, `size: 34–64px`, `weight: title (500)`, `lineHeight: title (1.2)` |
414
+ | Secondary text | `color: text-secondary (#595A5C)` |
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 (#E2E3E6, 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
424
- Card → bg: background, shadow: shadow-primary (navy-200, soft)
426
+ FillButton → bg: primary (#0073C4), color: white, hover: primary-hover (#141C36)
427
+ StrokeButton → bg: transparent, border: secondary (#6A6E75)
428
+ Checkbox/Toggle → primary (#0073C4), hover: primary-hover (#141C36)
429
+ Card → bg: background, shadow: shadow-primary (#E2E3E6, navy-200, soft)
425
430
  Alert (error) → uses feedback-error + background-error
426
431
  Alert (success) → uses feedback-success + background-success
427
432
  Alert (warning) → uses feedback-warning + background-warning
@@ -1,12 +1 @@
1
- Product-specific design context lives in this directory. **Use one `DESIGN.md` per app — matched to the Gamut theme that app uses.**
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`) |
8
-
9
- ```sh
10
- gamut plugin install cursor --theme <name>
11
- # refresh: gamut plugin update cursor --theme <name> --force
12
- ```
1
+ DEPRECATED. Use the appropriate DESIGN.\*.md from https://github.com/Codecademy/gamut/pull/3329 instead.
@@ -15,7 +15,7 @@ export async function claudePluginSpec(sourceRoot) {
15
15
  } catch {
16
16
  throw new Error(
17
17
  `Missing ${mp}.\n` +
18
- `A .claude-plugin/marketplace.json is required for Claude Code installation.`,
18
+ `A .claude-plugin/marketplace.json is required for Claude Code installation.`
19
19
  );
20
20
  }
21
21
 
@@ -26,14 +26,20 @@ export async function claudePluginSpec(sourceRoot) {
26
26
  const { name: marketplaceName, plugins } = json;
27
27
 
28
28
  if (!marketplaceName || !Array.isArray(plugins) || plugins.length === 0) {
29
- throw new Error(`Invalid marketplace.json — needs "name" and "plugins[]": ${mp}`);
29
+ throw new Error(
30
+ `Invalid marketplace.json — needs "name" and "plugins[]": ${mp}`
31
+ );
30
32
  }
31
33
 
32
34
  const entry =
33
- plugins.find((p) => p.source === './' || p.source === '.' || p.source == null) ?? plugins[0];
35
+ plugins.find(
36
+ (p) => p.source === './' || p.source === '.' || p.source == null
37
+ ) ?? plugins[0];
34
38
 
35
39
  if (!entry?.name) {
36
- throw new Error(`No plugin name found in marketplace.json plugins[]: ${mp}`);
40
+ throw new Error(
41
+ `No plugin name found in marketplace.json plugins[]: ${mp}`
42
+ );
37
43
  }
38
44
 
39
45
  return `${entry.name}@${marketplaceName}`;
@@ -47,6 +53,9 @@ export async function claudePluginSpec(sourceRoot) {
47
53
  */
48
54
  export function marketplaceName(spec) {
49
55
  const name = spec.split('@')[1];
50
- if (!name) throw new Error(`Could not parse marketplace name from plugin spec: ${spec}`);
56
+ if (!name)
57
+ throw new Error(
58
+ `Could not parse marketplace name from plugin spec: ${spec}`
59
+ );
51
60
  return name;
52
61
  }
@@ -4,7 +4,10 @@ import { join } from 'node:path';
4
4
 
5
5
  /** @returns {string} */
6
6
  export function cursorPluginsRoot() {
7
- return process.env.CURSOR_PLUGINS_LOCAL ?? join(homedir(), '.cursor', 'plugins', 'local');
7
+ return (
8
+ process.env.CURSOR_PLUGINS_LOCAL ??
9
+ join(homedir(), '.cursor', 'plugins', 'local')
10
+ );
8
11
  }
9
12
 
10
13
  /**
@@ -7,8 +7,8 @@ export declare const buttonPresetThemes: {
7
7
  readonly lantern: "darkmint";
8
8
  readonly royalblue: "brand-purple";
9
9
  };
10
- declare const themes: readonly ["hyper", "navy", "red", "white", "brand-red", "brand-yellow", "brand-purple", "brand-dark-blue", "brand-blue", "mint", "darkmint", "grey", "greyblue"];
11
- export type ButtonDeprecatedThemes = keyof typeof buttonPresetThemes | (typeof themes)[number];
10
+ declare const _themes: readonly ["hyper", "navy", "red", "white", "brand-red", "brand-yellow", "brand-purple", "brand-dark-blue", "brand-blue", "mint", "darkmint", "grey", "greyblue"];
11
+ export type ButtonDeprecatedThemes = keyof typeof buttonPresetThemes | (typeof _themes)[number];
12
12
  export type ButtonDeprecatedProps = ButtonDeprecatedBaseProps & {
13
13
  /**
14
14
  * Whether button should behave like a block element or inline.
@@ -16,7 +16,7 @@ export const buttonPresetThemes = {
16
16
  lantern: 'darkmint',
17
17
  royalblue: 'brand-purple'
18
18
  };
19
- const themes = ['hyper', 'navy', 'red', 'white', 'brand-red', 'brand-yellow', 'brand-purple', 'brand-dark-blue', 'brand-blue', 'mint', 'darkmint', 'grey', 'greyblue'];
19
+ const _themes = ['hyper', 'navy', 'red', 'white', 'brand-red', 'brand-yellow', 'brand-purple', 'brand-dark-blue', 'brand-blue', 'mint', 'darkmint', 'grey', 'greyblue'];
20
20
  const propKeys = ['theme', 'size', 'outline', 'underline', 'link', 'caps', 'go', 'children', 'block', 'className', 'round', 'square', 'flat', 'fitText', 'onClick'];
21
21
  const isPreset = theme => {
22
22
  return hasIn(buttonPresetThemes, theme);