@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
@@ -1,4 +1,34 @@
1
1
  import { t as parseColorTokenParts } from "./colorTokenParts-dT8MISgJ.mjs";
2
+ //#region ../theme-core/src/surfaces/foregroundContract.ts
3
+ const SURFACE_FOREGROUND_CSS_VARS = {
4
+ text: "--rb-surface-text-color",
5
+ heading: "--rb-surface-heading-color",
6
+ link: "--rb-surface-link-color",
7
+ supporting: "--rb-surface-supporting-color"
8
+ };
9
+ const DEFAULT_SURFACE_TEXT_COLOR = "rgb(var(--tb-text, 17 24 39))";
10
+ const DEFAULT_ROLE_FALLBACKS = {
11
+ text: DEFAULT_SURFACE_TEXT_COLOR,
12
+ heading: DEFAULT_SURFACE_TEXT_COLOR,
13
+ link: "rgb(var(--tb-primary, var(--tb-text, 17 24 39)))",
14
+ supporting: "rgb(var(--tb-mutedText, 100 116 139))"
15
+ };
16
+ function requireSurfaceColorValue(role, value) {
17
+ const normalized = value.trim();
18
+ if (normalized.length === 0) throw new RangeError(`Surface foreground ${role} must be a non-empty CSS color.`);
19
+ return normalized;
20
+ }
21
+ function surfaceForegroundValue(role, outsideProviderFallback = DEFAULT_ROLE_FALLBACKS[role]) {
22
+ const roleVariable = SURFACE_FOREGROUND_CSS_VARS[role];
23
+ const fallback = requireSurfaceColorValue("fallback", outsideProviderFallback);
24
+ if (role === "text") return `var(${roleVariable}, ${fallback})`;
25
+ return `var(${roleVariable}, var(${SURFACE_FOREGROUND_CSS_VARS.text}, ${fallback}))`;
26
+ }
27
+ function surfaceForegroundValueWithOpacity(role, opacityPercent) {
28
+ if (!Number.isFinite(opacityPercent) || opacityPercent < 0 || opacityPercent > 100) throw new RangeError("Surface foreground opacity must be between 0 and 100.");
29
+ return `color-mix(in srgb, ${surfaceForegroundValue(role)} ${opacityPercent}%, transparent)`;
30
+ }
31
+ //#endregion
2
32
  //#region ../theme-core/src/utils/colorStyles.ts
3
33
  const COLOR_VAR_PREFIX = "--tb-";
