@riverbankcms/sdk 0.76.0 → 0.77.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 (144) hide show
  1. package/dist/{PreviewEditorSidebar-X2HWXFOL.mjs → PreviewEditorSidebar-XSX7QKHQ.mjs} +1019 -442
  2. package/dist/{PreviewEditorUI-AQXIXPOH.mjs → PreviewEditorUI-YZNEZ3QD.mjs} +2 -2
  3. package/dist/SdkPreviewModeRuntime-5FS5E6BI.mjs +8 -0
  4. package/dist/_dts/ai/src/contracts/proposals.d.ts +528 -20
  5. package/dist/_dts/api/src/contentRuntime.d.ts +5 -0
  6. package/dist/_dts/api/src/siteAssets.d.ts +1 -0
  7. package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +26 -2
  8. package/dist/_dts/block-form/src/blockDraftSaveability.d.ts +28 -0
  9. package/dist/_dts/block-form/src/client/index.d.ts +2 -2
  10. package/dist/_dts/block-form/src/index.d.ts +2 -1
  11. package/dist/_dts/block-form/src/widgets/DateField/dateFieldSchema.d.ts +1 -1
  12. package/dist/_dts/block-form/src/widgets/DateTimeField/dateTimeFieldSchema.d.ts +1 -1
  13. package/dist/_dts/block-form/src/widgets/TimeField/timeFieldSchema.d.ts +1 -1
  14. package/dist/_dts/blocks/src/PageRenderer.d.ts +10 -10
  15. package/dist/_dts/blocks/src/client/site-chrome.d.ts +22 -0
  16. package/dist/_dts/blocks/src/customBlockRegistry.d.ts +38 -0
  17. package/dist/_dts/blocks/src/index.d.ts +2 -0
  18. package/dist/_dts/blocks/src/system/blocks/faq.d.ts +20 -2
  19. package/dist/_dts/blocks/src/system/blocks/feature-cards.d.ts +25 -0
  20. package/dist/_dts/blocks/src/system/blocks/index.d.ts +2 -0
  21. package/dist/_dts/blocks/src/system/blocks/intro.d.ts +24 -0
  22. package/dist/_dts/blocks/src/system/blocks/media-text.d.ts +3 -34
  23. package/dist/_dts/blocks/src/system/constants/blockKinds.d.ts +1 -1
  24. package/dist/_dts/blocks/src/system/fields/aspectRatio.d.ts +30 -0
  25. package/dist/_dts/blocks/src/system/fields/boxStyles.d.ts +4 -1
  26. package/dist/_dts/blocks/src/system/fields/ctas.d.ts +7 -0
  27. package/dist/_dts/blocks/src/system/manifest/fieldValidation/index.d.ts +11 -2
  28. package/dist/_dts/blocks/src/system/node/validation-constants.d.ts +1 -1
  29. package/dist/_dts/blocks/src/system/runtime/nodes/accordion.d.ts +2 -0
  30. package/dist/_dts/blocks/src/system/runtime/nodes/accordion.server.d.ts +2 -0
  31. package/dist/_dts/blocks/src/system/runtime/nodes/accordionIconTreatment.d.ts +5 -0
  32. package/dist/_dts/blocks/src/system/transforms/registry/layout.d.ts +1 -0
  33. package/dist/_dts/blocks/src/system/transforms/typed.d.ts +2 -1
  34. package/dist/_dts/content-editor/src/controller/EntryControllerProvider.d.ts +2 -0
  35. package/dist/_dts/content-editor/src/hooks/blockDraftLifecycle.d.ts +48 -0
  36. package/dist/_dts/content-editor/src/hooks/invalidBlockSelectors.d.ts +4 -0
  37. package/dist/_dts/content-editor/src/hooks/publishability.d.ts +47 -0
  38. package/dist/_dts/content-editor/src/index.d.ts +1 -0
  39. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +20 -0
  40. package/dist/_dts/editor-blocks/src/BlockEditor.d.ts +2 -1
  41. package/dist/_dts/editor-blocks/src/block-editor/SortableBlockItem.d.ts +2 -1
  42. package/dist/_dts/editor-blocks/src/block-editor/customBlockRegistry.d.ts +2 -0
  43. package/dist/_dts/editor-blocks/src/block-editor/sdkBlockMerger.d.ts +9 -37
  44. package/dist/_dts/editor-blocks/src/index.d.ts +2 -2
  45. package/dist/_dts/preview-next/src/client/index.d.ts +3 -0
  46. package/dist/_dts/preview-next/src/client/layout/PreviewLayoutContext.d.ts +5 -1
  47. package/dist/_dts/preview-next/src/client/preview/PreviewDesignCoordinatorContext.d.ts +20 -0
  48. package/dist/_dts/preview-next/src/client/preview/PreviewEditorSidebar.d.ts +7 -2
  49. package/dist/_dts/preview-next/src/client/preview/PreviewShell.d.ts +7 -2
  50. package/dist/_dts/preview-next/src/client/preview/PreviewShellLayout.d.ts +7 -2
  51. package/dist/_dts/preview-next/src/client/preview/PreviewThemedSiteDocument.d.ts +18 -0
  52. package/dist/_dts/preview-next/src/client/preview/SiteChromeCustomizeContext.d.ts +20 -3
  53. package/dist/_dts/preview-next/src/client/preview/StyleConfigurator.d.ts +6 -1
  54. package/dist/_dts/preview-next/src/client/preview/StyleConfigurator.state.d.ts +14 -4
  55. package/dist/_dts/preview-next/src/client/preview/previewDesignCoordinator.d.ts +73 -0
  56. package/dist/_dts/preview-next/src/client/preview/siteChromeLookRows.d.ts +12 -4
  57. package/dist/_dts/preview-next/src/client/preview/siteStylePreviewPlanner.d.ts +46 -0
  58. package/dist/_dts/preview-next/src/client/preview/styleConfiguratorSnapshot.d.ts +6 -1
  59. package/dist/_dts/preview-next/src/client/preview/typographySelectionInput.d.ts +14 -0
  60. package/dist/_dts/preview-next/src/client/sdk/SdkPreviewModeRuntime.d.ts +1 -1
  61. package/dist/_dts/sdk/src/cli/commands/style.d.ts +8 -0
  62. package/dist/_dts/sdk/src/client/management/types.d.ts +6 -1
  63. package/dist/_dts/sdk/src/client/types.d.ts +9 -0
  64. package/dist/_dts/sdk/src/client.d.ts +1 -1
  65. package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +35 -0
  66. package/dist/_dts/sdk/src/index.d.ts +2 -1
  67. package/dist/_dts/sdk/src/public-api/contracts.d.ts +5 -0
  68. package/dist/_dts/sdk/src/types/block-kinds.d.ts +1 -1
  69. package/dist/_dts/sdk/src/version.d.ts +1 -1
  70. package/dist/_dts/site-commands/src/commands.d.ts +15 -0
  71. package/dist/_dts/theme-core/src/buttons/personalities/earth-pill.d.ts +16 -0
  72. package/dist/_dts/theme-core/src/buttons/personalities/index.d.ts +11 -0
  73. package/dist/_dts/theme-core/src/fonts/types.d.ts +1 -1
  74. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +45 -0
  75. package/dist/_dts/theme-core/src/palette/variants/index.d.ts +15 -0
  76. package/dist/_dts/theme-core/src/palette/variants/warm-neutral.d.ts +16 -0
  77. package/dist/_dts/theme-core/src/schema.d.ts +280 -0
  78. package/dist/_dts/theme-core/src/site-styles/appearancePresetCatalog.d.ts +81 -0
  79. package/dist/_dts/theme-core/src/site-styles/appearancePresetTypes.d.ts +6 -4
  80. package/dist/_dts/theme-core/src/site-styles/blockAppearancePresets.d.ts +81 -0
  81. package/dist/_dts/theme-core/src/site-styles/curatedSiteStyles.d.ts +118 -2
  82. package/dist/_dts/theme-core/src/site-styles/footerLooks.d.ts +13 -0
  83. package/dist/_dts/theme-core/src/site-styles/generatedSchemas.d.ts +4 -2
  84. package/dist/_dts/theme-core/src/site-styles/headerLooks.d.ts +364 -5
  85. package/dist/_dts/theme-core/src/site-styles/headerOpeningSection.d.ts +6 -0
  86. package/dist/_dts/theme-core/src/site-styles/index.d.ts +2 -0
  87. package/dist/_dts/theme-core/src/site-styles/persistedIdParseResult.d.ts +9 -0
  88. package/dist/_dts/theme-core/src/site-styles/previewCompiler.d.ts +20 -4
  89. package/dist/_dts/theme-core/src/site-styles/types.d.ts +74 -2
  90. package/dist/_dts/theme-core/src/site-styles/typographyPresets.d.ts +189 -0
  91. package/dist/{chunk-Z7JLNTJR.mjs → chunk-6SMUFTXD.mjs} +2 -1
  92. package/dist/{chunk-V5VORNEJ.mjs → chunk-ANKDYZ2E.mjs} +1 -1
  93. package/dist/{chunk-Q4OLG66B.mjs → chunk-EAWHBECW.mjs} +476 -153
  94. package/dist/{chunk-TW2Y4RR5.mjs → chunk-GSQX43EZ.mjs} +383 -51
  95. package/dist/{chunk-LYI7TEMH.mjs → chunk-WLQBJN2Z.mjs} +3096 -354
  96. package/dist/cli/index.mjs +2023 -181
  97. package/dist/client/{accordion-2YHIBOZH.mjs → accordion-RZMQSYLR.mjs} +1 -1
  98. package/dist/client/{bookingForm-35IBDWAS.mjs → bookingForm-NF4ASVNV.mjs} +2 -2
  99. package/dist/client/bookings.mjs +92 -0
  100. package/dist/client/{carousel-K6XG7NZQ.mjs → carousel-LDX47ZIK.mjs} +1 -1
  101. package/dist/client/{cart-HCFYUTTU.mjs → cart-RGXDS5F4.mjs} +3 -3
  102. package/dist/client/{checkout-J3U4XR7K.mjs → checkout-P7WWSNNY.mjs} +3 -3
  103. package/dist/client/{chunk-BOIHIU7E.mjs → chunk-E2TDNXCL.mjs} +1 -1
  104. package/dist/client/{chunk-PFBX3IQL.mjs → chunk-GMVTOKYG.mjs} +2 -2
  105. package/dist/client/{chunk-FGUIVT2B.mjs → chunk-JNC7CGHX.mjs} +1 -1
  106. package/dist/client/{chunk-SNSWVZEP.mjs → chunk-L3DNHIJX.mjs} +3 -3
  107. package/dist/client/{chunk-7UOSCYY4.mjs → chunk-R56FQ3RR.mjs} +92 -0
  108. package/dist/client/{chunk-J227A3CQ.mjs → chunk-UFSWADAO.mjs} +1 -1
  109. package/dist/client/client.mjs +2134 -228
  110. package/dist/client/{courseRegistration-ZBXS7VGI.mjs → courseRegistration-7F65K5ZR.mjs} +2 -2
  111. package/dist/client/{eventCalendar-EQQZHJBA.mjs → eventCalendar-GLSC5KTL.mjs} +4 -4
  112. package/dist/client/{eventCombined-JCFTGBFQ.mjs → eventCombined-ZHK4WKUR.mjs} +4 -4
  113. package/dist/client/{eventDetails-HLUTQSYY.mjs → eventDetails-E3PJYBIN.mjs} +4 -4
  114. package/dist/client/{eventListing-FG4MICVB.mjs → eventListing-EMS3WC3E.mjs} +4 -4
  115. package/dist/client/{eventRegistration-GUEB7LBT.mjs → eventRegistration-NZOTVNPI.mjs} +4 -4
  116. package/dist/client/{form-YQEW4YIT.mjs → form-ETFZFATW.mjs} +1 -1
  117. package/dist/client/{headerSection-GTR3TTRM.mjs → headerSection-4LBP7ULT.mjs} +2 -2
  118. package/dist/client/hooks.mjs +1918 -293
  119. package/dist/client/{locationMap-SPC7VGUH.mjs → locationMap-5M655YSJ.mjs} +1 -1
  120. package/dist/client/{newsletterForm-4IW5BLID.mjs → newsletterForm-QOUYW44O.mjs} +1 -1
  121. package/dist/client/{productDetail-KP5H2WJO.mjs → productDetail-O4DOCWQG.mjs} +3 -3
  122. package/dist/client/{productList-3M3M72XZ.mjs → productList-A5RO5WIS.mjs} +3 -3
  123. package/dist/client/rendering/client.mjs +198 -32
  124. package/dist/client/rendering/islands.mjs +18 -18
  125. package/dist/client/rendering.mjs +2095 -208
  126. package/dist/client/{shop-ACQKVGOM.mjs → shop-L4MZH4I2.mjs} +3 -3
  127. package/dist/preview-next/client/runtime.mjs +4 -4
  128. package/dist/{sdk-runtime-K7HNB4U2.mjs → sdk-runtime-Q6MTR4KL.mjs} +5 -5
  129. package/dist/server/components.mjs +2046 -204
  130. package/dist/server/config-validation.mjs +1921 -293
  131. package/dist/server/config.mjs +1921 -293
  132. package/dist/server/data.mjs +1918 -293
  133. package/dist/server/index.mjs +31 -2
  134. package/dist/server/next.mjs +2067 -206
  135. package/dist/server/page-converter.mjs +1894 -281
  136. package/dist/server/prebuild.mjs +1 -1
  137. package/dist/server/rendering/server.mjs +2046 -204
  138. package/dist/server/rendering.mjs +2046 -204
  139. package/dist/server/routing.mjs +1963 -275
  140. package/dist/server/server.mjs +1932 -288
  141. package/dist/server/theme-bridge.mjs +158 -1
  142. package/dist/server/theme.mjs +158 -1
  143. package/package.json +1 -1
  144. package/dist/SdkPreviewModeRuntime-ZQNDCASH.mjs +0 -8
