@codecademy/gamut

68.7.068.7.1-alpha.1ea5a8.0
agent-tools/DESIGN.Codecademy.md
~agent-tools/DESIGN.Codecademy.mdModified
+90βˆ’120
Index: package/agent-tools/DESIGN.Codecademy.md
===================================================================
--- package/agent-tools/DESIGN.Codecademy.md
+++ package/agent-tools/DESIGN.Codecademy.md
@@ -7,14 +7,15 @@
   hyper-500: '#3A10E5'
   hyper-400: '#5533FF'
   navy-900: '#0A0D1C'
   navy-800: '#10162F'
-  navy-700: '#31374C'
-  navy-600: '#4C5063'
-  navy-500: '#686C7C'
-  navy-300: '#BCBEC5'
-  navy-200: '#E2E3E6'
-  navy-100: '#F5F6F7'
+  navy-700: 'rgba(16, 22, 47, 0.86)'
+  navy-600: 'rgba(16, 22, 47, 0.75)'
+  navy-500: 'rgba(16, 22, 47, 0.63)'
+  navy-400: 'rgba(16, 22, 47, 0.47)'
+  navy-300: 'rgba(16, 22, 47, 0.28)'
+  navy-200: 'rgba(16, 22, 47, 0.12)'
+  navy-100: 'rgba(16, 22, 47, 0.04)'
   yellow-500: '#FFD300'
   yellow-400: '#CCA900'
   yellow-0: '#FFFAE5'
   yellow-900: '#211B00'
@@ -76,10 +77,8 @@
     fontFamily: '"Apercu", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif'
     fontSize: '2.125rem'
     fontWeight: '700'
     lineHeight: '1.2'
-  hankenGrotesk:
-    fontFamily: '"Hanken Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif'
   monospace:
     fontFamily: 'Monaco, Menlo, "Ubuntu Mono", "Droid Sans Mono", Consolas, monospace'
 rounded:
   none: '0px'
@@ -180,8 +179,10 @@
 
 **Figma file**: https://www.figma.com/design/ReGfRNillGABAj5SlITalN/πŸ“-Gamut
 **Storybook**: https://gamut.codecademy.com
 
+> **Other Gamut themes:** This document covers **Codecademy** (Core, Admin, Platform) only. For Percipio or LX Studio, install that product's `DESIGN.md` instead: `gamut plugin install cursor --theme percipio` or `--theme lxstudio` (see `DESIGN.Percipio.md` / `DESIGN.LXStudio.md` in agent-tools).
+
 ---
 
 ## Visual Theme & Atmosphere
 
@@ -191,114 +192,85 @@
 
 **Design philosophy**:
 
 - Components are color mode–aware by default β€” never hardcode hex values for adaptive UI
-- Every component works across all themes without modification
+- Every component works across Core, Admin, and Platform without modification
 - Mobile-first responsive design built on a 12-column grid
 - Accessibility is guaranteed by design: semantic color tokens meet contrast requirements per mode automatically
 
 ---
 
 ## Themes
 
-Codecademy products use one of four Gamut themes, all sharing the same core visual identity. Token aliases resolve to the right values per theme automatically β€” components require no modification.
+Codecademy products use **Core**, **Admin**, or **Platform** β€” the same visual identity with theme-specific palette additions on Platform. Token aliases resolve per theme automatically; components require no modification.
 
-| Theme         | Use case                        | Base font      | Dark mode      |
-| ------------- | ------------------------------- | -------------- | -------------- |
-| **Core**      | Codecademy (default)            | Apercu         | βœ“ light + dark |
-| **Admin**     | Codecademy admin tools          | Apercu         | βœ“ light + dark |
-| **Platform**  | Codecademy learning environment | Apercu         | βœ“ light + dark |
-| **LX Studio** | LX Studio application           | Hanken Grotesk | light only     |
+| Theme        | Use case                        | Base font | Dark mode      |
+| ------------ | ------------------------------- | --------- | -------------- |
+| **Core**     | Codecademy (default)            | Apercu    | βœ“ light + dark |
+| **Admin**    | Codecademy admin tools          | Apercu    | βœ“ light + dark |
+| **Platform** | Codecademy learning environment | Apercu    | βœ“ light + dark |
 
