@codecademy/gamut 68.6.1-alpha.f6b2ce.0 → 68.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Modals/elements.d.ts +186 -1
- package/dist/Modals/elements.js +3 -3
- package/dist/{InternalFloatingCard/InternalFloatingCard.d.ts → PatternBackdrop/PatternBackdrop.d.ts} +8 -24
- package/dist/PatternBackdrop/PatternBackdrop.js +42 -0
- package/dist/Toast/Toast.js +4 -4
- package/package.json +8 -11
- package/agent-tools/.claude-plugin/marketplace.json +0 -16
- package/agent-tools/.claude-plugin/plugin.json +0 -7
- package/agent-tools/.cursor-plugin/plugin.json +0 -7
- package/agent-tools/DESIGN.Codecademy.md +0 -696
- package/agent-tools/DESIGN.LXStudio.md +0 -512
- package/agent-tools/DESIGN.Percipio.md +0 -513
- package/agent-tools/DESIGN.md +0 -1
- package/agent-tools/agents/.gitkeep +0 -0
- package/agent-tools/commands/gamut-review.md +0 -259
- package/agent-tools/guidelines/components/animations.md +0 -74
- package/agent-tools/guidelines/components/buttons.md +0 -95
- package/agent-tools/guidelines/components/card.md +0 -19
- package/agent-tools/guidelines/components/coachmark.md +0 -21
- package/agent-tools/guidelines/components/data-table.md +0 -79
- package/agent-tools/guidelines/components/forms.md +0 -106
- package/agent-tools/guidelines/components/loading-states.md +0 -17
- package/agent-tools/guidelines/components/menu.md +0 -58
- package/agent-tools/guidelines/components/overview.md +0 -124
- package/agent-tools/guidelines/components/radial-progress.md +0 -13
- package/agent-tools/guidelines/components/select.md +0 -23
- package/agent-tools/guidelines/components/tooltips.md +0 -22
- package/agent-tools/guidelines/components/video.md +0 -29
- package/agent-tools/guidelines/foundations/color.md +0 -168
- package/agent-tools/guidelines/foundations/modes.md +0 -69
- package/agent-tools/guidelines/foundations/spacing.md +0 -107
- package/agent-tools/guidelines/foundations/typography.md +0 -82
- package/agent-tools/guidelines/overview-icons.md +0 -19
- package/agent-tools/guidelines/overview-illustrations.md +0 -7
- package/agent-tools/guidelines/overview-patterns.md +0 -7
- package/agent-tools/guidelines/overview.md +0 -84
- package/agent-tools/guidelines/setup.md +0 -83
- package/agent-tools/rules/accessibility.mdc +0 -78
- package/agent-tools/skills/gamut-accessibility/SKILL.md +0 -224
- package/agent-tools/skills/gamut-color-mode/SKILL.md +0 -149
- package/agent-tools/skills/gamut-components/SKILL.md +0 -46
- package/agent-tools/skills/gamut-forms/SKILL.md +0 -101
- package/agent-tools/skills/gamut-style-utilities/SKILL.md +0 -111
- package/agent-tools/skills/gamut-system-props/SKILL.md +0 -225
- package/agent-tools/skills/gamut-testing/SKILL.md +0 -225
- package/agent-tools/skills/gamut-theming/SKILL.md +0 -63
- package/agent-tools/skills/gamut-typography/SKILL.md +0 -79
- package/bin/commands/plugin/install.mjs +0 -213
- package/bin/commands/plugin/list.mjs +0 -73
- package/bin/commands/plugin/remove.mjs +0 -108
- package/bin/commands/plugin/update.mjs +0 -59
- package/bin/gamut.mjs +0 -96
- package/bin/lib/claude.mjs +0 -52
- package/bin/lib/cursor.mjs +0 -40
- package/bin/lib/design.mjs +0 -71
- package/bin/lib/io.mjs +0 -14
- package/bin/lib/resolve-plugin-dir.mjs +0 -38
- package/bin/lib/run-command.mjs +0 -22
- package/dist/InternalFloatingCard/InternalFloatingCard.js +0 -98
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
# Spacing, Border Radius & Layout
|
|
2
|
-
|
|
3
|
-
Token values match [`packages/gamut-styles/src/variables`](https://github.com/Codecademy/gamut/tree/main/packages/gamut-styles/src/variables) (`spacing.ts`, `borderRadii.ts`, `responsive.ts`). Breakpoints and max-content widths align with Storybook [Foundations / Layout](https://gamut.codecademy.com/?path=/docs-foundations-layout--docs).
|
|
4
|
-
|
|
5
|
-
In code — use system props for spacing: Gamut layout primitives (`Box`, `FlexBox`, `GridBox`, …) expose margin, padding, and gap props backed by `system.space` from `@codecademy/gamut-styles`. Pass spacing scale numbers (`4`, `8`, `16`, …), not raw pixel strings. For custom `styled` components, compose `system.space` (see [`gamut-system-props` skill](../../skills/gamut-system-props/SKILL.md)). [Meta / Best practices](https://gamut.codecademy.com/?path=/docs-meta-best-practices--page) shows responsive `Box` examples.
|
|
6
|
-
|
|
7
|
-
Responsive behavior: All those props accept mobile-first object (`{ _: 8, md: 24 }`) or array syntax per [Responsive properties](https://gamut.codecademy.com/?path=/docs-foundations-system-responsive-properties--page). Container queries use keys `c_base`, `c_xs`, … `c_xl`; the parent must set a container (e.g. `containerType="inline-size"` on `FlexBox`). Prefer a media-query fallback when mixing `c_*` with viewport breakpoints.
|
|
8
|
-
|
|
9
|
-
Two different “grids”:
|
|
10
|
-
|
|
11
|
-
- Design / page grid (this doc’s “Grid” section, 12 columns, margins/gutters) — product layout guidelines; implement with [`LayoutGrid`](https://gamut.codecademy.com/?path=/docs-layouts-layoutgrid-layoutgrid--docs) and responsive `columnGap` / `rowGap` where appropriate.
|
|
12
|
-
- CSS Grid system props — `system.grid` on styled components or `GridBox` for local regions; not the same as full-page `LayoutGrid`. See [System props / Grid](https://gamut.codecademy.com/?path=/docs-foundations-system-props-grid--page). `LayoutGrid` is for flexible full-page sections; use `FlexBox` / `GridBox` / `Box` for smaller areas ([LayoutGrid usage](https://gamut.codecademy.com/?path=/docs-layouts-layoutgrid-layoutgrid--docs)).
|
|
13
|
-
|
|
14
|
-
Designer vs code names: Figma / Layout docs often label artboards XL, LG, MD, SM, XS, Base. In code, viewport breakpoints are `xl`, `lg`, `md`, `sm`, `xs` (min-widths below); `_` is the base (no min-width query). The “Max content width” column maps to those design sizes, not the `xs` token name alone.
|
|
15
|
-
|
|
16
|
-
## Spacing scale
|
|
17
|
-
|
|
18
|
-
All spacing is multiples of 4px on an 8px grid.
|
|
19
|
-
|
|
20
|
-
| Token | Value |
|
|
21
|
-
| ----- | ----- |
|
|
22
|
-
| `0` | 0 |
|
|
23
|
-
| `4` | 4px |
|
|
24
|
-
| `8` | 8px |
|
|
25
|
-
| `12` | 12px |
|
|
26
|
-
| `16` | 16px |
|
|
27
|
-
| `24` | 24px |
|
|
28
|
-
| `32` | 32px |
|
|
29
|
-
| `40` | 40px |
|
|
30
|
-
| `48` | 48px |
|
|
31
|
-
| `64` | 64px |
|
|
32
|
-
| `96` | 96px |
|
|
33
|
-
|
|
34
|
-
Use multiples of 8px for block-element spacing. Use 4px only for inline or typographic relationships.
|
|
35
|
-
|
|
36
|
-
## Border radius
|
|
37
|
-
|
|
38
|
-
| Token | Value | Use |
|
|
39
|
-
| ------ | ----- | ---------------------------------- |
|
|
40
|
-
| `none` | 0px | Square / non-interactive elements |
|
|
41
|
-
| `sm` | 2px | Subtle rounding, tags |
|
|
42
|
-
| `md` | 4px | Buttons, inputs, interactive cards |
|
|
43
|
-
| `lg` | 8px | Cards, panels |
|
|
44
|
-
| `xl` | 16px | Large cards, modals |
|
|
45
|
-
| `full` | 999px | Pills, avatars, circular elements |
|
|
46
|
-
|
|
47
|
-
## Breakpoints
|
|
48
|
-
|
|
49
|
-
Mobile-first. Styles apply from the named breakpoint and up.
|
|
50
|
-
|
|
51
|
-
| Token | Min-width | Max content width |
|
|
52
|
-
| -------- | --------- | ----------------- |
|
|
53
|
-
| _(base)_ | 0 | 288px |
|
|
54
|
-
| `xs` | 480px | 448px |
|
|
55
|
-
| `sm` | 768px | 704px |
|
|
56
|
-
| `md` | 1024px | 896px |
|
|
57
|
-
| `lg` | 1200px | 1072px |
|
|
58
|
-
| `xl` | 1440px | 1248px |
|
|
59
|
-
|
|
60
|
-
The grid table below collapses xl+lg, md, sm+xs, and base to four implementation tiers; max-content widths still follow the six design sizes in Layout.
|
|
61
|
-
|
|
62
|
-
## Container query breakpoints
|
|
63
|
-
|
|
64
|
-
Container keys (`c_*`) use the same min-width numbers as viewport breakpoints, but they apply to the width of a CSS containment context (usually a parent), not the browser viewport. Use them when a component must adapt inside sidebars, split layouts, or embeds. Full detail: [Responsive properties — Container Queries](https://gamut.codecademy.com/?path=/docs-foundations-system-responsive-properties--page).
|
|
65
|
-
|
|
66
|
-
| Key | Min container width | Typical use |
|
|
67
|
-
| -------- | ------------------- | ----------------------------------------------------------------------- |
|
|
68
|
-
| `c_base` | 1px | Always matches once a container exists; base style inside the container |
|
|
69
|
-
| `c_xs` | 480px | Matches viewport `xs` threshold, but on container width |
|
|
70
|
-
| `c_sm` | 768px | |
|
|
71
|
-
| `c_md` | 1024px | |
|
|
72
|
-
| `c_lg` | 1200px | |
|
|
73
|
-
| `c_xl` | 1440px | |
|
|
74
|
-
|
|
75
|
-
Requirements
|
|
76
|
-
|
|
77
|
-
- A descendant of an element that establishes a container — e.g. parent `<FlexBox containerType="inline-size">` (or other `container-type`). Without that, `c_*` rules never match.
|
|
78
|
-
- Prefer a viewport fallback alongside `c_*` (e.g. `display={{ _: 'block', sm: 'flex', c_md: 'grid' }}`) for browsers or trees without container support.
|
|
79
|
-
|
|
80
|
-
Object vs array
|
|
81
|
-
|
|
82
|
-
- Object: `p={{ _: 8, c_md: 24 }}` — readable for a few container-only overrides.
|
|
83
|
-
- Array: after the six viewport slots (`_` through `xl`), indices 6–11 are `c_base`, `c_xs`, `c_sm`, `c_md`, `c_lg`, `c_xl` respectively. Use when you need the full ordered chain.
|
|
84
|
-
|
|
85
|
-
When to use which
|
|
86
|
-
|
|
87
|
-
- Viewport keys (`_`, `xs`, … `xl`) — page-level layout, full-bleed sections, global nav.
|
|
88
|
-
- Container keys (`c_base`, … `c_xl`) — reusable widgets whose width is driven by layout, not the device alone.
|
|
89
|
-
|
|
90
|
-
## Page layout grid (12 columns)
|
|
91
|
-
|
|
92
|
-
12-column grid at all breakpoints. Tier columns group breakpoints with identical margin/gutter/row-gap numbers from [Layout](https://gamut.codecademy.com/?path=/docs-foundations-layout--docs).
|
|
93
|
-
|
|
94
|
-
| Property | xl/lg | md | sm/xs | base |
|
|
95
|
-
| ------------------ | ----- | ---- | ----- | ---- |
|
|
96
|
-
| Horizontal margins | 64px | 48px | 32px | 16px |
|
|
97
|
-
| Column gutters | 32px | 24px | 16px | 8px |
|
|
98
|
-
| Row gaps | 32px | 24px | 16px | 8px |
|
|
99
|
-
|
|
100
|
-
Minimum touch target on mobile: 44×44px — see `gamut-accessibility` skill for hit-target guidance.
|
|
101
|
-
|
|
102
|
-
## Responsive rules
|
|
103
|
-
|
|
104
|
-
- Begin design work at 1440px (XL), then adapt down.
|
|
105
|
-
- Multi-column layouts collapse to fewer columns — do not stretch or squish.
|
|
106
|
-
- Catalog cards and non-lockup elements should align on one axis (usually left), not fill column widths.
|
|
107
|
-
- Avoid dense or small components at the base (mobile) breakpoint.
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
# Typography
|
|
2
|
-
|
|
3
|
-
Use theme typography tokens (`fontFamily`, `fontSize`, `fontWeight`, `lineHeight`) — never hardcoded font-family strings or magic px for product UI. Prefer `<Text>` from `@codecademy/gamut`, or `system.typography` / `css()` from `@codecademy/gamut-styles` ([`gamut-system-props` skill](../../skills/gamut-system-props/SKILL.md)).
|
|
4
|
-
|
|
5
|
-
Source of truth for scales and stacks: [`packages/gamut-styles/src/variables/typography.ts`](https://github.com/Codecademy/gamut/blob/main/packages/gamut-styles/src/variables/typography.ts) and theme builders under [`packages/gamut-styles/src/themes`](https://github.com/Codecademy/gamut/tree/main/packages/gamut-styles/src/themes).
|
|
6
|
-
|
|
7
|
-
Storybook: [Typography / Text](https://gamut.codecademy.com/?path=/docs-typography-text--docs) · [Meta / Best practices](https://gamut.codecademy.com/?path=/docs-meta-best-practices--page) (system props) · Foundations / Theme: [Core](https://gamut.codecademy.com/?path=/docs-foundations-theme-core-theme--docs), [Percipio](https://gamut.codecademy.com/?path=/docs-foundations-theme-percipio-theme--docs), [LX Studio](https://gamut.codecademy.com/?path=/docs-foundations-theme-lx-studio-theme--docs)
|
|
8
|
-
|
|
9
|
-
## Themes × font families
|
|
10
|
-
|
|
11
|
-
Semantic keys (`base`, `accent`, `monospace`, `system`) are stable; resolved stacks depend on `GamutProvider` theme ([`setup.md`](../setup.md)).
|
|
12
|
-
|
|
13
|
-
| Theme | `fontFamily.base` | `fontFamily.accent` | `fontFamily.monospace` | `fontFamily.system` |
|
|
14
|
-
| --------------------- | ------------------------------------ | ------------------------------------- | -------------------------------------- | ------------------------------ |
|
|
15
|
-
| Core, Admin, Platform | Apercu stack (`fontBase`) | Suisse + Apercu stack (`fontAccent`) | Monaco / Menlo stack (`fontMonospace`) | System UI stack (`fontSystem`) |
|
|
16
|
-
| Percipio | Skillsoft Text (`fontPercipioBase`) | Skillsoft Sans (`fontPercipioAccent`) | Roboto Mono | Roboto (`system`) |
|
|
17
|
-
| LX Studio | Same as Percipio (`base` / `accent`) | Same | Same stack as Core (`fontMonospace`) | Same as Core (`fontSystem`) |
|
|
18
|
-
|
|
19
|
-
Admin and Platform extend Core for colors / modes only — typography matches Core.
|
|
20
|
-
|
|
21
|
-
Licensing: Apercu is licensed for Codecademy surfaces only; Skillsoft products use Percipio/LX stacks above.
|
|
22
|
-
|
|
23
|
-
## Font size scale
|
|
24
|
-
|
|
25
|
-
Values are `rem`-backed keys on `theme.fontSize` (aliases shown as px for readability).
|
|
26
|
-
|
|
27
|
-
| Token | Size | Common use |
|
|
28
|
-
| ----- | ---- | ---------------------------- |
|
|
29
|
-
| `64` | 64px | Hero / display |
|
|
30
|
-
| `44` | 44px | Page titles |
|
|
31
|
-
| `34` | 34px | Section titles |
|
|
32
|
-
| `26` | 26px | Sub-section titles |
|
|
33
|
-
| `22` | 22px | Card titles, large UI labels |
|
|
34
|
-
| `20` | 20px | Secondary titles |
|
|
35
|
-
| `18` | 18px | Large body, intro text |
|
|
36
|
-
| `16` | 16px | Default body text |
|
|
37
|
-
| `14` | 14px | Small body, captions, labels |
|
|
38
|
-
|
|
39
|
-
## Line height
|
|
40
|
-
|
|
41
|
-
| Token | Value | Use |
|
|
42
|
-
| ------------- | ----- | ---------------------------- |
|
|
43
|
-
| `base` | 1.5 | Body text |
|
|
44
|
-
| `spacedTitle` | 1.3 | Sub-headlines, medium titles |
|
|
45
|
-
| `title` | 1.2 | Large headlines |
|
|
46
|
-
|
|
47
|
-
## Font weight (semantic)
|
|
48
|
-
|
|
49
|
-
Use semantic keys on components — do not assume a numeric bold everywhere.
|
|
50
|
-
|
|
51
|
-
| Token | Core / Admin / Platform | Percipio / LX Studio |
|
|
52
|
-
| ------- | ----------------------- | ----------------------------- |
|
|
53
|
-
| `base` | 400 | 400 |
|
|
54
|
-
| `title` | 700 | 500 (`fontWeightMediumTitle`) |
|
|
55
|
-
|
|
56
|
-
Headlines, CTAs, and buttons should use `fontWeight="title"` so Percipio/LX get 500, Core gets 700. Literal `700` breaks Skillsoft branding on those themes.
|
|
57
|
-
|
|
58
|
-
Numeric `400` and `700` keys also exist on the theme for rare explicit needs.
|
|
59
|
-
|
|
60
|
-
## Codecademy (Core / Admin / Platform) — voice & layout
|
|
61
|
-
|
|
62
|
-
These UX rules target Apercu + Suisse products; do not blindly apply to Percipio/LX without brand guidance.
|
|
63
|
-
|
|
64
|
-
- `fontFamily="base"` (Apercu): default UI and marketing type. Emphasis inside body copy: Italic, not Bold for intra-paragraph stress.
|
|
65
|
-
- `fontFamily="accent"` (Suisse stack): technical accent — code snippets, captions, labels with engineering flavor, figures. Use sparingly; glyph box reads larger — step down ~10–15% vs equivalent `base` size; give comfortable line-height.
|
|
66
|
-
- Alignment: left-align by default; center only short marketing headlines; avoid right-align except tabs / numerics.
|
|
67
|
-
- Letter-spacing: do not tweak tracking unless design specifies.
|
|
68
|
-
- Line length: ~45–85 characters per line (~66 ideal for single-column body); constrain container width, not arbitrary CSS letter-spacing.
|
|
69
|
-
|
|
70
|
-
## Line length (all products)
|
|
71
|
-
|
|
72
|
-
| Context | Target |
|
|
73
|
-
| ------------------ | ------------------- |
|
|
74
|
-
| Single-column body | ~66 chars (max ~85) |
|
|
75
|
-
| Multi-column | ≤50 chars per line |
|
|
76
|
-
| Minimum | ~45 chars |
|
|
77
|
-
|
|
78
|
-
## Related skills
|
|
79
|
-
|
|
80
|
-
- [`gamut-typography`](../../skills/gamut-typography/SKILL.md) — deeper editorial patterns for agents.
|
|
81
|
-
- [`gamut-style-utilities`](../../skills/gamut-style-utilities/SKILL.md) — `css()` / `variant` / `states` and tokenized typography in styled components.
|
|
82
|
-
- [`gamut-theming`](../../skills/gamut-theming/SKILL.md) — which theme / `GamutProvider` / `theme.d.ts`.
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
# Icons
|
|
2
|
-
|
|
3
|
-
Icons must come from `@codecademy/gamut-icons`. Do not import or generate icons from other sources. If a needed icon is unavailable, pick a verified alternative from the library or flag for confirmation — do not substitute non-system assets.
|
|
4
|
-
|
|
5
|
-
## Identifying the correct icon
|
|
6
|
-
|
|
7
|
-
Do not rely on Figma layer names (`data-name`). Layer names are often stale after icon swaps.
|
|
8
|
-
|
|
9
|
-
Determine the correct icon by:
|
|
10
|
-
|
|
11
|
-
1. Reading the design image — visually identify the shape (three vertical dots → kebab menu, 3×3 grid → app switcher, etc.).
|
|
12
|
-
2. Using contextual clues — tooltip text, element purpose, surrounding UI patterns.
|
|
13
|
-
3. Cross-referencing exports — search `@codecademy/gamut-icons` for icons matching visual and semantic intent.
|
|
14
|
-
4. Treating layer names as hints only — if a layer name conflicts with visual/contextual evidence, trust the evidence.
|
|
15
|
-
5. When uncertain, flag for confirmation rather than guessing.
|
|
16
|
-
|
|
17
|
-
Before using any icon, confirm it exists in `@codecademy/gamut-icons` (`packages/gamut-icons/src` or package exports).
|
|
18
|
-
|
|
19
|
-
Storybook: [Foundations / Icons](https://gamut.codecademy.com/?path=/docs-foundations-icons--page)
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
# Illustrations
|
|
2
|
-
|
|
3
|
-
Illustrations must come from `@codecademy/gamut-illustrations`. Do not generate or import illustrations from other sources.
|
|
4
|
-
|
|
5
|
-
If the correct illustration is unavailable, flag for confirmation rather than substituting a non-system asset.
|
|
6
|
-
|
|
7
|
-
Storybook: [Illustrations](https://gamut.codecademy.com/?path=/docs-illustrations--page) · `packages/gamut-illustrations/src` exports.
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
# Patterns
|
|
2
|
-
|
|
3
|
-
Patterns must come from `@codecademy/gamut-patterns`. Match Figma component names to pattern exports when possible.
|
|
4
|
-
|
|
5
|
-
If the correct pattern is unavailable, flag for confirmation rather than substituting a non-system asset.
|
|
6
|
-
|
|
7
|
-
Storybook: browse pattern stories under the Gamut styleguide, or inspect `packages/gamut-patterns/src` exports.
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
# Gamut Design System
|
|
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
|
-
|
|
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.
|
|
8
|
-
|
|
9
|
-
Core principle: Always use Gamut components, tokens, and patterns. Every element must trace back to an existing token, component, or documented pattern — never 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.
|
|
12
|
-
|
|
13
|
-
Core principles:
|
|
14
|
-
|
|
15
|
-
- Components are color mode–aware by default — never hardcode hex values for adaptive, accessible UI
|
|
16
|
-
- All components work across all themes without modification
|
|
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`.
|
|
22
|
-
|
|
23
|
-
## Themes
|
|
24
|
-
|
|
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.
|
|
34
|
-
|
|
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`.
|
|
36
|
-
|
|
37
|
-
## Reading order
|
|
38
|
-
|
|
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`).
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
# Setup
|
|
2
|
-
|
|
3
|
-
## Install
|
|
4
|
-
|
|
5
|
-
```sh
|
|
6
|
-
yarn add @codecademy/gamut-kit @emotion/react @emotion/styled
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
`gamut-kit` bundles `gamut`, `gamut-icons`, `gamut-illustrations`, `gamut-patterns`, `gamut-styles`, `variance`, and `gamut-tests`.
|
|
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
|
-
|
|
17
|
-
## Required wrapper
|
|
18
|
-
|
|
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.
|
|
22
|
-
|
|
23
|
-
```tsx
|
|
24
|
-
import { GamutProvider, theme } from '@codecademy/gamut-styles';
|
|
25
|
-
|
|
26
|
-
const App = () => (
|
|
27
|
-
<GamutProvider theme={theme}>{/* app content */}</GamutProvider>
|
|
28
|
-
);
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## Theme selection
|
|
32
|
-
|
|
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` |
|
|
40
|
-
|
|
41
|
-
All themes are exported from `@codecademy/gamut-styles`.
|
|
42
|
-
|
|
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
|
-
```
|
|
82
|
-
|
|
83
|
-
See Emotion’s [TypeScript / define a theme](https://emotion.sh/docs/typescript#define-a-theme) for details.
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
---
|
|
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
|
-
alwaysApply: true
|
|
4
|
-
globs: ['*.tsx', '*.ts', '*.jsx', '*.js']
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Gamut Accessibility Rules
|
|
8
|
-
|
|
9
|
-
## Prefer HTML over ARIA
|
|
10
|
-
|
|
11
|
-
Unnecessary ARIA can cause harm. If a native HTML element or attribute with the semantics and behavior you need already exists, use it. Reach for ARIA only when native HTML is genuinely insufficient for the pattern.
|
|
12
|
-
|
|
13
|
-
## A Role is a Promise
|
|
14
|
-
|
|
15
|
-
ARIA roles modify the accessibility tree and _imply_ behavior. Always ensure that the implied keyboard behavior, focusability, and interactivity exists when a role is used.
|
|
16
|
-
|
|
17
|
-
## ARIA can both cloak and enhance
|
|
18
|
-
|
|
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
|
-
|
|
21
|
-
## Align accessible names with visible copy
|
|
22
|
-
|
|
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.
|
|
24
|
-
|
|
25
|
-
## Treat missing visible labels as a design smell
|
|
26
|
-
|
|
27
|
-
When there is no visible text for a nameable element, consider this a sign that the content design could be improved, but not a requirement that it is changed. This is not an accessibility violation.
|
|
28
|
-
|
|
29
|
-
```html
|
|
30
|
-
<!-- smell: this list has no conceptual name, so we have to create one using ARIA -->
|
|
31
|
-
<ul aria-label="List heading">
|
|
32
|
-
<li>...</li>
|
|
33
|
-
</ul>
|
|
34
|
-
|
|
35
|
-
<!-- better: the list's name is visible and can be used for its accessible name -->
|
|
36
|
-
<h2 id="list-name">List heading</h2>
|
|
37
|
-
<ul aria-labelledby="list-name">
|
|
38
|
-
<li>...</li>
|
|
39
|
-
</ul>
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
## Use Gamut primitives — do not fake buttons or dialogs
|
|
43
|
-
|
|
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.
|
|
46
|
-
|
|
47
|
-
## Every interactive control needs an accessible name
|
|
48
|
-
|
|
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.
|
|
52
|
-
|
|
53
|
-
## Form label association
|
|
54
|
-
|
|
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).
|
|
56
|
-
|
|
57
|
-
## Screen-reader-only text
|
|
58
|
-
|
|
59
|
-
Use `<Text screenreader>` for visually hidden but announced content. `<HiddenText>` is deprecated.
|
|
60
|
-
|
|
61
|
-
## Color and contrast
|
|
62
|
-
|
|
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.
|
|
64
|
-
|
|
65
|
-
## Focus visibility
|
|
66
|
-
|
|
67
|
-
Never suppress focus indicators with `outline: none` or `outline: 0` without a visible replacement. Gamut’s 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) |
|