meno-core 1.0.54 → 1.1.1

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 (298) hide show
  1. package/bin/cli.ts +19 -205
  2. package/build-astro.ts +31 -27
  3. package/dist/bin/cli.js +15 -154
  4. package/dist/bin/cli.js.map +2 -2
  5. package/dist/chunks/{chunk-3XER4E5W.js → chunk-4ZRU52J2.js} +6 -5
  6. package/dist/chunks/{chunk-3XER4E5W.js.map → chunk-4ZRU52J2.js.map} +2 -2
  7. package/dist/chunks/{chunk-NVRBTSQG.js → chunk-5X4HCN7J.js} +4 -4
  8. package/dist/chunks/chunk-5X4HCN7J.js.map +7 -0
  9. package/dist/chunks/{chunk-FZITJSSS.js → chunk-7CCVOL5M.js} +14 -14
  10. package/dist/chunks/chunk-7CCVOL5M.js.map +7 -0
  11. package/dist/chunks/{chunk-AE3QK5QW.js → chunk-7ZLF4NE5.js} +31 -26
  12. package/dist/chunks/chunk-7ZLF4NE5.js.map +7 -0
  13. package/dist/chunks/{chunk-HIZMY3EP.js → chunk-AR7LHIFY.js} +8 -2
  14. package/dist/chunks/chunk-AR7LHIFY.js.map +7 -0
  15. package/dist/chunks/{chunk-7HWQUVTU.js → chunk-J4IPTP5X.js} +1839 -443
  16. package/dist/chunks/chunk-J4IPTP5X.js.map +7 -0
  17. package/dist/chunks/{chunk-5ETZFREW.js → chunk-QWTQZHG3.js} +186 -79
  18. package/dist/chunks/chunk-QWTQZHG3.js.map +7 -0
  19. package/dist/chunks/{chunk-STDY3OVM.js → chunk-XTKNX4FW.js} +3 -3
  20. package/dist/chunks/{chunk-STDY3OVM.js.map → chunk-XTKNX4FW.js.map} +2 -2
  21. package/dist/chunks/{fs-ZI5JEU7V.js → fs-G3ANWEFP.js} +2 -2
  22. package/dist/lib/client/index.js +381 -159
  23. package/dist/lib/client/index.js.map +3 -3
  24. package/dist/lib/server/index.js +14365 -6276
  25. package/dist/lib/server/index.js.map +4 -4
  26. package/dist/lib/shared/index.js +296 -87
  27. package/dist/lib/shared/index.js.map +4 -4
  28. package/dist/lib/shared/richtext/index.js +1 -1
  29. package/dist/lib/test-utils/index.js +27 -21
  30. package/dist/lib/test-utils/index.js.map +2 -2
  31. package/lib/client/ErrorBoundary.test.tsx +147 -90
  32. package/lib/client/ErrorBoundary.tsx +8 -5
  33. package/lib/client/componentRegistry.ts +0 -1
  34. package/lib/client/core/ComponentBuilder.test.ts +150 -0
  35. package/lib/client/core/ComponentBuilder.ts +112 -12
  36. package/lib/client/core/ComponentRenderer.test.tsx +1 -2
  37. package/lib/client/core/builders/embedBuilder.ts +1 -1
  38. package/lib/client/core/builders/linkBuilder.ts +2 -2
  39. package/lib/client/core/builders/linkNodeBuilder.ts +1 -1
  40. package/lib/client/core/builders/listBuilder.ts +41 -4
  41. package/lib/client/core/builders/localeListBuilder.ts +2 -2
  42. package/lib/client/core/cmsTemplateProcessor.ts +1 -2
  43. package/lib/client/hmr/HMRManager.tsx +39 -30
  44. package/lib/client/hmrCssReload.ts +35 -6
  45. package/lib/client/hmrWebSocket.ts +5 -5
  46. package/lib/client/hooks/useColorVariables.ts +12 -9
  47. package/lib/client/hooks/usePropertyAutocomplete.ts +1 -1
  48. package/lib/client/hooks/useVariables.ts +3 -1
  49. package/lib/client/meno-filter/MenoFilter.test.ts +28 -28
  50. package/lib/client/meno-filter/MenoFilter.ts +9 -6
  51. package/lib/client/meno-filter/bindings.ts +3 -3
  52. package/lib/client/meno-filter/init.ts +3 -3
  53. package/lib/client/meno-filter/renderer.ts +8 -4
  54. package/lib/client/meno-filter/ui.ts +1 -1
  55. package/lib/client/meno-filter/updates.ts +3 -2
  56. package/lib/client/meno-filter/utils.ts +1 -1
  57. package/lib/client/navigation.test.ts +40 -44
  58. package/lib/client/responsiveStyleResolver.knownTokens.test.ts +71 -0
  59. package/lib/client/responsiveStyleResolver.test.ts +5 -5
  60. package/lib/client/responsiveStyleResolver.ts +61 -4
  61. package/lib/client/routing/RouteLoader.test.ts +1 -1
  62. package/lib/client/routing/RouteLoader.ts +8 -3
  63. package/lib/client/routing/Router.tsx +181 -152
  64. package/lib/client/scripts/ScriptExecutor.ts +3 -3
  65. package/lib/client/services/PrefetchService.test.ts +1 -1
  66. package/lib/client/services/PrefetchService.ts +13 -5
  67. package/lib/client/styleProcessor.ts +9 -3
  68. package/lib/client/styles/StyleInjector.ts +1 -1
  69. package/lib/client/styles/UtilityClassCollector.ts +54 -13
  70. package/lib/client/templateEngine.test.ts +17 -23
  71. package/lib/client/templateEngine.ts +7 -13
  72. package/lib/client/theme.test.ts +1 -1
  73. package/lib/server/__integration__/server-lifecycle.test.ts +3 -1
  74. package/lib/server/__integration__/static-assets.test.ts +2 -2
  75. package/lib/server/__integration__/test-helpers.ts +3 -4
  76. package/lib/server/astro/cmsPageEmitter.ts +4 -5
  77. package/lib/server/astro/componentEmitter.ts +11 -8
  78. package/lib/server/astro/nodeToAstro.test.ts +4 -4
  79. package/lib/server/astro/nodeToAstro.ts +41 -36
  80. package/lib/server/astro/normalizeOrphanTemplateProps.test.ts +11 -11
  81. package/lib/server/astro/normalizeOrphanTemplateProps.ts +7 -6
  82. package/lib/server/astro/pageEmitter.ts +1 -1
  83. package/lib/server/astro/templateTransformer.ts +3 -3
  84. package/lib/server/createServer.ts +2 -2
  85. package/lib/server/cssGenerator.ts +2 -2
  86. package/lib/server/fileWatcher.test.ts +41 -4
  87. package/lib/server/fileWatcher.ts +102 -23
  88. package/lib/server/index.ts +7 -16
  89. package/lib/server/jsonLoader.test.ts +3 -3
  90. package/lib/server/jsonLoader.ts +8 -5
  91. package/lib/server/middleware/cors.test.ts +1 -1
  92. package/lib/server/middleware/cors.ts +2 -2
  93. package/lib/server/middleware/errorHandler.test.ts +2 -2
  94. package/lib/server/middleware/logger.test.ts +3 -3
  95. package/lib/server/middleware/logger.ts +7 -7
  96. package/lib/server/migrateTemplates.ts +3 -3
  97. package/lib/server/projectContext.ts +1 -1
  98. package/lib/server/providers/fileSystemCMSProvider.test.ts +18 -4
  99. package/lib/server/providers/fileSystemCMSProvider.ts +27 -18
  100. package/lib/server/routes/api/cms.ts +1 -1
  101. package/lib/server/routes/api/colors.test.ts +2 -2
  102. package/lib/server/routes/api/components.ts +1 -1
  103. package/lib/server/routes/api/config.ts +3 -3
  104. package/lib/server/routes/api/core-routes.ts +2 -2
  105. package/lib/server/routes/api/enums.test.ts +2 -2
  106. package/lib/server/routes/api/functions.ts +1 -1
  107. package/lib/server/routes/api/variables.test.ts +2 -2
  108. package/lib/server/routes/index.ts +2 -2
  109. package/lib/server/routes/pages.ts +1 -2
  110. package/lib/server/routes/static.ts +1 -2
  111. package/lib/server/runtime/bundler.ts +65 -43
  112. package/lib/server/runtime/fs.ts +13 -13
  113. package/lib/server/runtime/httpServer.ts +3 -3
  114. package/lib/server/services/ColorService.test.ts +3 -3
  115. package/lib/server/services/ColorService.ts +5 -2
  116. package/lib/server/services/EnumService.test.ts +2 -2
  117. package/lib/server/services/EnumService.ts +4 -1
  118. package/lib/server/services/VariableService.test.ts +7 -7
  119. package/lib/server/services/VariableService.ts +5 -2
  120. package/lib/server/services/cmsService.test.ts +44 -44
  121. package/lib/server/services/cmsService.ts +17 -97
  122. package/lib/server/services/componentService.test.ts +10 -16
  123. package/lib/server/services/componentService.ts +20 -12
  124. package/lib/server/services/configService.test.ts +13 -14
  125. package/lib/server/services/configService.ts +30 -0
  126. package/lib/server/services/fileWatcherService.ts +2 -2
  127. package/lib/server/services/pageService.test.ts +7 -7
  128. package/lib/server/services/pageService.ts +18 -5
  129. package/lib/server/ssr/attributeBuilder.ts +2 -2
  130. package/lib/server/ssr/cmsSSRProcessor.ts +1 -2
  131. package/lib/server/ssr/errorOverlay.ts +1 -1
  132. package/lib/server/ssr/htmlGenerator.nonce.test.ts +6 -5
  133. package/lib/server/ssr/htmlGenerator.test.ts +0 -1
  134. package/lib/server/ssr/htmlGenerator.ts +25 -9
  135. package/lib/server/ssr/imageMetadata.ts +2 -2
  136. package/lib/server/ssr/jsCollector.test.ts +5 -5
  137. package/lib/server/ssr/liveReloadIntegration.test.ts +7 -8
  138. package/lib/server/ssr/ssrRenderer.branches.test.ts +9 -9
  139. package/lib/server/ssr/ssrRenderer.test.ts +150 -15
  140. package/lib/server/ssr/ssrRenderer.ts +218 -40
  141. package/lib/server/ssrRenderer.test.ts +6 -6
  142. package/lib/server/utils/jsonLineMapper.ts +7 -7
  143. package/lib/server/validateStyleCoverage.ts +0 -1
  144. package/lib/server/websocketManager.ts +12 -0
  145. package/lib/shared/breakpoints.test.ts +5 -5
  146. package/lib/shared/cmsQuery.test.ts +81 -0
  147. package/lib/shared/cmsQuery.ts +92 -0
  148. package/lib/shared/cmsQueryParser.ts +11 -7
  149. package/lib/shared/colorConversions.ts +9 -9
  150. package/lib/shared/colorVariableUtils.test.ts +22 -0
  151. package/lib/shared/colorVariableUtils.ts +19 -5
  152. package/lib/shared/constants.ts +4 -0
  153. package/lib/shared/cssGeneration.test.ts +33 -0
  154. package/lib/shared/cssGeneration.ts +50 -35
  155. package/lib/shared/cssProperties.test.ts +64 -64
  156. package/lib/shared/cssProperties.ts +2 -2
  157. package/lib/shared/elementClassName.ts +2 -2
  158. package/lib/shared/errorLogger.test.ts +12 -12
  159. package/lib/shared/expressionEvaluator.test.ts +27 -1
  160. package/lib/shared/expressionEvaluator.ts +9 -0
  161. package/lib/shared/fontLoader.test.ts +13 -13
  162. package/lib/shared/fontLoader.ts +2 -2
  163. package/lib/shared/gradientUtils.test.ts +2 -2
  164. package/lib/shared/gradientUtils.ts +15 -8
  165. package/lib/shared/hrefRefs.test.ts +2 -2
  166. package/lib/shared/hrefRefs.ts +1 -1
  167. package/lib/shared/i18n.test.ts +3 -3
  168. package/lib/shared/i18n.ts +5 -4
  169. package/lib/shared/index.ts +29 -0
  170. package/lib/shared/inlineSvgStyleRules.ts +12 -9
  171. package/lib/shared/interactiveStyleMappings.test.ts +21 -21
  172. package/lib/shared/interactiveStyleMappings.ts +2 -8
  173. package/lib/shared/interactiveStyles.test.ts +3 -1
  174. package/lib/shared/itemTemplateUtils.test.ts +5 -5
  175. package/lib/shared/itemTemplateUtils.ts +9 -5
  176. package/lib/shared/jsonRepair.ts +8 -8
  177. package/lib/shared/libraryLoader.test.ts +6 -6
  178. package/lib/shared/linkUtils.ts +1 -1
  179. package/lib/shared/logger.test.ts +66 -0
  180. package/lib/shared/logger.ts +94 -0
  181. package/lib/shared/markdown.ts +25 -0
  182. package/lib/shared/nodeUtils.test.ts +13 -9
  183. package/lib/shared/nodeUtils.ts +27 -4
  184. package/lib/shared/pathSecurity.ts +1 -1
  185. package/lib/shared/pathUtils.ts +1 -2
  186. package/lib/shared/paths/PathConverter.ts +3 -3
  187. package/lib/shared/paths/PathUtils.ts +4 -3
  188. package/lib/shared/paths/PathValidator.ts +1 -1
  189. package/lib/shared/permissions.test.ts +168 -0
  190. package/lib/shared/permissions.ts +162 -0
  191. package/lib/shared/propResolver.test.ts +1 -1
  192. package/lib/shared/propResolver.ts +1 -1
  193. package/lib/shared/registry/BaseNodeTypeRegistry.test.ts +5 -3
  194. package/lib/shared/registry/ClientRegistry.ts +0 -1
  195. package/lib/shared/registry/ComponentRegistry.test.ts +3 -3
  196. package/lib/shared/registry/ComponentRegistry.ts +6 -1
  197. package/lib/shared/registry/NodeTypeDefinition.ts +2 -2
  198. package/lib/shared/registry/SSRRegistry.ts +0 -1
  199. package/lib/shared/registry/fieldPresets.ts +3 -1
  200. package/lib/shared/registry/nodeTypes/CustomNodeType.ts +103 -0
  201. package/lib/shared/registry/nodeTypes/HtmlNodeType.ts +1 -1
  202. package/lib/shared/registry/nodeTypes/IslandNodeType.ts +129 -0
  203. package/lib/shared/registry/nodeTypes/ListNodeType.ts +43 -7
  204. package/lib/shared/registry/nodeTypes/MarkdownNodeType.ts +78 -0
  205. package/lib/shared/registry/nodeTypes/SlotMarkerType.ts +6 -1
  206. package/lib/shared/registry/nodeTypes/index.ts +16 -1
  207. package/lib/shared/responsiveScaling.test.ts +1 -3
  208. package/lib/shared/responsiveScaling.ts +6 -5
  209. package/lib/shared/responsiveStyleUtils.test.ts +0 -1
  210. package/lib/shared/richtext/htmlToTiptap.test.ts +116 -116
  211. package/lib/shared/richtext/htmlToTiptap.ts +1 -1
  212. package/lib/shared/styleNodeUtils.ts +17 -14
  213. package/lib/shared/tailwindThemeScale.ts +256 -0
  214. package/lib/shared/themeDefaults.test.ts +0 -3
  215. package/lib/shared/tree/PathBuilder.test.ts +1 -7
  216. package/lib/shared/tree/PathBuilder.ts +15 -13
  217. package/lib/shared/treePathUtils.test.ts +49 -2
  218. package/lib/shared/treePathUtils.ts +40 -4
  219. package/lib/shared/types/api.ts +105 -7
  220. package/lib/shared/types/cms.test.ts +34 -0
  221. package/lib/shared/types/cms.ts +65 -13
  222. package/lib/shared/types/components.ts +24 -0
  223. package/lib/shared/types/errors.test.ts +1 -1
  224. package/lib/shared/types/index.ts +23 -0
  225. package/lib/shared/types/permissions.ts +139 -0
  226. package/lib/shared/types/variables.ts +3 -3
  227. package/lib/shared/utilityClassConfig.ts +219 -0
  228. package/lib/shared/utilityClassMapper.durability.test.ts +117 -0
  229. package/lib/shared/utilityClassMapper.test.ts +401 -26
  230. package/lib/shared/utilityClassMapper.ts +193 -29
  231. package/lib/shared/utilityClassNames.test.ts +38 -0
  232. package/lib/shared/utilityClassNames.ts +301 -23
  233. package/lib/shared/validation/index.ts +1 -0
  234. package/lib/shared/validation/permissionsValidators.test.ts +49 -0
  235. package/lib/shared/validation/permissionsValidators.ts +49 -0
  236. package/lib/shared/validation/propValidator.test.ts +1 -1
  237. package/lib/shared/validation/propValidator.ts +1 -1
  238. package/lib/shared/validation/schemas.test.ts +41 -0
  239. package/lib/shared/validation/schemas.ts +159 -13
  240. package/lib/shared/validation/validators.test.ts +2 -2
  241. package/lib/shared/viewportUnits.test.ts +13 -0
  242. package/lib/shared/viewportUnits.ts +12 -5
  243. package/lib/test-utils/factories/ConsoleMockFactory.ts +7 -7
  244. package/lib/test-utils/factories/DomMockFactory.ts +10 -4
  245. package/lib/test-utils/factories/ServerMockFactory.ts +1 -1
  246. package/lib/test-utils/factories/StoreMockFactory.ts +5 -5
  247. package/lib/test-utils/mockFactories.ts +1 -1
  248. package/lib/test-utils/mocks.ts +3 -3
  249. package/package.json +3 -5
  250. package/scripts/build-for-publish.mjs +2 -4
  251. package/scripts/build-meno-filter.ts +3 -3
  252. package/tsconfig.json +1 -0
  253. package/vite.config.ts +1 -1
  254. package/build-next.ts +0 -1374
  255. package/build-static.test.ts +0 -453
  256. package/build-static.ts +0 -1072
  257. package/dist/build-static.js +0 -37
  258. package/dist/chunks/chunk-2FN4UOVO.js +0 -6465
  259. package/dist/chunks/chunk-2FN4UOVO.js.map +0 -7
  260. package/dist/chunks/chunk-5ETZFREW.js.map +0 -7
  261. package/dist/chunks/chunk-7E4IF5L7.js +0 -245
  262. package/dist/chunks/chunk-7E4IF5L7.js.map +0 -7
  263. package/dist/chunks/chunk-7HWQUVTU.js.map +0 -7
  264. package/dist/chunks/chunk-AE3QK5QW.js.map +0 -7
  265. package/dist/chunks/chunk-F6KTJYGV.js +0 -322
  266. package/dist/chunks/chunk-F6KTJYGV.js.map +0 -7
  267. package/dist/chunks/chunk-FZITJSSS.js.map +0 -7
  268. package/dist/chunks/chunk-GSYYA5GX.js +0 -77
  269. package/dist/chunks/chunk-GSYYA5GX.js.map +0 -7
  270. package/dist/chunks/chunk-HIZMY3EP.js.map +0 -7
  271. package/dist/chunks/chunk-I2WEGYA7.js +0 -424
  272. package/dist/chunks/chunk-I2WEGYA7.js.map +0 -7
  273. package/dist/chunks/chunk-JNO3CNLJ.js +0 -464
  274. package/dist/chunks/chunk-JNO3CNLJ.js.map +0 -7
  275. package/dist/chunks/chunk-NVRBTSQG.js.map +0 -7
  276. package/dist/chunks/chunk-Q4OBWKXG.js +0 -1143
  277. package/dist/chunks/chunk-Q4OBWKXG.js.map +0 -7
  278. package/dist/chunks/chunk-QTE32Y53.js +0 -3829
  279. package/dist/chunks/chunk-QTE32Y53.js.map +0 -7
  280. package/dist/chunks/configService-PRJZF7Y6.js +0 -14
  281. package/dist/chunks/configService-PRJZF7Y6.js.map +0 -7
  282. package/dist/chunks/constants-KIQEYMAM.js +0 -46
  283. package/dist/chunks/constants-KIQEYMAM.js.map +0 -7
  284. package/dist/chunks/fs-ZI5JEU7V.js.map +0 -7
  285. package/dist/entries/server-router.js +0 -62
  286. package/dist/entries/server-router.js.map +0 -7
  287. package/entries/server-router.tsx +0 -75
  288. package/lib/server/providers/fileSystemPageProvider.test.ts +0 -84
  289. package/lib/server/providers/fileSystemPageProvider.ts +0 -179
  290. package/lib/server/webflow/buildWebflow.ts +0 -623
  291. package/lib/server/webflow/index.ts +0 -23
  292. package/lib/server/webflow/nodeToWebflow.test.ts +0 -3102
  293. package/lib/server/webflow/nodeToWebflow.ts +0 -2372
  294. package/lib/server/webflow/styleMapper.test.ts +0 -348
  295. package/lib/server/webflow/styleMapper.ts +0 -687
  296. package/lib/server/webflow/templateWrapper.ts +0 -49
  297. package/lib/server/webflow/types.ts +0 -389
  298. /package/dist/{build-static.js.map → chunks/fs-G3ANWEFP.js.map} +0 -0
