@riverbankcms/sdk 0.125.0 → 0.127.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 (177) hide show
  1. package/README.md +3 -1
  2. package/dist/{PreviewEditorSidebar-BezDOtQ7.mjs → PreviewEditorSidebar-BXtfF7tp.mjs} +122 -301
  3. package/dist/{PreviewEditorUI-CgSqmfo2.mjs → PreviewEditorUI-Dou73Q0K.mjs} +3 -3
  4. package/dist/{PreviewQueryProvider-BH-3-jSj.mjs → PreviewQueryProvider-DgFDIwvK.mjs} +1 -1
  5. package/dist/{SdkPreviewModeRuntime-Co3AHfj0.mjs → SdkPreviewModeRuntime-B0HPXr-l.mjs} +141 -63
  6. package/dist/{SiteChromeCustomizeContext-BHF-KANn.mjs → SiteChromeCustomizeContext-DZiDBAYu.mjs} +5330 -5841
  7. package/dist/_dts/ai/src/contracts/proposals.d.ts +1552 -202
  8. package/dist/_dts/api/src/common/envelope.d.ts +1 -1
  9. package/dist/_dts/api/src/contentRuntime.d.ts +1 -7
  10. package/dist/_dts/api/src/endpoints.d.ts +0 -7
  11. package/dist/_dts/api/src/sdk-event-upsert.d.ts +42 -0
  12. package/dist/_dts/api/src/sdkContracts.d.ts +11 -9
  13. package/dist/_dts/api/src/siteOperations.d.ts +18 -1
  14. package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +1 -14
  15. package/dist/_dts/block-form/src/backend/store-backend.d.ts +2 -1
  16. package/dist/_dts/block-form/src/blockDraftSaveability.d.ts +1 -0
  17. package/dist/_dts/blocks/src/index.d.ts +3 -2
  18. package/dist/_dts/blocks/src/lib/media.d.ts +267 -0
  19. package/dist/_dts/blocks/src/system/constants/buttonRoles.d.ts +0 -13
  20. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationStripeReturn.d.ts +15 -2
  21. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCollectionContract.d.ts +4 -4
  22. package/dist/_dts/blocks/src/system/runtime/nodes/mergeResolveImageUrlContexts.d.ts +7 -0
  23. package/dist/_dts/blocks/src/system/runtime/nodes/shared/contract-schemas.d.ts +2 -2
  24. package/dist/_dts/content-editor/src/ui/blockValidationManifestRegistry.d.ts +17 -0
  25. package/dist/_dts/content-editor/src/ui/blockValidationView.d.ts +1 -1
  26. package/dist/_dts/content-editor/src/ui/editorUiStore.d.ts +4 -0
  27. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +322 -171
  28. package/dist/_dts/editor-blocks/src/BlockEditor.d.ts +4 -0
  29. package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockValidationManifests.d.ts +26 -0
  30. package/dist/_dts/editor-blocks/src/widgets/rich-text/imageInsert.d.ts +3 -3
  31. package/dist/_dts/media-editor/src/MediaEditor.d.ts +2 -2
  32. package/dist/_dts/media-editor/src/context.d.ts +1 -2
  33. package/dist/_dts/media-editor/src/index.d.ts +3 -1
  34. package/dist/_dts/media-editor/src/mediaSelection.d.ts +32 -0
  35. package/dist/_dts/media-editor/src/types.d.ts +3 -1
  36. package/dist/_dts/media-editor/src/useMediaSelection.d.ts +26 -0
  37. package/dist/_dts/preview-next/src/client/index.d.ts +2 -0
  38. package/dist/_dts/preview-next/src/client/preview/HeaderMenuControls.d.ts +12 -0
  39. package/dist/_dts/preview-next/src/client/preview/PreviewEditorSidebar.d.ts +1 -2
  40. package/dist/_dts/preview-next/src/client/preview/PreviewShell.d.ts +13 -3
  41. package/dist/_dts/preview-next/src/client/preview/PreviewShellLayout.d.ts +7 -2
  42. package/dist/_dts/preview-next/src/client/preview/SiteChromeCustomizeContext.d.ts +6 -60
  43. package/dist/_dts/preview-next/src/client/preview/StyleConfigurator.d.ts +3 -13
  44. package/dist/_dts/preview-next/src/client/preview/StyleConfigurator.state.d.ts +8 -100
  45. package/dist/_dts/preview-next/src/client/preview/headerInteractionPaletteSurfaceState.d.ts +8 -0
  46. package/dist/_dts/preview-next/src/client/preview/previewThemeRoles.d.ts +15 -0
  47. package/dist/_dts/preview-next/src/client/preview/siteChromeCustomizeTypes.d.ts +54 -0
  48. package/dist/_dts/preview-next/src/client/preview/siteChromeLookRows.d.ts +13 -3
  49. package/dist/_dts/preview-next/src/client/preview/siteChromeNavQuickControlHistory.d.ts +3 -0
  50. package/dist/_dts/preview-next/src/client/preview/siteChromeQuickControlHistoryState.d.ts +6 -3
  51. package/dist/_dts/preview-next/src/client/preview/siteStylePreviewPlanner.d.ts +1 -4
  52. package/dist/_dts/preview-next/src/client/preview/styleConfiguratorApplyPayload.d.ts +1 -15
  53. package/dist/_dts/preview-next/src/client/preview/styleConfiguratorSnapshot.d.ts +11 -21
  54. package/dist/_dts/sdk/src/cli/commands/event.d.ts +2 -2
  55. package/dist/_dts/sdk/src/cli/commands/eventOccurrenceSchedule.d.ts +12 -0
  56. package/dist/_dts/sdk/src/cli/commands/push/pushAllExtras.d.ts +6 -0
  57. package/dist/_dts/sdk/src/cli/commands/style.d.ts +1 -1
  58. package/dist/_dts/sdk/src/cli/content/legacyEventScheduleShapeError.d.ts +5 -0
  59. package/dist/_dts/sdk/src/cli/content/localEventSchedule.d.ts +17 -0
  60. package/dist/_dts/sdk/src/cli/content/reader.d.ts +5 -10
  61. package/dist/_dts/sdk/src/cli/migrations/events.d.ts +1 -1
  62. package/dist/_dts/sdk/src/cli/site-commands/eventScheduleCompiler.d.ts +24 -0
  63. package/dist/_dts/sdk/src/client/management/http.d.ts +1 -1
  64. package/dist/_dts/sdk/src/client/management/types.d.ts +3 -28
  65. package/dist/_dts/sdk/src/config/index.d.ts +1 -1
  66. package/dist/_dts/sdk/src/public-api/contracts.d.ts +5 -20
  67. package/dist/_dts/sdk/src/rendering/index.d.ts +1 -1
  68. package/dist/_dts/sdk/src/rendering/islands/types.d.ts +2 -2
  69. package/dist/_dts/sdk/src/version.d.ts +1 -1
  70. package/dist/_dts/site-commands/src/commandContract.d.ts +33 -5
  71. package/dist/_dts/site-commands/src/commandDomain.d.ts +2 -2
  72. package/dist/_dts/site-commands/src/commands.d.ts +38 -9
  73. package/dist/_dts/site-commands/src/siteStyleCommandSchema.d.ts +28 -1
  74. package/dist/_dts/site-commands/src/siteStyleSelectionSchemaBuilder.d.ts +4 -4
  75. package/dist/_dts/theme-core/src/buttons/effects/presets/background.d.ts +1 -1
  76. package/dist/_dts/theme-core/src/buttons/styles/registry.d.ts +0 -18
  77. package/dist/_dts/theme-core/src/buttons/types.d.ts +1 -3
  78. package/dist/_dts/theme-core/src/header/containerSchema.d.ts +20 -0
  79. package/dist/_dts/theme-core/src/header/generateHeaderCss.d.ts +1 -1
  80. package/dist/_dts/theme-core/src/header/interactionPalette.d.ts +14 -0
  81. package/dist/_dts/theme-core/src/header/legacyNavLinkStyle.d.ts +3 -0
  82. package/dist/_dts/theme-core/src/header/paintTargets.d.ts +25 -0
  83. package/dist/_dts/theme-core/src/header/scrollTreatment.d.ts +11 -0
  84. package/dist/_dts/theme-core/src/header/surfaceRules.d.ts +9 -0
  85. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +15 -0
  86. package/dist/_dts/theme-core/src/palette/colors.d.ts +1 -1
  87. package/dist/_dts/theme-core/src/palette/concretePalette.d.ts +20 -0
  88. package/dist/_dts/theme-core/src/palette/curated/index.d.ts +2 -17
  89. package/dist/_dts/theme-core/src/palette/index.d.ts +1 -6
  90. package/dist/_dts/theme-core/src/palette/schema.d.ts +39 -0
  91. package/dist/_dts/theme-core/src/schema.d.ts +105 -45
  92. package/dist/_dts/theme-core/src/site-styles/appearancePresetCatalog.d.ts +3 -51
  93. package/dist/_dts/theme-core/src/site-styles/appearancePresetTypes.d.ts +4 -11
  94. package/dist/_dts/theme-core/src/site-styles/blockAppearancePresets.d.ts +3 -51
  95. package/dist/_dts/theme-core/src/site-styles/headerInteractionPalette.d.ts +32 -0
  96. package/dist/_dts/theme-core/src/site-styles/headerLooks.d.ts +19 -106
  97. package/dist/_dts/theme-core/src/site-styles/headerOpeningForeground.d.ts +22 -0
  98. package/dist/_dts/theme-core/src/site-styles/headerOpeningSection.d.ts +2 -0
  99. package/dist/_dts/theme-core/src/site-styles/headerStyleParts.d.ts +4 -0
  100. package/dist/_dts/theme-core/src/site-styles/index.d.ts +3 -0
  101. package/dist/_dts/theme-core/src/site-styles/lookOptionGroups.d.ts +24 -0
  102. package/dist/_dts/theme-core/src/site-styles/lookResolution.d.ts +1 -2
  103. package/dist/_dts/theme-core/src/site-styles/pageDesignEditorModel.d.ts +4 -22
  104. package/dist/_dts/theme-core/src/site-styles/pageDesignEditorOptions.d.ts +21 -0
  105. package/dist/_dts/theme-core/src/site-styles/previewCompiler.d.ts +5 -7
  106. package/dist/_dts/theme-core/src/site-styles/runtimeCompiler.d.ts +5 -6
  107. package/dist/_dts/theme-core/src/site-styles/siteChromeNavPreferences.d.ts +4 -1
  108. package/dist/cli/index.mjs +1583 -1601
  109. package/dist/cli/init-docs/content/cli-reference.md +6 -3
  110. package/dist/cli/init-docs/content/content-management.md +24 -13
  111. package/dist/client/{DiscountCodeDisclosure-CyPpekBp.mjs → DiscountCodeDisclosure-BDFRp8Y7.mjs} +1 -1
  112. package/dist/client/{EventCombined.client-zywit-60.mjs → EventCombined.client-DJgF1_lf.mjs} +2 -2
  113. package/dist/client/{EventListing.client-J2nLhkKT.mjs → EventListing.client-CnWGNjOr.mjs} +2 -2
  114. package/dist/client/{LeafletStaticMap-CSubXWt6.mjs → LeafletStaticMap-BISs9Bl7.mjs} +1 -1
  115. package/dist/client/{MagicLinkForm-DDLIfiq9.mjs → MagicLinkForm-b5E_HoG9.mjs} +1 -1
  116. package/dist/client/{StepIndicator-DE8EvHIp.mjs → StepIndicator-D8gVYkK-.mjs} +2 -2
  117. package/dist/client/{accordion-Ct5T5NiA.mjs → accordion-DFDajgDz.mjs} +1 -1
  118. package/dist/client/{bookingForm-DMxtLPxw.mjs → bookingForm-Bdqj9-52.mjs} +5 -6
  119. package/dist/client/bookings.mjs +315 -46
  120. package/dist/client/{carousel--FMqgvob.mjs → carousel-Cvqf-kN8.mjs} +1 -1
  121. package/dist/client/{cart-BKX1bWiU.mjs → cart-CuH2TJXP.mjs} +3 -3
  122. package/dist/client/{checkout-B_jxi4WW.mjs → checkout-CMNPpejZ.mjs} +3 -3
  123. package/dist/client/client.mjs +1381 -1427
  124. package/dist/client/{courseRegistration-DH4MlkRD.mjs → courseRegistration-DTEYWL6Z.mjs} +6 -7
  125. package/dist/client/{eventCalendar-BQILwAcL.mjs → eventCalendar-BW-XoxZ0.mjs} +4 -4
  126. package/dist/client/{eventCombined-DFFW_Vmo.mjs → eventCombined-Bpn7s0y9.mjs} +2 -2
  127. package/dist/client/{eventDetails-B045CTSJ.mjs → eventDetails-D2uUSTMH.mjs} +3 -3
  128. package/dist/client/{eventListing-BDMYNVzS.mjs → eventListing-CVr1c094.mjs} +2 -2
  129. package/dist/client/{eventRegistration-CQ2-BSnB.mjs → eventRegistration-Dv4AvkMw.mjs} +30 -22
  130. package/dist/client/{form-DJKuyZgN.mjs → form-DxdKf9fs.mjs} +1 -1
  131. package/dist/client/{headerSection-DeTjfiDo.mjs → headerSection-BaXI5Sro.mjs} +2 -2
  132. package/dist/client/hooks.mjs +851 -976
  133. package/dist/client/{locationMap-i2wDA8gB.mjs → locationMap-BEtW2fKz.mjs} +2 -2
  134. package/dist/client/{newsletterForm-DKiueauk.mjs → newsletterForm-BKKs0S4R.mjs} +1 -1
  135. package/dist/client/{pricing-C01J3Epx.mjs → pricing-ClkqcElA.mjs} +1 -1
  136. package/dist/client/{productDetail-Dfc1sZaX.mjs → productDetail-H-ru8dyy.mjs} +3 -3
  137. package/dist/client/{productList-BXbvXWTF.mjs → productList-Buyi5c0C.mjs} +3 -3
  138. package/dist/client/{propsDecoder-CIR5DQ1l.mjs → propsDecoder-BF7i6Ijg.mjs} +293 -65
  139. package/dist/client/rendering/client.mjs +1145 -1190
  140. package/dist/client/rendering/islands.mjs +18 -18
  141. package/dist/client/rendering.mjs +1257 -1298
  142. package/dist/client/{useDiscountCodeUi-Bcyh4508.mjs → scrollToBlock-D_7t8yWb.mjs} +18 -2
  143. package/dist/client/{shop-BbNwPKM-.mjs → shop-CF7SZQNX.mjs} +5 -6
  144. package/dist/client/{shop-commerce-XO-XMFEt.mjs → shop-commerce-DA7_Rq5p.mjs} +4 -4
  145. package/dist/client/{shop-commerce-store-Byh6OUGK.mjs → shop-commerce-store-BmLqW7Gh.mjs} +1 -1
  146. package/dist/client/{shopShared-Bbq39mwr.mjs → shopShared-WL-E1znM.mjs} +2 -2
  147. package/dist/client/{useEventFilters-C8OOJ3el.mjs → useEventFilters-rc8VLeLV.mjs} +2 -2
  148. package/dist/client/{usePolling-CyJVo9kF.mjs → usePolling-1ncrfd4S.mjs} +2 -2
  149. package/dist/preview-next/before-render.mjs +0 -7
  150. package/dist/preview-next/client/runtime.mjs +4 -4
  151. package/dist/preview-next/middleware.mjs +0 -7
  152. package/dist/{previewAuthStore-CJX21dGi.mjs → previewAuthStore-Dev9CdG9.mjs} +0 -7
  153. package/dist/{sdk-runtime-BGhyuE-E.mjs → sdk-runtime-BnrCCFJq.mjs} +2 -2
  154. package/dist/{separator-BFs-Kmv5.mjs → separator-CFvBx2yl.mjs} +1 -1
  155. package/dist/server/components.mjs +1389 -1489
  156. package/dist/server/config-validation.mjs +851 -976
  157. package/dist/server/config.mjs +851 -976
  158. package/dist/server/data.mjs +851 -976
  159. package/dist/server/index.mjs +1 -8
  160. package/dist/server/next.mjs +1393 -1500
  161. package/dist/server/page-converter.mjs +851 -976
  162. package/dist/server/prebuild.mjs +1 -1
  163. package/dist/server/rendering/server.mjs +1346 -1446
  164. package/dist/server/rendering.mjs +1390 -1490
  165. package/dist/server/routing.mjs +939 -1041
  166. package/dist/server/server.mjs +852 -984
  167. package/dist/server/theme-bridge.mjs +322 -279
  168. package/dist/server/theme.mjs +277 -33
  169. package/package.json +1 -1
  170. package/dist/_dts/editor-blocks/src/widgets/rich-text/ensureRichTextImageAssetIdentifier.d.ts +0 -8
  171. package/dist/_dts/theme-core/src/palette/editorState.d.ts +0 -75
  172. package/dist/_dts/theme-core/src/palette/libraryModel.d.ts +0 -64
  173. package/dist/_dts/theme-core/src/palette/persistenceReadSource.d.ts +0 -81
  174. package/dist/_dts/theme-core/src/palette/resolveSelection.d.ts +0 -75
  175. package/dist/_dts/theme-core/src/palette/selection.d.ts +0 -74
  176. package/dist/_dts/theme-core/src/palette/sitePalettePersistence.d.ts +0 -34
  177. package/dist/client/scrollToBlock-C86BYkyV.mjs +0 -17
@@ -99,7 +99,7 @@ const parseEventOfferingId = (value) => parseUuidBrand$1(value, unsafeAsEventOff
99
99
  const parseEventSeriesId = (value) => parseUuidBrand$1(value, unsafeAsEventSeriesId);
100
100
  //#endregion
101
101
  //#region ../core/src/assert-never.ts
102
- function assertNever$25(value, message = "Unexpected variant") {
102
+ function assertNever$24(value, message = "Unexpected variant") {
103
103
  throw new Error(`${message}: ${String(value)}`);
104
104
  }
105
105
  const CURRENCY_LOCALE_BY_CODE = {
@@ -190,7 +190,7 @@ function formatCoursePriceDisplayLabel(display, options) {
190
190
  case "exact": return `Course (${formatCurrencyAmount(display.amount, display.currency, options)})`;
191
191
  case "from": return `Course (From ${formatCurrencyAmount(display.amount, display.currency, options)})`;
192
192
  case "range": return `Course (${formatCurrencyAmount(display.minAmount, display.currency, options)} - ${formatCurrencyAmount(display.maxAmount, display.currency, options)})`;
193
- default: return assertNever$25(display);
193
+ default: return assertNever$24(display);
194
194
  }
195
195
  }
196
196
  /**
@@ -210,7 +210,7 @@ function formatBookingPriceDisplay(display, options = {}) {
210
210
  case "unavailable": return "Pricing unavailable";
211
211
  case "external": return display.label;
212
212
  case "course": return formatCoursePriceDisplayLabel(display.display, options);
213
- default: return assertNever$25(display);
213
+ default: return assertNever$24(display);
214
214
  }
215
215
  }
216
216
  /** Render an event's price directly from its pricing value. */
@@ -3594,6 +3594,99 @@ function createRichTextDoc(paragraphs) {
3594
3594
  } : { type: "paragraph" })
3595
3595
  };
3596
3596
  }
3597
+ const PUBLIC_DOWNLOAD_MEDIA_TYPES = [
3598
+ "document",
3599
+ "spreadsheet",
3600
+ "archive",
3601
+ "audio"
3602
+ ];
3603
+ const hotspotSchema$1 = z.object({
3604
+ x: z.number().min(0).max(1),
3605
+ y: z.number().min(0).max(1),
3606
+ radius: z.number().optional()
3607
+ });
3608
+ const rotationSchema$1 = z.union([
3609
+ z.literal(0),
3610
+ z.literal(90),
3611
+ z.literal(180),
3612
+ z.literal(270)
3613
+ ]);
3614
+ const rectSchema$1 = z.tuple([
3615
+ z.number(),
3616
+ z.number(),
3617
+ z.number(),
3618
+ z.number()
3619
+ ]);
3620
+ const aspectCropSchema$1 = z.object({
3621
+ aspect: z.preprocess((value) => value == null ? void 0 : value, z.string().optional()),
3622
+ rect: z.preprocess((value) => value == null ? void 0 : value, rectSchema$1.optional()),
3623
+ hotspot: z.preprocess((value) => value == null ? void 0 : value, hotspotSchema$1.optional()),
3624
+ rotation: z.preprocess((value) => value == null ? void 0 : value, rotationSchema$1.optional())
3625
+ });
3626
+ const transformSchema$1 = z.object({
3627
+ aspectCrops: z.preprocess((value) => {
3628
+ if (!value || typeof value !== "object" || Array.isArray(value)) return;
3629
+ return value;
3630
+ }, z.record(z.string(), aspectCropSchema$1.catch({}))).optional(),
3631
+ rect: rectSchema$1.optional(),
3632
+ hotspot: hotspotSchema$1.optional(),
3633
+ rotation: rotationSchema$1.optional()
3634
+ });
3635
+ const mediaPosterSchema = z.discriminatedUnion("tag", [z.object({
3636
+ tag: z.literal("storage"),
3637
+ assetId: z.string().optional(),
3638
+ storageBucket: z.string().min(1),
3639
+ storagePath: z.string().min(1)
3640
+ }), z.object({
3641
+ tag: z.literal("external-src"),
3642
+ assetId: z.string().optional(),
3643
+ src: z.string().url()
3644
+ })]);
3645
+ const mediaBaseSchema = z.object({
3646
+ purpose: z.string().optional(),
3647
+ placeholder: z.boolean().default(true).optional(),
3648
+ assetId: z.string().optional(),
3649
+ identifier: z.string().optional(),
3650
+ src: z.string().optional(),
3651
+ alt: z.string().optional(),
3652
+ filename: z.string().optional(),
3653
+ mimeType: z.string().optional(),
3654
+ width: z.number().optional(),
3655
+ height: z.number().optional(),
3656
+ storageBucket: z.string().optional(),
3657
+ storagePath: z.string().optional(),
3658
+ poster: mediaPosterSchema.optional(),
3659
+ transform: transformSchema$1.optional()
3660
+ });
3661
+ /**
3662
+ * Canonical identifier carried by media values that are safe to persist.
3663
+ * Parsing trims boundary input so downstream writers cannot retain whitespace-only
3664
+ * identifiers or independently disagree about normalization.
3665
+ */
3666
+ const mediaIdentifierSchema = z.string().trim().min(1).brand();
3667
+ const imageMediaSchema = mediaBaseSchema.extend({ type: z.literal("image") });
3668
+ const videoMediaSchema = mediaBaseSchema.extend({ type: z.literal("video") });
3669
+ const audioMediaSchema = mediaBaseSchema.extend({ type: z.literal("audio") });
3670
+ const documentMediaSchema = mediaBaseSchema.extend({ type: z.literal("document") });
3671
+ const spreadsheetMediaSchema = mediaBaseSchema.extend({ type: z.literal("spreadsheet") });
3672
+ const archiveMediaSchema = mediaBaseSchema.extend({ type: z.literal("archive") });
3673
+ const mediaSchema$1 = z.discriminatedUnion("type", [
3674
+ imageMediaSchema,
3675
+ videoMediaSchema,
3676
+ audioMediaSchema,
3677
+ documentMediaSchema,
3678
+ spreadsheetMediaSchema,
3679
+ archiveMediaSchema
3680
+ ]);
3681
+ const persistableMediaBaseSchema = mediaBaseSchema.extend({ identifier: mediaIdentifierSchema });
3682
+ z.discriminatedUnion("type", [
3683
+ persistableMediaBaseSchema.extend({ type: z.literal("image") }),
3684
+ persistableMediaBaseSchema.extend({ type: z.literal("video") }),
3685
+ persistableMediaBaseSchema.extend({ type: z.literal("audio") }),
3686
+ persistableMediaBaseSchema.extend({ type: z.literal("document") }),
3687
+ persistableMediaBaseSchema.extend({ type: z.literal("spreadsheet") }),
3688
+ persistableMediaBaseSchema.extend({ type: z.literal("archive") })
3689
+ ]);
3597
3690
  //#endregion
