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