@riverbankcms/sdk 0.144.0 → 0.145.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 (162) hide show
  1. package/dist/{PreviewEditorSidebar-CQZNnFiM.mjs → PreviewEditorSidebar-O-V6Pl5a.mjs} +4 -4
  2. package/dist/{PreviewEditorUI-DCNxnmI0.mjs → PreviewEditorUI-1UlX_9cw.mjs} +3 -3
  3. package/dist/{PreviewQueryProvider-BCYICImX.mjs → PreviewQueryProvider-BxGwdOCV.mjs} +1 -1
  4. package/dist/{SdkPreviewModeRuntime-BJolUbr1.mjs → SdkPreviewModeRuntime-DYbA_4iv.mjs} +419 -348
  5. package/dist/{SiteChromeCustomizeContext-CKgEpoxi.mjs → SiteChromeCustomizeContext-CNTKQ9nx.mjs} +2081 -1313
  6. package/dist/_dts/ai/src/contracts/proposals.d.ts +4719 -66
  7. package/dist/_dts/ai/src/contracts/siteStyleProposalSchemas.d.ts +429 -6
  8. package/dist/_dts/api/src/appointmentEndpointDefinitions.d.ts +49 -0
  9. package/dist/_dts/api/src/appointmentServiceCategoryEndpoints.d.ts +75 -0
  10. package/dist/_dts/api/src/appointmentServiceContracts.d.ts +80 -0
  11. package/dist/_dts/api/src/appointmentSetup.d.ts +8 -1
  12. package/dist/_dts/api/src/bookingManagementEndpoints.d.ts +2 -12
  13. package/dist/_dts/api/src/communications.d.ts +14 -22
  14. package/dist/_dts/api/src/contentRuntime.d.ts +2 -0
  15. package/dist/_dts/api/src/endpoints.d.ts +105 -58
  16. package/dist/_dts/api/src/indexExtendedTypes.d.ts +1 -1
  17. package/dist/_dts/api/src/launchReadiness.d.ts +2 -0
  18. package/dist/_dts/api/src/newsletterEndpointDefinitions.d.ts +0 -23
  19. package/dist/_dts/api/src/onboarding/confirmationResend.d.ts +3 -0
  20. package/dist/_dts/api/src/publicBookingService.d.ts +35 -1
  21. package/dist/_dts/api/src/publicExperience/newsletterEndpoints.d.ts +13 -0
  22. package/dist/_dts/api/src/publicNewsletterEndpointDefinitions.d.ts +58 -0
  23. package/dist/_dts/api/src/schemas/admin-observability-logs.d.ts +3 -3
  24. package/dist/_dts/api/src/siteManagementEndpoints.d.ts +2 -6
  25. package/dist/_dts/api/src/types.d.ts +2 -1
  26. package/dist/_dts/blocks/src/PageRenderer.d.ts +4 -4
  27. package/dist/_dts/blocks/src/bindings/index.d.ts +2 -2
  28. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +24 -0
  29. package/dist/_dts/blocks/src/index.d.ts +1 -1
  30. package/dist/_dts/blocks/src/pageRenderJoins.d.ts +68 -0
  31. package/dist/_dts/blocks/src/pageRenderPlan.d.ts +8 -27
  32. package/dist/_dts/blocks/src/pageRenderPreparation.d.ts +7 -4
  33. package/dist/_dts/blocks/src/pageRendererBoundaries.d.ts +40 -23
  34. package/dist/_dts/blocks/src/server.d.ts +1 -1
  35. package/dist/_dts/blocks/src/system/blocks/appointment-services.d.ts +2 -0
  36. package/dist/_dts/blocks/src/system/blocks/events/eventSelectionFields.d.ts +2 -2
  37. package/dist/_dts/blocks/src/system/blocks/events/shared/calendarWindow.d.ts +1 -1
  38. package/dist/_dts/blocks/src/system/blocks/location-map.d.ts +2 -2
  39. package/dist/_dts/blocks/src/system/blocks/media-text.d.ts +47 -47
  40. package/dist/_dts/blocks/src/system/manifest/schema.d.ts +29 -3
  41. package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessBookingFlow.d.ts +8 -1
  42. package/dist/_dts/blocks/src/system/runtime/nodes/appointment-services.d.ts +22 -2
  43. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.headless.state.d.ts +3 -1
  44. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.interactive.d.ts +57 -2
  45. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.service-categories.d.ts +29 -0
  46. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.service-choices.d.ts +13 -0
  47. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.state.d.ts +3 -3
  48. package/dist/_dts/blocks/src/system/runtime/nodes/booking-runtime-sources.d.ts +13 -1
  49. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/eventSourceRecovery.d.ts +1 -1
  50. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCollectionContract.d.ts +3 -3
  51. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.submission.d.ts +20 -1
  52. package/dist/_dts/content-editor/src/ui/editorSnapshot.d.ts +2 -0
  53. package/dist/_dts/content-model/src/content-types/schema.d.ts +1 -1
  54. package/dist/_dts/core/src/appointment-service-categories.d.ts +108 -0
  55. package/dist/_dts/core/src/editor-state.d.ts +6 -0
  56. package/dist/_dts/core/src/index.d.ts +1 -0
  57. package/dist/_dts/core/src/public-profile.d.ts +9 -0
  58. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +663 -241
  59. package/dist/_dts/editor-blocks/src/block-editor/types.d.ts +6 -0
  60. package/dist/_dts/editor-blocks/src/widgets/site-option-picker/loaders.d.ts +16 -1
  61. package/dist/_dts/editor-blocks/src/widgets/site-option-picker/types.d.ts +13 -0
  62. package/dist/_dts/editor-blocks/src/widgets/site-option-picker/utils.d.ts +29 -0
  63. package/dist/_dts/preview-next/src/client/blocks/BoundaryControl.d.ts +7 -2
  64. package/dist/_dts/preview-next/src/client/blocks/composer/mergeDrafts.d.ts +1 -1
  65. package/dist/_dts/preview-next/src/client/blocks/composer/types.d.ts +1 -0
  66. package/dist/_dts/preview-next/src/client/blocks/previewProjection/applyPreviewProjections.d.ts +1 -3
  67. package/dist/_dts/preview-next/src/client/blocks/previewProjection/runtimeContentDecoration.d.ts +2 -2
  68. package/dist/_dts/preview-next/src/client/blocks/previewProjection/types.d.ts +2 -2
  69. package/dist/_dts/preview-next/src/client/preview/PreviewEntryControllerProvider.d.ts +1 -0
  70. package/dist/_dts/sdk/src/client/runtimeCacheKeys.d.ts +8 -0
  71. package/dist/_dts/sdk/src/client/types.d.ts +1 -1
  72. package/dist/_dts/sdk/src/contracts/index.d.ts +1 -1
  73. package/dist/_dts/sdk/src/contracts/page.d.ts +7 -2
  74. package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +5 -0
  75. package/dist/_dts/sdk/src/manifest/passes/pass1-fields.d.ts +2 -2
  76. package/dist/_dts/sdk/src/public-api/contracts.d.ts +6 -8
  77. package/dist/_dts/sdk/src/rendering/blocks-page-renderer.d.ts +2 -2
  78. package/dist/_dts/sdk/src/rendering/components/pageShared.d.ts +2 -2
  79. package/dist/_dts/sdk/src/rendering/helpers/loadContent.d.ts +1 -1
  80. package/dist/_dts/sdk/src/rendering/hooks/useContent.d.ts +1 -1
  81. package/dist/_dts/sdk/src/version.d.ts +1 -1
  82. package/dist/_dts/surfaces/src/index.d.ts +1 -0
  83. package/dist/_dts/theme-core/src/layout/boundaryCss.d.ts +3 -0
  84. package/dist/_dts/theme-core/src/site-styles/compositionBudget.d.ts +8 -0
  85. package/dist/_dts/theme-core/src/site-styles/contentTemplateRuntimeCompiler.d.ts +3 -2
  86. package/dist/_dts/theme-core/src/site-styles/designState.d.ts +1 -3
  87. package/dist/_dts/theme-core/src/site-styles/generatedDesignPipeline.d.ts +3 -0
  88. package/dist/_dts/theme-core/src/site-styles/index.d.ts +3 -0
  89. package/dist/_dts/theme-core/src/site-styles/joinTreatment.d.ts +132 -0
  90. package/dist/_dts/theme-core/src/site-styles/pageDesignEditorBoundaries.d.ts +31 -0
  91. package/dist/_dts/theme-core/src/site-styles/pageDesignEditorModel.d.ts +33 -29
  92. package/dist/_dts/theme-core/src/site-styles/pageDesignIntent.d.ts +4 -4
  93. package/dist/_dts/theme-core/src/site-styles/pageFlowPresets.d.ts +36 -0
  94. package/dist/_dts/theme-core/src/site-styles/previewCompiler.d.ts +4 -10
  95. package/dist/_dts/theme-core/src/site-styles/rawStyleFields.d.ts +17 -4
  96. package/dist/_dts/theme-core/src/site-styles/runtimeCompiler.d.ts +20 -74
  97. package/dist/_dts/theme-core/src/site-styles/sectionBoundaryComposition.d.ts +95 -0
  98. package/dist/_dts/theme-core/src/site-styles/sectionTransitions.d.ts +80 -518
  99. package/dist/_dts/theme-core/src/site-styles/siteStyleBlockPolicies.d.ts +9 -4
  100. package/dist/_dts/theme-core/src/site-styles/transitionCatalogue.d.ts +320 -0
  101. package/dist/_dts/theme-core/src/site-styles/types.d.ts +3 -18
  102. package/dist/client/{BookingConsentAgreement-DoAILrkN.mjs → BookingConsentAgreement-DlVOmpW4.mjs} +2 -2
  103. package/dist/client/{DiscountCodeDisclosure-X528hUTf.mjs → DiscountCodeDisclosure-T9q623PQ.mjs} +1 -1
  104. package/dist/client/{EventCombined.client-DSBVwq5m.mjs → EventCombined.client-DnsUeONl.mjs} +6 -6
  105. package/dist/client/{EventListing.client-DmFAX7Vb.mjs → EventListing.client-CNBFqJS4.mjs} +2 -2
  106. package/dist/client/{LeafletStaticMap-BAqXdfhq.mjs → LeafletStaticMap-C7higg52.mjs} +1 -1
  107. package/dist/client/{ThemedButton-BwNFVwi4.mjs → ThemedButton-LAJTNrS8.mjs} +1 -1
  108. package/dist/client/{accordion-DRhMdkbd.mjs → accordion-BcNF9TjX.mjs} +1 -1
  109. package/dist/client/{bookingForm-iJ_nCsNF.mjs → bookingForm-BUaQ3S03.mjs} +142 -50
  110. package/dist/client/bookings.mjs +191 -64
  111. package/dist/client/{carousel-D8zuffZr.mjs → carousel-CTdF6e0V.mjs} +1 -1
  112. package/dist/client/{cart-DeMGJViN.mjs → cart-pGtyf_XU.mjs} +3 -3
  113. package/dist/client/{checkout-DXc06Km2.mjs → checkout-Da9WSn7Y.mjs} +3 -3
  114. package/dist/client/client.mjs +1630 -816
  115. package/dist/client/{context-CDLCfDep.mjs → context-BFeY_Wbm.mjs} +1 -1
  116. package/dist/client/{dates-ClFx7Epy.mjs → dates-BhwVSxDg.mjs} +2 -2
  117. package/dist/client/{eventCalendar-BaGpnOGN.mjs → eventCalendar-BAtdnR4s.mjs} +9 -9
  118. package/dist/client/{eventCombined-ywONOx2m.mjs → eventCombined-RksA3tRC.mjs} +4 -4
  119. package/dist/client/{eventDetails-B2LlOTYY.mjs → eventDetails-BB9hB4wR.mjs} +4 -4
  120. package/dist/client/{eventListing-CMgxWpqP.mjs → eventListing-BpJBkviM.mjs} +4 -4
  121. package/dist/client/{eventRegistration-BarLDNHR.mjs → eventRegistration-B18jFq_o.mjs} +8 -8
  122. package/dist/client/{form-BjqKaBJ7.mjs → form-Dodt8Y8t.mjs} +3 -3
  123. package/dist/client/{headerSection-CP4XDwz1.mjs → headerSection-B0qj9ttg.mjs} +3 -3
  124. package/dist/client/hooks.mjs +550 -99
  125. package/dist/client/{locationMap-C5gW-d-w.mjs → locationMap-gn-iMk7a.mjs} +3 -3
  126. package/dist/client/{newsletterForm-afXlVSA0.mjs → newsletterForm-oByLdFkr.mjs} +26 -5
  127. package/dist/client/{pricing-Bl1CAl28.mjs → pricing-BOU0_Hai.mjs} +1 -1
  128. package/dist/client/{productDetail-CvQ3jWQe.mjs → productDetail-D9v1zH2j.mjs} +3 -3
  129. package/dist/client/{productList-U874PGO7.mjs → productList-D-mItx1n.mjs} +3 -3
  130. package/dist/client/{propsDecoder-DPXtCZWP.mjs → propsDecoder-C3TP_z4x.mjs} +72 -33
  131. package/dist/client/rendering/client.mjs +900 -266
  132. package/dist/client/rendering/islands.mjs +17 -17
  133. package/dist/client/rendering.mjs +1637 -788
  134. package/dist/client/{routeIslandApiConfig-NGYiUWXu.mjs → routeIslandApiConfig-DzN1W0sq.mjs} +1 -1
  135. package/dist/client/{scrollToBlock-0-C3DVhK.mjs → scrollToBlock-CWs8EIdo.mjs} +1 -1
  136. package/dist/client/{shop-BXjXhM9P.mjs → shop-Dufw7N7o.mjs} +7 -7
  137. package/dist/client/{shop-commerce-BZ6UlWJ7.mjs → shop-commerce-gklw_hLF.mjs} +6 -6
  138. package/dist/client/{shop-commerce-store-DlSBXb3D.mjs → shop-commerce-store-Sf1eyTaZ.mjs} +1 -1
  139. package/dist/client/{shopShared-kkEOiLPA.mjs → shopShared-B5nyA41S.mjs} +4 -4
  140. package/dist/client/{useEventFilters-zvnnE1ro.mjs → useEventFilters-CLL829vy.mjs} +6 -6
  141. package/dist/preview-next/before-render.mjs +147 -77
  142. package/dist/preview-next/client/runtime.mjs +4 -4
  143. package/dist/preview-next/keepAlive.mjs +147 -77
  144. package/dist/preview-next/middleware.mjs +147 -77
  145. package/dist/{previewAuthStore-JA6-I_sL.mjs → previewAuthStore-BxAFlu-j.mjs} +147 -77
  146. package/dist/{sdk-runtime-DFJlQt3q.mjs → sdk-runtime-D0uZFev7.mjs} +2 -2
  147. package/dist/{separator-o8GHb1xh.mjs → separator-EvdCAn4V.mjs} +1 -1
  148. package/dist/server/components.mjs +1727 -991
  149. package/dist/server/config-validation.mjs +537 -97
  150. package/dist/server/config.mjs +537 -97
  151. package/dist/server/data.mjs +549 -98
  152. package/dist/server/index.mjs +159 -81
  153. package/dist/server/next.mjs +1460 -748
  154. package/dist/server/page-converter.mjs +384 -54
  155. package/dist/server/prebuild.mjs +1 -1
  156. package/dist/server/rendering/server.mjs +1712 -973
  157. package/dist/server/rendering.mjs +1748 -1001
  158. package/dist/server/routing.mjs +624 -131
  159. package/dist/server/server.mjs +554 -138
  160. package/dist/server/theme-bridge.mjs +1192 -27
  161. package/dist/server/theme.mjs +6 -4
  162. package/package.json +2 -1
