@codecademy/gamut 68.5.2-alpha.f0a056.0 → 68.6.1-alpha.e6c390.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 (35) hide show
  1. package/agent-tools/.claude-plugin/marketplace.json +16 -0
  2. package/agent-tools/.claude-plugin/plugin.json +7 -0
  3. package/agent-tools/.cursor-plugin/plugin.json +7 -0
  4. package/agent-tools/DESIGN.Codecademy.md +648 -0
  5. package/agent-tools/DESIGN.LXStudio.md +460 -0
  6. package/agent-tools/DESIGN.Percipio.md +463 -0
  7. package/agent-tools/DESIGN.md +1 -0
  8. package/agent-tools/agents/.gitkeep +0 -0
  9. package/agent-tools/commands/gamut-review.md +170 -0
  10. package/agent-tools/guidelines/components/buttons.md +44 -0
  11. package/agent-tools/guidelines/components/overview.md +44 -0
  12. package/agent-tools/guidelines/foundations/color.md +86 -0
  13. package/agent-tools/guidelines/foundations/modes.md +47 -0
  14. package/agent-tools/guidelines/foundations/spacing.md +66 -0
  15. package/agent-tools/guidelines/foundations/typography.md +50 -0
  16. package/agent-tools/guidelines/overview.md +38 -0
  17. package/agent-tools/guidelines/setup.md +42 -0
  18. package/agent-tools/rules/accessibility.mdc +69 -0
  19. package/agent-tools/skills/gamut-accessibility/SKILL.md +239 -0
  20. package/agent-tools/skills/gamut-color-mode/SKILL.md +99 -0
  21. package/agent-tools/skills/gamut-system-props/SKILL.md +181 -0
  22. package/agent-tools/skills/gamut-testing/SKILL.md +181 -0
  23. package/agent-tools/skills/gamut-theming/SKILL.md +115 -0
  24. package/agent-tools/skills/gamut-typography/SKILL.md +123 -0
  25. package/bin/commands/plugin/install.mjs +173 -0
  26. package/bin/commands/plugin/list.mjs +105 -0
  27. package/bin/commands/plugin/remove.mjs +116 -0
  28. package/bin/commands/plugin/update.mjs +49 -0
  29. package/bin/gamut.mjs +92 -0
  30. package/bin/lib/claude.mjs +52 -0
  31. package/bin/lib/cursor.mjs +40 -0
  32. package/bin/lib/figma.mjs +49 -0
  33. package/bin/lib/resolve-plugin-dir.mjs +38 -0
  34. package/bin/lib/run-command.mjs +22 -0
  35. package/package.json +11 -8
