Files
brand/scripts/gen-variables.mjs
T
zeekayandHanzo Dev 04c919c4d9 tokens: re-emit @hanzo/tokens as styles/variables.css, drop the bespoke palette
variables.css was a hand-authored palette that had drifted from the system — a
purple accent, a Zen type stack, blue/amber status hues, its own surface blacks.
It is now @hanzo/tokens' generated bundle, re-emitted by scripts/gen-variables.mjs,
so the Go dashboards that vendor this sheet (ci/cd/git) share the one monochrome
palette. A short compatibility block aliases the legacy names those consumers
still reference (--hanzo-accent -> the ink, --error/--success -> the state hues,
--border-hairline -> --border, ...) onto the generated tokens, so nothing that
links this sheet stops resolving. Edit @hanzo/tokens src/theme.ts and run `pnpm gen`.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-01 12:19:28 -07:00

71 lines
3.2 KiB
JavaScript

// gen-variables.mjs — styles/variables.css is @hanzo/tokens, re-emitted.
//
// @hanzo/brand does not author its own palette any more. The values come from
// @hanzo/tokens (src/theme.ts), the one place the estate's colours, radii, type
// and spacing live, and this script republishes that generated bundle as a plain
// custom-property sheet the Go surfaces link or embed (ci/cd/git dashboards). One
// edit in @hanzo/tokens propagates to React (the TS), to @hanzo/design (its CSS),
// and here — nothing retyped, nothing to drift.
//
// A short compatibility block follows the bundle: the legacy @hanzo/brand names a
// few consumers still reference, each aliased onto a generated token so it keeps
// resolving while the value converges on the system. New code uses the token
// names from the bundle; the aliases are a bridge, not a second palette.
import { readFileSync, writeFileSync, existsSync } from 'node:fs'
import { fileURLToPath } from 'node:url'
import { createRequire } from 'node:module'
import { dirname, join } from 'node:path'
const root = join(dirname(fileURLToPath(import.meta.url)), '..')
const require = createRequire(import.meta.url)
function resolveBundle() {
const candidates = []
try { candidates.push(require.resolve('@hanzo/tokens/css')) } catch {}
candidates.push(join(root, '..', 'ui', 'pkgs', 'tokens', 'dist', 'tokens.css'))
for (const c of candidates) if (c && existsSync(c)) return c
throw new Error('gen-variables: @hanzo/tokens/css (dist/tokens.css) not found — build @hanzo/tokens first')
}
const src = resolveBundle()
const bundle = readFileSync(src, 'utf8')
// The bundle's own header names its generator; drop it, this file has its own.
.replace(/^\/\*[\s\S]*?\*\/\s*/, '')
.trim()
const header = `/**
* @hanzo/brand — CSS custom properties.
*
* AUTO-GENERATED by scripts/gen-variables.mjs from @hanzo/tokens — DO NOT EDIT.
* Edit the token in @hanzo/tokens src/theme.ts and re-run \`pnpm gen\` here (which
* regenerates from the freshly built @hanzo/tokens bundle).
*
* Hanzo is monochrome — one hue through an opacity ladder, dark by default.
* Usage: @import '@hanzo/brand/styles/variables.css';
* or: <link rel="stylesheet" href="https://unpkg.com/@hanzo/brand/styles/variables.css">
*/`
const compat = `
/* ——— compatibility aliases ———
Legacy @hanzo/brand names, each aliased onto a generated token so existing
consumers keep resolving while the value converges on the one system. Prefer
the token names above in new code. */
:root{
--border-hairline:var(--border);
--border-hairline-strong:var(--border-strong);
--radius-card:var(--radius);
--error:var(--state-error);
--success:var(--state-success);
--warning:#f59e0b; /* build-status amber, sibling of --chrome-dot-yellow */
--warning-light:#fcd34d;
--text-muted:var(--text-tertiary);
/* The one accent is the ink itself — monochrome, no purple. */
--hanzo-accent:var(--foreground);
--hanzo-accent-muted:var(--muted-foreground);
--hanzo-accent-soft:var(--white-10);
}
`
writeFileSync(join(root, 'styles', 'variables.css'), `${header}\n\n${bundle}\n${compat}`)
console.log(`gen-variables: wrote styles/variables.css from ${src}`)