@codecademy/gamut 68.6.1-alpha.edab62.0 → 68.6.1-alpha.f6b2ce.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/agent-tools/.cursor-plugin/plugin.json +1 -1
  2. package/agent-tools/DESIGN.Codecademy.md +466 -413
  3. package/agent-tools/DESIGN.LXStudio.md +350 -282
  4. package/agent-tools/DESIGN.Percipio.md +357 -279
  5. package/agent-tools/commands/gamut-review.md +176 -87
  6. package/agent-tools/guidelines/components/animations.md +74 -0
  7. package/agent-tools/guidelines/components/buttons.md +74 -23
  8. package/agent-tools/guidelines/components/card.md +19 -0
  9. package/agent-tools/guidelines/components/coachmark.md +21 -0
  10. package/agent-tools/guidelines/components/data-table.md +79 -0
  11. package/agent-tools/guidelines/components/forms.md +106 -0
  12. package/agent-tools/guidelines/components/loading-states.md +17 -0
  13. package/agent-tools/guidelines/components/menu.md +58 -0
  14. package/agent-tools/guidelines/components/overview.md +97 -17
  15. package/agent-tools/guidelines/components/radial-progress.md +13 -0
  16. package/agent-tools/guidelines/components/select.md +23 -0
  17. package/agent-tools/guidelines/components/tooltips.md +22 -0
  18. package/agent-tools/guidelines/components/video.md +29 -0
  19. package/agent-tools/guidelines/foundations/color.md +140 -58
  20. package/agent-tools/guidelines/foundations/modes.md +41 -17
  21. package/agent-tools/guidelines/foundations/spacing.md +78 -37
  22. package/agent-tools/guidelines/foundations/typography.md +69 -37
  23. package/agent-tools/guidelines/overview-icons.md +19 -0
  24. package/agent-tools/guidelines/overview-illustrations.md +7 -0
  25. package/agent-tools/guidelines/overview-patterns.md +7 -0
  26. package/agent-tools/guidelines/overview.md +71 -22
  27. package/agent-tools/guidelines/setup.md +59 -18
  28. package/agent-tools/rules/accessibility.mdc +22 -13
  29. package/agent-tools/skills/gamut-accessibility/SKILL.md +97 -112
  30. package/agent-tools/skills/gamut-color-mode/SKILL.md +91 -41
  31. package/agent-tools/skills/gamut-components/SKILL.md +46 -0
  32. package/agent-tools/skills/gamut-forms/SKILL.md +101 -0
  33. package/agent-tools/skills/gamut-style-utilities/SKILL.md +111 -0
  34. package/agent-tools/skills/gamut-system-props/SKILL.md +81 -29
  35. package/agent-tools/skills/gamut-testing/SKILL.md +106 -62
  36. package/agent-tools/skills/gamut-theming/SKILL.md +36 -86
  37. package/agent-tools/skills/gamut-typography/SKILL.md +36 -80
  38. package/bin/commands/plugin/install.mjs +96 -56
  39. package/bin/commands/plugin/list.mjs +11 -43
  40. package/bin/commands/plugin/remove.mjs +30 -38
  41. package/bin/commands/plugin/update.mjs +15 -5
  42. package/bin/gamut.mjs +17 -13
  43. package/bin/lib/design.mjs +71 -0
  44. package/bin/lib/io.mjs +14 -0
  45. package/package.json +6 -6
  46. package/bin/lib/figma.mjs +0 -49
@@ -1,35 +1,84 @@
1
1
  # Gamut Design System
2
2
 
3
+ ## For agents
4
+
5
+ Do not load all guideline files. Read this overview’s Step 2 table, then open only the `guidelines/components/*.md` (or foundation) guides you need for the current task. For Menu, DataTable, Card, and other components without a dedicated skill, use `gamut-components`.
6
+
3
7
  Gamut is the Codecademy / Skillsoft design system — React component library (`@codecademy/gamut`), design tokens (`@codecademy/gamut-styles`), and Figma components with live code previews via Figma Code Connect.
4
8
 