@@ -7779,6 +7779,9 @@ var manifestSchema = z5.object({
7779
7779
  var TEL_RE = /^[+()0-9\s-]{3,}$/;
7780
7780
  var SLUG_PATTERN = /^(?:[a-z0-9]+(?:-[a-z0-9]+)*)(?:\/(?:[a-z0-9]+(?:-[a-z0-9]+)*))*$/;
7781
7781
  var ALLOWED_URL_PROTOCOLS = ["http:", "https:"];
7782
+ var DATE_PATTERN = /^(?<year>[1-9]\d{3})-(?<month>\d{2})-(?<day>\d{2})$/;
7783
+ var TIME_PATTERN = /^(?<hours>[01]\d|2[0-3]):(?<minutes>[0-5]\d)$/;
7784
+ var DATETIME_PATTERN = /^(?<date>[1-9]\d{3}-\d{2}-\d{2})T(?<time>(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d)(?:\.\d+)?(?<offset>Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/;
7782
7785
  function assertNever(value) {
7783
7786
  throw new Error(`Unhandled field validation variant: ${JSON.stringify(value)}`);
7784
7787
  }
@@ -7811,6 +7814,12 @@ function fieldIssueToMessage(issue2) {
7811
7814
  return "Check the format and try again";
7812
7815
  case "invalidUrl":
7813
7816
  return "Enter a valid web address";
7817
+ case "invalidDate":
7818
+ return "Choose a valid date";
7819
+ case "invalidTime":
7820
+ return "Choose a valid time";
7821
+ case "invalidDateTime":
7822
+ return "Choose a valid date and time";
7814
7823
  case "invalidNumber":
7815
7824
  return `${issue2.label} needs a number`;
7816
7825
  case "tooSmall":
@@ -7847,12 +7856,16 @@ function deriveFieldValidationPlan(field, path = [field.id]) {
7847
7856
  case "text": {
7848
7857
  const inputType = field.ui?.inputType;
7849
7858
  if (inputType === "number") {
7850
- const constraints2 = commonConstraints(required, { kind: "numberType" });
7859
+ const constraints2 = commonConstraints(required, {
7860
+ kind: "numberType"
7861
+ });
7851
7862
  if (typeof field.ui?.min === "number") constraints2.push({ kind: "numberMin", minimum: field.ui.min });
7852
7863
  if (typeof field.ui?.max === "number") constraints2.push({ kind: "numberMax", maximum: field.ui.max });
7853
7864
  return makePlan("number", "number", field, path, required, constraints2);
7854
7865
  }
7855
- const constraints = commonConstraints(required, { kind: "textType" });
7866
+ const constraints = commonConstraints(required, {
7867
+ kind: "textType"
7868
+ });
7856
7869
  if (inputType === "email") constraints.push({ kind: "emailFormat" });
7857
7870
  if (inputType === "tel") constraints.push({ kind: "phoneFormat" });
7858
7871
  if (field.ui?.pattern) constraints.push({ kind: "patternFormat", pattern: field.ui.pattern });
@@ -7860,7 +7873,9 @@ function deriveFieldValidationPlan(field, path = [field.id]) {
7860
7873
  return makePlan("string", "string", field, path, required, constraints);
7861
7874
  }
7862
7875
  case "number": {
7863
- const constraints = commonConstraints(required, { kind: "numberType" });
7876
+ const constraints = commonConstraints(required, {
7877
+ kind: "numberType"
7878
+ });
7864
7879
  if (typeof field.min === "number") constraints.push({ kind: "numberMin", minimum: field.min });
7865
7880
  if (typeof field.max === "number") constraints.push({ kind: "numberMax", maximum: field.max });
7866
7881
  return makePlan("number", "number", field, path, required, constraints);
@@ -7871,23 +7886,42 @@ function deriveFieldValidationPlan(field, path = [field.id]) {
7871
7886
  return makePlan("string", "string", field, path, required, constraints);
7872
7887
  }
7873
7888
  case "url":
7874
- return makePlan("string", "string", field, path, required, commonConstraints(
7889
+ return makePlan(
7890
+ "string",
7891
+ "string",
7892
+ field,
7893
+ path,
7875
7894
  required,
7876
- { kind: "textType" },
7877
- { kind: "urlFormat", allowRelative: Boolean(field.allowRelative) }
7878
- ));
7895
+ commonConstraints(required, { kind: "textType" }, { kind: "urlFormat", allowRelative: Boolean(field.allowRelative) })
7896
+ );
7879
7897
  case "reference":
7880
7898
  return makePlan("string", "string", field, path, required, commonConstraints(required, { kind: "referenceText" }));
7881
7899
  case "date":
7900
+ return makePlan("string", "string", field, path, required, commonConstraints(required, { kind: "textType" }, { kind: "dateFormat" }));
7882
7901
  case "time":
7902
+ return makePlan("string", "string", field, path, required, commonConstraints(required, { kind: "textType" }, { kind: "timeFormat" }));
7883
7903
  case "datetime":
7884
- return makePlan("string", "string", field, path, required, commonConstraints(required, { kind: "textType" }));
7904
+ return makePlan(
7905
+ "string",
7906
+ "string",
7907
+ field,
7908
+ path,
7909
+ required,
7910
+ commonConstraints(required, { kind: "textType" }, { kind: "datetimeFormat" })
7911
+ );
7885
7912
  case "select":
7886
- return makePlan("select", "select", field, path, required, commonConstraints(required, {
7887
- kind: "selectOption",
7888
- source: resolveSelectConstraintSource(field),
7889
- multiple: Boolean(field.multiple)
7890
- }));
7913
+ return makePlan(
7914
+ "select",
7915
+ "select",
7916
+ field,
7917
+ path,
7918
+ required,
7919
+ commonConstraints(required, {
7920
+ kind: "selectOption",
7921
+ source: resolveSelectConstraintSource(field),
7922
+ multiple: Boolean(field.multiple)
7923
+ })
7924
+ );
7891
7925
  case "richText":
7892
7926
  return makePlan("richText", "object", field, path, required, commonConstraints(required, { kind: "richTextDoc" }));
7893
7927
  case "media":
@@ -7900,7 +7934,11 @@ function deriveFieldValidationPlan(field, path = [field.id]) {
7900
7934
  case "repeater":
7901
7935
  return {
7902
7936
  ...makePlan("repeater", "array", field, path, required, commonConstraints(required, { kind: "arrayType" })),
7903
- ...field.polymorphic && field.itemTypes ? { repeatedItemVariants: deriveRepeatedItemVariants(field, [...path, 0]) } : { repeatedItemPlan: deriveNestedFieldPlans(getRepeaterFields(field), [...path, 0]) },
7937
+ ...field.polymorphic && field.itemTypes ? {
7938
+ repeatedItemVariants: deriveRepeatedItemVariants(field, [...path, 0])
7939
+ } : {
7940
+ repeatedItemPlan: deriveNestedFieldPlans(getRepeaterFields(field), [...path, 0])
7941
+ },
7904
7942
  constraints: withRepeaterItemConstraints(field, commonConstraints(required, { kind: "arrayType" }))
7905
7943
  };
7906
7944
  case "group":
@@ -7985,7 +8023,10 @@ function resolveSelectConstraintSource(field) {
7985
8023
  const source = normalizeSelectSource(field);
7986
8024
  switch (source.kind) {
7987
8025
  case "static":
7988
- return { kind: "static", values: field.options.map((option) => option.value) };
8026
+ return {
8027
+ kind: "static",
8028
+ values: field.options.map((option) => option.value)
8029
+ };
7989
8030
  case "site":
7990
8031
  case "sdk":
7991
8032
  return { kind: "runtime", source: source.kind };
@@ -8081,7 +8122,9 @@ function normalizeFieldValue(plan, value, ctx) {
8081
8122
  }
8082
8123
  function normalizeObjectChildren(children, value, ctx) {
8083
8124
  if (!value || typeof value !== "object" || Array.isArray(value)) return value;
8084
- const normalized = { ...value };
8125
+ const normalized = {
8126
+ ...value
8127
+ };
8085
8128
  for (const child of children) {
8086
8129
  normalized[child.fieldId] = normalizeFieldValue(child, normalized[child.fieldId], ctx);
8087
8130
  }
@@ -8175,6 +8218,12 @@ function validateStringConstraint(plan, constraint, value) {
8175
8218
  }
8176
8219
  case "urlFormat":
8177
8220
  return isValidUrl(value, constraint.allowRelative) ? [] : [issue(plan, "invalidUrl")];
8221
+ case "dateFormat":
8222
+ return isValidDateString(value) ? [] : [issue(plan, "invalidDate")];
8223
+ case "timeFormat":
8224
+ return isValidTimeString(value) ? [] : [issue(plan, "invalidTime")];
8225
+ case "datetimeFormat":
8226
+ return isValidDateTimeInstantString(value) ? [] : [issue(plan, "invalidDateTime")];
8178
8227
  case "slugFormat":
8179
8228
  return SLUG_PATTERN.test(value) ? [] : [issue(plan, "invalidSlug")];
8180
8229
  default:
@@ -8211,17 +8260,24 @@ function validateRepeaterPlan(plan, value, ctx) {
8211
8260
  case "arrayType":
8212
8261
  return [];
8213
8262
  case "minItems":
8214
- return value.length < constraint.minimum ? [issue(plan, "tooFewItems", { minimum: constraint.minimum, itemLabel: "item" })] : [];
8263
+ return value.length < constraint.minimum ? [
8264
+ issue(plan, "tooFewItems", {
8265
+ minimum: constraint.minimum,
8266
+ itemLabel: "item"
8267
+ })
8268
+ ] : [];
8215
8269
  case "maxItems":
8216
- return value.length > constraint.maximum ? [issue(plan, "tooManyItems", { maximum: constraint.maximum, itemLabel: "item" })] : [];
8270
+ return value.length > constraint.maximum ? [
8271
+ issue(plan, "tooManyItems", {
8272
+ maximum: constraint.maximum,
8273
+ itemLabel: "item"
8274
+ })
8275
+ ] : [];
8217
8276
  default:
8218
8277
  return assertNever(constraint);
8219
8278
  }
8220
8279
  });
8221
- return [
8222
- ...constraintIssues,
8223
- ...value.flatMap((item, index) => validateRepeaterItem(plan, item, index, ctx))
8224
- ];
8280
+ return [...constraintIssues, ...value.flatMap((item, index) => validateRepeaterItem(plan, item, index, ctx))];
8225
8281
  }
8226
8282
  function validateRepeaterItem(plan, item, index, ctx) {
8227
8283
  if (!isPlainObject(item)) return [];
@@ -8264,9 +8320,7 @@ function rebaseFieldPlanPath(plan, fromPrefix, toPrefix) {
8264
8320
  }))
8265
8321
  } : {},
8266
8322
  ...plan.repeatedItemPlan ? {
8267
- repeatedItemPlan: plan.repeatedItemPlan.map(
8268
- (fieldPlan) => rebaseFieldPlanPath(fieldPlan, fromPrefix, toPrefix)
8269
- )
8323
+ repeatedItemPlan: plan.repeatedItemPlan.map((fieldPlan) => rebaseFieldPlanPath(fieldPlan, fromPrefix, toPrefix))
8270
8324
  } : {}
8271
8325
  };
8272
8326
  case "string":
@@ -8353,6 +8407,9 @@ function addFieldIssueToZodContext(zodCtx, validationIssue, rootPath) {
8353
8407
  case "invalidPhone":
8354
8408
  case "invalidPattern":
8355
8409
  case "invalidUrl":
8410
+ case "invalidDate":
8411
+ case "invalidTime":
8412
+ case "invalidDateTime":
8356
8413
  case "invalidNumber":
8357
8414
  case "tooSmall":
8358
8415
  case "tooLarge":
@@ -8392,6 +8449,53 @@ function isValidUrl(value, allowRelative) {
8392
8449
  return false;
8393
8450
  }
8394
8451
  }
8452
+ function isValidDateString(value) {
8453
+ const match = DATE_PATTERN.exec(value);
8454
+ if (!match?.groups) return false;
8455
+ const year = Number(match.groups.year);
8456
+ const month = Number(match.groups.month);
8457
+ const day = Number(match.groups.day);
8458
+ return isValidCalendarDate(year, month, day);
8459
+ }
8460
+ function isValidTimeString(value) {
8461
+ return TIME_PATTERN.test(value);
8462
+ }
8463
+ function isValidDateTimeInstantString(value) {
8464
+ const match = DATETIME_PATTERN.exec(value);
8465
+ if (!match?.groups) return false;
8466
+ const datePart = match.groups.date;
8467
+ if (!datePart || !isValidDateString(datePart)) return false;
8468
+ return !Number.isNaN(Date.parse(value));
8469
+ }
8470
+ function isValidCalendarDate(year, month, day) {
8471
+ if (!Number.isInteger(year) || !Number.isInteger(month) || !Number.isInteger(day)) return false;
8472
+ if (year < 1 || month < 1 || month > 12) return false;
8473
+ return day >= 1 && day <= daysInMonth(year, month);
8474
+ }
8475
+ function daysInMonth(year, month) {
8476
+ switch (month) {
8477
+ case 2:
8478
+ return isLeapYear(year) ? 29 : 28;
8479
+ case 4:
8480
+ case 6:
8481
+ case 9:
8482
+ case 11:
8483
+ return 30;
8484
+ case 1:
8485
+ case 3:
8486
+ case 5:
8487
+ case 7:
8488
+ case 8:
8489
+ case 10:
8490
+ case 12:
8491
+ return 31;
8492
+ default:
8493
+ return 0;
8494
+ }
8495
+ }
8496
+ function isLeapYear(year) {
8497
+ return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
8498
+ }
8395
8499
  function isValidSelectValue(value, values, multiple) {
8396
8500
  if (multiple) {
8397
8501
  return Array.isArray(value) && value.every((item) => typeof item === "string" && values.includes(item));
@@ -8751,6 +8855,47 @@ var eyebrowTreatmentValues = [
8751
8855
  "pill-bounce",
8752
8856
  "accent-pill-bounce"
8753
8857
  ];
8858
+ var visibleHeadingDecorationFamilyValues = [
8859
+ "organic-squiggle",
8860
+ "short-center-rule"
8861
+ ];
8862
+ var visibleHeadingDecorationPlacementValues = [
8863
+ "after-heading",
8864
+ "between-heading-and-body",
8865
+ "under-centered-heading"
8866
+ ];
8867
+ var headingDecorationOverrideValues = [
8868
+ "site-default",
8869
+ "on",
8870
+ "off"
8871
+ ];
8872
+ var headingDecorationColorTokenValues = [
8873
+ "text",
8874
+ "primary",
8875
+ "secondary",
8876
+ "accent",
8877
+ "border",
8878
+ "muted"
8879
+ ];
8880
+ var accordionIconSetValues = [
8881
+ "plus",
8882
+ "chevron",
8883
+ "caret",
8884
+ "minimal-cross"
8885
+ ];
8886
+ var accordionIconColorTokenValues = [
8887
+ "text",
8888
+ "muted",
8889
+ "primary",
8890
+ "secondary",
8891
+ "accent",
8892
+ "current"
8893
+ ];
8894
+ var accordionIconMotionValues = [
8895
+ "none",
8896
+ "rotate",
8897
+ "swap"
8898
+ ];
8754
8899
  function defineBlockDesignCapability(capability) {
8755
8900
  return {
8756
8901
  ...capability,
@@ -8760,7 +8905,9 @@ function defineBlockDesignCapability(capability) {
8760
8905
  imageSurfaceMotions: capability.imageSurfaceMotions ?? ["static"],
8761
8906
  testimonialCardTreatments: capability.testimonialCardTreatments ?? ["default"],
8762
8907
  tileTreatments: capability.tileTreatments ?? ["default"],
8763
- eyebrowTreatments: capability.eyebrowTreatments ?? ["plain"]
8908
+ eyebrowTreatments: capability.eyebrowTreatments ?? ["plain"],
8909
+ ...capability.headingDecorations ? { headingDecorations: capability.headingDecorations } : {},
8910
+ ...capability.accordionIconSets ? { accordionIconSets: capability.accordionIconSets } : {}
8764
8911
  };
8765
8912
  }
8766
8913
 
@@ -8951,6 +9098,25 @@ var blockAppearancePresets = [
8951
9098
  emphasis: "high"
8952
9099
  }
8953
9100
  }),
9101
+ defineBlockAppearancePreset({
9102
+ kind: "block-design",
9103
+ id: "intro-soft-earth-statement",
9104
+ target: "intro",
9105
+ label: "Soft Earth intro statement",
9106
+ blockKinds: ["block.intro"],
9107
+ design: {
9108
+ sectionSurface: "base",
9109
+ contentFrame: plainFrame,
9110
+ itemSurface: "none",
9111
+ transitionAfter: "soft-fade-short",
9112
+ emphasis: "high",
9113
+ headingDecoration: {
9114
+ family: "organic-squiggle",
9115
+ placement: "after-heading",
9116
+ colorToken: "primary"
9117
+ }
9118
+ }
9119
+ }),
8954
9120
  defineBlockAppearancePreset({
8955
9121
  kind: "block-design",
8956
9122
  id: "offerings-calm-list",
@@ -8965,6 +9131,25 @@ var blockAppearancePresets = [
8965
9131
  emphasis: "medium"
8966
9132
  }
8967
9133
  }),
9134
+ defineBlockAppearancePreset({
9135
+ kind: "block-design",
9136
+ id: "feature-cards-soft-earth-offerings",
9137
+ target: "feature-cards",
9138
+ label: "Soft Earth offering cards",
9139
+ blockKinds: ["block.feature-cards"],
9140
+ design: {
9141
+ sectionSurface: "base",
9142
+ contentFrame: plainFrame,
9143
+ itemSurface: "raised",
9144
+ transitionAfter: "none",
9145
+ emphasis: "high",
9146
+ headingDecoration: {
9147
+ family: "short-center-rule",
9148
+ placement: "under-centered-heading",
9149
+ colorToken: "primary"
9150
+ }
9151
+ }
9152
+ }),
8968
9153
  defineBlockAppearancePreset({
8969
9154
  kind: "block-design",
8970
9155
  id: "events-base-calendar",
@@ -9093,6 +9278,26 @@ var blockAppearancePresets = [
9093
9278
  testimonialCardTreatment: "accent-quote"
9094
9279
  }
9095
9280
  }),
9281
+ defineBlockAppearancePreset({
9282
+ kind: "block-design",
9283
+ id: "testimonials-soft-earth-proof-band",
9284
+ target: "testimonials",
9285
+ label: "Soft Earth proof band",
9286
+ blockKinds: ["block.testimonials"],
9287
+ design: {
9288
+ sectionSurface: "brand-depth-band",
9289
+ contentFrame: plainFrame,
9290
+ itemSurface: "none",
9291
+ transitionAfter: "soft-fade-short",
9292
+ emphasis: "high",
9293
+ testimonialCardTreatment: "accent-quote",
9294
+ headingDecoration: {
9295
+ family: "short-center-rule",
9296
+ placement: "under-centered-heading",
9297
+ colorToken: "border"
9298
+ }
9299
+ }
9300
+ }),
9096
9301
  defineBlockAppearancePreset({
9097
9302
  kind: "block-design",
9098
9303
  id: "faq-base-accordion",
@@ -9121,6 +9326,25 @@ var blockAppearancePresets = [
9121
9326
  emphasis: "low"
9122
9327
  }
9123
9328
  }),
9329
+ defineBlockAppearancePreset({
9330
+ kind: "block-design",
9331
+ id: "faq-soft-earth-two-column",
9332
+ target: "faq",
9333
+ label: "Soft Earth two-column FAQ",
9334
+ blockKinds: ["block.faq"],
9335
+ design: {
9336
+ sectionSurface: "base",
9337
+ contentFrame: plainFrame,
9338
+ itemSurface: "flat",
9339
+ transitionAfter: "none",
9340
+ emphasis: "medium",
9341
+ accordionIconTreatment: {
9342
+ iconSet: "plus",
9343
+ colorToken: "primary",
9344
+ motion: "swap"
9345
+ }
9346
+ }
9347
+ }),
9124
9348
  defineBlockAppearancePreset({
9125
9349
  kind: "block-design",
9126
9350
  id: "contact-form-panel",
@@ -9816,6 +10040,97 @@ var confidentChip = defineButtonPersonality({
9816
10040
  }
9817
10041
  });
9818
10042
 
10043
+ // ../theme-core/src/buttons/personalities/earth-pill.ts
10044
+ var earthPill = defineButtonPersonality({
10045
+ id: "earth-pill",
10046
+ name: "Earth Pill",
10047
+ description: "Compact terracotta pills with quiet primary-coloured ghost CTAs.",
10048
+ tags: { tone: "classic", energy: "calm", motion: "subtle", era: "organic" },
10049
+ buttonSystem: {
10050
+ global: {
10051
+ cornerStyle: "pill",
10052
+ shadow: "low",
10053
+ textTransform: "none",
10054
+ fontWeight: 500,
10055
+ borderWidth: 1,
10056
+ hoverTransform: "lift",
10057
+ hoverColor: "none",
10058
+ typography: "body",
10059
+ paddingPreset: "default"
10060
+ },
10061
+ sizes: {
10062
+ sm: { padding: "0.5rem 1rem", fontSize: "text-sm" },
10063
+ md: { padding: "0.625rem 1.35rem" },
10064
+ lg: { padding: "0.75rem 1.65rem", fontSize: "text-lg" },
10065
+ xl: { padding: "0.875rem 2rem", fontSize: "text-xl" }
10066
+ },
10067
+ variants: [
10068
+ {
10069
+ id: "primary",
10070
+ name: "Primary",
10071
+ enabled: true,
10072
+ priority: 1,
10073
+ background: { type: "solid", colorToken: "primary" },
10074
+ textColorToken: "primaryForeground",
10075
+ borderRadius: "rounded-full",
10076
+ shadow: { elevation: "low", softness: "soft", position: "bottom" },
10077
+ effects: {
10078
+ hover: [
10079
+ { effectId: "lift", options: { translateY: "-1px" } },
10080
+ { effectId: "background-on-hover", options: { colorToken: "accent" } }
10081
+ ],
10082
+ active: [{ effectId: "scale-down", options: { scale: "0.98" } }]
10083
+ }
10084
+ },
10085
+ {
10086
+ id: "secondary",
10087
+ name: "Secondary",
10088
+ enabled: true,
10089
+ priority: 2,
10090
+ background: { type: "transparent" },
10091
+ textColorToken: "primary",
10092
+ borderRadius: "rounded-full",
10093
+ border: { widthClass: "border", colorToken: "primary" },
10094
+ effects: {
10095
+ hover: [{ effectId: "background-on-hover", options: { colorToken: "muted" } }]
10096
+ }
10097
+ },
10098
+ {
10099
+ id: "outline",
10100
+ name: "Outline",
10101
+ enabled: true,
10102
+ priority: 3,
10103
+ background: { type: "transparent" },
10104
+ textColorToken: "text",
10105
+ borderRadius: "rounded-full",
10106
+ border: { widthClass: "border", colorToken: "border" },
10107
+ effects: {
10108
+ hover: [{ effectId: "background-on-hover", options: { colorToken: "surfaceAlt" } }]
10109
+ }
10110
+ },
10111
+ {
10112
+ id: "ghost",
10113
+ name: "Ghost",
10114
+ enabled: true,
10115
+ priority: 3,
10116
+ background: { type: "transparent" },
10117
+ textColorToken: "primary",
10118
+ borderRadius: "rounded-full",
10119
+ shadow: { elevation: "none", softness: null, position: "bottom" },
10120
+ sizes: {
10121
+ sm: { padding: "0.25rem 0", fontSize: "text-sm" },
10122
+ md: { padding: "0.375rem 0" },
10123
+ lg: { padding: "0.5rem 0", fontSize: "text-lg" },
10124
+ xl: { padding: "0.625rem 0", fontSize: "text-xl" }
10125
+ },
10126
+ effects: {
10127
+ hover: [{ effectId: "opacity-reduce", options: { reduction: 25 } }]
10128
+ }
10129
+ }
10130
+ ]
10131
+ }
10132
+ });
10133
+
9819
10134
  // ../theme-core/src/buttons/personalities/editorial-link.ts
9820
10135
  var editorialLink = defineButtonPersonality({
9821
10136
  id: "editorial-link",
@@ -10274,6 +10589,7 @@ var softPill = defineButtonPersonality({
10274
10589
  // ../theme-core/src/buttons/personalities/index.ts
10275
10590
  var buttonPersonalities = [
10276
10591
  softPill,
10592
+ earthPill,
10277
10593
  confidentChip,
10278
10594
  editorialLink,
10279
10595
  pebble,
@@ -13031,12 +13347,36 @@ var boxBackgroundSchema = z24.object({
13031
13347
  textColor: tokenOrCssColorValueSchema.nullable().optional(),
13032
13348
  headingColor: tokenOrCssColorValueSchema.nullable().optional()
13033
13349
  });
13350
+ var noHeadingDecorationSchema = z24.object({
13351
+ family: z24.literal("none"),
13352
+ placement: z24.literal("none")
13353
+ });
13354
+ var visibleHeadingDecorationSchema = z24.object({
13355
+ family: z24.enum(visibleHeadingDecorationFamilyValues),
13356
+ placement: z24.enum(visibleHeadingDecorationPlacementValues),
13357
+ colorToken: z24.enum(headingDecorationColorTokenValues).optional()
13358
+ });
13359
+ var headingDecorationSchema = z24.union([
13360
+ noHeadingDecorationSchema,
13361
+ visibleHeadingDecorationSchema
13362
+ ]);
13363
+ var accordionIconTreatmentSchema = z24.object({
13364
+ iconSet: z24.enum(accordionIconSetValues),
13365
+ colorToken: z24.enum(accordionIconColorTokenValues),
13366
+ openColorToken: z24.enum(accordionIconColorTokenValues).optional(),
13367
+ motion: z24.enum(accordionIconMotionValues)
13368
+ });
13034
13369
  var sectionStylesOverrideSchema = z24.object({
13035
13370
  background: boxBackgroundSchema.nullable().optional(),
13036
13371
  spacing: semanticSpacingSchema.nullable().optional(),
13037
13372
  minHeight: z24.enum(["none", "banner", "hero", "immersive"]).nullable().optional(),
13038
13373
  tileTreatment: z24.enum(tileTreatmentValues).nullable().optional(),
13039
- eyebrowTreatment: z24.enum(eyebrowTreatmentValues).nullable().optional()
13374
+ eyebrowTreatment: z24.enum(eyebrowTreatmentValues).nullable().optional(),
13375
+ headingDecoration: headingDecorationSchema.nullable().optional(),
13376
+ // Author-level override consumed by later block/editor rendering phases.
13377
+ // Keeping it in section styles lets existing block save APIs persist it.
13378
+ headingDecorationOverride: z24.enum(headingDecorationOverrideValues).nullable().optional(),
13379
+ accordionIconTreatment: accordionIconTreatmentSchema.nullable().optional()
13040
13380
  });
13041
13381
  var containerStylesOverrideSchema = z24.object({
13042
13382
  background: boxBackgroundSchema.nullable().optional(),
@@ -13744,6 +14084,28 @@ var warmNeutralCream = definePaletteVariant({
13744
14084
  { name: "border", hex: "#e0d2b8" }
13745
14085
  ]
13746
14086
  });
14087
+ var warmNeutralSoftEarth = definePaletteVariant({
14088
+ id: "warm-neutral-soft-earth",
14089
+ name: "Warm Neutral \u2014 Soft Earth",
14090
+ description: "Cream ground with terracotta primary, clay accents, and olive depth.",
14091
+ tags: { tone: "classic", energy: "calm", era: "organic" },
14092
+ mode: "light",
14093
+ colors: [
14094
+ { name: "primary", hex: "#a8573d" },
14095
+ { name: "secondary", hex: "#72765c" },
14096
+ { name: "accent", hex: "#c87557" },
14097
+ { name: "success", hex: "#687854" },
14098
+ { name: "warning", hex: "#b7863e" },
14099
+ { name: "destructive", hex: "#a54b3c" },
14100
+ { name: "background", hex: "#fbf6eb" },
14101
+ { name: "surface", hex: "#fffdf7" },
14102
+ { name: "surfaceAlt", hex: "#f0e4d3" },
14103
+ { name: "muted", hex: "#eadbc6" },
14104
+ { name: "text", hex: "#30281f" },
14105
+ { name: "primaryForeground", hex: "#fffaf3" },
14106
+ { name: "border", hex: "#d9c8b2" }
14107
+ ]
14108
+ });
13747
14109
  var warmNeutralForest = definePaletteVariant({
13748
14110
  id: "warm-neutral-forest",
13749
14111
  name: "Warm Neutral \u2014 Forest",
@@ -13777,6 +14139,7 @@ var paletteVariants = [
13777
14139
  // Warm-neutral family
13778
14140
  warmNeutralClay,
13779
14141
  warmNeutralCream,
14142
+ warmNeutralSoftEarth,
13780
14143
  warmNeutralForest,
13781
14144
  // High-contrast family
13782
14145
  highContrastInk,
@@ -13795,6 +14158,12 @@ var paletteVariantsById = new Map(
13795
14158
  function asHeaderLookId(value) {
13796
14159
  return value;
13797
14160
  }
14161
+ function asHeaderLayoutId(value) {
14162
+ return value;
14163
+ }
14164
+ function asHeaderStyleId(value) {
14165
+ return value;
14166
+ }
13798
14167
  function baseHeader(theme) {
13799
14168
  const {
13800
14169
  navLinkStyle: _navLinkStyle,
@@ -13813,6 +14182,309 @@ function baseHeader(theme) {
13813
14182
  navContainer: { type: "none", tint: null, opacity: 0.15 }
13814
14183
  };
13815
14184
  }
14185
+ var headerLayoutCatalog = [
14186
+ {
14187
+ id: asHeaderLayoutId("classic"),
14188
+ label: "Classic",
14189
+ description: "Logo and navigation in one practical horizontal row.",
14190
+ structure: "inline-classic",
14191
+ variant: "classic",
14192
+ defaultPositioning: "sticky",
14193
+ shrinkOnScroll: false
14194
+ },
14195
+ {
14196
+ id: asHeaderLayoutId("centered"),
14197
+ label: "Centered",
14198
+ description: "Logo centered above a balanced navigation row.",
14199
+ structure: "centered-stack",
14200
+ variant: "centered",
14201
+ defaultPositioning: "static",
14202
+ shrinkOnScroll: false,
14203
+ maxRecommendedNavItems: 5,
14204
+ allowedLogoShapes: ["none", "text-only", "horizontal", "square"]
14205
+ },
14206
+ {
14207
+ id: asHeaderLayoutId("editorial"),
14208
+ label: "Editorial",
14209
+ description: "A composed, magazine-like stacked header treatment.",
14210
+ structure: "editorial-stack",
14211
+ variant: "editorial",
14212
+ defaultPositioning: "static",
14213
+ shrinkOnScroll: false,
14214
+ maxRecommendedNavItems: 6
14215
+ },
14216
+ {
14217
+ id: asHeaderLayoutId("floating"),
14218
+ label: "Floating",
14219
+ description: "Detached header chrome that sits over the opening section.",
14220
+ structure: "floating-shell",
14221
+ variant: "floating",
14222
+ defaultPositioning: "fixed",
14223
+ shrinkOnScroll: true,
14224
+ maxRecommendedNavItems: 5,
14225
+ allowedLogoShapes: ["none", "text-only", "horizontal"]
14226
+ }
14227
+ ];
14228
+ function supportedLayouts(ids) {
14229
+ return ids.map(asHeaderLayoutId);
14230
+ }
14231
+ var headerStyleCatalog = [
14232
+ {
14233
+ id: asHeaderStyleId("minimal"),
14234
+ label: "Minimal",
14235
+ description: "Quiet surface with simple color-change navigation.",
14236
+ supportedLayoutIds: supportedLayouts(["classic", "centered", "editorial"]),
14237
+ navInteraction: "color-change",
14238
+ surface: "neutral"
14239
+ },
14240
+ {
14241
+ id: asHeaderStyleId("fine-line"),
14242
+ label: "Fine Line",
14243
+ description: "Light surface with a crisp lower rule and underline hover.",
14244
+ supportedLayoutIds: supportedLayouts(["classic", "centered", "editorial"]),
14245
+ navInteraction: "underline-grow",
14246
+ surface: "bordered"
14247
+ },
14248
+ {
14249
+ id: asHeaderStyleId("soft-bar"),
14250
+ label: "Soft Bar",
14251
+ description: "Soft tinted surface with gentle pill hover states.",
14252
+ supportedLayoutIds: supportedLayouts(["classic", "centered"]),
14253
+ navInteraction: "pill-background",
14254
+ surface: "soft"
14255
+ },
14256
+ {
14257
+ id: asHeaderStyleId("pill-nav"),
14258
+ label: "Pill Nav",
14259
+ description: "A calm pill navigation rail over a neutral header.",
14260
+ supportedLayoutIds: supportedLayouts(["classic", "centered"]),
14261
+ navInteraction: "pill-background",
14262
+ surface: "soft"
14263
+ },
14264
+ {
14265
+ id: asHeaderStyleId("brand-bar"),
14266
+ label: "Brand Bar",
14267
+ description: "Solid brand surface with high-contrast navigation.",
14268
+ supportedLayoutIds: supportedLayouts(["classic", "centered", "editorial"]),
14269
+ navInteraction: "color-change",
14270
+ surface: "brand-solid"
14271
+ },
14272
+ {
14273
+ id: asHeaderStyleId("brand-underline"),
14274
+ label: "Brand Underline",
14275
+ description: "Brand surface with underline-grow navigation.",
14276
+ supportedLayoutIds: supportedLayouts(["classic", "editorial"]),
14277
+ navInteraction: "underline-grow",
14278
+ surface: "brand-solid"
14279
+ },
14280
+ {
14281
+ id: asHeaderStyleId("brand-pill"),
14282
+ label: "Brand Pill",
14283
+ description: "Solid brand surface with rounded active and hover states.",
14284
+ supportedLayoutIds: supportedLayouts(["classic", "centered", "floating"]),
14285
+ navInteraction: "pill-background",
14286
+ surface: "brand-solid"
14287
+ },
14288
+ {
14289
+ id: asHeaderStyleId("editorial-line"),
14290
+ label: "Editorial Line",
14291
+ description: "Typographic logo treatment with understated underline navigation.",
14292
+ supportedLayoutIds: supportedLayouts(["classic", "centered", "editorial"]),
14293
+ navInteraction: "underline-grow",
14294
+ surface: "bordered"
14295
+ },
14296
+ {
14297
+ id: asHeaderStyleId("flat-tabs"),
14298
+ label: "Flat Tabs",
14299
+ description: "Flat block hover and active states with a Swiss utility feel.",
14300
+ supportedLayoutIds: supportedLayouts(["classic", "centered", "editorial"]),
14301
+ navInteraction: "flat-block",
14302
+ surface: "bordered"
14303
+ },
14304
+ {
14305
+ id: asHeaderStyleId("glass"),
14306
+ label: "Glass",
14307
+ description: "Floating translucent chrome with frosted navigation backing.",
14308
+ supportedLayoutIds: supportedLayouts(["floating"]),
14309
+ navInteraction: "glass-backed",
14310
+ surface: "floating",
14311
+ requiresFloatingLayout: true
14312
+ },
14313
+ {
14314
+ id: asHeaderStyleId("minimal-surface"),
14315
+ label: "Minimal Surface",
14316
+ description: "Floating chrome with a restrained translucent surface.",
14317
+ supportedLayoutIds: supportedLayouts(["floating"]),
14318
+ navInteraction: "color-change",
14319
+ surface: "floating",
14320
+ requiresFloatingLayout: true
14321
+ },
14322
+ {
14323
+ id: asHeaderStyleId("soft-shell"),
14324
+ label: "Soft Shell",
14325
+ description: "Floating rounded shell with soft pill navigation states.",
14326
+ supportedLayoutIds: supportedLayouts(["floating"]),
14327
+ navInteraction: "pill-background",
14328
+ surface: "floating",
14329
+ requiresFloatingLayout: true
14330
+ }
14331
+ ];
14332
+ var headerLayoutsById = new Map(
14333
+ headerLayoutCatalog.map((layout) => [layout.id, layout])
14334
+ );
14335
+ var headerStylesById = new Map(
14336
+ headerStyleCatalog.map((style) => [style.id, style])
14337
+ );
14338
+ var headerStyleCompatibilityOrder = /* @__PURE__ */ new Map([
14339
+ [
14340
+ asHeaderLayoutId("classic"),
14341
+ headerStyleRepairChain([
14342
+ "minimal",
14343
+ "fine-line",
14344
+ "soft-bar",
14345
+ "pill-nav",
14346
+ "brand-bar",
14347
+ "brand-underline",
14348
+ "brand-pill",
14349
+ "editorial-line",
14350
+ "flat-tabs"
14351
+ ])
14352
+ ],
14353
+ [
14354
+ asHeaderLayoutId("centered"),
14355
+ headerStyleRepairChain([
14356
+ "minimal",
14357
+ "fine-line",
14358
+ "soft-bar",
14359
+ "pill-nav",
14360
+ "brand-bar",
14361
+ "brand-pill",
14362
+ "editorial-line",
14363
+ "flat-tabs"
14364
+ ])
14365
+ ],
14366
+ [
14367
+ asHeaderLayoutId("editorial"),
14368
+ headerStyleRepairChain([
14369
+ "minimal",
14370
+ "fine-line",
14371
+ "soft-bar",
14372
+ "brand-bar",
14373
+ "brand-underline",
14374
+ "editorial-line",
14375
+ "flat-tabs"
14376
+ ])
14377
+ ],
14378
+ [
14379
+ asHeaderLayoutId("floating"),
14380
+ headerStyleRepairChain([
14381
+ "glass",
14382
+ "minimal-surface",
14383
+ "soft-shell",
14384
+ "brand-pill"
14385
+ ])
14386
+ ]
14387
+ ]);
14388
+ function headerStyleRepairChain(values) {
14389
+ return values.map(asHeaderStyleId);
14390
+ }
14391
+ var headerStyleRepairOrder = /* @__PURE__ */ new Map([
14392
+ [asHeaderStyleId("brand-bar"), headerStyleRepairChain(["brand-bar", "brand-pill", "minimal"])],
14393
+ [asHeaderStyleId("brand-underline"), headerStyleRepairChain(["editorial-line", "fine-line", "minimal"])],
14394
+ [asHeaderStyleId("brand-pill"), headerStyleRepairChain(["brand-pill", "brand-bar", "minimal"])],
14395
+ [asHeaderStyleId("pill-nav"), headerStyleRepairChain(["pill-nav", "soft-bar", "minimal"])],
14396
+ [asHeaderStyleId("flat-tabs"), headerStyleRepairChain(["flat-tabs", "pill-nav", "minimal"])],
14397
+ [asHeaderStyleId("editorial-line"), headerStyleRepairChain(["editorial-line", "fine-line", "minimal"])],
14398
+ [asHeaderStyleId("glass"), headerStyleRepairChain(["glass", "minimal-surface", "minimal"])],
14399
+ [asHeaderStyleId("soft-shell"), headerStyleRepairChain(["soft-shell", "soft-bar", "minimal"])],
14400
+ [asHeaderStyleId("minimal-surface"), headerStyleRepairChain(["minimal-surface", "minimal"])],
14401
+ [asHeaderStyleId("fine-line"), headerStyleRepairChain(["fine-line", "minimal"])],
14402
+ [asHeaderStyleId("soft-bar"), headerStyleRepairChain(["soft-bar", "minimal"])],
14403
+ [asHeaderStyleId("minimal"), headerStyleRepairChain(["minimal"])]
14404
+ ]);
14405
+ var legacyHeaderLookAliases = [
14406
+ {
14407
+ lookId: asHeaderLookId("clean-base"),
14408
+ selection: {
14409
+ layoutId: asHeaderLayoutId("classic"),
14410
+ styleId: asHeaderStyleId("minimal")
14411
+ }
14412
+ },
14413
+ {
14414
+ lookId: asHeaderLookId("brand-solid"),
14415
+ selection: {
14416
+ layoutId: asHeaderLayoutId("classic"),
14417
+ styleId: asHeaderStyleId("brand-bar")
14418
+ }
14419
+ },
14420
+ {
14421
+ lookId: asHeaderLookId("editorial-line"),
14422
+ selection: {
14423
+ layoutId: asHeaderLayoutId("editorial"),
14424
+ styleId: asHeaderStyleId("editorial-line")
14425
+ }
14426
+ },
14427
+ {
14428
+ lookId: asHeaderLookId("centered-calm"),
14429
+ selection: {
14430
+ layoutId: asHeaderLayoutId("centered"),
14431
+ styleId: asHeaderStyleId("minimal")
14432
+ }
14433
+ },
14434
+ {
14435
+ lookId: asHeaderLookId("practical-utility"),
14436
+ selection: {
14437
+ layoutId: asHeaderLayoutId("classic"),
14438
+ styleId: asHeaderStyleId("flat-tabs")
14439
+ }
14440
+ },
14441
+ {
14442
+ lookId: asHeaderLookId("minimal-transparent"),
14443
+ selection: {
14444
+ layoutId: asHeaderLayoutId("classic"),
14445
+ styleId: asHeaderStyleId("minimal")
14446
+ }
14447
+ },
14448
+ {
14449
+ lookId: asHeaderLookId("transparent-overlay"),
14450
+ selection: {
14451
+ layoutId: asHeaderLayoutId("floating"),
14452
+ styleId: asHeaderStyleId("glass")
14453
+ }
14454
+ },
14455
+ {
14456
+ lookId: asHeaderLookId("floating-glass"),
14457
+ selection: {
14458
+ layoutId: asHeaderLayoutId("floating"),
14459
+ styleId: asHeaderStyleId("glass")
14460
+ }
14461
+ }
14462
+ ];
14463
+ var legacyHeaderLookAliasesById = new Map(
14464
+ legacyHeaderLookAliases.map((alias) => [alias.lookId, alias])
14465
+ );
14466
+ function getHeaderStyle(id) {
14467
+ return headerStylesById.get(id) ?? null;
14468
+ }
14469
+ function isHeaderStyleCompatibleWithLayout(style, layoutId) {
14470
+ return style.supportedLayoutIds.includes(layoutId);
14471
+ }
14472
+ function getHeaderStyleOrThrow(id) {
14473
+ const style = getHeaderStyle(id);
14474
+ if (!style) {
14475
+ throw new Error(`Unknown Theme V2 header style: ${id}`);
14476
+ }
14477
+ return style;
14478
+ }
14479
+ function resolveLegacyHeaderLookAlias(lookId) {
14480
+ return legacyHeaderLookAliasesById.get(lookId)?.selection ?? null;
14481
+ }
14482
+ function getCompatibleHeaderStyleIds(layoutId) {
14483
+ return (headerStyleCompatibilityOrder.get(layoutId) ?? []).filter((styleId) => {
14484
+ const style = getHeaderStyleOrThrow(styleId);
14485
+ return isHeaderStyleCompatibleWithLayout(style, layoutId);
14486
+ });
14487
+ }
13816
14488
  function solidBrandHeader(theme) {
13817
14489
  const ctaVariant = resolveHeaderCtaVariant(theme, "inverted");
13818
14490
  return {
@@ -14049,6 +14721,11 @@ var headerLookCatalog = [
14049
14721
  label: "Clean base",
14050
14722
  visualTreatment: "solid-neutral",
14051
14723
  layoutBehavior: "sticky",
14724
+ configuration: {
14725
+ structure: "inline-classic",
14726
+ treatment: "solid-neutral",
14727
+ behavior: "sticky"
14728
+ },
14052
14729
  openingRequirement: "none",
14053
14730
  compile: cleanBaseHeader
14054
14731
  },
@@ -14057,6 +14734,11 @@ var headerLookCatalog = [
14057
14734
  label: "Brand solid",
14058
14735
  visualTreatment: "solid-brand",
14059
14736
  layoutBehavior: "sticky-shrink",
14737
+ configuration: {
14738
+ structure: "inline-classic",
14739
+ treatment: "solid-brand",
14740
+ behavior: "sticky-shrink"
14741
+ },
14060
14742
  openingRequirement: "none",
14061
14743
  compile: solidBrandHeader
14062
14744
  },
@@ -14065,6 +14747,11 @@ var headerLookCatalog = [
14065
14747
  label: "Editorial line",
14066
14748
  visualTreatment: "light-editorial",
14067
14749
  layoutBehavior: "sticky",
14750
+ configuration: {
14751
+ structure: "editorial-stack",
14752
+ treatment: "light-editorial",
14753
+ behavior: "sticky"
14754
+ },
14068
14755
  openingRequirement: "none",
14069
14756
  maxRecommendedNavItems: 6,
14070
14757
  compile: editorialLineHeader
@@ -14074,6 +14761,11 @@ var headerLookCatalog = [
14074
14761
  label: "Centered calm",
14075
14762
  visualTreatment: "light-editorial",
14076
14763
  layoutBehavior: "normal-flow",
14764
+ configuration: {
14765
+ structure: "centered-stack",
14766
+ treatment: "light-editorial",
14767
+ behavior: "normal-flow"
14768
+ },
14077
14769
  openingRequirement: "none",
14078
14770
  maxRecommendedNavItems: 5,
14079
14771
  allowedLogoShapes: ["none", "text-only", "horizontal", "square"],
@@ -14084,6 +14776,11 @@ var headerLookCatalog = [
14084
14776
  label: "Practical utility",
14085
14777
  visualTreatment: "solid-neutral",
14086
14778
  layoutBehavior: "sticky-shrink",
14779
+ configuration: {
14780
+ structure: "inline-classic",
14781
+ treatment: "solid-neutral",
14782
+ behavior: "sticky-shrink"
14783
+ },
14087
14784
  openingRequirement: "none",
14088
14785
  requiresProminentCta: true,
14089
14786
  compile: practicalUtilityHeader
@@ -14093,6 +14790,11 @@ var headerLookCatalog = [
14093
14790
  label: "Minimal transparent",
14094
14791
  visualTreatment: "minimal-transparent",
14095
14792
  layoutBehavior: "normal-flow",
14793
+ configuration: {
14794
+ structure: "inline-classic",
14795
+ treatment: "minimal-transparent",
14796
+ behavior: "normal-flow"
14797
+ },
14096
14798
  openingRequirement: "reserved-space-ok",
14097
14799
  compile: minimalTransparentHeader
14098
14800
  },
@@ -14101,6 +14803,11 @@ var headerLookCatalog = [
14101
14803
  label: "Transparent overlay",
14102
14804
  visualTreatment: "transparent-overlay",
14103
14805
  layoutBehavior: "fixed-overlay",
14806
+ configuration: {
14807
+ structure: "inline-classic",
14808
+ treatment: "transparent-overlay",
14809
+ behavior: "fixed-overlay"
14810
+ },
14104
14811
  openingRequirement: "requires-image-hero-with-contrast-overlay",
14105
14812
  maxRecommendedNavItems: 5,
14106
14813
  allowedLogoShapes: ["none", "text-only", "horizontal"],
@@ -14111,6 +14818,11 @@ var headerLookCatalog = [
14111
14818
  label: "Floating glass",
14112
14819
  visualTreatment: "floating-glass",
14113
14820
  layoutBehavior: "fixed-floating",
14821
+ configuration: {
14822
+ structure: "floating-shell",
14823
+ treatment: "floating-glass",
14824
+ behavior: "fixed-floating"
14825
+ },
14114
14826
  openingRequirement: "requires-image-hero-with-contrast-overlay",
14115
14827
  maxRecommendedNavItems: 5,
14116
14828
  allowedLogoShapes: ["none", "text-only", "horizontal"],
@@ -14118,9 +14830,17 @@ var headerLookCatalog = [
14118
14830
  }
14119
14831
  ];
14120
14832
  var guaranteedFallbackHeaderLookId = asHeaderLookId("clean-base");
14833
+ var guaranteedFallbackHeaderLayoutId = asHeaderLayoutId("classic");
14834
+ var guaranteedFallbackHeaderStyleId = asHeaderStyleId("minimal");
14835
+ var allowedHeaderConfigurationKeys = new Set(
14836
+ headerLookCatalog.map((look) => headerConfigurationKey(look.configuration))
14837
+ );
14121
14838
  var headerLooksById = new Map(
14122
14839
  headerLookCatalog.map((look) => [look.id, look])
14123
14840
  );
14841
+ function headerConfigurationKey(configuration) {
14842
+ return `${configuration.structure}:${configuration.treatment}:${configuration.behavior}`;
14843
+ }
14124
14844
 
14125
14845
  // ../theme-core/src/site-styles/footerLooks.ts
14126
14846
  function asFooterLookId(value) {
@@ -14253,6 +14973,264 @@ var advancedDesignOptionCatalog = {
14253
14973
  detachedCustom: true
14254
14974
  };
14255
14975
 
14976
+ // ../theme-core/src/site-styles/typographyPresets.ts
14977
+ var bodyReadablePolicy = {
14978
+ recommendedCategories: ["sans-serif", "serif"],
14979
+ allowedCategories: ["sans-serif", "serif"],
14980
+ requiresItalicForBody: true,
14981
+ requiresBoldForBody: true
14982
+ };
14983
+ var headingFlexiblePolicy = {
14984
+ recommendedCategories: ["sans-serif", "serif", "display"],
14985
+ allowedCategories: ["sans-serif", "serif", "display"]
14986
+ };
14987
+ var displayHeadingPolicy = {
14988
+ recommendedCategories: ["display", "sans-serif", "serif"],
14989
+ allowedCategories: ["display", "sans-serif", "serif"]
14990
+ };
14991
+ function asTypographyPresetId(value) {
14992
+ if (!value.startsWith("typography-preset:")) {
14993
+ throw new Error(`TypographyPresetId must start with "typography-preset:". Received: ${value}`);
14994
+ }
14995
+ return value;
14996
+ }
14997
+ function defineTypographyPreset(preset2) {
14998
+ return {
14999
+ ...preset2,
15000
+ id: asTypographyPresetId(preset2.id)
15001
+ };
15002
+ }
15003
+ var modernSansTypography = {
15004
+ body: {
15005
+ family: "Inter, system-ui, sans-serif",
15006
+ size: "md",
15007
+ weight: "regular",
15008
+ lineHeight: "relaxed",
15009
+ letterSpacing: "normal"
15010
+ },
15011
+ headings: {
15012
+ default: {
15013
+ family: "Inter, system-ui, sans-serif",
15014
+ weight: "semibold",
15015
+ lineHeight: "normal",
15016
+ letterSpacing: "tight",
15017
+ italic: null,
15018
+ case: null
15019
+ },
15020
+ h1: { size: "xl", weight: "bold", lineHeight: "normal", letterSpacing: "tight", italic: null },
15021
+ h2: { size: "lg", weight: "semibold", lineHeight: "normal", letterSpacing: "tight", italic: null },
15022
+ h3: { size: "md", weight: "semibold", lineHeight: "normal", letterSpacing: "normal", italic: null }
15023
+ },
15024
+ scale: "balanced"
15025
+ };
15026
+ var warmRoundedTypography = {
15027
+ body: {
15028
+ family: "Nunito Sans, system-ui, sans-serif",
15029
+ size: "lg",
15030
+ weight: "regular",
15031
+ lineHeight: "relaxed",
15032
+ letterSpacing: "normal"
15033
+ },
15034
+ headings: {
15035
+ default: {
15036
+ family: "Nunito Sans, system-ui, sans-serif",
15037
+ weight: "bold",
15038
+ lineHeight: "normal",
15039
+ letterSpacing: "normal",
15040
+ italic: null,
15041
+ case: null
15042
+ },
15043
+ h1: { size: "xl", weight: "bold", lineHeight: "normal", letterSpacing: "normal", italic: null },
15044
+ h2: { size: "lg", weight: "bold", lineHeight: "normal", letterSpacing: "normal", italic: null },
15045
+ h3: { size: "md", weight: "semibold", lineHeight: "relaxed", letterSpacing: "normal", italic: null }
15046
+ },
15047
+ scale: "balanced"
15048
+ };
15049
+ var editorialSerifTypography = {
15050
+ body: {
15051
+ family: "Lora, Georgia, serif",
15052
+ size: "lg",
15053
+ weight: "regular",
15054
+ lineHeight: "loose",
15055
+ letterSpacing: "normal"
15056
+ },
15057
+ headings: {
15058
+ default: {
15059
+ family: "Playfair Display, Georgia, serif",
15060
+ weight: "semibold",
15061
+ lineHeight: "normal",
15062
+ letterSpacing: "tight",
15063
+ italic: null,
15064
+ case: null
15065
+ },
15066
+ h1: { size: "2xl", weight: "semibold", lineHeight: "normal", letterSpacing: "tight", italic: null },
15067
+ h2: { size: "xl", weight: "semibold", lineHeight: "normal", letterSpacing: "normal", italic: null },
15068
+ h3: { size: "md", weight: "semibold", lineHeight: "relaxed", letterSpacing: "normal", italic: true }
15069
+ },
15070
+ scale: "spacious"
15071
+ };
15072
+ var classicSerifTypography = {
15073
+ body: {
15074
+ family: "Libre Baskerville, Georgia, serif",
15075
+ size: "md",
15076
+ weight: "regular",
15077
+ lineHeight: "relaxed",
15078
+ letterSpacing: "normal"
15079
+ },
15080
+ headings: {
15081
+ default: {
15082
+ family: "Cormorant Garamond, Georgia, serif",
15083
+ weight: "semibold",
15084
+ lineHeight: "normal",
15085
+ letterSpacing: "normal",
15086
+ italic: null,
15087
+ case: null
15088
+ },
15089
+ h1: { size: "2xl", weight: "semibold", lineHeight: "normal", letterSpacing: "normal", italic: null },
15090
+ h2: { size: "xl", weight: "semibold", lineHeight: "normal", letterSpacing: "normal", italic: null },
15091
+ h3: { size: "md", weight: "medium", lineHeight: "relaxed", letterSpacing: "normal", italic: null }
15092
+ },
15093
+ scale: "balanced"
15094
+ };
15095
+ var luxeContrastTypography = {
15096
+ body: {
15097
+ family: "Manrope, system-ui, sans-serif",
15098
+ size: "md",
15099
+ weight: "regular",
15100
+ lineHeight: "relaxed",
15101
+ letterSpacing: "normal"
15102
+ },
15103
+ headings: {
15104
+ default: {
15105
+ family: "Cormorant Garamond, Georgia, serif",
15106
+ weight: "semibold",
15107
+ lineHeight: "normal",
15108
+ letterSpacing: "tight",
15109
+ italic: null,
15110
+ case: null
15111
+ },
15112
+ h1: { size: "2xl", weight: "semibold", lineHeight: "normal", letterSpacing: "tight", italic: null },
15113
+ h2: { size: "xl", weight: "semibold", lineHeight: "normal", letterSpacing: "tight", italic: null },
15114
+ h3: { size: "md", weight: "medium", lineHeight: "relaxed", letterSpacing: "normal", italic: null }
15115
+ },
15116
+ scale: "spacious"
15117
+ };
15118
+ var boldDisplayTypography = {
15119
+ body: {
15120
+ family: "Manrope, system-ui, sans-serif",
15121
+ size: "lg",
15122
+ weight: "regular",
15123
+ lineHeight: "relaxed",
15124
+ letterSpacing: "normal"
15125
+ },
15126
+ headings: {
15127
+ default: {
15128
+ family: '"TAN - PEARL", sans-serif',
15129
+ weight: "bold",
15130
+ lineHeight: "normal",
15131
+ letterSpacing: "tight",
15132
+ colorToken: "primary",
15133
+ italic: null,
15134
+ case: null
15135
+ },
15136
+ h1: { size: "xl", weight: "bold", lineHeight: "normal", letterSpacing: "tight", italic: null },
15137
+ h2: { size: "lg", weight: "bold", lineHeight: "normal", letterSpacing: "normal", italic: null },
15138
+ h3: { size: "md", weight: "bold", lineHeight: "normal", letterSpacing: "normal", italic: null }
15139
+ },
15140
+ scale: "balanced"
15141
+ };
15142
+ var typographyPresets = [
15143
+ defineTypographyPreset({
15144
+ id: "typography-preset:modern-sans",
15145
+ name: "Modern Sans",
15146
+ description: "Crisp, neutral type for clear service pages and practical editorial structure.",
15147
+ defaultFonts: { body: "Inter, system-ui, sans-serif", heading: "Inter, system-ui, sans-serif" },
15148
+ recommendedFonts: {
15149
+ body: ["Inter", "Source Sans 3", "IBM Plex Sans"],
15150
+ heading: ["Inter", "Manrope", "Source Sans 3"]
15151
+ },
15152
+ slotPolicies: { body: bodyReadablePolicy, heading: headingFlexiblePolicy },
15153
+ typography: modernSansTypography
15154
+ }),
15155
+ defineTypographyPreset({
15156
+ id: "typography-preset:warm-rounded",
15157
+ name: "Warm Rounded",
15158
+ description: "Soft, friendly type for welcoming studios, classes, and community businesses.",
15159
+ defaultFonts: { body: "Nunito Sans, system-ui, sans-serif", heading: "Nunito Sans, system-ui, sans-serif" },
15160
+ recommendedFonts: {
15161
+ body: ["Nunito Sans", "Atkinson Hyperlegible", "Lato"],
15162
+ heading: ["Nunito Sans", "Quicksand", "Manrope"]
15163
+ },
15164
+ slotPolicies: { body: bodyReadablePolicy, heading: headingFlexiblePolicy },
15165
+ typography: warmRoundedTypography
15166
+ }),
15167
+ defineTypographyPreset({
15168
+ id: "typography-preset:editorial-serif",
15169
+ name: "Editorial Serif",
15170
+ description: "Story-led type with warm reading rhythm and expressive headings.",
15171
+ defaultFonts: { body: "Lora, Georgia, serif", heading: "Playfair Display, Georgia, serif" },
15172
+ recommendedFonts: {
15173
+ body: ["Lora", "Source Serif 4", "Libre Baskerville"],
15174
+ heading: ["Playfair Display", "Cormorant Garamond", "Fraunces"]
15175
+ },
15176
+ slotPolicies: { body: bodyReadablePolicy, heading: displayHeadingPolicy },
15177
+ typography: editorialSerifTypography
15178
+ }),
15179
+ defineTypographyPreset({
15180
+ id: "typography-preset:classic-serif",
15181
+ name: "Classic Serif",
15182
+ description: "Measured, polished type for premium and established offers.",
15183
+ defaultFonts: { body: "Libre Baskerville, Georgia, serif", heading: "Cormorant Garamond, Georgia, serif" },
15184
+ recommendedFonts: {
15185
+ body: ["Libre Baskerville", "Source Serif 4", "Lora"],
15186
+ heading: ["Cormorant Garamond", "Playfair Display", "Libre Baskerville"]
15187
+ },
15188
+ slotPolicies: { body: bodyReadablePolicy, heading: displayHeadingPolicy },
15189
+ typography: classicSerifTypography
15190
+ }),
15191
+ defineTypographyPreset({
15192
+ id: "typography-preset:luxe-contrast",
15193
+ name: "Luxe Contrast",
15194
+ description: "A restrained sans body paired with elegant high-contrast headings.",
15195
+ defaultFonts: { body: "Manrope, system-ui, sans-serif", heading: "Cormorant Garamond, Georgia, serif" },
15196
+ recommendedFonts: {
15197
+ body: ["Manrope", "Inter", "Source Sans 3"],
15198
+ heading: ["Cormorant Garamond", "Playfair Display", "Bodoni Moda"]
15199
+ },
15200
+ slotPolicies: { body: bodyReadablePolicy, heading: displayHeadingPolicy },
15201
+ typography: luxeContrastTypography
15202
+ }),
15203
+ defineTypographyPreset({
15204
+ id: "typography-preset:bold-display",
15205
+ name: "Bold Display",
15206
+ description: "Punchy display headings with readable sans body copy for branded launches.",
15207
+ defaultFonts: { body: "Manrope, system-ui, sans-serif", heading: '"TAN - PEARL", sans-serif' },
15208
+ recommendedFonts: {
15209
+ body: ["Manrope", "Inter", "Space Grotesk"],
15210
+ heading: ["Anton", "Bebas Neue", "Archivo Black"]
15211
+ },
15212
+ slotPolicies: { body: bodyReadablePolicy, heading: displayHeadingPolicy },
15213
+ typography: boldDisplayTypography,
15214
+ heroTypography: {
15215
+ headlineSize: "6xl",
15216
+ headlineLineHeight: "tight",
15217
+ subheadlineSize: "editorial",
15218
+ subheadlineLineHeight: "normal",
15219
+ microHeadlineSize: "6xl",
15220
+ microHeadlineLineHeight: "tight",
15221
+ microSubheadlineSize: "xl",
15222
+ microSubheadlineLineHeight: "normal",
15223
+ responsive: {
15224
+ tablet: { headlineSize: "5xl" },
15225
+ mobile: { headlineSize: "4xl", subheadlineSize: "xl" }
15226
+ }
15227
+ }
15228
+ })
15229
+ ];
15230
+ var typographyPresetsById = new Map(
15231
+ typographyPresets.map((preset2) => [preset2.id, preset2])
15232
+ );
15233
+
14256
15234
  // ../theme-core/src/site-styles/curatedSiteStyles.ts
14257
15235
  var curatedSiteStyleIdValues = [
14258
15236
  "site-style:calm-studio",
@@ -14265,6 +15243,7 @@ var curatedSiteStyleIdValues = [
14265
15243
  "site-style:personal-retreat-journal",
14266
15244
  "site-style:tactile-workshop",
14267
15245
  "site-style:modern-wellness",
15246
+ "site-style:soft-earth",
14268
15247
  "site-style:bold-launch",
14269
15248
  "site-style:south-west-twerk-school"
14270
15249
  ];
@@ -14341,6 +15320,15 @@ function uniqueContentFrameKinds() {
14341
15320
  }
14342
15321
  var generatedContentFrameKinds = uniqueContentFrameKinds();
14343
15322
  function defineCuratedSiteStyle(input) {
15323
+ const legacyHeaderLookIds = input.recommendedHeaderLookIds ?? ["clean-base"];
15324
+ const inferredHeaderCuration = inferHeaderCurationFromLegacyLooks(legacyHeaderLookIds);
15325
+ const typographyPresetChoices = input.typographyPresetChoices ?? defaultTypographyPresetChoicesForRecipe(input.tokenRecipes.typography);
15326
+ const defaultTypographyPresetId = input.defaultTypographyPresetId ? asTypographyPresetId(input.defaultTypographyPresetId) : typographyPresetChoices[0].id;
15327
+ if (!typographyPresetChoices.some((choice) => choice.id === defaultTypographyPresetId)) {
15328
+ throw new Error(
15329
+ `Default typography preset ${defaultTypographyPresetId} is not curated for site style ${input.id}.`
15330
+ );
15331
+ }
14344
15332
  return {
14345
15333
  id: asSiteStyleId(input.id),
14346
15334
  name: input.name,
@@ -14361,11 +15349,23 @@ function defineCuratedSiteStyle(input) {
14361
15349
  },
14362
15350
  ...input.themeOverrides ? { themeOverrides: input.themeOverrides } : {},
14363
15351
  recommendedAppearancePresetIds: (input.recommendedAppearancePresetIds ?? []).map(asAppearancePresetId),
14364
- recommendedHeaderLookIds: (input.recommendedHeaderLookIds ?? ["clean-base"]).map(asHeaderLookId),
15352
+ defaultHeaderSelection: input.defaultHeaderSelection ? {
15353
+ layoutId: asHeaderLayoutId(input.defaultHeaderSelection.layoutId),
15354
+ styleId: asHeaderStyleId(input.defaultHeaderSelection.styleId)
15355
+ } : inferredHeaderCuration.defaultHeaderSelection,
15356
+ recommendedHeaderLayoutChoices: input.recommendedHeaderLayoutChoices ?? inferredHeaderCuration.recommendedHeaderLayoutChoices,
15357
+ recommendedHeaderStyleChoicesByLayout: input.recommendedHeaderStyleChoicesByLayout ?? inferredHeaderCuration.recommendedHeaderStyleChoicesByLayout,
15358
+ discouragedHeaderSelections: input.discouragedHeaderSelections?.map((selection) => ({
15359
+ layoutId: asHeaderLayoutId(selection.layoutId),
15360
+ styleId: asHeaderStyleId(selection.styleId)
15361
+ })),
15362
+ recommendedHeaderLookIds: legacyHeaderLookIds.map(asHeaderLookId),
14365
15363
  // Empty is intentional: resolveFooterLook always appends its guaranteed fallback.
14366
15364
  recommendedFooterLookIds: (input.recommendedFooterLookIds ?? []).map(asFooterLookId),
14367
15365
  buttonPersonalityChoices: input.buttonPersonalityChoices,
14368
- paletteVariantChoices: input.paletteVariantChoices
15366
+ paletteVariantChoices: input.paletteVariantChoices,
15367
+ typographyPresetChoices,
15368
+ defaultTypographyPresetId
14369
15369
  };
14370
15370
  }
14371
15371
  function buttonChoice(id, note) {
@@ -14374,6 +15374,88 @@ function buttonChoice(id, note) {
14374
15374
  function paletteChoice(id, note) {
14375
15375
  return note ? { id: asPaletteVariantId(id), note } : { id: asPaletteVariantId(id) };
14376
15376
  }
15377
+ function headerLayoutChoice(id, note) {
15378
+ return note ? { id: asHeaderLayoutId(id), note } : { id: asHeaderLayoutId(id) };
15379
+ }
15380
+ function headerStyleChoice(id, note) {
15381
+ return note ? { id: asHeaderStyleId(id), note } : { id: asHeaderStyleId(id) };
15382
+ }
15383
+ function headerLayoutRecordKey(id) {
15384
+ return id;
15385
+ }
15386
+ function uniqueHeaderLayoutChoices(choices) {
15387
+ const seen = /* @__PURE__ */ new Set();
15388
+ const unique = choices.filter((choice) => {
15389
+ if (seen.has(choice.id)) return false;
15390
+ seen.add(choice.id);
15391
+ return true;
15392
+ });
15393
+ const first = unique[0];
15394
+ if (!first) {
15395
+ throw new Error("Expected at least one curated header layout choice.");
15396
+ }
15397
+ return [first, ...unique.slice(1)];
15398
+ }
15399
+ function nonEmptyHeaderStyleChoices(choices, fallbackLayoutId) {
15400
+ const first = choices[0] ?? {
15401
+ id: getCompatibleHeaderStyleIds(fallbackLayoutId)[0] ?? asHeaderStyleId("minimal")
15402
+ };
15403
+ return [first, ...choices.slice(1)];
15404
+ }
15405
+ function inferHeaderCurationFromLegacyLooks(lookIds) {
15406
+ const selections = lookIds.map((lookId) => resolveLegacyHeaderLookAlias(asHeaderLookId(lookId))).filter((selection) => Boolean(selection));
15407
+ const defaultHeaderSelection = selections[0] ?? {
15408
+ layoutId: asHeaderLayoutId("classic"),
15409
+ styleId: asHeaderStyleId("minimal")
15410
+ };
15411
+ const layoutChoices = uniqueHeaderLayoutChoices(
15412
+ selections.map((selection) => headerLayoutChoice(selection.layoutId))
15413
+ );
15414
+ const stylesByLayout = {};
15415
+ for (const layoutChoice of layoutChoices) {
15416
+ const styleChoices = selections.filter((selection) => selection.layoutId === layoutChoice.id).map((selection) => headerStyleChoice(selection.styleId));
15417
+ stylesByLayout[headerLayoutRecordKey(layoutChoice.id)] = nonEmptyHeaderStyleChoices(
15418
+ styleChoices,
15419
+ layoutChoice.id
15420
+ );
15421
+ }
15422
+ return {
15423
+ defaultHeaderSelection,
15424
+ recommendedHeaderLayoutChoices: layoutChoices,
15425
+ recommendedHeaderStyleChoicesByLayout: stylesByLayout
15426
+ };
15427
+ }
15428
+ function typographyChoice(id, note) {
15429
+ return note ? { id: asTypographyPresetId(id), note } : { id: asTypographyPresetId(id) };
15430
+ }
15431
+ function defaultTypographyPresetChoicesForRecipe(recipe) {
15432
+ switch (recipe) {
15433
+ case "clean-sans":
15434
+ return [
15435
+ typographyChoice("typography-preset:modern-sans"),
15436
+ typographyChoice("typography-preset:luxe-contrast"),
15437
+ typographyChoice("typography-preset:bold-display")
15438
+ ];
15439
+ case "friendly-sans":
15440
+ return [
15441
+ typographyChoice("typography-preset:warm-rounded"),
15442
+ typographyChoice("typography-preset:modern-sans"),
15443
+ typographyChoice("typography-preset:editorial-serif")
15444
+ ];
15445
+ case "serif-editorial":
15446
+ return [
15447
+ typographyChoice("typography-preset:editorial-serif"),
15448
+ typographyChoice("typography-preset:classic-serif"),
15449
+ typographyChoice("typography-preset:warm-rounded")
15450
+ ];
15451
+ case "classic-serif":
15452
+ return [
15453
+ typographyChoice("typography-preset:classic-serif"),
15454
+ typographyChoice("typography-preset:luxe-contrast"),
15455
+ typographyChoice("typography-preset:editorial-serif")
15456
+ ];
15457
+ }
15458
+ }
14377
15459
  var curatedSiteStyles = [
14378
15460
  defineCuratedSiteStyle({
14379
15461
  id: "site-style:calm-studio",
@@ -14699,6 +15781,102 @@ var curatedSiteStyles = [
14699
15781
  paletteChoice("warm-neutral-clay")
14700
15782
  ]
14701
15783
  }),
15784
+ defineCuratedSiteStyle({
15785
+ id: "site-style:soft-earth",
15786
+ name: "Soft Earth",
15787
+ description: "Warm, grounded, and editorial for yoga studios, retreats, and wellbeing communities.",
15788
+ generationBrief: "Use cream space, terracotta CTAs, olive proof bands, natural imagery, generous but composed spacing, and editorial serif headings. Prefer a real intro section, image-led offering cards, warm community proof, and a simple two-column FAQ when content allows.",
15789
+ siteCreatorSelection: { kind: "site_creator_keyword_heuristic", priority: 45 },
15790
+ selectionKeywordRules: [
15791
+ { kind: "word", value: "meditation" },
15792
+ { kind: "word", value: "wellbeing" },
15793
+ { kind: "substring", value: "retreat" },
15794
+ { kind: "phrase", value: "yoga studio" },
15795
+ { kind: "phrase", value: "mindful movement" }
15796
+ ],
15797
+ tokenRecipes: {
15798
+ palette: "warm-neutral",
15799
+ contrast: "standard",
15800
+ radius: "soft",
15801
+ shadow: "subtle",
15802
+ typography: "serif-editorial",
15803
+ spacing: "airy",
15804
+ motion: "subtle"
15805
+ },
15806
+ compositionBudget: balancedBudget,
15807
+ themeOverrides: {
15808
+ typography: {
15809
+ body: {
15810
+ family: "Inter, system-ui, sans-serif",
15811
+ size: "md",
15812
+ weight: "regular",
15813
+ lineHeight: "relaxed",
15814
+ letterSpacing: "normal"
15815
+ },
15816
+ headings: {
15817
+ default: {
15818
+ family: '"Cormorant Garamond", Georgia, serif',
15819
+ weight: "regular",
15820
+ lineHeight: "normal",
15821
+ letterSpacing: "normal",
15822
+ colorToken: "text",
15823
+ italic: null,
15824
+ case: null
15825
+ },
15826
+ h1: {
15827
+ size: "xl",
15828
+ weight: "regular",
15829
+ lineHeight: "normal",
15830
+ letterSpacing: "normal",
15831
+ italic: null
15832
+ },
15833
+ h2: {
15834
+ size: "lg",
15835
+ weight: "regular",
15836
+ lineHeight: "normal",
15837
+ letterSpacing: "normal",
15838
+ italic: null
15839
+ },
15840
+ h3: {
15841
+ size: "md",
15842
+ weight: "regular",
15843
+ lineHeight: "normal",
15844
+ letterSpacing: "normal",
15845
+ italic: null
15846
+ }
15847
+ },
15848
+ scale: "majorThird"
15849
+ },
15850
+ bodyText: {
15851
+ intro: {
15852
+ paragraphSize: "default",
15853
+ headingSize: "editorial"
15854
+ }
15855
+ }
15856
+ },
15857
+ recommendedAppearancePresetIds: [
15858
+ "hero-brand-scrim",
15859
+ "intro-soft-earth-statement",
15860
+ "feature-cards-soft-earth-offerings",
15861
+ "testimonials-soft-earth-proof-band",
15862
+ "faq-soft-earth-two-column",
15863
+ "contact-form-panel"
15864
+ ],
15865
+ recommendedHeaderLookIds: ["centered-calm", "minimal-transparent", "editorial-line"],
15866
+ recommendedFooterLookIds: ["footer-muted-grounding", "site-footer-brand-two-band"],
15867
+ buttonPersonalityChoices: [
15868
+ buttonChoice("earth-pill"),
15869
+ buttonChoice("soft-pill"),
15870
+ buttonChoice("pebble"),
15871
+ buttonChoice("editorial-link")
15872
+ ],
15873
+ paletteVariantChoices: [
15874
+ paletteChoice("warm-neutral-soft-earth"),
15875
+ paletteChoice("warm-neutral-clay"),
15876
+ paletteChoice("warm-neutral-forest"),
15877
+ paletteChoice("soft-natural-sage")
15878
+ ]
15879
+ }),
14702
15880
  defineCuratedSiteStyle({
14703
15881
  id: "site-style:bold-launch",
14704
15882
  name: "Bold Launch",
@@ -14752,49 +15930,13 @@ var curatedSiteStyles = [
14752
15930
  motion: "expressive"
14753
15931
  },
14754
15932
  compositionBudget: expressiveBudget,
15933
+ typographyPresetChoices: [
15934
+ typographyChoice("typography-preset:bold-display"),
15935
+ typographyChoice("typography-preset:modern-sans"),
15936
+ typographyChoice("typography-preset:luxe-contrast")
15937
+ ],
15938
+ defaultTypographyPresetId: "typography-preset:bold-display",
14755
15939
  themeOverrides: {
14756
- typography: {
14757
- body: {
14758
- family: "Manrope, system-ui, sans-serif",
14759
- size: "lg",
14760
- weight: "regular",
14761
- lineHeight: "relaxed",
14762
- letterSpacing: "normal"
14763
- },
14764
- headings: {
14765
- default: {
14766
- family: '"TAN - PEARL", sans-serif',
14767
- weight: "bold",
14768
- lineHeight: "normal",
14769
- letterSpacing: "tight",
14770
- colorToken: "primary",
14771
- italic: null,
14772
- case: null
14773
- },
14774
- h1: {
14775
- size: "xl",
14776
- weight: "bold",
14777
- lineHeight: "normal",
14778
- letterSpacing: "tight",
14779
- italic: null
14780
- },
14781
- h2: {
14782
- size: "lg",
14783
- weight: "bold",
14784
- lineHeight: "normal",
14785
- letterSpacing: "normal",
14786
- italic: null
14787
- },
14788
- h3: {
14789
- size: "md",
14790
- weight: "bold",
14791
- lineHeight: "normal",
14792
- letterSpacing: "normal",
14793
- italic: null
14794
- }
14795
- },
14796
- scale: "balanced"
14797
- },
14798
15940
  bodyText: {
14799
15941
  intro: {
14800
15942
  paragraphSize: "editorial",
@@ -19433,8 +20575,9 @@ var faqAccordionFragment = defineFragment({
19433
20575
  },
19434
20576
  fallback: "rb-faq-item"
19435
20577
  },
19436
- iconStyle: { $bind: { from: "theme.accordions.icon.style" } }
19437
- // Pass icon style from theme
20578
+ iconStyle: { $bind: { from: "theme.accordions.icon.style" } },
20579
+ // Legacy theme accordion style
20580
+ iconTreatment: { $bind: { from: "content._sectionStyles.accordionIconTreatment" } }
19438
20581
  },
19439
20582
  triggerFrom: "faqItem.question",
19440
20583
  contentFrom: "faqItem.answer"
@@ -20611,6 +21754,334 @@ var heroBlockDefinition = {
20611
21754
  manifest: heroManifest
20612
21755
  };
20613
21756
 
21757
+ // ../blocks/src/system/fields/aspectRatio.ts
21758
+ var standardAspectRatioOptions = [
21759
+ { value: "auto", label: "Auto (original)" },
21760
+ { value: "16/9", label: "16:9 (Landscape)" },
21761
+ { value: "4/3", label: "4:3 (Standard)" },
21762
+ { value: "1/1", label: "1:1 (Square)" },
21763
+ { value: "3/4", label: "3:4 (Portrait)" }
21764
+ ];
21765
+ function createAspectRatioField(options = {}) {
21766
+ return {
21767
+ id: options.id ?? "aspectRatio",
21768
+ type: "select",
21769
+ label: options.label ?? "Aspect ratio",
21770
+ ...options.description ? { description: options.description } : {},
21771
+ required: false,
21772
+ defaultValue: options.defaultValue ?? "auto",
21773
+ multiple: false,
21774
+ options: [...standardAspectRatioOptions],
21775
+ ui: {
21776
+ intent: options.uiIntent ?? "display",
21777
+ ...options.visibleWhen ? { visibleWhen: options.visibleWhen } : {}
21778
+ }
21779
+ };
21780
+ }
21781
+
21782
+ // ../blocks/src/system/fields/imageLayout.ts
21783
+ function createImageColSizeField(options = {}) {
21784
+ const {
21785
+ id = "imageColSize",
21786
+ label = "Image column size",
21787
+ description = "Controls how large the image/thumbnail column is at desktop breakpoints.",
21788
+ defaultValue = "1/3",
21789
+ uiIntent = "display",
21790
+ visibleWhen
21791
+ } = options;
21792
+ return {
21793
+ id,
21794
+ type: "select",
21795
+ label,
21796
+ description,
21797
+ required: false,
21798
+ defaultValue,
21799
+ multiple: false,
21800
+ options: [
21801
+ { value: "1/4", label: "Small (1/4)" },
21802
+ { value: "1/3", label: "Medium (1/3)" },
21803
+ { value: "2/5", label: "Large (2/5)" },
21804
+ { value: "1/2", label: "Extra large (1/2)" },
21805
+ { value: "2/3", label: "Huge (2/3)" }
21806
+ ],
21807
+ ui: {
21808
+ intent: uiIntent,
21809
+ ...visibleWhen ? { visibleWhen } : {}
21810
+ }
21811
+ };
21812
+ }
21813
+ function createImagePositionField(options = {}) {
21814
+ const {
21815
+ id = "imagePosition",
21816
+ label = "Image position",
21817
+ description = "Choose which side the image appears on.",
21818
+ defaultValue = "left",
21819
+ includeAlternate = false,
21820
+ uiIntent = "display",
21821
+ visibleWhen
21822
+ } = options;
21823
+ const positionOptions = [
21824
+ { value: "left", label: "Left" },
21825
+ { value: "right", label: "Right" },
21826
+ ...includeAlternate ? [{ value: "alternate", label: "Alternate" }] : []
21827
+ ];
21828
+ return {
21829
+ id,
21830
+ type: "select",
21831
+ label,
21832
+ description,
21833
+ required: false,
21834
+ defaultValue,
21835
+ multiple: false,
21836
+ // Spread to get a mutable array type without unsafe casts.
21837
+ options: [...positionOptions],
21838
+ ui: {
21839
+ intent: uiIntent,
21840
+ ...visibleWhen ? { visibleWhen } : {}
21841
+ }
21842
+ };
21843
+ }
21844
+
21845
+ // ../blocks/src/system/blocks/intro.ts
21846
+ function introHeading(className) {
21847
+ return text(
21848
+ {
21849
+ as: "h2",
21850
+ className
21851
+ },
21852
+ when("content.title"),
21853
+ bind("content.title")
21854
+ );
21855
+ }
21856
+ function introBody(className = "rb-prose rb-max-w-none") {
21857
+ return richText({ className }, bind("content.body"));
21858
+ }
21859
+ function introCtas(justify = "start") {
21860
+ return ctaRow({
21861
+ justify,
21862
+ gap: "md",
21863
+ containerClassName: "rb-mt-2"
21864
+ });
21865
+ }
21866
+ function introCopyStack(options = {}) {
21867
+ return stack(
21868
+ {
21869
+ gap: "md",
21870
+ className: options.className ?? "rb-intro-copy"
21871
+ },
21872
+ [
21873
+ introHeading(options.headingClassName ?? "rb-intro-title"),
21874
+ introBody(options.bodyClassName),
21875
+ introCtas(options.ctaJustify)
21876
+ ]
21877
+ );
21878
+ }
21879
+ var introMedia = media(
21880
+ {
21881
+ className: "rb-intro-media rb-w-full rb-h-auto rb-object-cover",
21882
+ style: {
21883
+ aspectRatio: { $bind: { from: "content.aspectRatio" } }
21884
+ }
21885
+ },
21886
+ bind("content.media")
21887
+ );
21888
+ var centeredCopyLayout = styledSection({
21889
+ children: styledContainer({
21890
+ rootType: "stack",
21891
+ rootProps: { gap: "lg" },
21892
+ children: [
21893
+ introCopyStack({
21894
+ className: "rb-intro-copy rb-mx-auto rb-max-w-3xl rb-text-center",
21895
+ headingClassName: "rb-intro-title rb-text-center",
21896
+ bodyClassName: "rb-prose rb-mx-auto rb-max-w-none",
21897
+ ctaJustify: "center"
21898
+ })
21899
+ ]
21900
+ }),
21901
+ baseClass: "",
21902
+ spacing: "medium"
21903
+ });
21904
+ var statementCopyLayout = styledSection({
21905
+ children: styledContainer({
21906
+ children: [
21907
+ el(
21908
+ "div",
21909
+ {
21910
+ className: "rb-intro rb-intro-statement rb-grid rb-grid-cols-1 rb-gap-8 rb-md-grid-cols-2 rb-md-items-start"
21911
+ },
21912
+ [
21913
+ introHeading("rb-intro-title rb-max-w-xl"),
21914
+ stack({ gap: "md", className: "rb-intro-copy rb-max-w-xl" }, [
21915
+ introBody(),
21916
+ introCtas("start")
21917
+ ])
21918
+ ]
21919
+ )
21920
+ ]
21921
+ }),
21922
+ baseClass: "",
21923
+ spacing: "medium"
21924
+ });
21925
+ var statementMediaLayout = styledSection({
21926
+ children: styledContainer({
21927
+ children: [
21928
+ el(
21929
+ "div",
21930
+ {
21931
+ className: "rb-intro rb-intro-statement-media rb-grid rb-grid-cols-1 rb-gap-8 rb-lg-grid-cols-3 rb-lg-items-center"
21932
+ },
21933
+ [
21934
+ introHeading("rb-intro-title rb-max-w-xl"),
21935
+ stack({ gap: "md", className: "rb-intro-copy rb-max-w-xl" }, [
21936
+ introBody(),
21937
+ introCtas("start")
21938
+ ]),
21939
+ el("div", { className: "rb-intro-media-wrap rb-w-full" }, [introMedia], when("content.media"))
21940
+ ]
21941
+ )
21942
+ ]
21943
+ }),
21944
+ baseClass: "",
21945
+ spacing: "medium"
21946
+ });
21947
+ var mediaCopyLayout = styledSection({
21948
+ children: styledContainer({
21949
+ children: [
21950
+ responsiveTwoColumn({
21951
+ image: el("div", { className: "rb-intro-media-wrap rb-w-full" }, [introMedia]),
21952
+ text: introCopyStack({
21953
+ className: "rb-intro-copy rb-max-w-xl",
21954
+ headingClassName: "rb-intro-title"
21955
+ }),
21956
+ ratioFrom: "content.ratio",
21957
+ imagePositionFrom: "content.imagePosition",
21958
+ gapFrom: "content.gap",
21959
+ gapFallback: "comfortable",
21960
+ imageWrapperClassName: "rb-w-full rb-shrink-0",
21961
+ textWrapperClassName: "rb-w-full rb-min-w-0 rb-flex-1 rb-self-center"
21962
+ })
21963
+ ]
21964
+ }),
21965
+ baseClass: "",
21966
+ spacing: "medium"
21967
+ });
21968
+ var introConfig = {
21969
+ id: "block.intro",
21970
+ title: "Intro",
21971
+ category: "layout",
21972
+ includeContainerStyles: true,
21973
+ titleSource: "title",
21974
+ additionalFields: [
21975
+ {
21976
+ id: "title",
21977
+ type: "text",
21978
+ label: "Statement",
21979
+ required: false,
21980
+ multiline: true,
21981
+ maxLength: 160
21982
+ },
21983
+ {
21984
+ id: "body",
21985
+ type: "richText",
21986
+ label: "Text",
21987
+ required: true,
21988
+ ui: {
21989
+ richTextVariant: "limited"
21990
+ }
21991
+ },
21992
+ {
21993
+ id: "media",
21994
+ type: "media",
21995
+ label: "Media",
21996
+ required: false,
21997
+ mediaKinds: ["image"],
21998
+ ui: {
21999
+ intent: "content",
22000
+ visibleWhen: { field: "variant", notEquals: "statement-copy" }
22001
+ }
22002
+ },
22003
+ createImagePositionField({
22004
+ id: "imagePosition",
22005
+ label: "Image position",
22006
+ defaultValue: "left",
22007
+ uiIntent: "display",
22008
+ visibleWhen: { field: "variant", equals: "media-copy" }
22009
+ }),
22010
+ {
22011
+ id: "gap",
22012
+ type: "select",
22013
+ label: "Gap between media and text",
22014
+ required: false,
22015
+ defaultValue: "comfortable",
22016
+ multiple: false,
22017
+ options: [
22018
+ { value: "none", label: "None" },
22019
+ { value: "compact", label: "Compact" },
22020
+ { value: "cozy", label: "Cozy" },
22021
+ { value: "medium", label: "Medium" },
22022
+ { value: "comfortable", label: "Comfortable" },
22023
+ { value: "spacious", label: "Spacious" }
22024
+ ],
22025
+ ui: {
22026
+ intent: "display",
22027
+ visibleWhen: { field: "variant", equals: "media-copy" }
22028
+ }
22029
+ },
22030
+ createImageColSizeField({
22031
+ id: "ratio",
22032
+ label: "Media column size",
22033
+ defaultValue: "1/2",
22034
+ uiIntent: "display",
22035
+ visibleWhen: { field: "variant", equals: "media-copy" }
22036
+ }),
22037
+ createAspectRatioField({
22038
+ id: "aspectRatio",
22039
+ label: "Media aspect ratio",
22040
+ description: "Crop media to a consistent aspect ratio.",
22041
+ defaultValue: "auto",
22042
+ visibleWhen: { field: "media", notEquals: null }
22043
+ }),
22044
+ createCtasRepeater({
22045
+ label: "Calls to action",
22046
+ itemLabel: "CTA",
22047
+ maxItems: 2
22048
+ })
22049
+ ],
22050
+ layout: centeredCopyLayout,
22051
+ variants: {
22052
+ "centered-copy": centeredCopyLayout,
22053
+ "statement-copy": statementCopyLayout,
22054
+ "statement-media": statementMediaLayout,
22055
+ "media-copy": mediaCopyLayout
22056
+ },
22057
+ defaultVariant: "statement-copy",
22058
+ variantOptions: {
22059
+ "centered-copy": {
22060
+ label: "Centered copy",
22061
+ description: "A focused intro with centered text and optional calls to action."
22062
+ },
22063
+ "statement-copy": {
22064
+ label: "Statement and copy",
22065
+ description: "A large statement on the left with supporting copy on the right."
22066
+ },
22067
+ "statement-media": {
22068
+ label: "Statement, copy and media",
22069
+ description: "A three-part intro with statement, copy and a small image."
22070
+ },
22071
+ "media-copy": {
22072
+ label: "Media and copy",
22073
+ description: "A compact media/text intro for softer transitions after a hero."
22074
+ }
22075
+ },
22076
+ description: "A flexible introductory section for statement copy, supporting text, media, and CTAs.",
22077
+ tags: ["intro", "introduction", "about", "welcome", "statement", "media", "text"],
22078
+ icon: "PanelTopOpen"
22079
+ };
22080
+ var introManifest = createBlockManifest(introConfig);
22081
+ var introBlockDefinition = {
22082
+ manifest: introManifest
22083
+ };
22084
+
20614
22085
  // ../blocks/src/system/blocks/body-text.ts
20615
22086
  var bodyCopyComposition = composeFragments([{ fragment: bodyCopyFragment }]);
20616
22087
  var proseLayout = styledSection({
@@ -21476,6 +22947,37 @@ var faqComposition = composeFragments([
21476
22947
  { fragment: faqHeadingFragment, fieldPriority: 0 },
21477
22948
  { fragment: faqAccordionFragment, fieldPriority: 1 }
21478
22949
  ]);
22950
+ function fragmentLayoutNode(layout) {
22951
+ return isNodeDefinitionArray(layout) ? el("div", {}, [...layout]) : layout;
22952
+ }
22953
+ function isNodeDefinitionArray(layout) {
22954
+ return Array.isArray(layout);
22955
+ }
22956
+ var headingLayout = fragmentLayoutNode(faqHeadingFragment.layout);
22957
+ var accordionLayout = fragmentLayoutNode(faqAccordionFragment.layout);
22958
+ var defaultLayout = styledSection({
22959
+ children: styledContainer({
22960
+ baseClassName: "rb-relative rb-isolate",
22961
+ children: stack({ gap: "xl", className: "rb-w-full rb-max-w-4xl rb-mx-auto" }, faqComposition.layout)
22962
+ }),
22963
+ baseClass: ""
22964
+ });
22965
+ var twoColumnLayout = styledSection({
22966
+ children: styledContainer({
22967
+ baseClassName: "rb-relative rb-isolate",
22968
+ children: el(
22969
+ "div",
22970
+ {
22971
+ className: "rb-faq-two-column rb-grid rb-grid-cols-1 rb-gap-8 rb-lg-grid-cols-2 rb-lg-items-start"
22972
+ },
22973
+ [
22974
+ el("div", { className: "rb-faq-two-column-heading" }, [headingLayout]),
22975
+ el("div", { className: "rb-faq-two-column-accordion" }, [accordionLayout])
22976
+ ]
22977
+ )
22978
+ }),
22979
+ baseClass: ""
22980
+ });
21479
22981
  var faqManifest = createBlockManifest({
21480
22982
  id: "block.faq",
21481
22983
  title: "FAQ",
@@ -21492,13 +22994,22 @@ var faqManifest = createBlockManifest({
21492
22994
  label: "FAQ item styles"
21493
22995
  })
21494
22996
  ],
21495
- layout: styledSection({
21496
- children: styledContainer({
21497
- baseClassName: "rb-relative rb-isolate",
21498
- children: stack({ gap: "xl", className: "rb-w-full rb-max-w-4xl rb-mx-auto" }, faqComposition.layout)
21499
- }),
21500
- baseClass: ""
21501
- }),
22997
+ layout: defaultLayout,
22998
+ variants: {
22999
+ default: defaultLayout,
23000
+ "two-column": twoColumnLayout
23001
+ },
23002
+ defaultVariant: "default",
23003
+ variantOptions: {
23004
+ default: {
23005
+ label: "Default",
23006
+ description: "A centered heading above one FAQ accordion."
23007
+ },
23008
+ "two-column": {
23009
+ label: "Two column",
23010
+ description: "A left heading column with FAQ items on the right."
23011
+ }
23012
+ },
21502
23013
  description: "Accordion of frequently asked questions and answers.",
21503
23014
  tags: ["faq", "questions", "answers", "help", "support", "accordion", "q&a"],
21504
23015
  icon: "HelpCircle"
@@ -22148,7 +23659,8 @@ function resolveBackgroundVisualStyles(backgroundColor, tokens, defaultToken = "
22148
23659
  function resolveHeaderVisualStyles(header, tokens) {
22149
23660
  const navContainerType = header?.navContainer?.type ?? "none";
22150
23661
  const hasContainedNav = navContainerType === "glass" || navContainerType === "pill";
22151
- if (hasContainedNav) {
23662
+ const hasTransparentVariant = header?.variant === "transparent" || header?.variant === "floating";
23663
+ if (hasContainedNav || hasTransparentVariant) {
22152
23664
  return {
22153
23665
  backgroundToken: "transparent",
22154
23666
  paletteHex: null,
@@ -22277,6 +23789,17 @@ var headerRootStyleTransform = {
22277
23789
  return mergeStyles(...styleParts);
22278
23790
  }
22279
23791
  };
23792
+ var headerSectionBackgroundTransform = {
23793
+ id: "layout.headerSectionBackground",
23794
+ kind: "string",
23795
+ summary: "Resolve the inner site-header section background token",
23796
+ run: (value) => {
23797
+ const header = asPartialObject(value);
23798
+ const navContainerType = header?.navContainer?.type ?? "none";
23799
+ const usesTransparentRoot = header?.variant === "transparent" || header?.variant === "floating" || navContainerType === "glass" || navContainerType === "pill";
23800
+ return usesTransparentRoot ? "raw:transparent" : "background";
23801
+ }
23802
+ };
22280
23803
  var footerRootStyleTransform = {
22281
23804
  id: "layout.footerRootStyle",
22282
23805
  kind: "formatter",
@@ -22535,6 +24058,7 @@ var layoutTransforms = [
22535
24058
  headerRootClassTransform,
22536
24059
  footerRootClassTransform,
22537
24060
  headerRootStyleTransform,
24061
+ headerSectionBackgroundTransform,
22538
24062
  footerRootStyleTransform,
22539
24063
  footerBottomBarClassTransform,
22540
24064
  footerBottomBarContainerClassTransform,
@@ -23079,7 +24603,10 @@ var editorialLayout = stack(
23079
24603
  );
23080
24604
  var headerLayout = headerSection(
23081
24605
  {
23082
- background: "background",
24606
+ background: bindProp("$root.theme.header", {
24607
+ transforms: pipe(tx("layout.headerSectionBackground")),
24608
+ fallback: "background"
24609
+ }),
23083
24610
  allowOverflow: true,
23084
24611
  className: bindProp("$root.theme.header", {
23085
24612
  transforms: pipe(tx("layout.headerRootClass")),
@@ -23989,6 +25516,225 @@ var collectionBlockDefinition = {
23989
25516
  manifest: collectionManifest
23990
25517
  };
23991
25518
 
25519
+ // ../blocks/src/system/blocks/feature-cards.ts
25520
+ function grid3(props2, children) {
25521
+ return el("grid", props2 ?? void 0, children ?? void 0);
25522
+ }
25523
+ var sectionHeading = stack(
25524
+ { gap: "sm", className: "rb-feature-cards-heading rb-mx-auto rb-max-w-3xl rb-text-center" },
25525
+ [
25526
+ text(
25527
+ {
25528
+ as: "h2",
25529
+ className: "rb-feature-cards-title rb-text-center"
25530
+ },
25531
+ when("content.title"),
25532
+ bind("content.title")
25533
+ ),
25534
+ richText(
25535
+ {
25536
+ className: "rb-feature-cards-description rb-prose rb-mx-auto rb-max-w-none",
25537
+ style: textColorStyle("mutedText")
25538
+ },
25539
+ when("content.description"),
25540
+ bind("content.description")
25541
+ )
25542
+ ]
25543
+ );
25544
+ var featureCard = styledCard(
25545
+ [
25546
+ media(
25547
+ {
25548
+ className: "rb-feature-card-media rb-w-full rb-h-auto rb-object-cover",
25549
+ style: {
25550
+ aspectRatio: { $bind: { from: "card.aspectRatio" } }
25551
+ }
25552
+ },
25553
+ when("card.media"),
25554
+ bind("card.media")
25555
+ ),
25556
+ stack({ gap: "sm", className: "rb-feature-card-content rb-flex-1 rb-p-6" }, [
25557
+ text(
25558
+ {
25559
+ as: "h3",
25560
+ className: "rb-feature-card-title"
25561
+ },
25562
+ bind("card.title")
25563
+ ),
25564
+ richText(
25565
+ {
25566
+ className: "rb-feature-card-body rb-prose rb-max-w-none",
25567
+ style: textColorStyle("mutedText")
25568
+ },
25569
+ when("card.body"),
25570
+ bind("card.body")
25571
+ ),
25572
+ ctaRow({
25573
+ collectionPath: "ctas",
25574
+ itemName: "cta",
25575
+ gap: "sm",
25576
+ justify: "start",
25577
+ containerClassName: "rb-mt-auto"
25578
+ })
25579
+ ])
25580
+ ],
25581
+ {
25582
+ stylesFrom: "content._cardStyles",
25583
+ backgroundFrom: "content._cardStyles.background",
25584
+ baseClassName: "rb-feature-card rb-relative rb-isolate rb-overflow-hidden rb-border rb-flex rb-h-full rb-flex-col"
25585
+ },
25586
+ repeat("content.cards", "card")
25587
+ );
25588
+ var cardsLayout = styledSection({
25589
+ children: styledContainer({
25590
+ rootType: "stack",
25591
+ rootProps: { gap: "xl" },
25592
+ children: [
25593
+ sectionHeading,
25594
+ grid3(
25595
+ {
25596
+ cols: {
25597
+ $bind: {
25598
+ from: "content.columns",
25599
+ fallback: 3,
25600
+ coerce: "number"
25601
+ }
25602
+ },
25603
+ gap: "lg"
25604
+ },
25605
+ [featureCard]
25606
+ )
25607
+ ]
25608
+ }),
25609
+ baseClass: "",
25610
+ spacing: "medium"
25611
+ });
25612
+ var featureCardsConfig = {
25613
+ id: "block.feature-cards",
25614
+ title: "Feature Cards",
25615
+ category: "layout",
25616
+ includeContainerStyles: true,
25617
+ titleSource: "title",
25618
+ additionalFields: [
25619
+ {
25620
+ id: "title",
25621
+ type: "text",
25622
+ label: "Title",
25623
+ required: false,
25624
+ multiline: false,
25625
+ maxLength: 120
25626
+ },
25627
+ {
25628
+ id: "description",
25629
+ type: "richText",
25630
+ label: "Description",
25631
+ required: false,
25632
+ ui: {
25633
+ richTextVariant: "limited"
25634
+ }
25635
+ },
25636
+ {
25637
+ id: "columns",
25638
+ type: "select",
25639
+ label: "Columns",
25640
+ required: false,
25641
+ defaultValue: "3",
25642
+ multiple: false,
25643
+ options: [
25644
+ { value: "2", label: "2 columns" },
25645
+ { value: "3", label: "3 columns" },
25646
+ { value: "4", label: "4 columns" }
25647
+ ],
25648
+ ui: { intent: "display" }
25649
+ },
25650
+ {
25651
+ id: "cards",
25652
+ type: "repeater",
25653
+ label: "Cards",
25654
+ required: false,
25655
+ minItems: 1,
25656
+ maxItems: 8,
25657
+ itemLabel: "Card",
25658
+ itemLabelSource: "title",
25659
+ allowConversion: true,
25660
+ ui: {
25661
+ intent: "content"
25662
+ },
25663
+ schema: {
25664
+ fields: [
25665
+ {
25666
+ id: "media",
25667
+ type: "media",
25668
+ label: "Image",
25669
+ required: false,
25670
+ mediaKinds: ["image"]
25671
+ },
25672
+ createAspectRatioField({
25673
+ id: "aspectRatio",
25674
+ label: "Image aspect ratio",
25675
+ defaultValue: "4/3",
25676
+ visibleWhen: { field: "media", notEquals: null }
25677
+ }),
25678
+ {
25679
+ id: "title",
25680
+ type: "text",
25681
+ label: "Title",
25682
+ required: true,
25683
+ multiline: false,
25684
+ maxLength: 120
25685
+ },
25686
+ {
25687
+ id: "body",
25688
+ type: "richText",
25689
+ label: "Text",
25690
+ required: false,
25691
+ ui: {
25692
+ richTextVariant: "limited"
25693
+ }
25694
+ },
25695
+ createCtasRepeater({
25696
+ label: "Calls to action",
25697
+ itemLabel: "CTA",
25698
+ maxItems: 1,
25699
+ button: {
25700
+ variants: [
25701
+ { value: "primary", label: "Primary" },
25702
+ { value: "secondary", label: "Secondary" },
25703
+ { value: "outline", label: "Outline" },
25704
+ { value: "ghost", label: "Ghost" },
25705
+ { value: "link", label: "Link" }
25706
+ ],
25707
+ defaultVariant: "ghost"
25708
+ }
25709
+ })
25710
+ ]
25711
+ }
25712
+ },
25713
+ cardStylesField({
25714
+ id: "_cardStyles",
25715
+ label: "Card styles"
25716
+ })
25717
+ ],
25718
+ layout: cardsLayout,
25719
+ variants: {
25720
+ cards: cardsLayout
25721
+ },
25722
+ defaultVariant: "cards",
25723
+ variantOptions: {
25724
+ cards: {
25725
+ label: "Cards",
25726
+ description: "A responsive grid of image cards with optional calls to action."
25727
+ }
25728
+ },
25729
+ description: "A card grid for offerings, services, classes, benefits, or featured links.",
25730
+ tags: ["cards", "features", "offerings", "services", "classes", "grid", "links"],
25731
+ icon: "PanelsTopLeft"
25732
+ };
25733
+ var featureCardsManifest = createBlockManifest(featureCardsConfig);
25734
+ var featureCardsBlockDefinition = {
25735
+ manifest: featureCardsManifest
25736
+ };
25737
+
23992
25738
  // ../blocks/src/system/fields/carousel.ts
23993
25739
  var delayOptions = [
23994
25740
  { value: "3000", label: "3 seconds" },
@@ -24074,69 +25820,6 @@ function createCarouselBehaviorFields(options = {}) {
24074
25820
  return fields3;
24075
25821
  }
24076
25822
 
24077
- // ../blocks/src/system/fields/imageLayout.ts
24078
- function createImageColSizeField(options = {}) {
24079
- const {
24080
- id = "imageColSize",
24081
- label = "Image column size",
24082
- description = "Controls how large the image/thumbnail column is at desktop breakpoints.",
24083
- defaultValue = "1/3",
24084
- uiIntent = "display",
24085
- visibleWhen
24086
- } = options;
24087
- return {
24088
- id,
24089
- type: "select",
24090
- label,
24091
- description,
24092
- required: false,
24093
- defaultValue,
24094
- multiple: false,
24095
- options: [
24096
- { value: "1/4", label: "Small (1/4)" },
24097
- { value: "1/3", label: "Medium (1/3)" },
24098
- { value: "2/5", label: "Large (2/5)" },
24099
- { value: "1/2", label: "Extra large (1/2)" },
24100
- { value: "2/3", label: "Huge (2/3)" }
24101
- ],
24102
- ui: {
24103
- intent: uiIntent,
24104
- ...visibleWhen ? { visibleWhen } : {}
24105
- }
24106
- };
24107
- }
24108
- function createImagePositionField(options = {}) {
24109
- const {
24110
- id = "imagePosition",
24111
- label = "Image position",
24112
- description = "Choose which side the image appears on.",
24113
- defaultValue = "left",
24114
- includeAlternate = false,
24115
- uiIntent = "display",
24116
- visibleWhen
24117
- } = options;
24118
- const positionOptions = [
24119
- { value: "left", label: "Left" },
24120
- { value: "right", label: "Right" },
24121
- ...includeAlternate ? [{ value: "alternate", label: "Alternate" }] : []
24122
- ];
24123
- return {
24124
- id,
24125
- type: "select",
24126
- label,
24127
- description,
24128
- required: false,
24129
- defaultValue,
24130
- multiple: false,
24131
- // Spread to get a mutable array type without unsafe casts.
24132
- options: [...positionOptions],
24133
- ui: {
24134
- intent: uiIntent,
24135
- ...visibleWhen ? { visibleWhen } : {}
24136
- }
24137
- };
24138
- }
24139
-
24140
25823
  // ../blocks/src/system/blocks/media-text.ts
24141
25824
  var mediaTextFrameCapability = defineFrameCapability([
24142
25825
  "plain",
@@ -24260,26 +25943,13 @@ var mediaTextManifest = createBlockManifest({
24260
25943
  },
24261
25944
  ui: { intent: "behavior" }
24262
25945
  }),
24263
- {
25946
+ createAspectRatioField({
24264
25947
  id: "aspectRatio",
24265
- type: "select",
24266
25948
  label: "Media aspect ratio",
24267
25949
  description: "Crop media to a consistent aspect ratio.",
24268
- required: false,
24269
25950
  defaultValue: "auto",
24270
- multiple: false,
24271
- options: [
24272
- { value: "auto", label: "Auto (original)" },
24273
- { value: "16/9", label: "16:9 (Landscape)" },
24274
- { value: "4/3", label: "4:3 (Standard)" },
24275
- { value: "1/1", label: "1:1 (Square)" },
24276
- { value: "3/4", label: "3:4 (Portrait)" }
24277
- ],
24278
- ui: {
24279
- intent: "display",
24280
- visibleWhen: { field: "images", notEquals: null }
24281
- }
24282
- },
25951
+ visibleWhen: { field: "images", notEquals: null }
25952
+ }),
24283
25953
  {
24284
25954
  id: "text",
24285
25955
  type: "richText",
@@ -24409,7 +26079,7 @@ var mediaTextManifest = createBlockManifest({
24409
26079
  whenImagesLength(0)
24410
26080
  );
24411
26081
  const defaultInner = el("div", {}, [defaultImagesLayout, defaultTextOnlyLayout]);
24412
- const defaultLayout = styledSection({
26082
+ const defaultLayout2 = styledSection({
24413
26083
  children: styledContainer({
24414
26084
  rootType: "stack",
24415
26085
  rootProps: { gap: "lg" },
@@ -24441,9 +26111,9 @@ var mediaTextManifest = createBlockManifest({
24441
26111
  spacing: "medium"
24442
26112
  });
24443
26113
  return {
24444
- layout: defaultLayout,
26114
+ layout: defaultLayout2,
24445
26115
  variants: {
24446
- default: defaultLayout
26116
+ default: defaultLayout2
24447
26117
  },
24448
26118
  defaultVariant: "default",
24449
26119
  variantOptions: {
@@ -30079,7 +31749,7 @@ var embedBlockDefinition = {
30079
31749
  };
30080
31750
 
30081
31751
  // ../blocks/src/system/blocks/image-gallery.ts
30082
- var grid3 = (props2, children, ...mods) => el("grid", props2 ?? void 0, children ?? void 0, ...mods);
31752
+ var grid4 = (props2, children, ...mods) => el("grid", props2 ?? void 0, children ?? void 0, ...mods);
30083
31753
  var galleryContainer = (children, opts) => {
30084
31754
  const gap = opts?.gap ?? "md";
30085
31755
  const withExtraClass = (baseClass) => opts?.className ? `${baseClass} ${opts.className}` : baseClass;
@@ -30159,7 +31829,7 @@ var galleryItem = (options) => stack(
30159
31829
  ],
30160
31830
  repeat("content.images", "item")
30161
31831
  );
30162
- var gridLayout3 = grid3(
31832
+ var gridLayout3 = grid4(
30163
31833
  {
30164
31834
  className: "rb-grid rb-grid-cols-1 rb-gap-4 rb-sm-grid-cols-2 rb-md-grid-cols-3"
30165
31835
  },
@@ -30762,7 +32432,7 @@ var imageGalleryBlockDefinition = {
30762
32432
  };
30763
32433
 
30764
32434
  // ../blocks/src/system/blocks/video-grid.ts
30765
- var grid4 = (props2, children, ...mods) => el("grid", props2 ?? void 0, children ?? void 0, ...mods);
32435
+ var grid5 = (props2, children, ...mods) => el("grid", props2 ?? void 0, children ?? void 0, ...mods);
30766
32436
  var videoItem = (options) => stack(
30767
32437
  { gap: "xs", className: options.containerClassName },
30768
32438
  [
@@ -30812,7 +32482,7 @@ var gridColumnsClass = (columns) => {
30812
32482
  return "rb-grid rb-grid-cols-1 rb-gap-6 rb-sm-grid-cols-2 rb-md-grid-cols-3";
30813
32483
  }
30814
32484
  };
30815
- var createGridLayout = (columns) => grid4(
32485
+ var createGridLayout = (columns) => grid5(
30816
32486
  {
30817
32487
  className: gridColumnsClass(columns)
30818
32488
  },
@@ -34095,6 +35765,40 @@ var systemBlockDefinitionsRaw = [
34095
35765
  })
34096
35766
  ]
34097
35767
  })),
35768
+ withDesignCapability("block.intro", introBlockDefinition, declareBlockDesignCapability({
35769
+ sectionSurfaces: "supported",
35770
+ contentFrames: ["plain", "panel"],
35771
+ itemSurfaces: "unsupported",
35772
+ headingDecorations: ["organic-squiggle"]
35773
+ }), defineBlockDesignMetadata({
35774
+ flow: bodyFlow,
35775
+ layoutProfiles: [
35776
+ layoutProfile({
35777
+ variantKey: "centered-copy",
35778
+ family: "centered",
35779
+ weight: "featured",
35780
+ bias: "soft"
35781
+ }),
35782
+ layoutProfile({
35783
+ variantKey: "statement-copy",
35784
+ family: "split",
35785
+ weight: "featured",
35786
+ bias: "merge"
35787
+ }),
35788
+ layoutProfile({
35789
+ variantKey: "statement-media",
35790
+ family: "media-text",
35791
+ weight: "featured",
35792
+ bias: "soft"
35793
+ }),
35794
+ layoutProfile({
35795
+ variantKey: "media-copy",
35796
+ family: "media-text",
35797
+ weight: "featured",
35798
+ bias: "soft"
35799
+ })
35800
+ ]
35801
+ })),
34098
35802
  withDesignCapability("block.body-text", bodyTextBlockDefinition, sectionOnly(), defineBlockDesignMetadata({
34099
35803
  flow: bodyFlow,
34100
35804
  layoutProfiles: [
@@ -34155,9 +35859,17 @@ var systemBlockDefinitionsRaw = [
34155
35859
  flow: conversionFlow,
34156
35860
  layoutProfiles: [layoutProfile({ variantKey: "default", family: "form", weight: "standard" })]
34157
35861
  })),
34158
- withDesignCapability("block.faq", faqBlockDefinition, withEyebrowCapability(panelAndItemsCapable(), standardEyebrowTreatments), defineBlockDesignMetadata({
35862
+ withDesignCapability("block.faq", faqBlockDefinition, withEyebrowCapability(declareBlockDesignCapability({
35863
+ sectionSurfaces: "supported",
35864
+ contentFrames: ["plain", "panel"],
35865
+ itemSurfaces: "supported",
35866
+ accordionIconSets: ["plus", "chevron", "caret", "minimal-cross"]
35867
+ }), standardEyebrowTreatments), defineBlockDesignMetadata({
34159
35868
  flow: bodyFlow,
34160
- layoutProfiles: [layoutProfile({ variantKey: "default", family: "stack", weight: "standard" })]
35869
+ layoutProfiles: [
35870
+ layoutProfile({ variantKey: "default", family: "stack", weight: "standard" }),
35871
+ layoutProfile({ variantKey: "two-column", family: "split", weight: "standard" })
35872
+ ]
34161
35873
  })),
34162
35874
  withDesignCapability("block.site-header", siteHeaderBlockDefinition, declareNoBlockDesignCapability("site-chrome"), defineBlockDesignMetadata({
34163
35875
  flow: siteChromeFlow,
@@ -34171,7 +35883,8 @@ var systemBlockDefinitionsRaw = [
34171
35883
  sectionSurfaces: "supported",
34172
35884
  contentFrames: ["plain", "panel"],
34173
35885
  itemSurfaces: "supported",
34174
- testimonialCardTreatments: ["default", "accent-quote"]
35886
+ testimonialCardTreatments: ["default", "accent-quote"],
35887
+ headingDecorations: ["short-center-rule"]
34175
35888
  }), defineBlockDesignMetadata({
34176
35889
  flow: proofFlow,
34177
35890
  layoutProfiles: [
@@ -34197,6 +35910,22 @@ var systemBlockDefinitionsRaw = [
34197
35910
  flow: offeringsFlow,
34198
35911
  layoutProfiles: [layoutProfile({ variantKey: "default", family: "grid", weight: "standard" })]
34199
35912
  })),
35913
+ withDesignCapability("block.feature-cards", featureCardsBlockDefinition, declareBlockDesignCapability({
35914
+ sectionSurfaces: "supported",
35915
+ contentFrames: ["plain", "panel"],
35916
+ itemSurfaces: "supported",
35917
+ headingDecorations: ["short-center-rule"]
35918
+ }), defineBlockDesignMetadata({
35919
+ flow: offeringsFlow,
35920
+ layoutProfiles: [
35921
+ layoutProfile({
35922
+ variantKey: "cards",
35923
+ family: "grid",
35924
+ weight: "standard",
35925
+ bias: "soft"
35926
+ })
35927
+ ]
35928
+ })),
34200
35929
  withDesignCapability("block.media-text", mediaTextBlockDefinition, mediaPanelCapable(), defineBlockDesignMetadata({
34201
35930
  flow: mediaFlow,
34202
35931
  layoutProfiles: [
@@ -36423,6 +38152,42 @@ function normalizeBoolean2(value) {
36423
38152
  return Boolean(value);
36424
38153
  }
36425
38154
 
38155
+ // ../blocks/src/system/runtime/nodes/accordionIconTreatment.ts
38156
+ function resolveAccordionIconStyle(iconStyle, iconTreatment) {
38157
+ if (iconTreatment) {
38158
+ switch (iconTreatment.iconSet) {
38159
+ case "plus":
38160
+ return "plus-minus";
38161
+ case "chevron":
38162
+ return "chevron";
38163
+ case "caret":
38164
+ return "caret";
38165
+ case "minimal-cross":
38166
+ return "plus-minus";
38167
+ default:
38168
+ return assertNever4(iconTreatment.iconSet);
38169
+ }
38170
+ }
38171
+ return iconStyle && iconStyle in ICON_CONFIG ? iconStyle : "chevron";
38172
+ }
38173
+ function accordionIconColorStyle(iconTreatment) {
38174
+ const token = iconTreatment?.colorToken;
38175
+ if (!token || token === "current") return void 0;
38176
+ const themeToken = resolveIconColorToken(token);
38177
+ return {
38178
+ color: rgbColorValue(themeToken),
38179
+ ...iconTreatment.openColorToken && iconTreatment.openColorToken !== "current" ? {
38180
+ "--accordion-icon-open-color": rgbColorValue(resolveIconColorToken(iconTreatment.openColorToken))
38181
+ } : {}
38182
+ };
38183
+ }
38184
+ function resolveIconColorToken(token) {
38185
+ return token === "muted" ? "mutedText" : token;
38186
+ }
38187
+ function assertNever4(value) {
38188
+ throw new Error(`Unhandled accordion icon set: ${String(value)}`);
38189
+ }
38190
+
36426
38191
  // ../blocks/src/system/runtime/nodes/accordion.server.tsx
36427
38192
  import { jsx as jsx22, jsxs as jsxs9 } from "react/jsx-runtime";
36428
38193
  var ACCORDION_ICONS = {
@@ -36462,15 +38227,17 @@ var AccordionItemNodeSSR = ({
36462
38227
  content,
36463
38228
  question,
36464
38229
  answer,
36465
- iconStyle
38230
+ iconStyle,
38231
+ iconTreatment
36466
38232
  }) => {
36467
38233
  const resolvedValue = value !== void 0 && value !== null ? String(value) : void 0;
36468
38234
  const triggerSource = trigger ?? question;
36469
38235
  const contentSource = content ?? answer;
36470
- const resolvedIconStyle = iconStyle && iconStyle in ICON_CONFIG ? iconStyle : "chevron";
38236
+ const resolvedIconStyle = resolveAccordionIconStyle(iconStyle, iconTreatment);
36471
38237
  const iconConfig = ICON_CONFIG[resolvedIconStyle];
36472
38238
  const ClosedIconComponent = ACCORDION_ICONS[iconConfig.closedIcon];
36473
38239
  const OpenIconComponent = iconConfig.openIcon ? ACCORDION_ICONS[iconConfig.openIcon] : null;
38240
+ const iconColorStyle = accordionIconColorStyle(iconTreatment);
36474
38241
  return /* @__PURE__ */ jsxs9(
36475
38242
  "div",
36476
38243
  {
@@ -36480,10 +38247,20 @@ var AccordionItemNodeSSR = ({
36480
38247
  children: [
36481
38248
  /* @__PURE__ */ jsxs9("div", { className: "accordion-trigger", role: "button", tabIndex: 0, "aria-expanded": "false", children: [
36482
38249
  /* @__PURE__ */ jsx22("span", { className: "accordion-trigger-text", children: resolveNode(triggerSource) }),
36483
- /* @__PURE__ */ jsxs9("span", { className: "accordion-icon", "aria-hidden": "true", children: [
36484
- ClosedIconComponent && /* @__PURE__ */ jsx22(ClosedIconComponent, { className: "accordion-icon-closed" }),
36485
- OpenIconComponent && /* @__PURE__ */ jsx22(OpenIconComponent, { className: "accordion-icon-open" })
36486
- ] })
38250
+ /* @__PURE__ */ jsxs9(
38251
+ "span",
38252
+ {
38253
+ className: "accordion-icon",
38254
+ "aria-hidden": "true",
38255
+ "data-accordion-icon-set": iconTreatment?.iconSet,
38256
+ "data-accordion-icon-motion": iconTreatment?.motion,
38257
+ style: iconColorStyle,
38258
+ children: [
38259
+ ClosedIconComponent && /* @__PURE__ */ jsx22(ClosedIconComponent, { className: "accordion-icon-closed" }),
38260
+ OpenIconComponent && /* @__PURE__ */ jsx22(OpenIconComponent, { className: "accordion-icon-open" })
38261
+ ]
38262
+ }
38263
+ )
36487
38264
  ] }),
36488
38265
  /* @__PURE__ */ jsx22(
36489
38266
  "div",
@@ -43870,6 +45647,67 @@ function transformSdkBlockToDefinition(sdkBlock) {
43870
45647
  };
43871
45648
  }
43872
45649
 
45650
+ // ../blocks/src/customBlockRegistry.ts
45651
+ function isCustomBlockKind(blockKind) {
45652
+ return blockKind.startsWith("custom.");
45653
+ }
45654
+ function transformToBlockDescriptor(sdkBlock, source = "sdk") {
45655
+ return {
45656
+ name: sdkBlock.id,
45657
+ title: sdkBlock.title,
45658
+ description: sdkBlock.description,
45659
+ category: sdkBlock.category,
45660
+ tags: sdkBlock.tags,
45661
+ icon: sdkBlock.icon,
45662
+ definition: transformSdkBlockToDefinition(sdkBlock),
45663
+ source
45664
+ };
45665
+ }
45666
+ function toResolvedCustomBlock(manifest, source) {
45667
+ return {
45668
+ blockKind: manifest.id,
45669
+ manifest: transformSdkBlockToManifest(manifest),
45670
+ source,
45671
+ descriptor: transformToBlockDescriptor(
45672
+ manifest,
45673
+ source.kind === "managed-database" ? "database" : "sdk"
45674
+ )
45675
+ };
45676
+ }
45677
+ function createCustomBlockRegistry({
45678
+ sdkConfig,
45679
+ customBlocks = [],
45680
+ onConflict
45681
+ }) {
45682
+ const entriesByKind = /* @__PURE__ */ new Map();
45683
+ for (const sdkBlock of sdkConfig?.customBlocks ?? []) {
45684
+ entriesByKind.set(
45685
+ sdkBlock.id,
45686
+ toResolvedCustomBlock(sdkBlock, { kind: "sdk-config" })
45687
+ );
45688
+ }
45689
+ for (const customBlock of customBlocks) {
45690
+ const existing = entriesByKind.get(customBlock.manifest.id);
45691
+ if (existing) {
45692
+ onConflict?.(
45693
+ `Skipping DB custom block "${customBlock.manifest.id}" - conflicts with SDK config block`
45694
+ );
45695
+ continue;
45696
+ }
45697
+ entriesByKind.set(
45698
+ customBlock.manifest.id,
45699
+ toResolvedCustomBlock(customBlock.manifest, customBlock.source)
45700
+ );
45701
+ }
45702
+ return {
45703
+ entries: Array.from(entriesByKind.values()),
45704
+ findManifest: (blockKind) => {
45705
+ if (!isCustomBlockKind(blockKind)) return void 0;
45706
+ return entriesByKind.get(blockKind);
45707
+ }
45708
+ };
45709
+ }
45710
+
43873
45711
  // ../blocks/src/PageRenderer.tsx
43874
45712
  import { Fragment as Fragment6, jsx as jsx52 } from "react/jsx-runtime";
43875
45713
  function PageRenderer({
@@ -44037,17 +45875,14 @@ var MemoBlockSection = React6.memo(
44037
45875
  }
44038
45876
  const OverrideComponent = getBlockOverride(block.kind, blockOverrides);
44039
45877
  let definition = getBlockDefinition(block.kind);
44040
- if (!definition && block.kind.startsWith("custom.") && sdkConfig?.customBlocks) {
44041
- const sdkBlock = sdkConfig.customBlocks.find((b) => b.id === block.kind);
44042
- if (sdkBlock) {
44043
- definition = transformSdkBlockToDefinition(sdkBlock);
44044
- }
44045
- }
44046
- if (!definition && block.kind.startsWith("custom.") && customBlocks) {
44047
- const dbBlock = customBlocks.find((b) => b.id === block.kind);
44048
- if (dbBlock) {
44049
- definition = transformSdkBlockToDefinition(dbBlock);
44050
- }
45878
+ if (!definition && block.kind.startsWith("custom.")) {
45879
+ definition = createCustomBlockRegistry({
45880
+ sdkConfig,
45881
+ customBlocks: (customBlocks ?? []).map((manifest) => ({
45882
+ manifest,
45883
+ source: { kind: "managed-database" }
45884
+ }))
45885
+ }).findManifest(block.kind)?.descriptor.definition;
44051
45886
  }
44052
45887
  if (!definition) {
44053
45888
  if (OverrideComponent) {
@@ -44074,13 +45909,16 @@ var MemoBlockSection = React6.memo(
44074
45909
  }
44075
45910
  if (block.kind.startsWith("custom.") && shouldDebugCustomBlocks()) {
44076
45911
  try {
44077
- console.warn("[blocks:PageRenderer] custom block definition missing", {
44078
- blockId: block.id ?? null,
44079
- blockKind: block.kind,
44080
- hasOverride: Boolean(OverrideComponent),
44081
- sdkCustomBlocksCount: sdkConfig?.customBlocks?.length ?? 0,
44082
- dbCustomBlocksCount: customBlocks?.length ?? 0
44083
- });
45912
+ console.warn(
45913
+ "[blocks:PageRenderer] custom block definition missing",
45914
+ {
45915
+ blockId: block.id ?? null,
45916
+ blockKind: block.kind,
45917
+ hasOverride: Boolean(OverrideComponent),
45918
+ sdkCustomBlocksCount: sdkConfig?.customBlocks?.length ?? 0,
45919
+ dbCustomBlocksCount: customBlocks?.length ?? 0
45920
+ }
45921
+ );
44084
45922
  } catch {
44085
45923
  }
44086
45924
  }
@@ -44094,12 +45932,15 @@ var MemoBlockSection = React6.memo(
44094
45932
  if (!OverrideComponent && !manifestHasLayout) {
44095
45933
  if (block.kind.startsWith("custom.") && shouldDebugCustomBlocks()) {
44096
45934
  try {
44097
- console.warn("[blocks:PageRenderer] custom block has no layout/variants and no override", {
44098
- blockId: block.id ?? null,
44099
- blockKind: block.kind,
44100
- hasOverride: false,
44101
- manifestKeys: Object.keys(definition.manifest ?? {}).sort()
44102
- });
45935
+ console.warn(
45936
+ "[blocks:PageRenderer] custom block has no layout/variants and no override",
45937
+ {
45938
+ blockId: block.id ?? null,
45939
+ blockKind: block.kind,
45940
+ hasOverride: false,
45941
+ manifestKeys: Object.keys(definition.manifest ?? {}).sort()
45942
+ }
45943
+ );
44103
45944
  } catch {
44104
45945
  }
44105
45946
  }
@@ -44133,9 +45974,10 @@ var MemoBlockSection = React6.memo(
44133
45974
  if (parsed.success) {
44134
45975
  data = parsed.data;
44135
45976
  } else if (usePlaceholders) {
44136
- const relaxed = getCachedValidator(definition.manifest, "relaxed").safeParse(
44137
- content
44138
- );
45977
+ const relaxed = getCachedValidator(
45978
+ definition.manifest,
45979
+ "relaxed"
45980
+ ).safeParse(content);
44139
45981
  if (relaxed.success) {
44140
45982
  data = relaxed.data;
44141
45983
  } else {
@@ -58434,7 +60276,7 @@ var SimpleCache = class {
58434
60276
  };
58435
60277
 
58436
60278
  // src/version.ts
58437
- var SDK_VERSION = "0.76.0";
60279
+ var SDK_VERSION = "0.77.0";
58438
60280
 
58439
60281
  // src/client/error.ts
58440
60282
  var RiverbankApiError = class _RiverbankApiError extends Error {
@@ -58862,6 +60704,24 @@ function getPrebuildModule() {
58862
60704
  return null;
58863
60705
  }
58864
60706
  }
60707
+ function mergeDefaultHeaders(defaultHeaders, options) {
60708
+ if (!defaultHeaders || Object.keys(defaultHeaders).length === 0) {
60709
+ return options;
60710
+ }
60711
+ return {
60712
+ ...options,
60713
+ headers: {
60714
+ ...defaultHeaders,
60715
+ ...Object.fromEntries(new Headers(options?.headers).entries())
60716
+ }
60717
+ };
60718
+ }
60719
+ function withDefaultHeaders(apiClient, defaultHeaders) {
60720
+ return async (params) => apiClient({
60721
+ ...params,
60722
+ options: mergeDefaultHeaders(defaultHeaders, params.options)
60723
+ });
60724
+ }
58865
60725
  setSdkVersion(SDK_VERSION);
58866
60726
  var DEFAULT_BROWSER_TIMEOUT_MS = 5e3;
58867
60727
  var DEFAULT_SERVER_TIMEOUT_MS = 8e3;
@@ -59061,7 +60921,8 @@ function createRiverbankClient(config) {
59061
60921
  keyType = "preview";
59062
60922
  break;
59063
60923
  }
59064
- const apiClient = authConfig.type === "none" ? createInternalAPIClient(config.baseUrl) : authConfig.type === "api-key" ? createBearerAPIClient(authConfig.key, config.baseUrl) : createBearerAPIClient(authConfig.token, config.baseUrl);
60924
+ const baseApiClient = authConfig.type === "none" ? createInternalAPIClient(config.baseUrl) : authConfig.type === "api-key" ? createBearerAPIClient(authConfig.key, config.baseUrl) : createBearerAPIClient(authConfig.token, config.baseUrl);
60925
+ const apiClient = withDefaultHeaders(baseApiClient, config.defaultHeaders);
59065
60926
  const cache = new SimpleCache({
59066
60927
  maxSize: cacheMaxSize,
59067
60928
  ttl: cacheTTL,