@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,3 +1,14 @@
1
+ // ../api/src/apiEndpointTypes.ts
2
+ function blockedDemoMutationPolicy(classification, publicMessage) {
3
+ if (publicMessage.trim() === "") {
4
+ throw new Error(`Demo mutation policy ${classification} requires publicMessage.`);
5
+ }
6
+ return {
7
+ classification,
8
+ publicMessage
9
+ };
10
+ }
11
+
1
12
  // ../api/src/cache-tags.ts
2
13
  var TAG_TEMPLATES = {
3
14
  siteCollection: "riverbank:site",
@@ -28,6 +39,18 @@ var TAG_TEMPLATES = {
28
39
  };
29
40
 
30
41
  // ../api/src/endpoints.ts
42
+ var DEMO_MUTATION_BLOCKED_HIDDEN = blockedDemoMutationPolicy(
43
+ "blocked-hidden",
44
+ "This action is not available in demo sites."
45
+ );
46
+ var DEMO_MUTATION_BLOCKED_DISABLED = blockedDemoMutationPolicy(
47
+ "blocked-disabled",
48
+ "This setting is disabled in demo sites."
49
+ );
50
+ var DEMO_MUTATION_INTERNAL_ONLY = blockedDemoMutationPolicy(
51
+ "internal-only",
52
+ "This internal operation is not available in demo sites."
53
+ );
31
54
  var ENDPOINT_DEFINITIONS = {
32
55
  // AI endpoints - no cache due to dynamic nature
33
56
  aiContentUpdateChat: {
@@ -144,7 +167,8 @@ var ENDPOINT_DEFINITIONS = {
144
167
  path: "/sites/{siteId}/ai/generate",
145
168
  method: "POST",
146
169
  auth: "user",
147
- responseKind: "json"
170
+ responseKind: "json",
171
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
148
172
  },
149
173
  getOnboardingPreviewStatus: {
150
174
  path: "/public/sites/{siteId}/onboarding/preview-status",
@@ -165,7 +189,8 @@ var ENDPOINT_DEFINITIONS = {
165
189
  method: "POST",
166
190
  auth: "user",
167
191
  errors: [],
168
- responseKind: "json"
192
+ responseKind: "json",
193
+ demoMutation: DEMO_MUTATION_BLOCKED_DISABLED
169
194
  },
170
195
  goLiveSite: {
171
196
  path: "/sites/{siteId}/launch/go-live",
@@ -234,20 +259,23 @@ var ENDPOINT_DEFINITIONS = {
234
259
  path: "/sites/{siteId}/ai/site-wizard/goals",
235
260
  method: "POST",
236
261
  auth: "user",
237
- responseKind: "json"
262
+ responseKind: "json",
263
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
238
264
  },
239
265
  aiSiteWizardIntakeTriage: {
240
266
  path: "/sites/{siteId}/ai/site-wizard/intake-triage",
241
267
  method: "POST",
242
268
  auth: "user",
243
- responseKind: "json"
269
+ responseKind: "json",
270
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
244
271
  },
245
272
  aiSiteWizardTelemetry: {
246
273
  path: "/sites/{siteId}/ai/site-wizard/telemetry",
247
274
  method: "POST",
248
275
  auth: "user",
249
276
  errors: [],
250
- responseKind: "json"
277
+ responseKind: "json",
278
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
251
279
  },
252
280
  // Admin SEO
253
281
  listGscPropertiesAdmin: {
@@ -454,7 +482,7 @@ var ENDPOINT_DEFINITIONS = {
454
482
  responseKind: "json",
455
483
  errors: ["resource:not_found", "server:internal_error"]
456
484
  },
457
- // Ops (event hosts/admins)
485
+ // Ops (staff event operators/admins)
458
486
  opsListUpcomingEventOccurrences: {
459
487
  path: "/ops/sites/{siteId}/events",
460
488
  method: "GET",
@@ -472,6 +500,7 @@ var ENDPOINT_DEFINITIONS = {
472
500
  method: "POST",
473
501
  auth: "user",
474
502
  responseKind: "json",
503
+ demoMutation: DEMO_MUTATION_INTERNAL_ONLY,
475
504
  errors: [
476
505
  "validation:invalid_input",
477
506
  "auth:forbidden",
@@ -484,6 +513,7 @@ var ENDPOINT_DEFINITIONS = {
484
513
  method: "POST",
485
514
  auth: "user",
486
515
  responseKind: "json",
516
+ demoMutation: DEMO_MUTATION_INTERNAL_ONLY,
487
517
  errors: [
488
518
  "validation:invalid_input",
489
519
  "auth:forbidden",
@@ -502,6 +532,7 @@ var ENDPOINT_DEFINITIONS = {
502
532
  method: "POST",
503
533
  auth: "user",
504
534
  responseKind: "json",
535
+ demoMutation: DEMO_MUTATION_INTERNAL_ONLY,
505
536
  errors: [
506
537
  "validation:invalid_input",
507
538
  "auth:forbidden",
@@ -535,6 +566,7 @@ var ENDPOINT_DEFINITIONS = {
535
566
  method: "POST",
536
567
  auth: "user",
537
568
  responseKind: "json",
569
+ demoMutation: DEMO_MUTATION_INTERNAL_ONLY,
538
570
  errors: [
539
571
  "validation:invalid_input",
540
572
  "auth:forbidden",
@@ -563,7 +595,8 @@ var ENDPOINT_DEFINITIONS = {
563
595
  method: "POST",
564
596
  tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteEmailSettings],
565
597
  auth: "user",
566
- responseKind: "json"
598
+ responseKind: "json",
599
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
567
600
  },
568
601
  previewEmailTemplate: {
569
602
  path: "/sites/{siteId}/settings/emails/preview",
@@ -614,14 +647,16 @@ var ENDPOINT_DEFINITIONS = {
614
647
  method: "POST",
615
648
  tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter],
616
649
  auth: "user",
617
- responseKind: "json"
650
+ responseKind: "json",
651
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
618
652
  },
619
653
  createNewsletterSubscribersImportUploadUrl: {
620
654
  path: "/sites/{siteId}/newsletter/subscribers/import-url",
621
655
  method: "POST",
622
656
  tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter],
623
657
  auth: "user",
624
- responseKind: "json"
658
+ responseKind: "json",
659
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
625
660
  },
626
661
  exportNewsletterSubscribersCsv: {
627
662
  path: "/sites/{siteId}/newsletter/subscribers/export.csv",
@@ -818,14 +853,16 @@ var ENDPOINT_DEFINITIONS = {
818
853
  method: "POST",
819
854
  tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter],
820
855
  auth: "user",
821
- responseKind: "json"
856
+ responseKind: "json",
857
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
822
858
  },
823
859
  testSendNewsletterCampaign: {
824
860
  path: "/sites/{siteId}/newsletter/campaigns/{campaignId}/test-send",
825
861
  method: "POST",
826
862
  tags: [TAG_TEMPLATES.site, TAG_TEMPLATES.siteNewsletter],
827
863
  auth: "user",
828
- responseKind: "json"
864
+ responseKind: "json",
865
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
829
866
  },
830
867
  listNewsletterSendJobs: {
831
868
  path: "/sites/{siteId}/newsletter/jobs",
@@ -1513,7 +1550,8 @@ var ENDPOINT_DEFINITIONS = {
1513
1550
  method: "DELETE",
1514
1551
  tags: ["site", "site-{siteId}"],
1515
1552
  auth: "user",
1516
- responseKind: "json"
1553
+ responseKind: "json",
1554
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
1517
1555
  },
1518
1556
  listSiteMembers: {
1519
1557
  path: "/sites/{siteId}/members",
@@ -1969,7 +2007,8 @@ var ENDPOINT_DEFINITIONS = {
1969
2007
  method: "POST",
1970
2008
  tags: ["site-{siteId}", "content-{siteId}-{type}"],
1971
2009
  auth: "user",
1972
- responseKind: "json"
2010
+ responseKind: "json",
2011
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN
1973
2012
  },
1974
2013
  updateSiteGeneralSettings: {
1975
2014
  path: "/sites/{siteId}/settings/general",
@@ -4208,6 +4247,7 @@ var ENDPOINT_DEFINITIONS = {
4208
4247
  method: "POST",
4209
4248
  tags: ["site-{siteId}"],
4210
4249
  auth: "user",
4250
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN,
4211
4251
  errors: [
4212
4252
  "validation:invalid_input",
4213
4253
  "auth:forbidden",
@@ -4222,6 +4262,7 @@ var ENDPOINT_DEFINITIONS = {
4222
4262
  method: "POST",
4223
4263
  tags: ["site-{siteId}"],
4224
4264
  auth: "user",
4265
+ demoMutation: DEMO_MUTATION_BLOCKED_HIDDEN,
4225
4266
  errors: [
4226
4267
  "validation:invalid_input",
4227
4268
  "auth:forbidden",
@@ -4531,6 +4572,7 @@ var ENDPOINT_DEFINITIONS = {
4531
4572
  tags: ["site-{siteId}", "passes-{siteId}"],
4532
4573
  auth: "user",
4533
4574
  responseKind: "json",
4575
+ demoMutation: DEMO_MUTATION_BLOCKED_DISABLED,
4534
4576
  errors: ["validation:invalid_input", "server:internal_error"]
4535
4577
  },
4536
4578
  getBookingPass: {
@@ -4546,6 +4588,7 @@ var ENDPOINT_DEFINITIONS = {
4546
4588
  tags: ["site-{siteId}", "passes-{siteId}"],
4547
4589
  auth: "user",
4548
4590
  responseKind: "json",
4591
+ demoMutation: DEMO_MUTATION_BLOCKED_DISABLED,
4549
4592
  errors: [
4550
4593
  "validation:invalid_input",
4551
4594
  "resource:not_found",
@@ -4558,6 +4601,7 @@ var ENDPOINT_DEFINITIONS = {
4558
4601
  tags: ["site-{siteId}", "passes-{siteId}"],
4559
4602
  auth: "user",
4560
4603
  responseKind: "json",
4604
+ demoMutation: DEMO_MUTATION_BLOCKED_DISABLED,
4561
4605
  errors: [
4562
4606
  "validation:invalid_input",
4563
4607
  "resource:not_found",
@@ -4613,6 +4657,7 @@ var ENDPOINT_DEFINITIONS = {
4613
4657
  tags: ["site-{siteId}", "memberships-{siteId}"],
4614
4658
  auth: "user",
4615
4659
  responseKind: "json",
4660
+ demoMutation: DEMO_MUTATION_BLOCKED_DISABLED,
4616
4661
  errors: ["validation:invalid_input", "server:internal_error"]
4617
4662
  },
4618
4663
  getBookingMembership: {
@@ -4628,6 +4673,7 @@ var ENDPOINT_DEFINITIONS = {
4628
4673
  tags: ["site-{siteId}", "memberships-{siteId}"],
4629
4674
  auth: "user",
4630
4675
  responseKind: "json",
4676
+ demoMutation: DEMO_MUTATION_BLOCKED_DISABLED,
4631
4677
  errors: [
4632
4678
  "validation:invalid_input",
4633
4679
  "resource:not_found",
@@ -4640,6 +4686,7 @@ var ENDPOINT_DEFINITIONS = {
4640
4686
  tags: ["site-{siteId}", "memberships-{siteId}"],
4641
4687
  auth: "user",
4642
4688
  responseKind: "json",
4689
+ demoMutation: DEMO_MUTATION_BLOCKED_DISABLED,
4643
4690
  errors: [
4644
4691
  "validation:invalid_input",
4645
4692
  "resource:not_found",
@@ -4856,6 +4903,7 @@ var ENDPOINT_DEFINITIONS = {
4856
4903
  tags: ["site-{siteId}", "customers-{siteId}"],
4857
4904
  auth: "user",
4858
4905
  responseKind: "json",
4906
+ demoMutation: DEMO_MUTATION_BLOCKED_DISABLED,
4859
4907
  errors: [
4860
4908
  "validation:invalid_input",
4861
4909
  "auth:forbidden",
@@ -7115,8 +7163,7 @@ var dashboardNavVisibilityBaseSchema = z5.object({
7115
7163
  var dashboardNavVisibilityRolesSchema = z5.object({
7116
7164
  administrator: dashboardNavVisibilityBaseSchema.optional(),
7117
7165
  editor: dashboardNavVisibilityBaseSchema.optional(),
7118
- team_member: dashboardNavVisibilityBaseSchema.optional(),
7119
- event_host: dashboardNavVisibilityBaseSchema.optional()
7166
+ team_member: dashboardNavVisibilityBaseSchema.optional()
7120
7167
  }).strip().optional();
7121
7168
  var dashboardNavVisibilitySchema = dashboardNavVisibilityBaseSchema.extend({
7122
7169
  roles: dashboardNavVisibilityRolesSchema
@@ -7637,6 +7684,21 @@ var appointmentSetupServiceDraftSchema = z7.object({
7637
7684
  timezone: z7.string().trim().min(1).nullable(),
7638
7685
  payment: appointmentSetupPaymentDraftSchema,
7639
7686
  assignment: appointmentSetupServiceAssignmentDraftSchema
7687
+ }).superRefine((service, ctx) => {
7688
+ if (service.payment.priceType === "paid" && (service.priceAmount === null || service.priceAmount <= 0)) {
7689
+ ctx.addIssue({
7690
+ code: "custom",
7691
+ path: ["priceAmount"],
7692
+ message: "Paid appointment services need a positive price."
7693
+ });
7694
+ }
7695
+ if (service.payment.priceType === "free" && service.priceAmount !== null && service.priceAmount > 0) {
7696
+ ctx.addIssue({
7697
+ code: "custom",
7698
+ path: ["priceAmount"],
7699
+ message: "Free appointment services cannot carry a positive price."
7700
+ });
7701
+ }
7640
7702
  });
7641
7703
  var appointmentSetupPractitionerDraftSchema = z7.object({
7642
7704
  ref: appointmentSetupRefSchema,
@@ -8009,6 +8071,71 @@ function registerManifest(manifest) {
8009
8071
  return manifest;
8010
8072
  }
8011
8073
 
8074
+ // ../theme-core/src/palette/utils/colorConversion.ts
8075
+ var mod = (a, n) => (a % n + n) % n;
8076
+ var deg = (x) => mod(x, 360);
8077
+ function hexToRgb(hex) {
8078
+ const h = hex.replace(/^#/, "");
8079
+ const m = h.length === 3 ? h.split("").map((c) => c + c).join("") : h;
8080
+ if (m.length !== 6) throw new Error("Bad hex");
8081
+ const int = parseInt(m, 16);
8082
+ return { r: int >> 16 & 255, g: int >> 8 & 255, b: int & 255 };
8083
+ }
8084
+ function srgbToLinear(u) {
8085
+ const x = u / 255;
8086
+ return x <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);
8087
+ }
8088
+ function rgbToHsl(r, g, b) {
8089
+ const R = r / 255, G = g / 255, B = b / 255;
8090
+ const max = Math.max(R, G, B), min = Math.min(R, G, B);
8091
+ const d = max - min;
8092
+ let h = 0;
8093
+ if (d !== 0) {
8094
+ switch (max) {
8095
+ case R:
8096
+ h = (G - B) / d + (G < B ? 6 : 0);
8097
+ break;
8098
+ case G:
8099
+ h = (B - R) / d + 2;
8100
+ break;
8101
+ case B:
8102
+ h = (R - G) / d + 4;
8103
+ break;
8104
+ }
8105
+ h *= 60;
8106
+ }
8107
+ const l = (max + min) / 2;
8108
+ const s = d === 0 ? 0 : d / (1 - Math.abs(2 * l - 1));
8109
+ return { h, s, l };
8110
+ }
8111
+ function srgbToOklab(r, g, b) {
8112
+ const R = srgbToLinear(r), G = srgbToLinear(g), B = srgbToLinear(b);
8113
+ const l = 0.4122214708 * R + 0.5363325363 * G + 0.0514459929 * B;
8114
+ const m = 0.2119034982 * R + 0.6806995451 * G + 0.1073969566 * B;
8115
+ const s = 0.0883024619 * R + 0.2817188376 * G + 0.6299787005 * B;
8116
+ const l_ = Math.cbrt(l), m_ = Math.cbrt(m), s_ = Math.cbrt(s);
8117
+ const L = 0.2104542553 * l_ + 0.793617785 * m_ - 0.0040720468 * s_;
8118
+ const a = 1.9779984951 * l_ - 2.428592205 * m_ + 0.4505937099 * s_;
8119
+ const b2 = 0.0259040371 * l_ + 0.7827717662 * m_ - 0.808675766 * s_;
8120
+ return { L, a, b: b2 };
8121
+ }
8122
+ function oklabToOklch(L, a, b) {
8123
+ const C = Math.sqrt(a * a + b * b);
8124
+ const h = C < 1e-7 ? 0 : deg(Math.atan2(b, a) * 180 / Math.PI);
8125
+ return { L, C, h };
8126
+ }
8127
+ function featuresFromHex(hex) {
8128
+ const { r, g, b } = hexToRgb(hex);
8129
+ const { h, s, l } = rgbToHsl(r, g, b);
8130
+ const { L, a, b: b2 } = srgbToOklab(r, g, b);
8131
+ const { L: okL, C: okC, h: okH } = oklabToOklch(L, a, b2);
8132
+ const max = Math.max(r, g, b);
8133
+ const v = max / 255;
8134
+ const Y = 0.2126 * srgbToLinear(r) + 0.7152 * srgbToLinear(g) + 0.0722 * srgbToLinear(b);
8135
+ const chroma = s;
8136
+ return { r, g, b, h, s, l, v, Y, chroma, okL, okC, okH, hex };
8137
+ }
8138
+
8012
8139
  // ../theme-core/src/site-styles/appearancePresetResolution.ts
8013
8140
  function assertValidOptionGroups(preset2) {
8014
8141
  preset2.optionGroups?.forEach((group) => {
@@ -11538,6 +11665,9 @@ var curatedSiteStyleIdValues = [
11538
11665
  "site-style:bright-community",
11539
11666
  "site-style:quiet-luxury",
11540
11667
  "site-style:practical-services",
11668
+ "site-style:quiet-practice",
11669
+ "site-style:personal-retreat-journal",
11670
+ "site-style:tactile-workshop",
11541
11671
  "site-style:modern-wellness",
11542
11672
  "site-style:bold-launch",
11543
11673
  "site-style:south-west-twerk-school"
@@ -11620,7 +11750,8 @@ function defineCuratedSiteStyle(input) {
11620
11750
  name: input.name,
11621
11751
  description: input.description,
11622
11752
  generationBrief: input.generationBrief,
11623
- selectionKeywords: input.selectionKeywords ?? [],
11753
+ selectionKeywordRules: input.selectionKeywordRules ?? [],
11754
+ siteCreatorSelection: input.siteCreatorSelection ?? { kind: "explicit_only" },
11624
11755
  template: {
11625
11756
  id: asDesignSystemTemplateId(`template:${input.id.replace("site-style:", "")}`),
11626
11757
  name: input.name,
@@ -11764,12 +11895,13 @@ var curatedSiteStyles = [
11764
11895
  name: "Quiet Luxury",
11765
11896
  description: "Minimal, confident, and refined for premium experiences and private services.",
11766
11897
  generationBrief: "Use fewer claims, more specificity, and restrained sensory detail. Favor elegant media and low repetition over dense panels.",
11767
- selectionKeywords: [
11768
- "luxury",
11769
- "premium",
11770
- "boutique",
11771
- "bespoke",
11772
- "exclusive"
11898
+ siteCreatorSelection: { kind: "site_creator_keyword_heuristic", priority: 20 },
11899
+ selectionKeywordRules: [
11900
+ { kind: "word", value: "luxury" },
11901
+ { kind: "word", value: "premium" },
11902
+ { kind: "word", value: "boutique" },
11903
+ { kind: "word", value: "bespoke" },
11904
+ { kind: "word", value: "exclusive" }
11773
11905
  ],
11774
11906
  tokenRecipes: {
11775
11907
  palette: "high-contrast",
@@ -11798,13 +11930,14 @@ var curatedSiteStyles = [
11798
11930
  name: "Practical Services",
11799
11931
  description: "Efficient, plainspoken, and conversion-focused for trades and everyday services.",
11800
11932
  generationBrief: "Make services, location, trust signals, and contact paths obvious. Keep copy brief and avoid ornate visual treatments.",
11801
- selectionKeywords: [
11802
- "repair",
11803
- "plumb",
11804
- "electric",
11805
- "cleaning",
11806
- "landscap",
11807
- "contractor"
11933
+ siteCreatorSelection: { kind: "primary_goal_support" },
11934
+ selectionKeywordRules: [
11935
+ { kind: "word", value: "repair" },
11936
+ { kind: "substring", value: "plumb" },
11937
+ { kind: "substring", value: "electric" },
11938
+ { kind: "word", value: "cleaning" },
11939
+ { kind: "substring", value: "landscap" },
11940
+ { kind: "substring", value: "contractor" }
11808
11941
  ],
11809
11942
  tokenRecipes: {
11810
11943
  palette: "brand-led",
@@ -11855,18 +11988,134 @@ var curatedSiteStyles = [
11855
11988
  paletteChoice("warm-neutral-forest")
11856
11989
  ]
11857
11990
  }),
11991
+ defineCuratedSiteStyle({
11992
+ id: "site-style:quiet-practice",
11993
+ name: "Quiet Practice",
11994
+ description: "Grounded, calm, and practical for small appointment-first practices.",
11995
+ 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.",
11996
+ siteCreatorSelection: { kind: "site_creator_keyword_heuristic", priority: 30 },
11997
+ selectionKeywordRules: [
11998
+ { kind: "substring", value: "massage" },
11999
+ { kind: "word", value: "bodywork" },
12000
+ { kind: "phrase", value: "appointment practice" },
12001
+ { kind: "phrase", value: "appointment-first" },
12002
+ { kind: "substring", value: "practitioner" },
12003
+ { kind: "substring", value: "therap" },
12004
+ { kind: "substring", value: "clinic" },
12005
+ { kind: "phrase", value: "wellness practice" }
12006
+ ],
12007
+ tokenRecipes: {
12008
+ palette: "soft-natural",
12009
+ contrast: "standard",
12010
+ radius: "soft",
12011
+ shadow: "subtle",
12012
+ typography: "clean-sans",
12013
+ spacing: "regular",
12014
+ motion: "subtle"
12015
+ },
12016
+ compositionBudget: quietBudget,
12017
+ recommendedHeaderLookIds: ["practical-utility", "clean-base", "centered-calm"],
12018
+ buttonPersonalityChoices: [
12019
+ buttonChoice("pebble"),
12020
+ buttonChoice("soft-pill"),
12021
+ buttonChoice("editorial-link")
12022
+ ],
12023
+ paletteVariantChoices: [
12024
+ paletteChoice("soft-natural-stone"),
12025
+ paletteChoice("soft-natural-sage"),
12026
+ paletteChoice("warm-neutral-clay")
12027
+ ]
12028
+ }),
12029
+ defineCuratedSiteStyle({
12030
+ id: "site-style:personal-retreat-journal",
12031
+ name: "Personal Retreat Journal",
12032
+ description: "Warm, story-led, and readable for solo practitioners with mixed offers.",
12033
+ 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.",
12034
+ siteCreatorSelection: { kind: "site_creator_keyword_heuristic", priority: 40 },
12035
+ selectionKeywordRules: [
12036
+ { kind: "substring", value: "retreat" },
12037
+ { kind: "phrase", value: "solo practitioner" },
12038
+ { kind: "phrase", value: "personal brand" },
12039
+ { kind: "substring", value: "teacher" },
12040
+ { kind: "substring", value: "coach" },
12041
+ { kind: "phrase", value: "retreat resources" },
12042
+ { kind: "substring", value: "journal" }
12043
+ ],
12044
+ tokenRecipes: {
12045
+ palette: "warm-neutral",
12046
+ contrast: "standard",
12047
+ radius: "soft",
12048
+ shadow: "subtle",
12049
+ typography: "serif-editorial",
12050
+ spacing: "airy",
12051
+ motion: "subtle"
12052
+ },
12053
+ compositionBudget: balancedBudget,
12054
+ recommendedHeaderLookIds: ["editorial-line", "centered-calm", "minimal-transparent"],
12055
+ buttonPersonalityChoices: [
12056
+ buttonChoice("editorial-link"),
12057
+ buttonChoice("soft-pill"),
12058
+ buttonChoice("brushed-wash")
12059
+ ],
12060
+ paletteVariantChoices: [
12061
+ paletteChoice("warm-neutral-forest"),
12062
+ paletteChoice("warm-neutral-clay"),
12063
+ paletteChoice("soft-natural-stone")
12064
+ ]
12065
+ }),
12066
+ defineCuratedSiteStyle({
12067
+ id: "site-style:tactile-workshop",
12068
+ name: "Tactile Workshop",
12069
+ description: "Bright, hands-on, and image-led for maker studios, workshops, and creative classes.",
12070
+ 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.",
12071
+ siteCreatorSelection: { kind: "site_creator_keyword_heuristic", priority: 50 },
12072
+ selectionKeywordRules: [
12073
+ { kind: "substring", value: "ceramic" },
12074
+ { kind: "word", value: "pottery" },
12075
+ { kind: "phrase", value: "maker studio" },
12076
+ { kind: "phrase", value: "craft class" },
12077
+ { kind: "phrase", value: "craft workshop" },
12078
+ { kind: "word", value: "clay" },
12079
+ { kind: "word", value: "kiln" }
12080
+ ],
12081
+ tokenRecipes: {
12082
+ palette: "brand-led",
12083
+ contrast: "standard",
12084
+ radius: "soft",
12085
+ shadow: "subtle",
12086
+ typography: "friendly-sans",
12087
+ spacing: "regular",
12088
+ motion: "subtle"
12089
+ },
12090
+ compositionBudget: balancedBudget,
12091
+ recommendedHeaderLookIds: ["brand-solid", "practical-utility", "clean-base"],
12092
+ recommendedFooterLookIds: ["site-footer-brand-two-band", "footer-muted-grounding"],
12093
+ buttonPersonalityChoices: [
12094
+ buttonChoice("pebble"),
12095
+ buttonChoice("confident-chip"),
12096
+ buttonChoice("ink-stamp"),
12097
+ buttonChoice("editorial-link")
12098
+ ],
12099
+ paletteVariantChoices: [
12100
+ paletteChoice("brand-led-warm"),
12101
+ paletteChoice("brand-led-cool"),
12102
+ paletteChoice("soft-natural-watercolor"),
12103
+ paletteChoice("warm-neutral-clay")
12104
+ ]
12105
+ }),
11858
12106
  defineCuratedSiteStyle({
11859
12107
  id: "site-style:bold-launch",
11860
12108
  name: "Bold Launch",
11861
12109
  description: "High-energy and punchy for launches, campaigns, and creative offers.",
11862
12110
  generationBrief: "Use crisp positioning, bold hero structure, strong calls to action, and confident visual rhythm. Keep it precise, not shouty.",
11863
- selectionKeywords: [
11864
- "launch",
11865
- "campaign",
11866
- "preorder",
11867
- "pre-order",
11868
- "waitlist",
11869
- "drop"
12111
+ siteCreatorSelection: { kind: "site_creator_keyword_heuristic", priority: 10 },
12112
+ selectionKeywordRules: [
12113
+ { kind: "substring", value: "launch" },
12114
+ { kind: "substring", value: "campaign" },
12115
+ { kind: "word", value: "preorder" },
12116
+ { kind: "phrase", value: "pre-order" },
12117
+ { kind: "substring", value: "waitlist" },
12118
+ { kind: "word", value: "drop" }
11870
12119
  ],
11871
12120
  tokenRecipes: {
11872
12121
  palette: "high-contrast",
@@ -11897,15 +12146,6 @@ var curatedSiteStyles = [
11897
12146
  name: "South West Twerk School",
11898
12147
  description: "Energetic, editorial, and high-contrast for a branded dance school presence.",
11899
12148
  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.",
11900
- selectionKeywords: [
11901
- "dance",
11902
- "classes",
11903
- "workshop",
11904
- "school",
11905
- "movement",
11906
- "performance",
11907
- "community"
11908
- ],
11909
12149
  tokenRecipes: {
11910
12150
  palette: "brand-led",
11911
12151
  contrast: "maximum",
@@ -12212,25 +12452,19 @@ var defaultDesignRuntimeRules = defineDesignRuntimeRules({
12212
12452
  "muted-band": {
12213
12453
  background: {
12214
12454
  type: "color",
12215
- color: "muted",
12216
- textColor: "text",
12217
- headingColor: "text"
12455
+ color: "muted"
12218
12456
  }
12219
12457
  },
12220
12458
  "accent-band": {
12221
12459
  background: {
12222
12460
  type: "color",
12223
- color: "primary",
12224
- textColor: "primaryForeground",
12225
- headingColor: "primaryForeground"
12461
+ color: "primary"
12226
12462
  }
12227
12463
  },
12228
12464
  "brand-depth-band": {
12229
12465
  background: {
12230
12466
  type: "color",
12231
- color: "primary-800",
12232
- textColor: "primaryForeground",
12233
- headingColor: "primaryForeground"
12467
+ color: "primary-800"
12234
12468
  }
12235
12469
  },
12236
12470
  "hero-image": {
@@ -18338,6 +18572,16 @@ var jsonArrayTransform = {
18338
18572
  return "";
18339
18573
  }
18340
18574
  };
18575
+ var csvTransform = {
18576
+ id: "value.csv",
18577
+ kind: "formatter",
18578
+ summary: "Normalize a string or array of strings into a comma-separated list",
18579
+ run: (value) => {
18580
+ const rawValues = Array.isArray(value) ? value : typeof value === "string" ? value.split(",") : [];
18581
+ const normalized = rawValues.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean);
18582
+ return normalized.length > 0 ? Array.from(new Set(normalized)).join(",") : "";
18583
+ }
18584
+ };
18341
18585
  var marqueeLoopOptionsSchema = z36.object({
18342
18586
  minItems: z36.number().int().min(1).default(10)
18343
18587
  });
@@ -18363,6 +18607,7 @@ var formattingTransforms = [
18363
18607
  dateFormatShort,
18364
18608
  arrayLengthTransform,
18365
18609
  jsonArrayTransform,
18610
+ csvTransform,
18366
18611
  marqueeLoopTransform
18367
18612
  ];
18368
18613
 
@@ -18846,73 +19091,6 @@ var uiTransforms = [
18846
19091
 
18847
19092
  // ../blocks/src/system/transforms/registry/layout.ts
18848
19093
  import { z as z38 } from "zod";
18849
-
18850
- // ../theme-core/src/palette/utils/colorConversion.ts
18851
- var mod = (a, n) => (a % n + n) % n;
18852
- var deg = (x) => mod(x, 360);
18853
- function hexToRgb(hex) {
18854
- const h = hex.replace(/^#/, "");
18855
- const m = h.length === 3 ? h.split("").map((c) => c + c).join("") : h;
18856
- if (m.length !== 6) throw new Error("Bad hex");
18857
- const int = parseInt(m, 16);
18858
- return { r: int >> 16 & 255, g: int >> 8 & 255, b: int & 255 };
18859
- }
18860
- function srgbToLinear(u) {
18861
- const x = u / 255;
18862
- return x <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);
18863
- }
18864
- function rgbToHsl(r, g, b) {
18865
- const R = r / 255, G = g / 255, B = b / 255;
18866
- const max = Math.max(R, G, B), min = Math.min(R, G, B);
18867
- const d = max - min;
18868
- let h = 0;
18869
- if (d !== 0) {
18870
- switch (max) {
18871
- case R:
18872
- h = (G - B) / d + (G < B ? 6 : 0);
18873
- break;
18874
- case G:
18875
- h = (B - R) / d + 2;
18876
- break;
18877
- case B:
18878
- h = (R - G) / d + 4;
18879
- break;
18880
- }
18881
- h *= 60;
18882
- }
18883
- const l = (max + min) / 2;
18884
- const s = d === 0 ? 0 : d / (1 - Math.abs(2 * l - 1));
18885
- return { h, s, l };
18886
- }
18887
- function srgbToOklab(r, g, b) {
18888
- const R = srgbToLinear(r), G = srgbToLinear(g), B = srgbToLinear(b);
18889
- const l = 0.4122214708 * R + 0.5363325363 * G + 0.0514459929 * B;
18890
- const m = 0.2119034982 * R + 0.6806995451 * G + 0.1073969566 * B;
18891
- const s = 0.0883024619 * R + 0.2817188376 * G + 0.6299787005 * B;
18892
- const l_ = Math.cbrt(l), m_ = Math.cbrt(m), s_ = Math.cbrt(s);
18893
- const L = 0.2104542553 * l_ + 0.793617785 * m_ - 0.0040720468 * s_;
18894
- const a = 1.9779984951 * l_ - 2.428592205 * m_ + 0.4505937099 * s_;
18895
- const b2 = 0.0259040371 * l_ + 0.7827717662 * m_ - 0.808675766 * s_;
18896
- return { L, a, b: b2 };
18897
- }
18898
- function oklabToOklch(L, a, b) {
18899
- const C = Math.sqrt(a * a + b * b);
18900
- const h = C < 1e-7 ? 0 : deg(Math.atan2(b, a) * 180 / Math.PI);
18901
- return { L, C, h };
18902
- }
18903
- function featuresFromHex(hex) {
18904
- const { r, g, b } = hexToRgb(hex);
18905
- const { h, s, l } = rgbToHsl(r, g, b);
18906
- const { L, a, b: b2 } = srgbToOklab(r, g, b);
18907
- const { L: okL, C: okC, h: okH } = oklabToOklch(L, a, b2);
18908
- const max = Math.max(r, g, b);
18909
- const v = max / 255;
18910
- const Y = 0.2126 * srgbToLinear(r) + 0.7152 * srgbToLinear(g) + 0.0722 * srgbToLinear(b);
18911
- const chroma = s;
18912
- return { r, g, b, h, s, l, v, Y, chroma, okL, okC, okH, hex };
18913
- }
18914
-
18915
- // ../blocks/src/system/transforms/registry/layout.ts
18916
19094
  var joinClasses4 = (parts) => parts.filter(
18917
19095
  (part) => typeof part === "string" && part.trim().length > 0
18918
19096
  ).join(" ").replace(/\s+/g, " ").trim();
@@ -23596,7 +23774,12 @@ var eventListingBlockDefinition = {
23596
23774
  detailLevel: "listing",
23597
23775
  kind: { $bind: { from: "content.kind" } },
23598
23776
  eventSurface: { $bind: { from: "content.eventSurface" } },
23599
- eventPresets: { $bind: { from: "content.filterEventPresets" } },
23777
+ eventPresets: {
23778
+ $bind: {
23779
+ from: "content.filterEventPresets",
23780
+ transforms: [{ id: "value.csv" }]
23781
+ }
23782
+ },
23600
23783
  scheduleScope: { $bind: { from: "content.scheduleScope" } }
23601
23784
  },
23602
23785
  mode: "server"
@@ -24348,7 +24531,12 @@ var eventCalendarBlockDefinition = {
24348
24531
  // Pass filter params if configured
24349
24532
  kind: { $bind: { from: "content.kind" } },
24350
24533
  eventSurface: { $bind: { from: "content.eventSurface" } },
24351
- eventPresets: { $bind: { from: "content.filterEventPresets" } },
24534
+ eventPresets: {
24535
+ $bind: {
24536
+ from: "content.filterEventPresets",
24537
+ transforms: [{ id: "value.csv" }]
24538
+ }
24539
+ },
24352
24540
  scheduleScope: { $bind: { from: "content.scheduleScope" } },
24353
24541
  categoryIds: { $bind: { from: "content.filterCategoryIds" } },
24354
24542
  staffMemberId: { $bind: { from: "content.filterStaffMemberId" } },