4
34
  function parseToken(source) {
@@ -10,9 +40,17 @@ function parseToken(source) {
10
40
  if (parts.kind === "invalid") return { token: source };
11
41
  return {
12
42
  token: parts.token,
13
- alpha: parts.opacityPercent === null ? void 0 : parts.opacityPercent / 100
43
+ opacityPercent: parts.opacityPercent === null ? void 0 : parts.opacityPercent
14
44
  };
15
45
  }
46
+ const SURFACE_TEXT_ROLE_BY_TOKEN = {
47
+ text: "text",
48
+ heading: "heading",
49
+ mutedText: "supporting"
50
+ };
51
+ function surfaceRoleForTextToken(token) {
52
+ return Object.prototype.hasOwnProperty.call(SURFACE_TEXT_ROLE_BY_TOKEN, token) ? SURFACE_TEXT_ROLE_BY_TOKEN[token] : null;
53
+ }
16
54
  /**
17
55
  * Converts a theme color token to a CSS rgb value.
18
56
  * This is the primary function for applying theme colors to CSS properties.
@@ -26,11 +64,11 @@ function parseToken(source) {
26
64
  * rgbColorValue('raw:transparent') // => 'transparent'
27
65
  */
28
66
  function rgbColorValue(token) {
29
- const { token: baseToken, alpha, raw } = parseToken(token);
67
+ const { token: baseToken, opacityPercent, raw } = parseToken(token);
30
68
  if (raw) return raw;
31
69
  const cssVar = `${COLOR_VAR_PREFIX}${baseToken}`;
32
- if (alpha === void 0) return `rgb(var(${cssVar}))`;
33
- return `rgb(var(${cssVar}) / ${alpha})`;
70
+ if (opacityPercent === void 0) return `rgb(var(${cssVar}))`;
71
+ return `rgb(var(${cssVar}) / ${opacityPercent / 100})`;
34
72
  }
35
73
  /**
36
74
  * Creates a backgroundColor style object from a theme token.
@@ -48,6 +86,9 @@ function backgroundColorStyle(token) {
48
86
  * @returns CSSProperties with color
49
87
  */
50
88
  function textColorStyle(token) {
89
+ const parsed = parseToken(token);
90
+ const surfaceRole = parsed.raw ? null : surfaceRoleForTextToken(parsed.token);
91
+ if (surfaceRole) return { color: parsed.opacityPercent === void 0 ? surfaceForegroundValue(surfaceRole) : surfaceForegroundValueWithOpacity(surfaceRole, parsed.opacityPercent) };
51
92
  return { color: rgbColorValue(token) };
52
93
  }
53
94
  /**
@@ -1,17 +1,17 @@
1
1
  "use client";
2
- import { Dt as formatBookingTime, Mt as toBookingTimeZone, Nt as toScheduledBookingDateTime, t as defineIslandPropsDecoder, wt as formatBookingDate } from "./propsDecoder-WS6UEJwZ.mjs";
3
- import { n as formatCoursePriceDisplay, r as resolveCoursePricingState, t as formatCoursePriceAmount } from "./pricing-B5GmvfIH.mjs";
2
+ import { Nt as toBookingTimeZone, Ot as formatBookingTime, Pt as toScheduledBookingDateTime, Tt as formatBookingDate, t as defineIslandPropsDecoder } from "./propsDecoder-CD2pJ1WB.mjs";
3
+ import { n as formatCoursePriceDisplay, r as resolveCoursePricingState, t as formatCoursePriceAmount } from "./pricing-DIYnyHOk.mjs";
4
4
  import { n as useBlockApi, t as BlockApiProvider } from "./context-BGZNlGXB.mjs";
5
5
  import { n as isSpamProtectionEnabled, r as AltchaWidget, t as getChallengeUrl } from "./src-B833rYRr.mjs";
6
- import { i as CheckIcon, n as TerminalPanel, r as StateIcon, t as useDiscountCodeUi } from "./useDiscountCodeUi-v6OluyWl.mjs";
7
- import { t as DiscountCodeDisclosure } from "./DiscountCodeDisclosure-Dit2aItR.mjs";
8
- import { n as SpinnerNode, r as formatPrice, t as StepIndicator$1 } from "./StepIndicator-CRR17tYI.mjs";
9
- import { t as themeButtonClassName } from "./buttons-BbPn8OKA.mjs";
6
+ import { i as CheckIcon, n as TerminalPanel, r as StateIcon, t as useDiscountCodeUi } from "./useDiscountCodeUi-CirrT2bM.mjs";
7
+ import { t as DiscountCodeDisclosure } from "./DiscountCodeDisclosure-BXM73_E5.mjs";
8
+ import { n as SpinnerNode, r as formatPrice, t as StepIndicator$1 } from "./StepIndicator-nWqineJ2.mjs";
9
+ import { t as themeButtonClassName } from "./buttons-DfYyqt8C.mjs";
10
10
  import { t as FeedbackMessage } from "./FeedbackMessage-ByMrs3cr.mjs";
11
11
  import { n as getFieldValidationControlProps, t as FieldValidationMessage } from "./FieldValidationMessage-AYanWFb-.mjs";
12
12
  import { t as buildCheckoutReturnUrls } from "./checkoutUrls-Ct8Mxna3.mjs";
13
13
  import { t as scrollToBlock } from "./scrollToBlock-C86BYkyV.mjs";
14
- import { a as ClockIcon, i as LoggedInAsUser, n as logoutPortal, r as useWaitlistClaim, t as MagicLinkForm } from "./MagicLinkForm-EAsIktfw.mjs";
14
+ import { a as ClockIcon, i as LoggedInAsUser, n as logoutPortal, r as useWaitlistClaim, t as MagicLinkForm } from "./MagicLinkForm-u6Dul4j5.mjs";
15
15
  import { t as CrossIcon } from "./CrossIcon-Dn1KRKW5.mjs";
16
16
  import { t as mountReactIsland } from "./reactMount-SY8AVRof.mjs";
17
17
  import { t as buildRouteIslandApiConfig } from "./routeIslandApiConfig-UNsfPcYq.mjs";
@@ -1,12 +1,13 @@
1
1
  "use client";
2
- import { B as groupEventsByDate, D as getEventRuntimeFiltersKey, E as buildEventRuntimeFilters, G as getLocalDateKey, I as formatEventTeacherLine, K as getLocalMinuteOfDay, L as formatTime, T as buildEventCalendarListingRender, W as getEventAvailability, t as defineIslandPropsDecoder } from "./propsDecoder-WS6UEJwZ.mjs";
3
- import { a as CalendarDayCell, c as useCalendarEvents, d as getOrderedDayNames, f as getWeekCalendarDays, i as WeekAgendaView, l as MONTH_NAMES, o as EventModalProvider, p as isSameLocalDay, r as EventModals, s as useEventModal, t as EventCombinedClient, u as formatDateKey } from "./EventCombined.client-BnREyCjf.mjs";
4
- import { o as EventFilters, t as useEventFilters } from "./useEventFilters-BqSTcNOf.mjs";
2
+ import { t as clsx } from "./clsx-DgIEfj3H.mjs";
3
+ import { B as groupEventsByDate, D as getEventRuntimeFiltersKey, E as buildEventRuntimeFilters, G as getEventAvailabilityStatus, H as resolveEventLinkProps, I as formatEventTeacherLine, K as getLocalDateKey, L as formatTime, T as buildEventCalendarListingRender, W as getEventAvailability, q as getLocalMinuteOfDay, t as defineIslandPropsDecoder } from "./propsDecoder-CD2pJ1WB.mjs";
4
+ import { a as CalendarDayCell, c as useCalendarEvents, d as getOrderedDayNames, f as getWeekCalendarDayTuple, h as isToday, i as WeekAgendaView, l as MONTH_NAMES, m as isSameLocalDay, o as EventModalProvider, p as getWeekCalendarDays, r as EventModals, s as useEventModal, t as EventCombinedClient, u as formatDateKey } from "./EventCombined.client-DT5elP7j.mjs";
5
+ import { o as EventFilters, t as useEventFilters } from "./useEventFilters-CNZxlCcO.mjs";
5
6
  import { t as BlockApiProvider } from "./context-BGZNlGXB.mjs";
6
- import { t as themeButtonClassName } from "./buttons-BbPn8OKA.mjs";
7
+ import { t as themeButtonClassName } from "./buttons-DfYyqt8C.mjs";
7
8
  import { t as mountReactIsland } from "./reactMount-SY8AVRof.mjs";
8
9
  import { t as buildRouteIslandApiConfig } from "./routeIslandApiConfig-UNsfPcYq.mjs";
9
- import { n as EventListingController } from "./EventListing.client-0uHld51x.mjs";
10
+ import { n as EventListingController } from "./EventListing.client-pTYGfV9C.mjs";
10
11
  import { useEffect, useId, useMemo, useState } from "react";
11
12
  import { jsx, jsxs } from "react/jsx-runtime";
12
13
  //#region ../calendar/src/lane-packing.ts
@@ -322,6 +323,154 @@ function parseDateKey(dateKey) {
322
323
  };
323
324
  }
324
325
  //#endregion
326
+ //#region ../blocks/src/system/runtime/nodes/events/shared/WeekBoardView.tsx
327
+ const SHORT_DAY_NAMES = [
328
+ "Sun",
329
+ "Mon",
330
+ "Tue",
331
+ "Wed",
332
+ "Thu",
333
+ "Fri",
334
+ "Sat"
335
+ ];
336
+ const LEGEND_ITEMS = [
337
+ {
338
+ status: "available",
339
+ label: "Places available"
340
+ },
341
+ {
342
+ status: "filling",
343
+ label: "Filling up"
344
+ },
345
+ {
346
+ status: "waitlist",
347
+ label: "Waitlist"
348
+ }
349
+ ];
350
+ /**
351
+ * Format an event's start–end as a compact range, merging the shared meridiem.
352
+ * "6:00 PM" + "7:00 PM" -> "6:00 – 7:00 PM"; "9:30 AM" + "10:15 AM" -> "9:30 – 10:15 AM".
353
+ */
354
+ function formatCompactTimeRange(event) {
355
+ const timeZone = event.timeZone ?? null;
356
+ const start = formatTime(event.startsAt, { timeZone });
357
+ const end = formatTime(event.endsAt, { timeZone });
358
+ const startMeridiem = start.slice(-2);
359
+ const endMeridiem = end.slice(-2);
360
+ if ((startMeridiem === "AM" || startMeridiem === "PM") && startMeridiem === endMeridiem) return `${start.slice(0, -3).trim()} – ${end}`;
361
+ return `${start} – ${end}`;
362
+ }
363
+ const WeekBoardCard = ({ event, showCapacity }) => {
364
+ const linkProps = resolveEventLinkProps(event);
365
+ const { status, label } = getEventAvailabilityStatus(event);
366
+ const pill = showCapacity ? label : null;
367
+ return /* @__PURE__ */ jsxs("a", {
368
+ ...linkProps,
369
+ className: "event-week-board-card",
370
+ "data-status": status,
371
+ children: [
372
+ /* @__PURE__ */ jsx("span", {
373
+ className: "event-week-board-card-title",
374
+ children: event.title
375
+ }),
376
+ /* @__PURE__ */ jsx("span", {
377
+ className: "event-week-board-card-time",
378
+ children: formatCompactTimeRange(event)
379
+ }),
380
+ pill ? /* @__PURE__ */ jsx("span", {
381
+ className: "event-week-board-card-pill",
382
+ "data-status": status,
383
+ children: pill
384
+ }) : null
385
+ ]
386
+ });
387
+ };
388
+ /**
389
+ * WeekBoardView
390
+ *
391
+ * Compact "class day-board": day columns side by side (one card per class per
392
+ * day), a legend of the three availability states, and a footer CTA. Collapses
393
+ * to a stacked list on mobile. Repurposes the week-grouped agenda data as a
394
+ * board rather than an hour-positioned timetable grid.
395
+ */
396
+ const WeekBoardView = ({ days, events, showCapacity, emptyMessage = "No classes scheduled this week", title = "The week ahead", footerNote = "New to a class? We'll check it's right for you first.", ctaLabel = "Reserve a place", ctaHref = null, buttonVariant = "outline" }) => {
397
+ const eventsByDate = groupEventsByDate(events);
398
+ const hasAnyEvents = days.some((date) => (eventsByDate.get(formatDateKey(date)) ?? []).length > 0);
399
+ const ctaClassName = themeButtonClassName({
400
+ variant: buttonVariant,
401
+ size: "sm"
402
+ });
403
+ return /* @__PURE__ */ jsx("div", {
404
+ className: "event-calendar event-calendar--week-board",
405
+ "data-block": "event-calendar",
406
+ children: /* @__PURE__ */ jsxs("div", {
407
+ className: "event-week-board",
408
+ style: { "--event-week-board-cols": String(days.length) },
409
+ children: [
410
+ /* @__PURE__ */ jsxs("div", {
411
+ className: "event-week-board-top",
412
+ children: [/* @__PURE__ */ jsx("span", {
413
+ className: "event-week-board-title",
414
+ children: title
415
+ }), /* @__PURE__ */ jsx("div", {
416
+ className: "event-week-board-legend",
417
+ "aria-hidden": "true",
418
+ children: LEGEND_ITEMS.map((item) => /* @__PURE__ */ jsxs("span", {
419
+ className: "event-week-board-legend-item",
420
+ children: [/* @__PURE__ */ jsx("i", {
421
+ className: "event-week-board-legend-dot",
422
+ "data-status": item.status
423
+ }), item.label]
424
+ }, item.status))
425
+ })]
426
+ }),
427
+ /* @__PURE__ */ jsx("div", {
428
+ className: "event-week-board-grid",
429
+ children: days.map((date) => {
430
+ const dateKey = formatDateKey(date);
431
+ const dayEvents = eventsByDate.get(dateKey) ?? [];
432
+ const today = isToday(date);
433
+ return /* @__PURE__ */ jsxs("div", {
434
+ className: clsx("event-week-board-day", dayEvents.length === 0 && "event-week-board-day--empty", today && "event-week-board-day--today"),
435
+ children: [/* @__PURE__ */ jsxs("div", {
436
+ className: "event-week-board-day-head",
437
+ children: [/* @__PURE__ */ jsx("span", {
438
+ className: "event-week-board-day-abbr",
439
+ children: SHORT_DAY_NAMES[date.getDay()]
440
+ }), /* @__PURE__ */ jsx("span", {
441
+ className: "event-week-board-day-num",
442
+ children: date.getDate()
443
+ })]
444
+ }), /* @__PURE__ */ jsx("div", {
445
+ className: "event-week-board-day-body",
446
+ children: dayEvents.map((event) => /* @__PURE__ */ jsx(WeekBoardCard, {
447
+ event,
448
+ showCapacity
449
+ }, event.occurrenceId || event.id))
450
+ })]
451
+ }, dateKey);
452
+ })
453
+ }),
454
+ /* @__PURE__ */ jsxs("div", {
455
+ className: "event-week-board-foot",
456
+ children: [/* @__PURE__ */ jsx("p", {
457
+ className: "event-week-board-foot-note",
458
+ children: hasAnyEvents ? footerNote : emptyMessage
459
+ }), ctaHref ? /* @__PURE__ */ jsx("a", {
460
+ className: ctaClassName,
461
+ href: ctaHref,
462
+ children: ctaLabel
463
+ }) : /* @__PURE__ */ jsx("button", {
464
+ type: "button",
465
+ className: ctaClassName,
466
+ children: ctaLabel
467
+ })]
468
+ })
469
+ ]
470
+ })
471
+ });
472
+ };
473
+ //#endregion
325
474
  //#region ../blocks/src/system/runtime/nodes/events/shared/timetableModel.ts
326
475
  /**
327
476
  * Event-domain adapter over @riverbankcms/calendar.
@@ -586,8 +735,19 @@ const EventCalendarClient = ({ render }) => {
586
735
  });
587
736
  if (display.displayMode === "list") return /* @__PURE__ */ jsx(EventListingController, { render: buildEventCalendarListingRender(render) });
588
737
  if (display.displayMode === "timetable") return /* @__PURE__ */ jsx(EventCalendarTimetableClient, { render });
738
+ if (display.displayMode === "week-board") return /* @__PURE__ */ jsx(EventCalendarWeekBoardClient, { display });
589
739
  return /* @__PURE__ */ jsx(EventCalendarGridClient, { render });
590
740
  };