-The active theme is set at the app root via `<GamutProvider>`. When designing, know which theme your screen targets β€” it affects primary colors, font families, and available color weights.
+Set the active theme at the app root via `<GamutProvider theme={coreTheme | adminTheme | platformTheme}>`.
 
-**Font licensing**: Apercu is licensed for codecademy.com only. LX Studio uses Hanken Grotesk.
+**Font licensing:** Apercu is licensed for codecademy.com only.
 
-For Percipio projects, use `DESIGN.Percipio.md` from the same package instead.
-
-### LX Studio theme overrides
-
-LX Studio extends Core with these differences:
-
-**Font**: All families β†’ `"Hanken Grotesk"` (no Apercu, no Suisse).
-
-**Border radii** (all values shift up one step):
-
-| Token | Core | LX Studio |
-| ----- | ---- | --------- |
-| `sm`  | 2px  | 4px       |
-| `md`  | 4px  | 8px       |
-| `lg`  | 8px  | 12px      |
-
-**Semantic color overrides (light mode)**:
-
-| Token                | Core value          | LX Studio value                 |
-| -------------------- | ------------------- | ------------------------------- |
-| `primary`            | hyper-500 `#3A10E5` | `#5628FE` (lxStudioPurple)      |
-| `primary-hover`      | hyper-400 `#5533FF` | `#7955FC` (lxStudioPurpleHover) |
-| `feedback-success`   | green-700 `#008A27` | `#06844F` (lxStudioSuccess)     |
-| `background-primary` | beige `#FFF0E5`     | `#FAFBFC` (lxStudioBgPrimary)   |
-| `shadow-primary`     | navy-800            | navy-200                        |
-| `border-primary`     | navy-800            | navy-400                        |
-| `border-disabled`    | navy-500            | navy-300                        |
-
 ---
 
 ## Semantic Color Aliases
 
 Use these token names when specifying colors in designs. They resolve to the correct raw value for the active theme and color mode automatically. **Never hardcode hex values** for anything that needs to adapt across modes.
 
 ### Text
 
-| Token            | Light                      | Dark            | Use for                     |
-| ---------------- | -------------------------- | --------------- | --------------------------- |
-| `text`           | navy-800 `#10162F` at 100% | white `#ffffff` | Default body and UI text    |
-| `text-accent`    | navy-900 `#0A0D1C`         | beige `#FFF0E5` | Stronger emphasis text      |
-| `text-secondary` | navy-800 at 75%            | white at 65%    | Supporting / secondary copy |
-| `text-disabled`  | navy-800 at 63%            | white at 50%    | Disabled state labels       |
+| Token            | Light           | Dark         | Use for                     |
+| ---------------- | --------------- | ------------ | --------------------------- |
+| `text`           | `navy-800`      | `white`      | Default body and UI text    |
+| `text-accent`    | `navy-900`      | `beige`      | Stronger emphasis text      |
+| `text-secondary` | navy-800 at 75% | white at 65% | Supporting / secondary copy |
+| `text-disabled`  | navy-800 at 63% | white at 50% | Disabled state labels       |
 
 ### Background
 
-| Token                 | Light              | Dark                 | Use for                           |
-| --------------------- | ------------------ | -------------------- | --------------------------------- |
-| `background`          | white `#ffffff`    | navy-800 `#10162F`   | Default page/component background |
-| `background-primary`  | beige `#FFF0E5`    | navy-900 `#0A0D1C`   | Slightly elevated surfaces        |
-| `background-contrast` | white              | black `#000000`      | Maximum contrast surface          |
-| `background-selected` | navy-800 at 4%     | white at 4%          | Selected row / item               |
-| `background-hover`    | navy-800 at 12%    | white at 9%          | Hover state overlay               |
-| `background-disabled` | navy-800 at 12%    | white at 9%          | Disabled surface                  |
-| `background-success`  | green-0 `#F5FFE3`  | green-900 `#151C07`  | Success state container           |
-| `background-warning`  | yellow-0 `#FFFAE5` | yellow-900 `#211B00` | Warning state container           |
-| `background-error`    | red-0 `#FBF1F0`    | red-900 `#280503`    | Error state container             |
+| Token                 | Light           | Dark         | Use for                           |
+| --------------------- | --------------- | ------------ | --------------------------------- |
+| `background`          | `white`         | `navy-800`   | Default page/component background |
+| `background-primary`  | `beige`         | `navy-900`   | Slightly elevated surfaces        |
+| `background-contrast` | `white`         | `black`      | Maximum contrast surface          |
+| `background-selected` | navy-800 at 4%  | white at 4%  | Selected row / item               |
+| `background-hover`    | navy-800 at 12% | white at 9%  | Hover state overlay               |
+| `background-disabled` | navy-800 at 12% | white at 9%  | Disabled surface                  |
+| `background-success`  | `green-0`       | `green-900`  | Success state container           |
+| `background-warning`  | `yellow-0`      | `yellow-900` | Warning state container           |
+| `background-error`    | `red-0`         | `red-900`    | Error state container             |
 
 ### Interactive
 
