@riverbankcms/sdk 0.82.0 → 0.84.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (206) hide show
  1. package/README.md +16 -0
  2. package/dist/{PreviewEditorSidebar-LHGK6RIO.mjs → PreviewEditorSidebar-X7RLMEI6.mjs} +330 -11
  3. package/dist/{PreviewEditorUI-AXZG2SDC.mjs → PreviewEditorUI-CT67N4O3.mjs} +3 -3
  4. package/dist/SdkPreviewModeRuntime-EIMQ3S2V.mjs +8 -0
  5. package/dist/_dts/ai/src/contracts/proposals.d.ts +200 -0
  6. package/dist/_dts/api/src/blocks.d.ts +36 -0
  7. package/dist/_dts/api/src/contentRuntime.d.ts +46 -0
  8. package/dist/_dts/api/src/endpoints.d.ts +40 -0
  9. package/dist/_dts/api/src/index.d.ts +2 -2
  10. package/dist/_dts/api/src/sdk-event-pricing.d.ts +61 -0
  11. package/dist/_dts/api/src/sdk-event-schedule.d.ts +52 -0
  12. package/dist/_dts/api/src/sdk-event-upsert.d.ts +50 -0
  13. package/dist/_dts/api/src/sdkContracts.d.ts +67 -33
  14. package/dist/_dts/api/src/shared-contracts.d.ts +13 -0
  15. package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +22 -36
  16. package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +46 -1
  17. package/dist/_dts/block-form/src/backend/useBackendWatch.d.ts +6 -1
  18. package/dist/_dts/block-form/src/utils/evaluateVisibility.d.ts +3 -2
  19. package/dist/_dts/block-form/src/utils/visibleWhen.d.ts +7 -0
  20. package/dist/_dts/blocks/src/PageRenderer.d.ts +11 -0
  21. package/dist/_dts/blocks/src/bindings/index.d.ts +1 -1
  22. package/dist/_dts/blocks/src/client/site-chrome.d.ts +1 -1
  23. package/dist/_dts/blocks/src/client.d.ts +4 -0
  24. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +16 -4
  25. package/dist/_dts/blocks/src/system/blocks/appointment-booking.d.ts +288 -2016
  26. package/dist/_dts/blocks/src/system/blocks/blog-listing.d.ts +288 -2016
  27. package/dist/_dts/blocks/src/system/blocks/cart.d.ts +288 -2016
  28. package/dist/_dts/blocks/src/system/blocks/checkout.d.ts +288 -2016
  29. package/dist/_dts/blocks/src/system/blocks/collection.d.ts +288 -2016
  30. package/dist/_dts/blocks/src/system/blocks/contact-newsletter.d.ts +171 -0
  31. package/dist/_dts/blocks/src/system/blocks/faq.d.ts +288 -2016
  32. package/dist/_dts/blocks/src/system/blocks/gifting.d.ts +288 -2016
  33. package/dist/_dts/blocks/src/system/blocks/hero.d.ts +3 -2
  34. package/dist/_dts/blocks/src/system/blocks/index.d.ts +1 -0
  35. package/dist/_dts/blocks/src/system/blocks/location-map.d.ts +1 -7
  36. package/dist/_dts/blocks/src/system/blocks/media-text.d.ts +2534 -151
  37. package/dist/_dts/blocks/src/system/blocks/product-detail.d.ts +288 -2016
  38. package/dist/_dts/blocks/src/system/blocks/product-list.d.ts +288 -2016
  39. package/dist/_dts/blocks/src/system/blocks/shop.d.ts +288 -2016
  40. package/dist/_dts/blocks/src/system/blocks/site-header.d.ts +36 -3
  41. package/dist/_dts/blocks/src/system/blocks/team-members.d.ts +2 -2
  42. package/dist/_dts/blocks/src/system/constants/blockKinds.d.ts +1 -1
  43. package/dist/_dts/blocks/src/system/fields/aspectRatio.d.ts +4 -1
  44. package/dist/_dts/blocks/src/system/fields/imageShape.d.ts +30 -0
  45. package/dist/_dts/blocks/src/system/fragments/library/heroLayoutControls.d.ts +25 -0
  46. package/dist/_dts/blocks/src/system/manifest/schema.d.ts +35 -161
  47. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +24 -6
  48. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +12 -3
  49. package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessEventRegistrationFlow.d.ts +33 -0
  50. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationWizard.d.ts +0 -2
  51. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/constants.d.ts +1 -0
  52. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.contract.d.ts +275 -0
  53. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.override.d.ts +10 -0
  54. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.planning.d.ts +22 -0
  55. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.state.d.ts +3 -0
  56. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.d.ts +20 -1
  57. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +13 -4
  58. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/utils.d.ts +1 -1
  59. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +28 -6
  60. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/pricing.d.ts +14 -0
  61. package/dist/_dts/content-editor/src/controller/EntryControllerProvider.d.ts +1 -1
  62. package/dist/_dts/content-editor/src/controller/buildBlockPublishedBaselines.d.ts +1 -1
  63. package/dist/_dts/content-editor/src/controller/seedDraftBaselinesFromBlocks.d.ts +1 -1
  64. package/dist/_dts/content-editor/src/controller/useBlocksList.d.ts +1 -1
  65. package/dist/_dts/content-editor/src/controller/useInvalidBlockRecovery.d.ts +1 -1
  66. package/dist/_dts/content-editor/src/primitives/PreviewRichTextEditor.d.ts +2 -1
  67. package/dist/_dts/content-editor/src/primitives/PreviewTextEditor.d.ts +1 -0
  68. package/dist/_dts/content-model/src/entry-slots/index.d.ts +1 -0
  69. package/dist/_dts/content-model/src/entry-slots/types.d.ts +356 -0
  70. package/dist/_dts/content-model/src/index.d.ts +1 -0
  71. package/dist/_dts/content-model/src/templates/defaults.d.ts +7 -0
  72. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +100 -5
  73. package/dist/_dts/editor-blocks/src/BlockEditor.d.ts +6 -1
  74. package/dist/_dts/editor-blocks/src/BlockForm.d.ts +7 -5
  75. package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockCreation.d.ts +3 -2
  76. package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockDuplication.d.ts +3 -2
  77. package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockReorder.d.ts +3 -2
  78. package/dist/_dts/editor-blocks/src/block-editor/owner.d.ts +27 -0
  79. package/dist/_dts/editor-blocks/src/index.d.ts +1 -0
  80. package/dist/_dts/media-core/src/assetsInUseSummary.d.ts +8 -0
  81. package/dist/_dts/media-core/src/mediaUsageProjection.d.ts +37 -3
  82. package/dist/_dts/preview-next/src/client/blocks/pageDesignRuntimePreview.d.ts +4 -2
  83. package/dist/_dts/preview-next/src/client/blocks/previewProjection/runtimeContentDecoration.d.ts +2 -2
  84. package/dist/_dts/preview-next/src/client/preview/EntryEditorPanel.d.ts +3 -1
  85. package/dist/_dts/preview-next/src/client/preview/EntrySlotBlockEditorPanel.d.ts +19 -0
  86. package/dist/_dts/preview-next/src/client/preview/SiteChromeCustomizeButton.d.ts +8 -0
  87. package/dist/_dts/preview-next/src/client/preview/SiteChromeCustomizeContext.d.ts +4 -1
  88. package/dist/_dts/preview-next/src/client/preview/StyleConfigurator.state.d.ts +1 -1
  89. package/dist/_dts/preview-next/src/client/preview/linkedEntryEditEvents.d.ts +9 -0
  90. package/dist/_dts/preview-next/src/client/preview/previewCustomizeControls.d.ts +9 -8
  91. package/dist/_dts/preview-next/src/client/preview/siteChromeLookRows.d.ts +10 -1
  92. package/dist/_dts/preview-next/src/client/preview/siteChromeQuickControlHistoryState.d.ts +5 -1
  93. package/dist/_dts/sdk/src/bookings/index.d.ts +5 -4
  94. package/dist/_dts/sdk/src/bookings/types.d.ts +2 -2
  95. package/dist/_dts/sdk/src/cli/content/reader.d.ts +9 -8
  96. package/dist/_dts/sdk/src/cli/content/writer.d.ts +6 -1
  97. package/dist/_dts/sdk/src/cli/helpers.d.ts +10 -5
  98. package/dist/_dts/sdk/src/cli/merge-remote/entryLocal.d.ts +2 -2
  99. package/dist/_dts/sdk/src/cli/merge-remote/entryMerge.d.ts +2 -1
  100. package/dist/_dts/sdk/src/cli/merge-remote/entrySnapshots.d.ts +2 -2
  101. package/dist/_dts/sdk/src/client/management/index.d.ts +1 -1
  102. package/dist/_dts/sdk/src/client/management/types.d.ts +40 -10
  103. package/dist/_dts/sdk/src/config/field-definitions.d.ts +13 -7
  104. package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +26 -3
  105. package/dist/_dts/sdk/src/public-api/contracts.d.ts +13 -0
  106. package/dist/_dts/sdk/src/rendering/blocks-page-renderer.d.ts +1 -0
  107. package/dist/_dts/sdk/src/rendering/components/pageShared.d.ts +6 -1
  108. package/dist/_dts/sdk/src/rendering/overrides.d.ts +6 -1
  109. package/dist/_dts/sdk/src/types/block-kinds.d.ts +1 -1
  110. package/dist/_dts/sdk/src/version.d.ts +1 -1
  111. package/dist/_dts/site-commands/src/commands.d.ts +15 -0
  112. package/dist/_dts/theme-core/src/accordions/types.d.ts +1 -1
  113. package/dist/_dts/theme-core/src/buttons/personalities/index.d.ts +11 -0
  114. package/dist/_dts/theme-core/src/buttons/personalities/ornate-ritual.d.ts +16 -0
  115. package/dist/_dts/theme-core/src/buttons/personalities/types.d.ts +1 -1
  116. package/dist/_dts/theme-core/src/buttons/types.d.ts +3 -3
  117. package/dist/_dts/theme-core/src/cards/types.d.ts +15 -15
  118. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  119. package/dist/_dts/theme-core/src/inputs/types.d.ts +1 -1
  120. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +33 -33
  121. package/dist/_dts/theme-core/src/palette/variants/index.d.ts +15 -0
  122. package/dist/_dts/theme-core/src/palette/variants/warm-dark.d.ts +16 -0
  123. package/dist/_dts/theme-core/src/schema.d.ts +30 -25
  124. package/dist/_dts/theme-core/src/site-styles/backgroundAppearance.d.ts +2 -2
  125. package/dist/_dts/theme-core/src/site-styles/curatedSiteStyles.d.ts +141 -1
  126. package/dist/_dts/theme-core/src/site-styles/designState.d.ts +2 -0
  127. package/dist/_dts/theme-core/src/site-styles/footerLooks.d.ts +110 -5
  128. package/dist/_dts/theme-core/src/site-styles/generatedSchemas.d.ts +4 -2
  129. package/dist/_dts/theme-core/src/site-styles/previewCompiler.d.ts +1 -1
  130. package/dist/_dts/theme-core/src/site-styles/runtimeCompiler.d.ts +5 -1
  131. package/dist/_dts/theme-core/src/site-styles/tokenRecipes.d.ts +1 -1
  132. package/dist/_dts/theme-core/src/site-styles/types.d.ts +1 -1
  133. package/dist/_dts/theme-core/src/site-styles/typographyPresets.d.ts +16 -1
  134. package/dist/_dts/theme-core/src/siteChromePlanning.d.ts +1 -0
  135. package/dist/_dts/theme-core/src/utils/colorStyles.d.ts +6 -6
  136. package/dist/{chunk-2BUMISSH.mjs → chunk-3LXFQS7T.mjs} +1 -1
  137. package/dist/{chunk-FIREV57T.mjs → chunk-LBBPD2IW.mjs} +40 -0
  138. package/dist/{chunk-XQR6THQJ.mjs → chunk-O62NDCTI.mjs} +3390 -1331
  139. package/dist/{chunk-6FWNF3DJ.mjs → chunk-QRKJDWT7.mjs} +158 -20
  140. package/dist/{chunk-HKB6XVIP.mjs → chunk-RCTJAZSK.mjs} +2 -2
  141. package/dist/{chunk-G35HOQEN.mjs → chunk-X5ZCSU6F.mjs} +132 -46
  142. package/dist/cli/index.mjs +2925 -577
  143. package/dist/cli/init-docs/content/agents-section.md +5 -0
  144. package/dist/cli/init-docs/content/cli-reference.md +13 -0
  145. package/dist/cli/init-docs/content/content-management.md +31 -0
  146. package/dist/cli/init-docs/content/getting-started.md +14 -0
  147. package/dist/cli/init-docs/content/workflow-add-block.md +3 -1
  148. package/dist/cli/init-docs/content/workflow-agent-safe-sync.md +81 -0
  149. package/dist/cli/init-docs/content/workflow-create-page.md +13 -3
  150. package/dist/cli/init-docs/content/workflow-custom-block.md +9 -0
  151. package/dist/cli/init-docs/content/workflow-templates.md +107 -2
  152. package/dist/client/{accordion-G34C45TW.mjs → accordion-2UZPBMYM.mjs} +2 -2
  153. package/dist/client/{bookingForm-BLBVKSAQ.mjs → bookingForm-DYXT6YB6.mjs} +5 -5
  154. package/dist/client/bookings.mjs +3477 -186
  155. package/dist/client/{carousel-7ZVTBRMD.mjs → carousel-QH77HR6X.mjs} +3 -3
  156. package/dist/client/{cart-Q6S6LZUO.mjs → cart-X4YK4FTW.mjs} +6 -6
  157. package/dist/client/{checkout-5QJLDE4I.mjs → checkout-OM2BEPWD.mjs} +6 -6
  158. package/dist/client/{chunk-ZF4XEWDM.mjs → chunk-3DTWLTXM.mjs} +1 -1
  159. package/dist/client/{chunk-5PQH4Y75.mjs → chunk-4OXKTA3D.mjs} +2 -2
  160. package/dist/client/{chunk-WJFHDTYF.mjs → chunk-52CGCQ7B.mjs} +5 -5
  161. package/dist/client/{chunk-CHAB5ACD.mjs → chunk-7UCLJ5SP.mjs} +2 -2
  162. package/dist/client/{chunk-U2EW7RSR.mjs → chunk-F5VRX5Y6.mjs} +1 -1
  163. package/dist/client/{chunk-SBBSMFFG.mjs → chunk-SYIJ5JO2.mjs} +1 -1
  164. package/dist/client/{chunk-EQKYMX4N.mjs → chunk-UHDWIXVR.mjs} +180 -157
  165. package/dist/client/{chunk-RJHTCTCZ.mjs → chunk-VGDBVNOO.mjs} +429 -15
  166. package/dist/client/{chunk-S3MKFGOG.mjs → chunk-ZE5G642V.mjs} +1 -1
  167. package/dist/client/{chunk-CSZGLBYR.mjs → chunk-ZKUO52W3.mjs} +1 -1
  168. package/dist/client/client.mjs +2685 -847
  169. package/dist/client/{courseRegistration-VUG2JJDB.mjs → courseRegistration-YBOGURTA.mjs} +5 -5
  170. package/dist/client/{eventCalendar-E7D2LD4N.mjs → eventCalendar-K4QJVCMD.mjs} +7 -7
  171. package/dist/client/{eventCombined-FUZ2Z3CS.mjs → eventCombined-MTXGMTCZ.mjs} +7 -7
  172. package/dist/client/{eventDetails-QRITJAOW.mjs → eventDetails-3PC4NL3U.mjs} +7 -7
  173. package/dist/client/{eventListing-INMQMJZ5.mjs → eventListing-TFJET6DN.mjs} +7 -7
  174. package/dist/client/{eventRegistration-TOOJD4WU.mjs → eventRegistration-QGPBGJTW.mjs} +7 -7
  175. package/dist/client/{form-BOWN7ZNQ.mjs → form-MDKR4FNB.mjs} +2 -2
  176. package/dist/client/{headerSection-HFQNZOUU.mjs → headerSection-Y5TMR3TW.mjs} +3 -3
  177. package/dist/client/hooks.mjs +2077 -546
  178. package/dist/client/{locationMap-VUZGC7Y5.mjs → locationMap-RH2LG7FZ.mjs} +2 -2
  179. package/dist/client/{newsletterForm-X2XQTPCB.mjs → newsletterForm-ZR5UDGBT.mjs} +2 -2
  180. package/dist/client/{productDetail-TA7D2G2B.mjs → productDetail-OIGDR4YE.mjs} +6 -6
  181. package/dist/client/{productList-AZOLOZKM.mjs → productList-4MA5S2CX.mjs} +6 -6
  182. package/dist/client/rendering/client.mjs +2560 -1205
  183. package/dist/client/rendering/islands.mjs +19 -19
  184. package/dist/client/rendering.mjs +2932 -1021
  185. package/dist/client/{shop-ZDLO7IIG.mjs → shop-WXSYV5QO.mjs} +6 -6
  186. package/dist/preview-next/before-render.mjs +40 -0
  187. package/dist/preview-next/client/runtime.mjs +5 -5
  188. package/dist/preview-next/middleware.mjs +40 -0
  189. package/dist/{sdk-runtime-CTWKNBDQ.mjs → sdk-runtime-7HJYPRWQ.mjs} +6 -6
  190. package/dist/server/components.mjs +2232 -534
  191. package/dist/server/config-validation.mjs +2068 -536
  192. package/dist/server/config.mjs +2068 -536
  193. package/dist/server/data.mjs +2077 -546
  194. package/dist/server/index.mjs +42 -1
  195. package/dist/server/next.mjs +2345 -574
  196. package/dist/server/page-converter.mjs +2684 -1220
  197. package/dist/server/prebuild.mjs +1 -1
  198. package/dist/server/rendering/server.mjs +2244 -546
  199. package/dist/server/rendering.mjs +2323 -552
  200. package/dist/server/routing.mjs +2012 -420
  201. package/dist/server/server.mjs +2153 -549
  202. package/dist/server/theme-bridge.mjs +1180 -101
  203. package/dist/server/theme.mjs +92 -1
  204. package/dist/styles/index.css +292 -36
  205. package/package.json +1 -1
  206. package/dist/SdkPreviewModeRuntime-RNVRHFFR.mjs +0 -8
@@ -110,6 +110,30 @@ var init_collections = __esm({
110
110
  });
111
111
 
112
112
  // ../core/src/event-pricing.ts
113
+ function publicEventPricingType(pricing) {
114
+ switch (pricing.kind) {
115
+ case "drop_in":
116
+ case "free_registration":
117
+ return "free";
118
+ case "single_paid":
119
+ case "ticket_types":
120
+ case "course":
121
+ return isFreePublicEventPriceDisplay(pricing.display) ? "free" : "paid";
122
+ }
123
+ }
124
+ function isFreePublicEventPriceDisplay(display) {
125
+ switch (display.kind) {
126
+ case "free":
127
+ return true;
128
+ case "course":
129
+ return display.display.kind === "free";
130
+ case "exact":
131
+ case "from":
132
+ case "mixed":
133
+ case "unavailable":
134
+ return false;
135
+ }
136
+ }
113
137
  var init_event_pricing = __esm({
114
138
  "../core/src/event-pricing.ts"() {
115
139
  }
@@ -140,8 +164,139 @@ var init_booking_instalments = __esm({
140
164
  });
141
165
 
142
166
  // ../core/src/booking-date-time.ts
167
+ function isValidTimeZone(timeZone) {
168
+ try {
169
+ new Intl.DateTimeFormat(DEFAULT_LOCALE, { timeZone }).format(/* @__PURE__ */ new Date());
170
+ return true;
171
+ } catch {
172
+ return false;
173
+ }
174
+ }
175
+ function getSafeTimeZone(timeZone) {
176
+ const normalized = typeof timeZone === "string" ? timeZone.trim() : "";
177
+ return normalized && isValidTimeZone(normalized) ? normalized : FALLBACK_TIMEZONE;
178
+ }
179
+ function parseStrictBookingTimeZone(timeZone) {
180
+ const normalized = timeZone.trim();
181
+ if (!normalized || !isValidTimeZone(normalized)) {
182
+ return null;
183
+ }
184
+ return normalized;
185
+ }
186
+ function formatParseError(error) {
187
+ switch (error.reason) {
188
+ case "invalid_starts_at":
189
+ return `Expected a valid UTC/offset-aware ISO datetime in startsAt, received "${error.value}"`;
190
+ case "invalid_ends_at":
191
+ return `Expected a valid UTC/offset-aware ISO datetime in endsAt, received "${error.value ?? ""}"`;
192
+ case "invalid_time_zone":
193
+ return `Expected a valid IANA timezone in timeZone, received "${error.value}"`;
194
+ }
195
+ }
196
+ function formatToPartsLookup(date, locale, timeZone, format) {
197
+ return new Map(
198
+ new Intl.DateTimeFormat(locale, {
199
+ ...format,
200
+ timeZone
201
+ }).formatToParts(date).map((part) => [part.type, part.value])
202
+ );
203
+ }
204
+ function getZonedDateTimeParts(date, timeZone) {
205
+ const parts = formatToPartsLookup(date, "en-GB", timeZone, {
206
+ year: "numeric",
207
+ month: "2-digit",
208
+ day: "2-digit",
209
+ hour: "2-digit",
210
+ minute: "2-digit",
211
+ second: "2-digit",
212
+ hour12: false
213
+ });
214
+ const read = (type) => Number(parts.get(type) ?? "");
215
+ return {
216
+ year: read("year"),
217
+ month: read("month"),
218
+ day: read("day"),
219
+ hour: read("hour"),
220
+ minute: read("minute"),
221
+ second: read("second")
222
+ };
223
+ }
224
+ function formatDateKey(date) {
225
+ const year = String(date.year).padStart(4, "0");
226
+ const month = String(date.month).padStart(2, "0");
227
+ const day = String(date.day).padStart(2, "0");
228
+ return `${year}-${month}-${day}`;
229
+ }
230
+ function parseUtcIsoDateTimeString(value) {
231
+ const normalized = value.trim();
232
+ const hasUtcSuffix = normalized.endsWith("Z");
233
+ const hasExplicitOffset = /[+-]\d{2}:\d{2}$/u.test(normalized);
234
+ if (!hasUtcSuffix && !hasExplicitOffset) {
235
+ return err("missing-timezone-offset");
236
+ }
237
+ const date = new Date(normalized);
238
+ if (Number.isNaN(date.getTime())) {
239
+ return err("invalid-date-time");
240
+ }
241
+ return ok(date.toISOString());
242
+ }
243
+ function toUtcIsoDateTimeString(value) {
244
+ const parsed = parseUtcIsoDateTimeString(value);
245
+ if (!parsed.ok) {
246
+ const message = parsed.error === "missing-timezone-offset" ? `Expected an offset-aware ISO datetime, received "${value}"` : `Expected a valid ISO datetime, received "${value}"`;
247
+ throw new Error(message);
248
+ }
249
+ return parsed.value;
250
+ }
251
+ function parseScheduledBookingDateTime(input) {
252
+ try {
253
+ const startsAt = toUtcIsoDateTimeString(input.startsAt);
254
+ const timeZone = parseStrictBookingTimeZone(input.timeZone);
255
+ if (!timeZone) {
256
+ return {
257
+ ok: false,
258
+ field: "timeZone",
259
+ reason: "invalid_time_zone",
260
+ value: input.timeZone
261
+ };
262
+ }
263
+ return {
264
+ ok: true,
265
+ value: {
266
+ startsAt,
267
+ timeZone,
268
+ locale: input.locale
269
+ }
270
+ };
271
+ } catch {
272
+ return {
273
+ ok: false,
274
+ field: "startsAt",
275
+ reason: "invalid_starts_at",
276
+ value: input.startsAt
277
+ };
278
+ }
279
+ }
280
+ function toScheduledBookingDateTime(input) {
281
+ const result = parseScheduledBookingDateTime(input);
282
+ if (result.ok) {
283
+ return result.value;
284
+ }
285
+ throw new Error(formatParseError(result));
286
+ }
287
+ function getBookingLocalDateKey(input) {
288
+ return formatDateKey(getLocalScheduleDate(new Date(input.startsAt), input.timeZone));
289
+ }
290
+ function getLocalScheduleDate(date, timeZone) {
291
+ const parts = getZonedDateTimeParts(date, getSafeTimeZone(timeZone));
292
+ return { year: parts.year, month: parts.month, day: parts.day };
293
+ }
294
+ var DEFAULT_LOCALE, FALLBACK_TIMEZONE;
143
295
  var init_booking_date_time = __esm({
144
296
  "../core/src/booking-date-time.ts"() {
297
+ init_result();
298
+ DEFAULT_LOCALE = "en-US";
299
+ FALLBACK_TIMEZONE = "UTC";
145
300
  }
146
301
  });
147
302
 
@@ -1279,7 +1434,7 @@ function createSdkSelectField(input) {
1279
1434
  })
1280
1435
  );
1281
1436
  }