3598
3691
  //#region ../blocks/src/system/manifest/fieldValidation/index.ts
3599
3692
  const TEL_RE = /^[+()0-9\s-]{3,}$/;
@@ -3602,7 +3695,7 @@ const ALLOWED_URL_PROTOCOLS = ["http:", "https:"];
3602
3695
  const DATE_PATTERN = /^(?<year>[1-9]\d{3})-(?<month>\d{2})-(?<day>\d{2})$/;
3603
3696
  const TIME_PATTERN = /^(?<hours>[01]\d|2[0-3]):(?<minutes>[0-5]\d)$/;
3604
3697
  const 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)$/;
3605
- function assertNever$17(value) {
3698
+ function assertNever$16(value) {
3606
3699
  throw new Error(`Unhandled field validation variant: ${JSON.stringify(value)}`);
3607
3700
  }
3608
3701
  function validationContext(options = {}) {
@@ -3655,7 +3748,7 @@ function fieldIssueToMessage(issue) {
3655
3748
  case "invalidMedia": return `${issue.label} must be a media object with an identifier`;
3656
3749
  case "invalidLink": return `${issue.label} must be a valid link`;
3657
3750
  case "invalidReference": return `${issue.label} must reference a valid item`;
3658
- default: return assertNever$17(issue);
3751
+ default: return assertNever$16(issue);
3659
3752
  }
3660
3753
  }
3661
3754
  function pluralize(label, count) {
@@ -3775,7 +3868,7 @@ function deriveFieldValidationPlan(field, path = [field.id]) {
3775
3868
  case "presetOrCustom":
3776
3869
  case "contentTypeSelect":
3777
3870
  case "entryPicker": return makePlan("passthrough", "unknown", field, path, false, []);
3778
- default: return assertNever$17(field);
3871
+ default: return assertNever$16(field);
3779
3872
  }
3780
3873
  }
3781
3874
  function deriveFieldValidationPlans(fields, parentPath = []) {
@@ -3850,7 +3943,7 @@ function resolveSelectConstraintSource(field) {
3850
3943
  kind: "runtime",
3851
3944
  source: source.kind
3852
3945
  };
3853
- default: return assertNever$17(source);
3946
+ default: return assertNever$16(source);
3854
3947
  }
3855
3948
  }
3856
3949
  function normalizeStoredContentValues(plans, content, options = {}) {
@@ -3869,7 +3962,7 @@ function allGroupChildPlans(plan) {
3869
3962
  switch (plan.childSelection.kind) {
3870
3963
  case "all": return plan.childSelection.fields;
3871
3964
  case "discriminatedTabs": return plan.childSelection.tabs.flatMap((tab) => tab.fields);
3872
- default: return assertNever$17(plan.childSelection);
3965
+ default: return assertNever$16(plan.childSelection);
3873
3966
  }
3874
3967
  }
3875
3968
  function selectedGroupChildPlans(plan, value) {
@@ -3883,7 +3976,7 @@ function canonicalizeFieldValueForWrite(plan, value) {
3883
3976
  case "media": {
3884
3977
  if (!isPlainObject$5(value)) return value;
3885
3978
  const canonical = { ...value };
3886
- if (typeof canonical.identifier === "string" && canonical.identifier.trim().length > 0) deleteEnvSpecificKeys(canonical);
3979
+ if (mediaIdentifierSchema.safeParse(canonical.identifier).success) deleteEnvSpecificKeys(canonical);
3887
3980
  return canonical;
3888
3981
  }
3889
3982
  case "group": return canonicalizeObjectForWrite(selectedGroupChildPlans(plan, value), value);
@@ -3902,7 +3995,7 @@ function canonicalizeFieldValueForWrite(plan, value) {
3902
3995
  case "link":
3903
3996
  case "select":
3904
3997
  case "passthrough": return value;
3905
- default: return assertNever$17(plan);
3998
+ default: return assertNever$16(plan);
3906
3999
  }
3907
4000
  }
3908
4001
  function canonicalizeObjectForWrite(plans, value) {
@@ -3928,7 +4021,7 @@ function normalizeStoredFieldValueWithContext(plan, value, ctx) {
3928
4021
  case "link":
3929
4022
  case "select":
3930
4023
  case "passthrough": return normalizeFieldValue(plan, value, ctx);
3931
- default: return assertNever$17(plan);
4024
+ default: return assertNever$16(plan);
3932
4025
  }
3933
4026
  }
3934
4027
  function normalizeStoredObjectChildren(children, value, ctx) {
@@ -3965,7 +4058,7 @@ function normalizeFieldValue(plan, value, ctx) {
3965
4058
  case "select":
3966
4059
  case "passthrough": return value;
3967
4060
  case "media": return value;
3968
- default: return assertNever$17(plan);
4061
+ default: return assertNever$16(plan);
3969
4062
  }
3970
4063
  }
3971
4064
  function normalizeObjectChildren(children, value, ctx) {
@@ -3978,7 +4071,7 @@ function normalizeObjectChildren(children, value, ctx) {
3978
4071
  function normalizeInlineTextFallbacks(plans, values, ctx) {
3979
4072
  for (const plan of plans) {
3980
4073
  if (plan.kind !== "inlineText" || !plan.plainTextFallbackPath) continue;
3981
- if (!isMissingForPlan(plan, values[plan.fieldId])) continue;
4074
+ if (!isMissingForPlan(plan, values[plan.fieldId]) && !(ctx.allowIncomplete && !parseInlineTextFromUnknown(values[plan.fieldId]).ok)) continue;
3982
4075
  const fallback = getAtFieldPath(values, plan.plainTextFallbackPath);
3983
4076
  if (typeof fallback !== "string" || fallback.trim().length === 0) continue;
3984
4077
  values[plan.fieldId] = normalizeFieldValue(plan, plainTextToInlineText(fallback), ctx);
@@ -4019,12 +4112,12 @@ function validateNormalizedFieldValue(plan, value, ctx) {
4019
4112
  case "select": return validateSelectPlan(plan, value);
4020
4113
  case "richText": return isValidRichTextDoc(value) ? [] : [issue(plan, "invalidRichText")];
4021
4114
  case "inlineText": return validateInlineTextPlan(plan, value);
4022
- case "media": return isPlainObject$5(value) && typeof value.identifier === "string" && value.identifier.trim().length > 0 && (value.type === void 0 || typeof value.type === "string" && plan.allowedMediaTypes.includes(value.type)) ? [] : [issue(plan, "invalidMedia")];
4115
+ case "media": return isPlainObject$5(value) && mediaIdentifierSchema.safeParse(value.identifier).success && (value.type === void 0 || typeof value.type === "string" && plan.allowedMediaTypes.includes(value.type)) ? [] : [issue(plan, "invalidMedia")];
4023
4116
  case "link": return linkSchema.safeParse(value).success ? [] : [issue(plan, "invalidLink")];
4024
4117
  case "repeater": return validateRepeaterPlan(plan, value, ctx);
4025
4118
  case "group": return validateGroupPlan(plan, value, ctx);
4026
4119
  case "passthrough": return [];
4027
- default: return assertNever$17(plan);
4120
+ default: return assertNever$16(plan);
4028
4121
  }
4029
4122
  }
4030
4123
  function shouldRequireValue(plan, value, ctx) {
@@ -4066,7 +4159,7 @@ function validateStringConstraint(plan, constraint, value) {
4066
4159
  case "timeFormat": return typeof value === "string" && isValidTimeString(value) ? [] : [issue(plan, "invalidTime")];
4067
4160
  case "datetimeFormat": return typeof value === "string" && isValidDateTimeInstantString(value) ? [] : [issue(plan, "invalidDateTime")];
4068
4161
  case "slugFormat": return typeof value === "string" && SLUG_PATTERN.test(value) ? [] : [issue(plan, "invalidSlug")];
4069
- default: return assertNever$17(constraint);
4162
+ default: return assertNever$16(constraint);
4070
4163
  }
4071
4164
  }
4072
4165
  function isValidIconPickerValue(value) {
@@ -4085,7 +4178,7 @@ function validateNumberConstraint(plan, constraint, value) {
4085
4178
  case "numberType": return [];
4086
4179
  case "numberMin": return value < constraint.minimum ? [issue(plan, "tooSmall", { minimum: constraint.minimum })] : [];
4087
4180
  case "numberMax": return value > constraint.maximum ? [issue(plan, "tooLarge", { maximum: constraint.maximum })] : [];
4088
- default: return assertNever$17(constraint);
4181
+ default: return assertNever$16(constraint);
4089
4182
  }
4090
4183
  }
4091
4184
  function validateSelectPlan(plan, value) {
@@ -4107,7 +4200,7 @@ function validateRepeaterPlan(plan, value, ctx) {
4107
4200
  maximum: constraint.maximum,
4108
4201
  itemLabel: "item"
4109
4202
  })] : [];
4110
- default: return assertNever$17(constraint);
4203
+ default: return assertNever$16(constraint);
4111
4204
  }
4112
4205
  }), ...value.flatMap((item, index) => validateRepeaterItem(plan, item, index, ctx))];
4113
4206
  }
@@ -4198,7 +4291,7 @@ function rebaseFieldPlanPath(plan, fromPrefix, toPrefix) {
4198
4291
  ...plan,
4199
4292
  path
4200
4293
  };
4201
- default: return assertNever$17(plan);
4294
+ default: return assertNever$16(plan);
4202
4295
  }
4203
4296
  }
4204
4297
  function validateInlineTextPlan(plan, value) {
@@ -4245,7 +4338,7 @@ function fieldPlanToObjectPropertyZod(plan, options = {}) {
4245
4338
  switch (presence.kind) {
4246
4339
  case "required": return schema;
4247
4340
  case "optional": return schema.optional();
4248
- default: return assertNever$17(presence);
4341
+ default: return assertNever$16(presence);
4249
4342
  }
4250
4343
  }
4251
4344
  function addFieldIssueToZodContext(zodCtx, validationIssue, rootPath) {
@@ -4315,7 +4408,7 @@ function addFieldIssueToZodContext(zodCtx, validationIssue, rootPath) {
4315
4408
  message
4316
4409
  });
4317
4410
  return;
4318
- default: assertNever$17(validationIssue);
4411
+ default: assertNever$16(validationIssue);
4319
4412
  }
4320
4413
  }
4321
4414
  function relativeZodIssuePath(path, rootPath) {
@@ -4346,7 +4439,7 @@ function findNestedFieldValidationPlan(plan, path) {
4346
4439
  case "link":
4347
4440
  case "select":
4348
4441
  case "passthrough": return null;
4349
- default: return assertNever$17(plan);
4442
+ default: return assertNever$16(plan);
4350
4443
  }
4351
4444
  }
4352
4445
  function sameFieldPath(left, right) {
@@ -4370,7 +4463,7 @@ function validateExplicitNullForPushPlan(plan, value, ctx) {
4370
4463
  case "link":
4371
4464
  case "select":
4372
4465
  case "passthrough": return [];
4373
- default: return assertNever$17(plan);
4466
+ default: return assertNever$16(plan);
4374
4467
  }
4375
4468
  }
