@caelo-cms/shared 0.10.21 → 0.10.23

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 (241) hide show
  1. package/dist/ai-tools.d.ts +291 -231
  2. package/dist/ai-tools.d.ts.map +1 -1
  3. package/dist/ai-tools.js +349 -281
  4. package/dist/ai-tools.js.map +1 -1
  5. package/dist/auth-forms.d.ts.map +1 -1
  6. package/dist/auth-forms.js +4 -1
  7. package/dist/auth-forms.js.map +1 -1
  8. package/dist/base-css.d.ts +24 -0
  9. package/dist/base-css.d.ts.map +1 -0
  10. package/dist/base-css.js +28 -0
  11. package/dist/base-css.js.map +1 -0
  12. package/dist/build-page.d.ts +330 -0
  13. package/dist/build-page.d.ts.map +1 -0
  14. package/dist/build-page.js +282 -0
  15. package/dist/build-page.js.map +1 -0
  16. package/dist/content.d.ts +322 -9
  17. package/dist/content.d.ts.map +1 -1
  18. package/dist/content.js +354 -11
  19. package/dist/content.js.map +1 -1
  20. package/dist/css-gradient-scan.d.ts +14 -0
  21. package/dist/css-gradient-scan.d.ts.map +1 -0
  22. package/dist/css-gradient-scan.js +81 -0
  23. package/dist/css-gradient-scan.js.map +1 -0
  24. package/dist/css-var-scan.d.ts +56 -0
  25. package/dist/css-var-scan.d.ts.map +1 -0
  26. package/dist/css-var-scan.js +97 -0
  27. package/dist/css-var-scan.js.map +1 -0
  28. package/dist/design-manifest.d.ts +36 -0
  29. package/dist/design-manifest.d.ts.map +1 -0
  30. package/dist/design-manifest.js +90 -0
  31. package/dist/design-manifest.js.map +1 -0
  32. package/dist/fonts.d.ts +89 -0
  33. package/dist/fonts.d.ts.map +1 -0
  34. package/dist/fonts.js +241 -0
  35. package/dist/fonts.js.map +1 -0
  36. package/dist/genesis-inventory.d.ts +32 -0
  37. package/dist/genesis-inventory.d.ts.map +1 -0
  38. package/dist/genesis-inventory.js +186 -0
  39. package/dist/genesis-inventory.js.map +1 -0
  40. package/dist/genesis.d.ts +62 -0
  41. package/dist/genesis.d.ts.map +1 -0
  42. package/dist/genesis.js +78 -0
  43. package/dist/genesis.js.map +1 -0
  44. package/dist/i18n.d.ts +44 -1
  45. package/dist/i18n.d.ts.map +1 -1
  46. package/dist/i18n.js +72 -6
  47. package/dist/i18n.js.map +1 -1
  48. package/dist/index.d.ts +27 -0
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +27 -0
  51. package/dist/index.js.map +1 -1
  52. package/dist/interactions.d.ts +23 -0
  53. package/dist/interactions.d.ts.map +1 -0
  54. package/dist/interactions.js +44 -0
  55. package/dist/interactions.js.map +1 -0
  56. package/dist/media.d.ts +101 -16
  57. package/dist/media.d.ts.map +1 -1
  58. package/dist/media.js +126 -15
  59. package/dist/media.js.map +1 -1
  60. package/dist/page-log.d.ts +94 -0
  61. package/dist/page-log.d.ts.map +1 -0
  62. package/dist/page-log.js +111 -0
  63. package/dist/page-log.js.map +1 -0
  64. package/dist/preview-compose.d.ts +79 -0
  65. package/dist/preview-compose.d.ts.map +1 -1
  66. package/dist/preview-compose.js +155 -25
  67. package/dist/preview-compose.js.map +1 -1
  68. package/dist/proposal-status.d.ts +40 -0
  69. package/dist/proposal-status.d.ts.map +1 -0
  70. package/dist/proposal-status.js +34 -0
  71. package/dist/proposal-status.js.map +1 -0
  72. package/dist/responsive-images.d.ts +64 -0
  73. package/dist/responsive-images.d.ts.map +1 -0
  74. package/dist/responsive-images.js +98 -0
  75. package/dist/responsive-images.js.map +1 -0
  76. package/dist/safe-keys.d.ts +9 -0
  77. package/dist/safe-keys.d.ts.map +1 -0
  78. package/dist/safe-keys.js +20 -0
  79. package/dist/safe-keys.js.map +1 -0
  80. package/dist/seo.d.ts +8 -0
  81. package/dist/seo.d.ts.map +1 -1
  82. package/dist/seo.js +3 -1
  83. package/dist/seo.js.map +1 -1
  84. package/dist/skills.d.ts +14 -68
  85. package/dist/skills.d.ts.map +1 -1
  86. package/dist/skills.js +19 -113
  87. package/dist/skills.js.map +1 -1
  88. package/dist/strip-cdata.d.ts +7 -0
  89. package/dist/strip-cdata.d.ts.map +1 -0
  90. package/dist/strip-cdata.js +48 -0
  91. package/dist/strip-cdata.js.map +1 -0
  92. package/dist/structured-sets.d.ts +6 -16
  93. package/dist/structured-sets.d.ts.map +1 -1
  94. package/dist/structured-sets.js +5 -16
  95. package/dist/structured-sets.js.map +1 -1
  96. package/dist/subagents.d.ts +105 -3
  97. package/dist/subagents.d.ts.map +1 -1
  98. package/dist/subagents.js +224 -41
  99. package/dist/subagents.js.map +1 -1
  100. package/dist/template-engine.d.ts +85 -0
  101. package/dist/template-engine.d.ts.map +1 -0
  102. package/dist/template-engine.js +403 -0
  103. package/dist/template-engine.js.map +1 -0
  104. package/dist/theme-importers/auto-detect.d.ts +26 -0
  105. package/dist/theme-importers/auto-detect.d.ts.map +1 -0
  106. package/dist/theme-importers/auto-detect.js +42 -0
  107. package/dist/theme-importers/auto-detect.js.map +1 -0
  108. package/dist/theme-importers/css-comments.d.ts +12 -0
  109. package/dist/theme-importers/css-comments.d.ts.map +1 -0
  110. package/dist/theme-importers/css-comments.js +15 -0
  111. package/dist/theme-importers/css-comments.js.map +1 -0
  112. package/dist/theme-importers/dtcg.d.ts +46 -0
  113. package/dist/theme-importers/dtcg.d.ts.map +1 -0
  114. package/dist/theme-importers/dtcg.js +111 -0
  115. package/dist/theme-importers/dtcg.js.map +1 -0
  116. package/dist/theme-importers/loose.d.ts +3 -0
  117. package/dist/theme-importers/loose.d.ts.map +1 -0
  118. package/dist/theme-importers/loose.js +76 -0
  119. package/dist/theme-importers/loose.js.map +1 -0
  120. package/dist/theme-importers/shadcn.d.ts +24 -0
  121. package/dist/theme-importers/shadcn.d.ts.map +1 -0
  122. package/dist/theme-importers/shadcn.js +135 -0
  123. package/dist/theme-importers/shadcn.js.map +1 -0
  124. package/dist/theme-importers/style-dictionary.d.ts +17 -0
  125. package/dist/theme-importers/style-dictionary.d.ts.map +1 -0
  126. package/dist/theme-importers/style-dictionary.js +125 -0
  127. package/dist/theme-importers/style-dictionary.js.map +1 -0
  128. package/dist/theme-importers/tailwind.d.ts +3 -0
  129. package/dist/theme-importers/tailwind.d.ts.map +1 -0
  130. package/dist/theme-importers/tailwind.js +218 -0
  131. package/dist/theme-importers/tailwind.js.map +1 -0
  132. package/dist/theme-literal-binding.d.ts +37 -0
  133. package/dist/theme-literal-binding.d.ts.map +1 -0
  134. package/dist/theme-literal-binding.js +138 -0
  135. package/dist/theme-literal-binding.js.map +1 -0
  136. package/dist/theme-normalize.d.ts +31 -0
  137. package/dist/theme-normalize.d.ts.map +1 -0
  138. package/dist/theme-normalize.js +587 -0
  139. package/dist/theme-normalize.js.map +1 -0
  140. package/dist/theme-ramp.d.ts +55 -0
  141. package/dist/theme-ramp.d.ts.map +1 -0
  142. package/dist/theme-ramp.js +149 -0
  143. package/dist/theme-ramp.js.map +1 -0
  144. package/dist/theme-render.d.ts +105 -0
  145. package/dist/theme-render.d.ts.map +1 -0
  146. package/dist/theme-render.js +441 -0
  147. package/dist/theme-render.js.map +1 -0
  148. package/dist/themes-errors.d.ts +109 -0
  149. package/dist/themes-errors.d.ts.map +1 -0
  150. package/dist/themes-errors.js +170 -0
  151. package/dist/themes-errors.js.map +1 -0
  152. package/dist/themes.d.ts +343 -0
  153. package/dist/themes.d.ts.map +1 -0
  154. package/dist/themes.js +697 -0
  155. package/dist/themes.js.map +1 -0
  156. package/dist/version.d.ts +7 -4
  157. package/dist/version.d.ts.map +1 -1
  158. package/dist/version.js +6 -3
  159. package/dist/version.js.map +1 -1
  160. package/package.json +10 -2
  161. package/src/__tests__/redos-hardening.test.ts +160 -0
  162. package/src/ai-tools-add-module-modes.test.ts +106 -0
  163. package/src/ai-tools-position.test.ts +134 -0
  164. package/src/ai-tools.test.ts +81 -0
  165. package/src/ai-tools.ts +1179 -0
  166. package/src/auth-forms.ts +36 -0
  167. package/src/base-css.ts +30 -0
  168. package/src/build-page.test.ts +228 -0
  169. package/src/build-page.ts +319 -0
  170. package/src/cap-failures.ts +67 -0
  171. package/src/content.test.ts +170 -0
  172. package/src/content.ts +620 -0
  173. package/src/context.ts +43 -0
  174. package/src/css-gradient-scan.ts +88 -0
  175. package/src/css-var-scan.test.ts +96 -0
  176. package/src/css-var-scan.ts +144 -0
  177. package/src/derive-module-type.test.ts +80 -0
  178. package/src/design-manifest.ts +93 -0
  179. package/src/fonts.test.ts +157 -0
  180. package/src/fonts.ts +296 -0
  181. package/src/genesis-inventory.test.ts +86 -0
  182. package/src/genesis-inventory.ts +215 -0
  183. package/src/genesis-sanitize.test.ts +35 -0
  184. package/src/genesis.ts +87 -0
  185. package/src/i18n.test.ts +274 -0
  186. package/src/i18n.ts +269 -0
  187. package/src/index.test.ts +10 -0
  188. package/src/index.ts +59 -0
  189. package/src/interactions.ts +48 -0
  190. package/src/logger.ts +147 -0
  191. package/src/media.test.ts +160 -0
  192. package/src/media.ts +355 -0
  193. package/src/page-log.test.ts +163 -0
  194. package/src/page-log.ts +124 -0
  195. package/src/preview-compose.test.ts +602 -0
  196. package/src/preview-compose.ts +709 -0
  197. package/src/preview-scanner.test.ts +96 -0
  198. package/src/preview-scanner.ts +214 -0
  199. package/src/proposal-status.test.ts +69 -0
  200. package/src/proposal-status.ts +40 -0
  201. package/src/responsive-images.test.ts +104 -0
  202. package/src/responsive-images.ts +151 -0
  203. package/src/result.ts +29 -0
  204. package/src/safe-keys.ts +21 -0
  205. package/src/seo.test.ts +234 -0
  206. package/src/seo.ts +261 -0
  207. package/src/skills.ts +48 -0
  208. package/src/snapshots.test.ts +80 -0
  209. package/src/snapshots.ts +81 -0
  210. package/src/strip-cdata.test.ts +41 -0
  211. package/src/strip-cdata.ts +50 -0
  212. package/src/structured-sets.ts +180 -0
  213. package/src/subagents.test.ts +262 -0
  214. package/src/subagents.ts +432 -0
  215. package/src/template-engine.test.ts +379 -0
  216. package/src/template-engine.ts +520 -0
  217. package/src/theme-gradient.test.ts +92 -0
  218. package/src/theme-importers/__tests__/proto-pollution.test.ts +54 -0
  219. package/src/theme-importers/auto-detect.ts +84 -0
  220. package/src/theme-importers/css-comments.ts +15 -0
  221. package/src/theme-importers/dtcg.ts +106 -0
  222. package/src/theme-importers/loose.ts +76 -0
  223. package/src/theme-importers/shadcn.ts +133 -0
  224. package/src/theme-importers/style-dictionary.ts +125 -0
  225. package/src/theme-importers/tailwind.ts +217 -0
  226. package/src/theme-literal-binding.test.ts +71 -0
  227. package/src/theme-literal-binding.ts +159 -0
  228. package/src/theme-motion.test.ts +115 -0
  229. package/src/theme-normalize-envelope.test.ts +43 -0
  230. package/src/theme-normalize-gradient.test.ts +135 -0
  231. package/src/theme-normalize.ts +661 -0
  232. package/src/theme-ramp.ts +187 -0
  233. package/src/theme-render-sanitize.test.ts +45 -0
  234. package/src/theme-render.test.ts +119 -0
  235. package/src/theme-render.ts +487 -0
  236. package/src/theme-shadow.test.ts +56 -0
  237. package/src/themes-errors.ts +199 -0
  238. package/src/themes.ts +842 -0
  239. package/src/translation.test.ts +160 -0
  240. package/src/translation.ts +295 -0
  241. package/src/version.ts +66 -0
