@orion-studios/payload-studio 0.5.0-beta.3 → 0.5.0-beta.30

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 (46) hide show
  1. package/dist/admin/client.js +68 -7
  2. package/dist/admin/client.mjs +68 -7
  3. package/dist/admin/index.d.mts +1 -1
  4. package/dist/admin/index.d.ts +1 -1
  5. package/dist/admin/index.js +37 -0
  6. package/dist/admin/index.mjs +3 -1
  7. package/dist/admin-app/client.d.mts +4 -0
  8. package/dist/admin-app/client.d.ts +4 -0
  9. package/dist/admin-app/client.js +705 -2
  10. package/dist/admin-app/client.mjs +701 -1
  11. package/dist/admin-app/index.d.mts +1 -1
  12. package/dist/admin-app/index.d.ts +1 -1
  13. package/dist/admin-app/index.js +167 -0
  14. package/dist/admin-app/index.mjs +13 -1
  15. package/dist/admin-app/styles.css +127 -0
  16. package/dist/blocks/index.js +193 -3
  17. package/dist/blocks/index.mjs +2 -2
  18. package/dist/{chunk-J7W5EE3B.mjs → chunk-7IGLXLUB.mjs} +37 -0
  19. package/dist/{chunk-ZLLNO5FM.mjs → chunk-GPQPDEB5.mjs} +44 -13
  20. package/dist/{chunk-PC5622T7.mjs → chunk-H7DSTEVT.mjs} +180 -4
  21. package/dist/{chunk-UJFU323N.mjs → chunk-QW24Y4UH.mjs} +18 -8
  22. package/dist/{chunk-ETRRXURT.mjs → chunk-SIL2J5MF.mjs} +14 -0
  23. package/dist/chunk-XVH5SCBD.mjs +234 -0
  24. package/dist/index-BBvk9b9i.d.mts +97 -0
  25. package/dist/index-BBvk9b9i.d.ts +97 -0
  26. package/dist/{index-DbH0Ljwp.d.mts → index-CpG3UHcS.d.mts} +1 -0
  27. package/dist/{index-DbH0Ljwp.d.ts → index-CpG3UHcS.d.ts} +1 -0
  28. package/dist/{index-DJFhANvJ.d.ts → index-Dj21uD_B.d.mts} +5 -2
  29. package/dist/{index-DJFhANvJ.d.mts → index-Dj21uD_B.d.ts} +5 -2
  30. package/dist/index.d.mts +3 -3
  31. package/dist/index.d.ts +3 -3
  32. package/dist/index.js +674 -250
  33. package/dist/index.mjs +11 -11
  34. package/dist/nextjs/index.d.mts +1 -1
  35. package/dist/nextjs/index.d.ts +1 -1
  36. package/dist/nextjs/index.js +276 -13
  37. package/dist/nextjs/index.mjs +4 -1
  38. package/dist/studio-pages/builder.css +25 -1
  39. package/dist/studio-pages/client.js +2063 -1118
  40. package/dist/studio-pages/client.mjs +2063 -1118
  41. package/dist/studio-pages/index.js +18 -7
  42. package/dist/studio-pages/index.mjs +2 -2
  43. package/package.json +2 -2
  44. package/dist/chunk-AAOHJDNS.mjs +0 -67
  45. package/dist/index-BallJs-K.d.mts +0 -43
  46. package/dist/index-BallJs-K.d.ts +0 -43
