@riverbankcms/sdk 0.136.0 → 0.137.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 (160) hide show
  1. package/CHANGELOG.md +101 -0
  2. package/dist/{PreviewEditorSidebar-BU5ZlhQR.mjs → PreviewEditorSidebar-Bn6cONPa.mjs} +8 -8
  3. package/dist/{PreviewEditorUI-9XkHL-bC.mjs → PreviewEditorUI-LAwXZPSx.mjs} +3 -3
  4. package/dist/{PreviewQueryProvider-wbEpXryy.mjs → PreviewQueryProvider-ztQUdsNo.mjs} +1 -1
  5. package/dist/{SdkPreviewModeRuntime-CnWmj-2B.mjs → SdkPreviewModeRuntime-BbbGsI_v.mjs} +596 -164
  6. package/dist/{SiteChromeCustomizeContext-B6d5zkog.mjs → SiteChromeCustomizeContext-BbkNSt5a.mjs} +2888 -1404
  7. package/dist/_dts/ai/src/contracts/proposals.d.ts +12 -298
  8. package/dist/_dts/ai/src/contracts/siteStyleProposalSchemas.d.ts +21 -14
  9. package/dist/_dts/ai/src/designer/themePatch.d.ts +5 -10
  10. package/dist/_dts/api/src/accessAdmin.d.ts +1 -9
  11. package/dist/_dts/api/src/accountApi.d.ts +49 -2
  12. package/dist/_dts/api/src/contentRuntime.d.ts +1 -4
  13. package/dist/_dts/api/src/domainConnection.d.ts +41 -0
  14. package/dist/_dts/api/src/endpoints.d.ts +194 -181
  15. package/dist/_dts/api/src/index.d.ts +4 -3
  16. package/dist/_dts/api/src/media.d.ts +19 -2
  17. package/dist/_dts/api/src/sdkContracts.d.ts +2 -15
  18. package/dist/_dts/api/src/sdkMediaContracts.d.ts +40 -0
  19. package/dist/_dts/api/src/sdkMediaEndpointDefinitions.d.ts +61 -0
  20. package/dist/_dts/api/src/sdkThemeWire.d.ts +15 -4
  21. package/dist/_dts/api/src/siteInfrastructure.d.ts +17 -23
  22. package/dist/_dts/api/src/siteManagementEndpoints.d.ts +7 -21
  23. package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +27 -3
  24. package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +37 -17
  25. package/dist/_dts/api/src/types.d.ts +1 -1
  26. package/dist/_dts/blocks/src/PageRenderer.d.ts +2 -2
  27. package/dist/_dts/blocks/src/index.d.ts +1 -1
  28. package/dist/_dts/blocks/src/pageRenderAdmission.d.ts +9 -0
  29. package/dist/_dts/blocks/src/pageRendererBlockSupport.d.ts +75 -0
  30. package/dist/_dts/blocks/src/pageRendererBoundaries.d.ts +2 -0
  31. package/dist/_dts/blocks/src/server.d.ts +1 -1
  32. package/dist/_dts/blocks/src/system/blocks/event-registration.d.ts +1 -1
  33. package/dist/_dts/blocks/src/system/runtime/api/client.d.ts +2 -1
  34. package/dist/_dts/blocks/src/system/runtime/hooks/useCalendarEvents.d.ts +3 -3
  35. package/dist/_dts/blocks/src/system/runtime/hooks/useCalendarEvents.state.d.ts +34 -22
  36. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/ErrorStep.d.ts +3 -5
  37. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.contract.d.ts +2 -0
  38. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.planning.d.ts +1 -1
  39. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/hooks.d.ts +2 -0
  40. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationErrorPresentation.d.ts +5 -0
  41. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationErrorRecovery.d.ts +25 -0
  42. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationWizardContext.d.ts +4 -0
  43. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationStripeReturn.d.ts +7 -3
  44. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.d.ts +2 -0
  45. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +5 -2
  46. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useWaitlistClaimRestoration.d.ts +2 -0
  47. package/dist/_dts/blocks/src/system/runtime/nodes/events/domain/capacity.d.ts +164 -0
  48. package/dist/_dts/blocks/src/system/runtime/nodes/events/domain/cta.d.ts +29 -0
  49. package/dist/_dts/blocks/src/system/runtime/nodes/events/domain/dates.d.ts +47 -0
  50. package/dist/_dts/blocks/src/system/runtime/nodes/events/domain/index.d.ts +14 -0
  51. package/dist/_dts/blocks/src/system/runtime/nodes/events/domain/people.d.ts +6 -0
  52. package/dist/_dts/blocks/src/system/runtime/nodes/events/domain/pricing.d.ts +31 -0
  53. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/OfferingTitle.d.ts +11 -0
  54. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/WeekAgendaView.d.ts +1 -1
  55. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/WeekBoardView.d.ts +1 -1
  56. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/index.d.ts +3 -1
  57. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/listingLayout.d.ts +23 -0
  58. package/dist/_dts/commerce/src/purchase/event-registration-errors.d.ts +57 -0
  59. package/dist/_dts/commerce/src/purchase/index.d.ts +1 -0
  60. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +8 -40
  61. package/dist/_dts/db/src/index.d.ts +1 -0
  62. package/dist/_dts/db/src/utils/postgrestFilter.d.ts +2 -0
  63. package/dist/_dts/media-core/src/bulkDeletePlanning.d.ts +4 -0
  64. package/dist/_dts/media-core/src/fileDomain.d.ts +3 -0
  65. package/dist/_dts/preview-next/src/client/preview/PreviewShell.d.ts +1 -0
  66. package/dist/_dts/preview-next/src/client/preview/PreviewShellLayout.d.ts +1 -0
  67. package/dist/_dts/preview-next/src/client/preview/SiteChromeCustomizeContext.d.ts +3 -2
  68. package/dist/_dts/preview-next/src/client/preview/siteChromeBrandPreferences.d.ts +1 -1
  69. package/dist/_dts/preview-next/src/client/preview/siteChromeQuickControlHistoryState.d.ts +2 -0
  70. package/dist/_dts/preview-next/src/client/preview/siteChromeQuickControlSaveRequest.d.ts +51 -0
  71. package/dist/_dts/preview-next/src/client/preview/siteChromeSavePlan.d.ts +24 -2
  72. package/dist/_dts/preview-next/src/client/preview/siteStylePreviewPlanner.d.ts +23 -1
  73. package/dist/_dts/preview-next/src/client/preview/usePersistedHeaderPreferences.d.ts +8 -0
  74. package/dist/_dts/sdk/src/public-api/contracts.d.ts +2 -1
  75. package/dist/_dts/sdk/src/version.d.ts +1 -1
  76. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  77. package/dist/_dts/theme-core/src/gradients/types.d.ts +5 -0
  78. package/dist/_dts/theme-core/src/header/interactionPalette.d.ts +25 -2
  79. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +3 -3
  80. package/dist/_dts/theme-core/src/schema.d.ts +12 -11
  81. package/dist/_dts/theme-core/src/site-styles/compilationPlan.d.ts +43 -3
  82. package/dist/_dts/theme-core/src/site-styles/curatedSiteStyles.d.ts +10 -0
  83. package/dist/_dts/theme-core/src/site-styles/headerBrandPresentation.d.ts +63 -0
  84. package/dist/_dts/theme-core/src/site-styles/headerBytesComparison.d.ts +30 -0
  85. package/dist/_dts/theme-core/src/site-styles/headerInteractionPalette.d.ts +50 -1
  86. package/dist/_dts/theme-core/src/site-styles/headerLayoutCatalog.d.ts +48 -9
  87. package/dist/_dts/theme-core/src/site-styles/headerPreferences.d.ts +162 -0
  88. package/dist/_dts/theme-core/src/site-styles/headerPreferencesPersistence.d.ts +73 -0
  89. package/dist/_dts/theme-core/src/site-styles/headerRecompile.d.ts +118 -0
  90. package/dist/_dts/theme-core/src/site-styles/headerStyleCompiler.d.ts +10 -1
  91. package/dist/_dts/theme-core/src/site-styles/headerStyleDefaults.d.ts +1 -1
  92. package/dist/_dts/theme-core/src/site-styles/headerStyleRecipe.d.ts +7 -0
  93. package/dist/_dts/theme-core/src/site-styles/index.d.ts +5 -0
  94. package/dist/_dts/theme-core/src/site-styles/previewCompiler.d.ts +1 -1
  95. package/dist/_dts/theme-core/src/site-styles/siteChromeBackgrounds.d.ts +20 -1
  96. package/dist/_dts/theme-core/src/site-styles/siteChromeNavPreferences.d.ts +43 -2
  97. package/dist/client/{BookingConsentAgreement-DCch21a6.mjs → BookingConsentAgreement--_fUCZe-.mjs} +2 -2
  98. package/dist/client/{DiscountCodeDisclosure-DIj1T59K.mjs → DiscountCodeDisclosure-BMipSoDJ.mjs} +1 -1
  99. package/dist/client/{EventCombined.client-BWVNlXTx.mjs → EventCombined.client-CwJOxn7A.mjs} +154 -178
  100. package/dist/client/{EventListing.client-DVFCDe3i.mjs → EventListing.client-eVwiylPW.mjs} +2 -2
  101. package/dist/client/{LeafletStaticMap-BY5mIHw9.mjs → LeafletStaticMap-IKenna5u.mjs} +1 -1
  102. package/dist/client/{accordion-CK29E8rG.mjs → accordion-MGAO3PuE.mjs} +1 -1
  103. package/dist/client/{bookingForm-DFvnet-N.mjs → bookingForm-CudlQPUu.mjs} +5 -5
  104. package/dist/client/bookings.mjs +418 -79
  105. package/dist/client/capacity-BW00PO7s.mjs +271 -0
  106. package/dist/client/{carousel-BVU5NQlb.mjs → carousel-BrbGJ2Jl.mjs} +1 -1
  107. package/dist/client/{cart-BNItcZVa.mjs → cart-Bq5eU0xZ.mjs} +3 -3
  108. package/dist/client/{checkout-Bu6iCdkP.mjs → checkout-BAFVRdrK.mjs} +3 -3
  109. package/dist/client/client.mjs +2919 -1918
  110. package/dist/client/{context-BImarOAq.mjs → context-DCkiHVdD.mjs} +8 -5
  111. package/dist/client/dates-2RPXHQy4.mjs +264 -0
  112. package/dist/client/{eventCalendar-DS2h-UXD.mjs → eventCalendar-B0O-hPF7.mjs} +10 -17
  113. package/dist/client/{eventCombined-Drt4Oq9p.mjs → eventCombined-DCkDaoDI.mjs} +3 -3
  114. package/dist/client/{eventDetails-Bl2vWgTX.mjs → eventDetails-D8GG2dnD.mjs} +5 -3
  115. package/dist/client/{eventListing-CS7PHY7v.mjs → eventListing-3ssV_bxz.mjs} +3 -3
  116. package/dist/client/{eventRegistration-D-j8eNy2.mjs → eventRegistration-bPQo3kVw.mjs} +562 -309
  117. package/dist/client/{form-RMpoLTyr.mjs → form-qMv8RDkk.mjs} +2 -2
  118. package/dist/client/{headerSection-BYE3Lb3k.mjs → headerSection-CH0Sc5hX.mjs} +2 -2
  119. package/dist/client/hooks.mjs +289 -32
  120. package/dist/client/{locationMap-BxSr7Kkh.mjs → locationMap-0_xlBnNI.mjs} +2 -2
  121. package/dist/client/{newsletterForm-DerbXwFC.mjs → newsletterForm-NUW7m9RI.mjs} +2 -2
  122. package/dist/client/{productDetail-4SZCLhAf.mjs → productDetail-FBEOM7jW.mjs} +3 -3
  123. package/dist/client/{productList-D7AP4GNq.mjs → productList-R0OSGhnn.mjs} +3 -3
  124. package/dist/client/{propsDecoder-pzBeCh14.mjs → propsDecoder-pYvx_Srl.mjs} +88 -380
  125. package/dist/client/rendering/client.mjs +2616 -1637
  126. package/dist/client/rendering/islands.mjs +17 -17
  127. package/dist/client/rendering.mjs +2710 -1702
  128. package/dist/client/{scrollToBlock-CduAKf8T.mjs → scrollToBlock-ByQv96M2.mjs} +1 -1
  129. package/dist/client/{shop-Cp5p_kGe.mjs → shop-RUG9DmRE.mjs} +6 -6
  130. package/dist/client/{shop-commerce-DicXYaYX.mjs → shop-commerce-B76Jz23B.mjs} +5 -5
  131. package/dist/client/{shop-commerce-store-CGWnpY4K.mjs → shop-commerce-store-QuQNdDsD.mjs} +1 -1
  132. package/dist/client/{shopShared-BDf9ljkm.mjs → shopShared-vXU1omwJ.mjs} +3 -3
  133. package/dist/client/{useEventFilters-DeeyGYuk.mjs → useEventFilters-ByuU6HLA.mjs} +33 -18
  134. package/dist/preview-next/before-render.mjs +79 -51
  135. package/dist/preview-next/client/runtime.mjs +4 -4
  136. package/dist/preview-next/keepAlive.mjs +79 -51
  137. package/dist/preview-next/middleware.mjs +79 -51
  138. package/dist/{previewAuthStore-DbqBol0V.mjs → previewAuthStore-L_cKW8Sb.mjs} +79 -51
  139. package/dist/{sdk-runtime-19MO27F0.mjs → sdk-runtime-sUMr5d70.mjs} +2 -2
  140. package/dist/{separator-DaPLtJ1f.mjs → separator-BIHkie5i.mjs} +1 -1
  141. package/dist/server/components.mjs +2077 -1274
  142. package/dist/server/config-validation.mjs +289 -32
  143. package/dist/server/config.mjs +289 -32
  144. package/dist/server/data.mjs +289 -32
  145. package/dist/server/index.mjs +80 -52
  146. package/dist/server/next.mjs +1822 -1111
  147. package/dist/server/page-converter.mjs +167 -31
  148. package/dist/server/prebuild.mjs +1 -1
  149. package/dist/server/rendering/server.mjs +1988 -1286
  150. package/dist/server/rendering.mjs +1943 -1182
  151. package/dist/server/routing.mjs +351 -86
  152. package/dist/server/server.mjs +293 -128
  153. package/dist/server/theme-bridge.mjs +52 -8
  154. package/dist/server/theme.mjs +27 -8
  155. package/dist/styles/index.css +15 -0
  156. package/package.json +1 -1
  157. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCapacity.d.ts +0 -48
  158. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/pricing.d.ts +0 -17
  159. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/utils.d.ts +0 -100
  160. /package/dist/_dts/blocks/src/system/runtime/nodes/events/{shared → domain}/destination.d.ts +0 -0
