meno-core 1.0.54 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (296) 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-7HWQUVTU.js → chunk-2IIQK7T3.js} +1353 -347
  6. package/dist/chunks/chunk-2IIQK7T3.js.map +7 -0
  7. package/dist/chunks/{chunk-3XER4E5W.js → chunk-4ZRU52J2.js} +6 -5
  8. package/dist/chunks/{chunk-3XER4E5W.js.map → chunk-4ZRU52J2.js.map} +2 -2
  9. package/dist/chunks/{chunk-NVRBTSQG.js → chunk-5X4HCN7J.js} +4 -4
  10. package/dist/chunks/chunk-5X4HCN7J.js.map +7 -0
  11. package/dist/chunks/{chunk-FZITJSSS.js → chunk-7CCVOL5M.js} +14 -14
  12. package/dist/chunks/chunk-7CCVOL5M.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-AE3QK5QW.js → chunk-NUP7H7D3.js} +31 -26
  16. package/dist/chunks/chunk-NUP7H7D3.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 +14345 -6265
  25. package/dist/lib/server/index.js.map +4 -4
  26. package/dist/lib/shared/index.js +292 -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 +7 -7
  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 +125 -15
  140. package/lib/server/ssr/ssrRenderer.ts +206 -38
  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 +23 -0
  154. package/lib/shared/cssGeneration.ts +40 -27
  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 +23 -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/itemTemplateUtils.test.ts +5 -5
  174. package/lib/shared/itemTemplateUtils.ts +9 -5
  175. package/lib/shared/jsonRepair.ts +8 -8
  176. package/lib/shared/libraryLoader.test.ts +6 -6
  177. package/lib/shared/linkUtils.ts +1 -1
  178. package/lib/shared/logger.test.ts +66 -0
  179. package/lib/shared/logger.ts +94 -0
  180. package/lib/shared/markdown.ts +25 -0
  181. package/lib/shared/nodeUtils.test.ts +13 -9
  182. package/lib/shared/nodeUtils.ts +27 -4
  183. package/lib/shared/pathSecurity.ts +1 -1
  184. package/lib/shared/pathUtils.ts +1 -2
  185. package/lib/shared/paths/PathConverter.ts +3 -3
  186. package/lib/shared/paths/PathUtils.ts +4 -3
  187. package/lib/shared/paths/PathValidator.ts +1 -1
  188. package/lib/shared/permissions.test.ts +168 -0
  189. package/lib/shared/permissions.ts +162 -0
  190. package/lib/shared/propResolver.test.ts +1 -1
  191. package/lib/shared/propResolver.ts +1 -1
  192. package/lib/shared/registry/BaseNodeTypeRegistry.test.ts +5 -3
  193. package/lib/shared/registry/ClientRegistry.ts +0 -1
  194. package/lib/shared/registry/ComponentRegistry.test.ts +3 -3
  195. package/lib/shared/registry/ComponentRegistry.ts +6 -1
  196. package/lib/shared/registry/NodeTypeDefinition.ts +2 -2
  197. package/lib/shared/registry/SSRRegistry.ts +0 -1
  198. package/lib/shared/registry/fieldPresets.ts +3 -1
  199. package/lib/shared/registry/nodeTypes/CustomNodeType.ts +103 -0
  200. package/lib/shared/registry/nodeTypes/HtmlNodeType.ts +1 -1
  201. package/lib/shared/registry/nodeTypes/IslandNodeType.ts +129 -0
  202. package/lib/shared/registry/nodeTypes/ListNodeType.ts +43 -7
  203. package/lib/shared/registry/nodeTypes/MarkdownNodeType.ts +78 -0
  204. package/lib/shared/registry/nodeTypes/SlotMarkerType.ts +6 -1
  205. package/lib/shared/registry/nodeTypes/index.ts +16 -1
  206. package/lib/shared/responsiveScaling.test.ts +1 -3
  207. package/lib/shared/responsiveScaling.ts +6 -5
  208. package/lib/shared/responsiveStyleUtils.test.ts +0 -1
  209. package/lib/shared/richtext/htmlToTiptap.test.ts +116 -116
  210. package/lib/shared/richtext/htmlToTiptap.ts +1 -1
  211. package/lib/shared/styleNodeUtils.ts +17 -14
  212. package/lib/shared/themeDefaults.test.ts +0 -3
  213. package/lib/shared/tree/PathBuilder.test.ts +1 -7
  214. package/lib/shared/tree/PathBuilder.ts +15 -13
  215. package/lib/shared/treePathUtils.test.ts +49 -2
  216. package/lib/shared/treePathUtils.ts +40 -4
  217. package/lib/shared/types/api.ts +105 -7
  218. package/lib/shared/types/cms.test.ts +34 -0
  219. package/lib/shared/types/cms.ts +65 -13
  220. package/lib/shared/types/components.ts +24 -0
  221. package/lib/shared/types/errors.test.ts +1 -1
  222. package/lib/shared/types/index.ts +23 -0
  223. package/lib/shared/types/permissions.ts +139 -0
  224. package/lib/shared/types/variables.ts +3 -3
  225. package/lib/shared/utilityClassConfig.ts +103 -0
  226. package/lib/shared/utilityClassMapper.durability.test.ts +117 -0
  227. package/lib/shared/utilityClassMapper.test.ts +253 -26
  228. package/lib/shared/utilityClassMapper.ts +160 -29
  229. package/lib/shared/utilityClassNames.test.ts +38 -0
  230. package/lib/shared/utilityClassNames.ts +155 -23
  231. package/lib/shared/validation/index.ts +1 -0
  232. package/lib/shared/validation/permissionsValidators.test.ts +49 -0
  233. package/lib/shared/validation/permissionsValidators.ts +49 -0
  234. package/lib/shared/validation/propValidator.test.ts +1 -1
  235. package/lib/shared/validation/propValidator.ts +1 -1
  236. package/lib/shared/validation/schemas.test.ts +41 -0
  237. package/lib/shared/validation/schemas.ts +159 -13
  238. package/lib/shared/validation/validators.test.ts +2 -2
  239. package/lib/shared/viewportUnits.test.ts +13 -0
  240. package/lib/shared/viewportUnits.ts +12 -5
  241. package/lib/test-utils/factories/ConsoleMockFactory.ts +7 -7
  242. package/lib/test-utils/factories/DomMockFactory.ts +10 -4
  243. package/lib/test-utils/factories/ServerMockFactory.ts +1 -1
  244. package/lib/test-utils/factories/StoreMockFactory.ts +5 -5
  245. package/lib/test-utils/mockFactories.ts +1 -1
  246. package/lib/test-utils/mocks.ts +3 -3
  247. package/package.json +3 -5
  248. package/scripts/build-for-publish.mjs +2 -4
  249. package/scripts/build-meno-filter.ts +3 -3
  250. package/tsconfig.json +1 -0
  251. package/vite.config.ts +1 -1
  252. package/build-next.ts +0 -1374
  253. package/build-static.test.ts +0 -453
  254. package/build-static.ts +0 -1072
  255. package/dist/build-static.js +0 -37
  256. package/dist/chunks/chunk-2FN4UOVO.js +0 -6465
  257. package/dist/chunks/chunk-2FN4UOVO.js.map +0 -7
  258. package/dist/chunks/chunk-5ETZFREW.js.map +0 -7
  259. package/dist/chunks/chunk-7E4IF5L7.js +0 -245
  260. package/dist/chunks/chunk-7E4IF5L7.js.map +0 -7
  261. package/dist/chunks/chunk-7HWQUVTU.js.map +0 -7
  262. package/dist/chunks/chunk-AE3QK5QW.js.map +0 -7
  263. package/dist/chunks/chunk-F6KTJYGV.js +0 -322
  264. package/dist/chunks/chunk-F6KTJYGV.js.map +0 -7
  265. package/dist/chunks/chunk-FZITJSSS.js.map +0 -7
  266. package/dist/chunks/chunk-GSYYA5GX.js +0 -77
  267. package/dist/chunks/chunk-GSYYA5GX.js.map +0 -7
  268. package/dist/chunks/chunk-HIZMY3EP.js.map +0 -7
  269. package/dist/chunks/chunk-I2WEGYA7.js +0 -424
  270. package/dist/chunks/chunk-I2WEGYA7.js.map +0 -7
  271. package/dist/chunks/chunk-JNO3CNLJ.js +0 -464
  272. package/dist/chunks/chunk-JNO3CNLJ.js.map +0 -7
  273. package/dist/chunks/chunk-NVRBTSQG.js.map +0 -7
  274. package/dist/chunks/chunk-Q4OBWKXG.js +0 -1143
  275. package/dist/chunks/chunk-Q4OBWKXG.js.map +0 -7
  276. package/dist/chunks/chunk-QTE32Y53.js +0 -3829
  277. package/dist/chunks/chunk-QTE32Y53.js.map +0 -7
  278. package/dist/chunks/configService-PRJZF7Y6.js +0 -14
  279. package/dist/chunks/configService-PRJZF7Y6.js.map +0 -7
  280. package/dist/chunks/constants-KIQEYMAM.js +0 -46
  281. package/dist/chunks/constants-KIQEYMAM.js.map +0 -7
  282. package/dist/chunks/fs-ZI5JEU7V.js.map +0 -7
  283. package/dist/entries/server-router.js +0 -62
  284. package/dist/entries/server-router.js.map +0 -7
  285. package/entries/server-router.tsx +0 -75
  286. package/lib/server/providers/fileSystemPageProvider.test.ts +0 -84
  287. package/lib/server/providers/fileSystemPageProvider.ts +0 -179
  288. package/lib/server/webflow/buildWebflow.ts +0 -623
  289. package/lib/server/webflow/index.ts +0 -23
  290. package/lib/server/webflow/nodeToWebflow.test.ts +0 -3102
  291. package/lib/server/webflow/nodeToWebflow.ts +0 -2372
  292. package/lib/server/webflow/styleMapper.test.ts +0 -348
  293. package/lib/server/webflow/styleMapper.ts +0 -687
  294. package/lib/server/webflow/templateWrapper.ts +0 -49
  295. package/lib/server/webflow/types.ts +0 -389
  296. /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
