@riverbankcms/sdk 0.101.0 → 0.102.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 (54) hide show
  1. package/dist/{PreviewEditorSidebar-DBpy0KTh.mjs → PreviewEditorSidebar-BKkhhkJk.mjs} +358 -68
  2. package/dist/{PreviewEditorUI-Fg6I2R2T.mjs → PreviewEditorUI-DIvTqcqI.mjs} +3 -3
  3. package/dist/{PreviewQueryProvider-BICQLAUF.mjs → PreviewQueryProvider-ZF6TXq5Q.mjs} +1 -1
  4. package/dist/{SdkPreviewModeRuntime-DFQP-Q53.mjs → SdkPreviewModeRuntime-CA2k7Z_T.mjs} +200 -122
  5. package/dist/{SiteChromeCustomizeContext-GwZc89KN.mjs → SiteChromeCustomizeContext-Bh9-DtMQ.mjs} +203 -34
  6. package/dist/_dts/ai/src/designer/rfc6902.d.ts +57 -1
  7. package/dist/_dts/ai/src/designer/themePatch.d.ts +16 -6
  8. package/dist/_dts/api/src/bookingVerticals.d.ts +53 -1
  9. package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +1 -0
  10. package/dist/_dts/blocks/src/bindings/index.d.ts +1 -1
  11. package/dist/_dts/blocks/src/system/runtime/nodes/layout.d.ts +1 -0
  12. package/dist/_dts/content-editor/src/index.d.ts +1 -0
  13. package/dist/_dts/core/src/branded.d.ts +4 -0
  14. package/dist/_dts/core/src/person-records.d.ts +6 -1
  15. package/dist/_dts/media-core/src/identifiers.d.ts +14 -1
  16. package/dist/_dts/preview-next/src/client/blocks/composer/mergeDrafts.d.ts +1 -1
  17. package/dist/_dts/preview-next/src/client/blocks/previewProjection/applyPreviewProjections.d.ts +3 -1
  18. package/dist/_dts/preview-next/src/client/blocks/previewProjection/runtimeContentDecoration.d.ts +2 -2
  19. package/dist/_dts/preview-next/src/client/preview/PreviewChromeLayer.d.ts +2 -1
  20. package/dist/_dts/preview-next/src/client/preview/StyleConfigurator.state.d.ts +43 -7
  21. package/dist/_dts/preview-next/src/client/preview/siteStylePreviewPlanner.d.ts +4 -4
  22. package/dist/_dts/preview-next/src/client/preview/styleConfiguratorApplyPayload.d.ts +1 -1
  23. package/dist/_dts/preview-next/src/client/preview/typographySelectionInput.d.ts +4 -2
  24. package/dist/_dts/sdk/src/version.d.ts +1 -1
  25. package/dist/_dts/theme-core/src/site-styles/designState.d.ts +4 -2
  26. package/dist/_dts/theme-core/src/site-styles/headerLooks.d.ts +4 -4
  27. package/dist/_dts/theme-core/src/site-styles/previewCompiler.d.ts +6 -1
  28. package/dist/_dts/theme-core/src/site-styles/rawStyleFields.d.ts +3 -3
  29. package/dist/_dts/theme-core/src/site-styles/runtimeCompiler.d.ts +24 -1
  30. package/dist/cli/index.mjs +31 -15
  31. package/dist/client/client.mjs +44 -16
  32. package/dist/client/hooks.mjs +14 -5
  33. package/dist/client/rendering/client.mjs +21 -13
  34. package/dist/client/rendering.mjs +43 -15
  35. package/dist/preview-next/before-render.mjs +1 -1
  36. package/dist/preview-next/client/runtime.mjs +4 -4
  37. package/dist/{previewAuthStore-Da74OL0X.mjs → previewAuthStore-ByPPZqmp.mjs} +1 -0
  38. package/dist/{sdk-runtime-CP6Kwalv.mjs → sdk-runtime-K8Oqj97H.mjs} +2 -2
  39. package/dist/{separator-BVk7GvGN.mjs → separator-CRoP34pT.mjs} +1 -1
  40. package/dist/server/components.mjs +37 -13
  41. package/dist/server/config-validation.mjs +14 -5
  42. package/dist/server/config.mjs +14 -5
  43. package/dist/server/data.mjs +14 -5
  44. package/dist/server/index.mjs +2 -2
  45. package/dist/server/next.mjs +38 -14
  46. package/dist/server/page-converter.mjs +7 -4
  47. package/dist/server/prebuild.mjs +1 -1
  48. package/dist/server/rendering/server.mjs +37 -13
  49. package/dist/server/rendering.mjs +37 -13
  50. package/dist/server/routing.mjs +16 -6
  51. package/dist/server/server.mjs +15 -6
  52. package/dist/server/theme-bridge.mjs +5 -4
  53. package/dist/server/theme.mjs +1 -0
  54. package/package.json +1 -1
@@ -18751,6 +18751,7 @@ const themeV2RuntimeStyleFieldNames = [
18751
18751
  "_sectionStyles",
18752
18752
  "_containerStyles",
18753
18753
  "_cardStyles",
18754
+ "_transitionStyles",
18754
18755
  "styleGroup"
18755
18756
  ];