@@ -0,0 +1,463 @@
1
+ ---
2
+ version: alpha
3
+ name: Percipio Design System
4
+ description: Design tokens for the Skillsoft Percipio platform.
5
+ colors:
6
+ # palette — reference hex for docs/tools; in product UI use semantic colors via Gamut theme (Emotion) / system props or Figma tokens—never paste these literals into code
7
+ percipioTextPrimary: '#222325'
8
+ percipioTextAccent: '#222325'
9
+ percipioTextSecondary: 'rgba(34, 35, 37, 0.75)'
10
+ percipioTextDisabled: '#AFB6C2'
11
+ percipioActionPrimary: '#0073C4'
12
+ percipioActionPrimaryHover: '#141C36'
13
+ percipioActionSecondary: '#6A6E75'
14
+ percipioActionSecondaryHover: 'rgba(106, 110, 117, 0.86)'
15
+ percipioActionDangerHover: '#A52020'
16
+ percipioDanger: '#B83C3C'
17
+ percipioFeedbackSuccess: '#1B8057'
18
+ percipioFeedbackWarning: '#EF5B0D'
19
+ percipioBgPrimary: '#FAFBFC'
20
+ percipioBgSuccess: '#EEF7F3'
21
+ percipioBgWarning: '#FFF7E0'
22
+ percipioBgError: '#FFF1F5'
23
+ navy-800: '#10162F'
24
+ navy-400: '#8F919D'
25
+ navy-300: '#BCBEC5'
26
+ navy-200: '#E2E3E6'
27
+ navy-100: '#F5F6F7'
28
+ white: '#ffffff'
29
+ # semantic aliases — use these in code, not palette swatches or hex values
30
+ text: '{colors.percipioTextPrimary}'
31
+ text-accent: '{colors.percipioTextAccent}'
32
+ text-secondary: '{colors.percipioTextSecondary}'
33
+ text-disabled: '{colors.percipioTextDisabled}'
34
+ background: '{colors.white}'
35
+ background-primary: '{colors.percipioBgPrimary}'
36
+ background-selected: '{colors.navy-100}'
37
+ background-hover: '{colors.navy-200}'
38
+ background-disabled: '{colors.navy-200}'
39
+ background-success: '{colors.percipioBgSuccess}'
40
+ background-warning: '{colors.percipioBgWarning}'
41
+ background-error: '{colors.percipioBgError}'
42
+ primary: '{colors.percipioActionPrimary}'
43
+ primary-hover: '{colors.percipioActionPrimaryHover}'
44
+ primary-inverse: '{colors.white}'
45
+ secondary: '{colors.percipioActionSecondary}'
46
+ secondary-hover: '{colors.percipioActionSecondaryHover}'
47
+ interface: '{colors.percipioActionPrimary}'
48
+ interface-hover: '{colors.percipioActionPrimaryHover}'
49
+ danger: '{colors.percipioDanger}'
50
+ danger-hover: '{colors.percipioActionDangerHover}'
51
+ feedback-error: '{colors.percipioDanger}'
52
+ feedback-success: '{colors.percipioFeedbackSuccess}'
53
+ feedback-warning: '{colors.percipioFeedbackWarning}'
54
+ border-primary: '{colors.navy-400}'
55
+ border-secondary: '{colors.navy-200}'
56
+ border-tertiary: '{colors.navy-800}'
57
+ border-disabled: '{colors.navy-300}'
58
+ shadow-primary: '{colors.navy-200}'
59
+ shadow-secondary: '{colors.navy-400}'
60
+ typography:
61
+ base:
62
+ fontFamily: '"Roboto", sans-serif'
63
+ fontSize: '1rem'
64
+ fontWeight: '400'
65
+ lineHeight: '1.5'
66
+ accent:
67
+ fontFamily: '"Roboto", sans-serif'
68
+ fontSize: '0.875rem'
69
+ fontWeight: '400'
70
+ lineHeight: '1.5'
71
+ title:
72
+ fontFamily: '"Roboto", sans-serif'
73
+ fontSize: '2.125rem'
74
+ fontWeight: '500'
75
+ lineHeight: '1.2'
76
+ monospace:
77
+ fontFamily: '"Roboto Mono", monospace'
78
+ borderRadii:
79
+ none: '0px'
80
+ sm: '2px'
81
+ md: '4px'
82
+ lg: '8px'
83
+ xl: '16px'
84
+ full: '999px'
85
+ spacing:
86
+ '0': '0'
87
+ '4': '0.25rem'
88
+ '8': '0.5rem'
89
+ '12': '0.75rem'
90
+ '16': '1rem'
91
+ '24': '1.5rem'
92
+ '32': '2rem'
93
+ '40': '2.5rem'
94
+ '48': '3rem'
95
+ '64': '4rem'
96
+ '96': '6rem'
97
+
98
+ components:
99
+ FillButton:
100
+ backgroundColor: '{colors.primary}'
101
+ textColor: '{colors.primary-inverse}'
102
+ rounded: '{rounded.md}'
103
+ FillButton-hover:
104
+ backgroundColor: '{colors.primary-hover}'
105
+ textColor: '{colors.primary-inverse}'
106
+ FillButton-danger:
107
+ backgroundColor: '{colors.danger}'
108
+ textColor: '{colors.white}'
109
+ rounded: '{rounded.md}'
110
+ FillButton-danger-hover:
111
+ backgroundColor: '{colors.danger-hover}'
112
+ textColor: '{colors.white}'
113
+ StrokeButton:
114
+ backgroundColor: 'transparent'
115
+ textColor: '{colors.secondary}'
116
+ rounded: '{rounded.md}'
117
+ Input:
118
+ backgroundColor: '{colors.background}'
119
+ textColor: '{colors.text}'
120
+ rounded: '{rounded.md}'
121
+ borderColor: '{colors.border-primary}'
122
+ Checkbox:
123
+ backgroundColor: '{colors.interface}'
124
+ rounded: '{rounded.sm}'
125
+ Checkbox-hover:
126
+ backgroundColor: '{colors.interface-hover}'
127
+ Alert-error:
128
+ backgroundColor: '{colors.background-error}'
129
+ textColor: '{colors.feedback-error}'
130
+ Alert-success:
131
+ backgroundColor: '{colors.background-success}'
132
+ textColor: '{colors.text}'
133
+ Alert-warning:
134
+ backgroundColor: '{colors.background-warning}'
135
+ textColor: '{colors.text}'
136
+ ---
137
+
138
+ # Percipio
139
+
140
+ This file defines the visual design tokens for the Skillsoft Percipio platform, implemented using the Gamut design system (`@codecademy/gamut`, `@codecademy/gamut-styles`). Percipio uses a dedicated Gamut theme that applies its own colors and typography — all Gamut components work without modification.
141
+
142
+ In handoffs and implementation, **default to semantic token names** (`primary`, `text`, `interface`, …) and Gamut system props — do not paste hex literals where a theme token exists. Hex in this file documents resolved light-mode values for designers and reviewers.
143
+
144
+ **Storybook**: https://gamut.codecademy.com
145
+
146
+ ---
147
+
148
+ ## Visual Theme & Atmosphere
149
+
150
+ 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.
151
+
152
+ **Density**: Medium. Consistent with Codecademy layouts but with softer shadows and a lighter overall feel due to the muted neutral palette.
153
+
154
+ **Design philosophy**:
155
+
156
+ - Extends **Core** — light and dark color modes are available; `percipioTheme` defines explicit **light** overrides and inherits **Core dark** where not overridden
157
+ - Primary blue (`percipioActionPrimary`) replaces Codecademy's `hyper-500` for all interactive elements
158
+ - Text is near-black dark gray rather than navy
159
+ - Shadows are soft and minimal (navy at low opacity) rather than hard borders
160
+ - Title font weight is 500 (medium) rather than 700 (bold) — Percipio headlines are less heavy
161
+
162
+ ---
163
+
164
+ ## Themes
165
+
166
+ Percipio uses **`percipioTheme`**, which spreads **`coreTheme`** and adds explicit **light** semantic overrides (see `packages/gamut-styles/src/themes/percipio.ts`). Dark mode resolves through the same Core color-mode system.
167
+
168
+ | Theme | Use case | Base font | Dark mode |
169
+ | ------------ | --------------------------- | --------- | ------------------------------------------------------- |
170
+ | **Percipio** | Skillsoft Percipio platform | Roboto | yes (inherits Core dark; light overrides in theme file) |
171
+
172
+ The active theme is set at the app root via `<GamutProvider theme={percipioTheme}>`.
173
+
174
+ ---
175
+
176
+ ## Semantic Color Aliases
177
+
178
+ Use **semantic token names** in specs and code. **`percipioTheme`** (`packages/gamut-styles/src/themes/percipio.ts`) extends **`coreTheme`**, so **light and dark** color modes behave like Codecademy: the theme file lists explicit **light** overrides, and **dark** uses **Core dark** semantics anywhere Percipio does not override them. Hex or rgba in the **Value** column documents **light mode** for designers (`percipioColors` in `packages/gamut-styles/src/variables/colors.ts`). For raw vs semantic usage, see `guidelines/foundations/color.md` in this package.
179
+
180
+ The YAML `components:` block at the top of this file is an **illustrative recipe set**—use semantic system props and Gamut primitives in application code.
181
+
182
+ ### Text
183
+
184
+ | Token | Value | Use for |
185
+ | ---------------- | -------------------------------------------------- | ---------------------------------------------- |
186
+ | `text` | `#222325` (`percipioTextPrimary`) | Default body and UI text |
187
+ | `text-accent` | `#222325` (`percipioTextAccent`) | Emphasis text (same hex as `text` in Percipio) |
188
+ | `text-secondary` | `rgba(34, 35, 37, 0.75)` (`percipioTextSecondary`) | Supporting / secondary copy |
189
+ | `text-disabled` | `#AFB6C2` (`percipioTextDisabled`) | Disabled state labels |
190
+
191
+ ### Background
192
+
193
+ | Token | Value | Use for |
194
+ | --------------------- | -------------------- | --------------------------------- |
195
+ | `background` | `#ffffff` | Default page/component background |
196
+ | `background-primary` | `#FAFBFC` | Slightly elevated surfaces |
197
+ | `background-selected` | `#F5F6F7` (navy-100) | Selected row / item |
198
+ | `background-hover` | `#E2E3E6` (navy-200) | Hover state overlay |
199
+ | `background-disabled` | `#E2E3E6` (navy-200) | Disabled surface |
200
+ | `background-success` | `#EEF7F3` | Success state container |
201
+ | `background-warning` | `#FFF7E0` | Warning state container |
202
+ | `background-error` | `#FFF1F5` | Error state container |
203
+
204
+ ### Interactive
205
+
206
+ | Token | Value | Use for |
207
+ | ----------------- | ------------------------------------------------------------ | --------------------------------------------- |
208
+ | `primary` | `#0073C4` | Primary CTA, links, focus rings |
209
+ | `primary-hover` | `#141C36` | Hover state of primary interactive |
210
+ | `primary-inverse` | `#ffffff` | Primary on a colored background |
211
+ | `secondary` | `#6A6E75` | Secondary CTA, ghost buttons |
212
+ | `secondary-hover` | `rgba(106, 110, 117, 0.86)` (`percipioActionSecondaryHover`) | Hover state of secondary interactive |
213
+ | `interface` | `#0073C4` | UI affordances (checkboxes, toggles, sliders) |
214
+ | `interface-hover` | `#141C36` | Hover on interface elements |
215
+ | `danger` | `#B83C3C` | Destructive actions, error states |
216
+ | `danger-hover` | `#A52020` | Hover on danger interactive |
217
+
218
+ ### Border
219
+
220
+ 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.
221
+
222
+ | Token | Value | Use for |
223
+ | ------------------ | -------------------- | ----------------------------------- |
224
+ | `border-primary` | `#8F919D` (navy-400) | Standard input and card borders |
225
+ | `border-secondary` | `#E2E3E6` (navy-200) | Subtle dividers, section separators |
226
+ | `border-tertiary` | `#10162F` (navy-800) | Strong structural borders |
227
+ | `border-disabled` | `#BCBEC5` (navy-300) | Disabled input borders |
228
+
229
+ ### Feedback
230
+
231
+ | Token | Value | Use for |
232
+ | ------------------ | --------- | -------------------------------- |
233
+ | `feedback-error` | `#B83C3C` | Error messages, validation |
234
+ | `feedback-success` | `#1B8057` | Success messages, confirmations |
235
+ | `feedback-warning` | `#EF5B0D` | Warning messages, caution states |
236
+
237
+ ### Shadow
238
+
239
+ | Token | Value |
240
+ | ------------------ | -------------------- |
241
+ | `shadow-primary` | `#E2E3E6` (navy-200) |
242
+ | `shadow-secondary` | `#8F919D` (navy-400) |
243
+
244
+ Percipio shadows are softer than Codecademy's — use `shadow-primary` for standard elevated surfaces.
245
+
246
+ ---
247
+
248
+ ## Percipio Color Palette
249
+
250
+ 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.
251
+
252
+ | Named color | Value | Mapped to |
253
+ | ------------------------------ | --------------------------- | ---------------------------------- |
254
+ | `percipioTextPrimary` | `#222325` | `text` |
255
+ | `percipioTextAccent` | `#222325` | `text-accent` |
256
+ | `percipioTextSecondary` | `rgba(34, 35, 37, 0.75)` | `text-secondary` |
257
+ | `percipioTextDisabled` | `#AFB6C2` | `text-disabled` |
258
+ | `percipioActionPrimary` | `#0073C4` | `primary`, `interface` |
259
+ | `percipioActionPrimaryHover` | `#141C36` | `primary-hover`, `interface-hover` |
260
+ | `percipioActionSecondary` | `#6A6E75` | `secondary` |
261
+ | `percipioActionSecondaryHover` | `rgba(106, 110, 117, 0.86)` | `secondary-hover` |
262
+ | `percipioActionDangerHover` | `#A52020` | `danger-hover` |
263
+ | `percipioDanger` | `#B83C3C` | `danger`, `feedback-error` |
264
+ | `percipioFeedbackSuccess` | `#1B8057` | `feedback-success` |
265
+ | `percipioFeedbackWarning` | `#EF5B0D` | `feedback-warning` |
266
+ | `percipioBgPrimary` | `#FAFBFC` | `background-primary` |
267
+ | `percipioBgSuccess` | `#EEF7F3` | `background-success` |
268
+ | `percipioBgWarning` | `#FFF7E0` | `background-warning` |
269
+ | `percipioBgError` | `#FFF1F5` | `background-error` |
270
+
271
+ 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.).
272
+
273
+ ---
274
+
275
+ ## Typography
276
+
277
+ ### Typefaces
278
+
279
+ All font families in Percipio use **Roboto**. There is no separate accent or display typeface.
280
+
281
+ | Token | Font | Use for |
282
+ | ----------- | -------------------------- | ------------------------------------------- |
283
+ | `base` | `"Roboto", sans-serif` | All default UI text, headlines, body copy |
284
+ | `accent` | `"Roboto", sans-serif` | Labels, captions (same as base in Percipio) |
285
+ | `monospace` | `"Roboto Mono", monospace` | Code editor contexts |
286
+ | `system` | `"Roboto", sans-serif` | Performance-critical surfaces |
287
+
288
+ ### Rules
289
+
290
+ - **Roboto Medium (500)** for headlines, sub-headlines, CTAs, and buttons — not Bold (700).
291
+ - **Roboto Regular (400)** for body text, UI labels, and menu items.
292
+ - Text is **left-aligned** by default. Center-align only for short marketing headlines. Never right-align.
293
+ - Do not adjust letter-spacing.
294
+
295
+ ### Font weight scale
296
+
297
+ Percipio overrides the title weight from Core's 700 to 500 (medium). This gives Percipio a lighter, less heavy headline style.
298
+
299
+ | Token | Value | Use |
300
+ | ------- | ------- | ---------------------------------------------------------- |
301
+ | `base` | 400 | Body text, UI labels |
302
+ | `title` | **500** | Headlines, CTAs, buttons _(differs from Codecademy's 700)_ |
303
+
304
+ ### Font size scale
305
+
306
+ Shared with Core — all sizes are identical.
307
+
308
+ | Token key | Size | Common use |
309
+ | --------- | ---- | ---------------------------- |
310
+ | `64` | 64px | Hero / display |
311
+ | `44` | 44px | Page titles |
312
+ | `34` | 34px | Section titles |
313
+ | `26` | 26px | Sub-section titles |
314
+ | `22` | 22px | Card titles, large UI labels |
315
+ | `20` | 20px | Secondary titles |
316
+ | `18` | 18px | Large body, intro text |
317
+ | `16` | 16px | Default body text |
318
+ | `14` | 14px | Small body, captions, labels |
319
+
320
+ ### Line height scale
321
+
322
+ Shared with Core.
323
+
324
+ | Token | Value | Use |
325
+ | ------------- | ----- | ------------------------------- |
326
+ | `base` | 1.5 | Body text |
327
+ | `spacedTitle` | 1.3 | Sub-headlines and medium titles |
328
+ | `title` | 1.2 | Large headlines |
329
+
330
+ ### Line length
331
+
332
+ Target 45–85 characters per line; 66 characters is ideal. Max 50 for multi-column layouts.
333
+
334
+ ---
335
+
336
+ ## Spacing Scale
337
+
338
+ Identical to Core. All spacing is multiples of 4px on an 8px grid.
339
+
340
+ | Token | Value |
341
+ | ----- | ----- |
342
+ | `0` | 0 |
343
+ | `4` | 4px |
344
+ | `8` | 8px |
345
+ | `12` | 12px |
346
+ | `16` | 16px |
347
+ | `24` | 24px |
348
+ | `32` | 32px |
349
+ | `40` | 40px |
350
+ | `48` | 48px |
351
+ | `64` | 64px |
352
+ | `96` | 96px |
353
+
354
+ ---
355
+
356
+ ## Border Radius Scale
357
+
358
+ Identical to Core.
359
+
360
+ | Token | Value | Use |
361
+ | ------ | ----- | ------------------------------------------ |
362
+ | `none` | 0px | Square / non-interactive elements |
363
+ | `sm` | 2px | Subtle rounding, tags |
364
+ | `md` | 4px | Default buttons, inputs, interactive cards |
365
+ | `lg` | 8px | Cards, panels |
366
+ | `xl` | 16px | Large cards, modals |
367
+ | `full` | 999px | Pills, avatars, circular elements |
368
+
369
+ ---
370
+
371
+ ## Responsive Behavior
372
+
373
+ Identical to Core. Mobile-first, apply styles from the named breakpoint up.
374
+
375
+ | Token | Min-width | Max content |
376
+ | -------- | --------- | ----------- |
377
+ | _(base)_ | 0 | 288px |
378
+ | `xs` | 480px | 448px |
379
+ | `sm` | 768px | 704px |
380
+ | `md` | 1024px | 896px |
381
+ | `lg` | 1200px | 1072px |
382
+ | `xl` | 1440px | 1248px |
383
+
384
+ 12-column grid at all breakpoints.
385
+
386
+ | Usage | Recommended values |
387
+ | --------------------- | ------------------------------------------------ |
388
+ | Horizontal margins | 64px (lg+), 48px (md), 32px (sm/xs), 16px (base) |
389
+ | Column gaps (gutters) | 32px (lg+), 24px (md), 16px (sm/xs), 8px (base) |
390
+ | Row gaps | 32px (lg+), 24px (md), 16px (sm/xs), 8px (base) |
391
+
392
+ Minimum interactive touch target: **44×44px** on mobile breakpoints.
393
+
394
+ ---
395
+
396
+ ## Component Library
397
+
398
+ Same component library as Codecademy — all atoms, molecules, and organisms apply. Token values resolve differently per theme automatically.
399
+
400
+ Key Percipio-specific visual differences:
401
+
402
+ - `FillButton` uses **`primary`** (Percipio blue — `#0073C4` resolved in light) instead of Codecademy hyper-purple
403
+ - `FillButton` hover uses **`primary-hover`** (near-black `#141C36` resolved in light) rather than a lighter purple
404
+ - `Checkbox` / `Toggle` use **`interface`** (same Percipio blue ramp as primary affordances)
405
+ - `Card` has softer shadows (navy-200 vs navy-800 in Codecademy light mode)
406
+ - Card shadow patterns (`patternLeft`, `patternRight`) are available but rarely used in Percipio UIs
407
+
408
+ ---
409
+
410
+ ## Do's and Don'ts
411
+
412
+ ### Colors
413
+
414
+ - **Do** use semantic color aliases (`primary`, `text`, `background`, etc.) — never hardcode hex values in product UI where a token exists.
415
+ - **Do** use **`primary`** / **`interface`** (and their hover tokens) for all Percipio blues — they resolve to the Percipio palette in the theme; do not duplicate those blues as literals.
416
+ - **Don't** use Codecademy's hyper-purple or yellow in Percipio contexts.
417
+ - **Don't** treat the semantic tables as exhaustive for dark mode — they show resolved **light** values; use tokens and `colorMode` in code.
418
+
419
+ ### Typography
420
+
421
+ - **Do** use title weight (500) for headlines, CTAs, and buttons — not 700.
422
+ - **Do** keep body text at 150–175% line height for readability.
423
+ - **Don't** use a separate accent typeface — Roboto is used uniformly for base and accent.
424
+ - **Don't** right-align or center-align body paragraphs.
425
+ - **Don't** adjust letter-spacing.
426
+
427
+ ### Layout & Spacing
428
+
429
+ - **Do** use multiples of 8px for block-element spacing (4px only for inline / typographic relationships).
430
+ - **Do** begin design work at 1440px (XL), then adapt down.
431
+ - **Do** align elements to the 12-column grid.
432
+
433
+ ---
434
+
435
+ ## Agent Prompt Guide
436
+
437
+ Quick color/token reference for generating or specifying Percipio UI. **Token names are the contract**; parenthetical hex is reference only. Implement with `@codecademy/gamut-styles` theme keys and system props, not raw color strings.
438
+
439
+ | Scenario | Tokens |
440
+ | ---------------- | ------------------------------------------------------------------------------------------------------------ |
441
+ | Primary button | `bg: primary (#0073C4)`, `color: white`, `hover: primary-hover (#141C36)` |
442
+ | Body text | `color: text (#222325)`, `font: Roboto`, `size: 16px`, `weight: 400`, `lineHeight: base (1.5)` |
443
+ | Headline | `color: text (#222325)`, `font: Roboto`, `size: 34–64px`, `weight: title (500)`, `lineHeight: title (1.2)` |
444
+ | Secondary text | `color: text-secondary` (`rgba(34, 35, 37, 0.75)`) |
445
+ | Disabled text | `color: text-disabled (#AFB6C2)` |
446
+ | Elevated surface | `bg: background-primary (#FAFBFC)` |
447
+ | Card default | `bg: background (#ffffff)`, `borderRadius: none` — add `isInteractive` for hover shadow + `borderRadius: md` |
448
+ | Error state | `color: feedback-error (#B83C3C)`, `bg: background-error (#FFF1F5)`, `border: danger` |
449
+ | Success state | `color: feedback-success (#1B8057)`, `bg: background-success (#EEF7F3)` |
450
+ | Warning state | `color: feedback-warning (#EF5B0D)`, `bg: background-warning (#FFF7E0)` |
451
+ | Disabled state | `color: text-disabled (#AFB6C2)`, `bg: background-disabled (#E2E3E6, navy-200)`, `border: border-disabled` |
452
+
453
+ ### Component token cheatsheet
454
+
455
+ ```
456
+ FillButton → bg: primary (#0073C4), color: white, hover: primary-hover (#141C36)
457
+ StrokeButton → bg: transparent, border: secondary (#6A6E75)
458
+ Checkbox/Toggle → interface (#0073C4), hover: interface-hover (#141C36)
459
+ Card → bg: background, shadow: shadow-primary (#E2E3E6, navy-200, soft)
460
+ Alert (error) → uses feedback-error + background-error
461
+ Alert (success) → uses feedback-success + background-success
462
+ Alert (warning) → uses feedback-warning + background-warning
463
+ ```
@@ -0,0 +1 @@
1
+ Use the appropriate DESIGN.\*.md based on your Gamut theme.
File without changes
@@ -0,0 +1,170 @@
1
+ ---
2
+ description: Use this command when auditing existing code for Gamut usage — dependencies, GamutProvider, deep imports, hardcoded hex colors, and test patterns — and you need a consolidated report with pointers to the matching Gamut skills.
3
+ argument-hint: [path]
4
+ allowed-tools: Read Glob Grep
5
+ ---
6
+
7
+ This is an audit of **existing code** at **`$ARGUMENTS`** (default: current working directory). Your job is to find violations and misuse, not to generate new code.
8
+
9
+ Use `DESIGN.md` at the project root as the authoritative reference for the product's design intent, token names, and component patterns. This file is distributed as `DESIGN.Codecademy.md` or `DESIGN.Percipio.md` from the `@codecademy/gamut` agent-tools package and renamed to `DESIGN.md` by the consuming project. When a finding maps to a skill, note it in the report so the developer knows where to get remediation guidance.
10
+
11
+ Run all five checks below, then print a single consolidated report using the format at the end of this file.
12
+
13
+ ---
14
+
15
+ ## Check 1 — Dependencies
16
+
17
+ Read `package.json` (and `package.json` in `$ARGUMENTS` if a path was given). Inspect `dependencies`, `devDependencies`, and `peerDependencies` combined.
18
+
19
+ | Package | Expectation |
20
+ |---|---|
21
+ | `@codecademy/gamut` | **Required** — core component library |
22
+ | `@codecademy/gamut-styles` | Recommended — design tokens and theme primitives |
23
+ | `@codecademy/variance` | Recommended — style-prop system used by Gamut internals |
24
+
25
+ ---
26
+
27
+ ## Check 2 — Setup
28
+
29
+ Search source files (`.ts`, `.tsx`, `.js`, `.jsx`) for these symbols. Skip `node_modules`, `dist`, `.next`, `build`, `.turbo`.
30
+
31
+ | Symbol | Expectation |
32
+ |---|---|
33
+ | `GamutProvider` | **Required** — must appear at least once (app root wrapper) |
34
+ | `ColorMode` | Recommended — enables semantic light/dark theming |
35
+ | `Background` | Recommended — semantic surface color via `@codecademy/gamut-styles` |
36
+
37
+ For each found symbol report the first file path where it appears.
38
+
39
+ ---
40
+
41
+ ## Check 3 — Import patterns
42
+
43
+ Grep source files for any of these patterns. Each match is an error.
44
+
45
+ | Pattern | Reason |
46
+ |---|---|
47
+ | `@codecademy/gamut/dist/` | Deep dist import — bypasses public API and breaks on internal refactors |
48
+ | `@codecademy/gamut/src/` | Deep src import — not part of the published package |
49
+ | `@codecademy/gamut-styles/src/` | Deep src import — use the package root |
50
+ | `@codecademy/variance/src/` | Deep src import — use the package root |
51
+
52
+ Report each violation as `file:line`.
53
+
54
+ ---
55
+
56
+ ## Check 4 — Hardcoded colors
57
+
58
+ Grep source files (`.ts`, `.tsx`, `.js`, `.jsx`, `.css`, `.scss`, `.less`) for inline hex color literals (`#RGB` or `#RRGGBB`). For each match, suggest the Gamut token name using this table (case-insensitive comparison):
59
+
60
+ | Hex | Token |
61
+ |---|---|
62
+ | `#000000` | `black` |
63
+ | `#ffffff` | `white` |
64
+ | `#10162f` | `navy` / `navy-800` |
65
+ | `#0a0d1c` | `navy-900` |
66
+ | `#fff0e5` | `beige-100` |
67
+ | `#f5fcff` | `blue-0` |
68
+ | `#d3f2ff` | `blue-100` |
69
+ | `#66c4ff` | `blue-300` |
70
+ | `#3388ff` | `blue-400` |
71
+ | `#1557ff` | `blue-500` |
72
+ | `#1d2340` | `blue-800` |
73
+ | `#f5ffe3` | `green-0` |
74
+ | `#eafdc6` | `green-100` |
75
+ | `#aee938` | `green-400` / `lightGreen` |
76
+ | `#008a27` | `green-700` |
77
+ | `#151c07` | `green-900` |
78
+ | `#fffae5` | `yellow-0` |
79
+ | `#cca900` | `yellow-400` |
80
+ | `#ffd300` | `yellow-500` / `yellow` |
81
+ | `#211b00` | `yellow-900` |
82
+ | `#fff5ff` | `pink-0` |
83
+ | `#f966ff` | `pink-400` / `pink` |
84
+ | `#fbf1f0` | `red-0` |
85
+ | `#e85d7f` | `red-300` |
86
+ | `#dc5879` | `red-400` / `paleRed` |
87
+ | `#e91c11` | `red-500` / `red` |
88
+ | `#be1809` | `red-600` |
89
+ | `#280503` | `red-900` |
90
+ | `#ffe8cc` | `orange-100` |
91
+ | `#ff8c00` | `orange-500` / `orange` |
92
+ | `#5533ff` | `hyper-400` |
93
+ | `#3a10e5` | `hyper-500` / `hyper` |
94
+ | `#f5f5f5` | `gray-100` |
95
+ | `#eeeeee` | `gray-200` |
96
+ | `#e0e0e0` | `gray-300` |
97
+ | `#9e9e9e` | `gray-600` |
98
+ | `#616161` | `gray-800` |
99
+ | `#424242` | `gray-900` |
100
+ | `#fffbf8` | `beige-0` |
101
+ | `#8a7300` | `gold-800` / `gold` |
102
+ | `#d14900` | `orange-800` |
103
+ | `#ca00d1` | `pink-800` |
104
+ | `#006d82` | `teal-500` / `teal` |
105
+ | `#b3ccff` | `purple-300` / `purple` |
106
+
107
+ Ignore hex values inside design token definition files themselves (e.g. `variables/colors.ts`, `_colors.scss`) — those are the source of truth, not violations.
108
+
109
+ For each match outside token files report: `file:line 'HEX' → token` (or `→ no Gamut token` if unknown).
110
+
111
+ ---
112
+
113
+ ## Check 5 — Test setup
114
+
115
+ Grep test files (`**/__tests__/**/*.{ts,tsx}`, `**/*.test.{ts,tsx}`, `**/*.spec.{ts,tsx}`) for these patterns. Skip `node_modules`, `dist`.
116
+
117
+ | Pattern | Verdict | Reason |
118
+ |---|---|---|
119
+ | `jest.mock\(.*@codecademy/gamut` | **Error** | Manual mocking bypasses theme context and produces false-positive tests; use `setupRtl` or `MockGamutProvider` instead |
120
+ | `jest.mock\(.*@codecademy/gamut-styles` | **Error** | Same issue as above — mocking gamut-styles breaks token resolution |
121
+ | `from '@codecademy/gamut-tests'` | Good — report count of files using it | Correct import for `setupRtl` and `MockGamutProvider` |
122
+ | `from 'component-test-setup'` (without gamut-tests) | **Warning** | Should import `setupRtl` from `@codecademy/gamut-tests`, not directly from `component-test-setup` — the gamut-tests wrapper adds `MockGamutProvider` automatically |
123
+ | `new GamutProvider` or `<GamutProvider` in test files | **Warning** | Tests should use `MockGamutProvider` (sets `useCache={false}`, `useGlobals={false}`), not `GamutProvider` directly |
124
+
125
+ Skill reference for remediation: `gamut-testing`
126
+
127
+ ---
128
+
129
+ ## Output format
130
+
131
+ ```
132
+ Gamut Review — <absolute path>
133
+ ══════════════════════════════════════════════════
134
+
135
+ Dependencies
136
+ ✓ @codecademy/gamut <version>
137
+ ⚠ @codecademy/gamut-styles not found — recommended
138
+ ✗ @codecademy/variance not found — recommended
139
+
140
+ Setup
141
+ ✓ GamutProvider found (src/App.tsx)
142
+ ⚠ ColorMode not found — use ColorMode for light/dark theming [→ gamut-color-mode]
143
+ ⚠ Background not found — use <Background> for semantic surfaces [→ gamut-color-mode]
144
+
145
+ Import patterns
146
+ ✓ Deep dist imports none found
147
+ ✗ Deep src imports 2 occurrences
148
+ src/Thing.tsx:7
149
+ src/Other.tsx:12
150
+
151
+ Hardcoded colors [→ gamut-color-mode]
152
+ ⚠ src/Hero.tsx:14 '#1557FF' → blue-500
153
+ ⚠ src/Nav.tsx:8 '#BADA55' → no Gamut token
154
+
155
+ Test setup [→ gamut-testing]
156
+ ✓ @codecademy/gamut-tests used in 12 test files
157
+ ✗ jest.mock(@codecademy/gamut) 2 occurrences — remove and use setupRtl instead
158
+ src/components/Foo/__tests__/Foo.test.tsx:3
159
+ src/components/Bar/__tests__/Bar.test.tsx:5
160
+ ⚠ direct component-test-setup import 1 occurrence — import from @codecademy/gamut-tests
161
+ src/components/Baz/__tests__/Baz.test.tsx:2
162
+
163
+ ══════════════════════════════════════════════════
164
+ <N> error(s), <N> warning(s) found. (or "All checks passed." if none)
165
+ ```
166
+
167
+ Icons: `✓` = pass, `⚠` = warning (recommended, not required), `✗` = error (required).
168
+ `[→ skill-name]` annotations indicate which Gamut skill has remediation guidance for that category.
169
+
170
+ After printing the report, offer one sentence of prioritized next-step advice based on what was found.
@@ -0,0 +1,44 @@
1
+ # Buttons
2
+
3
+ ## Variants
4
+
5
+ | Component | Use for | Background | Text |
6
+ |---|---|---|---|
7
+ | `FillButton` | Primary CTA, high-emphasis actions | `primary` | `white` |
8
+ | `StrokeButton` | Secondary actions, outlined style | transparent | `secondary` |
9
+ | `CTAButton` | High-visibility marketing promotions | `primary` | `white` |
10
+ | `CTAButton` (inverse) | CTA on a colored surface | `primary-inverse` | `secondary` |
11
+ | `TextButton` | Low-emphasis, inline text actions | transparent | `primary` |
12
+ | `IconButton` | Compact icon-only actions | — | — |
13
+
14
+ ## Sizes
15
+
16
+ `small` | `normal` (default) | `large`
17
+
18
+ ## Key props
19
+
20
+ | Prop | Type | Effect |
21
+ |---|---|---|
22
+ | `size` | `"small" \| "normal" \| "large"` | Controls padding and font size |
23
+ | `icon` | Icon component | Leading or trailing icon |
24
+ | `iconPosition` | `"left" \| "right"` | Defaults to left |
25
+ | `disabled` | boolean | Disabled state styling |
26
+ | `href` | string | Renders as `<a>` tag |
27
+
28
+ ## States
29
+
30
+ `default` → `hover` (`primary-hover` / `secondary-hover`) → `active` → `disabled` (`text-disabled` + `background-disabled`)
31
+
32
+ ## Token cheatsheet
33
+
34
+ ```
35
+ FillButton → bg: primary (#3A10E5 light / #FFD300 dark), color: white, hover: primary-hover
36
+ StrokeButton → bg: transparent, border: secondary (#10162F / #fff), hover: secondary-hover
37
+ TextButton → bg: transparent, color: primary, hover: primary-hover
38
+ ```
39
+
40
+ ## Rules
41
+
42
+ - Use `FillButton` for primary actions and `StrokeButton` for secondary — do not use both at equal weight.
43
+ - Reserve `CTAButton` for marketing / high-visibility promotions; do not use it for standard UI actions.
44
+ - Every interactive `Card` wrapped in `<Anchor>` should have `isInteractive` — not a button inside.