@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
@@ -1418,6 +1418,9 @@ var manifestSchema = z3.object({
1418
1418
  var TEL_RE = /^[+()0-9\s-]{3,}$/;
1419
1419
  var SLUG_PATTERN = /^(?:[a-z0-9]+(?:-[a-z0-9]+)*)(?:\/(?:[a-z0-9]+(?:-[a-z0-9]+)*))*$/;
1420
1420
  var ALLOWED_URL_PROTOCOLS = ["http:", "https:"];
1421
+ var DATE_PATTERN = /^(?<year>[1-9]\d{3})-(?<month>\d{2})-(?<day>\d{2})$/;
1422
+ var TIME_PATTERN = /^(?<hours>[01]\d|2[0-3]):(?<minutes>[0-5]\d)$/;
1423
+ 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)$/;
1421
1424
  function assertNever(value) {
1422
1425
  throw new Error(`Unhandled field validation variant: ${JSON.stringify(value)}`);
1423
1426
  }
@@ -1450,6 +1453,12 @@ function fieldIssueToMessage(issue2) {
1450
1453
  return "Check the format and try again";
1451
1454
  case "invalidUrl":
1452
1455
  return "Enter a valid web address";
1456
+ case "invalidDate":
1457
+ return "Choose a valid date";
1458
+ case "invalidTime":
1459
+ return "Choose a valid time";
1460
+ case "invalidDateTime":
1461
+ return "Choose a valid date and time";
1453
1462
  case "invalidNumber":
1454
1463
  return `${issue2.label} needs a number`;
1455
1464
  case "tooSmall":
@@ -1486,12 +1495,16 @@ function deriveFieldValidationPlan(field, path = [field.id]) {
1486
1495
  case "text": {
1487
1496
  const inputType = field.ui?.inputType;
1488
1497
  if (inputType === "number") {
1489
- const constraints2 = commonConstraints(required, { kind: "numberType" });
1498
+ const constraints2 = commonConstraints(required, {
1499
+ kind: "numberType"
1500
+ });
1490
1501
  if (typeof field.ui?.min === "number") constraints2.push({ kind: "numberMin", minimum: field.ui.min });
1491
1502
  if (typeof field.ui?.max === "number") constraints2.push({ kind: "numberMax", maximum: field.ui.max });
1492
1503
  return makePlan("number", "number", field, path, required, constraints2);
1493
1504
  }
1494
- const constraints = commonConstraints(required, { kind: "textType" });
1505
+ const constraints = commonConstraints(required, {
1506
+ kind: "textType"
1507
+ });
1495
1508
  if (inputType === "email") constraints.push({ kind: "emailFormat" });
1496
1509
  if (inputType === "tel") constraints.push({ kind: "phoneFormat" });
1497
1510
  if (field.ui?.pattern) constraints.push({ kind: "patternFormat", pattern: field.ui.pattern });
@@ -1499,7 +1512,9 @@ function deriveFieldValidationPlan(field, path = [field.id]) {
1499
1512
  return makePlan("string", "string", field, path, required, constraints);
1500
1513
  }
1501
1514
  case "number": {
1502
- const constraints = commonConstraints(required, { kind: "numberType" });
1515
+ const constraints = commonConstraints(required, {
1516
+ kind: "numberType"
1517
+ });
1503
1518
  if (typeof field.min === "number") constraints.push({ kind: "numberMin", minimum: field.min });
1504
1519
  if (typeof field.max === "number") constraints.push({ kind: "numberMax", maximum: field.max });
1505
1520
  return makePlan("number", "number", field, path, required, constraints);
@@ -1510,23 +1525,42 @@ function deriveFieldValidationPlan(field, path = [field.id]) {
1510
1525
  return makePlan("string", "string", field, path, required, constraints);
1511
1526
  }
1512
1527
  case "url":
1513
- return makePlan("string", "string", field, path, required, commonConstraints(
1528
+ return makePlan(
1529
+ "string",
1530
+ "string",
1531
+ field,
1532
+ path,
1514
1533
  required,
1515
- { kind: "textType" },
1516
- { kind: "urlFormat", allowRelative: Boolean(field.allowRelative) }
1517
- ));
1534
+ commonConstraints(required, { kind: "textType" }, { kind: "urlFormat", allowRelative: Boolean(field.allowRelative) })
1535
+ );
1518
1536
  case "reference":
1519
1537
  return makePlan("string", "string", field, path, required, commonConstraints(required, { kind: "referenceText" }));
1520
1538
  case "date":
1539
+ return makePlan("string", "string", field, path, required, commonConstraints(required, { kind: "textType" }, { kind: "dateFormat" }));
1521
1540
  case "time":
1541
+ return makePlan("string", "string", field, path, required, commonConstraints(required, { kind: "textType" }, { kind: "timeFormat" }));
1522
1542
  case "datetime":
1523
- return makePlan("string", "string", field, path, required, commonConstraints(required, { kind: "textType" }));
1543
+ return makePlan(
1544
+ "string",
1545
+ "string",
1546
+ field,
1547
+ path,
1548
+ required,
1549
+ commonConstraints(required, { kind: "textType" }, { kind: "datetimeFormat" })
1550
+ );
1524
1551
  case "select":
1525
- return makePlan("select", "select", field, path, required, commonConstraints(required, {
1526
- kind: "selectOption",
1527
- source: resolveSelectConstraintSource(field),
1528
- multiple: Boolean(field.multiple)
1529
- }));
1552
+ return makePlan(
1553
+ "select",
1554
+ "select",
1555
+ field,
1556
+ path,
1557
+ required,
1558
+ commonConstraints(required, {
1559
+ kind: "selectOption",
1560
+ source: resolveSelectConstraintSource(field),
1561
+ multiple: Boolean(field.multiple)
1562
+ })
1563
+ );
1530
1564
  case "richText":
1531
1565
  return makePlan("richText", "object", field, path, required, commonConstraints(required, { kind: "richTextDoc" }));
1532
1566
  case "media":
@@ -1539,7 +1573,11 @@ function deriveFieldValidationPlan(field, path = [field.id]) {
1539
1573
  case "repeater":
1540
1574
  return {
1541
1575
  ...makePlan("repeater", "array", field, path, required, commonConstraints(required, { kind: "arrayType" })),
1542
- ...field.polymorphic && field.itemTypes ? { repeatedItemVariants: deriveRepeatedItemVariants(field, [...path, 0]) } : { repeatedItemPlan: deriveNestedFieldPlans(getRepeaterFields(field), [...path, 0]) },
1576
+ ...field.polymorphic && field.itemTypes ? {
1577
+ repeatedItemVariants: deriveRepeatedItemVariants(field, [...path, 0])
1578
+ } : {
1579
+ repeatedItemPlan: deriveNestedFieldPlans(getRepeaterFields(field), [...path, 0])
1580
+ },
1543
1581
  constraints: withRepeaterItemConstraints(field, commonConstraints(required, { kind: "arrayType" }))
1544
1582
  };
1545
1583
  case "group":
@@ -1624,7 +1662,10 @@ function resolveSelectConstraintSource(field) {
1624
1662
  const source = normalizeSelectSource(field);
1625
1663
  switch (source.kind) {
1626
1664
  case "static":
1627
- return { kind: "static", values: field.options.map((option) => option.value) };
1665
+ return {
1666
+ kind: "static",
1667
+ values: field.options.map((option) => option.value)
1668
+ };
1628
1669
  case "site":
1629
1670
  case "sdk":
1630
1671
  return { kind: "runtime", source: source.kind };
@@ -1720,7 +1761,9 @@ function normalizeFieldValue(plan, value, ctx) {
1720
1761
  }
1721
1762
  function normalizeObjectChildren(children, value, ctx) {
1722
1763
  if (!value || typeof value !== "object" || Array.isArray(value)) return value;
1723
- const normalized = { ...value };
1764
+ const normalized = {
1765
+ ...value
1766
+ };
1724
1767
  for (const child of children) {
1725
1768
  normalized[child.fieldId] = normalizeFieldValue(child, normalized[child.fieldId], ctx);
1726
1769
  }
@@ -1814,6 +1857,12 @@ function validateStringConstraint(plan, constraint, value) {
1814
1857
  }
1815
1858
  case "urlFormat":
1816
1859
  return isValidUrl(value, constraint.allowRelative) ? [] : [issue(plan, "invalidUrl")];
1860
+ case "dateFormat":
1861
+ return isValidDateString(value) ? [] : [issue(plan, "invalidDate")];
1862
+ case "timeFormat":
1863
+ return isValidTimeString(value) ? [] : [issue(plan, "invalidTime")];
1864
+ case "datetimeFormat":
1865
+ return isValidDateTimeInstantString(value) ? [] : [issue(plan, "invalidDateTime")];
1817
1866
  case "slugFormat":
1818
1867
  return SLUG_PATTERN.test(value) ? [] : [issue(plan, "invalidSlug")];
1819
1868
  default:
@@ -1850,17 +1899,24 @@ function validateRepeaterPlan(plan, value, ctx) {
1850
1899
  case "arrayType":
1851
1900
  return [];
1852
1901
  case "minItems":
1853
- return value.length < constraint.minimum ? [issue(plan, "tooFewItems", { minimum: constraint.minimum, itemLabel: "item" })] : [];
1902
+ return value.length < constraint.minimum ? [
1903
+ issue(plan, "tooFewItems", {
1904
+ minimum: constraint.minimum,
1905
+ itemLabel: "item"
1906
+ })
1907
+ ] : [];
1854
1908
  case "maxItems":
1855
- return value.length > constraint.maximum ? [issue(plan, "tooManyItems", { maximum: constraint.maximum, itemLabel: "item" })] : [];
1909
+ return value.length > constraint.maximum ? [
1910
+ issue(plan, "tooManyItems", {
1911
+ maximum: constraint.maximum,
1912
+ itemLabel: "item"
1913
+ })
1914
+ ] : [];
1856
1915
  default:
1857
1916
  return assertNever(constraint);
1858
1917
  }
1859
1918
  });
1860
- return [
1861
- ...constraintIssues,
1862
- ...value.flatMap((item, index) => validateRepeaterItem(plan, item, index, ctx))
1863
- ];
1919
+ return [...constraintIssues, ...value.flatMap((item, index) => validateRepeaterItem(plan, item, index, ctx))];
1864
1920
  }
1865
1921
  function validateRepeaterItem(plan, item, index, ctx) {
1866
1922
  if (!isPlainObject(item)) return [];
@@ -1903,9 +1959,7 @@ function rebaseFieldPlanPath(plan, fromPrefix, toPrefix) {
1903
1959
  }))
1904
1960
  } : {},
1905
1961
  ...plan.repeatedItemPlan ? {
1906
- repeatedItemPlan: plan.repeatedItemPlan.map(
1907
- (fieldPlan) => rebaseFieldPlanPath(fieldPlan, fromPrefix, toPrefix)
1908
- )
1962
+ repeatedItemPlan: plan.repeatedItemPlan.map((fieldPlan) => rebaseFieldPlanPath(fieldPlan, fromPrefix, toPrefix))
1909
1963
  } : {}
1910
1964
  };
1911
1965
  case "string":
@@ -1992,6 +2046,9 @@ function addFieldIssueToZodContext(zodCtx, validationIssue, rootPath) {
1992
2046
  case "invalidPhone":
1993
2047
  case "invalidPattern":
1994
2048
  case "invalidUrl":
2049
+ case "invalidDate":
2050
+ case "invalidTime":
2051
+ case "invalidDateTime":
1995
2052
  case "invalidNumber":
1996
2053
  case "tooSmall":
1997
2054
  case "tooLarge":
@@ -2031,6 +2088,53 @@ function isValidUrl(value, allowRelative) {
2031
2088
  return false;
2032
2089
  }
2033
2090
  }
2091
+ function isValidDateString(value) {
2092
+ const match = DATE_PATTERN.exec(value);
2093
+ if (!match?.groups) return false;
2094
+ const year = Number(match.groups.year);
2095
+ const month = Number(match.groups.month);
2096
+ const day = Number(match.groups.day);
2097
+ return isValidCalendarDate(year, month, day);
2098
+ }
2099
+ function isValidTimeString(value) {
2100
+ return TIME_PATTERN.test(value);
2101
+ }
2102
+ function isValidDateTimeInstantString(value) {
2103
+ const match = DATETIME_PATTERN.exec(value);
2104
+ if (!match?.groups) return false;
2105
+ const datePart = match.groups.date;
2106
+ if (!datePart || !isValidDateString(datePart)) return false;
2107
+ return !Number.isNaN(Date.parse(value));
2108
+ }
2109
+ function isValidCalendarDate(year, month, day) {
2110
+ if (!Number.isInteger(year) || !Number.isInteger(month) || !Number.isInteger(day)) return false;
2111
+ if (year < 1 || month < 1 || month > 12) return false;
2112
+ return day >= 1 && day <= daysInMonth(year, month);
2113
+ }
2114
+ function daysInMonth(year, month) {
2115
+ switch (month) {
2116
+ case 2:
2117
+ return isLeapYear(year) ? 29 : 28;
2118
+ case 4:
2119
+ case 6:
2120
+ case 9:
2121
+ case 11:
2122
+ return 30;
2123
+ case 1:
2124
+ case 3:
2125
+ case 5:
2126
+ case 7:
2127
+ case 8:
2128
+ case 10:
2129
+ case 12:
2130
+ return 31;
2131
+ default:
2132
+ return 0;
2133
+ }
2134
+ }
2135
+ function isLeapYear(year) {
2136
+ return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
2137
+ }
2034
2138
  function isValidSelectValue(value, values, multiple) {
2035
2139
  if (multiple) {
2036
2140
  return Array.isArray(value) && value.every((item) => typeof item === "string" && values.includes(item));
@@ -2390,6 +2494,47 @@ var eyebrowTreatmentValues = [
2390
2494
  "pill-bounce",
2391
2495
  "accent-pill-bounce"
2392
2496
  ];
2497
+ var visibleHeadingDecorationFamilyValues = [
2498
+ "organic-squiggle",
2499
+ "short-center-rule"
2500
+ ];
2501
+ var visibleHeadingDecorationPlacementValues = [
2502
+ "after-heading",
2503
+ "between-heading-and-body",
2504
+ "under-centered-heading"
2505
+ ];
2506
+ var headingDecorationOverrideValues = [
2507
+ "site-default",
2508
+ "on",
2509
+ "off"
2510
+ ];
2511
+ var headingDecorationColorTokenValues = [
2512
+ "text",
2513
+ "primary",
2514
+ "secondary",
2515
+ "accent",
2516
+ "border",
2517
+ "muted"
2518
+ ];
2519
+ var accordionIconSetValues = [
2520
+ "plus",
2521
+ "chevron",
2522
+ "caret",
2523
+ "minimal-cross"
2524
+ ];
2525
+ var accordionIconColorTokenValues = [
2526
+ "text",
2527
+ "muted",
2528
+ "primary",
2529
+ "secondary",
2530
+ "accent",
2531
+ "current"
2532
+ ];
2533
+ var accordionIconMotionValues = [
2534
+ "none",
2535
+ "rotate",
2536
+ "swap"
2537
+ ];
2393
2538
  function defineBlockDesignCapability(capability) {
2394
2539
  return {
2395
2540
  ...capability,
@@ -2399,7 +2544,9 @@ function defineBlockDesignCapability(capability) {
2399
2544
  imageSurfaceMotions: capability.imageSurfaceMotions ?? ["static"],
2400
2545
  testimonialCardTreatments: capability.testimonialCardTreatments ?? ["default"],
2401
2546
  tileTreatments: capability.tileTreatments ?? ["default"],
2402
- eyebrowTreatments: capability.eyebrowTreatments ?? ["plain"]
2547
+ eyebrowTreatments: capability.eyebrowTreatments ?? ["plain"],
2548
+ ...capability.headingDecorations ? { headingDecorations: capability.headingDecorations } : {},
2549
+ ...capability.accordionIconSets ? { accordionIconSets: capability.accordionIconSets } : {}
2403
2550
  };
2404
2551
  }
2405
2552
 
@@ -2590,6 +2737,25 @@ var blockAppearancePresets = [
2590
2737
  emphasis: "high"
2591
2738
  }
2592
2739
  }),
2740
+ defineBlockAppearancePreset({
2741
+ kind: "block-design",
2742
+ id: "intro-soft-earth-statement",
2743
+ target: "intro",
2744
+ label: "Soft Earth intro statement",
2745
+ blockKinds: ["block.intro"],
2746
+ design: {
2747
+ sectionSurface: "base",
2748
+ contentFrame: plainFrame,
2749
+ itemSurface: "none",
2750
+ transitionAfter: "soft-fade-short",
2751
+ emphasis: "high",
2752
+ headingDecoration: {
2753
+ family: "organic-squiggle",
2754
+ placement: "after-heading",
2755
+ colorToken: "primary"
2756
+ }
2757
+ }
2758
+ }),
2593
2759
  defineBlockAppearancePreset({
2594
2760
  kind: "block-design",
2595
2761
  id: "offerings-calm-list",
@@ -2604,6 +2770,25 @@ var blockAppearancePresets = [
2604
2770
  emphasis: "medium"
2605
2771
  }
2606
2772
  }),
2773
+ defineBlockAppearancePreset({
2774
+ kind: "block-design",
2775
+ id: "feature-cards-soft-earth-offerings",
2776
+ target: "feature-cards",
2777
+ label: "Soft Earth offering cards",
2778
+ blockKinds: ["block.feature-cards"],
2779
+ design: {
2780
+ sectionSurface: "base",
2781
+ contentFrame: plainFrame,
2782
+ itemSurface: "raised",
2783
+ transitionAfter: "none",
2784
+ emphasis: "high",
2785
+ headingDecoration: {
2786
+ family: "short-center-rule",
2787
+ placement: "under-centered-heading",
2788
+ colorToken: "primary"
2789
+ }
2790
+ }
2791
+ }),
2607
2792
  defineBlockAppearancePreset({
2608
2793
  kind: "block-design",
2609
2794
  id: "events-base-calendar",
@@ -2732,6 +2917,26 @@ var blockAppearancePresets = [
2732
2917
  testimonialCardTreatment: "accent-quote"
2733
2918
  }
2734
2919
  }),
2920
+ defineBlockAppearancePreset({
2921
+ kind: "block-design",
2922
+ id: "testimonials-soft-earth-proof-band",
2923
+ target: "testimonials",
2924
+ label: "Soft Earth proof band",
2925
+ blockKinds: ["block.testimonials"],
2926
+ design: {
2927
+ sectionSurface: "brand-depth-band",
2928
+ contentFrame: plainFrame,
2929
+ itemSurface: "none",
2930
+ transitionAfter: "soft-fade-short",
2931
+ emphasis: "high",
2932
+ testimonialCardTreatment: "accent-quote",
2933
+ headingDecoration: {
2934
+ family: "short-center-rule",
2935
+ placement: "under-centered-heading",
2936
+ colorToken: "border"
2937
+ }
2938
+ }
2939
+ }),
2735
2940
  defineBlockAppearancePreset({
2736
2941
  kind: "block-design",
2737
2942
  id: "faq-base-accordion",
@@ -2760,6 +2965,25 @@ var blockAppearancePresets = [
2760
2965
  emphasis: "low"
2761
2966
  }
2762
2967
  }),
2968
+ defineBlockAppearancePreset({
2969
+ kind: "block-design",
2970
+ id: "faq-soft-earth-two-column",
2971
+ target: "faq",
2972
+ label: "Soft Earth two-column FAQ",
2973
+ blockKinds: ["block.faq"],
2974
+ design: {
2975
+ sectionSurface: "base",
2976
+ contentFrame: plainFrame,
2977
+ itemSurface: "flat",
2978
+ transitionAfter: "none",
2979
+ emphasis: "medium",
2980
+ accordionIconTreatment: {
2981
+ iconSet: "plus",
2982
+ colorToken: "primary",
2983
+ motion: "swap"
2984
+ }
2985
+ }
2986
+ }),
2763
2987
  defineBlockAppearancePreset({
2764
2988
  kind: "block-design",
2765
2989
  id: "contact-form-panel",
@@ -3455,6 +3679,97 @@ var confidentChip = defineButtonPersonality({
3455
3679
  }
3456
3680
  });
3457
3681
 
3682
+ // ../theme-core/src/buttons/personalities/earth-pill.ts
3683
+ var earthPill = defineButtonPersonality({
3684
+ id: "earth-pill",
3685
+ name: "Earth Pill",
3686
+ description: "Compact terracotta pills with quiet primary-coloured ghost CTAs.",
3687
+ tags: { tone: "classic", energy: "calm", motion: "subtle", era: "organic" },
3688
+ buttonSystem: {
3689
+ global: {
3690
+ cornerStyle: "pill",
3691
+ shadow: "low",
3692
+ textTransform: "none",
3693
+ fontWeight: 500,
3694
+ borderWidth: 1,
3695
+ hoverTransform: "lift",
3696
+ hoverColor: "none",
3697
+ typography: "body",
3698
+ paddingPreset: "default"
3699
+ },
3700
+ sizes: {
3701
+ sm: { padding: "0.5rem 1rem", fontSize: "text-sm" },
3702
+ md: { padding: "0.625rem 1.35rem" },
3703
+ lg: { padding: "0.75rem 1.65rem", fontSize: "text-lg" },
3704
+ xl: { padding: "0.875rem 2rem", fontSize: "text-xl" }
3705
+ },
3706
+ variants: [
3707
+ {
3708
+ id: "primary",
3709
+ name: "Primary",
3710
+ enabled: true,
3711
+ priority: 1,
3712
+ background: { type: "solid", colorToken: "primary" },
3713
+ textColorToken: "primaryForeground",
3714
+ borderRadius: "rounded-full",
3715
+ shadow: { elevation: "low", softness: "soft", position: "bottom" },
3716
+ effects: {
3717
+ hover: [
3718
+ { effectId: "lift", options: { translateY: "-1px" } },
3719
+ { effectId: "background-on-hover", options: { colorToken: "accent" } }
3720
+ ],
3721
+ active: [{ effectId: "scale-down", options: { scale: "0.98" } }]
3722
+ }
3723
+ },
3724
+ {
3725
+ id: "secondary",
3726
+ name: "Secondary",
3727
+ enabled: true,
3728
+ priority: 2,
3729
+ background: { type: "transparent" },
3730
+ textColorToken: "primary",
3731
+ borderRadius: "rounded-full",
3732
+ border: { widthClass: "border", colorToken: "primary" },
3733
+ effects: {
3734
+ hover: [{ effectId: "background-on-hover", options: { colorToken: "muted" } }]
3735
+ }
3736
+ },
3737
+ {
3738
+ id: "outline",
3739
+ name: "Outline",
3740
+ enabled: true,
3741
+ priority: 3,
3742
+ background: { type: "transparent" },
3743
+ textColorToken: "text",
3744
+ borderRadius: "rounded-full",
3745
+ border: { widthClass: "border", colorToken: "border" },
3746
+ effects: {
3747
+ hover: [{ effectId: "background-on-hover", options: { colorToken: "surfaceAlt" } }]
3748
+ }
3749
+ },
3750
+ {
3751
+ id: "ghost",
3752
+ name: "Ghost",
3753
+ enabled: true,
3754
+ priority: 3,
3755
+ background: { type: "transparent" },
3756
+ textColorToken: "primary",
3757
+ borderRadius: "rounded-full",
3758
+ shadow: { elevation: "none", softness: null, position: "bottom" },
3759
+ sizes: {
3760
+ sm: { padding: "0.25rem 0", fontSize: "text-sm" },
3761
+ md: { padding: "0.375rem 0" },
3762
+ lg: { padding: "0.5rem 0", fontSize: "text-lg" },
3763
+ xl: { padding: "0.625rem 0", fontSize: "text-xl" }
3764
+ },
3765
+ effects: {
3766
+ hover: [{ effectId: "opacity-reduce", options: { reduction: 25 } }]
3767
+ }
3768
+ }
3769
+ ]
3770
+ }
3771
+ });
3772
+
3458
3773
  // ../theme-core/src/buttons/personalities/editorial-link.ts
3459
3774
  var editorialLink = defineButtonPersonality({
3460
3775
  id: "editorial-link",
@@ -3913,6 +4228,7 @@ var softPill = defineButtonPersonality({
3913
4228
  // ../theme-core/src/buttons/personalities/index.ts
3914
4229
  var buttonPersonalities = [
3915
4230
  softPill,
4231
+ earthPill,
3916
4232
  confidentChip,
3917
4233
  editorialLink,
3918
4234
  pebble,
@@ -6670,12 +6986,36 @@ var boxBackgroundSchema = z22.object({
6670
6986
  textColor: tokenOrCssColorValueSchema.nullable().optional(),
6671
6987
  headingColor: tokenOrCssColorValueSchema.nullable().optional()
6672
6988
  });
6989
+ var noHeadingDecorationSchema = z22.object({
6990
+ family: z22.literal("none"),
6991
+ placement: z22.literal("none")
6992
+ });
6993
+ var visibleHeadingDecorationSchema = z22.object({
6994
+ family: z22.enum(visibleHeadingDecorationFamilyValues),
6995
+ placement: z22.enum(visibleHeadingDecorationPlacementValues),
6996
+ colorToken: z22.enum(headingDecorationColorTokenValues).optional()
6997
+ });
6998
+ var headingDecorationSchema = z22.union([
6999
+ noHeadingDecorationSchema,
7000
+ visibleHeadingDecorationSchema
7001
+ ]);
7002
+ var accordionIconTreatmentSchema = z22.object({
7003
+ iconSet: z22.enum(accordionIconSetValues),
7004
+ colorToken: z22.enum(accordionIconColorTokenValues),
7005
+ openColorToken: z22.enum(accordionIconColorTokenValues).optional(),
7006
+ motion: z22.enum(accordionIconMotionValues)
7007
+ });
6673
7008
  var sectionStylesOverrideSchema = z22.object({
6674
7009
  background: boxBackgroundSchema.nullable().optional(),
6675
7010
  spacing: semanticSpacingSchema.nullable().optional(),
6676
7011
  minHeight: z22.enum(["none", "banner", "hero", "immersive"]).nullable().optional(),
6677
7012
  tileTreatment: z22.enum(tileTreatmentValues).nullable().optional(),
6678
- eyebrowTreatment: z22.enum(eyebrowTreatmentValues).nullable().optional()
7013
+ eyebrowTreatment: z22.enum(eyebrowTreatmentValues).nullable().optional(),
7014
+ headingDecoration: headingDecorationSchema.nullable().optional(),
7015
+ // Author-level override consumed by later block/editor rendering phases.
7016
+ // Keeping it in section styles lets existing block save APIs persist it.
7017
+ headingDecorationOverride: z22.enum(headingDecorationOverrideValues).nullable().optional(),
7018
+ accordionIconTreatment: accordionIconTreatmentSchema.nullable().optional()
6679
7019
  });
6680
7020
  var containerStylesOverrideSchema = z22.object({
6681
7021
  background: boxBackgroundSchema.nullable().optional(),
@@ -7383,6 +7723,28 @@ var warmNeutralCream = definePaletteVariant({
7383
7723
  { name: "border", hex: "#e0d2b8" }
7384
7724
  ]
7385
7725
  });
7726
+ var warmNeutralSoftEarth = definePaletteVariant({
7727
+ id: "warm-neutral-soft-earth",
7728
+ name: "Warm Neutral \u2014 Soft Earth",
7729
+ description: "Cream ground with terracotta primary, clay accents, and olive depth.",
7730
+ tags: { tone: "classic", energy: "calm", era: "organic" },
7731
+ mode: "light",
7732
+ colors: [
7733
+ { name: "primary", hex: "#a8573d" },
7734
+ { name: "secondary", hex: "#72765c" },
7735
+ { name: "accent", hex: "#c87557" },
7736
+ { name: "success", hex: "#687854" },
7737
+ { name: "warning", hex: "#b7863e" },
7738
+ { name: "destructive", hex: "#a54b3c" },
7739
+ { name: "background", hex: "#fbf6eb" },
7740
+ { name: "surface", hex: "#fffdf7" },
7741
+ { name: "surfaceAlt", hex: "#f0e4d3" },
7742
+ { name: "muted", hex: "#eadbc6" },
7743
+ { name: "text", hex: "#30281f" },
7744
+ { name: "primaryForeground", hex: "#fffaf3" },
7745
+ { name: "border", hex: "#d9c8b2" }
7746
+ ]
7747
+ });
7386
7748
  var warmNeutralForest = definePaletteVariant({
7387
7749
  id: "warm-neutral-forest",
7388
7750
  name: "Warm Neutral \u2014 Forest",
@@ -7416,6 +7778,7 @@ var paletteVariants = [
7416
7778
  // Warm-neutral family
7417
7779
  warmNeutralClay,
7418
7780
  warmNeutralCream,
7781
+ warmNeutralSoftEarth,
7419
7782
  warmNeutralForest,
7420
7783
  // High-contrast family
7421
7784
  highContrastInk,
@@ -7434,6 +7797,12 @@ var paletteVariantsById = new Map(
7434
7797
  function asHeaderLookId(value) {
7435
7798
  return value;
7436
7799
  }
7800
+ function asHeaderLayoutId(value) {
7801
+ return value;
7802
+ }
7803
+ function asHeaderStyleId(value) {
7804
+ return value;
7805
+ }
7437
7806
  function baseHeader(theme) {
7438
7807
  const {
7439
7808
  navLinkStyle: _navLinkStyle,
@@ -7452,6 +7821,309 @@ function baseHeader(theme) {
7452
7821
  navContainer: { type: "none", tint: null, opacity: 0.15 }
7453
7822
  };
7454
7823
  }
7824
+ var headerLayoutCatalog = [
7825
+ {
7826
+ id: asHeaderLayoutId("classic"),
7827
+ label: "Classic",
7828
+ description: "Logo and navigation in one practical horizontal row.",
7829
+ structure: "inline-classic",
7830
+ variant: "classic",
7831
+ defaultPositioning: "sticky",
7832
+ shrinkOnScroll: false
7833
+ },
7834
+ {
7835
+ id: asHeaderLayoutId("centered"),
7836
+ label: "Centered",
7837
+ description: "Logo centered above a balanced navigation row.",
7838
+ structure: "centered-stack",
7839
+ variant: "centered",
7840
+ defaultPositioning: "static",
7841
+ shrinkOnScroll: false,
7842
+ maxRecommendedNavItems: 5,
7843
+ allowedLogoShapes: ["none", "text-only", "horizontal", "square"]
7844
+ },
7845
+ {
7846
+ id: asHeaderLayoutId("editorial"),
7847
+ label: "Editorial",
7848
+ description: "A composed, magazine-like stacked header treatment.",
7849
+ structure: "editorial-stack",
7850
+ variant: "editorial",
7851
+ defaultPositioning: "static",
7852
+ shrinkOnScroll: false,
7853
+ maxRecommendedNavItems: 6
7854
+ },
7855
+ {
7856
+ id: asHeaderLayoutId("floating"),
7857
+ label: "Floating",
7858
+ description: "Detached header chrome that sits over the opening section.",
7859
+ structure: "floating-shell",
7860
+ variant: "floating",
7861
+ defaultPositioning: "fixed",
7862
+ shrinkOnScroll: true,
7863
+ maxRecommendedNavItems: 5,
7864
+ allowedLogoShapes: ["none", "text-only", "horizontal"]
7865
+ }
7866
+ ];
7867
+ function supportedLayouts(ids) {
7868
+ return ids.map(asHeaderLayoutId);
7869
+ }
7870
+ var headerStyleCatalog = [
7871
+ {
7872
+ id: asHeaderStyleId("minimal"),
7873
+ label: "Minimal",
7874
+ description: "Quiet surface with simple color-change navigation.",
7875
+ supportedLayoutIds: supportedLayouts(["classic", "centered", "editorial"]),
7876
+ navInteraction: "color-change",
7877
+ surface: "neutral"
7878
+ },
7879
+ {
7880
+ id: asHeaderStyleId("fine-line"),
7881
+ label: "Fine Line",
7882
+ description: "Light surface with a crisp lower rule and underline hover.",
7883
+ supportedLayoutIds: supportedLayouts(["classic", "centered", "editorial"]),
7884
+ navInteraction: "underline-grow",
7885
+ surface: "bordered"
7886
+ },
7887
+ {
7888
+ id: asHeaderStyleId("soft-bar"),
7889
+ label: "Soft Bar",
7890
+ description: "Soft tinted surface with gentle pill hover states.",
7891
+ supportedLayoutIds: supportedLayouts(["classic", "centered"]),
7892
+ navInteraction: "pill-background",
7893
+ surface: "soft"
7894
+ },
7895
+ {
7896
+ id: asHeaderStyleId("pill-nav"),
7897
+ label: "Pill Nav",
7898
+ description: "A calm pill navigation rail over a neutral header.",
7899
+ supportedLayoutIds: supportedLayouts(["classic", "centered"]),
7900
+ navInteraction: "pill-background",
7901
+ surface: "soft"
7902
+ },
7903
+ {
7904
+ id: asHeaderStyleId("brand-bar"),
7905
+ label: "Brand Bar",
7906
+ description: "Solid brand surface with high-contrast navigation.",
7907
+ supportedLayoutIds: supportedLayouts(["classic", "centered", "editorial"]),
7908
+ navInteraction: "color-change",
7909
+ surface: "brand-solid"
7910
+ },
7911
+ {
7912
+ id: asHeaderStyleId("brand-underline"),
7913
+ label: "Brand Underline",
7914
+ description: "Brand surface with underline-grow navigation.",
7915
+ supportedLayoutIds: supportedLayouts(["classic", "editorial"]),
7916
+ navInteraction: "underline-grow",
7917
+ surface: "brand-solid"
7918
+ },
7919
+ {
7920
+ id: asHeaderStyleId("brand-pill"),
7921
+ label: "Brand Pill",
7922
+ description: "Solid brand surface with rounded active and hover states.",
7923
+ supportedLayoutIds: supportedLayouts(["classic", "centered", "floating"]),
7924
+ navInteraction: "pill-background",
7925
+ surface: "brand-solid"
7926
+ },
7927
+ {
7928
+ id: asHeaderStyleId("editorial-line"),
7929
+ label: "Editorial Line",
7930
+ description: "Typographic logo treatment with understated underline navigation.",
7931
+ supportedLayoutIds: supportedLayouts(["classic", "centered", "editorial"]),
7932
+ navInteraction: "underline-grow",
7933
+ surface: "bordered"
7934
+ },
7935
+ {
7936
+ id: asHeaderStyleId("flat-tabs"),
7937
+ label: "Flat Tabs",
7938
+ description: "Flat block hover and active states with a Swiss utility feel.",
7939
+ supportedLayoutIds: supportedLayouts(["classic", "centered", "editorial"]),
7940
+ navInteraction: "flat-block",
7941
+ surface: "bordered"
7942
+ },
7943
+ {
7944
+ id: asHeaderStyleId("glass"),
7945
+ label: "Glass",
7946
+ description: "Floating translucent chrome with frosted navigation backing.",
7947
+ supportedLayoutIds: supportedLayouts(["floating"]),
7948
+ navInteraction: "glass-backed",
7949
+ surface: "floating",
7950
+ requiresFloatingLayout: true
7951
+ },
7952
+ {
7953
+ id: asHeaderStyleId("minimal-surface"),
7954
+ label: "Minimal Surface",
7955
+ description: "Floating chrome with a restrained translucent surface.",
7956
+ supportedLayoutIds: supportedLayouts(["floating"]),
7957
+ navInteraction: "color-change",
7958
+ surface: "floating",
7959
+ requiresFloatingLayout: true
7960
+ },
7961
+ {
7962
+ id: asHeaderStyleId("soft-shell"),
7963
+ label: "Soft Shell",
7964
+ description: "Floating rounded shell with soft pill navigation states.",
7965
+ supportedLayoutIds: supportedLayouts(["floating"]),
7966
+ navInteraction: "pill-background",
7967
+ surface: "floating",
7968
+ requiresFloatingLayout: true
7969
+ }
7970
+ ];
7971
+ var headerLayoutsById = new Map(
7972
+ headerLayoutCatalog.map((layout) => [layout.id, layout])
7973
+ );
7974
+ var headerStylesById = new Map(
7975
+ headerStyleCatalog.map((style) => [style.id, style])
7976
+ );
7977
+ var headerStyleCompatibilityOrder = /* @__PURE__ */ new Map([
7978
+ [
7979
+ asHeaderLayoutId("classic"),
7980
+ headerStyleRepairChain([
7981
+ "minimal",
7982
+ "fine-line",
7983
+ "soft-bar",
7984
+ "pill-nav",
7985
+ "brand-bar",
7986
+ "brand-underline",
7987
+ "brand-pill",
7988
+ "editorial-line",
7989
+ "flat-tabs"
7990
+ ])
7991
+ ],
7992
+ [
7993
+ asHeaderLayoutId("centered"),
7994
+ headerStyleRepairChain([
7995
+ "minimal",
7996
+ "fine-line",
7997
+ "soft-bar",
7998
+ "pill-nav",
7999
+ "brand-bar",
8000
+ "brand-pill",
8001
+ "editorial-line",
8002
+ "flat-tabs"
8003
+ ])
8004
+ ],
8005
+ [
8006
+ asHeaderLayoutId("editorial"),
8007
+ headerStyleRepairChain([
8008
+ "minimal",
8009
+ "fine-line",
8010
+ "soft-bar",
8011
+ "brand-bar",
8012
+ "brand-underline",
8013
+ "editorial-line",
8014
+ "flat-tabs"
8015
+ ])
8016
+ ],
8017
+ [
8018
+ asHeaderLayoutId("floating"),
8019
+ headerStyleRepairChain([
8020
+ "glass",
8021
+ "minimal-surface",
8022
+ "soft-shell",
8023
+ "brand-pill"
8024
+ ])
8025
+ ]
8026
+ ]);
8027
+ function headerStyleRepairChain(values) {
8028
+ return values.map(asHeaderStyleId);
8029
+ }
8030
+ var headerStyleRepairOrder = /* @__PURE__ */ new Map([
8031
+ [asHeaderStyleId("brand-bar"), headerStyleRepairChain(["brand-bar", "brand-pill", "minimal"])],
8032
+ [asHeaderStyleId("brand-underline"), headerStyleRepairChain(["editorial-line", "fine-line", "minimal"])],
8033
+ [asHeaderStyleId("brand-pill"), headerStyleRepairChain(["brand-pill", "brand-bar", "minimal"])],
8034
+ [asHeaderStyleId("pill-nav"), headerStyleRepairChain(["pill-nav", "soft-bar", "minimal"])],
8035
+ [asHeaderStyleId("flat-tabs"), headerStyleRepairChain(["flat-tabs", "pill-nav", "minimal"])],
8036
+ [asHeaderStyleId("editorial-line"), headerStyleRepairChain(["editorial-line", "fine-line", "minimal"])],
8037
+ [asHeaderStyleId("glass"), headerStyleRepairChain(["glass", "minimal-surface", "minimal"])],
8038
+ [asHeaderStyleId("soft-shell"), headerStyleRepairChain(["soft-shell", "soft-bar", "minimal"])],
8039
+ [asHeaderStyleId("minimal-surface"), headerStyleRepairChain(["minimal-surface", "minimal"])],
8040
+ [asHeaderStyleId("fine-line"), headerStyleRepairChain(["fine-line", "minimal"])],
8041
+ [asHeaderStyleId("soft-bar"), headerStyleRepairChain(["soft-bar", "minimal"])],
8042
+ [asHeaderStyleId("minimal"), headerStyleRepairChain(["minimal"])]
8043
+ ]);
8044
+ var legacyHeaderLookAliases = [
8045
+ {
8046
+ lookId: asHeaderLookId("clean-base"),
8047
+ selection: {
8048
+ layoutId: asHeaderLayoutId("classic"),
8049
+ styleId: asHeaderStyleId("minimal")
8050
+ }
8051
+ },
8052
+ {
8053
+ lookId: asHeaderLookId("brand-solid"),
8054
+ selection: {
8055
+ layoutId: asHeaderLayoutId("classic"),
8056
+ styleId: asHeaderStyleId("brand-bar")
8057
+ }
8058
+ },
8059
+ {
8060
+ lookId: asHeaderLookId("editorial-line"),
8061
+ selection: {
8062
+ layoutId: asHeaderLayoutId("editorial"),
8063
+ styleId: asHeaderStyleId("editorial-line")
8064
+ }
8065
+ },
8066
+ {
8067
+ lookId: asHeaderLookId("centered-calm"),
8068
+ selection: {
8069
+ layoutId: asHeaderLayoutId("centered"),
8070
+ styleId: asHeaderStyleId("minimal")
8071
+ }
8072
+ },
8073
+ {
8074
+ lookId: asHeaderLookId("practical-utility"),
8075
+ selection: {
8076
+ layoutId: asHeaderLayoutId("classic"),
8077
+ styleId: asHeaderStyleId("flat-tabs")
8078
+ }
8079
+ },
8080
+ {
8081
+ lookId: asHeaderLookId("minimal-transparent"),
8082
+ selection: {
8083
+ layoutId: asHeaderLayoutId("classic"),
8084
+ styleId: asHeaderStyleId("minimal")
8085
+ }
8086
+ },
8087
+ {
8088
+ lookId: asHeaderLookId("transparent-overlay"),
8089
+ selection: {
8090
+ layoutId: asHeaderLayoutId("floating"),
8091
+ styleId: asHeaderStyleId("glass")
8092
+ }
8093
+ },
8094
+ {
8095
+ lookId: asHeaderLookId("floating-glass"),
8096
+ selection: {
8097
+ layoutId: asHeaderLayoutId("floating"),
8098
+ styleId: asHeaderStyleId("glass")
8099
+ }
8100
+ }
8101
+ ];
8102
+ var legacyHeaderLookAliasesById = new Map(
8103
+ legacyHeaderLookAliases.map((alias) => [alias.lookId, alias])
8104
+ );
8105
+ function getHeaderStyle(id) {
8106
+ return headerStylesById.get(id) ?? null;
8107
+ }
8108
+ function isHeaderStyleCompatibleWithLayout(style, layoutId) {
8109
+ return style.supportedLayoutIds.includes(layoutId);
8110
+ }
8111
+ function getHeaderStyleOrThrow(id) {
8112
+ const style = getHeaderStyle(id);
8113
+ if (!style) {
8114
+ throw new Error(`Unknown Theme V2 header style: ${id}`);
8115
+ }
8116
+ return style;
8117
+ }
8118
+ function resolveLegacyHeaderLookAlias(lookId) {
8119
+ return legacyHeaderLookAliasesById.get(lookId)?.selection ?? null;
8120
+ }
8121
+ function getCompatibleHeaderStyleIds(layoutId) {
8122
+ return (headerStyleCompatibilityOrder.get(layoutId) ?? []).filter((styleId) => {
8123
+ const style = getHeaderStyleOrThrow(styleId);
8124
+ return isHeaderStyleCompatibleWithLayout(style, layoutId);
8125
+ });
8126
+ }
7455
8127
  function solidBrandHeader(theme) {
7456
8128
  const ctaVariant = resolveHeaderCtaVariant(theme, "inverted");
7457
8129
  return {
@@ -7688,6 +8360,11 @@ var headerLookCatalog = [
7688
8360
  label: "Clean base",
7689
8361
  visualTreatment: "solid-neutral",
7690
8362
  layoutBehavior: "sticky",
8363
+ configuration: {
8364
+ structure: "inline-classic",
8365
+ treatment: "solid-neutral",
8366
+ behavior: "sticky"
8367
+ },
7691
8368
  openingRequirement: "none",
7692
8369
  compile: cleanBaseHeader
7693
8370
  },
@@ -7696,6 +8373,11 @@ var headerLookCatalog = [
7696
8373
  label: "Brand solid",
7697
8374
  visualTreatment: "solid-brand",
7698
8375
  layoutBehavior: "sticky-shrink",
8376
+ configuration: {
8377
+ structure: "inline-classic",
8378
+ treatment: "solid-brand",
8379
+ behavior: "sticky-shrink"
8380
+ },
7699
8381
  openingRequirement: "none",
7700
8382
  compile: solidBrandHeader
7701
8383
  },
@@ -7704,6 +8386,11 @@ var headerLookCatalog = [
7704
8386
  label: "Editorial line",
7705
8387
  visualTreatment: "light-editorial",
7706
8388
  layoutBehavior: "sticky",
8389
+ configuration: {
8390
+ structure: "editorial-stack",
8391
+ treatment: "light-editorial",
8392
+ behavior: "sticky"
8393
+ },
7707
8394
  openingRequirement: "none",
7708
8395
  maxRecommendedNavItems: 6,
7709
8396
  compile: editorialLineHeader
@@ -7713,6 +8400,11 @@ var headerLookCatalog = [
7713
8400
  label: "Centered calm",
7714
8401
  visualTreatment: "light-editorial",
7715
8402
  layoutBehavior: "normal-flow",
8403
+ configuration: {
8404
+ structure: "centered-stack",
8405
+ treatment: "light-editorial",
8406
+ behavior: "normal-flow"
8407
+ },
7716
8408
  openingRequirement: "none",
7717
8409
  maxRecommendedNavItems: 5,
7718
8410
  allowedLogoShapes: ["none", "text-only", "horizontal", "square"],
@@ -7723,6 +8415,11 @@ var headerLookCatalog = [
7723
8415
  label: "Practical utility",
7724
8416
  visualTreatment: "solid-neutral",
7725
8417
  layoutBehavior: "sticky-shrink",
8418
+ configuration: {
8419
+ structure: "inline-classic",
8420
+ treatment: "solid-neutral",
8421
+ behavior: "sticky-shrink"
8422
+ },
7726
8423
  openingRequirement: "none",
7727
8424
  requiresProminentCta: true,
7728
8425
  compile: practicalUtilityHeader
@@ -7732,6 +8429,11 @@ var headerLookCatalog = [
7732
8429
  label: "Minimal transparent",
7733
8430
  visualTreatment: "minimal-transparent",
7734
8431
  layoutBehavior: "normal-flow",
8432
+ configuration: {
8433
+ structure: "inline-classic",
8434
+ treatment: "minimal-transparent",
8435
+ behavior: "normal-flow"
8436
+ },
7735
8437
  openingRequirement: "reserved-space-ok",
7736
8438
  compile: minimalTransparentHeader
7737
8439
  },
@@ -7740,6 +8442,11 @@ var headerLookCatalog = [
7740
8442
  label: "Transparent overlay",
7741
8443
  visualTreatment: "transparent-overlay",
7742
8444
  layoutBehavior: "fixed-overlay",
8445
+ configuration: {
8446
+ structure: "inline-classic",
8447
+ treatment: "transparent-overlay",
8448
+ behavior: "fixed-overlay"
8449
+ },
7743
8450
  openingRequirement: "requires-image-hero-with-contrast-overlay",
7744
8451
  maxRecommendedNavItems: 5,
7745
8452
  allowedLogoShapes: ["none", "text-only", "horizontal"],
@@ -7750,6 +8457,11 @@ var headerLookCatalog = [
7750
8457
  label: "Floating glass",
7751
8458
  visualTreatment: "floating-glass",
7752
8459
  layoutBehavior: "fixed-floating",
8460
+ configuration: {
8461
+ structure: "floating-shell",
8462
+ treatment: "floating-glass",
8463
+ behavior: "fixed-floating"
8464
+ },
7753
8465
  openingRequirement: "requires-image-hero-with-contrast-overlay",
7754
8466
  maxRecommendedNavItems: 5,
7755
8467
  allowedLogoShapes: ["none", "text-only", "horizontal"],
@@ -7757,9 +8469,17 @@ var headerLookCatalog = [
7757
8469
  }
7758
8470
  ];
7759
8471
  var guaranteedFallbackHeaderLookId = asHeaderLookId("clean-base");
8472
+ var guaranteedFallbackHeaderLayoutId = asHeaderLayoutId("classic");
8473
+ var guaranteedFallbackHeaderStyleId = asHeaderStyleId("minimal");
8474
+ var allowedHeaderConfigurationKeys = new Set(
8475
+ headerLookCatalog.map((look) => headerConfigurationKey(look.configuration))
8476
+ );
7760
8477
  var headerLooksById = new Map(
7761
8478
  headerLookCatalog.map((look) => [look.id, look])
7762
8479
  );
8480
+ function headerConfigurationKey(configuration) {
8481
+ return `${configuration.structure}:${configuration.treatment}:${configuration.behavior}`;
8482
+ }
7763
8483
 
7764
8484
  // ../theme-core/src/site-styles/footerLooks.ts
7765
8485
  function asFooterLookId(value) {
@@ -7892,6 +8612,264 @@ var advancedDesignOptionCatalog = {
7892
8612
  detachedCustom: true
7893
8613
  };
7894
8614
 
8615
+ // ../theme-core/src/site-styles/typographyPresets.ts
8616
+ var bodyReadablePolicy = {
8617
+ recommendedCategories: ["sans-serif", "serif"],
8618
+ allowedCategories: ["sans-serif", "serif"],
8619
+ requiresItalicForBody: true,
8620
+ requiresBoldForBody: true
8621
+ };
8622
+ var headingFlexiblePolicy = {
8623
+ recommendedCategories: ["sans-serif", "serif", "display"],
8624
+ allowedCategories: ["sans-serif", "serif", "display"]
8625
+ };
8626
+ var displayHeadingPolicy = {
8627
+ recommendedCategories: ["display", "sans-serif", "serif"],
8628
+ allowedCategories: ["display", "sans-serif", "serif"]
8629
+ };
8630
+ function asTypographyPresetId(value) {
8631
+ if (!value.startsWith("typography-preset:")) {
8632
+ throw new Error(`TypographyPresetId must start with "typography-preset:". Received: ${value}`);
8633
+ }
8634
+ return value;
8635
+ }
8636
+ function defineTypographyPreset(preset2) {
8637
+ return {
8638
+ ...preset2,
8639
+ id: asTypographyPresetId(preset2.id)
8640
+ };
8641
+ }
8642
+ var modernSansTypography = {
8643
+ body: {
8644
+ family: "Inter, system-ui, sans-serif",
8645
+ size: "md",
8646
+ weight: "regular",
8647
+ lineHeight: "relaxed",
8648
+ letterSpacing: "normal"
8649
+ },
8650
+ headings: {
8651
+ default: {
8652
+ family: "Inter, system-ui, sans-serif",
8653
+ weight: "semibold",
8654
+ lineHeight: "normal",
8655
+ letterSpacing: "tight",
8656
+ italic: null,
8657
+ case: null
8658
+ },
8659
+ h1: { size: "xl", weight: "bold", lineHeight: "normal", letterSpacing: "tight", italic: null },
8660
+ h2: { size: "lg", weight: "semibold", lineHeight: "normal", letterSpacing: "tight", italic: null },
8661
+ h3: { size: "md", weight: "semibold", lineHeight: "normal", letterSpacing: "normal", italic: null }
8662
+ },
8663
+ scale: "balanced"
8664
+ };
8665
+ var warmRoundedTypography = {
8666
+ body: {
8667
+ family: "Nunito Sans, system-ui, sans-serif",
8668
+ size: "lg",
8669
+ weight: "regular",
8670
+ lineHeight: "relaxed",
8671
+ letterSpacing: "normal"
8672
+ },
8673
+ headings: {
8674
+ default: {
8675
+ family: "Nunito Sans, system-ui, sans-serif",
8676
+ weight: "bold",
8677
+ lineHeight: "normal",
8678
+ letterSpacing: "normal",
8679
+ italic: null,
8680
+ case: null
8681
+ },
8682
+ h1: { size: "xl", weight: "bold", lineHeight: "normal", letterSpacing: "normal", italic: null },
8683
+ h2: { size: "lg", weight: "bold", lineHeight: "normal", letterSpacing: "normal", italic: null },
8684
+ h3: { size: "md", weight: "semibold", lineHeight: "relaxed", letterSpacing: "normal", italic: null }
8685
+ },
8686
+ scale: "balanced"
8687
+ };
8688
+ var editorialSerifTypography = {
8689
+ body: {
8690
+ family: "Lora, Georgia, serif",
8691
+ size: "lg",
8692
+ weight: "regular",
8693
+ lineHeight: "loose",
8694
+ letterSpacing: "normal"
8695
+ },
8696
+ headings: {
8697
+ default: {
8698
+ family: "Playfair Display, Georgia, serif",
8699
+ weight: "semibold",
8700
+ lineHeight: "normal",
8701
+ letterSpacing: "tight",
8702
+ italic: null,
8703
+ case: null
8704
+ },
8705
+ h1: { size: "2xl", weight: "semibold", lineHeight: "normal", letterSpacing: "tight", italic: null },
8706
+ h2: { size: "xl", weight: "semibold", lineHeight: "normal", letterSpacing: "normal", italic: null },
8707
+ h3: { size: "md", weight: "semibold", lineHeight: "relaxed", letterSpacing: "normal", italic: true }
8708
+ },
8709
+ scale: "spacious"
8710
+ };
8711
+ var classicSerifTypography = {
8712
+ body: {
8713
+ family: "Libre Baskerville, Georgia, serif",
8714
+ size: "md",
8715
+ weight: "regular",
8716
+ lineHeight: "relaxed",
8717
+ letterSpacing: "normal"
8718
+ },
8719
+ headings: {
8720
+ default: {
8721
+ family: "Cormorant Garamond, Georgia, serif",
8722
+ weight: "semibold",
8723
+ lineHeight: "normal",
8724
+ letterSpacing: "normal",
8725
+ italic: null,
8726
+ case: null
8727
+ },
8728
+ h1: { size: "2xl", weight: "semibold", lineHeight: "normal", letterSpacing: "normal", italic: null },
8729
+ h2: { size: "xl", weight: "semibold", lineHeight: "normal", letterSpacing: "normal", italic: null },
8730
+ h3: { size: "md", weight: "medium", lineHeight: "relaxed", letterSpacing: "normal", italic: null }
8731
+ },
8732
+ scale: "balanced"
8733
+ };
8734
+ var luxeContrastTypography = {
8735
+ body: {
8736
+ family: "Manrope, system-ui, sans-serif",
8737
+ size: "md",
8738
+ weight: "regular",
8739
+ lineHeight: "relaxed",
8740
+ letterSpacing: "normal"
8741
+ },
8742
+ headings: {
8743
+ default: {
8744
+ family: "Cormorant Garamond, Georgia, serif",
8745
+ weight: "semibold",
8746
+ lineHeight: "normal",
8747
+ letterSpacing: "tight",
8748
+ italic: null,
8749
+ case: null
8750
+ },
8751
+ h1: { size: "2xl", weight: "semibold", lineHeight: "normal", letterSpacing: "tight", italic: null },
8752
+ h2: { size: "xl", weight: "semibold", lineHeight: "normal", letterSpacing: "tight", italic: null },
8753
+ h3: { size: "md", weight: "medium", lineHeight: "relaxed", letterSpacing: "normal", italic: null }
8754
+ },
8755
+ scale: "spacious"
8756
+ };
8757
+ var boldDisplayTypography = {
8758
+ body: {
8759
+ family: "Manrope, system-ui, sans-serif",
8760
+ size: "lg",
8761
+ weight: "regular",
8762
+ lineHeight: "relaxed",
8763
+ letterSpacing: "normal"
8764
+ },
8765
+ headings: {
8766
+ default: {
8767
+ family: '"TAN - PEARL", sans-serif',
8768
+ weight: "bold",
8769
+ lineHeight: "normal",
8770
+ letterSpacing: "tight",
8771
+ colorToken: "primary",
8772
+ italic: null,
8773
+ case: null
8774
+ },
8775
+ h1: { size: "xl", weight: "bold", lineHeight: "normal", letterSpacing: "tight", italic: null },
8776
+ h2: { size: "lg", weight: "bold", lineHeight: "normal", letterSpacing: "normal", italic: null },
8777
+ h3: { size: "md", weight: "bold", lineHeight: "normal", letterSpacing: "normal", italic: null }
8778
+ },
8779
+ scale: "balanced"
8780
+ };
8781
+ var typographyPresets = [
8782
+ defineTypographyPreset({
8783
+ id: "typography-preset:modern-sans",
8784
+ name: "Modern Sans",
8785
+ description: "Crisp, neutral type for clear service pages and practical editorial structure.",
8786
+ defaultFonts: { body: "Inter, system-ui, sans-serif", heading: "Inter, system-ui, sans-serif" },
8787
+ recommendedFonts: {
8788
+ body: ["Inter", "Source Sans 3", "IBM Plex Sans"],
8789
+ heading: ["Inter", "Manrope", "Source Sans 3"]
8790
+ },
8791
+ slotPolicies: { body: bodyReadablePolicy, heading: headingFlexiblePolicy },
8792
+ typography: modernSansTypography
8793
+ }),
8794
+ defineTypographyPreset({
8795
+ id: "typography-preset:warm-rounded",
8796
+ name: "Warm Rounded",
8797
+ description: "Soft, friendly type for welcoming studios, classes, and community businesses.",
8798
+ defaultFonts: { body: "Nunito Sans, system-ui, sans-serif", heading: "Nunito Sans, system-ui, sans-serif" },
8799
+ recommendedFonts: {
8800
+ body: ["Nunito Sans", "Atkinson Hyperlegible", "Lato"],
8801
+ heading: ["Nunito Sans", "Quicksand", "Manrope"]
8802
+ },
8803
+ slotPolicies: { body: bodyReadablePolicy, heading: headingFlexiblePolicy },
8804
+ typography: warmRoundedTypography
8805
+ }),
8806
+ defineTypographyPreset({
8807
+ id: "typography-preset:editorial-serif",
8808
+ name: "Editorial Serif",
8809
+ description: "Story-led type with warm reading rhythm and expressive headings.",
8810
+ defaultFonts: { body: "Lora, Georgia, serif", heading: "Playfair Display, Georgia, serif" },
8811
+ recommendedFonts: {
8812
+ body: ["Lora", "Source Serif 4", "Libre Baskerville"],
8813
+ heading: ["Playfair Display", "Cormorant Garamond", "Fraunces"]
8814
+ },
8815
+ slotPolicies: { body: bodyReadablePolicy, heading: displayHeadingPolicy },
8816
+ typography: editorialSerifTypography
8817
+ }),
8818
+ defineTypographyPreset({
8819
+ id: "typography-preset:classic-serif",
8820
+ name: "Classic Serif",
8821
+ description: "Measured, polished type for premium and established offers.",
8822
+ defaultFonts: { body: "Libre Baskerville, Georgia, serif", heading: "Cormorant Garamond, Georgia, serif" },
8823
+ recommendedFonts: {
8824
+ body: ["Libre Baskerville", "Source Serif 4", "Lora"],
8825
+ heading: ["Cormorant Garamond", "Playfair Display", "Libre Baskerville"]
8826
+ },
8827
+ slotPolicies: { body: bodyReadablePolicy, heading: displayHeadingPolicy },
8828
+ typography: classicSerifTypography
8829
+ }),
8830
+ defineTypographyPreset({
8831
+ id: "typography-preset:luxe-contrast",
8832
+ name: "Luxe Contrast",
8833
+ description: "A restrained sans body paired with elegant high-contrast headings.",
8834
+ defaultFonts: { body: "Manrope, system-ui, sans-serif", heading: "Cormorant Garamond, Georgia, serif" },
8835
+ recommendedFonts: {
8836
+ body: ["Manrope", "Inter", "Source Sans 3"],
8837
+ heading: ["Cormorant Garamond", "Playfair Display", "Bodoni Moda"]
8838
+ },
8839
+ slotPolicies: { body: bodyReadablePolicy, heading: displayHeadingPolicy },
8840
+ typography: luxeContrastTypography
8841
+ }),
8842
+ defineTypographyPreset({
8843
+ id: "typography-preset:bold-display",
8844
+ name: "Bold Display",
8845
+ description: "Punchy display headings with readable sans body copy for branded launches.",
8846
+ defaultFonts: { body: "Manrope, system-ui, sans-serif", heading: '"TAN - PEARL", sans-serif' },
8847
+ recommendedFonts: {
8848
+ body: ["Manrope", "Inter", "Space Grotesk"],
8849
+ heading: ["Anton", "Bebas Neue", "Archivo Black"]
8850
+ },
8851
+ slotPolicies: { body: bodyReadablePolicy, heading: displayHeadingPolicy },
8852
+ typography: boldDisplayTypography,
8853
+ heroTypography: {
8854
+ headlineSize: "6xl",
8855
+ headlineLineHeight: "tight",
8856
+ subheadlineSize: "editorial",
8857
+ subheadlineLineHeight: "normal",
8858
+ microHeadlineSize: "6xl",
8859
+ microHeadlineLineHeight: "tight",
8860
+ microSubheadlineSize: "xl",
8861
+ microSubheadlineLineHeight: "normal",
8862
+ responsive: {
8863
+ tablet: { headlineSize: "5xl" },
8864
+ mobile: { headlineSize: "4xl", subheadlineSize: "xl" }
8865
+ }
8866
+ }
8867
+ })
8868
+ ];
8869
+ var typographyPresetsById = new Map(
8870
+ typographyPresets.map((preset2) => [preset2.id, preset2])
8871
+ );
8872
+
7895
8873
  // ../theme-core/src/site-styles/curatedSiteStyles.ts
7896
8874
  var curatedSiteStyleIdValues = [
7897
8875
  "site-style:calm-studio",
@@ -7904,6 +8882,7 @@ var curatedSiteStyleIdValues = [
7904
8882
  "site-style:personal-retreat-journal",
7905
8883
  "site-style:tactile-workshop",
7906
8884
  "site-style:modern-wellness",
8885
+ "site-style:soft-earth",
7907
8886
  "site-style:bold-launch",
7908
8887
  "site-style:south-west-twerk-school"
7909
8888
  ];
@@ -7980,6 +8959,15 @@ function uniqueContentFrameKinds() {
7980
8959
  }
7981
8960
  var generatedContentFrameKinds = uniqueContentFrameKinds();
7982
8961
  function defineCuratedSiteStyle(input) {
8962
+ const legacyHeaderLookIds = input.recommendedHeaderLookIds ?? ["clean-base"];
8963
+ const inferredHeaderCuration = inferHeaderCurationFromLegacyLooks(legacyHeaderLookIds);
8964
+ const typographyPresetChoices = input.typographyPresetChoices ?? defaultTypographyPresetChoicesForRecipe(input.tokenRecipes.typography);
8965
+ const defaultTypographyPresetId = input.defaultTypographyPresetId ? asTypographyPresetId(input.defaultTypographyPresetId) : typographyPresetChoices[0].id;
8966
+ if (!typographyPresetChoices.some((choice) => choice.id === defaultTypographyPresetId)) {
8967
+ throw new Error(
8968
+ `Default typography preset ${defaultTypographyPresetId} is not curated for site style ${input.id}.`
8969
+ );
8970
+ }
7983
8971
  return {
7984
8972
  id: asSiteStyleId(input.id),
7985
8973
  name: input.name,
@@ -8000,11 +8988,23 @@ function defineCuratedSiteStyle(input) {
8000
8988
  },
8001
8989
  ...input.themeOverrides ? { themeOverrides: input.themeOverrides } : {},
8002
8990
  recommendedAppearancePresetIds: (input.recommendedAppearancePresetIds ?? []).map(asAppearancePresetId),
8003
- recommendedHeaderLookIds: (input.recommendedHeaderLookIds ?? ["clean-base"]).map(asHeaderLookId),
8991
+ defaultHeaderSelection: input.defaultHeaderSelection ? {
8992
+ layoutId: asHeaderLayoutId(input.defaultHeaderSelection.layoutId),
8993
+ styleId: asHeaderStyleId(input.defaultHeaderSelection.styleId)
8994
+ } : inferredHeaderCuration.defaultHeaderSelection,
8995
+ recommendedHeaderLayoutChoices: input.recommendedHeaderLayoutChoices ?? inferredHeaderCuration.recommendedHeaderLayoutChoices,
8996
+ recommendedHeaderStyleChoicesByLayout: input.recommendedHeaderStyleChoicesByLayout ?? inferredHeaderCuration.recommendedHeaderStyleChoicesByLayout,
8997
+ discouragedHeaderSelections: input.discouragedHeaderSelections?.map((selection) => ({
8998
+ layoutId: asHeaderLayoutId(selection.layoutId),
8999
+ styleId: asHeaderStyleId(selection.styleId)
9000
+ })),
9001
+ recommendedHeaderLookIds: legacyHeaderLookIds.map(asHeaderLookId),
8004
9002
  // Empty is intentional: resolveFooterLook always appends its guaranteed fallback.
8005
9003
  recommendedFooterLookIds: (input.recommendedFooterLookIds ?? []).map(asFooterLookId),
8006
9004
  buttonPersonalityChoices: input.buttonPersonalityChoices,
8007
- paletteVariantChoices: input.paletteVariantChoices
9005
+ paletteVariantChoices: input.paletteVariantChoices,
9006
+ typographyPresetChoices,
9007
+ defaultTypographyPresetId
8008
9008
  };
8009
9009
  }
8010
9010
  function buttonChoice(id, note) {
@@ -8013,6 +9013,88 @@ function buttonChoice(id, note) {
8013
9013
  function paletteChoice(id, note) {
8014
9014
  return note ? { id: asPaletteVariantId(id), note } : { id: asPaletteVariantId(id) };
8015
9015
  }
9016
+ function headerLayoutChoice(id, note) {
9017
+ return note ? { id: asHeaderLayoutId(id), note } : { id: asHeaderLayoutId(id) };
9018
+ }
9019
+ function headerStyleChoice(id, note) {
9020
+ return note ? { id: asHeaderStyleId(id), note } : { id: asHeaderStyleId(id) };
9021
+ }
9022
+ function headerLayoutRecordKey(id) {
9023
+ return id;
9024
+ }
9025
+ function uniqueHeaderLayoutChoices(choices) {
9026
+ const seen = /* @__PURE__ */ new Set();
9027
+ const unique = choices.filter((choice) => {
9028
+ if (seen.has(choice.id)) return false;
9029
+ seen.add(choice.id);
9030
+ return true;
9031
+ });
9032
+ const first = unique[0];
9033
+ if (!first) {
9034
+ throw new Error("Expected at least one curated header layout choice.");
9035
+ }
9036
+ return [first, ...unique.slice(1)];
9037
+ }
9038
+ function nonEmptyHeaderStyleChoices(choices, fallbackLayoutId) {
9039
+ const first = choices[0] ?? {
9040
+ id: getCompatibleHeaderStyleIds(fallbackLayoutId)[0] ?? asHeaderStyleId("minimal")
9041
+ };
9042
+ return [first, ...choices.slice(1)];
9043
+ }
9044
+ function inferHeaderCurationFromLegacyLooks(lookIds) {
9045
+ const selections = lookIds.map((lookId) => resolveLegacyHeaderLookAlias(asHeaderLookId(lookId))).filter((selection) => Boolean(selection));
9046
+ const defaultHeaderSelection = selections[0] ?? {
9047
+ layoutId: asHeaderLayoutId("classic"),
9048
+ styleId: asHeaderStyleId("minimal")
9049
+ };
9050
+ const layoutChoices = uniqueHeaderLayoutChoices(
9051
+ selections.map((selection) => headerLayoutChoice(selection.layoutId))
9052
+ );
9053
+ const stylesByLayout = {};
9054
+ for (const layoutChoice of layoutChoices) {
9055
+ const styleChoices = selections.filter((selection) => selection.layoutId === layoutChoice.id).map((selection) => headerStyleChoice(selection.styleId));
9056
+ stylesByLayout[headerLayoutRecordKey(layoutChoice.id)] = nonEmptyHeaderStyleChoices(
9057
+ styleChoices,
9058
+ layoutChoice.id
9059
+ );
9060
+ }
9061
+ return {
9062
+ defaultHeaderSelection,
9063
+ recommendedHeaderLayoutChoices: layoutChoices,
9064
+ recommendedHeaderStyleChoicesByLayout: stylesByLayout
9065
+ };
9066
+ }
9067
+ function typographyChoice(id, note) {
9068
+ return note ? { id: asTypographyPresetId(id), note } : { id: asTypographyPresetId(id) };
9069
+ }
9070
+ function defaultTypographyPresetChoicesForRecipe(recipe) {
9071
+ switch (recipe) {
9072
+ case "clean-sans":
9073
+ return [
9074
+ typographyChoice("typography-preset:modern-sans"),
9075
+ typographyChoice("typography-preset:luxe-contrast"),
9076
+ typographyChoice("typography-preset:bold-display")
9077
+ ];
9078
+ case "friendly-sans":
9079
+ return [
9080
+ typographyChoice("typography-preset:warm-rounded"),
9081
+ typographyChoice("typography-preset:modern-sans"),
9082
+ typographyChoice("typography-preset:editorial-serif")
9083
+ ];
9084
+ case "serif-editorial":
9085
+ return [
9086
+ typographyChoice("typography-preset:editorial-serif"),
9087
+ typographyChoice("typography-preset:classic-serif"),
9088
+ typographyChoice("typography-preset:warm-rounded")
9089
+ ];
9090
+ case "classic-serif":
9091
+ return [
9092
+ typographyChoice("typography-preset:classic-serif"),
9093
+ typographyChoice("typography-preset:luxe-contrast"),
9094
+ typographyChoice("typography-preset:editorial-serif")
9095
+ ];
9096
+ }
9097
+ }
8016
9098
  var curatedSiteStyles = [
8017
9099
  defineCuratedSiteStyle({
8018
9100
  id: "site-style:calm-studio",
@@ -8338,6 +9420,102 @@ var curatedSiteStyles = [
8338
9420
  paletteChoice("warm-neutral-clay")
8339
9421
  ]
8340
9422
  }),
9423
+ defineCuratedSiteStyle({
9424
+ id: "site-style:soft-earth",
9425
+ name: "Soft Earth",
9426
+ description: "Warm, grounded, and editorial for yoga studios, retreats, and wellbeing communities.",
9427
+ 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.",
9428
+ siteCreatorSelection: { kind: "site_creator_keyword_heuristic", priority: 45 },
9429
+ selectionKeywordRules: [
9430
+ { kind: "word", value: "meditation" },
9431
+ { kind: "word", value: "wellbeing" },
9432
+ { kind: "substring", value: "retreat" },
9433
+ { kind: "phrase", value: "yoga studio" },
9434
+ { kind: "phrase", value: "mindful movement" }
9435
+ ],
9436
+ tokenRecipes: {
9437
+ palette: "warm-neutral",
9438
+ contrast: "standard",
9439
+ radius: "soft",
9440
+ shadow: "subtle",
9441
+ typography: "serif-editorial",
9442
+ spacing: "airy",
9443
+ motion: "subtle"
9444
+ },
9445
+ compositionBudget: balancedBudget,
9446
+ themeOverrides: {
9447
+ typography: {
9448
+ body: {
9449
+ family: "Inter, system-ui, sans-serif",
9450
+ size: "md",
9451
+ weight: "regular",
9452
+ lineHeight: "relaxed",
9453
+ letterSpacing: "normal"
9454
+ },
9455
+ headings: {
9456
+ default: {
9457
+ family: '"Cormorant Garamond", Georgia, serif',
9458
+ weight: "regular",
9459
+ lineHeight: "normal",
9460
+ letterSpacing: "normal",
9461
+ colorToken: "text",
9462
+ italic: null,
9463
+ case: null
9464
+ },
9465
+ h1: {
9466
+ size: "xl",
9467
+ weight: "regular",
9468
+ lineHeight: "normal",
9469
+ letterSpacing: "normal",
9470
+ italic: null
9471
+ },
9472
+ h2: {
9473
+ size: "lg",
9474
+ weight: "regular",
9475
+ lineHeight: "normal",
9476
+ letterSpacing: "normal",
9477
+ italic: null
9478
+ },
9479
+ h3: {
9480
+ size: "md",
9481
+ weight: "regular",
9482
+ lineHeight: "normal",
9483
+ letterSpacing: "normal",
9484
+ italic: null
9485
+ }
9486
+ },
9487
+ scale: "majorThird"
9488
+ },
9489
+ bodyText: {
9490
+ intro: {
9491
+ paragraphSize: "default",
9492
+ headingSize: "editorial"
9493
+ }
9494
+ }
9495
+ },
9496
+ recommendedAppearancePresetIds: [
9497
+ "hero-brand-scrim",
9498
+ "intro-soft-earth-statement",
9499
+ "feature-cards-soft-earth-offerings",
9500
+ "testimonials-soft-earth-proof-band",
9501
+ "faq-soft-earth-two-column",
9502
+ "contact-form-panel"
9503
+ ],
9504
+ recommendedHeaderLookIds: ["centered-calm", "minimal-transparent", "editorial-line"],
9505
+ recommendedFooterLookIds: ["footer-muted-grounding", "site-footer-brand-two-band"],
9506
+ buttonPersonalityChoices: [
9507
+ buttonChoice("earth-pill"),
9508
+ buttonChoice("soft-pill"),
9509
+ buttonChoice("pebble"),
9510
+ buttonChoice("editorial-link")
9511
+ ],
9512
+ paletteVariantChoices: [
9513
+ paletteChoice("warm-neutral-soft-earth"),
9514
+ paletteChoice("warm-neutral-clay"),
9515
+ paletteChoice("warm-neutral-forest"),
9516
+ paletteChoice("soft-natural-sage")
9517
+ ]
9518
+ }),
8341
9519
  defineCuratedSiteStyle({
8342
9520
  id: "site-style:bold-launch",
8343
9521
  name: "Bold Launch",
@@ -8391,49 +9569,13 @@ var curatedSiteStyles = [
8391
9569
  motion: "expressive"
8392
9570
  },
8393
9571
  compositionBudget: expressiveBudget,
9572
+ typographyPresetChoices: [
9573
+ typographyChoice("typography-preset:bold-display"),
9574
+ typographyChoice("typography-preset:modern-sans"),
9575
+ typographyChoice("typography-preset:luxe-contrast")
9576
+ ],
9577
+ defaultTypographyPresetId: "typography-preset:bold-display",
8394
9578
  themeOverrides: {
8395
- typography: {
8396
- body: {
8397
- family: "Manrope, system-ui, sans-serif",
8398
- size: "lg",
8399
- weight: "regular",
8400
- lineHeight: "relaxed",
8401
- letterSpacing: "normal"
8402
- },
8403
- headings: {
8404
- default: {
8405
- family: '"TAN - PEARL", sans-serif',
8406
- weight: "bold",
8407
- lineHeight: "normal",
8408
- letterSpacing: "tight",
8409
- colorToken: "primary",
8410
- italic: null,
8411
- case: null
8412
- },
8413
- h1: {
8414
- size: "xl",
8415
- weight: "bold",
8416
- lineHeight: "normal",
8417
- letterSpacing: "tight",
8418
- italic: null
8419
- },
8420
- h2: {
8421
- size: "lg",
8422
- weight: "bold",
8423
- lineHeight: "normal",
8424
- letterSpacing: "normal",
8425
- italic: null
8426
- },
8427
- h3: {
8428
- size: "md",
8429
- weight: "bold",
8430
- lineHeight: "normal",
8431
- letterSpacing: "normal",
8432
- italic: null
8433
- }
8434
- },
8435
- scale: "balanced"
8436
- },
8437
9579
  bodyText: {
8438
9580
  intro: {
8439
9581
  paragraphSize: "editorial",
@@ -13072,8 +14214,9 @@ var faqAccordionFragment = defineFragment({
13072
14214
  },
13073
14215
  fallback: "rb-faq-item"
13074
14216
  },
13075
- iconStyle: { $bind: { from: "theme.accordions.icon.style" } }
13076
- // Pass icon style from theme
14217
+ iconStyle: { $bind: { from: "theme.accordions.icon.style" } },
14218
+ // Legacy theme accordion style
14219
+ iconTreatment: { $bind: { from: "content._sectionStyles.accordionIconTreatment" } }
13077
14220
  },
13078
14221
  triggerFrom: "faqItem.question",
13079
14222
  contentFrom: "faqItem.answer"
@@ -14250,6 +15393,334 @@ var heroBlockDefinition = {
14250
15393
  manifest: heroManifest
14251
15394
  };
14252
15395
 
15396
+ // ../blocks/src/system/fields/aspectRatio.ts
15397
+ var standardAspectRatioOptions = [
15398
+ { value: "auto", label: "Auto (original)" },
15399
+ { value: "16/9", label: "16:9 (Landscape)" },
15400
+ { value: "4/3", label: "4:3 (Standard)" },
15401
+ { value: "1/1", label: "1:1 (Square)" },
15402
+ { value: "3/4", label: "3:4 (Portrait)" }
15403
+ ];
15404
+ function createAspectRatioField(options = {}) {
15405
+ return {
15406
+ id: options.id ?? "aspectRatio",
15407
+ type: "select",
15408
+ label: options.label ?? "Aspect ratio",
15409
+ ...options.description ? { description: options.description } : {},
15410
+ required: false,
15411
+ defaultValue: options.defaultValue ?? "auto",
15412
+ multiple: false,
15413
+ options: [...standardAspectRatioOptions],
15414
+ ui: {
15415
+ intent: options.uiIntent ?? "display",
15416
+ ...options.visibleWhen ? { visibleWhen: options.visibleWhen } : {}
15417
+ }
15418
+ };
15419
+ }
15420
+
15421
+ // ../blocks/src/system/fields/imageLayout.ts
15422
+ function createImageColSizeField(options = {}) {
15423
+ const {
15424
+ id = "imageColSize",
15425
+ label = "Image column size",
15426
+ description = "Controls how large the image/thumbnail column is at desktop breakpoints.",
15427
+ defaultValue = "1/3",
15428
+ uiIntent = "display",
15429
+ visibleWhen
15430
+ } = options;
15431
+ return {
15432
+ id,
15433
+ type: "select",
15434
+ label,
15435
+ description,
15436
+ required: false,
15437
+ defaultValue,
15438
+ multiple: false,
15439
+ options: [
15440
+ { value: "1/4", label: "Small (1/4)" },
15441
+ { value: "1/3", label: "Medium (1/3)" },
15442
+ { value: "2/5", label: "Large (2/5)" },
15443
+ { value: "1/2", label: "Extra large (1/2)" },
15444
+ { value: "2/3", label: "Huge (2/3)" }
15445
+ ],
15446
+ ui: {
15447
+ intent: uiIntent,
15448
+ ...visibleWhen ? { visibleWhen } : {}
15449
+ }
15450
+ };
15451
+ }
15452
+ function createImagePositionField(options = {}) {
15453
+ const {
15454
+ id = "imagePosition",
15455
+ label = "Image position",
15456
+ description = "Choose which side the image appears on.",
15457
+ defaultValue = "left",
15458
+ includeAlternate = false,
15459
+ uiIntent = "display",
15460
+ visibleWhen
15461
+ } = options;
15462
+ const positionOptions = [
15463
+ { value: "left", label: "Left" },
15464
+ { value: "right", label: "Right" },
15465
+ ...includeAlternate ? [{ value: "alternate", label: "Alternate" }] : []
15466
+ ];
15467
+ return {
15468
+ id,
15469
+ type: "select",
15470
+ label,
15471
+ description,
15472
+ required: false,
15473
+ defaultValue,
15474
+ multiple: false,
15475
+ // Spread to get a mutable array type without unsafe casts.
15476
+ options: [...positionOptions],
15477
+ ui: {
15478
+ intent: uiIntent,
15479
+ ...visibleWhen ? { visibleWhen } : {}
15480
+ }
15481
+ };
15482
+ }
15483
+
15484
+ // ../blocks/src/system/blocks/intro.ts
15485
+ function introHeading(className) {
15486
+ return text(
15487
+ {
15488
+ as: "h2",
15489
+ className
15490
+ },
15491
+ when("content.title"),
15492
+ bind("content.title")
15493
+ );
15494
+ }
15495
+ function introBody(className = "rb-prose rb-max-w-none") {
15496
+ return richText({ className }, bind("content.body"));
15497
+ }
15498
+ function introCtas(justify = "start") {
15499
+ return ctaRow({
15500
+ justify,
15501
+ gap: "md",
15502
+ containerClassName: "rb-mt-2"
15503
+ });
15504
+ }
15505
+ function introCopyStack(options = {}) {
15506
+ return stack(
15507
+ {
15508
+ gap: "md",
15509
+ className: options.className ?? "rb-intro-copy"
15510
+ },
15511
+ [
15512
+ introHeading(options.headingClassName ?? "rb-intro-title"),
15513
+ introBody(options.bodyClassName),
15514
+ introCtas(options.ctaJustify)
15515
+ ]
15516
+ );
15517
+ }
15518
+ var introMedia = media(
15519
+ {
15520
+ className: "rb-intro-media rb-w-full rb-h-auto rb-object-cover",
15521
+ style: {
15522
+ aspectRatio: { $bind: { from: "content.aspectRatio" } }
15523
+ }
15524
+ },
15525
+ bind("content.media")
15526
+ );
15527
+ var centeredCopyLayout = styledSection({
15528
+ children: styledContainer({
15529
+ rootType: "stack",
15530
+ rootProps: { gap: "lg" },
15531
+ children: [
15532
+ introCopyStack({
15533
+ className: "rb-intro-copy rb-mx-auto rb-max-w-3xl rb-text-center",
15534
+ headingClassName: "rb-intro-title rb-text-center",
15535
+ bodyClassName: "rb-prose rb-mx-auto rb-max-w-none",
15536
+ ctaJustify: "center"
15537
+ })
15538
+ ]
15539
+ }),
15540
+ baseClass: "",
15541
+ spacing: "medium"
15542
+ });
15543
+ var statementCopyLayout = styledSection({
15544
+ children: styledContainer({
15545
+ children: [
15546
+ el(
15547
+ "div",
15548
+ {
15549
+ className: "rb-intro rb-intro-statement rb-grid rb-grid-cols-1 rb-gap-8 rb-md-grid-cols-2 rb-md-items-start"
15550
+ },
15551
+ [
15552
+ introHeading("rb-intro-title rb-max-w-xl"),
15553
+ stack({ gap: "md", className: "rb-intro-copy rb-max-w-xl" }, [
15554
+ introBody(),
15555
+ introCtas("start")
15556
+ ])
15557
+ ]
15558
+ )
15559
+ ]
15560
+ }),
15561
+ baseClass: "",
15562
+ spacing: "medium"
15563
+ });
15564
+ var statementMediaLayout = styledSection({
15565
+ children: styledContainer({
15566
+ children: [
15567
+ el(
15568
+ "div",
15569
+ {
15570
+ 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"
15571
+ },
15572
+ [
15573
+ introHeading("rb-intro-title rb-max-w-xl"),
15574
+ stack({ gap: "md", className: "rb-intro-copy rb-max-w-xl" }, [
15575
+ introBody(),
15576
+ introCtas("start")
15577
+ ]),
15578
+ el("div", { className: "rb-intro-media-wrap rb-w-full" }, [introMedia], when("content.media"))
15579
+ ]
15580
+ )
15581
+ ]
15582
+ }),
15583
+ baseClass: "",
15584
+ spacing: "medium"
15585
+ });
15586
+ var mediaCopyLayout = styledSection({
15587
+ children: styledContainer({
15588
+ children: [
15589
+ responsiveTwoColumn({
15590
+ image: el("div", { className: "rb-intro-media-wrap rb-w-full" }, [introMedia]),
15591
+ text: introCopyStack({
15592
+ className: "rb-intro-copy rb-max-w-xl",
15593
+ headingClassName: "rb-intro-title"
15594
+ }),
15595
+ ratioFrom: "content.ratio",
15596
+ imagePositionFrom: "content.imagePosition",
15597
+ gapFrom: "content.gap",
15598
+ gapFallback: "comfortable",
15599
+ imageWrapperClassName: "rb-w-full rb-shrink-0",
15600
+ textWrapperClassName: "rb-w-full rb-min-w-0 rb-flex-1 rb-self-center"
15601
+ })
15602
+ ]
15603
+ }),
15604
+ baseClass: "",
15605
+ spacing: "medium"
15606
+ });
15607
+ var introConfig = {
15608
+ id: "block.intro",
15609
+ title: "Intro",
15610
+ category: "layout",
15611
+ includeContainerStyles: true,
15612
+ titleSource: "title",
15613
+ additionalFields: [
15614
+ {
15615
+ id: "title",
15616
+ type: "text",
15617
+ label: "Statement",
15618
+ required: false,
15619
+ multiline: true,
15620
+ maxLength: 160
15621
+ },
15622
+ {
15623
+ id: "body",
15624
+ type: "richText",
15625
+ label: "Text",
15626
+ required: true,
15627
+ ui: {
15628
+ richTextVariant: "limited"
15629
+ }
15630
+ },
15631
+ {
15632
+ id: "media",
15633
+ type: "media",
15634
+ label: "Media",
15635
+ required: false,
15636
+ mediaKinds: ["image"],
15637
+ ui: {
15638
+ intent: "content",
15639
+ visibleWhen: { field: "variant", notEquals: "statement-copy" }
15640
+ }
15641
+ },
15642
+ createImagePositionField({
15643
+ id: "imagePosition",
15644
+ label: "Image position",
15645
+ defaultValue: "left",
15646
+ uiIntent: "display",
15647
+ visibleWhen: { field: "variant", equals: "media-copy" }
15648
+ }),
15649
+ {
15650
+ id: "gap",
15651
+ type: "select",
15652
+ label: "Gap between media and text",
15653
+ required: false,
15654
+ defaultValue: "comfortable",
15655
+ multiple: false,
15656
+ options: [
15657
+ { value: "none", label: "None" },
15658
+ { value: "compact", label: "Compact" },
15659
+ { value: "cozy", label: "Cozy" },
15660
+ { value: "medium", label: "Medium" },
15661
+ { value: "comfortable", label: "Comfortable" },
15662
+ { value: "spacious", label: "Spacious" }
15663
+ ],
15664
+ ui: {
15665
+ intent: "display",
15666
+ visibleWhen: { field: "variant", equals: "media-copy" }
15667
+ }
15668
+ },
15669
+ createImageColSizeField({
15670
+ id: "ratio",
15671
+ label: "Media column size",
15672
+ defaultValue: "1/2",
15673
+ uiIntent: "display",
15674
+ visibleWhen: { field: "variant", equals: "media-copy" }
15675
+ }),
15676
+ createAspectRatioField({
15677
+ id: "aspectRatio",
15678
+ label: "Media aspect ratio",
15679
+ description: "Crop media to a consistent aspect ratio.",
15680
+ defaultValue: "auto",
15681
+ visibleWhen: { field: "media", notEquals: null }
15682
+ }),
15683
+ createCtasRepeater({
15684
+ label: "Calls to action",
15685
+ itemLabel: "CTA",
15686
+ maxItems: 2
15687
+ })
15688
+ ],
15689
+ layout: centeredCopyLayout,
15690
+ variants: {
15691
+ "centered-copy": centeredCopyLayout,
15692
+ "statement-copy": statementCopyLayout,
15693
+ "statement-media": statementMediaLayout,
15694
+ "media-copy": mediaCopyLayout
15695
+ },
15696
+ defaultVariant: "statement-copy",
15697
+ variantOptions: {
15698
+ "centered-copy": {
15699
+ label: "Centered copy",
15700
+ description: "A focused intro with centered text and optional calls to action."
15701
+ },
15702
+ "statement-copy": {
15703
+ label: "Statement and copy",
15704
+ description: "A large statement on the left with supporting copy on the right."
15705
+ },
15706
+ "statement-media": {
15707
+ label: "Statement, copy and media",
15708
+ description: "A three-part intro with statement, copy and a small image."
15709
+ },
15710
+ "media-copy": {
15711
+ label: "Media and copy",
15712
+ description: "A compact media/text intro for softer transitions after a hero."
15713
+ }
15714
+ },
15715
+ description: "A flexible introductory section for statement copy, supporting text, media, and CTAs.",
15716
+ tags: ["intro", "introduction", "about", "welcome", "statement", "media", "text"],
15717
+ icon: "PanelTopOpen"
15718
+ };
15719
+ var introManifest = createBlockManifest(introConfig);
15720
+ var introBlockDefinition = {
15721
+ manifest: introManifest
15722
+ };
15723
+
14253
15724
  // ../blocks/src/system/blocks/body-text.ts
14254
15725
  var bodyCopyComposition = composeFragments([{ fragment: bodyCopyFragment }]);
14255
15726
  var proseLayout = styledSection({
@@ -15115,6 +16586,37 @@ var faqComposition = composeFragments([
15115
16586
  { fragment: faqHeadingFragment, fieldPriority: 0 },
15116
16587
  { fragment: faqAccordionFragment, fieldPriority: 1 }
15117
16588
  ]);
16589
+ function fragmentLayoutNode(layout) {
16590
+ return isNodeDefinitionArray(layout) ? el("div", {}, [...layout]) : layout;
16591
+ }
16592
+ function isNodeDefinitionArray(layout) {
16593
+ return Array.isArray(layout);
16594
+ }
16595
+ var headingLayout = fragmentLayoutNode(faqHeadingFragment.layout);
16596
+ var accordionLayout = fragmentLayoutNode(faqAccordionFragment.layout);
16597
+ var defaultLayout = styledSection({
16598
+ children: styledContainer({
16599
+ baseClassName: "rb-relative rb-isolate",
16600
+ children: stack({ gap: "xl", className: "rb-w-full rb-max-w-4xl rb-mx-auto" }, faqComposition.layout)
16601
+ }),
16602
+ baseClass: ""
16603
+ });
16604
+ var twoColumnLayout = styledSection({
16605
+ children: styledContainer({
16606
+ baseClassName: "rb-relative rb-isolate",
16607
+ children: el(
16608
+ "div",
16609
+ {
16610
+ className: "rb-faq-two-column rb-grid rb-grid-cols-1 rb-gap-8 rb-lg-grid-cols-2 rb-lg-items-start"
16611
+ },
16612
+ [
16613
+ el("div", { className: "rb-faq-two-column-heading" }, [headingLayout]),
16614
+ el("div", { className: "rb-faq-two-column-accordion" }, [accordionLayout])
16615
+ ]
16616
+ )
16617
+ }),
16618
+ baseClass: ""
16619
+ });
15118
16620
  var faqManifest = createBlockManifest({
15119
16621
  id: "block.faq",
15120
16622
  title: "FAQ",
@@ -15131,13 +16633,22 @@ var faqManifest = createBlockManifest({
15131
16633
  label: "FAQ item styles"
15132
16634
  })
15133
16635
  ],
15134
- layout: styledSection({
15135
- children: styledContainer({
15136
- baseClassName: "rb-relative rb-isolate",
15137
- children: stack({ gap: "xl", className: "rb-w-full rb-max-w-4xl rb-mx-auto" }, faqComposition.layout)
15138
- }),
15139
- baseClass: ""
15140
- }),
16636
+ layout: defaultLayout,
16637
+ variants: {
16638
+ default: defaultLayout,
16639
+ "two-column": twoColumnLayout
16640
+ },
16641
+ defaultVariant: "default",
16642
+ variantOptions: {
16643
+ default: {
16644
+ label: "Default",
16645
+ description: "A centered heading above one FAQ accordion."
16646
+ },
16647
+ "two-column": {
16648
+ label: "Two column",
16649
+ description: "A left heading column with FAQ items on the right."
16650
+ }
16651
+ },
15141
16652
  description: "Accordion of frequently asked questions and answers.",
15142
16653
  tags: ["faq", "questions", "answers", "help", "support", "accordion", "q&a"],
15143
16654
  icon: "HelpCircle"
@@ -15787,7 +17298,8 @@ function resolveBackgroundVisualStyles(backgroundColor, tokens, defaultToken = "
15787
17298
  function resolveHeaderVisualStyles(header, tokens) {
15788
17299
  const navContainerType = header?.navContainer?.type ?? "none";
15789
17300
  const hasContainedNav = navContainerType === "glass" || navContainerType === "pill";
15790
- if (hasContainedNav) {
17301
+ const hasTransparentVariant = header?.variant === "transparent" || header?.variant === "floating";
17302
+ if (hasContainedNav || hasTransparentVariant) {
15791
17303
  return {
15792
17304
  backgroundToken: "transparent",
15793
17305
  paletteHex: null,
@@ -15916,6 +17428,17 @@ var headerRootStyleTransform = {
15916
17428
  return mergeStyles(...styleParts);
15917
17429
  }
15918
17430
  };
17431
+ var headerSectionBackgroundTransform = {
17432
+ id: "layout.headerSectionBackground",
17433
+ kind: "string",
17434
+ summary: "Resolve the inner site-header section background token",
17435
+ run: (value) => {
17436
+ const header = asPartialObject(value);
17437
+ const navContainerType = header?.navContainer?.type ?? "none";
17438
+ const usesTransparentRoot = header?.variant === "transparent" || header?.variant === "floating" || navContainerType === "glass" || navContainerType === "pill";
17439
+ return usesTransparentRoot ? "raw:transparent" : "background";
17440
+ }
17441
+ };
15919
17442
  var footerRootStyleTransform = {
15920
17443
  id: "layout.footerRootStyle",
15921
17444
  kind: "formatter",
@@ -16174,6 +17697,7 @@ var layoutTransforms = [
16174
17697
  headerRootClassTransform,
16175
17698
  footerRootClassTransform,
16176
17699
  headerRootStyleTransform,
17700
+ headerSectionBackgroundTransform,
16177
17701
  footerRootStyleTransform,
16178
17702
  footerBottomBarClassTransform,
16179
17703
  footerBottomBarContainerClassTransform,
@@ -16718,7 +18242,10 @@ var editorialLayout = stack(
16718
18242
  );
16719
18243
  var headerLayout = headerSection(
16720
18244
  {
16721
- background: "background",
18245
+ background: bindProp("$root.theme.header", {
18246
+ transforms: pipe(tx("layout.headerSectionBackground")),
18247
+ fallback: "background"
18248
+ }),
16722
18249
  allowOverflow: true,
16723
18250
  className: bindProp("$root.theme.header", {
16724
18251
  transforms: pipe(tx("layout.headerRootClass")),
@@ -17628,6 +19155,225 @@ var collectionBlockDefinition = {
17628
19155
  manifest: collectionManifest
17629
19156
  };
17630
19157
 
19158
+ // ../blocks/src/system/blocks/feature-cards.ts
19159
+ function grid3(props2, children) {
19160
+ return el("grid", props2 ?? void 0, children ?? void 0);
19161
+ }
19162
+ var sectionHeading = stack(
19163
+ { gap: "sm", className: "rb-feature-cards-heading rb-mx-auto rb-max-w-3xl rb-text-center" },
19164
+ [
19165
+ text(
19166
+ {
19167
+ as: "h2",
19168
+ className: "rb-feature-cards-title rb-text-center"
19169
+ },
19170
+ when("content.title"),
19171
+ bind("content.title")
19172
+ ),
19173
+ richText(
19174
+ {
19175
+ className: "rb-feature-cards-description rb-prose rb-mx-auto rb-max-w-none",
19176
+ style: textColorStyle("mutedText")
19177
+ },
19178
+ when("content.description"),
19179
+ bind("content.description")
19180
+ )
19181
+ ]
19182
+ );
19183
+ var featureCard = styledCard(
19184
+ [
19185
+ media(
19186
+ {
19187
+ className: "rb-feature-card-media rb-w-full rb-h-auto rb-object-cover",
19188
+ style: {
19189
+ aspectRatio: { $bind: { from: "card.aspectRatio" } }
19190
+ }
19191
+ },
19192
+ when("card.media"),
19193
+ bind("card.media")
19194
+ ),
19195
+ stack({ gap: "sm", className: "rb-feature-card-content rb-flex-1 rb-p-6" }, [
19196
+ text(
19197
+ {
19198
+ as: "h3",
19199
+ className: "rb-feature-card-title"
19200
+ },
19201
+ bind("card.title")
19202
+ ),
19203
+ richText(
19204
+ {
19205
+ className: "rb-feature-card-body rb-prose rb-max-w-none",
19206
+ style: textColorStyle("mutedText")
19207
+ },
19208
+ when("card.body"),
19209
+ bind("card.body")
19210
+ ),
19211
+ ctaRow({
19212
+ collectionPath: "ctas",
19213
+ itemName: "cta",
19214
+ gap: "sm",
19215
+ justify: "start",
19216
+ containerClassName: "rb-mt-auto"
19217
+ })
19218
+ ])
19219
+ ],
19220
+ {
19221
+ stylesFrom: "content._cardStyles",
19222
+ backgroundFrom: "content._cardStyles.background",
19223
+ baseClassName: "rb-feature-card rb-relative rb-isolate rb-overflow-hidden rb-border rb-flex rb-h-full rb-flex-col"
19224
+ },
19225
+ repeat("content.cards", "card")
19226
+ );
19227
+ var cardsLayout = styledSection({
19228
+ children: styledContainer({
19229
+ rootType: "stack",
19230
+ rootProps: { gap: "xl" },
19231
+ children: [
19232
+ sectionHeading,
19233
+ grid3(
19234
+ {
19235
+ cols: {
19236
+ $bind: {
19237
+ from: "content.columns",
19238
+ fallback: 3,
19239
+ coerce: "number"
19240
+ }
19241
+ },
19242
+ gap: "lg"
19243
+ },
19244
+ [featureCard]
19245
+ )
19246
+ ]
19247
+ }),
19248
+ baseClass: "",
19249
+ spacing: "medium"
19250
+ });
19251
+ var featureCardsConfig = {
19252
+ id: "block.feature-cards",
19253
+ title: "Feature Cards",
19254
+ category: "layout",
19255
+ includeContainerStyles: true,
19256
+ titleSource: "title",
19257
+ additionalFields: [
19258
+ {
19259
+ id: "title",
19260
+ type: "text",
19261
+ label: "Title",
19262
+ required: false,
19263
+ multiline: false,
19264
+ maxLength: 120
19265
+ },
19266
+ {
19267
+ id: "description",
19268
+ type: "richText",
19269
+ label: "Description",
19270
+ required: false,
19271
+ ui: {
19272
+ richTextVariant: "limited"
19273
+ }
19274
+ },
19275
+ {
19276
+ id: "columns",
19277
+ type: "select",
19278
+ label: "Columns",
19279
+ required: false,
19280
+ defaultValue: "3",
19281
+ multiple: false,
19282
+ options: [
19283
+ { value: "2", label: "2 columns" },
19284
+ { value: "3", label: "3 columns" },
19285
+ { value: "4", label: "4 columns" }
19286
+ ],
19287
+ ui: { intent: "display" }
19288
+ },
19289
+ {
19290
+ id: "cards",
19291
+ type: "repeater",
19292
+ label: "Cards",
19293
+ required: false,
19294
+ minItems: 1,
19295
+ maxItems: 8,
19296
+ itemLabel: "Card",
19297
+ itemLabelSource: "title",
19298
+ allowConversion: true,
19299
+ ui: {
19300
+ intent: "content"
19301
+ },
19302
+ schema: {
19303
+ fields: [
19304
+ {
19305
+ id: "media",
19306
+ type: "media",
19307
+ label: "Image",
19308
+ required: false,
19309
+ mediaKinds: ["image"]
19310
+ },
19311
+ createAspectRatioField({
19312
+ id: "aspectRatio",
19313
+ label: "Image aspect ratio",
19314
+ defaultValue: "4/3",
19315
+ visibleWhen: { field: "media", notEquals: null }
19316
+ }),
19317
+ {
19318
+ id: "title",
19319
+ type: "text",
19320
+ label: "Title",
19321
+ required: true,
19322
+ multiline: false,
19323
+ maxLength: 120
19324
+ },
19325
+ {
19326
+ id: "body",
19327
+ type: "richText",
19328
+ label: "Text",
19329
+ required: false,
19330
+ ui: {
19331
+ richTextVariant: "limited"
19332
+ }
19333
+ },
19334
+ createCtasRepeater({
19335
+ label: "Calls to action",
19336
+ itemLabel: "CTA",
19337
+ maxItems: 1,
19338
+ button: {
19339
+ variants: [
19340
+ { value: "primary", label: "Primary" },
19341
+ { value: "secondary", label: "Secondary" },
19342
+ { value: "outline", label: "Outline" },
19343
+ { value: "ghost", label: "Ghost" },
19344
+ { value: "link", label: "Link" }
19345
+ ],
19346
+ defaultVariant: "ghost"
19347
+ }
19348
+ })
19349
+ ]
19350
+ }
19351
+ },
19352
+ cardStylesField({
19353
+ id: "_cardStyles",
19354
+ label: "Card styles"
19355
+ })
19356
+ ],
19357
+ layout: cardsLayout,
19358
+ variants: {
19359
+ cards: cardsLayout
19360
+ },
19361
+ defaultVariant: "cards",
19362
+ variantOptions: {
19363
+ cards: {
19364
+ label: "Cards",
19365
+ description: "A responsive grid of image cards with optional calls to action."
19366
+ }
19367
+ },
19368
+ description: "A card grid for offerings, services, classes, benefits, or featured links.",
19369
+ tags: ["cards", "features", "offerings", "services", "classes", "grid", "links"],
19370
+ icon: "PanelsTopLeft"
19371
+ };
19372
+ var featureCardsManifest = createBlockManifest(featureCardsConfig);
19373
+ var featureCardsBlockDefinition = {
19374
+ manifest: featureCardsManifest
19375
+ };
19376
+
17631
19377
  // ../blocks/src/system/fields/carousel.ts
17632
19378
  var delayOptions = [
17633
19379
  { value: "3000", label: "3 seconds" },
@@ -17713,69 +19459,6 @@ function createCarouselBehaviorFields(options = {}) {
17713
19459
  return fields3;
17714
19460
  }
17715
19461
 
17716
- // ../blocks/src/system/fields/imageLayout.ts
17717
- function createImageColSizeField(options = {}) {
17718
- const {
17719
- id = "imageColSize",
17720
- label = "Image column size",
17721
- description = "Controls how large the image/thumbnail column is at desktop breakpoints.",
17722
- defaultValue = "1/3",
17723
- uiIntent = "display",
17724
- visibleWhen
17725
- } = options;
17726
- return {
17727
- id,
17728
- type: "select",
17729
- label,
17730
- description,
17731
- required: false,
17732
- defaultValue,
17733
- multiple: false,
17734
- options: [
17735
- { value: "1/4", label: "Small (1/4)" },
17736
- { value: "1/3", label: "Medium (1/3)" },
17737
- { value: "2/5", label: "Large (2/5)" },
17738
- { value: "1/2", label: "Extra large (1/2)" },
17739
- { value: "2/3", label: "Huge (2/3)" }
17740
- ],
17741
- ui: {
17742
- intent: uiIntent,
17743
- ...visibleWhen ? { visibleWhen } : {}
17744
- }
17745
- };
17746
- }
17747
- function createImagePositionField(options = {}) {
17748
- const {
17749
- id = "imagePosition",
17750
- label = "Image position",
17751
- description = "Choose which side the image appears on.",
17752
- defaultValue = "left",
17753
- includeAlternate = false,
17754
- uiIntent = "display",
17755
- visibleWhen
17756
- } = options;
17757
- const positionOptions = [
17758
- { value: "left", label: "Left" },
17759
- { value: "right", label: "Right" },
17760
- ...includeAlternate ? [{ value: "alternate", label: "Alternate" }] : []
17761
- ];
17762
- return {
17763
- id,
17764
- type: "select",
17765
- label,
17766
- description,
17767
- required: false,
17768
- defaultValue,
17769
- multiple: false,
17770
- // Spread to get a mutable array type without unsafe casts.
17771
- options: [...positionOptions],
17772
- ui: {
17773
- intent: uiIntent,
17774
- ...visibleWhen ? { visibleWhen } : {}
17775
- }
17776
- };
17777
- }
17778
-
17779
19462
  // ../blocks/src/system/blocks/media-text.ts
17780
19463
  var mediaTextFrameCapability = defineFrameCapability([
17781
19464
  "plain",
@@ -17899,26 +19582,13 @@ var mediaTextManifest = createBlockManifest({
17899
19582
  },
17900
19583
  ui: { intent: "behavior" }
17901
19584
  }),
17902
- {
19585
+ createAspectRatioField({
17903
19586
  id: "aspectRatio",
17904
- type: "select",
17905
19587
  label: "Media aspect ratio",
17906
19588
  description: "Crop media to a consistent aspect ratio.",
17907
- required: false,
17908
19589
  defaultValue: "auto",
17909
- multiple: false,
17910
- options: [
17911
- { value: "auto", label: "Auto (original)" },
17912
- { value: "16/9", label: "16:9 (Landscape)" },
17913
- { value: "4/3", label: "4:3 (Standard)" },
17914
- { value: "1/1", label: "1:1 (Square)" },
17915
- { value: "3/4", label: "3:4 (Portrait)" }
17916
- ],
17917
- ui: {
17918
- intent: "display",
17919
- visibleWhen: { field: "images", notEquals: null }
17920
- }
17921
- },
19590
+ visibleWhen: { field: "images", notEquals: null }
19591
+ }),
17922
19592
  {
17923
19593
  id: "text",
17924
19594
  type: "richText",
@@ -18048,7 +19718,7 @@ var mediaTextManifest = createBlockManifest({
18048
19718
  whenImagesLength(0)
18049
19719
  );
18050
19720
  const defaultInner = el("div", {}, [defaultImagesLayout, defaultTextOnlyLayout]);
18051
- const defaultLayout = styledSection({
19721
+ const defaultLayout2 = styledSection({
18052
19722
  children: styledContainer({
18053
19723
  rootType: "stack",
18054
19724
  rootProps: { gap: "lg" },
@@ -18080,9 +19750,9 @@ var mediaTextManifest = createBlockManifest({
18080
19750
  spacing: "medium"
18081
19751
  });
18082
19752
  return {
18083
- layout: defaultLayout,
19753
+ layout: defaultLayout2,
18084
19754
  variants: {
18085
- default: defaultLayout
19755
+ default: defaultLayout2
18086
19756
  },
18087
19757
  defaultVariant: "default",
18088
19758
  variantOptions: {
@@ -23721,7 +25391,7 @@ var embedBlockDefinition = {
23721
25391
  };
23722
25392
 
23723
25393
  // ../blocks/src/system/blocks/image-gallery.ts
23724
- var grid3 = (props2, children, ...mods) => el("grid", props2 ?? void 0, children ?? void 0, ...mods);
25394
+ var grid4 = (props2, children, ...mods) => el("grid", props2 ?? void 0, children ?? void 0, ...mods);
23725
25395
  var galleryContainer = (children, opts) => {
23726
25396
  const gap = opts?.gap ?? "md";
23727
25397
  const withExtraClass = (baseClass) => opts?.className ? `${baseClass} ${opts.className}` : baseClass;
@@ -23801,7 +25471,7 @@ var galleryItem = (options) => stack(
23801
25471
  ],
23802
25472
  repeat("content.images", "item")
23803
25473
  );
23804
- var gridLayout3 = grid3(
25474
+ var gridLayout3 = grid4(
23805
25475
  {
23806
25476
  className: "rb-grid rb-grid-cols-1 rb-gap-4 rb-sm-grid-cols-2 rb-md-grid-cols-3"
23807
25477
  },
@@ -24404,7 +26074,7 @@ var imageGalleryBlockDefinition = {
24404
26074
  };
24405
26075
 
24406
26076
  // ../blocks/src/system/blocks/video-grid.ts
24407
- var grid4 = (props2, children, ...mods) => el("grid", props2 ?? void 0, children ?? void 0, ...mods);
26077
+ var grid5 = (props2, children, ...mods) => el("grid", props2 ?? void 0, children ?? void 0, ...mods);
24408
26078
  var videoItem = (options) => stack(
24409
26079
  { gap: "xs", className: options.containerClassName },
24410
26080
  [
@@ -24454,7 +26124,7 @@ var gridColumnsClass = (columns) => {
24454
26124
  return "rb-grid rb-grid-cols-1 rb-gap-6 rb-sm-grid-cols-2 rb-md-grid-cols-3";
24455
26125
  }
24456
26126
  };
24457
- var createGridLayout = (columns) => grid4(
26127
+ var createGridLayout = (columns) => grid5(
24458
26128
  {
24459
26129
  className: gridColumnsClass(columns)
24460
26130
  },
@@ -27737,6 +29407,40 @@ var systemBlockDefinitionsRaw = [
27737
29407
  })
27738
29408
  ]
27739
29409
  })),
29410
+ withDesignCapability("block.intro", introBlockDefinition, declareBlockDesignCapability({
29411
+ sectionSurfaces: "supported",
29412
+ contentFrames: ["plain", "panel"],
29413
+ itemSurfaces: "unsupported",
29414
+ headingDecorations: ["organic-squiggle"]
29415
+ }), defineBlockDesignMetadata({
29416
+ flow: bodyFlow,
29417
+ layoutProfiles: [
29418
+ layoutProfile({
29419
+ variantKey: "centered-copy",
29420
+ family: "centered",
29421
+ weight: "featured",
29422
+ bias: "soft"
29423
+ }),
29424
+ layoutProfile({
29425
+ variantKey: "statement-copy",
29426
+ family: "split",
29427
+ weight: "featured",
29428
+ bias: "merge"
29429
+ }),
29430
+ layoutProfile({
29431
+ variantKey: "statement-media",
29432
+ family: "media-text",
29433
+ weight: "featured",
29434
+ bias: "soft"
29435
+ }),
29436
+ layoutProfile({
29437
+ variantKey: "media-copy",
29438
+ family: "media-text",
29439
+ weight: "featured",
29440
+ bias: "soft"
29441
+ })
29442
+ ]
29443
+ })),
27740
29444
  withDesignCapability("block.body-text", bodyTextBlockDefinition, sectionOnly(), defineBlockDesignMetadata({
27741
29445
  flow: bodyFlow,
27742
29446
  layoutProfiles: [
@@ -27797,9 +29501,17 @@ var systemBlockDefinitionsRaw = [
27797
29501
  flow: conversionFlow,
27798
29502
  layoutProfiles: [layoutProfile({ variantKey: "default", family: "form", weight: "standard" })]
27799
29503
  })),
27800
- withDesignCapability("block.faq", faqBlockDefinition, withEyebrowCapability(panelAndItemsCapable(), standardEyebrowTreatments), defineBlockDesignMetadata({
29504
+ withDesignCapability("block.faq", faqBlockDefinition, withEyebrowCapability(declareBlockDesignCapability({
29505
+ sectionSurfaces: "supported",
29506
+ contentFrames: ["plain", "panel"],
29507
+ itemSurfaces: "supported",
29508
+ accordionIconSets: ["plus", "chevron", "caret", "minimal-cross"]
29509
+ }), standardEyebrowTreatments), defineBlockDesignMetadata({
27801
29510
  flow: bodyFlow,
27802
- layoutProfiles: [layoutProfile({ variantKey: "default", family: "stack", weight: "standard" })]
29511
+ layoutProfiles: [
29512
+ layoutProfile({ variantKey: "default", family: "stack", weight: "standard" }),
29513
+ layoutProfile({ variantKey: "two-column", family: "split", weight: "standard" })
29514
+ ]
27803
29515
  })),
27804
29516
  withDesignCapability("block.site-header", siteHeaderBlockDefinition, declareNoBlockDesignCapability("site-chrome"), defineBlockDesignMetadata({
27805
29517
  flow: siteChromeFlow,
@@ -27813,7 +29525,8 @@ var systemBlockDefinitionsRaw = [
27813
29525
  sectionSurfaces: "supported",
27814
29526
  contentFrames: ["plain", "panel"],
27815
29527
  itemSurfaces: "supported",
27816
- testimonialCardTreatments: ["default", "accent-quote"]
29528
+ testimonialCardTreatments: ["default", "accent-quote"],
29529
+ headingDecorations: ["short-center-rule"]
27817
29530
  }), defineBlockDesignMetadata({
27818
29531
  flow: proofFlow,
27819
29532
  layoutProfiles: [
@@ -27839,6 +29552,22 @@ var systemBlockDefinitionsRaw = [
27839
29552
  flow: offeringsFlow,
27840
29553
  layoutProfiles: [layoutProfile({ variantKey: "default", family: "grid", weight: "standard" })]
27841
29554
  })),
29555
+ withDesignCapability("block.feature-cards", featureCardsBlockDefinition, declareBlockDesignCapability({
29556
+ sectionSurfaces: "supported",
29557
+ contentFrames: ["plain", "panel"],
29558
+ itemSurfaces: "supported",
29559
+ headingDecorations: ["short-center-rule"]
29560
+ }), defineBlockDesignMetadata({
29561
+ flow: offeringsFlow,
29562
+ layoutProfiles: [
29563
+ layoutProfile({
29564
+ variantKey: "cards",
29565
+ family: "grid",
29566
+ weight: "standard",
29567
+ bias: "soft"
29568
+ })
29569
+ ]
29570
+ })),
27842
29571
  withDesignCapability("block.media-text", mediaTextBlockDefinition, mediaPanelCapable(), defineBlockDesignMetadata({
27843
29572
  flow: mediaFlow,
27844
29573
  layoutProfiles: [
@@ -30068,6 +31797,42 @@ function normalizeBoolean2(value) {
30068
31797
  return Boolean(value);
30069
31798
  }
30070
31799
 
31800
+ // ../blocks/src/system/runtime/nodes/accordionIconTreatment.ts
31801
+ function resolveAccordionIconStyle(iconStyle, iconTreatment) {
31802
+ if (iconTreatment) {
31803
+ switch (iconTreatment.iconSet) {
31804
+ case "plus":
31805
+ return "plus-minus";
31806
+ case "chevron":
31807
+ return "chevron";
31808
+ case "caret":
31809
+ return "caret";
31810
+ case "minimal-cross":
31811
+ return "plus-minus";
31812
+ default:
31813
+ return assertNever4(iconTreatment.iconSet);
31814
+ }
31815
+ }
31816
+ return iconStyle && iconStyle in ICON_CONFIG ? iconStyle : "chevron";
31817
+ }
31818
+ function accordionIconColorStyle(iconTreatment) {
31819
+ const token = iconTreatment?.colorToken;
31820
+ if (!token || token === "current") return void 0;
31821
+ const themeToken = resolveIconColorToken(token);
31822
+ return {
31823
+ color: rgbColorValue(themeToken),
31824
+ ...iconTreatment.openColorToken && iconTreatment.openColorToken !== "current" ? {
31825
+ "--accordion-icon-open-color": rgbColorValue(resolveIconColorToken(iconTreatment.openColorToken))
31826
+ } : {}
31827
+ };
31828
+ }
31829
+ function resolveIconColorToken(token) {
31830
+ return token === "muted" ? "mutedText" : token;
31831
+ }
31832
+ function assertNever4(value) {
31833
+ throw new Error(`Unhandled accordion icon set: ${String(value)}`);
31834
+ }
31835
+
30071
31836
  // ../blocks/src/system/runtime/nodes/accordion.server.tsx
30072
31837
  import { jsx as jsx22, jsxs as jsxs9 } from "react/jsx-runtime";
30073
31838
  var ACCORDION_ICONS = {
@@ -30107,15 +31872,17 @@ var AccordionItemNodeSSR = ({
30107
31872
  content,
30108
31873
  question,
30109
31874
  answer,
30110
- iconStyle
31875
+ iconStyle,
31876
+ iconTreatment
30111
31877
  }) => {
30112
31878
  const resolvedValue = value !== void 0 && value !== null ? String(value) : void 0;
30113
31879
  const triggerSource = trigger ?? question;
30114
31880
  const contentSource = content ?? answer;
30115
- const resolvedIconStyle = iconStyle && iconStyle in ICON_CONFIG ? iconStyle : "chevron";
31881
+ const resolvedIconStyle = resolveAccordionIconStyle(iconStyle, iconTreatment);
30116
31882
  const iconConfig = ICON_CONFIG[resolvedIconStyle];
30117
31883
  const ClosedIconComponent = ACCORDION_ICONS[iconConfig.closedIcon];
30118
31884
  const OpenIconComponent = iconConfig.openIcon ? ACCORDION_ICONS[iconConfig.openIcon] : null;
31885
+ const iconColorStyle = accordionIconColorStyle(iconTreatment);
30119
31886
  return /* @__PURE__ */ jsxs9(
30120
31887
  "div",
30121
31888
  {
@@ -30125,10 +31892,20 @@ var AccordionItemNodeSSR = ({
30125
31892
  children: [
30126
31893
  /* @__PURE__ */ jsxs9("div", { className: "accordion-trigger", role: "button", tabIndex: 0, "aria-expanded": "false", children: [
30127
31894
  /* @__PURE__ */ jsx22("span", { className: "accordion-trigger-text", children: resolveNode(triggerSource) }),
30128
- /* @__PURE__ */ jsxs9("span", { className: "accordion-icon", "aria-hidden": "true", children: [
30129
- ClosedIconComponent && /* @__PURE__ */ jsx22(ClosedIconComponent, { className: "accordion-icon-closed" }),
30130
- OpenIconComponent && /* @__PURE__ */ jsx22(OpenIconComponent, { className: "accordion-icon-open" })
30131
- ] })
31895
+ /* @__PURE__ */ jsxs9(
31896
+ "span",
31897
+ {
31898
+ className: "accordion-icon",
31899
+ "aria-hidden": "true",
31900
+ "data-accordion-icon-set": iconTreatment?.iconSet,
31901
+ "data-accordion-icon-motion": iconTreatment?.motion,
31902
+ style: iconColorStyle,
31903
+ children: [
31904
+ ClosedIconComponent && /* @__PURE__ */ jsx22(ClosedIconComponent, { className: "accordion-icon-closed" }),
31905
+ OpenIconComponent && /* @__PURE__ */ jsx22(OpenIconComponent, { className: "accordion-icon-open" })
31906
+ ]
31907
+ }
31908
+ )
30132
31909
  ] }),
30133
31910
  /* @__PURE__ */ jsx22(
30134
31911
  "div",
@@ -37556,6 +39333,67 @@ function transformSdkBlockToDefinition(sdkBlock) {
37556
39333
  };
37557
39334
  }
37558
39335
 
39336
+ // ../blocks/src/customBlockRegistry.ts
39337
+ function isCustomBlockKind(blockKind) {
39338
+ return blockKind.startsWith("custom.");
39339
+ }
39340
+ function transformToBlockDescriptor(sdkBlock, source = "sdk") {
39341
+ return {
39342
+ name: sdkBlock.id,
39343
+ title: sdkBlock.title,
39344
+ description: sdkBlock.description,
39345
+ category: sdkBlock.category,
39346
+ tags: sdkBlock.tags,
39347
+ icon: sdkBlock.icon,
39348
+ definition: transformSdkBlockToDefinition(sdkBlock),
39349
+ source
39350
+ };
39351
+ }
39352
+ function toResolvedCustomBlock(manifest, source) {
39353
+ return {
39354
+ blockKind: manifest.id,
39355
+ manifest: transformSdkBlockToManifest(manifest),
39356
+ source,
39357
+ descriptor: transformToBlockDescriptor(
39358
+ manifest,
39359
+ source.kind === "managed-database" ? "database" : "sdk"
39360
+ )
39361
+ };
39362
+ }
39363
+ function createCustomBlockRegistry({
39364
+ sdkConfig,
39365
+ customBlocks = [],
39366
+ onConflict
39367
+ }) {
39368
+ const entriesByKind = /* @__PURE__ */ new Map();
39369
+ for (const sdkBlock of sdkConfig?.customBlocks ?? []) {
39370
+ entriesByKind.set(
39371
+ sdkBlock.id,
39372
+ toResolvedCustomBlock(sdkBlock, { kind: "sdk-config" })
39373
+ );
39374
+ }
39375
+ for (const customBlock of customBlocks) {
39376
+ const existing = entriesByKind.get(customBlock.manifest.id);
39377
+ if (existing) {
39378
+ onConflict?.(
39379
+ `Skipping DB custom block "${customBlock.manifest.id}" - conflicts with SDK config block`
39380
+ );
39381
+ continue;
39382
+ }
39383
+ entriesByKind.set(
39384
+ customBlock.manifest.id,
39385
+ toResolvedCustomBlock(customBlock.manifest, customBlock.source)
39386
+ );
39387
+ }
39388
+ return {
39389
+ entries: Array.from(entriesByKind.values()),
39390
+ findManifest: (blockKind) => {
39391
+ if (!isCustomBlockKind(blockKind)) return void 0;
39392
+ return entriesByKind.get(blockKind);
39393
+ }
39394
+ };
39395
+ }
39396
+
37559
39397
  // ../blocks/src/PageRenderer.tsx
37560
39398
  import { Fragment as Fragment6, jsx as jsx52 } from "react/jsx-runtime";
37561
39399
  function PageRenderer({
@@ -37723,17 +39561,14 @@ var MemoBlockSection = React6.memo(
37723
39561
  }
37724
39562
  const OverrideComponent = getBlockOverride(block.kind, blockOverrides);
37725
39563
  let definition = getBlockDefinition(block.kind);
37726
- if (!definition && block.kind.startsWith("custom.") && sdkConfig?.customBlocks) {
37727
- const sdkBlock = sdkConfig.customBlocks.find((b) => b.id === block.kind);
37728
- if (sdkBlock) {
37729
- definition = transformSdkBlockToDefinition(sdkBlock);
37730
- }
37731
- }
37732
- if (!definition && block.kind.startsWith("custom.") && customBlocks) {
37733
- const dbBlock = customBlocks.find((b) => b.id === block.kind);
37734
- if (dbBlock) {
37735
- definition = transformSdkBlockToDefinition(dbBlock);
37736
- }
39564
+ if (!definition && block.kind.startsWith("custom.")) {
39565
+ definition = createCustomBlockRegistry({
39566
+ sdkConfig,
39567
+ customBlocks: (customBlocks ?? []).map((manifest) => ({
39568
+ manifest,
39569
+ source: { kind: "managed-database" }
39570
+ }))
39571
+ }).findManifest(block.kind)?.descriptor.definition;
37737
39572
  }
37738
39573
  if (!definition) {
37739
39574
  if (OverrideComponent) {
@@ -37760,13 +39595,16 @@ var MemoBlockSection = React6.memo(
37760
39595
  }
37761
39596
  if (block.kind.startsWith("custom.") && shouldDebugCustomBlocks()) {
37762
39597
  try {
37763
- console.warn("[blocks:PageRenderer] custom block definition missing", {
37764
- blockId: block.id ?? null,
37765
- blockKind: block.kind,
37766
- hasOverride: Boolean(OverrideComponent),
37767
- sdkCustomBlocksCount: sdkConfig?.customBlocks?.length ?? 0,
37768
- dbCustomBlocksCount: customBlocks?.length ?? 0
37769
- });
39598
+ console.warn(
39599
+ "[blocks:PageRenderer] custom block definition missing",
39600
+ {
39601
+ blockId: block.id ?? null,
39602
+ blockKind: block.kind,
39603
+ hasOverride: Boolean(OverrideComponent),
39604
+ sdkCustomBlocksCount: sdkConfig?.customBlocks?.length ?? 0,
39605
+ dbCustomBlocksCount: customBlocks?.length ?? 0
39606
+ }
39607
+ );
37770
39608
  } catch {
37771
39609
  }
37772
39610
  }
@@ -37780,12 +39618,15 @@ var MemoBlockSection = React6.memo(
37780
39618
  if (!OverrideComponent && !manifestHasLayout) {
37781
39619
  if (block.kind.startsWith("custom.") && shouldDebugCustomBlocks()) {
37782
39620
  try {
37783
- console.warn("[blocks:PageRenderer] custom block has no layout/variants and no override", {
37784
- blockId: block.id ?? null,
37785
- blockKind: block.kind,
37786
- hasOverride: false,
37787
- manifestKeys: Object.keys(definition.manifest ?? {}).sort()
37788
- });
39621
+ console.warn(
39622
+ "[blocks:PageRenderer] custom block has no layout/variants and no override",
39623
+ {
39624
+ blockId: block.id ?? null,
39625
+ blockKind: block.kind,
39626
+ hasOverride: false,
39627
+ manifestKeys: Object.keys(definition.manifest ?? {}).sort()
39628
+ }
39629
+ );
37789
39630
  } catch {
37790
39631
  }
37791
39632
  }
@@ -37819,9 +39660,10 @@ var MemoBlockSection = React6.memo(
37819
39660
  if (parsed.success) {
37820
39661
  data = parsed.data;
37821
39662
  } else if (usePlaceholders) {
37822
- const relaxed = getCachedValidator(definition.manifest, "relaxed").safeParse(
37823
- content
37824
- );
39663
+ const relaxed = getCachedValidator(
39664
+ definition.manifest,
39665
+ "relaxed"
39666
+ ).safeParse(content);
37825
39667
  if (relaxed.success) {
37826
39668
  data = relaxed.data;
37827
39669
  } else {