@ohhwells/bridge 0.1.123 → 0.1.124-next.344

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.
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
 
3
3
  // src/OhhwellsBridge.tsx
4
- import React12, { useCallback as useCallback10, useEffect as useEffect15, useLayoutEffect as useLayoutEffect5, useRef as useRef12, useState as useState16 } from "react";
4
+ import React12, { useCallback as useCallback11, useEffect as useEffect16, useLayoutEffect as useLayoutEffect5, useRef as useRef13, useState as useState17 } from "react";
5
5
  import { createRoot as createRoot2 } from "react-dom/client";
6
6
  import { flushSync as flushSync2 } from "react-dom";
7
7
 
@@ -222,10 +222,14 @@ function reapRemovedAiSections(state, store, removedIds, excludeIds = /* @__PURE
222
222
  var BRAND_NAME_KEY = "__ohw_brand_name";
223
223
  var BRAND_TITLE_KEY = "__ohw_site_title";
224
224
  var BRAND_FAVICON_LETTER_KEY = "__ohw_favicon_letter";
225
+ var SITE_DESCRIPTION_KEY = "__ohw_site_description";
226
+ var SITE_OG_IMAGE_KEY = "__ohw_og_image";
225
227
  var BRAND_CHROME_KEYS = /* @__PURE__ */ new Set([
226
228
  BRAND_NAME_KEY,
227
229
  BRAND_TITLE_KEY,
228
- BRAND_FAVICON_LETTER_KEY
230
+ BRAND_FAVICON_LETTER_KEY,
231
+ SITE_DESCRIPTION_KEY,
232
+ SITE_OG_IMAGE_KEY
229
233
  ]);
230
234
  function upsertMeta(selector, attr, token, value) {
231
235
  let el = document.head.querySelector(selector);
@@ -236,6 +240,9 @@ function upsertMeta(selector, attr, token, value) {
236
240
  }
237
241
  if (el.getAttribute("content") !== value) el.setAttribute("content", value);
238
242
  }
243
+ function removeMeta(selector) {
244
+ document.head.querySelector(selector)?.remove();
245
+ }
239
246
  function escapeXml(value) {
240
247
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
241
248
  }
@@ -251,6 +258,22 @@ function applyLetterFavicon(letter) {
251
258
  link.type = "image/svg+xml";
252
259
  if (link.href !== href) link.href = href;
253
260
  }
261
+ function applyDescription(description) {
262
+ if (!description) return;
263
+ upsertMeta('meta[name="description"]', "name", "description", description);
264
+ upsertMeta('meta[property="og:description"]', "property", "og:description", description);
265
+ upsertMeta('meta[name="twitter:description"]', "name", "twitter:description", description);
266
+ }
267
+ function applyOgImage(url) {
268
+ if (url) {
269
+ upsertMeta('meta[property="og:image"]', "property", "og:image", url);
270
+ upsertMeta('meta[name="twitter:image"]', "name", "twitter:image", url);
271
+ upsertMeta('meta[name="twitter:card"]', "name", "twitter:card", "summary_large_image");
272
+ return;
273
+ }
274
+ removeMeta('meta[property="og:image"]');
275
+ removeMeta('meta[name="twitter:image"]');
276
+ }
254
277
  function applyBrandChrome(content) {
255
278
  const name = content[BRAND_NAME_KEY];
256
279
  if (typeof name === "string" && name.length > 0) {
@@ -269,6 +292,13 @@ function applyBrandChrome(content) {
269
292
  if (typeof letter === "string" && letter.length > 0) {
270
293
  applyLetterFavicon(letter);
271
294
  }
295
+ const description = content[SITE_DESCRIPTION_KEY];
296
+ if (typeof description === "string" && description.length > 0) {
297
+ applyDescription(description);
298
+ }
299
+ if (Object.prototype.hasOwnProperty.call(content, SITE_OG_IMAGE_KEY)) {
300
+ applyOgImage(String(content[SITE_OG_IMAGE_KEY] ?? "").trim());
301
+ }
272
302
  }
273
303
 
274
304
  // src/lib/brand-kit.ts
@@ -1207,7 +1237,7 @@ function initSectionInstancesFromContent(content, currentPath) {
1207
1237
 
1208
1238
  // src/ui/ai-tree/AiTreeRenderer.tsx
1209
1239
  import React from "react";
1210
- import { ArrowLeft, ArrowRight, ChevronDown, icons as lucideIcons } from "lucide-react";
1240
+ import { ArrowLeft, ArrowRight, ChevronDown, Play, icons as lucideIcons } from "lucide-react";
1211
1241
 
1212
1242
  // src/lib/placeholder-imagery.ts
1213
1243
  var U = (id) => `https://images.unsplash.com/photo-${id}?auto=format&fit=crop&w=1600&q=80`;
@@ -1679,6 +1709,22 @@ function pricingCardEmphasis(featured, ctx, hasBg) {
1679
1709
  function textAttrs(ctx, path) {
1680
1710
  return ctx.keyFor ? { "data-ohw-key": ctx.keyFor(path), "data-ohw-editable": "text" } : {};
1681
1711
  }
1712
+ var AI_RESPONSIVE_CSS = [
1713
+ "@media (max-width: 960px) {",
1714
+ " [data-ai-responsive] [data-ai-grid] { grid-template-columns: repeat(2, 1fr) !important; }",
1715
+ ' [data-ai-responsive] [data-ai-grid="1"] { grid-template-columns: 1fr !important; }',
1716
+ "}",
1717
+ "@media (max-width: 640px) {",
1718
+ " [data-ai-responsive] [data-ai-grid] { grid-template-columns: 1fr !important; }",
1719
+ " [data-ai-responsive] [data-ai-columns] > * { grid-column: 1 / -1 !important; }",
1720
+ // Group containers flatten to a column on phones; span placements come along for free.
1721
+ " [data-ai-responsive] [data-ai-group] { display: flex !important; flex-direction: column !important; }",
1722
+ " [data-ai-responsive] [data-ai-group] > * { grid-column: auto !important; }",
1723
+ " [data-ai-responsive] [data-ai-section-inner] { padding-left: 20px !important; padding-right: 20px !important; }",
1724
+ " [data-ai-responsive] { overflow-x: hidden; }",
1725
+ " [data-ai-responsive] img { max-width: 100%; }",
1726
+ "}"
1727
+ ].join("\n");
1682
1728
  var TRANSPARENT_PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
1683
1729
  function MediaBox({
1684
1730
  refValue,
@@ -1696,9 +1742,9 @@ function MediaBox({
1696
1742
  const url = refValue ? ctx.resolveMedia(refValue) : null;
1697
1743
  const isIcon = /^(lucide|simple):/.test(refValue);
1698
1744
  const aspectRatio = aspect && /^\d+:\d+$/.test(aspect) ? aspect.replace(":", " / ") : void 0;
1699
- const editAttrs = ctx.keyFor && editPath && !isIcon ? {
1745
+ const editAttrs = ctx.keyFor && editPath ? {
1700
1746
  "data-ohw-key": ctx.keyFor(editPath),
1701
- ...genericImageEdit ? { "data-ohw-editable": "image" } : {}
1747
+ ...isIcon ? { "data-ohw-editable": "icon" } : genericImageEdit ? { "data-ohw-editable": "image" } : {}
1702
1748
  } : {};
1703
1749
  if (isIcon) {
1704
1750
  const Icon = refValue.startsWith("lucide:") ? lucideByName(refValue.slice(7)) : null;
@@ -1706,6 +1752,7 @@ function MediaBox({
1706
1752
  "span",
1707
1753
  {
1708
1754
  "data-ai-icon": refValue,
1755
+ ...editAttrs,
1709
1756
  style: {
1710
1757
  display: "inline-flex",
1711
1758
  width: 48,
@@ -1757,6 +1804,112 @@ function MediaBox({
1757
1804
  }
1758
1805
  );
1759
1806
  }
1807
+ function VideoEmbed({ slots, ctx, path }) {
1808
+ const [playing, setPlaying] = React.useState(false);
1809
+ const videoId = str(slots.videoId);
1810
+ const caption = str(slots.caption);
1811
+ return /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: AI_TREE_TOKENS.spacing3 }, children: [
1812
+ /* @__PURE__ */ jsx(
1813
+ "div",
1814
+ {
1815
+ "data-ohw-video-block": "",
1816
+ "data-ohw-video-path": path,
1817
+ style: {
1818
+ position: "relative",
1819
+ width: "100%",
1820
+ aspectRatio: "16 / 9",
1821
+ borderRadius: AI_TREE_TOKENS.radiusCard,
1822
+ overflow: "hidden",
1823
+ background: "#DBEAFE"
1824
+ },
1825
+ children: !videoId ? /* @__PURE__ */ jsx(
1826
+ "div",
1827
+ {
1828
+ style: {
1829
+ position: "absolute",
1830
+ inset: 0,
1831
+ display: "flex",
1832
+ alignItems: "center",
1833
+ justifyContent: "center",
1834
+ color: "#93C5FD",
1835
+ fontSize: 13
1836
+ },
1837
+ children: "video"
1838
+ }
1839
+ ) : playing ? /* @__PURE__ */ jsx(
1840
+ "iframe",
1841
+ {
1842
+ src: `https://www.youtube-nocookie.com/embed/${videoId}?autoplay=1&mute=1`,
1843
+ title: caption || "YouTube video",
1844
+ style: { position: "absolute", inset: 0, width: "100%", height: "100%", border: 0 },
1845
+ allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
1846
+ sandbox: "allow-scripts allow-same-origin allow-presentation allow-popups allow-popups-to-escape-sandbox",
1847
+ loading: "lazy"
1848
+ }
1849
+ ) : /* @__PURE__ */ jsxs(
1850
+ "button",
1851
+ {
1852
+ type: "button",
1853
+ onClick: () => setPlaying(true),
1854
+ "aria-label": "Play video",
1855
+ style: {
1856
+ position: "absolute",
1857
+ inset: 0,
1858
+ width: "100%",
1859
+ height: "100%",
1860
+ border: 0,
1861
+ padding: 0,
1862
+ margin: 0,
1863
+ cursor: "pointer",
1864
+ background: "none"
1865
+ },
1866
+ children: [
1867
+ /* @__PURE__ */ jsx(
1868
+ "img",
1869
+ {
1870
+ src: `https://i.ytimg.com/vi/${videoId}/hqdefault.jpg`,
1871
+ alt: "",
1872
+ style: { width: "100%", height: "100%", objectFit: "cover", display: "block" }
1873
+ }
1874
+ ),
1875
+ /* @__PURE__ */ jsx(
1876
+ "span",
1877
+ {
1878
+ style: {
1879
+ position: "absolute",
1880
+ top: "50%",
1881
+ left: "50%",
1882
+ transform: "translate(-50%, -50%)",
1883
+ width: 64,
1884
+ height: 64,
1885
+ borderRadius: "50%",
1886
+ background: "rgba(0,0,0,0.65)",
1887
+ display: "flex",
1888
+ alignItems: "center",
1889
+ justifyContent: "center"
1890
+ },
1891
+ children: /* @__PURE__ */ jsx(Play, { size: 28, color: "#fff", fill: "#fff" })
1892
+ }
1893
+ )
1894
+ ]
1895
+ }
1896
+ )
1897
+ }
1898
+ ),
1899
+ caption && /* @__PURE__ */ jsx(
1900
+ "div",
1901
+ {
1902
+ ...textAttrs(ctx, `${path}.caption`),
1903
+ style: {
1904
+ ...typeStyle(AI_TREE_TOKENS.type.bodyM, ctx.brand.fonts.body),
1905
+ color: ctx.brand.palette.dark,
1906
+ textAlign: "center"
1907
+ },
1908
+ children: caption
1909
+ }
1910
+ )
1911
+ ] });
1912
+ }
1760
1913
  function ButtonEl({
1761
1914
  slots,
1762
1915
  ctx,
@@ -2764,7 +2917,7 @@ function CollectionBlock({ node, ctx, path }) {
2764
2917
  return /* @__PURE__ */ jsx(
2765
2918
  "div",
2766
2919
  {
2767
- "data-ai-grid": "",
2920
+ "data-ai-grid": String(itemsPerRow),
2768
2921
  "data-ohw-pricing-collection": isPricing ? "" : void 0,
2769
2922
  style: {
2770
2923
  display: "grid",
@@ -2837,6 +2990,8 @@ function renderNode(node, ctx, path) {
2837
2990
  editPath: `${path}.source`
2838
2991
  }
2839
2992
  );
2993
+ case "video":
2994
+ return /* @__PURE__ */ jsx(VideoEmbed, { slots, ctx, path });
2840
2995
  case "media-list": {
2841
2996
  const stacked = slots.layout === "stack";
2842
2997
  return /* @__PURE__ */ jsx("div", { style: { display: "flex", gap: stacked ? 0 : AI_TREE_TOKENS.spacing3 }, children: (node.children ?? []).map((child, i) => /* @__PURE__ */ jsx(
@@ -3123,6 +3278,7 @@ function AiTreeRenderer({
3123
3278
  {
3124
3279
  "data-ai-section": tree.tag ?? "",
3125
3280
  ...bgAttrs,
3281
+ "data-ai-responsive": "",
3126
3282
  style: {
3127
3283
  position: "relative",
3128
3284
  padding: `${pad}px 0`,
@@ -3133,12 +3289,13 @@ function AiTreeRenderer({
3133
3289
  color: settings.sectionBackground === "accent" ? blockBrand.palette.dark : void 0
3134
3290
  },
3135
3291
  children: [
3136
- isOverlay && backgroundUrl && /* @__PURE__ */ jsx("div", { style: { position: "absolute", inset: 0, background: `rgba(255,255,255,${overlayAlpha})` } }),
3292
+ /* @__PURE__ */ jsx("style", { children: AI_RESPONSIVE_CSS }),
3137
3293
  /* @__PURE__ */ jsx("style", { children: AI_MOBILE_CSS }),
3294
+ isOverlay && backgroundUrl && /* @__PURE__ */ jsx("div", { style: { position: "absolute", inset: 0, background: `rgba(255,255,255,${overlayAlpha})` } }),
3138
3295
  /* @__PURE__ */ jsx(
3139
3296
  "div",
3140
3297
  {
3141
- "data-ai-container": "",
3298
+ "data-ai-section-inner": "",
3142
3299
  style: {
3143
3300
  position: "relative",
3144
3301
  maxWidth: AI_TREE_TOKENS.sectionMaxWidth,
@@ -3149,7 +3306,7 @@ function AiTreeRenderer({
3149
3306
  children: tree.rows.map((row, r2) => /* @__PURE__ */ jsx(
3150
3307
  "div",
3151
3308
  {
3152
- "data-ai-row": "",
3309
+ "data-ai-columns": "",
3153
3310
  style: {
3154
3311
  display: "grid",
3155
3312
  gridTemplateColumns: "repeat(12, 1fr)",
@@ -3553,9 +3710,10 @@ function applyAiSectionsToDom(state, options) {
3553
3710
  if (existing && existing.serialized === serialized && existing.container.isConnected) {
3554
3711
  continue;
3555
3712
  }
3556
- const isNewMount = !existing || !existing.container.isConnected;
3557
3713
  let container = existing?.container;
3714
+ let isNewMount = false;
3558
3715
  if (!container || !container.isConnected) {
3716
+ isNewMount = true;
3559
3717
  existing?.root.unmount();
3560
3718
  container?.remove();
3561
3719
  container = document.createElement("div");
@@ -3944,6 +4102,7 @@ function EmptyState({ inEditor, insertAfter }) {
3944
4102
  /* @__PURE__ */ jsx4(
3945
4103
  "button",
3946
4104
  {
4105
+ "data-ohw-bridge": true,
3947
4106
  onClick: handleAddSchedule,
3948
4107
  className: "h-9 px-2 py-1.5 flex items-center justify-center bg-white border border-[#E7E5E4] rounded-md font-body text-sm font-medium text-(--color-dark,#200C02) cursor-pointer",
3949
4108
  children: "Add Schedule"
@@ -4361,7 +4520,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
4361
4520
  const timer = setTimeout(() => {
4362
4521
  if (!done) {
4363
4522
  done = true;
4364
- setLoading(false);
4523
+ innerCleanup = loadWithId(null);
4365
4524
  }
4366
4525
  }, 2e3);
4367
4526
  const configHandler = (e) => {
@@ -9342,7 +9501,7 @@ function FieldTypePicker({ onPick }) {
9342
9501
 
9343
9502
  // src/ui/MediaOverlay.tsx
9344
9503
  import * as React8 from "react";
9345
- import { Film, ImageIcon, Pause, Play, Volume2, VolumeX } from "lucide-react";
9504
+ import { Film, ImageIcon, Pause, Play as Play2, Volume2, VolumeX } from "lucide-react";
9346
9505
 
9347
9506
  // src/ui/button.tsx
9348
9507
  import * as React7 from "react";
@@ -9449,6 +9608,7 @@ function MediaOverlay({
9449
9608
  (prev) => prev && prev.fullWidth === width && prev.height === height ? prev : { fullWidth: width, height }
9450
9609
  );
9451
9610
  }, [isVideo]);
9611
+ const replaceLabel = isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image";
9452
9612
  const replaceMode = buttonSize ? replaceButtonMode({ width: rect.width, height: rect.height }, buttonSize) : "none";
9453
9613
  const box = {
9454
9614
  position: "fixed",
@@ -9513,7 +9673,7 @@ function MediaOverlay({
9513
9673
  e.stopPropagation();
9514
9674
  onVideoSettingsChange?.(hover.key, { autoplay: !autoplay });
9515
9675
  },
9516
- children: autoplay ? /* @__PURE__ */ jsx15(Pause, { size: 14 }) : /* @__PURE__ */ jsx15(Play, { size: 14 })
9676
+ children: autoplay ? /* @__PURE__ */ jsx15(Pause, { size: 14 }) : /* @__PURE__ */ jsx15(Play2, { size: 14 })
9517
9677
  }
9518
9678
  ),
9519
9679
  /* @__PURE__ */ jsx15(
@@ -9547,11 +9707,10 @@ function MediaOverlay({
9547
9707
  className: "flex items-center justify-center cursor-pointer",
9548
9708
  style: {
9549
9709
  ...box,
9550
- // When text overlays this media, let clicks fall THROUGH to the text underneath. In the
9551
- // parent this needed a whole `ow:click-at` round-trip to re-hit-test inside the iframe;
9552
- // in-document, pointer-events does it natively. The button below opts back in, so
9553
- // Replace still works.
9554
- pointerEvents: hover.hasTextOverlap || cueOnly ? "none" : "auto",
9710
+ // Visual only. `pointer-events: auto` on this full-bleed rect covered the navbar
9711
+ // (hero bg includes the absolute TopNav) and swallowed CTA press-drag. Text overlay
9712
+ // and cueOnly also need clicks to fall through — Replace / video controls opt back in.
9713
+ pointerEvents: "none",
9555
9714
  // Selected: a firm component ring with no wash, so the image reads as chosen rather
9556
9715
  // than hovered. Hover keeps the existing tinted preview.
9557
9716
  boxShadow: selected ? "inset 0 0 0 2px var(--color-bridge-primary)" : "inset 0 0 0 1.5px var(--color-bridge-primary)",
@@ -9578,17 +9737,17 @@ function MediaOverlay({
9578
9737
  },
9579
9738
  children: [
9580
9739
  isVideo ? /* @__PURE__ */ jsx15(Film, { size: 14 }) : /* @__PURE__ */ jsx15(ImageIcon, { size: 14 }),
9581
- isVideo ? "Replace video" : "Replace image"
9740
+ replaceLabel
9582
9741
  ]
9583
9742
  }
9584
9743
  ),
9585
- replaceMode === "none" || cueOnly ? null : /* @__PURE__ */ jsxs7(
9744
+ showChrome && replaceMode !== "none" && /* @__PURE__ */ jsxs7(
9586
9745
  Button,
9587
9746
  {
9588
9747
  "data-ohw-media-overlay": "",
9589
9748
  variant: "outline",
9590
9749
  size: "sm",
9591
- "aria-label": isVideo ? "Replace video" : "Replace image",
9750
+ "aria-label": replaceLabel,
9592
9751
  className: "gap-1.5 cursor-pointer hover:bg-background",
9593
9752
  style: {
9594
9753
  ...OVERLAY_BUTTON_STYLE,
@@ -9611,7 +9770,7 @@ function MediaOverlay({
9611
9770
  },
9612
9771
  children: [
9613
9772
  isVideo ? /* @__PURE__ */ jsx15(Film, { size: 14 }) : /* @__PURE__ */ jsx15(ImageIcon, { size: 14 }),
9614
- replaceMode === "full" ? isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image" : null
9773
+ replaceMode === "full" ? replaceLabel : null
9615
9774
  ]
9616
9775
  }
9617
9776
  )
@@ -11267,7 +11426,497 @@ function AiPricingCardOverlay({
11267
11426
  window.addEventListener("blur", onBlur);
11268
11427
  return () => window.removeEventListener("blur", onBlur);
11269
11428
  }, []);
11270
- useEffect6(() => {
11429
+ useEffect6(() => {
11430
+ const onKeyDown = (e) => {
11431
+ if (e.key !== "Escape") return;
11432
+ if (!activeRef.current) return;
11433
+ setActive(null);
11434
+ setError(null);
11435
+ };
11436
+ document.addEventListener("keydown", onKeyDown);
11437
+ return () => document.removeEventListener("keydown", onKeyDown);
11438
+ }, []);
11439
+ const findEntry = useCallback4(
11440
+ (sectionId) => {
11441
+ const state = parseAiSectionsState(aiSectionsRef.current);
11442
+ return state.sections.find((s) => s.id === sectionId) ?? null;
11443
+ },
11444
+ [aiSectionsRef]
11445
+ );
11446
+ const runMutation = useCallback4(
11447
+ async (sectionId, mutate) => {
11448
+ const entry = findEntry(sectionId);
11449
+ if (!entry) return false;
11450
+ const nextTree = mutate(entry.tree);
11451
+ if (!nextTree) return false;
11452
+ setPending(true);
11453
+ setError(null);
11454
+ const { ok, reasons } = await requestValidateTree2(postToParent2, nextTree);
11455
+ setPending(false);
11456
+ if (!ok) {
11457
+ setError(reasons[0] ?? "That change is not allowed.");
11458
+ return false;
11459
+ }
11460
+ applyTreeLocalRef.current?.({
11461
+ id: sectionId,
11462
+ mode: "replace",
11463
+ targetSectionId: sectionId,
11464
+ tree: nextTree,
11465
+ label: entry.label,
11466
+ media: entry.media,
11467
+ ...entry.brand ? { brand: entry.brand } : {},
11468
+ // The user is already looking at the card they just edited — recentering the
11469
+ // viewport on every tier add/remove/toggle reads as the section jumping around.
11470
+ skipScrollIntoView: true
11471
+ });
11472
+ return true;
11473
+ },
11474
+ [findEntry, postToParent2, applyTreeLocalRef]
11475
+ );
11476
+ const activeEntry = active ? findEntry(active.sectionId) : null;
11477
+ const activeCardRect = useLiveCardRect(active);
11478
+ const hoverHandleRect = useLiveCardRect(!active && hover ? hover : null);
11479
+ return /* @__PURE__ */ jsxs11(Fragment7, { children: [
11480
+ hoverHandleRect && hover && /* @__PURE__ */ jsx19(
11481
+ "button",
11482
+ {
11483
+ type: "button",
11484
+ "data-ohw-toolbar": "",
11485
+ onClick: () => setActive(hover),
11486
+ "aria-label": "Configure pricing tier",
11487
+ style: {
11488
+ position: "fixed",
11489
+ top: hoverHandleRect.top + 8,
11490
+ left: hoverHandleRect.left + hoverHandleRect.width - 36,
11491
+ width: 28,
11492
+ height: 28,
11493
+ borderRadius: 8,
11494
+ border: `1.5px dashed ${PRIMARY4}`,
11495
+ background: "#ffffff",
11496
+ color: PRIMARY4,
11497
+ display: "flex",
11498
+ alignItems: "center",
11499
+ justifyContent: "center",
11500
+ cursor: "pointer",
11501
+ zIndex: 2147483643,
11502
+ fontSize: 14,
11503
+ fontWeight: 700
11504
+ },
11505
+ children: /* @__PURE__ */ jsx19(Star2, { size: 14, style: { pointerEvents: "none" } })
11506
+ }
11507
+ ),
11508
+ activeCardRect && active && activeEntry && /* @__PURE__ */ jsx19(
11509
+ ItemInteractionLayer,
11510
+ {
11511
+ rect: activeCardRect,
11512
+ state: "active-top",
11513
+ toolbar: /* @__PURE__ */ jsx19(
11514
+ PricingCardToolbar,
11515
+ {
11516
+ entry: activeEntry,
11517
+ index: active.index,
11518
+ pending,
11519
+ error,
11520
+ onAddTier: () => runMutation(active.sectionId, addPricingTier),
11521
+ onRemoveTier: () => {
11522
+ void runMutation(active.sectionId, (tree) => removePricingTier(tree, active.index)).then(
11523
+ (applied) => {
11524
+ if (applied) setActive(null);
11525
+ }
11526
+ );
11527
+ },
11528
+ onToggleFeatured: (enabled) => runMutation(
11529
+ active.sectionId,
11530
+ (tree) => setPricingCardFeatured(tree, active.index, { enabled })
11531
+ ),
11532
+ onSetTreatment: (treatment) => runMutation(
11533
+ active.sectionId,
11534
+ (tree) => setPricingCardFeatured(tree, active.index, { enabled: true, treatment })
11535
+ ),
11536
+ onAddButton: () => runMutation(active.sectionId, (tree) => addPricingCardButton(tree, active.index, "Learn more")),
11537
+ onRemoveButton: () => runMutation(active.sectionId, (tree) => removePricingCardButton(tree, active.index)),
11538
+ onAddFeature: () => runMutation(active.sectionId, (tree) => addPricingCardFeature(tree, active.index, "New feature")),
11539
+ onRemoveFeature: () => runMutation(active.sectionId, (tree) => removePricingCardFeature(tree, active.index))
11540
+ }
11541
+ )
11542
+ }
11543
+ )
11544
+ ] });
11545
+ }
11546
+
11547
+ // src/ui/ai-section/AiVideoOverlay.tsx
11548
+ import { useCallback as useCallback5, useEffect as useEffect7, useRef as useRef7, useState as useState9 } from "react";
11549
+ import { Star as Star3 } from "lucide-react";
11550
+
11551
+ // src/lib/ai-video-tree.ts
11552
+ function resolveVideoBlock(tree, path) {
11553
+ const segments = path.split(".");
11554
+ const rowSeg = segments[0];
11555
+ const blockSeg = segments[1];
11556
+ if (!rowSeg?.startsWith("r") || !blockSeg?.startsWith("b")) return null;
11557
+ let node = tree.rows[Number(rowSeg.slice(1))]?.blocks[Number(blockSeg.slice(1))];
11558
+ for (const seg of segments.slice(2)) {
11559
+ if (!node || !seg.startsWith("c")) return null;
11560
+ node = node.children?.[Number(seg.slice(1))];
11561
+ }
11562
+ return node && node.type === "video" ? node : null;
11563
+ }
11564
+ function withVideo(tree, path, mutate) {
11565
+ const next = JSON.parse(JSON.stringify(tree));
11566
+ const block = resolveVideoBlock(next, path);
11567
+ if (!block) return null;
11568
+ block.slots = block.slots ?? {};
11569
+ return mutate(block) ? next : null;
11570
+ }
11571
+ function videoIdAt(tree, path) {
11572
+ const block = resolveVideoBlock(tree, path);
11573
+ const id = block?.slots?.videoId;
11574
+ return typeof id === "string" ? id : "";
11575
+ }
11576
+ function setVideoId(tree, path, videoId) {
11577
+ return withVideo(tree, path, (block) => {
11578
+ block.slots = { ...block.slots, videoId };
11579
+ return true;
11580
+ });
11581
+ }
11582
+ function clearVideo(tree, path) {
11583
+ return withVideo(tree, path, (block) => {
11584
+ const slots = { ...block.slots };
11585
+ delete slots.videoId;
11586
+ block.slots = slots;
11587
+ return true;
11588
+ });
11589
+ }
11590
+
11591
+ // src/lib/youtube.ts
11592
+ var YOUTUBE_ID_PATTERN = /^[A-Za-z0-9_-]{11}$/;
11593
+ function extractYouTubeId(input) {
11594
+ const trimmed = input.trim();
11595
+ if (!trimmed) return null;
11596
+ if (YOUTUBE_ID_PATTERN.test(trimmed)) return trimmed;
11597
+ let url;
11598
+ try {
11599
+ url = new URL(trimmed);
11600
+ } catch {
11601
+ return null;
11602
+ }
11603
+ const host = url.hostname.replace(/^www\./, "");
11604
+ if (host !== "youtube.com" && host !== "m.youtube.com" && host !== "youtu.be" && host !== "youtube-nocookie.com") {
11605
+ return null;
11606
+ }
11607
+ let candidate = null;
11608
+ if (host === "youtu.be") {
11609
+ candidate = url.pathname.slice(1).split("/")[0] ?? null;
11610
+ } else if (url.pathname === "/watch") {
11611
+ candidate = url.searchParams.get("v");
11612
+ } else {
11613
+ const match = url.pathname.match(/^\/(?:embed|shorts)\/([^/]+)/);
11614
+ candidate = match ? match[1] : null;
11615
+ }
11616
+ return candidate && YOUTUBE_ID_PATTERN.test(candidate) ? candidate : null;
11617
+ }
11618
+
11619
+ // src/ui/ai-section/AiVideoOverlay.tsx
11620
+ import { Fragment as Fragment8, jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
11621
+ var PRIMARY5 = "#0885FE";
11622
+ var OHW_BLUE3 = `var(--ohw-primary, ${PRIMARY5})`;
11623
+ var OHW_BLUE_DARK3 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY5}) 60%, #000000)`;
11624
+ function findVideoBlockElement(sectionId, path) {
11625
+ const sectionEl = findByInstanceId(sectionId);
11626
+ if (!sectionEl) return null;
11627
+ const items = sectionEl.querySelectorAll("[data-ohw-video-block]");
11628
+ for (const el of Array.from(items)) {
11629
+ if (el.dataset.ohwVideoPath === path) return el;
11630
+ }
11631
+ return null;
11632
+ }
11633
+ function readRect4(ref) {
11634
+ const el = ref && findVideoBlockElement(ref.sectionId, ref.path);
11635
+ if (!el) return null;
11636
+ const r2 = el.getBoundingClientRect();
11637
+ if (r2.width <= 0 || r2.height <= 0) return null;
11638
+ return { top: r2.top, left: r2.left, width: r2.width, height: r2.height };
11639
+ }
11640
+ function useLiveBlockRect(ref) {
11641
+ const [rect, setRect] = useState9(null);
11642
+ useEffect7(() => {
11643
+ if (!ref) {
11644
+ setRect(null);
11645
+ return;
11646
+ }
11647
+ const update = () => {
11648
+ const next = readRect4(ref);
11649
+ setRect(
11650
+ (prev) => prev && next && prev.top === next.top && prev.left === next.left && prev.width === next.width && prev.height === next.height ? prev : next
11651
+ );
11652
+ };
11653
+ update();
11654
+ const opts = { capture: true, passive: true };
11655
+ window.addEventListener("scroll", update, opts);
11656
+ window.addEventListener("resize", update);
11657
+ const interval = setInterval(update, 500);
11658
+ return () => {
11659
+ window.removeEventListener("scroll", update, opts);
11660
+ window.removeEventListener("resize", update);
11661
+ clearInterval(interval);
11662
+ };
11663
+ }, [ref?.sectionId, ref?.path]);
11664
+ return rect;
11665
+ }
11666
+ function requestValidateTree3(postToParent2, tree) {
11667
+ return new Promise((resolve) => {
11668
+ const id = `ai-validate-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
11669
+ const timeout = window.setTimeout(() => {
11670
+ window.removeEventListener("message", onMessage);
11671
+ resolve({ ok: false, reasons: ["Validation request timed out."] });
11672
+ }, 8e3);
11673
+ function onMessage(e) {
11674
+ if (e.data?.type !== "ow:ai-validate-tree-result" || e.data.id !== id) return;
11675
+ window.clearTimeout(timeout);
11676
+ window.removeEventListener("message", onMessage);
11677
+ resolve({ ok: e.data.ok === true, reasons: Array.isArray(e.data.reasons) ? e.data.reasons : [] });
11678
+ }
11679
+ window.addEventListener("message", onMessage);
11680
+ postToParent2({ type: "ow:ai-validate-tree-request", id, tree });
11681
+ });
11682
+ }
11683
+ function Pill3({
11684
+ label,
11685
+ onClick,
11686
+ disabled
11687
+ }) {
11688
+ return /* @__PURE__ */ jsx20(
11689
+ "button",
11690
+ {
11691
+ type: "button",
11692
+ onClick,
11693
+ disabled,
11694
+ style: {
11695
+ height: 28,
11696
+ padding: "0 10px",
11697
+ display: "inline-flex",
11698
+ alignItems: "center",
11699
+ gap: 4,
11700
+ borderRadius: 999,
11701
+ border: "none",
11702
+ cursor: disabled ? "default" : "pointer",
11703
+ background: "#ffffff",
11704
+ color: OHW_BLUE_DARK3,
11705
+ opacity: disabled ? 0.4 : 1,
11706
+ fontSize: 12,
11707
+ lineHeight: "16px",
11708
+ fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
11709
+ whiteSpace: "nowrap",
11710
+ flex: "0 0 auto"
11711
+ },
11712
+ children: label
11713
+ }
11714
+ );
11715
+ }
11716
+ function watchUrl(id) {
11717
+ return `https://www.youtube.com/watch?v=${id}`;
11718
+ }
11719
+ function VideoUrlInput({ value, onCommit }) {
11720
+ const [draft, setDraft] = useState9(value ? watchUrl(value) : "");
11721
+ const [invalid, setInvalid] = useState9(false);
11722
+ useEffect7(() => {
11723
+ setDraft(value ? watchUrl(value) : "");
11724
+ setInvalid(false);
11725
+ }, [value]);
11726
+ const commit = () => {
11727
+ const next = draft.trim();
11728
+ if (!next) {
11729
+ setInvalid(false);
11730
+ if (value) onCommit(null);
11731
+ return;
11732
+ }
11733
+ const id = extractYouTubeId(next);
11734
+ if (!id) return setInvalid(true);
11735
+ setInvalid(false);
11736
+ setDraft(watchUrl(id));
11737
+ if (id !== value) onCommit(id);
11738
+ };
11739
+ const handleChange = (next) => {
11740
+ setDraft(next);
11741
+ const id = extractYouTubeId(next.trim());
11742
+ if (id && id !== value) {
11743
+ setInvalid(false);
11744
+ onCommit(id);
11745
+ }
11746
+ };
11747
+ return /* @__PURE__ */ jsxs12("div", { style: { display: "flex", flexDirection: "column", gap: 4, width: "100%", maxWidth: 280 }, children: [
11748
+ /* @__PURE__ */ jsxs12(
11749
+ "div",
11750
+ {
11751
+ style: {
11752
+ display: "flex",
11753
+ alignItems: "center",
11754
+ gap: 6,
11755
+ height: 28,
11756
+ padding: "0 12px",
11757
+ borderRadius: 999,
11758
+ background: "#ffffff",
11759
+ width: "100%",
11760
+ boxSizing: "border-box",
11761
+ boxShadow: invalid ? "inset 0 0 0 1.5px #EF4444" : "none"
11762
+ },
11763
+ children: [
11764
+ /* @__PURE__ */ jsx20(
11765
+ "span",
11766
+ {
11767
+ style: {
11768
+ flex: "0 0 auto",
11769
+ color: OHW_BLUE_DARK3,
11770
+ fontSize: 10,
11771
+ lineHeight: "16px",
11772
+ fontWeight: 700,
11773
+ textTransform: "uppercase",
11774
+ letterSpacing: 0.4
11775
+ },
11776
+ children: "Video"
11777
+ }
11778
+ ),
11779
+ /* @__PURE__ */ jsx20(
11780
+ "input",
11781
+ {
11782
+ type: "text",
11783
+ inputMode: "url",
11784
+ value: draft,
11785
+ onChange: (e) => handleChange(e.target.value),
11786
+ onBlur: commit,
11787
+ onKeyDown: (e) => {
11788
+ if (e.key === "Enter") e.currentTarget.blur();
11789
+ if (e.key === "Escape") {
11790
+ setDraft(value ? watchUrl(value) : "");
11791
+ setInvalid(false);
11792
+ e.currentTarget.blur();
11793
+ }
11794
+ },
11795
+ placeholder: "Paste a YouTube URL",
11796
+ "aria-label": "YouTube video URL",
11797
+ "aria-invalid": invalid,
11798
+ style: {
11799
+ flex: 1,
11800
+ minWidth: 0,
11801
+ border: "none",
11802
+ outline: "none",
11803
+ background: "transparent",
11804
+ padding: 0,
11805
+ margin: 0,
11806
+ fontSize: 12,
11807
+ lineHeight: "16px",
11808
+ fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
11809
+ color: "#1f2937"
11810
+ }
11811
+ }
11812
+ )
11813
+ ]
11814
+ }
11815
+ ),
11816
+ invalid && /* @__PURE__ */ jsx20("div", { style: { color: "#FCA5A5", fontSize: 11, textAlign: "center" }, children: "That doesn't look like a YouTube link \u2014 try pasting the video URL again." })
11817
+ ] });
11818
+ }
11819
+ function VideoToolbar({
11820
+ videoId,
11821
+ pending,
11822
+ error,
11823
+ onSetVideoId,
11824
+ onRemove
11825
+ }) {
11826
+ return /* @__PURE__ */ jsxs12(
11827
+ "div",
11828
+ {
11829
+ "data-ohw-bridge": "",
11830
+ "data-ohw-toolbar": "",
11831
+ onMouseDown: (e) => e.stopPropagation(),
11832
+ style: {
11833
+ display: "flex",
11834
+ flexDirection: "column",
11835
+ gap: 6,
11836
+ alignItems: "center",
11837
+ width: 280,
11838
+ background: OHW_BLUE3,
11839
+ padding: 8,
11840
+ borderRadius: 12,
11841
+ boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
11842
+ pointerEvents: pending ? "none" : "auto",
11843
+ opacity: pending ? 0.6 : 1
11844
+ },
11845
+ children: [
11846
+ /* @__PURE__ */ jsx20(VideoUrlInput, { value: videoId, onCommit: onSetVideoId }),
11847
+ /* @__PURE__ */ jsx20(Pill3, { label: "Remove video", onClick: onRemove, disabled: !videoId }),
11848
+ error && /* @__PURE__ */ jsx20("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
11849
+ ]
11850
+ }
11851
+ );
11852
+ }
11853
+ function AiVideoOverlay({
11854
+ postToParent: postToParent2,
11855
+ aiSectionsRef,
11856
+ applyTreeLocalRef,
11857
+ clearInteractionChromeRef
11858
+ }) {
11859
+ const [hover, setHover] = useState9(null);
11860
+ const [active, setActive] = useState9(null);
11861
+ const [pending, setPending] = useState9(false);
11862
+ const [error, setError] = useState9(null);
11863
+ const activeRef = useRef7(null);
11864
+ activeRef.current = active;
11865
+ useEffect7(() => {
11866
+ const onMove = (e) => {
11867
+ const t = e.target;
11868
+ if (!(t instanceof HTMLElement)) return;
11869
+ if (t.closest("[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-link-modal-root], [data-ohw-section-picker], [data-ohw-ai-review]")) {
11870
+ return;
11871
+ }
11872
+ const blockEl = t.closest("[data-ohw-video-block]");
11873
+ if (!blockEl) {
11874
+ setHover(null);
11875
+ return;
11876
+ }
11877
+ const sectionEl = blockEl.closest("[data-ohw-section]");
11878
+ const unit = sectionEl ? movableUnit(sectionEl) : null;
11879
+ const sectionId = unit ? instanceIdOf(unit) || null : null;
11880
+ const path = blockEl.dataset.ohwVideoPath;
11881
+ if (!sectionId || !path) {
11882
+ setHover(null);
11883
+ return;
11884
+ }
11885
+ setHover({ sectionId, path });
11886
+ };
11887
+ const onLeave = () => setHover(null);
11888
+ document.addEventListener("mousemove", onMove, { passive: true });
11889
+ document.documentElement.addEventListener("mouseleave", onLeave);
11890
+ return () => {
11891
+ document.removeEventListener("mousemove", onMove);
11892
+ document.documentElement.removeEventListener("mouseleave", onLeave);
11893
+ };
11894
+ }, []);
11895
+ useEffect7(() => {
11896
+ const onClick = (e) => {
11897
+ const current = activeRef.current;
11898
+ if (!current) return;
11899
+ const t = e.target;
11900
+ if (!(t instanceof HTMLElement)) return;
11901
+ if (t.closest("[data-ohw-item-interaction]")) return;
11902
+ const blockEl = findVideoBlockElement(current.sectionId, current.path);
11903
+ if (blockEl && blockEl.contains(t)) return;
11904
+ setActive(null);
11905
+ setError(null);
11906
+ };
11907
+ document.addEventListener("click", onClick, true);
11908
+ return () => document.removeEventListener("click", onClick, true);
11909
+ }, []);
11910
+ useEffect7(() => {
11911
+ const onBlur = () => {
11912
+ if (!activeRef.current) return;
11913
+ setActive(null);
11914
+ setError(null);
11915
+ };
11916
+ window.addEventListener("blur", onBlur);
11917
+ return () => window.removeEventListener("blur", onBlur);
11918
+ }, []);
11919
+ useEffect7(() => {
11271
11920
  const onKeyDown = (e) => {
11272
11921
  if (e.key !== "Escape") return;
11273
11922
  if (!activeRef.current) return;
@@ -11277,14 +11926,14 @@ function AiPricingCardOverlay({
11277
11926
  document.addEventListener("keydown", onKeyDown);
11278
11927
  return () => document.removeEventListener("keydown", onKeyDown);
11279
11928
  }, []);
11280
- const findEntry = useCallback4(
11929
+ const findEntry = useCallback5(
11281
11930
  (sectionId) => {
11282
11931
  const state = parseAiSectionsState(aiSectionsRef.current);
11283
11932
  return state.sections.find((s) => s.id === sectionId) ?? null;
11284
11933
  },
11285
11934
  [aiSectionsRef]
11286
11935
  );
11287
- const runMutation = useCallback4(
11936
+ const runMutation = useCallback5(
11288
11937
  async (sectionId, mutate) => {
11289
11938
  const entry = findEntry(sectionId);
11290
11939
  if (!entry) return false;
@@ -11292,7 +11941,7 @@ function AiPricingCardOverlay({
11292
11941
  if (!nextTree) return false;
11293
11942
  setPending(true);
11294
11943
  setError(null);
11295
- const { ok, reasons } = await requestValidateTree2(postToParent2, nextTree);
11944
+ const { ok, reasons } = await requestValidateTree3(postToParent2, nextTree);
11296
11945
  setPending(false);
11297
11946
  if (!ok) {
11298
11947
  setError(reasons[0] ?? "That change is not allowed.");
@@ -11305,26 +11954,28 @@ function AiPricingCardOverlay({
11305
11954
  tree: nextTree,
11306
11955
  label: entry.label,
11307
11956
  media: entry.media,
11308
- ...entry.brand ? { brand: entry.brand } : {},
11309
- // The user is already looking at the card they just edited — recentering the
11310
- // viewport on every tier add/remove/toggle reads as the section jumping around.
11311
- skipScrollIntoView: true
11957
+ ...entry.brand ? { brand: entry.brand } : {}
11312
11958
  });
11313
11959
  return true;
11314
11960
  },
11315
11961
  [findEntry, postToParent2, applyTreeLocalRef]
11316
11962
  );
11317
11963
  const activeEntry = active ? findEntry(active.sectionId) : null;
11318
- const activeCardRect = useLiveCardRect(active);
11319
- const hoverHandleRect = useLiveCardRect(!active && hover ? hover : null);
11320
- return /* @__PURE__ */ jsxs11(Fragment7, { children: [
11321
- hoverHandleRect && hover && /* @__PURE__ */ jsx19(
11964
+ const hoverHandleRect = useLiveBlockRect(!active && hover ? hover : null);
11965
+ const activeBlockRect = useLiveBlockRect(active);
11966
+ const TOOLBAR_APPROX_H = 90;
11967
+ const toolbarState = activeBlockRect && activeBlockRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
11968
+ return /* @__PURE__ */ jsxs12(Fragment8, { children: [
11969
+ hoverHandleRect && hover && /* @__PURE__ */ jsx20(
11322
11970
  "button",
11323
11971
  {
11324
11972
  type: "button",
11325
11973
  "data-ohw-toolbar": "",
11326
- onClick: () => setActive(hover),
11327
- "aria-label": "Configure pricing tier",
11974
+ onClick: () => {
11975
+ clearInteractionChromeRef.current();
11976
+ setActive(hover);
11977
+ },
11978
+ "aria-label": "Configure video",
11328
11979
  style: {
11329
11980
  position: "fixed",
11330
11981
  top: hoverHandleRect.top + 8,
@@ -11332,9 +11983,9 @@ function AiPricingCardOverlay({
11332
11983
  width: 28,
11333
11984
  height: 28,
11334
11985
  borderRadius: 8,
11335
- border: `1.5px dashed ${PRIMARY4}`,
11986
+ border: `1.5px dashed ${PRIMARY5}`,
11336
11987
  background: "#ffffff",
11337
- color: PRIMARY4,
11988
+ color: PRIMARY5,
11338
11989
  display: "flex",
11339
11990
  alignItems: "center",
11340
11991
  justifyContent: "center",
@@ -11343,41 +11994,29 @@ function AiPricingCardOverlay({
11343
11994
  fontSize: 14,
11344
11995
  fontWeight: 700
11345
11996
  },
11346
- children: /* @__PURE__ */ jsx19(Star2, { size: 14, style: { pointerEvents: "none" } })
11997
+ children: /* @__PURE__ */ jsx20(Star3, { size: 14, style: { pointerEvents: "none" } })
11347
11998
  }
11348
11999
  ),
11349
- activeCardRect && active && activeEntry && /* @__PURE__ */ jsx19(
12000
+ activeBlockRect && active && activeEntry && /* @__PURE__ */ jsx20(
11350
12001
  ItemInteractionLayer,
11351
12002
  {
11352
- rect: activeCardRect,
11353
- state: "active-top",
11354
- toolbar: /* @__PURE__ */ jsx19(
11355
- PricingCardToolbar,
12003
+ rect: activeBlockRect,
12004
+ state: toolbarState,
12005
+ toolbar: /* @__PURE__ */ jsx20(
12006
+ VideoToolbar,
11356
12007
  {
11357
- entry: activeEntry,
11358
- index: active.index,
12008
+ videoId: videoIdAt(activeEntry.tree, active.path),
11359
12009
  pending,
11360
12010
  error,
11361
- onAddTier: () => runMutation(active.sectionId, addPricingTier),
11362
- onRemoveTier: () => {
11363
- void runMutation(active.sectionId, (tree) => removePricingTier(tree, active.index)).then(
11364
- (applied) => {
11365
- if (applied) setActive(null);
11366
- }
12011
+ onSetVideoId: (videoId) => {
12012
+ void runMutation(
12013
+ active.sectionId,
12014
+ (tree) => videoId ? setVideoId(tree, active.path, videoId) : clearVideo(tree, active.path)
11367
12015
  );
11368
12016
  },
11369
- onToggleFeatured: (enabled) => runMutation(
11370
- active.sectionId,
11371
- (tree) => setPricingCardFeatured(tree, active.index, { enabled })
11372
- ),
11373
- onSetTreatment: (treatment) => runMutation(
11374
- active.sectionId,
11375
- (tree) => setPricingCardFeatured(tree, active.index, { enabled: true, treatment })
11376
- ),
11377
- onAddButton: () => runMutation(active.sectionId, (tree) => addPricingCardButton(tree, active.index, "Learn more")),
11378
- onRemoveButton: () => runMutation(active.sectionId, (tree) => removePricingCardButton(tree, active.index)),
11379
- onAddFeature: () => runMutation(active.sectionId, (tree) => addPricingCardFeature(tree, active.index, "New feature")),
11380
- onRemoveFeature: () => runMutation(active.sectionId, (tree) => removePricingCardFeature(tree, active.index))
12017
+ onRemove: () => {
12018
+ void runMutation(active.sectionId, (tree) => clearVideo(tree, active.path));
12019
+ }
11381
12020
  }
11382
12021
  )
11383
12022
  }
@@ -11696,28 +12335,28 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
11696
12335
  }
11697
12336
 
11698
12337
  // src/ui/link-modal/LinkPopover.tsx
11699
- import { useEffect as useEffect10 } from "react";
12338
+ import { useEffect as useEffect11 } from "react";
11700
12339
 
11701
12340
  // src/ui/dialog.tsx
11702
12341
  import * as React9 from "react";
11703
12342
  import { Dialog as DialogPrimitive } from "radix-ui";
11704
12343
  import { X as X2 } from "lucide-react";
11705
- import { jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
12344
+ import { jsx as jsx21, jsxs as jsxs13 } from "react/jsx-runtime";
11706
12345
  function Dialog2({
11707
12346
  ...props
11708
12347
  }) {
11709
- return /* @__PURE__ */ jsx20(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
12348
+ return /* @__PURE__ */ jsx21(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
11710
12349
  }
11711
12350
  function DialogPortal({
11712
12351
  ...props
11713
12352
  }) {
11714
- return /* @__PURE__ */ jsx20(DialogPrimitive.Portal, { ...props });
12353
+ return /* @__PURE__ */ jsx21(DialogPrimitive.Portal, { ...props });
11715
12354
  }
11716
12355
  function DialogOverlay({
11717
12356
  className,
11718
12357
  ...props
11719
12358
  }) {
11720
- return /* @__PURE__ */ jsx20(
12359
+ return /* @__PURE__ */ jsx21(
11721
12360
  DialogPrimitive.Overlay,
11722
12361
  {
11723
12362
  "data-slot": "dialog-overlay",
@@ -11730,9 +12369,9 @@ function DialogOverlay({
11730
12369
  var DialogContent = React9.forwardRef(
11731
12370
  ({ className, children, showCloseButton = true, container, ...props }, ref) => {
11732
12371
  const positionMode = container ? "absolute" : "fixed";
11733
- return /* @__PURE__ */ jsxs12(DialogPortal, { container: container ?? void 0, children: [
11734
- /* @__PURE__ */ jsx20(DialogOverlay, { className: cn(positionMode, "inset-0") }),
11735
- /* @__PURE__ */ jsxs12(
12372
+ return /* @__PURE__ */ jsxs13(DialogPortal, { container: container ?? void 0, children: [
12373
+ /* @__PURE__ */ jsx21(DialogOverlay, { className: cn(positionMode, "inset-0") }),
12374
+ /* @__PURE__ */ jsxs13(
11736
12375
  DialogPrimitive.Content,
11737
12376
  {
11738
12377
  ref,
@@ -11748,13 +12387,13 @@ var DialogContent = React9.forwardRef(
11748
12387
  ...props,
11749
12388
  children: [
11750
12389
  children,
11751
- showCloseButton ? /* @__PURE__ */ jsx20(
12390
+ showCloseButton ? /* @__PURE__ */ jsx21(
11752
12391
  DialogPrimitive.Close,
11753
12392
  {
11754
12393
  type: "button",
11755
12394
  className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
11756
12395
  "aria-label": "Close",
11757
- children: /* @__PURE__ */ jsx20(X2, { size: 16, "aria-hidden": true })
12396
+ children: /* @__PURE__ */ jsx21(X2, { size: 16, "aria-hidden": true })
11758
12397
  }
11759
12398
  ) : null
11760
12399
  ]
@@ -11768,13 +12407,13 @@ function DialogHeader({
11768
12407
  className,
11769
12408
  ...props
11770
12409
  }) {
11771
- return /* @__PURE__ */ jsx20("div", { className: cn("flex flex-col gap-1.5", className), ...props });
12410
+ return /* @__PURE__ */ jsx21("div", { className: cn("flex flex-col gap-1.5", className), ...props });
11772
12411
  }
11773
12412
  function DialogFooter({
11774
12413
  className,
11775
12414
  ...props
11776
12415
  }) {
11777
- return /* @__PURE__ */ jsx20(
12416
+ return /* @__PURE__ */ jsx21(
11778
12417
  "div",
11779
12418
  {
11780
12419
  className: cn("flex items-center justify-end gap-2", className),
@@ -11782,7 +12421,7 @@ function DialogFooter({
11782
12421
  }
11783
12422
  );
11784
12423
  }
11785
- var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx20(
12424
+ var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx21(
11786
12425
  DialogPrimitive.Title,
11787
12426
  {
11788
12427
  ref,
@@ -11794,7 +12433,7 @@ var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE
11794
12433
  }
11795
12434
  ));
11796
12435
  DialogTitle.displayName = DialogPrimitive.Title.displayName;
11797
- var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx20(
12436
+ var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx21(
11798
12437
  DialogPrimitive.Description,
11799
12438
  {
11800
12439
  ref,
@@ -11810,19 +12449,19 @@ import { Info, X as X4 } from "lucide-react";
11810
12449
 
11811
12450
  // src/ui/link-modal/DestinationBreadcrumb.tsx
11812
12451
  import { ArrowRight as ArrowRight2, File, GalleryVertical } from "lucide-react";
11813
- import { jsx as jsx21, jsxs as jsxs13 } from "react/jsx-runtime";
12452
+ import { jsx as jsx22, jsxs as jsxs14 } from "react/jsx-runtime";
11814
12453
  function DestinationBreadcrumb({
11815
12454
  pageTitle,
11816
12455
  sectionLabel
11817
12456
  }) {
11818
- return /* @__PURE__ */ jsxs13("div", { className: "flex w-full flex-col gap-2", children: [
11819
- /* @__PURE__ */ jsx21("p", { className: "text-sm font-medium! text-foreground m-0", children: "Destination" }),
11820
- /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-3", children: [
11821
- /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2", children: [
11822
- /* @__PURE__ */ jsx21(File, { size: 16, className: "shrink-0 text-foreground", "aria-hidden": true }),
11823
- /* @__PURE__ */ jsx21("span", { className: "text-sm font-medium leading-none text-foreground!", children: pageTitle })
12457
+ return /* @__PURE__ */ jsxs14("div", { className: "flex w-full flex-col gap-2", children: [
12458
+ /* @__PURE__ */ jsx22("p", { className: "text-sm font-medium! text-foreground m-0", children: "Destination" }),
12459
+ /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-3", children: [
12460
+ /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
12461
+ /* @__PURE__ */ jsx22(File, { size: 16, className: "shrink-0 text-foreground", "aria-hidden": true }),
12462
+ /* @__PURE__ */ jsx22("span", { className: "text-sm font-medium leading-none text-foreground!", children: pageTitle })
11824
12463
  ] }),
11825
- /* @__PURE__ */ jsx21(
12464
+ /* @__PURE__ */ jsx22(
11826
12465
  ArrowRight2,
11827
12466
  {
11828
12467
  size: 16,
@@ -11830,8 +12469,8 @@ function DestinationBreadcrumb({
11830
12469
  "aria-hidden": true
11831
12470
  }
11832
12471
  ),
11833
- /* @__PURE__ */ jsxs13("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
11834
- /* @__PURE__ */ jsx21(
12472
+ /* @__PURE__ */ jsxs14("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
12473
+ /* @__PURE__ */ jsx22(
11835
12474
  GalleryVertical,
11836
12475
  {
11837
12476
  size: 16,
@@ -11839,7 +12478,7 @@ function DestinationBreadcrumb({
11839
12478
  "aria-hidden": true
11840
12479
  }
11841
12480
  ),
11842
- /* @__PURE__ */ jsx21("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
12481
+ /* @__PURE__ */ jsx22("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
11843
12482
  ] })
11844
12483
  ] })
11845
12484
  ] });
@@ -11847,22 +12486,22 @@ function DestinationBreadcrumb({
11847
12486
 
11848
12487
  // src/ui/link-modal/SectionTreeItem.tsx
11849
12488
  import { GalleryVertical as GalleryVertical2 } from "lucide-react";
11850
- import { jsx as jsx22, jsxs as jsxs14 } from "react/jsx-runtime";
12489
+ import { jsx as jsx23, jsxs as jsxs15 } from "react/jsx-runtime";
11851
12490
  function SectionTreeItem({
11852
12491
  section,
11853
12492
  onSelect,
11854
12493
  selected
11855
12494
  }) {
11856
12495
  const interactive = Boolean(onSelect);
11857
- return /* @__PURE__ */ jsxs14("div", { className: "flex h-9 w-full items-end pl-3", children: [
11858
- /* @__PURE__ */ jsx22(
12496
+ return /* @__PURE__ */ jsxs15("div", { className: "flex h-9 w-full items-end pl-3", children: [
12497
+ /* @__PURE__ */ jsx23(
11859
12498
  "div",
11860
12499
  {
11861
12500
  className: "-mr-px h-9 w-2 shrink-0 rounded-bl-sm border-b border-l border-border mb-4",
11862
12501
  "aria-hidden": true
11863
12502
  }
11864
12503
  ),
11865
- /* @__PURE__ */ jsxs14(
12504
+ /* @__PURE__ */ jsxs15(
11866
12505
  "div",
11867
12506
  {
11868
12507
  role: interactive ? "button" : void 0,
@@ -11880,7 +12519,7 @@ function SectionTreeItem({
11880
12519
  interactive && selected && "border-bridge-primary"
11881
12520
  ),
11882
12521
  children: [
11883
- /* @__PURE__ */ jsx22(
12522
+ /* @__PURE__ */ jsx23(
11884
12523
  GalleryVertical2,
11885
12524
  {
11886
12525
  size: 16,
@@ -11888,7 +12527,7 @@ function SectionTreeItem({
11888
12527
  "aria-hidden": true
11889
12528
  }
11890
12529
  ),
11891
- /* @__PURE__ */ jsx22("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
12530
+ /* @__PURE__ */ jsx23("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
11892
12531
  ]
11893
12532
  }
11894
12533
  )
@@ -11896,14 +12535,14 @@ function SectionTreeItem({
11896
12535
  }
11897
12536
 
11898
12537
  // src/ui/link-modal/UrlOrPageInput.tsx
11899
- import { useEffect as useEffect7, useId as useId2, useRef as useRef7, useState as useState9 } from "react";
12538
+ import { useEffect as useEffect8, useId as useId2, useRef as useRef8, useState as useState10 } from "react";
11900
12539
 
11901
12540
  // src/ui/input.tsx
11902
12541
  import * as React10 from "react";
11903
- import { jsx as jsx23 } from "react/jsx-runtime";
12542
+ import { jsx as jsx24 } from "react/jsx-runtime";
11904
12543
  var Input = React10.forwardRef(
11905
12544
  ({ className, type, ...props }, ref) => {
11906
- return /* @__PURE__ */ jsx23(
12545
+ return /* @__PURE__ */ jsx24(
11907
12546
  "input",
11908
12547
  {
11909
12548
  type,
@@ -11922,9 +12561,9 @@ Input.displayName = "Input";
11922
12561
 
11923
12562
  // src/ui/label.tsx
11924
12563
  import { Label as LabelPrimitive } from "radix-ui";
11925
- import { jsx as jsx24 } from "react/jsx-runtime";
12564
+ import { jsx as jsx25 } from "react/jsx-runtime";
11926
12565
  function Label({ className, ...props }) {
11927
- return /* @__PURE__ */ jsx24(
12566
+ return /* @__PURE__ */ jsx25(
11928
12567
  LabelPrimitive.Root,
11929
12568
  {
11930
12569
  "data-slot": "label",
@@ -11936,11 +12575,11 @@ function Label({ className, ...props }) {
11936
12575
 
11937
12576
  // src/ui/link-modal/UrlOrPageInput.tsx
11938
12577
  import { ChevronDown as ChevronDown3, File as File2, X as X3 } from "lucide-react";
11939
- import { jsx as jsx25, jsxs as jsxs15 } from "react/jsx-runtime";
12578
+ import { jsx as jsx26, jsxs as jsxs16 } from "react/jsx-runtime";
11940
12579
  function FieldChevron({
11941
12580
  onClick
11942
12581
  }) {
11943
- return /* @__PURE__ */ jsx25(
12582
+ return /* @__PURE__ */ jsx26(
11944
12583
  "button",
11945
12584
  {
11946
12585
  type: "button",
@@ -11948,7 +12587,7 @@ function FieldChevron({
11948
12587
  onClick,
11949
12588
  "aria-label": "Open page list",
11950
12589
  tabIndex: -1,
11951
- children: /* @__PURE__ */ jsx25(ChevronDown3, { size: 16 })
12590
+ children: /* @__PURE__ */ jsx26(ChevronDown3, { size: 16 })
11952
12591
  }
11953
12592
  );
11954
12593
  }
@@ -11965,10 +12604,10 @@ function UrlOrPageInput({
11965
12604
  urlError
11966
12605
  }) {
11967
12606
  const inputId = useId2();
11968
- const inputRef = useRef7(null);
11969
- const rootRef = useRef7(null);
11970
- const [isFocused, setIsFocused] = useState9(false);
11971
- useEffect7(() => {
12607
+ const inputRef = useRef8(null);
12608
+ const rootRef = useRef8(null);
12609
+ const [isFocused, setIsFocused] = useState10(false);
12610
+ useEffect8(() => {
11972
12611
  if (!dropdownOpen) return;
11973
12612
  const isOutside = (e) => {
11974
12613
  const root = rootRef.current;
@@ -12009,11 +12648,11 @@ function UrlOrPageInput({
12009
12648
  "data-ohw-link-field flex h-[36px] w-full items-center overflow-hidden rounded-md border bg-background pl-3 pr-3 py-2 outline-none transition-[border-color,box-shadow]",
12010
12649
  urlError ? "border-destructive shadow-[0_0_0_1px_var(--ohw-destructive)]" : isFocused ? "border-bridge-primary shadow-[0_0_0_1px_var(--ohw-primary)]" : "border-input"
12011
12650
  );
12012
- return /* @__PURE__ */ jsxs15("div", { className: "flex w-full flex-col gap-2 p-0", children: [
12013
- /* @__PURE__ */ jsx25(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
12014
- /* @__PURE__ */ jsxs15("div", { ref: rootRef, className: "relative w-full", children: [
12015
- /* @__PURE__ */ jsxs15("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
12016
- selectedPage ? /* @__PURE__ */ jsx25("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ jsx25(
12651
+ return /* @__PURE__ */ jsxs16("div", { className: "flex w-full flex-col gap-2 p-0", children: [
12652
+ /* @__PURE__ */ jsx26(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
12653
+ /* @__PURE__ */ jsxs16("div", { ref: rootRef, className: "relative w-full", children: [
12654
+ /* @__PURE__ */ jsxs16("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
12655
+ selectedPage ? /* @__PURE__ */ jsx26("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ jsx26(
12017
12656
  File2,
12018
12657
  {
12019
12658
  size: 16,
@@ -12021,7 +12660,7 @@ function UrlOrPageInput({
12021
12660
  "aria-hidden": true
12022
12661
  }
12023
12662
  ) }) : null,
12024
- readOnly ? /* @__PURE__ */ jsx25("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ jsx25(
12663
+ readOnly ? /* @__PURE__ */ jsx26("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ jsx26(
12025
12664
  Input,
12026
12665
  {
12027
12666
  ref: inputRef,
@@ -12047,7 +12686,7 @@ function UrlOrPageInput({
12047
12686
  )
12048
12687
  }
12049
12688
  ),
12050
- selectedPage && !readOnly ? /* @__PURE__ */ jsx25(
12689
+ selectedPage && !readOnly ? /* @__PURE__ */ jsx26(
12051
12690
  "button",
12052
12691
  {
12053
12692
  type: "button",
@@ -12055,26 +12694,26 @@ function UrlOrPageInput({
12055
12694
  onMouseDown: clearSelection,
12056
12695
  "aria-label": "Clear selected page",
12057
12696
  tabIndex: -1,
12058
- children: /* @__PURE__ */ jsx25(X3, { size: 16, "aria-hidden": true })
12697
+ children: /* @__PURE__ */ jsx26(X3, { size: 16, "aria-hidden": true })
12059
12698
  }
12060
12699
  ) : null,
12061
- !readOnly ? /* @__PURE__ */ jsx25(FieldChevron, { onClick: toggleDropdown }) : null
12700
+ !readOnly ? /* @__PURE__ */ jsx26(FieldChevron, { onClick: toggleDropdown }) : null
12062
12701
  ] }),
12063
- dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ jsx25(
12702
+ dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ jsx26(
12064
12703
  "div",
12065
12704
  {
12066
12705
  "data-ohw-link-page-dropdown": "",
12067
12706
  className: "absolute left-0 right-0 top-[calc(100%+4px)] z-50 max-h-48 overflow-auto rounded-lg border border-border bg-popover py-1 shadow-lg",
12068
12707
  onMouseDown: (e) => e.preventDefault(),
12069
- children: filteredPages.map((page) => /* @__PURE__ */ jsxs15(
12708
+ children: filteredPages.map((page) => /* @__PURE__ */ jsxs16(
12070
12709
  "button",
12071
12710
  {
12072
12711
  type: "button",
12073
12712
  className: "flex h-9 w-full items-center gap-2 border-0 bg-transparent px-3 text-left text-sm leading-5 text-foreground outline-none hover:bg-muted",
12074
12713
  onClick: () => onPageSelect(page),
12075
12714
  children: [
12076
- /* @__PURE__ */ jsx25(File2, { size: 16, className: "shrink-0", "aria-hidden": true }),
12077
- /* @__PURE__ */ jsx25("span", { className: "truncate", children: page.title })
12715
+ /* @__PURE__ */ jsx26(File2, { size: 16, className: "shrink-0", "aria-hidden": true }),
12716
+ /* @__PURE__ */ jsx26("span", { className: "truncate", children: page.title })
12078
12717
  ]
12079
12718
  },
12080
12719
  page.path
@@ -12082,34 +12721,34 @@ function UrlOrPageInput({
12082
12721
  }
12083
12722
  ) : null
12084
12723
  ] }),
12085
- urlError ? /* @__PURE__ */ jsx25("p", { className: "text-sm font-medium text-destructive", children: urlError }) : null
12724
+ urlError ? /* @__PURE__ */ jsx26("p", { className: "text-sm font-medium text-destructive", children: urlError }) : null
12086
12725
  ] });
12087
12726
  }
12088
12727
 
12089
12728
  // src/ui/link-modal/LinkEditorPanel.tsx
12090
- import { Fragment as Fragment8, jsx as jsx26, jsxs as jsxs16 } from "react/jsx-runtime";
12729
+ import { Fragment as Fragment9, jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
12091
12730
  function LinkEditorPanel({ state, onClose }) {
12092
12731
  const isCancel = state.secondaryLabel === "Cancel" || state.secondaryLabel === "Back to sections";
12093
- return /* @__PURE__ */ jsxs16(Fragment8, { children: [
12094
- /* @__PURE__ */ jsx26(DialogClose, { asChild: true, children: /* @__PURE__ */ jsx26(
12732
+ return /* @__PURE__ */ jsxs17(Fragment9, { children: [
12733
+ /* @__PURE__ */ jsx27(DialogClose, { asChild: true, children: /* @__PURE__ */ jsx27(
12095
12734
  "button",
12096
12735
  {
12097
12736
  type: "button",
12098
12737
  className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50 h-7",
12099
12738
  "aria-label": "Close",
12100
12739
  onClick: onClose,
12101
- children: /* @__PURE__ */ jsx26(X4, { size: 16, "aria-hidden": true })
12740
+ children: /* @__PURE__ */ jsx27(X4, { size: 16, "aria-hidden": true })
12102
12741
  }
12103
12742
  ) }),
12104
- /* @__PURE__ */ jsx26(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ jsx26(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
12105
- /* @__PURE__ */ jsxs16("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
12106
- state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ jsx26(
12743
+ /* @__PURE__ */ jsx27(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ jsx27(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
12744
+ /* @__PURE__ */ jsxs17("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
12745
+ state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ jsx27(
12107
12746
  DestinationBreadcrumb,
12108
12747
  {
12109
12748
  pageTitle: state.selectedPage.title,
12110
12749
  sectionLabel: state.selectedSection.label
12111
12750
  }
12112
- ) : /* @__PURE__ */ jsx26(
12751
+ ) : /* @__PURE__ */ jsx27(
12113
12752
  UrlOrPageInput,
12114
12753
  {
12115
12754
  value: state.searchValue,
@@ -12122,8 +12761,8 @@ function LinkEditorPanel({ state, onClose }) {
12122
12761
  urlError: state.urlError
12123
12762
  }
12124
12763
  ),
12125
- state.showChooseSection ? /* @__PURE__ */ jsxs16("div", { className: "flex flex-col justify-center gap-2", children: [
12126
- /* @__PURE__ */ jsx26(
12764
+ state.showChooseSection ? /* @__PURE__ */ jsxs17("div", { className: "flex flex-col justify-center gap-2", children: [
12765
+ /* @__PURE__ */ jsx27(
12127
12766
  Button,
12128
12767
  {
12129
12768
  type: "button",
@@ -12134,15 +12773,15 @@ function LinkEditorPanel({ state, onClose }) {
12134
12773
  children: "Choose a section"
12135
12774
  }
12136
12775
  ),
12137
- /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
12138
- /* @__PURE__ */ jsx26(Info, { size: 16, className: "shrink-0", "aria-hidden": true }),
12139
- /* @__PURE__ */ jsx26("span", { children: "Pick a section this link should scroll to." })
12776
+ /* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
12777
+ /* @__PURE__ */ jsx27(Info, { size: 16, className: "shrink-0", "aria-hidden": true }),
12778
+ /* @__PURE__ */ jsx27("span", { children: "Pick a section this link should scroll to." })
12140
12779
  ] })
12141
12780
  ] }) : null,
12142
- state.showSectionRow && state.selectedSection ? /* @__PURE__ */ jsx26(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
12781
+ state.showSectionRow && state.selectedSection ? /* @__PURE__ */ jsx27(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
12143
12782
  ] }),
12144
- /* @__PURE__ */ jsxs16(DialogFooter, { className: "w-full px-6 pb-6", children: [
12145
- /* @__PURE__ */ jsx26(
12783
+ /* @__PURE__ */ jsxs17(DialogFooter, { className: "w-full px-6 pb-6", children: [
12784
+ /* @__PURE__ */ jsx27(
12146
12785
  Button,
12147
12786
  {
12148
12787
  type: "button",
@@ -12157,7 +12796,7 @@ function LinkEditorPanel({ state, onClose }) {
12157
12796
  children: state.secondaryLabel
12158
12797
  }
12159
12798
  ),
12160
- /* @__PURE__ */ jsx26(
12799
+ /* @__PURE__ */ jsx27(
12161
12800
  Button,
12162
12801
  {
12163
12802
  type: "button",
@@ -12176,7 +12815,7 @@ function LinkEditorPanel({ state, onClose }) {
12176
12815
  }
12177
12816
 
12178
12817
  // src/ui/link-modal/SectionPickerOverlay.tsx
12179
- import { useCallback as useCallback5, useEffect as useEffect8, useMemo as useMemo2, useRef as useRef8, useState as useState10 } from "react";
12818
+ import { useCallback as useCallback6, useEffect as useEffect9, useMemo as useMemo2, useRef as useRef9, useState as useState11 } from "react";
12180
12819
  import { createPortal as createPortal2 } from "react-dom";
12181
12820
  import { ArrowLeft as ArrowLeft2, Check as Check2 } from "lucide-react";
12182
12821
  import { usePathname, useRouter as useRouter2 } from "next/navigation";
@@ -12200,7 +12839,7 @@ function getIframeChromeClip(parentScroll) {
12200
12839
  }
12201
12840
 
12202
12841
  // src/ui/link-modal/SectionPickerOverlay.tsx
12203
- import { jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
12842
+ import { jsx as jsx28, jsxs as jsxs18 } from "react/jsx-runtime";
12204
12843
  var DIM_OVERLAY = "rgba(0, 0, 0, 0.45)";
12205
12844
  function rectsEqual(a, b) {
12206
12845
  if (a.size !== b.size) return false;
@@ -12233,12 +12872,12 @@ function hitTestSectionId(x, y, sectionIds, rects) {
12233
12872
  return null;
12234
12873
  }
12235
12874
  function useSectionRects(sectionIdsKey, enabled) {
12236
- const [rects, setRects] = useState10(/* @__PURE__ */ new Map());
12875
+ const [rects, setRects] = useState11(/* @__PURE__ */ new Map());
12237
12876
  const sectionIds = useMemo2(
12238
12877
  () => sectionIdsKey ? sectionIdsKey.split("\0") : [],
12239
12878
  [sectionIdsKey]
12240
12879
  );
12241
- useEffect8(() => {
12880
+ useEffect9(() => {
12242
12881
  if (!enabled || sectionIds.length === 0) {
12243
12882
  setRects((prev) => prev.size === 0 ? prev : /* @__PURE__ */ new Map());
12244
12883
  return;
@@ -12279,13 +12918,13 @@ function SectionPickerOverlay({
12279
12918
  }) {
12280
12919
  const router = useRouter2();
12281
12920
  const pathname = usePathname();
12282
- const [selectedId, setSelectedId] = useState10(null);
12283
- const [hoveredId, setHoveredId] = useState10(null);
12284
- const pointerRef = useRef8(null);
12285
- const pointerScreenRef = useRef8(null);
12286
- const iframeOffsetTopRef = useRef8(null);
12287
- const sectionIdsRef = useRef8([]);
12288
- const [chromeClip, setChromeClip] = useState10(
12921
+ const [selectedId, setSelectedId] = useState11(null);
12922
+ const [hoveredId, setHoveredId] = useState11(null);
12923
+ const pointerRef = useRef9(null);
12924
+ const pointerScreenRef = useRef9(null);
12925
+ const iframeOffsetTopRef = useRef9(null);
12926
+ const sectionIdsRef = useRef9([]);
12927
+ const [chromeClip, setChromeClip] = useState11(
12289
12928
  () => ({
12290
12929
  top: 0,
12291
12930
  bottom: typeof window !== "undefined" ? window.innerHeight : 0
@@ -12293,12 +12932,12 @@ function SectionPickerOverlay({
12293
12932
  );
12294
12933
  const normalizedTarget = normalizePath(pagePath);
12295
12934
  const isOnTargetPage = normalizePath(pathname) === normalizedTarget;
12296
- useEffect8(() => {
12935
+ useEffect9(() => {
12297
12936
  if (isOnTargetPage) return;
12298
12937
  const search = readPreservedSearch();
12299
12938
  router.push(`${normalizedTarget}${search}`);
12300
12939
  }, [isOnTargetPage, normalizedTarget, router]);
12301
- useEffect8(() => {
12940
+ useEffect9(() => {
12302
12941
  document.documentElement.setAttribute("data-ohw-section-picking", "");
12303
12942
  document.querySelectorAll("[data-ohw-hovered]").forEach((el) => {
12304
12943
  el.removeAttribute("data-ohw-hovered");
@@ -12327,7 +12966,7 @@ function SectionPickerOverlay({
12327
12966
  );
12328
12967
  sectionIdsRef.current = sectionIds;
12329
12968
  const rects = useSectionRects(sectionIdsKey, isOnTargetPage);
12330
- const applyHoverAt = useCallback5(
12969
+ const applyHoverAt = useCallback6(
12331
12970
  (x, y, liveRects) => {
12332
12971
  const ids = sectionIdsRef.current;
12333
12972
  const map = liveRects ?? readSectionRects(ids);
@@ -12336,7 +12975,7 @@ function SectionPickerOverlay({
12336
12975
  },
12337
12976
  []
12338
12977
  );
12339
- useEffect8(() => {
12978
+ useEffect9(() => {
12340
12979
  const applyClip = (iframeOffsetTop, visibleCanvasTop, canvasH, promptBarH = 0) => {
12341
12980
  const next = getIframeVisibleClip({
12342
12981
  iframeOffsetTop,
@@ -12380,12 +13019,12 @@ function SectionPickerOverlay({
12380
13019
  window.removeEventListener("resize", onResize);
12381
13020
  };
12382
13021
  }, [applyHoverAt]);
12383
- useEffect8(() => {
13022
+ useEffect9(() => {
12384
13023
  const ptr = pointerRef.current;
12385
13024
  if (!ptr) return;
12386
13025
  applyHoverAt(ptr.x, ptr.y, rects);
12387
13026
  }, [rects, applyHoverAt]);
12388
- useEffect8(() => {
13027
+ useEffect9(() => {
12389
13028
  const rememberPointer = (clientX, clientY) => {
12390
13029
  pointerRef.current = { x: clientX, y: clientY };
12391
13030
  const top = iframeOffsetTopRef.current;
@@ -12409,7 +13048,7 @@ function SectionPickerOverlay({
12409
13048
  window.removeEventListener("message", onPointerSync);
12410
13049
  };
12411
13050
  }, [rects, applyHoverAt]);
12412
- const handleSelect = useCallback5(
13051
+ const handleSelect = useCallback6(
12413
13052
  (section) => {
12414
13053
  if (selectedId) return;
12415
13054
  setSelectedId(section.id);
@@ -12417,7 +13056,7 @@ function SectionPickerOverlay({
12417
13056
  },
12418
13057
  [selectedId, onSelect]
12419
13058
  );
12420
- useEffect8(() => {
13059
+ useEffect9(() => {
12421
13060
  const onKeyDown = (e) => {
12422
13061
  if (e.key === "Escape") {
12423
13062
  e.preventDefault();
@@ -12431,7 +13070,7 @@ function SectionPickerOverlay({
12431
13070
  const portalRoot = typeof document !== "undefined" ? document.querySelector("[data-ohw-bridge-root]") ?? document.body : null;
12432
13071
  if (!portalRoot) return null;
12433
13072
  return createPortal2(
12434
- /* @__PURE__ */ jsxs17(
13073
+ /* @__PURE__ */ jsxs18(
12435
13074
  "div",
12436
13075
  {
12437
13076
  "data-ohw-section-picker": "",
@@ -12441,12 +13080,12 @@ function SectionPickerOverlay({
12441
13080
  role: "dialog",
12442
13081
  "aria-label": "Choose a section",
12443
13082
  children: [
12444
- /* @__PURE__ */ jsx27(
13083
+ /* @__PURE__ */ jsx28(
12445
13084
  "div",
12446
13085
  {
12447
13086
  className: "pointer-events-auto fixed left-5 z-[2]",
12448
13087
  style: { top: chromeClip.top + 20 },
12449
- children: /* @__PURE__ */ jsxs17(
13088
+ children: /* @__PURE__ */ jsxs18(
12450
13089
  Button,
12451
13090
  {
12452
13091
  type: "button",
@@ -12455,14 +13094,14 @@ function SectionPickerOverlay({
12455
13094
  className: "h-8 min-w-0 gap-1 border-border bg-background px-2 py-1.5 shadow-sm hover:bg-muted cursor-pointer",
12456
13095
  onClick: onBack,
12457
13096
  children: [
12458
- /* @__PURE__ */ jsx27(ArrowLeft2, { className: "size-4 shrink-0", "aria-hidden": true }),
13097
+ /* @__PURE__ */ jsx28(ArrowLeft2, { className: "size-4 shrink-0", "aria-hidden": true }),
12459
13098
  "Back"
12460
13099
  ]
12461
13100
  }
12462
13101
  )
12463
13102
  }
12464
13103
  ),
12465
- /* @__PURE__ */ jsx27(
13104
+ /* @__PURE__ */ jsx28(
12466
13105
  "div",
12467
13106
  {
12468
13107
  className: "pointer-events-none fixed left-1/2 z-[2] rounded-lg px-4 py-3 text-xs leading-4 tracking-[0.18px] text-white shadow-md",
@@ -12475,7 +13114,7 @@ function SectionPickerOverlay({
12475
13114
  children: "Click on section to select"
12476
13115
  }
12477
13116
  ),
12478
- !isOnTargetPage ? /* @__PURE__ */ jsx27(
13117
+ !isOnTargetPage ? /* @__PURE__ */ jsx28(
12479
13118
  "div",
12480
13119
  {
12481
13120
  className: "pointer-events-none fixed left-1/2 z-[1] -translate-x-1/2 rounded-md px-3 py-2 text-sm text-muted-foreground shadow-sm",
@@ -12483,14 +13122,14 @@ function SectionPickerOverlay({
12483
13122
  children: "Loading page preview\u2026"
12484
13123
  }
12485
13124
  ) : null,
12486
- isOnTargetPage && liveSections.length === 0 ? /* @__PURE__ */ jsx27("div", { className: "pointer-events-auto fixed inset-0 z-[1] flex items-center justify-center bg-muted/40", children: /* @__PURE__ */ jsx27("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." }) }) : null,
13125
+ isOnTargetPage && liveSections.length === 0 ? /* @__PURE__ */ jsx28("div", { className: "pointer-events-auto fixed inset-0 z-[1] flex items-center justify-center bg-muted/40", children: /* @__PURE__ */ jsx28("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." }) }) : null,
12487
13126
  isOnTargetPage ? liveSections.map((section) => {
12488
13127
  const rect = rects.get(section.id);
12489
13128
  if (!rect || rect.width <= 0 || rect.height <= 0) return null;
12490
13129
  const isSelected = selectedId === section.id;
12491
13130
  const isHovered = hoveredId === section.id;
12492
13131
  const isLit = isSelected || isHovered;
12493
- return /* @__PURE__ */ jsxs17(
13132
+ return /* @__PURE__ */ jsxs18(
12494
13133
  "button",
12495
13134
  {
12496
13135
  type: "button",
@@ -12505,7 +13144,7 @@ function SectionPickerOverlay({
12505
13144
  "aria-label": `Select section ${section.label}`,
12506
13145
  onClick: () => handleSelect(section),
12507
13146
  children: [
12508
- isLit ? /* @__PURE__ */ jsx27(
13147
+ isLit ? /* @__PURE__ */ jsx28(
12509
13148
  "span",
12510
13149
  {
12511
13150
  className: "pointer-events-none absolute",
@@ -12518,13 +13157,13 @@ function SectionPickerOverlay({
12518
13157
  "aria-hidden": true
12519
13158
  }
12520
13159
  ) : null,
12521
- isSelected ? /* @__PURE__ */ jsx27(
13160
+ isSelected ? /* @__PURE__ */ jsx28(
12522
13161
  "span",
12523
13162
  {
12524
13163
  className: "absolute right-3 top-3 flex size-8 items-center justify-center rounded-full text-white",
12525
13164
  style: { backgroundColor: "var(--ohw-primary, #0885fe)" },
12526
13165
  "aria-hidden": true,
12527
- children: /* @__PURE__ */ jsx27(Check2, { className: "size-5" })
13166
+ children: /* @__PURE__ */ jsx28(Check2, { className: "size-5" })
12528
13167
  }
12529
13168
  ) : null
12530
13169
  ]
@@ -12540,7 +13179,7 @@ function SectionPickerOverlay({
12540
13179
  }
12541
13180
 
12542
13181
  // src/ui/link-modal/useLinkModalState.ts
12543
- import { useCallback as useCallback6, useEffect as useEffect9, useMemo as useMemo3, useState as useState11 } from "react";
13182
+ import { useCallback as useCallback7, useEffect as useEffect10, useMemo as useMemo3, useState as useState12 } from "react";
12544
13183
  function useLinkModalState({
12545
13184
  open,
12546
13185
  mode,
@@ -12553,13 +13192,13 @@ function useLinkModalState({
12553
13192
  onSubmit
12554
13193
  }) {
12555
13194
  const availablePages = useMemo3(() => pages, [pages]);
12556
- const [searchValue, setSearchValue] = useState11("");
12557
- const [selectedPage, setSelectedPage] = useState11(null);
12558
- const [selectedSection, setSelectedSection] = useState11(null);
12559
- const [step, setStep] = useState11("input");
12560
- const [dropdownOpen, setDropdownOpen] = useState11(false);
12561
- const [urlError, setUrlError] = useState11("");
12562
- const reset = useCallback6(() => {
13195
+ const [searchValue, setSearchValue] = useState12("");
13196
+ const [selectedPage, setSelectedPage] = useState12(null);
13197
+ const [selectedSection, setSelectedSection] = useState12(null);
13198
+ const [step, setStep] = useState12("input");
13199
+ const [dropdownOpen, setDropdownOpen] = useState12(false);
13200
+ const [urlError, setUrlError] = useState12("");
13201
+ const reset = useCallback7(() => {
12563
13202
  setSearchValue("");
12564
13203
  setSelectedPage(null);
12565
13204
  setSelectedSection(null);
@@ -12567,7 +13206,7 @@ function useLinkModalState({
12567
13206
  setDropdownOpen(false);
12568
13207
  setUrlError("");
12569
13208
  }, []);
12570
- useEffect9(() => {
13209
+ useEffect10(() => {
12571
13210
  if (!open) return;
12572
13211
  if (mode === "edit" && initialTarget) {
12573
13212
  const { pageRoute } = parseTarget(initialTarget);
@@ -12704,7 +13343,7 @@ function useLinkModalState({
12704
13343
  }
12705
13344
 
12706
13345
  // src/ui/link-modal/LinkPopover.tsx
12707
- import { Fragment as Fragment9, jsx as jsx28, jsxs as jsxs18 } from "react/jsx-runtime";
13346
+ import { Fragment as Fragment10, jsx as jsx29, jsxs as jsxs19 } from "react/jsx-runtime";
12708
13347
  function postToParent(data) {
12709
13348
  window.parent?.postMessage(data, "*");
12710
13349
  }
@@ -12733,7 +13372,7 @@ function LinkPopover({
12733
13372
  onSubmit
12734
13373
  });
12735
13374
  const sectionPickerActive = state.showSectionPicker && Boolean(state.selectedPage);
12736
- useEffect10(() => {
13375
+ useEffect11(() => {
12737
13376
  if (!open) return;
12738
13377
  if (sectionPickerActive) {
12739
13378
  postToParent({ type: "ui:unlock" });
@@ -12800,15 +13439,15 @@ function LinkPopover({
12800
13439
  );
12801
13440
  };
12802
13441
  }, [open, sectionPickerActive]);
12803
- return /* @__PURE__ */ jsxs18(Fragment9, { children: [
12804
- /* @__PURE__ */ jsx28(
13442
+ return /* @__PURE__ */ jsxs19(Fragment10, { children: [
13443
+ /* @__PURE__ */ jsx29(
12805
13444
  Dialog2,
12806
13445
  {
12807
13446
  open: open && !sectionPickerActive,
12808
13447
  onOpenChange: (next) => {
12809
13448
  if (!next) onClose?.();
12810
13449
  },
12811
- children: /* @__PURE__ */ jsx28(
13450
+ children: /* @__PURE__ */ jsx29(
12812
13451
  DialogContent,
12813
13452
  {
12814
13453
  ref: panelRef,
@@ -12818,12 +13457,12 @@ function LinkPopover({
12818
13457
  "data-ohw-bridge": "",
12819
13458
  showCloseButton: false,
12820
13459
  className: "gap-0 p-0 w-full max-w-[448px] pointer-events-auto z-[2147483646] overflow-visible",
12821
- children: /* @__PURE__ */ jsx28(LinkEditorPanel, { state, onClose })
13460
+ children: /* @__PURE__ */ jsx29(LinkEditorPanel, { state, onClose })
12822
13461
  }
12823
13462
  )
12824
13463
  }
12825
13464
  ),
12826
- sectionPickerActive && state.selectedPage ? /* @__PURE__ */ jsx28(
13465
+ sectionPickerActive && state.selectedPage ? /* @__PURE__ */ jsx29(
12827
13466
  SectionPickerOverlay,
12828
13467
  {
12829
13468
  pagePath: state.selectedPage.path,
@@ -15945,6 +16584,7 @@ function readLogoSizeState(content, placement) {
15945
16584
  function getLogoElement(el) {
15946
16585
  const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
15947
16586
  if (marked) return marked;
16587
+ if (el.closest('[data-ohw-editable="icon"]')) return null;
15948
16588
  const root = el.closest("nav, [data-ohw-nav-root], footer");
15949
16589
  if (!root) return null;
15950
16590
  const anchor = el.closest("a");
@@ -16012,14 +16652,14 @@ function addFooterColumnWithPersist({
16012
16652
 
16013
16653
  // src/ui/FloatingPanel.tsx
16014
16654
  import {
16015
- useCallback as useCallback7,
16016
- useEffect as useEffect11,
16655
+ useCallback as useCallback8,
16656
+ useEffect as useEffect12,
16017
16657
  useLayoutEffect as useLayoutEffect4,
16018
- useRef as useRef9,
16019
- useState as useState12
16658
+ useRef as useRef10,
16659
+ useState as useState13
16020
16660
  } from "react";
16021
16661
  import { X as X5 } from "lucide-react";
16022
- import { jsx as jsx29, jsxs as jsxs19 } from "react/jsx-runtime";
16662
+ import { jsx as jsx30, jsxs as jsxs20 } from "react/jsx-runtime";
16023
16663
  var PANEL_WIDTH = 256;
16024
16664
  var EDGE_MARGIN = 16;
16025
16665
  var HEADER_MIN = 56;
@@ -16079,10 +16719,10 @@ function FloatingPanel({
16079
16719
  className,
16080
16720
  bodyClassName
16081
16721
  }) {
16082
- const panelRef = useRef9(null);
16083
- const [measured, setMeasured] = useState12({ w: PANEL_WIDTH, h: 280 });
16084
- const dragRef = useRef9(null);
16085
- const homeRef = useRef9(null);
16722
+ const panelRef = useRef10(null);
16723
+ const [measured, setMeasured] = useState13({ w: PANEL_WIDTH, h: 280 });
16724
+ const dragRef = useRef10(null);
16725
+ const homeRef = useRef10(null);
16086
16726
  if (!open) {
16087
16727
  homeRef.current = null;
16088
16728
  } else if (position) {
@@ -16090,17 +16730,17 @@ function FloatingPanel({
16090
16730
  } else if (homeRef.current == null) {
16091
16731
  homeRef.current = defaultFloatingPanelPosition(parentScroll);
16092
16732
  }
16093
- const [liveScroll, setLiveScroll] = useState12(parentScroll);
16733
+ const [liveScroll, setLiveScroll] = useState13(parentScroll);
16094
16734
  const home = position ?? homeRef.current ?? defaultFloatingPanelPosition(parentScroll);
16095
16735
  const { y: fittedY, maxHeight } = fitPanelInClip(home.y, liveScroll, measured.h);
16096
16736
  const clamped = {
16097
16737
  x: clampX(home.x, measured.w),
16098
16738
  y: fittedY
16099
16739
  };
16100
- useEffect11(() => {
16740
+ useEffect12(() => {
16101
16741
  setLiveScroll(parentScroll);
16102
16742
  }, [parentScroll]);
16103
- useEffect11(() => {
16743
+ useEffect12(() => {
16104
16744
  if (!open) return;
16105
16745
  const onParentScroll = (e) => {
16106
16746
  if (e.data?.type !== "ow:parent-scroll") return;
@@ -16110,7 +16750,7 @@ function FloatingPanel({
16110
16750
  window.addEventListener("message", onParentScroll);
16111
16751
  return () => window.removeEventListener("message", onParentScroll);
16112
16752
  }, [open]);
16113
- const positionRef = useRef9(position);
16753
+ const positionRef = useRef10(position);
16114
16754
  useLayoutEffect4(() => {
16115
16755
  if (!open) {
16116
16756
  positionRef.current = position;
@@ -16130,7 +16770,7 @@ function FloatingPanel({
16130
16770
  const next = { w: el.offsetWidth || PANEL_WIDTH, h: contentH };
16131
16771
  setMeasured((prev) => prev.w === next.w && prev.h === next.h ? prev : next);
16132
16772
  }, [open, children, title, context]);
16133
- const onHeaderPointerDown = useCallback7(
16773
+ const onHeaderPointerDown = useCallback8(
16134
16774
  (e) => {
16135
16775
  if (e.button !== 0) return;
16136
16776
  if (e.target.closest("[data-ohw-floating-panel-close]")) return;
@@ -16149,7 +16789,7 @@ function FloatingPanel({
16149
16789
  },
16150
16790
  [clamped.x, clamped.y]
16151
16791
  );
16152
- const onHeaderPointerMove = useCallback7(
16792
+ const onHeaderPointerMove = useCallback8(
16153
16793
  (e) => {
16154
16794
  const drag = dragRef.current;
16155
16795
  if (!drag || drag.pointerId !== e.pointerId) return;
@@ -16175,7 +16815,7 @@ function FloatingPanel({
16175
16815
  },
16176
16816
  [measured.w, onPositionChange, liveScroll]
16177
16817
  );
16178
- const endDrag = useCallback7((e) => {
16818
+ const endDrag = useCallback8((e) => {
16179
16819
  const drag = dragRef.current;
16180
16820
  if (!drag || drag.pointerId !== e.pointerId) return;
16181
16821
  dragRef.current = null;
@@ -16185,13 +16825,13 @@ function FloatingPanel({
16185
16825
  } catch {
16186
16826
  }
16187
16827
  }, []);
16188
- useEffect11(() => {
16828
+ useEffect12(() => {
16189
16829
  if (open) return;
16190
16830
  document.documentElement.removeAttribute("data-ohw-panel-dragging");
16191
16831
  }, [open]);
16192
- useEffect11(() => () => document.documentElement.removeAttribute("data-ohw-panel-dragging"), []);
16832
+ useEffect12(() => () => document.documentElement.removeAttribute("data-ohw-panel-dragging"), []);
16193
16833
  if (!open) return null;
16194
- return /* @__PURE__ */ jsxs19(
16834
+ return /* @__PURE__ */ jsxs20(
16195
16835
  "div",
16196
16836
  {
16197
16837
  ref: panelRef,
@@ -16208,7 +16848,7 @@ function FloatingPanel({
16208
16848
  onPointerDown: (e) => e.stopPropagation(),
16209
16849
  onClick: (e) => e.stopPropagation(),
16210
16850
  children: [
16211
- /* @__PURE__ */ jsxs19(
16851
+ /* @__PURE__ */ jsxs20(
16212
16852
  "div",
16213
16853
  {
16214
16854
  "data-ohw-floating-panel-header": "",
@@ -16218,14 +16858,14 @@ function FloatingPanel({
16218
16858
  onPointerUp: endDrag,
16219
16859
  onPointerCancel: endDrag,
16220
16860
  children: [
16221
- /* @__PURE__ */ jsxs19("div", { className: "flex min-w-0 flex-1 flex-col gap-1.5", children: [
16222
- /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2", children: [
16223
- icon ? /* @__PURE__ */ jsx29("span", { className: "shrink-0 text-foreground", children: icon }) : null,
16224
- /* @__PURE__ */ jsx29("p", { className: "min-w-0 flex-1 text-lg font-semibold leading-7 text-foreground", children: title })
16861
+ /* @__PURE__ */ jsxs20("div", { className: "flex min-w-0 flex-1 flex-col gap-1.5", children: [
16862
+ /* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-2", children: [
16863
+ icon ? /* @__PURE__ */ jsx30("span", { className: "shrink-0 text-foreground", children: icon }) : null,
16864
+ /* @__PURE__ */ jsx30("p", { className: "min-w-0 flex-1 text-lg font-semibold leading-7 text-foreground", children: title })
16225
16865
  ] }),
16226
- context ? /* @__PURE__ */ jsx29("p", { className: "w-full text-sm leading-5 text-muted-foreground", children: context }) : null
16866
+ context ? /* @__PURE__ */ jsx30("p", { className: "w-full text-sm leading-5 text-muted-foreground", children: context }) : null
16227
16867
  ] }),
16228
- /* @__PURE__ */ jsx29(
16868
+ /* @__PURE__ */ jsx30(
16229
16869
  "button",
16230
16870
  {
16231
16871
  type: "button",
@@ -16237,13 +16877,13 @@ function FloatingPanel({
16237
16877
  onClose();
16238
16878
  },
16239
16879
  onPointerDown: (e) => e.stopPropagation(),
16240
- children: /* @__PURE__ */ jsx29(X5, { size: 16, "aria-hidden": true })
16880
+ children: /* @__PURE__ */ jsx30(X5, { size: 16, "aria-hidden": true })
16241
16881
  }
16242
16882
  )
16243
16883
  ]
16244
16884
  }
16245
16885
  ),
16246
- /* @__PURE__ */ jsx29(
16886
+ /* @__PURE__ */ jsx30(
16247
16887
  "div",
16248
16888
  {
16249
16889
  "data-ohw-floating-panel-body": "",
@@ -16261,15 +16901,15 @@ function FloatingPanel({
16261
16901
  }
16262
16902
 
16263
16903
  // src/ui/socials-display-panel.tsx
16264
- import { jsx as jsx30, jsxs as jsxs20 } from "react/jsx-runtime";
16904
+ import { jsx as jsx31, jsxs as jsxs21 } from "react/jsx-runtime";
16265
16905
  function DisplaySwitch({
16266
16906
  label,
16267
16907
  checked,
16268
16908
  disabled,
16269
16909
  onChange
16270
16910
  }) {
16271
- return /* @__PURE__ */ jsxs20("div", { className: "flex w-full items-center gap-2", children: [
16272
- /* @__PURE__ */ jsx30(
16911
+ return /* @__PURE__ */ jsxs21("div", { className: "flex w-full items-center gap-2", children: [
16912
+ /* @__PURE__ */ jsx31(
16273
16913
  "span",
16274
16914
  {
16275
16915
  className: cn(
@@ -16279,7 +16919,7 @@ function DisplaySwitch({
16279
16919
  children: label
16280
16920
  }
16281
16921
  ),
16282
- /* @__PURE__ */ jsx30(
16922
+ /* @__PURE__ */ jsx31(
16283
16923
  "button",
16284
16924
  {
16285
16925
  type: "button",
@@ -16293,7 +16933,7 @@ function DisplaySwitch({
16293
16933
  checked ? "bg-bridge-primary" : "bg-primary-50",
16294
16934
  disabled ? "cursor-default opacity-50" : "cursor-pointer"
16295
16935
  ),
16296
- children: /* @__PURE__ */ jsx30(
16936
+ children: /* @__PURE__ */ jsx31(
16297
16937
  "span",
16298
16938
  {
16299
16939
  className: cn(
@@ -16307,8 +16947,8 @@ function DisplaySwitch({
16307
16947
  ] });
16308
16948
  }
16309
16949
  function SocialsDisplayPanel({ display, onChange, className }) {
16310
- return /* @__PURE__ */ jsxs20("div", { className: cn("flex w-full flex-col gap-3", className), children: [
16311
- /* @__PURE__ */ jsx30(
16950
+ return /* @__PURE__ */ jsxs21("div", { className: cn("flex w-full flex-col gap-3", className), children: [
16951
+ /* @__PURE__ */ jsx31(
16312
16952
  DisplaySwitch,
16313
16953
  {
16314
16954
  label: "Text",
@@ -16317,7 +16957,7 @@ function SocialsDisplayPanel({ display, onChange, className }) {
16317
16957
  onChange: (text) => onChange({ ...display, text })
16318
16958
  }
16319
16959
  ),
16320
- /* @__PURE__ */ jsx30(
16960
+ /* @__PURE__ */ jsx31(
16321
16961
  DisplaySwitch,
16322
16962
  {
16323
16963
  label: "Icon",
@@ -17033,7 +17673,7 @@ function withAssignment(content, id, assignment) {
17033
17673
  }
17034
17674
 
17035
17675
  // src/ui/button-style-panel.tsx
17036
- import { jsx as jsx31, jsxs as jsxs21 } from "react/jsx-runtime";
17676
+ import { jsx as jsx32, jsxs as jsxs22 } from "react/jsx-runtime";
17037
17677
  var SIZE_LABEL = { s: "S", m: "M", l: "L" };
17038
17678
  function ButtonStylePanel({
17039
17679
  variants,
@@ -17047,15 +17687,15 @@ function ButtonStylePanel({
17047
17687
  }) {
17048
17688
  const preview = scaleGeometry(sizes.m, 0.75);
17049
17689
  const label = previewLabel.trim() || "Book Now";
17050
- return /* @__PURE__ */ jsxs21("div", { className: "flex w-full flex-col gap-5", children: [
17051
- /* @__PURE__ */ jsxs21("section", { className: "flex w-full flex-col gap-2.5", children: [
17052
- /* @__PURE__ */ jsx31("h3", { className: "text-xs font-semibold uppercase leading-4 tracking-[0.6px] text-stone-500 font-sans", children: "Variants" }),
17053
- /* @__PURE__ */ jsx31("div", { className: "flex w-full flex-col gap-2.5", children: BUTTON_VARIANT_IDS.map((id) => {
17690
+ return /* @__PURE__ */ jsxs22("div", { className: "flex w-full flex-col gap-5", children: [
17691
+ /* @__PURE__ */ jsxs22("section", { className: "flex w-full flex-col gap-2.5", children: [
17692
+ /* @__PURE__ */ jsx32("h3", { className: "text-xs font-semibold uppercase leading-4 tracking-[0.6px] text-stone-500 font-sans", children: "Variants" }),
17693
+ /* @__PURE__ */ jsx32("div", { className: "flex w-full flex-col gap-2.5", children: BUTTON_VARIANT_IDS.map((id) => {
17054
17694
  const chrome = variants[id];
17055
17695
  const selected = id === variant;
17056
17696
  const hasBorder = parseFloat(chrome.borderWidth) > 0;
17057
17697
  const cardSlot = previewSlotForChrome(chrome, slotBackground);
17058
- return /* @__PURE__ */ jsxs21(
17698
+ return /* @__PURE__ */ jsxs22(
17059
17699
  "button",
17060
17700
  {
17061
17701
  type: "button",
@@ -17071,12 +17711,12 @@ function ButtonStylePanel({
17071
17711
  selected ? "border-2 border-primary" : "border border-border"
17072
17712
  ),
17073
17713
  children: [
17074
- /* @__PURE__ */ jsx31(
17714
+ /* @__PURE__ */ jsx32(
17075
17715
  "div",
17076
17716
  {
17077
17717
  className: "flex w-full items-center justify-center py-4",
17078
17718
  style: { background: cardSlot },
17079
- children: /* @__PURE__ */ jsx31(
17719
+ children: /* @__PURE__ */ jsx32(
17080
17720
  "span",
17081
17721
  {
17082
17722
  className: "inline-flex items-center justify-center whitespace-nowrap font-semibold uppercase leading-none",
@@ -17098,12 +17738,12 @@ function ButtonStylePanel({
17098
17738
  )
17099
17739
  }
17100
17740
  ),
17101
- selected ? /* @__PURE__ */ jsx31(
17741
+ selected ? /* @__PURE__ */ jsx32(
17102
17742
  "span",
17103
17743
  {
17104
17744
  className: "absolute right-0.5 top-0.5 flex size-5 items-center justify-center rounded-full bg-primary text-primary-foreground",
17105
17745
  "aria-hidden": true,
17106
- children: /* @__PURE__ */ jsx31(Check3, { className: "size-3", strokeWidth: 3 })
17746
+ children: /* @__PURE__ */ jsx32(Check3, { className: "size-3", strokeWidth: 3 })
17107
17747
  }
17108
17748
  ) : null
17109
17749
  ]
@@ -17112,9 +17752,9 @@ function ButtonStylePanel({
17112
17752
  );
17113
17753
  }) })
17114
17754
  ] }),
17115
- /* @__PURE__ */ jsxs21("section", { className: "flex w-full flex-col gap-2.5", children: [
17116
- /* @__PURE__ */ jsx31("h3", { className: "text-xs font-semibold uppercase leading-4 tracking-[0.6px] text-stone-500 font-sans", children: "Size" }),
17117
- /* @__PURE__ */ jsx31(
17755
+ /* @__PURE__ */ jsxs22("section", { className: "flex w-full flex-col gap-2.5", children: [
17756
+ /* @__PURE__ */ jsx32("h3", { className: "text-xs font-semibold uppercase leading-4 tracking-[0.6px] text-stone-500 font-sans", children: "Size" }),
17757
+ /* @__PURE__ */ jsx32(
17118
17758
  "div",
17119
17759
  {
17120
17760
  className: "flex w-full items-start rounded-lg bg-stone-100 p-1",
@@ -17122,7 +17762,7 @@ function ButtonStylePanel({
17122
17762
  "aria-label": "Size",
17123
17763
  children: BUTTON_SIZE_IDS.map((id) => {
17124
17764
  const selected = id === size;
17125
- return /* @__PURE__ */ jsx31(
17765
+ return /* @__PURE__ */ jsx32(
17126
17766
  "button",
17127
17767
  {
17128
17768
  type: "button",
@@ -18026,7 +18666,7 @@ function hitTestNavDropSlot(clientX, clientY, draggedHrefKey, draggedEl) {
18026
18666
  }
18027
18667
 
18028
18668
  // src/useNavItemDrag.ts
18029
- import { useCallback as useCallback8, useEffect as useEffect12, useRef as useRef10, useState as useState13 } from "react";
18669
+ import { useCallback as useCallback9, useEffect as useEffect13, useRef as useRef11, useState as useState14 } from "react";
18030
18670
  function useNavItemDrag({
18031
18671
  isEditMode,
18032
18672
  editContentRef,
@@ -18050,11 +18690,11 @@ function useNavItemDrag({
18050
18690
  getNavigationItemAnchor: getNavigationItemAnchor2,
18051
18691
  isDragHandleDisabled: isDragHandleDisabled2
18052
18692
  }) {
18053
- const navDragRef = useRef10(null);
18054
- const [navDropSlots, setNavDropSlots] = useState13([]);
18055
- const [activeNavDropIndex, setActiveNavDropIndex] = useState13(null);
18056
- const navPointerDragRef = useRef10(null);
18057
- const clearNavDragVisuals = useCallback8(() => {
18693
+ const navDragRef = useRef11(null);
18694
+ const [navDropSlots, setNavDropSlots] = useState14([]);
18695
+ const [activeNavDropIndex, setActiveNavDropIndex] = useState14(null);
18696
+ const navPointerDragRef = useRef11(null);
18697
+ const clearNavDragVisuals = useCallback9(() => {
18058
18698
  const session = navDragRef.current;
18059
18699
  const nestedHrefKey = session?.draggedEl?.closest("[data-ohw-nav-children]") != null ? session.hrefKey : null;
18060
18700
  navDragRef.current = null;
@@ -18087,7 +18727,7 @@ function useNavItemDrag({
18087
18727
  document.documentElement.removeAttribute("data-ohw-nav-dragging-root");
18088
18728
  unlockItemDragInteraction();
18089
18729
  }, [setDraggedItemRect, setIsItemDragging, setSiblingHintRects]);
18090
- const refreshNavDragVisuals = useCallback8(
18730
+ const refreshNavDragVisuals = useCallback9(
18091
18731
  (session, activeSlot, clientX, clientY) => {
18092
18732
  setDraggedItemRect(session.draggedEl.getBoundingClientRect());
18093
18733
  if (typeof clientX === "number" && typeof clientY === "number") {
@@ -18105,13 +18745,13 @@ function useNavItemDrag({
18105
18745
  },
18106
18746
  [setDraggedItemRect, setSiblingHintRects]
18107
18747
  );
18108
- const refreshNavDragVisualsRef = useRef10(refreshNavDragVisuals);
18748
+ const refreshNavDragVisualsRef = useRef11(refreshNavDragVisuals);
18109
18749
  refreshNavDragVisualsRef.current = refreshNavDragVisuals;
18110
- const commitNavDragRef = useRef10(() => {
18750
+ const commitNavDragRef = useRef11(() => {
18111
18751
  });
18112
- const beginNavDragRef = useRef10(() => {
18752
+ const beginNavDragRef = useRef11(() => {
18113
18753
  });
18114
- const beginNavDrag = useCallback8(
18754
+ const beginNavDrag = useCallback9(
18115
18755
  (session) => {
18116
18756
  const rect = session.draggedEl.getBoundingClientRect();
18117
18757
  session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
@@ -18150,7 +18790,7 @@ function useNavItemDrag({
18150
18790
  ]
18151
18791
  );
18152
18792
  beginNavDragRef.current = beginNavDrag;
18153
- const commitNavDrag = useCallback8(
18793
+ const commitNavDrag = useCallback9(
18154
18794
  (clientX, clientY) => {
18155
18795
  const session = navDragRef.current;
18156
18796
  if (!session) {
@@ -18229,7 +18869,7 @@ function useNavItemDrag({
18229
18869
  [clearNavDragVisuals, deselectRef, editContentRef, postToParentRef, selectRef]
18230
18870
  );
18231
18871
  commitNavDragRef.current = commitNavDrag;
18232
- const startNavLinkDrag = useCallback8(
18872
+ const startNavLinkDrag = useCallback9(
18233
18873
  (anchor, clientX, clientY, wasSelected) => {
18234
18874
  if (footerDragRef.current) return false;
18235
18875
  const hrefKey = anchor.getAttribute("data-ohw-href-key");
@@ -18247,7 +18887,7 @@ function useNavItemDrag({
18247
18887
  },
18248
18888
  [beginNavDrag, footerDragRef, isDragHandleDisabled2, isCtaButton]
18249
18889
  );
18250
- const onNavDragOver = useCallback8(
18890
+ const onNavDragOver = useCallback9(
18251
18891
  (e) => {
18252
18892
  const session = navDragRef.current;
18253
18893
  if (!session) return false;
@@ -18259,7 +18899,7 @@ function useNavItemDrag({
18259
18899
  },
18260
18900
  []
18261
18901
  );
18262
- useEffect12(() => {
18902
+ useEffect13(() => {
18263
18903
  if (!isEditMode) return;
18264
18904
  const THRESHOLD = 10;
18265
18905
  const resolveWasSelected = (el) => {
@@ -18386,7 +19026,7 @@ function useNavItemDrag({
18386
19026
  setLinkPopover,
18387
19027
  suppressNextClickRef
18388
19028
  ]);
18389
- const armNavPressFromChrome = useCallback8(
19029
+ const armNavPressFromChrome = useCallback9(
18390
19030
  (selected, clientX, clientY, pointerId) => {
18391
19031
  const hrefKey = selected.getAttribute("data-ohw-href-key");
18392
19032
  if (!hrefKey || !isNavbarHrefKey(hrefKey)) return false;
@@ -18418,7 +19058,7 @@ function useNavItemDrag({
18418
19058
  }
18419
19059
 
18420
19060
  // src/useSectionDrag.ts
18421
- import { useCallback as useCallback9, useEffect as useEffect13, useRef as useRef11, useState as useState14 } from "react";
19061
+ import { useCallback as useCallback10, useEffect as useEffect14, useRef as useRef12, useState as useState15 } from "react";
18422
19062
 
18423
19063
  // src/lib/section-dnd.ts
18424
19064
  function isFooterSection(el) {
@@ -18511,21 +19151,21 @@ function useSectionDrag({
18511
19151
  suppressNextClickRef,
18512
19152
  suppressClickUntilRef
18513
19153
  }) {
18514
- const sectionDragRef = useRef11(null);
18515
- const [sectionDropSlots, setSectionDropSlots] = useState14([]);
18516
- const [activeSectionDropIndex, setActiveSectionDropIndex] = useState14(null);
18517
- const [isSectionDragging, setIsSectionDragging] = useState14(false);
18518
- const sectionPointerDragRef = useRef11(null);
18519
- const autoScrollRafRef = useRef11(null);
18520
- const autoScrollDeltaRef = useRef11(0);
18521
- const stopAutoScroll = useCallback9(() => {
19154
+ const sectionDragRef = useRef12(null);
19155
+ const [sectionDropSlots, setSectionDropSlots] = useState15([]);
19156
+ const [activeSectionDropIndex, setActiveSectionDropIndex] = useState15(null);
19157
+ const [isSectionDragging, setIsSectionDragging] = useState15(false);
19158
+ const sectionPointerDragRef = useRef12(null);
19159
+ const autoScrollRafRef = useRef12(null);
19160
+ const autoScrollDeltaRef = useRef12(0);
19161
+ const stopAutoScroll = useCallback10(() => {
18522
19162
  if (autoScrollRafRef.current != null) {
18523
19163
  cancelAnimationFrame(autoScrollRafRef.current);
18524
19164
  autoScrollRafRef.current = null;
18525
19165
  }
18526
19166
  autoScrollDeltaRef.current = 0;
18527
19167
  }, []);
18528
- const tickAutoScroll = useCallback9(() => {
19168
+ const tickAutoScroll = useCallback10(() => {
18529
19169
  if (!sectionDragRef.current) {
18530
19170
  stopAutoScroll();
18531
19171
  return;
@@ -18535,7 +19175,7 @@ function useSectionDrag({
18535
19175
  }
18536
19176
  autoScrollRafRef.current = requestAnimationFrame(tickAutoScroll);
18537
19177
  }, [postToParentRef, stopAutoScroll]);
18538
- const updateAutoScroll = useCallback9(
19178
+ const updateAutoScroll = useCallback10(
18539
19179
  (clientY) => {
18540
19180
  const clip = getIframeChromeClip(parentScrollRef.current);
18541
19181
  let delta = 0;
@@ -18557,7 +19197,7 @@ function useSectionDrag({
18557
19197
  },
18558
19198
  [parentScrollRef, stopAutoScroll, tickAutoScroll]
18559
19199
  );
18560
- const clearSectionDragVisuals = useCallback9(() => {
19200
+ const clearSectionDragVisuals = useCallback10(() => {
18561
19201
  sectionDragRef.current?.draggedEl.removeAttribute("data-ohw-section-dragging");
18562
19202
  sectionDragRef.current = null;
18563
19203
  setSectionDropSlots([]);
@@ -18567,7 +19207,7 @@ function useSectionDrag({
18567
19207
  document.documentElement.removeAttribute("data-ohw-section-dragging-root");
18568
19208
  unlockItemDragInteraction();
18569
19209
  }, [stopAutoScroll]);
18570
- const refreshSectionDragVisuals = useCallback9(
19210
+ const refreshSectionDragVisuals = useCallback10(
18571
19211
  (session, clientX, clientY) => {
18572
19212
  session.lastClientX = clientX;
18573
19213
  session.lastClientY = clientY;
@@ -18581,7 +19221,7 @@ function useSectionDrag({
18581
19221
  },
18582
19222
  [updateAutoScroll]
18583
19223
  );
18584
- const beginSectionDrag = useCallback9(
19224
+ const beginSectionDrag = useCallback10(
18585
19225
  (session) => {
18586
19226
  sectionDragRef.current = session;
18587
19227
  setIsSectionDragging(true);
@@ -18592,7 +19232,7 @@ function useSectionDrag({
18592
19232
  },
18593
19233
  [refreshSectionDragVisuals]
18594
19234
  );
18595
- const commitSectionDrag = useCallback9(() => {
19235
+ const commitSectionDrag = useCallback10(() => {
18596
19236
  const session = sectionDragRef.current;
18597
19237
  if (!session) {
18598
19238
  clearSectionDragVisuals();
@@ -18621,7 +19261,7 @@ function useSectionDrag({
18621
19261
  });
18622
19262
  });
18623
19263
  }, [clearSectionDragVisuals, editContentRef, postToParentRef]);
18624
- const startSectionPressDrag = useCallback9(
19264
+ const startSectionPressDrag = useCallback10(
18625
19265
  (el, clientX, clientY, pointerId) => {
18626
19266
  if (navDragRef.current || footerDragRef.current || sectionDragRef.current) return false;
18627
19267
  const instanceId = instanceIdOf(el);
@@ -18638,7 +19278,7 @@ function useSectionDrag({
18638
19278
  },
18639
19279
  [footerDragRef, navDragRef]
18640
19280
  );
18641
- useEffect13(() => {
19281
+ useEffect14(() => {
18642
19282
  if (!isEditMode) return;
18643
19283
  const onPointerDown = (e) => {
18644
19284
  if (e.button !== 0) return;
@@ -18744,7 +19384,7 @@ function useSectionDrag({
18744
19384
 
18745
19385
  // src/ui/footer-container-chrome.tsx
18746
19386
  import { Plus as Plus2 } from "lucide-react";
18747
- import { jsx as jsx32, jsxs as jsxs22 } from "react/jsx-runtime";
19387
+ import { jsx as jsx33, jsxs as jsxs23 } from "react/jsx-runtime";
18748
19388
  function FooterContainerChrome({
18749
19389
  rect,
18750
19390
  onAdd,
@@ -18752,7 +19392,7 @@ function FooterContainerChrome({
18752
19392
  }) {
18753
19393
  const chromeGap = 6;
18754
19394
  const buttonMargin = 7;
18755
- return /* @__PURE__ */ jsx32(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsx32(
19395
+ return /* @__PURE__ */ jsx33(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsx33(
18756
19396
  "div",
18757
19397
  {
18758
19398
  "data-ohw-footer-container-chrome": "",
@@ -18764,8 +19404,8 @@ function FooterContainerChrome({
18764
19404
  width: rect.width + chromeGap * 2,
18765
19405
  height: rect.height + chromeGap * 2
18766
19406
  },
18767
- children: /* @__PURE__ */ jsxs22(Tooltip, { children: [
18768
- /* @__PURE__ */ jsx32(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx32(
19407
+ children: /* @__PURE__ */ jsxs23(Tooltip, { children: [
19408
+ /* @__PURE__ */ jsx33(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx33(
18769
19409
  "button",
18770
19410
  {
18771
19411
  type: "button",
@@ -18784,17 +19424,17 @@ function FooterContainerChrome({
18784
19424
  if (addDisabled) return;
18785
19425
  onAdd();
18786
19426
  },
18787
- children: /* @__PURE__ */ jsx32(Plus2, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
19427
+ children: /* @__PURE__ */ jsx33(Plus2, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
18788
19428
  }
18789
19429
  ) }),
18790
- /* @__PURE__ */ jsx32(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
19430
+ /* @__PURE__ */ jsx33(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
18791
19431
  ] })
18792
19432
  }
18793
19433
  ) });
18794
19434
  }
18795
19435
 
18796
19436
  // src/lib/carousel.ts
18797
- import { useEffect as useEffect14, useState as useState15 } from "react";
19437
+ import { useEffect as useEffect15, useState as useState16 } from "react";
18798
19438
  var CAROUSEL_ATTR = "data-ohw-carousel";
18799
19439
  var CAROUSEL_VALUE_ATTR = "data-ohw-carousel-value";
18800
19440
  var CAROUSEL_SLIDE_ATTR = "data-ohw-carousel-slide";
@@ -18856,8 +19496,8 @@ function applyCarouselNode(key, val) {
18856
19496
  return true;
18857
19497
  }
18858
19498
  function useOhwCarousel(key, initial) {
18859
- const [images, setImages] = useState15(initial);
18860
- useEffect14(() => {
19499
+ const [images, setImages] = useState16(initial);
19500
+ useEffect15(() => {
18861
19501
  const el = document.querySelector(
18862
19502
  `[${CAROUSEL_ATTR}][data-ohw-key="${CSS.escape(key)}"]`
18863
19503
  );
@@ -19277,13 +19917,13 @@ function deleteSelectedNavFooterItem(deps) {
19277
19917
 
19278
19918
  // src/ui/navbar-container-chrome.tsx
19279
19919
  import { Plus as Plus3 } from "lucide-react";
19280
- import { jsx as jsx33 } from "react/jsx-runtime";
19920
+ import { jsx as jsx34 } from "react/jsx-runtime";
19281
19921
  function NavbarContainerChrome({
19282
19922
  rect,
19283
19923
  onAdd
19284
19924
  }) {
19285
19925
  const chromeGap = 6;
19286
- return /* @__PURE__ */ jsx33(
19926
+ return /* @__PURE__ */ jsx34(
19287
19927
  "div",
19288
19928
  {
19289
19929
  "data-ohw-navbar-container-chrome": "",
@@ -19295,7 +19935,7 @@ function NavbarContainerChrome({
19295
19935
  width: rect.width + chromeGap * 2,
19296
19936
  height: rect.height + chromeGap * 2
19297
19937
  },
19298
- children: /* @__PURE__ */ jsx33(
19938
+ children: /* @__PURE__ */ jsx34(
19299
19939
  "button",
19300
19940
  {
19301
19941
  type: "button",
@@ -19312,7 +19952,7 @@ function NavbarContainerChrome({
19312
19952
  e.stopPropagation();
19313
19953
  onAdd();
19314
19954
  },
19315
- children: /* @__PURE__ */ jsx33(Plus3, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
19955
+ children: /* @__PURE__ */ jsx34(Plus3, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
19316
19956
  }
19317
19957
  )
19318
19958
  }
@@ -19321,7 +19961,7 @@ function NavbarContainerChrome({
19321
19961
 
19322
19962
  // src/ui/drop-indicator.tsx
19323
19963
  import * as React11 from "react";
19324
- import { jsx as jsx34 } from "react/jsx-runtime";
19964
+ import { jsx as jsx35 } from "react/jsx-runtime";
19325
19965
  var dropIndicatorVariants = cva(
19326
19966
  "ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
19327
19967
  {
@@ -19345,7 +19985,7 @@ var dropIndicatorVariants = cva(
19345
19985
  );
19346
19986
  var DropIndicator = React11.forwardRef(
19347
19987
  ({ className, direction, state, ...props }, ref) => {
19348
- return /* @__PURE__ */ jsx34(
19988
+ return /* @__PURE__ */ jsx35(
19349
19989
  "div",
19350
19990
  {
19351
19991
  ref,
@@ -19362,7 +20002,7 @@ var DropIndicator = React11.forwardRef(
19362
20002
  DropIndicator.displayName = "DropIndicator";
19363
20003
 
19364
20004
  // src/ui/badge.tsx
19365
- import { jsx as jsx35 } from "react/jsx-runtime";
20005
+ import { jsx as jsx36 } from "react/jsx-runtime";
19366
20006
  var badgeVariants = cva(
19367
20007
  "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
19368
20008
  {
@@ -19380,13 +20020,13 @@ var badgeVariants = cva(
19380
20020
  }
19381
20021
  );
19382
20022
  function Badge({ className, variant, ...props }) {
19383
- return /* @__PURE__ */ jsx35("div", { className: cn(badgeVariants({ variant }), className), ...props });
20023
+ return /* @__PURE__ */ jsx36("div", { className: cn(badgeVariants({ variant }), className), ...props });
19384
20024
  }
19385
20025
 
19386
20026
  // src/OhhwellsBridge.tsx
19387
20027
  import { Brush as Brush2, Link as Link2, Plus as Plus4, Settings } from "lucide-react";
19388
- import { Fragment as Fragment10, jsx as jsx36, jsxs as jsxs23 } from "react/jsx-runtime";
19389
- var PRIMARY5 = "#0885FE";
20028
+ import { Fragment as Fragment11, jsx as jsx37, jsxs as jsxs24 } from "react/jsx-runtime";
20029
+ var PRIMARY6 = "#0885FE";
19390
20030
  var IMAGE_FADE_MS = 300;
19391
20031
  var MEDIA_SETTLE_TIMEOUT_MS = 2500;
19392
20032
  function runOpacityFade(el, onDone) {
@@ -19507,7 +20147,7 @@ function duplicateSchedulingWidget(instanceId, scheduleId) {
19507
20147
  schedulingRoots.set(container, root);
19508
20148
  flushSync2(() => {
19509
20149
  root.render(
19510
- /* @__PURE__ */ jsx36(
20150
+ /* @__PURE__ */ jsx37(
19511
20151
  SchedulingWidget,
19512
20152
  {
19513
20153
  notifyOnConnect: false,
@@ -19550,21 +20190,10 @@ function parseSchedulingInsertAfter(insertAfter) {
19550
20190
  insertBefore: insertAfter.slice(idx + INSERT_BEFORE_MARKER.length)
19551
20191
  };
19552
20192
  }
19553
- function resolveSchedulingInsert(insertAfter, explicitInsertBefore) {
19554
- const parsed = parseSchedulingInsertAfter(insertAfter);
19555
- const insertBefore = explicitInsertBefore ?? parsed.insertBefore;
19556
- const effectiveInsertAfter = insertBefore && parsed.insertBefore === null ? `${insertAfter}${INSERT_BEFORE_MARKER}${insertBefore}` : insertAfter;
19557
- return { effectiveInsertAfter, insertBefore };
19558
- }
19559
- function getSchedulingMountPoint(insertAfter) {
19560
- const { anchor } = parseSchedulingInsertAfter(insertAfter);
19561
- let anchorEl = document.querySelector(`[data-ohw-section="${anchor}"]`);
19562
- if (!anchorEl && anchor === "scheduling") {
19563
- const widgets = Array.from(document.querySelectorAll('[data-ohw-section^="scheduling-"]'));
19564
- anchorEl = widgets.at(-1) ?? null;
19565
- }
19566
- if (!anchorEl) return null;
19567
- return anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
20193
+ function resolveEntryAnchor(entry) {
20194
+ if (entry.anchorId !== void 0) return { anchorId: entry.anchorId, beforeId: entry.beforeId ?? null };
20195
+ const parsed = parseSchedulingInsertAfter(entry.insertAfter);
20196
+ return { anchorId: parsed.anchor, beforeId: parsed.insertBefore };
19568
20197
  }
19569
20198
  function schedulingMountDepth(insertAfter) {
19570
20199
  if (!insertAfter.includes(INSERT_BEFORE_MARKER)) return 0;
@@ -19581,8 +20210,7 @@ function getPageSchedulingEntries(raw) {
19581
20210
  }
19582
20211
  }
19583
20212
  function isSchedulingWidgetMissing(entry) {
19584
- const { effectiveInsertAfter } = resolveSchedulingInsert(entry.insertAfter);
19585
- return !document.querySelector(`[data-ohw-section="${schedulingSectionId(effectiveInsertAfter)}"]`);
20213
+ return !document.querySelector(`[data-ohw-section="${schedulingSectionId(entry.insertAfter)}"]`);
19586
20214
  }
19587
20215
  function hasMissingSchedulingWidgets(entries) {
19588
20216
  return entries.some(isSchedulingWidgetMissing);
@@ -19620,17 +20248,18 @@ function initSectionsFromContent(content, removeExisting = false, currentPath =
19620
20248
  } catch {
19621
20249
  }
19622
20250
  }
19623
- function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId, explicitInsertBefore) {
19624
- const { effectiveInsertAfter, insertBefore } = resolveSchedulingInsert(insertAfter, explicitInsertBefore);
19625
- const sectionId = schedulingSectionId(effectiveInsertAfter);
20251
+ function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, beforeId, existingWidgetId) {
20252
+ const widgetId = existingWidgetId ?? (beforeId ? `${anchorId}${INSERT_BEFORE_MARKER}${beforeId}` : anchorId);
20253
+ const sectionId = schedulingSectionId(widgetId);
19626
20254
  if (document.querySelector(`[data-ohw-section="${sectionId}"]`)) return false;
19627
- const mountPoint = getSchedulingMountPoint(effectiveInsertAfter);
19628
- if (!mountPoint) return false;
20255
+ const anchorEl = document.querySelector(`[data-ohw-section="${anchorId}"]`);
20256
+ if (!anchorEl) return false;
20257
+ const mountPoint = anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
19629
20258
  const container = document.createElement("div");
19630
20259
  container.dataset.ohwSectionContainer = "scheduling";
19631
20260
  container.dataset.ohwInstance = sectionId;
19632
- if (insertBefore) {
19633
- const beforeAnchor = document.querySelector(`[data-ohw-section="${insertBefore}"]`);
20261
+ if (beforeId) {
20262
+ const beforeAnchor = document.querySelector(`[data-ohw-section="${beforeId}"]`);
19634
20263
  const beforePoint = beforeAnchor?.closest('[data-ohw-section-container="scheduling"]') ?? beforeAnchor;
19635
20264
  if (!beforePoint) return false;
19636
20265
  beforePoint.insertAdjacentElement("beforebegin", container);
@@ -19641,20 +20270,26 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
19641
20270
  }
19642
20271
  tail.insertAdjacentElement("afterend", container);
19643
20272
  }
19644
- const root = createRoot2(container);
19645
- schedulingRoots.set(container, root);
19646
- flushSync2(() => {
19647
- root.render(
19648
- /* @__PURE__ */ jsx36(
19649
- SchedulingWidget,
19650
- {
19651
- notifyOnConnect,
19652
- initialScheduleId: scheduleId,
19653
- insertAfter: effectiveInsertAfter
19654
- }
19655
- )
19656
- );
19657
- });
20273
+ try {
20274
+ const root = createRoot2(container);
20275
+ schedulingRoots.set(container, root);
20276
+ flushSync2(() => {
20277
+ root.render(
20278
+ /* @__PURE__ */ jsx37(
20279
+ SchedulingWidget,
20280
+ {
20281
+ notifyOnConnect,
20282
+ initialScheduleId: scheduleId,
20283
+ insertAfter: widgetId
20284
+ }
20285
+ )
20286
+ );
20287
+ });
20288
+ } catch (err) {
20289
+ console.error("[ow:scheduling] render threw", err);
20290
+ container.remove();
20291
+ return false;
20292
+ }
19658
20293
  const tracker = getSectionsTracker();
19659
20294
  let sections = [];
19660
20295
  try {
@@ -19662,10 +20297,12 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
19662
20297
  } catch {
19663
20298
  }
19664
20299
  const inEditor = typeof window !== "undefined" && window.self !== window.top;
19665
- if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter === effectiveInsertAfter)) {
20300
+ if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter === widgetId)) {
19666
20301
  sections.push({
19667
20302
  type: "scheduling",
19668
- insertAfter: effectiveInsertAfter,
20303
+ insertAfter: widgetId,
20304
+ anchorId,
20305
+ beforeId: beforeId ?? null,
19669
20306
  pagePath: window.location.pathname,
19670
20307
  ...scheduleId ? { scheduleId } : {}
19671
20308
  });
@@ -19679,7 +20316,8 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
19679
20316
  for (let i = pending.length - 1; i >= 0; i--) {
19680
20317
  const entry = pending[i];
19681
20318
  const shouldNotify = typeof notifyOnConnect === "function" ? notifyOnConnect(entry) : notifyOnConnect;
19682
- if (mountSchedulingWidget(entry.insertAfter, shouldNotify, entry.scheduleId ?? null)) {
20319
+ const { anchorId, beforeId } = resolveEntryAnchor(entry);
20320
+ if (mountSchedulingWidget(anchorId, shouldNotify, entry.scheduleId ?? null, beforeId, entry.insertAfter)) {
19683
20321
  pending.splice(i, 1);
19684
20322
  }
19685
20323
  }
@@ -20146,7 +20784,7 @@ function getNavigationSelectionParent(el) {
20146
20784
  if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
20147
20785
  return getFooterLinksContainer();
20148
20786
  }
20149
- if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
20787
+ if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isFooterLinksContainer(el) || isInferredFooterGroup2(el)) {
20150
20788
  return getNavigationRoot(el);
20151
20789
  }
20152
20790
  return null;
@@ -20368,13 +21006,12 @@ var ICONS = {
20368
21006
  insertUnorderedList: '<line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/>',
20369
21007
  insertOrderedList: '<line x1="10" y1="6" x2="21" y2="6"/><line x1="10" y1="12" x2="21" y2="12"/><line x1="10" y1="18" x2="21" y2="18"/><path d="M4 6h1v4"/><path d="M4 10h2"/><path d="M6 18H4c0-1 2-2 2-3s-1-1.5-2-1"/>'
20370
21008
  };
20371
- var HEIGHT_SETTLE_DELAYS = [150, 400, 800];
20372
21009
  var SELECTION_CHROME_GAP2 = 4;
20373
21010
  var TOOLBAR_STROKE_GAP2 = 4;
20374
21011
  var TOOLBAR_OFFSET_FROM_ELEMENT = SELECTION_CHROME_GAP2 + TOOLBAR_STROKE_GAP2;
20375
21012
  var HOVER_STROKE_WIDTH = 1.5;
20376
21013
  var TEXT_HOVER_SIDE_PAD = 4;
20377
- var CHROME_PRIMARY = `var(--ohw-primary, ${PRIMARY5})`;
21014
+ var CHROME_PRIMARY = `var(--ohw-primary, ${PRIMARY6})`;
20378
21015
  var TOOLBAR_GROUPS = [
20379
21016
  [
20380
21017
  { cmd: "bold", title: "Bold" },
@@ -20400,7 +21037,7 @@ function EditGlowChrome({
20400
21037
  hideHandle = false
20401
21038
  }) {
20402
21039
  const GAP = SELECTION_CHROME_GAP2;
20403
- return /* @__PURE__ */ jsxs23(
21040
+ return /* @__PURE__ */ jsxs24(
20404
21041
  "div",
20405
21042
  {
20406
21043
  ref: elRef,
@@ -20415,7 +21052,7 @@ function EditGlowChrome({
20415
21052
  zIndex: 2147483646
20416
21053
  },
20417
21054
  children: [
20418
- /* @__PURE__ */ jsx36(
21055
+ /* @__PURE__ */ jsx37(
20419
21056
  "div",
20420
21057
  {
20421
21058
  style: {
@@ -20429,7 +21066,7 @@ function EditGlowChrome({
20429
21066
  }
20430
21067
  }
20431
21068
  ),
20432
- reorderHrefKey && !hideHandle && /* @__PURE__ */ jsx36(
21069
+ reorderHrefKey && !hideHandle && /* @__PURE__ */ jsx37(
20433
21070
  "div",
20434
21071
  {
20435
21072
  "data-ohw-drag-handle-container": "",
@@ -20441,7 +21078,7 @@ function EditGlowChrome({
20441
21078
  transform: "translate(calc(-100% - 7px), -50%)",
20442
21079
  pointerEvents: dragDisabled ? "none" : "auto"
20443
21080
  },
20444
- children: /* @__PURE__ */ jsx36(
21081
+ children: /* @__PURE__ */ jsx37(
20445
21082
  DragHandle,
20446
21083
  {
20447
21084
  "aria-label": `Reorder ${reorderHrefKey}`,
@@ -20645,7 +21282,7 @@ function FloatingToolbar({
20645
21282
  return () => ro.disconnect();
20646
21283
  }, [showEditLink, activeCommands]);
20647
21284
  const { top, left, transform } = calcToolbarPos(rect, parentScroll, measuredW);
20648
- return /* @__PURE__ */ jsx36(
21285
+ return /* @__PURE__ */ jsx37(
20649
21286
  "div",
20650
21287
  {
20651
21288
  ref: setRefs,
@@ -20657,12 +21294,12 @@ function FloatingToolbar({
20657
21294
  zIndex: 2147483647,
20658
21295
  pointerEvents: "auto"
20659
21296
  },
20660
- children: /* @__PURE__ */ jsxs23(CustomToolbar, { children: [
20661
- TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ jsxs23(React12.Fragment, { children: [
20662
- gi > 0 && /* @__PURE__ */ jsx36(CustomToolbarDivider, {}),
21297
+ children: /* @__PURE__ */ jsxs24(CustomToolbar, { children: [
21298
+ TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ jsxs24(React12.Fragment, { children: [
21299
+ gi > 0 && /* @__PURE__ */ jsx37(CustomToolbarDivider, {}),
20663
21300
  btns.map((btn) => {
20664
21301
  const isActive = activeCommands.has(btn.cmd);
20665
- return /* @__PURE__ */ jsx36(
21302
+ return /* @__PURE__ */ jsx37(
20666
21303
  CustomToolbarButton,
20667
21304
  {
20668
21305
  title: btn.title,
@@ -20671,7 +21308,7 @@ function FloatingToolbar({
20671
21308
  e.preventDefault();
20672
21309
  onCommand(btn.cmd);
20673
21310
  },
20674
- children: /* @__PURE__ */ jsx36(
21311
+ children: /* @__PURE__ */ jsx37(
20675
21312
  "svg",
20676
21313
  {
20677
21314
  width: "16",
@@ -20692,7 +21329,7 @@ function FloatingToolbar({
20692
21329
  );
20693
21330
  })
20694
21331
  ] }, gi)),
20695
- showEditLink ? /* @__PURE__ */ jsx36(
21332
+ showEditLink ? /* @__PURE__ */ jsx37(
20696
21333
  CustomToolbarButton,
20697
21334
  {
20698
21335
  type: "button",
@@ -20706,7 +21343,7 @@ function FloatingToolbar({
20706
21343
  e.preventDefault();
20707
21344
  e.stopPropagation();
20708
21345
  },
20709
- children: /* @__PURE__ */ jsx36(Link2, { className: "size-4 shrink-0", "aria-hidden": true })
21346
+ children: /* @__PURE__ */ jsx37(Link2, { className: "size-4 shrink-0", "aria-hidden": true })
20710
21347
  }
20711
21348
  ) : null
20712
21349
  ] })
@@ -20723,7 +21360,7 @@ function StateToggle({
20723
21360
  states,
20724
21361
  onStateChange
20725
21362
  }) {
20726
- return /* @__PURE__ */ jsx36(
21363
+ return /* @__PURE__ */ jsx37(
20727
21364
  ToggleGroup,
20728
21365
  {
20729
21366
  "data-ohw-state-toggle": "",
@@ -20737,11 +21374,12 @@ function StateToggle({
20737
21374
  left: rect.right - 8,
20738
21375
  transform: "translateX(-100%)"
20739
21376
  },
20740
- children: states.map((state) => /* @__PURE__ */ jsx36(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
21377
+ children: states.map((state) => /* @__PURE__ */ jsx37(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
20741
21378
  }
20742
21379
  );
20743
21380
  }
20744
21381
  var contentCache = /* @__PURE__ */ new Map();
21382
+ var fetchedContentPaths = /* @__PURE__ */ new Set();
20745
21383
  var brandingCache = /* @__PURE__ */ new Map();
20746
21384
  var OHW_LOADER_STYLE = {
20747
21385
  position: "fixed",
@@ -20753,9 +21391,9 @@ var OHW_LOADER_STYLE = {
20753
21391
  justifyContent: "center"
20754
21392
  };
20755
21393
  function OhwLoaderSpinner() {
20756
- return /* @__PURE__ */ jsxs23("svg", { width: "28", height: "28", viewBox: "0 0 28 28", fill: "none", "aria-hidden": true, children: [
20757
- /* @__PURE__ */ jsx36("circle", { cx: "14", cy: "14", r: "11", stroke: "#E7E5E4", strokeWidth: "3" }),
20758
- /* @__PURE__ */ jsx36(
21394
+ return /* @__PURE__ */ jsxs24("svg", { width: "28", height: "28", viewBox: "0 0 28 28", fill: "none", "aria-hidden": true, children: [
21395
+ /* @__PURE__ */ jsx37("circle", { cx: "14", cy: "14", r: "11", stroke: "#E7E5E4", strokeWidth: "3" }),
21396
+ /* @__PURE__ */ jsx37(
20759
21397
  "circle",
20760
21398
  {
20761
21399
  cx: "14",
@@ -20765,7 +21403,7 @@ function OhwLoaderSpinner() {
20765
21403
  strokeWidth: "3",
20766
21404
  strokeDasharray: "17 52",
20767
21405
  strokeLinecap: "round",
20768
- children: /* @__PURE__ */ jsx36(
21406
+ children: /* @__PURE__ */ jsx37(
20769
21407
  "animateTransform",
20770
21408
  {
20771
21409
  attributeName: "transform",
@@ -20781,7 +21419,7 @@ function OhwLoaderSpinner() {
20781
21419
  ] });
20782
21420
  }
20783
21421
  function OhwBrandMark() {
20784
- return /* @__PURE__ */ jsxs23(
21422
+ return /* @__PURE__ */ jsxs24(
20785
21423
  "svg",
20786
21424
  {
20787
21425
  width: "16",
@@ -20792,7 +21430,7 @@ function OhwBrandMark() {
20792
21430
  style: { display: "block", flexShrink: 0 },
20793
21431
  xmlns: "http://www.w3.org/2000/svg",
20794
21432
  children: [
20795
- /* @__PURE__ */ jsx36(
21433
+ /* @__PURE__ */ jsx37(
20796
21434
  "mask",
20797
21435
  {
20798
21436
  id: "ohw-badge-mark",
@@ -20802,15 +21440,15 @@ function OhwBrandMark() {
20802
21440
  y: "0",
20803
21441
  width: "48",
20804
21442
  height: "48",
20805
- children: /* @__PURE__ */ jsx36("path", { d: "M23.8741 48C37.0594 48 47.7481 37.2548 47.7481 24C47.7481 10.7452 37.0594 0 23.8741 0C10.6888 0 0 10.7452 0 24C0 37.2548 10.6888 48 23.8741 48Z", fill: "white" })
21443
+ children: /* @__PURE__ */ jsx37("path", { d: "M23.8741 48C37.0594 48 47.7481 37.2548 47.7481 24C47.7481 10.7452 37.0594 0 23.8741 0C10.6888 0 0 10.7452 0 24C0 37.2548 10.6888 48 23.8741 48Z", fill: "white" })
20806
21444
  }
20807
21445
  ),
20808
- /* @__PURE__ */ jsxs23("g", { mask: "url(#ohw-badge-mark)", children: [
20809
- /* @__PURE__ */ jsx36("path", { d: "M23.8731 48.0497C37.0584 48.0497 47.7472 37.3046 47.7472 24.0497C47.7472 10.7949 37.0584 0.0497208 23.8731 0.0497208C10.6878 0.0497208 -0.000976562 10.7949 -0.000976562 24.0497C-0.000976562 37.3046 10.6878 48.0497 23.8731 48.0497Z", fill: "#0078E5" }),
20810
- /* @__PURE__ */ jsx36("path", { d: "M17.1307 14.7172C13.1687 14.7172 9.38102 18.1154 8.65114 22.34C8.38885 23.8488 8.5598 25.2581 9.06929 26.4451C6.20005 29.1677 1.77216 27.8721 -1.40212 26.1536C-2.73618 25.4317 -3.92695 27.4745 -2.59037 28.1981C1.33389 30.3226 6.86037 31.6621 10.4402 28.4188C11.4718 29.3859 12.867 29.9621 14.4894 29.9621C18.4161 29.9621 22.2038 26.5318 22.9337 22.34C23.6636 18.1162 21.0566 14.7172 17.1298 14.7172H17.1307ZM19.9798 22.34C19.5281 25.0399 17.2689 27.231 14.9754 27.231C12.6466 27.231 11.1877 25.0399 11.6394 22.34C12.1262 19.6401 14.3151 17.4482 16.6438 17.4482C18.9374 17.4482 20.4667 19.6401 19.9798 22.34Z", fill: "white" }),
20811
- /* @__PURE__ */ jsx36("path", { d: "M40.0017 27.0262C39.1797 27.081 38.2721 26.995 37.4668 26.7415C37.3344 26.6993 37.28 26.5401 37.3529 26.4205C37.5959 26.0212 37.8255 25.6152 38.009 25.1889C38.1071 24.9918 38.2018 24.793 38.2897 24.5908C38.3274 24.5041 38.4163 24.451 38.5101 24.4619C38.63 24.4754 38.7054 24.4821 38.8881 24.4821L39.1529 24.4796L39.8283 24.4543C45.9229 24.0492 50.4765 20.4319 54.8466 16.9014C56.0172 15.9554 57.6932 17.6208 56.5116 18.5752C51.7687 22.4065 47.1966 26.5081 40.9319 26.9689", fill: "white" }),
20812
- /* @__PURE__ */ jsx36("path", { d: "M37.9687 24.27C38.4472 23.1319 38.7656 21.9045 38.9609 20.6991C39.5927 16.76 38.5058 14.2193 36.1553 14.2193C34.1835 14.2193 33.1469 17.2427 32.9199 18.8694C32.743 19.9872 32.5914 22.1219 33.6028 23.9524C33.7553 24.259 34.15 24.7712 34.471 25.1259C34.5447 25.2067 34.6746 25.2 34.7349 25.1082C34.9528 24.7788 35.1615 24.4039 35.3584 24.0257C35.5444 23.6677 35.5888 23.6138 35.8587 23.0207C35.8838 22.966 35.8813 22.9002 35.8478 22.8505C35.5888 22.4597 35.2168 21.9787 35.1204 21.4614C34.9184 20.4455 34.9436 19.2257 35.2218 18.1078C35.4413 17.3118 35.7195 16.7844 35.9039 16.5106C35.9466 16.4466 36.0279 16.4129 36.0975 16.4449C36.369 16.5671 36.5827 16.8838 36.7385 17.396C37.0167 18.2089 37.0167 19.3782 36.814 20.6999C36.6991 21.5271 36.4771 22.3729 36.1746 23.1673C36.1293 23.308 36.0757 23.4461 36.0187 23.5826C36.0187 23.5868 36.0187 23.591 36.0187 23.5961C35.9911 23.6946 35.9207 23.8067 35.8846 23.901C35.5536 24.5497 35.2344 25.1697 34.8439 25.7838C34.8388 25.7863 34.8346 25.7914 34.8296 25.7931C34.6528 26.0525 34.4718 26.2901 34.2866 26.4965C34.2774 26.5099 34.2682 26.5234 34.2589 26.5369C34.2405 26.5638 34.2179 26.5815 34.1944 26.595C33.5064 27.3212 32.7665 27.6893 32.0123 27.6893C31.8606 27.6893 31.6838 27.664 31.507 27.4349C31.3042 27.1299 30.85 26.0879 31.2539 22.9112C31.4785 21.3949 31.8011 20.0268 31.931 19.5408C31.9579 19.4413 31.8908 19.3419 31.7886 19.3293L30.0062 19.1162C29.9241 19.1061 29.8478 19.1566 29.8252 19.2366C29.2704 21.1615 27.0305 27.6885 24.9599 27.6885C24.328 27.6885 24.1512 26.6211 24.1001 26.2909C23.775 23.6264 25.528 18.5492 29.5302 16.2267C29.6048 16.1838 29.635 16.0928 29.5998 16.0136L28.9042 14.467C28.8632 14.3752 28.7501 14.3389 28.6638 14.3886C25.8079 16.0414 24.1847 18.5231 23.2915 20.3436C22.2046 22.5793 21.6993 25.0189 21.9515 26.8738C22.1795 28.7794 23.1398 29.872 24.6054 29.872C26.0543 29.872 27.4369 28.9066 28.7098 27.0187C28.7953 26.8915 28.9889 26.9311 29.0149 27.0819C29.2646 28.5283 29.9811 29.872 31.6579 29.872C33.5282 29.872 35.3232 28.7288 36.7134 26.6447C36.7712 26.5874 36.7972 26.5411 36.8181 26.4906C36.8232 26.4931 36.8282 26.4948 36.8332 26.4973C37.01 26.2025 37.181 25.9051 37.3444 25.6027C37.4508 25.4005 37.5572 25.1992 37.6586 24.9945C37.7181 24.874 37.7743 24.7527 37.8262 24.6289C37.838 24.6002 37.8547 24.5665 37.8706 24.5337", fill: "white" }),
20813
- /* @__PURE__ */ jsx36("path", { d: "M30.5839 31.6397C25.7546 34.8577 19.4773 34.7853 14.6907 31.5243C13.5368 30.7384 12.5044 32.6498 13.6474 33.4281C19.034 37.0985 26.3077 37.096 31.7218 33.488C32.8791 32.7172 31.7478 30.8639 30.5839 31.6397Z", fill: "white" })
21446
+ /* @__PURE__ */ jsxs24("g", { mask: "url(#ohw-badge-mark)", children: [
21447
+ /* @__PURE__ */ jsx37("path", { d: "M23.8731 48.0497C37.0584 48.0497 47.7472 37.3046 47.7472 24.0497C47.7472 10.7949 37.0584 0.0497208 23.8731 0.0497208C10.6878 0.0497208 -0.000976562 10.7949 -0.000976562 24.0497C-0.000976562 37.3046 10.6878 48.0497 23.8731 48.0497Z", fill: "#0078E5" }),
21448
+ /* @__PURE__ */ jsx37("path", { d: "M17.1307 14.7172C13.1687 14.7172 9.38102 18.1154 8.65114 22.34C8.38885 23.8488 8.5598 25.2581 9.06929 26.4451C6.20005 29.1677 1.77216 27.8721 -1.40212 26.1536C-2.73618 25.4317 -3.92695 27.4745 -2.59037 28.1981C1.33389 30.3226 6.86037 31.6621 10.4402 28.4188C11.4718 29.3859 12.867 29.9621 14.4894 29.9621C18.4161 29.9621 22.2038 26.5318 22.9337 22.34C23.6636 18.1162 21.0566 14.7172 17.1298 14.7172H17.1307ZM19.9798 22.34C19.5281 25.0399 17.2689 27.231 14.9754 27.231C12.6466 27.231 11.1877 25.0399 11.6394 22.34C12.1262 19.6401 14.3151 17.4482 16.6438 17.4482C18.9374 17.4482 20.4667 19.6401 19.9798 22.34Z", fill: "white" }),
21449
+ /* @__PURE__ */ jsx37("path", { d: "M40.0017 27.0262C39.1797 27.081 38.2721 26.995 37.4668 26.7415C37.3344 26.6993 37.28 26.5401 37.3529 26.4205C37.5959 26.0212 37.8255 25.6152 38.009 25.1889C38.1071 24.9918 38.2018 24.793 38.2897 24.5908C38.3274 24.5041 38.4163 24.451 38.5101 24.4619C38.63 24.4754 38.7054 24.4821 38.8881 24.4821L39.1529 24.4796L39.8283 24.4543C45.9229 24.0492 50.4765 20.4319 54.8466 16.9014C56.0172 15.9554 57.6932 17.6208 56.5116 18.5752C51.7687 22.4065 47.1966 26.5081 40.9319 26.9689", fill: "white" }),
21450
+ /* @__PURE__ */ jsx37("path", { d: "M37.9687 24.27C38.4472 23.1319 38.7656 21.9045 38.9609 20.6991C39.5927 16.76 38.5058 14.2193 36.1553 14.2193C34.1835 14.2193 33.1469 17.2427 32.9199 18.8694C32.743 19.9872 32.5914 22.1219 33.6028 23.9524C33.7553 24.259 34.15 24.7712 34.471 25.1259C34.5447 25.2067 34.6746 25.2 34.7349 25.1082C34.9528 24.7788 35.1615 24.4039 35.3584 24.0257C35.5444 23.6677 35.5888 23.6138 35.8587 23.0207C35.8838 22.966 35.8813 22.9002 35.8478 22.8505C35.5888 22.4597 35.2168 21.9787 35.1204 21.4614C34.9184 20.4455 34.9436 19.2257 35.2218 18.1078C35.4413 17.3118 35.7195 16.7844 35.9039 16.5106C35.9466 16.4466 36.0279 16.4129 36.0975 16.4449C36.369 16.5671 36.5827 16.8838 36.7385 17.396C37.0167 18.2089 37.0167 19.3782 36.814 20.6999C36.6991 21.5271 36.4771 22.3729 36.1746 23.1673C36.1293 23.308 36.0757 23.4461 36.0187 23.5826C36.0187 23.5868 36.0187 23.591 36.0187 23.5961C35.9911 23.6946 35.9207 23.8067 35.8846 23.901C35.5536 24.5497 35.2344 25.1697 34.8439 25.7838C34.8388 25.7863 34.8346 25.7914 34.8296 25.7931C34.6528 26.0525 34.4718 26.2901 34.2866 26.4965C34.2774 26.5099 34.2682 26.5234 34.2589 26.5369C34.2405 26.5638 34.2179 26.5815 34.1944 26.595C33.5064 27.3212 32.7665 27.6893 32.0123 27.6893C31.8606 27.6893 31.6838 27.664 31.507 27.4349C31.3042 27.1299 30.85 26.0879 31.2539 22.9112C31.4785 21.3949 31.8011 20.0268 31.931 19.5408C31.9579 19.4413 31.8908 19.3419 31.7886 19.3293L30.0062 19.1162C29.9241 19.1061 29.8478 19.1566 29.8252 19.2366C29.2704 21.1615 27.0305 27.6885 24.9599 27.6885C24.328 27.6885 24.1512 26.6211 24.1001 26.2909C23.775 23.6264 25.528 18.5492 29.5302 16.2267C29.6048 16.1838 29.635 16.0928 29.5998 16.0136L28.9042 14.467C28.8632 14.3752 28.7501 14.3389 28.6638 14.3886C25.8079 16.0414 24.1847 18.5231 23.2915 20.3436C22.2046 22.5793 21.6993 25.0189 21.9515 26.8738C22.1795 28.7794 23.1398 29.872 24.6054 29.872C26.0543 29.872 27.4369 28.9066 28.7098 27.0187C28.7953 26.8915 28.9889 26.9311 29.0149 27.0819C29.2646 28.5283 29.9811 29.872 31.6579 29.872C33.5282 29.872 35.3232 28.7288 36.7134 26.6447C36.7712 26.5874 36.7972 26.5411 36.8181 26.4906C36.8232 26.4931 36.8282 26.4948 36.8332 26.4973C37.01 26.2025 37.181 25.9051 37.3444 25.6027C37.4508 25.4005 37.5572 25.1992 37.6586 24.9945C37.7181 24.874 37.7743 24.7527 37.8262 24.6289C37.838 24.6002 37.8547 24.5665 37.8706 24.5337", fill: "white" }),
21451
+ /* @__PURE__ */ jsx37("path", { d: "M30.5839 31.6397C25.7546 34.8577 19.4773 34.7853 14.6907 31.5243C13.5368 30.7384 12.5044 32.6498 13.6474 33.4281C19.034 37.0985 26.3077 37.096 31.7218 33.488C32.8791 32.7172 31.7478 30.8639 30.5839 31.6397Z", fill: "white" })
20814
21452
  ] })
20815
21453
  ]
20816
21454
  }
@@ -20847,7 +21485,7 @@ var OHW_BADGE_LABEL_STYLE = {
20847
21485
  whiteSpace: "nowrap"
20848
21486
  };
20849
21487
  function MadeWithOhhWells() {
20850
- return /* @__PURE__ */ jsxs23(
21488
+ return /* @__PURE__ */ jsxs24(
20851
21489
  "a",
20852
21490
  {
20853
21491
  href: "https://ohhwells.com",
@@ -20857,8 +21495,8 @@ function MadeWithOhhWells() {
20857
21495
  "data-ohw-badge": "",
20858
21496
  style: OHW_BADGE_STYLE,
20859
21497
  children: [
20860
- /* @__PURE__ */ jsx36(OhwBrandMark, {}),
20861
- /* @__PURE__ */ jsx36("span", { style: OHW_BADGE_LABEL_STYLE, children: "Made with OhhWells" })
21498
+ /* @__PURE__ */ jsx37(OhwBrandMark, {}),
21499
+ /* @__PURE__ */ jsx37("span", { style: OHW_BADGE_LABEL_STYLE, children: "Made with OhhWells" })
20862
21500
  ]
20863
21501
  }
20864
21502
  );
@@ -20904,8 +21542,8 @@ function OhhwellsBridge() {
20904
21542
  const router = useRouter3();
20905
21543
  const searchParams = useSearchParams();
20906
21544
  const isEditMode = isEditSessionActive();
20907
- const [bridgeRoot, setBridgeRoot] = useState16(null);
20908
- useEffect15(() => {
21545
+ const [bridgeRoot, setBridgeRoot] = useState17(null);
21546
+ useEffect16(() => {
20909
21547
  const figtreeFontId = "ohw-figtree-font";
20910
21548
  if (!document.getElementById(figtreeFontId)) {
20911
21549
  const preconnect1 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.googleapis.com" });
@@ -20931,7 +21569,7 @@ function OhhwellsBridge() {
20931
21569
  };
20932
21570
  }, []);
20933
21571
  const subdomainFromQuery = searchParams.get("subdomain");
20934
- const [subdomain, setSubdomain] = useState16(() => resolveSubdomain(subdomainFromQuery));
21572
+ const [subdomain, setSubdomain] = useState17(() => resolveSubdomain(subdomainFromQuery));
20935
21573
  useLayoutEffect5(() => {
20936
21574
  const next = resolveSubdomain(subdomainFromQuery);
20937
21575
  if (next !== subdomain) setSubdomain(next);
@@ -20944,54 +21582,55 @@ function OhhwellsBridge() {
20944
21582
  }, 0);
20945
21583
  return () => window.clearTimeout(t);
20946
21584
  }, [subdomainFromQuery, subdomain]);
20947
- useEffect15(() => {
21585
+ useEffect16(() => {
20948
21586
  if (!subdomainFromQuery || typeof window === "undefined") return;
20949
21587
  const url = new URL(window.location.href);
20950
21588
  if (!url.searchParams.has("subdomain")) return;
21589
+ if (!resolveSubdomain(null)) return;
20951
21590
  url.searchParams.delete("subdomain");
20952
21591
  window.history.replaceState(null, "", url.pathname + url.search + url.hash);
20953
21592
  }, [subdomainFromQuery]);
20954
21593
  useLinkHrefGuardian(pathname, subdomain, isEditMode);
20955
21594
  useSavedLinkNavigation(isEditMode);
20956
- const postToParent2 = useCallback10((data) => {
21595
+ const postToParent2 = useCallback11((data) => {
20957
21596
  if (typeof window !== "undefined" && window.parent !== window) {
20958
21597
  window.parent.postMessage(data, "*");
20959
21598
  }
20960
21599
  }, []);
20961
- const [fetchState, setFetchState] = useState16("idle");
20962
- const [showBranding, setShowBranding] = useState16(false);
20963
- const autoSaveTimers = useRef12(/* @__PURE__ */ new Map());
20964
- const activeElRef = useRef12(null);
20965
- const pointerHeldRef = useRef12(false);
20966
- const selectedElRef = useRef12(null);
20967
- const selectedHrefKeyRef = useRef12(null);
20968
- const selectedFooterColAttrRef = useRef12(null);
20969
- const originalContentRef = useRef12(null);
20970
- const activeStateElRef = useRef12(null);
20971
- const parentScrollRef = useRef12(null);
20972
- const visibleViewportRef = useRef12(null);
20973
- const [dialogPortalContainer, setDialogPortalContainer] = useState16(null);
20974
- const attachVisibleViewport = useCallback10((node) => {
21600
+ const [fetchState, setFetchState] = useState17("idle");
21601
+ const [showBranding, setShowBranding] = useState17(false);
21602
+ const autoSaveTimers = useRef13(/* @__PURE__ */ new Map());
21603
+ const activeElRef = useRef13(null);
21604
+ const pointerHeldRef = useRef13(false);
21605
+ const selectedElRef = useRef13(null);
21606
+ const selectedHrefKeyRef = useRef13(null);
21607
+ const selectedFooterColAttrRef = useRef13(null);
21608
+ const originalContentRef = useRef13(null);
21609
+ const activeStateElRef = useRef13(null);
21610
+ const parentScrollRef = useRef13(null);
21611
+ const visibleViewportRef = useRef13(null);
21612
+ const [dialogPortalContainer, setDialogPortalContainer] = useState17(null);
21613
+ const attachVisibleViewport = useCallback11((node) => {
20975
21614
  visibleViewportRef.current = node;
20976
21615
  setDialogPortalContainer(node);
20977
21616
  if (node) applyVisibleViewport(node, parentScrollRef.current);
20978
21617
  }, []);
20979
- const toolbarElRef = useRef12(null);
20980
- const glowElRef = useRef12(null);
20981
- const hoveredImageRef = useRef12(null);
20982
- const hoveredImageHasTextOverlapRef = useRef12(false);
20983
- const dragOverElRef = useRef12(null);
20984
- const [mediaHover, setMediaHover] = useState16(null);
20985
- const [selectedAiSectionId, setSelectedAiSectionId] = useState16(null);
20986
- const selectedAiSectionIdRef = useRef12(null);
20987
- const handleAiSectionSelectionChange = useCallback10((id) => {
21618
+ const toolbarElRef = useRef13(null);
21619
+ const glowElRef = useRef13(null);
21620
+ const hoveredImageRef = useRef13(null);
21621
+ const hoveredImageHasTextOverlapRef = useRef13(false);
21622
+ const dragOverElRef = useRef13(null);
21623
+ const [mediaHover, setMediaHover] = useState17(null);
21624
+ const [selectedAiSectionId, setSelectedAiSectionId] = useState17(null);
21625
+ const selectedAiSectionIdRef = useRef13(null);
21626
+ const handleAiSectionSelectionChange = useCallback11((id) => {
20988
21627
  selectedAiSectionIdRef.current = id;
20989
21628
  setSelectedAiSectionId(id);
20990
21629
  }, []);
20991
- const [selectedMedia, setSelectedMedia] = useState16(null);
20992
- const selectedMediaElRef = useRef12(null);
20993
- const mediaKeyDropTokenRef = useRef12(0);
20994
- const clearMediaSelection = useCallback10(() => {
21630
+ const [selectedMedia, setSelectedMedia] = useState17(null);
21631
+ const selectedMediaElRef = useRef13(null);
21632
+ const mediaKeyDropTokenRef = useRef13(0);
21633
+ const clearMediaSelection = useCallback11(() => {
20995
21634
  const prev = selectedMediaElRef.current;
20996
21635
  selectedMediaElRef.current = null;
20997
21636
  setSelectedMedia(null);
@@ -21016,9 +21655,9 @@ function OhhwellsBridge() {
21016
21655
  window.postMessage({ type: "ow:media-key-drop", token }, "*");
21017
21656
  }
21018
21657
  }, []);
21019
- const clearMediaSelectionRef = useRef12(clearMediaSelection);
21658
+ const clearMediaSelectionRef = useRef13(clearMediaSelection);
21020
21659
  clearMediaSelectionRef.current = clearMediaSelection;
21021
- const selectMediaElement = useCallback10((el) => {
21660
+ const selectMediaElement = useCallback11((el) => {
21022
21661
  const r2 = el.getBoundingClientRect();
21023
21662
  const video = el.dataset.ohwEditable === "video" ? el.querySelector("video") : null;
21024
21663
  selectedMediaElRef.current = el;
@@ -21042,9 +21681,9 @@ function OhhwellsBridge() {
21042
21681
  keyLabel: el.dataset.ohwEditable === "video" ? "Video" : el.dataset.ohwEditable === "bg-image" ? "Background" : "Image"
21043
21682
  });
21044
21683
  }, []);
21045
- const selectMediaElementRef = useRef12(selectMediaElement);
21684
+ const selectMediaElementRef = useRef13(selectMediaElement);
21046
21685
  selectMediaElementRef.current = selectMediaElement;
21047
- useEffect15(() => {
21686
+ useEffect16(() => {
21048
21687
  if (!selectedMedia) return;
21049
21688
  const update = () => {
21050
21689
  const el = selectedMediaElRef.current;
@@ -21064,54 +21703,54 @@ function OhhwellsBridge() {
21064
21703
  window.removeEventListener("resize", update);
21065
21704
  };
21066
21705
  }, [selectedMedia !== null]);
21067
- const [carouselHover, setCarouselHover] = useState16(null);
21068
- const [uploadingRects, setUploadingRects] = useState16({});
21069
- const hoveredGapRef = useRef12(null);
21070
- const imageUnhoverTimerRef = useRef12(null);
21071
- const imageShowTimerRef = useRef12(null);
21072
- const editStylesRef = useRef12(null);
21073
- const activateRef = useRef12(() => {
21706
+ const [carouselHover, setCarouselHover] = useState17(null);
21707
+ const [uploadingRects, setUploadingRects] = useState17({});
21708
+ const hoveredGapRef = useRef13(null);
21709
+ const imageUnhoverTimerRef = useRef13(null);
21710
+ const imageShowTimerRef = useRef13(null);
21711
+ const editStylesRef = useRef13(null);
21712
+ const activateRef = useRef13(() => {
21074
21713
  });
21075
- const deactivateRef = useRef12(() => {
21714
+ const deactivateRef = useRef13(() => {
21076
21715
  });
21077
- const selectRef = useRef12(() => {
21716
+ const selectRef = useRef13(() => {
21078
21717
  });
21079
- const selectFrameRef = useRef12(() => {
21718
+ const selectFrameRef = useRef13(() => {
21080
21719
  });
21081
- const selectLogoRef = useRef12(() => {
21720
+ const selectLogoRef = useRef13(() => {
21082
21721
  });
21083
- const openLogoSizePanelRef = useRef12(() => {
21722
+ const openLogoSizePanelRef = useRef13(() => {
21084
21723
  });
21085
- const deselectRef = useRef12(() => {
21724
+ const deselectRef = useRef13(() => {
21086
21725
  });
21087
- const closeFloatingPanelOnlyRef = useRef12(() => {
21726
+ const closeFloatingPanelOnlyRef = useRef13(() => {
21088
21727
  });
21089
- const reselectNavigationItemRef = useRef12(() => {
21728
+ const reselectNavigationItemRef = useRef13(() => {
21090
21729
  });
21091
- const commitNavigationTextEditRef = useRef12(() => {
21730
+ const commitNavigationTextEditRef = useRef13(() => {
21092
21731
  });
21093
- const handleDeleteSelectedRef = useRef12(() => false);
21094
- const runPendingDeleteUndoRef = useRef12(() => false);
21095
- const isFooterFrameSelectionRef = useRef12(false);
21096
- const refreshActiveCommandsRef = useRef12(() => {
21732
+ const handleDeleteSelectedRef = useRef13(() => false);
21733
+ const runPendingDeleteUndoRef = useRef13(() => false);
21734
+ const isFooterFrameSelectionRef = useRef13(false);
21735
+ const refreshActiveCommandsRef = useRef13(() => {
21097
21736
  });
21098
- const postToParentRef = useRef12(postToParent2);
21737
+ const postToParentRef = useRef13(postToParent2);
21099
21738
  postToParentRef.current = postToParent2;
21100
- const aiSectionApiRef = useRef12(null);
21101
- const sectionsLoadedRef = useRef12(false);
21102
- const pendingScheduleConfigRequests = useRef12([]);
21103
- const [toolbarRect, setToolbarRect] = useState16(null);
21104
- const [formPickRect, setFormPickRect] = useState16(null);
21105
- const formPickElRef = useRef12(null);
21106
- const [formViewState, setFormViewStateUi] = useState16("default");
21107
- const [formPickCount, setFormPickCount] = useState16(null);
21108
- const [formHoverRect, setFormHoverRect] = useState16(null);
21109
- const formHoverElRef = useRef12(null);
21110
- const [fieldPickRect, setFieldPickRect] = useState16(null);
21111
- const fieldPickElRef = useRef12(null);
21112
- const [fieldPickState, setFieldPickState] = useState16(null);
21113
- const [fieldTypePickerOpen, setFieldTypePickerOpen] = useState16(false);
21114
- const clearFormPick = useCallback10(() => {
21739
+ const aiSectionApiRef = useRef13(null);
21740
+ const sectionsLoadedRef = useRef13(false);
21741
+ const pendingScheduleConfigRequests = useRef13([]);
21742
+ const [toolbarRect, setToolbarRect] = useState17(null);
21743
+ const [formPickRect, setFormPickRect] = useState17(null);
21744
+ const formPickElRef = useRef13(null);
21745
+ const [formViewState, setFormViewStateUi] = useState17("default");
21746
+ const [formPickCount, setFormPickCount] = useState17(null);
21747
+ const [formHoverRect, setFormHoverRect] = useState17(null);
21748
+ const formHoverElRef = useRef13(null);
21749
+ const [fieldPickRect, setFieldPickRect] = useState17(null);
21750
+ const fieldPickElRef = useRef13(null);
21751
+ const [fieldPickState, setFieldPickState] = useState17(null);
21752
+ const [fieldTypePickerOpen, setFieldTypePickerOpen] = useState17(false);
21753
+ const clearFormPick = useCallback11(() => {
21115
21754
  const form = formPickElRef.current;
21116
21755
  const editing = fieldPickElRef.current;
21117
21756
  if (commitPlaceholderEdit(editing) && editing) {
@@ -21131,7 +21770,7 @@ function OhhwellsBridge() {
21131
21770
  formPickElRef.current = null;
21132
21771
  setFormPickRect(null);
21133
21772
  }, []);
21134
- const clearFieldPick = useCallback10(() => {
21773
+ const clearFieldPick = useCallback11(() => {
21135
21774
  const wrapper = fieldPickElRef.current;
21136
21775
  if (commitPlaceholderEdit(wrapper) && wrapper) {
21137
21776
  const form = wrapper.closest('[data-ohw-editable="form"]');
@@ -21141,9 +21780,9 @@ function OhhwellsBridge() {
21141
21780
  setFieldPickRect(null);
21142
21781
  setFieldPickState(null);
21143
21782
  }, []);
21144
- const persistFieldsRef = useRef12(() => {
21783
+ const persistFieldsRef = useRef13(() => {
21145
21784
  });
21146
- const persistFields = useCallback10(
21785
+ const persistFields = useCallback11(
21147
21786
  (form) => {
21148
21787
  const key = formKeyOf(form);
21149
21788
  if (!key) return;
@@ -21154,7 +21793,7 @@ function OhhwellsBridge() {
21154
21793
  []
21155
21794
  );
21156
21795
  persistFieldsRef.current = persistFields;
21157
- const selectField = useCallback10((wrapper) => {
21796
+ const selectField = useCallback11((wrapper) => {
21158
21797
  if (fieldPickElRef.current && fieldPickElRef.current !== wrapper) {
21159
21798
  commitPlaceholderEdit(fieldPickElRef.current);
21160
21799
  }
@@ -21167,7 +21806,7 @@ function OhhwellsBridge() {
21167
21806
  setFieldPickState({ type: fieldTypeOf(wrapper), required: isFieldRequired(wrapper) });
21168
21807
  setFieldTypePickerOpen(false);
21169
21808
  }, []);
21170
- const withSelectedField = useCallback10(
21809
+ const withSelectedField = useCallback11(
21171
21810
  (run) => {
21172
21811
  const wrapper = fieldPickElRef.current;
21173
21812
  const form = formPickElRef.current;
@@ -21180,28 +21819,28 @@ function OhhwellsBridge() {
21180
21819
  },
21181
21820
  [persistFields]
21182
21821
  );
21183
- const handleFieldTypeChange = useCallback10(
21822
+ const handleFieldTypeChange = useCallback11(
21184
21823
  (type) => withSelectedField((_form, wrapper) => {
21185
21824
  applyFieldType(wrapper, type);
21186
21825
  selectField(wrapper);
21187
21826
  }),
21188
21827
  [selectField, withSelectedField]
21189
21828
  );
21190
- const handleFieldRequiredToggle = useCallback10(
21829
+ const handleFieldRequiredToggle = useCallback11(
21191
21830
  () => withSelectedField((_form, wrapper) => {
21192
21831
  setFieldRequired(wrapper, !isFieldRequired(wrapper));
21193
21832
  selectField(wrapper);
21194
21833
  }),
21195
21834
  [selectField, withSelectedField]
21196
21835
  );
21197
- const handleFieldDuplicate = useCallback10(
21836
+ const handleFieldDuplicate = useCallback11(
21198
21837
  () => withSelectedField((form, wrapper) => {
21199
21838
  const copy = duplicateField(form, wrapper);
21200
21839
  selectField(copy);
21201
21840
  }),
21202
21841
  [selectField, withSelectedField]
21203
21842
  );
21204
- const handleFieldDelete = useCallback10(
21843
+ const handleFieldDelete = useCallback11(
21205
21844
  () => withSelectedField((_form, wrapper) => {
21206
21845
  removeField(wrapper);
21207
21846
  clearFieldPick();
@@ -21209,7 +21848,7 @@ function OhhwellsBridge() {
21209
21848
  }),
21210
21849
  [clearFieldPick, withSelectedField]
21211
21850
  );
21212
- const handleAddField = useCallback10(
21851
+ const handleAddField = useCallback11(
21213
21852
  (type) => {
21214
21853
  const form = formPickElRef.current;
21215
21854
  if (!form) return;
@@ -21225,8 +21864,8 @@ function OhhwellsBridge() {
21225
21864
  },
21226
21865
  [persistFields, selectField]
21227
21866
  );
21228
- const fieldDragRef = useRef12(null);
21229
- const buildFieldDropSlots = useCallback10((form, draggedKey) => {
21867
+ const fieldDragRef = useRef13(null);
21868
+ const buildFieldDropSlots = useCallback11((form, draggedKey) => {
21230
21869
  const others = listFieldWrappers(form).filter((el) => fieldKeyOf(el) !== draggedKey);
21231
21870
  const slots = others.map((el) => {
21232
21871
  const rect = el.getBoundingClientRect();
@@ -21239,7 +21878,7 @@ function OhhwellsBridge() {
21239
21878
  }
21240
21879
  return slots;
21241
21880
  }, []);
21242
- const handleFieldDragStart = useCallback10(() => {
21881
+ const handleFieldDragStart = useCallback11(() => {
21243
21882
  const wrapper = fieldPickElRef.current;
21244
21883
  const form = formPickElRef.current;
21245
21884
  if (!wrapper || !form) return;
@@ -21248,18 +21887,18 @@ function OhhwellsBridge() {
21248
21887
  setFieldDragging(true);
21249
21888
  setFieldDropSlots(buildFieldDropSlots(form, key));
21250
21889
  }, [buildFieldDropSlots]);
21251
- const handleFieldDragEnd = useCallback10(() => {
21890
+ const handleFieldDragEnd = useCallback11(() => {
21252
21891
  fieldDragRef.current = null;
21253
21892
  setFieldDropIndex(null);
21254
21893
  setFieldDropSlots([]);
21255
21894
  setFieldDragging(false);
21256
21895
  }, []);
21257
- const [fieldDropIndex, setFieldDropIndex] = useState16(null);
21258
- const [fieldDropSlots, setFieldDropSlots] = useState16([]);
21259
- const [fieldDragging, setFieldDragging] = useState16(false);
21260
- const clearFormPickRef = useRef12(clearFormPick);
21896
+ const [fieldDropIndex, setFieldDropIndex] = useState17(null);
21897
+ const [fieldDropSlots, setFieldDropSlots] = useState17([]);
21898
+ const [fieldDragging, setFieldDragging] = useState17(false);
21899
+ const clearFormPickRef = useRef13(clearFormPick);
21261
21900
  clearFormPickRef.current = clearFormPick;
21262
- useEffect15(() => {
21901
+ useEffect16(() => {
21263
21902
  const el = fieldPickElRef.current;
21264
21903
  if (!el || fieldPickRect === null) return;
21265
21904
  const observer = new ResizeObserver(() => {
@@ -21268,7 +21907,7 @@ function OhhwellsBridge() {
21268
21907
  observer.observe(el);
21269
21908
  return () => observer.disconnect();
21270
21909
  }, [fieldPickRect !== null, fieldPickState]);
21271
- useEffect15(() => {
21910
+ useEffect16(() => {
21272
21911
  const el = formPickElRef.current;
21273
21912
  if (!el || formPickRect === null) return;
21274
21913
  const observer = new ResizeObserver(() => {
@@ -21277,25 +21916,25 @@ function OhhwellsBridge() {
21277
21916
  observer.observe(el);
21278
21917
  return () => observer.disconnect();
21279
21918
  }, [formPickRect !== null, formViewState]);
21280
- const [toolbarVariant, setToolbarVariant] = useState16("none");
21281
- const toolbarVariantRef = useRef12("none");
21919
+ const [toolbarVariant, setToolbarVariant] = useState17("none");
21920
+ const toolbarVariantRef = useRef13("none");
21282
21921
  toolbarVariantRef.current = toolbarVariant;
21283
- const [selectedIsCta, setSelectedIsCta] = useState16(false);
21284
- const [selectedIsSocial, setSelectedIsSocial] = useState16(false);
21285
- const [selectedIsSocialsRow, setSelectedIsSocialsRow] = useState16(false);
21286
- const [reorderHrefKey, setReorderHrefKey] = useState16(null);
21287
- const [reorderDragDisabled, setReorderDragDisabled] = useState16(false);
21288
- const [toggleState, setToggleState] = useState16(null);
21289
- const [maxBadge, setMaxBadge] = useState16(null);
21290
- const [activeCommands, setActiveCommands] = useState16(/* @__PURE__ */ new Set());
21291
- const [sectionGap, setSectionGap] = useState16(null);
21292
- const [toolbarShowEditLink, setToolbarShowEditLink] = useState16(false);
21293
- const hoveredNavContainerRef = useRef12(null);
21294
- const [hoveredNavContainerRect, setHoveredNavContainerRect] = useState16(null);
21295
- const hoveredItemElRef = useRef12(null);
21296
- const [hoveredItemRect, setHoveredItemRect] = useState16(null);
21297
- const [hoveredTextRect, setHoveredTextRect] = useState16(null);
21298
- useEffect15(() => {
21922
+ const [selectedIsCta, setSelectedIsCta] = useState17(false);
21923
+ const [selectedIsSocial, setSelectedIsSocial] = useState17(false);
21924
+ const [selectedIsSocialsRow, setSelectedIsSocialsRow] = useState17(false);
21925
+ const [reorderHrefKey, setReorderHrefKey] = useState17(null);
21926
+ const [reorderDragDisabled, setReorderDragDisabled] = useState17(false);
21927
+ const [toggleState, setToggleState] = useState17(null);
21928
+ const [maxBadge, setMaxBadge] = useState17(null);
21929
+ const [activeCommands, setActiveCommands] = useState17(/* @__PURE__ */ new Set());
21930
+ const [sectionGap, setSectionGap] = useState17(null);
21931
+ const [toolbarShowEditLink, setToolbarShowEditLink] = useState17(false);
21932
+ const hoveredNavContainerRef = useRef13(null);
21933
+ const [hoveredNavContainerRect, setHoveredNavContainerRect] = useState17(null);
21934
+ const hoveredItemElRef = useRef13(null);
21935
+ const [hoveredItemRect, setHoveredItemRect] = useState17(null);
21936
+ const [hoveredTextRect, setHoveredTextRect] = useState17(null);
21937
+ useEffect16(() => {
21299
21938
  const sync = () => {
21300
21939
  const el = document.querySelector(
21301
21940
  '[data-ohw-hovered]:not([contenteditable]):not([data-ohw-href-key]):not([data-ohw-editable="form"] *)'
@@ -21339,60 +21978,71 @@ function OhhwellsBridge() {
21339
21978
  });
21340
21979
  return () => observer.disconnect();
21341
21980
  }, []);
21342
- const siblingHintElRef = useRef12(null);
21343
- const [siblingHintRect, setSiblingHintRect] = useState16(null);
21344
- const [siblingHintRects, setSiblingHintRects] = useState16([]);
21345
- const [isItemDragging, setIsItemDragging] = useState16(false);
21346
- const [isFooterFrameSelection, setIsFooterFrameSelection] = useState16(false);
21981
+ const siblingHintElRef = useRef13(null);
21982
+ const [siblingHintRect, setSiblingHintRect] = useState17(null);
21983
+ const [siblingHintRects, setSiblingHintRects] = useState17([]);
21984
+ const [isItemDragging, setIsItemDragging] = useState17(false);
21985
+ const [isFooterFrameSelection, setIsFooterFrameSelection] = useState17(false);
21347
21986
  isFooterFrameSelectionRef.current = isFooterFrameSelection;
21348
- const [floatingPanel, setFloatingPanel] = useState16(null);
21349
- const floatingPanelOpenRef = useRef12(false);
21350
- floatingPanelOpenRef.current = floatingPanel !== null;
21351
- const floatingPanelRef = useRef12(null);
21352
- floatingPanelRef.current = floatingPanel;
21353
- const [floatingPanelPos, setFloatingPanelPos] = useState16(null);
21354
- const buttonCollectionDragRef = useRef12(null);
21355
- const buttonDropInsertIndexRef = useRef12(null);
21356
- const [buttonDropSlots, setButtonDropSlots] = useState16([]);
21357
- const [activeButtonDropIndex, setActiveButtonDropIndex] = useState16(null);
21358
- const buttonPointerDragRef = useRef12(null);
21359
- const [buttonStyleTick, setButtonStyleTick] = useState16(0);
21360
- const [logoSizeDraft, setLogoSizeDraft] = useState16(null);
21361
- const [editorViewport, setEditorViewport] = useState16("desktop");
21362
- const [parentScrollSnap, setParentScrollSnap] = useState16(null);
21363
- const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = useState16(null);
21364
- const [footerHeadingVisible, setFooterHeadingVisible] = useState16(null);
21365
- const footerDragRef = useRef12(null);
21366
- const [footerDropSlots, setFooterDropSlots] = useState16([]);
21367
- const [activeFooterDropIndex, setActiveFooterDropIndex] = useState16(null);
21368
- const [draggedItemRect, setDraggedItemRect] = useState16(null);
21369
- const footerPointerDragRef = useRef12(null);
21370
- const suppressNextClickRef = useRef12(false);
21371
- const suppressClickUntilRef = useRef12(0);
21372
- const [linkPopover, setLinkPopover] = useState16(null);
21373
- const linkPopoverSessionRef = useRef12(null);
21374
- const addNavAfterAnchorRef = useRef12(null);
21375
- const editContentRef = useRef12({});
21376
- const aiSectionsRef = useRef12("");
21377
- const applyTreeLocalRef = useRef12(
21987
+ const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = useState17(null);
21988
+ const [footerHeadingVisible, setFooterHeadingVisible] = useState17(null);
21989
+ const footerDragRef = useRef13(null);
21990
+ const [footerDropSlots, setFooterDropSlots] = useState17([]);
21991
+ const [activeFooterDropIndex, setActiveFooterDropIndex] = useState17(null);
21992
+ const [draggedItemRect, setDraggedItemRect] = useState17(null);
21993
+ const footerPointerDragRef = useRef13(null);
21994
+ const suppressNextClickRef = useRef13(false);
21995
+ const suppressClickUntilRef = useRef13(0);
21996
+ const [linkPopover, setLinkPopover] = useState17(null);
21997
+ const linkPopoverSessionRef = useRef13(null);
21998
+ const addNavAfterAnchorRef = useRef13(null);
21999
+ const editContentRef = useRef13({});
22000
+ const aiSectionsRef = useRef13("");
22001
+ const applyTreeLocalRef = useRef13(
21378
22002
  null
21379
22003
  );
21380
- const clearInteractionChromeRef = useRef12(() => {
22004
+ const clearInteractionChromeRef = useRef13(() => {
21381
22005
  });
21382
- const brandKitRef = useRef12("");
21383
- const stylesRef = useRef12("");
21384
- const appliedDrawerRef = useRef12(null);
21385
- const pendingDeleteUndoRef = useRef12(null);
21386
- const [sitePages, setSitePages] = useState16([]);
21387
- const [sectionsByPath, setSectionsByPath] = useState16({});
21388
- const sectionsPrefetchGenRef = useRef12(0);
21389
- const setLinkPopoverRef = useRef12(setLinkPopover);
21390
- const linkPopoverPanelRef = useRef12(null);
21391
- const linkPopoverOpenRef = useRef12(false);
21392
- const linkPopoverGraceUntilRef = useRef12(0);
22006
+ const brandKitRef = useRef13("");
22007
+ const stylesRef = useRef13("");
22008
+ const appliedDrawerRef = useRef13(null);
22009
+ const pendingDeleteUndoRef = useRef13(null);
22010
+ const [floatingPanel, setFloatingPanel] = useState17(null);
22011
+ const floatingPanelOpenRef = useRef13(false);
22012
+ const floatingPanelRef = useRef13(null);
22013
+ floatingPanelRef.current = floatingPanel;
22014
+ const setFloatingPanelRef = useRef13(setFloatingPanel);
22015
+ const [floatingPanelPos, setFloatingPanelPos] = useState17(null);
22016
+ const buttonCollectionDragRef = useRef13(null);
22017
+ const buttonDropInsertIndexRef = useRef13(null);
22018
+ const [buttonDropSlots, setButtonDropSlots] = useState17([]);
22019
+ const [activeButtonDropIndex, setActiveButtonDropIndex] = useState17(null);
22020
+ const buttonPointerDragRef = useRef13(null);
22021
+ const [buttonStyleTick, setButtonStyleTick] = useState17(0);
22022
+ const [logoSizeDraft, setLogoSizeDraft] = useState17(null);
22023
+ const [editorViewport, setEditorViewport] = useState17("desktop");
22024
+ const [parentScrollSnap, setParentScrollSnap] = useState17(null);
22025
+ const [sitePages, setSitePages] = useState17([]);
22026
+ const [sectionsByPath, setSectionsByPath] = useState17({});
22027
+ const sectionsPrefetchGenRef = useRef13(0);
22028
+ const setLinkPopoverRef = useRef13(setLinkPopover);
22029
+ const linkPopoverPanelRef = useRef13(null);
22030
+ const linkPopoverOpenRef = useRef13(false);
22031
+ const linkPopoverGraceUntilRef = useRef13(0);
21393
22032
  setLinkPopoverRef.current = setLinkPopover;
22033
+ setFloatingPanelRef.current = setFloatingPanel;
21394
22034
  linkPopoverSessionRef.current = linkPopover;
21395
- useEffect15(() => {
22035
+ floatingPanelOpenRef.current = Boolean(floatingPanel);
22036
+ useEffect16(() => {
22037
+ const syncViewport = () => {
22038
+ const next = window.innerWidth <= 480 ? "mobile" : "desktop";
22039
+ setEditorViewport((prev) => prev === next ? prev : next);
22040
+ };
22041
+ syncViewport();
22042
+ window.addEventListener("resize", syncViewport);
22043
+ return () => window.removeEventListener("resize", syncViewport);
22044
+ }, []);
22045
+ useEffect16(() => {
21396
22046
  setSectionOrderPersistHandler((entries) => {
21397
22047
  const currentPath = window.location.pathname;
21398
22048
  const merged = mergePageSectionOrder(editContentRef.current[SECTION_ORDER_KEY], currentPath, entries);
@@ -21448,7 +22098,7 @@ function OhhwellsBridge() {
21448
22098
  const bumpLinkPopoverGrace = () => {
21449
22099
  linkPopoverGraceUntilRef.current = Date.now() + 350;
21450
22100
  };
21451
- const runSectionsPrefetch = useCallback10((pages) => {
22101
+ const runSectionsPrefetch = useCallback11((pages) => {
21452
22102
  if (!isEditMode || shouldUseDevFixtures() || pages.length === 0) return;
21453
22103
  const gen = ++sectionsPrefetchGenRef.current;
21454
22104
  const paths = pages.map((p) => p.path);
@@ -21467,9 +22117,9 @@ function OhhwellsBridge() {
21467
22117
  );
21468
22118
  });
21469
22119
  }, [isEditMode, pathname]);
21470
- const runSectionsPrefetchRef = useRef12(runSectionsPrefetch);
22120
+ const runSectionsPrefetchRef = useRef13(runSectionsPrefetch);
21471
22121
  runSectionsPrefetchRef.current = runSectionsPrefetch;
21472
- useEffect15(() => {
22122
+ useEffect16(() => {
21473
22123
  if (!linkPopover) {
21474
22124
  document.documentElement.removeAttribute("data-ohw-link-popover-open");
21475
22125
  return;
@@ -21497,7 +22147,7 @@ function OhhwellsBridge() {
21497
22147
  document.documentElement.removeAttribute("data-ohw-link-popover-open");
21498
22148
  };
21499
22149
  }, [linkPopover, postToParent2]);
21500
- useEffect15(() => {
22150
+ useEffect16(() => {
21501
22151
  if (!isEditMode) return;
21502
22152
  const useFixtures = shouldUseDevFixtures();
21503
22153
  if (useFixtures) {
@@ -21521,14 +22171,14 @@ function OhhwellsBridge() {
21521
22171
  if (!useFixtures) postToParent2({ type: "ow:request-site-pages" });
21522
22172
  return () => window.removeEventListener("message", onSitePages);
21523
22173
  }, [isEditMode, postToParent2]);
21524
- useEffect15(() => {
22174
+ useEffect16(() => {
21525
22175
  if (!isEditMode || shouldUseDevFixtures()) return;
21526
22176
  void loadAllSectionsManifest().then((manifest) => {
21527
22177
  if (Object.keys(manifest).length === 0) return;
21528
22178
  setSectionsByPath((prev) => ({ ...manifest, ...prev }));
21529
22179
  });
21530
22180
  }, [isEditMode]);
21531
- useEffect15(() => {
22181
+ useEffect16(() => {
21532
22182
  const update = () => {
21533
22183
  const el = activeElRef.current ?? selectedElRef.current;
21534
22184
  if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
@@ -21552,10 +22202,10 @@ function OhhwellsBridge() {
21552
22202
  vvp.removeEventListener("resize", update);
21553
22203
  };
21554
22204
  }, []);
21555
- const refreshStateRules = useCallback10(() => {
22205
+ const refreshStateRules = useCallback11(() => {
21556
22206
  editStylesRef.current?.forceHover && (editStylesRef.current.forceHover.textContent = collectStateRules());
21557
22207
  }, []);
21558
- const processConfigRequest = useCallback10((insertAfterVal) => {
22208
+ const processConfigRequest = useCallback11((insertAfterVal) => {
21559
22209
  const tracker = getSectionsTracker();
21560
22210
  let entries = [];
21561
22211
  try {
@@ -21578,7 +22228,7 @@ function OhhwellsBridge() {
21578
22228
  }
21579
22229
  window.postMessage({ type: "ow:schedule-config", insertAfter: insertAfterVal, scheduleId: null }, "*");
21580
22230
  }, [isEditMode]);
21581
- const deactivate = useCallback10(() => {
22231
+ const deactivate = useCallback11(() => {
21582
22232
  const el = activeElRef.current;
21583
22233
  if (!el) return;
21584
22234
  const isFormBlock = el.dataset.ohwEditable === "form";
@@ -21629,12 +22279,12 @@ function OhhwellsBridge() {
21629
22279
  setToolbarShowEditLink(false);
21630
22280
  postToParent2({ type: "ow:exit-edit" });
21631
22281
  }, [postToParent2]);
21632
- const clearSelectedAttr = useCallback10(() => {
22282
+ const clearSelectedAttr = useCallback11(() => {
21633
22283
  document.querySelectorAll("[data-ohw-selected]").forEach((el) => {
21634
22284
  el.removeAttribute("data-ohw-selected");
21635
22285
  });
21636
22286
  }, []);
21637
- const deselect = useCallback10(() => {
22287
+ const deselect = useCallback11(() => {
21638
22288
  const nestedGroup = selectedElRef.current?.closest("[data-ohw-nav-children]") != null ? selectedElRef.current.closest("[data-ohw-nav-group]") : null;
21639
22289
  clearSelectedAttr();
21640
22290
  selectedElRef.current = null;
@@ -21669,20 +22319,20 @@ function OhhwellsBridge() {
21669
22319
  setToolbarVariant("none");
21670
22320
  }
21671
22321
  }, [clearSelectedAttr]);
21672
- const markSelected = useCallback10((el) => {
22322
+ const markSelected = useCallback11((el) => {
21673
22323
  clearSelectedAttr();
21674
22324
  el.removeAttribute("data-ohw-hovered");
21675
22325
  el.setAttribute("data-ohw-selected", "");
21676
22326
  }, [clearSelectedAttr]);
21677
- const isSelectedForHover = useCallback10((el) => {
22327
+ const isSelectedForHover = useCallback11((el) => {
21678
22328
  if (!el) return false;
21679
22329
  return [selectedElRef.current, activeElRef.current].some(
21680
22330
  (busy) => busy && (el === busy || busy.contains(el) || el.contains(busy))
21681
22331
  );
21682
22332
  }, []);
21683
- const isSelectedForHoverRef = useRef12(isSelectedForHover);
22333
+ const isSelectedForHoverRef = useRef13(isSelectedForHover);
21684
22334
  isSelectedForHoverRef.current = isSelectedForHover;
21685
- const resolveHrefKeyElement = useCallback10((hrefKey) => {
22335
+ const resolveHrefKeyElement = useCallback11((hrefKey) => {
21686
22336
  if (isFooterHrefKey(hrefKey)) {
21687
22337
  return document.querySelector(
21688
22338
  `footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`
@@ -21697,7 +22347,7 @@ function OhhwellsBridge() {
21697
22347
  `[data-ohw-href-key="${CSS.escape(hrefKey)}"]`
21698
22348
  );
21699
22349
  }, []);
21700
- const resyncSelectedNavigationItem = useCallback10(() => {
22350
+ const resyncSelectedNavigationItem = useCallback11(() => {
21701
22351
  const hrefKey = selectedHrefKeyRef.current;
21702
22352
  if (hrefKey) {
21703
22353
  const link = resolveHrefKeyElement(hrefKey);
@@ -21735,7 +22385,7 @@ function OhhwellsBridge() {
21735
22385
  );
21736
22386
  }
21737
22387
  }, [resolveHrefKeyElement]);
21738
- const reselectNavigationItem = useCallback10((navAnchor) => {
22388
+ const reselectNavigationItem = useCallback11((navAnchor) => {
21739
22389
  selectedElRef.current = navAnchor;
21740
22390
  selectedHrefKeyRef.current = navAnchor.getAttribute("data-ohw-href-key");
21741
22391
  selectedFooterColAttrRef.current = null;
@@ -21766,7 +22416,7 @@ function OhhwellsBridge() {
21766
22416
  setToolbarShowEditLink(false);
21767
22417
  setActiveCommands(/* @__PURE__ */ new Set());
21768
22418
  }, [markSelected]);
21769
- const commitNavigationTextEdit = useCallback10((navAnchor) => {
22419
+ const commitNavigationTextEdit = useCallback11((navAnchor) => {
21770
22420
  const el = activeElRef.current;
21771
22421
  if (!el) return;
21772
22422
  const key = el.dataset.ohwKey;
@@ -21799,7 +22449,7 @@ function OhhwellsBridge() {
21799
22449
  postToParent2({ type: "ow:exit-edit" });
21800
22450
  reselectNavigationItem(navAnchor);
21801
22451
  }, [postToParent2, reselectNavigationItem]);
21802
- const handleAddTopLevelNavItem = useCallback10(() => {
22452
+ const handleAddTopLevelNavItem = useCallback11(() => {
21803
22453
  const items = listNavbarRootItems();
21804
22454
  addNavAfterAnchorRef.current = items[items.length - 1] ?? null;
21805
22455
  deselectRef.current();
@@ -21811,7 +22461,7 @@ function OhhwellsBridge() {
21811
22461
  intent: "add-nav"
21812
22462
  });
21813
22463
  }, []);
21814
- const maybeWarnNavLinkDropdownConflict = useCallback10(
22464
+ const maybeWarnNavLinkDropdownConflict = useCallback11(
21815
22465
  (anchor) => {
21816
22466
  if (!isNavbarHrefKey(anchor.getAttribute("data-ohw-href-key"))) return;
21817
22467
  if (!navDropdownsOpenOnClick()) return;
@@ -21824,7 +22474,7 @@ function OhhwellsBridge() {
21824
22474
  },
21825
22475
  [postToParent2]
21826
22476
  );
21827
- const handleNavDropdownOpenChange = useCallback10((open) => {
22477
+ const handleNavDropdownOpenChange = useCallback11((open) => {
21828
22478
  const selected = selectedElRef.current;
21829
22479
  if (!selected || !isNavigationItem2(selected)) return;
21830
22480
  if (isNestedNavChild(selected)) return;
@@ -21840,7 +22490,7 @@ function OhhwellsBridge() {
21840
22490
  }
21841
22491
  });
21842
22492
  }, []);
21843
- const handleFooterHeadingVisibleChange = useCallback10(
22493
+ const handleFooterHeadingVisibleChange = useCallback11(
21844
22494
  (visible) => {
21845
22495
  const selected = selectedElRef.current;
21846
22496
  if (!selected || !isFooterFrameSelectionRef.current) return;
@@ -21864,7 +22514,7 @@ function OhhwellsBridge() {
21864
22514
  },
21865
22515
  [postToParent2]
21866
22516
  );
21867
- const enterEditOnNewItem = useCallback10((anchor) => {
22517
+ const enterEditOnNewItem = useCallback11((anchor) => {
21868
22518
  const label = anchor.querySelector('[data-ohw-editable="text"]');
21869
22519
  if (!label) {
21870
22520
  selectRef.current(anchor);
@@ -21873,8 +22523,8 @@ function OhhwellsBridge() {
21873
22523
  setNavGroupForceOpen(anchor, true);
21874
22524
  activateRef.current(label);
21875
22525
  }, []);
21876
- const pendingSocialAddRef = useRef12(null);
21877
- const handleAddChildItem = useCallback10(() => {
22526
+ const pendingSocialAddRef = useRef13(null);
22527
+ const handleAddChildItem = useCallback11(() => {
21878
22528
  const selected = selectedElRef.current;
21879
22529
  if (!selected) return;
21880
22530
  const socialsRow = isSocialsRow(selected) ? selected : findSocialsRow(selected);
@@ -21985,7 +22635,7 @@ function OhhwellsBridge() {
21985
22635
  });
21986
22636
  });
21987
22637
  }, [enterEditOnNewItem, isFooterFrameSelection, maybeWarnNavLinkDropdownConflict, postToParent2]);
21988
- const handleAddFooterColumn = useCallback10(() => {
22638
+ const handleAddFooterColumn = useCallback11(() => {
21989
22639
  if (!canAddFooterColumn()) {
21990
22640
  postToParent2({
21991
22641
  type: "ow:toast",
@@ -22006,7 +22656,7 @@ function OhhwellsBridge() {
22006
22656
  selectRef.current(result.firstLink);
22007
22657
  });
22008
22658
  }, [postToParent2]);
22009
- const clearFooterDragVisuals = useCallback10(() => {
22659
+ const clearFooterDragVisuals = useCallback11(() => {
22010
22660
  footerDragRef.current = null;
22011
22661
  setSiblingHintRects([]);
22012
22662
  setFooterDropSlots([]);
@@ -22015,7 +22665,7 @@ function OhhwellsBridge() {
22015
22665
  setIsItemDragging(false);
22016
22666
  unlockFooterDragInteraction();
22017
22667
  }, []);
22018
- const refreshFooterDragVisuals = useCallback10((session, activeSlot, clientX, clientY) => {
22668
+ const refreshFooterDragVisuals = useCallback11((session, activeSlot, clientX, clientY) => {
22019
22669
  const dragged = session.draggedEl;
22020
22670
  setDraggedItemRect(dragged.getBoundingClientRect());
22021
22671
  if (typeof clientX === "number" && typeof clientY === "number") {
@@ -22047,13 +22697,13 @@ function OhhwellsBridge() {
22047
22697
  const activeIdx = activeSlot ? slots.findIndex((s) => s.insertIndex === activeSlot.insertIndex) : -1;
22048
22698
  setActiveFooterDropIndex(activeIdx >= 0 ? activeIdx : null);
22049
22699
  }, []);
22050
- const refreshFooterDragVisualsRef = useRef12(refreshFooterDragVisuals);
22700
+ const refreshFooterDragVisualsRef = useRef13(refreshFooterDragVisuals);
22051
22701
  refreshFooterDragVisualsRef.current = refreshFooterDragVisuals;
22052
- const commitFooterDragRef = useRef12(() => {
22702
+ const commitFooterDragRef = useRef13(() => {
22053
22703
  });
22054
- const beginFooterDragRef = useRef12(() => {
22704
+ const beginFooterDragRef = useRef13(() => {
22055
22705
  });
22056
- const beginFooterDrag = useCallback10(
22706
+ const beginFooterDrag = useCallback11(
22057
22707
  (session) => {
22058
22708
  const rect = session.draggedEl.getBoundingClientRect();
22059
22709
  session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
@@ -22073,7 +22723,7 @@ function OhhwellsBridge() {
22073
22723
  [refreshFooterDragVisuals]
22074
22724
  );
22075
22725
  beginFooterDragRef.current = beginFooterDrag;
22076
- const commitFooterDrag = useCallback10(
22726
+ const commitFooterDrag = useCallback11(
22077
22727
  (clientX, clientY) => {
22078
22728
  const session = footerDragRef.current;
22079
22729
  if (!session) {
@@ -22202,7 +22852,7 @@ function OhhwellsBridge() {
22202
22852
  [clearFooterDragVisuals, resolveHrefKeyElement, resyncSelectedNavigationItem]
22203
22853
  );
22204
22854
  commitFooterDragRef.current = commitFooterDrag;
22205
- const startFooterLinkDrag = useCallback10(
22855
+ const startFooterLinkDrag = useCallback11(
22206
22856
  (anchor, clientX, clientY, wasSelected) => {
22207
22857
  const hrefKey = anchor.getAttribute("data-ohw-href-key");
22208
22858
  if (!hrefKey) return false;
@@ -22238,7 +22888,7 @@ function OhhwellsBridge() {
22238
22888
  },
22239
22889
  [beginFooterDrag]
22240
22890
  );
22241
- const startFooterColumnDrag = useCallback10(
22891
+ const startFooterColumnDrag = useCallback11(
22242
22892
  (columnEl, clientX, clientY, wasSelected) => {
22243
22893
  const columns = listFooterColumns();
22244
22894
  const idx = columns.indexOf(columnEl);
@@ -22258,7 +22908,7 @@ function OhhwellsBridge() {
22258
22908
  },
22259
22909
  [beginFooterDrag]
22260
22910
  );
22261
- const persistButtonCollectionDrag = useCallback10(
22911
+ const persistButtonCollectionDrag = useCallback11(
22262
22912
  (button, clientX) => {
22263
22913
  const insertIndex = buttonDropInsertIndexRef.current;
22264
22914
  if (insertIndex != null) insertButtonAtCollectionIndex(button, insertIndex);
@@ -22282,7 +22932,7 @@ function OhhwellsBridge() {
22282
22932
  },
22283
22933
  [postToParent2]
22284
22934
  );
22285
- const refreshButtonDragVisuals = useCallback10((button, clientX, clientY) => {
22935
+ const refreshButtonDragVisuals = useCallback11((button, clientX, clientY) => {
22286
22936
  const collection = buttonCollectionOf(button);
22287
22937
  if (!collection) {
22288
22938
  setButtonDropSlots([]);
@@ -22299,7 +22949,7 @@ function OhhwellsBridge() {
22299
22949
  setDraggedItemRect(button.getBoundingClientRect());
22300
22950
  if (selectedElRef.current === button) setToolbarRect(button.getBoundingClientRect());
22301
22951
  }, []);
22302
- const handleItemDragStart = useCallback10(
22952
+ const handleItemDragStart = useCallback11(
22303
22953
  (e) => {
22304
22954
  const selected = selectedElRef.current;
22305
22955
  if (!selected) {
@@ -22330,7 +22980,7 @@ function OhhwellsBridge() {
22330
22980
  },
22331
22981
  [startFooterColumnDrag, startFooterLinkDrag, startNavLinkDrag, refreshButtonDragVisuals]
22332
22982
  );
22333
- const handleItemDragEnd = useCallback10(
22983
+ const handleItemDragEnd = useCallback11(
22334
22984
  (e) => {
22335
22985
  const collectionButton = buttonCollectionDragRef.current;
22336
22986
  if (collectionButton) {
@@ -22361,7 +23011,7 @@ function OhhwellsBridge() {
22361
23011
  },
22362
23012
  [commitFooterDrag, commitNavDrag, navDragRef, persistButtonCollectionDrag]
22363
23013
  );
22364
- const handleItemChromePointerDown = useCallback10((e) => {
23014
+ const handleItemChromePointerDown = useCallback11((e) => {
22365
23015
  if (e.button !== 0) return;
22366
23016
  const selected = selectedElRef.current;
22367
23017
  if (!selected) return;
@@ -22402,7 +23052,7 @@ function OhhwellsBridge() {
22402
23052
  }
22403
23053
  if (armNavPressFromChrome(selected, e.clientX, e.clientY, e.pointerId)) return;
22404
23054
  }, [armNavPressFromChrome]);
22405
- const handleItemChromeClick = useCallback10((clientX, clientY) => {
23055
+ const handleItemChromeClick = useCallback11((clientX, clientY) => {
22406
23056
  if (suppressNextClickRef.current || Date.now() < suppressClickUntilRef.current) {
22407
23057
  suppressNextClickRef.current = false;
22408
23058
  return;
@@ -22415,7 +23065,7 @@ function OhhwellsBridge() {
22415
23065
  }, []);
22416
23066
  reselectNavigationItemRef.current = reselectNavigationItem;
22417
23067
  commitNavigationTextEditRef.current = commitNavigationTextEdit;
22418
- const select = useCallback10((anchor) => {
23068
+ const select = useCallback11((anchor) => {
22419
23069
  if (!isNavigationItem2(anchor)) return;
22420
23070
  if (activeElRef.current) deactivate();
22421
23071
  aiSectionApiRef.current?.selectFromElement(anchor);
@@ -22477,7 +23127,7 @@ function OhhwellsBridge() {
22477
23127
  setLogoSizeDraft(null);
22478
23128
  }
22479
23129
  }, [deactivate, markSelected]);
22480
- const selectFrame = useCallback10((el) => {
23130
+ const selectFrame = useCallback11((el) => {
22481
23131
  if (!isNavigationContainer(el)) return;
22482
23132
  if (activeElRef.current) deactivate();
22483
23133
  aiSectionApiRef.current?.selectFromElement(el);
@@ -22518,7 +23168,7 @@ function OhhwellsBridge() {
22518
23168
  setFloatingPanelPos(null);
22519
23169
  setLogoSizeDraft(null);
22520
23170
  }, [deactivate, markSelected, postToParent2]);
22521
- const selectLogo = useCallback10(
23171
+ const selectLogo = useCallback11(
22522
23172
  (logoEl) => {
22523
23173
  if (activeElRef.current) deactivate();
22524
23174
  selectedElRef.current = logoEl;
@@ -22547,7 +23197,7 @@ function OhhwellsBridge() {
22547
23197
  },
22548
23198
  [deactivate, markSelected]
22549
23199
  );
22550
- const openLogoSizePanel = useCallback10((logoEl) => {
23200
+ const openLogoSizePanel = useCallback11((logoEl) => {
22551
23201
  const placement = getLogoPlacement(logoEl);
22552
23202
  const draft = readLogoSizeState(editContentRef.current, placement);
22553
23203
  setLogoSizeDraft(draft);
@@ -22560,7 +23210,7 @@ function OhhwellsBridge() {
22560
23210
  placement
22561
23211
  });
22562
23212
  }, []);
22563
- const openSocialsDisplayPanel = useCallback10((row) => {
23213
+ const openSocialsDisplayPanel = useCallback11((row) => {
22564
23214
  setFloatingPanelPos(null);
22565
23215
  setParentScrollSnap(parentScrollRef.current);
22566
23216
  setFloatingPanel({
@@ -22571,7 +23221,7 @@ function OhhwellsBridge() {
22571
23221
  row
22572
23222
  });
22573
23223
  }, []);
22574
- const rememberButtonTokens = useCallback10(
23224
+ const rememberButtonTokens = useCallback11(
22575
23225
  (content, tokens, nodes) => {
22576
23226
  if (nodes.length === 0) return content;
22577
23227
  const next = { ...content };
@@ -22582,7 +23232,7 @@ function OhhwellsBridge() {
22582
23232
  },
22583
23233
  [postToParent2]
22584
23234
  );
22585
- const tokensForButton = useCallback10(
23235
+ const tokensForButton = useCallback11(
22586
23236
  (el, persistFallback = false) => {
22587
23237
  const stored = readStoredStyleTokens(editContentRef.current);
22588
23238
  if (stored) return stored;
@@ -22597,7 +23247,7 @@ function OhhwellsBridge() {
22597
23247
  },
22598
23248
  [rememberButtonTokens]
22599
23249
  );
22600
- const openButtonStylePanel = useCallback10(
23250
+ const openButtonStylePanel = useCallback11(
22601
23251
  (anchor) => {
22602
23252
  const id = buttonId(anchor);
22603
23253
  if (!id) return;
@@ -22615,7 +23265,7 @@ function OhhwellsBridge() {
22615
23265
  },
22616
23266
  [tokensForButton]
22617
23267
  );
22618
- const applySelectedButtonStyle = useCallback10(
23268
+ const applySelectedButtonStyle = useCallback11(
22619
23269
  (patch) => {
22620
23270
  const panel = floatingPanelRef.current;
22621
23271
  const id = panel?.kind === "button-style" ? panel.buttonId : null;
@@ -22633,7 +23283,7 @@ function OhhwellsBridge() {
22633
23283
  },
22634
23284
  [postToParent2]
22635
23285
  );
22636
- useEffect15(() => {
23286
+ useEffect16(() => {
22637
23287
  const onDragOver = (e) => {
22638
23288
  const dragged = buttonCollectionDragRef.current;
22639
23289
  if (!dragged) return;
@@ -22652,11 +23302,11 @@ function OhhwellsBridge() {
22652
23302
  document.removeEventListener("drop", onDrop);
22653
23303
  };
22654
23304
  }, [refreshButtonDragVisuals]);
22655
- const isEditModeRef = useRef12(false);
22656
- const requestMissingSocialIconsRef = useRef12(() => {
23305
+ const isEditModeRef = useRef13(false);
23306
+ const requestMissingSocialIconsRef = useRef13(() => {
22657
23307
  });
22658
- const askedSocialIconsRef = useRef12(/* @__PURE__ */ new Set());
22659
- const requestMissingSocialIcons = useCallback10(() => {
23308
+ const askedSocialIconsRef = useRef13(/* @__PURE__ */ new Set());
23309
+ const requestMissingSocialIcons = useCallback11(() => {
22660
23310
  const items = Array.from(document.querySelectorAll(`[${SOCIALS_ROW_ATTR}]`)).filter((row) => socialsDisplayFor(row, editContentRef.current).icon).flatMap((row) => {
22661
23311
  const missing = socialsMissingIcons(row);
22662
23312
  listSocialItems(row).forEach((item) => ensureIconSlot(item));
@@ -22668,7 +23318,7 @@ function OhhwellsBridge() {
22668
23318
  }, []);
22669
23319
  requestMissingSocialIconsRef.current = requestMissingSocialIcons;
22670
23320
  isEditModeRef.current = isEditMode;
22671
- const changeSocialsDisplay = useCallback10(
23321
+ const changeSocialsDisplay = useCallback11(
22672
23322
  (row, next) => {
22673
23323
  if (next.icon) {
22674
23324
  const missing = socialsMissingIcons(row);
@@ -22692,19 +23342,19 @@ function OhhwellsBridge() {
22692
23342
  },
22693
23343
  []
22694
23344
  );
22695
- const closeFloatingPanelOnly = useCallback10(() => {
23345
+ const closeFloatingPanelOnly = useCallback11(() => {
22696
23346
  setFloatingPanel(null);
22697
23347
  setFloatingPanelPos(null);
22698
23348
  setLogoSizeDraft(null);
22699
23349
  }, []);
22700
23350
  closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
22701
- const closeFloatingPanelAndDeselect = useCallback10(() => {
23351
+ const closeFloatingPanelAndDeselect = useCallback11(() => {
22702
23352
  setFloatingPanel(null);
22703
23353
  setFloatingPanelPos(null);
22704
23354
  setLogoSizeDraft(null);
22705
23355
  deselectRef.current();
22706
23356
  }, []);
22707
- useEffect15(() => {
23357
+ useEffect16(() => {
22708
23358
  const session = floatingPanel && floatingPanel.kind === "logo-size" ? floatingPanel : null;
22709
23359
  if (!session || !logoSizeDraft) {
22710
23360
  postToParentRef.current({ type: "ow:logo-size-panel", open: false });
@@ -22723,7 +23373,7 @@ function OhhwellsBridge() {
22723
23373
  max: LOGO_SIZE_MAX
22724
23374
  });
22725
23375
  }, [floatingPanel, logoSizeDraft, editorViewport]);
22726
- const persistLogoSizeDraft = useCallback10(
23376
+ const persistLogoSizeDraft = useCallback11(
22727
23377
  (placement, draft) => {
22728
23378
  const desktopKey = LOGO_SIZE_DESKTOP_KEYS[placement];
22729
23379
  const mobileKey = LOGO_SIZE_MOBILE_KEYS[placement];
@@ -22763,7 +23413,7 @@ function OhhwellsBridge() {
22763
23413
  },
22764
23414
  [postToParent2]
22765
23415
  );
22766
- const activate = useCallback10((el, options) => {
23416
+ const activate = useCallback11((el, options) => {
22767
23417
  if (activeElRef.current === el) return;
22768
23418
  document.querySelectorAll("[data-ohw-hovered]").forEach((hovered) => {
22769
23419
  hovered.removeAttribute("data-ohw-hovered");
@@ -22861,8 +23511,8 @@ function OhhwellsBridge() {
22861
23511
  openLogoSizePanelRef.current = openLogoSizePanel;
22862
23512
  deselectRef.current = deselect;
22863
23513
  closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
22864
- const lastSiteWideScopeRef = useRef12(null);
22865
- useEffect15(() => {
23514
+ const lastSiteWideScopeRef = useRef13(null);
23515
+ useEffect16(() => {
22866
23516
  if (!isEditMode) {
22867
23517
  if (lastSiteWideScopeRef.current !== false) {
22868
23518
  lastSiteWideScopeRef.current = false;
@@ -22909,6 +23559,7 @@ function OhhwellsBridge() {
22909
23559
  }
22910
23560
  if (typeof content[STYLE_STORE_KEY] === "string") {
22911
23561
  stylesRef.current = content[STYLE_STORE_KEY];
23562
+ document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
22912
23563
  applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
22913
23564
  }
22914
23565
  applyBrandChrome(content);
@@ -22917,12 +23568,12 @@ function OhhwellsBridge() {
22917
23568
  for (const [key, val] of Object.entries(content)) {
22918
23569
  if (key === "__ohw_sections") continue;
22919
23570
  if (key === AI_SECTIONS_KEY) continue;
23571
+ if (key === LOGO_PLACEHOLDER_KEY) continue;
23572
+ if (LOGO_IMAGE_KEYS.includes(key)) continue;
22920
23573
  if (key === BRAND_KIT_KEY) continue;
22921
23574
  if (key === STYLE_STORE_KEY) continue;
22922
23575
  if (BRAND_CHROME_KEYS.has(key)) continue;
22923
- if (key === LOGO_PLACEHOLDER_KEY) continue;
22924
23576
  if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
22925
- if (LOGO_IMAGE_KEYS.includes(key)) continue;
22926
23577
  if (applyVideoSettingNode(key, val)) continue;
22927
23578
  if (applyCarouselNode(key, val)) continue;
22928
23579
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -22994,7 +23645,9 @@ function OhhwellsBridge() {
22994
23645
  let cancelled = false;
22995
23646
  setFetchState("loading");
22996
23647
  const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
22997
- fetch(`${apiUrl}/api/public/sites/${subdomain}/content`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
23648
+ const initialPath = pathname;
23649
+ fetchedContentPaths.add(`${subdomain}::${initialPath}`);
23650
+ fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(initialPath)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
22998
23651
  if (cancelled) return;
22999
23652
  const content = data?.content ?? {};
23000
23653
  const branding = Boolean(data?.showBranding);
@@ -23010,7 +23663,7 @@ function OhhwellsBridge() {
23010
23663
  cancelled = true;
23011
23664
  };
23012
23665
  }, [subdomain, isEditMode]);
23013
- useEffect15(() => {
23666
+ useEffect16(() => {
23014
23667
  if (!isEditMode) return;
23015
23668
  const resolveIndex = (form, clientY) => {
23016
23669
  const wrappers = listFieldWrappers(form).filter((el) => fieldKeyOf(el) !== fieldDragRef.current?.key);
@@ -23051,7 +23704,7 @@ function OhhwellsBridge() {
23051
23704
  window.removeEventListener("drop", onDrop, true);
23052
23705
  };
23053
23706
  }, [buildFieldDropSlots, isEditMode, persistFields, selectField]);
23054
- useEffect15(() => {
23707
+ useEffect16(() => {
23055
23708
  if (!isEditMode) return;
23056
23709
  const mark = () => document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
23057
23710
  markFormFields(form);
@@ -23063,7 +23716,7 @@ function OhhwellsBridge() {
23063
23716
  });
23064
23717
  return () => observer.disconnect();
23065
23718
  }, [isEditMode, fetchState, pathname]);
23066
- useEffect15(() => {
23719
+ useEffect16(() => {
23067
23720
  if (!isEditMode) return;
23068
23721
  let saveTimer = null;
23069
23722
  const onInput = (e) => {
@@ -23085,14 +23738,14 @@ function OhhwellsBridge() {
23085
23738
  document.addEventListener("input", onInput, true);
23086
23739
  return () => document.removeEventListener("input", onInput, true);
23087
23740
  }, [isEditMode, persistFields]);
23088
- useEffect15(() => {
23741
+ useEffect16(() => {
23089
23742
  if (isEditMode || fetchState !== "done") return;
23090
23743
  const content = contentCache.get(subdomain) ?? {};
23091
23744
  document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
23092
23745
  reconcileFieldsFromContent(form, content);
23093
23746
  });
23094
23747
  }, [isEditMode, fetchState, subdomain]);
23095
- useEffect15(() => {
23748
+ useEffect16(() => {
23096
23749
  if (!isEditMode) return;
23097
23750
  const swallow = (e) => {
23098
23751
  const target = e.target;
@@ -23101,14 +23754,14 @@ function OhhwellsBridge() {
23101
23754
  document.addEventListener("submit", swallow, true);
23102
23755
  return () => document.removeEventListener("submit", swallow, true);
23103
23756
  }, [isEditMode]);
23104
- useEffect15(() => {
23757
+ useEffect16(() => {
23105
23758
  if (isEditMode || fetchState !== "done") return;
23106
23759
  console.log("env", process.env.NEXT_PUBLIC_FLOWOPS_API_URL);
23107
23760
  const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
23108
23761
  console.log({ apiUrl, subdomain });
23109
23762
  bindPublishedForms(apiUrl, subdomain, contentCache.get(subdomain) ?? {});
23110
23763
  }, [isEditMode, fetchState, subdomain]);
23111
- useEffect15(() => {
23764
+ useEffect16(() => {
23112
23765
  if (!subdomain || isEditMode) return;
23113
23766
  let debounceTimer = null;
23114
23767
  let observer = null;
@@ -23130,16 +23783,17 @@ function OhhwellsBridge() {
23130
23783
  applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
23131
23784
  }
23132
23785
  if (typeof content[STYLE_STORE_KEY] === "string") {
23786
+ document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
23133
23787
  applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
23134
23788
  }
23135
23789
  for (const [key, val] of Object.entries(content)) {
23136
23790
  if (key === "__ohw_sections") continue;
23137
23791
  if (key === AI_SECTIONS_KEY) continue;
23792
+ if (key === LOGO_PLACEHOLDER_KEY) continue;
23793
+ if (LOGO_IMAGE_KEYS.includes(key)) continue;
23138
23794
  if (key === BRAND_KIT_KEY) continue;
23139
23795
  if (key === STYLE_STORE_KEY) continue;
23140
23796
  if (BRAND_CHROME_KEYS.has(key)) continue;
23141
- if (key === LOGO_PLACEHOLDER_KEY) continue;
23142
- if (LOGO_IMAGE_KEYS.includes(key)) continue;
23143
23797
  if (applyVideoSettingNode(key, val)) continue;
23144
23798
  if (applyCarouselNode(key, val)) continue;
23145
23799
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -23191,6 +23845,17 @@ function OhhwellsBridge() {
23191
23845
  debounceTimer = setTimeout(applyFromCache, 150);
23192
23846
  };
23193
23847
  applyFromCache();
23848
+ const pathCacheKey = `${subdomain}::${pathname}`;
23849
+ if (!fetchedContentPaths.has(pathCacheKey)) {
23850
+ fetchedContentPaths.add(pathCacheKey);
23851
+ const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
23852
+ fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(pathname)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
23853
+ if (!data?.content) return;
23854
+ contentCache.set(subdomain, data.content);
23855
+ applyFromCache();
23856
+ }).catch(() => {
23857
+ });
23858
+ }
23194
23859
  observer = new MutationObserver(scheduleApply);
23195
23860
  observer.observe(document.body, { childList: true, subtree: true });
23196
23861
  return () => {
@@ -23204,10 +23869,10 @@ function OhhwellsBridge() {
23204
23869
  const visible = Boolean(subdomain) && fetchState !== "done";
23205
23870
  el.style.display = visible ? "flex" : "none";
23206
23871
  }, [subdomain, fetchState]);
23207
- useEffect15(() => {
23872
+ useEffect16(() => {
23208
23873
  postToParent2({ type: "ow:navigation", path: pathname });
23209
23874
  }, [pathname, postToParent2]);
23210
- useEffect15(() => {
23875
+ useEffect16(() => {
23211
23876
  if (!subdomain || isEditMode) return;
23212
23877
  const content = contentCache.get(subdomain);
23213
23878
  if (!content) return;
@@ -23223,7 +23888,7 @@ function OhhwellsBridge() {
23223
23888
  applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
23224
23889
  }
23225
23890
  }, [pathname, subdomain, isEditMode]);
23226
- useEffect15(() => {
23891
+ useEffect16(() => {
23227
23892
  if (!isEditMode) return;
23228
23893
  if (linkPopoverSessionRef.current?.intent === "add-nav") return;
23229
23894
  if (document.querySelector("[data-ohw-section-picker]")) return;
@@ -23231,11 +23896,11 @@ function OhhwellsBridge() {
23231
23896
  deselectRef.current();
23232
23897
  deactivateRef.current();
23233
23898
  }, [pathname, isEditMode]);
23234
- useEffect15(() => {
23899
+ useEffect16(() => {
23235
23900
  if (!isEditMode) return;
23236
23901
  initSectionInstancesFromContent(editContentRef.current, pathname);
23237
23902
  }, [pathname, isEditMode]);
23238
- useEffect15(() => {
23903
+ useEffect16(() => {
23239
23904
  if (!isEditMode) return;
23240
23905
  const observer = new MutationObserver(() => {
23241
23906
  const drawer = document.querySelector("[data-ohw-nav-drawer]");
@@ -23246,7 +23911,7 @@ function OhhwellsBridge() {
23246
23911
  observer.observe(document.body, { childList: true, subtree: true });
23247
23912
  return () => observer.disconnect();
23248
23913
  }, [isEditMode, pathname]);
23249
- useEffect15(() => {
23914
+ useEffect16(() => {
23250
23915
  const contentForNav = () => {
23251
23916
  if (isEditMode) return editContentRef.current;
23252
23917
  if (!subdomain) return {};
@@ -23319,7 +23984,7 @@ function OhhwellsBridge() {
23319
23984
  observer?.disconnect();
23320
23985
  };
23321
23986
  }, [isEditMode, pathname, subdomain, fetchState, resyncSelectedNavigationItem]);
23322
- useEffect15(() => {
23987
+ useEffect16(() => {
23323
23988
  if (!isEditMode) return;
23324
23989
  let applying = false;
23325
23990
  let rafId = null;
@@ -23357,7 +24022,7 @@ function OhhwellsBridge() {
23357
24022
  observer.disconnect();
23358
24023
  };
23359
24024
  }, [isEditMode, pathname]);
23360
- useEffect15(() => {
24025
+ useEffect16(() => {
23361
24026
  if (!isEditMode) return;
23362
24027
  let lastPosted = 0;
23363
24028
  const measure = () => {
@@ -23379,29 +24044,14 @@ function OhhwellsBridge() {
23379
24044
  const t2 = setTimeout(measure, 500);
23380
24045
  const ro = new ResizeObserver(schedule);
23381
24046
  ro.observe(document.body);
23382
- let lastWidth = window.innerWidth;
23383
- let resizeTimers = [];
23384
- const clearResizeTimers = () => {
23385
- resizeTimers.forEach(clearTimeout);
23386
- resizeTimers = [];
23387
- };
23388
- const handleResize = () => {
23389
- if (window.innerWidth === lastWidth) return;
23390
- lastWidth = window.innerWidth;
23391
- clearResizeTimers();
23392
- resizeTimers = HEIGHT_SETTLE_DELAYS.map((delay) => setTimeout(measure, delay));
23393
- };
23394
- window.addEventListener("resize", handleResize);
23395
24047
  return () => {
23396
24048
  clearTimeout(t1);
23397
24049
  clearTimeout(t2);
23398
24050
  if (raf != null) cancelAnimationFrame(raf);
23399
24051
  ro.disconnect();
23400
- clearResizeTimers();
23401
- window.removeEventListener("resize", handleResize);
23402
24052
  };
23403
24053
  }, [pathname, isEditMode, postToParent2]);
23404
- useEffect15(() => {
24054
+ useEffect16(() => {
23405
24055
  if (!subdomainFromQuery || isEditMode) return;
23406
24056
  const handleClick = (e) => {
23407
24057
  const anchor = e.target.closest("a");
@@ -23417,7 +24067,7 @@ function OhhwellsBridge() {
23417
24067
  document.addEventListener("click", handleClick, true);
23418
24068
  return () => document.removeEventListener("click", handleClick, true);
23419
24069
  }, [subdomainFromQuery, isEditMode, router]);
23420
- useEffect15(() => {
24070
+ useEffect16(() => {
23421
24071
  if (!isEditMode) {
23422
24072
  editStylesRef.current?.base.remove();
23423
24073
  editStylesRef.current?.forceHover.remove();
@@ -23643,11 +24293,11 @@ function OhhwellsBridge() {
23643
24293
  footer [data-ohw-href-key] [data-ohw-editable][contenteditable],
23644
24294
  footer [data-ohw-href-key] [data-ohw-editable][contenteditable] * {
23645
24295
  outline: none !important;
23646
- caret-color: ${PRIMARY5} !important;
24296
+ caret-color: ${PRIMARY6} !important;
23647
24297
  cursor: text !important;
23648
24298
  }
23649
24299
  [data-ohw-editable][contenteditable]::selection,
23650
- [data-ohw-editable][contenteditable] *::selection { background: ${PRIMARY5}59 !important; }
24300
+ [data-ohw-editable][contenteditable] *::selection { background: ${PRIMARY6}59 !important; }
23651
24301
  [data-ohw-editable-state], [data-ohw-editable-state] * { pointer-events: none !important; }
23652
24302
  [data-ohw-editable-state][data-ohw-active-state] [data-ohw-editable] { pointer-events: auto !important; }
23653
24303
  [data-ohw-editable-state][data-ohw-active-state][data-ohw-editable] { pointer-events: auto !important; }
@@ -23693,6 +24343,13 @@ function OhhwellsBridge() {
23693
24343
  if (target.closest("[data-ohw-state-toggle]")) return;
23694
24344
  if (target.closest("[data-ohw-max-badge]")) return;
23695
24345
  if (isInsideLinkEditor(target)) return;
24346
+ if (isInsideFloatingPanel(target)) return;
24347
+ if (target.closest("[data-ohw-form-toolbar]")) return;
24348
+ if (target.closest(
24349
+ '[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
24350
+ )) {
24351
+ return;
24352
+ }
23696
24353
  if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
23697
24354
  clearMediaSelectionRef.current();
23698
24355
  }
@@ -23713,13 +24370,6 @@ function OhhwellsBridge() {
23713
24370
  return;
23714
24371
  }
23715
24372
  }
23716
- if (isInsideFloatingPanel(target)) return;
23717
- if (target.closest("[data-ohw-form-toolbar]")) return;
23718
- if (target.closest(
23719
- '[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
23720
- )) {
23721
- return;
23722
- }
23723
24373
  {
23724
24374
  const formEl = getFormElement(target);
23725
24375
  const onSuccessText = target.closest(`[${SUCCESS_TEXT_ATTR}]`);
@@ -24099,6 +24749,9 @@ function OhhwellsBridge() {
24099
24749
  setHoveredItemRect(null);
24100
24750
  hoveredNavContainerRef.current = null;
24101
24751
  setHoveredNavContainerRect(null);
24752
+ siblingHintElRef.current = null;
24753
+ setSiblingHintRect(null);
24754
+ setSiblingHintRects([]);
24102
24755
  return;
24103
24756
  }
24104
24757
  {
@@ -24219,7 +24872,6 @@ function OhhwellsBridge() {
24219
24872
  hoveredNavContainerRef.current = null;
24220
24873
  setHoveredNavContainerRect(null);
24221
24874
  hoveredItemElRef.current = editable;
24222
- setHoveredItemRect(isSelectedForHoverRef.current(editable) ? null : editable.getBoundingClientRect());
24223
24875
  }
24224
24876
  }
24225
24877
  }
@@ -24929,7 +25581,11 @@ function OhhwellsBridge() {
24929
25581
  };
24930
25582
  const handleMouseMove = (e) => {
24931
25583
  const { clientX, clientY } = e;
24932
- if (pointOwnedByFloatingPanel(clientX, clientY)) return;
25584
+ if (pointOwnedByFloatingPanel(clientX, clientY)) {
25585
+ dismissImageHover();
25586
+ clearImageHover();
25587
+ return;
25588
+ }
24933
25589
  if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) {
24934
25590
  document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
24935
25591
  formHoverElRef.current = null;
@@ -24958,7 +25614,12 @@ function OhhwellsBridge() {
24958
25614
  setHoveredItemRect(null);
24959
25615
  hoveredNavContainerRef.current = null;
24960
25616
  setHoveredNavContainerRect(null);
25617
+ siblingHintElRef.current = null;
25618
+ setSiblingHintRect(null);
25619
+ setSiblingHintRects([]);
24961
25620
  dismissImageHover();
25621
+ clearImageHover();
25622
+ setSectionGap(null);
24962
25623
  return;
24963
25624
  }
24964
25625
  if (probeSocialsRowAt(clientX, clientY)) return;
@@ -24970,7 +25631,11 @@ function OhhwellsBridge() {
24970
25631
  if (e.data?.type !== "ow:pointer-sync") return;
24971
25632
  const { clientX, clientY } = e.data;
24972
25633
  if (typeof clientX !== "number" || typeof clientY !== "number") return;
24973
- if (pointOwnedByFloatingPanel(clientX, clientY)) return;
25634
+ if (pointOwnedByFloatingPanel(clientX, clientY)) {
25635
+ dismissImageHover();
25636
+ clearImageHover();
25637
+ return;
25638
+ }
24974
25639
  if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) return;
24975
25640
  if (probeSocialsRowAt(clientX, clientY)) return;
24976
25641
  probeSectionGapAt(clientX, clientY);
@@ -25316,6 +25981,7 @@ function OhhwellsBridge() {
25316
25981
  }
25317
25982
  if (typeof content[STYLE_STORE_KEY] === "string") {
25318
25983
  stylesRef.current = content[STYLE_STORE_KEY];
25984
+ document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
25319
25985
  applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
25320
25986
  }
25321
25987
  applyBrandChrome(content);
@@ -25328,12 +25994,12 @@ function OhhwellsBridge() {
25328
25994
  continue;
25329
25995
  }
25330
25996
  if (key === AI_SECTIONS_KEY) continue;
25997
+ if (key === LOGO_PLACEHOLDER_KEY) continue;
25998
+ if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
25331
25999
  if (key === BRAND_KIT_KEY) continue;
25332
26000
  if (key === STYLE_STORE_KEY) continue;
25333
26001
  if (BRAND_CHROME_KEYS.has(key)) continue;
25334
- if (key === LOGO_PLACEHOLDER_KEY) continue;
25335
26002
  if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
25336
- if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
25337
26003
  if (applyVideoSettingNode(key, val)) continue;
25338
26004
  if (applyCarouselNode(key, val)) continue;
25339
26005
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -25779,6 +26445,12 @@ function OhhwellsBridge() {
25779
26445
  closeLinkPopoverRef.current();
25780
26446
  return;
25781
26447
  }
26448
+ if (floatingPanelOpenRef.current) {
26449
+ setFloatingPanelRef.current(null);
26450
+ deselectRef.current();
26451
+ deactivateRef.current();
26452
+ return;
26453
+ }
25782
26454
  deselectRef.current();
25783
26455
  deactivateRef.current();
25784
26456
  clearMediaSelectionRef.current();
@@ -26055,6 +26727,21 @@ function OhhwellsBridge() {
26055
26727
  type: "text",
26056
26728
  text: editContentRef.current[CUSTOM_CODE_AFTER_HEAD_KEY] ?? ""
26057
26729
  });
26730
+ nodes.push({
26731
+ key: BRAND_TITLE_KEY,
26732
+ type: "text",
26733
+ text: editContentRef.current[BRAND_TITLE_KEY] ?? ""
26734
+ });
26735
+ nodes.push({
26736
+ key: SITE_DESCRIPTION_KEY,
26737
+ type: "text",
26738
+ text: editContentRef.current[SITE_DESCRIPTION_KEY] ?? ""
26739
+ });
26740
+ nodes.push({
26741
+ key: SITE_OG_IMAGE_KEY,
26742
+ type: "text",
26743
+ text: editContentRef.current[SITE_OG_IMAGE_KEY] ?? ""
26744
+ });
26058
26745
  document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
26059
26746
  const formKey = formKeyOf(form);
26060
26747
  if (!formKey) return;
@@ -26077,8 +26764,12 @@ function OhhwellsBridge() {
26077
26764
  if (inserted) {
26078
26765
  const tracker = getSectionsTracker();
26079
26766
  postToParentRef.current({ type: "ow:change", nodes: [{ key: "__ohw_sections", text: tracker.textContent ?? "[]" }] });
26080
- const h = document.body.scrollHeight;
26081
- if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
26767
+ const reportHeight = () => {
26768
+ const h = document.body.scrollHeight;
26769
+ if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
26770
+ };
26771
+ reportHeight();
26772
+ setTimeout(reportHeight, 500);
26082
26773
  }
26083
26774
  };
26084
26775
  const handleSwitchSchedule = (e) => {
@@ -26507,17 +27198,17 @@ function OhhwellsBridge() {
26507
27198
  window.removeEventListener("message", handleDeleteSection);
26508
27199
  window.removeEventListener("message", handleDuplicateSection);
26509
27200
  window.removeEventListener("message", handleDeactivate);
26510
- document.documentElement.removeAttribute("data-ohw-panel-dragging");
26511
27201
  window.removeEventListener("message", handleToastAction);
26512
27202
  window.removeEventListener("message", handleFormCount);
26513
27203
  window.removeEventListener("message", handleUiEscape);
27204
+ document.documentElement.removeAttribute("data-ohw-panel-dragging");
26514
27205
  autoSaveTimers.current.forEach(clearTimeout);
26515
27206
  autoSaveTimers.current.clear();
26516
27207
  if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
26517
27208
  if (imageShowTimerRef.current) clearTimeout(imageShowTimerRef.current);
26518
27209
  };
26519
27210
  }, [isEditMode, refreshStateRules]);
26520
- useEffect15(() => {
27211
+ useEffect16(() => {
26521
27212
  if (!isEditMode) return;
26522
27213
  const THRESHOLD = 10;
26523
27214
  const resolveWasSelected = (el) => {
@@ -26673,7 +27364,7 @@ function OhhwellsBridge() {
26673
27364
  unlockFooterDragInteraction();
26674
27365
  };
26675
27366
  }, [isEditMode]);
26676
- useEffect15(() => {
27367
+ useEffect16(() => {
26677
27368
  if (!isEditMode) return;
26678
27369
  const THRESHOLD = 10;
26679
27370
  const onPointerDown = (e) => {
@@ -26764,7 +27455,7 @@ function OhhwellsBridge() {
26764
27455
  document.removeEventListener("selectstart", blockSelectStart, true);
26765
27456
  };
26766
27457
  }, [isEditMode, persistButtonCollectionDrag, refreshButtonDragVisuals]);
26767
- useEffect15(() => {
27458
+ useEffect16(() => {
26768
27459
  const handler = (e) => {
26769
27460
  if (e.data?.type !== "ow:request-schedule-config") return;
26770
27461
  const insertAfterVal = e.data.insertAfter;
@@ -26780,7 +27471,7 @@ function OhhwellsBridge() {
26780
27471
  window.addEventListener("message", handler);
26781
27472
  return () => window.removeEventListener("message", handler);
26782
27473
  }, [processConfigRequest]);
26783
- useEffect15(() => {
27474
+ useEffect16(() => {
26784
27475
  if (!isEditMode) return;
26785
27476
  document.querySelectorAll("[data-ohw-active-state]").forEach((el) => {
26786
27477
  el.removeAttribute("data-ohw-active-state");
@@ -26804,7 +27495,7 @@ function OhhwellsBridge() {
26804
27495
  postToParent2({
26805
27496
  type: "ow:ready",
26806
27497
  version: "1",
26807
- bridgeVersion: "0.1.122",
27498
+ bridgeVersion: "0.1.124",
26808
27499
  path: pathname,
26809
27500
  nodes: collectEditableNodes(editContentRef.current),
26810
27501
  sections
@@ -26816,13 +27507,13 @@ function OhhwellsBridge() {
26816
27507
  clearTimeout(timer);
26817
27508
  };
26818
27509
  }, [pathname, isEditMode, refreshStateRules, postToParent2]);
26819
- useEffect15(() => {
27510
+ useEffect16(() => {
26820
27511
  scrollToHashSectionWhenReady();
26821
27512
  const onHashChange = () => scrollToHashSectionWhenReady();
26822
27513
  window.addEventListener("hashchange", onHashChange);
26823
27514
  return () => window.removeEventListener("hashchange", onHashChange);
26824
27515
  }, [pathname]);
26825
- const handleCommand = useCallback10((cmd) => {
27516
+ const handleCommand = useCallback11((cmd) => {
26826
27517
  const el = activeElRef.current;
26827
27518
  const selBefore = window.getSelection();
26828
27519
  let savedOffsets = null;
@@ -26858,7 +27549,7 @@ function OhhwellsBridge() {
26858
27549
  if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
26859
27550
  refreshActiveCommandsRef.current();
26860
27551
  }, []);
26861
- useEffect15(() => {
27552
+ useEffect16(() => {
26862
27553
  const session = floatingPanel && floatingPanel.kind === "logo-size" ? floatingPanel : null;
26863
27554
  if (!session || !logoSizeDraft) return;
26864
27555
  const onPanelAction = (e) => {
@@ -26896,7 +27587,7 @@ function OhhwellsBridge() {
26896
27587
  window.addEventListener("message", onPanelAction);
26897
27588
  return () => window.removeEventListener("message", onPanelAction);
26898
27589
  }, [floatingPanel, logoSizeDraft, editorViewport, persistLogoSizeDraft, closeFloatingPanelAndDeselect]);
26899
- const handleStateChange = useCallback10((state) => {
27590
+ const handleStateChange = useCallback11((state) => {
26900
27591
  if (!activeStateElRef.current) return;
26901
27592
  const el = activeStateElRef.current;
26902
27593
  if (state === "Default") {
@@ -26909,7 +27600,7 @@ function OhhwellsBridge() {
26909
27600
  }
26910
27601
  setToggleState((prev) => prev ? { ...prev, activeState: state } : null);
26911
27602
  }, [deactivate]);
26912
- const reselectAfterLinkPopover = useCallback10(
27603
+ const reselectAfterLinkPopover = useCallback11(
26913
27604
  (hrefKey) => {
26914
27605
  requestAnimationFrame(() => {
26915
27606
  const el = resolveHrefKeyElement(hrefKey);
@@ -26918,7 +27609,7 @@ function OhhwellsBridge() {
26918
27609
  },
26919
27610
  [resolveHrefKeyElement]
26920
27611
  );
26921
- const closeLinkPopover = useCallback10(() => {
27612
+ const closeLinkPopover = useCallback11(() => {
26922
27613
  const session = linkPopoverSessionRef.current;
26923
27614
  addNavAfterAnchorRef.current = null;
26924
27615
  setLinkPopover(null);
@@ -26926,9 +27617,9 @@ function OhhwellsBridge() {
26926
27617
  reselectAfterLinkPopover(session.key);
26927
27618
  }
26928
27619
  }, [reselectAfterLinkPopover]);
26929
- const closeLinkPopoverRef = useRef12(closeLinkPopover);
27620
+ const closeLinkPopoverRef = useRef13(closeLinkPopover);
26930
27621
  closeLinkPopoverRef.current = closeLinkPopover;
26931
- const openLinkPopoverForActive = useCallback10(() => {
27622
+ const openLinkPopoverForActive = useCallback11(() => {
26932
27623
  const hrefCtx = getHrefKeyFromElement(activeElRef.current);
26933
27624
  if (!hrefCtx) return;
26934
27625
  bumpLinkPopoverGrace();
@@ -26939,7 +27630,7 @@ function OhhwellsBridge() {
26939
27630
  });
26940
27631
  deactivate();
26941
27632
  }, [deactivate]);
26942
- const openLinkPopoverForSelected = useCallback10(() => {
27633
+ const openLinkPopoverForSelected = useCallback11(() => {
26943
27634
  const anchor = selectedElRef.current;
26944
27635
  if (!anchor) return;
26945
27636
  const key = anchor.getAttribute("data-ohw-href-key");
@@ -26956,7 +27647,7 @@ function OhhwellsBridge() {
26956
27647
  });
26957
27648
  deselect();
26958
27649
  }, [deselect]);
26959
- const handleSelectParent = useCallback10(() => {
27650
+ const handleSelectParent = useCallback11(() => {
26960
27651
  const selected = selectedElRef.current;
26961
27652
  if (!selected) return;
26962
27653
  if (toolbarVariantRef.current === "select-frame") {
@@ -26983,7 +27674,7 @@ function OhhwellsBridge() {
26983
27674
  }
26984
27675
  deselectRef.current();
26985
27676
  }, []);
26986
- const handleDuplicateSelected = useCallback10(() => {
27677
+ const handleDuplicateSelected = useCallback11(() => {
26987
27678
  const selected = selectedElRef.current;
26988
27679
  if (!selected || !isNavigationItem2(selected)) return;
26989
27680
  if (isCtaButton(selected)) {
@@ -27146,7 +27837,7 @@ function OhhwellsBridge() {
27146
27837
  });
27147
27838
  }
27148
27839
  }, [postToParent2, tokensForButton]);
27149
- const runPendingDeleteUndo = useCallback10(() => {
27840
+ const runPendingDeleteUndo = useCallback11(() => {
27150
27841
  const pending = pendingDeleteUndoRef.current;
27151
27842
  if (!pending) return false;
27152
27843
  pendingDeleteUndoRef.current = null;
@@ -27154,7 +27845,7 @@ function OhhwellsBridge() {
27154
27845
  enforceLinkHrefs();
27155
27846
  return true;
27156
27847
  }, []);
27157
- const handleDeleteSelected = useCallback10(() => {
27848
+ const handleDeleteSelected = useCallback11(() => {
27158
27849
  const selected = selectedElRef.current;
27159
27850
  if (!selected) return false;
27160
27851
  if (isCtaButton(selected)) {
@@ -27207,7 +27898,7 @@ function OhhwellsBridge() {
27207
27898
  }, [postToParent2]);
27208
27899
  handleDeleteSelectedRef.current = handleDeleteSelected;
27209
27900
  runPendingDeleteUndoRef.current = runPendingDeleteUndo;
27210
- const handleLinkPopoverSubmit = useCallback10(
27901
+ const handleLinkPopoverSubmit = useCallback11(
27211
27902
  (target) => {
27212
27903
  const session = linkPopoverSessionRef.current;
27213
27904
  if (!session) return;
@@ -27273,14 +27964,14 @@ function OhhwellsBridge() {
27273
27964
  const showEditLink = toolbarShowEditLink;
27274
27965
  const currentSections = sectionsByPath[pathname] ?? [];
27275
27966
  linkPopoverOpenRef.current = linkPopover !== null;
27276
- const handleMediaSelect = useCallback10((key) => {
27967
+ const handleMediaSelect = useCallback11((key) => {
27277
27968
  const el = hoveredImageRef.current?.dataset.ohwKey === key ? hoveredImageRef.current : Array.from(document.querySelectorAll(MEDIA_SELECTOR)).find(
27278
27969
  (m) => (m.dataset.ohwKey ?? "") === key
27279
27970
  ) ?? null;
27280
27971
  if (!el) return;
27281
27972
  selectMediaElementRef.current(el);
27282
27973
  }, []);
27283
- const handleMediaReplace = useCallback10(
27974
+ const handleMediaReplace = useCallback11(
27284
27975
  (key) => {
27285
27976
  postToParent2({
27286
27977
  type: "ow:image-pick",
@@ -27290,13 +27981,13 @@ function OhhwellsBridge() {
27290
27981
  },
27291
27982
  [postToParent2, mediaHover?.elementType, selectedMedia?.elementType]
27292
27983
  );
27293
- const handleEditCarousel = useCallback10(
27984
+ const handleEditCarousel = useCallback11(
27294
27985
  (key) => {
27295
27986
  postToParent2({ type: "ow:carousel-open", key, images: readCarouselValue(key) });
27296
27987
  },
27297
27988
  [postToParent2]
27298
27989
  );
27299
- const handleMediaFadeOutComplete = useCallback10((key) => {
27990
+ const handleMediaFadeOutComplete = useCallback11((key) => {
27300
27991
  setUploadingRects((prev) => {
27301
27992
  if (!(key in prev)) return prev;
27302
27993
  const next = { ...prev };
@@ -27304,7 +27995,7 @@ function OhhwellsBridge() {
27304
27995
  return next;
27305
27996
  });
27306
27997
  }, []);
27307
- const handleVideoSettingsChange = useCallback10(
27998
+ const handleVideoSettingsChange = useCallback11(
27308
27999
  (key, settings) => {
27309
28000
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
27310
28001
  const video = getVideoEl2(el);
@@ -27326,14 +28017,14 @@ function OhhwellsBridge() {
27326
28017
  },
27327
28018
  [postToParent2]
27328
28019
  );
27329
- return /* @__PURE__ */ jsxs23(Fragment10, { children: [
27330
- /* @__PURE__ */ jsx36("div", { id: "ohw-loader", suppressHydrationWarning: true, style: { ...OHW_LOADER_STYLE, display: "none" }, children: /* @__PURE__ */ jsx36(OhwLoaderSpinner, {}) }),
27331
- /* @__PURE__ */ jsx36("script", { suppressHydrationWarning: true, dangerouslySetInnerHTML: { __html: OHW_LOADER_PREHYDRATE_SCRIPT } }),
27332
- subdomain && !isEditMode && showBranding && /* @__PURE__ */ jsx36(MadeWithOhhWells, {}),
28020
+ return /* @__PURE__ */ jsxs24(Fragment11, { children: [
28021
+ /* @__PURE__ */ jsx37("div", { id: "ohw-loader", suppressHydrationWarning: true, style: { ...OHW_LOADER_STYLE, display: "none" }, children: /* @__PURE__ */ jsx37(OhwLoaderSpinner, {}) }),
28022
+ /* @__PURE__ */ jsx37("script", { suppressHydrationWarning: true, dangerouslySetInnerHTML: { __html: OHW_LOADER_PREHYDRATE_SCRIPT } }),
28023
+ subdomain && !isEditMode && showBranding && /* @__PURE__ */ jsx37(MadeWithOhhWells, {}),
27333
28024
  bridgeRoot ? createPortal3(
27334
- /* @__PURE__ */ jsxs23(Fragment10, { children: [
27335
- /* @__PURE__ */ jsx36("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
27336
- isEditMode && /* @__PURE__ */ jsx36(
28025
+ /* @__PURE__ */ jsxs24(Fragment11, { children: [
28026
+ /* @__PURE__ */ jsx37("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
28027
+ isEditMode && /* @__PURE__ */ jsx37(
27337
28028
  AiSectionOverlay,
27338
28029
  {
27339
28030
  postToParent: postToParent2,
@@ -27341,7 +28032,7 @@ function OhhwellsBridge() {
27341
28032
  onSelectionChange: handleAiSectionSelectionChange
27342
28033
  }
27343
28034
  ),
27344
- isEditMode && /* @__PURE__ */ jsx36(
28035
+ isEditMode && /* @__PURE__ */ jsx37(
27345
28036
  AiMediaStripOverlay,
27346
28037
  {
27347
28038
  postToParent: postToParent2,
@@ -27350,7 +28041,7 @@ function OhhwellsBridge() {
27350
28041
  clearInteractionChromeRef
27351
28042
  }
27352
28043
  ),
27353
- isEditMode && /* @__PURE__ */ jsx36(
28044
+ isEditMode && /* @__PURE__ */ jsx37(
27354
28045
  AiPricingCardOverlay,
27355
28046
  {
27356
28047
  postToParent: postToParent2,
@@ -27358,12 +28049,21 @@ function OhhwellsBridge() {
27358
28049
  applyTreeLocalRef
27359
28050
  }
27360
28051
  ),
27361
- isSectionDragging && sectionDropSlots.map((slot, i) => /* @__PURE__ */ jsx36(
28052
+ isEditMode && /* @__PURE__ */ jsx37(
28053
+ AiVideoOverlay,
28054
+ {
28055
+ postToParent: postToParent2,
28056
+ aiSectionsRef,
28057
+ applyTreeLocalRef,
28058
+ clearInteractionChromeRef
28059
+ }
28060
+ ),
28061
+ isSectionDragging && sectionDropSlots.map((slot, i) => /* @__PURE__ */ jsx37(
27362
28062
  "div",
27363
28063
  {
27364
28064
  className: "pointer-events-none fixed z-2147483646",
27365
28065
  style: { left: slot.left, top: slot.y, width: slot.width, height: 3, transform: "translateY(-50%)" },
27366
- children: /* @__PURE__ */ jsx36(
28066
+ children: /* @__PURE__ */ jsx37(
27367
28067
  DropIndicator,
27368
28068
  {
27369
28069
  direction: "horizontal",
@@ -27374,7 +28074,7 @@ function OhhwellsBridge() {
27374
28074
  },
27375
28075
  `section-drop-${slot.insertIndex}-${i}`
27376
28076
  )),
27377
- Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ jsx36(
28077
+ Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ jsx37(
27378
28078
  MediaOverlay,
27379
28079
  {
27380
28080
  hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
@@ -27385,7 +28085,7 @@ function OhhwellsBridge() {
27385
28085
  },
27386
28086
  `uploading-${key}`
27387
28087
  )),
27388
- mediaHover && !(mediaHover.key in uploadingRects) && mediaHover.key !== selectedMedia?.key && /* @__PURE__ */ jsx36(
28088
+ mediaHover && !(mediaHover.key in uploadingRects) && mediaHover.key !== selectedMedia?.key && /* @__PURE__ */ jsx37(
27389
28089
  MediaOverlay,
27390
28090
  {
27391
28091
  hover: mediaHover,
@@ -27396,7 +28096,7 @@ function OhhwellsBridge() {
27396
28096
  onVideoSettingsChange: handleVideoSettingsChange
27397
28097
  }
27398
28098
  ),
27399
- selectedMedia && !(selectedMedia.key in uploadingRects) && !linkPopover && /* @__PURE__ */ jsx36(
28099
+ selectedMedia && !(selectedMedia.key in uploadingRects) && !linkPopover && /* @__PURE__ */ jsx37(
27400
28100
  MediaOverlay,
27401
28101
  {
27402
28102
  hover: selectedMedia,
@@ -27408,7 +28108,7 @@ function OhhwellsBridge() {
27408
28108
  onVideoSettingsChange: handleVideoSettingsChange
27409
28109
  }
27410
28110
  ),
27411
- carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx36(
28111
+ carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx37(
27412
28112
  CarouselOverlay,
27413
28113
  {
27414
28114
  hover: carouselHover,
@@ -27416,10 +28116,10 @@ function OhhwellsBridge() {
27416
28116
  cueOnly: !!carouselHover.fullBleedSectionId && carouselHover.fullBleedSectionId !== selectedAiSectionId
27417
28117
  }
27418
28118
  ),
27419
- siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ jsx36(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
27420
- siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ jsx36(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
27421
- isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && selectedElRef.current !== buttonCollectionDragRef.current && /* @__PURE__ */ jsx36(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
27422
- isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ jsx36(
28119
+ siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ jsx37(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
28120
+ siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ jsx37(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
28121
+ isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && selectedElRef.current !== buttonCollectionDragRef.current && /* @__PURE__ */ jsx37(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
28122
+ isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ jsx37(
27423
28123
  "div",
27424
28124
  {
27425
28125
  className: "pointer-events-none fixed z-2147483646",
@@ -27429,7 +28129,7 @@ function OhhwellsBridge() {
27429
28129
  width: slot.width,
27430
28130
  height: slot.height
27431
28131
  },
27432
- children: /* @__PURE__ */ jsx36(
28132
+ children: /* @__PURE__ */ jsx37(
27433
28133
  DropIndicator,
27434
28134
  {
27435
28135
  direction: slot.direction,
@@ -27440,7 +28140,7 @@ function OhhwellsBridge() {
27440
28140
  },
27441
28141
  `footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
27442
28142
  )),
27443
- isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ jsx36(
28143
+ isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ jsx37(
27444
28144
  "div",
27445
28145
  {
27446
28146
  className: "pointer-events-none fixed z-2147483646",
@@ -27450,7 +28150,7 @@ function OhhwellsBridge() {
27450
28150
  width: slot.width,
27451
28151
  height: slot.height
27452
28152
  },
27453
- children: /* @__PURE__ */ jsx36(
28153
+ children: /* @__PURE__ */ jsx37(
27454
28154
  DropIndicator,
27455
28155
  {
27456
28156
  direction: slot.direction,
@@ -27461,7 +28161,7 @@ function OhhwellsBridge() {
27461
28161
  },
27462
28162
  `nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
27463
28163
  )),
27464
- isItemDragging && buttonDropSlots.map((slot, i) => /* @__PURE__ */ jsx36(
28164
+ isItemDragging && buttonDropSlots.map((slot, i) => /* @__PURE__ */ jsx37(
27465
28165
  "div",
27466
28166
  {
27467
28167
  className: "pointer-events-none fixed z-2147483646",
@@ -27471,7 +28171,7 @@ function OhhwellsBridge() {
27471
28171
  width: slot.width,
27472
28172
  height: slot.height
27473
28173
  },
27474
- children: /* @__PURE__ */ jsx36(
28174
+ children: /* @__PURE__ */ jsx37(
27475
28175
  DropIndicator,
27476
28176
  {
27477
28177
  direction: slot.direction,
@@ -27482,10 +28182,10 @@ function OhhwellsBridge() {
27482
28182
  },
27483
28183
  `button-drop-${slot.direction}-${slot.insertIndex}-${i}`
27484
28184
  )),
27485
- hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx36(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
27486
- hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ jsx36(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
27487
- hoveredTextRect && !hoveredNavContainerRect && !hoveredItemRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ jsx36(ItemInteractionLayer, { rect: hoveredTextRect, state: "hover" }),
27488
- formPickRect && !isItemDragging && /* @__PURE__ */ jsx36(
28185
+ hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx37(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
28186
+ hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ jsx37(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
28187
+ hoveredTextRect && !hoveredNavContainerRect && !hoveredItemRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ jsx37(ItemInteractionLayer, { rect: hoveredTextRect, state: "hover" }),
28188
+ formPickRect && !isItemDragging && /* @__PURE__ */ jsx37(
27489
28189
  ItemInteractionLayer,
27490
28190
  {
27491
28191
  rect: formPickRect,
@@ -27493,13 +28193,13 @@ function OhhwellsBridge() {
27493
28193
  itemDragSurface: false,
27494
28194
  toolbarAlign: "left",
27495
28195
  chromeGap: 24,
27496
- toolbar: fieldPickRect ? void 0 : /* @__PURE__ */ jsxs23(
28196
+ toolbar: fieldPickRect ? void 0 : /* @__PURE__ */ jsxs24(
27497
28197
  "div",
27498
28198
  {
27499
28199
  "data-ohw-form-toolbar": "",
27500
28200
  className: "pointer-events-auto flex items-center gap-0.5 whitespace-nowrap rounded-lg border border-border bg-background p-1 shadow-md",
27501
28201
  children: [
27502
- /* @__PURE__ */ jsx36(
28202
+ /* @__PURE__ */ jsx37(
27503
28203
  "button",
27504
28204
  {
27505
28205
  type: "button",
@@ -27507,11 +28207,11 @@ function OhhwellsBridge() {
27507
28207
  className: "flex h-7 w-7 items-center justify-center rounded-md text-foreground transition-colors hover:bg-muted/80",
27508
28208
  onClick: () => setFieldTypePickerOpen((open) => !open),
27509
28209
  "data-ohw-add-field": "",
27510
- children: /* @__PURE__ */ jsx36(Plus4, { size: 15, "aria-hidden": true })
28210
+ children: /* @__PURE__ */ jsx37(Plus4, { size: 15, "aria-hidden": true })
27511
28211
  }
27512
28212
  ),
27513
- /* @__PURE__ */ jsx36("div", { className: "mx-0.5 h-5 w-px bg-border" }),
27514
- /* @__PURE__ */ jsxs23(
28213
+ /* @__PURE__ */ jsx37("div", { className: "mx-0.5 h-5 w-px bg-border" }),
28214
+ /* @__PURE__ */ jsxs24(
27515
28215
  "button",
27516
28216
  {
27517
28217
  type: "button",
@@ -27527,11 +28227,11 @@ function OhhwellsBridge() {
27527
28227
  });
27528
28228
  },
27529
28229
  children: [
27530
- /* @__PURE__ */ jsx36(Settings, { size: 14, "aria-hidden": true }),
28230
+ /* @__PURE__ */ jsx37(Settings, { size: 14, "aria-hidden": true }),
27531
28231
  "Form settings",
27532
28232
  formPickCount ? (
27533
28233
  // Counter pill, per the design — not a text suffix.
27534
- /* @__PURE__ */ jsx36(
28234
+ /* @__PURE__ */ jsx37(
27535
28235
  "span",
27536
28236
  {
27537
28237
  "data-ohw-form-count": "",
@@ -27543,8 +28243,8 @@ function OhhwellsBridge() {
27543
28243
  ]
27544
28244
  }
27545
28245
  ),
27546
- /* @__PURE__ */ jsx36("div", { className: "mx-0.5 h-5 w-px bg-border" }),
27547
- /* @__PURE__ */ jsx36("div", { className: "flex items-center rounded-md bg-muted/70 p-0.5", children: ["default", "success"].map((state) => /* @__PURE__ */ jsx36(
28246
+ /* @__PURE__ */ jsx37("div", { className: "mx-0.5 h-5 w-px bg-border" }),
28247
+ /* @__PURE__ */ jsx37("div", { className: "flex items-center rounded-md bg-muted/70 p-0.5", children: ["default", "success"].map((state) => /* @__PURE__ */ jsx37(
27548
28248
  "button",
27549
28249
  {
27550
28250
  type: "button",
@@ -27575,7 +28275,7 @@ function OhhwellsBridge() {
27575
28275
  )
27576
28276
  }
27577
28277
  ),
27578
- formHoverRect && !isItemDragging && /* @__PURE__ */ jsx36(
28278
+ formHoverRect && !isItemDragging && /* @__PURE__ */ jsx37(
27579
28279
  ItemInteractionLayer,
27580
28280
  {
27581
28281
  rect: formHoverRect,
@@ -27583,7 +28283,7 @@ function OhhwellsBridge() {
27583
28283
  chromeGap: formHoverElRef.current && getFieldWrapper(formHoverElRef.current) ? 8 : 24
27584
28284
  }
27585
28285
  ),
27586
- fieldPickRect && fieldPickState && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ jsx36(
28286
+ fieldPickRect && fieldPickState && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ jsx37(
27587
28287
  ItemInteractionLayer,
27588
28288
  {
27589
28289
  rect: fieldPickRect,
@@ -27595,7 +28295,7 @@ function OhhwellsBridge() {
27595
28295
  dragHandleLabel: "Reorder field",
27596
28296
  onDragHandleDragStart: handleFieldDragStart,
27597
28297
  onDragHandleDragEnd: handleFieldDragEnd,
27598
- toolbar: /* @__PURE__ */ jsx36(
28298
+ toolbar: /* @__PURE__ */ jsx37(
27599
28299
  FormFieldToolbar,
27600
28300
  {
27601
28301
  type: fieldPickState.type,
@@ -27608,12 +28308,12 @@ function OhhwellsBridge() {
27608
28308
  )
27609
28309
  }
27610
28310
  ),
27611
- fieldDragging ? fieldDropSlots.map((slot, i) => /* @__PURE__ */ jsx36(
28311
+ fieldDragging ? fieldDropSlots.map((slot, i) => /* @__PURE__ */ jsx37(
27612
28312
  "div",
27613
28313
  {
27614
28314
  className: "pointer-events-none fixed z-[2147483644]",
27615
28315
  style: { top: slot.top, left: slot.left, width: slot.width },
27616
- children: /* @__PURE__ */ jsx36(
28316
+ children: /* @__PURE__ */ jsx37(
27617
28317
  DropIndicator,
27618
28318
  {
27619
28319
  direction: "horizontal",
@@ -27626,7 +28326,7 @@ function OhhwellsBridge() {
27626
28326
  )) : null,
27627
28327
  fieldTypePickerOpen && formPickRect ? (() => {
27628
28328
  const toolbar = document.querySelector("[data-ohw-form-toolbar]")?.getBoundingClientRect();
27629
- return /* @__PURE__ */ jsx36(
28329
+ return /* @__PURE__ */ jsx37(
27630
28330
  "div",
27631
28331
  {
27632
28332
  className: "pointer-events-none fixed z-[2147483645]",
@@ -27634,12 +28334,12 @@ function OhhwellsBridge() {
27634
28334
  top: toolbar ? toolbar.bottom + 6 : formPickRect.top + 16,
27635
28335
  left: toolbar ? toolbar.left : formPickRect.left + 24
27636
28336
  },
27637
- children: /* @__PURE__ */ jsx36(FieldTypePicker, { onPick: handleAddField })
28337
+ children: /* @__PURE__ */ jsx37(FieldTypePicker, { onPick: handleAddField })
27638
28338
  }
27639
28339
  );
27640
28340
  })() : null,
27641
- toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ jsx36(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
27642
- toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ jsx36(
28341
+ toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ jsx37(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
28342
+ toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ jsx37(
27643
28343
  FooterContainerChrome,
27644
28344
  {
27645
28345
  rect: toolbarRect,
@@ -27647,7 +28347,7 @@ function OhhwellsBridge() {
27647
28347
  addDisabled: !canAddFooterColumn()
27648
28348
  }
27649
28349
  ),
27650
- toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame" || toolbarVariant === "logo") && /* @__PURE__ */ jsx36(
28350
+ toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame" || toolbarVariant === "logo") && /* @__PURE__ */ jsx37(
27651
28351
  ItemInteractionLayer,
27652
28352
  {
27653
28353
  rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected || selectedElRef.current === buttonCollectionDragRef.current) ? draggedItemRect : toolbarRect,
@@ -27667,7 +28367,7 @@ function OhhwellsBridge() {
27667
28367
  onItemPointerDown: toolbarVariant === "logo" ? void 0 : handleItemChromePointerDown,
27668
28368
  onItemClick: toolbarVariant === "logo" ? void 0 : handleItemChromeClick,
27669
28369
  itemDragSurface: toolbarVariant !== "logo" && !isFooterFrameSelection && !selectedIsSocialsRow,
27670
- toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ jsx36(
28370
+ toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ jsx37(
27671
28371
  ItemActionToolbar,
27672
28372
  {
27673
28373
  onEditLink: openLinkPopoverForSelected,
@@ -27718,8 +28418,8 @@ function OhhwellsBridge() {
27718
28418
  ) : void 0
27719
28419
  }
27720
28420
  ),
27721
- toolbarRect && toolbarVariant === "rich-text" && !linkPopover && !isRectOutsideClip(toolbarRect, getIframeVisibleClip(parentScrollRef.current)) && /* @__PURE__ */ jsxs23(Fragment10, { children: [
27722
- /* @__PURE__ */ jsx36(
28421
+ toolbarRect && toolbarVariant === "rich-text" && !linkPopover && !isRectOutsideClip(toolbarRect, getIframeVisibleClip(parentScrollRef.current)) && /* @__PURE__ */ jsxs24(Fragment11, { children: [
28422
+ /* @__PURE__ */ jsx37(
27723
28423
  EditGlowChrome,
27724
28424
  {
27725
28425
  rect: toolbarRect,
@@ -27729,7 +28429,7 @@ function OhhwellsBridge() {
27729
28429
  hideHandle: isItemDragging
27730
28430
  }
27731
28431
  ),
27732
- /* @__PURE__ */ jsx36(
28432
+ /* @__PURE__ */ jsx37(
27733
28433
  FloatingToolbar,
27734
28434
  {
27735
28435
  rect: toolbarRect,
@@ -27742,7 +28442,7 @@ function OhhwellsBridge() {
27742
28442
  }
27743
28443
  )
27744
28444
  ] }),
27745
- maxBadge && /* @__PURE__ */ jsxs23(
28445
+ maxBadge && /* @__PURE__ */ jsxs24(
27746
28446
  "div",
27747
28447
  {
27748
28448
  "data-ohw-max-badge": "",
@@ -27768,7 +28468,7 @@ function OhhwellsBridge() {
27768
28468
  ]
27769
28469
  }
27770
28470
  ),
27771
- toggleState && !linkPopover && /* @__PURE__ */ jsx36(
28471
+ toggleState && !linkPopover && /* @__PURE__ */ jsx37(
27772
28472
  StateToggle,
27773
28473
  {
27774
28474
  rect: toggleState.rect,
@@ -27777,15 +28477,15 @@ function OhhwellsBridge() {
27777
28477
  onStateChange: handleStateChange
27778
28478
  }
27779
28479
  ),
27780
- sectionGap && !linkPopover && /* @__PURE__ */ jsxs23(
28480
+ sectionGap && !linkPopover && /* @__PURE__ */ jsxs24(
27781
28481
  "div",
27782
28482
  {
27783
28483
  "data-ohw-section-insert-line": "",
27784
28484
  className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
27785
28485
  style: { top: sectionGap.y, transform: "translateY(-50%)" },
27786
28486
  children: [
27787
- /* @__PURE__ */ jsx36("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } }),
27788
- /* @__PURE__ */ jsx36(
28487
+ /* @__PURE__ */ jsx37("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } }),
28488
+ /* @__PURE__ */ jsx37(
27789
28489
  Badge,
27790
28490
  {
27791
28491
  className: "px-8 py-1 bg-bridge-primary hover:bg-bridge-primary text-primary-foreground text-xs font-medium shrink-0 rounded-full cursor-pointer pointer-events-auto",
@@ -27802,11 +28502,11 @@ function OhhwellsBridge() {
27802
28502
  children: "Add Section"
27803
28503
  }
27804
28504
  ),
27805
- /* @__PURE__ */ jsx36("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } })
28505
+ /* @__PURE__ */ jsx37("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } })
27806
28506
  ]
27807
28507
  }
27808
28508
  ),
27809
- linkPopover && dialogPortalContainer ? /* @__PURE__ */ jsx36(
28509
+ linkPopover && dialogPortalContainer ? /* @__PURE__ */ jsx37(
27810
28510
  LinkPopover,
27811
28511
  {
27812
28512
  panelRef: linkPopoverPanelRef,
@@ -27823,7 +28523,7 @@ function OhhwellsBridge() {
27823
28523
  },
27824
28524
  linkPopover.key
27825
28525
  ) : null,
27826
- floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ jsx36(
28526
+ floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ jsx37(
27827
28527
  FloatingPanel,
27828
28528
  {
27829
28529
  open: true,
@@ -27833,7 +28533,7 @@ function OhhwellsBridge() {
27833
28533
  onPositionChange: setFloatingPanelPos,
27834
28534
  parentScroll: parentScrollSnap ?? parentScrollRef.current,
27835
28535
  onClose: closeFloatingPanelOnly,
27836
- children: /* @__PURE__ */ jsx36(
28536
+ children: /* @__PURE__ */ jsx37(
27837
28537
  SocialsDisplayPanel,
27838
28538
  {
27839
28539
  display: socialsDisplayFor(floatingPanel.row, editContentRef.current),
@@ -27854,19 +28554,19 @@ function OhhwellsBridge() {
27854
28554
  const tokens = tokensFromButton(button);
27855
28555
  const current = assignmentFor(button, editContentRef.current, tokens);
27856
28556
  void buttonStyleTick;
27857
- return /* @__PURE__ */ jsx36(
28557
+ return /* @__PURE__ */ jsx37(
27858
28558
  FloatingPanel,
27859
28559
  {
27860
28560
  open: true,
27861
28561
  title: floatingPanel.title,
27862
28562
  context: floatingPanel.context,
27863
- icon: /* @__PURE__ */ jsx36(Brush2, { className: "size-4 shrink-0", "aria-hidden": true }),
28563
+ icon: /* @__PURE__ */ jsx37(Brush2, { className: "size-4 shrink-0", "aria-hidden": true }),
27864
28564
  position: floatingPanelPos,
27865
28565
  onPositionChange: setFloatingPanelPos,
27866
28566
  parentScroll: parentScrollSnap ?? parentScrollRef.current,
27867
28567
  onClose: closeFloatingPanelOnly,
27868
28568
  bodyClassName: "gap-5",
27869
- children: /* @__PURE__ */ jsx36(
28569
+ children: /* @__PURE__ */ jsx37(
27870
28570
  ButtonStylePanel,
27871
28571
  {
27872
28572
  variants: tokens.variants,
@@ -27891,6 +28591,59 @@ function OhhwellsBridge() {
27891
28591
  ) : null
27892
28592
  ] });
27893
28593
  }
28594
+
28595
+ // src/ui/EmptySection.tsx
28596
+ import Link3 from "next/link";
28597
+ import { Fragment as Fragment12, jsx as jsx38, jsxs as jsxs25 } from "react/jsx-runtime";
28598
+ function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey }) {
28599
+ return /* @__PURE__ */ jsxs25(Fragment12, { children: [
28600
+ /* @__PURE__ */ jsx38(
28601
+ "p",
28602
+ {
28603
+ style: {
28604
+ fontFamily: "var(--brand-font-body)",
28605
+ fontSize: "0.75rem",
28606
+ fontWeight: 500,
28607
+ letterSpacing: "0.15em",
28608
+ textTransform: "uppercase",
28609
+ color: "var(--brand-accent)",
28610
+ marginBottom: "1.5rem"
28611
+ },
28612
+ children: /* @__PURE__ */ jsx38(Link3, { href: homeHref, style: { color: "inherit" }, children: /* @__PURE__ */ jsx38("span", { ...eyebrowKey ? { "data-ohw-editable": "text", "data-ohw-key": eyebrowKey } : {}, children: "Home" }) })
28613
+ }
28614
+ ),
28615
+ /* @__PURE__ */ jsx38(
28616
+ "h1",
28617
+ {
28618
+ style: {
28619
+ fontFamily: "var(--brand-font-heading)",
28620
+ fontSize: "clamp(2rem, 3.5vw, 2.75rem)",
28621
+ lineHeight: 1.1,
28622
+ letterSpacing: "-0.025em",
28623
+ color: "var(--brand-text)",
28624
+ marginBottom: "1rem"
28625
+ },
28626
+ ...titleKey ? { "data-ohw-editable": "text", "data-ohw-key": titleKey, "data-ohw-max-length": 80 } : {},
28627
+ children: title
28628
+ }
28629
+ ),
28630
+ /* @__PURE__ */ jsx38(
28631
+ "p",
28632
+ {
28633
+ style: {
28634
+ fontFamily: "var(--brand-font-body)",
28635
+ fontSize: "1rem",
28636
+ lineHeight: 1.7,
28637
+ fontWeight: 300,
28638
+ color: "var(--brand-text-muted)",
28639
+ maxWidth: "340px"
28640
+ },
28641
+ ...subtitleKey ? { "data-ohw-editable": "text", "data-ohw-key": subtitleKey, "data-ohw-max-length": 160 } : {},
28642
+ children: "This page doesn't have any content yet."
28643
+ }
28644
+ )
28645
+ ] });
28646
+ }
27894
28647
  export {
27895
28648
  AI_DEFAULT_BRAND,
27896
28649
  AI_TREE_SCHEMA_VERSIONS,
@@ -27907,6 +28660,7 @@ export {
27907
28660
  DropdownMenuItem,
27908
28661
  DropdownMenuSeparator,
27909
28662
  DropdownMenuTrigger,
28663
+ EmptySection,
27910
28664
  ItemActionToolbar,
27911
28665
  ItemInteractionLayer,
27912
28666
  LinkEditorPanel,