@@ -42,6 +42,7 @@ var sectionStyleDefaults = {
42
42
  contentGradientPreset: "none",
43
43
  contentGradientTo: "#f4f6f2",
44
44
  contentWidth: "inherit",
45
+ sectionPaddingX: "inherit",
45
46
  sectionBackgroundColor: "#ffffff",
46
47
  sectionBackgroundMode: "none",
47
48
  sectionGradientAngle: "135",
@@ -69,6 +70,9 @@ var defaultNodeData = {
69
70
  items: [
70
71
  {
71
72
  description: "Before and after result summary.",
73
+ imageCornerStyle: "rounded",
74
+ imageFit: "cover",
75
+ imagePosition: "center",
72
76
  label: "Project One"
73
77
  }
74
78
  ],
@@ -92,9 +96,9 @@ var defaultNodeData = {
92
96
  featureGrid: {
93
97
  ...withSectionStyleDefaults({}),
94
98
  items: [
95
- { description: "Explain this point.", icon: "01", title: "Feature One" },
96
- { description: "Explain this point.", icon: "02", title: "Feature Two" },
97
- { description: "Explain this point.", icon: "03", title: "Feature Three" }
99
+ { description: "Explain this point.", icon: "01", imageCornerStyle: "rounded", imageFit: "cover", imagePosition: "center", title: "Feature One" },
100
+ { description: "Explain this point.", icon: "02", imageCornerStyle: "rounded", imageFit: "cover", imagePosition: "center", title: "Feature Two" },
101
+ { description: "Explain this point.", icon: "03", imageCornerStyle: "rounded", imageFit: "cover", imagePosition: "center", title: "Feature Three" }
98
102
  ],
99
103
  title: "Section Title",
100
104
  variant: "cards"
@@ -107,7 +111,11 @@ var defaultNodeData = {
107
111
  },
108
112
  hero: {
109
113
  ...withSectionStyleDefaults({}),
110
- backgroundColor: "#124a37",
114
+ backgroundColor: "",
115
+ backgroundImageCornerStyle: "rounded",
116
+ backgroundImageFit: "cover",
117
+ backgroundImagePosition: "center",
118
+ heroHeight: "sm",
111
119
  headline: "New Hero Section",
112
120
  kicker: "Optional kicker",
113
121
  primaryHref: "/contact",
@@ -120,13 +128,16 @@ var defaultNodeData = {
120
128
  media: {
121
129
  ...withSectionStyleDefaults({}),
122
130
  caption: "Add a caption",
131
+ imageCornerStyle: "rounded",
132
+ imageFit: "cover",
133
+ imagePosition: "center",
123
134
  size: "default"
124
135
  },
125
136
  logoWall: withSectionStyleDefaults({
126
137
  items: [
127
- { name: "Trusted Partner 1" },
128
- { name: "Trusted Partner 2" },
129
- { name: "Trusted Partner 3" }
138
+ { imageCornerStyle: "rounded", imageFit: "contain", imagePosition: "center", name: "Trusted Partner 1" },
139
+ { imageCornerStyle: "rounded", imageFit: "contain", imagePosition: "center", name: "Trusted Partner 2" },
140
+ { imageCornerStyle: "rounded", imageFit: "contain", imagePosition: "center", name: "Trusted Partner 3" }
130
141
  ],
131
142
  subtitle: "Trusted by teams and homeowners across Central Texas.",
132
143
  title: "Trusted by Local Organizations"
@@ -453,6 +464,61 @@ var resolveMedia = (value) => {
453
464
  }
454
465
  return null;
455
466
  };
467
+ var normalizeHeroImageFit = (value) => {
468
+ if (value === "contain" || value === "contain-square") {
469
+ return "contain";
470
+ }
471
+ return "cover";
472
+ };
473
+ var normalizeHeroImageCornerStyle = (value, legacyFitValue) => {
474
+ if (value === "rounded" || value === "square") {
475
+ return value;
476
+ }
477
+ if (legacyFitValue === "cover-square" || legacyFitValue === "contain-square") {
478
+ return "square";
479
+ }
480
+ return "rounded";
481
+ };
482
+ var getHeroImageCornerRadius = (cornerStyle) => cornerStyle === "square" ? "0px" : "var(--orion-studio-radius-lg)";
483
+ var normalizeHeroImagePosition = (value) => {
484
+ if (value === "top" || value === "bottom" || value === "left" || value === "right") {
485
+ return value;
486
+ }
487
+ return "center";
488
+ };
489
+ var normalizeHeroHeight = (value) => {
490
+ if (value === "md" || value === "full") {
491
+ return value;
492
+ }
493
+ return "sm";
494
+ };
495
+ var heroHeightMap = {
496
+ sm: "360px",
497
+ md: "50svh",
498
+ full: "100svh"
499
+ };
500
+ var normalizeImageFit = (value) => normalizeHeroImageFit(value);
501
+ var normalizeImageCornerStyle = (value, legacyFitValue) => normalizeHeroImageCornerStyle(value, legacyFitValue);
502
+ var normalizeImagePosition = (value) => normalizeHeroImagePosition(value);
503
+ var imageObjectPosition = (value) => {
504
+ switch (value) {
505
+ case "top":
506
+ return "center top";
507
+ case "bottom":
508
+ return "center bottom";
509
+ case "left":
510
+ return "left center";
511
+ case "right":
512
+ return "right center";
513
+ default:
514
+ return "center center";
515
+ }
516
+ };
517
+ var getImagePresentationStyle = (options) => ({
518
+ borderRadius: options.cornerStyle === "square" ? 0 : `${options.roundedRadius ?? 12}px`,
519
+ objectFit: options.fit || "cover",
520
+ objectPosition: imageObjectPosition(options.position || "center")
521
+ });
456
522
  function cloneBlockLayout(layout) {
457
523
  return JSON.parse(JSON.stringify(layout));
458
524
  }
@@ -543,6 +609,7 @@ var defaultSectionStyle = {
543
609
  contentGradientPreset: "none",
544
610
  contentGradientTo: "#f4f6f2",
545
611
  contentWidth: "inherit",
612
+ sectionPaddingX: "inherit",
546
613
  sectionBackgroundColor: "#ffffff",
547
614
  sectionBackgroundMode: "none",
548
615
  sectionGradientAngle: "135",
@@ -564,6 +631,7 @@ var gradientPresetPairs = {
564
631
  slate: ["#1a2f2a", "#34524a"]
565
632
  };
566
633
  var sectionPaddingMap = {
634
+ none: "0px",
567
635
  sm: "1.4rem",
568
636
  md: "2.6rem",
569
637
  lg: "3.4rem"
@@ -590,8 +658,12 @@ function getDefaultBlock(blockType) {
590
658
  switch (blockType) {
591
659
  case "hero":
592
660
  return withSectionStyleDefaults2({
593
- backgroundColor: "#124a37",
661
+ backgroundColor: "",
662
+ backgroundImageCornerStyle: "rounded",
663
+ backgroundImageFit: "cover",
664
+ backgroundImagePosition: "center",
594
665
  blockType: "hero",
666
+ heroHeight: "sm",
595
667
  headline: "New Hero Section",
596
668
  kicker: "Optional kicker",
597
669
  primaryHref: "/contact",
@@ -606,9 +678,9 @@ function getDefaultBlock(blockType) {
606
678
  backgroundColor: "#1f684f",
607
679
  blockType: "featureGrid",
608
680
  items: [
609
- { description: "Explain this point.", icon: "01", title: "Feature One" },
610
- { description: "Explain this point.", icon: "02", title: "Feature Two" },
611
- { description: "Explain this point.", icon: "03", title: "Feature Three" }
681
+ { description: "Explain this point.", icon: "01", imageCornerStyle: "rounded", imageFit: "cover", imagePosition: "center", title: "Feature One" },
682
+ { description: "Explain this point.", icon: "02", imageCornerStyle: "rounded", imageFit: "cover", imagePosition: "center", title: "Feature Two" },
683
+ { description: "Explain this point.", icon: "03", imageCornerStyle: "rounded", imageFit: "cover", imagePosition: "center", title: "Feature Three" }
612
684
  ],
613
685
  title: "Section Title",
614
686
  variant: "cards"
@@ -627,14 +699,18 @@ function getDefaultBlock(blockType) {
627
699
  case "logoWall":
628
700
  return withSectionStyleDefaults2({
629
701
  blockType: "logoWall",
630
- items: [{ name: "Partner One" }, { name: "Partner Two" }, { name: "Partner Three" }],
702
+ items: [
703
+ { imageCornerStyle: "rounded", imageFit: "contain", imagePosition: "center", name: "Partner One" },
704
+ { imageCornerStyle: "rounded", imageFit: "contain", imagePosition: "center", name: "Partner Two" },
705
+ { imageCornerStyle: "rounded", imageFit: "contain", imagePosition: "center", name: "Partner Three" }
706
+ ],
631
707
  subtitle: "Show logos from trusted organizations.",
632
708
  title: "Trusted by Local Partners"
633
709
  });
634
710
  case "beforeAfter":
635
711
  return withSectionStyleDefaults2({
636
712
  blockType: "beforeAfter",
637
- items: [{ description: "Project result summary.", label: "Project One" }],
713
+ items: [{ description: "Project result summary.", imageCornerStyle: "rounded", imageFit: "cover", imagePosition: "center", label: "Project One" }],
638
714
  subtitle: "Visual proof from completed projects.",
639
715
  title: "Before & After Results"
640
716
  });
@@ -649,6 +725,9 @@ function getDefaultBlock(blockType) {
649
725
  return withSectionStyleDefaults2({
650
726
  blockType: "media",
651
727
  caption: "Add a caption",
728
+ imageCornerStyle: "rounded",
729
+ imageFit: "cover",
730
+ imagePosition: "center",
652
731
  size: "default"
653
732
  });
654
733
  case "testimonials":
@@ -718,20 +797,40 @@ function parseAngle(value, fallback = "135") {
718
797
  var sectionStyleFromBlock = (block, pageDefaults) => {
719
798
  const contentWidthRaw = normalizeText(block.contentWidth, defaultSectionStyle.contentWidth);
720
799
  const sectionPaddingRaw = normalizeText(block.sectionPaddingY, defaultSectionStyle.sectionPaddingY);
721
- const sectionPaddingY = sectionPaddingRaw === "sm" || sectionPaddingRaw === "lg" ? sectionPaddingRaw : "md";
800
+ const sectionPaddingXRaw = normalizeText(block.sectionPaddingX, defaultSectionStyle.sectionPaddingX);
801
+ const sectionPaddingY = sectionPaddingRaw === "none" || sectionPaddingRaw === "sm" || sectionPaddingRaw === "lg" ? sectionPaddingRaw : "md";
802
+ const sectionPaddingX = sectionPaddingXRaw === "none" || sectionPaddingXRaw === "sm" || sectionPaddingXRaw === "md" || sectionPaddingXRaw === "lg" ? sectionPaddingXRaw : pageDefaults.pageWidthDefault === "full" ? "none" : "md";
722
803
  const contentWidth = contentWidthRaw === "narrow" || contentWidthRaw === "content" || contentWidthRaw === "wide" || contentWidthRaw === "full" || contentWidthRaw === "inherit" ? contentWidthRaw : "inherit";
723
804
  const resolvedContentWidth = contentWidth === "inherit" ? pageDefaults.pageWidthDefault : contentWidth;
724
805
  const sectionMode = normalizeText(block.sectionBackgroundMode, defaultSectionStyle.sectionBackgroundMode);
725
- const sectionColor = parseColor(block.sectionBackgroundColor, defaultSectionStyle.sectionBackgroundColor);
806
+ const sectionColor = parseColor(
807
+ normalizeText(block.sectionBackgroundColor, ""),
808
+ normalizeText(defaultSectionStyle.sectionBackgroundColor, "#ffffff")
809
+ );
726
810
  const sectionPreset = normalizeText(block.sectionGradientPreset, defaultSectionStyle.sectionGradientPreset);
727
- const sectionFrom = parseColor(block.sectionGradientFrom, defaultSectionStyle.sectionGradientFrom);
728
- const sectionTo = parseColor(block.sectionGradientTo, defaultSectionStyle.sectionGradientTo);
811
+ const sectionFrom = parseColor(
812
+ normalizeText(block.sectionGradientFrom, ""),
813
+ normalizeText(defaultSectionStyle.sectionGradientFrom, "#124a37")
814
+ );
815
+ const sectionTo = parseColor(
816
+ normalizeText(block.sectionGradientTo, ""),
817
+ normalizeText(defaultSectionStyle.sectionGradientTo, "#1f684f")
818
+ );
729
819
  const sectionAngle = parseAngle(block.sectionGradientAngle, defaultSectionStyle.sectionGradientAngle);
730
820
  const contentMode = normalizeText(block.contentBackgroundMode, defaultSectionStyle.contentBackgroundMode);
731
- const contentColor = parseColor(block.contentBackgroundColor, defaultSectionStyle.contentBackgroundColor);
821
+ const contentColor = parseColor(
822
+ normalizeText(block.contentBackgroundColor, ""),
823
+ normalizeText(defaultSectionStyle.contentBackgroundColor, "#ffffff")
824
+ );
732
825
  const contentPreset = normalizeText(block.contentGradientPreset, defaultSectionStyle.contentGradientPreset);
733
- const contentFrom = parseColor(block.contentGradientFrom, defaultSectionStyle.contentGradientFrom);
734
- const contentTo = parseColor(block.contentGradientTo, defaultSectionStyle.contentGradientTo);
826
+ const contentFrom = parseColor(
827
+ normalizeText(block.contentGradientFrom, ""),
828
+ normalizeText(defaultSectionStyle.contentGradientFrom, "#ffffff")
829
+ );
830
+ const contentTo = parseColor(
831
+ normalizeText(block.contentGradientTo, ""),
832
+ normalizeText(defaultSectionStyle.contentGradientTo, "#f4f6f2")
833
+ );
735
834
  const contentAngle = parseAngle(block.contentGradientAngle, defaultSectionStyle.contentGradientAngle);
736
835
  const sectionPresetPair = gradientPresetPairs[sectionPreset];
737
836
  const contentPresetPair = gradientPresetPairs[contentPreset];
@@ -742,18 +841,20 @@ var sectionStyleFromBlock = (block, pageDefaults) => {
742
841
  contentStyle: contentMode === "color" ? {
743
842
  background: contentColor,
744
843
  borderRadius: 20,
745
- boxShadow: "0 8px 20px rgba(13, 74, 55, 0.08)"
844
+ boxShadow: "0 8px 20px rgba(13, 74, 55, 0.08)",
845
+ padding: "1rem"
746
846
  } : contentMode === "gradient" ? {
747
847
  background: contentGradient,
748
848
  borderRadius: 20,
749
- boxShadow: "0 8px 20px rgba(13, 74, 55, 0.08)"
849
+ boxShadow: "0 8px 20px rgba(13, 74, 55, 0.08)",
850
+ padding: "1rem"
750
851
  } : {},
751
- sectionClass: `orion-builder-shell is-${pageDefaults.pageWidthDefault}`,
852
+ sectionClass: `orion-builder-shell is-${pageDefaults.pageWidthDefault} padx-${sectionPaddingX}`,
752
853
  sectionInnerStyle: {
753
854
  paddingBottom: sectionPaddingMap[sectionPaddingY],
754
855
  paddingTop: sectionPaddingMap[sectionPaddingY]
755
856
  },
756
- sectionStyle: sectionMode === "color" ? { background: sectionColor } : sectionMode === "gradient" ? { background: sectionGradient } : {}
857
+ sectionStyle: sectionMode === "color" ? { background: sectionColor } : sectionMode === "gradient" ? { background: sectionGradient } : block.blockType === "hero" ? { background: "transparent" } : {}
757
858
  };
758
859
  };
759
860
  function getRelationID(value) {
@@ -771,6 +872,19 @@ function getRelationID(value) {
771
872
  }
772
873
  return null;
773
874
  }
875
+ function getMediaURL(value) {
876
+ if (!value || typeof value !== "object") {
877
+ return "";
878
+ }
879
+ const typed = value;
880
+ if (typeof typed.url === "string" && typed.url.trim().length > 0) {
881
+ return typed.url.trim();
882
+ }
883
+ if (typeof typed.filename === "string" && typed.filename.trim().length > 0) {
884
+ return `/api/media/file/${encodeURIComponent(typed.filename)}`;
885
+ }
886
+ return "";
887
+ }
774
888
  function extractUploadedMedia(value) {
775
889
  const candidate = value && typeof value === "object" && "doc" in value ? value.doc : value;
776
890
  if (!candidate || typeof candidate !== "object") {
@@ -787,18 +901,58 @@ function extractUploadedMedia(value) {
787
901
  url: typeof candidate.url === "string" ? candidate.url : ""
788
902
  };
789
903
  }
790
- function getUploadedMediaURL(value) {
904
+ function toMediaLibraryItem(value) {
791
905
  if (!value || typeof value !== "object") {
792
- return "";
906
+ return null;
907
+ }
908
+ const id = getRelationID(value);
909
+ if (id === null) {
910
+ return null;
793
911
  }
794
912
  const typed = value;
795
- if (typeof typed.url === "string" && typed.url.length > 0) {
796
- return typed.url;
913
+ const filename = typeof typed.filename === "string" ? typed.filename : "";
914
+ const url = typeof typed.url === "string" && typed.url.length > 0 ? typed.url : filename ? `/api/media/file/${encodeURIComponent(filename)}` : "";
915
+ return {
916
+ alt: typeof typed.alt === "string" ? typed.alt : "",
917
+ filename,
918
+ id,
919
+ url
920
+ };
921
+ }
922
+ function mediaLabel(item) {
923
+ return item.filename || item.alt || `Media #${item.id}`;
924
+ }
925
+ function mediaFromLibraryItem(item) {
926
+ return {
927
+ alt: item.alt,
928
+ filename: item.filename,
929
+ id: item.id,
930
+ url: item.url
931
+ };
932
+ }
933
+ async function parsePayloadErrorMessage(response, fallbackMessage) {
934
+ const contentType = response.headers.get("content-type") || "";
935
+ if (!contentType.toLowerCase().includes("application/json")) {
936
+ const raw = await response.text();
937
+ return raw.trim() || fallbackMessage;
797
938
  }
798
- if (typeof typed.filename === "string" && typed.filename.length > 0) {
799
- return `/api/media/file/${encodeURIComponent(typed.filename)}`;
939
+ try {
940
+ const payload = await response.json();
941
+ const nestedMessage = payload.errors?.[0]?.data?.errors?.[0]?.message;
942
+ if (typeof nestedMessage === "string" && nestedMessage.trim().length > 0) {
943
+ return nestedMessage;
944
+ }
945
+ const topMessage = payload.errors?.[0]?.message;
946
+ if (typeof topMessage === "string" && topMessage.trim().length > 0) {
947
+ return topMessage;
948
+ }
949
+ if (typeof payload.message === "string" && payload.message.trim().length > 0) {
950
+ return payload.message;
951
+ }
952
+ } catch {
953
+ return fallbackMessage;
800
954
  }
801
- return "";
955
+ return fallbackMessage;
802
956
  }
803
957
  var MAX_DIRECT_UPLOAD_BYTES = 4e6;
804
958
  async function optimizeImageForUpload(file) {
@@ -1150,22 +1304,19 @@ function BuilderPageEditor({ initialDoc, pageID }) {
1150
1304
  const [dragIndex, setDragIndex] = (0, import_react.useState)(null);
1151
1305
  const [sidebarOpen, setSidebarOpen] = (0, import_react.useState)(true);
1152
1306
  const [savingStatus, setSavingStatus] = (0, import_react.useState)(null);
1153
- const [saveMessage, setSaveMessage] = (0, import_react.useState)("");
1154
- const [saveError, setSaveError] = (0, import_react.useState)("");
1155
1307
  const [uploadingTarget, setUploadingTarget] = (0, import_react.useState)(null);
1156
1308
  const [uploadError, setUploadError] = (0, import_react.useState)("");
1157
1309
  const [uploadMessage, setUploadMessage] = (0, import_react.useState)("");
1158
1310
  const [uploadAltText, setUploadAltText] = (0, import_react.useState)("");
1311
+ const [mediaLibrary, setMediaLibrary] = (0, import_react.useState)([]);
1312
+ const [mediaLibraryError, setMediaLibraryError] = (0, import_react.useState)("");
1313
+ const [mediaLibraryLoading, setMediaLibraryLoading] = (0, import_react.useState)(false);
1314
+ const [selectedHeroMediaID, setSelectedHeroMediaID] = (0, import_react.useState)("");
1159
1315
  const [presetQuery, setPresetQuery] = (0, import_react.useState)("");
1160
1316
  const [pastSnapshots, setPastSnapshots] = (0, import_react.useState)([]);
1161
1317
  const [futureSnapshots, setFutureSnapshots] = (0, import_react.useState)([]);
1162
- const [panelState, setPanelState] = (0, import_react.useState)({
1163
- addSections: true,
1164
- pageDefaults: true,
1165
- quickAdd: true,
1166
- save: true,
1167
- selected: true
1168
- });
1318
+ const isSidebarPanelKey = (value) => value === "pageDefaults" || value === "addSections" || value === "selected";
1319
+ const [activeSidebarPanel, setActiveSidebarPanel] = (0, import_react.useState)("selected");
1169
1320
  const historyBypassRef = (0, import_react.useRef)(true);
1170
1321
  const previousSnapshotRef = (0, import_react.useRef)({
1171
1322
  layout: cloneBlockLayout(initialLayout).map((block) => withSectionStyleDefaults2(block)),
@@ -1182,6 +1333,23 @@ function BuilderPageEditor({ initialDoc, pageID }) {
1182
1333
  ...defaultSectionStyle,
1183
1334
  ...selectedBlock || {}
1184
1335
  };
1336
+ const resolveMediaLibraryItemFromValue = (value) => {
1337
+ const direct = toMediaLibraryItem(value);
1338
+ if (direct) {
1339
+ return direct;
1340
+ }
1341
+ const relationID = getRelationID(value);
1342
+ if (relationID === null) {
1343
+ return null;
1344
+ }
1345
+ return mediaLibrary.find((item) => String(item.id) === String(relationID)) || null;
1346
+ };
1347
+ const selectedHeroMedia = (0, import_react.useMemo)(() => {
1348
+ if (selectedType !== "hero" || !selectedBlock) {
1349
+ return null;
1350
+ }
1351
+ return resolveMediaLibraryItemFromValue(selectedBlock.media);
1352
+ }, [mediaLibrary, selectedBlock, selectedType]);
1185
1353
  const filteredSectionPresets = (0, import_react.useMemo)(() => {
1186
1354
  const query = presetQuery.trim().toLowerCase();
1187
1355
  if (!query) {
@@ -1191,6 +1359,37 @@ function BuilderPageEditor({ initialDoc, pageID }) {
1191
1359
  (preset) => `${preset.title} ${preset.description}`.toLowerCase().includes(query)
1192
1360
  );
1193
1361
  }, [presetQuery]);
1362
+ (0, import_react.useEffect)(() => {
1363
+ const loadMediaLibrary = async () => {
1364
+ setMediaLibraryLoading(true);
1365
+ setMediaLibraryError("");
1366
+ try {
1367
+ const response = await fetch("/api/media?depth=1&limit=100&sort=-updatedAt", {
1368
+ credentials: "include"
1369
+ });
1370
+ if (!response.ok) {
1371
+ throw new Error("Could not load media library.");
1372
+ }
1373
+ const json = await response.json();
1374
+ const docs = Array.isArray(json.docs) ? json.docs : [];
1375
+ const items = docs.map((doc2) => toMediaLibraryItem(doc2)).filter((item) => item !== null);
1376
+ setMediaLibrary(items);
1377
+ } catch (error) {
1378
+ setMediaLibraryError(error instanceof Error ? error.message : "Could not load media library.");
1379
+ } finally {
1380
+ setMediaLibraryLoading(false);
1381
+ }
1382
+ };
1383
+ void loadMediaLibrary();
1384
+ }, []);
1385
+ (0, import_react.useEffect)(() => {
1386
+ if (selectedType !== "hero") {
1387
+ setSelectedHeroMediaID("");
1388
+ return;
1389
+ }
1390
+ const relationID = getRelationID(selectedBlock?.media);
1391
+ setSelectedHeroMediaID(relationID !== null ? String(relationID) : "");
1392
+ }, [selectedBlock, selectedType]);
1194
1393
  const applyTemplateStarter = () => {
1195
1394
  const templateBlocks = templateStarterPresets[pageTemplate] || templateStarterPresets.standard;
1196
1395
  const nextLayout = clonePresetBlocks(templateBlocks).map((block) => withSectionStyleDefaults2(block));
@@ -1275,6 +1474,55 @@ function BuilderPageEditor({ initialDoc, pageID }) {
1275
1474
  currentItems.filter((_, index) => index !== itemIndex)
1276
1475
  );
1277
1476
  };
1477
+ const setSelectedMediaFieldFromLibrary = (fieldName, mediaID) => {
1478
+ if (!mediaID) {
1479
+ updateSelectedField(fieldName, null);
1480
+ if (selectedType === "hero" && fieldName === "media") {
1481
+ updateSelectedField("backgroundImageURL", "");
1482
+ setSelectedHeroMediaID("");
1483
+ }
1484
+ return;
1485
+ }
1486
+ const selectedMedia = mediaLibrary.find((item) => String(item.id) === mediaID);
1487
+ if (!selectedMedia) {
1488
+ return;
1489
+ }
1490
+ updateSelectedField(fieldName, mediaFromLibraryItem(selectedMedia));
1491
+ if (selectedType === "hero" && fieldName === "media") {
1492
+ updateSelectedField("backgroundImageURL", selectedMedia.url);
1493
+ setSelectedHeroMediaID(String(selectedMedia.id));
1494
+ }
1495
+ };
1496
+ const setSelectedItemMediaFieldFromLibrary = (itemIndex, fieldName, mediaID) => {
1497
+ if (selectedIndex === null) {
1498
+ return;
1499
+ }
1500
+ if (!mediaID) {
1501
+ updateArrayItemField(selectedIndex, "items", itemIndex, fieldName, null);
1502
+ return;
1503
+ }
1504
+ const selectedMedia = mediaLibrary.find((item) => String(item.id) === mediaID);
1505
+ if (!selectedMedia) {
1506
+ return;
1507
+ }
1508
+ updateArrayItemField(selectedIndex, "items", itemIndex, fieldName, mediaFromLibraryItem(selectedMedia));
1509
+ };
1510
+ const setHeroMediaFromLibrary = (mediaID) => {
1511
+ if (selectedIndex === null || selectedType !== "hero") {
1512
+ return;
1513
+ }
1514
+ setSelectedMediaFieldFromLibrary("media", mediaID);
1515
+ };
1516
+ const clearHeroMedia = () => {
1517
+ if (selectedType !== "hero") {
1518
+ return;
1519
+ }
1520
+ updateSelectedField("media", null);
1521
+ updateSelectedField("backgroundImageURL", "");
1522
+ setSelectedHeroMediaID("");
1523
+ setUploadMessage("Hero image removed.");
1524
+ setUploadError("");
1525
+ };
1278
1526
  const uploadMediaForSelected = async (target, file) => {
1279
1527
  if (selectedIndex === null) {
1280
1528
  setUploadError("Select a section first.");
@@ -1300,8 +1548,7 @@ function BuilderPageEditor({ initialDoc, pageID }) {
1300
1548
  method: "POST"
1301
1549
  });
1302
1550
  if (!response.ok) {
1303
- const body = await response.text();
1304
- throw new Error(body || "Upload failed");
1551
+ throw new Error(await parsePayloadErrorMessage(response, "Could not upload image."));
1305
1552
  }
1306
1553
  const json = await response.json();
1307
1554
  const uploaded = extractUploadedMedia(json);
@@ -1311,12 +1558,19 @@ function BuilderPageEditor({ initialDoc, pageID }) {
1311
1558
  const nextLayout = cloneBlockLayout(layout);
1312
1559
  const block = nextLayout[selectedIndex];
1313
1560
  if (target.kind === "hero") {
1314
- const uploadedURL = getUploadedMediaURL(uploaded);
1561
+ const uploadedItem = toMediaLibraryItem(uploaded);
1315
1562
  nextLayout[selectedIndex] = {
1316
1563
  ...block,
1317
- backgroundImageURL: uploadedURL,
1564
+ backgroundImageURL: uploadedItem?.url || normalizeText(uploaded.url),
1318
1565
  media: uploaded
1319
1566
  };
1567
+ if (uploadedItem) {
1568
+ setMediaLibrary((current) => {
1569
+ const deduped = current.filter((item) => String(item.id) !== String(uploadedItem.id));
1570
+ return [uploadedItem, ...deduped];
1571
+ });
1572
+ setSelectedHeroMediaID(String(uploadedItem.id));
1573
+ }
1320
1574
  } else if (target.kind === "media") {
1321
1575
  nextLayout[selectedIndex] = {
1322
1576
  ...block,
@@ -1342,6 +1596,25 @@ function BuilderPageEditor({ initialDoc, pageID }) {
1342
1596
  setUploadingTarget(null);
1343
1597
  }
1344
1598
  };
1599
+ const withHeroMediaFallbacks = (sourceLayout) => sourceLayout.map((block) => {
1600
+ if (!block || typeof block !== "object") {
1601
+ return block;
1602
+ }
1603
+ const nextBlock = { ...block };
1604
+ const blockType = normalizeText(nextBlock.blockType);
1605
+ if (blockType !== "hero") {
1606
+ return nextBlock;
1607
+ }
1608
+ const existingBackgroundImageURL = normalizeText(nextBlock.backgroundImageURL).trim();
1609
+ if (existingBackgroundImageURL.length > 0) {
1610
+ return nextBlock;
1611
+ }
1612
+ const mediaURL = getMediaURL(nextBlock.media);
1613
+ if (mediaURL.length > 0) {
1614
+ nextBlock.backgroundImageURL = mediaURL;
1615
+ }
1616
+ return nextBlock;
1617
+ });
1345
1618
  const toPersistedLayout = (sourceLayout) => sourceLayout.map((block) => {
1346
1619
  if (!block || typeof block !== "object") {
1347
1620
  return block;
@@ -1386,7 +1659,7 @@ function BuilderPageEditor({ initialDoc, pageID }) {
1386
1659
  });
1387
1660
  const renderWithSectionShell = (block, className, content) => {
1388
1661
  const shell = sectionStyleFromBlock(block, pageDefaults);
1389
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("section", { className: `${className} ${shell.sectionClass}`, style: shell.sectionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: shell.contentClass, style: shell.contentStyle, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: shell.sectionInnerStyle, children: content }) }) });
1662
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("section", { className: `${className} ${shell.sectionClass}`, style: shell.sectionStyle, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: shell.sectionInnerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: shell.contentClass, style: shell.contentStyle, children: content }) }) });
1390
1663
  };
1391
1664
  const sidebarSectionStyle = {
1392
1665
  border: "1px solid rgba(13, 74, 55, 0.15)",
@@ -1478,8 +1751,10 @@ function BuilderPageEditor({ initialDoc, pageID }) {
1478
1751
  setLayout(cloneBlockLayout(target.layout));
1479
1752
  setPageDefaults(clonePageDefaults(target.pageDefaults));
1480
1753
  };
1481
- const togglePanel = (panel) => {
1482
- setPanelState((current) => ({ ...current, [panel]: !current[panel] }));
1754
+ const collapseSidebar = () => setSidebarOpen(false);
1755
+ const openSidebarPanel = (panel) => {
1756
+ setActiveSidebarPanel(panel);
1757
+ setSidebarOpen(true);
1483
1758
  };
1484
1759
  const setSelectedStyleField = (fieldName, value) => {
1485
1760
  updateSelectedField(fieldName, value);
@@ -1501,17 +1776,19 @@ function BuilderPageEditor({ initialDoc, pageID }) {
1501
1776
  }
1502
1777
  };
1503
1778
  const saveLayout = async (status) => {
1779
+ if (savingStatus !== null) {
1780
+ return false;
1781
+ }
1504
1782
  setSavingStatus(status);
1505
- setSaveError("");
1506
- setSaveMessage("");
1507
1783
  try {
1508
- const persistedLayout = toPersistedLayout(layout);
1784
+ const normalizedLayout = withHeroMediaFallbacks(layout);
1785
+ const persistedLayout = toPersistedLayout(normalizedLayout);
1509
1786
  const response = await fetch(`/api/pages/${pageID}`, {
1510
1787
  body: JSON.stringify({
1511
1788
  _status: status,
1512
1789
  layout: persistedLayout,
1513
1790
  studioDocument: layoutToStudioDocument(
1514
- layout,
1791
+ normalizedLayout,
1515
1792
  title,
1516
1793
  {
1517
1794
  pageWidthDefault: pageDefaults.pageWidthDefault
@@ -1525,14 +1802,19 @@ function BuilderPageEditor({ initialDoc, pageID }) {
1525
1802
  method: "PATCH"
1526
1803
  });
1527
1804
  if (!response.ok) {
1528
- const body = await response.text();
1529
- throw new Error(body || "Failed to save page");
1805
+ throw new Error(await parsePayloadErrorMessage(response, "Could not save this page."));
1530
1806
  }
1531
- setSaveMessage(status === "published" ? "Published." : "Draft saved.");
1532
- lastSavedRef.current = cloneSnapshot({
1533
- layout: cloneBlockLayout(layout),
1807
+ const savedSnapshot = {
1808
+ layout: cloneBlockLayout(normalizedLayout),
1534
1809
  pageDefaults: clonePageDefaults(pageDefaults)
1535
- });
1810
+ };
1811
+ const shouldSyncLayout = snapshotKey(savedSnapshot) !== snapshotKey(currentSnapshot);
1812
+ if (shouldSyncLayout) {
1813
+ historyBypassRef.current = true;
1814
+ previousSnapshotRef.current = cloneSnapshot(savedSnapshot);
1815
+ setLayout(cloneBlockLayout(savedSnapshot.layout));
1816
+ }
1817
+ lastSavedRef.current = cloneSnapshot(savedSnapshot);
1536
1818
  window.parent?.postMessage(
1537
1819
  {
1538
1820
  message: status === "published" ? "Published." : "Draft saved.",
@@ -1546,10 +1828,9 @@ function BuilderPageEditor({ initialDoc, pageID }) {
1546
1828
  return true;
1547
1829
  } catch (error) {
1548
1830
  console.error(error);
1549
- setSaveError("Could not save. Check permissions/session and retry.");
1550
1831
  window.parent?.postMessage(
1551
1832
  {
1552
- message: "Could not save. Check permissions/session and retry.",
1833
+ message: error instanceof Error ? error.message : "Could not save. Check permissions/session and retry.",
1553
1834
  ok: false,
1554
1835
  source: "payload-visual-builder-child",
1555
1836
  status,
@@ -1570,26 +1851,42 @@ function BuilderPageEditor({ initialDoc, pageID }) {
1570
1851
  }
1571
1852
  try {
1572
1853
  const parsed = JSON.parse(raw);
1573
- setPanelState((current) => ({
1574
- addSections: typeof parsed.addSections === "boolean" ? parsed.addSections : current.addSections,
1575
- pageDefaults: typeof parsed.pageDefaults === "boolean" ? parsed.pageDefaults : current.pageDefaults,
1576
- quickAdd: typeof parsed.quickAdd === "boolean" ? parsed.quickAdd : current.quickAdd,
1577
- save: typeof parsed.save === "boolean" ? parsed.save : current.save,
1578
- selected: typeof parsed.selected === "boolean" ? parsed.selected : current.selected
1579
- }));
1854
+ const maybeActive = parsed.activePanel;
1855
+ if (isSidebarPanelKey(maybeActive)) {
1856
+ setActiveSidebarPanel(maybeActive);
1857
+ return;
1858
+ }
1859
+ const oldSelected = typeof parsed.selected === "boolean" ? parsed.selected : false;
1860
+ const oldAdd = (typeof parsed.addSections === "boolean" ? parsed.addSections : false) || (typeof parsed.addContent === "boolean" ? parsed.addContent : false) || (typeof parsed.quickAdd === "boolean" ? parsed.quickAdd : false);
1861
+ const oldDefaults = typeof parsed.pageDefaults === "boolean" ? parsed.pageDefaults : false;
1862
+ if (oldSelected) {
1863
+ setActiveSidebarPanel("selected");
1864
+ } else if (oldAdd) {
1865
+ setActiveSidebarPanel("addSections");
1866
+ } else if (oldDefaults) {
1867
+ setActiveSidebarPanel("pageDefaults");
1868
+ }
1580
1869
  } catch {
1581
1870
  }
1582
1871
  }, [pageID]);
1583
1872
  (0, import_react.useEffect)(() => {
1584
1873
  const storageKey = `orion-builder-panels:${pageID}`;
1585
- window.localStorage.setItem(storageKey, JSON.stringify(panelState));
1586
- }, [pageID, panelState]);
1874
+ window.localStorage.setItem(storageKey, JSON.stringify({ activePanel: activeSidebarPanel }));
1875
+ }, [activeSidebarPanel, pageID]);
1587
1876
  (0, import_react.useEffect)(() => {
1588
1877
  if (selectedIndex === null) {
1589
1878
  return;
1590
1879
  }
1591
- setPanelState((current) => current.selected ? current : { ...current, selected: true });
1880
+ setSidebarOpen(true);
1881
+ setActiveSidebarPanel("selected");
1592
1882
  }, [selectedIndex]);
1883
+ (0, import_react.useEffect)(() => {
1884
+ if (layout.length > 0) {
1885
+ return;
1886
+ }
1887
+ setSidebarOpen(true);
1888
+ setActiveSidebarPanel("addSections");
1889
+ }, [layout.length]);
1593
1890
  (0, import_react.useEffect)(() => {
1594
1891
  if (historyBypassRef.current) {
1595
1892
  historyBypassRef.current = false;
@@ -1620,29 +1917,79 @@ function BuilderPageEditor({ initialDoc, pageID }) {
1620
1917
  return () => window.removeEventListener("keydown", onKeyDown);
1621
1918
  }, [canRedo, canUndo, futureSnapshots, pastSnapshots, currentSnapshot]);
1622
1919
  (0, import_react.useEffect)(() => {
1623
- const onBeforeUnload = (event) => {
1624
- if (!isDirty) {
1625
- return;
1626
- }
1627
- event.preventDefault();
1628
- event.returnValue = "";
1629
- };
1630
- window.addEventListener("beforeunload", onBeforeUnload);
1631
- return () => window.removeEventListener("beforeunload", onBeforeUnload);
1920
+ window.parent?.postMessage(
1921
+ {
1922
+ dirty: isDirty,
1923
+ source: "payload-visual-builder-child",
1924
+ type: "dirty-state"
1925
+ },
1926
+ "*"
1927
+ );
1632
1928
  }, [isDirty]);
1929
+ (0, import_react.useEffect)(() => {
1930
+ window.parent?.postMessage(
1931
+ {
1932
+ canRedo,
1933
+ canUndo,
1934
+ source: "payload-visual-builder-child",
1935
+ type: "history-state"
1936
+ },
1937
+ "*"
1938
+ );
1939
+ }, [canRedo, canUndo]);
1633
1940
  (0, import_react.useEffect)(() => {
1634
1941
  const onMessage = (event) => {
1635
1942
  const data = event.data;
1636
- if (!data || data.source !== "payload-visual-builder-parent" || data.type !== "save") {
1943
+ if (!data || data.source !== "payload-visual-builder-parent") {
1944
+ return;
1945
+ }
1946
+ if (data.type === "dirty-check-request") {
1947
+ window.parent?.postMessage(
1948
+ {
1949
+ dirty: isDirty,
1950
+ source: "payload-visual-builder-child",
1951
+ type: "dirty-state"
1952
+ },
1953
+ "*"
1954
+ );
1955
+ window.parent?.postMessage(
1956
+ {
1957
+ canRedo,
1958
+ canUndo,
1959
+ source: "payload-visual-builder-child",
1960
+ type: "history-state"
1961
+ },
1962
+ "*"
1963
+ );
1964
+ return;
1965
+ }
1966
+ if (data.type === "history-check-request") {
1967
+ window.parent?.postMessage(
1968
+ {
1969
+ canRedo,
1970
+ canUndo,
1971
+ source: "payload-visual-builder-child",
1972
+ type: "history-state"
1973
+ },
1974
+ "*"
1975
+ );
1637
1976
  return;
1638
1977
  }
1639
- if (data.status === "draft" || data.status === "published") {
1978
+ if (data.type === "save" && (data.status === "draft" || data.status === "published")) {
1640
1979
  void saveLayout(data.status);
1980
+ return;
1981
+ }
1982
+ if (data.type === "undo") {
1983
+ undo();
1984
+ return;
1985
+ }
1986
+ if (data.type === "redo") {
1987
+ redo();
1641
1988
  }
1642
1989
  };
1643
1990
  window.addEventListener("message", onMessage);
1644
1991
  return () => window.removeEventListener("message", onMessage);
1645
- }, [layout, pageDefaults.pageWidthDefault, title]);
1992
+ }, [canRedo, canUndo, isDirty, layout, pageDefaults.pageWidthDefault, title]);
1646
1993
  (0, import_react.useEffect)(() => {
1647
1994
  const preventNavigationWhileEditing = (event) => {
1648
1995
  const editorRoot = editorRootRef.current;
@@ -1677,43 +2024,6 @@ function BuilderPageEditor({ initialDoc, pageID }) {
1677
2024
  },
1678
2025
  children: [
1679
2026
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { minWidth: 0 }, children: [
1680
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1681
- "div",
1682
- {
1683
- style: {
1684
- alignItems: "center",
1685
- display: "flex",
1686
- gap: 8,
1687
- justifyContent: "space-between",
1688
- marginBottom: 10
1689
- },
1690
- children: [
1691
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--ink-700)", fontSize: 12, fontWeight: 600 }, children: isDirty ? "Unsaved changes" : "All changes saved" }),
1692
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", gap: 6 }, children: [
1693
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1694
- "button",
1695
- {
1696
- disabled: !canUndo,
1697
- onClick: undo,
1698
- style: { borderRadius: 999, cursor: canUndo ? "pointer" : "not-allowed", fontSize: 12, padding: "7px 11px" },
1699
- type: "button",
1700
- children: "Undo"
1701
- }
1702
- ),
1703
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1704
- "button",
1705
- {
1706
- disabled: !canRedo,
1707
- onClick: redo,
1708
- style: { borderRadius: 999, cursor: canRedo ? "pointer" : "not-allowed", fontSize: 12, padding: "7px 11px" },
1709
- type: "button",
1710
- children: "Redo"
1711
- }
1712
- )
1713
- ] })
1714
- ]
1715
- }
1716
- ),
1717
2027
  layout.map((block, index) => {
1718
2028
  const type = normalizeText(block.blockType, "unknown");
1719
2029
  const selectBlock = () => setSelectedIndex(index);
@@ -1728,14 +2038,36 @@ function BuilderPageEditor({ initialDoc, pageID }) {
1728
2038
  if (type === "hero") {
1729
2039
  const media = resolveMedia(block.media);
1730
2040
  const variant = normalizeText(block.variant, "default");
1731
- const backgroundColor = normalizeText(block.backgroundColor);
2041
+ const backgroundColor = normalizeText(block.backgroundColor).trim();
2042
+ const backgroundImageFit = normalizeHeroImageFit(block.backgroundImageFit);
2043
+ const backgroundImageCornerStyle = normalizeHeroImageCornerStyle(
2044
+ block.backgroundImageCornerStyle,
2045
+ block.backgroundImageFit
2046
+ );
2047
+ const backgroundImagePosition = normalizeHeroImagePosition(block.backgroundImagePosition);
2048
+ const heroHeight = normalizeHeroHeight(block.heroHeight);
2049
+ const heroMinHeight = heroHeightMap[heroHeight];
2050
+ const heroCornerRadius = getHeroImageCornerRadius(backgroundImageCornerStyle);
2051
+ const sectionBackgroundMode = normalizeText(
2052
+ block.sectionBackgroundMode,
2053
+ defaultSectionStyle.sectionBackgroundMode
2054
+ );
1732
2055
  const backgroundImageURL = normalizeText(block.backgroundImageURL);
1733
- const backgroundImage = backgroundImageURL || media?.url;
2056
+ const backgroundImage = media?.url || backgroundImageURL;
2057
+ const hasCustomHeroColor = backgroundColor.length > 0 && backgroundColor.toLowerCase() !== "#124a37";
1734
2058
  const mediaStyle = backgroundImage && variant === "default" ? {
1735
- backgroundColor: backgroundColor || void 0,
1736
- backgroundImage: `linear-gradient(145deg, rgba(13, 74, 55, 0.34), rgba(13, 74, 55, 0.74)), url('${backgroundImage}')`
1737
- } : {
1738
- backgroundColor: backgroundColor || void 0
2059
+ ...hasCustomHeroColor ? { backgroundColor } : {},
2060
+ backgroundImage: `url('${backgroundImage}')`,
2061
+ backgroundPosition: backgroundImagePosition,
2062
+ backgroundRepeat: "no-repeat",
2063
+ backgroundSize: backgroundImageFit,
2064
+ minHeight: heroMinHeight
2065
+ } : hasCustomHeroColor && sectionBackgroundMode !== "none" ? {
2066
+ backgroundColor,
2067
+ minHeight: heroMinHeight
2068
+ } : { minHeight: heroMinHeight };
2069
+ const heroStyle = {
2070
+ borderRadius: heroCornerRadius
1739
2071
  };
1740
2072
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1741
2073
  BlockFrame,
@@ -1749,8 +2081,8 @@ function BuilderPageEditor({ initialDoc, pageID }) {
1749
2081
  setDragIndex,
1750
2082
  children: renderWithSectionShell(
1751
2083
  block,
1752
- `hero ${variant === "centered" ? "hero-centered" : ""}`,
1753
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
2084
+ "",
2085
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: `hero ${variant === "centered" ? "hero-centered" : ""}`, style: heroStyle, children: [
1754
2086
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "hero-grid", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "hero-media", role: "img", style: mediaStyle }) }),
1755
2087
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "hero-content", children: [
1756
2088
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "kicker", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -1837,47 +2169,57 @@ function BuilderPageEditor({ initialDoc, pageID }) {
1837
2169
  value: normalizeText(block.title)
1838
2170
  }
1839
2171
  ) }) }),
1840
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "feature-grid", children: items.map((item, itemIndex) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("article", { className: "feature-item", children: [
1841
- resolveMedia(item?.media)?.url ? (
1842
- // eslint-disable-next-line @next/next/no-img-element
2172
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "feature-grid", children: items.map((item, itemIndex) => {
2173
+ const itemRecord = item;
2174
+ const itemMedia = resolveMedia(itemRecord?.media);
2175
+ const itemImageStyle = getImagePresentationStyle({
2176
+ cornerStyle: normalizeImageCornerStyle(itemRecord?.imageCornerStyle),
2177
+ fit: normalizeImageFit(itemRecord?.imageFit),
2178
+ position: normalizeImagePosition(itemRecord?.imagePosition)
2179
+ });
2180
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("article", { className: "feature-item", children: [
2181
+ itemMedia?.url ? (
2182
+ // eslint-disable-next-line @next/next/no-img-element
2183
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2184
+ "img",
2185
+ {
2186
+ alt: itemMedia.alt || normalizeText(itemRecord?.title, "Feature image"),
2187
+ className: "feature-item-media",
2188
+ src: itemMedia.url,
2189
+ style: itemImageStyle
2190
+ }
2191
+ )
2192
+ ) : null,
2193
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "feature-icon", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2194
+ InlineText,
2195
+ {
2196
+ as: "span",
2197
+ onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "icon", value),
2198
+ placeholder: "01",
2199
+ value: normalizeText(itemRecord?.icon)
2200
+ }
2201
+ ) }),
1843
2202
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1844
- "img",
2203
+ InlineText,
2204
+ {
2205
+ as: "h3",
2206
+ onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "title", value),
2207
+ placeholder: "Feature title",
2208
+ value: normalizeText(itemRecord?.title)
2209
+ }
2210
+ ),
2211
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2212
+ InlineText,
1845
2213
  {
1846
- alt: resolveMedia(item?.media)?.alt || normalizeText(item?.title, "Feature image"),
1847
- className: "feature-item-media",
1848
- src: resolveMedia(item?.media)?.url
2214
+ as: "p",
2215
+ multiline: true,
2216
+ onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "description", value),
2217
+ placeholder: "Feature description",
2218
+ value: normalizeText(itemRecord?.description)
1849
2219
  }
1850
2220
  )
1851
- ) : null,
1852
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "feature-icon", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1853
- InlineText,
1854
- {
1855
- as: "span",
1856
- onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "icon", value),
1857
- placeholder: "01",
1858
- value: normalizeText(item?.icon)
1859
- }
1860
- ) }),
1861
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1862
- InlineText,
1863
- {
1864
- as: "h3",
1865
- onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "title", value),
1866
- placeholder: "Feature title",
1867
- value: normalizeText(item?.title)
1868
- }
1869
- ),
1870
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1871
- InlineText,
1872
- {
1873
- as: "p",
1874
- multiline: true,
1875
- onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "description", value),
1876
- placeholder: "Feature description",
1877
- value: normalizeText(item?.description)
1878
- }
1879
- )
1880
- ] }, `item-${itemIndex}`)) })
2221
+ ] }, `item-${itemIndex}`);
2222
+ }) })
1881
2223
  ] }) })
1882
2224
  )
1883
2225
  },
@@ -1907,47 +2249,57 @@ function BuilderPageEditor({ initialDoc, pageID }) {
1907
2249
  value: normalizeText(block.title)
1908
2250
  }
1909
2251
  ) }) }),
