@riverbankcms/sdk 0.64.0 → 0.67.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/dist/_dts/api/src/aiPlayground.d.ts +18 -11
  2. package/dist/_dts/api/src/apiEndpointTypes.d.ts +12 -0
  3. package/dist/_dts/api/src/bookingOperations.d.ts +1 -1
  4. package/dist/_dts/api/src/endpoints.d.ts +25 -0
  5. package/dist/_dts/api/src/sdkConfig/contracts.d.ts +0 -40
  6. package/dist/_dts/api/src/sdkContracts.d.ts +1 -1
  7. package/dist/_dts/api/src/siteMembers.d.ts +1 -1
  8. package/dist/_dts/api/src/siteOperations.d.ts +1 -1
  9. package/dist/_dts/billing/src/plans/types.d.ts +1 -1
  10. package/dist/_dts/blocks/src/bindings/index.d.ts +1 -1
  11. package/dist/_dts/blocks/src/system/node/validation-constants.d.ts +1 -1
  12. package/dist/_dts/blocks/src/system/transforms/registry/formatting.d.ts +1 -0
  13. package/dist/_dts/blocks/src/system/transforms/typed.d.ts +2 -1
  14. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +81 -0
  15. package/dist/_dts/preview-next/src/client/blocks/pageDesignRuntimePreview.d.ts +7 -3
  16. package/dist/_dts/preview-next/src/client/blocks/previewProjection/runtimeContentDecoration.d.ts +2 -2
  17. package/dist/_dts/sdk/src/cli/commands/push/execute/footer.d.ts +33 -0
  18. package/dist/_dts/sdk/src/cli/commands/push-execute.d.ts +2 -1
  19. package/dist/_dts/sdk/src/cli/env.d.ts +2 -1
  20. package/dist/_dts/sdk/src/cli/merge-remote/entryMergePush.d.ts +2 -1
  21. package/dist/_dts/sdk/src/cli/site-commands/commandKeys.d.ts +13 -0
  22. package/dist/_dts/sdk/src/cli/site-commands/commandRuntime.d.ts +114 -0
  23. package/dist/_dts/sdk/src/cli/site-commands/entryCommands.d.ts +26 -48
  24. package/dist/_dts/sdk/src/cli/site-commands/footerCommands.d.ts +50 -0
  25. package/dist/_dts/sdk/src/cli/site-commands/formCommands.d.ts +57 -0
  26. package/dist/_dts/sdk/src/cli/site-commands/index.d.ts +5 -0
  27. package/dist/_dts/sdk/src/cli/site-commands/navigationCommands.d.ts +57 -0
  28. package/dist/_dts/sdk/src/cli/site-commands/pageCommands.d.ts +83 -0
  29. package/dist/_dts/sdk/src/cli/site-commands/pushExecution.d.ts +67 -14
  30. package/dist/_dts/sdk/src/cli/sync/executor.d.ts +10 -28
  31. package/dist/_dts/sdk/src/cli/sync/index.d.ts +1 -1
  32. package/dist/_dts/sdk/src/config/dashboard-validation.d.ts +0 -48
  33. package/dist/_dts/sdk/src/config/types.d.ts +1 -1
  34. package/dist/_dts/sdk/src/version.d.ts +1 -1
  35. package/dist/_dts/site-commands/src/adapter.d.ts +2 -2
  36. package/dist/_dts/site-commands/src/commands.d.ts +410 -13
  37. package/dist/_dts/site-commands/src/domain.d.ts +3 -3
  38. package/dist/_dts/site-commands/src/exposure.d.ts +41 -0
  39. package/dist/_dts/site-commands/src/index.d.ts +1 -0
  40. package/dist/_dts/site-commands/src/metadata.d.ts +93 -2
  41. package/dist/_dts/site-commands/src/planner.d.ts +13 -6
  42. package/dist/_dts/site-commands/src/refs.d.ts +13 -1
  43. package/dist/_dts/theme-core/src/palette/utils/index.d.ts +1 -0
  44. package/dist/_dts/theme-core/src/palette/utils/onColor.d.ts +2 -0
  45. package/dist/_dts/theme-core/src/site-styles/accessibleSurfaces.d.ts +83 -0
  46. package/dist/_dts/theme-core/src/site-styles/contentTemplateRuntimeCompiler.d.ts +2 -1
  47. package/dist/_dts/theme-core/src/site-styles/curatedSiteStyles.d.ts +89 -12
  48. package/dist/_dts/theme-core/src/site-styles/generatedSchemas.d.ts +8 -2
  49. package/dist/_dts/theme-core/src/site-styles/index.d.ts +1 -0
  50. package/dist/_dts/theme-core/src/site-styles/previewCompiler.d.ts +3 -2
  51. package/dist/_dts/theme-core/src/site-styles/runtimeCompiler.d.ts +9 -6
  52. package/dist/_dts/ui/src/callout.d.ts +1 -1
  53. package/dist/cli/index.mjs +4290 -2513
  54. package/dist/client/client.mjs +598 -372
  55. package/dist/client/hooks.mjs +311 -123
  56. package/dist/client/rendering/client.mjs +209 -68
  57. package/dist/client/rendering/islands.mjs +281 -150
  58. package/dist/client/rendering.mjs +416 -190
  59. package/dist/preview-next/before-render.mjs +61 -13
  60. package/dist/preview-next/client/runtime.mjs +930 -376
  61. package/dist/preview-next/middleware.mjs +61 -13
  62. package/dist/server/components.mjs +526 -325
  63. package/dist/server/config-validation.mjs +313 -125
  64. package/dist/server/config.mjs +313 -125
  65. package/dist/server/data.mjs +311 -123
  66. package/dist/server/index.mjs +78 -16
  67. package/dist/server/next.mjs +527 -326
  68. package/dist/server/page-converter.mjs +159 -41
  69. package/dist/server/prebuild.mjs +1 -1
  70. package/dist/server/rendering/server.mjs +526 -325
  71. package/dist/server/rendering.mjs +526 -325
  72. package/dist/server/routing.mjs +392 -131
  73. package/dist/server/server.mjs +312 -124
  74. package/dist/server/theme-bridge.mjs +155 -48
  75. package/package.json +1 -1
  76. package/dist/_dts/path-utils/src/index.d.ts +0 -8
  77. package/dist/_dts/path-utils/src/redirectPaths.d.ts +0 -26
  78. package/dist/_dts/path-utils/src/safeAppPath.d.ts +0 -26
@@ -1995,6 +1995,144 @@ function resolveVariantKey(manifest, content) {
1995
1995
  return null;
1996
1996
  }
1997
1997
 
