@framework-cwf/theme
v2.0.0
Published
Curated brand palette (8 baseId x 12 brandId) with derivation + legacy-hex migration helpers. The framework's single source of truth for visual identity across customer sites.
Downloads
275
Readme
@framework-cwf/theme
The framework's curated brand palette — 8 base canvases × 12 brand accents, with build-time AA-pass validation, a deterministic primary ladder anchored at the brand hex, and a one-shot helper to migrate already-published free-hex configs onto the enum pair.
The companion enums (BaseId, BrandId) live in
@framework-cwf/contracts so the schema and the runtime stay
in lockstep; this package owns the runtime values.
Installation
Published to GitHub Packages under the @framework-cwf scope. Consumers need an
.npmrc pointing the scope at the GitHub Packages registry plus an auth token:
@framework-cwf:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}pnpm add @framework-cwf/themeQuick example
import {
deriveBrandPalette,
migrateLegacyBrand,
getValidBrandsForBase,
} from "@framework-cwf/theme";
// Resolve a curated pair (either already on the config, or migrate legacy hex).
const { baseId, brandId } = migrateLegacyBrand({
primaryColor: "#4d83ff",
bgColor: "#000000",
});
// ⇒ { baseId: 'ink', brandId: 'cobalt' }
const palette = deriveBrandPalette(baseId, brandId);
// ⇒ { bg: '#000000', text: '#fafafa',
// primary50…primary700, accent, link, muted }
const allowedBrandsForInk = getValidBrandsForBase("ink");
// ⇒ filters out brands that fail white-on-primary 4.5:1Why a curated palette
Customer sites scaffolded from this framework share the same visual identity
language. The locked palette removes the failure mode where a per-site free
hex (e.g. Sniply's #4d83ff) escapes review and ships with a sub-AA contrast.
Extending the palette (adding bases/brands) is a minor bump on this package. Removing or repurposing an entry is a major bump because a customer's published config may name it.
API
| Export | Description |
| ----------------------- | -------------------------------------------------------------------------- |
| BASES, BRANDS | Locked v1 hex anchors keyed by BaseId / BrandId. |
| BASE_IDS, BRAND_IDS | Typed iteration arrays. |
| EXCLUSIONS | Pre-computed [baseId, brandId][] pairs that fail white-on-primary AA. |
| isExcluded(b, br) | Picker-side guard. |
| getValidBrandsForBase | Filtered brand list for a chosen base. |
| deriveBrandPalette | Anchors primary400 at the brand hex; derives ladder + accent/link/muted. |
| migrateLegacyBrand | Maps free hex → nearest (baseId, brandId) by OKLab ΔE. |
| contrastRatio | WCAG 2.x contrast (chroma-js). |
| passesAaBodyText | 4.5:1 helper for the build-time exclusion check. |
| passesAaUi | 3:1 helper for UI-component contrast checks at picker time. |