1910
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "card-grid services", children: items.map((item, itemIndex) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("article", { className: "service-card", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "service-body", children: [
1911
- resolveMedia(item?.media)?.url ? (
1912
- // eslint-disable-next-line @next/next/no-img-element
2252
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "card-grid services", children: items.map((item, itemIndex) => {
2253
+ const itemRecord = item;
2254
+ const itemMedia = resolveMedia(itemRecord?.media);
2255
+ const itemImageStyle = getImagePresentationStyle({
2256
+ cornerStyle: normalizeImageCornerStyle(itemRecord?.imageCornerStyle),
2257
+ fit: normalizeImageFit(itemRecord?.imageFit),
2258
+ position: normalizeImagePosition(itemRecord?.imagePosition)
2259
+ });
2260
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("article", { className: "service-card", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "service-body", children: [
2261
+ itemMedia?.url ? (
2262
+ // eslint-disable-next-line @next/next/no-img-element
2263
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2264
+ "img",
2265
+ {
2266
+ alt: itemMedia.alt || normalizeText(itemRecord?.title, "Feature image"),
2267
+ className: "feature-item-media feature-item-media-card",
2268
+ src: itemMedia.url,
2269
+ style: itemImageStyle
2270
+ }
2271
+ )
2272
+ ) : null,
2273
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "service-tag", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2274
+ InlineText,
2275
+ {
2276
+ as: "span",
2277
+ onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "icon", value),
2278
+ placeholder: "01",
2279
+ value: normalizeText(itemRecord?.icon)
2280
+ }
2281
+ ) }),
1913
2282
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1914
- "img",
2283
+ InlineText,
2284
+ {
2285
+ as: "h3",
2286
+ onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "title", value),
2287
+ placeholder: "Feature title",
2288
+ value: normalizeText(itemRecord?.title)
2289
+ }
2290
+ ),
2291
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2292
+ InlineText,
1915
2293
  {
1916
- alt: resolveMedia(item?.media)?.alt || normalizeText(item?.title, "Feature image"),
1917
- className: "feature-item-media feature-item-media-card",
1918
- src: resolveMedia(item?.media)?.url
2294
+ as: "p",
2295
+ multiline: true,
2296
+ onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "description", value),
2297
+ placeholder: "Feature description",
2298
+ value: normalizeText(itemRecord?.description)
1919
2299
  }
1920
2300
  )
1921
- ) : null,
1922
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "service-tag", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1923
- InlineText,
1924
- {
1925
- as: "span",
1926
- onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "icon", value),
1927
- placeholder: "01",
1928
- value: normalizeText(item?.icon)
1929
- }
1930
- ) }),
1931
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1932
- InlineText,
1933
- {
1934
- as: "h3",
1935
- onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "title", value),
1936
- placeholder: "Feature title",
1937
- value: normalizeText(item?.title)
1938
- }
1939
- ),
1940
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1941
- InlineText,
1942
- {
1943
- as: "p",
1944
- multiline: true,
1945
- onCommit: (value) => updateArrayItemField(index, "items", itemIndex, "description", value),
1946
- placeholder: "Feature description",
1947
- value: normalizeText(item?.description)
1948
- }
1949
- )
1950
- ] }) }, `item-${itemIndex}`)) })
2301
+ ] }) }, `item-${itemIndex}`);
2302
+ }) })
1951
2303
  ] })
1952
2304
  )
1953
2305
  },
@@ -2066,6 +2418,12 @@ function BuilderPageEditor({ initialDoc, pageID }) {
2066
2418
  ] }) }),
