@viax.io/uxm 4.36.0 → 4.37.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.
Files changed (133) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +74 -31
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.ts +3 -3
  5. package/dist/index.js.map +1 -1
  6. package/dist/previews/index.cjs +3 -0
  7. package/dist/previews/index.cjs.map +1 -1
  8. package/dist/previews/index.d.ts +3 -2
  9. package/dist/previews/index.d.ts.map +1 -1
  10. package/dist/previews/index.js +2 -0
  11. package/dist/previews/index.js.map +1 -1
  12. package/dist/studio/index.cjs.map +1 -1
  13. package/dist/studio/index.d.ts +2 -2
  14. package/dist/studio/index.js.map +1 -1
  15. package/dist/studio/lib/registry/app.cjs +52 -0
  16. package/dist/studio/lib/registry/app.cjs.map +1 -1
  17. package/dist/studio/lib/registry/app.d.ts.map +1 -1
  18. package/dist/studio/lib/registry/app.js +52 -0
  19. package/dist/studio/lib/registry/app.js.map +1 -1
  20. package/dist/studio/lib/registry/buttons.cjs +2 -2
  21. package/dist/studio/lib/registry/buttons.cjs.map +1 -1
  22. package/dist/studio/lib/registry/buttons.js +2 -2
  23. package/dist/studio/lib/registry/buttons.js.map +1 -1
  24. package/dist/studio/lib/registry/composite.cjs +1 -1
  25. package/dist/studio/lib/registry/composite.cjs.map +1 -1
  26. package/dist/studio/lib/registry/composite.js +1 -1
  27. package/dist/studio/lib/registry/composite.js.map +1 -1
  28. package/dist/studio/lib/registry/diagram.cjs +1 -1
  29. package/dist/studio/lib/registry/diagram.cjs.map +1 -1
  30. package/dist/studio/lib/registry/diagram.js +1 -1
  31. package/dist/studio/lib/registry/diagram.js.map +1 -1
  32. package/dist/studio/lib/registry/display.cjs +2 -2
  33. package/dist/studio/lib/registry/display.cjs.map +1 -1
  34. package/dist/studio/lib/registry/display.js +2 -2
  35. package/dist/studio/lib/registry/display.js.map +1 -1
  36. package/dist/studio/lib/registry/feedback.cjs +3 -3
  37. package/dist/studio/lib/registry/feedback.cjs.map +1 -1
  38. package/dist/studio/lib/registry/feedback.js +3 -3
  39. package/dist/studio/lib/registry/feedback.js.map +1 -1
  40. package/dist/studio/lib/registry/inputs.cjs +12 -12
  41. package/dist/studio/lib/registry/inputs.cjs.map +1 -1
  42. package/dist/studio/lib/registry/inputs.js +12 -12
  43. package/dist/studio/lib/registry/inputs.js.map +1 -1
  44. package/dist/studio/lib/types.cjs.map +1 -1
  45. package/dist/studio/persistence/generate-css.cjs +15 -0
  46. package/dist/studio/persistence/generate-css.cjs.map +1 -1
  47. package/dist/studio/persistence/generate-css.d.ts.map +1 -1
  48. package/dist/studio/persistence/generate-css.js +15 -0
  49. package/dist/studio/persistence/generate-css.js.map +1 -1
  50. package/dist/studio/shell/canvas.cjs +1 -0
  51. package/dist/studio/shell/canvas.cjs.map +1 -1
  52. package/dist/studio/shell/canvas.d.ts.map +1 -1
  53. package/dist/studio/shell/canvas.js +2 -0
  54. package/dist/studio/shell/canvas.js.map +1 -1
  55. package/dist/ui/calendar/calendar.cjs +3 -1
  56. package/dist/ui/calendar/calendar.cjs.map +1 -1
  57. package/dist/ui/calendar/calendar.d.ts +6 -2
  58. package/dist/ui/calendar/calendar.d.ts.map +1 -1
  59. package/dist/ui/calendar/calendar.js +3 -1
  60. package/dist/ui/calendar/calendar.js.map +1 -1
  61. package/dist/ui/currency-input/currency-input.cjs +3 -1
  62. package/dist/ui/currency-input/currency-input.cjs.map +1 -1
  63. package/dist/ui/currency-input/currency-input.d.ts +4 -2
  64. package/dist/ui/currency-input/currency-input.d.ts.map +1 -1
  65. package/dist/ui/currency-input/currency-input.js +3 -1
  66. package/dist/ui/currency-input/currency-input.js.map +1 -1
  67. package/dist/ui/date-input/date-input.cjs +2 -1
  68. package/dist/ui/date-input/date-input.cjs.map +1 -1
  69. package/dist/ui/date-input/date-input.d.ts +11 -1
  70. package/dist/ui/date-input/date-input.d.ts.map +1 -1
  71. package/dist/ui/date-input/date-input.js +2 -1
  72. package/dist/ui/date-input/date-input.js.map +1 -1
  73. package/dist/ui/editable-cell/editable-cell.cjs +20 -6
  74. package/dist/ui/editable-cell/editable-cell.cjs.map +1 -1
  75. package/dist/ui/editable-cell/editable-cell.d.ts +24 -1
  76. package/dist/ui/editable-cell/editable-cell.d.ts.map +1 -1
  77. package/dist/ui/editable-cell/editable-cell.js +20 -6
  78. package/dist/ui/editable-cell/editable-cell.js.map +1 -1
  79. package/dist/ui/file-upload/file-upload.cjs +36 -9
  80. package/dist/ui/file-upload/file-upload.cjs.map +1 -1
  81. package/dist/ui/file-upload/file-upload.d.ts +46 -4
  82. package/dist/ui/file-upload/file-upload.d.ts.map +1 -1
  83. package/dist/ui/file-upload/file-upload.js +36 -9
  84. package/dist/ui/file-upload/file-upload.js.map +1 -1
  85. package/dist/ui/index.cjs +12 -2
  86. package/dist/ui/index.cjs.map +1 -1
  87. package/dist/ui/index.d.ts +5 -1
  88. package/dist/ui/index.d.ts.map +1 -1
  89. package/dist/ui/index.js +7 -1
  90. package/dist/ui/index.js.map +1 -1
  91. package/dist/ui/language-switcher/index.cjs +29 -0
  92. package/dist/ui/language-switcher/index.cjs.map +1 -0
  93. package/dist/ui/language-switcher/index.d.ts +3 -0
  94. package/dist/ui/language-switcher/index.d.ts.map +1 -0
  95. package/dist/ui/language-switcher/index.js +5 -0
  96. package/dist/ui/language-switcher/index.js.map +1 -0
  97. package/dist/ui/language-switcher/language-switcher-preview.cjs +137 -0
  98. package/dist/ui/language-switcher/language-switcher-preview.cjs.map +1 -0
  99. package/dist/ui/language-switcher/language-switcher-preview.d.ts +3 -0
  100. package/dist/ui/language-switcher/language-switcher-preview.d.ts.map +1 -0
  101. package/dist/ui/language-switcher/language-switcher-preview.js +113 -0
  102. package/dist/ui/language-switcher/language-switcher-preview.js.map +1 -0
  103. package/dist/ui/language-switcher/language-switcher.cjs +127 -0
  104. package/dist/ui/language-switcher/language-switcher.cjs.map +1 -0
  105. package/dist/ui/language-switcher/language-switcher.css +95 -0
  106. package/dist/ui/language-switcher/language-switcher.d.ts +73 -0
  107. package/dist/ui/language-switcher/language-switcher.d.ts.map +1 -0
  108. package/dist/ui/language-switcher/language-switcher.js +103 -0
  109. package/dist/ui/language-switcher/language-switcher.js.map +1 -0
  110. package/dist/ui/locale/index.cjs +33 -0
  111. package/dist/ui/locale/index.cjs.map +1 -0
  112. package/dist/ui/locale/index.d.ts +3 -0
  113. package/dist/ui/locale/index.d.ts.map +1 -0
  114. package/dist/ui/locale/index.js +7 -0
  115. package/dist/ui/locale/index.js.map +1 -0
  116. package/dist/ui/locale/locale.cjs +43 -0
  117. package/dist/ui/locale/locale.cjs.map +1 -0
  118. package/dist/ui/locale/locale.d.ts +49 -0
  119. package/dist/ui/locale/locale.d.ts.map +1 -0
  120. package/dist/ui/locale/locale.js +17 -0
  121. package/dist/ui/locale/locale.js.map +1 -0
  122. package/dist/ui/page-shell/page-shell.cjs.map +1 -1
  123. package/dist/ui/page-shell/page-shell.d.ts +1 -1
  124. package/dist/ui/page-shell/page-shell.d.ts.map +1 -1
  125. package/dist/ui/page-shell/page-shell.js.map +1 -1
  126. package/dist/ui/range-slider/range-slider.cjs +7 -3
  127. package/dist/ui/range-slider/range-slider.cjs.map +1 -1
  128. package/dist/ui/range-slider/range-slider.d.ts +17 -1
  129. package/dist/ui/range-slider/range-slider.d.ts.map +1 -1
  130. package/dist/ui/range-slider/range-slider.js +7 -3
  131. package/dist/ui/range-slider/range-slider.js.map +1 -1
  132. package/dist/ui/styles.css +2 -1
  133. package/package.json +4 -5
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/studio/lib/types.ts"],"sourcesContent":["export type Category = 'App' | 'Buttons' | 'Inputs' | 'Display' | 'Feedback' | 'Forms' | 'Composite' | 'Configuration' | 'Diagram' | 'Icons' | 'Layout';\n\nexport interface BrandTokens {\n light?: Record<string, string>;\n dark?: Record<string, string>;\n}\n\nexport interface BrandConfig {\n logoUrl?: string;\n iconUrl?: string;\n faviconUrl?: string;\n logoUrlDark?: string;\n iconUrlDark?: string;\n faviconUrlDark?: string;\n fontFamily?: string;\n /** Typeface for heading surfaces. Unset = headings inherit the body face. */\n headingFontFamily?: string;\n /** Weight for heading surfaces ('500' | '600' | '700'). Unset = each\n * component keeps its own default (600, or 700 for the display sizes). */\n headingFontWeight?: string;\n /** Per-role heading refinements, layered UNDER the umbrella above: unset =\n * the role follows `headingFontFamily` / `headingFontWeight`. Roles are\n * display (StatCard value, ErrorPage code), h1 (PageHeader / ErrorPage\n * title) and h2 (DetailSection / SegmentRow title). */\n displayFontFamily?: string;\n displayFontWeight?: string;\n displayScale?: string;\n pageTitleFontFamily?: string;\n pageTitleFontWeight?: string;\n pageTitleScale?: string;\n sectionTitleFontFamily?: string;\n sectionTitleFontWeight?: string;\n sectionTitleScale?: string;\n /** Base text size multiplier applied to every font-size in the library. */\n typeScale?: string;\n /** Line height for multi-line body copy. Unset = each surface's own value. */\n bodyLineHeight?: string;\n tokens?: BrandTokens;\n}\n\nexport type EditorControlType = 'color' | 'number' | 'select' | 'toggle' | 'slider' | 'text';\n\nexport interface StyleProperty {\n key: string;\n label: string;\n control: EditorControlType;\n defaultValue: string | number | boolean;\n options?: string[];\n min?: number;\n max?: number;\n step?: number;\n unit?: string;\n /** Variant scoping. A string matches one variant value; a string[] matches\n * any of several (same shape as a LayoutVariant option's `showWhen`) — use\n * the array form for \"this knob applies to several types / states\" instead\n * of a `'a|b'` string, which is compared verbatim and can never match. */\n showWhen?: Record<string, string | string[]>;\n section?: string;\n}\n\nexport interface LayoutVariant {\n key: string;\n label: string;\n options: Array<{\n value: string;\n label: string;\n /** Per-option scoping. A string matches one variant value; a string[]\n * matches any of several (e.g. show `editing` only for the input-like\n * types `['text','number','date']`, hiding it for the pickers). */\n showWhen?: Record<string, string | string[]>;\n }>;\n defaultValue: string;\n /** Variant-level scoping — same shape as styleProperties.showWhen. The\n * entire variant picker is hidden when its conditions aren't met by\n * the current variant selections. Use to hide a picker that's\n * irrelevant in a given context (e.g. the State picker on list-item\n * when `trailing` is `meta` / `none`). */\n showWhen?: Record<string, string>;\n}\n\n/**\n * One emitted event a component fires during interaction. Surfaces in\n * the Events tab of the Properties pane: a static spec on top (what\n * fires when, with what payload) and a live log below (chronological\n * capture of real events from the canvas).\n *\n * Names use the canonical React handler name (`onClick`, `onChange`)\n * rather than the DOM event name (`click`, `change`) so the spec reads\n * the way a consumer would type it in JSX. The DOM-event → handler\n * mapping lives in canvas.tsx's capture wrapper.\n */\nexport interface EventSpec {\n /** Handler name, e.g. \"onClick\". */\n name: string;\n /** Short prose describing what triggers the event. */\n description: string;\n /** TypeScript-ish payload signature, e.g. \"MouseEvent\" or \"{ value: string }\". */\n payload?: string;\n /** Variant scoping — same shape as styleProperties.showWhen. */\n showWhen?: Record<string, string>;\n}\n\n/**\n * One prop in the developer-facing API documentation. Surfaces in the\n * Dev tab's API section as a row in the props table.\n *\n * Authored alongside the atom (in the registry) rather than auto-\n * extracted from TypeScript today. The shape mirrors what an\n * extraction tool (react-docgen-typescript, ts-morph) would emit, so a\n * future build-time generator can populate this slot without changing\n * the consumer shape.\n */\nexport interface PropSpec {\n /** Prop name as it appears in JSX, e.g. \"variant\". */\n name: string;\n /** TypeScript-ish type signature, e.g. `\"primary\" | \"ghost\"`, `ReactNode`, `(e: MouseEvent) => void`. */\n type: string;\n /** Whether the prop is required (no `?` in the source interface). */\n required?: boolean;\n /** Default value as it appears in the destructured fn signature, stringified. */\n defaultValue?: string;\n /** Short prose — JSDoc summary, or hand-authored description. */\n description?: string;\n}\n\n/**\n * Developer-facing API documentation for a component. Drives the Dev\n * tab's API section (import path + props table + usage snippet).\n * Optional — atoms without `api` show only Events + Variant Matrix.\n */\nexport interface ComponentApi {\n /** Import path consumers use, e.g. \"@modo/uxm/ui\". */\n importPath: string;\n /** Named export(s) to import. Single string or array for atoms that ship multiple exports (Button family). */\n importNames: string | string[];\n /** Props in declaration order — exclude inherited HTML attributes for clarity. */\n props: PropSpec[];\n}\n\nexport interface ComponentDef {\n id: string;\n name: string;\n category: Category;\n description: string;\n styleProperties: StyleProperty[];\n layoutVariants: LayoutVariant[];\n canvasBackground?: boolean;\n /**\n * Fill the canvas width and top-align instead of the default center-both-\n * axes layout. For previews that are galleries / long lists (e.g. the Icon\n * set grid) where centering wastes horizontal space and — worse — re-centres\n * vertically as content height changes (a filter shrinking results makes the\n * whole block jump); top-aligning keeps it anchored so filtering stays in\n * place.\n */\n canvasFill?: boolean;\n /** Optional event-API documentation, surfaced in the Events tab. */\n events?: EventSpec[];\n /** Optional dev-facing API documentation, surfaced in the Dev tab. */\n api?: ComponentApi;\n}\n\nexport type StyleOverrides = Record<string, string | number | boolean>;\n\n// Authoritative PreviewProps now lives in @viax.io/uxm/previews. Re-exported\n// here so the rest of the shell (registry, panels) keeps working without\n// import-site changes.\nexport type { PreviewProps } from '@/previews';\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
1
+ {"version":3,"sources":["../../../src/studio/lib/types.ts"],"sourcesContent":["export type Category = 'App' | 'Buttons' | 'Inputs' | 'Display' | 'Feedback' | 'Forms' | 'Composite' | 'Configuration' | 'Diagram' | 'Icons' | 'Layout';\n\nexport interface BrandTokens {\n light?: Record<string, string>;\n dark?: Record<string, string>;\n}\n\nexport interface BrandConfig {\n logoUrl?: string;\n iconUrl?: string;\n faviconUrl?: string;\n logoUrlDark?: string;\n iconUrlDark?: string;\n faviconUrlDark?: string;\n fontFamily?: string;\n /** Typeface for heading surfaces. Unset = headings inherit the body face. */\n headingFontFamily?: string;\n /** Weight for heading surfaces ('500' | '600' | '700'). Unset = each\n * component keeps its own default (600, or 700 for the display sizes). */\n headingFontWeight?: string;\n /** Per-role heading refinements, layered UNDER the umbrella above: unset =\n * the role follows `headingFontFamily` / `headingFontWeight`. Roles are\n * display (StatCard value, ErrorPage code), h1 (PageHeader / ErrorPage\n * title) and h2 (DetailSection / SegmentRow title). */\n displayFontFamily?: string;\n displayFontWeight?: string;\n displayScale?: string;\n pageTitleFontFamily?: string;\n pageTitleFontWeight?: string;\n pageTitleScale?: string;\n sectionTitleFontFamily?: string;\n sectionTitleFontWeight?: string;\n sectionTitleScale?: string;\n /** Base text size multiplier applied to every font-size in the library. */\n typeScale?: string;\n /** Line height for multi-line body copy. Unset = each surface's own value. */\n bodyLineHeight?: string;\n tokens?: BrandTokens;\n}\n\nexport type EditorControlType = 'color' | 'number' | 'select' | 'toggle' | 'slider' | 'text';\n\nexport interface StyleProperty {\n key: string;\n label: string;\n control: EditorControlType;\n defaultValue: string | number | boolean;\n options?: string[];\n min?: number;\n max?: number;\n step?: number;\n unit?: string;\n /** Variant scoping. A string matches one variant value; a string[] matches\n * any of several (same shape as a LayoutVariant option's `showWhen`) — use\n * the array form for \"this knob applies to several types / states\" instead\n * of a `'a|b'` string, which is compared verbatim and can never match. */\n showWhen?: Record<string, string | string[]>;\n section?: string;\n}\n\nexport interface LayoutVariant {\n key: string;\n label: string;\n options: Array<{\n value: string;\n label: string;\n /** Per-option scoping. A string matches one variant value; a string[]\n * matches any of several (e.g. show `editing` only for the input-like\n * types `['text','number','date']`, hiding it for the pickers). */\n showWhen?: Record<string, string | string[]>;\n }>;\n defaultValue: string;\n /** Variant-level scoping — same shape as styleProperties.showWhen. The\n * entire variant picker is hidden when its conditions aren't met by\n * the current variant selections. Use to hide a picker that's\n * irrelevant in a given context (e.g. the State picker on list-item\n * when `trailing` is `meta` / `none`). */\n showWhen?: Record<string, string>;\n}\n\n/**\n * One emitted event a component fires during interaction. Surfaces in\n * the Events tab of the Properties pane: a static spec on top (what\n * fires when, with what payload) and a live log below (chronological\n * capture of real events from the canvas).\n *\n * Names use the canonical React handler name (`onClick`, `onChange`)\n * rather than the DOM event name (`click`, `change`) so the spec reads\n * the way a consumer would type it in JSX. The DOM-event → handler\n * mapping lives in canvas.tsx's capture wrapper.\n */\nexport interface EventSpec {\n /** Handler name, e.g. \"onClick\". */\n name: string;\n /** Short prose describing what triggers the event. */\n description: string;\n /** TypeScript-ish payload signature, e.g. \"MouseEvent\" or \"{ value: string }\". */\n payload?: string;\n /** Variant scoping — same shape as styleProperties.showWhen. */\n showWhen?: Record<string, string>;\n}\n\n/**\n * One prop in the developer-facing API documentation. Surfaces in the\n * Dev tab's API section as a row in the props table.\n *\n * Authored alongside the atom (in the registry) rather than auto-\n * extracted from TypeScript today. The shape mirrors what an\n * extraction tool (react-docgen-typescript, ts-morph) would emit, so a\n * future build-time generator can populate this slot without changing\n * the consumer shape.\n */\nexport interface PropSpec {\n /** Prop name as it appears in JSX, e.g. \"variant\". */\n name: string;\n /** TypeScript-ish type signature, e.g. `\"primary\" | \"ghost\"`, `ReactNode`, `(e: MouseEvent) => void`. */\n type: string;\n /** Whether the prop is required (no `?` in the source interface). */\n required?: boolean;\n /** Default value as it appears in the destructured fn signature, stringified. */\n defaultValue?: string;\n /** Short prose — JSDoc summary, or hand-authored description. */\n description?: string;\n}\n\n/**\n * Developer-facing API documentation for a component. Drives the Dev\n * tab's API section (import path + props table + usage snippet).\n * Optional — atoms without `api` show only Events + Variant Matrix.\n */\nexport interface ComponentApi {\n /** Import path consumers use, e.g. \"@modo/uxm/ui\". */\n importPath: string;\n /** Named export(s) to import. Single string or array for atoms that ship multiple exports (Button family). */\n importNames: string | string[];\n /** Props in declaration order — exclude inherited HTML attributes for clarity. */\n props: PropSpec[];\n}\n\nexport interface ComponentDef {\n id: string;\n name: string;\n category: Category;\n description: string;\n styleProperties: StyleProperty[];\n layoutVariants: LayoutVariant[];\n canvasBackground?: boolean;\n /**\n * Fill the canvas width and top-align instead of the default center-both-\n * axes layout. For previews that are galleries / long lists (e.g. the Icon\n * set grid) where centering wastes horizontal space and — worse — re-centres\n * vertically as content height changes (a filter shrinking results makes the\n * whole block jump); top-aligning keeps it anchored so filtering stays in\n * place.\n */\n canvasFill?: boolean;\n /** Optional event-API documentation, surfaced in the Events tab. */\n events?: EventSpec[];\n /** Optional dev-facing API documentation, surfaced in the Dev tab. */\n api?: ComponentApi;\n}\n\nexport type StyleOverrides = Record<string, string | number | boolean>;\n\n// Authoritative PreviewProps now lives in @viax/uxm/previews. Re-exported\n// here so the rest of the shell (registry, panels) keeps working without\n// import-site changes.\nexport type { PreviewProps } from '@/previews';\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -108,6 +108,21 @@ const PER_COMPONENT_MAPPING = {
108
108
  paddingY: "--uxm-number-input-padding-y",
109
109
  fontSize: "--uxm-number-input-font-size"
110
110
  },
111
+ // Every key below collides with REAL_CSS_PROPS. The atom passes its class to
112
+ // `Listbox`, so the emitted rule lands on that in-page ROOT while the styled
113
+ // element is the `__trigger` child, which declares its own `color`,
114
+ // `border-color`, `font-size` and `gap` from `--uxm-language-switcher-*` and
115
+ // therefore beats anything inherited — every one of these would be a silent
116
+ // no-op. Padding is worse: `padding-inline` on the root pads OUTSIDE the
117
+ // button while the trigger keeps its default 10px/7px.
118
+ "language-switcher": {
119
+ color: "--uxm-language-switcher-color",
120
+ borderColor: "--uxm-language-switcher-border-color",
121
+ fontSize: "--uxm-language-switcher-font-size",
122
+ gap: "--uxm-language-switcher-gap",
123
+ paddingX: "--uxm-language-switcher-padding-x",
124
+ paddingY: "--uxm-language-switcher-padding-y"
125
+ },
111
126
  // Without this entry `fontSize` falls through REAL_CSS_PROPS and emits a
112
127
  // literal `font-size` on `.uxm-color-input`, which the atom's own children
113
128
  // (`__value-field`, `__format`) always beat — so the knob did nothing at all.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/studio/persistence/generate-css.ts"],"sourcesContent":["import type { AllOverrides } from './types';\nimport type { BrandConfig } from '../lib/types';\n\n/**\n * Pure CSS generator for UXM Studio overrides.\n *\n * Single source of truth (R5): the modo Hono `/api/uxm/save` route imports\n * `generateOverridesCss` from here instead of keeping its own copy. No Node\n * APIs — runs in browser (client export) and server alike.\n *\n * Emits a stylesheet from per-component style overrides plus brand config\n * (font, logo/icon URLs, brand token blocks). All attacker-controlled brand\n * values are sanitised before interpolation because the output is served to\n * every browser session.\n */\n\nconst BRAND_FONT_WEIGHTS = 'wght@400;500;600;700';\n\nexport function fontFileUrl(fontFamily: string): string {\n const encoded = fontFamily.trim().replace(/\\s+/g, '+');\n return `https://fonts.googleapis.com/css2?family=${encoded}:${BRAND_FONT_WEIGHTS}&display=swap`;\n}\n\nconst REAL_CSS_PROPS = new Set([\n 'background', 'backgroundColor',\n 'color',\n 'border', 'borderColor', 'borderRadius', 'borderWidth', 'borderStyle',\n 'padding', 'paddingX', 'paddingY', 'margin',\n 'gap', 'rowGap', 'columnGap',\n 'width', 'height', 'minWidth', 'maxWidth', 'minHeight', 'maxHeight',\n 'fontSize', 'fontWeight', 'fontFamily', 'lineHeight',\n 'opacity',\n 'cursor', 'display', 'position', 'overflow', 'direction',\n]);\n\n// Per-component selector overrides for the emitted rule. Defaults to\n// `.uxm-{id}`. Override when the atom renders the styled element via a PORTAL\n// (Listbox / Popover panel mounts to document.body): CSS custom properties\n// cascade DOWN from the declaring element, so vars on the in-page wrapper\n// never reach a portaled descendant. Emit on BOTH wrapper and panel selector.\nconst PER_COMPONENT_SELECTOR: Record<string, string> = {\n listbox: '.uxm-listbox, .uxm-listbox__panel',\n // Menu mirrors Listbox: the `.uxm-menu` wrapper lives in-page around the\n // trigger, but the `.uxm-menu__panel` portals to document.body, so vars on\n // the wrapper never reach it. Emit on both so the panel carries them.\n menu: '.uxm-menu, .uxm-menu__panel',\n // PhoneInput no longer needs a panel-scoped selector: its country picker\n // now delegates to the shared `Listbox`, whose portaled panel already gets\n // its vars via the `listbox` entry above. All `--uxm-phone-input-*` knobs\n // target the in-page field, so the default `.uxm-phone-input` selector is\n // correct.\n};\n\n// One knob → one variable. A multi-target (string[]) form was briefly added so\n// Card's Row Gap could write both the Stack and Cluster gap vars; that was the\n// only use, and it was the wrong shape (see the `card` entry below), so the\n// mapping stays single-target on purpose — a knob that themes a SIBLING atom's\n// var cannot win against that atom's own knob.\nconst PER_COMPONENT_MAPPING: Record<string, Record<string, string>> = {\n 'input-with-icon': {\n backgroundColor: '--uxm-input-with-icon-bg',\n borderColor: '--uxm-input-with-icon-border-color',\n borderRadius: '--uxm-input-with-icon-radius',\n paddingX: '--uxm-input-with-icon-padding-x',\n paddingY: '--uxm-input-with-icon-padding-y',\n fontSize: '--uxm-input-with-icon-font-size',\n color: '--uxm-input-with-icon-color',\n },\n 'input-text': {\n backgroundColor: '--uxm-input-text-bg',\n borderColor: '--uxm-input-text-border-color',\n color: '--uxm-input-text-color',\n borderRadius: '--uxm-input-text-border-radius',\n paddingX: '--uxm-input-text-padding-x',\n paddingY: '--uxm-input-text-padding-y',\n fontSize: '--uxm-input-text-font-size',\n },\n 'number-input': {\n backgroundColor: '--uxm-number-input-bg',\n borderColor: '--uxm-number-input-border-color',\n color: '--uxm-number-input-color',\n borderRadius: '--uxm-number-input-border-radius',\n paddingX: '--uxm-number-input-padding-x',\n paddingY: '--uxm-number-input-padding-y',\n fontSize: '--uxm-number-input-font-size',\n },\n // Without this entry `fontSize` falls through REAL_CSS_PROPS and emits a\n // literal `font-size` on `.uxm-color-input`, which the atom's own children\n // (`__value-field`, `__format`) always beat — so the knob did nothing at all.\n 'color-input': {\n fontSize: '--uxm-color-input-font-size',\n },\n // Every key here collides with REAL_CSS_PROPS, where the generic fallback\n // emits a REAL property on `.uxm-code-editor` instead of a var. That root is\n // pure chrome — the text lives in `__input` / `__gutter-lines`, which declare\n // their own `color` / `font-size` / `line-height` and always beat inherited\n // values, so Text / Font Size / Line Height would be silent no-ops. Padding is\n // worse than a no-op: `padding-inline` on the root pads OUTSIDE the code while\n // `--uxm-code-editor-padding-x` stays unset, so the gutter's absolutely\n // positioned `left` keeps its 14px default and the numbers leave their column.\n // Same defect as the `color-input` entry above.\n 'code-editor': {\n backgroundColor: '--uxm-code-editor-bg',\n borderColor: '--uxm-code-editor-border-color',\n color: '--uxm-code-editor-color',\n borderRadius: '--uxm-code-editor-border-radius',\n paddingX: '--uxm-code-editor-padding-x',\n paddingY: '--uxm-code-editor-padding-y',\n fontSize: '--uxm-code-editor-font-size',\n lineHeight: '--uxm-code-editor-line-height',\n minHeight: '--uxm-code-editor-min-height',\n },\n 'currency-input': {\n backgroundColor: '--uxm-currency-input-background-color',\n borderColor: '--uxm-currency-input-border-color',\n borderRadius: '--uxm-currency-input-border-radius',\n paddingX: '--uxm-currency-input-padding-x',\n paddingY: '--uxm-currency-input-padding-y',\n fontSize: '--uxm-currency-input-font-size',\n color: '--uxm-currency-input-color',\n },\n textarea: {\n backgroundColor: '--uxm-textarea-bg',\n borderColor: '--uxm-textarea-border-color',\n color: '--uxm-textarea-color',\n minHeight: '--uxm-textarea-min-height',\n borderRadius: '--uxm-textarea-border-radius',\n paddingX: '--uxm-textarea-padding-x',\n paddingY: '--uxm-textarea-padding-y',\n fontSize: '--uxm-textarea-font-size',\n },\n 'file-upload': {\n backgroundColor: '--uxm-file-upload-bg',\n borderColor: '--uxm-file-upload-border-color',\n color: '--uxm-file-upload-color',\n borderRadius: '--uxm-file-upload-border-radius',\n borderStyle: '--uxm-file-upload-border-style',\n borderWidth: '--uxm-file-upload-border-width',\n paddingX: '--uxm-file-upload-padding-x',\n paddingY: '--uxm-file-upload-padding-y',\n minHeight: '--uxm-file-upload-min-height',\n gap: '--uxm-file-upload-gap',\n rowGap: '--uxm-file-upload-row-gap',\n },\n 'select-dropdown': {\n backgroundColor: '--uxm-select-dropdown-bg',\n borderColor: '--uxm-select-dropdown-border-color',\n color: '--uxm-select-dropdown-color',\n borderRadius: '--uxm-select-dropdown-border-radius',\n paddingX: '--uxm-select-dropdown-padding-x',\n paddingY: '--uxm-select-dropdown-padding-y',\n fontSize: '--uxm-select-dropdown-font-size',\n },\n 'date-input': {\n backgroundColor: '--uxm-date-input-background-color',\n borderColor: '--uxm-date-input-border-color',\n borderRadius: '--uxm-date-input-border-radius',\n paddingX: '--uxm-date-input-padding-x',\n paddingY: '--uxm-date-input-padding-y',\n fontSize: '--uxm-date-input-font-size',\n color: '--uxm-date-input-color',\n },\n 'password-input': {\n backgroundColor: '--uxm-password-input-background-color',\n borderColor: '--uxm-password-input-border-color',\n borderRadius: '--uxm-password-input-border-radius',\n paddingX: '--uxm-password-input-padding-x',\n paddingY: '--uxm-password-input-padding-y',\n fontSize: '--uxm-password-input-font-size',\n color: '--uxm-password-input-color',\n },\n 'time-input': {\n backgroundColor: '--uxm-time-input-background-color',\n borderColor: '--uxm-time-input-border-color',\n borderRadius: '--uxm-time-input-border-radius',\n paddingX: '--uxm-time-input-padding-x',\n paddingY: '--uxm-time-input-padding-y',\n fontSize: '--uxm-time-input-font-size',\n color: '--uxm-time-input-color',\n },\n 'phone-input': {\n backgroundColor: '--uxm-phone-input-background-color',\n borderColor: '--uxm-phone-input-border-color',\n borderRadius: '--uxm-phone-input-border-radius',\n paddingX: '--uxm-phone-input-padding-x',\n paddingY: '--uxm-phone-input-padding-y',\n fontSize: '--uxm-phone-input-font-size',\n color: '--uxm-phone-input-color',\n },\n calendar: {\n backgroundColor: '--uxm-calendar-background-color',\n borderColor: '--uxm-calendar-border-color',\n borderRadius: '--uxm-calendar-border-radius',\n padding: '--uxm-calendar-padding',\n },\n tabs: {\n gap: '--uxm-tabs-gap',\n paddingX: '--uxm-tabs-padding-x',\n paddingY: '--uxm-tabs-padding-y',\n fontSize: '--uxm-tabs-font-size',\n fontWeight: '--uxm-tabs-font-weight',\n },\n 'tabs-underline': {\n gap: '--uxm-tabs-underline-gap',\n paddingX: '--uxm-tabs-underline-padding-x',\n paddingY: '--uxm-tabs-underline-padding-y',\n fontSize: '--uxm-tabs-underline-font-size',\n fontWeight: '--uxm-tabs-underline-font-weight',\n },\n 'filter-tabs': {\n gap: '--uxm-filter-tabs-gap',\n paddingX: '--uxm-filter-tabs-padding-x',\n paddingY: '--uxm-filter-tabs-padding-y',\n fontSize: '--uxm-filter-tabs-font-size',\n fontWeight: '--uxm-filter-tabs-font-weight',\n },\n 'view-switcher': {\n gap: '--uxm-view-switcher-gap',\n },\n 'button-group': {\n borderColor: '--uxm-button-group-border-color',\n borderRadius: '--uxm-button-group-border-radius',\n paddingX: '--uxm-button-group-padding-x',\n paddingY: '--uxm-button-group-padding-y',\n fontSize: '--uxm-button-group-font-size',\n },\n checkbox: {\n borderRadius: '--uxm-checkbox-border-radius',\n gap: '--uxm-checkbox-gap',\n },\n card: {\n backgroundColor: '--uxm-card-bg',\n borderColor: '--uxm-card-border-color',\n borderRadius: '--uxm-card-radius',\n padding: '--uxm-card-padding',\n // `gap` (\"Header Gap\") collides with REAL_CSS_PROPS — the generic fallback\n // would emit a literal `gap` property that `.uxm-card` never activates (the\n // card is only a flex column via the `--gap` modifier). Route it to the var\n // the modifier actually reads.\n //\n // There is deliberately NO Card knob for the CONTENT's row gap. It looks\n // like it belongs here, but the row gap is owned by the nested Stack /\n // Cluster, which already have their own Gap knobs — and those emit\n // `--uxm-stack-gap` DIRECTLY on `.uxm-stack`, where a directly-set custom\n // property always beats one inherited from `.uxm-card`. A Card-side knob\n // would therefore lose the moment anyone themed Stack, while also leaking\n // to every Stack/Cluster at any depth inside any card (custom properties\n // inherit). One owner per visual property; Card owns only its own gap.\n gap: '--uxm-card-gap',\n },\n 'toggle-switch': {\n width: '--uxm-toggle-switch-width',\n height: '--uxm-toggle-switch-height',\n },\n 'radio-group': {\n gap: '--uxm-radio-group-gap',\n },\n loader: {\n color: '--uxm-loader-color',\n gap: '--uxm-loader-gap',\n },\n 'data-table': {\n borderColor: '--uxm-data-table-border-color',\n fontSize: '--uxm-data-table-font-size',\n borderRadius: '--uxm-data-table-border-radius',\n },\n 'app-sidebar': {\n borderColor: '--uxm-app-sidebar-border-color',\n backgroundColor: '--uxm-app-sidebar-background-color',\n },\n // Every key here collides with REAL_CSS_PROPS, where the generic fallback\n // emits the LITERAL css property on the root selector instead of the var.\n //\n // For `fontSize` / `fontWeight` that is a silent no-op rather than a mere\n // detour: the atom reads those vars on `.uxm-sidebar-nav-trigger__value`, and\n // a `font-size` landing on the root is beaten by the child's own declaration.\n // The live workbench hides it — that path projects custom properties through\n // the preview's `buildVars`, so the knob only dies once a brand is SAVED.\n //\n // The rest (padding, gap, radius) do sit on the root and would survive the\n // literal route on source order alone, but they are mapped too: the sibling\n // `sidebar-nav-item` maps all six, and leaving half of them to cascade luck\n // invites exactly the question of which half.\n 'sidebar-nav-trigger': {\n paddingX: '--uxm-sidebar-nav-trigger-padding-x',\n paddingY: '--uxm-sidebar-nav-trigger-padding-y',\n fontSize: '--uxm-sidebar-nav-trigger-font-size',\n fontWeight: '--uxm-sidebar-nav-trigger-font-weight',\n gap: '--uxm-sidebar-nav-trigger-gap',\n borderRadius: '--uxm-sidebar-nav-trigger-border-radius',\n },\n 'sidebar-nav-item': {\n paddingX: '--uxm-sidebar-nav-item-padding-x',\n paddingY: '--uxm-sidebar-nav-item-padding-y',\n fontSize: '--uxm-sidebar-nav-item-font-size',\n fontWeight: '--uxm-sidebar-nav-item-font-weight',\n gap: '--uxm-sidebar-nav-item-gap',\n borderRadius: '--uxm-sidebar-nav-item-border-radius',\n },\n 'explorer-list-item': {\n paddingX: '--uxm-explorer-list-item-padding-x',\n paddingY: '--uxm-explorer-list-item-padding-y',\n fontSize: '--uxm-explorer-list-item-font-size',\n fontWeight: '--uxm-explorer-list-item-font-weight',\n gap: '--uxm-explorer-list-item-gap',\n borderRadius: '--uxm-explorer-list-item-border-radius',\n },\n 'app-top-bar': {\n borderColor: '--uxm-app-top-bar-border-color',\n backgroundColor: '--uxm-app-top-bar-background-color',\n height: '--uxm-app-top-bar-height',\n paddingX: '--uxm-app-top-bar-padding-x',\n gap: '--uxm-app-top-bar-gap',\n },\n 'explorer-section': {\n paddingX: '--uxm-explorer-section-padding-x',\n paddingY: '--uxm-explorer-section-padding-y',\n borderRadius: '--uxm-explorer-section-border-radius',\n gap: '--uxm-explorer-section-gap',\n fontSize: '--uxm-explorer-section-font-size',\n fontWeight: '--uxm-explorer-section-font-weight',\n },\n 'number-field': {\n backgroundColor: '--uxm-number-field-input-bg',\n borderColor: '--uxm-number-field-input-border',\n color: '--uxm-number-field-input-color',\n borderRadius: '--uxm-number-field-input-radius',\n paddingX: '--uxm-number-field-input-padding-x',\n paddingY: '--uxm-number-field-input-padding-y',\n fontSize: '--uxm-number-field-font-size',\n gap: '--uxm-number-field-gap',\n },\n 'icon-button': {\n color: '--uxm-icon-button-color',\n backgroundColor: '--uxm-icon-button-bg',\n hoverBackgroundColor: '--uxm-icon-button-hover-bg',\n activeBackgroundColor: '--uxm-icon-button-active-bg',\n borderRadius: '--uxm-icon-button-radius',\n },\n 'button-primary': {\n backgroundColor: '--uxm-button-primary-background-color',\n color: '--uxm-button-primary-color',\n borderRadius: '--uxm-button-primary-border-radius',\n fontSize: '--uxm-button-primary-font-size',\n fontWeight: '--uxm-button-primary-font-weight',\n paddingX: '--uxm-button-primary-padding-x',\n paddingY: '--uxm-button-primary-padding-y',\n },\n 'button-secondary': {\n backgroundColor: '--uxm-button-secondary-background-color',\n color: '--uxm-button-secondary-color',\n borderColor: '--uxm-button-secondary-border-color',\n borderRadius: '--uxm-button-secondary-border-radius',\n fontSize: '--uxm-button-secondary-font-size',\n fontWeight: '--uxm-button-secondary-font-weight',\n paddingX: '--uxm-button-secondary-padding-x',\n paddingY: '--uxm-button-secondary-padding-y',\n },\n 'button-tertiary': {\n backgroundColor: '--uxm-button-tertiary-background-color',\n color: '--uxm-button-tertiary-color',\n borderColor: '--uxm-button-tertiary-border-color',\n borderRadius: '--uxm-button-tertiary-border-radius',\n fontSize: '--uxm-button-tertiary-font-size',\n fontWeight: '--uxm-button-tertiary-font-weight',\n paddingX: '--uxm-button-tertiary-padding-x',\n paddingY: '--uxm-button-tertiary-padding-y',\n },\n 'button-ghost': {\n backgroundColor: '--uxm-button-ghost-background-color',\n color: '--uxm-button-ghost-color',\n borderRadius: '--uxm-button-ghost-border-radius',\n fontSize: '--uxm-button-ghost-font-size',\n fontWeight: '--uxm-button-ghost-font-weight',\n paddingX: '--uxm-button-ghost-padding-x',\n paddingY: '--uxm-button-ghost-padding-y',\n },\n 'button-danger': {\n backgroundColor: '--uxm-button-danger-background-color',\n color: '--uxm-button-danger-color',\n borderColor: '--uxm-button-danger-border-color',\n borderRadius: '--uxm-button-danger-border-radius',\n fontSize: '--uxm-button-danger-font-size',\n fontWeight: '--uxm-button-danger-font-weight',\n paddingX: '--uxm-button-danger-padding-x',\n paddingY: '--uxm-button-danger-padding-y',\n },\n 'button-with-icon': {\n backgroundColor: '--uxm-button-with-icon-background-color',\n color: '--uxm-button-with-icon-color',\n borderColor: '--uxm-button-with-icon-border-color',\n borderRadius: '--uxm-button-with-icon-border-radius',\n fontSize: '--uxm-button-with-icon-font-size',\n fontWeight: '--uxm-button-with-icon-font-weight',\n paddingX: '--uxm-button-with-icon-padding-x',\n paddingY: '--uxm-button-with-icon-padding-y',\n },\n 'button-icon': {\n backgroundColor: '--uxm-button-icon-background-color',\n color: '--uxm-button-icon-color',\n borderRadius: '--uxm-button-icon-border-radius',\n },\n 'back-link': {\n color: '--uxm-back-link-color',\n fontSize: '--uxm-back-link-font-size',\n fontWeight: '--uxm-back-link-font-weight',\n gap: '--uxm-back-link-gap',\n },\n breadcrumb: {\n fontSize: '--uxm-breadcrumb-font-size',\n gap: '--uxm-breadcrumb-gap',\n },\n disclosure: {\n paddingX: '--uxm-disclosure-padding-x',\n paddingY: '--uxm-disclosure-padding-y',\n fontSize: '--uxm-disclosure-font-size',\n gap: '--uxm-disclosure-gap',\n borderRadius: '--uxm-disclosure-border-radius',\n },\n 'side-flexpane': {\n paddingX: '--uxm-side-flexpane-padding-x',\n paddingY: '--uxm-side-flexpane-padding-y',\n backgroundColor: '--uxm-side-flexpane-background-color',\n borderColor: '--uxm-side-flexpane-border-color',\n borderRadius: '--uxm-side-flexpane-border-radius',\n width: '--uxm-side-flexpane-width',\n },\n 'list-item': {\n paddingX: '--uxm-list-item-padding-x',\n paddingY: '--uxm-list-item-padding-y',\n fontSize: '--uxm-list-item-font-size',\n gap: '--uxm-list-item-gap',\n borderRadius: '--uxm-list-item-border-radius',\n borderColor: '--uxm-list-item-border-color',\n },\n 'pill-select': {\n backgroundColor: '--uxm-pill-select-bg',\n borderColor: '--uxm-pill-select-border-color',\n paddingX: '--uxm-pill-select-padding-x',\n paddingY: '--uxm-pill-select-padding-y',\n },\n modal: {\n backgroundColor: '--uxm-modal-background-color',\n borderColor: '--uxm-modal-border-color',\n borderRadius: '--uxm-modal-border-radius',\n paddingX: '--uxm-modal-padding-x',\n paddingY: '--uxm-modal-padding-y',\n },\n toast: {\n backgroundColor: '--uxm-toast-background-color',\n color: '--uxm-toast-color',\n borderColor: '--uxm-toast-border-color',\n borderRadius: '--uxm-toast-border-radius',\n paddingX: '--uxm-toast-padding-x',\n paddingY: '--uxm-toast-padding-y',\n fontSize: '--uxm-toast-font-size',\n },\n avatar: {\n backgroundColor: '--uxm-avatar-background-color',\n borderColor: '--uxm-avatar-border-color',\n borderRadius: '--uxm-avatar-border-radius',\n borderWidth: '--uxm-avatar-border-width',\n color: '--uxm-avatar-color',\n fontSize: '--uxm-avatar-font-size',\n fontWeight: '--uxm-avatar-font-weight',\n },\n banner: {\n borderRadius: '--uxm-banner-border-radius',\n paddingX: '--uxm-banner-padding-x',\n paddingY: '--uxm-banner-padding-y',\n fontSize: '--uxm-banner-font-size',\n },\n 'bulk-action-bar': {\n backgroundColor: '--uxm-bulk-action-bar-background-color',\n color: '--uxm-bulk-action-bar-color',\n borderColor: '--uxm-bulk-action-bar-border-color',\n borderRadius: '--uxm-bulk-action-bar-border-radius',\n paddingX: '--uxm-bulk-action-bar-padding-x',\n paddingY: '--uxm-bulk-action-bar-padding-y',\n gap: '--uxm-bulk-action-bar-gap',\n fontSize: '--uxm-bulk-action-bar-font-size',\n },\n cluster: {\n gap: '--uxm-cluster-gap',\n },\n 'config-component-row': {\n padding: '--uxm-config-component-row-padding',\n borderRadius: '--uxm-config-component-row-radius',\n },\n 'config-segment-item': {\n paddingX: '--uxm-config-segment-item-padding-x',\n paddingY: '--uxm-config-segment-item-padding-y',\n borderRadius: '--uxm-config-segment-item-radius',\n },\n 'detail-section': {\n backgroundColor: '--uxm-detail-section-bg',\n borderColor: '--uxm-detail-section-border-color',\n borderRadius: '--uxm-detail-section-radius',\n padding: '--uxm-detail-section-padding',\n },\n divider: {\n color: '--uxm-divider-color',\n gap: '--uxm-divider-gap',\n },\n 'editable-cell': {\n // Dimensions are per-size keys (smallPaddingX, mediumMaxWidth, …) that\n // resolve via the generic `--uxm-editable-cell-{kebab(key)}` fallback in\n // toCSS; only the value colour needs an explicit entry (`color` is in\n // REAL_CSS_PROPS, so the fallback would emit a real CSS property that\n // outranks the component layer).\n color: '--uxm-editable-cell-color',\n // RETIRED knobs, kept mapped on purpose. The per-size split replaced these\n // four, but `generateOverridesCss` emits whatever keys are PERSISTED — not\n // what the registry currently declares — so a config saved before the split\n // still carries them. Without an entry here they'd fall through to\n // REAL_CSS_PROPS / the paddingX-paddingY special case in toCSS and emit\n // REAL `min-height` / `padding-inline` / `padding-block` declarations on\n // `.uxm-editable-cell`, which land in a sheet loaded after the library CSS\n // and would hard-override BOTH size presets (killing `medium`) and\n // resurrect the min-height the size work deliberately removed. Mapped to\n // their old, now-unread custom properties they are true no-ops instead.\n // Safe to delete once persisted overrides are pruned against the registry.\n minHeight: '--uxm-editable-cell-min-height',\n paddingX: '--uxm-editable-cell-padding-x',\n paddingY: '--uxm-editable-cell-padding-y',\n // `maxWidth` joined them when the cap went per-size: it is in\n // REAL_CSS_PROPS, so without this it would emit a real `max-width` that\n // pins BOTH presets (and would silently re-cap `medium`, whose whole point\n // is filling its container).\n maxWidth: '--uxm-editable-cell-max-width',\n },\n 'empty-state': {\n padding: '--uxm-empty-state-padding',\n },\n 'form-field': {\n gap: '--uxm-form-field-gap',\n // Per-tint label colours — the component reads `--uxm-form-field-label-\n // tint-*` (see form-field.scss tone classes); the generic kebab fallback\n // would emit `--uxm-form-field-tint-strong-color` etc., which nothing\n // reads, so the saved colour would silently not apply.\n tintStrongColor: '--uxm-form-field-label-tint-strong',\n tintDefaultColor: '--uxm-form-field-label-tint-default',\n tintMutedColor: '--uxm-form-field-label-tint-muted',\n // MIGRATION — `labelColor` was the single label-colour knob the tints\n // replaced. It is gone from the registry, but `generateOverridesCss` emits\n // whatever is PERSISTED, and its generic fallback lands on\n // `--uxm-form-field-label-color` — the very var the tint classes assign,\n // at equal specificity from a later sheet. Left alone it would beat ALL\n // THREE tints and silently disable them, with no knob left in the panel to\n // notice or clear it. Routed to the STRONG tint instead: strong was the\n // old (only) label colour and is still the default tone, so a pre-split\n // theme keeps the exact look it saved. A newly-saved `tintStrongColor`\n // still wins — overrides are appended, so it emits after this one.\n labelColor: '--uxm-form-field-label-tint-strong',\n },\n 'icon-tile': {\n borderRadius: '--uxm-icon-tile-radius',\n iconBg: '--uxm-icon-tile-bg',\n iconColor: '--uxm-icon-tile-color',\n },\n icon: {\n color: '--uxm-icon-color',\n },\n 'inline-action': {\n color: '--uxm-inline-action-color',\n fontSize: '--uxm-inline-action-font-size',\n fontWeight: '--uxm-inline-action-font-weight',\n gap: '--uxm-inline-action-gap',\n },\n 'inline-filter': {\n gap: '--uxm-inline-filter-gap',\n },\n 'lifecycle-edge-label': {\n paddingX: '--uxm-lifecycle-edge-label-padding-x',\n paddingY: '--uxm-lifecycle-edge-label-padding-y',\n borderRadius: '--uxm-lifecycle-edge-label-radius',\n borderWidth: '--uxm-lifecycle-edge-label-border-width',\n fontSize: '--uxm-lifecycle-edge-label-font-size',\n fontWeight: '--uxm-lifecycle-edge-label-font-weight',\n },\n // Same rule as lifecycle-group-box below — only the REAL_CSS_PROPS collisions\n // need an entry. `color` is the one that matters: a real `color` declaration\n // on `.uxm-lifecycle-drop-slot` from a later sheet would paint the text but\n // leave the dashes on the token, splitting a pair the atom deliberately drives\n // from one variable. The shape-scoped knobs (`cardRadius`, `pillFontSize`, …)\n // and `bg` need nothing: the generic `--uxm-{id}-{kebab}` rule already lands\n // on the names the stylesheet reads.\n 'lifecycle-drop-slot': {\n borderColor: '--uxm-lifecycle-drop-slot-border-color',\n borderStyle: '--uxm-lifecycle-drop-slot-border-style',\n borderWidth: '--uxm-lifecycle-drop-slot-border-width',\n color: '--uxm-lifecycle-drop-slot-color',\n },\n // Only the knobs whose keys collide with REAL_CSS_PROPS need an entry: left\n // to the generic path they'd emit a real `background-color` / `border-width` /\n // `padding` on `.uxm-lifecycle-group-box` from a later sheet, hard-overriding\n // the rule's own `var(--uxm-… , token)` chain — and `padding` is read BY THE\n // CONSUMER off the custom property to inset the group's members, so a real\n // declaration would leave that value unreadable.\n //\n // `blur` and the three `target*` knobs are absent on purpose: the generic\n // `--uxm-{id}-{kebab}` rule already lands on the names the stylesheet reads.\n 'lifecycle-group-box': {\n backgroundColor: '--uxm-lifecycle-group-box-bg',\n borderColor: '--uxm-lifecycle-group-box-border-color',\n borderWidth: '--uxm-lifecycle-group-box-border-width',\n borderRadius: '--uxm-lifecycle-group-box-radius',\n padding: '--uxm-lifecycle-group-box-padding',\n },\n 'lifecycle-minimap': {\n backgroundColor: '--uxm-lifecycle-minimap-bg',\n borderColor: '--uxm-lifecycle-minimap-border-color',\n borderRadius: '--uxm-lifecycle-minimap-radius',\n width: '--uxm-lifecycle-minimap-width',\n height: '--uxm-lifecycle-minimap-height',\n },\n 'lifecycle-node-card': {\n backgroundColor: '--uxm-lifecycle-node-card-bg',\n borderColor: '--uxm-lifecycle-node-card-border-color',\n borderRadius: '--uxm-lifecycle-node-card-radius',\n paddingX: '--uxm-lifecycle-node-card-padding-x',\n paddingY: '--uxm-lifecycle-node-card-padding-y',\n width: '--uxm-lifecycle-node-card-width',\n minHeight: '--uxm-lifecycle-node-card-min-height',\n },\n 'lifecycle-terminal': {\n backgroundColor: '--uxm-lifecycle-terminal-bg',\n borderColor: '--uxm-lifecycle-terminal-border-color',\n color: '--uxm-lifecycle-terminal-color',\n borderRadius: '--uxm-lifecycle-terminal-radius',\n width: '--uxm-lifecycle-terminal-width',\n height: '--uxm-lifecycle-terminal-height',\n fontSize: '--uxm-lifecycle-terminal-font-size',\n fontWeight: '--uxm-lifecycle-terminal-font-weight',\n },\n 'lifecycle-zoom-control': {\n backgroundColor: '--uxm-lifecycle-zoom-bg',\n borderColor: '--uxm-lifecycle-zoom-border-color',\n borderRadius: '--uxm-lifecycle-zoom-radius',\n fontSize: '--uxm-lifecycle-zoom-font-size',\n color: '--uxm-lifecycle-zoom-color',\n buttonSize: '--uxm-lifecycle-zoom-button-size',\n iconColor: '--uxm-lifecycle-zoom-icon-color',\n },\n link: {\n fontSize: '--uxm-link-font-size',\n fontWeight: '--uxm-link-font-weight',\n },\n 'meta-row': {\n fontSize: '--uxm-meta-row-font-size',\n color: '--uxm-meta-row-color',\n gap: '--uxm-meta-row-gap',\n },\n 'number-stepper': {\n backgroundColor: '--uxm-number-stepper-input-bg',\n borderColor: '--uxm-number-stepper-input-border',\n color: '--uxm-number-stepper-input-color',\n borderRadius: '--uxm-number-stepper-input-radius',\n paddingX: '--uxm-number-stepper-input-padding-x',\n paddingY: '--uxm-number-stepper-input-padding-y',\n fontSize: '--uxm-number-stepper-font-size',\n gap: '--uxm-number-stepper-gap',\n },\n 'page-header': {\n gap: '--uxm-page-header-gap',\n paddingX: '--uxm-page-header-padding-x',\n paddingY: '--uxm-page-header-padding-y',\n },\n 'page-shell': {\n backgroundColor: '--uxm-page-shell-bg',\n },\n 'property-field': {\n gap: '--uxm-property-field-gap',\n },\n 'property-grid': {\n rowGap: '--uxm-property-grid-row-gap',\n columnGap: '--uxm-property-grid-column-gap',\n },\n 'responsive-grid': {\n gap: '--uxm-responsive-grid-gap',\n },\n 'section-header': {\n gap: '--uxm-section-header-gap',\n },\n stack: {\n gap: '--uxm-stack-gap',\n },\n 'stat-card': {\n backgroundColor: '--uxm-stat-card-background-color',\n borderColor: '--uxm-stat-card-border-color',\n borderRadius: '--uxm-stat-card-border-radius',\n padding: '--uxm-stat-card-padding',\n },\n tag: {\n borderRadius: '--uxm-tag-border-radius',\n fontWeight: '--uxm-tag-font-weight',\n },\n thumbnail: {\n borderRadius: '--uxm-thumbnail-border-radius',\n backgroundColor: '--uxm-thumbnail-background-color',\n borderColor: '--uxm-thumbnail-border-color',\n borderWidth: '--uxm-thumbnail-border-width',\n },\n 'timeline-entry': {\n gap: '--uxm-timeline-entry-gap',\n },\n 'segment-row': {\n paddingX: '--uxm-segment-row-padding-x',\n paddingY: '--uxm-segment-row-padding-y',\n gap: '--uxm-segment-row-gap',\n dragColor: '--uxm-segment-row-drag-color',\n dragHoverColor: '--uxm-segment-row-drag-hover-color',\n chevronColor: '--uxm-segment-row-chevron-color',\n chevronSize: '--uxm-segment-row-chevron-size',\n accentColor: '--uxm-segment-row-accent-color',\n accentWidth: '--uxm-segment-row-accent-width',\n accentRadius: '--uxm-segment-row-accent-radius',\n titleColor: '--uxm-segment-row-title-color',\n titleSize: '--uxm-segment-row-title-size',\n titleWeight: '--uxm-segment-row-title-weight',\n countBg: '--uxm-segment-row-count-bg',\n countColor: '--uxm-segment-row-count-color',\n countSize: '--uxm-segment-row-count-size',\n countPaddingX: '--uxm-segment-row-count-padding-x',\n countPaddingY: '--uxm-segment-row-count-padding-y',\n countRadius: '--uxm-segment-row-count-radius',\n rowHoverBg: '--uxm-segment-row-row-hover-bg',\n rowHoverRadius: '--uxm-segment-row-row-hover-radius',\n },\n 'segment-card': {\n borderColor: '--uxm-segment-card-border-color',\n borderWidth: '--uxm-segment-card-border-width',\n borderRadius: '--uxm-segment-card-border-radius',\n backgroundColor: '--uxm-segment-card-background',\n paddingX: '--uxm-segment-card-padding-x',\n paddingY: '--uxm-segment-card-padding-y',\n childrenInsetX: '--uxm-segment-card-children-inset-x',\n childrenInsetY: '--uxm-segment-card-children-inset-y',\n childrenGap: '--uxm-segment-card-children-gap',\n dividerColor: '--uxm-segment-card-divider-color',\n dividerWidth: '--uxm-segment-card-divider-width',\n },\n 'component-row': {\n paddingX: '--uxm-component-row-padding-x',\n paddingY: '--uxm-component-row-padding-y',\n gap: '--uxm-component-row-gap',\n backgroundColor: '--uxm-component-row-background',\n dragColor: '--uxm-component-row-drag-color',\n dragHoverColor: '--uxm-component-row-drag-hover-color',\n iconBadgeSize: '--uxm-component-row-icon-badge-size',\n iconBadgeRadius: '--uxm-component-row-icon-badge-radius',\n iconBadgePadding: '--uxm-component-row-icon-badge-padding',\n nameColor: '--uxm-component-row-name-color',\n nameSize: '--uxm-component-row-name-size',\n nameWeight: '--uxm-component-row-name-weight',\n typeLabelColor: '--uxm-component-row-type-label-color',\n typeLabelSize: '--uxm-component-row-type-label-size',\n typeLabelWeight: '--uxm-component-row-type-label-weight',\n chevronColor: '--uxm-component-row-chevron-color',\n chevronSize: '--uxm-component-row-chevron-size',\n rowHoverBg: '--uxm-component-row-row-hover-bg',\n rowHoverRadius: '--uxm-component-row-row-hover-radius',\n },\n 'option-list': {\n indent: '--uxm-option-list-indent',\n backgroundColor: '--uxm-option-list-background',\n borderColor: '--uxm-option-list-border-color',\n borderWidth: '--uxm-option-list-border-width',\n borderRadius: '--uxm-option-list-border-radius',\n paddingX: '--uxm-option-list-padding-x',\n paddingY: '--uxm-option-list-padding-y',\n gap: '--uxm-option-list-gap',\n rowPaddingX: '--uxm-option-list-row-padding-x',\n rowPaddingY: '--uxm-option-list-row-padding-y',\n dragColor: '--uxm-option-list-drag-color',\n dragHoverColor: '--uxm-option-list-drag-hover-color',\n bulletSize: '--uxm-option-list-bullet-size',\n bulletGap: '--uxm-option-list-bullet-gap',\n nameColor: '--uxm-option-list-name-color',\n nameSize: '--uxm-option-list-name-size',\n nameWeight: '--uxm-option-list-name-weight',\n rowHoverBg: '--uxm-option-list-row-hover-bg',\n rowHoverRadius: '--uxm-option-list-row-hover-radius',\n },\n tooltip: {\n backgroundColor: '--uxm-tooltip-background-color',\n color: '--uxm-tooltip-color',\n borderRadius: '--uxm-tooltip-border-radius',\n paddingX: '--uxm-tooltip-padding-x',\n paddingY: '--uxm-tooltip-padding-y',\n fontSize: '--uxm-tooltip-font-size',\n },\n 'content-tooltip': {\n backgroundColor: '--uxm-content-tooltip-background-color',\n borderColor: '--uxm-content-tooltip-border-color',\n borderRadius: '--uxm-content-tooltip-border-radius',\n padding: '--uxm-content-tooltip-padding',\n maxWidth: '--uxm-content-tooltip-max-width',\n },\n 'type-overview-card': {\n backgroundColor: '--uxm-typeoverview-bg',\n borderColor: '--uxm-typeoverview-border-color',\n borderRadius: '--uxm-typeoverview-radius',\n padding: '--uxm-typeoverview-padding',\n accentColor: '--uxm-typeoverview-accent-color',\n accentWidth: '--uxm-typeoverview-accent-width',\n iconBg: '--uxm-typeoverview-icon-bg',\n iconColor: '--uxm-typeoverview-icon-color',\n iconBoxSize: '--uxm-typeoverview-icon-tile-size',\n iconRadius: '--uxm-typeoverview-icon-tile-radius',\n labelSize: '--uxm-typeoverview-label-size',\n labelColor: '--uxm-typeoverview-label-color',\n valueSize: '--uxm-typeoverview-value-size',\n valueColor: '--uxm-typeoverview-value-color',\n },\n // Without an entry here every knob would fall through to the generic\n // `--uxm-{id}-{kebab}` rule and double the segment — `connectorIdleColor`\n // under id `lifecycle-connector` becomes\n // `--uxm-lifecycle-connector-connector-idle-color`. The stylesheet reads the\n // canonical single-`connector` names (and still accepts the doubled ones as\n // a fallback alias), so map the knobs explicitly.\n //\n // `connectorArrowSize` sizes an SVG polygon rather than setting any CSS\n // property, so no rule can consume it — `useThemedArrowSize` in\n // lifecycle-connector.tsx reads `--uxm-lifecycle-connector-arrow-size` back\n // off the element instead. It is published here for that reason, not for\n // naming tidiness: drop this line and a saved Arrow Size stops applying.\n 'lifecycle-connector': {\n connectorIdleColor: '--uxm-lifecycle-connector-idle-color',\n connectorActiveColor: '--uxm-lifecycle-connector-active-color',\n connectorIdleStrokeWidth: '--uxm-lifecycle-connector-idle-stroke-width',\n connectorActiveStrokeWidth: '--uxm-lifecycle-connector-active-stroke-width',\n connectorDashedColor: '--uxm-lifecycle-connector-dashed-color',\n connectorDashedStrokeWidth: '--uxm-lifecycle-connector-dashed-stroke-width',\n connectorDashPattern: '--uxm-lifecycle-connector-dash-pattern',\n connectorArrowSize: '--uxm-lifecycle-connector-arrow-size',\n },\n};\n\nfunction toCSS(key: string, componentId: string): string {\n const componentMapping = PER_COMPONENT_MAPPING[componentId];\n if (componentMapping?.[key]) return componentMapping[key];\n\n const mapping: Record<string, string> = {\n paddingX: 'padding-inline',\n paddingY: 'padding-block',\n };\n if (mapping[key]) return mapping[key];\n\n const kebab = key.replace(/([A-Z])/g, '-$1').toLowerCase();\n if (REAL_CSS_PROPS.has(key)) return kebab;\n return `--uxm-${componentId}-${kebab}`;\n}\n\nfunction formatValue(value: string | number | boolean, key: string): string {\n if (typeof value === 'boolean') return value ? '1' : '0';\n if (typeof value === 'number') {\n // `lineHeight` is a ratio, not a length — without it here a knob saved as\n // 1.5 emits `line-height: 1.5px`, which collapses every line box.\n const unitless = ['fontWeight', 'titleWeight', 'nameWeight', 'typeLabelWeight', 'lineHeight', 'shadow', 'disabledOpacity'];\n // `opacity` is always unitless — match every *Opacity knob (e.g. the\n // per-element `itemDisabledOpacity` / `optionDisabledOpacity` variants)\n // so a saved value never gets a spurious `px` suffix.\n if (unitless.includes(key) || key.endsWith('Opacity')) return String(value);\n return `${value}px`;\n }\n // String style-override values are user/attacker-controlled and persisted\n // to a stylesheet served to every browser session — sanitise the same way\n // as brand token values so one can't break out of the declaration (e.g.\n // `red; } body{display:none}/*`). An unsafe value is dropped to '' rather\n // than throwing, so a single bad override can't blank the whole rule.\n return safeTokenValue(value) ?? '';\n}\n\n// CSS sanitizers — applied to every brand value before interpolation. The\n// output is persisted and served to all browser sessions, so attacker-\n// controlled values must not break out of the declaration they belong to.\nfunction safeUrl(v: unknown): string | undefined {\n if (typeof v !== 'string') return undefined;\n const trimmed = v.trim();\n if (!/^(https?:\\/\\/|\\/)/.test(trimmed)) return undefined;\n if (/[\")\\n\\r]/.test(trimmed)) return undefined;\n return trimmed;\n}\nexport function safeFontFamily(v: unknown): string | undefined {\n if (typeof v !== 'string') return undefined;\n const trimmed = v.trim();\n return /^[A-Za-z0-9 _-]+$/.test(trimmed) ? trimmed : undefined;\n}\n// Heading weight is a closed set (the editor offers exactly these three), so a\n// strict whitelist is both the sanitizer and the contract. Numbers are accepted\n// defensively — a persisted config may carry the JSON number rather than the\n// string the <select> yields.\nexport function safeFontWeight(v: unknown): string | undefined {\n const s = typeof v === 'number' ? String(v) : typeof v === 'string' ? v.trim() : undefined;\n return s !== undefined && /^(500|600|700)$/.test(s) ? s : undefined;\n}\n// Scales multiply a length inside calc(), which makes a bad value far worse\n// than a dropped declaration: `abc` or `1.2px` (length × length) is invalid at\n// computed-value time, so `font-size` resolves to `unset` and INHERITS — one\n// poisoned value on :root collapses the whole app to the parent's size. A\n// plain-number whitelist plus a sane range is the only safe gate; note\n// `safeTokenValue` is NOT sufficient (it passes `abc`, `-1` and unbalanced\n// parens). Range mirrors the editor's slider bounds.\nexport function safeTypeScale(v: unknown): string | undefined {\n const s = typeof v === 'number' ? String(v) : typeof v === 'string' ? v.trim() : undefined;\n if (s === undefined || !/^(?:0|[1-9]\\d?)(?:\\.\\d{1,3})?$/.test(s)) return undefined;\n const n = Number(s);\n return n >= 0.5 && n <= 2 ? s : undefined;\n}\n// Line height is a unitless ratio; same invalid-at-computed-value-time risk as\n// the scales, but it only affects the declarations that read it.\nexport function safeLineHeight(v: unknown): string | undefined {\n const s = typeof v === 'number' ? String(v) : typeof v === 'string' ? v.trim() : undefined;\n if (s === undefined || !/^[1-9](?:\\.\\d{1,2})?$/.test(s)) return undefined;\n const n = Number(s);\n return n >= 1 && n <= 2.5 ? s : undefined;\n}\nexport function safeTokenKey(v: string): boolean {\n return /^--[A-Za-z0-9-]+$/.test(v);\n}\nexport function safeTokenValue(v: unknown): string | undefined {\n if (typeof v !== 'string') return undefined;\n return /[{};\\n\\r]/.test(v) ? undefined : v;\n}\n\n// The three heading roles, in one place. Both the publish path below and the\n// live mirror (`brand-font-styles.tsx`) derive their emitted var names from\n// `role` by interpolation, so a rename here reaches both — keeping these in two\n// hand-maintained lists is how `--type-${role}-font` silently drifts away from\n// the names the stylesheets actually read.\nexport const TYPE_ROLES = [\n { role: 'display', family: 'displayFontFamily', weight: 'displayFontWeight', scale: 'displayScale' },\n { role: 'page-title', family: 'pageTitleFontFamily', weight: 'pageTitleFontWeight', scale: 'pageTitleScale' },\n { role: 'section-title', family: 'sectionTitleFontFamily', weight: 'sectionTitleFontWeight', scale: 'sectionTitleScale' },\n] as const satisfies ReadonlyArray<{\n role: string;\n family: keyof BrandConfig;\n weight: keyof BrandConfig;\n scale: keyof BrandConfig;\n}>;\n\n/** Sanitised per-role typography, shared by the generator and the live mirror. */\nexport function resolveTypeRoles(brand: BrandConfig) {\n return TYPE_ROLES.map((r) => ({\n role: r.role,\n family: safeFontFamily(brand[r.family]),\n weight: safeFontWeight(brand[r.weight]),\n scale: safeTypeScale(brand[r.scale]),\n }));\n}\n\n/** Generate the overrides stylesheet from style overrides + brand config. */\nexport function generateOverridesCss(allOverrides: AllOverrides, brand: BrandConfig): string {\n const lines: string[] = ['/* Auto-generated by UXM — do not edit manually */', ''];\n\n const fontFamily = safeFontFamily(brand.fontFamily);\n const headingFontFamily = safeFontFamily(brand.headingFontFamily);\n const headingFontWeight = safeFontWeight(brand.headingFontWeight);\n // Per-role refinements, layered under the umbrella heading vars above.\n const roles = resolveTypeRoles(brand);\n const typeScale = safeTypeScale(brand.typeScale);\n const bodyLineHeight = safeLineHeight(brand.bodyLineHeight);\n const logoUrl = safeUrl(brand.logoUrl);\n const iconUrl = safeUrl(brand.iconUrl);\n const logoUrlDark = safeUrl(brand.logoUrlDark);\n const iconUrlDark = safeUrl(brand.iconUrlDark);\n\n if (fontFamily) {\n lines.push(`@import url(\"${fontFileUrl(fontFamily)}\");`);\n lines.push('');\n }\n // Second font file only when the heading face is actually a different family\n // — picking the same one for both is a no-op, not a reason to fetch twice.\n if (headingFontFamily && headingFontFamily !== fontFamily) {\n lines.push(`@import url(\"${fontFileUrl(headingFontFamily)}\");`);\n lines.push('');\n }\n // A role may pick a face neither the body nor the umbrella uses — fetch each\n // distinct one exactly once (@import must stay above the rules below).\n const imported = new Set([fontFamily, headingFontFamily].filter(Boolean));\n for (const { family } of roles) {\n if (family && !imported.has(family)) {\n imported.add(family);\n lines.push(`@import url(\"${fontFileUrl(family)}\");`);\n lines.push('');\n }\n }\n\n const brandRules: string[] = [];\n if (fontFamily) {\n brandRules.push(` --brand-font: \"${fontFamily}\", var(--font-inter), system-ui, sans-serif;`);\n }\n // Heading vars are consumed by the components' own two-layer fallbacks (see\n // e.g. page-header.scss), so there is no `body` rule and no `!important`:\n // an unset var simply lets each component's own default paint.\n if (headingFontFamily) {\n brandRules.push(` --brand-heading-font: \"${headingFontFamily}\", var(--font-inter), system-ui, sans-serif;`);\n }\n if (headingFontWeight) {\n brandRules.push(` --brand-heading-weight: ${headingFontWeight};`);\n }\n // Role vars sit between the component var and the umbrella in each atom's\n // chain, so an unset role simply falls through to the umbrella.\n for (const { role, family, weight, scale } of roles) {\n if (family) {\n brandRules.push(` --type-${role}-font: \"${family}\", var(--font-inter), system-ui, sans-serif;`);\n }\n if (weight) brandRules.push(` --type-${role}-weight: ${weight};`);\n if (scale) brandRules.push(` --type-${role}-scale: ${scale};`);\n }\n if (typeScale) brandRules.push(` --type-scale: ${typeScale};`);\n if (bodyLineHeight) brandRules.push(` --type-body-line-height: ${bodyLineHeight};`);\n if (logoUrl) brandRules.push(` --brand-logo-url: url(\"${logoUrl}\");`);\n if (iconUrl) brandRules.push(` --brand-icon-url: url(\"${iconUrl}\");`);\n\n if (brandRules.length > 0) {\n lines.push(':root {');\n lines.push(...brandRules);\n lines.push('}');\n lines.push('');\n if (fontFamily) {\n lines.push('body { font-family: var(--brand-font) !important; }');\n lines.push('');\n }\n // Emitted ONLY when set. The library ships no element-level rules at all,\n // so an unconditional `body { line-height }` would reflow the host's own\n // content — same reasoning as the font-family rule above.\n if (bodyLineHeight) {\n // Explicit fallback: if the var is later cancelled (the studio mirror\n // re-declares it as `initial` on revert) a bare `var()` would be invalid\n // at computed-value time and `line-height` — being inherited — would\n // resolve to the parent's value, silently replacing whatever the host\n // had set on `body`. `normal` makes the wind-down state deliberate.\n lines.push(`body { line-height: var(--type-body-line-height, normal); }`);\n lines.push('');\n }\n }\n\n const darkBrandRules: string[] = [];\n if (logoUrlDark) darkBrandRules.push(` --brand-logo-url: url(\"${logoUrlDark}\");`);\n if (iconUrlDark) darkBrandRules.push(` --brand-icon-url: url(\"${iconUrlDark}\");`);\n if (darkBrandRules.length > 0) {\n lines.push('[data-theme=\"dark\"] {');\n lines.push(...darkBrandRules);\n lines.push('}');\n lines.push('');\n }\n\n const emitTokens = (selector: string, overrides: Record<string, string> | undefined) => {\n if (!overrides) return;\n const safeEntries = Object.entries(overrides).flatMap(([k, v]) => {\n if (!safeTokenKey(k)) return [];\n const safeValue = safeTokenValue(v);\n return safeValue === undefined ? [] : [[k, safeValue] as const];\n });\n if (safeEntries.length === 0) return;\n lines.push(`${selector} {`);\n for (const [cssVar, value] of safeEntries) {\n lines.push(` ${cssVar}: ${value};`);\n }\n lines.push('}');\n lines.push('');\n };\n // Scope customized light-mode color tokens to non-dark. `:root` and\n // `[data-theme=\"dark\"]` carry equal specificity, so an unconditional\n // `:root` block would win over this stylesheet's own dark block for any\n // token NOT also customized for dark (equal specificity, later source\n // order) — pinning that token to its light value in dark mode too. Scoping\n // lets an unset dark token fall through the cascade to tokens/index.css's\n // own `[data-theme=\"dark\"]` default instead.\n emitTokens(':root:not([data-theme=\"dark\"])', brand.tokens?.light);\n emitTokens('[data-theme=\"dark\"]', brand.tokens?.dark);\n\n const componentIds = Object.keys(allOverrides).sort();\n\n for (const id of componentIds) {\n const overrides = allOverrides[id];\n const entries = Object.entries(overrides);\n if (entries.length === 0) continue;\n\n const selector = PER_COMPONENT_SELECTOR[id] ?? `.uxm-${id}`;\n lines.push(`${selector} {`);\n for (const [key, value] of entries) {\n const cssProp = toCSS(key, id);\n const cssValue = formatValue(value, key);\n lines.push(` ${cssProp}: ${cssValue};`);\n }\n lines.push('}');\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/studio/persistence/generate-css.ts"],"sourcesContent":["import type { AllOverrides } from './types';\nimport type { BrandConfig } from '../lib/types';\n\n/**\n * Pure CSS generator for UXM Studio overrides.\n *\n * Single source of truth (R5): the modo Hono `/api/uxm/save` route imports\n * `generateOverridesCss` from here instead of keeping its own copy. No Node\n * APIs — runs in browser (client export) and server alike.\n *\n * Emits a stylesheet from per-component style overrides plus brand config\n * (font, logo/icon URLs, brand token blocks). All attacker-controlled brand\n * values are sanitised before interpolation because the output is served to\n * every browser session.\n */\n\nconst BRAND_FONT_WEIGHTS = 'wght@400;500;600;700';\n\nexport function fontFileUrl(fontFamily: string): string {\n const encoded = fontFamily.trim().replace(/\\s+/g, '+');\n return `https://fonts.googleapis.com/css2?family=${encoded}:${BRAND_FONT_WEIGHTS}&display=swap`;\n}\n\nconst REAL_CSS_PROPS = new Set([\n 'background', 'backgroundColor',\n 'color',\n 'border', 'borderColor', 'borderRadius', 'borderWidth', 'borderStyle',\n 'padding', 'paddingX', 'paddingY', 'margin',\n 'gap', 'rowGap', 'columnGap',\n 'width', 'height', 'minWidth', 'maxWidth', 'minHeight', 'maxHeight',\n 'fontSize', 'fontWeight', 'fontFamily', 'lineHeight',\n 'opacity',\n 'cursor', 'display', 'position', 'overflow', 'direction',\n]);\n\n// Per-component selector overrides for the emitted rule. Defaults to\n// `.uxm-{id}`. Override when the atom renders the styled element via a PORTAL\n// (Listbox / Popover panel mounts to document.body): CSS custom properties\n// cascade DOWN from the declaring element, so vars on the in-page wrapper\n// never reach a portaled descendant. Emit on BOTH wrapper and panel selector.\nconst PER_COMPONENT_SELECTOR: Record<string, string> = {\n listbox: '.uxm-listbox, .uxm-listbox__panel',\n // Menu mirrors Listbox: the `.uxm-menu` wrapper lives in-page around the\n // trigger, but the `.uxm-menu__panel` portals to document.body, so vars on\n // the wrapper never reach it. Emit on both so the panel carries them.\n menu: '.uxm-menu, .uxm-menu__panel',\n // PhoneInput no longer needs a panel-scoped selector: its country picker\n // now delegates to the shared `Listbox`, whose portaled panel already gets\n // its vars via the `listbox` entry above. All `--uxm-phone-input-*` knobs\n // target the in-page field, so the default `.uxm-phone-input` selector is\n // correct.\n};\n\n// One knob → one variable. A multi-target (string[]) form was briefly added so\n// Card's Row Gap could write both the Stack and Cluster gap vars; that was the\n// only use, and it was the wrong shape (see the `card` entry below), so the\n// mapping stays single-target on purpose — a knob that themes a SIBLING atom's\n// var cannot win against that atom's own knob.\nconst PER_COMPONENT_MAPPING: Record<string, Record<string, string>> = {\n 'input-with-icon': {\n backgroundColor: '--uxm-input-with-icon-bg',\n borderColor: '--uxm-input-with-icon-border-color',\n borderRadius: '--uxm-input-with-icon-radius',\n paddingX: '--uxm-input-with-icon-padding-x',\n paddingY: '--uxm-input-with-icon-padding-y',\n fontSize: '--uxm-input-with-icon-font-size',\n color: '--uxm-input-with-icon-color',\n },\n 'input-text': {\n backgroundColor: '--uxm-input-text-bg',\n borderColor: '--uxm-input-text-border-color',\n color: '--uxm-input-text-color',\n borderRadius: '--uxm-input-text-border-radius',\n paddingX: '--uxm-input-text-padding-x',\n paddingY: '--uxm-input-text-padding-y',\n fontSize: '--uxm-input-text-font-size',\n },\n 'number-input': {\n backgroundColor: '--uxm-number-input-bg',\n borderColor: '--uxm-number-input-border-color',\n color: '--uxm-number-input-color',\n borderRadius: '--uxm-number-input-border-radius',\n paddingX: '--uxm-number-input-padding-x',\n paddingY: '--uxm-number-input-padding-y',\n fontSize: '--uxm-number-input-font-size',\n },\n // Every key below collides with REAL_CSS_PROPS. The atom passes its class to\n // `Listbox`, so the emitted rule lands on that in-page ROOT while the styled\n // element is the `__trigger` child, which declares its own `color`,\n // `border-color`, `font-size` and `gap` from `--uxm-language-switcher-*` and\n // therefore beats anything inherited — every one of these would be a silent\n // no-op. Padding is worse: `padding-inline` on the root pads OUTSIDE the\n // button while the trigger keeps its default 10px/7px.\n 'language-switcher': {\n color: '--uxm-language-switcher-color',\n borderColor: '--uxm-language-switcher-border-color',\n fontSize: '--uxm-language-switcher-font-size',\n gap: '--uxm-language-switcher-gap',\n paddingX: '--uxm-language-switcher-padding-x',\n paddingY: '--uxm-language-switcher-padding-y',\n },\n // Without this entry `fontSize` falls through REAL_CSS_PROPS and emits a\n // literal `font-size` on `.uxm-color-input`, which the atom's own children\n // (`__value-field`, `__format`) always beat — so the knob did nothing at all.\n 'color-input': {\n fontSize: '--uxm-color-input-font-size',\n },\n // Every key here collides with REAL_CSS_PROPS, where the generic fallback\n // emits a REAL property on `.uxm-code-editor` instead of a var. That root is\n // pure chrome — the text lives in `__input` / `__gutter-lines`, which declare\n // their own `color` / `font-size` / `line-height` and always beat inherited\n // values, so Text / Font Size / Line Height would be silent no-ops. Padding is\n // worse than a no-op: `padding-inline` on the root pads OUTSIDE the code while\n // `--uxm-code-editor-padding-x` stays unset, so the gutter's absolutely\n // positioned `left` keeps its 14px default and the numbers leave their column.\n // Same defect as the `color-input` entry above.\n 'code-editor': {\n backgroundColor: '--uxm-code-editor-bg',\n borderColor: '--uxm-code-editor-border-color',\n color: '--uxm-code-editor-color',\n borderRadius: '--uxm-code-editor-border-radius',\n paddingX: '--uxm-code-editor-padding-x',\n paddingY: '--uxm-code-editor-padding-y',\n fontSize: '--uxm-code-editor-font-size',\n lineHeight: '--uxm-code-editor-line-height',\n minHeight: '--uxm-code-editor-min-height',\n },\n 'currency-input': {\n backgroundColor: '--uxm-currency-input-background-color',\n borderColor: '--uxm-currency-input-border-color',\n borderRadius: '--uxm-currency-input-border-radius',\n paddingX: '--uxm-currency-input-padding-x',\n paddingY: '--uxm-currency-input-padding-y',\n fontSize: '--uxm-currency-input-font-size',\n color: '--uxm-currency-input-color',\n },\n textarea: {\n backgroundColor: '--uxm-textarea-bg',\n borderColor: '--uxm-textarea-border-color',\n color: '--uxm-textarea-color',\n minHeight: '--uxm-textarea-min-height',\n borderRadius: '--uxm-textarea-border-radius',\n paddingX: '--uxm-textarea-padding-x',\n paddingY: '--uxm-textarea-padding-y',\n fontSize: '--uxm-textarea-font-size',\n },\n 'file-upload': {\n backgroundColor: '--uxm-file-upload-bg',\n borderColor: '--uxm-file-upload-border-color',\n color: '--uxm-file-upload-color',\n borderRadius: '--uxm-file-upload-border-radius',\n borderStyle: '--uxm-file-upload-border-style',\n borderWidth: '--uxm-file-upload-border-width',\n paddingX: '--uxm-file-upload-padding-x',\n paddingY: '--uxm-file-upload-padding-y',\n minHeight: '--uxm-file-upload-min-height',\n gap: '--uxm-file-upload-gap',\n rowGap: '--uxm-file-upload-row-gap',\n },\n 'select-dropdown': {\n backgroundColor: '--uxm-select-dropdown-bg',\n borderColor: '--uxm-select-dropdown-border-color',\n color: '--uxm-select-dropdown-color',\n borderRadius: '--uxm-select-dropdown-border-radius',\n paddingX: '--uxm-select-dropdown-padding-x',\n paddingY: '--uxm-select-dropdown-padding-y',\n fontSize: '--uxm-select-dropdown-font-size',\n },\n 'date-input': {\n backgroundColor: '--uxm-date-input-background-color',\n borderColor: '--uxm-date-input-border-color',\n borderRadius: '--uxm-date-input-border-radius',\n paddingX: '--uxm-date-input-padding-x',\n paddingY: '--uxm-date-input-padding-y',\n fontSize: '--uxm-date-input-font-size',\n color: '--uxm-date-input-color',\n },\n 'password-input': {\n backgroundColor: '--uxm-password-input-background-color',\n borderColor: '--uxm-password-input-border-color',\n borderRadius: '--uxm-password-input-border-radius',\n paddingX: '--uxm-password-input-padding-x',\n paddingY: '--uxm-password-input-padding-y',\n fontSize: '--uxm-password-input-font-size',\n color: '--uxm-password-input-color',\n },\n 'time-input': {\n backgroundColor: '--uxm-time-input-background-color',\n borderColor: '--uxm-time-input-border-color',\n borderRadius: '--uxm-time-input-border-radius',\n paddingX: '--uxm-time-input-padding-x',\n paddingY: '--uxm-time-input-padding-y',\n fontSize: '--uxm-time-input-font-size',\n color: '--uxm-time-input-color',\n },\n 'phone-input': {\n backgroundColor: '--uxm-phone-input-background-color',\n borderColor: '--uxm-phone-input-border-color',\n borderRadius: '--uxm-phone-input-border-radius',\n paddingX: '--uxm-phone-input-padding-x',\n paddingY: '--uxm-phone-input-padding-y',\n fontSize: '--uxm-phone-input-font-size',\n color: '--uxm-phone-input-color',\n },\n calendar: {\n backgroundColor: '--uxm-calendar-background-color',\n borderColor: '--uxm-calendar-border-color',\n borderRadius: '--uxm-calendar-border-radius',\n padding: '--uxm-calendar-padding',\n },\n tabs: {\n gap: '--uxm-tabs-gap',\n paddingX: '--uxm-tabs-padding-x',\n paddingY: '--uxm-tabs-padding-y',\n fontSize: '--uxm-tabs-font-size',\n fontWeight: '--uxm-tabs-font-weight',\n },\n 'tabs-underline': {\n gap: '--uxm-tabs-underline-gap',\n paddingX: '--uxm-tabs-underline-padding-x',\n paddingY: '--uxm-tabs-underline-padding-y',\n fontSize: '--uxm-tabs-underline-font-size',\n fontWeight: '--uxm-tabs-underline-font-weight',\n },\n 'filter-tabs': {\n gap: '--uxm-filter-tabs-gap',\n paddingX: '--uxm-filter-tabs-padding-x',\n paddingY: '--uxm-filter-tabs-padding-y',\n fontSize: '--uxm-filter-tabs-font-size',\n fontWeight: '--uxm-filter-tabs-font-weight',\n },\n 'view-switcher': {\n gap: '--uxm-view-switcher-gap',\n },\n 'button-group': {\n borderColor: '--uxm-button-group-border-color',\n borderRadius: '--uxm-button-group-border-radius',\n paddingX: '--uxm-button-group-padding-x',\n paddingY: '--uxm-button-group-padding-y',\n fontSize: '--uxm-button-group-font-size',\n },\n checkbox: {\n borderRadius: '--uxm-checkbox-border-radius',\n gap: '--uxm-checkbox-gap',\n },\n card: {\n backgroundColor: '--uxm-card-bg',\n borderColor: '--uxm-card-border-color',\n borderRadius: '--uxm-card-radius',\n padding: '--uxm-card-padding',\n // `gap` (\"Header Gap\") collides with REAL_CSS_PROPS — the generic fallback\n // would emit a literal `gap` property that `.uxm-card` never activates (the\n // card is only a flex column via the `--gap` modifier). Route it to the var\n // the modifier actually reads.\n //\n // There is deliberately NO Card knob for the CONTENT's row gap. It looks\n // like it belongs here, but the row gap is owned by the nested Stack /\n // Cluster, which already have their own Gap knobs — and those emit\n // `--uxm-stack-gap` DIRECTLY on `.uxm-stack`, where a directly-set custom\n // property always beats one inherited from `.uxm-card`. A Card-side knob\n // would therefore lose the moment anyone themed Stack, while also leaking\n // to every Stack/Cluster at any depth inside any card (custom properties\n // inherit). One owner per visual property; Card owns only its own gap.\n gap: '--uxm-card-gap',\n },\n 'toggle-switch': {\n width: '--uxm-toggle-switch-width',\n height: '--uxm-toggle-switch-height',\n },\n 'radio-group': {\n gap: '--uxm-radio-group-gap',\n },\n loader: {\n color: '--uxm-loader-color',\n gap: '--uxm-loader-gap',\n },\n 'data-table': {\n borderColor: '--uxm-data-table-border-color',\n fontSize: '--uxm-data-table-font-size',\n borderRadius: '--uxm-data-table-border-radius',\n },\n 'app-sidebar': {\n borderColor: '--uxm-app-sidebar-border-color',\n backgroundColor: '--uxm-app-sidebar-background-color',\n },\n // Every key here collides with REAL_CSS_PROPS, where the generic fallback\n // emits the LITERAL css property on the root selector instead of the var.\n //\n // For `fontSize` / `fontWeight` that is a silent no-op rather than a mere\n // detour: the atom reads those vars on `.uxm-sidebar-nav-trigger__value`, and\n // a `font-size` landing on the root is beaten by the child's own declaration.\n // The live workbench hides it — that path projects custom properties through\n // the preview's `buildVars`, so the knob only dies once a brand is SAVED.\n //\n // The rest (padding, gap, radius) do sit on the root and would survive the\n // literal route on source order alone, but they are mapped too: the sibling\n // `sidebar-nav-item` maps all six, and leaving half of them to cascade luck\n // invites exactly the question of which half.\n 'sidebar-nav-trigger': {\n paddingX: '--uxm-sidebar-nav-trigger-padding-x',\n paddingY: '--uxm-sidebar-nav-trigger-padding-y',\n fontSize: '--uxm-sidebar-nav-trigger-font-size',\n fontWeight: '--uxm-sidebar-nav-trigger-font-weight',\n gap: '--uxm-sidebar-nav-trigger-gap',\n borderRadius: '--uxm-sidebar-nav-trigger-border-radius',\n },\n 'sidebar-nav-item': {\n paddingX: '--uxm-sidebar-nav-item-padding-x',\n paddingY: '--uxm-sidebar-nav-item-padding-y',\n fontSize: '--uxm-sidebar-nav-item-font-size',\n fontWeight: '--uxm-sidebar-nav-item-font-weight',\n gap: '--uxm-sidebar-nav-item-gap',\n borderRadius: '--uxm-sidebar-nav-item-border-radius',\n },\n 'explorer-list-item': {\n paddingX: '--uxm-explorer-list-item-padding-x',\n paddingY: '--uxm-explorer-list-item-padding-y',\n fontSize: '--uxm-explorer-list-item-font-size',\n fontWeight: '--uxm-explorer-list-item-font-weight',\n gap: '--uxm-explorer-list-item-gap',\n borderRadius: '--uxm-explorer-list-item-border-radius',\n },\n 'app-top-bar': {\n borderColor: '--uxm-app-top-bar-border-color',\n backgroundColor: '--uxm-app-top-bar-background-color',\n height: '--uxm-app-top-bar-height',\n paddingX: '--uxm-app-top-bar-padding-x',\n gap: '--uxm-app-top-bar-gap',\n },\n 'explorer-section': {\n paddingX: '--uxm-explorer-section-padding-x',\n paddingY: '--uxm-explorer-section-padding-y',\n borderRadius: '--uxm-explorer-section-border-radius',\n gap: '--uxm-explorer-section-gap',\n fontSize: '--uxm-explorer-section-font-size',\n fontWeight: '--uxm-explorer-section-font-weight',\n },\n 'number-field': {\n backgroundColor: '--uxm-number-field-input-bg',\n borderColor: '--uxm-number-field-input-border',\n color: '--uxm-number-field-input-color',\n borderRadius: '--uxm-number-field-input-radius',\n paddingX: '--uxm-number-field-input-padding-x',\n paddingY: '--uxm-number-field-input-padding-y',\n fontSize: '--uxm-number-field-font-size',\n gap: '--uxm-number-field-gap',\n },\n 'icon-button': {\n color: '--uxm-icon-button-color',\n backgroundColor: '--uxm-icon-button-bg',\n hoverBackgroundColor: '--uxm-icon-button-hover-bg',\n activeBackgroundColor: '--uxm-icon-button-active-bg',\n borderRadius: '--uxm-icon-button-radius',\n },\n 'button-primary': {\n backgroundColor: '--uxm-button-primary-background-color',\n color: '--uxm-button-primary-color',\n borderRadius: '--uxm-button-primary-border-radius',\n fontSize: '--uxm-button-primary-font-size',\n fontWeight: '--uxm-button-primary-font-weight',\n paddingX: '--uxm-button-primary-padding-x',\n paddingY: '--uxm-button-primary-padding-y',\n },\n 'button-secondary': {\n backgroundColor: '--uxm-button-secondary-background-color',\n color: '--uxm-button-secondary-color',\n borderColor: '--uxm-button-secondary-border-color',\n borderRadius: '--uxm-button-secondary-border-radius',\n fontSize: '--uxm-button-secondary-font-size',\n fontWeight: '--uxm-button-secondary-font-weight',\n paddingX: '--uxm-button-secondary-padding-x',\n paddingY: '--uxm-button-secondary-padding-y',\n },\n 'button-tertiary': {\n backgroundColor: '--uxm-button-tertiary-background-color',\n color: '--uxm-button-tertiary-color',\n borderColor: '--uxm-button-tertiary-border-color',\n borderRadius: '--uxm-button-tertiary-border-radius',\n fontSize: '--uxm-button-tertiary-font-size',\n fontWeight: '--uxm-button-tertiary-font-weight',\n paddingX: '--uxm-button-tertiary-padding-x',\n paddingY: '--uxm-button-tertiary-padding-y',\n },\n 'button-ghost': {\n backgroundColor: '--uxm-button-ghost-background-color',\n color: '--uxm-button-ghost-color',\n borderRadius: '--uxm-button-ghost-border-radius',\n fontSize: '--uxm-button-ghost-font-size',\n fontWeight: '--uxm-button-ghost-font-weight',\n paddingX: '--uxm-button-ghost-padding-x',\n paddingY: '--uxm-button-ghost-padding-y',\n },\n 'button-danger': {\n backgroundColor: '--uxm-button-danger-background-color',\n color: '--uxm-button-danger-color',\n borderColor: '--uxm-button-danger-border-color',\n borderRadius: '--uxm-button-danger-border-radius',\n fontSize: '--uxm-button-danger-font-size',\n fontWeight: '--uxm-button-danger-font-weight',\n paddingX: '--uxm-button-danger-padding-x',\n paddingY: '--uxm-button-danger-padding-y',\n },\n 'button-with-icon': {\n backgroundColor: '--uxm-button-with-icon-background-color',\n color: '--uxm-button-with-icon-color',\n borderColor: '--uxm-button-with-icon-border-color',\n borderRadius: '--uxm-button-with-icon-border-radius',\n fontSize: '--uxm-button-with-icon-font-size',\n fontWeight: '--uxm-button-with-icon-font-weight',\n paddingX: '--uxm-button-with-icon-padding-x',\n paddingY: '--uxm-button-with-icon-padding-y',\n },\n 'button-icon': {\n backgroundColor: '--uxm-button-icon-background-color',\n color: '--uxm-button-icon-color',\n borderRadius: '--uxm-button-icon-border-radius',\n },\n 'back-link': {\n color: '--uxm-back-link-color',\n fontSize: '--uxm-back-link-font-size',\n fontWeight: '--uxm-back-link-font-weight',\n gap: '--uxm-back-link-gap',\n },\n breadcrumb: {\n fontSize: '--uxm-breadcrumb-font-size',\n gap: '--uxm-breadcrumb-gap',\n },\n disclosure: {\n paddingX: '--uxm-disclosure-padding-x',\n paddingY: '--uxm-disclosure-padding-y',\n fontSize: '--uxm-disclosure-font-size',\n gap: '--uxm-disclosure-gap',\n borderRadius: '--uxm-disclosure-border-radius',\n },\n 'side-flexpane': {\n paddingX: '--uxm-side-flexpane-padding-x',\n paddingY: '--uxm-side-flexpane-padding-y',\n backgroundColor: '--uxm-side-flexpane-background-color',\n borderColor: '--uxm-side-flexpane-border-color',\n borderRadius: '--uxm-side-flexpane-border-radius',\n width: '--uxm-side-flexpane-width',\n },\n 'list-item': {\n paddingX: '--uxm-list-item-padding-x',\n paddingY: '--uxm-list-item-padding-y',\n fontSize: '--uxm-list-item-font-size',\n gap: '--uxm-list-item-gap',\n borderRadius: '--uxm-list-item-border-radius',\n borderColor: '--uxm-list-item-border-color',\n },\n 'pill-select': {\n backgroundColor: '--uxm-pill-select-bg',\n borderColor: '--uxm-pill-select-border-color',\n paddingX: '--uxm-pill-select-padding-x',\n paddingY: '--uxm-pill-select-padding-y',\n },\n modal: {\n backgroundColor: '--uxm-modal-background-color',\n borderColor: '--uxm-modal-border-color',\n borderRadius: '--uxm-modal-border-radius',\n paddingX: '--uxm-modal-padding-x',\n paddingY: '--uxm-modal-padding-y',\n },\n toast: {\n backgroundColor: '--uxm-toast-background-color',\n color: '--uxm-toast-color',\n borderColor: '--uxm-toast-border-color',\n borderRadius: '--uxm-toast-border-radius',\n paddingX: '--uxm-toast-padding-x',\n paddingY: '--uxm-toast-padding-y',\n fontSize: '--uxm-toast-font-size',\n },\n avatar: {\n backgroundColor: '--uxm-avatar-background-color',\n borderColor: '--uxm-avatar-border-color',\n borderRadius: '--uxm-avatar-border-radius',\n borderWidth: '--uxm-avatar-border-width',\n color: '--uxm-avatar-color',\n fontSize: '--uxm-avatar-font-size',\n fontWeight: '--uxm-avatar-font-weight',\n },\n banner: {\n borderRadius: '--uxm-banner-border-radius',\n paddingX: '--uxm-banner-padding-x',\n paddingY: '--uxm-banner-padding-y',\n fontSize: '--uxm-banner-font-size',\n },\n 'bulk-action-bar': {\n backgroundColor: '--uxm-bulk-action-bar-background-color',\n color: '--uxm-bulk-action-bar-color',\n borderColor: '--uxm-bulk-action-bar-border-color',\n borderRadius: '--uxm-bulk-action-bar-border-radius',\n paddingX: '--uxm-bulk-action-bar-padding-x',\n paddingY: '--uxm-bulk-action-bar-padding-y',\n gap: '--uxm-bulk-action-bar-gap',\n fontSize: '--uxm-bulk-action-bar-font-size',\n },\n cluster: {\n gap: '--uxm-cluster-gap',\n },\n 'config-component-row': {\n padding: '--uxm-config-component-row-padding',\n borderRadius: '--uxm-config-component-row-radius',\n },\n 'config-segment-item': {\n paddingX: '--uxm-config-segment-item-padding-x',\n paddingY: '--uxm-config-segment-item-padding-y',\n borderRadius: '--uxm-config-segment-item-radius',\n },\n 'detail-section': {\n backgroundColor: '--uxm-detail-section-bg',\n borderColor: '--uxm-detail-section-border-color',\n borderRadius: '--uxm-detail-section-radius',\n padding: '--uxm-detail-section-padding',\n },\n divider: {\n color: '--uxm-divider-color',\n gap: '--uxm-divider-gap',\n },\n 'editable-cell': {\n // Dimensions are per-size keys (smallPaddingX, mediumMaxWidth, …) that\n // resolve via the generic `--uxm-editable-cell-{kebab(key)}` fallback in\n // toCSS; only the value colour needs an explicit entry (`color` is in\n // REAL_CSS_PROPS, so the fallback would emit a real CSS property that\n // outranks the component layer).\n color: '--uxm-editable-cell-color',\n // RETIRED knobs, kept mapped on purpose. The per-size split replaced these\n // four, but `generateOverridesCss` emits whatever keys are PERSISTED — not\n // what the registry currently declares — so a config saved before the split\n // still carries them. Without an entry here they'd fall through to\n // REAL_CSS_PROPS / the paddingX-paddingY special case in toCSS and emit\n // REAL `min-height` / `padding-inline` / `padding-block` declarations on\n // `.uxm-editable-cell`, which land in a sheet loaded after the library CSS\n // and would hard-override BOTH size presets (killing `medium`) and\n // resurrect the min-height the size work deliberately removed. Mapped to\n // their old, now-unread custom properties they are true no-ops instead.\n // Safe to delete once persisted overrides are pruned against the registry.\n minHeight: '--uxm-editable-cell-min-height',\n paddingX: '--uxm-editable-cell-padding-x',\n paddingY: '--uxm-editable-cell-padding-y',\n // `maxWidth` joined them when the cap went per-size: it is in\n // REAL_CSS_PROPS, so without this it would emit a real `max-width` that\n // pins BOTH presets (and would silently re-cap `medium`, whose whole point\n // is filling its container).\n maxWidth: '--uxm-editable-cell-max-width',\n },\n 'empty-state': {\n padding: '--uxm-empty-state-padding',\n },\n 'form-field': {\n gap: '--uxm-form-field-gap',\n // Per-tint label colours — the component reads `--uxm-form-field-label-\n // tint-*` (see form-field.scss tone classes); the generic kebab fallback\n // would emit `--uxm-form-field-tint-strong-color` etc., which nothing\n // reads, so the saved colour would silently not apply.\n tintStrongColor: '--uxm-form-field-label-tint-strong',\n tintDefaultColor: '--uxm-form-field-label-tint-default',\n tintMutedColor: '--uxm-form-field-label-tint-muted',\n // MIGRATION — `labelColor` was the single label-colour knob the tints\n // replaced. It is gone from the registry, but `generateOverridesCss` emits\n // whatever is PERSISTED, and its generic fallback lands on\n // `--uxm-form-field-label-color` — the very var the tint classes assign,\n // at equal specificity from a later sheet. Left alone it would beat ALL\n // THREE tints and silently disable them, with no knob left in the panel to\n // notice or clear it. Routed to the STRONG tint instead: strong was the\n // old (only) label colour and is still the default tone, so a pre-split\n // theme keeps the exact look it saved. A newly-saved `tintStrongColor`\n // still wins — overrides are appended, so it emits after this one.\n labelColor: '--uxm-form-field-label-tint-strong',\n },\n 'icon-tile': {\n borderRadius: '--uxm-icon-tile-radius',\n iconBg: '--uxm-icon-tile-bg',\n iconColor: '--uxm-icon-tile-color',\n },\n icon: {\n color: '--uxm-icon-color',\n },\n 'inline-action': {\n color: '--uxm-inline-action-color',\n fontSize: '--uxm-inline-action-font-size',\n fontWeight: '--uxm-inline-action-font-weight',\n gap: '--uxm-inline-action-gap',\n },\n 'inline-filter': {\n gap: '--uxm-inline-filter-gap',\n },\n 'lifecycle-edge-label': {\n paddingX: '--uxm-lifecycle-edge-label-padding-x',\n paddingY: '--uxm-lifecycle-edge-label-padding-y',\n borderRadius: '--uxm-lifecycle-edge-label-radius',\n borderWidth: '--uxm-lifecycle-edge-label-border-width',\n fontSize: '--uxm-lifecycle-edge-label-font-size',\n fontWeight: '--uxm-lifecycle-edge-label-font-weight',\n },\n // Same rule as lifecycle-group-box below — only the REAL_CSS_PROPS collisions\n // need an entry. `color` is the one that matters: a real `color` declaration\n // on `.uxm-lifecycle-drop-slot` from a later sheet would paint the text but\n // leave the dashes on the token, splitting a pair the atom deliberately drives\n // from one variable. The shape-scoped knobs (`cardRadius`, `pillFontSize`, …)\n // and `bg` need nothing: the generic `--uxm-{id}-{kebab}` rule already lands\n // on the names the stylesheet reads.\n 'lifecycle-drop-slot': {\n borderColor: '--uxm-lifecycle-drop-slot-border-color',\n borderStyle: '--uxm-lifecycle-drop-slot-border-style',\n borderWidth: '--uxm-lifecycle-drop-slot-border-width',\n color: '--uxm-lifecycle-drop-slot-color',\n },\n // Only the knobs whose keys collide with REAL_CSS_PROPS need an entry: left\n // to the generic path they'd emit a real `background-color` / `border-width` /\n // `padding` on `.uxm-lifecycle-group-box` from a later sheet, hard-overriding\n // the rule's own `var(--uxm-… , token)` chain — and `padding` is read BY THE\n // CONSUMER off the custom property to inset the group's members, so a real\n // declaration would leave that value unreadable.\n //\n // `blur` and the three `target*` knobs are absent on purpose: the generic\n // `--uxm-{id}-{kebab}` rule already lands on the names the stylesheet reads.\n 'lifecycle-group-box': {\n backgroundColor: '--uxm-lifecycle-group-box-bg',\n borderColor: '--uxm-lifecycle-group-box-border-color',\n borderWidth: '--uxm-lifecycle-group-box-border-width',\n borderRadius: '--uxm-lifecycle-group-box-radius',\n padding: '--uxm-lifecycle-group-box-padding',\n },\n 'lifecycle-minimap': {\n backgroundColor: '--uxm-lifecycle-minimap-bg',\n borderColor: '--uxm-lifecycle-minimap-border-color',\n borderRadius: '--uxm-lifecycle-minimap-radius',\n width: '--uxm-lifecycle-minimap-width',\n height: '--uxm-lifecycle-minimap-height',\n },\n 'lifecycle-node-card': {\n backgroundColor: '--uxm-lifecycle-node-card-bg',\n borderColor: '--uxm-lifecycle-node-card-border-color',\n borderRadius: '--uxm-lifecycle-node-card-radius',\n paddingX: '--uxm-lifecycle-node-card-padding-x',\n paddingY: '--uxm-lifecycle-node-card-padding-y',\n width: '--uxm-lifecycle-node-card-width',\n minHeight: '--uxm-lifecycle-node-card-min-height',\n },\n 'lifecycle-terminal': {\n backgroundColor: '--uxm-lifecycle-terminal-bg',\n borderColor: '--uxm-lifecycle-terminal-border-color',\n color: '--uxm-lifecycle-terminal-color',\n borderRadius: '--uxm-lifecycle-terminal-radius',\n width: '--uxm-lifecycle-terminal-width',\n height: '--uxm-lifecycle-terminal-height',\n fontSize: '--uxm-lifecycle-terminal-font-size',\n fontWeight: '--uxm-lifecycle-terminal-font-weight',\n },\n 'lifecycle-zoom-control': {\n backgroundColor: '--uxm-lifecycle-zoom-bg',\n borderColor: '--uxm-lifecycle-zoom-border-color',\n borderRadius: '--uxm-lifecycle-zoom-radius',\n fontSize: '--uxm-lifecycle-zoom-font-size',\n color: '--uxm-lifecycle-zoom-color',\n buttonSize: '--uxm-lifecycle-zoom-button-size',\n iconColor: '--uxm-lifecycle-zoom-icon-color',\n },\n link: {\n fontSize: '--uxm-link-font-size',\n fontWeight: '--uxm-link-font-weight',\n },\n 'meta-row': {\n fontSize: '--uxm-meta-row-font-size',\n color: '--uxm-meta-row-color',\n gap: '--uxm-meta-row-gap',\n },\n 'number-stepper': {\n backgroundColor: '--uxm-number-stepper-input-bg',\n borderColor: '--uxm-number-stepper-input-border',\n color: '--uxm-number-stepper-input-color',\n borderRadius: '--uxm-number-stepper-input-radius',\n paddingX: '--uxm-number-stepper-input-padding-x',\n paddingY: '--uxm-number-stepper-input-padding-y',\n fontSize: '--uxm-number-stepper-font-size',\n gap: '--uxm-number-stepper-gap',\n },\n 'page-header': {\n gap: '--uxm-page-header-gap',\n paddingX: '--uxm-page-header-padding-x',\n paddingY: '--uxm-page-header-padding-y',\n },\n 'page-shell': {\n backgroundColor: '--uxm-page-shell-bg',\n },\n 'property-field': {\n gap: '--uxm-property-field-gap',\n },\n 'property-grid': {\n rowGap: '--uxm-property-grid-row-gap',\n columnGap: '--uxm-property-grid-column-gap',\n },\n 'responsive-grid': {\n gap: '--uxm-responsive-grid-gap',\n },\n 'section-header': {\n gap: '--uxm-section-header-gap',\n },\n stack: {\n gap: '--uxm-stack-gap',\n },\n 'stat-card': {\n backgroundColor: '--uxm-stat-card-background-color',\n borderColor: '--uxm-stat-card-border-color',\n borderRadius: '--uxm-stat-card-border-radius',\n padding: '--uxm-stat-card-padding',\n },\n tag: {\n borderRadius: '--uxm-tag-border-radius',\n fontWeight: '--uxm-tag-font-weight',\n },\n thumbnail: {\n borderRadius: '--uxm-thumbnail-border-radius',\n backgroundColor: '--uxm-thumbnail-background-color',\n borderColor: '--uxm-thumbnail-border-color',\n borderWidth: '--uxm-thumbnail-border-width',\n },\n 'timeline-entry': {\n gap: '--uxm-timeline-entry-gap',\n },\n 'segment-row': {\n paddingX: '--uxm-segment-row-padding-x',\n paddingY: '--uxm-segment-row-padding-y',\n gap: '--uxm-segment-row-gap',\n dragColor: '--uxm-segment-row-drag-color',\n dragHoverColor: '--uxm-segment-row-drag-hover-color',\n chevronColor: '--uxm-segment-row-chevron-color',\n chevronSize: '--uxm-segment-row-chevron-size',\n accentColor: '--uxm-segment-row-accent-color',\n accentWidth: '--uxm-segment-row-accent-width',\n accentRadius: '--uxm-segment-row-accent-radius',\n titleColor: '--uxm-segment-row-title-color',\n titleSize: '--uxm-segment-row-title-size',\n titleWeight: '--uxm-segment-row-title-weight',\n countBg: '--uxm-segment-row-count-bg',\n countColor: '--uxm-segment-row-count-color',\n countSize: '--uxm-segment-row-count-size',\n countPaddingX: '--uxm-segment-row-count-padding-x',\n countPaddingY: '--uxm-segment-row-count-padding-y',\n countRadius: '--uxm-segment-row-count-radius',\n rowHoverBg: '--uxm-segment-row-row-hover-bg',\n rowHoverRadius: '--uxm-segment-row-row-hover-radius',\n },\n 'segment-card': {\n borderColor: '--uxm-segment-card-border-color',\n borderWidth: '--uxm-segment-card-border-width',\n borderRadius: '--uxm-segment-card-border-radius',\n backgroundColor: '--uxm-segment-card-background',\n paddingX: '--uxm-segment-card-padding-x',\n paddingY: '--uxm-segment-card-padding-y',\n childrenInsetX: '--uxm-segment-card-children-inset-x',\n childrenInsetY: '--uxm-segment-card-children-inset-y',\n childrenGap: '--uxm-segment-card-children-gap',\n dividerColor: '--uxm-segment-card-divider-color',\n dividerWidth: '--uxm-segment-card-divider-width',\n },\n 'component-row': {\n paddingX: '--uxm-component-row-padding-x',\n paddingY: '--uxm-component-row-padding-y',\n gap: '--uxm-component-row-gap',\n backgroundColor: '--uxm-component-row-background',\n dragColor: '--uxm-component-row-drag-color',\n dragHoverColor: '--uxm-component-row-drag-hover-color',\n iconBadgeSize: '--uxm-component-row-icon-badge-size',\n iconBadgeRadius: '--uxm-component-row-icon-badge-radius',\n iconBadgePadding: '--uxm-component-row-icon-badge-padding',\n nameColor: '--uxm-component-row-name-color',\n nameSize: '--uxm-component-row-name-size',\n nameWeight: '--uxm-component-row-name-weight',\n typeLabelColor: '--uxm-component-row-type-label-color',\n typeLabelSize: '--uxm-component-row-type-label-size',\n typeLabelWeight: '--uxm-component-row-type-label-weight',\n chevronColor: '--uxm-component-row-chevron-color',\n chevronSize: '--uxm-component-row-chevron-size',\n rowHoverBg: '--uxm-component-row-row-hover-bg',\n rowHoverRadius: '--uxm-component-row-row-hover-radius',\n },\n 'option-list': {\n indent: '--uxm-option-list-indent',\n backgroundColor: '--uxm-option-list-background',\n borderColor: '--uxm-option-list-border-color',\n borderWidth: '--uxm-option-list-border-width',\n borderRadius: '--uxm-option-list-border-radius',\n paddingX: '--uxm-option-list-padding-x',\n paddingY: '--uxm-option-list-padding-y',\n gap: '--uxm-option-list-gap',\n rowPaddingX: '--uxm-option-list-row-padding-x',\n rowPaddingY: '--uxm-option-list-row-padding-y',\n dragColor: '--uxm-option-list-drag-color',\n dragHoverColor: '--uxm-option-list-drag-hover-color',\n bulletSize: '--uxm-option-list-bullet-size',\n bulletGap: '--uxm-option-list-bullet-gap',\n nameColor: '--uxm-option-list-name-color',\n nameSize: '--uxm-option-list-name-size',\n nameWeight: '--uxm-option-list-name-weight',\n rowHoverBg: '--uxm-option-list-row-hover-bg',\n rowHoverRadius: '--uxm-option-list-row-hover-radius',\n },\n tooltip: {\n backgroundColor: '--uxm-tooltip-background-color',\n color: '--uxm-tooltip-color',\n borderRadius: '--uxm-tooltip-border-radius',\n paddingX: '--uxm-tooltip-padding-x',\n paddingY: '--uxm-tooltip-padding-y',\n fontSize: '--uxm-tooltip-font-size',\n },\n 'content-tooltip': {\n backgroundColor: '--uxm-content-tooltip-background-color',\n borderColor: '--uxm-content-tooltip-border-color',\n borderRadius: '--uxm-content-tooltip-border-radius',\n padding: '--uxm-content-tooltip-padding',\n maxWidth: '--uxm-content-tooltip-max-width',\n },\n 'type-overview-card': {\n backgroundColor: '--uxm-typeoverview-bg',\n borderColor: '--uxm-typeoverview-border-color',\n borderRadius: '--uxm-typeoverview-radius',\n padding: '--uxm-typeoverview-padding',\n accentColor: '--uxm-typeoverview-accent-color',\n accentWidth: '--uxm-typeoverview-accent-width',\n iconBg: '--uxm-typeoverview-icon-bg',\n iconColor: '--uxm-typeoverview-icon-color',\n iconBoxSize: '--uxm-typeoverview-icon-tile-size',\n iconRadius: '--uxm-typeoverview-icon-tile-radius',\n labelSize: '--uxm-typeoverview-label-size',\n labelColor: '--uxm-typeoverview-label-color',\n valueSize: '--uxm-typeoverview-value-size',\n valueColor: '--uxm-typeoverview-value-color',\n },\n // Without an entry here every knob would fall through to the generic\n // `--uxm-{id}-{kebab}` rule and double the segment — `connectorIdleColor`\n // under id `lifecycle-connector` becomes\n // `--uxm-lifecycle-connector-connector-idle-color`. The stylesheet reads the\n // canonical single-`connector` names (and still accepts the doubled ones as\n // a fallback alias), so map the knobs explicitly.\n //\n // `connectorArrowSize` sizes an SVG polygon rather than setting any CSS\n // property, so no rule can consume it — `useThemedArrowSize` in\n // lifecycle-connector.tsx reads `--uxm-lifecycle-connector-arrow-size` back\n // off the element instead. It is published here for that reason, not for\n // naming tidiness: drop this line and a saved Arrow Size stops applying.\n 'lifecycle-connector': {\n connectorIdleColor: '--uxm-lifecycle-connector-idle-color',\n connectorActiveColor: '--uxm-lifecycle-connector-active-color',\n connectorIdleStrokeWidth: '--uxm-lifecycle-connector-idle-stroke-width',\n connectorActiveStrokeWidth: '--uxm-lifecycle-connector-active-stroke-width',\n connectorDashedColor: '--uxm-lifecycle-connector-dashed-color',\n connectorDashedStrokeWidth: '--uxm-lifecycle-connector-dashed-stroke-width',\n connectorDashPattern: '--uxm-lifecycle-connector-dash-pattern',\n connectorArrowSize: '--uxm-lifecycle-connector-arrow-size',\n },\n};\n\nfunction toCSS(key: string, componentId: string): string {\n const componentMapping = PER_COMPONENT_MAPPING[componentId];\n if (componentMapping?.[key]) return componentMapping[key];\n\n const mapping: Record<string, string> = {\n paddingX: 'padding-inline',\n paddingY: 'padding-block',\n };\n if (mapping[key]) return mapping[key];\n\n const kebab = key.replace(/([A-Z])/g, '-$1').toLowerCase();\n if (REAL_CSS_PROPS.has(key)) return kebab;\n return `--uxm-${componentId}-${kebab}`;\n}\n\nfunction formatValue(value: string | number | boolean, key: string): string {\n if (typeof value === 'boolean') return value ? '1' : '0';\n if (typeof value === 'number') {\n // `lineHeight` is a ratio, not a length — without it here a knob saved as\n // 1.5 emits `line-height: 1.5px`, which collapses every line box.\n const unitless = ['fontWeight', 'titleWeight', 'nameWeight', 'typeLabelWeight', 'lineHeight', 'shadow', 'disabledOpacity'];\n // `opacity` is always unitless — match every *Opacity knob (e.g. the\n // per-element `itemDisabledOpacity` / `optionDisabledOpacity` variants)\n // so a saved value never gets a spurious `px` suffix.\n if (unitless.includes(key) || key.endsWith('Opacity')) return String(value);\n return `${value}px`;\n }\n // String style-override values are user/attacker-controlled and persisted\n // to a stylesheet served to every browser session — sanitise the same way\n // as brand token values so one can't break out of the declaration (e.g.\n // `red; } body{display:none}/*`). An unsafe value is dropped to '' rather\n // than throwing, so a single bad override can't blank the whole rule.\n return safeTokenValue(value) ?? '';\n}\n\n// CSS sanitizers — applied to every brand value before interpolation. The\n// output is persisted and served to all browser sessions, so attacker-\n// controlled values must not break out of the declaration they belong to.\nfunction safeUrl(v: unknown): string | undefined {\n if (typeof v !== 'string') return undefined;\n const trimmed = v.trim();\n if (!/^(https?:\\/\\/|\\/)/.test(trimmed)) return undefined;\n if (/[\")\\n\\r]/.test(trimmed)) return undefined;\n return trimmed;\n}\nexport function safeFontFamily(v: unknown): string | undefined {\n if (typeof v !== 'string') return undefined;\n const trimmed = v.trim();\n return /^[A-Za-z0-9 _-]+$/.test(trimmed) ? trimmed : undefined;\n}\n// Heading weight is a closed set (the editor offers exactly these three), so a\n// strict whitelist is both the sanitizer and the contract. Numbers are accepted\n// defensively — a persisted config may carry the JSON number rather than the\n// string the <select> yields.\nexport function safeFontWeight(v: unknown): string | undefined {\n const s = typeof v === 'number' ? String(v) : typeof v === 'string' ? v.trim() : undefined;\n return s !== undefined && /^(500|600|700)$/.test(s) ? s : undefined;\n}\n// Scales multiply a length inside calc(), which makes a bad value far worse\n// than a dropped declaration: `abc` or `1.2px` (length × length) is invalid at\n// computed-value time, so `font-size` resolves to `unset` and INHERITS — one\n// poisoned value on :root collapses the whole app to the parent's size. A\n// plain-number whitelist plus a sane range is the only safe gate; note\n// `safeTokenValue` is NOT sufficient (it passes `abc`, `-1` and unbalanced\n// parens). Range mirrors the editor's slider bounds.\nexport function safeTypeScale(v: unknown): string | undefined {\n const s = typeof v === 'number' ? String(v) : typeof v === 'string' ? v.trim() : undefined;\n if (s === undefined || !/^(?:0|[1-9]\\d?)(?:\\.\\d{1,3})?$/.test(s)) return undefined;\n const n = Number(s);\n return n >= 0.5 && n <= 2 ? s : undefined;\n}\n// Line height is a unitless ratio; same invalid-at-computed-value-time risk as\n// the scales, but it only affects the declarations that read it.\nexport function safeLineHeight(v: unknown): string | undefined {\n const s = typeof v === 'number' ? String(v) : typeof v === 'string' ? v.trim() : undefined;\n if (s === undefined || !/^[1-9](?:\\.\\d{1,2})?$/.test(s)) return undefined;\n const n = Number(s);\n return n >= 1 && n <= 2.5 ? s : undefined;\n}\nexport function safeTokenKey(v: string): boolean {\n return /^--[A-Za-z0-9-]+$/.test(v);\n}\nexport function safeTokenValue(v: unknown): string | undefined {\n if (typeof v !== 'string') return undefined;\n return /[{};\\n\\r]/.test(v) ? undefined : v;\n}\n\n// The three heading roles, in one place. Both the publish path below and the\n// live mirror (`brand-font-styles.tsx`) derive their emitted var names from\n// `role` by interpolation, so a rename here reaches both — keeping these in two\n// hand-maintained lists is how `--type-${role}-font` silently drifts away from\n// the names the stylesheets actually read.\nexport const TYPE_ROLES = [\n { role: 'display', family: 'displayFontFamily', weight: 'displayFontWeight', scale: 'displayScale' },\n { role: 'page-title', family: 'pageTitleFontFamily', weight: 'pageTitleFontWeight', scale: 'pageTitleScale' },\n { role: 'section-title', family: 'sectionTitleFontFamily', weight: 'sectionTitleFontWeight', scale: 'sectionTitleScale' },\n] as const satisfies ReadonlyArray<{\n role: string;\n family: keyof BrandConfig;\n weight: keyof BrandConfig;\n scale: keyof BrandConfig;\n}>;\n\n/** Sanitised per-role typography, shared by the generator and the live mirror. */\nexport function resolveTypeRoles(brand: BrandConfig) {\n return TYPE_ROLES.map((r) => ({\n role: r.role,\n family: safeFontFamily(brand[r.family]),\n weight: safeFontWeight(brand[r.weight]),\n scale: safeTypeScale(brand[r.scale]),\n }));\n}\n\n/** Generate the overrides stylesheet from style overrides + brand config. */\nexport function generateOverridesCss(allOverrides: AllOverrides, brand: BrandConfig): string {\n const lines: string[] = ['/* Auto-generated by UXM — do not edit manually */', ''];\n\n const fontFamily = safeFontFamily(brand.fontFamily);\n const headingFontFamily = safeFontFamily(brand.headingFontFamily);\n const headingFontWeight = safeFontWeight(brand.headingFontWeight);\n // Per-role refinements, layered under the umbrella heading vars above.\n const roles = resolveTypeRoles(brand);\n const typeScale = safeTypeScale(brand.typeScale);\n const bodyLineHeight = safeLineHeight(brand.bodyLineHeight);\n const logoUrl = safeUrl(brand.logoUrl);\n const iconUrl = safeUrl(brand.iconUrl);\n const logoUrlDark = safeUrl(brand.logoUrlDark);\n const iconUrlDark = safeUrl(brand.iconUrlDark);\n\n if (fontFamily) {\n lines.push(`@import url(\"${fontFileUrl(fontFamily)}\");`);\n lines.push('');\n }\n // Second font file only when the heading face is actually a different family\n // — picking the same one for both is a no-op, not a reason to fetch twice.\n if (headingFontFamily && headingFontFamily !== fontFamily) {\n lines.push(`@import url(\"${fontFileUrl(headingFontFamily)}\");`);\n lines.push('');\n }\n // A role may pick a face neither the body nor the umbrella uses — fetch each\n // distinct one exactly once (@import must stay above the rules below).\n const imported = new Set([fontFamily, headingFontFamily].filter(Boolean));\n for (const { family } of roles) {\n if (family && !imported.has(family)) {\n imported.add(family);\n lines.push(`@import url(\"${fontFileUrl(family)}\");`);\n lines.push('');\n }\n }\n\n const brandRules: string[] = [];\n if (fontFamily) {\n brandRules.push(` --brand-font: \"${fontFamily}\", var(--font-inter), system-ui, sans-serif;`);\n }\n // Heading vars are consumed by the components' own two-layer fallbacks (see\n // e.g. page-header.scss), so there is no `body` rule and no `!important`:\n // an unset var simply lets each component's own default paint.\n if (headingFontFamily) {\n brandRules.push(` --brand-heading-font: \"${headingFontFamily}\", var(--font-inter), system-ui, sans-serif;`);\n }\n if (headingFontWeight) {\n brandRules.push(` --brand-heading-weight: ${headingFontWeight};`);\n }\n // Role vars sit between the component var and the umbrella in each atom's\n // chain, so an unset role simply falls through to the umbrella.\n for (const { role, family, weight, scale } of roles) {\n if (family) {\n brandRules.push(` --type-${role}-font: \"${family}\", var(--font-inter), system-ui, sans-serif;`);\n }\n if (weight) brandRules.push(` --type-${role}-weight: ${weight};`);\n if (scale) brandRules.push(` --type-${role}-scale: ${scale};`);\n }\n if (typeScale) brandRules.push(` --type-scale: ${typeScale};`);\n if (bodyLineHeight) brandRules.push(` --type-body-line-height: ${bodyLineHeight};`);\n if (logoUrl) brandRules.push(` --brand-logo-url: url(\"${logoUrl}\");`);\n if (iconUrl) brandRules.push(` --brand-icon-url: url(\"${iconUrl}\");`);\n\n if (brandRules.length > 0) {\n lines.push(':root {');\n lines.push(...brandRules);\n lines.push('}');\n lines.push('');\n if (fontFamily) {\n lines.push('body { font-family: var(--brand-font) !important; }');\n lines.push('');\n }\n // Emitted ONLY when set. The library ships no element-level rules at all,\n // so an unconditional `body { line-height }` would reflow the host's own\n // content — same reasoning as the font-family rule above.\n if (bodyLineHeight) {\n // Explicit fallback: if the var is later cancelled (the studio mirror\n // re-declares it as `initial` on revert) a bare `var()` would be invalid\n // at computed-value time and `line-height` — being inherited — would\n // resolve to the parent's value, silently replacing whatever the host\n // had set on `body`. `normal` makes the wind-down state deliberate.\n lines.push(`body { line-height: var(--type-body-line-height, normal); }`);\n lines.push('');\n }\n }\n\n const darkBrandRules: string[] = [];\n if (logoUrlDark) darkBrandRules.push(` --brand-logo-url: url(\"${logoUrlDark}\");`);\n if (iconUrlDark) darkBrandRules.push(` --brand-icon-url: url(\"${iconUrlDark}\");`);\n if (darkBrandRules.length > 0) {\n lines.push('[data-theme=\"dark\"] {');\n lines.push(...darkBrandRules);\n lines.push('}');\n lines.push('');\n }\n\n const emitTokens = (selector: string, overrides: Record<string, string> | undefined) => {\n if (!overrides) return;\n const safeEntries = Object.entries(overrides).flatMap(([k, v]) => {\n if (!safeTokenKey(k)) return [];\n const safeValue = safeTokenValue(v);\n return safeValue === undefined ? [] : [[k, safeValue] as const];\n });\n if (safeEntries.length === 0) return;\n lines.push(`${selector} {`);\n for (const [cssVar, value] of safeEntries) {\n lines.push(` ${cssVar}: ${value};`);\n }\n lines.push('}');\n lines.push('');\n };\n // Scope customized light-mode color tokens to non-dark. `:root` and\n // `[data-theme=\"dark\"]` carry equal specificity, so an unconditional\n // `:root` block would win over this stylesheet's own dark block for any\n // token NOT also customized for dark (equal specificity, later source\n // order) — pinning that token to its light value in dark mode too. Scoping\n // lets an unset dark token fall through the cascade to tokens/index.css's\n // own `[data-theme=\"dark\"]` default instead.\n emitTokens(':root:not([data-theme=\"dark\"])', brand.tokens?.light);\n emitTokens('[data-theme=\"dark\"]', brand.tokens?.dark);\n\n const componentIds = Object.keys(allOverrides).sort();\n\n for (const id of componentIds) {\n const overrides = allOverrides[id];\n const entries = Object.entries(overrides);\n if (entries.length === 0) continue;\n\n const selector = PER_COMPONENT_SELECTOR[id] ?? `.uxm-${id}`;\n lines.push(`${selector} {`);\n for (const [key, value] of entries) {\n const cssProp = toCSS(key, id);\n const cssValue = formatValue(value, key);\n lines.push(` ${cssProp}: ${cssValue};`);\n }\n lines.push('}');\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"generate-css.d.ts","sourceRoot":"","sources":["../../../src/studio/persistence/generate-css.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAiBhD,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAGtD;AA+1BD,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAI7D;AAKD,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAG7D;AAQD,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAK5D;AAGD,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAK7D;AACD,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAE/C;AACD,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAG7D;AAOD,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;EASrB,CAAC;AAEH,kFAAkF;AAClF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW;;;;;IAOlD;AAED,6EAA6E;AAC7E,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,GAAG,MAAM,CA4I3F"}
1
+ {"version":3,"file":"generate-css.d.ts","sourceRoot":"","sources":["../../../src/studio/persistence/generate-css.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAiBhD,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAGtD;AA82BD,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAI7D;AAKD,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAG7D;AAQD,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAK5D;AAGD,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAK7D;AACD,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAE/C;AACD,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAG7D;AAOD,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;EASrB,CAAC;AAEH,kFAAkF;AAClF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW;;;;;IAOlD;AAED,6EAA6E;AAC7E,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,GAAG,MAAM,CA4I3F"}
@@ -76,6 +76,21 @@ const PER_COMPONENT_MAPPING = {
76
76
  paddingY: "--uxm-number-input-padding-y",
77
77
  fontSize: "--uxm-number-input-font-size"
78
78
  },
79
+ // Every key below collides with REAL_CSS_PROPS. The atom passes its class to
80
+ // `Listbox`, so the emitted rule lands on that in-page ROOT while the styled
81
+ // element is the `__trigger` child, which declares its own `color`,
82
+ // `border-color`, `font-size` and `gap` from `--uxm-language-switcher-*` and
83
+ // therefore beats anything inherited — every one of these would be a silent
84
+ // no-op. Padding is worse: `padding-inline` on the root pads OUTSIDE the
85
+ // button while the trigger keeps its default 10px/7px.
86
+ "language-switcher": {
87
+ color: "--uxm-language-switcher-color",
88
+ borderColor: "--uxm-language-switcher-border-color",
89
+ fontSize: "--uxm-language-switcher-font-size",
90
+ gap: "--uxm-language-switcher-gap",
91
+ paddingX: "--uxm-language-switcher-padding-x",
92
+ paddingY: "--uxm-language-switcher-padding-y"
93
+ },
79
94
  // Without this entry `fontSize` falls through REAL_CSS_PROPS and emits a
80
95
  // literal `font-size` on `.uxm-color-input`, which the atom's own children
81
96
  // (`__value-field`, `__format`) always beat — so the knob did nothing at all.