18756
18757
  const themeV2BlockSpecificRawStyleFieldNames = [
@@ -21852,12 +21853,12 @@ const headerStyleCatalog = defineExactCatalog()([
21852
21853
  },
21853
21854
  {
21854
21855
  id: asHeaderStyleId("fine-line"),
21855
- label: "Fine Line",
21856
- description: "Light surface with a crisp lower rule and underline hover.",
21856
+ label: "Seamless",
21857
+ description: "Borderless surface with underline hover for a quieter page transition.",
21857
21858
  supportedLayoutIds: supportedLayouts(["classic", "centered"]),
21858
21859
  navInteraction: "underline-grow",
21859
- surface: "bordered",
21860
- defaultDepth: "line",
21860
+ surface: "neutral",
21861
+ defaultDepth: "none",
21861
21862
  navTypography: "plain",
21862
21863
  moods: [
21863
21864
  "calm",
@@ -41598,6 +41599,7 @@ const eventListingBlockDefinition = {
41598
41599
  } },
41599
41600
  seeAllUrl: { $bind: {
41600
41601
  from: "content.seeAllUrl",
41602
+ fallback: "",
41601
41603
  transforms: [{ id: "links.resolve" }]
41602
41604
  } },
41603
41605
  loadMoreText: { $bind: {
@@ -41934,6 +41936,7 @@ const eventCalendarLayout = [styledSection({
41934
41936
  } },
41935
41937
  seeAllUrl: { $bind: {
41936
41938
  from: "content.seeAllUrl",
41939
+ fallback: "",
41937
41940
  transforms: [{ id: "links.resolve" }]
41938
41941
  } },
41939
41942
  loadMoreText: { $bind: {
@@ -49406,15 +49409,15 @@ function Grid({ as: Comp = "div", cols = {
49406
49409
  }
49407
49410
  //#endregion
49408
49411
  //#region ../blocks/src/system/runtime/nodes/layout.tsx
49409
- const SectionNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, allowOverflow, ...props }) => /* @__PURE__ */ jsx(Section, {
49412
+ const SectionNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, allowOverflow, ...props }) => /* @__PURE__ */ jsx(Section, {
49410
49413
  ...props,
49411
49414
  allowOverflow
49412
49415
  });
49413
- const StackNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Stack, { ...props });
49414
- const InlineNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Inline, { ...props });
49415
- const GridNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Grid, { ...props });
49416
- const DivNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx("div", { ...props });
49417
- const FigureNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx("figure", { ...props });
49416
+ const StackNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Stack, { ...props });
49417
+ const InlineNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Inline, { ...props });
49418
+ const GridNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Grid, { ...props });
49419
+ const DivNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx("div", { ...props });
49420
+ const FigureNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx("figure", { ...props });
49418
49421
  //#endregion
49419
49422
  //#region ../blocks/src/primitives/content/utils/sanitizeHref.ts
49420
49423
  const SAFE_PROTOCOLS = /* @__PURE__ */ new Set([
@@ -57091,6 +57094,7 @@ function applyTransformsAndFallback(value, binding, context) {
57091
57094
  viewModel: context.viewModel
57092
57095
  }, transforms);
57093
57096
  if (binding.transforms && binding.transforms.length > 0 && transformed === null) {
57097
+ if (binding.fallback !== void 0) return binding.fallback;
57094
57098
  if (process.env.NODE_ENV === "development") console.warn("[block-system] Transform returned null for binding", {
57095
57099
  bindingFrom: binding.from,
57096
57100
  transforms: binding.transforms?.map((t) => t.id)
@@ -59070,7 +59074,7 @@ function generateHeaderRootStyles(header, themeId, tokens, _theme) {
59070
59074
  }
59071
59075
  }
59072
59076
  if (header.positioning === "sticky" || header.positioning === "fixed") {
59073
- const shadowVar = getComponentShadowVar(header.shadow?.elevation ?? "sm");
59077
+ const shadowVar = getComponentShadowVar(header.shadow?.elevation ?? "none");
59074
59078
  if (shadowVar) rules.push(`box-shadow: ${shadowVar};`);
59075
59079
  }
59076
59080
  const baseBlock = `\n${selector} {\n ${rules.join("\n ")}\n}\n`;
@@ -61922,6 +61926,7 @@ function PageRenderer$1({ theme, page, usePlaceholders = false, dataContext, wra
61922
61926
  const wrapperClassName = [`block-${cleanKind}`, wrapBlock ? "group relative" : null].filter(Boolean).join(" ");
61923
61927
  const styleGroup = typeof renderableContent.styleGroup === "string" ? renderableContent.styleGroup : void 0;
61924
61928
  const blockLook = typeof renderableContent.blockLook === "string" ? renderableContent.blockLook : void 0;
61929
+ const transitionStyle = transitionCssVarsStyle(renderableContent);
61925
61930
  const blockElement = /* @__PURE__ */ jsx("div", {
61926
61931
  className: wrapperClassName,
61927
61932
  "data-block": cleanKind,
@@ -61932,6 +61937,7 @@ function PageRenderer$1({ theme, page, usePlaceholders = false, dataContext, wra
61932
61937
  "data-block-look": blockLook,
61933
61938
  "data-page-block-position": blockPosition,
61934
61939
  "data-style-group": styleGroup,
61940
+ style: transitionStyle,
61935
61941
  children: /* @__PURE__ */ jsx(MemoBlockSection, { ...blockSectionProps })
61936
61942
  }, blockKey);
61937
61943
  if (!isSiteStyleTransitionStyleGroup(styleGroup)) return blockElement;
@@ -61939,13 +61945,25 @@ function PageRenderer$1({ theme, page, usePlaceholders = false, dataContext, wra
61939
61945
  "aria-hidden": "true",
61940
61946
  "data-block-transition": "",
61941
61947
  "data-block-transition-for": block.id ?? blockKey,
61942
- "data-style-group": styleGroup
61948
+ "data-style-group": styleGroup,
61949
+ style: transitionStyle
61943
61950
  })] }, blockKey);
61944
61951
  }) });
61945
61952
  }
61946
61953
  function isSiteStyleTransitionStyleGroup(value) {
61947
61954
  return value?.startsWith("site-style-transition-") === true;
61948
61955
  }
61956
+ function transitionCssVarsStyle(content) {
61957
+ const transitionStyles = isObjectRecord(content._transitionStyles) ? content._transitionStyles : null;
61958
+ const cssVars = isObjectRecord(transitionStyles?.cssVars) ? transitionStyles.cssVars : null;
61959
+ const from = typeof cssVars?.from === "string" ? cssVars.from : null;
61960
+ const to = typeof cssVars?.to === "string" ? cssVars.to : null;
61961
+ if (!from && !to) return void 0;
61962
+ return {
61963
+ ...from ? { "--site-style-transition-from": from } : {},
61964
+ ...to ? { "--site-style-transition-to": to } : {}
61965
+ };
61966
+ }
61949
61967
  function pageBlockPosition(index, blockCount) {
61950
61968
  if (blockCount <= 1) return "only";
61951
61969
  if (index === 0) return "first";
@@ -74197,7 +74215,7 @@ z$1.object({ acceptExtraSiteCharge: z$1.boolean().optional() });
74197
74215
  //#region ../surfaces/src/index.ts
74198
74216
  const SURFACE_IDS = ["core", "macadamia"];
74199
74217
  const DEFAULT_SURFACE_ID = "core";
74200
- SURFACE_IDS.filter((surfaceId) => surfaceId !== DEFAULT_SURFACE_ID);
74218
+ [...SURFACE_IDS.filter((surfaceId) => surfaceId !== DEFAULT_SURFACE_ID)];
74201
74219
  //#endregion
74202
74220
  //#region ../api/src/url.ts
74203
74221
  /**
@@ -74746,6 +74764,7 @@ const VERTICAL_IDS = [
74746
74764
  "training_provider",
74747
74765
  "retreat_centre",
74748
74766
  "music_school",
74767
+ "voice_singing",
74749
74768
  "performing_arts_school",
74750
74769
  "community_wellbeing",
74751
74770
  "venue_event_space"
@@ -74798,6 +74817,11 @@ const VERTICAL_BOOKING_PRESETS = [
74798
74817
  preset("music_school.terms", "music_school", "course", "Term", "Terms", "Multi-week term blocks or fixed-date group courses."),
74799
74818
  preset("music_school.workshops", "music_school", "workshop", "Workshop", "Workshops", "One-off workshops, masterclasses, or intensives."),
74800
74819
  preset("music_school.performances", "music_school", "performance", "Performance", "Performances", "Concerts, recitals, showcases, or ticketed performances."),
74820
+ preset("voice_singing.lessons", "voice_singing", "appointment", "Voice session", "Voice sessions", "One-to-one singing lessons, voice coaching, or private practice sessions."),
74821
+ preset("voice_singing.classes", "voice_singing", "class", "Ongoing weekly session", "Ongoing weekly sessions", "Regular choirs, voice circles, community singing, or group practice."),
74822
+ preset("voice_singing.terms", "voice_singing", "course", "Singing term", "Singing terms", "Multi-week choir terms, voice courses, or fixed-date group programmes."),
74823
+ preset("voice_singing.workshops", "voice_singing", "workshop", "Workshop", "Workshops", "One-off singing workshops, voice journeys, or devotional singing sessions."),
74824
+ preset("voice_singing.performances", "voice_singing", "performance", "Performance", "Performances", "Choir concerts, sharing events, recitals, or community performances."),
74801
74825
  preset("performing_arts_school.classes", "performing_arts_school", "class", "Class", "Classes", "Regular group classes, rehearsals, or weekly sessions."),
74802
74826
  preset("performing_arts_school.terms", "performing_arts_school", "course", "Term", "Terms", "Multi-week term blocks or fixed-date course groups."),
74803
74827
  preset("performing_arts_school.workshops", "performing_arts_school", "workshop", "Workshop", "Workshops", "One-off workshops, masterclasses, or intensives."),
@@ -80123,7 +80147,7 @@ var CircuitOpenError = class extends Error {
80123
80147
  * 1. This constant
80124
80148
  * 2. The "version" field in package.json
80125
80149
  */
80126
- const SDK_VERSION = "0.101.0";
80150
+ const SDK_VERSION = "0.102.0";
80127
80151
  //#endregion
80128
80152
  //#region src/next/content-load-failure.ts
80129
80153
  const SdkContentLoadError = RiverbankContentLoadError;
@@ -3789,6 +3789,7 @@ const themeV2RuntimeStyleFieldNames = [
3789
3789
  "_sectionStyles",
3790
3790
  "_containerStyles",
3791
3791
  "_cardStyles",
3792
+ "_transitionStyles",
3792
3793
  "styleGroup"
3793
3794
  ];
3794
3795
  const themeV2BlockSpecificRawStyleFieldNames = [
@@ -7475,12 +7476,12 @@ const headerStyleCatalog = defineExactCatalog()([
7475
7476
  },
7476
7477
  {
7477
7478
  id: asHeaderStyleId("fine-line"),
7478
- label: "Fine Line",
7479
- description: "Light surface with a crisp lower rule and underline hover.",
7479
+ label: "Seamless",
7480
+ description: "Borderless surface with underline hover for a quieter page transition.",
7480
7481
  supportedLayoutIds: supportedLayouts(["classic", "centered"]),
7481
7482
  navInteraction: "underline-grow",
7482
- surface: "bordered",
7483
- defaultDepth: "line",
7483
+ surface: "neutral",
7484
+ defaultDepth: "none",
7484
7485
  navTypography: "plain",
7485
7486
  moods: [
7486
7487
  "calm",
@@ -23580,6 +23581,7 @@ const eventListingBlockDefinition = {
23580
23581
  } },
23581
23582
  seeAllUrl: { $bind: {
23582
23583
  from: "content.seeAllUrl",
23584
+ fallback: "",
23583
23585
  transforms: [{ id: "links.resolve" }]
23584
23586
  } },
23585
23587
  loadMoreText: { $bind: {
@@ -23883,6 +23885,7 @@ const eventCalendarLayout = [styledSection({
23883
23885
  } },
23884
23886
  seeAllUrl: { $bind: {
23885
23887
  from: "content.seeAllUrl",
23888
+ fallback: "",
23886
23889
  transforms: [{ id: "links.resolve" }]
23887
23890
  } },
23888
23891
  loadMoreText: { $bind: {
@@ -12,7 +12,7 @@ import * as crypto from "crypto";
12
12
  * 1. This constant
13
13
  * 2. The "version" field in package.json
14
14
  */
15
- const SDK_VERSION = "0.101.0";
15
+ const SDK_VERSION = "0.102.0";
16
16
  //#endregion
17
17
  //#region src/constants.ts
18
18
  /**
@@ -11221,6 +11221,7 @@ const themeV2RuntimeStyleFieldNames = [
11221
11221
  "_sectionStyles",
11222
11222
  "_containerStyles",
11223
11223
  "_cardStyles",
11224
+ "_transitionStyles",
11224
11225
  "styleGroup"
11225
11226
  ];
11226
11227
  const themeV2BlockSpecificRawStyleFieldNames = [
@@ -14334,12 +14335,12 @@ const headerStyleCatalog = defineExactCatalog()([
14334
14335
  },
14335
14336
  {
14336
14337
  id: asHeaderStyleId("fine-line"),
14337
- label: "Fine Line",
14338
- description: "Light surface with a crisp lower rule and underline hover.",
14338
+ label: "Seamless",
14339
+ description: "Borderless surface with underline hover for a quieter page transition.",
14339
14340
  supportedLayoutIds: supportedLayouts(["classic", "centered"]),
14340
14341
  navInteraction: "underline-grow",
14341
- surface: "bordered",
14342
- defaultDepth: "line",
14342
+ surface: "neutral",
14343
+ defaultDepth: "none",
14343
14344
  navTypography: "plain",
14344
14345
  moods: [
14345
14346
  "calm",
@@ -33869,6 +33870,7 @@ const eventListingBlockDefinition = {
33869
33870
  } },
33870
33871
  seeAllUrl: { $bind: {
33871
33872
  from: "content.seeAllUrl",
33873
+ fallback: "",
33872
33874
  transforms: [{ id: "links.resolve" }]
33873
33875
  } },
33874
33876
  loadMoreText: { $bind: {
@@ -34205,6 +34207,7 @@ const eventCalendarLayout = [styledSection({
34205
34207
  } },
34206
34208
  seeAllUrl: { $bind: {
34207
34209
  from: "content.seeAllUrl",
34210
+ fallback: "",
34208
34211
  transforms: [{ id: "links.resolve" }]
34209
34212
  } },
34210
34213
  loadMoreText: { $bind: {
@@ -41664,15 +41667,15 @@ function Grid({ as: Comp = "div", cols = {
41664
41667
  }
41665
41668
  //#endregion
41666
41669
  //#region ../blocks/src/system/runtime/nodes/layout.tsx
41667
- const SectionNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, allowOverflow, ...props }) => /* @__PURE__ */ jsx(Section, {
41670
+ const SectionNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, allowOverflow, ...props }) => /* @__PURE__ */ jsx(Section, {
41668
41671
  ...props,
41669
41672
  allowOverflow
41670
41673
  });
41671
- const StackNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Stack, { ...props });
41672
- const InlineNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Inline, { ...props });
41673
- const GridNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Grid, { ...props });
41674
- const DivNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx("div", { ...props });
41675
- const FigureNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx("figure", { ...props });
41674
+ const StackNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Stack, { ...props });
41675
+ const InlineNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Inline, { ...props });
41676
+ const GridNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Grid, { ...props });
41677
+ const DivNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx("div", { ...props });
41678
+ const FigureNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx("figure", { ...props });
41676
41679
  //#endregion
41677
41680
  //#region ../path-utils/src/index.ts
41678
41681
  const PATH_SEPARATOR_REGEX$1 = /\./g;
@@ -46920,6 +46923,7 @@ function applyTransformsAndFallback(value, binding, context) {
46920
46923
  viewModel: context.viewModel
46921
46924
  }, transforms);
46922
46925
  if (binding.transforms && binding.transforms.length > 0 && transformed === null) {
46926
+ if (binding.fallback !== void 0) return binding.fallback;
46923
46927
  if (process.env.NODE_ENV === "development") console.warn("[block-system] Transform returned null for binding", {
46924
46928
  bindingFrom: binding.from,
46925
46929
  transforms: binding.transforms?.map((t) => t.id)
@@ -48848,7 +48852,7 @@ function generateHeaderRootStyles(header, themeId, tokens, _theme) {
48848
48852
  }
48849
48853
  }
48850
48854
  if (header.positioning === "sticky" || header.positioning === "fixed") {
48851
- const shadowVar = getComponentShadowVar(header.shadow?.elevation ?? "sm");
48855
+ const shadowVar = getComponentShadowVar(header.shadow?.elevation ?? "none");
48852
48856
  if (shadowVar) rules.push(`box-shadow: ${shadowVar};`);
48853
48857
  }
48854
48858
  const baseBlock = `\n${selector} {\n ${rules.join("\n ")}\n}\n`;
@@ -51700,6 +51704,7 @@ function PageRenderer$1({ theme, page, usePlaceholders = false, dataContext, wra
51700
51704
  const wrapperClassName = [`block-${cleanKind}`, wrapBlock ? "group relative" : null].filter(Boolean).join(" ");
51701
51705
  const styleGroup = typeof renderableContent.styleGroup === "string" ? renderableContent.styleGroup : void 0;
51702
51706
  const blockLook = typeof renderableContent.blockLook === "string" ? renderableContent.blockLook : void 0;
51707
+ const transitionStyle = transitionCssVarsStyle(renderableContent);
51703
51708
  const blockElement = /* @__PURE__ */ jsx("div", {
51704
51709
  className: wrapperClassName,
51705
51710
  "data-block": cleanKind,
@@ -51710,6 +51715,7 @@ function PageRenderer$1({ theme, page, usePlaceholders = false, dataContext, wra
51710
51715
  "data-block-look": blockLook,
51711
51716
  "data-page-block-position": blockPosition,
51712
51717
  "data-style-group": styleGroup,
51718
+ style: transitionStyle,
51713
51719
  children: /* @__PURE__ */ jsx(MemoBlockSection, { ...blockSectionProps })
51714
51720
  }, blockKey);
51715
51721
  if (!isSiteStyleTransitionStyleGroup(styleGroup)) return blockElement;
@@ -51717,13 +51723,25 @@ function PageRenderer$1({ theme, page, usePlaceholders = false, dataContext, wra
51717
51723
  "aria-hidden": "true",
51718
51724
  "data-block-transition": "",
51719
51725
  "data-block-transition-for": block.id ?? blockKey,
51720
- "data-style-group": styleGroup
51726
+ "data-style-group": styleGroup,
51727
+ style: transitionStyle
51721
51728
  })] }, blockKey);
51722
51729
  }) });
51723
51730
  }
51724
51731
  function isSiteStyleTransitionStyleGroup(value) {
51725
51732
  return value?.startsWith("site-style-transition-") === true;
51726
51733
  }
51734
+ function transitionCssVarsStyle(content) {
51735
+ const transitionStyles = isObjectRecord(content._transitionStyles) ? content._transitionStyles : null;
51736
+ const cssVars = isObjectRecord(transitionStyles?.cssVars) ? transitionStyles.cssVars : null;
51737
+ const from = typeof cssVars?.from === "string" ? cssVars.from : null;
51738
+ const to = typeof cssVars?.to === "string" ? cssVars.to : null;
51739
+ if (!from && !to) return void 0;
51740
+ return {
51741
+ ...from ? { "--site-style-transition-from": from } : {},
51742
+ ...to ? { "--site-style-transition-to": to } : {}
51743
+ };
51744
+ }
51727
51745
  function pageBlockPosition(index, blockCount) {
51728
51746
  if (blockCount <= 1) return "only";
51729
51747
  if (index === 0) return "first";
@@ -64913,7 +64931,7 @@ z$1.object({ acceptExtraSiteCharge: z$1.boolean().optional() });
64913
64931
  //#region ../surfaces/src/index.ts
64914
64932
  const SURFACE_IDS = ["core", "macadamia"];
64915
64933
  const DEFAULT_SURFACE_ID = "core";
64916
- SURFACE_IDS.filter((surfaceId) => surfaceId !== DEFAULT_SURFACE_ID);
64934
+ [...SURFACE_IDS.filter((surfaceId) => surfaceId !== DEFAULT_SURFACE_ID)];
64917
64935
  const CANONICAL_REFUND_PLANNER_ERROR_CODES = [
64918
64936
  ...[
64919
64937
  "already_refunded",
@@ -64962,6 +64980,7 @@ const VERTICAL_IDS = [
64962
64980
  "training_provider",
64963
64981
  "retreat_centre",
64964
64982
  "music_school",
64983
+ "voice_singing",
64965
64984
  "performing_arts_school",
64966
64985
  "community_wellbeing",
64967
64986
  "venue_event_space"
@@ -65014,6 +65033,11 @@ const VERTICAL_BOOKING_PRESETS = [
65014
65033
  preset("music_school.terms", "music_school", "course", "Term", "Terms", "Multi-week term blocks or fixed-date group courses."),
65015
65034
  preset("music_school.workshops", "music_school", "workshop", "Workshop", "Workshops", "One-off workshops, masterclasses, or intensives."),
65016
65035
  preset("music_school.performances", "music_school", "performance", "Performance", "Performances", "Concerts, recitals, showcases, or ticketed performances."),
65036
+ preset("voice_singing.lessons", "voice_singing", "appointment", "Voice session", "Voice sessions", "One-to-one singing lessons, voice coaching, or private practice sessions."),
65037
+ preset("voice_singing.classes", "voice_singing", "class", "Ongoing weekly session", "Ongoing weekly sessions", "Regular choirs, voice circles, community singing, or group practice."),
65038
+ preset("voice_singing.terms", "voice_singing", "course", "Singing term", "Singing terms", "Multi-week choir terms, voice courses, or fixed-date group programmes."),
65039
+ preset("voice_singing.workshops", "voice_singing", "workshop", "Workshop", "Workshops", "One-off singing workshops, voice journeys, or devotional singing sessions."),
65040
+ preset("voice_singing.performances", "voice_singing", "performance", "Performance", "Performances", "Choir concerts, sharing events, recitals, or community performances."),
65017
65041
  preset("performing_arts_school.classes", "performing_arts_school", "class", "Class", "Classes", "Regular group classes, rehearsals, or weekly sessions."),
65018
65042
  preset("performing_arts_school.terms", "performing_arts_school", "course", "Term", "Terms", "Multi-week term blocks or fixed-date course groups."),
65019
65043
  preset("performing_arts_school.workshops", "performing_arts_school", "workshop", "Workshop", "Workshops", "One-off workshops, masterclasses, or intensives."),
@@ -11554,6 +11554,7 @@ const themeV2RuntimeStyleFieldNames = [
11554
11554
  "_sectionStyles",
11555
11555
  "_containerStyles",
11556
11556
  "_cardStyles",
11557
+ "_transitionStyles",
11557
11558
  "styleGroup"
11558
11559
  ];
11559
11560
  const themeV2BlockSpecificRawStyleFieldNames = [
@@ -14655,12 +14656,12 @@ const headerStyleCatalog = defineExactCatalog()([
14655
14656
  },
14656
14657
  {
14657
14658
  id: asHeaderStyleId("fine-line"),
14658
- label: "Fine Line",
14659
- description: "Light surface with a crisp lower rule and underline hover.",
14659
+ label: "Seamless",
14660
+ description: "Borderless surface with underline hover for a quieter page transition.",
14660
14661
  supportedLayoutIds: supportedLayouts(["classic", "centered"]),
14661
14662
  navInteraction: "underline-grow",
14662
- surface: "bordered",
14663
- defaultDepth: "line",
14663
+ surface: "neutral",
14664
+ defaultDepth: "none",
14664
14665
  navTypography: "plain",
14665
14666
  moods: [
14666
14667
  "calm",
@@ -34428,6 +34429,7 @@ const eventListingBlockDefinition = {
34428
34429
  } },
34429
34430
  seeAllUrl: { $bind: {
34430
34431
  from: "content.seeAllUrl",
34432
+ fallback: "",
34431
34433
  transforms: [{ id: "links.resolve" }]
34432
34434
  } },
34433
34435
  loadMoreText: { $bind: {
@@ -34764,6 +34766,7 @@ const eventCalendarLayout = [styledSection({
34764
34766
  } },
34765
34767
  seeAllUrl: { $bind: {
34766
34768
  from: "content.seeAllUrl",
34769
+ fallback: "",
34767
34770
  transforms: [{ id: "links.resolve" }]
34768
34771
  } },
34769
34772
  loadMoreText: { $bind: {
@@ -42239,15 +42242,15 @@ function Grid({ as: Comp = "div", cols = {
42239
42242
  }
42240
42243
  //#endregion
42241
42244
  //#region ../blocks/src/system/runtime/nodes/layout.tsx
42242
- const SectionNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, allowOverflow, ...props }) => /* @__PURE__ */ jsx(Section, {
42245
+ const SectionNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, allowOverflow, ...props }) => /* @__PURE__ */ jsx(Section, {
42243
42246
  ...props,
42244
42247
  allowOverflow
42245
42248
  });
42246
- const StackNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Stack, { ...props });
42247
- const InlineNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Inline, { ...props });
42248
- const GridNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Grid, { ...props });
42249
- const DivNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx("div", { ...props });
42250
- const FigureNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx("figure", { ...props });
42249
+ const StackNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Stack, { ...props });
42250
+ const InlineNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Inline, { ...props });
42251
+ const GridNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx(Grid, { ...props });
42252
+ const DivNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx("div", { ...props });
42253
+ const FigureNode = ({ blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, previewAuthoring: _previewAuthoring, pathBase: _pathBase, ...props }) => /* @__PURE__ */ jsx("figure", { ...props });
42251
42254
  //#endregion
42252
42255
  //#region ../path-utils/src/index.ts
42253
42256
  const PATH_SEPARATOR_REGEX$1 = /\./g;
@@ -49968,6 +49971,7 @@ function applyTransformsAndFallback(value, binding, context) {
49968
49971
  viewModel: context.viewModel
49969
49972
  }, transforms);
49970
49973
  if (binding.transforms && binding.transforms.length > 0 && transformed === null) {
49974
+ if (binding.fallback !== void 0) return binding.fallback;
49971
49975
  if (process.env.NODE_ENV === "development") console.warn("[block-system] Transform returned null for binding", {
49972
49976
  bindingFrom: binding.from,
49973
49977
  transforms: binding.transforms?.map((t) => t.id)
@@ -51981,7 +51985,7 @@ function generateHeaderRootStyles(header, themeId, tokens, _theme) {
51981
51985
  }
51982
51986
  }
51983
51987
  if (header.positioning === "sticky" || header.positioning === "fixed") {
51984
- const shadowVar = getComponentShadowVar(header.shadow?.elevation ?? "sm");
51988
+ const shadowVar = getComponentShadowVar(header.shadow?.elevation ?? "none");
51985
51989
  if (shadowVar) rules.push(`box-shadow: ${shadowVar};`);
51986
51990
  }
51987
51991
  const baseBlock = `\n${selector} {\n ${rules.join("\n ")}\n}\n`;
@@ -54833,6 +54837,7 @@ function PageRenderer$1({ theme, page, usePlaceholders = false, dataContext, wra
54833
54837
  const wrapperClassName = [`block-${cleanKind}`, wrapBlock ? "group relative" : null].filter(Boolean).join(" ");
54834
54838
  const styleGroup = typeof renderableContent.styleGroup === "string" ? renderableContent.styleGroup : void 0;
54835
54839
  const blockLook = typeof renderableContent.blockLook === "string" ? renderableContent.blockLook : void 0;
54840
+ const transitionStyle = transitionCssVarsStyle(renderableContent);
54836
54841
  const blockElement = /* @__PURE__ */ jsx("div", {
54837
54842
  className: wrapperClassName,
54838
54843
  "data-block": cleanKind,
@@ -54843,6 +54848,7 @@ function PageRenderer$1({ theme, page, usePlaceholders = false, dataContext, wra
54843
54848
  "data-block-look": blockLook,
54844
54849
  "data-page-block-position": blockPosition,
54845
54850
  "data-style-group": styleGroup,
54851
+ style: transitionStyle,
54846
54852
  children: /* @__PURE__ */ jsx(MemoBlockSection, { ...blockSectionProps })
54847
54853
  }, blockKey);
54848
54854
  if (!isSiteStyleTransitionStyleGroup(styleGroup)) return blockElement;
@@ -54850,13 +54856,25 @@ function PageRenderer$1({ theme, page, usePlaceholders = false, dataContext, wra
54850
54856
  "aria-hidden": "true",
54851
54857
  "data-block-transition": "",
54852
54858
  "data-block-transition-for": block.id ?? blockKey,
54853
- "data-style-group": styleGroup
54859
+ "data-style-group": styleGroup,
54860
+ style: transitionStyle
54854
54861
  })] }, blockKey);
54855
54862
  }) });
54856
54863
  }
54857
54864
  function isSiteStyleTransitionStyleGroup(value) {
54858
54865
  return value?.startsWith("site-style-transition-") === true;
54859
54866
  }
54867
+ function transitionCssVarsStyle(content) {
54868
+ const transitionStyles = isObjectRecord(content._transitionStyles) ? content._transitionStyles : null;
54869
+ const cssVars = isObjectRecord(transitionStyles?.cssVars) ? transitionStyles.cssVars : null;
54870
+ const from = typeof cssVars?.from === "string" ? cssVars.from : null;
54871
+ const to = typeof cssVars?.to === "string" ? cssVars.to : null;
54872
+ if (!from && !to) return void 0;
54873
+ return {
54874
+ ...from ? { "--site-style-transition-from": from } : {},
54875
+ ...to ? { "--site-style-transition-to": to } : {}
54876
+ };
54877
+ }
54860
54878
  function pageBlockPosition(index, blockCount) {
54861
54879
  if (blockCount <= 1) return "only";
54862
54880
  if (index === 0) return "first";
@@ -68301,7 +68319,7 @@ z$1.object({ acceptExtraSiteCharge: z$1.boolean().optional() });
68301
68319
  //#region ../surfaces/src/index.ts
68302
68320
  const SURFACE_IDS = ["core", "macadamia"];
68303
68321
  const DEFAULT_SURFACE_ID = "core";
68304
- SURFACE_IDS.filter((surfaceId) => surfaceId !== DEFAULT_SURFACE_ID);
68322
+ [...SURFACE_IDS.filter((surfaceId) => surfaceId !== DEFAULT_SURFACE_ID)];
68305
68323
  const CANONICAL_REFUND_PLANNER_ERROR_CODES = [
68306
68324
  ...[
68307
68325
  "already_refunded",
@@ -68348,6 +68366,7 @@ const VERTICAL_IDS = [
68348
68366
  "training_provider",
68349
68367
  "retreat_centre",
68350
68368
  "music_school",
68369
+ "voice_singing",
68351
68370
  "performing_arts_school",
68352
68371
  "community_wellbeing",
68353
68372
  "venue_event_space"
@@ -68400,6 +68419,11 @@ const VERTICAL_BOOKING_PRESETS = [
68400
68419
  preset("music_school.terms", "music_school", "course", "Term", "Terms", "Multi-week term blocks or fixed-date group courses."),
68401
68420
  preset("music_school.workshops", "music_school", "workshop", "Workshop", "Workshops", "One-off workshops, masterclasses, or intensives."),
68402
68421
  preset("music_school.performances", "music_school", "performance", "Performance", "Performances", "Concerts, recitals, showcases, or ticketed performances."),
68422
+ preset("voice_singing.lessons", "voice_singing", "appointment", "Voice session", "Voice sessions", "One-to-one singing lessons, voice coaching, or private practice sessions."),
68423
+ preset("voice_singing.classes", "voice_singing", "class", "Ongoing weekly session", "Ongoing weekly sessions", "Regular choirs, voice circles, community singing, or group practice."),
68424
+ preset("voice_singing.terms", "voice_singing", "course", "Singing term", "Singing terms", "Multi-week choir terms, voice courses, or fixed-date group programmes."),
68425
+ preset("voice_singing.workshops", "voice_singing", "workshop", "Workshop", "Workshops", "One-off singing workshops, voice journeys, or devotional singing sessions."),
68426
+ preset("voice_singing.performances", "voice_singing", "performance", "Performance", "Performances", "Choir concerts, sharing events, recitals, or community performances."),
68403
68427
  preset("performing_arts_school.classes", "performing_arts_school", "class", "Class", "Classes", "Regular group classes, rehearsals, or weekly sessions."),
68404
68428
  preset("performing_arts_school.terms", "performing_arts_school", "course", "Term", "Terms", "Multi-week term blocks or fixed-date course groups."),
68405
68429
  preset("performing_arts_school.workshops", "performing_arts_school", "workshop", "Workshop", "Workshops", "One-off workshops, masterclasses, or intensives."),
@@ -4748,6 +4748,7 @@ var init_rawStyleFields = __esmMin((() => {
4748
4748
  "_sectionStyles",
4749
4749
  "_containerStyles",
4750
4750
  "_cardStyles",
4751
+ "_transitionStyles",
4751
4752
  "styleGroup"
4752
4753
  ];
4753
4754
  themeV2BlockSpecificRawStyleFieldNames = [
@@ -8963,12 +8964,12 @@ var init_headerLooks = __esmMin((() => {
8963
8964
  },
8964
8965
  {
8965
8966
  id: asHeaderStyleId("fine-line"),
8966
- label: "Fine Line",
8967
- description: "Light surface with a crisp lower rule and underline hover.",
8967
+ label: "Seamless",
8968
+ description: "Borderless surface with underline hover for a quieter page transition.",
8968
8969
  supportedLayoutIds: supportedLayouts(["classic", "centered"]),
8969
8970
  navInteraction: "underline-grow",
8970
- surface: "bordered",
8971
- defaultDepth: "line",
8971
+ surface: "neutral",
8972
+ defaultDepth: "none",
8972
8973
  navTypography: "plain",
8973
8974
  moods: [
8974
8975
  "calm",
@@ -29684,6 +29685,7 @@ var init_event_listing = __esmMin((() => {
29684
29685
  } },
29685
29686
  seeAllUrl: { $bind: {
29686
29687
  from: "content.seeAllUrl",
29688
+ fallback: "",
29687
29689
  transforms: [{ id: "links.resolve" }]
29688
29690
  } },
29689
29691
  loadMoreText: { $bind: {
@@ -30030,6 +30032,7 @@ var init_event_calendar = __esmMin((() => {
30030
30032
  } },
30031
30033
  seeAllUrl: { $bind: {
30032
30034
  from: "content.seeAllUrl",
30035
+ fallback: "",
30033
30036
  transforms: [{ id: "links.resolve" }]
30034
30037
  } },
30035
30038
  loadMoreText: { $bind: {
@@ -38103,11 +38106,12 @@ var init_siteOnboarding = __esmMin((() => {
38103
38106
  //#region ../api/src/launchReadiness.ts
38104
38107
  var init_launchReadiness = __esmMin((() => {
38105
38108
  init_siteOnboarding();
38106
- })), SURFACE_IDS, DEFAULT_SURFACE_ID;
38109
+ })), SURFACE_IDS, DEFAULT_SURFACE_ID, NAMED_SURFACE_IDS;
38107
38110
  var init_src$1 = __esmMin((() => {
38108
38111
  SURFACE_IDS = ["core", "macadamia"];
38109
38112
  DEFAULT_SURFACE_ID = "core";
38110
- SURFACE_IDS.filter((surfaceId) => surfaceId !== DEFAULT_SURFACE_ID);
38113
+ NAMED_SURFACE_IDS = SURFACE_IDS.filter((surfaceId) => surfaceId !== DEFAULT_SURFACE_ID);
38114
+ [...NAMED_SURFACE_IDS];
38111
38115
  }));
38112
38116
  //#endregion
38113
38117
  //#region ../api/src/url.ts
@@ -38300,6 +38304,7 @@ var init_bookingVerticals = __esmMin((() => {
38300
38304
  "training_provider",
38301
38305
  "retreat_centre",
38302
38306
  "music_school",
38307
+ "voice_singing",
38303
38308
  "performing_arts_school",
38304
38309
  "community_wellbeing",
38305
38310
  "venue_event_space"
@@ -38352,6 +38357,11 @@ var init_bookingVerticals = __esmMin((() => {
38352
38357
  preset("music_school.terms", "music_school", "course", "Term", "Terms", "Multi-week term blocks or fixed-date group courses."),
38353
38358
  preset("music_school.workshops", "music_school", "workshop", "Workshop", "Workshops", "One-off workshops, masterclasses, or intensives."),
38354
38359
  preset("music_school.performances", "music_school", "performance", "Performance", "Performances", "Concerts, recitals, showcases, or ticketed performances."),
38360
+ preset("voice_singing.lessons", "voice_singing", "appointment", "Voice session", "Voice sessions", "One-to-one singing lessons, voice coaching, or private practice sessions."),
38361
+ preset("voice_singing.classes", "voice_singing", "class", "Ongoing weekly session", "Ongoing weekly sessions", "Regular choirs, voice circles, community singing, or group practice."),
38362
+ preset("voice_singing.terms", "voice_singing", "course", "Singing term", "Singing terms", "Multi-week choir terms, voice courses, or fixed-date group programmes."),
38363
+ preset("voice_singing.workshops", "voice_singing", "workshop", "Workshop", "Workshops", "One-off singing workshops, voice journeys, or devotional singing sessions."),
38364
+ preset("voice_singing.performances", "voice_singing", "performance", "Performance", "Performances", "Choir concerts, sharing events, recitals, or community performances."),
38355
38365
  preset("performing_arts_school.classes", "performing_arts_school", "class", "Class", "Classes", "Regular group classes, rehearsals, or weekly sessions."),
38356
38366
  preset("performing_arts_school.terms", "performing_arts_school", "course", "Term", "Terms", "Multi-week term blocks or fixed-date course groups."),
38357
38367
  preset("performing_arts_school.workshops", "performing_arts_school", "workshop", "Workshop", "Workshops", "One-off workshops, masterclasses, or intensives."),