5
- **Design voice**: "Ruled by logic, but creative and a bit unexpected." Structured and trustworthy for a learning platform, with engaging personality. Medium density information-rich layouts with strong typographic hierarchy. Never cramped or overly airy.
9
+ Core principle: Always use Gamut components, tokens, and patterns. Every element must trace back to an existing token, component, or documented patternnever introduce ad-hoc values when a system equivalent exists.
10
+
11
+ Design voice: "Ruled by logic, but creative and a bit unexpected." Structured and trustworthy for a learning platform, with engaging personality. Medium density — information-rich layouts with strong typographic hierarchy.
6
12
 
7
- **Core principles**:
8
- - Components are color mode–aware by default — never hardcode hex values for adaptive UI
13
+ Core principles:
14
+
15
+ - Components are color mode–aware by default — never hardcode hex values for adaptive, accessible UI
9
16
  - All components work across all themes without modification
10
- - Mobile-first, 12-column grid
11
- - Semantic color tokens guarantee WCAG AA contrast automatically
17
+ - 12-column grid
18
+ - Use semantic theme tokens from `@codecademy/gamut-styles` for color roles, typography, spacing, border radii, and layout — not raw palette hex or magic numbers. Validate non-standard combinations against WCAG.
19
+ - Product theme: infer semantic tokens, fonts, and palette from root `DESIGN.md` (installed via `gamut plugin install --theme <name>`) and `<GamutProvider>`. See [`skills/gamut-theming/SKILL.md`](../skills/gamut-theming/SKILL.md).
20
+
21
+ Agent skills: `gamut-components`, `gamut-style-utilities`, `gamut-theming`, `gamut-system-props`, `gamut-color-mode`, `gamut-forms`, `gamut-accessibility`, `gamut-typography`, `gamut-testing`.
12
22
 
13
23
  ## Themes
14
24
 
15
- | Theme | Product | Base font | Dark mode |
16
- |---|---|---|---|
17
- | **Core** | Codecademy (default) | Apercu | ✓ |
18
- | **Admin** | Codecademy admin tools | Apercu | ✓ |
19
- | **Platform** | Codecademy learning environment | Apercu | ✓ |
20
- | **LX Studio** | LX Studio application | Hanken Grotesk | |
21
- | **Percipio** | Skillsoft Percipio | Roboto | |
25
+ | Theme | Product | Primary UI fonts (shipped theme) | Dark mode |
26
+ | --------- | ------------------------------- | ------------------------------------------------------ | --------- |
27
+ | Core | Codecademy (default) | Apercu + Suisse (`accent`) | ✓ |
28
+ | Admin | Codecademy admin tools | Same as Core | ✓ |
29
+ | Platform | Codecademy learning environment | Same as Core | ✓ |
30
+ | LX Studio | LX Studio application | Skillsoft Text / Sans (`base` / `accent`) | ✓ |
31
+ | Percipio | Skillsoft Percipio | Skillsoft Text / Sans; Roboto Mono / Roboto (`system`) | ✓ |
32
+
33
+ Set the theme at the app root via `<GamutProvider theme={...}>`. Match `DESIGN.md` in the app repo to the active product.
22
34
 
