@riverbankcms/sdk 0.128.0 → 0.129.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 (51) hide show
  1. package/README.md +33 -0
  2. package/dist/{PreviewEditorSidebar-Dbvb7GIr.mjs → PreviewEditorSidebar-B43CJ0g_.mjs} +3 -3
  3. package/dist/{PreviewEditorUI-e9O9l20X.mjs → PreviewEditorUI-DHirVkeM.mjs} +2 -2
  4. package/dist/{SdkPreviewModeRuntime-BZHt6e9w.mjs → SdkPreviewModeRuntime-BJumZy1B.mjs} +495 -292
  5. package/dist/{SiteChromeCustomizeContext-CvuGbHJX.mjs → SiteChromeCustomizeContext-D9SlpwEj.mjs} +140 -140
  6. package/dist/_dts/blocks/src/PageRenderer.d.ts +20 -10
  7. package/dist/_dts/blocks/src/index.d.ts +2 -1
  8. package/dist/_dts/blocks/src/pageRendererBoundaries.d.ts +30 -0
  9. package/dist/_dts/blocks/src/pageRenderingMode.d.ts +37 -0
  10. package/dist/_dts/blocks/src/server.d.ts +1 -1
  11. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +14 -0
  12. package/dist/_dts/preview-next/src/client/blocks/pageDesignRuntimePreview.d.ts +2 -0
  13. package/dist/_dts/preview-next/src/client/index.d.ts +47 -47
  14. package/dist/_dts/preview-next/src/client/preview/PreviewShell.d.ts +18 -6
  15. package/dist/_dts/preview-next/src/client/preview/PreviewShellLayout.d.ts +30 -21
  16. package/dist/_dts/preview-next/src/client/preview/PreviewThemedSiteDocument.d.ts +18 -5
  17. package/dist/_dts/preview-next/src/client/preview/themeRuntime.d.ts +9 -0
  18. package/dist/_dts/preview-next/src/client/sdk/SdkPreviewMode.d.ts +21 -6
  19. package/dist/_dts/preview-next/src/client/sdk-runtime.d.ts +8 -8
  20. package/dist/_dts/sdk/src/next/catch-all.d.ts +6 -0
  21. package/dist/_dts/sdk/src/next/index.d.ts +2 -1
  22. package/dist/_dts/sdk/src/next/renderSdkContent.d.ts +33 -0
  23. package/dist/_dts/sdk/src/next/types.d.ts +23 -9
  24. package/dist/_dts/sdk/src/preview-next/before-render.d.ts +4 -6
  25. package/dist/_dts/sdk/src/preview-next/client/index.d.ts +3 -3
  26. package/dist/_dts/sdk/src/preview-next/client/runtime.d.ts +1 -1
  27. package/dist/_dts/sdk/src/rendering/blocks-page-renderer.d.ts +25 -3
  28. package/dist/_dts/sdk/src/rendering/components/Block.shared.d.ts +13 -2
  29. package/dist/_dts/sdk/src/rendering/components/Layout.d.ts +31 -18
  30. package/dist/_dts/sdk/src/rendering/components/pageShared.d.ts +20 -9
  31. package/dist/_dts/sdk/src/rendering/index.d.ts +4 -2
  32. package/dist/_dts/sdk/src/rendering/renderingMode.d.ts +23 -0
  33. package/dist/_dts/sdk/src/rendering/server.d.ts +5 -3
  34. package/dist/_dts/sdk/src/rendering/themeRuntime.d.ts +6 -0
  35. package/dist/_dts/sdk/src/version.d.ts +1 -1
  36. package/dist/cli/index.mjs +237 -211
  37. package/dist/cli/init-docs/content/workflow-preview-mode.md +24 -11
  38. package/dist/client/client.mjs +420 -337
  39. package/dist/client/rendering.mjs +503 -358
  40. package/dist/preview-next/before-render.mjs +10 -3
  41. package/dist/preview-next/client/runtime.mjs +3 -3
  42. package/dist/{sdk-runtime-Cn_QSCOg.mjs → sdk-runtime-CfZd5pAm.mjs} +1 -1
  43. package/dist/{separator-CEoGABRc.mjs → separator-DkTe68HE.mjs} +1 -1
  44. package/dist/server/components.mjs +478 -351
  45. package/dist/server/index.mjs +1 -1
  46. package/dist/server/next.mjs +640 -500
  47. package/dist/server/prebuild.mjs +1 -1
  48. package/dist/server/rendering/server.mjs +499 -355
  49. package/dist/server/rendering.mjs +499 -355
  50. package/dist/server/server.mjs +1 -1
  51. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { $a as Image, $n as clientComponentRegistry, $t as useDebouncedLatestSave, Aa as parseFooterModuleId, Ai as assertNever$1, An as createCustomBlockRegistry, Ar as gradientToCss, At as RichTextWidgetProvider, Bi as mapCurrentValueForSelect, Bn as getLinkedContentEntryMeta, C as usePreviewThemeOverlay, Cn as AMBIENT_BACKGROUND_ROLES, Cr as planPageDesignLayoutLookCompatibility, Ct as ButtonWidgetProvider, Da as Button, Di as isThemeV2NormalEditorRawStyleFieldName, Dn as isSupportedLoaderEndpoint, Dt as ReferenceWidgetProvider, Ei as parseThemeForPersistence, En as useApiMediaUploader, Er as designRuntimeRulesForTheme, Et as ReferenceField, Fa as parseMediaAssetId, Fi as getFieldIntent, Fn as makeDefaultBlockComponent, Fr as defaultSectionTransitionVariantForFamily, Ga as RotateCcw, Gn as getBlockDefinition, Gr as parseBackgroundAppearanceColorToken, Gt as canUndoHistory, Hi as unmapValueFromSelect, Hn as resolveEntryRouteTarget, Hr as backgroundAppearanceColorTokenNames, Ht as useEditorUiStoreInstance, Ia as parseSiteId, Ii as isHeaderField, In as readBlockComposition, Ir as sectionTransitionFamilies, It as hideThemeV2RawStyleFields, J as confirmAutosaveBatch, Ji as Select, Jn as SITE_OVERLAY_HEADER_CLEARANCE_CSS_VAR, Jr as runTransforms, Jt as redoHistory, Kn as projectRecurringSchedule, Kr as defaultThemeTokens, Kt as createHistoryState, La as X, Li as SdkConfigProvider, Ln as getDefaultComponentRegistry, Lr as sectionTransitionFamilyForBoundaryOptionId, Lt as prepareBlockEditorManifest, Ma as unsafeAsEditorBlockValues, Mn as DEFAULT_THEME_RESPONSIVE_MODE, Mr as GRADIENT_PRESET_IDS, Mt as useEditor, Na as assertNever$2, Ni as textColorStyle, Nn as getResponsiveScopeSpec, Nr as getGradientPreset, Nt as LinkField, Oi as pageDesignEditorBackgroundOverrideOwner, On as ThemeScope, Or as surfaceResolutionContextFromTheme, Ot as useRichTextImagePicker, Pa as expectParsedBrandedId, Pi as BlockApiProvider, Pn as escapeStyleContent, Pr as parseGradientPresetId, Pt as LinkWidgetProvider, Q as rejectAutosaveBatch, Qi as SelectValue, Qn as createManifestValidator, Qr as eventCalendarListLayoutOptions, Ra as Upload, Ri as useSdkConfig, Rn as LINKED_CONTENT_ENTRY_META_KEY, Rr as sectionTransitionVariantForBoundaryOptionId, Rt as stripTopLevelRoutingUi, S as PreviewThemeOverlayProvider, Sn as deriveLaunchReadiness, Sr as retargetCompiledRuntimeFieldsForContentAdjacency, St as ButtonVariantField, Tn as useMediaEditorOptional, Tt as MediaField, Ui as FieldFrame, Un as resolvePageRouteTarget, Ur as backgroundAppearanceQuickColorTokenNames, Ut as useOptionalEditorUiStoreInstance, Vi as mapOptionValueForSelect, Vn as defaultTransforms, Vr as BACKGROUND_BODY_TEXT_MIN_CONTRAST_RATIO, Vt as useEditorUiStore, Wi as useField, Wn as resolveRouteTarget, Wr as foregroundTokenForBackgroundAppearanceColorToken, Wt as canRedoHistory, X as enqueueTransaction, Xi as SelectItem, Xn as visibleHeaderClearancePx, Xr as bindingSchema, Xt as unsafeAsLinkedContentEntryId, Y as deriveTransactionCapabilities, Yi as SelectContent, Yn as planSiteOverlayHeaderClearance, Yr as ctaButton, Yt as undoHistory, Z as idleEditorTransactionQueueState, Zi as SelectTrigger, Zn as resolveVariantKey, Zr as eventCalendarListLayoutCompatibleDisplayModeValues, Zt as recordsEqual, _i as attachRenderableMediaAssetFields, _n as applyPageDesignEditorAction, _r as defineFragment, _t as OfferingsPreviewWidgetProvider, ai as isObjectRecord, ar as faqHeadingFragment, at as PreviewTextEditor, b as PreviewDesignCoordinatorProvider, bn as decodePublicProductCategorySelectorQuery, br as compileEditorModelRuntime, bt as EntryPickerField, ca as TabsList, ci as inlineTextToPlainText, cn as PaletteProvider, cr as formEmbedFragment, ct as EditableBlockProvider, da as DialogContent, di as RichText$1, dn as createManifestFormAdapter, dr as testimonialsHeadingFragment, dt as useEntryEditorController, ei as planSiteChromePlacement, en as createRoutingHelpers, eo as GripVertical, er as ImageResolveContextProvider, et as resolvePreviewSidebarTab, f as PREVIEW_DESIGN_LOAD_ERROR_MESSAGE, fa as DialogDescription, fi as buildResolveImageUrlContext, fr as ctaCopyFragment, ft as createSiteOptionApiLoader, gi as SECTION_BACKGROUND_MIN_SOURCE_WIDTH, gn as MediaEditor, gr as bodyCopyFragment, gt as OfferingsPreviewGroupOrderField, ha as DialogTitle, hi as setContextResolveImageUrlContext, hn as createStoreBackend, hr as heroCopyFragment, ht as SiteOptionWidgetProvider, i as usePreviewDesignHistoryOrder, ii as renderInlineText, in as parseReferenceKind, io as ChevronLeft, ir as faqAccordionFragment, it as PreviewInlineTextEditor, ja as unsafeAsEditorBlockId, jn as buildThemeRuntime, jr as GRADIENT_PRESETS, jt as EditorProvider, ka as cn, ki as asDesignBlockId, kn as containerResponsiveThemeCss, kt as RichTextField, la as TabsTrigger, li as isInlineTextEmpty, ln as usePalette, lr as formCopyFragment, lt as EntryControllerProvider, m as reportPreviewDesignError, ma as DialogHeader, mi as resolveImageUrlWithContext, mn as evaluateVisibility, mr as ctaRowFragment, mt as SiteOptionPickerField, n as useSiteChromeCustomizeOptional, ni as parseGeneratedIconAssetId, nn as BUILT_IN_REFERENCE_KINDS, nr as headingFragment, nt as renderSiteChromeBlock, oa as Tabs, oi as isRecord$13, or as blogFeaturedPostFragment, p as PREVIEW_DESIGN_SAVE_ERROR_MESSAGE, pa as DialogFooter, pi as getCurrentResolveImageUrlContext, pn as FormRenderer, pr as heroCtaRowFragment, pt as createSiteOptionWidgetAdapters, q as beginAutosaveBatch, qn as SITE_CHROME_VISIBLE_HEADER_SELECTOR, qt as pushHistoryEntry, r as PreviewDesignHistoryOrderProvider, ri as parseGeneratedIconSetId, ro as ChevronRight, rr as cardFragment, rt as PreviewRichTextEditor, sa as TabsContent, si as coerceInlineTextWithFallback, so as __exportAll, sr as singleButtonFragment, st as useUISelector, t as SiteChromeCustomizeProvider, ti as parseBlockIconValue, tn as createSnapshotFromPageRecord, tr as richTextFragment, ua as Dialog, ui as Text$1, ur as testimonialsCarouselFragment, vi as getAtPath, vn as getPageDesignEditorState, vr as formatSiteChromeBackgroundTokenLabel, vt as InlineTextField, wn as MediaEditorContextProvider, wr as componentRuntimeRulesForTheme, wt as FileField, xn as DEFAULT_LAUNCH_READINESS_INPUT, xr as retargetCompiledBoundaryRuntimeForContentAdjacency, xt as EntryPickerWidgetProvider, yi as siblingPath, yr as applyCompiledRuntimeFieldsToContent, yt as IconPickerField, zi as hasEmptyOption, zn as coerceLinkedContentEntriesPayload, zt as getBlockManifestFromSdkConfig } from "./SiteChromeCustomizeContext-CvuGbHJX.mjs";