@@ -6669,6 +6669,15 @@ function asSiteStyleId(value) {
6669
6669
  function asDesignSystemTemplateId(value) {
6670
6670
  return brandNonEmptyString(value, "DesignSystemTemplateId");
6671
6671
  }
6672
+ function toNonEmptyReadonlyArray(values) {
6673
+ const [first, ...rest] = values;
6674
+ return first === void 0 ? null : [first, ...rest];
6675
+ }
6676
+ function requireNonEmptyReadonlyArray(values, message = "Expected a non-empty array.") {
6677
+ const result = toNonEmptyReadonlyArray(values);
6678
+ if (!result) throw new Error(message);
6679
+ return result;
6680
+ }
6672
6681
  function makeBoundaryId(previousBlockId, nextBlockId) {
6673
6682
  return asDesignBoundaryId(`boundary:${encodeURIComponent(previousBlockId)}:${encodeURIComponent(nextBlockId)}`);
6674
6683
  }
@@ -6871,16 +6880,18 @@ const themeV2RuntimeStyleFieldNames = [
6871
6880
  "_frameStyles",
6872
6881
  "_sectionStyles",
6873
6882
  "_containerStyles",
6874
- "_cardStyles",
6875
- "_transitionStyles",
6876
- "styleGroup"
6883
+ "_cardStyles"
6877
6884
  ];
6878
6885
  const themeV2BlockSpecificRawStyleFieldNames = [
6879
6886
  "_contentCardStyles",
6880
6887
  "_heroLayoutStyles",
6881
6888
  "_textCardStyles"
6882
6889
  ];
6883
- const themeV2NormalEditorRawStyleFieldNames = [...themeV2RuntimeStyleFieldNames, ...themeV2BlockSpecificRawStyleFieldNames];
6890
+ const themeV2NormalEditorRawStyleFieldNames = [
6891
+ ...themeV2RuntimeStyleFieldNames,
6892
+ ...themeV2BlockSpecificRawStyleFieldNames,
6893
+ "styleGroup"
6894
+ ];
6884
6895
  new Set(themeV2NormalEditorRawStyleFieldNames);
6885
6896
  [...themeV2RuntimeStyleFieldNames, ...themeV2BlockSpecificRawStyleFieldNames];
6886
6897
  const pageDesignEditorBackgroundOverrideOwner = "page-design-editor";
@@ -8504,6 +8515,75 @@ const calendarWindowPageSchema = z.discriminatedUnion("kind", [z.object({
8504
8515
  nextCursor: calendarSourceCursorSchema
8505
8516
  })]);
8506
8517
  //#endregion
8518
+ //#region ../api/src/defineEndpointDefinitions.ts
8519
+ /**
8520
+ * Validates extracted endpoint descriptors while preserving each literal path,
8521
+ * method, and parameter contract for the typed URL builders.
8522
+ */
8523
+ function defineEndpointDefinitions(definitions) {
8524
+ return definitions;
8525
+ }
8526
+ //#endregion
8527
+ //#region ../api/src/publicNewsletterEndpointDefinitions.ts
8528
+ const PUBLIC_NEWSLETTER_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
8529
+ subscribeNewsletter: {
8530
+ path: "/public/sites/{siteId}/newsletter/subscribe",
8531
+ method: "POST",
8532
+ tags: ["public-newsletter-{siteId}"],
8533
+ auth: "public",
8534
+ responseKind: "json"
8535
+ },
8536
+ confirmNewsletter: {
8537
+ path: "/public/sites/{siteId}/newsletter/confirm/{token}",
8538
+ method: "GET",
8539
+ tags: ["public-newsletter-{siteId}"],
8540
+ auth: "public",
8541
+ responseKind: "text"
8542
+ },
8543
+ unsubscribeNewsletter: {
8544
+ path: "/public/sites/{siteId}/newsletter/unsubscribe/{token}",
8545
+ method: "GET",
8546
+ tags: ["public-newsletter-{siteId}"],
8547
+ auth: "public",
8548
+ responseKind: "text"
8549
+ },
8550
+ unsubscribeNewsletterPost: {
8551
+ path: "/public/sites/{siteId}/newsletter/unsubscribe/{token}",
8552
+ method: "POST",
8553
+ tags: ["public-newsletter-{siteId}"],
8554
+ auth: "public",
8555
+ responseKind: "text"
8556
+ },
8557
+ confirmNewsletterPost: {
8558
+ path: "/public/sites/{siteId}/newsletter/confirm/{token}",
8559
+ method: "POST",
8560
+ tags: ["public-newsletter-{siteId}"],
8561
+ auth: "public",
8562
+ responseKind: "text"
8563
+ },
8564
+ getNewsletterPreferences: {
8565
+ path: "/public/sites/{siteId}/newsletter/preferences/{token}",
8566
+ method: "GET",
8567
+ tags: ["public-newsletter-{siteId}"],
8568
+ auth: "public",
8569
+ responseKind: "text"
8570
+ },
8571
+ saveNewsletterPreferences: {
8572
+ path: "/public/sites/{siteId}/newsletter/preferences/{token}",
8573
+ method: "POST",
8574
+ tags: ["public-newsletter-{siteId}"],
8575
+ auth: "public",
8576
+ responseKind: "text"
8577
+ },
8578
+ getNewsletterArchive: {
8579
+ path: "/public/sites/{siteId}/newsletter/archive/{token}",
8580
+ method: "GET",
8581
+ tags: ["public-newsletter-{siteId}"],
8582
+ auth: "public",
8583
+ responseKind: "text"
8584
+ }
8585
+ });
8586
+ //#endregion
8507
8587
  //#region ../api/src/apiEndpointTypes.ts
