@riverbankcms/sdk 0.145.0 → 0.146.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/{PreviewEditorSidebar-O-V6Pl5a.mjs → PreviewEditorSidebar-kg2r2Fyi.mjs} +4 -4
  3. package/dist/{PreviewEditorUI-1UlX_9cw.mjs → PreviewEditorUI-sWMLp5dT.mjs} +3 -3
  4. package/dist/{PreviewQueryProvider-BxGwdOCV.mjs → PreviewQueryProvider-Cg51xq1w.mjs} +1 -1
  5. package/dist/{SdkPreviewModeRuntime-DYbA_4iv.mjs → SdkPreviewModeRuntime-h2ti3Hch.mjs} +280 -182
  6. package/dist/{SiteChromeCustomizeContext-CNTKQ9nx.mjs → SiteChromeCustomizeContext-DEACFH9m.mjs} +1330 -734
  7. package/dist/_dts/ai/src/contracts/proposals.d.ts +924 -0
  8. package/dist/_dts/ai/src/contracts/siteStyleProposalSchemas.d.ts +84 -0
  9. package/dist/_dts/api/src/bookingConfig.d.ts +8 -1
  10. package/dist/_dts/api/src/bookingManagementEndpoints.d.ts +8 -14
  11. package/dist/_dts/api/src/bookingManagementEventEndpointTypes.d.ts +45 -1
  12. package/dist/_dts/api/src/clientErrorReporting.d.ts +50 -0
  13. package/dist/_dts/api/src/communications.d.ts +20 -4
  14. package/dist/_dts/api/src/contentRuntime.d.ts +3 -7
  15. package/dist/_dts/api/src/endpoints.d.ts +223 -88
  16. package/dist/_dts/api/src/event-visibility.d.ts +20 -0
  17. package/dist/_dts/api/src/eventManagementContracts.d.ts +56 -3
  18. package/dist/_dts/api/src/eventManagementEndpointDefinitions.d.ts +24 -0
  19. package/dist/_dts/api/src/eventPageWords.d.ts +19 -0
  20. package/dist/_dts/api/src/eventSeriesRegistrationEndpointDefinitions.d.ts +14 -0
  21. package/dist/_dts/api/src/index.d.ts +7 -1
  22. package/dist/_dts/api/src/indexCoreTypes.d.ts +1 -1
  23. package/dist/_dts/api/src/indexExtendedTypes.d.ts +1 -1
  24. package/dist/_dts/api/src/launchReadiness.d.ts +20 -2
  25. package/dist/_dts/api/src/launchRequirementPriority.d.ts +3 -0
  26. package/dist/_dts/api/src/newsletterCampaignCommandEndpoints.d.ts +13 -0
  27. package/dist/_dts/api/src/newsletterEndpointDefinitions.d.ts +42 -0
  28. package/dist/_dts/api/src/occurrenceScheduling.d.ts +10 -0
  29. package/dist/_dts/api/src/pageSurfaceEndpoints.d.ts +44 -0
  30. package/dist/_dts/api/src/participantMessaging.d.ts +11 -1
  31. package/dist/_dts/api/src/sdk-event-upsert.d.ts +40 -1
  32. package/dist/_dts/api/src/sdkContracts.d.ts +3 -42
  33. package/dist/_dts/api/src/sdkCourseBooking.d.ts +30 -0
  34. package/dist/_dts/api/src/sdkEventEndpointDefinitions.d.ts +76 -0
  35. package/dist/_dts/api/src/sdkEventLifecycle.d.ts +37 -0
  36. package/dist/_dts/api/src/sdkManagedEventContracts.d.ts +18 -0
  37. package/dist/_dts/api/src/sdkPageDesign.d.ts +388 -0
  38. package/dist/_dts/api/src/sdkPageDesignEndpointDefinitions.d.ts +22 -0
  39. package/dist/_dts/api/src/sdkPullEventContracts.d.ts +46 -0
  40. package/dist/_dts/api/src/siteAddressEndpoints.d.ts +29 -0
  41. package/dist/_dts/api/src/siteManagementEndpointDefinitions.d.ts +49 -0
  42. package/dist/_dts/api/src/siteManagementEndpoints.d.ts +2 -32
  43. package/dist/_dts/api/src/siteOnboarding.d.ts +75 -9
  44. package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +1 -1
  45. package/dist/_dts/api/src/types.d.ts +7 -1
  46. package/dist/_dts/api/src/wholeSeriesRuns.d.ts +14 -0
  47. package/dist/_dts/blocks/src/index.d.ts +2 -0
  48. package/dist/_dts/blocks/src/pageRenderAdmission.d.ts +10 -0
  49. package/dist/_dts/blocks/src/pageRendererContracts.d.ts +3 -1
  50. package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +27 -5
  51. package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +14 -1
  52. package/dist/_dts/blocks/src/system/icons/social.d.ts +1 -1
  53. package/dist/_dts/blocks/src/system/registry.d.ts +1 -1
  54. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/eventSourceRecovery.d.ts +1 -0
  55. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCollectionContract.d.ts +20 -4
  56. package/dist/_dts/blocks/src/system/runtime/nodes/form.fields.d.ts +5 -0
  57. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.block-submission.d.ts +36 -0
  58. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.client.d.ts +1 -1
  59. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.interactive.d.ts +6 -1
  60. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.parts.d.ts +46 -0
  61. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.types.d.ts +2 -1
  62. package/dist/_dts/blocks/src/system/runtime/resolver.d.ts +2 -1
  63. package/dist/_dts/blocks/src/system/runtime/shared/components/CheckboxChoice.d.ts +18 -0
  64. package/dist/_dts/blocks/src/system/runtime/shared/components/index.d.ts +1 -0
  65. package/dist/_dts/content-editor/src/index.d.ts +1 -0
  66. package/dist/_dts/content-editor/src/primitives/previewEditableOutline.d.ts +2 -0
  67. package/dist/_dts/content-editor/src/ui/editorBlockEquality.d.ts +3 -0
  68. package/dist/_dts/content-editor/src/ui/editorSnapshot.d.ts +3 -5
  69. package/dist/_dts/core/src/block-content-identity.d.ts +5 -0
  70. package/dist/_dts/core/src/editor-state.d.ts +2 -7
  71. package/dist/_dts/core/src/index.d.ts +1 -0
  72. package/dist/_dts/core/src/mailing-list-submission.d.ts +3 -1
  73. package/dist/_dts/core/src/public-event-booking-availability.d.ts +20 -1
  74. package/dist/_dts/core/src/public-profile.d.ts +3 -1
  75. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +49 -2
  76. package/dist/_dts/editor-blocks/src/BlockEditor.d.ts +3 -0
  77. package/dist/_dts/editor-blocks/src/block-editor/EmptyState.d.ts +13 -1
  78. package/dist/_dts/editor-blocks/src/block-editor/types.d.ts +2 -8
  79. package/dist/_dts/editor-blocks/src/index.d.ts +1 -0
  80. package/dist/_dts/preview-next/src/client/blocks/composer/types.d.ts +3 -4
  81. package/dist/_dts/preview-next/src/client/preview/PreviewEntryControllerProvider.d.ts +1 -2
  82. package/dist/_dts/sdk/src/next/renderSdkContent.d.ts +0 -1
  83. package/dist/_dts/sdk/src/rendering/blocks-page-renderer.d.ts +2 -2
  84. package/dist/_dts/sdk/src/rendering/components/pageShared.d.ts +2 -2
  85. package/dist/_dts/sdk/src/rendering/helpers/loadContent.d.ts +6 -1
  86. package/dist/_dts/sdk/src/rendering/helpers/loadPage.d.ts +5 -2
  87. package/dist/_dts/sdk/src/rendering/helpers/pageRuntimeSupport.d.ts +6 -1
  88. package/dist/_dts/sdk/src/rendering/helpers/templateContent.d.ts +2 -0
  89. package/dist/_dts/sdk/src/rendering/hooks/useContent.d.ts +5 -1
  90. package/dist/_dts/sdk/src/rendering/hooks/usePage.d.ts +5 -1
  91. package/dist/_dts/sdk/src/version.d.ts +1 -1
  92. package/dist/_dts/surfaces/src/index.d.ts +9 -0
  93. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  94. package/dist/_dts/theme-core/src/inputs/checkable.d.ts +42 -0
  95. package/dist/_dts/theme-core/src/inputs/inputGroup.d.ts +19 -0
  96. package/dist/_dts/ui/src/navigation-tabs.d.ts +2 -1
  97. package/dist/client/{BookingConsentAgreement-DlVOmpW4.mjs → BookingConsentAgreement-BQKL045f.mjs} +2 -2
  98. package/dist/client/CheckboxChoice--W2n6yKs.mjs +24 -0
  99. package/dist/client/{DiscountCodeDisclosure-T9q623PQ.mjs → DiscountCodeDisclosure-CsOtjFY7.mjs} +1 -1
  100. package/dist/client/{EventCombined.client-DnsUeONl.mjs → EventCombined.client-BdRjVbhH.mjs} +6 -6
  101. package/dist/client/{EventListing.client-CNBFqJS4.mjs → EventListing.client-DBxC6xOU.mjs} +2 -2
  102. package/dist/client/{LeafletStaticMap-C7higg52.mjs → LeafletStaticMap-mHEJKrTs.mjs} +1 -1
  103. package/dist/client/{ThemedButton-LAJTNrS8.mjs → ThemedButton-CE5KYT6z.mjs} +1 -1
  104. package/dist/client/{accordion-BcNF9TjX.mjs → accordion-BEQNSptH.mjs} +1 -1
  105. package/dist/client/{bookingForm-BUaQ3S03.mjs → bookingForm-AMr-s5vw.mjs} +33 -52
  106. package/dist/client/bookings.mjs +48 -46
  107. package/dist/client/{carousel-CTdF6e0V.mjs → carousel-Bbt_QgJy.mjs} +1 -1
  108. package/dist/client/{cart-pGtyf_XU.mjs → cart-CnWi30zJ.mjs} +3 -3
  109. package/dist/client/{checkout-Da9WSn7Y.mjs → checkout-f3nkWgd4.mjs} +3 -3
  110. package/dist/client/client.mjs +1611 -815
  111. package/dist/client/{context-BFeY_Wbm.mjs → context-Bc8T6pCe.mjs} +1 -1
  112. package/dist/client/{dates-BhwVSxDg.mjs → dates-DUsCEzLb.mjs} +2 -3
  113. package/dist/client/{eventCalendar-BAtdnR4s.mjs → eventCalendar-CKwgXui5.mjs} +9 -9
  114. package/dist/client/{eventCombined-RksA3tRC.mjs → eventCombined-CBAOSTGR.mjs} +4 -4
  115. package/dist/client/{eventDetails-BB9hB4wR.mjs → eventDetails-Dh-_WiBD.mjs} +4 -4
  116. package/dist/client/{eventListing-BpJBkviM.mjs → eventListing-CA3frIH5.mjs} +4 -4
  117. package/dist/client/{eventRegistration-B18jFq_o.mjs → eventRegistration-BHtsgdcg.mjs} +21 -22
  118. package/dist/client/{form-Dodt8Y8t.mjs → form-C2h3YAcg.mjs} +135 -104
  119. package/dist/client/{headerSection-B0qj9ttg.mjs → headerSection-lwMuMTH9.mjs} +3 -3
  120. package/dist/client/hooks.mjs +489 -65
  121. package/dist/client/{locationMap-gn-iMk7a.mjs → locationMap-DJ2bLODV.mjs} +3 -3
  122. package/dist/client/{newsletterForm-oByLdFkr.mjs → newsletterForm-8Pu5K32g.mjs} +203 -101
  123. package/dist/client/{pricing-BOU0_Hai.mjs → pricing-HHx3IgBz.mjs} +1 -1
  124. package/dist/client/{productDetail-D9v1zH2j.mjs → productDetail-C_1odnAf.mjs} +3 -3
  125. package/dist/client/{productList-D-mItx1n.mjs → productList-CtCv-Nmx.mjs} +3 -3
  126. package/dist/client/{propsDecoder-C3TP_z4x.mjs → propsDecoder-Dcgsncxb.mjs} +40 -23
  127. package/dist/client/rendering/client.mjs +490 -457
  128. package/dist/client/rendering/islands.mjs +17 -17
  129. package/dist/client/rendering.mjs +1515 -628
  130. package/dist/client/{routeIslandApiConfig-DzN1W0sq.mjs → routeIslandApiConfig-CWLP7wu3.mjs} +1 -1
  131. package/dist/client/{scrollToBlock-CWs8EIdo.mjs → scrollToBlock-BNgaEUpo.mjs} +1 -1
  132. package/dist/client/{shop-Dufw7N7o.mjs → shop-DQXrQ8kJ.mjs} +7 -7
  133. package/dist/client/{shop-commerce-gklw_hLF.mjs → shop-commerce-B88zmWWo.mjs} +6 -6
  134. package/dist/client/{shop-commerce-store-Sf1eyTaZ.mjs → shop-commerce-store-DtSfkKuX.mjs} +1 -1
  135. package/dist/client/{shopShared-B5nyA41S.mjs → shopShared-cuaONpkJ.mjs} +4 -4
  136. package/dist/client/{useEventFilters-CLL829vy.mjs → useEventFilters-Bukew6Gb.mjs} +6 -6
  137. package/dist/preview-next/before-render.mjs +368 -103
  138. package/dist/preview-next/client/runtime.mjs +4 -4
  139. package/dist/preview-next/editor-base.css +11 -0
  140. package/dist/preview-next/keepAlive.mjs +328 -103
  141. package/dist/preview-next/middleware.mjs +329 -103
  142. package/dist/{previewAuthStore-BxAFlu-j.mjs → previewAuthStore-h5IgbSp4.mjs} +353 -103
  143. package/dist/{sdk-runtime-D0uZFev7.mjs → sdk-runtime-DTc1uIXn.mjs} +2 -2
  144. package/dist/{separator-EvdCAn4V.mjs → separator-BpHS1KZK.mjs} +1 -1
  145. package/dist/server/components.mjs +1376 -331
  146. package/dist/server/config-validation.mjs +405 -27
  147. package/dist/server/config.mjs +405 -27
  148. package/dist/server/data.mjs +405 -27
  149. package/dist/server/index.mjs +370 -104
  150. package/dist/server/next.mjs +1430 -463
  151. package/dist/server/page-converter.mjs +36 -25
  152. package/dist/server/prebuild.mjs +1 -1
  153. package/dist/server/rendering/server.mjs +1374 -331
  154. package/dist/server/rendering.mjs +1436 -364
  155. package/dist/server/routing.mjs +476 -43
  156. package/dist/server/server.mjs +504 -169
  157. package/dist/server/theme-bridge.mjs +467 -111
  158. package/dist/styles/index.css +186 -65
  159. package/package.json +1 -1