@@ -50,3 +50,8 @@ export declare const gradientConfigSchema: z.ZodObject<{
50
50
  }, z.core.$strip>>;
51
51
  }, z.core.$strip>;
52
52
  export type GradientConfig = z.infer<typeof gradientConfigSchema>;
53
+ export declare const gradientsSchema: z.ZodObject<{
54
+ button: z.ZodOptional<z.ZodNullable<z.ZodString>>;
55
+ hero: z.ZodOptional<z.ZodNullable<z.ZodString>>;
56
+ background: z.ZodOptional<z.ZodNullable<z.ZodString>>;
57
+ }, z.core.$strip>;
@@ -1,9 +1,27 @@
1
1
  import { z } from 'zod';
2
- export declare const headerInteractionPaletteValues: readonly ["primary", "secondary", "accent"];
2
+ /**
3
+ * The palettes that fill the nav link with a colour on hover and focus. Each
4
+ * one names a background/foreground token pair.
5
+ */
6
+ export declare const headerInteractionPillPaletteValues: readonly ["primary", "secondary", "accent"];
7
+ export type HeaderInteractionPillPalette = (typeof headerInteractionPillPaletteValues)[number];
8
+ /**
9
+ * "No pill": the nav link keeps whatever hover treatment its recipe compiled,
10
+ * and the palette step writes nothing at all (#1318 Phase 4c decision 2).
11
+ *
12
+ * It exists because "a colour change on hover, no filled background" was not
13
+ * expressible in the vocabulary, and it is what
14
+ * `anna-raven-therapy-and-yoga` and `kirtan-lucy` have rendered since before
15
+ * the palette existed. Without it those two rows can only be classified as a
16
+ * conscious visual change.
17
+ */
18
+ export declare const headerInteractionQuietPalette = "quiet";
19
+ export declare const headerInteractionPaletteValues: readonly ["primary", "secondary", "accent", "quiet"];
3
20
  export declare const headerInteractionPaletteSchema: z.ZodEnum<{
4
21
  accent: "accent";
5
22
  primary: "primary";
6
23
  secondary: "secondary";
24
+ quiet: "quiet";
7
25
  }>;