1282
- var visibilityLevels, MEDIA_KINDS, DISPLAY_MEDIA_KINDS, PUBLIC_FILE_FIELD_KINDS, siteOptionSources, mediaDeliverySchema, selectOptionSchema, selectSourceSchema, uiSchema, baseFieldSchema, textFieldSchema, richTextFieldSchema, mediaFieldSchema, fileFieldSchema, booleanFieldSchema, dateFieldSchema, timeFieldSchema, dateTimeFieldSchema, slugFieldSchema, urlFieldSchema, linkFieldSchema, selectFieldSchema, referenceFieldSchema, itemTypeSchema, repeaterFieldSchema, groupFieldSchema, modalFieldSchema, numberFieldSchema, tabDefinitionSchema, tabGroupFieldSchema, presetOptionSchema, presetOrCustomFieldSchema, contentTypeSelectFieldSchema, entryPickerFieldSchema, _fieldSchemaInternal, fieldSchema, slotSchema, typographyTokens, colorTokens, spacingTokens, radiusTokens, styleTokenSchema, behaviourSchema, quickFieldPrioritySchema, previewCustomizeManifestCurationSchema, blockCategoryEnum;
1437
+ var visibilityLevels, MEDIA_KINDS, DISPLAY_MEDIA_KINDS, PUBLIC_FILE_FIELD_KINDS, siteOptionSources, mediaDeliverySchema, selectOptionSchema, selectSourceSchema, visibleWhenPredicateSchema, visibleWhenSchema, uiSchema, baseFieldSchema, textFieldSchema, richTextFieldSchema, mediaFieldSchema, fileFieldSchema, booleanFieldSchema, dateFieldSchema, timeFieldSchema, dateTimeFieldSchema, slugFieldSchema, urlFieldSchema, linkFieldSchema, selectFieldSchema, referenceFieldSchema, itemTypeSchema, repeaterFieldSchema, groupFieldSchema, modalFieldSchema, numberFieldSchema, tabDefinitionSchema, tabGroupFieldSchema, presetOptionSchema, presetOrCustomFieldSchema, contentTypeSelectFieldSchema, entryPickerFieldSchema, _fieldSchemaInternal, fieldSchema, slotSchema, typographyTokens, colorTokens, spacingTokens, radiusTokens, styleTokenSchema, behaviourSchema, quickFieldPrioritySchema, previewCustomizeManifestCurationSchema, blockCategoryEnum;
1283
1438
  var init_schema2 = __esm({
1284
1439
  "../blocks/src/system/manifest/schema.ts"() {
1285
1440
  init_src2();
@@ -1337,6 +1492,21 @@ var init_schema2 = __esm({
1337
1492
  kind: z.literal("sdk")
1338
1493
  })
1339
1494
  ]);
1495
+ visibleWhenPredicateSchema = z.object({
1496
+ field: z.string().min(1),
1497
+ equals: z.any().optional(),
1498
+ notEquals: z.any().optional(),
1499
+ oneOf: z.array(z.any()).optional(),
1500
+ notIn: z.array(z.any()).optional(),
1501
+ minItems: z.number().int().nonnegative().optional(),
1502
+ maxItems: z.number().int().nonnegative().optional()
1503
+ });
1504
+ visibleWhenSchema = z.union([
1505
+ visibleWhenPredicateSchema,
1506
+ z.object({
1507
+ allOf: z.array(visibleWhenPredicateSchema).min(1)
1508
+ })
1509
+ ]);
1340
1510
  uiSchema = z.object({
1341
1511
  widget: z.string().optional(),
1342
1512
  // Container/widget presets (used by Group/Repeater widgets themselves, not for widget selection)
@@ -1369,13 +1539,7 @@ var init_schema2 = __esm({
1369
1539
  showValue: z.boolean().optional(),
1370
1540
  pattern: z.string().optional(),
1371
1541
  placeholder: z.string().optional(),
1372
- visibleWhen: z.object({
1373
- field: z.string().min(1),
1374
- equals: z.any().optional(),
1375
- notEquals: z.any().optional(),
1376
- oneOf: z.array(z.any()).optional(),
1377
- notIn: z.array(z.any()).optional()
1378
- }).optional(),
1542
+ visibleWhen: visibleWhenSchema.optional(),
1379
1543
  // Modal configuration for modal and group fields
1380
1544
  modalConfig: z.object({
1381
1545
  buttonLabel: z.string().optional(),
@@ -2106,6 +2270,7 @@ var init_types2 = __esm({
2106
2270
  ];
2107
2271
  eyebrowTreatmentValues = [
2108
2272
  "plain",
2273
+ "accent",
2109
2274
  "pill",
2110
2275
  "accent-pill",
2111
2276
  "pill-bounce",
@@ -5735,6 +5900,101 @@ var init_joy_stamp = __esm({
5735
5900
  }
5736
5901
  });
5737
5902
 
5903
+ // ../theme-core/src/buttons/personalities/ornate-ritual.ts
5904
+ var ornateRitual;
5905
+ var init_ornate_ritual = __esm({
5906
+ "../theme-core/src/buttons/personalities/ornate-ritual.ts"() {
5907
+ init_types5();
5908
+ ornateRitual = defineButtonPersonality({
5909
+ id: "ornate-ritual",
5910
+ name: "Ornate Ritual",
5911
+ description: "Ceremonial framed buttons with jewel-toned fills and quiet color-change hover states.",
5912
+ tags: { tone: "classic", energy: "vibrant", motion: "subtle", era: "organic" },
5913
+ buttonSystem: {
5914
+ global: {
5915
+ cornerStyle: "rounded",
5916
+ shadow: "none",
5917
+ textTransform: "uppercase",
5918
+ fontWeight: 600,
5919
+ borderWidth: 1,
5920
+ hoverTransform: "none",
5921
+ hoverColor: "none",
5922
+ letterSpacing: "loose"
5923
+ },
5924
+ sizes: {
5925
+ sm: { padding: "0.5625rem 1.25rem", fontSize: "text-xs" },
5926
+ md: { padding: "0.75rem 1.75rem", fontSize: "text-xs" },
5927
+ lg: { padding: "0.875rem 2.25rem", fontSize: "text-sm" },
5928
+ xl: { padding: "1rem 2.75rem", fontSize: "text-base" }
5929
+ },
5930
+ variants: [
5931
+ {
5932
+ id: "primary",
5933
+ name: "Primary",
5934
+ enabled: true,
5935
+ priority: 1,
5936
+ background: { type: "solid", colorToken: "primary" },
5937
+ textColorToken: "primaryForeground",
5938
+ borderRadius: "rounded-md",
5939
+ border: { widthClass: "border", colorToken: "primary" },
5940
+ shadow: { elevation: "none", softness: null, position: "bottom" },
5941
+ effects: {
5942
+ hover: [{ effectId: "background-on-hover", options: { colorToken: "primary-100" } }],
5943
+ active: [{ effectId: "scale-down", options: { scale: "0.98" } }]
5944
+ }
5945
+ },
5946
+ {
5947
+ id: "secondary",
5948
+ name: "Secondary",
5949
+ enabled: true,
5950
+ priority: 2,
5951
+ background: { type: "solid", colorToken: "secondary" },
5952
+ textColorToken: "primaryForeground",
5953
+ borderRadius: "rounded-md",
5954
+ border: { widthClass: "border", colorToken: "primary" },
5955
+ shadow: { elevation: "none", softness: null, position: "bottom" },
5956
+ effects: {
5957
+ hover: [{ effectId: "background-on-hover", options: { colorToken: "surface" } }]
5958
+ }
5959
+ },
5960
+ {
5961
+ id: "outline",
5962
+ name: "Outline",
5963
+ enabled: true,
5964
+ priority: 3,
5965
+ background: { type: "transparent" },
5966
+ textColorToken: "primary",
5967
+ borderRadius: "rounded-md",
5968
+ border: { widthClass: "border", colorToken: "primary" },
5969
+ shadow: { elevation: "none", softness: null, position: "bottom" },
5970
+ effects: {
5971
+ hover: [{ effectId: "background-on-hover", options: { colorToken: "muted" } }]
5972
+ }
5973
+ },
5974
+ {
5975
+ id: "ghost",
5976
+ name: "Ghost",
5977
+ enabled: true,
5978
+ priority: 3,
5979
+ background: { type: "transparent" },
5980
+ textColorToken: "accent",
5981
+ borderRadius: "rounded-none",
5982
+ sizes: {
5983
+ sm: { padding: "0.375rem 0", fontSize: "text-xs" },
5984
+ md: { padding: "0.5rem 0", fontSize: "text-sm" },
5985
+ lg: { padding: "0.625rem 0", fontSize: "text-base" },
5986
+ xl: { padding: "0.75rem 0", fontSize: "text-lg" }
5987
+ },
5988
+ effects: {
5989
+ base: [{ effectId: "border-bottom-grow", options: { height: 1, colorToken: "accent", origin: "left" } }]
5990
+ }
5991
+ }
5992
+ ]
5993
+ }
5994
+ });
5995
+ }
5996
+ });
5997
+
5738
5998
  // ../theme-core/src/buttons/personalities/pebble.ts
5739
5999
  var pebble;
5740
6000
  var init_pebble = __esm({
@@ -6029,6 +6289,7 @@ var init_personalities = __esm({
6029
6289
  init_editorial_link();
6030
6290
  init_ink_stamp();
6031
6291
  init_joy_stamp();
6292
+ init_ornate_ritual();
6032
6293
  init_pebble();
6033
6294
  init_showtime_pill();
6034
6295
  init_soft_pill();
@@ -6042,7 +6303,8 @@ var init_personalities = __esm({
6042
6303
  inkStamp,
6043
6304
  brushedWash,
6044
6305
  showtimePill,
6045
- joyStamp
6306
+ joyStamp,
6307
+ ornateRitual
6046
6308
  ];
6047
6309
  personalitiesById = new Map(
6048
6310
  buttonPersonalities.map((p) => [p.id, p])
@@ -6776,7 +7038,7 @@ function rgbColorValue(token) {
6776
7038
  if (alpha === void 0) {
6777
7039
  return `rgb(var(${cssVar}))`;
6778
7040
  }
6779
- return `rgba(var(${cssVar}), ${alpha})`;
7041
+ return `rgb(var(${cssVar}) / ${alpha})`;
6780
7042
  }
6781
7043
  function backgroundColorStyle(token) {
6782
7044
  return { backgroundColor: rgbColorValue(token) };
@@ -7920,7 +8182,7 @@ var init_warm_neutral = __esm({
7920
8182
  });
7921
8183
 
7922
8184
  // ../theme-core/src/palette/variants/warm-dark.ts
7923
- var warmDarkEmber;
8185
+ var warmDarkEmber, warmDarkKirtanGold;
7924
8186
  var init_warm_dark = __esm({
7925
8187
  "../theme-core/src/palette/variants/warm-dark.ts"() {
7926
8188
  init_types12();
@@ -7946,6 +8208,28 @@ var init_warm_dark = __esm({
7946
8208
  { name: "border", hex: "#894e31" }
7947
8209
  ]
7948
8210
  });
8211
+ warmDarkKirtanGold = definePaletteVariant({
8212
+ id: "warm-dark-kirtan-gold",
8213
+ name: "Warm Dark \u2014 Kirtan Gold",
8214
+ description: "Deep plum ground with pale gold primary, rose accent, and soft devotional text.",
8215
+ tags: { tone: "bold", energy: "calm", era: "editorial" },
8216
+ mode: "dark",
8217
+ colors: [
8218
+ { name: "primary", hex: "#ffcdb2" },
8219
+ { name: "secondary", hex: "#b5838d" },
8220
+ { name: "accent", hex: "#e5989b" },
8221
+ { name: "success", hex: "#8fbf8f" },
8222
+ { name: "warning", hex: "#f2b86b" },
8223
+ { name: "destructive", hex: "#d96b6b" },
8224
+ { name: "background", hex: "#403944" },
8225
+ { name: "surface", hex: "#403944" },
8226
+ { name: "surfaceAlt", hex: "#372f3b" },
8227
+ { name: "muted", hex: "#4d4550" },
8228
+ { name: "text", hex: "#e6d2d5" },
8229
+ { name: "primaryForeground", hex: "#403944" },
8230
+ { name: "border", hex: "#8d747a" }
8231
+ ]
8232
+ });
7949
8233
  }
7950
8234
  });
7951
8235
 
@@ -7983,7 +8267,8 @@ var init_variants = __esm({
7983
8267
  softNaturalWatercolor,
7984
8268
  softNaturalLilac,
7985
8269
  // Warm-dark family (dark mode)
7986
- warmDarkEmber
8270
+ warmDarkEmber,
8271
+ warmDarkKirtanGold
7987
8272
  ];
7988
8273
  paletteVariantsById = new Map(
7989
8274
  paletteVariants.map((v) => [v.id, v])
@@ -9596,8 +9881,69 @@ var init_headerLooks = __esm({
9596
9881
  function asFooterLookId(value) {
9597
9882
  return value;
9598
9883
  }
9884
+ function asFooterLayoutId(value) {
9885
+ return value;
9886
+ }
9887
+ function asFooterStyleId(value) {
9888
+ return value;
9889
+ }
9890
+ function identityQuietFooter(theme) {
9891
+ return {
9892
+ ...theme.footer,
9893
+ variant: "simple",
9894
+ maxWidth: "container",
9895
+ background: {
9896
+ type: "color",
9897
+ color: "surface"
9898
+ },
9899
+ navStyle: "minimal",
9900
+ navWeight: "regular",
9901
+ navColor: "text",
9902
+ navLinkStyle: {
9903
+ typography: "body",
9904
+ fontWeight: "regular",
9905
+ textTransform: "none",
9906
+ italic: false,
9907
+ colorToken: "text",
9908
+ hoverColorToken: "primary",
9909
+ padding: "none",
9910
+ borderRadius: "none"
9911
+ },
9912
+ navLayout: {
9913
+ layout: "inline-wrap",
9914
+ align: "start",
9915
+ gapX: "default",
9916
+ gapY: "tight"
9917
+ },
9918
+ logo: {
9919
+ showLogo: true,
9920
+ showLogoText: true,
9921
+ placement: "left",
9922
+ size: "sm",
9923
+ align: "start"
9924
+ },
9925
+ bottomBar: {
9926
+ enabled: false,
9927
+ fullBleed: false,
9928
+ textAlign: "left",
9929
+ paddingX: "default",
9930
+ paddingY: "compact",
9931
+ borderTop: {
9932
+ width: "none"
9933
+ }
9934
+ }
9935
+ };
9936
+ }
9599
9937
  function mutedGroundingFooter(theme) {
9600
- return theme.footer;
9938
+ return {
9939
+ ...identityQuietFooter(theme),
9940
+ background: theme.footer.background,
9941
+ navStyle: theme.footer.navStyle,
9942
+ navColor: theme.footer.navColor,
9943
+ navWeight: theme.footer.navWeight,
9944
+ navLinkStyle: theme.footer.navLinkStyle,
9945
+ bottomTextLinkStyle: theme.footer.bottomTextLinkStyle
9946
+ };
9601
9947
  }
9602
9948
  function brandTwoBandFooter(theme) {
9603
9949
  return {
@@ -9702,6 +10048,53 @@ function centeredCalmFooter(theme) {
9702
10048
  }
9703
10049
  };
9704
10050
  }
10051
+ function splitEditorialFooter(theme) {
10052
+ return {
10053
+ ...theme.footer,
10054
+ variant: "split",
10055
+ maxWidth: "container",
10056
+ background: {
10057
+ type: "color",
10058
+ color: "surface"
10059
+ },
10060
+ navStyle: "minimal",
10061
+ navWeight: "regular",
10062
+ navColor: "text",
10063
+ navLinkStyle: {
10064
+ typography: "body",
10065
+ fontWeight: "regular",
10066
+ textTransform: "none",
10067
+ italic: false,
10068
+ colorToken: "text",
10069
+ hoverColorToken: "primary",
10070
+ padding: "none",
10071
+ borderRadius: "none"
10072
+ },
10073
+ navLayout: {
10074
+ layout: "inline-wrap",
10075
+ align: "start",
10076
+ gapX: "relaxed",
10077
+ gapY: "tight"
10078
+ },
10079
+ logo: {
10080
+ showLogo: true,
10081
+ showLogoText: true,
10082
+ placement: "right",
10083
+ size: "sm",
10084
+ align: "end"
10085
+ },
10086
+ bottomBar: {
10087
+ enabled: true,
10088
+ fullBleed: false,
10089
+ textAlign: "left",
10090
+ paddingX: "default",
10091
+ paddingY: "compact",
10092
+ borderTop: {
10093
+ width: "thin"
10094
+ }
10095
+ }
10096
+ };
10097
+ }
9705
10098
  function editorialColumnsFooter(theme) {
9706
10099
  return {
9707
10100
  ...theme.footer,
@@ -9746,31 +10139,108 @@ function editorialColumnsFooter(theme) {
9746
10139
  function findFooterLook(id) {
9747
10140
  return footerLooksById.get(id);
9748
10141
  }
9749
- var footerLookCatalog, footerLooksById;
10142
+ var footerLayoutCatalog, footerStyleCatalog, footerLookCatalog, footerLooksById;
9750
10143
  var init_footerLooks = __esm({
9751
10144
  "../theme-core/src/site-styles/footerLooks.ts"() {
9752
10145
  init_customizableSurfaces();
9753
10146
  init_types2();
10147
+ footerLayoutCatalog = defineExactCatalog()([
10148
+ {
10149
+ id: asFooterLayoutId("identity"),
10150
+ label: "Identity",
10151
+ description: "Logo, site text, address, and legal copy without relying on footer navigation."
10152
+ },
10153
+ {
10154
+ id: asFooterLayoutId("centered"),
10155
+ label: "Centered",
10156
+ description: "A calm centered stack for identity, short copy, and optional compact navigation.",
10157
+ maxRecommendedNavDensity: "sparse"
10158
+ },
10159
+ {
10160
+ id: asFooterLayoutId("split"),
10161
+ label: "Split",
10162
+ description: "Navigation and brand signoff separated into a wider split footer.",
10163
+ requiresFooterNav: true,
10164
+ maxRecommendedNavDensity: "balanced"
10165
+ },
10166
+ {
10167
+ id: asFooterLayoutId("columns"),
10168
+ label: "Columns",
10169
+ description: "Grouped footer navigation columns with a supporting bottom line.",
10170
+ requiresFooterNav: true,
10171
+ requiresFooterNavGroups: true
10172
+ }
10173
+ ]);
10174
+ footerStyleCatalog = defineExactCatalog()([
10175
+ {
10176
+ id: asFooterStyleId("quiet"),
10177
+ label: "Quiet",
10178
+ description: "Lightweight, practical footer treatment."
10179
+ },
10180
+ {
10181
+ id: asFooterStyleId("calm"),
10182
+ label: "Calm",
10183
+ description: "Soft centered treatment with restrained dividers."
10184
+ },
10185
+ {
10186
+ id: asFooterStyleId("editorial"),
10187
+ label: "Editorial",
10188
+ description: "Text-forward treatment with fine-line structure."
10189
+ },
10190
+ {
10191
+ id: asFooterStyleId("brand-band"),
10192
+ label: "Brand band",
10193
+ description: "High-contrast brand treatment with a stronger bottom bar."
10194
+ }
10195
+ ]);
10196
+ new Map(
10197
+ footerLayoutCatalog.map((layout) => [layout.id, layout])
10198
+ );
10199
+ new Map(
10200
+ footerStyleCatalog.map((style) => [style.id, style])
10201
+ );
9754
10202
  footerLookCatalog = defineExactCatalog()([
10203
+ {
10204
+ id: asFooterLookId("footer-identity-quiet"),
10205
+ label: "Identity footer",
10206
+ layoutId: asFooterLayoutId("identity"),
10207
+ styleId: asFooterStyleId("quiet"),
10208
+ compile: identityQuietFooter
10209
+ },
9755
10210
  {
9756
10211
  id: asFooterLookId("footer-muted-grounding"),
9757
10212
  label: "Muted grounding footer",
10213
+ layoutId: asFooterLayoutId("identity"),
10214
+ styleId: asFooterStyleId("quiet"),
10215
+ hiddenFromLayoutStyleControls: true,
9758
10216
  compile: mutedGroundingFooter
9759
10217
  },
9760
10218
  {
9761
10219
  id: asFooterLookId("footer-centered-calm"),
9762
10220
  label: "Centered calm footer",
10221
+ layoutId: asFooterLayoutId("centered"),
10222
+ styleId: asFooterStyleId("calm"),
9763
10223
  compile: centeredCalmFooter
9764
10224
  },
10225
+ {
10226
+ id: asFooterLookId("footer-split-editorial"),
10227
+ label: "Split editorial footer",
10228
+ layoutId: asFooterLayoutId("split"),
10229
+ styleId: asFooterStyleId("editorial"),
10230
+ compile: splitEditorialFooter
10231
+ },
9765
10232
  {
9766
10233
  id: asFooterLookId("footer-editorial-columns"),
9767
10234
  label: "Editorial columns footer",
10235
+ layoutId: asFooterLayoutId("columns"),
10236
+ styleId: asFooterStyleId("editorial"),
9768
10237
  compile: editorialColumnsFooter
9769
10238
  },
9770
10239
  {
9771
10240
  id: asFooterLookId("site-footer-brand-two-band"),
9772
10241
  label: "Two-band brand footer",
9773
- maxRecommendedNavDensity: "balanced",
10242
+ layoutId: asFooterLayoutId("split"),
10243
+ styleId: asFooterStyleId("brand-band"),
9774
10244
  allowedContentPresence: ["default-footer", "default-and-blocks"],
9775
10245
  compile: brandTwoBandFooter
9776
10246
  }
@@ -9861,7 +10331,7 @@ function defineTypographyPreset(preset2) {
9861
10331
  function findTypographyPreset(id) {
9862
10332
  return typographyPresetsById.get(id);
9863
10333
  }
9864
- var bodyReadablePolicy, headingFlexiblePolicy, displayHeadingPolicy, modernSansTypography, warmRoundedTypography, editorialSerifTypography, classicSerifTypography, luxeContrastTypography, boldDisplayTypography, originalJoyTypography, typographyPresets, typographyPresetsById;
10334
+ var bodyReadablePolicy, headingFlexiblePolicy, displayHeadingPolicy, modernSansTypography, warmRoundedTypography, editorialSerifTypography, classicSerifTypography, luxeContrastTypography, kirtanOrnateTypography, boldDisplayTypography, originalJoyTypography, typographyPresets, typographyPresetsById;
9865
10335
  var init_typographyPresets = __esm({
9866
10336
  "../theme-core/src/site-styles/typographyPresets.ts"() {
9867
10337
  bodyReadablePolicy = {
@@ -9993,6 +10463,30 @@ var init_typographyPresets = __esm({
9993
10463
  },
9994
10464
  scale: "spacious"
9995
10465
  };
10466
+ kirtanOrnateTypography = {
10467
+ body: {
10468
+ family: "Jost, system-ui, sans-serif",
10469
+ size: "md",
10470
+ weight: "regular",
10471
+ lineHeight: "relaxed",
10472
+ letterSpacing: "normal"
10473
+ },
10474
+ headings: {
10475
+ default: {
10476
+ family: "Marcellus, Georgia, serif",
10477
+ weight: "regular",
10478
+ lineHeight: "normal",
10479
+ letterSpacing: "normal",
10480
+ colorToken: "primary",
10481
+ italic: null,
10482
+ case: null
10483
+ },
10484
+ h1: { size: "2xl", weight: "regular", lineHeight: "normal", letterSpacing: "normal", italic: null },
10485
+ h2: { size: "xl", weight: "regular", lineHeight: "normal", letterSpacing: "normal", italic: null },
10486
+ h3: { size: "md", weight: "regular", lineHeight: "relaxed", letterSpacing: "normal", italic: null }
10487
+ },
10488
+ scale: "spacious"
10489
+ };
9996
10490
  boldDisplayTypography = {
9997
10491
  body: {
9998
10492
  family: "Manrope, system-ui, sans-serif",
@@ -10027,16 +10521,16 @@ var init_typographyPresets = __esm({
10027
10521
  },
10028
10522
  headings: {
10029
10523
  default: {
10030
- family: "Bricolage Grotesque, system-ui, sans-serif",
10031
- weight: "bold",
10524
+ family: "Lobster, cursive",
10525
+ weight: "regular",
10032
10526
  lineHeight: "normal",
10033
- letterSpacing: "tight",
10527
+ letterSpacing: "normal",
10034
10528
  italic: null,
10035
10529
  case: null
10036
10530
  },
10037
- h1: { size: "2xl", weight: "bold", lineHeight: "normal", letterSpacing: "tight", italic: null },
10038
- h2: { size: "xl", weight: "bold", lineHeight: "normal", letterSpacing: "tight", italic: null },
10039
- h3: { size: "lg", weight: "bold", lineHeight: "normal", letterSpacing: "tight", italic: null }
10531
+ h1: { size: "2xl", weight: "regular", lineHeight: "normal", letterSpacing: "normal", italic: null },
10532
+ h2: { size: "xl", weight: "regular", lineHeight: "normal", letterSpacing: "normal", italic: null },
10533
+ h3: { size: "lg", weight: "regular", lineHeight: "normal", letterSpacing: "normal", italic: null }
10040
10534
  },
10041
10535
  scale: "balanced"
10042
10536
  };
@@ -10101,6 +10595,32 @@ var init_typographyPresets = __esm({
10101
10595
  slotPolicies: { body: bodyReadablePolicy, heading: displayHeadingPolicy },
10102
10596
  typography: luxeContrastTypography
10103
10597
  }),
10598
+ defineTypographyPreset({
10599
+ id: "typography-preset:kirtan-ornate",
10600
+ name: "Kirtan Ornate",
10601
+ description: "Marcellus devotional headings over a refined Jost body, matching dark ceremonial layouts.",
10602
+ defaultFonts: { body: "Jost, system-ui, sans-serif", heading: "Marcellus, Georgia, serif" },
10603
+ recommendedFonts: {
10604
+ body: ["Jost", "Manrope", "Inter"],
10605
+ heading: ["Marcellus", "Cormorant Garamond", "Playfair Display"]
10606
+ },
10607
+ slotPolicies: { body: bodyReadablePolicy, heading: displayHeadingPolicy },
10608
+ typography: kirtanOrnateTypography,
10609
+ heroTypography: {
10610
+ headlineSize: "6xl",
10611
+ headlineLineHeight: "normal",
10612
+ subheadlineSize: "xl",
10613
+ subheadlineLineHeight: "relaxed",
10614
+ microHeadlineSize: "5xl",
10615
+ microHeadlineLineHeight: "normal",
10616
+ microSubheadlineSize: "lg",
10617
+ microSubheadlineLineHeight: "relaxed",
10618
+ responsive: {
10619
+ tablet: { headlineSize: "5xl" },
10620
+ mobile: { headlineSize: "4xl", subheadlineSize: "lg" }
10621
+ }
10622
+ }
10623
+ }),
10104
10624
  defineTypographyPreset({
10105
10625
  id: "typography-preset:bold-display",
10106
10626
  name: "Bold Display",
@@ -10130,11 +10650,11 @@ var init_typographyPresets = __esm({
10130
10650
  defineTypographyPreset({
10131
10651
  id: "typography-preset:original-joy",
10132
10652
  name: "Original Joy",
10133
- description: "Bold Bricolage Grotesque display headings over a clean DM Sans body, editorial and warm.",
10134
- defaultFonts: { body: "DM Sans, system-ui, sans-serif", heading: "Bricolage Grotesque, system-ui, sans-serif" },
10653
+ description: "Lobster display headings over a clean DM Sans body, expressive and warm.",
10654
+ defaultFonts: { body: "DM Sans, system-ui, sans-serif", heading: "Lobster, cursive" },
10135
10655
  recommendedFonts: {
10136
10656
  body: ["DM Sans", "Inter", "Manrope"],
10137
- heading: ["Bricolage Grotesque", "Space Grotesk", "Archivo"]
10657
+ heading: ["Lobster", "Bricolage Grotesque", "Space Grotesk"]
10138
10658
  },
10139
10659
  slotPolicies: { body: bodyReadablePolicy, heading: displayHeadingPolicy },
10140
10660
  typography: originalJoyTypography,
@@ -10159,6 +10679,228 @@ var init_typographyPresets = __esm({
10159
10679
  );
10160
10680
  }
10161
10681
  });
10682
+ function uniqueNonEmpty(values) {
10683
+ const uniqueValues = [...new Set(values)];
10684
+ const firstValue = uniqueValues[0];
10685
+ if (!firstValue) {
10686
+ throw new Error("Expected at least one Theme V2 design state option.");
10687
+ }
10688
+ return [firstValue, ...uniqueValues.slice(1)];
10689
+ }
10690
+ var themeV2DesignStateSchemaVersion, designResolutionPolicySchema, runtimeStyleFieldNameSchema, nonEmptyRuntimeStyleFieldNamesSchema, heroLegibilityStrategySchema, heroCompositionIntentSchema, heroTypographyScaleIntentSchema, sectionHeightIntentSchema, imageSurfaceTreatmentIntensitySchema, imageSurfaceMotionSchema, imageSurfaceTreatmentSchema, testimonialCardTreatmentSchema, tileTreatmentSchema, eventListTreatmentSchema, eyebrowTreatmentSchema, userPanelTreatments, userFlushTreatments, userFlushBleeds, contentFrameIntentSchema, blockDesignPlanSchema, styleAuthoritySchema, blockRuntimeStyleAuthoritySchema;
10691
+ var init_designState = __esm({
10692
+ "../theme-core/src/site-styles/designState.ts"() {
10693
+ init_sourceCatalogs();
10694
+ init_types2();
10695
+ init_schemaVersionedJson();
10696
+ init_rawStyleFields();
10697
+ init_rawStyleFields();
10698
+ themeV2DesignStateSchemaVersion = 1;
10699
+ designResolutionPolicySchema = z.enum(["generated", "user", "admin", "sdk"]);
10700
+ runtimeStyleFieldNameSchema = z.enum(themeV2RuntimeStyleFieldNames);
10701
+ nonEmptyRuntimeStyleFieldNamesSchema = z.array(runtimeStyleFieldNameSchema).min(1).transform((fields3) => [
10702
+ fields3[0],
10703
+ ...fields3.slice(1)
10704
+ ]);
10705
+ heroLegibilityStrategySchema = z.enum([
10706
+ "none",
10707
+ "scrim-gradient",
10708
+ "solid-panel"
10709
+ ]);
10710
+ heroCompositionIntentSchema = z.enum([
10711
+ "center",
10712
+ "bottom-left"
10713
+ ]);
10714
+ heroTypographyScaleIntentSchema = z.enum([
10715
+ "quiet",
10716
+ "editorial",
10717
+ "display",
10718
+ "poster"
10719
+ ]);
10720
+ sectionHeightIntentSchema = z.enum([
10721
+ "default",
10722
+ "banner",
10723
+ "hero",
10724
+ "immersive"
10725
+ ]);
10726
+ imageSurfaceTreatmentIntensitySchema = z.enum(["soft", "balanced", "strong"]);
10727
+ imageSurfaceMotionSchema = z.enum(["static", "fixed-frame"]);
10728
+ imageSurfaceTreatmentSchema = z.discriminatedUnion("kind", [
10729
+ z.object({ kind: z.literal("none") }).strict(),
10730
+ z.object({
10731
+ kind: z.literal("brand-scrim"),
10732
+ token: z.enum(["primary", "secondary", "accent"]),
10733
+ intensity: imageSurfaceTreatmentIntensitySchema.optional()
10734
+ }).strict(),
10735
+ z.object({
10736
+ kind: z.literal("brand-wash"),
10737
+ token: z.enum(["primary", "secondary", "accent"]),
10738
+ intensity: imageSurfaceTreatmentIntensitySchema.optional()
10739
+ }).strict(),
10740
+ z.object({
10741
+ kind: z.literal("neutral-scrim"),
10742
+ intensity: imageSurfaceTreatmentIntensitySchema.optional()
10743
+ }).strict(),
10744
+ z.object({
10745
+ kind: z.literal("neutral-wash"),
10746
+ intensity: imageSurfaceTreatmentIntensitySchema.optional()
10747
+ }).strict(),
10748
+ z.object({
10749
+ kind: z.literal("solid-panel"),
10750
+ intensity: imageSurfaceTreatmentIntensitySchema.optional()
10751
+ }).strict()
10752
+ ]);
10753
+ testimonialCardTreatmentSchema = z.enum(["default", "accent-quote"]);
10754
+ tileTreatmentSchema = z.enum(tileTreatmentValues);
10755
+ eventListTreatmentSchema = z.enum(eventListTreatmentValues);
10756
+ eyebrowTreatmentSchema = z.enum(eyebrowTreatmentValues);
10757
+ userPanelTreatments = uniqueNonEmpty(
10758
+ userDesignOptionCatalog.contentFrames.filter((frame) => frame.kind === "panel").map((frame) => frame.treatment)
10759
+ );
10760
+ userFlushTreatments = uniqueNonEmpty(
10761
+ userDesignOptionCatalog.contentFrames.filter((frame) => frame.kind === "flush-panel").map((frame) => frame.treatment)
10762
+ );
10763
+ userFlushBleeds = uniqueNonEmpty(
10764
+ userDesignOptionCatalog.contentFrames.filter((frame) => frame.kind === "flush-panel").map((frame) => frame.bleed)
10765
+ );
10766
+ contentFrameIntentSchema = z.discriminatedUnion("kind", [
10767
+ z.object({ kind: z.literal("plain") }).strict(),
10768
+ z.object({
10769
+ kind: z.literal("panel"),
10770
+ treatment: z.enum(userPanelTreatments)
10771
+ }).strict(),
10772
+ z.object({
10773
+ kind: z.literal("flush-panel"),
10774
+ treatment: z.enum(userFlushTreatments),
10775
+ bleed: z.enum(userFlushBleeds)
10776
+ }).strict()
10777
+ ]);
10778
+ blockDesignPlanSchema = z.object({
10779
+ blockId: z.string().min(1).transform(asDesignBlockId),
10780
+ blockKind: z.string().min(1),
10781
+ purpose: z.string().min(1),
10782
+ sectionSurface: z.enum(userDesignOptionCatalog.sectionSurfaces),
10783
+ contentFrame: contentFrameIntentSchema,
10784
+ itemSurface: z.enum(userDesignOptionCatalog.itemSurfaces),
10785
+ transitionAfter: z.enum(userDesignOptionCatalog.transitions),
10786
+ emphasis: z.enum(userDesignOptionCatalog.emphases),
10787
+ sectionHeight: sectionHeightIntentSchema.optional(),
10788
+ heroLegibility: heroLegibilityStrategySchema.optional(),
10789
+ heroComposition: heroCompositionIntentSchema.optional(),
10790
+ heroTypographyScale: heroTypographyScaleIntentSchema.optional(),
10791
+ imageSurfaceTreatment: imageSurfaceTreatmentSchema.optional(),
10792
+ imageSurfaceMotion: imageSurfaceMotionSchema.optional(),
10793
+ testimonialCardTreatment: testimonialCardTreatmentSchema.optional(),
10794
+ tileTreatment: tileTreatmentSchema.optional(),
10795
+ eventListTreatment: eventListTreatmentSchema.optional(),
10796
+ eyebrowTreatment: eyebrowTreatmentSchema.optional()
10797
+ }).strict();
10798
+ styleAuthoritySchema = z.discriminatedUnion("kind", [
10799
+ z.object({
10800
+ kind: z.literal("theme-v2"),
10801
+ source: designResolutionPolicySchema,
10802
+ siteStyleId: z.string().min(1).transform(asSiteStyleId),
10803
+ templateId: z.string().min(1).transform(asDesignSystemTemplateId),
10804
+ templateVersion: z.number().int().nonnegative(),
10805
+ resolverVersion: z.number().int().nonnegative()
10806
+ }).strict(),
10807
+ z.object({
10808
+ kind: z.literal("legacy-raw"),
10809
+ reason: z.enum(["pre-theme-v2", "manual-runtime-fields"])
10810
+ }).strict(),
10811
+ z.object({
10812
+ kind: z.literal("advanced-detached"),
10813
+ reason: z.literal("detached-custom-runtime-fields")
10814
+ }).strict()
10815
+ ]);
10816
+ blockRuntimeStyleAuthoritySchema = z.object({
10817
+ unit: z.literal("block-runtime-fields"),
10818
+ blockId: z.string().min(1).transform(asDesignBlockId),
10819
+ fields: nonEmptyRuntimeStyleFieldNamesSchema,
10820
+ authority: styleAuthoritySchema
10821
+ }).strict();
10822
+ z.object({
10823
+ schemaVersion: z.literal(themeV2DesignStateSchemaVersion),
10824
+ siteStyleId: z.string().min(1).transform(asSiteStyleId),
10825
+ templateId: z.string().min(1).transform(asDesignSystemTemplateId),
10826
+ templateVersion: z.number().int().nonnegative(),
10827
+ resolverVersion: z.number().int().nonnegative(),
10828
+ rhythmPresetId: z.string().min(1),
10829
+ blocks: z.array(blockDesignPlanSchema),
10830
+ styleAuthorities: z.array(blockRuntimeStyleAuthoritySchema)
10831
+ }).strict();
10832
+ }
10833
+ });
10834
+
10835
+ // ../theme-core/src/site-styles/runtimeCompiler.ts
10836
+ function defineDesignRuntimeRules(rules) {
10837
+ return rules;
10838
+ }
10839
+ function uniformSectionForeground(token) {
10840
+ return {
10841
+ textColor: token,
10842
+ headingColor: token,
10843
+ linkColor: token,
10844
+ supportingColor: token
10845
+ };
10846
+ }
10847
+ var defaultDesignRuntimeRules;
10848
+ var init_runtimeCompiler = __esm({
10849
+ "../theme-core/src/site-styles/runtimeCompiler.ts"() {
10850
+ init_schema3();
10851
+ init_modern_minimal();
10852
+ init_expandPalette();
10853
+ init_personalities();
10854
+ init_variants();
10855
+ init_designState();
10856
+ init_types2();
10857
+ init_accessibleSurfaces();
10858
+ defaultDesignRuntimeRules = defineDesignRuntimeRules({
10859
+ sectionSurfaces: {
10860
+ base: {},
10861
+ "muted-band": {
10862
+ background: {
10863
+ type: "color",
10864
+ color: "muted"
10865
+ }
10866
+ },
10867
+ "accent-band": {
10868
+ background: {
10869
+ type: "color",
10870
+ color: "primary"
10871
+ }
10872
+ },
10873
+ "brand-depth-band": {
10874
+ background: {
10875
+ type: "color",
10876
+ color: "primary-800"
10877
+ }
10878
+ },
10879
+ "hero-image": {
10880
+ background: {
10881
+ type: "image",
10882
+ opacity: 1,
10883
+ position: "center center",
10884
+ ...uniformSectionForeground("text")
10885
+ }
10886
+ }
10887
+ },
10888
+ heroLegibility: {
10889
+ "scrim-gradient": {
10890
+ type: "gradient",
10891
+ gradient: "linear-gradient(180deg, rgba(255,255,255,0.38) 0%, rgba(244,241,234,0.62) 90%)",
10892
+ opacity: 1
10893
+ },
10894
+ "solid-panel": {
10895
+ type: "color",
10896
+ color: "surface",
10897
+ opacity: 0.88
10898
+ }
10899
+ },
10900
+ transitionClassName: (transition, fromSurface, toSurface) => transition === "none" ? null : `site-style-transition-${transition}-from-${fromSurface}-to-${toSurface}`
10901
+ });
10902
+ }
10903
+ });
10162
10904
 
10163
10905
  // ../theme-core/src/site-styles/curatedSiteStyles.ts
10164
10906
  function uniqueContentFrameKinds() {
@@ -10217,6 +10959,7 @@ function defineCuratedSiteStyle(input) {
10217
10959
  // clean/minimal styles default to none.
10218
10960
  headingDecoration: input.headingDecoration ?? noHeadingDecoration,
10219
10961
  ...input.themeOverrides ? { themeOverrides: input.themeOverrides } : {},
10962
+ ...input.designRuntimeRules ? { designRuntimeRules: input.designRuntimeRules } : {},
10220
10963
  ...input.defaultBlockVariants ? { defaultBlockVariants: input.defaultBlockVariants } : {},
10221
10964
  recommendedAppearancePresetIds: (input.recommendedAppearancePresetIds ?? []).map(asAppearancePresetId),
10222
10965
  defaultHeaderSelection: input.defaultHeaderSelection ? {
@@ -10401,7 +11144,7 @@ function defaultTypographyPresetChoicesForRecipe(recipe) {
10401
11144
  function getCuratedSiteStyle(id) {
10402
11145
  return curatedSiteStylesById.get(id) ?? null;
10403
11146
  }
10404
- var SOFT_EARTH_SITE_STYLE_ID_VALUE, SOFT_EARTH_SITE_STYLE_ID, curatedSiteStyleIdValues, quietBudget, balancedBudget, expressiveBudget, expressiveUnderlineInputs, generatedContentFrameKinds, curatedSiteStyles, curatedSiteStylesById;
11147
+ var SOFT_EARTH_SITE_STYLE_ID_VALUE, SOFT_EARTH_SITE_STYLE_ID, curatedSiteStyleIdValues, quietBudget, balancedBudget, expressiveBudget, kirtanOrnateDesignRuntimeRules, expressiveUnderlineInputs, ornateDarkInputs, generatedContentFrameKinds, curatedSiteStyles, curatedSiteStylesById;
10405
11148
  var init_curatedSiteStyles = __esm({
10406
11149
  "../theme-core/src/site-styles/curatedSiteStyles.ts"() {
10407
11150
  init_personalities();
@@ -10415,6 +11158,7 @@ var init_curatedSiteStyles = __esm({
10415
11158
  init_sourceCatalogs();
10416
11159
  init_types2();
10417
11160
  init_typographyPresets();
11161
+ init_runtimeCompiler();
10418
11162
  SOFT_EARTH_SITE_STYLE_ID_VALUE = "site-style:soft-earth";
10419
11163
  SOFT_EARTH_SITE_STYLE_ID = asSiteStyleId(SOFT_EARTH_SITE_STYLE_ID_VALUE);
10420
11164
  curatedSiteStyleIdValues = [
@@ -10432,6 +11176,7 @@ var init_curatedSiteStyles = __esm({
10432
11176
  SOFT_EARTH_SITE_STYLE_ID_VALUE,
10433
11177
  "site-style:bold-launch",
10434
11178
  "site-style:south-west-twerk-school",
11179
+ "site-style:kirtan-ornate",
10435
11180
  "site-style:original-joy"
10436
11181
  ];
10437
11182
  quietBudget = {
@@ -10458,6 +11203,50 @@ var init_curatedSiteStyles = __esm({
10458
11203
  mediaDensity: "high",
10459
11204
  decorativeRepetition: "medium"
10460
11205
  };
11206
+ kirtanOrnateDesignRuntimeRules = defineDesignRuntimeRules({
11207
+ ...defaultDesignRuntimeRules,
11208
+ defaultEyebrowTreatment: "accent",
11209
+ sectionSurfaces: {
11210
+ ...defaultDesignRuntimeRules.sectionSurfaces,
11211
+ "muted-band": {
11212
+ background: {
11213
+ type: "color",
11214
+ color: "muted"
11215
+ },
11216
+ foreground: {
11217
+ textColor: "text",
11218
+ headingColor: "primary",
11219
+ linkColor: "primary",
11220
+ supportingColor: "text"
11221
+ }
11222
+ },
11223
+ "brand-depth-band": {
11224
+ background: {
11225
+ type: "color",
11226
+ color: "primary-800"
11227
+ },
11228
+ foreground: {
11229
+ textColor: "text",
11230
+ headingColor: "primary",
11231
+ linkColor: "primary",
11232
+ supportingColor: "text"
11233
+ }
11234
+ },
11235
+ "hero-image": {
11236
+ background: {
11237
+ type: "image",
11238
+ opacity: 1,
11239
+ position: "center center"
11240
+ },
11241
+ foreground: {
11242
+ textColor: "text",
11243
+ headingColor: "primary",
11244
+ linkColor: "primary",
11245
+ supportingColor: "text"
11246
+ }
11247
+ }
11248
+ }
11249
+ });
10461
11250
  expressiveUnderlineInputs = {
10462
11251
  base: {
10463
11252
  background: { type: "transparent" },
@@ -10495,6 +11284,43 @@ var init_curatedSiteStyles = __esm({
10495
11284
  opacity: 0.6
10496
11285
  }
10497
11286
  };
11287
+ ornateDarkInputs = {
11288
+ base: {
11289
+ background: { type: "solid", colorToken: "surfaceAlt" },
11290
+ textColorToken: "text",
11291
+ border: {
11292
+ widthClass: "border",
11293
+ colorToken: "primary/45",
11294
+ style: "all"
11295
+ },
11296
+ corners: "square",
11297
+ shadow: null,
11298
+ spacing: "medium",
11299
+ fontSize: "base"
11300
+ },
11301
+ label: {
11302
+ textColorToken: "primary",
11303
+ fontWeight: "semibold",
11304
+ fontSize: "xs",
11305
+ textTransform: "uppercase",
11306
+ letterSpacing: "wider",
11307
+ opacity: 1
11308
+ },
11309
+ focus: {
11310
+ ringColorToken: "primary/18",
11311
+ ringWidth: "2",
11312
+ borderColorToken: "primary/70"
11313
+ },
11314
+ error: {
11315
+ borderColorToken: "destructive",
11316
+ textColorToken: "destructive"
11317
+ },
11318
+ disabled: {
11319
+ backgroundColorToken: "muted",
11320
+ textColorToken: "mutedText",
11321
+ opacity: 0.6
11322
+ }
11323
+ };
10498
11324
  generatedContentFrameKinds = uniqueContentFrameKinds();
10499
11325
  curatedSiteStyles = [
10500
11326
  defineCuratedSiteStyle({
@@ -11265,6 +12091,80 @@ var init_curatedSiteStyles = __esm({
11265
12091
  paletteChoice("high-contrast-ink")
11266
12092
  ]
11267
12093
  }),
12094
+ defineCuratedSiteStyle({
12095
+ id: "site-style:kirtan-ornate",
12096
+ name: "Kirtan Ornate",
12097
+ headingDecoration: { family: "short-center-rule", colorToken: "accent" },
12098
+ description: "Ceremonial, jewel-toned, and devotional: ornate frames, warm contrast, and composed rhythm for intimate music gatherings.",
12099
+ generationBrief: "Use a deep plum ground with pale gold as the main brand color, rose accent details, cream text, spacious split hero sections, devotional editorial headings, compact event lists, and framed conversion sections. The mood should feel soulful and ceremonial, not gothic or theatrical.",
12100
+ selectionKeywordRules: [
12101
+ { kind: "word", value: "kirtan" },
12102
+ { kind: "word", value: "chanting" },
12103
+ { kind: "word", value: "ceremony" },
12104
+ { kind: "word", value: "devotional" }
12105
+ ],
12106
+ tokenRecipes: {
12107
+ palette: "brand-led",
12108
+ contrast: "strong",
12109
+ radius: "soft",
12110
+ shadow: "subtle",
12111
+ typography: "serif-editorial",
12112
+ spacing: "airy",
12113
+ motion: "subtle"
12114
+ },
12115
+ compositionBudget: expressiveBudget,
12116
+ typographyPresetChoices: [
12117
+ typographyChoice("typography-preset:kirtan-ornate"),
12118
+ typographyChoice("typography-preset:luxe-contrast"),
12119
+ typographyChoice("typography-preset:editorial-serif")
12120
+ ],
12121
+ defaultTypographyPresetId: "typography-preset:kirtan-ornate",
12122
+ themeOverrides: {
12123
+ accordions: warmInsetAccordionSystem,
12124
+ cards: originalJoyCardSystem,
12125
+ testimonialQuote: serifDisplayQuote,
12126
+ bodyText: {
12127
+ intro: {
12128
+ paragraphSize: "editorial",
12129
+ headingSize: "editorial"
12130
+ }
12131
+ },
12132
+ inputs: ornateDarkInputs
12133
+ },
12134
+ designRuntimeRules: kirtanOrnateDesignRuntimeRules,
12135
+ recommendedAppearancePresetIds: [
12136
+ "hero-brand-scrim-fixed-frame",
12137
+ "media-text-quiet-story",
12138
+ "events-lined-panel",
12139
+ "schedule-details-brand-depth",
12140
+ "testimonials-statement-cards",
12141
+ "contact-form-panel"
12142
+ ],
12143
+ defaultHeaderSelection: { layoutId: "floating", styleId: "minimal-surface" },
12144
+ recommendedHeaderLayoutChoices: [headerLayoutChoice("floating")],
12145
+ recommendedHeaderStyleChoicesByLayout: {
12146
+ floating: [
12147
+ headerStyleChoice("minimal-surface"),
12148
+ headerStyleChoice("split-glass"),
12149
+ headerStyleChoice("glass")
12150
+ ]
12151
+ },
12152
+ recommendedHeaderLookIds: ["minimal-transparent"],
12153
+ recommendedFooterLookIds: [
12154
+ "site-footer-brand-two-band",
12155
+ "footer-muted-grounding"
12156
+ ],
12157
+ buttonPersonalityChoices: [
12158
+ buttonChoice("ornate-ritual"),
12159
+ buttonChoice("joy-stamp"),
12160
+ buttonChoice("ink-stamp")
12161
+ ],
12162
+ paletteVariantChoices: [
12163
+ paletteChoice("warm-dark-kirtan-gold"),
12164
+ paletteChoice("warm-dark-ember"),
12165
+ paletteChoice("brand-led-burgundy-gold")
12166
+ ]
12167
+ }),
11268
12168
  defineCuratedSiteStyle({
11269
12169
  id: "site-style:original-joy",
11270
12170
  name: "Original Joy",
@@ -11400,170 +12300,6 @@ var init_resolver2 = __esm({
11400
12300
  init_types2();
11401
12301
  }
11402
12302
  });
11403
- function uniqueNonEmpty(values) {
11404
- const uniqueValues = [...new Set(values)];
11405
- const firstValue = uniqueValues[0];
11406
- if (!firstValue) {
11407
- throw new Error("Expected at least one Theme V2 design state option.");
11408
- }
11409
- return [firstValue, ...uniqueValues.slice(1)];
11410
- }
11411
- var themeV2DesignStateSchemaVersion, designResolutionPolicySchema, runtimeStyleFieldNameSchema, nonEmptyRuntimeStyleFieldNamesSchema, heroLegibilityStrategySchema, heroCompositionIntentSchema, heroTypographyScaleIntentSchema, sectionHeightIntentSchema, imageSurfaceTreatmentIntensitySchema, imageSurfaceMotionSchema, imageSurfaceTreatmentSchema, testimonialCardTreatmentSchema, tileTreatmentSchema, eventListTreatmentSchema, eyebrowTreatmentSchema, userPanelTreatments, userFlushTreatments, userFlushBleeds, contentFrameIntentSchema, blockDesignPlanSchema, styleAuthoritySchema, blockRuntimeStyleAuthoritySchema;
11412
- var init_designState = __esm({
11413
- "../theme-core/src/site-styles/designState.ts"() {
11414
- init_sourceCatalogs();
11415
- init_types2();
11416
- init_schemaVersionedJson();
11417
- init_rawStyleFields();
11418
- init_rawStyleFields();
11419
- themeV2DesignStateSchemaVersion = 1;
11420
- designResolutionPolicySchema = z.enum(["generated", "user", "admin", "sdk"]);
11421
- runtimeStyleFieldNameSchema = z.enum(themeV2RuntimeStyleFieldNames);
11422
- nonEmptyRuntimeStyleFieldNamesSchema = z.array(runtimeStyleFieldNameSchema).min(1).transform((fields3) => [
11423
- fields3[0],
11424
- ...fields3.slice(1)
11425
- ]);
11426
- heroLegibilityStrategySchema = z.enum([
11427
- "none",
11428
- "scrim-gradient",
11429
- "solid-panel"
11430
- ]);
11431
- heroCompositionIntentSchema = z.enum([
11432
- "center",
11433
- "bottom-left"
11434
- ]);
11435
- heroTypographyScaleIntentSchema = z.enum([
11436
- "quiet",
11437
- "editorial",
11438
- "display",
11439
- "poster"
11440
- ]);
11441
- sectionHeightIntentSchema = z.enum([
11442
- "default",
11443
- "banner",
11444
- "hero",
11445
- "immersive"
11446
- ]);
11447
- imageSurfaceTreatmentIntensitySchema = z.enum(["soft", "balanced", "strong"]);
11448
- imageSurfaceMotionSchema = z.enum(["static", "fixed-frame"]);
11449
- imageSurfaceTreatmentSchema = z.discriminatedUnion("kind", [
11450
- z.object({ kind: z.literal("none") }).strict(),
11451
- z.object({
11452
- kind: z.literal("brand-scrim"),
11453
- token: z.enum(["primary", "secondary", "accent"]),
11454
- intensity: imageSurfaceTreatmentIntensitySchema.optional()
11455
- }).strict(),
11456
- z.object({
11457
- kind: z.literal("brand-wash"),
11458
- token: z.enum(["primary", "secondary", "accent"]),
11459
- intensity: imageSurfaceTreatmentIntensitySchema.optional()
11460
- }).strict(),
11461
- z.object({
11462
- kind: z.literal("neutral-scrim"),
11463
- intensity: imageSurfaceTreatmentIntensitySchema.optional()
11464
- }).strict(),
11465
- z.object({
11466
- kind: z.literal("neutral-wash"),
11467
- intensity: imageSurfaceTreatmentIntensitySchema.optional()
11468
- }).strict(),
11469
- z.object({
11470
- kind: z.literal("solid-panel"),
11471
- intensity: imageSurfaceTreatmentIntensitySchema.optional()
11472
- }).strict()
11473
- ]);
11474
- testimonialCardTreatmentSchema = z.enum(["default", "accent-quote"]);
11475
- tileTreatmentSchema = z.enum(tileTreatmentValues);
11476
- eventListTreatmentSchema = z.enum(eventListTreatmentValues);
11477
- eyebrowTreatmentSchema = z.enum(eyebrowTreatmentValues);
11478
- userPanelTreatments = uniqueNonEmpty(
11479
- userDesignOptionCatalog.contentFrames.filter((frame) => frame.kind === "panel").map((frame) => frame.treatment)
11480
- );
11481
- userFlushTreatments = uniqueNonEmpty(
11482
- userDesignOptionCatalog.contentFrames.filter((frame) => frame.kind === "flush-panel").map((frame) => frame.treatment)
11483
- );
11484
- userFlushBleeds = uniqueNonEmpty(
11485
- userDesignOptionCatalog.contentFrames.filter((frame) => frame.kind === "flush-panel").map((frame) => frame.bleed)
11486
- );
11487
- contentFrameIntentSchema = z.discriminatedUnion("kind", [
11488
- z.object({ kind: z.literal("plain") }).strict(),
11489
- z.object({
11490
- kind: z.literal("panel"),
11491
- treatment: z.enum(userPanelTreatments)
11492
- }).strict(),
11493
- z.object({
11494
- kind: z.literal("flush-panel"),
11495
- treatment: z.enum(userFlushTreatments),
11496
- bleed: z.enum(userFlushBleeds)
11497
- }).strict()
11498
- ]);
11499
- blockDesignPlanSchema = z.object({
11500
- blockId: z.string().min(1).transform(asDesignBlockId),
11501
- blockKind: z.string().min(1),
11502
- purpose: z.string().min(1),
11503
- sectionSurface: z.enum(userDesignOptionCatalog.sectionSurfaces),
11504
- contentFrame: contentFrameIntentSchema,
11505
- itemSurface: z.enum(userDesignOptionCatalog.itemSurfaces),
11506
- transitionAfter: z.enum(userDesignOptionCatalog.transitions),
11507
- emphasis: z.enum(userDesignOptionCatalog.emphases),
11508
- sectionHeight: sectionHeightIntentSchema.optional(),
11509
- heroLegibility: heroLegibilityStrategySchema.optional(),
11510
- heroComposition: heroCompositionIntentSchema.optional(),
11511
- heroTypographyScale: heroTypographyScaleIntentSchema.optional(),
11512
- imageSurfaceTreatment: imageSurfaceTreatmentSchema.optional(),
11513
- imageSurfaceMotion: imageSurfaceMotionSchema.optional(),
11514
- testimonialCardTreatment: testimonialCardTreatmentSchema.optional(),
11515
- tileTreatment: tileTreatmentSchema.optional(),
11516
- eventListTreatment: eventListTreatmentSchema.optional(),
11517
- eyebrowTreatment: eyebrowTreatmentSchema.optional()
11518
- }).strict();
11519
- styleAuthoritySchema = z.discriminatedUnion("kind", [
11520
- z.object({
11521
- kind: z.literal("theme-v2"),
11522
- source: designResolutionPolicySchema,
11523
- siteStyleId: z.string().min(1).transform(asSiteStyleId),
11524
- templateId: z.string().min(1).transform(asDesignSystemTemplateId),
11525
- templateVersion: z.number().int().nonnegative(),
11526
- resolverVersion: z.number().int().nonnegative()
11527
- }).strict(),
11528
- z.object({
11529
- kind: z.literal("legacy-raw"),
11530
- reason: z.enum(["pre-theme-v2", "manual-runtime-fields"])
11531
- }).strict(),
11532
- z.object({
11533
- kind: z.literal("advanced-detached"),
11534
- reason: z.literal("detached-custom-runtime-fields")
11535
- }).strict()
11536
- ]);
11537
- blockRuntimeStyleAuthoritySchema = z.object({
11538
- unit: z.literal("block-runtime-fields"),
11539
- blockId: z.string().min(1).transform(asDesignBlockId),
11540
- fields: nonEmptyRuntimeStyleFieldNamesSchema,
11541
- authority: styleAuthoritySchema
11542
- }).strict();
11543
- z.object({
11544
- schemaVersion: z.literal(themeV2DesignStateSchemaVersion),
11545
- siteStyleId: z.string().min(1).transform(asSiteStyleId),
11546
- templateId: z.string().min(1).transform(asDesignSystemTemplateId),
11547
- templateVersion: z.number().int().nonnegative(),
11548
- resolverVersion: z.number().int().nonnegative(),
11549
- rhythmPresetId: z.string().min(1),
11550
- blocks: z.array(blockDesignPlanSchema),
11551
- styleAuthorities: z.array(blockRuntimeStyleAuthoritySchema)
11552
- }).strict();
11553
- }
11554
- });
11555
- var init_runtimeCompiler = __esm({
11556
- "../theme-core/src/site-styles/runtimeCompiler.ts"() {
11557
- init_schema3();
11558
- init_modern_minimal();
11559
- init_expandPalette();
11560
- init_personalities();
11561
- init_variants();
11562
- init_designState();
11563
- init_types2();
11564
- init_accessibleSurfaces();
11565
- }
11566
- });
11567
12303
 
11568
12304
  // ../theme-core/src/site-styles/siteStyleThemeCompiler.ts
11569
12305
  var init_siteStyleThemeCompiler = __esm({
@@ -11745,6 +12481,7 @@ var init_generatedDesignPipeline = __esm({
11745
12481
  init_designState();
11746
12482
  init_generatedSchemas();
11747
12483
  init_siteStyleBlockPolicies();
12484
+ init_curatedSiteStyles();
11748
12485
  init_lookResolution();
11749
12486
  init_headerOpeningSection();
11750
12487
  init_resolver2();
@@ -11753,8 +12490,8 @@ var init_generatedDesignPipeline = __esm({
11753
12490
  }
11754
12491
  });
11755
12492
  function validateBlockSequence(snapshots, ctx) {
11756
- for (const issue2 of collectBlockSequenceIssues(snapshots)) {
11757
- ctx.addIssue(issue2);
12493
+ for (const issue4 of collectBlockSequenceIssues(snapshots)) {
12494
+ ctx.addIssue(issue4);
11758
12495
  }
11759
12496
  }
11760
12497
  function collectBlockSequenceIssues(snapshots) {
@@ -13428,7 +14165,7 @@ function buildFooterNavAll(common) {
13428
14165
  return stack(
13429
14166
  { className: common.className, gap: common.gap, align: "stretch" },
13430
14167
  [item],
13431
- when(collectionPath)
14168
+ whenCollectionHasItems(collectionPath)
13432
14169
  );
13433
14170
  }
13434
14171
  function buildFooterNavLinksOnly(common) {
@@ -13461,7 +14198,7 @@ function buildFooterNavLinksOnly(common) {
13461
14198
  return stack(
13462
14199
  { className: common.className, gap: common.gap, align: "stretch" },
13463
14200
  [item],
13464
- when(collectionPath)
14201
+ whenCollectionHasItems(collectionPath)
13465
14202
  );
13466
14203
  }
13467
14204
  function buildFooterNavFlatten(common) {
@@ -13510,7 +14247,7 @@ function buildFooterNavFlatten(common) {
13510
14247
  return stack(
13511
14248
  { className: common.className, gap: common.gap, align: "stretch" },
13512
14249
  [item],
13513
- when(collectionPath)
14250
+ whenCollectionHasItems(collectionPath)
13514
14251
  );
13515
14252
  }
13516
14253
  function footerNav(opts) {
@@ -13532,9 +14269,21 @@ function footerNav(opts) {
13532
14269
  if (mode === "flatten") return buildFooterNavFlatten(common);
13533
14270
  return buildFooterNavAll(common);
13534
14271
  }
14272
+ var whenCollectionHasItems;
13535
14273
  var init_footerNav = __esm({
13536
14274
  "../blocks/src/system/node/fragments/footerNav.ts"() {
13537
14275
  init_builder2();
14276
+ whenCollectionHasItems = (collectionPath) => (node) => ({
14277
+ ...node,
14278
+ $when: {
14279
+ when: {
14280
+ from: collectionPath,
14281
+ transforms: [{ id: "array.length" }]
14282
+ },
14283
+ equals: 0,
14284
+ not: true
14285
+ }
14286
+ });
13538
14287
  }
13539
14288
  });
13540
14289
 
@@ -16427,8 +17176,23 @@ var init_heroLayoutControls = __esm({
16427
17176
  heroLayoutControlsFragment = defineFragment({
16428
17177
  id: "heroLayoutControls",
16429
17178
  title: "Hero Layout",
16430
- description: "Alignment and content width controls for hero layouts.",
17179
+ description: "Title scale, alignment, and content width controls for hero layouts.",
16431
17180
  fields: [
17181
+ {
17182
+ id: "titleSize",
17183
+ type: "select",
17184
+ label: "Title size",
17185
+ description: "Adjust the visual scale of the hero title.",
17186
+ required: false,
17187
+ ui: { intent: "display" },
17188
+ options: [
17189
+ { value: "auto", label: "Auto" },
17190
+ { value: "quiet", label: "Normal" },
17191
+ { value: "editorial", label: "Large" },
17192
+ { value: "display", label: "Huge" },
17193
+ { value: "poster", label: "Poster" }
17194
+ ]
17195
+ },
16432
17196
  {
16433
17197
  id: "contentAlignment",
16434
17198
  type: "select",
@@ -17503,9 +18267,9 @@ function createZodCodec(schema) {
17503
18267
  return decodeSuccess(parsed.data);
17504
18268
  }
17505
18269
  return decodeFailure(
17506
- parsed.error.issues.map((issue2) => ({
17507
- path: zodIssuePath(issue2.path),
17508
- message: issue2.message
18270
+ parsed.error.issues.map((issue4) => ({
18271
+ path: zodIssuePath(issue4.path),
18272
+ message: issue4.message
17509
18273
  }))
17510
18274
  );
17511
18275
  }
@@ -18310,9 +19074,14 @@ function isEventCalendarDisplayMode(value) {
18310
19074
  function isEventCalendarListLayout(value) {
18311
19075
  return typeof value === "string" && eventCalendarListLayoutValues.includes(value);
18312
19076
  }
18313
- var eventCalendarDisplayModeValues, eventCalendarListLayoutValues, eventCalendarListLayoutOptions;
19077
+ function isEventContentType(slug) {
19078
+ if (!slug) return false;
19079
+ return EVENT_CONTENT_TYPE_SLUGS.includes(slug);
19080
+ }
19081
+ var EVENT_CONTENT_TYPE_SLUGS, eventCalendarDisplayModeValues, eventCalendarListLayoutValues, eventCalendarListLayoutOptions;
18314
19082
  var init_events = __esm({
18315
19083
  "../blocks/src/system/constants/events.ts"() {
19084
+ EVENT_CONTENT_TYPE_SLUGS = ["event", "events"];
18316
19085
  eventCalendarDisplayModeValues = ["combined", "month", "week", "list", "timetable"];
18317
19086
  eventCalendarListLayoutValues = ["stack", "grid", "compact"];
18318
19087
  eventCalendarListLayoutOptions = [
@@ -18322,6 +19091,131 @@ var init_events = __esm({
18322
19091
  ];
18323
19092
  }
18324
19093
  });
19094
+
19095
+ // ../blocks/src/system/runtime/nodes/events/shared/pricing.ts
19096
+ function resolveRuntimeEventPricing(event) {
19097
+ if (isPublicEventPricing(event.pricing)) {
19098
+ return event.pricing;
19099
+ }
19100
+ const legacy = event;
19101
+ const currency = readCurrency(legacy.currency);
19102
+ if (event.requiresRegistration === false) {
19103
+ return {
19104
+ kind: "drop_in",
19105
+ currency,
19106
+ display: { kind: "free", currency }
19107
+ };
19108
+ }
19109
+ if (legacy.pricingMode === "ticket_types") {
19110
+ const ticketTypes = Array.isArray(legacy.ticketTypes) ? legacy.ticketTypes.filter(isPublicEventTicketType) : [];
19111
+ return {
19112
+ kind: "ticket_types",
19113
+ currency,
19114
+ ticketTypes,
19115
+ display: readTicketTypePriceDisplay(legacy.priceDisplay, currency)
19116
+ };
19117
+ }
19118
+ const amount = typeof legacy.price === "number" ? legacy.price : 0;
19119
+ if (legacy.pricingType === "paid" && amount > 0) {
19120
+ return {
19121
+ kind: "single_paid",
19122
+ amount,
19123
+ currency,
19124
+ display: { kind: "exact", amount, currency }
19125
+ };
19126
+ }
19127
+ return {
19128
+ kind: "free_registration",
19129
+ currency,
19130
+ display: { kind: "free", currency }
19131
+ };
19132
+ }
19133
+ function readCurrency(value) {
19134
+ return typeof value === "string" && value.trim().length > 0 ? value : DEFAULT_EVENT_CURRENCY;
19135
+ }
19136
+ function isRecord4(value) {
19137
+ return typeof value === "object" && value !== null && !Array.isArray(value);
19138
+ }
19139
+ function isPublicEventPricing(value) {
19140
+ if (!isRecord4(value) || typeof value.kind !== "string") return false;
19141
+ return value.kind === "drop_in" || value.kind === "free_registration" || value.kind === "single_paid" || value.kind === "ticket_types" || value.kind === "course";
19142
+ }
19143
+ function isPublicEventTicketType(value) {
19144
+ return isRecord4(value) && typeof value.id === "string";
19145
+ }
19146
+ function readTicketTypePriceDisplay(value, currency) {
19147
+ const display = readLegacyPriceDisplay(value, currency);
19148
+ return display.kind === "course" ? { kind: "unavailable", currency } : display;
19149
+ }
19150
+ function readLegacyPriceDisplay(value, currency) {
19151
+ if (!isRecord4(value) || typeof value.kind !== "string") {
19152
+ return { kind: "unavailable", currency };
19153
+ }
19154
+ const displayCurrency = readCurrency(value.currency);
19155
+ switch (value.kind) {
19156
+ case "free":
19157
+ return { kind: "free", currency: displayCurrency };
19158
+ case "exact":
19159
+ return readAmount(value.amount) !== null ? {
19160
+ kind: "exact",
19161
+ amount: readAmount(value.amount) ?? 0,
19162
+ currency: displayCurrency
19163
+ } : { kind: "unavailable", currency };
19164
+ case "from":
19165
+ return readAmount(value.amount) !== null ? {
19166
+ kind: "from",
19167
+ amount: readAmount(value.amount) ?? 0,
19168
+ currency: displayCurrency
19169
+ } : { kind: "unavailable", currency };
19170
+ case "mixed":
19171
+ return readAmount(value.paidFromAmount) !== null ? {
19172
+ kind: "mixed",
19173
+ paidFromAmount: readAmount(value.paidFromAmount) ?? 0,
19174
+ currency: displayCurrency
19175
+ } : { kind: "unavailable", currency };
19176
+ case "unavailable":
19177
+ return { kind: "unavailable", currency: displayCurrency };
19178
+ case "course":
19179
+ return isRecord4(value.display) ? {
19180
+ kind: "course",
19181
+ display: readCoursePriceDisplay(value.display, displayCurrency)
19182
+ } : {
19183
+ kind: "course",
19184
+ display: { kind: "unavailable", currency: displayCurrency }
19185
+ };
19186
+ default:
19187
+ return { kind: "unavailable", currency };
19188
+ }
19189
+ }
19190
+ function readCoursePriceDisplay(value, currency) {
19191
+ switch (value.kind) {
19192
+ case "free":
19193
+ return { kind: "free", currency: readCurrency(value.currency) };
19194
+ case "exact":
19195
+ return readAmount(value.amount) !== null ? {
19196
+ kind: "exact",
19197
+ amount: readAmount(value.amount) ?? 0,
19198
+ currency: readCurrency(value.currency)
19199
+ } : { kind: "unavailable", currency };
19200
+ case "from":
19201
+ return readAmount(value.amount) !== null ? {
19202
+ kind: "from",
19203
+ amount: readAmount(value.amount) ?? 0,
19204
+ currency: readCurrency(value.currency)
19205
+ } : { kind: "unavailable", currency };
19206
+ default:
19207
+ return { kind: "unavailable", currency };
19208
+ }
19209
+ }
19210
+ function readAmount(value) {
19211
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
19212
+ }
19213
+ var DEFAULT_EVENT_CURRENCY;
19214
+ var init_pricing = __esm({
19215
+ "../blocks/src/system/runtime/nodes/events/shared/pricing.ts"() {
19216
+ DEFAULT_EVENT_CURRENCY = "USD";
19217
+ }
19218
+ });
18325
19219
  var previewStageSchema, registrationButtonVariantSchema, eventButtonVariantSchema, eventLayoutSchema, eventCalendarDisplayModeSchema, columnOptionSchema, weekStartSchema, filterAutoShowSchema, calendarTabViewsSchema;
18326
19220
  var init_contract_schemas = __esm({
18327
19221
  "../blocks/src/system/runtime/nodes/shared/contract-schemas.ts"() {
@@ -18337,27 +19231,184 @@ var init_contract_schemas = __esm({
18337
19231
  calendarTabViewsSchema = z.enum(["both", "month", "week"]);
18338
19232
  }
18339
19233
  });
19234
+
19235
+ // ../blocks/src/system/runtime/nodes/event-registration/wizardSteps.ts
19236
+ function getWizardStepsForContext(hasPreSelectedContext, needsPaymentStep) {
19237
+ const baseSteps = hasPreSelectedContext ? ["select-tickets", "enter-details"] : ["select-event", "select-tickets", "enter-details"];
19238
+ if (!needsPaymentStep) {
19239
+ return baseSteps;
19240
+ }
19241
+ return [...baseSteps, "select-payment"];
19242
+ }
19243
+ var init_wizardSteps = __esm({
19244
+ "../blocks/src/system/runtime/nodes/event-registration/wizardSteps.ts"() {
19245
+ }
19246
+ });
19247
+
19248
+ // ../blocks/src/system/runtime/nodes/event-registration/registrationDerivations.ts
19249
+ function eventMatchesOccurrenceId(event, occurrenceId) {
19250
+ return event.registrationOccurrenceId === occurrenceId || event.publicEventId === occurrenceId;
19251
+ }
19252
+ function findPreSelectedEvent(input) {
19253
+ const occurrenceContext = input.occurrenceContext;
19254
+ if (!occurrenceContext) {
19255
+ return null;
19256
+ }
19257
+ const contextDate = getBookingLocalDateKey(toScheduledBookingDateTime({
19258
+ startsAt: occurrenceContext.startsAt,
19259
+ timeZone: occurrenceContext.timeZone
19260
+ }));
19261
+ return input.scopedEvents.find(
19262
+ (event) => eventMatchesOccurrenceId(event, occurrenceContext.id) || getBookingLocalDateKey(toScheduledBookingDateTime({
19263
+ startsAt: event.startsAt,
19264
+ timeZone: event.timeZone
19265
+ })) === contextDate
19266
+ ) ?? null;
19267
+ }
19268
+ function resolveEventRequiresPayment(input) {
19269
+ if (input.eligibility) {
19270
+ return input.eligibility.requiresPayment;
19271
+ }
19272
+ if (!input.event) {
19273
+ return false;
19274
+ }
19275
+ return publicEventPricingType(resolveRuntimeEventPricing(input.event)) !== "free";
19276
+ }
19277
+ var init_registrationDerivations = __esm({
19278
+ "../blocks/src/system/runtime/nodes/event-registration/registrationDerivations.ts"() {
19279
+ init_src();
19280
+ init_pricing();
19281
+ }
19282
+ });
19283
+
19284
+ // ../blocks/src/system/runtime/nodes/event-registration/registrationEventAdapter.ts
19285
+ function toRegistrationEvent(event) {
19286
+ return {
19287
+ ...event,
19288
+ pricing: resolveRuntimeEventPricing(event),
19289
+ publicEventId: event.id,
19290
+ registrationOccurrenceId: event.occurrenceId
19291
+ };
19292
+ }
19293
+ function toRegistrationEvents(events) {
19294
+ return events.map(toRegistrationEvent);
19295
+ }
19296
+ var init_registrationEventAdapter = __esm({
19297
+ "../blocks/src/system/runtime/nodes/event-registration/registrationEventAdapter.ts"() {
19298
+ init_pricing();
19299
+ }
19300
+ });
18340
19301
  function buildEventRegistrationDisplay(source) {
19302
+ const stepLabels = buildEventRegistrationShellStepLabels(source);
18341
19303
  return {
18342
19304
  kind: "event-registration",
18343
- state: "shell",
19305
+ state: "generic-shell",
18344
19306
  className: source.className ?? null,
19307
+ titleText: "Event registration",
19308
+ bodyText: buildEventRegistrationShellBodyText(stepLabels),
19309
+ stepLabels,
18345
19310
  summaryButtonText: source.buttonText?.trim() || "Register"
18346
19311
  };
18347
19312
  }
18348
- var contentEntrySchema, eventRegistrationSourceSchema, eventRegistrationDisplaySchema, eventRegistrationHydrationSchema, eventRegistrationRenderSchema, eventRegistrationBlockRuntime;
19313
+ function buildEventRegistrationShellStepLabels(source) {
19314
+ const scopedEvents = scopeEventRegistrationEvents(source);
19315
+ if (scopedEvents.length === 0) {
19316
+ return EVENT_REGISTRATION_GENERIC_SHELL_STEP_LABELS;
19317
+ }
19318
+ const preSelectedEvent = findPreSelectedEvent({
19319
+ scopedEvents,
19320
+ occurrenceContext: source.occurrenceContext
19321
+ });
19322
+ const hasPreSelectedContext = Boolean(source.occurrenceContext || preSelectedEvent);
19323
+ const needsPaymentStep = hasPreSelectedContext && preSelectedEvent ? resolveEventRequiresPayment({
19324
+ eligibility: null,
19325
+ event: preSelectedEvent
19326
+ }) : false;
19327
+ return getWizardStepsForContext(hasPreSelectedContext, needsPaymentStep).map((step) => shellLabelForRegistrationStep(step, scopedEvents));
19328
+ }
19329
+ function scopeEventRegistrationEvents(source) {
19330
+ const events = toRegistrationEvents(source.events ?? []);
19331
+ if (source.occurrenceContext?.seriesId) {
19332
+ return events.filter((event) => event.seriesId === source.occurrenceContext?.seriesId);
19333
+ }
19334
+ const entrySlug = source.contentEntry?.slug;
19335
+ const entryContentType = source.contentEntry?.contentTypeSlug;
19336
+ if (entrySlug && entryContentType && isEventContentType(entryContentType)) {
19337
+ return events.filter((event) => event.slug === entrySlug);
19338
+ }
19339
+ return events;
19340
+ }
19341
+ function shellLabelForRegistrationStep(step, events) {
19342
+ switch (step) {
19343
+ case "select-event":
19344
+ return isDateSelection(events) ? "Date" : "Event";
19345
+ case "select-tickets":
19346
+ return "Tickets";
19347
+ case "enter-details":
19348
+ return "Details";
19349
+ case "select-payment":
19350
+ return "Payment";
19351
+ case "error":
19352
+ case "success":
19353
+ case "submitting":
19354
+ case "redirecting":
19355
+ case "verifying-payment":
19356
+ case "verifying-timeout":
19357
+ case "payment-failed":
19358
+ return "Details";
19359
+ }
19360
+ }
19361
+ function isDateSelection(events) {
19362
+ const firstSeriesId = events[0]?.seriesId;
19363
+ return Boolean(
19364
+ events.length > 1 && firstSeriesId && events.every((event) => event.seriesId === firstSeriesId)
19365
+ );
19366
+ }
19367
+ function buildEventRegistrationShellBodyText(stepLabels) {
19368
+ if (stepLabels.includes("Payment")) {
19369
+ return "Preparing tickets, details, and payment options.";
19370
+ }
19371
+ if (stepLabels[0] === "Tickets") {
19372
+ return "Preparing tickets and booking details.";
19373
+ }
19374
+ return "Preparing dates, tickets, and booking details.";
19375
+ }
19376
+ function normalizeEventRegistrationEventInput(value) {
19377
+ if (!isRecord5(value)) {
19378
+ return value;
19379
+ }
19380
+ return {
19381
+ ...value,
19382
+ pricing: resolveRuntimeEventPricing(value)
19383
+ };
19384
+ }
19385
+ function isRecord5(value) {
19386
+ return typeof value === "object" && value !== null && !Array.isArray(value);
19387
+ }
19388
+ var EVENT_REGISTRATION_GENERIC_SHELL_STEP_LABELS, EVENT_REGISTRATION_SHELL_STEP_LABELS, contentEntrySchema, eventRegistrationPublicEventSchema, eventRegistrationSourceSchema, eventRegistrationDisplaySchema, eventRegistrationHydrationSchema, eventRegistrationRenderSchema, eventRegistrationBlockRuntime;
18349
19389
  var init_event_registration_interactive = __esm({
18350
19390
  "../blocks/src/system/runtime/nodes/event-registration.interactive.ts"() {
18351
19391
  init_schemas2();
18352
19392
  init_event_registration_shared();
19393
+ init_events();
19394
+ init_pricing();
18353
19395
  init_islands();
18354
19396
  init_runtime();
18355
19397
  init_contract_schemas();
19398
+ init_wizardSteps();
19399
+ init_registrationDerivations();
19400
+ init_registrationEventAdapter();
19401
+ EVENT_REGISTRATION_GENERIC_SHELL_STEP_LABELS = ["Date", "Tickets", "Details"];
19402
+ EVENT_REGISTRATION_SHELL_STEP_LABELS = ["Event", "Date", "Tickets", "Details", "Payment"];
18356
19403
  contentEntrySchema = z.object({
18357
19404
  id: z.string(),
18358
19405
  slug: z.string(),
18359
19406
  contentTypeSlug: z.string()
18360
19407
  });
19408
+ eventRegistrationPublicEventSchema = z.preprocess(
19409
+ normalizeEventRegistrationEventInput,
19410
+ publicEventSchema
19411
+ );
18361
19412
  eventRegistrationSourceSchema = z.object({
18362
19413
  siteId: z.string().optional(),
18363
19414
  apiBaseUrl: z.string().optional(),
@@ -18365,7 +19416,7 @@ var init_event_registration_interactive = __esm({
18365
19416
  previewToken: z.string().nullable().optional(),
18366
19417
  occurrenceContext: occurrenceContextSchema.optional(),
18367
19418
  contentEntry: contentEntrySchema.nullable().optional(),
18368
- events: z.array(publicEventSchema).nullable().optional(),
19419
+ events: z.array(eventRegistrationPublicEventSchema).nullable().optional(),
18369
19420
  className: z.string().nullable().optional(),
18370
19421
  buttonText: z.string().nullable().optional(),
18371
19422
  maxTickets: z.string().nullable().optional(),
@@ -18380,14 +19431,17 @@ var init_event_registration_interactive = __esm({
18380
19431
  });
18381
19432
  eventRegistrationDisplaySchema = z.object({
18382
19433
  kind: z.literal("event-registration"),
18383
- state: z.literal("shell"),
19434
+ state: z.literal("generic-shell"),
18384
19435
  className: z.string().nullable(),
19436
+ titleText: z.string(),
19437
+ bodyText: z.string(),
19438
+ stepLabels: z.array(z.enum(EVENT_REGISTRATION_SHELL_STEP_LABELS)).min(1),
18385
19439
  summaryButtonText: z.string()
18386
19440
  });
18387
19441
  eventRegistrationHydrationSchema = z.object({
18388
19442
  occurrenceContext: occurrenceContextSchema.optional(),
18389
19443
  contentEntry: contentEntrySchema.nullable().optional(),
18390
- events: z.array(publicEventSchema).nullable().optional(),
19444
+ events: z.array(eventRegistrationPublicEventSchema).nullable().optional(),
18391
19445
  maxTickets: z.string().optional(),
18392
19446
  showVenue: z.boolean().optional(),
18393
19447
  showCapacity: z.boolean().optional(),
@@ -18441,7 +19495,7 @@ var init_types16 = __esm({
18441
19495
  });
18442
19496
 
18443
19497
  // ../blocks/src/system/blocks/courses/shared/pricing.ts
18444
- var init_pricing = __esm({
19498
+ var init_pricing2 = __esm({
18445
19499
  "../blocks/src/system/blocks/courses/shared/pricing.ts"() {
18446
19500
  }
18447
19501
  });
@@ -18451,7 +19505,7 @@ var init_shared3 = __esm({
18451
19505
  "../blocks/src/system/blocks/courses/shared/index.ts"() {
18452
19506
  init_types16();
18453
19507
  init_schemas();
18454
- init_pricing();
19508
+ init_pricing2();
18455
19509
  }
18456
19510
  });
18457
19511
  function buildCourseRegistrationDisplay(source) {
@@ -23747,6 +24801,46 @@ var ENDPOINT_DEFINITIONS = {
23747
24801
  auth: "user",
23748
24802
  responseKind: "json"
23749
24803
  },
24804
+ listEntrySlotBlocks: {
24805
+ path: "/sites/{siteId}/content/{type}/{entryId}/slots/{slotKey}/blocks",
24806
+ method: "GET",
24807
+ tags: ["site-{siteId}", "content-entry-{entryId}", "entry-slot-{slotKey}", "blocks"],
24808
+ auth: "user",
24809
+ responseKind: "json",
24810
+ errors: ["resource:not_found"]
24811
+ },
24812
+ listEntryPageContentSlots: {
24813
+ path: "/sites/{siteId}/content/{type}/{entryId}/slots",
24814
+ method: "GET",
24815
+ tags: ["site-{siteId}", "content-entry-{entryId}", "entry-slots", "blocks"],
24816
+ auth: "user",
24817
+ responseKind: "json",
24818
+ errors: ["resource:not_found"]
24819
+ },
24820
+ createEntrySlotBlock: {
24821
+ path: "/sites/{siteId}/content/{type}/{entryId}/slots/{slotKey}/blocks",
24822
+ method: "POST",
24823
+ tags: ["site-{siteId}", "content-entry-{entryId}", "entry-slot-{slotKey}", "blocks"],
24824
+ auth: "user",
24825
+ responseKind: "json",
24826
+ errors: ["validation:invalid_input", "resource:not_found"]
24827
+ },
24828
+ reorderEntrySlotBlocks: {
24829
+ path: "/sites/{siteId}/content/{type}/{entryId}/slots/{slotKey}/blocks/reorder",
24830
+ method: "POST",
24831
+ tags: ["site-{siteId}", "content-entry-{entryId}", "entry-slot-{slotKey}", "blocks"],
24832
+ auth: "user",
24833
+ responseKind: "json",
24834
+ errors: ["validation:invalid_input", "resource:not_found"]
24835
+ },
24836
+ deleteEntrySlotBlock: {
24837
+ path: "/sites/{siteId}/content/{type}/{entryId}/slots/{slotKey}/blocks/{blockId}",
24838
+ method: "DELETE",
24839
+ tags: ["site-{siteId}", "content-entry-{entryId}", "entry-slot-{slotKey}", "blocks"],
24840
+ auth: "user",
24841
+ responseKind: "json",
24842
+ errors: ["resource:not_found"]
24843
+ },
23750
24844
  createBlock: {
23751
24845
  path: "/sites/{siteId}/pages/{pageId}/blocks",
23752
24846
  method: "POST",
@@ -27501,14 +28595,14 @@ function formatFieldPath(path25) {
27501
28595
  function toZodIssuePath(path25) {
27502
28596
  return [...path25];
27503
28597
  }
27504
- function fieldIssueToMessage(issue2) {
27505
- switch (issue2.kind) {
28598
+ function fieldIssueToMessage(issue4) {
28599
+ switch (issue4.kind) {
27506
28600
  case "required":
27507
28601
  return "This field is required";
27508
28602
  case "wrongType":
27509
- return `${issue2.label} needs ${issue2.expected}`;
28603
+ return `${issue4.label} needs ${issue4.expected}`;
27510
28604
  case "tooLong":
27511
- return `Use ${issue2.maximum} characters or fewer`;
28605
+ return `Use ${issue4.maximum} characters or fewer`;
27512
28606
  case "invalidEmail":
27513
28607
  return "Enter a valid email address";
27514
28608
  case "invalidPhone":
@@ -27524,29 +28618,29 @@ function fieldIssueToMessage(issue2) {
27524
28618
  case "invalidDateTime":
27525
28619
  return "Choose a valid date and time";
27526
28620
  case "invalidNumber":
27527
- return `${issue2.label} needs a number`;
28621
+ return `${issue4.label} needs a number`;
27528
28622
  case "tooSmall":
27529
- return `${issue2.label} must be ${issue2.minimum} or more`;
28623
+ return `${issue4.label} must be ${issue4.minimum} or more`;
27530
28624
  case "tooLarge":
27531
- return `${issue2.label} must be ${issue2.maximum} or less`;
28625
+ return `${issue4.label} must be ${issue4.maximum} or less`;
27532
28626
  case "invalidSlug":
27533
- return `${issue2.label} can only use lowercase letters, numbers, and dashes`;
28627
+ return `${issue4.label} can only use lowercase letters, numbers, and dashes`;
27534
28628
  case "invalidOption":
27535
- return `Choose one of the available options for ${issue2.label}`;
28629
+ return `Choose one of the available options for ${issue4.label}`;
27536
28630
  case "tooFewItems":
27537
- return `${issue2.label} must have at least ${issue2.minimum} ${pluralize(issue2.itemLabel, issue2.minimum)}`;
28631
+ return `${issue4.label} must have at least ${issue4.minimum} ${pluralize(issue4.itemLabel, issue4.minimum)}`;
27538
28632
  case "tooManyItems":
27539
- return `${issue2.label} must have at most ${issue2.maximum} ${pluralize(issue2.itemLabel, issue2.maximum)}`;
28633
+ return `${issue4.label} must have at most ${issue4.maximum} ${pluralize(issue4.itemLabel, issue4.maximum)}`;
27540
28634
  case "invalidRichText":
27541
- return `${issue2.label} must be valid rich text`;
28635
+ return `${issue4.label} must be valid rich text`;
27542
28636
  case "invalidMedia":
27543
- return `${issue2.label} must be a valid media item`;
28637
+ return `${issue4.label} must be a valid media item`;
27544
28638
  case "invalidLink":
27545
- return `${issue2.label} must be a valid link`;
28639
+ return `${issue4.label} must be a valid link`;
27546
28640
  case "invalidReference":
27547
- return `${issue2.label} must reference a valid item`;
28641
+ return `${issue4.label} must reference a valid item`;
27548
28642
  default:
27549
- return assertNever2(issue2);
28643
+ return assertNever2(issue4);
27550
28644
  }
27551
28645
  }
27552
28646
  function pluralize(label, count) {
@@ -28185,8 +29279,8 @@ function isValidTimeString(value) {
28185
29279
  function isValidDateTimeInstantString(value) {
28186
29280
  const match = DATETIME_PATTERN.exec(value);
28187
29281
  if (!match?.groups) return false;
28188
- const datePart = match.groups.date;
28189
- if (!datePart || !isValidDateString(datePart)) return false;
29282
+ const datePart2 = match.groups.date;
29283
+ if (!datePart2 || !isValidDateString(datePart2)) return false;
28190
29284
  return !Number.isNaN(Date.parse(value));
28191
29285
  }
28192
29286
  function isValidCalendarDate(year, month, day) {
@@ -28333,6 +29427,33 @@ function declareNoBlockDesignCapability(reason) {
28333
29427
 
28334
29428
  // ../blocks/src/system/blocks/hero.ts
28335
29429
  init_boxStyles();
29430
+
29431
+ // ../blocks/src/system/fields/imageShape.ts
29432
+ var standardImageShapeOptions = [
29433
+ { value: "default", label: "Default" },
29434
+ { value: "square", label: "Square corners" },
29435
+ { value: "rounded", label: "Rounded corners" },
29436
+ { value: "circle", label: "Circle" },
29437
+ { value: "arch", label: "Arch" }
29438
+ ];
29439
+ function createImageShapeField(options = {}) {
29440
+ return {
29441
+ id: options.id ?? "imageShape",
29442
+ type: "select",
29443
+ label: options.label ?? "Image shape",
29444
+ ...options.description ? { description: options.description } : {},
29445
+ required: false,
29446
+ defaultValue: options.defaultValue ?? "default",
29447
+ multiple: false,
29448
+ options: [...standardImageShapeOptions],
29449
+ ui: {
29450
+ intent: options.uiIntent ?? "display",
29451
+ ...options.visibleWhen ? { visibleWhen: options.visibleWhen } : {}
29452
+ }
29453
+ };
29454
+ }
29455
+
29456
+ // ../blocks/src/system/blocks/hero.ts
28336
29457
  init_fragments();
28337
29458
  init_styledSection();
28338
29459
  init_defineBlock();
@@ -28400,7 +29521,18 @@ function heroSplitImagePane() {
28400
29521
  return stack(
28401
29522
  {
28402
29523
  gap: "none",
28403
- className: "rb-relative rb-overflow-hidden rb-rounded-3xl",
29524
+ className: {
29525
+ $bind: {
29526
+ from: "content.imageShape",
29527
+ transforms: [
29528
+ {
29529
+ id: "ui.imageShapeClassName",
29530
+ options: { baseClass: "rb-relative rb-overflow-hidden rb-rounded-3xl" }
29531
+ }
29532
+ ],
29533
+ fallback: "rb-relative rb-overflow-hidden rb-rounded-3xl"
29534
+ }
29535
+ },
28404
29536
  style: {
28405
29537
  minHeight: "clamp(18rem, 36vw, 34rem)"
28406
29538
  }
@@ -28518,6 +29650,12 @@ var heroConfig = {
28518
29650
  label: "Content card",
28519
29651
  renderInHeader: true,
28520
29652
  intent: "style"
29653
+ }),
29654
+ createImageShapeField({
29655
+ id: "imageShape",
29656
+ label: "Image shape",
29657
+ defaultValue: "default",
29658
+ uiIntent: "display"
28521
29659
  })
28522
29660
  ],
28523
29661
  layout: classicLayout,
@@ -28532,6 +29670,15 @@ var heroConfig = {
28532
29670
  description: "Hero section with headline, subtitle, and repeatable CTAs.",
28533
29671
  tags: ["header", "banner", "landing", "introduction", "welcome", "splash", "headline"],
28534
29672
  icon: "Sparkles",
29673
+ previewCustomize: {
29674
+ quickFieldPriority: [
29675
+ "titleSize",
29676
+ "contentAlignment",
29677
+ "contentMaxWidth",
29678
+ "verticalAlignment",
29679
+ "imageShape"
29680
+ ]
29681
+ },
28535
29682
  styleTokens: {
28536
29683
  typography: "display",
28537
29684
  spacing: "xl"
@@ -28551,7 +29698,8 @@ var standardAspectRatioOptions = [
28551
29698
  { value: "16/9", label: "16:9 (Landscape)" },
28552
29699
  { value: "4/3", label: "4:3 (Standard)" },
28553
29700
  { value: "1/1", label: "1:1 (Square)" },
28554
- { value: "3/4", label: "3:4 (Portrait)" }
29701
+ { value: "3/4", label: "3:4 (Portrait)" },
29702
+ { value: "9/16", label: "9:16 (Tall portrait)" }
28555
29703
  ];
28556
29704
  function createAspectRatioField(options = {}) {
28557
29705
  return {
@@ -29522,6 +30670,263 @@ var formBlockDefinition = {
29522
30670
  runtime: formBlockRuntime
29523
30671
  };
29524
30672
 
30673
+ // ../blocks/src/system/blocks/contact-newsletter.ts
30674
+ init_fragments();
30675
+ init_styledSection();
30676
+ init_builder2();
30677
+ init_defineBlock();
30678
+ init_api_bindings();
30679
+ var contactNewsletterLayout = styledSection({
30680
+ children: sectionContainer([
30681
+ el(
30682
+ "div",
30683
+ { className: "contact-newsletter-grid" },
30684
+ [
30685
+ el(
30686
+ "div",
30687
+ { className: "contact-newsletter-column contact-newsletter-contact" },
30688
+ [
30689
+ el(
30690
+ "div",
30691
+ { className: "contact-newsletter-copy" },
30692
+ [
30693
+ text(
30694
+ {
30695
+ as: "h2",
30696
+ className: "form-copy-title"
30697
+ },
30698
+ when("contactTitle"),
30699
+ bind("contactTitle")
30700
+ ),
30701
+ richText(
30702
+ {
30703
+ className: "form-copy-intro rb-prose rb-max-w-none"
30704
+ },
30705
+ when("contactIntro"),
30706
+ bind("contactIntro")
30707
+ )
30708
+ ]
30709
+ ),
30710
+ el(
30711
+ "form",
30712
+ withApiBindings({
30713
+ spamProtectionEnabled: { $bind: { from: "$root.spamProtectionEnabled" } },
30714
+ submitLabel: { $bind: { from: "contactSubmitLabel" } },
30715
+ successMessage: { $bind: { from: "contactSuccessMessage" } }
30716
+ }),
30717
+ [],
30718
+ bind("data.form")
30719
+ )
30720
+ ]
30721
+ ),
30722
+ el(
30723
+ "div",
30724
+ { className: "contact-newsletter-column contact-newsletter-info contact-newsletter-newsletter" },
30725
+ [
30726
+ el(
30727
+ "div",
30728
+ { className: "contact-newsletter-copy" },
30729
+ [
30730
+ text(
30731
+ {
30732
+ as: "h2",
30733
+ className: "newsletter-copy-title"
30734
+ },
30735
+ when("newsletterTitle"),
30736
+ bind("newsletterTitle")
30737
+ ),
30738
+ richText(
30739
+ {
30740
+ className: "newsletter-copy-subtitle rb-prose rb-max-w-none"
30741
+ },
30742
+ when("newsletterSubtitle"),
30743
+ bind("newsletterSubtitle")
30744
+ )
30745
+ ]
30746
+ ),
30747
+ el(
30748
+ "newsletter-form",
30749
+ withApiBindings({
30750
+ listId: { $bind: { from: "listId" } },
30751
+ preset: { $bind: { from: "preset" } },
30752
+ includePhone: { $bind: { from: "includePhone" } },
30753
+ buttonLabel: { $bind: { from: "newsletterButtonLabel" } },
30754
+ successMessage: { $bind: { from: "newsletterSuccessMessage" } },
30755
+ privacyNote: { $bind: { from: "newsletterPrivacyNote" } },
30756
+ tags: { $bind: { from: "newsletterTags" } },
30757
+ spamProtectionEnabled: { $bind: { from: "$root.spamProtectionEnabled" } }
30758
+ }),
30759
+ []
30760
+ )
30761
+ ]
30762
+ )
30763
+ ]
30764
+ )
30765
+ ], {
30766
+ className: "contact-newsletter-container"
30767
+ }),
30768
+ baseClass: "",
30769
+ spacing: "medium",
30770
+ background: "surface"
30771
+ });
30772
+ var contactNewsletterManifest = createBlockManifest({
30773
+ id: "block.contact-newsletter",
30774
+ title: "Contact + Newsletter",
30775
+ titleSource: "contactTitle",
30776
+ description: "Two-column newsletter signup and contact form section.",
30777
+ category: "interactive",
30778
+ layout: contactNewsletterLayout,
30779
+ defaultVariant: "default",
30780
+ variants: {
30781
+ default: contactNewsletterLayout
30782
+ },
30783
+ variantOptions: {
30784
+ default: {
30785
+ label: "Two column",
30786
+ description: "Newsletter and contact form side by side.",
30787
+ icon: "Columns2"
30788
+ }
30789
+ },
30790
+ additionalFields: [
30791
+ {
30792
+ id: "newsletterTitle",
30793
+ type: "text",
30794
+ label: "Newsletter title",
30795
+ defaultValue: "Stay connected"
30796
+ },
30797
+ {
30798
+ id: "newsletterSubtitle",
30799
+ type: "richText",
30800
+ label: "Newsletter intro"
30801
+ },
30802
+ {
30803
+ id: "listId",
30804
+ type: "reference",
30805
+ label: "Newsletter list",
30806
+ description: "Select the list new subscribers should be added to.",
30807
+ required: true,
30808
+ referenceKind: "newsletterList",
30809
+ allowManualEntry: false,
30810
+ ui: { intent: "behavior" }
30811
+ },
30812
+ {
30813
+ id: "preset",
30814
+ type: "select",
30815
+ label: "Newsletter fields",
30816
+ defaultValue: "emailOnly",
30817
+ ui: { intent: "display" },
30818
+ options: [
30819
+ { value: "emailOnly", label: "Email only" },
30820
+ { value: "emailName", label: "Email + Name" },
30821
+ { value: "emailFirstLast", label: "Email + First/Last Name" },
30822
+ { value: "emailNameCompany", label: "Email + Name + Company (B2B)" }
30823
+ ]
30824
+ },
30825
+ {
30826
+ id: "includePhone",
30827
+ type: "boolean",
30828
+ label: "Include phone field",
30829
+ defaultValue: false,
30830
+ ui: { intent: "display" }
30831
+ },
30832
+ {
30833
+ id: "newsletterButtonLabel",
30834
+ type: "text",
30835
+ label: "Newsletter button label",
30836
+ defaultValue: "Subscribe",
30837
+ ui: { intent: "display" }
30838
+ },
30839
+ {
30840
+ id: "newsletterSuccessMessage",
30841
+ type: "text",
30842
+ label: "Newsletter success message",
30843
+ defaultValue: "Thanks for subscribing!",
30844
+ ui: { intent: "behavior" }
30845
+ },
30846
+ {
30847
+ id: "newsletterPrivacyNote",
30848
+ type: "text",
30849
+ label: "Privacy note",
30850
+ ui: { intent: "display" }
30851
+ },
30852
+ {
30853
+ id: "newsletterTags",
30854
+ type: "text",
30855
+ label: "Newsletter tags",
30856
+ description: "Optional tags to apply on subscribe, separated by comma or semicolon.",
30857
+ ui: { intent: "behavior" }
30858
+ },
30859
+ {
30860
+ id: "contactTitle",
30861
+ type: "text",
30862
+ label: "Contact title",
30863
+ defaultValue: "Get in touch"
30864
+ },
30865
+ {
30866
+ id: "contactIntro",
30867
+ type: "richText",
30868
+ label: "Contact intro"
30869
+ },
30870
+ {
30871
+ id: "formSlug",
30872
+ type: "reference",
30873
+ label: "Contact form",
30874
+ description: "Pick a saved form to render.",
30875
+ required: true,
30876
+ referenceKind: "form",
30877
+ allowManualEntry: false,
30878
+ ui: { intent: "behavior" }
30879
+ },
30880
+ {
30881
+ id: "contactSubmitLabel",
30882
+ type: "text",
30883
+ label: "Contact button label",
30884
+ defaultValue: "Send message",
30885
+ ui: { intent: "display" }
30886
+ },
30887
+ {
30888
+ id: "contactSuccessMessage",
30889
+ type: "text",
30890
+ label: "Contact success message",
30891
+ defaultValue: "Thanks - we received your message.",
30892
+ ui: { intent: "behavior" }
30893
+ }
30894
+ ],
30895
+ styleTokens: {
30896
+ background: "surface",
30897
+ typography: "body",
30898
+ spacing: "md"
30899
+ },
30900
+ behaviours: {
30901
+ supportsThemeSwitching: true,
30902
+ inlineEditing: true,
30903
+ animation: false,
30904
+ paletteHidden: false
30905
+ },
30906
+ tags: [
30907
+ "contact",
30908
+ "newsletter",
30909
+ "signup",
30910
+ "email",
30911
+ "form",
30912
+ "lead-capture"
30913
+ ],
30914
+ icon: "MailPlus"
30915
+ });
30916
+ var contactNewsletterBlockDefinition = {
30917
+ manifest: contactNewsletterManifest,
30918
+ dataSchemas: { form: formDataSchema.optional() },
30919
+ dataLoaders: {
30920
+ form: {
30921
+ endpoint: "getPublicFormById",
30922
+ params: {
30923
+ formSlug: { $bind: { from: "formSlug" } }
30924
+ },
30925
+ mode: "server"
30926
+ }
30927
+ }
30928
+ };
30929
+
29525
30930
  // ../blocks/src/system/blocks/faq.ts
29526
30931
  init_fragments();
29527
30932
  init_styledSection();
@@ -29762,6 +31167,7 @@ var joinClasses3 = (parts) => parts.filter(
29762
31167
  ).join(" ").replace(/\s+/g, " ").trim();
29763
31168
  var eyebrowTreatmentClassMap = {
29764
31169
  plain: "",
31170
+ accent: "rb-eyebrow-treatment-accent",
29765
31171
  pill: "rb-eyebrow-treatment-pill",
29766
31172
  "accent-pill": "rb-eyebrow-treatment-pill rb-eyebrow-treatment-accent",
29767
31173
  "pill-bounce": "rb-eyebrow-treatment-pill rb-eyebrow-treatment-pill-bounce",
@@ -29788,6 +31194,13 @@ var imageGalleryCornerClassMap = {
29788
31194
  "2xl": "rb-rounded-2xl",
29789
31195
  "3xl": "rb-rounded-3xl"
29790
31196
  };
31197
+ var imageShapeClassMap = {
31198
+ default: "",
31199
+ square: "rb-media-shape-square",
31200
+ rounded: "rb-media-shape-rounded",
31201
+ circle: "rb-media-shape-circle",
31202
+ arch: "rb-media-shape-arch"
31203
+ };
29791
31204
  var parseRatio = (raw) => {
29792
31205
  if (typeof raw !== "string") return null;
29793
31206
  const value = raw.trim();
@@ -29932,6 +31345,10 @@ function resolveHeroContentMaxWidth(content) {
29932
31345
  return "default";
29933
31346
  }
29934
31347
  function resolveHeroTypographyScale(content) {
31348
+ const titleSize = readString(content, "titleSize");
31349
+ if (titleSize === "quiet" || titleSize === "editorial" || titleSize === "display" || titleSize === "poster") {
31350
+ return titleSize;
31351
+ }
29935
31352
  const raw = readHeroLayoutString(
29936
31353
  content,
29937
31354
  "typographyScale",
@@ -30173,6 +31590,16 @@ var uiTransforms = [
30173
31590
  heroGridClassFromVerticalAlignmentTransform,
30174
31591
  imageFragmentClassTransform,
30175
31592
  imageFragmentSizeTransform,
31593
+ {
31594
+ id: "ui.imageShapeClassName",
31595
+ kind: "string",
31596
+ summary: "Apply a constrained media shape class",
31597
+ run: (value, options) => {
31598
+ const baseClass = typeof options?.baseClass === "string" ? options.baseClass : "";
31599
+ const shape = typeof value === "string" ? value.trim() : "default";
31600
+ return joinClasses3([baseClass, imageShapeClassMap[shape] ?? ""]);
31601
+ }
31602
+ },
30176
31603
  conditionalClassTransform,
30177
31604
  twoColumnContainerClassTransform,
30178
31605
  twoColumnFlexBasisTransform,
@@ -31514,6 +32941,21 @@ var siteHeaderManifest = createBlockManifest({
31514
32941
  id: "block.site-header",
31515
32942
  title: "Site Header",
31516
32943
  category: "layout",
32944
+ additionalFields: [
32945
+ {
32946
+ id: "mode",
32947
+ type: "select",
32948
+ label: "Header display",
32949
+ required: false,
32950
+ multiple: false,
32951
+ defaultValue: "default",
32952
+ options: [
32953
+ { value: "default", label: "Show header" },
32954
+ { value: "hidden", label: "Hide header" }
32955
+ ],
32956
+ ui: { intent: "display" }
32957
+ }
32958
+ ],
31517
32959
  // Skip section styles - this block uses theme-based styling
31518
32960
  skipSectionStyles: true,
31519
32961
  // Block manages its own wrapper - enables sticky positioning
@@ -32960,6 +34402,9 @@ var mediaTextManifest = createBlockManifest({
32960
34402
  category: "layout",
32961
34403
  includeContainerStyles: true,
32962
34404
  titleSource: "title",
34405
+ previewCustomize: {
34406
+ quickFieldPriority: ["imagePosition", "ratio", "imageShape", "titleAlignment", "aspectRatio"]
34407
+ },
32963
34408
  additionalFields: [
32964
34409
  {
32965
34410
  id: "images",
@@ -32998,7 +34443,7 @@ var mediaTextManifest = createBlockManifest({
32998
34443
  {
32999
34444
  id: "titleAlignment",
33000
34445
  type: "select",
33001
- label: "Title alignment",
34446
+ label: "Content alignment",
33002
34447
  required: false,
33003
34448
  defaultValue: "left",
33004
34449
  multiple: false,
@@ -33056,7 +34501,18 @@ var mediaTextManifest = createBlockManifest({
33056
34501
  transition: "slide"
33057
34502
  },
33058
34503
  ui: { intent: "behavior" }
33059
- }),
34504
+ }).map((field) => ({
34505
+ ...field,
34506
+ ui: {
34507
+ ...field.ui ?? {},
34508
+ visibleWhen: field.id === "carouselAutoplayDelay" ? {
34509
+ allOf: [
34510
+ { field: "images", minItems: 2 },
34511
+ { field: "carouselAutoplay", equals: true }
34512
+ ]
34513
+ } : { field: "images", minItems: 2 }
34514
+ }
34515
+ })),
33060
34516
  createAspectRatioField({
33061
34517
  id: "aspectRatio",
33062
34518
  label: "Media aspect ratio",
@@ -33064,6 +34520,12 @@ var mediaTextManifest = createBlockManifest({
33064
34520
  defaultValue: "auto",
33065
34521
  visibleWhen: { field: "images", notEquals: null }
33066
34522
  }),
34523
+ createImageShapeField({
34524
+ id: "imageShape",
34525
+ label: "Media shape",
34526
+ defaultValue: "default",
34527
+ visibleWhen: { field: "images", notEquals: null }
34528
+ }),
33067
34529
  {
33068
34530
  id: "text",
33069
34531
  type: "richText",
@@ -33097,6 +34559,30 @@ var mediaTextManifest = createBlockManifest({
33097
34559
  ...options?.not ? { not: true } : {}
33098
34560
  }
33099
34561
  });
34562
+ const bodyClassNameFromAlignment = {
34563
+ $bind: {
34564
+ from: "content.titleAlignment",
34565
+ transforms: [
34566
+ {
34567
+ id: "ui.bodyClassFromAlignment",
34568
+ options: { base: "rb-prose rb-max-w-none" }
34569
+ }
34570
+ ],
34571
+ fallback: "rb-prose rb-max-w-none"
34572
+ }
34573
+ };
34574
+ const titleClassNameFromAlignment = {
34575
+ $bind: {
34576
+ from: "content.titleAlignment",
34577
+ transforms: [
34578
+ {
34579
+ id: "ui.headingClassFromAlignment",
34580
+ options: { base: "" }
34581
+ }
34582
+ ],
34583
+ fallback: ""
34584
+ }
34585
+ };
33100
34586
  const defaultTextColumn = el("div", {}, [
33101
34587
  styledCard(
33102
34588
  [
@@ -33121,8 +34607,55 @@ var mediaTextManifest = createBlockManifest({
33121
34607
  bind("content.text")
33122
34608
  )
33123
34609
  ]);
34610
+ const bioTextColumn = el(
34611
+ "div",
34612
+ { className: "rb-flex rb-h-full rb-w-full rb-max-w-prose rb-flex-col rb-justify-center rb-gap-5" },
34613
+ [
34614
+ text(
34615
+ {
34616
+ as: "h2",
34617
+ className: titleClassNameFromAlignment
34618
+ },
34619
+ when("content.title"),
34620
+ bind("content.title")
34621
+ ),
34622
+ styledCard(
34623
+ [
34624
+ richText(
34625
+ {
34626
+ className: bodyClassNameFromAlignment
34627
+ },
34628
+ bind("content.text")
34629
+ )
34630
+ ],
34631
+ {
34632
+ stylesFrom: "content._textCardStyles",
34633
+ backgroundFrom: "content._textCardStyles.background"
34634
+ },
34635
+ when("content.wrapTextInCard")
34636
+ ),
34637
+ richText(
34638
+ {
34639
+ className: bodyClassNameFromAlignment
34640
+ },
34641
+ when("content.wrapTextInCard", { not: true }),
34642
+ bind("content.text")
34643
+ )
34644
+ ]
34645
+ );
33124
34646
  const defaultImageCommonProps = {
33125
- className: "rb-w-full rb-h-auto rb-object-cover",
34647
+ className: {
34648
+ $bind: {
34649
+ from: "content.imageShape",
34650
+ transforms: [
34651
+ {
34652
+ id: "ui.imageShapeClassName",
34653
+ options: { baseClass: "rb-w-full rb-h-auto rb-object-cover" }
34654
+ }
34655
+ ],
34656
+ fallback: "rb-w-full rb-h-auto rb-object-cover"
34657
+ }
34658
+ },
33126
34659
  style: {
33127
34660
  aspectRatio: { $bind: { from: "content.aspectRatio" } }
33128
34661
  }
@@ -33163,6 +34696,27 @@ var mediaTextManifest = createBlockManifest({
33163
34696
  ],
33164
34697
  whenImagesLength(0, { not: true })
33165
34698
  );
34699
+ const bioImagesLayout = el(
34700
+ "div",
34701
+ {},
34702
+ [
34703
+ responsiveTwoColumn({
34704
+ image: el("div", {}, [
34705
+ el("div", {}, [defaultSingleImage], whenImagesLength(1)),
34706
+ el("div", {}, [defaultCarouselImages], whenImagesLength(1, { not: true }))
34707
+ ]),
34708
+ text: bioTextColumn,
34709
+ ratioFrom: "content.ratio",
34710
+ imagePositionFrom: "content.imagePosition",
34711
+ containerClassName: "rb-flex rb-flex-col rb-md-flex-row rb-md-items-center",
34712
+ gapFrom: "content.gap",
34713
+ gapFallback: "comfortable",
34714
+ imageWrapperClassName: "rb-w-full rb-shrink-0",
34715
+ textWrapperClassName: "rb-w-full rb-min-w-0 rb-flex-1 rb-self-stretch"
34716
+ })
34717
+ ],
34718
+ whenImagesLength(0, { not: true })
34719
+ );
33166
34720
  const defaultTextOnlyLayout = el(
33167
34721
  "div",
33168
34722
  {},
@@ -33192,7 +34746,45 @@ var mediaTextManifest = createBlockManifest({
33192
34746
  ],
33193
34747
  whenImagesLength(0)
33194
34748
  );
34749
+ const bioTextOnlyLayout = el(
34750
+ "div",
34751
+ { className: "rb-flex rb-w-full rb-max-w-prose rb-flex-col rb-gap-5" },
34752
+ [
34753
+ text(
34754
+ {
34755
+ as: "h2",
34756
+ className: titleClassNameFromAlignment
34757
+ },
34758
+ when("content.title"),
34759
+ bind("content.title")
34760
+ ),
34761
+ styledCard(
34762
+ [
34763
+ richText(
34764
+ {
34765
+ className: bodyClassNameFromAlignment
34766
+ },
34767
+ bind("content.text")
34768
+ )
34769
+ ],
34770
+ {
34771
+ stylesFrom: "content._textCardStyles",
34772
+ backgroundFrom: "content._textCardStyles.background"
34773
+ },
34774
+ when("content.wrapTextInCard")
34775
+ ),
34776
+ richText(
34777
+ {
34778
+ className: bodyClassNameFromAlignment
34779
+ },
34780
+ when("content.wrapTextInCard", { not: true }),
34781
+ bind("content.text")
34782
+ )
34783
+ ],
34784
+ whenImagesLength(0)
34785
+ );
33195
34786
  const defaultInner = el("div", {}, [defaultImagesLayout, defaultTextOnlyLayout]);
34787
+ const bioInner = el("div", {}, [bioImagesLayout, bioTextOnlyLayout]);
33196
34788
  const defaultLayout2 = styledSection({
33197
34789
  children: styledContainer({
33198
34790
  rootType: "stack",
@@ -33201,18 +34793,7 @@ var mediaTextManifest = createBlockManifest({
33201
34793
  text(
33202
34794
  {
33203
34795
  as: "h2",
33204
- className: {
33205
- $bind: {
33206
- from: "content.titleAlignment",
33207
- transforms: [
33208
- {
33209
- id: "ui.headingClassFromAlignment",
33210
- options: { base: "" }
33211
- }
33212
- ],
33213
- fallback: ""
33214
- }
33215
- }
34796
+ className: titleClassNameFromAlignment
33216
34797
  },
33217
34798
  when("content.title"),
33218
34799
  bind("content.title")
@@ -33224,14 +34805,28 @@ var mediaTextManifest = createBlockManifest({
33224
34805
  baseClass: "",
33225
34806
  spacing: "medium"
33226
34807
  });
34808
+ const bioLayout = styledSection({
34809
+ children: styledContainer({
34810
+ rootType: "stack",
34811
+ rootProps: { gap: "lg" },
34812
+ children: [bioInner]
34813
+ }),
34814
+ baseClass: "",
34815
+ spacing: "medium"
34816
+ });
33227
34817
  return {
33228
34818
  layout: defaultLayout2,
33229
34819
  variants: {
33230
- default: defaultLayout2
34820
+ default: defaultLayout2,
34821
+ bio: bioLayout
33231
34822
  },
33232
34823
  defaultVariant: "default",
33233
34824
  variantOptions: {
33234
- default: { label: "Default" }
34825
+ default: { label: "Default" },
34826
+ bio: {
34827
+ label: "Bio",
34828
+ description: "Vertically centered title and copy beside media."
34829
+ }
33235
34830
  }
33236
34831
  };
33237
34832
  })(),
@@ -35046,7 +36641,7 @@ function inferLegacyOfferingsPreviewGroupOrder(overrides) {
35046
36641
  return keys.length >= 2 ? keys : [];
35047
36642
  }
35048
36643
  function normalizeOfferingsPreviewContentForWrite(value) {
35049
- if (!isRecord4(value)) return null;
36644
+ if (!isRecord6(value)) return null;
35050
36645
  const groupOrderValue = value.groupOrder;
35051
36646
  if (Array.isArray(groupOrderValue)) {
35052
36647
  const normalized = normalizeOfferingsPreviewGroupOrder(groupOrderValue);
@@ -35059,7 +36654,7 @@ function normalizeOfferingsPreviewContentForWrite(value) {
35059
36654
  return { ...value, groupOrder: [] };
35060
36655
  }
35061
36656
  const legacyOrder = inferLegacyOfferingsPreviewGroupOrder(
35062
- Array.isArray(value.groupOverrides) ? value.groupOverrides.filter(isRecord4) : []
36657
+ Array.isArray(value.groupOverrides) ? value.groupOverrides.filter(isRecord6) : []
35063
36658
  );
35064
36659
  return legacyOrder.length > 0 ? { ...value, groupOrder: legacyOrder } : value;
35065
36660
  }
@@ -35073,7 +36668,7 @@ function uniqueOfferingsPreviewSourceKeys(values) {
35073
36668
  }
35074
36669
  return keys;
35075
36670
  }
35076
- function isRecord4(value) {
36671
+ function isRecord6(value) {
35077
36672
  return typeof value === "object" && value !== null && !Array.isArray(value);
35078
36673
  }
35079
36674
 
@@ -35440,7 +37035,7 @@ function isOfferingsPreviewItemLimit(value) {
35440
37035
  return value === "1" || value === "2" || value === "3" || value === "4" || value === "5" || value === "6" || value === null;
35441
37036
  }
35442
37037
  function normalizeOfferingsPreviewGroupOverride(value) {
35443
- if (!isRecord5(value)) return [];
37038
+ if (!isRecord7(value)) return [];
35444
37039
  const override = {};
35445
37040
  if (isOfferingsPreviewSourceKey(value.sourceKey) || value.sourceKey === null) {
35446
37041
  override.sourceKey = value.sourceKey;
@@ -35472,12 +37067,12 @@ function isButtonVariant(value) {
35472
37067
  return value === "primary" || value === "secondary" || value === "outline" || value === "link" || value === null;
35473
37068
  }
35474
37069
  function normalizeCardStylesContent(value) {
35475
- return isRecord5(value) || value === null ? value : void 0;
37070
+ return isRecord7(value) || value === null ? value : void 0;
35476
37071
  }
35477
37072
  function normalizeSectionStylesContent(value) {
35478
- return isRecord5(value) || value === null ? value : void 0;
37073
+ return isRecord7(value) || value === null ? value : void 0;
35479
37074
  }
35480
- function isRecord5(value) {
37075
+ function isRecord7(value) {
35481
37076
  return typeof value === "object" && value !== null && !Array.isArray(value);
35482
37077
  }
35483
37078
 
@@ -38386,11 +39981,13 @@ var heroImageSurfaceMotions = [
38386
39981
  ];
38387
39982
  var standardEyebrowTreatments = [
38388
39983
  "plain",
39984
+ "accent",
38389
39985
  "pill",
38390
39986
  "accent-pill"
38391
39987
  ];
38392
39988
  var animatedEyebrowTreatments = [
38393
39989
  "plain",
39990
+ "accent",
38394
39991
  "pill",
38395
39992
  "accent-pill",
38396
39993
  "pill-bounce",
@@ -38691,6 +40288,17 @@ var systemBlockDefinitionsRaw = [
38691
40288
  layoutProfile({ variantKey: "two-column", family: "split", weight: "standard" })
38692
40289
  ]
38693
40290
  })),
40291
+ withDesignCapability("block.contact-newsletter", contactNewsletterBlockDefinition, sectionOnly(), defineBlockDesignMetadata({
40292
+ flow: conversionFlow,
40293
+ layoutProfiles: [
40294
+ layoutProfile({
40295
+ variantKey: "default",
40296
+ family: "split",
40297
+ weight: "featured",
40298
+ bias: "soft"
40299
+ })
40300
+ ]
40301
+ })),
38694
40302
  withDesignCapability("block.faq", faqBlockDefinition, withEyebrowCapability(declareBlockDesignCapability({
38695
40303
  sectionSurfaces: "supported",
38696
40304
  contentFrames: ["plain", "panel"],
@@ -38782,6 +40390,12 @@ var systemBlockDefinitionsRaw = [
38782
40390
  family: "media-text",
38783
40391
  weight: "featured",
38784
40392
  bias: "soft"
40393
+ }),
40394
+ layoutProfile({
40395
+ variantKey: "bio",
40396
+ family: "media-text",
40397
+ weight: "featured",
40398
+ bias: "soft"
38785
40399
  })
38786
40400
  ]
38787
40401
  })),
@@ -39617,6 +41231,7 @@ init_colorStyles();
39617
41231
  // ../theme-core/src/inputs/generateInputCss.ts
39618
41232
  init_types9();
39619
41233
  init_constants();
41234
+ init_colorStyles();
39620
41235
 
39621
41236
  // ../theme-core/src/header/generateHeaderCss.ts
39622
41237
  init_resolver();
@@ -39653,6 +41268,11 @@ ${root} {
39653
41268
  --er-event-card-bg: rgb(var(--tb-surface));
39654
41269
  --er-event-card-border-width: var(--rb-border-width, 1px);
39655
41270
  --er-event-card-hover-opacity: 1;
41271
+ --er-control-bg: rgb(var(--tb-background, var(--tb-surface)));
41272
+ --er-control-text: rgb(var(--tb-foreground, var(--tb-text)));
41273
+ --er-radius: var(--rb-block-radius);
41274
+ --er-surface-muted: rgba(var(--tb-muted, 241 245 249), 0.42);
41275
+ --er-shell-line: rgba(var(--tb-mutedText, 100 116 139), 0.22);
39656
41276
 
39657
41277
  /* Step indicator */
39658
41278
  --er-step-active: rgb(var(--tb-primary));
@@ -41250,7 +42870,7 @@ function preset(id, verticalId, canonicalBehaviour, label, pluralLabel, descript
41250
42870
  }
41251
42871
 
41252
42872
  // ../api/src/utils/isRecord.ts
41253
- function isRecord6(value) {
42873
+ function isRecord8(value) {
41254
42874
  return typeof value === "object" && value !== null && !Array.isArray(value);
41255
42875
  }
41256
42876
  var APPOINTMENT_SETUP_MAX_MINUTES = 1440;
@@ -41388,11 +43008,11 @@ siteBannerSettingsSchema.superRefine((value, ctx) => {
41388
43008
  return;
41389
43009
  }
41390
43010
  const analysis = analyzeSiteBannerBody(value.body);
41391
- for (const issue2 of analysis.issues) {
43011
+ for (const issue4 of analysis.issues) {
41392
43012
  ctx.addIssue({
41393
43013
  code: z.ZodIssueCode.custom,
41394
43014
  path: ["body"],
41395
- message: siteBannerBodyIssueMessage(issue2)
43015
+ message: siteBannerBodyIssueMessage(issue4)
41396
43016
  });
41397
43017
  }
41398
43018
  });
@@ -41426,8 +43046,8 @@ function analyzeSiteBannerBody(body) {
41426
43046
  issues
41427
43047
  };
41428
43048
  }
41429
- function siteBannerBodyIssueMessage(issue2) {
41430
- switch (issue2) {
43049
+ function siteBannerBodyIssueMessage(issue4) {
43050
+ switch (issue4) {
41431
43051
  case "empty":
41432
43052
  return "Banner message is required when the banner is enabled.";
41433
43053
  case "too-many-paragraphs":
@@ -41523,7 +43143,7 @@ function sanitizeMarks(marks) {
41523
43143
  if (mark.type === "bold" || mark.type === "strong" || mark.type === "italic" || mark.type === "em") {
41524
43144
  return [{ type: mark.type }];
41525
43145
  }
41526
- if (mark.type === "link" && isRecord6(mark.attrs) && typeof mark.attrs.href === "string") {
43146
+ if (mark.type === "link" && isRecord8(mark.attrs) && typeof mark.attrs.href === "string") {
41527
43147
  const attrs = { href: mark.attrs.href };
41528
43148
  if (typeof mark.attrs.target === "string" && mark.attrs.target.trim().length > 0) {
41529
43149
  attrs.target = mark.attrs.target;
@@ -41538,10 +43158,10 @@ function sanitizeMarks(marks) {
41538
43158
  return sanitized.length > 0 ? sanitized : void 0;
41539
43159
  }
41540
43160
  function unwrapRichTextValue(value) {
41541
- if (isRecord6(value) && isRecord6(value.doc)) {
43161
+ if (isRecord8(value) && isRecord8(value.doc)) {
41542
43162
  return unwrapRichTextValue(value.doc);
41543
43163
  }
41544
- if (isRecord6(value) && value.type === "doc") {
43164
+ if (isRecord8(value) && value.type === "doc") {
41545
43165
  return {
41546
43166
  type: "doc",
41547
43167
  content: Array.isArray(value.content) ? value.content.filter(isTipTapNodeLike).map(coerceTipTapNode) : []
@@ -41550,7 +43170,7 @@ function unwrapRichTextValue(value) {
41550
43170
  return EMPTY_SITE_BANNER_BODY;
41551
43171
  }
41552
43172
  function isTipTapNodeLike(value) {
41553
- return isRecord6(value) && typeof value.type === "string";
43173
+ return isRecord8(value) && typeof value.type === "string";
41554
43174
  }
41555
43175
  function coerceTipTapNode(value) {
41556
43176
  return {
@@ -41558,9 +43178,9 @@ function coerceTipTapNode(value) {
41558
43178
  ...Array.isArray(value.content) ? { content: value.content.filter(isTipTapNodeLike).map(coerceTipTapNode) } : {},
41559
43179
  ...typeof value.text === "string" ? { text: value.text } : {},
41560
43180
  ...Array.isArray(value.marks) ? {
41561
- marks: value.marks.filter((mark) => isRecord6(mark) && typeof mark.type === "string").map((mark) => ({
43181
+ marks: value.marks.filter((mark) => isRecord8(mark) && typeof mark.type === "string").map((mark) => ({
41562
43182
  type: mark.type,
41563
- ...isRecord6(mark.attrs) ? { attrs: mark.attrs } : {}
43183
+ ...isRecord8(mark.attrs) ? { attrs: mark.attrs } : {}
41564
43184
  }))
41565
43185
  } : {}
41566
43186
  };
@@ -41676,7 +43296,7 @@ function collectCartLinkStats(items, depth = 0) {
41676
43296
  return result;
41677
43297
  }
41678
43298
  function isNavigationMenuValidationItem(value) {
41679
- if (!isRecord6(value)) return false;
43299
+ if (!isRecord8(value)) return false;
41680
43300
  return typeof value.label === "string";
41681
43301
  }
41682
43302
 
@@ -41901,6 +43521,7 @@ var SYSTEM_BLOCK_KINDS = [
41901
43521
  "block.site-footer",
41902
43522
  // Form/booking blocks
41903
43523
  "block.form",
43524
+ "block.contact-newsletter",
41904
43525
  "block.appointment-booking",
41905
43526
  "block.event-registration",
41906
43527
  "block.event-details",
@@ -42109,7 +43730,7 @@ var fieldBindingSchema = z.object({
42109
43730
  var metaBindingSchema = z.object({
42110
43731
  source: z.literal("meta"),
42111
43732
  path: z.enum(TEMPLATE_BINDING_META_PATHS, {
42112
- error: (issue2) => describeInvalidTemplateBindingMetaPath(String(issue2.input))
43733
+ error: (issue4) => describeInvalidTemplateBindingMetaPath(String(issue4.input))
42113
43734
  })
42114
43735
  });
42115
43736
  var literalBindingSchema = z.object({
@@ -42120,7 +43741,7 @@ var transformBindingSchema = z.object({
42120
43741
  source: z.literal("transform"),
42121
43742
  path: z.string().min(1, "Transform path is required"),
42122
43743
  transform: z.enum(BINDING_TRANSFORM_VALUES, {
42123
- error: (issue2) => describeInvalidBindingTransform(String(issue2.input))
43744
+ error: (issue4) => describeInvalidBindingTransform(String(issue4.input))
42124
43745
  })
42125
43746
  });
42126
43747
  var baseBindingSchema = z.discriminatedUnion("source", [
@@ -42924,20 +44545,20 @@ var ManagementApiError = class extends Error {
42924
44545
  function is404Error(error) {
42925
44546
  return error instanceof ManagementApiError && error.statusCode === 404;
42926
44547
  }
42927
- function isRecord7(value) {
44548
+ function isRecord9(value) {
42928
44549
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
42929
44550
  }
42930
44551
  function isFieldError(value) {
42931
- return isRecord7(value) && typeof value.field === "string" && typeof value.code === "string" && typeof value.message === "string";
44552
+ return isRecord9(value) && typeof value.field === "string" && typeof value.code === "string" && typeof value.message === "string";
42932
44553
  }
42933
44554
  function parseApiResponse(value) {
42934
- if (!isRecord7(value)) return null;
44555
+ if (!isRecord9(value)) return null;
42935
44556
  if (value.success === true) {
42936
44557
  return { success: true, data: value.data };
42937
44558
  }
42938
44559
  if (value.success === false) {
42939
44560
  const error = value.error;
42940
- if (!isRecord7(error) || typeof error.code !== "string" || typeof error.message !== "string") {
44561
+ if (!isRecord9(error) || typeof error.code !== "string" || typeof error.message !== "string") {
42941
44562
  return { success: false, error: { code: "sdk:http-error", message: "Request failed", details: error } };
42942
44563
  }
42943
44564
  const fieldErrorsRaw = error.fieldErrors;
@@ -44174,8 +45795,8 @@ function mapEntryForOutput(entry) {
44174
45795
  data: entry.data,
44175
45796
  status: entry.status,
44176
45797
  hasUnpublishedChanges: entry.hasUnpublishedChanges,
44177
- title: entry.title,
44178
- manualOrder: entry.manualOrder
45798
+ manualOrder: entry.manualOrder,
45799
+ blocks: entry.blocks
44179
45800
  };
44180
45801
  if (entry.slug !== void 0) {
44181
45802
  result.slug = entry.slug;
@@ -44466,7 +46087,7 @@ function createListCommand(config2) {
44466
46087
 
44467
46088
  // src/cli/push-config.ts
44468
46089
  var DEFAULT_CONFIG_PATH = "./riverbank.config.ts";
44469
- function isRecord8(value) {
46090
+ function isRecord10(value) {
44470
46091
  return typeof value === "object" && value !== null;
44471
46092
  }
44472
46093
  function parseErrorDetails(value) {
@@ -44474,10 +46095,10 @@ function parseErrorDetails(value) {
44474
46095
  if (typeof value === "string") {
44475
46096
  return { message: value };
44476
46097
  }
44477
- if (!isRecord8(value)) return {};
46098
+ if (!isRecord10(value)) return {};
44478
46099
  const message = typeof value.message === "string" ? value.message : void 0;
44479
46100
  const fieldErrorsRaw = value.fieldErrors;
44480
- const fieldErrors = Array.isArray(fieldErrorsRaw) ? fieldErrorsRaw.filter(isRecord8).map((d) => ({
46101
+ const fieldErrors = Array.isArray(fieldErrorsRaw) ? fieldErrorsRaw.filter(isRecord10).map((d) => ({
44481
46102
  field: typeof d.field === "string" ? d.field : "",
44482
46103
  message: typeof d.message === "string" ? d.message : ""
44483
46104
  })).filter((d) => d.field.length > 0 && d.message.length > 0) : void 0;
@@ -44489,12 +46110,12 @@ function formatFieldErrors(fieldErrors) {
44489
46110
  }
44490
46111
  function getDashboardErrorMessage(responseJson, fallback) {
44491
46112
  if (!responseJson) return fallback;
44492
- if (isRecord8(responseJson) && responseJson.success === false && "error" in responseJson) {
46113
+ if (isRecord10(responseJson) && responseJson.success === false && "error" in responseJson) {
44493
46114
  const parsed = parseErrorDetails(responseJson.error);
44494
46115
  const msg = parsed.message ?? fallback;
44495
46116
  return msg + formatFieldErrors(parsed.fieldErrors);
44496
46117
  }
44497
- if (isRecord8(responseJson) && "error" in responseJson) {
46118
+ if (isRecord10(responseJson) && "error" in responseJson) {
44498
46119
  const parsed = parseErrorDetails(responseJson.error);
44499
46120
  const msg = parsed.message ?? fallback;
44500
46121
  return msg + formatFieldErrors(parsed.fieldErrors);
@@ -44613,9 +46234,9 @@ async function pushConfigAction(output, options) {
44613
46234
  const parseResult = riverbankSiteConfigSchema.safeParse(rawConfig);
44614
46235
  if (!parseResult.success) {
44615
46236
  output.error("Invalid config", {
44616
- issues: parseResult.error.issues.map((issue2) => ({
44617
- path: issue2.path.join("."),
44618
- message: issue2.message
46237
+ issues: parseResult.error.issues.map((issue4) => ({
46238
+ path: issue4.path.join("."),
46239
+ message: issue4.message
44619
46240
  }))
44620
46241
  });
44621
46242
  }
@@ -44819,7 +46440,7 @@ function duplicateNavigationIdentityMessage(error) {
44819
46440
 
44820
46441
  // src/cli/media/portable.ts
44821
46442
  var ENV_SPECIFIC_MEDIA_KEYS = ["assetId", "storagePath", "storageBucket"];
44822
- var isRecord9 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
46443
+ var isRecord11 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
44823
46444
  var isMediaObject = (value) => value.type === "image" || value.type === "video";
44824
46445
  function stripEnvSpecificMediaFieldsInPlace(value) {
44825
46446
  if (value === null || value === void 0) return;
@@ -44829,7 +46450,7 @@ function stripEnvSpecificMediaFieldsInPlace(value) {
44829
46450
  }
44830
46451
  return;
44831
46452
  }
44832
- if (!isRecord9(value)) return;
46453
+ if (!isRecord11(value)) return;
44833
46454
  if (isMediaObject(value)) {
44834
46455
  const hasCmsRef = typeof value.identifier === "string" || typeof value.assetId === "string" || typeof value.storagePath === "string" || typeof value.storageBucket === "string";
44835
46456
  for (const key of ENV_SPECIFIC_MEDIA_KEYS) {
@@ -44840,7 +46461,7 @@ function stripEnvSpecificMediaFieldsInPlace(value) {
44840
46461
  }
44841
46462
  delete value.mimeType;
44842
46463
  }
44843
- if (value.type === "image" && isRecord9(value.attrs)) {
46464
+ if (value.type === "image" && isRecord11(value.attrs)) {
44844
46465
  const attrs = value.attrs;
44845
46466
  const hasIdentifier = typeof attrs.identifier === "string" && attrs.identifier.trim().length > 0;
44846
46467
  if (hasIdentifier) {
@@ -44905,7 +46526,8 @@ function pulledEntryToLocalEntry(entry) {
44905
46526
  data: entry.data,
44906
46527
  status: entry.status,
44907
46528
  hasUnpublishedChanges: entry.hasUnpublishedChanges,
44908
- ...entry.slug !== void 0 ? { slug: entry.slug } : {}
46529
+ ...entry.slug !== void 0 ? { slug: entry.slug } : {},
46530
+ ...entry.blocks !== void 0 ? { blocks: entry.blocks } : {}
44909
46531
  };
44910
46532
  }
44911
46533
 
@@ -45011,11 +46633,11 @@ function entryFilePath(input) {
45011
46633
  }
45012
46634
 
45013
46635
  // src/cli/content/writer.ts
45014
- function isRecord10(value) {
46636
+ function isRecord12(value) {
45015
46637
  return typeof value === "object" && value !== null && !Array.isArray(value);
45016
46638
  }
45017
46639
  function parseThemeMeta(value) {
45018
- if (!isRecord10(value) || typeof value.pulledAt !== "string" || !isRecord10(value.themes)) {
46640
+ if (!isRecord12(value) || typeof value.pulledAt !== "string" || !isRecord12(value.themes)) {
45019
46641
  return null;
45020
46642
  }
45021
46643
  return { pulledAt: value.pulledAt, themes: value.themes };
@@ -45627,7 +47249,9 @@ async function readEntries(contentDir, contentType) {
45627
47249
  const items = await fs5.readdir(entriesDir, { withFileTypes: true });
45628
47250
  for (const item of items) {
45629
47251
  if (item.isDirectory()) {
45630
- const entries = await readEntriesFromDirectory(path5.join(entriesDir, item.name));
47252
+ const entries = await readEntriesFromDirectory(
47253
+ path5.join(entriesDir, item.name)
47254
+ );
45631
47255
  await applyManualOrderMetadata(contentDir, item.name, entries);
45632
47256
  if (entries.length > 0) {
45633
47257
  result.set(item.name, entries);
@@ -45644,7 +47268,9 @@ async function applyManualOrderMetadata(contentDir, contentType, entries) {
45644
47268
  const meta = await readEntriesMeta(contentDir, contentType);
45645
47269
  const order = meta?.manualOrder;
45646
47270
  if (!order?.length) return;
45647
- const orderByIdentifier = new Map(order.map((identifier, index) => [identifier, index]));
47271
+ const orderByIdentifier = new Map(
47272
+ order.map((identifier, index) => [identifier, index])
47273
+ );
45648
47274
  for (const entry of entries) {
45649
47275
  const manualOrder = orderByIdentifier.get(entry.identifier);
45650
47276
  if (manualOrder !== void 0) {
@@ -45689,7 +47315,9 @@ async function readSettings(contentDir) {
45689
47315
  if (!parsed.success) {
45690
47316
  throw new Error(
45691
47317
  `${filePath}: invalid settings.json
45692
- ` + parsed.error.issues.map((issue2) => ` - ${issue2.path.join(".") || "(root)"}: ${issue2.message}`).join("\n")
47318
+ ` + parsed.error.issues.map(
47319
+ (issue4) => ` - ${issue4.path.join(".") || "(root)"}: ${issue4.message}`
47320
+ ).join("\n")
45693
47321
  );
45694
47322
  }
45695
47323
  return parsed.data;
@@ -45809,7 +47437,18 @@ async function readFooter(contentDir) {
45809
47437
  return raw;
45810
47438
  }
45811
47439
  async function readAllContent(contentDir) {
45812
- const [entries, pages, navigation, settings, forms, footer, venues, eventCategories, events, courses] = await Promise.all([
47440
+ const [
47441
+ entries,
47442
+ pages,
47443
+ navigation,
47444
+ settings,
47445
+ forms,
47446
+ footer,
47447
+ venues,
47448
+ eventCategories,
47449
+ events,
47450
+ courses
47451
+ ] = await Promise.all([
45813
47452
  readEntries(contentDir),
45814
47453
  readPages(contentDir),
45815
47454
  readNavigation(contentDir),
@@ -45821,7 +47460,18 @@ async function readAllContent(contentDir) {
45821
47460
  readEvents(contentDir),
45822
47461
  readCourses(contentDir)
45823
47462
  ]);
45824
- return { entries, pages, navigation, settings, forms, footer, venues, eventCategories, events, courses };
47463
+ return {
47464
+ entries,
47465
+ pages,
47466
+ navigation,
47467
+ settings,
47468
+ forms,
47469
+ footer,
47470
+ venues,
47471
+ eventCategories,
47472
+ events,
47473
+ courses
47474
+ };
45825
47475
  }
45826
47476
  async function contentDirExists(contentDir) {
45827
47477
  return fileExists(contentDir);
@@ -46401,9 +48051,9 @@ async function localMediaFileExists(filePath) {
46401
48051
  }
46402
48052
 
46403
48053
  // src/cli/media/identifiers.ts
46404
- var isRecord11 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
48054
+ var isRecord13 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
46405
48055
  var isMediaValue = (value) => {
46406
- if (!isRecord11(value)) return false;
48056
+ if (!isRecord13(value)) return false;
46407
48057
  const type = value.type;
46408
48058
  if (type !== "image" && type !== "video" && type !== "audio" && type !== "document" && type !== "spreadsheet" && type !== "archive") return false;
46409
48059
  return typeof value.identifier === "string" || typeof value.assetId === "string" || typeof value.storagePath === "string" || typeof value.src === "string";
@@ -46418,7 +48068,7 @@ var walkMediaValues = (value, location2, handler) => {
46418
48068
  });
46419
48069
  return;
46420
48070
  }
46421
- if (isRecord11(value)) {
48071
+ if (isRecord13(value)) {
46422
48072
  Object.entries(value).forEach(([key, entry]) => {
46423
48073
  walkMediaValues(entry, location2 ? `${location2}.${key}` : key, handler);
46424
48074
  });
@@ -46428,6 +48078,15 @@ var walkLocalContentMedia = (content, handler) => {
46428
48078
  for (const [contentType, entries] of content.entries ?? []) {
46429
48079
  for (const entry of entries) {
46430
48080
  walkMediaValues(entry.data, `entries.${contentType}.${entry.identifier}.data`, handler);
48081
+ for (const [slotKey, blocks] of Object.entries(entry.blocks ?? {})) {
48082
+ for (const block of blocks) {
48083
+ walkMediaValues(
48084
+ block.content,
48085
+ `entries.${contentType}.${entry.identifier}.blocks.${slotKey}.${block.identifier ?? "unidentified"}.content`,
48086
+ handler
48087
+ );
48088
+ }
48089
+ }
46431
48090
  }
46432
48091
  }
46433
48092
  for (const page of content.pages ?? []) {
@@ -46468,6 +48127,15 @@ var walkPulledContentMedia = (content, handler) => {
46468
48127
  for (const [contentType, entries] of Object.entries(content.entries)) {
46469
48128
  for (const entry of entries) {
46470
48129
  walkMediaValues(entry.data, `entries.${contentType}.${entry.identifier}.data`, handler);
48130
+ for (const [slotKey, blocks] of Object.entries(entry.blocks ?? {})) {
48131
+ for (const block of blocks) {
48132
+ walkMediaValues(
48133
+ block.content,
48134
+ `entries.${contentType}.${entry.identifier}.blocks.${slotKey}.${block.identifier ?? "unidentified"}.content`,
48135
+ handler
48136
+ );
48137
+ }
48138
+ }
46471
48139
  }
46472
48140
  }
46473
48141
  for (const page of content.pages) {
@@ -46526,7 +48194,7 @@ var normalizeMediaValueToIdentifierOnly = (value, identifier, asset) => {
46526
48194
  };
46527
48195
 
46528
48196
  // src/cli/media/rich-text.ts
46529
- var isRecord12 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
48197
+ var isRecord14 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
46530
48198
  function collectRichTextImageAttrs(value, out = [], location2 = "") {
46531
48199
  if (Array.isArray(value)) {
46532
48200
  value.forEach(
@@ -46534,8 +48202,8 @@ function collectRichTextImageAttrs(value, out = [], location2 = "") {
46534
48202
  );
46535
48203
  return out;
46536
48204
  }
46537
- if (!isRecord12(value)) return out;
46538
- if (value.type === "image" && isRecord12(value.attrs)) {
48205
+ if (!isRecord14(value)) return out;
48206
+ if (value.type === "image" && isRecord14(value.attrs)) {
46539
48207
  out.push({ attrs: value.attrs, location: location2 ? `${location2}.attrs` : "attrs" });
46540
48208
  }
46541
48209
  for (const [key, child] of Object.entries(value)) {
@@ -49166,7 +50834,7 @@ async function writeAllEntries(contentDir, entriesByType, pulledAt, entriesMeta,
49166
50834
  }
49167
50835
  const { dirPath, count } = await writeEntries(contentDir, {
49168
50836
  contentType,
49169
- entries,
50837
+ entries: entries.map(mapEntryForOutput),
49170
50838
  meta: { pulledAt, entries: ctMeta },
49171
50839
  pagination: { limit: entries.length, total: entries.length}
49172
50840
  }, writerOptions);
@@ -49181,7 +50849,7 @@ async function fetchAllContentPaginated(client, contentTypes, output, baseConten
49181
50849
  for (const contentType of contentTypes) {
49182
50850
  output.info(`Fetching ${contentType} entries...`);
49183
50851
  const result = await pullEntriesWithPagination(client, contentType, output);
49184
- allEntries[contentType] = result.entries.map(mapEntryForOutput);
50852
+ allEntries[contentType] = result.entries;
49185
50853
  for (const [id, meta] of Object.entries(result.meta.entries || {})) {
49186
50854
  allMeta[`${contentType}:${id}`] = meta;
49187
50855
  }
@@ -50446,10 +52114,303 @@ function normalizeLocalContentShape(content) {
50446
52114
  courses: Array.isArray(value.courses) ? value.courses : []
50447
52115
  };
50448
52116
  }
52117
+
52118
+ // ../api/src/sdk-event-pricing.ts
52119
+ var identifierRegex = /^[a-z0-9][a-z0-9-]*$/;
52120
+ var currencyRegex = /^[A-Z]{3}$/;
52121
+ var isoDateTimeRegex = /^\d{4}-\d{2}-\d{2}T.+/;
52122
+ function issue2(path25, message) {
52123
+ return { path: path25, message };
52124
+ }
52125
+ function isRecord15(value) {
52126
+ return typeof value === "object" && value !== null && !Array.isArray(value);
52127
+ }
52128
+ function isCurrency(value) {
52129
+ return typeof value === "string" && currencyRegex.test(value);
52130
+ }
52131
+ function isWholeNumber(value) {
52132
+ return typeof value === "number" && Number.isInteger(value);
52133
+ }
52134
+ function isWholeMinuteIsoDateTime(value) {
52135
+ if (!isoDateTimeRegex.test(value)) return false;
52136
+ const epochMs = Date.parse(value);
52137
+ return Number.isFinite(epochMs) && epochMs % 6e4 === 0;
52138
+ }
52139
+ function validateTicketType(raw, index, currency) {
52140
+ const path25 = ["ticketTypes", String(index)];
52141
+ if (!isRecord15(raw)) return [issue2(path25, "Ticket type must be an object")];
52142
+ const issues = [];
52143
+ const identifier = raw.identifier;
52144
+ if (typeof identifier !== "string" || !identifierRegex.test(identifier)) {
52145
+ issues.push(
52146
+ issue2(
52147
+ [...path25, "identifier"],
52148
+ "Ticket identifier must use lowercase letters, numbers, and hyphens"
52149
+ )
52150
+ );
52151
+ }
52152
+ const name = raw.name;
52153
+ if (typeof name !== "string" || name.trim().length === 0) {
52154
+ issues.push(issue2([...path25, "name"], "Ticket name is required"));
52155
+ }
52156
+ const priceAmount = raw.priceAmount;
52157
+ if (!isWholeNumber(priceAmount) || priceAmount < 0) {
52158
+ issues.push(
52159
+ issue2(
52160
+ [...path25, "priceAmount"],
52161
+ "Ticket priceAmount must be a non-negative integer"
52162
+ )
52163
+ );
52164
+ }
52165
+ const priceCurrency = raw.priceCurrency;
52166
+ if (priceCurrency !== void 0 && priceCurrency !== null && priceCurrency !== currency) {
52167
+ issues.push(
52168
+ issue2(
52169
+ [...path25, "priceCurrency"],
52170
+ "Ticket priceCurrency must match pricing.priceCurrency"
52171
+ )
52172
+ );
52173
+ }
52174
+ const sortOrder = raw.sortOrder;
52175
+ if (sortOrder !== void 0 && (!isWholeNumber(sortOrder) || sortOrder < 0)) {
52176
+ issues.push(
52177
+ issue2(
52178
+ [...path25, "sortOrder"],
52179
+ "Ticket sortOrder must be a non-negative integer"
52180
+ )
52181
+ );
52182
+ }
52183
+ const capacityLimit2 = raw.capacityLimit;
52184
+ if (capacityLimit2 !== void 0 && capacityLimit2 !== null && (!isWholeNumber(capacityLimit2) || capacityLimit2 < 1)) {
52185
+ issues.push(
52186
+ issue2(
52187
+ [...path25, "capacityLimit"],
52188
+ "Ticket capacityLimit must be a positive integer"
52189
+ )
52190
+ );
52191
+ }
52192
+ const attendanceScope = raw.attendanceScope;
52193
+ if (attendanceScope !== void 0 && attendanceScope !== "in_person" && attendanceScope !== "online" && attendanceScope !== "both") {
52194
+ issues.push(
52195
+ issue2(
52196
+ [...path25, "attendanceScope"],
52197
+ "Ticket attendanceScope must be in_person, online, or both"
52198
+ )
52199
+ );
52200
+ }
52201
+ const saleStartsAt = raw.saleStartsAt;
52202
+ if (saleStartsAt !== void 0 && saleStartsAt !== null && (typeof saleStartsAt !== "string" || !isWholeMinuteIsoDateTime(saleStartsAt))) {
52203
+ issues.push(
52204
+ issue2(
52205
+ [...path25, "saleStartsAt"],
52206
+ "Ticket saleStartsAt must be an ISO datetime aligned to a whole minute"
52207
+ )
52208
+ );
52209
+ }
52210
+ const saleEndsAt = raw.saleEndsAt;
52211
+ if (saleEndsAt !== void 0 && saleEndsAt !== null && (typeof saleEndsAt !== "string" || !isWholeMinuteIsoDateTime(saleEndsAt))) {
52212
+ issues.push(
52213
+ issue2(
52214
+ [...path25, "saleEndsAt"],
52215
+ "Ticket saleEndsAt must be an ISO datetime aligned to a whole minute"
52216
+ )
52217
+ );
52218
+ }
52219
+ if (typeof saleStartsAt === "string" && typeof saleEndsAt === "string" && Date.parse(saleEndsAt) <= Date.parse(saleStartsAt)) {
52220
+ issues.push(
52221
+ issue2(
52222
+ [...path25, "saleEndsAt"],
52223
+ "Ticket saleEndsAt must be after saleStartsAt"
52224
+ )
52225
+ );
52226
+ }
52227
+ const cmsTicketTypeId = raw.cmsTicketTypeId;
52228
+ if (cmsTicketTypeId !== void 0 && cmsTicketTypeId !== null && (typeof cmsTicketTypeId !== "string" || cmsTicketTypeId.length === 0)) {
52229
+ issues.push(
52230
+ issue2(
52231
+ [...path25, "cmsTicketTypeId"],
52232
+ "Ticket cmsTicketTypeId must be a non-empty string"
52233
+ )
52234
+ );
52235
+ }
52236
+ if (issues.length > 0) return issues;
52237
+ return {
52238
+ identifier,
52239
+ ...cmsTicketTypeId ? { cmsTicketTypeId } : {},
52240
+ name,
52241
+ description: typeof raw.description === "string" ? raw.description : null,
52242
+ priceAmount,
52243
+ isActive: typeof raw.isActive === "boolean" ? raw.isActive : true,
52244
+ sortOrder: isWholeNumber(sortOrder) ? sortOrder : index,
52245
+ capacityLimit: isWholeNumber(capacityLimit2) ? capacityLimit2 : null,
52246
+ attendanceScope: attendanceScope === "in_person" || attendanceScope === "online" || attendanceScope === "both" ? attendanceScope : "both",
52247
+ saleStartsAt: typeof saleStartsAt === "string" ? saleStartsAt : null,
52248
+ saleEndsAt: typeof saleEndsAt === "string" ? saleEndsAt : null
52249
+ };
52250
+ }
52251
+ function validateTicketTypes(rawTicketTypes, currency) {
52252
+ if (!Array.isArray(rawTicketTypes) || rawTicketTypes.length === 0) {
52253
+ return [
52254
+ issue2(
52255
+ ["ticketTypes"],
52256
+ "Ticket-type pricing requires at least one ticket type"
52257
+ )
52258
+ ];
52259
+ }
52260
+ const issues = [];
52261
+ const ticketTypes = [];
52262
+ const seenIdentifiers = /* @__PURE__ */ new Set();
52263
+ rawTicketTypes.forEach((rawTicketType, index) => {
52264
+ const rawIdentifier = isRecord15(rawTicketType) ? rawTicketType.identifier : void 0;
52265
+ const hasValidIdentifier = typeof rawIdentifier === "string" && identifierRegex.test(rawIdentifier);
52266
+ const isDuplicateIdentifier = hasValidIdentifier && seenIdentifiers.has(rawIdentifier);
52267
+ if (isDuplicateIdentifier) {
52268
+ issues.push(
52269
+ issue2(
52270
+ ["ticketTypes", String(index), "identifier"],
52271
+ `Duplicate ticket identifier "${rawIdentifier}"`
52272
+ )
52273
+ );
52274
+ } else if (hasValidIdentifier) {
52275
+ seenIdentifiers.add(rawIdentifier);
52276
+ }
52277
+ const parsed = validateTicketType(rawTicketType, index, currency);
52278
+ if (Array.isArray(parsed)) {
52279
+ issues.push(...parsed);
52280
+ return;
52281
+ }
52282
+ if (isDuplicateIdentifier) {
52283
+ return;
52284
+ }
52285
+ ticketTypes.push(parsed);
52286
+ });
52287
+ if (issues.length > 0) return issues;
52288
+ return sortSdkEventTicketTypes(ticketTypes);
52289
+ }
52290
+ function isPricingIssueArray(value) {
52291
+ const first = value[0];
52292
+ return first !== void 0 && "message" in first;
52293
+ }
52294
+ function sortSdkEventTicketTypes(ticketTypes) {
52295
+ return [...ticketTypes].sort((left, right) => {
52296
+ const leftOrder = left.sortOrder ?? Number.MAX_SAFE_INTEGER;
52297
+ const rightOrder = right.sortOrder ?? Number.MAX_SAFE_INTEGER;
52298
+ if (leftOrder !== rightOrder) return leftOrder - rightOrder;
52299
+ const identifierCompare = left.identifier.localeCompare(right.identifier);
52300
+ if (identifierCompare !== 0) return identifierCompare;
52301
+ return left.name.localeCompare(right.name);
52302
+ });
52303
+ }
52304
+ function classifySdkEventPricing(rawInput) {
52305
+ if (rawInput === void 0 || rawInput === null) {
52306
+ return { ok: true, pricing: { kind: "free" } };
52307
+ }
52308
+ if (!isRecord15(rawInput)) {
52309
+ return { ok: false, issues: [issue2([], "Pricing must be an object")] };
52310
+ }
52311
+ const record = rawInput;
52312
+ const kind = typeof record.kind === "string" ? record.kind : record.pricingMode === "ticket_types" ? "ticket_types" : record.pricingMode === "fixed_price" ? "fixed_price" : record.pricingMode === "free" ? "free" : record.requiresPayment || typeof record.priceAmount === "number" && record.priceAmount > 0 ? "fixed_price" : "free";
52313
+ const acceptsPasses = typeof record.acceptsPasses === "boolean" ? record.acceptsPasses : void 0;
52314
+ const acceptsMemberships = typeof record.acceptsMemberships === "boolean" ? record.acceptsMemberships : void 0;
52315
+ const priceDisplay = typeof record.priceDisplay === "string" ? record.priceDisplay : null;
52316
+ switch (kind) {
52317
+ case "free":
52318
+ return {
52319
+ ok: true,
52320
+ pricing: {
52321
+ kind: "free",
52322
+ priceDisplay,
52323
+ ...acceptsPasses !== void 0 ? { acceptsPasses } : {},
52324
+ ...acceptsMemberships !== void 0 ? { acceptsMemberships } : {}
52325
+ }
52326
+ };
52327
+ case "fixed_price": {
52328
+ const issues = [];
52329
+ const priceAmount = record.priceAmount;
52330
+ if (!isWholeNumber(priceAmount) || priceAmount < 0) {
52331
+ issues.push(
52332
+ issue2(
52333
+ ["priceAmount"],
52334
+ "Fixed-price events require a non-negative integer priceAmount"
52335
+ )
52336
+ );
52337
+ }
52338
+ const rawPriceCurrency = record.priceCurrency;
52339
+ const priceCurrency = rawPriceCurrency === void 0 || rawPriceCurrency === null ? "USD" : isCurrency(rawPriceCurrency) ? rawPriceCurrency : null;
52340
+ if (rawPriceCurrency !== void 0 && rawPriceCurrency !== null && !isCurrency(rawPriceCurrency)) {
52341
+ issues.push(
52342
+ issue2(
52343
+ ["priceCurrency"],
52344
+ "priceCurrency must be a 3-letter uppercase currency code"
52345
+ )
52346
+ );
52347
+ }
52348
+ if (issues.length > 0) return { ok: false, issues };
52349
+ if (!isWholeNumber(priceAmount) || priceCurrency === null) {
52350
+ return {
52351
+ ok: false,
52352
+ issues: [issue2(["priceAmount"], "Invalid fixed-price event pricing")]
52353
+ };
52354
+ }
52355
+ return {
52356
+ ok: true,
52357
+ pricing: {
52358
+ kind: "fixed_price",
52359
+ priceAmount,
52360
+ priceCurrency,
52361
+ priceDisplay,
52362
+ ...acceptsPasses !== void 0 ? { acceptsPasses } : {},
52363
+ ...acceptsMemberships !== void 0 ? { acceptsMemberships } : {}
52364
+ }
52365
+ };
52366
+ }
52367
+ case "ticket_types": {
52368
+ const priceCurrency = record.priceCurrency;
52369
+ if (!isCurrency(priceCurrency)) {
52370
+ return {
52371
+ ok: false,
52372
+ issues: [
52373
+ issue2(
52374
+ ["priceCurrency"],
52375
+ "Ticket-type pricing requires a 3-letter uppercase priceCurrency"
52376
+ )
52377
+ ]
52378
+ };
52379
+ }
52380
+ const ticketTypes = record.ticketTypes === void 0 || record.ticketTypes === null ? [] : validateTicketTypes(record.ticketTypes, priceCurrency);
52381
+ if (isPricingIssueArray(ticketTypes)) {
52382
+ return { ok: false, issues: ticketTypes };
52383
+ }
52384
+ return {
52385
+ ok: true,
52386
+ pricing: {
52387
+ kind: "ticket_types",
52388
+ priceCurrency,
52389
+ priceDisplay,
52390
+ ...acceptsPasses !== void 0 ? { acceptsPasses } : {},
52391
+ ...acceptsMemberships !== void 0 ? { acceptsMemberships } : {},
52392
+ ticketTypes
52393
+ }
52394
+ };
52395
+ }
52396
+ default:
52397
+ return {
52398
+ ok: false,
52399
+ issues: [
52400
+ issue2(
52401
+ ["kind"],
52402
+ "Pricing kind must be free, fixed_price, or ticket_types"
52403
+ )
52404
+ ]
52405
+ };
52406
+ }
52407
+ }
52408
+
52409
+ // src/cli/commands/push/pushAllExtras.ts
50449
52410
  function nullishToNull(value) {
50450
52411
  return value == null ? null : value;
50451
52412
  }
50452
- function isRecord13(value) {
52413
+ function isRecord16(value) {
50453
52414
  return typeof value === "object" && value !== null && !Array.isArray(value);
50454
52415
  }
50455
52416
  function stringValue(value, fallback) {
@@ -50459,8 +52420,13 @@ function stringValue(value, fallback) {
50459
52420
  }
50460
52421
  return fallback;
50461
52422
  }
52423
+ function normalizeEventPricingForCompare(pricing) {
52424
+ const result = classifySdkEventPricing(pricing);
52425
+ if (result.ok) return result.pricing;
52426
+ return { kind: "free" };
52427
+ }
50462
52428
  function normalizeVenueAddress(value) {
50463
- const obj = isRecord13(value) ? value : {};
52429
+ const obj = isRecord16(value) ? value : {};
50464
52430
  return {
50465
52431
  line1: nullishToNull(typeof obj.line1 === "string" ? obj.line1 : void 0),
50466
52432
  line2: nullishToNull(typeof obj.line2 === "string" ? obj.line2 : void 0),
@@ -50477,7 +52443,7 @@ function normalizeVenueAddress(value) {
50477
52443
  };
50478
52444
  }
50479
52445
  function normalizeVenueLocation(value) {
50480
- if (!isRecord13(value)) return null;
52446
+ if (!isRecord16(value)) return null;
50481
52447
  const obj = value;
50482
52448
  const lat = typeof obj.lat === "number" ? obj.lat : null;
50483
52449
  const lng = typeof obj.lng === "number" ? obj.lng : null;
@@ -50485,32 +52451,41 @@ function normalizeVenueLocation(value) {
50485
52451
  return { lat, lng };
50486
52452
  }
50487
52453
  function normalizeVenueForCompare(venue) {
50488
- const obj = isRecord13(venue) ? venue : {};
52454
+ const obj = isRecord16(venue) ? venue : {};
50489
52455
  return {
50490
52456
  slug: String(obj.slug),
50491
52457
  title: String(obj.title),
50492
- description: nullishToNull(typeof obj.description === "string" ? obj.description : void 0),
50493
- timezone: nullishToNull(typeof obj.timezone === "string" ? obj.timezone : void 0),
50494
- capacity: nullishToNull(typeof obj.capacity === "number" ? obj.capacity : void 0),
52458
+ description: nullishToNull(
52459
+ typeof obj.description === "string" ? obj.description : void 0
52460
+ ),
52461
+ timezone: nullishToNull(
52462
+ typeof obj.timezone === "string" ? obj.timezone : void 0
52463
+ ),
52464
+ capacity: nullishToNull(
52465
+ typeof obj.capacity === "number" ? obj.capacity : void 0
52466
+ ),
50495
52467
  address: normalizeVenueAddress(obj.address),
50496
52468
  location: normalizeVenueLocation(obj.location),
50497
- mapEmbed: nullishToNull(typeof obj.mapEmbed === "string" ? obj.mapEmbed : void 0)
52469
+ mapEmbed: nullishToNull(
52470
+ typeof obj.mapEmbed === "string" ? obj.mapEmbed : void 0
52471
+ )
50498
52472
  };
50499
52473
  }
50500
52474
  function normalizeEventCategoryForCompare(category) {
50501
- const obj = isRecord13(category) ? category : {};
52475
+ const obj = isRecord16(category) ? category : {};
50502
52476
  return {
50503
52477
  identifier: String(obj.identifier),
50504
52478
  name: String(obj.name),
50505
- description: nullishToNull(typeof obj.description === "string" ? obj.description : void 0),
52479
+ description: nullishToNull(
52480
+ typeof obj.description === "string" ? obj.description : void 0
52481
+ ),
50506
52482
  color: nullishToNull(typeof obj.color === "string" ? obj.color : void 0),
50507
52483
  sortOrder: typeof obj.sortOrder === "number" ? obj.sortOrder : 0
50508
52484
  };
50509
52485
  }
50510
52486
  function normalizeRemoteEventForCompare(event) {
50511
- const obj = isRecord13(event) ? event : {};
50512
- const schedule = isRecord13(obj.schedule) ? obj.schedule : {};
50513
- const pricing = isRecord13(obj.pricing) ? obj.pricing : {};
52487
+ const obj = isRecord16(event) ? event : {};
52488
+ const schedule = isRecord16(obj.schedule) ? obj.schedule : {};
50514
52489
  return {
50515
52490
  identifier: String(obj.identifier),
50516
52491
  title: String(obj.title),
@@ -50521,36 +52496,31 @@ function normalizeRemoteEventForCompare(event) {
50521
52496
  recurrenceRule: nullishToNull(
50522
52497
  schedule.recurrenceRule
50523
52498
  ),
50524
- startDate: nullishToNull(
50525
- schedule.startDate
50526
- ),
52499
+ startDate: nullishToNull(schedule.startDate),
50527
52500
  defaultStartTime: stringValue(schedule.defaultStartTime, "09:00:00"),
50528
52501
  durationMinutes: typeof schedule.durationMinutes === "number" ? schedule.durationMinutes : 60
50529
52502
  },
50530
- capacity: nullishToNull(typeof obj.capacity === "number" ? obj.capacity : void 0),
50531
- pricing: {
50532
- requiresPayment: Boolean(pricing.requiresPayment ?? false),
50533
- priceAmount: nullishToNull(pricing.priceAmount),
50534
- priceCurrency: nullishToNull(
50535
- pricing.priceCurrency
50536
- ),
50537
- priceDisplay: nullishToNull(
50538
- pricing.priceDisplay
50539
- ),
50540
- acceptsPasses: Boolean(pricing.acceptsPasses ?? true),
50541
- acceptsMemberships: Boolean(pricing.acceptsMemberships ?? true)
50542
- },
50543
- venueRef: nullishToNull(typeof obj.venueRef === "string" ? obj.venueRef : void 0),
50544
- categoryRef: nullishToNull(typeof obj.categoryRef === "string" ? obj.categoryRef : void 0),
50545
- formRef: nullishToNull(typeof obj.formRef === "string" ? obj.formRef : void 0),
50546
- content: isRecord13(obj.content) ? obj.content : {},
50547
- settings: isRecord13(obj.settings) ? obj.settings : {},
50548
- presentation: isRecord13(obj.presentation) ? obj.presentation : null,
52503
+ capacity: nullishToNull(
52504
+ typeof obj.capacity === "number" ? obj.capacity : void 0
52505
+ ),
52506
+ pricing: normalizeEventPricingForCompare(obj.pricing),
52507
+ venueRef: nullishToNull(
52508
+ typeof obj.venueRef === "string" ? obj.venueRef : void 0
52509
+ ),
52510
+ categoryRef: nullishToNull(
52511
+ typeof obj.categoryRef === "string" ? obj.categoryRef : void 0
52512
+ ),
52513
+ formRef: nullishToNull(
52514
+ typeof obj.formRef === "string" ? obj.formRef : void 0
52515
+ ),
52516
+ content: isRecord16(obj.content) ? obj.content : {},
52517
+ settings: isRecord16(obj.settings) ? obj.settings : {},
52518
+ presentation: isRecord16(obj.presentation) ? obj.presentation : null,
50549
52519
  tags: Array.isArray(obj.tags) ? obj.tags : []
50550
52520
  };
50551
52521
  }
50552
52522
  function normalizeLocalEventAgainstRemoteForCompare(localEvent, remoteEvent) {
50553
- const local = isRecord13(localEvent) ? localEvent : {};
52523
+ const local = isRecord16(localEvent) ? localEvent : {};
50554
52524
  const base = remoteEvent ? normalizeRemoteEventForCompare(remoteEvent) : normalizeRemoteEventForCompare({
50555
52525
  identifier: local.identifier,
50556
52526
  title: local.title,
@@ -50568,8 +52538,7 @@ function normalizeLocalEventAgainstRemoteForCompare(localEvent, remoteEvent) {
50568
52538
  presentation: local.presentation ?? null,
50569
52539
  tags: local.tags ?? []
50570
52540
  });
50571
- const schedule = isRecord13(local.schedule) ? local.schedule : {};
50572
- const pricing = isRecord13(local.pricing) ? local.pricing : {};
52541
+ const schedule = isRecord16(local.schedule) ? local.schedule : {};
50573
52542
  return {
50574
52543
  ...base,
50575
52544
  identifier: stringValue(local.identifier, base.identifier),
@@ -50580,24 +52549,28 @@ function normalizeLocalEventAgainstRemoteForCompare(localEvent, remoteEvent) {
50580
52549
  schedule: {
50581
52550
  recurrenceRule: schedule.recurrenceRule === void 0 ? base.schedule.recurrenceRule : nullishToNull(schedule.recurrenceRule),
50582
52551
  startDate: schedule.startDate === void 0 ? base.schedule.startDate : nullishToNull(schedule.startDate),
50583
- defaultStartTime: schedule.defaultStartTime === void 0 ? base.schedule.defaultStartTime : stringValue(schedule.defaultStartTime, base.schedule.defaultStartTime),
52552
+ defaultStartTime: schedule.defaultStartTime === void 0 ? base.schedule.defaultStartTime : stringValue(
52553
+ schedule.defaultStartTime,
52554
+ base.schedule.defaultStartTime
52555
+ ),
50584
52556
  durationMinutes: schedule.durationMinutes === void 0 ? base.schedule.durationMinutes : typeof schedule.durationMinutes === "number" ? schedule.durationMinutes : base.schedule.durationMinutes
50585
52557
  },
50586
- capacity: local.capacity === void 0 ? base.capacity : nullishToNull(typeof local.capacity === "number" ? local.capacity : void 0),
50587
- pricing: {
50588
- requiresPayment: pricing.requiresPayment === void 0 ? base.pricing.requiresPayment : Boolean(pricing.requiresPayment),
50589
- priceAmount: pricing.priceAmount === void 0 ? base.pricing.priceAmount : nullishToNull(pricing.priceAmount),
50590
- priceCurrency: pricing.priceCurrency === void 0 ? base.pricing.priceCurrency : nullishToNull(pricing.priceCurrency),
50591
- priceDisplay: pricing.priceDisplay === void 0 ? base.pricing.priceDisplay : nullishToNull(pricing.priceDisplay),
50592
- acceptsPasses: pricing.acceptsPasses === void 0 ? base.pricing.acceptsPasses : Boolean(pricing.acceptsPasses),
50593
- acceptsMemberships: pricing.acceptsMemberships === void 0 ? base.pricing.acceptsMemberships : Boolean(pricing.acceptsMemberships)
50594
- },
50595
- venueRef: local.venueRef === void 0 ? base.venueRef : nullishToNull(typeof local.venueRef === "string" ? local.venueRef : void 0),
50596
- categoryRef: local.categoryRef === void 0 ? base.categoryRef : nullishToNull(typeof local.categoryRef === "string" ? local.categoryRef : void 0),
50597
- formRef: local.formRef === void 0 ? base.formRef : nullishToNull(typeof local.formRef === "string" ? local.formRef : void 0),
50598
- content: local.content === void 0 ? base.content : isRecord13(local.content) ? local.content : {},
50599
- settings: local.settings === void 0 ? base.settings : isRecord13(local.settings) ? local.settings : {},
50600
- presentation: local.presentation === void 0 ? base.presentation : isRecord13(local.presentation) ? local.presentation : null,
52558
+ capacity: local.capacity === void 0 ? base.capacity : nullishToNull(
52559
+ typeof local.capacity === "number" ? local.capacity : void 0
52560
+ ),
52561
+ pricing: local.pricing === void 0 ? base.pricing : normalizeEventPricingForCompare(local.pricing),
52562
+ venueRef: local.venueRef === void 0 ? base.venueRef : nullishToNull(
52563
+ typeof local.venueRef === "string" ? local.venueRef : void 0
52564
+ ),
52565
+ categoryRef: local.categoryRef === void 0 ? base.categoryRef : nullishToNull(
52566
+ typeof local.categoryRef === "string" ? local.categoryRef : void 0
52567
+ ),
52568
+ formRef: local.formRef === void 0 ? base.formRef : nullishToNull(
52569
+ typeof local.formRef === "string" ? local.formRef : void 0
52570
+ ),
52571
+ content: local.content === void 0 ? base.content : isRecord16(local.content) ? local.content : {},
52572
+ settings: local.settings === void 0 ? base.settings : isRecord16(local.settings) ? local.settings : {},
52573
+ presentation: local.presentation === void 0 ? base.presentation : isRecord16(local.presentation) ? local.presentation : null,
50601
52574
  tags: local.tags === void 0 ? base.tags : Array.isArray(local.tags) ? local.tags : []
50602
52575
  };
50603
52576
  }
@@ -50609,7 +52582,7 @@ function toIsoStringOrOriginal(value) {
50609
52582
  function normalizeCourseSessions(value) {
50610
52583
  if (!Array.isArray(value)) return [];
50611
52584
  return value.map((session) => {
50612
- const obj = isRecord13(session) ? session : {};
52585
+ const obj = isRecord16(session) ? session : {};
50613
52586
  return {
50614
52587
  startsAt: toIsoStringOrOriginal(obj.startsAt),
50615
52588
  endsAt: toIsoStringOrOriginal(obj.endsAt)
@@ -50621,41 +52594,53 @@ function normalizeCourseSessions(value) {
50621
52594
  }
50622
52595
  function normalizeCourseProgram(value) {
50623
52596
  if (value == null) return null;
50624
- if (!isRecord13(value)) {
52597
+ if (!isRecord16(value)) {
50625
52598
  return { identifier: null, data: {} };
50626
52599
  }
50627
52600
  return {
50628
52601
  identifier: nullishToNull(
50629
52602
  typeof value.identifier === "string" ? value.identifier : void 0
50630
52603
  ),
50631
- data: isRecord13(value.data) ? value.data : {}
52604
+ data: isRecord16(value.data) ? value.data : {}
50632
52605
  };
50633
52606
  }
50634
52607
  function normalizeRemoteCourseForCompare(course) {
50635
- const obj = isRecord13(course) ? course : {};
52608
+ const obj = isRecord16(course) ? course : {};
50636
52609
  return {
50637
52610
  identifier: String(obj.identifier),
50638
52611
  title: String(obj.title),
50639
52612
  slug: String(obj.slug),
50640
52613
  status: obj.status === "active" || obj.status === "cancelled" || obj.status === "completed" ? obj.status : "draft",
50641
52614
  visibility: obj.visibility === "public" || obj.visibility === "private" || obj.visibility === "unlisted" ? obj.visibility : "public",
50642
- venueRef: nullishToNull(typeof obj.venueRef === "string" ? obj.venueRef : void 0),
50643
- categoryRef: nullishToNull(typeof obj.categoryRef === "string" ? obj.categoryRef : void 0),
50644
- formRef: nullishToNull(typeof obj.formRef === "string" ? obj.formRef : void 0),
50645
- capacity: nullishToNull(typeof obj.capacity === "number" ? obj.capacity : void 0),
52615
+ venueRef: nullishToNull(
52616
+ typeof obj.venueRef === "string" ? obj.venueRef : void 0
52617
+ ),
52618
+ categoryRef: nullishToNull(
52619
+ typeof obj.categoryRef === "string" ? obj.categoryRef : void 0
52620
+ ),
52621
+ formRef: nullishToNull(
52622
+ typeof obj.formRef === "string" ? obj.formRef : void 0
52623
+ ),
52624
+ capacity: nullishToNull(
52625
+ typeof obj.capacity === "number" ? obj.capacity : void 0
52626
+ ),
50646
52627
  enrollmentCapacity: nullishToNull(
50647
52628
  typeof obj.enrollmentCapacity === "number" ? obj.enrollmentCapacity : void 0
50648
52629
  ),
50649
52630
  acceptsMemberships: Boolean(obj.acceptsMemberships ?? false),
50650
- priceCents: nullishToNull(typeof obj.priceCents === "number" ? obj.priceCents : void 0),
52631
+ priceCents: nullishToNull(
52632
+ typeof obj.priceCents === "number" ? obj.priceCents : void 0
52633
+ ),
50651
52634
  currency: typeof obj.currency === "string" && obj.currency.trim().length > 0 ? obj.currency.toUpperCase() : "GBP",
50652
52635
  sessions: normalizeCourseSessions(obj.sessions),
50653
- programRef: nullishToNull(typeof obj.programRef === "string" ? obj.programRef : void 0),
52636
+ programRef: nullishToNull(
52637
+ typeof obj.programRef === "string" ? obj.programRef : void 0
52638
+ ),
50654
52639
  program: normalizeCourseProgram(obj.program)
50655
52640
  };
50656
52641
  }
50657
52642
  function normalizeLocalCourseAgainstRemoteForCompare(localCourse, remoteCourse) {
50658
- const local = isRecord13(localCourse) ? localCourse : {};
52643
+ const local = isRecord16(localCourse) ? localCourse : {};
50659
52644
  const base = remoteCourse ? normalizeRemoteCourseForCompare(remoteCourse) : normalizeRemoteCourseForCompare({
50660
52645
  identifier: local.identifier,
50661
52646
  title: local.title,
@@ -50676,11 +52661,11 @@ function normalizeLocalCourseAgainstRemoteForCompare(localCourse, remoteCourse)
50676
52661
  });
50677
52662
  const status = local.status === void 0 ? base.status : local.status === "active" || local.status === "cancelled" || local.status === "completed" ? local.status : "draft";
50678
52663
  const visibility = local.visibility === void 0 ? base.visibility : local.visibility === "public" || local.visibility === "private" || local.visibility === "unlisted" ? local.visibility : "public";
50679
- const program2 = local.program === void 0 ? base.program : local.program === null ? null : isRecord13(local.program) ? {
52664
+ const program2 = local.program === void 0 ? base.program : local.program === null ? null : isRecord16(local.program) ? {
50680
52665
  identifier: local.program.identifier === void 0 ? base.program?.identifier ?? null : nullishToNull(
50681
52666
  typeof local.program.identifier === "string" ? local.program.identifier : void 0
50682
52667
  ),
50683
- data: isRecord13(local.program.data) ? local.program.data : base.program?.data ?? {}
52668
+ data: isRecord16(local.program.data) ? local.program.data : base.program?.data ?? {}
50684
52669
  } : base.program;
50685
52670
  return {
50686
52671
  ...base,
@@ -50689,18 +52674,30 @@ function normalizeLocalCourseAgainstRemoteForCompare(localCourse, remoteCourse)
50689
52674
  slug: stringValue(local.slug, base.slug),
50690
52675
  status,
50691
52676
  visibility,
50692
- venueRef: local.venueRef === void 0 ? base.venueRef : nullishToNull(typeof local.venueRef === "string" ? local.venueRef : void 0),
50693
- categoryRef: local.categoryRef === void 0 ? base.categoryRef : nullishToNull(typeof local.categoryRef === "string" ? local.categoryRef : void 0),
50694
- formRef: local.formRef === void 0 ? base.formRef : nullishToNull(typeof local.formRef === "string" ? local.formRef : void 0),
50695
- capacity: local.capacity === void 0 ? base.capacity : nullishToNull(typeof local.capacity === "number" ? local.capacity : void 0),
52677
+ venueRef: local.venueRef === void 0 ? base.venueRef : nullishToNull(
52678
+ typeof local.venueRef === "string" ? local.venueRef : void 0
52679
+ ),
52680
+ categoryRef: local.categoryRef === void 0 ? base.categoryRef : nullishToNull(
52681
+ typeof local.categoryRef === "string" ? local.categoryRef : void 0
52682
+ ),
52683
+ formRef: local.formRef === void 0 ? base.formRef : nullishToNull(
52684
+ typeof local.formRef === "string" ? local.formRef : void 0
52685
+ ),
52686
+ capacity: local.capacity === void 0 ? base.capacity : nullishToNull(
52687
+ typeof local.capacity === "number" ? local.capacity : void 0
52688
+ ),
50696
52689
  enrollmentCapacity: local.enrollmentCapacity === void 0 ? base.enrollmentCapacity : nullishToNull(
50697
52690
  typeof local.enrollmentCapacity === "number" ? local.enrollmentCapacity : void 0
50698
52691
  ),
50699
52692
  acceptsMemberships: local.acceptsMemberships === void 0 ? base.acceptsMemberships : Boolean(local.acceptsMemberships),
50700
- priceCents: local.priceCents === void 0 ? base.priceCents : nullishToNull(typeof local.priceCents === "number" ? local.priceCents : void 0),
52693
+ priceCents: local.priceCents === void 0 ? base.priceCents : nullishToNull(
52694
+ typeof local.priceCents === "number" ? local.priceCents : void 0
52695
+ ),
50701
52696
  currency: local.currency === void 0 ? base.currency : typeof local.currency === "string" && local.currency.trim().length > 0 ? local.currency.toUpperCase() : base.currency,
50702
52697
  sessions: local.sessions === void 0 ? base.sessions : normalizeCourseSessions(local.sessions),
50703
- programRef: local.programRef === void 0 ? base.programRef : nullishToNull(typeof local.programRef === "string" ? local.programRef : void 0),
52698
+ programRef: local.programRef === void 0 ? base.programRef : nullishToNull(
52699
+ typeof local.programRef === "string" ? local.programRef : void 0
52700
+ ),
50704
52701
  program: program2
50705
52702
  };
50706
52703
  }
@@ -50717,26 +52714,15 @@ function detectOrphans(changes, localIds, remoteMap) {
50717
52714
  }
50718
52715
  function calculatePushAllExtraChanges(local, remote, options) {
50719
52716
  const deleteOrphaned = options?.deleteOrphaned ?? false;
50720
- const remoteVenues = new Map(
50721
- (remote.venues ?? []).map((v) => [v.slug, v])
50722
- );
52717
+ const remoteVenues = new Map((remote.venues ?? []).map((v) => [v.slug, v]));
50723
52718
  const remoteCategories = new Map(
50724
- (remote.eventCategories ?? []).map((c) => [
50725
- c.identifier,
50726
- c
50727
- ])
52719
+ (remote.eventCategories ?? []).map((c) => [c.identifier, c])
50728
52720
  );
50729
52721
  const remoteEvents = new Map(
50730
- (remote.events ?? []).map((e) => [
50731
- e.identifier,
50732
- e
50733
- ])
52722
+ (remote.events ?? []).map((e) => [e.identifier, e])
50734
52723
  );
50735
52724
  const remoteCourses = new Map(
50736
- (remote.courses ?? []).map((course) => [
50737
- course.identifier,
50738
- course
50739
- ])
52725
+ (remote.courses ?? []).map((course) => [course.identifier, course])
50740
52726
  );
50741
52727
  const venues = {
50742
52728
  toPush: /* @__PURE__ */ new Set(),
@@ -50801,7 +52787,10 @@ function calculatePushAllExtraChanges(local, remote, options) {
50801
52787
  events.toPush.add(identifier);
50802
52788
  continue;
50803
52789
  }
50804
- const localNorm = normalizeLocalEventAgainstRemoteForCompare(event, remoteEvent);
52790
+ const localNorm = normalizeLocalEventAgainstRemoteForCompare(
52791
+ event,
52792
+ remoteEvent
52793
+ );
50805
52794
  const remoteNorm = normalizeRemoteEventForCompare(remoteEvent);
50806
52795
  if (!equal(localNorm, remoteNorm)) {
50807
52796
  events.update++;
@@ -50825,7 +52814,10 @@ function calculatePushAllExtraChanges(local, remote, options) {
50825
52814
  courses.toPush.add(identifier);
50826
52815
  continue;
50827
52816
  }
50828
- const localNorm = normalizeLocalCourseAgainstRemoteForCompare(course, remoteCourse);
52817
+ const localNorm = normalizeLocalCourseAgainstRemoteForCompare(
52818
+ course,
52819
+ remoteCourse
52820
+ );
50829
52821
  const remoteNorm = normalizeRemoteCourseForCompare(remoteCourse);
50830
52822
  if (!equal(localNorm, remoteNorm)) {
50831
52823
  courses.update++;
@@ -50835,10 +52827,26 @@ function calculatePushAllExtraChanges(local, remote, options) {
50835
52827
  }
50836
52828
  }
50837
52829
  if (deleteOrphaned) {
50838
- detectOrphans(venues, local.venues.map((v) => String(v.slug)), remoteVenues);
50839
- detectOrphans(eventCategories, local.eventCategories.map((c) => String(c.identifier)), remoteCategories);
50840
- detectOrphans(events, local.events.map((e) => String(e.identifier)), remoteEvents);
50841
- detectOrphans(courses, local.courses.map((course) => String(course.identifier)), remoteCourses);
52830
+ detectOrphans(
52831
+ venues,
52832
+ local.venues.map((v) => String(v.slug)),
52833
+ remoteVenues
52834
+ );
52835
+ detectOrphans(
52836
+ eventCategories,
52837
+ local.eventCategories.map((c) => String(c.identifier)),
52838
+ remoteCategories
52839
+ );
52840
+ detectOrphans(
52841
+ events,
52842
+ local.events.map((e) => String(e.identifier)),
52843
+ remoteEvents
52844
+ );
52845
+ detectOrphans(
52846
+ courses,
52847
+ local.courses.map((course) => String(course.identifier)),
52848
+ remoteCourses
52849
+ );
50842
52850
  }
50843
52851
  return {
50844
52852
  venues,
@@ -51264,6 +53272,12 @@ var appointmentResourceRefSchema = resourceRefSchema("appointment-resource");
51264
53272
  var appointmentAvailabilityRefSchema = resourceRefSchema("availability");
51265
53273
  var unknownRecordSchema = z.record(z.string(), z.unknown());
51266
53274
  var stringArraySchema = z.array(z.string()).readonly();
53275
+ var entrySlotBlockSchema = z.object({
53276
+ identifier: z.string().nullable().optional(),
53277
+ kind: z.string().min(1),
53278
+ content: unknownRecordSchema
53279
+ }).strict();
53280
+ var entrySlotBlocksSchema = z.record(z.string(), z.array(entrySlotBlockSchema));
51267
53281
  var positiveIntegerSchema = z.number().int().positive();
51268
53282
  var nonNegativeIntegerSchema = z.number().int().nonnegative();
51269
53283
  var recipeIdentifierSchema = z.string().regex(
@@ -51642,6 +53656,7 @@ var upsertContentEntryCommandSchema = z.object({
51642
53656
  title: z.string().min(1).optional(),
51643
53657
  manualOrder: z.number().int().min(0).optional(),
51644
53658
  data: unknownRecordSchema.optional(),
53659
+ blocks: entrySlotBlocksSchema.optional(),
51645
53660
  linkedSubjectRef: contentEntryRefSchema.optional(),
51646
53661
  mediaRefs: z.array(mediaRefSchema).readonly().optional()
51647
53662
  }).strict()
@@ -52885,7 +54900,7 @@ function getSiteCommandLifecycleIntent(command) {
52885
54900
  init_src();
52886
54901
 
52887
54902
  // ../site-commands/src/guards.ts
52888
- function isRecord14(value) {
54903
+ function isRecord17(value) {
52889
54904
  return typeof value === "object" && value !== null;
52890
54905
  }
52891
54906
 
@@ -53150,7 +55165,7 @@ function collectVenueRefsFromIntervals(intervals, path25) {
53150
55165
  }
53151
55166
  function collectNavigationRefs(items, path25) {
53152
55167
  return items.flatMap((item, index) => {
53153
- if (!isRecord14(item)) return [];
55168
+ if (!isRecord17(item)) return [];
53154
55169
  const itemPath = `${path25}[${index}]`;
53155
55170
  const refs = [];
53156
55171
  if (typeof item.pageRef === "string") {
@@ -53167,7 +55182,7 @@ function collectNavigationRefs(items, path25) {
53167
55182
  }
53168
55183
  function collectBlockRefs(blocks, path25) {
53169
55184
  return blocks.flatMap((block, index) => {
53170
- if (!isRecord14(block)) return [];
55185
+ if (!isRecord17(block)) return [];
53171
55186
  const blockPath = `${path25}[${index}]`;
53172
55187
  return [
53173
55188
  ...collectNestedRefs(block.props, `${blockPath}.props`),
@@ -53183,7 +55198,7 @@ function collectNestedRefs(value, path25) {
53183
55198
  if (Array.isArray(value)) {
53184
55199
  return value.flatMap((item, index) => collectNestedRefs(item, `${path25}[${index}]`));
53185
55200
  }
53186
- if (!isRecord14(value)) return [];
55201
+ if (!isRecord17(value)) return [];
53187
55202
  return Object.entries(value).flatMap(([key, child]) => collectNestedRefs(child, `${path25}.${key}`));
53188
55203
  }
53189
55204
 
@@ -53267,7 +55282,7 @@ function parseCommandBatch(input) {
53267
55282
  if (unknownTypeErrors.length > 0) return err(unknownTypeErrors);
53268
55283
  const parsed = siteCommandBatchSchema.safeParse(input);
53269
55284
  if (!parsed.success) {
53270
- return err(parsed.error.issues.map((issue2) => invalidPayloadError(input, issue2)));
55285
+ return err(parsed.error.issues.map((issue4) => invalidPayloadError(input, issue4)));
53271
55286
  }
53272
55287
  return ok(parsed.data);
53273
55288
  }
@@ -53439,9 +55454,9 @@ function deriveIdempotencyKey(input) {
53439
55454
  ].join("|"));
53440
55455
  }
53441
55456
  function findUnknownCommandTypes(input) {
53442
- if (!isRecord14(input) || !Array.isArray(input.commands)) return [];
55457
+ if (!isRecord17(input) || !Array.isArray(input.commands)) return [];
53443
55458
  return input.commands.flatMap((command, commandIndex) => {
53444
- if (!isRecord14(command) || typeof command.type !== "string") return [];
55459
+ if (!isRecord17(command) || typeof command.type !== "string") return [];
53445
55460
  if (commandTypeSet.has(command.type)) return [];
53446
55461
  return [{
53447
55462
  code: "unknown_command_type",
@@ -53451,25 +55466,25 @@ function findUnknownCommandTypes(input) {
53451
55466
  }];
53452
55467
  });
53453
55468
  }
53454
- function invalidPayloadError(input, issue2) {
53455
- const commandIndex = commandIndexForIssuePath(issue2.path);
55469
+ function invalidPayloadError(input, issue4) {
55470
+ const commandIndex = commandIndexForIssuePath(issue4.path);
53456
55471
  const commandType = commandTypeForIssue(input, commandIndex);
53457
- const field = formatIssuePath(issue2.path);
55472
+ const field = formatIssuePath(issue4.path);
53458
55473
  return {
53459
55474
  code: "invalid_command_payload",
53460
55475
  commandIndex,
53461
55476
  commandType,
53462
55477
  field,
53463
- message: `${field}: ${issue2.message}`
55478
+ message: `${field}: ${issue4.message}`
53464
55479
  };
53465
55480
  }
53466
55481
  function commandIndexForIssuePath(path25) {
53467
55482
  return path25[0] === "commands" && typeof path25[1] === "number" ? path25[1] : -1;
53468
55483
  }
53469
55484
  function commandTypeForIssue(input, commandIndex) {
53470
- if (!isRecord14(input) || !isUnknownArray3(input.commands)) return null;
55485
+ if (!isRecord17(input) || !isUnknownArray3(input.commands)) return null;
53471
55486
  const command = input.commands[commandIndex];
53472
- return isRecord14(command) && typeof command.type === "string" ? command.type : null;
55487
+ return isRecord17(command) && typeof command.type === "string" ? command.type : null;
53473
55488
  }
53474
55489
  function isUnknownArray3(value) {
53475
55490
  return Array.isArray(value);
@@ -54136,6 +56151,186 @@ function reportSubjectForCommandRef(subjectsByCommandRef, commandRef) {
54136
56151
 
54137
56152
  // src/cli/site-commands/datedOfferingCommands.ts
54138
56153
  init_src();
56154
+
56155
+ // ../api/src/sdk-event-schedule.ts
56156
+ var timeRegex = /^([01]\d|2[0-3]):([0-5]\d)(:([0-5]\d))?$/;
56157
+ var explicitOffsetDateTimeRegex = /^(\d{4})-(\d{2})-(\d{2})T([01]\d|2[0-3]):([0-5]\d)(?::([0-5]\d))?(\.\d{1,3})?(Z|[+-]([01]\d|2[0-3]):[0-5]\d)$/;
56158
+ var localDateTimeRegex = /^(\d{4})-(\d{2})-(\d{2})T([01]\d|2[0-3]):([0-5]\d)(?::([0-5]\d))?(\.\d{1,3})?$/;
56159
+ function issue3(path25, message) {
56160
+ return { path: path25, message };
56161
+ }
56162
+ function isValidDateParts(year, month, day) {
56163
+ const date = new Date(Date.UTC(year, month - 1, day));
56164
+ return date.getUTCFullYear() === year && date.getUTCMonth() === month - 1 && date.getUTCDate() === day;
56165
+ }
56166
+ function isZeroFraction(fraction) {
56167
+ return fraction === void 0 || /^\.0+$/.test(fraction);
56168
+ }
56169
+ function datePart(year, month, day) {
56170
+ return `${year}-${month}-${day}`;
56171
+ }
56172
+ function timePart(hours, minutes, seconds = "00") {
56173
+ return `${hours}:${minutes}:${seconds}`;
56174
+ }
56175
+ function parseSdkEventDateTime(value) {
56176
+ const explicitMatch = explicitOffsetDateTimeRegex.exec(value);
56177
+ if (explicitMatch) {
56178
+ const [, yearRaw2, monthRaw2, dayRaw2, hours2, minutes2, seconds2 = "00", fraction2] = explicitMatch;
56179
+ if (!yearRaw2 || !monthRaw2 || !dayRaw2 || !hours2 || !minutes2) return null;
56180
+ const year2 = Number(yearRaw2);
56181
+ const month2 = Number(monthRaw2);
56182
+ const day2 = Number(dayRaw2);
56183
+ if (!isValidDateParts(year2, month2, day2) || !isZeroFraction(fraction2)) return null;
56184
+ const epochMs2 = Date.parse(value);
56185
+ if (!Number.isFinite(epochMs2)) return null;
56186
+ return {
56187
+ epochMs: epochMs2,
56188
+ date: datePart(yearRaw2, monthRaw2, dayRaw2),
56189
+ time: timePart(hours2, minutes2, seconds2),
56190
+ iso: new Date(epochMs2).toISOString()
56191
+ };
56192
+ }
56193
+ const localMatch = localDateTimeRegex.exec(value);
56194
+ if (!localMatch) return null;
56195
+ const [, yearRaw, monthRaw, dayRaw, hours, minutes, seconds = "00", fraction] = localMatch;
56196
+ if (!yearRaw || !monthRaw || !dayRaw || !hours || !minutes) return null;
56197
+ const year = Number(yearRaw);
56198
+ const month = Number(monthRaw);
56199
+ const day = Number(dayRaw);
56200
+ if (!isValidDateParts(year, month, day) || !isZeroFraction(fraction)) return null;
56201
+ const epochMs = Date.UTC(year, month - 1, day, Number(hours), Number(minutes), Number(seconds));
56202
+ return {
56203
+ epochMs,
56204
+ date: datePart(yearRaw, monthRaw, dayRaw),
56205
+ time: timePart(hours, minutes, seconds),
56206
+ iso: new Date(epochMs).toISOString()
56207
+ };
56208
+ }
56209
+ function durationMinutesBetween(startsAt, endsAt) {
56210
+ if (endsAt.epochMs <= startsAt.epochMs) return null;
56211
+ const durationMs = endsAt.epochMs - startsAt.epochMs;
56212
+ if (durationMs % 6e4 !== 0) return null;
56213
+ return durationMs / 6e4;
56214
+ }
56215
+ function exceedsMaxDuration(durationMinutes, options) {
56216
+ return options.maxDurationMinutes !== void 0 && durationMinutes > options.maxDurationMinutes;
56217
+ }
56218
+ function maxDurationMessage(options) {
56219
+ return options.maxDurationDays === void 0 ? "Duration is above the allowed maximum" : `Duration must be ${options.maxDurationDays} days or less`;
56220
+ }
56221
+ function classifyCanonicalSchedule(input, options) {
56222
+ const issues = [];
56223
+ if (options.requireCanonicalFields && input.recurrenceRule === void 0) {
56224
+ issues.push(issue3(["recurrenceRule"], "recurrenceRule is required"));
56225
+ }
56226
+ if (input.defaultStartTime !== void 0 && input.defaultStartTime !== null && !timeRegex.test(input.defaultStartTime)) {
56227
+ issues.push(issue3(["defaultStartTime"], "Invalid time format (HH:MM or HH:MM:SS)"));
56228
+ }
56229
+ if (options.requireCanonicalFields && !input.defaultStartTime) {
56230
+ issues.push(issue3(["defaultStartTime"], "defaultStartTime is required"));
56231
+ }
56232
+ if (options.requireCanonicalFields && input.durationMinutes === void 0) {
56233
+ issues.push(issue3(["durationMinutes"], "durationMinutes is required"));
56234
+ }
56235
+ if (input.durationMinutes !== void 0 && input.durationMinutes !== null) {
56236
+ if (input.durationMinutes < 1) {
56237
+ issues.push(issue3(["durationMinutes"], "durationMinutes must be at least 1"));
56238
+ } else if (exceedsMaxDuration(input.durationMinutes, options)) {
56239
+ issues.push(issue3(["durationMinutes"], maxDurationMessage(options)));
56240
+ }
56241
+ }
56242
+ if (issues.length > 0) return { ok: false, issues };
56243
+ return {
56244
+ ok: true,
56245
+ kind: "canonical",
56246
+ canonical: {
56247
+ recurrenceRule: input.recurrenceRule ?? null,
56248
+ startDate: input.startDate,
56249
+ defaultStartTime: input.defaultStartTime ?? "09:00:00",
56250
+ durationMinutes: input.durationMinutes ?? 60
56251
+ }
56252
+ };
56253
+ }
56254
+ function classifySdkEventSchedule(input, options = {}) {
56255
+ const issues = [];
56256
+ const hasStartsAt = input.startsAt !== void 0 && input.startsAt !== null;
56257
+ const hasEndsAt = input.endsAt !== void 0 && input.endsAt !== null;
56258
+ const hasDateTimeDuration = hasStartsAt && input.durationMinutes !== void 0 && input.durationMinutes !== null;
56259
+ const hasCanonicalStart = input.startDate !== void 0 || input.defaultStartTime !== void 0;
56260
+ if (!hasStartsAt && !hasEndsAt) {
56261
+ return classifyCanonicalSchedule(input, options);
56262
+ }
56263
+ if (hasStartsAt && hasCanonicalStart) {
56264
+ issues.push(issue3(["startsAt"], "Use either startsAt or startDate/defaultStartTime, not both"));
56265
+ }
56266
+ if (input.recurrenceRule) {
56267
+ issues.push(issue3(["recurrenceRule"], "startsAt schedules are only supported for one-off events"));
56268
+ }
56269
+ if (!hasStartsAt) {
56270
+ issues.push(issue3(["startsAt"], "startsAt is required when endsAt is provided"));
56271
+ }
56272
+ if (!hasEndsAt && !hasDateTimeDuration) {
56273
+ issues.push(issue3(["endsAt"], "Provide either endsAt or durationMinutes with startsAt"));
56274
+ }
56275
+ if (hasEndsAt && hasDateTimeDuration) {
56276
+ issues.push(issue3(["endsAt"], "Use either endsAt or durationMinutes with startsAt, not both"));
56277
+ }
56278
+ const startsAt = typeof input.startsAt === "string" ? parseSdkEventDateTime(input.startsAt) : null;
56279
+ const endsAt = typeof input.endsAt === "string" ? parseSdkEventDateTime(input.endsAt) : null;
56280
+ if (hasStartsAt && !startsAt) {
56281
+ issues.push(issue3(["startsAt"], "Invalid datetime format. Use ISO datetime format, e.g. 2026-06-01T10:00:00Z"));
56282
+ }
56283
+ if (hasEndsAt && !endsAt) {
56284
+ issues.push(issue3(["endsAt"], "Invalid datetime format. Use ISO datetime format, e.g. 2026-06-07T10:00:00Z"));
56285
+ }
56286
+ if (startsAt && endsAt) {
56287
+ const durationMinutes = durationMinutesBetween(startsAt, endsAt);
56288
+ if (durationMinutes === null) {
56289
+ issues.push(issue3(["endsAt"], "endsAt must be after startsAt and align to a whole minute"));
56290
+ } else if (exceedsMaxDuration(durationMinutes, options)) {
56291
+ issues.push(issue3(["endsAt"], maxDurationMessage(options)));
56292
+ }
56293
+ if (issues.length === 0 && durationMinutes !== null) {
56294
+ return {
56295
+ ok: true,
56296
+ kind: "start-end",
56297
+ canonical: {
56298
+ recurrenceRule: null,
56299
+ startDate: startsAt.date,
56300
+ defaultStartTime: startsAt.time,
56301
+ durationMinutes
56302
+ },
56303
+ startsAtIso: startsAt.iso,
56304
+ endsAtIso: endsAt.iso
56305
+ };
56306
+ }
56307
+ }
56308
+ if (startsAt && hasDateTimeDuration && input.durationMinutes !== void 0 && input.durationMinutes !== null) {
56309
+ if (input.durationMinutes < 1) {
56310
+ issues.push(issue3(["durationMinutes"], "durationMinutes must be at least 1"));
56311
+ } else if (exceedsMaxDuration(input.durationMinutes, options)) {
56312
+ issues.push(issue3(["durationMinutes"], maxDurationMessage(options)));
56313
+ }
56314
+ if (issues.length === 0) {
56315
+ const endsAtMs = startsAt.epochMs + input.durationMinutes * 6e4;
56316
+ return {
56317
+ ok: true,
56318
+ kind: "start-duration",
56319
+ canonical: {
56320
+ recurrenceRule: null,
56321
+ startDate: startsAt.date,
56322
+ defaultStartTime: startsAt.time,
56323
+ durationMinutes: input.durationMinutes
56324
+ },
56325
+ startsAtIso: startsAt.iso,
56326
+ endsAtIso: new Date(endsAtMs).toISOString()
56327
+ };
56328
+ }
56329
+ }
56330
+ return { ok: false, issues };
56331
+ }
56332
+
56333
+ // src/cli/site-commands/datedOfferingCommands.ts
54139
56334
  var datedOfferingSiteCommandTypes = [
54140
56335
  "upsertVenue",
54141
56336
  "deleteVenue",
@@ -54151,72 +56346,105 @@ function compileDatedOfferingPushCommands(input) {
54151
56346
  for (const venue of input.venues?.items ?? []) {
54152
56347
  const command = venueCommand(venue.item);
54153
56348
  if (!command.ok) return command;
54154
- commandBindings.push(commandBinding(command.value, {
54155
- scopeCommand: "venues",
54156
- scopeName: "venues",
54157
- itemLabelSingular: "venue",
54158
- identifier: venue.item.slug,
54159
- counter: venue.exists ? "updated" : "created"
54160
- }));
56349
+ commandBindings.push(
56350
+ commandBinding(command.value, {
56351
+ scopeCommand: "venues",
56352
+ scopeName: "venues",
56353
+ itemLabelSingular: "venue",
56354
+ identifier: venue.item.slug,
56355
+ counter: venue.exists ? "updated" : "created"
56356
+ })
56357
+ );
54161
56358
  }
54162
56359
  for (const category of input.eventCategories?.items ?? []) {
54163
- commandBindings.push(commandBinding(eventCategoryCommand(category.item), {
54164
- scopeCommand: "event-categories",
54165
- scopeName: "event categories",
54166
- itemLabelSingular: "event category",
54167
- identifier: category.item.identifier,
54168
- counter: category.exists ? "updated" : "created"
54169
- }));
56360
+ commandBindings.push(
56361
+ commandBinding(eventCategoryCommand(category.item), {
56362
+ scopeCommand: "event-categories",
56363
+ scopeName: "event categories",
56364
+ itemLabelSingular: "event category",
56365
+ identifier: category.item.identifier,
56366
+ counter: category.exists ? "updated" : "created"
56367
+ })
56368
+ );
54170
56369
  }
54171
56370
  for (const event of input.events?.items ?? []) {
54172
56371
  const command = eventSeriesCommand(event.item);
54173
56372
  if (!command.ok) return command;
54174
- commandBindings.push(commandBinding(command.value, {
54175
- scopeCommand: "events",
54176
- scopeName: "events",
54177
- itemLabelSingular: "event",
54178
- identifier: event.item.identifier,
54179
- counter: event.exists ? "updated" : "created"
54180
- }));
56373
+ commandBindings.push(
56374
+ commandBinding(command.value, {
56375
+ scopeCommand: "events",
56376
+ scopeName: "events",
56377
+ itemLabelSingular: "event",
56378
+ identifier: event.item.identifier,
56379
+ counter: event.exists ? "updated" : "created"
56380
+ })
56381
+ );
54181
56382
  }
54182
56383
  for (const course of input.courses?.items ?? []) {
54183
56384
  const command = courseCommand(course.item);
54184
56385
  if (!command.ok) return command;
54185
- commandBindings.push(commandBinding(command.value, {
54186
- scopeCommand: "courses",
54187
- scopeName: "courses",
54188
- itemLabelSingular: "course",
54189
- identifier: course.item.identifier,
54190
- counter: course.exists ? "updated" : "created"
54191
- }));
56386
+ commandBindings.push(
56387
+ commandBinding(command.value, {
56388
+ scopeCommand: "courses",
56389
+ scopeName: "courses",
56390
+ itemLabelSingular: "course",
56391
+ identifier: course.item.identifier,
56392
+ counter: course.exists ? "updated" : "created"
56393
+ })
56394
+ );
54192
56395
  }
54193
56396
  for (const identifier of input.delete?.events ?? []) {
54194
- commandBindings.push(commandBinding({
54195
- type: "deleteEventSeries",
54196
- ref: createCommandRef("delete-event", [identifier]),
54197
- input: { identifier }
54198
- }, deleteSubject("events", "events", "event", identifier)));
56397
+ commandBindings.push(
56398
+ commandBinding(
56399
+ {
56400
+ type: "deleteEventSeries",
56401
+ ref: createCommandRef("delete-event", [identifier]),
56402
+ input: { identifier }
56403
+ },
56404
+ deleteSubject("events", "events", "event", identifier)
56405
+ )
56406
+ );
54199
56407
  }
54200
56408
  for (const identifier of input.delete?.courses ?? []) {
54201
- commandBindings.push(commandBinding({
54202
- type: "deleteCourse",
54203
- ref: createCommandRef("delete-course", [identifier]),
54204
- input: { identifier }
54205
- }, deleteSubject("courses", "courses", "course", identifier)));
56409
+ commandBindings.push(
56410
+ commandBinding(
56411
+ {
56412
+ type: "deleteCourse",
56413
+ ref: createCommandRef("delete-course", [identifier]),
56414
+ input: { identifier }
56415
+ },
56416
+ deleteSubject("courses", "courses", "course", identifier)
56417
+ )
56418
+ );
54206
56419
  }
54207
56420
  for (const slug of input.delete?.venues ?? []) {
54208
- commandBindings.push(commandBinding({
54209
- type: "deleteVenue",
54210
- ref: createCommandRef("delete-venue", [slug]),
54211
- input: { slug }
54212
- }, deleteSubject("venues", "venues", "venue", slug)));
56421
+ commandBindings.push(
56422
+ commandBinding(
56423
+ {
56424
+ type: "deleteVenue",
56425
+ ref: createCommandRef("delete-venue", [slug]),
56426
+ input: { slug }
56427
+ },
56428
+ deleteSubject("venues", "venues", "venue", slug)
56429
+ )
56430
+ );
54213
56431
  }
54214
56432
  for (const identifier of input.delete?.eventCategories ?? []) {
54215
- commandBindings.push(commandBinding({
54216
- type: "deleteEventCategory",
54217
- ref: createCommandRef("delete-event-category", [identifier]),
54218
- input: { identifier }
54219
- }, deleteSubject("event-categories", "event categories", "event category", identifier)));
56433
+ commandBindings.push(
56434
+ commandBinding(
56435
+ {
56436
+ type: "deleteEventCategory",
56437
+ ref: createCommandRef("delete-event-category", [identifier]),
56438
+ input: { identifier }
56439
+ },
56440
+ deleteSubject(
56441
+ "event-categories",
56442
+ "event categories",
56443
+ "event category",
56444
+ identifier
56445
+ )
56446
+ )
56447
+ );
54220
56448
  }
54221
56449
  const planned = planCliCommandBatchForBindings({
54222
56450
  ...input,
@@ -54281,10 +56509,16 @@ function deleteSubject(scopeCommand, scopeName, itemLabelSingular, identifier) {
54281
56509
  }
54282
56510
  function venueCommand(venue) {
54283
56511
  if (!venue.timezone) {
54284
- return unsupported(venue.slug, `Venue ${venue.slug} is missing timezone; command-backed venue pushes require an IANA timezone.`);
56512
+ return unsupported(
56513
+ venue.slug,
56514
+ `Venue ${venue.slug} is missing timezone; command-backed venue pushes require an IANA timezone.`
56515
+ );
54285
56516
  }
54286
56517
  if (venue.location && (typeof venue.location.lat !== "number" || typeof venue.location.lng !== "number")) {
54287
- return unsupported(venue.slug, `Venue ${venue.slug} has an incomplete location; command-backed venue pushes require both lat and lng.`);
56518
+ return unsupported(
56519
+ venue.slug,
56520
+ `Venue ${venue.slug} has an incomplete location; command-backed venue pushes require both lat and lng.`
56521
+ );
54288
56522
  }
54289
56523
  const location2 = venue.location && typeof venue.location.lat === "number" && typeof venue.location.lng === "number" ? {
54290
56524
  latitude: venue.location.lat,
@@ -54327,10 +56561,16 @@ function eventCategoryCommand(category) {
54327
56561
  }
54328
56562
  function eventSeriesCommand(event) {
54329
56563
  if (event.identifier !== event.slug) {
54330
- return unsupported(event.identifier, `Event identifier "${event.identifier}" must match slug "${event.slug}".`);
56564
+ return unsupported(
56565
+ event.identifier,
56566
+ `Event identifier "${event.identifier}" must match slug "${event.slug}".`
56567
+ );
54331
56568
  }
54332
56569
  if (event.schedule?.recurrenceRule) {
54333
- return unsupported(event.identifier, `Event ${event.identifier} uses recurrenceRule; command-backed SDK pushes currently support one-off events only.`);
56570
+ return unsupported(
56571
+ event.identifier,
56572
+ `Event ${event.identifier} uses recurrenceRule; command-backed SDK pushes currently support one-off events only.`
56573
+ );
54334
56574
  }
54335
56575
  const occurrence = eventOccurrence(event);
54336
56576
  if (!occurrence.ok) return occurrence;
@@ -54354,8 +56594,8 @@ function eventSeriesCommand(event) {
54354
56594
  capacity: capacity(event.capacity),
54355
56595
  pricing: pricing.value,
54356
56596
  priceDisplay: event.pricing?.priceDisplay ?? void 0,
54357
- acceptsPasses: event.pricing?.acceptsPasses,
54358
- acceptsMemberships: event.pricing?.acceptsMemberships,
56597
+ acceptsPasses: event.pricing?.acceptsPasses ?? void 0,
56598
+ acceptsMemberships: event.pricing?.acceptsMemberships ?? void 0,
54359
56599
  occurrences: [occurrence.value],
54360
56600
  content: event.content ? {
54361
56601
  summary: event.content.summary ?? void 0,
@@ -54370,7 +56610,10 @@ function eventSeriesCommand(event) {
54370
56610
  }
54371
56611
  function courseCommand(course) {
54372
56612
  if (course.identifier !== course.slug) {
54373
- return unsupported(course.identifier, `Course identifier "${course.identifier}" must match slug "${course.slug}".`);
56613
+ return unsupported(
56614
+ course.identifier,
56615
+ `Course identifier "${course.identifier}" must match slug "${course.slug}".`
56616
+ );
54374
56617
  }
54375
56618
  const pricing = coursePricing(course);
54376
56619
  if (!pricing.ok) return pricing;
@@ -54402,39 +56645,74 @@ function courseCommand(course) {
54402
56645
  });
54403
56646
  }
54404
56647
  function eventOccurrence(event) {
56648
+ const scheduleClassification = classifySdkEventSchedule(event.schedule ?? {});
56649
+ if (!scheduleClassification.ok) {
56650
+ return unsupported(
56651
+ event.identifier,
56652
+ `Event ${event.identifier} has an invalid schedule: ${scheduleClassification.issues.map((validationIssue) => validationIssue.message).join("; ")}`
56653
+ );
56654
+ }
56655
+ if (scheduleClassification.kind === "start-end" || scheduleClassification.kind === "start-duration") {
56656
+ return ok({
56657
+ startAt: scheduleClassification.startsAtIso,
56658
+ endAt: scheduleClassification.endsAtIso
56659
+ });
56660
+ }
54405
56661
  const startDate = event.schedule?.startDate;
54406
56662
  if (!startDate) {
54407
- return unsupported(event.identifier, `Event ${event.identifier} is missing schedule.startDate; command-backed event pushes require a concrete occurrence.`);
56663
+ return unsupported(
56664
+ event.identifier,
56665
+ `Event ${event.identifier} is missing schedule.startDate; command-backed event pushes require a concrete occurrence.`
56666
+ );
54408
56667
  }
54409
56668
  const startTime = event.schedule?.defaultStartTime ?? "09:00:00";
54410
56669
  const durationMinutes = event.schedule?.durationMinutes ?? 60;
54411
56670
  const startAt = toUtcIso(startDate, startTime);
54412
- const endAt = new Date(Date.parse(startAt) + durationMinutes * 6e4).toISOString();
56671
+ const endAt = new Date(
56672
+ Date.parse(startAt) + durationMinutes * 6e4
56673
+ ).toISOString();
54413
56674
  return ok({
54414
56675
  startAt,
54415
56676
  endAt
54416
56677
  });
54417
56678
  }
54418
56679
  function eventPricing(event) {
54419
- const pricing = event.pricing;
54420
- if (!pricing?.requiresPayment) return ok({ kind: "free" });
54421
- const amount = pricing.priceAmount;
54422
- if (typeof amount !== "number" || amount < 0) {
54423
- return unsupported(event.identifier, `Event ${event.identifier} requires payment but has no valid priceAmount.`);
56680
+ const pricing = classifySdkEventPricing(event.pricing);
56681
+ if (!pricing.ok) {
56682
+ return unsupported(
56683
+ event.identifier,
56684
+ `Event ${event.identifier} has invalid pricing: ${pricing.issues[0]?.message ?? "invalid pricing"}.`
56685
+ );
56686
+ }
56687
+ switch (pricing.pricing.kind) {
56688
+ case "free":
56689
+ return ok({ kind: "free" });
56690
+ case "fixed_price":
56691
+ return ok({
56692
+ kind: "fixed_price",
56693
+ price: {
56694
+ amountCents: pricing.pricing.priceAmount,
56695
+ currency: pricing.pricing.priceCurrency
56696
+ }
56697
+ });
56698
+ case "ticket_types":
56699
+ return unsupported(
56700
+ event.identifier,
56701
+ `Event ${event.identifier} uses ticket-type pricing; command-backed event pushes do not support ticket types yet.`
56702
+ );
56703
+ default:
56704
+ return assertNever(pricing.pricing);
54424
56705
  }
54425
- return ok({
54426
- kind: "fixed_price",
54427
- price: {
54428
- amountCents: amount,
54429
- currency: pricing.priceCurrency
54430
- }
54431
- });
54432
56706
  }
54433
56707
  function coursePricing(course) {
54434
56708
  const amount = course.priceCents;
54435
- if (amount === void 0 || amount === null || amount === 0) return ok({ kind: "free" });
56709
+ if (amount === void 0 || amount === null || amount === 0)
56710
+ return ok({ kind: "free" });
54436
56711
  if (amount < 0) {
54437
- return unsupported(course.identifier, `Course ${course.identifier} has invalid priceCents.`);
56712
+ return unsupported(
56713
+ course.identifier,
56714
+ `Course ${course.identifier} has invalid priceCents.`
56715
+ );
54438
56716
  }
54439
56717
  return ok({
54440
56718
  kind: "fixed_price",
@@ -54468,7 +56746,8 @@ function venueUpsertInput(command) {
54468
56746
  }
54469
56747
  function eventSeriesUpsertInput(command) {
54470
56748
  const occurrence = command.input.occurrences[0];
54471
- if (!occurrence) throw new Error(`Event command ${command.ref} has no occurrence.`);
56749
+ if (!occurrence)
56750
+ throw new Error(`Event command ${command.ref} has no occurrence.`);
54472
56751
  return {
54473
56752
  identifier: command.input.slug,
54474
56753
  title: command.input.title,
@@ -54491,8 +56770,8 @@ function eventContentInput(content) {
54491
56770
  if (!content) return void 0;
54492
56771
  return {
54493
56772
  ...content.summary ? { summary: content.summary } : {},
54494
- ...typeof content.body === "string" || isRecord15(content.body) ? { body: content.body } : {},
54495
- ...typeof content.image === "string" || isRecord15(content.image) ? { image: content.image } : {}
56773
+ ...typeof content.body === "string" || isRecord18(content.body) ? { body: content.body } : {},
56774
+ ...typeof content.image === "string" || isRecord18(content.image) ? { image: content.image } : {}
54496
56775
  };
54497
56776
  }
54498
56777
  function courseUpsertInput(command) {
@@ -54524,34 +56803,29 @@ function eventPricingInput(input) {
54524
56803
  switch (input.pricing.kind) {
54525
56804
  case "free":
54526
56805
  return {
54527
- requiresPayment: false,
54528
- priceAmount: null,
54529
- priceCurrency: null,
56806
+ kind: "free",
54530
56807
  priceDisplay: input.priceDisplay ?? null,
54531
56808
  acceptsPasses: input.acceptsPasses ?? false,
54532
56809
  acceptsMemberships: input.acceptsMemberships ?? false
54533
56810
  };
54534
56811
  case "fixed_price":
54535
56812
  return {
54536
- requiresPayment: input.pricing.price.amountCents > 0,
56813
+ kind: "fixed_price",
54537
56814
  priceAmount: input.pricing.price.amountCents,
54538
- priceCurrency: input.pricing.price.currency ?? null,
56815
+ priceCurrency: input.pricing.price.currency ?? "USD",
54539
56816
  priceDisplay: input.priceDisplay ?? null,
54540
56817
  acceptsPasses: input.acceptsPasses ?? false,
54541
56818
  acceptsMemberships: input.acceptsMemberships ?? false
54542
56819
  };
54543
56820
  case "ticket_types":
54544
- return {
54545
- requiresPayment: false,
54546
- priceAmount: null,
54547
- priceCurrency: input.pricing.currency ?? null,
54548
- priceDisplay: input.priceDisplay ?? null,
54549
- acceptsPasses: input.acceptsPasses ?? false,
54550
- acceptsMemberships: input.acceptsMemberships ?? false
54551
- };
56821
+ throw new Error(
56822
+ "Unsupported ticket-type event command reached SDK mapper."
56823
+ );
54552
56824
  case "manual_payment":
54553
56825
  case "external":
54554
- throw new Error(`Unsupported event pricing mode reached SDK mapper: ${input.pricing.kind}`);
56826
+ throw new Error(
56827
+ `Unsupported event pricing mode reached SDK mapper: ${input.pricing.kind}`
56828
+ );
54555
56829
  default:
54556
56830
  return assertNever(input.pricing);
54557
56831
  }
@@ -54567,7 +56841,9 @@ function coursePricingInput(pricing) {
54567
56841
  };
54568
56842
  case "manual_payment":
54569
56843
  case "external":
54570
- throw new Error(`Unsupported course pricing mode reached SDK mapper: ${pricing.kind}`);
56844
+ throw new Error(
56845
+ `Unsupported course pricing mode reached SDK mapper: ${pricing.kind}`
56846
+ );
54571
56847
  default:
54572
56848
  return assertNever(pricing);
54573
56849
  }
@@ -54657,14 +56933,16 @@ function scheduleFromOccurrence(occurrence) {
54657
56933
  recurrenceRule: null,
54658
56934
  startDate: occurrence.startAt.slice(0, 10),
54659
56935
  defaultStartTime: occurrence.startAt.slice(11, 19),
54660
- durationMinutes: Math.round((Date.parse(occurrence.endAt) - Date.parse(occurrence.startAt)) / 6e4)
56936
+ durationMinutes: Math.round(
56937
+ (Date.parse(occurrence.endAt) - Date.parse(occurrence.startAt)) / 6e4
56938
+ )
54661
56939
  };
54662
56940
  }
54663
56941
  function toUtcIso(date, time) {
54664
56942
  const normalizedTime = time.length === 5 ? `${time}:00` : time;
54665
56943
  return (/* @__PURE__ */ new Date(`${date}T${normalizedTime}Z`)).toISOString();
54666
56944
  }
54667
- function isRecord15(value) {
56945
+ function isRecord18(value) {
54668
56946
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
54669
56947
  }
54670
56948
  function unsupported(identifier, message) {
@@ -54777,7 +57055,8 @@ async function executeEntryCommandPlan(input) {
54777
57055
  contentType: command.input.contentTypeKey,
54778
57056
  data: command.input.data ?? {},
54779
57057
  slug: command.input.slug,
54780
- manualOrder: command.input.manualOrder
57058
+ manualOrder: command.input.manualOrder,
57059
+ blocks: command.input.blocks
54781
57060
  });
54782
57061
  return;
54783
57062
  }
@@ -54902,7 +57181,8 @@ function entryCommandsForDiff(input) {
54902
57181
  ...localEntry.slug ? { slug: localEntry.slug } : {},
54903
57182
  ...typeof localEntry.manualOrder === "number" ? { manualOrder: localEntry.manualOrder } : {},
54904
57183
  ...optionalTitle(localEntry.data),
54905
- data: localEntry.data
57184
+ data: localEntry.data,
57185
+ ...localEntry.blocks ? { blocks: localEntry.blocks } : {}
54906
57186
  }
54907
57187
  };
54908
57188
  commandBindings.push({
@@ -55504,15 +57784,15 @@ function validateBlockContent(data, manifest, customFields) {
55504
57784
  validator.parse(data);
55505
57785
  } catch (error) {
55506
57786
  if (error instanceof ZodError) {
55507
- for (const issue2 of error.issues) {
55508
- const fieldPath = issue2.path.join(".");
55509
- if (issue2.code === "invalid_type" && issue2.received === "undefined") {
57787
+ for (const issue4 of error.issues) {
57788
+ const fieldPath = issue4.path.join(".");
57789
+ if (issue4.code === "invalid_type" && issue4.received === "undefined") {
55510
57790
  continue;
55511
57791
  }
55512
57792
  warnings.push({
55513
57793
  type: "invalid_content",
55514
57794
  field: fieldPath || "(root)",
55515
- message: `Invalid content${fieldPath ? ` in "${fieldPath}"` : ""}: ${issue2.message}`
57795
+ message: `Invalid content${fieldPath ? ` in "${fieldPath}"` : ""}: ${issue4.message}`
55516
57796
  });
55517
57797
  }
55518
57798
  }
@@ -56948,7 +59228,7 @@ async function handleThemePushForAllScope(params) {
56948
59228
  }
56949
59229
  const validation = themeSchema2.safeParse(localTheme.theme);
56950
59230
  if (!validation.success) {
56951
- const errors = validation.error.issues.map((issue2) => ` - ${issue2.path.join(".")}: ${issue2.message}`).join("\n");
59231
+ const errors = validation.error.issues.map((issue4) => ` - ${issue4.path.join(".")}: ${issue4.message}`).join("\n");
56952
59232
  output.warn(
56953
59233
  `Skipping theme push - invalid theme at content/themes/${themeName}.json:
56954
59234
  ${errors}`
@@ -57557,9 +59837,14 @@ function entriesEqual(left, right) {
57557
59837
  function contentFields(entry) {
57558
59838
  const data = structuredClone(entry.data);
57559
59839
  stripEnvSpecificMediaFieldsInPlace(data);
59840
+ const blocks = entry.blocks ? structuredClone(entry.blocks) : void 0;
59841
+ if (blocks) {
59842
+ stripEnvSpecificMediaFieldsInPlace(blocks);
59843
+ }
57560
59844
  return {
57561
59845
  identifier: entry.identifier,
57562
59846
  data: sortRecord(data),
59847
+ ...blocks ? { blocks: sortRecord(blocks) } : {},
57563
59848
  ...entry.slug !== void 0 ? { slug: entry.slug } : {}
57564
59849
  };
57565
59850
  }
@@ -58429,7 +60714,7 @@ ${available.map((t) => ` - ${t.name} (content/themes/${t.name}.json)`).join("\n
58429
60714
  }
58430
60715
  const validation = themeSchema.safeParse(localTheme.theme);
58431
60716
  if (!validation.success) {
58432
- const errors = validation.error.issues.map((issue2) => ` - ${issue2.path.join(".")}: ${issue2.message}`).join("\n");
60717
+ const errors = validation.error.issues.map((issue4) => ` - ${issue4.path.join(".")}: ${issue4.message}`).join("\n");
58433
60718
  output.error(
58434
60719
  `Invalid theme file at content/themes/${themeName}.json:
58435
60720
  ${errors}`
@@ -59588,7 +61873,8 @@ async function applyOneOffEntryCommand(command, client) {
59588
61873
  identifier: entryIdentifierForCommand(command),
59589
61874
  contentType: command.input.contentTypeKey,
59590
61875
  data: command.input.data ?? {},
59591
- slug: command.input.slug
61876
+ slug: command.input.slug,
61877
+ blocks: command.input.blocks
59592
61878
  });
59593
61879
  case "publishContentEntry":
59594
61880
  await client.entries.publish(
@@ -60721,7 +63007,7 @@ var THEME_FIELD_CATEGORY_MAP = {
60721
63007
  };
60722
63008
 
60723
63009
  // src/cli/init-docs/zod-to-markdown.ts
60724
- function isRecord16(value) {
63010
+ function isRecord19(value) {
60725
63011
  return typeof value === "object" && value !== null && !Array.isArray(value);
60726
63012
  }
60727
63013
  function isZodTypeAny(value) {
@@ -60849,7 +63135,7 @@ function extractLiteralValue(schema) {
60849
63135
  const typeName = getTypeName(schema);
60850
63136
  if (typeName !== ZodTypeName.ZodLiteral) return void 0;
60851
63137
  const def = schema._def;
60852
- if (!isRecord16(def)) return void 0;
63138
+ if (!isRecord19(def)) return void 0;
60853
63139
  return String(def.value);
60854
63140
  }
60855
63141
  function extractSchemaInfo(schema, skipFields = []) {
@@ -60919,7 +63205,7 @@ function extractFieldInfo(name, schema) {
60919
63205
  }
60920
63206
  if (typeName === ZodTypeName.ZodRecord) {
60921
63207
  const def = inner._def;
60922
- const valueSchema = isRecord16(def) ? def.valueType : void 0;
63208
+ const valueSchema = isRecord19(def) ? def.valueType : void 0;
60923
63209
  if (!isZodTypeAny(valueSchema)) {
60924
63210
  info.recordValueType = "unknown";
60925
63211
  return info;
@@ -60934,7 +63220,7 @@ function extractFieldInfo(name, schema) {
60934
63220
  }
60935
63221
  } else if (getTypeName(valueInner) === ZodTypeName.ZodRecord) {
60936
63222
  const nestedDef = valueInner._def;
60937
- const nestedValueSchema = isRecord16(nestedDef) ? nestedDef.valueType : void 0;
63223
+ const nestedValueSchema = isRecord19(nestedDef) ? nestedDef.valueType : void 0;
60938
63224
  if (!isZodTypeAny(nestedValueSchema)) {
60939
63225
  info.recordValueType = "record<string, unknown>";
60940
63226
  return info;
@@ -60945,7 +63231,7 @@ function extractFieldInfo(name, schema) {
60945
63231
  }
60946
63232
  if (typeName === ZodTypeName.ZodUnion || typeName === ZodTypeName.ZodDiscriminatedUnion) {
60947
63233
  const def = inner._def;
60948
- const optionsValue = isRecord16(def) ? def.options : void 0;
63234
+ const optionsValue = isRecord19(def) ? def.options : void 0;
60949
63235
  const options = Array.isArray(optionsValue) ? optionsValue.filter(isZodTypeAny) : [];
60950
63236
  const optionTypes = options.map((opt) => {
60951
63237
  const { inner: optInner } = unwrapSchema(opt);
@@ -61781,7 +64067,8 @@ async function initDocs(options) {
61781
64067
  { filename: "cmsify-page.md", template: "workflow-cmsify-page" },
61782
64068
  { filename: "editor-workflows.md", template: "workflow-editor-workflows" },
61783
64069
  { filename: "preview-mode.md", template: "workflow-preview-mode" },
61784
- { filename: "isr-revalidation.md", template: "workflow-isr-revalidation" }
64070
+ { filename: "isr-revalidation.md", template: "workflow-isr-revalidation" },
64071
+ { filename: "agent-safe-sync.md", template: "workflow-agent-safe-sync" }
61785
64072
  ];
61786
64073
  await Promise.all(
61787
64074
  coreWorkflows.map(
@@ -62109,7 +64396,7 @@ var SimpleCache = class {
62109
64396
  };
62110
64397
 
62111
64398
  // src/version.ts
62112
- var SDK_VERSION = "0.82.0";
64399
+ var SDK_VERSION = "0.84.1";
62113
64400
 
62114
64401
  // src/client/error.ts
62115
64402
  var RiverbankApiError = class _RiverbankApiError extends Error {
@@ -64201,9 +66488,9 @@ Examples:
64201
66488
  const parseResult = verifyConfigSchema.safeParse(rawConfig);
64202
66489
  if (!parseResult.success) {
64203
66490
  return output.error("Invalid config format", {
64204
- issues: parseResult.error.issues.map((issue2) => ({
64205
- path: issue2.path.join("."),
64206
- message: issue2.message
66491
+ issues: parseResult.error.issues.map((issue4) => ({
66492
+ path: issue4.path.join("."),
66493
+ message: issue4.message
64207
66494
  })),
64208
66495
  suggestion: "Ensure your config exports a valid riverbank config object"
64209
66496
  });
@@ -64731,8 +67018,8 @@ async function executeAuditForEnv(output, target, options, isJsonOutput) {
64731
67018
  client
64732
67019
  });
64733
67020
  const mediaIssues = mapMediaGuardDiagnosticsToAuditIssues(mediaGuardResult.diagnostics);
64734
- errors.push(...mediaIssues.filter((issue2) => issue2.severity === "error"));
64735
- warnings.push(...mediaIssues.filter((issue2) => issue2.severity === "warning"));
67021
+ errors.push(...mediaIssues.filter((issue4) => issue4.severity === "error"));
67022
+ warnings.push(...mediaIssues.filter((issue4) => issue4.severity === "warning"));
64736
67023
  }
64737
67024
  if (!isJsonOutput) {
64738
67025
  output.info("Checking for duplicate page paths...");
@@ -64756,8 +67043,8 @@ async function executeAuditForEnv(output, target, options, isJsonOutput) {
64756
67043
  }
64757
67044
  errors.push(...auditEventReferences(localContent.events, auditCtx));
64758
67045
  const courseRefIssues = auditCourseReferences(localContent.courses, auditCtx);
64759
- errors.push(...courseRefIssues.filter((issue2) => issue2.severity === "error"));
64760
- warnings.push(...courseRefIssues.filter((issue2) => issue2.severity === "warning"));
67046
+ errors.push(...courseRefIssues.filter((issue4) => issue4.severity === "error"));
67047
+ warnings.push(...courseRefIssues.filter((issue4) => issue4.severity === "warning"));
64761
67048
  const success = errors.length === 0;
64762
67049
  const result = { success, errors, warnings };
64763
67050
  if (isJsonOutput) {
@@ -64772,14 +67059,14 @@ async function executeAuditForEnv(output, target, options, isJsonOutput) {
64772
67059
  output.info("");
64773
67060
  if (errors.length > 0) {
64774
67061
  output.warn(`Found ${errors.length} error(s):`);
64775
- for (const issue2 of errors) {
64776
- output.info(` [ERROR] ${issue2.message}`);
67062
+ for (const issue4 of errors) {
67063
+ output.info(` [ERROR] ${issue4.message}`);
64777
67064
  }
64778
67065
  }
64779
67066
  if (warnings.length > 0) {
64780
67067
  output.warn(`Found ${warnings.length} warning(s):`);
64781
- for (const issue2 of warnings) {
64782
- output.info(` [WARN] ${issue2.message}`);
67068
+ for (const issue4 of warnings) {
67069
+ output.info(` [WARN] ${issue4.message}`);
64783
67070
  }
64784
67071
  }
64785
67072
  if (success && warnings.length === 0) {
@@ -68629,27 +70916,76 @@ var envStatusCommand = new Command("status").description("Show which environment
68629
70916
  })
68630
70917
  );
68631
70918
  var envCommand = new Command("env").description("Environment configuration and status").addCommand(envStatusCommand);
70919
+ var eventScheduleInputSchema = z.object({
70920
+ recurrenceRule: z.string().nullable().optional(),
70921
+ startDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).nullable().optional(),
70922
+ defaultStartTime: z.string().min(1).optional(),
70923
+ durationMinutes: z.number().int().positive().optional(),
70924
+ startsAt: z.string().min(1).optional(),
70925
+ endsAt: z.string().min(1).optional()
70926
+ }).superRefine((schedule, ctx) => {
70927
+ const result = classifySdkEventSchedule(schedule, {
70928
+ requireCanonicalFields: true
70929
+ });
70930
+ if (!result.ok) {
70931
+ result.issues.forEach((validationIssue) => {
70932
+ ctx.addIssue({
70933
+ code: "custom",
70934
+ path: [...validationIssue.path],
70935
+ message: validationIssue.message
70936
+ });
70937
+ });
70938
+ }
70939
+ }).transform((schedule) => {
70940
+ const result = classifySdkEventSchedule(schedule, {
70941
+ requireCanonicalFields: true
70942
+ });
70943
+ if (!result.ok) {
70944
+ throw new Error("Unreachable invalid event schedule after Zod validation");
70945
+ }
70946
+ if (result.kind === "start-end") {
70947
+ const { startsAt, endsAt } = schedule;
70948
+ if (typeof startsAt !== "string" || typeof endsAt !== "string") {
70949
+ throw new Error("Unreachable invalid start/end event schedule after Zod validation");
70950
+ }
70951
+ return { startsAt, endsAt };
70952
+ }
70953
+ if (result.kind === "start-duration") {
70954
+ const { startsAt, durationMinutes } = schedule;
70955
+ if (typeof startsAt !== "string" || typeof durationMinutes !== "number") {
70956
+ throw new Error("Unreachable invalid start/duration event schedule after Zod validation");
70957
+ }
70958
+ return { startsAt, durationMinutes };
70959
+ }
70960
+ return result.canonical;
70961
+ });
70962
+ var eventPricingInputSchema = z.unknown().superRefine((pricing, ctx) => {
70963
+ const result = classifySdkEventPricing(pricing);
70964
+ if (!result.ok) {
70965
+ result.issues.forEach((validationIssue) => {
70966
+ ctx.addIssue({
70967
+ code: "custom",
70968
+ path: [...validationIssue.path],
70969
+ message: validationIssue.message
70970
+ });
70971
+ });
70972
+ }
70973
+ }).transform((pricing) => {
70974
+ const result = classifySdkEventPricing(pricing);
70975
+ if (!result.ok) {
70976
+ throw new Error("Unreachable invalid event pricing after Zod validation");
70977
+ }
70978
+ return result.pricing;
70979
+ });
68632
70980
  var eventUpsertInputSchema = z.object({
68633
70981
  identifier: z.string().min(1).optional(),
68634
70982
  title: z.string().min(1, "title is required"),
68635
70983
  slug: z.string().min(1).optional(),
68636
70984
  status: z.enum(["draft", "active", "archived", "cancelled", "completed"]).optional(),
68637
70985
  visibility: z.enum(["private", "public", "unlisted"]).optional(),
68638
- schedule: z.object({
68639
- recurrenceRule: z.string().nullable(),
68640
- startDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).nullable().optional(),
68641
- defaultStartTime: z.string().min(1),
68642
- durationMinutes: z.number().int().positive()
68643
- }),
70986
+ schedule: eventScheduleInputSchema,
68644
70987
  capacity: z.number().int().positive().nullable().optional(),
68645
- pricing: z.object({
68646
- requiresPayment: z.boolean().optional(),
68647
- priceAmount: z.number().nullable().optional(),
68648
- priceCurrency: z.string().nullable().optional(),
68649
- priceDisplay: z.string().nullable().optional(),
68650
- acceptsPasses: z.boolean().optional(),
68651
- acceptsMemberships: z.boolean().optional()
68652
- }).optional(),
70988
+ pricing: eventPricingInputSchema.optional(),
68653
70989
  venueRef: z.string().nullable().optional(),
68654
70990
  categoryRef: z.string().nullable().optional(),
68655
70991
  content: z.record(z.string(), z.unknown()).optional(),
@@ -68683,7 +71019,13 @@ function toEventUpsertInput(identifier, raw) {
68683
71019
  return payload;
68684
71020
  }
68685
71021
  function buildCancelledEventUpsertInput(current) {
68686
- const { id: _id, createdAt: _createdAt, updatedAt: _updatedAt, contentUpdatedAt: _contentUpdatedAt, ...rest } = current;
71022
+ const {
71023
+ id: _id,
71024
+ createdAt: _createdAt,
71025
+ updatedAt: _updatedAt,
71026
+ contentUpdatedAt: _contentUpdatedAt,
71027
+ ...rest
71028
+ } = current;
68687
71029
  return {
68688
71030
  ...rest,
68689
71031
  status: "cancelled"
@@ -68693,23 +71035,25 @@ function canCancelEventStatus(status) {
68693
71035
  return status === "draft" || status === "active";
68694
71036
  }
68695
71037
  var upsertCommand5 = new Command("upsert").description("Create or update an event series").argument("<identifier>", "Event identifier").option("--data <json>", "Event payload as JSON string").option("--file <path>", "Path to JSON file with event payload").action(
68696
- withErrorHandling(async (identifier, options, command) => {
68697
- const { output, client } = createCommandContext(command);
68698
- const raw = await parseJsonData(options);
68699
- if (raw.status === "completed") {
68700
- output.warn(
68701
- `Event ${identifier}: status "completed" is read-only; omitting status on upsert.`
68702
- );
71038
+ withErrorHandling(
71039
+ async (identifier, options, command) => {
71040
+ const { output, client } = createCommandContext(command);
71041
+ const raw = await parseJsonData(options);
71042
+ if (raw.status === "completed") {
71043
+ output.warn(
71044
+ `Event ${identifier}: status "completed" is read-only; omitting status on upsert.`
71045
+ );
71046
+ }
71047
+ const input = toEventUpsertInput(identifier, raw);
71048
+ output.info(`Upserting event: ${identifier}`);
71049
+ const event = await client.events.upsert(input);
71050
+ output.success(`Event upserted: ${event.identifier}`, {
71051
+ id: event.id,
71052
+ status: event.status,
71053
+ visibility: event.visibility
71054
+ });
68703
71055
  }
68704
- const input = toEventUpsertInput(identifier, raw);
68705
- output.info(`Upserting event: ${identifier}`);
68706
- const event = await client.events.upsert(input);
68707
- output.success(`Event upserted: ${event.identifier}`, {
68708
- id: event.id,
68709
- status: event.status,
68710
- visibility: event.visibility
68711
- });
68712
- })
71056
+ )
68713
71057
  );
68714
71058
  var getCommand5 = createGetCommand({
68715
71059
  resourceName: "event",
@@ -68753,31 +71097,35 @@ var deleteCommand3 = new Command("delete").description("Delete an event series")
68753
71097
  )
68754
71098
  );
68755
71099
  var cancelCommand = new Command("cancel").description("Cancel an event series").argument("<identifier>", "Event identifier").action(
68756
- withErrorHandling(async (identifier, _options, command) => {
68757
- const { output, client } = createCommandContext(command);
68758
- const current = await client.events.get(identifier);
68759
- if (!current) {
68760
- return output.error(`Event not found: ${identifier}`);
68761
- }
68762
- if (current.status === "cancelled") {
68763
- output.success(`Event already cancelled: ${identifier}`);
68764
- return;
68765
- }
68766
- if (!canCancelEventStatus(current.status)) {
68767
- return output.error(
68768
- `Event ${identifier} cannot be cancelled from status "${current.status}".`
68769
- );
68770
- }
68771
- try {
68772
- await client.events.upsert(buildCancelledEventUpsertInput(current));
68773
- output.success(`Event cancelled: ${identifier}`);
68774
- } catch (error) {
68775
- if (error instanceof ManagementApiError && error.statusCode === 404) {
68776
- return output.error(`Event ${identifier} was removed before cancellation. Pull and retry.`);
71100
+ withErrorHandling(
71101
+ async (identifier, _options, command) => {
71102
+ const { output, client } = createCommandContext(command);
71103
+ const current = await client.events.get(identifier);
71104
+ if (!current) {
71105
+ return output.error(`Event not found: ${identifier}`);
71106
+ }
71107
+ if (current.status === "cancelled") {
71108
+ output.success(`Event already cancelled: ${identifier}`);
71109
+ return;
71110
+ }
71111
+ if (!canCancelEventStatus(current.status)) {
71112
+ return output.error(
71113
+ `Event ${identifier} cannot be cancelled from status "${current.status}".`
71114
+ );
71115
+ }
71116
+ try {
71117
+ await client.events.upsert(buildCancelledEventUpsertInput(current));
71118
+ output.success(`Event cancelled: ${identifier}`);
71119
+ } catch (error) {
71120
+ if (error instanceof ManagementApiError && error.statusCode === 404) {
71121
+ return output.error(
71122
+ `Event ${identifier} was removed before cancellation. Pull and retry.`
71123
+ );
71124
+ }
71125
+ throw error;
68777
71126
  }
68778
- throw error;
68779
71127
  }
68780
- })
71128
+ )
68781
71129
  );
68782
71130
  var eventCommand = new Command("event").description("Manage events").addHelpText(
68783
71131
  "after",