-| Token             | Light                | Dark                 | Use for                              |
-| ----------------- | -------------------- | -------------------- | ------------------------------------ |
-| `primary`         | hyper-500 `#3A10E5`  | yellow-500 `#FFD300` | Primary CTA, links, focus rings      |
-| `primary-hover`   | hyper-400 `#5533FF`  | yellow-400 `#CCA900` | Hover state of primary interactive   |
-| `primary-inverse` | yellow-500 `#FFD300` | hyper-500 `#3A10E5`  | Primary on a colored background      |
-| `secondary`       | navy-800 `#10162F`   | white `#ffffff`      | Secondary CTA, ghost buttons         |
-| `secondary-hover` | navy-800 at 86%      | white at 80%         | Hover state of secondary interactive |
-| `danger`          | red-500 `#E91C11`    | red-300 `#E85D7F`    | Destructive actions, error states    |
-| `danger-hover`    | red-600 `#BE1809`    | red-400 `#DC5879`    | Hover on danger interactive          |
+| Token             | Light           | Dark         | Use for                              |
+| ----------------- | --------------- | ------------ | ------------------------------------ |
+| `primary`         | `hyper-500`     | `yellow-500` | Primary CTA, links, focus rings      |
+| `primary-hover`   | `hyper-400`     | `yellow-400` | Hover state of primary interactive   |
+| `primary-inverse` | `yellow-500`    | `hyper-500`  | Primary on a colored background      |
+| `secondary`       | `navy-800`      | `white`      | Secondary CTA, ghost buttons         |
+| `secondary-hover` | navy-800 at 86% | white at 80% | Hover state of secondary interactive |
+| `danger`          | `red-500`       | `red-300`    | Destructive actions, error states    |
+| `danger-hover`    | `red-600`       | `red-400`    | Hover on danger interactive          |
 
 ### Border
 
-| Token              | Light              | Dark            | Use for                    |
-| ------------------ | ------------------ | --------------- | -------------------------- |
-| `border-primary`   | navy-800 `#10162F` | white `#ffffff` | Strong borders, dividers   |
-| `border-secondary` | navy-800 at 75%    | white at 65%    | Medium-weight borders      |
-| `border-tertiary`  | navy-800 at 28%    | white at 20%    | Subtle borders, separators |
-| `border-disabled`  | navy-800 at 63%    | white at 50%    | Disabled input borders     |
+| Token              | Light           | Dark         | Use for                    |
+| ------------------ | --------------- | ------------ | -------------------------- |
+| `border-primary`   | `navy-800`      | `white`      | Strong borders, dividers   |
+| `border-secondary` | navy-800 at 75% | white at 65% | Medium-weight borders      |
+| `border-tertiary`  | navy-800 at 28% | white at 20% | Subtle borders, separators |
+| `border-disabled`  | navy-800 at 63% | white at 50% | Disabled input borders     |
 
 ### Feedback
 
-| Token              | Light               | Dark                | Use for                          |
-| ------------------ | ------------------- | ------------------- | -------------------------------- |
-| `feedback-error`   | red-600 `#BE1809`   | red-300 `#E85D7F`   | Error messages, validation       |
-| `feedback-success` | green-700 `#008A27` | green-400 `#AEE938` | Success messages, confirmations  |
-| `feedback-warning` | yellow `#FFD300`    | yellow-0 `#FFFAE5`  | Warning messages, caution states |
+| Token              | Light       | Dark        | Use for                          |
+| ------------------ | ----------- | ----------- | -------------------------------- |
+| `feedback-error`   | `red-600`   | `red-300`   | Error messages, validation       |
+| `feedback-success` | `green-700` | `green-400` | Success messages, confirmations  |
+| `feedback-warning` | `yellow`    | `yellow-0`  | Warning messages, caution states |
 
 ### Shadow
 
 | Token              | Light           | Dark         |