4376
4469
  function validateExplicitNullsForPushRepeater(plan, value, ctx) {
@@ -4738,6 +4831,17 @@ function asAccessibleSurfaceToken(token) {
4738
4831
  return token;
4739
4832
  }
4740
4833
  //#endregion
4834
+ //#region ../theme-core/src/site-styles/lookOptionGroups.ts
4835
+ function defineLookOptionGroup(group) {
4836
+ defaultOption(group);
4837
+ return group;
4838
+ }
4839
+ function defaultOption(group) {
4840
+ const option = group.options.find((candidate) => candidate.id === group.defaultOptionId);
4841
+ if (option) return option;
4842
+ throw new Error(`Look option group "${group.id}" defaults to missing option "${group.defaultOptionId}".`);
4843
+ }
4844
+ //#endregion
4741
4845
  //#region ../theme-core/src/site-styles/types.ts
4742
4846
  /**
4743
4847
  * Defines a literal-preserving catalog while rejecting top-level extra keys on
@@ -4790,7 +4894,7 @@ function asDesignSystemTemplateId(value) {
4790
4894
  function makeBoundaryId(previousBlockId, nextBlockId) {
4791
4895
  return asDesignBoundaryId(`boundary:${encodeURIComponent(previousBlockId)}:${encodeURIComponent(nextBlockId)}`);
4792
4896
  }
4793
- function assertNever$16(value, message = "Unhandled Theme V2 variant") {
4897
+ function assertNever$15(value, message = "Unhandled Theme V2 variant") {
4794
4898
  throw new Error(`${message}: ${String(value)}`);
4795
4899
  }
4796
4900
  function brandNonEmptyString(value, label) {
@@ -4883,767 +4987,655 @@ function defineBlockDesignCapability(capability) {
4883
4987
  //#region ../theme-core/src/site-styles/appearancePresetResolution.ts
4884
4988
  function assertValidOptionGroups(preset) {
4885
4989
  preset.optionGroups?.forEach((group) => {
4886
- if (!group.options.find((option) => option.id === group.selectedOptionId)) throw new Error(`Appearance preset "${preset.id}" option group "${group.id}" selects missing option "${group.selectedOptionId}".`);
4990
+ defineLookOptionGroup(group);
4887
4991
  });
4888
4992
  }
4889
4993
  function defineBlockAppearancePreset(preset) {
4890
4994
  assertValidOptionGroups(preset);
4891
4995
  return preset;
4892
4996
  }
4893
- [...[
4894
- defineBlockAppearancePreset({
4895
- kind: "block-design",
4896
- id: "hero-immersive-image",
4897
- target: "hero",
4898
- label: "Immersive image hero",
4899
- blockKinds: ["block.hero"],
4900
- constraints: { layoutFamilies: ["centered", "compact"] },
4901
- layoutPatches: [{
4902
- constraints: { layoutVariantKeys: ["micro"] },
4903
- designPatch: {
4904
- sectionHeight: "banner",
4905
- heroTypographyScale: "display"
4906
- }
4907
- }],
4908
- design: {
4909
- sectionSurface: "hero-image",
4910
- contentFrame: plainFrame,
4911
- itemSurface: "none",
4912
- sectionHeight: "hero",
4913
- heroComposition: "center",
4914
- heroTypographyScale: "display",
4915
- imageSurfaceTreatment: { kind: "neutral-wash" }
4997
+ //#endregion
4998
+ //#region ../theme-core/src/site-styles/blockAppearancePresets.ts
4999
+ const brandScrimOptionGroups = [{
5000
+ id: "image-surface-treatment",
5001
+ label: "Treatment",
5002
+ defaultOptionId: "brand-scrim-primary",
5003
+ options: [{
5004
+ id: "brand-scrim-primary",
5005
+ label: "Brand scrim",
5006
+ designPatch: { imageSurfaceTreatment: {
5007
+ kind: "brand-scrim",
5008
+ token: "primary"
5009
+ } }
5010
+ }, {
5011
+ id: "neutral-scrim",
5012
+ label: "Neutral scrim",
5013
+ designPatch: { imageSurfaceTreatment: { kind: "neutral-scrim" } }
5014
+ }]
5015
+ }];
5016
+ const microBannerLayoutPatches = [{
5017
+ constraints: { layoutVariantKeys: ["micro"] },
5018
+ designPatch: { sectionHeight: "banner" }
5019
+ }];
5020
+ defineBlockAppearancePreset({
5021
+ id: "hero-immersive-image",
5022
+ target: "hero",
5023
+ label: "Immersive image hero",
5024
+ blockKinds: ["block.hero"],
5025
+ constraints: { layoutFamilies: ["centered", "compact"] },
5026
+ layoutPatches: [{
5027
+ constraints: { layoutVariantKeys: ["micro"] },
5028
+ designPatch: {
5029
+ sectionHeight: "banner",
5030
+ heroTypographyScale: "display"
4916
5031
  }
4917
- }),
4918
- defineBlockAppearancePreset({
4919
- kind: "block-design",
4920
- id: "hero-bottom-left-panel",
4921
- target: "hero",
4922
- label: "Bottom-left panel hero",
4923
- blockKinds: ["block.hero"],
4924
- constraints: { layoutFamilies: ["centered", "compact"] },
4925
- optionGroups: [{
4926
- id: "image-surface-treatment",
4927
- label: "Treatment",
4928
- selectedOptionId: "neutral-scrim",
4929
- options: [{
4930
- id: "neutral-scrim",
4931
- label: "Neutral scrim",
4932
- designPatch: { imageSurfaceTreatment: {
4933
- kind: "neutral-scrim",
4934
- intensity: "balanced"
4935
- } }
4936
- }, {
4937
- id: "brand-scrim-primary",
4938
- label: "Brand scrim",
4939
- designPatch: { imageSurfaceTreatment: {
4940
- kind: "brand-scrim",
4941
- token: "primary",
4942
- intensity: "balanced"
4943
- } }
4944
- }]
4945
- }],
4946
- layoutPatches: [{
4947
- constraints: { layoutVariantKeys: ["micro"] },
4948
- designPatch: {
4949
- sectionHeight: "banner",
4950
- heroTypographyScale: "editorial"
4951
- }
4952
- }],
4953
- design: {
4954
- sectionSurface: "hero-image",
4955
- contentFrame: panelFrame("raised"),
4956
- itemSurface: "none",
4957
- sectionHeight: "immersive",
4958
- heroComposition: "bottom-left",
4959
- heroTypographyScale: "display",
4960
- imageSurfaceTreatment: {
5032
+ }],
5033
+ design: {
5034
+ sectionSurface: "hero-image",
5035
+ contentFrame: plainFrame,
5036
+ itemSurface: "none",
5037
+ sectionHeight: "hero",
5038
+ heroComposition: "center",
5039
+ heroTypographyScale: "display",
5040
+ imageSurfaceTreatment: { kind: "neutral-wash" }
5041
+ }
5042
+ }), defineBlockAppearancePreset({
5043
+ id: "hero-bottom-left-panel",
5044
+ target: "hero",
5045
+ label: "Bottom-left panel hero",
5046
+ blockKinds: ["block.hero"],
5047
+ constraints: { layoutFamilies: ["centered", "compact"] },
5048
+ optionGroups: [{
5049
+ id: "image-surface-treatment",
5050
+ label: "Treatment",
5051
+ defaultOptionId: "neutral-scrim",
5052
+ options: [{
5053
+ id: "neutral-scrim",
5054
+ label: "Neutral scrim",
5055
+ designPatch: { imageSurfaceTreatment: {
4961
5056
  kind: "neutral-scrim",
4962
5057
  intensity: "balanced"
4963
- }
4964
- }
4965
- }),
4966
- defineBlockAppearancePreset({
4967
- kind: "block-design",
4968
- id: "hero-poster-image",
4969
- target: "hero",
4970
- label: "Poster image hero",
4971
- blockKinds: ["block.hero"],
4972
- constraints: { layoutFamilies: ["centered", "compact"] },
4973
- layoutPatches: [{
4974
- constraints: { layoutVariantKeys: ["micro"] },
4975
- designPatch: {
4976
- sectionHeight: "banner",
4977
- heroTypographyScale: "display"
4978
- }
4979
- }],
4980
- design: {
4981
- sectionSurface: "hero-image",
4982
- contentFrame: plainFrame,
4983
- itemSurface: "none",
4984
- sectionHeight: "immersive",
4985
- heroComposition: "center",
4986
- heroTypographyScale: "poster",
4987
- imageSurfaceTreatment: {
5058
+ } }
5059
+ }, {
5060
+ id: "brand-scrim-primary",
5061
+ label: "Brand scrim",
5062
+ designPatch: { imageSurfaceTreatment: {
4988
5063
  kind: "brand-scrim",
4989
5064
  token: "primary",
4990
- intensity: "strong"
4991
- }
4992
- }
4993
- }),
4994
- defineBlockAppearancePreset({
4995
- kind: "block-design",
4996
- id: "hero-brand-scrim",
4997
- target: "hero",
4998
- label: "Brand scrim image hero",
4999
- blockKinds: ["block.hero"],
5000
- constraints: { layoutFamilies: ["centered", "compact"] },
5001
- optionGroups: [{
5002
- id: "image-surface-treatment",
5003
- label: "Treatment",
5004
- selectedOptionId: "brand-scrim-primary",
5005
- options: [{
5006
- id: "brand-scrim-primary",
5007
- label: "Brand scrim",
5008
- designPatch: { imageSurfaceTreatment: {
5009
- kind: "brand-scrim",
5010
- token: "primary"
5011
- } }
5012
- }, {
5013
- id: "neutral-scrim",
5014
- label: "Neutral scrim",
5015
- designPatch: { imageSurfaceTreatment: { kind: "neutral-scrim" } }
5016
- }]
5017
- }],
5018
- layoutPatches: [{
5019
- constraints: { layoutVariantKeys: ["micro"] },
5020
- designPatch: { sectionHeight: "banner" }
5021
- }],
5022
- design: {
5023
- sectionSurface: "hero-image",
5024
- contentFrame: plainFrame,
5025
- itemSurface: "none",
5026
- sectionHeight: "immersive",
5027
- heroComposition: "center",
5028
- heroTypographyScale: "display",
5029
- imageSurfaceTreatment: {
5030
- kind: "brand-scrim",
5031
- token: "primary"
5032
- }
5033
- }
5034
- }),
5035
- defineBlockAppearancePreset({
5036
- kind: "block-design",
5037
- id: "hero-brand-scrim-fixed-frame",
5038
- target: "hero",
5039
- label: "Fixed-frame brand scrim hero",
5040
- blockKinds: ["block.hero"],
5041
- constraints: { layoutFamilies: ["centered", "compact"] },
5042
- optionGroups: [{
5043
- id: "image-surface-treatment",
5044
- label: "Treatment",
5045
- selectedOptionId: "brand-scrim-primary",
5046
- options: [{
5047
- id: "brand-scrim-primary",
5048
- label: "Brand scrim",
5049
- designPatch: { imageSurfaceTreatment: {
5050
- kind: "brand-scrim",
5051
- token: "primary"
5052
- } }
5053
- }, {
5054
- id: "neutral-scrim",
5055
- label: "Neutral scrim",
5056
- designPatch: { imageSurfaceTreatment: { kind: "neutral-scrim" } }
5057
- }]
5058
- }],
5059
- layoutPatches: [{
5060
- constraints: { layoutVariantKeys: ["micro"] },
5061
- designPatch: { sectionHeight: "banner" }
5062
- }],
5063
- design: {
5064
- sectionSurface: "hero-image",
5065
- contentFrame: plainFrame,
5066
- itemSurface: "none",
5067
- sectionHeight: "immersive",
5068
- heroComposition: "center",
5069
- heroTypographyScale: "display",
5070
- imageSurfaceTreatment: {
5071
- kind: "brand-scrim",
5072
- token: "primary"
5073
- },
5074
- imageSurfaceMotion: "fixed-frame",
5075
- eyebrowTreatment: "accent-pill-bounce"
5076
- }
5077
- }),
5078
- defineBlockAppearancePreset({
5079
- kind: "block-design",
5080
- id: "hero-brand-depth-expressive",
5081
- target: "hero",
5082
- label: "Expressive brand-depth hero",
5083
- blockKinds: ["block.hero"],
5084
- constraints: { layoutFamilies: ["centered", "compact"] },
5085
- design: {
5086
- sectionSurface: "brand-depth-band",
5087
- contentFrame: plainFrame,
5088
- itemSurface: "none",
5089
- heroComposition: "center",
5090
- heroTypographyScale: "editorial",
5091
- eyebrowTreatment: "accent-pill-bounce"
5092
- }
5093
- }),
5094
- defineBlockAppearancePreset({
5095
- kind: "block-design",
5096
- id: "hero-contained-intro",
5097
- target: "hero",
5098
- label: "Contained intro hero",
5099
- blockKinds: ["block.hero"],
5100
- design: {
5101
- sectionSurface: "muted-band",
5102
- contentFrame: panelFrame("inset"),
5103
- itemSurface: "none",
5104
- heroComposition: "center",
5105
- heroTypographyScale: "editorial"
5106
- }
5107
- }),
5108
- defineBlockAppearancePreset({
5109
- kind: "block-design",
5110
- id: "hero-split-editorial",
5111
- target: "hero",
5112
- label: "Editorial split hero",
5113
- blockKinds: ["block.hero"],
5114
- constraints: { layoutFamilies: ["split"] },
5115
- design: {
5116
- sectionSurface: "base",
5117
- contentFrame: plainFrame,
5118
- itemSurface: "none",
5119
- heroTypographyScale: "editorial"
5120
- }
5121
- }),
5122
- defineBlockAppearancePreset({
5123
- kind: "block-design",
5124
- id: "hero-split-brand",
5125
- target: "hero",
5126
- label: "Brand split hero",
5127
- blockKinds: ["block.hero"],
5128
- constraints: { layoutFamilies: ["split"] },
5129
- design: {
5130
- sectionSurface: "brand-depth-band",
5131
- contentFrame: plainFrame,
5132
- itemSurface: "none",
5133
- heroTypographyScale: "display",
5134
- eyebrowTreatment: "accent-pill-bounce"
5135
- }
5136
- }),
5137
- defineBlockAppearancePreset({
5138
- kind: "block-design",
5139
- id: "hero-split-soft-panel",
5140
- target: "hero",
5141
- label: "Soft panel split hero",
5142
- blockKinds: ["block.hero"],
5143
- constraints: { layoutFamilies: ["split"] },
5144
- design: {
5145
- sectionSurface: "muted-band",
5146
- contentFrame: panelFrame("raised"),
5147
- itemSurface: "none",
5065
+ intensity: "balanced"
5066
+ } }
5067
+ }]
5068
+ }],
5069
+ layoutPatches: [{
5070
+ constraints: { layoutVariantKeys: ["micro"] },
5071
+ designPatch: {
5072
+ sectionHeight: "banner",
5148
5073
  heroTypographyScale: "editorial"
5149
5074
  }
5150
- }),
5151
- defineBlockAppearancePreset({
5152
- kind: "block-design",
5153
- id: "hero-split-accent",
5154
- target: "hero",
5155
- label: "Accent split hero",
5156
- blockKinds: ["block.hero"],
5157
- constraints: { layoutFamilies: ["split"] },
5158
- design: {
5159
- sectionSurface: "accent-band",
5160
- contentFrame: panelFrame("raised"),
5161
- itemSurface: "none",
5075
+ }],
5076
+ design: {
5077
+ sectionSurface: "hero-image",
5078
+ contentFrame: panelFrame("raised"),
5079
+ itemSurface: "none",
5080
+ sectionHeight: "immersive",
5081
+ heroComposition: "bottom-left",
5082
+ heroTypographyScale: "display",
5083
+ imageSurfaceTreatment: {
5084
+ kind: "neutral-scrim",
5085
+ intensity: "balanced"
5086
+ }
5087
+ }
5088
+ }), defineBlockAppearancePreset({
5089
+ id: "hero-poster-image",
5090
+ target: "hero",
5091
+ label: "Poster image hero",
5092
+ blockKinds: ["block.hero"],
5093
+ constraints: { layoutFamilies: ["centered", "compact"] },
5094
+ layoutPatches: [{
5095
+ constraints: { layoutVariantKeys: ["micro"] },
5096
+ designPatch: {
5097
+ sectionHeight: "banner",
5162
5098
  heroTypographyScale: "display"
5163
5099
  }
5164
- }),
5165
- defineBlockAppearancePreset({
5166
- kind: "block-design",
5167
- id: "intro-editorial-statement",
5168
- target: "intro",
5169
- label: "Editorial intro statement",
5170
- blockKinds: ["block.intro"],
5171
- constraints: { layoutVariantKeys: ["centered-copy", "statement-copy"] },
5172
- design: {
5173
- sectionSurface: "base",
5174
- contentFrame: plainFrame,
5175
- itemSurface: "none",
5176
- composition: {
5177
- kind: "intro",
5178
- treatment: "editorial-statement"
5179
- }
5180
- }
5181
- }),
5182
- defineBlockAppearancePreset({
5183
- kind: "block-design",
5184
- id: "intro-portrait-bio",
5185
- target: "intro",
5186
- label: "Portrait and bio",
5187
- blockKinds: ["block.intro"],
5188
- constraints: { layoutVariantKeys: ["media-copy"] },
5189
- design: {
5190
- sectionSurface: "base",
5191
- contentFrame: plainFrame,
5192
- itemSurface: "none",
5193
- composition: {
5194
- kind: "intro",
5195
- treatment: "portrait-bio"
5196
- }
5197
- }
5198
- }),
5199
- defineBlockAppearancePreset({
5200
- kind: "block-design",
5201
- id: "offerings-preview-default-cards",
5202
- target: "offerings",
5203
- label: "Default offering cards",
5204
- blockKinds: ["block.offerings-preview"],
5205
- design: {
5206
- sectionSurface: "base",
5207
- contentFrame: plainFrame,
5208
- itemSurface: "default"
5209
- }
5210
- }),
5211
- defineBlockAppearancePreset({
5212
- kind: "block-design",
5213
- id: "offerings-preview-secondary-cards",
5214
- target: "offerings",
5215
- label: "Secondary offering cards",
5216
- blockKinds: ["block.offerings-preview"],
5217
- design: {
5218
- sectionSurface: "muted-band",
5219
- contentFrame: plainFrame,
5220
- itemSurface: "inset"
5221
- }
5222
- }),
5223
- defineBlockAppearancePreset({
5224
- kind: "block-design",
5225
- id: "offerings-preview-non-carded",
5226
- target: "offerings",
5227
- label: "Non-carded offerings",
5228
- blockKinds: ["block.offerings-preview"],
5229
- design: {
5230
- sectionSurface: "muted-band",
5231
- contentFrame: plainFrame,
5232
- itemSurface: "editorial"
5233
- }
5234
- }),
5235
- defineBlockAppearancePreset({
5236
- kind: "block-design",
5237
- id: "offerings-preview-paired-feature-cards",
5238
- target: "offerings",
5239
- label: "Paired feature cards",
5240
- blockKinds: ["block.offerings-preview"],
5241
- constraints: { layoutVariantKeys: ["cards"] },
5242
- design: {
5243
- sectionSurface: "base",
5244
- contentFrame: plainFrame,
5245
- itemSurface: "none"
5246
- }
5247
- }),
5248
- defineBlockAppearancePreset({
5249
- kind: "block-design",
5250
- id: "offerings-preview-open-editorial-columns",
5251
- target: "offerings",
5252
- label: "Open editorial columns",
5253
- blockKinds: ["block.offerings-preview"],
5254
- constraints: { layoutVariantKeys: ["cards"] },
5255
- design: {
5256
- sectionSurface: "base",
5257
- contentFrame: plainFrame,
5258
- itemSurface: "none"
5259
- }
5260
- }),
5261
- defineBlockAppearancePreset({
5262
- kind: "block-design",
5263
- id: "offerings-preview-joined-programme-panel",
5264
- target: "offerings",
5265
- label: "Joined programme panel",
5266
- blockKinds: ["block.offerings-preview"],
5267
- constraints: { layoutVariantKeys: ["cards"] },
5268
- design: {
5269
- sectionSurface: "base",
5270
- contentFrame: plainFrame,
5271
- itemSurface: "none"
5272
- }
5273
- }),
5274
- defineBlockAppearancePreset({
5275
- kind: "block-design",
5276
- id: "feature-cards-raised-rule",
5277
- target: "feature-cards",
5278
- label: "Raised cards with rule",
5279
- blockKinds: ["block.feature-cards"],
5280
- design: {
5281
- sectionSurface: "base",
5282
- contentFrame: plainFrame,
5283
- itemSurface: "raised"
5284
- }
5285
- }),
5286
- defineBlockAppearancePreset({
5287
- kind: "block-design",
5288
- id: "feature-cards-bold-colors",
5289
- target: "feature-cards",
5290
- label: "Bold colour-blocked cards",
5291
- blockKinds: ["block.feature-cards"],
5292
- design: {
5293
- sectionSurface: "base",
5294
- contentFrame: plainFrame,
5295
- itemSurface: "color-blocked"
5296
- }
5297
- }),
5298
- defineBlockAppearancePreset({
5299
- kind: "block-design",
5300
- id: "feature-cards-editorial-columns",
5301
- target: "feature-cards",
5302
- label: "Editorial open columns",
5303
- blockKinds: ["block.feature-cards"],
5304
- design: {
5305
- sectionSurface: "base",
5306
- contentFrame: plainFrame,
5307
- itemSurface: "editorial"
5308
- }
5309
- }),
5310
- defineBlockAppearancePreset({
5311
- kind: "block-design",
5312
- id: "feature-cards-asymmetric-emphasis",
5313
- target: "feature-cards",
5314
- label: "Asymmetric emphasis pair",
5315
- blockKinds: ["block.feature-cards"],
5316
- constraints: { layoutFamilies: ["grid"] },
5317
- design: {
5318
- sectionSurface: "base",
5319
- contentFrame: plainFrame,
5320
- itemSurface: "none",
5321
- composition: {
5322
- kind: "feature-cards",
5323
- treatment: "asymmetric-emphasis"
5324
- }
5325
- }
5326
- }),
5327
- defineBlockAppearancePreset({
5328
- kind: "block-design",
5329
- id: "feature-cards-framed-programme",
5330
- target: "feature-cards",
5331
- label: "Framed programme cards",
5332
- blockKinds: ["block.feature-cards"],
5333
- constraints: { layoutFamilies: ["grid"] },
5334
- design: {
5335
- sectionSurface: "brand-depth-band",
5336
- contentFrame: plainFrame,
5337
- itemSurface: "inset",
5338
- composition: {
5339
- kind: "feature-cards",
5340
- treatment: "framed-programme"
5341
- }
5342
- }
5343
- }),
5344
- defineBlockAppearancePreset({
5345
- kind: "block-design",
5346
- id: "feature-cards-soft-panels",
5347
- target: "feature-cards",
5348
- label: "Soft tinted panels",
5349
- blockKinds: ["block.feature-cards"],
5350
- design: {
5351
- sectionSurface: "base",
5352
- contentFrame: plainFrame,
5353
- itemSurface: "inset"
5354
- }
5355
- }),
5356
- defineBlockAppearancePreset({
5357
- kind: "block-design",
5358
- id: "feature-cards-editorial-diptych",
5359
- target: "feature-cards",
5360
- label: "Editorial diptych",
5361
- blockKinds: ["block.feature-cards"],
5362
- constraints: { layoutVariantKeys: ["editorial-diptych"] },
5363
- design: {
5364
- sectionSurface: "base",
5365
- contentFrame: plainFrame,
5366
- itemSurface: "flat"
5367
- }
5368
- }),
5369
- defineBlockAppearancePreset({
5370
- kind: "block-design",
5371
- id: "feature-cards-editorial-pathways",
5372
- target: "feature-cards",
5373
- label: "Editorial pathways",
5374
- blockKinds: ["block.feature-cards"],
5375
- constraints: { layoutVariantKeys: ["editorial-pathways"] },
5376
- design: {
5377
- sectionSurface: "base",
5378
- contentFrame: plainFrame,
5379
- itemSurface: "flat"
5380
- }
5381
- }),
5382
- defineBlockAppearancePreset({
5383
- kind: "block-design",
5384
- id: "feature-cards-photo-tiles",
5385
- target: "feature-cards",
5386
- label: "Photo tiles",
5387
- blockKinds: ["block.feature-cards"],
5388
- design: {
5389
- sectionSurface: "base",
5390
- contentFrame: plainFrame,
5391
- itemSurface: "raised"
5392
- }
5393
- }),
5394
- defineBlockAppearancePreset({
5395
- kind: "block-design",
5396
- id: "events-lined-panel",
5397
- target: "events",
5398
- label: "Raised event panel",
5399
- blockKinds: ["block.event-calendar", "block.event-listing"],
5400
- design: {
5401
- sectionSurface: "base",
5402
- contentFrame: panelFrame("raised"),
5403
- itemSurface: "none"
5404
- }
5405
- }),
5406
- defineBlockAppearancePreset({
5407
- kind: "block-design",
5408
- id: "events-ruled-register",
5409
- target: "events",
5410
- label: "Ruled event register",
5411
- blockKinds: ["block.event-calendar", "block.event-listing"],
5412
- design: {
5413
- sectionSurface: "brand-depth-band",
5414
- contentFrame: plainFrame,
5415
- itemSurface: "none",
5416
- eventListTreatment: "ruled-register"
5417
- }
5418
- }),
5419
- defineBlockAppearancePreset({
5420
- kind: "block-design",
5421
- id: "events-editorial-register",
5422
- target: "events",
5423
- label: "Editorial event register",
5424
- blockKinds: ["block.event-calendar", "block.event-listing"],
5425
- design: {
5426
- sectionSurface: "base",
5427
- contentFrame: plainFrame,
5428
- itemSurface: "none",
5429
- eventListTreatment: "editorial-register"
5430
- }
5431
- }),
5432
- defineBlockAppearancePreset({
5433
- kind: "block-design",
5434
- id: "events-dense-index",
5435
- target: "events",
5436
- label: "Dense event index",
5437
- blockKinds: ["block.event-calendar", "block.event-listing"],
5438
- design: {
5439
- sectionSurface: "accent-band",
5440
- contentFrame: plainFrame,
5441
- itemSurface: "none",
5442
- eventListTreatment: "dense-index"
5443
- }
5444
- }),
5445
- defineBlockAppearancePreset({
5446
- kind: "block-design",
5447
- id: "schedule-details-brand-depth",
5448
- target: "events",
5449
- label: "Brand-depth schedule details",
5450
- blockKinds: ["block.event-details", "block.course-details"],
5451
- design: {
5452
- sectionSurface: "brand-depth-band",
5453
- contentFrame: plainFrame,
5454
- itemSurface: "none",
5455
- tileTreatment: "brand-depth"
5456
- }
5457
- }),
5458
- defineBlockAppearancePreset({
5459
- kind: "block-design",
5460
- id: "media-text-flush-feature",
5461
- target: "media-text",
5462
- label: "Flush media feature",
5463
- blockKinds: ["block.media-text"],
5464
- design: {
5465
- sectionSurface: "muted-band",
5466
- contentFrame: flushPanelFrame({ bleed: "start" }),
5467
- itemSurface: "none"
5468
- }
5469
- }),
5470
- defineBlockAppearancePreset({
5471
- kind: "block-design",
5472
- id: "testimonials-simple-cards",
5473
- target: "testimonials",
5474
- label: "Simple testimonial cards",
5475
- blockKinds: ["block.testimonials"],
5476
- design: {
5477
- sectionSurface: "base",
5478
- contentFrame: plainFrame,
5479
- itemSurface: "default"
5480
- }
5481
- }),
5482
- defineBlockAppearancePreset({
5483
- kind: "block-design",
5484
- id: "testimonials-raised-panel",
5485
- target: "testimonials",
5486
- label: "Raised testimonial panel",
5487
- blockKinds: ["block.testimonials"],
5488
- design: {
5489
- sectionSurface: "muted-band",
5490
- contentFrame: panelFrame("raised"),
5491
- itemSurface: "raised"
5492
- }
5493
- }),
5494
- defineBlockAppearancePreset({
5495
- kind: "block-design",
5496
- id: "testimonials-accent-panel",
5497
- target: "testimonials",
5498
- label: "Accent testimonial panel",
5499
- blockKinds: ["block.testimonials"],
5500
- design: {
5501
- sectionSurface: "accent-band",
5502
- contentFrame: panelFrame("raised"),
5503
- itemSurface: "raised"
5504
- }
5505
- }),
5506
- defineBlockAppearancePreset({
5507
- kind: "block-design",
5508
- id: "testimonials-default-cards",
5509
- target: "testimonials",
5510
- label: "Default cards",
5511
- blockKinds: ["block.testimonials"],
5512
- design: {
5513
- sectionSurface: "base",
5514
- contentFrame: plainFrame,
5515
- itemSurface: "none",
5516
- testimonialCardTreatment: "default"
5517
- }
5518
- }),
5519
- defineBlockAppearancePreset({
5520
- kind: "block-design",
5521
- id: "testimonials-statement-cards",
5522
- target: "testimonials",
5523
- label: "Statement cards",
5524
- blockKinds: ["block.testimonials"],
5525
- design: {
5526
- sectionSurface: "accent-band",
5527
- contentFrame: plainFrame,
5528
- itemSurface: "raised",
5529
- testimonialCardTreatment: "statement"
5530
- }
5531
- }),
5532
- defineBlockAppearancePreset({
5533
- kind: "block-design",
5534
- id: "testimonials-brand-statement-cards",
5535
- target: "testimonials",
5536
- label: "Brand statement cards",
5537
- blockKinds: ["block.testimonials"],
5538
- design: {
5539
- sectionSurface: "brand-depth-band",
5540
- contentFrame: plainFrame,
5541
- itemSurface: "raised",
5542
- testimonialCardTreatment: "statement"
5543
- }
5544
- }),
5545
- defineBlockAppearancePreset({
5546
- kind: "block-design",
5547
- id: "testimonials-non-carded",
5548
- target: "testimonials",
5549
- label: "Non-carded",
5550
- blockKinds: ["block.testimonials"],
5551
- design: {
5552
- sectionSurface: "muted-band",
5553
- contentFrame: plainFrame,
5554
- itemSurface: "none",
5555
- testimonialCardTreatment: "non-carded"
5556
- }
5557
- }),
5558
- defineBlockAppearancePreset({
5559
- kind: "block-design",
5560
- id: "testimonials-evergreen-lead",
5561
- target: "testimonials",
5562
- label: "Evergreen lead",
5563
- blockKinds: ["block.testimonials"],
5564
- constraints: { layoutVariantKeys: ["featured-editorial"] },
5565
- design: {
5566
- sectionSurface: "base",
5567
- contentFrame: plainFrame,
5568
- itemSurface: "none"
5569
- }
5570
- }),
5571
- defineBlockAppearancePreset({
5572
- kind: "block-design",
5573
- id: "testimonials-room-and-response",
5574
- target: "testimonials",
5575
- label: "Room and response",
5576
- blockKinds: ["block.testimonials"],
5577
- constraints: { layoutVariantKeys: ["featured-editorial"] },
5578
- design: {
5579
- sectionSurface: "base",
5580
- contentFrame: plainFrame,
5581
- itemSurface: "none"
5582
- }
5583
- }),
5584
- defineBlockAppearancePreset({
5585
- kind: "block-design",
5586
- id: "testimonials-open-floor",
5587
- target: "testimonials",
5588
- label: "Open floor",
5589
- blockKinds: ["block.testimonials"],
5590
- constraints: { layoutVariantKeys: ["featured-editorial"] },
5591
- design: {
5592
- sectionSurface: "base",
5593
- contentFrame: plainFrame,
5594
- itemSurface: "none"
5595
- }
5596
- }),
5597
- defineBlockAppearancePreset({
5598
- kind: "block-design",
5599
- id: "faq-base-accordion",
5600
- target: "faq",
5601
- label: "Base accordion FAQ",
5602
- blockKinds: ["block.faq"],
5603
- design: {
5604
- sectionSurface: "base",
5605
- contentFrame: plainFrame,
5606
- itemSurface: "default"
5607
- }
5608
- }),
5609
- defineBlockAppearancePreset({
5610
- kind: "block-design",
5611
- id: "faq-contained-help",
5612
- target: "faq",
5613
- label: "Contained help panel",
5614
- blockKinds: ["block.faq"],
5615
- design: {
5616
- sectionSurface: "muted-band",
5617
- contentFrame: panelFrame("inset"),
5618
- itemSurface: "default"
5619
- }
5620
- }),
5621
- defineBlockAppearancePreset({
5622
- kind: "block-design",
5623
- id: "contact-form-panel",
5624
- target: "contact-form",
5625
- label: "Raised form panel",
5626
- blockKinds: ["block.form"],
5627
- design: {
5628
- sectionSurface: "muted-band",
5629
- contentFrame: panelFrame("raised"),
5630
- itemSurface: "none"
5631
- }
5632
- }),
5633
- defineBlockAppearancePreset({
5634
- kind: "block-design",
5635
- id: "cta-accent-band",
5636
- target: "cta",
5637
- label: "Accent CTA band",
5638
- blockKinds: ["block.cta-full"],
5639
- design: {
5640
- sectionSurface: "accent-band",
5641
- contentFrame: plainFrame,
5642
- itemSurface: "none",
5643
- eyebrowTreatment: "accent"
5644
- }
5645
- })
5646
- ]];
5100
+ }],
5101
+ design: {
5102
+ sectionSurface: "hero-image",
5103
+ contentFrame: plainFrame,
5104
+ itemSurface: "none",
5105
+ sectionHeight: "immersive",
5106
+ heroComposition: "center",
5107
+ heroTypographyScale: "poster",
5108
+ imageSurfaceTreatment: {
5109
+ kind: "brand-scrim",
5110
+ token: "primary",
5111
+ intensity: "strong"
5112
+ }
5113
+ }
5114
+ }), defineBlockAppearancePreset({
5115
+ id: "hero-brand-scrim",
5116
+ target: "hero",
5117
+ label: "Brand scrim image hero",
5118
+ blockKinds: ["block.hero"],
5119
+ constraints: { layoutFamilies: ["centered", "compact"] },
5120
+ optionGroups: brandScrimOptionGroups,
5121
+ layoutPatches: microBannerLayoutPatches,
5122
+ design: {
5123
+ sectionSurface: "hero-image",
5124
+ contentFrame: plainFrame,
5125
+ itemSurface: "none",
5126
+ sectionHeight: "immersive",
5127
+ heroComposition: "center",
5128
+ heroTypographyScale: "display",
5129
+ imageSurfaceTreatment: {
5130
+ kind: "brand-scrim",
5131
+ token: "primary"
5132
+ }
5133
+ }
5134
+ }), defineBlockAppearancePreset({
5135
+ id: "hero-brand-scrim-fixed-frame",
5136
+ target: "hero",
5137
+ label: "Fixed-frame brand scrim hero",
5138
+ blockKinds: ["block.hero"],
5139
+ constraints: { layoutFamilies: ["centered", "compact"] },
5140
+ optionGroups: brandScrimOptionGroups,
5141
+ layoutPatches: microBannerLayoutPatches,
5142
+ design: {
5143
+ sectionSurface: "hero-image",
5144
+ contentFrame: plainFrame,
5145
+ itemSurface: "none",
5146
+ sectionHeight: "immersive",
5147
+ heroComposition: "center",
5148
+ heroTypographyScale: "display",
5149
+ imageSurfaceTreatment: {
5150
+ kind: "brand-scrim",
5151
+ token: "primary"
5152
+ },
5153
+ imageSurfaceMotion: "fixed-frame",
5154
+ eyebrowTreatment: "accent-pill-bounce"
5155
+ }
5156
+ }), defineBlockAppearancePreset({
5157
+ id: "hero-brand-depth-expressive",
5158
+ target: "hero",
5159
+ label: "Expressive brand-depth hero",
5160
+ blockKinds: ["block.hero"],
5161
+ constraints: { layoutFamilies: ["centered", "compact"] },
5162
+ design: {
5163
+ sectionSurface: "brand-depth-band",
5164
+ contentFrame: plainFrame,
5165
+ itemSurface: "none",
5166
+ heroComposition: "center",
5167
+ heroTypographyScale: "editorial",
5168
+ eyebrowTreatment: "accent-pill-bounce"
5169
+ }
5170
+ }), defineBlockAppearancePreset({
5171
+ id: "hero-contained-intro",
5172
+ target: "hero",
5173
+ label: "Contained intro hero",
5174
+ blockKinds: ["block.hero"],
5175
+ design: {
5176
+ sectionSurface: "muted-band",
5177
+ contentFrame: panelFrame("inset"),
5178
+ itemSurface: "none",
5179
+ heroComposition: "center",
5180
+ heroTypographyScale: "editorial"
5181
+ }
5182
+ }), defineBlockAppearancePreset({
5183
+ id: "hero-split-editorial",
5184
+ target: "hero",
5185
+ label: "Editorial split hero",
5186
+ blockKinds: ["block.hero"],
5187
+ constraints: { layoutFamilies: ["split"] },
5188
+ design: {
5189
+ sectionSurface: "base",
5190
+ contentFrame: plainFrame,
5191
+ itemSurface: "none",
5192
+ heroTypographyScale: "editorial"
5193
+ }
5194
+ }), defineBlockAppearancePreset({
5195
+ id: "hero-split-brand",
5196
+ target: "hero",
5197
+ label: "Brand split hero",
5198
+ blockKinds: ["block.hero"],
5199
+ constraints: { layoutFamilies: ["split"] },
5200
+ design: {
5201
+ sectionSurface: "brand-depth-band",
5202
+ contentFrame: plainFrame,
5203
+ itemSurface: "none",
5204
+ heroTypographyScale: "display",
5205
+ eyebrowTreatment: "accent-pill-bounce"
5206
+ }
5207
+ }), defineBlockAppearancePreset({
5208
+ id: "hero-split-soft-panel",
5209
+ target: "hero",
5210
+ label: "Soft panel split hero",
5211
+ blockKinds: ["block.hero"],
5212
+ constraints: { layoutFamilies: ["split"] },
5213
+ design: {
5214
+ sectionSurface: "muted-band",
5215
+ contentFrame: panelFrame("raised"),
5216
+ itemSurface: "none",
5217
+ heroTypographyScale: "editorial"
5218
+ }
5219
+ }), defineBlockAppearancePreset({
5220
+ id: "hero-split-accent",
5221
+ target: "hero",
5222
+ label: "Accent split hero",
5223
+ blockKinds: ["block.hero"],
5224
+ constraints: { layoutFamilies: ["split"] },
5225
+ design: {
5226
+ sectionSurface: "accent-band",
5227
+ contentFrame: panelFrame("raised"),
5228
+ itemSurface: "none",
5229
+ heroTypographyScale: "display"
5230
+ }
5231
+ }), defineBlockAppearancePreset({
5232
+ id: "intro-editorial-statement",
5233
+ target: "intro",
5234
+ label: "Editorial intro statement",
5235
+ blockKinds: ["block.intro"],
5236
+ constraints: { layoutVariantKeys: ["centered-copy", "statement-copy"] },
5237
+ design: {
5238
+ sectionSurface: "base",
5239
+ contentFrame: plainFrame,
5240
+ itemSurface: "none",
5241
+ composition: {
5242
+ kind: "intro",
5243
+ treatment: "editorial-statement"
5244
+ }
5245
+ }
5246
+ }), defineBlockAppearancePreset({
5247
+ id: "intro-portrait-bio",
5248
+ target: "intro",
5249
+ label: "Portrait and bio",
5250
+ blockKinds: ["block.intro"],
5251
+ constraints: { layoutVariantKeys: ["media-copy"] },
5252
+ design: {
5253
+ sectionSurface: "base",
5254
+ contentFrame: plainFrame,
5255
+ itemSurface: "none",
5256
+ composition: {
5257
+ kind: "intro",
5258
+ treatment: "portrait-bio"
5259
+ }
5260
+ }
5261
+ }), defineBlockAppearancePreset({
5262
+ id: "offerings-preview-default-cards",
5263
+ target: "offerings",
5264
+ label: "Default offering cards",
5265
+ blockKinds: ["block.offerings-preview"],
5266
+ design: {
5267
+ sectionSurface: "base",
5268
+ contentFrame: plainFrame,
5269
+ itemSurface: "default"
5270
+ }
5271
+ }), defineBlockAppearancePreset({
5272
+ id: "offerings-preview-secondary-cards",
5273
+ target: "offerings",
5274
+ label: "Secondary offering cards",
5275
+ blockKinds: ["block.offerings-preview"],
5276
+ design: {
5277
+ sectionSurface: "muted-band",
5278
+ contentFrame: plainFrame,
5279
+ itemSurface: "inset"
5280
+ }
5281
+ }), defineBlockAppearancePreset({
5282
+ id: "offerings-preview-non-carded",
5283
+ target: "offerings",
5284
+ label: "Non-carded offerings",
5285
+ blockKinds: ["block.offerings-preview"],
5286
+ design: {
5287
+ sectionSurface: "muted-band",
5288
+ contentFrame: plainFrame,
5289
+ itemSurface: "editorial"
5290
+ }
5291
+ }), defineBlockAppearancePreset({
5292
+ id: "offerings-preview-paired-feature-cards",
5293
+ target: "offerings",
5294
+ label: "Paired feature cards",
5295
+ blockKinds: ["block.offerings-preview"],
5296
+ constraints: { layoutVariantKeys: ["cards"] },
5297
+ design: {
5298
+ sectionSurface: "base",
5299
+ contentFrame: plainFrame,
5300
+ itemSurface: "none"
5301
+ }
5302
+ }), defineBlockAppearancePreset({
5303
+ id: "offerings-preview-open-editorial-columns",
5304
+ target: "offerings",
5305
+ label: "Open editorial columns",
5306
+ blockKinds: ["block.offerings-preview"],
5307
+ constraints: { layoutVariantKeys: ["cards"] },
5308
+ design: {
5309
+ sectionSurface: "base",
5310
+ contentFrame: plainFrame,
5311
+ itemSurface: "none"
5312
+ }
5313
+ }), defineBlockAppearancePreset({
5314
+ id: "offerings-preview-joined-programme-panel",
5315
+ target: "offerings",
5316
+ label: "Joined programme panel",
5317
+ blockKinds: ["block.offerings-preview"],
5318
+ constraints: { layoutVariantKeys: ["cards"] },
5319
+ design: {
5320
+ sectionSurface: "base",
5321
+ contentFrame: plainFrame,
5322
+ itemSurface: "none"
5323
+ }
5324
+ }), defineBlockAppearancePreset({
5325
+ id: "feature-cards-raised-rule",
5326
+ target: "feature-cards",
5327
+ label: "Raised cards with rule",
5328
+ blockKinds: ["block.feature-cards"],
5329
+ design: {
5330
+ sectionSurface: "base",
5331
+ contentFrame: plainFrame,
5332
+ itemSurface: "raised"
5333
+ }
5334
+ }), defineBlockAppearancePreset({
5335
+ id: "feature-cards-bold-colors",
5336
+ target: "feature-cards",
5337
+ label: "Bold colour-blocked cards",
5338
+ blockKinds: ["block.feature-cards"],
5339
+ design: {
5340
+ sectionSurface: "base",
5341
+ contentFrame: plainFrame,
5342
+ itemSurface: "color-blocked"
5343
+ }
5344
+ }), defineBlockAppearancePreset({
5345
+ id: "feature-cards-editorial-columns",
5346
+ target: "feature-cards",
5347
+ label: "Editorial open columns",
5348
+ blockKinds: ["block.feature-cards"],
5349
+ design: {
5350
+ sectionSurface: "base",
5351
+ contentFrame: plainFrame,
5352
+ itemSurface: "editorial"
5353
+ }
5354
+ }), defineBlockAppearancePreset({
5355
+ id: "feature-cards-asymmetric-emphasis",
5356
+ target: "feature-cards",
5357
+ label: "Asymmetric emphasis pair",
5358
+ blockKinds: ["block.feature-cards"],
5359
+ constraints: { layoutFamilies: ["grid"] },
5360
+ design: {
5361
+ sectionSurface: "base",
5362
+ contentFrame: plainFrame,
5363
+ itemSurface: "none",
5364
+ composition: {
5365
+ kind: "feature-cards",
5366
+ treatment: "asymmetric-emphasis"
5367
+ }
5368
+ }
5369
+ }), defineBlockAppearancePreset({
5370
+ id: "feature-cards-framed-programme",
5371
+ target: "feature-cards",
5372
+ label: "Framed programme cards",
5373
+ blockKinds: ["block.feature-cards"],
5374
+ constraints: { layoutFamilies: ["grid"] },
5375
+ design: {
5376
+ sectionSurface: "brand-depth-band",
5377
+ contentFrame: plainFrame,
5378
+ itemSurface: "inset",
5379
+ composition: {
5380
+ kind: "feature-cards",
5381
+ treatment: "framed-programme"
5382
+ }
5383
+ }
5384
+ }), defineBlockAppearancePreset({
5385
+ id: "feature-cards-soft-panels",
5386
+ target: "feature-cards",
5387
+ label: "Soft tinted panels",
5388
+ blockKinds: ["block.feature-cards"],
5389
+ design: {
5390
+ sectionSurface: "base",
5391
+ contentFrame: plainFrame,
5392
+ itemSurface: "inset"
5393
+ }
5394
+ }), defineBlockAppearancePreset({
5395
+ id: "feature-cards-editorial-diptych",
5396
+ target: "feature-cards",
5397
+ label: "Editorial diptych",
5398
+ blockKinds: ["block.feature-cards"],
5399
+ constraints: { layoutVariantKeys: ["editorial-diptych"] },
5400
+ design: {
5401
+ sectionSurface: "base",
5402
+ contentFrame: plainFrame,
5403
+ itemSurface: "flat"
5404
+ }
5405
+ }), defineBlockAppearancePreset({
5406
+ id: "feature-cards-editorial-pathways",
5407
+ target: "feature-cards",
5408
+ label: "Editorial pathways",
5409
+ blockKinds: ["block.feature-cards"],
5410
+ constraints: { layoutVariantKeys: ["editorial-pathways"] },
5411
+ design: {
5412
+ sectionSurface: "base",
5413
+ contentFrame: plainFrame,
5414
+ itemSurface: "flat"
5415
+ }
5416
+ }), defineBlockAppearancePreset({
5417
+ id: "feature-cards-photo-tiles",
5418
+ target: "feature-cards",
5419
+ label: "Photo tiles",
5420
+ blockKinds: ["block.feature-cards"],
5421
+ design: {
5422
+ sectionSurface: "base",
5423
+ contentFrame: plainFrame,
5424
+ itemSurface: "raised"
5425
+ }
5426
+ }), defineBlockAppearancePreset({
5427
+ id: "events-lined-panel",
5428
+ target: "events",
5429
+ label: "Raised event panel",
5430
+ blockKinds: ["block.event-calendar", "block.event-listing"],
5431
+ design: {
5432
+ sectionSurface: "base",
5433
+ contentFrame: panelFrame("raised"),
5434
+ itemSurface: "none"
5435
+ }
5436
+ }), defineBlockAppearancePreset({
5437
+ id: "events-ruled-register",
5438
+ target: "events",
5439
+ label: "Ruled event register",
5440
+ blockKinds: ["block.event-calendar", "block.event-listing"],
5441
+ design: {
5442
+ sectionSurface: "brand-depth-band",
5443
+ contentFrame: plainFrame,
5444
+ itemSurface: "none",
5445
+ eventListTreatment: "ruled-register"
5446
+ }
5447
+ }), defineBlockAppearancePreset({
5448
+ id: "events-editorial-register",
5449
+ target: "events",
5450
+ label: "Editorial event register",
5451
+ blockKinds: ["block.event-calendar", "block.event-listing"],
5452
+ design: {
5453
+ sectionSurface: "base",
5454
+ contentFrame: plainFrame,
5455
+ itemSurface: "none",
5456
+ eventListTreatment: "editorial-register"
5457
+ }
5458
+ }), defineBlockAppearancePreset({
5459
+ id: "events-dense-index",
5460
+ target: "events",
5461
+ label: "Dense event index",
5462
+ blockKinds: ["block.event-calendar", "block.event-listing"],
5463
+ design: {
5464
+ sectionSurface: "accent-band",
5465
+ contentFrame: plainFrame,
5466
+ itemSurface: "none",
5467
+ eventListTreatment: "dense-index"
5468
+ }
5469
+ }), defineBlockAppearancePreset({
5470
+ id: "schedule-details-brand-depth",
5471
+ target: "events",
5472
+ label: "Brand-depth schedule details",
5473
+ blockKinds: ["block.event-details", "block.course-details"],
5474
+ design: {
5475
+ sectionSurface: "brand-depth-band",
5476
+ contentFrame: plainFrame,
5477
+ itemSurface: "none",
5478
+ tileTreatment: "brand-depth"
5479
+ }
5480
+ }), defineBlockAppearancePreset({
5481
+ id: "media-text-flush-feature",
5482
+ target: "media-text",
5483
+ label: "Flush media feature",
5484
+ blockKinds: ["block.media-text"],
5485
+ design: {
5486
+ sectionSurface: "muted-band",
5487
+ contentFrame: flushPanelFrame({ bleed: "start" }),
5488
+ itemSurface: "none"
5489
+ }
5490
+ }), defineBlockAppearancePreset({
5491
+ id: "testimonials-simple-cards",
5492
+ target: "testimonials",
5493
+ label: "Simple testimonial cards",
5494
+ blockKinds: ["block.testimonials"],
5495
+ design: {
5496
+ sectionSurface: "base",
5497
+ contentFrame: plainFrame,
5498
+ itemSurface: "default"
5499
+ }
5500
+ }), defineBlockAppearancePreset({
5501
+ id: "testimonials-raised-panel",
5502
+ target: "testimonials",
5503
+ label: "Raised testimonial panel",
5504
+ blockKinds: ["block.testimonials"],
5505
+ design: {
5506
+ sectionSurface: "muted-band",
5507
+ contentFrame: panelFrame("raised"),
5508
+ itemSurface: "raised"
5509
+ }
5510
+ }), defineBlockAppearancePreset({
5511
+ id: "testimonials-accent-panel",
5512
+ target: "testimonials",
5513
+ label: "Accent testimonial panel",
5514
+ blockKinds: ["block.testimonials"],
5515
+ design: {
5516
+ sectionSurface: "accent-band",
5517
+ contentFrame: panelFrame("raised"),
5518
+ itemSurface: "raised"
5519
+ }
5520
+ }), defineBlockAppearancePreset({
5521
+ id: "testimonials-default-cards",
5522
+ target: "testimonials",
5523
+ label: "Default cards",
5524
+ blockKinds: ["block.testimonials"],
5525
+ design: {
5526
+ sectionSurface: "base",
5527
+ contentFrame: plainFrame,
5528
+ itemSurface: "none",
5529
+ testimonialCardTreatment: "default"
5530
+ }
5531
+ }), defineBlockAppearancePreset({
5532
+ id: "testimonials-statement-cards",
5533
+ target: "testimonials",
5534
+ label: "Statement cards",
5535
+ blockKinds: ["block.testimonials"],
5536
+ design: {
5537
+ sectionSurface: "accent-band",
5538
+ contentFrame: plainFrame,
5539
+ itemSurface: "raised",
5540
+ testimonialCardTreatment: "statement"
5541
+ }
5542
+ }), defineBlockAppearancePreset({
5543
+ id: "testimonials-brand-statement-cards",
5544
+ target: "testimonials",
5545
+ label: "Brand statement cards",
5546
+ blockKinds: ["block.testimonials"],
5547
+ design: {
5548
+ sectionSurface: "brand-depth-band",
5549
+ contentFrame: plainFrame,
5550
+ itemSurface: "raised",
5551
+ testimonialCardTreatment: "statement"
5552
+ }
5553
+ }), defineBlockAppearancePreset({
5554
+ id: "testimonials-non-carded",
5555
+ target: "testimonials",
5556
+ label: "Non-carded",
5557
+ blockKinds: ["block.testimonials"],
5558
+ design: {
5559
+ sectionSurface: "muted-band",
5560
+ contentFrame: plainFrame,
5561
+ itemSurface: "none",
5562
+ testimonialCardTreatment: "non-carded"
5563
+ }
5564
+ }), defineBlockAppearancePreset({
5565
+ id: "testimonials-evergreen-lead",
5566
+ target: "testimonials",
5567
+ label: "Evergreen lead",
5568
+ blockKinds: ["block.testimonials"],
5569
+ constraints: { layoutVariantKeys: ["featured-editorial"] },
5570
+ design: {
5571
+ sectionSurface: "base",
5572
+ contentFrame: plainFrame,
5573
+ itemSurface: "none"
5574
+ }
5575
+ }), defineBlockAppearancePreset({
5576
+ id: "testimonials-room-and-response",
5577
+ target: "testimonials",
5578
+ label: "Room and response",
5579
+ blockKinds: ["block.testimonials"],
5580
+ constraints: { layoutVariantKeys: ["featured-editorial"] },
5581
+ design: {
5582
+ sectionSurface: "base",
5583
+ contentFrame: plainFrame,
5584
+ itemSurface: "none"
5585
+ }
5586
+ }), defineBlockAppearancePreset({
5587
+ id: "testimonials-open-floor",
5588
+ target: "testimonials",
5589
+ label: "Open floor",
5590
+ blockKinds: ["block.testimonials"],
5591
+ constraints: { layoutVariantKeys: ["featured-editorial"] },
5592
+ design: {
5593
+ sectionSurface: "base",
5594
+ contentFrame: plainFrame,
5595
+ itemSurface: "none"
5596
+ }
5597
+ }), defineBlockAppearancePreset({
5598
+ id: "faq-base-accordion",
5599
+ target: "faq",
5600
+ label: "Base accordion FAQ",
5601
+ blockKinds: ["block.faq"],
5602
+ design: {
5603
+ sectionSurface: "base",
5604
+ contentFrame: plainFrame,
5605
+ itemSurface: "default"
5606
+ }
5607
+ }), defineBlockAppearancePreset({
5608
+ id: "faq-contained-help",
5609
+ target: "faq",
5610
+ label: "Contained help panel",
5611
+ blockKinds: ["block.faq"],
5612
+ design: {
5613
+ sectionSurface: "muted-band",
5614
+ contentFrame: panelFrame("inset"),
5615
+ itemSurface: "default"
5616
+ }
5617
+ }), defineBlockAppearancePreset({
5618
+ id: "contact-form-panel",
5619
+ target: "contact-form",
5620
+ label: "Raised form panel",
5621
+ blockKinds: ["block.form"],
5622
+ design: {
5623
+ sectionSurface: "muted-band",
5624
+ contentFrame: panelFrame("raised"),
5625
+ itemSurface: "none"
5626
+ }
5627
+ }), defineBlockAppearancePreset({
5628
+ id: "cta-accent-band",
5629
+ target: "cta",
5630
+ label: "Accent CTA band",
5631
+ blockKinds: ["block.cta-full"],
5632
+ design: {
5633
+ sectionSurface: "accent-band",
5634
+ contentFrame: plainFrame,
5635
+ itemSurface: "none",
5636
+ eyebrowTreatment: "accent"
5637
+ }
5638
+ });
5647
5639
  //#endregion
5648
5640
  //#region ../theme-core/src/site-styles/headerCtaVariants.ts
5649
5641
  function hasButtonVariant(theme, variantId) {
@@ -7052,6 +7044,21 @@ const themeColorTokenSchema = z$1.string().min(1).refine((value) => Boolean(isTh
7052
7044
  //#region ../theme-core/src/palette/colors.ts
7053
7045
  const HEX_COLOR_REGEX = /^#[0-9a-f]{6}$/;
7054
7046
  const NORMALIZABLE_HEX_REGEX = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i;
7047
+ const THEME_PALETTE_COLOR_ORDER = [
7048
+ "primary",
7049
+ "secondary",
7050
+ "accent",
7051
+ "success",
7052
+ "warning",
7053
+ "destructive",
7054
+ "background",
7055
+ "surface",
7056
+ "surfaceAlt",
7057
+ "muted",
7058
+ "text",
7059
+ "primaryForeground",
7060
+ "border"
7061
+ ];
7055
7062
  const hexColorSchema = z$1.string().regex(HEX_COLOR_REGEX, "Hex must be #RRGGBB (lowercase)").transform((value) => value);
7056
7063
  const paletteModeSchema = z$1.enum(["light", "dark"]);
7057
7064
  const PALETTE_VALUE_KEY_PREFIX = "palette-value:v1|";
@@ -7129,6 +7136,12 @@ function requirePaletteColorsFromEntries(entries) {
7129
7136
  if (result.ok) return result.colors;
7130
7137
  throw new Error(`Invalid complete palette: ${result.error.kind}`);
7131
7138
  }
7139
+ function paletteColorEntries(colors) {
7140
+ return THEME_PALETTE_COLOR_ORDER.map((name) => ({
7141
+ name,
7142
+ hex: colors[name]
7143
+ }));
7144
+ }
7132
7145
  function paletteColorFingerprint(colors) {
7133
7146
  return PALETTE_TOKEN_NAMES.map((name) => `${name}:${colors[name]}`).join("|");
7134
7147
  }
@@ -7136,7 +7149,7 @@ function canonicalPaletteHashInput(colors, mode) {
7136
7149
  return `${mode}|${paletteColorFingerprint(colors)}`;
7137
7150
  }
7138
7151
  /**
7139
- * The shared TypeScript/SQL protocol. Do not reorder roles: the order comes
7152
+ * Stable curated-catalogue identity. Do not reorder roles: the order comes
7140
7153
  * from PALETTE_TOKEN_NAMES through canonicalPaletteHashInput.
7141
7154
  */
7142
7155
  function paletteValueKey(colors, mode) {
@@ -8462,13 +8475,6 @@ const warmDarkKirtanGold = defineCuratedPalette({
8462
8475
  });
8463
8476
  //#endregion
8464
8477
  //#region ../theme-core/src/palette/curated/index.ts
8465
- /**
8466
- * Curated palette library.
8467
- *
8468
- * Authoring keys are readable source aliases. Value keys are derived from the
8469
- * complete mode and semantic colours and are the only curated identity used at
8470
- * persistence and runtime boundaries.
8471
- */
8472
8478
  function admitCuratedPaletteDefinition(definition) {
8473
8479
  return {
8474
8480
  ...definition,
@@ -8495,11 +8501,8 @@ const curatedPalettes = [
8495
8501
  admitCuratedPaletteDefinition(warmDarkEmber),
8496
8502
  admitCuratedPaletteDefinition(warmDarkKirtanGold)
8497
8503
  ];
8498
- const curatedPalettesByValueKey = new Map(curatedPalettes.map((palette) => [palette.valueKey, palette]));
8504
+ new Map(curatedPalettes.map((palette) => [palette.valueKey, palette]));
8499
8505
  const curatedPalettesByAuthoringKey = new Map(curatedPalettes.map((palette) => [palette.authoringKey, palette]));
8500
- function findCuratedPalette(valueKey) {
8501
- return curatedPalettesByValueKey.get(valueKey);
8502
- }
8503
8506
  function findCuratedPaletteByAuthoringKey(authoringKey) {
8504
8507
  return curatedPalettesByAuthoringKey.get(authoringKey);
8505
8508
  }
@@ -8508,87 +8511,6 @@ function requireCuratedPaletteValueKey(authoringKey) {
8508
8511
  if (!palette) throw new Error(`Unknown curated palette authoring key "${authoringKey}"`);
8509
8512
  return palette.valueKey;
8510
8513
  }
8511
- /** Parses a raw persisted key into catalogue-proven curated membership. */
8512
- const knownCuratedPaletteValueKeySchema = z$1.string().transform((value, ctx) => {
8513
- const valueKey = parsePaletteValueKey(value);
8514
- if (!valueKey) {
8515
- ctx.addIssue({
8516
- code: "custom",
8517
- message: "Invalid canonical palette value key"
8518
- });
8519
- return z$1.NEVER;
8520
- }
8521
- const palette = findCuratedPalette(valueKey);
8522
- if (!palette) {
8523
- ctx.addIssue({
8524
- code: "custom",
8525
- message: "Unknown curated palette value key"
8526
- });
8527
- return z$1.NEVER;
8528
- }
8529
- return palette.valueKey;
8530
- });
8531
- //#endregion
8532
- //#region ../theme-core/src/palette/selection.ts
8533
- const sitePaletteIdSchema = z$1.string().uuid().transform((value) => value);
8534
- const sitePaletteVersionSchema = z$1.number().int().nonnegative().transform((value) => value);
8535
- const paletteSelectionSchema = z$1.discriminatedUnion("kind", [z$1.object({
8536
- kind: z$1.literal("curated"),
8537
- valueKey: knownCuratedPaletteValueKeySchema
8538
- }), z$1.object({
8539
- kind: z$1.literal("site"),
8540
- paletteId: sitePaletteIdSchema
8541
- })]);
8542
- const onboardingPaletteOriginSchema = z$1.object({
8543
- kind: z$1.literal("onboarding"),
8544
- sourceKey: z$1.string().min(1).nullable()
8545
- });
8546
- const curatedForkPaletteOriginSchema = z$1.object({
8547
- kind: z$1.literal("curated-fork"),
8548
- sourceValueKey: paletteValueKeySchema
8549
- });
8550
- const manualPaletteOriginSchema = z$1.object({ kind: z$1.literal("manual") });
8551
- const legacyCustomizedPaletteOriginSchema = z$1.object({
8552
- kind: z$1.literal("legacy-customized"),
8553
- sourceKey: z$1.string().min(1).nullable()
8554
- });
8555
- const sitePaletteOriginSchema = z$1.discriminatedUnion("kind", [
8556
- onboardingPaletteOriginSchema,
8557
- curatedForkPaletteOriginSchema,
8558
- manualPaletteOriginSchema,
8559
- legacyCustomizedPaletteOriginSchema
8560
- ]);
8561
- const editorSitePaletteOriginSchema = z$1.discriminatedUnion("kind", [z$1.object({
8562
- kind: z$1.literal("curated-fork"),
8563
- sourceValueKey: knownCuratedPaletteValueKeySchema
8564
- }), manualPaletteOriginSchema]);
8565
- z$1.object({
8566
- id: sitePaletteIdSchema,
8567
- colors: paletteColorsSchema,
8568
- mode: paletteModeSchema,
8569
- origin: sitePaletteOriginSchema,
8570
- version: sitePaletteVersionSchema
8571
- });
8572
- z$1.discriminatedUnion("kind", [
8573
- z$1.object({ kind: z$1.literal("preserve") }),
8574
- z$1.object({
8575
- kind: z$1.literal("select"),
8576
- selection: paletteSelectionSchema
8577
- }),
8578
- z$1.object({
8579
- kind: z$1.literal("create-site"),
8580
- colors: paletteColorsSchema,
8581
- mode: paletteModeSchema,
8582
- origin: editorSitePaletteOriginSchema
8583
- }),
8584
- z$1.object({
8585
- kind: z$1.literal("update-site"),
8586
- paletteId: sitePaletteIdSchema,
8587
- expectedVersion: sitePaletteVersionSchema,
8588
- colors: paletteColorsSchema,
8589
- mode: paletteModeSchema
8590
- })
8591
- ]);
8592
8514
  const defaultThemeTokens = {
8593
8515
  color: {
8594
8516
  "background/base": "#ffffff",
@@ -8797,6 +8719,32 @@ function parseBackgroundAppearanceColorToken(value) {
8797
8719
  function uniqueStrings(values) {
8798
8720
  return Array.from(new Set(values));
8799
8721
  }
8722
+ const headerInteractionPaletteSchema = z$1.enum([
8723
+ "primary",
8724
+ "secondary",
8725
+ "accent"
8726
+ ]);
8727
+ //#endregion
8728
+ //#region ../theme-core/src/site-styles/headerInteractionPalette.ts
8729
+ const clearSplitInteractionPalette = defineLookOptionGroup({
8730
+ id: "interaction-palette",
8731
+ label: "Hover colour",
8732
+ defaultOptionId: "accent",
8733
+ options: [
8734
+ {
8735
+ id: "accent",
8736
+ label: "Accent"
8737
+ },
8738
+ {
8739
+ id: "primary",
8740
+ label: "Primary"
8741
+ },
8742
+ {
8743
+ id: "secondary",
8744
+ label: "Secondary"
8745
+ }
8746
+ ]
8747
+ });
8800
8748
  //#endregion
8801
8749
  //#region ../theme-core/src/site-styles/logoBranding.ts
8802
8750
  const logoTextConfidenceValues = [
@@ -9019,7 +8967,7 @@ const overlayLogoAccommodations = [
9019
8967
  * optional nested styling fields that would otherwise leak from another Look.
9020
8968
  */
9021
8969
  function baseHeader(theme) {
9022
- const { navLinkStyle: _navLinkStyle, navFontRole: _navFontRole, navTypography: _navTypography, navTextSize: _navTextSize, dropdownStyle: _dropdownStyle, ctaVariant: _ctaVariant, navContainer: _navContainer, container: _container, shadow: _shadow, logo: _logo, logoText: _logoText, border: _border, ...header } = theme.header;
8970
+ const { navLinkStyle: _navLinkStyle, navFontRole: _navFontRole, navTypography: _navTypography, navTextSize: _navTextSize, interactionPalette: _interactionPalette, dropdownStyle: _dropdownStyle, ctaVariant: _ctaVariant, navContainer: _navContainer, container: _container, shadow: _shadow, logo: _logo, logoText: _logoText, border: _border, ...header } = theme.header;
9023
8971
  return {
9024
8972
  ...header,
9025
8973
  navContainer: {
@@ -9034,7 +8982,6 @@ const headerLayoutCatalog = defineExactCatalog()([
9034
8982
  id: asHeaderLayoutId("classic"),
9035
8983
  label: "Classic",
9036
8984
  description: "Logo and navigation in one practical horizontal row.",
9037
- structure: "inline-classic",
9038
8985
  variant: "classic",
9039
8986
  defaultPositioning: "sticky",
9040
8987
  shrinkOnScroll: false
@@ -9043,7 +8990,6 @@ const headerLayoutCatalog = defineExactCatalog()([
9043
8990
  id: asHeaderLayoutId("centered"),
9044
8991
  label: "Centered",
9045
8992
  description: "Logo centered above a balanced navigation row.",
9046
- structure: "centered-stack",
9047
8993
  variant: "centered",
9048
8994
  defaultPositioning: "static",
9049
8995
  shrinkOnScroll: false,
@@ -9059,7 +9005,6 @@ const headerLayoutCatalog = defineExactCatalog()([
9059
9005
  id: asHeaderLayoutId("floating"),
9060
9006
  label: "Floating",
9061
9007
  description: "Detached header chrome that sits over the opening section.",
9062
- structure: "floating-shell",
9063
9008
  variant: "floating",
9064
9009
  defaultPositioning: "sticky",
9065
9010
  shrinkOnScroll: true,
@@ -9221,10 +9166,13 @@ const headerStyleCatalog = defineExactCatalog()([
9221
9166
  label: "Clear Split",
9222
9167
  description: "Floating logo with transparent navigation and no shared shell.",
9223
9168
  supportedLayoutIds: supportedLayouts(["floating"]),
9224
- navInteraction: "color-change",
9169
+ navInteraction: "pill-background",
9225
9170
  surface: "floating",
9226
- defaultDepth: "none",
9171
+ defaultDepth: "line",
9227
9172
  navTypography: "plain",
9173
+ openingForegroundTarget: "all",
9174
+ scrollTreatment: "contrast-glass",
9175
+ interactionPalette: clearSplitInteractionPalette,
9228
9176
  moods: ["editorial", "calm"]
9229
9177
  },
9230
9178
  {
@@ -9247,6 +9195,7 @@ const headerStyleCatalog = defineExactCatalog()([
9247
9195
  surface: "floating",
9248
9196
  defaultDepth: "shadow",
9249
9197
  navTypography: "quiet-caps",
9198
+ openingForegroundTarget: "brand-only",
9250
9199
  moods: ["expressive"]
9251
9200
  },
9252
9201
  {
@@ -9258,6 +9207,7 @@ const headerStyleCatalog = defineExactCatalog()([
9258
9207
  surface: "floating",
9259
9208
  defaultDepth: "shadow",
9260
9209
  navTypography: "heading",
9210
+ openingForegroundTarget: "brand-only",
9261
9211
  moods: ["calm", "editorial"]
9262
9212
  }
9263
9213
  ]);
@@ -9452,7 +9402,7 @@ function applyNavTypography(style, typography) {
9452
9402
  textSize: "sm",
9453
9403
  letterSpacing: "wider"
9454
9404
  };
9455
- default: return assertNever$16(typography, "Unhandled header nav typography");
9405
+ default: return assertNever$15(typography, "Unhandled header nav typography");
9456
9406
  }
9457
9407
  }
9458
9408
  function underlineNavLinkStyle(colorToken, underlineColorToken, typography = "plain") {
@@ -9481,7 +9431,7 @@ function themedHeaderShadow(theme) {
9481
9431
  case "low": return { elevation: "sm" };
9482
9432
  case "medium": return { elevation: "md" };
9483
9433
  case "high": return { elevation: "lg" };
9484
- default: return assertNever$16(theme.shadow.elevation, "Unhandled theme shadow elevation");
9434
+ default: return assertNever$15(theme.shadow.elevation, "Unhandled theme shadow elevation");
9485
9435
  }
9486
9436
  }
9487
9437
  function solidBrandHeader(theme) {
@@ -9759,13 +9709,6 @@ const headerLookCatalog = defineExactCatalog()([
9759
9709
  {
9760
9710
  id: asHeaderLookId("clean-base"),
9761
9711
  label: "Clean base",
9762
- visualTreatment: "solid-neutral",
9763
- layoutBehavior: "sticky",
9764
- configuration: {
9765
- structure: "inline-classic",
9766
- treatment: "solid-neutral",
9767
- behavior: "sticky"
9768
- },
9769
9712
  openingRequirement: "none",
9770
9713
  logoAccommodations: inlineClassicLogoAccommodations,
9771
9714
  compile: cleanBaseHeader
@@ -9773,13 +9716,6 @@ const headerLookCatalog = defineExactCatalog()([
9773
9716
  {
9774
9717
  id: asHeaderLookId("classic-centered-nav"),
9775
9718
  label: "Centered nav",
9776
- visualTreatment: "solid-neutral",
9777
- layoutBehavior: "sticky",
9778
- configuration: {
9779
- structure: "inline-classic",
9780
- treatment: "solid-neutral",
9781
- behavior: "sticky"
9782
- },
9783
9719
  openingRequirement: "none",
9784
9720
  maxRecommendedNavItems: 6,
9785
9721
  logoAccommodations: inlineClassicLogoAccommodations,
@@ -9788,13 +9724,6 @@ const headerLookCatalog = defineExactCatalog()([
9788
9724
  {
9789
9725
  id: asHeaderLookId("brand-solid"),
9790
9726
  label: "Brand solid",
9791
- visualTreatment: "solid-brand",
9792
- layoutBehavior: "sticky-shrink",
9793
- configuration: {
9794
- structure: "inline-classic",
9795
- treatment: "solid-brand",
9796
- behavior: "sticky-shrink"
9797
- },
9798
9727
  openingRequirement: "none",
9799
9728
  logoAccommodations: inlineClassicLogoAccommodations,
9800
9729
  compile: solidBrandHeader
@@ -9802,13 +9731,6 @@ const headerLookCatalog = defineExactCatalog()([
9802
9731
  {
9803
9732
  id: asHeaderLookId("serif-line"),
9804
9733
  label: "Serif line",
9805
- visualTreatment: "light-serif",
9806
- layoutBehavior: "sticky",
9807
- configuration: {
9808
- structure: "centered-stack",
9809
- treatment: "light-serif",
9810
- behavior: "sticky"
9811
- },
9812
9734
  openingRequirement: "none",
9813
9735
  maxRecommendedNavItems: 6,
9814
9736
  logoAccommodations: centeredLogoAccommodations,
@@ -9817,13 +9739,6 @@ const headerLookCatalog = defineExactCatalog()([
9817
9739
  {
9818
9740
  id: asHeaderLookId("centered-calm"),
9819
9741
  label: "Centered calm",
9820
- visualTreatment: "light-serif",
9821
- layoutBehavior: "normal-flow",
9822
- configuration: {
9823
- structure: "centered-stack",
9824
- treatment: "light-serif",
9825
- behavior: "normal-flow"
9826
- },
9827
9742
  openingRequirement: "none",
9828
9743
  maxRecommendedNavItems: 5,
9829
9744
  logoAccommodations: centeredLogoAccommodations,
@@ -9832,13 +9747,6 @@ const headerLookCatalog = defineExactCatalog()([
9832
9747
  {
9833
9748
  id: asHeaderLookId("practical-utility"),
9834
9749
  label: "Practical utility",
9835
- visualTreatment: "solid-neutral",
9836
- layoutBehavior: "sticky-shrink",
9837
- configuration: {
9838
- structure: "inline-classic",
9839
- treatment: "solid-neutral",
9840
- behavior: "sticky-shrink"
9841
- },
9842
9750
  openingRequirement: "none",
9843
9751
  requiresProminentCta: true,
9844
9752
  logoAccommodations: inlineClassicLogoAccommodations,
@@ -9847,13 +9755,6 @@ const headerLookCatalog = defineExactCatalog()([
9847
9755
  {
9848
9756
  id: asHeaderLookId("minimal-transparent"),
9849
9757
  label: "Minimal transparent",
9850
- visualTreatment: "minimal-transparent",
9851
- layoutBehavior: "normal-flow",
9852
- configuration: {
9853
- structure: "inline-classic",
9854
- treatment: "minimal-transparent",
9855
- behavior: "normal-flow"
9856
- },
9857
9758
  openingRequirement: "reserved-space-ok",
9858
9759
  logoAccommodations: inlineClassicLogoAccommodations,
9859
9760
  compile: minimalTransparentHeader
@@ -9861,13 +9762,6 @@ const headerLookCatalog = defineExactCatalog()([
9861
9762
  {
9862
9763
  id: asHeaderLookId("transparent-overlay"),
9863
9764
  label: "Transparent overlay",
9864
- visualTreatment: "transparent-overlay",
9865
- layoutBehavior: "fixed-overlay",
9866
- configuration: {
9867
- structure: "inline-classic",
9868
- treatment: "transparent-overlay",
9869
- behavior: "fixed-overlay"
9870
- },
9871
9765
  openingRequirement: "requires-image-hero-with-contrast-overlay",
9872
9766
  maxRecommendedNavItems: 5,
9873
9767
  logoAccommodations: overlayLogoAccommodations,
@@ -9876,24 +9770,13 @@ const headerLookCatalog = defineExactCatalog()([
9876
9770
  {
9877
9771
  id: asHeaderLookId("floating-glass"),
9878
9772
  label: "Floating glass",
9879
- visualTreatment: "floating-glass",
9880
- layoutBehavior: "fixed-floating",
9881
- configuration: {
9882
- structure: "floating-shell",
9883
- treatment: "floating-glass",
9884
- behavior: "fixed-floating"
9885
- },
9886
9773
  openingRequirement: "requires-image-hero-with-contrast-overlay",
9887
9774
  maxRecommendedNavItems: 5,
9888
9775
  logoAccommodations: overlayLogoAccommodations,
9889
9776
  compile: floatingGlassHeader
9890
9777
  }
9891
9778
  ]);
9892
- new Set(headerLookCatalog.map((look) => headerConfigurationKey(look.configuration)));
9893
9779
  new Map(headerLookCatalog.map((look) => [look.id, look]));
9894
- function headerConfigurationKey(configuration) {
9895
- return `${configuration.structure}:${configuration.treatment}:${configuration.behavior}`;
9896
- }
9897
9780
  //#endregion
9898
9781
  //#region ../theme-core/src/site-styles/sectionTransitions.ts
9899
9782
  function boundaryRuntimeMetrics(family, size, heightExpression) {
@@ -10097,8 +9980,6 @@ const VARIANT_ROLES = [
10097
9980
  "secondary",
10098
9981
  "outline",
10099
9982
  "ghost",
10100
- "link",
10101
- "tertiary",
10102
9983
  "accent"
10103
9984
  ];
10104
9985
  function isVariantRole(value) {
@@ -10110,7 +9991,7 @@ function isVariantRole(value) {
10110
9991
  * IDs become class selectors, so keep the contract deliberately narrower than
10111
9992
  * an arbitrary string and shared with every authoring/runtime boundary.
10112
9993
  */
10113
- const buttonVariantIdSchema = z$1.string().min(1).max(50).regex(/^[a-z0-9-]+$/, "Button variant IDs may contain lowercase letters, numbers, and hyphens only");
9994
+ const buttonVariantIdSchema = z$1.string().min(1).max(50).regex(/^[a-z0-9-]+$/, "Button variant IDs may contain lowercase letters, numbers, and hyphens only").refine((value) => value !== "link" && value !== "tertiary", { message: "Retired button role IDs are not valid variant IDs" });
10114
9995
  function asSpecialVariantId(value) {
10115
9996
  const parsed = buttonVariantIdSchema.safeParse(value);
10116
9997
  if (!parsed.success) throw new Error("SpecialVariantId must be a CSS-safe button variant ID");
@@ -13301,39 +13182,39 @@ function defaultTypographyForRecipe(recipe) {
13301
13182
  }
13302
13183
  //#endregion
13303
13184
  //#region ../theme-core/src/lib/media.ts
13304
- const hotspotSchema$1 = z.object({
13185
+ const hotspotSchema = z.object({
13305
13186
  x: z.number().min(0).max(1),
13306
13187
  y: z.number().min(0).max(1),
13307
13188
  radius: z.number().optional()
13308
13189
  });
13309
- const rotationSchema$1 = z.union([
13190
+ const rotationSchema = z.union([
13310
13191
  z.literal(0),
13311
13192
  z.literal(90),
13312
13193
  z.literal(180),
13313
13194
  z.literal(270)
13314
13195
  ]);
13315
- const rectSchema$1 = z.tuple([
13196
+ const rectSchema = z.tuple([
13316
13197
  z.number(),
13317
13198
  z.number(),
13318
13199
  z.number(),
13319
13200
  z.number()
13320
13201
  ]);
13321
- const aspectCropSchema$1 = z.object({
13202
+ const aspectCropSchema = z.object({
13322
13203
  aspect: z.preprocess((value) => value == null ? void 0 : value, z.string().optional()),
13323
- rect: z.preprocess((value) => value == null ? void 0 : value, rectSchema$1.optional()),
13324
- hotspot: z.preprocess((value) => value == null ? void 0 : value, hotspotSchema$1.optional()),
13325
- rotation: z.preprocess((value) => value == null ? void 0 : value, rotationSchema$1.optional())
13204
+ rect: z.preprocess((value) => value == null ? void 0 : value, rectSchema.optional()),
13205
+ hotspot: z.preprocess((value) => value == null ? void 0 : value, hotspotSchema.optional()),
13206
+ rotation: z.preprocess((value) => value == null ? void 0 : value, rotationSchema.optional())
13326
13207
  });
13327
- const transformSchema$1 = z.object({
13208
+ const transformSchema = z.object({
13328
13209
  aspectCrops: z.preprocess((value) => {
13329
13210
  if (!value || typeof value !== "object" || Array.isArray(value)) return;
13330
13211
  return value;
13331
- }, z.record(z.string(), aspectCropSchema$1.catch({}))).optional(),
13332
- rect: rectSchema$1.optional(),
13333
- hotspot: hotspotSchema$1.optional(),
13334
- rotation: rotationSchema$1.optional()
13212
+ }, z.record(z.string(), aspectCropSchema.catch({}))).optional(),
13213
+ rect: rectSchema.optional(),
13214
+ hotspot: hotspotSchema.optional(),
13215
+ rotation: rotationSchema.optional()
13335
13216
  });
13336
- const mediaSchema$1 = z.object({
13217
+ const mediaSchema = z.object({
13337
13218
  type: z.enum([
13338
13219
  "image",
13339
13220
  "video",
@@ -13354,7 +13235,35 @@ const mediaSchema$1 = z.object({
13354
13235
  height: z.number().optional(),
13355
13236
  storageBucket: z.string().optional(),
13356
13237
  storagePath: z.string().optional(),
13357
- transform: transformSchema$1.optional()
13238
+ transform: transformSchema.optional()
13239
+ });
13240
+ //#endregion
13241
+ //#region ../theme-core/src/palette/schema.ts
13242
+ const colourHexString = z$1.string().regex(/^#([0-9A-Fa-f]{3}){1,2}$/);
13243
+ const paletteColorSchema = z$1.object({
13244
+ name: z$1.string().min(1),
13245
+ hex: colourHexString
13246
+ });
13247
+ const paletteMetaSchema = z$1.object({ mode: z$1.enum(["light", "dark"]) });
13248
+ const paletteSchema = z$1.object({
13249
+ colors: z$1.array(paletteColorSchema),
13250
+ meta: paletteMetaSchema
13251
+ }).transform((palette, ctx) => {
13252
+ const colors = paletteColorsFromEntries(palette.colors);
13253
+ if (!colors.ok) {
13254
+ ctx.addIssue({
13255
+ code: "custom",
13256
+ message: `Invalid complete palette: ${colors.error.kind}`
13257
+ });
13258
+ return z$1.NEVER;
13259
+ }
13260
+ return {
13261
+ colors: paletteColorEntries(colors.colors).map(({ name, hex }) => ({
13262
+ name: String(name),
13263
+ hex: String(hex)
13264
+ })),
13265
+ meta: palette.meta
13266
+ };
13358
13267
  });
13359
13268
  //#endregion
13360
13269
  //#region ../theme-core/src/surfaces/foregroundRoles.ts
@@ -14159,264 +14068,6 @@ function generateInteractiveChildInheritanceCSS(selector) {
14159
14068
  return `\n${selector} * {\n font-family: inherit;\n font-weight: inherit;\n font-style: inherit;\n letter-spacing: inherit;\n text-transform: inherit;\n color: inherit;\n}\n`;
14160
14069
  }
14161
14070
  //#endregion
14162
- //#region ../theme-core/src/buttons/effects/presets/background.ts
14163
- /**
14164
- * Darken background on hover
14165
- *
14166
- * Works with solid backgrounds only. Darkens the background color by adjusting the shade.
14167
- */
14168
- const darkenBackgroundEffect = {
14169
- id: "darken-background",
14170
- name: "Darken on Hover",
14171
- description: "Darkens the background color on hover",
14172
- category: "background",
14173
- pseudoElement: "none",
14174
- applicableTo: ["button"],
14175
- customizableOption: {
14176
- name: "amount",
14177
- type: "select",
14178
- label: "Darken Amount (shade step)",
14179
- default: 100,
14180
- options: [
14181
- 0,
14182
- 100,
14183
- 200,
14184
- 300,
14185
- 400,
14186
- 500,
14187
- 600,
14188
- 700,
14189
- 800,
14190
- 900
14191
- ]
14192
- },
14193
- isApplicable: (buttonConfig) => {
14194
- return buttonConfig.background.type === "solid";
14195
- },
14196
- generateCSS: (ctx) => {
14197
- const { themeId, variantId, options, tokens, buttonConfig } = ctx;
14198
- if (buttonConfig.background.type !== "solid") return "";
14199
- const amount = options.amount || 100;
14200
- const baseToken = buttonConfig.background.colorToken ?? "primary-500";
14201
- const darkerToken = tokens.adjustShade(baseToken, amount);
14202
- return `
14203
- :where([data-theme-scope="${themeId}"]) .${variantId}:hover {
14204
- background-color: ${tokens.getColor(darkerToken)};
14205
- }
14206
- `;
14207
- }
14208
- };
14209
- /**
14210
- * Lighten background on hover
14211
- *
14212
- * Works with solid backgrounds only. Lightens the background color by adjusting the shade.
14213
- */
14214
- const lightenBackgroundEffect = {
14215
- id: "lighten-background",
14216
- name: "Lighten on Hover",
14217
- description: "Lightens the background color on hover",
14218
- category: "background",
14219
- pseudoElement: "none",
14220
- applicableTo: ["button"],
14221
- customizableOption: {
14222
- name: "amount",
14223
- type: "select",
14224
- label: "Lighten Amount (shade step)",
14225
- default: 100,
14226
- options: [
14227
- 0,
14228
- 100,
14229
- 200,
14230
- 300,
14231
- 400,
14232
- 500,
14233
- 600,
14234
- 700,
14235
- 800,
14236
- 900
14237
- ]
14238
- },
14239
- isApplicable: (buttonConfig) => {
14240
- return buttonConfig.background.type === "solid";
14241
- },
14242
- generateCSS: (ctx) => {
14243
- const { themeId, variantId, options, tokens, buttonConfig } = ctx;
14244
- if (buttonConfig.background.type !== "solid") return "";
14245
- const amount = options.amount || 100;
14246
- const baseToken = buttonConfig.background.colorToken ?? "primary-500";
14247
- const lighterToken = tokens.adjustShade(baseToken, -amount);
14248
- return `
14249
- :where([data-theme-scope="${themeId}"]) .${variantId}:hover {
14250
- background-color: ${tokens.getColor(lighterToken)};
14251
- }
14252
- `;
14253
- }
14254
- };
14255
- /**
14256
- * Fade background on hover (reduce opacity)
14257
- *
14258
- * Works with all background types.
14259
- */
14260
- const fadeBackgroundEffect = {
14261
- id: "fade-background",
14262
- name: "Fade on Hover",
14263
- description: "Reduces background opacity on hover",
14264
- category: "background",
14265
- pseudoElement: "none",
14266
- applicableTo: ["nav-link"],
14267
- customizableOption: {
14268
- name: "opacity",
14269
- type: "percentage",
14270
- label: "Hover Opacity",
14271
- default: 80
14272
- },
14273
- generateCSS: (ctx) => {
14274
- const { themeId, variantId, options } = ctx;
14275
- return `
14276
- :where([data-theme-scope="${themeId}"]) .${variantId}:hover {
14277
- opacity: ${(options.opacity || 80) / 100};
14278
- }
14279
- `;
14280
- }
14281
- };
14282
- /**
14283
- * Reduce opacity on hover (simple opacity reduction)
14284
- *
14285
- * Navigation-link effect that reduces opacity by a percentage (default 15%).
14286
- */
14287
- const opacityReduceEffect = {
14288
- id: "opacity-reduce",
14289
- name: "Reduce Opacity",
14290
- description: "Reduces navigation-link opacity on hover by a percentage",
14291
- category: "background",
14292
- pseudoElement: "none",
14293
- applicableTo: ["nav-link"],
14294
- customizableOption: {
14295
- name: "reduction",
14296
- type: "percentage",
14297
- label: "Opacity Reduction",
14298
- default: 15
14299
- },
14300
- generateCSS: (ctx) => {
14301
- const { themeId, variantId, options } = ctx;
14302
- return `
14303
- :where([data-theme-scope="${themeId}"]) .${variantId}:hover {
14304
- opacity: ${1 - (options.reduction || 15) / 100};
14305
- }
14306
- `;
14307
- }
14308
- };
14309
- /**
14310
- * Animated gradient background
14311
- *
14312
- * Animates a gradient background by shifting its position on hover.
14313
- * Works with gradient backgrounds only.
14314
- *
14315
- * Sets background-size to 200% and animates background-position from left to right.
14316
- */
14317
- const animatedGradientEffect = {
14318
- id: "animated-gradient",
14319
- name: "Animated Gradient",
14320
- description: "Animates gradient position on hover",
14321
- category: "background",
14322
- pseudoElement: "none",
14323
- applicableTo: ["button"],
14324
- customizableOption: {
14325
- name: "direction",
14326
- type: "select",
14327
- label: "Animation Direction",
14328
- default: "horizontal",
14329
- options: ["horizontal", "vertical"]
14330
- },
14331
- isApplicable: (buttonConfig) => {
14332
- return buttonConfig.background.type === "gradient";
14333
- },
14334
- generateCSS: (ctx) => {
14335
- const { themeId, variantId, options, buttonConfig } = ctx;
14336
- if (buttonConfig.background.type !== "gradient") return "";
14337
- const direction = options.direction || "horizontal";
14338
- return `
14339
- /* Setup animated gradient */
14340
- :where([data-theme-scope="${themeId}"]) .${variantId} {
14341
- background-size: ${direction === "horizontal" ? "200% auto" : "auto 200%"};
14342
- background-position: left center;
14343
- transition: background-position 0.3s ease;
14344
- }
14345
-
14346
- /* Animate gradient on hover */
14347
- :where([data-theme-scope="${themeId}"]) .${variantId}:hover {
14348
- background-position: ${direction === "horizontal" ? "right center" : "center bottom"};
14349
- }
14350
- `;
14351
- }
14352
- };
14353
- /**
14354
- * Add background color on hover
14355
- *
14356
- * Works best with transparent backgrounds. Adds a solid background color on hover.
14357
- */
14358
- const backgroundOnHoverEffect = {
14359
- id: "background-on-hover",
14360
- name: "Background on Hover",
14361
- description: "Adds background color on hover",
14362
- category: "background",
14363
- pseudoElement: "none",
14364
- applicableTo: ["button", "nav-link"],
14365
- customizableOption: {
14366
- name: "colorToken",
14367
- type: "select",
14368
- label: "Background Color",
14369
- default: "neutral-800",
14370
- options: [
14371
- "neutral-700",
14372
- "neutral-800",
14373
- "neutral-900",
14374
- "primary"
14375
- ]
14376
- },
14377
- generateCSS: (ctx) => {
14378
- const { themeId, variantId, options, tokens, buttonConfig } = ctx;
14379
- const colorToken = options.colorToken || "neutral-800";
14380
- return `
14381
- /* Add background on hover */
14382
- :where([data-theme-scope="${themeId}"]) .${variantId}:hover {
14383
- background-color: ${tokens.getColor(colorToken)};${"textColorToken" in buttonConfig && typeof options.textColorToken === "string" ? `\n color: ${tokens.getColor(options.textColorToken)};` : ""}
14384
- }
14385
- `;
14386
- }
14387
- };
14388
- /**
14389
- * Add semi-transparent background color on hover
14390
- *
14391
- * Adds a background with opacity/alpha channel. Perfect for retro/arcade styles.
14392
- */
14393
- const backgroundOnHoverAlphaEffect = {
14394
- id: "background-on-hover-alpha",
14395
- name: "Background on Hover (Transparent)",
14396
- description: "Adds semi-transparent background on hover",
14397
- category: "background",
14398
- pseudoElement: "none",
14399
- applicableTo: ["nav-link"],
14400
- customizableOption: {
14401
- name: "opacity",
14402
- type: "percentage",
14403
- label: "Opacity",
14404
- default: 50
14405
- },
14406
- generateCSS: (ctx) => {
14407
- const { themeId, variantId, stateGroup, options } = ctx;
14408
- const rawOpacity = options.opacity;
14409
- const clampedOpacity = Math.max(0, Math.min(100, typeof rawOpacity === "number" && !Number.isNaN(rawOpacity) ? rawOpacity : 50));
14410
- const cssVar = `var(--tb-${options.colorToken || "neutral-800"})`;
14411
- return `
14412
- /* Add semi-transparent background (${stateGroup}) */
14413
- :where([data-theme-scope="${themeId}"]) .${variantId}${stateGroup === "base" ? "" : `:${stateGroup}`} {
14414
- background-color: rgb(${cssVar} / ${clampedOpacity}%);
14415
- }
14416
- `;
14417
- }
14418
- };
14419
- //#endregion
14420
14071
  //#region ../theme-core/src/buttons/effects/cssUtils.ts
14421
14072
  /**
14422
14073
  * CSS Utilities for Effect Presets
@@ -14468,6 +14119,71 @@ function generateStateCSS(themeId, variantId, state, cssProperties) {
14468
14119
  `;
14469
14120
  }
14470
14121
  //#endregion
14122
+ //#region ../theme-core/src/buttons/effects/presets/background.ts
14123
+ /**
14124
+ * Darken background on hover
14125
+ *
14126
+ * Works with solid backgrounds only. Darkens the background color by adjusting the shade.
14127
+ */
14128
+ const darkenBackgroundEffect = shadeBackgroundEffect({
14129
+ id: "darken-background",
14130
+ name: "Darken on Hover",
14131
+ description: "Darkens the background color on hover",
14132
+ label: "Darken Amount (shade step)",
14133
+ shadeDirection: 1
14134
+ });
14135
+ /**
14136
+ * Lighten background on hover
14137
+ *
14138
+ * Works with solid backgrounds only. Lightens the background color by adjusting the shade.
14139
+ */
14140
+ const lightenBackgroundEffect = shadeBackgroundEffect({
14141
+ id: "lighten-background",
14142
+ name: "Lighten on Hover",
14143
+ description: "Lightens the background color on hover",
14144
+ label: "Lighten Amount (shade step)",
14145
+ shadeDirection: -1
14146
+ });
14147
+ function shadeBackgroundEffect(config) {
14148
+ return {
14149
+ id: config.id,
14150
+ name: config.name,
14151
+ description: config.description,
14152
+ category: "background",
14153
+ pseudoElement: "none",
14154
+ applicableTo: ["button"],
14155
+ customizableOption: {
14156
+ name: "amount",
14157
+ type: "select",
14158
+ label: config.label,
14159
+ default: 100,
14160
+ options: [
14161
+ 0,
14162
+ 100,
14163
+ 200,
14164
+ 300,
14165
+ 400,
14166
+ 500,
14167
+ 600,
14168
+ 700,
14169
+ 800,
14170
+ 900
14171
+ ]
14172
+ },
14173
+ isApplicable: (buttonConfig) => buttonConfig.background.type === "solid",
14174
+ generateCSS: ({ themeId, variantId, options, tokens, buttonConfig }) => {
14175
+ if (buttonConfig.background.type !== "solid") return "";
14176
+ const amount = (options.amount || 100) * config.shadeDirection;
14177
+ const baseToken = buttonConfig.background.colorToken ?? "primary-500";
14178
+ return `
14179
+ :where([data-theme-scope="${themeId}"]) .${variantId}:hover {
14180
+ background-color: ${tokens.getColor(tokens.adjustShade(baseToken, amount))};
14181
+ }
14182
+ `;
14183
+ }
14184
+ };
14185
+ }
14186
+ //#endregion
14471
14187
  //#region ../theme-core/src/buttons/effects/registry.ts
14472
14188
  /**
14473
14189
  * Registry of all available effect presets
@@ -14475,11 +14191,144 @@ function generateStateCSS(themeId, variantId, state, cssProperties) {
14475
14191
  const EFFECT_PRESETS = [
14476
14192
  darkenBackgroundEffect,
14477
14193
  lightenBackgroundEffect,
14478
- fadeBackgroundEffect,
14479
- opacityReduceEffect,
14480
- animatedGradientEffect,
14481
- backgroundOnHoverEffect,
14482
- backgroundOnHoverAlphaEffect,
14194
+ {
14195
+ id: "fade-background",
14196
+ name: "Fade on Hover",
14197
+ description: "Reduces background opacity on hover",
14198
+ category: "background",
14199
+ pseudoElement: "none",
14200
+ applicableTo: ["nav-link"],
14201
+ customizableOption: {
14202
+ name: "opacity",
14203
+ type: "percentage",
14204
+ label: "Hover Opacity",
14205
+ default: 80
14206
+ },
14207
+ generateCSS: (ctx) => {
14208
+ const { themeId, variantId, options } = ctx;
14209
+ return `
14210
+ :where([data-theme-scope="${themeId}"]) .${variantId}:hover {
14211
+ opacity: ${(options.opacity || 80) / 100};
14212
+ }
14213
+ `;
14214
+ }
14215
+ },
14216
+ {
14217
+ id: "opacity-reduce",
14218
+ name: "Reduce Opacity",
14219
+ description: "Reduces navigation-link opacity on hover by a percentage",
14220
+ category: "background",
14221
+ pseudoElement: "none",
14222
+ applicableTo: ["nav-link"],
14223
+ customizableOption: {
14224
+ name: "reduction",
14225
+ type: "percentage",
14226
+ label: "Opacity Reduction",
14227
+ default: 15
14228
+ },
14229
+ generateCSS: (ctx) => {
14230
+ const { themeId, variantId, options } = ctx;
14231
+ return `
14232
+ :where([data-theme-scope="${themeId}"]) .${variantId}:hover {
14233
+ opacity: ${1 - (options.reduction || 15) / 100};
14234
+ }
14235
+ `;
14236
+ }
14237
+ },
14238
+ {
14239
+ id: "animated-gradient",
14240
+ name: "Animated Gradient",
14241
+ description: "Animates gradient position on hover",
14242
+ category: "background",
14243
+ pseudoElement: "none",
14244
+ applicableTo: ["button"],
14245
+ customizableOption: {
14246
+ name: "direction",
14247
+ type: "select",
14248
+ label: "Animation Direction",
14249
+ default: "horizontal",
14250
+ options: ["horizontal", "vertical"]
14251
+ },
14252
+ isApplicable: (buttonConfig) => {
14253
+ return buttonConfig.background.type === "gradient";
14254
+ },
14255
+ generateCSS: (ctx) => {
14256
+ const { themeId, variantId, options, buttonConfig } = ctx;
14257
+ if (buttonConfig.background.type !== "gradient") return "";
14258
+ const direction = options.direction || "horizontal";
14259
+ return `
14260
+ /* Setup animated gradient */
14261
+ :where([data-theme-scope="${themeId}"]) .${variantId} {
14262
+ background-size: ${direction === "horizontal" ? "200% auto" : "auto 200%"};
14263
+ background-position: left center;
14264
+ transition: background-position 0.3s ease;
14265
+ }
14266
+
14267
+ /* Animate gradient on hover */
14268
+ :where([data-theme-scope="${themeId}"]) .${variantId}:hover {
14269
+ background-position: ${direction === "horizontal" ? "right center" : "center bottom"};
14270
+ }
14271
+ `;
14272
+ }
14273
+ },
14274
+ {
14275
+ id: "background-on-hover",
14276
+ name: "Background on Hover",
14277
+ description: "Adds background color on hover",
14278
+ category: "background",
14279
+ pseudoElement: "none",
14280
+ applicableTo: ["button", "nav-link"],
14281
+ customizableOption: {
14282
+ name: "colorToken",
14283
+ type: "select",
14284
+ label: "Background Color",
14285
+ default: "neutral-800",
14286
+ options: [
14287
+ "neutral-700",
14288
+ "neutral-800",
14289
+ "neutral-900",
14290
+ "primary"
14291
+ ]
14292
+ },
14293
+ generateCSS: (ctx) => {
14294
+ const { themeId, variantId, stateGroup, options, tokens, buttonConfig } = ctx;
14295
+ const colorToken = options.colorToken || "neutral-800";
14296
+ const color = tokens.getColor(colorToken);
14297
+ const navForeground = "textColorToken" in buttonConfig && typeof options.textColorToken === "string" ? `\n color: ${tokens.getColor(options.textColorToken)};` : "";
14298
+ return `
14299
+ /* Add background on hover */
14300
+ ${getStateSelector(themeId, variantId, stateGroup)} {
14301
+ background-color: ${color};${navForeground}
14302
+ }
14303
+ `;
14304
+ }
14305
+ },
14306
+ {
14307
+ id: "background-on-hover-alpha",
14308
+ name: "Background on Hover (Transparent)",
14309
+ description: "Adds semi-transparent background on hover",
14310
+ category: "background",
14311
+ pseudoElement: "none",
14312
+ applicableTo: ["nav-link"],
14313
+ customizableOption: {
14314
+ name: "opacity",
14315
+ type: "percentage",
14316
+ label: "Opacity",
14317
+ default: 50
14318
+ },
14319
+ generateCSS: (ctx) => {
14320
+ const { themeId, variantId, stateGroup, options } = ctx;
14321
+ const rawOpacity = options.opacity;
14322
+ const clampedOpacity = Math.max(0, Math.min(100, typeof rawOpacity === "number" && !Number.isNaN(rawOpacity) ? rawOpacity : 50));
14323
+ const cssVar = `var(--tb-${options.colorToken || "neutral-800"})`;
14324
+ return `
14325
+ /* Add semi-transparent background (${stateGroup}) */
14326
+ :where([data-theme-scope="${themeId}"]) .${variantId}${stateGroup === "base" ? "" : `:${stateGroup}`} {
14327
+ background-color: rgb(${cssVar} / ${clampedOpacity}%);
14328
+ }
14329
+ `;
14330
+ }
14331
+ },
14483
14332
  {
14484
14333
  id: "border-glow",
14485
14334
  name: "Border Glow",
@@ -17418,6 +17267,147 @@ function resolveOnColorForThemeToken(token) {
17418
17267
  return shade <= 400 ? "#000000" : "#FFFFFF";
17419
17268
  }
17420
17269
  //#endregion
17270
+ //#region ../theme-core/src/header/paintTargets.ts
17271
+ /** Resolve the element that owns the visible header surface for each layout. */
17272
+ function getHeaderPaintTargets(variant, themeId, state = "base") {
17273
+ const scope = `:where([data-theme-scope="${themeId}"])`;
17274
+ const scrolledRoot = state === "scrolled" ? ".header-root.header-scrolled " : "";
17275
+ if (variant === "floating") {
17276
+ if (state === "scrolled") {
17277
+ const desktopOwner = `${scope} ${scrolledRoot}.header-floating-container`;
17278
+ const mobileOwner = `${scope} ${scrolledRoot}.header-mobile-bar`;
17279
+ return [{
17280
+ kind: "viewport-band",
17281
+ clipSelector: `${scope}:has(.header-root.header-scrolled)`,
17282
+ ownerSelector: desktopOwner,
17283
+ selector: `${desktopOwner}::before`,
17284
+ mediaQuery: MQ_MD_UP,
17285
+ topExtension: {
17286
+ customProperty: "--rb-header-floating-top-gap",
17287
+ value: "1rem",
17288
+ ownerProperty: "top"
17289
+ },
17290
+ ownerNeedsPositioning: false
17291
+ }, {
17292
+ kind: "viewport-band",
17293
+ clipSelector: `${scope}:has(.header-root.header-scrolled)`,
17294
+ ownerSelector: mobileOwner,
17295
+ selector: `${mobileOwner}::before`,
17296
+ mediaQuery: MQ_MD_DOWN,
17297
+ topExtension: {
17298
+ customProperty: "--rb-header-floating-top-gap",
17299
+ value: "0.75rem",
17300
+ ownerProperty: "margin-top"
17301
+ },
17302
+ ownerNeedsPositioning: true
17303
+ }];
17304
+ }
17305
+ return [{
17306
+ kind: "element-box",
17307
+ selector: `${scope} ${scrolledRoot}.header-floating-container`,
17308
+ mediaQuery: MQ_MD_UP
17309
+ }, {
17310
+ kind: "element-box",
17311
+ selector: `${scope} ${scrolledRoot}.header-mobile-bar`,
17312
+ mediaQuery: MQ_MD_DOWN
17313
+ }];
17314
+ }
17315
+ return [{
17316
+ kind: "element-box",
17317
+ selector: `${scope} .header-root${state === "scrolled" ? ".header-scrolled" : ""}::before`,
17318
+ pseudoElement: "inset"
17319
+ }];
17320
+ }
17321
+ function renderHeaderPaintTargetRules(targets, rules) {
17322
+ return targets.map((target) => {
17323
+ const block = renderHeaderPaintTargetRule(target, rules);
17324
+ return target.mediaQuery ? `@media ${target.mediaQuery} {\n${block}\n}` : block;
17325
+ }).join("\n");
17326
+ }
17327
+ function renderHeaderPaintTargetRule(target, rules) {
17328
+ switch (target.kind) {
17329
+ case "element-box": {
17330
+ const pseudoElementSetup = target.pseudoElement === "inset" ? [
17331
+ "content: \"\";",
17332
+ "position: absolute;",
17333
+ "inset: 0;",
17334
+ "pointer-events: none;",
17335
+ "border-radius: inherit;",
17336
+ "z-index: -1;"
17337
+ ] : [];
17338
+ return `${target.selector} {\n ${[...pseudoElementSetup, ...rules].join("\n ")}\n}`;
17339
+ }
17340
+ case "viewport-band": {
17341
+ const gap = target.topExtension;
17342
+ const ownerRules = [
17343
+ `${gap.customProperty}: ${gap.value};`,
17344
+ `${gap.ownerProperty}: var(${gap.customProperty});`,
17345
+ ...target.ownerNeedsPositioning ? ["position: relative;"] : [],
17346
+ "isolation: isolate;",
17347
+ "background: none;",
17348
+ "backdrop-filter: none;",
17349
+ "-webkit-backdrop-filter: none;",
17350
+ "border: 0;",
17351
+ "box-shadow: none;"
17352
+ ];
17353
+ const bandRules = [
17354
+ "content: \"\";",
17355
+ "position: absolute;",
17356
+ `top: calc(-1 * var(${gap.customProperty}));`,
17357
+ "bottom: 0;",
17358
+ "left: 50%;",
17359
+ "width: 100vw;",
17360
+ "transform: translateX(-50%);",
17361
+ "pointer-events: none;",
17362
+ "border-radius: 0;",
17363
+ "z-index: -1;",
17364
+ ...rules
17365
+ ];
17366
+ return `${target.clipSelector} {\n overflow-x: clip;\n}\n${target.ownerSelector} {\n ${ownerRules.join("\n ")}\n}\n${target.selector} {\n ${bandRules.join("\n ")}\n}`;
17367
+ }
17368
+ }
17369
+ }
17370
+ //#endregion
17371
+ //#region ../theme-core/src/header/scrollTreatment.ts
17372
+ const headerScrollTreatmentSchema = z$1.discriminatedUnion("kind", [z$1.object({
17373
+ kind: z$1.literal("contrast-glass"),
17374
+ backgroundTone: z$1.enum(["light", "dark"])
17375
+ })]).optional();
17376
+ function generateMobileOverlayBackdropFilterFix(themeId, variant) {
17377
+ const root = `:where([data-theme-scope="${themeId}"]) .header-root:has([data-nav-mobile-overlay][aria-hidden="false"])`;
17378
+ return `\n${(variant === "floating" ? [`${root} .header-mobile-bar`, `${root} .header-mobile-bar::before`] : [`${root}::before`]).join(",\n")} {\n backdrop-filter: none !important;\n -webkit-backdrop-filter: none !important;\n}\n`;
17379
+ }
17380
+ function generateHeaderScrollTreatmentStyles(treatment, themeId, variant, surfaceRules = []) {
17381
+ if (!treatment) return "";
17382
+ switch (treatment.kind) {
17383
+ case "contrast-glass": {
17384
+ const backgroundChannels = treatment.backgroundTone === "dark" ? "0 0 0" : "255 255 255";
17385
+ return renderHeaderPaintTargetRules(getHeaderPaintTargets(variant, themeId, "scrolled"), [`background-color: rgb(${backgroundChannels} / 0.60);`, ...surfaceRules]);
17386
+ }
17387
+ }
17388
+ }
17389
+ //#endregion
17390
+ //#region ../theme-core/src/header/containerSchema.ts
17391
+ const headerContainerSchema = z$1.object({
17392
+ rounded: z$1.enum([
17393
+ "none",
17394
+ "sm",
17395
+ "md",
17396
+ "lg",
17397
+ "xl",
17398
+ "2xl"
17399
+ ]).default("xl"),
17400
+ border: z$1.boolean().default(true),
17401
+ shadow: z$1.boolean().default(true),
17402
+ padding: z$1.enum([
17403
+ "sm",
17404
+ "md",
17405
+ "lg"
17406
+ ]).default("md"),
17407
+ tint: z$1.string().nullable().optional(),
17408
+ opacity: z$1.number().min(0).max(1).default(.12)
17409
+ }).optional();
17410
+ //#endregion
17421
17411
  //#region ../theme-core/src/schema.ts
17422
17412
  const axesSchema = z$1.object({
17423
17413
  tone: z$1.enum([
@@ -17447,16 +17437,6 @@ const axesSchema = z$1.object({
17447
17437
  "expressive"
17448
17438
  ])
17449
17439
  });
17450
- const colourHexString = z$1.string().regex(/^#([0-9A-Fa-f]{3}){1,2}$/);
17451
- const paletteColorSchema = z$1.object({
17452
- name: z$1.string().min(1),
17453
- hex: colourHexString
17454
- });
17455
- const paletteMetaSchema = z$1.object({ mode: z$1.enum(["light", "dark"]) });
17456
- const paletteSchema = z$1.object({
17457
- colors: z$1.array(paletteColorSchema),
17458
- meta: paletteMetaSchema
17459
- });
17460
17440
  const typographyStyleSchema = z$1.object({
17461
17441
  family: z$1.string().min(1),
17462
17442
  weight: z$1.enum([
@@ -17588,7 +17568,7 @@ const boxBackgroundSchema = z$1.object({
17588
17568
  color: tokenOrCssColorValueSchema.nullable().optional(),
17589
17569
  gradient: z$1.string().nullable().optional(),
17590
17570
  gradientPresetId: z$1.string().min(1).nullable().optional(),
17591
- image: mediaSchema$1.nullable().optional(),
17571
+ image: mediaSchema.nullable().optional(),
17592
17572
  objectFit: z$1.enum([
17593
17573
  "fill",
17594
17574
  "fit",
@@ -17836,25 +17816,6 @@ const navFontWeight = z$1.enum([
17836
17816
  ]);
17837
17817
  const headerMaxWidth = z$1.enum(["container", "full"]);
17838
17818
  const headerBarFrame = z$1.enum(["full-bleed", "inset-shell"]);
17839
- const headerContainerSchema = z$1.object({
17840
- rounded: z$1.enum([
17841
- "none",
17842
- "sm",
17843
- "md",
17844
- "lg",
17845
- "xl",
17846
- "2xl"
17847
- ]).default("xl"),
17848
- border: z$1.boolean().default(true),
17849
- shadow: z$1.boolean().default(true),
17850
- padding: z$1.enum([
17851
- "sm",
17852
- "md",
17853
- "lg"
17854
- ]).default("md"),
17855
- tint: z$1.string().nullable().optional(),
17856
- opacity: z$1.number().min(0).max(1).default(.12)
17857
- }).optional();
17858
17819
  const headerBorderSchema = componentBorderSchema.extend({ position: z$1.enum([
17859
17820
  "bottom",
17860
17821
  "top",
@@ -17972,7 +17933,7 @@ const headerBackgroundSchema = z$1.object({
17972
17933
  contentOwner: z$1.literal(siteChromeBackgroundOverrideOwner).optional(),
17973
17934
  color: tokenOrCssColorValueSchema.nullable().optional(),
17974
17935
  gradient: gradientConfigSchema.nullable().optional(),
17975
- image: mediaSchema$1.nullable().optional(),
17936
+ image: mediaSchema.nullable().optional(),
17976
17937
  textColor: tokenOrCssColorValueSchema.nullable().optional()
17977
17938
  });
17978
17939
  const headerSchema = z$1.object({
@@ -17981,7 +17942,8 @@ const headerSchema = z$1.object({
17981
17942
  shrinkOnScroll: z$1.boolean(),
17982
17943
  maxWidth: headerMaxWidth,
17983
17944
  barFrame: headerBarFrame.optional(),
17984
- logoOverride: mediaSchema$1.nullable().optional(),
17945
+ scrollTreatment: headerScrollTreatmentSchema,
17946
+ logoOverride: mediaSchema.nullable().optional(),
17985
17947
  background: headerBackgroundSchema.default({
17986
17948
  type: "color",
17987
17949
  color: "surface"
@@ -17993,6 +17955,7 @@ const headerSchema = z$1.object({
17993
17955
  navFontRole: z$1.enum(["body", "heading"]).optional(),
17994
17956
  navTypography: z$1.enum(["body", "heading"]).optional(),
17995
17957
  navTextSize: navLinkStyleSchema.shape.textSize,
17958
+ interactionPalette: headerInteractionPaletteSchema.optional(),
17996
17959
  navPlacement: z$1.enum(["end", "center"]).optional(),
17997
17960
  container: headerContainerSchema,
17998
17961
  border: headerBorderSchema,
@@ -23469,15 +23432,6 @@ const heroCopyFragment = defineFragment({
23469
23432
  */
23470
23433
  const BLOCK_BUTTON_ROLES = PUBLIC_BUTTON_ROLES;
23471
23434
  const blockButtonRoleSchema = z$1.enum(BLOCK_BUTTON_ROLES);
23472
- /**
23473
- * Temporary rollout boundary for persisted content written before issue #1220.
23474
- * Authoring remains strict through `blockButtonRoleSchema`; this parser exists
23475
- * only until the post-deploy role rewrite has been audited in production.
23476
- */
23477
- function canonicalizePersistedBlockButtonRole(value) {
23478
- return value === "link" || value === "tertiary" ? "ghost" : value;
23479
- }
23480
- const persistedBlockButtonRoleSchema = z$1.preprocess((value) => typeof value === "string" ? canonicalizePersistedBlockButtonRole(value) : value, blockButtonRoleSchema);
23481
23435
  const BLOCK_BUTTON_ROLE_LABELS = {
23482
23436
  primary: "Primary",
23483
23437
  secondary: "Secondary",
@@ -28223,7 +28177,7 @@ function planSiteChromePlacement(positioning) {
28223
28177
  headerRootClassName: "rb-fixed rb-top-0 rb-left-0 rb-right-0",
28224
28178
  standaloneShellClassName: "fixed left-0 right-0 top-0 z-40 w-full"
28225
28179
  };
28226
- default: return assertNever$16(positioning);
28180
+ default: return assertNever$15(positioning);
28227
28181
  }
28228
28182
  }
28229
28183
  function splitSiteChromePlacementClasses(className) {
@@ -31251,84 +31205,6 @@ const weeklySlotAvailabilityBlockDefinition = {
31251
31205
  mode: "server"
31252
31206
  } }
31253
31207
  };
31254
- const PUBLIC_DOWNLOAD_MEDIA_TYPES = [
31255
- "document",
31256
- "spreadsheet",
31257
- "archive",
31258
- "audio"
31259
- ];
31260
- const hotspotSchema = z.object({
31261
- x: z.number().min(0).max(1),
31262
- y: z.number().min(0).max(1),
31263
- radius: z.number().optional()
31264
- });
31265
- const rotationSchema = z.union([
31266
- z.literal(0),
31267
- z.literal(90),
31268
- z.literal(180),
31269
- z.literal(270)
31270
- ]);
31271
- const rectSchema = z.tuple([
31272
- z.number(),
31273
- z.number(),
31274
- z.number(),
31275
- z.number()
31276
- ]);
31277
- const aspectCropSchema = z.object({
31278
- aspect: z.preprocess((value) => value == null ? void 0 : value, z.string().optional()),
31279
- rect: z.preprocess((value) => value == null ? void 0 : value, rectSchema.optional()),
31280
- hotspot: z.preprocess((value) => value == null ? void 0 : value, hotspotSchema.optional()),
31281
- rotation: z.preprocess((value) => value == null ? void 0 : value, rotationSchema.optional())
31282
- });
31283
- const transformSchema = z.object({
31284
- aspectCrops: z.preprocess((value) => {
31285
- if (!value || typeof value !== "object" || Array.isArray(value)) return;
31286
- return value;
31287
- }, z.record(z.string(), aspectCropSchema.catch({}))).optional(),
31288
- rect: rectSchema.optional(),
31289
- hotspot: hotspotSchema.optional(),
31290
- rotation: rotationSchema.optional()
31291
- });
31292
- const mediaPosterSchema = z.discriminatedUnion("tag", [z.object({
31293
- tag: z.literal("storage"),
31294
- assetId: z.string().optional(),
31295
- storageBucket: z.string().min(1),
31296
- storagePath: z.string().min(1)
31297
- }), z.object({
31298
- tag: z.literal("external-src"),
31299
- assetId: z.string().optional(),
31300
- src: z.string().url()
31301
- })]);
31302
- const mediaBaseSchema = z.object({
31303
- purpose: z.string().optional(),
31304
- placeholder: z.boolean().default(true).optional(),
31305
- assetId: z.string().optional(),
31306
- identifier: z.string().optional(),
31307
- src: z.string().optional(),
31308
- alt: z.string().optional(),
31309
- filename: z.string().optional(),
31310
- mimeType: z.string().optional(),
31311
- width: z.number().optional(),
31312
- height: z.number().optional(),
31313
- storageBucket: z.string().optional(),
31314
- storagePath: z.string().optional(),
31315
- poster: mediaPosterSchema.optional(),
31316
- transform: transformSchema.optional()
31317
- });
31318
- const imageMediaSchema = mediaBaseSchema.extend({ type: z.literal("image") });
31319
- const videoMediaSchema = mediaBaseSchema.extend({ type: z.literal("video") });
31320
- const audioMediaSchema = mediaBaseSchema.extend({ type: z.literal("audio") });
31321
- const documentMediaSchema = mediaBaseSchema.extend({ type: z.literal("document") });
31322
- const spreadsheetMediaSchema = mediaBaseSchema.extend({ type: z.literal("spreadsheet") });
31323
- const archiveMediaSchema = mediaBaseSchema.extend({ type: z.literal("archive") });
31324
- const mediaSchema = z.discriminatedUnion("type", [
31325
- imageMediaSchema,
31326
- videoMediaSchema,
31327
- audioMediaSchema,
31328
- documentMediaSchema,
31329
- spreadsheetMediaSchema,
31330
- archiveMediaSchema
31331
- ]);
31332
31208
  //#endregion
31333
31209
  //#region ../blocks/src/system/blocks/shared/bookingPaymentTerms.ts
31334
31210
  const bookingDepositRefundPolicySchema = z$1.enum(["refundable", "non_refundable"]);
@@ -31768,7 +31644,7 @@ const publicEventSchema = z$1.object({
31768
31644
  presentation: z$1.object({
31769
31645
  cardTitleOverride: z$1.string().nullable().optional(),
31770
31646
  summary: z$1.string().nullable().optional(),
31771
- image: mediaSchema.nullable().optional()
31647
+ image: mediaSchema$1.nullable().optional()
31772
31648
  }).optional(),
31773
31649
  slug: z$1.string(),
31774
31650
  path: z$1.string().nullable(),
@@ -32394,7 +32270,7 @@ function isEventCalendarListLayout(value) {
32394
32270
  //#region ../blocks/src/system/runtime/nodes/shared/contract-schemas.ts
32395
32271
  const previewStageSchema = z$1.enum(["preview", "published"]);
32396
32272
  const registrationButtonVariantSchema = blockButtonRoleSchema;
32397
- const eventButtonVariantSchema = persistedBlockButtonRoleSchema;
32273
+ const eventButtonVariantSchema = blockButtonRoleSchema;
32398
32274
  const eventLayoutSchema = z$1.enum(eventCalendarListLayoutValues);
32399
32275
  const eventCalendarDisplayModeSchema = z$1.enum(eventCalendarDisplayModeValues);
32400
32276
  const eventCalendarDefaultViewSchema = z$1.enum(eventCalendarDefaultViewValues);
@@ -38368,10 +38244,10 @@ function preferredPathsForSource(source) {
38368
38244
  case "workshop": return ["/workshops", "/workshop"];
38369
38245
  case "retreat": return ["/retreats", "/retreat"];
38370
38246
  case "performance": return ["/performances", "/performance"];
38371
- default: return assertNever$25(source.preset, "Unhandled offerings preview event preset");
38247
+ default: return assertNever$24(source.preset, "Unhandled offerings preview event preset");
38372
38248
  }
38373
38249
  case "course": return ["/courses", "/course"];
38374
- default: return assertNever$25(source, "Unhandled offerings preview source");
38250
+ default: return assertNever$24(source, "Unhandled offerings preview source");
38375
38251
  }
38376
38252
  }
38377
38253
  function normalizeRoutePath(value) {
@@ -42388,7 +42264,7 @@ const newsletterSignupBlockDefinition = {
42388
42264
  //#endregion
42389
42265
  //#region ../blocks/src/system/blocks/team-members.ts
42390
42266
  const ITEM_NAME = "member";
42391
- const teamMemberPhotoSchema = mediaSchema.refine((media) => media.type === "image", { message: "Team member photos must be image media" }).nullable();
42267
+ const teamMemberPhotoSchema = mediaSchema$1.refine((media) => media.type === "image", { message: "Team member photos must be image media" }).nullable();
42392
42268
  const teamMemberDataSchema = z$1.object({
42393
42269
  _type: z$1.literal("teamMember"),
42394
42270
  id: z$1.string(),
@@ -43963,7 +43839,7 @@ function getBlockDefinition(name) {
43963
43839
  //#endregion
43964
43840
  //#region ../blocks/src/system/helpers/backgroundMedia.ts
43965
43841
  function resolveBackgroundMedia(input) {
43966
- const parsedMedia = mediaSchema.safeParse(input.image);
43842
+ const parsedMedia = mediaSchema$1.safeParse(input.image);
43967
43843
  if (!parsedMedia.success) return null;
43968
43844
  switch (parsedMedia.data.type) {
43969
43845
  case "image":
@@ -45194,6 +45070,9 @@ function renderTrailingAffordanceIcon(affordance) {
45194
45070
  className: "rb-ml-2 rb-h-4 rb-w-4 rb-inline-block"
45195
45071
  });
45196
45072
  }
45073
+ function isMissingRequiredLink(linkRequired, resolvedHref) {
45074
+ return linkRequired && resolvedHref.length === 0;
45075
+ }
45197
45076
  const ButtonNode = ({ value, children, href, variantId = "primary", size = "md", disabled, type = "button", target, rel, linkRequired = false, trailingIcon, blockId: _blockId, blockKind: _blockKind, blockContent: _blockContent, fragmentRegistry: _fragmentRegistry, pathBase: _pathBase, className, ...rest }) => {
45198
45077
  const content = value ?? children;
45199
45078
  if (!content) {
@@ -45202,12 +45081,16 @@ const ButtonNode = ({ value, children, href, variantId = "primary", size = "md",
45202
45081
  }
45203
45082
  const affordanceIcon = renderTrailingAffordanceIcon(resolveButtonAffordance({ trailingIcon }));
45204
45083
  const resolvedHref = typeof href === "string" ? href.trim() : "";
45205
- if (linkRequired && resolvedHref.length === 0) {
45084
+ if (isMissingRequiredLink(linkRequired, resolvedHref)) {
45206
45085
  if (process.env.NODE_ENV === "development") console.warn("[ButtonNode] Missing href for link-required button");
45207
45086
  return null;
45208
45087
  }
45209
45088
  const extraClassName = affordanceIcon ? [className, AFFORDANCE_SUPPRESS_CLASS].filter(Boolean).join(" ") : className;
45210
- const resolvedVariantId = parseThemeButtonVariantId(canonicalizePersistedBlockButtonRole(variantId));
45089
+ const resolvedVariantId = parseThemeButtonVariantId(variantId);
45090
+ if (variantId && !resolvedVariantId) {
45091
+ console.error("[ButtonNode] Invalid button variant", { variantId });
45092
+ return null;
45093
+ }
45211
45094
  const combinedClassName = resolvedVariantId ? themeButtonClassName({
45212
45095
  variant: resolvedVariantId,
45213
45096
  size,
@@ -45336,8 +45219,9 @@ function iconForMediaType(type) {
45336
45219
  });
45337
45220
  }
45338
45221
  }
45339
- function normalizeButtonVariant(value) {
45340
- return isBlockButtonRole(value) ? value : "primary";
45222
+ function parseButtonVariant(value) {
45223
+ if (value === null || value === void 0) return "primary";
45224
+ return isBlockButtonRole(value) ? value : null;
45341
45225
  }
45342
45226
  function FileDownloadNode({ value, title, description, buttonLabel, buttonVariant, className }) {
45343
45227
  if (!value || !isDownloadableMediaType(value.type)) return null;
@@ -45347,7 +45231,11 @@ function FileDownloadNode({ value, title, description, buttonLabel, buttonVarian
45347
45231
  const heading = title?.trim() || filename;
45348
45232
  const body = description?.trim();
45349
45233
  const label = buttonLabel?.trim() || "Download";
45350
- const variant = normalizeButtonVariant(buttonVariant);
45234
+ const variant = parseButtonVariant(buttonVariant);
45235
+ if (!variant) {
45236
+ console.error("[FileDownloadNode] Invalid button variant", { buttonVariant });
45237
+ return null;
45238
+ }
45351
45239
  return /* @__PURE__ */ jsx("div", {
45352
45240
  className,
45353
45241
  children: /* @__PURE__ */ jsxs("div", {
@@ -46961,7 +46849,7 @@ function eventSeriesIdsForSubject(subject) {
46961
46849
  switch (subject.kind) {
46962
46850
  case "eventSeries": return [subject.eventSeriesId];
46963
46851
  case "eventOffering": return subject.availableEventSeriesIds;
46964
- default: return assertNever$25(subject);
46852
+ default: return assertNever$24(subject);
46965
46853
  }
46966
46854
  }
46967
46855
  //#endregion
@@ -47678,7 +47566,7 @@ function renderOfferingGroupItems(presentation, items, options) {
47678
47566
  children: items.map((item) => renderOfferingCompactItem(item, options))
47679
47567
  })
47680
47568
  });
47681
- default: return assertNever$25(presentation, "Unhandled offerings preview presentation");
47569
+ default: return assertNever$24(presentation, "Unhandled offerings preview presentation");
47682
47570
  }
47683
47571
  }
47684
47572
  function compareCoursesByNextSession(left, right) {
@@ -47723,7 +47611,7 @@ function featuredSummaryDetails(item) {
47723
47611
  const summary = deriveCourseScheduleSummary(item.course);
47724
47612
  return summary ? formatFeaturedSummary(summary, item.course.venue?.name ?? null) : null;
47725
47613
  }
47726
- default: return assertNever$25(item, "Unhandled offerings preview item");
47614
+ default: return assertNever$24(item, "Unhandled offerings preview item");
47727
47615
  }
47728
47616
  }
47729
47617
  function formatFeaturedSummary(summary, venue) {
@@ -47732,7 +47620,7 @@ function formatFeaturedSummary(summary, venue) {
47732
47620
  case "multi-day-span": return detailsFromOccurrences(summary.occurrence, summary.occurrence, venue, null, null, true);
47733
47621
  case "fixed-recurring-run": return detailsFromOccurrences(summary.first, summary.last, venue, summary.recurrenceLabel, null);
47734
47622
  case "irregular-multi-session-run": return detailsFromOccurrences(summary.first, summary.last, venue, null, `${summary.sessionCount} dates`);
47735
- default: return assertNever$25(summary, "Unhandled offerings preview schedule summary");
47623
+ default: return assertNever$24(summary, "Unhandled offerings preview schedule summary");
47736
47624
  }
47737
47625
  }
47738
47626
  function detailsFromOccurrences(first, last, venue, recurrence, sessionCount, spanUsesEndDate = false) {
@@ -48129,7 +48017,7 @@ function bookingActionContent(input) {
48129
48017
  children: input.buttonText
48130
48018
  });
48131
48019
  case "unavailable": return null;
48132
- default: return assertNever$25(input.booking);
48020
+ default: return assertNever$24(input.booking);
48133
48021
  }
48134
48022
  }
48135
48023
  function RecurringSchedule({ schedule, buttonText = "Book", buttonVariant = "primary", showVenue = true, emptyMessage = "Regular schedule details will be added shortly." }) {
@@ -50307,7 +50195,7 @@ function previewEditableTargetToPath(target) {
50307
50195
  case "current-entry-field":
50308
50196
  case "current-entry-metadata": return target.path;
50309
50197
  case "read-only": return;
50310
- default: return assertNever$25(target);
50198
+ default: return assertNever$24(target);
50311
50199
  }
50312
50200
  }
50313
50201
  function previewEditableTargetToFieldKey(target) {
@@ -51382,7 +51270,7 @@ function collectNestedPreviewFieldConstraintEntries(field, path) {
51382
51270
  case "text":
51383
51271
  case "time":
51384
51272
  case "url": return [];
51385
- default: return assertNever$25(field);
51273
+ default: return assertNever$24(field);
51386
51274
  }
51387
51275
  }
51388
51276
  function makeDefaultBlockComponent(args) {
@@ -52268,6 +52156,41 @@ function resolveColorTokenHex(theme, colorToken) {
52268
52156
  if (colorToken === "transparent") return null;
52269
52157
  return expandPalette(theme.palette)[colorToken] ?? null;
52270
52158
  }
52159
+ const NAV_DROPDOWN_CONTAINER_RAIL_CSS_RULES = [
52160
+ `min-width: 12rem;`,
52161
+ `width: max-content;`,
52162
+ `max-width: min(22rem, calc(100vw - 2rem));`,
52163
+ `transform: translateX(var(--nav-dropdown-shift-x, 0px));`
52164
+ ];
52165
+ //#endregion
52166
+ //#region ../theme-core/src/header/surfaceRules.ts
52167
+ /** Compile the visual surface declarations independently of paint geometry. */
52168
+ function buildHeaderSurfaceRules(header, tokens, blur) {
52169
+ const base = [];
52170
+ const scrolled = [];
52171
+ const background = header.background;
52172
+ if (background.type === "color") base.push(`background-color: ${tokens.getColor(background.color || "surface")};`);
52173
+ else if (background.type === "gradient" && background.gradient) {
52174
+ const stops = background.gradient.stops.map((stop) => tokens.getColor(stop.color)).join(", ");
52175
+ base.push(`background-image: linear-gradient(${background.gradient.angle ?? 180}deg, ${stops});`);
52176
+ }
52177
+ const blurRules = [`backdrop-filter: ${blur};`, `-webkit-backdrop-filter: ${blur};`];
52178
+ base.push(...blurRules);
52179
+ scrolled.push(...blurRules);
52180
+ const borderWidth = getComponentBorderWidthPx(header.border?.width ?? "none");
52181
+ if (!header.border || borderWidth === "0") return {
52182
+ base,
52183
+ scrolled,
52184
+ border: []
52185
+ };
52186
+ const color = rgbColorValue(header.border.colorToken?.trim() || "border");
52187
+ const style = header.border.style === "dashed" ? "dashed" : "solid";
52188
+ return {
52189
+ base,
52190
+ scrolled,
52191
+ border: header.border.position === "both" ? [`border-top: ${borderWidth} ${style} ${color};`, `border-bottom: ${borderWidth} ${style} ${color};`] : [`border-${header.border.position}: ${borderWidth} ${style} ${color};`]
52192
+ };
52193
+ }
52271
52194
  //#endregion
52272
52195
  //#region ../theme-core/src/navigation/presets.ts
52273
52196
  /**
@@ -52429,12 +52352,71 @@ function getNavLinkPreset(presetId) {
52429
52352
  return NAV_LINK_PRESETS[presetId];
52430
52353
  }
52431
52354
  Object.keys(NAV_LINK_PRESETS);
52432
- const NAV_DROPDOWN_CONTAINER_RAIL_CSS_RULES = [
52433
- `min-width: 12rem;`,
52434
- `width: max-content;`,
52435
- `max-width: min(22rem, calc(100vw - 2rem));`,
52436
- `transform: translateX(var(--nav-dropdown-shift-x, 0px));`
52437
- ];
52355
+ //#endregion
52356
+ //#region ../theme-core/src/header/legacyNavLinkStyle.ts
52357
+ function buildLegacyHeaderNavLinkStyle(header, contrastTreatment, navTextSize) {
52358
+ const navStyle = header.navStyle ?? "minimal";
52359
+ const basePreset = getNavLinkPreset(navStyle);
52360
+ if (!basePreset) return null;
52361
+ const style = {
52362
+ ...basePreset,
52363
+ fontWeight: header.navWeight ?? basePreset.fontWeight,
52364
+ colorToken: (header.navColor ?? header.textColor)?.trim() || basePreset.colorToken,
52365
+ ...contrastTreatment ? { contrastTreatment } : {},
52366
+ ...navTextSize ? { textSize: navTextSize } : {}
52367
+ };
52368
+ if (header.navWeight === "bold" && navStyle === "solid") style.textTransform = "uppercase";
52369
+ applyLegacyNavEffects(style, header);
52370
+ applyLegacyGlassTreatment(style, header, navStyle);
52371
+ return style;
52372
+ }
52373
+ function applyLegacyNavEffects(style, header) {
52374
+ if (!header.navEffects) return;
52375
+ const effects = style.effects = {
52376
+ ...style.effects,
52377
+ hover: [...style.effects?.hover ?? []],
52378
+ active: [...style.effects?.active ?? []]
52379
+ };
52380
+ if (header.navEffects.glow) effects.hover.push({
52381
+ effectId: "outer-glow",
52382
+ options: { spread: 5 }
52383
+ });
52384
+ if (header.navEffects.neumorphic) {
52385
+ effects.hover.push({
52386
+ effectId: "neumorphic-shadow",
52387
+ options: { mode: "pressed" }
52388
+ });
52389
+ effects.hover.push({
52390
+ effectId: "text-color-change",
52391
+ options: { hoverColorToken: "primary" }
52392
+ });
52393
+ }
52394
+ if (header.navEffects.underlineGradient) effects.hover.push({
52395
+ effectId: "border-bottom-grow",
52396
+ options: { origin: "center" }
52397
+ });
52398
+ }
52399
+ function applyLegacyGlassTreatment(style, header, navStyle) {
52400
+ if (header.navContainer?.type !== "glass" || navStyle !== "minimal") return;
52401
+ style.borderRadius = "full";
52402
+ style.effects = {
52403
+ ...style.effects,
52404
+ hover: glassStateEffects(10),
52405
+ active: glassStateEffects(18)
52406
+ };
52407
+ }
52408
+ function glassStateEffects(opacity) {
52409
+ return [{
52410
+ effectId: "background-on-hover-alpha",
52411
+ options: {
52412
+ colorToken: "neutral-50",
52413
+ opacity
52414
+ }
52415
+ }, {
52416
+ effectId: "text-color-change",
52417
+ options: { hoverColorToken: "neutral-50" }
52418
+ }];
52419
+ }
52438
52420
  //#endregion
52439
52421
  //#region ../theme-core/src/header/generateHeaderCss.ts
52440
52422
  const HEADER_BLUR = "blur(12px)";
@@ -52464,8 +52446,8 @@ function generateHeaderCss(options) {
52464
52446
  const cssChunks = [];
52465
52447
  const headerContrastTreatment = resolveHeaderContrastTreatment(header);
52466
52448
  const headerNavTextSize = resolveHeaderNavTextSize(header);
52467
- cssChunks.push(generateHeaderRootStyles(header, themeId, tokens, theme));
52468
- cssChunks.push(generateMobileOverlayBackdropFilterFix(themeId));
52449
+ cssChunks.push(generateHeaderRootStyles(header, themeId, tokens));
52450
+ cssChunks.push(generateMobileOverlayBackdropFilterFix(themeId, header.variant));
52469
52451
  cssChunks.push(generateLogoStyles({
52470
52452
  logo: header.logo,
52471
52453
  themeId,
@@ -52503,56 +52485,34 @@ function isClearSplitHeaderShape(header) {
52503
52485
  function isDetachedFloatingHeaderShape(header) {
52504
52486
  return header.variant === "floating" && !header.container;
52505
52487
  }
52506
- function generateMobileOverlayBackdropFilterFix(themeId) {
52507
- return `\n${`:where([data-theme-scope="${themeId}"]) .header-root:has([data-nav-mobile-overlay][aria-hidden="false"])::before`} {\n backdrop-filter: none !important;\n -webkit-backdrop-filter: none !important;\n}\n`;
52508
- }
52509
52488
  /**
52510
52489
  * Generate root header container styles
52511
52490
  */
52512
- function generateHeaderRootStyles(header, themeId, tokens, _theme) {
52491
+ function generateHeaderRootStyles(header, themeId, tokens) {
52513
52492
  const selector = `:where([data-theme-scope="${themeId}"]) .header-root`;
52514
- const backgroundSelector = `:where([data-theme-scope="${themeId}"]) .header-root::before`;
52515
52493
  const rules = [];
52516
- const backgroundRules = [];
52517
52494
  const navContainerType = header.navContainer?.type ?? "none";
52518
52495
  const isContainedNav = navContainerType === "pill" || navContainerType === "glass";
52519
52496
  rules.push("position: relative;");
52520
52497
  rules.push("isolation: isolate;");
52521
- if (!isContainedNav) {
52522
- const bg = header.background;
52523
- if (bg.type === "color") {
52524
- const bgColor = tokens.getColor(bg.color || "surface");
52525
- backgroundRules.push(`background-color: ${bgColor};`);
52526
- } else if (bg.type === "gradient" && bg.gradient) {
52527
- const stops = bg.gradient.stops.map((s) => tokens.getColor(s.color)).join(", ");
52528
- const angle = bg.gradient.angle ?? 180;
52529
- backgroundRules.push(`background-image: linear-gradient(${angle}deg, ${stops});`);
52530
- }
52531
- backgroundRules.push(`backdrop-filter: ${HEADER_BLUR};`);
52532
- backgroundRules.push(`-webkit-backdrop-filter: ${HEADER_BLUR};`);
52533
- if (header.border) {
52534
- const borderWidth = getComponentBorderWidthPx(header.border.width);
52535
- if (borderWidth !== "0") {
52536
- const borderToken = header.border?.colorToken?.trim() || "border";
52537
- const borderColor = tokens.getColor(borderToken);
52538
- const borderStyle = header.border.style === "dashed" ? "dashed" : "solid";
52539
- if (header.border.position === "bottom") rules.push(`border-bottom: ${borderWidth} ${borderStyle} ${borderColor};`);
52540
- else if (header.border.position === "top") rules.push(`border-top: ${borderWidth} ${borderStyle} ${borderColor};`);
52541
- else if (header.border.position === "both") {
52542
- rules.push(`border-top: ${borderWidth} ${borderStyle} ${borderColor};`);
52543
- rules.push(`border-bottom: ${borderWidth} ${borderStyle} ${borderColor};`);
52544
- }
52545
- }
52546
- }
52547
- }
52498
+ const surfaceRules = isContainedNav ? {
52499
+ base: [],
52500
+ scrolled: [],
52501
+ border: []
52502
+ } : buildHeaderSurfaceRules(header, tokens, HEADER_BLUR);
52503
+ const floatingSurfaceBorder = header.variant === "floating";
52504
+ if (!floatingSurfaceBorder) rules.push(...surfaceRules.border);
52505
+ const basePaintRules = floatingSurfaceBorder ? [...surfaceRules.base, ...surfaceRules.border] : surfaceRules.base;
52506
+ const scrolledPaintRules = floatingSurfaceBorder ? [...surfaceRules.scrolled, ...surfaceRules.border] : surfaceRules.scrolled;
52548
52507
  if (header.positioning === "sticky" || header.positioning === "fixed") {
52549
52508
  const shadowVar = getComponentShadowVar(header.shadow?.elevation ?? "none");
52550
52509
  if (shadowVar) rules.push(`box-shadow: ${shadowVar};`);
52551
52510
  }
52552
52511
  const baseBlock = `\n${selector} {\n ${rules.join("\n ")}\n}\n`;
52553
52512
  const overlayFix = `\n${`${selector}:has([data-nav-mobile-overlay][aria-hidden="false"])`} {\n backdrop-filter: none !important;\n -webkit-backdrop-filter: none !important;\n}\n`;
52554
- if (isContainedNav || backgroundRules.length === 0) return `${baseBlock}\n${overlayFix}`;
52555
- return `${baseBlock}\n${`\n${backgroundSelector} {\n content: \"\";\n position: absolute;\n inset: 0;\n pointer-events: none;\n border-radius: inherit;\n z-index: -1;\n ${backgroundRules.join("\n ")}\n}\n`}\n${overlayFix}${usesInsetShell(header) ? generateInsetShellStyles(header, themeId) : ""}`;
52513
+ const scrollTreatmentStyles = generateHeaderScrollTreatmentStyles(header.scrollTreatment, themeId, header.variant, scrolledPaintRules);
52514
+ if (isContainedNav || basePaintRules.length === 0) return `${baseBlock}\n${overlayFix}${scrollTreatmentStyles}`;
52515
+ return `${baseBlock}\n${renderHeaderPaintTargetRules(getHeaderPaintTargets(header.variant, themeId), basePaintRules)}\n${overlayFix}${usesInsetShell(header) ? generateInsetShellStyles(header, themeId) : ""}${scrollTreatmentStyles}`;
52556
52516
  }
52557
52517
  /**
52558
52518
  * Reshapes the full-bleed header paint layer into a contained brand capsule at
@@ -52597,10 +52557,10 @@ function generateLogoStyles(input) {
52597
52557
  else rules.push(`font-family: var(--font-heading);`);
52598
52558
  if (logo) {
52599
52559
  if (logo.letterSpacing && logo.letterSpacing !== "normal") rules.push(`letter-spacing: ${{
52600
- "normal": "0em",
52601
- "wide": "0.05em",
52602
- "wider": "0.1em",
52603
- "widest": "0.15em"
52560
+ normal: "0em",
52561
+ wide: "0.05em",
52562
+ wider: "0.1em",
52563
+ widest: "0.15em"
52604
52564
  }[logo.letterSpacing]};`);
52605
52565
  if (logo.gradient) {
52606
52566
  rules.push(`background: linear-gradient(to right, ${primaryColor}, ${accentColor});`);
@@ -52673,71 +52633,11 @@ function generateNavLinkStyles(header, themeId, tokens, theme, contrastTreatment
52673
52633
  } : header.navLinkStyle, navPreferences),
52674
52634
  className: "header-nav-link"
52675
52635
  });
52676
- const navStyle = header.navStyle ?? "minimal";
52677
- const basePreset = getNavLinkPreset(navStyle);
52678
- if (!basePreset) {
52679
- console.warn(`[generateHeaderCss] Nav link preset not found: ${navStyle}`);
52636
+ const mergedStyle = buildLegacyHeaderNavLinkStyle(header, contrastTreatment, navTextSize);
52637
+ if (!mergedStyle) {
52638
+ console.warn(`[generateHeaderCss] Nav link preset not found: ${header.navStyle}`);
52680
52639
  return "";
52681
52640
  }
52682
- const mergedStyle = {
52683
- ...basePreset,
52684
- fontWeight: header.navWeight ?? basePreset.fontWeight,
52685
- colorToken: (header.navColor ?? header.textColor)?.trim() || basePreset.colorToken,
52686
- ...contrastTreatment ? { contrastTreatment } : {},
52687
- ...navTextSize ? { textSize: navTextSize } : {}
52688
- };
52689
- if (header.navWeight === "bold" && navStyle === "solid") mergedStyle.textTransform = "uppercase";
52690
- if (header.navEffects) {
52691
- const effects = mergedStyle.effects = {
52692
- ...mergedStyle.effects,
52693
- hover: [...mergedStyle.effects?.hover || []],
52694
- active: [...mergedStyle.effects?.active || []]
52695
- };
52696
- if (header.navEffects.glow) effects.hover.push({
52697
- effectId: "outer-glow",
52698
- options: { spread: 5 }
52699
- });
52700
- if (header.navEffects.neumorphic) {
52701
- effects.hover.push({
52702
- effectId: "neumorphic-shadow",
52703
- options: { mode: "pressed" }
52704
- });
52705
- effects.hover.push({
52706
- effectId: "text-color-change",
52707
- options: { hoverColorToken: "primary" }
52708
- });
52709
- }
52710
- if (header.navEffects.underlineGradient) effects.hover.push({
52711
- effectId: "border-bottom-grow",
52712
- options: { origin: "center" }
52713
- });
52714
- }
52715
- if ((header.navContainer?.type ?? "none") === "glass" && navStyle === "minimal") {
52716
- mergedStyle.borderRadius = "full";
52717
- mergedStyle.effects = {
52718
- ...mergedStyle.effects,
52719
- hover: [{
52720
- effectId: "background-on-hover-alpha",
52721
- options: {
52722
- colorToken: "neutral-50",
52723
- opacity: 10
52724
- }
52725
- }, {
52726
- effectId: "text-color-change",
52727
- options: { hoverColorToken: "neutral-50" }
52728
- }],
52729
- active: [{
52730
- effectId: "background-on-hover-alpha",
52731
- options: {
52732
- colorToken: "neutral-50",
52733
- opacity: 18
52734
- }
52735
- }, {
52736
- effectId: "text-color-change",
52737
- options: { hoverColorToken: "neutral-50" }
52738
- }]
52739
- };
52740
- }
52741
52641
  return generateNavLinkCSS({
52742
52642
  themeId,
52743
52643
  tokens,
@@ -52765,10 +52665,10 @@ function generateDropdownContainerStyles(header, themeId, tokens) {
52765
52665
  if (shadowVar) rules.push(`box-shadow: ${shadowVar};`);
52766
52666
  const borderRadius = dropdownStyle?.borderRadius ?? "md";
52767
52667
  rules.push(`border-radius: ${{
52768
- "none": "0",
52769
- "sm": "0.25rem",
52770
- "md": "0.5rem",
52771
- "lg": "0.75rem"
52668
+ none: "0",
52669
+ sm: "0.25rem",
52670
+ md: "0.5rem",
52671
+ lg: "0.75rem"
52772
52672
  }[borderRadius]};`);
52773
52673
  rules.push(`padding: 0.5rem 0;`);
52774
52674
  return `\n${selector} {\n ${rules.join("\n ")}\n}\n`;
@@ -52823,16 +52723,16 @@ function generateDropdownLinkStyles(header, themeId, tokens, theme) {
52823
52723
  const additionalRules = [];
52824
52724
  const letterSpacing = configuredDropdownStyle?.letterSpacing ?? "normal";
52825
52725
  if (letterSpacing !== "normal") additionalRules.push(`letter-spacing: ${{
52826
- "normal": "0em",
52827
- "wide": "0.05em",
52828
- "wider": "0.1em"
52726
+ normal: "0em",
52727
+ wide: "0.05em",
52728
+ wider: "0.1em"
52829
52729
  }[letterSpacing]};`);
52830
52730
  const textSize = configuredDropdownStyle?.textSize ?? "sm";
52831
52731
  additionalRules.push(`font-size: ${{
52832
- "xs": "0.75rem",
52833
- "sm": "0.875rem",
52834
- "base": "1rem",
52835
- "lg": "1.125rem"
52732
+ xs: "0.75rem",
52733
+ sm: "0.875rem",
52734
+ base: "1rem",
52735
+ lg: "1.125rem"
52836
52736
  }[textSize]};`);
52837
52737
  if (additionalRules.length > 0) return baseCSS + `\n${`:where([data-theme-scope="${themeId}"]) .nav-dropdown-link`} {\n ${additionalRules.join("\n ")}\n}\n`;
52838
52738
  return baseCSS;
@@ -52928,18 +52828,18 @@ function generateFloatingContainerStyles(header, themeId, tokens) {
52928
52828
  rules.push(`-webkit-backdrop-filter: ${FLOATING_BLUR};`);
52929
52829
  if (container.border) rules.push(`border: 1px solid rgb(255 255 255 / 0.2);`);
52930
52830
  rules.push(`border-radius: ${{
52931
- "none": "0",
52932
- "sm": "0.375rem",
52933
- "md": "0.5rem",
52934
- "lg": "0.75rem",
52935
- "xl": "1rem",
52831
+ none: "0",
52832
+ sm: "0.375rem",
52833
+ md: "0.5rem",
52834
+ lg: "0.75rem",
52835
+ xl: "1rem",
52936
52836
  "2xl": "1.5rem"
52937
52837
  }[container.rounded]};`);
52938
52838
  if (container.shadow) rules.push(`box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);`);
52939
52839
  rules.push(`padding: ${{
52940
- "sm": "1rem 1.5rem",
52941
- "md": "1.5rem 2rem",
52942
- "lg": "2rem 2.5rem"
52840
+ sm: "1rem 1.5rem",
52841
+ md: "1.5rem 2rem",
52842
+ lg: "2rem 2.5rem"
52943
52843
  }[container.padding]};`);
52944
52844
  return `\n${selector} {\n ${rules.join("\n ")}\n}\n`;
52945
52845
  }
@@ -55537,7 +55437,7 @@ function sourceLabel(source) {
55537
55437
  case "managed-database": return "DB";
55538
55438
  case "sdk-synced": return "SDK-synced DB";
55539
55439
  case "sdk-config": return "SDK config";
55540
- default: return assertNever$25(source);
55440
+ default: return assertNever$24(source);
55541
55441
  }
55542
55442
  }
55543
55443
  //#endregion
@@ -69284,7 +69184,7 @@ function renderWithSdkThemeRuntime({ themeRuntime, theme, children }) {
69284
69184
  children
69285
69185
  });
69286
69186
  case "none": return /* @__PURE__ */ jsx(Fragment, { children });
69287
- default: return assertNever$25(themeRuntime);
69187
+ default: return assertNever$24(themeRuntime);
69288
69188
  }
69289
69189
  }
69290
69190
  //#endregion
@@ -71710,7 +71610,7 @@ function navigationAuthoringLinkToCommandLink(link) {
71710
71610
  badge: link.badge,
71711
71611
  label: link.label
71712
71612
  };
71713
- default: return assertNever$25(link);
71613
+ default: return assertNever$24(link);
71714
71614
  }
71715
71615
  }
71716
71616
  function portalLabelsForCommand(labels) {
@@ -71753,7 +71653,7 @@ function navigationReadLinkToLocalLink(item) {
71753
71653
  badge: link.badge,
71754
71654
  label: link.label
71755
71655
  };
71756
- default: return assertNever$25(link);
71656
+ default: return assertNever$24(link);
71757
71657
  }
71758
71658
  }
71759
71659
  function internalNavigationLinkToLocalLink(item) {