@@ -1,42 +1,71 @@
1
- import {
2
- DEFAULT_BREAKPOINTS,
3
- DEFAULT_FLUID_RANGE,
4
- SCALABLE_CSS_PROPERTIES,
5
- applyRemConversion,
6
- buildFluidClampWithExplicitMin,
7
- buildFluidPropertyValue,
8
- convertPxToRem,
9
- getBreakpointName,
10
- getBreakpointValues,
11
- getScaleMultiplier,
12
- getSmallestBreakpointName,
13
- parseValue,
14
- scalePropertyValue,
15
- shouldConvertProperty
16
- } from "./chunk-I2WEGYA7.js";
17
1
  import {
18
2
  DEFAULT_I18N_CONFIG,
19
3
  isI18nValue,
20
4
  resolveI18nInProps,
21
5
  resolveI18nValue
22
- } from "./chunk-3XER4E5W.js";
6
+ } from "./chunk-4ZRU52J2.js";
23
7
  import {
24
8
  isTiptapDocument,
25
9
  tiptapToHtml
26
- } from "./chunk-NVRBTSQG.js";
10
+ } from "./chunk-5X4HCN7J.js";
27
11
  import {
28
12
  NODE_TYPE,
29
13
  init_constants
30
- } from "./chunk-HIZMY3EP.js";
14
+ } from "./chunk-AR7LHIFY.js";
31
15
  import {
32
16
  __esm,
33
17
  __export,
34
18
  __toCommonJS
35
19
  } from "./chunk-KSBZ2L7C.js";
36
20
 
21
+ // lib/shared/errorLogger.ts
22
+ function setErrorHandler(handler) {
23
+ errorHandler = handler;
24
+ }
25
+ function isDevelopment() {
26
+ if (typeof process !== "undefined" && process.env?.NODE_ENV) {
27
+ return process.env.NODE_ENV === "development";
28
+ }
29
+ return true;
30
+ }
31
+ function logRuntimeError(location, error, context) {
32
+ const entry = {
33
+ location,
34
+ category: "runtime",
35
+ error,
36
+ context,
37
+ timestamp: Date.now()
38
+ };
39
+ if (isDevelopment()) {
40
+ const errorMessage = error instanceof Error ? error.message : String(error);
41
+ console.error(`[${location}] ${errorMessage}`, context ?? "");
42
+ }
43
+ errorHandler?.(entry);
44
+ }
45
+ function logNetworkError(location, error, context) {
46
+ const entry = {
47
+ location,
48
+ category: "network",
49
+ error,
50
+ context,
51
+ timestamp: Date.now()
52
+ };
53
+ if (isDevelopment()) {
54
+ console.error(`[${location}] Network error:`, error, context ?? "");
55
+ }
56
+ errorHandler?.(entry);
57
+ }
58
+ var errorHandler;
59
+ var init_errorLogger = __esm({
60
+ "lib/shared/errorLogger.ts"() {
61
+ "use strict";
62
+ errorHandler = null;
63
+ }
64
+ });
65
+
37
66
  // lib/shared/validation/schemas.ts
38
67
  import { z } from "zod";