2
+ import { $a as Image, $n as clientComponentRegistry, $t as useDebouncedLatestSave, Aa as parseFooterModuleId, Ai as assertNever$1, An as buildThemeRuntime, Ar as gradientToCss, At as RichTextWidgetProvider, Bi as mapCurrentValueForSelect, Bn as getLinkedContentEntryMeta, C as usePreviewThemeOverlay, Cn as AMBIENT_BACKGROUND_ROLES, Cr as planPageDesignLayoutLookCompatibility, Ct as ButtonWidgetProvider, Da as Button, Di as isThemeV2NormalEditorRawStyleFieldName, Dn as isSupportedLoaderEndpoint, Dt as ReferenceWidgetProvider, Ei as parseThemeForPersistence, En as useApiMediaUploader, Er as designRuntimeRulesForTheme, Et as ReferenceField, Fa as parseMediaAssetId, Fi as getFieldIntent, Fn as makeDefaultBlockComponent, Fr as defaultSectionTransitionVariantForFamily, Ga as RotateCcw, Gn as getBlockDefinition, Gr as parseBackgroundAppearanceColorToken, Gt as canUndoHistory, Hi as unmapValueFromSelect, Hn as resolveEntryRouteTarget, Hr as backgroundAppearanceColorTokenNames, Ht as useEditorUiStoreInstance, Ia as parseSiteId, Ii as isHeaderField, In as readBlockComposition, Ir as sectionTransitionFamilies, It as hideThemeV2RawStyleFields, J as confirmAutosaveBatch, Ji as Select, Jn as SITE_OVERLAY_HEADER_CLEARANCE_CSS_VAR, Jr as runTransforms, Jt as redoHistory, Kn as projectRecurringSchedule, Kr as defaultThemeTokens, Kt as createHistoryState, La as X, Li as SdkConfigProvider, Ln as getDefaultComponentRegistry, Lr as sectionTransitionFamilyForBoundaryOptionId, Lt as prepareBlockEditorManifest, Ma as unsafeAsEditorBlockValues, Mn as getResponsiveScopeSpec, Mr as GRADIENT_PRESET_IDS, Mt as useEditor, Na as assertNever$2, Ni as textColorStyle, Nn as escapeStyleContent, Nr as getGradientPreset, Nt as LinkField, Oi as pageDesignEditorBackgroundOverrideOwner, On as ThemeScope, Or as surfaceResolutionContextFromTheme, Ot as useRichTextImagePicker, Pa as expectParsedBrandedId, Pi as BlockApiProvider, Pn as createCustomBlockRegistry, Pr as parseGradientPresetId, Pt as LinkWidgetProvider, Q as rejectAutosaveBatch, Qi as SelectValue, Qn as createManifestValidator, Qr as eventCalendarListLayoutOptions, Ra as Upload, Ri as useSdkConfig, Rn as LINKED_CONTENT_ENTRY_META_KEY, Rr as sectionTransitionVariantForBoundaryOptionId, Rt as stripTopLevelRoutingUi, S as PreviewThemeOverlayProvider, Sn as deriveLaunchReadiness, Sr as retargetCompiledRuntimeFieldsForContentAdjacency, St as ButtonVariantField, Tn as useMediaEditorOptional, Tt as MediaField, Ui as FieldFrame, Un as resolvePageRouteTarget, Ur as backgroundAppearanceQuickColorTokenNames, Ut as useOptionalEditorUiStoreInstance, Vi as mapOptionValueForSelect, Vn as defaultTransforms, Vr as BACKGROUND_BODY_TEXT_MIN_CONTRAST_RATIO, Vt as useEditorUiStore, Wi as useField, Wn as resolveRouteTarget, Wr as foregroundTokenForBackgroundAppearanceColorToken, Wt as canRedoHistory, X as enqueueTransaction, Xi as SelectItem, Xn as visibleHeaderClearancePx, Xr as bindingSchema, Xt as unsafeAsLinkedContentEntryId, Y as deriveTransactionCapabilities, Yi as SelectContent, Yn as planSiteOverlayHeaderClearance, Yr as ctaButton, Yt as undoHistory, Z as idleEditorTransactionQueueState, Zi as SelectTrigger, Zn as resolveVariantKey, Zr as eventCalendarListLayoutCompatibleDisplayModeValues, Zt as recordsEqual, _i as attachRenderableMediaAssetFields, _n as applyPageDesignEditorAction, _r as defineFragment, _t as OfferingsPreviewWidgetProvider, ai as isObjectRecord, ar as faqHeadingFragment, at as PreviewTextEditor, b as PreviewDesignCoordinatorProvider, bn as decodePublicProductCategorySelectorQuery, br as compileEditorModelRuntime, bt as EntryPickerField, ca as TabsList, ci as inlineTextToPlainText, cn as PaletteProvider, cr as formEmbedFragment, ct as EditableBlockProvider, da as DialogContent, di as RichText$1, dn as createManifestFormAdapter, dr as testimonialsHeadingFragment, dt as useEntryEditorController, ei as planSiteChromePlacement, en as createRoutingHelpers, eo as GripVertical, er as ImageResolveContextProvider, et as resolvePreviewSidebarTab, f as PREVIEW_DESIGN_LOAD_ERROR_MESSAGE, fa as DialogDescription, fi as buildResolveImageUrlContext, fr as ctaCopyFragment, ft as createSiteOptionApiLoader, gi as SECTION_BACKGROUND_MIN_SOURCE_WIDTH, gn as MediaEditor, gr as bodyCopyFragment, gt as OfferingsPreviewGroupOrderField, ha as DialogTitle, hi as setContextResolveImageUrlContext, hn as createStoreBackend, hr as heroCopyFragment, ht as SiteOptionWidgetProvider, i as usePreviewDesignHistoryOrder, ii as renderInlineText, in as parseReferenceKind, io as ChevronLeft, ir as faqAccordionFragment, it as PreviewInlineTextEditor, ja as unsafeAsEditorBlockId, jn as DEFAULT_THEME_RESPONSIVE_MODE, jr as GRADIENT_PRESETS, jt as EditorProvider, ka as cn, ki as asDesignBlockId, kn as containerResponsiveThemeCss, kt as RichTextField, la as TabsTrigger, li as isInlineTextEmpty, ln as usePalette, lr as formCopyFragment, lt as EntryControllerProvider, m as reportPreviewDesignError, ma as DialogHeader, mi as resolveImageUrlWithContext, mn as evaluateVisibility, mr as ctaRowFragment, mt as SiteOptionPickerField, n as useSiteChromeCustomizeOptional, ni as parseGeneratedIconAssetId, nn as BUILT_IN_REFERENCE_KINDS, nr as headingFragment, nt as renderSiteChromeBlock, oa as Tabs, oi as isRecord$13, or as blogFeaturedPostFragment, p as PREVIEW_DESIGN_SAVE_ERROR_MESSAGE, pa as DialogFooter, pi as getCurrentResolveImageUrlContext, pn as FormRenderer, pr as heroCtaRowFragment, pt as createSiteOptionWidgetAdapters, q as beginAutosaveBatch, qn as SITE_CHROME_VISIBLE_HEADER_SELECTOR, qt as pushHistoryEntry, r as PreviewDesignHistoryOrderProvider, ri as parseGeneratedIconSetId, ro as ChevronRight, rr as cardFragment, rt as PreviewRichTextEditor, sa as TabsContent, si as coerceInlineTextWithFallback, so as __exportAll, sr as singleButtonFragment, st as useUISelector, t as SiteChromeCustomizeProvider, ti as parseBlockIconValue, tn as createSnapshotFromPageRecord, tr as richTextFragment, ua as Dialog, ui as Text$1, ur as testimonialsCarouselFragment, vi as getAtPath, vn as getPageDesignEditorState, vr as formatSiteChromeBackgroundTokenLabel, vt as InlineTextField, wn as MediaEditorContextProvider, wr as componentRuntimeRulesForTheme, wt as FileField, xn as DEFAULT_LAUNCH_READINESS_INPUT, xr as retargetCompiledBoundaryRuntimeForContentAdjacency, xt as EntryPickerWidgetProvider, yi as siblingPath, yr as applyCompiledRuntimeFieldsToContent, yt as IconPickerField, zi as hasEmptyOption, zn as coerceLinkedContentEntriesPayload, zt as getBlockManifestFromSdkConfig } from "./SiteChromeCustomizeContext-D9SlpwEj.mjs";
3
3
  import { i as useOptionalPreviewLayout, t as PreviewQueryProvider } from "./PreviewQueryProvider-B1kbhaJD.mjs";