23
- Set the theme at the app root via `<GamutProvider theme={...}>`.
35
+ Plugin install: Storybook [Meta → AI Tooling → Gamut plugin → Install](https://gamut.codecademy.com/?path=/docs-meta-ai-tooling-gamut-plugin-install--page). `gamut plugin install cursor --theme core` (or `percipio`, `lxstudio`, …) copies `DESIGN.*.md` to `./DESIGN.md`.
24
36
 
25
37
  ## Reading order
26
38
 
27
- | File | What it covers |
28
- |---|---|
29
- | [setup.md](setup.md) | Packages, GamutProvider, theme selection |
30
- | [foundations/color.md](foundations/color.md) | Semantic aliases, raw palette, decision guide |
31
- | [foundations/modes.md](foundations/modes.md) | Light/dark ColorMode, Background component |
32
- | [foundations/typography.md](foundations/typography.md) | Typefaces, font scale, rules |
33
- | [foundations/spacing.md](foundations/spacing.md) | Spacing, border radius, responsive grid |
34
- | [components/overview.md](components/overview.md) | Full component catalog |
35
- | [components/buttons.md](components/buttons.md) | Button variants, props, decision tree |
39
+ ### Step 1: Overview (required)
40
+
41
+ | File | What it covers |
42
+ | -------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
43
+ | [setup.md](setup.md) | Packages, `GamutProvider`, theme selection |
44
+ | [foundations/spacing.md](foundations/spacing.md) + [color.md](foundations/color.md) + [typography.md](foundations/typography.md) | Tokens spacing, color, typography |
45
+ | [foundations/modes.md](foundations/modes.md) | `ColorMode`, `Background` |
46
+ | [components/overview.md](components/overview.md) | Component catalog, discovery, forms breadcrumb |
47
+ | [overview-icons.md](overview-icons.md) | Icon selection from `@codecademy/gamut-icons` |
48
+ | [overview-illustrations.md](overview-illustrations.md) | `@codecademy/gamut-illustrations` |
49
+ | [overview-patterns.md](overview-patterns.md) | `@codecademy/gamut-patterns` |
50
+ | [validation-checklist.md](validation-checklist.md) | Pre-ship checklist |
51
+
52
+ ### Step 2: Component guides (read before using that component)
53
+
54
+ | Using… | Read first |
55
+ | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
56
+ | `FillButton` / `StrokeButton` / `TextButton` / `IconButton` / `CTAButton` | [components/buttons.md](components/buttons.md) |
57
+ | `GridForm` / `ConnectedForm` | [components/forms.md](components/forms.md) · [`skills/gamut-forms/SKILL.md`](../skills/gamut-forms/SKILL.md) |
58
+ | `DataTable` / `DataList` | [components/data-table.md](components/data-table.md) |
59
+ | `Menu` / `MenuItem` / `MenuSeparator` | [components/menu.md](components/menu.md) |
60
+ | `Card` | [components/card.md](components/card.md) |
61
+ | `Select` / `SelectDropdown` | [components/select.md](components/select.md) |
62
+ | `RadialProgress` | [components/radial-progress.md](components/radial-progress.md) |
63
+ | `Shimmer` / `Spinner` / `FeatureShimmer` | [components/loading-states.md](components/loading-states.md) |
64
+ | `Coachmark` | [components/coachmark.md](components/coachmark.md) |
65
+ | `ToolTip` / `InfoTip` | [components/tooltips.md](components/tooltips.md) |
66
+ | `Video` | [components/video.md](components/video.md) |
67
+ | `Rotation` / `ExpandInCollapseOut` / `FadeInSlideOut` | [components/animations.md](components/animations.md) |
68
+ | `ColorMode` / `Background` | [foundations/modes.md](foundations/modes.md) · [`skills/gamut-color-mode/SKILL.md`](../skills/gamut-color-mode/SKILL.md) |
69
+
70
+ ### Step 3: Skills (on demand)
71
+
72
+ | Skill | When |
73
+ | ------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
74
+ | [`gamut-components`](../skills/gamut-components/SKILL.md) | Menu, DataTable, Card, Select, Video, Coachmark, loading, animations (read matching component guides) |
75
+ | [`gamut-style-utilities`](../skills/gamut-style-utilities/SKILL.md) | `css` / `variant` / `states`, `StyleProps` |
76
+ | [`gamut-system-props`](../skills/gamut-system-props/SKILL.md) | `system.*`, responsive props, `Box` |
77
+ | [`gamut-theming`](../skills/gamut-theming/SKILL.md) | Theme matrix, `GamutProvider`, new themes |
78
+ | [`gamut-color-mode`](../skills/gamut-color-mode/SKILL.md) | ColorMode, semantic color, `<Background>` |
79
+ | [`gamut-forms`](../skills/gamut-forms/SKILL.md) | Form accessibility wiring |
80
+ | [`gamut-accessibility`](../skills/gamut-accessibility/SKILL.md) | Component a11y matrix, overlays |
81
+ | [`gamut-typography`](../skills/gamut-typography/SKILL.md) | Type stacks and voice |
82
+ | [`gamut-testing`](../skills/gamut-testing/SKILL.md) | `setupRtl`, test harnesses |
83
+
84
+ Pre-ship audit: [`commands/gamut-review.md`](../commands/gamut-review.md) (`/gamut-review`).
@@ -3,40 +3,81 @@
3
3
  ## Install
4
4
 
5
5
  ```sh
6
- npm install @codecademy/gamut-kit
6
+ yarn add @codecademy/gamut-kit @emotion/react @emotion/styled
7
7
  ```
8
8
 
9
9
  `gamut-kit` bundles `gamut`, `gamut-icons`, `gamut-illustrations`, `gamut-patterns`, `gamut-styles`, `variance`, and `gamut-tests`.
10
10
 
11
+ Full guide: [Meta / Installation](https://gamut.codecademy.com/?path=/docs-meta-installation--page) in Storybook (CSP `nonce` on `GamutProvider`, Jest, Next/Gatsby entry points). For Emotion + TypeScript, add `theme.d.ts` as in [TypeScript (`theme.d.ts`)](#typescript-themedts) below.
12
+
13
+ Product design intent: After install, use root `DESIGN.md` (from `gamut plugin install --theme <name>`) with [`skills/gamut-theming/SKILL.md`](../skills/gamut-theming/SKILL.md) for semantic tokens, fonts, and component patterns for that product. Do not modify or alias `@codecademy/*` packages away from published APIs.
14
+
15
+ Optionally add a `peerDependencies` block in `package.json` listing `@codecademy/gamut`, `@codecademy/gamut-icons`, `@codecademy/gamut-illustrations`, `@codecademy/gamut-patterns`, `@codecademy/gamut-styles`, `@codecademy/gamut-tests`, and `@codecademy/variance` (e.g. `"*"`) so editors surface those packages — see Meta / Installation for the JSON snippet.
16
+
11
17
  ## Required wrapper
12
18
 
13
- Wrap the app root in `<GamutProvider>`. This wires up the theme, color mode, and logical properties for all child components.
19
+ Wrap the app root in `<GamutProvider>` from `@codecademy/gamut-styles`. This wires up the theme, color mode, and logical properties for all child components.
20
+
21
+ At runtime, `GamutProvider` defaults to Core when `theme` is omitted (`theme = coreTheme` in the implementation). For non-Core products and for TypeScript (`theme` is required on `GamutProviderProps`), pass `theme` explicitly using the table below.
14
22
 
15
23
  ```tsx
16
- import { GamutProvider } from '@codecademy/gamut';
17
- import { theme } from '@codecademy/gamut-styles';
24
+ import { GamutProvider, theme } from '@codecademy/gamut-styles';
18
25
 
19
26
  const App = () => (
20
- <GamutProvider theme={theme}>
21
- {/* app content */}
22
- </GamutProvider>
27
+ <GamutProvider theme={theme}>{/* app content */}</GamutProvider>
23
28
  );
24
29
  ```
25
30
 
26
31
  ## Theme selection
27
32
 
28
- | Product | Theme to import |
29
- |---|---|
30
- | Codecademy public | `coreTheme` (default `theme`) |
31
- | Codecademy admin | `adminTheme` |
32
- | Codecademy platform | `platformTheme` |
33
- | LX Studio | `lxStudioTheme` |
34
- | Percipio | `percipioTheme` |
33
+ | Product | Theme to import |
34
+ | ------------------- | ----------------------------- |
35
+ | Codecademy public | `coreTheme` (default `theme`) |
36
+ | Codecademy admin | `adminTheme` |
37
+ | Codecademy platform | `platformTheme` |
38
+ | LX Studio | `lxStudioTheme` |
39
+ | Percipio | `percipioTheme` |
35
40
 
36
41
  All themes are exported from `@codecademy/gamut-styles`.
37
42
 
38
- ## Font licensing
43
+ ## TypeScript (`theme.d.ts`)
44
+
45
+ Augment `@emotion/react` so `props.theme` in `styled` / `css` matches the same theme object you pass to `<GamutProvider theme={...}>`. If the types disagree, system props and token autocomplete will not line up with runtime.
46
+
47
+ Add a root `theme.d.ts` (or merge into your existing global types):
48
+
49
+ ```tsx
50
+ // theme.d.ts
51
+ import '@emotion/react';
52
+
53
+ import type { CoreTheme } from '@codecademy/gamut-styles';
54
+
55
+ declare module '@emotion/react' {
56
+ export interface Theme extends CoreTheme {}
57
+ }
58
+ ```
59
+
60
+ Use the theme interface that matches your provider — same row as the [theme selection](#theme-selection) table:
61
+
62
+ | `GamutProvider` `theme` prop | Import for `Theme extends …` |
63
+ | ---------------------------- | ---------------------------- |
64
+ | `theme` or `coreTheme` | `CoreTheme` |
65
+ | `adminTheme` | `AdminTheme` |
66
+ | `platformTheme` | `PlatformTheme` |
67
+ | `lxStudioTheme` | `LxStudioTheme` |
68
+ | `percipioTheme` | `PercipioTheme` |
69
+
70
+ Example when the app uses Percipio:
71
+
72
+ ```tsx
73
+ // theme.d.ts
74
+ import '@emotion/react';
75
+
76
+ import type { PercipioTheme } from '@codecademy/gamut-styles';
77
+
78
+ declare module '@emotion/react' {
79
+ export interface Theme extends PercipioTheme {}
80
+ }
81
+ ```
39
82
 
40
- **Apercu Pro** is licensed for codecademy.com only. Non-Codecademy products must use their theme's approved typeface:
41
- - LX Studio → Hanken Grotesk
42
- - Percipio → Roboto
83
+ See Emotion’s [TypeScript / define a theme](https://emotion.sh/docs/typescript#define-a-theme) for details.
@@ -1,7 +1,7 @@
1
1
  ---
2
- description: Apply these guardrails when editing Gamut UI in TS/JS/TSX/JSX. Mirrors the General rules in the `gamut-accessibility` skill; see `skills/gamut-accessibility/SKILL.md` in this plugin for full component patterns and checklists. Loaded automatically for matched files.
2
+ description: Apply these guardrails when editing Gamut UI in TS/JS/TSX/JSX. Universal rules (always loaded). Form wiring depth: `gamut-forms` skill; other component matrix and audit detail: `gamut-accessibility` those skills do not repeat this rule set.
3
3
  alwaysApply: true
4
- globs: ["*.tsx", "*.ts", "*.jsx", "*.js"]
4
+ globs: ['*.tsx', '*.ts', '*.jsx', '*.js']
5
5
  ---
6
6
 
7
7
  # Gamut Accessibility Rules
@@ -18,7 +18,6 @@ ARIA roles modify the accessibility tree and _imply_ behavior. Always ensure tha
18
18
 
19
19
  ARIA can augment native semantics (`aria-pressed` on a `<button>`) or override them entirely (`role="menuitem"` on an `<a>`). Both capabilities are powerful and dangerous. Override only when native HTML genuinely doesn't fit the pattern; when augmenting, don't contradict the native semantics.
20
20
 
21
-
22
21
  ## Align accessible names with visible copy
23
22
 
24
23
  Prefer wiring names through visible text and native `<label>` / control text / `alt` over using `aria-label`. Point `aria-labelledby` at the visible heading or label that should define the name if it's not possible to name elements from their content. Use bare `aria-label` when there is no suitable visible label.
@@ -40,21 +39,20 @@ When there is no visible text for a nameable element, consider this a sign that
40
39
  </ul>
41
40
  ```
42
41
 
43
- ## Use Gamut componentsdon't reimplement what they already solve
42
+ ## Use Gamut primitivesdo not fake buttons or dialogs
44
43
 
45
- - `<Button>` not `<div onClick>` or `<span role="button">`
46
- - `<Tabs>` / `<Tab>` / `<TabList>` / `<TabPanel>`arrow key, Home, End navigation is automatic
47
- - `<Dialog>` / `<Modal>` — always provide an accessible name; **prefer `aria-labelledby`** to a visible title when one exists, otherwise `aria-label`. Focus lock and Escape are handled by the components.
44
+ - Actions: use Gamut button atoms (`FillButton`, `TextButton`, `StrokeButton`, `CTAButton`, `IconButton`) — not `<div onClick>`, not `<span role="button">`, not `<a>` without `href` for actions. Variant and `tip` guidance: [`guidelines/components/buttons.md`](../guidelines/components/buttons.md).
45
+ - Tabs / overlays: `Tabs`, `Dialog`, `Modal`, and related primitives implement keyboard and focus patterns in code still supply labels, titles, and trigger semantics as documented in the skill.
48
46
 
49
47
  ## Every interactive control needs an accessible name
50
48
 
51
- - **`<IconButton>`** — provide `tip` (becomes the accessible name for icon-only)
52
- - **`<InfoTip>`** — provide `ariaLabel` or `ariaLabelledby`; there is no automatic fallback
53
- - Icon SVGs next to visible text — add `aria-hidden="true"` to decorative icons
49
+ - `IconButton` — provide `tip` (accessible name for icon-only).
50
+ - `InfoTip` — provide `ariaLabel` or `ariaLabelledby`; there is no automatic fallback.
51
+ - Decorative icon SVGs next to visible text — `aria-hidden="true"` on the icon.
54
52
 
55
53
  ## Form label association
56
54
 
57
- Match `htmlFor` on `<FormGroupLabel>` with the `id` on the input. `<FormGroup>` auto-wires `aria-live` for `error` and `description` — do not add redundant live regions manually.
55
+ Match `htmlFor` on `<FormGroupLabel>` with the `id` on the control. Base `<FormGroup>` renders live regions for `error` and `description`; `GridForm` and `ConnectedForm` add field wiring (`aria-describedby`, `aria-invalid`, first-error `aria-live` behavior) — do not add redundant duplicate regions. Depth: [`skills/gamut-forms/SKILL.md`](../skills/gamut-forms/SKILL.md).
58
56
 
59
57
  ## Screen-reader-only text
60
58
 
@@ -62,8 +60,19 @@ Use `<Text screenreader>` for visually hidden but announced content. `<HiddenTex
62
60
 
63
61
  ## Color and contrast
64
62
 
65
- Do not hardcode hex values for adaptive UI. Gamut semantic color tokens through `ColorMode` are built for WCAG AA; see the `gamut-color-mode` skill for token usage. For non-text contrast, focus order, and ARIA beyond color, see `gamut-accessibility`.
63
+ Do not hardcode hex for adaptive UI. Prefer semantic tokens and `ColorMode` / `<Background>` so surfaces track theme and mode — see the `gamut-color-mode` skill and [`foundations/modes.md`](../guidelines/foundations/modes.md). Default pairings support accessible UI, but tokens do not guarantee WCAG compliance for every layout; validate non-standard combinations.
66
64
 
67
65
  ## Focus visibility
68
66
 
69
- Never suppress focus indicators with `outline: none` or `outline: 0` without a visible replacement. Gamut's focus styles are intentional and meet WCAG 2.4.7.
67
+ Never suppress focus indicators with `outline: none` or `outline: 0` without a visible replacement. Gamuts focus styles are intentional (WCAG 2.4.7).
68
+
69
+ ## Where to read more (minimal index)
70
+
71
+ | Topic | Primary doc |
72
+ | --- | --- |
73
+ | Forms (`GridForm`, `ConnectedForm`, `FormGroup`, validation, live regions) | [`skills/gamut-forms/SKILL.md`](../skills/gamut-forms/SKILL.md) |
74
+ | Component matrix (tips, overlays, composites, checklists; not form wiring) | [`skills/gamut-accessibility/SKILL.md`](../skills/gamut-accessibility/SKILL.md) |
75
+ | Button variants, `IconButton` `tip`, `disabled` vs `aria-disabled` | [`guidelines/components/buttons.md`](../guidelines/components/buttons.md) |
76
+ | ColorMode, `Background`, semantic color roles | `gamut-color-mode` skill · [`foundations/modes.md`](../guidelines/foundations/modes.md) · [`foundations/color.md`](../guidelines/foundations/color.md) |
77
+ | Tokens, `css` / `variant` / `states` | Storybook [Meta / Best practices](https://gamut.codecademy.com/?path=/docs-meta-best-practices--page) |
78
+ | Install, `GamutProvider`, CSP | Storybook [Meta / Installation](https://gamut.codecademy.com/?path=/docs-meta-installation--page) |