1998
+ // ../theme-core/src/palette/utils/colorConversion.ts
1999
+ var clamp01 = (x) => Math.max(0, Math.min(1, x));
2000
+ var mod = (a, n) => (a % n + n) % n;
2001
+ var deg = (x) => mod(x, 360);
2002
+ function hexToRgb(hex) {
2003
+ const h = hex.replace(/^#/, "");
2004
+ const m = h.length === 3 ? h.split("").map((c) => c + c).join("") : h;
2005
+ if (m.length !== 6) throw new Error("Bad hex");
2006
+ const int = parseInt(m, 16);
2007
+ return { r: int >> 16 & 255, g: int >> 8 & 255, b: int & 255 };
2008
+ }
2009
+ function rgbToHex(r2, g, b) {
2010
+ const to = (n) => Math.round(n).toString(16).padStart(2, "0");
2011
+ return `#${to(r2)}${to(g)}${to(b)}`;
2012
+ }
2013
+ function srgbToLinear(u) {
2014
+ const x = u / 255;
2015
+ return x <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);
2016
+ }
2017
+ function linearToSrgb(x) {
2018
+ const y = x <= 31308e-7 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055;
2019
+ return clamp01(y) * 255;
2020
+ }
2021
+ function rgbToHsl(r2, g, b) {
2022
+ const R = r2 / 255, G = g / 255, B = b / 255;
2023
+ const max = Math.max(R, G, B), min = Math.min(R, G, B);
2024
+ const d = max - min;
2025
+ let h = 0;
2026
+ if (d !== 0) {
2027
+ switch (max) {
2028
+ case R:
2029
+ h = (G - B) / d + (G < B ? 6 : 0);
2030
+ break;
2031
+ case G:
2032
+ h = (B - R) / d + 2;
2033
+ break;
2034
+ case B:
2035
+ h = (R - G) / d + 4;
2036
+ break;
2037
+ }
2038
+ h *= 60;
2039
+ }
2040
+ const l = (max + min) / 2;
2041
+ const s = d === 0 ? 0 : d / (1 - Math.abs(2 * l - 1));
2042
+ return { h, s, l };
2043
+ }
2044
+ function srgbToOklab(r2, g, b) {
2045
+ const R = srgbToLinear(r2), G = srgbToLinear(g), B = srgbToLinear(b);
2046
+ const l = 0.4122214708 * R + 0.5363325363 * G + 0.0514459929 * B;
2047
+ const m = 0.2119034982 * R + 0.6806995451 * G + 0.1073969566 * B;
2048
+ const s = 0.0883024619 * R + 0.2817188376 * G + 0.6299787005 * B;
2049
+ const l_ = Math.cbrt(l), m_ = Math.cbrt(m), s_ = Math.cbrt(s);
2050
+ const L = 0.2104542553 * l_ + 0.793617785 * m_ - 0.0040720468 * s_;
2051
+ const a = 1.9779984951 * l_ - 2.428592205 * m_ + 0.4505937099 * s_;
2052
+ const b2 = 0.0259040371 * l_ + 0.7827717662 * m_ - 0.808675766 * s_;
2053
+ return { L, a, b: b2 };
2054
+ }
2055
+ function oklabToSrgb(L, a, b) {
2056
+ const l_ = Math.pow(L + 0.3963377774 * a + 0.2158037573 * b, 3);
2057
+ const m_ = Math.pow(L - 0.1055613458 * a - 0.0638541728 * b, 3);
2058
+ const s_ = Math.pow(L - 0.0894841775 * a - 1.291485548 * b, 3);
2059
+ const R = 4.0767416621 * l_ - 3.3077115913 * m_ + 0.2309699292 * s_;
2060
+ const G = -1.2684380046 * l_ + 2.6097574011 * m_ - 0.3413193965 * s_;
2061
+ const B = -0.0041960863 * l_ - 0.7034186147 * m_ + 1.707614701 * s_;
2062
+ return { r: linearToSrgb(R), g: linearToSrgb(G), b: linearToSrgb(B) };
2063
+ }
2064
+ function oklabToOklch(L, a, b) {
2065
+ const C = Math.sqrt(a * a + b * b);
2066
+ const h = C < 1e-7 ? 0 : deg(Math.atan2(b, a) * 180 / Math.PI);
2067
+ return { L, C, h };
2068
+ }
2069
+ function oklchToOklab(L, C, h) {
2070
+ const hr = h * Math.PI / 180;
2071
+ const a = C * Math.cos(hr);
2072
+ const b = C * Math.sin(hr);
2073
+ return { L, a, b };
2074
+ }
2075
+ function inSRGB(r2, g, b) {
2076
+ return r2 >= 0 && r2 <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255;
2077
+ }
2078
+ function oklchToHexGamut(L, C, h) {
2079
+ let lo = 0, hi = C, best = 0;
2080
+ for (let i = 0; i < 18; i++) {
2081
+ const mid = (lo + hi) / 2;
2082
+ const { a: a2, b: b2 } = oklchToOklab(L, mid, h);
2083
+ const { r: r3, g: g2, b: bb2 } = oklabToSrgb(L, a2, b2);
2084
+ if (inSRGB(r3, g2, bb2)) {
2085
+ best = mid;
2086
+ lo = mid;
2087
+ } else {
2088
+ hi = mid;
2089
+ }
2090
+ }
2091
+ const { a, b } = oklchToOklab(L, best, h);
2092
+ const { r: r2, g, b: bb } = oklabToSrgb(L, a, b);
2093
+ return rgbToHex(r2, g, bb);
2094
+ }
2095
+ function featuresFromHex(hex) {
2096
+ const { r: r2, g, b } = hexToRgb(hex);
2097
+ const { h, s, l } = rgbToHsl(r2, g, b);
2098
+ const { L, a, b: b2 } = srgbToOklab(r2, g, b);
2099
+ const { L: okL, C: okC, h: okH } = oklabToOklch(L, a, b2);
2100
+ const max = Math.max(r2, g, b);
2101
+ const v = max / 255;
2102
+ const Y = 0.2126 * srgbToLinear(r2) + 0.7152 * srgbToLinear(g) + 0.0722 * srgbToLinear(b);
2103
+ const chroma = s;
2104
+ return { r: r2, g, b, h, s, l, v, Y, chroma, okL, okC, okH, hex };
2105
+ }
2106
+
2107
+ // ../theme-core/src/palette/utils/contrast.ts
2108
+ function relativeLuminance(r2, g, b) {
2109
+ const R = srgbToLinear(r2), G = srgbToLinear(g), B = srgbToLinear(b);
2110
+ return 0.2126 * R + 0.7152 * G + 0.0722 * B;
2111
+ }
2112
+
2113
+ // ../theme-core/src/palette/utils/onColor.ts
2114
+ var BACKGROUND_ROLE_NAMES = /* @__PURE__ */ new Set([
2115
+ "primary",
2116
+ "secondary",
2117
+ "accent",
2118
+ "success",
2119
+ "warning",
2120
+ "destructive",
2121
+ "info",
2122
+ "background",
2123
+ "surface",
2124
+ "surfaceAlt",
2125
+ "muted",
2126
+ "neutral"
2127
+ ]);
2128
+ function onColorTokenName(backgroundToken) {
2129
+ return `on${backgroundToken.split("-").filter((part) => part.length > 0).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("")}`;
2130
+ }
2131
+ function isOnColorBackgroundCandidateToken(token) {
2132
+ const role = token.match(/^(.*?)(?:-\d{2,3})?$/)?.[1] ?? token;
2133
+ return BACKGROUND_ROLE_NAMES.has(role);
2134
+ }
2135
+
1998
2136
  // ../theme-core/src/site-styles/appearancePresetResolution.ts
