Skip to content

Commit 0c31a30

Browse files
committed
feat: add initial support for figma make kits
1 parent f8d2416 commit 0c31a30

10 files changed

Lines changed: 444 additions & 12 deletions

File tree

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Components
2+
3+
52 components have Figma ↔ code mappings via Figma Code Connect (`packages/code-connect/`). Live code snippets appear in Figma's inspect panel when you select a component.
4+
5+
## Atoms — foundational, single-purpose
6+
7+
Badge, Button (FillButton, StrokeButton, CTAButton, TextButton, IconButton), ButtonBase, Card, Checkbox, CodeBlock, ColorMode, Drawer, FlexBox, FormGroup, GridBox, HiddenText, Icon, Input, Label, Loader, Radio, Select, Spinner, Tag, TextArea, Toggle, Tooltip
8+
9+
## Molecules — composed of atoms
10+
11+
Alert, Anchor, Breadcrumbs, Coachmark, Disclosure, GridForm, Markdown, Menu, Modal, Pagination, Popover, ProgressBar, Table, Tabs, Toast, Toaster, Video
12+
13+
## Organisms — page-level compositions
14+
15+
ContentContainer, GridContainer, Layout, LayoutGrid
16+
17+
## Key patterns
18+
19+
### Buttons
20+
See [buttons.md](buttons.md) for full reference. Use `FillButton` for primary actions, `StrokeButton` for secondary.
21+
22+
### Cards
23+
- **Background variants**: `default` (ColorMode-responsive), `white`, `yellow`, `beige`, `navy`, `hyper`
24+
- **Shadow variants**: `none` (default), `outline`, `patternLeft`, `patternRight`
25+
- Add `isInteractive` when wrapping in `<Anchor>` — enables hover shadow + `borderRadius: md`
26+
- Default `borderRadius` is `none`; override with `borderRadius` prop
27+
28+
### Color-aware components
29+
- `<ColorMode mode="light|dark|system">` — scopes a subtree to an explicit color mode
30+
- `<Background bg="<color>">` — applies background color + auto-switches inner color mode for contrast
31+
32+
### Alerts
33+
| Variant | Tokens |
34+
|---|---|
35+
| Error | `feedback-error` + `background-error` |
36+
| Success | `feedback-success` + `background-success` |
37+
| Warning | `feedback-warning` + `background-warning` |
38+
39+
## Global tokens
40+
41+
| Token | Value | Use |
42+
|---|---|---|
43+
| `headerHeight` | 64px (base), 80px (md+) | Global page header height |
44+
| `headerZ` | 15 | Z-index for global page header |
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Color
2+
3+
Use **semantic aliases** for all UI that adapts to color mode or theme. Use raw palette tokens only when a color must stay fixed regardless of mode.
4+
5+
## Semantic aliases
6+
7+
### Text
8+
9+
| Token | Light | Dark | Use for |
10+
|---|---|---|---|
11+
| `text` | `#10162F` | `#ffffff` | Default body and UI text |
12+
| `text-accent` | `#0A0D1C` | `#FFF0E5` | Stronger emphasis text |
13+
| `text-secondary` | navy-800 75% | white 65% | Supporting / secondary copy |
14+
| `text-disabled` | navy-800 63% | white 50% | Disabled state labels |
15+
16+
### Background
17+
18+
| Token | Light | Dark | Use for |
19+
|---|---|---|---|
20+
| `background` | `#ffffff` | `#10162F` | Default page/component background |
21+
| `background-primary` | `#FFF0E5` | `#0A0D1C` | Slightly elevated surfaces |
22+
| `background-contrast` | white | black | Maximum contrast surface |
23+
| `background-selected` | navy-800 4% | white 4% | Selected row / item |
24+
| `background-hover` | navy-800 12% | white 9% | Hover state overlay |
25+
| `background-disabled` | navy-800 12% | white 9% | Disabled surface |
26+
| `background-success` | `#F5FFE3` | `#151C07` | Success state container |
27+
| `background-warning` | `#FFFAE5` | `#211B00` | Warning state container |
28+
| `background-error` | `#FBF1F0` | `#280503` | Error state container |
29+
30+
### Interactive
31+
32+
| Token | Light | Dark | Use for |
33+
|---|---|---|---|
34+
| `primary` | `#3A10E5` | `#FFD300` | Primary CTA, links, focus rings |
35+
| `primary-hover` | `#5533FF` | `#CCA900` | Hover on primary interactive |
36+
| `primary-inverse` | `#FFD300` | `#3A10E5` | Primary on a colored background |
37+
| `secondary` | `#10162F` | `#ffffff` | Secondary CTA, ghost buttons |
38+
| `secondary-hover` | navy-800 86% | white 80% | Hover on secondary interactive |
39+
| `interface` | `#3A10E5` | `#FFD300` | Checkboxes, toggles, sliders |
40+
| `interface-hover` | `#5533FF` | `#CCA900` | Hover on interface elements |
41+
| `danger` | `#E91C11` | `#E85D7F` | Destructive actions, error states |
42+
| `danger-hover` | `#BE1809` | `#DC5879` | Hover on danger interactive |
43+
44+
### Border
45+
46+
| Token | Light | Dark | Use for |
47+
|---|---|---|---|
48+
| `border-primary` | `#10162F` | `#ffffff` | Strong borders, dividers |
49+
| `border-secondary` | navy-800 75% | white 65% | Medium-weight borders |
50+
| `border-tertiary` | navy-800 28% | white 20% | Subtle borders, separators |
51+
| `border-disabled` | navy-800 63% | white 50% | Disabled input borders |
52+
53+
### Feedback
54+
55+
| Token | Light | Dark | Use for |
56+
|---|---|---|---|
57+
| `feedback-error` | `#BE1809` | `#E85D7F` | Error messages, validation |
58+
| `feedback-success` | `#008A27` | `#AEE938` | Success messages |
59+
| `feedback-warning` | `#FFD300` | `#FFFAE5` | Warning messages |
60+
61+
## Raw palette
62+
63+
Use raw tokens only when color must be **fixed** (not adaptive).
64+
65+
| Name | Weights | Key values |
66+
|---|---|---|
67+
| `navy` | 100–900 | 800 = `#10162F`, 900 = `#0A0D1C` |
68+
| `hyper` | 400, 500 | 500 = `#3A10E5`, 400 = `#5533FF` |
69+
| `yellow` | 0, 400, 500, 900 | 500 = `#FFD300` |
70+
| `red` | 0, 300, 400, 500, 600, 900 | 500 = `#E91C11` |
71+
| `green` | 0, 100, 400, 700, 900 | 700 = `#008A27` |
72+
| `blue` | 0, 100, 300, 400, 500, 800 | 500 = `#1557FF` |
73+
| `beige` || `#FFF0E5` |
74+
| `pink` | 0, 400 | 400 = `#F966FF` |
75+
| `orange` | 100, 500 | 500 = `#FF8C00` |
76+
77+
Named shorthand aliases: `beige`, `blue`, `green`, `hyper`, `navy`, `orange`, `pink`, `red`, `yellow`, `black`, `white`
78+
79+
## Decision guide
80+
81+
```
82+
Coloring UI text or backgrounds?
83+
└─ Needs to adapt to light/dark or theme? → use semantic alias (text, background, primary, …)
84+
└─ Must be fixed regardless of mode? → use raw token (navy-800, yellow-500, …)
85+
└─ Setting a section background with content inside? → use <Background bg="…"> (see modes.md)
86+
```
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Color Modes
2+
3+
Gamut uses **semantic color aliases** so components adapt to light/dark mode without configuration. See [color.md](color.md) for the full alias reference.
4+
5+
## `<ColorMode>`
6+
7+
Wraps a subtree in an explicit color mode. Nest to create scoped mode regions.
8+
9+
```tsx
10+
import { ColorMode } from '@codecademy/gamut-styles';
11+
12+
<ColorMode mode="light">{children}</ColorMode> // force light
13+
<ColorMode mode="dark">{children}</ColorMode> // force dark
14+
<ColorMode mode="system">{children}</ColorMode> // follows OS preference
15+
```
16+
17+
**Props**: `mode="light" | "dark" | "system"`
18+
19+
## `<Background>`
20+
21+
Use `<Background>` — not a raw `bg` prop — whenever setting a colored background on a section that contains text or interactive elements. It automatically switches the color mode inside to maintain accessible contrast.
22+
23+
```tsx
24+
import { Background } from '@codecademy/gamut-styles';
25+
26+
<Background bg="hyper">{children}</Background>
27+
```
28+
29+
Nesting is supported — each `<Background>` creates its own accessible color context.
30+
31+
## Hooks
32+
33+
| Hook | Returns | Use |
34+
|---|---|---|
35+
| `useCurrentMode()` | `"light" \| "dark"` | Read active mode in JS |
36+
| `useColorMode()` | `[modeKey, modeColors, allModes]` | Access all mode data |
37+
| `usePrefersDarkMode()` | `boolean` | Read OS dark preference only |
38+
39+
Import from `@codecademy/gamut-styles`.
40+
41+
## Common mistakes
42+
43+
- Do not use raw color tokens (`navy-400`, `white`) for text/backgrounds that must be accessible across modes — use semantic aliases.
44+
- Do not use a raw `bg` prop on colored sections containing content — use `<Background>` so contrast is guaranteed.
45+
- Do not manually toggle modes from `usePrefersDarkMode()` — use `<ColorMode mode="system">` instead.
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Spacing, Border Radius & Layout
2+
3+
## Spacing scale
4+
5+
All spacing is multiples of 4px on an 8px grid.
6+
7+
| Token | Value |
8+
|---|---|
9+
| `0` | 0 |
10+
| `4` | 4px |
11+
| `8` | 8px |
12+
| `12` | 12px |
13+
| `16` | 16px |
14+
| `24` | 24px |
15+
| `32` | 32px |
16+
| `40` | 40px |
17+
| `48` | 48px |
18+
| `64` | 64px |
19+
| `96` | 96px |
20+
21+
Use multiples of 8px for block-element spacing. Use 4px only for inline or typographic relationships.
22+
23+
## Border radius
24+
25+
| Token | Value | Use |
26+
|---|---|---|
27+
| `none` | 0px | Square / non-interactive elements |
28+
| `sm` | 2px | Subtle rounding, tags |
29+
| `md` | 4px | Buttons, inputs, interactive cards |
30+
| `lg` | 8px | Cards, panels |
31+
| `xl` | 16px | Large cards, modals |
32+
| `full` | 999px | Pills, avatars, circular elements |
33+
34+
## Breakpoints
35+
36+
Mobile-first. Styles apply from the named breakpoint and up.
37+
38+
| Token | Min-width | Max content width |
39+
|---|---|---|
40+
| _(base)_ | 0 | 288px |
41+
| `xs` | 480px | 448px |
42+
| `sm` | 768px | 704px |
43+
| `md` | 1024px | 896px |
44+
| `lg` | 1200px | 1072px |
45+
| `xl` | 1440px | 1248px |
46+
47+
Container query variants (`c_xs``c_xl`) mirror these values but trigger on component width.
48+
49+
## Grid
50+
51+
12-column grid at all breakpoints.
52+
53+
| Property | xl/lg | md | sm/xs | base |
54+
|---|---|---|---|---|
55+
| Horizontal margins | 64px | 48px | 32px | 16px |
56+
| Column gutters | 32px | 24px | 16px | 8px |
57+
| Row gaps | 32px | 24px | 16px | 8px |
58+
59+
Minimum touch target on mobile: **44×44px**.
60+
61+
## Responsive rules
62+
63+
- Begin design work at 1440px (XL), then adapt down.
64+
- Multi-column layouts collapse to fewer columns — do not stretch or squish.
65+
- Catalog cards and non-lockup elements should align on one axis (usually left), not fill column widths.
66+
- Avoid dense or small components at the base (mobile) breakpoint.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Typography
2+
3+
## Typefaces
4+
5+
| Token | Codecademy font | Non-Codecademy | Use for |
6+
|---|---|---|---|
7+
| `base` | Apercu Pro | Hanken Grotesk | All UI text, headlines, body copy |
8+
| `accent` | Suisse Intl Mono | Hanken Grotesk | Code, captions, labels, technical context |
9+
| `monospace` | Monaco / Menlo / Consolas | Monaco / Menlo / Consolas | Code editor contexts |
10+
11+
Percipio overrides all families to Roboto. Apercu is licensed for codecademy.com only.
12+
13+
## Font size scale
14+
15+
| Token | Size | Common use |
16+
|---|---|---|
17+
| `64` | 64px | Hero / display |
18+
| `44` | 44px | Page titles |
19+
| `34` | 34px | Section titles |
20+
| `26` | 26px | Sub-section titles |
21+
| `22` | 22px | Card titles, large UI labels |
22+
| `20` | 20px | Secondary titles |
23+
| `18` | 18px | Large body, intro text |
24+
| `16` | 16px | Default body text |
25+
| `14` | 14px | Small body, captions, labels |
26+
27+
## Font weight
28+
29+
| Token | Value | Use |
30+
|---|---|---|
31+
| `base` | 400 | Body text, UI labels |
32+
| `title` | 700 | Headlines, CTAs, buttons |
33+
34+
## Line height
35+
36+
| Token | Value | Use |
37+
|---|---|---|
38+
| `base` | 1.5 | Body text |
39+
| `spacedTitle` | 1.3 | Sub-headlines, medium titles |
40+
| `title` | 1.2 | Large headlines |
41+
42+
Target 45–85 characters per line (66 ideal for web body text).
43+
44+
## Rules
45+
46+
- Use `title` weight (700) for headlines, CTAs, and buttons.
47+
- Use Apercu Italic to emphasize within a Regular paragraph — not Bold.
48+
- Use `accent` (Suisse) sparingly: code snippets, captions, enumerated items. Suisse reads ~10–15% large — size it down relative to Apercu equivalents.
49+
- Left-align text by default. Center-align only for short marketing headlines. Never right-align.
50+
- Do not adjust letter-spacing.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Gamut Design System
2+
3+
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+
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.
6+
7+
**Core principles**:
8+
- Components are color mode–aware by default — never hardcode hex values for adaptive UI
9+
- All components work across all themes without modification
10+
- Mobile-first, 12-column grid
11+
- Semantic color tokens guarantee WCAG AA contrast automatically
12+
13+
## Themes
14+
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 ||
22+
23+
Set the theme at the app root via `<GamutProvider theme={...}>`.
24+
25+
## Reading order
26+
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 |

0 commit comments

Comments
 (0)