@@ -3735,6 +4248,82 @@ var staticUtilities = {
3735
4248
  none: "outline-none"
3736
4249
  }
3737
4250
  };
4251
+ var SPACING_SCALE = {
4252
+ "0": "0px",
4253
+ px: "1px",
4254
+ "0.5": "2px",
4255
+ "1": "4px",
4256
+ "1.5": "6px",
4257
+ "2": "8px",
4258
+ "2.5": "10px",
4259
+ "3": "12px",
4260
+ "3.5": "14px",
4261
+ "4": "16px",
4262
+ "5": "20px",
4263
+ "6": "24px",
4264
+ "7": "28px",
4265
+ "8": "32px",
4266
+ "9": "36px",
4267
+ "10": "40px",
4268
+ "11": "44px",
4269
+ "12": "48px",
4270
+ "14": "56px",
4271
+ "16": "64px",
4272
+ "20": "80px",
4273
+ "24": "96px",
4274
+ "28": "112px",
4275
+ "32": "128px",
4276
+ "36": "144px",
4277
+ "40": "160px",
4278
+ "44": "176px",
4279
+ "48": "192px",
4280
+ "52": "208px",
4281
+ "56": "224px",
4282
+ "60": "240px",
4283
+ "64": "256px",
4284
+ "72": "288px",
4285
+ "80": "320px",
4286
+ "96": "384px"
4287
+ };
4288
+ var SPACING_SCALE_REVERSE = (() => {
4289
+ const reverse = {};
4290
+ for (const [step, length] of Object.entries(SPACING_SCALE)) {
4291
+ reverse[length] = step;
4292
+ }
4293
+ return reverse;
4294
+ })();
4295
+ var SPACING_SCALE_ROOTS = /* @__PURE__ */ new Set([
4296
+ "p",
4297
+ "pt",
4298
+ "pr",
4299
+ "pb",
4300
+ "pl",
4301
+ "px",
4302
+ "py",
4303
+ "m",
4304
+ "mt",
4305
+ "mr",
4306
+ "mb",
4307
+ "ml",
4308
+ "mx",
4309
+ "my",
4310
+ "gap",
4311
+ "gap-x",
4312
+ "gap-y",
4313
+ "top",
4314
+ "right",
4315
+ "bottom",
4316
+ "left",
4317
+ "inset",
4318
+ "w",
4319
+ "h",
4320
+ "min-w",
4321
+ "min-h",
4322
+ "max-w",
4323
+ "max-h",
4324
+ "basis"
4325
+ ]);
4326
+ var COLOR_TOKEN_ROOTS = /* @__PURE__ */ new Set(["text", "bg", "border", "accent", "outline"]);
3738
4327
  var staticUtilityReverse = (() => {
3739
4328
  const reverse = {};
3740
4329
  for (const [prop, values] of Object.entries(staticUtilities)) {
@@ -3813,6 +4402,170 @@ var presetClassReverse = (() => {
3813
4402
  return reverse;
3814
4403
  })();
3815
4404
 
4405
+ // lib/shared/cssNamedColors.ts
4406
+ var CSS_NAMED_COLORS = /* @__PURE__ */ new Set([
4407
+ // CSS Level 4 named colors
4408
+ "aliceblue",
4409
+ "antiquewhite",
4410
+ "aqua",
4411
+ "aquamarine",
4412
+ "azure",
4413
+ "beige",
4414
+ "bisque",
4415
+ "black",
4416
+ "blanchedalmond",
4417
+ "blue",
4418
+ "blueviolet",
4419
+ "brown",
4420
+ "burlywood",
4421
+ "cadetblue",
4422
+ "chartreuse",
4423
+ "chocolate",
4424
+ "coral",
4425
+ "cornflowerblue",
4426
+ "cornsilk",
4427
+ "crimson",
4428
+ "cyan",
4429
+ "darkblue",
4430
+ "darkcyan",
4431
+ "darkgoldenrod",
4432
+ "darkgray",
4433
+ "darkgreen",
4434
+ "darkgrey",
4435
+ "darkkhaki",
4436
+ "darkmagenta",
4437
+ "darkolivegreen",
4438
+ "darkorange",
4439
+ "darkorchid",
4440
+ "darkred",
4441
+ "darksalmon",
4442
+ "darkseagreen",
4443
+ "darkslateblue",
4444
+ "darkslategray",
4445
+ "darkslategrey",
4446
+ "darkturquoise",
4447
+ "darkviolet",
4448
+ "deeppink",
4449
+ "deepskyblue",
4450
+ "dimgray",
4451
+ "dimgrey",
4452
+ "dodgerblue",
4453
+ "firebrick",
4454
+ "floralwhite",
4455
+ "forestgreen",
4456
+ "fuchsia",
4457
+ "gainsboro",
4458
+ "ghostwhite",
4459
+ "gold",
4460
+ "goldenrod",
4461
+ "gray",
4462
+ "green",
4463
+ "greenyellow",
4464
+ "grey",
4465
+ "honeydew",
4466
+ "hotpink",
4467
+ "indianred",
4468
+ "indigo",
4469
+ "ivory",
4470
+ "khaki",
4471
+ "lavender",
4472
+ "lavenderblush",
4473
+ "lawngreen",
4474
+ "lemonchiffon",
4475
+ "lightblue",
4476
+ "lightcoral",
4477
+ "lightcyan",
4478
+ "lightgoldenrodyellow",
4479
+ "lightgray",
4480
+ "lightgreen",
4481
+ "lightgrey",
4482
+ "lightpink",
4483
+ "lightsalmon",
4484
+ "lightseagreen",
4485
+ "lightskyblue",
4486
+ "lightslategray",
4487
+ "lightslategrey",
4488
+ "lightsteelblue",
4489
+ "lightyellow",
4490
+ "lime",
4491
+ "limegreen",
4492
+ "linen",
4493
+ "magenta",
4494
+ "maroon",
4495
+ "mediumaquamarine",
4496
+ "mediumblue",
4497
+ "mediumorchid",
4498
+ "mediumpurple",
4499
+ "mediumseagreen",
4500
+ "mediumslateblue",
4501
+ "mediumspringgreen",
4502
+ "mediumturquoise",
4503
+ "mediumvioletred",
4504
+ "midnightblue",
4505
+ "mintcream",
4506
+ "mistyrose",
4507
+ "moccasin",
4508
+ "navajowhite",
4509
+ "navy",
4510
+ "oldlace",
4511
+ "olive",
4512
+ "olivedrab",
4513
+ "orange",
4514
+ "orangered",
4515
+ "orchid",
4516
+ "palegoldenrod",
4517
+ "palegreen",
4518
+ "paleturquoise",
4519
+ "palevioletred",
4520
+ "papayawhip",
4521
+ "peachpuff",
4522
+ "peru",
4523
+ "pink",
4524
+ "plum",
4525
+ "powderblue",
4526
+ "purple",
4527
+ "rebeccapurple",
4528
+ "red",
4529
+ "rosybrown",
4530
+ "royalblue",
4531
+ "saddlebrown",
4532
+ "salmon",
4533
+ "sandybrown",
4534
+ "seagreen",
4535
+ "seashell",
4536
+ "sienna",
4537
+ "silver",
4538
+ "skyblue",
4539
+ "slateblue",
4540
+ "slategray",
4541
+ "slategrey",
4542
+ "snow",
4543
+ "springgreen",
4544
+ "steelblue",
4545
+ "tan",
4546
+ "teal",
4547
+ "thistle",
4548
+ "tomato",
4549
+ "turquoise",
4550
+ "violet",
4551
+ "wheat",
4552
+ "white",
4553
+ "whitesmoke",
4554
+ "yellow",
4555
+ "yellowgreen",
4556
+ // CSS color keywords
4557
+ "transparent",
4558
+ "currentcolor",
4559
+ // CSS-wide keywords (should never be wrapped in var())
4560
+ "inherit",
4561
+ "initial",
4562
+ "unset",
4563
+ "revert"
4564
+ ]);
4565
+ function isCssNamedColor(value) {
4566
+ return CSS_NAMED_COLORS.has(value.toLowerCase());
4567
+ }
4568
+
3816
4569
  // lib/shared/utilityClassNames.ts
3817
4570
  var SORTED_ROOTS = Object.keys(prefixToCSSProperty).sort((a, b) => b.length - a.length);
3818
4571
  function camelToKebab(prop) {
@@ -3865,15 +4618,16 @@ function transformOutsideUrl(input, transform) {
3865
4618
  function encodeArbitraryValue(value) {
3866
4619
  let ok = true;
3867
4620
  const encoded = transformOutsideUrl(value, (segment) => {
3868
- if (/[_"'\\[\]]/.test(segment)) ok = false;
3869
- return segment.replace(/\s+/g, "_");
4621
+ if (/["'\\[\]]/.test(segment)) ok = false;
4622
+ return segment.replace(/_/g, "\\_").replace(/\s+/g, "_");
3870
4623
  });
3871
4624
  if (!ok) return null;
3872
- if (/[\s"'\\[\]]/.test(encoded.replace(/^\[|\]$/g, ""))) return null;
4625
+ const guardTarget = encoded.replace(/^\[|\]$/g, "").replace(/\\_/g, "");
4626
+ if (/[\s"'\\[\]]/.test(guardTarget)) return null;
3873
4627
  return encoded;
3874
4628
  }
3875
4629
  function decodeArbitraryValue(encoded) {
3876
- return transformOutsideUrl(encoded, (segment) => segment.replace(/_/g, " "));
4630
+ return transformOutsideUrl(encoded, (segment) => segment.replace(/\\_|_/g, (m) => m === "\\_" ? "_" : " "));
3877
4631
  }
3878
4632
  var FONT_SIZE_KEYWORDS = /* @__PURE__ */ new Set([
3879
4633
  "xx-small",
@@ -3893,6 +4647,12 @@ function isColorValue(value) {
3893
4647
  if (value === "transparent" || value === "currentColor" || value === "currentcolor") return true;
3894
4648
  return isCssNamedColor(value);
3895
4649
  }
4650
+ function isBareColorTokenName(value) {
4651
+ if (!/^[a-zA-Z][\w-]*$/.test(value)) return false;
4652
+ if (isColorValue(value)) return false;
4653
+ if (/^[a-z]+-\d/i.test(value)) return false;
4654
+ return true;
4655
+ }
3896
4656
  function isFontSizeValue(value) {
3897
4657
  if (/^[\d.+-]/.test(value)) return true;
3898
4658
  if (/^(calc|clamp|min|max)\(/i.test(value)) return true;
@@ -3909,6 +4669,16 @@ function isImageValue(value) {
3909
4669
  function isLengthValue(value) {
3910
4670
  return /^-?[\d.]+[a-z%]*$/i.test(value);
3911
4671
  }
4672
+ function hasTopLevelWhitespace(value) {
4673
+ let depth = 0;
4674
+ for (let i = 0; i < value.length; i++) {
4675
+ const ch = value[i] ?? "";
4676
+ if (ch === "(") depth++;
4677
+ else if (ch === ")") depth = Math.max(0, depth - 1);
4678
+ else if (depth === 0 && /\s/.test(ch)) return true;
4679
+ }
4680
+ return false;
4681
+ }
3912
4682
  function resolveRootProperty(root, value) {
3913
4683
  switch (root) {
3914
4684
  case "text":
@@ -3918,9 +4688,9 @@ function resolveRootProperty(root, value) {
3918
4688
  case "bg":
3919
4689
  return isImageValue(value) ? "background-image" : "background-color";
3920
4690
  case "border":
3921
- return !value.includes(" ") && isColorValue(value) ? "border-color" : "border";
4691
+ return isColorValue(value) && !hasTopLevelWhitespace(value) ? "border-color" : "border";
3922
4692
  case "outline": {
3923
- if (value.includes(" ") || value === "none") return "outline";
4693
+ if (hasTopLevelWhitespace(value) || value === "none") return "outline";
3924
4694
  if (isColorValue(value)) return "outline-color";
3925
4695
  if (isLengthValue(value)) return "outline-width";
3926
4696
  return "outline";
@@ -3932,15 +4702,34 @@ function resolveRootProperty(root, value) {
3932
4702
  function splitVariantPrefix(className) {
3933
4703
  const match = className.match(/^([a-z][a-z0-9_-]*):(.+)$/);
3934
4704
  if (match) {
3935
- return { breakpoint: match[1], base: match[2] };
4705
+ return { breakpoint: match[1] ?? null, base: match[2] ?? className };
3936
4706
  }
3937
4707
  return { breakpoint: null, base: className };
3938
4708
  }
4709
+ var DESKTOP_FIRST_VARIANT_PREFIX = "max-";
4710
+ var BREAKPOINT_NAME_TO_CLASS = { tablet: "lg", mobile: "sm" };
4711
+ var CLASS_NAME_TO_BREAKPOINT = { lg: "tablet", sm: "mobile" };
3939
4712
  function breakpointClassPrefix(breakpointName) {
3940
- return `${breakpointName.toLowerCase()}:`;
4713
+ const lower = breakpointName.toLowerCase();
4714
+ const aliased = BREAKPOINT_NAME_TO_CLASS[lower] ?? lower;
4715
+ return `${DESKTOP_FIRST_VARIANT_PREFIX}${aliased}:`;
4716
+ }
4717
+ function breakpointClassPrefixes(breakpointName) {
4718
+ const lower = breakpointName.toLowerCase();
4719
+ const aliased = BREAKPOINT_NAME_TO_CLASS[lower];
4720
+ const prefixes = [`${DESKTOP_FIRST_VARIANT_PREFIX}${lower}:`, `${lower}:`];
4721
+ if (aliased) prefixes.unshift(`${DESKTOP_FIRST_VARIANT_PREFIX}${aliased}:`);
4722
+ return prefixes;
4723
+ }
4724
+ function normalizeBreakpointVariant(variant) {
4725
+ if (variant?.startsWith(DESKTOP_FIRST_VARIANT_PREFIX)) {
4726
+ const bare = variant.slice(DESKTOP_FIRST_VARIANT_PREFIX.length);
4727
+ return CLASS_NAME_TO_BREAKPOINT[bare] ?? bare;
4728
+ }
4729
+ return variant;
3941
4730
  }
3942
4731
  var HASH_VALUE_RE = /^h[0-9a-z]+$/;
3943
- function parseUtilityClass(className) {
4732
+ function parseUtilityClass(className, knownTokens) {
3944
4733
  const stat = staticUtilityReverse[className];
3945
4734
  if (stat) {
3946
4735
  return { property: camelToKebab(stat.prop), value: stat.value, root: null, kind: "static" };
@@ -3952,8 +4741,8 @@ function parseUtilityClass(className) {
3952
4741
  const arbProp = className.match(/^\[([a-z-]+):(.+)\]$/);
3953
4742
  if (arbProp) {
3954
4743
  return {
3955
- property: arbProp[1],
3956
- value: decodeArbitraryValue(arbProp[2]),
4744
+ property: arbProp[1] ?? "",
4745
+ value: decodeArbitraryValue(arbProp[2] ?? ""),
3957
4746
  root: null,
3958
4747
  kind: "arbitrary-property"
3959
4748
  };
@@ -3962,12 +4751,12 @@ function parseUtilityClass(className) {
3962
4751
  if (!className.startsWith(`${root}-`)) continue;
3963
4752
  const rest = className.slice(root.length + 1);
3964
4753
  if (!rest) continue;
3965
- const parsed = parseRootValue(root, rest);
4754
+ const parsed = parseRootValue(root, rest, knownTokens);
3966
4755
  if (parsed) return parsed;
3967
4756
  }
3968
4757
  return null;
3969
4758
  }
3970
- function parseRootValue(root, rest) {
4759
+ function parseRootValue(root, rest, knownTokens) {
3971
4760
  if (rest.startsWith("[") && rest.endsWith("]") && rest.length > 2) {
3972
4761
  const value = decodeArbitraryValue(rest.slice(1, -1));
3973
4762
  return { property: resolveRootProperty(root, value), value, root, kind: "arbitrary" };
@@ -3993,18 +4782,79 @@ function parseRootValue(root, rest) {
3993
4782
  if (genericKeywordRoots.has(root) && /^[a-z][a-z-]*$/.test(rest)) {
3994
4783
  return { property: resolveRootProperty(root, rest), value: rest, root, kind: "keyword" };
3995
4784
  }
4785
+ if (SPACING_SCALE_ROOTS.has(root)) {
4786
+ const scaleVal = SPACING_SCALE[rest];
4787
+ if (scaleVal !== void 0) {
4788
+ return { property: resolveRootProperty(root, scaleVal), value: scaleVal, root, kind: "keyword" };
4789
+ }
4790
+ }
3996
4791
  if (integerValueRoots.has(root) && /^-?\d+$/.test(rest)) {
3997
- return { property: prefixToCSSProperty[root], value: rest, root, kind: "numeric" };
4792
+ return { property: prefixToCSSProperty[root] ?? root, value: rest, root, kind: "numeric" };
3998
4793
  }
3999
4794
  if (root === "opacity" && /^\d{1,3}$/.test(rest)) {
4000
4795
  return { property: "opacity", value: String(Number(rest) / 100), root, kind: "numeric" };
4001
4796
  }
4797
+ if (COLOR_TOKEN_ROOTS.has(root) && knownTokens?.has(rest)) {
4798
+ const value = `var(--${rest})`;
4799
+ return { property: resolveRootProperty(root, value), value, root, kind: "var" };
4800
+ }
4002
4801
  if (HASH_VALUE_RE.test(rest)) {
4003
- return { property: prefixToCSSProperty[root], value: null, root, kind: "hash" };
4802
+ return { property: prefixToCSSProperty[root] ?? root, value: null, root, kind: "hash" };
4004
4803
  }
4005
4804
  return null;
4006
4805
  }
4007
4806
 
4807
+ // lib/shared/styleValueRegistry.ts
4808
+ var registry = /* @__PURE__ */ new Map();
4809
+ var dynamicRegistry = /* @__PURE__ */ new Map();
4810
+ function registerStyleValue(className, value) {
4811
+ registry.set(className, value);
4812
+ }
4813
+ function registerDynamicStyle(className, property, value) {
4814
+ dynamicRegistry.set(className, { property, value });
4815
+ }
4816
+ function getStyleValue(className) {
4817
+ return registry.get(className);
4818
+ }
4819
+ function getDynamicStyle(className) {
4820
+ return dynamicRegistry.get(className);
4821
+ }
4822
+ function isDynamicClass(className) {
4823
+ return dynamicRegistry.has(className);
4824
+ }
4825
+ function getAllDynamicClasses() {
4826
+ return Array.from(dynamicRegistry.keys());
4827
+ }
4828
+ function clearRegistry() {
4829
+ registry.clear();
4830
+ dynamicRegistry.clear();
4831
+ }
4832
+ function serializeRegistry() {
4833
+ return JSON.stringify({
4834
+ standard: Array.from(registry.entries()),
4835
+ dynamic: Array.from(dynamicRegistry.entries())
4836
+ });
4837
+ }
4838
+ function hydrateRegistry(data) {
4839
+ const parsed = JSON.parse(data);
4840
+ if (Array.isArray(parsed)) {
4841
+ for (const [key, value] of parsed) {
4842
+ registry.set(key, value);
4843
+ }
4844
+ } else {
4845
+ if (parsed.standard) {
4846
+ for (const [key, value] of parsed.standard) {
4847
+ registry.set(key, value);
4848
+ }
4849
+ }
4850
+ if (parsed.dynamic) {
4851
+ for (const [key, value] of parsed.dynamic) {
4852
+ dynamicRegistry.set(key, value);
4853
+ }
4854
+ }
4855
+ }
4856
+ }
4857
+
4008
4858
  // lib/shared/utilityClassMapper.ts
4009
4859
  function isStyleMapping(value) {
4010
4860
  return typeof value === "object" && value !== null && "_mapping" in value && value._mapping === true;
@@ -4017,10 +4867,9 @@ function shortHash(input) {
4017
4867
  }
4018
4868
  return (hash >>> 0).toString(36);
4019
4869
  }
4020
- function isBareColorToken(value) {
4021
- if (!/^[a-zA-Z][\w-]*$/.test(value)) return false;
4022
- if (isColorValue(value)) return false;
4023
- return true;
4870
+ function rootFormMisresolves(root, prop, value) {
4871
+ const parsedProp = ROOT_CAMEL_OVERRIDES[root] ?? cssPropertyToCamel(resolveRootProperty(root, value));
4872
+ return parsedProp !== prop;
4024
4873
  }
4025
4874
  function propertyValueToClass(prop, value) {
4026
4875
  let stringValue = String(value);
@@ -4038,19 +4887,22 @@ function propertyValueToClass(prop, value) {
4038
4887
  registerStyleValue(staticClass, stringValue);
4039
4888
  return staticClass;
4040
4889
  }
4041
- if (prop === "boxShadow" && shadowPresets[stringValue]) {
4890
+ const shadowPreset = shadowPresets[stringValue];
4891
+ if (prop === "boxShadow" && shadowPreset) {
4042
4892
  const className2 = `shadow-${stringValue}`;
4043
- registerStyleValue(className2, shadowPresets[stringValue]);
4893
+ registerStyleValue(className2, shadowPreset);
4044
4894
  return className2;
4045
4895
  }
4046
- if ((prop === "background" || prop === "backgroundImage") && gradientPresets[stringValue]) {
4896
+ const gradientPreset = gradientPresets[stringValue];
4897
+ if ((prop === "background" || prop === "backgroundImage") && gradientPreset) {
4047
4898
  const className2 = `bg-gradient-${stringValue}`;
4048
- registerStyleValue(className2, gradientPresets[stringValue]);
4899
+ registerStyleValue(className2, gradientPreset);
4049
4900
  return className2;
4050
4901
  }
4051
- if (prop === "border" && borderPresets[stringValue]) {
4902
+ const borderPreset = borderPresets[stringValue];
4903
+ if (prop === "border" && borderPreset) {
4052
4904
  const className2 = `border-preset-${stringValue}`;
4053
- registerStyleValue(className2, borderPresets[stringValue]);
4905
+ registerStyleValue(className2, borderPreset);
4054
4906
  return className2;
4055
4907
  }
4056
4908
  const root = propertyMap[prop];
@@ -4086,21 +4938,32 @@ function propertyValueToClass(prop, value) {
4086
4938
  }
4087
4939
  }
4088
4940
  }
4941
+ if (!className && SPACING_SCALE_ROOTS.has(root)) {
4942
+ const step = SPACING_SCALE_REVERSE[stringValue];
4943
+ if (step !== void 0) {
4944
+ className = `${root}-${step}`;
4945
+ }
4946
+ }
4089
4947
  if (!className) {
4090
4948
  const varMatch = stringValue.match(/^var\((--[\w-]+)\)$/);
4091
4949
  if (varMatch) {
4950
+ const varName = (varMatch[1] ?? "").slice(2);
4092
4951
  if (prop === "fontSize") className = `text-(length:${varMatch[1]})`;
4093
4952
  else if (prop === "fontWeight") className = `font-(number:${varMatch[1]})`;
4094
- else className = `${root}-(${varMatch[1]})`;
4953
+ else if (rootFormMisresolves(root, prop, stringValue)) {
4954
+ className = `[${camelToKebab(prop)}:${stringValue}]`;
4955
+ } else if (colorTokenProps.has(prop) && isBareColorTokenName(varName)) {
4956
+ className = `${root}-${varName}`;
4957
+ } else className = `${root}-(${varMatch[1]})`;
4095
4958
  }
4096
4959
  }
4097
- if (!className && colorTokenProps.has(prop) && isBareColorToken(stringValue)) {
4098
- className = `${root}-(--${stringValue})`;
4960
+ if (!className && colorTokenProps.has(prop) && isBareColorTokenName(stringValue)) {
4961
+ className = `${root}-${stringValue}`;
4099
4962
  }
4100
4963
  if (!className) {
4101
4964
  const encoded = encodeArbitraryValue(stringValue);
4102
4965
  if (encoded != null) {
4103
- className = `${root}-[${encoded}]`;
4966
+ className = rootFormMisresolves(root, prop, stringValue) ? `[${camelToKebab(prop)}:${encoded}]` : `${root}-[${encoded}]`;
4104
4967
  }
4105
4968
  }
4106
4969
  if (!className) {
@@ -4121,6 +4984,7 @@ function stylesToClasses(styles) {
4121
4984
  const classes = [];
4122
4985
  for (const prop of sortedProps) {
4123
4986
  const value = styles[prop];
4987
+ if (value === void 0) continue;
4124
4988
  if (isStyleMapping(value)) continue;
4125
4989
  const className = propertyValueToClass(prop, value);
4126
4990
  if (className) {
@@ -4209,7 +5073,7 @@ function responsiveStylesToClasses(styles, options) {
4209
5073
  }
4210
5074
  return classes;
4211
5075
  }
4212
- function classToStyle(className) {
5076
+ function classToStyle(className, knownTokens) {
4213
5077
  const { base: cleanClass } = splitVariantPrefix(className);
4214
5078
  if (staticUtilityReverse[cleanClass]) {
4215
5079
  return staticUtilityReverse[cleanClass];
@@ -4217,7 +5081,7 @@ function classToStyle(className) {
4217
5081
  if (presetClassReverse[cleanClass]) {
4218
5082
  return presetClassReverse[cleanClass];
4219
5083
  }
4220
- const parsed = parseUtilityClass(cleanClass);
5084
+ const parsed = parseUtilityClass(cleanClass, knownTokens);
4221
5085
  if (!parsed) {
4222
5086
  const dynamic = getDynamicStyle(cleanClass);
4223
5087
  if (dynamic) {
@@ -4244,12 +5108,13 @@ function classToStyle(className) {
4244
5108
  }
4245
5109
  return { prop, value };
4246
5110
  }
4247
- function classesToStyles(classes) {
5111
+ function classesToStyles(classes, knownTokens) {
4248
5112
  const styles = { base: {}, tablet: {}, mobile: {} };
4249
5113
  for (const className of classes) {
4250
5114
  const { breakpoint: variant, base: cleanClass } = splitVariantPrefix(className);
4251
- const breakpoint = variant === "tablet" ? "tablet" : variant === "mobile" ? "mobile" : "base";
4252
- const styleEntry = classToStyle(cleanClass);
5115
+ const bp = normalizeBreakpointVariant(variant);
5116
+ const breakpoint = bp === "tablet" ? "tablet" : bp === "mobile" ? "mobile" : "base";
5117
+ const styleEntry = classToStyle(cleanClass, knownTokens);
4253
5118
  if (styleEntry) {
4254
5119
  if (!styles[breakpoint]) {
4255
5120
  styles[breakpoint] = {};
@@ -4259,7 +5124,53 @@ function classesToStyles(classes) {
4259
5124
  }
4260
5125
  if (Object.keys(styles.tablet || {}).length === 0) delete styles.tablet;
4261
5126
  if (Object.keys(styles.mobile || {}).length === 0) delete styles.mobile;
4262
- return Object.keys(styles.base || {}).length > 0 ? styles : null;
5127
+ const hasAny = Object.keys(styles.base || {}).length > 0 || Object.keys(styles.tablet || {}).length > 0 || Object.keys(styles.mobile || {}).length > 0;
5128
+ return hasAny ? styles : null;
5129
+ }
5130
+ function isClassableStyleValue(value) {
5131
+ if (typeof value === "number") return true;
5132
+ if (typeof value === "string") return !value.includes("{{");
5133
+ return false;
5134
+ }
5135
+ function splitStyleBucket(bucket) {
5136
+ const classable = {};
5137
+ const residual = {};
5138
+ for (const [k, v] of Object.entries(bucket)) {
5139
+ if (isClassableStyleValue(v)) classable[k] = v;
5140
+ else residual[k] = v;
5141
+ }
5142
+ return { classable, residual };
5143
+ }
5144
+ function splitStyleByClassability(style) {
5145
+ if (!style || typeof style !== "object") return { classable: null, residual: null };
5146
+ if (isResponsiveStyle(style)) {
5147
+ const classable = {};
5148
+ const residual = {};
5149
+ for (const [bp, bucket] of Object.entries(style)) {
5150
+ if (!bucket || typeof bucket !== "object") continue;
5151
+ const split2 = splitStyleBucket(bucket);
5152
+ if (Object.keys(split2.classable).length > 0) classable[bp] = split2.classable;
5153
+ if (Object.keys(split2.residual).length > 0) residual[bp] = split2.residual;
5154
+ }
5155
+ return {
5156
+ classable: Object.keys(classable).length > 0 ? classable : null,
5157
+ residual: Object.keys(residual).length > 0 ? residual : null
5158
+ };
5159
+ }
5160
+ const split = splitStyleBucket(style);
5161
+ return {
5162
+ classable: Object.keys(split.classable).length > 0 ? { base: split.classable } : null,
5163
+ residual: Object.keys(split.residual).length > 0 ? { base: split.residual } : null
5164
+ };
5165
+ }
5166
+ function styleHasMapping(style) {
5167
+ if (!style || typeof style !== "object") return false;
5168
+ const buckets = isResponsiveStyle(style) ? Object.values(style) : [style];
5169
+ for (const bucket of buckets) {
5170
+ if (!bucket || typeof bucket !== "object") continue;
5171
+ for (const v of Object.values(bucket)) if (isStyleMapping(v)) return true;
5172
+ }
5173
+ return false;
4263
5174
  }
4264
5175
 
4265
5176
  // lib/shared/paths/Path.ts
@@ -4292,7 +5203,7 @@ function validatePath(path) {
4292
5203
  }
4293
5204
  for (let i = 0; i < path.length; i++) {
4294
5205
  const value = path[i];
4295
- if (typeof value !== "number" || isNaN(value) || !isFinite(value)) {
5206
+ if (typeof value !== "number" || Number.isNaN(value) || !Number.isFinite(value)) {
4296
5207
  throw new InvalidPathError(`Invalid path value at index ${i}: expected number, got ${typeof value}`, path, i);
4297
5208
  }
4298
5209
  }
@@ -4320,7 +5231,7 @@ function stringToPath(str) {
4320
5231
  }
4321
5232
  return str.split(",").map((s) => {
4322
5233
  const num = parseInt(s, 10);
4323
- if (isNaN(num)) {
5234
+ if (Number.isNaN(num)) {
4324
5235
  throw new PathConversionError(`Invalid numeric index: ${s}`, str);
4325
5236
  }
4326
5237
  return num;
@@ -4345,9 +5256,9 @@ function domPathStringToTreePath(domPath) {
4345
5256
  const path = [0];
4346
5257
  for (let i = 0; i < parts.length; i++) {
4347
5258
  if (parts[i] === CHILDREN_TOKEN && i + 1 < parts.length) {
4348
- const indexStr = parts[i + 1];
5259
+ const indexStr = parts[i + 1] ?? "";
4349
5260
  const index = parseInt(indexStr, 10);
4350
- if (!isNaN(index) && indexStr === String(index)) {
5261
+ if (!Number.isNaN(index) && indexStr === String(index)) {
4351
5262
  path.push(index);
4352
5263
  i++;
4353
5264
  }
@@ -4381,6 +5292,7 @@ function calculateChildrenExpansionOffset(componentPath, componentStructure, ins
4381
5292
  let currentNode = componentStructure;
4382
5293
  for (let i = 1; i < componentPath.length; i++) {
4383
5294
  const index = componentPath[i];
5295
+ if (index === void 0) break;
4384
5296
  if (!currentNode || !Array.isArray(currentNode.children)) {
4385
5297
  break;
4386
5298
  }
@@ -4446,12 +5358,12 @@ function convertPagePathToComponentPath(pagePath, componentInstancePath, compone
4446
5358
  if (suffix.length > 0 && componentStructure && Array.isArray(instanceChildren)) {
4447
5359
  const childrenCount = instanceChildren.length;
4448
5360
  if (Array.isArray(componentStructure.children) && componentStructure.children.length > 0 && isSlotMarker(componentStructure.children[0])) {
4449
- const pageFirstIndex = suffix[0];
5361
+ const pageFirstIndex = suffix[0] ?? 0;
4450
5362
  if (pageFirstIndex < childrenCount) {
4451
5363
  adjustedSuffix = suffix;
4452
5364
  } else {
4453
5365
  const offset = childrenCount - 1;
4454
- adjustedSuffix = [suffix[0] - offset, ...suffix.slice(1)];
5366
+ adjustedSuffix = [pageFirstIndex - offset, ...suffix.slice(1)];
4455
5367
  }
4456
5368
  }
4457
5369
  }
@@ -4465,7 +5377,7 @@ function convertComponentPathToPagePath(componentPath, componentInstancePath, co
4465
5377
  const offset = calculateChildrenExpansionOffset(componentPath, componentStructure, instanceChildren);
4466
5378
  let adjustedSuffix = suffix;
4467
5379
  if (offset > 0 && suffix.length > 0) {
4468
- adjustedSuffix = [suffix[0] + offset, ...suffix.slice(1)];
5380
+ adjustedSuffix = [(suffix[0] ?? 0) + offset, ...suffix.slice(1)];
4469
5381
  }
4470
5382
  return [...componentInstancePath, ...adjustedSuffix];
4471
5383
  }
@@ -4499,8 +5411,8 @@ function parseElementClassName(className) {
4499
5411
  if (!match) return null;
4500
5412
  return {
4501
5413
  fileType: match[1] === "c" ? "component" : "page",
4502
- fileName: match[2],
4503
- elementName: match[3]
5414
+ fileName: match[2] ?? "",
5415
+ elementName: match[3] ?? ""
4504
5416
  };
4505
5417
  }
4506
5418
 
@@ -4627,7 +5539,7 @@ function createStyleMappingFromProps(componentPropDefs, currentValue) {
4627
5539
  mappingValues[opt] = "";
4628
5540
  });
4629
5541
  } else {
4630
- mappingValues["default"] = currentValue;
5542
+ mappingValues.default = currentValue;
4631
5543
  }
4632
5544
  return {
4633
5545
  _mapping: true,
@@ -4638,7 +5550,7 @@ function createStyleMappingFromProps(componentPropDefs, currentValue) {
4638
5550
 
4639
5551
  // lib/shared/linkUtils.ts
4640
5552
  function normalizePath(path) {
4641
- let normalized = path.split("?")[0].split("#")[0];
5553
+ let normalized = (path.split("?")[0] ?? "").split("#")[0] ?? "";
4642
5554
  if (normalized.length > 1 && normalized.endsWith("/")) {
4643
5555
  normalized = normalized.slice(0, -1);
4644
5556
  }
@@ -4650,7 +5562,7 @@ function isCurrentLink(href, currentPagePath) {
4650
5562
  }
4651
5563
 
4652
5564
  // lib/shared/viewportUnits.ts
4653
- var VIEWPORT_UNIT_RE = /(?<![\w-])(-?\d*\.?\d+)(s|l|d)?(vh|vw)\b/g;
5565
+ var VIEWPORT_UNIT_RE = /(?<![\w\-[])(-?\d*\.?\d+)(s|l|d)?(vh|vw)\b/g;
4654
5566
  function rewriteViewportUnits(input) {
4655
5567
  if (!input) return input;
4656
5568
  return input.replace(VIEWPORT_UNIT_RE, (_match, num, sizeKw, axis) => {
@@ -4750,11 +5662,59 @@ function toFriendlyError(input) {
4750
5662
  };
4751
5663
  }
4752
5664
 
5665
+ // lib/shared/pxToRem.ts
5666
+ var DEFAULT_REM_CONFIG = {
5667
+ enabled: false,
5668
+ baseFontSize: 16
5669
+ };
5670
+ var PX_REGEX = /(-?\d*\.?\d+)px/g;
5671
+ function convertPxToRem(cssValue, baseFontSize) {
5672
+ return cssValue.replace(PX_REGEX, (_, num) => {
5673
+ const px = parseFloat(num);
5674
+ if (px === 0) return "0";
5675
+ const rem = px / baseFontSize;
5676
+ const rounded = parseFloat(rem.toFixed(4));
5677
+ return `${rounded}rem`;
5678
+ });
5679
+ }
5680
+ var PX_KEEP_PROPERTIES = /* @__PURE__ */ new Set([
5681
+ "border-width",
5682
+ "border-top-width",
5683
+ "border-right-width",
5684
+ "border-bottom-width",
5685
+ "border-left-width",
5686
+ "outline-width",
5687
+ "outline-offset",
5688
+ "border",
5689
+ "box-shadow",
5690
+ "text-shadow"
5691
+ ]);
5692
+ function shouldConvertProperty(cssProperty) {
5693
+ return !PX_KEEP_PROPERTIES.has(cssProperty);
5694
+ }
5695
+ function applyRemConversion(declarations, remConfig) {
5696
+ if (!remConfig?.enabled) return declarations;
5697
+ return declarations.split(";").map((decl) => {
5698
+ const trimmed = decl.trim();
5699
+ if (!trimmed) return "";
5700
+ const colonIndex = trimmed.indexOf(":");
5701
+ if (colonIndex === -1) return trimmed;
5702
+ const property = trimmed.substring(0, colonIndex).trim();
5703
+ const value = trimmed.substring(colonIndex + 1).trim();
5704
+ if (shouldConvertProperty(property)) {
5705
+ return `${property}: ${convertPxToRem(value, remConfig.baseFontSize)}`;
5706
+ }
5707
+ return trimmed;
5708
+ }).filter(Boolean).join("; ");
5709
+ }
5710
+
4753
5711
  // lib/shared/cssGeneration.ts
4754
5712
  var cssPropertyOrderMap = (() => {
4755
5713
  const map = /* @__PURE__ */ new Map();
4756
5714
  for (let i = 0; i < propertyOrder.length; i++) {
4757
- const kebab = camelToKebab(propertyOrder[i]);
5715
+ const prop = propertyOrder[i];
5716
+ if (prop === void 0) continue;
5717
+ const kebab = camelToKebab(prop);
4758
5718
  if (!map.has(kebab)) map.set(kebab, i);
4759
5719
  }
4760
5720
  return map;
@@ -4829,11 +5789,11 @@ var borderSideMap = {
4829
5789
  "border-b": "border-bottom",
4830
5790
  "border-l": "border-left"
4831
5791
  };
4832
- function generateRuleForClass(className) {
5792
+ function generateRuleForClass(className, knownTokens) {
4833
5793
  if (utilityClassRules[className]) {
4834
5794
  return utilityClassRules[className];
4835
5795
  }
4836
- const parsed = parseUtilityClass(className);
5796
+ const parsed = parseUtilityClass(className, knownTokens);
4837
5797
  if (!parsed) {
4838
5798
  const dynamicStyle = getDynamicStyle(className);
4839
5799
  if (dynamicStyle) {
@@ -4944,28 +5904,30 @@ function applyContainerPattern(style, fluidActive) {
4944
5904
  marginRight: "auto"
4945
5905
  };
4946
5906
  }
4947
- function generateUtilityCSS(usedClasses, breakpoints = DEFAULT_BREAKPOINTS, responsiveScales, remConfig) {
5907
+ function generateUtilityCSS(usedClasses, breakpoints = DEFAULT_BREAKPOINTS, responsiveScales, remConfig, knownTokens) {
4948
5908
  const css = [];
4949
5909
  const baseClasses = /* @__PURE__ */ new Set();
4950
5910
  const autoResponsiveClasses = /* @__PURE__ */ new Set();
4951
5911
  const breakpointValues = getBreakpointValues(breakpoints);
4952
5912
  const responsiveClasses = {};
4953
5913
  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
- };
5914
+ for (const prefix of breakpointClassPrefixes(breakpointName)) {
5915
+ responsiveClasses[prefix] = {
5916
+ classes: /* @__PURE__ */ new Set(),
5917
+ breakpointName,
5918
+ value: breakpointValue
5919
+ };
5920
+ }
4960
5921
  }
4961
5922
  for (const className of usedClasses) {
4962
5923
  let matched = false;
4963
5924
  for (const prefix of Object.keys(responsiveClasses)) {
4964
5925
  if (className.startsWith(prefix) && className.length > prefix.length) {
4965
5926
  const potentialClass = className.substring(prefix.length);
4966
- const rule = generateRuleForClass(potentialClass);
4967
- if (rule) {
4968
- responsiveClasses[prefix].classes.add(potentialClass);
5927
+ const rule = generateRuleForClass(potentialClass, knownTokens);
5928
+ const bucket = responsiveClasses[prefix];
5929
+ if (rule && bucket) {
5930
+ bucket.classes.add(potentialClass);
4969
5931
  matched = true;
4970
5932
  break;
4971
5933
  }
@@ -4987,7 +5949,7 @@ function generateUtilityCSS(usedClasses, breakpoints = DEFAULT_BREAKPOINTS, resp
4987
5949
  const mode = getResponsiveMode(responsiveScales);
4988
5950
  const fluidActive = responsiveScales?.enabled === true && mode === "fluid";
4989
5951
  for (const className of sortClassesByPropertyOrder(baseClasses)) {
4990
- let rule = generateRuleForClass(className);
5952
+ let rule = generateRuleForClass(className, knownTokens);
4991
5953
  if (rule) {
4992
5954
  if (fluidActive && autoResponsiveClasses.has(className)) {
4993
5955
  rule = applyFluidToUtilityRule(rule, className, responsiveScales, breakpoints);
@@ -5040,7 +6002,7 @@ function generateUtilityCSS(usedClasses, breakpoints = DEFAULT_BREAKPOINTS, resp
5040
6002
  for (const [prefix, breakpointInfo] of sortedManualResponsive) {
5041
6003
  const rules = [];
5042
6004
  for (const className of sortClassesByPropertyOrder(breakpointInfo.classes)) {
5043
- const rule = generateRuleForClass(className);
6005
+ const rule = generateRuleForClass(className, knownTokens);
5044
6006
  if (rule) {
5045
6007
  const escapedClassName = escapeCSSClassName(`${prefix}${className}`);
5046
6008
  const finalRule = applyRemConversion(rule, remConfig);
@@ -5055,21 +6017,24 @@ function generateUtilityCSS(usedClasses, breakpoints = DEFAULT_BREAKPOINTS, resp
5055
6017
  }
5056
6018
  return css.join("\n");
5057
6019
  }
5058
- function generateSingleClassCSS(className, breakpoints = DEFAULT_BREAKPOINTS, responsiveScales, remConfig) {
6020
+ function generateSingleClassCSS(className, breakpoints = DEFAULT_BREAKPOINTS, responsiveScales, remConfig, knownTokens) {
5059
6021
  const breakpointValues = getBreakpointValues(breakpoints);
5060
6022
  const css = [];
5061
6023
  const responsivePrefixes = {};
5062
6024
  for (const [breakpointName, breakpointValue] of Object.entries(breakpointValues)) {
5063
- responsivePrefixes[breakpointClassPrefix(breakpointName)] = { breakpointName, value: breakpointValue };
6025
+ for (const prefix of breakpointClassPrefixes(breakpointName)) {
6026
+ responsivePrefixes[prefix] = { breakpointName, value: breakpointValue };
6027
+ }
5064
6028
  }
5065
6029
  let matched = false;
5066
6030
  for (const prefix of Object.keys(responsivePrefixes)) {
5067
6031
  if (className.startsWith(prefix) && className.length > prefix.length) {
5068
6032
  const potentialClass = className.substring(prefix.length);
5069
- const rule = generateRuleForClass(potentialClass);
5070
- if (rule) {
6033
+ const rule = generateRuleForClass(potentialClass, knownTokens);
6034
+ const responsivePrefix = responsivePrefixes[prefix];
6035
+ if (rule && responsivePrefix) {
5071
6036
  const escapedClassName = escapeCSSClassName(className);
5072
- const bpValue = responsivePrefixes[prefix].value;
6037
+ const bpValue = responsivePrefix.value;
5073
6038
  const finalRule = applyRemConversion(rule, remConfig);
5074
6039
  css.push(`@media (max-width: ${bpValue}px) {
5075
6040
  .${escapedClassName} { ${finalRule} }
@@ -5080,7 +6045,7 @@ function generateSingleClassCSS(className, breakpoints = DEFAULT_BREAKPOINTS, re
5080
6045
  }
5081
6046
  }
5082
6047
  if (!matched) {
5083
- let rule = generateRuleForClass(className);
6048
+ let rule = generateRuleForClass(className, knownTokens);
5084
6049
  if (!rule) return "";
5085
6050
  const mode = getResponsiveMode(responsiveScales);
5086
6051
  const fluidActive = responsiveScales?.enabled === true && mode === "fluid";
@@ -5121,16 +6086,17 @@ function generateSingleClassCSS(className, breakpoints = DEFAULT_BREAKPOINTS, re
5121
6086
  }
5122
6087
  return css.join("\n");
5123
6088
  }
5124
- function extractUtilityClassesFromHTML(html) {
6089
+ function extractUtilityClassesFromHTML(html, knownTokens) {
5125
6090
  const classes = /* @__PURE__ */ new Set();
5126
6091
  const classRegex = /class="([^"]*)"/g;
5127
- let match;
5128
- while ((match = classRegex.exec(html)) !== null) {
5129
- const classList = match[1].split(/\s+/);
6092
+ let match = classRegex.exec(html);
6093
+ while (match !== null) {
6094
+ const classList = (match[1] ?? "").split(/\s+/);
6095
+ match = classRegex.exec(html);
5130
6096
  for (const className of classList) {
5131
6097
  if (!className) continue;
5132
6098
  const { base } = splitVariantPrefix(className);
5133
- if (parseUtilityClass(base)) {
6099
+ if (parseUtilityClass(base, knownTokens)) {
5134
6100
  classes.add(className);
5135
6101
  continue;
5136
6102
  }
@@ -5261,6 +6227,35 @@ function generateAllInteractiveCSS(interactiveStylesMap, breakpoints = DEFAULT_B
5261
6227
  }
5262
6228
 
5263
6229
  export {
6230
+ DEFAULT_BREAKPOINTS,
6231
+ normalizeBreakpointConfig,
6232
+ getBreakpointValues,
6233
+ getPreviewPointValues,
6234
+ getAllBreakpointNames,
6235
+ getBreakpointName,
6236
+ getBreakpointLabel,
6237
+ DEFAULT_FLUID_RANGE,
6238
+ DEFAULT_SITE_MARGIN,
6239
+ parseValue,
6240
+ SCALABLE_CSS_PROPERTIES,
6241
+ calculateResponsiveValue,
6242
+ getScaleMultiplier,
6243
+ parseMultiValue,
6244
+ scaleValue,
6245
+ scalePropertyValue,
6246
+ getResponsiveValues,
6247
+ resolveVariableValueAtBreakpoint,
6248
+ getSmallestBreakpointName,
6249
+ buildFluidClamp,
6250
+ buildFluidClampWithExplicitMin,
6251
+ buildSiteMarginClamp,
6252
+ buildFluidPropertyValue,
6253
+ DEFAULT_RESPONSIVE_SCALES,
6254
+ DEFAULT_REM_CONFIG,
6255
+ setErrorHandler,
6256
+ logRuntimeError,
6257
+ logNetworkError,
6258
+ init_errorLogger,
5264
6259
  DEFAULT_PREFETCH_CONFIG,
5265
6260
  PropDefinitionSchema,
5266
6261
  StyleMappingSchema,
@@ -5361,6 +6356,8 @@ export {
5361
6356
  isEmbedNode,
5362
6357
  isLinkNode,
5363
6358
  isLocaleListNode,
6359
+ isIslandNode,
6360
+ isCustomNode,
5364
6361
  isCMSListNode,
5365
6362
  isListNode,
5366
6363
  isValidNodeType,
@@ -5381,9 +6378,15 @@ export {
5381
6378
  isRichTextMarker,
5382
6379
  richTextMarkerToHtml,
5383
6380
  resolvePropsFromDefinition,
6381
+ propertyMap,
6382
+ staticUtilityReverse,
6383
+ keywordValues,
6384
+ presetClassReverse,
5384
6385
  CSS_NAMED_COLORS,
5385
6386
  isCssNamedColor,
5386
- breakpointClassPrefix,
6387
+ splitVariantPrefix,
6388
+ breakpointClassPrefixes,
6389
+ normalizeBreakpointVariant,
5387
6390
  registerStyleValue,
5388
6391
  registerDynamicStyle,
5389
6392
  getStyleValue,
@@ -5397,6 +6400,9 @@ export {
5397
6400
  responsiveStylesToClasses,
5398
6401
  classToStyle,
5399
6402
  classesToStyles,
6403
+ isClassableStyleValue,
6404
+ splitStyleByClassability,
6405
+ styleHasMapping,
5400
6406
  ROOT_STRING,
5401
6407
  ROOT_0_STRING,
5402
6408
  CHILDREN_SEPARATOR,
@@ -5443,4 +6449,4 @@ export {
5443
6449
  generateInteractiveCSS,
5444
6450
  generateAllInteractiveCSS
5445
6451
  };
5446
- //# sourceMappingURL=chunk-7HWQUVTU.js.map
6452
+ //# sourceMappingURL=chunk-2IIQK7T3.js.map