8508
8588
  function allowedDemoMutationPolicy() {
8509
8589
  return {
@@ -8595,17 +8675,85 @@ const SDK_ENTRY_READ_ENDPOINTS = {
8595
8675
  }
8596
8676
  };
8597
8677
  //#endregion
8598
- //#region ../api/src/defineEndpointDefinitions.ts
8599
- /**
8600
- * Validates extracted endpoint descriptors while preserving each literal path,
8601
- * method, and parameter contract for the typed URL builders.
8602
- */
8603
- function defineEndpointDefinitions(definitions) {
8604
- return definitions;
8605
- }
8606
- //#endregion
8607
8678
  //#region ../api/src/appointmentEndpointDefinitions.ts
8608
8679
  const APPOINTMENT_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
8680
+ ...defineEndpointDefinitions({
8681
+ listGroupedAppointmentServices: {
8682
+ path: "/sites/{siteId}/bookings/services/grouped",
8683
+ method: "GET",
8684
+ auth: "user",
8685
+ responseKind: "json",
8686
+ errors: ["server:internal_error"]
8687
+ },
8688
+ reorderAppointmentServices: {
8689
+ path: "/sites/{siteId}/bookings/services/order",
8690
+ method: "PUT",
8691
+ auth: "user",
8692
+ responseKind: "json",
8693
+ errors: [
8694
+ "validation:invalid_input",
8695
+ "auth:forbidden",
8696
+ "resource:not_found",
8697
+ "resource:conflict",
8698
+ "server:internal_error"
8699
+ ]
8700
+ },
8701
+ listAppointmentServiceCategories: {
8702
+ path: "/sites/{siteId}/bookings/service-categories",
8703
+ method: "GET",
8704
+ auth: "user",
8705
+ responseKind: "json",
8706
+ errors: ["server:internal_error"]
8707
+ },
8708
+ createAppointmentServiceCategory: {
8709
+ path: "/sites/{siteId}/bookings/service-categories",
8710
+ method: "POST",
8711
+ auth: "user",
8712
+ responseKind: "json",
8713
+ errors: [
8714
+ "validation:invalid_input",
8715
+ "auth:forbidden",
8716
+ "resource:conflict",
8717
+ "server:internal_error"
8718
+ ]
8719
+ },
8720
+ updateAppointmentServiceCategory: {
8721
+ path: "/sites/{siteId}/bookings/service-categories/{categoryId}",
8722
+ method: "PUT",
8723
+ auth: "user",
8724
+ responseKind: "json",
8725
+ errors: [
8726
+ "validation:invalid_input",
8727
+ "auth:forbidden",
8728
+ "resource:not_found",
8729
+ "resource:conflict",
8730
+ "server:internal_error"
8731
+ ]
8732
+ },
8733
+ deleteAppointmentServiceCategory: {
8734
+ path: "/sites/{siteId}/bookings/service-categories/{categoryId}",
8735
+ method: "DELETE",
8736
+ auth: "user",
8737
+ responseKind: "json",
8738
+ errors: [
8739
+ "auth:forbidden",
8740
+ "resource:not_found",
8741
+ "server:internal_error"
8742
+ ]
8743
+ },
8744
+ reorderAppointmentServiceCategories: {
8745
+ path: "/sites/{siteId}/bookings/service-categories/order",
8746
+ method: "PUT",
8747
+ auth: "user",
8748
+ responseKind: "json",
8749
+ errors: [
8750
+ "validation:invalid_input",
8751
+ "auth:forbidden",
8752
+ "resource:conflict",
8753
+ "server:internal_error"
8754
+ ]
8755
+ }
8756
+ }),
8609
8757
  listAppointmentResources: {
8610
8758
  path: "/sites/{siteId}/bookings/resources",
8611
8759
  method: "GET",
@@ -9753,39 +9901,6 @@ const NEWSLETTER_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
9753
9901
  auth: "user",
9754
9902
  responseKind: "json",
9755
9903
  demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
9756
- },
9757
- listNewsletterSendJobs: {
9758
- path: "/sites/{siteId}/newsletter/jobs",
9759
- method: "GET",
9760
- tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter],
9761
- auth: "user",
9762
- responseKind: "json"
9763
- },
9764
- retryNewsletterSendJob: {
9765
- path: "/sites/{siteId}/newsletter/jobs/{jobId}/retry",
9766
- method: "POST",
9767
- errors: [
9768
- "validation:invalid_input",
9769
- "resource:not_found",
9770
- "auth:forbidden",
9771
- "server:internal_error"
9772
- ],
9773
- tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter],
9774
- auth: "user",
9775
- responseKind: "json"
9776
- },
9777
- cancelNewsletterSendJob: {
9778
- path: "/sites/{siteId}/newsletter/jobs/{jobId}/cancel",
9779
- method: "POST",
9780
- errors: [
9781
- "validation:invalid_input",
9782
- "resource:not_found",
9783
- "auth:forbidden",
9784
- "server:internal_error"
9785
- ],
9786
- tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter],
9787
- auth: "user",
9788
- responseKind: "json"
9789
9904
  }