@@ -0,0 +1,149 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ /**
3
+ * v0.11.1 (issue #76) — OKLCh primary-color ramp generator.
4
+ *
5
+ * Given a seed color, derive a 10-stop ramp (`50`,`100`,…,`900`) by
6
+ * walking lightness linearly outward from the seed while preserving its
7
+ * chroma + hue. Anchored so the `500` stop equals the seed.
8
+ *
9
+ * Returns a DTCG group ready to merge at `color.primary`: each stop is
10
+ * a token leaf carrying `$value: "oklch(L C H)"` + `$type: "color"` +
11
+ * `_derived: true` annotation, plus a DTCG alias token at `DEFAULT`
12
+ * pointing at `{color.primary.500}` so existing `--color-primary`
13
+ * references continue to resolve via the v0.11.0 alias resolver.
14
+ *
15
+ * Simplest-possible math (Material 3 inspiration, OKLCh execution); the
16
+ * issue explicitly calls out HCT as future-tuning, not current scope.
17
+ */
18
+ import Color from "colorjs.io";
19
+ /**
20
+ * v0.11.1 — failure surface for the OKLCh ramp generator. Carries the
21
+ * supported color input formats so the AI's next turn can fix the
22
+ * input without round-tripping (CLAUDE.md §11 AI-actionable errors).
23
+ */
24
+ export class InvalidSeedColor extends Error {
25
+ kind = "InvalidSeedColor";
26
+ input;
27
+ supportedFormats;
28
+ constructor(input) {
29
+ const formats = [
30
+ "#rrggbb",
31
+ "#rgb",
32
+ "oklch(L C H)",
33
+ "rgb(r g b)",
34
+ "hsl(h s% l%)",
35
+ "lab(L a b)",
36
+ "lch(L C H)",
37
+ ];
38
+ super(`seed color '${input}' is not a recognised CSS color — pass one of: ${formats.join(", ")}.`);
39
+ this.name = "InvalidSeedColor";
40
+ this.input = input;
41
+ this.supportedFormats = formats;
42
+ }
43
+ }
44
+ /**
45
+ * Linearly-spaced lightness values for the 10 stops. The `500` slot is
46
+ * intentionally a placeholder — the seed's measured lightness replaces
47
+ * it at runtime so the brand color shows up unmodified at its anchor.
48
+ *
49
+ * Curve picked to match Tailwind's perceptual feel: light tints at
50
+ * 50/100 stay near-white, deep shades at 800/900 stay near-black.
51
+ */
52
+ const RAMP_KEYS = ["50", "100", "200", "300", "400", "500", "600", "700", "800", "900"];
53
+ const RAMP_LIGHTNESS = [0.97, 0.94, 0.87, 0.78, 0.67, 0.55, 0.45, 0.35, 0.25, 0.18];
54
+ const SEED_INDEX = RAMP_KEYS.indexOf("500");
55
+ /**
56
+ * Derive a 10-stop OKLCh primary-color ramp from a seed color.
57
+ *
58
+ * @param seedColor — any CSS color string. The seed's chroma + hue are
59
+ * preserved; lightness shifts to each ramp stop.
60
+ * @returns A DTCG group ready to write at `color.primary`.
61
+ * @throws InvalidSeedColor when the input doesn't parse as a CSS color.
62
+ */
63
+ export function deriveOklchPrimaryRamp(seedColor) {
64
+ if (typeof seedColor !== "string" || seedColor.trim().length === 0) {
65
+ throw new InvalidSeedColor(String(seedColor));
66
+ }
67
+ let seed;
68
+ try {
69
+ seed = new Color(seedColor);
70
+ }
71
+ catch (_e) {
72
+ throw new InvalidSeedColor(seedColor);
73
+ }
74
+ // Convert to OKLCh; the conversion is lossless within colorjs.io's
75
+ // gamut model (clamps to displayable sRGB on output).
76
+ const oklch = seed.to("oklch");
77
+ const coords = oklch.coords; // [L, C, H]
78
+ const seedL = coords[0];
79
+ const chroma = Number.isFinite(coords[1]) ? coords[1] : 0;
80
+ // Achromatic colors (#888, white, black) have NaN hue — preserve 0
81
+ // so the OKLCh string parses; chroma is 0 anyway.
82
+ const hue = Number.isFinite(coords[2]) ? coords[2] : 0;
83
+ const tokens = {};
84
+ const derivedPaths = [];
85
+ for (let i = 0; i < RAMP_KEYS.length; i += 1) {
86
+ const key = RAMP_KEYS[i];
87
+ // Anchor the seed's lightness at the 500 stop; the rest follow the
88
+ // pre-computed curve. Clamp to [0.001, 0.999] so OKLCh emits a
89
+ // valid color (pure black/white can clip chroma in edge cases).
90
+ const rawL = i === SEED_INDEX ? seedL : RAMP_LIGHTNESS[i];
91
+ const L = Math.max(0.001, Math.min(0.999, rawL));
92
+ const value = formatOklch(L, chroma, hue);
93
+ tokens[key] = { $value: value, $type: "color", _derived: true };
94
+ derivedPaths.push(`color.primary.${key}`);
95
+ }
96
+ // DTCG alias so callers / CSS-vars that reference `color.primary`
97
+ // continue to resolve to the 500 stop. The renderer's alias resolver
98
+ // (v0.11.0) handles the indirection; no renderer changes needed.
99
+ tokens.DEFAULT = {
100
+ $value: "{color.primary.500}",
101
+ $type: "color",
102
+ _derived: true,
103
+ };
104
+ derivedPaths.push("color.primary.DEFAULT");
105
+ return { tokens, derivedPaths };
106
+ }
107
+ /**
108
+ * Merge a ramp result into a tokens document at `color.primary`,
109
+ * preserving any operator-supplied explicit stops in `overrides`
110
+ * (`{"color.primary.500": "#ff0000"}` keeps the explicit stop AND the
111
+ * derived ramp around it — explicit-wins precedence per Risk §6.2).
112
+ *
113
+ * Returns a fresh document; input is not mutated.
114
+ */
115
+ export function mergeRampIntoTokens(baseTokens, ramp, explicitOverrides) {
116
+ const out = JSON.parse(JSON.stringify(baseTokens));
117
+ const colorGroup = out.color;
118
+ const nextColor = { ...(colorGroup ?? {}) };
119
+ // REPLACE the previous color.primary entry with the derived ramp
120
+ // group. The replacement is total — a leaf `{"$value": "…"}` becomes
121
+ // a group `{50: {…}, 100: {…}, …, DEFAULT: {…}}`. Other color tokens
122
+ // (foreground, secondary, etc.) are untouched.
123
+ nextColor.primary = { ...ramp.tokens };
124
+ out.color = nextColor;
125
+ // Layer explicit operator-supplied `color.primary.<stop>` overrides
126
+ // on top of the derived ramp. Only `color.primary.*` paths matter
127
+ // here; other overrides flow through the existing applyDtcgWrites
128
+ // call upstream.
129
+ for (const [path, value] of Object.entries(explicitOverrides)) {
130
+ if (!path.startsWith("color.primary."))
131
+ continue;
132
+ const stopKey = path.slice("color.primary.".length);
133
+ if (!stopKey || stopKey.includes("."))
134
+ continue;
135
+ const primary = out.color.primary;
136
+ primary[stopKey] = {
137
+ $value: value,
138
+ $type: "color",
139
+ };
140
+ }
141
+ return out;
142
+ }
143
+ function formatOklch(L, C, H) {
144
+ // Three decimal places — enough for visual fidelity (OKLCh's perceptual
145
+ // step is ~0.005L), small enough for cache-friendly stable bytes.
146
+ const fmt = (n) => n.toFixed(3).replace(/\.?0+$/, "") || "0";
147
+ return `oklch(${fmt(L)} ${fmt(C)} ${fmt(H)})`;
148
+ }
149
+ //# sourceMappingURL=theme-ramp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-ramp.js","sourceRoot":"","sources":["../src/theme-ramp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * v0.11.0 — DTCG-aligned theme renderer (#45 Phase 3).
3
+ *
4
+ * Walks a `ThemeDocument` (DTCG tokens jsonb) and emits CSS custom
5
+ * properties under the Tailwind 4 namespace convention so module CSS
6
+ * can `var(--color-primary)` / `var(--spacing-lg)` etc. without
7
+ * mental-translation from DTCG paths.
8
+ *
9
+ * Namespace mapping (matches Tailwind 4's `@theme { … }` directive):
10
+ *
11
+ * color.X → --color-X
12
+ * typography.X → --font-X (fontFamily) + --text-X (fontSize)
13
+ * + --font-weight-X + --leading-X + --tracking-X
14
+ * spacing.X → --spacing-X
15
+ * radius.X → --radius-X
16
+ * shadow.X → --shadow-X (expanded to `<x> <y> <blur> [spread] <color> [inset]`)
17
+ * breakpoint.X → --breakpoint-X
18
+ * duration.X → --duration-X
19
+ * ease.X → --ease-X (cubic-bezier expansion)
20
+ *
21
+ * Color tokens carrying `{ light, dark }` emit the light value inside
22
+ * `:root { … }` AND the dark value inside `:root.dark { … }` so a
23
+ * single declaration drives both surfaces.
24
+ *
25
+ * DTCG aliases (`"{group.token}"`) are resolved before emission.
26
+ * Cyclic aliases produce a structured error rather than infinite-
27
+ * looping. Pure function — no IO, dependency-free, testable in unit
28
+ * isolation.
29
+ */
30
+ import { type ThemeDocument } from "./themes.js";
31
+ /** Renderer-level error for cyclic / unresolved aliases. */
32
+ export declare class ThemeRenderError extends Error {
33
+ readonly kind: "cyclic-alias" | "missing-alias";
34
+ readonly path: string;
35
+ constructor(kind: "cyclic-alias" | "missing-alias", path: string, message: string);
36
+ }
37
+ /**
38
+ * Optional render options. The `selector` parameter (v0.11.1, issue #76)
39
+ * scopes the emitted CSS variables under a custom selector so the admin
40
+ * live-preview pane can render the byte-identical CSS without leaking
41
+ * the theme's tokens onto the surrounding admin chrome. Default `:root`
42
+ * keeps the static-gen + chat-runner paths unchanged.
43
+ */
44
+ export interface RenderThemeCssOptions {
45
+ /**
46
+ * Selector to wrap the emitted rule blocks. Defaults to `:root`. The
47
+ * dark-variant block becomes `${selector}.dark` so a single `.dark`
48
+ * class toggle on the scoping element flips both surfaces — same
49
+ * behaviour as the public site's `:root` / `:root.dark` pairing.
50
+ */
51
+ readonly selector?: string;
52
+ }
53
+ /**
54
+ * Emit the `:root { … }` (+ optional `:root.dark { … }`) CSS for the
55
+ * supplied tokens document. Returns the bare CSS body — caller wraps
56
+ * it in `<style data-source="theme">…</style>` and injects it ahead of
57
+ * module CSS in the document head.
58
+ *
59
+ * Pass `options.selector` (v0.11.1) to scope the rule blocks under a
60
+ * custom selector instead of `:root`. The admin live preview uses
61
+ * `.theme-preview` so the operator's edits don't leak onto the admin
62
+ * UI. Public + chat paths omit the option and get the default.
63
+ */
64
+ export declare function renderThemeCss(tokens: ThemeDocument, options?: RenderThemeCssOptions): string;
65
+ /**
66
+ * Named export of the `:root { … }` CSS-vars form. Alias for
67
+ * `renderThemeCss(tokens)` — exists so the AI tool's `as: "css-vars"`
68
+ * dispatch table reads symmetrically with the other format names.
69
+ */
70
+ export declare function formatThemeAsCssVars(tokens: ThemeDocument): string;
71
+ /**
72
+ * v0.11.4 (issue #76 follow-up) — return JUST the CSS variable names
73
+ * the renderer would emit for this token document. The AI uses this in
74
+ * the system-prompt `## Theme` block so it knows exactly which
75
+ * `var(--…)` names exist before authoring module CSS.
76
+ *
77
+ * Without this surface the AI guesses var names (e.g. `--color-text`,
78
+ * `--color-surface`) that look reasonable but don't exist in the
79
+ * shadcn-style theme — its CSS then falls through to hardcoded
80
+ * fallbacks and the page renders monochrome regardless of token values.
81
+ *
82
+ * Returns a sorted, de-duplicated array. Emits the same names as the
83
+ * `renderThemeCss` light branch (the dark variant uses the same names
84
+ * with different values, so listing them once is correct).
85
+ */
86
+ export declare function listThemeCssVarNames(tokens: ThemeDocument): readonly string[];
87
+ /**
88
+ * Emit a Tailwind 4 `@theme inline { … }` block. The body re-uses the
89
+ * same per-category emission as `renderThemeCss` so the variable names
90
+ * match what `app.css` exposes — feeding this output into the Tailwind
91
+ * importer round-trips to the same DTCG document.
92
+ */
93
+ export declare function formatThemeAsTailwind(tokens: ThemeDocument): string;
94
+ /**
95
+ * Emit a terse one-line summary of the tokens document — primary color
96
+ * shorthand, body font, default radius, and category counts. Used by
97
+ * the system-prompt `## Theme` block so the AI sees the theme's feel
98
+ * without spending tokens on the full DTCG document.
99
+ *
100
+ * Format: `primary=<hex|oklch>, body=<fontFamily-first-name>, radius=<value>, <category counts>`.
101
+ * Falls back to category counts only when the canonical paths aren't
102
+ * populated (e.g. an empty or unusual theme).
103
+ */
104
+ export declare function formatThemeSummary(tokens: ThemeDocument): string;
105
+ //# sourceMappingURL=theme-render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-render.d.ts","sourceRoot":"","sources":["../src/theme-render.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAqC,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAEpF,4DAA4D;AAC5D,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,eAAe,CAAC;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBACV,IAAI,EAAE,cAAc,GAAG,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAMlF;AAED;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,GAAE,qBAA0B,GAAG,MAAM,CAgBjG;AAMD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAElE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,MAAM,EAAE,CAmB7E;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAgBnE;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CA8ChE"}