@@ -313,49 +285,45 @@
 All colors available as static tokens regardless of color mode. Use these only when a color should be **fixed** and not adapt to dark mode.
 
 ### Core Palette
 
-| Name            | Weights available            | Notes                                                                             |
-| --------------- | ---------------------------- | --------------------------------------------------------------------------------- |
-| `navy`          | 100–900                      | 100–700 are rgba transparencies of `#10162F`; 800 = `#10162F`; 900 = `#0A0D1C`    |
-| `white`         | 100–700                      | rgba transparencies of `#ffffff` (no solid white weight β€” use `white` for `#fff`) |
-| `blue`          | 0, 100, 300, 400, 500, 800   | 500 = `#1557FF`                                                                   |
-| `hyper`         | 400, 500                     | 500 = `#3A10E5` (purple-blue), 400 = `#5533FF`                                    |
-| `green`         | 0, 100, 400, 700, 900        | 700 = `#008A27`                                                                   |
-| `yellow`        | 0, 400, 500, 900             | 500 = `#FFD300`                                                                   |
-| `red`           | 0, 300, 400, 500, 600, 900   | 500 = `#E91C11`                                                                   |
-| `gray`          | 100, 200, 300, 600, 800, 900 |                                                                                   |
-| `pink`          | 0, 400                       | 400 = `#F966FF`                                                                   |
-| `orange`        | 100, 500                     | 500 = `#FF8C00`                                                                   |
-| `beige`         | 100 (alias: `beige`)         | `#FFF0E5`                                                                         |
-| `black`         | β€”                            | `#000000`                                                                         |
-| `white` (solid) | β€”                            | `#ffffff`                                                                         |
+| Name            | Weights available            | Notes                                                                      |
+| --------------- | ---------------------------- | -------------------------------------------------------------------------- |
+| `navy`          | 100–900                      | 100–700 are rgba transparencies of `navy-800`; 800 and 900 are solid       |
+| `white`         | 100–700                      | rgba transparencies of `white` (no solid white weight β€” use `white` token) |
+| `blue`          | 0, 100, 300, 400, 500, 800   | named alias `blue` maps to `blue-500`                                      |
+| `hyper`         | 400, 500                     | named alias `hyper` maps to `hyper-500`                                    |
+| `green`         | 0, 100, 400, 700, 900        | named alias `green` maps to `green-700`                                    |
+| `yellow`        | 0, 400, 500, 900             | named alias `yellow` maps to `yellow-500`                                  |
+| `red`           | 0, 300, 400, 500, 600, 900   | named alias `red` maps to `red-500`                                        |
+| `gray`          | 100, 200, 300, 600, 800, 900 |                                                                            |
+| `pink`          | 0, 400                       | named alias `pink` maps to `pink-400`                                      |
+| `orange`        | 100, 500                     | named alias `orange` maps to `orange-500`                                  |
+| `beige`         | 100 (alias: `beige`)         | solid `beige` token                                                        |
+| `black`         | β€”                            | `black` token                                                              |
+| `white` (solid) | β€”                            | `white` token                                                              |
 
 **Named aliases** (shorthand for common weights):
 `beige`, `blue`, `green`, `hyper`, `lightBlue`, `lightGreen`, `navy`, `orange`, `paleBlue`, `paleGreen`, `palePink`, `paleRed`, `paleYellow`, `pink`, `red`, `yellow`, `black`, `white`
 
 ### Platform-only additions
 
-`lightBeige` (`#FFFBF8`), `gold` (`#8A7300`), `teal` (`#006D82`), `purple` (`#B3CCFF`)
+`lightBeige`, `gold`, `teal`, `purple` (Platform theme palette)
 
-### LX Studio additions
-
-`lxStudioPurple` (`#5628FE`), `lxStudioPurpleHover` (`#7955FC`), `lxStudioSuccess` (`#06844F`)
-
 ---
 
 ## Typography
 
 ### Typefaces
 