4
4
  import { _ as API_ENDPOINTS, a as usePreviewToken, c as createBearerAPIClient, d as unwrapResponse, g as resolveSurfaceDocumentAttributes, h as SURFACE_IDS, i as usePreviewAuthFetch, m as SURFACE_DOCUMENT_DATA_ATTRIBUTE, n as markPreviewAuthExpired, o as isPreviewRuntimeSessionEditable, r as usePreviewAuth, s as ApiRequestError, t as initPreviewAuth } from "./previewAuthStore-BesgU5Xu.mjs";
5
5
  import * as React$1 from "react";
@@ -426,8 +426,115 @@ function hydrateEntryLink(link, context) {
426
426
  };
427
427
  }
428
428
  //#endregion
429
+ //#region ../blocks/src/pageRenderingMode.ts
430
+ var MissingBlockOverrideError = class extends Error {
431
+ constructor(blockKind) {
432
+ super(`Override-only rendering requires an override for block kind "${blockKind}".`);
433
+ this.blockKind = blockKind;
434
+ this.code = "missing_block_override";
435
+ this.name = "MissingBlockOverrideError";
436
+ }
437
+ };
438
+ function isOverrideOnlyResourceInput(props) {
439
+ return props.rendering?.kind === "overrides-only";
440
+ }
441
+ function resolvePageThemeResources(props) {
442
+ if (isOverrideOnlyResourceInput(props)) return { kind: "unavailable" };
443
+ return {
444
+ kind: "available",
445
+ tokens: props.themeTokens ?? buildThemeRuntime(props.theme).tokens,
446
+ config: props.theme
447
+ };
448
+ }
449
+ function requireBlockOverride(resources, override, blockKind) {
450
+ if (resources.kind === "unavailable" && !override) throw new MissingBlockOverrideError(blockKind);
451
+ }
452
+ function overrideThemeProps(resources) {
453
+ return resources.kind === "available" ? {
454
+ theme: resources.tokens,
455
+ themeConfig: resources.config
456
+ } : {};
457
+ }
458
+ function requireThemeResources(resources, blockKind) {
459
+ if (resources.kind === "unavailable") throw new MissingBlockOverrideError(blockKind);
460
+ return resources;
461
+ }
462
+ //#endregion
463
+ //#region ../blocks/src/pageRendererBoundaries.tsx
464
+ const boundaryKey = (previousBlockId, nextBlockId) => `${previousBlockId}\u0000${nextBlockId}`;
465
+ function isSiteStyleTransitionStyleGroup(value) {
466
+ return value?.startsWith("site-style-transition-") === true;
467
+ }
468
+ function boundaryMapForAdjacentBlockIds(boundaries) {
469
+ return new Map(boundaries.map((boundary) => [boundaryKey(boundary.previousBlockId, boundary.nextBlockId), boundary]));
470
+ }
471
+ function boundaryBetweenBlocks(previousBlock, nextBlock, boundaries) {
472
+ const previousBlockId = previousBlock?.id ?? null;
473
+ const nextBlockId = nextBlock?.id ?? null;
474
+ if (!previousBlockId || !nextBlockId) return null;
475
+ return boundaries.get(boundaryKey(previousBlockId, nextBlockId)) ?? null;
476
+ }
477
+ function renderBoundaryAfterBlock(input) {
478
+ const previousBlockId = input.block.id;
479
+ const nextBlockId = input.nextBlock?.id ?? null;
480
+ if (!previousBlockId || !nextBlockId) return null;
481
+ const boundary = input.boundaryByAdjacentBlockIds.get(boundaryKey(previousBlockId, nextBlockId));
482
+ if (!boundary) return null;
483
+ const rendered = /* @__PURE__ */ jsx("div", {
484
+ "aria-hidden": "true",
485
+ "data-block-boundary": "",
486
+ "data-boundary-id": boundary.boundaryId,
487
+ "data-boundary-previous-block-id": boundary.previousBlockId,
488
+ "data-boundary-next-block-id": boundary.nextBlockId,
489
+ "data-style-group": boundary.styleGroup,
490
+ style: boundaryCssVarsStyle(boundary)
491
+ }, `${input.blockKey}:boundary`);
492
+ return input.wrapBoundary ? input.wrapBoundary(boundary, rendered) : rendered;
493
+ }
494
+ function boundaryCssVarsStyle(boundary) {
495
+ return {
496
+ "--site-style-transition-from": boundary.cssVars.from,
497
+ "--site-style-transition-to": boundary.cssVars.to
498
+ };
499
+ }
500
+ function boundaryReserveCssVarsStyle(input) {
501
+ const before = input.before?.metrics.reserveCss ?? null;
502
+ const after = input.after?.metrics.reserveCss ?? null;
503
+ if (!before && !after) return void 0;
504
+ return {
505
+ ...before ? { "--site-style-boundary-before-reserve": before } : {},
506
+ ...after ? { "--site-style-boundary-after-reserve": after } : {}
507
+ };
508
+ }
509
+ function transitionCssVarsStyle(content) {
510
+ const transitionStyles = isObjectRecord(content._transitionStyles) ? content._transitionStyles : null;
511
+ const cssVars = isObjectRecord(transitionStyles?.cssVars) ? transitionStyles.cssVars : null;
512
+ const from = typeof cssVars?.from === "string" ? cssVars.from : null;
513
+ const to = typeof cssVars?.to === "string" ? cssVars.to : null;
514
+ if (!from && !to) return void 0;
515
+ return {
516
+ ...from ? { "--site-style-transition-from": from } : {},
517
+ ...to ? { "--site-style-transition-to": to } : {}
518
+ };
519
+ }
520
+ function mergeStyleObjects(left, right) {
521
+ if (!left) return right;
522
+ if (!right) return left;
523
+ return {
524
+ ...left,
525
+ ...right
526
+ };
527
+ }
528
+ function pageBlockPosition(index, blockCount) {
529
+ if (blockCount <= 1) return "only";
530
+ if (index === 0) return "first";
531
+ if (index === blockCount - 1) return "last";
532
+ return "middle";
533
+ }
534
+ //#endregion
429
535
  //#region ../blocks/src/PageRenderer.tsx
