Repository navigation
Conversation
… color system - Brands: every brand shares one role mapping and supplies a palette, emitted under [data-brand]. Palette and role overrides go through the same checks. - originalCodecademy: old core rebuilt as a brand, with core's fonts, weights and elevation. - ColorMode sets data-color-mode and data-brand on generated themes instead of injecting role variables. - Background paints the outer mode's palette color for an alias bg. - BREAKING: --color-* variables are renamed to --colors-* (variance too); tokens.css rules live in @layer tokens. - migration.ts re-synced to gamut-sandbox c363244. Alert General moves to surface-brand-subtle. - Styling contract test across seven themes in both modes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ands # Conflicts: # packages/gamut-styles/src/colorSystem/__tests__/system.test.ts # packages/gamut-styles/src/themes/skillsoft.ts
… pairs primary with accent-alt Brands can move a gradient role's circles to another slot (`overrides.gradients`), keeping design's grades, sizes and positions. ColorSystem carries each brand's resolved gradients, and the emitters, the migration contrast checks and tokens.css read from it. A brand whose gradient differs from the default's gets a `--gradient-*` line under `[data-brand][data-color-mode]`, like a role override. Original Codecademy's two-color gradient takes accent-alt in place of the yellow accent, per design, so it reads blue to violet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ps pinning navy and beige Design feedback on the comparison page (2026-10-29), and design's migration map at sandbox 15c2195: - Status alerts (error, success, notice) put their status ink on the message, and a floating Alert's border takes the same ink. General, feature and subtle keep text-default. - The CTA follows the Alert's own color mode. Forcing it dark only made sense on the old saturated fills; on the tints, light-mode alerts get light-mode buttons. - The ported migration map is synced to 15c2195 (Alert message slot, Alert and floating-surface summaries). - Original Codecademy no longer pins navy-800 and beige. Pinned, they carried much more chroma than the generated surfaces beside them; the generated steps at their hues are used as is. Yellow stays exact. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Design feedback on the comparison page (2026-10-29): pinned navy-800 carries much more chroma than the generated surfaces beside it. As for Original Codecademy (#52), lxStudio uses the generated step at navy's hue. Admin and platform inherit Original Codecademy's pins, so they follow; platform's blue-0 and the near-white pages are nearly achromatic and stay. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dreamwasp
left a comment
There was a problem hiding this comment.
Fixes from design feedback on the comparison pages (2026-10-29), plus design's migration map at sandbox 15c2195. Notes on the lines below.
| const buttonColorMode = isSubtleVariant ? currentColorMode : 'dark'; | ||
|
|
||
| /* | ||
| * The tints follow the color mode, so the CTA does too: it inherits the |
There was a problem hiding this comment.
Design feedback (comparison page, 2026-10-29): now that the alert fills are mode-following tints, light-mode alerts need light-mode buttons. The CTA was forced to mode="dark" for every non-subtle variant, a holdover from the old saturated fills. It now inherits the mode the Alert's Background sets. The test checks that no forced mode's variables land on the button.
| * (design's preview at sandbox 15c2195; its shared "Floating border" slot | ||
| * still says border-default and is out of date). | ||
| */ | ||
| const alertInk = ({ ink, placement, theme }: InkProps) => { |
There was a problem hiding this comment.
Design's map at sandbox 15c2195: status alerts (error, success, notice) put their status ink on the message, not text-default, and a floating Alert's border takes the same ink. General, feature and subtle keep text-default.
Note: the map's shared "Floating border" slot still says border-default, but design's coded preview and the Alert summary both use the message ink. I followed the preview, so a floating general or feature alert's edge is text-default.
| kind: 'text', | ||
| legacy: 'auto (Background)', | ||
| role: 'text-default', | ||
| role: `text-${status}`, |
There was a problem hiding this comment.
Synced to design's sandbox at 15c2195 (commit c5190b6, "Alert: status ink on message text, floating border matches text"). This message slot plus the Alert and floating-surface summaries are the whole diff; the components section now matches the sandbox exactly. validate:tokens still passes: each status ink clears 4.5:1 on its own tint for every brand.
| overrides: { | ||
| /* Each at the grade whose fixed lightness is nearest. */ | ||
| palette: { | ||
| 'accent-300': '#FFD300', // yellow-500 |
There was a problem hiding this comment.
Design feedback (comparison page, 2026-10-29): pinned navy-800 at neutral-dark-1100 carried much more chroma than the generated sunken and raised surfaces next to it, which made block tabs and table zebra rows look off. Beige had the same problem, less strongly. Both pins are gone; the generated steps at navy's and beige's hues are used as is. Yellow stays exact. Admin and platform (#58) inherit this.
| }, | ||
| }, | ||
| gradients: { | ||
| 'surface-brand': { accent: 'accent-alt' }, |
There was a problem hiding this comment.
Feature (and general) alerts on Original Codecademy render this gradient: primary + accent-alt rather than blue to yellow. Design approved the override on the brand comparison page (2026-10-29). The components screenshot page was captured before this landed, so its feature alerts still show the yellow pair until it's retaken.
Overview
Builds on #50 so the generated system can carry the old themes: a brand supplies only a palette, every brand shares one role mapping, and manual overrides keep colors the generator wouldn't produce. Adds
originalCodecademy, old core rebuilt as a brand. Also moves mode switches to an attribute and renames the color variables to Panda's--colors-*. Draft, stacked on #50.Brands
colorSystem/brands/—BRANDSdrives the build; every brand has to pass every check or nothing is emitted.tokens.cssemits roles once and a palette-only block per brand under[data-brand].colorSystem/brand.ts,system.ts—overrides.palette(an exact hex in place of a generated step),overrides.roles(a role repointed in one mode) andoverrides.gradients(a gradient role's circles moved to another slot, keeping design's grades, sizes and positions). Rounded to whattokens.cssprints and guarded to round-trip; unknown roles or steps throw.brand.sourcesreports how far each supplied hex lands from its nearest step.brands/originalCodecademy.ts,themes/originalCodecademy.ts:themes/createBrandTheme.ts— one factory for every brand theme;skillsoftThemeuses it too.emit.ts— brand gradients are written against palette variables (color-mix(in oklab, …)), so one gradient follows every brand (pixel diff against the old literal gradients: max 1/255).Runtime
ColorMode— on generated themes, a mode switch setsdata-color-modeanddata-brandand injects no role variables. 100 nested switches, server-rendered: 7.6 → 4.2 ms, 5 KB → 46 B of injected CSS. Old themes behave as before.Background— fixes a bug that's also onmain(see fix(gamut-styles): Background paints the outer mode's color for an alias bg #51): an aliasbgthat flips the mode painted the flipped mode's color.Breaking
variancecreateTheme, gamut-styles — color variables are--colors-*, not--color-*. Matches variance's own convention for scales and its types (the mode colors were already typedvar(--colors-…)).tokens.css— all blocks inside@layer tokens, withreset, base, tokens, recipes, utilitiesdeclared up front (Panda's order). Emotion's styles stay unlayered and win.Design sync
colorSystem/migration.ts— re-synced to sandbox15c2195. Sincec363244: apendingkind for shadows, and status alerts carry their ink on the message and on a floating border.gamut/src/Alert:surface-brand-subtle.cqwradii measure the alert, not the viewport.text-<status>on the message and on a floating border. General, feature and subtle staytext-default.Tests
__tests__/stylingContract.test.tsx—css,variant,states, system props,themed,modeColorProps,_getColorValue,ColorMode,Backgroundand the mode hooks on all seven themes in both modes. Every color they write has to resolve through everyvar()to a real color.validate-tokens.ts— every check per brand, including a round-trip of each brand's roles throughtokens.css.Storybook and docs
.storybook— an "Original Codecademy (color spike)" theme option.gamut-agent-toolsskills,colorSystem/README.md, the CSS contract story —--colors-*.Known gaps
text-default, following design's coded preview. Design's map still has a shared "Floating border:border-default" slot.shadow-primary, which has no role yet (design has it as pending), so shadows renderundefinedon the new themes.PR Checklist
15c2195)Testing Instructions
yarn workspace @skillsoft/gamut-styles validate:tokens→ both brands pass every check, including thetokens.cssround-trip.yarn nx test gamut-styles(281 tests),yarn nx test variance(104), andnpx jest packages/gamut/src/Alert(16).ColorModeelement: it carriesdata-color-modeanddata-brand="originalCodecademy", and its class has no--colors-*role declarations.🤖 Generated with Claude Code