2067
2419
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "orion-logo-wall", children: items.map((item, itemIndex) => {
2068
2420
  const media = resolveMedia(item?.media);
2421
+ const imageStyle = getImagePresentationStyle({
2422
+ cornerStyle: normalizeImageCornerStyle(item?.imageCornerStyle),
2423
+ fit: normalizeImageFit(item?.imageFit),
2424
+ position: normalizeImagePosition(item?.imagePosition),
2425
+ roundedRadius: 10
2426
+ });
2069
2427
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("article", { className: "orion-logo-wall-item", children: media?.url ? (
2070
2428
  // eslint-disable-next-line @next/next/no-img-element
2071
2429
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -2073,7 +2431,8 @@ function BuilderPageEditor({ initialDoc, pageID }) {
2073
2431
  {
2074
2432
  alt: media.alt || normalizeText(item?.name, "Logo"),
2075
2433
  className: "orion-logo-wall-image",
2076
- src: media.url
2434
+ src: media.url,
2435
+ style: imageStyle
2077
2436
  }
2078
2437
  )
2079
2438
  ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -2132,6 +2491,11 @@ function BuilderPageEditor({ initialDoc, pageID }) {
2132
2491
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "orion-before-after-grid", children: items.map((item, itemIndex) => {
2133
2492
  const beforeMedia = resolveMedia(item?.beforeMedia);
2134
2493
  const afterMedia = resolveMedia(item?.afterMedia);
2494
+ const imageStyle = getImagePresentationStyle({
2495
+ cornerStyle: normalizeImageCornerStyle(item?.imageCornerStyle),
2496
+ fit: normalizeImageFit(item?.imageFit),
2497
+ position: normalizeImagePosition(item?.imagePosition)
2498
+ });
2135
2499
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("article", { className: "orion-before-after-card", children: [
2136
2500
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "orion-before-after-media", children: [
2137
2501
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("figure", { children: [
@@ -2141,7 +2505,8 @@ function BuilderPageEditor({ initialDoc, pageID }) {
2141
2505
  "img",
2142
2506
  {
2143
2507
  alt: beforeMedia.alt || `${normalizeText(item?.label, "Project")} before`,
2144
- src: beforeMedia.url
2508
+ src: beforeMedia.url,
2509
+ style: imageStyle
2145
2510
  }
2146
2511
  )
2147
2512
  ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "orion-before-after-placeholder", children: "Before" }),
@@ -2154,7 +2519,8 @@ function BuilderPageEditor({ initialDoc, pageID }) {
2154
2519
  "img",
2155
2520
  {
2156
2521
  alt: afterMedia.alt || `${normalizeText(item?.label, "Project")} after`,
2157
- src: afterMedia.url
2522
+ src: afterMedia.url,
2523
+ style: imageStyle
2158
2524
  }
2159
2525
  )
2160
2526
  ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "orion-before-after-placeholder", children: "After" }),
@@ -2419,6 +2785,11 @@ function BuilderPageEditor({ initialDoc, pageID }) {
2419
2785
  if (type === "media") {
2420
2786
  const image = resolveMedia(block.image);
2421
2787
  const size = normalizeText(block.size, "default");
2788
+ const imageStyle = getImagePresentationStyle({
2789
+ cornerStyle: normalizeImageCornerStyle(block?.imageCornerStyle),
2790
+ fit: normalizeImageFit(block?.imageFit),
2791
+ position: normalizeImagePosition(block?.imagePosition)
2792
+ });
2422
2793
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2423
2794
  BlockFrame,
2424
2795
  {
@@ -2435,7 +2806,7 @@ function BuilderPageEditor({ initialDoc, pageID }) {
2435
2806
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("figure", { className: `media-figure ${size === "wide" ? "wide" : ""}`, children: [
2436
2807
  image?.url ? (
2437
2808
  // eslint-disable-next-line @next/next/no-img-element
2438
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { alt: image.alt || "Page media", src: image.url })
2809
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { alt: image.alt || "Page media", src: image.url, style: imageStyle })
2439
2810
  ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2440
2811
  "div",
2441
2812
  {
@@ -2638,998 +3009,1572 @@ function BuilderPageEditor({ initialDoc, pageID }) {
2638
3009
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "+" })
2639
3010
  }
2640
3011
  ),
2641
- sidebarOpen ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "grid", gap: 12, maxHeight: "calc(100vh - 90px)", overflowY: "auto", padding: 12 }, children: [
2642
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { style: sidebarSectionStyle, children: [
2643
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3012
+ (() => {
3013
+ const tabs = [
3014
+ { key: "pageDefaults", label: "Page Defaults" },
3015
+ { key: "addSections", label: "Add Sections" },
3016
+ { key: "selected", label: "Selected Section" }
3017
+ ].map((panel) => {
3018
+ const isActive = activeSidebarPanel === panel.key;
3019
+ const iconFill = isActive ? "#ffffff" : "#124a37";
3020
+ const iconButtonBg = isActive ? "#124a37" : "rgba(18, 74, 55, 0.08)";
3021
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2644
3022
  "button",
2645
3023
  {
2646
- onClick: () => togglePanel("save"),
2647
- style: { alignItems: "center", background: "transparent", border: "none", cursor: "pointer", display: "flex", fontSize: 13, fontWeight: 700, justifyContent: "space-between", padding: 0, width: "100%" },
3024
+ "aria-label": panel.label,
3025
+ onClick: () => openSidebarPanel(panel.key),
3026
+ style: {
3027
+ alignItems: "center",
3028
+ background: iconButtonBg,
3029
+ border: "1px solid rgba(18, 74, 55, 0.14)",
3030
+ borderRadius: 14,
3031
+ cursor: "pointer",
3032
+ display: "grid",
3033
+ height: 34,
3034
+ placeItems: "center",
3035
+ width: 34
3036
+ },
3037
+ title: panel.label,
2648
3038
  type: "button",
2649
3039
  children: [
2650
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "Save & Publish" }),
2651
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: panelState.save ? "Hide" : "Show" })
3040
+ panel.key === "pageDefaults" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { fill: "none", height: "18", viewBox: "0 0 24 24", width: "18", children: [
3041
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { height: "14", rx: "2", stroke: iconFill, strokeWidth: "2", width: "18", x: "3", y: "5" }),
3042
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M9 5v14", stroke: iconFill, strokeWidth: "2" })
3043
+ ] }) : null,
3044
+ panel.key === "addSections" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { fill: "none", height: "18", viewBox: "0 0 24 24", width: "18", children: [
3045
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 5v14", stroke: iconFill, strokeWidth: "2", strokeLinecap: "round" }),
3046
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M5 12h14", stroke: iconFill, strokeWidth: "2", strokeLinecap: "round" })
3047
+ ] }) : null,
3048
+ panel.key === "selected" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { fill: "none", height: "18", viewBox: "0 0 24 24", width: "18", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M6 3l12 9-7 2-2 7-3-18z", fill: iconFill, opacity: "0.92" }) }) : null
2652
3049
  ]
2653
- }
2654
- ),
2655
- panelState.save ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "grid", gap: 8, marginTop: 10 }, children: [
2656
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--ink-700)", fontSize: 11, fontWeight: 600 }, children: isDirty ? "Unsaved edits" : "All changes saved" }),
2657
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", gap: 6 }, children: [
2658
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2659
- "button",
2660
- {
2661
- disabled: !canUndo,
2662
- onClick: undo,
2663
- style: { borderRadius: 999, cursor: canUndo ? "pointer" : "not-allowed", fontSize: 12, padding: "7px 10px" },
2664
- type: "button",
2665
- children: "Undo"
2666
- }
2667
- ),
2668
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2669
- "button",
2670
- {
2671
- disabled: !canRedo,
2672
- onClick: redo,
2673
- style: { borderRadius: 999, cursor: canRedo ? "pointer" : "not-allowed", fontSize: 12, padding: "7px 10px" },
2674
- type: "button",
2675
- children: "Redo"
2676
- }
2677
- )
2678
- ] }),
2679
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", gap: 6 }, children: [
2680
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2681
- "button",
2682
- {
2683
- disabled: savingStatus !== null,
2684
- onClick: () => void saveLayout("draft"),
2685
- style: {
2686
- borderRadius: 999,
2687
- cursor: savingStatus ? "not-allowed" : "pointer",
2688
- fontSize: 12,
2689
- fontWeight: 700,
2690
- padding: "7px 10px"
2691
- },
2692
- type: "button",
2693
- children: savingStatus === "draft" ? "Saving..." : "Save Draft"
2694
- }
2695
- ),
2696
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2697
- "button",
2698
- {
2699
- disabled: savingStatus !== null,
2700
- onClick: () => void saveLayout("published"),
2701
- style: {
2702
- background: "#0f7d52",
2703
- border: "none",
2704
- borderRadius: 999,
2705
- color: "#fff",
2706
- cursor: savingStatus ? "not-allowed" : "pointer",
2707
- fontSize: 12,
2708
- fontWeight: 700,
2709
- padding: "7px 10px"
2710
- },
2711
- type: "button",
2712
- children: savingStatus === "published" ? "Publishing..." : "Publish"
2713
- }
2714
- )
2715
- ] }),
2716
- saveMessage ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#0f7d52", fontSize: 11, fontWeight: 700 }, children: saveMessage }) : null,
2717
- saveError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#8d1d1d", fontSize: 11, fontWeight: 700 }, children: saveError }) : null
2718
- ] }) : null
2719
- ] }),
2720
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { style: sidebarSectionStyle, children: [
2721
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2722
- "button",
2723
- {
2724
- onClick: () => togglePanel("pageDefaults"),
2725
- style: { alignItems: "center", background: "transparent", border: "none", cursor: "pointer", display: "flex", fontSize: 13, fontWeight: 700, justifyContent: "space-between", padding: 0, width: "100%" },
2726
- type: "button",
2727
- children: [
2728
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "Page Defaults" }),
2729
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: panelState.pageDefaults ? "Hide" : "Show" })
2730
- ]
2731
- }
2732
- ),
2733
- panelState.pageDefaults ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "grid", gap: 8, marginTop: 10 }, children: [
2734
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
2735
- "Default Page Width",
2736
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2737
- "select",
2738
- {
2739
- onChange: (event) => setPageDefaults((current) => ({
2740
- ...current,
2741
- pageWidthDefault: event.target.value === "wide" || event.target.value === "full" ? event.target.value : "content"
2742
- })),
2743
- style: sidebarInputStyle,
2744
- value: pageDefaults.pageWidthDefault,
2745
- children: [
2746
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "content", children: "Content" }),
2747
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "wide", children: "Wide" }),
2748
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "full", children: "Full" })
2749
- ]
2750
- }
2751
- )
2752
- ] }),
2753
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--ink-700)", fontSize: 11 }, children: "Applies when section/content width is set to inherit." })
2754
- ] }) : null
2755
- ] }),
2756
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { style: sidebarSectionStyle, children: [
2757
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2758
- "button",
2759
- {
2760
- onClick: () => togglePanel("addSections"),
2761
- style: { alignItems: "center", background: "transparent", border: "none", cursor: "pointer", display: "flex", fontSize: 13, fontWeight: 700, justifyContent: "space-between", padding: 0, width: "100%" },
2762
- type: "button",
2763
- children: [
2764
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "Add Sections" }),
2765
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: panelState.addSections ? "Hide" : "Show" })
2766
- ]
2767
- }
2768
- ),
2769
- panelState.addSections ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "grid", gap: 8, marginTop: 10 }, children: [
2770
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2771
- "button",
2772
- {
2773
- onClick: applyTemplateStarter,
2774
- style: {
2775
- background: "#0f7d52",
2776
- border: "none",
2777
- borderRadius: 999,
2778
- color: "#fff",
2779
- cursor: "pointer",
2780
- fontSize: 12,
2781
- fontWeight: 700,
2782
- padding: "8px 10px"
2783
- },
2784
- type: "button",
2785
- children: [
2786
- "Apply ",
2787
- pageTemplate,
2788
- " Template Starter"
2789
- ]
2790
- }
2791
- ),
2792
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "grid", gap: 8 }, children: [
2793
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2794
- "input",
2795
- {
2796
- onChange: (event) => setPresetQuery(event.target.value),
2797
- placeholder: "Search presets...",
2798
- style: sidebarInputStyle,
2799
- type: "text",
2800
- value: presetQuery
2801
- }
2802
- ),
2803
- filteredSectionPresets.map((preset) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2804
- "button",
2805
- {
2806
- onClick: () => addSectionPreset(preset.blocks),
2807
- style: {
2808
- border: "1px solid rgba(13, 74, 55, 0.2)",
2809
- borderRadius: 10,
2810
- cursor: "pointer",
2811
- display: "grid",
2812
- gap: 3,
2813
- padding: 9,
2814
- textAlign: "left"
2815
- },
2816
- type: "button",
2817
- children: [
2818
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: 12, fontWeight: 700 }, children: preset.title }),
2819
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: "var(--ink-700)", fontSize: 11 }, children: preset.description })
2820
- ]
2821
- },
2822
- preset.id
2823
- )),
2824
- filteredSectionPresets.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--ink-700)", fontSize: 11 }, children: "No presets match this search." }) : null
2825
- ] })
2826
- ] }) : null
2827
- ] }),
2828
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { style: sidebarSectionStyle, children: [
2829
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2830
- "button",
2831
- {
2832
- onClick: () => togglePanel("quickAdd"),
2833
- style: { alignItems: "center", background: "transparent", border: "none", cursor: "pointer", display: "flex", fontSize: 13, fontWeight: 700, justifyContent: "space-between", padding: 0, width: "100%" },
2834
- type: "button",
2835
- children: [
2836
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "Quick Add Block" }),
2837
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: panelState.quickAdd ? "Hide" : "Show" })
2838
- ]
2839
- }
2840
- ),
2841
- panelState.quickAdd ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "grid", gap: 6, gridTemplateColumns: "1fr 1fr", marginTop: 10 }, children: quickAddBlockTypes.map((type) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2842
- "button",
3050
+ },
3051
+ panel.key
3052
+ );
3053
+ });
3054
+ return sidebarOpen ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "grid", gridTemplateRows: "auto 1fr", maxHeight: "calc(100vh - 90px)", overflow: "hidden" }, children: [
3055
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3056
+ "div",
2843
3057
  {
2844
- onClick: () => addBlockByType(type),
2845
3058
  style: {
2846
- border: "1px solid rgba(13, 74, 55, 0.2)",
2847
- borderRadius: 10,
2848
- cursor: "pointer",
2849
- fontSize: 12,
2850
- fontWeight: 600,
2851
- padding: "8px 7px"
3059
+ alignItems: "center",
3060
+ background: "linear-gradient(180deg, rgba(18, 74, 55, 0.06), rgba(18, 74, 55, 0))",
3061
+ borderBottom: "1px solid rgba(13, 74, 55, 0.12)",
3062
+ display: "flex",
3063
+ gap: 8,
3064
+ padding: "10px 10px"
2852
3065
  },
2853
- type: "button",
2854
- children: [
2855
- "+ ",
2856
- blockTypeLabels[type] || type
2857
- ]
2858
- },
2859
- type
2860
- )) }) : null
2861
- ] }),
2862
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { style: sidebarSectionStyle, children: [
2863
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2864
- "button",
2865
- {
2866
- onClick: () => togglePanel("selected"),
2867
- style: { alignItems: "center", background: "transparent", border: "none", cursor: "pointer", display: "flex", fontSize: 13, fontWeight: 700, justifyContent: "space-between", padding: 0, width: "100%" },
2868
- type: "button",
2869
- children: [
2870
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "Selected Section" }),
2871
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: selectedIndex !== null ? `#${selectedIndex + 1}` : "None" })
2872
- ]
3066
+ children: tabs
2873
3067
  }
2874
3068
  ),
2875
- panelState.selected ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "grid", gap: 8, marginTop: 10 }, children: selectedBlock ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
2876
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--ink-700)", fontSize: 12, fontWeight: 600 }, children: blockTypeLabels[selectedType] || selectedType }),
2877
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", flexWrap: "wrap", gap: 6 }, children: [
2878
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2879
- "button",
2880
- {
2881
- disabled: selectedIndex === null || selectedIndex <= 0,
2882
- onClick: () => moveSelectedBlock("up"),
2883
- style: { borderRadius: 999, cursor: "pointer", fontSize: 12, padding: "7px 10px" },
2884
- type: "button",
2885
- children: "Move Up"
2886
- }
2887
- ),
2888
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2889
- "button",
2890
- {
2891
- disabled: selectedIndex === null || selectedIndex >= layout.length - 1,
2892
- onClick: () => moveSelectedBlock("down"),
2893
- style: { borderRadius: 999, cursor: "pointer", fontSize: 12, padding: "7px 10px" },
2894
- type: "button",
2895
- children: "Move Down"
2896
- }
2897
- ),
2898
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2899
- "button",
2900
- {
2901
- onClick: duplicateSelectedBlock,
2902
- style: { borderRadius: 999, cursor: "pointer", fontSize: 12, padding: "7px 10px" },
2903
- type: "button",
2904
- children: "Duplicate"
2905
- }
2906
- ),
2907
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2908
- "button",
2909
- {
2910
- onClick: removeSelectedBlock,
2911
- style: {
2912
- background: "#8d1d1d",
2913
- border: "none",
2914
- borderRadius: 999,
2915
- color: "#fff",
2916
- cursor: "pointer",
2917
- fontSize: 12,
2918
- padding: "7px 10px"
2919
- },
2920
- type: "button",
2921
- children: "Remove"
2922
- }
2923
- )
2924
- ] }),
2925
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { color: "var(--ink-700)", fontSize: 11 }, children: [
2926
- "Section width follows ",
2927
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: "Page Defaults" }),
2928
- " for a consistent page layout."
2929
- ] }),
2930
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
2931
- "Content Width",
2932
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2933
- "select",
2934
- {
2935
- onChange: (event) => setSelectedStyleField("contentWidth", event.target.value),
2936
- style: sidebarInputStyle,
2937
- value: normalizeText(selectedSectionStyle.contentWidth, "inherit"),
2938
- children: [
2939
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "inherit", children: "Inherit Page Default" }),
2940
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "narrow", children: "Narrow" }),
2941
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "content", children: "Content" }),
2942
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "wide", children: "Wide" }),
2943
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "full", children: "Full" })
2944
- ]
2945
- }
2946
- )
2947
- ] }),
2948
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
2949
- "Section Vertical Spacing",
2950
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2951
- "select",
2952
- {
2953
- onChange: (event) => setSelectedStyleField("sectionPaddingY", event.target.value),
2954
- style: sidebarInputStyle,
2955
- value: normalizeText(selectedSectionStyle.sectionPaddingY, "md"),
2956
- children: [
2957
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "sm", children: "Small" }),
2958
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "md", children: "Medium" }),
2959
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "lg", children: "Large" })
2960
- ]
2961
- }
2962
- )
2963
- ] }),
2964
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
2965
- "Section Background",
2966
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2967
- "select",
2968
- {
2969
- onChange: (event) => setSelectedStyleField("sectionBackgroundMode", event.target.value),
2970
- style: sidebarInputStyle,
2971
- value: normalizeText(selectedSectionStyle.sectionBackgroundMode, "none"),
2972
- children: [
2973
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "none", children: "None" }),
2974
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "color", children: "Color" }),
2975
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "gradient", children: "Gradient" })
2976
- ]
2977
- }
2978
- )
2979
- ] }),
2980
- normalizeText(selectedSectionStyle.sectionBackgroundMode, "none") === "color" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
2981
- "Section Background Color",
2982
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2983
- "input",
2984
- {
2985
- onChange: (event) => setSelectedStyleField("sectionBackgroundColor", event.target.value),
2986
- style: { ...sidebarInputStyle, height: 36, padding: 4 },
2987
- type: "color",
2988
- value: parseColor(selectedSectionStyle.sectionBackgroundColor, "#ffffff")
2989
- }
2990
- )
2991
- ] }) : null,
2992
- normalizeText(selectedSectionStyle.sectionBackgroundMode, "none") === "gradient" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
2993
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
2994
- "Section Gradient Preset",
3069
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "grid", overflowY: "auto", padding: 12 }, children: [
3070
+ activeSidebarPanel === "pageDefaults" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { style: sidebarSectionStyle, children: [
3071
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { alignItems: "center", display: "flex", justifyContent: "space-between" }, children: [
3072
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: 13, fontWeight: 800 }, children: "Page Defaults" }),
2995
3073
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2996
- "select",
3074
+ "button",
2997
3075
  {
2998
- onChange: (event) => applyGradientPreset("section", event.target.value),
2999
- style: sidebarInputStyle,
3000
- value: normalizeText(selectedSectionStyle.sectionGradientPreset, "forest"),
3001
- children: Object.keys(gradientPresetPairs).map((preset) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: preset, children: preset }, preset))
3076
+ onClick: collapseSidebar,
3077
+ style: {
3078
+ background: "transparent",
3079
+ border: "none",
3080
+ color: "var(--ink-700)",
3081
+ cursor: "pointer",
3082
+ fontSize: 12,
3083
+ fontWeight: 700,
3084
+ padding: 0
3085
+ },
3086
+ type: "button",
3087
+ children: "Hide"
3002
3088
  }
