@riverbankcms/sdk 0.104.1 → 0.104.3

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 (120) hide show
  1. package/dist/{PreviewEditorSidebar-CmaPXdKu.mjs → PreviewEditorSidebar-CBMhU9p_.mjs} +3 -3
  2. package/dist/{PreviewEditorUI-C5xRTh2b.mjs → PreviewEditorUI-C5KEw4M8.mjs} +2 -2
  3. package/dist/{SdkPreviewModeRuntime-Eks51NcN.mjs → SdkPreviewModeRuntime-Iq12HjL7.mjs} +1142 -177
  4. package/dist/{SiteChromeCustomizeContext-Bt8zb3qu.mjs → SiteChromeCustomizeContext-Cx0NMdyv.mjs} +1640 -877
  5. package/dist/_dts/ai/src/contracts/proposals.d.ts +10 -0
  6. package/dist/_dts/blocks/src/primitives/layout/Grid.d.ts +12 -8
  7. package/dist/_dts/blocks/src/system/blocks/events/event-calendar.d.ts +3 -0
  8. package/dist/_dts/blocks/src/system/blocks/events/shared/layout.d.ts +11 -1
  9. package/dist/_dts/blocks/src/system/blocks/testimonials.d.ts +7 -1
  10. package/dist/_dts/blocks/src/system/constants/events.d.ts +1 -1
  11. package/dist/_dts/blocks/src/system/fragments/library/testimonialsCarousel.d.ts +12 -0
  12. package/dist/_dts/blocks/src/system/node/validation-constants.d.ts +2 -2
  13. package/dist/_dts/blocks/src/system/runtime/nodes/basic.d.ts +14 -0
  14. package/dist/_dts/blocks/src/system/runtime/nodes/buttonAffordance.d.ts +33 -0
  15. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/WeekBoardView.d.ts +28 -0
  16. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCapacity.d.ts +32 -0
  17. package/dist/_dts/blocks/src/system/runtime/nodes/shared/contract-schemas.d.ts +1 -0
  18. package/dist/_dts/blocks/src/system/runtime/nodes/svg.d.ts +77 -0
  19. package/dist/_dts/blocks/src/system/transforms/registry/_utils/surfaceForegroundStyles.d.ts +2 -0
  20. package/dist/_dts/blocks/src/system/transforms/registry/boxStyles.d.ts +3 -40
  21. package/dist/_dts/blocks/src/system/transforms/registry/formatting.d.ts +14 -0
  22. package/dist/_dts/blocks/src/system/transforms/registry/layout.d.ts +11 -0
  23. package/dist/_dts/core/src/branded.d.ts +5 -0
  24. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +18 -0
  25. package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +2 -2
  26. package/dist/_dts/sdk/src/version.d.ts +1 -1
  27. package/dist/_dts/theme-core/src/ThemeScope.d.ts +1 -1
  28. package/dist/_dts/theme-core/src/buttons/affordanceIcons.d.ts +29 -0
  29. package/dist/_dts/theme-core/src/buttons/generateButtonCss.d.ts +6 -0
  30. package/dist/_dts/theme-core/src/buttons/index.d.ts +1 -0
  31. package/dist/_dts/theme-core/src/buttons/personalities/flat-ink.d.ts +20 -0
  32. package/dist/_dts/theme-core/src/buttons/personalities/index.d.ts +11 -0
  33. package/dist/_dts/theme-core/src/buttons/personalities/types.d.ts +4 -0
  34. package/dist/_dts/theme-core/src/buttons/types.d.ts +34 -0
  35. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  36. package/dist/_dts/theme-core/src/gradients/types.d.ts +27 -3
  37. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +51 -15
  38. package/dist/_dts/theme-core/src/palette/curated/brand-led.d.ts +13 -0
  39. package/dist/_dts/theme-core/src/palette/curated/index.d.ts +12 -0
  40. package/dist/_dts/theme-core/src/palette/historicalThemePalette.d.ts +44 -0
  41. package/dist/_dts/theme-core/src/palette/index.d.ts +1 -0
  42. package/dist/_dts/theme-core/src/palette/legacySelection.d.ts +13 -2
  43. package/dist/_dts/theme-core/src/palette/persistenceReadSource.d.ts +17 -2
  44. package/dist/_dts/theme-core/src/palette/themePaletteCompatibility.d.ts +3 -4
  45. package/dist/_dts/theme-core/src/runtime/themeCssVarNames.d.ts +1 -0
  46. package/dist/_dts/theme-core/src/schema.d.ts +108 -26
  47. package/dist/_dts/theme-core/src/site-styles/accessibleSurfaces.d.ts +2 -1
  48. package/dist/_dts/theme-core/src/site-styles/curatedSiteStyles.d.ts +50 -1
  49. package/dist/_dts/theme-core/src/site-styles/designState.d.ts +2 -2
  50. package/dist/_dts/theme-core/src/site-styles/generatedSchemas.d.ts +4 -2
  51. package/dist/_dts/theme-core/src/site-styles/headerLooks.d.ts +56 -1
  52. package/dist/_dts/theme-core/src/site-styles/typographyPresets.d.ts +16 -1
  53. package/dist/_dts/theme-core/src/status/index.d.ts +0 -1
  54. package/dist/_dts/theme-core/src/surfaces/foregroundContract.d.ts +19 -0
  55. package/dist/_dts/theme-core/src/surfaces/foregroundRoles.d.ts +9 -0
  56. package/dist/_dts/theme-core/src/surfaces/index.d.ts +2 -0
  57. package/dist/_dts/ui/src/button.d.ts +1 -1
  58. package/dist/cli/index.mjs +1558 -468
  59. package/dist/client/{DiscountCodeDisclosure-Dit2aItR.mjs → DiscountCodeDisclosure-BXM73_E5.mjs} +1 -1
  60. package/dist/client/{EventCombined.client-BnREyCjf.mjs → EventCombined.client-DT5elP7j.mjs} +4 -4
  61. package/dist/client/{EventListing.client-0uHld51x.mjs → EventListing.client-pTYGfV9C.mjs} +2 -2
  62. package/dist/client/{LeafletStaticMap-DJcvSfmj.mjs → LeafletStaticMap-dQrhlUe3.mjs} +1 -1
  63. package/dist/client/{MagicLinkForm-EAsIktfw.mjs → MagicLinkForm-u6Dul4j5.mjs} +2 -2
  64. package/dist/client/{StepIndicator-CRR17tYI.mjs → StepIndicator-nWqineJ2.mjs} +2 -2
  65. package/dist/client/{accordion-B47HIuuH.mjs → accordion-CSJcTUyH.mjs} +1 -1
  66. package/dist/client/{bookingForm-I1E-8F9P.mjs → bookingForm-C73wOuVa.mjs} +6 -6
  67. package/dist/client/bookings.mjs +137 -1
  68. package/dist/client/{buttons-BbPn8OKA.mjs → buttons-DfYyqt8C.mjs} +138 -2
  69. package/dist/client/{carousel-OlM7SyBs.mjs → carousel-fMBb0JSc.mjs} +1 -1
  70. package/dist/client/{cart-BKpG5jz6.mjs → cart-BtaCwT3S.mjs} +3 -3
  71. package/dist/client/{checkout-Dmmr6qoU.mjs → checkout-DkTwZSnh.mjs} +3 -3
  72. package/dist/client/client.mjs +2327 -542
  73. package/dist/client/{colorStyles-DuW4Fjqd.mjs → colorStyles-Wyl6JujD.mjs} +45 -4
  74. package/dist/client/{courseRegistration-CflZiqGk.mjs → courseRegistration-DnLmapJu.mjs} +7 -7
  75. package/dist/client/{eventCalendar-BvoLWcp-.mjs → eventCalendar-BvLOc9KY.mjs} +165 -5
  76. package/dist/client/{eventCombined-DsrO8t_t.mjs → eventCombined-kShgJPQr.mjs} +2 -2
  77. package/dist/client/{eventDetails-C3hxgcJm.mjs → eventDetails-C5NTM0Vo.mjs} +3 -3
  78. package/dist/client/{eventListing-C-hb237X.mjs → eventListing-B82ZdKP6.mjs} +2 -2
  79. package/dist/client/{eventRegistration-B0gyzDGi.mjs → eventRegistration-qJVFqBWo.mjs} +7 -7
  80. package/dist/client/{form-C_RUi6oJ.mjs → form-BvAcKiuu.mjs} +2 -2
  81. package/dist/client/{headerSection-IKQiD2U0.mjs → headerSection-NvAiEHAg.mjs} +3 -3
  82. package/dist/client/hooks.mjs +1034 -356
  83. package/dist/client/{locationMap-8ZBrMzRJ.mjs → locationMap-D0j52xfI.mjs} +3 -3
  84. package/dist/client/{media-CZJKL7fi.mjs → media-BCW_g2cQ.mjs} +1 -1
  85. package/dist/client/{newsletterForm-CYk3ucwj.mjs → newsletterForm-B8_i93qH.mjs} +2 -2
  86. package/dist/client/{pricing-B5GmvfIH.mjs → pricing-DIYnyHOk.mjs} +1 -1
  87. package/dist/client/{productDetail-BjS2Dqzo.mjs → productDetail-w0eAHkuQ.mjs} +3 -3
  88. package/dist/client/{productList-BOHvC8My.mjs → productList-Vsguq5Xt.mjs} +3 -3
  89. package/dist/client/{propsDecoder-WS6UEJwZ.mjs → propsDecoder-CD2pJ1WB.mjs} +37 -2
  90. package/dist/client/rendering/client.mjs +1722 -760
  91. package/dist/client/rendering/islands.mjs +19 -19
  92. package/dist/client/rendering.mjs +2303 -518
  93. package/dist/client/{shop-CON03-wN.mjs → shop-Dgxs-Q8F.mjs} +6 -6
  94. package/dist/client/{shop-commerce-DlqrFgH8.mjs → shop-commerce-DJAhsTaT.mjs} +6 -6
  95. package/dist/client/{shop-commerce-store-l74-Kne6.mjs → shop-commerce-store-CfCXltXW.mjs} +1 -1
  96. package/dist/client/{shopShared-CQheEXSg.mjs → shopShared-CmDcPXUt.mjs} +2 -2
  97. package/dist/client/{useDiscountCodeUi-v6OluyWl.mjs → useDiscountCodeUi-CirrT2bM.mjs} +1 -1
  98. package/dist/client/{useEventFilters-BqSTcNOf.mjs → useEventFilters-CNZxlCcO.mjs} +5 -5
  99. package/dist/client/{usePolling-DMfADjIF.mjs → usePolling-Baks_iBI.mjs} +2 -2
  100. package/dist/preview-next/client/runtime.mjs +3 -3
  101. package/dist/{sdk-runtime-BUmJ0DaT.mjs → sdk-runtime-BfNiFeNJ.mjs} +1 -1
  102. package/dist/{separator-Dd-JYok7.mjs → separator-BhAR_Xmf.mjs} +1 -1
  103. package/dist/server/components.mjs +2293 -531
  104. package/dist/server/config-validation.mjs +1040 -357
  105. package/dist/server/config.mjs +1040 -357
  106. package/dist/server/data.mjs +1034 -356
  107. package/dist/server/index.mjs +1 -1
  108. package/dist/server/next.mjs +2296 -534
  109. package/dist/server/page-converter.mjs +1018 -324
  110. package/dist/server/prebuild.mjs +1 -1
  111. package/dist/server/rendering/server.mjs +2278 -521
  112. package/dist/server/rendering.mjs +2293 -531
  113. package/dist/server/routing.mjs +1092 -338
  114. package/dist/server/server.mjs +1016 -338
  115. package/dist/server/theme-bridge.mjs +1240 -77
  116. package/dist/server/theme.mjs +165 -5
  117. package/dist/styles/index.css +617 -34
  118. package/package.json +1 -1
  119. package/dist/_dts/blocks/src/system/transforms/registry/_utils/sectionForegroundStyles.d.ts +0 -2
  120. package/dist/_dts/theme-core/src/status/contextualColors.d.ts +0 -6