@@ -1548,7 +1548,8 @@ var init_business_address = __esmMin((() => {
1548
1548
  var init_try_async = __esmMin((() => {
1549
1549
  init_result$1();
1550
1550
  }));
1551
- var init_narrow_result = __esmMin((() => {})), init_editor_state = __esmMin((() => {}));
1551
+ var init_narrow_result = __esmMin((() => {}));
1552
+ var init_editor_state = __esmMin((() => {})), init_block_content_identity = __esmMin((() => {}));
1552
1553
  var init_sensitive_collection = __esmMin((() => {}));
1553
1554
  //#endregion
1554
1555
  //#region ../core/src/assertNever.ts
@@ -1932,6 +1933,27 @@ var init_mailing_list_setup_parser = __esmMin((() => {
1932
1933
  init_mailing_list_identifiers();
1933
1934
  init_result$1();
1934
1935
  }));
1936
+ //#endregion
1937
+ //#region ../core/src/mailing-list-targeting.ts
1938
+ function sameMailingListPlacementTargeting(left, right) {
1939
+ if (left.mode !== right.mode) return false;
1940
+ if (left.mode === "default" || right.mode === "default") return true;
1941
+ if (left.provider !== right.provider || left.selection.tag !== right.selection.tag) return false;
1942
+ if (left.provider === "mailchimp" && (right.provider !== "mailchimp" || left.audienceId !== right.audienceId)) return false;
1943
+ return sameIds(targetingSelectionIds(left), targetingSelectionIds(right));
1944
+ }
1945
+ function targetingSelectionIds(targeting) {
1946
+ switch (targeting.provider) {
1947
+ case "native": return targeting.selection.tag === "fixed" ? targeting.selection.topicIds : targeting.selection.offeredTopicIds;
1948
+ case "brevo": return targeting.selection.tag === "fixed" ? targeting.selection.listIds : targeting.selection.offeredListIds;
1949
+ case "mailchimp": return targeting.selection.tag === "fixed" ? targeting.selection.interestIds : targeting.selection.offeredInterestIds;
1950
+ }
1951
+ }
1952
+ function sameIds(left, right) {
1953
+ const leftIds = new Set(left);
1954
+ const rightIds = new Set(right);
1955
+ return leftIds.size === left.length && rightIds.size === right.length && leftIds.size === rightIds.size && [...leftIds].every((id) => rightIds.has(id));
1956
+ }
1935
1957
  function planMailingListChoicePresentation(targeting) {
1936
1958
  if (targeting.mode === "default" || targeting.selection.tag === "fixed") return { tag: "hidden" };
1937
1959
  switch (targeting.provider) {
@@ -2683,6 +2705,7 @@ var init_src$2 = __esmMin((() => {
2683
2705
  init_narrow_result();
2684
2706
  init_non_empty_array();
2685
2707
  init_editor_state();
2708
+ init_block_content_identity();
2686
2709
  init_sensitive_collection();
2687
2710
  init_assertNever$1();
2688
2711
  init_participants();
@@ -13501,7 +13524,7 @@ var init_bookingConsent = __esmMin((() => {
13501
13524
  checkboxLabel: z$1.string().min(1)
13502
13525
  });
13503
13526
  bookingConsentCarrierSchema = z$1.union([blockBookingConsentSchema, bookingRequirementConsentFieldSchema]);
13504
- })), publicEventLoaderQuerySchemaShape, eventPresetSchema, eventScheduleScopeSchema$2, publicEventRecurrenceSchema, eventDestinationModeSchema, publicEventDestinationSchema, eventVenueSchema, eventCategorySchema, accessRestrictionSchema, publicCurrencySchema, publicCentsSchema, publicPositiveCentsSchema, publicIsoDateTimeSchema, publicEventAttendanceModeSchema, publicEventAttendanceModeAvailabilitySchema, publicEventPricingOptionAvailabilitySchema, publicEventPricingOptionSchema, publicEventPricingSchema, publicTeamMemberSummarySchema, publicEventBookingAvailabilitySchema, publicRunSessionSchema, publicWholeSeriesRunSchema, publicEventBaseSchema, publicEventSchema, publicEventsArraySchema;
13527
+ })), publicEventLoaderQuerySchemaShape, eventPresetSchema, eventScheduleScopeSchema$2, publicEventRecurrenceSchema, eventDestinationModeSchema, publicEventDestinationSchema, eventVenueSchema, eventCategorySchema, accessRestrictionSchema, publicCurrencySchema, publicCentsSchema, publicPositiveCentsSchema, publicIsoDateTimeSchema, publicEventAttendanceModeSchema, publicEventAttendanceModeAvailabilitySchema, publicEventPricingOptionAvailabilitySchema, publicEventPricingOptionSchema, publicEventPricingSchema, publicTeamMemberSummarySchema, publicEventBookingAvailabilitySchema, publicEventBookingClosedDetailSchema, publicRunSessionSchema, publicWholeSeriesRunSchema, publicEventBaseSchema, publicEventSchema, publicEventsArraySchema;
13505
13528
  var init_schemas = __esmMin((() => {
13506
13529
  init_media$1();
13507
13530
  init_richTextSchema();
@@ -13525,6 +13548,7 @@ var init_schemas = __esmMin((() => {
13525
13548
  seriesSlug: z$1.string().optional(),
13526
13549
  includeOccurrenceId: z$1.string().optional(),
13527
13550
  readIntent: z$1.string().optional(),
13551
+ detailAdmission: z$1.string().optional(),
13528
13552
  detailLevel: z$1.string().optional(),
13529
13553
  readProfile: z$1.string().optional()
13530
13554
  };
@@ -13682,11 +13706,11 @@ var init_schemas = __esmMin((() => {
13682
13706
  "series_archived",
13683
13707
  "parent_archived",
13684
13708
  "parent_inconsistent",
13685
- "not_public",
13686
13709
  "already_started",
13687
13710
  "enrollment_closed"
13688
13711
  ])
13689
13712
  })]);
13713
+ publicEventBookingClosedDetailSchema = z$1.discriminatedUnion("kind", [z$1.object({ kind: z$1.literal("opensSoon") }), z$1.object({ kind: z$1.literal("paused") })]);
13690
13714
  publicRunSessionSchema = z$1.object({
13691
13715
  occurrenceId: z$1.string(),
13692
13716
  startsAt: z$1.string(),
@@ -13728,6 +13752,7 @@ var init_schemas = __esmMin((() => {
13728
13752
  destination: publicEventDestinationSchema,
13729
13753
  requiresRegistration: z$1.boolean(),
13730
13754
  bookingAvailability: publicEventBookingAvailabilitySchema,
13755
+ bookingClosedDetail: publicEventBookingClosedDetailSchema.optional(),
13731
13756
  deliveryMode: z$1.enum([
13732
13757
  "in_person",
13733
13758
  "online",
@@ -29908,7 +29933,6 @@ function closedEventBookingLabel(reason) {
29908
29933
  case "series_archived":
29909
29934
  case "parent_archived":
29910
29935
  case "parent_inconsistent":
29911
- case "not_public":
29912
29936
  case "already_started":
29913
29937
  case "enrollment_closed": return "Registration closed";
29914
29938
  default: return assertNever$20(reason);
@@ -32719,6 +32743,7 @@ var init_social = __esmMin((() => {
32719
32743
  "SocialInstagram",
32720
32744
  "SocialLinkedIn",
32721
32745
  "SocialTikTok",
32746
+ "SocialWhatsApp",
32722
32747
  "SocialX",
32723
32748
  "SocialYouTube"
32724
32749
  ];
@@ -32755,6 +32780,7 @@ var init_social = __esmMin((() => {
32755
32780
  /* @__PURE__ */ jsx("path", { d: "M10.5 9v10" })
32756
32781
  ] })),
32757
32782
  SocialTikTok: createIcon("SocialTikTokIcon", /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("path", { d: "M14 4v11.5a4.5 4.5 0 1 1-4-4.47" }), /* @__PURE__ */ jsx("path", { d: "M14 4c.7 3 2.4 4.5 5 4.5" })] })),
32783
+ SocialWhatsApp: createIcon("SocialWhatsAppIcon", /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("path", { d: "M3.5 20.5 4.8 16.4A8.5 8.5 0 1 1 8 19.3Z" }), /* @__PURE__ */ jsx("path", { d: "M9.2 8.2c.2-.5.9-.6 1.2-.1l.8 1.4c.2.3.1.7-.2 1l-.5.5c.5 1.1 1.4 2 2.5 2.5l.5-.5c.3-.3.7-.4 1-.2l1.4.8c.5.3.4 1-.1 1.2-2.9 1.1-7.7-3.7-6.6-6.6Z" })] })),
32758
32784
  SocialX: createIcon("SocialXIcon", /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("path", { d: "m5 4 14 16" }), /* @__PURE__ */ jsx("path", { d: "M19 4 5 20" })] })),
32759
32785
  SocialYouTube: createIcon("SocialYouTubeIcon", /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("path", { d: "M21 12c0 3.5-.5 5.5-1.3 6.3S16.5 19.5 12 19.5s-6.9-.4-7.7-1.2S3 15.5 3 12s.5-5.5 1.3-6.3S7.5 4.5 12 4.5s6.9.4 7.7 1.2S21 8.5 21 12Z" }), /* @__PURE__ */ jsx("path", { d: "m10 9 5 3-5 3Z" })] }))
32760
32786
  };
@@ -35026,6 +35052,11 @@ function withOptionalPhone(fields, includePhone) {
35026
35052
  var init_newsletter_form_types = __esmMin((() => {}));
35027
35053
  //#endregion
35028
35054
  //#region ../blocks/src/system/runtime/nodes/newsletter-form.interactive.ts
35055
+ function newsletterBlockSubmissionMessage(target) {
35056
+ if (target.tag === "block-source") return target.sourceRef ? null : NEWSLETTER_SIGNUPS_PAUSED_MESSAGE;
35057
+ if (target.tag !== "unpublished-preview") return null;
35058
+ return target.reason === "unpublished-form" ? "Publish this form to test a signup here." : "This form's signup settings are unpublished. Publish it to test a signup here.";
35059
+ }
35029
35060
  function buildNewsletterDisplay(source) {
35030
35061
  const context = source.mailingList;
35031
35062
  const form = context?.tag === "configured" ? context.form : {
@@ -35051,16 +35082,21 @@ function buildNewsletterDisplay(source) {
35051
35082
  }
35052
35083
  function projectNewsletterFormHydrationTarget(source) {
35053
35084
  switch (source.source) {
35054
- case "block": {
35055
- const sourceRef = buildMailingListSignupBlockSourceRef(source.blockId, source.contentVersionId);
35056
- if (sourceRef?.tag === "block_ref") return {
35085
+ case "block": switch (source.newsletterBlockSubmission.tag) {
35086
+ case "unpublished-form":
35087
+ case "unpublished-settings": return {
35088
+ tag: "unpublished-preview",
35089
+ reason: source.newsletterBlockSubmission.tag
35090
+ };
35091
+ case "ready": return {
35057
35092
  tag: "block-source",
35058
- sourceRef
35093
+ sourceRef: source.newsletterBlockSubmission.sourceRef
35059
35094
  };
35060
- return {
35095
+ case "unavailable": return {
35061
35096
  tag: "block-source",
35062
35097
  sourceRef: null
35063
35098
  };
35099
+ default: return assertNever$20(source.newsletterBlockSubmission);
35064
35100
  }
35065
35101
  case "signed-footer": return {
35066
35102
  tag: "signed-footer-source",
@@ -35129,6 +35165,7 @@ function buildNewsletterFormInteractiveIslandProps(props) {
35129
35165
  const decoded = newsletterFormBlockRuntime.contracts.source.decode(props);
35130
35166
  const source = isDecodeSuccess(decoded) ? decoded.value : {
35131
35167
  ...props,
35168
+ ...props.source === "block" ? { newsletterBlockSubmission: { tag: "unavailable" } } : {},
35132
35169
  mailingList: void 0,
35133
35170
  targeting: { mode: "default" }
35134
35171
  };
@@ -35152,13 +35189,14 @@ function parseRequiredMailingListSignedSourceToken(value) {
35152
35189
  if (!parsed) throw new Error("Mailing-list signup signed source ref requires token");
35153
35190
  return parsed;
35154
35191
  }
35155
- var newsletterButtonVariantSchema, mailingListContextSchema, mailingListTargetingSchema, newsletterFieldSchema, mailingListSignupBlockIdSchema, mailingListContentVersionIdSchema, signedMailingListSourceTokenSchema, newsletterSourceCommonSchema, newsletterSourceSchema, newsletterDisplaySchema, newsletterHydrationSchema, newsletterRenderSchema, newsletterIslandMetaCodec, newsletterIslandMetaKeys, newsletterFormBlockRuntime, newsletterFormInteractiveIslandPropsCodec;
35192
+ var NEWSLETTER_SIGNUPS_PAUSED_MESSAGE, newsletterButtonVariantSchema, mailingListContextSchema, mailingListTargetingSchema, newsletterFieldSchema, mailingListSignupBlockIdSchema, mailingListContentVersionIdSchema, mailingListSignupBlockSourceRefSchema, signedMailingListSourceTokenSchema, newsletterSourceCommonSchema, newsletterSourceSchema, newsletterDisplaySchema, newsletterHydrationSchema, newsletterRenderSchema, newsletterIslandMetaCodec, newsletterIslandMetaKeys, newsletterFormBlockRuntime, newsletterFormInteractiveIslandPropsCodec;
35156
35193
  var init_newsletter_form_interactive = __esmMin((() => {
35157
35194
  init_src$2();
35158
35195
  init_islands();
35159
35196
  init_runtime();
35160
35197
  init_newsletter_form_types();
35161
35198
  init_buttonRoles();
35199
+ NEWSLETTER_SIGNUPS_PAUSED_MESSAGE = "We can’t accept signups right now. Please try again later.";
35162
35200
  newsletterButtonVariantSchema = blockButtonRoleSchema;
35163
35201
  mailingListContextSchema = z$1.unknown().transform((value, ctx) => {
35164
35202
  const parsed = parseMailingListRuntimeContext(value);
@@ -35199,6 +35237,11 @@ var init_newsletter_form_interactive = __esmMin((() => {
35199
35237
  });
35200
35238
  return z$1.NEVER;
35201
35239
  });
35240
+ mailingListSignupBlockSourceRefSchema = z$1.object({
35241
+ tag: z$1.literal("block_ref"),
35242
+ blockId: mailingListSignupBlockIdSchema,
35243
+ contentVersionId: mailingListContentVersionIdSchema
35244
+ });
35202
35245
  signedMailingListSourceTokenSchema = z$1.string().trim().min(1).transform(parseRequiredMailingListSignedSourceToken);
35203
35246
  newsletterSourceCommonSchema = z$1.object({
35204
35247
  siteId: z$1.string().optional(),
@@ -35213,7 +35256,15 @@ var init_newsletter_form_interactive = __esmMin((() => {
35213
35256
  newsletterSourceCommonSchema.extend({
35214
35257
  source: z$1.literal("block"),
35215
35258
  blockId: z$1.string().nullable().optional(),
35216
- contentVersionId: z$1.string().nullable().optional()
35259
+ newsletterBlockSubmission: z$1.discriminatedUnion("tag", [
35260
+ z$1.object({
35261
+ tag: z$1.literal("ready"),
35262
+ sourceRef: mailingListSignupBlockSourceRefSchema
35263
+ }),
35264
+ z$1.object({ tag: z$1.literal("unpublished-form") }),
35265
+ z$1.object({ tag: z$1.literal("unpublished-settings") }),
35266
+ z$1.object({ tag: z$1.literal("unavailable") })
35267
+ ])
35217
35268
  }),
35218
35269
  newsletterSourceCommonSchema.extend({
35219
35270
  source: z$1.literal("signed-footer"),
@@ -35242,11 +35293,7 @@ var init_newsletter_form_interactive = __esmMin((() => {
35242
35293
  target: z$1.discriminatedUnion("tag", [
35243
35294
  z$1.object({
35244
35295
  tag: z$1.literal("block-source"),
35245
- sourceRef: z$1.object({
35246
- tag: z$1.literal("block_ref"),
35247
- blockId: mailingListSignupBlockIdSchema,
35248
- contentVersionId: mailingListContentVersionIdSchema
35249
- }).nullable()
35296
+ sourceRef: mailingListSignupBlockSourceRefSchema.nullable()
35250
35297
  }),
35251
35298
  z$1.object({
35252
35299
  tag: z$1.literal("signed-footer-source"),
@@ -35255,7 +35302,11 @@ var init_newsletter_form_interactive = __esmMin((() => {
35255
35302
  token: signedMailingListSourceTokenSchema
35256
35303
  })
35257
35304
  }),
35258
- z$1.object({ tag: z$1.literal("preview") })
35305
+ z$1.object({ tag: z$1.literal("preview") }),
35306
+ z$1.object({
35307
+ tag: z$1.literal("unpublished-preview"),
35308
+ reason: z$1.enum(["unpublished-form", "unpublished-settings"])
35309
+ })
35259
35310
  ]),
35260
35311
  setupRevision: z$1.number().int().positive().nullable(),
35261
35312
  choiceProvider: z$1.enum([
@@ -37283,6 +37334,13 @@ const EVENT_SERIES_REGISTRATION_ENDPOINT_DEFINITIONS = defineEndpointDefinitions
37283
37334
  errors: [],
37284
37335
  responseKind: "blob"
37285
37336
  },
37337
+ exportEventOfferingRegistrationsCsv: {
37338
+ path: "/sites/{siteId}/bookings/event-offerings/{eventOfferingId}/registrations/export.csv",
37339
+ method: "GET",
37340
+ auth: "user",
37341
+ errors: [],
37342
+ responseKind: "blob"
37343
+ },
37286
37344
  updateEventSeriesRegistration: {
37287
37345
  path: "/sites/{siteId}/bookings/event-series/{seriesId}/registrations/{registrationId}",
37288
37346
  method: "PATCH",
@@ -37293,6 +37351,19 @@ const EVENT_SERIES_REGISTRATION_ENDPOINT_DEFINITIONS = defineEndpointDefinitions
37293
37351
  "resource:not_found",
37294
37352
  "server:internal_error"
37295
37353
  ]
37354
+ },
37355
+ saveEventSeriesRegistrationAnswers: {
37356
+ path: "/sites/{siteId}/bookings/event-series/{seriesId}/registrations/{registrationId}/answers",
37357
+ method: "PUT",
37358
+ auth: "user",
37359
+ responseKind: "json",
37360
+ errors: [
37361
+ "validation:invalid_input",
37362
+ "auth:forbidden",
37363
+ "resource:not_found",
37364
+ "resource:conflict",
37365
+ "server:internal_error"
37366
+ ]
37296
37367
  }
37297
37368
  });
37298
37369
  //#endregion
@@ -37713,6 +37784,30 @@ const NEWSLETTER_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
37713
37784
  responseKind: "json",
37714
37785
  demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
37715
37786
  },
37787
+ scheduleNewsletterCampaign: {
37788
+ path: "/sites/{siteId}/newsletter/campaigns/{campaignId}/schedule",
37789
+ method: "POST",
37790
+ tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter],
37791
+ auth: "user",
37792
+ responseKind: "json",
37793
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
37794
+ },
37795
+ unscheduleNewsletterCampaign: {
37796
+ path: "/sites/{siteId}/newsletter/campaigns/{campaignId}/unschedule",
37797
+ method: "POST",
37798
+ tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter],
37799
+ auth: "user",
37800
+ responseKind: "json",
37801
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
37802
+ },
37803
+ stopNewsletterCampaign: {
37804
+ path: "/sites/{siteId}/newsletter/campaigns/{campaignId}/stop",
37805
+ method: "POST",
37806
+ tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter],
37807
+ auth: "user",
37808
+ responseKind: "json",
37809
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
37810
+ },
37716
37811
  testSendNewsletterCampaign: {
37717
37812
  path: "/sites/{siteId}/newsletter/campaigns/{campaignId}/test-send",
37718
37813
  method: "POST",
@@ -37723,6 +37818,154 @@ const NEWSLETTER_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
37723
37818
  }
37724
37819
  });
37725
37820
  //#endregion
37821
+ //#region ../api/src/sdkEventEndpointDefinitions.ts
37822
+ /**
37823
+ * The SDK's Event graph: the Events themselves and the occurrences of one run.
37824
+ * Extracted from `endpoints.ts` so this family can be read, and added to, on
37825
+ * its own. New entries here must declare `errors`; the
37826
+ * require-api-endpoint-errors lint enforces that here as in endpoints.ts.
37827
+ */
37828
+ const SDK_EVENT_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
37829
+ sdkListEvents: {
37830
+ path: "/sdk/{siteId}/events",
37831
+ method: "GET",
37832
+ auth: "service",
37833
+ responseKind: "json"
37834
+ },
37835
+ sdkUpsertEvent: {
37836
+ path: "/sdk/{siteId}/events",
37837
+ method: "POST",
37838
+ auth: "service",
37839
+ responseKind: "json",
37840
+ errors: [
37841
+ "validation:invalid_input",
37842
+ "resource:not_found",
37843
+ "resource:conflict",
37844
+ "billing:plan_limit_exceeded",
37845
+ "server:internal_error"
37846
+ ]
37847
+ },
37848
+ sdkGetEvent: {
37849
+ path: "/sdk/{siteId}/events/{identifier}",
37850
+ method: "GET",
37851
+ auth: "service",
37852
+ responseKind: "json"
37853
+ },
37854
+ sdkDeleteEvent: {
37855
+ path: "/sdk/{siteId}/events/{identifier}",
37856
+ method: "DELETE",
37857
+ auth: "service",
37858
+ responseKind: "json",
37859
+ errors: [
37860
+ "resource:not_found",
37861
+ "resource:conflict",
37862
+ "server:internal_error"
37863
+ ]
37864
+ },
37865
+ sdkTakeEventOffline: {
37866
+ path: "/sdk/{siteId}/events/{identifier}/lifecycle",
37867
+ method: "POST",
37868
+ auth: "service",
37869
+ responseKind: "json",
37870
+ errors: [
37871
+ "resource:not_found",
37872
+ "validation:invalid_input",
37873
+ "resource:conflict",
37874
+ "server:internal_error"
37875
+ ]
37876
+ },
37877
+ sdkListEventOccurrences: {
37878
+ path: "/sdk/{siteId}/events/{identifier}/runs/{runIdentifier}/occurrences",
37879
+ method: "GET",
37880
+ auth: "service",
37881
+ responseKind: "json",
37882
+ errors: [
37883
+ "resource:not_found",
37884
+ "validation:invalid_input",
37885
+ "server:internal_error"
37886
+ ]
37887
+ },
37888
+ sdkAddEventOccurrence: {
37889
+ path: "/sdk/{siteId}/events/{identifier}/runs/{runIdentifier}/occurrences",
37890
+ method: "POST",
37891
+ auth: "service",
37892
+ responseKind: "json",
37893
+ errors: [
37894
+ "resource:not_found",
37895
+ "validation:invalid_input",
37896
+ "resource:conflict",
37897
+ "server:internal_error"
37898
+ ]
37899
+ },
37900
+ sdkUpdateEventOccurrence: {
37901
+ path: "/sdk/{siteId}/events/{identifier}/runs/{runIdentifier}/occurrences/{occurrenceId}",
37902
+ method: "PATCH",
37903
+ auth: "service",
37904
+ responseKind: "json",
37905
+ errors: [
37906
+ "resource:not_found",
37907
+ "validation:invalid_input",
37908
+ "resource:conflict",
37909
+ "server:internal_error"
37910
+ ]
37911
+ },
37912
+ sdkCancelEventOccurrence: {
37913
+ path: "/sdk/{siteId}/events/{identifier}/runs/{runIdentifier}/occurrences/{occurrenceId}/cancel",
37914
+ method: "POST",
37915
+ auth: "service",
37916
+ responseKind: "json",
37917
+ errors: [
37918
+ "resource:not_found",
37919
+ "resource:conflict",
37920
+ "server:internal_error"
37921
+ ]
37922
+ },
37923
+ sdkDeleteEventOccurrence: {
37924
+ path: "/sdk/{siteId}/events/{identifier}/runs/{runIdentifier}/occurrences/{occurrenceId}",
37925
+ method: "DELETE",
37926
+ auth: "service",
37927
+ responseKind: "json",
37928
+ errors: [
37929
+ "resource:not_found",
37930
+ "resource:conflict",
37931
+ "server:internal_error"
37932
+ ]
37933
+ }
37934
+ });
37935
+ //#endregion
37936
+ //#region ../api/src/sdkPageDesignEndpointDefinitions.ts
37937
+ /**
37938
+ * SDK management endpoints for a page's draft design (issue 1497), spread into
37939
+ * `ENDPOINT_DEFINITIONS` like the other endpoint-definition modules. New
37940
+ * entries here must declare `errors`, which the require-api-endpoint-errors
37941
+ * lint enforces.
37942
+ */
37943
+ const SDK_PAGE_DESIGN_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
37944
+ sdkGetPageDesign: {
37945
+ path: "/sdk/{siteId}/pages/{identifier}/design",
37946
+ method: "GET",
37947
+ auth: "service",
37948
+ responseKind: "json",
37949
+ errors: [
37950
+ "resource:not_found",
37951
+ "validation:invalid_input",
37952
+ "server:internal_error"
37953
+ ]
37954
+ },
37955
+ sdkSavePageDesign: {
37956
+ path: "/sdk/{siteId}/pages/{identifier}/design",
37957
+ method: "POST",
37958
+ auth: "service",
37959
+ responseKind: "json",
37960
+ errors: [
37961
+ "resource:not_found",
37962
+ "validation:invalid_input",
37963
+ "resource:conflict",
37964
+ "server:internal_error"
37965
+ ]
37966
+ }
37967
+ });
37968
+ //#endregion
37726
37969
  //#region ../api/src/publicEventEndpointDefinitions.ts
37727
37970
  init_src$2();
37728
37971
  const PUBLIC_EVENT_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
@@ -37969,6 +38212,45 @@ const SITE_API_KEY_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
37969
38212
  }
37970
38213
  });
37971
38214
  //#endregion
38215
+ //#region ../api/src/siteManagementEndpointDefinitions.ts
38216
+ const SITE_MANAGEMENT_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
38217
+ createSite: {
38218
+ path: "/sites/manage",
38219
+ method: "POST",
38220
+ tags: ["site"],
38221
+ auth: "user",
38222
+ responseKind: "json"
38223
+ },
38224
+ updateSite: {
38225
+ path: "/sites/manage",
38226
+ method: "PUT",
38227
+ tags: ["site"],
38228
+ auth: "user",
38229
+ responseKind: "json"
38230
+ },
38231
+ changeSiteAddress: {
38232
+ path: "/sites/{siteId}/address",
38233
+ method: "PUT",
38234
+ auth: "user",
38235
+ responseKind: "json",
38236
+ demoMutation: DEMO_MUTATION_BLOCKED_DISABLED
38237
+ },
38238
+ getSiteAddressAvailability: {
38239
+ path: "/sites/{siteId}/address/availability",
38240
+ method: "GET",
38241
+ auth: "user",
38242
+ responseKind: "json"
38243
+ },
38244
+ deleteSite: {
38245
+ path: "/sites/{siteId}",
38246
+ method: "DELETE",
38247
+ tags: ["site", "site-{siteId}"],
38248
+ auth: "user",
38249
+ responseKind: "json",
38250
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
38251
+ }
38252
+ });
38253
+ //#endregion
37972
38254
  //#region ../api/src/eventManagementEndpointDefinitions.ts
37973
38255
  const EVENT_MANAGEMENT_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
37974
38256
  listEvents: {
@@ -38016,6 +38298,28 @@ const EVENT_MANAGEMENT_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
38016
38298
  "server:internal_error"
38017
38299
  ]
38018
38300
  },
38301
+ /**
38302
+ * The web address of an event's own page. A course page belongs to the
38303
+ * event itself, so its address is written here rather than through a run.
38304
+ */
38305
+ updateEventAddress: {
38306
+ path: "/sites/{siteId}/bookings/events/{eventId}/address",
38307
+ method: "PATCH",
38308
+ tags: [
38309
+ "site-{siteId}",
38310
+ "event-series-{siteId}",
38311
+ TAG_TEMPLATES.siteRoutableContent,
38312
+ TAG_TEMPLATES.siteRedirects
38313
+ ],
38314
+ auth: "user",
38315
+ responseKind: "json",
38316
+ errors: [
38317
+ "validation:invalid_input",
38318
+ "resource:not_found",
38319
+ "resource:conflict",
38320
+ "server:internal_error"
38321
+ ]
38322
+ },
38019
38323
  createWholeSeriesRun: {
38020
38324
  path: "/sites/{siteId}/bookings/events/{eventId}/runs",
38021
38325
  method: "POST",
@@ -38042,6 +38346,20 @@ const EVENT_MANAGEMENT_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
38042
38346
  "server:internal_error"
38043
38347
  ]
38044
38348
  },
38349
+ updateCourseBookingSettings: {
38350
+ path: "/sites/{siteId}/bookings/events/{eventId}/booking-settings",
38351
+ method: "PATCH",
38352
+ tags: ["site-{siteId}", "event-series-{siteId}"],
38353
+ auth: "user",
38354
+ responseKind: "json",
38355
+ errors: [
38356
+ "validation:invalid_input",
38357
+ "auth:forbidden",
38358
+ "resource:not_found",
38359
+ "resource:conflict",
38360
+ "server:internal_error"
38361
+ ]
38362
+ },
38045
38363
  cancelWholeSeriesRun: {
38046
38364
  path: "/sites/{siteId}/bookings/events/{eventId}/runs/{runId}/cancellation",
38047
38365
  method: "POST",
@@ -38054,6 +38372,28 @@ const EVENT_MANAGEMENT_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
38054
38372
  "resource:conflict",
38055
38373
  "server:internal_error"
38056
38374
  ]
38375
+ },
38376
+ /**
38377
+ * The Content tab's one write: the short introduction, image and
38378
+ * description of an event's page, published without its layout.
38379
+ */
38380
+ saveEventPageWords: {
38381
+ path: "/sites/{siteId}/page-surfaces/{pageSurfaceId}/words",
38382
+ method: "PUT",
38383
+ tags: [
38384
+ TAG_TEMPLATES.siteCollection,
38385
+ TAG_TEMPLATES.siteRoutableContent,
38386
+ TAG_TEMPLATES.pageSurfaceById
38387
+ ],
38388
+ auth: "user",
38389
+ responseKind: "json",
38390
+ errors: [
38391
+ "auth:forbidden",
38392
+ "validation:invalid_input",
38393
+ "resource:not_found",
38394
+ "resource:conflict",
38395
+ "server:internal_error"
38396
+ ]
38057
38397
  }
38058
38398
  });
38059
38399
  //#endregion
@@ -38487,7 +38827,43 @@ const BILLING_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
38487
38827
  responseKind: "json"
38488
38828
  }
38489
38829
  });
38830
+ //#endregion
38831
+ //#region ../api/src/clientErrorReporting.ts
38832
+ const CLIENT_ERROR_REPORT_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({ reportClientError: {
38833
+ path: "/client/error-report",
38834
+ method: "POST",
38835
+ auth: "user",
38836
+ errors: [],
38837
+ responseKind: "json"
38838
+ } });
38839
+ const CLIENT_ERROR_REPORT_LIMITS = {
38840
+ pathname: 1024,
38841
+ name: 120,
38842
+ message: 2e3,
38843
+ stack: 8e3,
38844
+ digest: 128,
38845
+ componentStack: 8e3,
38846
+ sourceLocation: 1024
38847
+ };
38848
+ const clientErrorEventSchema = z$1.enum([
38849
+ "dashboard:route-error",
38850
+ "dashboard:app-error",
38851
+ "client:error-boundary",
38852
+ "client:window-error",
38853
+ "client:unhandled-rejection"
38854
+ ]);
38855
+ z$1.object({
38856
+ event: clientErrorEventSchema,
38857
+ pathname: z$1.string().startsWith("/").max(CLIENT_ERROR_REPORT_LIMITS.pathname),
38858
+ name: z$1.string().max(CLIENT_ERROR_REPORT_LIMITS.name),
38859
+ message: z$1.string().max(CLIENT_ERROR_REPORT_LIMITS.message),
38860
+ stack: z$1.string().max(CLIENT_ERROR_REPORT_LIMITS.stack).nullable(),
38861
+ digest: z$1.string().max(CLIENT_ERROR_REPORT_LIMITS.digest).nullable(),
38862
+ componentStack: z$1.string().max(CLIENT_ERROR_REPORT_LIMITS.componentStack).nullable(),
38863
+ sourceLocation: z$1.string().max(CLIENT_ERROR_REPORT_LIMITS.sourceLocation).nullable()
38864
+ }).strict();
38490
38865
  const API_ENDPOINTS$1 = {
38866
+ ...CLIENT_ERROR_REPORT_ENDPOINT_DEFINITIONS,
38491
38867
  ...PUBLIC_NEWSLETTER_ENDPOINT_DEFINITIONS,
38492
38868
  ...ACCOUNT_ENDPOINT_DEFINITIONS,
38493
38869
  ...PUBLIC_ONBOARDING_ATTEMPT_ENDPOINT_DEFINITIONS,
@@ -38495,6 +38871,7 @@ const API_ENDPOINTS$1 = {
38495
38871
  ...GIFTING_ENDPOINT_DEFINITIONS,
38496
38872
  ...PUBLIC_READ_ENDPOINT_DEFINITIONS,
38497
38873
  ...BILLING_ENDPOINT_DEFINITIONS,
38874
+ ...SITE_MANAGEMENT_ENDPOINT_DEFINITIONS,
38498
38875
  aiContentUpdateChat: {
38499
38876
  path: "/ai/content-update-chat",
38500
38877
  method: "POST",
@@ -39021,13 +39398,6 @@ const API_ENDPOINTS$1 = {
39021
39398
  auth: "user",
39022
39399
  responseKind: "json"
39023
39400
  },
39024
- createSite: {
39025
- path: "/sites/manage",
39026
- method: "POST",
39027
- tags: ["site"],
39028
- auth: "user",
39029
- responseKind: "json"
39030
- },
39031
39401
  createSiteManual: {
39032
39402
  path: "/sites/manual",
39033
39403
  method: "POST",
@@ -39035,21 +39405,6 @@ const API_ENDPOINTS$1 = {
39035
39405
  auth: "user",
39036
39406
  responseKind: "json"
39037
39407
  },
39038
- updateSite: {
39039
- path: "/sites/manage",
39040
- method: "PUT",
39041
- tags: ["site"],
39042
- auth: "user",
39043
- responseKind: "json"
39044
- },
39045
- deleteSite: {
39046
- path: "/sites/{siteId}",
39047
- method: "DELETE",
39048
- tags: ["site", "site-{siteId}"],
39049
- auth: "user",
39050
- responseKind: "json",
39051
- demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
39052
- },
39053
39408
  listSiteMembers: {
39054
39409
  path: "/sites/{siteId}/members",
39055
39410
  method: "GET",
@@ -43282,6 +43637,7 @@ const API_ENDPOINTS$1 = {
43282
43637
  auth: "service",
43283
43638
  responseKind: "json"
43284
43639
  },
43640
+ ...SDK_PAGE_DESIGN_ENDPOINT_DEFINITIONS,
43285
43641
  sdkUpsertPageBlock: {
43286
43642
  path: "/sdk/{siteId}/pages/{identifier}/blocks",
43287
43643
  method: "POST",
@@ -43404,87 +43760,7 @@ const API_ENDPOINTS$1 = {
43404
43760
  auth: "service",
43405
43761
  responseKind: "json"
43406
43762
  },
43407
- sdkListEvents: {
43408
- path: "/sdk/{siteId}/events",
43409
- method: "GET",
43410
- auth: "service",
43411
- responseKind: "json"
43412
- },
43413
- sdkUpsertEvent: {
43414
- path: "/sdk/{siteId}/events",
43415
- method: "POST",
43416
- auth: "service",
43417
- responseKind: "json"
43418
- },
43419
- sdkGetEvent: {
43420
- path: "/sdk/{siteId}/events/{identifier}",
43421
- method: "GET",
43422
- auth: "service",
43423
- responseKind: "json"
43424
- },
43425
- sdkDeleteEvent: {
43426
- path: "/sdk/{siteId}/events/{identifier}",
43427
- method: "DELETE",
43428
- auth: "service",
43429
- responseKind: "json"
43430
- },
43431
- sdkListEventOccurrences: {
43432
- path: "/sdk/{siteId}/events/{identifier}/runs/{runIdentifier}/occurrences",
43433
- method: "GET",
43434
- auth: "service",
43435
- responseKind: "json",
43436
- errors: [
43437
- "resource:not_found",
43438
- "validation:invalid_input",
43439
- "server:internal_error"
43440
- ]
43441
- },
43442
- sdkAddEventOccurrence: {
43443
- path: "/sdk/{siteId}/events/{identifier}/runs/{runIdentifier}/occurrences",
43444
- method: "POST",
43445
- auth: "service",
43446
- responseKind: "json",
43447
- errors: [
43448
- "resource:not_found",
43449
- "validation:invalid_input",
43450
- "resource:conflict",
43451
- "server:internal_error"
43452
- ]
43453
- },
43454
- sdkUpdateEventOccurrence: {
43455
- path: "/sdk/{siteId}/events/{identifier}/runs/{runIdentifier}/occurrences/{occurrenceId}",
43456
- method: "PATCH",
43457
- auth: "service",
43458
- responseKind: "json",
43459
- errors: [
43460
- "resource:not_found",
43461
- "validation:invalid_input",
43462
- "resource:conflict",
43463
- "server:internal_error"
43464
- ]
43465
- },
43466
- sdkCancelEventOccurrence: {
43467
- path: "/sdk/{siteId}/events/{identifier}/runs/{runIdentifier}/occurrences/{occurrenceId}/cancel",
43468
- method: "POST",
43469
- auth: "service",
43470
- responseKind: "json",
43471
- errors: [
43472
- "resource:not_found",
43473
- "resource:conflict",
43474
- "server:internal_error"
43475
- ]
43476
- },
43477
- sdkDeleteEventOccurrence: {
43478
- path: "/sdk/{siteId}/events/{identifier}/runs/{runIdentifier}/occurrences/{occurrenceId}",
43479
- method: "DELETE",
43480
- auth: "service",
43481
- responseKind: "json",
43482
- errors: [
43483
- "resource:not_found",
43484
- "resource:conflict",
43485
- "server:internal_error"
43486
- ]
43487
- },
43763
+ ...SDK_EVENT_ENDPOINT_DEFINITIONS,
43488
43764
  sdkUpsertEntry: {
43489
43765
  path: "/sdk/{siteId}/entries",
43490
43766
  method: "POST",
@@ -55287,10 +55563,167 @@ function FeedbackMessage({ tone, treatment = "panel", children, className, id, t
55287
55563
  }
55288
55564
  var init_FeedbackMessage = __esmMin((() => {}));
55289
55565
  //#endregion
55566
+ //#region ../blocks/src/system/runtime/shared/components/CheckboxChoice.tsx
55567
+ /**
55568
+ * The customer-facing checkbox every block renders. Styling comes from the
55569
+ * theme's input CSS (`.form-check`, `.form-checkbox`), so it follows each
55570
+ * site's input colours, borders and corners.
55571
+ */
55572
+ function CheckboxChoice({ label, presentation = "row", className, ...inputProps }) {
55573
+ return /* @__PURE__ */ jsxs("label", {
55574
+ className: clsx("form-check", presentation === "tile" && "form-check--tile", className),
55575
+ children: [/* @__PURE__ */ jsx("input", {
55576
+ ...inputProps,
55577
+ type: "checkbox",
55578
+ className: "form-checkbox"
55579
+ }), /* @__PURE__ */ jsx("span", {
55580
+ className: "form-check-label",
55581
+ children: label
55582
+ })]
55583
+ });
55584
+ }
55585
+ var init_CheckboxChoice = __esmMin((() => {
55586
+ init_clsx();
55587
+ }));
55588
+ //#endregion
55589
+ //#region ../blocks/src/system/runtime/nodes/form.fields.tsx
55590
+ function fieldBasics(field) {
55591
+ return {
55592
+ inputId: `f_${field.id}`,
55593
+ label: String(field.label ?? field.id),
55594
+ required: Boolean(field.required)
55595
+ };
55596
+ }
55597
+ function textInputType(type) {
55598
+ return type === "email" || type === "url" || type === "tel" || type === "number" ? type : "text";
55599
+ }
55600
+ function textInputConstraints(field, inputType) {
55601
+ if (inputType === "number") return {
55602
+ ...typeof field.min === "number" ? { min: field.min } : {},
55603
+ ...typeof field.max === "number" ? { max: field.max } : {}
55604
+ };
55605
+ return {
55606
+ ...typeof field.minLength === "number" ? { minLength: field.minLength } : {},
55607
+ ...typeof field.maxLength === "number" ? { maxLength: field.maxLength } : {},
55608
+ ...typeof field.pattern === "string" && field.pattern ? { pattern: field.pattern } : {}
55609
+ };
55610
+ }
55611
+ function LabelledField({ basics, children }) {
55612
+ return /* @__PURE__ */ jsxs("div", {
55613
+ className: "fb-field",
55614
+ children: [/* @__PURE__ */ jsx("label", {
55615
+ htmlFor: basics.inputId,
55616
+ className: "form-label",
55617
+ children: basics.label
55618
+ }), children]
55619
+ });
55620
+ }
55621
+ function TextareaField({ field }) {
55622
+ const basics = fieldBasics(field);
55623
+ return /* @__PURE__ */ jsx(LabelledField, {
55624
+ basics,
55625
+ children: /* @__PURE__ */ jsx("textarea", {
55626
+ id: basics.inputId,
55627
+ name: field.id,
55628
+ required: basics.required,
55629
+ placeholder: field.placeholder,
55630
+ rows: field.rows,
55631
+ className: "form-textarea"
55632
+ })
55633
+ });
55634
+ }
55635
+ function SelectField({ field }) {
55636
+ const basics = fieldBasics(field);
55637
+ const options = field.options ?? [];
55638
+ const multiple = Boolean(field.multiple);
55639
+ return /* @__PURE__ */ jsx(LabelledField, {
55640
+ basics,
55641
+ children: /* @__PURE__ */ jsxs("select", {
55642
+ id: basics.inputId,
55643
+ name: field.id,
55644
+ multiple,
55645
+ required: basics.required,
55646
+ className: "form-select",
55647
+ children: [!multiple && /* @__PURE__ */ jsx("option", {
55648
+ value: "",
55649
+ children: "Select…"
55650
+ }), options.map((opt) => /* @__PURE__ */ jsx("option", {
55651
+ value: opt.value,
55652
+ children: opt.label
55653
+ }, opt.value))]
55654
+ })
55655
+ });
55656
+ }
55657
+ function RadioField({ field }) {
55658
+ const basics = fieldBasics(field);
55659
+ const options = field.options ?? [];
55660
+ return /* @__PURE__ */ jsxs("fieldset", {
55661
+ className: "fb-fieldset",
55662
+ children: [/* @__PURE__ */ jsx("legend", {
55663
+ className: "form-label",
55664
+ children: basics.label
55665
+ }), options.map((opt) => /* @__PURE__ */ jsxs("label", {
55666
+ className: "form-check",
55667
+ children: [/* @__PURE__ */ jsx("input", {
55668
+ type: "radio",
55669
+ name: field.id,
55670
+ value: opt.value,
55671
+ required: basics.required,
55672
+ className: "form-radio"
55673
+ }), /* @__PURE__ */ jsx("span", {
55674
+ className: "form-check-label",
55675
+ children: opt.label
55676
+ })]
55677
+ }, opt.value))]
55678
+ });
55679
+ }
55680
+ function TextInputField({ field, type }) {
55681
+ const basics = fieldBasics(field);
55682
+ const inputType = textInputType(type);
55683
+ return /* @__PURE__ */ jsx(LabelledField, {
55684
+ basics,
55685
+ children: /* @__PURE__ */ jsx("input", {
55686
+ id: basics.inputId,
55687
+ name: field.id,
55688
+ type: inputType,
55689
+ required: basics.required,
55690
+ placeholder: field.placeholder,
55691
+ ...textInputConstraints(field, inputType),
55692
+ className: "form-input"
55693
+ })
55694
+ });
55695
+ }
55696
+ function FormFieldControl({ field }) {
55697
+ const type = String(field.type ?? "text");
55698
+ switch (type) {
55699
+ case "textarea": return /* @__PURE__ */ jsx(TextareaField, { field });
55700
+ case "select": return /* @__PURE__ */ jsx(SelectField, { field });
55701
+ case "radio": return /* @__PURE__ */ jsx(RadioField, { field });
55702
+ case "checkbox":
55703
+ case "consent": {
55704
+ const basics = fieldBasics(field);
55705
+ return /* @__PURE__ */ jsx(CheckboxChoice, {
55706
+ name: field.id,
55707
+ required: basics.required,
55708
+ label: basics.label,
55709
+ presentation: type === "consent" ? "tile" : "row"
55710
+ });
55711
+ }
55712
+ default: return /* @__PURE__ */ jsx(TextInputField, {
55713
+ field,
55714
+ type
55715
+ });
55716
+ }
55717
+ }
55718
+ var init_form_fields = __esmMin((() => {
55719
+ init_CheckboxChoice();
55720
+ }));
55721
+ //#endregion
55290
55722
  //#region ../blocks/src/system/runtime/nodes/form.server.tsx
55291
55723
  init_clsx();
55292
55724
  init_ThemedButton();
55293
55725
  init_FeedbackMessage();
55726
+ init_form_fields();
55294
55727
  init_form_interactive();
55295
55728
  const FormNodeSSR = ({ blockId, value, submitLabel, successMessage, className, onSubmit, action = "/api/forms/submit", siteId, apiBaseUrl, spamProtectionEnabled }) => {
55296
55729
  const islandProps = buildFormInteractiveIslandProps({
@@ -55314,107 +55747,7 @@ const FormNodeSSR = ({ blockId, value, submitLabel, successMessage, className, o
55314
55747
  })]
55315
55748
  });
55316
55749
  const groups = display.groups;
55317
- const renderField = (field) => {
55318
- const inputId = `f_${field.id}`;
55319
- const label = String(field.label ?? field.id);
55320
- const required = Boolean(field.required);
55321
- const type = String(field.type ?? "text");
55322
- if (type === "textarea") return /* @__PURE__ */ jsxs("div", {
55323
- className: "fb-field",
55324
- children: [/* @__PURE__ */ jsx("label", {
55325
- htmlFor: inputId,
55326
- className: "form-label",
55327
- children: label
55328
- }), /* @__PURE__ */ jsx("textarea", {
55329
- id: inputId,
55330
- name: field.id,
55331
- required,
55332
- placeholder: field.placeholder,
55333
- rows: field.rows,
55334
- className: "form-textarea"
55335
- })]
55336
- }, field.id);
55337
- if (type === "select") {
55338
- const options = field.options ?? [];
55339
- const multiple = Boolean(field.multiple);
55340
- return /* @__PURE__ */ jsxs("div", {
55341
- className: "fb-field",
55342
- children: [/* @__PURE__ */ jsx("label", {
55343
- htmlFor: inputId,
55344
- className: "form-label",
55345
- children: label
55346
- }), /* @__PURE__ */ jsxs("select", {
55347
- id: inputId,
55348
- name: field.id,
55349
- multiple,
55350
- required,
55351
- className: "form-select",
55352
- children: [!multiple && /* @__PURE__ */ jsx("option", {
55353
- value: "",
55354
- children: "Select…"
55355
- }), options.map((opt) => /* @__PURE__ */ jsx("option", {
55356
- value: opt.value,
55357
- children: opt.label
55358
- }, opt.value))]
55359
- })]
55360
- }, field.id);
55361
- }
55362
- if (type === "radio") {
55363
- const options = field.options ?? [];
55364
- return /* @__PURE__ */ jsxs("fieldset", {
55365
- className: "fb-fieldset",
55366
- children: [/* @__PURE__ */ jsx("legend", {
55367
- className: "form-label",
55368
- children: label
55369
- }), options.map((opt) => /* @__PURE__ */ jsxs("label", {
55370
- className: "fb-inline form-label",
55371
- children: [/* @__PURE__ */ jsx("input", {
55372
- type: "radio",
55373
- name: field.id,
55374
- value: opt.value,
55375
- required,
55376
- className: "form-radio"
55377
- }), /* @__PURE__ */ jsx("span", { children: opt.label })]
55378
- }, opt.value))]
55379
- }, field.id);
55380
- }
55381
- if (type === "checkbox" || type === "consent") return /* @__PURE__ */ jsxs("label", {
55382
- className: "fb-inline form-label",
55383
- children: [/* @__PURE__ */ jsx("input", {
55384
- type: "checkbox",
55385
- name: field.id,
55386
- required,
55387
- className: "form-checkbox"
55388
- }), /* @__PURE__ */ jsx("span", { children: label })]
55389
- }, field.id);
55390
- const inputType = type === "email" || type === "url" || type === "tel" || type === "number" ? type : "text";
55391
- const extra = {};
55392
- if (inputType === "text" || inputType === "email" || inputType === "url" || inputType === "tel") {
55393
- if (typeof field.minLength === "number") extra.minLength = field.minLength;
55394
- if (typeof field.maxLength === "number") extra.maxLength = field.maxLength;
55395
- if (typeof field.pattern === "string" && field.pattern) extra.pattern = field.pattern;
55396
- }
55397
- if (inputType === "number") {
55398
- if (typeof field.min === "number") extra.min = field.min;
55399
- if (typeof field.max === "number") extra.max = field.max;
55400
- }
55401
- return /* @__PURE__ */ jsxs("div", {
55402
- className: "fb-field",
55403
- children: [/* @__PURE__ */ jsx("label", {
55404
- htmlFor: inputId,
55405
- className: "form-label",
55406
- children: label
55407
- }), /* @__PURE__ */ jsx("input", {
55408
- id: inputId,
55409
- name: field.id,
55410
- type: inputType,
55411
- required,
55412
- placeholder: field.placeholder,
55413
- ...extra,
55414
- className: "form-input"
55415
- })]
55416
- }, field.id);
55417
- };
55750
+ const renderField = (field) => /* @__PURE__ */ jsx(FormFieldControl, { field }, field.id);
55418
55751
  return /* @__PURE__ */ jsxs("div", {
55419
55752
  ...getIslandRootProps("form", blockId),
55420
55753
  children: [/* @__PURE__ */ jsx(IslandPropsScript, { value: islandProps }), /* @__PURE__ */ jsxs("form", {
@@ -55460,9 +55793,173 @@ const FormNodeSSR = ({ blockId, value, submitLabel, successMessage, className, o
55460
55793
  });
55461
55794
  };
55462
55795
  //#endregion
55796
+ //#region ../blocks/src/system/runtime/shared/components/FieldValidationMessage.tsx
55797
+ function getFieldValidationControlProps({ message, messageId, describedBy }) {
55798
+ const hasMessage = Boolean(message);
55799
+ const ariaDescribedBy = [describedBy, hasMessage ? messageId : void 0].filter((part) => typeof part === "string" && part.length > 0).join(" ");
55800
+ return {
55801
+ "aria-invalid": hasMessage ? "true" : void 0,
55802
+ "aria-describedby": ariaDescribedBy || void 0
55803
+ };
55804
+ }
55805
+ function FieldValidationMessage({ id, children, className, live = "assertive" }) {
55806
+ return /* @__PURE__ */ jsx("p", {
55807
+ id,
55808
+ className,
55809
+ "data-field-validation-message": true,
55810
+ "data-field-validation-tone": "error",
55811
+ role: "alert",
55812
+ "aria-live": live === "off" ? void 0 : live,
55813
+ children
55814
+ });
55815
+ }
55816
+ var init_FieldValidationMessage = __esmMin((() => {}));
55817
+ //#endregion
55818
+ //#region ../blocks/src/system/runtime/nodes/newsletter-form.parts.tsx
55819
+ /** Splits the preset's fields into the email (joined with the button) and the rest. */
55820
+ function partitionNewsletterFields(fields) {
55821
+ const email = fields.find((field) => field.type === "email") ?? null;
55822
+ return {
55823
+ email,
55824
+ extra: fields.filter((field) => field !== email)
55825
+ };
55826
+ }
55827
+ function NewsletterExtraField({ field, disabled, error }) {
55828
+ const inputId = inputIdFor(field);
55829
+ const errorId = `${inputId}-error`;
55830
+ return /* @__PURE__ */ jsxs("div", {
55831
+ className: "fb-field newsletter-field",
55832
+ children: [
55833
+ /* @__PURE__ */ jsx("label", {
55834
+ htmlFor: inputId,
55835
+ className: "rb-sr-only",
55836
+ children: field.label
55837
+ }),
55838
+ /* @__PURE__ */ jsx("input", {
55839
+ id: inputId,
55840
+ name: field.id,
55841
+ type: field.type,
55842
+ required: field.required,
55843
+ placeholder: field.placeholder ?? field.label,
55844
+ className: "form-input",
55845
+ disabled,
55846
+ ...getFieldValidationControlProps({
55847
+ message: error,
55848
+ messageId: errorId
55849
+ })
55850
+ }),
55851
+ error ? /* @__PURE__ */ jsx(FieldValidationMessage, {
55852
+ id: errorId,
55853
+ className: "fb-error",
55854
+ children: error
55855
+ }) : null
55856
+ ]
55857
+ });
55858
+ }
55859
+ /** The email field and submit button sharing one input-styled shell. */
55860
+ function NewsletterEmailEntry({ field, buttonVariant, buttonLabel, disabled, error }) {
55861
+ const inputId = inputIdFor(field);
55862
+ const errorId = `${inputId}-error`;
55863
+ return /* @__PURE__ */ jsxs("div", {
55864
+ className: "newsletter-entry",
55865
+ children: [/* @__PURE__ */ jsxs("div", {
55866
+ className: "form-input-group newsletter-entry-group",
55867
+ children: [
55868
+ /* @__PURE__ */ jsx("label", {
55869
+ htmlFor: inputId,
55870
+ className: "rb-sr-only",
55871
+ children: field.label
55872
+ }),
55873
+ /* @__PURE__ */ jsx("input", {
55874
+ id: inputId,
55875
+ name: field.id,
55876
+ type: "email",
55877
+ required: field.required,
55878
+ placeholder: field.placeholder ?? field.label,
55879
+ className: "form-input-group-field",
55880
+ autoComplete: "email",
55881
+ disabled,
55882
+ ...getFieldValidationControlProps({
55883
+ message: error,
55884
+ messageId: errorId
55885
+ })
55886
+ }),
55887
+ /* @__PURE__ */ jsx(ThemedButton, {
55888
+ type: "submit",
55889
+ variant: buttonVariant,
55890
+ size: "md",
55891
+ disabled,
55892
+ label: buttonLabel
55893
+ })
55894
+ ]
55895
+ }), error ? /* @__PURE__ */ jsx(FieldValidationMessage, {
55896
+ id: errorId,
55897
+ className: "fb-error",
55898
+ children: error
55899
+ }) : null]
55900
+ });
55901
+ }
55902
+ /**
55903
+ * The submit action: joined to the email field when the preset has one
55904
+ * (every current preset does), otherwise a plain themed button.
55905
+ */
55906
+ function NewsletterSubmitRow({ emailField, buttonVariant, buttonLabel, disabled, error }) {
55907
+ if (emailField) return /* @__PURE__ */ jsx(NewsletterEmailEntry, {
55908
+ field: emailField,
55909
+ buttonVariant,
55910
+ buttonLabel,
55911
+ disabled,
55912
+ error
55913
+ });
55914
+ return /* @__PURE__ */ jsx("div", {
55915
+ className: "newsletter-submit",
55916
+ children: /* @__PURE__ */ jsx(ThemedButton, {
55917
+ type: "submit",
55918
+ variant: buttonVariant,
55919
+ size: "md",
55920
+ disabled,
55921
+ label: buttonLabel
55922
+ })
55923
+ });
55924
+ }
55925
+ /** Visitor-chosen topics as toggle chips. Real checkboxes underneath. */
55926
+ function NewsletterTopicChips({ choices, disabled, error }) {
55927
+ const errorId = `newsletter_${TOPIC_CHOICE_FIELD_ID}-error`;
55928
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("fieldset", {
55929
+ className: "newsletter-topics",
55930
+ "aria-describedby": error ? errorId : void 0,
55931
+ children: [/* @__PURE__ */ jsx("legend", {
55932
+ className: "newsletter-topics-legend",
55933
+ children: "What would you like to hear about?"
55934
+ }), /* @__PURE__ */ jsx("div", {
55935
+ className: "newsletter-topic-chips",
55936
+ children: choices.map((choice) => /* @__PURE__ */ jsxs("label", {
55937
+ className: "newsletter-topic-chip",
55938
+ children: [/* @__PURE__ */ jsx("input", {
55939
+ type: "checkbox",
55940
+ name: TOPIC_CHOICE_FIELD_ID,
55941
+ value: choice.id,
55942
+ disabled
55943
+ }), /* @__PURE__ */ jsx("span", { children: choice.label })]
55944
+ }, choice.id))
55945
+ })]
55946
+ }), error ? /* @__PURE__ */ jsx(FieldValidationMessage, {
55947
+ id: errorId,
55948
+ className: "fb-error",
55949
+ children: error
55950
+ }) : null] });
55951
+ }
55952
+ var TOPIC_CHOICE_FIELD_ID, inputIdFor;
55953
+ var init_newsletter_form_parts = __esmMin((() => {
55954
+ init_ThemedButton();
55955
+ init_FieldValidationMessage();
55956
+ TOPIC_CHOICE_FIELD_ID = "mailingListChoice";
55957
+ inputIdFor = (field) => `newsletter_${field.id}`;
55958
+ }));
55959
+ //#endregion
55463
55960
  //#region ../blocks/src/system/runtime/nodes/newsletter-form.server.tsx
55464
55961
  init_clsx();
55465
- init_ThemedButton();
55962
+ init_newsletter_form_parts();
55466
55963
  init_newsletter_form_interactive();
55467
55964
  /**
55468
55965
  * Newsletter Form Server Component
@@ -55483,36 +55980,15 @@ function NewsletterFormSSR(props) {
55483
55980
  });
55484
55981
  const display = islandProps.render.display;
55485
55982
  const fields = display.fields;
55983
+ const submissionMessage = newsletterBlockSubmissionMessage(islandProps.render.hydration.target);
55486
55984
  if (display.availability === "unavailable") return /* @__PURE__ */ jsx("div", {
55487
55985
  className: clsx("newsletter-form-ssr", className),
55488
55986
  children: /* @__PURE__ */ jsx("p", {
55489
55987
  role: "status",
55490
- children: "We can’t accept signups right now. Please try again later."
55988
+ children: NEWSLETTER_SIGNUPS_PAUSED_MESSAGE
55491
55989
  })
55492
55990
  });
55493
- const renderField = (field) => {
55494
- const inputId = `newsletter_${field.id}`;
55495
- return /* @__PURE__ */ jsxs("div", {
55496
- className: "fb-field newsletter-field",
55497
- children: [/* @__PURE__ */ jsxs("label", {
55498
- htmlFor: inputId,
55499
- className: "form-label",
55500
- children: [field.label, field.required && /* @__PURE__ */ jsx("span", {
55501
- className: "newsletter-required",
55502
- "aria-hidden": "true",
55503
- children: "*"
55504
- })]
55505
- }), /* @__PURE__ */ jsx("input", {
55506
- id: inputId,
55507
- name: field.id,
55508
- type: field.type,
55509
- required: field.required,
55510
- placeholder: field.placeholder,
55511
- className: "form-input",
55512
- autoComplete: field.type === "email" ? "email" : void 0
55513
- })]
55514
- }, field.id);
55515
- };
55991
+ const { email: emailField, extra: extraFields } = partitionNewsletterFields(fields);
55516
55992
  return /* @__PURE__ */ jsxs("div", {
55517
55993
  ...getIslandRootProps("newsletter-form", blockId),
55518
55994
  className: clsx("newsletter-form-ssr", className),
@@ -55531,30 +56007,20 @@ function NewsletterFormSSR(props) {
55531
56007
  /* @__PURE__ */ jsxs("div", {
55532
56008
  className: "newsletter-form-fields",
55533
56009
  children: [
55534
- fields.map(renderField),
55535
- islandProps.render.hydration.choicePresentation === "visitor_choice" ? /* @__PURE__ */ jsxs("fieldset", {
55536
- className: "fb-fieldset newsletter-topics",
55537
- children: [/* @__PURE__ */ jsx("legend", {
55538
- className: "form-label",
55539
- children: "What would you like to hear about?"
55540
- }), display.choices.map((choice) => /* @__PURE__ */ jsxs("label", {
55541
- className: "fb-inline form-label newsletter-topic-choice",
55542
- children: [/* @__PURE__ */ jsx("input", {
55543
- type: "checkbox",
55544
- name: "mailingListChoice",
55545
- value: choice.id,
55546
- className: "form-checkbox"
55547
- }), /* @__PURE__ */ jsx("span", { children: choice.label })]
55548
- }, choice.id))]
56010
+ islandProps.render.hydration.choicePresentation === "visitor_choice" ? /* @__PURE__ */ jsx(NewsletterTopicChips, { choices: display.choices }) : null,
56011
+ extraFields.length > 0 ? /* @__PURE__ */ jsx("div", {
56012
+ className: "newsletter-extra-fields",
56013
+ children: extraFields.map((field) => /* @__PURE__ */ jsx(NewsletterExtraField, { field }, field.id))
55549
56014
  }) : null,
55550
- /* @__PURE__ */ jsx("div", {
55551
- className: "newsletter-submit",
55552
- children: /* @__PURE__ */ jsx(ThemedButton, {
55553
- type: "submit",
55554
- variant: display.buttonVariant,
55555
- size: "md",
55556
- label: display.buttonLabel
55557
- })
56015
+ /* @__PURE__ */ jsx(NewsletterSubmitRow, {
56016
+ emailField,
56017
+ buttonVariant: display.buttonVariant,
56018
+ buttonLabel: display.buttonLabel,
56019
+ disabled: submissionMessage !== null
56020
+ }),
56021
+ submissionMessage && /* @__PURE__ */ jsx("p", {
56022
+ role: "status",
56023
+ children: submissionMessage
55558
56024
  })
55559
56025
  ]
55560
56026
  }),
@@ -56547,7 +57013,7 @@ const RENDERER_METADATA_PROP_KEYS = /* @__PURE__ */ new Set([
56547
57013
  "blockContent",
56548
57014
  "fragmentRegistry",
56549
57015
  "previewAuthoring",
56550
- "contentVersionId",
57016
+ "newsletterBlockSubmission",
56551
57017
  "imageResolveContext"
56552
57018
  ]);
56553
57019
  function omitRendererMetadataProps(props) {
@@ -56603,7 +57069,7 @@ function resolveNodeMetadata(nodeType, context) {
56603
57069
  pathBase: context.pathBase,
56604
57070
  fragmentRegistry: context.fragmentRegistry
56605
57071
  } : {},
56606
- ...normalizedType === "newsletter-form" ? { contentVersionId: context.contentVersionId } : {},
57072
+ ...normalizedType === "newsletter-form" ? { newsletterBlockSubmission: context.newsletterBlockSubmission } : {},
56607
57073
  ...normalizedType === "media" && context.imageResolveContext ? { imageResolveContext: context.imageResolveContext } : {}
56608
57074
  };
56609
57075
  }
@@ -57222,6 +57688,259 @@ function generateHoverEffects(axes, _space) {
57222
57688
  };
57223
57689
  }
57224
57690
  //#endregion
57691
+ //#region ../theme-core/src/inputs/checkable.ts
57692
+ init_colorTokenParts();
57693
+ init_colorStyles();
57694
+ const CHECKABLE_SIZE = "1.375rem";
57695
+ /** Never fully round: a round checkbox reads as a radio. */
57696
+ const CHECKBOX_RADIUS = {
57697
+ square: "0",
57698
+ soft: "0.25rem",
57699
+ rounded: "0.375rem",
57700
+ pill: "0.375rem"
57701
+ };
57702
+ /** Tiles hold wrapping text, so pill themes get a generous radius, not a capsule. */
57703
+ const TILE_RADIUS = {
57704
+ square: "0",
57705
+ soft: "0.5rem",
57706
+ rounded: "0.75rem",
57707
+ pill: "1rem"
57708
+ };
57709
+ const ON_ACCENT_TOKENS = {
57710
+ primary: "onPrimary",
57711
+ secondary: "onSecondary",
57712
+ accent: "onAccent"
57713
+ };
57714
+ /**
57715
+ * Colour for the tick/dot drawn on top of the accent fill. Uses the palette's
57716
+ * matching "on" token where there is one, falling back to white.
57717
+ */
57718
+ /** The accent at full strength: `primary/70` becomes `primary`. */
57719
+ function solidAccentToken(accentToken) {
57720
+ const parsed = parseColorTokenParts(accentToken);
57721
+ return parsed.kind === "token" ? parsed.token : accentToken;
57722
+ }
57723
+ function checkableMarkColor(accentToken) {
57724
+ const parsed = parseColorTokenParts(accentToken);
57725
+ const onToken = parsed.kind === "token" ? ON_ACCENT_TOKENS[parsed.token] : void 0;
57726
+ return onToken ? `rgb(var(--tb-${onToken}, 255 255 255))` : "rgb(255 255 255)";
57727
+ }
57728
+ function checkableSelectors(root) {
57729
+ return {
57730
+ checkbox: `${root} .form-checkbox`,
57731
+ radio: `${root} .form-radio`,
57732
+ check: `${root} .form-check`,
57733
+ tile: `${root} .form-check--tile`
57734
+ };
57735
+ }
57736
+ /** The box and circle themselves, unchecked. */
57737
+ function controlBaseCss(sel, input) {
57738
+ const border = input.borderWidth === "0" ? "1px" : input.borderWidth;
57739
+ return [
57740
+ `${sel.checkbox},
57741
+ ${sel.radio} {
57742
+ appearance: none;
57743
+ display: inline-grid;
57744
+ place-content: center;
57745
+ width: ${CHECKABLE_SIZE};
57746
+ height: ${CHECKABLE_SIZE};
57747
+ margin: 0;
57748
+ flex-shrink: 0;
57749
+ border: ${border} solid ${input.borderColor};
57750
+ background-color: ${input.background};
57751
+ color: inherit;
57752
+ cursor: pointer;
57753
+ transition: background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
57754
+ }`,
57755
+ `${sel.checkbox} {
57756
+ border-radius: ${CHECKBOX_RADIUS[input.corners]};
57757
+ }`,
57758
+ `${sel.radio} {
57759
+ border-radius: 9999px;
57760
+ }`
57761
+ ];
57762
+ }
57763
+ /** The tick and dot, drawn with ::before so their colour is a theme token. */
57764
+ function controlMarkCss(sel, accentToken) {
57765
+ return [
57766
+ `${sel.checkbox}::before,
57767
+ ${sel.radio}::before {
57768
+ content: "";
57769
+ background-color: ${checkableMarkColor(accentToken)};
57770
+ transform: scale(0);
57771
+ transition: transform 0.12s ease;
57772
+ }`,
57773
+ `${sel.checkbox}::before {
57774
+ width: 0.75rem;
57775
+ height: 0.75rem;
57776
+ clip-path: polygon(14% 52%, 0 67%, 38% 100%, 100% 22%, 85% 8%, 37% 70%);
57777
+ }`,
57778
+ `${sel.radio}::before {
57779
+ width: 0.5rem;
57780
+ height: 0.5rem;
57781
+ border-radius: 9999px;
57782
+ }`
57783
+ ];
57784
+ }
57785
+ function controlStateCss(sel, input) {
57786
+ const accent = rgbColorValue(solidAccentToken(input.accentToken));
57787
+ return [
57788
+ `${sel.checkbox}:hover,
57789
+ ${sel.radio}:hover,
57790
+ ${sel.check}:hover > .form-checkbox,
57791
+ ${sel.check}:hover > .form-radio {
57792
+ border-color: ${accent};
57793
+ }`,
57794
+ `${sel.checkbox}:checked,
57795
+ ${sel.radio}:checked {
57796
+ background-color: ${accent};
57797
+ border-color: ${accent};
57798
+ }`,
57799
+ `${sel.checkbox}:checked::before,
57800
+ ${sel.radio}:checked::before {
57801
+ transform: scale(1);
57802
+ }`,
57803
+ `${sel.checkbox}:focus-visible,
57804
+ ${sel.radio}:focus-visible {
57805
+ outline: 2px solid ${accent};
57806
+ outline-offset: 2px;
57807
+ }`,
57808
+ `${sel.checkbox}:disabled,
57809
+ ${sel.radio}:disabled {
57810
+ opacity: 0.5;
57811
+ cursor: not-allowed;
57812
+ }`
57813
+ ];
57814
+ }
57815
+ /** Label row: control lined up with the first line of wrapping text. */
57816
+ function checkRowCss(sel) {
57817
+ return [
57818
+ `${sel.check} {
57819
+ display: flex;
57820
+ align-items: flex-start;
57821
+ gap: 0.75rem;
57822
+ line-height: 1.5;
57823
+ cursor: pointer;
57824
+ }`,
57825
+ `${sel.check} > .form-checkbox,
57826
+ ${sel.check} > .form-radio {
57827
+ margin-top: 0.0625rem;
57828
+ margin-top: max(0px, calc((1lh - ${CHECKABLE_SIZE}) / 2));
57829
+ }`,
57830
+ `${sel.check}:has(> :disabled) {
57831
+ cursor: not-allowed;
57832
+ }`
57833
+ ];
57834
+ }
57835
+ function agreementTileCss(sel, input) {
57836
+ const accent = rgbColorValue(solidAccentToken(input.accentToken));
57837
+ return [
57838
+ `${sel.tile} {
57839
+ padding: 0.875rem 1rem;
57840
+ border: 1px solid color-mix(in srgb, currentColor 22%, transparent);
57841
+ border-radius: ${TILE_RADIUS[input.corners]};
57842
+ transition: border-color 0.15s ease, background-color 0.15s ease;
57843
+ }`,
57844
+ `${sel.tile}:hover {
57845
+ border-color: color-mix(in srgb, ${accent} 55%, transparent);
57846
+ }`,
57847
+ `${sel.tile}:has(> .form-checkbox:checked) {
57848
+ border-color: ${accent};
57849
+ background-color: color-mix(in srgb, ${accent} 7%, transparent);
57850
+ }`,
57851
+ `${sel.tile}:has(> .form-checkbox[aria-invalid="true"]) {
57852
+ border-color: ${input.errorColor};
57853
+ }`
57854
+ ];
57855
+ }
57856
+ function checkableMediaCss(sel) {
57857
+ return [`@media (prefers-reduced-motion: reduce) {
57858
+ ${sel.checkbox}, ${sel.radio}, ${sel.checkbox}::before, ${sel.radio}::before, ${sel.tile} {
57859
+ transition: none;
57860
+ }
57861
+ }`, `@media (forced-colors: active) {
57862
+ ${sel.checkbox}::before,
57863
+ ${sel.radio}::before {
57864
+ background-color: CanvasText;
57865
+ }
57866
+ }`];
57867
+ }
57868
+ /**
57869
+ * Exposes the accent and mark colours so other choice controls (newsletter
57870
+ * topic chips) match the checkboxes without re-deriving the theme tokens.
57871
+ */
57872
+ function checkableVarsCss(input) {
57873
+ return [`${input.root} {
57874
+ --rb-check-accent: ${rgbColorValue(solidAccentToken(input.accentToken))};
57875
+ --rb-check-mark: ${checkableMarkColor(input.accentToken)};
57876
+ }`];
57877
+ }
57878
+ function generateCheckableCss(input) {
57879
+ const sel = checkableSelectors(input.root);
57880
+ return [
57881
+ ...checkableVarsCss(input),
57882
+ ...controlBaseCss(sel, input),
57883
+ ...controlMarkCss(sel, input.accentToken),
57884
+ ...controlStateCss(sel, input),
57885
+ ...checkRowCss(sel),
57886
+ ...agreementTileCss(sel, input),
57887
+ ...checkableMediaCss(sel)
57888
+ ].join("\n\n");
57889
+ }
57890
+ //#endregion
57891
+ //#region ../theme-core/src/inputs/inputGroup.ts
57892
+ /**
57893
+ * Input group: a field and an action (usually a themed button) sharing one
57894
+ * input-styled shell, e.g. the newsletter email + Sign up row.
57895
+ *
57896
+ * The shell `.form-input-group` takes the theme's `.form-input` rules (the
57897
+ * generators add it to that selector list, plus focus and error), so it
57898
+ * follows the site's input background, border, corners and shadow. This file
57899
+ * only adds the layout overrides and the borderless inner field.
57900
+ */
57901
+ const INPUT_GROUP_SELECTOR = ".form-input-group";
57902
+ /** Shell focus ring follows the field only, not the button beside it. */
57903
+ const INPUT_GROUP_FOCUS_SELECTOR = ".form-input-group:has(> .form-input-group-field:focus-visible)";
57904
+ const INPUT_GROUP_ERROR_SELECTOR = ".form-input-group:has(> .form-input-group-field[aria-invalid=\"true\"])";
57905
+ const GROUP_INSET = "0.25rem";
57906
+ /**
57907
+ * @param root - scoped root selector
57908
+ * @param padding - the theme's input padding shorthand (`block inline`), so the
57909
+ * inner field's text sits where a plain input's text would.
57910
+ */
57911
+ function generateInputGroupCss(root, padding) {
57912
+ const [block = padding, inline = block] = padding.trim().split(/\s+/);
57913
+ return `${root} .form-input-group {
57914
+ display: flex;
57915
+ align-items: stretch;
57916
+ gap: ${GROUP_INSET};
57917
+ padding: ${GROUP_INSET};
57918
+ }
57919
+
57920
+ ${root} .form-input-group-field {
57921
+ flex: 1 1 auto;
57922
+ min-width: 0;
57923
+ margin: 0;
57924
+ border: 0;
57925
+ border-radius: 0;
57926
+ background: transparent;
57927
+ box-shadow: none;
57928
+ outline: none;
57929
+ color: inherit;
57930
+ font: inherit;
57931
+ padding: calc(${block} - ${GROUP_INSET}) calc(${inline} - ${GROUP_INSET});
57932
+ }
57933
+
57934
+ ${root} .form-input-group-field::placeholder {
57935
+ color: inherit;
57936
+ opacity: 0.6;
57937
+ }
57938
+
57939
+ ${root} .form-input-group > :not(.form-input-group-field) {
57940
+ flex-shrink: 0;
57941
+ }`;
57942
+ }
57943
+ //#endregion
57225
57944
  //#region ../theme-core/src/inputs/generateInputCss.ts
57226
57945
  init_types$11();
57227
57946
  init_constants$2();
@@ -57235,6 +57954,9 @@ const CORNER_MAP$1 = {
57235
57954
  rounded: "1rem",
57236
57955
  pill: "9999px"
57237
57956
  };
57957
+ function inputBackgroundValue(background) {
57958
+ return background.type === "transparent" ? "transparent" : rgbColorValue(background.colorToken);
57959
+ }
57238
57960
  /**
57239
57961
  * Generate CSS for form input styling based on theme configuration
57240
57962
  *
@@ -57252,8 +57974,7 @@ const CORNER_MAP$1 = {
57252
57974
  function generateInputCss({ themeId, theme, inputSystem }) {
57253
57975
  const rootSelector = `:where([data-theme-scope="${themeId}"])`;
57254
57976
  const baseInputRules = [];
57255
- if (inputSystem.base.background.type === "transparent") baseInputRules.push("background-color: transparent");
57256
- else baseInputRules.push(`background-color: ${rgbColorValue(inputSystem.base.background.colorToken)}`);
57977
+ baseInputRules.push(`background-color: ${inputBackgroundValue(inputSystem.base.background)}`);
57257
57978
  baseInputRules.push(`color: ${rgbColorValue(inputSystem.base.textColorToken)}`);
57258
57979
  const borderPx = parseBorderWidth(inputSystem.base.border.widthClass);
57259
57980
  const borderStyle = inputSystem.base.border.style ?? "all";
@@ -57309,7 +58030,8 @@ function generateInputCss({ themeId, theme, inputSystem }) {
57309
58030
  const focusSelectors = [
57310
58031
  `${inputSelector}:focus-visible`,
57311
58032
  `${textareaSelector}:focus-visible`,
57312
- `${selectSelector}:focus-visible`
58033
+ `${selectSelector}:focus-visible`,
58034
+ `${rootSelector} ${INPUT_GROUP_FOCUS_SELECTOR}`
57313
58035
  ];
57314
58036
  const focusRules = [];
57315
58037
  focusRules.push("outline: none");
@@ -57318,7 +58040,8 @@ function generateInputCss({ themeId, theme, inputSystem }) {
57318
58040
  const errorSelectors = [
57319
58041
  `${inputSelector}[aria-invalid="true"]`,
57320
58042
  `${textareaSelector}[aria-invalid="true"]`,
57321
- `${selectSelector}[aria-invalid="true"]`
58043
+ `${selectSelector}[aria-invalid="true"]`,
58044
+ `${rootSelector} ${INPUT_GROUP_ERROR_SELECTOR}`
57322
58045
  ];
57323
58046
  const errorRules = [];
57324
58047
  errorRules.push(`border-color: ${rgbColorValue(inputSystem.error.borderColorToken)}`);
@@ -57333,53 +58056,25 @@ function generateInputCss({ themeId, theme, inputSystem }) {
57333
58056
  disabledRules.push(`color: ${rgbColorValue(inputSystem.disabled.textColorToken)}`);
57334
58057
  disabledRules.push(`opacity: ${inputSystem.disabled.opacity}`);
57335
58058
  disabledRules.push("cursor: not-allowed");
57336
- const checkboxSelector = `${rootSelector} .form-checkbox`;
57337
- const radioSelector = `${rootSelector} .form-radio`;
57338
- const checkableRules = [];
57339
- checkableRules.push("appearance: none");
57340
- checkableRules.push("width: 1.125rem");
57341
- checkableRules.push("height: 1.125rem");
57342
- checkableRules.push("flex-shrink: 0");
57343
- checkableRules.push(`border: ${borderPx} solid ${rgbColorValue(inputSystem.base.border.colorToken)}`);
57344
- if (inputSystem.base.background.type === "transparent") checkableRules.push("background-color: transparent");
57345
- else checkableRules.push(`background-color: ${rgbColorValue(inputSystem.base.background.colorToken)}`);
57346
- checkableRules.push("cursor: pointer");
57347
- checkableRules.push("transition: background-color 0.2s ease, border-color 0.2s ease");
57348
- const checkboxSpecificRules = [...checkableRules];
57349
- checkboxSpecificRules.push(`border-radius: ${CORNER_MAP$1.soft}`);
57350
- const radioSpecificRules = [...checkableRules];
57351
- radioSpecificRules.push("border-radius: 9999px");
57352
- const checkboxCheckedSelector = `${checkboxSelector}:checked`;
57353
- const checkboxCheckedRules = [];
57354
- checkboxCheckedRules.push(`background-color: ${rgbColorValue(inputSystem.focus.ringColorToken)}`);
57355
- checkboxCheckedRules.push(`border-color: ${rgbColorValue(inputSystem.focus.ringColorToken)}`);
57356
- checkboxCheckedRules.push("background-image: url(\"data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e\")");
57357
- checkboxCheckedRules.push("background-size: 100% 100%");
57358
- checkboxCheckedRules.push("background-position: center");
57359
- checkboxCheckedRules.push("background-repeat: no-repeat");
57360
- const radioCheckedSelector = `${radioSelector}:checked`;
57361
- const radioCheckedRules = [];
57362
- radioCheckedRules.push(`background-color: ${rgbColorValue(inputSystem.focus.ringColorToken)}`);
57363
- radioCheckedRules.push(`border-color: ${rgbColorValue(inputSystem.focus.ringColorToken)}`);
57364
- radioCheckedRules.push("background-image: radial-gradient(circle, white 40%, transparent 40%)");
57365
- const checkboxFocusSelector = `${checkboxSelector}:focus-visible`;
57366
- const radioFocusSelector = `${radioSelector}:focus-visible`;
57367
- const checkableFocusRules = [];
57368
- checkableFocusRules.push("outline: none");
57369
- checkableFocusRules.push(`box-shadow: 0 0 0 ${inputSystem.focus.ringWidth}px ${rgbColorValue(inputSystem.focus.ringColorToken)}`);
58059
+ const checkableCss = generateCheckableCss({
58060
+ root: rootSelector,
58061
+ borderWidth: borderPx,
58062
+ borderColor: rgbColorValue(inputSystem.base.border.colorToken),
58063
+ background: inputBackgroundValue(inputSystem.base.background),
58064
+ corners: inputSystem.base.corners ?? theme.corners,
58065
+ accentToken: inputSystem.focus.borderColorToken ?? inputSystem.focus.ringColorToken,
58066
+ errorColor: rgbColorValue(inputSystem.error.borderColorToken)
58067
+ });
57370
58068
  const cssBlocks = [];
57371
58069
  cssBlocks.push(`${labelSelector} {\n ${labelRules.join(";\n ")};\n}`);
57372
- cssBlocks.push(`${inputSelector} {\n ${inputRules.join(";\n ")};\n}`);
58070
+ cssBlocks.push(`${inputSelector},\n${rootSelector} ${INPUT_GROUP_SELECTOR} {\n ${inputRules.join(";\n ")};\n}`);
57373
58071
  cssBlocks.push(`${textareaSelector} {\n ${textareaRules.join(";\n ")};\n}`);
57374
58072
  cssBlocks.push(`${selectSelector} {\n ${selectRules.join(";\n ")};\n}`);
57375
58073
  cssBlocks.push(`${focusSelectors.join(",\n")} {\n ${focusRules.join(";\n ")};\n}`);
57376
58074
  cssBlocks.push(`${errorSelectors.join(",\n")} {\n ${errorRules.join(";\n ")};\n}`);
57377
58075
  cssBlocks.push(`${disabledSelectors.join(",\n")} {\n ${disabledRules.join(";\n ")};\n}`);
57378
- cssBlocks.push(`${checkboxSelector} {\n ${checkboxSpecificRules.join(";\n ")};\n}`);
57379
- cssBlocks.push(`${radioSelector} {\n ${radioSpecificRules.join(";\n ")};\n}`);
57380
- cssBlocks.push(`${checkboxCheckedSelector} {\n ${checkboxCheckedRules.join(";\n ")};\n}`);
57381
- cssBlocks.push(`${radioCheckedSelector} {\n ${radioCheckedRules.join(";\n ")};\n}`);
57382
- cssBlocks.push(`${checkboxFocusSelector},\n${radioFocusSelector} {\n ${checkableFocusRules.join(";\n ")};\n}`);
58076
+ cssBlocks.push(generateInputGroupCss(rootSelector, padding));
58077
+ cssBlocks.push(checkableCss);
57383
58078
  return cssBlocks.join("\n\n");
57384
58079
  }
57385
58080
  //#endregion
@@ -63877,13 +64572,13 @@ const hours = stack({
63877
64572
  as: "p",
63878
64573
  className: "rb-caption rb-opacity-70"
63879
64574
  }, bind("module.timeZone"), when("module.timeZone"))], when("module.kind", { equals: "opening-hours" }));
63880
- const socials = inline({ className: "rb-flex rb-flex-wrap rb-gap-x-5 rb-gap-y-3" }, [link({
64575
+ const socials = inline({ className: "rb-footer-socials" }, [link({
63881
64576
  href: { $bind: { from: "social.href" } },
63882
64577
  target: "_blank",
63883
64578
  rel: "noreferrer noopener",
63884
64579
  "aria-label": { $bind: { from: "social.label" } },
63885
- className: "rb-nav-text transition-theme-standard"
63886
- }, [icon({ className: "rb-h-5 rb-w-5" }, bind("social.icon"), when("social.icon")), text({ as: "span" }, bind("social.label"), when("social.icon", { equals: null }))], repeat("module.socialLinks", "social"))], when("module.kind", { equals: "social-links" }));
64580
+ className: "rb-footer-social-link rb-nav-text transition-theme-standard"
64581
+ }, [icon({ className: "rb-footer-social-icon" }, bind("social.icon"), when("social.icon")), text({ as: "span" }, bind("social.label"), when("social.icon", { equals: null }))], repeat("module.socialLinks", "social"))], when("module.kind", { equals: "social-links" }));
63887
64582
  const authoredCopy = richText({
63888
64583
  className: "rb-prose rb-prose-sm rb-max-w-none",
63889
64584
  style: textColorStyle("text/80")
@@ -69986,43 +70681,53 @@ function collectNestedPreviewFieldConstraintEntries(field, path) {
69986
70681
  default: return assertNever$20(field);
69987
70682
  }
69988
70683
  }
70684
+ function prepareDefaultBlockRender(manifest, props) {
70685
+ if (!props.theme) throw new Error("Block rendering requires theme tokens; none were provided to makeDefaultBlockComponent");
70686
+ if (!props.registry) throw new Error("Block rendering requires a component registry; none was provided");
70687
+ const content = props.content;
70688
+ const layout = resolveBlockLayout(manifest, content);
70689
+ if (!layout) throw new Error(`Block manifest "${manifest.name}" requires a layout definition`);
70690
+ const mergedContent = mergeContentWithBlockStyleOverrides(content, props.themeConfig, props.blockKind ?? manifest.name);
70691
+ return {
70692
+ registry: props.registry,
70693
+ layout,
70694
+ mergedContent,
70695
+ fieldConstraints: buildPreviewFieldConstraints(manifest),
70696
+ viewModel: buildBlockViewModel({
70697
+ mergedContent,
70698
+ data: props.data,
70699
+ resolvedThemeConfig: resolveThemeConfigForBindings(props.themeConfig),
70700
+ viewModelOverrides: props.viewModelOverrides
70701
+ }),
70702
+ themeForTransforms: withButtonSystem(props.theme, props.themeConfig)
70703
+ };
70704
+ }
69989
70705
  function makeDefaultBlockComponent(args) {
69990
- const { manifest } = args;
69991
- return function DefaultBlockComponent({ content, data, registry, theme, themeConfig, transforms, viewModelOverrides, pathBase, blockId, contentVersionId, blockKind, blockBindings, editableRouteMetadataFieldIds, fragmentRegistry, imageResolveContext, previewAuthoring }) {
70706
+ return function DefaultBlockComponent(props) {
69992
70707
  const perf = beginBlockRenderMeasurement();
69993
- if (!theme) throw new Error("Block rendering requires theme tokens; none were provided to makeDefaultBlockComponent");
69994
- if (!registry) throw new Error("Block rendering requires a component registry; none was provided");
69995
- const layout = resolveBlockLayout(manifest, content);
69996
- if (!layout) throw new Error(`Block manifest "${manifest.name}" requires a layout definition`);
69997
- const fieldConstraints = buildPreviewFieldConstraints(manifest);
69998
- const mergedContent = mergeContentWithBlockStyleOverrides(content, themeConfig, blockKind ?? manifest.name);
69999
- const result = resolveTree(layout, {
70000
- registry,
70001
- viewModel: buildBlockViewModel({
70002
- mergedContent,
70003
- data,
70004
- resolvedThemeConfig: resolveThemeConfigForBindings(themeConfig),
70005
- viewModelOverrides
70006
- }),
70007
- transforms,
70008
- theme: withButtonSystem(theme, themeConfig),
70009
- pathBase,
70010
- blockId,
70011
- contentVersionId,
70012
- blockKind,
70013
- blockContent: mergedContent,
70014
- blockBindings,
70015
- editableRouteMetadataFieldIds,
70016
- fragmentRegistry,
70017
- fieldConstraints,
70018
- imageResolveContext,
70019
- previewAuthoring
70708
+ const prepared = prepareDefaultBlockRender(args.manifest, props);
70709
+ const result = resolveTree(prepared.layout, {
70710
+ registry: prepared.registry,
70711
+ viewModel: prepared.viewModel,
70712
+ transforms: props.transforms,
70713
+ theme: prepared.themeForTransforms,
70714
+ pathBase: props.pathBase,
70715
+ blockId: props.blockId,
70716
+ newsletterBlockSubmission: props.newsletterBlockSubmission,
70717
+ blockKind: props.blockKind,
70718
+ blockContent: prepared.mergedContent,
70719
+ blockBindings: props.blockBindings,
70720
+ editableRouteMetadataFieldIds: props.editableRouteMetadataFieldIds,
70721
+ fragmentRegistry: props.fragmentRegistry,
70722
+ fieldConstraints: prepared.fieldConstraints,
70723
+ imageResolveContext: props.imageResolveContext,
70724
+ previewAuthoring: props.previewAuthoring
70020
70725
  });
70021
70726
  reportSlowBlockRender(perf, {
70022
- content,
70023
- blockId,
70024
- blockKind: blockKind ?? manifest.name,
70025
- manifestName: manifest.name
70727
+ content: props.content,
70728
+ blockId: props.blockId,
70729
+ blockKind: props.blockKind ?? args.manifest.name,
70730
+ manifestName: args.manifest.name
70026
70731
  });
70027
70732
  return result;
70028
70733
  };
@@ -70601,6 +71306,40 @@ function resolveBlockData(blockId, dataLoaders, dataContext, routes) {
70601
71306
  return dataLoaders && typeof dataLoaders === "object" && Object.keys(dataLoaders).length > 0 ? {} : void 0;
70602
71307
  }
70603
71308
  //#endregion
71309
+ //#region ../blocks/src/system/runtime/nodes/newsletter-form.block-submission.ts
71310
+ init_src$2();
71311
+ /** Authorise one block source for both public and preview rendering. */
71312
+ function planNewsletterBlockSubmission(placement) {
71313
+ if (placement.stage === "published") {
71314
+ const sourceRef = buildMailingListSignupBlockSourceRef(placement.blockId, placement.selectedContentVersionId);
71315
+ return sourceRef ? {
71316
+ tag: "ready",
71317
+ sourceRef
71318
+ } : { tag: "unavailable" };
71319
+ }
71320
+ if (placement.publishedPlacement) return planNewsletterPreviewSubmission({
71321
+ blockId: placement.blockId,
71322
+ publishedContentId: placement.publishedPlacement.id,
71323
+ renderedContent: placement.renderedContent,
71324
+ publishedContent: placement.publishedPlacement.content
71325
+ });
71326
+ if (placement.stage === "preview") return { tag: "unpublished-form" };
71327
+ return { tag: "unavailable" };
71328
+ }
71329
+ /** Decide whether the visible draft can safely cite the published placement. */
71330
+ function planNewsletterPreviewSubmission(placement) {
71331
+ if (!placement.publishedContentId) return { tag: "unpublished-form" };
71332
+ if (!placement.publishedContent) return { tag: "unpublished-settings" };
71333
+ const draft = parseMailingListPlacementTargeting(placement.renderedContent.targeting ?? { mode: "default" });
71334
+ const published = parseMailingListPlacementTargeting(placement.publishedContent.targeting);
71335
+ if (!draft.ok || !published.ok || !sameMailingListPlacementTargeting(draft.value, published.value)) return { tag: "unpublished-settings" };
71336
+ const sourceRef = buildMailingListSignupBlockSourceRef(placement.blockId, placement.publishedContentId);
71337
+ return sourceRef ? {
71338
+ tag: "ready",
71339
+ sourceRef
71340
+ } : { tag: "unpublished-settings" };
71341
+ }
71342
+ //#endregion
70604
71343
  //#region ../blocks/src/pageRenderPreparation.ts
70605
71344
  /**
70606
71345
  * Stage two of the render plan.
@@ -70729,9 +71468,20 @@ function buildBlockOverrideProps(input) {
70729
71468
  imageResolveContext: input.imageResolveContext,
70730
71469
  blockId: block.id ?? null,
70731
71470
  contentVersionId: block.contentVersionId ?? null,
71471
+ ...newsletterBlockProps(block, input.content, dataContext?.previewStage),
70732
71472
  blockKind: block.kind
70733
71473
  };
70734
71474
  }
71475
+ function newsletterBlockProps(block, renderedContent, stage) {
71476
+ if (block.kind !== "block.newsletter-signup") return {};
71477
+ return { newsletterBlockSubmission: planNewsletterBlockSubmission({
71478
+ blockId: block.id,
71479
+ selectedContentVersionId: block.contentVersionId ?? null,
71480
+ publishedPlacement: block.publishedPlacement ?? null,
71481
+ renderedContent,
71482
+ stage
71483
+ }) };
71484
+ }
70735
71485
  /** Site, transport and session context a block needs to call back to the API. */
70736
71486
  function blockSessionProps(dataContext) {
70737
71487
  return {
@@ -70821,6 +71571,15 @@ function createBlockErrorBoundary() {
70821
71571
  const BlockErrorBoundary = createBlockErrorBoundary();
70822
71572
  //#endregion
70823
71573
  //#region ../blocks/src/pageRenderAdmission.ts
71574
+ /** Pair a published version with the content it authorises at the render boundary. */
71575
+ function readPublishedBlockPlacement(id, content) {
71576
+ if (id == null && content == null) return null;
71577
+ if (id == null || content == null) throw new Error("Published block placement requires both an ID and content");
71578
+ return {
71579
+ id,
71580
+ content
71581
+ };
71582
+ }
70824
71583
  function toPresentationPage(page) {
70825
71584
  if (!page) return null;
70826
71585
  return {
@@ -70831,6 +71590,8 @@ function toPresentationPage(page) {
70831
71590
  kind: block.kind,
70832
71591
  purpose: block.purpose,
70833
71592
  ...block.contentVersionId ? { contentVersionId: block.contentVersionId } : {},
71593
+ ...block.draftContentId !== void 0 ? { draftContentId: block.draftContentId } : {},
71594
+ ...block.publishedPlacement !== void 0 ? { publishedPlacement: block.publishedPlacement } : {},
70834
71595
  ...block.bindings ? { bindings: block.bindings } : {}
70835
71596
  };
70836
71597
  return block.admission.kind === "renderable" ? {
@@ -72682,6 +73443,9 @@ const containerResponsiveThemeCss = `/*
72682
73443
  .rb-h-4 {
72683
73444
  height: 1rem;
72684
73445
  }
73446
+ .rb-h-5 {
73447
+ height: 1.25rem;
73448
+ }
72685
73449
  .rb-h-8 {
72686
73450
  height: 2rem;
72687
73451
  }
@@ -76647,6 +77411,10 @@ const containerResponsiveThemeCss = `/*
76647
77411
  margin-bottom: 0.25rem;
76648
77412
  }
76649
77413
 
77414
+ :where(.theme-scope) :where([data-block='event-registration']) .er-consent-check {
77415
+ margin-top: 0.75rem;
77416
+ }
77417
+
76650
77418
  :where(.theme-scope) :where([data-block='event-registration']) .er-required {
76651
77419
  color: var(--er-required);
76652
77420
  }
@@ -81366,13 +82134,6 @@ const containerResponsiveThemeCss = `/*
81366
82134
  margin: 0;
81367
82135
  }
81368
82136
 
81369
- /* Inline field (checkbox, radio with label) */
81370
- :where(.theme-scope) :where([data-block="form"]) .fb-inline {
81371
- display: flex;
81372
- align-items: center;
81373
- gap: 0.5rem;
81374
- }
81375
-
81376
82137
  /* Success state */
81377
82138
  :where(.theme-scope) :where([data-block="form"]) .fb-success {
81378
82139
  background-color: var(--fb-success-bg);
@@ -83489,9 +84250,11 @@ const containerResponsiveThemeCss = `/*
83489
84250
  */
83490
84251
 
83491
84252
  /* Newsletter copy styling */
84253
+ /* Size only: weight, family and colour come from the theme's heading styles */
83492
84254
  :where(.theme-scope) :where([data-block="newsletter-signup"]) .newsletter-copy-title {
83493
- font-size: 1.5rem;
83494
- font-weight: 600;
84255
+ font-size: clamp(1.75rem, 1.35rem + 1.6vw, 2.5rem);
84256
+ line-height: 1.15;
84257
+ text-wrap: balance;
83495
84258
  }
83496
84259
 
83497
84260
  :where(.theme-scope) :where([data-block="newsletter-signup"]) .newsletter-copy-subtitle {
@@ -83515,37 +84278,150 @@ const containerResponsiveThemeCss = `/*
83515
84278
  gap: var(--rb-gap-sm, 0.75rem);
83516
84279
  }
83517
84280
 
83518
- /* Individual field styling */
84281
+ /* Extra preset fields (name, company...). Labels are visually hidden, so
84282
+ these sit in a row above the email entry. */
84283
+ :where(.theme-scope) .newsletter-extra-fields {
84284
+ display: grid;
84285
+ grid-template-columns: repeat(auto-fit, minmax(min(12rem, 100%), 1fr));
84286
+ gap: 0.5rem;
84287
+ }
84288
+
83519
84289
  :where(.theme-scope) .newsletter-field {
83520
84290
  display: flex;
83521
84291
  flex-direction: column;
83522
84292
  gap: 0.25rem;
84293
+ text-align: left;
83523
84294
  }
83524
84295
 
83525
- /* Topic choices (visitor picks what to hear about). Same treatment as the
83526
- form block's .fb-fieldset / .fb-inline, defined here because the newsletter
83527
- form also renders inside contact-newsletter and the site footer. */
83528
- :where(.theme-scope) .newsletter-topics {
84296
+ /* Email entry: the email field and the themed submit button share one shell.
84297
+ The shell's look (background, border, corners, focus ring) comes from the
84298
+ theme's input system via .form-input-group; this only handles layout. */
84299
+ :where(.theme-scope) .newsletter-entry {
84300
+ container-type: inline-size;
83529
84301
  display: flex;
83530
84302
  flex-direction: column;
83531
- gap: 0.5rem;
84303
+ gap: 0.375rem;
84304
+ text-align: left;
84305
+ }
84306
+
84307
+ :where(.theme-scope) .newsletter-entry-group > button {
84308
+ white-space: nowrap;
84309
+ }
84310
+
84311
+ /* Too narrow for field and button side by side (phones, footer columns):
84312
+ stack them inside the shell and keep pill themes from turning the taller
84313
+ shell into a capsule. */
84314
+ @container (max-width: 22rem) {
84315
+ :where(.theme-scope) .newsletter-entry .newsletter-entry-group {
84316
+ flex-direction: column;
84317
+ border-radius: min(var(--rb-input-radius, 0.5rem), 1rem);
84318
+ }
84319
+
84320
+ :where(.theme-scope) .newsletter-entry .newsletter-entry-group > button {
84321
+ width: 100%;
84322
+ justify-content: center;
84323
+ }
84324
+ }
84325
+
84326
+ /* Topic choices (visitor picks what to hear about) as toggle chips. Each chip
84327
+ is a real checkbox underneath; the chip is its visible face. */
84328
+ :where(.theme-scope) .newsletter-topics {
83532
84329
  border: none;
83533
84330
  padding: 0;
83534
84331
  margin: 0;
83535
84332
  min-width: 0;
83536
84333
  }
83537
84334
 
83538
- :where(.theme-scope) .newsletter-topics > legend {
84335
+ :where(.theme-scope) .newsletter-topics-legend {
83539
84336
  padding: 0;
83540
- margin-bottom: 0.25rem;
84337
+ margin-bottom: 0.625rem;
84338
+ font-size: 0.9375rem;
84339
+ color: var(--rb-surface-text-color, rgb(var(--tb-text, 17 24 39)));
83541
84340
  }
83542
84341
 
83543
- :where(.theme-scope) .newsletter-topic-choice {
84342
+ :where(.theme-scope) .newsletter-topic-chips {
83544
84343
  display: flex;
83545
- align-items: center;
84344
+ flex-wrap: wrap;
83546
84345
  gap: 0.5rem;
83547
84346
  }
83548
84347
 
84348
+ :where(.theme-scope) .newsletter-stacked .newsletter-topics-legend {
84349
+ width: 100%;
84350
+ }
84351
+
84352
+ :where(.theme-scope) .newsletter-stacked .newsletter-topic-chips {
84353
+ justify-content: center;
84354
+ }
84355
+
84356
+ :where(.theme-scope) .newsletter-topic-chip {
84357
+ position: relative;
84358
+ display: inline-flex;
84359
+ }
84360
+
84361
+ :where(.theme-scope) .newsletter-topic-chip > input {
84362
+ position: absolute;
84363
+ inset: 0;
84364
+ width: 100%;
84365
+ height: 100%;
84366
+ margin: 0;
84367
+ opacity: 0;
84368
+ cursor: pointer;
84369
+ }
84370
+
84371
+ :where(.theme-scope) .newsletter-topic-chip > span {
84372
+ display: inline-flex;
84373
+ align-items: center;
84374
+ gap: 0.375rem;
84375
+ padding: 0.4375rem 0.9375rem;
84376
+ border: 1px solid color-mix(in srgb, currentColor 35%, transparent);
84377
+ border-radius: var(--rb-button-radius, var(--rb-input-radius, 9999px));
84378
+ font-size: 0.9375rem;
84379
+ line-height: 1.3;
84380
+ color: var(--rb-surface-text-color, rgb(var(--tb-text, 17 24 39)));
84381
+ transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
84382
+ }
84383
+
84384
+ /* Tick that grows in when the chip is on */
84385
+ :where(.theme-scope) .newsletter-topic-chip > span::before {
84386
+ content: "";
84387
+ width: 0;
84388
+ height: 0.7em;
84389
+ background-color: currentColor;
84390
+ clip-path: polygon(14% 52%, 0 67%, 38% 100%, 100% 22%, 85% 8%, 37% 70%);
84391
+ transition: width 0.15s ease;
84392
+ }
84393
+
84394
+ :where(.theme-scope) .newsletter-topic-chip:hover > span {
84395
+ border-color: currentColor;
84396
+ }
84397
+
84398
+ /* Same accent and mark colours as the theme's checkboxes */
84399
+ :where(.theme-scope) .newsletter-topic-chip > input:checked + span {
84400
+ background-color: var(--rb-check-accent, rgb(var(--tb-primary)));
84401
+ border-color: var(--rb-check-accent, rgb(var(--tb-primary)));
84402
+ color: var(--rb-check-mark, rgb(var(--tb-onPrimary, 255 255 255)));
84403
+ }
84404
+
84405
+ :where(.theme-scope) .newsletter-topic-chip > input:checked + span::before {
84406
+ width: 0.7em;
84407
+ }
84408
+
84409
+ :where(.theme-scope) .newsletter-topic-chip > input:focus-visible + span {
84410
+ outline: 2px solid var(--rb-check-accent, rgb(var(--tb-primary)));
84411
+ outline-offset: 2px;
84412
+ }
84413
+
84414
+ :where(.theme-scope) .newsletter-topic-chip > input:disabled + span {
84415
+ opacity: 0.6;
84416
+ }
84417
+
84418
+ @media (prefers-reduced-motion: reduce) {
84419
+ :where(.theme-scope) .newsletter-topic-chip > span,
84420
+ :where(.theme-scope) .newsletter-topic-chip > span::before {
84421
+ transition: none;
84422
+ }
84423
+ }
84424
+
83549
84425
  /* Error panel and field notes. The form block scopes these to its own
83550
84426
  data-block, so the newsletter form (which also renders in the footer)
83551
84427
  needs its own copy of the treatment. */
@@ -83563,13 +84439,7 @@ const containerResponsiveThemeCss = `/*
83563
84439
  color: var(--fb-error-text);
83564
84440
  }
83565
84441
 
83566
- /* Required indicator */
83567
- :where(.theme-scope) .newsletter-required {
83568
- color: rgb(var(--tb-primary));
83569
- margin-left: 0.125rem;
83570
- }
83571
-
83572
- /* Submit button container */
84442
+ /* Submit button container (only when a preset has no email field) */
83573
84443
  :where(.theme-scope) .newsletter-submit {
83574
84444
  margin-top: 0.5rem;
83575
84445
  }
@@ -83581,52 +84451,29 @@ const containerResponsiveThemeCss = `/*
83581
84451
  justify-content: center;
83582
84452
  }
83583
84453
 
83584
- /* Privacy note */
84454
+ /* Privacy note: quieter than the intro so the entry row leads */
83585
84455
  :where(.theme-scope) .newsletter-privacy-note {
83586
84456
  margin-top: 0.75rem;
83587
- font-size: 1rem;
83588
- line-height: 1.6;
83589
- color: var(--rb-surface-text-color, rgb(var(--tb-text, 17 24 39)));
84457
+ font-size: 0.8125rem;
84458
+ line-height: 1.5;
84459
+ color: var(--rb-surface-supporting-color, var(--rb-surface-text-color, rgb(var(--tb-text, 17 24 39))));
84460
+ opacity: 0.85;
83590
84461
  text-align: center;
83591
84462
  }
83592
84463
 
83593
84464
  /* =============================================================================
83594
- * Inline Variant - Horizontal layout
84465
+ * Inline Variant - left-aligned, wider entry row
83595
84466
  * =============================================================================
83596
84467
  */
83597
84468
 
83598
- :where(.theme-scope) .newsletter-inline .newsletter-form-fields {
83599
- flex-direction: row;
83600
- align-items: flex-end;
83601
- flex-wrap: wrap;
83602
- gap: var(--rb-gap-sm, 0.75rem);
83603
- }
83604
-
83605
- :where(.theme-scope) .newsletter-inline .newsletter-field {
83606
- flex: 1 1 auto;
83607
- min-width: 10rem;
83608
- }
83609
-
83610
- :where(.theme-scope) .newsletter-inline .newsletter-submit {
83611
- margin-top: 0;
83612
- flex-shrink: 0;
83613
- }
83614
-
83615
- :where(.theme-scope) .newsletter-inline .newsletter-topics {
83616
- flex-basis: 100%;
84469
+ :where(.theme-scope) .newsletter-inline .newsletter-form {
84470
+ max-width: 40rem;
84471
+ margin-left: 0;
84472
+ margin-right: 0;
83617
84473
  }
83618
84474
 
83619
- /* Mobile fallback for inline variant */
83620
- @container rb-site (max-width: 640px) {
83621
- @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
83622
- :where(.theme-scope) .newsletter-inline .newsletter-form-fields {
83623
- flex-direction: column;
83624
- }
83625
-
83626
- :where(.theme-scope) .newsletter-inline .newsletter-field {
83627
- min-width: 100%;
83628
- }
83629
- }
84475
+ :where(.theme-scope) .newsletter-inline .newsletter-privacy-note {
84476
+ text-align: left;
83630
84477
  }
83631
84478
 
83632
84479
  /* =============================================================================
@@ -83764,12 +84611,6 @@ const containerResponsiveThemeCss = `/*
83764
84611
  margin: 0;
83765
84612
  }
83766
84613
 
83767
- :where(.theme-scope) :where([data-block="contact-newsletter"]) .fb-inline {
83768
- display: flex;
83769
- align-items: center;
83770
- gap: 0.5rem;
83771
- }
83772
-
83773
84614
  :where(.theme-scope) :where([data-block="contact-newsletter"]) .fb-success,
83774
84615
  :where(.theme-scope) :where([data-block="contact-newsletter"]) .fb-error,
83775
84616
  :where(.theme-scope) :where([data-block="contact-newsletter"]) .fb-empty {
@@ -85666,6 +86507,44 @@ const containerResponsiveThemeCss = `/*
85666
86507
  flex: 0 0 auto;
85667
86508
  }
85668
86509
  }
86510
+ }
86511
+
86512
+ /* =============================================================================
86513
+ * Site footer: social links
86514
+ *
86515
+ * Icon links get a 40px tap target with a hairline ring drawn from the link's
86516
+ * own colour, so it follows the footer's text colour on any surface. Links
86517
+ * without an icon (unknown platforms) stay plain text.
86518
+ * =============================================================================
86519
+ */
86520
+
86521
+ :where(.theme-scope) .rb-footer-socials {
86522
+ display: flex;
86523
+ flex-wrap: wrap;
86524
+ align-items: center;
86525
+ gap: 0.75rem 1.25rem;
86526
+ }
86527
+
86528
+ :where(.theme-scope) .rb-footer-social-link:has(> .rb-footer-social-icon) {
86529
+ display: inline-grid;
86530
+ place-items: center;
86531
+ width: 2.5rem;
86532
+ height: 2.5rem;
86533
+ border: 1px solid color-mix(in srgb, currentColor 22%, transparent);
86534
+ border-radius: 9999px;
86535
+ }
86536
+
86537
+ :where(.theme-scope) .rb-footer-socials:has(.rb-footer-social-icon) {
86538
+ gap: 0.5rem;
86539
+ }
86540
+
86541
+ :where(.theme-scope) .rb-footer-social-link:has(> .rb-footer-social-icon):hover {
86542
+ border-color: currentColor;
86543
+ }
86544
+
86545
+ :where(.theme-scope) .rb-footer-social-icon {
86546
+ width: 1.5rem;
86547
+ height: 1.5rem;
85669
86548
  }`;
85670
86549
  //#endregion
85671
86550
  //#region ../theme-core/src/ThemeScopeCore.tsx
@@ -86768,6 +87647,46 @@ z$1.object({ acceptExtraSiteCharge: z$1.boolean().optional() });
86768
87647
  //#region ../surfaces/src/index.ts
86769
87648
  const SURFACE_IDS = ["core", "macadamia"];
86770
87649
  const DEFAULT_SURFACE_ID = "core";
87650
+ /**
87651
+ * Root hosts for each surface, keyed by deployment tier. The tier-keyed shape
87652
+ * makes it impossible to mis-order entries: callers like
87653
+ * `buildSurfaceAwareDashboardOriginForSurfaceId` look up by tier directly
87654
+ * rather than relying on positional alignment between arrays.
87655
+ */
87656
+ const SURFACE_ROOT_HOSTS = {
87657
+ core: {
87658
+ local: "localhost",
87659
+ prod: "riverbankcms.com"
87660
+ },
87661
+ macadamia: {
87662
+ local: "macadamia.localhost",
87663
+ prod: "macadamia.studio"
87664
+ }
87665
+ };
87666
+ const SURFACE_SITE_ROOT_HOSTS = {
87667
+ core: {
87668
+ local: "localhost",
87669
+ prod: "riverbanksites.com"
87670
+ },
87671
+ macadamia: {
87672
+ local: "macadamia.localhost",
87673
+ prod: "macadamia.studio"
87674
+ }
87675
+ };
87676
+ const SURFACE_SITE_ROOT_HOST_ALIASES = { core: { prod: ["preview.riverbanksites.com"] } };
87677
+ function surfaceHostTableValues(table) {
87678
+ return Object.values(table).flatMap((byTier) => Object.values(byTier).flat());
87679
+ }
87680
+ function siteSlugLabelUnderRoot(host, siteRootHost) {
87681
+ if (!host.endsWith(`.${siteRootHost}`)) return [];
87682
+ return host.slice(0, host.length - siteRootHost.length - 1).split(".").slice(-1);
87683
+ }
87684
+ function deriveSurfaceOwnedSiteSlugs() {
87685
+ const siteRootHosts = [...surfaceHostTableValues(SURFACE_SITE_ROOT_HOSTS), ...surfaceHostTableValues(SURFACE_SITE_ROOT_HOST_ALIASES)];
87686
+ const labels = [...surfaceHostTableValues(SURFACE_ROOT_HOSTS), ...siteRootHosts].flatMap((host) => siteRootHosts.flatMap((root) => siteSlugLabelUnderRoot(host, root)));
87687
+ return [...new Set(labels)].sort();
87688
+ }
87689
+ deriveSurfaceOwnedSiteSlugs();
86771
87690
  [...SURFACE_IDS.filter((surfaceId) => surfaceId !== DEFAULT_SURFACE_ID)];
86772
87691
  //#endregion
86773
87692
  //#region ../api/src/url.ts
@@ -87826,6 +88745,7 @@ function parsePublicProductCategorySelector(value) {
87826
88745
  productCategoryEntryId: record.productCategoryEntryId
87827
88746
  };
87828
88747
  }
88748
+ z$1.enum(["public", "unlisted"], { error: "visibility must be 'public' or 'unlisted'" });
87829
88749
  //#endregion
87830
88750
  //#region ../api/src/bookingConfig.ts
87831
88751
  init_src$2();
@@ -88442,21 +89362,42 @@ function resolveSiteCustomBlocks(site) {
88442
89362
  const sdkBlocks = site.sdkConfig?.customBlocks;
88443
89363
  if (Array.isArray(sdkBlocks) && sdkBlocks.length > 0) return sdkBlocks;
88444
89364
  }
88445
- function convertPageResponseBlock(block) {
89365
+ function collectMediaAssetSidecar(mediaAssets) {
89366
+ return Array.isArray(mediaAssets) && mediaAssets.length > 0 ? mediaAssets : void 0;
89367
+ }
89368
+ function readBlockContentId(value, name) {
89369
+ if (value === null || value === void 0) return null;
89370
+ if (typeof value === "string") return value;
89371
+ throw new Error(`Invalid ${name} in page: expected string or null`);
89372
+ }
89373
+ function readTransportedBlockIdentity(block, kind, stage) {
89374
+ return {
89375
+ draftContentId: readBlockContentId(block.draftContentId, "draft content id"),
89376
+ publishedPlacement: stage === "preview" ? readPublishedBlockPlacement(readBlockContentId(block.publishedContentId, "published content id"), sanitizeNullableSdkRuntimeBlockContent(kind, readNestedContentRecord(block.publishedContent))) : null
89377
+ };
89378
+ }
89379
+ function convertPageResponseBlock(block, stage) {
88446
89380
  if (!isRecord$4(block)) throw new Error("Invalid block format in page API response");
89381
+ const header = readTransportedBlockHeader(block);
89382
+ const admission = readInvalidBlockAdmission(block.admission);
89383
+ return {
89384
+ ...header,
89385
+ ...readTransportedBlockIdentity(block, header.kind, stage),
89386
+ content: sanitizeSdkRuntimeBlockContent(header.kind, readContentRecord(block.content) ?? {}),
89387
+ draftContent: sanitizeNullableSdkRuntimeBlockContent(header.kind, readNestedContentRecord(block.draftContent)),
89388
+ ...admission ? { admission } : {}
89389
+ };
89390
+ }
89391
+ function readTransportedBlockHeader(block) {
88447
89392
  if (typeof block.id !== "string" && block.id !== null) throw new Error(`Invalid block id in page: expected string or null, got ${typeof block.id}`);
88448
89393
  if (typeof block.kind !== "string") throw new Error(`Invalid block kind in page: expected string, got ${typeof block.kind}`);
88449
89394
  if (typeof block.purpose !== "string") throw new Error(`Invalid block purpose in page: expected string, got ${typeof block.purpose}`);
88450
89395
  if (block.contentVersionId !== void 0 && block.contentVersionId !== null && typeof block.contentVersionId !== "string") throw new Error(`Invalid content version id in page: expected string or null, got ${typeof block.contentVersionId}`);
88451
- const admission = readInvalidBlockAdmission(block.admission);
88452
89396
  return {
88453
89397
  id: block.id,
88454
89398
  ...block.contentVersionId !== void 0 ? { contentVersionId: block.contentVersionId } : {},
88455
89399
  kind: block.kind,
88456
- purpose: block.purpose,
88457
- content: sanitizeSdkRuntimeBlockContent(block.kind, readContentRecord(block.content) ?? {}),
88458
- draftContent: sanitizeNullableSdkRuntimeBlockContent(block.kind, readNestedContentRecord(block.draftContent)),
88459
- ...admission ? { admission } : {}
89400
+ purpose: block.purpose
88460
89401
  };
88461
89402
  }
88462
89403
  function readInvalidBlockAdmission(value) {
@@ -88469,7 +89410,7 @@ function buildPageOutline(input) {
88469
89410
  name: input.name,
88470
89411
  path: input.path ?? input.fallbackPath,
88471
89412
  purpose: input.purpose,
88472
- blocks: input.blocks.map(convertPageResponseBlock)
89413
+ blocks: input.blocks.map((block) => convertPageResponseBlock(block, input.previewStage))
88473
89414
  };
88474
89415
  }
88475
89416
  function buildRenderablePageOutline(input) {
@@ -88495,6 +89436,8 @@ function projectRenderablePageOutline(page) {
88495
89436
  function admitSdkRuntimePageBlock(block, customBlocks) {
88496
89437
  const base = {
88497
89438
  id: block.id,
89439
+ draftContentId: block.draftContentId,
89440
+ publishedPlacement: block.publishedPlacement,
88498
89441
  ...block.contentVersionId !== void 0 ? { contentVersionId: block.contentVersionId } : {},
88499
89442
  kind: block.kind,
88500
89443
  purpose: block.purpose,
@@ -88556,6 +89499,40 @@ function sanitizeNullableSdkRuntimeBlockContent(blockKind, content) {
88556
89499
  *
88557
89500
  * Use this in client components for dynamic page loading.
88558
89501
  */
89502
+ async function loadUsePageSuccess(input) {
89503
+ const { client, site, pageResponse, siteId, path, pageId, preview } = input;
89504
+ const pageData = pageResponse.page;
89505
+ const mediaAssets = collectMediaAssetSidecar(pageResponse.mediaAssets);
89506
+ const previewStage = preview ? "preview" : "published";
89507
+ const pageOutline = buildRenderablePageOutline({
89508
+ name: pageData.name,
89509
+ path: pageData.path ?? path,
89510
+ fallbackPath: path,
89511
+ purpose: pageData.purpose,
89512
+ blocks: pageData.blocks,
89513
+ previewStage,
89514
+ customBlocks: resolveSiteCustomBlocks(site)
89515
+ });
89516
+ const resolvedData = await prefetchBlockData(projectRenderablePageOutline(pageOutline), {
89517
+ siteId,
89518
+ pageId: pageId ?? pageData.id,
89519
+ previewStage
89520
+ }, client);
89521
+ return {
89522
+ loading: false,
89523
+ error: null,
89524
+ page: pageOutline,
89525
+ runtimeJoins: pageData.runtimeJoins,
89526
+ theme: requireSdkTheme(site.theme, siteId),
89527
+ siteId,
89528
+ resolvedData,
89529
+ dataContext: { previewStage },
89530
+ mailingList: site.mailingList,
89531
+ sdkConfig: site.sdkConfig ?? null,
89532
+ supabaseUrl: site.supabaseUrl,
89533
+ ...mediaAssets ? { mediaAssets } : {}
89534
+ };
89535
+ }
88559
89536
  /**
88560
89537
  * Client-side React hook to fetch all data needed for <Page> component.
88561
89538
  *
@@ -88646,36 +89623,17 @@ function usePage(params) {
88646
89623
  if (cancelled) return;
88647
89624
  if ("entry" in pageResponse) throw new Error("This path resolves to a content entry, not a page. Use useContent() instead, which handles both pages and entries. For entries, useContent() returns the raw entry data for custom rendering.");
88648
89625
  if ("pageSurface" in pageResponse) throw new Error("This path resolves to a page surface, not a page. Use useContent() instead, which handles pages, entries, and page surfaces.");
88649
- const { page: pageData } = pageResponse;
88650
- const canonicalPagePath = pageData.path ?? path;
88651
- const mediaAssets = Array.isArray(pageResponse.mediaAssets) && pageResponse.mediaAssets.length > 0 ? toMediaAssetSidecar$1(pageResponse.mediaAssets) : void 0;
88652
- const pageOutline = buildRenderablePageOutline({
88653
- name: pageData.name,
88654
- path: canonicalPagePath,
88655
- fallbackPath: path,
88656
- purpose: pageData.purpose,
88657
- blocks: pageData.blocks,
88658
- customBlocks: resolveSiteCustomBlocks(site)
88659
- });
88660
- const resolvedData = await prefetchBlockData(projectRenderablePageOutline(pageOutline), {
88661
- siteId,
88662
- pageId: pageId ?? pageData.id,
88663
- previewStage: preview ? "preview" : "published"
88664
- }, client);
88665
- if (cancelled) return;
88666
- setResult({
88667
- loading: false,
88668
- error: null,
88669
- page: pageOutline,
88670
- runtimeJoins: pageData.runtimeJoins,
88671
- theme: requireSdkTheme(site.theme, siteId),
89626
+ const success = await loadUsePageSuccess({
89627
+ client,
89628
+ site,
89629
+ pageResponse,
88672
89630
  siteId,
88673
- resolvedData,
88674
- mailingList: site.mailingList,
88675
- sdkConfig: site.sdkConfig ?? null,
88676
- supabaseUrl: site.supabaseUrl,
88677
- ...mediaAssets ? { mediaAssets } : {}
89631
+ path,
89632
+ pageId,
89633
+ preview
88678
89634
  });
89635
+ if (cancelled) return;
89636
+ setResult(success);
88679
89637
  } catch (error) {
88680
89638
  if (cancelled) return;
88681
89639
  setResult({
@@ -88702,9 +89660,6 @@ function usePage(params) {
88702
89660
  ]);
88703
89661
  return result;
88704
89662
  }
88705
- function toMediaAssetSidecar$1(mediaAssets) {
88706
- return mediaAssets ?? [];
88707
- }
88708
89663
  //#endregion
88709
89664
  //#region src/rendering/hooks/useContent.ts
88710
89665
  /**
@@ -88713,6 +89668,79 @@ function toMediaAssetSidecar$1(mediaAssets) {
88713
89668
  * Use this in client components for dynamic routing where a path
88714
89669
  * could resolve to either a page or content entry.
88715
89670
  */
89671
+ function projectEntrySuccess(input) {
89672
+ const { response, site, siteId, preview } = input;
89673
+ const entryData = response.entry;
89674
+ return {
89675
+ loading: false,
89676
+ error: null,
89677
+ type: "entry",
89678
+ page: null,
89679
+ entry: {
89680
+ id: entryData.id,
89681
+ type: entryData.type,
89682
+ title: entryData.title,
89683
+ slug: entryData.slug,
89684
+ path: entryData.path,
89685
+ status: entryData.status,
89686
+ publishAt: entryData.publishAt,
89687
+ content: preview ? entryData.draftContent ?? entryData.content : entryData.content,
89688
+ metaTitle: preview ? entryData.draftMetaTitle ?? entryData.metaTitle : entryData.metaTitle,
89689
+ metaDescription: preview ? entryData.draftMetaDescription ?? entryData.metaDescription : entryData.metaDescription,
89690
+ createdAt: entryData.createdAt,
89691
+ updatedAt: entryData.updatedAt
89692
+ },
89693
+ theme: site.theme,
89694
+ siteId,
89695
+ resolvedData: null
89696
+ };
89697
+ }
89698
+ async function loadPageSuccess(input) {
89699
+ const { client, response, site, siteId, path, preview } = input;
89700
+ const pageData = response.page;
89701
+ const mediaAssets = collectMediaAssetSidecar(response.mediaAssets);
89702
+ const previewStage = preview ? "preview" : "published";
89703
+ const pageOutline = buildRenderablePageOutline({
89704
+ name: pageData.name,
89705
+ path: pageData.path ?? path,
89706
+ fallbackPath: path,
89707
+ purpose: pageData.purpose,
89708
+ blocks: pageData.blocks,
89709
+ previewStage,
89710
+ customBlocks: resolveSiteCustomBlocks(site)
89711
+ });
89712
+ const resolvedData = await prefetchBlockData(projectRenderablePageOutline(pageOutline), {
89713
+ siteId,
89714
+ pageId: pageData.id,
89715
+ previewStage
89716
+ }, client);
89717
+ return {
89718
+ loading: false,
89719
+ error: null,
89720
+ type: "page",
89721
+ page: pageOutline,
89722
+ runtimeJoins: pageData.runtimeJoins,
89723
+ entry: null,
89724
+ theme: site.theme,
89725
+ siteId,
89726
+ resolvedData,
89727
+ dataContext: { previewStage },
89728
+ supabaseUrl: site.supabaseUrl,
89729
+ ...mediaAssets ? { mediaAssets } : {}
89730
+ };
89731
+ }
89732
+ function toContentError(siteId, error) {
89733
+ return {
89734
+ loading: false,
89735
+ error: error instanceof Error ? error : new Error(String(error)),
89736
+ type: null,
89737
+ page: null,
89738
+ entry: null,
89739
+ theme: null,
89740
+ siteId,
89741
+ resolvedData: null
89742
+ };
89743
+ }
88716
89744
  /**
88717
89745
  * Type guard to check if result is loading
88718
89746
  */
@@ -88760,7 +89788,7 @@ function isEntryContentResult(result) {
88760
89788
  *
88761
89789
  * if (isPageContentResult(content)) {
88762
89790
  * if (!content.theme) return <div>This site needs a theme before it can be displayed.</div>;
88763
- * return <Page page={content.page} theme={content.theme} siteId={content.siteId} resolvedData={content.resolvedData} />;
89791
+ * return <Page page={content.page} theme={content.theme} siteId={content.siteId} resolvedData={content.resolvedData} dataContext={content.dataContext} />;
88764
89792
  * }
88765
89793
  *
88766
89794
  * // Render entry with custom UI
@@ -88816,75 +89844,28 @@ function useContent(params) {
88816
89844
  })]);
88817
89845
  if (cancelled) return;
88818
89846
  if (isEntryResponse(contentResponse)) {
88819
- const entryData = contentResponse.entry;
88820
- setResult({
88821
- loading: false,
88822
- error: null,
88823
- type: "entry",
88824
- page: null,
88825
- entry: {
88826
- id: entryData.id,
88827
- type: entryData.type,
88828
- title: entryData.title,
88829
- slug: entryData.slug,
88830
- path: entryData.path,
88831
- status: entryData.status,
88832
- publishAt: entryData.publishAt,
88833
- content: preview ? entryData.draftContent ?? entryData.content : entryData.content,
88834
- metaTitle: preview ? entryData.draftMetaTitle ?? entryData.metaTitle : entryData.metaTitle,
88835
- metaDescription: preview ? entryData.draftMetaDescription ?? entryData.metaDescription : entryData.metaDescription,
88836
- createdAt: entryData.createdAt,
88837
- updatedAt: entryData.updatedAt
88838
- },
88839
- theme: site.theme,
89847
+ setResult(projectEntrySuccess({
89848
+ response: contentResponse,
89849
+ site,
88840
89850
  siteId,
88841
- resolvedData: null
88842
- });
89851
+ preview
89852
+ }));
88843
89853
  return;
88844
89854
  }
88845
89855
  if ("pageSurface" in contentResponse) throw new Error("This path resolves to a page surface. Use the server loadContent() helper for native page-surface rendering.");
88846
- const { page: pageData } = contentResponse;
88847
- const canonicalPagePath = pageData.path ?? path;
88848
- const mediaAssets = Array.isArray(contentResponse.mediaAssets) && contentResponse.mediaAssets.length > 0 ? toMediaAssetSidecar(contentResponse.mediaAssets) : void 0;
88849
- const pageOutline = buildRenderablePageOutline({
88850
- name: pageData.name,
88851
- path: canonicalPagePath,
88852
- fallbackPath: path,
88853
- purpose: pageData.purpose,
88854
- blocks: pageData.blocks,
88855
- customBlocks: resolveSiteCustomBlocks(site)
88856
- });
88857
- const resolvedData = await prefetchBlockData(projectRenderablePageOutline(pageOutline), {
88858
- siteId,
88859
- pageId: pageData.id,
88860
- previewStage: preview ? "preview" : "published"
88861
- }, client);
88862
- if (cancelled) return;
88863
- setResult({
88864
- loading: false,
88865
- error: null,
88866
- type: "page",
88867
- page: pageOutline,
88868
- runtimeJoins: pageData.runtimeJoins,
88869
- entry: null,
88870
- theme: site.theme,
89856
+ const success = await loadPageSuccess({
89857
+ client,
89858
+ response: contentResponse,
89859
+ site,
88871
89860
  siteId,
88872
- resolvedData,
88873
- supabaseUrl: site.supabaseUrl,
88874
- ...mediaAssets ? { mediaAssets } : {}
89861
+ path,
89862
+ preview
88875
89863
  });
89864
+ if (cancelled) return;
89865
+ setResult(success);
88876
89866
  } catch (error) {
88877
89867
  if (cancelled) return;
88878
- setResult({
88879
- loading: false,
88880
- error: error instanceof Error ? error : new Error(String(error)),
88881
- type: null,
88882
- page: null,
88883
- entry: null,
88884
- theme: null,
88885
- siteId,
88886
- resolvedData: null
88887
- });
89868
+ setResult(toContentError(siteId, error));
88888
89869
  }
88889
89870
  }
88890
89871
  fetchContent();
@@ -88899,9 +89880,6 @@ function useContent(params) {
88899
89880
  ]);
88900
89881
  return result;
88901
89882
  }
88902
- function toMediaAssetSidecar(mediaAssets) {
88903
- return mediaAssets ?? [];
88904
- }
88905
89883
  /**
88906
89884
  * Type guard to check if API response is an entry
88907
89885
  */
@@ -150090,6 +151068,7 @@ var init_form_client = __esmMin((() => {
150090
151068
  init_useFormSubmission();
150091
151069
  init_ThemedButton();
150092
151070
  init_FeedbackMessage();
151071
+ init_form_fields();
150093
151072
  FormNodeClient = ({ render }) => {
150094
151073
  const form = render.display.form;
150095
151074
  const { submit, state } = useFormSubmission();
@@ -150102,107 +151081,7 @@ var init_form_client = __esmMin((() => {
150102
151081
  children: "Missing or unknown form."
150103
151082
  });
150104
151083
  const groups = render.display.groups;
150105
- const renderField = (field) => {
150106
- const inputId = `f_${field.id}`;
150107
- const label = String(field.label ?? field.id);
150108
- const required = Boolean(field.required);
150109
- const type = String(field.type ?? "text");
150110
- if (type === "textarea") return /* @__PURE__ */ jsxs("div", {
150111
- className: "fb-field",
150112
- children: [/* @__PURE__ */ jsx("label", {
150113
- htmlFor: inputId,
150114
- className: "form-label",
150115
- children: label
150116
- }), /* @__PURE__ */ jsx("textarea", {
150117
- id: inputId,
150118
- name: field.id,
150119
- required,
150120
- placeholder: field.placeholder,
150121
- rows: field.rows,
150122
- className: "form-textarea"
150123
- })]
150124
- }, field.id);
150125
- if (type === "select") {
150126
- const options = field.options ?? [];
150127
- const multiple = Boolean(field.multiple);
150128
- return /* @__PURE__ */ jsxs("div", {
150129
- className: "fb-field",
150130
- children: [/* @__PURE__ */ jsx("label", {
150131
- htmlFor: inputId,
150132
- className: "form-label",
150133
- children: label
150134
- }), /* @__PURE__ */ jsxs("select", {
150135
- id: inputId,
150136
- name: field.id,
150137
- multiple,
150138
- required,
150139
- className: "form-select",
150140
- children: [!multiple && /* @__PURE__ */ jsx("option", {
150141
- value: "",
150142
- children: "Select…"
150143
- }), options.map((opt) => /* @__PURE__ */ jsx("option", {
150144
- value: opt.value,
150145
- children: opt.label
150146
- }, opt.value))]
150147
- })]
150148
- }, field.id);
150149
- }
150150
- if (type === "radio") {
150151
- const options = field.options ?? [];
150152
- return /* @__PURE__ */ jsxs("fieldset", {
150153
- className: "fb-fieldset",
150154
- children: [/* @__PURE__ */ jsx("legend", {
150155
- className: "form-label",
150156
- children: label
150157
- }), options.map((opt) => /* @__PURE__ */ jsxs("label", {
150158
- className: "fb-inline form-label",
150159
- children: [/* @__PURE__ */ jsx("input", {
150160
- type: "radio",
150161
- name: field.id,
150162
- value: opt.value,
150163
- required,
150164
- className: "form-radio"
150165
- }), /* @__PURE__ */ jsx("span", { children: opt.label })]
150166
- }, opt.value))]
150167
- }, field.id);
150168
- }
150169
- if (type === "checkbox" || type === "consent") return /* @__PURE__ */ jsxs("label", {
150170
- className: "fb-inline form-label",
150171
- children: [/* @__PURE__ */ jsx("input", {
150172
- type: "checkbox",
150173
- name: field.id,
150174
- required,
150175
- className: "form-checkbox"
150176
- }), /* @__PURE__ */ jsx("span", { children: label })]
150177
- }, field.id);
150178
- const inputType = type === "email" || type === "url" || type === "tel" || type === "number" ? type : "text";
150179
- const extra = {};
150180
- if (inputType === "text" || inputType === "email" || inputType === "url" || inputType === "tel") {
150181
- if (typeof field.minLength === "number") extra.minLength = field.minLength;
150182
- if (typeof field.maxLength === "number") extra.maxLength = field.maxLength;
150183
- if (typeof field.pattern === "string" && field.pattern) extra.pattern = field.pattern;
150184
- }
150185
- if (inputType === "number") {
150186
- if (typeof field.min === "number") extra.min = field.min;
150187
- if (typeof field.max === "number") extra.max = field.max;
150188
- }
150189
- return /* @__PURE__ */ jsxs("div", {
150190
- className: "fb-field",
150191
- children: [/* @__PURE__ */ jsx("label", {
150192
- htmlFor: inputId,
150193
- className: "form-label",
150194
- children: label
150195
- }), /* @__PURE__ */ jsx("input", {
150196
- id: inputId,
150197
- name: field.id,
150198
- type: inputType,
150199
- required,
150200
- placeholder: field.placeholder,
150201
- ...extra,
150202
- className: "form-input"
150203
- })]
150204
- }, field.id);
150205
- };
151084
+ const renderField = (field) => /* @__PURE__ */ jsx(FormFieldControl, { field }, field.id);
150206
151085
  const handleSubmit = async (e) => {
150207
151086
  e.preventDefault();
150208
151087
  const formData = new FormData(e.currentTarget);
@@ -153591,28 +154470,6 @@ var init_DiscountCodeDisclosure = __esmMin((() => {
153591
154470
  };
153592
154471
  }));
153593
154472
  //#endregion
153594
- //#region ../blocks/src/system/runtime/shared/components/FieldValidationMessage.tsx
153595
- function getFieldValidationControlProps({ message, messageId, describedBy }) {
153596
- const hasMessage = Boolean(message);
153597
- const ariaDescribedBy = [describedBy, hasMessage ? messageId : void 0].filter((part) => typeof part === "string" && part.length > 0).join(" ");
153598
- return {
153599
- "aria-invalid": hasMessage ? "true" : void 0,
153600
- "aria-describedby": ariaDescribedBy || void 0
153601
- };
153602
- }
153603
- function FieldValidationMessage({ id, children, className, live = "assertive" }) {
153604
- return /* @__PURE__ */ jsx("p", {
153605
- id,
153606
- className,
153607
- "data-field-validation-message": true,
153608
- "data-field-validation-tone": "error",
153609
- role: "alert",
153610
- "aria-live": live === "off" ? void 0 : live,
153611
- children
153612
- });
153613
- }
153614
- var init_FieldValidationMessage = __esmMin((() => {}));
153615
- //#endregion
153616
154473
  //#region ../blocks/src/system/runtime/shared/components/BookingConsentAgreement.tsx
153617
154474
  function BookingConsentAgreement({ agreement, showTitle = true, title, titleId }) {
153618
154475
  return /* @__PURE__ */ jsxs(Fragment, { children: [showTitle ? /* @__PURE__ */ jsxs("div", {
@@ -154227,7 +155084,7 @@ function DefaultFieldInput({ describedBy, error, errorId, field, onBlur, onChang
154227
155084
  case "radio": return /* @__PURE__ */ jsx("div", {
154228
155085
  className: "rb-space-y-2",
154229
155086
  children: field.field.options?.map((option) => /* @__PURE__ */ jsxs("label", {
154230
- className: "rb-flex rb-items-center rb-gap-2 rb-cursor-pointer",
155087
+ className: "form-check",
154231
155088
  children: [/* @__PURE__ */ jsx("input", {
154232
155089
  type: "radio",
154233
155090
  name: field.id,
@@ -154239,7 +155096,7 @@ function DefaultFieldInput({ describedBy, error, errorId, field, onBlur, onChang
154239
155096
  ...validationProps,
154240
155097
  className: "form-radio"
154241
155098
  }), /* @__PURE__ */ jsx("span", {
154242
- className: "rb-caption",
155099
+ className: "form-check-label",
154243
155100
  children: option.label
154244
155101
  })]
154245
155102
  }, option.value))
@@ -154249,47 +155106,20 @@ function DefaultFieldInput({ describedBy, error, errorId, field, onBlur, onChang
154249
155106
  const checkedValues = toStringArray(value);
154250
155107
  return /* @__PURE__ */ jsx("div", {
154251
155108
  className: "rb-space-y-2",
154252
- children: field.field.options.map((option) => /* @__PURE__ */ jsxs("label", {
154253
- className: "rb-flex rb-items-center rb-gap-2 rb-cursor-pointer",
154254
- children: [/* @__PURE__ */ jsx("input", {
154255
- type: "checkbox",
154256
- name: field.id,
154257
- value: option.value,
154258
- checked: checkedValues.includes(option.value),
154259
- onChange: (event) => {
154260
- onChange(event.target.checked ? [...checkedValues, option.value] : checkedValues.filter((item) => item !== option.value));
154261
- },
154262
- onBlur,
154263
- ...validationProps,
154264
- className: "form-checkbox"
154265
- }), /* @__PURE__ */ jsx("span", {
154266
- className: "rb-caption",
154267
- children: option.label
154268
- })]
155109
+ children: field.field.options.map((option) => /* @__PURE__ */ jsx(CheckboxChoice, {
155110
+ name: field.id,
155111
+ value: option.value,
155112
+ checked: checkedValues.includes(option.value),
155113
+ onChange: (event) => {
155114
+ onChange(event.target.checked ? [...checkedValues, option.value] : checkedValues.filter((item) => item !== option.value));
155115
+ },
155116
+ onBlur,
155117
+ ...validationProps,
155118
+ label: option.label
154269
155119
  }, option.value))
154270
155120
  });
154271
155121
  }
154272
- return /* @__PURE__ */ jsxs("label", {
154273
- className: "rb-flex rb-items-center rb-gap-2 rb-cursor-pointer",
154274
- children: [/* @__PURE__ */ jsx("input", {
154275
- type: "checkbox",
154276
- id: field.inputId,
154277
- name: field.id,
154278
- checked: Boolean(value),
154279
- onChange: (event) => onChange(event.target.checked),
154280
- onBlur,
154281
- required: field.required,
154282
- ...validationProps,
154283
- className: "form-checkbox"
154284
- }), /* @__PURE__ */ jsx("span", {
154285
- className: "rb-caption",
154286
- children: field.field.placeholder || field.label
154287
- })]
154288
- });
154289
- case "booking_requirement_consent": return /* @__PURE__ */ jsxs("label", {
154290
- className: "rb-flex rb-items-start rb-gap-2 rb-cursor-pointer",
154291
- children: [/* @__PURE__ */ jsx("input", {
154292
- type: "checkbox",
155122
+ return /* @__PURE__ */ jsx(CheckboxChoice, {
154293
155123
  id: field.inputId,
154294
155124
  name: field.id,
154295
155125
  checked: Boolean(value),
@@ -154297,11 +155127,18 @@ function DefaultFieldInput({ describedBy, error, errorId, field, onBlur, onChang
154297
155127
  onBlur,
154298
155128
  required: field.required,
154299
155129
  ...validationProps,
154300
- className: "form-checkbox rb-mt-0.5"
154301
- }), /* @__PURE__ */ jsx("span", {
154302
- className: "rb-caption",
154303
- children: field.field.checkboxLabel
154304
- })]
155130
+ label: field.field.placeholder || field.label
155131
+ });
155132
+ case "booking_requirement_consent": return /* @__PURE__ */ jsx(CheckboxChoice, {
155133
+ id: field.inputId,
155134
+ name: field.id,
155135
+ checked: Boolean(value),
155136
+ onChange: (event) => onChange(event.target.checked),
155137
+ onBlur,
155138
+ required: field.required,
155139
+ ...validationProps,
155140
+ label: field.field.checkboxLabel,
155141
+ presentation: "tile"
154305
155142
  });
154306
155143
  case "number": return /* @__PURE__ */ jsx("input", {
154307
155144
  ...commonProps,
@@ -154430,6 +155267,7 @@ var init_booking_form_default_ui = __esmMin((() => {
154430
155267
  init_DiscountCodeDisclosure();
154431
155268
  init_FieldValidationMessage();
154432
155269
  init_BookingConsentAgreement();
155270
+ init_CheckboxChoice();
154433
155271
  init_booking_form_service_choices();
154434
155272
  }));
154435
155273
  //#endregion
@@ -154771,6 +155609,7 @@ var init_SelectableOptionCard = __esmMin((() => {}));
154771
155609
  //#endregion
154772
155610
  //#region ../blocks/src/system/runtime/shared/components/index.ts
154773
155611
  var init_components = __esmMin((() => {
155612
+ init_CheckboxChoice();
154774
155613
  init_CheckIcon$1();
154775
155614
  init_ClockIcon();
154776
155615
  init_CrossIcon();
@@ -159838,26 +160677,24 @@ function EventConsentField({ consent, error, formData, idBase, onChange }) {
159838
160677
  title: consent.title,
159839
160678
  titleId: `${idBase}-consent-title`
159840
160679
  }),
159841
- /* @__PURE__ */ jsxs("label", {
159842
- className: "er-label rb-flex rb-items-start rb-gap-2 rb-cursor-pointer",
159843
- children: [
159844
- /* @__PURE__ */ jsx("input", {
159845
- "aria-describedby": error ? errorId : void 0,
159846
- className: "form-checkbox rb-mt-0.5",
159847
- checked: formData.consentAccepted === true,
159848
- onChange: (event) => onChange({
159849
- ...formData,
159850
- consentAccepted: event.target.checked
159851
- }),
159852
- type: "checkbox"
159853
- }),
160680
+ /* @__PURE__ */ jsx(CheckboxChoice, {
160681
+ "aria-describedby": error ? errorId : void 0,
160682
+ "aria-invalid": error ? true : void 0,
160683
+ checked: formData.consentAccepted === true,
160684
+ onChange: (event) => onChange({
160685
+ ...formData,
160686
+ consentAccepted: event.target.checked
160687
+ }),
160688
+ label: /* @__PURE__ */ jsxs(Fragment, { children: [
159854
160689
  consent.checkboxLabel,
159855
160690
  " ",
159856
160691
  /* @__PURE__ */ jsx("span", {
159857
160692
  className: "er-required",
159858
160693
  children: "*"
159859
160694
  })
159860
- ]
160695
+ ] }),
160696
+ presentation: "tile",
160697
+ className: "er-consent-check"
159861
160698
  }),
159862
160699
  error ? /* @__PURE__ */ jsx(FieldValidationMessage, {
159863
160700
  id: errorId,
@@ -159893,6 +160730,7 @@ var init_AttendeeDetailsStep = __esmMin((() => {
159893
160730
  init_LoggedInAsUser();
159894
160731
  init_FieldValidationMessage();
159895
160732
  init_BookingConsentAgreement();
160733
+ init_CheckboxChoice();
159896
160734
  AttendeeDetailsStep = ({ formData, onChange, errors, emailLocked = false, onLogout, ticketsCount = 1, requireGuestDetails = false, guests = [], onGuestsChange, guestErrors = {}, guestSectionShake = false, onGuestShakeEnd, consent }) => {
159897
160735
  const idBase = useId();
159898
160736
  const nameId = `${idBase}-name`;
@@ -165968,6 +166806,10 @@ function resolveNewsletterSubmitTarget(input) {
165968
166806
  tag: "unavailable",
165969
166807
  reason: "preview_only_source"
165970
166808
  };
166809
+ case "unpublished-preview": return {
166810
+ tag: "unavailable",
166811
+ reason: "preview_only_source"
166812
+ };
165971
166813
  default: return assertNever$20(input);
165972
166814
  }
165973
166815
  }
@@ -165990,6 +166832,7 @@ var init_newsletter_form_submission = __esmMin((() => {
165990
166832
  //#endregion
165991
166833
  //#region ../blocks/src/system/runtime/nodes/newsletter-form.client.tsx
165992
166834
  function NewsletterFormClient({ render }) {
166835
+ const submissionMessage = newsletterBlockSubmissionMessage(render.hydration.target);
165993
166836
  const api = useBlockApi();
165994
166837
  const [submissionState, dispatchSubmission] = useReducer(newsletterFormSubmissionReducer, initialNewsletterFormSubmissionState);
165995
166838
  const [altchaSolution, setAltchaSolution] = useState(null);
@@ -165999,7 +166842,6 @@ function NewsletterFormClient({ render }) {
165999
166842
  if (succeeded) successRef.current?.focus();
166000
166843
  }, [succeeded]);
166001
166844
  const showSpamProtection = render.hydration.spamProtectionEnabled ?? isSpamProtectionEnabled();
166002
- const fields = render.display.fields;
166003
166845
  const handleSubmit = async (e) => {
166004
166846
  e.preventDefault();
166005
166847
  const formData = new FormData(e.currentTarget);
@@ -166031,7 +166873,7 @@ function NewsletterFormClient({ render }) {
166031
166873
  reportNewsletterSignupRefusal(submitTarget.reason, { target: render.hydration.target });
166032
166874
  dispatchSubmission({
166033
166875
  type: "failed",
166034
- error: newsletterFormError(SIGNUPS_PAUSED_MESSAGE)
166876
+ error: newsletterFormError(NEWSLETTER_SIGNUPS_PAUSED_MESSAGE)
166035
166877
  });
166036
166878
  return;
166037
166879
  }
@@ -166039,7 +166881,7 @@ function NewsletterFormClient({ render }) {
166039
166881
  reportNewsletterSignupRefusal("setup_not_configured");
166040
166882
  dispatchSubmission({
166041
166883
  type: "failed",
166042
- error: newsletterFormError(SIGNUPS_PAUSED_MESSAGE)
166884
+ error: newsletterFormError(NEWSLETTER_SIGNUPS_PAUSED_MESSAGE)
166043
166885
  });
166044
166886
  return;
166045
166887
  }
@@ -166047,7 +166889,7 @@ function NewsletterFormClient({ render }) {
166047
166889
  reportNewsletterSignupRefusal("destination_unavailable", { setupRevision: render.hydration.setupRevision });
166048
166890
  dispatchSubmission({
166049
166891
  type: "failed",
166050
- error: newsletterFormError(SIGNUPS_PAUSED_MESSAGE)
166892
+ error: newsletterFormError(NEWSLETTER_SIGNUPS_PAUSED_MESSAGE)
166051
166893
  });
166052
166894
  return;
166053
166895
  }
@@ -166122,43 +166964,14 @@ function NewsletterFormClient({ render }) {
166122
166964
  autoComplete: "off",
166123
166965
  "aria-hidden": "true"
166124
166966
  }),
166125
- /* @__PURE__ */ jsxs("div", {
166126
- className: "newsletter-form-fields",
166127
- children: [
166128
- fields.map((field) => /* @__PURE__ */ jsx(NewsletterField, {
166129
- field,
166130
- submitting,
166131
- error: getNewsletterSubmissionFieldError(submissionState, field.id)
166132
- }, field.id)),
166133
- render.hydration.choicePresentation === "visitor_choice" ? /* @__PURE__ */ jsx(NewsletterTopicChoices, {
166134
- choices: render.display.choices,
166135
- submitting,
166136
- error: getNewsletterSubmissionFieldError(submissionState, TOPIC_CHOICE_FIELD_ID)
166137
- }) : null,
166138
- showSpamProtection && /* @__PURE__ */ jsx("div", {
166139
- className: "newsletter-altcha",
166140
- children: /* @__PURE__ */ jsx(AltchaWidget, {
166141
- challengeUrl: getChallengeUrl(),
166142
- onSolutionChange: setAltchaSolution
166143
- })
166144
- }),
166145
- formError && /* @__PURE__ */ jsx(FeedbackMessage, {
166146
- tone: "error",
166147
- className: "fb-error",
166148
- role: "alert",
166149
- children: formError
166150
- }),
166151
- /* @__PURE__ */ jsx("div", {
166152
- className: "newsletter-submit",
166153
- children: /* @__PURE__ */ jsx(ThemedButton, {
166154
- type: "submit",
166155
- variant: render.display.buttonVariant,
166156
- size: "md",
166157
- disabled: submitting,
166158
- label: submitting ? "Subscribing..." : render.display.buttonLabel
166159
- })
166160
- })
166161
- ]
166967
+ /* @__PURE__ */ jsx(NewsletterFormFields, {
166968
+ render,
166969
+ submissionState,
166970
+ submitting,
166971
+ submissionMessage,
166972
+ formError,
166973
+ showSpamProtection,
166974
+ onAltchaSolution: setAltchaSolution
166162
166975
  }),
166163
166976
  render.display.privacyNote && /* @__PURE__ */ jsx("p", {
166164
166977
  className: "newsletter-privacy-note",
@@ -166168,67 +166981,52 @@ function NewsletterFormClient({ render }) {
166168
166981
  })
166169
166982
  });
166170
166983
  }
166171
- function NewsletterField({ field, submitting, error }) {
166172
- const inputId = `newsletter_${field.id}`;
166173
- const errorId = `${inputId}-error`;
166984
+ function NewsletterFormFields({ render, submissionState, submitting, submissionMessage, formError, showSpamProtection, onAltchaSolution }) {
166985
+ const { email: emailField, extra: extraFields } = partitionNewsletterFields(render.display.fields);
166986
+ const fieldError = (id) => getNewsletterSubmissionFieldError(submissionState, id);
166174
166987
  return /* @__PURE__ */ jsxs("div", {
166175
- className: "fb-field newsletter-field",
166988
+ className: "newsletter-form-fields",
166176
166989
  children: [
166177
- /* @__PURE__ */ jsxs("label", {
166178
- htmlFor: inputId,
166179
- className: "form-label",
166180
- children: [field.label, field.required && /* @__PURE__ */ jsx("span", {
166181
- className: "newsletter-required",
166182
- "aria-hidden": "true",
166183
- children: "*"
166184
- })]
166185
- }),
166186
- /* @__PURE__ */ jsx("input", {
166187
- id: inputId,
166188
- name: field.id,
166189
- type: field.type,
166190
- required: field.required,
166191
- placeholder: field.placeholder,
166192
- className: "form-input",
166193
- autoComplete: field.type === "email" ? "email" : void 0,
166990
+ render.hydration.choicePresentation === "visitor_choice" ? /* @__PURE__ */ jsx(NewsletterTopicChips, {
166991
+ choices: render.display.choices,
166194
166992
  disabled: submitting,
166195
- ...getFieldValidationControlProps({
166196
- message: error,
166197
- messageId: errorId
166993
+ error: fieldError(TOPIC_CHOICE_FIELD_ID)
166994
+ }) : null,
166995
+ extraFields.length > 0 ? /* @__PURE__ */ jsx("div", {
166996
+ className: "newsletter-extra-fields",
166997
+ children: extraFields.map((field) => /* @__PURE__ */ jsx(NewsletterExtraField, {
166998
+ field,
166999
+ disabled: submitting,
167000
+ error: fieldError(field.id)
167001
+ }, field.id))
167002
+ }) : null,
167003
+ showSpamProtection && /* @__PURE__ */ jsx("div", {
167004
+ className: "newsletter-altcha",
167005
+ children: /* @__PURE__ */ jsx(AltchaWidget, {
167006
+ challengeUrl: getChallengeUrl(),
167007
+ onSolutionChange: onAltchaSolution
166198
167008
  })
166199
167009
  }),
166200
- error && /* @__PURE__ */ jsx(FieldValidationMessage, {
166201
- id: errorId,
167010
+ formError && /* @__PURE__ */ jsx(FeedbackMessage, {
167011
+ tone: "error",
166202
167012
  className: "fb-error",
166203
- children: error
167013
+ role: "alert",
167014
+ children: formError
167015
+ }),
167016
+ /* @__PURE__ */ jsx(NewsletterSubmitRow, {
167017
+ emailField,
167018
+ buttonVariant: render.display.buttonVariant,
167019
+ buttonLabel: submitting ? "Subscribing..." : render.display.buttonLabel,
167020
+ disabled: submitting || submissionMessage !== null,
167021
+ error: emailField ? fieldError(emailField.id) : null
167022
+ }),
167023
+ submissionMessage && /* @__PURE__ */ jsx("p", {
167024
+ role: "status",
167025
+ children: submissionMessage
166204
167026
  })
166205
167027
  ]
166206
167028
  });
166207
167029
  }
166208
- function NewsletterTopicChoices({ choices, submitting, error }) {
166209
- const errorId = `newsletter_${TOPIC_CHOICE_FIELD_ID}-error`;
166210
- return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("fieldset", {
166211
- className: "fb-fieldset newsletter-topics",
166212
- "aria-describedby": error ? errorId : void 0,
166213
- children: [/* @__PURE__ */ jsx("legend", {
166214
- className: "form-label",
166215
- children: "What would you like to hear about?"
166216
- }), choices.map((choice) => /* @__PURE__ */ jsxs("label", {
166217
- className: "fb-inline form-label newsletter-topic-choice",
166218
- children: [/* @__PURE__ */ jsx("input", {
166219
- type: "checkbox",
166220
- name: TOPIC_CHOICE_FIELD_ID,
166221
- value: choice.id,
166222
- className: "form-checkbox",
166223
- disabled: submitting
166224
- }), /* @__PURE__ */ jsx("span", { children: choice.label })]
166225
- }, choice.id))]
166226
- }), error && /* @__PURE__ */ jsx(FieldValidationMessage, {
166227
- id: errorId,
166228
- className: "fb-error",
166229
- children: error
166230
- })] });
166231
- }
166232
167030
  function UnavailableNewsletterForm({ className }) {
166233
167031
  return /* @__PURE__ */ jsx("div", {
166234
167032
  className: clsx("newsletter-form", className ?? void 0),
@@ -166236,7 +167034,7 @@ function UnavailableNewsletterForm({ className }) {
166236
167034
  tone: "error",
166237
167035
  className: "fb-error",
166238
167036
  role: "status",
166239
- children: SIGNUPS_PAUSED_MESSAGE
167037
+ children: NEWSLETTER_SIGNUPS_PAUSED_MESSAGE
166240
167038
  })
166241
167039
  });
166242
167040
  }
@@ -166256,7 +167054,7 @@ function transportFailureMessage(err) {
166256
167054
  function visitorSelectionError(selection) {
166257
167055
  switch (selection.tag) {
166258
167056
  case "nothing_chosen": return newsletterFieldError(TOPIC_CHOICE_FIELD_ID, "Choose at least one email topic.");
166259
- case "unusable": return newsletterFormError(SIGNUPS_PAUSED_MESSAGE);
167057
+ case "unusable": return newsletterFormError(NEWSLETTER_SIGNUPS_PAUSED_MESSAGE);
166260
167058
  case "not_offered":
166261
167059
  case "chosen": return null;
166262
167060
  }
@@ -166288,7 +167086,7 @@ function publicSignupError(outcome) {
166288
167086
  case "unavailable": switch (outcome.reason) {
166289
167087
  case "configuration_unavailable":
166290
167088
  case "authentication_failed":
166291
- case "target_unavailable": return SIGNUPS_PAUSED_MESSAGE;
167089
+ case "target_unavailable": return NEWSLETTER_SIGNUPS_PAUSED_MESSAGE;
166292
167090
  case "stale_configuration": return "This signup form has changed. Refresh the page, then try again.";
166293
167091
  case "rate_limited": return TOO_MANY_ATTEMPTS_MESSAGE;
166294
167092
  case "temporarily_unavailable": return RETRY_SHORTLY_MESSAGE;
@@ -166296,20 +167094,18 @@ function publicSignupError(outcome) {
166296
167094
  case "uncertain": return "We could not confirm whether your signup completed. Please wait a moment, then try again.";
166297
167095
  }
166298
167096
  }
166299
- var TOPIC_CHOICE_FIELD_ID, SIGNUPS_PAUSED_MESSAGE, RETRY_SHORTLY_MESSAGE, TOO_MANY_ATTEMPTS_MESSAGE;
167097
+ var RETRY_SHORTLY_MESSAGE, TOO_MANY_ATTEMPTS_MESSAGE;
166300
167098
  var init_newsletter_form_client = __esmMin((() => {
166301
167099
  init_clsx();
166302
167100
  init_client();
166303
167101
  init_src();
166304
167102
  init_api$1();
166305
167103
  init_src$2();
166306
- init_ThemedButton();
166307
167104
  init_FeedbackMessage();
166308
- init_FieldValidationMessage();
167105
+ init_newsletter_form_parts();
166309
167106
  init_newsletter_form_client_state();
166310
167107
  init_newsletter_form_submission();
166311
- TOPIC_CHOICE_FIELD_ID = "mailingListChoice";
166312
- SIGNUPS_PAUSED_MESSAGE = "We can’t accept signups right now. Please try again later.";
167108
+ init_newsletter_form_interactive();
166313
167109
  RETRY_SHORTLY_MESSAGE = "We couldn’t confirm your signup. Please try again in a little while.";
166314
167110
  TOO_MANY_ATTEMPTS_MESSAGE = "There have been too many signup attempts. Please wait a moment and try again.";
166315
167111
  }));
@@ -166672,7 +167468,7 @@ function toBlocksCommonProps(props) {
166672
167468
  return {
166673
167469
  page: props.page,
166674
167470
  runtimeJoins: props.runtimeJoins,
166675
- dataContext: props.dataContext ? toBlocksPageRendererDataContext(props.dataContext) : void 0,
167471
+ dataContext: toBlocksPageRendererDataContext(props.dataContext),
166676
167472
  routeMap: props.routeMap,
166677
167473
  wrapBlock: props.wrapBlock,
166678
167474
  registry: props.registry,
@@ -166761,14 +167557,14 @@ function resolveSdkBookingTimeZone(timeZone) {
166761
167557
  }
166762
167558
  function buildPageRouteRenderContext(dataContext) {
166763
167559
  return {
166764
- pathname: dataContext?.pathname,
166765
- occurrenceContext: dataContext?.occurrenceContext ?? null,
166766
- entrySubrouteContext: dataContext?.entrySubrouteContext ?? null,
166767
- contentEntry: dataContext?.contentEntry ?? null,
166768
- pageSurface: dataContext?.pageSurface ?? null,
166769
- subject: dataContext?.subject ?? null,
166770
- editableRouteMetadataFieldIds: dataContext?.editableRouteMetadataFieldIds ?? null,
166771
- previewStage: dataContext?.previewStage
167560
+ pathname: dataContext.pathname,
167561
+ occurrenceContext: dataContext.occurrenceContext ?? null,
167562
+ entrySubrouteContext: dataContext.entrySubrouteContext ?? null,
167563
+ contentEntry: dataContext.contentEntry ?? null,
167564
+ pageSurface: dataContext.pageSurface ?? null,
167565
+ subject: dataContext.subject ?? null,
167566
+ editableRouteMetadataFieldIds: dataContext.editableRouteMetadataFieldIds ?? null,
167567
+ previewStage: dataContext.previewStage
166772
167568
  };
166773
167569
  }
166774
167570
  function PageContent(props) {
@@ -166782,10 +167578,10 @@ function PageContent(props) {
166782
167578
  apiBaseUrl,
166783
167579
  portalToken,
166784
167580
  previewToken,
166785
- readAuthority: readAuthority ?? dataContext?.readAuthority,
167581
+ readAuthority: readAuthority ?? dataContext.readAuthority,
166786
167582
  resolvedData,
166787
167583
  bookingOfferingPresets: bookingOfferingPresets ?? [],
166788
- mailingList: mailingList ?? dataContext?.mailingList,
167584
+ mailingList: mailingList ?? dataContext.mailingList,
166789
167585
  bookingTimeZone: resolveSdkBookingTimeZone(bookingTimeZone),
166790
167586
  routes: routeMap,
166791
167587
  pagesByIdentifier,
@@ -166986,7 +167782,7 @@ var SimpleCache = class {
166986
167782
  * 1. This constant
166987
167783
  * 2. The "version" field in package.json
166988
167784
  */
166989
- const SDK_VERSION = "0.145.0";
167785
+ const SDK_VERSION = "0.146.0";
166990
167786
  //#endregion
166991
167787
  //#region src/client/error.ts
166992
167788
  let _Symbol$for;