430
- function PageRenderer({ theme, page, runtimeBoundaries, usePlaceholders = false, dataContext, wrapBlock, wrapBoundary, registry, themeTokens: providedThemeTokens, routeMap, blockOverrides, sdkConfig, customBlocks, previewAuthoring }) {
536
+ function PageRenderer(props) {
537
+ const { page, runtimeBoundaries, usePlaceholders = false, dataContext, wrapBlock, wrapBoundary, registry, routeMap, blockOverrides, sdkConfig, customBlocks, previewAuthoring } = props;
431
538
  const imageResolveContext = React$1.useMemo(() => resolvePageRendererImageResolveContext(dataContext), [
432
539
  dataContext?.imageResolveContext,
433
540
  dataContext?.mediaAssets,
@@ -436,12 +543,16 @@ function PageRenderer({ theme, page, runtimeBoundaries, usePlaceholders = false,
436
543
  ]);
437
544
  const boundaryByAdjacentBlockIds = React$1.useMemo(() => boundaryMapForAdjacentBlockIds(runtimeBoundaries ?? []), [runtimeBoundaries]);
438
545
  const usesRuntimeBoundaries = runtimeBoundaries !== void 0;
546
+ const themeResources = React$1.useMemo(() => resolvePageThemeResources(props), [
547
+ props.rendering,
548
+ props.theme,
549
+ props.themeTokens
550
+ ]);
439
551
  if (!page || page.blocks.length === 0) return /* @__PURE__ */ jsx("div", {
440
552
  className: "rb-p-6 rb-caption",
441
553
  style: textColorStyle("mutedText"),
442
554
  children: "No blocks found."
443
555
  });
444
- const themeTokens = providedThemeTokens ?? buildThemeRuntime(theme).tokens;
445
556
  const resolvedRegistry = registry ?? getDefaultComponentRegistry();
446
557
  setContextResolveImageUrlContext(imageResolveContext);
447
558
  return /* @__PURE__ */ jsx("div", { children: page.blocks.map((block, index) => {
@@ -464,22 +575,14 @@ function PageRenderer({ theme, page, runtimeBoundaries, usePlaceholders = false,
464
575
  const renderableContent = getRenderableContent(block, dataContext?.previewStage);
465
576
  const variantKey = definition?.manifest ? resolveVariantKey(definition.manifest, renderableContent) : null;
466
577
  const shouldUseWrapper = !managesOwnWrapper || Boolean(wrapBlock);
467
- const blockSectionProps = {
468
- themeTokens,
469
- themeConfig: theme,
578
+ const blockSectionProps = buildBlockSectionProps({
579
+ props,
580
+ themeResources,
470
581
  block,
471
- usePlaceholders,
472
- dataContext,
473
582
  blockKey,
474
- registry: resolvedRegistry,
475
- routeMap,
476
- wrapBlock,
477
- blockOverrides,
478
- sdkConfig,
479
- customBlocks,
480
583
  imageResolveContext,
481
- previewAuthoring
482
- };
584
+ registry: resolvedRegistry
585
+ });
483
586
  if (!shouldUseWrapper) {
484
587
  const rendered = /* @__PURE__ */ jsx(MemoBlockSection, { ...blockSectionProps }, `${blockKey}:block`);
485
588
  return boundaryElement ? /* @__PURE__ */ jsxs(React$1.Fragment, { children: [rendered, boundaryElement] }, blockKey) : rendered;
@@ -521,81 +624,6 @@ function PageRenderer({ theme, page, runtimeBoundaries, usePlaceholders = false,
521
624
  })] }, blockKey);
522
625
  }) });
523
626
  }
524
- function isSiteStyleTransitionStyleGroup(value) {
525
- return value?.startsWith("site-style-transition-") === true;
526
- }
527
- function boundaryMapForAdjacentBlockIds(boundaries) {
528
- return new Map(boundaries.map((boundary) => [boundaryKey(boundary.previousBlockId, boundary.nextBlockId), boundary]));
529
- }
530
- function boundaryKey(previousBlockId, nextBlockId) {
531
- return `${previousBlockId}\u0000${nextBlockId}`;
532
- }
533
- function boundaryBetweenBlocks(previousBlock, nextBlock, boundaryByAdjacentBlockIds) {
534
- const previousBlockId = previousBlock?.id ?? null;
535
- const nextBlockId = nextBlock?.id ?? null;
536
- if (!previousBlockId || !nextBlockId) return null;
537
- return boundaryByAdjacentBlockIds.get(boundaryKey(previousBlockId, nextBlockId)) ?? null;
538
- }
539
- function renderBoundaryAfterBlock(input) {
540
- const previousBlockId = input.block.id;
541
- const nextBlockId = input.nextBlock?.id ?? null;
542
- if (!previousBlockId || !nextBlockId) return null;
543
- const boundary = input.boundaryByAdjacentBlockIds.get(boundaryKey(previousBlockId, nextBlockId));
544
- if (!boundary) return null;
545
- const rendered = /* @__PURE__ */ jsx("div", {
546
- "aria-hidden": "true",
547
- "data-block-boundary": "",
548
- "data-boundary-id": boundary.boundaryId,
549
- "data-boundary-previous-block-id": boundary.previousBlockId,
550
- "data-boundary-next-block-id": boundary.nextBlockId,
551
- "data-style-group": boundary.styleGroup,
552
- style: boundaryCssVarsStyle(boundary)
553
- }, `${input.blockKey}:boundary`);
554
- return input.wrapBoundary ? input.wrapBoundary(boundary, rendered) : rendered;
555
- }
556
- function boundaryCssVarsStyle(boundary) {
557
- return {
558
- "--site-style-transition-from": boundary.cssVars.from,
559
- "--site-style-transition-to": boundary.cssVars.to
560
- };
561
- }
562
- function boundaryReserveCssVarsStyle(input) {
563
- const before = input.before ? boundaryReserveValueForTreatment(input.before) : null;
564
- const after = input.after ? boundaryReserveValueForTreatment(input.after) : null;
565
- if (!before && !after) return void 0;
566
- return {
567
- ...before ? { "--site-style-boundary-before-reserve": before } : {},
568
- ...after ? { "--site-style-boundary-after-reserve": after } : {}
569
- };
570
- }
571
- function boundaryReserveValueForTreatment(boundary) {
572
- return boundary.metrics.reserveCss;
573
- }
574
- function transitionCssVarsStyle(content) {
575
- const transitionStyles = isObjectRecord(content._transitionStyles) ? content._transitionStyles : null;
576
- const cssVars = isObjectRecord(transitionStyles?.cssVars) ? transitionStyles.cssVars : null;
577
- const from = typeof cssVars?.from === "string" ? cssVars.from : null;
578
- const to = typeof cssVars?.to === "string" ? cssVars.to : null;
579
- if (!from && !to) return void 0;
580
- return {
581
- ...from ? { "--site-style-transition-from": from } : {},
582
- ...to ? { "--site-style-transition-to": to } : {}
583
- };
584
- }
585
- function mergeStyleObjects(left, right) {
586
- if (!left) return right;
587
- if (!right) return left;
588
- return {
589
- ...left,
590
- ...right
591
- };
592
- }
593
- function pageBlockPosition(index, blockCount) {
594
- if (blockCount <= 1) return "only";
595
- if (index === 0) return "first";
596
- if (index === blockCount - 1) return "last";
597
- return "middle";
598
- }
599
627
  function resolvePageRendererImageResolveContext(dataContext) {
600
628
  const input = dataContext?.imageResolveContext;
601
629
  return buildResolveImageUrlContext({
@@ -605,6 +633,23 @@ function resolvePageRendererImageResolveContext(dataContext) {
605
633
  mediaAssets: input?.mediaAssets ?? dataContext?.mediaAssets
606
634
  });
607
635
  }
636
+ function buildBlockSectionProps(input) {
637
+ return {
638
+ themeResources: input.themeResources,
639
+ block: input.block,
640
+ usePlaceholders: input.props.usePlaceholders ?? false,
641
+ dataContext: input.props.dataContext,
642
+ blockKey: input.blockKey,
643
+ registry: input.registry,
644
+ routeMap: input.props.routeMap,
645
+ wrapBlock: input.props.wrapBlock,
646
+ blockOverrides: input.props.blockOverrides,
647
+ sdkConfig: input.props.sdkConfig,
648
+ customBlocks: input.props.customBlocks,
649
+ imageResolveContext: input.imageResolveContext,
650
+ previewAuthoring: input.props.previewAuthoring
651
+ };
652
+ }
608
653
  /**
609
654
  * Look up a block override component by block kind.
610
655
  * Supports both full ("block.hero") and short ("hero") keys.
@@ -671,7 +716,7 @@ function getCachedValidator(manifest, flavour) {
671
716
  * referential equality of all props that affect rendering. Standard React.memo
672
717
  * wouldn't catch all the render triggers from the editor store.
673
718
  */
674
- const MemoBlockSection = React$1.memo(function MemoBlockSection({ themeTokens, themeConfig, block, usePlaceholders, dataContext, registry, routeMap, wrapBlock, blockOverrides, sdkConfig, customBlocks, imageResolveContext, previewAuthoring }) {
719
+ const MemoBlockSection = React$1.memo(function MemoBlockSection({ themeResources, block, usePlaceholders, dataContext, registry, routeMap, wrapBlock, blockOverrides, sdkConfig, customBlocks, imageResolveContext, previewAuthoring }) {
675
720
  const perfStart = globalThis.process?.env?.DEBUG_PERF === "1" && typeof window === "undefined" ? Date.now() : 0;
676
721
  const fallbackImageResolveContext = getCurrentResolveImageUrlContext();
677
722
  const resolvedImageResolveContext = imageResolveContext ?? fallbackImageResolveContext;
@@ -692,6 +737,7 @@ const MemoBlockSection = React$1.memo(function MemoBlockSection({ themeTokens, t
692
737
  return node;
693
738
  }
694
739
  const OverrideComponent = getBlockOverride(block.kind, blockOverrides);
740
+ requireBlockOverride(themeResources, OverrideComponent, block.kind);
695
741
  let definition = getBlockDefinition(block.kind);
696
742
  if (!definition && block.kind.startsWith("custom.")) definition = createCustomBlockRegistry({
697
743
  sdkConfig,
@@ -704,8 +750,7 @@ const MemoBlockSection = React$1.memo(function MemoBlockSection({ themeTokens, t
704
750
  if (OverrideComponent) {
705
751
  const rendered = /* @__PURE__ */ jsx(OverrideComponent, {
706
752
  content: getRenderableContent(block, dataContext?.previewStage),
707
- theme: themeTokens,
708
- themeConfig,
753
+ ...overrideThemeProps(themeResources),
709
754
  data: void 0,
710
755
  siteId: dataContext?.siteId,
711
756
  apiBaseUrl: dataContext?.apiBaseUrl,
@@ -804,8 +849,7 @@ const MemoBlockSection = React$1.memo(function MemoBlockSection({ themeTokens, t
804
849
  const hasResolvedData = !!resolved && typeof resolved === "object" && Object.keys(resolved).length > 0;
805
850
  const baseProps = {
806
851
  content: hydratedContent,
807
- theme: themeTokens,
808
- themeConfig,
852
+ ...overrideThemeProps(themeResources),
809
853
  data: resolved,
810
854
  siteId: dataContext?.siteId,
811
855
  apiBaseUrl: dataContext?.apiBaseUrl,
@@ -825,6 +869,7 @@ const MemoBlockSection = React$1.memo(function MemoBlockSection({ themeTokens, t
825
869
  let rendered;
826
870
  if (OverrideComponent) rendered = /* @__PURE__ */ jsx(OverrideComponent, { ...baseProps });
827
871
  else {
872
+ requireThemeResources(themeResources, block.kind);
828
873
  const BlockComponent = getCachedBlockComponent(definition.manifest);
829
874
  const pathBase = typeof block.id === "string" && block.id.length > 0 ? `blocks.${block.id}.` : void 0;
830
875
  const rootContext = { $root: {
@@ -874,7 +919,7 @@ const MemoBlockSection = React$1.memo(function MemoBlockSection({ themeTokens, t
874
919
  });
875
920
  }
876
921
  }, (prev, next) => {
877
- return prev.block === next.block && prev.registry === next.registry && prev.dataContext === next.dataContext && prev.themeTokens === next.themeTokens && prev.themeConfig === next.themeConfig && prev.routeMap === next.routeMap && prev.usePlaceholders === next.usePlaceholders && prev.wrapBlock === next.wrapBlock && prev.blockOverrides === next.blockOverrides && prev.sdkConfig === next.sdkConfig && prev.customBlocks === next.customBlocks && prev.imageResolveContext === next.imageResolveContext && prev.previewAuthoring === next.previewAuthoring;
922
+ return prev.block === next.block && prev.registry === next.registry && prev.dataContext === next.dataContext && prev.themeResources === next.themeResources && prev.routeMap === next.routeMap && prev.usePlaceholders === next.usePlaceholders && prev.wrapBlock === next.wrapBlock && prev.blockOverrides === next.blockOverrides && prev.sdkConfig === next.sdkConfig && prev.customBlocks === next.customBlocks && prev.imageResolveContext === next.imageResolveContext && prev.previewAuthoring === next.previewAuthoring;
878
923
  });
879
924
  function fallback(message) {
880
925
  return /* @__PURE__ */ jsx("div", {
@@ -8007,12 +8052,27 @@ function assertNever(value) {
8007
8052
  const defaultPreviewThemeRuntime = { kind: "cms-theme" };
8008
8053
  //#endregion
8009
8054
  //#region ../preview-next/src/client/preview/PreviewThemedSiteDocument.tsx
8055
+ function planPreviewSiteDocument(theme, bannerNode, headerNode) {
8056
+ return planSiteDocument({
8057
+ headerPositioning: theme.header?.positioning ?? "static",
8058
+ headerVariant: theme.header?.variant ?? null,
8059
+ hasVisibleBanner: Boolean(bannerNode),
8060
+ hasVisibleHeader: Boolean(headerNode)
8061
+ });
8062
+ }
8063
+ function resolveDocumentResponsiveMode(runtime, useContainerResponsiveMode) {
8064
+ return runtime.kind === "none" ? void 0 : runtime.responsiveMode ?? (useContainerResponsiveMode ? "container" : "viewport");
8065
+ }
8066
+ function renderPreviewHeader(model, theme, fallback) {
8067
+ if (!model?.header) return fallback;
8068
+ return /* @__PURE__ */ jsx(SiteChromeEditableSurface, {
8069
+ surface: "header",
8070
+ children: renderSiteChromeBlock(model, "header", theme, { themeConfigOverrideMode: "ignore" })
8071
+ });
8072
+ }
8010
8073
  function PreviewThemedSiteDocument({ children, themeRuntime = defaultPreviewThemeRuntime, useContainerResponsiveMode, viewportMode, viewportWidth, scale, contentHeight, scaleContainerRef, contentRef, staticHeaderNode, bannerNode, staticFooterNode, siteChromeRenderModel }) {
8011
8074
  const { effectiveTheme } = usePreviewThemeOverlay();
8012
- const headerNode = siteChromeRenderModel?.header ? /* @__PURE__ */ jsx(SiteChromeEditableSurface, {
8013
- surface: "header",
8014
- children: renderSiteChromeBlock(siteChromeRenderModel, "header", effectiveTheme, { themeConfigOverrideMode: "ignore" })
8015
- }) : staticHeaderNode;
8075
+ const headerNode = renderPreviewHeader(siteChromeRenderModel, effectiveTheme, staticHeaderNode);
8016
8076
  const documentNode = renderPreviewDocument({
8017
8077
  viewportMode,
8018
8078
  viewportWidth,
@@ -8020,12 +8080,7 @@ function PreviewThemedSiteDocument({ children, themeRuntime = defaultPreviewThem
8020
8080
  contentHeight,
8021
8081
  scaleContainerRef,
8022
8082
  contentRef,
8023
- siteDocumentPlan: planSiteDocument({
8024
- headerPositioning: effectiveTheme.header?.positioning ?? "static",
8025
- headerVariant: effectiveTheme.header?.variant ?? null,
8026
- hasVisibleBanner: Boolean(bannerNode),
8027
- hasVisibleHeader: Boolean(headerNode)
8028
- }),
8083
+ siteDocumentPlan: planPreviewSiteDocument(effectiveTheme, bannerNode, headerNode),
8029
8084
  headerNode,
8030
8085
  bannerNode,
8031
8086
  footerNode: Boolean(siteChromeRenderModel) && siteChromeRenderModel?.footer.canRenderReactively !== false && siteChromeRenderModel ? /* @__PURE__ */ jsx(SiteChromeEditableSurface, {
@@ -8035,7 +8090,7 @@ function PreviewThemedSiteDocument({ children, themeRuntime = defaultPreviewThem
8035
8090
  }) : staticFooterNode,
8036
8091
  children
8037
8092
  });
8038
- const responsiveMode = themeRuntime.kind === "none" ? void 0 : themeRuntime.responsiveMode ?? (useContainerResponsiveMode ? "container" : "viewport");
8093
+ const responsiveMode = resolveDocumentResponsiveMode(themeRuntime, useContainerResponsiveMode);
8039
8094
  switch (themeRuntime.kind) {
8040
8095
  case "cms-theme": return /* @__PURE__ */ jsx(ThemeScope, {
8041
8096
  theme: effectiveTheme,
@@ -8052,6 +8107,32 @@ function PreviewThemedSiteDocument({ children, themeRuntime = defaultPreviewThem
8052
8107
  default: return assertNever$2(themeRuntime);
8053
8108
  }
8054
8109
  }
8110
+ function PreviewOverrideOnlySiteDocument({ children, runtime, useContainerResponsiveMode, viewportMode, viewportWidth, scale, contentHeight, scaleContainerRef, contentRef }) {
8111
+ const documentNode = renderPreviewDocument({
8112
+ viewportMode,
8113
+ viewportWidth,
8114
+ scale,
8115
+ contentHeight,
8116
+ scaleContainerRef,
8117
+ contentRef,
8118
+ siteDocumentPlan: planSiteDocument({
8119
+ headerPositioning: "static",
8120
+ headerVariant: null,
8121
+ hasVisibleBanner: false,
8122
+ hasVisibleHeader: false
8123
+ }),
8124
+ headerNode: null,
8125
+ bannerNode: null,
8126
+ footerNode: null,
8127
+ children
8128
+ });
8129
+ if (runtime.kind === "none") return documentNode;
8130
+ return /* @__PURE__ */ jsx(ResponsiveScope, {
8131
+ responsiveMode: runtime.responsiveMode ?? (useContainerResponsiveMode ? "container" : "viewport"),
8132
+ className: "rb-flex rb-flex-1 rb-flex-col",
8133
+ children: documentNode
8134
+ });
8135
+ }
8055
8136
  function renderPreviewDocument({ viewportMode, viewportWidth, scale, contentHeight, scaleContainerRef, contentRef, siteDocumentPlan, headerNode, bannerNode, footerNode, children }) {
8056
8137
  const framePlan = planPreviewDocumentFrame({
8057
8138
  viewportMode,
@@ -8175,23 +8256,88 @@ function LinkedEntryEditEventBridge() {
8175
8256
  }
8176
8257
  //#endregion
8177
8258
  //#region ../preview-next/src/client/preview/PreviewShellLayout.tsx
8259
+ function isOverrideOnlyPreviewShellLayout(props) {
8260
+ return props.rendering?.kind === "overrides-only";
8261
+ }
8262
+ function resolveShellThemeRoles(props) {
8263
+ if (isOverrideOnlyPreviewShellLayout(props)) return null;
8264
+ return resolvePreviewThemeRoles({
8265
+ theme: props.theme,
8266
+ renderTheme: props.renderTheme
8267
+ });
8268
+ }
8178
8269
  const previewContainerResponsiveEnabled = process.env.NEXT_PUBLIC_ENABLE_PREVIEW_CONTAINER_RESPONSIVE !== "false";
8179
8270
  const PreviewEditorSidebar = React.lazy(async () => {
8180
- return { default: (await import("./PreviewEditorSidebar-Dbvb7GIr.mjs")).PreviewEditorSidebar };
8271
+ return { default: (await import("./PreviewEditorSidebar-B43CJ0g_.mjs")).PreviewEditorSidebar };
8181
8272
  });
8182
8273
  const PreviewEditorUI = React.lazy(async () => {
8183
- return { default: (await import("./PreviewEditorUI-e9O9l20X.mjs")).PreviewEditorUI };
8274
+ return { default: (await import("./PreviewEditorUI-DHirVkeM.mjs")).PreviewEditorUI };
8184
8275
  });
8185
8276
  const previewPaneContainmentStyle = {
8186
8277
  contain: "layout paint",
8187
8278
  isolation: "isolate",
8188
8279
  transform: "translateZ(0)"
8189
8280
  };
8190
- function PreviewShellLayout({ children, theme, renderTheme, surfaceId, siteId, dashboardBaseUrl = null, pageId, entryData, contentTypeSchema, referenceContentTypeKeys = [], draftContent, currentTemplate, apiClient, bearerToken, themeId = null, themeSelectionId = null, themeSelectionVersion = null, themeSelectionUpdatedAt = null, themeSelectionButtonStyleSelection = null, themeSelectionHeaderLayoutId = null, themeSelectionHeaderStyleId = null, themeSelectionHeaderLookId = null, themeSelectionFooterLookId = null, themeSelectionHeaderContext, isSiteLaunched, maintenanceModeEnabled, entrySubrouteContext, assistantPanel, sdkConfig, bookingOfferingPresets, themeRuntime = defaultPreviewThemeRuntime, siteStyleAccess = { kind: "hidden" }, onFooterSaved }) {
8191
- const { persistenceTheme, documentTheme } = resolvePreviewThemeRoles({
8192
- theme,
8193
- renderTheme
8281
+ function renderShellProviders(input) {
8282
+ if (!input.themeRoles) return input.content;
8283
+ const { props, themeRoles } = input;
8284
+ return /* @__PURE__ */ jsx(PreviewThemeOverlayProvider, {
8285
+ baseTheme: themeRoles.documentTheme,
8286
+ children: /* @__PURE__ */ jsx(PreviewDesignCoordinatorProvider, { children: /* @__PURE__ */ jsx(SiteChromeCustomizeProvider, {
8287
+ siteId: props.siteId,
8288
+ apiClient: input.apiClient,
8289
+ theme: themeRoles.persistenceTheme,
8290
+ themeId: props.themeId ?? null,
8291
+ selectionId: props.themeSelectionId ?? null,
8292
+ selectionVersion: props.themeSelectionVersion ?? null,
8293
+ selectionUpdatedAt: props.themeSelectionUpdatedAt ?? null,
8294
+ initialSelections: {
8295
+ selectionVersion: props.themeSelectionVersion ?? null,
8296
+ selectionUpdatedAt: props.themeSelectionUpdatedAt ?? null,
8297
+ buttonStyleSelection: props.themeSelectionButtonStyleSelection ?? null,
8298
+ headerLayoutId: props.themeSelectionHeaderLayoutId ?? null,
8299
+ headerStyleId: props.themeSelectionHeaderStyleId ?? null,
8300
+ headerLookId: props.themeSelectionHeaderLookId ?? null,
8301
+ footerLookId: props.themeSelectionFooterLookId ?? null
8302
+ },
8303
+ headerSelectionContext: props.themeSelectionHeaderContext,
8304
+ siteStyleAccess: input.siteStyleAccess,
8305
+ canOpenDesignEditor: props.entryData == null && props.pageId !== null && canInspectSiteStyle(input.siteStyleAccess),
8306
+ children: input.content
8307
+ }) })
8194
8308
  });
8309
+ }
8310
+ function PreviewDocumentContent(input) {
8311
+ if (input.rendering?.kind === "overrides-only") return /* @__PURE__ */ jsx(PreviewOverrideOnlySiteDocument, {
8312
+ runtime: input.rendering.runtime,
8313
+ useContainerResponsiveMode: previewContainerResponsiveEnabled,
8314
+ viewportMode: input.viewportMode,
8315
+ viewportWidth: input.viewportWidth,
8316
+ scale: input.scale,
8317
+ contentHeight: input.contentHeight,
8318
+ scaleContainerRef: input.scaleContainerRef,
8319
+ contentRef: input.contentRef,
8320
+ children: input.children
8321
+ });
8322
+ return /* @__PURE__ */ jsx(PreviewChromeLayerProvider, { children: /* @__PURE__ */ jsx(PreviewThemedSiteDocument, {
8323
+ themeRuntime: input.themeRuntime,
8324
+ useContainerResponsiveMode: previewContainerResponsiveEnabled,
8325
+ viewportMode: input.viewportMode,
8326
+ viewportWidth: input.viewportWidth,
8327
+ scale: input.scale,
8328
+ contentHeight: input.contentHeight,
8329
+ scaleContainerRef: input.scaleContainerRef,
8330
+ contentRef: input.contentRef,
8331
+ staticHeaderNode: input.headerNode,
8332
+ bannerNode: input.bannerNode,
8333
+ staticFooterNode: input.footerNode,
8334
+ siteChromeRenderModel: input.siteChromeRenderModel,
8335
+ children: input.children
8336
+ }) });
8337
+ }
8338
+ function PreviewShellLayout(props) {
8339
+ const themeRoles = resolveShellThemeRoles(props);
8340
+ const { children, rendering, surfaceId, siteId, dashboardBaseUrl = null, pageId, entryData, contentTypeSchema, referenceContentTypeKeys = [], draftContent, currentTemplate, apiClient, bearerToken, themeId = null, themeSelectionId = null, themeSelectionVersion = null, themeSelectionUpdatedAt = null, themeSelectionButtonStyleSelection = null, themeSelectionHeaderLayoutId = null, themeSelectionHeaderStyleId = null, themeSelectionHeaderLookId = null, themeSelectionFooterLookId = null, themeSelectionHeaderContext, isSiteLaunched, maintenanceModeEnabled, entrySubrouteContext, assistantPanel, sdkConfig, bookingOfferingPresets, themeRuntime = defaultPreviewThemeRuntime, siteStyleAccess = { kind: "hidden" }, onFooterSaved } = props;
8195
8341
  const layout = useOptionalPreviewLayout();
8196
8342
  const headerNode = layout?.headerNode ?? null;
8197
8343
  const bannerNode = layout?.bannerNode ?? null;
@@ -8309,9 +8455,9 @@ function PreviewShellLayout({ children, theme, renderTheme, surfaceId, siteId, d
8309
8455
  const leftPane = /* @__PURE__ */ jsx("div", {
8310
8456
  className: "relative flex h-full min-h-0 flex-col overflow-auto bg-muted/30",
8311
8457
  style: previewPaneContainmentStyle,
8312
- children: /* @__PURE__ */ jsx(PreviewChromeLayerProvider, { children: /* @__PURE__ */ jsx(PreviewThemedSiteDocument, {
8458
+ children: /* @__PURE__ */ jsx(PreviewDocumentContent, {
8459
+ rendering,
8313
8460
  themeRuntime,
8314
- useContainerResponsiveMode: previewContainerResponsiveEnabled,
8315
8461
  viewportMode,
8316
8462
  viewportWidth,
8317
8463
  scale: useMemo(() => {
@@ -8337,12 +8483,12 @@ function PreviewShellLayout({ children, theme, renderTheme, surfaceId, siteId, d
8337
8483
  contentHeight,
8338
8484
  scaleContainerRef,
8339
8485
  contentRef,
8340
- staticHeaderNode: headerNode,
8486
+ headerNode,
8341
8487
  bannerNode,
8342
- staticFooterNode: footerNode,
8488
+ footerNode,
8343
8489
  siteChromeRenderModel,
8344
8490
  children
8345
- }) })
8491
+ })
8346
8492
  });
8347
8493
  const rightPane = /* @__PURE__ */ jsx("div", {
8348
8494
  className: `${PREVIEW_CHROME_THEME_CLASS_NAME} flex h-full min-h-0 flex-col overflow-hidden ${surfaceDocument.surfaceClassName ?? ""}`,
@@ -8359,7 +8505,7 @@ function PreviewShellLayout({ children, theme, renderTheme, surfaceId, siteId, d
8359
8505
  referenceContentTypeKeys,
8360
8506
  draftContent,
8361
8507
  currentTemplate,
8362
- theme: persistenceTheme,
8508
+ theme: themeRoles?.persistenceTheme,
8363
8509
  apiClient,
8364
8510
  bearerToken,
8365
8511
  themeId,
@@ -8393,68 +8539,103 @@ function PreviewShellLayout({ children, theme, renderTheme, surfaceId, siteId, d
8393
8539
  }, overlayScopeKey)
8394
8540
  })
8395
8541
  });
8396
- return /* @__PURE__ */ jsx(PreviewThemeOverlayProvider, {
8397
- baseTheme: documentTheme,
8398
- children: /* @__PURE__ */ jsx(PreviewDesignCoordinatorProvider, { children: /* @__PURE__ */ jsx(SiteChromeCustomizeProvider, {
8399
- siteId,
8400
- apiClient,
8401
- theme: persistenceTheme,
8402
- themeId,
8403
- selectionId: themeSelectionId,
8404
- selectionVersion: themeSelectionVersion,
8405
- selectionUpdatedAt: themeSelectionUpdatedAt,
8406
- initialSelections: {
8407
- selectionVersion: themeSelectionVersion,
8408
- selectionUpdatedAt: themeSelectionUpdatedAt,
8409
- buttonStyleSelection: themeSelectionButtonStyleSelection,
8410
- headerLayoutId: themeSelectionHeaderLayoutId,
8411
- headerStyleId: themeSelectionHeaderStyleId,
8412
- headerLookId: themeSelectionHeaderLookId,
8413
- footerLookId: themeSelectionFooterLookId
8414
- },
8415
- headerSelectionContext: themeSelectionHeaderContext,
8416
- siteStyleAccess,
8417
- canOpenDesignEditor: entryData == null && pageId !== null && canInspectSiteStyle(siteStyleAccess),
8418
- children: /* @__PURE__ */ jsxs(PreviewBlockCustomizeSelectionProvider, { children: [
8419
- /* @__PURE__ */ jsx(LinkedEntryEditEventBridge, {}),
8420
- /* @__PURE__ */ jsx(React.Suspense, {
8421
- fallback: null,
8422
- children: /* @__PURE__ */ jsx(PreviewEditorUI, {
8423
- dashboardBaseUrl,
8424
- inMaintenanceMode: maintenanceModeEnabled,
8425
- siteId,
8426
- surfaceId,
8427
- isSiteLaunched,
8428
- apiClient
8429
- })
8430
- }),
8431
- /* @__PURE__ */ jsx(PreviewAuthBanner, {
8542
+ return renderShellProviders({
8543
+ props,
8544
+ apiClient,
8545
+ siteStyleAccess,
8546
+ themeRoles,
8547
+ content: /* @__PURE__ */ jsxs(PreviewBlockCustomizeSelectionProvider, { children: [
8548
+ /* @__PURE__ */ jsx(LinkedEntryEditEventBridge, {}),
8549
+ /* @__PURE__ */ jsx(React.Suspense, {
8550
+ fallback: null,
8551
+ children: /* @__PURE__ */ jsx(PreviewEditorUI, {
8432
8552
  dashboardBaseUrl,
8433
- surfaceId
8434
- }),
8435
- /* @__PURE__ */ jsx("div", {
8436
- className: "fixed inset-0 overflow-hidden bg-background",
8437
- children: isOpen ? /* @__PURE__ */ jsx(ResizableSplitPane, {
8438
- left: leftPane,
8439
- right: rightPane,
8440
- defaultSplit: 100 - sidebarWidth,
8441
- minLeftWidth: 400,
8442
- minRightWidth: 320,
8443
- leftLabel: "Preview",
8444
- rightLabel: "Editor",
8445
- defaultTab: "right",
8446
- rightPaneClassName: "h-full min-h-0 overflow-hidden",
8447
- onSplitChange: (split) => handleSidebarWidthChange(100 - split),
8448
- splitPercent: 100 - sidebarWidth
8449
- }) : leftPane
8553
+ inMaintenanceMode: maintenanceModeEnabled,
8554
+ siteId,
8555
+ surfaceId,
8556
+ isSiteLaunched,
8557
+ apiClient
8450
8558
  })
8451
- ] })
8452
- }) })
8559
+ }),
8560
+ /* @__PURE__ */ jsx(PreviewAuthBanner, {
8561
+ dashboardBaseUrl,
8562
+ surfaceId
8563
+ }),
8564
+ /* @__PURE__ */ jsx("div", {
8565
+ className: "fixed inset-0 overflow-hidden bg-background",
8566
+ children: isOpen ? /* @__PURE__ */ jsx(ResizableSplitPane, {
8567
+ left: leftPane,
8568
+ right: rightPane,
8569
+ defaultSplit: 100 - sidebarWidth,
8570
+ minLeftWidth: 400,
8571
+ minRightWidth: 320,
8572
+ leftLabel: "Preview",
8573
+ rightLabel: "Editor",
8574
+ defaultTab: "right",
8575
+ rightPaneClassName: "h-full min-h-0 overflow-hidden",
8576
+ onSplitChange: (split) => handleSidebarWidthChange(100 - split),
8577
+ splitPercent: 100 - sidebarWidth
8578
+ }) : leftPane
8579
+ })
8580
+ ] })
8453
8581
  });
8454
8582
  }
8455
8583
  //#endregion
8456
8584
  //#region ../preview-next/src/client/preview/PreviewShell.tsx
8457
- function PreviewShell({ children, apiBaseUrl, blockApiConfig, siteId, siteSlug, editableId, previewSession, previewToken, dashboardBaseUrl = null, surfaceId, theme, renderTheme, themeId = null, themeSelectionId = null, themeSelectionVersion = null, themeSelectionUpdatedAt = null, themeSelectionButtonStyleSelection = null, themeSelectionHeaderLayoutId = null, themeSelectionHeaderStyleId = null, themeSelectionHeaderLookId = null, themeSelectionFooterLookId = null, themeSelectionHeaderContext, pageId, routeId, entryData, contentTypeSchema, referenceContentTypeKeys = [], draftContent, currentTemplate, initialStatus, initialBlocks, pageMetadata, isSiteLaunched, maintenanceModeEnabled, entrySubrouteContext, assistantPanel, sdkConfig, mediaAssets, bookingOfferingPresets, supabaseUrl, themeRuntime = defaultPreviewThemeRuntime, designEditorEligibility, hideSiteStyleConfigurator = false, baseFetch, onFooterSaved }) {
8585
+ function isOverrideOnlyPreviewShell(props) {
8586
+ return props.rendering?.kind === "overrides-only";
8587
+ }
8588
+ function resolveShellLayoutProps(input) {
8589
+ const { props } = input;
8590
+ return {
8591
+ surfaceId: props.surfaceId,
8592
+ siteId: props.siteId,
8593
+ dashboardBaseUrl: props.dashboardBaseUrl ?? null,
8594
+ pageId: props.pageId,
8595
+ entryData: props.entryData ?? null,
8596
+ contentTypeSchema: props.contentTypeSchema,
8597
+ referenceContentTypeKeys: props.referenceContentTypeKeys ?? [],
8598
+ draftContent: props.draftContent,
8599
+ currentTemplate: props.currentTemplate,
8600
+ apiClient: input.apiClient,
8601
+ bearerToken: props.previewToken,
8602
+ themeId: props.themeId ?? null,
8603
+ themeSelectionId: props.themeSelectionId ?? null,
8604
+ themeSelectionVersion: props.themeSelectionVersion ?? null,
8605
+ themeSelectionUpdatedAt: props.themeSelectionUpdatedAt ?? null,
8606
+ themeSelectionButtonStyleSelection: props.themeSelectionButtonStyleSelection ?? null,
8607
+ themeSelectionHeaderLayoutId: props.themeSelectionHeaderLayoutId ?? null,
8608
+ themeSelectionHeaderStyleId: props.themeSelectionHeaderStyleId ?? null,
8609
+ themeSelectionHeaderLookId: props.themeSelectionHeaderLookId ?? null,
8610
+ themeSelectionFooterLookId: props.themeSelectionFooterLookId ?? null,
8611
+ themeSelectionHeaderContext: props.themeSelectionHeaderContext,
8612
+ isSiteLaunched: props.isSiteLaunched,
8613
+ maintenanceModeEnabled: props.maintenanceModeEnabled,
8614
+ entrySubrouteContext: props.entrySubrouteContext,
8615
+ assistantPanel: props.assistantPanel,
8616
+ sdkConfig: props.sdkConfig ?? null,
8617
+ bookingOfferingPresets: props.bookingOfferingPresets,
8618
+ siteStyleAccess: input.siteStyleAccess,
8619
+ onFooterSaved: props.onFooterSaved
8620
+ };
8621
+ }
8622
+ function renderShellLayout(input) {
8623
+ const { props } = input;
8624
+ const layoutProps = resolveShellLayoutProps(input);
8625
+ return isOverrideOnlyPreviewShell(props) ? /* @__PURE__ */ jsx(PreviewShellLayout, {
8626
+ ...layoutProps,
8627
+ rendering: props.rendering,
8628
+ children: props.children
8629
+ }) : /* @__PURE__ */ jsx(PreviewShellLayout, {
8630
+ ...layoutProps,
8631
+ theme: props.theme,
8632
+ renderTheme: props.renderTheme,
8633
+ themeRuntime: props.themeRuntime ?? defaultPreviewThemeRuntime,
8634
+ children: props.children
8635
+ });
8636
+ }
8637
+ function PreviewShell(props) {
8638
+ const { children, apiBaseUrl, blockApiConfig, siteId, siteSlug, editableId, previewSession, previewToken, dashboardBaseUrl = null, surfaceId, themeId = null, themeSelectionId = null, themeSelectionVersion = null, themeSelectionUpdatedAt = null, themeSelectionButtonStyleSelection = null, themeSelectionHeaderLayoutId = null, themeSelectionHeaderStyleId = null, themeSelectionHeaderLookId = null, themeSelectionFooterLookId = null, themeSelectionHeaderContext, pageId, routeId, entryData, contentTypeSchema, referenceContentTypeKeys = [], draftContent, currentTemplate, initialStatus, initialBlocks, pageMetadata, isSiteLaunched, maintenanceModeEnabled, entrySubrouteContext, assistantPanel, sdkConfig, mediaAssets, bookingOfferingPresets, supabaseUrl, designEditorEligibility, hideSiteStyleConfigurator = false, baseFetch, onFooterSaved } = props;
8458
8639
  const apiClient = useMemo(() => createBearerAPIClient(previewToken, apiBaseUrl), [previewToken, apiBaseUrl]);
8459
8640
  const { designEditorEnabled, siteStyleAccess } = resolveShellAccess({
8460
8641
  previewSession,
@@ -8463,6 +8644,11 @@ function PreviewShell({ children, apiBaseUrl, blockApiConfig, siteId, siteSlug,
8463
8644
  entryData,
8464
8645
  hideSiteStyleConfigurator
8465
8646
  });
8647
+ const shellLayout = renderShellLayout({
8648
+ props,
8649
+ apiClient,
8650
+ siteStyleAccess
8651
+ });
8466
8652
  return /* @__PURE__ */ jsx(BlockApiProvider, {
8467
8653
  config: blockApiConfig,
8468
8654
  children: /* @__PURE__ */ jsx(PreviewQueryProvider, { children: /* @__PURE__ */ jsx(PreviewAuthInit, {
@@ -8495,41 +8681,7 @@ function PreviewShell({ children, apiBaseUrl, blockApiConfig, siteId, siteSlug,
8495
8681
  bearerToken: previewToken,
8496
8682
  supabaseUrl,
8497
8683
  mediaAssets,
8498
- children: [/* @__PURE__ */ jsx(PreviewKeepAliveClient, { baseFetch }), /* @__PURE__ */ jsx(PreviewShellLayout, {
8499
- theme,
8500
- renderTheme,
8501
- surfaceId,
8502
- siteId,
8503
- dashboardBaseUrl,
8504
- pageId,
8505
- entryData: entryData ?? null,
8506
- contentTypeSchema,
8507
- referenceContentTypeKeys,
8508
- draftContent,
8509
- currentTemplate,
8510
- apiClient,
8511
- bearerToken: previewToken,
8512
- themeId,
8513
- themeSelectionId,
8514
- themeSelectionVersion,
8515
- themeSelectionUpdatedAt,
8516
- themeSelectionButtonStyleSelection,
8517
- themeSelectionHeaderLayoutId,
8518
- themeSelectionHeaderStyleId,
8519
- themeSelectionHeaderLookId,
8520
- themeSelectionFooterLookId,
8521
- themeSelectionHeaderContext,
8522
- isSiteLaunched,
8523
- maintenanceModeEnabled,
8524
- entrySubrouteContext,
8525
- assistantPanel,
8526
- sdkConfig: sdkConfig ?? null,
8527
- bookingOfferingPresets,
8528
- themeRuntime,
8529
- siteStyleAccess,
8530
- onFooterSaved,
8531
- children
8532
- })]
8684
+ children: [/* @__PURE__ */ jsx(PreviewKeepAliveClient, { baseFetch }), shellLayout]
8533
8685
  })
8534
8686
  }) })
8535
8687
  })
@@ -10299,6 +10451,18 @@ function formatBlockKindLabel(blockKind) {
10299
10451
  }
10300
10452
  //#endregion
10301
10453
  //#region ../preview-next/src/client/blocks/pageDesignRuntimePreview.ts
10454
+ function resolveRuntimePreviewSourceForTheme(pageDesignState, theme) {
10455
+ if (!theme?.palette) return resolveRuntimePreviewSource({
10456
+ pageDesignState,
10457
+ surfaceResolutionContext: null
10458
+ });
10459
+ return resolveRuntimePreviewSource({
10460
+ pageDesignState,
10461
+ surfaceResolutionContext: surfaceResolutionContextFromTheme(theme),
10462
+ designRules: designRuntimeRulesForTheme(theme),
10463
+ componentRules: componentRuntimeRulesForTheme(theme)
10464
+ });
10465
+ }
10302
10466
  function pageDesignRuntimeProjectionFromSource(source) {
10303
10467
  if (source.kind === "preserve-server-runtime") return null;
10304
10468
  return runtimeContentDecorationProjectionFromEditorModel(source.editorModel, source.surfaceResolutionContext, source.designRules, source.componentRules);
@@ -10421,17 +10585,8 @@ function EditablePageRenderer(props) {
10421
10585
  }, [uiStore, renderStateVersion]);
10422
10586
  const linkedEntryDataContext = useMemo(() => applyLinkedEntryRenderOverlayToDataContext(pageRendererProps.dataContext, linkedEntryOverlays), [linkedEntryOverlays, pageRendererProps.dataContext]);
10423
10587
  const aiProjections = useMemo(() => previewProjectionsFromAiOverlays(uiStore.getState().aiOverlays), [uiStore, renderStateVersion]);
10424
- const surfaceResolutionContext = useMemo(() => hasThemePalette(pageRendererProps.theme) ? surfaceResolutionContextFromTheme(pageRendererProps.theme) : null, [pageRendererProps.theme]);
10425
- const runtimePreviewSource = useMemo(() => resolveRuntimePreviewSource({
10426
- pageDesignState,
10427
- surfaceResolutionContext,
10428
- designRules: designRuntimeRulesForTheme(pageRendererProps.theme),
10429
- componentRules: componentRuntimeRulesForTheme(pageRendererProps.theme)
10430
- }), [
10431
- pageDesignState,
10432
- pageRendererProps.theme,
10433
- surfaceResolutionContext
10434
- ]);
10588
+ const previewTheme = pageRendererProps.rendering?.kind === "overrides-only" ? null : pageRendererProps.theme;
10589
+ const runtimePreviewSource = useMemo(() => resolveRuntimePreviewSourceForTheme(pageDesignState, previewTheme), [pageDesignState, previewTheme]);
10435
10590
  const runtimeProjection = useMemo(() => pageDesignRuntimeProjectionFromSource(runtimePreviewSource), [runtimePreviewSource]);
10436
10591
  const renderProjections = useMemo(() => runtimeProjection ? [runtimeProjection] : [], [runtimeProjection]);
10437
10592
  const blockItemsForRender = useMemo(() => {
@@ -10504,7 +10659,7 @@ function EditablePageRenderer(props) {
10504
10659
  blockKind: block.kind,
10505
10660
  content,
10506
10661
  bookingOfferingPresets: pageRendererProps.dataContext?.bookingOfferingPresets ?? [],
10507
- theme: pageRendererProps.theme,
10662
+ theme: previewTheme,
10508
10663
  placement: planBlockToolbarPlacement({
10509
10664
  blocks: chromeBlocks,
10510
10665
  blockIndex,
@@ -10517,7 +10672,7 @@ function EditablePageRenderer(props) {
10517
10672
  blockItemsForRender,
10518
10673
  headerClearance,
10519
10674
  isEntryTemplatePage,
10520
- pageRendererProps.theme,
10675
+ previewTheme,
10521
10676
  renderProjections,
10522
10677
  renderPage?.blocks,
10523
10678
  uiStore
@@ -10825,9 +10980,6 @@ function buildBatchLoaderRequest(id, endpoint, params) {
10825
10980
  };
10826
10981
  }
10827
10982
  }
10828
- function hasThemePalette(theme) {
10829
- return Boolean(theme?.palette);
10830
- }
10831
10983
  function usePreviewHeaderClearance() {
10832
10984
  const [clearance, setClearance] = useState({ kind: "none" });
10833
10985
  useEffect(() => {
@@ -10900,66 +11052,49 @@ function getSdkConfigForBlockPicker(value) {
10900
11052
  return isSdkCustomBlockArray(customBlocks) ? { customBlocks } : {};
10901
11053
  }
10902
11054
  function SdkPreviewModeRuntime(props) {
10903
- const { apiBaseUrl, dashboardBaseUrl, siteId, siteSlug, previewSession, previewToken, content, blockOverrides, themeRuntime = defaultPreviewThemeRuntime } = props;
10904
- const resolvedDashboardBaseUrl = dashboardBaseUrl ?? deriveDashboardBaseUrlFromApiBaseUrl(apiBaseUrl);
10905
- const surfaceId = props.surfaceId ?? "core";
10906
- const parsedTheme = parseThemeForPersistence(content.theme);
10907
- if (!parsedTheme.ok) throw new Error(`Preview theme does not satisfy the canonical runtime contract: ${parsedTheme.error.kind}`);
10908
- const theme = parsedTheme.value;
10909
- const page = content.page;
10910
- const routeMap = content.routeMap ?? void 0;
10911
- const sdkConfig = getSdkConfigForBlockPicker(content.sdkConfig);
10912
- const customBlocks = isSdkCustomBlockArray(content.customBlocks) ? content.customBlocks : null;
10913
- const typedBlockOverrides = blockOverrides ?? null;
11055
+ const { apiBaseUrl, siteId, siteSlug, previewSession, previewToken } = props;
11056
+ const model = resolveSdkPreviewRuntimeModel(props);
11057
+ const { content, customBlocks, dataContext, initialBlocks, page, pageMetadata, resolvedDashboardBaseUrl, routeMap, sdkConfig, surfaceId, typedBlockOverrides } = model;
10914
11058
  const sdkConfigForEditor = useMemo(() => {
10915
11059
  const blocks = customBlocks ?? sdkConfig?.customBlocks ?? void 0;
10916
11060
  if (!blocks || blocks.length === 0) return null;
10917
11061
  return { customBlocks: blocks };
10918
11062
  }, [sdkConfig, customBlocks]);
10919
- const initialBlocks = (page.blocks ?? []).map((block, index) => ({
10920
- id: block.id ?? null,
10921
- kind: block.kind,
10922
- purpose: block.purpose ?? null,
10923
- orderIndex: index,
10924
- content: block.content ?? null,
10925
- draftContent: block.draftContent ?? null,
10926
- publishedContent: null,
10927
- bindings: block.bindings ?? null
10928
- }));
10929
- const pageMetadata = content.pageMetadata;
10930
- const pagesByIdentifier = content.pagesByIdentifier ?? void 0;
10931
- const entriesByIdentifier = content.entriesByIdentifier ?? void 0;
10932
- const dataContext = {
11063
+ const blockApiConfig = useMemo(() => ({
11064
+ baseUrl: apiBaseUrl,
11065
+ auth: {
11066
+ type: "bearer",
11067
+ token: previewToken
11068
+ },
10933
11069
  siteId,
11070
+ isPreview: true
11071
+ }), [
10934
11072
  apiBaseUrl,
10935
- portalToken: null,
10936
- resolvedData: content.resolvedData,
10937
- routes: routeMap,
10938
- pagesByIdentifier,
10939
- entriesByIdentifier,
10940
- occurrenceContext: null,
10941
- entrySubrouteContext: null,
10942
- contentEntry: null,
10943
- editableRouteMetadataFieldIds: null,
10944
- previewStage: "preview",
10945
- supabaseUrl: content.supabaseUrl,
10946
- mediaAssets: content.mediaAssets
10947
- };
10948
- return /* @__PURE__ */ jsx(PreviewShell, {
11073
+ previewToken,
11074
+ siteId
11075
+ ]);
11076
+ const editablePage = model.rendering.kind === "overrides-only" ? /* @__PURE__ */ jsx(EditablePageRenderer, {
11077
+ rendering: { kind: "overrides-only" },
11078
+ page,
11079
+ usePlaceholders: false,
11080
+ dataContext,
11081
+ routeMap,
11082
+ blockOverrides: typedBlockOverrides ?? {},
11083
+ sdkConfig: sdkConfig ?? void 0,
11084
+ customBlocks: customBlocks ?? void 0
11085
+ }) : /* @__PURE__ */ jsx(EditablePageRenderer, {
11086
+ theme: requireSdkPreviewTheme(model.theme),
11087
+ page,
11088
+ usePlaceholders: false,
11089
+ dataContext,
11090
+ routeMap,
11091
+ blockOverrides: typedBlockOverrides ?? void 0,
11092
+ sdkConfig: sdkConfig ?? void 0,
11093
+ customBlocks: customBlocks ?? void 0
11094
+ });
11095
+ const shellProps = {
10949
11096
  apiBaseUrl,
10950
- blockApiConfig: useMemo(() => ({
10951
- baseUrl: apiBaseUrl,
10952
- auth: {
10953
- type: "bearer",
10954
- token: previewToken
10955
- },
10956
- siteId,
10957
- isPreview: true
10958
- }), [
10959
- apiBaseUrl,
10960
- previewToken,
10961
- siteId
10962
- ]),
11097
+ blockApiConfig,
10963
11098
  siteId,
10964
11099
  siteSlug,
10965
11100
  editableId: content.pageId,
@@ -10967,7 +11102,6 @@ function SdkPreviewModeRuntime(props) {
10967
11102
  previewToken,
10968
11103
  dashboardBaseUrl: resolvedDashboardBaseUrl,
10969
11104
  surfaceId,
10970
- theme,
10971
11105
  pageId: content.pageId,
10972
11106
  routeId: content.routeId,
10973
11107
  initialStatus: "draft",
@@ -10980,20 +11114,89 @@ function SdkPreviewModeRuntime(props) {
10980
11114
  sdkConfig: sdkConfigForEditor,
10981
11115
  mediaAssets: content.mediaAssets,
10982
11116
  supabaseUrl: content.supabaseUrl,
10983
- themeRuntime,
10984
11117
  designEditorEligibility: { kind: "sdk-page" },
10985
- hideSiteStyleConfigurator: true,
10986
- children: /* @__PURE__ */ jsx(EditablePageRenderer, {
10987
- theme,
10988
- page,
10989
- usePlaceholders: false,
10990
- dataContext,
10991
- routeMap,
10992
- blockOverrides: typedBlockOverrides ?? void 0,
10993
- sdkConfig: sdkConfig ?? void 0,
10994
- customBlocks: customBlocks ?? void 0
10995
- })
11118
+ hideSiteStyleConfigurator: true
11119
+ };
11120
+ if (model.rendering.kind === "overrides-only") return /* @__PURE__ */ jsx(PreviewShell, {
11121
+ ...shellProps,
11122
+ rendering: model.rendering,
11123
+ children: editablePage
10996
11124
  });
11125
+ return /* @__PURE__ */ jsx(PreviewShell, {
11126
+ ...shellProps,
11127
+ theme: requireSdkPreviewTheme(model.theme),
11128
+ themeRuntime: model.rendering.themeRuntime,
11129
+ children: editablePage
11130
+ });
11131
+ }
11132
+ function requireSdkPreviewTheme(theme) {
11133
+ if (!theme) throw new Error("Themed SDK preview requires a canonical theme.");
11134
+ return theme;
11135
+ }
11136
+ function resolveSdkPreviewRuntimeModel(props) {
11137
+ const { apiBaseUrl, content, siteId } = props;
11138
+ const rendering = props.rendering ?? {
11139
+ kind: "themed",
11140
+ themeRuntime: props.themeRuntime ?? defaultPreviewThemeRuntime
11141
+ };
11142
+ const page = content.page;
11143
+ const routeMap = content.routeMap ?? void 0;
11144
+ const sdkConfig = getSdkConfigForBlockPicker(content.sdkConfig);
11145
+ const customBlocks = isSdkCustomBlockArray(content.customBlocks) ? content.customBlocks : null;
11146
+ const initialBlocks = (page.blocks ?? []).map((block, index) => ({
11147
+ id: block.id ?? null,
11148
+ kind: block.kind,
11149
+ purpose: block.purpose ?? null,
11150
+ orderIndex: index,
11151
+ content: block.content ?? null,
11152
+ draftContent: block.draftContent ?? null,
11153
+ publishedContent: null,
11154
+ bindings: block.bindings ?? null
11155
+ }));
11156
+ const commonModel = {
11157
+ content,
11158
+ customBlocks,
11159
+ dataContext: {
11160
+ siteId,
11161
+ apiBaseUrl,
11162
+ portalToken: null,
11163
+ previewToken: props.previewToken,
11164
+ resolvedData: content.resolvedData,
11165
+ routes: routeMap,
11166
+ pagesByIdentifier: content.pagesByIdentifier ?? void 0,
11167
+ entriesByIdentifier: content.entriesByIdentifier ?? void 0,
11168
+ occurrenceContext: null,
11169
+ entrySubrouteContext: null,
11170
+ contentEntry: null,
11171
+ editableRouteMetadataFieldIds: null,
11172
+ previewStage: "preview",
11173
+ supabaseUrl: content.supabaseUrl,
11174
+ mediaAssets: content.mediaAssets
11175
+ },
11176
+ initialBlocks,
11177
+ page,
11178
+ pageMetadata: content.pageMetadata,
11179
+ resolvedDashboardBaseUrl: props.dashboardBaseUrl ?? deriveDashboardBaseUrlFromApiBaseUrl(apiBaseUrl),
11180
+ routeMap,
11181
+ sdkConfig,
11182
+ surfaceId: props.surfaceId ?? "core",
11183
+ typedBlockOverrides: props.blockOverrides ?? null
11184
+ };
11185
+ if (rendering.kind === "overrides-only") return {
11186
+ ...commonModel,
11187
+ rendering,
11188
+ theme: null
11189
+ };
11190
+ return {
11191
+ ...commonModel,
11192
+ rendering,
11193
+ theme: parseSdkPreviewTheme(content.theme)
11194
+ };
11195
+ }
11196
+ function parseSdkPreviewTheme(value) {
11197
+ const parsedTheme = parseThemeForPersistence(value);
11198
+ if (!parsedTheme.ok) throw new Error(`Preview theme does not satisfy the canonical runtime contract: ${parsedTheme.error.kind}`);
11199
+ return parsedTheme.value;
10997
11200
  }
10998
11201
  function deriveDashboardBaseUrlFromApiBaseUrl(apiBaseUrl) {
10999
11202
  try {