1999
2137
  function assertValidOptionGroups(preset2) {
2000
2138
  preset2.optionGroups?.forEach((group) => {
@@ -7616,6 +7754,9 @@ var curatedSiteStyleIdValues = [
7616
7754
  "site-style:bright-community",
7617
7755
  "site-style:quiet-luxury",
7618
7756
  "site-style:practical-services",
7757
+ "site-style:quiet-practice",
7758
+ "site-style:personal-retreat-journal",
7759
+ "site-style:tactile-workshop",
7619
7760
  "site-style:modern-wellness",
7620
7761
  "site-style:bold-launch",
7621
7762
  "site-style:south-west-twerk-school"
@@ -7698,7 +7839,8 @@ function defineCuratedSiteStyle(input) {
7698
7839
  name: input.name,
7699
7840
  description: input.description,
7700
7841
  generationBrief: input.generationBrief,
7701
- selectionKeywords: input.selectionKeywords ?? [],
7842
+ selectionKeywordRules: input.selectionKeywordRules ?? [],
7843
+ siteCreatorSelection: input.siteCreatorSelection ?? { kind: "explicit_only" },
7702
7844
  template: {
7703
7845
  id: asDesignSystemTemplateId(`template:${input.id.replace("site-style:", "")}`),
7704
7846
  name: input.name,
@@ -7842,12 +7984,13 @@ var curatedSiteStyles = [
7842
7984
  name: "Quiet Luxury",
7843
7985
  description: "Minimal, confident, and refined for premium experiences and private services.",
7844
7986
  generationBrief: "Use fewer claims, more specificity, and restrained sensory detail. Favor elegant media and low repetition over dense panels.",
7845
- selectionKeywords: [
7846
- "luxury",
7847
- "premium",
7848
- "boutique",
7849
- "bespoke",
7850
- "exclusive"
7987
+ siteCreatorSelection: { kind: "site_creator_keyword_heuristic", priority: 20 },
7988
+ selectionKeywordRules: [
7989
+ { kind: "word", value: "luxury" },
7990
+ { kind: "word", value: "premium" },
7991
+ { kind: "word", value: "boutique" },
7992
+ { kind: "word", value: "bespoke" },
7993
+ { kind: "word", value: "exclusive" }
7851
7994
  ],
7852
7995
  tokenRecipes: {
7853
7996
  palette: "high-contrast",
@@ -7876,13 +8019,14 @@ var curatedSiteStyles = [
7876
8019
  name: "Practical Services",
7877
8020
  description: "Efficient, plainspoken, and conversion-focused for trades and everyday services.",
7878
8021
  generationBrief: "Make services, location, trust signals, and contact paths obvious. Keep copy brief and avoid ornate visual treatments.",
7879
- selectionKeywords: [
7880
- "repair",
7881
- "plumb",
7882
- "electric",
7883
- "cleaning",
7884
- "landscap",
7885
- "contractor"
8022
+ siteCreatorSelection: { kind: "primary_goal_support" },
8023
+ selectionKeywordRules: [
8024
+ { kind: "word", value: "repair" },
8025
+ { kind: "substring", value: "plumb" },
8026
+ { kind: "substring", value: "electric" },
8027
+ { kind: "word", value: "cleaning" },
8028
+ { kind: "substring", value: "landscap" },
8029
+ { kind: "substring", value: "contractor" }
7886
8030
  ],
7887
8031
  tokenRecipes: {
7888
8032
  palette: "brand-led",
@@ -7933,18 +8077,134 @@ var curatedSiteStyles = [
7933
8077
  paletteChoice("warm-neutral-forest")
7934
8078
  ]
7935
8079
  }),
8080
+ defineCuratedSiteStyle({
8081
+ id: "site-style:quiet-practice",
8082
+ name: "Quiet Practice",
8083
+ description: "Grounded, calm, and practical for small appointment-first practices.",
8084
+ generationBrief: "Make services, practitioner trust, preparation notes, and booking routes easy to scan. Keep the tone warm and specific, with quiet confidence rather than spa cliches or medical claims.",
8085
+ siteCreatorSelection: { kind: "site_creator_keyword_heuristic", priority: 30 },
8086
+ selectionKeywordRules: [
8087
+ { kind: "substring", value: "massage" },
8088
+ { kind: "word", value: "bodywork" },
8089
+ { kind: "phrase", value: "appointment practice" },
8090
+ { kind: "phrase", value: "appointment-first" },
8091
+ { kind: "substring", value: "practitioner" },
8092
+ { kind: "substring", value: "therap" },
8093
+ { kind: "substring", value: "clinic" },
8094
+ { kind: "phrase", value: "wellness practice" }
8095
+ ],
8096
+ tokenRecipes: {
8097
+ palette: "soft-natural",
8098
+ contrast: "standard",
8099
+ radius: "soft",
8100
+ shadow: "subtle",
8101
+ typography: "clean-sans",
8102
+ spacing: "regular",
8103
+ motion: "subtle"
8104
+ },
8105
+ compositionBudget: quietBudget,
8106
+ recommendedHeaderLookIds: ["practical-utility", "clean-base", "centered-calm"],
8107
+ buttonPersonalityChoices: [
8108
+ buttonChoice("pebble"),
8109
+ buttonChoice("soft-pill"),
8110
+ buttonChoice("editorial-link")
8111
+ ],
8112
+ paletteVariantChoices: [
8113
+ paletteChoice("soft-natural-stone"),
8114
+ paletteChoice("soft-natural-sage"),
8115
+ paletteChoice("warm-neutral-clay")
8116
+ ]
8117
+ }),
8118
+ defineCuratedSiteStyle({
8119
+ id: "site-style:personal-retreat-journal",
8120
+ name: "Personal Retreat Journal",
8121
+ description: "Warm, story-led, and readable for solo practitioners with mixed offers.",
8122
+ generationBrief: "Center the practitioner as the guide, then make private sessions, classes, retreats, and resources feel like clear pathways. Keep retreat copy grounded and practical, with enough editorial warmth for longer reading.",
8123
+ siteCreatorSelection: { kind: "site_creator_keyword_heuristic", priority: 40 },
8124
+ selectionKeywordRules: [
8125
+ { kind: "substring", value: "retreat" },
8126
+ { kind: "phrase", value: "solo practitioner" },
8127
+ { kind: "phrase", value: "personal brand" },
8128
+ { kind: "substring", value: "teacher" },
8129
+ { kind: "substring", value: "coach" },
8130
+ { kind: "phrase", value: "retreat resources" },
8131
+ { kind: "substring", value: "journal" }
8132
+ ],
8133
+ tokenRecipes: {
8134
+ palette: "warm-neutral",
8135
+ contrast: "standard",
8136
+ radius: "soft",
8137
+ shadow: "subtle",
8138
+ typography: "serif-editorial",
8139
+ spacing: "airy",
8140
+ motion: "subtle"
8141
+ },
8142
+ compositionBudget: balancedBudget,
8143
+ recommendedHeaderLookIds: ["editorial-line", "centered-calm", "minimal-transparent"],
8144
+ buttonPersonalityChoices: [
8145
+ buttonChoice("editorial-link"),
8146
+ buttonChoice("soft-pill"),
8147
+ buttonChoice("brushed-wash")
8148
+ ],
8149
+ paletteVariantChoices: [
8150
+ paletteChoice("warm-neutral-forest"),
8151
+ paletteChoice("warm-neutral-clay"),
8152
+ paletteChoice("soft-natural-stone")
8153
+ ]
8154
+ }),
8155
+ defineCuratedSiteStyle({
8156
+ id: "site-style:tactile-workshop",
8157
+ name: "Tactile Workshop",
8158
+ description: "Bright, hands-on, and image-led for maker studios, workshops, and creative classes.",
8159
+ generationBrief: "Lead with objects, materials, studio process, and practical booking detail. Keep the tone warm and direct, with useful mess, clear dates, and enough gallery rhythm to feel like a real creative studio.",
8160
+ siteCreatorSelection: { kind: "site_creator_keyword_heuristic", priority: 50 },
8161
+ selectionKeywordRules: [
8162
+ { kind: "substring", value: "ceramic" },
8163
+ { kind: "word", value: "pottery" },
8164
+ { kind: "phrase", value: "maker studio" },
8165
+ { kind: "phrase", value: "craft class" },
8166
+ { kind: "phrase", value: "craft workshop" },
8167
+ { kind: "word", value: "clay" },
8168
+ { kind: "word", value: "kiln" }
8169
+ ],
8170
+ tokenRecipes: {
8171
+ palette: "brand-led",
8172
+ contrast: "standard",
8173
+ radius: "soft",
8174
+ shadow: "subtle",
8175
+ typography: "friendly-sans",
8176
+ spacing: "regular",
8177
+ motion: "subtle"
8178
+ },
8179
+ compositionBudget: balancedBudget,
8180
+ recommendedHeaderLookIds: ["brand-solid", "practical-utility", "clean-base"],
8181
+ recommendedFooterLookIds: ["site-footer-brand-two-band", "footer-muted-grounding"],
8182
+ buttonPersonalityChoices: [
8183
+ buttonChoice("pebble"),
8184
+ buttonChoice("confident-chip"),
8185
+ buttonChoice("ink-stamp"),
8186
+ buttonChoice("editorial-link")
8187
+ ],
8188
+ paletteVariantChoices: [
8189
+ paletteChoice("brand-led-warm"),
8190
+ paletteChoice("brand-led-cool"),
8191
+ paletteChoice("soft-natural-watercolor"),
8192
+ paletteChoice("warm-neutral-clay")
8193
+ ]
8194
+ }),
7936
8195
  defineCuratedSiteStyle({
7937
8196
  id: "site-style:bold-launch",
7938
8197
  name: "Bold Launch",
7939
8198
  description: "High-energy and punchy for launches, campaigns, and creative offers.",
7940
8199
  generationBrief: "Use crisp positioning, bold hero structure, strong calls to action, and confident visual rhythm. Keep it precise, not shouty.",
7941
- selectionKeywords: [
7942
- "launch",
7943
- "campaign",
7944
- "preorder",
7945
- "pre-order",
7946
- "waitlist",
7947
- "drop"
8200
+ siteCreatorSelection: { kind: "site_creator_keyword_heuristic", priority: 10 },
8201
+ selectionKeywordRules: [
8202
+ { kind: "substring", value: "launch" },
8203
+ { kind: "substring", value: "campaign" },
8204
+ { kind: "word", value: "preorder" },
8205
+ { kind: "phrase", value: "pre-order" },
8206
+ { kind: "substring", value: "waitlist" },
8207
+ { kind: "word", value: "drop" }
7948
8208
  ],
7949
8209
  tokenRecipes: {
7950
8210
  palette: "high-contrast",
@@ -7975,15 +8235,6 @@ var curatedSiteStyles = [
7975
8235
  name: "South West Twerk School",
7976
8236
  description: "Energetic, editorial, and high-contrast for a branded dance school presence.",
7977
8237
  generationBrief: "Use confident rhythm, bold burgundy-and-gold accents, large editorial intro copy, strong booking routes, and dark feature sections where proof or forms need emphasis.",
7978
- selectionKeywords: [
7979
- "dance",
7980
- "classes",
7981
- "workshop",
7982
- "school",
7983
- "movement",
7984
- "performance",
7985
- "community"
7986
- ],
7987
8238
  tokenRecipes: {
7988
8239
  palette: "brand-led",
7989
8240
  contrast: "maximum",
@@ -8226,6 +8477,148 @@ var modernMinimalTheme = {
8226
8477
  }
8227
8478
  };
8228
8479
 
8480
+ // ../theme-core/src/palette/generateShades.ts
8481
+ function generateShades(hexColor, name) {
8482
+ const shadeSteps = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950];
8483
+ const base = featuresFromHex(hexColor);
8484
+ const hue = base.okH;
8485
+ const baseChroma = base.okC;
8486
+ const toneMap = {
8487
+ 50: 0.975,
8488
+ 100: 0.945,
8489
+ 200: 0.89,
8490
+ 300: 0.82,
8491
+ 400: 0.74,
8492
+ 500: 0.66,
8493
+ 600: 0.58,
8494
+ 700: 0.49,
8495
+ 800: 0.4,
8496
+ 900: 0.28,
8497
+ 950: 0.16
8498
+ };
8499
+ const shadeDefs = shadeSteps.map((step, idx) => {
8500
+ const t = idx / (shadeSteps.length - 1);
8501
+ const L = toneMap[step];
8502
+ const chromaFactor = 0.06 + 0.94 * Math.sin(Math.PI * t);
8503
+ const C = baseChroma * chromaFactor;
8504
+ return {
8505
+ name: `${name}-${step}`,
8506
+ hex: oklchToHexGamut(L, C, hue)
8507
+ };
8508
+ });
8509
+ shadeDefs.push({ name, hex: hexColor });
8510
+ return shadeDefs;
8511
+ }
8512
+
8513
+ // ../theme-core/src/palette/neutralScale.ts
8514
+ function generateNeutralScale({
8515
+ background,
8516
+ steps = 11,
8517
+ warm = false
8518
+ }) {
8519
+ const isDark = background === "#000000" || background.startsWith("#0") || background.startsWith("#1");
8520
+ const shadeNames = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950];
8521
+ const count = Math.min(steps, shadeNames.length);
8522
+ const scale = [];
8523
+ for (let i = 0; i < count; i++) {
8524
+ const t = i / (count - 1);
8525
+ const tone = isDark ? mix(0.06, 0.92, t) : mix(0.98, 0.1, t);
8526
+ const hex = oklchToHexGamut(tone, 0.02, warm ? 85 : 250);
8527
+ const name = `neutral-${shadeNames[i]}`;
8528
+ scale.push({ name, hex });
8529
+ }
8530
+ return scale;
8531
+ }
8532
+ function mix(a, b, t) {
8533
+ return a + (b - a) * Math.max(0, Math.min(1, t));
8534
+ }
8535
+
8536
+ // ../theme-core/src/palette/utils/textColor.ts
8537
+ function pickBlackOrWhiteTextColor(background, minContrast = 4.5) {
8538
+ const { r: r2, g, b } = parseColorToRgb(background);
8539
+ const luminance = relativeLuminance(r2, g, b);
8540
+ const blackContrast = (luminance + 0.05) / 0.05;
8541
+ const whiteContrast = 1.05 / (luminance + 0.05);
8542
+ if (blackContrast >= minContrast && whiteContrast < minContrast) {
8543
+ return "#000000";
8544
+ }
8545
+ if (whiteContrast >= minContrast && blackContrast < minContrast) {
8546
+ return "#FFFFFF";
8547
+ }
8548
+ return blackContrast >= whiteContrast ? "#000000" : "#FFFFFF";
8549
+ }
8550
+ function getTextColorForBackground(background) {
8551
+ return pickBlackOrWhiteTextColor(background);
8552
+ }
8553
+ function parseColorToRgb(input) {
8554
+ const trimmed = input.trim();
8555
+ if (trimmed.startsWith("#")) {
8556
+ return hexToRgb(trimmed);
8557
+ }
8558
+ const rgbMatch = trimmed.match(
8559
+ /^rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})(?:\s*,\s*(?:0|1|0?\.\d+))?\s*\)$/i
8560
+ );
8561
+ if (rgbMatch?.[1] && rgbMatch[2] && rgbMatch[3]) {
8562
+ return {
8563
+ r: clamp255(Number(rgbMatch[1])),
8564
+ g: clamp255(Number(rgbMatch[2])),
8565
+ b: clamp255(Number(rgbMatch[3]))
8566
+ };
8567
+ }
8568
+ throw new Error("Unsupported color format");
8569
+ }
8570
+ function clamp255(value) {
8571
+ if (Number.isNaN(value)) return 0;
8572
+ return Math.max(0, Math.min(255, value));
8573
+ }
8574
+
8575
+ // ../theme-core/src/palette/expandPalette.ts
8576
+ function colorsToMap(palette) {
8577
+ const map = {};
8578
+ for (const c of palette.colors) {
8579
+ map[c.name] = c.hex;
8580
+ }
8581
+ return map;
8582
+ }
8583
+ function isBackgroundDark(hex) {
8584
+ try {
8585
+ return featuresFromHex(hex).Y < 0.5;
8586
+ } catch {
8587
+ return false;
8588
+ }
8589
+ }
8590
+ function expandPalette(palette) {
8591
+ const base = colorsToMap(palette);
8592
+ const expanded = { ...base };
8593
+ const background = base.background || base.surface || "#ffffff";
8594
+ const neutral2 = generateNeutralScale({ background, steps: 11, warm: false });
8595
+ neutral2.forEach((n) => {
8596
+ expanded[n.name] = n.hex;
8597
+ });
8598
+ for (const [name, hex] of Object.entries(base)) {
8599
+ if (hex) {
8600
+ const shades = generateShades(hex, name);
8601
+ shades.forEach((shade) => {
8602
+ expanded[shade.name] = shade.hex;
8603
+ });
8604
+ }
8605
+ }
8606
+ if (base.text) expanded.body = base.text;
8607
+ if (base.danger && !base.destructive) {
8608
+ expanded.destructive = base.danger;
8609
+ }
8610
+ const isDark = base.background ? isBackgroundDark(base.background) : false;
8611
+ const isDarkMode = palette.meta?.mode === "dark" || isDark;
8612
+ expanded.mutedText = isDarkMode ? expanded["neutral-600"] ?? "#666" : expanded["neutral-500"] ?? "#888";
8613
+ for (const [token, hex] of Object.entries({ ...expanded })) {
8614
+ if (!hex || !isOnColorBackgroundCandidateToken(token)) continue;
8615
+ const onToken = onColorTokenName(token);
8616
+ if (expanded[onToken]) continue;
8617
+ expanded[onToken] = getTextColorForBackground(hex);
8618
+ }
8619
+ return expanded;
8620
+ }
8621
+
8229
8622
  // ../theme-core/src/site-styles/designState.ts
8230
8623
  import { z as z24 } from "zod";
8231
8624
 
@@ -8394,25 +8787,19 @@ var defaultDesignRuntimeRules = defineDesignRuntimeRules({
8394
8787
  "muted-band": {
8395
8788
  background: {
8396
8789
  type: "color",
8397
- color: "muted",
8398
- textColor: "text",
8399
- headingColor: "text"
8790
+ color: "muted"
8400
8791
  }
8401
8792
  },
8402
8793
  "accent-band": {
8403
8794
  background: {
8404
8795
  type: "color",
8405
- color: "primary",
8406
- textColor: "primaryForeground",
8407
- headingColor: "primaryForeground"
8796
+ color: "primary"
8408
8797
  }
8409
8798
  },
8410
8799
  "brand-depth-band": {
8411
8800
  background: {
8412
8801
  type: "color",
8413
- color: "primary-800",
8414
- textColor: "primaryForeground",
8415
- headingColor: "primaryForeground"
8802
+ color: "primary-800"
8416
8803
  }
8417
8804
  },
8418
8805
  "hero-image": {
@@ -14634,6 +15021,16 @@ var jsonArrayTransform = {
14634
15021
  return "";
14635
15022
  }
14636
15023
  };
15024
+ var csvTransform = {
15025
+ id: "value.csv",
15026
+ kind: "formatter",
15027
+ summary: "Normalize a string or array of strings into a comma-separated list",
15028
+ run: (value) => {
15029
+ const rawValues = Array.isArray(value) ? value : typeof value === "string" ? value.split(",") : [];
15030
+ const normalized = rawValues.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean);
15031
+ return normalized.length > 0 ? Array.from(new Set(normalized)).join(",") : "";
15032
+ }
15033
+ };
14637
15034
  var marqueeLoopOptionsSchema = z33.object({
14638
15035
  minItems: z33.number().int().min(1).default(10)
14639
15036
  });
@@ -14659,6 +15056,7 @@ var formattingTransforms = [
14659
15056
  dateFormatShort,
14660
15057
  arrayLengthTransform,
14661
15058
  jsonArrayTransform,
15059
+ csvTransform,
14662
15060
  marqueeLoopTransform
14663
15061
  ];
14664
15062
 
@@ -15142,117 +15540,6 @@ var uiTransforms = [
15142
15540
 
15143
15541
  // ../blocks/src/system/transforms/registry/layout.ts
15144
15542
  import { z as z35 } from "zod";
15145
-
15146
- // ../theme-core/src/palette/utils/colorConversion.ts
15147
- var clamp01 = (x) => Math.max(0, Math.min(1, x));
15148
- var mod = (a, n) => (a % n + n) % n;
15149
- var deg = (x) => mod(x, 360);
15150
- function hexToRgb(hex) {
15151
- const h = hex.replace(/^#/, "");
15152
- const m = h.length === 3 ? h.split("").map((c) => c + c).join("") : h;
15153
- if (m.length !== 6) throw new Error("Bad hex");
15154
- const int = parseInt(m, 16);
15155
- return { r: int >> 16 & 255, g: int >> 8 & 255, b: int & 255 };
15156
- }
15157
- function rgbToHex(r2, g, b) {
15158
- const to = (n) => Math.round(n).toString(16).padStart(2, "0");
15159
- return `#${to(r2)}${to(g)}${to(b)}`;
15160
- }
15161
- function srgbToLinear(u) {
15162
- const x = u / 255;
15163
- return x <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);
15164
- }
15165
- function linearToSrgb(x) {
15166
- const y = x <= 31308e-7 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055;
15167
- return clamp01(y) * 255;
15168
- }
15169
- function rgbToHsl(r2, g, b) {
15170
- const R = r2 / 255, G = g / 255, B = b / 255;
15171
- const max = Math.max(R, G, B), min = Math.min(R, G, B);
15172
- const d = max - min;
15173
- let h = 0;
15174
- if (d !== 0) {
15175
- switch (max) {
15176
- case R:
15177
- h = (G - B) / d + (G < B ? 6 : 0);
15178
- break;
15179
- case G:
15180
- h = (B - R) / d + 2;
15181
- break;
15182
- case B:
15183
- h = (R - G) / d + 4;
15184
- break;
15185
- }
15186
- h *= 60;
15187
- }
15188
- const l = (max + min) / 2;
15189
- const s = d === 0 ? 0 : d / (1 - Math.abs(2 * l - 1));
15190
- return { h, s, l };
15191
- }
15192
- function srgbToOklab(r2, g, b) {
15193
- const R = srgbToLinear(r2), G = srgbToLinear(g), B = srgbToLinear(b);
15194
- const l = 0.4122214708 * R + 0.5363325363 * G + 0.0514459929 * B;
15195
- const m = 0.2119034982 * R + 0.6806995451 * G + 0.1073969566 * B;
15196
- const s = 0.0883024619 * R + 0.2817188376 * G + 0.6299787005 * B;
15197
- const l_ = Math.cbrt(l), m_ = Math.cbrt(m), s_ = Math.cbrt(s);
15198
- const L = 0.2104542553 * l_ + 0.793617785 * m_ - 0.0040720468 * s_;
15199
- const a = 1.9779984951 * l_ - 2.428592205 * m_ + 0.4505937099 * s_;
15200
- const b2 = 0.0259040371 * l_ + 0.7827717662 * m_ - 0.808675766 * s_;
15201
- return { L, a, b: b2 };
15202
- }
15203
- function oklabToSrgb(L, a, b) {
15204
- const l_ = Math.pow(L + 0.3963377774 * a + 0.2158037573 * b, 3);
15205
- const m_ = Math.pow(L - 0.1055613458 * a - 0.0638541728 * b, 3);
15206
- const s_ = Math.pow(L - 0.0894841775 * a - 1.291485548 * b, 3);
15207
- const R = 4.0767416621 * l_ - 3.3077115913 * m_ + 0.2309699292 * s_;
15208
- const G = -1.2684380046 * l_ + 2.6097574011 * m_ - 0.3413193965 * s_;
15209
- const B = -0.0041960863 * l_ - 0.7034186147 * m_ + 1.707614701 * s_;
15210
- return { r: linearToSrgb(R), g: linearToSrgb(G), b: linearToSrgb(B) };
15211
- }
15212
- function oklabToOklch(L, a, b) {
15213
- const C = Math.sqrt(a * a + b * b);
15214
- const h = C < 1e-7 ? 0 : deg(Math.atan2(b, a) * 180 / Math.PI);
15215
- return { L, C, h };
15216
- }
15217
- function oklchToOklab(L, C, h) {
15218
- const hr = h * Math.PI / 180;
15219
- const a = C * Math.cos(hr);
15220
- const b = C * Math.sin(hr);
15221
- return { L, a, b };
15222
- }
15223
- function inSRGB(r2, g, b) {
15224
- return r2 >= 0 && r2 <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255;
15225
- }
15226
- function oklchToHexGamut(L, C, h) {
15227
- let lo = 0, hi = C, best = 0;
15228
- for (let i = 0; i < 18; i++) {
15229
- const mid = (lo + hi) / 2;
15230
- const { a: a2, b: b2 } = oklchToOklab(L, mid, h);
15231
- const { r: r3, g: g2, b: bb2 } = oklabToSrgb(L, a2, b2);
15232
- if (inSRGB(r3, g2, bb2)) {
15233
- best = mid;
15234
- lo = mid;
15235
- } else {
15236
- hi = mid;
15237
- }
15238
- }
15239
- const { a, b } = oklchToOklab(L, best, h);
15240
- const { r: r2, g, b: bb } = oklabToSrgb(L, a, b);
15241
- return rgbToHex(r2, g, bb);
15242
- }
15243
- function featuresFromHex(hex) {
15244
- const { r: r2, g, b } = hexToRgb(hex);
15245
- const { h, s, l } = rgbToHsl(r2, g, b);
15246
- const { L, a, b: b2 } = srgbToOklab(r2, g, b);
15247
- const { L: okL, C: okC, h: okH } = oklabToOklch(L, a, b2);
15248
- const max = Math.max(r2, g, b);
15249
- const v = max / 255;
15250
- const Y = 0.2126 * srgbToLinear(r2) + 0.7152 * srgbToLinear(g) + 0.0722 * srgbToLinear(b);
15251
- const chroma = s;
15252
- return { r: r2, g, b, h, s, l, v, Y, chroma, okL, okC, okH, hex };
15253
- }
15254
-
15255
- // ../blocks/src/system/transforms/registry/layout.ts
15256
15543
  var joinClasses4 = (parts) => parts.filter(
15257
15544
  (part) => typeof part === "string" && part.trim().length > 0
15258
15545
  ).join(" ").replace(/\s+/g, " ").trim();
@@ -20201,51 +20488,6 @@ function resolveEventCta(event, buttonText) {
20201
20488
  return { label, href: event.path, hidden: false };
20202
20489
  }
20203
20490
 
20204
- // ../theme-core/src/palette/utils/contrast.ts
20205
- function relativeLuminance(r2, g, b) {
20206
- const R = srgbToLinear(r2), G = srgbToLinear(g), B = srgbToLinear(b);
20207
- return 0.2126 * R + 0.7152 * G + 0.0722 * B;
20208
- }
20209
-
20210
- // ../theme-core/src/palette/utils/textColor.ts
20211
- function pickBlackOrWhiteTextColor(background, minContrast = 4.5) {
20212
- const { r: r2, g, b } = parseColorToRgb(background);
20213
- const luminance = relativeLuminance(r2, g, b);
20214
- const blackContrast = (luminance + 0.05) / 0.05;
20215
- const whiteContrast = 1.05 / (luminance + 0.05);
20216
- if (blackContrast >= minContrast && whiteContrast < minContrast) {
20217
- return "#000000";
20218
- }
20219
- if (whiteContrast >= minContrast && blackContrast < minContrast) {
20220
- return "#FFFFFF";
20221
- }
20222
- return blackContrast >= whiteContrast ? "#000000" : "#FFFFFF";
20223
- }
20224
- function getTextColorForBackground(background) {
20225
- return pickBlackOrWhiteTextColor(background);
20226
- }
20227
- function parseColorToRgb(input) {
20228
- const trimmed = input.trim();
20229
- if (trimmed.startsWith("#")) {
20230
- return hexToRgb(trimmed);
20231
- }
20232
- const rgbMatch = trimmed.match(
20233
- /^rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})(?:\s*,\s*(?:0|1|0?\.\d+))?\s*\)$/i
20234
- );
20235
- if (rgbMatch?.[1] && rgbMatch[2] && rgbMatch[3]) {
20236
- return {
20237
- r: clamp255(Number(rgbMatch[1])),
20238
- g: clamp255(Number(rgbMatch[2])),
20239
- b: clamp255(Number(rgbMatch[3]))
20240
- };
20241
- }
20242
- throw new Error("Unsupported color format");
20243
- }
20244
- function clamp255(value) {
20245
- if (Number.isNaN(value)) return 0;
20246
- return Math.max(0, Math.min(255, value));
20247
- }
20248
-
20249
20491
  // ../../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
20250
20492
  function r(e) {
20251
20493
  var t, f, n = "";
@@ -22175,7 +22417,12 @@ var eventListingBlockDefinition = {
22175
22417
  detailLevel: "listing",
22176
22418
  kind: { $bind: { from: "content.kind" } },
22177
22419
  eventSurface: { $bind: { from: "content.eventSurface" } },
22178
- eventPresets: { $bind: { from: "content.filterEventPresets" } },
22420
+ eventPresets: {
22421
+ $bind: {
22422
+ from: "content.filterEventPresets",
22423
+ transforms: [{ id: "value.csv" }]
22424
+ }
22425
+ },
22179
22426
  scheduleScope: { $bind: { from: "content.scheduleScope" } }
22180
22427
  },
22181
22428
  mode: "server"
@@ -22960,7 +23207,12 @@ var eventCalendarBlockDefinition = {
22960
23207
  // Pass filter params if configured
22961
23208
  kind: { $bind: { from: "content.kind" } },
22962
23209
  eventSurface: { $bind: { from: "content.eventSurface" } },
22963
- eventPresets: { $bind: { from: "content.filterEventPresets" } },
23210
+ eventPresets: {
23211
+ $bind: {
23212
+ from: "content.filterEventPresets",
23213
+ transforms: [{ id: "value.csv" }]
23214
+ }
23215
+ },
22964
23216
  scheduleScope: { $bind: { from: "content.scheduleScope" } },
22965
23217
  categoryIds: { $bind: { from: "content.filterCategoryIds" } },
22966
23218
  staffMemberId: { $bind: { from: "content.filterStaffMemberId" } },
@@ -33422,119 +33674,6 @@ function renderBlock(manifest, content, options = {}) {
33422
33674
  );
33423
33675
  }
33424
33676
 
33425
- // ../theme-core/src/palette/generateShades.ts
33426
- function generateShades(hexColor, name) {
33427
- const shadeSteps = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950];
33428
- const base = featuresFromHex(hexColor);
33429
- const hue = base.okH;
33430
- const baseChroma = base.okC;
33431
- const toneMap = {
33432
- 50: 0.975,
33433
- 100: 0.945,
33434
- 200: 0.89,
33435
- 300: 0.82,
33436
- 400: 0.74,
33437
- 500: 0.66,
33438
- 600: 0.58,
33439
- 700: 0.49,
33440
- 800: 0.4,
33441
- 900: 0.28,
33442
- 950: 0.16
33443
- };
33444
- const shadeDefs = shadeSteps.map((step, idx) => {
33445
- const t = idx / (shadeSteps.length - 1);
33446
- const L = toneMap[step];
33447
- const chromaFactor = 0.06 + 0.94 * Math.sin(Math.PI * t);
33448
- const C = baseChroma * chromaFactor;
33449
- return {
33450
- name: `${name}-${step}`,
33451
- hex: oklchToHexGamut(L, C, hue)
33452
- };
33453
- });
33454
- shadeDefs.push({ name, hex: hexColor });
33455
- return shadeDefs;
33456
- }
33457
-
33458
- // ../theme-core/src/palette/neutralScale.ts
33459
- function generateNeutralScale({
33460
- background,
33461
- steps = 11,
33462
- warm = false
33463
- }) {
33464
- const isDark = background === "#000000" || background.startsWith("#0") || background.startsWith("#1");
33465
- const shadeNames = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950];
33466
- const count = Math.min(steps, shadeNames.length);
33467
- const scale = [];
33468
- for (let i = 0; i < count; i++) {
33469
- const t = i / (count - 1);
33470
- const tone = isDark ? mix(0.06, 0.92, t) : mix(0.98, 0.1, t);
33471
- const hex = oklchToHexGamut(tone, 0.02, warm ? 85 : 250);
33472
- const name = `neutral-${shadeNames[i]}`;
33473
- scale.push({ name, hex });
33474
- }
33475
- return scale;
33476
- }
33477
- function mix(a, b, t) {
33478
- return a + (b - a) * Math.max(0, Math.min(1, t));
33479
- }
33480
-
33481
- // ../theme-core/src/palette/expandPalette.ts
33482
- function colorsToMap(palette) {
33483
- const map = {};
33484
- for (const c of palette.colors) {
33485
- map[c.name] = c.hex;
33486
- }
33487
- return map;
33488
- }
33489
- function isBackgroundDark(hex) {
33490
- try {
33491
- return featuresFromHex(hex).Y < 0.5;
33492
- } catch {
33493
- return false;
33494
- }
33495
- }
33496
- function expandPalette(palette) {
33497
- const base = colorsToMap(palette);
33498
- const expanded = { ...base };
33499
- const background = base.background || base.surface || "#ffffff";
33500
- const neutral2 = generateNeutralScale({ background, steps: 11, warm: false });
33501
- neutral2.forEach((n) => {
33502
- expanded[n.name] = n.hex;
33503
- });
33504
- for (const [name, hex] of Object.entries(base)) {
33505
- if (hex) {
33506
- const shades = generateShades(hex, name);
33507
- shades.forEach((shade) => {
33508
- expanded[shade.name] = shade.hex;
33509
- });
33510
- }
33511
- }
33512
- if (base.text) expanded.body = base.text;
33513
- if (base.danger && !base.destructive) {
33514
- expanded.destructive = base.danger;
33515
- }
33516
- const isDark = base.background ? isBackgroundDark(base.background) : false;
33517
- const isDarkMode = palette.meta?.mode === "dark" || isDark;
33518
- expanded.mutedText = isDarkMode ? expanded["neutral-600"] ?? "#666" : expanded["neutral-500"] ?? "#888";
33519
- const onRoles = [
33520
- { role: "primary", on: "onPrimary" },
33521
- { role: "secondary", on: "onSecondary" },
33522
- { role: "accent", on: "onAccent" },
33523
- { role: "success", on: "onSuccess" },
33524
- { role: "warning", on: "onWarning" },
33525
- { role: "destructive", on: "onDestructive" },
33526
- { role: "info", on: "onInfo" },
33527
- { role: "surface", on: "onSurface" }
33528
- ];
33529
- for (const { role, on } of onRoles) {
33530
- const bg = base[role];
33531
- if (!bg) continue;
33532
- if (expanded[on]) continue;
33533
- expanded[on] = getTextColorForBackground(bg);
33534
- }
33535
- return expanded;
33536
- }
33537
-
33538
33677
  // ../theme-core/src/runtime/fontFamily.ts
33539
33678
  var GENERIC_CSS_FAMILIES = [
33540
33679
  "serif",
@@ -49016,6 +49155,17 @@ function normalizeLoaderParams(endpoint, params, context) {
49016
49155
  // ../blocks/src/primitives/content/primitives.tsx
49017
49156
  var RichText2 = RichText;
49018
49157
 
49158
+ // ../api/src/apiEndpointTypes.ts
49159
+ function blockedDemoMutationPolicy(classification, publicMessage) {
49160
+ if (publicMessage.trim() === "") {
49161
+ throw new Error(`Demo mutation policy ${classification} requires publicMessage.`);
49162
+ }
49163
+ return {
49164
+ classification,
49165
+ publicMessage
49166
+ };
49167
+ }
49168
+
49019
49169
  // ../api/src/cache-tags.ts
49020
49170
  var TAG_TEMPLATES = {
49021
49171
  siteCollection: "riverbank:site",
@@ -49046,6 +49196,18 @@ var TAG_TEMPLATES = {
49046
49196
  };
49047
49197
 
49048
49198
  // ../api/src/endpoints.ts
49199
+ var DEMO_MUTATION_BLOCKED_HIDDEN = blockedDemoMutationPolicy(
49200
+ "blocked-hidden",
49201
+ "This action is not available in demo sites."
49202
+ );
49203
+ var DEMO_MUTATION_BLOCKED_DISABLED = blockedDemoMutationPolicy(
49204
+ "blocked-disabled",
49205
+ "This setting is disabled in demo sites."
49206
+ );
49207
+ var DEMO_MUTATION_INTERNAL_ONLY = blockedDemoMutationPolicy(
49208
+ "internal-only",
49209
+ "This internal operation is not available in demo sites."
49210
+ );
49049
49211
  var ENDPOINT_DEFINITIONS = {
49050
49212
  // AI endpoints - no cache due to dynamic nature
49051
49213
  aiContentUpdateChat: {
@@ -49162,7 +49324,8 @@ var ENDPOINT_DEFINITIONS = {
49162
49324
  path: "/sites/{siteId}/ai/generate",
49163
49325
  method: "POST",
49164
49326
  auth: "user",
49165
- responseKind: "json"
49327
+ responseKind: "json",
49328
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
49166
49329
  },
49167
49330
  getOnboardingPreviewStatus: {
49168
49331
  path: "/public/sites/{siteId}/onboarding/preview-status",
@@ -49183,7 +49346,8 @@ var ENDPOINT_DEFINITIONS = {
49183
49346
  method: "POST",
49184
49347
  auth: "user",
49185
49348
  errors: [],
49186
- responseKind: "json"
49349
+ responseKind: "json",
49350
+ demoMutation: DEMO_MUTATION_BLOCKED_DISABLED
49187
49351
  },
49188
49352
  goLiveSite: {
49189
49353
  path: "/sites/{siteId}/launch/go-live",
@@ -49252,20 +49416,23 @@ var ENDPOINT_DEFINITIONS = {
49252
49416
  path: "/sites/{siteId}/ai/site-wizard/goals",
49253
49417
  method: "POST",
49254
49418
  auth: "user",
49255
- responseKind: "json"
49419
+ responseKind: "json",
49420
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
49256
49421
  },
49257
49422
  aiSiteWizardIntakeTriage: {
49258
49423
  path: "/sites/{siteId}/ai/site-wizard/intake-triage",
49259
49424
  method: "POST",
49260
49425
  auth: "user",
49261
- responseKind: "json"
49426
+ responseKind: "json",
49427
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
49262
49428
  },
49263
49429
  aiSiteWizardTelemetry: {
49264
49430
  path: "/sites/{siteId}/ai/site-wizard/telemetry",
49265
49431
  method: "POST",
49266
49432
  auth: "user",
49267
49433
  errors: [],
49268
- responseKind: "json"
49434
+ responseKind: "json",
49435
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
49269
49436
  },
49270
49437
  // Admin SEO
49271
49438
  listGscPropertiesAdmin: {
@@ -49472,7 +49639,7 @@ var ENDPOINT_DEFINITIONS = {
49472
49639
  responseKind: "json",
49473
49640
  errors: ["resource:not_found", "server:internal_error"]
49474
49641
  },
49475
- // Ops (event hosts/admins)
49642
+ // Ops (staff event operators/admins)
49476
49643
  opsListUpcomingEventOccurrences: {
49477
49644
  path: "/ops/sites/{siteId}/events",
49478
49645
  method: "GET",
@@ -49490,6 +49657,7 @@ var ENDPOINT_DEFINITIONS = {
49490
49657
  method: "POST",
49491
49658
  auth: "user",
49492
49659
  responseKind: "json",
49660
+ demoMutation: DEMO_MUTATION_INTERNAL_ONLY,
49493
49661
  errors: [
49494
49662
  "validation:invalid_input",
49495
49663
  "auth:forbidden",
@@ -49502,6 +49670,7 @@ var ENDPOINT_DEFINITIONS = {
49502
49670
  method: "POST",
49503
49671
  auth: "user",
49504
49672
  responseKind: "json",
49673
+ demoMutation: DEMO_MUTATION_INTERNAL_ONLY,
49505
49674
  errors: [
49506
49675
  "validation:invalid_input",
49507
49676
  "auth:forbidden",
@@ -49520,6 +49689,7 @@ var ENDPOINT_DEFINITIONS = {
49520
49689
  method: "POST",
49521
49690
  auth: "user",
49522
49691
  responseKind: "json",
49692
+ demoMutation: DEMO_MUTATION_INTERNAL_ONLY,
49523
49693
  errors: [
49524
49694
  "validation:invalid_input",
49525
49695
  "auth:forbidden",
@@ -49553,6 +49723,7 @@ var ENDPOINT_DEFINITIONS = {
49553
49723
  method: "POST",
49554
49724
  auth: "user",
49555
49725
  responseKind: "json",
49726
+ demoMutation: DEMO_MUTATION_INTERNAL_ONLY,
49556
49727
  errors: [
49557
49728
  "validation:invalid_input",
49558
49729
  "auth:forbidden",
@@ -49581,7 +49752,8 @@ var ENDPOINT_DEFINITIONS = {
49581
49752
  method: "POST",
49582
49753
  tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteEmailSettings],
49583
49754
  auth: "user",
49584
- responseKind: "json"
49755
+ responseKind: "json",
49756
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
49585
49757
  },
49586
49758
  previewEmailTemplate: {
49587
49759
  path: "/sites/{siteId}/settings/emails/preview",
@@ -49632,14 +49804,16 @@ var ENDPOINT_DEFINITIONS = {
49632
49804
  method: "POST",
49633
49805
  tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter],
49634
49806
  auth: "user",
49635
- responseKind: "json"
49807
+ responseKind: "json",
49808
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
49636
49809
  },
49637
49810
  createNewsletterSubscribersImportUploadUrl: {
49638
49811
  path: "/sites/{siteId}/newsletter/subscribers/import-url",
49639
49812
  method: "POST",
49640
49813
  tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter],
49641
49814
  auth: "user",
49642
- responseKind: "json"
49815
+ responseKind: "json",
49816
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
49643
49817
  },
49644
49818
  exportNewsletterSubscribersCsv: {
49645
49819
  path: "/sites/{siteId}/newsletter/subscribers/export.csv",
@@ -49836,14 +50010,16 @@ var ENDPOINT_DEFINITIONS = {
49836
50010
  method: "POST",
49837
50011
  tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter],
49838
50012
  auth: "user",
49839
- responseKind: "json"
50013
+ responseKind: "json",
50014
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
49840
50015
  },
49841
50016
  testSendNewsletterCampaign: {
49842
50017
  path: "/sites/{siteId}/newsletter/campaigns/{campaignId}/test-send",
49843
50018
  method: "POST",
49844
50019
  tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter],
49845
50020
  auth: "user",
49846
- responseKind: "json"
50021
+ responseKind: "json",
50022
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
49847
50023
  },
49848
50024
  listNewsletterSendJobs: {
49849
50025
  path: "/sites/{siteId}/newsletter/jobs",
@@ -50531,7 +50707,8 @@ var ENDPOINT_DEFINITIONS = {
50531
50707
  method: "DELETE",
50532
50708
  tags: ["site", "site-{siteId}"],
50533
50709
  auth: "user",
50534
- responseKind: "json"
50710
+ responseKind: "json",
50711
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
50535
50712
  },
50536
50713
  listSiteMembers: {
50537
50714
  path: "/sites/{siteId}/members",
@@ -50987,7 +51164,8 @@ var ENDPOINT_DEFINITIONS = {
50987
51164
  method: "POST",
50988
51165
  tags: ["site-{siteId}", "content-{siteId}-{type}"],
50989
51166
  auth: "user",
50990
- responseKind: "json"
51167
+ responseKind: "json",
51168
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
50991
51169
  },
50992
51170
  updateSiteGeneralSettings: {
50993
51171
  path: "/sites/{siteId}/settings/general",
@@ -53226,6 +53404,7 @@ var ENDPOINT_DEFINITIONS = {
53226
53404
  method: "POST",
53227
53405
  tags: ["site-{siteId}"],
53228
53406
  auth: "user",
53407
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN,
53229
53408
  errors: [
53230
53409
  "validation:invalid_input",
53231
53410
  "auth:forbidden",
@@ -53240,6 +53419,7 @@ var ENDPOINT_DEFINITIONS = {
53240
53419
  method: "POST",
53241
53420
  tags: ["site-{siteId}"],
53242
53421
  auth: "user",
53422
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN,
53243
53423
  errors: [
53244
53424
  "validation:invalid_input",
53245
53425
  "auth:forbidden",
@@ -53549,6 +53729,7 @@ var ENDPOINT_DEFINITIONS = {
53549
53729
  tags: ["site-{siteId}", "passes-{siteId}"],
53550
53730
  auth: "user",
53551
53731
  responseKind: "json",
53732
+ demoMutation: DEMO_MUTATION_BLOCKED_DISABLED,
53552
53733
  errors: ["validation:invalid_input", "server:internal_error"]
53553
53734
  },
53554
53735
  getBookingPass: {
@@ -53564,6 +53745,7 @@ var ENDPOINT_DEFINITIONS = {
53564
53745
  tags: ["site-{siteId}", "passes-{siteId}"],
53565
53746
  auth: "user",
53566
53747
  responseKind: "json",
53748
+ demoMutation: DEMO_MUTATION_BLOCKED_DISABLED,
53567
53749
  errors: [
53568
53750
  "validation:invalid_input",
53569
53751
  "resource:not_found",
@@ -53576,6 +53758,7 @@ var ENDPOINT_DEFINITIONS = {
53576
53758
  tags: ["site-{siteId}", "passes-{siteId}"],
53577
53759
  auth: "user",
53578
53760
  responseKind: "json",
53761
+ demoMutation: DEMO_MUTATION_BLOCKED_DISABLED,
53579
53762
  errors: [
53580
53763
  "validation:invalid_input",
53581
53764
  "resource:not_found",
@@ -53631,6 +53814,7 @@ var ENDPOINT_DEFINITIONS = {
53631
53814
  tags: ["site-{siteId}", "memberships-{siteId}"],
53632
53815
  auth: "user",
53633
53816
  responseKind: "json",
53817
+ demoMutation: DEMO_MUTATION_BLOCKED_DISABLED,
53634
53818
  errors: ["validation:invalid_input", "server:internal_error"]
53635
53819
  },
53636
53820
  getBookingMembership: {
@@ -53646,6 +53830,7 @@ var ENDPOINT_DEFINITIONS = {
53646
53830
  tags: ["site-{siteId}", "memberships-{siteId}"],
53647
53831
  auth: "user",
53648
53832
  responseKind: "json",
53833
+ demoMutation: DEMO_MUTATION_BLOCKED_DISABLED,
53649
53834
  errors: [
53650
53835
  "validation:invalid_input",
53651
53836
  "resource:not_found",
@@ -53658,6 +53843,7 @@ var ENDPOINT_DEFINITIONS = {
53658
53843
  tags: ["site-{siteId}", "memberships-{siteId}"],
53659
53844
  auth: "user",
53660
53845
  responseKind: "json",
53846
+ demoMutation: DEMO_MUTATION_BLOCKED_DISABLED,
53661
53847
  errors: [
53662
53848
  "validation:invalid_input",
53663
53849
  "resource:not_found",
@@ -53874,6 +54060,7 @@ var ENDPOINT_DEFINITIONS = {
53874
54060
  tags: ["site-{siteId}", "customers-{siteId}"],
53875
54061
  auth: "user",
53876
54062
  responseKind: "json",
54063
+ demoMutation: DEMO_MUTATION_BLOCKED_DISABLED,
53877
54064
  errors: [
53878
54065
  "validation:invalid_input",
53879
54066
  "auth:forbidden",
@@ -55251,8 +55438,7 @@ var dashboardNavVisibilityBaseSchema = z66.object({
55251
55438
  var dashboardNavVisibilityRolesSchema = z66.object({
55252
55439
  administrator: dashboardNavVisibilityBaseSchema.optional(),
55253
55440
  editor: dashboardNavVisibilityBaseSchema.optional(),
55254
- team_member: dashboardNavVisibilityBaseSchema.optional(),
55255
- event_host: dashboardNavVisibilityBaseSchema.optional()
55441
+ team_member: dashboardNavVisibilityBaseSchema.optional()
55256
55442
  }).strip().optional();
55257
55443
  var dashboardNavVisibilitySchema = dashboardNavVisibilityBaseSchema.extend({
55258
55444
  roles: dashboardNavVisibilityRolesSchema
@@ -55773,6 +55959,21 @@ var appointmentSetupServiceDraftSchema = z68.object({
55773
55959
  timezone: z68.string().trim().min(1).nullable(),
55774
55960
  payment: appointmentSetupPaymentDraftSchema,
55775
55961
  assignment: appointmentSetupServiceAssignmentDraftSchema
55962
+ }).superRefine((service, ctx) => {
55963
+ if (service.payment.priceType === "paid" && (service.priceAmount === null || service.priceAmount <= 0)) {
55964
+ ctx.addIssue({
55965
+ code: "custom",
55966
+ path: ["priceAmount"],
55967
+ message: "Paid appointment services need a positive price."
55968
+ });
55969
+ }
55970
+ if (service.payment.priceType === "free" && service.priceAmount !== null && service.priceAmount > 0) {
55971
+ ctx.addIssue({
55972
+ code: "custom",
55973
+ path: ["priceAmount"],
55974
+ message: "Free appointment services cannot carry a positive price."
55975
+ });
55976
+ }
55776
55977
  });
55777
55978
  var appointmentSetupPractitionerDraftSchema = z68.object({
55778
55979
  ref: appointmentSetupRefSchema,