741
+ const EventCalendarWeekBoardClient = ({ display }) => {
742
+ return /* @__PURE__ */ jsx(WeekBoardView, {
743
+ days: useMemo(() => getWeekCalendarDayTuple(/* @__PURE__ */ new Date(), display.startOfWeek), [display.startOfWeek]),
744
+ events: [...display.events],
745
+ showCapacity: display.showCapacity,
746
+ emptyMessage: display.emptyMessage,
747
+ ctaLabel: display.buttonText,
748
+ buttonVariant: display.buttonVariant
749
+ });
750
+ };
591
751
  const EventCalendarTimetableClient = ({ render }) => {
592
752
  const { display, hydration } = render;
593
753
  const { filtersNode, listFilters } = useEventCalendarFilterState(display);
@@ -1,5 +1,5 @@
1
- import { t as defineIslandPropsDecoder } from "./propsDecoder-WS6UEJwZ.mjs";
2
- import { n as EventCombinedIslandClient } from "./EventCombined.client-BnREyCjf.mjs";
1
+ import { t as defineIslandPropsDecoder } from "./propsDecoder-CD2pJ1WB.mjs";
2
+ import { n as EventCombinedIslandClient } from "./EventCombined.client-DT5elP7j.mjs";
3
3
  import { t as BlockApiProvider } from "./context-BGZNlGXB.mjs";
4
4
  import { t as mountReactIsland } from "./reactMount-SY8AVRof.mjs";
5
5
  import { t as buildRouteIslandApiConfig } from "./routeIslandApiConfig-UNsfPcYq.mjs";
@@ -1,8 +1,8 @@
1
- import { Bt as formatCurrencyAmount, Ft as publicEventPricingCurrency, H as resolveEventLinkProps, Lt as publicEventPricingType, Mt as toBookingTimeZone, N as formatEventDateParts, Nt as toScheduledBookingDateTime, P as formatEventPrice, U as resolveRuntimeEventPricing, kt as getBookingLocalDateKey, t as defineIslandPropsDecoder } from "./propsDecoder-WS6UEJwZ.mjs";
2
- import { n as formatCoursePriceDisplay, r as resolveCoursePricingState, t as formatCoursePriceAmount } from "./pricing-B5GmvfIH.mjs";
1
+ import { At as getBookingLocalDateKey, H as resolveEventLinkProps, It as publicEventPricingCurrency, N as formatEventDateParts, Nt as toBookingTimeZone, P as formatEventPrice, Pt as toScheduledBookingDateTime, Rt as publicEventPricingType, U as resolveRuntimeEventPricing, Vt as formatCurrencyAmount, t as defineIslandPropsDecoder } from "./propsDecoder-CD2pJ1WB.mjs";
2
+ import { n as formatCoursePriceDisplay, r as resolveCoursePricingState, t as formatCoursePriceAmount } from "./pricing-DIYnyHOk.mjs";
3
3
  import { t as mountReactIsland } from "./reactMount-SY8AVRof.mjs";
4
4
  import { n as filterPassesForEvent, t as filterMembershipsForEvent } from "./eventProductEligibility-AVxyCB1u.mjs";
5
- import { t as LeafletStaticMap } from "./LeafletStaticMap-DJcvSfmj.mjs";
5
+ import { t as LeafletStaticMap } from "./LeafletStaticMap-dQrhlUe3.mjs";
6
6
  import "react";
7
7
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
8
  //#region ../blocks/src/system/runtime/nodes/event-details/logic.ts
@@ -1,8 +1,8 @@
1
- import { t as defineIslandPropsDecoder } from "./propsDecoder-WS6UEJwZ.mjs";
1
+ import { t as defineIslandPropsDecoder } from "./propsDecoder-CD2pJ1WB.mjs";
2
2
  import { t as BlockApiProvider } from "./context-BGZNlGXB.mjs";
3
3
  import { t as mountReactIsland } from "./reactMount-SY8AVRof.mjs";
4
4
  import { t as buildRouteIslandApiConfig } from "./routeIslandApiConfig-UNsfPcYq.mjs";
5
- import { t as EventListingClient } from "./EventListing.client-0uHld51x.mjs";
5
+ import { t as EventListingClient } from "./EventListing.client-pTYGfV9C.mjs";
6
6
  import "react";
7
7
  import { jsx } from "react/jsx-runtime";
8
8
  //#region src/rendering/islands/enhancers/eventListing.tsx
@@ -1,17 +1,17 @@
1
1
  "use client";
2
- import { n as buildBookingPaymentSelectionViewModel, t as usePolling } from "./usePolling-DMfADjIF.mjs";
3
- import { Bt as formatCurrencyAmount, C as getWizardStepsForContext, Dt as formatBookingTime, F as formatEventPriceDisplay, Ft as publicEventPricingCurrency, It as publicEventPricingMode, Lt as publicEventPricingType, Mt as toBookingTimeZone, Nt as toScheduledBookingDateTime, Rt as publicEventScalarPrice, S as getStepNumber, Tt as formatBookingDateTime, U as resolveRuntimeEventPricing, _ as findPreSelectedEvent, b as resolveRegistrationTarget, g as findEventByOccurrenceId, gt as assertNever, h as toRegistrationEvents, t as defineIslandPropsDecoder, v as resolveDiscountContext, w as resolveEventRegistrationScopedEvents, wt as formatBookingDate, x as WIZARD_STEPS, y as resolveEventRequiresPayment, zt as publicEventTicketTypes } from "./propsDecoder-WS6UEJwZ.mjs";
2
+ import { n as buildBookingPaymentSelectionViewModel, t as usePolling } from "./usePolling-Baks_iBI.mjs";
3
+ import { Bt as publicEventTicketTypes, C as getWizardStepsForContext, Et as formatBookingDateTime, F as formatEventPriceDisplay, It as publicEventPricingCurrency, Lt as publicEventPricingMode, Nt as toBookingTimeZone, Ot as formatBookingTime, Pt as toScheduledBookingDateTime, Rt as publicEventPricingType, S as getStepNumber, Tt as formatBookingDate, U as resolveRuntimeEventPricing, Vt as formatCurrencyAmount, _ as findPreSelectedEvent, _t as assertNever, b as resolveRegistrationTarget, g as findEventByOccurrenceId, h as toRegistrationEvents, t as defineIslandPropsDecoder, v as resolveDiscountContext, w as resolveEventRegistrationScopedEvents, x as WIZARD_STEPS, y as resolveEventRequiresPayment, zt as publicEventScalarPrice } from "./propsDecoder-CD2pJ1WB.mjs";
4
4
  import { n as useBlockApi, t as BlockApiProvider } from "./context-BGZNlGXB.mjs";
5
5
  import { n as isSpamProtectionEnabled, r as AltchaWidget, t as getChallengeUrl } from "./src-B833rYRr.mjs";
6
- import { i as CheckIcon, n as TerminalPanel, r as StateIcon, t as useDiscountCodeUi } from "./useDiscountCodeUi-v6OluyWl.mjs";
7
- import { t as DiscountCodeDisclosure } from "./DiscountCodeDisclosure-Dit2aItR.mjs";
8
- import { n as SpinnerNode, r as formatPrice, t as StepIndicator$1 } from "./StepIndicator-CRR17tYI.mjs";
9
- import { t as themeButtonClassName } from "./buttons-BbPn8OKA.mjs";
6
+ import { i as CheckIcon, n as TerminalPanel, r as StateIcon, t as useDiscountCodeUi } from "./useDiscountCodeUi-CirrT2bM.mjs";
7
+ import { t as DiscountCodeDisclosure } from "./DiscountCodeDisclosure-BXM73_E5.mjs";
8
+ import { n as SpinnerNode, r as formatPrice, t as StepIndicator$1 } from "./StepIndicator-nWqineJ2.mjs";
9
+ import { t as themeButtonClassName } from "./buttons-DfYyqt8C.mjs";
10
10
  import { t as FeedbackMessage } from "./FeedbackMessage-ByMrs3cr.mjs";
11
11
  import { n as getFieldValidationControlProps, t as FieldValidationMessage } from "./FieldValidationMessage-AYanWFb-.mjs";
12
12
  import { t as createBodyThemePortalRoot } from "./themePortalRoot-AGs4cE7t.mjs";
13
13
  import { t as consumeSearchParam } from "./urlParams-D71VXFGx.mjs";
14
- import { a as ClockIcon, i as LoggedInAsUser, n as logoutPortal, r as useWaitlistClaim, t as MagicLinkForm } from "./MagicLinkForm-EAsIktfw.mjs";
14
+ import { a as ClockIcon, i as LoggedInAsUser, n as logoutPortal, r as useWaitlistClaim, t as MagicLinkForm } from "./MagicLinkForm-u6Dul4j5.mjs";
15
15
  import { t as CrossIcon } from "./CrossIcon-Dn1KRKW5.mjs";
16
16
  import { t as mountReactIsland } from "./reactMount-SY8AVRof.mjs";
17
17
  import { t as buildRouteIslandApiConfig } from "./routeIslandApiConfig-UNsfPcYq.mjs";
@@ -1,9 +1,9 @@
1
1
  "use client";
2
2
  import { t as clsx } from "./clsx-DgIEfj3H.mjs";
3
- import { gt as assertNever, t as defineIslandPropsDecoder, vt as err, yt as ok } from "./propsDecoder-WS6UEJwZ.mjs";
3
+ import { _t as assertNever, bt as ok, t as defineIslandPropsDecoder, yt as err } from "./propsDecoder-CD2pJ1WB.mjs";
4
4
  import { n as useBlockApi, t as BlockApiProvider } from "./context-BGZNlGXB.mjs";
5
5
  import { n as isSpamProtectionEnabled, r as AltchaWidget, t as getChallengeUrl } from "./src-B833rYRr.mjs";
6
- import { t as themeButtonClassName } from "./buttons-BbPn8OKA.mjs";
6
+ import { t as themeButtonClassName } from "./buttons-DfYyqt8C.mjs";
7
7
  import { t as FeedbackMessage } from "./FeedbackMessage-ByMrs3cr.mjs";
8
8
  import { t as mountReactIsland } from "./reactMount-SY8AVRof.mjs";
9
9
  import { useReducer, useRef, useState } from "react";
@@ -1,8 +1,8 @@
1
1
  "use client";
2
- import { r as buildCartDisplay, t as defineIslandPropsDecoder } from "./propsDecoder-WS6UEJwZ.mjs";
3
- import { t as themeButtonClassName } from "./buttons-BbPn8OKA.mjs";
2
+ import { r as buildCartDisplay, t as defineIslandPropsDecoder } from "./propsDecoder-CD2pJ1WB.mjs";
3
+ import { t as themeButtonClassName } from "./buttons-DfYyqt8C.mjs";
4
4
  import { t as resolveDedicatedCheckoutPath } from "./checkoutRoute-ClwHwYVA.mjs";
5
- import { n as useCommerceCart } from "./shop-commerce-store-l74-Kne6.mjs";
5
+ import { n as useCommerceCart } from "./shop-commerce-store-CfCXltXW.mjs";
6
6
  import { t as ModalShell } from "./ModalShell-CqkBvBIC.mjs";
7
7
  import * as React$1 from "react";
8
8
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";