Files
agency/.pnpm-store/v3/files/b0/7bccd631f245def95b6b4a43b89d70ae3b1318d3468729107606c79394aa2e14fb79c33f000569fb1ca1840f0ef113c8cf0f272ff43f80db176d9f6bea50f7
hanzo-agent 5af6960b87 run project
Run: sess_f37640604ae254cb4d11dc6217f7b721
2026-09-30 00:04:56 +00:00

63 lines
2.5 KiB
Plaintext

"use strict";
// A brand's declared theme, projected onto the semantic tokens.
//
// A brand package (@luxfi/brand, @zooai/brand) carries its own light and dark
// theme in brand.json. This is the ONE place that says which semantic token each
// of those answers for — the design system owns the token contract, a brand owns
// the values, and neither holds a copy of the other.
//
// It exists because that mapping was about to be written twice: once in each
// brand package to generate a stylesheet, and once in every app that resolves its
// brand at runtime and cannot import a build-time stylesheet. Two copies of a
// mapping is how a brand comes to look like itself in one surface and not
// another.
Object.defineProperty(exports, "__esModule", { value: true });
exports.themeToTokens = themeToTokens;
exports.applyBrandTheme = applyBrandTheme;
/** theme key → the semantic tokens it answers for. */
const OWNS = {
surface1: ['--background'],
surface2: ['--card', '--popover', '--muted'],
surface3: ['--accent'],
neutral1: ['--foreground', '--card-foreground', '--popover-foreground', '--accent-foreground'],
neutral2: ['--muted-foreground'],
neutral3: [],
accent1: ['--primary'],
accent2: [],
accent3: [],
border: ['--border'],
success: ['--state-success'],
warning: ['--state-warning'],
error: ['--state-error'],
};
/**
* The tokens a brand's theme sets, as `{ '--background': '#000', … }`.
*
* Only ground, ink, accent and the edges drawn on them. The radius scale, the
* type ramp, spacing, motion and z are NOT here and must not be: they are the
* system's grammar rather than a brand's voice, and a brand that redefines them
* is a fork wearing a stylesheet.
*/
function themeToTokens(theme) {
const out = {};
for (const [key, tokens] of Object.entries(OWNS)) {
const value = theme[key];
if (!value)
continue;
for (const token of tokens)
out[token] = value;
}
// --primary carries ink on top of it, so the accent names its own contrast
// partner rather than leaving whatever the previous theme set.
if (theme.accent1 && theme.surface1)
out['--primary-foreground'] = theme.surface1;
return out;
}
/** Apply a brand's theme to a live document — for an app that resolves its brand
* at runtime and so cannot import a build-time stylesheet. */
function applyBrandTheme(theme, el) {
for (const [name, value] of Object.entries(themeToTokens(theme))) {
el.style.setProperty(name, value);
}
}