3003
3089
  )
3004
3090
  ] }),
3005
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "grid", gap: 6, gridTemplateColumns: "1fr 1fr" }, children: [
3091
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "grid", gap: 8, marginTop: 10 }, children: [
3006
3092
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3007
- "From",
3008
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3009
- "input",
3093
+ "Default Page Width",
3094
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3095
+ "select",
3010
3096
  {
3011
- onChange: (event) => setSelectedStyleField("sectionGradientFrom", event.target.value),
3012
- style: { ...sidebarInputStyle, height: 36, padding: 4 },
3013
- type: "color",
3014
- value: parseColor(selectedSectionStyle.sectionGradientFrom, "#124a37")
3097
+ onChange: (event) => setPageDefaults((current) => ({
3098
+ ...current,
3099
+ pageWidthDefault: event.target.value === "wide" || event.target.value === "full" ? event.target.value : "content"
3100
+ })),
3101
+ style: sidebarInputStyle,
3102
+ value: pageDefaults.pageWidthDefault,
3103
+ children: [
3104
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "content", children: "Content" }),
3105
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "wide", children: "Wide" }),
3106
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "full", children: "Full" })
3107
+ ]
3015
3108
  }
3016
3109
  )
3017
3110
  ] }),
3018
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3019
- "To",
3020
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3021
- "input",
3022
- {
3023
- onChange: (event) => setSelectedStyleField("sectionGradientTo", event.target.value),
3024
- style: { ...sidebarInputStyle, height: 36, padding: 4 },
3025
- type: "color",
3026
- value: parseColor(selectedSectionStyle.sectionGradientTo, "#1f684f")
3027
- }
3028
- )
3029
- ] })
3030
- ] }),
3031
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3032
- "Angle",
3033
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3034
- "input",
3035
- {
3036
- max: 360,
3037
- min: 0,
3038
- onChange: (event) => setSelectedStyleField("sectionGradientAngle", event.target.value),
3039
- style: sidebarInputStyle,
3040
- type: "number",
3041
- value: parseAngle(selectedSectionStyle.sectionGradientAngle, "135")
3042
- }
3043
- )
3111
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--ink-700)", fontSize: 11 }, children: "Applies when section/content width is set to inherit." })
3044
3112
  ] })
3045
3113
  ] }) : null,
3046
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3047
- "Content Background",
3048
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3049
- "select",
3050
- {
3051
- onChange: (event) => setSelectedStyleField("contentBackgroundMode", event.target.value),
3052
- style: sidebarInputStyle,
3053
- value: normalizeText(selectedSectionStyle.contentBackgroundMode, "none"),
3054
- children: [
3055
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "none", children: "None" }),
3056
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "color", children: "Color" }),
3057
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "gradient", children: "Gradient" })
3058
- ]
3059
- }
3060
- )
3061
- ] }),
3062
- normalizeText(selectedSectionStyle.contentBackgroundMode, "none") === "color" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3063
- "Content Background Color",
3064
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3065
- "input",
3066
- {
3067
- onChange: (event) => setSelectedStyleField("contentBackgroundColor", event.target.value),
3068
- style: { ...sidebarInputStyle, height: 36, padding: 4 },
3069
- type: "color",
3070
- value: parseColor(selectedSectionStyle.contentBackgroundColor, "#ffffff")
3071
- }
3072
- )
3073
- ] }) : null,
3074
- normalizeText(selectedSectionStyle.contentBackgroundMode, "none") === "gradient" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
3075
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3076
- "Content Gradient Preset",
3114
+ activeSidebarPanel === "addSections" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { style: sidebarSectionStyle, children: [
3115
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { alignItems: "center", display: "flex", justifyContent: "space-between" }, children: [
3116
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: 13, fontWeight: 800 }, children: "Add Sections" }),
3077
3117
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3078
- "select",
3118
+ "button",
3079
3119
  {
3080
- onChange: (event) => applyGradientPreset("content", event.target.value),
3081
- style: sidebarInputStyle,
3082
- value: normalizeText(selectedSectionStyle.contentGradientPreset, "none"),
3083
- children: Object.keys(gradientPresetPairs).map((preset) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: preset, children: preset }, preset))
3120
+ onClick: collapseSidebar,
3121
+ style: {
3122
+ background: "transparent",
3123
+ border: "none",
3124
+ color: "var(--ink-700)",
3125
+ cursor: "pointer",
3126
+ fontSize: 12,
3127
+ fontWeight: 700,
3128
+ padding: 0
3129
+ },
3130
+ type: "button",
3131
+ children: "Hide"
3084
3132
  }
3085
3133
  )
3086
3134
  ] }),
3087
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "grid", gap: 6, gridTemplateColumns: "1fr 1fr" }, children: [
3088
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3089
- "From",
3135
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "grid", gap: 10, marginTop: 10 }, children: [
3136
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3137
+ "button",
3138
+ {
3139
+ onClick: applyTemplateStarter,
3140
+ style: {
3141
+ background: "#0f7d52",
3142
+ border: "none",
3143
+ borderRadius: 999,
3144
+ color: "#fff",
3145
+ cursor: "pointer",
3146
+ fontSize: 12,
3147
+ fontWeight: 700,
3148
+ padding: "8px 10px"
3149
+ },
3150
+ type: "button",
3151
+ children: [
3152
+ "Apply ",
3153
+ pageTemplate,
3154
+ " Template Starter"
3155
+ ]
3156
+ }
3157
+ ),
3158
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "grid", gap: 8 }, children: [
3090
3159
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3091
3160
  "input",
3092
3161
  {
3093
- onChange: (event) => setSelectedStyleField("contentGradientFrom", event.target.value),
3094
- style: { ...sidebarInputStyle, height: 36, padding: 4 },
3095
- type: "color",
3096
- value: parseColor(selectedSectionStyle.contentGradientFrom, "#ffffff")
3162
+ onChange: (event) => setPresetQuery(event.target.value),
3163
+ placeholder: "Search section presets...",
3164
+ style: sidebarInputStyle,
3165
+ type: "text",
3166
+ value: presetQuery
3097
3167
  }
3098
- )
3168
+ ),
3169
+ filteredSectionPresets.map((preset) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3170
+ "button",
3171
+ {
3172
+ onClick: () => addSectionPreset(preset.blocks),
3173
+ style: {
3174
+ border: "1px solid rgba(13, 74, 55, 0.2)",
3175
+ borderRadius: 10,
3176
+ cursor: "pointer",
3177
+ display: "grid",
3178
+ gap: 3,
3179
+ padding: 9,
3180
+ textAlign: "left"
3181
+ },
3182
+ type: "button",
3183
+ children: [
3184
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: 12, fontWeight: 700 }, children: preset.title }),
3185
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: "var(--ink-700)", fontSize: 11 }, children: preset.description })
3186
+ ]
3187
+ },
3188
+ preset.id
3189
+ )),
3190
+ filteredSectionPresets.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--ink-700)", fontSize: 11 }, children: "No presets match this search." }) : null
3099
3191
  ] }),
3100
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3101
- "To",
3102
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3103
- "input",
3192
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { borderTop: "1px solid rgba(13, 74, 55, 0.12)", marginTop: 2, paddingTop: 10 }, children: [
3193
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--ink-700)", fontSize: 11, fontWeight: 800, textTransform: "uppercase" }, children: "Quick Add Blocks" }),
3194
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "grid", gap: 6, gridTemplateColumns: "1fr 1fr", marginTop: 8 }, children: quickAddBlockTypes.map((type) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3195
+ "button",
3104
3196
  {
3105
- onChange: (event) => setSelectedStyleField("contentGradientTo", event.target.value),
3106
- style: { ...sidebarInputStyle, height: 36, padding: 4 },
3107
- type: "color",
3108
- value: parseColor(selectedSectionStyle.contentGradientTo, "#f4f6f2")
3109
- }
3110
- )
3197
+ onClick: () => addBlockByType(type),
3198
+ style: {
3199
+ border: "1px solid rgba(13, 74, 55, 0.2)",
3200
+ borderRadius: 10,
3201
+ cursor: "pointer",
3202
+ fontSize: 12,
3203
+ fontWeight: 600,
3204
+ padding: "8px 7px"
3205
+ },
3206
+ type: "button",
3207
+ children: [
3208
+ "+ ",
3209
+ blockTypeLabels[type] || type
3210
+ ]
3211
+ },
3212
+ type
3213
+ )) })
3111
3214
  ] })
3112
- ] }),
3113
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3114
- "Angle",
3115
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3116
- "input",
3117
- {
3118
- max: 360,
3119
- min: 0,
3120
- onChange: (event) => setSelectedStyleField("contentGradientAngle", event.target.value),
3121
- style: sidebarInputStyle,
3122
- type: "number",
3123
- value: parseAngle(selectedSectionStyle.contentGradientAngle, "135")
3124
- }
3125
- )
3126
3215
  ] })
3127
3216
  ] }) : null,
3128
- selectedType === "hero" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
3129
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3130
- "Variant",
3131
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3132
- "select",
3133
- {
3134
- onChange: (event) => updateSelectedField("variant", event.target.value),
3135
- style: sidebarInputStyle,
3136
- value: normalizeText(selectedBlock.variant, "default"),
3137
- children: [
3138
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "default", children: "Default" }),
3139
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "centered", children: "Centered" })
3140
- ]
3141
- }
3142
- )
3143
- ] }),
3144
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3145
- "Background Image URL",
3146
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3147
- "input",
3148
- {
3149
- onChange: (event) => updateSelectedField("backgroundImageURL", event.target.value),
3150
- placeholder: "https://...",
3151
- style: sidebarInputStyle,
3152
- type: "text",
3153
- value: normalizeText(selectedBlock.backgroundImageURL)
3154
- }
3155
- )
3156
- ] }),
3157
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3158
- "Background Color",
3159
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3160
- "input",
3161
- {
3162
- onChange: (event) => updateSelectedField("backgroundColor", event.target.value),
3163
- style: { ...sidebarInputStyle, height: 36, padding: 4 },
3164
- type: "color",
3165
- value: parseColor(selectedBlock.backgroundColor, "#124a37")
3166
- }
3167
- )
3168
- ] }),
3169
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3170
- "Upload Hero Background Image",
3217
+ activeSidebarPanel === "selected" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { style: sidebarSectionStyle, children: [
3218
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { alignItems: "center", display: "flex", justifyContent: "space-between" }, children: [
3219
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { fontSize: 13, fontWeight: 800 }, children: [
3220
+ "Selected Section ",
3221
+ selectedIndex !== null ? `#${selectedIndex + 1}` : ""
3222
+ ] }),
3171
3223
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3172
- "input",
3224
+ "button",
3173
3225
  {
3174
- accept: "image/*",
3175
- disabled: uploadingTarget !== null,
3176
- onChange: (event) => {
3177
- const file = event.currentTarget.files?.[0];
3178
- if (file) {
3179
- void uploadMediaForSelected({ kind: "hero" }, file);
3180
- }
3181
- event.currentTarget.value = "";
3226
+ onClick: collapseSidebar,
3227
+ style: {
3228
+ background: "transparent",
3229
+ border: "none",
3230
+ color: "var(--ink-700)",
3231
+ cursor: "pointer",
3232
+ fontSize: 12,
3233
+ fontWeight: 700,
3234
+ padding: 0
3182
3235
  },
3183
- style: sidebarInputStyle,
3184
- type: "file"
3185
- }
3186
- )
3187
- ] })
3188
- ] }) : null,
3189
- selectedType === "featureGrid" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
3190
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3191
- "Variant",
3192
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3193
- "select",
3194
- {
3195
- onChange: (event) => updateSelectedField("variant", event.target.value),
3196
- style: sidebarInputStyle,
3197
- value: normalizeText(selectedBlock.variant, "cards"),
3198
- children: [
3199
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "cards", children: "Cards" }),
3200
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "highlight", children: "Highlight" })
3201
- ]
3202
- }
3203
- )
3204
- ] }),
3205
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3206
- "Highlight Background Color",
3207
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3208
- "input",
3209
- {
3210
- onChange: (event) => updateSelectedField("backgroundColor", event.target.value),
3211
- style: { ...sidebarInputStyle, height: 36, padding: 4 },
3212
- type: "color",
3213
- value: parseColor(selectedBlock.backgroundColor, "#1f684f")
3236
+ type: "button",
3237
+ children: "Hide"
3214
3238
  }
3215
3239
  )
3216
3240
  ] }),
3217
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3218
- "button",
3219
- {
3220
- onClick: () => appendItemToSelected("items", {
3221
- description: "Describe this feature.",
3222
- icon: "04",
3223
- title: "New Feature"
3224
- }),
3225
- style: { borderRadius: 999, cursor: "pointer", fontSize: 12, padding: "7px 10px" },
3226
- type: "button",
3227
- children: "Add Feature Item"
3228
- }
3229
- ),
3230
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "grid", gap: 8 }, children: selectedItems.map((item, itemIndex) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { border: "1px solid rgba(13, 74, 55, 0.16)", borderRadius: 10, display: "grid", gap: 6, padding: 8 }, children: [
3231
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { color: "var(--ink-700)", fontSize: 11, fontWeight: 700 }, children: [
3232
- "Item ",
3233
- itemIndex + 1
3234
- ] }),
3235
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3236
- "input",
3237
- {
3238
- onChange: (event) => updateArrayItemField(selectedIndex ?? 0, "items", itemIndex, "title", event.target.value),
3239
- placeholder: "Title",
3240
- style: sidebarInputStyle,
3241
- type: "text",
3242
- value: normalizeText(item.title)
3243
- }
3244
- ),
3245
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3246
- "input",
3247
- {
3248
- onChange: (event) => updateArrayItemField(selectedIndex ?? 0, "items", itemIndex, "icon", event.target.value),
3249
- placeholder: "Icon",
3250
- style: sidebarInputStyle,
3251
- type: "text",
3252
- value: normalizeText(item.icon)
3253
- }
3254
- ),
3255
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3256
- "textarea",
3257
- {
3258
- onChange: (event) => updateArrayItemField(selectedIndex ?? 0, "items", itemIndex, "description", event.target.value),
3259
- placeholder: "Description",
3260
- style: { ...sidebarInputStyle, minHeight: 70, resize: "vertical" },
3261
- value: normalizeText(item.description)
3262
- }
3263
- ),
3264
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3265
- "Item Image",
3241
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "grid", gap: 8, marginTop: 10 }, children: selectedBlock ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
3242
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--ink-700)", fontSize: 12, fontWeight: 600 }, children: blockTypeLabels[selectedType] || selectedType }),
3243
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", flexWrap: "wrap", gap: 6 }, children: [
3266
3244
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3267
- "input",
3245
+ "button",
3268
3246
  {
3269
- accept: "image/*",
3270
- disabled: uploadingTarget !== null,
3271
- onChange: (event) => {
3272
- const file = event.currentTarget.files?.[0];
3273
- if (file) {
3274
- void uploadMediaForSelected({ field: "media", itemIndex, kind: "featureGridItem" }, file);
3275
- }
3276
- event.currentTarget.value = "";
3247
+ disabled: selectedIndex === null || selectedIndex <= 0,
3248
+ onClick: () => moveSelectedBlock("up"),
3249
+ style: { borderRadius: 999, cursor: "pointer", fontSize: 12, padding: "7px 10px" },
3250
+ type: "button",
3251
+ children: "Move Up"
3252
+ }
3253
+ ),
3254
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3255
+ "button",
3256
+ {
3257
+ disabled: selectedIndex === null || selectedIndex >= layout.length - 1,
3258
+ onClick: () => moveSelectedBlock("down"),
3259
+ style: { borderRadius: 999, cursor: "pointer", fontSize: 12, padding: "7px 10px" },
3260
+ type: "button",
3261
+ children: "Move Down"
3262
+ }
3263
+ ),
3264
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3265
+ "button",
3266
+ {
3267
+ onClick: duplicateSelectedBlock,
3268
+ style: { borderRadius: 999, cursor: "pointer", fontSize: 12, padding: "7px 10px" },
3269
+ type: "button",
3270
+ children: "Duplicate"
3271
+ }
3272
+ ),
3273
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3274
+ "button",
3275
+ {
3276
+ onClick: removeSelectedBlock,
3277
+ style: {
3278
+ background: "#8d1d1d",
3279
+ border: "none",
3280
+ borderRadius: 999,
3281
+ color: "#fff",
3282
+ cursor: "pointer",
3283
+ fontSize: 12,
3284
+ padding: "7px 10px"
3277
3285
  },
3286
+ type: "button",
3287
+ children: "Remove"
3288
+ }
3289
+ )
3290
+ ] }),
3291
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { color: "var(--ink-700)", fontSize: 11 }, children: [
3292
+ "Section width follows ",
3293
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: "Page Defaults" }),
3294
+ " for a consistent page layout."
3295
+ ] }),
3296
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3297
+ "Content Width",
3298
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3299
+ "select",
3300
+ {
3301
+ onChange: (event) => setSelectedStyleField("contentWidth", event.target.value),
3278
3302
  style: sidebarInputStyle,
3279
- type: "file"
3303
+ value: normalizeText(selectedSectionStyle.contentWidth, "inherit"),
3304
+ children: [
3305
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "inherit", children: "Inherit Page Default" }),
3306
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "narrow", children: "Narrow" }),
3307
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "content", children: "Content" }),
3308
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "wide", children: "Wide" }),
3309
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "full", children: "Full" })
3310
+ ]
3280
3311
  }
3281
3312
  )
3282
3313
  ] }),