@@ -367,6 +367,10 @@ const buttonBorderSchema = z$1.object({
367
367
  widthClass: z$1.string(),
368
368
  colorToken: themeColorTokenSchema
369
369
  });
370
+ const buttonVariantAffordanceSchema = z$1.object({
371
+ iconId: z$1.string().min(1),
372
+ colorToken: themeColorTokenSchema.optional()
373
+ });
370
374
  const variantShadowSchema = z$1.object({
371
375
  elevation: z$1.enum([
372
376
  "none",
@@ -420,7 +424,8 @@ const buttonVariantSchema = z$1.object({
420
424
  border: buttonBorderSchema.optional(),
421
425
  hoverBackgroundToken: z$1.string().optional(),
422
426
  effects: variantEffectsSchema.optional(),
423
- sizes: variantSizeOverridesSchema.optional()
427
+ sizes: variantSizeOverridesSchema.optional(),
428
+ affordance: buttonVariantAffordanceSchema.optional()
424
429
  });
425
430
  const buttonSystemSchema = z$1.object({
426
431
  global: buttonGlobalSettingsSchema,
@@ -998,6 +1003,136 @@ const editorialLink = defineButtonPersonality({
998
1003
  }
999
1004
  });
1000
1005
  //#endregion
1006
+ //#region ../theme-core/src/buttons/personalities/flat-ink.ts
1007
+ /**
1008
+ * Flat Ink — a solid ink primary, a hairline ghost secondary, and a single
1009
+ * amber accent climax, all completely flat (no drop shadow) with a modest
1010
+ * radius. Reads as grounded, editorial and clinician-precise: the Fulcrum
1011
+ * physiotherapy voice. The primary shifts to the secondary (moss) on hover and
1012
+ * every variant lifts 2px; the amber accent is meant to be used sparingly as
1013
+ * the page's one conversion climax.
1014
+ */
1015
+ const flatInk = defineButtonPersonality({
1016
+ id: "flat-ink",
1017
+ name: "Flat Ink",
1018
+ description: "Flat solid-ink primary, hairline ghost secondary, and a single amber accent climax — modest radius, no shadow.",
1019
+ tags: {
1020
+ tone: "classic",
1021
+ energy: "calm",
1022
+ motion: "subtle",
1023
+ era: "editorial"
1024
+ },
1025
+ buttonSystem: {
1026
+ global: {
1027
+ cornerStyle: "rounded",
1028
+ shadow: "low",
1029
+ textTransform: "none",
1030
+ fontWeight: 600,
1031
+ borderWidth: 1,
1032
+ typography: "body",
1033
+ letterSpacing: "tight",
1034
+ paddingPreset: "default",
1035
+ hoverTransform: "lift",
1036
+ hoverColor: "none"
1037
+ },
1038
+ sizes: {
1039
+ sm: {
1040
+ padding: "0.625rem 1.125rem",
1041
+ fontSize: "text-sm"
1042
+ },
1043
+ md: { padding: "0.8125rem 1.375rem" },
1044
+ lg: {
1045
+ padding: "0.9375rem 1.625rem",
1046
+ fontSize: "text-lg"
1047
+ },
1048
+ xl: {
1049
+ padding: "1.0625rem 2rem",
1050
+ fontSize: "text-xl"
1051
+ }
1052
+ },
1053
+ variants: [
1054
+ {
1055
+ id: "primary",
1056
+ name: "Primary",
1057
+ enabled: true,
1058
+ priority: 1,
1059
+ background: {
1060
+ type: "solid",
1061
+ colorToken: "primary"
1062
+ },
1063
+ textColorToken: "primaryForeground",
1064
+ borderRadius: "rounded-lg",
1065
+ affordance: {
1066
+ iconId: "ArrowRight",
1067
+ colorToken: "accent"
1068
+ },
1069
+ shadow: {
1070
+ elevation: "none",
1071
+ softness: null,
1072
+ position: "bottom"
1073
+ },
1074
+ effects: { hover: [{
1075
+ effectId: "lift",
1076
+ options: { translateY: "-2px" }
1077
+ }, {
1078
+ effectId: "background-on-hover",
1079
+ options: { colorToken: "secondary" }
1080
+ }] }
1081
+ },
1082
+ {
1083
+ id: "secondary",
1084
+ name: "Secondary",
1085
+ enabled: true,
1086
+ priority: 2,
1087
+ background: { type: "transparent" },
1088
+ textColorToken: "primary",
1089
+ borderRadius: "rounded-lg",
1090
+ border: {
1091
+ widthClass: "border",
1092
+ colorToken: "border"
1093
+ },
1094
+ shadow: {
1095
+ elevation: "none",
1096
+ softness: null,
1097
+ position: "bottom"
1098
+ },
1099
+ effects: { hover: [{
1100
+ effectId: "lift",
1101
+ options: { translateY: "-2px" }
1102
+ }, {
1103
+ effectId: "background-on-hover",
1104
+ options: { colorToken: "surfaceAlt" }
1105
+ }] }
1106
+ },
1107
+ {
1108
+ id: "accent",
1109
+ name: "Accent",
1110
+ enabled: true,
1111
+ priority: 3,
1112
+ background: {
1113
+ type: "solid",
1114
+ colorToken: "accent"
1115
+ },
1116
+ textColorToken: "accentForeground",
1117
+ borderRadius: "rounded-lg",
1118
+ shadow: {
1119
+ elevation: "none",
1120
+ softness: null,
1121
+ position: "bottom"
1122
+ },
1123
+ affordance: {
1124
+ iconId: "ArrowRight",
1125
+ colorToken: "accentForeground"
1126
+ },
1127
+ effects: { hover: [{
1128
+ effectId: "lift",
1129
+ options: { translateY: "-2px" }
1130
+ }] }
1131
+ }
1132
+ ]
1133
+ }
1134
+ });
1135
+ //#endregion
1001
1136
  //#region ../theme-core/src/buttons/personalities/ink-stamp.ts
1002
1137
  /**
1003
1138
  * Ink Stamp — solid earthy fills with a bordered, hand-stamped block-print
@@ -1768,6 +1903,7 @@ const buttonPersonalities = [
1768
1903
  editorialLink,
1769
1904
  pebble,
1770
1905
  inkStamp,
1906
+ flatInk,
1771
1907
  brushedWash,
1772
1908
  showtimePill,
1773
1909
  joyStamp,
@@ -2019,17 +2155,60 @@ const cardVariantSchema = z$1.object({
2019
2155
  });
2020
2156
  const cardSystemSchema = z$1.object({ variants: z$1.array(cardVariantSchema).min(1).max(3) });
2021
2157
  //#endregion
2022
- //#region ../theme-core/src/status/contextualColors.ts
2023
- const STATUS_MUTED_COLOR_VAR = "--rb-status-muted-color";
2024
- const DEFAULT_STATUS_MUTED_COLOR = "rgb(var(--tb-mutedText))";
2025
- function statusMutedColorValue() {
2026
- return `var(${STATUS_MUTED_COLOR_VAR}, ${DEFAULT_STATUS_MUTED_COLOR})`;
2158
+ //#region ../theme-core/src/surfaces/foregroundRoles.ts
2159
+ const SURFACE_FOREGROUND_ROLES = [
2160
+ "text",
2161
+ "heading",
2162
+ "link",
2163
+ "supporting"
2164
+ ];
2165
+ //#endregion
2166
+ //#region ../theme-core/src/surfaces/foregroundContract.ts
2167
+ const SURFACE_FOREGROUND_CSS_VARS = {
2168
+ text: "--rb-surface-text-color",
2169
+ heading: "--rb-surface-heading-color",
2170
+ link: "--rb-surface-link-color",
2171
+ supporting: "--rb-surface-supporting-color"
2172
+ };
2173
+ const DEFAULT_SURFACE_TEXT_COLOR = "rgb(var(--tb-text, 17 24 39))";
2174
+ const DEFAULT_ROLE_FALLBACKS = {
2175
+ text: DEFAULT_SURFACE_TEXT_COLOR,
2176
+ heading: DEFAULT_SURFACE_TEXT_COLOR,
2177
+ link: "rgb(var(--tb-primary, var(--tb-text, 17 24 39)))",
2178
+ supporting: "rgb(var(--tb-mutedText, 100 116 139))"
2179
+ };
2180
+ function requireSurfaceColorValue(role, value) {
2181
+ const normalized = value.trim();
2182
+ if (normalized.length === 0) throw new RangeError(`Surface foreground ${role} must be a non-empty CSS color.`);
2183
+ return normalized;
2184
+ }
2185
+ function completeSurfaceForegrounds(input) {
2186
+ const text = requireSurfaceColorValue("text", input.text);
2187
+ return {
2188
+ text,
2189
+ heading: input.heading === void 0 ? text : requireSurfaceColorValue("heading", input.heading),
2190
+ link: input.link === void 0 ? text : requireSurfaceColorValue("link", input.link),
2191
+ supporting: input.supporting === void 0 ? text : requireSurfaceColorValue("supporting", input.supporting)
2192
+ };
2027
2193
  }
2028
- function statusMutedColorDeclaration() {
2029
- return `color: ${statusMutedColorValue()};`;
2194
+ function surfaceForegroundValue(role, outsideProviderFallback = DEFAULT_ROLE_FALLBACKS[role]) {
2195
+ const roleVariable = SURFACE_FOREGROUND_CSS_VARS[role];
2196
+ const fallback = requireSurfaceColorValue("fallback", outsideProviderFallback);
2197
+ if (role === "text") return `var(${roleVariable}, ${fallback})`;
2198
+ return `var(${roleVariable}, var(${SURFACE_FOREGROUND_CSS_VARS.text}, ${fallback}))`;
2199
+ }
2200
+ function surfaceForegroundDeclarations(input) {
2201
+ const foregrounds = completeSurfaceForegrounds(input);
2202
+ return [`color: ${foregrounds.text}`, ...SURFACE_FOREGROUND_ROLES.map((role) => `${SURFACE_FOREGROUND_CSS_VARS[role]}: ${foregrounds[role]}`)];
2030
2203
  }
2031
2204
  //#endregion
2032
2205
  //#region ../theme-core/src/cards/core.ts
2206
+ /**
2207
+ * Core Card CSS Generator
2208
+ *
2209
+ * Pure functions for generating card CSS without requiring the full Theme type.
2210
+ * Used by both the full CMS theme system and the SDK theme bridge.
2211
+ */
2033
2212
  const CORNER_RADIUS_MAP$1 = {
2034
2213
  square: "0",
2035
2214
  soft: "0.5rem",
@@ -2123,14 +2302,21 @@ function generateVariantCss(scopeId, variant, settings) {
2123
2302
  const mediaSelector = `${containerSelector} .card-media`;
2124
2303
  const contentSelector = `${containerSelector} .card-content`;
2125
2304
  const containerRules = [];
2126
- if (variant.background === "solid" && variant.backgroundToken) containerRules.push(`background: rgb(var(--tb-${variant.backgroundToken}))`);
2127
- else if (variant.background === "gradient" && variant.gradientFromToken && variant.gradientToToken) {
2305
+ let ownsBackground = false;
2306
+ if (variant.background === "solid" && variant.backgroundToken) {
2307
+ containerRules.push(`background: rgb(var(--tb-${variant.backgroundToken}))`);
2308
+ ownsBackground = true;
2309
+ } else if (variant.background === "gradient" && variant.gradientFromToken && variant.gradientToToken) {
2128
2310
  const fromColor = `rgb(var(--tb-${variant.gradientFromToken}))`;
2129
2311
  const toColor = `rgb(var(--tb-${variant.gradientToToken}))`;
2130
2312
  const direction = GRADIENT_DIRECTION_MAP[variant.gradientDirection ?? "to-r"];
2131
2313
  containerRules.push(`background: linear-gradient(${direction}, ${fromColor}, ${toColor})`);
2314
+ ownsBackground = true;
2132
2315
  } else containerRules.push("background: transparent");
2133
- if (variant.foregroundToken) containerRules.push(`color: rgb(var(--tb-${variant.foregroundToken}))`);
2316
+ if (ownsBackground) {
2317
+ const foreground = `rgb(var(--tb-${variant.foregroundToken ?? "text"}))`;
2318
+ containerRules.push(...surfaceForegroundDeclarations({ text: foreground }));
2319
+ }
2134
2320
  if (variant.accentEdge) {
2135
2321
  const side = ACCENT_EDGE_SIDE_MAP[variant.accentEdge.edge];
2136
2322
  const width = ACCENT_EDGE_WIDTH_MAP[variant.accentEdge.width];
@@ -2407,11 +2593,31 @@ const gradientStopSchema = z$1.object({
2407
2593
  position: z$1.number().min(0).max(100)
2408
2594
  });
2409
2595
  /**
2410
- * Gradient configuration
2596
+ * Radial gradient shape. Optional; defaults to `circle` (the historical shape)
2597
+ * so existing radial gradients are byte-identical.
2598
+ *
2599
+ * Named `RadialGradientShape` to avoid clashing with `styles/gradients.ts`'s
2600
+ * `GradientShape` (which names the gradient *kind*: linear/radial/conic).
2601
+ */
2602
+ const radialGradientShapeSchema = z$1.enum(["circle", "ellipse"]);
2603
+ /**
2604
+ * Gradient configuration.
2605
+ *
2606
+ * `type` is optional and defaults to `'linear'` so gradients persisted without a
2607
+ * type (or with an explicit `'linear'`) render exactly as before. `'radial'` and
2608
+ * `'conic'` are additive kinds:
2609
+ * - linear: `angle` (degrees)
2610
+ * - radial: optional `shape` (circle/ellipse) + `position`
2611
+ * - conic: optional `angle` (from-angle, degrees) + `position`
2411
2612
  */
2412
2613
  const gradientConfigSchema = z$1.object({
2413
- type: z$1.enum(["linear", "radial"]),
2614
+ type: z$1.enum([
2615
+ "linear",
2616
+ "radial",
2617
+ "conic"
2618
+ ]).default("linear"),
2414
2619
  angle: z$1.number().min(0).max(360).optional(),
2620
+ shape: radialGradientShapeSchema.optional(),
2415
2621
  position: z$1.string().optional(),
2416
2622
  stops: z$1.array(gradientStopSchema).min(2)
2417
2623
  });
@@ -3038,7 +3244,7 @@ function parseToken(source) {
3038
3244
  if (parts.kind === "invalid") return { token: source };
3039
3245
  return {
3040
3246
  token: parts.token,
3041
- alpha: parts.opacityPercent === null ? void 0 : parts.opacityPercent / 100
3247
+ opacityPercent: parts.opacityPercent === null ? void 0 : parts.opacityPercent
3042
3248
  };
3043
3249
  }
3044
3250
  /**
@@ -3054,11 +3260,26 @@ function parseToken(source) {
3054
3260
  * rgbColorValue('raw:transparent') // => 'transparent'
3055
3261
  */
3056
3262
  function rgbColorValue(token) {
3057
- const { token: baseToken, alpha, raw } = parseToken(token);
3263
+ const { token: baseToken, opacityPercent, raw } = parseToken(token);
3058
3264
  if (raw) return raw;
3059
3265
  const cssVar = `${COLOR_VAR_PREFIX}${baseToken}`;
3060
- if (alpha === void 0) return `rgb(var(${cssVar}))`;
3061
- return `rgb(var(${cssVar}) / ${alpha})`;
3266
+ if (opacityPercent === void 0) return `rgb(var(${cssVar}))`;
3267
+ return `rgb(var(${cssVar}) / ${opacityPercent / 100})`;
3268
+ }
3269
+ /**
3270
+ * Converts a theme color token to a CSS variable reference.
3271
+ * Note: This returns the base variable without rgb() wrapper, ignoring opacity.
3272
+ *
3273
+ * @param token - Theme color token
3274
+ * @returns CSS variable reference
3275
+ *
3276
+ * @example
3277
+ * cssVarValue('primary') // => 'var(--tb-primary)'
3278
+ * cssVarValue('surface/95') // => 'var(--tb-surface)' (opacity ignored)
3279
+ */
3280
+ function cssVarValue(token) {
3281
+ const { token: baseToken } = parseToken(token);
3282
+ return `var(${COLOR_VAR_PREFIX}${baseToken})`;
3062
3283
  }
3063
3284
  //#endregion
3064
3285
  //#region ../theme-core/src/utils/tokenOrColor.ts
@@ -3333,6 +3554,7 @@ const typographyScaleSchema = z$1.enum([
3333
3554
  "majorThird",
3334
3555
  "perfectFourth"
3335
3556
  ]);
3557
+ const eyebrowTypographyStyleSchema = z$1.object({ family: z$1.string().min(1) });
3336
3558
  const typographySchema = z$1.object({
3337
3559
  body: bodyTypographyStyleSchema,
3338
3560
  headings: z$1.object({
@@ -3345,7 +3567,8 @@ const typographySchema = z$1.object({
3345
3567
  h6: headingTypographyOverridesSchema.optional()
3346
3568
  }),
3347
3569
  scale: typographyScaleSchema,
3348
- proseLinkStyle: proseLinkStyleSchema.optional()
3570
+ proseLinkStyle: proseLinkStyleSchema.optional(),
3571
+ eyebrow: eyebrowTypographyStyleSchema.optional()
3349
3572
  });
3350
3573
  const spaceSchema = z$1.enum([
3351
3574
  "comfortable",
@@ -3370,7 +3593,8 @@ const shadow = z$1.object({
3370
3593
  "soft",
3371
3594
  "hard"
3372
3595
  ]).nullable(),
3373
- position: z$1.enum(["bottom", "bottom-right"]).default("bottom")
3596
+ position: z$1.enum(["bottom", "bottom-right"]).default("bottom"),
3597
+ colorToken: themeColorTokenSchema.optional()
3374
3598
  });
3375
3599
  const border = z$1.object({
3376
3600
  width: z$1.enum([
@@ -3615,6 +3839,7 @@ const headerSchema = z$1.object({
3615
3839
  navWeight: navFontWeight.default("medium"),
3616
3840
  navTypography: z$1.enum(["body", "heading"]).optional(),
3617
3841
  navTextSize: navLinkStyleSchema.shape.textSize,
3842
+ navPlacement: z$1.enum(["end", "center"]).optional(),
3618
3843
  container: headerContainerSchema,
3619
3844
  border: headerBorderSchema,
3620
3845
  shadow: componentShadowSchema.optional(),
@@ -3909,6 +4134,8 @@ function hexToRgb(hex) {
3909
4134
  function generateShadowCssVars(theme) {
3910
4135
  const level = theme.shadow.elevation;
3911
4136
  const soft = theme.shadow.softness !== "crisp";
4137
+ const tintVar = theme.shadow.colorToken ? cssVarValue(theme.shadow.colorToken) : null;
4138
+ const shadowColor = (a) => tintVar ? `rgb(${tintVar} / ${a})` : `rgba(0, 0, 0, ${a})`;
3912
4139
  const base = {
3913
4140
  sm: [{
3914
4141
  y: 1,
@@ -3968,7 +4195,7 @@ function generateShadowCssVars(theme) {
3968
4195
  const blurMul = soft ? 1.2 : 1;
3969
4196
  const alphaMul = soft ? .9 : 1.05;
3970
4197
  const fmt = (layers) => layers.map((l) => {
3971
- return `0 ${Math.round(l.y * scale)}px ${Math.round(l.blur * scale * blurMul)}px ${Math.round(l.spread * scale)}px rgba(0, 0, 0, ${Math.max(0, Math.min(1, +(l.a * alphaMul).toFixed(3)))})`;
4198
+ return `0 ${Math.round(l.y * scale)}px ${Math.round(l.blur * scale * blurMul)}px ${Math.round(l.spread * scale)}px ${shadowColor(Math.max(0, Math.min(1, +(l.a * alphaMul).toFixed(3))))}`;
3972
4199
  }).join(", ");
3973
4200
  return {
3974
4201
  "--shadow-sm": fmt(base.sm),
@@ -4299,6 +4526,71 @@ const brandLedJewel = defineCuratedPalette({
4299
4526
  }
4300
4527
  ]
4301
4528
  });
4529
+ const brandLedSpruce = defineCuratedPalette({
4530
+ id: "brand-led-spruce",
4531
+ name: "Brand-led — Spruce",
4532
+ description: "Spruce-ink primary and moss secondary with an amber accent over a green-mist ground and hairline sage borders.",
4533
+ tags: {
4534
+ tone: "classic",
4535
+ energy: "calm",
4536
+ era: "editorial"
4537
+ },
4538
+ mode: "light",
4539
+ colors: [
4540
+ {
4541
+ name: "primary",
4542
+ hex: "#14312b"
4543
+ },
4544
+ {
4545
+ name: "secondary",
4546
+ hex: "#356a59"
4547
+ },
4548
+ {
4549
+ name: "accent",
4550
+ hex: "#f08a4b"
4551
+ },
4552
+ {
4553
+ name: "success",
4554
+ hex: "#356a59"
4555
+ },
4556
+ {
4557
+ name: "warning",
4558
+ hex: "#f08a4b"
4559
+ },
4560
+ {
4561
+ name: "destructive",
4562
+ hex: "#b5561f"
4563
+ },
4564
+ {
4565
+ name: "background",
4566
+ hex: "#ecefe9"
4567
+ },
4568
+ {
4569
+ name: "surface",
4570
+ hex: "#ffffff"
4571
+ },
4572
+ {
4573
+ name: "surfaceAlt",
4574
+ hex: "#f4f6f1"
4575
+ },
4576
+ {
4577
+ name: "muted",
4578
+ hex: "#5c6a64"
4579
+ },
4580
+ {
4581
+ name: "text",
4582
+ hex: "#1c2a26"
4583
+ },
4584
+ {
4585
+ name: "primaryForeground",
4586
+ hex: "#f4f7f1"
4587
+ },
4588
+ {
4589
+ name: "border",
4590
+ hex: "#d7ddd2"
4591
+ }
4592
+ ]
4593
+ });
4302
4594
  const brandLedBurgundyGold = defineCuratedPalette({
4303
4595
  id: "brand-led-burgundy-gold",
4304
4596
  name: "Brand-led — Burgundy Gold",
@@ -4838,6 +5130,7 @@ const curatedPalettes = [
4838
5130
  brandLedWarm,
4839
5131
  brandLedJewel,
4840
5132
  brandLedBurgundyGold,
5133
+ brandLedSpruce,
4841
5134
  defineCuratedPalette({
4842
5135
  id: "warm-neutral-clay",
4843
5136
  name: "Warm Neutral — Clay",
@@ -6092,6 +6385,13 @@ const legacyHeaderLookAliases = defineExactCatalog()([
6092
6385
  styleId: asHeaderStyleId("minimal")
6093
6386
  }
6094
6387
  },
6388
+ {
6389
+ lookId: asHeaderLookId("classic-centered-nav"),
6390
+ selection: {
6391
+ layoutId: asHeaderLayoutId("classic"),
6392
+ styleId: asHeaderStyleId("fine-line")
6393
+ }
6394
+ },
6095
6395
  {
6096
6396
  lookId: asHeaderLookId("brand-solid"),
6097
6397
  selection: {
@@ -6162,6 +6462,50 @@ function getCompatibleHeaderStyleIds(layoutId) {
6162
6462
  return isHeaderStyleCompatibleWithLayout(getHeaderStyleOrThrow(styleId), layoutId);
6163
6463
  });
6164
6464
  }
6465
+ function applyNavTypography(style, typography) {
6466
+ switch (typography) {
6467
+ case "plain": return style;
6468
+ case "heading": return {
6469
+ ...style,
6470
+ typography: "heading",
6471
+ fontWeight: "medium",
6472
+ letterSpacing: "wide"
6473
+ };
6474
+ case "quiet-caps": return {
6475
+ ...style,
6476
+ textTransform: "uppercase",
6477
+ textSize: "sm",
6478
+ letterSpacing: "wide"
6479
+ };
6480
+ case "brand-caps": return {
6481
+ ...style,
6482
+ textTransform: "uppercase",
6483
+ textSize: "sm",
6484
+ letterSpacing: "wider"
6485
+ };
6486
+ default: return assertNever(typography, "Unhandled header nav typography");
6487
+ }
6488
+ }
6489
+ function underlineNavLinkStyle(colorToken, underlineColorToken, typography = "plain") {
6490
+ return applyNavTypography({
6491
+ name: "Underline grow",
6492
+ typography: "body",
6493
+ fontWeight: "medium",
6494
+ textTransform: "none",
6495
+ italic: false,
6496
+ colorToken,
6497
+ padding: "compact",
6498
+ paddingX: "compact",
6499
+ borderRadius: "none",
6500
+ effects: { hover: [{
6501
+ effectId: "nav-underline",
6502
+ options: {
6503
+ style: "grow",
6504
+ ...underlineColorToken ? { colorToken: underlineColorToken } : {}
6505
+ }
6506
+ }] }
6507
+ }, typography);
6508
+ }
6165
6509
  function themedHeaderShadow(theme) {
6166
6510
  switch (theme.shadow.elevation) {
6167
6511
  case "none": return;
@@ -6261,6 +6605,38 @@ function cleanBaseHeader(theme) {
6261
6605
  ctaGap: "default"
6262
6606
  };
6263
6607
  }
6608
+ function classicCenteredNavHeader(theme) {
6609
+ return {
6610
+ ...baseHeader(theme),
6611
+ variant: "classic",
6612
+ navPlacement: "center",
6613
+ positioning: "sticky",
6614
+ shrinkOnScroll: false,
6615
+ background: {
6616
+ type: "color",
6617
+ color: "surface"
6618
+ },
6619
+ textColor: "text",
6620
+ navColor: "text",
6621
+ navStyle: "underline-grow",
6622
+ navWeight: "medium",
6623
+ navLinkStyle: underlineNavLinkStyle("text", "accent"),
6624
+ border: {
6625
+ style: "solid",
6626
+ width: "thin",
6627
+ position: "bottom",
6628
+ colorToken: "border"
6629
+ },
6630
+ ctaTreatment: "primary",
6631
+ ctaVariant: resolveHeaderCtaVariant(theme, "primary"),
6632
+ ctaGap: "default",
6633
+ logoText: {
6634
+ mobileMaxWidth: "sm",
6635
+ mobileWrapLines: 1,
6636
+ hideOnShrink: false
6637
+ }
6638
+ };
6639
+ }
6264
6640
  function serifLineHeader(theme) {
6265
6641
  return {
6266
6642
  ...baseHeader(theme),
@@ -6425,6 +6801,21 @@ const headerLookCatalog = defineExactCatalog()([
6425
6801
  logoAccommodations: inlineClassicLogoAccommodations,
6426
6802
  compile: cleanBaseHeader
6427
6803
  },
6804
+ {
6805
+ id: asHeaderLookId("classic-centered-nav"),
6806
+ label: "Centered nav",
6807
+ visualTreatment: "solid-neutral",
6808
+ layoutBehavior: "sticky",
6809
+ configuration: {
6810
+ structure: "inline-classic",
6811
+ treatment: "solid-neutral",
6812
+ behavior: "sticky"
6813
+ },
6814
+ openingRequirement: "none",
6815
+ maxRecommendedNavItems: 6,
6816
+ logoAccommodations: inlineClassicLogoAccommodations,
6817
+ compile: classicCenteredNavHeader
6818
+ },
6428
6819
  {
6429
6820
  id: asHeaderLookId("brand-solid"),
6430
6821
  label: "Brand solid",
@@ -7591,28 +7982,96 @@ const typographyPresets = [
7591
7982
  }
7592
7983
  }
7593
7984
  }
7594
- })
7595
- ];
7596
- new Map(typographyPresets.map((preset) => [preset.id, preset]));
7597
- const designResolutionPolicySchema = z$1.enum([
7598
- "generated",
7599
- "user",
7600
- "admin",
7601
- "sdk"
7602
- ]);
7603
- const runtimeStyleFieldNameSchema = z$1.enum(themeV2RuntimeStyleFieldNames);
7604
- const nonEmptyRuntimeStyleFieldNamesSchema = z$1.array(runtimeStyleFieldNameSchema).min(1).transform((fields) => [fields[0], ...fields.slice(1)]);
7605
- const heroLegibilityStrategySchema = z$1.enum([
7606
- "none",
7607
- "scrim-gradient",
7608
- "solid-panel"
7609
- ]);
7610
- const heroCompositionIntentSchema = z$1.enum(["center", "bottom-left"]);
7611
- const heroTypographyScaleIntentSchema = z$1.enum([
7612
- "quiet",
7613
- "editorial",
7614
- "display",
7615
- "poster"
7985
+ }),
7986
+ defineTypographyPreset({
7987
+ id: "typography-preset:fulcrum",
7988
+ name: "Fulcrum",
7989
+ description: "Newsreader serif headings over an IBM Plex Sans body, with an IBM Plex Mono eyebrow role for uppercase kickers and mono captions.",
7990
+ defaultFonts: {
7991
+ body: "IBM Plex Sans, system-ui, -apple-system, sans-serif",
7992
+ heading: "Newsreader, Georgia, \"Times New Roman\", serif"
7993
+ },
7994
+ recommendedFonts: {
7995
+ body: [
7996
+ "IBM Plex Sans",
7997
+ "Source Sans 3",
7998
+ "Inter"
7999
+ ],
8000
+ heading: [
8001
+ "Newsreader",
8002
+ "Source Serif 4",
8003
+ "Lora"
8004
+ ]
8005
+ },
8006
+ slotPolicies: {
8007
+ body: bodyReadablePolicy,
8008
+ heading: displayHeadingPolicy
8009
+ },
8010
+ typography: {
8011
+ body: {
8012
+ family: "IBM Plex Sans, system-ui, -apple-system, sans-serif",
8013
+ size: "lg",
8014
+ weight: "regular",
8015
+ lineHeight: "relaxed",
8016
+ letterSpacing: "normal"
8017
+ },
8018
+ headings: {
8019
+ default: {
8020
+ family: "Newsreader, Georgia, \"Times New Roman\", serif",
8021
+ weight: "medium",
8022
+ lineHeight: "normal",
8023
+ letterSpacing: "tight",
8024
+ colorToken: "primary",
8025
+ italic: null,
8026
+ case: null
8027
+ },
8028
+ h1: {
8029
+ size: "2xl",
8030
+ weight: "medium",
8031
+ lineHeight: "normal",
8032
+ letterSpacing: "tight",
8033
+ italic: null
8034
+ },
8035
+ h2: {
8036
+ size: "xl",
8037
+ weight: "medium",
8038
+ lineHeight: "normal",
8039
+ letterSpacing: "tight",
8040
+ italic: null
8041
+ },
8042
+ h3: {
8043
+ size: "md",
8044
+ weight: "semibold",
8045
+ lineHeight: "normal",
8046
+ letterSpacing: "normal",
8047
+ italic: null
8048
+ }
8049
+ },
8050
+ scale: "spacious",
8051
+ eyebrow: { family: "IBM Plex Mono, ui-monospace, \"SF Mono\", monospace" }
8052
+ }
8053
+ })
8054
+ ];
8055
+ new Map(typographyPresets.map((preset) => [preset.id, preset]));
8056
+ const designResolutionPolicySchema = z$1.enum([
8057
+ "generated",
8058
+ "user",
8059
+ "admin",
8060
+ "sdk"
8061
+ ]);
8062
+ const runtimeStyleFieldNameSchema = z$1.enum(themeV2RuntimeStyleFieldNames);
8063
+ const nonEmptyRuntimeStyleFieldNamesSchema = z$1.array(runtimeStyleFieldNameSchema).min(1).transform((fields) => [fields[0], ...fields.slice(1)]);
8064
+ const heroLegibilityStrategySchema = z$1.enum([
8065
+ "none",
8066
+ "scrim-gradient",
8067
+ "solid-panel"
8068
+ ]);
8069
+ const heroCompositionIntentSchema = z$1.enum(["center", "bottom-left"]);
8070
+ const heroTypographyScaleIntentSchema = z$1.enum([
8071
+ "quiet",
8072
+ "editorial",
8073
+ "display",
8074
+ "poster"
7616
8075
  ]);
7617
8076
  const sectionHeightIntentSchema = z$1.enum([
7618
8077
  "default",
@@ -9267,6 +9726,104 @@ const curatedSiteStyles = [
9267
9726
  buttonChoice("showtime-pill")
9268
9727
  ],
9269
9728
  paletteRecommendations: [paletteRecommendation("warm-dark-ember")]
9729
+ }),
9730
+ defineCuratedSiteStyle({
9731
+ id: "site-style:fulcrum",
9732
+ name: "Fulcrum",
9733
+ headingDecoration: {
9734
+ family: "short-center-rule",
9735
+ colorToken: "accent"
9736
+ },
9737
+ description: "Spruce-ink and moss with an amber climax, Newsreader serif over IBM Plex Sans, hairline sage borders and flat buttons — a grounded, editorial physiotherapy skin.",
9738
+ generationBrief: "Use a calm, clinician-led voice: precise, reassuring and specific rather than clinical-cold. Lead with the assessment-treatment-rehab journey, mono uppercase eyebrows for practical labels (hours, registrations, appointment windows), Newsreader serif headings over IBM Plex Sans body, and a single amber call to action as the page climax. Keep proof concrete (registrations, same-week appointments, return-to-activity outcomes) and avoid spa or hard-sell wellness language or medical claims.",
9739
+ siteCreatorSelection: {
9740
+ kind: "site_creator_keyword_heuristic",
9741
+ priority: 28
9742
+ },
9743
+ selectionKeywordRules: [
9744
+ {
9745
+ kind: "substring",
9746
+ value: "physiotherap"
9747
+ },
9748
+ {
9749
+ kind: "word",
9750
+ value: "physio"
9751
+ },
9752
+ {
9753
+ kind: "phrase",
9754
+ value: "sports injury"
9755
+ },
9756
+ {
9757
+ kind: "phrase",
9758
+ value: "rehab clinic"
9759
+ },
9760
+ {
9761
+ kind: "substring",
9762
+ value: "musculoskeletal"
9763
+ },
9764
+ {
9765
+ kind: "phrase",
9766
+ value: "sports therapy"
9767
+ }
9768
+ ],
9769
+ tokenRecipes: {
9770
+ palette: "brand-led",
9771
+ contrast: "standard",
9772
+ radius: "rounded",
9773
+ shadow: "subtle",
9774
+ typography: "serif-editorial",
9775
+ spacing: "airy",
9776
+ motion: "subtle"
9777
+ },
9778
+ compositionBudget: quietBudget,
9779
+ typographyPresetChoices: [
9780
+ typographyChoice("typography-preset:fulcrum"),
9781
+ typographyChoice("typography-preset:editorial-serif"),
9782
+ typographyChoice("typography-preset:modern-sans")
9783
+ ],
9784
+ defaultTypographyPresetId: "typography-preset:fulcrum",
9785
+ themeOverrides: {
9786
+ shadow: { colorToken: "primary" },
9787
+ accordions: {
9788
+ background: null,
9789
+ spacing: "comfortable",
9790
+ corners: "square",
9791
+ border: null,
9792
+ shadow: null,
9793
+ icon: {
9794
+ style: "plus-minus",
9795
+ position: "right",
9796
+ size: "md",
9797
+ colorToken: "accent"
9798
+ },
9799
+ trigger: {
9800
+ textColorToken: "primary",
9801
+ fontWeight: "medium",
9802
+ fontFamily: "heading",
9803
+ fontScale: "md"
9804
+ },
9805
+ hover: { textColorToken: "secondary" },
9806
+ content: { textColorToken: "muted" }
9807
+ },
9808
+ testimonialQuote: serifDisplayQuote
9809
+ },
9810
+ recommendedHeaderLookIds: [
9811
+ "classic-centered-nav",
9812
+ "serif-line",
9813
+ "centered-calm",
9814
+ "clean-base"
9815
+ ],
9816
+ recommendedFooterLookIds: ["footer-editorial-columns", "footer-muted-grounding"],
9817
+ buttonPersonalityChoices: [
9818
+ buttonChoice("flat-ink"),
9819
+ buttonChoice("confident-chip"),
9820
+ buttonChoice("editorial-link")
9821
+ ],
9822
+ paletteRecommendations: [
9823
+ paletteRecommendation("brand-led-spruce"),
9824
+ paletteRecommendation("warm-neutral-forest"),
9825
+ paletteRecommendation("soft-natural-sage")
9826
+ ]
9270
9827
  })
9271
9828
  ];
9272
9829
  new Map(curatedSiteStyles.map((style) => [style.id, style]));
@@ -9331,7 +9888,7 @@ ${root} .status-error { color: rgb(var(--tb-destructive)); }
9331
9888
  ${root} .status-success { color: rgb(var(--tb-success)); }
9332
9889
  ${root} .status-warning { color: rgb(var(--tb-warning)); }
9333
9890
  ${root} .status-info { color: rgb(var(--tb-info)); }
9334
- ${root} .status-muted { ${statusMutedColorDeclaration()} }`);
9891
+ ${root} .status-muted { color: ${surfaceForegroundValue("supporting")}; }`);
9335
9892
  cssBlocks.push(`/* Alert containers */
9336
9893
  ${root} .alert {
9337
9894
  padding: 1rem;
@@ -9804,6 +10361,7 @@ const THEME_RADIUS_CSS_VARS = {
9804
10361
  block: "--rb-block-radius",
9805
10362
  button: "--rb-button-radius",
9806
10363
  input: "--rb-input-radius",
10364
+ panel: "--rb-panel-radius",
9807
10365
  legacyCard: "--radius-card",
9808
10366
  legacyControl: "--radius-control"
9809
10367
  };
@@ -9885,6 +10443,10 @@ ${`:where([data-theme-scope="${themeId}"]) :where([data-block="customer-portal"]
9885
10443
  /* Modal (shared rb-modal classes) */
9886
10444
  --rb-modal-overlay-bg: rgb(var(--tb-text, 0 0 0) / 0.35);
9887
10445
  --rb-modal-bg: var(--cp-card-bg);
10446
+ --rb-modal-text: var(--cp-text);
10447
+ --rb-modal-heading: var(--cp-text);
10448
+ --rb-modal-link: var(--cp-primary);
10449
+ --rb-modal-supporting: var(--cp-muted);
9888
10450
  --rb-modal-border: var(--cp-card-border);
9889
10451
  --rb-modal-shadow: var(--shadow-lg, var(--shadow-elev));
9890
10452
  --rb-modal-radius: var(--cp-card-radius);
@@ -10300,8 +10862,12 @@ const containerResponsiveThemeCss = `/*
10300
10862
  text-transform: uppercase;
10301
10863
  }
10302
10864
 
10303
- /* Eyebrow text - small uppercase labels for section introductions */
10865
+ /* Eyebrow text - small uppercase labels for section introductions.
10866
+ font-family resolves to the optional eyebrow/mono font role, falling back
10867
+ to the body font when the theme sets none (so existing themes are
10868
+ unchanged). */
10304
10869
  .rb-eyebrow {
10870
+ font-family: var(--font-eyebrow, var(--font-body));
10305
10871
  font-size: 0.875rem;
10306
10872
  font-weight: 600;
10307
10873
  letter-spacing: 0.025em;
@@ -10316,11 +10882,11 @@ const containerResponsiveThemeCss = `/*
10316
10882
  width: fit-content;
10317
10883
  align-items: center;
10318
10884
  justify-content: center;
10319
- border: 1px solid color-mix(in srgb, var(--section-text-color, rgb(var(--tb-text))) 46%, transparent);
10885
+ border: 1px solid color-mix(in srgb, var(--rb-surface-text-color, rgb(var(--tb-text, 17 24 39))) 46%, transparent);
10320
10886
  border-radius: 9999px;
10321
- background: color-mix(in srgb, var(--section-text-color, rgb(var(--tb-text))) 14%, transparent);
10887
+ background: color-mix(in srgb, var(--rb-surface-text-color, rgb(var(--tb-text, 17 24 39))) 14%, transparent);
10322
10888
  padding: 0.5rem 1rem;
10323
- color: var(--section-text-color, rgb(var(--tb-text)));
10889
+ color: var(--rb-surface-text-color, rgb(var(--tb-text, 17 24 39)));
10324
10890
  line-height: 1;
10325
10891
  }
10326
10892
  .rb-eyebrow-treatment-pill.rb-eyebrow-treatment-accent {
@@ -10822,6 +11388,58 @@ const containerResponsiveThemeCss = `/*
10822
11388
  }
10823
11389
  }
10824
11390
 
11391
+ }
11392
+
11393
+ /*
11394
+ * Responsive fractional grid tracks (rb-grid-tracks).
11395
+ *
11396
+ * Asymmetric AND responsive grid-template-columns, driven by inline custom
11397
+ * properties the Grid primitive sets per breakpoint from string track
11398
+ * templates:
11399
+ * --rb-gtc-base / --rb-gtc-sm / --rb-gtc-md / --rb-gtc-lg / --rb-gtc-xl
11400
+ * Each breakpoint falls back to the next smaller one, so only the breakpoints
11401
+ * an author actually sets take effect (e.g. base '1fr' + lg '1fr 0.9fr'
11402
+ * collapses to a single column below lg). Authored here (not per node) so the
11403
+ * @media -> @container conversion (container responsive mode) applies too.
11404
+ */
11405
+ .rb-grid-tracks {
11406
+ grid-template-columns: var(--rb-gtc-base, 1fr);
11407
+ }
11408
+ @container rb-site (min-width: 640px) {
11409
+
11410
+ @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
11411
+ .rb-grid-tracks {
11412
+ grid-template-columns: var(--rb-gtc-sm, var(--rb-gtc-base, 1fr));
11413
+ }
11414
+ }
11415
+
11416
+ }
11417
+ @container rb-site (min-width: 768px) {
11418
+
11419
+ @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
11420
+ .rb-grid-tracks {
11421
+ grid-template-columns: var(--rb-gtc-md, var(--rb-gtc-sm, var(--rb-gtc-base, 1fr)));
11422
+ }
11423
+ }
11424
+
11425
+ }
11426
+ @container rb-site (min-width: 1024px) {
11427
+
11428
+ @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
11429
+ .rb-grid-tracks {
11430
+ grid-template-columns: var(--rb-gtc-lg, var(--rb-gtc-md, var(--rb-gtc-sm, var(--rb-gtc-base, 1fr))));
11431
+ }
11432
+ }
11433
+
11434
+ }
11435
+ @container rb-site (min-width: 1280px) {
11436
+
11437
+ @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
11438
+ .rb-grid-tracks {
11439
+ grid-template-columns: var(--rb-gtc-xl, var(--rb-gtc-lg, var(--rb-gtc-md, var(--rb-gtc-sm, var(--rb-gtc-base, 1fr)))));
11440
+ }
11441
+ }
11442
+
10825
11443
  }
10826
11444
 
10827
11445
  /* Alignment */
@@ -12026,6 +12644,11 @@ const containerResponsiveThemeCss = `/*
12026
12644
  :where(.theme-scope) .rb-modal {
12027
12645
  width: min(var(--rb-modal-max-width, 560px), 100%);
12028
12646
  background: var(--rb-modal-bg, rgb(var(--tb-surface)));
12647
+ color: var(--rb-modal-text, rgb(var(--tb-text, 17 24 39)));
12648
+ --rb-surface-text-color: var(--rb-modal-text, rgb(var(--tb-text, 17 24 39)));
12649
+ --rb-surface-heading-color: var(--rb-modal-heading, var(--rb-modal-text, rgb(var(--tb-text, 17 24 39))));
12650
+ --rb-surface-link-color: var(--rb-modal-link, var(--rb-modal-text, rgb(var(--tb-text, 17 24 39))));
12651
+ --rb-surface-supporting-color: var(--rb-modal-supporting, var(--rb-modal-text, rgb(var(--tb-text, 17 24 39))));
12029
12652
  border: 1px solid var(--rb-modal-border, rgb(var(--tb-border)));
12030
12653
  border-radius: var(--rb-modal-radius, var(--radius-card));
12031
12654
  box-shadow: var(--rb-modal-shadow, var(--shadow-lg, var(--shadow-elev)));
@@ -12045,7 +12668,7 @@ const containerResponsiveThemeCss = `/*
12045
12668
  font-family: var(--font-heading);
12046
12669
  font-size: 1.0625rem;
12047
12670
  font-weight: 600;
12048
- color: rgb(var(--tb-text));
12671
+ color: var(--rb-surface-heading-color, var(--rb-surface-text-color, rgb(var(--tb-text, 17 24 39))));
12049
12672
  }
12050
12673
 
12051
12674
  :where(.theme-scope) .rb-modal__close {
@@ -12055,7 +12678,7 @@ const containerResponsiveThemeCss = `/*
12055
12678
  height: 2.25rem;
12056
12679
  padding: 0;
12057
12680
  line-height: 1;
12058
- color: rgb(var(--tb-mutedText));
12681
+ color: var(--rb-surface-supporting-color, var(--rb-surface-text-color, rgb(var(--tb-mutedText, 100 116 139))));
12059
12682
  cursor: pointer;
12060
12683
  display: grid;
12061
12684
  place-items: center;
@@ -12063,7 +12686,7 @@ const containerResponsiveThemeCss = `/*
12063
12686
  }
12064
12687
 
12065
12688
  :where(.theme-scope) .rb-modal__close:hover {
12066
- color: rgb(var(--tb-text));
12689
+ color: var(--rb-surface-text-color, rgb(var(--tb-text, 17 24 39)));
12067
12690
  background: rgba(var(--tb-border), 0.2);
12068
12691
  }
12069
12692
 
@@ -12074,7 +12697,7 @@ const containerResponsiveThemeCss = `/*
12074
12697
 
12075
12698
  :where(.theme-scope) .rb-modal__body {
12076
12699
  padding: 0.875rem 1rem 1rem;
12077
- color: rgb(var(--tb-text));
12700
+ color: var(--rb-surface-text-color, rgb(var(--tb-text, 17 24 39)));
12078
12701
  font-size: 0.9375rem;
12079
12702
  line-height: 1.45;
12080
12703
  }
@@ -12234,7 +12857,7 @@ const containerResponsiveThemeCss = `/*
12234
12857
  & h6 {
12235
12858
  font-family: var(--font-heading);
12236
12859
  /* Color is set by generateTypographyCss.ts with full cascade:
12237
- --section-heading-color -> --section-text-color -> --hc-hN -> --hc-heading -> inherit */
12860
+ --rb-surface-heading-color -> --rb-surface-text-color -> --hc-hN -> --hc-heading -> global text */
12238
12861
  font-weight: var(--font-weight-heading);
12239
12862
  text-transform: var(--tt-heading);
12240
12863
  font-variant-caps: var(--fv-heading);
@@ -12382,7 +13005,7 @@ const containerResponsiveThemeCss = `/*
12382
13005
 
12383
13006
  /* Neutral prose uses theme text color by default */
12384
13007
  :where(.theme-scope) .rb-prose-neutral {
12385
- color: var(--section-text-color, rgb(var(--tb-text)));
13008
+ color: var(--rb-surface-text-color, rgb(var(--tb-text, 17 24 39)));
12386
13009
  }
12387
13010
 
12388
13011
  :where(.theme-scope) .rb-prose p,
@@ -12416,8 +13039,14 @@ const containerResponsiveThemeCss = `/*
12416
13039
 
12417
13040
  :where(.theme-scope) .rb-prose a {
12418
13041
  --rb-prose-effective-link-color: var(
12419
- --section-link-color,
12420
- var(--rb-prose-link-color, rgb(var(--tb-primary)))
13042
+ --rb-surface-link-color,
13043
+ var(
13044
+ --rb-surface-text-color,
13045
+ var(
13046
+ --rb-prose-link-color,
13047
+ rgb(var(--tb-primary, var(--tb-text, 17 24 39)))
13048
+ )
13049
+ )
12421
13050
  );
12422
13051
  color: var(--rb-prose-effective-link-color);
12423
13052
  text-decoration-line: var(--rb-prose-link-decoration-line, underline);
@@ -12428,14 +13057,11 @@ const containerResponsiveThemeCss = `/*
12428
13057
  );
12429
13058
  text-underline-offset: var(--rb-prose-link-underline-offset, 0.14em);
12430
13059
  text-decoration-color: var(
12431
- --section-link-decoration-color,
12432
- var(
12433
- --rb-prose-link-decoration-color,
12434
- color-mix(
12435
- in srgb,
12436
- var(--rb-prose-effective-link-color) 35%,
12437
- transparent
12438
- )
13060
+ --rb-prose-link-decoration-color,
13061
+ color-mix(
13062
+ in srgb,
13063
+ var(--rb-prose-effective-link-color) 35%,
13064
+ transparent
12439
13065
  )
12440
13066
  );
12441
13067
  transition:
@@ -12459,7 +13085,7 @@ const containerResponsiveThemeCss = `/*
12459
13085
 
12460
13086
  :where(.theme-scope) .rb-prose blockquote {
12461
13087
  /* Blockquotes use muted text color */
12462
- color: var(--section-supporting-color, rgb(var(--tb-mutedText)));
13088
+ color: var(--rb-surface-supporting-color, var(--rb-surface-text-color, rgb(var(--tb-mutedText, 100 116 139))));
12463
13089
  border-left-color: rgb(var(--tb-border));
12464
13090
  }
12465
13091
 
@@ -13493,6 +14119,10 @@ const containerResponsiveThemeCss = `/*
13493
14119
  :where(.theme-scope) .card-surface {
13494
14120
  background: rgb(var(--tb-surface));
13495
14121
  color: rgb(var(--tb-onSurface, var(--tb-text)));
14122
+ --rb-surface-text-color: rgb(var(--tb-onSurface, var(--tb-text)));
14123
+ --rb-surface-heading-color: rgb(var(--tb-onSurface, var(--tb-text)));
14124
+ --rb-surface-link-color: rgb(var(--tb-onSurface, var(--tb-text)));
14125
+ --rb-surface-supporting-color: rgb(var(--tb-onSurface, var(--tb-text)));
13496
14126
  border: 1px solid rgb(var(--tb-border));
13497
14127
  border-radius: var(--radius-card);
13498
14128
  box-shadow: var(--shadow-elev);
@@ -13636,6 +14266,10 @@ const containerResponsiveThemeCss = `/*
13636
14266
  padding: clamp(1rem, 2vw, 1.5rem);
13637
14267
  background: var(--rb-reg-surface-bg, rgb(var(--tb-surface, 248 250 252)));
13638
14268
  color: var(--rb-reg-on-surface, rgb(var(--tb-onSurface, var(--tb-text, 15 23 42))));
14269
+ --rb-surface-text-color: var(--rb-reg-on-surface, rgb(var(--tb-onSurface, var(--tb-text, 15 23 42))));
14270
+ --rb-surface-heading-color: var(--rb-reg-on-surface, rgb(var(--tb-onSurface, var(--tb-text, 15 23 42))));
14271
+ --rb-surface-link-color: var(--rb-reg-on-surface, rgb(var(--tb-onSurface, var(--tb-text, 15 23 42))));
14272
+ --rb-surface-supporting-color: var(--rb-reg-on-surface-muted, var(--rb-reg-on-surface, rgb(var(--tb-onSurface, var(--tb-text, 15 23 42)))));
13639
14273
  transition: border-color var(--rb-block-transition, 150ms) ease;
13640
14274
  width: 100%;
13641
14275
  max-width: 800px;
@@ -16723,6 +17357,350 @@ const containerResponsiveThemeCss = `/*
16723
17357
  }
16724
17358
  }
16725
17359
 
17360
+ /* -----------------------------------------------------------------------------
17361
+ * Week Board View
17362
+ * Compact "class day-board": day columns side by side, one card per class,
17363
+ * three-state availability (available / filling / waitlist), and a footer CTA.
17364
+ * ----------------------------------------------------------------------------- */
17365
+
17366
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board {
17367
+ /* Status accent tokens — map the three availability states onto theme colours.
17368
+ * available -> secondary, filling -> accent, waitlist -> muted text. */
17369
+ --ec-status-available: rgb(var(--tb-secondary));
17370
+ --ec-status-filling: rgb(var(--tb-accent));
17371
+ --ec-status-waitlist: rgba(var(--tb-text), 0.4);
17372
+ --event-week-board-cols: 7;
17373
+
17374
+ border: 1px solid var(--ec-border);
17375
+ border-radius: var(--rb-block-radius);
17376
+ background-color: var(--ec-surface);
17377
+ color: var(--ec-text);
17378
+ overflow: hidden;
17379
+ box-shadow: 0 14px 34px -24px rgba(var(--tb-text), 0.35);
17380
+ }
17381
+
17382
+ /* Top bar: title + legend */
17383
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-top {
17384
+ display: flex;
17385
+ align-items: center;
17386
+ justify-content: space-between;
17387
+ gap: 1rem;
17388
+ flex-wrap: wrap;
17389
+ padding: 1.1rem 1.5rem;
17390
+ background-color: var(--ec-header-bg);
17391
+ border-bottom: 1px solid var(--ec-border-subtle);
17392
+ }
17393
+
17394
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-title {
17395
+ font-size: 0.8125rem;
17396
+ font-weight: 600;
17397
+ letter-spacing: 0.12em;
17398
+ text-transform: uppercase;
17399
+ color: rgb(var(--tb-primary));
17400
+ }
17401
+
17402
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-legend {
17403
+ display: flex;
17404
+ align-items: center;
17405
+ gap: 1.1rem;
17406
+ flex-wrap: wrap;
17407
+ font-size: 0.6875rem;
17408
+ letter-spacing: 0.03em;
17409
+ opacity: 0.75;
17410
+ }
17411
+
17412
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-legend-item {
17413
+ display: inline-flex;
17414
+ align-items: center;
17415
+ gap: 0.4rem;
17416
+ }
17417
+
17418
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-legend-dot {
17419
+ width: 0.55rem;
17420
+ height: 0.55rem;
17421
+ border-radius: 50%;
17422
+ display: inline-block;
17423
+ }
17424
+
17425
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-legend-dot[data-status="available"] {
17426
+ background-color: var(--ec-status-available);
17427
+ }
17428
+
17429
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-legend-dot[data-status="filling"] {
17430
+ background-color: var(--ec-status-filling);
17431
+ }
17432
+
17433
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-legend-dot[data-status="waitlist"] {
17434
+ background-color: var(--ec-status-waitlist);
17435
+ }
17436
+
17437
+ /* Day columns grid */
17438
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-grid {
17439
+ display: grid;
17440
+ grid-template-columns: repeat(var(--event-week-board-cols), minmax(0, 1fr));
17441
+ }
17442
+
17443
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-day {
17444
+ display: flex;
17445
+ flex-direction: column;
17446
+ min-height: 15rem;
17447
+ /* Tabular column rule. Driven by the theme border tokens so borderless site
17448
+ * styles (border.width: 'none' -> --rb-border-width: 0) render no grid at all,
17449
+ * while hairline/thin/thick themes get a crisp full-strength divider. */
17450
+ border-right: var(--rb-border-width, 1px) solid rgb(var(--tb-border));
17451
+ }
17452
+
17453
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-day:last-child {
17454
+ border-right: none;
17455
+ }
17456
+
17457
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-day-head {
17458
+ display: flex;
17459
+ align-items: baseline;
17460
+ gap: 0.4rem;
17461
+ padding: 0.9rem 0.9rem 0.65rem;
17462
+ /* Header-row underline — same border-token gating as the column rules. */
17463
+ border-bottom: var(--rb-border-width, 1px) solid rgb(var(--tb-border));
17464
+ }
17465
+
17466
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-day--today .event-week-board-day-head {
17467
+ background-color: var(--ec-today-bg);
17468
+ }
17469
+
17470
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-day-abbr {
17471
+ font-size: 0.6875rem;
17472
+ font-weight: 600;
17473
+ letter-spacing: 0.1em;
17474
+ text-transform: uppercase;
17475
+ opacity: 0.65;
17476
+ }
17477
+
17478
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-day--today .event-week-board-day-abbr {
17479
+ opacity: 1;
17480
+ color: var(--ec-today-text);
17481
+ }
17482
+
17483
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-day-num {
17484
+ font-size: 0.8125rem;
17485
+ font-weight: 600;
17486
+ opacity: 0.5;
17487
+ }
17488
+
17489
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-day-body {
17490
+ display: flex;
17491
+ flex-direction: column;
17492
+ gap: 0.65rem;
17493
+ padding: 0.9rem;
17494
+ flex: 1;
17495
+ }
17496
+
17497
+ /* Class card */
17498
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-card {
17499
+ display: flex;
17500
+ flex-direction: column;
17501
+ gap: 0.45rem;
17502
+ padding: 0.8rem 0.85rem;
17503
+ border: 1px solid var(--ec-border-subtle);
17504
+ border-left: 3px solid var(--ec-status-available);
17505
+ border-radius: calc(var(--rb-block-radius) / 1.5);
17506
+ background-color: var(--ec-surface);
17507
+ color: inherit;
17508
+ text-decoration: none;
17509
+ transition:
17510
+ transform var(--rb-block-transition) ease,
17511
+ box-shadow var(--rb-block-transition) ease,
17512
+ border-color var(--rb-block-transition) ease;
17513
+ }
17514
+
17515
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-card[data-status="filling"] {
17516
+ border-left-color: var(--ec-status-filling);
17517
+ }
17518
+
17519
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-card[data-status="waitlist"] {
17520
+ border-left-color: var(--ec-status-waitlist);
17521
+ }
17522
+
17523
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-card:hover {
17524
+ transform: translateY(-2px);
17525
+ box-shadow: 0 6px 16px -8px rgba(var(--tb-text), 0.28);
17526
+ border-color: rgba(var(--tb-primary), 0.4);
17527
+ }
17528
+
17529
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-card:focus-visible {
17530
+ outline: 2px solid rgb(var(--tb-primary));
17531
+ outline-offset: 2px;
17532
+ }
17533
+
17534
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-card-title {
17535
+ font-family: var(--font-heading, inherit);
17536
+ font-size: 0.9375rem;
17537
+ font-weight: 600;
17538
+ line-height: 1.2;
17539
+ }
17540
+
17541
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-card-time {
17542
+ font-size: 0.75rem;
17543
+ letter-spacing: 0.01em;
17544
+ opacity: 0.7;
17545
+ }
17546
+
17547
+ /* Capacity pill */
17548
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-card-pill {
17549
+ align-self: flex-start;
17550
+ display: inline-flex;
17551
+ align-items: center;
17552
+ padding: 0.15rem 0.6rem;
17553
+ border-radius: 999px;
17554
+ font-size: 0.6875rem;
17555
+ font-weight: 600;
17556
+ letter-spacing: 0.02em;
17557
+ /* Available (default): a calm neutral/muted pill — not a coloured outline.
17558
+ * Filling -> amber and waitlist -> muted outline are handled by the
17559
+ * data-status overrides below. */
17560
+ border: 1px solid var(--ec-border);
17561
+ background-color: rgba(var(--tb-text), 0.06);
17562
+ color: rgba(var(--tb-text), 0.62);
17563
+ border-color: var(--ec-border);
17564
+ }
17565
+
17566
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-card-pill[data-status="filling"] {
17567
+ background-color: rgba(var(--tb-accent), 0.14);
17568
+ color: var(--ec-status-filling);
17569
+ border-color: rgba(var(--tb-accent), 0.32);
17570
+ }
17571
+
17572
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-card-pill[data-status="waitlist"] {
17573
+ background-color: transparent;
17574
+ color: rgba(var(--tb-text), 0.6);
17575
+ border-color: var(--ec-border);
17576
+ }
17577
+
17578
+ /* Footer */
17579
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-foot {
17580
+ display: flex;
17581
+ align-items: center;
17582
+ justify-content: space-between;
17583
+ gap: 1rem;
17584
+ flex-wrap: wrap;
17585
+ padding: 1.1rem 1.5rem;
17586
+ background-color: var(--ec-header-bg);
17587
+ border-top: 1px solid var(--ec-border-subtle);
17588
+ }
17589
+
17590
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-foot-note {
17591
+ margin: 0;
17592
+ font-size: 0.875rem;
17593
+ opacity: 0.75;
17594
+ }
17595
+
17596
+ /* Responsive: collapse day columns to a stacked list on narrow viewports */
17597
+ @container rb-site (max-width: 1023px) {
17598
+ @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
17599
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-grid {
17600
+ grid-template-columns: 1fr;
17601
+ }
17602
+
17603
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-day {
17604
+ min-height: 0;
17605
+ border-right: none;
17606
+ border-bottom: var(--rb-border-width, 1px) solid rgb(var(--tb-border));
17607
+ }
17608
+
17609
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-day:last-child {
17610
+ border-bottom: none;
17611
+ }
17612
+
17613
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-day--empty {
17614
+ display: none;
17615
+ }
17616
+
17617
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-day-head {
17618
+ border-bottom: none;
17619
+ padding-bottom: 0.25rem;
17620
+ }
17621
+
17622
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-day-body {
17623
+ flex-direction: row;
17624
+ flex-wrap: wrap;
17625
+ padding-top: 0.35rem;
17626
+ }
17627
+
17628
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-card {
17629
+ flex: 1 1 14rem;
17630
+ }
17631
+ }
17632
+ }
17633
+
17634
+ @container rb-site (max-width: 639px) {
17635
+ @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
17636
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-legend {
17637
+ display: none;
17638
+ }
17639
+
17640
+ :where(.theme-scope) :where([data-block="event-calendar"]) .event-week-board-card {
17641
+ flex: 1 1 100%;
17642
+ }
17643
+ }
17644
+ }
17645
+
17646
+ /* -----------------------------------------------------------------------------
17647
+ * Week-board section band
17648
+ * Give the whole week-board section (head + panel) a subtle surface band so it
17649
+ * reads as a distinct zone from the page — the "testimonials band" pattern.
17650
+ * Painted as a pseudo-element above the section's fallback background layer
17651
+ * (z-index -10) but behind the content, so no block-content wiring is needed.
17652
+ * Surface + hairline rules are token-referenced: on a borderless site style
17653
+ * (--rb-border-width: 0) the band keeps its surface tint but drops the rules.
17654
+ * ----------------------------------------------------------------------------- */
17655
+ :where(.theme-scope) [data-slot="section"]:has(.event-calendar--week-board)::before {
17656
+ content: "";
17657
+ position: absolute;
17658
+ inset: 0;
17659
+ z-index: -9;
17660
+ background-color: rgb(var(--tb-surfaceAlt));
17661
+ border-block: var(--rb-border-width, 1px) solid rgb(var(--tb-border));
17662
+ pointer-events: none;
17663
+ }
17664
+
17665
+ /* -----------------------------------------------------------------------------
17666
+ * Event section head — split (heading left, intro right)
17667
+ * Rendered by the block frame (outside [data-block="event-calendar"]) via
17668
+ * eventSectionHeaderLayoutNodes({ splitClassName }). Lays the heading and its
17669
+ * supporting intro out as a two-column head on wide viewports, stacking on
17670
+ * narrow ones. The section band above provides the distinct background.
17671
+ * ----------------------------------------------------------------------------- */
17672
+ :where(.theme-scope) .event-section-head--split {
17673
+ display: flex;
17674
+ align-items: flex-end;
17675
+ justify-content: space-between;
17676
+ gap: clamp(1.5rem, 4vw, 3.5rem);
17677
+ flex-wrap: wrap;
17678
+ }
17679
+
17680
+ :where(.theme-scope) .event-section-head--split > :where(h1, h2, h3) {
17681
+ margin: 0;
17682
+ }
17683
+
17684
+ :where(.theme-scope) .event-section-head--split > .rb-prose {
17685
+ flex: 1 1 22rem;
17686
+ max-width: 34rem;
17687
+ margin: 0;
17688
+ }
17689
+
17690
+ @container rb-site (max-width: 767px) {
17691
+ @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
17692
+ :where(.theme-scope) .event-section-head--split {
17693
+ flex-direction: column;
17694
+ align-items: flex-start;
17695
+ gap: 0.75rem;
17696
+ }
17697
+
17698
+ :where(.theme-scope) .event-section-head--split > .rb-prose {
17699
+ flex-basis: auto;
17700
+ }
17701
+ }
17702
+ }
17703
+
16726
17704
  /* -----------------------------------------------------------------------------
16727
17705
  * Event Calendar Modals
16728
17706
  * Modal overlays for event details and day events list
@@ -17150,7 +18128,7 @@ const containerResponsiveThemeCss = `/*
17150
18128
  }
17151
18129
 
17152
18130
  :where(.theme-scope) .rb-inline-text-accent-contrast {
17153
- color: var(--section-text-color, rgb(var(--tb-text)));
18131
+ color: var(--rb-surface-text-color, rgb(var(--tb-text, 17 24 39)));
17154
18132
  }
17155
18133
 
17156
18134
  :where(.theme-scope) .rb-inline-text-highlight {
@@ -17161,7 +18139,7 @@ const containerResponsiveThemeCss = `/*
17161
18139
  }
17162
18140
 
17163
18141
  :where(.theme-scope) .rb-inline-text-highlight-soft {
17164
- background: color-mix(in oklab, var(--section-text-color, rgb(var(--tb-text))) 14%, transparent);
18142
+ background: color-mix(in oklab, var(--rb-surface-text-color, rgb(var(--tb-text, 17 24 39))) 14%, transparent);
17165
18143
  }
17166
18144
 
17167
18145
  :where(.theme-scope) .rb-inline-text-highlight-accent {
@@ -17180,7 +18158,7 @@ const containerResponsiveThemeCss = `/*
17180
18158
 
17181
18159
  /* Eyebrow - color only (typography via .rb-eyebrow) */
17182
18160
  :where(.theme-scope) :where([data-block="hero"]) .hero-eyebrow:not(.rb-eyebrow-treatment-accent) {
17183
- color: var(--section-text-color, rgb(var(--tb-text)));
18161
+ color: var(--rb-surface-text-color, rgb(var(--tb-text, 17 24 39)));
17184
18162
  }
17185
18163
 
17186
18164
  /* Subheadline - supporting text below headline */
@@ -17190,7 +18168,7 @@ const containerResponsiveThemeCss = `/*
17190
18168
 
17191
18169
  :where(.theme-scope) :where([data-block="hero"]) .hero-subheadline {
17192
18170
  font-size: 1.125rem;
17193
- color: var(--section-supporting-color, var(--section-text-color, rgb(var(--tb-text))));
18171
+ color: var(--rb-surface-supporting-color, var(--rb-surface-text-color, rgb(var(--tb-mutedText, 100 116 139))));
17194
18172
  }
17195
18173
 
17196
18174
  @container rb-site (min-width: 640px) {
@@ -17281,7 +18259,7 @@ const containerResponsiveThemeCss = `/*
17281
18259
 
17282
18260
  /* CTA content/body text */
17283
18261
  :where(.theme-scope) :where([data-block="cta-full"]) .cta-content {
17284
- color: var(--section-supporting-color, rgb(var(--tb-mutedText)));
18262
+ color: var(--rb-surface-supporting-color, var(--rb-surface-text-color, rgb(var(--tb-mutedText, 100 116 139))));
17285
18263
  }
17286
18264
 
17287
18265
  /* CTA button row container */
@@ -17381,7 +18359,7 @@ const containerResponsiveThemeCss = `/*
17381
18359
  /* Form intro text */
17382
18360
  :where(.theme-scope) :where([data-block="form"]) .form-copy-intro {
17383
18361
  font-size: 1rem;
17384
- color: var(--section-text-color, rgb(var(--tb-text)));
18362
+ color: var(--rb-surface-text-color, rgb(var(--tb-text, 17 24 39)));
17385
18363
  }
17386
18364
 
17387
18365
  /* =============================================================================
@@ -17740,6 +18718,10 @@ const containerResponsiveThemeCss = `/*
17740
18718
  --rb-modal-overlay-bg: rgb(var(--tb-text, 0 0 0) / 0.6);
17741
18719
  --rb-modal-shadow: var(--shadow-lg, var(--shadow-elev));
17742
18720
  --rb-modal-z-index: 20000;
18721
+ --rb-modal-text: rgb(var(--tb-text, 17 24 39));
18722
+ --rb-modal-heading: rgb(var(--tb-text, 17 24 39));
18723
+ --rb-modal-link: rgb(var(--tb-primary, var(--tb-text, 17 24 39)));
18724
+ --rb-modal-supporting: rgb(var(--tb-mutedText, 100 116 139));
17743
18725
  --shop-card-radius: var(--rb-block-radius, var(--radius-card, 0.75rem));
17744
18726
  --shop-control-radius: var(--rb-input-radius, var(--radius-control, 0.375rem));
17745
18727
  }
@@ -17797,6 +18779,11 @@ const containerResponsiveThemeCss = `/*
17797
18779
  /* Product card */
17798
18780
  :where(.theme-scope) .shop__card {
17799
18781
  background: rgb(var(--tb-surface));
18782
+ color: rgb(var(--tb-text, 17 24 39));
18783
+ --rb-surface-text-color: rgb(var(--tb-text, 17 24 39));
18784
+ --rb-surface-heading-color: rgb(var(--tb-text, 17 24 39));
18785
+ --rb-surface-link-color: rgb(var(--tb-primary, var(--tb-text, 17 24 39)));
18786
+ --rb-surface-supporting-color: rgb(var(--tb-mutedText, 100 116 139));
17800
18787
  border: 1px solid rgb(var(--tb-border));
17801
18788
  border-radius: var(--shop-card-radius);
17802
18789
  padding: 1.5rem;
@@ -17951,6 +18938,11 @@ const containerResponsiveThemeCss = `/*
17951
18938
  border: 1px solid rgb(var(--tb-border));
17952
18939
  border-radius: var(--shop-card-radius);
17953
18940
  background: rgb(var(--tb-surface));
18941
+ color: rgb(var(--tb-text, 17 24 39));
18942
+ --rb-surface-text-color: rgb(var(--tb-text, 17 24 39));
18943
+ --rb-surface-heading-color: rgb(var(--tb-text, 17 24 39));
18944
+ --rb-surface-link-color: rgb(var(--tb-primary, var(--tb-text, 17 24 39)));
18945
+ --rb-surface-supporting-color: rgb(var(--tb-mutedText, 100 116 139));
17954
18946
  }
17955
18947
 
17956
18948
  :where(.theme-scope) :where([data-block="shop"]) .rb-state-icon--success {
@@ -18023,6 +19015,11 @@ const containerResponsiveThemeCss = `/*
18023
19015
  margin: 0 auto;
18024
19016
  padding: 2rem;
18025
19017
  background: var(--cp-card-bg);
19018
+ color: var(--cp-text);
19019
+ --rb-surface-text-color: var(--cp-text);
19020
+ --rb-surface-heading-color: var(--cp-text);
19021
+ --rb-surface-link-color: var(--cp-primary);
19022
+ --rb-surface-supporting-color: var(--cp-muted);
18026
19023
  border: 1px solid var(--cp-card-border);
18027
19024
  border-radius: var(--cp-card-radius);
18028
19025
  }
@@ -18151,6 +19148,11 @@ const containerResponsiveThemeCss = `/*
18151
19148
  padding: 3rem 2rem;
18152
19149
  text-align: center;
18153
19150
  background: var(--cp-card-bg);
19151
+ color: var(--cp-text);
19152
+ --rb-surface-text-color: var(--cp-text);
19153
+ --rb-surface-heading-color: var(--cp-text);
19154
+ --rb-surface-link-color: var(--cp-primary);
19155
+ --rb-surface-supporting-color: var(--cp-muted);
18154
19156
  border: 1px dashed var(--cp-card-border);
18155
19157
  border-radius: var(--cp-card-radius);
18156
19158
  }
@@ -18163,6 +19165,11 @@ const containerResponsiveThemeCss = `/*
18163
19165
  /* Card */
18164
19166
  :where(.theme-scope) :where([data-block="customer-portal"]) .cp-card {
18165
19167
  background: var(--cp-card-bg);
19168
+ color: var(--cp-text);
19169
+ --rb-surface-text-color: var(--cp-text);
19170
+ --rb-surface-heading-color: var(--cp-text);
19171
+ --rb-surface-link-color: var(--cp-primary);
19172
+ --rb-surface-supporting-color: var(--cp-muted);
18166
19173
  border: 1px solid var(--cp-card-border);
18167
19174
  border-radius: var(--cp-card-radius);
18168
19175
  padding: 1.25rem;
@@ -18327,6 +19334,11 @@ const containerResponsiveThemeCss = `/*
18327
19334
  /* Table */
18328
19335
  :where(.theme-scope) :where([data-block="customer-portal"]) .cp-table-wrap {
18329
19336
  background: var(--cp-card-bg);
19337
+ color: var(--cp-text);
19338
+ --rb-surface-text-color: var(--cp-text);
19339
+ --rb-surface-heading-color: var(--cp-text);
19340
+ --rb-surface-link-color: var(--cp-primary);
19341
+ --rb-surface-supporting-color: var(--cp-muted);
18330
19342
  border: 1px solid var(--cp-card-border);
18331
19343
  border-radius: var(--cp-card-radius);
18332
19344
  }
@@ -18888,6 +19900,143 @@ const containerResponsiveThemeCss = `/*
18888
19900
  }
18889
19901
 
18890
19902
 
19903
+ /* =============================================================================
19904
+ * Variant: featured-editorial
19905
+ *
19906
+ * An asymmetric layout: a large featured (spruce-ink) quote card beside a
19907
+ * column of stacked white cards. Renders NO avatars. Colours are palette
19908
+ * tokens only. Node structure is built in testimonialsCarousel.ts.
19909
+ * ============================================================================= */
19910
+
19911
+ /* Section head: heading left, lead-in line to the right; stacks on mobile. */
19912
+ :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe-head {
19913
+ display: flex;
19914
+ flex-direction: column;
19915
+ align-items: flex-start;
19916
+ gap: 0.875rem;
19917
+ }
19918
+
19919
+ :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe-leadin {
19920
+ max-width: 30rem;
19921
+ }
19922
+
19923
+ @container rb-site (min-width: 768px) {
19924
+ @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
19925
+ :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe-head {
19926
+ flex-direction: row;
19927
+ align-items: flex-end;
19928
+ justify-content: space-between;
19929
+ gap: 1.5rem;
19930
+ }
19931
+ }
19932
+ }
19933
+
19934
+ /* Card grid: featured (wider) beside the stacked column. Single column on
19935
+ * small screens. */
19936
+ :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe-grid {
19937
+ display: grid;
19938
+ grid-template-columns: minmax(0, 1fr);
19939
+ gap: 1.25rem;
19940
+ align-items: stretch;
19941
+ }
19942
+
19943
+ @container rb-site (min-width: 1024px) {
19944
+ @scope ([data-rb-responsive-mode="container"]) to (:scope [data-rb-responsive-mode]) {
19945
+ :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe-grid {
19946
+ grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
19947
+ }
19948
+ }
19949
+ }
19950
+
19951
+ :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe-col {
19952
+ display: grid;
19953
+ gap: 1.25rem;
19954
+ align-content: start;
19955
+ }
19956
+
19957
+ /* Base card (white surface) */
19958
+ :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe-card {
19959
+ display: flex;
19960
+ flex-direction: column;
19961
+ height: 100%;
19962
+ border-radius: var(--rb-block-radius);
19963
+ padding: 1.875rem 1.875rem 1.625rem;
19964
+ background: rgb(var(--tb-surface));
19965
+ border: 1px solid rgba(var(--tb-border), 0.9);
19966
+ box-shadow: 0 1px 2px rgba(var(--tb-shadow, 0 0 0), 0.05);
19967
+ }
19968
+
19969
+ /* Featured (spruce-ink) card */
19970
+ :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe-card--feature {
19971
+ padding: 2.5rem;
19972
+ background: rgb(var(--tb-primary));
19973
+ border-color: transparent;
19974
+ color: rgb(var(--tb-onPrimary));
19975
+ }
19976
+
19977
+ /* Amber quote mark, oversized serif */
19978
+ :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe-qmark {
19979
+ display: block;
19980
+ height: 1.6rem;
19981
+ font-family: var(--font-heading, Georgia, serif);
19982
+ font-style: italic;
19983
+ font-size: 3.375rem;
19984
+ line-height: 0.6;
19985
+ color: rgb(var(--tb-secondary));
19986
+ }
19987
+
19988
+ /* Quote body. The inner <p> is targeted directly (not via :where) so the
19989
+ * serif display font and sizing win over the theme's base paragraph rule. */
19990
+ :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe-quote {
19991
+ flex: 1 1 auto;
19992
+ margin-top: 1.25rem;
19993
+ }
19994
+
19995
+ :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe-quote p {
19996
+ margin: 0;
19997
+ font-family: var(--font-heading, Georgia, serif);
19998
+ font-size: 1.15rem;
19999
+ line-height: 1.5;
20000
+ color: rgb(var(--tb-text));
20001
+ }
20002
+
20003
+ :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe-card--feature .rb-testimonials-fe-quote p {
20004
+ color: rgb(var(--tb-onPrimary));
20005
+ font-size: clamp(1.375rem, 2.4vw, 1.6875rem);
20006
+ line-height: 1.42;
20007
+ letter-spacing: -0.01em;
20008
+ }
20009
+
20010
+ /* Attribution: name (bold) + context line, no avatar */
20011
+ :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe-meta {
20012
+ display: flex;
20013
+ flex-direction: column;
20014
+ gap: 0.25rem;
20015
+ margin-top: 1.625rem;
20016
+ }
20017
+
20018
+ :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe-name {
20019
+ font-weight: 600;
20020
+ font-size: 0.97rem;
20021
+ color: rgb(var(--tb-text));
20022
+ }
20023
+
20024
+ :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe-context {
20025
+ font-size: 0.78rem;
20026
+ letter-spacing: 0.02em;
20027
+ color: rgb(var(--tb-mutedText));
20028
+ }
20029
+
20030
+ :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe-card--feature .rb-testimonials-fe-name {
20031
+ color: rgb(var(--tb-onPrimary));
20032
+ }
20033
+
20034
+ :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-fe-card--feature .rb-testimonials-fe-context {
20035
+ color: rgb(var(--tb-onPrimary));
20036
+ opacity: 0.7;
20037
+ }
20038
+
20039
+
18891
20040
  /* Testimonials carousel tweaks: arrow styling + gutters + equal-height cards */
18892
20041
  :where(.theme-scope) :where([data-block="testimonials"]) .rb-testimonials-carousel.carousel-root .carousel-nav-btn {
18893
20042
  height: var(--rb-testimonial-carousel-arrow-size);
@@ -20034,7 +21183,7 @@ const containerResponsiveThemeCss = `/*
20034
21183
 
20035
21184
  :where(.theme-scope) :where([data-block="newsletter-signup"]) .newsletter-copy-subtitle {
20036
21185
  font-size: 1rem;
20037
- color: var(--section-text-color, rgb(var(--tb-text)));
21186
+ color: var(--rb-surface-text-color, rgb(var(--tb-text, 17 24 39)));
20038
21187
  opacity: 0.85;
20039
21188
  }
20040
21189
 
@@ -20083,7 +21232,7 @@ const containerResponsiveThemeCss = `/*
20083
21232
  margin-top: 0.75rem;
20084
21233
  font-size: 1rem;
20085
21234
  line-height: 1.6;
20086
- color: var(--section-text-color, rgb(var(--tb-text)));
21235
+ color: var(--rb-surface-text-color, rgb(var(--tb-text, 17 24 39)));
20087
21236
  text-align: center;
20088
21237
  }
20089
21238
 
@@ -20165,7 +21314,7 @@ const containerResponsiveThemeCss = `/*
20165
21314
 
20166
21315
  :where(.theme-scope) :where([data-block="contact-newsletter"]) .form-copy-intro,
20167
21316
  :where(.theme-scope) :where([data-block="contact-newsletter"]) .newsletter-copy-subtitle {
20168
- color: var(--section-text-color, rgb(var(--tb-text)));
21317
+ color: var(--rb-surface-text-color, rgb(var(--tb-text, 17 24 39)));
20169
21318
  }
20170
21319
 
20171
21320
  :where(.theme-scope) :where([data-block="contact-newsletter"]) .contact-newsletter-info {
@@ -20563,7 +21712,7 @@ const containerResponsiveThemeCss = `/*
20563
21712
 
20564
21713
  :where(.theme-scope) .event-compact-row-title {
20565
21714
  margin: 0;
20566
- color: var(--section-heading-color, rgb(var(--tb-primary, 0 0 0)));
21715
+ color: var(--rb-surface-heading-color, var(--rb-surface-text-color, rgb(var(--tb-primary, var(--tb-text, 17 24 39)))));
20567
21716
  font-family: var(--font-heading, var(--font-body, inherit));
20568
21717
  font-size: clamp(1.05rem, 1rem + 0.35vw, 1.3rem);
20569
21718
  font-weight: 400;
@@ -21225,27 +22374,41 @@ const containerResponsiveThemeCss = `/*
21225
22374
  background: rgb(var(--tb-surface));
21226
22375
  }
21227
22376
  :where(.theme-scope) .rb-card-treatment-color-blocked:nth-child(3n + 1) {
22377
+ background: rgb(var(--tb-surface));
21228
22378
  color: rgb(var(--tb-onSurface));
22379
+ --rb-surface-text-color: rgb(var(--tb-onSurface));
22380
+ --rb-surface-heading-color: rgb(var(--tb-onSurface));
22381
+ --rb-surface-link-color: rgb(var(--tb-onSurface));
22382
+ --rb-surface-supporting-color: rgb(var(--tb-onSurface));
21229
22383
  }
21230
22384
 
21231
22385
  :where(.theme-scope) .rb-card-treatment-color-blocked:nth-child(3n + 2) > .rb-bg-surface {
21232
22386
  background: rgb(var(--tb-secondary));
21233
22387
  }
21234
22388
  :where(.theme-scope) .rb-card-treatment-color-blocked:nth-child(3n + 2) {
22389
+ background: rgb(var(--tb-secondary));
21235
22390
  color: rgb(var(--tb-onSecondary));
22391
+ --rb-surface-text-color: rgb(var(--tb-onSecondary));
22392
+ --rb-surface-heading-color: rgb(var(--tb-onSecondary));
22393
+ --rb-surface-link-color: rgb(var(--tb-onSecondary));
22394
+ --rb-surface-supporting-color: rgb(var(--tb-onSecondary));
21236
22395
  }
21237
22396
 
21238
22397
  :where(.theme-scope) .rb-card-treatment-color-blocked:nth-child(3n + 3) > .rb-bg-surface {
21239
22398
  background: rgb(var(--tb-primary));
21240
22399
  }
21241
22400
  :where(.theme-scope) .rb-card-treatment-color-blocked:nth-child(3n + 3) {
22401
+ background: rgb(var(--tb-primary));
21242
22402
  color: rgb(var(--tb-onPrimary));
22403
+ --rb-surface-text-color: rgb(var(--tb-onPrimary));
22404
+ --rb-surface-heading-color: rgb(var(--tb-onPrimary));
22405
+ --rb-surface-link-color: rgb(var(--tb-onPrimary));
22406
+ --rb-surface-supporting-color: rgb(var(--tb-onPrimary));
21243
22407
  }
21244
22408
 
21245
- /* Body copy carries an inline muted colour from the block; force it to the
21246
- * card's on-colour so it reads on every block (inline style needs !important). */
22409
+ /* Keep the intended visual hierarchy; the body color itself now resolves via
22410
+ * the nearest surface provider instead of requiring an inline override. */
21247
22411
  :where(.theme-scope) .rb-card-treatment-color-blocked .rb-feature-card-body {
21248
- color: inherit !important;
21249
22412
  opacity: 0.9;
21250
22413
  }
21251
22414