-| Token       | Core / Admin / Platform                                  | LX Studio                                             | Use for                                          |
-| ----------- | -------------------------------------------------------- | ----------------------------------------------------- | ------------------------------------------------ |
-| `base`      | Apercu Pro (CSS: `Apercu`)                               | Hanken Grotesk                                        | All default UI text, headlines, body copy        |
-| `accent`    | Suisse Intl Mono (CSS: `Suisse`); falls back to `Apercu` | Hanken Grotesk                                        | Code, captions, labels, lists, technical context |
-| `monospace` | Monaco, Menlo, Ubuntu Mono, Droid Sans Mono, Consolas    | Monaco, Menlo, Ubuntu Mono, Droid Sans Mono, Consolas | Code editor contexts                             |
-| `system`    | System UI fonts                                          | System UI fonts                                       | Performance-critical surfaces                    |
+| Token       | Font stack                                               | Use for                                          |
+| ----------- | -------------------------------------------------------- | ------------------------------------------------ |
+| `base`      | Apercu Pro (CSS: `Apercu`)                               | All default UI text, headlines, body copy        |
+| `accent`    | Suisse Intl Mono (CSS: `Suisse`); falls back to `Apercu` | Code, captions, labels, lists, technical context |
+| `monospace` | Monaco, Menlo, Ubuntu Mono, Droid Sans Mono, Consolas    | Code editor contexts                             |
+| `system`    | System UI fonts                                          | Performance-critical surfaces                    |
 
-**Apercu is licensed for codecademy.com only.** LX Studio uses Hanken Grotesk for both `base` and `accent`.
+**Apercu is licensed for codecademy.com only.**
 
 ### Rules
 
 - **Apercu Bold** for headlines, sub-headlines, CTAs, and buttons.
@@ -453,19 +421,21 @@
 ---
 
 ## Border Radius Scale
 
-| Token  | Value | Use                                        |
-| ------ | ----- | ------------------------------------------ |
-| `none` | 0px   | Square / non-interactive elements          |
-| `sm`   | 2px   | Subtle rounding, tags                      |
-| `md`   | 4px   | Default buttons, inputs, interactive cards |
-| `lg`   | 8px   | Cards, panels                              |
-| `xl`   | 16px  | Large cards, modals                        |
-| `full` | 999px | Pills, avatars, circular elements          |
+| Token  | Value | Use                      |
+| ------ | ----- | ------------------------ |
+| `none` | 0px   | Non-interactive elements |
+| `sm`   | 2px   | Overlays                 |
+| `md`   | 4px   | Interactive elements     |
+| `lg`   | 8px   | Non-interactive elements |
+| `xl`   | 16px  | Non-interactive elements |
+| `full` | 999px | Toggles, badges          |
 
 ---
 
+---
+
 ## Responsive Behavior
 
 Mobile-first. Apply styles from the named breakpoint and up.
 
@@ -602,10 +572,10 @@
 Quick color/token reference for generating or specifying UI:
 
 | Scenario               | Tokens                                                                                                |
 | ---------------------- | ----------------------------------------------------------------------------------------------------- |
-| Primary button (light) | `bg: primary (#3A10E5)`, `color: white`, `hover: primary-hover (#5533FF)`                             |
-| Primary button (dark)  | `bg: primary (#FFD300)`, `color: navy-800`, `hover: primary-hover (#CCA900)`                          |
+| Primary button (light) | `bg: primary`, `color: white`, `hover: primary-hover`                                                 |
+| Primary button (dark)  | `bg: primary`, `color: text`, `hover: primary-hover`                                                  |
 | Body text              | `color: text`, `font: base (Apercu Pro)`, `size: 16px`, `weight: 400`, `lineHeight: base (1.5)`       |
 | Headline               | `color: text-accent`, `font: base`, `size: 34–64px`, `weight: title (700)`, `lineHeight: title (1.2)` |
 | Caption / label        | `color: text-secondary`, `font: accent (Suisse Int'l Mono)`, `size: 14px`                             |
 | Card default           | `bg: background`, `borderRadius: none` β€” add `isInteractive` for hover shadow + `borderRadius: md`    |