3283
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3284
- "button",
3285
- {
3286
- onClick: () => removeItemFromSelected("items", itemIndex),
3287
- style: { borderRadius: 999, cursor: "pointer", fontSize: 12, padding: "7px 10px" },
3288
- type: "button",
3289
- children: "Remove Item"
3290
- }
3291
- )
3292
- ] }, `feature-item-control-${itemIndex}`)) })
3293
- ] }) : null,
3294
- selectedType === "stats" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
3295
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3296
- "button",
3297
- {
3298
- onClick: () => appendItemToSelected("items", {
3299
- description: "Add context for this metric.",
3300
- label: "Metric",
3301
- value: "00"
3302
- }),
3303
- style: { borderRadius: 999, cursor: "pointer", fontSize: 12, padding: "7px 10px" },
3304
- type: "button",
3305
- children: "Add Stat"
3306
- }
3307
- ),
3308
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "grid", gap: 8 }, children: selectedItems.map((item, itemIndex) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { border: "1px solid rgba(13, 74, 55, 0.16)", borderRadius: 10, display: "grid", gap: 6, padding: 8 }, children: [
3309
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3310
- "input",
3311
- {
3312
- onChange: (event) => updateArrayItemField(selectedIndex ?? 0, "items", itemIndex, "value", event.target.value),
3313
- placeholder: "Value",
3314
- style: sidebarInputStyle,
3315
- type: "text",
3316
- value: normalizeText(item.value)
3317
- }
3318
- ),
3319
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3320
- "input",
3321
- {
3322
- onChange: (event) => updateArrayItemField(selectedIndex ?? 0, "items", itemIndex, "label", event.target.value),
3323
- placeholder: "Label",
3324
- style: sidebarInputStyle,
3325
- type: "text",
3326
- value: normalizeText(item.label)
3327
- }
3328
- ),
3329
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3330
- "input",
3331
- {
3332
- onChange: (event) => updateArrayItemField(selectedIndex ?? 0, "items", itemIndex, "description", event.target.value),
3333
- placeholder: "Description",
3334
- style: sidebarInputStyle,
3335
- type: "text",
3336
- value: normalizeText(item.description)
3337
- }
3338
- ),
3339
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3340
- "button",
3341
- {
3342
- onClick: () => removeItemFromSelected("items", itemIndex),
3343
- style: { borderRadius: 999, cursor: "pointer", fontSize: 12, padding: "7px 10px" },
3344
- type: "button",
3345
- children: "Remove Item"
3346
- }
3347
- )
3348
- ] }, `stats-item-control-${itemIndex}`)) })
3349
- ] }) : null,
3350
- selectedType === "logoWall" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
3351
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3352
- "button",
3353
- {
3354
- onClick: () => appendItemToSelected("items", {
3355
- href: "",
3356
- name: "Partner"
3357
- }),
3358
- style: { borderRadius: 999, cursor: "pointer", fontSize: 12, padding: "7px 10px" },
3359
- type: "button",
3360
- children: "Add Logo"
3361
- }
3362
- ),
3363
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "grid", gap: 8 }, children: selectedItems.map((item, itemIndex) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { border: "1px solid rgba(13, 74, 55, 0.16)", borderRadius: 10, display: "grid", gap: 6, padding: 8 }, children: [
3364
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3365
- "input",
3366
- {
3367
- onChange: (event) => updateArrayItemField(selectedIndex ?? 0, "items", itemIndex, "name", event.target.value),
3368
- placeholder: "Partner Name",
3369
- style: sidebarInputStyle,
3370
- type: "text",
3371
- value: normalizeText(item.name)
3372
- }
3373
- ),
3374
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3375
- "input",
3376
- {
3377
- onChange: (event) => updateArrayItemField(selectedIndex ?? 0, "items", itemIndex, "href", event.target.value),
3378
- placeholder: "https://example.com",
3379
- style: sidebarInputStyle,
3380
- type: "text",
3381
- value: normalizeText(item.href)
3382
- }
3383
- ),
3384
3314
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3385
- "Logo Image",
3386
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3387
- "input",
3315
+ "Section Vertical Spacing",
3316
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3317
+ "select",
3388
3318
  {
3389
- accept: "image/*",
3390
- disabled: uploadingTarget !== null,
3391
- onChange: (event) => {
3392
- const file = event.currentTarget.files?.[0];
3393
- if (file) {
3394
- void uploadMediaForSelected({ field: "media", itemIndex, kind: "logoWallItem" }, file);
3395
- }
3396
- event.currentTarget.value = "";
3397
- },
3319
+ onChange: (event) => setSelectedStyleField("sectionPaddingY", event.target.value),
3398
3320
  style: sidebarInputStyle,
3399
- type: "file"
3321
+ value: normalizeText(selectedSectionStyle.sectionPaddingY, "md"),
3322
+ children: [
3323
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "none", children: "None" }),
3324
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "sm", children: "Small" }),
3325
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "md", children: "Medium" }),
3326
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "lg", children: "Large" })
3327
+ ]
3400
3328
  }
3401
3329
  )
3402
3330
  ] }),
3403
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3404
- "button",
3405
- {
3406
- onClick: () => removeItemFromSelected("items", itemIndex),
3407
- style: { borderRadius: 999, cursor: "pointer", fontSize: 12, padding: "7px 10px" },
3408
- type: "button",
3409
- children: "Remove Item"
3410
- }
3411
- )
3412
- ] }, `logo-item-control-${itemIndex}`)) })
3413
- ] }) : null,
3414
- selectedType === "beforeAfter" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
3415
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3416
- "button",
3417
- {
3418
- onClick: () => appendItemToSelected("items", {
3419
- description: "Describe the outcome.",
3420
- label: "Project"
3421
- }),
3422
- style: { borderRadius: 999, cursor: "pointer", fontSize: 12, padding: "7px 10px" },
3423
- type: "button",
3424
- children: "Add Before/After Pair"
3425
- }
3426
- ),
3427
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "grid", gap: 8 }, children: selectedItems.map((item, itemIndex) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { border: "1px solid rgba(13, 74, 55, 0.16)", borderRadius: 10, display: "grid", gap: 6, padding: 8 }, children: [
3428
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3429
- "input",
3430
- {
3431
- onChange: (event) => updateArrayItemField(selectedIndex ?? 0, "items", itemIndex, "label", event.target.value),
3432
- placeholder: "Project Label",
3433
- style: sidebarInputStyle,
3434
- type: "text",
3435
- value: normalizeText(item.label)
3436
- }
3437
- ),
3438
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3439
- "textarea",
3440
- {
3441
- onChange: (event) => updateArrayItemField(selectedIndex ?? 0, "items", itemIndex, "description", event.target.value),
3442
- placeholder: "Description",
3443
- style: { ...sidebarInputStyle, minHeight: 70, resize: "vertical" },
3444
- value: normalizeText(item.description)
3445
- }
3446
- ),
3447
3331
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3448
- "Before Image",
3332
+ "Section Horizontal Spacing",
3333
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3334
+ "select",
3335
+ {
3336
+ onChange: (event) => setSelectedStyleField("sectionPaddingX", event.target.value),
3337
+ style: sidebarInputStyle,
3338
+ value: normalizeText(selectedSectionStyle.sectionPaddingX, "inherit"),
3339
+ children: [
3340
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "inherit", children: "Inherit (Edge-to-Edge on Full Width)" }),
3341
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "none", children: "None" }),
3342
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "sm", children: "Small" }),
3343
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "md", children: "Medium" }),
3344
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "lg", children: "Large" })
3345
+ ]
3346
+ }
3347
+ )
3348
+ ] }),
3349
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3350
+ "Section Background",
3351
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3352
+ "select",
3353
+ {
3354
+ onChange: (event) => setSelectedStyleField("sectionBackgroundMode", event.target.value),
3355
+ style: sidebarInputStyle,
3356
+ value: normalizeText(selectedSectionStyle.sectionBackgroundMode, "none"),
3357
+ children: [
3358
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "none", children: "None" }),
3359
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "color", children: "Color" }),
3360
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "gradient", children: "Gradient" })
3361
+ ]
3362
+ }
3363
+ )
3364
+ ] }),
3365
+ normalizeText(selectedSectionStyle.sectionBackgroundMode, "none") === "color" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3366
+ "Section Background Color",
3449
3367
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3450
3368
  "input",
3451
3369
  {
3452
- accept: "image/*",
3453
- disabled: uploadingTarget !== null,
3454
- onChange: (event) => {
3455
- const file = event.currentTarget.files?.[0];
3456
- if (file) {
3457
- void uploadMediaForSelected({ field: "beforeMedia", itemIndex, kind: "beforeAfterItem" }, file);
3370
+ onChange: (event) => setSelectedStyleField("sectionBackgroundColor", event.target.value),
3371
+ style: { ...sidebarInputStyle, height: 36, padding: 4 },
3372
+ type: "color",
3373
+ value: parseColor(selectedSectionStyle.sectionBackgroundColor, "#ffffff")
3374
+ }
3375
+ )
3376
+ ] }) : null,
3377
+ normalizeText(selectedSectionStyle.sectionBackgroundMode, "none") === "gradient" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
3378
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3379
+ "Section Gradient Preset",
3380
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3381
+ "select",
3382
+ {
3383
+ onChange: (event) => applyGradientPreset("section", event.target.value),
3384
+ style: sidebarInputStyle,
3385
+ value: normalizeText(selectedSectionStyle.sectionGradientPreset, "forest"),
3386
+ children: Object.keys(gradientPresetPairs).map((preset) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: preset, children: preset }, preset))
3387
+ }
3388
+ )
3389
+ ] }),
3390
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "grid", gap: 6, gridTemplateColumns: "1fr 1fr" }, children: [
3391
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3392
+ "From",
3393
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3394
+ "input",
3395
+ {
3396
+ onChange: (event) => setSelectedStyleField("sectionGradientFrom", event.target.value),
3397
+ style: { ...sidebarInputStyle, height: 36, padding: 4 },
3398
+ type: "color",
3399
+ value: parseColor(selectedSectionStyle.sectionGradientFrom, "#124a37")
3458
3400
  }
3459
- event.currentTarget.value = "";
3460
- },
3401
+ )
3402
+ ] }),
3403
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3404
+ "To",
3405
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3406
+ "input",
3407
+ {
3408
+ onChange: (event) => setSelectedStyleField("sectionGradientTo", event.target.value),
3409
+ style: { ...sidebarInputStyle, height: 36, padding: 4 },
3410
+ type: "color",
3411
+ value: parseColor(selectedSectionStyle.sectionGradientTo, "#1f684f")
3412
+ }
3413
+ )
3414
+ ] })
3415
+ ] }),
3416
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3417
+ "Angle",
3418
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3419
+ "input",
3420
+ {
3421
+ max: 360,
3422
+ min: 0,
3423
+ onChange: (event) => setSelectedStyleField("sectionGradientAngle", event.target.value),
3424
+ style: sidebarInputStyle,
3425
+ type: "number",
3426
+ value: parseAngle(selectedSectionStyle.sectionGradientAngle, "135")
3427
+ }
3428
+ )
3429
+ ] })
3430
+ ] }) : null,
3431
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3432
+ "Content Background",
3433
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3434
+ "select",
3435
+ {
3436
+ onChange: (event) => setSelectedStyleField("contentBackgroundMode", event.target.value),
3461
3437
  style: sidebarInputStyle,
3462
- type: "file"
3438
+ value: normalizeText(selectedSectionStyle.contentBackgroundMode, "none"),
3439
+ children: [
3440
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "none", children: "None" }),
3441
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "color", children: "Color" }),
3442
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "gradient", children: "Gradient" })
3443
+ ]
3463
3444
  }
3464
3445
  )
3465
3446
  ] }),
3466
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3467
- "After Image",
3447
+ normalizeText(selectedSectionStyle.contentBackgroundMode, "none") === "color" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3448
+ "Content Background Color",
3468
3449
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3469
3450
  "input",
