@nebutra/tokens 0.1.3 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/brands/README.md +66 -0
- package/brands/cosmos/DESIGN.md +356 -0
- package/brands/cosmos/brand.json +209 -0
- package/brands/cosmos/refero-tokens.json +312 -0
- package/brands/gsap/brand.json +1 -27
- package/brands/linear/DESIGN.md +478 -0
- package/brands/linear/brand.json +2 -19
- package/brands/notion/brand.json +2 -28
- package/brands/raycast/brand.json +2 -17
- package/brands/stripe/brand.json +1 -16
- package/brands/vanta/brand.json +1 -38
- package/brands/vercel/brand.json +1 -18
- package/dist/brand-package/index.d.ts +13 -7
- package/dist/brand-package/index.js +2290 -34
- package/dist/brand-package/index.js.map +1 -1
- package/dist/brand-package/use-brand.d.ts +1 -1
- package/dist/brand-package/use-brand.js +957 -5
- package/dist/brand-package/use-brand.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2417 -22
- package/dist/index.js.map +1 -1
- package/dist/{use-brand-C8d4DPqE.d.ts → use-brand-ClmvK_lC.d.ts} +19 -3
- package/dist/values.d.ts +1192 -0
- package/dist/values.js +518 -0
- package/dist/values.js.map +1 -0
- package/package.json +16 -4
- package/recipe.css +36 -2
- package/skins/cosmos.css +239 -0
- package/skins/gsap.css +32 -20
- package/skins/linear.css +54 -17
- package/skins/notion.css +36 -25
- package/skins/raycast.css +37 -19
- package/skins/stripe.css +34 -15
- package/skins/vanta.css +34 -30
- package/skins/vercel.css +55 -19
- package/styles.css +492 -149
- package/dist/chunk-ALJTP5HL.js +0 -881
- package/dist/chunk-ALJTP5HL.js.map +0 -1
- package/dist/chunk-RGUJQOLH.js +0 -1582
- package/dist/chunk-RGUJQOLH.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/brand-package/use-brand.ts","../../src/brand-package/emit-css.ts","../../src/brand-package/hex-to-hsl.ts","../../src/brand-package/normalize.ts","../../src/brand-package/apply-brand.ts"],"sourcesContent":["\"use client\";\n\nimport { type RefObject, useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n type ApplyBrandOptions,\n applyBrandPackage,\n clearBrand,\n getActiveBrandId,\n restorePersistedBrand,\n} from \"./apply-brand\";\nimport { emitBrandCss } from \"./emit-css\";\nimport type { BrandPackage } from \"./types\";\n\nexport interface UseBrandOptions {\n /** Restore from localStorage on mount */\n autoRestore?: boolean;\n /** Persist apply/clear to localStorage */\n persist?: boolean;\n}\n\nexport interface UseBrandResult {\n brand: BrandPackage | null;\n brandId: string | null;\n apply: (brand: BrandPackage) => void;\n clear: () => void;\n restore: () => BrandPackage | null;\n}\n\n/**\n * Create Center / app-level brand state for the host document.\n */\nexport function useBrand(options: UseBrandOptions = {}): UseBrandResult {\n const { autoRestore = false, persist = true } = options;\n const [brand, setBrand] = useState<BrandPackage | null>(null);\n const [brandId, setBrandId] = useState<string | null>(null);\n\n useEffect(() => {\n if (!autoRestore) return;\n const restored = restorePersistedBrand({ persist: false });\n if (restored) {\n setBrand(restored);\n setBrandId(restored.id);\n } else {\n setBrandId(getActiveBrandId());\n }\n }, [autoRestore]);\n\n const apply = useCallback(\n (next: BrandPackage) => {\n applyBrandPackage(next, { persist });\n setBrand(next);\n setBrandId(next.id);\n },\n [persist],\n );\n\n const clear = useCallback(() => {\n clearBrand({ persist });\n setBrand(null);\n setBrandId(null);\n }, [persist]);\n\n const restore = useCallback(() => {\n const restored = restorePersistedBrand({ persist: false });\n if (restored) {\n setBrand(restored);\n setBrandId(restored.id);\n }\n return restored;\n }, []);\n\n return { brand, brandId, apply, clear, restore };\n}\n\nexport interface BrandIframePreviewOptions {\n /**\n * Stylesheets the iframe must load before the brand skin\n * (e.g. app CSS URL that already includes tokens + recipe).\n */\n baseStylesheetHrefs?: string[];\n /** Extra head HTML (fonts CDN, etc.) */\n headHtml?: string;\n /** Minimal body wrapper class */\n bodyClassName?: string;\n /** Called after brand CSS is injected into the iframe */\n onApplied?: (brand: BrandPackage | null) => void;\n}\n\nexport interface UseBrandIframePreviewResult {\n iframeRef: RefObject<HTMLIFrameElement | null>;\n brand: BrandPackage | null;\n /** Write/update brand inside the iframe document */\n apply: (brand: BrandPackage) => void;\n clear: () => void;\n /**\n * Optional: write a self-contained preview document.\n * Use when the iframe has no host app styles yet.\n */\n writePreviewDocument: (brand: BrandPackage, bodyHtml?: string) => void;\n}\n\nfunction ensureIframeDoc(iframe: HTMLIFrameElement | null): Document | null {\n if (!iframe) return null;\n try {\n return iframe.contentDocument;\n } catch {\n return null; // cross-origin\n }\n}\n\nfunction injectBaseStyles(doc: Document, hrefs: string[] | undefined): void {\n if (!hrefs?.length) return;\n for (const href of hrefs) {\n const id = `nebutra-base-${hashHref(href)}`;\n if (doc.getElementById(id)) continue;\n const link = doc.createElement(\"link\");\n link.id = id;\n link.rel = \"stylesheet\";\n link.href = href;\n doc.head.appendChild(link);\n }\n}\n\nfunction hashHref(href: string): string {\n let h = 0;\n for (let i = 0; i < href.length; i++) h = (h * 31 + href.charCodeAt(i)) | 0;\n return Math.abs(h).toString(36);\n}\n\n/**\n * Multi-tenant / Create Center iframe preview.\n * Applies Brand Packages into the iframe's document without touching the host shell.\n */\nexport function useBrandIframePreview(\n options: BrandIframePreviewOptions = {},\n): UseBrandIframePreviewResult {\n const iframeRef = useRef<HTMLIFrameElement | null>(null);\n const [brand, setBrand] = useState<BrandPackage | null>(null);\n const optsRef = useRef(options);\n optsRef.current = options;\n\n const apply = useCallback((next: BrandPackage) => {\n const doc = ensureIframeDoc(iframeRef.current);\n if (!doc?.documentElement) {\n setBrand(next);\n return;\n }\n injectBaseStyles(doc, optsRef.current.baseStylesheetHrefs);\n applyBrandPackage(next, { doc, persist: false });\n setBrand(next);\n optsRef.current.onApplied?.(next);\n }, []);\n\n const clear = useCallback(() => {\n const doc = ensureIframeDoc(iframeRef.current);\n if (doc) clearBrand({ doc, persist: false });\n setBrand(null);\n optsRef.current.onApplied?.(null);\n }, []);\n\n const writePreviewDocument = useCallback((next: BrandPackage, bodyHtml = \"\") => {\n const iframe = iframeRef.current;\n if (!iframe) return;\n const css = emitBrandCss(next);\n const links = (optsRef.current.baseStylesheetHrefs ?? [])\n .map((href) => `<link rel=\"stylesheet\" href=\"${href}\" />`)\n .join(\"\\n\");\n const html = `<!DOCTYPE html>\n<html lang=\"en\" data-brand=\"${next.id}\" class=\"${next.darkDefault ? \"dark\" : \"\"}\">\n<head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n ${links}\n ${optsRef.current.headHtml ?? \"\"}\n <style id=\"nebutra-brand-skin\">${css}</style>\n <style>\n html, body { margin: 0; min-height: 100%; }\n body {\n font-family: var(--font-sans, system-ui, sans-serif);\n background: hsl(var(--background));\n color: hsl(var(--foreground));\n }\n </style>\n</head>\n<body class=\"${optsRef.current.bodyClassName ?? \"\"} bg-background text-foreground\">\n ${bodyHtml}\n</body>\n</html>`;\n iframe.srcdoc = html;\n setBrand(next);\n optsRef.current.onApplied?.(next);\n }, []);\n\n return { iframeRef, brand, apply, clear, writePreviewDocument };\n}\n\n/** Imperative helper for non-hook call sites */\nexport function applyBrandToIframe(\n iframe: HTMLIFrameElement,\n brand: BrandPackage,\n options: ApplyBrandOptions & { baseStylesheetHrefs?: string[] } = {},\n): void {\n const doc = iframe.contentDocument;\n if (!doc) return;\n injectBaseStyles(doc, options.baseStylesheetHrefs);\n applyBrandPackage(brand, { ...options, doc, persist: false });\n}\n","/**\n * Emit carrier CSS from a normalized Brand Package.\n * Components bind: --primary (= action), --brand-mark, --elevation-*, --radius-*.\n */\n\n// The source subpath, not the built entry: this module is consumed by\n// emit-skins at build time, and depending on another package's dist made the\n// skin pipeline fail whenever turbo scheduled the two builds side by side.\nimport { withNearestRegistryFont } from \"@nebutra/fonts/registry\";\nimport { isDualModeBrand, normalizeBrandPackage } from \"./normalize\";\nimport type {\n BrandColorRoles,\n BrandFontFace,\n BrandMotion,\n BrandPackage,\n BrandRecipe,\n BrandSemanticColors,\n BrandSpacing,\n} from \"./types\";\n\n/**\n * Resolve a declared stack to something that can actually render.\n *\n * Biome's CSS formatter prefers double quotes, and `withNearestRegistryFont`\n * prepends the first family in the stack that the app self-hosts — without it a\n * bare `Inter` in a brand stack does not reach next/font's hashed face and the\n * whole chain falls through to `ui-sans-serif`.\n */\nfunction cssFontStack(stack: string): string {\n return (withNearestRegistryFont(stack) ?? stack).replace(/'/g, '\"');\n}\n\n/** The generic families that end a stack — nothing after one is ever reached. */\nconst GENERIC_FAMILIES = new Set([\n \"ui-sans-serif\",\n \"ui-serif\",\n \"ui-monospace\",\n \"system-ui\",\n \"sans-serif\",\n \"serif\",\n \"monospace\",\n \"-apple-system\",\n \"BlinkMacSystemFont\",\n]);\n\n/**\n * Keep Chinese readable in every design language.\n *\n * Inter, Geist, Söhne and Mori carry no CJK glyphs, and a generic family always\n * resolves — so `\"Inter\", ui-sans-serif, sans-serif` hands every Han character\n * to whatever the OS picks, and the careful MiSans / PingFang order that\n * the default stack spells out is lost the moment a visitor picks a language.\n *\n * The tail goes in ahead of the first generic family, which is the last point\n * at which it can still be reached.\n */\nfunction withCjkTail(stack: string): string {\n const families = stack.split(\",\").map((f) => f.trim());\n const cut = families.findIndex((f) => GENERIC_FAMILIES.has(f.replace(/\"/g, \"\")));\n if (cut === -1 || families.some((f) => f.includes(\"MiSans\"))) return stack;\n const cjk = ['var(--font-misans, \"MiSans\")', '\"PingFang SC\"'];\n return [...families.slice(0, cut), ...cjk, ...families.slice(cut)].join(\", \");\n}\n\n/**\n * Timing for one language.\n *\n * Emits both spellings the shared sheet ships — `--duration-flow` and\n * `--motion-duration-flow` — because both are already consumed and a skin that\n * set only one would leave half the surface on the default ramp, which reads as\n * a language that moves at two speeds.\n *\n * Only the keys the package declares are written. An omitted curve inherits the\n * shared ramp rather than being reset to it, so a language can adjust its\n * durations without also restating curves it does not care about.\n */\nfunction motionVars(motion: BrandMotion | undefined): string[] {\n if (!motion) return [];\n const lines: string[] = [];\n // Both rails, for the same reason the durations write both spellings: the\n // utility layer reads --motion-ease-*, hand-written CSS reads --ease-*, and a\n // skin that moved only one would animate its utilities and its stylesheets at\n // different speeds.\n const curves: Array<[keyof BrandMotion, string]> = [\n [\"easeOut\", \"ease-out\"],\n [\"easeInOut\", \"ease-in-out\"],\n [\"easeSpring\", \"ease-spring\"],\n ];\n for (const [key, name] of curves) {\n const value = motion[key];\n if (typeof value !== \"string\" || !value.trim()) continue;\n lines.push(` --${name}: ${value};`);\n lines.push(` --motion-${name}: ${value};`);\n }\n const durations: Array<[keyof BrandMotion, string]> = [\n [\"micro\", \"micro\"],\n [\"flow\", \"flow\"],\n [\"reveal\", \"reveal\"],\n [\"cinematic\", \"cinematic\"],\n ];\n for (const [key, name] of durations) {\n const value = motion[key];\n if (typeof value !== \"number\" || !Number.isFinite(value)) continue;\n lines.push(` --duration-${name}: ${value}ms;`);\n lines.push(` --motion-duration-${name}: ${value}ms;`);\n }\n return lines.length ? [``, ` /* Motion */`, ...lines] : [];\n}\n\n/**\n * Breathing room for one language.\n *\n * Writes only `--space-source-*`. Consumers read those vars directly\n * (`var(--space-source-md, …)`). We deliberately do NOT also emit\n * `--spacing-sm|md|…` into @theme: Tailwind v4 treats every --spacing-{key}\n * as a size token, so max-w-sm / max-w-2xl would resolve to the breathing\n * lengths (0.75rem…3rem) instead of the container scale (24rem…42rem).\n */\nfunction spacingVars(spacing: BrandSpacing | undefined): string[] {\n if (!spacing) return [];\n const lines: string[] = [];\n const steps: Array<[keyof BrandSpacing, string]> = [\n [\"xs\", \"xs\"],\n [\"sm\", \"sm\"],\n [\"md\", \"md\"],\n [\"lg\", \"lg\"],\n [\"xl\", \"xl\"],\n [\"2xl\", \"2xl\"],\n ];\n for (const [key, name] of steps) {\n const value = spacing[key];\n if (typeof value !== \"string\" || !value.trim()) continue;\n lines.push(` --space-source-${name}: ${value};`);\n }\n return lines.length ? [``, ` /* Spacing */`, ...lines] : [];\n}\n\nfunction recipeVars(recipe: BrandRecipe): string[] {\n const radii = recipe.radii;\n const elev = recipe.elevationTokens;\n\n const lines: string[] = [\n ` /* Shape slots */`,\n ` --btn-default-radius: ${radii.button};`,\n ` --radius-button: ${radii.button};`,\n ` --radius-buttons: ${radii.button};`,\n // A step on the size scale, not the button role.\n //\n // Aliasing it straight to `radii.button` is fine while a language's buttons\n // are modestly rounded — five of the seven are 4–8px and never noticed. It\n // breaks for the two whose buttons are pills: GSAP emitted\n // `--radius-md: 100px` and Vanta 999px, and forty-two files read that step\n // for panels and surfaces. The Combobox popover under GSAP came out as a\n // lozenge, which is what a 100px radius does to a 260px-wide panel.\n //\n // `min()` keeps every language whose button is the tighter of the two\n // exactly where it was, and stops a pill from escaping its role. A pill is\n // a control decision; it has no business setting the radius of a surface.\n ` --radius-md: min(${radii.button}, ${radii.card});`,\n ` --radius-card: ${radii.card};`,\n ` --radius-lg: ${radii.card};`,\n ` --radius-badge: ${radii.badge ?? \"9999px\"};`,\n ` --badge-default-radius: ${radii.badge ?? \"9999px\"};`,\n ` --radius-inputs: ${radii.input ?? radii.button};`,\n ` --input-radius: ${radii.input ?? radii.button};`,\n ` --radius-pill: ${radii.pill ?? \"9999px\"};`,\n ``,\n ` /* Free elevation (carrier-provided CSS shadows) */`,\n ` --elevation-card: ${elev.card};`,\n ` --elevation-control: ${elev.control ?? \"0 0 #0000\"};`,\n ` --elevation-raised: ${elev.raised ?? elev.card};`,\n // --elevation-*, not --shadow-*. The theme block maps `--shadow-md` to\n // `var(--elevation-md)` and inlines that into `.shadow-md`, so a skin that\n // set --shadow-md was writing to the alias while the utility read the\n // source. Every language's shadows were therefore byte-identical in the\n // browser — measured across all seven with getComputedStyle — while the\n // token files disagreed convincingly. Setting the source is what a brand\n // switch needs; the alias takes care of itself.\n ` --elevation-xs: ${elev.control ?? \"0 0 #0000\"};`,\n ` --elevation-sm: ${elev.card};`,\n ` --elevation-md: ${elev.raised ?? elev.card};`,\n ` --elevation-lg: ${elev.raised ?? elev.card};`,\n ` --btn-default-shadow: 0 0 #0000;`,\n ];\n\n switch (recipe.buttonDefault) {\n case \"outline\": {\n const edge = recipe.outlineBorder ?? \"hsl(var(--foreground))\";\n lines.push(\" --btn-default-bg: transparent;\");\n lines.push(\" --btn-default-fg: hsl(var(--foreground));\");\n lines.push(\" --btn-default-border-width: 1px;\");\n lines.push(\" --btn-default-border: transparent;\");\n lines.push(` --btn-default-stroke-gradient: linear-gradient(${edge}, ${edge});`);\n lines.push(\" --btn-default-hover-bg: hsl(var(--foreground) / 0.06);\");\n break;\n }\n case \"gradient-stroke\": {\n const grad =\n recipe.primaryStrokeGradient ??\n \"linear-gradient(135deg, hsl(var(--primary)), color-mix(in srgb, hsl(var(--primary)) 55%, white))\";\n lines.push(\" --btn-default-bg: transparent;\");\n lines.push(\" --btn-default-fg: hsl(var(--foreground));\");\n lines.push(\" --btn-default-border-width: 1.5px;\");\n lines.push(\" --btn-default-border: transparent;\");\n lines.push(` --btn-default-stroke-gradient: ${grad};`);\n lines.push(\" --btn-default-hover-bg: hsl(var(--primary) / 0.08);\");\n break;\n }\n default:\n lines.push(\" --btn-default-bg: hsl(var(--primary));\");\n lines.push(\" --btn-default-fg: hsl(var(--primary-foreground));\");\n lines.push(\" --btn-default-border-width: 0px;\");\n lines.push(\" --btn-default-border: transparent;\");\n // A gradient, not `transparent`. This slot is a background-image layer:\n // a colour invalidates the whole declaration and takes the solid fill\n // above it with it, leaving the button with no background. Every solid\n // skin goes through this branch, so the one wrong word reached them all.\n lines.push(\" --btn-default-stroke-gradient: linear-gradient(transparent, transparent);\");\n lines.push(\n \" --btn-default-hover-bg: color-mix(in srgb, hsl(var(--primary)) 90%, transparent);\",\n );\n break;\n }\n\n const badgeMode = recipe.badgeDefault ?? \"match-action\";\n if (badgeMode === \"outline\") {\n const edge = recipe.outlineBorder ?? \"hsl(var(--border))\";\n lines.push(\" --badge-default-bg: transparent;\");\n lines.push(\" --badge-default-fg: hsl(var(--foreground));\");\n lines.push(` --badge-default-border: ${edge};`);\n lines.push(\" --badge-default-hover-bg: hsl(var(--foreground) / 0.06);\");\n } else if (badgeMode === \"muted\") {\n lines.push(\" --badge-default-bg: hsl(var(--secondary));\");\n lines.push(\" --badge-default-fg: hsl(var(--secondary-foreground));\");\n lines.push(\" --badge-default-border: transparent;\");\n lines.push(\" --badge-default-hover-bg: color-mix(in srgb, hsl(var(--secondary)) 90%, white);\");\n } else if (badgeMode === \"brand\") {\n lines.push(\" --badge-default-bg: hsl(var(--brand-mark, var(--accent)));\");\n lines.push(\n \" --badge-default-fg: hsl(var(--brand-mark-foreground, var(--accent-foreground)));\",\n );\n lines.push(\" --badge-default-border: transparent;\");\n lines.push(\n \" --badge-default-hover-bg: color-mix(in srgb, hsl(var(--brand-mark, var(--accent))) 85%, transparent);\",\n );\n } else if (recipe.buttonDefault === \"outline\" || recipe.buttonDefault === \"gradient-stroke\") {\n const edge = recipe.outlineBorder ?? \"hsl(var(--foreground))\";\n lines.push(\" --badge-default-bg: transparent;\");\n lines.push(\" --badge-default-fg: hsl(var(--foreground));\");\n lines.push(` --badge-default-border: ${edge};`);\n lines.push(\" --badge-default-hover-bg: hsl(var(--foreground) / 0.06);\");\n } else {\n // match-action\n lines.push(\" --badge-default-bg: hsl(var(--primary));\");\n lines.push(\" --badge-default-fg: hsl(var(--primary-foreground));\");\n lines.push(\" --badge-default-border: transparent;\");\n lines.push(\n \" --badge-default-hover-bg: color-mix(in srgb, hsl(var(--primary)) 80%, transparent);\",\n );\n }\n\n if (recipe.density === \"compact\") {\n lines.push(\" --btn-default-padding-y: 0.5rem;\");\n lines.push(\" --btn-default-padding-x: 0.875rem;\");\n lines.push(\" --control-height-tiny: 1.25rem;\");\n lines.push(\" --control-height-sm: 1.75rem;\");\n lines.push(\" --control-height-md: 2rem;\");\n lines.push(\" --control-height-lg: 2.5rem;\");\n lines.push(\" --control-height-icon-sm: 1.5rem;\");\n lines.push(\" --control-height-icon-md: 1.75rem;\");\n lines.push(\" --control-height-icon-lg: 2rem;\");\n lines.push(\" --control-font-size-md: 0.8125rem;\");\n } else if (recipe.density === \"spacious\") {\n lines.push(\" --btn-default-padding-y: 0.875rem;\");\n lines.push(\" --btn-default-padding-x: 1.5rem;\");\n lines.push(\" --control-height-tiny: 1.75rem;\");\n lines.push(\" --control-height-sm: 2.25rem;\");\n lines.push(\" --control-height-md: 2.75rem;\");\n lines.push(\" --control-height-lg: 3.25rem;\");\n lines.push(\" --control-height-icon-sm: 2rem;\");\n lines.push(\" --control-height-icon-md: 2.25rem;\");\n lines.push(\" --control-height-icon-lg: 2.5rem;\");\n }\n\n return lines;\n}\n\n/**\n * A skin may only @font-face something the app's own origin can serve.\n *\n * The seven built-in languages between them declared nine faces: four pulled\n * Inter/Geist from a public CDN, which every app's `font-src 'self' data:` CSP\n * blocked, and five pointed at `/brand-assets/*.woff2` files that are not in\n * the repo and never can be — they are other companies' licensed typefaces.\n * Nine declarations, zero fonts, no error anywhere: the stylesheet parsed, the\n * rule was present, the browser simply refused the fetch.\n *\n * Same-origin is the line because it is the one the CSP already draws. A\n * customer who owns Söhne drops the file in `public/` and the face works; a\n * skin cannot quietly reintroduce a third-party runtime dependency, and there\n * is no CSP to widen for it.\n */\nfunction isServableFaceUrl(url: string): boolean {\n return url.startsWith(\"/\") && !url.startsWith(\"//\");\n}\n\nfunction emitFontFaces(faces: BrandFontFace[] | undefined): string[] {\n const servable = faces?.filter((face) => face.src.every((s) => isServableFaceUrl(s.url)));\n if (!servable?.length) return [];\n const out: string[] = [\"/* Brand font faces */\"];\n for (const face of servable) {\n const src = face.src\n .map((s) => {\n const fmt = s.format ? ` format(\"${s.format}\")` : \"\";\n return `url(\"${s.url}\")${fmt}`;\n })\n .join(\", \");\n out.push(\"@font-face {\");\n out.push(` font-family: \"${face.family}\";`);\n out.push(` src: ${src};`);\n if (face.weight != null) out.push(` font-weight: ${face.weight};`);\n if (face.style) out.push(` font-style: ${face.style};`);\n out.push(` font-display: ${face.display ?? \"swap\"};`);\n if (face.unicodeRange) out.push(` unicode-range: ${face.unicodeRange};`);\n out.push(\"}\");\n out.push(\"\");\n }\n return out;\n}\n\nexport type EmitBrandCssMode =\n /** Single-skin import / Create Center inject — also binds :root (global swap) */\n | \"global\"\n /** Multi-language catalog — only activates under html[data-brand] */\n | \"scoped\";\n\nexport interface EmitBrandCssOptions {\n /**\n * `global` (default): `:root` + `<root>[data-brand]` — one import recolors the app.\n * Single-mode dark packs also include `.dark`.\n * Dual-mode packs (`modes.light` + `modes.dark`) emit separate light/dark color blocks.\n * `scoped`: only `<root>[data-brand]` (+ `<root>.dark[data-brand]` when dual).\n */\n mode?: EmitBrandCssMode;\n /**\n * Element the carrier attaches to. Defaults to `html` — the app-level swap.\n * A subtree preview passes its own root (e.g. `.theme-preview-artboard`) so\n * the emitted CSS cannot leak out of the preview.\n */\n root?: string;\n}\n\n/** Global single-skin selector list — single-mode packs only. */\nexport function emitGlobalSkinSelector(\n brandId: string,\n darkDefault: boolean,\n root = \"html\",\n): string {\n if (darkDefault) {\n return `:root,\\n.dark,\\n${root}[data-brand=\"${brandId}\"] {`;\n }\n return `:root,\\n${root}[data-brand=\"${brandId}\"] {`;\n}\n\n/** Light mode selector (dual-mode). */\nexport function emitLightModeSelector(\n brandId: string,\n mode: EmitBrandCssMode,\n root = \"html\",\n): string {\n if (mode === \"scoped\") return `${root}[data-brand=\"${brandId}\"] {`;\n return `:root,\\n${root}[data-brand=\"${brandId}\"] {`;\n}\n\n/** Dark mode selector (dual-mode) — never paints light colors under .dark. */\nexport function emitDarkModeSelector(\n brandId: string,\n mode: EmitBrandCssMode,\n root = \"html\",\n): string {\n if (mode === \"scoped\") return `${root}.dark[data-brand=\"${brandId}\"] {`;\n return `.dark,\\n${root}.dark[data-brand=\"${brandId}\"] {`;\n}\n\n/**\n * The 12-step neutral ramp, re-anchored on the language's own roles.\n *\n * `--neutral-1 … --neutral-12` is a fixed slate scale that no skin touched, so\n * `text-neutral-11` and `bg-neutral-2` rendered identically under every design\n * language — 1065 call sites across web, landing and the component library.\n * Under a language whose canvas is dark that is not a small drift: the navbar\n * links came out at 1.84:1, dark slate text on a dark canvas, unreadable.\n *\n * A neutral ramp IS part of a design language, so it belongs in the skin. The\n * anchors are the roles the package already declares, in the positions\n * CLAUDE.md gives them — 1 app background, 2 subtle background, 7 default\n * border, 11 secondary text, 12 primary text — and the steps between are mixed\n * in Oklab, which keeps the ramp perceptually even instead of bunching in the\n * middle the way an sRGB blend does.\n *\n * Deriving rather than hand-listing means a language cannot ship a ramp that\n * disagrees with its own surfaces, and a new language gets one for free.\n */\nfunction neutralRamp(s: BrandSemanticColors, r: BrandColorRoles | undefined): string[] {\n const hsl = (triple: string) => `hsl(${triple})`;\n const anchors: Array<[number, string]> = [\n [1, hsl(r?.canvas ?? s.background)],\n [2, hsl(r?.surface ?? s.card)],\n [7, hsl(r?.border ?? s.border)],\n [11, hsl(r?.mutedForeground ?? s.mutedForeground)],\n [12, hsl(r?.canvasForeground ?? s.foreground)],\n ];\n\n const lines = [``, ` /* ── Neutral ramp, anchored on this language's roles ── */`];\n for (let step = 1; step <= 12; step++) {\n const exact = anchors.find(([n]) => n === step);\n if (exact) {\n lines.push(` --neutral-${step}: ${exact[1]};`);\n continue;\n }\n const lower = [...anchors].reverse().find(([n]) => n < step);\n const upper = anchors.find(([n]) => n > step);\n if (!lower || !upper) continue;\n const t = Math.round(((step - lower[0]) / (upper[0] - lower[0])) * 100);\n lines.push(` --neutral-${step}: color-mix(in oklab, ${upper[1]} ${t}%, ${lower[1]});`);\n }\n return lines;\n}\n\nfunction emitColorVars(s: BrandSemanticColors, r: BrandColorRoles | undefined): string[] {\n const roleLines: string[] = [\n ` /* ── Color roles (carrier) ── */`,\n ` --role-canvas: ${r?.canvas ?? s.background};`,\n ` --role-canvas-fg: ${r?.canvasForeground ?? s.foreground};`,\n ` --role-surface: ${r?.surface ?? s.card};`,\n ` --role-surface-fg: ${r?.surfaceForeground ?? s.cardForeground};`,\n ` --role-action: ${r?.action ?? s.primary};`,\n ` --role-action-fg: ${r?.actionForeground ?? s.primaryForeground};`,\n ` --role-quiet: ${r?.quiet ?? s.secondary};`,\n ` --role-quiet-fg: ${r?.quietForeground ?? s.secondaryForeground};`,\n ` --role-muted: ${r?.muted ?? s.muted};`,\n ` --role-muted-fg: ${r?.mutedForeground ?? s.mutedForeground};`,\n ` --role-border: ${r?.border ?? s.border};`,\n ` --role-input: ${r?.input ?? s.input ?? s.border};`,\n ` --role-ring: ${r?.ring ?? s.ring};`,\n ];\n if (r?.brand) {\n roleLines.push(` --role-brand: ${r.brand};`);\n roleLines.push(\n ` --role-brand-fg: ${r.brandForeground ?? r.actionForeground ?? s.primaryForeground};`,\n );\n roleLines.push(` --brand-mark: ${r.brand};`);\n roleLines.push(\n ` --brand-mark-foreground: ${r.brandForeground ?? r.actionForeground ?? s.primaryForeground};`,\n );\n }\n\n const semantic = [\n ``,\n ` /* ── shadcn bridge (primary = action CTA) ── */`,\n ` --background: ${s.background};`,\n ` --foreground: ${s.foreground};`,\n ` --card: ${s.card};`,\n ` --card-foreground: ${s.cardForeground};`,\n ` --popover: ${s.popover};`,\n ` --popover-foreground: ${s.popoverForeground};`,\n ` --primary: ${s.primary};`,\n ` --primary-foreground: ${s.primaryForeground};`,\n ` --secondary: ${s.secondary};`,\n ` --secondary-foreground: ${s.secondaryForeground};`,\n ` --muted: ${s.muted};`,\n ` --muted-foreground: ${s.mutedForeground};`,\n ` --accent: ${s.accent};`,\n ` --accent-foreground: ${s.accentForeground};`,\n ` --destructive: ${s.destructive};`,\n ` --destructive-foreground: ${s.destructiveForeground};`,\n ` --border: ${s.border};`,\n // Field stroke, not field fill: --input reaches the DOM only through\n // `border-input`. A language that omits it inherits the hairline colour,\n // which is always a visible boundary — writing the surface colour here\n // drew the outline in the same colour as what sits behind it.\n ` --input: ${s.input ?? s.border};`,\n ` --ring: ${s.ring};`,\n ];\n\n if (s.success) semantic.push(` --success: ${s.success};`);\n if (s.successForeground) semantic.push(` --success-foreground: ${s.successForeground};`);\n if (s.warning) semantic.push(` --warning: ${s.warning};`);\n if (s.warningForeground) semantic.push(` --warning-foreground: ${s.warningForeground};`);\n if (s.info) semantic.push(` --info: ${s.info};`);\n if (s.infoForeground) semantic.push(` --info-foreground: ${s.infoForeground};`);\n\n semantic.push(\n ` --sidebar: ${s.card};`,\n ` --sidebar-foreground: ${s.foreground};`,\n ` --sidebar-primary: ${s.primary};`,\n ` --sidebar-primary-foreground: ${s.primaryForeground};`,\n ` --sidebar-accent: ${s.accent};`,\n ` --sidebar-accent-foreground: ${s.accentForeground};`,\n ` --sidebar-border: ${s.border};`,\n ` --sidebar-ring: ${s.ring};`,\n // The identity aliases, taken over by the language.\n //\n // These were the one family a Brand Package did not reach: --brand-primary\n // and --brand-accent are declared in styles.css as Nebutra's own #0033FE and\n // #0BF1C3, and no skin overrode them. Switching to Linear moved three\n // thousand semantic usages and left seventy-five sitting in Nebutra's cyan —\n // a page that reads as half-switched rather than as another language.\n //\n // A language has exactly two vivid hues to offer, and they are `roles.brand`\n // — the identity mark — and `roles.action`, the product fill. Notion is blue\n // on black, Raycast coral behind near-white chrome, Stripe indigo on\n // midnight. --brand-primary takes the mark, --brand-accent the action, and a\n // language declaring no separate mark simply shows one hue in both, which is\n // true of it rather than a gap to paper over.\n //\n // NOT `semantic.accent`: that is the shadcn hover-surface role, and mapping\n // it here produced --brand-accent: 220 14% 96% for Linear and 70 5% 25% for\n // GSAP. The glow elevations would have tinted themselves with a hover grey.\n // Same slot-versus-role confusion as --radius-md and --input, one family out.\n //\n // --brand-tertiary falls back to the accent rather than inventing a third\n // hue: two honest hues beat three where one is made up.\n //\n // Emitted as complete colours, not channel triples. --brand-accent is read\n // inside `color-mix(in srgb, var(--brand-accent) 8%, transparent)` by the\n // glow elevations, and a bare triple there voids the whole declaration —\n // silently, which is the failure this codebase keeps relearning.\n ` --brand-primary: hsl(${r?.brand ?? s.primary});`,\n ` --brand-accent: hsl(${s.primary});`,\n ` --brand-accent-foreground: hsl(${s.primaryForeground});`,\n ` --brand-tertiary: hsl(${s.primary});`,\n ` --brand-gradient: hsl(var(--primary));`,\n ` --brand-gradient-reverse: hsl(var(--primary));`,\n ` --brand-gradient-vertical: hsl(var(--primary));`,\n ` --brand-gradient-radial: hsl(var(--primary));`,\n );\n\n return [...roleLines, ...semantic, ...neutralRamp(s, r)];\n}\n\n/**\n * Emit a single opt-in skin CSS file from a Brand Package.\n */\nexport function emitBrandCss(brand: BrandPackage, options: EmitBrandCssOptions = {}): string {\n const mode = options.mode ?? \"global\";\n const root = options.root ?? \"html\";\n const b = normalizeBrandPackage(brand);\n const t = b.typography;\n const dual = isDualModeBrand(b);\n\n const parts: string[] = [\n `/**`,\n ` * Brand carrier skin: ${b.name} (${b.id}) v${b.version}`,\n ` * darkDefault=${b.darkDefault} dualMode=${dual} button=${b.recipe.buttonDefault}`,\n ` * fonts=${t.faces?.length ?? 0} mode=${mode}`,\n ` * Contract: roles.action → --primary; roles.brand → --brand-mark (never default CTA)`,\n ` */`,\n ``,\n ...emitFontFaces(t.faces),\n ];\n\n // Biome CSS formatter prefers double-quoted font families.\n const fontSans = withCjkTail(cssFontStack(t.fontSans));\n const fontDisplay = withCjkTail(cssFontStack(t.fontDisplay ?? t.fontSans));\n const typeLines = [\n ` --font-sans: ${fontSans};`,\n // The CJK-locale rule in base.css sets body's font-family from --font-cn,\n // which sits above --font-sans in specificity. A skin that left it alone\n // was silently overruled on every Chinese page: picking a design language\n // changed nothing about the type. The tail is already in fontSans, so the\n // two stacks are the same stack.\n ` --font-cn: ${fontSans};`,\n ` --font-heading: ${fontDisplay};`,\n ` --font-display: ${fontDisplay};`,\n ];\n if (t.fontMono) typeLines.push(` --font-mono: ${cssFontStack(t.fontMono)};`);\n if (t.headingWeight != null) {\n typeLines.push(` --font-weight-heading: ${t.headingWeight};`);\n }\n\n const cats = b.extensions?.categories;\n const decorative = b.extensions?.decorative;\n const extLines: string[] = [];\n if (cats) {\n for (const [key, value] of Object.entries(cats)) {\n const safe = key.replace(/[^a-z0-9_-]/gi, \"-\").toLowerCase();\n extLines.push(` --brand-category-${safe}: ${value};`);\n }\n }\n if (decorative) {\n for (const [key, value] of Object.entries(decorative)) {\n const safe = key.replace(/[^a-z0-9_-]/gi, \"-\").toLowerCase();\n extLines.push(` --brand-decorative-${safe}: ${value};`);\n }\n }\n\n const sharedChrome = [\n ``,\n ` /* Recipe (action language + free elev/radii) */`,\n ...recipeVars(b.recipe),\n ``,\n ` /* Typography */`,\n ...typeLines,\n ...motionVars(b.motion),\n ...spacingVars(b.spacing),\n ...(extLines.length\n ? [\"\", \" /* Taxonomy / decorative (not product CTA) */\", ...extLines]\n : []),\n ];\n\n if (dual && b.modes?.light?.semantic && b.modes?.dark?.semantic) {\n // Light block: colors + shared chrome\n parts.push(emitLightModeSelector(b.id, mode, root));\n parts.push(\n ...emitColorVars(b.modes.light.semantic, b.modes.light.roles),\n ...sharedChrome,\n `}`,\n ``,\n );\n // Dark block: colors only (chrome inherits)\n parts.push(emitDarkModeSelector(b.id, mode, root));\n parts.push(...emitColorVars(b.modes.dark.semantic, b.modes.dark.roles), `}`, ``);\n } else {\n // Single-mode: one selector + full block\n const selector =\n mode === \"scoped\"\n ? `${root}[data-brand=\"${b.id}\"] {`\n : emitGlobalSkinSelector(b.id, b.darkDefault, root);\n parts.push(selector);\n parts.push(...emitColorVars(b.semantic, b.roles), ...sharedChrome, `}`, ``);\n }\n\n return parts.join(\"\\n\");\n}\n","/** Convert #rgb / #rrggbb to HSL channel triple \"H S% L%\" for shadcn-style vars. */\nexport function hexToHslChannels(hex: string): string {\n let h = hex.trim().replace(/^#/, \"\");\n if (h.length === 3) {\n h = h\n .split(\"\")\n .map((c) => c + c)\n .join(\"\");\n }\n if (h.length !== 6 || !/^[0-9a-fA-F]+$/.test(h)) {\n throw new Error(`Invalid hex color: ${hex}`);\n }\n const r = Number.parseInt(h.slice(0, 2), 16) / 255;\n const g = Number.parseInt(h.slice(2, 4), 16) / 255;\n const b = Number.parseInt(h.slice(4, 6), 16) / 255;\n return srgbToHslChannels(r, g, b);\n}\n\nfunction srgbToHslChannels(r: number, g: number, b: number): string {\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const l = (max + min) / 2;\n let s = 0;\n let hue = 0;\n if (max !== min) {\n const d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n switch (max) {\n case r:\n hue = (g - b) / d + (g < b ? 6 : 0);\n break;\n case g:\n hue = (b - r) / d + 2;\n break;\n default:\n hue = (r - g) / d + 4;\n }\n hue /= 6;\n }\n const H = Math.round(hue * 360);\n const S = Math.round(s * 100);\n const L = Math.round(l * 100);\n return `${H} ${S}% ${L}%`;\n}\n\n/** Already a shadcn-style channel triple? e.g. \"228 85% 56%\" */\nconst HSL_CHANNELS_RE = /^(\\d+(?:\\.\\d+)?)\\s+(\\d+(?:\\.\\d+)?)%\\s+(\\d+(?:\\.\\d+)?)%$/;\n\n/**\n * Normalize any common color input to HSL channel triple \"H S% L%\".\n * Accepts: #hex, \"H S% L%\", hsl()/hsla(), rgb()/rgba().\n */\nexport function colorToHslChannels(color: string): string {\n const t = color.trim();\n if (!t) throw new Error(\"Empty color\");\n\n const channels = t.match(HSL_CHANNELS_RE);\n if (channels) {\n return `${Math.round(Number(channels[1]))} ${Math.round(Number(channels[2]))}% ${Math.round(Number(channels[3]))}%`;\n }\n\n // Parse hsl()/rgb() without open-ended \\s* quantifiers (ReDoS-safe).\n const hslPrefix = t.match(/^hsla?\\(/i);\n if (hslPrefix) {\n const inner = t.slice(hslPrefix[0].length).split(\")\")[0] ?? \"\";\n const nums = inner.match(/[\\d.]+/g) ?? [];\n if (nums.length >= 3) {\n return `${Math.round(Number(nums[0]))} ${Math.round(Number(nums[1]))}% ${Math.round(Number(nums[2]))}%`;\n }\n }\n\n const rgbPrefix = t.match(/^rgba?\\(/i);\n if (rgbPrefix) {\n const inner = t.slice(rgbPrefix[0].length).split(\")\")[0] ?? \"\";\n const nums = inner.match(/[\\d.]+/g) ?? [];\n if (nums.length >= 3) {\n return srgbToHslChannels(Number(nums[0]) / 255, Number(nums[1]) / 255, Number(nums[2]) / 255);\n }\n }\n\n if (t.startsWith(\"#\") || /^[0-9a-fA-F]{3,8}$/.test(t)) {\n return hexToHslChannels(t.startsWith(\"#\") ? t : `#${t}`);\n }\n\n throw new Error(`Unsupported color: ${color}`);\n}\n\n/** Prefer {@link colorToHslChannels}; hex-only name kept for call sites. */\nexport function tryHexToHsl(hex: string | undefined, fallback: string): string {\n return tryColorToHsl(hex, fallback);\n}\n\nexport function tryColorToHsl(color: string | undefined, fallback: string): string {\n if (!color) return fallback;\n try {\n return colorToHslChannels(color);\n } catch {\n return fallback;\n }\n}\n","/**\n * Normalize Brand Packages into the carrier contract.\n * Accepts legacy recipe fields and missing roles; always outputs full roles + free elev/radii.\n */\n\nimport { tryHexToHsl } from \"./hex-to-hsl\";\nimport type {\n BrandColorRoles,\n BrandElevationTokens,\n BrandModePalette,\n BrandModes,\n BrandPackage,\n BrandPackageInput,\n BrandRadii,\n BrandRecipe,\n BrandRecipeInput,\n BrandSemanticColors,\n ElevationStyle,\n} from \"./types\";\n\nconst NONE = \"0 0 #0000\";\n\nconst KEY_SHADOW =\n \"rgba(255, 255, 255, 0.05) 0px 1px 0px 0px inset, rgba(255, 255, 255, 0.25) 0px 0px 0px 1px, rgba(0, 0, 0, 0.2) 0px -1px 0px 0px inset\";\n\nconst HAIRLINE_SHADOW = \"rgba(0, 0, 0, 0.08) 0px 0px 0px 1px, rgb(250, 250, 250) 0px 0px 0px 1px\";\n\n// Inlined, not `var(--shadow-sm, …)`. The theme block maps --shadow-sm to\n// var(--elevation-sm) and the skin sets --elevation-sm from these, so the\n// reference closed a loop onto itself: the fallback rescued it in the browser\n// while validateBrandPackage — correctly — refused the package. A default that\n// only works because its own fallback fires is not a default.\nconst SOFT_CARD = \"0 1px 2px 0 rgb(0 0 0 / 0.05)\";\nconst SOFT_CONTROL = \"0 1px 2px 0 rgb(0 0 0 / 0.04)\";\nconst SOFT_RAISED = \"0 4px 6px -1px rgb(0 0 0 / 0.1)\";\n\n/** Ensure role color is HSL channels (accept hex for convenience). */\nfunction asChannels(value: string | undefined): string | undefined {\n if (value == null || value === \"\") return undefined;\n const v = value.trim();\n if (v.startsWith(\"#\")) return tryHexToHsl(v, \"0 0% 50%\");\n return v;\n}\n\n/** Expand elevation preset → free CSS tokens. */\nexport function elevationPresetToTokens(\n preset: ElevationStyle | undefined,\n cardShadow?: string,\n): BrandElevationTokens {\n switch (preset) {\n case \"none\":\n return { card: NONE, control: NONE, raised: NONE };\n case \"key\":\n return {\n card: cardShadow ?? KEY_SHADOW,\n control: NONE,\n raised: cardShadow ?? KEY_SHADOW,\n };\n case \"hairline\":\n return {\n card: cardShadow ?? HAIRLINE_SHADOW,\n control: NONE,\n raised: cardShadow ?? HAIRLINE_SHADOW,\n };\n case \"raised\":\n return { card: SOFT_RAISED, control: SOFT_CONTROL, raised: SOFT_RAISED };\n default:\n return { card: SOFT_CARD, control: SOFT_CONTROL, raised: SOFT_RAISED };\n }\n}\n\nexport function rolesFromSemantic(\n s: BrandSemanticColors,\n brandMark?: { brand?: string; brandForeground?: string },\n): BrandColorRoles {\n const roles: BrandColorRoles = {\n canvas: s.background,\n canvasForeground: s.foreground,\n surface: s.card,\n surfaceForeground: s.cardForeground,\n action: s.primary,\n actionForeground: s.primaryForeground,\n quiet: s.secondary,\n quietForeground: s.secondaryForeground,\n muted: s.muted,\n mutedForeground: s.mutedForeground,\n border: s.border,\n ring: s.ring,\n destructive: s.destructive,\n destructiveForeground: s.destructiveForeground,\n };\n // Optional under exactOptionalPropertyTypes: an absent field stroke must stay\n // absent so the emitter derives it from border, not become an explicit\n // undefined the emitter's ?? would then have to defend against twice.\n if (s.input) roles.input = s.input;\n const brand = asChannels(brandMark?.brand);\n if (brand) roles.brand = brand;\n const brandFg = asChannels(brandMark?.brandForeground);\n if (brandFg) roles.brandForeground = brandFg;\n if (s.success) roles.success = s.success;\n if (s.successForeground) roles.successForeground = s.successForeground;\n if (s.warning) roles.warning = s.warning;\n if (s.warningForeground) roles.warningForeground = s.warningForeground;\n if (s.info) roles.info = s.info;\n if (s.infoForeground) roles.infoForeground = s.infoForeground;\n return roles;\n}\n\n/** roles → shadcn semantic: primary ALWAYS tracks action (CTA), never brand mark. */\nexport function semanticFromRoles(r: BrandColorRoles): BrandSemanticColors {\n const accent = r.brand ?? r.quiet;\n const accentFg = r.brandForeground ?? r.quietForeground;\n const semantic: BrandSemanticColors = {\n background: r.canvas,\n foreground: r.canvasForeground,\n card: r.surface,\n cardForeground: r.surfaceForeground,\n popover: r.surface,\n popoverForeground: r.surfaceForeground,\n primary: r.action,\n primaryForeground: r.actionForeground,\n secondary: r.quiet,\n secondaryForeground: r.quietForeground,\n muted: r.muted,\n mutedForeground: r.mutedForeground,\n accent,\n accentForeground: accentFg,\n destructive: r.destructive,\n destructiveForeground: r.destructiveForeground,\n border: r.border,\n ring: r.ring,\n };\n if (r.input) semantic.input = r.input;\n if (r.success) semantic.success = r.success;\n if (r.successForeground) semantic.successForeground = r.successForeground;\n if (r.warning) semantic.warning = r.warning;\n if (r.warningForeground) semantic.warningForeground = r.warningForeground;\n if (r.info) semantic.info = r.info;\n if (r.infoForeground) semantic.infoForeground = r.infoForeground;\n return semantic;\n}\n\nfunction normalizeRadii(recipe: BrandRecipeInput): BrandRadii {\n const button = recipe.radii?.button ?? recipe.buttonRadius ?? \"0.375rem\";\n const card = recipe.radii?.card ?? recipe.cardRadius ?? \"0.75rem\";\n const radii: BrandRadii = {\n button,\n card,\n badge: recipe.radii?.badge ?? recipe.badgeRadius ?? \"9999px\",\n input: recipe.radii?.input ?? recipe.inputRadius ?? button,\n pill: recipe.radii?.pill ?? \"9999px\",\n };\n return radii;\n}\n\nfunction normalizeElevation(recipe: BrandRecipeInput): BrandElevationTokens {\n if (recipe.elevationTokens?.card) {\n const elev: BrandElevationTokens = { card: recipe.elevationTokens.card };\n elev.control = recipe.elevationTokens.control ?? NONE;\n elev.raised = recipe.elevationTokens.raised ?? recipe.elevationTokens.card;\n return elev;\n }\n return elevationPresetToTokens(recipe.elevation, recipe.cardShadow);\n}\n\nfunction normalizeBadgeDefault(\n badge: BrandRecipeInput[\"badgeDefault\"],\n): NonNullable<BrandRecipe[\"badgeDefault\"]> {\n if (!badge || badge === \"match-primary\") return \"match-action\";\n return badge;\n}\n\nfunction categoryBrandMark(brand: BrandPackage | BrandPackageInput): string | undefined {\n return typeof brand.extensions?.categories?.brand === \"string\"\n ? brand.extensions.categories.brand\n : undefined;\n}\n\n/** Canonicalize one mode palette → full roles + semantic. */\nexport function normalizeModePalette(\n palette: BrandModePalette,\n categoryBrand?: string,\n): { roles: BrandColorRoles; semantic: BrandSemanticColors } {\n let baseRoles: BrandColorRoles;\n if (palette.roles) {\n baseRoles = { ...palette.roles };\n } else if (palette.semantic) {\n const mark: { brand?: string; brandForeground?: string } = {\n brandForeground: palette.semantic.primaryForeground,\n };\n if (categoryBrand) mark.brand = categoryBrand;\n baseRoles = rolesFromSemantic(palette.semantic, mark);\n } else {\n throw new Error(\"BrandModePalette requires roles or semantic\");\n }\n\n const roles: BrandColorRoles = {\n canvas: baseRoles.canvas,\n canvasForeground: baseRoles.canvasForeground,\n surface: baseRoles.surface,\n surfaceForeground: baseRoles.surfaceForeground,\n action: baseRoles.action,\n actionForeground: baseRoles.actionForeground,\n quiet: baseRoles.quiet,\n quietForeground: baseRoles.quietForeground,\n muted: baseRoles.muted,\n mutedForeground: baseRoles.mutedForeground,\n border: baseRoles.border,\n ring: baseRoles.ring,\n destructive: baseRoles.destructive,\n destructiveForeground: baseRoles.destructiveForeground,\n };\n if (baseRoles.input) roles.input = baseRoles.input;\n const brandCh = asChannels(baseRoles.brand);\n if (brandCh) roles.brand = brandCh;\n const brandFg = asChannels(baseRoles.brandForeground) ?? baseRoles.actionForeground;\n if (brandCh) roles.brandForeground = brandFg;\n if (baseRoles.success) roles.success = baseRoles.success;\n if (baseRoles.successForeground) roles.successForeground = baseRoles.successForeground;\n if (baseRoles.warning) roles.warning = baseRoles.warning;\n if (baseRoles.warningForeground) roles.warningForeground = baseRoles.warningForeground;\n if (baseRoles.info) roles.info = baseRoles.info;\n if (baseRoles.infoForeground) roles.infoForeground = baseRoles.infoForeground;\n\n return { roles, semantic: semanticFromRoles(roles) };\n}\n\nfunction normalizeModes(\n brand: BrandPackage | BrandPackageInput,\n categoryBrand?: string,\n): BrandModes | undefined {\n const raw = brand.modes;\n if (!raw?.light && !raw?.dark) return undefined;\n\n const modes: BrandModes = {};\n if (raw.light) {\n const n = normalizeModePalette(raw.light, categoryBrand);\n modes.light = { roles: n.roles, semantic: n.semantic };\n }\n if (raw.dark) {\n const n = normalizeModePalette(raw.dark, categoryBrand);\n modes.dark = { roles: n.roles, semantic: n.semantic };\n }\n // Dual-mode complete: both present\n if (modes.light && modes.dark) return modes;\n // Partial modes still useful (e.g. only dark override)\n return modes;\n}\n\n/** Ensure package has roles + free radii/elev; strip legacy recipe aliases from output. */\nexport function normalizeBrandPackage(brand: BrandPackage | BrandPackageInput): BrandPackage {\n const categoryBrand = categoryBrandMark(brand);\n const modes = normalizeModes(brand, categoryBrand);\n\n // Default mode palette: dual-mode prefers modes[darkDefault], else top-level semantic/roles\n const defaultModeKey = brand.darkDefault ? \"dark\" : \"light\";\n const defaultMode = modes?.[defaultModeKey] ?? modes?.light ?? modes?.dark;\n\n let primaryPalette: BrandModePalette;\n if (defaultMode?.roles || defaultMode?.semantic) {\n primaryPalette = {};\n if (defaultMode.roles) primaryPalette.roles = defaultMode.roles;\n if (defaultMode.semantic) primaryPalette.semantic = defaultMode.semantic;\n } else {\n primaryPalette = { semantic: brand.semantic };\n if (brand.roles) primaryPalette.roles = brand.roles;\n }\n\n const { roles, semantic } = normalizeModePalette(primaryPalette, categoryBrand);\n\n const looseRecipe = brand.recipe as BrandRecipeInput;\n const radii = normalizeRadii(looseRecipe);\n const elevationTokens = normalizeElevation(looseRecipe);\n\n const recipe: BrandRecipe = {\n buttonDefault: looseRecipe.buttonDefault,\n density: looseRecipe.density ?? \"comfortable\",\n badgeDefault: normalizeBadgeDefault(looseRecipe.badgeDefault),\n radii,\n elevationTokens,\n };\n if (looseRecipe.primaryStrokeGradient) {\n recipe.primaryStrokeGradient = looseRecipe.primaryStrokeGradient;\n }\n if (looseRecipe.outlineBorder) {\n recipe.outlineBorder = looseRecipe.outlineBorder;\n }\n\n const out: BrandPackage = {\n ...brand,\n roles,\n semantic,\n recipe,\n };\n if (modes) out.modes = modes;\n else delete (out as { modes?: BrandModes }).modes;\n return out;\n}\n\n/** True when package has full dual light+dark palettes. */\nexport function isDualModeBrand(brand: BrandPackage): boolean {\n return Boolean(brand.modes?.light?.semantic && brand.modes?.dark?.semantic);\n}\n","import { emitBrandCss } from \"./emit-css\";\nimport type { BrandPackage } from \"./types\";\n\nexport const BRAND_STYLE_ELEMENT_ID = \"nebutra-brand-skin\";\nexport const BRAND_STORAGE_KEY = \"nebutra-brand-package\";\n\nexport interface ApplyBrandOptions {\n /** Persist package JSON to localStorage for Create Center preview reload */\n persist?: boolean;\n /** Target document (iframe preview support) */\n doc?: Document;\n}\n\nfunction targetDoc(doc?: Document): Document | null {\n if (doc) return doc;\n if (typeof document === \"undefined\") return null;\n return document;\n}\n\n/**\n * Inject brand skin CSS at runtime (Create Center preview / tenant switch).\n * Does not require rebuilding app CSS — overrides semantic + recipe vars.\n */\nexport function applyBrandCss(\n css: string,\n brandId?: string,\n options: ApplyBrandOptions = {},\n): void {\n const d = targetDoc(options.doc);\n if (!d) return;\n\n let el = d.getElementById(BRAND_STYLE_ELEMENT_ID) as HTMLStyleElement | null;\n if (!el) {\n el = d.createElement(\"style\");\n el.id = BRAND_STYLE_ELEMENT_ID;\n el.setAttribute(\"data-nebutra-brand\", brandId ?? \"custom\");\n d.head.appendChild(el);\n }\n el.textContent = css;\n if (brandId) {\n d.documentElement.dataset.brand = brandId;\n }\n}\n\n/** Apply a full Brand Package (emit CSS + optional persist). */\nexport function applyBrandPackage(brand: BrandPackage, options: ApplyBrandOptions = {}): void {\n const css = emitBrandCss(brand);\n applyBrandCss(css, brand.id, options);\n\n if (options.persist && typeof localStorage !== \"undefined\") {\n try {\n localStorage.setItem(BRAND_STORAGE_KEY, JSON.stringify(brand));\n } catch {\n // quota / private mode — ignore\n }\n }\n}\n\n/** Remove runtime brand skin and restore default Nebutra tokens. */\nexport function clearBrand(options: ApplyBrandOptions = {}): void {\n const d = targetDoc(options.doc);\n if (!d) return;\n d.getElementById(BRAND_STYLE_ELEMENT_ID)?.remove();\n delete d.documentElement.dataset.brand;\n if (options.persist && typeof localStorage !== \"undefined\") {\n try {\n localStorage.removeItem(BRAND_STORAGE_KEY);\n } catch {\n // ignore\n }\n }\n}\n\n/** Restore brand package previously persisted by applyBrandPackage({ persist: true }). */\nexport function restorePersistedBrand(options: ApplyBrandOptions = {}): BrandPackage | null {\n if (typeof localStorage === \"undefined\") return null;\n try {\n const raw = localStorage.getItem(BRAND_STORAGE_KEY);\n if (!raw) return null;\n const brand = JSON.parse(raw) as BrandPackage;\n if (!brand?.id || !brand?.semantic || !brand?.recipe) return null;\n applyBrandPackage(brand, { ...options, persist: false });\n return brand;\n } catch {\n return null;\n }\n}\n\nexport function getActiveBrandId(doc?: Document): string | null {\n const d = targetDoc(doc);\n return d?.documentElement.dataset.brand ?? null;\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
export { B as BRAND_STORAGE_KEY, a as BrandColorRoles, b as BrandElevationTokens, c as BrandFontFace, d as
|
|
3
|
+
export { B as BRAND_STORAGE_KEY, a as BrandColorRoles, b as BrandElevationTokens, c as BrandFontFace, d as BrandIframePreviewOptions, e as BrandPackage, f as BrandRadii, g as BrandRecipe, C as CompileResult, U as UseBrandOptions, h as UseBrandResult, i as applyBrandCss, j as applyBrandPackage, k as applyBrandToIframe, l as clearBrand, m as getActiveBrandId, r as restorePersistedBrand, u as useBrand, n as useBrandIframePreview } from './use-brand-ClmvK_lC.js';
|
|
4
4
|
export { ValidationResult, compileReferoTokens, emitBrandCss, hexToHslChannels, inferRecipeFromDesignMd, normalizeBrandPackage, rolesFromSemantic, semanticFromRoles, validateBrandPackage } from './brand-package/index.js';
|
|
5
5
|
|
|
6
6
|
type Theme = "light" | "dark" | "system";
|