8
26
  export type HeaderInteractionPalette = z.infer<typeof headerInteractionPaletteSchema>;
9
27
  export type HeaderInteractionPalettePreference = 'recommended' | HeaderInteractionPalette;
@@ -11,4 +29,9 @@ export type HeaderInteractionPalettePair = Readonly<{
11
29
  backgroundToken: 'primary' | 'secondary' | 'accent';
12
30
  foregroundToken: 'onPrimary' | 'onSecondary' | 'onAccent';
13
31
  }>;
14
- export declare function headerInteractionPalettePair(palette: HeaderInteractionPalette): HeaderInteractionPalettePair;
32
+ /**
33
+ * Narrowed to the pill palettes on purpose: `'quiet'` has no token pair, and a
34
+ * caller that reaches this function without excluding it first is a type error
35
+ * rather than a runtime surprise.
36
+ */
37
+ export declare function headerInteractionPalettePair(palette: HeaderInteractionPillPalette): HeaderInteractionPalettePair;
@@ -419,7 +419,7 @@ export declare const mockThemes: {
419
419
  navColor?: string | null | undefined;
420
420
  navFontRole?: "heading" | "body" | undefined;
421
421
  navTextSize?: "base" | "sm" | "lg" | "xl" | "xs" | undefined;
422
- interactionPalette?: "accent" | "primary" | "secondary" | undefined;
422
+ interactionPalette?: "accent" | "primary" | "secondary" | "quiet" | undefined;
423
423
  container?: {
424
424
  rounded: "none" | "sm" | "md" | "lg" | "xl" | "2xl";
425
425
  border: boolean;
@@ -2702,7 +2702,7 @@ export declare const mockThemes: {
2702
2702
  navColor?: string | null | undefined;
2703
2703
  navFontRole?: "heading" | "body" | undefined;
2704
2704
  navTextSize?: "base" | "sm" | "lg" | "xl" | "xs" | undefined;
2705
- interactionPalette?: "accent" | "primary" | "secondary" | undefined;
2705
+ interactionPalette?: "accent" | "primary" | "secondary" | "quiet" | undefined;
2706
2706
  container?: {
2707
2707
  rounded: "none" | "sm" | "md" | "lg" | "xl" | "2xl";
2708
2708
  border: boolean;
@@ -4985,7 +4985,7 @@ export declare const mockThemes: {
4985
4985
  navColor?: string | null | undefined;
4986
4986
  navFontRole?: "heading" | "body" | undefined;
4987
4987
  navTextSize?: "base" | "sm" | "lg" | "xl" | "xs" | undefined;
4988
- interactionPalette?: "accent" | "primary" | "secondary" | undefined;
4988
+ interactionPalette?: "accent" | "primary" | "secondary" | "quiet" | undefined;
4989
4989
  container?: {
4990
4990
  rounded: "none" | "sm" | "md" | "lg" | "xl" | "2xl";
4991
4991
  border: boolean;
@@ -2,6 +2,8 @@ import { z } from 'zod';
2
2
  import { mediaIdentifierSchema, imageMediaSchema, mediaSchema, mediaTypeDiscriminants, persistableMediaSchema, videoMediaSchema } from './lib/media';
3
3
  import type { ExpandedPalette } from './palette/expandPalette';
4
4
  import { paletteSchema, type paletteMetaSchema } from './palette/schema';
5
+ import { gradientsSchema } from './gradients/types';
6
+ export { gradientsSchema } from './gradients/types';
5
7
  import { headerVariantValues, type headerVariantSchema } from './header/legacyHeaderVariant';
6
8
  import { headerContainerSchema } from './header/containerSchema';
7
9
  import { boxBackgroundOverlaySchema, boxBackgroundSchema } from './boxBackgroundSchema';
@@ -2463,6 +2465,7 @@ export declare const inputStyle: z.ZodObject<{
2463
2465
  inside: "inside";
2464
2466
  }>;
2465
2467
  }, z.core.$strip>;
2468
+ export declare const headerPositioningValues: readonly ["static", "sticky", "fixed"];
2466
2469
  declare const headerPositioning: z.ZodEnum<{
2467
2470
  fixed: "fixed";
2468
2471
  static: "static";
@@ -2905,10 +2908,10 @@ export declare const headerSchema: z.ZodObject<{
2905
2908
  sticky: "sticky";
2906
2909
  }>;
2907
2910
  shrinkOnScroll: z.ZodBoolean;
2908
- maxWidth: z.ZodEnum<{
2911
+ maxWidth: z.ZodDefault<z.ZodEnum<{
2909
2912
  full: "full";
2910
2913
  container: "container";
2911
- }>;
2914
+ }>>;
2912
2915
  scrollTreatment: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
2913
2916
  kind: z.ZodLiteral<"contrast-glass">;
2914
2917
  backgroundTone: z.ZodEnum<{
@@ -3234,6 +3237,7 @@ export declare const headerSchema: z.ZodObject<{
3234
3237
  accent: "accent";
3235
3238
  primary: "primary";
3236
3239
  secondary: "secondary";
3240
+ quiet: "quiet";
3237
3241
  }>>;
3238
3242
  container: z.ZodOptional<z.ZodObject<{
3239
3243
  rounded: z.ZodDefault<z.ZodEnum<{
@@ -4455,11 +4459,6 @@ declare const bodyTextSchema: z.ZodOptional<z.ZodObject<{
4455
4459
  }>>;
4456
4460
  }, z.core.$strip>>;
4457
4461
  }, z.core.$strip>>;
4458
- export declare const gradientsSchema: z.ZodObject<{
4459
- button: z.ZodOptional<z.ZodNullable<z.ZodString>>;
4460
- hero: z.ZodOptional<z.ZodNullable<z.ZodString>>;
4461
- background: z.ZodOptional<z.ZodNullable<z.ZodString>>;
4462
- }, z.core.$strip>;
4463
4462
  /**
4464
4463
  * Testimonial quote-mark treatment, owned by the site style (analogous to the
4465
4464
  * accordion icon). `style` is the coarse selector; the optional fields fine-tune
@@ -5110,10 +5109,10 @@ export declare const themeSchema: z.ZodObject<{
5110
5109
  sticky: "sticky";
5111
5110
  }>;
5112
5111
  shrinkOnScroll: z.ZodBoolean;
5113
- maxWidth: z.ZodEnum<{
5112
+ maxWidth: z.ZodDefault<z.ZodEnum<{
5114
5113
  full: "full";
5115
5114
  container: "container";
5116
- }>;
5115
+ }>>;
5117
5116
  scrollTreatment: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
5118
5117
  kind: z.ZodLiteral<"contrast-glass">;
5119
5118
  backgroundTone: z.ZodEnum<{
@@ -5439,6 +5438,7 @@ export declare const themeSchema: z.ZodObject<{
5439
5438
  accent: "accent";
5440
5439
  primary: "primary";
5441
5440
  secondary: "secondary";
5441
+ quiet: "quiet";
5442
5442
  }>>;
5443
5443
  container: z.ZodOptional<z.ZodObject<{
5444
5444
  rounded: z.ZodDefault<z.ZodEnum<{
@@ -9020,10 +9020,10 @@ export declare const themesTurnSchema: z.ZodObject<{
9020
9020
  sticky: "sticky";
9021
9021
  }>;
9022
9022
  shrinkOnScroll: z.ZodBoolean;
9023
- maxWidth: z.ZodEnum<{
9023
+ maxWidth: z.ZodDefault<z.ZodEnum<{
9024
9024
  full: "full";
9025
9025
  container: "container";
9026
- }>;
9026
+ }>>;
9027
9027
  scrollTreatment: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
9028
9028
  kind: z.ZodLiteral<"contrast-glass">;
9029
9029
  backgroundTone: z.ZodEnum<{
@@ -9349,6 +9349,7 @@ export declare const themesTurnSchema: z.ZodObject<{
9349
9349
  accent: "accent";
9350
9350
  primary: "primary";
9351
9351
  secondary: "secondary";
9352
+ quiet: "quiet";
9352
9353
  }>>;
9353
9354
  container: z.ZodOptional<z.ZodObject<{
9354
9355
  rounded: z.ZodDefault<z.ZodEnum<{
@@ -4,6 +4,7 @@ import type { ButtonStyleSelection } from '../buttons/styles/selection';
4
4
  import type { HeaderLayoutStyleSelection, HeaderLogoContext } from './headerLayoutStyles';
5
5
  import type { FooterLookId } from './footerLooks';
6
6
  import type { BrandDisplayMode, LogoSizePolicy } from './logoBranding';
7
+ import type { HeaderPreferences } from './headerPreferences';
7
8
  export type HeaderBrandPreferences = Readonly<{
8
9
  brandDisplay: BrandDisplayMode;
9
10
  logoSize: LogoSizePolicy;
@@ -15,10 +16,42 @@ export type HeaderRecompileDirective = Readonly<{
15
16
  selection: HeaderLayoutStyleSelection;
16
17
  brandPresentation: ReplacementBrandPresentation;
17
18
  }>;
18
- export type HeaderCompilationDirective = Readonly<{
19
+ /**
20
+ * "Leave the header as the user last chose it", expressed as intent rather
21
+ * than as bytes (#1318 Phase 4d).
22
+ *
23
+ * Until 4d this arm carried `header: Theme['header']` and the compiler returned
24
+ * it verbatim, which was a fourth authority over `theme.header`: bytes reached
25
+ * persistence without passing through a recipe. It now names the row whose
26
+ * intent is to be honoured, and the compiler recompiles from
27
+ * `(stored selection, preferences)` — the same pipeline every other write uses.
28
+ *
29
+ * `preferences` is the stored record when the caller holds one and `null` while
30
+ * the Phase 4c backfill has not reached the row, in which case the intent is
31
+ * read back out of `persistedTheme`'s own bytes by the Phase 4a reader. It is
32
+ * never "the defaults": a default here would be the hidden authority this slice
33
+ * removes.
34
+ */
35
+ export type HeaderPreserveDirective = Readonly<{
19
36
  kind: 'preserve';
20
- header: Theme['header'];
21
- }> | HeaderRecompileDirective;
37
+ /** The row's own persisted theme. Its intent is read; its bytes are not copied. */
38
+ persistedTheme: Theme;
39
+ preferences: HeaderPreferences | null;
40
+ /**
41
+ * Always the logo context, never `use-compiled-defaults` — which is why this
42
+ * is narrowed to the one arm rather than taking the whole union.
43
+ *
44
+ * The intent on this path is derived from the row's own bytes, and that
45
+ * derivation compares the persisted `logo` against **both** compiled
46
+ * candidates. Withholding the context leaves it one, so a `'recommended'` row
47
+ * classifies as `'plain'` and silently loses its logo treatment. Which mode
48
+ * then wins is `applyHeaderPreferences`'s business, from the record (D24).
49
+ */
50
+ brandPresentation: Extract<ReplacementBrandPresentation, {
51
+ kind: 'apply-logo-context';
52
+ }>;
53
+ }>;
54
+ export type HeaderCompilationDirective = HeaderPreserveDirective | HeaderRecompileDirective;
22
55
  export type FooterCompilationDirective = Readonly<{
23
56
  kind: 'preserve';
24
57
  footer: Theme['footer'];
@@ -69,3 +102,10 @@ export declare function replaceSiteStyleCompilationPlan(input: Readonly<{
69
102
  }>): Extract<SiteThemeCompilationPlan, {
70
103
  kind: 'replace-site-style';
71
104
  }>;
105
+ /**
106
+ * Writes the brand display / logo size preference onto the header's logo style.
107
+ *
108
+ * Moved here from preview-next in #1318 Phase 4a so the header preference
109
+ * pipeline can be composed once, in theme-core, rather than half in the client.
110
+ */
111
+ export declare function withHeaderBrandThemePreferences(theme: Theme, preferences: HeaderBrandPreferences): Theme;
@@ -146,6 +146,16 @@ export type CuratedSiteStyle = Readonly<{
146
146
  export declare function defaultButtonStyleSelectionForSiteStyle(siteStyle: CuratedSiteStyle): ButtonStyleSelection;
147
147
  export declare function defaultPaletteForSiteStyle(siteStyle: CuratedSiteStyle): KnownCuratedPaletteValueKey;
148
148
  export declare function defaultHeaderSelectionForSiteStyle(siteStyle: CuratedSiteStyle): HeaderLayoutStyleSelection;
149
+ /**
150
+ * The curated default selection together with the style choices that belong to
151
+ * it. Carrying the styles alongside the ids is what lets a caller fall back to
152
+ * the default layout without a second, nullable lookup that can never actually
153
+ * miss — the source of an unreachable throw before #1318 Phase 4a.
154
+ */
155
+ export declare function defaultHeaderCurationForSiteStyle(siteStyle: CuratedSiteStyle): Readonly<{
156
+ selection: HeaderLayoutStyleSelection;
157
+ styles: NonEmptyReadonlyArray<HeaderStyleChoice>;
158
+ }>;
149
159
  export declare function headerLayoutChoicesForSiteStyle(siteStyle: CuratedSiteStyle): NonEmptyReadonlyArray<HeaderLayoutChoice>;
150
160
  export declare function headerStyleChoicesForLayout(siteStyle: CuratedSiteStyle, layoutId: HeaderLayoutId): NonEmptyReadonlyArray<HeaderStyleChoice> | null;
151
161
  /**
@@ -0,0 +1,63 @@
1
+ import type { ThemeHeader } from '../schema';
2
+ /**
3
+ * Whether the header wears a brand presentation at all (#1318 Phase 4c).
4
+ *
5
+ * `applyHeaderBrandPresentation` is unconditional today: given a logo context
6
+ * it always writes a `logo` object carrying a resolved display, size and
7
+ * accommodation. That makes "this header has no brand presentation block" —
8
+ * which is what several live sites persist, including one whose site *does*
9
+ * have a logo asset — a state the preference record could not express, so a
10
+ * recompile would silently give the site a logo treatment it has never
11
+ * rendered.
12
+ *
13
+ * This is the third field in this phase with that shape, after the interaction
14
+ * palette and the nav text size: the persisted bytes carry intent the reader
15
+ * cannot say, so the recompile "corrects" it. The fix is the same one — widen
16
+ * the closed vocabulary with a named member and derive it by baseline
17
+ * comparison — and it is a *widening*, not a restyle: `'recommended'` is the
18
+ * default and reproduces today's behaviour exactly, so no row whose bytes carry
19
+ * a presentation compiles differently for `'plain'` existing.
20
+ *
21
+ * `'plain'` is deliberately not "preserve whatever bytes are there". It is a
22
+ * constructive instruction — *write no presentation block* — so Phase 4e's
23
+ * compiler, which builds the header from nothing, can produce it.
24
+ */
25
+ export declare const headerBrandPresentationValues: readonly ["recommended", "plain"];
26
+ export type HeaderBrandPresentationPreference = (typeof headerBrandPresentationValues)[number];
27
+ export declare const defaultHeaderBrandPresentation: HeaderBrandPresentationPreference;
28
+ /**
29
+ * What the row's own bytes say about the presentation mode.
30
+ *
31
+ * `unrecognised` is its own state for the same reason it is on the interaction
32
+ * palette: the record has no way to represent "a logo block nobody's rule
33
+ * produces", and answering `'plain'` for one would drop a treatment the site
34
+ * renders. An unrecognised row falls back to `'recommended'` in the record and
35
+ * is reported by the divergence report, which blocks the Phase 4e gate.
36
+ */
37
+ export type HeaderBrandPresentationBytesClassification = Readonly<{
38
+ kind: 'recommended';
39
+ }> | Readonly<{
40
+ kind: 'plain';
41
+ }> | Readonly<{
42
+ kind: 'unrecognised';
43
+ }>;
44
+ /**
45
+ * Which mode reproduces this row's persisted logo bytes.
46
+ *
47
+ * Both candidates are supplied rather than reconstructed here, because both are
48
+ * the compilation's own output and rebuilding either would be a second
49
+ * authority on what the modes mean. `'recommended'` is tested first so that a
50
+ * row the resolver already agrees with keeps the live mode; `'plain'` is the
51
+ * answer for the rows that carry no presentation — an absent block, or a block
52
+ * holding only the recipe's own brand typography.
53
+ */
54
+ export declare function classifyHeaderBrandPresentationBytes(persisted: ThemeHeader,
55
+ /** The header `'recommended'` produces for this row — presentation applied. */
56
+ recommended: ThemeHeader,
57
+ /** The header `'plain'` produces — the presentation step skipped. */
58
+ plain: ThemeHeader): HeaderBrandPresentationBytesClassification;
59
+ /**
60
+ * The preference the bytes express, or `null` when they express none the record
61
+ * can carry. `null` is the caller's cue to fall back to the default and say so.
62
+ */
63
+ export declare function readHeaderBrandPresentationFromBytes(persisted: ThemeHeader, recommended: ThemeHeader, plain: ThemeHeader): HeaderBrandPresentationPreference | null;
@@ -0,0 +1,30 @@
1
+ import type { ThemeHeader } from '../schema';
2
+ export type HeaderFieldDiff = Readonly<{
3
+ path: string;
4
+ left: unknown;
5
+ right: unknown;
6
+ }>;
7
+ /**
8
+ * Structural diff by JSON path. Values are compared through
9
+ * `JSON.stringify`, so a key present with the value `undefined` and an absent
10
+ * key read as the same thing — which is what `jsonb` does to them anyway
11
+ * (#1318 Correction 5).
12
+ */
13
+ export declare function diffJsonPaths(left: unknown, right: unknown, path?: string): readonly HeaderFieldDiff[];
14
+ export type CompiledHeaderComparison = Readonly<{
15
+ kind: 'equal';
16
+ }> | Readonly<{
17
+ kind: 'different';
18
+ diffs: readonly HeaderFieldDiff[];
19
+ differingPaths: readonly string[];
20
+ }>;
21
+ /**
22
+ * The Phase 4b equality assertion: does the header a client compiled match the
23
+ * one the server compiles from the same `(selection, preferences)`?
24
+ *
25
+ * Both sides go through a JSON round trip first, because the persisted form is
26
+ * `jsonb` and an in-memory `ctaVariant: undefined` is not a difference the
27
+ * database could ever store (#1318 Correction 5). Comparing the in-memory
28
+ * objects directly would report a mismatch that no save could produce.
29
+ */
30
+ export declare function compareCompiledHeaders(left: ThemeHeader, right: ThemeHeader): CompiledHeaderComparison;
@@ -10,7 +10,7 @@ export declare const clearSplitInteractionPalette: Readonly<{
10
10
  id: "interaction-palette";
11
11
  label: string;
12
12
  options: readonly [HeaderInteractionPaletteOption, ...HeaderInteractionPaletteOption[]];
13
- defaultOptionId: "accent" | "primary" | "secondary";
13
+ defaultOptionId: "accent" | "primary" | "secondary" | "quiet";
14
14
  }>;
15
15
  export type HeaderInteractionPaletteControlState = Readonly<{
16
16
  kind: 'unavailable';
@@ -30,3 +30,52 @@ export type HeaderInteractionPaletteControlState = Readonly<{
30
30
  }>;
31
31
  export declare function resolveHeaderInteractionPaletteControl(group: HeaderInteractionPaletteOptionGroup | undefined, preference: HeaderInteractionPalettePreference): HeaderInteractionPaletteControlState;
32
32
  export declare function applyHeaderInteractionPalette(header: ThemeHeader, group: HeaderInteractionPaletteOptionGroup | undefined, preference: HeaderInteractionPalettePreference): ThemeHeader;
33
+ /**
34
+ * What a persisted header's nav link style says about the palette.
35
+ *
36
+ * `'unrecognised'` is the arm that matters. `'quiet'` writes nothing and is
37
+ * therefore a fixed point of *every* header, so a fixed-point search alone
38
+ * would answer `'quiet'` for a pill nobody in the group produces — and a
39
+ * recompile under `'quiet'` would then drop that pill. Reporting the state
40
+ * instead means a row like that reaches a human through the Phase 4c report
41
+ * rather than losing its hover treatment quietly.
42
+ */
43
+ export type HeaderInteractionPaletteBytesClassification = Readonly<{
44
+ kind: 'derived';
45
+ preference: HeaderInteractionPalettePreference;
46
+ }> | Readonly<{
47
+ kind: 'unrecognised';
48
+ }> | Readonly<{
49
+ kind: 'no-palette';
50
+ }>;
51
+ /**
52
+ * Which option of `group` a persisted header's nav link style is the output of
53
+ * (#1318 Phase 4c decision 2).
54
+ *
55
+ * This is a baseline comparison rather than a pattern match on effect bytes.
56
+ * The palette overwrites its four fields unconditionally, so applying an option
57
+ * to a header leaves that header unchanged exactly when the header is already
58
+ * that option's output — which makes "which option produced these bytes" a
59
+ * fixed-point search over the closed option list.
60
+ *
61
+ * Order is load-bearing twice over:
62
+ *
63
+ * - `'recommended'` is tried first, so a row compiled from the recommendation
64
+ * derives the sentinel rather than the default option's own id. As with the
65
+ * structure rule, an explicit choice that happens to equal the default
66
+ * collapses to the sentinel; nothing in the bytes distinguishes the two.
67
+ * - `'quiet'` is tried last, because it writes nothing and is therefore a fixed
68
+ * point of every header. Reaching it means no pill option produced these
69
+ * bytes — which is what "this row renders no pill" means, *provided the row
70
+ * carries no pill*. `carriesPaletteShapedEffect` is that proviso: a
71
+ * palette-shaped nav link that no option reproduces is `'unrecognised'`, not
72
+ * `'quiet'`.
73
+ */
74
+ export declare function classifyHeaderInteractionPaletteBytes(header: ThemeHeader, group: HeaderInteractionPaletteOptionGroup | undefined): HeaderInteractionPaletteBytesClassification;
75
+ /**
76
+ * The preference `classifyHeaderInteractionPaletteBytes` derived, or `null`
77
+ * when the bytes express none — either because the style offers no palette or
78
+ * because they match no option it does offer. Callers that need to tell those
79
+ * two apart use the classification directly.
80
+ */
81
+ export declare function readHeaderInteractionPaletteFromBytes(header: ThemeHeader, group: HeaderInteractionPaletteOptionGroup | undefined): HeaderInteractionPalettePreference | null;
@@ -1,18 +1,57 @@
1
- import type { Theme } from '../schema';
2
- import { type HeaderBrandPresentationPlan, type HeaderBrandPresentationSelection, type LogoAccommodationOption } from './logoBranding';
3
- import { type HeaderLayoutId, type HeaderLogoContext, type HeaderStyleId } from './headerLayoutTypes';
1
+ import { type HeaderBrandPresentationPlan, type HeaderBrandPresentationSelection, type BrandDisplayMode, type LogoAccommodationOption, type LogoAccommodationPattern, type LogoSizePolicy } from './logoBranding';
2
+ import { type HeaderLayoutId, type HeaderLogoContext, type HeaderLogoDimensions, type HeaderLogoShape, type HeaderStyleId } from './headerLayoutTypes';
3
+ export declare function logoAccommodationProvidesBacking(pattern: LogoAccommodationPattern): boolean;
4
+ export type HeaderLogoAsset = Readonly<{
5
+ /** The site's stored logo, or `null` when it has none. */
6
+ asset: HeaderLogoDimensions | null;
7
+ /** The accommodation the row currently persists, if any. */
8
+ accommodation: LogoAccommodationPattern | undefined;
9
+ }>;
10
+ /**
11
+ * The single answer to "what shape is this site's logo" (#1318 Phase 4b).
12
+ *
13
+ * The server and the public frontend each had their own copy of this, and they
14
+ * disagreed on the one case that matters: a logo whose dimensions are unknown.
15
+ * The server assumed `horizontal`; the frontend asked whether the persisted
16
+ * accommodation brings its own backing and answered `square` if it does. The
17
+ * richer rule is the correct one — a badge or masthead accommodation is
18
+ * evidence about the asset that raw dimensions would otherwise supply — and it
19
+ * reduces to `horizontal` whenever there is no backing, so it subsumes the
20
+ * server's rule rather than contradicting it. The backing question goes through
21
+ * `logoAccommodationProvidesBacking`, so the pattern list has one home.
22
+ */
23
+ export declare function deriveHeaderLogoShape({ asset, accommodation, }: HeaderLogoAsset): HeaderLogoShape;
24
+ /**
25
+ * The site's logo as the header pipeline sees it, from the two database values
26
+ * that describe it: the asset (or its absence) and the accommodation the row
27
+ * currently persists, which is evidence about the asset when its dimensions are
28
+ * missing.
29
+ *
30
+ * One definition, shared by every shell that has to answer it — the dashboard's
31
+ * `loadHeaderLogoContextForSite`, the public frontend, and the Phase 4c repair
32
+ * generator — because a second copy is a second answer to "what shape is this
33
+ * site's logo", and the two former copies disagreed on exactly the case this
34
+ * one is careful about (#1318 Phase 4b/4c).
35
+ */
36
+ export declare function headerLogoShapeContext(input: HeaderLogoAsset & Readonly<{
37
+ /**
38
+ * The brand half of the preference record, when the caller holds one.
39
+ * Both members are optional because the public frontend reads them off
40
+ * the persisted header, where either can be absent; an absent one is left
41
+ * off the context rather than written as `undefined`, so the resolver's
42
+ * own `?? 'auto'` still decides.
43
+ */
44
+ brand?: Readonly<{
45
+ brandDisplay?: BrandDisplayMode;
46
+ logoSize?: LogoSizePolicy;
47
+ }>;
48
+ }>): HeaderLogoContext;
4
49
  export declare function resolveHeaderBrandPresentation(input: Readonly<{
5
50
  logo: HeaderLogoContext;
6
51
  accommodations: readonly LogoAccommodationOption[];
7
52
  allowDisplayFallback?: boolean;
8
53
  }>): HeaderBrandPresentationPlan;
9
54
  export declare function requireHeaderBrandPresentationSelection(plan: HeaderBrandPresentationPlan): HeaderBrandPresentationSelection;
10
- /**
11
- * Starts each compilation from the generated theme's header branch, then
12
- * clears optional nested styling fields that would otherwise leak from a
13
- * different header selection.
14
- */
15
- export declare function baseHeader(theme: Theme): Theme['header'];
16
55
  export declare const headerLayoutCatalog: readonly [{
17
56
  readonly id: HeaderLayoutId;
18
57
  readonly label: "Classic";
@@ -0,0 +1,162 @@
1
+ import type { Theme, ThemeHeader } from '../schema';
2
+ import { type SiteChromeBackgroundOverride } from './siteChromeBackgrounds';
3
+ import { type HeaderNavFontSizePreference, type HeaderNavTypographyPreference } from './siteChromeNavPreferences';
4
+ import type { HeaderInteractionPalettePreference } from '../header/interactionPalette';
5
+ import { type HeaderInteractionPaletteOptionGroup } from './headerInteractionPalette';
6
+ import { type HeaderBrandPresentationPreference } from './headerBrandPresentation';
7
+ import type { BrandDisplayMode, HeaderBrandPresentationSelection, LogoSizePolicy } from './logoBranding';
8
+ export type HeaderLogoTextIntent = NonNullable<ThemeHeader['logoText']>;
9
+ /**
10
+ * Site-agnostic overrides of the layout's structural defaults (#1318 D15).
11
+ *
12
+ * `'inherit'` means "take whatever the row's own (layout, recipe) compiles". It
13
+ * is a sentinel rather than an absent field so that "the user has not chosen"
14
+ * stays distinguishable from "the user chose the value that happens to equal
15
+ * the layout default" — the distinction an optional field cannot carry.
16
+ *
17
+ * `logoText` has a third state because the classic layout compiles a value and
18
+ * a row can legitimately carry none: `'none'` is an explicit "no logo text
19
+ * accommodation", which `'inherit'` would silently turn back into the layout's.
20
+ */
21
+ export type HeaderStructurePreferences = Readonly<{
22
+ positioning: 'inherit' | ThemeHeader['positioning'];
23
+ shrinkOnScroll: 'inherit' | boolean;
24
+ logoText: 'inherit' | 'none' | HeaderLogoTextIntent;
25
+ }>;
26
+ /**
27
+ * Everything a user can express about a header, as intent rather than as
28
+ * compiled bytes. The first six fields already persist inside `theme.header`
29
+ * today and have readers; `structure` is new (D15).
30
+ */
31
+ export type HeaderPreferences = Readonly<{
32
+ /**
33
+ * Whether the header wears a brand presentation at all. `'plain'` is the
34
+ * state several live rows persist — no `logo` block — which the record could
35
+ * not express before (#1318 Phase 4c decision 5b, D24).
36
+ */
37
+ brandPresentation: HeaderBrandPresentationPreference;
38
+ brandDisplay: BrandDisplayMode;
39
+ logoSize: LogoSizePolicy;
40
+ navFontRole: HeaderNavTypographyPreference;
41
+ navTextSize: HeaderNavFontSizePreference;
42
+ interactionPalette: HeaderInteractionPalettePreference;
43
+ background: SiteChromeBackgroundOverride;
44
+ structure: HeaderStructurePreferences;
45
+ }>;
46
+ export declare const defaultHeaderStructurePreferences: HeaderStructurePreferences;
47
+ export declare const defaultHeaderPreferences: HeaderPreferences;
48
+ /**
49
+ * The written-down backfill rule (#1318 Phase 4a): compare the persisted value
50
+ * against the value the row's own (layout, recipe) compiles, and emit
51
+ * `'inherit'` when they are equal, the explicit value when they are not.
52
+ *
53
+ * Equal-to-default therefore collapses to `'inherit'`. Nothing in the data
54
+ * distinguishes a deliberate "sticky, same as the default" from an untouched
55
+ * row, so the backfill does not pretend to recover it; going forward the editor
56
+ * records what the user picks and the distinction is real for new intent.
57
+ *
58
+ * Two qualifications on "the value it compiles", both of which keep the rule
59
+ * from inventing intent:
60
+ *
61
+ * 1. A value that no vocabulary accepts expresses nothing, so it derives to
62
+ * `'inherit'` rather than to whatever a fallback would have picked.
63
+ * 2. A field a later pipeline step overwrites unconditionally cannot carry
64
+ * intent at all. That is `shrinkOnScroll` on a display-logo row — see
65
+ * `headerBrandPresentationForcesShrink`.
66
+ */
67
+ export declare function readHeaderStructurePreferences(persisted: ThemeHeader, compiled: ThemeHeader): HeaderStructurePreferences;
68
+ /**
69
+ * Total over any persisted theme, including a malformed one: every field goes
70
+ * through a reader that closes over the vocabulary rather than trusting the
71
+ * stored value.
72
+ *
73
+ * `compiledHeader` is the structure baseline — the header this row's own
74
+ * (layout, recipe) compiles. It is a required parameter rather than something
75
+ * derived inside, because a `Theme` alone does not carry the selection ids the
76
+ * baseline needs; asking the caller for it keeps the rule single-valued.
77
+ *
78
+ * `navTextSize` is derived against that same baseline rather than read off
79
+ * `header.navTextSize` (#1318 Phase 4c decision 1). It is the one nav field a
80
+ * pre-preferences row could express only through the compiled bytes, so
81
+ * reading the marker alone loses it — see
82
+ * `readHeaderNavFontSizeAgainstBaseline`. `navFontRole` stays a marker read:
83
+ * unlike size, `navLinkStyle.typography` is written by the recipe's own
84
+ * treatment on every row, so a baseline comparison there would report the
85
+ * treatment's default role as user intent.
86
+ *
87
+ * `interactionPaletteGroup` is the palette the row's resolved recipe offers,
88
+ * and the same reasoning applies to it (#1318 Phase 4c decision 2): a row that
89
+ * predates the palette carries its hover treatment in the compiled bytes and
90
+ * nothing in `header.interactionPalette`. `undefined` means the caller does not
91
+ * know which palette applies — it is not "the style has none" — and the marker
92
+ * read stands.
93
+ *
94
+ * `brandPresentationCandidates` are the two headers the two presentation modes
95
+ * produce for this row. The mode is derived by comparing the persisted `logo`
96
+ * against both, so a row that carries no presentation block keeps having none
97
+ * instead of being given one it has never rendered (#1318 Phase 4c decision
98
+ * 5b). They are supplied rather than rebuilt here because they are the
99
+ * compilation's own output, and a second construction of them would be a second
100
+ * authority on what the modes mean — `headerBrandPresentationCandidates` builds
101
+ * them with the real appliers.
102
+ */
103
+ export declare function readHeaderPreferences(theme: Theme, compiledHeader: ThemeHeader, interactionPaletteGroup: HeaderInteractionPaletteOptionGroup | undefined, brandPresentationCandidates: HeaderBrandPresentationCandidates): HeaderPreferences;
104
+ /** The header each brand-presentation mode compiles to, for one row. */
105
+ export type HeaderBrandPresentationCandidates = Readonly<{
106
+ recommended: ThemeHeader;
107
+ plain: ThemeHeader;
108
+ }>;
109
+ /**
110
+ * Both candidates, built with the same two appliers the pipeline uses.
111
+ *
112
+ * There is no circularity to resolve: the only record fields that reach
113
+ * `header.logo` are `brandDisplay` and `logoSize`, and those are read straight
114
+ * off the persisted theme rather than derived. The structure preferences run
115
+ * before the presentation in the named order but touch `positioning`,
116
+ * `shrinkOnScroll` and `logoText` — never `logo` — so leaving them out here
117
+ * cannot change either answer.
118
+ *
119
+ * One known over-specification, recorded rather than fixed because it changes
120
+ * no bytes. `applyHeaderBrandPresentation` reads `positioning` when it decides
121
+ * whether to force `shrinkOnScroll` for a display logo, and it sees the
122
+ * *structure-adjusted* value at apply time while it sees the layout default
123
+ * here. On a `'recommended'` row that overrides positioning to `'static'` the
124
+ * candidate can therefore carry a forced `shrinkOnScroll` the applied header
125
+ * will not, which makes `readHeaderStructurePreferences` emit an explicit
126
+ * `shrinkOnScroll` where `'inherit'` would have done. The record is more
127
+ * specific than it needs to be; the compiled bytes are identical either way,
128
+ * because the explicit value it writes is the one the row already has. Fixing
129
+ * it means deriving `positioning` before the candidates, which is a second
130
+ * derivation pass for no byte change (#1318 Phase 4c review round 2, item 10).
131
+ */
132
+ export declare function headerBrandPresentationCandidates(theme: Theme, compiledBaseline: ThemeHeader, presentation: HeaderBrandPresentationSelection | null): HeaderBrandPresentationCandidates;
133
+ export declare function applyHeaderStructurePreferences(header: ThemeHeader, preferences: HeaderStructurePreferences): ThemeHeader;
134
+ /**
135
+ * The brand presentation step, which sits between the structure preferences and
136
+ * the nav/logo/background ones because it reads `positioning` and can force
137
+ * `shrinkOnScroll` for a display logo (`previewCompiler.ts`).
138
+ */
139
+ /**
140
+ * Writes a resolved brand presentation onto the header. Lives here rather than
141
+ * in `previewCompiler` so the pipeline step has one definition: it sits between
142
+ * the structure preferences and the nav/logo/background ones, and it is the
143
+ * reason that position is load-bearing — it reads `positioning` and can force
144
+ * `shrinkOnScroll` for a display logo that brings its own backing.
145
+ */
146
+ export declare function applyHeaderBrandPresentation(header: ThemeHeader, presentation: HeaderBrandPresentationSelection): ThemeHeader;
147
+ /**
148
+ * The preference half of the header pipeline, composed once so that no caller
149
+ * assembles its own order. Named order, tail of the recompile:
150
+ *
151
+ * structure preferences → brand presentation → brand display/logo size
152
+ * → nav preferences → header background override
153
+ *
154
+ * `brandPresentation` is data rather than a callback so the step is inspectable
155
+ * and cannot vary by caller; `null` is "this caller has no logo context".
156
+ *
157
+ * The background applier is the header-only one on purpose: the header+footer
158
+ * pair function would clobber footer intent (#1318 Correction 20).
159
+ */
160
+ export declare function applyHeaderPreferences(theme: Theme, preferences: HeaderPreferences, brandPresentation: HeaderBrandPresentationSelection | null): Theme;
161
+ /** The fields authored by header quick controls; structure and presentation belong to the row. */
162
+ export type HeaderQuickControlPreferences = Pick<HeaderPreferences, 'brandDisplay' | 'logoSize' | 'navFontRole' | 'navTextSize' | 'interactionPalette' | 'background'>;