3470
3451
  {
3471
- accept: "image/*",
3472
- disabled: uploadingTarget !== null,
3473
- onChange: (event) => {
3474
- const file = event.currentTarget.files?.[0];
3475
- if (file) {
3476
- void uploadMediaForSelected({ field: "afterMedia", itemIndex, kind: "beforeAfterItem" }, file);
3452
+ onChange: (event) => setSelectedStyleField("contentBackgroundColor", event.target.value),
3453
+ style: { ...sidebarInputStyle, height: 36, padding: 4 },
3454
+ type: "color",
3455
+ value: parseColor(selectedSectionStyle.contentBackgroundColor, "#ffffff")
3456
+ }
3457
+ )
3458
+ ] }) : null,
3459
+ normalizeText(selectedSectionStyle.contentBackgroundMode, "none") === "gradient" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
3460
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3461
+ "Content Gradient Preset",
3462
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3463
+ "select",
3464
+ {
3465
+ onChange: (event) => applyGradientPreset("content", event.target.value),
3466
+ style: sidebarInputStyle,
3467
+ value: normalizeText(selectedSectionStyle.contentGradientPreset, "none"),
3468
+ children: Object.keys(gradientPresetPairs).map((preset) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: preset, children: preset }, preset))
3469
+ }
3470
+ )
3471
+ ] }),
3472
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "grid", gap: 6, gridTemplateColumns: "1fr 1fr" }, children: [
3473
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3474
+ "From",
3475
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3476
+ "input",
3477
+ {
3478
+ onChange: (event) => setSelectedStyleField("contentGradientFrom", event.target.value),
3479
+ style: { ...sidebarInputStyle, height: 36, padding: 4 },
3480
+ type: "color",
3481
+ value: parseColor(selectedSectionStyle.contentGradientFrom, "#ffffff")
3477
3482
  }
3478
- event.currentTarget.value = "";
3479
- },
3483
+ )
3484
+ ] }),
3485
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3486
+ "To",
3487
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3488
+ "input",
3489
+ {
3490
+ onChange: (event) => setSelectedStyleField("contentGradientTo", event.target.value),
3491
+ style: { ...sidebarInputStyle, height: 36, padding: 4 },
3492
+ type: "color",
3493
+ value: parseColor(selectedSectionStyle.contentGradientTo, "#f4f6f2")
3494
+ }
3495
+ )
3496
+ ] })
3497
+ ] }),
3498
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3499
+ "Angle",
3500
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3501
+ "input",
3502
+ {
3503
+ max: 360,
3504
+ min: 0,
3505
+ onChange: (event) => setSelectedStyleField("contentGradientAngle", event.target.value),
3506
+ style: sidebarInputStyle,
3507
+ type: "number",
3508
+ value: parseAngle(selectedSectionStyle.contentGradientAngle, "135")
3509
+ }
3510
+ )
3511
+ ] })
3512
+ ] }) : null,
3513
+ selectedType === "hero" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
3514
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3515
+ "Variant",
3516
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3517
+ "select",
3518
+ {
3519
+ onChange: (event) => updateSelectedField("variant", event.target.value),
3520
+ style: sidebarInputStyle,
3521
+ value: normalizeText(selectedBlock.variant, "default"),
3522
+ children: [
3523
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "default", children: "Default" }),
3524
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "centered", children: "Centered" })
3525
+ ]
3526
+ }
3527
+ )
3528
+ ] }),
3529
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3530
+ "Hero Height",
3531
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3532
+ "select",
3533
+ {
3534
+ onChange: (event) => updateSelectedField("heroHeight", event.target.value),
3535
+ style: sidebarInputStyle,
3536
+ value: normalizeHeroHeight(selectedBlock.heroHeight),
3537
+ children: [
3538
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "sm", children: "Small" }),
3539
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "md", children: "Medium (Half Screen)" }),
3540
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "full", children: "Full Screen" })
3541
+ ]
3542
+ }
3543
+ )
3544
+ ] }),
3545
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { ...sidebarSectionStyle, display: "grid", gap: 8 }, children: [
3546
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--ink-700)", fontSize: 12, fontWeight: 600 }, children: "Hero Image" }),
3547
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--ink-700)", fontSize: 12 }, children: selectedHeroMedia ? `${selectedHeroMedia.filename || `Media #${selectedHeroMedia.id}`}${selectedHeroMedia.alt ? ` (${selectedHeroMedia.alt})` : ""}` : "No image selected." }),
3548
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3549
+ "Choose from Media Library",
3550
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3551
+ "select",
3552
+ {
3553
+ onChange: (event) => setHeroMediaFromLibrary(event.target.value),
3554
+ style: sidebarInputStyle,
3555
+ value: selectedHeroMediaID,
3556
+ children: [
3557
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: "No image" }),
3558
+ mediaLibrary.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: String(item.id), children: mediaLabel(item) }, String(item.id)))
3559
+ ]
3560
+ }
3561
+ )
3562
+ ] }),
3563
+ mediaLibraryLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--ink-700)", fontSize: 11 }, children: "Loading media library..." }) : null,
3564
+ mediaLibraryError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#8d1d1d", fontSize: 11 }, children: mediaLibraryError }) : null,
3565
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3566
+ "button",
3567
+ {
3568
+ disabled: !selectedHeroMedia && !selectedHeroMediaID,
3569
+ onClick: clearHeroMedia,
3570
+ style: {
3571
+ borderRadius: 999,
3572
+ cursor: selectedHeroMedia || selectedHeroMediaID ? "pointer" : "not-allowed",
3573
+ fontSize: 12,
3574
+ padding: "7px 10px"
3575
+ },
3576
+ type: "button",
3577
+ children: "Remove Hero Image"
3578
+ }
3579
+ ),
3580
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3581
+ "Upload Hero Background Image",
3582
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3583
+ "input",
3584
+ {
3585
+ accept: "image/*",
3586
+ disabled: uploadingTarget !== null,
3587
+ onChange: (event) => {
3588
+ const file = event.currentTarget.files?.[0];
3589
+ if (file) {
3590
+ void uploadMediaForSelected({ kind: "hero" }, file);
3591
+ }
3592
+ event.currentTarget.value = "";
3593
+ },
3594
+ style: sidebarInputStyle,
3595
+ type: "file"
3596
+ }
3597
+ )
3598
+ ] }),
3599
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3600
+ "Image Fit",
3601
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3602
+ "select",
3603
+ {
3604
+ onChange: (event) => updateSelectedField("backgroundImageFit", event.target.value),
3605
+ style: sidebarInputStyle,
3606
+ value: normalizeHeroImageFit(selectedBlock.backgroundImageFit),
3607
+ children: [
3608
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "cover", children: "Cover" }),
3609
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "contain", children: "Contain" })
3610
+ ]
3611
+ }
3612
+ )
3613
+ ] }),
3614
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3615
+ "Image Corners",
3616
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3617
+ "select",
3618
+ {
3619
+ onChange: (event) => updateSelectedField("backgroundImageCornerStyle", event.target.value),
3620
+ style: sidebarInputStyle,
3621
+ value: normalizeHeroImageCornerStyle(
3622
+ selectedBlock.backgroundImageCornerStyle,
3623
+ selectedBlock.backgroundImageFit
3624
+ ),
3625
+ children: [
3626
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "rounded", children: "Rounded" }),
3627
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "square", children: "Square" })
3628
+ ]
3629
+ }
3630
+ )
3631
+ ] }),
3632
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3633
+ "Image Position",
3634
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3635
+ "select",
3636
+ {
3637
+ onChange: (event) => updateSelectedField("backgroundImagePosition", event.target.value),
3638
+ style: sidebarInputStyle,
3639
+ value: normalizeHeroImagePosition(selectedBlock.backgroundImagePosition),
3640
+ children: [
3641
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "center", children: "Center" }),
3642
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "top", children: "Top" }),
3643
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "bottom", children: "Bottom" }),
3644
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "left", children: "Left" }),
3645
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "right", children: "Right" })
3646
+ ]
3647
+ }
3648
+ )
3649
+ ] })
3650
+ ] }),
3651
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3652
+ "Background Color",
3653
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3654
+ "input",
3655
+ {
3656
+ onChange: (event) => updateSelectedField("backgroundColor", event.target.value),
3657
+ style: { ...sidebarInputStyle, height: 36, padding: 4 },
3658
+ type: "color",
3659
+ value: parseColor(selectedBlock.backgroundColor, "#ffffff")
3660
+ }
3661
+ )
3662
+ ] }),
3663
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3664
+ "button",
3665
+ {
3666
+ onClick: () => updateSelectedField("backgroundColor", ""),
3667
+ style: { borderRadius: 999, cursor: "pointer", fontSize: 12, padding: "7px 10px" },
3668
+ type: "button",
3669
+ children: "Clear Hero Background Color"
3670
+ }
3671
+ )
3672
+ ] }) : null,
3673
+ selectedType === "featureGrid" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
3674
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3675
+ "Variant",
3676
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3677
+ "select",
3678
+ {
3679
+ onChange: (event) => updateSelectedField("variant", event.target.value),
3680
+ style: sidebarInputStyle,
3681
+ value: normalizeText(selectedBlock.variant, "cards"),
3682
+ children: [
3683
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "cards", children: "Cards" }),
3684
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "highlight", children: "Highlight" })
3685
+ ]
3686
+ }
3687
+ )
3688
+ ] }),
3689
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3690
+ "Highlight Background Color",
3691
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3692
+ "input",
3693
+ {
3694
+ onChange: (event) => updateSelectedField("backgroundColor", event.target.value),
3695
+ style: { ...sidebarInputStyle, height: 36, padding: 4 },
3696
+ type: "color",
3697
+ value: parseColor(selectedBlock.backgroundColor, "#1f684f")
3698
+ }
3699
+ )
3700
+ ] }),
3701
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3702
+ "button",
3703
+ {
3704
+ onClick: () => appendItemToSelected("items", {
3705
+ description: "Describe this feature.",
3706
+ icon: "04",
3707
+ imageCornerStyle: "rounded",
3708
+ imageFit: "cover",
3709
+ imagePosition: "center",
3710
+ title: "New Feature"
3711
+ }),
3712
+ style: { borderRadius: 999, cursor: "pointer", fontSize: 12, padding: "7px 10px" },
3713
+ type: "button",
3714
+ children: "Add Feature Item"
3715
+ }
3716
+ ),
3717
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "grid", gap: 8 }, children: selectedItems.map((item, itemIndex) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { border: "1px solid rgba(13, 74, 55, 0.16)", borderRadius: 10, display: "grid", gap: 6, padding: 8 }, children: [
3718
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { color: "var(--ink-700)", fontSize: 11, fontWeight: 700 }, children: [
3719
+ "Item ",
3720
+ itemIndex + 1
3721
+ ] }),
3722
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3723
+ "input",
3724
+ {
3725
+ onChange: (event) => updateArrayItemField(selectedIndex ?? 0, "items", itemIndex, "title", event.target.value),
3726
+ placeholder: "Title",
3727
+ style: sidebarInputStyle,
3728
+ type: "text",
3729
+ value: normalizeText(item.title)
3730
+ }
3731
+ ),
3732
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3733
+ "input",
3734
+ {
3735
+ onChange: (event) => updateArrayItemField(selectedIndex ?? 0, "items", itemIndex, "icon", event.target.value),
3736
+ placeholder: "Icon",
3737
+ style: sidebarInputStyle,
3738
+ type: "text",
3739
+ value: normalizeText(item.icon)
3740
+ }
3741
+ ),
3742
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3743
+ "textarea",
3744
+ {
3745
+ onChange: (event) => updateArrayItemField(selectedIndex ?? 0, "items", itemIndex, "description", event.target.value),
3746
+ placeholder: "Description",
3747
+ style: { ...sidebarInputStyle, minHeight: 70, resize: "vertical" },
3748
+ value: normalizeText(item.description)
3749
+ }
3750
+ ),
3751
+ (() => {
3752
+ const itemMedia = resolveMediaLibraryItemFromValue(item.media);
3753
+ const itemMediaID = getRelationID(item.media);
3754
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
3755
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--ink-700)", fontSize: 12 }, children: itemMedia ? `Selected image: ${mediaLabel(itemMedia)}` : "No item image selected." }),
3756
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3757
+ "Choose from Media Library",
3758
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3759
+ "select",
3760
+ {
3761
+ onChange: (event) => setSelectedItemMediaFieldFromLibrary(itemIndex, "media", event.target.value),
3762
+ style: sidebarInputStyle,
3763
+ value: itemMediaID !== null ? String(itemMediaID) : "",
3764
+ children: [
3765
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: "No image" }),
3766
+ mediaLibrary.map((libraryItem) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: String(libraryItem.id), children: mediaLabel(libraryItem) }, String(libraryItem.id)))
3767
+ ]
3768
+ }
3769
+ )
3770
+ ] }),
3771
+ mediaLibraryLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--ink-700)", fontSize: 11 }, children: "Loading media library..." }) : null,
3772
+ mediaLibraryError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#8d1d1d", fontSize: 11 }, children: mediaLibraryError }) : null,
3773
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3774
+ "button",
3775
+ {
3776
+ disabled: !itemMedia && itemMediaID === null,
3777
+ onClick: () => setSelectedItemMediaFieldFromLibrary(itemIndex, "media", ""),
3778
+ style: {
3779
+ borderRadius: 999,
3780
+ cursor: itemMedia || itemMediaID !== null ? "pointer" : "not-allowed",
3781
+ fontSize: 12,
3782
+ padding: "7px 10px"
3783
+ },
3784
+ type: "button",
3785
+ children: "Remove Item Image"
3786
+ }
3787
+ ),
3788
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3789
+ "Image Fit",
3790
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3791
+ "select",
3792
+ {
3793
+ onChange: (event) => updateArrayItemField(
3794
+ selectedIndex ?? 0,
3795
+ "items",
3796
+ itemIndex,
3797
+ "imageFit",
3798
+ event.target.value
3799
+ ),
3800
+ style: sidebarInputStyle,
3801
+ value: normalizeImageFit(item.imageFit),
3802
+ children: [
3803
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "cover", children: "Cover" }),
3804
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "contain", children: "Contain" })
3805
+ ]
3806
+ }
3807
+ )
3808
+ ] }),
3809
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3810
+ "Image Corners",
3811
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3812
+ "select",
3813
+ {
3814
+ onChange: (event) => updateArrayItemField(
3815
+ selectedIndex ?? 0,
3816
+ "items",
3817
+ itemIndex,
3818
+ "imageCornerStyle",
3819
+ event.target.value
3820
+ ),
3821
+ style: sidebarInputStyle,
3822
+ value: normalizeImageCornerStyle(item.imageCornerStyle),
3823
+ children: [
3824
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "rounded", children: "Rounded" }),
3825
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "square", children: "Square" })
3826
+ ]
3827
+ }
3828
+ )
3829
+ ] }),
3830
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3831
+ "Image Position",
3832
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3833
+ "select",
3834
+ {
3835
+ onChange: (event) => updateArrayItemField(
3836
+ selectedIndex ?? 0,
3837
+ "items",
3838
+ itemIndex,
3839
+ "imagePosition",
3840
+ event.target.value
3841
+ ),
3842
+ style: sidebarInputStyle,
3843
+ value: normalizeImagePosition(item.imagePosition),
3844
+ children: [
3845
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "center", children: "Center" }),
3846
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "top", children: "Top" }),
3847
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "bottom", children: "Bottom" }),
3848
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "left", children: "Left" }),
3849
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "right", children: "Right" })
3850
+ ]
3851
+ }
3852
+ )
3853
+ ] })
3854
+ ] });
3855
+ })(),
3856
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3857
+ "Upload Item Image",
3858
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3859
+ "input",
3860
+ {
3861
+ accept: "image/*",
3862
+ disabled: uploadingTarget !== null,
3863
+ onChange: (event) => {
3864
+ const file = event.currentTarget.files?.[0];
3865
+ if (file) {
3866
+ void uploadMediaForSelected({ field: "media", itemIndex, kind: "featureGridItem" }, file);
3867
+ }
3868
+ event.currentTarget.value = "";
3869
+ },
3870
+ style: sidebarInputStyle,
3871
+ type: "file"
3872
+ }
3873
+ )
3874
+ ] }),
3875
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3876
+ "button",
3877
+ {
3878
+ onClick: () => removeItemFromSelected("items", itemIndex),
3879
+ style: { borderRadius: 999, cursor: "pointer", fontSize: 12, padding: "7px 10px" },
3880
+ type: "button",
3881
+ children: "Remove Item"
3882
+ }
3883
+ )
3884
+ ] }, `feature-item-control-${itemIndex}`)) })
3885
+ ] }) : null,
3886
+ selectedType === "stats" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
3887
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3888
+ "button",
3889
+ {
3890
+ onClick: () => appendItemToSelected("items", {
3891
+ description: "Add context for this metric.",
3892
+ label: "Metric",
3893
+ value: "00"
3894
+ }),
3895
+ style: { borderRadius: 999, cursor: "pointer", fontSize: 12, padding: "7px 10px" },
3896
+ type: "button",
3897
+ children: "Add Stat"
3898
+ }
3899
+ ),
3900
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "grid", gap: 8 }, children: selectedItems.map((item, itemIndex) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { border: "1px solid rgba(13, 74, 55, 0.16)", borderRadius: 10, display: "grid", gap: 6, padding: 8 }, children: [
3901
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3902
+ "input",
3903
+ {
3904
+ onChange: (event) => updateArrayItemField(selectedIndex ?? 0, "items", itemIndex, "value", event.target.value),
3905
+ placeholder: "Value",
3906
+ style: sidebarInputStyle,
3907
+ type: "text",
3908
+ value: normalizeText(item.value)
3909
+ }
3910
+ ),
3911
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3912
+ "input",
3913
+ {
3914
+ onChange: (event) => updateArrayItemField(selectedIndex ?? 0, "items", itemIndex, "label", event.target.value),
3915
+ placeholder: "Label",
3916
+ style: sidebarInputStyle,
3917
+ type: "text",
3918
+ value: normalizeText(item.label)
3919
+ }
3920
+ ),
3921
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3922
+ "input",
3923
+ {
3924
+ onChange: (event) => updateArrayItemField(selectedIndex ?? 0, "items", itemIndex, "description", event.target.value),
3925
+ placeholder: "Description",
3926
+ style: sidebarInputStyle,
3927
+ type: "text",
3928
+ value: normalizeText(item.description)
3929
+ }
3930
+ ),
3931
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3932
+ "button",
3933
+ {
3934
+ onClick: () => removeItemFromSelected("items", itemIndex),
3935
+ style: { borderRadius: 999, cursor: "pointer", fontSize: 12, padding: "7px 10px" },
3936
+ type: "button",
3937
+ children: "Remove Item"
3938
+ }
3939
+ )
3940
+ ] }, `stats-item-control-${itemIndex}`)) })
3941
+ ] }) : null,
3942
+ selectedType === "logoWall" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
3943
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3944
+ "button",
3945
+ {
3946
+ onClick: () => appendItemToSelected("items", {
3947
+ href: "",
3948
+ imageCornerStyle: "rounded",
3949
+ imageFit: "contain",
3950
+ imagePosition: "center",
3951
+ name: "Partner"
3952
+ }),
3953
+ style: { borderRadius: 999, cursor: "pointer", fontSize: 12, padding: "7px 10px" },
3954
+ type: "button",
3955
+ children: "Add Logo"
3956
+ }
3957
+ ),
3958
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "grid", gap: 8 }, children: selectedItems.map((item, itemIndex) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { border: "1px solid rgba(13, 74, 55, 0.16)", borderRadius: 10, display: "grid", gap: 6, padding: 8 }, children: [
3959
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3960
+ "input",
3961
+ {
3962
+ onChange: (event) => updateArrayItemField(selectedIndex ?? 0, "items", itemIndex, "name", event.target.value),
3963
+ placeholder: "Partner Name",
3964
+ style: sidebarInputStyle,
3965
+ type: "text",
3966
+ value: normalizeText(item.name)
3967
+ }
3968
+ ),
3969
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3970
+ "input",
3971
+ {
3972
+ onChange: (event) => updateArrayItemField(selectedIndex ?? 0, "items", itemIndex, "href", event.target.value),
3973
+ placeholder: "https://example.com",
3974
+ style: sidebarInputStyle,
3975
+ type: "text",
3976
+ value: normalizeText(item.href)
3977
+ }
3978
+ ),
3979
+ (() => {
3980
+ const logoMedia = resolveMediaLibraryItemFromValue(item.media);
3981
+ const logoMediaID = getRelationID(item.media);
3982
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
3983
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--ink-700)", fontSize: 12 }, children: logoMedia ? `Selected logo: ${mediaLabel(logoMedia)}` : "No logo image selected." }),
3984
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3985
+ "Choose from Media Library",
3986
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3987
+ "select",
3988
+ {
3989
+ onChange: (event) => setSelectedItemMediaFieldFromLibrary(itemIndex, "media", event.target.value),
3990
+ style: sidebarInputStyle,
3991
+ value: logoMediaID !== null ? String(logoMediaID) : "",
3992
+ children: [
3993
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: "No image" }),
3994
+ mediaLibrary.map((libraryItem) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: String(libraryItem.id), children: mediaLabel(libraryItem) }, String(libraryItem.id)))
3995
+ ]
3996
+ }
3997
+ )
3998
+ ] }),
3999
+ mediaLibraryLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--ink-700)", fontSize: 11 }, children: "Loading media library..." }) : null,
4000
+ mediaLibraryError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#8d1d1d", fontSize: 11 }, children: mediaLibraryError }) : null,
4001
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
4002
+ "button",
4003
+ {
4004
+ disabled: !logoMedia && logoMediaID === null,
4005
+ onClick: () => setSelectedItemMediaFieldFromLibrary(itemIndex, "media", ""),
4006
+ style: {
4007
+ borderRadius: 999,
4008
+ cursor: logoMedia || logoMediaID !== null ? "pointer" : "not-allowed",
4009
+ fontSize: 12,
4010
+ padding: "7px 10px"
4011
+ },
4012
+ type: "button",
4013
+ children: "Remove Logo Image"
4014
+ }
4015
+ ),
4016
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
4017
+ "Image Fit",
4018
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
4019
+ "select",
4020
+ {
4021
+ onChange: (event) => updateArrayItemField(
4022
+ selectedIndex ?? 0,
4023
+ "items",
4024
+ itemIndex,
4025
+ "imageFit",
4026
+ event.target.value
4027
+ ),
4028
+ style: sidebarInputStyle,
4029
+ value: normalizeImageFit(item.imageFit),
4030
+ children: [
4031
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "cover", children: "Cover" }),
4032
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "contain", children: "Contain" })
4033
+ ]
4034
+ }
4035
+ )
4036
+ ] }),
4037
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
4038
+ "Image Corners",
4039
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
4040
+ "select",
4041
+ {
4042
+ onChange: (event) => updateArrayItemField(
4043
+ selectedIndex ?? 0,
4044
+ "items",
4045
+ itemIndex,
4046
+ "imageCornerStyle",
4047
+ event.target.value
4048
+ ),
4049
+ style: sidebarInputStyle,
4050
+ value: normalizeImageCornerStyle(item.imageCornerStyle),
4051
+ children: [
4052
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "rounded", children: "Rounded" }),
4053
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "square", children: "Square" })
4054
+ ]
4055
+ }
4056
+ )
4057
+ ] }),
4058
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
4059
+ "Image Position",
4060
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
4061
+ "select",
4062
+ {
4063
+ onChange: (event) => updateArrayItemField(
4064
+ selectedIndex ?? 0,
4065
+ "items",
4066
+ itemIndex,
4067
+ "imagePosition",
4068
+ event.target.value
4069
+ ),
4070
+ style: sidebarInputStyle,
4071
+ value: normalizeImagePosition(item.imagePosition),
4072
+ children: [
4073
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "center", children: "Center" }),
4074
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "top", children: "Top" }),
4075
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "bottom", children: "Bottom" }),
4076
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "left", children: "Left" }),
4077
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "right", children: "Right" })
4078
+ ]
4079
+ }
4080
+ )
4081
+ ] })
4082
+ ] });
4083
+ })(),
4084
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
4085
+ "Upload Logo Image",
4086
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
4087
+ "input",
4088
+ {
4089
+ accept: "image/*",
4090
+ disabled: uploadingTarget !== null,
4091
+ onChange: (event) => {
4092
+ const file = event.currentTarget.files?.[0];
4093
+ if (file) {
4094
+ void uploadMediaForSelected({ field: "media", itemIndex, kind: "logoWallItem" }, file);
4095
+ }
4096
+ event.currentTarget.value = "";
4097
+ },
4098
+ style: sidebarInputStyle,
4099
+ type: "file"
4100
+ }
4101
+ )
4102
+ ] }),
4103
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
4104
+ "button",
4105
+ {
4106
+ onClick: () => removeItemFromSelected("items", itemIndex),
4107
+ style: { borderRadius: 999, cursor: "pointer", fontSize: 12, padding: "7px 10px" },
4108
+ type: "button",
4109
+ children: "Remove Item"
4110
+ }
4111
+ )
4112
+ ] }, `logo-item-control-${itemIndex}`)) })
4113
+ ] }) : null,
4114
+ selectedType === "beforeAfter" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
4115
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
4116
+ "button",
4117
+ {
4118
+ onClick: () => appendItemToSelected("items", {
4119
+ description: "Describe the outcome.",
4120
+ imageCornerStyle: "rounded",
4121
+ imageFit: "cover",
4122
+ imagePosition: "center",
4123
+ label: "Project"
4124
+ }),
4125
+ style: { borderRadius: 999, cursor: "pointer", fontSize: 12, padding: "7px 10px" },
4126
+ type: "button",
4127
+ children: "Add Before/After Pair"
4128
+ }
4129
+ ),
4130
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "grid", gap: 8 }, children: selectedItems.map((item, itemIndex) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { border: "1px solid rgba(13, 74, 55, 0.16)", borderRadius: 10, display: "grid", gap: 6, padding: 8 }, children: [
4131
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
4132
+ "input",
4133
+ {
4134
+ onChange: (event) => updateArrayItemField(selectedIndex ?? 0, "items", itemIndex, "label", event.target.value),
4135
+ placeholder: "Project Label",
4136
+ style: sidebarInputStyle,
4137
+ type: "text",
4138
+ value: normalizeText(item.label)
4139
+ }
4140
+ ),
4141
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
4142
+ "textarea",
4143
+ {
4144
+ onChange: (event) => updateArrayItemField(selectedIndex ?? 0, "items", itemIndex, "description", event.target.value),
4145
+ placeholder: "Description",
4146
+ style: { ...sidebarInputStyle, minHeight: 70, resize: "vertical" },
4147
+ value: normalizeText(item.description)
4148
+ }
4149
+ ),
4150
+ (() => {
4151
+ const beforeMedia = resolveMediaLibraryItemFromValue(item.beforeMedia);
4152
+ const beforeMediaID = getRelationID(item.beforeMedia);
4153
+ const afterMedia = resolveMediaLibraryItemFromValue(item.afterMedia);
4154
+ const afterMediaID = getRelationID(item.afterMedia);
4155
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
4156
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--ink-700)", fontSize: 12 }, children: beforeMedia ? `Before image: ${mediaLabel(beforeMedia)}` : "No before image selected." }),
4157
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
4158
+ "Choose Before Image",
4159
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
4160
+ "select",
4161
+ {
4162
+ onChange: (event) => setSelectedItemMediaFieldFromLibrary(itemIndex, "beforeMedia", event.target.value),
4163
+ style: sidebarInputStyle,
4164
+ value: beforeMediaID !== null ? String(beforeMediaID) : "",
4165
+ children: [
4166
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: "No image" }),
4167
+ mediaLibrary.map((libraryItem) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: String(libraryItem.id), children: mediaLabel(libraryItem) }, String(libraryItem.id)))
4168
+ ]
4169
+ }
4170
+ )
4171
+ ] }),
4172
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
4173
+ "button",
4174
+ {
4175
+ disabled: !beforeMedia && beforeMediaID === null,
4176
+ onClick: () => setSelectedItemMediaFieldFromLibrary(itemIndex, "beforeMedia", ""),
4177
+ style: {
4178
+ borderRadius: 999,
4179
+ cursor: beforeMedia || beforeMediaID !== null ? "pointer" : "not-allowed",
4180
+ fontSize: 12,
4181
+ padding: "7px 10px"
4182
+ },
4183
+ type: "button",
4184
+ children: "Remove Before Image"
4185
+ }
4186
+ ),
4187
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--ink-700)", fontSize: 12 }, children: afterMedia ? `After image: ${mediaLabel(afterMedia)}` : "No after image selected." }),
4188
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
4189
+ "Choose After Image",
4190
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
4191
+ "select",
4192
+ {
4193
+ onChange: (event) => setSelectedItemMediaFieldFromLibrary(itemIndex, "afterMedia", event.target.value),
4194
+ style: sidebarInputStyle,
4195
+ value: afterMediaID !== null ? String(afterMediaID) : "",
4196
+ children: [
4197
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: "No image" }),
4198
+ mediaLibrary.map((libraryItem) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: String(libraryItem.id), children: mediaLabel(libraryItem) }, String(libraryItem.id)))
4199
+ ]
4200
+ }
4201
+ )
4202
+ ] }),
4203
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
4204
+ "button",
4205
+ {
4206
+ disabled: !afterMedia && afterMediaID === null,
4207
+ onClick: () => setSelectedItemMediaFieldFromLibrary(itemIndex, "afterMedia", ""),
4208
+ style: {
4209
+ borderRadius: 999,
4210
+ cursor: afterMedia || afterMediaID !== null ? "pointer" : "not-allowed",
4211
+ fontSize: 12,
4212
+ padding: "7px 10px"
4213
+ },
4214
+ type: "button",
4215
+ children: "Remove After Image"
4216
+ }
4217
+ ),
4218
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
4219
+ "Image Fit",
4220
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
4221
+ "select",
4222
+ {
4223
+ onChange: (event) => updateArrayItemField(
4224
+ selectedIndex ?? 0,
4225
+ "items",
4226
+ itemIndex,
4227
+ "imageFit",
4228
+ event.target.value
4229
+ ),
4230
+ style: sidebarInputStyle,
4231
+ value: normalizeImageFit(item.imageFit),
4232
+ children: [
4233
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "cover", children: "Cover" }),
4234
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "contain", children: "Contain" })
4235
+ ]
4236
+ }
4237
+ )
4238
+ ] }),
4239
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
4240
+ "Image Corners",
4241
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
4242
+ "select",
4243
+ {
4244
+ onChange: (event) => updateArrayItemField(
4245
+ selectedIndex ?? 0,
4246
+ "items",
4247
+ itemIndex,
4248
+ "imageCornerStyle",
4249
+ event.target.value
4250
+ ),
4251
+ style: sidebarInputStyle,
4252
+ value: normalizeImageCornerStyle(item.imageCornerStyle),
4253
+ children: [
4254
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "rounded", children: "Rounded" }),
4255
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "square", children: "Square" })
4256
+ ]
4257
+ }
4258
+ )
4259
+ ] }),
4260
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
4261
+ "Image Position",
4262
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
4263
+ "select",
4264
+ {
4265
+ onChange: (event) => updateArrayItemField(
4266
+ selectedIndex ?? 0,
4267
+ "items",
4268
+ itemIndex,
4269
+ "imagePosition",
4270
+ event.target.value
4271
+ ),
4272
+ style: sidebarInputStyle,
4273
+ value: normalizeImagePosition(item.imagePosition),
4274
+ children: [
4275
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "center", children: "Center" }),
4276
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "top", children: "Top" }),
4277
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "bottom", children: "Bottom" }),
4278
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "left", children: "Left" }),
4279
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "right", children: "Right" })
4280
+ ]
4281
+ }
4282
+ )
4283
+ ] })
4284
+ ] });
4285
+ })(),
4286
+ mediaLibraryLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--ink-700)", fontSize: 11 }, children: "Loading media library..." }) : null,
4287
+ mediaLibraryError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#8d1d1d", fontSize: 11 }, children: mediaLibraryError }) : null,
4288
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
4289
+ "Upload Before Image",
4290
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
4291
+ "input",
4292
+ {
4293
+ accept: "image/*",
4294
+ disabled: uploadingTarget !== null,
4295
+ onChange: (event) => {
4296
+ const file = event.currentTarget.files?.[0];
4297
+ if (file) {
4298
+ void uploadMediaForSelected({ field: "beforeMedia", itemIndex, kind: "beforeAfterItem" }, file);
4299
+ }
4300
+ event.currentTarget.value = "";
4301
+ },
4302
+ style: sidebarInputStyle,
4303
+ type: "file"
4304
+ }
4305
+ )
4306
+ ] }),
4307
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
4308
+ "Upload After Image",
4309
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
4310
+ "input",
4311
+ {
4312
+ accept: "image/*",
4313
+ disabled: uploadingTarget !== null,
4314
+ onChange: (event) => {
4315
+ const file = event.currentTarget.files?.[0];
4316
+ if (file) {
4317
+ void uploadMediaForSelected({ field: "afterMedia", itemIndex, kind: "beforeAfterItem" }, file);
4318
+ }
4319
+ event.currentTarget.value = "";
4320
+ },
4321
+ style: sidebarInputStyle,
4322
+ type: "file"
4323
+ }
4324
+ )
4325
+ ] }),
4326
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
4327
+ "button",
4328
+ {
4329
+ onClick: () => removeItemFromSelected("items", itemIndex),
4330
+ style: { borderRadius: 999, cursor: "pointer", fontSize: 12, padding: "7px 10px" },
4331
+ type: "button",
4332
+ children: "Remove Item"
4333
+ }
4334
+ )
4335
+ ] }, `before-after-item-control-${itemIndex}`)) })
4336
+ ] }) : null,
4337
+ selectedType === "cta" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
4338
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
4339
+ "Style",
4340
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
4341
+ "select",
4342
+ {
4343
+ onChange: (event) => updateSelectedField("style", event.target.value),
4344
+ style: sidebarInputStyle,
4345
+ value: normalizeText(selectedBlock.style, "light"),
4346
+ children: [
4347
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "light", children: "Light" }),
4348
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "dark", children: "Dark" })
4349
+ ]
4350
+ }
4351
+ )
4352
+ ] }),
4353
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
4354
+ "Background Color",
4355
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
4356
+ "input",
4357
+ {
4358
+ onChange: (event) => updateSelectedField("backgroundColor", event.target.value),
4359
+ style: { ...sidebarInputStyle, height: 36, padding: 4 },
4360
+ type: "color",
4361
+ value: parseColor(selectedBlock.backgroundColor, "#1f684f")
4362
+ }
4363
+ )
4364
+ ] })
4365
+ ] }) : null,
4366
+ selectedType === "media" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
4367
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
4368
+ "Image Size",
4369
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
4370
+ "select",
4371
+ {
4372
+ onChange: (event) => updateSelectedField("size", event.target.value),
4373
+ style: sidebarInputStyle,
4374
+ value: normalizeText(selectedBlock.size, "default"),
4375
+ children: [
4376
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "default", children: "Default" }),
4377
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "wide", children: "Wide" })
4378
+ ]
4379
+ }
4380
+ )
4381
+ ] }),
4382
+ (() => {
4383
+ const selectedMedia = resolveMediaLibraryItemFromValue(selectedBlock.image);
4384
+ const selectedMediaID = getRelationID(selectedBlock.image);
4385
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
4386
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--ink-700)", fontSize: 12 }, children: selectedMedia ? `Selected image: ${mediaLabel(selectedMedia)}` : "No image selected." }),
4387
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
4388
+ "Choose from Media Library",
4389
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
4390
+ "select",
4391
+ {
4392
+ onChange: (event) => setSelectedMediaFieldFromLibrary("image", event.target.value),
4393
+ style: sidebarInputStyle,
4394
+ value: selectedMediaID !== null ? String(selectedMediaID) : "",
4395
+ children: [
4396
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: "No image" }),
4397
+ mediaLibrary.map((libraryItem) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: String(libraryItem.id), children: mediaLabel(libraryItem) }, String(libraryItem.id)))
4398
+ ]
4399
+ }
4400
+ )
4401
+ ] }),
4402
+ mediaLibraryLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--ink-700)", fontSize: 11 }, children: "Loading media library..." }) : null,
4403
+ mediaLibraryError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#8d1d1d", fontSize: 11 }, children: mediaLibraryError }) : null,
4404
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
4405
+ "button",
4406
+ {
4407
+ disabled: !selectedMedia && selectedMediaID === null,
4408
+ onClick: () => setSelectedMediaFieldFromLibrary("image", ""),
4409
+ style: {
4410
+ borderRadius: 999,
4411
+ cursor: selectedMedia || selectedMediaID !== null ? "pointer" : "not-allowed",
4412
+ fontSize: 12,
4413
+ padding: "7px 10px"
4414
+ },
4415
+ type: "button",
4416
+ children: "Remove Section Image"
4417
+ }
4418
+ ),
4419
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
4420
+ "Image Fit",
4421
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
4422
+ "select",
4423
+ {
4424
+ onChange: (event) => updateSelectedField("imageFit", event.target.value),
4425
+ style: sidebarInputStyle,
4426
+ value: normalizeImageFit(selectedBlock.imageFit),
4427
+ children: [
4428
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "cover", children: "Cover" }),
4429
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "contain", children: "Contain" })
4430
+ ]
4431
+ }
4432
+ )
4433
+ ] }),
4434
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
4435
+ "Image Corners",
4436
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
4437
+ "select",
4438
+ {
4439
+ onChange: (event) => updateSelectedField("imageCornerStyle", event.target.value),
4440
+ style: sidebarInputStyle,
4441
+ value: normalizeImageCornerStyle(selectedBlock.imageCornerStyle),
4442
+ children: [
4443
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "rounded", children: "Rounded" }),
4444
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "square", children: "Square" })
4445
+ ]
4446
+ }
4447
+ )
4448
+ ] }),
4449
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
4450
+ "Image Position",
4451
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
4452
+ "select",
4453
+ {
4454
+ onChange: (event) => updateSelectedField("imagePosition", event.target.value),
4455
+ style: sidebarInputStyle,
4456
+ value: normalizeImagePosition(selectedBlock.imagePosition),
4457
+ children: [
4458
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "center", children: "Center" }),
4459
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "top", children: "Top" }),
4460
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "bottom", children: "Bottom" }),
4461
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "left", children: "Left" }),
4462
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "right", children: "Right" })
4463
+ ]
4464
+ }
4465
+ )
4466
+ ] })
4467
+ ] });
4468
+ })(),
4469
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
4470
+ "Upload Section Image",
4471
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
4472
+ "input",
4473
+ {
4474
+ accept: "image/*",
4475
+ disabled: uploadingTarget !== null,
4476
+ onChange: (event) => {
4477
+ const file = event.currentTarget.files?.[0];
4478
+ if (file) {
4479
+ void uploadMediaForSelected({ kind: "media" }, file);
4480
+ }
4481
+ event.currentTarget.value = "";
4482
+ },
4483
+ style: sidebarInputStyle,
4484
+ type: "file"
4485
+ }
4486
+ )
4487
+ ] })
4488
+ ] }) : null,
4489
+ selectedType === "richText" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
4490
+ "Content Width",
4491
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
4492
+ "select",
4493
+ {
4494
+ onChange: (event) => updateSelectedField("width", event.target.value),
3480
4495
  style: sidebarInputStyle,
3481
- type: "file"
4496
+ value: normalizeText(selectedBlock.width, "normal"),
4497
+ children: [
4498
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "normal", children: "Normal" }),
4499
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "narrow", children: "Narrow" })
4500
+ ]
3482
4501
  }