39
- var BasePropTypeSchema, PropTypeSchema, I18nValueObjectSchema, BasePropDefinitionSchema, EnumsConfigSchema, ListItemSchemaSchema, ListPropDefinitionSchema, PropDefinitionSchema, StyleMappingSchema, BooleanMappingSchema, IfConditionSchema, LinkMappingSchema, HtmlMappingSchema, StyleObjectSchema, ResponsiveStyleObjectSchema, StyleValueSchema, InteractiveStyleRuleSchema, InteractiveStylesSchema, SlotMarkerSchema, ComponentNodeSchema, HtmlNodeSchema, ComponentInstanceNodeSchema, EmbedNodeSchema, LinkNodeSchema, LocaleListNodeSchema, ListNodeSchemaBasic, ScriptLoadModeSchema, LibraryPositionSchema, ScriptTypeSchema, JSLibraryConfigSchema, CSSLibraryConfigSchema, LibrariesConfigSchema, StructuredComponentDefinitionSchema, ComponentDefinitionSchema, I18nOrStringSchema, LibraryMergeModeSchema, PageLibrariesConfigSchema, CustomCodeConfigSchema, PageMetaDataBaseSchema, PageMetaDataSchema, LineRangeSchema, JSONPageSchema, PageDataWithComponentSchema, PageDataSchema, CMSFieldTypeSchema, CMSFieldDefinitionSchema, CMSClientDataStrategySchema, CMSClientDataConfigSchema, CMSSchemaSchema, CMSItemSchema, CMSDraftItemSchema, CMSFilterConditionSchema, CMSSortConfigSchema, CMSListQuerySchema, CMSListNodeSchema, PageCmsConfigSchema, PageMetaDataWithCMSSchema;
68
+ var BasePropTypeSchema, PropTypeSchema, I18nValueObjectSchema, BasePropDefinitionSchema, EnumsConfigSchema, ListItemSchemaSchema, ListPropDefinitionSchema, PropDefinitionSchema, StyleMappingSchema, BooleanMappingSchema, VerbatimCodeSchema, IfConditionSchema, LinkMappingSchema, HtmlMappingSchema, StyleObjectSchema, ResponsiveStyleObjectSchema, StyleValueSchema, InteractiveStyleRuleSchema, InteractiveStylesSchema, SlotMarkerSchema, ComponentNodeSchema, HtmlNodeSchema, ComponentInstanceNodeSchema, EmbedNodeSchema, LinkNodeSchema, LocaleListNodeSchema, ListNodeSchemaBasic, IslandNodeSchema, MarkdownNodeSchema, CustomNodeSchema, ScriptLoadModeSchema, LibraryPositionSchema, ScriptTypeSchema, JSLibraryConfigSchema, CSSLibraryConfigSchema, LibrariesConfigSchema, StructuredComponentDefinitionSchema, ComponentDefinitionSchema, I18nOrStringSchema, LibraryMergeModeSchema, PageLibrariesConfigSchema, CustomCodeConfigSchema, SitemapPageConfigSchema, PageMetaDataBaseSchema, PageMetaDataSchema, LineRangeSchema, JSONPageSchema, PageDataWithComponentSchema, PageDataSchema, CMSFieldTypeSchema, CMSFieldDefinitionSchema, CMSClientDataStrategySchema, CMSClientDataConfigSchema, CMSSchemaSchema, CMSItemSchema, CMSDraftItemSchema, CMSFilterConditionSchema, CMSSortConfigSchema, CMSListQuerySchema, CMSListNodeSchema, PageCmsConfigSchema, PageDataSourceSchema, PageDataConfigSchema, PageMetaDataWithCMSSchema;
40
69
  var init_schemas = __esm({
41
70
  "lib/shared/validation/schemas.ts"() {
42
71
  "use strict";
@@ -114,7 +143,8 @@ var init_schemas = __esm({
114
143
  prop: z.string(),
115
144
  values: z.record(z.string(), z.boolean())
116
145
  }).passthrough();
117
- IfConditionSchema = z.union([z.boolean(), z.string(), BooleanMappingSchema]);
146
+ VerbatimCodeSchema = z.object({ _code: z.literal(true), expr: z.string() }).passthrough();
147
+ IfConditionSchema = z.union([z.boolean(), z.string(), BooleanMappingSchema, VerbatimCodeSchema]);
118
148
  LinkMappingSchema = z.object({
119
149
  _mapping: z.literal(true),
120
150
  prop: z.string(),
@@ -168,7 +198,7 @@ var init_schemas = __esm({
168
198
  style: StyleValueSchema.optional(),
169
199
  interactiveStyles: InteractiveStylesSchema.optional(),
170
200
  generateElementClass: z.boolean().optional(),
171
- attributes: z.record(z.string(), z.union([z.string(), z.number(), z.boolean(), I18nValueObjectSchema])).optional(),
201
+ attributes: z.record(z.string(), z.union([z.string(), z.number(), z.boolean(), I18nValueObjectSchema, VerbatimCodeSchema])).optional(),
172
202
  props: z.record(z.string(), z.any()).optional(),
173
203
  // Allow props for backward compatibility
174
204
  children: z.union([
@@ -188,7 +218,7 @@ var init_schemas = __esm({
188
218
  style: StyleValueSchema.optional(),
189
219
  interactiveStyles: InteractiveStylesSchema.optional(),
190
220
  generateElementClass: z.boolean().optional(),
191
- attributes: z.record(z.string(), z.union([z.string(), z.number(), z.boolean(), I18nValueObjectSchema])).optional(),
221
+ attributes: z.record(z.string(), z.union([z.string(), z.number(), z.boolean(), I18nValueObjectSchema, VerbatimCodeSchema])).optional(),
192
222
  children: z.union([
193
223
  z.array(z.union([ComponentNodeSchema, z.string(), I18nValueObjectSchema])),
194
224
  z.string(),
@@ -205,7 +235,7 @@ var init_schemas = __esm({
205
235
  style: StyleValueSchema.optional(),
206
236
  interactiveStyles: InteractiveStylesSchema.optional(),
207
237
  generateElementClass: z.boolean().optional(),
208
- attributes: z.record(z.string(), z.union([z.string(), z.number(), z.boolean(), I18nValueObjectSchema])).optional()
238
+ attributes: z.record(z.string(), z.union([z.string(), z.number(), z.boolean(), I18nValueObjectSchema, VerbatimCodeSchema])).optional()
209
239
  }).passthrough()
210
240
  );
211
241
  LinkNodeSchema = z.lazy(
@@ -217,7 +247,7 @@ var init_schemas = __esm({
217
247
  style: StyleValueSchema.optional(),
218
248
  interactiveStyles: InteractiveStylesSchema.optional(),
219
249
  generateElementClass: z.boolean().optional(),
220
- attributes: z.record(z.string(), z.union([z.string(), z.number(), z.boolean(), I18nValueObjectSchema])).optional(),
250
+ attributes: z.record(z.string(), z.union([z.string(), z.number(), z.boolean(), I18nValueObjectSchema, VerbatimCodeSchema])).optional(),
221
251
  children: z.union([
222
252
  z.array(z.union([ComponentNodeSchema, z.string(), I18nValueObjectSchema])),
223
253
  z.string(),
@@ -240,19 +270,29 @@ var init_schemas = __esm({
240
270
  showSeparator: z.boolean().optional(),
241
271
  showFlag: z.boolean().optional(),
242
272
  flagStyle: StyleValueSchema.optional(),
243
- attributes: z.record(z.string(), z.union([z.string(), z.number(), z.boolean(), I18nValueObjectSchema])).optional()
273
+ attributes: z.record(z.string(), z.union([z.string(), z.number(), z.boolean(), I18nValueObjectSchema, VerbatimCodeSchema])).optional()
244
274
  }).passthrough()
245
275
  );
246
276
  ListNodeSchemaBasic = z.lazy(
247
277
  () => z.object({
248
278
  type: z.union([z.literal(NODE_TYPE.LIST), z.literal("cms-list")]),
249
279
  // Support both for migration
250
- sourceType: z.enum(["prop", "collection"]).optional(),
280
+ sourceType: z.enum(["prop", "collection", "remote", "sanity", "expression"]).optional(),
251
281
  // defaults to 'prop'
252
282
  source: z.string().optional(),
253
283
  // Source prop name or collection name
254
284
  collection: z.string().optional(),
255
285
  // Legacy field for cms-list migration
286
+ // Remote-source options (sourceType: 'remote')
287
+ url: z.string().optional(),
288
+ // HTTP/JSON endpoint
289
+ path: z.string().optional(),
290
+ // dot-path into the response to the items array
291
+ // Sanity-source options (sourceType: 'sanity')
292
+ documentType: z.string().optional(),
293
+ // Sanity document `_type`
294
+ slugField: z.string().optional(),
295
+ // field used as the URL slug
256
296
  label: z.string().optional(),
257
297
  if: IfConditionSchema.optional(),
258
298
  itemAs: z.string().optional(),
@@ -267,6 +307,48 @@ var init_schemas = __esm({
267
307
  children: z.array(z.union([ComponentNodeSchema, z.string(), I18nValueObjectSchema])).optional()
268
308
  }).passthrough()
269
309
  );
310
+ IslandNodeSchema = z.lazy(
311
+ () => z.object({
312
+ type: z.literal(NODE_TYPE.ISLAND),
313
+ src: z.string(),
314
+ client: z.object({
315
+ directive: z.enum(["load", "idle", "visible", "media", "only"]),
316
+ value: z.string().optional()
317
+ }).passthrough().optional(),
318
+ props: z.record(z.string(), z.any()).optional(),
319
+ if: IfConditionSchema.optional(),
320
+ children: z.union([
321
+ z.array(z.union([ComponentNodeSchema, z.string(), I18nValueObjectSchema])),
322
+ z.string(),
323
+ I18nValueObjectSchema
324
+ ]).optional()
325
+ }).passthrough()
326
+ );
327
+ MarkdownNodeSchema = z.lazy(
328
+ () => z.object({
329
+ type: z.literal(NODE_TYPE.MARKDOWN),
330
+ source: z.string(),
331
+ label: z.string().optional(),
332
+ if: IfConditionSchema.optional(),
333
+ style: StyleValueSchema.optional(),
334
+ interactiveStyles: InteractiveStylesSchema.optional(),
335
+ generateElementClass: z.boolean().optional(),
336
+ attributes: z.record(z.string(), z.union([z.string(), z.number(), z.boolean(), I18nValueObjectSchema, VerbatimCodeSchema])).optional()
337
+ }).passthrough()
338
+ );
339
+ CustomNodeSchema = z.lazy(
340
+ () => z.object({
341
+ type: z.literal(NODE_TYPE.CUSTOM),
342
+ src: z.string(),
343
+ props: z.record(z.string(), z.any()).optional(),
344
+ if: IfConditionSchema.optional(),
345
+ children: z.union([
346
+ z.array(z.union([ComponentNodeSchema, z.string(), I18nValueObjectSchema])),
347
+ z.string(),
348
+ I18nValueObjectSchema
349
+ ]).optional()
350
+ }).passthrough()
351
+ );
270
352
  ComponentNodeSchema = z.union([
271
353
  HtmlNodeSchema,
272
354
  ComponentInstanceNodeSchema,
@@ -274,7 +356,13 @@ var init_schemas = __esm({
274
356
  EmbedNodeSchema,
275
357
  LinkNodeSchema,
276
358
  LocaleListNodeSchema,
277
- ListNodeSchemaBasic
359
+ ListNodeSchemaBasic,
360
+ IslandNodeSchema,
361
+ MarkdownNodeSchema,
362
+ CustomNodeSchema,
363
+ // A verbatim-code marker is a valid child node (renders natively at build; nothing in the
364
+ // editor preview) — a meno-astro component with any `{_code}` child must validate to open.
365
+ VerbatimCodeSchema
278
366
  ]);
279
367
  ScriptLoadModeSchema = z.enum(["async", "defer"]);
280
368
  LibraryPositionSchema = z.enum(["head", "body-end"]);
@@ -333,6 +421,11 @@ var init_schemas = __esm({
333
421
  bodyStart: z.string().optional(),
334
422
  bodyEnd: z.string().optional()
335
423
  }).passthrough();
424
+ SitemapPageConfigSchema = z.object({
425
+ priority: z.number().optional(),
426
+ changefreq: z.enum(["always", "hourly", "daily", "weekly", "monthly", "yearly", "never"]).optional(),
427
+ exclude: z.boolean().optional()
428
+ }).passthrough();
336
429
  PageMetaDataBaseSchema = z.object({
337
430
  title: I18nOrStringSchema.optional(),
338
431
  description: I18nOrStringSchema.optional(),
@@ -344,7 +437,11 @@ var init_schemas = __esm({
344
437
  slugs: z.record(z.string(), z.string()).optional(),
345
438
  draft: z.boolean().optional(),
346
439
  libraries: PageLibrariesConfigSchema.optional(),
347
- customCode: CustomCodeConfigSchema.optional()
440
+ customCode: CustomCodeConfigSchema.optional(),
441
+ viewTransitions: z.boolean().optional(),
442
+ noindex: z.boolean().optional(),
443
+ prerender: z.boolean().optional(),
444
+ sitemap: SitemapPageConfigSchema.optional()
348
445
  }).passthrough();
349
446
  PageMetaDataSchema = PageMetaDataBaseSchema;
350
447
  LineRangeSchema = z.object({
@@ -355,7 +452,10 @@ var init_schemas = __esm({
355
452
  components: z.record(z.string(), ComponentDefinitionSchema).optional(),
356
453
  root: ComponentNodeSchema.optional(),
357
454
  meta: PageMetaDataSchema.optional(),
358
- _lineMap: z.record(z.string(), LineRangeSchema).optional()
455
+ _lineMap: z.record(z.string(), LineRangeSchema).optional(),
456
+ // Marks a page whose source is outside the meno-astro dialect (read-only in the editor).
457
+ // Explicit (not just .passthrough()) so it survives a future tightening of this schema.
458
+ _unsupported: z.object({ reason: z.string() }).passthrough().optional()
359
459
  }).passthrough().refine(
360
460
  (data) => {
361
461
  return data.meta !== void 0 || data.components !== void 0 || data.root !== void 0;
@@ -407,10 +507,12 @@ var init_schemas = __esm({
407
507
  CMSSchemaSchema = z.object({
408
508
  id: z.string(),
409
509
  name: z.string(),
410
- slugField: z.string(),
411
- urlPattern: z.string(),
510
+ // Optional: a data-only collection (no per-item route) omits both.
511
+ slugField: z.string().optional(),
512
+ urlPattern: z.string().optional(),
412
513
  fields: z.record(CMSFieldDefinitionSchema),
413
- clientData: CMSClientDataConfigSchema.optional()
514
+ clientData: CMSClientDataConfigSchema.optional(),
515
+ rss: z.boolean().optional()
414
516
  }).passthrough();
415
517
  CMSItemSchema = z.object({
416
518
  _id: z.string(),
@@ -456,9 +558,23 @@ var init_schemas = __esm({
456
558
  PageCmsConfigSchema = z.object({
457
559
  id: z.string(),
458
560
  name: z.string(),
459
- slugField: z.string(),
460
- urlPattern: z.string(),
461
- fields: z.record(CMSFieldDefinitionSchema)
561
+ // Optional: a data-only collection (no per-item route) omits both.
562
+ slugField: z.string().optional(),
563
+ urlPattern: z.string().optional(),
564
+ fields: z.record(CMSFieldDefinitionSchema),
565
+ rss: z.boolean().optional()
566
+ }).passthrough();
567
+ PageDataSourceSchema = z.object({
568
+ type: z.literal("fetch"),
569
+ url: z.string(),
570
+ method: z.literal("GET").optional(),
571
+ headers: z.record(z.string(), z.string()).optional(),
572
+ path: z.string().optional(),
573
+ fields: z.record(z.enum(["string", "number", "boolean", "date", "image", "object"])).optional(),
574
+ cardinality: z.enum(["object", "list"]).optional()
575
+ }).passthrough();
576
+ PageDataConfigSchema = z.object({
577
+ sources: z.record(z.string(), PageDataSourceSchema)
462
578
  }).passthrough();
463
579
  PageMetaDataWithCMSSchema = z.object({
464
580
  title: z.union([z.string(), z.object({ _i18n: z.literal(true) }).passthrough()]).optional(),
@@ -469,11 +585,18 @@ var init_schemas = __esm({
469
585
  ogImage: z.string().optional(),
470
586
  ogType: z.string().optional(),
471
587
  slugs: z.record(z.string(), z.string()).optional(),
472
- source: z.enum(["static", "cms"]).optional(),
588
+ source: z.enum(["static", "cms", "ssr"]).optional(),
473
589
  cms: PageCmsConfigSchema.optional(),
590
+ data: PageDataConfigSchema.optional(),
591
+ routeParams: z.array(z.string()).optional(),
592
+ routePreview: z.record(z.string(), z.string()).optional(),
474
593
  draft: z.boolean().optional(),
475
594
  libraries: PageLibrariesConfigSchema.optional(),
476
- customCode: CustomCodeConfigSchema.optional()
595
+ customCode: CustomCodeConfigSchema.optional(),
596
+ viewTransitions: z.boolean().optional(),
597
+ noindex: z.boolean().optional(),
598
+ prerender: z.boolean().optional(),
599
+ sitemap: SitemapPageConfigSchema.optional()
477
600
  }).passthrough();
478
601
  }
479
602
  });
@@ -483,6 +606,7 @@ var BaseComponentRegistry;
483
606
  var init_ComponentRegistry = __esm({
484
607
  "lib/shared/registry/ComponentRegistry.ts"() {
485
608
  "use strict";
609
+ init_errorLogger();
486
610
  BaseComponentRegistry = class {
487
611
  registry = {};
488
612
  listeners = /* @__PURE__ */ new Set();
@@ -557,6 +681,7 @@ var init_ComponentRegistry = __esm({
557
681
  try {
558
682
  listener();
559
683
  } catch (err) {
684
+ logRuntimeError("ComponentRegistry.notify", err);
560
685
  }
561
686
  }
562
687
  }
@@ -1312,7 +1437,12 @@ var init_SlotMarkerType = __esm({
1312
1437
  defaultValues: {},
1313
1438
  treeDisplay: {
1314
1439
  icon: "SLOT_MARKER",
1315
- getLabel: () => "slot"
1440
+ // Show the slot's name so multiple named slots in a component are distinguishable
1441
+ // (e.g. `slot: header`). Unnamed (default) slots stay just `slot`.
1442
+ getLabel: (node) => {
1443
+ const name = node.name;
1444
+ return typeof name === "string" && name ? `slot: ${name}` : "slot";
1445
+ }
1316
1446
  },
1317
1447
  clientRenderer: (_node, _context) => {
1318
1448
  return null;
@@ -1553,14 +1683,36 @@ var init_ListNodeType = __esm({
1553
1683
  * Data source type:
1554
1684
  * - 'prop': Read items from component props (default)
1555
1685
  * - 'collection': Query items from CMS collection
1686
+ * - 'remote': Fetch items from a public HTTP/JSON endpoint at build/SSR time
1687
+ * - 'sanity': Fetch a Sanity document type via GROQ at build/SSR time (read-only, public dataset)
1688
+ * - 'expression': Iterate a verbatim JS expression (`source`) that yields an array — a
1689
+ * `.map()` over arbitrary frontmatter data (e.g. an Astro Action / supabase query) the
1690
+ * dialect can't model as a prop/collection. The item template (`children` + `itemAs`) IS
1691
+ * editable; the source itself is a read-only black box (edit it in the .astro frontmatter).
1692
+ * The editor has no data for it, so it renders empty in the design canvas (real Astro play
1693
+ * renders it for real at build/SSR).
1556
1694
  */
1557
- sourceType: z8.enum(["prop", "collection"]).default("prop"),
1695
+ sourceType: z8.enum(["prop", "collection", "remote", "sanity", "expression"]).default("prop"),
1558
1696
  /**
1559
- * Source identifier:
1697
+ * Source identifier (sourceType 'prop'/'collection'/'expression'; 'remote' uses `url`):
1560
1698
  * - For sourceType 'prop': Prop name (e.g., "items") or template expression (e.g., "{{category.items}}")
1561
1699
  * - For sourceType 'collection': Collection name (e.g., "posts", "authors")
1700
+ * - For sourceType 'expression': the verbatim JS expression iterated by `.map()` (e.g. "notes?")
1701
+ */
1702
+ source: z8.string().optional(),
1703
+ // Remote-only options (sourceType: 'remote')
1704
+ /** HTTP(S) endpoint returning JSON, fetched at build/SSR time (e.g. a public REST API). */
1705
+ url: z8.string().optional(),
1706
+ /**
1707
+ * Dot-path into the JSON response to reach the items array (e.g. "data.items").
1708
+ * Empty/absent = the response body is itself the array.
1562
1709
  */
1563
- source: z8.string(),
1710
+ path: z8.string().optional(),
1711
+ // Sanity-only options (sourceType: 'sanity')
1712
+ /** Sanity document `_type` to fetch (`*[_type == "<documentType>"]`). projectId/dataset come from project config. */
1713
+ documentType: z8.string().optional(),
1714
+ /** Field used as the URL slug (for synthesizing item links); defaults to 'slug'. */
1715
+ slugField: z8.string().optional(),
1564
1716
  label: z8.string().optional(),
1565
1717
  // Custom label displayed in structure tree
1566
1718
  if: IfConditionSchema.optional(),
@@ -1613,8 +1765,9 @@ var init_ListNodeType = __esm({
1613
1765
  getLabel: (node) => {
1614
1766
  const listNode = node;
1615
1767
  const sourceType = listNode.sourceType || "prop";
1616
- const prefix = sourceType === "collection" ? "CMS List" : "List";
1617
- return listNode.source ? `${prefix}: ${listNode.source}` : prefix;
1768
+ const prefix = sourceType === "collection" ? "CMS List" : sourceType === "remote" ? "Remote List" : sourceType === "sanity" ? "Sanity List" : sourceType === "expression" ? "Loop" : "List";
1769
+ const src = sourceType === "remote" ? listNode.url : sourceType === "sanity" ? listNode.documentType : listNode.source;
1770
+ return src ? `${prefix}: ${src}` : prefix;
1618
1771
  }
1619
1772
  },
1620
1773
  clientRenderer: (node, context) => {
@@ -1631,7 +1784,7 @@ var init_ListNodeType = __esm({
1631
1784
  key: context.key,
1632
1785
  "data-list": "true",
1633
1786
  "data-source-type": sourceType,
1634
- "data-source": listNode.source,
1787
+ "data-source": sourceType === "remote" ? listNode.url : sourceType === "sanity" ? listNode.documentType : listNode.source,
1635
1788
  style: {
1636
1789
  padding: "8px 12px",
1637
1790
  background: bgColor,
@@ -1657,7 +1810,7 @@ var init_ListNodeType = __esm({
1657
1810
  label: "Source Type",
1658
1811
  type: "select",
1659
1812
  required: false,
1660
- options: ["prop", "collection"]
1813
+ options: ["prop", "collection", "remote", "sanity"]
1661
1814
  },
1662
1815
  {
1663
1816
  name: "source",
@@ -1678,6 +1831,240 @@ var init_ListNodeType = __esm({
1678
1831
  }
1679
1832
  });
1680
1833
 
1834
+ // lib/shared/registry/nodeTypes/IslandNodeType.ts
1835
+ import { z as z9 } from "zod";
1836
+ import { createElement as h7 } from "react";
1837
+ function islandName(src) {
1838
+ const base = src.split("/").pop() ?? src;
1839
+ return base.replace(/\.(tsx|jsx|vue|svelte)$/i, "") || base;
1840
+ }
1841
+ function islandChildren(node) {
1842
+ const { children } = node;
1843
+ if (Array.isArray(children)) return children.length > 0 ? children : void 0;
1844
+ if (typeof children === "string") return children.length > 0 ? children : void 0;
1845
+ return void 0;
1846
+ }
1847
+ function escapeHtml(value) {
1848
+ return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
1849
+ }
1850
+ var IslandClientDirectiveSchema, IslandNodeSchemaInternal, IslandNodeType;
1851
+ var init_IslandNodeType = __esm({
1852
+ "lib/shared/registry/nodeTypes/IslandNodeType.ts"() {
1853
+ "use strict";
1854
+ init_schemas();
1855
+ init_createNodeType();
1856
+ init_fieldPresets();
1857
+ IslandClientDirectiveSchema = z9.object({
1858
+ directive: z9.enum(["load", "idle", "visible", "media", "only"]),
1859
+ value: z9.string().optional()
1860
+ }).passthrough();
1861
+ IslandNodeSchemaInternal = z9.object({
1862
+ type: z9.literal("island"),
1863
+ // Path to the framework component file relative to `src/islands/`
1864
+ // (e.g. "Counter.tsx", "widgets/Chart.vue"). The extension derives the
1865
+ // framework, which drives the Astro integration that gets provisioned.
1866
+ src: z9.string(),
1867
+ client: IslandClientDirectiveSchema.optional(),
1868
+ props: z9.record(z9.string(), z9.any()).optional(),
1869
+ if: IfConditionSchema.optional(),
1870
+ // Conditional rendering - skip node when false
1871
+ // Slotted children (rendered server-side into the island's <slot/>).
1872
+ children: z9.union([z9.array(z9.any()), z9.string()]).optional()
1873
+ }).passthrough();
1874
+ IslandNodeType = createNodeType({
1875
+ type: "island",
1876
+ displayName: "Island",
1877
+ category: "special",
1878
+ schema: IslandNodeSchemaInternal,
1879
+ defaultValues: {
1880
+ src: "",
1881
+ client: { directive: "load" }
1882
+ },
1883
+ treeDisplay: {
1884
+ icon: "COMPONENT",
1885
+ getLabel: (node) => `Island: ${islandName(node.src) || "?"}`
1886
+ },
1887
+ editableFields: [
1888
+ textField({ name: "src", label: "Island file", required: true, placeholder: "Counter.tsx" }),
1889
+ selectField({
1890
+ name: "client.directive",
1891
+ label: "Hydration",
1892
+ // The empty-value entry clears `client` entirely → a server-rendered island
1893
+ // with zero JS (a valid Astro pattern); the rest map to `client:<directive>`.
1894
+ options: [{ value: "", label: "None (server-only, no JS)" }, "load", "idle", "visible", "media", "only"]
1895
+ })
1896
+ ],
1897
+ // meno-core can't run a framework component. Instead of a loud highlight box
1898
+ // (which made island-heavy pages unreadable), render the island's slotted
1899
+ // children as normal content and fall back to a quiet inline marker when there
1900
+ // are none. The wrapper keeps `data-island` for selection/identification only.
1901
+ // Real hydration is play/build only.
1902
+ clientRenderer: (node, context) => {
1903
+ const children = islandChildren(node);
1904
+ const inner = children ? context.buildChildren(children, context.elementPath) : h7("span", { style: { color: "#9ca3af", fontSize: "13px" } }, islandName(node.src) || "?");
1905
+ return h7("div", { key: context.key, "data-island": node.src, style: { display: "contents" } }, inner);
1906
+ },
1907
+ ssrRenderer: (node, context) => {
1908
+ const children = islandChildren(node);
1909
+ const inner = children ? context.renderChildren(children, context) : `<span style="color:#9ca3af;font-size:13px">${escapeHtml(islandName(node.src) || "?")}</span>`;
1910
+ return `<div data-island="${escapeHtml(node.src)}" style="display:contents">${inner}</div>`;
1911
+ },
1912
+ capabilities: {
1913
+ canHaveChildren: true,
1914
+ canHaveStyle: false,
1915
+ canHaveAttributes: false,
1916
+ requiresProps: ["src"]
1917
+ }
1918
+ });
1919
+ }
1920
+ });
1921
+
1922
+ // lib/shared/markdown.ts
1923
+ import MarkdownIt from "markdown-it";
1924
+ function renderMarkdown(source) {
1925
+ if (typeof source !== "string" || source.trim() === "") return "";
1926
+ return md.render(source);
1927
+ }
1928
+ var md;
1929
+ var init_markdown = __esm({
1930
+ "lib/shared/markdown.ts"() {
1931
+ "use strict";
1932
+ md = new MarkdownIt({ html: true, linkify: true, breaks: false });
1933
+ }
1934
+ });
1935
+
1936
+ // lib/shared/registry/nodeTypes/MarkdownNodeType.ts
1937
+ import { z as z10 } from "zod";
1938
+ import { createElement as h8 } from "react";
1939
+ var MarkdownNodeSchemaInternal, MarkdownNodeType;
1940
+ var init_MarkdownNodeType = __esm({
1941
+ "lib/shared/registry/nodeTypes/MarkdownNodeType.ts"() {
1942
+ "use strict";
1943
+ init_markdown();
1944
+ init_schemas();
1945
+ init_createNodeType();
1946
+ init_fieldPresets();
1947
+ MarkdownNodeSchemaInternal = z10.object({
1948
+ type: z10.literal("markdown"),
1949
+ source: z10.string(),
1950
+ // verbatim Markdown source (whitespace-significant)
1951
+ label: z10.string().optional(),
1952
+ // Custom label displayed in structure tree
1953
+ if: IfConditionSchema.optional(),
1954
+ // Conditional rendering - skip node when false
1955
+ style: StyleValueSchema.optional(),
1956
+ interactiveStyles: InteractiveStylesSchema.optional(),
1957
+ generateElementClass: z10.boolean().optional(),
1958
+ attributes: z10.record(z10.string(), z10.union([z10.string(), z10.number(), z10.boolean()])).optional()
1959
+ }).passthrough();
1960
+ MarkdownNodeType = createNodeType({
1961
+ type: "markdown",
1962
+ displayName: "Markdown",
1963
+ category: "content",
1964
+ schema: MarkdownNodeSchemaInternal,
1965
+ defaultValues: {
1966
+ source: "",
1967
+ style: { base: {} }
1968
+ },
1969
+ treeDisplay: {
1970
+ icon: "HTML_ELEMENT",
1971
+ getLabel: () => "Markdown"
1972
+ },
1973
+ editableFields: [
1974
+ textareaField({
1975
+ name: "source",
1976
+ label: "Markdown",
1977
+ required: true,
1978
+ placeholder: "# Heading\n\nWrite **markdown** here\u2026"
1979
+ })
1980
+ ],
1981
+ clientRenderer: (node, context) => {
1982
+ return h8("div", {
1983
+ key: context.key,
1984
+ dangerouslySetInnerHTML: { __html: renderMarkdown(node.source) }
1985
+ });
1986
+ },
1987
+ ssrRenderer: (node, _context) => {
1988
+ return `<div>${renderMarkdown(node.source)}</div>`;
1989
+ },
1990
+ capabilities: {
1991
+ canHaveChildren: false,
1992
+ requiresProps: ["source"]
1993
+ }
1994
+ });
1995
+ }
1996
+ });
1997
+
1998
+ // lib/shared/registry/nodeTypes/CustomNodeType.ts
1999
+ import { z as z11 } from "zod";
2000
+ import { createElement as h9 } from "react";
2001
+ function customName(src) {
2002
+ const base = src.split("/").pop() ?? src;
2003
+ return base.replace(/\.astro$/i, "") || base;
2004
+ }
2005
+ function customChildren(node) {
2006
+ const { children } = node;
2007
+ if (Array.isArray(children)) return children.length > 0 ? children : void 0;
2008
+ if (typeof children === "string") return children.length > 0 ? children : void 0;
2009
+ return void 0;
2010
+ }
2011
+ function escapeHtml2(value) {
2012
+ return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
2013
+ }
2014
+ var CustomNodeSchemaInternal, CustomNodeType;
2015
+ var init_CustomNodeType = __esm({
2016
+ "lib/shared/registry/nodeTypes/CustomNodeType.ts"() {
2017
+ "use strict";
2018
+ init_schemas();
2019
+ init_createNodeType();
2020
+ init_fieldPresets();
2021
+ CustomNodeSchemaInternal = z11.object({
2022
+ type: z11.literal("custom"),
2023
+ // Path to the hand-authored .astro component relative to `src/custom/`
2024
+ // (e.g. "Fancy.astro", "widgets/Banner.astro").
2025
+ src: z11.string(),
2026
+ props: z11.record(z11.string(), z11.any()).optional(),
2027
+ if: IfConditionSchema.optional(),
2028
+ // Conditional rendering - skip node when false
2029
+ // Slotted children (rendered server-side into the component's default <slot/>).
2030
+ children: z11.union([z11.array(z11.any()), z11.string()]).optional()
2031
+ }).passthrough();
2032
+ CustomNodeType = createNodeType({
2033
+ type: "custom",
2034
+ displayName: "Custom Component",
2035
+ category: "special",
2036
+ schema: CustomNodeSchemaInternal,
2037
+ defaultValues: {
2038
+ src: ""
2039
+ },
2040
+ treeDisplay: {
2041
+ icon: "COMPONENT",
2042
+ getLabel: (node) => `Custom: ${customName(node.src) || "?"}`
2043
+ },
2044
+ editableFields: [textField({ name: "src", label: "Custom .astro file", required: true, placeholder: "Fancy.astro" })],
2045
+ // meno-core can't run a foreign `.astro` file. Render the slotted children as normal
2046
+ // content and fall back to a quiet inline marker when there are none. The wrapper keeps
2047
+ // `data-custom` for selection/identification only. Real rendering is play/build only.
2048
+ clientRenderer: (node, context) => {
2049
+ const children = customChildren(node);
2050
+ const inner = children ? context.buildChildren(children, context.elementPath) : h9("span", { style: { color: "#9ca3af", fontSize: "13px" } }, customName(node.src) || "?");
2051
+ return h9("div", { key: context.key, "data-custom": node.src, style: { display: "contents" } }, inner);
2052
+ },
2053
+ ssrRenderer: (node, context) => {
2054
+ const children = customChildren(node);
2055
+ const inner = children ? context.renderChildren(children, context) : `<span style="color:#9ca3af;font-size:13px">${escapeHtml2(customName(node.src) || "?")}</span>`;
2056
+ return `<div data-custom="${escapeHtml2(node.src)}" style="display:contents">${inner}</div>`;
2057
+ },
2058
+ capabilities: {
2059
+ canHaveChildren: true,
2060
+ canHaveStyle: false,
2061
+ canHaveAttributes: false,
2062
+ requiresProps: ["src"]
2063
+ }
2064
+ });
2065
+ }
2066
+ });
2067
+
1681
2068
  // lib/shared/registry/nodeTypes/index.ts
1682
2069
  function registerBuiltInNodeTypes() {
1683
2070
  globalNodeTypeManager.registerAll(builtInNodeTypes);
@@ -1694,6 +2081,9 @@ var init_nodeTypes = __esm({
1694
2081
  init_LinkNodeType();
1695
2082
  init_LocaleListNodeType();
1696
2083
  init_ListNodeType();
2084
+ init_IslandNodeType();
2085
+ init_MarkdownNodeType();
2086
+ init_CustomNodeType();
1697
2087
  init_HtmlNodeType();
1698
2088
  init_ComponentInstanceNodeType();
1699
2089
  init_SlotMarkerType();
@@ -1701,6 +2091,9 @@ var init_nodeTypes = __esm({
1701
2091
  init_LinkNodeType();
1702
2092
  init_LocaleListNodeType();
1703
2093
  init_ListNodeType();
2094
+ init_IslandNodeType();
2095
+ init_MarkdownNodeType();
2096
+ init_CustomNodeType();
1704
2097
  builtInNodeTypes = [
1705
2098
  HtmlNodeType,
1706
2099
  ComponentInstanceNodeType,
@@ -1708,7 +2101,10 @@ var init_nodeTypes = __esm({
1708
2101
  EmbedNodeType,
1709
2102
  LinkNodeType,
1710
2103
  LocaleListNodeType,
1711
- ListNodeType
2104
+ ListNodeType,
2105
+ IslandNodeType,
2106
+ MarkdownNodeType,
2107
+ CustomNodeType
1712
2108
  ];
1713
2109
  }
1714
2110
  });
@@ -1761,6 +2157,312 @@ var init_registry = __esm({
1761
2157
  }
1762
2158
  });
1763
2159
 
2160
+ // lib/shared/breakpoints.ts
2161
+ var DEFAULT_BREAKPOINTS = {
2162
+ tablet: { breakpoint: 1024, previewPoint: 768 },
2163
+ mobile: { breakpoint: 540, previewPoint: 375 }
2164
+ };
2165
+ function normalizeBreakpointConfig(input) {
2166
+ const result = {};
2167
+ for (const [name, value] of Object.entries(input)) {
2168
+ if (typeof value === "number") {
2169
+ result[name] = { breakpoint: value, previewPoint: value };
2170
+ } else if (typeof value === "object" && value !== null) {
2171
+ result[name] = {
2172
+ breakpoint: value.breakpoint,
2173
+ previewPoint: value.previewPoint ?? value.breakpoint,
2174
+ ...value.label !== void 0 && { label: value.label }
2175
+ };
2176
+ }
2177
+ }
2178
+ return result;
2179
+ }
2180
+ function getBreakpointValues(config) {
2181
+ const result = {};
2182
+ for (const [name, entry] of Object.entries(config)) {
2183
+ result[name] = entry.breakpoint;
2184
+ }
2185
+ return result;
2186
+ }
2187
+ function getPreviewPointValues(config) {
2188
+ const result = {};
2189
+ for (const [name, entry] of Object.entries(config)) {
2190
+ result[name] = entry.previewPoint;
2191
+ }
2192
+ return result;
2193
+ }
2194
+ function getAllBreakpointNames(breakpoints = DEFAULT_BREAKPOINTS) {
2195
+ const names = ["base"];
2196
+ const breakpointEntries = Object.entries(breakpoints);
2197
+ breakpointEntries.sort((a, b) => b[1].breakpoint - a[1].breakpoint);
2198
+ for (const [name] of breakpointEntries) {
2199
+ names.push(name);
2200
+ }
2201
+ return names;
2202
+ }
2203
+ function getBreakpointName(viewportWidth, breakpoints = DEFAULT_BREAKPOINTS) {
2204
+ const breakpointEntries = Object.entries(breakpoints);
2205
+ breakpointEntries.sort((a, b) => a[1].breakpoint - b[1].breakpoint);
2206
+ for (const [name, entry] of breakpointEntries) {
2207
+ if (viewportWidth <= entry.breakpoint) {
2208
+ return name;
2209
+ }
2210
+ }
2211
+ return "base";
2212
+ }
2213
+ function getBreakpointLabel(name, breakpoints = DEFAULT_BREAKPOINTS) {
2214
+ if (name === "base") {
2215
+ return "Desktop";
2216
+ }
2217
+ const entry = breakpoints[name];
2218
+ if (entry?.label) {
2219
+ return entry.label;
2220
+ }
2221
+ return name.replace(/([A-Z])/g, " $1").replace(/^./, (str) => str.toUpperCase()).trim();
2222
+ }
2223
+
2224
+ // lib/shared/responsiveScaling.ts
2225
+ var DEFAULT_FLUID_RANGE = { min: 320, max: 1440 };
2226
+ var DEFAULT_SITE_MARGIN = { min: 16, max: 32 };
2227
+ function getScaleCategory(property) {
2228
+ const propertyStr = property;
2229
+ if (property === "fontSize") return "fontSize";
2230
+ if (propertyStr.startsWith("padding")) return "padding";
2231
+ if (propertyStr.startsWith("margin")) return "margin";
2232
+ if (property === "gap" || property === "rowGap" || property === "columnGap") return "gap";
2233
+ if (propertyStr === "borderRadius" || propertyStr.startsWith("border") && propertyStr.includes("Radius"))
2234
+ return "borderRadius";
2235
+ if (property === "width" || property === "height" || property === "maxWidth" || property === "maxHeight" || property === "minWidth" || property === "minHeight")
2236
+ return "size";
2237
+ return null;
2238
+ }
2239
+ function parseValue(valueStr) {
2240
+ const match = valueStr.trim().match(/^(-?[\d.]+)(px|rem|em|%|pt)$/);
2241
+ if (!match) return null;
2242
+ return {
2243
+ value: parseFloat(match[1] ?? ""),
2244
+ unit: match[2] ?? ""
2245
+ };
2246
+ }
2247
+ var SCALABLE_CSS_PROPERTIES = /* @__PURE__ */ new Set([
2248
+ "padding",
2249
+ "padding-left",
2250
+ "padding-right",
2251
+ "padding-top",
2252
+ "padding-bottom",
2253
+ "paddingLeft",
2254
+ "paddingRight",
2255
+ "paddingTop",
2256
+ "paddingBottom",
2257
+ "margin",
2258
+ "margin-left",
2259
+ "margin-right",
2260
+ "margin-top",
2261
+ "margin-bottom",
2262
+ "marginLeft",
2263
+ "marginRight",
2264
+ "marginTop",
2265
+ "marginBottom",
2266
+ "font-size",
2267
+ "fontSize",
2268
+ "gap",
2269
+ "row-gap",
2270
+ "column-gap",
2271
+ "rowGap",
2272
+ "columnGap",
2273
+ "border-radius",
2274
+ "borderRadius",
2275
+ "border-top-left-radius",
2276
+ "border-top-right-radius",
2277
+ "border-bottom-left-radius",
2278
+ "border-bottom-right-radius",
2279
+ "borderTopLeftRadius",
2280
+ "borderTopRightRadius",
2281
+ "borderBottomLeftRadius",
2282
+ "borderBottomRightRadius",
2283
+ "width",
2284
+ "height",
2285
+ "max-width",
2286
+ "max-height",
2287
+ "min-width",
2288
+ "min-height",
2289
+ "maxWidth",
2290
+ "maxHeight",
2291
+ "minWidth",
2292
+ "minHeight"
2293
+ ]);
2294
+ function calculateResponsiveValue(baseValue, baseReference, scale) {
2295
+ if (Math.abs(baseValue) <= baseReference) {
2296
+ return Math.round(baseValue);
2297
+ }
2298
+ const scaled = baseValue + (baseValue - baseReference) * (scale - 1);
2299
+ return Math.round(scaled);
2300
+ }
2301
+ function getScaleMultiplier(scales, property, breakpoint) {
2302
+ const category = getScaleCategory(property);
2303
+ if (!category || !scales[category]) return null;
2304
+ const scaleConfig = scales[category];
2305
+ return scaleConfig?.[breakpoint] ?? null;
2306
+ }
2307
+ function parseMultiValue(valueStr) {
2308
+ const normalized = valueStr.replace(/(?<=\w)-(?=\d|auto|inherit|initial|unset)/g, " ");
2309
+ return normalized.trim().split(/\s+/).filter((v) => v.length > 0);
2310
+ }
2311
+ function scaleValue(valueStr, baseReference, scale) {
2312
+ const parsed = parseValue(valueStr);
2313
+ if (!parsed) return null;
2314
+ if (parsed.unit === "%" || parsed.unit === "em") {
2315
+ return valueStr.trim();
2316
+ }
2317
+ const scaledValue = calculateResponsiveValue(parsed.value, baseReference, scale);
2318
+ return `${scaledValue}${parsed.unit}`;
2319
+ }
2320
+ function scalePropertyValue(valueStr, baseReference, scale) {
2321
+ const parts = parseMultiValue(valueStr);
2322
+ if (parts.length === 0) return null;
2323
+ const scaledParts = parts.map((part) => {
2324
+ const scaled = scaleValue(part, baseReference, scale);
2325
+ if (scaled !== null) {
2326
+ return scaled;
2327
+ }
2328
+ return part;
2329
+ });
2330
+ return scaledParts.join(" ");
2331
+ }
2332
+ function getResponsiveValues(baseValue, property, scales, breakpointNames) {
2333
+ if (!scales.enabled) {
2334
+ return { base: baseValue };
2335
+ }
2336
+ const result = {
2337
+ base: baseValue
2338
+ };
2339
+ const baseRef = scales.baseReference || 16;
2340
+ const breakpoints = breakpointNames ?? ["tablet", "mobile"];
2341
+ for (const breakpointName of breakpoints) {
2342
+ const scale = getScaleMultiplier(scales, property, breakpointName);
2343
+ if (scale !== null) {
2344
+ result[breakpointName] = scalePropertyValue(baseValue, baseRef, scale);
2345
+ }
2346
+ }
2347
+ return result;
2348
+ }
2349
+ function resolveVariableValueAtBreakpoint(variable, breakpoint, responsiveScales) {
2350
+ if (breakpoint === "base") return variable.value;
2351
+ const override = variable.scales?.[breakpoint];
2352
+ if (override !== void 0) return override;
2353
+ if (responsiveScales?.enabled && variable.type !== "none") {
2354
+ const scale = getScaleMultiplier(responsiveScales, variable.type, breakpoint);
2355
+ if (scale !== null) {
2356
+ const baseRef = responsiveScales.baseReference || 16;
2357
+ const scaled = scalePropertyValue(variable.value, baseRef, scale);
2358
+ if (scaled !== null) return scaled;
2359
+ }
2360
+ }
2361
+ return variable.value;
2362
+ }
2363
+ function getSmallestBreakpointName(breakpoints) {
2364
+ if (!breakpoints) return null;
2365
+ const entries = Object.entries(breakpoints);
2366
+ const firstEntry = entries[0];
2367
+ if (entries.length === 0 || firstEntry === void 0) return null;
2368
+ let smallestName = firstEntry[0];
2369
+ let smallestWidth = firstEntry[1].breakpoint;
2370
+ for (const [name, cfg] of entries) {
2371
+ if (cfg.breakpoint < smallestWidth) {
2372
+ smallestWidth = cfg.breakpoint;
2373
+ smallestName = name;
2374
+ }
2375
+ }
2376
+ return smallestName;
2377
+ }
2378
+ function buildFluidClamp(baseValue, unit, scale, vpMin, vpMax, baseReference = 16) {
2379
+ const max = baseValue;
2380
+ const min = calculateResponsiveValue(baseValue, baseReference, scale);
2381
+ if (min === max || vpMax === vpMin) {
2382
+ return `${formatNumber(max)}${unit}`;
2383
+ }
2384
+ const unitToPx = unit === "rem" ? 16 : 1;
2385
+ const minPx = min * unitToPx;
2386
+ const maxPx = max * unitToPx;
2387
+ const slopePx = (maxPx - minPx) / (vpMax - vpMin);
2388
+ const interceptPx = minPx - slopePx * vpMin;
2389
+ const interceptInUnit = interceptPx / unitToPx;
2390
+ const slopeVw = slopePx * 100;
2391
+ return `clamp(${formatNumber(min)}${unit}, ${formatNumber(interceptInUnit)}${unit} + ${formatNumber(slopeVw)}vw, ${formatNumber(max)}${unit})`;
2392
+ }
2393
+ function buildFluidClampWithExplicitMin(minValue, maxValue, unit, vpMin, vpMax) {
2394
+ if (minValue === maxValue || vpMax === vpMin) {
2395
+ return `${formatNumber(maxValue)}${unit}`;
2396
+ }
2397
+ const unitToPx = unit === "rem" ? 16 : 1;
2398
+ const minPx = minValue * unitToPx;
2399
+ const maxPx = maxValue * unitToPx;
2400
+ const slopePx = (maxPx - minPx) / (vpMax - vpMin);
2401
+ const interceptPx = minPx - slopePx * vpMin;
2402
+ const interceptInUnit = interceptPx / unitToPx;
2403
+ const slopeVw = slopePx * 100;
2404
+ return `clamp(${formatNumber(minValue)}${unit}, ${formatNumber(interceptInUnit)}${unit} + ${formatNumber(slopeVw)}vw, ${formatNumber(maxValue)}${unit})`;
2405
+ }
2406
+ function formatNumber(n) {
2407
+ if (Number.isInteger(n)) return String(n);
2408
+ return Number(n.toFixed(4)).toString();
2409
+ }
2410
+ function buildSiteMarginClamp(siteMargin, fluidRange) {
2411
+ const { min, max } = siteMargin;
2412
+ const { min: vpMin, max: vpMax } = fluidRange;
2413
+ if (min === max || vpMax === vpMin) {
2414
+ return `${formatNumber(max)}px`;
2415
+ }
2416
+ const slopePx = (max - min) / (vpMax - vpMin);
2417
+ const interceptPx = min - slopePx * vpMin;
2418
+ const slopeVw = slopePx * 100;
2419
+ return `clamp(${formatNumber(min)}px, ${formatNumber(interceptPx)}px + ${formatNumber(slopeVw)}vw, ${formatNumber(max)}px)`;
2420
+ }
2421
+ function buildFluidPropertyValue(valueStr, scale, vpMin, vpMax, baseReference = 16) {
2422
+ const parts = parseMultiValue(valueStr);
2423
+ if (parts.length === 0) return null;
2424
+ let anyScaled = false;
2425
+ const out = parts.map((part) => {
2426
+ const parsed = parseValue(part);
2427
+ if (!parsed) return part;
2428
+ if (parsed.unit === "%" || parsed.unit === "em") return part;
2429
+ anyScaled = true;
2430
+ return buildFluidClamp(parsed.value, parsed.unit, scale, vpMin, vpMax, baseReference);
2431
+ });
2432
+ return anyScaled ? out.join(" ") : null;
2433
+ }
2434
+ var DEFAULT_RESPONSIVE_SCALES = {
2435
+ enabled: false,
2436
+ mode: "breakpoints",
2437
+ baseReference: 16,
2438
+ fluidRange: { ...DEFAULT_FLUID_RANGE },
2439
+ siteMargin: { ...DEFAULT_SITE_MARGIN },
2440
+ fontSize: {
2441
+ tablet: 0.88,
2442
+ mobile: 0.75
2443
+ },
2444
+ padding: {
2445
+ tablet: 0.75,
2446
+ mobile: 0.5
2447
+ },
2448
+ margin: {
2449
+ tablet: 0.7,
2450
+ mobile: 0.45
2451
+ },
2452
+ gap: {
2453
+ tablet: 0.65,
2454
+ mobile: 0.4
2455
+ },
2456
+ borderRadius: {
2457
+ tablet: 0.85,
2458
+ mobile: 0.7
2459
+ },
2460
+ size: {
2461
+ tablet: 0.9,
2462
+ mobile: 0.75
2463
+ }
2464
+ };
2465
+
1764
2466
  // lib/shared/types/prefetch.ts
1765
2467
  var DEFAULT_PREFETCH_CONFIG = {
1766
2468
  enabled: false,
@@ -1998,18 +2700,29 @@ var IRREGULAR_PLURALS = {
1998
2700
  vertices: "vertex",
1999
2701
  matrices: "matrix"
2000
2702
  };
2001
- function singularize(collection) {
2703
+ function toIdentifier(name) {
2704
+ if (/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name)) return name;
2705
+ const parts = name.split(/[^A-Za-z0-9]+/).filter(Boolean);
2706
+ if (parts.length === 0) return "item";
2707
+ const camel = parts[0] + parts.slice(1).map((p) => p[0].toUpperCase() + p.slice(1)).join("");
2708
+ return /^[0-9]/.test(camel) ? `_${camel}` : camel;
2709
+ }
2710
+ function singularizeRaw(collection) {
2002
2711
  if (IRREGULAR_PLURALS[collection]) {
2003
2712
  return IRREGULAR_PLURALS[collection];
2004
2713
  }
2005
2714
  if (collection.endsWith("ies")) {
2006
- return collection.slice(0, -3) + "y";
2715
+ return `${collection.slice(0, -3)}y`;
2007
2716
  }
2008
2717
  if (collection.endsWith("ses") || collection.endsWith("xes") || collection.endsWith("zes") || collection.endsWith("ches") || collection.endsWith("shes")) {
2009
2718
  return collection.slice(0, -2);
2010
2719
  }
2011
2720
  return collection.endsWith("s") ? collection.slice(0, -1) : collection;
2012
2721
  }
2722
+ function singularize(collection) {
2723
+ if (typeof collection !== "string" || collection === "") return "item";
2724
+ return toIdentifier(singularizeRaw(collection));
2725
+ }
2013
2726
  function isItemDraftForLocale(item, locale) {
2014
2727
  return item._draftLocales?.includes(locale) === true;
2015
2728
  }
@@ -2053,6 +2766,10 @@ function evaluateNode(node, context) {
2053
2766
  const left2 = evaluateNode(binaryNode.left, context);
2054
2767
  return left2 ? left2 : evaluateNode(binaryNode.right, context);
2055
2768
  }
2769
+ if (binaryNode.operator === "??") {
2770
+ const left2 = evaluateNode(binaryNode.left, context);
2771
+ return left2 === null || left2 === void 0 ? evaluateNode(binaryNode.right, context) : left2;
2772
+ }
2056
2773
  const left = evaluateNode(binaryNode.left, context);
2057
2774
  const right = evaluateNode(binaryNode.right, context);
2058
2775
  switch (binaryNode.operator) {
@@ -2266,7 +2983,8 @@ function processItemTemplate(text, ctx, resolveValue) {
2266
2983
  function resolveCompleteTemplateRaw(template, ctx, resolveValue) {
2267
2984
  const match = template.match(/^\{\{(\w+)\.([^}]+)\}\}$/);
2268
2985
  if (!match) return void 0;
2269
- const [, varName, fieldPath] = match;
2986
+ const varName = match[1] ?? "";
2987
+ const fieldPath = match[2] ?? "";
2270
2988
  const trimmedField = fieldPath.trim();
2271
2989
  if (/[?:<>=!&|+\-*/%]/.test(trimmedField)) return void 0;
2272
2990
  const item = ctx[varName];
@@ -2312,7 +3030,8 @@ function resolveItemsTemplate(template, ctx) {
2312
3030
  if (!match) {
2313
3031
  return template;
2314
3032
  }
2315
- const [, varName, fieldPath] = match;
3033
+ const varName = match[1] ?? "";
3034
+ const fieldPath = match[2] ?? "";
2316
3035
  const item = ctx[varName];
2317
3036
  if (!item || typeof item !== "object") {
2318
3037
  return void 0;
@@ -2329,7 +3048,8 @@ function resolveItemsTemplate(template, ctx) {
2329
3048
  function resolveTemplateRawValue(template, ctx) {
2330
3049
  const match = template.match(/^\{\{(\w+)\.([^}]+)\}\}$/);
2331
3050
  if (!match) return void 0;
2332
- const [, varName, fieldPath] = match;
3051
+ const varName = match[1] ?? "";
3052
+ const fieldPath = match[2] ?? "";
2333
3053
  const item = ctx[varName];
2334
3054
  if (!item || typeof item !== "object") return void 0;
2335
3055
  return getNestedValue(item, fieldPath.trim());
@@ -2367,6 +3087,7 @@ function buildItemUrl(urlPattern, item, slugField, locale, i18nConfig) {
2367
3087
  return urlPattern.replace("{{slug}}", String(slug));
2368
3088
  }
2369
3089
  function addItemUrl(item, schema, locale, i18nConfig) {
3090
+ if (!schema.urlPattern || !schema.slugField) return item;
2370
3091
  return {
2371
3092
  ...item,
2372
3093
  _url: buildItemUrl(schema.urlPattern, item, schema.slugField, locale, i18nConfig)
@@ -2542,7 +3263,8 @@ function extractNodeProperties(node) {
2542
3263
  }
2543
3264
  function isLikelyComponentTag(tag) {
2544
3265
  if (!tag) return false;
2545
- return tag.length > 0 && tag[0] === tag[0].toUpperCase() && tag[0] !== tag[0].toLowerCase();
3266
+ const first = tag[0];
3267
+ return first !== void 0 && first === first.toUpperCase() && first !== first.toLowerCase();
2546
3268
  }
2547
3269
  function isSlotMarker(node) {
2548
3270
  return node?.type === NODE_TYPE.SLOT;
@@ -2575,6 +3297,12 @@ function isLinkNode(node) {
2575
3297
  function isLocaleListNode(node) {
2576
3298
  return node?.type === NODE_TYPE.LOCALE_LIST;
2577
3299
  }
3300
+ function isIslandNode(node) {
3301
+ return node?.type === NODE_TYPE.ISLAND;
3302
+ }
3303
+ function isCustomNode(node) {
3304
+ return node?.type === NODE_TYPE.CUSTOM;
3305
+ }
2578
3306
  function isCMSListNode(node) {
2579
3307
  if (node === null || typeof node !== "object") return false;
2580
3308
  const n = node;
@@ -2586,10 +3314,10 @@ function isListNode(node) {
2586
3314
  return n.type === NODE_TYPE.LIST || n.type === "cms-list";
2587
3315
  }
2588
3316
  function isValidNodeType(type) {
2589
- return type === NODE_TYPE.NODE || type === NODE_TYPE.COMPONENT || type === NODE_TYPE.SLOT || type === NODE_TYPE.EMBED || type === NODE_TYPE.LINK || type === NODE_TYPE.LOCALE_LIST || type === NODE_TYPE.LIST || type === "cms-list";
3317
+ return type === NODE_TYPE.NODE || type === NODE_TYPE.COMPONENT || type === NODE_TYPE.SLOT || type === NODE_TYPE.EMBED || type === NODE_TYPE.LINK || type === NODE_TYPE.LOCALE_LIST || type === NODE_TYPE.LIST || type === NODE_TYPE.ISLAND || type === NODE_TYPE.CUSTOM || type === NODE_TYPE.MARKDOWN || type === "cms-list";
2590
3318
  }
2591
3319
  function canHaveChildren(node) {
2592
- return node !== null && node !== void 0 && !isSlotMarker(node);
3320
+ return node !== null && node !== void 0 && !isSlotMarker(node) && node._code !== true;
2593
3321
  }
2594
3322
  function canHaveStyle(node) {
2595
3323
  return node !== null && node !== void 0 && !isSlotMarker(node);
@@ -2685,7 +3413,7 @@ function coerceValue(value, expectedType) {
2685
3413
  }
2686
3414
  if (typeof value === "string") {
2687
3415
  const num = Number(value);
2688
- if (!isNaN(num) && isFinite(num)) {
3416
+ if (!Number.isNaN(num) && Number.isFinite(num)) {
2689
3417
  return num;
2690
3418
  }
2691
3419
  }
@@ -2891,7 +3619,7 @@ function resolveComponentProps(options) {
2891
3619
  result = resolveI18nInProps(result, locale, i18nConfig);
2892
3620
  }
2893
3621
  return wrapRichTextProps(result, propDefs);
2894
- } catch (error) {
3622
+ } catch (_error) {
2895
3623
  const resolvedProps = {};
2896
3624
  for (const [propName, propDef] of Object.entries(propDefs)) {
2897
3625
  if (propDef && typeof propDef === "object" && "default" in propDef) {
@@ -2922,221 +3650,6 @@ function resolvePropsFromDefinition(componentDef, passedProps = {}, children = [
2922
3650
  });
2923
3651
  }
2924
3652
 
2925
- // lib/shared/cssNamedColors.ts
2926
- var CSS_NAMED_COLORS = /* @__PURE__ */ new Set([
2927
- // CSS Level 4 named colors
2928
- "aliceblue",
2929
- "antiquewhite",
2930
- "aqua",
2931
- "aquamarine",
2932
- "azure",
2933
- "beige",
2934
- "bisque",
2935
- "black",
2936
- "blanchedalmond",
2937
- "blue",
2938
- "blueviolet",
2939
- "brown",
2940
- "burlywood",
2941
- "cadetblue",
2942
- "chartreuse",
2943
- "chocolate",
2944
- "coral",
2945
- "cornflowerblue",
2946
- "cornsilk",
2947
- "crimson",
2948
- "cyan",
2949
- "darkblue",
2950
- "darkcyan",
2951
- "darkgoldenrod",
2952
- "darkgray",
2953
- "darkgreen",
2954
- "darkgrey",
2955
- "darkkhaki",
2956
- "darkmagenta",
2957
- "darkolivegreen",
2958
- "darkorange",
2959
- "darkorchid",
2960
- "darkred",
2961
- "darksalmon",
2962
- "darkseagreen",
2963
- "darkslateblue",
2964
- "darkslategray",
2965
- "darkslategrey",
2966
- "darkturquoise",
2967
- "darkviolet",
2968
- "deeppink",
2969
- "deepskyblue",
2970
- "dimgray",
2971
- "dimgrey",
2972
- "dodgerblue",
2973
- "firebrick",
2974
- "floralwhite",
2975
- "forestgreen",
2976
- "fuchsia",
2977
- "gainsboro",
2978
- "ghostwhite",
2979
- "gold",
2980
- "goldenrod",
2981
- "gray",
2982
- "green",
2983
- "greenyellow",
2984
- "grey",
2985
- "honeydew",
2986
- "hotpink",
2987
- "indianred",
2988
- "indigo",
2989
- "ivory",
2990
- "khaki",
2991
- "lavender",
2992
- "lavenderblush",
2993
- "lawngreen",
2994
- "lemonchiffon",
2995
- "lightblue",
2996
- "lightcoral",
2997
- "lightcyan",
2998
- "lightgoldenrodyellow",
2999
- "lightgray",
3000
- "lightgreen",
3001
- "lightgrey",
3002
- "lightpink",
3003
- "lightsalmon",
3004
- "lightseagreen",
3005
- "lightskyblue",
3006
- "lightslategray",
3007
- "lightslategrey",
3008
- "lightsteelblue",
3009
- "lightyellow",
3010
- "lime",
3011
- "limegreen",
3012
- "linen",
3013
- "magenta",
3014
- "maroon",
3015
- "mediumaquamarine",
3016
- "mediumblue",
3017
- "mediumorchid",
3018
- "mediumpurple",
3019
- "mediumseagreen",
3020
- "mediumslateblue",
3021
- "mediumspringgreen",
3022
- "mediumturquoise",
3023
- "mediumvioletred",
3024
- "midnightblue",
3025
- "mintcream",
3026
- "mistyrose",
3027
- "moccasin",
3028
- "navajowhite",
3029
- "navy",
3030
- "oldlace",
3031
- "olive",
3032
- "olivedrab",
3033
- "orange",
3034
- "orangered",
3035
- "orchid",
3036
- "palegoldenrod",
3037
- "palegreen",
3038
- "paleturquoise",
3039
- "palevioletred",
3040
- "papayawhip",
3041
- "peachpuff",
3042
- "peru",
3043
- "pink",
3044
- "plum",
3045
- "powderblue",
3046
- "purple",
3047
- "rebeccapurple",
3048
- "red",
3049
- "rosybrown",
3050
- "royalblue",
3051
- "saddlebrown",
3052
- "salmon",
3053
- "sandybrown",
3054
- "seagreen",
3055
- "seashell",
3056
- "sienna",
3057
- "silver",
3058
- "skyblue",
3059
- "slateblue",
3060
- "slategray",
3061
- "slategrey",
3062
- "snow",
3063
- "springgreen",
3064
- "steelblue",
3065
- "tan",
3066
- "teal",
3067
- "thistle",
3068
- "tomato",
3069
- "turquoise",
3070
- "violet",
3071
- "wheat",
3072
- "white",
3073
- "whitesmoke",
3074
- "yellow",
3075
- "yellowgreen",
3076
- // CSS color keywords
3077
- "transparent",
3078
- "currentcolor",
3079
- // CSS-wide keywords (should never be wrapped in var())
3080
- "inherit",
3081
- "initial",
3082
- "unset",
3083
- "revert"
3084
- ]);
3085
- function isCssNamedColor(value) {
3086
- return CSS_NAMED_COLORS.has(value.toLowerCase());
3087
- }
3088
-
3089
- // lib/shared/styleValueRegistry.ts
3090
- var registry = /* @__PURE__ */ new Map();
3091
- var dynamicRegistry = /* @__PURE__ */ new Map();
3092
- function registerStyleValue(className, value) {
3093
- registry.set(className, value);
3094
- }
3095
- function registerDynamicStyle(className, property, value) {
3096
- dynamicRegistry.set(className, { property, value });
3097
- }
3098
- function getStyleValue(className) {
3099
- return registry.get(className);
3100
- }
3101
- function getDynamicStyle(className) {
3102
- return dynamicRegistry.get(className);
3103
- }
3104
- function isDynamicClass(className) {
3105
- return dynamicRegistry.has(className);
3106
- }
3107
- function getAllDynamicClasses() {
3108
- return Array.from(dynamicRegistry.keys());
3109
- }
3110
- function clearRegistry() {
3111
- registry.clear();
3112
- dynamicRegistry.clear();
3113
- }
3114
- function serializeRegistry() {
3115
- return JSON.stringify({
3116
- standard: Array.from(registry.entries()),
3117
- dynamic: Array.from(dynamicRegistry.entries())
3118
- });
3119
- }
3120
- function hydrateRegistry(data) {
3121
- const parsed = JSON.parse(data);
3122
- if (Array.isArray(parsed)) {
3123
- for (const [key, value] of parsed) {
3124
- registry.set(key, value);
3125
- }
3126
- } else {
3127
- if (parsed.standard) {
3128
- for (const [key, value] of parsed.standard) {
3129
- registry.set(key, value);
3130
- }
3131
- }
3132
- if (parsed.dynamic) {
3133
- for (const [key, value] of parsed.dynamic) {
3134
- dynamicRegistry.set(key, value);
3135
- }
3136
- }
3137
- }
3138
- }
3139
-
3140
3653
  // lib/shared/utilityClassConfig.ts
3141
3654
  var propertyOrder = [
3142
3655
  // Padding
@@ -3212,6 +3725,9 @@ var propertyOrder = [
3212
3725
  // Transform & Effects
3213
3726
  "opacity",
3214
3727
  "transform",
3728
+ "translate",
3729
+ "rotate",
3730
+ "scale",
3215
3731
  "transformOrigin",
3216
3732
  "boxShadow",
3217
3733
  "textShadow",
@@ -3227,6 +3743,8 @@ var propertyOrder = [
3227
3743
  "bottom",
3228
3744
  "left",
3229
3745
  "inset",
3746
+ "insetInline",
3747
+ "insetBlock",
3230
3748
  "zIndex",
3231
3749
  // Grid Layout
3232
3750
  "gridTemplateColumns",
@@ -3235,7 +3753,11 @@ var propertyOrder = [
3235
3753
  "gridGap",
3236
3754
  "gridAutoFlow",
3237
3755
  "gridColumn",
3756
+ "gridColumnStart",
3757
+ "gridColumnEnd",
3238
3758
  "gridRow",
3759
+ "gridRowStart",
3760
+ "gridRowEnd",
3239
3761
  "gridArea",
3240
3762
  "gridAutoRows",
3241
3763
  "gridAutoColumns",
@@ -3264,6 +3786,10 @@ var propertyOrder = [
3264
3786
  "pointerEvents",
3265
3787
  "userSelect",
3266
3788
  "transition",
3789
+ "transitionProperty",
3790
+ "transitionDuration",
3791
+ "transitionTimingFunction",
3792
+ "transitionDelay",
3267
3793
  "objectFit",
3268
3794
  "objectPosition",
3269
3795
  "boxSizing",
@@ -3390,6 +3916,8 @@ var prefixToCSSProperty = {
3390
3916
  // Sizing
3391
3917
  w: "width",
3392
3918
  h: "height",
3919
+ size: "width",
3920
+ // multi-prop (width + height) — expanded in generateRuleForClass / classesToStyles
3393
3921
  "max-w": "max-width",
3394
3922
  "max-h": "max-height",
3395
3923
  "min-w": "min-width",
@@ -3428,13 +3956,27 @@ var prefixToCSSProperty = {
3428
3956
  "grid-cols": "grid-template-columns",
3429
3957
  "grid-rows": "grid-template-rows",
3430
3958
  col: "grid-column",
3959
+ "col-span": "grid-column",
3960
+ "col-start": "grid-column-start",
3961
+ "col-end": "grid-column-end",
3431
3962
  row: "grid-row",
3963
+ "row-span": "grid-row",
3964
+ "row-start": "grid-row-start",
3965
+ "row-end": "grid-row-end",
3432
3966
  "auto-rows": "grid-auto-rows",
3433
3967
  "auto-cols": "grid-auto-columns",
3434
3968
  // Effects
3435
3969
  opacity: "opacity",
3436
3970
  transform: "transform",
3971
+ scale: "scale",
3972
+ rotate: "rotate",
3973
+ "translate-x": "translate",
3974
+ "translate-y": "translate",
3437
3975
  origin: "transform-origin",
3976
+ // Transitions (each maps to a distinct longhand → compose across classes)
3977
+ duration: "transition-duration",
3978
+ delay: "transition-delay",
3979
+ ease: "transition-timing-function",
3438
3980
  shadow: "box-shadow",
3439
3981
  "text-shadow": "text-shadow",
3440
3982
  filter: "filter",
@@ -3445,6 +3987,8 @@ var prefixToCSSProperty = {
3445
3987
  bottom: "bottom",
3446
3988
  left: "left",
3447
3989
  inset: "inset",
3990
+ "inset-x": "inset-inline",
3991
+ "inset-y": "inset-block",
3448
3992
  z: "z-index",
3449
3993
  // Outline
3450
3994
  outline: "outline",
@@ -3709,109 +4253,591 @@ var staticUtilities = {
3709
4253
  "row dense": "grid-flow-row-dense",
3710
4254
  "column dense": "grid-flow-col-dense"
3711
4255
  },
3712
- listStyleType: {
3713
- none: "list-none",
3714
- disc: "list-disc",
3715
- decimal: "list-decimal"
4256
+ listStyleType: {
4257
+ none: "list-none",
4258
+ disc: "list-disc",
4259
+ decimal: "list-decimal"
4260
+ },
4261
+ listStylePosition: {
4262
+ inside: "list-inside",
4263
+ outside: "list-outside"
4264
+ },
4265
+ backfaceVisibility: {
4266
+ visible: "backface-visible",
4267
+ hidden: "backface-hidden"
4268
+ },
4269
+ transition: {
4270
+ none: "transition-none"
4271
+ },
4272
+ transform: {
4273
+ none: "transform-none"
4274
+ },
4275
+ boxShadow: {
4276
+ none: "shadow-none"
4277
+ },
4278
+ outline: {
4279
+ none: "outline-none"
4280
+ }
4281
+ };
4282
+ var SPACING_SCALE = {
4283
+ "0": "0px",
4284
+ px: "1px",
4285
+ "0.5": "2px",
4286
+ "1": "4px",
4287
+ "1.5": "6px",
4288
+ "2": "8px",
4289
+ "2.5": "10px",
4290
+ "3": "12px",
4291
+ "3.5": "14px",
4292
+ "4": "16px",
4293
+ "5": "20px",
4294
+ "6": "24px",
4295
+ "7": "28px",
4296
+ "8": "32px",
4297
+ "9": "36px",
4298
+ "10": "40px",
4299
+ "11": "44px",
4300
+ "12": "48px",
4301
+ "14": "56px",
4302
+ "16": "64px",
4303
+ "20": "80px",
4304
+ "24": "96px",
4305
+ "28": "112px",
4306
+ "32": "128px",
4307
+ "36": "144px",
4308
+ "40": "160px",
4309
+ "44": "176px",
4310
+ "48": "192px",
4311
+ "52": "208px",
4312
+ "56": "224px",
4313
+ "60": "240px",
4314
+ "64": "256px",
4315
+ "72": "288px",
4316
+ "80": "320px",
4317
+ "96": "384px"
4318
+ };
4319
+ var SPACING_SCALE_REVERSE = (() => {
4320
+ const reverse = {};
4321
+ for (const [step, length] of Object.entries(SPACING_SCALE)) {
4322
+ reverse[length] = step;
4323
+ }
4324
+ return reverse;
4325
+ })();
4326
+ var SPACING_SCALE_ROOTS = /* @__PURE__ */ new Set([
4327
+ "p",
4328
+ "pt",
4329
+ "pr",
4330
+ "pb",
4331
+ "pl",
4332
+ "px",
4333
+ "py",
4334
+ "m",
4335
+ "mt",
4336
+ "mr",
4337
+ "mb",
4338
+ "ml",
4339
+ "mx",
4340
+ "my",
4341
+ "gap",
4342
+ "gap-x",
4343
+ "gap-y",
4344
+ "top",
4345
+ "right",
4346
+ "bottom",
4347
+ "left",
4348
+ "inset",
4349
+ "inset-x",
4350
+ "inset-y",
4351
+ "w",
4352
+ "h",
4353
+ "size",
4354
+ "min-w",
4355
+ "min-h",
4356
+ "max-w",
4357
+ "max-h",
4358
+ "basis"
4359
+ ]);
4360
+ var COLOR_TOKEN_ROOTS = /* @__PURE__ */ new Set(["text", "bg", "border", "accent", "outline"]);
4361
+ var staticUtilityReverse = (() => {
4362
+ const reverse = {};
4363
+ for (const [prop, values] of Object.entries(staticUtilities)) {
4364
+ for (const [value, className] of Object.entries(values)) {
4365
+ if (!reverse[className]) {
4366
+ reverse[className] = { prop, value };
4367
+ }
4368
+ }
4369
+ }
4370
+ return reverse;
4371
+ })();
4372
+ var keywordValues = {
4373
+ w: { auto: "auto", full: "100%", screen: "100vw", fit: "fit-content", min: "min-content", max: "max-content" },
4374
+ h: { auto: "auto", full: "100%", screen: "100vh", fit: "fit-content", min: "min-content", max: "max-content" },
4375
+ "max-w": { full: "100%", none: "none", screen: "100vw", fit: "fit-content", min: "min-content", max: "max-content" },
4376
+ "max-h": { full: "100%", none: "none", screen: "100vh", fit: "fit-content", min: "min-content", max: "max-content" },
4377
+ size: { auto: "auto", full: "100%", fit: "fit-content", min: "min-content", max: "max-content" },
4378
+ "min-w": { auto: "auto", full: "100%", fit: "fit-content", min: "min-content", max: "max-content" },
4379
+ "min-h": { auto: "auto", full: "100%", screen: "100vh", fit: "fit-content", min: "min-content", max: "max-content" },
4380
+ m: { auto: "auto" },
4381
+ mt: { auto: "auto" },
4382
+ mr: { auto: "auto" },
4383
+ mb: { auto: "auto" },
4384
+ ml: { auto: "auto" },
4385
+ mx: { auto: "auto" },
4386
+ my: { auto: "auto" },
4387
+ top: { auto: "auto", full: "100%" },
4388
+ right: { auto: "auto", full: "100%" },
4389
+ bottom: { auto: "auto", full: "100%" },
4390
+ left: { auto: "auto", full: "100%" },
4391
+ inset: { auto: "auto", full: "100%" },
4392
+ basis: { auto: "auto", full: "100%" },
4393
+ rounded: { none: "0", full: "9999px" },
4394
+ "rounded-tl": { none: "0", full: "9999px" },
4395
+ "rounded-tr": { none: "0", full: "9999px" },
4396
+ "rounded-bl": { none: "0", full: "9999px" },
4397
+ "rounded-br": { none: "0", full: "9999px" },
4398
+ z: { auto: "auto" },
4399
+ leading: { normal: "normal" },
4400
+ tracking: { normal: "normal" },
4401
+ "inset-x": { auto: "auto", full: "100%" },
4402
+ "inset-y": { auto: "auto", full: "100%" },
4403
+ aspect: { auto: "auto", square: "1 / 1", video: "16 / 9" },
4404
+ order: { first: "-9999", last: "9999", none: "0" }
4405
+ };
4406
+ var genericKeywordRoots = /* @__PURE__ */ new Set(["cursor", "align", "origin", "object", "list"]);
4407
+ var integerValueRoots = /* @__PURE__ */ new Set(["z", "order", "flex", "grow", "shrink"]);
4408
+ var colorTokenProps = /* @__PURE__ */ new Set([
4409
+ "color",
4410
+ "backgroundColor",
4411
+ "borderColor",
4412
+ "accentColor",
4413
+ "outlineColor"
4414
+ ]);
4415
+ var FRACTION_ROOTS = /* @__PURE__ */ new Set([
4416
+ "w",
4417
+ "h",
4418
+ "size",
4419
+ "min-w",
4420
+ "min-h",
4421
+ "max-w",
4422
+ "max-h",
4423
+ "basis",
4424
+ "top",
4425
+ "right",
4426
+ "bottom",
4427
+ "left",
4428
+ "inset",
4429
+ "inset-x",
4430
+ "inset-y",
4431
+ "translate-x",
4432
+ "translate-y"
4433
+ ]);
4434
+ var NEGATABLE_ROOTS = /* @__PURE__ */ new Set([
4435
+ "m",
4436
+ "mt",
4437
+ "mr",
4438
+ "mb",
4439
+ "ml",
4440
+ "mx",
4441
+ "my",
4442
+ "top",
4443
+ "right",
4444
+ "bottom",
4445
+ "left",
4446
+ "inset",
4447
+ "inset-x",
4448
+ "inset-y",
4449
+ "translate-x",
4450
+ "translate-y",
4451
+ "rotate"
4452
+ ]);
4453
+ var EASE_TIMING = {
4454
+ linear: "linear",
4455
+ in: "cubic-bezier(0.4, 0, 1, 1)",
4456
+ out: "cubic-bezier(0, 0, 0.2, 1)",
4457
+ "in-out": "cubic-bezier(0.4, 0, 0.2, 1)",
4458
+ initial: "initial"
4459
+ };
4460
+ var TRANSITION_PROPERTY_VALUES = {
4461
+ "": "color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter",
4462
+ all: "all",
4463
+ colors: "color, background-color, border-color, text-decoration-color, fill, stroke",
4464
+ opacity: "opacity",
4465
+ shadow: "box-shadow",
4466
+ transform: "transform, translate, scale, rotate"
4467
+ };
4468
+ var TRANSITION_DEFAULT_TIMING = "150ms cubic-bezier(0.4, 0, 0.2, 1)";
4469
+ var shadowPresets = {
4470
+ "0": "none",
4471
+ "1": "0 1px 2px rgba(0, 0, 0, 0.05)",
4472
+ "2": "0 4px 12px rgba(0, 0, 0, 0.1)",
4473
+ "3": "0 8px 24px rgba(0, 0, 0, 0.15)",
4474
+ "4": "0 12px 32px rgba(0, 0, 0, 0.2)"
4475
+ };
4476
+ var gradientPresets = {
4477
+ "1": "linear-gradient(90deg, rgba(10,22,40,0.85) 0%, rgba(10,22,40,0.2) 100%)",
4478
+ "2": "linear-gradient(0deg, #a9e8fd, #00aee8 25%, #0f1335 72%)"
4479
+ };
4480
+ var borderPresets = {
4481
+ "0": "1px solid var(--border)",
4482
+ "1": "1px solid var(--border-light)"
4483
+ };
4484
+ var presetClassReverse = (() => {
4485
+ const reverse = {};
4486
+ for (const [key, value] of Object.entries(shadowPresets)) {
4487
+ reverse[`shadow-${key}`] = { prop: "boxShadow", value };
4488
+ }
4489
+ for (const [key, value] of Object.entries(gradientPresets)) {
4490
+ reverse[`bg-gradient-${key}`] = { prop: "background", value };
4491
+ }
4492
+ for (const [key, value] of Object.entries(borderPresets)) {
4493
+ reverse[`border-preset-${key}`] = { prop: "border", value };
4494
+ }
4495
+ return reverse;
4496
+ })();
4497
+
4498
+ // lib/shared/cssNamedColors.ts
4499
+ var CSS_NAMED_COLORS = /* @__PURE__ */ new Set([
4500
+ // CSS Level 4 named colors
4501
+ "aliceblue",
4502
+ "antiquewhite",
4503
+ "aqua",
4504
+ "aquamarine",
4505
+ "azure",
4506
+ "beige",
4507
+ "bisque",
4508
+ "black",
4509
+ "blanchedalmond",
4510
+ "blue",
4511
+ "blueviolet",
4512
+ "brown",
4513
+ "burlywood",
4514
+ "cadetblue",
4515
+ "chartreuse",
4516
+ "chocolate",
4517
+ "coral",
4518
+ "cornflowerblue",
4519
+ "cornsilk",
4520
+ "crimson",
4521
+ "cyan",
4522
+ "darkblue",
4523
+ "darkcyan",
4524
+ "darkgoldenrod",
4525
+ "darkgray",
4526
+ "darkgreen",
4527
+ "darkgrey",
4528
+ "darkkhaki",
4529
+ "darkmagenta",
4530
+ "darkolivegreen",
4531
+ "darkorange",
4532
+ "darkorchid",
4533
+ "darkred",
4534
+ "darksalmon",
4535
+ "darkseagreen",
4536
+ "darkslateblue",
4537
+ "darkslategray",
4538
+ "darkslategrey",
4539
+ "darkturquoise",
4540
+ "darkviolet",
4541
+ "deeppink",
4542
+ "deepskyblue",
4543
+ "dimgray",
4544
+ "dimgrey",
4545
+ "dodgerblue",
4546
+ "firebrick",
4547
+ "floralwhite",
4548
+ "forestgreen",
4549
+ "fuchsia",
4550
+ "gainsboro",
4551
+ "ghostwhite",
4552
+ "gold",
4553
+ "goldenrod",
4554
+ "gray",
4555
+ "green",
4556
+ "greenyellow",
4557
+ "grey",
4558
+ "honeydew",
4559
+ "hotpink",
4560
+ "indianred",
4561
+ "indigo",
4562
+ "ivory",
4563
+ "khaki",
4564
+ "lavender",
4565
+ "lavenderblush",
4566
+ "lawngreen",
4567
+ "lemonchiffon",
4568
+ "lightblue",
4569
+ "lightcoral",
4570
+ "lightcyan",
4571
+ "lightgoldenrodyellow",
4572
+ "lightgray",
4573
+ "lightgreen",
4574
+ "lightgrey",
4575
+ "lightpink",
4576
+ "lightsalmon",
4577
+ "lightseagreen",
4578
+ "lightskyblue",
4579
+ "lightslategray",
4580
+ "lightslategrey",
4581
+ "lightsteelblue",
4582
+ "lightyellow",
4583
+ "lime",
4584
+ "limegreen",
4585
+ "linen",
4586
+ "magenta",
4587
+ "maroon",
4588
+ "mediumaquamarine",
4589
+ "mediumblue",
4590
+ "mediumorchid",
4591
+ "mediumpurple",
4592
+ "mediumseagreen",
4593
+ "mediumslateblue",
4594
+ "mediumspringgreen",
4595
+ "mediumturquoise",
4596
+ "mediumvioletred",
4597
+ "midnightblue",
4598
+ "mintcream",
4599
+ "mistyrose",
4600
+ "moccasin",
4601
+ "navajowhite",
4602
+ "navy",
4603
+ "oldlace",
4604
+ "olive",
4605
+ "olivedrab",
4606
+ "orange",
4607
+ "orangered",
4608
+ "orchid",
4609
+ "palegoldenrod",
4610
+ "palegreen",
4611
+ "paleturquoise",
4612
+ "palevioletred",
4613
+ "papayawhip",
4614
+ "peachpuff",
4615
+ "peru",
4616
+ "pink",
4617
+ "plum",
4618
+ "powderblue",
4619
+ "purple",
4620
+ "rebeccapurple",
4621
+ "red",
4622
+ "rosybrown",
4623
+ "royalblue",
4624
+ "saddlebrown",
4625
+ "salmon",
4626
+ "sandybrown",
4627
+ "seagreen",
4628
+ "seashell",
4629
+ "sienna",
4630
+ "silver",
4631
+ "skyblue",
4632
+ "slateblue",
4633
+ "slategray",
4634
+ "slategrey",
4635
+ "snow",
4636
+ "springgreen",
4637
+ "steelblue",
4638
+ "tan",
4639
+ "teal",
4640
+ "thistle",
4641
+ "tomato",
4642
+ "turquoise",
4643
+ "violet",
4644
+ "wheat",
4645
+ "white",
4646
+ "whitesmoke",
4647
+ "yellow",
4648
+ "yellowgreen",
4649
+ // CSS color keywords
4650
+ "transparent",
4651
+ "currentcolor",
4652
+ // CSS-wide keywords (should never be wrapped in var())
4653
+ "inherit",
4654
+ "initial",
4655
+ "unset",
4656
+ "revert"
4657
+ ]);
4658
+ function isCssNamedColor(value) {
4659
+ return CSS_NAMED_COLORS.has(value.toLowerCase());
4660
+ }
4661
+
4662
+ // lib/shared/tailwindThemeScale.ts
4663
+ var SANS = "ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif";
4664
+ var SERIF = "ui-serif, Georgia, Cambria, serif";
4665
+ var MONO = "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace";
4666
+ var SPECS = [
4667
+ {
4668
+ root: "text",
4669
+ property: "font-size",
4670
+ group: "font-size",
4671
+ varPrefix: "text",
4672
+ labelPrefix: "Text",
4673
+ values: [
4674
+ ["xs", "0.75rem"],
4675
+ ["sm", "0.875rem"],
4676
+ ["base", "1rem"],
4677
+ ["lg", "1.125rem"],
4678
+ ["xl", "1.25rem"],
4679
+ ["2xl", "1.5rem"],
4680
+ ["3xl", "1.875rem"],
4681
+ ["4xl", "2.25rem"],
4682
+ ["5xl", "3rem"],
4683
+ ["6xl", "3.75rem"],
4684
+ ["7xl", "4.5rem"],
4685
+ ["8xl", "6rem"],
4686
+ ["9xl", "8rem"]
4687
+ ]
4688
+ },
4689
+ {
4690
+ // Only the weights Meno's static utilities don't already cover (normal/bold stay static).
4691
+ root: "font",
4692
+ property: "font-weight",
4693
+ group: "font-weight",
4694
+ varPrefix: "font-weight",
4695
+ labelPrefix: "Font Weight",
4696
+ values: [
4697
+ ["thin", "100"],
4698
+ ["extralight", "200"],
4699
+ ["light", "300"],
4700
+ ["medium", "500"],
4701
+ ["semibold", "600"],
4702
+ ["extrabold", "800"],
4703
+ ["black", "900"]
4704
+ ]
3716
4705
  },
3717
- listStylePosition: {
3718
- inside: "list-inside",
3719
- outside: "list-outside"
4706
+ {
4707
+ root: "font",
4708
+ property: "font-family",
4709
+ group: "font-family",
4710
+ varPrefix: "font",
4711
+ labelPrefix: "Font",
4712
+ values: [
4713
+ ["sans", SANS],
4714
+ ["serif", SERIF],
4715
+ ["mono", MONO]
4716
+ ]
3720
4717
  },
3721
- backfaceVisibility: {
3722
- visible: "backface-visible",
3723
- hidden: "backface-hidden"
4718
+ {
4719
+ root: "rounded",
4720
+ property: "border-radius",
4721
+ group: "border-radius",
4722
+ varPrefix: "radius",
4723
+ labelPrefix: "Radius",
4724
+ values: [
4725
+ ["", "0.25rem"],
4726
+ ["sm", "0.125rem"],
4727
+ ["md", "0.375rem"],
4728
+ ["lg", "0.5rem"],
4729
+ ["xl", "0.75rem"],
4730
+ ["2xl", "1rem"],
4731
+ ["3xl", "1.5rem"]
4732
+ ]
3724
4733
  },
3725
- transition: {
3726
- none: "transition-none"
4734
+ {
4735
+ root: "shadow",
4736
+ property: "box-shadow",
4737
+ group: "shadow",
4738
+ varPrefix: "shadow",
4739
+ labelPrefix: "Shadow",
4740
+ values: [
4741
+ ["", "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)"],
4742
+ ["sm", "0 1px 2px 0 rgb(0 0 0 / 0.05)"],
4743
+ ["md", "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)"],
4744
+ ["lg", "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)"],
4745
+ ["xl", "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)"],
4746
+ ["2xl", "0 25px 50px -12px rgb(0 0 0 / 0.25)"]
4747
+ ]
3727
4748
  },
3728
- transform: {
3729
- none: "transform-none"
4749
+ {
4750
+ root: "max-w",
4751
+ property: "max-width",
4752
+ group: "size",
4753
+ varPrefix: "container",
4754
+ labelPrefix: "Container",
4755
+ values: [
4756
+ ["xs", "20rem"],
4757
+ ["sm", "24rem"],
4758
+ ["md", "28rem"],
4759
+ ["lg", "32rem"],
4760
+ ["xl", "36rem"],
4761
+ ["2xl", "42rem"],
4762
+ ["3xl", "48rem"],
4763
+ ["4xl", "56rem"],
4764
+ ["5xl", "64rem"],
4765
+ ["6xl", "72rem"],
4766
+ ["7xl", "80rem"],
4767
+ ["prose", "65ch"]
4768
+ ]
3730
4769
  },
3731
- boxShadow: {
3732
- none: "shadow-none"
4770
+ {
4771
+ root: "leading",
4772
+ property: "line-height",
4773
+ group: "line-height",
4774
+ varPrefix: "leading",
4775
+ labelPrefix: "Leading",
4776
+ values: [
4777
+ ["none", "1"],
4778
+ ["tight", "1.25"],
4779
+ ["snug", "1.375"],
4780
+ ["relaxed", "1.625"],
4781
+ ["loose", "2"]
4782
+ ]
3733
4783
  },
3734
- outline: {
3735
- none: "outline-none"
3736
- }
3737
- };
3738
- var staticUtilityReverse = (() => {
3739
- const reverse = {};
3740
- for (const [prop, values] of Object.entries(staticUtilities)) {
3741
- for (const [value, className] of Object.entries(values)) {
3742
- if (!reverse[className]) {
3743
- reverse[className] = { prop, value };
3744
- }
3745
- }
3746
- }
3747
- return reverse;
3748
- })();
3749
- var keywordValues = {
3750
- w: { auto: "auto", full: "100%", screen: "100vw", fit: "fit-content", min: "min-content", max: "max-content" },
3751
- h: { auto: "auto", full: "100%", screen: "100vh", fit: "fit-content", min: "min-content", max: "max-content" },
3752
- "max-w": { full: "100%", none: "none", screen: "100vw", fit: "fit-content", min: "min-content", max: "max-content" },
3753
- "max-h": { full: "100%", none: "none", screen: "100vh", fit: "fit-content", min: "min-content", max: "max-content" },
3754
- "min-w": { auto: "auto", full: "100%", fit: "fit-content", min: "min-content", max: "max-content" },
3755
- "min-h": { auto: "auto", full: "100%", screen: "100vh", fit: "fit-content", min: "min-content", max: "max-content" },
3756
- m: { auto: "auto" },
3757
- mt: { auto: "auto" },
3758
- mr: { auto: "auto" },
3759
- mb: { auto: "auto" },
3760
- ml: { auto: "auto" },
3761
- mx: { auto: "auto" },
3762
- my: { auto: "auto" },
3763
- top: { auto: "auto", full: "100%" },
3764
- right: { auto: "auto", full: "100%" },
3765
- bottom: { auto: "auto", full: "100%" },
3766
- left: { auto: "auto", full: "100%" },
3767
- inset: { auto: "auto", full: "100%" },
3768
- basis: { auto: "auto", full: "100%" },
3769
- rounded: { none: "0", full: "9999px" },
3770
- "rounded-tl": { none: "0", full: "9999px" },
3771
- "rounded-tr": { none: "0", full: "9999px" },
3772
- "rounded-bl": { none: "0", full: "9999px" },
3773
- "rounded-br": { none: "0", full: "9999px" },
3774
- z: { auto: "auto" },
3775
- leading: { normal: "normal" },
3776
- tracking: { normal: "normal" }
3777
- };
3778
- var genericKeywordRoots = /* @__PURE__ */ new Set(["cursor", "align", "origin", "object", "list"]);
3779
- var integerValueRoots = /* @__PURE__ */ new Set(["z", "order", "flex", "grow", "shrink"]);
3780
- var colorTokenProps = /* @__PURE__ */ new Set([
3781
- "color",
3782
- "backgroundColor",
3783
- "borderColor",
3784
- "accentColor",
3785
- "outlineColor"
3786
- ]);
3787
- var shadowPresets = {
3788
- "0": "none",
3789
- "1": "0 1px 2px rgba(0, 0, 0, 0.05)",
3790
- "2": "0 4px 12px rgba(0, 0, 0, 0.1)",
3791
- "3": "0 8px 24px rgba(0, 0, 0, 0.15)",
3792
- "4": "0 12px 32px rgba(0, 0, 0, 0.2)"
3793
- };
3794
- var gradientPresets = {
3795
- "1": "linear-gradient(90deg, rgba(10,22,40,0.85) 0%, rgba(10,22,40,0.2) 100%)",
3796
- "2": "linear-gradient(0deg, #a9e8fd, #00aee8 25%, #0f1335 72%)"
3797
- };
3798
- var borderPresets = {
3799
- "0": "1px solid var(--border)",
3800
- "1": "1px solid var(--border-light)"
3801
- };
3802
- var presetClassReverse = (() => {
3803
- const reverse = {};
3804
- for (const [key, value] of Object.entries(shadowPresets)) {
3805
- reverse[`shadow-${key}`] = { prop: "boxShadow", value };
3806
- }
3807
- for (const [key, value] of Object.entries(gradientPresets)) {
3808
- reverse[`bg-gradient-${key}`] = { prop: "background", value };
4784
+ {
4785
+ root: "tracking",
4786
+ property: "letter-spacing",
4787
+ group: "letter-spacing",
4788
+ varPrefix: "tracking",
4789
+ labelPrefix: "Tracking",
4790
+ values: [
4791
+ ["tighter", "-0.05em"],
4792
+ ["tight", "-0.025em"],
4793
+ ["wide", "0.025em"],
4794
+ ["wider", "0.05em"],
4795
+ ["widest", "0.1em"]
4796
+ ]
3809
4797
  }
3810
- for (const [key, value] of Object.entries(borderPresets)) {
3811
- reverse[`border-preset-${key}`] = { prop: "border", value };
4798
+ ];
4799
+ function labelSuffix(suffix) {
4800
+ if (/^(xs|sm|md|lg|xl|\dxl)$/.test(suffix)) return suffix.toUpperCase();
4801
+ return suffix.charAt(0).toUpperCase() + suffix.slice(1);
4802
+ }
4803
+ var THEME_SCALE_ENTRIES = SPECS.flatMap(
4804
+ (spec) => spec.values.map(([suffix, value]) => {
4805
+ const className = suffix ? `${spec.root}-${suffix}` : spec.root;
4806
+ const cssVar = suffix ? `--${spec.varPrefix}-${suffix}` : `--${spec.varPrefix}`;
4807
+ const label = suffix ? `${spec.labelPrefix} ${labelSuffix(suffix)}` : spec.labelPrefix;
4808
+ return { className, root: spec.root, cssVar, property: spec.property, value, group: spec.group, label };
4809
+ })
4810
+ );
4811
+ var THEME_SCALE_BY_CLASS = new Map(
4812
+ THEME_SCALE_ENTRIES.map((e) => [e.className, e])
4813
+ );
4814
+ var THEME_SCALE_BY_CSSVAR = new Map(
4815
+ THEME_SCALE_ENTRIES.map((e) => [e.cssVar, e])
4816
+ );
4817
+ function themeScaleValue(entry) {
4818
+ return `var(${entry.cssVar})`;
4819
+ }
4820
+ function scalingTypeFor(group) {
4821
+ switch (group) {
4822
+ case "font-size":
4823
+ return "fontSize";
4824
+ case "border-radius":
4825
+ return "borderRadius";
4826
+ case "size":
4827
+ return "size";
4828
+ default:
4829
+ return "none";
3812
4830
  }
3813
- return reverse;
3814
- })();
4831
+ }
4832
+ function defaultTailwindThemeVariables() {
4833
+ return THEME_SCALE_ENTRIES.map((e) => ({
4834
+ name: e.label,
4835
+ cssVar: e.cssVar,
4836
+ value: e.value,
4837
+ type: scalingTypeFor(e.group),
4838
+ group: e.group
4839
+ }));
4840
+ }
3815
4841
 
3816
4842
  // lib/shared/utilityClassNames.ts
3817
4843
  var SORTED_ROOTS = Object.keys(prefixToCSSProperty).sort((a, b) => b.length - a.length);
@@ -3865,15 +4891,16 @@ function transformOutsideUrl(input, transform) {
3865
4891
  function encodeArbitraryValue(value) {
3866
4892
  let ok = true;
3867
4893
  const encoded = transformOutsideUrl(value, (segment) => {
3868
- if (/[_"'\\[\]]/.test(segment)) ok = false;
3869
- return segment.replace(/\s+/g, "_");
4894
+ if (/["'\\[\]]/.test(segment)) ok = false;
4895
+ return segment.replace(/_/g, "\\_").replace(/\s+/g, "_");
3870
4896
  });
3871
4897
  if (!ok) return null;
3872
- if (/[\s"'\\[\]]/.test(encoded.replace(/^\[|\]$/g, ""))) return null;
4898
+ const guardTarget = encoded.replace(/^\[|\]$/g, "").replace(/\\_/g, "");
4899
+ if (/[\s"'\\[\]]/.test(guardTarget)) return null;
3873
4900
  return encoded;
3874
4901
  }
3875
4902
  function decodeArbitraryValue(encoded) {
3876
- return transformOutsideUrl(encoded, (segment) => segment.replace(/_/g, " "));
4903
+ return transformOutsideUrl(encoded, (segment) => segment.replace(/\\_|_/g, (m) => m === "\\_" ? "_" : " "));
3877
4904
  }
3878
4905
  var FONT_SIZE_KEYWORDS = /* @__PURE__ */ new Set([
3879
4906
  "xx-small",
@@ -3893,6 +4920,12 @@ function isColorValue(value) {
3893
4920
  if (value === "transparent" || value === "currentColor" || value === "currentcolor") return true;
3894
4921
  return isCssNamedColor(value);
3895
4922
  }
4923
+ function isBareColorTokenName(value) {
4924
+ if (!/^[a-zA-Z][\w-]*$/.test(value)) return false;
4925
+ if (isColorValue(value)) return false;
4926
+ if (/^[a-z]+-\d/i.test(value)) return false;
4927
+ return true;
4928
+ }
3896
4929
  function isFontSizeValue(value) {
3897
4930
  if (/^[\d.+-]/.test(value)) return true;
3898
4931
  if (/^(calc|clamp|min|max)\(/i.test(value)) return true;
@@ -3909,6 +4942,16 @@ function isImageValue(value) {
3909
4942
  function isLengthValue(value) {
3910
4943
  return /^-?[\d.]+[a-z%]*$/i.test(value);
3911
4944
  }
4945
+ function hasTopLevelWhitespace(value) {
4946
+ let depth = 0;
4947
+ for (let i = 0; i < value.length; i++) {
4948
+ const ch = value[i] ?? "";
4949
+ if (ch === "(") depth++;
4950
+ else if (ch === ")") depth = Math.max(0, depth - 1);
4951
+ else if (depth === 0 && /\s/.test(ch)) return true;
4952
+ }
4953
+ return false;
4954
+ }
3912
4955
  function resolveRootProperty(root, value) {
3913
4956
  switch (root) {
3914
4957
  case "text":
@@ -3918,9 +4961,9 @@ function resolveRootProperty(root, value) {
3918
4961
  case "bg":
3919
4962
  return isImageValue(value) ? "background-image" : "background-color";
3920
4963
  case "border":
3921
- return !value.includes(" ") && isColorValue(value) ? "border-color" : "border";
4964
+ return isColorValue(value) && !hasTopLevelWhitespace(value) ? "border-color" : "border";
3922
4965
  case "outline": {
3923
- if (value.includes(" ") || value === "none") return "outline";
4966
+ if (hasTopLevelWhitespace(value) || value === "none") return "outline";
3924
4967
  if (isColorValue(value)) return "outline-color";
3925
4968
  if (isLengthValue(value)) return "outline-width";
3926
4969
  return "outline";
@@ -3932,28 +4975,88 @@ function resolveRootProperty(root, value) {
3932
4975
  function splitVariantPrefix(className) {
3933
4976
  const match = className.match(/^([a-z][a-z0-9_-]*):(.+)$/);
3934
4977
  if (match) {
3935
- return { breakpoint: match[1], base: match[2] };
4978
+ return { breakpoint: match[1] ?? null, base: match[2] ?? className };
3936
4979
  }
3937
4980
  return { breakpoint: null, base: className };
3938
4981
  }
4982
+ var DESKTOP_FIRST_VARIANT_PREFIX = "max-";
4983
+ var BREAKPOINT_NAME_TO_CLASS = { tablet: "lg", mobile: "sm" };
4984
+ var CLASS_NAME_TO_BREAKPOINT = { lg: "tablet", sm: "mobile" };
3939
4985
  function breakpointClassPrefix(breakpointName) {
3940
- return `${breakpointName.toLowerCase()}:`;
4986
+ const lower = breakpointName.toLowerCase();
4987
+ const aliased = BREAKPOINT_NAME_TO_CLASS[lower] ?? lower;
4988
+ return `${DESKTOP_FIRST_VARIANT_PREFIX}${aliased}:`;
4989
+ }
4990
+ function breakpointClassPrefixes(breakpointName) {
4991
+ const lower = breakpointName.toLowerCase();
4992
+ const aliased = BREAKPOINT_NAME_TO_CLASS[lower];
4993
+ const prefixes = [`${DESKTOP_FIRST_VARIANT_PREFIX}${lower}:`, `${lower}:`];
4994
+ if (aliased) prefixes.unshift(`${DESKTOP_FIRST_VARIANT_PREFIX}${aliased}:`);
4995
+ return prefixes;
4996
+ }
4997
+ function normalizeBreakpointVariant(variant) {
4998
+ if (variant?.startsWith(DESKTOP_FIRST_VARIANT_PREFIX)) {
4999
+ const bare = variant.slice(DESKTOP_FIRST_VARIANT_PREFIX.length);
5000
+ return CLASS_NAME_TO_BREAKPOINT[bare] ?? bare;
5001
+ }
5002
+ return variant;
3941
5003
  }
3942
5004
  var HASH_VALUE_RE = /^h[0-9a-z]+$/;
3943
- function parseUtilityClass(className) {
5005
+ function resolveFraction(rest) {
5006
+ const m = rest.match(/^(\d+)\/(\d+)$/);
5007
+ if (!m) return null;
5008
+ const d = Number(m[2]);
5009
+ if (d === 0) return null;
5010
+ const pct = Number(m[1]) / d * 100;
5011
+ return `${pct.toFixed(6).replace(/\.?0+$/, "")}%`;
5012
+ }
5013
+ function resolveSpacingOrFraction(rest) {
5014
+ const frac = resolveFraction(rest);
5015
+ if (frac != null) return frac;
5016
+ if (rest === "full") return "100%";
5017
+ return SPACING_SCALE[rest] ?? null;
5018
+ }
5019
+ function negateCssValue(root, value) {
5020
+ if (root === "translate-y") {
5021
+ const m = value.match(/^0 (.+)$/);
5022
+ return m ? `0 -${m[1]}` : null;
5023
+ }
5024
+ return /^\d/.test(value) ? `-${value}` : null;
5025
+ }
5026
+ function parseUtilityClass(className, knownTokens) {
3944
5027
  const stat = staticUtilityReverse[className];
3945
5028
  if (stat) {
3946
5029
  return { property: camelToKebab(stat.prop), value: stat.value, root: null, kind: "static" };
3947
5030
  }
5031
+ if (className === "transition") {
5032
+ return {
5033
+ property: "transition",
5034
+ value: `${TRANSITION_PROPERTY_VALUES[""]} ${TRANSITION_DEFAULT_TIMING}`,
5035
+ root: "transition",
5036
+ kind: "keyword"
5037
+ };
5038
+ }
5039
+ if (className.startsWith("-") && className.length > 1) {
5040
+ const positive = parseUtilityClass(className.slice(1), knownTokens);
5041
+ if (positive?.root && positive.value != null && NEGATABLE_ROOTS.has(positive.root)) {
5042
+ const negated = negateCssValue(positive.root, positive.value);
5043
+ if (negated != null) return { ...positive, value: negated };
5044
+ }
5045
+ return null;
5046
+ }
3948
5047
  const preset = presetClassReverse[className];
3949
5048
  if (preset) {
3950
5049
  return { property: camelToKebab(preset.prop), value: preset.value, root: null, kind: "preset" };
3951
5050
  }
5051
+ const themed = THEME_SCALE_BY_CLASS.get(className);
5052
+ if (themed) {
5053
+ return { property: themed.property, value: themeScaleValue(themed), root: themed.root, kind: "var" };
5054
+ }
3952
5055
  const arbProp = className.match(/^\[([a-z-]+):(.+)\]$/);
3953
5056
  if (arbProp) {
3954
5057
  return {
3955
- property: arbProp[1],
3956
- value: decodeArbitraryValue(arbProp[2]),
5058
+ property: arbProp[1] ?? "",
5059
+ value: decodeArbitraryValue(arbProp[2] ?? ""),
3957
5060
  root: null,
3958
5061
  kind: "arbitrary-property"
3959
5062
  };
@@ -3962,12 +5065,12 @@ function parseUtilityClass(className) {
3962
5065
  if (!className.startsWith(`${root}-`)) continue;
3963
5066
  const rest = className.slice(root.length + 1);
3964
5067
  if (!rest) continue;
3965
- const parsed = parseRootValue(root, rest);
5068
+ const parsed = parseRootValue(root, rest, knownTokens);
3966
5069
  if (parsed) return parsed;
3967
5070
  }
3968
5071
  return null;
3969
5072
  }
3970
- function parseRootValue(root, rest) {
5073
+ function parseRootValue(root, rest, knownTokens) {
3971
5074
  if (rest.startsWith("[") && rest.endsWith("]") && rest.length > 2) {
3972
5075
  const value = decodeArbitraryValue(rest.slice(1, -1));
3973
5076
  return { property: resolveRootProperty(root, value), value, root, kind: "arbitrary" };
@@ -3993,18 +5096,132 @@ function parseRootValue(root, rest) {
3993
5096
  if (genericKeywordRoots.has(root) && /^[a-z][a-z-]*$/.test(rest)) {
3994
5097
  return { property: resolveRootProperty(root, rest), value: rest, root, kind: "keyword" };
3995
5098
  }
5099
+ if (root === "grid-cols" || root === "grid-rows") {
5100
+ if (/^[1-9]\d*$/.test(rest)) {
5101
+ const value = `repeat(${rest}, minmax(0, 1fr))`;
5102
+ return { property: prefixToCSSProperty[root] ?? root, value, root, kind: "numeric" };
5103
+ }
5104
+ if (rest === "none" || rest === "subgrid") {
5105
+ return { property: prefixToCSSProperty[root] ?? root, value: rest, root, kind: "keyword" };
5106
+ }
5107
+ }
5108
+ if (root === "col-span" || root === "row-span") {
5109
+ const property = root === "col-span" ? "grid-column" : "grid-row";
5110
+ if (rest === "full") return { property, value: "1 / -1", root, kind: "keyword" };
5111
+ if (/^[1-9]\d*$/.test(rest)) return { property, value: `span ${rest} / span ${rest}`, root, kind: "numeric" };
5112
+ }
5113
+ if (root === "col-start" || root === "col-end" || root === "row-start" || root === "row-end") {
5114
+ const property = prefixToCSSProperty[root] ?? root;
5115
+ if (rest === "auto") return { property, value: "auto", root, kind: "keyword" };
5116
+ if (/^-?[1-9]\d*$/.test(rest)) return { property, value: rest, root, kind: "numeric" };
5117
+ }
5118
+ if (root === "translate-x" || root === "translate-y") {
5119
+ const len = resolveSpacingOrFraction(rest);
5120
+ if (len != null) {
5121
+ const value = root === "translate-x" ? len : `0 ${len}`;
5122
+ return { property: "translate", value, root, kind: "numeric" };
5123
+ }
5124
+ }
5125
+ if (root === "scale" && /^\d+$/.test(rest)) {
5126
+ return { property: "scale", value: String(Number(rest) / 100), root, kind: "numeric" };
5127
+ }
5128
+ if (root === "rotate" && /^\d+(\.\d+)?$/.test(rest)) {
5129
+ return { property: "rotate", value: `${rest}deg`, root, kind: "numeric" };
5130
+ }
5131
+ if ((root === "duration" || root === "delay") && /^\d+$/.test(rest)) {
5132
+ return { property: prefixToCSSProperty[root] ?? root, value: `${rest}ms`, root, kind: "numeric" };
5133
+ }
5134
+ if (root === "ease") {
5135
+ const timing = EASE_TIMING[rest];
5136
+ if (timing) return { property: "transition-timing-function", value: timing, root, kind: "keyword" };
5137
+ }
5138
+ if (root === "transition") {
5139
+ const props = TRANSITION_PROPERTY_VALUES[rest];
5140
+ if (props !== void 0) {
5141
+ return { property: "transition", value: `${props} ${TRANSITION_DEFAULT_TIMING}`, root, kind: "keyword" };
5142
+ }
5143
+ }
5144
+ if (root === "leading") {
5145
+ const scale = SPACING_SCALE[rest];
5146
+ if (scale !== void 0) return { property: "line-height", value: scale, root, kind: "keyword" };
5147
+ }
5148
+ if (FRACTION_ROOTS.has(root)) {
5149
+ const value = resolveFraction(rest);
5150
+ if (value != null) return { property: resolveRootProperty(root, value), value, root, kind: "numeric" };
5151
+ }
5152
+ if (SPACING_SCALE_ROOTS.has(root)) {
5153
+ const scaleVal = SPACING_SCALE[rest];
5154
+ if (scaleVal !== void 0) {
5155
+ return { property: resolveRootProperty(root, scaleVal), value: scaleVal, root, kind: "keyword" };
5156
+ }
5157
+ }
3996
5158
  if (integerValueRoots.has(root) && /^-?\d+$/.test(rest)) {
3997
- return { property: prefixToCSSProperty[root], value: rest, root, kind: "numeric" };
5159
+ return { property: prefixToCSSProperty[root] ?? root, value: rest, root, kind: "numeric" };
3998
5160
  }
3999
5161
  if (root === "opacity" && /^\d{1,3}$/.test(rest)) {
4000
5162
  return { property: "opacity", value: String(Number(rest) / 100), root, kind: "numeric" };
4001
5163
  }
5164
+ if (COLOR_TOKEN_ROOTS.has(root) && knownTokens?.has(rest)) {
5165
+ const value = `var(--${rest})`;
5166
+ return { property: resolveRootProperty(root, value), value, root, kind: "var" };
5167
+ }
4002
5168
  if (HASH_VALUE_RE.test(rest)) {
4003
- return { property: prefixToCSSProperty[root], value: null, root, kind: "hash" };
5169
+ return { property: prefixToCSSProperty[root] ?? root, value: null, root, kind: "hash" };
4004
5170
  }
4005
5171
  return null;
4006
5172
  }
4007
5173
 
5174
+ // lib/shared/styleValueRegistry.ts
5175
+ var registry = /* @__PURE__ */ new Map();
5176
+ var dynamicRegistry = /* @__PURE__ */ new Map();
5177
+ function registerStyleValue(className, value) {
5178
+ registry.set(className, value);
5179
+ }
5180
+ function registerDynamicStyle(className, property, value) {
5181
+ dynamicRegistry.set(className, { property, value });
5182
+ }
5183
+ function getStyleValue(className) {
5184
+ return registry.get(className);
5185
+ }
5186
+ function getDynamicStyle(className) {
5187
+ return dynamicRegistry.get(className);
5188
+ }
5189
+ function isDynamicClass(className) {
5190
+ return dynamicRegistry.has(className);
5191
+ }
5192
+ function getAllDynamicClasses() {
5193
+ return Array.from(dynamicRegistry.keys());
5194
+ }
5195
+ function clearRegistry() {
5196
+ registry.clear();
5197
+ dynamicRegistry.clear();
5198
+ }
5199
+ function serializeRegistry() {
5200
+ return JSON.stringify({
5201
+ standard: Array.from(registry.entries()),
5202
+ dynamic: Array.from(dynamicRegistry.entries())
5203
+ });
5204
+ }
5205
+ function hydrateRegistry(data) {
5206
+ const parsed = JSON.parse(data);
5207
+ if (Array.isArray(parsed)) {
5208
+ for (const [key, value] of parsed) {
5209
+ registry.set(key, value);
5210
+ }
5211
+ } else {
5212
+ if (parsed.standard) {
5213
+ for (const [key, value] of parsed.standard) {
5214
+ registry.set(key, value);
5215
+ }
5216
+ }
5217
+ if (parsed.dynamic) {
5218
+ for (const [key, value] of parsed.dynamic) {
5219
+ dynamicRegistry.set(key, value);
5220
+ }
5221
+ }
5222
+ }
5223
+ }
5224
+
4008
5225
  // lib/shared/utilityClassMapper.ts
4009
5226
  function isStyleMapping(value) {
4010
5227
  return typeof value === "object" && value !== null && "_mapping" in value && value._mapping === true;
@@ -4017,13 +5234,19 @@ function shortHash(input) {
4017
5234
  }
4018
5235
  return (hash >>> 0).toString(36);
4019
5236
  }
4020
- function isBareColorToken(value) {
4021
- if (!/^[a-zA-Z][\w-]*$/.test(value)) return false;
4022
- if (isColorValue(value)) return false;
4023
- return true;
5237
+ function rootFormMisresolves(root, prop, value) {
5238
+ const parsedProp = ROOT_CAMEL_OVERRIDES[root] ?? cssPropertyToCamel(resolveRootProperty(root, value));
5239
+ return parsedProp !== prop;
4024
5240
  }
4025
5241
  function propertyValueToClass(prop, value) {
4026
5242
  let stringValue = String(value);
5243
+ const varRef = stringValue.match(/^var\((--[\w-]+)(?:\s*,[\s\S]*)?\)$/);
5244
+ if (varRef) {
5245
+ const entry = THEME_SCALE_BY_CSSVAR.get(varRef[1] ?? "");
5246
+ if (entry && entry.property === camelToKebab(prop)) {
5247
+ return entry.className;
5248
+ }
5249
+ }
4027
5250
  if (prop === "fontFamily") {
4028
5251
  stringValue = stringValue.split(",").map((font) => {
4029
5252
  const trimmed = font.trim();
@@ -4038,19 +5261,22 @@ function propertyValueToClass(prop, value) {
4038
5261
  registerStyleValue(staticClass, stringValue);
4039
5262
  return staticClass;
4040
5263
  }
4041
- if (prop === "boxShadow" && shadowPresets[stringValue]) {
5264
+ const shadowPreset = shadowPresets[stringValue];
5265
+ if (prop === "boxShadow" && shadowPreset) {
4042
5266
  const className2 = `shadow-${stringValue}`;
4043
- registerStyleValue(className2, shadowPresets[stringValue]);
5267
+ registerStyleValue(className2, shadowPreset);
4044
5268
  return className2;
4045
5269
  }
4046
- if ((prop === "background" || prop === "backgroundImage") && gradientPresets[stringValue]) {
5270
+ const gradientPreset = gradientPresets[stringValue];
5271
+ if ((prop === "background" || prop === "backgroundImage") && gradientPreset) {
4047
5272
  const className2 = `bg-gradient-${stringValue}`;
4048
- registerStyleValue(className2, gradientPresets[stringValue]);
5273
+ registerStyleValue(className2, gradientPreset);
4049
5274
  return className2;
4050
5275
  }
4051
- if (prop === "border" && borderPresets[stringValue]) {
5276
+ const borderPreset = borderPresets[stringValue];
5277
+ if (prop === "border" && borderPreset) {
4052
5278
  const className2 = `border-preset-${stringValue}`;
4053
- registerStyleValue(className2, borderPresets[stringValue]);
5279
+ registerStyleValue(className2, borderPreset);
4054
5280
  return className2;
4055
5281
  }
4056
5282
  const root = propertyMap[prop];
@@ -4086,21 +5312,40 @@ function propertyValueToClass(prop, value) {
4086
5312
  }
4087
5313
  }
4088
5314
  }
5315
+ if (!className && SPACING_SCALE_ROOTS.has(root)) {
5316
+ const step = SPACING_SCALE_REVERSE[stringValue];
5317
+ if (step !== void 0) {
5318
+ className = `${root}-${step}`;
5319
+ }
5320
+ }
5321
+ if (!className && (root === "grid-cols" || root === "grid-rows")) {
5322
+ const repeatMatch = stringValue.match(/^repeat\(\s*([1-9]\d*)\s*,\s*minmax\(\s*0\s*,\s*1fr\s*\)\s*\)$/);
5323
+ if (repeatMatch) {
5324
+ className = `${root}-${repeatMatch[1]}`;
5325
+ } else if (stringValue === "none" || stringValue === "subgrid") {
5326
+ className = `${root}-${stringValue}`;
5327
+ }
5328
+ }
4089
5329
  if (!className) {
4090
5330
  const varMatch = stringValue.match(/^var\((--[\w-]+)\)$/);
4091
5331
  if (varMatch) {
5332
+ const varName = (varMatch[1] ?? "").slice(2);
4092
5333
  if (prop === "fontSize") className = `text-(length:${varMatch[1]})`;
4093
5334
  else if (prop === "fontWeight") className = `font-(number:${varMatch[1]})`;
4094
- else className = `${root}-(${varMatch[1]})`;
5335
+ else if (rootFormMisresolves(root, prop, stringValue)) {
5336
+ className = `[${camelToKebab(prop)}:${stringValue}]`;
5337
+ } else if (colorTokenProps.has(prop) && isBareColorTokenName(varName)) {
5338
+ className = `${root}-${varName}`;
5339
+ } else className = `${root}-(${varMatch[1]})`;
4095
5340
  }
4096
5341
  }
4097
- if (!className && colorTokenProps.has(prop) && isBareColorToken(stringValue)) {
4098
- className = `${root}-(--${stringValue})`;
5342
+ if (!className && colorTokenProps.has(prop) && isBareColorTokenName(stringValue)) {
5343
+ className = `${root}-${stringValue}`;
4099
5344
  }
4100
5345
  if (!className) {
4101
5346
  const encoded = encodeArbitraryValue(stringValue);
4102
5347
  if (encoded != null) {
4103
- className = `${root}-[${encoded}]`;
5348
+ className = rootFormMisresolves(root, prop, stringValue) ? `[${camelToKebab(prop)}:${encoded}]` : `${root}-[${encoded}]`;
4104
5349
  }
4105
5350
  }
4106
5351
  if (!className) {
@@ -4121,6 +5366,7 @@ function stylesToClasses(styles) {
4121
5366
  const classes = [];
4122
5367
  for (const prop of sortedProps) {
4123
5368
  const value = styles[prop];
5369
+ if (value === void 0) continue;
4124
5370
  if (isStyleMapping(value)) continue;
4125
5371
  const className = propertyValueToClass(prop, value);
4126
5372
  if (className) {
@@ -4209,7 +5455,7 @@ function responsiveStylesToClasses(styles, options) {
4209
5455
  }
4210
5456
  return classes;
4211
5457
  }
4212
- function classToStyle(className) {
5458
+ function classToStyle(className, knownTokens) {
4213
5459
  const { base: cleanClass } = splitVariantPrefix(className);
4214
5460
  if (staticUtilityReverse[cleanClass]) {
4215
5461
  return staticUtilityReverse[cleanClass];
@@ -4217,7 +5463,7 @@ function classToStyle(className) {
4217
5463
  if (presetClassReverse[cleanClass]) {
4218
5464
  return presetClassReverse[cleanClass];
4219
5465
  }
4220
- const parsed = parseUtilityClass(cleanClass);
5466
+ const parsed = parseUtilityClass(cleanClass, knownTokens);
4221
5467
  if (!parsed) {
4222
5468
  const dynamic = getDynamicStyle(cleanClass);
4223
5469
  if (dynamic) {
@@ -4244,22 +5490,72 @@ function classToStyle(className) {
4244
5490
  }
4245
5491
  return { prop, value };
4246
5492
  }
4247
- function classesToStyles(classes) {
5493
+ function classesToStyles(classes, knownTokens) {
4248
5494
  const styles = { base: {}, tablet: {}, mobile: {} };
4249
5495
  for (const className of classes) {
4250
5496
  const { breakpoint: variant, base: cleanClass } = splitVariantPrefix(className);
4251
- const breakpoint = variant === "tablet" ? "tablet" : variant === "mobile" ? "mobile" : "base";
4252
- const styleEntry = classToStyle(cleanClass);
5497
+ const bp = normalizeBreakpointVariant(variant);
5498
+ const breakpoint = bp === "tablet" ? "tablet" : bp === "mobile" ? "mobile" : "base";
5499
+ const styleEntry = classToStyle(cleanClass, knownTokens);
4253
5500
  if (styleEntry) {
4254
5501
  if (!styles[breakpoint]) {
4255
5502
  styles[breakpoint] = {};
4256
5503
  }
4257
5504
  styles[breakpoint][styleEntry.prop] = styleEntry.value;
5505
+ if (cleanClass.startsWith("size-") && styleEntry.prop === "width") {
5506
+ styles[breakpoint].height = styleEntry.value;
5507
+ }
4258
5508
  }
4259
5509
  }
4260
5510
  if (Object.keys(styles.tablet || {}).length === 0) delete styles.tablet;
4261
5511
  if (Object.keys(styles.mobile || {}).length === 0) delete styles.mobile;
4262
- return Object.keys(styles.base || {}).length > 0 ? styles : null;
5512
+ const hasAny = Object.keys(styles.base || {}).length > 0 || Object.keys(styles.tablet || {}).length > 0 || Object.keys(styles.mobile || {}).length > 0;
5513
+ return hasAny ? styles : null;
5514
+ }
5515
+ function isClassableStyleValue(value) {
5516
+ if (typeof value === "number") return true;
5517
+ if (typeof value === "string") return !value.includes("{{");
5518
+ return false;
5519
+ }
5520
+ function splitStyleBucket(bucket) {
5521
+ const classable = {};
5522
+ const residual = {};
5523
+ for (const [k, v] of Object.entries(bucket)) {
5524
+ if (isClassableStyleValue(v)) classable[k] = v;
5525
+ else residual[k] = v;
5526
+ }
5527
+ return { classable, residual };
5528
+ }
5529
+ function splitStyleByClassability(style) {
5530
+ if (!style || typeof style !== "object") return { classable: null, residual: null };
5531
+ if (isResponsiveStyle(style)) {
5532
+ const classable = {};
5533
+ const residual = {};
5534
+ for (const [bp, bucket] of Object.entries(style)) {
5535
+ if (!bucket || typeof bucket !== "object") continue;
5536
+ const split2 = splitStyleBucket(bucket);
5537
+ if (Object.keys(split2.classable).length > 0) classable[bp] = split2.classable;
5538
+ if (Object.keys(split2.residual).length > 0) residual[bp] = split2.residual;
5539
+ }
5540
+ return {
5541
+ classable: Object.keys(classable).length > 0 ? classable : null,
5542
+ residual: Object.keys(residual).length > 0 ? residual : null
5543
+ };
5544
+ }
5545
+ const split = splitStyleBucket(style);
5546
+ return {
5547
+ classable: Object.keys(split.classable).length > 0 ? { base: split.classable } : null,
5548
+ residual: Object.keys(split.residual).length > 0 ? { base: split.residual } : null
5549
+ };
5550
+ }
5551
+ function styleHasMapping(style) {
5552
+ if (!style || typeof style !== "object") return false;
5553
+ const buckets = isResponsiveStyle(style) ? Object.values(style) : [style];
5554
+ for (const bucket of buckets) {
5555
+ if (!bucket || typeof bucket !== "object") continue;
5556
+ for (const v of Object.values(bucket)) if (isStyleMapping(v)) return true;
5557
+ }
5558
+ return false;
4263
5559
  }
4264
5560
 
4265
5561
  // lib/shared/paths/Path.ts
@@ -4292,7 +5588,7 @@ function validatePath(path) {
4292
5588
  }
4293
5589
  for (let i = 0; i < path.length; i++) {
4294
5590
  const value = path[i];
4295
- if (typeof value !== "number" || isNaN(value) || !isFinite(value)) {
5591
+ if (typeof value !== "number" || Number.isNaN(value) || !Number.isFinite(value)) {
4296
5592
  throw new InvalidPathError(`Invalid path value at index ${i}: expected number, got ${typeof value}`, path, i);
4297
5593
  }
4298
5594
  }
@@ -4320,7 +5616,7 @@ function stringToPath(str) {
4320
5616
  }
4321
5617
  return str.split(",").map((s) => {
4322
5618
  const num = parseInt(s, 10);
4323
- if (isNaN(num)) {
5619
+ if (Number.isNaN(num)) {
4324
5620
  throw new PathConversionError(`Invalid numeric index: ${s}`, str);
4325
5621
  }
4326
5622
  return num;
@@ -4345,9 +5641,9 @@ function domPathStringToTreePath(domPath) {
4345
5641
  const path = [0];
4346
5642
  for (let i = 0; i < parts.length; i++) {
4347
5643
  if (parts[i] === CHILDREN_TOKEN && i + 1 < parts.length) {
4348
- const indexStr = parts[i + 1];
5644
+ const indexStr = parts[i + 1] ?? "";
4349
5645
  const index = parseInt(indexStr, 10);
4350
- if (!isNaN(index) && indexStr === String(index)) {
5646
+ if (!Number.isNaN(index) && indexStr === String(index)) {
4351
5647
  path.push(index);
4352
5648
  i++;
4353
5649
  }
@@ -4381,6 +5677,7 @@ function calculateChildrenExpansionOffset(componentPath, componentStructure, ins
4381
5677
  let currentNode = componentStructure;
4382
5678
  for (let i = 1; i < componentPath.length; i++) {
4383
5679
  const index = componentPath[i];
5680
+ if (index === void 0) break;
4384
5681
  if (!currentNode || !Array.isArray(currentNode.children)) {
4385
5682
  break;
4386
5683
  }
@@ -4446,12 +5743,12 @@ function convertPagePathToComponentPath(pagePath, componentInstancePath, compone
4446
5743
  if (suffix.length > 0 && componentStructure && Array.isArray(instanceChildren)) {
4447
5744
  const childrenCount = instanceChildren.length;
4448
5745
  if (Array.isArray(componentStructure.children) && componentStructure.children.length > 0 && isSlotMarker(componentStructure.children[0])) {
4449
- const pageFirstIndex = suffix[0];
5746
+ const pageFirstIndex = suffix[0] ?? 0;
4450
5747
  if (pageFirstIndex < childrenCount) {
4451
5748
  adjustedSuffix = suffix;
4452
5749
  } else {
4453
5750
  const offset = childrenCount - 1;
4454
- adjustedSuffix = [suffix[0] - offset, ...suffix.slice(1)];
5751
+ adjustedSuffix = [pageFirstIndex - offset, ...suffix.slice(1)];
4455
5752
  }
4456
5753
  }
4457
5754
  }
@@ -4465,7 +5762,7 @@ function convertComponentPathToPagePath(componentPath, componentInstancePath, co
4465
5762
  const offset = calculateChildrenExpansionOffset(componentPath, componentStructure, instanceChildren);
4466
5763
  let adjustedSuffix = suffix;
4467
5764
  if (offset > 0 && suffix.length > 0) {
4468
- adjustedSuffix = [suffix[0] + offset, ...suffix.slice(1)];
5765
+ adjustedSuffix = [(suffix[0] ?? 0) + offset, ...suffix.slice(1)];
4469
5766
  }
4470
5767
  return [...componentInstancePath, ...adjustedSuffix];
4471
5768
  }
@@ -4499,8 +5796,8 @@ function parseElementClassName(className) {
4499
5796
  if (!match) return null;
4500
5797
  return {
4501
5798
  fileType: match[1] === "c" ? "component" : "page",
4502
- fileName: match[2],
4503
- elementName: match[3]
5799
+ fileName: match[2] ?? "",
5800
+ elementName: match[3] ?? ""
4504
5801
  };
4505
5802
  }
4506
5803
 
@@ -4627,7 +5924,7 @@ function createStyleMappingFromProps(componentPropDefs, currentValue) {
4627
5924
  mappingValues[opt] = "";
4628
5925
  });
4629
5926
  } else {
4630
- mappingValues["default"] = currentValue;
5927
+ mappingValues.default = currentValue;
4631
5928
  }
4632
5929
  return {
4633
5930
  _mapping: true,
@@ -4638,7 +5935,7 @@ function createStyleMappingFromProps(componentPropDefs, currentValue) {
4638
5935
 
4639
5936
  // lib/shared/linkUtils.ts
4640
5937
  function normalizePath(path) {
4641
- let normalized = path.split("?")[0].split("#")[0];
5938
+ let normalized = (path.split("?")[0] ?? "").split("#")[0] ?? "";
4642
5939
  if (normalized.length > 1 && normalized.endsWith("/")) {
4643
5940
  normalized = normalized.slice(0, -1);
4644
5941
  }
@@ -4650,7 +5947,7 @@ function isCurrentLink(href, currentPagePath) {
4650
5947
  }
4651
5948
 
4652
5949
  // lib/shared/viewportUnits.ts
4653
- var VIEWPORT_UNIT_RE = /(?<![\w-])(-?\d*\.?\d+)(s|l|d)?(vh|vw)\b/g;
5950
+ var VIEWPORT_UNIT_RE = /(?<![\w\-[])(-?\d*\.?\d+)(s|l|d)?(vh|vw)\b/g;
4654
5951
  function rewriteViewportUnits(input) {
4655
5952
  if (!input) return input;
4656
5953
  return input.replace(VIEWPORT_UNIT_RE, (_match, num, sizeKw, axis) => {
@@ -4750,11 +6047,59 @@ function toFriendlyError(input) {
4750
6047
  };
4751
6048
  }
4752
6049
 
6050
+ // lib/shared/pxToRem.ts
6051
+ var DEFAULT_REM_CONFIG = {
6052
+ enabled: false,
6053
+ baseFontSize: 16
6054
+ };
6055
+ var PX_REGEX = /(-?\d*\.?\d+)px/g;
6056
+ function convertPxToRem(cssValue, baseFontSize) {
6057
+ return cssValue.replace(PX_REGEX, (_, num) => {
6058
+ const px = parseFloat(num);
6059
+ if (px === 0) return "0";
6060
+ const rem = px / baseFontSize;
6061
+ const rounded = parseFloat(rem.toFixed(4));
6062
+ return `${rounded}rem`;
6063
+ });
6064
+ }
6065
+ var PX_KEEP_PROPERTIES = /* @__PURE__ */ new Set([
6066
+ "border-width",
6067
+ "border-top-width",
6068
+ "border-right-width",
6069
+ "border-bottom-width",
6070
+ "border-left-width",
6071
+ "outline-width",
6072
+ "outline-offset",
6073
+ "border",
6074
+ "box-shadow",
6075
+ "text-shadow"
6076
+ ]);
6077
+ function shouldConvertProperty(cssProperty) {
6078
+ return !PX_KEEP_PROPERTIES.has(cssProperty);
6079
+ }
6080
+ function applyRemConversion(declarations, remConfig) {
6081
+ if (!remConfig?.enabled) return declarations;
6082
+ return declarations.split(";").map((decl) => {
6083
+ const trimmed = decl.trim();
6084
+ if (!trimmed) return "";
6085
+ const colonIndex = trimmed.indexOf(":");
6086
+ if (colonIndex === -1) return trimmed;
6087
+ const property = trimmed.substring(0, colonIndex).trim();
6088
+ const value = trimmed.substring(colonIndex + 1).trim();
6089
+ if (shouldConvertProperty(property)) {
6090
+ return `${property}: ${convertPxToRem(value, remConfig.baseFontSize)}`;
6091
+ }
6092
+ return trimmed;
6093
+ }).filter(Boolean).join("; ");
6094
+ }
6095
+
4753
6096
  // lib/shared/cssGeneration.ts
4754
6097
  var cssPropertyOrderMap = (() => {
4755
6098
  const map = /* @__PURE__ */ new Map();
4756
6099
  for (let i = 0; i < propertyOrder.length; i++) {
4757
- const kebab = camelToKebab(propertyOrder[i]);
6100
+ const prop = propertyOrder[i];
6101
+ if (prop === void 0) continue;
6102
+ const kebab = camelToKebab(prop);
4758
6103
  if (!map.has(kebab)) map.set(kebab, i);
4759
6104
  }
4760
6105
  return map;
@@ -4829,11 +6174,11 @@ var borderSideMap = {
4829
6174
  "border-b": "border-bottom",
4830
6175
  "border-l": "border-left"
4831
6176
  };
4832
- function generateRuleForClass(className) {
6177
+ function generateRuleForClass(className, knownTokens) {
4833
6178
  if (utilityClassRules[className]) {
4834
6179
  return utilityClassRules[className];
4835
6180
  }
4836
- const parsed = parseUtilityClass(className);
6181
+ const parsed = parseUtilityClass(className, knownTokens);
4837
6182
  if (!parsed) {
4838
6183
  const dynamicStyle = getDynamicStyle(className);
4839
6184
  if (dynamicStyle) {
@@ -4860,6 +6205,9 @@ function generateRuleForClass(className) {
4860
6205
  } else {
4861
6206
  value = parsed.value;
4862
6207
  }
6208
+ if (root === "size") {
6209
+ return `width: ${value}; height: ${value};`;
6210
+ }
4863
6211
  if (root === "px") {
4864
6212
  return `padding-left: ${value}; padding-right: ${value};`;
4865
6213
  }
@@ -4944,28 +6292,30 @@ function applyContainerPattern(style, fluidActive) {
4944
6292
  marginRight: "auto"
4945
6293
  };
4946
6294
  }
4947
- function generateUtilityCSS(usedClasses, breakpoints = DEFAULT_BREAKPOINTS, responsiveScales, remConfig) {
6295
+ function generateUtilityCSS(usedClasses, breakpoints = DEFAULT_BREAKPOINTS, responsiveScales, remConfig, knownTokens) {
4948
6296
  const css = [];
4949
6297
  const baseClasses = /* @__PURE__ */ new Set();
4950
6298
  const autoResponsiveClasses = /* @__PURE__ */ new Set();
4951
6299
  const breakpointValues = getBreakpointValues(breakpoints);
4952
6300
  const responsiveClasses = {};
4953
6301
  for (const [breakpointName, breakpointValue] of Object.entries(breakpointValues)) {
4954
- const prefix = breakpointClassPrefix(breakpointName);
4955
- responsiveClasses[prefix] = {
4956
- classes: /* @__PURE__ */ new Set(),
4957
- breakpointName,
4958
- value: breakpointValue
4959
- };
6302
+ for (const prefix of breakpointClassPrefixes(breakpointName)) {
6303
+ responsiveClasses[prefix] = {
6304
+ classes: /* @__PURE__ */ new Set(),
6305
+ breakpointName,
6306
+ value: breakpointValue
6307
+ };
6308
+ }
4960
6309
  }
4961
6310
  for (const className of usedClasses) {
4962
6311
  let matched = false;
4963
6312
  for (const prefix of Object.keys(responsiveClasses)) {
4964
6313
  if (className.startsWith(prefix) && className.length > prefix.length) {
4965
6314
  const potentialClass = className.substring(prefix.length);
4966
- const rule = generateRuleForClass(potentialClass);
4967
- if (rule) {
4968
- responsiveClasses[prefix].classes.add(potentialClass);
6315
+ const rule = generateRuleForClass(potentialClass, knownTokens);
6316
+ const bucket = responsiveClasses[prefix];
6317
+ if (rule && bucket) {
6318
+ bucket.classes.add(potentialClass);
4969
6319
  matched = true;
4970
6320
  break;
4971
6321
  }
@@ -4987,7 +6337,7 @@ function generateUtilityCSS(usedClasses, breakpoints = DEFAULT_BREAKPOINTS, resp
4987
6337
  const mode = getResponsiveMode(responsiveScales);
4988
6338
  const fluidActive = responsiveScales?.enabled === true && mode === "fluid";
4989
6339
  for (const className of sortClassesByPropertyOrder(baseClasses)) {
4990
- let rule = generateRuleForClass(className);
6340
+ let rule = generateRuleForClass(className, knownTokens);
4991
6341
  if (rule) {
4992
6342
  if (fluidActive && autoResponsiveClasses.has(className)) {
4993
6343
  rule = applyFluidToUtilityRule(rule, className, responsiveScales, breakpoints);
@@ -5040,7 +6390,7 @@ function generateUtilityCSS(usedClasses, breakpoints = DEFAULT_BREAKPOINTS, resp
5040
6390
  for (const [prefix, breakpointInfo] of sortedManualResponsive) {
5041
6391
  const rules = [];
5042
6392
  for (const className of sortClassesByPropertyOrder(breakpointInfo.classes)) {
5043
- const rule = generateRuleForClass(className);
6393
+ const rule = generateRuleForClass(className, knownTokens);
5044
6394
  if (rule) {
5045
6395
  const escapedClassName = escapeCSSClassName(`${prefix}${className}`);
5046
6396
  const finalRule = applyRemConversion(rule, remConfig);
@@ -5055,21 +6405,24 @@ function generateUtilityCSS(usedClasses, breakpoints = DEFAULT_BREAKPOINTS, resp
5055
6405
  }
5056
6406
  return css.join("\n");
5057
6407
  }
5058
- function generateSingleClassCSS(className, breakpoints = DEFAULT_BREAKPOINTS, responsiveScales, remConfig) {
6408
+ function generateSingleClassCSS(className, breakpoints = DEFAULT_BREAKPOINTS, responsiveScales, remConfig, knownTokens) {
5059
6409
  const breakpointValues = getBreakpointValues(breakpoints);
5060
6410
  const css = [];
5061
6411
  const responsivePrefixes = {};
5062
6412
  for (const [breakpointName, breakpointValue] of Object.entries(breakpointValues)) {
5063
- responsivePrefixes[breakpointClassPrefix(breakpointName)] = { breakpointName, value: breakpointValue };
6413
+ for (const prefix of breakpointClassPrefixes(breakpointName)) {
6414
+ responsivePrefixes[prefix] = { breakpointName, value: breakpointValue };
6415
+ }
5064
6416
  }
5065
6417
  let matched = false;
5066
6418
  for (const prefix of Object.keys(responsivePrefixes)) {
5067
6419
  if (className.startsWith(prefix) && className.length > prefix.length) {
5068
6420
  const potentialClass = className.substring(prefix.length);
5069
- const rule = generateRuleForClass(potentialClass);
5070
- if (rule) {
6421
+ const rule = generateRuleForClass(potentialClass, knownTokens);
6422
+ const responsivePrefix = responsivePrefixes[prefix];
6423
+ if (rule && responsivePrefix) {
5071
6424
  const escapedClassName = escapeCSSClassName(className);
5072
- const bpValue = responsivePrefixes[prefix].value;
6425
+ const bpValue = responsivePrefix.value;
5073
6426
  const finalRule = applyRemConversion(rule, remConfig);
5074
6427
  css.push(`@media (max-width: ${bpValue}px) {
5075
6428
  .${escapedClassName} { ${finalRule} }
@@ -5080,7 +6433,7 @@ function generateSingleClassCSS(className, breakpoints = DEFAULT_BREAKPOINTS, re
5080
6433
  }
5081
6434
  }
5082
6435
  if (!matched) {
5083
- let rule = generateRuleForClass(className);
6436
+ let rule = generateRuleForClass(className, knownTokens);
5084
6437
  if (!rule) return "";
5085
6438
  const mode = getResponsiveMode(responsiveScales);
5086
6439
  const fluidActive = responsiveScales?.enabled === true && mode === "fluid";
@@ -5121,16 +6474,17 @@ function generateSingleClassCSS(className, breakpoints = DEFAULT_BREAKPOINTS, re
5121
6474
  }
5122
6475
  return css.join("\n");
5123
6476
  }
5124
- function extractUtilityClassesFromHTML(html) {
6477
+ function extractUtilityClassesFromHTML(html, knownTokens) {
5125
6478
  const classes = /* @__PURE__ */ new Set();
5126
6479
  const classRegex = /class="([^"]*)"/g;
5127
- let match;
5128
- while ((match = classRegex.exec(html)) !== null) {
5129
- const classList = match[1].split(/\s+/);
6480
+ let match = classRegex.exec(html);
6481
+ while (match !== null) {
6482
+ const classList = (match[1] ?? "").split(/\s+/);
6483
+ match = classRegex.exec(html);
5130
6484
  for (const className of classList) {
5131
6485
  if (!className) continue;
5132
6486
  const { base } = splitVariantPrefix(className);
5133
- if (parseUtilityClass(base)) {
6487
+ if (parseUtilityClass(base, knownTokens)) {
5134
6488
  classes.add(className);
5135
6489
  continue;
5136
6490
  }
@@ -5152,7 +6506,7 @@ function styleObjectToCSS(style) {
5152
6506
  }
5153
6507
  const cssProperty = prop.replace(/([A-Z])/g, "-$1").toLowerCase();
5154
6508
  let cssValue = String(value);
5155
- if ((prop === "backgroundColor" || prop === "color" || prop === "borderColor") && !cssValue.startsWith("#") && !cssValue.startsWith("rgb") && !cssValue.startsWith("var(") && !cssValue.includes("(")) {
6509
+ if ((prop === "backgroundColor" || prop === "color" || prop === "borderColor") && isBareColorTokenName(cssValue)) {
5156
6510
  cssValue = `var(--${cssValue})`;
5157
6511
  }
5158
6512
  declarations.push(`${cssProperty}: ${cssValue}`);
@@ -5261,6 +6615,35 @@ function generateAllInteractiveCSS(interactiveStylesMap, breakpoints = DEFAULT_B
5261
6615
  }
5262
6616
 
5263
6617
  export {
6618
+ DEFAULT_BREAKPOINTS,
6619
+ normalizeBreakpointConfig,
6620
+ getBreakpointValues,
6621
+ getPreviewPointValues,
6622
+ getAllBreakpointNames,
6623
+ getBreakpointName,
6624
+ getBreakpointLabel,
6625
+ DEFAULT_FLUID_RANGE,
6626
+ DEFAULT_SITE_MARGIN,
6627
+ parseValue,
6628
+ SCALABLE_CSS_PROPERTIES,
6629
+ calculateResponsiveValue,
6630
+ getScaleMultiplier,
6631
+ parseMultiValue,
6632
+ scaleValue,
6633
+ scalePropertyValue,
6634
+ getResponsiveValues,
6635
+ resolveVariableValueAtBreakpoint,
6636
+ getSmallestBreakpointName,
6637
+ buildFluidClamp,
6638
+ buildFluidClampWithExplicitMin,
6639
+ buildSiteMarginClamp,
6640
+ buildFluidPropertyValue,
6641
+ DEFAULT_RESPONSIVE_SCALES,
6642
+ DEFAULT_REM_CONFIG,
6643
+ setErrorHandler,
6644
+ logRuntimeError,
6645
+ logNetworkError,
6646
+ init_errorLogger,
5264
6647
  DEFAULT_PREFETCH_CONFIG,
5265
6648
  PropDefinitionSchema,
5266
6649
  StyleMappingSchema,
@@ -5361,6 +6744,8 @@ export {
5361
6744
  isEmbedNode,
5362
6745
  isLinkNode,
5363
6746
  isLocaleListNode,
6747
+ isIslandNode,
6748
+ isCustomNode,
5364
6749
  isCMSListNode,
5365
6750
  isListNode,
5366
6751
  isValidNodeType,
@@ -5381,9 +6766,17 @@ export {
5381
6766
  isRichTextMarker,
5382
6767
  richTextMarkerToHtml,
5383
6768
  resolvePropsFromDefinition,
6769
+ propertyMap,
6770
+ staticUtilityReverse,
6771
+ keywordValues,
6772
+ presetClassReverse,
5384
6773
  CSS_NAMED_COLORS,
5385
6774
  isCssNamedColor,
5386
- breakpointClassPrefix,
6775
+ THEME_SCALE_ENTRIES,
6776
+ defaultTailwindThemeVariables,
6777
+ splitVariantPrefix,
6778
+ breakpointClassPrefixes,
6779
+ normalizeBreakpointVariant,
5387
6780
  registerStyleValue,
5388
6781
  registerDynamicStyle,
5389
6782
  getStyleValue,
@@ -5397,6 +6790,9 @@ export {
5397
6790
  responsiveStylesToClasses,
5398
6791
  classToStyle,
5399
6792
  classesToStyles,
6793
+ isClassableStyleValue,
6794
+ splitStyleByClassability,
6795
+ styleHasMapping,
5400
6796
  ROOT_STRING,
5401
6797
  ROOT_0_STRING,
5402
6798
  CHILDREN_SEPARATOR,
@@ -5443,4 +6839,4 @@ export {
5443
6839
  generateInteractiveCSS,
5444
6840
  generateAllInteractiveCSS
5445
6841
  };
5446
- //# sourceMappingURL=chunk-7HWQUVTU.js.map
6842
+ //# sourceMappingURL=chunk-J4IPTP5X.js.map