9790
9905
  });
9791
9906
  //#endregion
@@ -10551,6 +10666,7 @@ const BILLING_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
10551
10666
  }
10552
10667
  });
10553
10668
  ({
10669
+ ...PUBLIC_NEWSLETTER_ENDPOINT_DEFINITIONS,
10554
10670
  ...ACCOUNT_ENDPOINT_DEFINITIONS,
10555
10671
  ...PUBLIC_ONBOARDING_ATTEMPT_ENDPOINT_DEFINITIONS,
10556
10672
  ...PUBLIC_EVENT_ENDPOINT_DEFINITIONS,
@@ -12911,11 +13027,260 @@ function cardRoleFromLegacyVocabulary(value) {
12911
13027
  */
12912
13028
  const cardRoleWithLegacyAliasSchema = z.preprocess((value) => cardRoleFromLegacyVocabulary(value) ?? value, cardRoleSchema);
12913
13029
  //#endregion
12914
- //#region ../theme-core/src/site-styles/compilationPlan.ts
12915
- const defaultHeaderBrandPreferences = {
12916
- brandDisplay: "auto",
12917
- logoSize: "auto"
12918
- };
13030
+ //#region ../theme-core/src/site-styles/transitionCatalogue.ts
13031
+ /**
13032
+ * Family order for pickers. Entries below are listed family by family in this
13033
+ * same order, so the flat option list and the grouped families agree.
13034
+ */
13035
+ const transitionCatalogueFamilies = [
13036
+ {
13037
+ id: "gradient",
13038
+ label: "Gradient"
13039
+ },
13040
+ {
13041
+ id: "wave",
13042
+ label: "Wave"
13043
+ },
13044
+ {
13045
+ id: "angle",
13046
+ label: "Angle"
13047
+ }
13048
+ ];
13049
+ const mediumHeight = "6rem + 2px";
13050
+ const compactHeight = "4.5rem + 2px";
13051
+ const largeHeight = "7rem + 2px";
13052
+ /**
13053
+ * The single source of transition vocabulary. Order is significant: it is the
13054
+ * order of `boundaryOptions` (after `none`) and of each family's variants,
13055
+ * which persisted pins, page-flow presets and the editor picker all rely on.
13056
+ *
13057
+ * Shapes match what `generateLayoutCss` draws today. Structured
13058
+ * amplitude/frequency treatments (issue 826) extend this list later.
13059
+ */
13060
+ const transitionCatalogueEntries = defineExactCatalog()([
13061
+ {
13062
+ intent: "soft-fade-short",
13063
+ optionId: asBoundaryOptionId("break:soft"),
13064
+ family: "gradient",
13065
+ variantId: "soft",
13066
+ label: "Soft",
13067
+ variantLabel: "Soft",
13068
+ treatment: {
13069
+ kind: "soft-fade",
13070
+ height: "medium",
13071
+ curve: "soft"
13072
+ },
13073
+ size: "medium",
13074
+ heightExpression: mediumHeight,
13075
+ shape: { kind: "fade" }
13076
+ },
13077
+ {
13078
+ intent: "soft-fade-long",
13079
+ optionId: asBoundaryOptionId("break:spacious"),
13080
+ family: "gradient",
13081
+ variantId: "spacious",
13082
+ label: "Spacious",
13083
+ variantLabel: "Spacious",
13084
+ treatment: {
13085
+ kind: "soft-fade",
13086
+ height: "large",
13087
+ curve: "spacious"
13088
+ },
13089
+ size: "spacious",
13090
+ heightExpression: "10rem",
13091
+ shape: { kind: "fade" }
13092
+ },
13093
+ {
13094
+ intent: "soft-fade-expansive",
13095
+ optionId: asBoundaryOptionId("break:expansive"),
13096
+ family: "gradient",
13097
+ variantId: "expansive",
13098
+ label: "Expansive",
13099
+ variantLabel: "Expansive",
13100
+ treatment: {
13101
+ kind: "soft-fade",
13102
+ height: "expansive",
13103
+ curve: "expansive"
13104
+ },
13105
+ size: "expansive",
13106
+ heightExpression: "14rem",
13107
+ shape: { kind: "fade" }
13108
+ },
13109
+ {
13110
+ intent: "wave-edge-balanced",
13111
+ optionId: asBoundaryOptionId("break:wave-balanced"),
13112
+ family: "wave",
13113
+ variantId: "balanced",
13114
+ label: "Balanced wave",
13115
+ variantLabel: "Balanced",
13116
+ treatment: {
13117
+ kind: "wave-edge",
13118
+ height: "medium",
13119
+ amplitude: "balanced",
13120
+ rhythm: "double",
13121
+ symmetry: "symmetrical"
13122
+ },
13123
+ size: "medium",
13124
+ heightExpression: mediumHeight,
13125
+ shape: {
13126
+ kind: "wave",
13127
+ mask: "balanced"
13128
+ }
13129
+ },
13130
+ {
13131
+ intent: "wave-edge",
13132
+ optionId: asBoundaryOptionId("break:wave"),
13133
+ family: "wave",
13134
+ variantId: "classic",
13135
+ label: "Classic wave",
13136
+ variantLabel: "Classic",
13137
+ treatment: {
13138
+ kind: "wave-edge",
13139
+ height: "medium",
13140
+ amplitude: "balanced",
13141
+ rhythm: "double",
13142
+ symmetry: "asymmetrical"
13143
+ },
13144
+ size: "medium",
13145
+ heightExpression: mediumHeight,
13146
+ shape: {
13147
+ kind: "wave",
13148
+ mask: "classic"
13149
+ }
13150
+ },
13151
+ {
13152
+ intent: "wave-edge-gentle",
13153
+ optionId: asBoundaryOptionId("break:wave-gentle"),
13154
+ family: "wave",
13155
+ variantId: "gentle",
13156
+ label: "Gentle wave",
13157
+ variantLabel: "Gentle",
13158
+ treatment: {
13159
+ kind: "wave-edge",
13160
+ height: "compact",
13161
+ amplitude: "subtle",
13162
+ rhythm: "single",
13163
+ symmetry: "symmetrical"
13164
+ },
13165
+ size: "compact",
13166
+ heightExpression: compactHeight,
13167
+ shape: {
13168
+ kind: "wave",
13169
+ mask: "gentle"
13170
+ }
13171
+ },
13172
+ {
13173
+ intent: "wave-edge-bold",
13174
+ optionId: asBoundaryOptionId("break:wave-bold"),
13175
+ family: "wave",
13176
+ variantId: "bold",
13177
+ label: "Bold wave",
13178
+ variantLabel: "Bold",
13179
+ treatment: {
13180
+ kind: "wave-edge",
13181
+ height: "large",
13182
+ amplitude: "bold",
13183
+ rhythm: "double",
13184
+ symmetry: "symmetrical"
13185
+ },
13186
+ size: "large",
13187
+ heightExpression: largeHeight,
13188
+ shape: {
13189
+ kind: "wave",
13190
+ mask: "bold"
13191
+ }
13192
+ },
13193
+ {
13194
+ intent: "wave-edge-drift",
13195
+ optionId: asBoundaryOptionId("break:wave-drift"),
13196
+ family: "wave",
13197
+ variantId: "drift",
13198
+ label: "Drift wave",
13199
+ variantLabel: "Drift",
13200
+ treatment: {
13201
+ kind: "wave-edge",
13202
+ height: "medium",
13203
+ amplitude: "balanced",
13204
+ rhythm: "double",
13205
+ symmetry: "drift"
13206
+ },
13207
+ size: "medium",
13208
+ heightExpression: mediumHeight,
13209
+ shape: {
13210
+ kind: "wave",
13211
+ mask: "drift"
13212
+ }
13213
+ },
13214
+ {
13215
+ intent: "angle-edge-subtle",
13216
+ optionId: asBoundaryOptionId("break:angle-subtle"),
13217
+ family: "angle",
13218
+ variantId: "subtle",
13219
+ label: "Subtle angle",
13220
+ variantLabel: "Subtle",
13221
+ treatment: {
13222
+ kind: "angle-edge",
13223
+ height: "compact",
13224
+ slope: "subtle",
13225
+ direction: "forward"
13226
+ },
13227
+ size: "compact",
13228
+ heightExpression: compactHeight,
13229
+ shape: {
13230
+ kind: "angle",
13231
+ polygon: {
13232
+ startTopPercent: 34,
13233
+ endTopPercent: 18
13234
+ }
13235
+ }
13236
+ },
13237
+ {
13238
+ intent: "angle-edge",
13239
+ optionId: asBoundaryOptionId("break:angle-balanced"),
13240
+ family: "angle",
13241
+ variantId: "balanced",
13242
+ label: "Balanced angle",
13243
+ variantLabel: "Balanced",
13244
+ treatment: {
13245
+ kind: "angle-edge",
13246
+ height: "medium",
13247
+ slope: "balanced",
13248
+ direction: "forward"
13249
+ },
13250
+ size: "medium",
13251
+ heightExpression: mediumHeight,
13252
+ shape: {
13253
+ kind: "angle",
13254
+ polygon: {
13255
+ startTopPercent: 42,
13256
+ endTopPercent: 8
13257
+ }
13258
+ }
13259
+ },
13260
+ {
13261
+ intent: "angle-edge-steep",
13262
+ optionId: asBoundaryOptionId("break:angle-steep"),
13263
+ family: "angle",
13264
+ variantId: "steep",
13265
+ label: "Steep angle",
13266
+ variantLabel: "Steep",
13267
+ treatment: {
13268
+ kind: "angle-edge",
13269
+ height: "large",
13270
+ slope: "steep",
13271
+ direction: "forward"
13272
+ },
13273
+ size: "large",
13274
+ heightExpression: largeHeight,
13275
+ shape: {
13276
+ kind: "angle",
13277
+ polygon: {
13278
+ startTopPercent: 54,
13279
+ endTopPercent: 0
13280
+ }
13281
+ }
13282
+ }
13283
+ ]);
12919
13284
  //#endregion
12920
13285
  //#region ../theme-core/src/site-styles/sectionTransitions.ts
12921
13286
  function boundaryRuntimeMetrics(family, size, heightExpression) {
@@ -12926,42 +13291,106 @@ function boundaryRuntimeMetrics(family, size, heightExpression) {
12926
13291
  reserveCss: `calc((${heightExpression}) / 2)`
12927
13292
  };
12928
13293
  }
12929
- boundaryRuntimeMetrics("gradient", "medium", "6rem + 2px"), boundaryRuntimeMetrics("gradient", "spacious", "10rem"), boundaryRuntimeMetrics("gradient", "expansive", "14rem"), boundaryRuntimeMetrics("wave", "medium", "6rem + 2px"), boundaryRuntimeMetrics("wave", "medium", "6rem + 2px"), boundaryRuntimeMetrics("wave", "compact", "4.5rem + 2px"), boundaryRuntimeMetrics("wave", "large", "7rem + 2px"), boundaryRuntimeMetrics("wave", "medium", "6rem + 2px"), boundaryRuntimeMetrics("angle", "medium", "6rem + 2px"), boundaryRuntimeMetrics("angle", "compact", "4.5rem + 2px"), boundaryRuntimeMetrics("angle", "large", "7rem + 2px");
13294
+ new Map(transitionCatalogueEntries.map((entry) => [entry.intent, entry]));
13295
+ new Map(transitionCatalogueEntries.map((entry) => [entry.intent, boundaryRuntimeMetrics(entry.family, entry.size, entry.heightExpression)]));
13296
+ /**
13297
+ * The catalogue's compile-time coverage check guarantees an entry per
13298
+ * decorative intent, so a miss here is a broken invariant, not bad input.
13299
+ */
13300
+ function requireCatalogueValue(values, intent) {
13301
+ const value = values.get(intent);
13302
+ if (value === void 0) throw new Error(`Transition catalogue has no entry for ${intent}`);
13303
+ return value;
13304
+ }
12930
13305
  const noneBoundaryOption = {
12931
13306
  id: asBoundaryOptionId("break:none"),
12932
13307
  label: "None",
12933
13308
  transitionAfter: "none",
12934
13309
  treatment: { kind: "none" }
12935
13310
  };
12936
- const softBoundaryOption = {
12937
- id: asBoundaryOptionId("break:soft"),
12938
- label: "Soft",
12939
- transitionAfter: "soft-fade-short",
12940
- treatment: {
12941
- kind: "soft-fade",
12942
- height: "medium",
12943
- curve: "soft"
12944
- }
13311
+ const boundaryOptionByIntent = new Map(transitionCatalogueEntries.map((entry) => [entry.intent, {
13312
+ id: entry.optionId,
13313
+ label: entry.label,
13314
+ transitionAfter: entry.intent,
13315
+ treatment: entry.treatment
13316
+ }]));
13317
+ function boundaryOptionForTransitionIntent(intent) {
13318
+ return requireCatalogueValue(boundaryOptionByIntent, intent);
13319
+ }
13320
+ const softBoundaryOption = boundaryOptionForTransitionIntent("soft-fade-short");
13321
+ const spaciousBoundaryOption = boundaryOptionForTransitionIntent("soft-fade-long");
13322
+ boundaryOptionForTransitionIntent("soft-fade-expansive");
13323
+ boundaryOptionForTransitionIntent("wave-edge");
13324
+ boundaryOptionForTransitionIntent("wave-edge-balanced");
13325
+ boundaryOptionForTransitionIntent("wave-edge-gentle");
13326
+ boundaryOptionForTransitionIntent("wave-edge-bold");
13327
+ boundaryOptionForTransitionIntent("wave-edge-drift");
13328
+ boundaryOptionForTransitionIntent("angle-edge-subtle");
13329
+ boundaryOptionForTransitionIntent("angle-edge");
13330
+ boundaryOptionForTransitionIntent("angle-edge-steep");
13331
+ /**
13332
+ * Must remain non-empty; downstream code indexes `[0]` as the documented default.
13333
+ */
13334
+ const boundaryOptions = [noneBoundaryOption, ...transitionCatalogueEntries.map((entry) => boundaryOptionForTransitionIntent(entry.intent))];
13335
+ const noneTransitionVariant = {
13336
+ familyId: "none",
13337
+ variantId: "none",
13338
+ label: "None",
13339
+ boundaryOption: noneBoundaryOption
12945
13340
  };
12946
- const spaciousBoundaryOption = {
12947
- id: asBoundaryOptionId("break:spacious"),
12948
- label: "Spacious",
12949
- transitionAfter: "soft-fade-long",
12950
- treatment: {
12951
- kind: "soft-fade",
12952
- height: "large",
12953
- curve: "spacious"
12954
- }
13341
+ function transitionVariantForEntry(entry) {
13342
+ return {
13343
+ familyId: entry.family,
13344
+ variantId: entry.variantId,
13345
+ label: entry.variantLabel,
13346
+ boundaryOption: boundaryOptionForTransitionIntent(entry.intent)
13347
+ };
13348
+ }
13349
+ const sectionTransitionFamilies = [{
13350
+ id: "none",
13351
+ label: "None",
13352
+ variants: [noneTransitionVariant]
13353
+ }, ...transitionCatalogueFamilies.map((family) => ({
13354
+ id: family.id,
13355
+ label: family.label,
13356
+ variants: requireNonEmptyReadonlyArray(transitionCatalogueEntries.filter((entry) => entry.family === family.id).map(transitionVariantForEntry), `Transition family ${family.id} has no catalogue entries.`)
13357
+ }))];
13358
+ new Map(boundaryOptions.map((option) => [option.id, option]));
13359
+ new Map(boundaryOptions.map((option) => [stableTreatmentKey(option.treatment), option]));
13360
+ new Map(sectionTransitionFamilies.flatMap((family) => family.variants.map((variant) => [variant.boundaryOption.id, variant])));
13361
+ new Map(sectionTransitionFamilies.map((family) => [family.id, family]));
13362
+ function stableTreatmentKey(treatment) {
13363
+ switch (treatment.kind) {
13364
+ case "none": return "none";
13365
+ case "soft-fade": return `${treatment.kind}:${treatment.height}:${treatment.curve}`;
13366
+ case "wave-edge": return [
13367
+ treatment.kind,
13368
+ treatment.height,
13369
+ treatment.amplitude,
13370
+ treatment.rhythm,
13371
+ treatment.symmetry
13372
+ ].join(":");
13373
+ case "angle-edge": return [
13374
+ treatment.kind,
13375
+ treatment.height,
13376
+ treatment.slope,
13377
+ treatment.direction
13378
+ ].join(":");
13379
+ case "legacy-unsupported": return `${treatment.kind}:${treatment.boundaryOptionId}`;
13380
+ }
13381
+ }
13382
+ requireThemeColorToken$1("background");
13383
+ function requireThemeColorToken$1(value) {
13384
+ const token = parseThemeColorToken(value);
13385
+ if (!token) throw new Error(`Expected a theme color token. Received: ${value}`);
13386
+ return token;
13387
+ }
13388
+ //#endregion
13389
+ //#region ../theme-core/src/site-styles/compilationPlan.ts
13390
+ const defaultHeaderBrandPreferences = {
13391
+ brandDisplay: "auto",
13392
+ logoSize: "auto"
12955
13393
  };
12956
- asBoundaryOptionId("break:expansive");
12957
- asBoundaryOptionId("break:wave");
12958
- asBoundaryOptionId("break:wave-balanced");
12959
- asBoundaryOptionId("break:wave-gentle");
12960
- asBoundaryOptionId("break:wave-bold");
12961
- asBoundaryOptionId("break:wave-drift");
12962
- asBoundaryOptionId("break:angle-subtle");
12963
- asBoundaryOptionId("break:angle-balanced");
12964
- asBoundaryOptionId("break:angle-steep");
12965
13394
  asBoundaryOptionId("break:unknown");
12966
13395
  const pageDesignUserPinnedAppearanceChoiceSchema = z.object({
12967
13396
  kind: z.literal("user-pinned"),
@@ -13088,14 +13517,11 @@ function validateUniquePageDesignPins(intent, ctx) {
13088
13517
  label: "block Look pin"
13089
13518
  });
13090
13519
  addDuplicateStringIssues(ctx, {
13091
- values: intent.boundaryPins.map((pin) => boundaryKey(pin.previousBlockId, pin.nextBlockId)),
13520
+ values: intent.boundaryPins.map((pin) => makeBoundaryId(pin.previousBlockId, pin.nextBlockId)),
13092
13521
  path: ["boundaryPins"],
13093
13522
  label: "boundary pin"
13094
13523
  });
13095
13524
  }
13096
- function boundaryKey(previousBlockId, nextBlockId) {
13097
- return makeBoundaryId(previousBlockId, nextBlockId);
13098
- }
13099
13525
  //#endregion
13100
13526
  //#region ../theme-core/src/accordions/siteStyleDefaults.ts
13101
13527
  /**
@@ -14723,6 +15149,13 @@ z.object({
14723
15149
  fields: nonEmptyRuntimeStyleFieldNamesSchema,
14724
15150
  authority: styleAuthoritySchema
14725
15151
  }).strict();
15152
+ asPageFlowPresetId("flow:quiet"), noneBoundaryOption.id, asPageFlowPresetId("flow:balanced"), softBoundaryOption.id, asPageFlowPresetId("flow:expressive"), spaciousBoundaryOption.id;
15153
+ asPageFlowPresetId("generated-default");
15154
+ asSiteStyleId("site-style:south-west-twerk-school");
15155
+ asAppearancePresetId("hero-brand-scrim-fixed-frame");
15156
+ asLayoutVariantKey("classic");
15157
+ asLayoutVariantKey("micro");
15158
+ asBoundaryOptionId("break:wave");
14726
15159
  //#endregion
14727
15160
  //#region ../theme-core/src/site-styles/runtimeCompiler.ts
14728
15161
  function defineSectionForegroundRuntimeTokens(input) {
@@ -14746,7 +15179,7 @@ function defineComponentRuntimeRules(rules) {
14746
15179
  }
14747
15180
  /**
14748
15181
  * Default design rules translate semantic page-level choices into the current
14749
- * runtime's section background and transition style-group vocabulary.
15182
+ * runtime's section background vocabulary.
14750
15183
  */
14751
15184
  const defaultDesignRuntimeRules = defineDesignRuntimeRules({
14752
15185
  sectionSurfaces: {
@@ -14781,8 +15214,7 @@ const defaultDesignRuntimeRules = defineDesignRuntimeRules({
14781
15214
  color: "surface",
14782
15215
  opacity: .88
14783
15216
  }
14784
- },
14785
- transitionClassName: (transition, fromSurface, toSurface) => transition === "none" ? null : `site-style-transition-${transition}-from-${fromSurface}-to-${toSurface}`
15217
+ }
14786
15218
  });
14787
15219
  /**
14788
15220
  * Default component rules translate frame and item-surface semantics into the
@@ -16517,19 +16949,11 @@ const curatedSiteStyles = [
16517
16949
  })
16518
16950
  ];
16519
16951
  new Map(curatedSiteStyles.map((style) => [style.id, style]));
16520
- asPageFlowPresetId("generated-default");
16521
- asSiteStyleId("site-style:south-west-twerk-school");
16522
- asAppearancePresetId("hero-brand-scrim-fixed-frame");
16523
- asLayoutVariantKey("classic");
16524
- asLayoutVariantKey("micro");
16525
- asBoundaryOptionId("break:wave");
16526
- asPageFlowPresetId("flow:quiet"), noneBoundaryOption.id, asPageFlowPresetId("flow:balanced"), softBoundaryOption.id, asPageFlowPresetId("flow:expressive"), spaciousBoundaryOption.id;
16527
16952
  //#endregion
16528
16953
  //#region ../theme-core/src/site-styles/resolver.ts
16529
16954
  const blockDesignFallback = {
16530
16955
  sectionSurface: "base",
16531
16956
  contentFrame: plainFrame,
16532
- transitionAfter: "none",
16533
16957
  sectionHeight: "default",
16534
16958
  heroLegibility: "none",
16535
16959
  imageSurfaceTreatment: { kind: "none" },
@@ -16540,7 +16964,7 @@ const blockDesignFallback = {
16540
16964
  accordionIconTreatment: null,
16541
16965
  composition: null
16542
16966
  };
16543
- blockDesignFallback.sectionSurface, blockDesignFallback.contentFrame, blockDesignFallback.transitionAfter, blockDesignFallback.sectionHeight, blockDesignFallback.heroLegibility, blockDesignFallback.imageSurfaceTreatment, blockDesignFallback.imageSurfaceMotion, blockDesignFallback.tileTreatment, blockDesignFallback.eventListTreatment, blockDesignFallback.eyebrowTreatment, blockDesignFallback.accordionIconTreatment, blockDesignFallback.composition;
16967
+ blockDesignFallback.sectionSurface, blockDesignFallback.contentFrame, blockDesignFallback.sectionHeight, blockDesignFallback.heroLegibility, blockDesignFallback.imageSurfaceTreatment, blockDesignFallback.imageSurfaceMotion, blockDesignFallback.tileTreatment, blockDesignFallback.eventListTreatment, blockDesignFallback.eyebrowTreatment, blockDesignFallback.accordionIconTreatment, blockDesignFallback.composition;
16544
16968
  //#endregion
16545
16969
  //#region ../theme-core/src/site-styles/siteChromeBackgrounds.ts
16546
16970
  const siteChromeBackgroundColorTokens = toSiteChromeBackgroundColorTokens(backgroundAppearanceColorTokenNames);
@@ -17143,7 +17567,8 @@ const siteOptionSources = [
17143
17567
  "eventCategories",
17144
17568
  "eventSeries",
17145
17569
  "venues",
17146
- "staffMembers"
17570
+ "staffMembers",
17571
+ "appointmentServiceCategories"
17147
17572
  ];
17148
17573
  const mediaDeliverySchema = z.object({
17149
17574
  sizes: z.string().optional(),
@@ -28012,6 +28437,15 @@ const appointmentServicesBlockDefinition = {
28012
28437
  required: false,
28013
28438
  ui: { intent: "content" }
28014
28439
  },
28440
+ createSiteOptionSelectField({
28441
+ id: "categoryId",
28442
+ label: "Category",
28443
+ description: "Show one category (with its heading and intro), or leave it on All categories to show everything grouped.",
28444
+ required: false,
28445
+ multiple: false,
28446
+ optionSource: "appointmentServiceCategories",
28447
+ ui: { intent: "content" }
28448
+ }),
28015
28449
  sectionStylesField({
28016
28450
  id: "_sectionStyles",
28017
28451
  label: "Section styles",
@@ -28046,6 +28480,7 @@ const appointmentServicesBlockDefinition = {
28046
28480
  richText({ className: "rb-prose rb-max-w-none" }, bind("content.description"), when("content.description")),
28047
28481
  el("appointment-services", {
28048
28482
  sectionHeading: { $bind: { from: "content.heading" } },
28483
+ categoryId: { $bind: { from: "content.categoryId" } },
28049
28484
  services: { $bind: { from: "data.services" } },
28050
28485
  pathname: { $bind: { from: "$root.pathname" } },
28051
28486
  servicePathPrefix: { $bind: { from: "$root.appointmentServicePathPrefix" } }
@@ -38504,6 +38939,17 @@ function coerceToString(value) {
38504
38939
  return "";
38505
38940
  }
38506
38941
  /**
38942
+ * The appointment-services catalogue (issue 1403) pairs the services with the
38943
+ * site's ordered categories. Both are needed to group them, so that response
38944
+ * is passed through whole; any other `{ services }` wrapper is unwrapped.
38945
+ */
38946
+ function coerceServicesPayload(record) {
38947
+ return Array.isArray(record.services) && Array.isArray(record.categories) ? {
38948
+ services: record.services,
38949
+ categories: record.categories
38950
+ } : record.services;
38951
+ }
38952
+ /**
38507
38953
  * Extract data from API response.
38508
38954
  * Unwraps common response wrappers: { data }, { form }, { entries }, { services }, { teamMembers }
38509
38955
  *
@@ -38518,7 +38964,7 @@ function coercePayload(payload) {
38518
38964
  if ("data" in record && typeof record.data !== "function") return record.data;
38519
38965
  if ("form" in record && typeof record.form !== "function") return record.form;
38520
38966
  if ("entries" in record && typeof record.entries !== "function") return record.entries;
38521
- if ("services" in record && typeof record.services !== "function") return record.services;
38967
+ if ("services" in record && typeof record.services !== "function") return coerceServicesPayload(record);
38522
38968
  if ("teamMembers" in record && typeof record.teamMembers !== "function") return record.teamMembers;
38523
38969
  }
38524
38970
  return payload;
@@ -39420,7 +39866,12 @@ const appointmentSetupServiceDraftSchema = z.object({
39420
39866
  venue: appointmentSetupVenueChoiceSchema,
39421
39867
  timezone: z.string().trim().min(1).nullable(),
39422
39868
  payment: appointmentSetupPaymentDraftSchema,
39423
- assignment: appointmentSetupServiceAssignmentDraftSchema
39869
+ assignment: appointmentSetupServiceAssignmentDraftSchema,
39870
+ /**
39871
+ * The service's category, or null for "Other" (issue 1403). Omitted leaves
39872
+ * an existing service's category alone and puts a new one in "Other".
39873
+ */
39874
+ categoryId: z.string().uuid().nullable().optional()
39424
39875
  }).superRefine((service, ctx) => {
39425
39876
  if (service.payment.kind !== "free" && (service.priceAmount === null || service.priceAmount <= 0)) ctx.addIssue({
39426
39877
  code: "custom",