3483
4502
  )
3484
- ] }),
3485
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
4503
+ ] }) : null,
4504
+ selectedType === "formEmbed" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
4505
+ "Form Type",
4506
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
4507
+ "select",
4508
+ {
4509
+ onChange: (event) => updateSelectedField("formType", event.target.value),
4510
+ style: sidebarInputStyle,
4511
+ value: normalizeText(selectedBlock.formType, "quote"),
4512
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "quote", children: "Quote" })
4513
+ }
4514
+ )
4515
+ ] }) : null,
4516
+ selectedType === "faq" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3486
4517
  "button",
3487
4518
  {
3488
- onClick: () => removeItemFromSelected("items", itemIndex),
4519
+ onClick: () => appendItemToSelected("items", {
4520
+ answer: "Answer this question here.",
4521
+ question: "New frequently asked question?"
4522
+ }),
3489
4523
  style: { borderRadius: 999, cursor: "pointer", fontSize: 12, padding: "7px 10px" },
3490
4524
  type: "button",
3491
- children: "Remove Item"
3492
- }
3493
- )
3494
- ] }, `before-after-item-control-${itemIndex}`)) })
3495
- ] }) : null,
3496
- selectedType === "cta" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
3497
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3498
- "Style",
3499
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3500
- "select",
3501
- {
3502
- onChange: (event) => updateSelectedField("style", event.target.value),
3503
- style: sidebarInputStyle,
3504
- value: normalizeText(selectedBlock.style, "light"),
3505
- children: [
3506
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "light", children: "Light" }),
3507
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "dark", children: "Dark" })
3508
- ]
3509
- }
3510
- )
3511
- ] }),
3512
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3513
- "Background Color",
3514
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3515
- "input",
3516
- {
3517
- onChange: (event) => updateSelectedField("backgroundColor", event.target.value),
3518
- style: { ...sidebarInputStyle, height: 36, padding: 4 },
3519
- type: "color",
3520
- value: parseColor(selectedBlock.backgroundColor, "#1f684f")
3521
- }
3522
- )
3523
- ] })
3524
- ] }) : null,
3525
- selectedType === "media" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
3526
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3527
- "Image Size",
3528
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3529
- "select",
3530
- {
3531
- onChange: (event) => updateSelectedField("size", event.target.value),
3532
- style: sidebarInputStyle,
3533
- value: normalizeText(selectedBlock.size, "default"),
3534
- children: [
3535
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "default", children: "Default" }),
3536
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "wide", children: "Wide" })
3537
- ]
4525
+ children: "Add FAQ Item"
3538
4526
  }
3539
- )
3540
- ] }),
3541
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3542
- "Upload Section Image",
3543
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3544
- "input",
4527
+ ) : null,
4528
+ selectedType === "testimonials" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
4529
+ "button",
3545
4530
  {
3546
- accept: "image/*",
3547
- disabled: uploadingTarget !== null,
3548
- onChange: (event) => {
3549
- const file = event.currentTarget.files?.[0];
3550
- if (file) {
3551
- void uploadMediaForSelected({ kind: "media" }, file);
3552
- }
3553
- event.currentTarget.value = "";
3554
- },
3555
- style: sidebarInputStyle,
3556
- type: "file"
4531
+ onClick: () => appendItemToSelected("items", {
4532
+ location: "City, ST",
4533
+ name: "Customer Name",
4534
+ quote: "Add testimonial text."
4535
+ }),
4536
+ style: { borderRadius: 999, cursor: "pointer", fontSize: 12, padding: "7px 10px" },
4537
+ type: "button",
4538
+ children: "Add Testimonial"
3557
4539
  }
3558
- )
3559
- ] })
3560
- ] }) : null,
3561
- selectedType === "richText" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3562
- "Content Width",
3563
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
3564
- "select",
3565
- {
3566
- onChange: (event) => updateSelectedField("width", event.target.value),
3567
- style: sidebarInputStyle,
3568
- value: normalizeText(selectedBlock.width, "normal"),
3569
- children: [
3570
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "normal", children: "Normal" }),
3571
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "narrow", children: "Narrow" })
3572
- ]
3573
- }
3574
- )
3575
- ] }) : null,
3576
- selectedType === "formEmbed" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3577
- "Form Type",
3578
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3579
- "select",
3580
- {
3581
- onChange: (event) => updateSelectedField("formType", event.target.value),
3582
- style: sidebarInputStyle,
3583
- value: normalizeText(selectedBlock.formType, "quote"),
3584
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "quote", children: "Quote" })
3585
- }
3586
- )
3587
- ] }) : null,
3588
- selectedType === "faq" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3589
- "button",
3590
- {
3591
- onClick: () => appendItemToSelected("items", {
3592
- answer: "Answer this question here.",
3593
- question: "New frequently asked question?"
3594
- }),
3595
- style: { borderRadius: 999, cursor: "pointer", fontSize: 12, padding: "7px 10px" },
3596
- type: "button",
3597
- children: "Add FAQ Item"
3598
- }
3599
- ) : null,
3600
- selectedType === "testimonials" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3601
- "button",
3602
- {
3603
- onClick: () => appendItemToSelected("items", {
3604
- location: "City, ST",
3605
- name: "Customer Name",
3606
- quote: "Add testimonial text."
3607
- }),
3608
- style: { borderRadius: 999, cursor: "pointer", fontSize: 12, padding: "7px 10px" },
3609
- type: "button",
3610
- children: "Add Testimonial"
3611
- }
3612
- ) : null,
3613
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
3614
- "Upload Alt Text",
3615
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3616
- "input",
3617
- {
3618
- onChange: (event) => setUploadAltText(event.target.value),
3619
- placeholder: "Describe the image",
3620
- style: sidebarInputStyle,
3621
- type: "text",
3622
- value: uploadAltText
3623
- }
3624
- )
3625
- ] }),
3626
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--ink-700)", fontSize: 11 }, children: "Click section text directly on the page for copy edits. Use this panel for layout and style options." }),
3627
- uploadingTarget ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--ink-700)", fontSize: 11 }, children: "Uploading image..." }) : null,
3628
- uploadMessage ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#0f7d52", fontSize: 11, fontWeight: 700 }, children: uploadMessage }) : null,
3629
- uploadError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#8d1d1d", fontSize: 11, fontWeight: 700 }, children: uploadError }) : null
3630
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: { color: "var(--ink-700)", fontSize: 12, margin: 0 }, children: "Click a section on the page preview to edit its options here." }) }) : null
3631
- ] })
3632
- ] }) : null
4540
+ ) : null,
4541
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: sidebarLabelStyle, children: [
4542
+ "Upload Alt Text",
4543
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
4544
+ "input",
4545
+ {
4546
+ onChange: (event) => setUploadAltText(event.target.value),
4547
+ placeholder: "Describe the image",
4548
+ style: sidebarInputStyle,
4549
+ type: "text",
4550
+ value: uploadAltText
4551
+ }
4552
+ )
4553
+ ] }),
4554
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--ink-700)", fontSize: 11 }, children: "Click section text directly on the page for copy edits. Use this panel for layout and style options." }),
4555
+ uploadingTarget ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--ink-700)", fontSize: 11 }, children: "Uploading image..." }) : null,
4556
+ uploadMessage ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#0f7d52", fontSize: 11, fontWeight: 700 }, children: uploadMessage }) : null,
4557
+ uploadError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#8d1d1d", fontSize: 11, fontWeight: 700 }, children: uploadError }) : null
4558
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: { color: "var(--ink-700)", fontSize: 12, margin: 0 }, children: "Click a section on the page preview to edit its options here." }) })
4559
+ ] }) : null
4560
+ ] })
4561
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
4562
+ "div",
4563
+ {
4564
+ style: {
4565
+ alignContent: "start",
4566
+ background: "linear-gradient(180deg, rgba(18, 74, 55, 0.06), rgba(18, 74, 55, 0))",
4567
+ display: "grid",
4568
+ gap: 10,
4569
+ justifyItems: "center",
4570
+ maxHeight: "calc(100vh - 90px)",
4571
+ overflow: "hidden",
4572
+ padding: "10px 6px"
4573
+ },
4574
+ children: tabs
4575
+ }
4576
+ );
4577
+ })()
3633
4578
  ]
3634
4579
  }
3635
4580
  )