@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
@@ -1,6 +1,17 @@
1
1
  // src/config/validation.ts
2
2
  import { z as z68 } from "zod";
3
3
 
4
+ // ../api/src/apiEndpointTypes.ts
5
+ function blockedDemoMutationPolicy(classification, publicMessage) {
6
+ if (publicMessage.trim() === "") {
7
+ throw new Error(`Demo mutation policy ${classification} requires publicMessage.`);
8
+ }
9
+ return {
10
+ classification,
11
+ publicMessage
12
+ };
13
+ }
14
+
4
15
  // ../api/src/cache-tags.ts
5
16
  var TAG_TEMPLATES = {
6
17
  siteCollection: "riverbank:site",
@@ -31,6 +42,18 @@ var TAG_TEMPLATES = {
31
42
  };
32
43
 
33
44
  // ../api/src/endpoints.ts
45
+ var DEMO_MUTATION_BLOCKED_HIDDEN = blockedDemoMutationPolicy(
46
+ "blocked-hidden",
47
+ "This action is not available in demo sites."
48
+ );
49
+ var DEMO_MUTATION_BLOCKED_DISABLED = blockedDemoMutationPolicy(
50
+ "blocked-disabled",
51
+ "This setting is disabled in demo sites."
52
+ );
53
+ var DEMO_MUTATION_INTERNAL_ONLY = blockedDemoMutationPolicy(
54
+ "internal-only",
55
+ "This internal operation is not available in demo sites."
56
+ );
34
57
  var ENDPOINT_DEFINITIONS = {
35
58
  // AI endpoints - no cache due to dynamic nature
36
59
  aiContentUpdateChat: {
@@ -147,7 +170,8 @@ var ENDPOINT_DEFINITIONS = {
147
170
  path: "/sites/{siteId}/ai/generate",
148
171
  method: "POST",
149
172
  auth: "user",
150
- responseKind: "json"
173
+ responseKind: "json",
174
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
151
175
  },
152
176
  getOnboardingPreviewStatus: {
153
177
  path: "/public/sites/{siteId}/onboarding/preview-status",
@@ -168,7 +192,8 @@ var ENDPOINT_DEFINITIONS = {
168
192
  method: "POST",
169
193
  auth: "user",
170
194
  errors: [],
171
- responseKind: "json"
195
+ responseKind: "json",
196
+ demoMutation: DEMO_MUTATION_BLOCKED_DISABLED
172
197
  },
173
198
  goLiveSite: {
174
199
  path: "/sites/{siteId}/launch/go-live",
@@ -237,20 +262,23 @@ var ENDPOINT_DEFINITIONS = {
237
262
  path: "/sites/{siteId}/ai/site-wizard/goals",
238
263
  method: "POST",
239
264
  auth: "user",
240
- responseKind: "json"
265
+ responseKind: "json",
266
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
241
267
  },
242
268
  aiSiteWizardIntakeTriage: {
243
269
  path: "/sites/{siteId}/ai/site-wizard/intake-triage",
244
270
  method: "POST",
245
271
  auth: "user",
246
- responseKind: "json"
272
+ responseKind: "json",
273
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
247
274
  },
248
275
  aiSiteWizardTelemetry: {
249
276
  path: "/sites/{siteId}/ai/site-wizard/telemetry",
250
277
  method: "POST",
251
278
  auth: "user",
252
279
  errors: [],
253
- responseKind: "json"
280
+ responseKind: "json",
281
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
254
282
  },
255
283
  // Admin SEO
256
284
  listGscPropertiesAdmin: {
@@ -457,7 +485,7 @@ var ENDPOINT_DEFINITIONS = {
457
485
  responseKind: "json",
458
486
  errors: ["resource:not_found", "server:internal_error"]
459
487
  },
460
- // Ops (event hosts/admins)
488
+ // Ops (staff event operators/admins)
461
489
  opsListUpcomingEventOccurrences: {
462
490
  path: "/ops/sites/{siteId}/events",
463
491
  method: "GET",
@@ -475,6 +503,7 @@ var ENDPOINT_DEFINITIONS = {
475
503
  method: "POST",
476
504
  auth: "user",
477
505
  responseKind: "json",
506
+ demoMutation: DEMO_MUTATION_INTERNAL_ONLY,
478
507
  errors: [
479
508
  "validation:invalid_input",
480
509
  "auth:forbidden",
@@ -487,6 +516,7 @@ var ENDPOINT_DEFINITIONS = {
487
516
  method: "POST",
488
517
  auth: "user",
489
518
  responseKind: "json",
519
+ demoMutation: DEMO_MUTATION_INTERNAL_ONLY,
490
520
  errors: [
491
521
  "validation:invalid_input",
492
522
  "auth:forbidden",
@@ -505,6 +535,7 @@ var ENDPOINT_DEFINITIONS = {
505
535
  method: "POST",
506
536
  auth: "user",
507
537
  responseKind: "json",
538
+ demoMutation: DEMO_MUTATION_INTERNAL_ONLY,
508
539
  errors: [
509
540
  "validation:invalid_input",
510
541
  "auth:forbidden",
@@ -538,6 +569,7 @@ var ENDPOINT_DEFINITIONS = {
538
569
  method: "POST",
539
570
  auth: "user",
540
571
  responseKind: "json",
572
+ demoMutation: DEMO_MUTATION_INTERNAL_ONLY,
541
573
  errors: [
542
574
  "validation:invalid_input",
543
575
  "auth:forbidden",
@@ -566,7 +598,8 @@ var ENDPOINT_DEFINITIONS = {
566
598
  method: "POST",
567
599
  tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteEmailSettings],
568
600
  auth: "user",
569
- responseKind: "json"
601
+ responseKind: "json",
602
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
570
603
  },
571
604
  previewEmailTemplate: {
572
605
  path: "/sites/{siteId}/settings/emails/preview",
@@ -617,14 +650,16 @@ var ENDPOINT_DEFINITIONS = {
617
650
  method: "POST",
618
651
  tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter],
619
652
  auth: "user",
620
- responseKind: "json"
653
+ responseKind: "json",
654
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
621
655
  },
622
656
  createNewsletterSubscribersImportUploadUrl: {
623
657
  path: "/sites/{siteId}/newsletter/subscribers/import-url",
624
658
  method: "POST",
625
659
  tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter],
626
660
  auth: "user",
627
- responseKind: "json"
661
+ responseKind: "json",
662
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
628
663
  },
629
664
  exportNewsletterSubscribersCsv: {
630
665
  path: "/sites/{siteId}/newsletter/subscribers/export.csv",
@@ -821,14 +856,16 @@ var ENDPOINT_DEFINITIONS = {
821
856
  method: "POST",
822
857
  tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter],
823
858
  auth: "user",
824
- responseKind: "json"
859
+ responseKind: "json",
860
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
825
861
  },
826
862
  testSendNewsletterCampaign: {
827
863
  path: "/sites/{siteId}/newsletter/campaigns/{campaignId}/test-send",
828
864
  method: "POST",
829
865
  tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter],
830
866
  auth: "user",
831
- responseKind: "json"
867
+ responseKind: "json",
868
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
832
869
  },
833
870
  listNewsletterSendJobs: {
834
871
  path: "/sites/{siteId}/newsletter/jobs",
@@ -1516,7 +1553,8 @@ var ENDPOINT_DEFINITIONS = {
1516
1553
  method: "DELETE",
1517
1554
  tags: ["site", "site-{siteId}"],
1518
1555
  auth: "user",
1519
- responseKind: "json"
1556
+ responseKind: "json",
1557
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
1520
1558
  },
1521
1559
  listSiteMembers: {
1522
1560
  path: "/sites/{siteId}/members",
@@ -1972,7 +2010,8 @@ var ENDPOINT_DEFINITIONS = {
1972
2010
  method: "POST",
1973
2011
  tags: ["site-{siteId}", "content-{siteId}-{type}"],
1974
2012
  auth: "user",
1975
- responseKind: "json"
2013
+ responseKind: "json",
2014
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
1976
2015
  },
1977
2016
  updateSiteGeneralSettings: {
1978
2017
  path: "/sites/{siteId}/settings/general",
@@ -4211,6 +4250,7 @@ var ENDPOINT_DEFINITIONS = {
4211
4250
  method: "POST",
4212
4251
  tags: ["site-{siteId}"],
4213
4252
  auth: "user",
4253
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN,
4214
4254
  errors: [
4215
4255
  "validation:invalid_input",
4216
4256
  "auth:forbidden",
@@ -4225,6 +4265,7 @@ var ENDPOINT_DEFINITIONS = {
4225
4265
  method: "POST",
4226
4266
  tags: ["site-{siteId}"],
4227
4267
  auth: "user",
4268
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN,
4228
4269
  errors: [
4229
4270
  "validation:invalid_input",
4230
4271
  "auth:forbidden",
@@ -4534,6 +4575,7 @@ var ENDPOINT_DEFINITIONS = {
4534
4575
  tags: ["site-{siteId}", "passes-{siteId}"],
4535
4576
  auth: "user",
4536
4577
  responseKind: "json",
4578
+ demoMutation: DEMO_MUTATION_BLOCKED_DISABLED,
4537
4579
  errors: ["validation:invalid_input", "server:internal_error"]
4538
4580
  },
4539
4581
  getBookingPass: {
@@ -4549,6 +4591,7 @@ var ENDPOINT_DEFINITIONS = {
4549
4591
  tags: ["site-{siteId}", "passes-{siteId}"],
4550
4592
  auth: "user",
4551
4593
  responseKind: "json",
4594
+ demoMutation: DEMO_MUTATION_BLOCKED_DISABLED,
4552
4595
  errors: [
4553
4596
  "validation:invalid_input",
4554
4597
  "resource:not_found",
@@ -4561,6 +4604,7 @@ var ENDPOINT_DEFINITIONS = {
4561
4604
  tags: ["site-{siteId}", "passes-{siteId}"],
4562
4605
  auth: "user",
4563
4606
  responseKind: "json",
4607
+ demoMutation: DEMO_MUTATION_BLOCKED_DISABLED,
4564
4608
  errors: [
4565
4609
  "validation:invalid_input",
4566
4610
  "resource:not_found",
@@ -4616,6 +4660,7 @@ var ENDPOINT_DEFINITIONS = {
4616
4660
  tags: ["site-{siteId}", "memberships-{siteId}"],
4617
4661
  auth: "user",
4618
4662
  responseKind: "json",
4663
+ demoMutation: DEMO_MUTATION_BLOCKED_DISABLED,
4619
4664
  errors: ["validation:invalid_input", "server:internal_error"]
4620
4665
  },
4621
4666
  getBookingMembership: {
@@ -4631,6 +4676,7 @@ var ENDPOINT_DEFINITIONS = {
4631
4676
  tags: ["site-{siteId}", "memberships-{siteId}"],
4632
4677
  auth: "user",
4633
4678
  responseKind: "json",
4679
+ demoMutation: DEMO_MUTATION_BLOCKED_DISABLED,
4634
4680
  errors: [
4635
4681
  "validation:invalid_input",
4636
4682
  "resource:not_found",
@@ -4643,6 +4689,7 @@ var ENDPOINT_DEFINITIONS = {
4643
4689
  tags: ["site-{siteId}", "memberships-{siteId}"],
4644
4690
  auth: "user",
4645
4691
  responseKind: "json",
4692
+ demoMutation: DEMO_MUTATION_BLOCKED_DISABLED,
4646
4693
  errors: [
4647
4694
  "validation:invalid_input",
4648
4695
  "resource:not_found",
@@ -4859,6 +4906,7 @@ var ENDPOINT_DEFINITIONS = {
4859
4906
  tags: ["site-{siteId}", "customers-{siteId}"],
4860
4907
  auth: "user",
4861
4908
  responseKind: "json",
4909
+ demoMutation: DEMO_MUTATION_BLOCKED_DISABLED,
4862
4910
  errors: [
4863
4911
  "validation:invalid_input",
4864
4912
  "auth:forbidden",
@@ -6447,6 +6495,7 @@ var ALLOWED_TRANSFORM_IDS = [
6447
6495
  "date.formatShort",
6448
6496
  "array.length",
6449
6497
  "value.jsonArray",
6498
+ "value.csv",
6450
6499
  "array.marqueeLoop",
6451
6500
  // Layout (layout.ts)
6452
6501
  "layout.maxWidthClass",
@@ -7216,8 +7265,7 @@ var dashboardNavVisibilityBaseSchema = z5.object({
7216
7265
  var dashboardNavVisibilityRolesSchema = z5.object({
7217
7266
  administrator: dashboardNavVisibilityBaseSchema.optional(),
7218
7267
  editor: dashboardNavVisibilityBaseSchema.optional(),
7219
- team_member: dashboardNavVisibilityBaseSchema.optional(),
7220
- event_host: dashboardNavVisibilityBaseSchema.optional()
7268
+ team_member: dashboardNavVisibilityBaseSchema.optional()
7221
7269
  }).strip().optional();
7222
7270
  var dashboardNavVisibilitySchema = dashboardNavVisibilityBaseSchema.extend({
7223
7271
  roles: dashboardNavVisibilityRolesSchema
@@ -7738,6 +7786,21 @@ var appointmentSetupServiceDraftSchema = z7.object({
7738
7786
  timezone: z7.string().trim().min(1).nullable(),
7739
7787
  payment: appointmentSetupPaymentDraftSchema,
7740
7788
  assignment: appointmentSetupServiceAssignmentDraftSchema
7789
+ }).superRefine((service, ctx) => {
7790
+ if (service.payment.priceType === "paid" && (service.priceAmount === null || service.priceAmount <= 0)) {
7791
+ ctx.addIssue({
7792
+ code: "custom",
7793
+ path: ["priceAmount"],
7794
+ message: "Paid appointment services need a positive price."
7795
+ });
7796
+ }
7797
+ if (service.payment.priceType === "free" && service.priceAmount !== null && service.priceAmount > 0) {
7798
+ ctx.addIssue({
7799
+ code: "custom",
7800
+ path: ["priceAmount"],
7801
+ message: "Free appointment services cannot carry a positive price."
7802
+ });
7803
+ }
7741
7804
  });
7742
7805
  var appointmentSetupPractitionerDraftSchema = z7.object({
7743
7806
  ref: appointmentSetupRefSchema,
@@ -8155,6 +8218,71 @@ function registerManifest(manifest) {
8155
8218
  return manifest;
8156
8219
  }
8157
8220
 
8221
+ // ../theme-core/src/palette/utils/colorConversion.ts
8222
+ var mod = (a, n) => (a % n + n) % n;
8223
+ var deg = (x) => mod(x, 360);
8224
+ function hexToRgb(hex) {
8225
+ const h = hex.replace(/^#/, "");
8226
+ const m = h.length === 3 ? h.split("").map((c) => c + c).join("") : h;
8227
+ if (m.length !== 6) throw new Error("Bad hex");
8228
+ const int = parseInt(m, 16);
8229
+ return { r: int >> 16 & 255, g: int >> 8 & 255, b: int & 255 };
8230
+ }
8231
+ function srgbToLinear(u) {
8232
+ const x = u / 255;
8233
+ return x <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);
8234
+ }
8235
+ function rgbToHsl(r, g, b) {
8236
+ const R = r / 255, G = g / 255, B = b / 255;
8237
+ const max = Math.max(R, G, B), min = Math.min(R, G, B);
8238
+ const d = max - min;
8239
+ let h = 0;
8240
+ if (d !== 0) {
8241
+ switch (max) {
8242
+ case R:
8243
+ h = (G - B) / d + (G < B ? 6 : 0);
8244
+ break;
8245
+ case G:
8246
+ h = (B - R) / d + 2;
8247
+ break;
8248
+ case B:
8249
+ h = (R - G) / d + 4;
8250
+ break;
8251
+ }
8252
+ h *= 60;
8253
+ }
8254
+ const l = (max + min) / 2;
8255
+ const s = d === 0 ? 0 : d / (1 - Math.abs(2 * l - 1));
8256
+ return { h, s, l };
8257
+ }
8258
+ function srgbToOklab(r, g, b) {
8259
+ const R = srgbToLinear(r), G = srgbToLinear(g), B = srgbToLinear(b);
8260
+ const l = 0.4122214708 * R + 0.5363325363 * G + 0.0514459929 * B;
8261
+ const m = 0.2119034982 * R + 0.6806995451 * G + 0.1073969566 * B;
8262
+ const s = 0.0883024619 * R + 0.2817188376 * G + 0.6299787005 * B;
8263
+ const l_ = Math.cbrt(l), m_ = Math.cbrt(m), s_ = Math.cbrt(s);
8264
+ const L = 0.2104542553 * l_ + 0.793617785 * m_ - 0.0040720468 * s_;
8265
+ const a = 1.9779984951 * l_ - 2.428592205 * m_ + 0.4505937099 * s_;
8266
+ const b2 = 0.0259040371 * l_ + 0.7827717662 * m_ - 0.808675766 * s_;
8267
+ return { L, a, b: b2 };
8268
+ }
8269
+ function oklabToOklch(L, a, b) {
8270
+ const C = Math.sqrt(a * a + b * b);
8271
+ const h = C < 1e-7 ? 0 : deg(Math.atan2(b, a) * 180 / Math.PI);
8272
+ return { L, C, h };
8273
+ }
8274
+ function featuresFromHex(hex) {
8275
+ const { r, g, b } = hexToRgb(hex);
8276
+ const { h, s, l } = rgbToHsl(r, g, b);
8277
+ const { L, a, b: b2 } = srgbToOklab(r, g, b);
8278
+ const { L: okL, C: okC, h: okH } = oklabToOklch(L, a, b2);
8279
+ const max = Math.max(r, g, b);
8280
+ const v = max / 255;
8281
+ const Y = 0.2126 * srgbToLinear(r) + 0.7152 * srgbToLinear(g) + 0.0722 * srgbToLinear(b);
8282
+ const chroma = s;
8283
+ return { r, g, b, h, s, l, v, Y, chroma, okL, okC, okH, hex };
8284
+ }
8285
+
8158
8286
  // ../theme-core/src/site-styles/appearancePresetResolution.ts
8159
8287
  function assertValidOptionGroups(preset2) {
8160
8288
  preset2.optionGroups?.forEach((group) => {
@@ -11684,6 +11812,9 @@ var curatedSiteStyleIdValues = [
11684
11812
  "site-style:bright-community",
11685
11813
  "site-style:quiet-luxury",
11686
11814
  "site-style:practical-services",
11815
+ "site-style:quiet-practice",
11816
+ "site-style:personal-retreat-journal",
11817
+ "site-style:tactile-workshop",
11687
11818
  "site-style:modern-wellness",
11688
11819
  "site-style:bold-launch",
11689
11820
  "site-style:south-west-twerk-school"
@@ -11766,7 +11897,8 @@ function defineCuratedSiteStyle(input) {
11766
11897
  name: input.name,
11767
11898
  description: input.description,
11768
11899
  generationBrief: input.generationBrief,
11769
- selectionKeywords: input.selectionKeywords ?? [],
11900
+ selectionKeywordRules: input.selectionKeywordRules ?? [],
11901
+ siteCreatorSelection: input.siteCreatorSelection ?? { kind: "explicit_only" },
11770
11902
  template: {
11771
11903
  id: asDesignSystemTemplateId(`template:${input.id.replace("site-style:", "")}`),
11772
11904
  name: input.name,
@@ -11910,12 +12042,13 @@ var curatedSiteStyles = [
11910
12042
  name: "Quiet Luxury",
11911
12043
  description: "Minimal, confident, and refined for premium experiences and private services.",
11912
12044
  generationBrief: "Use fewer claims, more specificity, and restrained sensory detail. Favor elegant media and low repetition over dense panels.",
11913
- selectionKeywords: [
11914
- "luxury",
11915
- "premium",
11916
- "boutique",
11917
- "bespoke",
11918
- "exclusive"
12045
+ siteCreatorSelection: { kind: "site_creator_keyword_heuristic", priority: 20 },
12046
+ selectionKeywordRules: [
12047
+ { kind: "word", value: "luxury" },
12048
+ { kind: "word", value: "premium" },
12049
+ { kind: "word", value: "boutique" },
12050
+ { kind: "word", value: "bespoke" },
12051
+ { kind: "word", value: "exclusive" }
11919
12052
  ],
11920
12053
  tokenRecipes: {
11921
12054
  palette: "high-contrast",
@@ -11944,13 +12077,14 @@ var curatedSiteStyles = [
11944
12077
  name: "Practical Services",
11945
12078
  description: "Efficient, plainspoken, and conversion-focused for trades and everyday services.",
11946
12079
  generationBrief: "Make services, location, trust signals, and contact paths obvious. Keep copy brief and avoid ornate visual treatments.",
11947
- selectionKeywords: [
11948
- "repair",
11949
- "plumb",
11950
- "electric",
11951
- "cleaning",
11952
- "landscap",
11953
- "contractor"
12080
+ siteCreatorSelection: { kind: "primary_goal_support" },
12081
+ selectionKeywordRules: [
12082
+ { kind: "word", value: "repair" },
12083
+ { kind: "substring", value: "plumb" },
12084
+ { kind: "substring", value: "electric" },
12085
+ { kind: "word", value: "cleaning" },
12086
+ { kind: "substring", value: "landscap" },
12087
+ { kind: "substring", value: "contractor" }
11954
12088
  ],
11955
12089
  tokenRecipes: {
11956
12090
  palette: "brand-led",
@@ -12001,18 +12135,134 @@ var curatedSiteStyles = [
12001
12135
  paletteChoice("warm-neutral-forest")
12002
12136
  ]
12003
12137
  }),
12138
+ defineCuratedSiteStyle({
12139
+ id: "site-style:quiet-practice",
12140
+ name: "Quiet Practice",
12141
+ description: "Grounded, calm, and practical for small appointment-first practices.",
12142
+ 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.",
12143
+ siteCreatorSelection: { kind: "site_creator_keyword_heuristic", priority: 30 },
12144
+ selectionKeywordRules: [
12145
+ { kind: "substring", value: "massage" },
12146
+ { kind: "word", value: "bodywork" },
12147
+ { kind: "phrase", value: "appointment practice" },
12148
+ { kind: "phrase", value: "appointment-first" },
12149
+ { kind: "substring", value: "practitioner" },
12150
+ { kind: "substring", value: "therap" },
12151
+ { kind: "substring", value: "clinic" },
12152
+ { kind: "phrase", value: "wellness practice" }
12153
+ ],
12154
+ tokenRecipes: {
12155
+ palette: "soft-natural",
12156
+ contrast: "standard",
12157
+ radius: "soft",
12158
+ shadow: "subtle",
12159
+ typography: "clean-sans",
12160
+ spacing: "regular",
12161
+ motion: "subtle"
12162
+ },
12163
+ compositionBudget: quietBudget,
12164
+ recommendedHeaderLookIds: ["practical-utility", "clean-base", "centered-calm"],
12165
+ buttonPersonalityChoices: [
12166
+ buttonChoice("pebble"),
12167
+ buttonChoice("soft-pill"),
12168
+ buttonChoice("editorial-link")
12169
+ ],
12170
+ paletteVariantChoices: [
12171
+ paletteChoice("soft-natural-stone"),
12172
+ paletteChoice("soft-natural-sage"),
12173
+ paletteChoice("warm-neutral-clay")
12174
+ ]
12175
+ }),
12176
+ defineCuratedSiteStyle({
12177
+ id: "site-style:personal-retreat-journal",
12178
+ name: "Personal Retreat Journal",
12179
+ description: "Warm, story-led, and readable for solo practitioners with mixed offers.",
12180
+ 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.",
12181
+ siteCreatorSelection: { kind: "site_creator_keyword_heuristic", priority: 40 },
12182
+ selectionKeywordRules: [
12183
+ { kind: "substring", value: "retreat" },
12184
+ { kind: "phrase", value: "solo practitioner" },
12185
+ { kind: "phrase", value: "personal brand" },
12186
+ { kind: "substring", value: "teacher" },
12187
+ { kind: "substring", value: "coach" },
12188
+ { kind: "phrase", value: "retreat resources" },
12189
+ { kind: "substring", value: "journal" }
12190
+ ],
12191
+ tokenRecipes: {
12192
+ palette: "warm-neutral",
12193
+ contrast: "standard",
12194
+ radius: "soft",
12195
+ shadow: "subtle",
12196
+ typography: "serif-editorial",
12197
+ spacing: "airy",
12198
+ motion: "subtle"
12199
+ },
12200
+ compositionBudget: balancedBudget,
12201
+ recommendedHeaderLookIds: ["editorial-line", "centered-calm", "minimal-transparent"],
12202
+ buttonPersonalityChoices: [
12203
+ buttonChoice("editorial-link"),
12204
+ buttonChoice("soft-pill"),
12205
+ buttonChoice("brushed-wash")
12206
+ ],
12207
+ paletteVariantChoices: [
12208
+ paletteChoice("warm-neutral-forest"),
12209
+ paletteChoice("warm-neutral-clay"),
12210
+ paletteChoice("soft-natural-stone")
12211
+ ]
12212
+ }),
12213
+ defineCuratedSiteStyle({
12214
+ id: "site-style:tactile-workshop",
12215
+ name: "Tactile Workshop",
12216
+ description: "Bright, hands-on, and image-led for maker studios, workshops, and creative classes.",
12217
+ 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.",
12218
+ siteCreatorSelection: { kind: "site_creator_keyword_heuristic", priority: 50 },
12219
+ selectionKeywordRules: [
12220
+ { kind: "substring", value: "ceramic" },
12221
+ { kind: "word", value: "pottery" },
12222
+ { kind: "phrase", value: "maker studio" },
12223
+ { kind: "phrase", value: "craft class" },
12224
+ { kind: "phrase", value: "craft workshop" },
12225
+ { kind: "word", value: "clay" },
12226
+ { kind: "word", value: "kiln" }
12227
+ ],
12228
+ tokenRecipes: {
12229
+ palette: "brand-led",
12230
+ contrast: "standard",
12231
+ radius: "soft",
12232
+ shadow: "subtle",
12233
+ typography: "friendly-sans",
12234
+ spacing: "regular",
12235
+ motion: "subtle"
12236
+ },
12237
+ compositionBudget: balancedBudget,
12238
+ recommendedHeaderLookIds: ["brand-solid", "practical-utility", "clean-base"],
12239
+ recommendedFooterLookIds: ["site-footer-brand-two-band", "footer-muted-grounding"],
12240
+ buttonPersonalityChoices: [
12241
+ buttonChoice("pebble"),
12242
+ buttonChoice("confident-chip"),
12243
+ buttonChoice("ink-stamp"),
12244
+ buttonChoice("editorial-link")
12245
+ ],
12246
+ paletteVariantChoices: [
12247
+ paletteChoice("brand-led-warm"),
12248
+ paletteChoice("brand-led-cool"),
12249
+ paletteChoice("soft-natural-watercolor"),
12250
+ paletteChoice("warm-neutral-clay")
12251
+ ]
12252
+ }),
12004
12253
  defineCuratedSiteStyle({
12005
12254
  id: "site-style:bold-launch",
12006
12255
  name: "Bold Launch",
12007
12256
  description: "High-energy and punchy for launches, campaigns, and creative offers.",
12008
12257
  generationBrief: "Use crisp positioning, bold hero structure, strong calls to action, and confident visual rhythm. Keep it precise, not shouty.",
12009
- selectionKeywords: [
12010
- "launch",
12011
- "campaign",
12012
- "preorder",
12013
- "pre-order",
12014
- "waitlist",
12015
- "drop"
12258
+ siteCreatorSelection: { kind: "site_creator_keyword_heuristic", priority: 10 },
12259
+ selectionKeywordRules: [
12260
+ { kind: "substring", value: "launch" },
12261
+ { kind: "substring", value: "campaign" },
12262
+ { kind: "word", value: "preorder" },
12263
+ { kind: "phrase", value: "pre-order" },
12264
+ { kind: "substring", value: "waitlist" },
12265
+ { kind: "word", value: "drop" }
12016
12266
  ],
12017
12267
  tokenRecipes: {
12018
12268
  palette: "high-contrast",
@@ -12043,15 +12293,6 @@ var curatedSiteStyles = [
12043
12293
  name: "South West Twerk School",
12044
12294
  description: "Energetic, editorial, and high-contrast for a branded dance school presence.",
12045
12295
  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.",
12046
- selectionKeywords: [
12047
- "dance",
12048
- "classes",
12049
- "workshop",
12050
- "school",
12051
- "movement",
12052
- "performance",
12053
- "community"
12054
- ],
12055
12296
  tokenRecipes: {
12056
12297
  palette: "brand-led",
12057
12298
  contrast: "maximum",
@@ -12358,25 +12599,19 @@ var defaultDesignRuntimeRules = defineDesignRuntimeRules({
12358
12599
  "muted-band": {
12359
12600
  background: {
12360
12601
  type: "color",
12361
- color: "muted",
12362
- textColor: "text",
12363
- headingColor: "text"
12602
+ color: "muted"
12364
12603
  }
12365
12604
  },
12366
12605
  "accent-band": {
12367
12606
  background: {
12368
12607
  type: "color",
12369
- color: "primary",
12370
- textColor: "primaryForeground",
12371
- headingColor: "primaryForeground"
12608
+ color: "primary"
12372
12609
  }
12373
12610
  },
12374
12611
  "brand-depth-band": {
12375
12612
  background: {
12376
12613
  type: "color",
12377
- color: "primary-800",
12378
- textColor: "primaryForeground",
12379
- headingColor: "primaryForeground"
12614
+ color: "primary-800"
12380
12615
  }
12381
12616
  },
12382
12617
  "hero-image": {
@@ -18473,6 +18708,16 @@ var jsonArrayTransform = {
18473
18708
  return "";
18474
18709
  }
18475
18710
  };
18711
+ var csvTransform = {
18712
+ id: "value.csv",
18713
+ kind: "formatter",
18714
+ summary: "Normalize a string or array of strings into a comma-separated list",
18715
+ run: (value) => {
18716
+ const rawValues = Array.isArray(value) ? value : typeof value === "string" ? value.split(",") : [];
18717
+ const normalized = rawValues.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean);
18718
+ return normalized.length > 0 ? Array.from(new Set(normalized)).join(",") : "";
18719
+ }
18720
+ };
18476
18721
  var marqueeLoopOptionsSchema = z36.object({
18477
18722
  minItems: z36.number().int().min(1).default(10)
18478
18723
  });
@@ -18498,6 +18743,7 @@ var formattingTransforms = [
18498
18743
  dateFormatShort,
18499
18744
  arrayLengthTransform,
18500
18745
  jsonArrayTransform,
18746
+ csvTransform,
18501
18747
  marqueeLoopTransform
18502
18748
  ];
18503
18749
 
@@ -18981,73 +19227,6 @@ var uiTransforms = [
18981
19227
 
18982
19228
  // ../blocks/src/system/transforms/registry/layout.ts
18983
19229
  import { z as z38 } from "zod";
18984
-
18985
- // ../theme-core/src/palette/utils/colorConversion.ts
18986
- var mod = (a, n) => (a % n + n) % n;
18987
- var deg = (x) => mod(x, 360);
18988
- function hexToRgb(hex) {
18989
- const h = hex.replace(/^#/, "");
18990
- const m = h.length === 3 ? h.split("").map((c) => c + c).join("") : h;
18991
- if (m.length !== 6) throw new Error("Bad hex");
18992
- const int = parseInt(m, 16);
18993
- return { r: int >> 16 & 255, g: int >> 8 & 255, b: int & 255 };
18994
- }
18995
- function srgbToLinear(u) {
18996
- const x = u / 255;
18997
- return x <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);
18998
- }
18999
- function rgbToHsl(r, g, b) {
19000
- const R = r / 255, G = g / 255, B = b / 255;
19001
- const max = Math.max(R, G, B), min = Math.min(R, G, B);
19002
- const d = max - min;
19003
- let h = 0;
19004
- if (d !== 0) {
19005
- switch (max) {
19006
- case R:
19007
- h = (G - B) / d + (G < B ? 6 : 0);
19008
- break;
19009
- case G:
19010
- h = (B - R) / d + 2;
19011
- break;
19012
- case B:
19013
- h = (R - G) / d + 4;
19014
- break;
19015
- }
19016
- h *= 60;
19017
- }
19018
- const l = (max + min) / 2;
19019
- const s = d === 0 ? 0 : d / (1 - Math.abs(2 * l - 1));
19020
- return { h, s, l };
19021
- }
19022
- function srgbToOklab(r, g, b) {
19023
- const R = srgbToLinear(r), G = srgbToLinear(g), B = srgbToLinear(b);
19024
- const l = 0.4122214708 * R + 0.5363325363 * G + 0.0514459929 * B;
19025
- const m = 0.2119034982 * R + 0.6806995451 * G + 0.1073969566 * B;
19026
- const s = 0.0883024619 * R + 0.2817188376 * G + 0.6299787005 * B;
19027
- const l_ = Math.cbrt(l), m_ = Math.cbrt(m), s_ = Math.cbrt(s);
19028
- const L = 0.2104542553 * l_ + 0.793617785 * m_ - 0.0040720468 * s_;
19029
- const a = 1.9779984951 * l_ - 2.428592205 * m_ + 0.4505937099 * s_;
19030
- const b2 = 0.0259040371 * l_ + 0.7827717662 * m_ - 0.808675766 * s_;
19031
- return { L, a, b: b2 };
19032
- }
19033
- function oklabToOklch(L, a, b) {
19034
- const C = Math.sqrt(a * a + b * b);
19035
- const h = C < 1e-7 ? 0 : deg(Math.atan2(b, a) * 180 / Math.PI);
19036
- return { L, C, h };
19037
- }
19038
- function featuresFromHex(hex) {
19039
- const { r, g, b } = hexToRgb(hex);
19040
- const { h, s, l } = rgbToHsl(r, g, b);
19041
- const { L, a, b: b2 } = srgbToOklab(r, g, b);
19042
- const { L: okL, C: okC, h: okH } = oklabToOklch(L, a, b2);
19043
- const max = Math.max(r, g, b);
19044
- const v = max / 255;
19045
- const Y = 0.2126 * srgbToLinear(r) + 0.7152 * srgbToLinear(g) + 0.0722 * srgbToLinear(b);
19046
- const chroma = s;
19047
- return { r, g, b, h, s, l, v, Y, chroma, okL, okC, okH, hex };
19048
- }
19049
-
19050
- // ../blocks/src/system/transforms/registry/layout.ts
19051
19230
  var joinClasses4 = (parts) => parts.filter(
19052
19231
  (part) => typeof part === "string" && part.trim().length > 0
19053
19232
  ).join(" ").replace(/\s+/g, " ").trim();
@@ -23728,7 +23907,12 @@ var eventListingBlockDefinition = {
23728
23907
  detailLevel: "listing",
23729
23908
  kind: { $bind: { from: "content.kind" } },
23730
23909
  eventSurface: { $bind: { from: "content.eventSurface" } },
23731
- eventPresets: { $bind: { from: "content.filterEventPresets" } },
23910
+ eventPresets: {
23911
+ $bind: {
23912
+ from: "content.filterEventPresets",
23913
+ transforms: [{ id: "value.csv" }]
23914
+ }
23915
+ },
23732
23916
  scheduleScope: { $bind: { from: "content.scheduleScope" } }
23733
23917
  },
23734
23918
  mode: "server"
@@ -24480,7 +24664,12 @@ var eventCalendarBlockDefinition = {
24480
24664
  // Pass filter params if configured
24481
24665
  kind: { $bind: { from: "content.kind" } },
24482
24666
  eventSurface: { $bind: { from: "content.eventSurface" } },
24483
- eventPresets: { $bind: { from: "content.filterEventPresets" } },
24667
+ eventPresets: {
24668
+ $bind: {
24669
+ from: "content.filterEventPresets",
24670
+ transforms: [{ id: "value.csv" }]
24671
+ }
24672
+ },
24484
24673
  scheduleScope: { $bind: { from: "content.scheduleScope" } },
24485
24674
  categoryIds: { $bind: { from: "content.filterCategoryIds" } },
24486
24675
  staffMemberId: { $bind: { from: "content.filterStaffMemberId" } },
@@ -30087,8 +30276,7 @@ var dashboardNavVisibilityBaseSchema2 = z66.object({
30087
30276
  var dashboardNavVisibilityRolesSchema2 = z66.object({
30088
30277
  administrator: dashboardNavVisibilityBaseSchema2.optional(),
30089
30278
  editor: dashboardNavVisibilityBaseSchema2.optional(),
30090
- team_member: dashboardNavVisibilityBaseSchema2.optional(),
30091
- event_host: dashboardNavVisibilityBaseSchema2.optional()
30279
+ team_member: dashboardNavVisibilityBaseSchema2.optional()
30092
30280
  }).strip().optional();
30093
30281
  var dashboardNavVisibilitySchema2 = dashboardNavVisibilityBaseSchema2.extend({
30094
30282
  roles: dashboardNavVisibilityRolesSchema2