@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);
@@ -38591,10 +38467,10 @@ function preferredPathsForSource(source) {
38591
38467
  case "workshop": return ["/workshops", "/workshop"];
38592
38468
  case "retreat": return ["/retreats", "/retreat"];
38593
38469
  case "performance": return ["/performances", "/performance"];
38594
- default: return assertNever$25(source.preset, "Unhandled offerings preview event preset");
38470
+ default: return assertNever$24(source.preset, "Unhandled offerings preview event preset");
38595
38471
  }
38596
38472
  case "course": return ["/courses", "/course"];
38597
- default: return assertNever$25(source, "Unhandled offerings preview source");
38473
+ default: return assertNever$24(source, "Unhandled offerings preview source");
38598
38474
  }
38599
38475
  }
38600
38476
  function normalizeRoutePath(value) {
@@ -42631,7 +42507,7 @@ const newsletterSignupBlockDefinition = {
42631
42507
  //#endregion
42632
42508
  //#region ../blocks/src/system/blocks/team-members.ts
42633
42509
  const ITEM_NAME = "member";
42634
- const teamMemberPhotoSchema = mediaSchema.refine((media) => media.type === "image", { message: "Team member photos must be image media" }).nullable();
42510
+ const teamMemberPhotoSchema = mediaSchema$1.refine((media) => media.type === "image", { message: "Team member photos must be image media" }).nullable();
42635
42511
  const teamMemberDataSchema = z$1.object({
42636
42512
  _type: z$1.literal("teamMember"),
42637
42513
  id: z$1.string(),
@@ -44206,7 +44082,7 @@ function getBlockDefinition(name) {
44206
44082
  //#endregion
44207
44083
  //#region ../blocks/src/system/helpers/backgroundMedia.ts
44208
44084
  function resolveBackgroundMedia(input) {
44209
- const parsedMedia = mediaSchema.safeParse(input.image);
44085
+ const parsedMedia = mediaSchema$1.safeParse(input.image);
44210
44086
  if (!parsedMedia.success) return null;
44211
44087
  switch (parsedMedia.data.type) {
44212
44088
  case "image":
@@ -44744,7 +44620,7 @@ function resolveLinkedContentEditSupport(contentType) {
44744
44620
  kind: "unsupported-domain-backed",
44745
44621
  reason: metadata.reason
44746
44622
  };
44747
- default: return assertNever$25(metadata);
44623
+ default: return assertNever$24(metadata);
44748
44624
  }
44749
44625
  }
44750
44626
  function contentTypeKeyToLabel(key) {
@@ -45574,6 +45450,9 @@ function renderTrailingAffordanceIcon(affordance) {
45574
45450
  className: "rb-ml-2 rb-h-4 rb-w-4 rb-inline-block"
45575
45451
  });
45576
45452
  }
45453
+ function isMissingRequiredLink(linkRequired, resolvedHref) {
45454
+ return linkRequired && resolvedHref.length === 0;
45455
+ }
45577
45456
  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 }) => {
45578
45457
  const content = value ?? children;
45579
45458
  if (!content) {
@@ -45582,12 +45461,16 @@ const ButtonNode = ({ value, children, href, variantId = "primary", size = "md",
45582
45461
  }
45583
45462
  const affordanceIcon = renderTrailingAffordanceIcon(resolveButtonAffordance({ trailingIcon }));
45584
45463
  const resolvedHref = typeof href === "string" ? href.trim() : "";
45585
- if (linkRequired && resolvedHref.length === 0) {
45464
+ if (isMissingRequiredLink(linkRequired, resolvedHref)) {
45586
45465
  if (process.env.NODE_ENV === "development") console.warn("[ButtonNode] Missing href for link-required button");
45587
45466
  return null;
45588
45467
  }
45589
45468
  const extraClassName = affordanceIcon ? [className, AFFORDANCE_SUPPRESS_CLASS].filter(Boolean).join(" ") : className;
45590
- const resolvedVariantId = parseThemeButtonVariantId(canonicalizePersistedBlockButtonRole(variantId));
45469
+ const resolvedVariantId = parseThemeButtonVariantId(variantId);
45470
+ if (variantId && !resolvedVariantId) {
45471
+ console.error("[ButtonNode] Invalid button variant", { variantId });
45472
+ return null;
45473
+ }
45591
45474
  const combinedClassName = resolvedVariantId ? themeButtonClassName({
45592
45475
  variant: resolvedVariantId,
45593
45476
  size,
@@ -45716,8 +45599,9 @@ function iconForMediaType(type) {
45716
45599
  });
45717
45600
  }
45718
45601
  }
45719
- function normalizeButtonVariant(value) {
45720
- return isBlockButtonRole(value) ? value : "primary";
45602
+ function parseButtonVariant(value) {
45603
+ if (value === null || value === void 0) return "primary";
45604
+ return isBlockButtonRole(value) ? value : null;
45721
45605
  }
45722
45606
  function FileDownloadNode({ value, title, description, buttonLabel, buttonVariant, className }) {
45723
45607
  if (!value || !isDownloadableMediaType(value.type)) return null;
@@ -45727,7 +45611,11 @@ function FileDownloadNode({ value, title, description, buttonLabel, buttonVarian
45727
45611
  const heading = title?.trim() || filename;
45728
45612
  const body = description?.trim();
45729
45613
  const label = buttonLabel?.trim() || "Download";
45730
- const variant = normalizeButtonVariant(buttonVariant);
45614
+ const variant = parseButtonVariant(buttonVariant);
45615
+ if (!variant) {
45616
+ console.error("[FileDownloadNode] Invalid button variant", { buttonVariant });
45617
+ return null;
45618
+ }
45731
45619
  return /* @__PURE__ */ jsx("div", {
45732
45620
  className,
45733
45621
  children: /* @__PURE__ */ jsxs("div", {
@@ -47341,7 +47229,7 @@ function eventSeriesIdsForSubject(subject) {
47341
47229
  switch (subject.kind) {
47342
47230
  case "eventSeries": return [subject.eventSeriesId];
47343
47231
  case "eventOffering": return subject.availableEventSeriesIds;
47344
- default: return assertNever$25(subject);
47232
+ default: return assertNever$24(subject);
47345
47233
  }
47346
47234
  }
47347
47235
  //#endregion
@@ -48058,7 +47946,7 @@ function renderOfferingGroupItems(presentation, items, options) {
48058
47946
  children: items.map((item) => renderOfferingCompactItem(item, options))
48059
47947
  })
48060
47948
  });
48061
- default: return assertNever$25(presentation, "Unhandled offerings preview presentation");
47949
+ default: return assertNever$24(presentation, "Unhandled offerings preview presentation");
48062
47950
  }
48063
47951
  }
48064
47952
  function compareCoursesByNextSession(left, right) {
@@ -48103,7 +47991,7 @@ function featuredSummaryDetails(item) {
48103
47991
  const summary = deriveCourseScheduleSummary(item.course);
48104
47992
  return summary ? formatFeaturedSummary(summary, item.course.venue?.name ?? null) : null;
48105
47993
  }
48106
- default: return assertNever$25(item, "Unhandled offerings preview item");
47994
+ default: return assertNever$24(item, "Unhandled offerings preview item");
48107
47995
  }
48108
47996
  }
48109
47997
  function formatFeaturedSummary(summary, venue) {
@@ -48112,7 +48000,7 @@ function formatFeaturedSummary(summary, venue) {
48112
48000
  case "multi-day-span": return detailsFromOccurrences(summary.occurrence, summary.occurrence, venue, null, null, true);
48113
48001
  case "fixed-recurring-run": return detailsFromOccurrences(summary.first, summary.last, venue, summary.recurrenceLabel, null);
48114
48002
  case "irregular-multi-session-run": return detailsFromOccurrences(summary.first, summary.last, venue, null, `${summary.sessionCount} dates`);
48115
- default: return assertNever$25(summary, "Unhandled offerings preview schedule summary");
48003
+ default: return assertNever$24(summary, "Unhandled offerings preview schedule summary");
48116
48004
  }
48117
48005
  }
48118
48006
  function detailsFromOccurrences(first, last, venue, recurrence, sessionCount, spanUsesEndDate = false) {
@@ -48509,7 +48397,7 @@ function bookingActionContent(input) {
48509
48397
  children: input.buttonText
48510
48398
  });
48511
48399
  case "unavailable": return null;
48512
- default: return assertNever$25(input.booking);
48400
+ default: return assertNever$24(input.booking);
48513
48401
  }
48514
48402
  }
48515
48403
  function RecurringSchedule({ schedule, buttonText = "Book", buttonVariant = "primary", showVenue = true, emptyMessage = "Regular schedule details will be added shortly." }) {
@@ -50687,7 +50575,7 @@ function previewEditableTargetToPath(target) {
50687
50575
  case "current-entry-field":
50688
50576
  case "current-entry-metadata": return target.path;
50689
50577
  case "read-only": return;
50690
- default: return assertNever$25(target);
50578
+ default: return assertNever$24(target);
50691
50579
  }
50692
50580
  }
50693
50581
  function previewEditableTargetToFieldKey(target) {
@@ -51762,7 +51650,7 @@ function collectNestedPreviewFieldConstraintEntries(field, path) {
51762
51650
  case "text":
51763
51651
  case "time":
51764
51652
  case "url": return [];
51765
- default: return assertNever$25(field);
51653
+ default: return assertNever$24(field);
51766
51654
  }
51767
51655
  }
51768
51656
  function makeDefaultBlockComponent(args) {
@@ -52648,6 +52536,41 @@ function resolveColorTokenHex(theme, colorToken) {
52648
52536
  if (colorToken === "transparent") return null;
52649
52537
  return expandPalette(theme.palette)[colorToken] ?? null;
52650
52538
  }
52539
+ const NAV_DROPDOWN_CONTAINER_RAIL_CSS_RULES = [
52540
+ `min-width: 12rem;`,
52541
+ `width: max-content;`,
52542
+ `max-width: min(22rem, calc(100vw - 2rem));`,
52543
+ `transform: translateX(var(--nav-dropdown-shift-x, 0px));`
52544
+ ];
52545
+ //#endregion
52546
+ //#region ../theme-core/src/header/surfaceRules.ts
52547
+ /** Compile the visual surface declarations independently of paint geometry. */
52548
+ function buildHeaderSurfaceRules(header, tokens, blur) {
52549
+ const base = [];
52550
+ const scrolled = [];
52551
+ const background = header.background;
52552
+ if (background.type === "color") base.push(`background-color: ${tokens.getColor(background.color || "surface")};`);
52553
+ else if (background.type === "gradient" && background.gradient) {
52554
+ const stops = background.gradient.stops.map((stop) => tokens.getColor(stop.color)).join(", ");
52555
+ base.push(`background-image: linear-gradient(${background.gradient.angle ?? 180}deg, ${stops});`);
52556
+ }
52557
+ const blurRules = [`backdrop-filter: ${blur};`, `-webkit-backdrop-filter: ${blur};`];
52558
+ base.push(...blurRules);
52559
+ scrolled.push(...blurRules);
52560
+ const borderWidth = getComponentBorderWidthPx(header.border?.width ?? "none");
52561
+ if (!header.border || borderWidth === "0") return {
52562
+ base,
52563
+ scrolled,
52564
+ border: []
52565
+ };
52566
+ const color = rgbColorValue(header.border.colorToken?.trim() || "border");
52567
+ const style = header.border.style === "dashed" ? "dashed" : "solid";
52568
+ return {
52569
+ base,
52570
+ scrolled,
52571
+ border: header.border.position === "both" ? [`border-top: ${borderWidth} ${style} ${color};`, `border-bottom: ${borderWidth} ${style} ${color};`] : [`border-${header.border.position}: ${borderWidth} ${style} ${color};`]
52572
+ };
52573
+ }
52651
52574
  //#endregion
52652
52575
  //#region ../theme-core/src/navigation/presets.ts
52653
52576
  /**
@@ -52809,12 +52732,71 @@ function getNavLinkPreset(presetId) {
52809
52732
  return NAV_LINK_PRESETS[presetId];
52810
52733
  }
52811
52734
  Object.keys(NAV_LINK_PRESETS);
52812
- const NAV_DROPDOWN_CONTAINER_RAIL_CSS_RULES = [
52813
- `min-width: 12rem;`,
52814
- `width: max-content;`,
52815
- `max-width: min(22rem, calc(100vw - 2rem));`,
52816
- `transform: translateX(var(--nav-dropdown-shift-x, 0px));`
52817
- ];
52735
+ //#endregion
52736
+ //#region ../theme-core/src/header/legacyNavLinkStyle.ts
52737
+ function buildLegacyHeaderNavLinkStyle(header, contrastTreatment, navTextSize) {
52738
+ const navStyle = header.navStyle ?? "minimal";
52739
+ const basePreset = getNavLinkPreset(navStyle);
52740
+ if (!basePreset) return null;
52741
+ const style = {
52742
+ ...basePreset,
52743
+ fontWeight: header.navWeight ?? basePreset.fontWeight,
52744
+ colorToken: (header.navColor ?? header.textColor)?.trim() || basePreset.colorToken,
52745
+ ...contrastTreatment ? { contrastTreatment } : {},
52746
+ ...navTextSize ? { textSize: navTextSize } : {}
52747
+ };
52748
+ if (header.navWeight === "bold" && navStyle === "solid") style.textTransform = "uppercase";
52749
+ applyLegacyNavEffects(style, header);
52750
+ applyLegacyGlassTreatment(style, header, navStyle);
52751
+ return style;
52752
+ }
52753
+ function applyLegacyNavEffects(style, header) {
52754
+ if (!header.navEffects) return;
52755
+ const effects = style.effects = {
52756
+ ...style.effects,
52757
+ hover: [...style.effects?.hover ?? []],
52758
+ active: [...style.effects?.active ?? []]
52759
+ };
52760
+ if (header.navEffects.glow) effects.hover.push({
52761
+ effectId: "outer-glow",
52762
+ options: { spread: 5 }
52763
+ });
52764
+ if (header.navEffects.neumorphic) {
52765
+ effects.hover.push({
52766
+ effectId: "neumorphic-shadow",
52767
+ options: { mode: "pressed" }
52768
+ });
52769
+ effects.hover.push({
52770
+ effectId: "text-color-change",
52771
+ options: { hoverColorToken: "primary" }
52772
+ });
52773
+ }
52774
+ if (header.navEffects.underlineGradient) effects.hover.push({
52775
+ effectId: "border-bottom-grow",
52776
+ options: { origin: "center" }
52777
+ });
52778
+ }
52779
+ function applyLegacyGlassTreatment(style, header, navStyle) {
52780
+ if (header.navContainer?.type !== "glass" || navStyle !== "minimal") return;
52781
+ style.borderRadius = "full";
52782
+ style.effects = {
52783
+ ...style.effects,
52784
+ hover: glassStateEffects(10),
52785
+ active: glassStateEffects(18)
52786
+ };
52787
+ }
52788
+ function glassStateEffects(opacity) {
52789
+ return [{
52790
+ effectId: "background-on-hover-alpha",
52791
+ options: {
52792
+ colorToken: "neutral-50",
52793
+ opacity
52794
+ }
52795
+ }, {
52796
+ effectId: "text-color-change",
52797
+ options: { hoverColorToken: "neutral-50" }
52798
+ }];
52799
+ }
52818
52800
  //#endregion
52819
52801
  //#region ../theme-core/src/header/generateHeaderCss.ts
52820
52802
  const HEADER_BLUR = "blur(12px)";
@@ -52844,8 +52826,8 @@ function generateHeaderCss(options) {
52844
52826
  const cssChunks = [];
52845
52827
  const headerContrastTreatment = resolveHeaderContrastTreatment(header);
52846
52828
  const headerNavTextSize = resolveHeaderNavTextSize(header);
52847
- cssChunks.push(generateHeaderRootStyles(header, themeId, tokens, theme));
52848
- cssChunks.push(generateMobileOverlayBackdropFilterFix(themeId));
52829
+ cssChunks.push(generateHeaderRootStyles(header, themeId, tokens));
52830
+ cssChunks.push(generateMobileOverlayBackdropFilterFix(themeId, header.variant));
52849
52831
  cssChunks.push(generateLogoStyles({
52850
52832
  logo: header.logo,
52851
52833
  themeId,
@@ -52883,56 +52865,34 @@ function isClearSplitHeaderShape(header) {
52883
52865
  function isDetachedFloatingHeaderShape(header) {
52884
52866
  return header.variant === "floating" && !header.container;
52885
52867
  }
52886
- function generateMobileOverlayBackdropFilterFix(themeId) {
52887
- 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`;
52888
- }
52889
52868
  /**
52890
52869
  * Generate root header container styles
52891
52870
  */
52892
- function generateHeaderRootStyles(header, themeId, tokens, _theme) {
52871
+ function generateHeaderRootStyles(header, themeId, tokens) {
52893
52872
  const selector = `:where([data-theme-scope="${themeId}"]) .header-root`;
52894
- const backgroundSelector = `:where([data-theme-scope="${themeId}"]) .header-root::before`;
52895
52873
  const rules = [];
52896
- const backgroundRules = [];
52897
52874
  const navContainerType = header.navContainer?.type ?? "none";
52898
52875
  const isContainedNav = navContainerType === "pill" || navContainerType === "glass";
52899
52876
  rules.push("position: relative;");
52900
52877
  rules.push("isolation: isolate;");
52901
- if (!isContainedNav) {
52902
- const bg = header.background;
52903
- if (bg.type === "color") {
52904
- const bgColor = tokens.getColor(bg.color || "surface");
52905
- backgroundRules.push(`background-color: ${bgColor};`);
52906
- } else if (bg.type === "gradient" && bg.gradient) {
52907
- const stops = bg.gradient.stops.map((s) => tokens.getColor(s.color)).join(", ");
52908
- const angle = bg.gradient.angle ?? 180;
52909
- backgroundRules.push(`background-image: linear-gradient(${angle}deg, ${stops});`);
52910
- }
52911
- backgroundRules.push(`backdrop-filter: ${HEADER_BLUR};`);
52912
- backgroundRules.push(`-webkit-backdrop-filter: ${HEADER_BLUR};`);
52913
- if (header.border) {
52914
- const borderWidth = getComponentBorderWidthPx(header.border.width);
52915
- if (borderWidth !== "0") {
52916
- const borderToken = header.border?.colorToken?.trim() || "border";
52917
- const borderColor = tokens.getColor(borderToken);
52918
- const borderStyle = header.border.style === "dashed" ? "dashed" : "solid";
52919
- if (header.border.position === "bottom") rules.push(`border-bottom: ${borderWidth} ${borderStyle} ${borderColor};`);
52920
- else if (header.border.position === "top") rules.push(`border-top: ${borderWidth} ${borderStyle} ${borderColor};`);
52921
- else if (header.border.position === "both") {
52922
- rules.push(`border-top: ${borderWidth} ${borderStyle} ${borderColor};`);
52923
- rules.push(`border-bottom: ${borderWidth} ${borderStyle} ${borderColor};`);
52924
- }
52925
- }
52926
- }
52927
- }
52878
+ const surfaceRules = isContainedNav ? {
52879
+ base: [],
52880
+ scrolled: [],
52881
+ border: []
52882
+ } : buildHeaderSurfaceRules(header, tokens, HEADER_BLUR);
52883
+ const floatingSurfaceBorder = header.variant === "floating";
52884
+ if (!floatingSurfaceBorder) rules.push(...surfaceRules.border);
52885
+ const basePaintRules = floatingSurfaceBorder ? [...surfaceRules.base, ...surfaceRules.border] : surfaceRules.base;
52886
+ const scrolledPaintRules = floatingSurfaceBorder ? [...surfaceRules.scrolled, ...surfaceRules.border] : surfaceRules.scrolled;
52928
52887
  if (header.positioning === "sticky" || header.positioning === "fixed") {
52929
52888
  const shadowVar = getComponentShadowVar(header.shadow?.elevation ?? "none");
52930
52889
  if (shadowVar) rules.push(`box-shadow: ${shadowVar};`);
52931
52890
  }
52932
52891
  const baseBlock = `\n${selector} {\n ${rules.join("\n ")}\n}\n`;
52933
52892
  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`;
52934
- if (isContainedNav || backgroundRules.length === 0) return `${baseBlock}\n${overlayFix}`;
52935
- 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) : ""}`;
52893
+ const scrollTreatmentStyles = generateHeaderScrollTreatmentStyles(header.scrollTreatment, themeId, header.variant, scrolledPaintRules);
52894
+ if (isContainedNav || basePaintRules.length === 0) return `${baseBlock}\n${overlayFix}${scrollTreatmentStyles}`;
52895
+ return `${baseBlock}\n${renderHeaderPaintTargetRules(getHeaderPaintTargets(header.variant, themeId), basePaintRules)}\n${overlayFix}${usesInsetShell(header) ? generateInsetShellStyles(header, themeId) : ""}${scrollTreatmentStyles}`;
52936
52896
  }
52937
52897
  /**
52938
52898
  * Reshapes the full-bleed header paint layer into a contained brand capsule at
@@ -52977,10 +52937,10 @@ function generateLogoStyles(input) {
52977
52937
  else rules.push(`font-family: var(--font-heading);`);
52978
52938
  if (logo) {
52979
52939
  if (logo.letterSpacing && logo.letterSpacing !== "normal") rules.push(`letter-spacing: ${{
52980
- "normal": "0em",
52981
- "wide": "0.05em",
52982
- "wider": "0.1em",
52983
- "widest": "0.15em"
52940
+ normal: "0em",
52941
+ wide: "0.05em",
52942
+ wider: "0.1em",
52943
+ widest: "0.15em"
52984
52944
  }[logo.letterSpacing]};`);
52985
52945
  if (logo.gradient) {
52986
52946
  rules.push(`background: linear-gradient(to right, ${primaryColor}, ${accentColor});`);
@@ -53053,71 +53013,11 @@ function generateNavLinkStyles(header, themeId, tokens, theme, contrastTreatment
53053
53013
  } : header.navLinkStyle, navPreferences),
53054
53014
  className: "header-nav-link"
53055
53015
  });
53056
- const navStyle = header.navStyle ?? "minimal";
53057
- const basePreset = getNavLinkPreset(navStyle);
53058
- if (!basePreset) {
53059
- console.warn(`[generateHeaderCss] Nav link preset not found: ${navStyle}`);
53016
+ const mergedStyle = buildLegacyHeaderNavLinkStyle(header, contrastTreatment, navTextSize);
53017
+ if (!mergedStyle) {
53018
+ console.warn(`[generateHeaderCss] Nav link preset not found: ${header.navStyle}`);
53060
53019
  return "";
53061
53020
  }
53062
- const mergedStyle = {
53063
- ...basePreset,
53064
- fontWeight: header.navWeight ?? basePreset.fontWeight,
53065
- colorToken: (header.navColor ?? header.textColor)?.trim() || basePreset.colorToken,
53066
- ...contrastTreatment ? { contrastTreatment } : {},
53067
- ...navTextSize ? { textSize: navTextSize } : {}
53068
- };
53069
- if (header.navWeight === "bold" && navStyle === "solid") mergedStyle.textTransform = "uppercase";
53070
- if (header.navEffects) {
53071
- const effects = mergedStyle.effects = {
53072
- ...mergedStyle.effects,
53073
- hover: [...mergedStyle.effects?.hover || []],
53074
- active: [...mergedStyle.effects?.active || []]
53075
- };
53076
- if (header.navEffects.glow) effects.hover.push({
53077
- effectId: "outer-glow",
53078
- options: { spread: 5 }
53079
- });
53080
- if (header.navEffects.neumorphic) {
53081
- effects.hover.push({
53082
- effectId: "neumorphic-shadow",
53083
- options: { mode: "pressed" }
53084
- });
53085
- effects.hover.push({
53086
- effectId: "text-color-change",
53087
- options: { hoverColorToken: "primary" }
53088
- });
53089
- }
53090
- if (header.navEffects.underlineGradient) effects.hover.push({
53091
- effectId: "border-bottom-grow",
53092
- options: { origin: "center" }
53093
- });
53094
- }
53095
- if ((header.navContainer?.type ?? "none") === "glass" && navStyle === "minimal") {
53096
- mergedStyle.borderRadius = "full";
53097
- mergedStyle.effects = {
53098
- ...mergedStyle.effects,
53099
- hover: [{
53100
- effectId: "background-on-hover-alpha",
53101
- options: {
53102
- colorToken: "neutral-50",
53103
- opacity: 10
53104
- }
53105
- }, {
53106
- effectId: "text-color-change",
53107
- options: { hoverColorToken: "neutral-50" }
53108
- }],
53109
- active: [{
53110
- effectId: "background-on-hover-alpha",
53111
- options: {
53112
- colorToken: "neutral-50",
53113
- opacity: 18
53114
- }
53115
- }, {
53116
- effectId: "text-color-change",
53117
- options: { hoverColorToken: "neutral-50" }
53118
- }]
53119
- };
53120
- }
53121
53021
  return generateNavLinkCSS({
53122
53022
  themeId,
53123
53023
  tokens,
@@ -53145,10 +53045,10 @@ function generateDropdownContainerStyles(header, themeId, tokens) {
53145
53045
  if (shadowVar) rules.push(`box-shadow: ${shadowVar};`);
53146
53046
  const borderRadius = dropdownStyle?.borderRadius ?? "md";
53147
53047
  rules.push(`border-radius: ${{
53148
- "none": "0",
53149
- "sm": "0.25rem",
53150
- "md": "0.5rem",
53151
- "lg": "0.75rem"
53048
+ none: "0",
53049
+ sm: "0.25rem",
53050
+ md: "0.5rem",
53051
+ lg: "0.75rem"
53152
53052
  }[borderRadius]};`);
53153
53053
  rules.push(`padding: 0.5rem 0;`);
53154
53054
  return `\n${selector} {\n ${rules.join("\n ")}\n}\n`;
@@ -53203,16 +53103,16 @@ function generateDropdownLinkStyles(header, themeId, tokens, theme) {
53203
53103
  const additionalRules = [];
53204
53104
  const letterSpacing = configuredDropdownStyle?.letterSpacing ?? "normal";
53205
53105
  if (letterSpacing !== "normal") additionalRules.push(`letter-spacing: ${{
53206
- "normal": "0em",
53207
- "wide": "0.05em",
53208
- "wider": "0.1em"
53106
+ normal: "0em",
53107
+ wide: "0.05em",
53108
+ wider: "0.1em"
53209
53109
  }[letterSpacing]};`);
53210
53110
  const textSize = configuredDropdownStyle?.textSize ?? "sm";
53211
53111
  additionalRules.push(`font-size: ${{
53212
- "xs": "0.75rem",
53213
- "sm": "0.875rem",
53214
- "base": "1rem",
53215
- "lg": "1.125rem"
53112
+ xs: "0.75rem",
53113
+ sm: "0.875rem",
53114
+ base: "1rem",
53115
+ lg: "1.125rem"
53216
53116
  }[textSize]};`);
53217
53117
  if (additionalRules.length > 0) return baseCSS + `\n${`:where([data-theme-scope="${themeId}"]) .nav-dropdown-link`} {\n ${additionalRules.join("\n ")}\n}\n`;
53218
53118
  return baseCSS;
@@ -53308,18 +53208,18 @@ function generateFloatingContainerStyles(header, themeId, tokens) {
53308
53208
  rules.push(`-webkit-backdrop-filter: ${FLOATING_BLUR};`);
53309
53209
  if (container.border) rules.push(`border: 1px solid rgb(255 255 255 / 0.2);`);
53310
53210
  rules.push(`border-radius: ${{
53311
- "none": "0",
53312
- "sm": "0.375rem",
53313
- "md": "0.5rem",
53314
- "lg": "0.75rem",
53315
- "xl": "1rem",
53211
+ none: "0",
53212
+ sm: "0.375rem",
53213
+ md: "0.5rem",
53214
+ lg: "0.75rem",
53215
+ xl: "1rem",
53316
53216
  "2xl": "1.5rem"
53317
53217
  }[container.rounded]};`);
53318
53218
  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);`);
53319
53219
  rules.push(`padding: ${{
53320
- "sm": "1rem 1.5rem",
53321
- "md": "1.5rem 2rem",
53322
- "lg": "2rem 2.5rem"
53220
+ sm: "1rem 1.5rem",
53221
+ md: "1.5rem 2rem",
53222
+ lg: "2rem 2.5rem"
53323
53223
  }[container.padding]};`);
53324
53224
  return `\n${selector} {\n ${rules.join("\n ")}\n}\n`;
53325
53225
  }
@@ -55917,7 +55817,7 @@ function sourceLabel(source) {
55917
55817
  case "managed-database": return "DB";
55918
55818
  case "sdk-synced": return "SDK-synced DB";
55919
55819
  case "sdk-config": return "SDK config";
55920
- default: return assertNever$25(source);
55820
+ default: return assertNever$24(source);
55921
55821
  }
55922
55822
  }
55923
55823
  //#endregion
@@ -69664,7 +69564,7 @@ function renderWithSdkThemeRuntime({ themeRuntime, theme, children }) {
69664
69564
  children
69665
69565
  });
69666
69566
  case "none": return /* @__PURE__ */ jsx(Fragment, { children });
69667
- default: return assertNever$25(themeRuntime);
69567
+ default: return assertNever$24(themeRuntime);
69668
69568
  }
69669
69569
  }
69670
69570
  //#endregion
@@ -72300,7 +72200,7 @@ function navigationAuthoringLinkToCommandLink(link) {
72300
72200
  badge: link.badge,
72301
72201
  label: link.label
72302
72202
  };
72303
- default: return assertNever$25(link);
72203
+ default: return assertNever$24(link);
72304
72204
  }
72305
72205
  }
72306
72206
  function portalLabelsForCommand(labels) {
@@ -72343,7 +72243,7 @@ function navigationReadLinkToLocalLink(item) {
72343
72243
  badge: link.badge,
72344
72244
  label: link.label
72345
72245
  };
72346
- default: return assertNever$25(link);
72246
+ default: return assertNever$24(link);
72347
72247
  }
72348
72248
  }
72349
72249
  function internalNavigationLinkToLocalLink(item) {